Module:StreetBrawlItems: Difference between revisions

Vergir (talk | contribs)
mNo edit summary
Vergir (talk | contribs)
Remove unused item/item_in_pool functions and now-dead helpers; rename normal to average; move all display text to the caller; anchor the gate above the Tier 1 heading so the reveal link lands on it (with help from vergir-bot LLM)
Line 10: Line 10:
local CARD_SIZE = "0.667"
local CARD_SIZE = "0.667"


local NAME_TO_KEY, KEY_TO_NAME, RELEASED = {}, {}, {}
local NAME_TO_KEY = {}
for key, h in pairs(heroes) do
for key, h in pairs(heroes) do
if type(h) == "table" and h.Name then
if type(h) == "table" and h.Name then
KEY_TO_NAME[key] = h.Name
NAME_TO_KEY[mw.ustring.lower(h.Name)] = key
NAME_TO_KEY[mw.ustring.lower(h.Name)] = key
if not h.InDevelopment and not h.IsDisabled then RELEASED[key] = true end
end
end
end
end
Line 60: Line 58:
if itier(code) ~= 5 then args.showTierTag = "true" end
if itier(code) ~= 5 then args.showTierTag = "true" end
return frame:expandTemplate{title = "ItemBox", args = args}
return frame:expandTemplate{title = "ItemBox", args = args}
end
local function render_hero(frame, key)
local name = KEY_TO_NAME[key]; if not name then return nil end
return frame:expandTemplate{title = "HeroIcon", args = {name}}
end
end


Line 91: Line 85:
end
end


-- Returns sorted high (favored), normal (pool), low (unfavored) item-code lists for a tier.
-- Returns sorted high (favored), average (pool), low (unfavored) item-code lists for a tier.
local function collect(hkey, tier)
local function collect(hkey, tier)
local favored, unfavored = hero_sets(hkey)
local favored, unfavored = hero_sets(hkey)
local high, normal, low = {}, {}, {}
local high, average, low = {}, {}, {}
for _, c in ipairs(sb.AvailableItems) do
for _, c in ipairs(sb.AvailableItems) do
if iok(c) and (tier == nil or itier(c) == tier) then
if iok(c) and (tier == nil or itier(c) == tier) then
if favored[c] then high[#high + 1] = c
if favored[c] then high[#high + 1] = c
elseif unfavored[c] then low[#low + 1] = c
elseif unfavored[c] then low[#low + 1] = c
else normal[#normal + 1] = c end
else average[#average + 1] = c end
end
end
end
end
table.sort(high, item_less)
table.sort(high, item_less)
table.sort(normal, item_less)
table.sort(average, item_less)
table.sort(low, item_less)
table.sort(low, item_less)
return high, normal, low
return high, average, low
end
 
local function item_code(input)
input = mw.text.trim(input or "")
if input == "" then return nil end
if items[input] then return input end
for k, v in pairs(items) do
if type(v) == "table" and v.Name == input and v.IsDisabled ~= true then return k end
end
for k, v in pairs(items) do
if type(v) == "table" and v.Name == input then return k end
end
return nil
end
end


-- Builds one tier as conditional columns:
-- Builds one tier as conditional columns:
--  High chance (favored) takes 35%, the middle column fills the rest.
--  High chance (favored) takes 35%, the average column fills the rest.
--  Low chance (unfavored) is dropped when empty; a narrow column on the right when
--  Low chance (unfavored) is dropped when empty; a narrow column on the right when
--  High is present; a fit-content column on the right when High is absent.
--  High is present; a fit-content column on the right when High is absent.
local function tier_columns(frame, hkey, tier, hi, mid, lo)
local function tier_columns(frame, hkey, tier, hi, avg, lo)
local high, normal, low = collect(hkey, tier)
local high, average, low = collect(hkey, tier)


local function col(codes, cls, head)
local function col(codes, cls, head)
Line 141: Line 122:
out[#out + 1] = col(high, "sb-col-high sb-w-high", hi)
out[#out + 1] = col(high, "sb-col-high sb-w-high", hi)
end
end
out[#out + 1] = col(normal, "sb-col-normal sb-w-fill", mid)
out[#out + 1] = col(average, "sb-col-average sb-w-fill", avg)
if #low > 0 then
if #low > 0 then
local low_w = (#high > 0) and "sb-low-narrow" or "sb-low-wide"
local low_w = (#high > 0) and "sb-low-narrow" or "sb-low-wide"
Line 149: Line 130:
end
end


-- {{#invoke:StreetBrawlItems|tiers|HERO|high=..|middle=..|low=..|gate=ID}}
-- {{#invoke:StreetBrawlItems|tiers|HERO|gate=ID|high=..|average=..|low=..|tier1=..|...|tier5=..}}
-- All five tiers under styled (non-TOC) headings. With gate=ID, everything from
-- All five tiers under styled (non-TOC) headings. All display text is supplied by the
-- the Tier 1 columns onward is wrapped in an open <div id=ID class="sb-gate">
-- caller. With gate=ID, the Tier 1 heading and everything after it is wrapped in an open
-- <div class="sb-gate-body"> that the caller must close after any trailing content.
-- <div id=ID class="sb-gate">, whose inner <div class="sb-gate-body"> the caller must
-- close after any trailing content. The id sits on the outer wrapper so following the
-- anchor lands on the Tier 1 heading rather than the columns below it.
function p.tiers(frame)
function p.tiers(frame)
local hkey = hero_key(frame.args[1]); if not hkey then return "" end
local hkey = hero_key(frame.args[1]); if not hkey then return "" end
local hi = frame.args.high or "High chance"
local hi = frame.args.high or ""
local mid = frame.args.middle or "Average chance"
local avg = frame.args.average or ""
local lo = frame.args.low or "Low chance"
local lo = frame.args.low or ""
local gate = frame.args.gate
local gate = frame.args.gate
if gate == "" then gate = nil end
if gate == "" then gate = nil end


local labels = { "Tier 1", "Tier 2", "Tier 3", "Tier 4", "Legendary" }
local out = {}
local out = {}
for t = 1, 5 do
for t = 1, 5 do
local head = heading_div(labels[t])
local head = heading_div(frame.args["tier" .. t] or "")
local cols = tier_columns(frame, hkey, t, hi, mid, lo)
local cols = tier_columns(frame, hkey, t, hi, avg, lo)
if t == 1 and gate then
if t == 1 and gate then
out[#out + 1] = head .. "\n"
out[#out + 1] = '<div id="' .. gate .. '" class="sb-gate">\n'
.. '<div id="' .. gate .. '" class="sb-gate"><div class="sb-gate-body">\n'
.. head .. "\n"
.. '<div class="sb-gate-body">\n'
.. cols
.. cols
else
else
Line 198: Line 181:
out[#out + 1] = classdiv(parts, "sb-cards")
out[#out + 1] = classdiv(parts, "sb-cards")
return table.concat(out, "\n")
return table.concat(out, "\n")
end
-- {{#invoke:StreetBrawlItems|item|ITEM|GROUP|label=..|note=..}}
-- GROUP = favored | unfavored | counter
function p.item(frame)
local code = item_code(frame.args[1]); if not code then return "" end
local group = mw.text.trim(frame.args[2] or "")
local fav, unf, ctr = {}, {}, {}
for _, o in ipairs(sb.Outliers) do
if o.Item == code and RELEASED[o.Hero] then
if o.Bucket == "Good" then fav[#fav + 1] = o.Hero
elseif type(o.Weight) == "number" and o.Weight < 1 then unf[#unf + 1] = o.Hero end
if o.Counter ~= nil then ctr[#ctr + 1] = o.Hero end
end
end
local list = (group == "favored" and fav) or (group == "unfavored" and unf) or (group == "counter" and ctr)
if not list then return "" end
table.sort(list, function(a, b) return (KEY_TO_NAME[a] or a) < (KEY_TO_NAME[b] or b) end)
local parts = {}
for _, k in ipairs(list) do local r = render_hero(frame, k); if r then parts[#parts + 1] = r end end
if #parts == 0 then return "" end
local pre = ""
local label = frame.args.label
if label and label ~= "" then pre = pre .. "'''" .. label .. "'''<br>" end
local note = frame.args.note
if note and note ~= "" then pre = pre .. "''" .. note .. "''<br>" end
return pre .. classdiv(parts, "sb-icons")
end
-- {{#invoke:StreetBrawlItems|item_in_pool|ITEM}} -> "1" if in the Street Brawl pool, else ""
function p.item_in_pool(frame)
local code = item_code(frame.args[1]); if not code then return "" end
for _, c in ipairs(sb.AvailableItems) do if c == code then return "1" end end
return ""
end
end


return p
return p