mirror of
https://github.com/FaceDeer/dfcaverns.git
synced 2024-12-26 02:40:36 +01:00
allow mycelium growth to pause when it hits unloaded areas
This commit is contained in:
parent
b2b5231c43
commit
63efbf6179
@ -1,3 +1,5 @@
|
|||||||
|
-- This file defines a type of root-like growth that spreads over the surface of the ground in a random web-like pattern
|
||||||
|
|
||||||
-- internationalization boilerplate
|
-- internationalization boilerplate
|
||||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
local MP = minetest.get_modpath(minetest.get_current_modname())
|
||||||
local S, NS = dofile(MP.."/intllib.lua")
|
local S, NS = dofile(MP.."/intllib.lua")
|
||||||
@ -18,7 +20,6 @@ local get_node_box = function(hub_thickness, connector_thickness)
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
minetest.register_node("df_primordial_items:giant_hypha_root", {
|
minetest.register_node("df_primordial_items:giant_hypha_root", {
|
||||||
description = S("Rooted Giant Hypha"),
|
description = S("Rooted Giant Hypha"),
|
||||||
tiles = {
|
tiles = {
|
||||||
@ -50,6 +51,12 @@ minetest.register_node("df_primordial_items:giant_hypha", {
|
|||||||
sounds = default.node_sound_wood_defaults(),
|
sounds = default.node_sound_wood_defaults(),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
-- Check each of the six cardinal directions to see if it's buildable-to,
|
||||||
|
-- if it has an adjacent "soil" node (or if it's going out over the corner of an adjacent soil node),
|
||||||
|
-- and does *not* have an adjacent hypha already.
|
||||||
|
-- By growing with these conditions hyphae will hug the ground and will not immediately loop back on themselves
|
||||||
|
-- (though they can run into other pre-existing growths, forming larger loops - which is fine, large loops are nice)
|
||||||
|
|
||||||
local find_mycelium_growth_targets = function(pos)
|
local find_mycelium_growth_targets = function(pos)
|
||||||
local nodes = {}
|
local nodes = {}
|
||||||
for x = -1, 1 do
|
for x = -1, 1 do
|
||||||
@ -59,8 +66,13 @@ local find_mycelium_growth_targets = function(pos)
|
|||||||
for z = -1, 1 do
|
for z = -1, 1 do
|
||||||
if not (x == y and y == z) then -- we don't care about the diagonals or the center node
|
if not (x == y and y == z) then -- we don't care about the diagonals or the center node
|
||||||
local node = minetest.get_node({x=pos.x+x, y=pos.y+y, z=pos.z+z})
|
local node = minetest.get_node({x=pos.x+x, y=pos.y+y, z=pos.z+z})
|
||||||
|
if node.name == "ignore" then
|
||||||
|
-- Pause growth! We're at the edge of the known world.
|
||||||
|
return nil
|
||||||
|
end
|
||||||
local state = {}
|
local state = {}
|
||||||
if minetest.get_item_group(node.name, "soil") > 0 then
|
if minetest.get_item_group(node.name, "soil") > 0 or
|
||||||
|
minetest.get_item_group(node.name, "stone") > 0 and math.random() < 0.5 then -- let hyphae explore out over stone
|
||||||
state.soil = true
|
state.soil = true
|
||||||
elseif minetest.get_item_group(node.name, "hypha") > 0 then
|
elseif minetest.get_item_group(node.name, "hypha") > 0 then
|
||||||
state.hypha = true
|
state.hypha = true
|
||||||
@ -199,6 +211,11 @@ local grow_mycelium = function(pos, meristem_name)
|
|||||||
local new_meristems = {}
|
local new_meristems = {}
|
||||||
-- Can we grow? If so, pick a random direction and add a new meristem there
|
-- Can we grow? If so, pick a random direction and add a new meristem there
|
||||||
local targets = find_mycelium_growth_targets(pos)
|
local targets = find_mycelium_growth_targets(pos)
|
||||||
|
|
||||||
|
if targets == nil then
|
||||||
|
return nil -- We hit the edge of the known world, pause!
|
||||||
|
end
|
||||||
|
|
||||||
local target_count = #targets
|
local target_count = #targets
|
||||||
if target_count > 0 then
|
if target_count > 0 then
|
||||||
local target = targets[math.random(1,target_count)]
|
local target = targets[math.random(1,target_count)]
|
||||||
@ -257,11 +274,16 @@ minetest.register_node("df_primordial_items:giant_hypha_apical_meristem", {
|
|||||||
local new_stack = {} -- populate this with new node output.
|
local new_stack = {} -- populate this with new node output.
|
||||||
for _, stackpos in ipairs(stack) do -- for each currently growing location
|
for _, stackpos in ipairs(stack) do -- for each currently growing location
|
||||||
local ret = grow_mycelium(stackpos, "df_primordial_items:giant_hypha_apical_meristem")
|
local ret = grow_mycelium(stackpos, "df_primordial_items:giant_hypha_apical_meristem")
|
||||||
|
if ret == nil then
|
||||||
|
-- We hit the edge of the known world, stop and retry later
|
||||||
|
minetest.get_node_timer(stackpos):start(math.random(min_growth_delay,max_growth_delay))
|
||||||
|
else
|
||||||
for _, retpos in ipairs(ret) do
|
for _, retpos in ipairs(ret) do
|
||||||
-- put the new locations into new_stack
|
-- put the new locations into new_stack
|
||||||
table.insert(new_stack, retpos)
|
table.insert(new_stack, retpos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
stack = new_stack -- replace the old stack with the new
|
stack = new_stack -- replace the old stack with the new
|
||||||
end
|
end
|
||||||
for _, donepos in ipairs(stack) do
|
for _, donepos in ipairs(stack) do
|
||||||
@ -271,10 +293,15 @@ minetest.register_node("df_primordial_items:giant_hypha_apical_meristem", {
|
|||||||
else
|
else
|
||||||
-- just do one iteration.
|
-- just do one iteration.
|
||||||
local new_meristems = grow_mycelium(pos, "df_primordial_items:giant_hypha_apical_meristem")
|
local new_meristems = grow_mycelium(pos, "df_primordial_items:giant_hypha_apical_meristem")
|
||||||
|
if new_meristems == nil then
|
||||||
|
-- We hit the end of the known world, try again later. Unlikely in this case, but theoretically possible I guess.
|
||||||
|
minetest.get_node_timer(pos):start(math.random(min_growth_delay,max_growth_delay))
|
||||||
|
else
|
||||||
for _, newpos in ipairs(new_meristems) do
|
for _, newpos in ipairs(new_meristems) do
|
||||||
minetest.get_node_timer(newpos):start(math.random(min_growth_delay,max_growth_delay))
|
minetest.get_node_timer(newpos):start(math.random(min_growth_delay,max_growth_delay))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -296,16 +323,18 @@ minetest.register_node("df_primordial_items:giant_hypha_apical_mapgen", {
|
|||||||
sounds = default.node_sound_wood_defaults(),
|
sounds = default.node_sound_wood_defaults(),
|
||||||
})
|
})
|
||||||
|
|
||||||
df_primordial_items.grow_mycelium_immediately = function(pos)
|
local grow_mycelium_immediately = function(pos)
|
||||||
local stack = {pos}
|
local stack = {pos}
|
||||||
while #stack > 0 do
|
while #stack > 0 do
|
||||||
local pos = table.remove(stack)
|
local pos = table.remove(stack)
|
||||||
local new_poses = grow_mycelium(pos, "df_primordial_items:giant_hypha_apical_meristem")
|
local new_poses = grow_mycelium(pos, "df_primordial_items:giant_hypha_apical_mapgen")
|
||||||
|
if new_poses then -- if we hit the end of the world, just stop. There'll be a mapgen meristem left here, the abm will re-trigger it when the player gets close.
|
||||||
for _, new_pos in ipairs(new_poses) do
|
for _, new_pos in ipairs(new_poses) do
|
||||||
table.insert(stack, new_pos)
|
table.insert(stack, new_pos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
minetest.register_abm({
|
minetest.register_abm({
|
||||||
label = "Mycelium mapgen growth",
|
label = "Mycelium mapgen growth",
|
||||||
@ -313,6 +342,6 @@ minetest.register_abm({
|
|||||||
interval = 1.0,
|
interval = 1.0,
|
||||||
chance = 1,
|
chance = 1,
|
||||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||||
df_primordial_items.grow_mycelium_immediately(pos)
|
grow_mycelium_immediately(pos)
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user