From 0da14dbb5609f9593a62d459f63c04e455113302 Mon Sep 17 00:00:00 2001
From: Auke Kok <sofar@foo-projects.org>
Date: Sun, 6 Mar 2016 21:39:07 -0800
Subject: [PATCH] cherry-pick from github.com/minetest/minetest_game> Default:
 Convert saplings to use node timers

Each sapling is given a single node timer that is between
2 and 4 days of game play time (40-80 minutes). If you walk out
of the zone, and come back later, the tree will always grow
to full if the timer has elapsed.

Because trees.lua is all functions, it needs to be parsed before
nodes.lua, since that references some of its functions. Hence,
change the order of parsing here. Otherwise saplings would not
grow to full.
---
 mods/default/init.lua  |  2 +-
 mods/default/nodes.lua | 20 +++++++++
 mods/default/trees.lua | 99 ++++++++++++++++++++++--------------------
 3 files changed, 73 insertions(+), 48 deletions(-)

diff --git a/mods/default/init.lua b/mods/default/init.lua
index 6f1b148b..b362fc75 100644
--- a/mods/default/init.lua
+++ b/mods/default/init.lua
@@ -36,6 +36,7 @@ default.gui_survival_form = "size[8,8.5]"..
 
 -- Load files
 dofile(minetest.get_modpath("default").."/functions.lua")
+dofile(minetest.get_modpath("default").."/trees.lua")
 dofile(minetest.get_modpath("default").."/nodes.lua")
 dofile(minetest.get_modpath("default").."/furnace.lua")
 dofile(minetest.get_modpath("default").."/tools.lua")
@@ -43,6 +44,5 @@ dofile(minetest.get_modpath("default").."/craftitems.lua")
 dofile(minetest.get_modpath("default").."/crafting.lua")
 dofile(minetest.get_modpath("default").."/mapgen.lua")
 dofile(minetest.get_modpath("default").."/player.lua")
-dofile(minetest.get_modpath("default").."/trees.lua")
 dofile(minetest.get_modpath("default").."/aliases.lua")
 dofile(minetest.get_modpath("default").."/legacy.lua")
diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua
index 26ffa02a..6a3afda1 100644
--- a/mods/default/nodes.lua
+++ b/mods/default/nodes.lua
@@ -455,6 +455,10 @@ minetest.register_node("default:sapling", {
 	paramtype = "light",
 	sunlight_propagates = true,
 	walkable = false,
+	on_timer = default.grow_sapling,
+	on_construct = function(pos)
+		minetest.get_node_timer(pos):start(math.random(2400,4800))
+	end,
 	selection_box = {
 		type = "fixed",
 		fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
@@ -573,6 +577,10 @@ minetest.register_node("default:junglesapling", {
 	paramtype = "light",
 	sunlight_propagates = true,
 	walkable = false,
+	on_timer = default.grow_sapling,
+	on_construct = function(pos)
+		minetest.get_node_timer(pos):start(math.random(2400,4800))
+	end,
 	selection_box = {
 		type = "fixed",
 		fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
@@ -634,6 +642,10 @@ minetest.register_node("default:pine_sapling", {
 	paramtype = "light",
 	sunlight_propagates = true,
 	walkable = false,
+	on_timer = default.grow_sapling,
+	on_construct = function(pos)
+		minetest.get_node_timer(pos):start(math.random(2400,4800))
+	end,
 	selection_box = {
 		type = "fixed",
 		fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
@@ -695,6 +707,10 @@ minetest.register_node("default:acacia_sapling", {
 	paramtype = "light",
 	sunlight_propagates = true,
 	walkable = false,
+	on_timer = default.grow_sapling,
+	on_construct = function(pos)
+		minetest.get_node_timer(pos):start(math.random(2400,4800))
+	end,
 	selection_box = {
 		type = "fixed",
 		fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
@@ -755,6 +771,10 @@ minetest.register_node("default:aspen_sapling", {
 	paramtype = "light",
 	sunlight_propagates = true,
 	walkable = false,
+	on_timer = default.grow_sapling,
+	on_construct = function(pos)
+		minetest.get_node_timer(pos):start(math.random(2400,4800))
+	end,
 	selection_box = {
 		type = "fixed",
 		fixed = {-0.3, -0.5, -0.3, 0.3, 0.35, 0.3}
diff --git a/mods/default/trees.lua b/mods/default/trees.lua
index de2452e4..1b062660 100644
--- a/mods/default/trees.lua
+++ b/mods/default/trees.lua
@@ -59,57 +59,62 @@ end
 
 -- Sapling ABM
 
-minetest.register_abm({
-	nodenames = {"default:sapling", "default:junglesapling",
-		"default:pine_sapling", "default:acacia_sapling",
-		"default:aspen_sapling"},
-	interval = 10,
-	chance = 50,
-	action = function(pos, node)
-		if not default.can_grow(pos) then
-			return
-		end
+function default.grow_sapling(pos)
+	if not default.can_grow(pos) then
+		-- try a bit later again
+		minetest.get_node_timer(pos):start(math.random(240, 600))
+		return
+	end
 
-		local mapgen = minetest.get_mapgen_params().mgname
-		if node.name == "default:sapling" then
-			minetest.log("action", "A sapling grows into a tree at "..
-				minetest.pos_to_string(pos))
-			if mapgen == "v6" then
-				default.grow_tree(pos, random(1, 4) == 1)
-			else
-				default.grow_new_apple_tree(pos)
-			end
-		elseif node.name == "default:junglesapling" then
-			minetest.log("action", "A jungle sapling grows into a tree at "..
-				minetest.pos_to_string(pos))
-			if mapgen == "v6" then
-				default.grow_jungle_tree(pos)
-			else
-				default.grow_new_jungle_tree(pos)
-			end
-		elseif node.name == "default:pine_sapling" then
-			minetest.log("action", "A pine sapling grows into a tree at "..
-				minetest.pos_to_string(pos))
-			local snow = is_snow_nearby(pos)
-			if mapgen == "v6" then
-				default.grow_pine_tree(pos, snow)
-			elseif snow then
-				default.grow_new_snowy_pine_tree(pos)
-			else
-				default.grow_new_pine_tree(pos)
-			end
-		elseif node.name == "default:acacia_sapling" then
-			minetest.log("action", "An acacia sapling grows into a tree at "..
-				minetest.pos_to_string(pos))
-			default.grow_new_acacia_tree(pos)
-		elseif node.name == "default:aspen_sapling" then
-			minetest.log("action", "An aspen sapling grows into a tree at "..
-				minetest.pos_to_string(pos))
-			default.grow_new_aspen_tree(pos)
+	local mapgen = minetest.get_mapgen_params().mgname
+	local node = minetest.get_node(pos)
+	if node.name == "default:sapling" then
+		minetest.log("action", "A sapling grows into a tree at "..
+			minetest.pos_to_string(pos))
+		if mapgen == "v6" then
+			default.grow_tree(pos, random(1, 4) == 1)
+		else
+			default.grow_new_apple_tree(pos)
+		end
+	elseif node.name == "default:junglesapling" then
+		minetest.log("action", "A jungle sapling grows into a tree at "..
+			minetest.pos_to_string(pos))
+		if mapgen == "v6" then
+			default.grow_jungle_tree(pos)
+		else
+			default.grow_new_jungle_tree(pos)
 		end
+	elseif node.name == "default:pine_sapling" then
+		minetest.log("action", "A pine sapling grows into a tree at "..
+			minetest.pos_to_string(pos))
+		local snow = is_snow_nearby(pos)
+		if mapgen == "v6" then
+			default.grow_pine_tree(pos, snow)
+		elseif snow then
+			default.grow_new_snowy_pine_tree(pos)
+		else
+			default.grow_new_pine_tree(pos)
+		end
+	elseif node.name == "default:acacia_sapling" then
+		minetest.log("action", "An acacia sapling grows into a tree at "..
+			minetest.pos_to_string(pos))
+		default.grow_new_acacia_tree(pos)
+	elseif node.name == "default:aspen_sapling" then
+		minetest.log("action", "An aspen sapling grows into a tree at "..
+			minetest.pos_to_string(pos))
+		default.grow_new_aspen_tree(pos)
 	end
-})
+end
 
+minetest.register_lbm({
+	name = "default:convert_saplings_to_node_timer",
+	nodenames = {"default:sapling", "default:junglesapling",
+			"default:pine_sapling", "default:acacia_sapling",
+			"default:aspen_sapling"},
+	action = function(pos)
+		minetest.get_node_timer(pos):start(math.random(1200, 2400))
+	end
+})
 
 --
 -- Tree generation
-- 
GitLab