Add new API call mcl_bone_meal.use_bone_meal and use this to remove duplicate code, update mcl_farming:sweet_berries to use bonemeal API, add stub for bonemeal mod compatibility

This commit is contained in:
teknomunk 2024-03-20 07:42:29 +00:00
parent a4f1ccd0ee
commit d5684ca305
5 changed files with 77 additions and 48 deletions

@ -42,6 +42,15 @@ Spawns standard or custom bone meal particles.
* `def`: (optional) particle definition; see minetest.add_particlespawner() * `def`: (optional) particle definition; see minetest.add_particlespawner()
for more details. for more details.
## mcl_bone_meal.use_bone_meal(itemstack, placer, pointed_thing)
For use in on_rightclick handlers that need support bone meal processing in addition
to other behaviors. Before calling, verify that the player is wielding bone meal.
* `itemstack`: The stack of bone meal being used
* `placer`: ObjectRef of the player who aplied the bone meal, can be nil!
* `pointed_thing`: exact pointing location (see Minetest API), where the
bone meal is applied
Returns itemstack with one bone meal consumed if not in creative mode.
# Legacy API # Legacy API
The bone meal API also provides a legacy compatibility function. This The bone meal API also provides a legacy compatibility function. This

@ -60,26 +60,14 @@ end
-- Legacy registered users of the old API are handled through this function. -- Legacy registered users of the old API are handled through this function.
-- --
local function apply_bone_meal(pointed_thing, placer) local function legacy_apply_bone_meal(pointed_thing, placer)
-- Legacy API support
for _, func in pairs(mcl_bone_meal.bone_meal_callbacks) do for _, func in pairs(mcl_bone_meal.bone_meal_callbacks) do
if func(pointed_thing, placer) then if func(pointed_thing, placer) then
return true return true
end end
end end
local pos = pointed_thing.under
local n = minetest.get_node(pos)
if n.name == "" then return false end
-- Wheat, Potato, Carrot, Pumpkin Stem, Melon Stem: Advance by 2-5 stages
if string.find(n.name, "mcl_farming:sweet_berry_bush_") then
mcl_dye.add_bone_meal_particle(pos)
if n.name == "mcl_farming:sweet_berry_bush_3" then
return minetest.add_item(vector.offset(pos,math.random()-0.5,math.random()-0.5,math.random()-0.5),"mcl_farming:sweet_berry")
else
return mcl_farming:grow_plant("plant_sweet_berry_bush", pos, n, 0, true)
end
return true
--[[ --[[
Here for when Bonemeal becomes an api, there's code if needed for handling applying to bamboo. Here for when Bonemeal becomes an api, there's code if needed for handling applying to bamboo.
-- Handle applying bonemeal to bamboo. -- Handle applying bonemeal to bamboo.
@ -90,12 +78,42 @@ local function apply_bone_meal(pointed_thing, placer)
end end
return success return success
--]] --]]
end
return false return false
end end
-- End legacy bone meal API -- End legacy bone meal API
mcl_bone_meal.use_bone_meal = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
-- Check protection
if mcl_util.check_area_protection(pos, pointed_thing.above, placer) then return false end
local node = minetest.get_node(pos)
local ndef = minetest.registered_nodes[node.name]
local success = false
-- If the pointed node can be bonemealed, let it handle the processing.
if ndef and ndef._mcl_on_bonemealing then
success = ndef._mcl_on_bonemealing(pointed_thing, placer)
else
-- Otherwise try the legacy API.
success = legacy_apply_bone_meal(pointed_thing, placer)
end
-- Particle effects
if success then
mcl_bone_meal.add_bone_meal_particle(pos)
end
-- Take the item
if not placer or not minetest.is_creative_enabled(placer:get_player_name()) then
itemstack:take_item()
end
return itemstack
end
minetest.register_craftitem("mcl_bone_meal:bone_meal", { minetest.register_craftitem("mcl_bone_meal:bone_meal", {
description = S("Bone Meal"), description = S("Bone Meal"),
_tt_help = S("Speeds up plant growth"), _tt_help = S("Speeds up plant growth"),
@ -107,26 +125,15 @@ minetest.register_craftitem("mcl_bone_meal:bone_meal", {
local pos = pointed_thing.under local pos = pointed_thing.under
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local ndef = minetest.registered_nodes[node.name] local ndef = minetest.registered_nodes[node.name]
-- Use pointed node's on_rightclick function first, if present. -- Use pointed node's on_rightclick function first, if present.
if placer and not placer:get_player_control().sneak then if placer and not placer:get_player_control().sneak then
if ndef and ndef.on_rightclick then if ndef and ndef.on_rightclick then
return ndef.on_rightclick(pos, node, placer, itemstack, pointed_thing) or itemstack return ndef.on_rightclick(pos, node, placer, itemstack, pointed_thing) or itemstack
end end
end end
-- If the pointed node can be bonemealed, let it handle the processing.
if ndef and ndef._mcl_on_bonemealing then return mcl_bone_meal.use_bone_meal(itemstack, placer, pointed_thing)
if ndef._mcl_on_bonemealing(pointed_thing, placer) then
mcl_bone_meal.add_bone_meal_particle(pos)
end
if not minetest.is_creative_enabled(placer:get_player_name()) then
itemstack:take_item()
end
-- Otherwise try the legacy API.
elseif apply_bone_meal(pointed_thing, placer) and
not minetest.is_creative_enabled(placer:get_player_name()) then
itemstack:take_item()
end
return itemstack
end, end,
_on_dispense = function(itemstack, pos, droppos, dropnode, dropdir) _on_dispense = function(itemstack, pos, droppos, dropnode, dropdir)
local pointed_thing local pointed_thing
@ -135,21 +142,8 @@ minetest.register_craftitem("mcl_bone_meal:bone_meal", {
else else
pointed_thing = {above = pos, under = droppos} pointed_thing = {above = pos, under = droppos}
end end
local node = minetest.get_node(pointed_thing.under)
local ndef = minetest.registered_nodes[node.name] return mcl_bone_meal.use_bone_meal(itemstack, nil, pointed_thing)
-- If the pointed node can be bonemealed, let it handle the processing.
if ndef and ndef._mcl_on_bonemealing then
if ndef._mcl_on_bonemealing(pointed_thing, nil) then
mcl_bone_meal.add_bone_meal_particle(pos)
end
itemstack:take_item()
else
-- Otherwise try the legacy API.
if apply_bone_meal(pointed_thing, nil) then
itemstack:take_item()
end
end
return itemstack
end, end,
_dispense_into_walkable = true _dispense_into_walkable = true
}) })

@ -12,6 +12,25 @@ for i=0, 3 do
local drop_berries = (i >= 2) local drop_berries = (i >= 2)
local berries_to_drop = drop_berries and {i - 1, i} or nil local berries_to_drop = drop_berries and {i - 1, i} or nil
local on_bonemealing = nil
local function do_berry_drop(pos)
for j=1, berries_to_drop[math.random(2)] do
minetest.add_item(pos, "mcl_farming:sweet_berry")
end
minetest.swap_node(pos, {name = "mcl_farming:sweet_berry_bush_1"})
end
if i ~= 3 then
on_bonemealing = function(pointed_thing, placer)
local pos = pointed_thing.under
local node = minetest.get_node(pos)
return mcl_farming:grow_plant("plant_sweet_berry_bush", pos, node, 0, true)
end
else
on_bonemealing = function(pointed_thing, placer)
do_berry_drop(pointed_thing.under)
end
end
minetest.register_node(node_name, { minetest.register_node(node_name, {
drawtype = "plantlike", drawtype = "plantlike",
tiles = {texture}, tiles = {texture},
@ -45,6 +64,7 @@ for i=0, 3 do
sounds = mcl_sounds.node_sound_leaves_defaults(), sounds = mcl_sounds.node_sound_leaves_defaults(),
_mcl_blast_resistance = 0, _mcl_blast_resistance = 0,
_mcl_hardness = 0, _mcl_hardness = 0,
_mcl_on_bonemealing = on_bonemealing,
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local pn = clicker:get_player_name() local pn = clicker:get_player_name()
if clicker:is_player() and minetest.is_protected(pos, pn) then if clicker:is_player() and minetest.is_protected(pos, pn) then
@ -60,11 +80,13 @@ for i=0, 3 do
return return
end end
if drop_berries then if i >= 2 then
for j=1, berries_to_drop[math.random(2)] do do_berry_drop(pos)
minetest.add_item(pos, "mcl_farming:sweet_berry") else
-- Use bonemeal
if mcl_bone_meal and clicker:get_wielded_item():get_name() == "mcl_bone_meal:bone_meal" then
return mcl_bone_meal.use_bone_meal(itemstack, clicker, pointed_thing)
end end
minetest.swap_node(pos, {name = "mcl_farming:sweet_berry_bush_1"})
end end
return itemstack return itemstack
end, end,

@ -0,0 +1,4 @@
name = bonemeal
author = teknomunk
description = Compatibility shim for WorldEdit-Additions bonemeal support
optional_depends = mcl_bone_meal