1
0
mirror of https://codeberg.org/tenplus1/farming.git synced 2025-06-29 14:50:52 +02:00

separate food /non-food items from crop files, tidy code

This commit is contained in:
tenplus1
2024-08-11 15:38:55 +01:00
parent cdac09a8f4
commit a9a1b720a3
57 changed files with 3691 additions and 3271 deletions

239
init.lua
View File

@ -5,6 +5,11 @@
auto-refill by crabman77
]]
-- Translation support
local S = minetest.get_translator("farming")
-- set global
farming = {
mod = "redo",
version = "20240811",
@ -22,7 +27,8 @@ farming = {
use_utensils = minetest.settings:get_bool("farming_use_utensils") ~= false,
mtg = minetest.get_modpath("default"),
mcl = minetest.get_modpath("mcl_core"),
mcl_hardness = 0.01
mcl_hardness = 0.01,
translate = S
}
-- determine which sounds to use, default or mcl_sounds
@ -46,36 +52,28 @@ sound_helper("node_sound_water_defaults")
sound_helper("node_sound_snow_defaults")
sound_helper("node_sound_glass_defaults")
-- check for creative mode or priv
local creative_mode_cache = minetest.settings:get_bool("creative_mode")
function farming.is_creative(name)
return creative_mode_cache or minetest.check_player_privs(name, {creative = true})
end
-- stats, locals, settings, function helper
local statistics = dofile(farming.path .. "/statistics.lua")
-- Translation support
local S = minetest.get_translator("farming")
farming.translate = S
-- localise
local random = math.random
local floor = math.floor
-- Utility Function
local time_speed = tonumber(minetest.settings:get("time_speed")) or 72
local SECS_PER_CYCLE = (time_speed > 0 and (24 * 60 * 60) / time_speed) or 0
local function clamp(x, min, max)
return (x < min and min) or (x > max and max) or x
end
-- return amount of day or night that has elapsed
-- dt is time elapsed, count_day if true counts day, otherwise night
local function day_or_night_time(dt, count_day)
local t_day = minetest.get_timeofday()
@ -104,7 +102,9 @@ local function day_or_night_time(dt, count_day)
local dt_c = clamp(t2_c, 0, 0.5) - clamp(t1_c, 0, 0.5) -- this cycle
if t1_c < -0.5 then
local nc = floor(-t1_c)
t1_c = t1_c + nc
dt_c = dt_c + 0.5 * nc + clamp(-t1_c - 0.5, 0, 0.5)
end
@ -112,14 +112,13 @@ local function day_or_night_time(dt, count_day)
return dt_c * SECS_PER_CYCLE
end
-- Growth Logic
local STAGE_LENGTH_AVG = tonumber(
minetest.settings:get("farming_stage_length")) or 200
local STAGE_LENGTH_AVG = tonumber(minetest.settings:get("farming_stage_length")) or 200
local STAGE_LENGTH_DEV = STAGE_LENGTH_AVG / 6
-- quick start seed timer
farming.start_seed_timer = function(pos)
local timer = minetest.get_node_timer(pos)
@ -128,16 +127,15 @@ farming.start_seed_timer = function(pos)
timer:start(grow_time)
end
-- return plant name and stage from node provided
local function plant_name_stage(node)
local name
if type(node) == "table" then
if node.name then
name = node.name
if node.name then name = node.name
elseif node.x and node.y and node.z then
node = minetest.get_node_or_nil(node)
name = node and node.name
@ -146,9 +144,7 @@ local function plant_name_stage(node)
name = tostring(node)
end
if not name or name == "ignore" then
return nil
end
if not name or name == "ignore" then return nil end
local sep_pos = name:find("_[^_]+$")
@ -164,7 +160,6 @@ local function plant_name_stage(node)
return name, 0
end
-- Map from node name to
-- { plant_name = ..., name = ..., stage = n, stages_left = { node_name, ... } }
@ -173,30 +168,24 @@ local plant_stages = {}
farming.plant_stages = plant_stages
--- Registers the stages of growth of a (possible plant) node.
--
-- @param node
-- Node or position table, or node name.
-- @return
-- The (possibly zero) number of stages of growth the plant will go through
-- before being fully grown, or nil if not a plant.
-- @param node - Node or position table, or node name.
-- @return - The (possibly zero) number of stages of growth the plant will go through
-- before being fully grown, or nil if not a plant.
local register_plant_node
-- Recursive helper
local function reg_plant_stages(plant_name, stage, force_last)
local node_name = plant_name and plant_name .. "_" .. stage
local node_def = node_name and minetest.registered_nodes[node_name]
if not node_def then
return nil
end
if not node_def then return nil end
local stages = plant_stages[node_name]
if stages then
return stages
end
if stages then return stages end
if minetest.get_item_group(node_name, "growing") > 0 then
@ -219,9 +208,7 @@ local function reg_plant_stages(plant_name, stage, force_last)
on_construct = function(pos)
if old_constr then
old_constr(pos)
end
if old_constr then old_constr(pos) end
farming.handle_growth(pos)
end,
@ -230,9 +217,7 @@ local function reg_plant_stages(plant_name, stage, force_last)
minetest.get_node_timer(pos):stop()
if old_destr then
old_destr(pos)
end
if old_destr then old_destr(pos) end
end,
on_timer = function(pos, elapsed)
@ -275,9 +260,7 @@ end
local function set_growing(pos, stages_left)
if not stages_left then
return
end
if not stages_left then return end
local timer = minetest.get_node_timer(pos)
@ -297,19 +280,15 @@ local function set_growing(pos, stages_left)
end
end
-- detects a crop at given position, starting or stopping growth timer when needed
function farming.handle_growth(pos, node)
if not pos then
return
end
if not pos then return end
local stages_left = register_plant_node(node or pos)
if stages_left then
set_growing(pos, stages_left)
end
if stages_left then set_growing(pos, stages_left) end
end
@ -320,21 +299,20 @@ minetest.after(0, function()
end
end)
-- Just in case a growing type or added node is missed (also catches existing
-- nodes added to map before timers were incorporated).
minetest.register_abm({
label = "Start crop timer",
nodenames = {"group:growing"},
interval = 300,
chance = 1,
catch_up = false,
action = function(pos, node)
-- skip if node timer already active
if minetest.get_node_timer(pos):is_started() then
return
end
if minetest.get_node_timer(pos):is_started() then return end
-- check if group:growing node is a seed
local def = minetest.registered_nodes[node.name]
@ -367,27 +345,24 @@ minetest.register_abm({
end
})
-- default check if on wet soil
-- check if on wet soil
farming.can_grow = function(pos)
local below = minetest.get_node({x = pos.x, y = pos.y -1, z = pos.z})
return minetest.get_item_group(below.name, "soil") >= 3
end
-- Plant timer function that grows plants under the right conditions.
function farming.plant_growth_timer(pos, elapsed, node_name)
local stages = plant_stages[node_name]
if not stages then
return false
end
if not stages then return false end
local max_growth = #stages.stages_left
if max_growth <= 0 then
return false
end
if max_growth <= 0 then return false end
local chk1 = minetest.registered_nodes[node_name].growth_check -- old
local chk2 = minetest.registered_nodes[node_name].can_grow -- new
@ -395,29 +370,21 @@ function farming.plant_growth_timer(pos, elapsed, node_name)
-- custom farming redo growth_check function
if chk1 then
if not chk1(pos, node_name) then
return true
end
if not chk1(pos, node_name) then return true end
-- custom mt 5.9x farming can_grow function
elseif chk2 then
if not chk2(pos) then
return true
end
if not chk2(pos) then return true end
-- default mt 5.9x farming.can_grow function
elseif not farming.can_grow(pos) then
return true
end
elseif not farming.can_grow(pos) then return true end
local growth
local light_pos = {x = pos.x, y = pos.y, z = pos.z}
local lambda = elapsed / STAGE_LENGTH_AVG
if lambda < 0.1 then
return true
end
if lambda < 0.1 then return true end
local MIN_LIGHT = minetest.registered_nodes[node_name].minlight or farming.min_light
local MAX_LIGHT = minetest.registered_nodes[node_name].maxlight or farming.max_light
@ -426,9 +393,7 @@ function farming.plant_growth_timer(pos, elapsed, node_name)
local light = (minetest.get_node_light(light_pos) or 0)
if light < MIN_LIGHT or light > MAX_LIGHT then
return true
end
if light < MIN_LIGHT or light > MAX_LIGHT then return true end
growth = 1
else
@ -439,9 +404,7 @@ function farming.plant_growth_timer(pos, elapsed, node_name)
if not night_growth then
if not day_growth then
return true
end
if not day_growth then return true end
lambda = day_or_night_time(elapsed, true) / STAGE_LENGTH_AVG
@ -452,9 +415,7 @@ function farming.plant_growth_timer(pos, elapsed, node_name)
growth = statistics.poisson(lambda, max_growth)
if growth < 1 then
return true
end
if growth < 1 then return true end
end
if minetest.registered_nodes[stages.stages_left[growth]] then
@ -469,8 +430,8 @@ function farming.plant_growth_timer(pos, elapsed, node_name)
return growth ~= max_growth
end
-- refill placed plant by crabman (26/08/2015) updated by TenPlus1
function farming.refill_plant(player, plantname, index)
if not player then return end
@ -481,9 +442,7 @@ function farming.refill_plant(player, plantname, index)
local old_stack = inv:get_stack("main", index)
if old_stack:get_name() ~= "" then
return
end
if old_stack:get_name() ~= "" then return end
for i, stack in ipairs(inv:get_list("main")) do
@ -498,22 +457,21 @@ function farming.refill_plant(player, plantname, index)
end
end
-- Place Seeds on Soil
function farming.place_seed(itemstack, placer, pointed_thing, plantname)
local pt = pointed_thing
-- check if pointing at a node
if not itemstack or not pt or pt.type ~= "node" then
return
end
if not itemstack or not pt or pt.type ~= "node" then return end
local under = minetest.get_node(pt.under)
-- am I right-clicking on something that has a custom on_place set?
-- thanks to Krock for helping with this issue :)
local def = minetest.registered_nodes[under.name]
if placer and itemstack and def and def.on_rightclick then
return def.on_rightclick(pt.under, under, placer, itemstack, pt)
end
@ -521,23 +479,16 @@ function farming.place_seed(itemstack, placer, pointed_thing, plantname)
local above = minetest.get_node(pt.above)
-- check if pointing at the top of the node
if pt.above.y ~= pt.under.y + 1 then
return
end
if pt.above.y ~= pt.under.y + 1 then return end
-- return if any of the nodes is not registered
if not minetest.registered_nodes[under.name]
or not minetest.registered_nodes[above.name] then
return
end
or not minetest.registered_nodes[above.name] then return end
-- can I replace above node, and am I pointing at soil
-- can I replace above node, and am I pointing directly at soil
if not minetest.registered_nodes[above.name].buildable_to
or minetest.get_item_group(under.name, "soil") < 2
-- avoid multiple seed placement bug
or minetest.get_item_group(above.name, "plant") ~= 0 then
return
end
or minetest.get_item_group(above.name, "plant") ~= 0 then return end
-- is player planting seed?
local name = placer and placer:get_player_name() or ""
@ -549,9 +500,7 @@ function farming.place_seed(itemstack, placer, pointed_thing, plantname)
minetest.set_node(pt.above, {name = plantname, param2 = p2})
farming.start_seed_timer(pt.above)
--minetest.get_node_timer(pt.above):start(1)
--farming.handle_growth(pt.above)--, node)
farming.start_seed_timer(pt.above)
minetest.sound_play("default_place_node", {pos = pt.above, gain = 1.0})
@ -565,12 +514,8 @@ farming.start_seed_timer(pt.above)
-- check for refill
if itemstack:get_count() == 0 then
minetest.after(0.2,
farming.refill_plant,
placer,
name,
placer:get_wield_index()
)
minetest.after(0.2, farming.refill_plant,
placer, name, placer:get_wield_index())
end
end
@ -578,13 +523,11 @@ farming.start_seed_timer(pt.above)
end
end
-- Function to register plants (default farming compatibility)
farming.register_plant = function(name, def)
if not def.steps then
return nil
end
if not def.steps then return nil end
local mname = name:split(":")[1]
local pname = name:split(":")[2]
@ -622,14 +565,12 @@ farming.register_plant = function(name, def)
local def = minetest.registered_nodes[mname .. ":" .. pname .. "_1"]
if def then
minetest.swap_node(pos, {
name = def.next_plant,
param2 = def.place_param2
})
minetest.swap_node(pos, {name = def.next_plant, param2 = def.place_param2})
end
end,
on_place = function(itemstack, placer, pointed_thing)
return farming.place_seed(itemstack, placer, pointed_thing,
mname .. ":seed_" .. pname)
end
@ -703,21 +644,21 @@ farming.register_plant = function(name, def)
})
end
-- add to farming.registered_plants
farming.registered_plants[mname .. ":" .. pname] = {
crop = mname .. ":" .. pname,
seed = mname .. ":seed_" .. pname,
steps = def.steps,
minlight = def.minlight,
maxlight = def.maxlight
}
--print(dump(farming.registered_plants[mname .. ":" .. pname]))
-- Return info
-- add to farming.registered_plants
farming.registered_plants[mname .. ":" .. pname] = {
crop = mname .. ":" .. pname,
seed = mname .. ":seed_" .. pname,
steps = def.steps,
minlight = def.minlight,
maxlight = def.maxlight
}
-- print(dump(farming.registered_plants[mname .. ":" .. pname]))
return {seed = mname .. ":seed_" .. pname, harvest = mname .. ":" .. pname}
end
-- default settings
farming.asparagus = 0.002
farming.eggplant = 0.002
farming.spinach = 0.002
@ -758,23 +699,26 @@ farming.strawberry = 0.002
farming.grains = true
farming.rice = true
-- Load new global settings if found inside mod folder
local input = io.open(farming.path .. "/farming.conf", "r")
if input then
dofile(farming.path .. "/farming.conf")
input:close()
dofile(farming.path .. "/farming.conf") ; input:close()
end
-- load new world-specific settings if found inside world folder
local worldpath = minetest.get_worldpath()
input = io.open(worldpath .. "/farming.conf", "r")
if input then
dofile(worldpath .. "/farming.conf")
input:close()
dofile(worldpath .. "/farming.conf") ; input:close()
end
-- helper function to add {eatable} group to food items
-- helper function to add {eatable} group to food items, also {flammable}
function farming.add_eatable(item, hp)
local def = minetest.registered_items[item]
@ -789,19 +733,21 @@ function farming.add_eatable(item, hp)
end
end
-- recipe items
dofile(farming.path .. "/items.lua")
-- recipe item list and alternatives
dofile(farming.path .. "/items_list.lua")
-- important items
if minetest.get_modpath("default") then
dofile(farming.path .. "/soil.lua")
dofile(farming.path .. "/hoes.lua")
end
dofile(farming.path.."/grass.lua")
dofile(farming.path.."/utensils.lua")
-- default crops
if not farming.mcl then
dofile(farming.path.."/crops/wheat.lua")
end
@ -809,6 +755,7 @@ end
dofile(farming.path.."/crops/cotton.lua")
-- disable crops Mineclone already has
if farming.mcl then
farming.carrot = nil
farming.potato = nil
@ -820,11 +767,10 @@ if farming.mcl then
end
-- helper function
local function ddoo(file, check)
if check then
dofile(farming.path .. "/crops/" .. file)
end
if check then dofile(farming.path .. "/crops/" .. file) end
end
-- add additional crops and food (if enabled)
@ -851,7 +797,7 @@ ddoo("pineapple.lua", farming.pineapple)
ddoo("peas.lua", farming.peas)
ddoo("beetroot.lua", farming.beetroot)
ddoo("chili.lua", farming.chili)
ddoo("ryeoatrice.lua", farming.grains)
ddoo("rye_oat.lua", farming.grains)
ddoo("rice.lua", farming.rice)
ddoo("mint.lua", farming.mint)
ddoo("cabbage.lua", farming.cabbage)
@ -868,7 +814,12 @@ ddoo("eggplant.lua", farming.eggplant)
ddoo("spinach.lua", farming.eggplant)
ddoo("ginger.lua", farming.ginger)
dofile(farming.path .. "/food.lua")
-- register food items, non-food items, recipes and stairs
dofile(farming.path .. "/items_non_food.lua")
dofile(farming.path .. "/items_food.lua")
dofile(farming.path .. "/item_recipes.lua")
dofile(farming.path .. "/item_stairs.lua")
if not farming.mcl then
dofile(farming.path .. "/compatibility.lua") -- Farming Plus compatibility