|
|
| Line 1: |
Line 1: |
| -- Audit: for every item stat that goes through Infobox item's append_label
| |
| -- with attribute styling enabled (Passive/Active Main stats), compute the
| |
| -- label link target under the CURRENT priority (attr link > StatLinks)
| |
| -- and the PROPOSED priority (StatLinks > attr link), and classify the change.
| |
| local p = {} | | local p = {} |
| local lang = require "Module:Lang"
| |
| local data = mw.loadJsonData("Data:ItemCards.json")
| |
| local stat_links = mw.loadJsonData("Data:StatLinks.json")
| |
| local ATTR = require("Module:Icon/attr")
| |
|
| |
| local LABEL_KEY_REMAP = { DotDuration = "DOTDuration" }
| |
| local IGNORED = { BuildUpPerShot = true }
| |
|
| |
| -- Keys whose StatLinks entry is worse than the current type link.
| |
| -- Proposed StatLinks fix noted alongside.
| |
| local STATLINKS_FIX = {
| |
| SlowPercent = "Movement Slow",
| |
| MaxSlowPercent = "Movement Slow",
| |
| }
| |
| local DEBATABLE = {
| |
| GroundDashReductionPercent = true,
| |
| }
| |
|
| |
| local function get_pair(base, s1, s2)
| |
| local v = lang.get_string(base .. s1)
| |
| if v and v ~= "" then return v end
| |
| v = lang.get_string(base .. s2)
| |
| if v and v ~= "" then return v end
| |
| return ""
| |
| end
| |
|
| |
| local function resolve_label_key(prop_key, loc_override)
| |
| local base = (loc_override or prop_key):gsub("^#", "")
| |
| return LABEL_KEY_REMAP[base] or base
| |
| end
| |
|
| |
| local function norm(s)
| |
| if s == nil or s == "" then return nil end
| |
| return (tostring(s):gsub("_", " "))
| |
| end
| |
|
| |
| -- Resolve a title through one redirect hop; returns final page name
| |
| local resolve_cache = {}
| |
| local function resolve(t)
| |
| if t == nil then return nil end
| |
| if resolve_cache[t] == nil then
| |
| local title = mw.title.new(t)
| |
| local r = t
| |
| if title and title.exists and title.isRedirect then
| |
| local tgt = title.redirectTarget
| |
| if tgt then r = tgt.prefixedText end
| |
| elseif not title or not title.exists then
| |
| r = t .. " (MISSING)"
| |
| end
| |
| resolve_cache[t] = r
| |
| end
| |
| return resolve_cache[t]
| |
| end
| |
|
| |
| local function fmt_value(label_key, value, label)
| |
| local n = tonumber(tostring(value):match("^-?%d+%.?%d*"))
| |
| if not n then return label end
| |
| local prefix = get_pair(label_key, "_prefix", "_Prefix")
| |
| local postfix = get_pair(label_key, "_postfix", "_Postfix")
| |
| if prefix == "{s:sign}" then prefix = n >= 0 and "+" or "" end
| |
| local s = tostring(n)
| |
| if prefix ~= "" then s = prefix .. s end
| |
| if postfix ~= "" then s = s .. (postfix == "HP/s" and " " or "") .. postfix end
| |
| return s .. " " .. label
| |
| end
| |
|
| |
| function p.audit(frame)
| |
| local names = {}
| |
| for key, item in pairs(data) do
| |
| if not item.IsDisabled then table.insert(names, key) end
| |
| end
| |
| table.sort(names, function(a, b)
| |
| return (data[a].Name or a) < (data[b].Name or b)
| |
| end)
| |
|
| |
| local rows = {}
| |
| local counts = {}
| |
| local n_items, n_stats, n_same = 0, 0, 0
| |
| for _, key in ipairs(names) do
| |
| local item = data[key]
| |
| n_items = n_items + 1
| |
| local i = 1
| |
| while item["Info" .. i] do
| |
| local sec = item["Info" .. i]
| |
| if sec.Type ~= "Innate" then
| |
| local seen = {}
| |
| for _, obj in ipairs(sec.Main or {}) do
| |
| local pk = obj.Key
| |
| if not seen[pk] and not IGNORED[pk] and not pk:match("^StatusEffect") then
| |
| seen[pk] = true
| |
| local label_key = resolve_label_key(pk, obj.LocTokenOverride)
| |
| local label = get_pair(label_key, "_label", "_Label")
| |
| if label ~= "" then
| |
| n_stats = n_stats + 1
| |
| local attr = obj.Type and ATTR[obj.Type] or nil
| |
| local attr_link = norm(attr and attr.link)
| |
| local sl = norm(stat_links[label_key])
| |
| local cur = attr_link or sl
| |
| local new = sl or attr_link
| |
| if (cur or "") == (new or "") then
| |
| n_same = n_same + 1
| |
| else
| |
| local kind
| |
| if STATLINKS_FIX[label_key] then
| |
| kind = "Regression → fixed via StatLinks (" .. label_key .. " = " .. STATLINKS_FIX[label_key] .. ")"
| |
| elseif DEBATABLE[label_key] then
| |
| kind = "Debatable"
| |
| elseif resolve(cur) == resolve(new) then
| |
| kind = "NOP (redirect to same page)"
| |
| else
| |
| kind = "Fix"
| |
| end
| |
| counts[kind] = (counts[kind] or 0) + 1
| |
| table.insert(rows, string.format(
| |
| "|-\n| [[%s]] || %s || [[%s]] || [[%s]] || %s",
| |
| item.Name or key, fmt_value(label_key, obj.Value, label),
| |
| cur or "", new or "", kind))
| |
| end
| |
| end
| |
| end
| |
| end
| |
| end
| |
| i = i + 1
| |
| end
| |
| end
| |
|
| |
| local out = {}
| |
| table.insert(out, string.format(
| |
| "Items scanned: %d. Passive/Active main stats with a label: %d. Unchanged: %d. Changed: %d.\n",
| |
| n_items, n_stats, n_same, #rows))
| |
| local ks = {}
| |
| for k in pairs(counts) do table.insert(ks, k) end
| |
| table.sort(ks)
| |
| for _, k in ipairs(ks) do table.insert(out, string.format("* %s: %d", k, counts[k])) end
| |
| table.insert(out, '{| class="wikitable sortable"\n! Item !! Label !! Current target !! Proposed target !! Type')
| |
| for _, r in ipairs(rows) do table.insert(out, r) end
| |
| table.insert(out, "|}")
| |
| return table.concat(out, "\n")
| |
| end
| |
|
| |
| return p | | return p |