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 918: Line 918:
return nil
return nil
end
end
-- ============================================================
-- Module 3 – Skill Source (Source + Scaling)
-- - Shows Source (big) + Scaling (smaller list)
-- - If BOTH are missing, module 3 stays empty
-- ============================================================
-- Compact scaling list:
--  "1% Vitality"
--  "8% Intelligence"
local function formatScalingCompactLines(scaling, basisOverride)
if type(scaling) ~= "table" then
return {}
end
local list = scaling
if #list == 0 then
-- support "single dict" style scaling
if scaling.Percent ~= nil or scaling["Scaling ID"] or scaling["Scaling Name"] then
list = { scaling }
else
return {}
end
end
local out = {}
for _, s in ipairs(list) do
if type(s) == "table" then
local stat = s["Scaling Name"] or s["Scaling ID"] or "Unknown"
local pct  = s.Percent
local pctN = toNum(pct)
if pctN ~= nil and pctN ~= 0 then
table.insert(out, string.format("%s%% %s", fmtNum(pctN), stat))
elseif pct ~= nil and tostring(pct) ~= "" and tostring(pct) ~= "0" then
table.insert(out, string.format("%s%% %s", tostring(pct), stat))
end
end
end
return out
end
-- Prefer the “current level value” (and dynSpan when we have series lists)
-- Falls back gracefully if Source is not in the expanded-per-level-list form.
local function sourceValueForLevel(src, maxLevel, level)
if type(src) ~= "table" then
return nil
end
local base = src.Base
local per  = src["Per Level"]
-- Preferred: expanded series list (wikiprep)
if type(per) == "table" and #per > 0 then
if isFlatList(per) then
local one  = formatUnitValue(per[1]) or tostring(per[1])
local show = formatUnitValue(base) or one
return show and mw.text.nowiki(show) or nil
end
local series = {}
for _, v in ipairs(per) do
table.insert(series, formatUnitValue(v) or tostring(v))
end
return dynSpan(series, level)
end
-- Fallback: if we can’t build a proper series, use the existing “value only” formatter
-- (may look like "X (Per Level: Y)" if not expanded by wikiprep)
return valuePairDynamicValueOnly(src, maxLevel, level)
end
-- Legacy (pre-Source) damage entry: compute a simple % value at the current level
local function legacyPercentAtLevel(entry, level)
if type(entry) ~= "table" then
return nil
end
local baseRaw = entry["Base %"]
local perRaw  = entry["Per Level %"]
local baseN  = toNum(baseRaw)
local perN    = toNum(perRaw)
-- If Per Level exists, level 1 should show at least per*1 even when base is 0/missing.
if perN ~= nil and perN ~= 0 then
local total = (baseN or 0) + (perN * level)
return fmtNum(total) .. "%"
end
-- Otherwise show base if present
if baseN ~= nil then
return fmtNum(baseN) .. "%"
end
if baseRaw ~= nil and tostring(baseRaw) ~= "" then
return tostring(baseRaw) .. "%"
end
return nil
end
local function buildModuleSkillSource(rec, level, maxLevel)
local sourceKind = nil
local sourceVal  = nil
local scaling    = nil
-- Preferred: new unified Source block
if type(rec.Source) == "table" then
local src = rec.Source
sourceKind = src.Type or ((src.Healing == true) and "Healing") or "Damage"
sourceVal  = sourceValueForLevel(src, maxLevel, level)
scaling    = src.Scaling
end
-- Backcompat: legacy Damage block
if (sourceVal == nil or sourceVal == "") and type(rec.Damage) == "table" then
local dmg = rec.Damage
scaling = scaling or dmg.Scaling
local main = dmg["Main Damage"]
local refl = dmg["Reflect Damage"]
local flat = dmg["Flat Damage"]
-- priority: Main Damage > Reflect > Flat > Healing-only main
if type(main) == "table" and #main > 0 then
-- pick first non-healing if possible
local pick = nil
for _, d in ipairs(main) do
if type(d) == "table" and d.Type ~= "Healing" then
pick = d
break
end
end
pick = pick or main[1]
if type(pick) == "table" then
sourceKind = (pick.Type == "Healing") and "Healing" or "Damage"
sourceVal  = legacyPercentAtLevel(pick, level)
end
elseif type(refl) == "table" and #refl > 0 and type(refl[1]) == "table" then
sourceKind = "Reflect"
sourceVal  = legacyPercentAtLevel(refl[1], level)
elseif type(flat) == "table" and #flat > 0 and type(flat[1]) == "table" then
sourceKind = "Flat"
sourceVal  = legacyPercentAtLevel(flat[1], level)
end
end
local scalingLines = formatScalingCompactLines(scaling)
local hasSource    = (sourceVal ~= nil and tostring(sourceVal) ~= "")
local hasScaling  = (type(scalingLines) == "table" and #scalingLines > 0)
-- RULE: if neither exists, leave module 3 empty
if (not hasSource) and (not hasScaling) then
return nil
end
local wrap = mw.html.create("div")
wrap:addClass("sv-source-grid")
-- Source column (left)
if hasSource then
local left = wrap:tag("div"):addClass("sv-source-col"):addClass("sv-source-main")
left:tag("div"):addClass("sv-source-title"):wikitext(mw.text.nowiki(sourceKind or "Source"))
left:tag("div"):addClass("sv-source-value"):wikitext(sourceVal)
end
-- Scaling column (right)
if hasScaling then
local right = wrap:tag("div"):addClass("sv-source-col"):addClass("sv-source-scaling")
right:tag("div"):addClass("sv-scaling-title"):wikitext("Scaling")
local list = right:tag("div"):addClass("sv-scaling-list")
for _, line in ipairs(scalingLines) do
list:tag("div")
:addClass("sv-scaling-item")
:wikitext(mw.text.nowiki(line))
end
end
-- If only one side exists, let CSS make it single-column
local extra = { "skill-source-module" }
if hasSource ~= hasScaling then
table.insert(extra, "sv-source-only")
end
return moduleBox(3, extra, tostring(wrap), false)
end


local grid = mw.html.create("div")
local grid = mw.html.create("div")
Line 954: Line 1,142:
grid:wikitext(buildModuleLevelSelector(level, maxLevel))
grid:wikitext(buildModuleLevelSelector(level, maxLevel))
grid:wikitext(buildModuleSkillType(rec.Type or {}))
grid:wikitext(buildModuleSkillType(rec.Type or {}))
grid:wikitext(buildEmptyModule(3))
    local m3 = buildModuleSkillSource(rec, level, maxLevel)
    grid:wikitext(m3 or buildEmptyModule(3))
grid:wikitext(buildEmptyModule(4))
grid:wikitext(buildEmptyModule(4))