summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crops_settings.txt11
-rw-r--r--init.lua229
-rw-r--r--textures/crops_hydrometer.pngbin0 -> 223 bytes
-rw-r--r--textures/crops_soak.pngbin0 -> 182 bytes
-rw-r--r--textures/crops_watering_can.pngbin0 -> 327 bytes
-rw-r--r--textures/crops_wither.pngbin0 -> 140 bytes
-rw-r--r--tomato.lua45
7 files changed, 279 insertions, 6 deletions
diff --git a/crops_settings.txt b/crops_settings.txt
index 39dd3c0..e784407 100644
--- a/crops_settings.txt
+++ b/crops_settings.txt
@@ -20,6 +20,17 @@ crops.light = 8
crops.chance = 8
crops.interval = 30
crops.light = 10
+crops.watercan = 25
+crops.watercan_max = 89
+crops.watercanuses = 20
+crops.waterstart = 50
+crops.wateruse = 1
+crops.night = 5
+crops.soak = 80
+crops.soak_damage = 90
+crops.wither = 20
+crops.wither_damage = 10
+crops.max_damage = 50
--[[
-- difficult --
diff --git a/init.lua b/init.lua
index 1e27f51..48ecd08 100644
--- a/init.lua
+++ b/init.lua
@@ -11,6 +11,7 @@ of the license, or (at your option) any later version.
--]]
crops = {}
+crops.plants = {}
local worldpath = minetest.get_worldpath()
local modpath = minetest.get_modpath(minetest.get_current_modname())
@@ -34,6 +35,174 @@ else
dofile(worldpath .. "/crops_settings.txt")
end
+local find_plant = function(node)
+ for i = 1,table.getn(crops.plants) do
+ if crops.plants[i].name == node.name then
+ return crops.plants[i]
+ end
+ end
+ return nil
+end
+
+crops.plant = function(pos, node)
+ minetest.set_node(pos, node)
+ local meta = minetest.get_meta(pos)
+ meta:set_int("crops_water", crops.waterstart)
+ meta:set_int("crops_damage", 0)
+end
+
+crops.can_grow = function(pos)
+ if minetest.get_node_light(pos, nil) < crops.light then
+ return false
+ end
+ local meta = minetest.get_meta(pos)
+ local water = meta:get_int("crops_water")
+ if water < crops.wither or water > crops.soak then
+ if math.random(0,1) == 0 then
+ return false
+ end
+ end
+ local damage = meta:get_int("crops_damage")
+ if not damage == 0 then
+ if math.random(math.min(50, damage), 100) > 75 then
+ return false
+ end
+ end
+ local plant = find_plant(pos)
+ if not plant then
+ return false
+ end
+
+ -- allow the plant to grow
+ return true
+end
+
+crops.particles = function(pos, flag)
+ local p = {}
+ if flag == 0 then
+ -- wither (0)
+ p = {
+ amount = 1 * crops.interval,
+ time = crops.interval,
+ minpos = { x = pos.x - 0.4, y = pos.y - 0.4, z = pos.z - 0.4 },
+ maxpos = { x = pos.x + 0.4, y = pos.y + 0.4, z = pos.z + 0.4 },
+ minvel = { x = 0, y = 0.2, z = 0 },
+ maxvel = { x = 0, y = 0.4, z = 0 },
+ minacc = { x = 0, y = 0, z = 0 },
+ maxacc = { x = 0, y = 0.2, z = 0 },
+ minexptime = 3,
+ maxexptime = 5,
+ minsize = 1,
+ maxsize = 2,
+ collisiondetection = false,
+ texture = "crops_wither.png",
+ vertical = true,
+ }
+ else
+ -- soak (1)
+ p = {
+ amount = 8 * crops.interval,
+ time = crops.interval,
+ minpos = { x = pos.x - 0.4, y = pos.y - 0.4, z = pos.z - 0.4 },
+ maxpos = { x = pos.x + 0.4, y = pos.y - 0.4, z = pos.z + 0.4 },
+ minvel = { x = -0.04, y = 0, z = -0.04 },
+ maxvel = { x = 0.04, y = 0, z = 0.04 },
+ minacc = { x = 0, y = 0, z = 0 },
+ maxacc = { x = 0, y = 0, z = 0 },
+ minexptime = 3,
+ maxexptime = 5,
+ minsize = 1,
+ maxsize = 2,
+ collisiondetection = false,
+ texture = "crops_soak.png",
+ vertical = false,
+ }
+ end
+ minetest.add_particlespawner(p)
+end
+
+minetest.register_tool("crops:watering_can", {
+ description = "Watering Can",
+ inventory_image = "crops_watering_can.png",
+ liquids_pointable = true,
+ range = 2.5,
+ stack_max = 1,
+ wear = 65535,
+ tool_capabilities = {
+ },
+ on_use = function(itemstack, user, pointed_thing)
+ local pos = pointed_thing.under
+ if pos == nil then
+ return itemstack
+ end
+ -- filling it up?
+ local node = minetest.get_node(pos)
+ if node.name == "default:water_source" or
+ node.name == "default:water_flowing" then
+ itemstack:set_wear(1)
+ return itemstack
+ end
+ -- using it on a plant?
+ local meta = minetest.get_meta(pos)
+ local water = meta:get_int("crops_water")
+ if water == nil then
+ return itemstack
+ end
+ local wear = itemstack:get_wear()
+ -- empty?
+ if wear == 65534 then
+ return itemstack
+ end
+ water = math.min(water + crops.watercan, crops.watercan_max)
+ meta:set_int("crops_water", water)
+ itemstack:set_wear(math.min(65534, wear + (65535 / crops.watercanuses)))
+ return itemstack
+ end,
+})
+
+minetest.register_tool("crops:hydrometer", {
+ description = "Hydrometer",
+ inventory_image = "crops_hydrometer.png",
+ liquids_pointable = false,
+ range = 2.5,
+ stack_max = 1,
+ tool_capabilities = {
+ },
+ on_use = function(itemstack, user, pointed_thing)
+ local pos = pointed_thing.under
+ if pos == nil then
+ return itemstack
+ end
+ local meta = minetest.get_meta(pos)
+ -- using it on a plant?
+ local water = meta:get_int("crops_water")
+ if water == nil then
+ itemstack:set_wear(65534)
+ return itemstack
+ end
+ itemstack:set_wear(65535 - ((65534 / 100) * water))
+ return itemstack
+ end,
+})
+
+minetest.register_craft({
+ output = "crops:watering_can",
+ recipe = {
+ { "default:steel_ingot", "", "" },
+ { "default:steel_ingot", "", "default:steel_ingot" },
+ { "", "default:steel_ingot", "" },
+ },
+})
+
+minetest.register_craft({
+ output = "crops:hydrometer",
+ recipe = {
+ { "default:mese_crystal_fragment", "", "" },
+ { "", "default:steel_ingot", "" },
+ { "", "", "default:steel_ingot" },
+ },
+})
+
-- crop nodes, crafts, craftitems
dofile(modpath .. "/melon.lua")
dofile(modpath .. "/corn.lua")
@@ -41,6 +210,66 @@ dofile(modpath .. "/tomato.lua")
dofile(modpath .. "/potato.lua")
dofile(modpath .. "/polebean.lua")
+-- water handling code
+minetest.register_abm({
+ nodenames = {
+ "crops:tomato_plant_1", "crops:tomato_plant_2", "crops:tomato_plant_3", "crops:tomato_plant_4", "crops:tomato_plant_5"
+ },
+ interval = crops.interval,
+ chance = crops.chance,
+ action = function(pos, node, active_object_count, active_object_count_wider)
+ local meta = minetest.get_meta(pos)
+ local water = meta:get_int("crops_water")
+ local damage = meta:get_int("crops_damage")
+
+ -- get plant specific data
+ local plant = find_plant(node)
+ if plant == nil then
+ -- FIXME - throw error?
+ return
+ end
+
+ -- increase water for nearby water sources
+ local f = minetest.find_node_near(pos, 1, {"default:water_source", "default:water_flowing"})
+ if not f == nil then
+ water = math.min(100, water + 2)
+ else
+ local f = minetest.find_node_near(pos, 2, {"default:water_source", "default:water_flowing"})
+ if not f == nil then
+ water = math.min(100, water + 1)
+ end
+ end
+
+ -- compensate for light: at night give some water back to the plant
+ if minetest.get_node_light(pos, nil) < crops.night then
+ water = math.min(100, water + 1)
+ end
+
+ -- dry out the plant
+ water = math.max(0, water - ( crops.wateruse * plant.wateruse ))
+ meta:set_int("crops_water", water)
+ if water < crops.wither_damage then
+ crops.particles(pos, 0)
+ damage = damage + math.random(0,5)
+ elseif water < crops.wither then
+ crops.particles(pos, 0)
+ return
+ elseif water > crops.soak_damage then
+ crops.particles(pos, 1)
+ damage = damage + math.random(0,5)
+ elseif water > crops.soak then
+ crops.particles(pos, 1)
+ return
+ end
+ meta:set_int("crops_damage", math.min(crops.max_damage, damage))
+
+ -- is it dead?
+ if damage >= 100 then
+ plant.wither(pos)
+ end
+ end
+})
+
-- cooking recipes that mix craftitems
dofile(modpath .. "/cooking.lua")
diff --git a/textures/crops_hydrometer.png b/textures/crops_hydrometer.png
new file mode 100644
index 0000000..1ab9951
--- /dev/null
+++ b/textures/crops_hydrometer.png
Binary files differ
diff --git a/textures/crops_soak.png b/textures/crops_soak.png
new file mode 100644
index 0000000..e6913bd
--- /dev/null
+++ b/textures/crops_soak.png
Binary files differ
diff --git a/textures/crops_watering_can.png b/textures/crops_watering_can.png
new file mode 100644
index 0000000..f3933b8
--- /dev/null
+++ b/textures/crops_watering_can.png
Binary files differ
diff --git a/textures/crops_wither.png b/textures/crops_wither.png
new file mode 100644
index 0000000..d67b605
--- /dev/null
+++ b/textures/crops_wither.png
Binary files differ
diff --git a/tomato.lua b/tomato.lua
index 0bb03d8..f289059 100644
--- a/tomato.lua
+++ b/tomato.lua
@@ -10,6 +10,8 @@ of the license, or (at your option) any later version.
--]]
+local wateruse = 1
+
minetest.register_node("crops:tomato_seed", {
description = "tomato seed",
inventory_image = "crops_tomato_seed.png",
@@ -30,7 +32,7 @@ minetest.register_node("crops:tomato_seed", {
if minetest.get_item_group(under.name, "soil") <= 1 then
return
end
- minetest.set_node(pointed_thing.above, {name="crops:tomato_plant_1"})
+ crops.plant(pointed_thing.above, {name="crops:tomato_plant_1"})
if not minetest.setting_getbool("creative_mode") then
itemstack:take_item()
end
@@ -79,6 +81,8 @@ minetest.register_node("crops:tomato_plant_5" , {
local meta = minetest.get_meta(pos)
local ttl = meta:get_int("crops_tomato_ttl")
+ local water = meta:get_int("crops_water")
+ local damage = meta:get_int("crops_damage")
if ttl > 1 then
minetest.set_node(pos, { name = "crops:tomato_plant_4"})
meta:set_int("crops_tomato_ttl", ttl - 1)
@@ -86,6 +90,8 @@ minetest.register_node("crops:tomato_plant_5" , {
minetest.set_node(pos, { name = "crops:tomato_plant_6"})
meta:set_int("crops_tomato_ttl", 0)
end
+ meta:set_int("crops_water", water)
+ meta:set_int("crops_damage", damage)
end
})
@@ -124,14 +130,19 @@ minetest.register_abm({
interval = crops.interval,
chance = crops.chance,
action = function(pos, node, active_object_count, active_object_count_wider)
- if minetest.get_node_light(pos, nil) < crops.light then
+ if not crops.can_grow(pos) then
return
end
+ local meta = minetest.get_meta(pos)
+ local water = meta:get_int("crops_water")
+ local damage = meta:get_int("crops_damage")
local n = string.gsub(node.name, "4", "5")
n = string.gsub(n, "3", "4")
n = string.gsub(n, "2", "3")
n = string.gsub(n, "1", "2")
minetest.set_node(pos, { name = n })
+ meta:set_int("crops_water", water)
+ meta:set_int("crops_damage", damage)
end
})
@@ -144,16 +155,38 @@ minetest.register_abm({
interval = crops.interval,
chance = crops.chance,
action = function(pos, node, active_object_count, active_object_count_wider)
- if minetest.get_node_light(pos, nil) < crops.light then
+ if not crops.can_grow(pos) then
return
end
local meta = minetest.get_meta(pos)
local ttl = meta:get_int("crops_tomato_ttl")
+ local water = meta:get_int("crops_water")
+ local damage = meta:get_int("crops_damage")
if ttl == 0 then
- ttl = math.random(4, 6)
+ -- damage 0 - drops 4-6
+ -- damage 50 - drops 2-3
+ -- damage 100 - drops 0-1
+ ttl = math.random(4 - (4 * (damage / 100)), 6 - (5 * (damage / 100)))
+ end
+ if ttl > 1 then
+ minetest.set_node(pos, { name = "crops:tomato_plant_5" })
+ meta:set_int("crops_tomato_ttl", ttl)
+ meta:set_int("crops_water", water)
+ meta:set_int("crops_damage", damage)
+ else
+ -- no luck, plant dead!
+ minetest.set_node(pos, { name = "crops:tomato_plant_6" })
end
- minetest.set_node(pos, { name = "crops:tomato_plant_5" })
- meta:set_int("crops_tomato_ttl", ttl)
end
})
+crops.tomato_die = function(pos)
+ minetest.set_node(pos, { name = "crops:tomato_plant_6" })
+end
+
+table.insert(crops.plants, { name = "crops:tomato_plant_1", wateruse = 1.0, wither = crops.tomato_die })
+table.insert(crops.plants, { name = "crops:tomato_plant_2", wateruse = 1.0, wither = crops.tomato_die })
+table.insert(crops.plants, { name = "crops:tomato_plant_3", wateruse = 1.0, wither = crops.tomato_die })
+table.insert(crops.plants, { name = "crops:tomato_plant_4", wateruse = 1.0, wither = crops.tomato_die })
+table.insert(crops.plants, { name = "crops:tomato_plant_5", wateruse = 1.0, wither = crops.tomato_die })
+