172 lines
5.7 KiB
Lua
172 lines
5.7 KiB
Lua
local is_farming_redo = minetest.get_modpath("farming") ~= nil
|
|
and farming ~= nil and farming.mod == "redo"
|
|
|
|
local MAX_ITEM_WEAR = 65535
|
|
local DEFAULT_SICKLE_USES = 120
|
|
local DEFAULT_SCYTHE_USES = 30
|
|
|
|
local function is_creative(playername)
|
|
return minetest.settings:get_bool("creative_mode")
|
|
or minetest.check_player_privs(playername, { creative = true })
|
|
end
|
|
|
|
local function get_wielded_item(player)
|
|
if not minetest.is_player(player) then return end
|
|
local itemstack = player:get_wielded_item()
|
|
if itemstack == nil then return end
|
|
return itemstack
|
|
end
|
|
|
|
local function get_item_group(def, group)
|
|
if def == nil
|
|
or def.groups == nil
|
|
or def.groups[group] == nil then
|
|
return 0
|
|
end
|
|
return def.groups[group]
|
|
end
|
|
|
|
function sickles.register_cuttable(nodename, base, item)
|
|
local def = minetest.registered_nodes[nodename]
|
|
if def == nil then return end
|
|
local default_handler = def.on_punch or minetest.node_punch
|
|
minetest.override_item(nodename, {
|
|
on_punch = function(pos, node, puncher, pointed_thing)
|
|
local itemstack = get_wielded_item(puncher)
|
|
local itemdef = itemstack:get_definition()
|
|
local level = get_item_group(itemdef, "sickle")
|
|
if level == 0 then
|
|
return default_handler(pos, node, puncher, pointed_thing)
|
|
end
|
|
local pname = puncher:get_player_name()
|
|
if minetest.is_protected(pos, pname) then
|
|
minetest.record_protection_violation(pos, pname)
|
|
return
|
|
end
|
|
minetest.handle_node_drops(pos, { item }, puncher)
|
|
minetest.after(0, function()
|
|
minetest.swap_node(pos, { name = base, param2 = node.param2 })
|
|
end)
|
|
if not is_creative(pname) then
|
|
local max_uses = get_item_group(itemdef, "sickle_uses") or DEFAULT_SICKLE_USES
|
|
itemstack:add_wear(math.ceil(MAX_ITEM_WEAR / (max_uses - 1)))
|
|
if itemstack:get_count() == 0 and itemdef.sound and itemdef.sound.breaks then
|
|
minetest.sound_play(itemdef.sound.breaks, { pos = pos, gain = 0.5 })
|
|
end
|
|
puncher:set_wielded_item(itemstack)
|
|
end
|
|
end
|
|
})
|
|
end
|
|
|
|
function sickles.register_trimmable(node, base)
|
|
local def = minetest.registered_nodes[node]
|
|
if def == nil then return end
|
|
local handler = def.after_dig_node
|
|
minetest.override_item(node, {
|
|
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
|
local itemstack = get_wielded_item(digger)
|
|
local itemdef = itemstack:get_definition()
|
|
local level = get_item_group(itemdef, "sickle")
|
|
if level == 0 then
|
|
if handler ~= nil then
|
|
return handler(pos, oldnode, oldmetadata, digger)
|
|
else return end
|
|
end
|
|
local param2 = minetest.registered_nodes[base].place_param2
|
|
minetest.set_node(pos, { name = base, param2 = param2 })
|
|
end
|
|
})
|
|
end
|
|
|
|
local function get_plant_definition(plant)
|
|
if is_farming_redo then
|
|
return farming.registered_plants[plant]
|
|
else
|
|
local mod = plant:split(":")[1] or ""
|
|
local name = plant:split(":")[2] or ""
|
|
local pname = name:gsub("(.*)_.*$", "%1")
|
|
return farming.registered_plants[pname]
|
|
end
|
|
end
|
|
|
|
local function get_seed_name(plant)
|
|
if is_farming_redo then
|
|
return farming.registered_plants[plant].seed
|
|
else
|
|
local mod = plant:split(":")[1]
|
|
local name = plant:split(":")[2]
|
|
local pname = name:gsub("(.*)_.*$", "%1")
|
|
return mod .. ":seed_" .. pname
|
|
end
|
|
end
|
|
|
|
local function harvest_and_replant(pos, player)
|
|
local playername = player:get_player_name()
|
|
local node = minetest.get_node(pos)
|
|
local node_id = node.name:gsub("(.*)_.*$", "%1")
|
|
local stage = tonumber(node.name:gsub(".*_(.*)$", "%1") or 0)
|
|
local plantdef = get_plant_definition(node_id)
|
|
if plantdef == nil or plantdef.steps == nil or stage < plantdef.steps then
|
|
return false
|
|
end
|
|
if minetest.is_protected(pos, playername) then
|
|
minetest.record_protection_violation(pos, playername)
|
|
return false
|
|
end
|
|
minetest.node_dig(pos, node, player)
|
|
minetest.sound_play("default_dig_snappy", { pos = pos, gain = 0.5, max_hear_distance = 8 }, true)
|
|
minetest.after(0, function()
|
|
local invref = player:get_inventory()
|
|
local seeds = get_seed_name(node_id)
|
|
if minetest.get_node(pos).name ~= "air" or
|
|
not invref:contains_item("main", seeds) then
|
|
return true
|
|
end
|
|
if not is_creative(playername) then
|
|
invref:remove_item("main", seeds)
|
|
end
|
|
if is_farming_redo then
|
|
-- plant first crop for farming redo
|
|
local crop_name = node_id .. "_1"
|
|
local crop_def = minetest.registered_nodes[crop_name]
|
|
if crop_def == nil then return end
|
|
minetest.set_node(pos, { name = crop_name, param2 = crop_def.place_param2 })
|
|
else
|
|
-- plant seeds for MTG farming
|
|
minetest.set_node(pos, { name = seeds, param2 = 1 })
|
|
end
|
|
end)
|
|
return true
|
|
end
|
|
|
|
function sickles.use_scythe(itemstack, user, pointed_thing)
|
|
if pointed_thing == nil then return end
|
|
local itemdef = itemstack:get_definition()
|
|
if pointed_thing.type == "object" then
|
|
local tool_capabilities = itemstack:get_tool_capabilities()
|
|
local meta = itemstack:get_meta()
|
|
local last_punch = meta:get_float("last_punch") or 0
|
|
local now = minetest.get_gametime()
|
|
meta:set_float("last_punch", now)
|
|
pointed_thing.ref:punch(user, now - last_punch, tool_capabilities)
|
|
end
|
|
if pointed_thing.type ~= "node" then return end
|
|
local max_uses = get_item_group(itemdef, "scythe_uses") or DEFAULT_SCYTHE_USES
|
|
local range = (get_item_group(itemdef, "scythe") or 1) - 1
|
|
local pos = pointed_thing.under
|
|
local harvested = harvest_and_replant(pos, user)
|
|
if not harvested then return end
|
|
if range > 0 then
|
|
local pos1 = vector.add(pos, { x = -range, y = 0, z = -range })
|
|
local pos2 = vector.add(pos, { x = range, y = 0, z = range })
|
|
local positions = minetest.find_nodes_in_area(pos1, pos2, "group:plant")
|
|
for _, check_pos in ipairs(positions) do
|
|
if pos ~= check_pos then
|
|
harvest_and_replant(check_pos, user)
|
|
end
|
|
end
|
|
end
|
|
itemstack:add_wear(math.ceil(MAX_ITEM_WEAR / (max_uses - 1)))
|
|
return itemstack
|
|
end |