Difference between revisions of "Module:Infobox enchantment"
Jump to navigation
Jump to search
Demcookies (talk | contribs) m (Fix trim given encantment name) |
Demcookies (talk | contribs) m (Fix add math.ceil to the 'Max Level' where strengthCap is not divisible to int by strengthPerLevel) |
||
| Line 178: | Line 178: | ||
--Upper limit of the buff 'level' | --Upper limit of the buff 'level' | ||
args[l()] = "Max Level" | args[l()] = "Max Level" | ||
| − | args[d()] = enchant.strengthCap and tostring(enchant.strengthCap / enchant.strengthPerLevel) or "" | + | args[d()] = enchant.strengthCap and tostring(math.ceil(enchant.strengthCap / enchant.strengthPerLevel)) or "" |
args[l()] = "Debuff" | args[l()] = "Debuff" | ||
Latest revision as of 19:52, 11 June 2025
Documentation for this module may be created at Module:Infobox enchantment/doc
--#region Variables and Imports
local p = {}
---@type table<string, Item>
local itemsData = mw.loadData("Module:Items/data")
---@type table<string, Enchantment>
local enchantmentData = require("Module:Enchantment/data")
---@type table<string, CookingItem>
local cookingListData = mw.loadData("Module:CookingList/data")
local craftingAugmentingData = mw.loadData("Module:CraftingAugmenting/data")
local infobox = require("Module:Infobox")
local headerCount = 1
local labelCount = 1
local dataCount = 1
local MAX_SLOTS = {
["arrows"] = 5,
["body"] = 8,
["boots"] = 7,
["cape"] = 2,
["chisel"] = 8,
["christmas elf gear"] = 0,
["combat-talisman"] = 4,
["cookingset"] = 3,
["fishingset"] = 3,
["foragingset"] = 3,
["gloves"] = 7,
["hatchet"] = 8,
["helm"] = 8,
["hoe"] = 8,
["ladle"] = 8,
["legs"] = 8,
["miningset"] = 3,
["necklace"] = 6,
["pickaxe"] = 8,
["ring"] = 6,
["runecraftingset"] = 3,
["shield"] = 8,
["smithingset"] = 3,
["tacklebox"] = 8,
["tome"] = 0,
["tongs"] = 8,
["weapon"] = 8,
}
--#endregion
--#region Utility Functions
---Finds the first table entry in the given table with key and value matching given values.
---@param tables table<any, table> # The tables to search.
---@param keys any # The key or an array of keys to search for.
---@param values any # The value or an array of values to search for.
---@return table|nil # The first table entry with first matching key and value, or nil if none was found.
---@return any|nil # The key of the found table entry, or nil if none was found.
local function findByKeyVal(tables, keys, values)
if type(tables) ~= "table" then return nil end
keys = type(keys) == "table" and keys or {keys}
values = type(values) == "table" and values or {values}
for tblk, tbl in pairs(tables) do
for k, v in pairs(tbl) do
for _, key in ipairs(keys) do
for _, value in ipairs(values) do
if k == key and v == value then
return tbl, tblk
end
end
end
end
end
end
--#endregion
--#region Elements
local function clearInfoboxInstance()
infobox.clear()
headerCount = 1
labelCount = 1
dataCount = 1
end
local function h()
local s = "header" .. headerCount
headerCount = headerCount + 1
labelCount = headerCount
dataCount = headerCount
return s
end
local function sbreak()
local s = "sbreak" .. headerCount
headerCount = headerCount + 1
labelCount = headerCount
dataCount = headerCount
return s
end
local function l()
local s = "label" .. labelCount
dataCount = labelCount
labelCount = labelCount + 1
headerCount = labelCount
return s
end
local function d()
local s = "data" .. dataCount
dataCount = dataCount + 1
headerCount = dataCount
labelCount = dataCount
return s
end
local function sl()
local s = "s" .. l()
return s
end
local function sd()
local s = "s" .. d()
return s
end
--#endregion
--#region Generic Module Functions
---Formats the given URL to full play.idlescape.com URL.
local function fullUrl(url)
local newUrl = url
if url:sub(1, 4) == "http" or url:sub(1,2) == "[[" then
return newUrl
end
if url:sub(1, 1) ~= "/" then
newUrl = "/" .. newUrl
end
return "https://www.play.idlescape.com" .. newUrl
end
---Creates an image link for the given name and URL.
---@param name string # The name of the link and image.
---@param url string # The URL of the image.
---@param word boolean # Whether to include the name in the link, if falsy it will be an image only.
---@param size number|string # The size of the image.
---@return string
local function image(name, url, word, size)
size = size or 20
url = fullUrl(url)
return string.format(
'[[%s|<img src="%s" alt="%s" width="%d" height="%d"><span style="position:relative;top:1px;">%s</span>]]',
name, url, name, size, size, word and name or ""
)
end
local function dottedTooltip(name, tooltip)
return string.format(
'<span class="rt-commentedText tooltip tooltip-dotted" title="%s">%s</span>',
tooltip,
name
)
end
--#endregion
--#region Infobox Elements
---Creates an infobox for the given enchantment/buff.
---@param enchant Enchantment
---@return string
local function createInfobox(enchant, ingredientSources)
local args = {}
args.autoheaders = "y"
args.subbox = "no"
args.bodystyle = " "
args.title = enchant.name
args.image = image(enchant.name, enchant.buffIcon, false, 150)
--Upper limit of the buff 'level'
args[l()] = "Max Level"
args[d()] = enchant.strengthCap and tostring(math.ceil(enchant.strengthCap / enchant.strengthPerLevel)) or ""
args[l()] = "Debuff"
args[d()] = enchant.isDebuff and "Yes" or "No"
args[l()] = dottedTooltip(
"Prolonging",
"Is influenced by Prolonging? Prolonging has a chance to prevent an action from consuming a buff stack."
)
args[d()] = enchant.ignoreProlonging and "No" or "Yes"
args[l()] = dottedTooltip("Stack Multiplier", "Food cooked gets its buff stacks multiplied by this value")
args[d()] = enchant.stackMult and enchant.stackMult .. "x" or ""
if enchant.relatedSkills then
local relatedSkills = {}
for _, skill in ipairs(enchant.relatedSkills) do
table.insert(relatedSkills, (skill:gsub("^%l", string.upper)))
end
args[l()] = "Related Skills"
args[d()] = "[[" .. table.concat(relatedSkills, "]]<br>[[") .. "]]"
end
if enchant.scrollID then
local lang = mw.language.getContentLanguage()
local scroll = itemsData[tostring(enchant.scrollID)]
args[h()] = "Scroll"
args[l()] = image(scroll.name, scroll.itemImage, false, 40)
args[d()] = "[[" .. scroll.name .. "]]"
if scroll.categories then
local categories = {}
for _, category in ipairs(scroll.categories) do
local slots = MAX_SLOTS[category] or 0
local cat = category:gsub("set$"," Set"):gsub('-',' '):gsub("^%l", string.upper):gsub(" %l", string.upper)
cat = string.format("[[:Category:%s|%s]] (%s)", cat, cat, slots)
table.insert(categories, cat)
end
args[l()] = "Slot (Max)"
args[d()] = table.concat(categories, "<br>")
end
args[l()] = "Experience"
args[d()] = lang:formatNum(scroll.experience)
args[l()] = "Level"
args[d()] = scroll.level and tostring(scroll.level) or ""
local ca = craftingAugmentingData[tostring(enchant.scrollID)]
if ca and ca.scrollcrafting then
local items = {}
for itemId, amount in pairs(ca.scrollcrafting) do
table.insert(items, {id = itemId, amount = amount})
end
table.sort(items, function(a, b) return tonumber(a.id) < tonumber(b.id) end)
for i, t in ipairs(items) do
local item = itemsData[t.id]
items[i] = string.format(
"%s %s",
lang:formatNum(t.amount),
image(item.name, item.itemImage, true, 20)
)
end
args[l()] = "Cost"
args[d()] = table.concat(items, "<br>")
end
end
local _, ingredientId = findByKeyVal(
cookingListData,
{"alchemyEnchantment", "cookingEnchantment"},
enchant.id
)
local ingredient = itemsData[tostring(ingredientId)]
if ingredient then
args[h()] = "Cooking Ingredient"
args[d()] = image(ingredient.name, ingredient.itemImage, true, 40)
if ingredientSources then
local sources = {}
for s in ingredientSources:gmatch("[^,]+") do
table.insert(sources, (s:gsub("^%s*%[*(.-)%]*%s*$", "%1")))
end
args[l()] = "Source"
args[d()] = "[[" .. table.concat(sources, "]]<br>[[") .. "]]"
end
end
local description = enchant.getTooltip and enchant.getTooltip(1, enchant.strengthPerLevel) or enchant.desc
args[h()] = "Description"
args[d()] = '<p style="margin:auto;font-style:italic;font-size:1.2em">' .. description .. "</p>"
return infobox.infobox(args)
end
--#endregion
--#region Module Functions
function p.enchantment(frame)
local args = frame:getParent().args
return p._enchantment(args)
end
---Creates an infobox for the given ability or abilities found in a item.
---@param args {[1]: string|nil, name: string|nil, title: string|nil, ["food-source"]: string|nil}
function p._enchantment(args)
local name = args[1] or args.name or args.title or mw.title.getCurrentTitle().text
name = name:gsub("^%s*(.-)%s*$", "%1")
local enchant = findByKeyVal(enchantmentData, "name", name)
local ingredientSources = args["food-source"]
if enchant then
return createInfobox(enchant, ingredientSources)
else
return string.format(
'<span class="error">Enchantment "%s" not found.</span>',
name
)
end
end
--#endregion
return p