forked from VoxeLibre/VoxeLibre
Add some growth for unloaded farming plants
This commit is contained in:
parent
766c76831d
commit
f2d68d909e
|
@ -1,22 +1,74 @@
|
|||
local plant_lists = {}
|
||||
local plant_nodename_to_id_list = {}
|
||||
|
||||
local function get_intervals_counter(pos, interval, chance)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local time_speed = tonumber(minetest.settings:get('time_speed') or 72)
|
||||
local current_game_time
|
||||
if time_speed == nil then
|
||||
return 1
|
||||
end
|
||||
if (time_speed < 0.1) then
|
||||
return 1
|
||||
end
|
||||
local time_multiplier = 86400 / time_speed
|
||||
current_game_time = .0 + ((minetest.get_day_count() + minetest.get_timeofday()) * time_multiplier)
|
||||
|
||||
local approx_interval = math.max(interval, 1) * math.max(chance, 1)
|
||||
|
||||
local last_game_time = meta:get_string("last_gametime")
|
||||
if last_game_time then
|
||||
last_game_time = tonumber(last_game_time)
|
||||
end
|
||||
if not last_game_time or last_game_time < 1 then
|
||||
last_game_time = current_game_time - approx_interval / 10
|
||||
elseif last_game_time == current_game_time then
|
||||
current_game_time = current_game_time + approx_interval
|
||||
end
|
||||
|
||||
local elapsed_game_time = .0 + current_game_time - last_game_time
|
||||
|
||||
meta:set_string("last_gametime", tostring(current_game_time))
|
||||
|
||||
return elapsed_game_time / approx_interval
|
||||
end
|
||||
|
||||
local function get_avg_light_level(pos)
|
||||
local node_light = tonumber(minetest.get_node_light(pos) or 0)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local counter = meta:get_int("avg_light_count")
|
||||
local summary = meta:get_int("avg_light_summary")
|
||||
if counter > 99 then
|
||||
counter = 51
|
||||
summary = math.ceil((summary + 0.0) / 2.0)
|
||||
else
|
||||
counter = counter + 1
|
||||
end
|
||||
summary = summary + node_light
|
||||
meta:set_int("avg_light_count", counter)
|
||||
meta:set_int("avg_light_summary", summary)
|
||||
return math.ceil((summary + 0.0) / counter)
|
||||
end
|
||||
|
||||
function mcl_farming:add_plant(identifier, full_grown, names, interval, chance)
|
||||
plant_lists[identifier] = {}
|
||||
plant_lists[identifier].full_grown = full_grown
|
||||
plant_lists[identifier].names = names
|
||||
plant_lists[identifier].interval = interval
|
||||
plant_lists[identifier].chance = chance
|
||||
minetest.register_abm({
|
||||
label = string.format("Farming plant growth (%s)", identifier),
|
||||
nodenames = names,
|
||||
interval = interval,
|
||||
chance = chance,
|
||||
action = function(pos, node)
|
||||
if minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name ~= "mcl_farming:soil_wet" and math.random(0, 9) > 0 then
|
||||
return
|
||||
else
|
||||
mcl_farming:grow_plant(identifier, pos, node)
|
||||
end
|
||||
local low_speed = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name ~= "mcl_farming:soil_wet"
|
||||
mcl_farming:grow_plant(identifier, pos, node, false, false, low_speed)
|
||||
end,
|
||||
})
|
||||
for _, nodename in pairs(names) do
|
||||
plant_nodename_to_id_list[nodename] = identifier
|
||||
end
|
||||
end
|
||||
|
||||
-- Attempts to advance a plant at pos by one or more growth stages (if possible)
|
||||
|
@ -28,15 +80,34 @@ end
|
|||
|
||||
-- Returns true if plant has been grown by 1 or more stages.
|
||||
-- Returns false if nothing changed.
|
||||
function mcl_farming:grow_plant(identifier, pos, node, stages, ignore_light)
|
||||
if not minetest.get_node_light(pos) and not ignore_light then
|
||||
function mcl_farming:grow_plant(identifier, pos, node, stages, ignore_light, low_speed)
|
||||
local average_light_level = get_avg_light_level(pos)
|
||||
local plant_info = plant_lists[identifier]
|
||||
local intervals_counter = get_intervals_counter(pos, plant_info.interval, plant_info.chance)
|
||||
local low_speed = low_speed or false
|
||||
if low_speed then
|
||||
if intervals_counter < 1.01 and math.random(0, 9) > 0 then
|
||||
return
|
||||
else
|
||||
intervals_counter = intervals_counter / 10
|
||||
end
|
||||
end
|
||||
if not minetest.get_node_light(pos) and not ignore_light and intervals_counter < 1.5 then
|
||||
return false
|
||||
end
|
||||
if minetest.get_node_light(pos) < 10 and not ignore_light then
|
||||
if minetest.get_node_light(pos) < 10 and not ignore_light and intervals_counter < 1.5 then
|
||||
return false
|
||||
end
|
||||
|
||||
local plant_info = plant_lists[identifier]
|
||||
if intervals_counter >= 1.5 then
|
||||
if average_light_level < 0.1 then
|
||||
return false
|
||||
end
|
||||
if average_light_level < 10 then
|
||||
intervals_counter = intervals_counter * average_light_level / 10
|
||||
end
|
||||
end
|
||||
|
||||
local step = nil
|
||||
|
||||
for i, name in ipairs(plant_info.names) do
|
||||
|
@ -51,6 +122,7 @@ function mcl_farming:grow_plant(identifier, pos, node, stages, ignore_light)
|
|||
if not stages then
|
||||
stages = 1
|
||||
end
|
||||
stages = stages + math.ceil(intervals_counter)
|
||||
local new_node = {name = plant_info.names[step+stages]}
|
||||
if new_node.name == nil then
|
||||
new_node.name = plant_info.full_grown
|
||||
|
@ -86,6 +158,7 @@ function mcl_farming:place_seed(itemstack, placer, pointed_thing, plantname)
|
|||
if string.find(farmland.name, "mcl_farming:soil") and string.find(place_s.name, "air") then
|
||||
minetest.sound_play(minetest.registered_nodes[plantname].sounds.place, {pos = pos}, true)
|
||||
minetest.add_node(pos, {name=plantname, param2 = minetest.registered_nodes[plantname].place_param2})
|
||||
local intervals_counter = get_intervals_counter(pos, 1, 1)
|
||||
else
|
||||
return
|
||||
end
|
||||
|
@ -379,3 +452,18 @@ function mcl_farming:stem_color(startcolor, endcolor, step, step_count)
|
|||
local colorstring = string.format("#%02X%02X%02X", color.r, color.g, color.b)
|
||||
return colorstring
|
||||
end
|
||||
|
||||
minetest.register_lbm({
|
||||
label = "Add growth for unloaded farming plants",
|
||||
name = "mcl_farming:growth",
|
||||
nodenames = {"group:plant"},
|
||||
run_at_every_load = true,
|
||||
action = function(pos, node)
|
||||
local identifier = plant_nodename_to_id_list[node.name]
|
||||
if not identifier then
|
||||
return
|
||||
end
|
||||
local low_speed = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name ~= "mcl_farming:soil_wet"
|
||||
mcl_farming:grow_plant(identifier, pos, node, false, false, low_speed)
|
||||
end,
|
||||
})
|
||||
|
|
Reference in New Issue