From b42dc75140dc2b74b61935a36875558f13607a1a Mon Sep 17 00:00:00 2001 From: Blockhead Date: Mon, 24 Oct 2022 23:39:44 +1100 Subject: [PATCH 1/3] Move sapling growth to nodetimer --- FIXME | 4 +- init.lua | 8 +- nodes/trees.lua | 42 ++++++++- saplings.lua | 241 ++++++++++++++++++++++-------------------------- 4 files changed, 155 insertions(+), 140 deletions(-) diff --git a/FIXME b/FIXME index 25054ab..c38c9de 100644 --- a/FIXME +++ b/FIXME @@ -9,7 +9,8 @@ * Woodship schematic as MTS * U-boat schematic as MTS * ABMs: Conversion to LBMs or nodetimers where appropriate, especially shipwrecks - * Tree growth to nodetimers (according to MTG practice) + * Coral ABMs to nodetimers + * Shipwreck LBMs? * Bonemeal support? * Tree Schematics with no sapling: * Small river oak (river_oak_small_tree) @@ -23,6 +24,7 @@ * Reproduction of smaller plants like spinifex, mitchell grass * Bonemeal addon? * Cultivation item(s)? +* Internationalise strings # Biomes testing coords Mapgen is always carpathian. Teleportation is not safe unless you have fly! diff --git a/init.lua b/init.lua index 8909eea..0e3ca3d 100755 --- a/init.lua +++ b/init.lua @@ -24,17 +24,17 @@ aus.schematics = {} -- Load files +dofile(aus.path .. "/tree_gen.lua") +dofile(aus.path .. "/nulda.lua") dofile(aus.path .. "/schematics.lua") dofile(aus.path .. "/schematics_commands.lua") dofile(aus.path .. "/decorations.lua") -dofile(aus.path .. "/nulda.lua") +dofile(aus.path .. "/mapgen.lua") +dofile(aus.path .. "/saplings.lua") dofile(aus.path .. "/nodes.lua") dofile(aus.path .. "/noairblocks.lua") dofile(aus.path .. "/craftitems.lua") dofile(aus.path .. "/crafting.lua") -dofile(aus.path .. "/tree_gen.lua") -dofile(aus.path .. "/mapgen.lua") -dofile(aus.path .. "/saplings.lua") --dofile(aus.path .. "/voxel.lua") -- Clear schematic-generating objects that are no longer needed diff --git a/nodes/trees.lua b/nodes/trees.lua index 7510065..b669b37 100644 --- a/nodes/trees.lua +++ b/nodes/trees.lua @@ -124,13 +124,31 @@ for _, treedef in ipairs(aus.treelist) do }) -- sapling - minetest.register_node("australia:"..treename.."_sapling", { + local saplingname = "australia:"..treename.."_sapling" + local sapling_texname = "aus_"..treesapling.."_sapling.png" + --[[print(saplingname) + print(dump(aus.saplings2schems))--]] + local sapling_schems = aus.saplings2schems[saplingname] + local sap_max_size_x = 0 + local sap_max_size_y = 0 + local sap_max_size_z = 0 + for schemidx, schem in pairs(sapling_schems) do + sap_max_size_x = math.max(sap_max_size_x, schem.size.x) + sap_max_size_y = math.max(sap_max_size_y, schem.size.y) + sap_max_size_z = math.max(sap_max_size_z, schem.size.z) + end + -- Due to rotations, we have to always check the largest axis. They should + -- be equal anyway. + local sap_max_bounds_horiz = math.floor(math.max(sap_max_size_x, sap_max_size_z)/2) + local sap_size = vector.new(sap_max_size_x, sap_max_size_y, sap_max_size_z) + + minetest.register_node(saplingname, { description = treedesc.." Sapling", drawtype = "plantlike", visual_scale = 1.0, - tiles = {"aus_"..treesapling.."_sapling.png"}, - inventory_image = "aus_"..treesapling.."_sapling.png", - wield_image = "aus_"..treesapling.."_sapling.png", + tiles = {sapling_texname}, + inventory_image = sapling_texname, + wield_image = sapling_texname, paramtype = "light", sunlight_propagates = true, walkable = false, @@ -139,8 +157,22 @@ for _, treedef in ipairs(aus.treelist) do type = "fixed", fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3} }, - groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1}, + groups = {snappy=2,dig_immediate=3,flammable=2,attached_node=1,sapling=1}, sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(300, 1500)) --300,1500 mtg default + end, + on_timer = aus.grow_sapling, + + on_place = function(itemstack, placer, pointed_thing) + return default.sapling_on_place(itemstack, placer, pointed_thing, + itemstack:get_name(), + vector.new(-sap_max_bounds_horiz, 1, -sap_max_bounds_horiz), + vector.new(sap_max_bounds_horiz, sap_max_size_y, sap_max_bounds_horiz), + 4 + ) + end }) -- fruit, if applicable diff --git a/saplings.lua b/saplings.lua index be0ced8..1da3d39 100755 --- a/saplings.lua +++ b/saplings.lua @@ -3,138 +3,119 @@ -- -- list of all saplings -aus.saplings = { - {sapling="australia:black_box_sapling", - schematics=aus.schematics.black_box_tree}, - {sapling="australia:black_wattle_sapling", - schematics=aus.schematics.black_wattle_tree}, - {sapling="australia:blue_gum_sapling", - schematics=aus.schematics.blue_gum_tree}, - {sapling="australia:boab_sapling", - schematics=aus.schematics.boab_tree}, - {sapling="australia:bull_banksia_sapling", - schematics=aus.schematics.bull_banksia_tree}, - {sapling="australia:celery_top_pine_sapling", - schematics=aus.schematics.celery_top_pine_tree}, - {sapling="australia:cherry_sapling", - schematics=aus.schematics.cherry_tree}, - {sapling="australia:cloncurry_box_sapling", - schematics=aus.schematics.cloncurry_box_tree}, - {sapling="australia:coast_banksia_sapling", - schematics=aus.schematics.coast_banksia_big_tree}, - {sapling="australia:coolabah_sapling", - schematics=aus.schematics.coolabah_tree}, - {sapling="australia:daintree_stringybark_sapling", - schematics=aus.schematics.daintree_stringybark_tree}, - {sapling="australia:darwin_woollybutt_sapling", - schematics=aus.schematics.darwin_woollybutt_tree}, - {sapling="australia:desert_oak_sapling", - schematics=aus.schematics.desert_oak_tree}, - {sapling="australia:fan_palm_sapling", - schematics=aus.schematics.fan_palm_tree}, - {sapling="australia:golden_wattle_sapling", - schematics=aus.schematics.golden_wattle_tree}, - {sapling="australia:grey_mangrove_sapling", - schematics=aus.schematics.grey_mangrove_tree}, - {sapling="australia:huon_pine_sapling", - schematics=aus.schematics.huon_pine_tree}, - {sapling="australia:illawarra_flame_sapling", - schematics=aus.schematics.illawarra_flame_tree}, - {sapling="australia:jarrah_sapling", - schematics=aus.schematics.jarrah_tree}, - {sapling="australia:karri_sapling", - schematics=aus.schematics.karri_tree}, - {sapling="australia:lemon_eucalyptus_sapling", - schematics=aus.schematics.lemon_eucalyptus_tree}, - {sapling="australia:lemon_myrtle_sapling", - schematics=aus.schematics.lemon_myrtle_tree}, - {sapling="australia:lilly_pilly_sapling", - schematics=aus.schematics.lilly_pilly_tree}, - {sapling="australia:macadamia_sapling", - schematics=aus.schematics.macadamia_tree}, - {sapling="australia:mangrove_apple_sapling", - schematics=aus.schematics.mangrove_apple_tree}, - {sapling="australia:marri_sapling", - schematics=aus.schematics.marri_tree}, - {sapling="australia:merbau_sapling", - schematics=aus.schematics.merbau_tree}, - {sapling="australia:moreton_bay_fig_sapling", - schematics=aus.schematics.moreton_bay_fig_tree}, - {sapling="australia:mulga_sapling", - schematics=aus.schematics.mulga_tree}, - {sapling="australia:paperbark_sapling", - schematics=aus.schematics.paperbark_tree}, - {sapling="australia:quandong_sapling", - schematics=aus.schematics.quandong_tree}, - {sapling="australia:red_bottlebrush_sapling", - schematics=aus.schematics.red_bottlebrush_tree}, +aus.saplings2schems = { + ["australia:black_box_sapling"] = + aus.schematics.black_box_tree, + ["australia:black_wattle_sapling"] = + aus.schematics.black_wattle_tree, + ["australia:blue_gum_sapling"] = + aus.schematics.blue_gum_tree, + ["australia:boab_sapling"] = + aus.schematics.boab_tree, + ["australia:bull_banksia_sapling"] = + aus.schematics.bull_banksia_tree, + ["australia:celery_top_pine_sapling"] = + aus.schematics.celery_top_pine_tree, + ["australia:cherry_sapling"] = + aus.schematics.cherry_tree, + ["australia:cloncurry_box_sapling"] = + aus.schematics.cloncurry_box_tree, + ["australia:coast_banksia_sapling"] = + aus.schematics.coast_banksia_big_tree, + ["australia:coolabah_sapling"] = + aus.schematics.coolabah_tree, + ["australia:daintree_stringybark_sapling"] = + aus.schematics.daintree_stringybark_tree, + ["australia:darwin_woollybutt_sapling"] = + aus.schematics.darwin_woollybutt_tree, + ["australia:desert_oak_sapling"] = + aus.schematics.desert_oak_tree, + ["australia:fan_palm_sapling"] = + aus.schematics.fan_palm_tree, + ["australia:golden_wattle_sapling"] = + aus.schematics.golden_wattle_tree, + ["australia:grey_mangrove_sapling"] = + aus.schematics.grey_mangrove_tree, + ["australia:huon_pine_sapling"] = + aus.schematics.huon_pine_tree, + ["australia:illawarra_flame_sapling"] = + aus.schematics.illawarra_flame_tree, + ["australia:jarrah_sapling"] = + aus.schematics.jarrah_tree, + ["australia:karri_sapling"] = + aus.schematics.karri_tree, + ["australia:lemon_eucalyptus_sapling"] = + aus.schematics.lemon_eucalyptus_tree, + ["australia:lemon_myrtle_sapling"] = + aus.schematics.lemon_myrtle_tree, + ["australia:lilly_pilly_sapling"] = + aus.schematics.lilly_pilly_tree, + ["australia:macadamia_sapling"] = + aus.schematics.macadamia_tree, + ["australia:mangrove_apple_sapling"] = + aus.schematics.mangrove_apple_tree, + ["australia:marri_sapling"] = + aus.schematics.marri_tree, + ["australia:merbau_sapling"] = + aus.schematics.merbau_tree, + ["australia:moreton_bay_fig_sapling"] = + aus.schematics.moreton_bay_fig_tree, + ["australia:mulga_sapling"] = + aus.schematics.mulga_tree, + ["australia:paperbark_sapling"] = + aus.schematics.paperbark_tree, + ["australia:quandong_sapling"] = + aus.schematics.quandong_tree, + ["australia:red_bottlebrush_sapling"] = + aus.schematics.red_bottlebrush_tree, -- @@@ Josselin2 --- {sapling="australia:river_oak_sapling", --- schematics=aus.schematics.river_oak_tree}, - {sapling="australia:river_oak_sapling", - schematics=aus.schematics.river_oak_big_tree}, - {sapling="australia:river_red_gum_sapling", - schematics=aus.schematics.river_red_gum_tree}, - {sapling="australia:rottnest_island_pine_sapling", - schematics=aus.schematics.rottnest_island_pine_tree}, - {sapling="australia:scribbly_gum_sapling", - schematics=aus.schematics.scribbly_gum_tree}, - {sapling="australia:shoestring_acacia_sapling", - schematics=aus.schematics.shoestring_acacia_tree}, - {sapling="australia:snow_gum_sapling", - schematics=aus.schematics.snow_gum_tree}, - {sapling="australia:southern_sassafras_sapling", - schematics=aus.schematics.southern_sassafras_tree}, - {sapling="australia:stilted_mangrove_sapling", - schematics=aus.schematics.stilted_mangrove_tree}, - {sapling="australia:sugar_gum_sapling", - schematics=aus.schematics.sugar_gum_tree}, - {sapling="australia:swamp_bloodwood_sapling", - schematics=aus.schematics.swamp_bloodwood_tree}, - {sapling="australia:swamp_gum_sapling", - schematics=aus.schematics.swamp_gum_tree}, - {sapling="australia:swamp_paperbark_sapling", - schematics=aus.schematics.swamp_paperbark_tree}, - {sapling="australia:tasmanian_myrtle_sapling", - schematics=aus.schematics.tasmanian_myrtle_tree}, - {sapling="australia:tea_tree_sapling", - schematics=aus.schematics.tea_tree_tree}, - {sapling="australia:white_box_sapling", - schematics=aus.schematics.white_box_tree}, - {sapling="australia:wirewood_sapling", - schematics=aus.schematics.wirewood_tree}, +-- ["australia:river_oak_sapling"] = +-- aus.schematics.river_oak_tree, + ["australia:river_oak_sapling"] = + aus.schematics.river_oak_big_tree, + ["australia:river_red_gum_sapling"] = + aus.schematics.river_red_gum_tree, + ["australia:rottnest_island_pine_sapling"] = + aus.schematics.rottnest_island_pine_tree, + ["australia:scribbly_gum_sapling"] = + aus.schematics.scribbly_gum_tree, + ["australia:shoestring_acacia_sapling"] = + aus.schematics.shoestring_acacia_tree, + ["australia:snow_gum_sapling"] = + aus.schematics.snow_gum_tree, + ["australia:southern_sassafras_sapling"] = + aus.schematics.southern_sassafras_tree, + ["australia:stilted_mangrove_sapling"] = + aus.schematics.stilted_mangrove_tree, + ["australia:sugar_gum_sapling"] = + aus.schematics.sugar_gum_tree, + ["australia:swamp_bloodwood_sapling"] = + aus.schematics.swamp_bloodwood_tree, + ["australia:swamp_gum_sapling"] = + aus.schematics.swamp_gum_tree, + ["australia:swamp_paperbark_sapling"] = + aus.schematics.swamp_paperbark_tree, + ["australia:tasmanian_myrtle_sapling"] = + aus.schematics.tasmanian_myrtle_tree, + ["australia:tea_tree_sapling"] = + aus.schematics.tea_tree_tree, + ["australia:white_box_sapling"] = + aus.schematics.white_box_tree, + ["australia:wirewood_sapling"] = + aus.schematics.wirewood_tree, } --- create a list of just the node names -local sapling_list = {} -for _, sap in pairs(aus.saplings) do - table.insert(sapling_list, sap.sapling) -end - --- This abm can handle all saplings. -minetest.register_abm({ - nodenames = sapling_list, - interval = 10, - chance = 50, - action = function(pos, node) - local node_under = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z}) - if not node_under or - minetest.get_item_group(node_under.name, "soil") == 0 then - return - end +function aus.grow_sapling(pos) + local node = minetest.get_node(pos) + local schems = aus.saplings2schems[node.name] + assert(schems ~= nil, string.format("No such sapling registered: %s @%s", node.name, pos)) - for _, sap in pairs(aus.saplings) do - if node.name == sap.sapling then - minetest.log("action", "A sapling grows into a tree at ".. - minetest.pos_to_string(pos)) - local schem = sap.schematics[math.random(1,#sap.schematics)] - local adj = {x = pos.x - math.floor(schem.size.x / 2), - y = pos.y - 1, - z = pos.z - math.floor(schem.size.z / 2)} + minetest.log("action", string.format("[Australia] %s sapling grows into a tree at %s", + node.name, minetest.pos_to_string(pos))) + local schem = schems[math.random(1,#schems)] + local adj = {x = pos.x - math.floor(schem.size.x / 2), + y = pos.y - 1, + z = pos.z - math.floor(schem.size.z / 2)} - minetest.place_schematic(adj, schem, 'random', nil, true) - break - end - end - end, -}) + minetest.place_schematic(adj, schem, 'random', nil, true) +end From 4d56aaffbb96dc0bd86516250bbdcb7b1c23aebe Mon Sep 17 00:00:00 2001 From: Blockhead Date: Tue, 25 Oct 2022 15:23:39 +1100 Subject: [PATCH 2/3] Scale tree growth by volume of nodes Also fix leaf decay radii for Celery Top Pine and Australian Cherry. The growth rate is scaled based on the number of trunks, leaves and fruits on average for each of the tree's schematics. Leaves and fruit weigh 1/3 the value of a trunk node; this is called the tree mass. Tree-mass is then scaled nonlinearly to make smaller trees grow relatively faster than larger trees; the function was made with the help of GeoGebra. --- README.md | 5 +++++ nodes/trees.lua | 15 ++++++++------- saplings.lua | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 9e3a342..5ef9413 100755 --- a/README.md +++ b/README.md @@ -115,6 +115,11 @@ All biomes are enabled by default. Currently, disabling the *Underground* biome ## Changelog +### 0.5.2 +* Trees' growth rate is now scaled by their volume. Bigger trees grow slower +than smaller trees, at a bias for smaller trees. +* Internally, trees now use nodetimers instead of ABMs. + ### 0.5.1 * Australian trees now finally support leaf decay. * A new series of commands will let server operators spawn aus schematics. diff --git a/nodes/trees.lua b/nodes/trees.lua index b669b37..5addd75 100644 --- a/nodes/trees.lua +++ b/nodes/trees.lua @@ -9,8 +9,8 @@ aus.treelist = { {"blue_gum", "Eucalyptus globulus: Blue Gum", 1.0, "eucalyptus", nil, nil, nil, nil, 3}, {"boab", "Adansonia gregorii: Boab", 1.0, "boab", nil, nil, nil, nil, 3}, {"bull_banksia", "Banksia grandis: Bull Banksia", 0.33, "banksia", nil, nil, nil, nil, 3}, - {"celery_top_pine", "Phyllocladus aspleniifolius: Celery-top Pine", 1, "pine", nil, nil, nil, nil, vector.new(3,4,3)}, - {"cherry", "Exocarpos cupressiformis: Australian Cherry", 0.5, "berry", "cherry", "Australian Cherries", 0.67, 1, 3}, + {"celery_top_pine", "Phyllocladus aspleniifolius: Celery-top Pine", 1, "pine", nil, nil, nil, nil, vector.new(4,6,4)}, + {"cherry", "Exocarpos cupressiformis: Australian Cherry", 0.5, "berry", "cherry", "Australian Cherries", 0.67, 1, vector.new(3,4,3)}, {"cloncurry_box", "Eucalyptus leucophylla: Cloncurry Box", 1.0, "eucalyptus", nil, nil, nil, nil, 3}, {"coast_banksia", "Banksia integrifolia: Coast Banksia", 1.0, "banksia", nil, nil, nil, nil, 3}, {"coolabah", "Eucalyptus coolabah: Coolabah", 1.0, "eucalyptus", nil, nil, nil, nil, 3}, @@ -126,8 +126,6 @@ for _, treedef in ipairs(aus.treelist) do -- sapling local saplingname = "australia:"..treename.."_sapling" local sapling_texname = "aus_"..treesapling.."_sapling.png" - --[[print(saplingname) - print(dump(aus.saplings2schems))--]] local sapling_schems = aus.saplings2schems[saplingname] local sap_max_size_x = 0 local sap_max_size_y = 0 @@ -141,6 +139,8 @@ for _, treedef in ipairs(aus.treelist) do -- be equal anyway. local sap_max_bounds_horiz = math.floor(math.max(sap_max_size_x, sap_max_size_z)/2) local sap_size = vector.new(sap_max_size_x, sap_max_size_y, sap_max_size_z) + local sap_growthrate_a, sap_growthrate_b = aus.sapling_growthrate( + sapling_schems, saplingname, (treefruit and "australia:"..treefruit)) minetest.register_node(saplingname, { description = treedesc.." Sapling", @@ -161,7 +161,8 @@ for _, treedef in ipairs(aus.treelist) do sounds = default.node_sound_leaves_defaults(), on_construct = function(pos) - minetest.get_node_timer(pos):start(math.random(300, 1500)) --300,1500 mtg default + minetest.get_node_timer(pos):start(math.random( + sap_growthrate_a, sap_growthrate_b)) end, on_timer = aus.grow_sapling, @@ -170,7 +171,7 @@ for _, treedef in ipairs(aus.treelist) do itemstack:get_name(), vector.new(-sap_max_bounds_horiz, 1, -sap_max_bounds_horiz), vector.new(sap_max_bounds_horiz, sap_max_size_y, sap_max_bounds_horiz), - 4 + 4 -- kind of a magic number but meh ) end }) @@ -178,7 +179,7 @@ for _, treedef in ipairs(aus.treelist) do -- fruit, if applicable local treefruit_name if treefruit then - treefruit_name = "australia:"..treefruit.."" + treefruit_name = "australia:"..treefruit minetest.register_node(treefruit_name, { description = treefruit_desc, drawtype = "plantlike", diff --git a/saplings.lua b/saplings.lua index 1da3d39..d193762 100755 --- a/saplings.lua +++ b/saplings.lua @@ -106,6 +106,12 @@ aus.saplings2schems = { } function aus.grow_sapling(pos) + if not default.can_grow(pos) then + -- Try again 2 minutes later (we'll be more generous than default because + -- some trees take ages) + minetest.get_node_timer(pos):start(120) + return + end local node = minetest.get_node(pos) local schems = aus.saplings2schems[node.name] assert(schems ~= nil, string.format("No such sapling registered: %s @%s", node.name, pos)) @@ -119,3 +125,33 @@ function aus.grow_sapling(pos) minetest.place_schematic(adj, schem, 'random', nil, true) end + +function aus.sapling_growthrate(schems, species, fruit) + local nschems = #schems + local node_counts = {} + for schem_idx, schem in pairs(schems) do + for data_idx, data_point in pairs(schem.data) do + local nodename = data_point.name + node_counts[nodename] = (node_counts[nodename] or 0) + 1 + end + end + local treemass = 0 + for node, count in pairs(node_counts) do + local avg_count = node_counts[node] / nschems + node_counts[node] = avg_count + if node:match("tree") then + treemass = treemass + avg_count + elseif node:match("leaves") + or (fruit and node:match(fruit)) + then + -- Leaves and fruit take less to grow than wood (but leaves + -- sometimes simulate branches, so not a huge penalty to mass either) + treemass = treemass + (1/3) * avg_count + end + end + + -- Slight bias in favour of smaller trees + -- From lightest (golden wattle) to heaviest (river red gum) this means 10-57+-10% minute wait times + local avg_time = 10*treemass^0.7 + 500 + return 0.9*avg_time, 1.1*avg_time +end From 519596e1c108944f4fca069cc6760b13255ec21c Mon Sep 17 00:00:00 2001 From: Maverick2797 <49946595+Maverick2797@users.noreply.github.com> Date: Sun, 22 Jan 2023 23:39:51 +0800 Subject: [PATCH 3/3] Add bonemeal compatability Use bonemeal on saplings to grow the relevant tree --- mod.conf | 2 +- saplings.lua | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/mod.conf b/mod.conf index 44a37fc..f35f242 100755 --- a/mod.conf +++ b/mod.conf @@ -2,5 +2,5 @@ name = australia title = Australia description = Adds Australian map generation to Minetest Game, including many species of native flora. depends = default, flowers -optional_depends = technic_worldgen, bucket, stairs +optional_depends = technic_worldgen, bucket, stairs, bonemeal supported_games = minetest_game diff --git a/saplings.lua b/saplings.lua index d193762..04609a2 100755 --- a/saplings.lua +++ b/saplings.lua @@ -155,3 +155,12 @@ function aus.sapling_growthrate(schems, species, fruit) local avg_time = 10*treemass^0.7 + 500 return 0.9*avg_time, 1.1*avg_time end + +-- add bonemeal compatability for saplings +if minetest.get_modpath("bonemeal") then + for sapling in pairs(aus.saplings2schems) do + bonemeal:add_sapling({ + {sapling, aus.grow_sapling, "group:soil"} + }) + end +end