Make pumpkins and melons opaque again
[MineClone/MineClone2.git] / mods / ITEMS / mcl_farming / shared_functions.lua
blob0b201ca620e07b545567531443d29c11b71729eb
1 local plant_lists = {}
3 function mcl_farming:add_plant(identifier, full_grown, names, interval, chance)
4 plant_lists[identifier] = {}
5 plant_lists[identifier].full_grown = full_grown
6 plant_lists[identifier].names = names
7 minetest.register_abm({
8 label = string.format("Farming plant growth (%s)", identifier),
9 nodenames = names,
10 interval = interval,
11 chance = chance,
12 action = function(pos, node)
13 if minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name ~= "mcl_farming:soil_wet" and math.random(0, 9) > 0 then
14 return
15 else
16 mcl_farming:grow_plant(identifier, pos, node)
17 end
18 end,
20 end
22 -- Attempts to advance a plant at pos by one or more growth stages (if possible)
23 -- identifier: Identifier of plant as defined by mcl_farming:add_plant
24 -- pos: Position
25 -- node: Node table
26 -- stages: Number of stages to advance (optional, defaults to 1)
28 -- Returns true if plant has been grown by 1 or more stages.
29 -- Returns false if nothing changed.
30 function mcl_farming:grow_plant(identifier, pos, node, stages)
31 if not minetest.get_node_light(pos) then
32 return false
33 end
34 if minetest.get_node_light(pos) < 10 then
35 return false
36 end
38 local plant_info = plant_lists[identifier]
39 local step = nil
41 for i, name in ipairs(plant_info.names) do
42 if name == node.name then
43 step = i
44 break
45 end
46 end
47 if step == nil then
48 return false
49 end
50 if not stages then
51 stages = 1
52 end
53 local new_node = {name = plant_info.names[step+stages]}
54 if new_node.name == nil then
55 new_node.name = plant_info.full_grown
56 end
57 new_node.param = node.param
58 new_node.param2 = node.param2
59 minetest.set_node(pos, new_node)
60 return true
61 end
63 function mcl_farming:place_seed(itemstack, placer, pointed_thing, plantname)
64 local pt = pointed_thing
65 if not pt then
66 return
67 end
68 if pt.type ~= "node" then
69 return
70 end
72 -- Use pointed node's on_rightclick function first, if present
73 local node = minetest.get_node(pt.under)
74 if placer and not placer:get_player_control().sneak then
75 if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then
76 return minetest.registered_nodes[node.name].on_rightclick(pt.under, node, placer, itemstack) or itemstack
77 end
78 end
80 local pos = {x=pt.above.x, y=pt.above.y-1, z=pt.above.z}
81 local farmland = minetest.get_node(pos)
82 pos= {x=pt.above.x, y=pt.above.y, z=pt.above.z}
83 local place_s = minetest.get_node(pos)
85 if string.find(farmland.name, "mcl_farming:soil") and string.find(place_s.name, "air") then
86 minetest.sound_play(minetest.registered_nodes[plantname].sounds.place, {pos = pos})
87 minetest.add_node(pos, {name=plantname, param2 = minetest.registered_nodes[plantname].place_param2})
88 else
89 return
90 end
92 if not minetest.settings:get_bool("creative_mode") then
93 itemstack:take_item()
94 end
95 return itemstack
96 end
99 --[[ Helper function to create a gourd (e.g. melon, pumpkin), the connected stem nodes as
101 - full_unconnected_stem: itemstring of the full-grown but unconnceted stem node. This node must already be done
102 - connected_stem_basename: prefix of the itemstrings used for the 4 connected stem nodes to create
103 - stem_itemstring: Desired itemstring of the fully-grown unconnected stem node
104 - stem_def: Partial node definition of the fully-grown unconnected stem node. Many fields are already defined. You need to add `tiles` and `description` at minimum. Don't define on_construct without good reason
105 - stem_drop: Drop probability table for all stem
106 - gourd_itemstring: Desired itemstring of the full gourd node
107 - gourd_def: (almost) full definition of the gourd node. This function will add on_construct and after_dig_node to the definition for unconnecting any connected stems
108 - grow_interval: Will attempt to grow a gourd periodically at this interval in seconds
109 - grow_chance: Chance of 1/grow_chance to grow a gourd next to the full unconnected stem after grow_interval has passed. Must be a natural number
110 - connected_stem_texture: Texture of the connected stem
111 - gourd_on_construct_extra: Custom on_construct extra function for the gourd. Will be called after the stem check code
114 function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, stem_itemstring, stem_def, stem_drop, gourd_itemstring, gourd_def, grow_interval, grow_chance, connected_stem_texture, gourd_on_construct_extra)
116 local connected_stem_names = {
117 connected_stem_basename .. "_r",
118 connected_stem_basename .. "_l",
119 connected_stem_basename .. "_t",
120 connected_stem_basename .. "_b",
123 local neighbors = {
124 { x=-1, y=0, z=0 },
125 { x=1, y=0, z=0 },
126 { x=0, y=0, z=-1 },
127 { x=0, y=0, z=1 },
130 -- Connect the stem at stempos to the first neighboring gourd block.
131 -- No-op if not a stem or no gourd block found
132 local try_connect_stem = function(stempos)
133 local stem = minetest.get_node(stempos)
134 if stem.name ~= full_unconnected_stem then
135 return false
137 for n=1, #neighbors do
138 local offset = neighbors[n]
139 local blockpos = vector.add(stempos, offset)
140 local block = minetest.get_node(blockpos)
141 if block.name == gourd_itemstring then
142 if offset.x == 1 then
143 minetest.set_node(stempos, {name=connected_stem_names[1]})
144 elseif offset.x == -1 then
145 minetest.set_node(stempos, {name=connected_stem_names[2]})
146 elseif offset.z == 1 then
147 minetest.set_node(stempos, {name=connected_stem_names[3]})
148 elseif offset.z == -1 then
149 minetest.set_node(stempos, {name=connected_stem_names[4]})
151 return true
156 -- Register gourd
157 if not gourd_def.after_dig_node then
158 gourd_def.after_dig_node = function(blockpos, oldnode, oldmetadata, user)
159 -- Disconnect any connected stems, turning them back to normal stems
160 for n=1, #neighbors do
161 local offset = neighbors[n]
162 local expected_stem = connected_stem_names[n]
163 local stempos = vector.add(blockpos, offset)
164 local stem = minetest.get_node(stempos)
165 if stem.name == expected_stem then
166 minetest.add_node(stempos, {name=full_unconnected_stem})
167 try_connect_stem(stempos)
172 if not gourd_def.on_construct then
173 gourd_def.on_construct = function(blockpos)
174 -- Connect all unconnected stems at full size
175 for n=1, #neighbors do
176 local stempos = vector.add(blockpos, neighbors[n])
177 try_connect_stem(stempos)
179 -- Call custom on_construct
180 if gourd_on_construct_extra then
181 gourd_on_construct_extra(blockpos)
185 minetest.register_node(gourd_itemstring, gourd_def)
187 -- Register unconnected stem
189 -- Default values for the stem definition
190 if not stem_def.selection_box then
191 stem_def.selection_box = {
192 type = "fixed",
193 fixed = {
194 {-0.15, -0.5, -0.15, 0.15, 0.5, 0.15}
198 if not stem_def.paramtype then
199 stem_def.paramtype = "light"
201 if not stem_def.drawtype then
202 stem_def.drawtype = "plantlike"
204 if stem_def.walkable == nil then
205 stem_def.walkable = false
207 if stem_def.sunlight_propagates == nil then
208 stem_def.sunlight_propagates = true
210 if stem_def.drop == nil then
211 stem_def.drop = stem_drop
213 if stem_def.groups == nil then
214 stem_def.groups = {dig_immediate=3, not_in_creative_inventory=1, plant=1,attached_node=1, dig_by_water=1,destroy_by_lava_flow=1,}
216 if stem_def.sounds == nil then
217 stem_def.sounds = mcl_sounds.node_sound_leaves_defaults()
220 if not stem_def.on_construct then
221 stem_def.on_construct = function(stempos)
222 -- Connect stem to gourd (if possible)
223 try_connect_stem(stempos)
226 minetest.register_node(stem_itemstring, stem_def)
228 -- Register connected stems
230 local connected_stem_tiles = {
231 { "blank.png", --top
232 "blank.png", -- bottom
233 "blank.png", -- right
234 "blank.png", -- left
235 connected_stem_texture, -- back
236 connected_stem_texture.."^[transformFX90" --front
238 { "blank.png", --top
239 "blank.png", -- bottom
240 "blank.png", -- right
241 "blank.png", -- left
242 connected_stem_texture.."^[transformFX90", --back
243 connected_stem_texture, -- front
245 { "blank.png", --top
246 "blank.png", -- bottom
247 connected_stem_texture.."^[transformFX90", -- right
248 connected_stem_texture, -- left
249 "blank.png", --back
250 "blank.png", -- front
252 { "blank.png", --top
253 "blank.png", -- bottom
254 connected_stem_texture, -- right
255 connected_stem_texture.."^[transformFX90", -- left
256 "blank.png", --back
257 "blank.png", -- front
260 local connected_stem_nodebox = {
261 {-0.5, -0.5, 0, 0.5, 0.5, 0},
262 {-0.5, -0.5, 0, 0.5, 0.5, 0},
263 {0, -0.5, -0.5, 0, 0.5, 0.5},
264 {0, -0.5, -0.5, 0, 0.5, 0.5},
266 local connected_stem_selectionbox = {
267 {-0.1, -0.5, -0.1, 0.5, 0.2, 0.1},
268 {-0.5, -0.5, -0.1, 0.1, 0.2, 0.1},
269 {-0.1, -0.5, -0.1, 0.1, 0.2, 0.5},
270 {-0.1, -0.5, -0.5, 0.1, 0.2, 0.1},
273 for i=1, 4 do
274 minetest.register_node(connected_stem_names[i], {
275 _doc_items_create_entry = false,
276 paramtype = "light",
277 sunlight_propagates = true,
278 walkable = false,
279 drop = stem_drop,
280 drawtype = "nodebox",
281 node_box = {
282 type = "fixed",
283 fixed = connected_stem_nodebox[i]
285 selection_box = {
286 type = "fixed",
287 fixed = connected_stem_selectionbox[i]
289 tiles = connected_stem_tiles[i],
290 groups = {dig_immediate=3, not_in_creative_inventory=1, plant=1,attached_node=1, dig_by_water=1,destroy_by_lava_flow=1,},
291 sounds = mcl_sounds.node_sound_leaves_defaults(),
292 _mcl_blast_resistance = 0,
295 if minetest.get_modpath("doc") then
296 doc.add_entry_alias("nodes", full_unconnected_stem, "nodes", connected_stem_names[i])
300 minetest.register_abm({
301 label = "Grow gourd stem to gourd ("..full_unconnected_stem.." → "..gourd_itemstring..")",
302 nodenames = {full_unconnected_stem},
303 neighbors = {"air"},
304 interval = grow_interval,
305 chance = grow_chance,
306 action = function(stempos)
307 local light = minetest.get_node_light(stempos)
308 if light and light > 10 then
309 -- Check the four neighbors and filter out neighbors where gourds can't grow
310 local neighbors = {
311 { x=-1, y=0, z=0 },
312 { x=1, y=0, z=0 },
313 { x=0, y=0, z=-1 },
314 { x=0, y=0, z=1 },
316 local floorpos, floor
317 for n=#neighbors, 1, -1 do
318 local offset = neighbors[n]
319 local blockpos = vector.add(stempos, offset)
320 floorpos = { x=blockpos.x, y=blockpos.y-1, z=blockpos.z }
321 floor = minetest.get_node(floorpos)
322 local block = minetest.get_node(blockpos)
323 local soilgroup = minetest.get_item_group(floor.name, "soil")
324 if not ((minetest.get_item_group(floor.name, "grass_block") == 1 or floor.name=="mcl_core:dirt" or soilgroup == 2 or soilgroup == 3) and block.name == "air") then
325 table.remove(neighbors, n)
329 -- Gourd needs at least 1 free neighbor to grow
330 if #neighbors > 0 then
331 -- From the remaining neighbors, grow randomly
332 local r = math.random(1, #neighbors)
333 local offset = neighbors[r]
334 local blockpos = vector.add(stempos, offset)
335 local p2
336 if offset.x == 1 then
337 minetest.set_node(stempos, {name=connected_stem_names[1]})
338 p2 = 3
339 elseif offset.x == -1 then
340 minetest.set_node(stempos, {name=connected_stem_names[2]})
341 p2 = 1
342 elseif offset.z == 1 then
343 minetest.set_node(stempos, {name=connected_stem_names[3]})
344 p2 = 2
345 elseif offset.z == -1 then
346 minetest.set_node(stempos, {name=connected_stem_names[4]})
347 p2 = 0
349 -- Place the gourd
350 if gourd_def.paramtype2 == "facedir" then
351 minetest.add_node(blockpos, {name=gourd_itemstring, param2=p2})
352 else
353 minetest.add_node(blockpos, {name=gourd_itemstring})
355 -- Reset farmland, etc. to dirt when the gourd grows on top
356 if minetest.get_item_group(floor.name, "dirtifies_below_solid") == 1 then
357 minetest.set_node(floorpos, {name = "mcl_core:dirt"})
361 end,
365 -- Used for growing gourd stems. Returns the intermediate color between startcolor and endcolor at a step
366 -- * startcolor: ColorSpec in table form for the stem in its lowest growing stage
367 -- * endcolor: ColorSpec in table form for the stem in its final growing stage
368 -- * step: The nth growth step. Counting starts at 1
369 -- * step_count: The number of total growth steps
370 function mcl_farming:stem_color(startcolor, endcolor, step, step_count)
371 local color = {}
372 local function get_component(startt, endd, step, step_count)
373 return math.floor(math.max(0, math.min(255, (startt + (((step-1)/step_count) * endd)))))
375 color.r = get_component(startcolor.r, endcolor.r, step, step_count)
376 color.g = get_component(startcolor.g, endcolor.g, step, step_count)
377 color.b = get_component(startcolor.b, endcolor.b, step, step_count)
378 local colorstring = string.format("#%02X%02X%02X", color.r, color.g, color.b)
379 return colorstring