VoxeLibre/mods/ITEMS/mcl_cocoas/init.lua
kabou 8acddab74f Bonemealing mechanics bugfix.
When applying bonemeal to eg. farm crops, these have a chance to grow in
response to the application of bone meal. When a node can be bonemealed, the
applied bone meal item should always be spent after using it, regardless of
the results.  Currently this does not work correctly, if the result of
bonemealing has no effect on the node, the used bone meal item is not spent.

This commit fixes the behavior of the bone meal item to always be taken when
used on a node that defines a `_mcl_on_bonemealing()` callback.

The nodes that implement the callback imay use the handler's return value
only to signal if the bonemealing was succesful, not to signal if it was at
all possible.  For this reason, some nodes need to be made more strictly
conforming to the API.

* Always take the used bone meal item (if user is not in creative mode),
  regardless of whether the bonemealed node's handler returned `true`.
* Make dispensers spawn particles after succesful bonemealing.
* Trivial comment fix.
* Ripe cocoa pod cannot be bonemealed.
* Update API.md to describe the stricter API semantics.
2024-11-09 20:24:02 -06:00

207 lines
6.6 KiB
Lua

local S = minetest.get_translator(minetest.get_current_modname())
mcl_cocoas = {}
--- Place a cocoa pod.
-- Attempt to place a cocoa pod on a jungle tree. Checks if attachment
-- point is a jungle tree and sets the correct orientation of the stem.
--
function mcl_cocoas.place(itemstack, placer, pt, plantname)
-- check if pointing at a node
if not pt or pt.type ~= "node" then
return
end
local node = minetest.get_node(pt.under)
-- return if any of the nodes are not registered
local def = minetest.registered_nodes[node.name]
if not def then
return
end
-- Am I right-clicking on something that has a custom on_rightclick set?
if placer and not placer:get_player_control().sneak then
if def and def.on_rightclick then
return def.on_rightclick(pt.under, node, placer, itemstack) or itemstack
end
end
-- Check if pointing at jungle tree
if node.name ~= "mcl_core:jungletree"
or minetest.get_node(pt.above).name ~= "air" then
return
end
-- Determine cocoa direction
local clickdir = vector.subtract(pt.under, pt.above)
-- Did user click on the SIDE of a jungle tree?
if clickdir.y ~= 0 then
return
end
-- Add the node, set facedir and remove 1 item from the itemstack
minetest.set_node(pt.above, {name = plantname, param2 = minetest.dir_to_facedir(clickdir)})
minetest.sound_play("default_place_node", {pos = pt.above, gain = 1.0}, true)
if not minetest.is_creative_enabled(placer:get_player_name()) then
itemstack:take_item()
end
return itemstack
end
--- Grows cocoa pod one size larger.
-- Attempts to grow a cocoa at pos, returns true when grown, returns false
-- if there's no cocoa or it is already at full size.
--
function mcl_cocoas.grow(pos)
local node = minetest.get_node(pos)
if node.name == "mcl_cocoas:cocoa_1" then
minetest.set_node(pos, {name = "mcl_cocoas:cocoa_2", param2 = node.param2})
elseif node.name == "mcl_cocoas:cocoa_2" then
minetest.set_node(pos, {name = "mcl_cocoas:cocoa_3", param2 = node.param2})
else
return false
end
return true
end
-- only caller was mcl_dye, now these can be local functions.
-- TODO: remove aliases, replace global functions with local functions.
local cocoa_place = mcl_cocoas.place
local cocoa_grow = mcl_cocoas.grow
-- Cocoa pod variant definitions.
--[[ TODO: Use a mesh for cocoas for perfect texture compability. ]]
local podinfo = {
{ desc = S("Premature Cocoa Pod"),
longdesc = S("Cocoa pods grow on the side of jungle trees in 3 stages."),
tiles = {
"[combine:16x16:6,1=mcl_cocoas_cocoa_stage_0.png",
"[combine:16x16:6,11=mcl_cocoas_cocoa_stage_0.png",
"mcl_cocoas_cocoa_stage_0.png",
"mcl_cocoas_cocoa_stage_0.png^[transformFX",
"[combine:16x16:-5,0=mcl_cocoas_cocoa_stage_0.png",
"[combine:16x16:-5,0=mcl_cocoas_cocoa_stage_0.png",
},
n_box = {-0.125, -0.0625, 0.1875, 0.125, 0.25, 0.4375},
s_box = {-0.125, -0.0625, 0.1875, 0.125, 0.5, 0.5 },
},
{ desc = S("Medium Cocoa Pod"),
tiles = {
"[combine:16x16:5,1=mcl_cocoas_cocoa_stage_1.png",
"[combine:16x16:5,9=mcl_cocoas_cocoa_stage_1.png",
"mcl_cocoas_cocoa_stage_1.png",
"mcl_cocoas_cocoa_stage_1.png^[transformFX",
"[combine:16x16:-4,0=mcl_cocoas_cocoa_stage_1.png",
"[combine:16x16:-4,0=mcl_cocoas_cocoa_stage_1.png",
},
n_box = {-0.1875, -0.1875, 0.0625, 0.1875, 0.25, 0.4375},
s_box = {-0.1875, -0.1875, 0.0625, 0.1875, 0.5, 0.5 },
},
{ desc = S("Mature Cocoa Pod"),
longdesc = S("A mature cocoa pod grew on a jungle tree to its full size and it is ready to be harvested for cocoa beans. It won't grow any further."),
tiles = {
-- The following 2 textures were derived from the original
-- because the size of the top/bottom is slightly different :-(
-- TODO: Find a way to *only* use the base texture
"mcl_cocoas_cocoa_top_stage_2.png",
"mcl_cocoas_cocoa_top_stage_2.png^[transformFY",
"mcl_cocoas_cocoa_stage_2.png",
"mcl_cocoas_cocoa_stage_2.png^[transformFX",
"[combine:16x16:-3,0=mcl_cocoas_cocoa_stage_2.png",
"[combine:16x16:-3,0=mcl_cocoas_cocoa_stage_2.png",
},
n_box = {-0.25, -0.3125, -0.0625, 0.25, 0.25, 0.4375},
s_box = {-0.25, -0.3125, -0.0625, 0.25, 0.5, 0.5 },
},
}
for i = 1, 3 do
local def = {
description = podinfo[i].desc,
_doc_items_create_entry = true,
_doc_items_longdesc = podinfo[i].longdesc,
paramtype = "light",
paramtype2 = "facedir",
drawtype = "nodebox",
tiles = podinfo[i].tiles,
use_texture_alpha = "clip",
node_box = {
type = "fixed",
fixed = {
podinfo[i].n_box, -- Pod
-- FIXME: This has a thickness of 0. Is this OK in Minetest?
{ 0, 0.25, 0.25, 0, 0.5, 0.5 }, }, -- Stem
},
collision_box = {
type = "fixed",
fixed = podinfo[i].n_box
},
selection_box = {
type = "fixed",
fixed = podinfo[i].s_box
},
groups = {
handy = 1, axey = 1, attached_node_facedir = 1,
dig_by_water = 1, destroy_by_lava_flow = 1, dig_by_piston = 1,
cocoa = i, not_in_creative_inventory = 1,
},
sunlight_propagates = true,
walkable = true,
drop = "mcl_cocoas:cocoa_beans",
sounds = mcl_sounds.node_sound_wood_defaults(),
on_rotate = false,
_mcl_blast_resistance = 3,
_mcl_hardness = 0.2,
_mcl_on_bonemealing = function(pointed_thing, placer)
local pos = pointed_thing.under
return cocoa_grow(pos)
end,
}
if i == 2 then
def._doc_items_longdesc = nil
def._doc_items_create_entry = false
end
if i == 3 then
def.drop = "mcl_cocoas:cocoa_beans 3"
def._mcl_on_bonemealing = nil
end
minetest.register_node("mcl_cocoas:cocoa_" .. i, table.copy(def))
end
minetest.register_craftitem("mcl_cocoas:cocoa_beans", {
inventory_image = "mcl_cocoa_beans.png",
_tt_help = S("Grows at the side of jungle trees"),
_doc_items_longdesc = S("Cocoa beans can be used to plant cocoa, bake cookies or cract brown dye."),
_doc_items_usagehelp = S("Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa."),
description = S("Cocoa Beans"),
stack_max = 64,
groups = {
dye = 1, craftitem = 1, compostability = 65,
basecolor_brown = 1, excolor_orange = 1, unicolor_dark_orange = 1,
},
on_place = function(itemstack, placer, pointed_thing)
return cocoa_place(itemstack, placer, pointed_thing, "mcl_cocoas:cocoa_1")
end,
})
minetest.register_abm({
label = "Cocoa pod growth",
nodenames = {"mcl_cocoas:cocoa_1", "mcl_cocoas:cocoa_2"},
-- Same as potatoes
-- TODO: Tweak/balance the growth speed
interval = 50,
chance = 20,
action = function(pos, node)
mcl_cocoas.grow(pos)
end
} )
-- Add entry aliases for the Help
if minetest.get_modpath("doc") then
doc.add_entry_alias("nodes", "mcl_cocoas:cocoa_1", "nodes", "mcl_cocoas:cocoa_2")
end