From 69e3dd99e90bf05fa89a757439e3fa0794bddbab Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Thu, 5 May 2022 10:01:51 +0200 Subject: [PATCH] Enforce sapling space checks before growing --- mods/rp_default/functions.lua | 50 +++++++++++++++++++++++++++++++++++ mods/rp_supertools/init.lua | 3 +-- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/mods/rp_default/functions.lua b/mods/rp_default/functions.lua index 172d9a2..1fb5c65 100644 --- a/mods/rp_default/functions.lua +++ b/mods/rp_default/functions.lua @@ -1,6 +1,10 @@ local water_level = tonumber(minetest.get_mapgen_setting("water_level")) local S = minetest.get_translator("rp_default") +-- If a sapling fails to grow, check the sapling again after this many seconds +local SAPLING_RECHECK_TIME_MIN = 60 +local SAPLING_RECHECK_TIME_MAX = 70 + -- -- Functions/ABMs -- @@ -90,10 +94,18 @@ local tree_data = { ["apple"] = { schem = "default_appletree.mts", offset = vector.new(-2, -1, -2), + space = { + { vector.new(0,0,0), vector.new(0,2,0) }, + { vector.new(-2,3,-2), vector.new(2,5,2) }, + }, }, ["oak"] = { schem = "default_oaktree.mts", offset = vector.new(-2, -1, -2), + space = { + { vector.new(0,0,0), vector.new(0,2,0) }, + { vector.new(-1,3,-1), vector.new(1,5,1) }, + }, }, ["birch"] = { schem = "default_squaretree.mts", @@ -103,14 +115,46 @@ local tree_data = { ["rp_default:apple"] = "air" }, offset = vector.new(-1, -1, -1), + space = { + { vector.new(0,0,0), vector.new(0,1,0) }, + { vector.new(-1,2,-1), vector.new(1,4,1) }, + }, }, ["dry_bush"] = { schem = "default_dry_bush.mts", offset = vector.new(-1, -1, -1), + space = { + { vector.new(0,0,0), vector.new(0,1,0) }, + }, }, } function default.check_sapling_space(pos, variety) + local tdata = tree_data[variety] + if not tdata then + return false + end + local space = tdata.space + for i=1, #space do + local min, max = space[i][1], space[i][2] + min = vector.add(pos, min) + max = vector.add(pos, max) + + -- Every node of the volume needs to be air, + -- so we calculate the volume first + local required_airs = (max.x - min.x + 1) * (max.y - min.y + 1) * (max.z - min.z + 1) + + -- If pos is inside the volume, don’t count it (cut it’s the sapling) + if pos.x >= min.x and pos.y >= min.y and pos.z >= min.z and pos.x <= max.x and pos.y <= max.y and pos.z <= max.z then + required_airs = required_airs - 1 + end + local _, counts = minetest.find_nodes_in_area(min, max, {"air"}, false) + local counted_airs = counts.air + if counted_airs < required_airs then + return false + end + end + return true end -- Start the sapling grow timer of the sapling at pos. @@ -152,6 +196,12 @@ function default.grow_sapling(pos) end local variety = sdata.grows_to + local enough_space = default.check_sapling_space(pos, variety) + if not enough_space then + minetest.get_node_timer(pos):start(math.random(SAPLING_RECHECK_TIME_MIN, SAPLING_RECHECK_TIME_MAX)) + return false + end + minetest.remove_node(pos) minetest.after(0, grow, variety) diff --git a/mods/rp_supertools/init.lua b/mods/rp_supertools/init.lua index 1b0d405..739a113 100644 --- a/mods/rp_supertools/init.lua +++ b/mods/rp_supertools/init.lua @@ -27,8 +27,7 @@ minetest.register_craftitem( local diff = vector.subtract(apos, upos) local used = false if minetest.get_item_group(unode.name, "sapling") ~= 0 then - default.grow_sapling(upos) - used = true + used = default.grow_sapling(upos) elseif diff.y > 0 and unode.name == "rp_default:dirt_with_grass" and anode.name == "air" then minetest.set_node(apos, {name="rp_default:grass"}) used = true