EinsDreiDreiSieben/mods/x_farming/cocoa.lua
2025-05-10 22:28:50 +02:00

720 lines
No EOL
21 KiB
Lua

--[[
X Farming. Extends Minetest farming mod with new plants, crops and ice fishing.
Copyright (C) 2024 SaKeL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to juraj.vajda@gmail.com
--]]
local S = minetest.get_translator(minetest.get_current_modname())
local dpath = minetest.get_modpath("default")
-- how often node timers for plants will tick, +/- some random value
local function tick(pos)
minetest.get_node_timer(pos):start(math.random(332, 572))
end
-- how often a growth failure tick is retried (e.g. too dark)
local function tick_again(pos)
minetest.get_node_timer(pos):start(math.random(80, 160))
end
function x_farming.grow_cocoa_plant(pos, elapsed)
local node = minetest.get_node(pos)
local name = node.name
local def = minetest.registered_nodes[name]
if not def.next_plant then
-- disable timer for fully grown plant
return
end
-- check if on jungletree
local direction = minetest.facedir_to_dir(node.param2)
local below_pos = vector.add(pos, direction)
local below = minetest.get_node(below_pos)
if below.name ~= 'default:jungletree' and below.name ~= 'x_farming:jungle_tree' then
tick_again(pos)
return
end
-- check light
local light = minetest.get_node_light(pos)
if not light or light < def.minlight or light > def.maxlight then
tick_again(pos)
return
end
-- grow
minetest.swap_node(pos, { name = def.next_plant, param2 = node.param2 })
-- new timer needed?
if minetest.registered_nodes[def.next_plant].next_plant then
tick(pos)
end
end
function x_farming.place_cocoa_bean(itemstack, placer, pointed_thing)
local pt = pointed_thing
-- check if pointing at a node
if not pt then
return itemstack
end
if pt.type ~= 'node' then
return itemstack
end
local under = minetest.get_node(pt.under)
local above = minetest.get_node(pt.above)
local udef = minetest.registered_nodes[under.name]
if udef and udef.on_rightclick
and not (placer and placer:is_player()
and placer:get_player_control().sneak)
then
return udef.on_rightclick(pt.under, under, placer, itemstack, pointed_thing) or itemstack
end
local player_name = placer and placer:get_player_name() or ''
if minetest.is_protected(pt.under, player_name) then
minetest.record_protection_violation(pt.under, player_name)
return
end
if minetest.is_protected(pt.above, player_name) then
minetest.record_protection_violation(pt.above, player_name)
return
end
-- return if any of the nodes is not registered
if not minetest.registered_nodes[under.name] then
return itemstack
end
if not minetest.registered_nodes[above.name] then
return itemstack
end
-- check if NOT pointing at the top/below of the node
if pt.above.y == pt.under.y - 1
or pt.above.y == pt.under.y + 1
then
return itemstack
end
-- check if you can replace the node above the pointed node
if not minetest.registered_nodes[above.name].buildable_to then
return itemstack
end
-- check if pointing at soil
if under.name ~= 'default:jungletree' and under.name ~= 'x_farming:jungle_tree' then
return itemstack
end
local direction = vector.direction(pt.above, pt.under)
local new_param2 = minetest.dir_to_facedir(direction)
-- add the node and remove 1 item from the itemstack
minetest.set_node(pt.above, { name = 'x_farming:cocoa_1', param2 = new_param2 })
tick(pt.above)
if not minetest.is_creative_enabled(player_name) then
itemstack:take_item()
end
return itemstack
end
-- COCOA
minetest.register_craftitem('x_farming:cocoa_bean', {
description = S('Cocoa bean') .. ' (' .. S('plant on jungle tree trunk') .. ')'
.. '\n' .. S('Compost chance') .. ': 65%',
short_description = S('Cocoa bean'),
tiles = { 'x_farming_cocoa_bean.png' },
inventory_image = 'x_farming_cocoa_bean.png',
wield_image = 'x_farming_cocoa_bean.png',
groups = { compost = 65 , food_cocoa = 1},
on_place = x_farming.place_cocoa_bean,
})
-- 1
minetest.register_node('x_farming:cocoa_1', {
description = S('Cocoa') .. ' 1',
short_description = S('Cocoa') .. ' 1',
drawtype = 'nodebox',
tiles = {
'x_farming_cocoa_top_1.png',
'x_farming_cocoa_bottom_1.png',
'x_farming_cocoa_right_1.png',
'x_farming_cocoa_left_1.png',
'x_farming_cocoa_front_1.png',
'x_farming_cocoa_front_1.png'
},
use_texture_alpha = 'clip',
paramtype = 'light',
sunlight_propagates = true,
wield_scale = { x = 2, y = 2, z = 2 },
on_rotate = function(pos, node, user, mode, new_param2)
return false
end,
paramtype2 = 'facedir',
is_ground_content = false,
drop = {
items = {
{ items = { 'x_farming:cocoa_bean' }, rarity = 3 },
}
},
node_box = {
type = 'fixed',
fixed = {
{ -0.125, -0.0625, 0.1875, 0.125, 0.25, 0.4375 }, -- fruit
{ 0, 0.25, 0.3125, 0, 0.375, 0.375 }, -- stem_1
{ 0, 0.375, 0.4375, 0, 0.4375, 0.5 }, -- stem_2
{ 0, 0.3125, 0.375, 0, 0.4375, 0.4375 }, -- stem_3
}
},
collision_box = {
type = 'fixed',
fixed = {
{ -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 },
},
},
groups = {
-- MTG
choppy = 3,
flammable = 2,
plant = 1,
cocoa = 1,
-- MCL
handy = 1,
axey = 1,
dig_by_water = 1,
destroy_by_lava_flow = 1,
dig_by_piston = 1,
attached_node_facedir = 1,
-- ALL
not_in_creative_inventory = 1,
},
_mcl_blast_resistance = 3,
_mcl_hardness = 0.2,
sounds = x_farming.node_sound_wood_defaults(),
next_plant = 'x_farming:cocoa_2',
on_timer = x_farming.grow_cocoa_plant,
minlight = 13,
maxlight = 15,
})
-- 2
minetest.register_node('x_farming:cocoa_2', {
description = S('Cocoa') .. ' 2',
short_description = S('Cocoa') .. ' 2',
drawtype = 'nodebox',
tiles = {
'x_farming_cocoa_top_2.png',
'x_farming_cocoa_bottom_2.png',
'x_farming_cocoa_right_2.png',
'x_farming_cocoa_left_2.png',
'x_farming_cocoa_front_2.png',
'x_farming_cocoa_front_2.png'
},
use_texture_alpha = 'clip',
paramtype = 'light',
sunlight_propagates = true,
wield_scale = { x = 1.5, y = 1.5, z = 1.5 },
on_rotate = function(pos, node, user, mode, new_param2)
return false
end,
paramtype2 = 'facedir',
is_ground_content = false,
drop = {
items = {
{ items = { 'x_farming:cocoa_bean' }, rarity = 2 },
}
},
node_box = {
type = 'fixed',
fixed = {
{ -0.1875, -0.1875, 0.0625, 0.1875, 0.25, 0.4375 }, -- fruit
{ 0, 0.25, 0.25, 0, 0.375, 0.375 }, -- stem_1
{ 0, 0.375, 0.375, 0, 0.5, 0.5 }, -- stem_2
{ 0, 0.375, 0.3125, 0, 0.4375, 0.375 }, -- stem_3
}
},
collision_box = {
type = 'fixed',
fixed = {
{ -0.1875, -0.1875, 0.0625, 0.1875, 0.5, 0.5 },
},
},
selection_box = {
type = 'fixed',
fixed = {
{ -0.1875, -0.1875, 0.0625, 0.1875, 0.5, 0.5 },
},
},
groups = {
-- MTG
choppy = 3,
flammable = 2,
plant = 1,
cocoa = 2,
-- MCL
handy = 1,
axey = 1,
dig_by_water = 1,
destroy_by_lava_flow = 1,
dig_by_piston = 1,
attached_node_facedir = 1,
-- ALL
not_in_creative_inventory = 1,
},
_mcl_blast_resistance = 3,
_mcl_hardness = 0.2,
sounds = x_farming.node_sound_wood_defaults(),
next_plant = 'x_farming:cocoa_3',
on_timer = x_farming.grow_cocoa_plant,
minlight = 13,
maxlight = 15
})
-- 3
minetest.register_node('x_farming:cocoa_3', {
description = S('Cocoa') .. ' 3',
short_description = S('Cocoa') .. ' 3',
drawtype = 'nodebox',
tiles = {
'x_farming_cocoa_top_3.png',
'x_farming_cocoa_bottom_3.png',
'x_farming_cocoa_right_3.png',
'x_farming_cocoa_left_3.png',
'x_farming_cocoa_front_3.png',
'x_farming_cocoa_front_3.png'
},
use_texture_alpha = 'clip',
paramtype = 'light',
sunlight_propagates = true,
wield_scale = { x = 1.5, y = 1.5, z = 1.5 },
on_rotate = function(pos, node, user, mode, new_param2)
return false
end,
paramtype2 = 'facedir',
is_ground_content = false,
drop = {
items = {
{ items = { 'x_farming:cocoa_bean' }, rarity = 1 },
{ items = { 'x_farming:cocoa_bean' }, rarity = 2 },
}
},
node_box = {
type = 'fixed',
fixed = {
{ -0.25, -0.3125, -0.0625, 0.25, 0.25, 0.4375 },
{ -0.0624999, 0.25, 0.25, 0.0625, 0.375, 0.4375 },
{ -0.0625, 0.375, 0.375, 0.0625, 0.5, 0.5 },
{ -0.0624999, 0.375, 0.3125, 0.0625, 0.4375, 0.375 },
}
},
collision_box = {
type = 'fixed',
fixed = {
{ -0.25, -0.3125, -0.0625, 0.25, 0.5, 0.5 },
},
},
selection_box = {
type = 'fixed',
fixed = {
{ -0.25, -0.3125, -0.0625, 0.25, 0.5, 0.5 },
},
},
groups = {
-- MTG
choppy = 3,
flammable = 2,
plant = 1,
leafdecay = 3,
leafdecay_drop = 1,
cocoa = 3,
-- MCL
handy = 1,
axey = 1,
dig_by_water = 1,
destroy_by_lava_flow = 1,
dig_by_piston = 1,
attached_node_facedir = 1,
-- ALL
not_in_creative_inventory = 1,
},
_mcl_blast_resistance = 3,
_mcl_hardness = 0.2,
sounds = x_farming.node_sound_wood_defaults(),
minlight = 13,
maxlight = 15
})
-- replacement LBM for pre-nodetimer plants
minetest.register_lbm({
name = 'x_farming:start_nodetimer_cocoa',
nodenames = {
'x_farming:cocoa_1',
'x_farming:cocoa_2'
},
action = function(pos, node)
tick_again(pos)
end,
})
if dpath then
minetest.register_alias("x_farming:jungle_tree","default:jungletree")
minetest.register_alias("x_farming:jungle_wood","default:junglewood")
minetest.register_alias("x_farming:jungle_leaves","default:jungleleaves")
minetest.register_alias("x_farming:jungle_with_cocoa_sapling","default:junglesapling")
minetest.register_alias("stairs:stair_jungle_wood","stairs:stair_junglewood")
minetest.register_alias("stairs:stair_inner_jungle_wood","stairs:stair_inner_junglewood")
minetest.register_alias("stairs:stair_outer_jungle_wood","stairs:stair_outer_junglewood")
minetest.register_alias("stairs:slab_jungle_wood","stairs:slab_junglewood")
-- leafdecay
default.register_leafdecay({
trunks = { 'default:jungletree' },
leaves = {
'x_farming:cocoa_1',
'x_farming:cocoa_2',
'x_farming:cocoa_3',
},
radius = 2,
})
else
--sapling
minetest.register_node('x_farming:jungle_with_cocoa_sapling', {
description = S('Jungle Tree with Cocoa Sapling') .. '\n' .. S('Compost chance') .. ': 30%',
short_description = S('Jungle Tree with Cocoa Sapling'),
drawtype = 'plantlike',
tiles = { 'x_farming_junglesapling.png' },
inventory_image = 'x_farming_junglesapling.png',
wield_image = 'x_farming_junglesapling.png',
paramtype = 'light',
sunlight_propagates = true,
walkable = false,
on_timer = x_farming.grow_jungle_tree,
selection_box = {
type = 'fixed',
fixed = { -4 / 16, -0.5, -4 / 16, 4 / 16, 7 / 16, 4 / 16 }
},
groups = {
-- MTG
snappy = 2,
flammable = 2,
-- MCL
plant = 1,
non_mycelium_plant = 1,
deco_block = 1,
dig_by_water = 1,
dig_by_piston = 1,
destroy_by_lava_flow = 1,
compostability = 30,
-- ALL
dig_immediate = 3,
attached_node = 1,
sapling = 1,
},
_mcl_blast_resistance = 0,
_mcl_hardness = 0,
sounds = x_farming.node_sound_leaves_defaults(),
on_construct = function(pos)
minetest.get_node_timer(pos):start(math.random(300, 1500))
end,
on_place = function(itemstack, placer, pointed_thing)
itemstack = x_farming.sapling_on_place(itemstack, placer, pointed_thing,
'x_farming:jungle_with_cocoa_sapling',
-- minp, maxp to be checked, relative to sapling pos
{ x = -3, y = -5, z = -3 },
{ x = 3, y = 31, z = 3 },
-- maximum interval of interior volume check
4)
return itemstack
end,
})
-- trunk
minetest.register_node('x_farming:jungle_tree', {
description = S('Jungle Tree'),
short_description = S('Jungle Tree'),
tiles = { 'x_farming_jungle_tree_top.png', 'x_farming_jungle_tree_top.png', 'x_farming_jungle_tree.png' },
paramtype2 = 'facedir',
is_ground_content = false,
groups = {
-- MTG
choppy = 2,
oddly_breakable_by_hand = 1,
-- MCL
handy = 1,
axey = 1,
building_block = 1,
material_wood = 1,
fire_encouragement = 5,
fire_flammability = 5,
-- ALL
tree = 1,
flammable = 2,
},
_mcl_blast_resistance = 2,
_mcl_hardness = 2,
sounds = x_farming.node_sound_wood_defaults(),
on_place = minetest.rotate_node
})
-- leaves
minetest.register_node('x_farming:jungle_leaves', {
description = S('Jungle Tree Leaves') .. '\n' .. S('Compost chance') .. ': 30%',
short_description = S('Jungle Tree Leaves'),
drawtype = 'allfaces_optional',
waving = 1,
tiles = { 'x_farming_jungleleaves.png' },
special_tiles = { 'x_farming_jungleleaves.png' },
paramtype = 'light',
is_ground_content = false,
groups = {
-- MTG
snappy = 3,
leafdecay = 3,
-- MCL
handy = 1,
hoey = 1,
shearsy = 1,
swordy = 1,
dig_by_piston = 1,
fire_encouragement = 30,
fire_flammability = 60,
deco_block = 1,
compostability = 30,
-- ALL
flammable = 2,
leaves = 1,
},
_mcl_shears_drop = true,
_mcl_blast_resistance = 0.2,
_mcl_hardness = 0.2,
_mcl_silk_touch_drop = true,
drop = {
max_items = 1,
items = {
{
-- player will get sapling with 1/20 chance
items = { 'x_farming:jungle_with_cocoa_sapling' },
rarity = 20,
},
{
-- player will get leaves only if he get no saplings,
-- this is because max_items is 1
items = { 'x_farming:jungle_leaves' },
}
}
},
sounds = x_farming.node_sound_leaves_defaults(),
after_place_node = x_farming.after_place_leaves,
})
-- leafdecay
x_farming.register_leafdecay({
trunks = { 'x_farming:jungle_tree' },
leaves = {
'x_farming:jungle_leaves'
},
radius = 2,
})
-- planks
minetest.register_node('x_farming:jungle_wood', {
description = S('Jungle Wood Planks'),
short_description = S('Jungle Wood Planks'),
paramtype2 = 'facedir',
place_param2 = 0,
tiles = { 'x_farming_jungle_wood.png' },
is_ground_content = false,
groups = {
-- MTG
choppy = 2,
oddly_breakable_by_hand = 2,
-- Everness
everness_wood = 1,
-- MCL
handy = 1,
axey = 1,
building_block = 1,
material_wood = 1,
fire_encouragement = 5,
fire_flammability = 20,
-- ALL
flammable = 3,
wood = 1,
},
_mcl_blast_resistance = 3,
_mcl_hardness = 2,
sounds = x_farming.node_sound_wood_defaults(),
})
-- Stairs
if minetest.global_exists('stairs') and minetest.get_modpath('stairs') then
stairs.register_stair_and_slab(
'jungle_wood',
'x_farming:jungle_wood',
{ choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 },
{ 'x_farming_jungle_wood.png' },
'Jungle Wooden Stair',
'Jungle Wooden Slab',
x_farming.node_sound_wood_defaults(),
false
)
end
end
-- Cookie
local cookie_def = {
description = S('Cookie') .. '\n' .. S('Compost chance') .. ': 85%\n'
.. minetest.colorize(x_farming.colors.brown, S('Hunger') .. ': 2'),
inventory_image = 'x_farming_cookie.png',
groups = {
-- MTG
compost = 85,
-- MCL
food = 2,
eatable = 2,
compostability = 85
},
}
if minetest.get_modpath('farming') then
cookie_def.on_use = minetest.item_eat(2)
end
if minetest.get_modpath('mcl_farming') then
cookie_def.on_place = minetest.item_eat(2)
cookie_def.on_secondary_use = minetest.item_eat(2)
end
minetest.register_craftitem('x_farming:cookie', cookie_def)
-- Chocolate
local chocolate_def = {
description = S('Chocolate') .. '\n' .. S('Compost chance') .. ': 65%\n'
.. minetest.colorize(x_farming.colors.brown, S('Hunger') .. ': 3'),
inventory_image = 'x_farming_chocolate.png',
groups = {
-- MTG
compost = 65,
-- MCL
food = 2,
eatable = 2,
compostability = 65
},
}
if minetest.get_modpath('farming') then
chocolate_def.on_use = minetest.item_eat(3)
end
if minetest.get_modpath('mcl_farming') then
chocolate_def.on_place = minetest.item_eat(3)
chocolate_def.on_secondary_use = minetest.item_eat(3)
end
minetest.register_craftitem('x_farming:chocolate', chocolate_def)
if minetest.get_modpath('mcl_stairs') then
mcl_stairs.register_stair_and_slab(
'x_farming_jungle_wood',
'x_farming:jungle_wood',
{ handy = 1, axey = 1, building_block = 1, material_wood = 1, fire_encouragement = 5, fire_flammability = 20, flammable = 3, wood = 1, },
{ 'x_farming_jungle_wood.png' },
S('Jungle Wooden Stair'),
S('Jungle Wooden Slab'),
x_farming.node_sound_wood_defaults(),
6,
2,
S('Double Jungle Wooden Slab'),
nil
)
end
-- Crate
x_farming.register_crate('crate_cocoa_bean_3', {
description = S('Cocoa Bean Crate'),
short_description = S('Cocoa Bean Crate'),
tiles = { 'x_farming_crate_cocoa_bean_3.png' },
_custom = {
crate_item = 'x_farming:cocoa_bean'
}
})
local c_jungletree = minetest.get_content_id("default:jungletree")
local c_cocoa2 = minetest.get_content_id("x_farming:cocoa_2")
local c_cocoa3 = minetest.get_content_id("x_farming:cocoa_3")
abdecor.register_advanced_decoration("x_farming_cocoa",{
target = {
place_on = "default:jungletree",
fill_ratio = 0.0075,
biomes = asuna.features.crops.cocoa,
y_min = 6,
y_max = 31000,
},
fn = function(mapgen)
-- Get provided values
local pos = mapgen.pos
local va = mapgen.voxelarea
local vdata = mapgen.data
local vparam2 = mapgen.param2
-- Get stride values and adjust position
local ystride = va.ystride
local zstride = va.zstride
pos = va:index(pos.x,pos.y + 2,pos.z)
-- Get adjacent tree trunk direction
local cardinal = {
zstride,
1,
-zstride,
-1,
}
for i = 1, 4 do
local treepos = pos + cardinal[i]
if vdata[treepos] == c_jungletree then
for j = 2, 6 do
pos = pos + ystride
treepos = treepos + ystride
if j % 2 == 0 and vdata[treepos] == c_jungletree and vdata[pos] == minetest.CONTENT_AIR then
vdata[pos] = (pos + 2 * j) % 7 == 0 and c_cocoa2 or c_cocoa3
vparam2[pos] = i - 1
end
end
end
end
end,
flags = {
param2 = true,
},
})