Skip to content

Commit

Permalink
Use node timers for farming plants also; may introduce issues but see…
Browse files Browse the repository at this point in the history
…ms good from some simple tests
  • Loading branch information
kaadmy committed Jul 4, 2017
1 parent 58e692b commit 5968bad
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 107 deletions.
142 changes: 142 additions & 0 deletions mods/farming/api.lua
Original file line number Diff line number Diff line change
@@ -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")
64 changes: 2 additions & 62 deletions mods/farming/init.lua
Original file line number Diff line number Diff line change
@@ -1,72 +1,12 @@

--
-- Farming mod
-- By Kaadmy, for Pixture
--

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")
Expand Down
72 changes: 33 additions & 39 deletions mods/farming/nodes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ minetest.register_node(
},
groups = {dig_immediate=2},
sounds=default.node_sound_leaves_defaults()
})
}
)

minetest.register_node(
"farming:wheat_2",
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -128,7 +132,8 @@ minetest.register_node(
},
groups = {dig_immediate=2},
sounds=default.node_sound_leaves_defaults()
})
}
)

minetest.register_node(
"farming:cotton_2",
Expand All @@ -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",
Expand All @@ -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",
Expand Down Expand Up @@ -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"})

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)
-- Drop some seeds

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
item_drop.drop_item(pos, "farming:cotton_1")
end

if math.random(1, 2) == 1 then
z = -z
end
-- Drop an extra cotton ball

drop:setvelocity({x = 1 / x, y = drop:getvelocity().y, z = 1 / z})
for i = 1, 2 do
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",
Expand All @@ -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")
Expand Down
14 changes: 8 additions & 6 deletions mods/farming/plants.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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")

0 comments on commit 5968bad

Please sign in to comment.