Merge pull request 'bonemeal API update' (#4221) from teknomunk/MineClone2:bonemeal-2 into master

Reviewed-on: https://git.minetest.land/VoxeLibre/VoxeLibre/pulls/4221
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
This commit is contained in:
the-real-herowl 2024-11-10 11:38:08 +01:00
commit c428fa576b
58 changed files with 995 additions and 819 deletions

@ -1131,3 +1131,25 @@ if not vector.in_area then
(pos.z >= min.z) and (pos.z <= max.z)
end
end
-- Traces along a line of nodes vertically to find the next possition that isn't an allowed node
---@param pos The position to start tracing from
---@param dir The direction to trace in. 1 is up, -1 is down, all other values are not allowed.
---@param allowed_nodes A set of node names to trace along.
---@param limit The maximum number of steps to make. Defaults to 16 if nil or missing
---@return Three return values:
--- the position of the next node that isn't allowed or nil if no such node was found,
--- the distance from the start where that node was found,
--- the node table if a node was found
function mcl_util.trace_nodes(pos, dir, allowed_nodes, limit)
if (dir ~= -1) and (dir ~= 1) then return nil, 0, nil end
limit = limit or 16
for i = 1,limit do
pos = vector.offset(pos, 0, dir, 0)
local node = minetest.get_node(pos)
if not allowed_nodes[node.name] then return pos, i, node end
end
return nil, limit, nil
end

@ -34,6 +34,10 @@ local bamboo_def = {
wield_image = "mcl_bamboo_bamboo_shoot.png",
_mcl_blast_resistance = 1,
_mcl_hardness = 1,
_on_bone_meal = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
return mcl_bamboo.grow_bamboo(pos, true)
end,
node_box = {
type = "fixed",
fixed = {

@ -44,6 +44,10 @@ mcl_bamboo.bamboo_index = {
"mcl_bamboo:bamboo_2",
"mcl_bamboo:bamboo_3",
}
mcl_bamboo.bamboo_set = {}
for _,key in pairs(mcl_bamboo.bamboo_index) do
mcl_bamboo.bamboo_set[key] = true
end
function mcl_bamboo.is_bamboo(node_name)
local index = table.indexof(mcl_bamboo.bamboo_index, node_name)
@ -94,172 +98,84 @@ end
--]]
function mcl_bamboo.grow_bamboo(pos, bonemeal_applied)
local log = mcl_bamboo.mcl_log
local node_above = minetest.get_node(vector.offset(pos, 0, 1, 0))
mcl_bamboo.mcl_log("Grow bamboo called; bonemeal: " .. tostring(bonemeal_applied))
log("Grow bamboo called; bonemeal: " .. tostring(bonemeal_applied))
if not bonemeal_applied and mcl_bamboo.is_bamboo(node_above.name) ~= false then
return false -- short circuit this function if we're trying to grow (std) the bamboo and it's not the top shoot.
if not bonemeal_applied then
-- Only allow natural growth at the top of the bamboo
if mcl_bamboo.is_bamboo(node_above.name) ~= false then return false end
-- Don't perform natual growth in low light
if minetest.get_node_light(pos) < 8 then return false end
end
if minetest.get_node_light(pos) < 8 then
-- Determine the location of soil
local soil_pos
soil_pos,a,b = mcl_util.trace_nodes(pos, -1, mcl_bamboo.bamboo_set, BAMBOO_MAX_HEIGHT - 1)
-- No soil found, return false so that bonemeal isn't used
if not soil_pos then return false end
log("Grow bamboo; soil found. ")
-- Find the first bamboo shoot and retrieve data about it
local first_shoot = vector.offset(soil_pos, 0, 1, 0)
local first_shoot_meta = minetest.get_meta(first_shoot)
-- Get or initialize bamboo height
local height = (first_shoot_meta and first_shoot_meta:get_int("height", -1)) or -1
if height == -1 then
height = rand(BAM_MAX_HEIGHT_STPCHK + 1, BAM_MAX_HEIGHT_TOP + 1)
first_shoot_meta:set_int("height", height)
end
log("Grow bamboo; height: " .. height)
-- Locate the bamboo tip
local bamboo_tip,actual_height,bamboo_tip_node = mcl_util.trace_nodes(first_shoot, 1, mcl_bamboo.bamboo_set, height - 1)
log("Current height: "..tostring(actual_height))
-- Short circuit growth if the bamboo is already finished growing
if not bamboo_tip or not actual_height or actual_height >= height then
log("Bamboo is already as large as it can grow")
return false
end
-- variables used in more than one spot.
local first_shoot
local chk_pos
local soil_pos
local node_name = ""
local dist = 0
local node_below
-- -------------------
-- Now that we are actually going to add nodes, initialize some more information
local first_shoot_node_name = minetest.get_node(first_shoot).name
mcl_bamboo.mcl_log("Grow bamboo; checking for soil: ")
-- the soil node below the bamboo.
for py = -1, BAMBOO_SOIL_DIST, -1 do
chk_pos = vector.offset(pos, 0, py, 0)
node_name = minetest.get_node(chk_pos).name
if mcl_bamboo.is_dirt(node_name) then
soil_pos = chk_pos
break
end
if mcl_bamboo.is_bamboo(node_name) == false then
break
end
end
-- requires knowing where the soil node is.
if soil_pos == nil then
return false -- returning false means don't use up the bonemeal.
end
mcl_bamboo.mcl_log("Grow bamboo; soil found. ")
local grow_amount = rand(1, GROW_DOUBLE_CHANCE)
grow_amount = rand(1, GROW_DOUBLE_CHANCE)
grow_amount = rand(1, GROW_DOUBLE_CHANCE) -- because yeah, not truly random, or even a good prng.
grow_amount = rand(1, GROW_DOUBLE_CHANCE)
local init_height = rand(BAM_MAX_HEIGHT_STPCHK + 1, BAM_MAX_HEIGHT_TOP + 1)
mcl_bamboo.mcl_log("Grow bamboo; random height: " .. init_height)
node_name = ""
-- update: add randomized max height to first node's meta data.
first_shoot = vector.offset(soil_pos, 0, 1, 0)
local meta = minetest.get_meta(first_shoot)
node_below = minetest.get_node(first_shoot).name
mcl_bamboo.mcl_log("Grow bamboo; checking height meta ")
-- check the meta data for the first node, to see how high to make the stalk.
if not meta then
-- if no metadata, set the metadata!!!
meta:set_int("height", init_height)
end
local height = meta:get_int("height", -1)
mcl_bamboo.mcl_log("Grow bamboo; meta-height: " .. height)
if height <= 10 then
height = init_height
meta:set_int("height", init_height)
end
mcl_bamboo.mcl_log("Grow bamboo; height: " .. height)
-- Bonemeal: Grows the bamboo by 1-2 stems. (per the minecraft wiki.)
-- If applying bonemeal, randomly grow two segments instead of one
local grow_amount = 1
if bonemeal_applied then
-- handle applying bonemeal.
for py = 1, BAM_MAX_HEIGHT_TOP do
-- find the top node of bamboo.
chk_pos = vector.offset(pos, 0, py, 0)
node_name = minetest.get_node(chk_pos).name
dist = vector.distance(soil_pos, chk_pos)
if mcl_bamboo.is_bamboo(node_name) == false or node_name == BAMBOO_ENDCAP_NAME then
break
end
end
mcl_bamboo.mcl_log("Grow bamboo; dist: " .. dist)
if node_name == BAMBOO_ENDCAP_NAME then
-- prevent overgrowth
return false
end
-- check to see if we have a full stalk of bamboo.
if dist >= height - 1 then
if dist == height - 1 then
-- equals top of the stalk before the cap
if node_name == "air" then
mcl_bamboo.mcl_log("Grow bamboo; Placing endcap")
minetest.set_node(vector.offset(chk_pos, 0, 1, 0), { name = BAMBOO_ENDCAP_NAME })
return true -- returning true means use up the bonemeal.
else
return false
end
else
-- okay, we're higher than the end cap, fail out.
return false -- returning false means don't use up the bonemeal.
end
end
-- and now, the meat of the section... add bamboo to the stalk.
-- at this point, we should be lower than the generated maximum height. ~ about height -2 or lower.
if dist <= height - 2 then
if node_name == "air" then
-- here we can check to see if we can do up to 2 bamboo shoots onto the stalk
mcl_bamboo.mcl_log("Grow bamboo; Placing bamboo.")
minetest.set_node(chk_pos, { name = node_below })
-- handle growing a second node.
if grow_amount == 2 then
chk_pos = vector.offset(chk_pos, 0, 1, 0)
if minetest.get_node(chk_pos).name == "air" then
mcl_bamboo.mcl_log("Grow bamboo; OOOH! It's twofer day!")
minetest.set_node(chk_pos, { name = node_below })
end
end
return true -- exit out with a success. We've added 1-2 nodes, per the wiki.
end
local rng = PcgRandom(minetest.hash_node_position(pos) + minetest.get_us_time())
if rng:next(1, GROW_DOUBLE_CHANGE) == 1 then
grow_amount = 2
end
end
log("Growing up to "..grow_amount.." segments")
-- Non-Bonemeal growth.
for py = 1, BAM_MAX_HEIGHT_TOP do
-- Find the topmost node above the stalk, and check it for "air"
chk_pos = vector.offset(pos, 0, py, 0)
node_below = minetest.get_node(pos).name
node_name = minetest.get_node(chk_pos).name
dist = vector.distance(soil_pos, chk_pos)
if node_name ~= "air" and mcl_bamboo.is_bamboo(node_name) == false then
break
-- Perform bamboo growth
for i = 1,grow_amount do
-- Check for air to grow into
local bamboo_tip_node = minetest.get_node(bamboo_tip)
if not bamboo_tip_node or bamboo_tip_node.name ~= "air" then
-- Something is blocking growth, stop and signal that use bonemeal has been used if at least on segment has grown
return i ~= 1
end
-- stop growing check. ie, handle endcap placement.
if dist >= height - 1 then
local above_node_name = minetest.get_node(vector.offset(chk_pos, 0, 1, 0)).name
if node_name == "air" and above_node_name == "air" then
if height - 1 == dist then
mcl_bamboo.mcl_log("Grow bamboo; Placing endcap")
minetest.set_node(chk_pos, { name = BAMBOO_ENDCAP_NAME })
end
end
break
if actual_height + 1 == height then
-- This is the end cap
minetest.set_node(bamboo_tip, { name = BAMBOO_ENDCAP_NAME })
return true
else
-- This isn't the end cap, add a bamboo segment
minetest.set_node(bamboo_tip, { name = first_shoot_node_name })
actual_height = actual_height + 1
end
-- handle regular node placement.
-- find the air node above the top shoot. place a node. And then, if short enough,
-- check for second node placement.
if node_name == "air" then
mcl_bamboo.mcl_log("Grow bamboo; dist: " .. dist)
mcl_bamboo.mcl_log("Grow bamboo; Placing bamboo.")
minetest.set_node(chk_pos, { name = node_below })
-- handle growing a second node. (1 in 32 chance.)
if grow_amount == 2 and dist <= height - 2 then
chk_pos = vector.offset(chk_pos, 0, 1, 0)
if minetest.get_node(chk_pos).name == "air" then
mcl_bamboo.mcl_log("Grow bamboo; OOOH! It's twofer day!")
minetest.set_node(chk_pos, { name = node_below })
end
end
break
end
bamboo_tip = vector.offset(bamboo_tip, 0, 1, 0)
end
return true
end
-- Add Groups function, courtesy of Warr1024.

@ -2,4 +2,4 @@ name = mcl_beds
author = BlockMen
description =
depends = playerphysics
optional_depends = mcl_sounds, mcl_worlds, mcl_wool, mcl_dye, mcl_explosions, mcl_weather, mcl_spawn, doc, mesecons
optional_depends = mcl_sounds, mcl_worlds, mcl_wool, mcl_dye, mcl_explosions, mcl_weather, mcl_spawn, doc, mesecons, mesecons_mvps

@ -0,0 +1,76 @@
# Bone meal API
Bonemealing callbacks and particle functions.
## _on_bone_meal(itemstack, placer, pointed_thing)
The bone meal API provides a callback definition that nodes can use to
register a handler that is executed when a bone meal item is used on it.
Nodes that wish to use the bone meal API should in their node registration
define a callback handler named `_on_bone_meal`.
Note that by registering the callback handler, the node declares that bone
meal can be used on it and as a result, when the user is not in creative
mode, the used bone meal is spent and taken from the itemstack passed to
the `on_place()` handler of the bone meal item used regardless of whether
the bone meal had an effect on the node and regardless of the result of
the callback handler.
It is for all intents and purposes up to the callback defined in the node to
decide how to handle the specific effect that bone meal has on that node.
The `_on_bone_meal` callback handler is a
`function(itemstack, placer, pointed_thing)`
Its arguments are:
* `itemstack`: the stack of bonem eal being applied
* `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
The return value of the handler function indicates if the bonemealing had
its intended effect. If `true`, 'bone meal particles' are spawned at the
position of the bonemealed node.
The `on_place` code in the bone meal item will spawn bone meal particles and
decrease the bone meal itemstack if the handler returned `true` and the
`placer` is not in creative mode.
## mcl_bone_meal.add_bone_meal_particle(pos, def)
Spawns standard or custom bone meal particles.
* `pos`: position, is ignored if you define def.minpos and def.maxpos
* `def`: (optional) particle definition; see minetest.add_particlespawner()
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
The bone meal API also provides a legacy compatibility function. This
function is not meant to be continued and callers should migrate to the
newer bonemealing API.
## mcl_bone_meal.register_on_bone_meal_apply(function(pointed_thing, placer))
Called when the bone meal is applied anywhere.
* `pointed_thing`: exact pointing location (see Minetest API), where the
bone meal is applied
* `placer`: ObjectRef of the player who aplied the bone meal, can be nil!
This function is deprecated and will be removed at some time in the future.
Bone meal is not consumed unless the provided function returns true.
## mcl_dye.add_bone_meal_particle(pos, def)
## mcl_dye.register_on_bone_meal_apply(function(pointed_thing, user))
These shims in mcl_dye that point to corresponding legacy compatibility
functions in mcl_bone_meal remain for legacy callers that have not yet been
updated to the new API. These shims will be removed at some time in the
future.

@ -0,0 +1,156 @@
local S = minetest.get_translator(minetest.get_current_modname())
local longdesc = S(
"Bone meal is a white dye and also useful as a fertilizer to " ..
"speed up the growth of many plants."
)
local usagehelp = S(
"Rightclick a sheep to turn its wool white. Rightclick a plant " ..
"to speed up its growth. Note that not all plants can be " ..
"fertilized like this. When you rightclick a grass block, tall " ..
"grass and flowers will grow all over the place."
)
mcl_bone_meal = {}
-- Bone meal particle API:
--- Spawns bone meal particles.
-- pos: where the particles spawn
-- def: particle spawner parameters, see minetest.add_particlespawner() for
-- details on these parameters.
--
function mcl_bone_meal.add_bone_meal_particle(pos, def)
def = def or {}
minetest.add_particlespawner({
amount = def.amount or 10,
time = def.time or 0.1,
minpos = def.minpos or vector.subtract(pos, 0.5),
maxpos = def.maxpos or vector.add(pos, 0.5),
minvel = def.minvel or vector.new(-0.01, 0.01, -0.01),
maxvel = def.maxvel or vector.new(0.01, 0.01, 0.01),
minacc = def.minacc or vector.new(0, 0, 0),
maxacc = def.maxacc or vector.new(0, 0, 0),
minexptime = def.minexptime or 1,
maxexptime = def.maxexptime or 4,
minsize = def.minsize or 0.7,
maxsize = def.maxsize or 2.4,
texture = "mcl_particles_bonemeal.png^[colorize:#00EE00:125",
glow = def.glow or 1,
})
end
-- Begin legacy bone meal API.
--
-- Compatibility code for legacy users of the old bone meal API.
-- This code will be removed at some time in the future.
--
mcl_bone_meal.bone_meal_callbacks = {}
-- Shims for the old API are still available in mcl_dye and defer to
-- the real functions in mcl_bone_meal.
--
function mcl_bone_meal.register_on_bone_meal_apply(func)
minetest.log("warning", "register_on_bone_meal_apply(func) is deprecated. Read mcl_bone_meal/API.md!")
local lines = string.split(debug.traceback(),"\n")
for _,line in ipairs(lines) do
minetest.log("warning",line)
end
table.insert(mcl_bone_meal.bone_meal_callbacks, func)
end
-- Legacy registered users of the old API are handled through this function.
--
local function legacy_apply_bone_meal(pointed_thing, placer)
-- Legacy API support
local callbacks = mcl_bone_meal.bone_meal_callbacks
for i = 1,#callbacks do
if callbacks[i](pointed_thing, placer) then
return true
end
end
return false
end
-- End legacy bone meal API
function mcl_bone_meal.use_bone_meal(itemstack, placer, pointed_thing)
local positions = {pointed_thing.under, pointed_thing.above}
for i = 1,2 do
local pos = positions[i]
-- 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
local consume
-- If the pointed node can be bonemealed, let it handle the processing.
if ndef and ndef._on_bone_meal then
success = ndef._on_bone_meal(itemstack, placer, {under = pos, above = vector.offset(pos, 0, 1, 0)})
consume = true
else
-- Otherwise try the legacy API.
success = legacy_apply_bone_meal(pointed_thing, placer)
consume = success
end
-- Take the item
if consume then
-- Particle effects
mcl_bone_meal.add_bone_meal_particle(pos)
if not placer or not minetest.is_creative_enabled(placer:get_player_name()) then
itemstack:take_item()
end
return itemstack
end
if success then return itemstack end
end
return itemstack
end
minetest.register_craftitem("mcl_bone_meal:bone_meal", {
description = S("Bone Meal"),
_tt_help = S("Speeds up plant growth"),
_doc_items_longdesc = longdesc,
_doc_items_usagehelp = usagehelp,
inventory_image = "mcl_bone_meal.png",
groups = {craftitem=1},
on_place = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
local node = minetest.get_node(pos)
local ndef = minetest.registered_nodes[node.name]
-- Use pointed node's on_rightclick function first, if present.
if placer and not placer:get_player_control().sneak then
if ndef and ndef.on_rightclick then
local new_stack = mcl_util.call_on_rightclick(itemstack, placer, pointed_thing)
if new_stack and new_stack ~= itemstack then return new_stack end
end
end
return mcl_bone_meal.use_bone_meal(itemstack, placer, pointed_thing)
end,
_on_dispense = function(itemstack, pos, droppos, dropnode, dropdir)
local pointed_thing
if dropnode.name == "air" then
pointed_thing = {above = droppos, under = vector.offset(droppos, 0, -1 ,0)}
else
pointed_thing = {above = pos, under = droppos}
end
return mcl_bone_meal.use_bone_meal(itemstack, nil, pointed_thing)
end,
_dispense_into_walkable = true
})
minetest.register_craft({
output = "mcl_bone_meal:bone_meal 3",
recipe = {{"mcl_mobitems:bone"}},
})

@ -0,0 +1,5 @@
# textdomain: mcl_bone_meal
Bone Meal=Knochenmehl
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=Knochenmehl ist ein weißer Farbstoff und auch nützlich als Dünger, um das Wachstum vieler Pflanzen zu beschleunigen.
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=Rechtsklicken Sie auf ein Schaf, um die Wolle weiß einzufärben. Rechtsklicken Sie auf eine Pflanze, um ihr Wachstum zu beschleunigen. Beachten Sie, dass nicht alle Pflanzen darauf ansprechen. Benutzen Sie es auf einem Grasblock, wächst viel hohes Gras und vielleicht auch ein paar Blumen.
Speeds up plant growth=Beschleunigt Pflanzenwachstum

@ -0,0 +1,5 @@
# textdomain: mcl_bone_meal
Bone Meal=Harina de hueso
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=La harina de hueso es un tinte blanco y también es útil como fertilizante para acelerar el crecimiento de muchas plantas.
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=RHaga clic derecho en una oveja para volver su lana blanca. Haga clic derecho en una planta para acelerar su crecimiento. Tenga en cuenta que no todas las plantas pueden ser fertilizadas de esta manera. Cuando haces clic derecho en un bloque de hierba, crecerán hierba alta y flores por todo el lugar.
Speeds up plant growth=Acelera el crecimiento de las plantas

@ -0,0 +1,6 @@
# textdomain: mcl_bone_meal
Bone Meal=Farine d'Os
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=La farine d'os est une teinture blanche et est également utile comme engrais pour accélérer la croissance de nombreuses plantes.
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=
Cliquez avec le bouton droit sur un mouton pour blanchir sa laine. Cliquez avec le bouton droit sur une plante pour accélérer sa croissance. Cependant, toutes les plantes ne peuvent pas être fertilisées de cette manière. Lorsque vous cliquez avec le bouton droit sur un bloc d'herbe, les hautes herbes et les fleurs poussent autour.
Speeds up plant growth=Accélère la croissance des plantes

@ -0,0 +1,5 @@
# textdomain: mcl_bone_meal
Bone Meal=Mączka kostna
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=Mączka kostna to biała farba i przydatny nawóz, który przyspiesza rośnięcie wielu roślin.
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=Kliknij prawym na owcę, aby wybielić jej wełnę. Kliknij prawym na roślinę aby przyspieszyć jej wzrost. Zważ, że nie na wszystkie rośliny to tak działa. Gdy klikniesz prawym na blok trawy, wysoka trawa wyrośnie wokół.
Speeds up plant growth=Przyspiesza wzrost roślin

@ -0,0 +1,5 @@
# textdomain: mcl_bone_meal
Bone Meal=Костная мука
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=Костная мука является белым красителем. Она также полезна в качестве удобрения, чтобы увеличить скорость роста многих растений.
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=Кликните правой по овце, чтобы сделать её шерсть белой. Кликните правой по растению, чтобы ускорить его рост. Имейте в виду, что не все растения можно удобрять таким способом. Если вы кликнете по травяному блоку, то на этом месте вырастет высокая трава и цветы.
Speeds up plant growth=Ускоряет рост растений

@ -0,0 +1,5 @@
# textdomain: mcl_bone_meal
Bone Meal=骨粉
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=骨粉是一種白色染料,也可作為肥料,加速許多植物的生長。
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=右鍵點擊一隻羊,使其羊毛變白。右鍵點擊一株植物以加快其生長速度。注意,不是所有的植物都能像這樣施肥。當你右鍵點擊一個草方時,高高的草和花會到處生長。
Speeds up plant growth=加速植物生長

@ -0,0 +1,5 @@
# textdomain: mcl_bone_meal
Bone Meal=
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=
Speeds up plant growth=

@ -0,0 +1,3 @@
name = mcl_bone_meal
description = Bone meal can be used as a fertilizer and as a dye.
author = kabou, teknomunk

Before

Width:  |  Height:  |  Size: 165 B

After

Width:  |  Height:  |  Size: 165 B

@ -2,29 +2,34 @@ local S = minetest.get_translator(minetest.get_current_modname())
mcl_cocoas = {}
-- Place cocoa
local function cocoa_place(itemstack, placer, pt, plantname)
--- 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 under = minetest.get_node(pt.under)
local node = minetest.get_node(pt.under)
-- return if any of the nodes are not registered
if not minetest.registered_nodes[under.name] then
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 minetest.registered_nodes[under.name] and minetest.registered_nodes[under.name].on_rightclick then
return minetest.registered_nodes[under.name].on_rightclick(pt.under, under, placer, itemstack) or itemstack
if def and def.on_rightclick then
local new_stack = mcl_util.call_on_rightclick(itemstack, placer, pt)
if new_stack and new_stack ~= itemstack then return new_stack end
end
end
-- Check if pointing at jungle tree
if under.name ~= "mcl_core:jungletree"
if node.name ~= "mcl_core:jungletree"
or minetest.get_node(pt.above).name ~= "air" then
return
end
@ -39,9 +44,7 @@ local function cocoa_place(itemstack, placer, pt, plantname)
-- 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
@ -49,111 +52,119 @@ local function cocoa_place(itemstack, placer, pt, plantname)
return itemstack
end
-- 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
--- 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})
return true
else
return false
end
return false
return true
end
-- Cocoa definition
-- 1st stage
local crop_def = {
description = S("Premature Cocoa Pod"),
_doc_items_create_entry = true,
_doc_items_longdesc = S("Cocoa pods grow on the side of jungle trees in 3 stages."),
drawtype = "mesh",
mesh = "mcl_cocoas_cocoa_stage_0.obj",
tiles = {"mcl_cocoas_cocoa_stage_0.png"},
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true,
paramtype = "light",
sunlight_propagates = true,
paramtype2 = "facedir",
walkable = true,
drop = "mcl_cocoas:cocoa_beans",
collision_box = {
type = "fixed",
fixed = {
{-0.125, -0.0625, 0.1875, 0.125, 0.25, 0.4375}, -- Pod
-- only caller was mcl_dye, consider converting these into 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 = {
"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 },
},
selection_box = {
type = "fixed",
fixed = {
{-0.125, -0.0625, 0.1875, 0.125, 0.5, 0.5}, -- Pod
{ desc = S("Medium Cocoa Pod"),
tiles = {
"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 },
},
groups = {
handy = 1, axey = 1,
dig_by_water=1, destroy_by_lava_flow=1, dig_by_piston=1,
attached_node_facedir=1,
not_in_creative_inventory=1,
cocoa=1
},
sounds = mcl_sounds.node_sound_wood_defaults(),
on_rotate = false,
_mcl_blast_resistance = 3,
_mcl_hardness = 0.2,
}
-- 2nd stage
minetest.register_node("mcl_cocoas:cocoa_1", table.copy(crop_def))
crop_def.description = S("Medium Cocoa Pod")
crop_def._doc_items_create_entry = false
crop_def.groups.cocoa = 2
crop_def.mesh = "mcl_cocoas_cocoa_stage_1.obj"
crop_def.tiles = {"mcl_cocoas_cocoa_stage_1.png"}
crop_def.collision_box = {
type = "fixed",
fixed = {
{-0.1875, -0.1875, 0.0625, 0.1875, 0.25, 0.4375}, -- Pod
},
}
crop_def.selection_box = {
type = "fixed",
fixed = {
{-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 = {
"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 },
},
}
minetest.register_node("mcl_cocoas:cocoa_2", table.copy(crop_def))
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,
_on_bone_meal = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
return cocoa_grow(pos)
end,
}
-- Final stage
crop_def.description = S("Mature Cocoa Pod")
crop_def._doc_items_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.")
crop_def._doc_items_create_entry = true
crop_def.groups.cocoa = 3
crop_def.mesh = "mcl_cocoas_cocoa_stage_2.obj"
crop_def.tiles = {"mcl_cocoas_cocoa_stage_2.png"}
crop_def.collision_box = {
type = "fixed",
fixed = {
{-0.25, -0.3125, -0.0625, 0.25, 0.25, 0.4375}, -- Pod
},
}
crop_def.selection_box = {
type = "fixed",
fixed = {
{-0.25, -0.3125, -0.0625, 0.25, 0.5, 0.5},
},
}
crop_def.drop = "mcl_cocoas:cocoa_beans 3"
minetest.register_node("mcl_cocoas:cocoa_3", table.copy(crop_def))
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._on_bone_mealing = nil
end
minetest.register_node("mcl_cocoas:cocoa_" .. i, table.copy(def))
end
minetest.register_craftitem("mcl_cocoas:cocoa_beans", {
description = S("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 craft brown dye."),
_doc_items_usagehelp = S("Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa."),
inventory_image = "mcl_cocoas_cocoa_beans.png",
groups = {craftitem = 1, compostability = 65},
_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 = {
craftitem = 1, compostability = 65,
},
on_place = function(itemstack, placer, pointed_thing)
return cocoa_place(itemstack, placer, pointed_thing, "mcl_cocoas:cocoa_1")
end,

@ -2,7 +2,7 @@
Cocoa Beans=Kakaobohnen
Grows at the side of jungle trees=Wächst an der Seite von Dschungelbäumen
Cocoa beans can be used to plant cocoa pods, bake chocolate cookies or craft brown dye.=Kakaobohnen können benutzt werden, um Kakao anzupflanzen, Kekse zu backen oder braune Farbstoffe herzustellen.
Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Rechtsklicken Sie an die Seite eines Dschungelbaumstamms (Dschungelholz), um eine junge Kakaoschote zu pflanzen.
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Rechtsklicken Sie auf ein Schaf, um die Wolle braun einzufärben. Rechtsklicken Sie an die Seite eines Dschungelbaumstamms (Dschungelholz), um eine junge Kakaoschote zu pflanzen.
Premature Cocoa Pod=Junge Kakaoschote
Cocoa pods grow on the side of jungle trees in 3 stages.=Kakaoschoten wachsen an der Seite von Dschungelbäumen in 3 Stufen.
Medium Cocoa Pod=Mittelgroße Kakaoschote

@ -2,7 +2,7 @@
Cocoa Beans=Granos de cacao
Grows at the side of jungle trees=Crece al lado de los árboles de la jungla
Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=Los granos de cacao se pueden usar para plantar cacao, hornear galletas o hacer tintes marrones.
Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Haga clic derecho en el costado del tronco de un árbol de la jungla para plantar un cacao joven.
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Haga clic derecho en una oveja para convertir su lana en marrón. Haga clic derecho en el costado del tronco de un árbol de la jungla para plantar un cacao joven.
Premature Cocoa Pod=Vaina de cacao prematura
Cocoa pods grow on the side of jungle trees in 3 stages.=Las vainas de cacao crecen al lado de los árboles de jungla en 3 etapas.
Medium Cocoa Pod=Vaina de cacao mediana

@ -2,7 +2,7 @@
Cocoa Beans=Fèves de Cacao
Grows at the side of jungle trees=Pousse à côté des arbres de la jungle
Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=Les fèves de cacao peuvent être utilisées pour planter du cacao, faire des biscuits ou fabriquer de la teinture brune.
Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Clic droit sur le côté d'un tronc d'arbre de la jungle (Bois Acajou) pour planter un jeune cacaoyer.
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Faites un clic droit sur un mouton pour brunir sa laine. Clic droit sur le côté d'un tronc d'arbre de la jungle (Bois Acajou) pour planter un jeune cacao.
Premature Cocoa Pod=Gousse de cacao prématurée
Cocoa pods grow on the side of jungle trees in 3 stages.=Les cabosses de cacao poussent sur le côté des arbres d'Acajou en 3 étapes.
Medium Cocoa Pod=Gousse de cacao moyenne

@ -2,7 +2,7 @@
Cocoa Beans=Ziarna kakaowe
Grows at the side of jungle trees=Rośnie na boku tropikalnych drzew
Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=Ziarna kakaowe mogą być używane do sadzenia kakao, pieczenia ciasteczek lub robienia brązowego barwnika.
Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Naciśnij prawym na boku tropikalnego pnia (Tropikalne drewno) aby zasadzić młode kakao.
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Naciśnij prawym aby zafarbować wełnę owcy na brązowo. Naciśnij prawym na boku tropikalnego pnia (Tropikalne drewno) aby zasadzić młode kakao.
Premature Cocoa Pod=Niedojrzała roślina kakao
Cocoa pods grow on the side of jungle trees in 3 stages.=Roślina kakao rośnie na bokach tropikalnych drzew w 3 etapach
Medium Cocoa Pod=Średnio-dojrzała roślina kakao

@ -2,7 +2,7 @@
Cocoa Beans=Какао-бобы
Grows at the side of jungle trees=Растут на стволах тропических деревьев
Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=Какао-бобы можно использовать для посадки какао, выпечки печенья или изготовления коричневого красителя.
Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Кликните правой по боковой части ствола тропического дерева, чтобы посадить молодое какао.
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Кликните правой по овце, чтобы сделать её шерсть коричневой. Кликните правой по боковой части ствола тропического дерева, чтобы посадить молодое какао.
Premature Cocoa Pod=Молодой стручок какао
Cocoa pods grow on the side of jungle trees in 3 stages.=Стручки какао растут на деревьях джунглей в 3 этапа.
Medium Cocoa Pod=Средний стручок какао

@ -2,7 +2,7 @@
Cocoa Beans=可可豆
Grows at the side of jungle trees=在叢林木側生長
Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=可可豆可用於種植可可、烘烤餅乾或製作棕色染料。
Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=右鍵點擊叢林木的一側,可以種植一個可可。
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=右鍵點擊一隻羊,使其羊毛變成褐色。右鍵點擊叢林木的一側,可以種植一個可可。
Premature Cocoa Pod=成長中的可可豆莢第1階段
Cocoa pods grow on the side of jungle trees in 3 stages.=可可莢果分3個階段生長在叢林樹的側面。
Medium Cocoa Pod=成長中的可可豆莢第2階段

@ -2,7 +2,7 @@
Cocoa Beans=
Grows at the side of jungle trees=
Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=
Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=
Premature Cocoa Pod=
Cocoa pods grow on the side of jungle trees in 3 stages.=
Medium Cocoa Pod=

@ -1,4 +1,4 @@
name = mcl_cocoas
description = Cocoa pods which grow at jungle trees. Does not include cocoa beans.
depends = mcl_sounds, mcl_core
optional_depends = doc
depends = mcl_sounds, mcl_core, mcl_util
optional_depends = doc

@ -11,7 +11,7 @@ local composter_description = S(
"Composter"
)
local composter_longdesc = S(
"Composters can convert various organic items into bonemeal."
"Composters can convert various organic items into bone meal."
)
local composter_usagehelp = S(
"Use organic items on the composter to fill it with layers of compost. " ..
@ -48,6 +48,41 @@ local vector_offset = vector.offset
local is_protected = minetest.is_protected
local record_protection_violation = minetest.record_protection_violation
--- Math and node swap during compost progression
---@param pos Vector Position of the node
---@param node node
---@param chance integer Value of "compostability" group of inserted item
local function composter_progress_chance(pos, node, chance)
-- calculate leveling up chance
local rand = math.random(0,100)
if chance >= rand then
-- get current compost level
local level = registered_nodes[node.name]["_mcl_compost_level"]
-- spawn green particles above new layer
mcl_bone_meal.add_bone_meal_particle(vector_offset(pos, 0, level/8, 0))
-- update composter block
if level < 7 then
level = level + 1
else
level = "ready"
end
swap_node(pos, {name = "mcl_composters:composter_" .. level})
minetest.sound_play({name="default_grass_footstep", gain=0.4}, {
pos = pos,
gain= 0.4,
max_hear_distance = 16,
}, true)
-- a full composter becomes ready for harvest after one second
-- the block will get updated by the node timer callback set in node reg def
if level == 7 then
local timer = get_node_timer(pos)
if not timer:is_started() then
timer:start(1)
end
end
end
end
--- Fill the composter when rightclicked.
--
-- `on_rightclick` handler for composter blocks of all fill levels except
@ -86,41 +121,6 @@ local function composter_add_item(pos, node, player, itemstack, pointed_thing)
return itemstack
end
--- Math and node swap during compost progression
---@param pos Vector Position of the node
---@param node node
---@param chance integer Value of "compostability" group of inserted item
function composter_progress_chance(pos, node, chance)
-- calculate leveling up chance
local rand = math.random(0,100)
if chance >= rand then
-- get current compost level
local level = registered_nodes[node.name]["_mcl_compost_level"]
-- spawn green particles above new layer
mcl_dye.add_bone_meal_particle(vector_offset(pos, 0, level/8, 0))
-- update composter block
if level < 7 then
level = level + 1
else
level = "ready"
end
swap_node(pos, {name = "mcl_composters:composter_" .. level})
minetest.sound_play({name="default_grass_footstep", gain=0.4}, {
pos = pos,
gain= 0.4,
max_hear_distance = 16,
}, true)
-- a full composter becomes ready for harvest after one second
-- the block will get updated by the node timer callback set in node reg def
if level == 7 then
local timer = get_node_timer(pos)
if not timer:is_started() then
timer:start(1)
end
end
end
end
--- Update a full composter block to ready for harvesting.
--
-- `on_timer` handler. The timer is set in function 'composter_add_item'
@ -203,7 +203,7 @@ end
--
minetest.register_node("mcl_composters:composter", {
description = composter_description,
_tt_help = S("Converts organic items into bonemeal"),
_tt_help = S("Converts organic items into bone meal"),
_doc_items_longdesc = composter_longdesc,
_doc_items_usagehelp = composter_usagehelp,
paramtype = "light",

@ -4,4 +4,4 @@ Composters can convert various organic items into bonemeal.=Les composteurs peuv
Use organic items on the composter to fill it with layers of compost. Every time an item is put in the composter, there is a chance that the composter adds another layer of compost. Some items have a bigger chance of adding an extra layer than other items. After filling up with 7 layers of compost, the composter is full. After a delay of approximately one second the composter becomes ready and bone meal can be retrieved from it. Right-clicking the composter takes out the bone meal empties the composter.=Utiliser des objets organiques sur le composteur pour le remplir de couches de compost. Chaque fois qu'un objet est mis dans le composteur, il y a une chance d'ajouter une nouvelle couche de compost au composteur. Certains objets ont une plus grande chance que d'autres d'ajouter une couche supplémentaire. Après l'avoir rempli de 7 couches de compost, le composteur est plein. Après un délai d'approximativement une seconde, le composteur est prêt et on peut récupérer la farine d'os. Cliquer droit le composteur permet de récupérer la farine d'os et de vider le composteur.
filled=rempli
ready for harvest=prêt pour la récolte
Converts organic items into bonemeal=Convertit les objets organiques en farine d'os.
Converts organic items into bone meal=Convertit les objets organiques en farine d'os.

@ -4,4 +4,4 @@ Composters can convert various organic items into bonemeal.=コンポスター
Use organic items on the composter to fill it with layers of compost. Every time an item is put in the composter, there is a chance that the composter adds another layer of compost. Some items have a bigger chance of adding an extra layer than other items. After filling up with 7 layers of compost, the composter is full. After a delay of approximately one second the composter becomes ready and bone meal can be retrieved from it. Right-clicking the composter takes out the bone meal empties the composter."=コンポスターに有機物を入れて、堆肥の層を作りましょう。コンポスターに有機物を入れるたびに、次の堆肥の層が追加されるチャンスが起きます。 追加される確率がより高くなっているアイテムもいくつかあります。 7層分の堆肥が充填されると、コンポスターは満杯となります。その約1秒後に、骨粉を取り出せる準備が完了します。右クリックして骨粉を取り出すと、コンポスターは空になります。
filled=充足
ready for harvest=収穫可能
Converts organic items into bonemeal=有機物を骨粉に変える
Converts organic items into bone meal=有機物を骨粉に変える

@ -4,4 +4,4 @@ Composters can convert various organic items into bonemeal.=Компостер
Use organic items on the composter to fill it with layers of compost. Every time an item is put in the composter, there is a chance that the composter adds another layer of compost. Some items have a bigger chance of adding an extra layer than other items. After filling up with 7 layers of compost, the composter is full. After a delay of approximately one second the composter becomes ready and bone meal can be retrieved from it. Right-clicking the composter takes out the bone meal empties the composter.=Используйте органические предметы на компостере, чтобы заполнить его слоями перегноя. Каждый раз когда в компостер попадает предмет, есть шанс что в компостере появится новый слой перегноя. Некоторые предметы имеют больший шанс на появление нового слоя. После заполнения 7 слоями перегноя, компостер можно опустошить, забрав из него костную муку. После задержки в одну секунду компостер будет готов и костная мука будет извлечена из него. Правым кликом по компостеру чтобы забрать костную муку.
filled=заполнен
ready for harvest=готов к сбору
Converts organic items into bonemeal=Перерабатывает органику в костную муку
Converts organic items into bone meal=Перерабатывает органику в костную муку

@ -1,7 +1,7 @@
# textdomain: mcl_composters
Composter=
Composters can convert various organic items into bonemeal.=
Use organic items on the composter to fill it with layers of compost. Every time an item is put in the composter, there is a chance that the composter adds another layer of compost. Some items have a bigger chance of adding an extra layer than other items. After filling up with 7 layers of compost, the composter is full. After a delay of approximately one second the composter becomes ready and bone meal can be retrieved from it. Right-clicking the composter takes out the bone meal empties the composter.=
Composters can convert various organic items into bone meal.=
Use organic items on the composter to fill it with layers of compost. Every time an item is put in the composter, there is a chance that the composter adds another layer of compost. Some items have a bigger chance of adding an extra layer than other items. After filling up with 7 layers of compost, the composter is full. After a delay of approximately one second the composter becomes ready and bone meal can be retrieved from it. Right-clicking the composter takes out the bone meal empties the composter.=
filled=
ready for harvest=
Converts organic items into bonemeal=
Converts organic items into bone meal=

@ -1,5 +1,5 @@
name = mcl_composters
author = kabou
description = Composters can convert various organic items into bonemeal.
depends = mcl_core, mcl_sounds, mcl_dye, mcl_hoppers
depends = mcl_core, mcl_sounds, mcl_bone_meal, mcl_hoppers
optional_depends = doc

@ -962,6 +962,7 @@ end
-- pos: Position
-- node: Node table of the node at this position, from minetest.get_node
-- Returns true on success and false on failure
-- TODO: replace this with a proper tree API
function mcl_core.grow_sapling(pos, node)
if node.name == "mcl_core:sapling" then
grow_oak(pos)
@ -975,6 +976,8 @@ function mcl_core.grow_sapling(pos, node)
grow_spruce(pos)
elseif node.name == "mcl_core:birchsapling" then
grow_birch(pos)
elseif node.name == "mcl_cherry_blossom:cherrysapling" then
return mcl_cherry_blossom.generate_cherry_tree(pos)
else
return false
end

@ -280,6 +280,14 @@ function mcl_core.register_sapling(subname, description, longdesc, tt_help, text
nn == "mcl_core:podzol" or nn == "mcl_core:podzol_snow" or
nn == "mcl_core:dirt" or nn == "mcl_core:mycelium" or nn == "mcl_core:coarse_dirt"
end),
_on_bone_meal = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
local n = minetest.get_node(pos)
-- Saplings: 45% chance to advance growth stage
if math.random(1,100) <= 45 then
return mcl_core.grow_sapling(pos, n)
end
end,
node_placement_prediction = "",
_mcl_blast_resistance = 0,
_mcl_hardness = 0,

@ -5,6 +5,8 @@ local modpath = minetest.get_modpath(modname)
-- by debiankaios
-- adapted for mcl2 by cora
local MAXIMUM_VINE_HEIGHT = 25
local wood_slab_groups = {handy = 1, axey = 1, material_wood = 1, wood_slab = 1}
local wood_stair_groups = {handy = 1, axey = 1, material_wood = 1, wood_stairs = 1}
@ -16,21 +18,36 @@ function generate_crimson_tree(pos)
minetest.place_schematic(pos,modpath.."/schematics/crimson_fungus_1.mts","random",nil,false,"place_center_x,place_center_z")
end
function grow_vines(pos, moreontop ,vine, dir)
function grow_vines(pos, moreontop, vine, dir)
-- Sanity checks
if dir == nil then dir = 1 end
local n
repeat
pos = vector.offset(pos,0,dir,0)
n = minetest.get_node(pos)
if n.name == "air" then
for i=0,math.max(moreontop,1) do
if minetest.get_node(pos).name == "air" then
minetest.set_node(vector.offset(pos,0,i*dir,0),{name=vine})
end
end
break
end
until n.name ~= "air" and n.name ~= vine
if not moreontop or moreontop < 1 then return false end
local allowed_nodes = {}
allowed_nodes[vine] = true
-- Find the root, tip and calculate height
local root,_,root_node = mcl_util.trace_nodes(pos, -dir, allowed_nodes, MAXIMUM_VINE_HEIGHT)
if not root then return false end
local tip,height,tip_node = mcl_util.trace_nodes(vector.offset(root, 0, dir, 0), dir, allowed_nodes, MAXIMUM_VINE_HEIGHT)
if not tip then return false end
local res = false
for i = 1,moreontop do
-- Check if we can grow into this position
if height >= MAXIMUM_VINE_HEIGHT then return res end
if tip_node.name ~= "air" then return res end
-- Update world map data
minetest.set_node(tip, {name = vine})
-- Move to the next position and flag that growth has occured
tip = vector.offset(tip, 0, dir, 0)
tip_node = minetest.get_node(tip)
height = height + 1
res = true
end
return res
end
local nether_plants = {
@ -83,17 +100,20 @@ minetest.register_node("mcl_crimson:warped_fungus", {
light_source = 1,
sounds = mcl_sounds.node_sound_leaves_defaults(),
node_placement_prediction = "",
on_rightclick = function(pos, node, pointed_thing, player, itemstack)
if pointed_thing:get_wielded_item():get_name() == "mcl_bone_meal:bone_meal" then
local nodepos = minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z})
if nodepos.name == "mcl_crimson:warped_nylium" or nodepos.name == "mcl_nether:netherrack" then
local random = math.random(1, 5)
if random == 1 then
minetest.remove_node(pos)
generate_warped_tree(pos)
end
_on_bone_meal = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
local nodepos = minetest.get_node(vector.offset(pos, 0, -1, 0))
if nodepos.name == "mcl_crimson:warped_nylium" or nodepos.name == "mcl_nether:netherrack" then
local random = math.random(1, 5)
if random == 1 then
minetest.remove_node(pos)
generate_warped_tree(pos)
return true
end
end
return false
end,
_mcl_blast_resistance = 0,
})
@ -102,6 +122,12 @@ mcl_flowerpots.register_potted_flower("mcl_crimson:warped_fungus", {
name = "warped_fungus",
desc = S("Warped Fungus"),
image = "mcl_crimson_warped_fungus.png",
_on_bone_meal = function(itemstack, placer, pointed_thing)
local n = has_nylium_neighbor(pointed_thing.under)
if n then
minetest.set_node(pointed_thing.under,n)
end
end,
})
minetest.register_node("mcl_crimson:twisting_vines", {
@ -121,6 +147,9 @@ minetest.register_node("mcl_crimson:twisting_vines", {
fixed = { -3/16, -0.5, -3/16, 3/16, 0.5, 3/16 },
},
node_placement_prediction = "",
_on_bone_meal = function(itemstack, placer, pointed_thing)
return grow_vines(pointed_thing.under, math.random(1, 3),"mcl_crimson:twisting_vines")
end,
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local pn = clicker:get_player_name()
if clicker:is_player() and minetest.is_protected(vector.offset(pos,0,1,0), pn or "") then
@ -141,26 +170,28 @@ minetest.register_node("mcl_crimson:twisting_vines", {
end
elseif clicker:get_wielded_item():get_name() == "mcl_bone_meal:bone_meal" then
if not minetest.is_creative_enabled(clicker:get_player_name()) then
itemstack:take_item()
end
grow_vines(pos, math.random(1, 3),"mcl_crimson:twisting_vines")
return mcl_bone_meal.use_bone_meal(itemstack, clicker, {under=pos, above=pos})
end
return itemstack
end,
on_place = function(itemstack, placer, pointed_thing)
local under = pointed_thing.under
local above = pointed_thing.above
local unode = minetest.get_node(under)
local unode_def = minetest.registered_nodes[unode.name]
local above = pointed_thing.above
local anode = minetest.get_node(above)
local anode_def = minetest.registered_nodes[anode.name]
if under.y < above.y then
minetest.set_node(above, {name = "mcl_crimson:twisting_vines"})
if not minetest.is_creative_enabled(placer:get_player_name()) then
itemstack:take_item()
end
else
if unode.name == "mcl_crimson:twisting_vines" then
return minetest.registered_nodes[unode.name].on_rightclick(under, unode, placer, itemstack, pointed_thing)
end
elseif unode_def and unode_def.on_rightclick then
return unode_def.on_rightclick(under, unode, placer, itemstack, pointed_thing)
elseif anode_def and anode_def.on_rightclick then
return unode_def.on_rightclick(above, anode, placer, itemstack, pointed_thing)
end
return itemstack
end,
@ -168,7 +199,7 @@ minetest.register_node("mcl_crimson:twisting_vines", {
local above = vector.offset(pos,0,1,0)
local abovenode = minetest.get_node(above)
minetest.node_dig(pos, node, digger)
if abovenode.name == node.name and (not mcl_core.check_vines_supported(above, abovenode)) then
if abovenode.name == node.name then
minetest.registered_nodes[node.name].on_dig(above, node, digger)
end
end,
@ -211,6 +242,9 @@ minetest.register_node("mcl_crimson:weeping_vines", {
fixed = { -3/16, -0.5, -3/16, 3/16, 0.5, 3/16 },
},
node_placement_prediction = "",
_on_bone_meal = function(itemstack, placer, pointed_thing)
return grow_vines(pointed_thing.under, math.random(1, 3),"mcl_crimson:weeping_vines", -1)
end,
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local pn = clicker:get_player_name()
if clicker:is_player() and minetest.is_protected(vector.offset(pos,0,1,0), pn or "") then
@ -231,26 +265,28 @@ minetest.register_node("mcl_crimson:weeping_vines", {
end
elseif clicker:get_wielded_item():get_name() == "mcl_bone_meal:bone_meal" then
if not minetest.is_creative_enabled(clicker:get_player_name()) then
itemstack:take_item()
end
grow_vines(pos, math.random(1, 3),"mcl_crimson:weeping_vines", -1)
return mcl_bone_meal.use_bone_meal(itemstack, clicker, {under=pos, above=pos})
end
return itemstack
end,
on_place = function(itemstack, placer, pointed_thing)
local under = pointed_thing.under
local above = pointed_thing.above
local unode = minetest.get_node(under)
local unode_def = minetest.registered_nodes[unode.name]
local above = pointed_thing.above
local anode = minetest.get_node(above)
local anode_def = minetest.registered_nodes[anode.name]
if under.y > above.y then
minetest.set_node(above, {name = "mcl_crimson:weeping_vines"})
if not minetest.is_creative_enabled(placer:get_player_name()) then
itemstack:take_item()
end
else
if unode.name == "mcl_crimson:weeping_vines" then
return minetest.registered_nodes[unode.name].on_rightclick(under, unode, placer, itemstack, pointed_thing)
end
elseif unode_def and unode_def.on_rightclick then
return unode_def.on_rightclick(under, unode, placer, itemstack, pointed_thing)
elseif anode_def and anode_def.on_rightclick then
return unode_def.on_rightclick(above, anode, placer, itemstack, pointed_thing)
end
return itemstack
end,
@ -258,7 +294,7 @@ minetest.register_node("mcl_crimson:weeping_vines", {
local below = vector.offset(pos,0,-1,0)
local belownode = minetest.get_node(below)
minetest.node_dig(pos, node, digger)
if belownode.name == node.name and (not mcl_core.check_vines_supported(below, belownode)) then
if belownode.name == node.name then
minetest.registered_nodes[node.name].on_dig(below, node, digger)
end
end,
@ -393,6 +429,11 @@ minetest.register_node("mcl_crimson:warped_nylium", {
_mcl_hardness = 0.4,
_mcl_blast_resistance = 0.4,
_mcl_silk_touch_drop = true,
_on_bone_meal = function(itemstack, placer, pointed_thing)
local node = minetest.get_node(pointed_thing.under)
spread_nether_plants(pointed_thing.under,node)
return true
end,
})
--Stem bark, stripped stem and bark
@ -525,17 +566,21 @@ minetest.register_node("mcl_crimson:crimson_fungus", {
fixed = { -3/16, -0.5, -3/16, 3/16, -2/16, 3/16 },
},
node_placement_prediction = "",
on_rightclick = function(pos, node, pointed_thing, player)
if pointed_thing:get_wielded_item():get_name() == "mcl_bone_meal:bone_meal" then
local nodepos = minetest.get_node(vector.offset(pos, 0, -1, 0))
if nodepos.name == "mcl_crimson:crimson_nylium" or nodepos.name == "mcl_nether:netherrack" then
local random = math.random(1, 5)
if random == 1 then
minetest.remove_node(pos)
generate_crimson_tree(pos)
end
_on_bone_meal = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
local nodepos = minetest.get_node(vector.offset(pos, 0, -1, 0))
if nodepos.name == "mcl_crimson:crimson_nylium" or nodepos.name == "mcl_nether:netherrack" then
local random = math.random(1, 5)
if random == 1 then
minetest.remove_node(pos)
generate_crimson_tree(pos)
return true
end
end
-- Failed to spread nylium
return false
end,
_mcl_blast_resistance = 0,
})
@ -682,6 +727,11 @@ minetest.register_node("mcl_crimson:crimson_nylium", {
_mcl_hardness = 0.4,
_mcl_blast_resistance = 0.4,
_mcl_silk_touch_drop = true,
_on_bone_meal = function(itemstack, placer, pointed_thing)
local node = minetest.get_node(pointed_thing.under)
spread_nether_plants(pointed_thing.under,node)
return true
end,
})
minetest.register_craft({
@ -723,19 +773,6 @@ minetest.register_craft({
mcl_stairs.register_stair("crimson_hyphae_wood", "mcl_crimson:crimson_hyphae_wood", wood_stair_groups, false, S("Crimson Stair"))
mcl_stairs.register_slab("crimson_hyphae_wood", "mcl_crimson:crimson_hyphae_wood", wood_slab_groups, false, S("Crimson Slab"))
mcl_dye.register_on_bone_meal_apply(function(pt,user)
if not pt.type == "node" then return end
local node = minetest.get_node(pt.under)
if node.name == "mcl_nether:netherrack" then
local n = has_nylium_neighbor(pt.under)
if n then
minetest.set_node(pt.under,n)
end
elseif node.name == "mcl_crimson:warped_nylium" or node.name == "mcl_crimson:crimson_nylium" then
spread_nether_plants(pt.under,node)
end
end)
minetest.register_abm({
label = "Turn Crimson Nylium and Warped Nylium below solid block into Netherrack",
nodenames = {"mcl_crimson:crimson_nylium","mcl_crimson:warped_nylium"},

@ -1,14 +0,0 @@
# mcl_dye
# Bone meal API
Callback and particle functions.
## mcl_dye.add_bone_meal_particle(pos, def)
Spawns standard or custom bone meal particles.
* `pos`: position, is ignored if you define def.minpos and def.maxpos
* `def`: (optional) particle definition
## mcl_dye.register_on_bone_meal_apply(function(pointed_thing, user))
Called when the bone meal is applied anywhere.
* `pointed_thing`: exact pointing location (see Minetest API), where the bone meal is applied
* `user`: ObjectRef of the player who aplied the bone meal, can be nil!

@ -15,7 +15,6 @@ mcl_dye = {}
local S = minetest.get_translator(minetest.get_current_modname())
local math = math
local string = string
-- Base color groups:
@ -115,328 +114,23 @@ for _, row in pairs(dyes) do
})
end
-- Bone meal code to be moved into its own mod.
-- Legacy support for things now in mcl_bone_meal.
-- These shims will at some time in the future be removed.
--
function mcl_dye.add_bone_meal_particle(pos, def)
if not def then
def = {}
minetest.log("warning", "mcl_dye.add_bone_meal_particles() is deprecated. Read mcl_bone_meal/API.md!")
local lines = string.split(debug.traceback(),"\n")
for _,line in ipairs(lines) do
minetest.log("warning",line)
end
minetest.add_particlespawner({
amount = def.amount or 10,
time = def.time or 0.1,
minpos = def.minpos or vector.subtract(pos, 0.5),
maxpos = def.maxpos or vector.add(pos, 0.5),
minvel = def.minvel or vector.new(-0.01, 0.01, -0.01),
maxvel = def.maxvel or vector.new(0.01, 0.01, 0.01),
minacc = def.minacc or vector.new(0, 0, 0),
maxacc = def.maxacc or vector.new(0, 0, 0),
minexptime = def.minexptime or 1,
maxexptime = def.maxexptime or 4,
minsize = def.minsize or 0.7,
maxsize = def.maxsize or 2.4,
texture = "mcl_particles_bonemeal.png^[colorize:#00EE00:125", -- TODO: real MC color
glow = def.glow or 1,
})
mcl_bone_meal.add_bone_meal_particle(pos, def)
end
mcl_dye.bone_meal_callbacks = {}
function mcl_dye.register_on_bone_meal_apply(func)
table.insert(mcl_dye.bone_meal_callbacks, func)
minetest.log("warning", "mcl_dye.register_on_bone_meal_apply() is deprecated. Read mcl_bone_meal/API.md!")
mcl_bone_meal.register_on_bone_meal_apply(func)
end
local function apply_bone_meal(pointed_thing, user)
-- Bone meal currently spawns all flowers found in the plains.
local flowers_table_plains = {
"mcl_flowers:dandelion",
"mcl_flowers:dandelion",
"mcl_flowers:poppy",
"mcl_flowers:oxeye_daisy",
"mcl_flowers:tulip_orange",
"mcl_flowers:tulip_red",
"mcl_flowers:tulip_white",
"mcl_flowers:tulip_pink",
"mcl_flowers:azure_bluet",
}
local flowers_table_simple = {
"mcl_flowers:dandelion",
"mcl_flowers:poppy",
}
local flowers_table_swampland = {
"mcl_flowers:blue_orchid",
}
local flowers_table_flower_forest = {
"mcl_flowers:dandelion",
"mcl_flowers:poppy",
"mcl_flowers:oxeye_daisy",
"mcl_flowers:tulip_orange",
"mcl_flowers:tulip_red",
"mcl_flowers:tulip_white",
"mcl_flowers:tulip_pink",
"mcl_flowers:azure_bluet",
"mcl_flowers:allium",
}
local pos = pointed_thing.under
local n = minetest.get_node(pos)
if n.name == "" then return false end
if mcl_util.check_area_protection(pos, pointed_thing.above, user) then
return false
end
for _, func in pairs(mcl_dye.bone_meal_callbacks) do
if func(pointed_thing, user) then
return true
end
end
if minetest.get_item_group(n.name, "sapling") >= 1 then
mcl_dye.add_bone_meal_particle(pos)
-- Saplings: 45% chance to advance growth stage
if math.random(1, 100) <= 45 then
if n.name == "mcl_cherry_blossom:cherrysapling" then
return mcl_cherry_blossom.generate_cherry_tree(pos) -- If cherry blossom sapling, run that callback instead.
else
return mcl_core.grow_sapling(pos, n)
end
end
elseif minetest.get_item_group(n.name, "mushroom") == 1 then
mcl_dye.add_bone_meal_particle(pos)
-- Try to grow huge mushroom
-- Must be on a dirt-type block
local below = minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z})
if below.name ~= "mcl_core:mycelium" and below.name ~= "mcl_core:dirt" and minetest.get_item_group(below.name, "grass_block") ~= 1 and below.name ~= "mcl_core:coarse_dirt" and below.name ~= "mcl_core:podzol" then
return false
end
-- Select schematic
local schematic, offset, height
if n.name == "mcl_mushrooms:mushroom_brown" then
schematic = minetest.get_modpath("mcl_mushrooms").."/schematics/mcl_mushrooms_huge_brown.mts"
offset = { x = -3, y = -1, z = -3 }
height = 8
elseif n.name == "mcl_mushrooms:mushroom_red" then
schematic = minetest.get_modpath("mcl_mushrooms").."/schematics/mcl_mushrooms_huge_red.mts"
offset = { x = -2, y = -1, z = -2 }
height = 8
else
return false
end
-- 40% chance
if math.random(1, 100) <= 40 then
-- Check space requirements
for i=1,3 do
local cpos = vector.add(pos, {x=0, y=i, z=0})
if minetest.get_node(cpos).name ~= "air" then
return false
end
end
local yoff = 3
local minp, maxp = {x=pos.x-3, y=pos.y+yoff, z=pos.z-3}, {x=pos.x+3, y=pos.y+yoff+(height-3), z=pos.z+3}
local diff = vector.subtract(maxp, minp)
diff = vector.add(diff, {x=1,y=1,z=1})
local totalnodes = diff.x * diff.y * diff.z
local goodnodes = minetest.find_nodes_in_area(minp, maxp, {"air", "group:leaves"})
if #goodnodes < totalnodes then
return false
end
-- Place the huge mushroom
minetest.remove_node(pos)
local place_pos = vector.add(pos, offset)
local ok = minetest.place_schematic(place_pos, schematic, 0, nil, false)
return ok ~= nil
end
return false
-- Wheat, Potato, Carrot, Pumpkin Stem, Melon Stem: Advance by 2-5 stages
elseif string.find(n.name, "mcl_farming:wheat_") then
mcl_dye.add_bone_meal_particle(pos)
local stages = math.random(2, 5)
return mcl_farming:grow_plant("plant_wheat", pos, n, stages, true)
elseif string.find(n.name, "mcl_farming:potato_") then
mcl_dye.add_bone_meal_particle(pos)
local stages = math.random(2, 5)
return mcl_farming:grow_plant("plant_potato", pos, n, stages, true)
elseif string.find(n.name, "mcl_farming:carrot_") then
mcl_dye.add_bone_meal_particle(pos)
local stages = math.random(2, 5)
return mcl_farming:grow_plant("plant_carrot", pos, n, stages, true)
elseif string.find(n.name, "mcl_farming:pumpkin_") then
mcl_dye.add_bone_meal_particle(pos)
local stages = math.random(2, 5)
return mcl_farming:grow_plant("plant_pumpkin_stem", pos, n, stages, true)
elseif string.find(n.name, "mcl_farming:melontige_") then
mcl_dye.add_bone_meal_particle(pos)
local stages = math.random(2, 5)
return mcl_farming:grow_plant("plant_melon_stem", pos, n, stages, true)
elseif string.find(n.name, "mcl_farming:beetroot_") then
mcl_dye.add_bone_meal_particle(pos)
-- Beetroot: 75% chance to advance to next stage
if math.random(1, 100) <= 75 then
return mcl_farming:grow_plant("plant_beetroot", pos, n, 1, true)
end
elseif 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, 1, true)
end
elseif n.name == "mcl_cocoas:cocoa_1" or n.name == "mcl_cocoas:cocoa_2" then
mcl_dye.add_bone_meal_particle(pos)
-- Cocoa: Advance by 1 stage
mcl_cocoas.grow(pos)
return true
elseif minetest.get_item_group(n.name, "grass_block") == 1 then
-- Grass Block: Generate tall grass and random flowers all over the place
for i = -7, 7 do
for j = -7, 7 do
for y = -1, 1 do
pos = vector.offset(pointed_thing.above, i, y, j)
n = minetest.get_node(pos)
local n2 = minetest.get_node(vector.offset(pos, 0, -1, 0))
if n.name ~= "" and n.name == "air" and (minetest.get_item_group(n2.name, "grass_block_no_snow") == 1) then
-- Randomly generate flowers, tall grass or nothing
if math.random(1, 100) <= 90 / ((math.abs(i) + math.abs(j)) / 2)then
-- 90% tall grass, 10% flower
mcl_dye.add_bone_meal_particle(pos, {amount = 4})
if math.random(1,100) <= 90 then
local col = n2.param2
minetest.add_node(pos, {name="mcl_flowers:tallgrass", param2=col})
else
local flowers_table
if mg_name == "v6" then
flowers_table = flowers_table_plains
else
local biome = minetest.get_biome_name(minetest.get_biome_data(pos).biome)
if biome == "Swampland" or biome == "Swampland_shore" or biome == "Swampland_ocean" or biome == "Swampland_deep_ocean" or biome == "Swampland_underground" then
flowers_table = flowers_table_swampland
elseif biome == "FlowerForest" or biome == "FlowerForest_beach" or biome == "FlowerForest_ocean" or biome == "FlowerForest_deep_ocean" or biome == "FlowerForest_underground" then
flowers_table = flowers_table_flower_forest
elseif biome == "Plains" or biome == "Plains_beach" or biome == "Plains_ocean" or biome == "Plains_deep_ocean" or biome == "Plains_underground" or biome == "SunflowerPlains" or biome == "SunflowerPlains_ocean" or biome == "SunflowerPlains_deep_ocean" or biome == "SunflowerPlains_underground" then
flowers_table = flowers_table_plains
else
flowers_table = flowers_table_simple
end
end
minetest.add_node(pos, {name=flowers_table[math.random(1, #flowers_table)]})
end
end
end
end
end
end
return true
-- Double flowers: Drop corresponding item
elseif n.name == "mcl_flowers:rose_bush" or n.name == "mcl_flowers:rose_bush_top" then
mcl_dye.add_bone_meal_particle(pos)
minetest.add_item(pos, "mcl_flowers:rose_bush")
return true
elseif n.name == "mcl_flowers:peony" or n.name == "mcl_flowers:peony_top" then
mcl_dye.add_bone_meal_particle(pos)
minetest.add_item(pos, "mcl_flowers:peony")
return true
elseif n.name == "mcl_flowers:lilac" or n.name == "mcl_flowers:lilac_top" then
mcl_dye.add_bone_meal_particle(pos)
minetest.add_item(pos, "mcl_flowers:lilac")
return true
elseif n.name == "mcl_flowers:sunflower" or n.name == "mcl_flowers:sunflower_top" then
mcl_dye.add_bone_meal_particle(pos)
minetest.add_item(pos, "mcl_flowers:sunflower")
return true
elseif n.name == "mcl_flowers:tallgrass" then
mcl_dye.add_bone_meal_particle(pos)
-- Tall Grass: Grow into double tallgrass
local toppos = { x=pos.x, y=pos.y+1, z=pos.z }
local topnode = minetest.get_node(toppos)
if minetest.registered_nodes[topnode.name].buildable_to then
minetest.set_node(pos, { name = "mcl_flowers:double_grass", param2 = n.param2 })
minetest.set_node(toppos, { name = "mcl_flowers:double_grass_top", param2 = n.param2 })
return true
end
--[[
Here for when Bonemeal becomes an api, there's code if needed for handling applying to bamboo.
-- Handle applying bonemeal to bamboo.
elseif mcl_bamboo.is_bamboo(n.name) then
local success = mcl_bamboo.grow_bamboo(pos, true)
if success then
mcl_dye.add_bone_meal_particle(pos)
end
return success
--]]
elseif n.name == "mcl_flowers:fern" then
mcl_dye.add_bone_meal_particle(pos)
-- Fern: Grow into large fern
local toppos = { x=pos.x, y=pos.y+1, z=pos.z }
local topnode = minetest.get_node(toppos)
if minetest.registered_nodes[topnode.name].buildable_to then
minetest.set_node(pos, { name = "mcl_flowers:double_fern", param2 = n.param2 })
minetest.set_node(toppos, { name = "mcl_flowers:double_fern_top", param2 = n.param2 })
return true
end
end
return false
end
mcl_dye.apply_bone_meal = apply_bone_meal
-- Bone meal item registration.
--
-- To be moved into its own mod.
--
minetest.register_craftitem(":mcl_bone_meal:bone_meal", {
inventory_image = "mcl_bone_meal_bone_meal.png",
description = S("Bone Meal"),
_tt_help = S("Speeds up plant growth"),
_doc_items_longdesc = S("Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants."),
_doc_items_usagehelp = S("Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place."),
stack_max = 64,
on_place = function(itemstack, user, pointed_thing)
-- Use pointed node's on_rightclick function first, if present
local node = minetest.get_node(pointed_thing.under)
if user and not user:get_player_control().sneak then
if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then
return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack
end
end
-- Use the bone meal on the ground
if (apply_bone_meal(pointed_thing, user) and (not minetest.is_creative_enabled(user:get_player_name()))) then
itemstack:take_item()
end
return itemstack
end,
_on_dispense = function(stack, pos, droppos, dropnode, dropdir)
-- Apply bone meal, if possible
local pointed_thing
if dropnode.name == "air" then
pointed_thing = { above = droppos, under = { x=droppos.x, y=droppos.y-1, z=droppos.z } }
else
pointed_thing = { above = pos, under = droppos }
end
local success = apply_bone_meal(pointed_thing, nil)
if success then
stack:take_item()
end
return stack
end,
_dispense_into_walkable = true
})
minetest.register_craft({
output = "mcl_bone_meal:bone_meal 3",
recipe = {{"mcl_mobitems:bone"}},
})
-- Dye creation recipes.
--
minetest.register_craft({
@ -609,19 +303,16 @@ minetest.register_craft({
output = "mcl_dye:magenta 2",
recipe = {"mcl_dye:violet", "mcl_dye:pink"},
})
minetest.register_craft({
type = "shapeless",
output = "mcl_dye:pink 2",
recipe = {"mcl_dye:red", "mcl_dye:white"},
})
minetest.register_craft({
type = "shapeless",
output = "mcl_dye:cyan 2",
recipe = {"mcl_dye:blue", "mcl_dye:dark_green"},
})
minetest.register_craft({
type = "shapeless",
output = "mcl_dye:violet 2",

@ -17,11 +17,3 @@ Magenta Dye=Magenta Farbstoff
Pink Dye=Rosa Farbstoff
This item is a dye which is used for dyeing and crafting.=Dieser Gegenstand ist ein Farbstoff, der zum Einfärben und in der Herstellung benutzt werden kann.
Rightclick on a sheep to dye its wool. Other things are dyed by crafting.=Rechtsklicken Sie auf ein Schaf, um seine Wolle zu färben. Andere Dinge werden mit der Fertigung eingefärbt.
Bone Meal=Knochenmehl
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=Knochenmehl ist ein weißer Farbstoff und auch nützlich als Dünger, um das Wachstum vieler Pflanzen zu beschleunigen.
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=Rechtsklicken Sie auf ein Schaf, um die Wolle weiß einzufärben. Rechtsklicken Sie auf eine Pflanze, um ihr Wachstum zu beschleunigen. Beachten Sie, dass nicht alle Pflanzen darauf ansprechen. Benutzen Sie es auf einem Grasblock, wächst viel hohes Gras und vielleicht auch ein paar Blumen.
Cocoa beans are a brown dye and can be used to plant cocoas.=Kakaobohnen sind ein brauner Farbstoff und werden benutzt, um Kakao anzupflanzen.
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Rechtsklicken Sie auf ein Schaf, um die Wolle braun einzufärben. Rechtsklicken Sie an die Seite eines Dschungelbaumstamms (Dschungelholz), um eine junge Kakaoschote zu pflanzen.
Cocoa Beans=Kakaobohnen
Grows at the side of jungle trees=Wächst an der Seite von Dschungelbäumen
Speeds up plant growth=Beschleunigt Pflanzenwachstum

@ -17,9 +17,3 @@ Magenta Dye=Tinte magenta
Pink Dye=Tinte rosado
This item is a dye which is used for dyeing and crafting.=Este artículo es un tinte que se utiliza para teñir y elaborar.
Rightclick on a sheep to dye its wool. Other things are dyed by crafting.=Haga clic derecho sobre una oveja para teñir su lana. Otras cosas pueden ser teñidas mediante la elaboración.
Bone Meal=Harina de hueso
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=La harina de hueso es un tinte blanco y también es útil como fertilizante para acelerar el crecimiento de muchas plantas.
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=RHaga clic derecho en una oveja para volver su lana blanca. Haga clic derecho en una planta para acelerar su crecimiento. Tenga en cuenta que no todas las plantas pueden ser fertilizadas de esta manera. Cuando haces clic derecho en un bloque de hierba, crecerán hierba alta y flores por todo el lugar.
Cocoa beans are a brown dye and can be used to plant cocoas.=Los granos de cacao son un tinte marrón y se pueden usar para plantar cacao.
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Haga clic derecho en una oveja para convertir su lana en marrón. Haga clic derecho en el costado del tronco de un árbol de jungla para plantar un cacao joven.
Cocoa Beans=Granos de cacao

@ -17,11 +17,3 @@ Magenta Dye=Teinture Magenta
Pink Dye=Teinture Rose
This item is a dye which is used for dyeing and crafting.=Cet objet est un colorant utilisé pour la teinture et l'artisanat.
Rightclick on a sheep to dye its wool. Other things are dyed by crafting.=Clic droit sur un mouton pour teindre sa laine. D'autres choses sont teintes par l'artisanat.
Bone Meal=Farine d'Os
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=La farine d'os est une teinture blanche et également utile comme engrais pour accélérer la croissance de nombreuses plantes.
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=Cliquez avec le bouton droit sur un mouton pour blanchir sa laine. Cliquez avec le bouton droit sur une plante pour accélérer sa croissance. Notez que toutes les plantes ne peuvent pas être fertilisées comme ça. Lorsque vous cliquez avec le bouton droit sur un bloc d'herbe, les hautes herbes et les fleurs poussent partout.
Cocoa beans are a brown dye and can be used to plant cocoas.=Les fèves de cacao ont une teinture brune et peuvent être utilisées pour planter du cacao.
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Faites un clic droit sur un mouton pour brunir sa laine. Clic droit sur le côté d'un tronc d'arbre de la jungle (Bois Acajou) pour planter un jeune cacao.
Cocoa Beans=Fèves de Cacao
Grows at the side of jungle trees=Pousse à côté des arbres de la jungle
Speeds up plant growth=Accélère la croissance des plantes

@ -17,11 +17,3 @@ Magenta Dye=Karmazynowa farba
Pink Dye=Różowa farba
This item is a dye which is used for dyeing and crafting.=Ten przedmiot to farba wykorzystywana to farbowania i wytwarzania.
Rightclick on a sheep to dye its wool. Other things are dyed by crafting.=Kliknij prawym na owcę aby zafarbować jej wełnę. Inne rzeczy mogą być zafarbowane przy wytwarzaniu.
Bone Meal=Mączka kostna
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=Mączka kostna to biała farba i przydatny nawóz, który przyspiesza rośnięcie wielu roślin.
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=Kliknij prawym na owcę, aby wybielić jej wełnę. Kliknij prawym na roślinę aby przyspieszyć jej wzrost. Zważ, że nie na wszystkie rośliny to tak działa. Gdy klikniesz prawym na blok trawy, wysoka trawa wyrośnie wokół.
Cocoa beans are a brown dye and can be used to plant cocoas.=Ziarna kakaowe mogą być wykorzystane do sadzenia kakao.
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Naciśnij prawym aby zafarbować wełnę owcy na brązowo. Naciśnij prawym na boku tropikalnego pnia (Tropikalne drewno) aby zasadzić młode kakao.
Cocoa Beans=Ziarna kakaowe
Grows at the side of jungle trees=Rośnie na boku tropikalnych drzew
Speeds up plant growth=Przyspiesza wzrost roślin

@ -22,6 +22,3 @@ Bone meal is a white dye and also useful as a fertilizer to speed up the growth
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=Кликните правой по овце, чтобы сделать её шерсть белой. Кликните правой по растению, чтобы ускорить его рост. Имейте в виду, что не все растения можно удобрять таким способом. Если вы кликнете по травяному блоку, то на этом месте вырастет высокая трава и цветы.
Cocoa beans are a brown dye and can be used to plant cocoas.=Какао-бобы являются коричневым красителем. Их также можно использовать, чтобы посадить какао.
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Кликните правой по овце, чтобы сделать её шерсть коричневой. Кликните правой по боковой части ствола тропического дерева, чтобы посадить молодое какао.
Cocoa Beans=Какао-бобы
Grows at the side of jungle trees=Растут на стволах тропических деревьев
Speeds up plant growth=Ускоряет рост растений

@ -17,9 +17,3 @@ Magenta Dye=洋紅色染料
Pink Dye=粉紅色染料
This item is a dye which is used for dyeing and crafting.=這個物品是一種用於染色和合成的染料。
Rightclick on a sheep to dye its wool. Other things are dyed by crafting.=右鍵單擊綿羊以染它的毛。其他東西是通過合成染色的。
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=骨粉是一種白色染料,也可作為肥料,加速許多植物的生長。
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=右鍵點擊一隻羊,使其羊毛變白。右鍵點擊一株植物以加快其生長速度。注意,不是所有的植物都能像這樣施肥。當你右鍵點擊一個草方時,高高的草和花會到處生長。
Cocoa beans are a brown dye and can be used to plant cocoas.=可可豆是一種棕色染料,也可用於種植可可。
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=右鍵點擊一隻羊,使其羊毛變成褐色。右鍵點擊叢林木的一側,可以種植一個可可。
Grows at the side of jungle trees=在叢林木側生長
Speeds up plant growth=加速植物生長

@ -17,11 +17,3 @@ Magenta Dye=
Pink Dye=
This item is a dye which is used for dyeing and crafting.=
Rightclick on a sheep to dye its wool. Other things are dyed by crafting.=
Bone Meal=
Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=
Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=
Cocoa beans are a brown dye and can be used to plant cocoas.=
Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=
Cocoa Beans=
Grows at the side of jungle trees=
Speeds up plant growth=

@ -1,2 +1,3 @@
name = mcl_dye
depends = mcl_core, mcl_flowers, mcl_mobitems, mcl_cocoas
description = Adds color to your world!
depends = mcl_bone_meal, mcl_cocoas

@ -13,78 +13,44 @@ minetest.register_craftitem("mcl_farming:beetroot_seeds", {
end
})
minetest.register_node("mcl_farming:beetroot_0", {
description = S("Premature Beetroot Plant (Stage 1)"),
_doc_items_longdesc = S("Beetroot plants are plants which grow on farmland under sunlight in 4 stages. On hydrated farmland, they grow a bit faster. They can be harvested at any time but will only yield a profit when mature."),
_doc_items_entry_name = S("Premature Beetroot Plant"),
paramtype = "light",
paramtype2 = "meshoptions",
sunlight_propagates = true,
place_param2 = 3,
walkable = false,
drawtype = "plantlike",
drop = "mcl_farming:beetroot_seeds",
tiles = {"mcl_farming_beetroot_0.png"},
inventory_image = "mcl_farming_beetroot_0.png",
wield_image = "mcl_farming_beetroot_0.png",
selection_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}
},
},
groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1},
sounds = mcl_sounds.node_sound_leaves_defaults(),
_mcl_blast_resistance = 0,
})
local size = {[0]=-5, -4, -3}
minetest.register_node("mcl_farming:beetroot_1", {
description = S("Premature Beetroot Plant (Stage 2)"),
_doc_items_create_entry = false,
paramtype = "light",
paramtype2 = "meshoptions",
sunlight_propagates = true,
place_param2 = 3,
walkable = false,
drawtype = "plantlike",
drop = "mcl_farming:beetroot_seeds",
tiles = {"mcl_farming_beetroot_1.png"},
inventory_image = "mcl_farming_beetroot_1.png",
wield_image = "mcl_farming_beetroot_1.png",
selection_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, -4/16, 0.5}
for i = 0, 2 do
minetest.register_node("mcl_farming:beetroot_".. i, {
description = S("Premature Beetroot Plant (Stage ".. i + 1 ..")"),
_doc_items_longdesc = S("Beetroot plants are plants which grow on farmland under sunlight in 4 stages. On hydrated farmland, they grow a bit faster. They can be harvested at any time but will only yield a profit when mature."),
_doc_items_entry_name = S("Premature Beetroot Plant"),
paramtype = "light",
paramtype2 = "meshoptions",
sunlight_propagates = true,
place_param2 = 3,
walkable = false,
drawtype = "plantlike",
drop = "mcl_farming:beetroot_seeds",
tiles = {"mcl_farming_beetroot_".. i ..".png"},
inventory_image = "mcl_farming_beetroot_".. i ..".png",
wield_image = "mcl_farming_beetroot_".. i ..".png",
selection_box = {
type = "fixed",
fixed = { {-0.5, -0.5, -0.5, 0.5, size[i]/16, 0.5} },
},
},
groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1},
sounds = mcl_sounds.node_sound_leaves_defaults(),
_mcl_blast_resistance = 0,
})
minetest.register_node("mcl_farming:beetroot_2", {
description = S("Premature Beetroot Plant (Stage 3)"),
_doc_items_create_entry = false,
paramtype = "light",
paramtype2 = "meshoptions",
sunlight_propagates = true,
place_param2 = 3,
walkable = false,
drawtype = "plantlike",
drop = "mcl_farming:beetroot_seeds",
tiles = {"mcl_farming_beetroot_2.png"},
inventory_image = "mcl_farming_beetroot_2.png",
wield_image = "mcl_farming_beetroot_2.png",
selection_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, -3/16, 0.5}
groups = {
dig_immediate=3, not_in_creative_inventory=1,
plant=1, attached_node=1, dig_by_water=1,
destroy_by_lava_flow=1,dig_by_piston=1
},
},
groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1},
sounds = mcl_sounds.node_sound_leaves_defaults(),
_mcl_blast_resistance = 0,
})
sounds = mcl_sounds.node_sound_leaves_defaults(),
_mcl_blast_resistance = 0,
_on_bone_meal = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
local n = minetest.get_node(pos)
-- 75% chance to advance to next stage
if math.random(1, 100) <= 75 then
return mcl_farming:grow_plant("plant_beetroot", pos, n, 1, true)
end
end
})
end
minetest.register_node("mcl_farming:beetroot", {
description = S("Mature Beetroot Plant"),

@ -45,6 +45,12 @@ for i=1, 7 do
groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1},
sounds = mcl_sounds.node_sound_leaves_defaults(),
_mcl_blast_resistance = 0,
_on_bone_meal = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
local n = minetest.get_node(pos)
local stages = math.random(2, 5)
return mcl_farming:grow_plant("plant_carrot", pos, n, stages, true)
end
})
end

@ -109,6 +109,12 @@ for s=1,7 do
groups = {dig_immediate=3, not_in_creative_inventory=1, plant=1,attached_node=1, dig_by_water=1,destroy_by_lava_flow=1, plant_melon_stem=s},
sounds = mcl_sounds.node_sound_leaves_defaults(),
_mcl_blast_resistance = 0,
_on_bone_meal = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
local n = minetest.get_node(pos)
local stages = math.random(2, 5)
return mcl_farming:grow_plant("plant_melon_stem", pos, n, stages, true)
end
})
end

@ -49,6 +49,12 @@ for i=1, 7 do
groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1},
sounds = mcl_sounds.node_sound_leaves_defaults(),
_mcl_blast_resistance = 0,
_on_bone_meal = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
local n = minetest.get_node(pos)
local stages = math.random(2, 5)
return mcl_farming:grow_plant("plant_potato", pos, n, stages, true)
end
})
end

@ -79,6 +79,12 @@ for s=1,7 do
groups = {dig_immediate=3, not_in_creative_inventory=1, plant=1,attached_node=1, dig_by_water=1,destroy_by_lava_flow=1,},
sounds = mcl_sounds.node_sound_leaves_defaults(),
_mcl_blast_resistance = 0,
_on_bone_meal = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
local n = minetest.get_node(pos)
local stages = math.random(2, 5)
return mcl_farming:grow_plant("plant_pumpkin_stem", pos, n, stages, true)
end
})
end

@ -12,6 +12,25 @@ for i=0, 3 do
local drop_berries = (i >= 2)
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(itemstack, placer, pointed_thing)
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(itemstack, placer, pointed_thing)
do_berry_drop(pointed_thing.under)
end
end
minetest.register_node(node_name, {
drawtype = "plantlike",
tiles = {texture},
@ -45,6 +64,7 @@ for i=0, 3 do
sounds = mcl_sounds.node_sound_leaves_defaults(),
_mcl_blast_resistance = 0,
_mcl_hardness = 0,
_on_bone_meal = on_bonemealing,
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local pn = clicker:get_player_name()
if clicker:is_player() and minetest.is_protected(pos, pn) then
@ -60,11 +80,13 @@ for i=0, 3 do
return
end
if drop_berries then
for j=1, berries_to_drop[math.random(2)] do
minetest.add_item(pos, "mcl_farming:sweet_berry")
if i >= 2 then
do_berry_drop(pos)
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
minetest.swap_node(pos, {name = "mcl_farming:sweet_berry_bush_1"})
end
return itemstack
end,

@ -60,6 +60,12 @@ for i=1,7 do
dig_by_water=1,destroy_by_lava_flow=1, dig_by_piston=1},
sounds = mcl_sounds.node_sound_leaves_defaults(),
_mcl_blast_resistance = 0,
_on_bone_meal = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
local n = minetest.get_node(pos)
local stages = math.random(2, 5)
return mcl_farming:grow_plant("plant_wheat", pos, n, stages, true)
end
})
end

@ -0,0 +1,136 @@
-- bonemealing grass nodes
--
-- When bonemealing "mcl_core:dirt_with_grass", it spawns grass and flowers
-- over a 7x7 patch of adjacent grassy nodes.
--
-- Because of potential dependency complications it is not advisable to add
-- callbacks to mcl_core that create dependencies on mods that depend on
-- mcl_core, such as mcl_flowers.
--
-- To work around this restriction, the bonemealing callback is defined here
-- and the _on_bone_meal callback in "mcl_core:dirt_with_grass" node
-- definition is overwritten with it.
local mg_name = minetest.get_mapgen_setting("mg_name")
local flowers_table_simple = {
"mcl_flowers:dandelion",
"mcl_flowers:poppy",
}
local flowers_table_plains = {
"mcl_flowers:dandelion",
"mcl_flowers:dandelion",
"mcl_flowers:poppy",
"mcl_flowers:oxeye_daisy",
"mcl_flowers:tulip_orange",
"mcl_flowers:tulip_red",
"mcl_flowers:tulip_white",
"mcl_flowers:tulip_pink",
"mcl_flowers:azure_bluet",
}
local flowers_table_swampland = {
"mcl_flowers:blue_orchid",
}
local flowers_table_flower_forest = {
"mcl_flowers:dandelion",
"mcl_flowers:poppy",
"mcl_flowers:oxeye_daisy",
"mcl_flowers:tulip_orange",
"mcl_flowers:tulip_red",
"mcl_flowers:tulip_white",
"mcl_flowers:tulip_pink",
"mcl_flowers:azure_bluet",
"mcl_flowers:allium",
}
local biome_flowers_tables = {
["Plains"] = flowers_table_plains,
["Plains_beach"] = flowers_table_plains,
["Plains_ocean"] = flowers_table_plains,
["Plains_deep_ocean"] = flowers_table_plains,
["Plains_underground"] = flowers_table_plains,
["SunflowerPlains"] = flowers_table_plains,
["SunflowerPlains_ocean"] = flowers_table_plains,
["SunflowerPlains_deep_ocean"] = flowers_table_plains,
["SunflowerPlains_underground"] = flowers_table_plains,
["Swampland"] = flowers_table_swampland,
["Swampland_shore"] = flowers_table_swampland,
["Swampland_ocean"] = flowers_table_swampland,
["Swampland_deep_ocean"] = flowers_table_swampland,
["Swampland_underground"] = flowers_table_swampland,
["FlowerForest"] = flowers_table_flower_forest,
["FlowerForest_beach"] = flowers_table_flower_forest,
["FlowerForest_ocean"] = flowers_table_flower_forest,
["FlowerForest_deep_ocean"] = flowers_table_flower_forest,
["FlowerForest_underground"] = flowers_table_flower_forest,
}
-- Randomly generate flowers, tall grass or nothing
-- pos: node to place into
-- color: param2 value for tall grass
--
local function add_random_flower(pos, color)
-- 90% tall grass, 10% flower
local rnd = math.random(1,100)
if rnd <= 60 then
minetest.add_node(pos, {name="mcl_flowers:tallgrass", param2=color})
elseif rnd <= 80 then
-- double tallgrass
local toppos = vector.offset(pos, 0, 1, 0)
local topnode = minetest.get_node(toppos)
if minetest.registered_nodes[topnode.name].buildable_to then
minetest.set_node(pos, { name = "mcl_flowers:double_grass", param2 = color })
minetest.set_node(toppos, { name = "mcl_flowers:double_grass_top", param2 = color })
return true
end
else
local flowers_table
if mg_name == "v6" then
flowers_table = flowers_table_plains
else
local biome = minetest.get_biome_name(minetest.get_biome_data(pos).biome)
flowers_table = biome_flowers_tables[biome] or flowers_table_simple
end
minetest.add_node(pos, {name=flowers_table[math.random(1, #flowers_table)]})
end
end
--- Generate tall grass and random flowers in a 7x7 area
-- Bonemealing callback handler for "mcl_core:dirt_with_grass"
--
local function bonemeal_grass(pointed_thing, placer)
local pos, below, r, color
for i = -7, 7 do for j = -7, 7 do for y = -1, 1 do
pos = vector.offset(pointed_thing.above, i, y, j)
if minetest.get_node(pos).name == "air" then
below = minetest.get_node(vector.offset(pos, 0, -1, 0))
r = ((math.abs(i) + math.abs(j)) / 2)
if (minetest.get_item_group(below.name, "grass_block_no_snow") == 1) and
math.random(1, 100) <= 90 / r then
color = below.param2
add_random_flower(pos, color)
if math.random(1,5) == 1 then
mcl_bone_meal.add_bone_meal_particle(pos)
end
end
end
end end end
return true
end
-- Override "mcl_core:dirt_with_grass" bonemealing handler.
local nodename = "mcl_core:dirt_with_grass"
local olddef = minetest.registered_nodes[nodename]
if not olddef then
minetest.log("warning", "'mcl_core:dirt_with_grass' not registered, cannot add override!")
else
local oldhandler = olddef._on_bone_meal
local newhandler = function(itemstack, placer, pointed_thing)
local res = bonemeal_grass(pointed_thing, placer)
if oldhandler then
res = oldhandler(itemstack, placer, pointed_thing) or res
end
return res
end
minetest.override_item(nodename, {_on_bone_meal = newhandler})
end

@ -162,6 +162,18 @@ local def_tallgrass = {
_mcl_fortune_drop = fortune_wheat_seed_drop,
node_placement_prediction = "",
on_place = on_place_flower,
_on_bone_meal = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
local n = minetest.get_node(pos)
-- Grow into double tallgrass
local toppos = vector.offset(pos, 0, 1, 0)
local topnode = minetest.get_node(toppos)
if minetest.registered_nodes[topnode.name].buildable_to then
minetest.set_node(pos, { name = "mcl_flowers:double_grass", param2 = n.param2 })
minetest.set_node(toppos, { name = "mcl_flowers:double_grass_top", param2 = n.param2 })
return true
end
end,
_mcl_blast_resistance = 0,
_mcl_hardness = 0,
}
@ -180,6 +192,18 @@ def_fern.selection_box = {
fixed = { -6/16, -0.5, -6/16, 6/16, 5/16, 6/16 },
}
def_fern.groups.compostability = 65
def_fern._on_bone_meal = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
local n = minetest.get_node(pos)
-- Grow into double fern.
local toppos = vector.offset(pos, 0, 1, 0)
local topnode = minetest.get_node(toppos)
if minetest.registered_nodes[topnode.name].buildable_to then
minetest.set_node(pos, { name = "mcl_flowers:double_fern", param2 = n.param2 })
minetest.set_node(toppos, { name = "mcl_flowers:double_fern_top", param2 = n.param2 })
return true
end
end
minetest.register_node("mcl_flowers:fern", def_fern)
@ -243,10 +267,16 @@ local function add_large_plant(name, desc, longdesc, bottom_img, top_img, inv_im
if name == "double_grass" then
bottom_groups.compostability = 50
end
local on_bonemealing
if is_flower then
bottom_groups.flower = 1
bottom_groups.place_flowerlike = 1
bottom_groups.dig_immediate = 3
on_bonemealing = function(itemstack, placer, pointed_thing)
local pos = pointed_thing.under
minetest.add_item(pos, "mcl_flowers:"..name)
return true
end
else
bottom_groups.place_flowerlike = 2
bottom_groups.handy = 1
@ -381,6 +411,7 @@ local function add_large_plant(name, desc, longdesc, bottom_img, top_img, inv_im
minetest.remove_node(top)
end
end,
_on_bone_meal = on_bonemealing,
groups = bottom_groups,
sounds = mcl_sounds.node_sound_leaves_defaults(),
mesh = mesh
@ -419,6 +450,7 @@ local function add_large_plant(name, desc, longdesc, bottom_img, top_img, inv_im
minetest.remove_node(bottom)
end
end,
_on_bone_meal = on_bonemealing,
groups = top_groups,
sounds = mcl_sounds.node_sound_leaves_defaults(),
})
@ -572,3 +604,6 @@ if mod_mcimport and mg_name == "singlenode" and fix_doubleplants == true then
end
dofile(modpath.."/register.lua")
-- Bonemealing handler and override for "mcl_core:dirt_with_grass":
dofile(modpath.."/bonemealing.lua")

@ -1,3 +1,3 @@
name=mcl_flowers
depends=mcl_core, mcl_util, mcl_sounds
optional_depends=screwdriver, doc, mcl_flowerpots
depends=mcl_core, mcl_util, mcl_sounds, mcl_bone_meal
optional_depends=screwdriver, doc, mcl_flowerpots

@ -1,5 +1,8 @@
local S = minetest.get_translator(minetest.get_current_modname())
local modpath = minetest.get_modpath(minetest.get_current_modname())
local schempath = modpath .. "/schematics/"
local on_place = mcl_util.generate_on_place_plant_function(function(place_pos, place_node)
local soil_node = minetest.get_node_or_nil({x=place_pos.x, y=place_pos.y-1, z=place_pos.z})
if not soil_node then return false end
@ -16,6 +19,40 @@ local on_place = mcl_util.generate_on_place_plant_function(function(place_pos, p
return ((snn == "mcl_core:podzol" or snn == "mcl_core:podzol_snow" or snn == "mcl_core:mycelium" or snn == "mcl_core:mycelium_snow") or (light_ok and minetest.get_item_group(snn, "solid") == 1 and minetest.get_item_group(snn, "opaque") == 1))
end)
-- Try to grow huge mushroom
local function apply_bonemeal(pos, schematic, offset)
-- Must be on a dirt-type block
local below = minetest.get_node(vector.offset(pos, 0, -1, 0))
if minetest.get_item_group(below.name, "grass_block") ~= 1
and below.name ~= "mcl_core:mycelium"
and below.name ~= "mcl_core:dirt"
and below.name ~= "mcl_core:coarse_dirt"
and below.name ~= "mcl_core:podzol" then
return false
end
-- 40% chance
if math.random(1, 100) <= 40 then
-- Check space requirements
for i= 1, 3 do
local cpos = vector.offset(pos, 0, i, 0)
if minetest.get_node(cpos).name ~= "air" then
return false
end
end
local minp = vector.offset(pos, -3, 3, -3)
local maxp = vector.offset(pos, 3, 8, 3)
local diff = maxp - minp
local goodnodes = minetest.find_nodes_in_area(minp, maxp, {"air", "group:leaves"})
if #goodnodes < (diff.x + 1) * (diff.y + 1) * (diff.z + 1) then
return false
end
-- Place the huge mushroom
minetest.remove_node(pos)
return minetest.place_schematic(pos + offset, schematic, 0, nil, false)
end
return false
end
local longdesc_intro_brown = S("Brown mushrooms are fungi which grow and spread in darkness, but are sensitive to light. They are inedible as such, but they can be used to craft food items.")
local longdesc_intro_red = S("Red mushrooms are fungi which grow and spread in darkness, but are sensitive to light. They are inedible as such, but they can be used to craft food items.")
@ -51,6 +88,11 @@ minetest.register_node("mcl_mushrooms:mushroom_brown", {
},
node_placement_prediction = "",
on_place = on_place,
_on_bone_meal = function(itemstack, placer, pointed_thing)
local schematic = schempath .. "mcl_mushrooms_huge_brown.mts"
local offset = vector.new(-3, -1, -3)
return apply_bonemeal(pointed_thing.under, schematic, offset)
end,
_mcl_blast_resistance = 0,
})
@ -78,6 +120,11 @@ minetest.register_node("mcl_mushrooms:mushroom_red", {
},
node_placement_prediction = "",
on_place = on_place,
_on_bone_meal = function(itemstack, placer, pointed_thing)
local schematic = schempath .. "mcl_mushrooms_huge_red.mts"
local offset = vector.new(-2, -1, -2)
return apply_bonemeal(pointed_thing.under, schematic, offset)
end,
_mcl_blast_resistance = 0,
})

@ -1,4 +1,4 @@
name = mcl_signs
description = New and Improved signs - can be colored and made to glow.
depends = mcl_core, mcl_sounds, mcl_dye, mcl_colors, mcl_util
depends = mcl_core, mcl_sounds, mcl_dye, mcl_colors, mcl_util, mesecons_mvps
optional_depends = doc

@ -0,0 +1,33 @@
bonemeal = {
item_list = {
bucket_water = "mcl_buckets:bucket_water",
bucket_empty = "mcl_buckets:bucket_empty",
dirt = "mcl_core:dirt",
torch = "mcl_torches:torch",
coral = "mcl_ocean:dead_horn_coral_block"
}
}
function bonemeal:on_use(pos, strength, node)
-- Fake itemstack for bone meal
local itemstack = ItemStack("mcl_bone_meal:bone_meal")
local pointed_thing = {
above = pos,
under = vector.offset(pos, 0, -1, 0)
}
mcl_bone_meal.use_bone_meal(itemstack, nil, pointed_thing)
end
function bonemeal:is_creative(player_name)
return minetest.is_creative_enabled(player_name)
end
function bonemeal:add_deco(list)
minetest.log("TODO: implement bonemeal:add_deco("..dump(list).."..)")
for i = 1,#list do
local item = list[i]
end
end
minetest.register_alias("bonemeal:bone", "mcl_mobitems:bone")

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

Before

Width:  |  Height:  |  Size: 244 B

After

Width:  |  Height:  |  Size: 244 B