From bcaf8cc6743a17c0ad942c9a59a20f43f7ee68af Mon Sep 17 00:00:00 2001 From: philipmi Date: Wed, 9 Aug 2023 00:22:31 +0200 Subject: [PATCH] Revise and add API --- README.md | 40 +++++++-- compatibility.lua | 43 ++++++++++ init.lua | 208 +++++++++++++++++++++++----------------------- settingtypes.txt | 9 +- 4 files changed, 190 insertions(+), 110 deletions(-) create mode 100644 compatibility.lua diff --git a/README.md b/README.md index a323901..ef3d805 100644 --- a/README.md +++ b/README.md @@ -9,18 +9,48 @@ Regrowing Fruits Info ---- -This mod causes fruits on trees from various other mods to regrow like apples in the 5.0 release of Minetest Game. -If you placed the fruits by hand or removed the tree leaves, the fruits don't regrow. +This mod causes fruits on trees from various other mods to regrow like apples in the 5.0 release of Minetest Game. It also offers a small API to add fruit regrowth quickly. +If the fruit was placed by hand or the tree was chopped down, the fruit won't grow back. There is also a small chance that regrowth will stop randomly, so trees will bear less fruit over time. -Cool_trees modpack, ethereal, farming_plus, multibiomegen, australia, aotearoa and moretrees are currently supported. -Default apples in older versions than Minetest 5.0 will also regrow. +Currently supported mods/modpacks are: `default`, `ethereal`, `cool_trees`, `moretrees`, `farming_plus`, `multibiomegen`, `australia` and `aotearoa`. + +The standard regrowth time can be changed in settings (via `min_regrow_interval` and `max_regrow_interval`) as well as the chance of regrowth stopping (`regrowth_stop_chance`). Ideas, bug reports or requests for more mod support are always welcome in the [Minetest Forum topic](https://forum.minetest.net/viewtopic.php?f=9&t=24986) or via the [Git Issue Tracker](https://git.sp-codes.de/minetest/regrowing_fruits/issues)! +API +---- + +The `regrowing_fruits.add()` function overrides the fruits `after_dig_node` function and registers a placeholder node that will be placed once the fruit is taken and regrows the fruit after a timer expires. + +**Definition:** +``` +regrowing_fruits.add(fruitname, leafname, param2, multiplier) +``` + +* `fruitname`: nodename of the fruit to be added. +* `leafname`: nodename of the corresponding leaves (used as a reference whether tree is still alive). +* `param2`: param2 value of fruit when placed naturally (not by player). Defaults to 0; -1 disables param2 checks for fruit regrowth (use this if your fruit has different rotations). If set, overrides `after_place_node` of fruit node to be able to differentiate fruits by param2 when placed by player. +* `multiplier`: multiplier for the standard average regrowth time. + +**Examples:** + +``` +regrowing_fruits.add("default:apple", "default:leaves") +regrowing_fruits.add("ethereal:golden_apple", "ethereal:yellowleaves", nil, 3) +regrowing_fruits.add("cacaotree:pod", "cacaotree:trunk", -1) +``` +For more examples see [init.lua](init.lua). + +Alternatives Mods +---- + +Consider using `regrow` by TenPlus1. It has similar features, but registers only one placeholder node in total instead of one node for every fruit. + Credits ---- -This mod is inspired by "endless_apples" by Shara RedCat (2018). +This mod is based on "endless_apples" by Shara RedCat (2018). License ---- diff --git a/compatibility.lua b/compatibility.lua new file mode 100644 index 0000000..37e48ab --- /dev/null +++ b/compatibility.lua @@ -0,0 +1,43 @@ +-- aliases to ensure compatibility with previous versions +minetest.register_alias("regrowing_fruits:goldapple_mark", "ethereal:golden_apple_mark") +minetest.register_alias("regrowing_fruits:coollemon_mark", "lemontree:lemon_mark") +minetest.register_alias("regrowing_fruits:coolcoconut_mark", "palm:coconut_mark") +minetest.register_alias("regrowing_fruits:cacao", "cacaotree:pod") +minetest.register_alias("regrowing_fruits:apple_mark", "default:apple_mark") +minetest.register_alias("regrowing_fruits:banana_mark", "ethereal:banana_mark") +minetest.register_alias("regrowing_fruits:banana_bunch_mark", "ethereal:banana_bunch_mark") +minetest.register_alias("regrowing_fruits:coconut_mark", "ethereal:coconut_mark") +minetest.register_alias("regrowing_fruits:golden_apple_mark", "ethereal:golden_apple_mark") +minetest.register_alias("regrowing_fruits:lemon_mark", "ethereal:lemon_mark") +minetest.register_alias("regrowing_fruits:olive_mark", "ethereal:olive_mark") +minetest.register_alias("regrowing_fruits:orange_mark", "ethereal:orange_mark") +minetest.register_alias("regrowing_fruits:cacao_mark", "cacaotree:pod_mark") +minetest.register_alias("regrowing_fruits:cherry_mark", "cherrytree:cherries_mark") +minetest.register_alias("regrowing_fruits:chestnut_mark", "chestnuttree:bur_mark") +minetest.register_alias("regrowing_fruits:clementine_mark", "clementinetree:clementine_mark") +minetest.register_alias("regrowing_fruits:persimmon_mark", "ebony:persimmon_mark") +minetest.register_alias("regrowing_fruits:cool_lemon_mark", "lemontree:lemon_mark") +minetest.register_alias("regrowing_fruits:acorn_mark", "oak:acorn_mark") +minetest.register_alias("regrowing_fruits:cool_coconut_mark", "palm:coconut_mark") +minetest.register_alias("regrowing_fruits:plum_mark", "plumtree:plum_mark") +minetest.register_alias("regrowing_fruits:pomegranate_mark", "pomegranate:pomegranate_mark") +minetest.register_alias("regrowing_fruits:moreacorn_mark", "moretrees:acorn_mark") +minetest.register_alias("regrowing_fruits:cedar_cone_mark", "moretrees:cedar_cone_mark") +minetest.register_alias("regrowing_fruits:fir_cone_mark", "moretrees:fir_cone_mark") +minetest.register_alias("regrowing_fruits:spruce_cone_mark", "moretrees:spruce_cone_mark") +minetest.register_alias("regrowing_fruits:cocoa_mark", "farming_plus:cocoa_mark") +minetest.register_alias("regrowing_fruits:banana_plus_mark", "farming_plus:banana_mark") +for i=0,230 do + minetest.register_alias("regrowing_fruits:fruit_"..i.."_mark", "multibiomegen:fruit_"..i.."_mark") +end +minetest.register_alias("regrowing_fruits:australia_cherry_mark", "australia:cherry_mark") +minetest.register_alias("regrowing_fruits:lilly_pilly_berries_mark", "australia:lilly_pilly_berries_mark") +minetest.register_alias("regrowing_fruits:macadamia_mark", "australia:macadamia_mark") +minetest.register_alias("regrowing_fruits:mangrove_apple_mark", "australia:mangrove_apple_mark") +minetest.register_alias("regrowing_fruits:moreton_bay_fig_mark", "australia:moreton_bay_fig_mark") +minetest.register_alias("regrowing_fruits:quandong_mark", "australia:quandong_mark") +minetest.register_alias("regrowing_fruits:karaka_fruit_mark", "aotearoa:karaka_fruit_mark") +minetest.register_alias("regrowing_fruits:miro_fruit_mark", "aotearoa:miro_fruit_mark") +minetest.register_alias("regrowing_fruits:tawa_fruit_mark", "aotearoa:tawa_fruit_mark") +minetest.register_alias("regrowing_fruits:hinau_fruit_mark", "aotearoa:hinau_fruit_mark") +minetest.register_alias("regrowing_fruits:kawakawa_fruit_mark", "aotearoa:kawakawa_fruit_mark") \ No newline at end of file diff --git a/init.lua b/init.lua index a7e800f..79d1124 100644 --- a/init.lua +++ b/init.lua @@ -1,81 +1,87 @@ +regrowing_fruits = { --- get min and max regrow interval settings -local min_interval = tonumber(minetest.settings:get("min_regrow_interval")) or 300 -local max_interval = tonumber(minetest.settings:get("max_regrow_interval")) or 1500 + -- get standard min and max regrow interval from settings + min_interval = tonumber(minetest.settings:get("min_regrow_interval")) or 300, + max_interval = tonumber(minetest.settings:get("max_regrow_interval")) or 1500, -local add_fruit_regrowable = function(fruit, node, leaves) + -- get chance to stop regrowth + stop_chance = tonumber(minetest.settings:get("regrowth_stop_chance")) or 0.02 +} + +regrowing_fruits.add = function(fruitname, leafname, param2, multiplier) -- check if node exists - if not minetest.registered_nodes[node] then + if not minetest.registered_nodes[fruitname] then return end - -- make sure cacao pod from cool_trees isn't placed by player - if node == "cacaotree:pod" then - minetest.register_node("regrowing_fruits:cacao", { - description = "Cacao Pod", - drawtype = "nodebox", - tiles = { - "cacaotree_bean_top.png", - "cacaotree_bean_top.png^[transformFY", - "cacaotree_bean_right.png", - "cacaotree_bean_right.png^[transformFX", - "cacaotree_bean_front.png", - }, - paramtype = "light", - paramtype2 = "wallmounted", - node_box = { - type = "fixed", - fixed = { - {-0.25, -0.5, 0, 0.25, 0.0625, 0.5}, - }, - }, - use_texture_alpha = "clip", - drop = "cacaotree:cacao_beans 10", - groups = {fleshy = 3, dig_immediate = 3, flammable = 2, - leafdecay = 3, leafdecay_drop = 1, not_in_creative_inventory = 1}, - sounds = default.node_sound_leaves_defaults(), - walkable = false, - is_ground_content = false, - }) + local min = regrowing_fruits.min_interval + local max = regrowing_fruits.max_interval + local diff = regrowing_fruits.max_interval - regrowing_fruits.min_interval - minetest.register_on_placenode(function(pos, newnode, placer) - if placer and placer:is_player() and newnode.name == "cacaotree:pod" then - minetest.set_node(pos, {name = "regrowing_fruits:cacao", param2 = newnode.param2}) - end - end) + -- apply multiplier to standard min and max interval + if multiplier then + if multiplier >= 1 then + min = multiplier * (min/2 + max/2) - diff/2 * (1/2 + multiplier/2) + max = min + diff * (1/2 + multiplier/2) + else + min = multiplier * min + max = multiplier * max + end end - -- make sure (moretrees) fruits don't fall on dig - local groups = minetest.registered_nodes[node].groups + -- remove nodes from attached_node group (causes regrowth not to work) + local groups = minetest.registered_nodes[fruitname].groups groups.attached_node = 0 -- wait until mods are loaded to ensure that other mods do not override overrides - minetest.after(0.1, function() - -- override fruit - minetest.override_item(node, { - --groups = groups, - after_place_node = function(pos, placer) -- make sure (moretrees and plumtree) fruits aren't placed by player - if placer:is_player() and node == "plumtree:plum" then - minetest.set_node(pos, {name = node, param2 = 0}) - elseif placer:is_player() then - minetest.set_node(pos, {name = node, param2 = 1}) - end - end, - on_dig = minetest.node_dig, -- override on_dig functions causing regrowth not to work + minetest.after(0, function() + + local override = { + + -- override on_dig functions causing regrowth not to work + on_dig = minetest.node_dig, + + -- start regrowth after node has been dug after_dig_node = function(pos, oldnode, oldmetadata, digger) - if oldnode.param2 == 0 and oldnode.name ~= "plumtree:plum" - or oldnode.name == "plumtree:plum" and oldnode.param2 == 1 - or oldnode.name == "cacaotree:pod" then - minetest.set_node(pos, {name = "regrowing_fruits:"..fruit.."_mark", param2 = oldnode.param2}) - minetest.get_node_timer(pos):start(math.random(min_interval, max_interval)) + + -- make sure node wasn't placed by player + if oldnode.param2 == (param2 or 0) or param2 == -1 then + + -- apply chance of no fruit regrowth + if regrowing_fruits.stop_chance == 0 or math.random(1, 1/regrowing_fruits.stop_chance) ~= 1 then + + -- set fruit marker node for regrowth + minetest.set_node(pos, {name = fruitname.."_mark", param2 = oldnode.param2}) + + -- start regrowth timer + minetest.get_node_timer(pos):start(math.random(min, max)) + end end end, - }) + } + + -- set after_place_node if it is not defined or if param2 is available + if not (param2 and minetest.registered_nodes[fruitname].after_place_node) or param2 and param2 == 0 then + override.after_place_node = function(pos, placer) + if placer:is_player() then + minetest.set_node(pos, {name = fruitname, param2 = 1}) + end + end + elseif param2 and param2 > 0 then + override.after_place_node = function(pos, placer) + if placer:is_player() then + minetest.set_node(pos, {name = fruitname, param2 = 0}) + end + end + end + + -- override fruit + minetest.override_item(fruitname, override) end) -- air node to mark fruit pos - minetest.register_node("regrowing_fruits:"..fruit.."_mark", { + minetest.register_node(":"..fruitname.."_mark", { description = "Air!", drawtype = "airlike", paramtype = "light", @@ -87,72 +93,70 @@ local add_fruit_regrowable = function(fruit, node, leaves) drop = "", groups = {not_in_creative_inventory = 1}, on_timer = function(pos, elapsed) - if not minetest.find_node_near(pos, 1, leaves) then + if not minetest.find_node_near(pos, 1, leafname) then minetest.remove_node(pos) elseif minetest.get_node_light(pos) < 11 then minetest.get_node_timer(pos):start(200) else - minetest.set_node(pos, {name = node, param2 = minetest.get_node(pos).param2}) + minetest.set_node(pos, {name = fruitname, param2 = minetest.get_node(pos).param2}) end end }) end --- apples -add_fruit_regrowable("apple", "default:apple", {"default:leaves", "moretrees:apple_tree_leaves"}) +-- default +regrowing_fruits.add("default:apple", {"default:leaves", "moretrees:apple_tree_leaves"}) -- ethereal -add_fruit_regrowable("banana","ethereal:banana", "ethereal:bananaleaves") -add_fruit_regrowable("banana_bunch", "ethereal:banana_bunch", "ethereal:bananaleaves") -add_fruit_regrowable("coconut", "ethereal:coconut", "ethereal:palmleaves") -add_fruit_regrowable("golden_apple", "ethereal:golden_apple", "ethereal:yellowleaves") -add_fruit_regrowable("lemon", "ethereal:lemon", "ethereal:lemon_leaves") -add_fruit_regrowable("olive", "ethereal:olive", "ethereal:olive_leaves") -add_fruit_regrowable("orange", "ethereal:orange", "ethereal:orange_leaves") +regrowing_fruits.add("ethereal:banana", "ethereal:bananaleaves") +regrowing_fruits.add("ethereal:banana_bunch", "ethereal:bananaleaves") +regrowing_fruits.add("ethereal:coconut", "ethereal:palmleaves") +regrowing_fruits.add("ethereal:golden_apple", "ethereal:yellowleaves", nil, 3) +regrowing_fruits.add("ethereal:lemon", "ethereal:lemon_leaves") +regrowing_fruits.add("ethereal:olive", "ethereal:olive_leaves") +regrowing_fruits.add("ethereal:orange", "ethereal:orange_leaves") -- cool_trees -add_fruit_regrowable("cacao", "cacaotree:pod", "cacaotree:trunk") -- use trunk instead of leaves -add_fruit_regrowable("cherry", "cherrytree:cherries", "cherrytree:blossom_leaves") -add_fruit_regrowable("chestnut", "chestnuttree:bur", "chestnuttree:leaves") -add_fruit_regrowable("clementine", "clementinetree:clementine", "clementinetree:leaves") -add_fruit_regrowable("persimmon", "ebony:persimmon", "ebony:leaves") -add_fruit_regrowable("cool_lemon", "lemontree:lemon", "lemontree:leaves") -add_fruit_regrowable("acorn", "oak:acorn", "oak:leaves") -add_fruit_regrowable("cool_coconut", "palm:coconut", "palm:leaves") -add_fruit_regrowable("plum", "plumtree:plum", "plumtree:leaves") -add_fruit_regrowable("pomegranate", "pomegranate:pomegranate", "pomegranate:leaves") +regrowing_fruits.add("cacaotree:pod", "cacaotree:trunk", -1) -- use trunk instead of leaves +regrowing_fruits.add("cherrytree:cherries", "cherrytree:blossom_leaves") +regrowing_fruits.add("chestnuttree:bur", "chestnuttree:leaves") +regrowing_fruits.add("clementinetree:clementine", "clementinetree:leaves") +regrowing_fruits.add("ebony:persimmon", "ebony:leaves") +regrowing_fruits.add("lemontree:lemon", "lemontree:leaves") +regrowing_fruits.add("oak:acorn", "oak:leaves") +regrowing_fruits.add("palm:coconut", "palm:leaves") +regrowing_fruits.add("plumtree:plum", "plumtree:leaves") +regrowing_fruits.add("pomegranate:pomegranate", "pomegranate:leaves") -- moretrees -add_fruit_regrowable("moreacorn", "moretrees:acorn", "moretrees:oak_leaves") -add_fruit_regrowable("cedar_cone", "moretrees:cedar_cone", "moretrees:cedar_leaves") -add_fruit_regrowable("fir_cone", "moretrees:fir_cone", "moretrees:fir_leaves") -add_fruit_regrowable("spruce_cone", "moretrees:spruce_cone", "moretrees:spruce_leaves") +regrowing_fruits.add("moretrees:acorn", "moretrees:oak_leaves") +regrowing_fruits.add("moretrees:cedar_cone", "moretrees:cedar_leaves") +regrowing_fruits.add("moretrees:fir_cone", "moretrees:fir_leaves") +regrowing_fruits.add("moretrees:spruce_cone", "moretrees:spruce_leaves") -- farming_plus -add_fruit_regrowable("cocoa", "farming_plus:cocoa", "farming_plus:cocoa_leaves") -add_fruit_regrowable("banana_plus", "farming_plus:banana", "farming_plus:banana_leaves") +regrowing_fruits.add("farming_plus:cocoa", "farming_plus:cocoa_leaves") +regrowing_fruits.add("farming_plus:banana", "farming_plus:banana_leaves") -- multibiomegen for i=0,230 do - add_fruit_regrowable("fruit_"..i, "multibiomegen:fruit_"..i, "multibiomegen:leaf_"..i) + regrowing_fruits.add("multibiomegen:fruit_"..i, "multibiomegen:leaf_"..i) end -- australia -add_fruit_regrowable("australia_cherry", "australia:cherry", "australia:cherry_leaves") -add_fruit_regrowable("lilly_pilly_berries", "australia:lilly_pilly_berries", "australia:lilly_pilly_leaves") -add_fruit_regrowable("macadamia", "australia:macadamia", "australia:macadamia_leaves") -add_fruit_regrowable("mangrove_apple", "australia:mangrove_apple", "australia:mangrove_apple_leaves") -add_fruit_regrowable("moreton_bay_fig", "australia:moreton_bay_fig", "australia:moreton_bay_fig_leaves") -add_fruit_regrowable("quandong", "australia:quandong", "australia:quandong_leaves") +regrowing_fruits.add("australia:cherry", "australia:cherry_leaves") +regrowing_fruits.add("australia:lilly_pilly_berries", "australia:lilly_pilly_leaves") +regrowing_fruits.add("australia:macadamia", "australia:macadamia_leaves") +regrowing_fruits.add("australia:mangrove_apple", "australia:mangrove_apple_leaves") +regrowing_fruits.add("australia:moreton_bay_fig", "australia:moreton_bay_fig_leaves") +regrowing_fruits.add("australia:quandong", "australia:quandong_leaves") -- aotearoa -add_fruit_regrowable("karaka_fruit", "aotearoa:karaka_fruit", "aotearoa:karaka_leaves") -add_fruit_regrowable("miro_fruit", "aotearoa:miro_fruit", "aotearoa:miro_leaves") -add_fruit_regrowable("tawa_fruit", "aotearoa:tawa_fruit", "aotearoa:tawa_leaves") -add_fruit_regrowable("hinau_fruit", "aotearoa:hinau_fruit", "aotearoa:hinau_leaves") -add_fruit_regrowable("kawakawa_fruit", "aotearoa:kawakawa_fruit", "aotearoa:kawakawa_leaves") +regrowing_fruits.add("aotearoa:karaka_fruit", "aotearoa:karaka_leaves") +regrowing_fruits.add("aotearoa:miro_fruit", "aotearoa:miro_leaves") +regrowing_fruits.add("aotearoa:tawa_fruit", "aotearoa:tawa_leaves") +regrowing_fruits.add("aotearoa:hinau_fruit", "aotearoa:hinau_leaves") +regrowing_fruits.add("aotearoa:kawakawa_fruit", "aotearoa:kawakawa_leaves") --- aliases -minetest.register_alias("regrowing_fruits:goldapple_mark", "regrowing_fruits:golden_apple_mark") -minetest.register_alias("regrowing_fruits:coollemon_mark", "regrowing_fruits:cool_lemon_mark") -minetest.register_alias("regrowing_fruits:coolcoconut_mark", "regrowing_fruits:cool_coconut_mark") \ No newline at end of file +-- load compatibility for earlier versions +dofile(minetest.get_modpath("regrowing_fruits").."/compatibility.lua") \ No newline at end of file diff --git a/settingtypes.txt b/settingtypes.txt index c91486f..096ebaa 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -1,5 +1,8 @@ -# Minimum interval (in seconds) it takes to regrow fruits +# Standard minimum interval (in seconds) it takes to regrow fruits min_regrow_interval (Minimum Regrow Interval) int 300 -# Maximum interval (in seconds) it takes to regrow fruits -max_regrow_interval (Maximum Regrow Interval) int 1500 \ No newline at end of file +# Standard maximum interval (in seconds) it takes to regrow fruits +max_regrow_interval (Maximum Regrow Interval) int 1500 + +# Chance to stop regrowth of a fruit (Causes trees to bear less fruit over time; set to 0 to disable) +regrowth_stop_chance (Regrowth Stop Chance) float 0.02 \ No newline at end of file