Use node timers for farming plants also; may introduce issues but seems good from some simple tests

This commit is contained in:
KaadmY 2017-07-04 09:48:25 -07:00
parent 58e692bc65
commit 5968bad31e
4 changed files with 187 additions and 109 deletions

142
mods/farming/api.lua Normal file
View File

@ -0,0 +1,142 @@
--
-- Farming and plant growing API
--
farming.registered_plants = {}
function farming.register_plant(name, plant)
-- Note: You'll have to register 4 plant growing nodes before calling this!
-- Format: "[mod:plant]_[stage from 1-4]"
farming.registered_plants[name] = plant -- Might need to fully copy here?
minetest.register_lbm(
{
label = "Grow legacy farming plants",
name = "farming:grow_legacy_plants",
nodenames = {
name .. "_1",
name .. "_2",
name .. "_3",
},
action = function(pos, node)
farming.grow_plant(pos, name)
end,
}
)
function add_callbacks(nodename)
minetest.override_item(
nodename,
{
on_timer = function(pos)
local name = string.gsub(minetest.get_node(pos).name, "_(%d+)", "")
farming.grow_plant(pos, name)
end,
on_construct = function(pos)
farming.begin_growing_plant(pos)
end,
on_place = farming.place_plant,
}
)
end
add_callbacks(name .. "_1")
add_callbacks(name .. "_2")
add_callbacks(name .. "_3")
end
function farming.begin_growing_plant(pos)
local name = string.gsub(minetest.get_node(pos).name, "_(%d+)", "")
local plant = farming.registered_plants[name]
minetest.get_node_timer(pos):start(
math.random(plant.grow_time / 8, plant.grow_time / 4))
end
function farming.place_plant(itemstack, placer, pointed_thing)
local name = string.gsub(itemstack:get_name(), "_(%d+)", "")
local plant = farming.registered_plants[name]
local under = minetest.get_node(pointed_thing.under)
for _, can_grow_on in ipairs(plant.grows_on) do
local group = string.match(can_grow_on, "group:(.*)")
if (group ~= nil and minetest.get_item_group(under.name, group) > 0) or
(under.name == can_grow_on) then
minetest.set_node(pointed_thing.above, {name = itemstack:get_name()})
itemstack:take_item()
break
end
end
return itemstack
end
function farming.next_stage(pos, under, underdef, name, plant)
local my_node = minetest.get_node(pos)
if my_node.name == name .. "_1" then
minetest.set_node(pos, {name = name .. "_2"})
elseif my_node.name == name .. "_2" then
minetest.set_node(pos, {name = name .. "_3"})
elseif my_node.name == name .. "_3" then
minetest.set_node(pos, {name = name .. "_4"})
-- Stop the timer on the node so no more growing occurs until needed
minetest.get_node_timer(pos):stop()
end
end
function farming.grow_plant(pos, name)
local plant = farming.registered_plants[name]
-- Check nearby nodes such as water
local my_node = minetest.get_node(pos)
if plant.grows_near and
minetest.find_node_near(pos, plant.growing_distance, plant.grows_near) == nil then
return
end
-- Check light; if too dark check again soon
local light = minetest.get_node_light(pos)
if light ~= nil and (light < plant.light_min or light > plant.light_max) then
minetest.get_node_timer(pos):start(
math.random(plant.grow_time / 16, plant.grow_time / 4))
return
end
-- Grow and check for rain and fertilizer
local under = minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z})
local underdef = minetest.registered_nodes[under.name]
farming.next_stage(pos, under, underdef, name, plant)
if minetest.get_item_group(under.name, "plantable_fertilizer") > 0 then
farming.next_stage(pos, under, underdef, name, plant)
end
if weather.weather == "storm" then
farming.next_stage(pos, under, underdefname, plant)
end
end
default.log("api", "loaded")

View File

@ -1,3 +1,4 @@
--
-- Farming mod
-- By Kaadmy, for Pixture
@ -5,68 +6,7 @@
farming = {}
function farming.grow_plant(pos, name, plant)
local my_node = minetest.get_node(pos)
if minetest.find_node_near(pos, plant.growing_distance, plant.grows_near) == nil then return end
local light = minetest.get_node_light(pos)
if light ~= nil and (light < plant.light_min or light > plant.light_max) then return end
local on_node = minetest.get_node({x = pos.x, y = pos.y-1, z = pos.z})
local on_nodedef = minetest.registered_nodes[on_node.name]
for _, can_grow_on in ipairs(plant.grows_on) do
local group = string.match(can_grow_on, "group:(.*)")
if (group ~= nil and on_nodedef.groups[group]) or (on_node.name == can_grow_on) then
if my_node.name == "farming:"..name.."_1" then
minetest.set_node(pos, {name = "farming:"..name.."_2"})
elseif my_node.name == "farming:"..name.."_2" then
minetest.set_node(pos, {name = "farming:"..name.."_3"})
elseif my_node.name == "farming:"..name.."_3" then
minetest.set_node(pos, {name = "farming:"..name.."_4"})
end
break
end
end
end
function farming.register_plant(name, plant)
-- note: you'll have to register 4
-- plant growing nodes before calling this!
--
-- format: "farming:[plant name]_[stage from 1-4]"
minetest.register_abm(
{
label = "Farming growing (" .. name .. ")",
nodenames = {
"farming:"..name.."_1",
"farming:"..name.."_2",
"farming:"..name.."_3",
},
neighbors = plant.grows_on, -- checked later anyway, but also check neighbors in C++ code for performance
interval = 1,
chance = plant.grow_time / 4,
action = function(pos, node, active_object_count, active_object_count_wider)
farming.grow_plant(pos, name, plant)
local underdef = minetest.registered_nodes[minetest.get_node({x = pos.x, y = pos.y-1, z = pos.z}).name]
if underdef.groups and underdef.groups.plantable_fertilizer then
print("Fertilizer!")
farming.grow_plant(pos, name, plant)
end
if weather.weather == "storm" then
farming.grow_plant(pos, name, plant)
end
end
})
end
dofile(minetest.get_modpath("farming").."/api.lua")
dofile(minetest.get_modpath("farming").."/nodes.lua")
dofile(minetest.get_modpath("farming").."/plants.lua")
dofile(minetest.get_modpath("farming").."/craft.lua")

View File

@ -27,7 +27,8 @@ minetest.register_node(
},
groups = {dig_immediate=2},
sounds=default.node_sound_leaves_defaults()
})
}
)
minetest.register_node(
"farming:wheat_2",
@ -51,7 +52,8 @@ minetest.register_node(
},
groups = {dig_immediate=2, not_in_craftingguide = 1},
sounds=default.node_sound_leaves_defaults()
})
}
)
minetest.register_node(
"farming:wheat_3",
@ -75,7 +77,8 @@ minetest.register_node(
},
groups = {dig_immediate=2, not_in_craftingguide = 1},
sounds=default.node_sound_leaves_defaults()
})
}
)
minetest.register_node(
"farming:wheat_4",
@ -102,7 +105,8 @@ minetest.register_node(
},
groups = {dig_immediate=2, not_in_craftingguide = 1},
sounds=default.node_sound_leaves_defaults()
})
}
)
minetest.register_node(
"farming:cotton_1",
@ -128,7 +132,8 @@ minetest.register_node(
},
groups = {dig_immediate=2},
sounds=default.node_sound_leaves_defaults()
})
}
)
minetest.register_node(
"farming:cotton_2",
@ -152,7 +157,8 @@ minetest.register_node(
},
groups = {dig_immediate=2, not_in_craftingguide = 1},
sounds=default.node_sound_leaves_defaults()
})
}
)
minetest.register_node(
"farming:cotton_3",
@ -176,7 +182,8 @@ minetest.register_node(
},
groups = {dig_immediate=2, not_in_craftingguide = 1},
sounds=default.node_sound_leaves_defaults()
})
}
)
minetest.register_node(
"farming:cotton_4",
@ -207,45 +214,31 @@ minetest.register_node(
local name = player:get_wielded_item():get_name()
if name == "default:shears" then
minetest.set_node(pos, {name = "farming:cotton_3"})
minetest.set_node(pos, {name = "farming:cotton_2"})
-- Drop some seeds
if math.random(1, 2) == 1 then
item_drop.drop_item(pos, "farming:cotton_1")
end
-- Drop an extra cotton ball
for i = 1, 2 do
if math.random(1, 2) == 1 then
break
end
local item = "farming:cotton"
if math.random(1, 4) == 1 then
item = item .. " 2"
end
local rpos = {
x = pos.x + math.random(-0.3, 0.3),
y = pos.y,
z = pos.z + math.random(-0.3, 0.3)
}
local drop = minetest.add_item(rpos, item)
if drop ~= nil then
local x = math.random(1, 5)
if math.random(1, 2) == 1 then
x = -x
end
local z = math.random(1, 5)
if math.random(1, 2) == 1 then
z = -z
end
drop:setvelocity({x = 1 / x, y = drop:getvelocity().y, z = 1 / z})
if math.random(1, 4) == 1 then -- 25% chance of dropping 2x
item_drop.drop_item(pos, "farming:cotton 2")
else
item_drop.drop_item(pos, "farming:cotton")
end
end
-- Keep it growing
farming.begin_growing_plant(pos)
end
end,
})
}
)
minetest.register_node(
"farming:cotton_bale",
@ -256,7 +249,8 @@ minetest.register_node(
groups = {snappy = 2, oddly_breakable_by_hand = 3,
fall_damage_add_percent = -15, fuzzy = 1},
sounds = default.node_sound_leaves_defaults(),
})
}
)
minetest.register_alias("farming:cotton_seed", "farming:cotton_1")
minetest.register_alias("farming:wheat_seed", "farming:wheat_1")

View File

@ -4,25 +4,27 @@
--
farming.register_plant(
"wheat",
"farming:wheat",
{
grow_time = 720,
grow_time = 600,
grows_near = {"group:water"},
growing_distance = 3,
grows_on = {"group:plantable_soil"},
light_min = 8,
light_max = 15,
})
}
)
farming.register_plant(
"cotton",
"farming:cotton",
{
grow_time = 1440,
grow_time = 780,
grows_near = {"group:water"},
growing_distance = 4,
grows_on = {"group:plantable_sandy", "group:plantable_soil"},
light_min = 12,
light_max = 15,
})
}
)
default.log("plants", "loaded")