diff options
-rw-r--r-- | crops_settings.txt | 11 | ||||
-rw-r--r-- | description.txt | 1 | ||||
-rw-r--r-- | init.lua | 231 | ||||
-rw-r--r-- | potato.lua | 35 | ||||
-rw-r--r-- | screenshot.png | bin | 0 -> 253354 bytes | |||
-rw-r--r-- | textures/crops_hydrometer.png | bin | 0 -> 223 bytes | |||
-rw-r--r-- | textures/crops_potato_plant_5.png | bin | 0 -> 424 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 |
11 files changed, 311 insertions, 12 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/description.txt b/description.txt new file mode 100644 index 0000000..45c16d9 --- /dev/null +++ b/description.txt @@ -0,0 +1 @@ +This mod expands the basic set of farming-related crops that minetest_game offers. @@ -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,176 @@ 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 + minetest.log("error", "Unable to find plant \"" .. node.name .. "\" in crops table") + 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 node = minetest.get_node(pos) + local plant = find_plant(node) + 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 +212,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", + "crops:potato_plant_1", "crops:potato_plant_2", "crops:potato_plant_3", "crops:potato_plant_4" + }, + 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 + 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") @@ -28,7 +28,7 @@ minetest.register_node("crops:potato_eyes", { if minetest.get_item_group(under.name, "soil") <= 1 then return end - minetest.set_node(pointed_thing.above, {name="crops:potato_plant_1"}) + crops.plant(pointed_thing.above, {name="crops:potato_plant_1"}) if not minetest.setting_getbool("creative_mode") then itemstack:take_item() end @@ -36,7 +36,7 @@ minetest.register_node("crops:potato_eyes", { end }) -for stage = 1, 4 do +for stage = 1, 5 do minetest.register_node("crops:potato_plant_" .. stage , { description = "potato plant", tiles = { "crops_potato_plant_" .. stage .. ".png" }, @@ -89,6 +89,7 @@ minetest.register_node("crops:soil_with_potatoes", { sounds = default.node_sound_dirt_defaults(), on_dig = function(pos, node, digger) local drops = {} + -- fixme account for damage for i = 1, math.random(3, 5) do table.insert(drops, "crops:potato") end @@ -110,17 +111,22 @@ minetest.register_abm({ interval = crops.interval, chance = crops.chance, action = function(pos, node, active_object_count, active_object_count_wider) - local below = { x = pos.x, y = pos.y - 1, z = pos.z } - if not minetest.registered_nodes[minetest.get_node(below).name].groups.soil then + if not crops.can_grow(pos) then return end - if minetest.get_node_light(pos, nil) < crops.light then + local below = { x = pos.x, y = pos.y - 1, z = pos.z } + if not minetest.registered_nodes[minetest.get_node(below).name].groups.soil 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, "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 }) @@ -133,15 +139,32 @@ 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 below = { x = pos.x, y = pos.y - 1, z = pos.z } if not minetest.registered_nodes[minetest.get_node(below).name].groups.soil then return end + local meta = minetest.get_meta(pos) + local water = meta:get_int("crops_water") + local damage = meta:get_int("crops_damage") local below = { x = pos.x, y = pos.y - 1, z = pos.z} minetest.set_node(below, { name = "crops:soil_with_potatoes" }) end }) +crops.potato_die = function(pos) + minetest.set_node(pos, { name = "crops:potato_plant_5" }) + local below = { x = pos.x, y = pos.y - 1, z = pos.z } + local node = minetest.get_node(below) + if node.name == "crops:soil_with_potatoes" then + local meta = minetest.get_meta(below) + meta:set_int("crops_damage", 100) + end +end + +table.insert(crops.plants, { name = "crops:potato_plant_1", wateruse = 1.0, wither = crops.potato_die }) +table.insert(crops.plants, { name = "crops:potato_plant_2", wateruse = 1.0, wither = crops.potato_die }) +table.insert(crops.plants, { name = "crops:potato_plant_3", wateruse = 1.0, wither = crops.potato_die }) +table.insert(crops.plants, { name = "crops:potato_plant_4", wateruse = 1.0, wither = crops.potato_die }) diff --git a/screenshot.png b/screenshot.png Binary files differnew file mode 100644 index 0000000..16f6348 --- /dev/null +++ b/screenshot.png 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_potato_plant_5.png b/textures/crops_potato_plant_5.png Binary files differnew file mode 100644 index 0000000..596ed1f --- /dev/null +++ b/textures/crops_potato_plant_5.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 }) + |