226 lines
6.9 KiB
Lua
226 lines
6.9 KiB
Lua
-- this file contains the code that is used by sickles
|
|
local mod_mcl_farming = core.get_modpath("mcl_farming") ~= nil
|
|
|
|
local MAX_ITEM_WEAR = 65535
|
|
local DEFAULT_SICKLE_USES = 120
|
|
|
|
local S = farmtools.i18n
|
|
|
|
local function get_wielded_item(player)
|
|
-- this function returns the item that the given player is currently holding
|
|
if not core.is_player(player) then
|
|
return
|
|
end
|
|
return player:get_wielded_item()
|
|
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 farmtools.register_cuttable(nodename, base, item)
|
|
-- this function is used for registering items that can be cut with the sickle
|
|
|
|
-- first ensure that the give node is actually a registered node
|
|
-- fail otherwise
|
|
local def = core.registered_nodes[nodename]
|
|
if def == nil then
|
|
return
|
|
end
|
|
|
|
-- save the default handler of the node when punched
|
|
-- if no handler exists, we save the default Luanti handler
|
|
local default_handler = def.on_punch or core.node_punch
|
|
|
|
-- now we override the handler of the node when punched
|
|
-- i.e. the function below will be called every time a node with this name gets punched
|
|
core.override_item(nodename, {
|
|
on_punch = function(pos, node, puncher, pointed_thing)
|
|
-- first we want to ensure that the user is holding a sickle
|
|
local itemstack = get_wielded_item(puncher)
|
|
|
|
-- I have no idea if this is possible, but we need to check against nil value
|
|
if itemstack == nil then
|
|
return
|
|
end
|
|
|
|
-- if the user is not holding a sickle when punching the node, we won't continue any
|
|
-- futher. instead, we return the default handler that we previously saved.
|
|
-- i.e. the sickle-behavior won't be used
|
|
local itemdef = itemstack:get_definition()
|
|
local level = get_item_group(itemdef, "sickle")
|
|
if level < 1 then
|
|
return default_handler(pos, node, puncher, pointed_thing)
|
|
end
|
|
|
|
-- get the name of the player who punched the node
|
|
local pname = puncher:get_player_name()
|
|
|
|
-- if the player isn't available to edit the node that was punched,
|
|
-- report the violation and then exit the function
|
|
if core.is_protected(pos, pname) then
|
|
core.record_protection_violation(pos, pname)
|
|
return
|
|
end
|
|
|
|
-- give the player the item that is supposed to be returned when the sickle is
|
|
-- used on the given node
|
|
if mod_mcl_farming and item == "sickles:moss" then
|
|
-- for some reason mineclonia does not want to drop moss, so just add to player inventory
|
|
local invref = puncher:get_inventory()
|
|
if invref:room_for_item("main", item) then
|
|
invref:add_item("main", item)
|
|
end
|
|
else
|
|
core.handle_node_drops(pos, { item }, puncher)
|
|
end
|
|
-- replace the node by the node that should be in its place after the sickle is used
|
|
core.after(0, function()
|
|
core.swap_node(pos, { name = base, param2 = node.param2 })
|
|
end)
|
|
|
|
-- wear out the sickle if the player is not in creative mode
|
|
if not core.is_creative_enabled(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
|
|
core.sound_play(itemdef.sound.breaks, { pos = pos, gain = 0.5 })
|
|
end
|
|
-- finally we set the current wielded item of the player to the sickle used for
|
|
-- punching the node.
|
|
-- I have no idea why we need to do this, but I believe that the original author of the
|
|
-- mod put this here for a reason.
|
|
puncher:set_wielded_item(itemstack)
|
|
end
|
|
end,
|
|
})
|
|
end
|
|
|
|
function farmtools.register_trimmable(node, base)
|
|
-- this function is used for registering items that can be trimmed with the sickle
|
|
|
|
-- first ensure that the give node is actually a registered node
|
|
-- fail otherwise
|
|
local def = core.registered_nodes[node]
|
|
if def == nil then
|
|
return
|
|
end
|
|
|
|
-- save the default handler of the node when dug
|
|
-- if no handler exists, we save the default Luanti handler
|
|
local handler = def.after_dig_node
|
|
|
|
-- now we override the handler of the node when dug
|
|
-- i.e. the function below will be called every time a node with this name gets dug
|
|
core.override_item(node, {
|
|
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
|
-- first we want to ensure that the user is holding a sickle
|
|
local itemstack = get_wielded_item(digger)
|
|
|
|
-- I have no idea if this is possible, but we need to check against nil value
|
|
if itemstack == nil then
|
|
return
|
|
end
|
|
|
|
-- if the user is not holding a sickle when digging the node, we won't continue any
|
|
-- futher. instead, we return the default handler that we previously saved.
|
|
-- i.e. the sickle-behavior won't be used
|
|
local itemdef = itemstack:get_definition()
|
|
local level = get_item_group(itemdef, "sickle")
|
|
if level < 1 then
|
|
if handler ~= nil then
|
|
return handler(pos, oldnode, oldmetadata, digger)
|
|
else
|
|
return
|
|
end
|
|
end
|
|
|
|
-- we save the param2 property of the node that was just dug with the sickle
|
|
local param2 = core.registered_nodes[base].place_param2
|
|
-- and we replace it with the node that is supposed to be in place on the node after
|
|
-- it is trimmed by a sickle
|
|
core.set_node(pos, { name = base, param2 = param2 })
|
|
end,
|
|
})
|
|
end
|
|
|
|
farmtools.register_sickle = function(name, def)
|
|
-- this function is used for registering new scythes in the easiest way possible
|
|
|
|
-- register new scythes in your mod's namespace
|
|
if name:sub(1, 1) ~= ":" then
|
|
name = ":" .. name
|
|
end
|
|
|
|
-- check definition table
|
|
if def.description == nil then
|
|
def.description = S("Sickle")
|
|
end
|
|
if def.inventory_image == nil then
|
|
def.inventory_image = "unknown_item.png"
|
|
end
|
|
if def.max_uses == nil then
|
|
def.max_uses = DEFAULT_SICKLE_USES
|
|
end
|
|
if def.groupcaps == nil then
|
|
def.groupcaps = {
|
|
snappy = {
|
|
times = {
|
|
[1] = 2.75,
|
|
[2] = 1.30,
|
|
[3] = 0.375,
|
|
uses = def.max_uses / 2,
|
|
maxlevel = 2,
|
|
},
|
|
},
|
|
}
|
|
end
|
|
if def.damage_groups == nil then
|
|
def.damage_groups = { fleshy = 3 }
|
|
end
|
|
-- support the definition providing groups, primarily for enchantability for voxelibre
|
|
local groups = { sickle = 1, sickle_uses = def.max_uses }
|
|
if def.groups then
|
|
for k, v in pairs(def.groups) do
|
|
groups[k] = v
|
|
end
|
|
end
|
|
|
|
-- now register the tool through the Luanti API
|
|
--
|
|
core.register_tool(name, {
|
|
description = def.description,
|
|
inventory_image = def.inventory_image,
|
|
tool_capabilities = {
|
|
full_punch_interval = 0.8,
|
|
max_drop_level = 1,
|
|
groupcaps = def.groupcaps,
|
|
damage_groups = def.damage_groups,
|
|
punch_attack_uses = def.max_uses / 2,
|
|
},
|
|
range = 6,
|
|
groups = groups,
|
|
sound = { breaks = "default_tool_breaks" },
|
|
})
|
|
|
|
-- now register recipe
|
|
if def.recipe then
|
|
core.register_craft({
|
|
output = name:sub(2),
|
|
recipe = def.recipe,
|
|
})
|
|
elseif def.material then
|
|
core.register_craft({
|
|
output = name:sub(2),
|
|
recipe = {
|
|
{ def.material, "" },
|
|
{ "", def.material },
|
|
{ "group:stick", "" },
|
|
},
|
|
})
|
|
end
|
|
end
|