EinsDreiDreiSieben/mods/x_farming/composter.lua
2025-05-04 16:01:41 +02:00

238 lines
8.4 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 function particle_effect(pos)
minetest.add_particlespawner({
amount = 8,
time = 2,
minpos = { x = pos.x - 0.4, y = pos.y + 0.4, z = pos.z - 0.4 },
maxpos = { x = pos.x + 0.4, y = pos.y + 0.6, z = pos.z + 0.4 },
minvel = { x = -0.1, y = 0, z = -0.1 },
maxvel = { x = 0.1, y = 0.1, z = 0.1 },
minacc = vector.new({ x = -0.1, y = 0, z = -0.1 }),
maxacc = vector.new({ x = 0.1, y = 0.1, z = 0.1 }),
minexptime = 1,
maxexptime = 2,
minsize = 1,
maxsize = 2,
texture = 'x_farming_x_bonemeal_particles.png',
animation = {
type = 'vertical_frames',
aspect_w = 8,
aspect_h = 8,
length = 3,
},
})
end
for i = 1, 5, 1 do
local def = {}
def.name = 'x_farming:composter_' .. i
def.description = S('Composter') .. ' ' .. i
def.short_description = S('Composter') .. ' ' .. i
def.drawtype = 'mesh'
def.mesh = 'x_farming_crate.obj'
def.tiles = { 'x_farming_composter_' .. i .. '.png' }
def.use_texture_alpha = 'clip'
def.sounds = x_farming.node_sound_wood_defaults()
def.paramtype = 'light'
def.paramtype2 = 'facedir'
def.place_param2 = 0
def.is_ground_content = false
def.groups = {
-- MTG
choppy = 2,
oddly_breakable_by_hand = 2,
flammable = 2,
not_in_creative_inventory = 1,
-- MCL
handy = 1,
material_wood = 1,
deco_block = 1,
dirtifier = 1,
fire_encouragement = 3,
fire_flammability = 4,
}
def.stack_max = 1
def.mod_origin = 'x_farming'
def.drop = 'x_farming:composter_1'
def.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local p_name = clicker:get_player_name()
if minetest.is_protected(pos, p_name) then
return itemstack
end
local wield_stack = clicker:get_wielded_item()
local wield_stack_name = wield_stack:get_name()
-- percentage, higher = better, max 100%
local chance = 0
if minetest.get_item_group(wield_stack_name, 'compost') > 0 then
-- defined in groups, e.g. `{ compost = 10 }`
chance = minetest.get_item_group(wield_stack_name, 'compost')
elseif minetest.get_item_group(wield_stack_name, 'food_bread') == 1
or minetest.get_item_group(wield_stack_name, 'wool') == 1
or node.name == 'farming:straw'
then
chance = 85
elseif minetest.get_item_group(wield_stack_name, 'flora') == 1
or minetest.get_item_group(wield_stack_name, 'food_apple') == 1
or minetest.get_item_group(wield_stack_name, 'fern') == 1
or minetest.get_item_group(wield_stack_name, 'food_wheat') == 1
or minetest.get_item_group(wield_stack_name, 'food_flour') == 1
or minetest.get_item_group(wield_stack_name, 'mushroom') == 1
or minetest.get_item_group(wield_stack_name, 'flower') == 1
then
chance = 65
elseif minetest.get_item_group(wield_stack_name, 'marram_grass') == 1
or minetest.get_item_group(wield_stack_name, 'junglegrass') == 1
or node.name == 'default:cactus'
or node.name == 'default:coral_green'
or node.name == 'default:coral_pink'
or node.name == 'default:coral_cyan'
then
chance = 50
elseif minetest.get_item_group(wield_stack_name, 'leaves') == 1
or minetest.get_item_group(wield_stack_name, 'seed') == 1
or minetest.get_item_group(wield_stack_name, 'grass') == 1
or minetest.get_item_group(wield_stack_name, 'snappy') == 3
or minetest.get_item_group(wield_stack_name, 'sapling') == 1
or minetest.get_item_group(wield_stack_name, 'food_blueberries') == 1
or minetest.get_item_group(wield_stack_name, 'food_berry') == 1
or node.name == 'default:sand_with_kelp'
or node.name == 'default:large_cactus_seedling'
then
chance = 30
end
if chance == 0 then
return itemstack
end
-- fill the composter
if math.random() < chance / 100 then
local meta = minetest.get_meta(pos)
local prev_status = meta:get_int('composter_status')
local status = prev_status + 10
if status > 100 then
status = 100
end
meta:set_int('composter_status', status)
local node_def = minetest.registered_nodes[node.name]
if math.fmod(status, 50) == 0 and node_def._next_state then
local placenode = { name = node_def._next_state }
minetest.swap_node(pos, placenode)
particle_effect(pos)
if i == 3 then
-- placed nr 4
minetest.get_node_timer(pos):start(math.random(1, 2))
end
elseif i == 1 then
-- convert to visual 1st level
minetest.swap_node(pos, { name = 'x_farming:composter_2' })
particle_effect(pos)
end
end
minetest.sound_play('x_farming_dirt_hit', { gain = 0.3, pos = pos, max_hear_distance = 10 }, true)
if not minetest.is_creative_enabled(clicker:get_player_name()) then
itemstack:take_item()
end
return itemstack
end
if i == 1 then
-- empty composter is craftable, so can be in creative inventory
def.groups = {
-- MTG
choppy = 2,
oddly_breakable_by_hand = 2,
-- MCL
handy = 1,
material_wood = 1,
deco_block = 1,
dirtifier = 1,
fire_encouragement = 3,
fire_flammability = 4,
-- ALL
flammable = 2,
}
def.description = S('Composter') .. ' (' .. S('right-click/place with item to create compost') .. ')'
def.short_description = S('Composter')
end
if i < 4 then
-- all except the last
def._next_state = 'x_farming:composter_' .. i + 1
end
if i == 4 then
def.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
-- do nothing
end
-- last step
def.on_timer = function(pos, elapsed)
minetest.swap_node(pos, { name = 'x_farming:composter_5' })
end
end
if i == 5 then
def.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local p_name = clicker:get_player_name()
if minetest.is_protected(pos, p_name) then
return itemstack
end
local meta = minetest.get_meta(pos)
local above = vector.new(pos.x, pos.y + 0.5, pos.z)
local drop_pos = minetest.find_node_near(above, 0.5, { 'air' }) or above
minetest.sound_play('x_farming_dirt_hit', { gain = 0.3, pos = pos, max_hear_distance = 10 }, true)
-- drop bonemeal
minetest.add_item(
vector.new(drop_pos.x, drop_pos.y + 1, drop_pos.z),
ItemStack({ name = 'x_farming:bonemeal', count = math.random(1, 2) })
)
-- swap to beginning
minetest.swap_node(pos, { name = 'x_farming:composter_1' })
-- reset status
meta:set_int('composter_status', 0)
end
end
-- MCL
def._mcl_hardness = 0.6
def._mcl_blast_resistance = 0.6
minetest.register_node(def.name, def)
end