Minetest_Game_Mushroom_Fork/mods/specific to Mushroom Fork/mushroom_tools/init.lua

492 lines
17 KiB
Lua

-- mushroom_tools mod for Minetest
-- Copyright © 2020 Alex Yst <mailto:copyright@y.st>
-- This program 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 software 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 program. If not, see
-- <https://www.gnu.org./licenses/>.
-- This script includes code copied from the fire mod bundled as a part
-- of Minetest game. That mod was provided by the following people:
-- Originally by RealBadAngel, Maciej Kasatkin (LGPLv2.1+)
-- Various Minetest developers and contributors (LGPLv2.1+)
local colour = {
brown = minetest.get_color_escape_sequence("#6d544e"),
red = minetest.get_color_escape_sequence("#c36666"),
}
local function repair_tool(itemstack, player, old_craft_grid, craft_inv)
local tooldef = itemstack:get_definition()
if itemstack:get_name():sub(1, 15) == "mushroom_tools:" and tooldef.type == "tool" then
-- We gather a list of tools in the recipe that match the type of the
-- output. If there are two such tools, and no other items are
-- included, this is probably a tool repair recipe, so we should modify
-- the repair count. Repair count is pretty meaningless in-game, but
-- gives an idea of how much the tool has been kept and cared for. It's
-- just a sort of bonus feature for players.
local input_tools = {}
local input_count = 0
for _, item in next, old_craft_grid do
if not item:is_empty() then
input_count = input_count + 1
if item:get_name() == itemstack:get_name() then
input_tools[#input_tools+1] = item
end
end
end
if #input_tools == 2 and input_count == 2 then
local meta = itemstack:get_meta()
if itemstack:get_wear() == 0 then
meta:set_string("description", colour.red..tooldef.description..colour.brown.."\n(mangled)")
itemstack:set_name("mushroom_tools:mangled")
else
local repair_count = 1
for _, tool in next, input_tools do
local old_meta = tool:get_meta()
repair_count = repair_count + old_meta:get_int("repair")
end
meta:set_int("repair", repair_count)
meta:set_string("description", colour.red..tooldef.description..colour.brown.."\n(repair count: "..repair_count..")")
end
return itemstack
end
end
end
minetest.register_craft_predict(repair_tool)
minetest.register_on_craft(repair_tool)
-- Mushroom swords guarantee sapling drops and mushroom shovels
-- guarantee flint drops.
--
-- TO DO: This functionality is going to be removed from mushroom
-- swords and shovels and added as a potential buff for rune swords and
-- shovels.
for node, toolset in next, {
["default:acacia_bush_leaves" ] = {"mushroom_tools:sword"},
["default:acacia_leaves" ] = {"mushroom_tools:sword"},
["default:aspen_leaves" ] = {"mushroom_tools:sword"},
["default:blueberry_bush_leaves"] = {"mushroom_tools:sword"},
["default:bush_leaves" ] = {"mushroom_tools:sword"},
["default:gravel" ] = {"mushroom_tools:shovel"},
["default:junglegrass" ] = {"mushroom_tools:sword"},
["default:jungleleaves" ] = {"mushroom_tools:sword"},
["default:leaves" ] = {"mushroom_tools:sword"},
["default:pine_bush_needles" ] = {"mushroom_tools:sword"},
["default:pine_needles" ] = {"mushroom_tools:sword"},
} do
local old_drop = minetest.registered_nodes[node].drop.items
local new_drop_table = {
max_items = 1,
items = {
{
items = old_drop[1].items,
tools = toolset,
},
},
}
for index, drop in next, old_drop do
new_drop_table.items[index+1] = drop
end
minetest.override_item(node, {
drop = new_drop_table,
})
end
minetest.register_craftitem("mushroom_tools:lump_brown", {
description = "Brown Mushroom Lump",
inventory_image = "mushroom_tools.lump_brown.png",
})
minetest.register_craftitem("mushroom_tools:lump_red", {
description = "Red Mushroom Lump",
inventory_image = "mushroom_tools.lump_red.png",
})
minetest.register_craftitem("mushroom_tools:ingot_brown", {
description = "Brown Mushroom Ingot",
inventory_image = "mushroom_tools.ingot_brown.png",
})
minetest.register_craftitem("mushroom_tools:ingot_red", {
description = "Red Mushroom Ingot",
inventory_image = "mushroom_tools.ingot_red.png",
})
minetest.register_craftitem("mushroom_tools:mangled", {
description = "Mangled Mushroom Tool",
inventory_image = "mushroom_tools.mangled.png",
})
minetest.register_craft({
type = "cooking",
output = "mushroom_tools:ingot_brown",
recipe = "mushroom_tools:lump_brown",
cooktime = 99,
})
minetest.register_craft({
type = "cooking",
output = "mushroom_tools:ingot_red",
recipe = "mushroom_tools:lump_red",
cooktime = 99,
})
minetest.register_tool("mushroom_tools:pick", {
description = "Mushroom Pickaxe",
inventory_image = "mushroom_tools.pick.png",
tool_capabilities = {
full_punch_interval = 0.9,
max_drop_level=3,
groupcaps={
cracky = {times={[1]=2.0, [2]=1.0, [3]=0.50}, uses=2427, maxlevel=3},
},
damage_groups = {fleshy=5},
},
sound = {breaks = "default_tool_breaks"},
groups = {pickaxe = 1},
})
-- TO DO: This functionality is going to be removed from mushroom
-- shovels and added as a potential buff to rune shovels.
local spread_function
for _, ABM in next, minetest.registered_abms do
if ABM.mod_origin == "default" and ABM.label == "Grass spread" then
spread_function = ABM.action
end
end
minetest.register_tool("mushroom_tools:shovel", {
description = "Mushroom Shovel",
inventory_image = "mushroom_tools.shovel.png",
wield_image = "mushroom_tools.shovel.png^[transformR90",
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level=1,
groupcaps={
crumbly = {times={[1]=1.10, [2]=0.50, [3]=0.30}, uses=2427, maxlevel=3},
},
damage_groups = {fleshy=4},
},
sound = {breaks = "default_tool_breaks"},
groups = {shovel = 1},
on_place = function(itemstack, user, pointed_thing)
local target = minetest.get_node(pointed_thing.under)
if target.name == "default:dirt" then
spread_function(pointed_thing.under, target)
elseif minetest.registered_nodes[target.name]
and minetest.registered_nodes[target.name].on_rightclick then
return minetest.registered_nodes[target.name].on_rightclick(pointed_thing.under, target, user, itemstack, pointed_thing)
end
end,
})
minetest.register_tool("mushroom_tools:axe", {
description = "Mushroom Axe",
inventory_image = "mushroom_tools.axe.png",
tool_capabilities = {
full_punch_interval = 0.9,
max_drop_level=1,
groupcaps={
choppy={times={[1]=2.10, [2]=0.90, [3]=0.50}, uses=2427, maxlevel=3},
},
damage_groups = {fleshy=7},
},
sound = {breaks = "default_tool_breaks"},
groups = {axe = 1},
})
-- TO DO: This functionality is going to be removed from mushroom
-- swords and added as a potential buff to rune swords.
local prunable_trunk = {
["default:tree"] = {
leaves = {"default:apple", "default:apple_mark", "default:leaves"},
range = 3,
},
["default:jungletree"] = {
leaves = {"default:jungleleaves"},
range = 2,
},
["default:pine_tree"] = {
leaves = {"default:pine_needles"},
range = 3,
},
["default:acacia_tree"] = {
leaves = {"default:acacia_leaves"},
range = 2,
},
["default:aspen_tree"] = {
leaves = {"default:aspen_leaves"},
range = 3,
},
["default:bush_stem"] = {
leaves = {"default:bush_leaves"},
range = 1,
},
["default:acacia_bush_stem"] = {
leaves = {"default:acacia_bush_leaves"},
range = 1,
},
["default:pine_bush_stem"] = {
leaves = {"default:pine_bush_needles"},
range = 1,
},
}
minetest.register_tool("mushroom_tools:sword", {
description = "Mushroom Sword",
inventory_image = "mushroom_tools.sword.png",
tool_capabilities = {
full_punch_interval = 0.7,
max_drop_level=1,
groupcaps={
snappy={times={[1]=1.90, [2]=0.90, [3]=0.30}, uses=2427, maxlevel=3},
},
damage_groups = {fleshy=8},
},
sound = {breaks = "default_tool_breaks"},
groups = {sword = 1},
on_place = function(itemstack, user, pointed_thing)
local potential_log = minetest.get_node(pointed_thing.under)
if prunable_trunk[potential_log.name] then
local to_prune = minetest.find_nodes_in_area({
x = pointed_thing.under.x - prunable_trunk[potential_log.name].range,
y = pointed_thing.under.y - prunable_trunk[potential_log.name].range,
z = pointed_thing.under.z - prunable_trunk[potential_log.name].range,
}, {
x = pointed_thing.under.x + prunable_trunk[potential_log.name].range,
y = pointed_thing.under.y + prunable_trunk[potential_log.name].range,
z = pointed_thing.under.z + prunable_trunk[potential_log.name].range,
}, prunable_trunk[potential_log.name].leaves)
for _, pos in next, to_prune do
local node = minetest.get_node(pos)
minetest.node_dig(pos, node, user)
-- Apple marks are dealt with separately because minetest.node_dig()
-- doesn't work on them. It's probably because players can't normally
-- dig them. We also assume that apples have left behind apple marks
-- and remove those as well.
if node.name == "default:apple_mark"
or node.name == "default:apple" then
minetest.remove_node(pos)
end
end
-- This seems a bit unclean, but I'm not sure how else to handle the
-- situation. If no value is returned, Minetest restores the tool's
-- durability that was used to prune the leaves because it sets the
-- item stack to what it was before the player used this functionality.
-- On the other hand, if we return the itemstack the engine passed to
-- our callback, we've just restored the durability ourselves because
-- that copy came from before the tool was used to prune the leaves.
-- Likewise, we shouldn't manually add the wear ourselves because we
-- don't know if each leaf was harvested successfully or not (for
-- example, an area might be protected). The only thing to do seems to
-- be to get the item now wielded and return it, basically overwriting
-- the worn item with whatever the player now holds, which should
-- hopefully always be itself (or an empty stack if it broke).
return user:get_wielded_item()
elseif minetest.registered_nodes[potential_log.name]
and minetest.registered_nodes[potential_log.name].on_rightclick then
return minetest.registered_nodes[potential_log.name].on_rightclick(pointed_thing.under, potential_log, user, itemstack, pointed_thing)
end
end,
})
minetest.register_tool("mushroom_tools:screwdriver", {
description = "Mushroom Screwdriver\n(left-click rotates face, right-click rotates axis)",
inventory_image = "mushroom_tools.screwdriver.png",
groups = {tool = 1},
on_use = function(itemstack, user, pointed_thing)
screwdriver.handler(itemstack, user, pointed_thing, screwdriver.ROTATE_FACE, 65536)
return itemstack
end,
on_place = function(itemstack, user, pointed_thing)
screwdriver.handler(itemstack, user, pointed_thing, screwdriver.ROTATE_AXIS, 65536)
return itemstack
end,
})
local function new_tool_itemstring(tool_name)
local tool = ItemStack(tool_name)
local meta = tool:get_meta()
local tooldef = tool:get_definition()
meta:set_int("repair", 0)
meta:set_string("description", colour.red..tooldef.description..colour.brown.."\n(repair count: 0)")
return tool:to_string()
end
minetest.register_craft({
output = new_tool_itemstring("mushroom_tools:pick"),
recipe = {
{"mushroom_tools:ingot_red", "mushroom_tools:ingot_red", "mushroom_tools:ingot_red"},
{"", "mushroom_tools:ingot_brown", ""},
{"", "mushroom_tools:ingot_brown", ""},
}
})
minetest.register_craft({
output = new_tool_itemstring("mushroom_tools:shovel"),
recipe = {
{"mushroom_tools:ingot_red"},
{"mushroom_tools:ingot_brown"},
{"mushroom_tools:ingot_brown"},
}
})
minetest.register_craft({
output = new_tool_itemstring("mushroom_tools:axe"),
recipe = {
{"mushroom_tools:ingot_red", "mushroom_tools:ingot_red"},
{"mushroom_tools:ingot_red", "mushroom_tools:ingot_brown"},
{"", "mushroom_tools:ingot_brown"},
}
})
minetest.register_craft({
output = new_tool_itemstring("mushroom_tools:sword"),
recipe = {
{"mushroom_tools:ingot_red"},
{"mushroom_tools:ingot_red"},
{"mushroom_tools:ingot_brown"},
}
})
minetest.register_craft({
output = new_tool_itemstring("mushroom_tools:screwdriver"),
recipe = {
{"mushroom_tools:ingot_red"},
{"mushroom_tools:ingot_brown"}
}
})
-----------------------------------------------------------------------
-- SHAMELESSLY COPIED VERBATIM FROM THE FIRE MOD, WITH ONLY THE WEAR
-- AMOUNT ALTERED. CREDIT GOES TO:
-- Originally by RealBadAngel, Maciej Kasatkin (LGPLv2.1+)
-- Various Minetest developers and contributors (LGPLv2.1+)
-----------------------------------------------------------------------
minetest.register_tool("mushroom_tools:fire_starter", {
description = "Mushroom Fire Starter",
inventory_image = "mushroom_tools.fire_starter.png",
sound = {breaks = "default_tool_breaks"},
on_use = function(itemstack, user, pointed_thing)
local sound_pos = pointed_thing.above or user:get_pos()
minetest.sound_play(
"fire_flint_and_steel",
{pos = sound_pos, gain = 0.5, max_hear_distance = 8}
)
local player_name = user:get_player_name()
if pointed_thing.type == "node" then
local node_under = minetest.get_node(pointed_thing.under).name
local nodedef = minetest.registered_nodes[node_under]
if not nodedef then
return
end
if minetest.is_protected(pointed_thing.under, player_name) then
minetest.chat_send_player(player_name, "This area is protected")
return
end
if nodedef.on_ignite then
nodedef.on_ignite(pointed_thing.under, user)
elseif minetest.get_item_group(node_under, "flammable") >= 1
and minetest.get_node(pointed_thing.above).name == "air" then
minetest.set_node(pointed_thing.above, {name = "fire:basic_flame"})
end
end
if not (creative and creative.is_enabled_for
and creative.is_enabled_for(player_name)) then
-- Wear tool
local wdef = itemstack:get_definition()
itemstack:add_wear(1)
-- Tool break sound
if itemstack:get_count() == 0 and wdef.sound and wdef.sound.breaks then
minetest.sound_play(wdef.sound.breaks, {pos = sound_pos, gain = 0.5})
end
return itemstack
end
end,
})
minetest.register_craft({
output = new_tool_itemstring("mushroom_tools:fire_starter"),
recipe = {
{"mushroom_tools:ingot_brown", "mushroom_tools:ingot_red"}
}
})
minetest.register_craft({
output = new_tool_itemstring("mushroom_tools:lump_brown"),
recipe = {
{"piled:mushroom_brown", "piled:mushroom_brown", "piled:mushroom_brown"},
{"piled:mushroom_brown", "piled:mushroom_brown", "piled:mushroom_brown"},
{"piled:mushroom_brown", "piled:mushroom_brown", "piled:mushroom_brown"},
}
})
minetest.register_craft({
output = new_tool_itemstring("mushroom_tools:lump_red"),
recipe = {
{"piled:mushroom_red", "piled:mushroom_red", "piled:mushroom_red"},
{"piled:mushroom_red", "piled:mushroom_red", "piled:mushroom_red"},
{"piled:mushroom_red", "piled:mushroom_red", "piled:mushroom_red"},
}
})
--[[
MOVE THIS SECTION TO THE OTHER MOD!!
Update: The "other mod" was mushroom_tools_extended, which was
discontinued before release. Instead, something similar might get added
as a buff to the rune screwdriver or other rune tool.
-- Given a node name, we need to be able to look up what time-based
-- functions apply to it. Time-based functions are registered as either
-- on_timer() callbacks or ABMs. on_timer() callbacks can obviously be
-- looked up by node name easily, but to look up an ABM, we'd need to
-- search the entire table of ABMs every time and check each one
-- individually to see if it applies. That is, unless we index the ABMs
-- in terms of what nodes they apply to before we need to do any
-- lookups. Let's do that now.
local ABM_index = {}
minetest.register_on_mods_loaded(function()
for _, ABM in next, minetest.registered_abms do
local applies_to = {}
for _, affected_node in next, ABM.nodenames do
if affected_node:sub(1, 6) == "group:" then
local groups = affected_node:sub(7):split(",")
for node_name, _ in next, minetest.registered_nodes do
local is_in_groups = true
for _, group in next, groups do
if minetest.get_item_group(node_name, group) == 0 then
is_in_groups = false
end
end
if is_in_groups then
applies_to[node_name] = true
end
end
else
applies_to[affected_node] = true
end
end
for affected_node, _ in next, applies_to do
ABM_index[affected_node] = ABM_index[affected_node] or {}
ABM_index[affected_node][#ABM_index[affected_node] + 1] = ABM
end
end
end)
]]