Module:Sandbox/Vergir: Difference between revisions

Vergir (talk | contribs)
Test copy of Module:AbilityTable with proposed per-prop Spirit scaling renderer inlined (with help from vergir-bot LLM)
Vergir (talk | contribs)
Use {{Ss}} badge in the Spirit Scaling cell; add plain-text dump for review (with help from vergir-bot LLM)
 
(One intermediate revision by the same user not shown)
Line 65: Line 65:
local function format_spirit(v)
local function format_spirit(v)
     return string.format("%.3g", v)
     return string.format("%.3g", v)
end
-- Formats one Spirit scaling for the table cell through the compact {{Ss}}
-- form, the same way RenderBarrier does. The template is expanded via the
-- frame the surrounding #invoke runs under, since module return values are
-- not re-expanded; the plain "×N" fallback covers a nil frame (module
-- console).
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
    return "×" .. text
end
end


Line 74: Line 91:


-- Renders Spirit Power scaling.
-- Renders Spirit Power scaling.
-- Lists every prop that scales with Spirit at base, one per line, labelled
-- Lists every prop that scales with Spirit at base, one per line as an {{Ss}}
-- with the prop's name from the ability card: "×0.55 (Base Damage)". Two
-- badge labelled with the prop's name from the ability card:
-- "x0.55 (Base Damage)". Two
-- props sharing a name are told apart by the card's Title
-- props sharing a name are told apart by the card's Title
-- ("Damage: Cost of Stay"); props the card does not list show their raw key.
-- ("Damage: Cost of Stay"); props the card does not list show their raw key.
Line 86: Line 104:


     local base  = spirit_scalings(ability, labels)
     local base  = spirit_scalings(ability, labels)
     local tiers = {}
     local tiers = {}   -- { tier = i, list = ... } in tier order
     local upgrades = ability["Upgrades"]
     local upgrades = ability["Upgrades"]
     if type(upgrades) == "table" then
     if type(upgrades) == "table" then
        -- ipairs rather than #: mw.loadJsonData tables have no length.
         for i, tier in ipairs(upgrades) do
         for i, tier in ipairs(upgrades) do
             if type(tier) == "table" then tiers[i] = spirit_scalings(tier, labels) end
             if type(tier) == "table" then
                table.insert(tiers, { tier = i, list = spirit_scalings(tier, labels) })
            end
         end
         end
     end
     end
Line 107: Line 128:
     end
     end
     note_keys(base)
     note_keys(base)
     for _, list in pairs(tiers) do note_keys(list) end
     for _, t in ipairs(tiers) do note_keys(t.list) end


     local function label_of(key)
     local function label_of(key)
Line 124: Line 145:
         local lines = {}
         local lines = {}
         for _, prop in ipairs(base) do
         for _, prop in ipairs(base) do
             table.insert(lines, "×" .. format_spirit(prop.value) .. " (" .. label_of(prop.key) .. ")")
             table.insert(lines, format_spirit_badge(prop.value) .. " (" .. label_of(prop.key) .. ")")
             running[prop.key] = prop.value
             running[prop.key] = prop.value
         end
         end
Line 131: Line 152:


     local notes = {}
     local notes = {}
     for i = 1, (type(upgrades) == "table" and #upgrades or 0) do
     for _, t in ipairs(tiers) do
         local list = tiers[i]
         local i, list = t.tier, t.list
         if list then
         local groups, group_order = {}, {}  -- Multiply upgrades, grouped by multiplier
            local groups, group_order = {}, {}  -- Multiply upgrades, grouped by multiplier
        for _, up in ipairs(list) do
            for _, up in ipairs(list) do
            local label  = label_of(up.key)
                local label  = label_of(up.key)
            local current = running[up.key]
                local current = running[up.key]
            if up.multiply then
                if up.multiply then
                local group = groups[up.value]
                    local group = groups[up.value]
                if not group then
                    if not group then
                    group = { labels = {}, totals = {} }
                        group = { labels = {}, totals = {} }
                    groups[up.value] = group
                        groups[up.value] = group
                    table.insert(group_order, up.value)
                        table.insert(group_order, up.value)
                end
                    end
                table.insert(group.labels, label)
                    table.insert(group.labels, label)
                if current then
                    if current then
                    running[up.key] = current * up.value
                        running[up.key] = current * up.value
                     table.insert(group.totals, "×" .. format_spirit(running[up.key]))
                        table.insert(group.totals, "×" .. format_spirit(running[up.key]))
                     else
                        table.insert(group.totals, "?")
                    end
                elseif current then
                    running[up.key] = current + up.value
                    table.insert(notes, "T" .. i .. " upgrade adds +×" .. format_spirit(up.value)
                        .. " " .. label .. " scaling (total ×" .. format_spirit(running[up.key]) .. ")")
                 else
                 else
                    running[up.key] = up.value
                     table.insert(group.totals, "?")
                     table.insert(notes, "T" .. i .. " upgrade grants ×" .. format_spirit(up.value)
                        .. " " .. label .. " scaling")
                 end
                 end
            elseif current then
                running[up.key] = current + up.value
                table.insert(notes, "T" .. i .. " upgrade adds +×" .. format_spirit(up.value)
                    .. " " .. label .. " scaling (total ×" .. format_spirit(running[up.key]) .. ")")
            else
                running[up.key] = up.value
                table.insert(notes, "T" .. i .. " upgrade grants ×" .. format_spirit(up.value)
                    .. " " .. label .. " scaling")
             end
             end
            for _, m in ipairs(group_order) do
        end
                local group = groups[m]
        for _, m in ipairs(group_order) do
                table.insert(notes, "T" .. i .. " upgrade multiplies " .. join_names(group.labels)
            local group = groups[m]
                    .. " scaling by " .. format_spirit(m)
            table.insert(notes, "T" .. i .. " upgrade multiplies " .. join_names(group.labels)
                    .. " (total " .. table.concat(group.totals, ", ") .. ")")
                .. " scaling by " .. format_spirit(m)
            end
                .. " (total " .. table.concat(group.totals, ", ") .. ")")
         end
         end
     end
     end
Line 656: Line 675:
     table.insert(out, "|}")
     table.insert(out, "|}")
     return table.concat(out, "\n")
     return table.concat(out, "\n")
end
-- TEST ONLY: plain-text dump of a list for review, one line per ability.
function p.dump(frame)
    local stat = mw.text.trim(frame.args[1] or ""):lower()
    local views, order = build_views()
    local spec = extra_columns[stat]
    local get_cells = spec and spec.get_cells or function() return {} end
    local out = {}
    for _, key in ipairs(order) do
        if p.is_member(stat, key) then
            local entry = views[key]
            local extra = get_cells(entry.view, entry.cardprops)
            local cell = extra["Spirit Scaling"] or "—"
            cell = mw.text.killMarkers(cell):gsub("<br>", " / "):gsub("<[^>]+>", "")
            table.insert(out, entry.heroName .. " | " .. entry.view["Name"] .. " | " .. cell .. " | " .. (extra["Notes"] or "—"))
        end
    end
    return "<pre>" .. mw.text.nowiki(table.concat(out, "\n")) .. "</pre>"
end
end


return p
return p