mirror of
https://github.com/BenjieFiftysix/sponge.git
synced 2024-11-19 22:13:49 +01:00
Make sponge area spherical, and add config options
This commit is contained in:
parent
42d644b69d
commit
4ef64420ca
18
README.md
18
README.md
@ -1,7 +1,7 @@
|
||||
# Minetest Sponge mod
|
||||
## Water-removing sponges for Minetest.
|
||||
|
||||
Created by Benjie/fiftysix/56 2018-08-27 - Last updated 2023-02-20
|
||||
Created by Benjie/fiftysix/56 2018-08-27 - Last updated 2023-02-21
|
||||
Copyright Benjie 2018-2023
|
||||
|
||||
[Forum topic](https://forum.minetest.net/viewtopic.php?f=9&t=20729)
|
||||
@ -13,12 +13,14 @@ They will hold the water away until they are removed.
|
||||
This will cause them to become soggy, so to use them again they have to be cooked.
|
||||
|
||||
### How it works:
|
||||
* Sponges create a 9x9x9 cube of air-like nodes that water can't flow through (checks for protection).
|
||||
* Sponges create a diameter 9 sphere of air-like nodes that water can't flow through (checks for protection).
|
||||
* If sponges have cleared more than 3 nodes of liquid, they become soggy sponges.
|
||||
* Removing a sponge or soggy sponge will turn a 9x9x9 cube of air-like nodes back into air, as long as they are not in the area of another sponge.
|
||||
* Removing a sponge or soggy sponge will turn a diameter 9 sphere of air-like nodes back into air, as long as they are not in the area of another sponge.
|
||||
*(Air-like nodes can be removed in protection by removing a sponge outside the protection, they are not meant to be permanent)*
|
||||
|
||||
### Options:
|
||||
The mod should be most enjoyable by leaving all options at their default values.
|
||||
|
||||
**Replace air nodes** (sponge_replace_air_nodes): boolean, default true
|
||||
Causes sponges not to replace air with water blocking airlike nodes. Disabling this may cause unusual behaviour with flowing water.
|
||||
|
||||
@ -29,3 +31,13 @@ See "Group list type" (sponge_group_list_type) for the behaviour of this list.
|
||||
**Group list type** (sponge_group_list_type): multi-choice, default whitelist_source
|
||||
If the groups in the group list should be treated as a whitelist or blacklist for removing liquids.
|
||||
The *_source variants will remove all flowing liquids regardless of the list.
|
||||
|
||||
**Radius** (sponge_radius): number, default 4.5
|
||||
Radius of the sphere or cube of liquid that gets removed.
|
||||
|
||||
**Sphere shape** (sponge_shape_sphere): boolean, default true
|
||||
Whether to use a sphere shape to remove liquids.
|
||||
|
||||
**Replace with air** (sponge_replace_with_air): boolean, default false
|
||||
Replace liquids with air instead of liquid blocking nodes.
|
||||
This causes water to flow back immediately after placing the sponge.
|
||||
|
181
init.lua
181
init.lua
@ -1,30 +1,31 @@
|
||||
--[[
|
||||
- Minetest Sponge mod
|
||||
- Water removing sponges for Minetest
|
||||
- Created by Benjie/fiftysix/56 2018-08-27 - Last updated 2023-02-20
|
||||
- Created by Benjie/fiftysix/56 2018-08-27 - Last updated 2023-02-21
|
||||
- Copyright Benjie 2018-2023
|
||||
|
||||
Soggy sponges can rarely be found deep in the sea where the darkness begins.
|
||||
These can be cooked into dry sponges, and then placed near a liquid to remove the surrounding cube of it
|
||||
These can be cooked into dry sponges, and then placed near a liquid to remove the surrounding sphere of it
|
||||
They will hold the water away until they are removed.
|
||||
This will cause them to become soggy, so to use them again they have to be cooked.
|
||||
|
||||
Sponges create a 9x9x9 cube of air-like nodes that water can't flow through (checks for protection)
|
||||
Sponges create a diameter 9 sphere of air-like nodes that water can't flow through (checks for protection)
|
||||
If sponges have cleared more than 3 nodes of liquid, they become soggy sponges
|
||||
removing a sponge or soggy sponge will turn a 9x9x9 cube of air-like nodes back into air
|
||||
removing a sponge or soggy sponge will turn a diameter 9 sphere of air-like nodes back into air
|
||||
(air-like nodes can be removed in protection by removing a sponge outside the protection, they are not meant to be permanent)
|
||||
]]--
|
||||
|
||||
|
||||
local modname = minetest.get_current_modname()
|
||||
|
||||
local area = 4 -- The "radius" (of the cube) to clear water
|
||||
local keep_dry = 3 -- The maximum amount of water cleared where the sponge doesn't turn soggy
|
||||
|
||||
-- Load configurable options
|
||||
local replace_air_nodes = minetest.settings:get_bool("sponge_replace_air_nodes", true)
|
||||
local group_list = minetest.settings:get("sponge_group_list", false) or "water"
|
||||
local group_list_type = minetest.settings:get("sponge_group_list_type") or "whitelist_source"
|
||||
local radius = tonumber(minetest.settings:get("sponge_radius") or 4.5)
|
||||
local shape_sphere = minetest.settings:get_bool("sponge_shape_sphere", true)
|
||||
local replace_with_air = minetest.settings:get_bool("sponge_replace_with_air", false)
|
||||
|
||||
-- returns true if groups contains anything in list
|
||||
local compare_groups = function(list, groups)
|
||||
@ -39,10 +40,15 @@ end
|
||||
|
||||
-- called by after_destruct()
|
||||
local destruct = function(pos) -- removing the air-like nodes
|
||||
-- if air was used, there is nothing to remove
|
||||
if replace_with_air then return end
|
||||
|
||||
local edge_distance = math.floor(radius)
|
||||
|
||||
-- find all sponges that intersect with this sponge's area
|
||||
-- find all sponges that intersect with this sponge's radius
|
||||
local sponge_info = minetest.find_nodes_in_area(
|
||||
{x=pos.x-area*2, y=pos.y-area*2, z=pos.z-area*2}, {x=pos.x+area*2, y=pos.y+area*2, z=pos.z+area*2},
|
||||
vector.new(pos.x-edge_distance*2, pos.y-edge_distance*2, pos.z-edge_distance*2),
|
||||
vector.new(pos.x+edge_distance*2, pos.y+edge_distance*2, pos.z+edge_distance*2),
|
||||
{modname..":soggy_sponge", modname..":sponge"}, true
|
||||
)
|
||||
local sponges = {}
|
||||
@ -53,23 +59,31 @@ local destruct = function(pos) -- removing the air-like nodes
|
||||
end
|
||||
end
|
||||
|
||||
for x = pos.x-area, pos.x+area do
|
||||
for y = pos.y-area, pos.y+area do
|
||||
for z = pos.z-area, pos.z+area do
|
||||
local n = minetest.get_node({x=x, y=y, z=z}).name
|
||||
if n == modname..":liquid_stop" then
|
||||
|
||||
-- check if position intersects with another sponge
|
||||
local intersect = false
|
||||
for _, s_pos in pairs(sponges) do
|
||||
if math.abs(s_pos.x-x) <= area and math.abs(s_pos.y-y) <= area and math.abs(s_pos.z-z) <= area then
|
||||
intersect = true
|
||||
break
|
||||
for x = pos.x-edge_distance, pos.x+edge_distance do
|
||||
for y = pos.y-edge_distance, pos.y+edge_distance do
|
||||
for z = pos.z-edge_distance, pos.z+edge_distance do
|
||||
local p = vector.new(x, y, z)
|
||||
if (not shape_sphere or p:distance(pos) <= radius) then
|
||||
local n = minetest.get_node(p).name
|
||||
if n == modname..":liquid_stop" then
|
||||
|
||||
-- check if position intersects with another sponge
|
||||
local intersect = false
|
||||
for _, s_pos in pairs(sponges) do
|
||||
if (
|
||||
(shape_sphere and p:distance(s_pos) <= radius) or
|
||||
(not shape_sphere and
|
||||
math.abs(s_pos.x-x) <= radius and math.abs(s_pos.y-y) <= radius and math.abs(s_pos.z-z) <= radius)
|
||||
) then
|
||||
|
||||
intersect = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not intersect then
|
||||
minetest.remove_node(p)
|
||||
end
|
||||
end
|
||||
|
||||
if not intersect then
|
||||
minetest.remove_node({x=x, y=y, z=z})
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -84,49 +98,57 @@ local construct = function(pos, placer, itemstack, pointed_thing)
|
||||
if not minetest.is_protected(pos, playername) then
|
||||
local count = 0
|
||||
|
||||
for x = pos.x-area, pos.x+area do
|
||||
for y = pos.y-area, pos.y+area do
|
||||
for z = pos.z-area, pos.z+area do
|
||||
local p = {x=x, y=y, z=z}
|
||||
|
||||
local n = minetest.get_node(p).name
|
||||
local def = minetest.registered_nodes[n]
|
||||
local replace = false
|
||||
if def == nil or minetest.is_protected(p, playername) then
|
||||
-- replace = false
|
||||
elseif replace_air_nodes and n == "air" then
|
||||
replace = true
|
||||
elseif def["drawtype"] == "flowingliquid" then
|
||||
if group_list_type == "whitelist" then
|
||||
if compare_groups(group_list, def.groups or {}) then
|
||||
replace = true
|
||||
end
|
||||
elseif group_list_type == "blacklist" then
|
||||
if not compare_groups(group_list, def.groups or {}) then
|
||||
replace = true
|
||||
end
|
||||
else
|
||||
replace = true
|
||||
end
|
||||
elseif def["drawtype"] == "liquid" then
|
||||
if group_list_type == "whitelist" or group_list_type == "whitelist_source" then
|
||||
if compare_groups(group_list, def.groups or {}) then
|
||||
replace = true
|
||||
end
|
||||
elseif group_list_type == "blacklist" or group_list_type == "blacklist_source" then
|
||||
if not compare_groups(group_list, def.groups or {}) then
|
||||
replace = true
|
||||
end
|
||||
else
|
||||
replace = true
|
||||
end
|
||||
end
|
||||
local edge_distance = math.floor(radius)
|
||||
for x = pos.x-edge_distance, pos.x+edge_distance do
|
||||
for y = pos.y-edge_distance, pos.y+edge_distance do
|
||||
for z = pos.z-edge_distance, pos.z+edge_distance do
|
||||
local p = vector.new(x, y, z)
|
||||
|
||||
if replace then
|
||||
if n ~= "air" then
|
||||
count = count + 1 -- counting liquids
|
||||
if (not shape_sphere or p:distance(pos) <= radius) then
|
||||
|
||||
local n = minetest.get_node(p).name
|
||||
local def = minetest.registered_nodes[n]
|
||||
local replace = false
|
||||
if def == nil or minetest.is_protected(p, playername) then
|
||||
-- replace = false
|
||||
elseif replace_air_nodes and n == "air" then
|
||||
replace = true
|
||||
elseif def["drawtype"] == "flowingliquid" then
|
||||
if group_list_type == "whitelist" then
|
||||
if compare_groups(group_list, def.groups or {}) then
|
||||
replace = true
|
||||
end
|
||||
elseif group_list_type == "blacklist" then
|
||||
if not compare_groups(group_list, def.groups or {}) then
|
||||
replace = true
|
||||
end
|
||||
else
|
||||
replace = true
|
||||
end
|
||||
elseif def["drawtype"] == "liquid" then
|
||||
if group_list_type == "whitelist" or group_list_type == "whitelist_source" then
|
||||
if compare_groups(group_list, def.groups or {}) then
|
||||
replace = true
|
||||
end
|
||||
elseif group_list_type == "blacklist" or group_list_type == "blacklist_source" then
|
||||
if not compare_groups(group_list, def.groups or {}) then
|
||||
replace = true
|
||||
end
|
||||
else
|
||||
replace = true
|
||||
end
|
||||
end
|
||||
|
||||
if replace then
|
||||
if n ~= "air" then
|
||||
count = count + 1 -- counting liquids
|
||||
end
|
||||
if replace_with_air then
|
||||
minetest.remove_node(p)
|
||||
else
|
||||
minetest.set_node(p, {name=modname..":liquid_stop"})
|
||||
end
|
||||
end
|
||||
minetest.set_node(p, {name=modname..":liquid_stop"})
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -138,19 +160,22 @@ local construct = function(pos, placer, itemstack, pointed_thing)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
minetest.register_node(modname..":liquid_stop", { -- air-like node
|
||||
description = "liquid blocker for sponges",
|
||||
drawtype = "airlike",
|
||||
drop = {max_items=0, items={}},
|
||||
groups = {not_in_creative_inventory=1},
|
||||
pointable = false,
|
||||
walkable = false,
|
||||
floodable = false,
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
buildable_to = true,
|
||||
})
|
||||
if replace_with_air then
|
||||
minetest.register_alias(modname..":liquid_stop", "air")
|
||||
else
|
||||
minetest.register_node(modname..":liquid_stop", { -- air-like node
|
||||
description = "liquid blocker for sponges",
|
||||
drawtype = "airlike",
|
||||
drop = {max_items=0, items={}},
|
||||
groups = {not_in_creative_inventory=1},
|
||||
pointable = false,
|
||||
walkable = false,
|
||||
floodable = false,
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
buildable_to = true,
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
minetest.register_node(modname..":sponge", { -- dry sponge
|
||||
|
@ -8,3 +8,13 @@ sponge_group_list (Group list) string water
|
||||
# If the groups in the group list should be treated as a whitelist or blacklist for removing liquids.
|
||||
# The *_source variants will remove all flowing liquids regardless of the list.
|
||||
sponge_group_list_type (Group list type) enum whitelist_source whitelist,whitelist_source,blacklist,blacklist_source,ignored
|
||||
|
||||
# Radius of sphere or cube of liquid that gets removed
|
||||
sponge_radius (Radius) float 4.5 1 39.9
|
||||
|
||||
# Whether to use a sphere shape to remove liquids
|
||||
sponge_shape_sphere (Sphere shape) bool true
|
||||
|
||||
# Replace liquids with air instead of liquid blocking nodes.
|
||||
# This causes water to flow back immediately after placing the sponge
|
||||
sponge_replace_with_air (Replace with air) bool false
|
||||
|
Loading…
Reference in New Issue
Block a user