Refactor enchanting tool registration

This commit is contained in:
Wuzzy 2024-12-01 19:54:45 +01:00
parent 06c2c9881a
commit ed5b525dd8

View File

@ -3,6 +3,8 @@ local S = minetest.get_translator("xdecor")
local FS = function(...) return minetest.formspec_escape(S(...)) end
local ceil, abs, random = math.ceil, math.abs, math.random
local reg_tools = minetest.registered_tools
local reg_enchantable_tools = {}
local available_tool_enchants = {}
-- Cost in Mese crystal(s) for enchanting.
local mese_cost = 1
@ -14,10 +16,6 @@ local enchanting = {
damages = 1, -- Sharpness
}
local function cap(str) return
str:gsub("^%l", string.upper)
end
local function to_percent(orig_value, final_value)
return abs(ceil(((final_value - orig_value) / orig_value) * 100))
end
@ -40,7 +38,7 @@ function enchanting:get_tooltip(enchant, orig_caps, fleshy)
bonus.damages = to_percent(fleshy, fleshy + enchanting.damages)
end
local specs = { -- not finished, to complete
local specs = {
durable = {"#00baff", " (+" .. bonus.durable .. "%)"},
fast = {"#74ff49", " (+" .. bonus.efficiency .. "%)"},
sharp = {"#ffff00", " (+" .. bonus.damages .. "%)"},
@ -58,12 +56,12 @@ function enchanting:get_tooltip(enchant, orig_caps, fleshy)
end
local enchant_buttons = {
"image_button[3.6,0.67;4.75,0.85;bg_btn.png;fast;"..FS("Efficiency").."]" ..
"image_button[3.6,1.65;4.75,1.05;bg_btn.png;durable;"..FS("Durability").."]",
"image_button[3.6,2.8;4.75,0.85;bg_btn.png;sharp;"..FS("Sharpness").."]",
fast = "image_button[3.6,0.67;4.75,0.85;bg_btn.png;fast;"..FS("Efficiency").."]",
durable = "image_button[3.6,1.65;4.75,1.05;bg_btn.png;durable;"..FS("Durability").."]",
sharp = "image_button[3.6,2.8;4.75,0.85;bg_btn.png;sharp;"..FS("Sharpness").."]",
}
function enchanting.formspec(pos, num)
function enchanting.formspec(pos, enchants)
local meta = minetest.get_meta(pos)
local formspec = [[
size[9,8.6;]
@ -85,22 +83,20 @@ function enchanting.formspec(pos, num)
.."tooltip[fast;"..FS("Your tool digs faster").."]"
..default.gui_slots .. default.get_hotbar_bg(0.55, 4.5)
formspec = formspec .. (enchant_buttons[num] or "")
if enchants then
for e=1, #enchants do
formspec = formspec .. enchant_buttons[enchants[e]]
end
end
meta:set_string("formspec", formspec)
end
function enchanting.on_put(pos, listname, _, stack)
if listname == "tool" then
local stackname = stack:get_name()
local tool_groups = {
"axe, pick, shovel",
"sword",
}
for idx, tools in ipairs(tool_groups) do
if tools:find(stackname:match(":(%w+)")) then
enchanting.formspec(pos, idx)
end
local enchants = available_tool_enchants[stackname]
if enchants then
enchanting.formspec(pos, enchants)
end
end
end
@ -140,12 +136,13 @@ function enchanting.blast(pos)
end
local function allowed(tool)
if not tool then return end
for item in pairs(reg_tools) do
if item:find("enchanted_" .. tool) then
return true
end
if not tool then
return false
end
if reg_enchantable_tools[tool] then
return true
else
return false
end
end
@ -154,7 +151,7 @@ function enchanting.put(_, listname, _, stack)
if listname == "mese" and (stackname == "default:mese_crystal" or
stackname == "imese:industrial_mese_crystal") then
return stack:get_count()
elseif listname == "tool" and allowed(stackname:match("[^:]+$")) then
elseif listname == "tool" and allowed(stackname) then
return 1
end
@ -278,69 +275,100 @@ minetest.register_lbm({
end,
})
function enchanting:register_tools(mod, def)
for tool in pairs(def.tools) do
for material in def.materials:gmatch("[%w_]+") do
for enchant in def.tools[tool].enchants:gmatch("[%w_]+") do
local original_tool = reg_tools[mod .. ":" .. tool .. "_" .. material]
if not original_tool then break end
local original_toolcaps = original_tool.tool_capabilities
function enchanting:register_tool(original_tool_name, def)
local original_tool = reg_tools[original_tool_name]
if not original_tool then
minetest.log("error", "[xdecor] Called enchanting:register_tool for non-existing tool: "..original_too_name)
return
end
local original_toolcaps = original_tool.tool_capabilities
if not original_toolcaps then
minetest.log("error", "[xdecor] Called enchanting:register_tool for tool without tool_capabilities: "..original_too_name)
return
end
local original_damage_groups = original_toolcaps.damage_groups
local original_groupcaps = original_toolcaps.groupcaps
local original_basename = original_tool_name:match(".*:(.*)")
for _, enchant in ipairs(def.enchants) do
local groupcaps = table.copy(original_groupcaps)
local fleshy = original_damage_groups.fleshy
local full_punch_interval = original_toolcaps.full_punch_interval
local max_drop_level = original_toolcaps.max_drop_level
local dig_group = def.dig_group
if original_toolcaps then
local original_damage_groups = original_toolcaps.damage_groups
local original_groupcaps = original_toolcaps.groupcaps
local groupcaps = table.copy(original_groupcaps)
local fleshy = original_damage_groups.fleshy
local full_punch_interval = original_toolcaps.full_punch_interval
local max_drop_level = original_toolcaps.max_drop_level
local group = next(original_groupcaps)
if enchant == "durable" then
groupcaps[group].uses = ceil(original_groupcaps[group].uses *
enchanting.uses)
elseif enchant == "fast" then
for i, time in pairs(original_groupcaps[group].times) do
groupcaps[group].times[i] = time - enchanting.times
end
elseif enchant == "sharp" then
fleshy = fleshy + enchanting.damages
if enchant == "durable" then
groupcaps[dig_group].uses = ceil(original_groupcaps[dig_group].uses *
enchanting.uses)
elseif enchant == "fast" then
for i, time in pairs(original_groupcaps[dig_group].times) do
groupcaps[dig_group].times[i] = time - enchanting.times
end
elseif enchant == "sharp" then
fleshy = fleshy + enchanting.damages
else
minetest.log("error", "[xdecor] Called enchanting:register_tool with unsupported enchant: "..tostring(enchant))
return
end
local arg1 = def.material_desc[material] or cap(material)
local arg2 = def.tools[tool].desc or cap(tool)
local arg3 = self:get_tooltip(enchant, original_groupcaps[group], fleshy)
local enchantedTool = mod .. ":enchanted_" .. tool .. "_" .. material .. "_" .. enchant
minetest.register_tool(":" .. enchantedTool, {
description = S("Enchanted @1 @2\n@3", arg1, arg2, arg3),
short_description = S("Enchanted @1 @2", arg1, arg2),
inventory_image = original_tool.inventory_image .. "^[colorize:violet:50",
wield_image = original_tool.wield_image,
groups = {not_in_creative_inventory = 1},
tool_capabilities = {
groupcaps = groupcaps, damage_groups = {fleshy = fleshy},
full_punch_interval = full_punch_interval,
max_drop_level = max_drop_level
}
})
if minetest.get_modpath("toolranks") then
toolranks.add_tool(enchantedTool)
end
local arg1 = def.material_desc
local arg2 = def.desc
local arg3 = self:get_tooltip(enchant, original_groupcaps[dig_group], fleshy)
local enchantedTool = original_tool.mod_origin .. ":enchanted_" .. original_basename .. "_" .. enchant
local invimg = original_tool.inventory_image
if invimg == nil or invimg == "" then
invimg = "no_texture.png"
else
invimg = "("..invimg.. ")^[colorize:violet:50"
end
local wieldimg = original_tool.wield_image
if wieldimg == nil or wieldimg == "" then
wieldimg = invimg
end
minetest.register_tool(":" .. enchantedTool, {
description = S("Enchanted @1 @2\n@3", arg1, arg2, arg3),
short_description = S("Enchanted @1 @2", arg1, arg2),
inventory_image = invimg,
wield_image = wieldimg,
groups = {not_in_creative_inventory = 1},
tool_capabilities = {
groupcaps = groupcaps, damage_groups = {fleshy = fleshy},
full_punch_interval = full_punch_interval,
max_drop_level = max_drop_level
}
})
if minetest.get_modpath("toolranks") then
toolranks.add_tool(enchantedTool)
end
end
end
end
available_tool_enchants[original_tool_name] = table.copy(def.enchants)
reg_enchantable_tools[original_tool_name] = true
end
enchanting:register_tools("default", {
materials = "steel, bronze, mese, diamond",
material_desc = {steel = S("Steel"), bronze = S("Bronze"), mese = S("Mese"), diamond = S("Diamond")},
tools = {
axe = {enchants = "durable, fast", desc = S("Axe")},
pick = {enchants = "durable, fast", desc = S("Pickaxe")},
shovel = {enchants = "durable, fast", desc = S("Shovel")},
sword = {enchants = "sharp", desc = S("Sword")}
},
})
-- Register enchantments for default tools
local materials = {"steel", "bronze", "mese", "diamond"}
local tooltypes = {
{ "axe", { "durable", "fast" }, "choppy" },
{ "pick", { "durable", "fast" }, "cracky" },
{ "shovel", { "durable", "fast" }, "crumbly" },
{ "sword", { "sharp" }, nil },
}
for t=1, #tooltypes do
for m=1, #materials do
local tooltype = tooltypes[t][1]
local enchants = tooltypes[t][2]
local dig_group = tooltypes[t][3]
local material = materials[m]
enchanting:register_tool("default:"..tooltype.."_"..material, {
enchants = enchants,
dig_group = dig_group,
-- dummy
material_desc = material,
desc = tooltype,
})
end
end
-- Recipes