Module:GameSkills: Difference between revisions
From SpiritVale Wiki
More actions
No edit summary |
No edit summary |
||
| Line 92: | Line 92: | ||
end | end | ||
end | end | ||
if v == nil then | if v == nil then | ||
return nil | return nil | ||
| Line 138: | Line 139: | ||
---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ||
local function | local function isFlatList(list) | ||
if type( | if type(list) ~= "table" or #list == 0 then | ||
return false | return false | ||
end | end | ||
local first = tostring(list[1]) | |||
local first = tostring( | for i = 2, #list do | ||
for i = 2, # | if tostring(list[i]) ~= first then | ||
if tostring( | |||
return false | return false | ||
end | end | ||
end | end | ||
return true | |||
if | end | ||
return | |||
local function isNonZeroScalar(v) | |||
if v == nil then return false end | |||
if type(v) == "number" then return v ~= 0 end | |||
if type(v) == "string" then | |||
local n = tonumber(v) | |||
if n == nil then | |||
return v ~= "" | |||
end | |||
return n ~= 0 | |||
end | |||
if type(v) == "table" and v.Value ~= nil then | |||
return isNonZeroScalar(v.Value) | |||
end | end | ||
return true | return true | ||
end | end | ||
local function | -- Turns a {Base, Per Level} block into lines: | ||
-- - If Per Level is a list: "Name: v1 / v2 / v3 ..." | |||
-- - Else: "Name: BaseValue" and (if non-zero) "Name Per Level: PerValue" | |||
local function valuePairLines(name, block) | |||
if type(block) ~= "table" then | if type(block) ~= "table" then | ||
return | return {} | ||
end | end | ||
| Line 165: | Line 179: | ||
local per = block["Per Level"] | local per = block["Per Level"] | ||
-- Per Level list (already expanded by wikiprep) | |||
-- Per Level | |||
if type(per) == "table" then | if type(per) == "table" then | ||
if | if #per == 0 then | ||
local baseText = formatUnitValue(base) | |||
if baseText then | if baseText then | ||
return " | return { string.format("%s: %s", name, baseText) } | ||
end | end | ||
if per[1] | return {} | ||
return " | end | ||
-- If it's a flat list, treat as "no scaling" (show single value) | |||
if isFlatList(per) then | |||
local baseText = formatUnitValue(base) | |||
local one = tostring(per[1]) | |||
local show = baseText or one | |||
if show then | |||
return { string.format("%s: %s", name, show) } | |||
end | end | ||
return | return {} | ||
end | end | ||
local | local vals = {} | ||
for _, v in ipairs(per) do | |||
table.insert( | table.insert(vals, formatUnitValue(v) or tostring(v)) | ||
end | end | ||
if #vals == 0 then | |||
return {} | |||
end | end | ||
return table.concat( | return { string.format("%s: %s", name, table.concat(vals, " / ")) } | ||
end | |||
if | -- Scalar Per Level | ||
local lines = {} | |||
local baseText = formatUnitValue(base) | |||
local perText = formatUnitValue(per) | |||
if baseText then | |||
table.insert(lines, string.format("%s: %s", name, baseText)) | |||
end | |||
if perText and isNonZeroScalar(per) then | |||
table.insert(lines, string.format("%s Per Level: %s", name, perText)) | |||
end | |||
return lines | |||
end | |||
local function valuePairText(name, block, sep) | |||
local lines = valuePairLines(name, block) | |||
if #lines == 0 then | |||
return nil | |||
end | |||
return table.concat(lines, sep or "<br />") | |||
end | |||
-- When you already have a label outside and just want the values. | |||
local function valuePairRawText(block) | |||
if type(block) ~= "table" then | |||
return nil | |||
end | |||
local base = block.Base | |||
local per = block["Per Level"] | |||
if type(per) == "table" then | |||
if #per == 0 then | |||
return formatUnitValue(base) | |||
end | end | ||
if per | if isFlatList(per) then | ||
return formatUnitValue(base) or tostring(per[1]) | |||
end | end | ||
local vals = {} | |||
for _, v in ipairs(per) do | |||
table.insert(vals, formatUnitValue(v) or tostring(v)) | |||
end | end | ||
return table.concat( | return (#vals > 0) and table.concat(vals, " / ") or nil | ||
end | |||
local baseText = formatUnitValue(base) | |||
local perText = formatUnitValue(per) | |||
if baseText and perText and isNonZeroScalar(per) then | |||
return string.format("%s (Per Level: %s)", baseText, perText) | |||
end | end | ||
return baseText or perText | |||
end | end | ||
| Line 305: | Line 367: | ||
end | end | ||
-- Area: Distance then Size, no Effective Distance | |||
local function formatArea(area) | local function formatArea(area) | ||
if type(area) ~= "table" then | if type(area) ~= "table" then | ||
| Line 310: | Line 373: | ||
end | end | ||
local parts = {} | local parts = {} | ||
local distLine = valuePairText("Distance", area["Area Distance"], "<br />") | |||
if distLine then | |||
table.insert(parts, distLine) | |||
end | |||
local size = area["Area Size"] | local size = area["Area Size"] | ||
if size and size ~= "" then | if size and size ~= "" then | ||
table.insert(parts, "Size: " .. tostring(size)) | table.insert(parts, "Size: " .. tostring(size)) | ||
end | end | ||
| Line 341: | Line 396: | ||
local parts = {} | local parts = {} | ||
local function add( | local function add(label, key) | ||
local block = bt[key] | local block = bt[key] | ||
local | if type(block) ~= "table" then | ||
return | |||
table.insert(parts, | end | ||
local lines = valuePairLines(label, block) | |||
for _, line in ipairs(lines) do | |||
table.insert(parts, line) | |||
end | end | ||
end | end | ||
| Line 375: | Line 433: | ||
local parts = {} | local parts = {} | ||
local | local manaLines = valuePairLines("MP", rc["Mana Cost"]) | ||
for _, line in ipairs(manaLines) do | |||
table.insert(parts, | table.insert(parts, line) | ||
end | end | ||
local | local hpLines = valuePairLines("HP", rc["Health Cost"]) | ||
for _, line in ipairs(hpLines) do | |||
table.insert(parts, | table.insert(parts, line) | ||
end | end | ||
| Line 435: | Line 493: | ||
local block = effects[name] | local block = effects[name] | ||
if type(block) == "table" then | if type(block) == "table" then | ||
local | -- Keep each effect to a single line when possible | ||
local txt = valuePairText(name, block, ", ") | |||
if | if txt then | ||
table.insert(parts, txt) | |||
end | end | ||
end | end | ||
end | end | ||
| Line 497: | Line 554: | ||
local dur = s.Duration | local dur = s.Duration | ||
if type(dur) == "table" then | if type(dur) == "table" then | ||
local t = | local t = valuePairText("Duration", dur, "; ") | ||
if t then | if t then | ||
table.insert(detail, | table.insert(detail, t) | ||
end | end | ||
end | end | ||
| Line 505: | Line 562: | ||
local ch = s.Chance | local ch = s.Chance | ||
if type(ch) == "table" then | if type(ch) == "table" then | ||
local t = | local t = valuePairText("Chance", ch, "; ") | ||
if t then | if t then | ||
table.insert(detail, | table.insert(detail, t) | ||
end | end | ||
end | end | ||
| Line 545: | Line 602: | ||
end | end | ||
local | local amt = valuePairRawText(r) | ||
local seg = label | local seg = label | ||
if | if amt then | ||
seg = seg .. " – " .. | seg = seg .. " – " .. amt | ||
end | end | ||
table.insert(parts, seg) | table.insert(parts, seg) | ||
| Line 611: | Line 668: | ||
if listHas(users.Events) then return true end | if listHas(users.Events) then return true end | ||
return false | |||
end | |||
---------------------------------------------------------------------- | |||
-- Direct page detection (hide Users on the skill's own page) | |||
---------------------------------------------------------------------- | |||
local function isDirectSkillPage(rec) | |||
if type(rec) ~= "table" then | |||
return false | |||
end | |||
local pageTitle = mw.title.getCurrentTitle() | |||
local pageName = pageTitle and pageTitle.text or "" | |||
pageName = trim(pageName) | |||
if not pageName then | |||
return false | |||
end | |||
pageName = mw.ustring.lower(pageName) | |||
local ext = trim(rec["External Name"] or rec["Name"] or rec["Display Name"]) | |||
local internal = trim(rec["Internal Name"] or rec["InternalName"] or rec["InternalID"]) | |||
if ext and mw.ustring.lower(ext) == pageName then | |||
return true | |||
end | |||
if internal and mw.ustring.lower(internal) == pageName then | |||
return true | |||
end | |||
return false | return false | ||
end | end | ||
| Line 618: | Line 704: | ||
---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ||
local function buildInfobox(rec) | local function buildInfobox(rec, opts) | ||
opts = opts or {} | |||
local showUsers = (opts.showUsers ~= false) | |||
local root = mw.html.create("table") | local root = mw.html.create("table") | ||
root:addClass("wikitable spiritvale-skill-infobox") | root:addClass("wikitable spiritvale-skill-infobox") | ||
| Line 666: | Line 755: | ||
addRow(root, "Max level", rec["Max Level"] and tostring(rec["Max Level"])) | addRow(root, "Max level", rec["Max Level"] and tostring(rec["Max Level"])) | ||
local users = rec.Users or {} | -- Hide Users when the skill is rendered on its own page | ||
if showUsers then | |||
local users = rec.Users or {} | |||
addRow(root, "Classes", listToText(users.Classes)) | |||
addRow(root, "Summons", listToText(users.Summons)) | |||
addRow(root, "Monsters", listToText(users.Monsters)) | |||
addRow(root, "Events", listToText(users.Events)) | |||
end | |||
------------------------------------------------------------------ | ------------------------------------------------------------------ | ||
| Line 856: | Line 948: | ||
for _, rec in ipairs(matches) do | for _, rec in ipairs(matches) do | ||
root:wikitext(buildInfobox(rec)) | root:wikitext(buildInfobox(rec, { showUsers = true })) | ||
end | end | ||
| Line 918: | Line 1,010: | ||
end | end | ||
return buildInfobox(rec) | -- Hide Users only when rendered on the skill's own page | ||
local showUsers = not isDirectSkillPage(rec) | |||
return buildInfobox(rec, { showUsers = showUsers }) | |||
end | end | ||
return p | return p | ||