Add 'crops' mod
|
@ -34,6 +34,7 @@ The game includes the mods from the default [minetest_game](https://github.com/m
|
|||
* [currency][] ([WTFPL][lic.currency]) -- version: [21f9811 Git][ver.currency] *2017-03-22* ([patched][patch.currency])
|
||||
* [enchanting][] ([GPL][lic.enchanting]) -- version: [13ea31c Git][ver.enchanting] *2016-12-16*
|
||||
* farming/
|
||||
* [crops][] ([LGPL / CC-BY-SA / CC-BY / CC0][lic.crops]) -- version: [2b1bb37 Git][ver.crops] *2017-03-31*
|
||||
* [farming_plus][] ([WTFPL][lic.farming_plus]) -- version: [7e0d976 Git][ver.farming_plus] *2014-07-31*
|
||||
* furniture/
|
||||
* [jukebox][] ([WTFPL / CC0][lic.jukebox]) -- version: [e6a507f Git][ver.jukebox] *2016-05-23*
|
||||
|
@ -225,6 +226,7 @@ The game includes the mods from the default [minetest_game](https://github.com/m
|
|||
[craft_guide]: https://cornernote.github.io/minetest-craft_guide/
|
||||
[craftguide]: https://forum.minetest.net/viewtopic.php?t=14088
|
||||
[creeper]: https://forum.minetest.net/viewtopic.php?t=11891
|
||||
[crops]: https://forum.minetest.net/viewtopic.php?t=11795
|
||||
[currency]: https://github.com/minetest-mods/currency
|
||||
[elevator]: https://forum.minetest.net/viewtopic.php?t=12944
|
||||
[enchanting]: https://forum.minetest.net/viewtopic.php?t=7354
|
||||
|
@ -330,6 +332,7 @@ The game includes the mods from the default [minetest_game](https://github.com/m
|
|||
[lic.coloredwood]: mods/wood/coloredwood/LICENSE
|
||||
[lic.craft_guide]: mods/crafting/craft_guide/LICENSE
|
||||
[lic.creeper]: mods/mobs_aggressive/creeper/LICENSE.md
|
||||
[lic.crops]: mods/farming/crops/LICENSE
|
||||
[lic.currency]: https://forum.minetest.net/viewtopic.php?t=7002
|
||||
[lic.enchanting]: mods/enchanting/LICENSE
|
||||
[lic.ethereal]: mods/world/ethereal/license.txt
|
||||
|
@ -376,6 +379,7 @@ The game includes the mods from the default [minetest_game](https://github.com/m
|
|||
[ver.craft_guide]: https://github.com/cornernote/minetest-craft_guide/tree/20520b5
|
||||
[ver.craftguide]: https://github.com/minetest-mods/craftguide/tree/86a96c3
|
||||
[ver.creeper]: https://github.com/Rui-Minetest/creeper/tree/036666e
|
||||
[ver.crops]: https://github.com/minetest-mods/crops/tree/2b1bb37
|
||||
[ver.currency]: https://github.com/minetest-mods/currency/tree/21f9811
|
||||
[ver.enchanting]: https://github.com/minetest-mods/enchanting/tree/13ea31c
|
||||
[ver.ethereal]: https://github.com/tenplus1/ethereal/tree/2c24961
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
unused_args = false
|
||||
allow_defined_top = true
|
||||
|
||||
read_globals = {
|
||||
"DIR_DELIM",
|
||||
"minetest", "core",
|
||||
"dump",
|
||||
"vector", "nodeupdate",
|
||||
"VoxelManip", "VoxelArea",
|
||||
"PseudoRandom", "ItemStack",
|
||||
"intllib",
|
||||
"default",
|
||||
table = { fields = { "copy", "getn" } }
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
Crops - a minetest mod that adds more farming crops
|
||||
|
||||
See spdx.org/licenses to see what the License Identifiers used below mean.
|
||||
|
||||
=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
|
||||
|
||||
All source code (lua):
|
||||
(C) Auke Kok <sofar@foo-projects.org>
|
||||
LGPL-2.0+
|
||||
|
||||
All textures, models:
|
||||
(C) Auke Kok <sofar@foo-projects.org>
|
||||
CC-BY-SA-3.0
|
||||
|
||||
Translations:
|
||||
- de.po
|
||||
(C) 2017 LNJ <git@lnj.li>
|
||||
LGPL-2.0+
|
||||
|
||||
Sounds:
|
||||
- crops_watercan_splash*
|
||||
http://freesound.org/people/junggle/sounds/27361/
|
||||
http://profiles.google.com/jun66le
|
||||
CC-BY-3.0
|
||||
- crops_watercan_entering.ogg
|
||||
http://freesound.org/people/Quistard/sounds/166824/
|
||||
CC-BY-3.0
|
||||
- crops_flies.ogg
|
||||
http://www.freesound.org/people/galeku/sounds/46938/
|
||||
CC0-1.0
|
||||
- crops_watercan_watering.ogg
|
||||
http://www.freesound.org/people/Eakoontz/sounds/151736/
|
||||
CC0-1.0
|
||||
|
||||
* Sounds edited with audacity
|
||||
|
||||
=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
PROJECT = crops
|
||||
all: release
|
||||
|
||||
release:
|
||||
VERSION=`git describe --tags`; \
|
||||
git archive --format zip --output "$(PROJECT)-$${VERSION}.zip" --prefix=$(PROJECT)/ master
|
||||
|
||||
poupdate:
|
||||
../intllib/tools/xgettext.sh *.lua
|
|
@ -0,0 +1,75 @@
|
|||
|
||||
--[[
|
||||
|
||||
Copyright (C) 2015 - Auke Kok <sofar@foo-projects.org>
|
||||
|
||||
"crops" is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1
|
||||
of the license, or (at your option) any later version.
|
||||
|
||||
--]]
|
||||
|
||||
--
|
||||
-- cooking recipes that don't go directly with any of the
|
||||
-- crops in this mod - either these combine them in new
|
||||
-- ways or use other items
|
||||
--
|
||||
|
||||
-- Intllib
|
||||
local S = crops.intllib
|
||||
|
||||
minetest.register_craftitem("crops:unbaked_clay_bowl", {
|
||||
description = S("Unbaked clay bowl"),
|
||||
inventory_image = "crops_unbaked_clay_bowl.png",
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "crops:unbaked_clay_bowl",
|
||||
recipe = {
|
||||
{ "", "", "" },
|
||||
{ "default:clay_lump", "", "default:clay_lump" },
|
||||
{ "", "default:clay_lump", "" }
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craftitem("crops:clay_bowl", {
|
||||
description = S("Clay bowl"),
|
||||
inventory_image = "crops_clay_bowl.png",
|
||||
groups = { food_bowl=1 }
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "crops:clay_bowl",
|
||||
recipe = "crops:unbaked_clay_bowl"
|
||||
})
|
||||
|
||||
minetest.register_craftitem("crops:vegetable_stew", {
|
||||
description = S("Bowl of vegetable stew"),
|
||||
inventory_image = "crops_bowl_vegetable_stew.png",
|
||||
groups = { eatable=1 },
|
||||
on_use = minetest.item_eat(8, "crops:clay_bowl"),
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "crops:vegetable_stew",
|
||||
recipe = "crops:uncooked_vegetable_stew"
|
||||
})
|
||||
|
||||
minetest.register_craftitem("crops:uncooked_vegetable_stew", {
|
||||
description = S("Bowl of uncooked vegetable stew"),
|
||||
inventory_image = "crops_bowl_uncooked_vegetable_stew.png",
|
||||
groups = { eatable=1 },
|
||||
on_use = minetest.item_eat(2, "crops:clay_bowl")
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "crops:uncooked_vegetable_stew",
|
||||
recipe = {
|
||||
{ "", "", "" },
|
||||
{ "crops:green_bean", "crops:potato", "crops:tomato" },
|
||||
{ "", "group:food_bowl", "" }
|
||||
}
|
||||
})
|
|
@ -0,0 +1,347 @@
|
|||
|
||||
--[[
|
||||
|
||||
Copyright (C) 2015 - Auke Kok <sofar@foo-projects.org>
|
||||
|
||||
"crops" is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1
|
||||
of the license, or (at your option) any later version.
|
||||
|
||||
--]]
|
||||
|
||||
-- Intllib
|
||||
local S = crops.intllib
|
||||
|
||||
minetest.register_node("crops:corn", {
|
||||
description = S("Corn"),
|
||||
inventory_image = "crops_corn.png",
|
||||
wield_image = "crops_corn.png",
|
||||
tiles = { "crops_corn_base_seed.png" },
|
||||
drawtype = "plantlike",
|
||||
paramtype2 = "meshoptions",
|
||||
waving = 1,
|
||||
sunlight_propagates = true,
|
||||
use_texture_alpha = true,
|
||||
walkable = true,
|
||||
paramtype = "light",
|
||||
node_placement_prediction = "crops:corn_base_seed",
|
||||
groups = { snappy=3,flammable=3,flora=1,attached_node=1 },
|
||||
drop = {},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
local under = minetest.get_node(pointed_thing.under)
|
||||
if minetest.get_item_group(under.name, "soil") <= 1 then
|
||||
return
|
||||
end
|
||||
crops.plant(pointed_thing.above, {name="crops:corn_base_seed", param2 = 3})
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
itemstack:take_item()
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_craftitem("crops:corn_cob", {
|
||||
description = S("Corn Cob"),
|
||||
inventory_image = "crops_corn_cob.png",
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "crops:corn",
|
||||
recipe = { "crops:corn_cob" }
|
||||
})
|
||||
|
||||
minetest.register_craftitem("crops:corn_on_the_cob", {
|
||||
description = S("Corn on the Cob"),
|
||||
inventory_image = "crops_corn_on_the_cob.png",
|
||||
on_use = minetest.item_eat(1)
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "crops:corn_on_the_cob",
|
||||
recipe = "crops:corn_cob"
|
||||
})
|
||||
|
||||
minetest.register_node("crops:corn_base_seed", {
|
||||
visual = "mesh",
|
||||
description = S("Corn plant"),
|
||||
drawtype = "plantlike",
|
||||
paramtype2 = "meshoptions",
|
||||
waving = 1,
|
||||
tiles = { "crops_corn_base_seed.png" },
|
||||
use_texture_alpha = true,
|
||||
walkable = false,
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
groups = { snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1 },
|
||||
drop = {},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, 0.5, -0.3, 0.5}
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = { "crops:corn_base_seed" },
|
||||
neighbors = { "group:soil" },
|
||||
interval = crops.settings.interval,
|
||||
chance = crops.settings.chance,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
if not crops.can_grow(pos) then
|
||||
return
|
||||
end
|
||||
minetest.swap_node(pos, { name = "crops:corn_base_1", param2 = 3 })
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_node("crops:corn_base_1", {
|
||||
visual = "mesh",
|
||||
description = S("Corn plant"),
|
||||
drawtype = "plantlike",
|
||||
paramtype2 = "meshoptions",
|
||||
tiles = { "crops_corn_base_1.png" },
|
||||
waving = 1,
|
||||
use_texture_alpha = true,
|
||||
walkable = false,
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
groups = { snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1 },
|
||||
drop = {},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = { "crops:corn_base_1" },
|
||||
neighbors = { "group:soil" },
|
||||
interval = crops.settings.interval,
|
||||
chance = crops.settings.chance,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
if not crops.can_grow(pos) then
|
||||
return
|
||||
end
|
||||
if not minetest.get_node({x = pos.x, y = pos.y + 1, z = pos.z}).name == "air" then
|
||||
return
|
||||
end
|
||||
minetest.swap_node(pos, { name = "crops:corn_base_2", param2 = 3 })
|
||||
local above = {x = pos.x, y = pos.y + 1, z = pos.z}
|
||||
minetest.set_node(above , { name = "crops:corn_top_1", param2 = 3 })
|
||||
local meta = minetest.get_meta(above)
|
||||
meta:set_int("crops_top_half", 1)
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_node("crops:corn_base_2", {
|
||||
description = S("Corn plant"),
|
||||
drawtype = "plantlike",
|
||||
paramtype2 = "meshoptions",
|
||||
tiles = { "crops_corn_base_2.png" },
|
||||
use_texture_alpha = true,
|
||||
walkable = false,
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
groups = { snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1 },
|
||||
drop = {},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
on_dig = function(pos, node, digger)
|
||||
local above = {x = pos.x, y = pos.y + 1, z = pos.z}
|
||||
if minetest.get_node(above).name == "crops:corn_top_1" or minetest.get_node(above).name == "crops:corn_top_2" then
|
||||
minetest.remove_node(above)
|
||||
minetest.remove_node(pos)
|
||||
return
|
||||
end
|
||||
if not minetest.get_node(above).name == "crops:corn_top_3" then
|
||||
minetest.remove_node(pos)
|
||||
end
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
local damage = meta:get_int("crops_damage")
|
||||
local drops = {}
|
||||
-- 0 - 2-4
|
||||
-- 50 - 2-3
|
||||
-- 100 - 1-1
|
||||
for i = 1,math.random(2 - (damage / 100), 4 - (3 * (damage / 100))) do
|
||||
table.insert(drops, ('crops:corn_cob'))
|
||||
end
|
||||
minetest.set_node(pos, { name = "crops:corn_base_3", param2 = 3 })
|
||||
minetest.set_node(above, { name = "crops:corn_top_4", param2 = 3 })
|
||||
core.handle_node_drops(above, drops, digger)
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_node("crops:corn_base_3", {
|
||||
description = S("Corn plant"),
|
||||
drawtype = "plantlike",
|
||||
paramtype2 = "meshoptions",
|
||||
tiles = { "crops_corn_base_3.png" },
|
||||
use_texture_alpha = true,
|
||||
walkable = false,
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
groups = { snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1 },
|
||||
drop = {},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
on_dig = function(pos, node, digger)
|
||||
local above = {x = pos.x, y = pos.y + 1, z = pos.z}
|
||||
if minetest.get_node(above).name == "crops:corn_top_4" then
|
||||
minetest.remove_node(above)
|
||||
end
|
||||
minetest.remove_node(pos)
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_node("crops:corn_top_1", {
|
||||
description = S("Corn plant"),
|
||||
drawtype = "plantlike",
|
||||
paramtype2 = "meshoptions",
|
||||
tiles = { "crops_corn_base_1.png" },
|
||||
waving = 1,
|
||||
use_texture_alpha = true,
|
||||
walkable = false,
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
groups = { snappy=3,flammable=3,flora=1,not_in_creative_inventory=1 },
|
||||
drop = {},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
on_dig = function(pos, node, digger)
|
||||
local below = {x = pos.x, y = pos.y - 1, z = pos.z}
|
||||
if not minetest.get_node(below).name == "crops:base_2" then
|
||||
return
|
||||
end
|
||||
minetest.remove_node(below)
|
||||
minetest.remove_node(pos)
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = { "crops:corn_top_1" },
|
||||
neighbors = { "crops:corn_base_2" },
|
||||
interval = crops.settings.interval,
|
||||
chance = crops.settings.chance,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
if minetest.get_node_light(pos, nil) < crops.settings.light then
|
||||
return
|
||||
end
|
||||
minetest.swap_node(pos, { name = "crops:corn_top_2", param2 = 3 })
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_node("crops:corn_top_2", {
|
||||
description = S("Corn plant"),
|
||||
drawtype = "plantlike",
|
||||
paramtype2 = "meshoptions",
|
||||
tiles = { "crops_corn_top_1.png" },
|
||||
waving = 1,
|
||||
use_texture_alpha = true,
|
||||
walkable = false,
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
groups = { snappy=3,flammable=3,flora=1,not_in_creative_inventory=1 },
|
||||
drop = {},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
|
||||
on_dig = function(pos, node, digger)
|
||||
local below = {x = pos.x, y = pos.y - 1, z = pos.z}
|
||||
if not minetest.get_node(below).name == "crops:base_2" then
|
||||
return
|
||||
end
|
||||
minetest.remove_node(below)
|
||||
minetest.remove_node(pos)
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = { "crops:corn_top_2" },
|
||||
neighbors = { "crops:corn_base_2" },
|
||||
interval = crops.settings.interval,
|
||||
chance = crops.settings.chance,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
-- we don't call crops.grow here otherwise there would be 2 abm's hitting
|
||||
-- this stack, and dmg needs to be applied to the bottom part
|
||||
if minetest.get_node_light(pos, nil) < crops.settings.light then
|
||||
return
|
||||
end
|
||||
minetest.swap_node(pos, { name = "crops:corn_top_3", param2 = 3 })
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_node("crops:corn_top_3", {
|
||||
description = S("Corn plant"),
|
||||
drawtype = "plantlike",
|
||||
paramtype2 = "meshoptions",
|
||||
tiles = { "crops_corn_top_2.png" },
|
||||
waving = 1,
|
||||
use_texture_alpha = true,
|
||||
walkable = false,
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
groups = { snappy=3,flammable=3,flora=1,not_in_creative_inventory=1 },
|
||||
drop = {},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
|
||||
on_dig = function(pos, node, digger)
|
||||
local below = { x = pos.x, y = pos.y - 1, z = pos.z }
|
||||
local meta = minetest.get_meta(below)
|
||||
local damage = meta:get_int("crops_damage")
|
||||
local drops = {}
|
||||
-- 0 - 2-4
|
||||
-- 50 - 2-3
|
||||
-- 100 - 1-1
|
||||
for i = 1,math.random(2 - (damage / 100), 4 - (3 * (damage / 100))) do
|
||||
table.insert(drops, ('crops:corn_cob'))
|
||||
end
|
||||
crops.die(below)
|
||||
core.handle_node_drops(pos, drops, digger)
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_node("crops:corn_top_4", {
|
||||
description = S("Corn plant"),
|
||||
drawtype = "plantlike",
|
||||
paramtype2 = "meshoptions",
|
||||
tiles = { "crops_corn_top_3.png" },
|
||||
waving = 1,
|
||||
use_texture_alpha = true,
|
||||
walkable = false,
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
groups = { snappy=3,flammable=3,flora=1,not_in_creative_inventory=1 },
|
||||
drop = {},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
|
||||
on_dig = function(pos, node, digger)
|
||||
local below = {x = pos.x, y = pos.y - 1, z = pos.z}
|
||||
if minetest.get_node(below).name == "crops:corn_base_3" then
|
||||
minetest.remove_node(below)
|
||||
end
|
||||
minetest.remove_node(pos)
|
||||
end
|
||||
})
|
||||
|
||||
crops.corn_die = function(pos)
|
||||
minetest.set_node(pos, { name = "crops:corn_base_3", param2 = 3 })
|
||||
local above = {x = pos.x, y = pos.y + 1, z = pos.z}
|
||||
minetest.set_node(above, { name = "crops:corn_top_4", param2 = 3 })
|
||||
end
|
||||
|
||||
local properties = {
|
||||
die = crops.corn_die,
|
||||
waterstart = 40,
|
||||
wateruse = 1,
|
||||
night = 5,
|
||||
soak = 60,
|
||||
soak_damage = 75,
|
||||
wither = 10,
|
||||
wither_damage = 5,
|
||||
doublesize = true,
|
||||
}
|
||||
|
||||
crops.register({ name = "crops:corn_base_seed", properties = properties })
|
||||
crops.register({ name = "crops:corn_base_1", properties = properties })
|
||||
crops.register({ name = "crops:corn_base_2", properties = properties })
|
||||
crops.register({ name = "crops:corn_base_3", properties = properties })
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
--
|
||||
-- crops_settings.txt
|
||||
--
|
||||
-- These are the default difficulty settings for the crops mod. You can uncomment
|
||||
-- the "easy" or "difficult" settings if you wish, or come up with your own values.
|
||||
--
|
||||
|
||||
-- Valid values are "easy", "normal", and "difficult"
|
||||
crops.difficulty = "normal"
|
|
@ -0,0 +1,3 @@
|
|||
default
|
||||
farming
|
||||
intllib?
|
|
@ -0,0 +1,5 @@
|
|||
This mod expands the basic set of farming-related crops that minetest_game offers. It adds melons, potatoes, tomatoes, green beans and corn. The mod also implements plant humidity - you will have to water plants to make sure they're not dried out, or make sure they don't get over-watered.
|
||||
|
||||
Mod specific settings can be changed in the "crops_settings.txt" file in the world folder.
|
||||
|
||||
For more information, go to: http://goo.gl/wf0XLh
|
|
@ -0,0 +1,385 @@
|
|||
|
||||
--[[
|
||||
|
||||
Copyright (C) 2015 - Auke Kok <sofar@foo-projects.org>
|
||||
|
||||
"crops" is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1
|
||||
of the license, or (at your option) any later version.
|
||||
|
||||
--]]
|
||||
|
||||
crops = {}
|
||||
crops.plants = {}
|
||||
crops.settings = {}
|
||||
|
||||
local settings = {}
|
||||
settings.easy = {
|
||||
chance = 4,
|
||||
interval = 30,
|
||||
light = 8,
|
||||
watercan = 25,
|
||||
watercan_max = 90,
|
||||
watercan_uses = 20,
|
||||
damage_chance = 8,
|
||||
damage_interval = 30,
|
||||
damage_tick_min = 0,
|
||||
damage_tick_max = 1,
|
||||
damage_max = 25,
|
||||
hydration = false,
|
||||
}
|
||||
settings.normal = {
|
||||
chance = 8,
|
||||
interval = 30,
|
||||
light = 10,
|
||||
watercan = 25,
|
||||
watercan_max = 90,
|
||||
watercan_uses = 20,
|
||||
damage_chance = 8,
|
||||
damage_interval = 30,
|
||||
damage_tick_min = 0,
|
||||
damage_tick_max = 5,
|
||||
damage_max = 50,
|
||||
hydration = true,
|
||||
}
|
||||
settings.difficult = {
|
||||
chance = 16,
|
||||
interval = 30,
|
||||
light = 13,
|
||||
watercan = 25,
|
||||
watercan_max = 100,
|
||||
watercan_uses = 20,
|
||||
damage_chance = 4,
|
||||
damage_interval = 30,
|
||||
damage_tick_min = 3,
|
||||
damage_tick_max = 7,
|
||||
damage_max = 100,
|
||||
hydration = true,
|
||||
}
|
||||
|
||||
|
||||
local worldpath = minetest.get_worldpath()
|
||||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
|
||||
-- Load support for intllib.
|
||||
local S, _ = dofile(modpath .. "/intllib.lua")
|
||||
crops.intllib = S
|
||||
|
||||
|
||||
dofile(modpath .. "/crops_settings.txt")
|
||||
|
||||
if io.open(worldpath .. "/crops_settings.txt", "r") == nil then
|
||||
io.input(modpath .. "/crops_settings.txt")
|
||||
io.output(worldpath .. "/crops_settings.txt")
|
||||
|
||||
local size = 4096
|
||||
while true do
|
||||
local buf = io.read(size)
|
||||
if not buf then
|
||||
io.close()
|
||||
break
|
||||
end
|
||||
io.write(buf)
|
||||
end
|
||||
else
|
||||
dofile(worldpath .. "/crops_settings.txt")
|
||||
end
|
||||
|
||||
if not crops.difficulty then
|
||||
crops.difficulty = "normal"
|
||||
minetest.log("error", "[crops] "..S("Defaulting to \"normal\" difficulty settings"))
|
||||
end
|
||||
crops.settings = settings[crops.difficulty]
|
||||
if not crops.settings then
|
||||
minetest.log("error", "[crops] "..S("Defaulting to \"normal\" difficulty settings"))
|
||||
crops.settings = settings.normal
|
||||
end
|
||||
if crops.settings.hydration then
|
||||
minetest.log("action", "[crops] "..S("Hydration and dehydration mechanics are enabled."))
|
||||
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", "[crops] "..S("Unable to find plant \"@1\" in crops table", node.name))
|
||||
return nil
|
||||
end
|
||||
|
||||
crops.register = function(plantdef)
|
||||
table.insert(crops.plants, plantdef)
|
||||
end
|
||||
|
||||
crops.plant = function(pos, node)
|
||||
minetest.set_node(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local plant = find_plant(node)
|
||||
meta:set_int("crops_water", math.max(plant.properties.waterstart, 1))
|
||||
meta:set_int("crops_damage", 0)
|
||||
end
|
||||
|
||||
crops.can_grow = function(pos)
|
||||
if minetest.get_node_light(pos) < crops.settings.light then
|
||||
return false
|
||||
end
|
||||
local node = minetest.get_node(pos)
|
||||
local plant = find_plant(node)
|
||||
if not plant then
|
||||
return false
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
if crops.settings.hydration then
|
||||
local water = meta:get_int("crops_water")
|
||||
if water < plant.properties.wither or water > plant.properties.soak then
|
||||
if math.random(0,1) == 0 then
|
||||
return false
|
||||
end
|
||||
end
|
||||
-- growing costs water!
|
||||
meta:set_int("crops_water", math.max(1, water - 10))
|
||||
end
|
||||
|
||||
-- damaged plants are less likely to grow
|
||||
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
|
||||
|
||||
-- allow the plant to grow
|
||||
return true
|
||||
end
|
||||
|
||||
crops.particles = function(pos, flag)
|
||||
if flag == 0 then
|
||||
-- wither (0)
|
||||
minetest.add_particlespawner({
|
||||
amount = 1 * crops.settings.interval,
|
||||
time = crops.settings.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,
|
||||
})
|
||||
elseif flag == 1 then
|
||||
-- soak (1)
|
||||
minetest.add_particlespawner({
|
||||
amount = 8 * crops.settings.interval,
|
||||
time = crops.settings.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,
|
||||
})
|
||||
elseif flag == 2 then
|
||||
-- watering (2)
|
||||
minetest.add_particlespawner({
|
||||
amount = 30,
|
||||
time = 3,
|
||||
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.0, z = 0 },
|
||||
maxvel = { x = 0, y = 0.0, z = 0 },
|
||||
minacc = { x = 0, y = -9.81, z = 0 },
|
||||
maxacc = { x = 0, y = -9.81, z = 0 },
|
||||
minexptime = 2,
|
||||
maxexptime = 2,
|
||||
minsize = 1,
|
||||
maxsize = 3,
|
||||
collisiondetection = false,
|
||||
texture = "crops_watering.png",
|
||||
vertical = true,
|
||||
})
|
||||
else
|
||||
-- withered/rotting (3)
|
||||
minetest.add_particlespawner({
|
||||
amount = 20,
|
||||
time = 30,
|
||||
minpos = { x = pos.x + 0.3, y = pos.y - 0.5, z = pos.z - 0.5 },
|
||||
maxpos = { x = pos.x + 0.5, y = pos.y + 0.5, z = pos.z + 0.5 },
|
||||
minvel = { x = -0.6, y = -0.1, z = -0.2 },
|
||||
maxvel = { x = -0.4, y = 0.1, z = 0.2 },
|
||||
minacc = { x = 0.4, y = 0, z = -0.1 },
|
||||
maxacc = { x = 0.5, y = 0, z = 0.1 },
|
||||
minexptime = 2,
|
||||
maxexptime = 4,
|
||||
minsize = 1,
|
||||
maxsize = 1,
|
||||
collisiondetection = false,
|
||||
texture = "crops_flies.png",
|
||||
vertical = true,
|
||||
})
|
||||
minetest.add_particlespawner({
|
||||
amount = 20,
|
||||
time = 30,
|
||||
minpos = { x = pos.x - 0.3, y = pos.y - 0.5, z = pos.z - 0.5 },
|
||||
maxpos = { x = pos.x - 0.5, y = pos.y + 0.5, z = pos.z + 0.5 },
|
||||
minvel = { x = 0.6, y = -0.1, z = -0.2 },
|
||||
maxvel = { x = 0.4, y = 0.1, z = 0.2 },
|
||||
minacc = { x = -0.4, y = 0, z = -0.1 },
|
||||
maxacc = { x = -0.5, y = 0, z = 0.1 },
|
||||
minexptime = 2,
|
||||
maxexptime = 4,
|
||||
minsize = 1,
|
||||
maxsize = 1,
|
||||
collisiondetection = false,
|
||||
texture = "crops_flies.png",
|
||||
vertical = true,
|
||||
})
|
||||
minetest.add_particlespawner({
|
||||
amount = 20,
|
||||
time = 30,
|
||||
minpos = { x = pos.x - 0.5, y = pos.y - 0.5, z = pos.z + 0.3 },
|
||||
maxpos = { x = pos.x + 0.5, y = pos.y + 0.5, z = pos.z + 0.5 },
|
||||
minvel = { z = -0.6, y = -0.1, x = -0.2 },
|
||||
maxvel = { z = -0.4, y = 0.1, x = 0.2 },
|
||||
minacc = { z = 0.4, y = 0, x = -0.1 },
|
||||
maxacc = { z = 0.5, y = 0, x = 0.1 },
|
||||
minexptime = 2,
|
||||
maxexptime = 4,
|
||||
minsize = 1,
|
||||
maxsize = 1,
|
||||
collisiondetection = false,
|
||||
texture = "crops_flies.png",
|
||||
vertical = true,
|
||||
})
|
||||
minetest.add_particlespawner({
|
||||
amount = 20,
|
||||
time = 30,
|
||||
minpos = { x = pos.x - 0.5, y = pos.y - 0.5, z = pos.z - 0.3 },
|
||||
maxpos = { x = pos.x + 0.5, y = pos.y + 0.5, z = pos.z - 0.5 },
|
||||
minvel = { z = 0.6, y = -0.1, x = -0.2 },
|
||||
maxvel = { z = 0.4, y = 0.1, x = 0.2 },
|
||||
minacc = { z = -0.4, y = 0, x = -0.1 },
|
||||
maxacc = { z = -0.5, y = 0, x = 0.1 },
|
||||
minexptime = 2,
|
||||
maxexptime = 4,
|
||||
minsize = 1,
|
||||
maxsize = 1,
|
||||
collisiondetection = false,
|
||||
texture = "crops_flies.png",
|
||||
vertical = true,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
crops.die = function(pos)
|
||||
crops.particles(pos, 3)
|
||||
local node = minetest.get_node(pos)
|
||||
local plant = find_plant(node)
|
||||
plant.properties.die(pos)
|
||||
minetest.sound_play("crops_flies", {pos=pos, gain=0.8})
|
||||
end
|
||||
|
||||
if crops.settings.hydration then
|
||||
dofile(modpath .. "/tools.lua")
|
||||
end
|
||||
|
||||
-- crop nodes, crafts, craftitems
|
||||
dofile(modpath .. "/melon.lua")
|
||||
dofile(modpath .. "/pumpkin.lua")
|
||||
dofile(modpath .. "/corn.lua")
|
||||
dofile(modpath .. "/tomato.lua")
|
||||
dofile(modpath .. "/potato.lua")
|
||||
dofile(modpath .. "/polebean.lua")
|
||||
|
||||
local nodenames = {}
|
||||
for i = 1,table.getn(crops.plants) do
|
||||
table.insert(nodenames, crops.plants[i].name)
|
||||
end
|
||||
|
||||
-- water handling code
|
||||
if crops.settings.hydration then
|
||||
minetest.register_abm({
|
||||
nodenames = nodenames,
|
||||
interval = crops.settings.damage_interval,
|
||||
chance = crops.settings.damage_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
|
||||
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
|
||||
|
||||
if minetest.get_node_light(pos, nil) < plant.properties.night then
|
||||
-- compensate for light: at night give some water back to the plant
|
||||
water = math.min(100, water + 1)
|
||||
else
|
||||
-- dry out the plant
|
||||
water = math.max(1, water - plant.properties.wateruse)
|
||||
end
|
||||
|
||||
meta:set_int("crops_water", water)
|
||||
|
||||
-- for convenience, copy water attribute to top half
|
||||
if not plant.properties.doublesize == nil and plant.properties.doublesize then
|
||||
local above = { x = pos.x, y = pos.y + 1, z = pos.z}
|
||||
local abovemeta = minetest.get_meta(above)
|
||||
abovemeta:set_int("crops_water", water)
|
||||
end
|
||||
|
||||
if water <= plant.properties.wither_damage then
|
||||
crops.particles(pos, 0)
|
||||
damage = damage + math.random(crops.settings.damage_tick_min, crops.settings.damage_tick_max)
|
||||
elseif water <= plant.properties.wither then
|
||||
crops.particles(pos, 0)
|
||||
return
|
||||
elseif water >= plant.properties.soak_damage then
|
||||
crops.particles(pos, 1)
|
||||
damage = damage + math.random(crops.settings.damage_tick_min, crops.settings.damage_tick_max)
|
||||
elseif water >= plant.properties.soak then
|
||||
crops.particles(pos, 1)
|
||||
return
|
||||
end
|
||||
meta:set_int("crops_damage", math.min(crops.settings.damage_max, damage))
|
||||
|
||||
-- is it dead?
|
||||
if damage >= 100 then
|
||||
crops.die(pos)
|
||||
end
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
-- cooking recipes that mix craftitems
|
||||
dofile(modpath .. "/cooking.lua")
|
||||
dofile(modpath .. "/mapgen.lua")
|
||||
|
||||
minetest.log("action", "[crops] "..S("Loaded!"))
|
|
@ -0,0 +1,44 @@
|
|||
-- Fallback functions for when `intllib` is not installed.
|
||||
-- Code released under Unlicense <http://unlicense.org>.
|
||||
|
||||
-- Get the latest version of this file at:
|
||||
-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua
|
||||
|
||||
local function format(str, ...)
|
||||
local args = { ... }
|
||||
local function repl(escape, open, num, close)
|
||||
if escape == "" then
|
||||
local replacement = tostring(args[tonumber(num)])
|
||||
if open == "" then
|
||||
replacement = replacement..close
|
||||
end
|
||||
return replacement
|
||||
else
|
||||
return "@"..open..num..close
|
||||
end
|
||||
end
|
||||
return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl))
|
||||
end
|
||||
|
||||
local gettext, ngettext
|
||||
if minetest.get_modpath("intllib") then
|
||||
if intllib.make_gettext_pair then
|
||||
-- New method using gettext.
|
||||
gettext, ngettext = intllib.make_gettext_pair()
|
||||
else
|
||||
-- Old method using text files.
|
||||
gettext = intllib.Getter()
|
||||
end
|
||||
end
|
||||
|
||||
-- Fill in missing functions.
|
||||
|
||||
gettext = gettext or function(msgid, ...)
|
||||
return format(msgid, ...)
|
||||
end
|
||||
|
||||
ngettext = ngettext or function(msgid, msgid_plural, n, ...)
|
||||
return format(n==1 and msgid or msgid_plural, ...)
|
||||
end
|
||||
|
||||
return gettext, ngettext
|
|
@ -0,0 +1,48 @@
|
|||
|
||||
local mg_params = minetest.get_mapgen_params()
|
||||
if mg_params.mgname ~= "v6" and mg_params.mgname ~= "singlenode" then
|
||||
minetest.register_decoration({
|
||||
deco_type = "simple",
|
||||
place_on = { "default:dirt_with_grass" },
|
||||
sidelen = 16,
|
||||
noise_params = {
|
||||
offset = -0.02,
|
||||
scale = 0.02,
|
||||
spread = {x = 200, y = 200, z = 200},
|
||||
seed = 90459126,
|
||||
octaves = 3,
|
||||
persist = 0.6
|
||||
},
|
||||
biomes = {"grassland", "deciduous_forest", "coniferous_forest"},
|
||||
y_min = 1,
|
||||
y_max = 31000,
|
||||
decoration = "crops:melon_plant_4"
|
||||
})
|
||||
minetest.register_decoration({
|
||||
deco_type = "simple",
|
||||
place_on = { "default:dirt_with_grass" },
|
||||
sidelen = 16,
|
||||
noise_params = {
|
||||
offset = -0.02,
|
||||
scale = 0.02,
|
||||
spread = {x = 200, y = 200, z = 200},
|
||||
seed = 26294592,
|
||||
octaves = 3,
|
||||
persist = 0.6
|
||||
},
|
||||
biomes = {"deciduous_forest", "coniferous_forest", "tundra"},
|
||||
y_min = 1,
|
||||
y_max = 31000,
|
||||
decoration = "crops:pumpkin_plant_4"
|
||||
})
|
||||
end
|
||||
|
||||
-- drop potatoes when digging in dirt
|
||||
minetest.override_item("default:dirt_with_grass", {
|
||||
drop = {
|
||||
items = {
|
||||
{ items = {'default:dirt'}},
|
||||
{ items = {'crops:potato'}, rarity = 500 }
|
||||
}
|
||||
}
|
||||
})
|
|
@ -0,0 +1,249 @@
|
|||
|
||||
--[[
|
||||
|
||||
Copyright (C) 2015 - Auke Kok <sofar@foo-projects.org>
|
||||
|
||||
"crops" is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1
|
||||
of the license, or (at your option) any later version.
|
||||
|
||||
--]]
|
||||
|
||||
-- Intllib
|
||||
local S = crops.intllib
|
||||
|
||||
local faces = {
|
||||
[1] = { x = -1, z = 0, r = 3, o = 1, m = 14 },
|
||||
[2] = { x = 1, z = 0, r = 1, o = 3, m = 16 },
|
||||
[3] = { x = 0, z = -1, r = 2, o = 0, m = 5 },
|
||||
[4] = { x = 0, z = 1, r = 0, o = 2, m = 11 }
|
||||
}
|
||||
|
||||
minetest.register_node("crops:melon_seed", {
|
||||
description = S("Melon seed"),
|
||||
inventory_image = "crops_melon_seed.png",
|
||||
wield_image = "crops_melon_seed.png",
|
||||
tiles = { "crops_melon_plant_1.png" },
|
||||
drawtype = "plantlike",
|
||||
waving = 1,
|
||||
sunlight_propagates = false,
|
||||
use_texture_alpha = true,
|
||||
walkable = false,
|
||||
paramtype = "light",
|
||||
node_placement_prediction = "crops:melon_plant_1",
|
||||
groups = { snappy=3,flammable=3,flora=1,attached_node=1 },
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
local under = minetest.get_node(pointed_thing.under)
|
||||
if minetest.get_item_group(under.name, "soil") <= 1 then
|
||||
return
|
||||
end
|
||||
crops.plant(pointed_thing.above, {name="crops:melon_plant_1"})
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
itemstack:take_item()
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
})
|
||||
|
||||
for stage = 1, 6 do
|
||||
minetest.register_node("crops:melon_plant_" .. stage , {
|
||||
description = S("Melon plant"),
|
||||
tiles = { "crops_melon_plant_" .. stage .. ".png" },
|
||||
drawtype = "plantlike",
|
||||
waving = 1,
|
||||
sunlight_propagates = true,
|
||||
use_texture_alpha = true,
|
||||
walkable = false,
|
||||
paramtype = "light",
|
||||
groups = { snappy=3, flammable=3, flora=1, attached_node=1, not_in_creative_inventory=1 },
|
||||
drop = "crops:melon_seed",
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, 0.5, -0.5 + (((math.min(stage, 4)) + 1) / 5), 0.5}
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_node("crops:melon_plant_5_attached", {
|
||||
visual = "mesh",
|
||||
mesh = "crops_plant_extra_face.obj",
|
||||
description = S("Melon plant"),
|
||||
tiles = { "crops_melon_stem.png", "crops_melon_plant_4.png" },
|
||||
drawtype = "mesh",
|
||||
paramtype2 = "facedir",
|
||||
sunlight_propagates = true,
|
||||
use_texture_alpha = true,
|
||||
walkable = false,
|
||||
paramtype = "light",
|
||||
groups = { snappy=3, flammable=3, flora=1, attached_node=1, not_in_creative_inventory=1 },
|
||||
drop = "crops:melon_seed",
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
})
|
||||
|
||||
|
||||
minetest.register_craftitem("crops:melon_slice", {
|
||||
description = S("Melon slice"),
|
||||
inventory_image = "crops_melon_slice.png",
|
||||
on_use = minetest.item_eat(1)
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "crops:melon_seed",
|
||||
recipe = { "crops:melon_slice" }
|
||||
})
|
||||
|
||||
--
|
||||
-- the melon "block"
|
||||
--
|
||||
minetest.register_node("crops:melon", {
|
||||
description = S("Melon"),
|
||||
tiles = {
|
||||
"crops_melon_top.png",
|
||||
"crops_melon_bottom.png",
|
||||
"crops_melon.png",
|
||||
},
|
||||
sunlight_propagates = false,
|
||||
use_texture_alpha = false,
|
||||
walkable = true,
|
||||
groups = { snappy=3, flammable=3, oddly_breakable_by_hand=2 },
|
||||
paramtype2 = "facedir",
|
||||
drop = {},
|
||||
sounds = default.node_sound_wood_defaults({
|
||||
dig = { name = "default_dig_oddly_breakable_by_hand" },
|
||||
dug = { name = "default_dig_choppy" }
|
||||
}),
|
||||
on_dig = function(pos, node, digger)
|
||||
for face = 1, 4 do
|
||||
local s = { x = pos.x + faces[face].x, y = pos.y, z = pos.z + faces[face].z }
|
||||
local n = minetest.get_node(s)
|
||||
if n.name == "crops:melon_plant_5_attached" then
|
||||
-- make sure it was actually attached to this stem
|
||||
if n.param2 == faces[face].o then
|
||||
minetest.swap_node(s, { name = "crops:melon_plant_4" })
|
||||
end
|
||||
end
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local damage = meta:get_int("crops_damage")
|
||||
local drops = {}
|
||||
-- 0 dmg - 3-5
|
||||
-- 50 dmg - 2-3
|
||||
-- 100 dmg - 1-1
|
||||
for i = 1,math.random(3 - (2 * (damage / 100)), 5 - (4 * (damage / 100))) do
|
||||
table.insert(drops, ('crops:melon_slice'))
|
||||
end
|
||||
core.handle_node_drops(pos, drops, digger)
|
||||
minetest.remove_node(pos)
|
||||
end
|
||||
})
|
||||
|
||||
--
|
||||
-- grows a plant to mature size
|
||||
--
|
||||
minetest.register_abm({
|
||||
nodenames = { "crops:melon_plant_1", "crops:melon_plant_2", "crops:melon_plant_3","crops:melon_plant_4" },
|
||||
neighbors = { "group:soil" },
|
||||
interval = crops.settings.interval,
|
||||
chance = crops.settings.chance,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
if not crops.can_grow(pos) then
|
||||
return
|
||||
end
|
||||
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.swap_node(pos, { name = n })
|
||||
end
|
||||
})
|
||||
|
||||
--
|
||||
-- grows a melon
|
||||
--
|
||||
minetest.register_abm({
|
||||
nodenames = { "crops:melon_plant_5" },
|
||||
neighbors = { "group:soil" },
|
||||
interval = crops.settings.interval,
|
||||
chance = crops.settings.chance,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
if not crops.can_grow(pos) then
|
||||
return
|
||||
end
|
||||
for face = 1, 4 do
|
||||
local t = { x = pos.x + faces[face].x, y = pos.y, z = pos.z + faces[face].z }
|
||||
if minetest.get_node(t).name == "crops:melon" then
|
||||
return
|
||||
end
|
||||
end
|
||||
local r = math.random(1, 4)
|
||||
local t = { x = pos.x + faces[r].x, y = pos.y, z = pos.z + faces[r].z }
|
||||
local n = minetest.get_node(t)
|
||||
if n.name == "ignore" then
|
||||
return
|
||||
end
|
||||
|
||||
if minetest.registered_nodes[minetest.get_node({ x = t.x, y = t.y - 1, z = t.z }).name].walkable == false then
|
||||
return
|
||||
end
|
||||
|
||||
if minetest.registered_nodes[n.name].drawtype == "plantlike" or
|
||||
minetest.registered_nodes[n.name].groups.flora == 1 or
|
||||
n.name == "air" then
|
||||
minetest.swap_node(pos, {name = "crops:melon_plant_5_attached", param2 = faces[r].r})
|
||||
minetest.set_node(t, {name = "crops:melon", param2 = faces[r].m})
|
||||
local meta = minetest.get_meta(pos)
|
||||
local damage = meta:get_int("crops_damage")
|
||||
local water = meta:get_int("crops_water")
|
||||
-- growing a melon costs 25 water!
|
||||
meta:set_int("crops_water", math.max(0, water - 25))
|
||||
meta = minetest.get_meta(t)
|
||||
-- reflect plants' damage in the melon yield
|
||||
meta:set_int("crops_damage", damage)
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
--
|
||||
-- return a melon to a normal one if there is no melon attached, so it can
|
||||
-- grow a new melon again
|
||||
--
|
||||
minetest.register_abm({
|
||||
nodenames = { "crops:melon_plant_5_attached" },
|
||||
interval = crops.settings.interval,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
for face = 1, 4 do
|
||||
local t = { x = pos.x + faces[face].x, y = pos.y, z = pos.z + faces[face].z }
|
||||
if minetest.get_node(t).name == "crops:melon" then
|
||||
return
|
||||
end
|
||||
end
|
||||
minetest.swap_node(pos, {name = "crops:melon_plant_4" })
|
||||
end
|
||||
})
|
||||
|
||||
crops.melon_die = function(pos)
|
||||
minetest.set_node(pos, { name = "crops:melon_plant_6" })
|
||||
end
|
||||
|
||||
local properties = {
|
||||
die = crops.melon_die,
|
||||
waterstart = 20,
|
||||
wateruse = 1,
|
||||
night = 5,
|
||||
soak = 80,
|
||||
soak_damage = 90,
|
||||
wither = 20,
|
||||
wither_damage = 10,
|
||||
}
|
||||
|
||||
crops.register({ name = "crops:melon_plant_1", properties = properties })
|
||||
crops.register({ name = "crops:melon_plant_2", properties = properties })
|
||||
crops.register({ name = "crops:melon_plant_3", properties = properties })
|
||||
crops.register({ name = "crops:melon_plant_4", properties = properties })
|
||||
crops.register({ name = "crops:melon_plant_5", properties = properties })
|
||||
crops.register({ name = "crops:melon_plant_5_attached", properties = properties })
|
|
@ -0,0 +1 @@
|
|||
name = crops
|
|
@ -0,0 +1,49 @@
|
|||
# Blender v2.60 (sub 0) OBJ File: 'p1.blend'
|
||||
# www.blender.org
|
||||
mtllib crops_plant_extra_face.mtl
|
||||
o Mesh_Stem_Stem
|
||||
v -0.000000 0.500000 0.500000
|
||||
v 0.000000 -0.500000 0.500000
|
||||
v 0.000000 -0.500000 -0.500000
|
||||
v -0.000000 0.500000 -0.500000
|
||||
vt 0.000000 0.000000
|
||||
vt 1.000000 0.000000
|
||||
vt 1.000000 1.000000
|
||||
vt 0.000000 1.000000
|
||||
vn 1.000000 0.000000 -0.000000
|
||||
g Mesh_Stem_Stem_Material.002
|
||||
usemtl Material.002
|
||||
s off
|
||||
f 1/1/1 2/2/1 3/3/1 4/4/1
|
||||
o Mesh_Plant_Plant
|
||||
v 0.359670 -0.500000 0.347329
|
||||
v 0.359670 0.500000 0.347329
|
||||
v -0.359670 0.500000 -0.347329
|
||||
v -0.359670 -0.500000 -0.347329
|
||||
v -0.347329 -0.500000 0.359670
|
||||
v -0.347329 0.500000 0.359670
|
||||
v 0.347329 0.500000 -0.359670
|
||||
v 0.347329 -0.500000 -0.359670
|
||||
v 0.359670 -0.500000 0.347329
|
||||
v -0.359670 -0.500000 -0.347329
|
||||
v -0.359670 0.500000 -0.347329
|
||||
v 0.359670 0.500000 0.347329
|
||||
v -0.347329 -0.500000 0.359670
|
||||
v 0.347329 -0.500000 -0.359670
|
||||
v 0.347329 0.500000 -0.359670
|
||||
v -0.347329 0.500000 0.359670
|
||||
vt 1.000000 0.000000
|
||||
vt 1.000000 1.000000
|
||||
vt 0.000000 1.000000
|
||||
vt 0.000000 0.000000
|
||||
vn -0.694658 0.000000 0.719340
|
||||
vn -0.719340 -0.000000 -0.694658
|
||||
vn 0.694658 -0.000000 -0.719340
|
||||
vn 0.719340 0.000000 0.694658
|
||||
g Mesh_Plant_Plant_Material.001
|
||||
usemtl Material.001
|
||||
s off
|
||||
f 5/5/2 6/6/2 7/7/2 8/8/2
|
||||
f 9/5/3 10/6/3 11/7/3 12/8/3
|
||||
f 13/5/4 14/8/4 15/7/4 16/6/4
|
||||
f 17/5/5 18/8/5 19/7/5 20/6/5
|
|
@ -0,0 +1,309 @@
|
|||
|
||||
--[[
|
||||
|
||||
Copyright (C) 2015 - Auke Kok <sofar@foo-projects.org>
|
||||
|
||||
"crops" is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1
|
||||
of the license, or (at your option) any later version.
|
||||
|
||||
--]]
|
||||
|
||||
-- Intllib
|
||||
local S = crops.intllib
|
||||
|
||||
minetest.register_craft({
|
||||
output = "crops:beanpoles",
|
||||
recipe = {
|
||||
{'', '', ''},
|
||||
{'default:stick', '', 'default:stick'},
|
||||
{'default:stick', '', 'default:stick'},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craftitem("crops:green_bean", {
|
||||
description = S("Green Bean"),
|
||||
inventory_image = "crops_green_bean.png",
|
||||
on_use = minetest.item_eat(1)
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "crops:green_bean_seed",
|
||||
recipe = { "crops:green_bean" }
|
||||
})
|
||||
|
||||
local function crops_beanpole_on_dig(pos, node, digger)
|
||||
local bottom
|
||||
local bottom_n
|
||||
local top
|
||||
local top_n
|
||||
local drops = {}
|
||||
|
||||
if node.name == "crops:beanpole_base" or
|
||||
node.name == "crops:beanpole_plant_base_1" or
|
||||
node.name == "crops:beanpole_plant_base_2" or
|
||||
node.name == "crops:beanpole_plant_base_3" or --grown tall enough for top section
|
||||
node.name == "crops:beanpole_plant_base_4" or --flowering
|
||||
node.name == "crops:beanpole_plant_base_5" or --ripe
|
||||
node.name == "crops:beanpole_plant_base_6" --harvested
|
||||
then
|
||||
bottom = pos
|
||||
bottom_n = node
|
||||
top = { x = pos.x, y = pos.y + 1, z = pos.z }
|
||||
top_n = minetest.get_node(top)
|
||||
elseif node.name == "crops:beanpole_top" or
|
||||
node.name == "crops:beanpole_plant_top_1" or
|
||||
node.name == "crops:beanpole_plant_top_2" or --flowering
|
||||
node.name == "crops:beanpole_plant_top_3" or --ripe
|
||||
node.name == "crops:beanpole_plant_top_4" --harvested
|
||||
then
|
||||
top = pos
|
||||
top_n = node
|
||||
bottom = { x = pos.x, y = pos.y - 1, z = pos.z }
|
||||
bottom_n = minetest.get_node(bottom)
|
||||
else
|
||||
-- ouch, this shouldn't happen
|
||||
print("beanpole on_dig falsely attached to: " .. pos.x .. "," .. pos.y .. "," .. pos.z)
|
||||
return
|
||||
end
|
||||
|
||||
if bottom_n.name == "crops:beanpole_base" and top_n.name == "crops:beanpole_top" then
|
||||
-- bare beanpole
|
||||
table.insert(drops, "crops:beanpoles")
|
||||
minetest.remove_node(bottom)
|
||||
minetest.remove_node(top)
|
||||
elseif (
|
||||
bottom_n.name == "crops:beanpole_plant_base_1" or
|
||||
bottom_n.name == "crops:beanpole_plant_base_2" or
|
||||
bottom_n.name == "crops:beanpole_plant_base_3" or
|
||||
bottom_n.name == "crops:beanpole_plant_base_4"
|
||||
) and (
|
||||
top_n.name == "crops:beanpole_top" or
|
||||
top_n.name == "crops:beanpole_plant_top_1" or
|
||||
top_n.name == "crops:beanpole_plant_top_2"
|
||||
) then
|
||||
-- non-ripe
|
||||
for i = 1,4 do
|
||||
table.insert(drops, "default:stick")
|
||||
end
|
||||
minetest.set_node(bottom, { name = "crops:beanpole_base"})
|
||||
minetest.set_node(top, { name = "crops:beanpole_top"})
|
||||
elseif bottom_n.name == "crops:beanpole_plant_base_5" and top_n.name == "crops:beanpole_plant_top_3" then
|
||||
-- ripe beanpole
|
||||
local meta = minetest.get_meta(bottom)
|
||||
local damage = meta:get_int("crops_damage")
|
||||
-- 0 - 3-7
|
||||
-- 50 - 2-4
|
||||
-- 100 - 1-1
|
||||
for i = 1,math.random(3 - (2 * (damage / 100)),7 - (6 * (damage / 100))) do
|
||||
table.insert(drops, "crops:green_bean")
|
||||
end
|
||||
crops.die(bottom)
|
||||
elseif bottom_n.name == "crops:beanpole_plant_base_6" and top_n.name == "crops:beanpole_plant_top_4" then
|
||||
-- harvested beans
|
||||
for i = 1,math.random(3,4) do
|
||||
table.insert(drops, "default:stick")
|
||||
end
|
||||
minetest.remove_node(bottom)
|
||||
minetest.remove_node(top)
|
||||
else
|
||||
-- ouch, this shouldn't happen
|
||||
print("beanpole on_dig can't handle blocks at to: " ..
|
||||
bottom.x .. "," .. bottom.y .. "," .. bottom.z ..
|
||||
" and " .. top.x .. "," .. top.y .. "," .. top.z)
|
||||
print("removing a " .. node.name .. " at " ..
|
||||
pos.x .. "," .. pos.y .. "," .. pos.z)
|
||||
minetest.remove_node(pos)
|
||||
return
|
||||
end
|
||||
|
||||
core.handle_node_drops(pos, drops, digger)
|
||||
end
|
||||
|
||||
minetest.register_node("crops:beanpole_base", {
|
||||
description = "",
|
||||
drawtype = "plantlike",
|
||||
tiles = { "crops_beanpole_base.png" },
|
||||
use_texture_alpha = true,
|
||||
walkable = true,
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
groups = { snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1 },
|
||||
drop = {},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
on_dig = crops_beanpole_on_dig,
|
||||
})
|
||||
|
||||
minetest.register_node("crops:beanpole_top", {
|
||||
description = "",
|
||||
drawtype = "plantlike",
|
||||
tiles = { "crops_beanpole_top.png" },
|
||||
use_texture_alpha = true,
|
||||
walkable = true,
|
||||
sunlight_propagates = true,
|
||||
paramtype = "light",
|
||||
groups = { snappy=3,flammable=3,flora=1,not_in_creative_inventory=1 },
|
||||
drop = {},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
on_dig = crops_beanpole_on_dig,
|
||||
})
|
||||
|
||||
minetest.register_node("crops:beanpoles", {
|
||||
description = S("Beanpoles"),
|
||||
inventory_image = "crops_beanpole_top.png",
|
||||
wield_image = "crops_beanpole_top.png",
|
||||
tiles = { "crops_beanpole_base.png" },
|
||||
drawtype = "plantlike",
|
||||
sunlight_propagates = true,
|
||||
use_texture_alpha = true,
|
||||
paramtype = "light",
|
||||
groups = { snappy=3,flammable=3,flora=1,attached_node=1 },
|
||||
drop = {},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
node_placement_prediction = "crops:beanpole_base",
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
local under = minetest.get_node(pointed_thing.under)
|
||||
if minetest.get_item_group(under.name, "soil") <= 1 then
|
||||
return
|
||||
end
|
||||
local top = { x = pointed_thing.above.x, y = pointed_thing.above.y + 1, z = pointed_thing.above.z }
|
||||
if not minetest.get_node(top).name == "air" then
|
||||
return
|
||||
end
|
||||
minetest.set_node(pointed_thing.above, {name="crops:beanpole_base"})
|
||||
minetest.set_node(top, {name="crops:beanpole_top"})
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
itemstack:take_item()
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_craftitem("crops:green_bean_seed", {
|
||||
description = S("Green bean seed"),
|
||||
inventory_image = "crops_green_bean_seed.png",
|
||||
wield_image = "crops_green_bean_seed.png",
|
||||
node_placement_prediction = "", -- disabled, prediction assumes pointed_think.above!
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
local under = minetest.get_node(pointed_thing.under)
|
||||
if under.name == "crops:beanpole_base" then
|
||||
crops.plant(pointed_thing.under, {name="crops:beanpole_plant_base_1"})
|
||||
local above = { x = pointed_thing.under.x, y = pointed_thing.under.y + 1, z = pointed_thing.under.z}
|
||||
local meta = minetest.get_meta(above)
|
||||
meta:set_int("crops_top_half", 1)
|
||||
elseif under.name == "crops:beanpole_top" then
|
||||
local below = { x = pointed_thing.under.x, y = pointed_thing.under.y - 1, z = pointed_thing.under.z }
|
||||
if minetest.get_node(below).name == "crops:beanpole_base" then
|
||||
crops.plant(below, {name="crops:beanpole_plant_base_1"})
|
||||
local meta = minetest.get_meta(pointed_thing.under)
|
||||
meta:set_int("crops_top_half", 1)
|
||||
else
|
||||
return
|
||||
end
|
||||
else
|
||||
return
|
||||
end
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
itemstack:take_item()
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
})
|
||||
|
||||
for stage = 1,6 do
|
||||
minetest.register_node("crops:beanpole_plant_base_" .. stage, {
|
||||
description = S("Green Bean plant"),
|
||||
tiles = { "crops_beanpole_plant_base_" .. stage .. ".png" },
|
||||
drawtype = "plantlike",
|
||||
sunlight_propagates = true,
|
||||
use_texture_alpha = true,
|
||||
paramtype = "light",
|
||||
walkable = false,
|
||||
groups = { snappy=3,flammable=3,flora=1,attached_node=1,not_in_creative_inventory=1 },
|
||||
drop = {},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
on_dig = crops_beanpole_on_dig
|
||||
})
|
||||
end
|
||||
|
||||
for stage = 1,4 do
|
||||
minetest.register_node("crops:beanpole_plant_top_" .. stage, {
|
||||
description = S("Green Bean plant"),
|
||||
tiles = { "crops_beanpole_plant_top_" .. stage .. ".png" },
|
||||
drawtype = "plantlike",
|
||||
sunlight_propagates = true,
|
||||
use_texture_alpha = true,
|
||||
paramtype = "light",
|
||||
walkable = true,
|
||||
groups = { snappy=3,flammable=3,flora=1,not_in_creative_inventory=1 },
|
||||
drop = {},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
on_dig = crops_beanpole_on_dig
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {
|
||||
"crops:beanpole_plant_base_1",
|
||||
"crops:beanpole_plant_base_2",
|
||||
"crops:beanpole_plant_base_3",
|
||||
"crops:beanpole_plant_base_4"
|
||||
},
|
||||
interval = crops.settings.interval,
|
||||
chance = crops.settings.chance,
|
||||
neighbors = { "group:soil" },
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
if not crops.can_grow(pos) then
|
||||
return
|
||||
end
|
||||
if node.name == "crops:beanpole_plant_base_1" then
|
||||
minetest.swap_node(pos, { name = "crops:beanpole_plant_base_2"})
|
||||
elseif node.name == "crops:beanpole_plant_base_2" then
|
||||
minetest.swap_node(pos, { name = "crops:beanpole_plant_base_3"})
|
||||
elseif node.name == "crops:beanpole_plant_base_3" then
|
||||
local apos = {x = pos.x, y = pos.y + 1, z = pos.z}
|
||||
local above = minetest.get_node(apos)
|
||||
if above.name == "crops:beanpole_top" then
|
||||
minetest.set_node(apos, { name = "crops:beanpole_plant_top_1" })
|
||||
local meta = minetest.get_meta(apos)
|
||||
meta:set_int("crops_top_half", 1)
|
||||
elseif above.name == "crops:beanpole_plant_top_1" then
|
||||
minetest.swap_node(pos, { name = "crops:beanpole_plant_base_4" })
|
||||
minetest.swap_node(apos, { name = "crops:beanpole_plant_top_2" })
|
||||
end
|
||||
elseif node.name == "crops:beanpole_plant_base_4" then
|
||||
local apos = {x = pos.x, y = pos.y + 1, z = pos.z}
|
||||
minetest.swap_node(pos, { name = "crops:beanpole_plant_base_5" })
|
||||
minetest.swap_node(apos, { name = "crops:beanpole_plant_top_3" })
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
crops.beanpole_die = function(pos)
|
||||
minetest.set_node(pos, { name = "crops:beanpole_plant_base_6" })
|
||||
local above = {x = pos.x, y = pos.y + 1, z = pos.z}
|
||||
minetest.set_node(above, { name = "crops:beanpole_plant_top_4" })
|
||||
end
|
||||
|
||||
local properties = {
|
||||
die = crops.beanpole_die,
|
||||
waterstart = 30,
|
||||
wateruse = 1,
|
||||
night = 5,
|
||||
soak = 60,
|
||||
soak_damage = 75,
|
||||
wither = 25,
|
||||
wither_damage = 15,
|
||||
doublesize = true,
|
||||
}
|
||||
|
||||
crops.register({ name = "crops:beanpole_plant_base_1", properties = properties })
|
||||
crops.register({ name = "crops:beanpole_plant_base_2", properties = properties })
|
||||
crops.register({ name = "crops:beanpole_plant_base_3", properties = properties })
|
||||
crops.register({ name = "crops:beanpole_plant_base_4", properties = properties })
|
||||
crops.register({ name = "crops:beanpole_plant_base_5", properties = properties })
|
||||
|
|
@ -0,0 +1,196 @@
|
|||
|
||||
--[[
|
||||
|
||||
Copyright (C) 2015 - Auke Kok <sofar@foo-projects.org>
|
||||
|
||||
"crops" is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1
|
||||
of the license, or (at your option) any later version.
|
||||
|
||||
--]]
|
||||
|
||||
-- Intllib
|
||||
local S = crops.intllib
|
||||
|
||||
minetest.register_node("crops:potato_eyes", {
|
||||
description = S("Potato eyes"),
|
||||
inventory_image = "crops_potato_eyes.png",
|
||||
wield_image = "crops_potato_eyes.png",
|
||||
tiles = { "crops_potato_plant_1.png" },
|
||||
drawtype = "plantlike",
|
||||
paramtype2 = "meshoptions",
|
||||
waving = 1,
|
||||
sunlight_propagates = false,
|
||||
use_texture_alpha = true,
|
||||
walkable = false,
|
||||
paramtype = "light",
|
||||
node_placement_prediction = "crops:potato_plant_1",
|
||||
groups = { snappy=3,flammable=3,flora=1,attached_node=1 },
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.45, -0.5, -0.45, 0.45, -0.4, 0.45}
|
||||
},
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
local under = minetest.get_node(pointed_thing.under)
|
||||
if minetest.get_item_group(under.name, "soil") <= 1 then
|
||||
return
|
||||
end
|
||||
crops.plant(pointed_thing.above, {name="crops:potato_plant_1", param2 = 3})
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
itemstack:take_item()
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
})
|
||||
|
||||
for stage = 1, 5 do
|
||||
minetest.register_node("crops:potato_plant_" .. stage , {
|
||||
description = S("Potato plant"),
|
||||
tiles = { "crops_potato_plant_" .. stage .. ".png" },
|
||||
drawtype = "plantlike",
|
||||
paramtype2 = "meshoptions",
|
||||
waving = 1,
|
||||
sunlight_propagates = true,
|
||||
use_texture_alpha = true,
|
||||
walkable = false,
|
||||
paramtype = "light",
|
||||
groups = { snappy=3, flammable=3, flora=1, attached_node=1, not_in_creative_inventory=1 },
|
||||
drop = {},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.45, -0.5, -0.45, 0.45, -0.6 + (((math.min(stage, 4)) + 1) / 5), 0.45}
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_craftitem("crops:potato", {
|
||||
description = S("Potato"),
|
||||
inventory_image = "crops_potato.png",
|
||||
on_use = minetest.item_eat(1)
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "crops:potato_eyes",
|
||||
recipe = { "crops:potato" }
|
||||
})
|
||||
|
||||
--
|
||||
-- the potatoes "block"
|
||||
--
|
||||
minetest.register_node("crops:soil_with_potatoes", {
|
||||
description = S("Soil with potatoes"),
|
||||
tiles = { "default_dirt.png^crops_potato_soil.png", "default_dirt.png" },
|
||||
sunlight_propagates = false,
|
||||
use_texture_alpha = false,
|
||||
walkable = true,
|
||||
groups = { snappy=3, flammable=3, oddly_breakable_by_hand=2, soil=1 },
|
||||
paramtype2 = "facedir",
|
||||
drop = {max_items = 5, items = {
|
||||
{ items = {'crops:potato'}, rarity = 1 },
|
||||
{ items = {'crops:potato'}, rarity = 1 },
|
||||
{ items = {'crops:potato'}, rarity = 1 },
|
||||
{ items = {'crops:potato'}, rarity = 2 },
|
||||
{ items = {'crops:potato'}, rarity = 5 },
|
||||
}},
|
||||
sounds = default.node_sound_dirt_defaults(),
|
||||
on_dig = function(pos, node, digger)
|
||||
local drops = {}
|
||||
-- damage 0 = drops 3-5
|
||||
-- damage 50 = drops 1-3
|
||||
-- damage 100 = drops 0-1
|
||||
local meta = minetest.get_meta(pos)
|
||||
local damage = meta:get_int("crops_damage")
|
||||
for i = 1, math.random(3 - (3 * damage / 100), 5 - (4 * (damage / 100))) do
|
||||
table.insert(drops, "crops:potato")
|
||||
end
|
||||
core.handle_node_drops(pos, drops, digger)
|
||||
minetest.set_node(pos, { name = "farming:soil" })
|
||||
local above = { x = pos.x, y = pos.y + 1, z = pos.z }
|
||||
if minetest.get_node(above).name == "crops:potato_plant_4" then
|
||||
minetest.set_node(above, { name = "air" })
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
--
|
||||
-- grows a plant to mature size
|
||||
--
|
||||
minetest.register_abm({
|
||||
nodenames = { "crops:potato_plant_1", "crops:potato_plant_2", "crops:potato_plant_3" },
|
||||
neighbors = { "group:soil" },
|
||||
interval = crops.settings.interval,
|
||||
chance = crops.settings.chance,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
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 damage = meta:get_int("crops_damage")
|
||||
if damage == 100 then
|
||||
crops.die(pos)
|
||||
return
|
||||
end
|
||||
local n = string.gsub(node.name, "3", "4")
|
||||
n = string.gsub(n, "2", "3")
|
||||
n = string.gsub(n, "1", "2")
|
||||
minetest.swap_node(pos, { name = n, param2 = 3 })
|
||||
end
|
||||
})
|
||||
|
||||
--
|
||||
-- grows the final potatoes in the soil beneath
|
||||
--
|
||||
minetest.register_abm({
|
||||
nodenames = { "crops:potato_plant_4" },
|
||||
neighbors = { "group:soil" },
|
||||
interval = crops.settings.interval,
|
||||
chance = crops.settings.chance,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
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 damage = meta:get_int("crops_damage")
|
||||
minetest.set_node(below, { name = "crops:soil_with_potatoes" })
|
||||
meta = minetest.get_meta(below)
|
||||
meta:set_int("crops_damage", damage)
|
||||
end
|
||||
})
|
||||
|
||||
crops.potato_die = function(pos)
|
||||
minetest.set_node(pos, { name = "crops:potato_plant_5", param2 = 3 })
|
||||
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
|
||||
|
||||
local properties = {
|
||||
die = crops.potato_die,
|
||||
waterstart = 30,
|
||||
wateruse = 1,
|
||||
night = 5,
|
||||
soak = 80,
|
||||
soak_damage = 90,
|
||||
wither = 20,
|
||||
wither_damage = 10,
|
||||
}
|
||||
|
||||
crops.register({ name = "crops:potato_plant_1", properties = properties })
|
||||
crops.register({ name = "crops:potato_plant_2", properties = properties })
|
||||
crops.register({ name = "crops:potato_plant_3", properties = properties })
|
||||
crops.register({ name = "crops:potato_plant_4", properties = properties })
|
|
@ -0,0 +1,260 @@
|
|||
|
||||
--[[
|
||||
|
||||
Copyright (C) 2015 - Auke Kok <sofar@foo-projects.org>
|
||||
|
||||
"crops" is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1
|
||||
of the license, or (at your option) any later version.
|
||||
|
||||
--]]
|
||||
|
||||
-- Intllib
|
||||
local S = crops.intllib
|
||||
|
||||
local faces = {
|
||||
[1] = { x = -1, z = 0, r = 3, o = 1, m = 14 },
|
||||
[2] = { x = 1, z = 0, r = 1, o = 3, m = 16 },
|
||||
[3] = { x = 0, z = -1, r = 2, o = 0, m = 5 },
|
||||
[4] = { x = 0, z = 1, r = 0, o = 2, m = 11 }
|
||||
}
|
||||
|
||||
minetest.register_node("crops:pumpkin_seed", {
|
||||
description = S("Pumpkin seed"),
|
||||
inventory_image = "crops_pumpkin_seed.png",
|
||||
wield_image = "crops_pumpkin_seed.png",
|
||||
tiles = { "crops_pumpkin_plant_1.png" },
|
||||
drawtype = "plantlike",
|
||||
waving = 1,
|
||||
sunlight_propagates = false,
|
||||
use_texture_alpha = true,
|
||||
walkable = false,
|
||||
paramtype = "light",
|
||||
node_placement_prediction = "crops:pumpkin_plant_1",
|
||||
groups = { snappy=3,flammable=3,flora=1,attached_node=1 },
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
local under = minetest.get_node(pointed_thing.under)
|
||||
if minetest.get_item_group(under.name, "soil") <= 1 then
|
||||
return
|
||||
end
|
||||
crops.plant(pointed_thing.above, {name="crops:pumpkin_plant_1"})
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
itemstack:take_item()
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
})
|
||||
|
||||
for stage = 1, 6 do
|
||||
minetest.register_node("crops:pumpkin_plant_" .. stage , {
|
||||
description = S("Pumpkin plant"),
|
||||
tiles = { "crops_pumpkin_plant_" .. stage .. ".png" },
|
||||
drawtype = "plantlike",
|
||||
waving = 1,
|
||||
sunlight_propagates = true,
|
||||
use_texture_alpha = true,
|
||||
walkable = false,
|
||||
paramtype = "light",
|
||||
groups = { snappy=3, flammable=3, flora=1, attached_node=1, not_in_creative_inventory=1 },
|
||||
drop = "crops:pumpkin_seed",
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, 0.5, -0.5 + (((math.min(stage, 4)) + 1) / 5), 0.5}
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_node("crops:pumpkin_plant_5_attached", {
|
||||
visual = "mesh",
|
||||
mesh = "crops_plant_extra_face.obj",
|
||||
description = S("Pumpkin plant"),
|
||||
tiles = { "crops_pumpkin_stem.png", "crops_pumpkin_plant_4.png" },
|
||||
drawtype = "mesh",
|
||||
paramtype2 = "facedir",
|
||||
sunlight_propagates = true,
|
||||
use_texture_alpha = true,
|
||||
walkable = false,
|
||||
paramtype = "light",
|
||||
groups = { snappy=3, flammable=3, flora=1, attached_node=1, not_in_creative_inventory=1 },
|
||||
drop = "crops:pumpkin_seed",
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
})
|
||||
|
||||
|
||||
minetest.register_craftitem("crops:roasted_pumpkin", {
|
||||
description = S("Roasted pumpkin"),
|
||||
inventory_image = "crops_roasted_pumpkin.png",
|
||||
on_use = minetest.item_eat(2)
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "crops:pumpkin_seed",
|
||||
recipe = { "crops:pumpkin" }
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "crops:roasted_pumpkin",
|
||||
recipe = "crops:pumpkin"
|
||||
})
|
||||
|
||||
--
|
||||
-- the pumpkin "block"
|
||||
--
|
||||
minetest.register_node("crops:pumpkin", {
|
||||
description = S("Pumpkin"),
|
||||
tiles = {
|
||||
"crops_pumpkin_top.png",
|
||||
"crops_pumpkin_bottom.png",
|
||||
"crops_pumpkin.png"
|
||||
},
|
||||
sunlight_propagates = false,
|
||||
use_texture_alpha = false,
|
||||
walkable = true,
|
||||
groups = { snappy=3, flammable=3, oddly_breakable_by_hand=2 },
|
||||
paramtype2 = "facedir",
|
||||
sounds = default.node_sound_wood_defaults({
|
||||
dig = { name = "default_dig_oddly_breakable_by_hand" },
|
||||
dug = { name = "default_dig_choppy" }
|
||||
}),
|
||||
after_dig_node = function(pos, node)
|
||||
for face = 1, 4 do
|
||||
local s = { x = pos.x + faces[face].x, y = pos.y, z = pos.z + faces[face].z }
|
||||
local n = minetest.get_node(s)
|
||||
if n.name == "crops:pumpkin_plant_5_attached" then
|
||||
-- make sure it was actually attached to this stem
|
||||
if n.param2 == faces[face].o then
|
||||
minetest.swap_node(s, { name = "crops:pumpkin_plant_4" })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
--
|
||||
-- grows a plant to mature size
|
||||
--
|
||||
minetest.register_abm({
|
||||
nodenames = { "crops:pumpkin_plant_1", "crops:pumpkin_plant_2", "crops:pumpkin_plant_3","crops:pumpkin_plant_4" },
|
||||
neighbors = { "group:soil" },
|
||||
interval = crops.settings.interval,
|
||||
chance = crops.settings.chance,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
if not crops.can_grow(pos) then
|
||||
return
|
||||
end
|
||||
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.swap_node(pos, { name = n })
|
||||
end
|
||||
})
|
||||
|
||||
--
|
||||
-- grows a pumpkin
|
||||
--
|
||||
minetest.register_abm({
|
||||
nodenames = { "crops:pumpkin_plant_5" },
|
||||
neighbors = { "group:soil" },
|
||||
interval = crops.settings.interval,
|
||||
chance = crops.settings.chance,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
if not crops.can_grow(pos) then
|
||||
return
|
||||
end
|
||||
for face = 1, 4 do
|
||||
local t = { x = pos.x + faces[face].x, y = pos.y, z = pos.z + faces[face].z }
|
||||
if minetest.get_node(t).name == "crops:pumpkin" then
|
||||
return
|
||||
end
|
||||
end
|
||||
local r = math.random(1, 4)
|
||||
local t = { x = pos.x + faces[r].x, y = pos.y, z = pos.z + faces[r].z }
|
||||
local n = minetest.get_node(t)
|
||||
if n.name == "ignore" then
|
||||
return
|
||||
end
|
||||
|
||||
if minetest.registered_nodes[minetest.get_node({ x = t.x, y = t.y - 1, z = t.z }).name].walkable == false then
|
||||
return
|
||||
end
|
||||
|
||||
if minetest.registered_nodes[n.name].drawtype == "plantlike" or
|
||||
minetest.registered_nodes[n.name].groups.flora == 1 or
|
||||
n.name == "air" then
|
||||
minetest.set_node(t, {name = "crops:pumpkin", param2 = faces[r].m})
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
local ttl = meta:get_int("crops_pumpkin_ttl")
|
||||
local damage = meta:get_int("crops_damage")
|
||||
if ttl == 0 then
|
||||
-- damage 0 - regrows 3-4
|
||||
-- damage 50 - drops 1-2
|
||||
-- damage 100 - drops 0-1
|
||||
ttl = math.random(3 - (3 * (damage / 100)), 4 - (3 * (damage / 100)))
|
||||
end
|
||||
if ttl > 1 then
|
||||
minetest.swap_node(pos, {name = "crops:pumpkin_plant_5_attached", param2 = faces[r].r})
|
||||
meta:set_int("crops_pumpkin_ttl", ttl - 1)
|
||||
else
|
||||
crops.die(pos)
|
||||
end
|
||||
local water = meta:get_int("crops_water")
|
||||
-- growing a pumpkin costs 25 water!
|
||||
meta:set_int("crops_water", math.max(0, water - 25))
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
--
|
||||
-- return a pumpkin to a normal one if there is no pumpkin attached, so it can
|
||||
-- grow a new pumpkin again
|
||||
--
|
||||
minetest.register_abm({
|
||||
nodenames = { "crops:pumpkin_plant_5_attached" },
|
||||
interval = crops.settings.interval,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
for face = 1, 4 do
|
||||
local t = { x = pos.x + faces[face].x, y = pos.y, z = pos.z + faces[face].z }
|
||||
if minetest.get_node(t).name == "crops:pumpkin" then
|
||||
return
|
||||
end
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local ttl = meta:get_int("crops_pumpkin_ttl")
|
||||
if ttl > 1 then
|
||||
minetest.swap_node(pos, { name = "crops:pumpkin_plant_4" })
|
||||
meta:set_int("crops_pumpkin_ttl", ttl)
|
||||
else
|
||||
crops.die(pos)
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
crops.pumpkin_die = function(pos)
|
||||
minetest.set_node(pos, { name = "crops:pumpkin_plant_6" })
|
||||
end
|
||||
|
||||
local properties = {
|
||||
die = crops.pumpkin_die,
|
||||
waterstart = 40,
|
||||
wateruse = 1,
|
||||
night = 5,
|
||||
soak = 80,
|
||||
soak_damage = 90,
|
||||
wither = 10,
|
||||
wither_damage = 5,
|
||||
}
|
||||
|
||||
crops.register({ name = "crops:pumpkin_plant_1", properties = properties })
|
||||
crops.register({ name = "crops:pumpkin_plant_2", properties = properties })
|
||||
crops.register({ name = "crops:pumpkin_plant_3", properties = properties })
|
||||
crops.register({ name = "crops:pumpkin_plant_4", properties = properties })
|
||||
crops.register({ name = "crops:pumpkin_plant_5", properties = properties })
|
||||
crops.register({ name = "crops:pumpkin_plant_5_attached", properties = properties })
|
|
@ -0,0 +1,162 @@
|
|||
## Crops - more farming crops mod for minetest
|
||||
|
||||
Copyright (C) 2015 - Auke Kok <sofar@foo-projects.org>
|
||||
|
||||
This minetest mod expands the basic set of farming-related crops that
|
||||
`minetest_game` offers. A list of crops/crafts is below.
|
||||
|
||||
## Configuration
|
||||
|
||||
A default configuration file, `crops_settings.txt` will be added
|
||||
to your world folder that contains suggested `easy`, `normal` (the
|
||||
default) and `difficult` settings for this mod. You can currently tune
|
||||
the ABM interval/chance, and required light level for plant growth.
|
||||
|
||||
## Hydration mechanic
|
||||
|
||||
This feature is disabled in the `easy` setting.
|
||||
|
||||
Plants need water. Plants need more water when they grow. This mod
|
||||
implements mechanics of plant hydration and what happens when you
|
||||
over-water or not water your plants properly: Plants may wither or
|
||||
soak, and if they wither/soak too much, the plant will get damaged.
|
||||
|
||||
You can see that plants are under stress visually. When a plant
|
||||
withers, there will be particles that are steam/smoke-like floating
|
||||
upwards from the plant. When a plant is over-watered, water bubbles
|
||||
can be seen at the plant base. These are implemented as particles.
|
||||
|
||||
In the default difficulty settings, plants don't accrue enough damage
|
||||
to kill the plant. But at difficult settings, withering will end up
|
||||
resulting in plant death, or the loss of crop entirely. At default
|
||||
settings, plants will yield significantly less harvest if not taken
|
||||
care of! So if you do decide to not water your plants, make sure you
|
||||
don't let them sit around for days and harvest them as soon as they
|
||||
are ripe to limit the effects.
|
||||
|
||||
Environment factors can influence hydration: nearby water, night time
|
||||
moisture. And of course, the watering can. The watering can holds
|
||||
20 watering charges, and it takes 3-4 charges to water a plant from
|
||||
completely dry to maximum wetness. Some plants will want more water,
|
||||
some will do better with less, so make sure you use a hydrometer to
|
||||
measure plant humidity. Recipes for the watering can and hydrometer
|
||||
are listed below.
|
||||
|
||||
## Plants
|
||||
|
||||
1. Melons and pumpkins
|
||||
|
||||
Melon plants grow from melon seeds. Once a plant is mature (there
|
||||
are 5 stages) it will spawn a melon block adjacent to the plant.
|
||||
The melon block can be harvested by punching, and yields 3-5
|
||||
melon slices. The melon slice can be crafted to a melon seed.
|
||||
|
||||
Pumpkins grow from pumpkin seeds, and are harvested to yield a
|
||||
pumpkin block. Each block can be cooked to yield one or more
|
||||
roast pumpkin chunks, which can be eaten. You can also craft
|
||||
the blocks to seeds. A pumpkin plant will only yield limited amounts
|
||||
of pumpkins. After a while they automatically wither.
|
||||
|
||||
2. Corn.
|
||||
|
||||
Corn plants are 2 blocks high, and yield corn cobs. These can be
|
||||
cooked to corn-on-the-cob, or processed to make corn seed (corn
|
||||
kernels, basically).
|
||||
|
||||
Digging a mature plant yields the corn cob. A harvested corn plant
|
||||
"wilts", and needs to be dug away to make the land usable, or can
|
||||
be left as ornamental 2-block plant. Digging either top or bottom
|
||||
block works in all cases.
|
||||
|
||||
3. Tomatoes.
|
||||
|
||||
Tomatoes appear to work simple enough, until you harvest them
|
||||
the first time: The plant stays! However, after the 3rd to 5th
|
||||
harvest, the plant wilts and needs to be removed, since no more
|
||||
tomatoes will grow on the plant. Per harvest you can get 1-2
|
||||
tomatoes only. You can craft the tomatoes to tomato seeds, as
|
||||
expected.
|
||||
|
||||
4. Potatoes.
|
||||
|
||||
The plants themselves don't drop anything. Only if the plant matures
|
||||
can you dig potatoes from the soil. If you can reach the soil from the
|
||||
side you can save yourself one dig by digging the soil as that will
|
||||
remove the plant from the top, but otherwise you need to dig twice:
|
||||
once to remove the plant, once to dig out the potatoes.
|
||||
|
||||
You get 3-5 potatoes. Each potato gives one (set of) "potato eyes"
|
||||
which are the clones that can grow back to potatoes. Be careful not
|
||||
to dig the plant when there's flowers! You have to wait until the soil
|
||||
below shows potatoes. It's fairly easy to see the difference, though.
|
||||
|
||||
5. Green Beans
|
||||
|
||||
These green beans are unnaturally green, but there's so many
|
||||
of them that grow on a vine! Sadly, these beans don't grow beans
|
||||
unsupported, so you stick some sticks together to make a beanpole,
|
||||
something like this way:
|
||||
|
||||
empty empty empty
|
||||
stick empty stick
|
||||
stick empty stick
|
||||
|
||||
There, that should help the viney bean plant to grow to 2 meters
|
||||
high. It has remarkable purple flowers, that pop all over the plant
|
||||
just before the beans grow.
|
||||
|
||||
Sadly, once the beans are picked, this plant turns into an unusable
|
||||
mess that makes it hard for the next plant to grow on the beanpole,
|
||||
so you salvage the beanpole's sticks after harvesting in order to
|
||||
make more beanpoles again. It's a bit of work, but worth it, these
|
||||
beans are delicious!
|
||||
|
||||
|
||||
## Cooking / Crafting
|
||||
|
||||
The corn cobs can be cooked directly to make Corn-on-the-Cob.
|
||||
|
||||
This mod includes a bowl recipe. The bowl is made from clay lumps,
|
||||
which results in an unbaked clay bowl that needs to be baked in an
|
||||
oven to be usable:
|
||||
|
||||
empty empty empty
|
||||
clay_lump empty clay_lump
|
||||
empty clay_lump empty
|
||||
|
||||
Pumpkin blocks can be cooked whole, and yield roasted pumpkin. It's
|
||||
okay as food, but it takes a lot of work.
|
||||
|
||||
You can fill these bowls (or any group:food_bowl) with vegetables to
|
||||
craft an uncooked vegetable stew:
|
||||
|
||||
empty empty empty
|
||||
grean_beans potato tomato
|
||||
empty clay_bowl empty
|
||||
|
||||
The uncooked vegetable stew obviously needs to be cooked as well in
|
||||
an oven. The resulting Vegetable Stew bowl gives a lot of hears back,
|
||||
which is worth the effort.
|
||||
|
||||
The watering can can be made as follows:
|
||||
|
||||
steel_ingot empty empty
|
||||
steel_ingot empty steel_ingot
|
||||
empty steel_ingot empty
|
||||
|
||||
To fill the watering can, left click any block of water. To use,
|
||||
left click a plant. The damage bar on the icon indicates the fill
|
||||
level of the watering can.
|
||||
|
||||
The hydrometer can be crafted like this:
|
||||
|
||||
mese_crystal_fragment empty empty
|
||||
empty steel_ingot empty
|
||||
empty empty steel_ingot
|
||||
|
||||
Left-click any plant with the hydrometer, and the charge bar indicates
|
||||
the humidity level of the plant: a dry plant will have 0% humidity
|
||||
and be a small red bar or no bar at all, and a soaked plant will
|
||||
have a full green bar. Be careful though! Some plants prefer to be
|
||||
at mid-level (yellow) instead of full wetness!
|
||||
|
After Width: | Height: | Size: 224 KiB |
After Width: | Height: | Size: 216 B |
After Width: | Height: | Size: 212 B |
After Width: | Height: | Size: 225 B |
After Width: | Height: | Size: 228 B |
After Width: | Height: | Size: 251 B |
After Width: | Height: | Size: 270 B |
After Width: | Height: | Size: 301 B |
After Width: | Height: | Size: 229 B |
After Width: | Height: | Size: 254 B |
After Width: | Height: | Size: 274 B |
After Width: | Height: | Size: 316 B |
After Width: | Height: | Size: 199 B |
After Width: | Height: | Size: 198 B |
After Width: | Height: | Size: 212 B |
After Width: | Height: | Size: 170 B |
After Width: | Height: | Size: 199 B |
After Width: | Height: | Size: 175 B |
After Width: | Height: | Size: 227 B |
After Width: | Height: | Size: 228 B |
After Width: | Height: | Size: 200 B |
After Width: | Height: | Size: 261 B |
After Width: | Height: | Size: 252 B |
After Width: | Height: | Size: 267 B |
After Width: | Height: | Size: 224 B |
After Width: | Height: | Size: 283 B |
After Width: | Height: | Size: 89 B |
After Width: | Height: | Size: 191 B |
After Width: | Height: | Size: 181 B |
After Width: | Height: | Size: 127 B |
After Width: | Height: | Size: 174 B |
After Width: | Height: | Size: 210 B |
After Width: | Height: | Size: 207 B |
After Width: | Height: | Size: 221 B |
After Width: | Height: | Size: 234 B |
After Width: | Height: | Size: 279 B |
After Width: | Height: | Size: 276 B |
After Width: | Height: | Size: 197 B |
After Width: | Height: | Size: 388 B |
After Width: | Height: | Size: 208 B |
After Width: | Height: | Size: 270 B |
After Width: | Height: | Size: 217 B |
After Width: | Height: | Size: 209 B |
After Width: | Height: | Size: 242 B |
After Width: | Height: | Size: 150 B |
After Width: | Height: | Size: 162 B |
After Width: | Height: | Size: 187 B |
After Width: | Height: | Size: 220 B |
After Width: | Height: | Size: 202 B |
After Width: | Height: | Size: 720 B |
After Width: | Height: | Size: 163 B |
After Width: | Height: | Size: 172 B |
After Width: | Height: | Size: 106 B |
After Width: | Height: | Size: 133 B |
After Width: | Height: | Size: 157 B |
After Width: | Height: | Size: 205 B |
After Width: | Height: | Size: 228 B |
After Width: | Height: | Size: 193 B |
After Width: | Height: | Size: 497 B |
After Width: | Height: | Size: 157 B |
After Width: | Height: | Size: 218 B |
After Width: | Height: | Size: 206 B |
After Width: | Height: | Size: 116 B |
After Width: | Height: | Size: 289 B |
After Width: | Height: | Size: 334 B |
After Width: | Height: | Size: 339 B |
After Width: | Height: | Size: 355 B |
After Width: | Height: | Size: 396 B |
After Width: | Height: | Size: 407 B |
After Width: | Height: | Size: 389 B |
After Width: | Height: | Size: 308 B |
After Width: | Height: | Size: 170 B |
After Width: | Height: | Size: 100 B |
After Width: | Height: | Size: 182 B |
After Width: | Height: | Size: 98 B |