From 5968bad31e269249b15fe658fa38d8e5443c843e Mon Sep 17 00:00:00 2001 From: KaadmY Date: Tue, 4 Jul 2017 09:48:25 -0700 Subject: [PATCH] Use node timers for farming plants also; may introduce issues but seems good from some simple tests --- mods/farming/api.lua | 142 ++++++++++++++++++++++++++++++++++++++++ mods/farming/init.lua | 64 +----------------- mods/farming/nodes.lua | 76 ++++++++++----------- mods/farming/plants.lua | 14 ++-- 4 files changed, 187 insertions(+), 109 deletions(-) create mode 100644 mods/farming/api.lua diff --git a/mods/farming/api.lua b/mods/farming/api.lua new file mode 100644 index 0000000..a4d353c --- /dev/null +++ b/mods/farming/api.lua @@ -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") diff --git a/mods/farming/init.lua b/mods/farming/init.lua index 990b7c0..b23a56a 100644 --- a/mods/farming/init.lua +++ b/mods/farming/init.lua @@ -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") diff --git a/mods/farming/nodes.lua b/mods/farming/nodes.lua index c026cbc..7e3799f 100644 --- a/mods/farming/nodes.lua +++ b/mods/farming/nodes.lua @@ -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") diff --git a/mods/farming/plants.lua b/mods/farming/plants.lua index 2caf46c..bb497c1 100644 --- a/mods/farming/plants.lua +++ b/mods/farming/plants.lua @@ -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")