diff options
-rw-r--r-- | crops_settings.txt | 11 | ||||
-rw-r--r-- | init.lua | 229 | ||||
-rw-r--r-- | textures/crops_hydrometer.png | bin | 0 -> 223 bytes | |||
-rw-r--r-- | textures/crops_soak.png | bin | 0 -> 182 bytes | |||
-rw-r--r-- | textures/crops_watering_can.png | bin | 0 -> 327 bytes | |||
-rw-r--r-- | textures/crops_wither.png | bin | 0 -> 140 bytes | |||
-rw-r--r-- | tomato.lua | 45 |
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 -- @@ -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 Binary files differnew file mode 100644 index 0000000..1ab9951 --- /dev/null +++ b/textures/crops_hydrometer.png diff --git a/textures/crops_soak.png b/textures/crops_soak.png Binary files differnew file mode 100644 index 0000000..e6913bd --- /dev/null +++ b/textures/crops_soak.png diff --git a/textures/crops_watering_can.png b/textures/crops_watering_can.png Binary files differnew file mode 100644 index 0000000..f3933b8 --- /dev/null +++ b/textures/crops_watering_can.png diff --git a/textures/crops_wither.png b/textures/crops_wither.png Binary files differnew file mode 100644 index 0000000..d67b605 --- /dev/null +++ b/textures/crops_wither.png @@ -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 }) + |