Render seed nodes as nodebox
[minetest_hades/hades_revisited.git] / mods / farming / api.lua
blobb84fc0851db9d96b797f7af667c3a03e1777153a
1 local S = minetest.get_translator("farming")
3 -- Wear out hoes, place soil
4 -- TODO Ignore group:flower
5 farming.hoe_on_use = function(itemstack, user, pointed_thing, uses)
6 local pt = pointed_thing
7 -- check if pointing at a node
8 if not pt then
9 return
10 end
11 if pt.type ~= "node" then
12 return
13 end
15 local under = minetest.get_node(pt.under)
16 local p = {x=pt.under.x, y=pt.under.y+1, z=pt.under.z}
17 local above = minetest.get_node(p)
19 -- return if any of the nodes is not registered
20 if not minetest.registered_nodes[under.name] then
21 return
22 end
23 if not minetest.registered_nodes[above.name] then
24 return
25 end
27 -- check if the node above the pointed thing is air
28 if above.name ~= "air" then
29 return
30 end
32 -- check if pointing at soil
33 if minetest.get_item_group(under.name, "soil") ~= 1 then
34 return
35 end
37 -- check if (wet) soil defined
38 local regN = minetest.registered_nodes
39 if regN[under.name].soil == nil or regN[under.name].soil.wet == nil or regN[under.name].soil.dry == nil then
40 return
41 end
43 -- turn the node into soil, wear out item and play sound
44 minetest.set_node(pt.under, {name = regN[under.name].soil.dry})
45 minetest.sound_play("default_dig_crumbly", {
46 pos = pt.under,
47 gain = 0.5,
48 }, true)
50 if not minetest.settings:get_bool("creative_mode") then
51 itemstack:add_wear(65535/(uses-1))
52 end
53 return itemstack
54 end
56 -- Register new hoes
57 farming.register_hoe = function(name, def)
58 -- Check for : prefix (register new hoes in your mod's namespace)
59 if name:sub(1,1) ~= ":" then
60 name = ":" .. name
61 end
62 -- Check def table
63 if def.description == nil then
64 def.description = "Hoe"
65 end
66 if def.inventory_image == nil then
67 def.inventory_image = "unknown_item.png"
68 end
69 if def.recipe == nil then
70 def.recipe = {
71 {"air","air",""},
72 {"","group:stick",""},
73 {"","group:stick",""}
75 end
76 if def.max_uses == nil then
77 def.max_uses = 30
78 end
79 -- Register the tool
80 minetest.register_tool(name, {
81 description = def.description,
82 _tt_help = def._tt_help .. "\n" .. S("Uses: @1", def.max_uses),
83 inventory_image = def.inventory_image,
84 on_use = function(itemstack, user, pointed_thing)
85 return farming.hoe_on_use(itemstack, user, pointed_thing, def.max_uses)
86 end
88 -- Register its recipe
89 if def.material == nil then
90 minetest.register_craft({
91 output = name:sub(2),
92 recipe = def.recipe
94 else
95 local handle
96 if def.material_handle then
97 handle = def.material_handle
98 else
99 handle = "group:stick"
101 minetest.register_craft({
102 output = name:sub(2),
103 recipe = {
104 {def.material, def.material, ""},
105 {"", handle, ""},
106 {"", handle, ""}
112 -- Seed placement
113 farming.place_seed = function(itemstack, placer, pointed_thing, plantname)
114 local pt = pointed_thing
115 -- check if pointing at a node
116 if not pt then
117 return
119 if pt.type ~= "node" then
120 return
123 local under = minetest.get_node(pt.under)
124 local above = minetest.get_node(pt.above)
126 -- return if any of the nodes is not registered
127 if not minetest.registered_nodes[under.name] then
128 return
130 if not minetest.registered_nodes[above.name] then
131 return
134 -- check if pointing at the top of the node
135 if pt.above.y ~= pt.under.y+1 then
136 return
139 -- check if you can replace the node above the pointed node
140 if not minetest.registered_nodes[above.name].buildable_to then
141 return
144 -- check if pointing at soil
145 if minetest.get_item_group(under.name, "soil") < 2 then
146 return
149 -- add the node and remove 1 item from the itemstack
150 minetest.add_node(pt.above, {name = plantname, param2 = 1})
151 if not minetest.settings:get_bool("creative_mode") then
152 itemstack:take_item()
154 return itemstack
157 -- Register plants
158 farming.register_plant = function(name, def)
159 local mname = name:split(":")[1]
160 local pname = name:split(":")[2]
162 -- Check def table
163 if not def.description then
164 def.description = "Seed"
166 if not def.inventory_image then
167 def.inventory_image = "unknown_item.png"
169 if not def.steps then
170 return nil
172 if not def.minlight then
173 def.minlight = 1
175 if not def.maxlight then
176 def.maxlight = 14
178 if not def.fertility then
179 def.fertility = {}
182 -- Register seed
183 local g = {seed = 1, snappy = 3, attached_node = 1}
184 for k, v in pairs(def.fertility) do
185 g[v] = 1
187 minetest.register_node(":" .. mname .. ":seed_" .. pname, {
188 description = def.description,
189 _tt_help = def._tt_help,
190 tiles = {def.inventory_image, def.inventory_image, "blank.png"},
191 inventory_image = def.inventory_image,
192 wield_image = def.inventory_image,
193 drawtype = "nodebox",
194 groups = g,
195 paramtype = "light",
196 walkable = false,
197 sunlight_propagates = true,
198 node_box = {
199 type = "fixed",
200 fixed = {-0.5, -0.5, -0.5, 0.5, -31/64, 0.5},
202 selection_box = {
203 type = "fixed",
204 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
206 fertility = def.fertility,
207 on_place = function(itemstack, placer, pointed_thing)
208 return farming.place_seed(itemstack, placer, pointed_thing, mname .. ":seed_" .. pname)
212 -- Register harvest
213 minetest.register_craftitem(":" .. mname .. ":" .. pname, {
214 description = def.description_harvest,
215 groups = { food = 1, eatable = def.food_points },
216 on_use = minetest.item_eat(def.food_points),
217 inventory_image = mname .. "_" .. pname .. ".png",
220 -- Register growing steps
221 for i=1,def.steps do
222 local drop = {
223 items = {
224 {items = {mname .. ":seed_" .. pname}, rarity = 4 - i},
225 {items = {mname .. ":seed_" .. pname}, rarity = 8 - i * 2},
226 {items = {mname .. ":" .. pname}, rarity = 4 - i},
227 {items = {mname .. ":" .. pname}, rarity = 6 - i},
228 {items = {mname .. ":" .. pname}, rarity= 8 - i * 2},
229 {items = {mname .. ":" .. pname}, rarity= 9 - i * 2},
232 local nodegroups = {snappy = 3, flammable = 2, plant = 1, not_in_creative_inventory = 1, attached_node = 1}
233 nodegroups[pname] = i
234 if pname == "corn" then
235 minetest.register_node(mname .. ":" .. pname .. "_" .. i, {
236 drawtype = "plantlike",
237 visual_scale = 1.8,
238 waving = 1,
239 tiles = {mname .. "_" .. pname .. "_" .. i .. ".png"},
240 paramtype = "light",
241 walkable = false,
242 buildable_to = true,
243 is_ground_content = true,
244 drop = drop,
245 selection_box = {
246 type = "fixed",
247 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
249 groups = nodegroups,
250 sounds = hades_sounds.node_sound_leaves_defaults(),
252 elseif pname == "beens" then
253 minetest.register_node(mname .. ":" .. pname .. "_" .. i, {
254 drawtype = "plantlike",
255 visual_scale = 1.4,
256 waving = 1,
257 tiles = {mname .. "_" .. pname .. "_" .. i .. ".png"},
258 paramtype = "light",
259 walkable = false,
260 buildable_to = true,
261 is_ground_content = true,
262 drop = drop,
263 selection_box = {
264 type = "fixed",
265 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
267 groups = nodegroups,
268 sounds = hades_sounds.node_sound_leaves_defaults(),
270 else
271 minetest.register_node(mname .. ":" .. pname .. "_" .. i, {
272 drawtype = "plantlike",
273 tiles = {mname .. "_" .. pname .. "_" .. i .. ".png"},
274 paramtype = "light",
275 walkable = false,
276 buildable_to = true,
277 is_ground_content = true,
278 drop = drop,
279 selection_box = {
280 type = "fixed",
281 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
283 groups = nodegroups,
284 sounds = hades_sounds.node_sound_leaves_defaults(),
289 -- Growing ABM
290 minetest.register_abm({
291 label = "Grow seeds",
292 nodenames = {"group:" .. pname, "group:seed"},
293 neighbors = {"group:soil"},
294 interval = 93,
295 chance = 12,
296 action = function(pos, node)
297 local plant_height = minetest.get_item_group(node.name, pname)
299 -- return if already full grown
300 if plant_height == def.steps then
301 return
304 local node_def = minetest.registered_items[node.name] or nil
306 -- grow seed
307 if minetest.get_item_group(node.name, "seed") and node_def.fertility then
308 local can_grow = false
309 local soil_node = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z})
310 if not soil_node then
311 return
313 for _, v in pairs(node_def.fertility) do
314 if minetest.get_item_group(soil_node.name, v) ~= 0 then
315 can_grow = true
318 if can_grow then
319 minetest.set_node(pos, {name = node.name:gsub("seed_", "") .. "_1"})
321 return
324 -- check if on wet soil
325 pos.y = pos.y - 1
326 local n = minetest.get_node(pos)
327 if minetest.get_item_group(n.name, "soil") < 3 then
328 return
330 pos.y = pos.y + 1
332 -- check light
333 local ll = minetest.get_node_light(pos)
335 if not ll or ll < def.minlight or ll > def.maxlight then
336 return
339 -- grow
340 minetest.set_node(pos, {name = mname .. ":" .. pname .. "_" .. plant_height + 1})
344 -- Return
345 local r = {
346 seed = mname .. ":seed_" .. pname,
347 harvest = mname .. ":" .. pname
349 return r