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 308: Line 308:
-- Formatting helpers
-- Formatting helpers
----------------------------------------------------------------------
----------------------------------------------------------------------
local function valuePairDynamicValueOnly(block, maxLevel, level)
if type(block) ~= "table" then
return nil
end
local base = block.Base
local per  = block["Per Level"]
-- Per Level list (expanded by wikiprep)
if type(per) == "table" then
if #per == 0 then
local baseText = formatUnitValue(base)
return baseText and mw.text.nowiki(baseText) or nil
end
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
local txt = valuePairRawText(block)
return txt and mw.text.nowiki(txt) or nil
end
local function formatSource(src, maxLevel, level)
if type(src) ~= "table" then
return nil
end
local kind = src.Type or "Damage"
local isHealing = (kind == "Healing") or (src.Healing == true)
local basis = basisLabel(src, isHealing)
if basis and mw.ustring.lower(tostring(basis)) == mw.ustring.lower(tostring(kind)) then
basis = nil -- avoid "Healing: X Healing"
end
local val = valuePairDynamicValueOnly(src, maxLevel, level)
if not val then
return nil
end
local out = mw.text.nowiki(tostring(kind)) .. ": " .. val
if basis then
out = out .. " " .. mw.text.nowiki(tostring(basis))
end
return out
end


local function basisLabel(entry, isHealing)
local function basisLabel(entry, isHealing)
Line 412: Line 470:
end
end


local function formatScaling(list, basisOverride)
local function formatScaling(scaling, basisOverride)
if type(list) ~= "table" or #list == 0 then
-- Accept {Percent=...} OR [{...},{...}]
if type(scaling) ~= "table" then
return nil
return nil
end
local list = scaling
if #list == 0 then
-- treat as single entry if it looks like one
if scaling.Percent ~= nil or scaling["Scaling ID"] or scaling["Scaling Name"] then
list = { scaling }
else
return nil
end
end
end


Line 691: Line 760:
for _, s in ipairs(list) do
for _, s in ipairs(list) do
if type(s) == "table" then
if type(s) == "table" then
local scope = s.Scope or "Target"
local typ  = s.Type or s.Scope or "Target"
local name = s["Status External Name"] or s["Status Internal Name"] or "Unknown status"
local name = s["Status External Name"] or s["Status Internal Name"] or "Unknown status"


local seg = scope .. " – " .. tostring(name)
local seg = tostring(typ) .. " – " .. tostring(name)
local detail = {}
local detail = {}


if type(s.Duration) == "table" then
if type(s.Duration) == "table" then
local t = valuePairDynamicText("Duration", s.Duration, maxLevel, level, "; ")
local t = valuePairDynamicText("Duration", s.Duration, maxLevel, level, "; ")
if t then
if t then table.insert(detail, t) end
table.insert(detail, t)
end
end
end


if type(s.Chance) == "table" then
if type(s.Chance) == "table" then
local t = valuePairDynamicText("Chance", s.Chance, maxLevel, level, "; ")
local t = valuePairDynamicText("Chance", s.Chance, maxLevel, level, "; ")
if t then
if t then table.insert(detail, t) end
table.insert(detail, t)
end
end
end


if s["Fixed Duration"] then
-- Fixed Duration removed intentionally
table.insert(detail, "Fixed duration")
end


if #detail > 0 then
if #detail > 0 then
Line 924: Line 987:
end
end


addChunk("Type",     typeBlock["Damage Type"])
-- NEW keys (with fallback to old keys so you don't hard-break on older JSON)
addChunk("Element",   typeBlock["Element Type"])
addChunk("Damage", typeBlock.Damage  or typeBlock["Damage Type"])
addChunk("Target",   typeBlock["Target Type"])
addChunk("Element", typeBlock.Element or typeBlock["Element Type"])
addChunk("Cast Type", typeBlock["Cast Type"])
addChunk("Target", typeBlock.Target  or typeBlock["Target Type"])
addChunk("Cast",   typeBlock.Cast    or typeBlock["Cast Type"])


if not added then
if not added then
Line 1,097: Line 1,161:
end
end


------------------------------------------------------------------
------------------------------------------------------------------
-- Damage & Scaling
-- Source (new unified Damage/Flat/Reflect/Healing) + Scaling
------------------------------------------------------------------
------------------------------------------------------------------
if type(rec.Source) == "table" then
addRow(root, "Source",  formatSource(rec.Source, maxLevel, level))
 
local basisOverride = (rec.Source.Type == "Healing" or rec.Source.Healing == true) and "Healing" or nil
addRow(root, "Scaling", formatScaling(rec.Source.Scaling, basisOverride))
 
else
-- BACKCOMPAT: old Damage block (safe to delete once all JSON is migrated)
local dmg = rec.Damage or {}
local dmg = rec.Damage or {}
if next(dmg) ~= nil then
if next(dmg) ~= nil then
Line 1,130: Line 1,202:
addRow(root, "Scaling", formatScaling(dmg.Scaling, pureHealing and "Healing" or nil))
addRow(root, "Scaling", formatScaling(dmg.Scaling, pureHealing and "Healing" or nil))
end
end
end


------------------------------------------------------------------
------------------------------------------------------------------