| Latest revision |
Your text |
| Line 410: |
Line 410: |
| end | | end |
|
| |
|
| -- ============================================================ | | -- Renders Spirit Power scaling. |
| -- Spirit scaling helpers
| | -- Shows the Scale.Value for abilities whose Scale.Type is "spirit". |
| -- ============================================================ | | function p.RenderSpiritScaling(ability) |
| | local base_scale = nil |
| | local base_prop = nil |
|
| |
|
| -- Spirit scaling entry of a prop, or nil. Scale is a single { Value, Type } | | -- Find base Spirit scaling |
| -- or an array of them (e.g. a duration scaling with both Spirit and duration).
| | for k, v in pairs(ability) do |
| local function spirit_scale(v)
| | if k ~= "Upgrades" and type(v) == "table" then |
| if type(v) ~= "table" then return nil end
| | local scale = v["Scale"] |
| local scale = v["Scale"]
| | if type(scale) == "table" |
| if type(scale) ~= "table" then return nil end
| | and scale["Type"] == "spirit" |
| if scale[1] == nil then
| | and type(scale["Value"]) == "number" |
| if scale["Type"] == "spirit" then return scale end
| | and scale["Value"] ~= 0 then |
| return nil
| | base_scale = scale["Value"] |
| end
| | base_prop = k |
| for _, entry in ipairs(scale) do
| | break |
| if type(entry) == "table" and entry["Type"] == "spirit" then return entry end
| |
| end
| |
| return nil
| |
| end
| |
| | |
| -- Non-zero Spirit scalings of one layer (base record or upgrade tier) as
| |
| -- { key, value, multiply }, in card order; props not on the card last, by key.
| |
| local function spirit_scalings(layer, labels)
| |
| local out = {}
| |
| for k, v in pairs(layer) do
| |
| if k ~= "Upgrades" and tostring(k):sub(1, 1) ~= "_" then
| |
| local s = spirit_scale(v)
| |
| if s and type(s["Value"]) == "number" and s["Value"] ~= 0 then
| |
| table.insert(out, { | |
| key = k,
| |
| value = s["Value"],
| |
| multiply = s["Multiply"] == true,
| |
| }) | |
| end | | end |
| end | | end |
| end | | end |
| table.sort(out, function(a, b)
| |
| local oa = labels[a.key] and labels[a.key].order or math.huge
| |
| local ob = labels[b.key] and labels[b.key].order or math.huge
| |
| if oa ~= ob then return oa < ob end
| |
| return a.key < b.key
| |
| end)
| |
| return out
| |
| end
| |
|
| |
|
| -- Formats a scaling value to 3 significant figures, as the ability cards do.
| | local cells = {} |
| local function format_spirit(v) | |
| return string.format("%.3g", v)
| |
| end
| |
|
| |
|
| -- Compact {{Ss}} badge for the cell, expanded via the current frame like
| | if base_scale then |
| -- format_barrier; plain "×N" when there is no frame (module console).
| | cells["Spirit Scaling"] = "×" .. base_scale |
| local function format_spirit_badge(v)
| |
| local text = format_spirit(v)
| |
| local frame = mw.getCurrentFrame()
| |
| if frame then | |
| return frame:expandTemplate{ | |
| title = "Ss",
| |
| args = { text, compact = "1", show_value = "1" },
| |
| }
| |
| end | | end |
| return "×" .. text
| |
| end
| |
|
| |
|
| -- "A", "A and B", "A, B and C".
| | local upgrades = ability["Upgrades"] |
| local function join_names(names) | | if type(upgrades) ~= "table" then return cells end |
| if #names <= 1 then return names[1] or "" end
| | |
| return table.concat(names, ", ", 1, #names - 1) .. " and " .. names[#names] | | local notes = {} |
| end
| |
|
| |
|
| -- Renders Spirit Power scaling: one {{Ss}} badge per scaling prop, labelled from
| | for i, tier in ipairs(upgrades) do |
| -- the card ("x0.55 (Base Damage)"; "Damage: Cost of Stay" when names collide;
| | if type(tier) == "table" then |
| -- raw key when the card lacks it). The Upgrades cell lists upgrades per prop
| | local upgrade_scale = nil |
| -- with running totals; Multiply upgrades multiply the current scaling, as the
| |
| -- ability-upgrade gadget does.
| |
| function p.RenderSpiritScaling(ability, cardprops)
| |
| local labels = cardprops or {}
| |
|
| |
|
| local base = spirit_scalings(ability, labels)
| | for k, v in pairs(tier) do |
| local tiers = {} -- { tier = i, list = ... } in tier order
| | if type(v) == "table" then |
| local upgrades = ability["Upgrades"]
| | local scale = v["Scale"] |
| if type(upgrades) == "table" then
| | if type(scale) == "table" |
| -- ipairs rather than #: mw.loadJsonData tables have no length.
| | and scale["Type"] == "spirit" |
| for i, tier in ipairs(upgrades) do
| | and type(scale["Value"]) == "number" |
| if type(tier) == "table" then
| | and scale["Value"] ~= 0 then |
| table.insert(tiers, { tier = i, list = spirit_scalings(tier, labels) }) | | upgrade_scale = scale["Value"] |
| | break |
| | end |
| | end |
| end | | end |
| end
| |
| end
| |
|
| |
|
| -- Props sharing a Name get their Title appended so they can be told apart.
| | if upgrade_scale then |
| local keys_by_name = {}
| | table.insert(notes, |
| local function note_keys(list)
| | "on T" .. i .. " gets +×" .. upgrade_scale .. " Spirit scaling") |
| for _, prop in ipairs(list) do
| |
| local info = labels[prop.key]
| |
| if info then
| |
| keys_by_name[info.name] = keys_by_name[info.name] or {}
| |
| keys_by_name[info.name][prop.key] = true
| |
| end | | end |
| end | | end |
| end
| |
| note_keys(base)
| |
| for _, t in ipairs(tiers) do note_keys(t.list) end
| |
|
| |
| local function label_of(key)
| |
| local info = labels[key]
| |
| if not info then return key end
| |
| local n = 0
| |
| for _ in pairs(keys_by_name[info.name] or {}) do n = n + 1 end
| |
| if n > 1 and info.title then return info.name .. ": " .. info.title end
| |
| return info.name
| |
| end
| |
|
| |
| local cells = {}
| |
| local running = {} -- prop key -> current total scaling
| |
|
| |
| if #base > 0 then
| |
| local lines = {}
| |
| for _, prop in ipairs(base) do
| |
| table.insert(lines, format_spirit_badge(prop.value) .. " (" .. label_of(prop.key) .. ")")
| |
| running[prop.key] = prop.value
| |
| end
| |
| cells["Spirit Scaling"] = table.concat(lines, "<br>")
| |
| end | | end |
|
| |
|
| local lines = {} | | if #notes > 0 then |
| for _, t in ipairs(tiers) do
| | cells["Notes"] = table.concat(notes, ". ") |
| local i, list = t.tier, t.list
| |
| local groups, group_order = {}, {} -- Multiply upgrades, grouped by multiplier
| |
| for _, up in ipairs(list) do
| |
| local label = label_of(up.key)
| |
| local current = running[up.key]
| |
| if up.multiply then
| |
| local group = groups[up.value]
| |
| if not group then
| |
| group = { labels = {}, totals = {} }
| |
| groups[up.value] = group
| |
| table.insert(group_order, up.value)
| |
| end
| |
| table.insert(group.labels, label)
| |
| if current then
| |
| running[up.key] = current * up.value
| |
| table.insert(group.totals, format_spirit_badge(running[up.key]))
| |
| else
| |
| table.insert(group.totals, "?")
| |
| end
| |
| elseif current then
| |
| running[up.key] = current + up.value
| |
| table.insert(lines, "T" .. i .. " adds ×" .. format_spirit(up.value) .. " " .. label
| |
| .. " scaling (total " .. format_spirit_badge(running[up.key]) .. ")")
| |
| else
| |
| running[up.key] = up.value
| |
| table.insert(lines, "T" .. i .. " grants " .. format_spirit_badge(up.value) .. " " .. label .. " scaling")
| |
| end
| |
| end
| |
| for _, m in ipairs(group_order) do
| |
| local group = groups[m]
| |
| table.insert(lines, "T" .. i .. " multiplies " .. join_names(group.labels)
| |
| .. " scaling by " .. format_spirit(m)
| |
| .. " (total " .. table.concat(group.totals, ", ") .. ")")
| |
| end
| |
| end | | end |
|
| |
|
| if #lines > 0 then cells["Upgrades"] = table.concat(lines, "<br>") end
| |
| return cells | | return cells |
| end | | end |