Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Join the Playtest on Steam Now: SpiritVale

Module:GameSkills: Difference between revisions

From SpiritVale Wiki
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 isFlatPerLevel(baseStr, perList)
local function isFlatList(list)
if type(perList) ~= "table" or #perList == 0 then
if type(list) ~= "table" or #list == 0 then
return false
return false
end
end
-- If all per-level entries are identical, treat as "no scaling"
local first = tostring(list[1])
local first = tostring(perList[1])
for i = 2, #list do
for i = 2, #perList do
if tostring(list[i]) ~= first then
if tostring(perList[i]) ~= first then
return false
return false
end
end
end
end
-- If base matches that identical value, definitely flat/no-op
return true
if baseStr ~= nil and tostring(baseStr) == first then
end
return true
 
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
-- Even if base differs (sometimes Base is "0" but Lv list is constant), still no meaningful scaling
return true
return true
end
end


local function formatBasePer(block)
-- 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 nil
return {}
end
end


Line 165: Line 179:
local per  = block["Per Level"]
local per  = block["Per Level"]


local baseText = (base ~= nil) and formatUnitValue(base) or nil
-- Per Level list (already expanded by wikiprep)
 
-- Per Level might be a scalar OR list (wikiprep expansion)
if type(per) == "table" then
if type(per) == "table" then
if isFlatPerLevel(baseText, per) then
if #per == 0 then
-- Show only Base (or Lv1 if Base is missing)
local baseText = formatUnitValue(base)
if baseText then
if baseText then
return "Base: " .. baseText
return { string.format("%s: %s", name, baseText) }
end
end
if per[1] ~= nil then
return {}
return "Lv1: " .. tostring(per[1])
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 nil
return {}
end
end


local lines = {}
local vals = {}
if baseText then
for _, v in ipairs(per) do
table.insert(lines, "Base: " .. baseText)
table.insert(vals, formatUnitValue(v) or tostring(v))
end
end
for i, v in ipairs(per) do
if #vals == 0 then
table.insert(lines, string.format("Lv%d: %s", i, tostring(v)))
return {}
end
end
return table.concat(lines, "<br />")
return { string.format("%s: %s", name, table.concat(vals, " / ")) }
else
end
local parts = {}
 
if baseText then
-- Scalar Per Level
table.insert(parts, "Base " .. baseText)
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 ~= nil then
if isFlatList(per) then
table.insert(parts, tostring(per) .. " / Lv")
return formatUnitValue(base) or tostring(per[1])
end
end
if #parts == 0 then
local vals = {}
return nil
for _, v in ipairs(per) do
table.insert(vals, formatUnitValue(v) or tostring(v))
end
end
return table.concat(parts, ", ")
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
local dist = area["Area Distance"]
local eff  = area["Effective Distance"]
local distText = formatBasePer(dist)
if distText then
table.insert(parts, "Distance: " .. distText)
end
local effText = formatUnitValue(eff)
if effText then
table.insert(parts, "Effective: " .. effText)
end
end


Line 341: Line 396:
local parts = {}
local parts = {}


local function add(name, key)
local function add(label, key)
local block = bt[key]
local block = bt[key]
local txt = formatBasePer(block)
if type(block) ~= "table" then
if txt then
return
table.insert(parts, name .. ": " .. txt)
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 manaTxt = formatBasePer(rc["Mana Cost"])
local manaLines = valuePairLines("MP", rc["Mana Cost"])
if manaTxt then
for _, line in ipairs(manaLines) do
table.insert(parts, "MP: " .. manaTxt)
table.insert(parts, line)
end
end


local hpTxt = formatBasePer(rc["Health Cost"])
local hpLines = valuePairLines("HP", rc["Health Cost"])
if hpTxt then
for _, line in ipairs(hpLines) do
table.insert(parts, "HP: " .. hpTxt)
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 bp = formatBasePer(block)
-- Keep each effect to a single line when possible
local seg = name
local txt = valuePairText(name, block, ", ")
if bp then
if txt then
seg = seg .. " – " .. bp
table.insert(parts, txt)
end
end
table.insert(parts, seg)
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 = formatBasePer(dur)
local t = valuePairText("Duration", dur, "; ")
if t then
if t then
table.insert(detail, "Duration " .. t)
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 = formatBasePer(ch)
local t = valuePairText("Chance", ch, "; ")
if t then
if t then
table.insert(detail, "Chance " .. t)
table.insert(detail, t)
end
end
end
end
Line 545: Line 602:
end
end


local bp = formatBasePer(r)
local amt = valuePairRawText(r)
local seg = label
local seg = label
if bp then
if amt then
seg = seg .. " – " .. bp
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
addRow(root, "Classes",  listToText(users.Classes))
if showUsers then
addRow(root, "Summons",  listToText(users.Summons))
local users = rec.Users or {}
addRow(root, "Monsters", listToText(users.Monsters))
addRow(root, "Classes",  listToText(users.Classes))
addRow(root, "Events",  listToText(users.Events))
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