diff --git a/df_caverns/primordial.lua b/df_caverns/primordial.lua index dc54889..d1c4bec 100644 --- a/df_caverns/primordial.lua +++ b/df_caverns/primordial.lua @@ -5,6 +5,7 @@ end local c_orb = minetest.get_content_id("df_primordial_items:glow_orb_hanging") local c_mycelial_dirt = minetest.get_content_id("df_primordial_items:dirt_with_mycelium") local c_dirt = minetest.get_content_id("default:dirt") +local c_giant_mycelium = minetest.get_content_id("df_primordial_items:giant_hypha_apical_mapgen") ----------------------------------------------------------------------------------------- @@ -47,7 +48,9 @@ local mushroom_cavern_floor = function(abs_cracks, humidity, vi, area, data, dat end local rand = math.random() * math.min(abs_cracks, 1) * humidityfactor - if rand < 0.01 then + if rand < 0.001 then + data[vi+ystride] = c_giant_mycelium + elseif rand < 0.01 then local schematic = df_primordial_items.get_primordial_mushroom() local rotation = (math.random(1,4)-1)*90 mapgen_helper.place_schematic_on_data_if_it_fits(data, data_param2, area, area:position(vi+ystride), schematic, rotation) @@ -65,7 +68,9 @@ local mushroom_cavern_ceiling = function(abs_cracks, humidity, vi, area, data, d data[vi] = c_mycelial_dirt if abs_cracks < 0.3 then local rand = math.random() * humidityfactor - if rand < 0.03 then + if rand < 0.003 then + data[vi-ystride] = c_giant_mycelium + elseif rand < 0.03 then df_primordial_items.spawn_ceiling_spire_vm(vi, area, data) elseif rand < 0.2 then data[vi-ystride] = c_orb @@ -81,7 +86,10 @@ local mushroom_warren_ceiling = function(abs_cracks, vi, area, data, data_param2 if abs_cracks < 0.3 then data[vi] = c_mycelial_dirt if abs_cracks < 0.2 then - if math.random() < 0.2 then + local rand = math.random() + if rand < 0.003 then + data[vi-ystride] = c_giant_mycelium + elseif rand < 0.2 then data[vi-ystride] = c_orb data_param2[vi-ystride] = math.random(0,179) end @@ -97,7 +105,9 @@ local mushroom_warren_floor = function(abs_cracks, vi, area, data, data_param2) data[vi] = c_dirt end local rand = math.random() * math.min(abs_cracks, 1) - if rand < 0.03 then + if rand < 0.001 then + data[vi+ystride] = c_giant_mycelium + elseif rand < 0.03 then data[vi+ystride] = plants[math.random(1,5)] end end diff --git a/df_primordial_items/ceiling_fungus.lua b/df_primordial_items/ceiling_fungus.lua index 77963c0..d24d2c5 100644 --- a/df_primordial_items/ceiling_fungus.lua +++ b/df_primordial_items/ceiling_fungus.lua @@ -38,7 +38,7 @@ minetest.register_node("df_primordial_items:glow_orb_hanging", { tiles = {"dfcaverns_mush_orb_vert.png"}, inventory_image = "dfcaverns_mush_orb_vert.png", wield_image = "dfcaverns_mush_orb_vert.png", - groups = {snappy = 3, flora = 1, attached_node = 1, flammable = 1}, + groups = {snappy = 3, flora = 1, flammable = 1}, paramtype = "light", paramtype2 = "degrotate", drawtype = "plantlike", diff --git a/df_primordial_items/giant_mycelium.lua b/df_primordial_items/giant_mycelium.lua index d3996cf..e03d701 100644 --- a/df_primordial_items/giant_mycelium.lua +++ b/df_primordial_items/giant_mycelium.lua @@ -2,30 +2,32 @@ local MP = minetest.get_modpath(minetest.get_current_modname()) local S, NS = dofile(MP.."/intllib.lua") -local hub_thickness = 0.1875--0.25 -local connector_thickness = 0.25--0.375 -local node_box = { - type = "connected", - fixed = {-hub_thickness,-hub_thickness,-hub_thickness,hub_thickness,hub_thickness,hub_thickness}, - connect_top = {-connector_thickness, 0, -connector_thickness, connector_thickness, 0.5, connector_thickness}, - connect_bottom = {-connector_thickness, -0.5, -connector_thickness, connector_thickness, 0, connector_thickness}, - connect_back = {-connector_thickness, -connector_thickness, 0, connector_thickness, connector_thickness, 0.5}, - connect_right = {0, -connector_thickness, -connector_thickness, 0.5, connector_thickness, connector_thickness}, - connect_front = {-connector_thickness, -connector_thickness, -0.5, connector_thickness, connector_thickness, 0}, - connect_left = {-0.5, -connector_thickness, -connector_thickness, 0, connector_thickness, connector_thickness}, - disconnected = {-connector_thickness,-connector_thickness,-connector_thickness,connector_thickness,connector_thickness,connector_thickness}, -} +-- hub_thickness -- the bit in the middle that's seen at the ends and corners of long hypha runs +-- connector_thickness +local get_node_box = function(hub_thickness, connector_thickness) + return { + type = "connected", + fixed = {-hub_thickness,-hub_thickness,-hub_thickness,hub_thickness,hub_thickness,hub_thickness}, + connect_top = {-connector_thickness, 0, -connector_thickness, connector_thickness, 0.5, connector_thickness}, + connect_bottom = {-connector_thickness, -0.5, -connector_thickness, connector_thickness, 0, connector_thickness}, + connect_back = {-connector_thickness, -connector_thickness, 0, connector_thickness, connector_thickness, 0.5}, + connect_right = {0, -connector_thickness, -connector_thickness, 0.5, connector_thickness, connector_thickness}, + connect_front = {-connector_thickness, -connector_thickness, -0.5, connector_thickness, connector_thickness, 0}, + connect_left = {-0.5, -connector_thickness, -connector_thickness, 0, connector_thickness, connector_thickness}, + disconnected = {-connector_thickness,-connector_thickness,-connector_thickness,connector_thickness,connector_thickness,connector_thickness}, + } +end minetest.register_node("df_primordial_items:giant_hypha_root", { description = S("Giant Hypha"), tiles = { - {name="dfcaverns_mush_stalk_side.png"}, + {name="dfcaverns_mush_giant_hypha.png"}, }, connects_to = {"group:soil", "group:hypha"}, connect_sides = { "top", "bottom", "front", "left", "back", "right" }, drawtype = "nodebox", - node_box = node_box, + node_box = get_node_box(0.1875, 0.25), paramtype = "light", light_source = 2, is_ground_content = false, @@ -35,12 +37,12 @@ minetest.register_node("df_primordial_items:giant_hypha_root", { minetest.register_node("df_primordial_items:giant_hypha", { description = S("Giant Hypha"), tiles = { - {name="dfcaverns_mush_stalk_side.png"}, + {name="dfcaverns_mush_giant_hypha.png"}, }, connects_to = {"group:hypha"}, connect_sides = { "top", "bottom", "front", "left", "back", "right" }, drawtype = "nodebox", - node_box = node_box, + node_box = get_node_box(0.1875, 0.25), paramtype = "light", light_source = 2, is_ground_content = false, @@ -48,23 +50,25 @@ minetest.register_node("df_primordial_items:giant_hypha", { sounds = default.node_sound_wood_defaults(), }) -local grow_mycelium = function(pos) +local find_mycelium_growth_targets = function(pos) local nodes = {} for x = -1, 1 do nodes[x] = {} for y = -1, 1 do nodes[x][y] = {} for z = -1, 1 do - local node = minetest.get_node({x=pos.x+x, y=pos.y+y, z=pos.z+z}) - local state = {} - if minetest.get_item_group(node.name, "soil") > 0 then - state.soil = true - elseif minetest.get_item_group(node.name, "hypha") > 0 then - state.hypha = true - elseif minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].buildable_to then - state.buildable = true + 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 state = {} + if minetest.get_item_group(node.name, "soil") > 0 then + state.soil = true + elseif minetest.get_item_group(node.name, "hypha") > 0 then + state.hypha = true + elseif minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].buildable_to then + state.buildable = true + end + nodes[x][y][z] = state end - nodes[x][y][z] = state end end end @@ -73,179 +77,215 @@ local grow_mycelium = function(pos) --copy and pasting is easy and nobody's going to decide whether to hire or fire me based on this --particular snippet of code so what the hell. I'll fix it later when that clever way comes to me. local valid_targets = {} - if nodes[-1][0][0].buildable then - if - -- test for soil to directly support new growth - (nodes[-1][-1][0].soil or - nodes[-1][1][0].soil or - nodes[-1][0][-1].soil or - nodes[-1][0][1].soil or - -- test for soil "around the corner" to allow for growth over an edge - nodes[0][-1][0].soil or - nodes[0][1][0].soil or - nodes[0][0][-1].soil or - nodes[0][0][1].soil) - and not -- no adjacent hypha - (nodes[-1][-1][0].hypha or - nodes[-1][1][0].hypha or - nodes[-1][0][-1].hypha or - nodes[-1][0][1].hypha) - then - table.insert(valid_targets, {x=pos.x-1, y=pos.y, z=pos.z}) - end + if nodes[-1][0][0].buildable and + -- test for soil to directly support new growth + (nodes[-1][-1][0].soil or + nodes[-1][1][0].soil or + nodes[-1][0][-1].soil or + nodes[-1][0][1].soil or + -- test for soil "around the corner" to allow for growth over an edge + nodes[0][-1][0].soil or + nodes[0][1][0].soil or + nodes[0][0][-1].soil or + nodes[0][0][1].soil) + and not -- no adjacent hypha + (nodes[-1][-1][0].hypha or + nodes[-1][1][0].hypha or + nodes[-1][0][-1].hypha or + nodes[-1][0][1].hypha) + then + table.insert(valid_targets, {x=pos.x-1, y=pos.y, z=pos.z}) end - if nodes[1][0][0].buildable then - if - -- test for soil to directly support new growth - (nodes[1][-1][0].soil or - nodes[1][1][0].soil or - nodes[1][0][-1].soil or - nodes[1][0][1].soil or - -- test for soil "around the corner" to allow for growth over an edge - nodes[0][-1][0].soil or - nodes[0][1][0].soil or - nodes[0][0][-1].soil or - nodes[0][0][1].soil) - and not -- no adjacent hypha - (nodes[1][-1][0].hypha or - nodes[1][1][0].hypha or - nodes[1][0][-1].hypha or - nodes[1][0][1].hypha) - then - table.insert(valid_targets, {x=pos.x+1, y=pos.y, z=pos.z}) - end + if nodes[1][0][0].buildable and + -- test for soil to directly support new growth + (nodes[1][-1][0].soil or + nodes[1][1][0].soil or + nodes[1][0][-1].soil or + nodes[1][0][1].soil or + -- test for soil "around the corner" to allow for growth over an edge + nodes[0][-1][0].soil or + nodes[0][1][0].soil or + nodes[0][0][-1].soil or + nodes[0][0][1].soil) + and not -- no adjacent hypha + (nodes[1][-1][0].hypha or + nodes[1][1][0].hypha or + nodes[1][0][-1].hypha or + nodes[1][0][1].hypha) + then + table.insert(valid_targets, {x=pos.x+1, y=pos.y, z=pos.z}) end - if nodes[0][-1][0].buildable then - if - -- test for soil to directly support new growth - (nodes[-1][-1][0].soil or - nodes[1][-1][0].soil or - nodes[0][-1][-1].soil or - nodes[0][-1][1].soil or - -- test for soil "around the corner" to allow for growth over an edge - nodes[-1][0][0].soil or - nodes[1][0][0].soil or - nodes[0][0][-1].soil or - nodes[0][0][1].soil) - and not -- no adjacent hypha - (nodes[-1][-1][0].hypha or - nodes[1][-1][0].hypha or - nodes[0][-1][-1].hypha or - nodes[0][-1][1].hypha) - then - table.insert(valid_targets, {x=pos.x, y=pos.y-1, z=pos.z}) - end + if nodes[0][-1][0].buildable and + -- test for soil to directly support new growth + (nodes[-1][-1][0].soil or + nodes[1][-1][0].soil or + nodes[0][-1][-1].soil or + nodes[0][-1][1].soil or + -- test for soil "around the corner" to allow for growth over an edge + nodes[-1][0][0].soil or + nodes[1][0][0].soil or + nodes[0][0][-1].soil or + nodes[0][0][1].soil) + and not -- no adjacent hypha + (nodes[-1][-1][0].hypha or + nodes[1][-1][0].hypha or + nodes[0][-1][-1].hypha or + nodes[0][-1][1].hypha) + then + table.insert(valid_targets, {x=pos.x, y=pos.y-1, z=pos.z}) end - if nodes[0][1][0].buildable then - if - -- test for soil to directly support new growth - (nodes[-1][1][0].soil or - nodes[1][1][0].soil or - nodes[0][1][-1].soil or - nodes[0][1][1].soil or - -- test for soil "around the corner" to allow for growth over an edge - nodes[-1][0][0].soil or - nodes[1][0][0].soil or - nodes[0][0][-1].soil or - nodes[0][0][1].soil) - and not -- no adjacent hypha - (nodes[-1][1][0].hypha or - nodes[1][1][0].hypha or - nodes[0][1][-1].hypha or - nodes[0][1][1].hypha) - then - table.insert(valid_targets, {x=pos.x, y=pos.y+1, z=pos.z}) - end + if nodes[0][1][0].buildable and + -- test for soil to directly support new growth + (nodes[-1][1][0].soil or + nodes[1][1][0].soil or + nodes[0][1][-1].soil or + nodes[0][1][1].soil or + -- test for soil "around the corner" to allow for growth over an edge + nodes[-1][0][0].soil or + nodes[1][0][0].soil or + nodes[0][0][-1].soil or + nodes[0][0][1].soil) + and not -- no adjacent hypha + (nodes[-1][1][0].hypha or + nodes[1][1][0].hypha or + nodes[0][1][-1].hypha or + nodes[0][1][1].hypha) + then + table.insert(valid_targets, {x=pos.x, y=pos.y+1, z=pos.z}) end - if nodes[0][0][-1].buildable then - if - -- test for soil to directly support new growth - (nodes[-1][0][-1].soil or - nodes[1][0][-1].soil or - nodes[0][-1][-1].soil or - nodes[0][1][-1].soil or - -- test for soil "around the corner" to allow for growth over an edge - nodes[-1][0][0].soil or - nodes[1][0][0].soil or - nodes[0][-1][0].soil or - nodes[0][1][0].soil) - and not -- no adjacent hypha - (nodes[-1][0][-1].hypha or - nodes[1][0][-1].hypha or - nodes[0][-1][-1].hypha or - nodes[0][1][-1].hypha) - then - table.insert(valid_targets, {x=pos.x, y=pos.y, z=pos.z-1}) - end + if nodes[0][0][-1].buildable and + -- test for soil to directly support new growth + (nodes[-1][0][-1].soil or + nodes[1][0][-1].soil or + nodes[0][-1][-1].soil or + nodes[0][1][-1].soil or + -- test for soil "around the corner" to allow for growth over an edge + nodes[-1][0][0].soil or + nodes[1][0][0].soil or + nodes[0][-1][0].soil or + nodes[0][1][0].soil) + and not -- no adjacent hypha + (nodes[-1][0][-1].hypha or + nodes[1][0][-1].hypha or + nodes[0][-1][-1].hypha or + nodes[0][1][-1].hypha) + then + table.insert(valid_targets, {x=pos.x, y=pos.y, z=pos.z-1}) end - if nodes[0][0][1].buildable then - if - -- test for soil to directly support new growth - (nodes[-1][0][1].soil or - nodes[1][0][1].soil or - nodes[0][-1][1].soil or - nodes[0][1][1].soil or - -- test for soil "around the corner" to allow for growth over an edge - nodes[-1][0][0].soil or - nodes[1][0][0].soil or - nodes[0][-1][0].soil or - nodes[0][1][0].soil) - and not -- no adjacent hypha - (nodes[-1][0][1].hypha or - nodes[1][0][1].hypha or - nodes[0][-1][1].hypha or - nodes[0][1][1].hypha) - then - table.insert(valid_targets, {x=pos.x, y=pos.y, z=pos.z+1}) - end + if nodes[0][0][1].buildable and + -- test for soil to directly support new growth + (nodes[-1][0][1].soil or + nodes[1][0][1].soil or + nodes[0][-1][1].soil or + nodes[0][1][1].soil or + -- test for soil "around the corner" to allow for growth over an edge + nodes[-1][0][0].soil or + nodes[1][0][0].soil or + nodes[0][-1][0].soil or + nodes[0][1][0].soil) + and not -- no adjacent hypha + (nodes[-1][0][1].hypha or + nodes[1][0][1].hypha or + nodes[0][-1][1].hypha or + nodes[0][1][1].hypha) + then + table.insert(valid_targets, {x=pos.x, y=pos.y, z=pos.z+1}) end return valid_targets end +local grow_mycelium = function(pos, meristem_name) + local new_meristems = {} + -- Can we grow? If so, pick a random direction and add a new meristem there + local targets = find_mycelium_growth_targets(pos) + local target_count = #targets + if target_count > 0 then + local target = targets[math.random(1,target_count)] + minetest.set_node(target, {name=meristem_name}) + table.insert(new_meristems, target) + else + --nowhere to grow, turn into a rooted hypha and we're done + minetest.set_node(pos, {name="df_primordial_items:giant_hypha_root"}) + return new_meristems + end + + if math.random() < 0.05 then + -- Split - try again from here next time + table.insert(new_meristems, pos) + -- Otherwise, just turn into a hypha and we're done + elseif math.random() < 0.333 then + minetest.set_node(pos, {name="df_primordial_items:giant_hypha_root"}) + else + minetest.set_node(pos, {name="df_primordial_items:giant_hypha"}) + end + return new_meristems +end + +local min_growth_delay = minetest.settings:get_key("dfcaverns_mycelium_min_growth_delay") or 240 +local max_growth_delay = minetest.settings:get_key("dfcaverns_mycelium_max_growth_delay") or 400 minetest.register_node("df_primordial_items:giant_hypha_apical_meristem", { description = S("Giant Hypha Apical Meristem"), tiles = { - {name="dfcaverns_mush_stalk_side.png^[brighten"}, + {name="dfcaverns_mush_giant_hypha.png^[brighten"}, }, connects_to = {"group:hypha"}, connect_sides = { "top", "bottom", "front", "left", "back", "right" }, drawtype = "nodebox", light_source = 6, - node_box = { - type = "connected", - fixed = {-0.25,-0.25,-0.25,0.25,0.25,0.25}, - connect_top = {-0.375, 0, -0.375, 0.375, 0.5, 0.375}, - connect_bottom = {-0.375, -0.5, -0.375, 0.375, 0, 0.375}, - connect_back = {-0.375, -0.375, 0, 0.375, 0.375, 0.5}, - connect_right = {0, -0.375, -0.375, 0.5, 0.375, 0.375}, - connect_front = {-0.375, -0.375, -0.5, 0.375, 0.375, 0}, - connect_left = {-0.5, -0.375, -0.375, 0, 0.375, 0.375}, - disconnected = {-0.375,-0.375,-0.375,0.375,0.375,0.375}, - }, + node_box = get_node_box(0.25, 0.375), paramtype = "light", is_ground_content = false, - groups = {oddly_breakable_by_hand = 1, choppy = 2, hypha =1}, + groups = {oddly_breakable_by_hand = 1, choppy = 2, hypha = 1, light_sensitive_fungus = 13}, sounds = default.node_sound_wood_defaults(), on_construct = function(pos) - minetest.get_node_timer(pos):start(1.0) + minetest.get_node_timer(pos):start(math.random(min_growth_delay,max_growth_delay)) end, on_timer = function(pos, elapsed) - --if math.random() < 0.99 then - local targets = grow_mycelium(pos) - local target_count = #targets - if target_count > 0 then - minetest.set_node(targets[math.random(1,target_count)], {name="df_primordial_items:giant_hypha_apical_meristem"}) - end - --end - if math.random() < 0.05 then - minetest.get_node_timer(pos):start(1.0) -- branch - elseif math.random() < 0.5 then - minetest.set_node(pos, {name="df_primordial_items:giant_hypha_root"}) - else - minetest.set_node(pos, {name="df_primordial_items:giant_hypha"}) + local new_meristems = grow_mycelium(pos, "df_primordial_items:giant_hypha_apical_meristem") + for _, newpos in ipairs(new_meristems) do + minetest.get_node_timer(newpos):start(math.random(min_growth_delay,max_growth_delay)) end end, }) + +-- this version grows instantly via ABM, is meant for mapgen usage +minetest.register_node("df_primordial_items:giant_hypha_apical_mapgen", { + description = S("Giant Hypha Apical Meristem"), + tiles = { + {name="dfcaverns_mush_giant_hypha.png^[brighten"}, + }, + connects_to = {"group:hypha"}, + connect_sides = { "top", "bottom", "front", "left", "back", "right" }, + drawtype = "nodebox", + light_source = 6, + node_box = get_node_box(0.25, 0.375), + paramtype = "light", + + is_ground_content = false, + groups = {oddly_breakable_by_hand = 1, choppy = 2, hypha = 1, light_sensitive_fungus = 13}, + sounds = default.node_sound_wood_defaults(), +}) + +df_primordial_items.grow_mycelium_immediately = function(pos) + local stack = {pos} + while #stack > 0 do + local pos = table.remove(stack) + local new_poses = grow_mycelium(pos, "df_primordial_items:giant_hypha_apical_meristem") + for _, new_pos in ipairs(new_poses) do + table.insert(stack, new_pos) + end + end +end + +minetest.register_abm({ + label = "Mycelium mapgen growth", + nodenames = {"df_primordial_items:giant_hypha_apical_mapgen"}, + interval = 1.0, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + df_primordial_items.grow_mycelium_immediately(pos) + end +}) diff --git a/df_primordial_items/settingtypes.txt b/df_primordial_items/settingtypes.txt new file mode 100644 index 0000000..48d1f7a --- /dev/null +++ b/df_primordial_items/settingtypes.txt @@ -0,0 +1,2 @@ +dfcaverns_mycelium_min_growth_delay (Minimum mycelium growth delay) int 240 +dfcaverns_mycelium_max_growth_delay (Maximum mycelium growth delay) int 400 \ No newline at end of file diff --git a/df_primordial_items/textures/dfcaverns_mush_giant_hypha.png b/df_primordial_items/textures/dfcaverns_mush_giant_hypha.png new file mode 100644 index 0000000..246e3f1 Binary files /dev/null and b/df_primordial_items/textures/dfcaverns_mush_giant_hypha.png differ