Make many nodes floodable
[minetest_hades/hades_revisited.git] / mods / farming / api.lua
blob5e8d760702623d142aa736dab95018349bd34844
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.is_creative_enabled(user:get_player_name()) 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 minetest.sound_play({name="default_place_node", gain=1.0}, {pos=pt.under})
151 -- add the node and remove 1 item from the itemstack
152 minetest.add_node(pt.above, {name = plantname, param2 = 1})
153 if not minetest.is_creative_enabled(placer:get_player_name()) then
154 itemstack:take_item()
156 return itemstack
159 -- Register plants
160 farming.register_plant = function(name, def)
161 local mname = name:split(":")[1]
162 local pname = name:split(":")[2]
164 -- Check def table
165 if not def.description then
166 def.description = "Seed"
168 if not def.inventory_image then
169 def.inventory_image = "unknown_item.png"
171 if not def.steps then
172 return nil
174 if not def.minlight then
175 def.minlight = 1
177 if not def.maxlight then
178 def.maxlight = 14
180 if not def.fertility then
181 def.fertility = {}
184 -- Register seed
185 local g = {seed = 1, snappy = 3, attached_node = 1}
186 for k, v in pairs(def.fertility) do
187 g[v] = 1
189 minetest.register_node(":" .. mname .. ":seed_" .. pname, {
190 description = def.description,
191 _tt_help = def._tt_help,
192 tiles = {def.inventory_image, def.inventory_image, "blank.png"},
193 inventory_image = def.inventory_image,
194 wield_image = def.inventory_image,
195 drawtype = "nodebox",
196 groups = g,
197 paramtype = "light",
198 walkable = false,
199 floodable = true,
200 sunlight_propagates = true,
201 node_box = {
202 type = "fixed",
203 fixed = {-0.5, -0.5, -0.5, 0.5, -31/64, 0.5},
205 selection_box = {
206 type = "fixed",
207 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
209 fertility = def.fertility,
210 on_place = function(itemstack, placer, pointed_thing)
211 return farming.place_seed(itemstack, placer, pointed_thing, mname .. ":seed_" .. pname)
215 -- Register harvest
216 minetest.register_craftitem(":" .. mname .. ":" .. pname, {
217 description = def.description_harvest,
218 groups = { food = 1, eatable = def.food_points },
219 on_use = minetest.item_eat(def.food_points),
220 inventory_image = mname .. "_" .. pname .. ".png",
223 -- Register growing steps
224 for i=1,def.steps do
225 local drop = {
226 items = {
227 {items = {mname .. ":seed_" .. pname}, rarity = 4 - i},
228 {items = {mname .. ":seed_" .. pname}, rarity = 8 - i * 2},
229 {items = {mname .. ":" .. pname}, rarity = 4 - i},
230 {items = {mname .. ":" .. pname}, rarity = 6 - i},
231 {items = {mname .. ":" .. pname}, rarity= 8 - i * 2},
232 {items = {mname .. ":" .. pname}, rarity= 9 - i * 2},
235 local nodegroups = {snappy = 3, flammable = 2, plant = 1, not_in_creative_inventory = 1, attached_node = 1}
236 nodegroups[pname] = i
237 if pname == "corn" then
238 minetest.register_node(mname .. ":" .. pname .. "_" .. i, {
239 drawtype = "plantlike",
240 visual_scale = 1.8,
241 waving = 1,
242 tiles = {mname .. "_" .. pname .. "_" .. i .. ".png"},
243 paramtype = "light",
244 walkable = false,
245 buildable_to = true,
246 floodable = true,
247 is_ground_content = true,
248 drop = drop,
249 selection_box = {
250 type = "fixed",
251 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
253 groups = nodegroups,
254 sounds = hades_sounds.node_sound_leaves_defaults(),
256 elseif pname == "beens" then
257 minetest.register_node(mname .. ":" .. pname .. "_" .. i, {
258 drawtype = "plantlike",
259 visual_scale = 1.4,
260 waving = 1,
261 tiles = {mname .. "_" .. pname .. "_" .. i .. ".png"},
262 paramtype = "light",
263 walkable = false,
264 buildable_to = true,
265 floodable = true,
266 is_ground_content = true,
267 drop = drop,
268 selection_box = {
269 type = "fixed",
270 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
272 groups = nodegroups,
273 sounds = hades_sounds.node_sound_leaves_defaults(),
275 else
276 minetest.register_node(mname .. ":" .. pname .. "_" .. i, {
277 drawtype = "plantlike",
278 tiles = {mname .. "_" .. pname .. "_" .. i .. ".png"},
279 paramtype = "light",
280 walkable = false,
281 buildable_to = true,
282 floodable = true,
283 is_ground_content = true,
284 drop = drop,
285 selection_box = {
286 type = "fixed",
287 fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
289 groups = nodegroups,
290 sounds = hades_sounds.node_sound_leaves_defaults(),
295 -- Growing ABM
296 minetest.register_abm({
297 label = "Grow seeds",
298 nodenames = {"group:" .. pname, "group:seed"},
299 neighbors = {"group:soil"},
300 interval = 93,
301 chance = 12,
302 action = function(pos, node)
303 local plant_height = minetest.get_item_group(node.name, pname)
305 -- return if already full grown
306 if plant_height == def.steps then
307 return
310 local node_def = minetest.registered_items[node.name] or nil
312 -- grow seed
313 if minetest.get_item_group(node.name, "seed") and node_def.fertility then
314 local can_grow = false
315 local soil_node = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z})
316 if not soil_node then
317 return
319 for _, v in pairs(node_def.fertility) do
320 if minetest.get_item_group(soil_node.name, v) ~= 0 then
321 can_grow = true
324 if can_grow then
325 minetest.set_node(pos, {name = node.name:gsub("seed_", "") .. "_1"})
327 return
330 -- check if on wet soil
331 pos.y = pos.y - 1
332 local n = minetest.get_node(pos)
333 if minetest.get_item_group(n.name, "soil") < 3 then
334 return
336 pos.y = pos.y + 1
338 -- check light
339 local ll = minetest.get_node_light(pos)
341 if not ll or ll < def.minlight or ll > def.maxlight then
342 return
345 -- grow
346 minetest.set_node(pos, {name = mname .. ":" .. pname .. "_" .. plant_height + 1})
350 -- Return
351 local r = {
352 seed = mname .. ":seed_" .. pname,
353 harvest = mname .. ":" .. pname
355 return r