Editing Module:StreetBrawlItemsGive feedback
Jump to navigation
Jump to search
The edit can be undone.
Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
| Latest revision | Your text | ||
| Line 7: | Line 7: | ||
-- Slot display order: Weapon -> Vitality (Armor) -> Spirit (Tech) | -- Slot display order: Weapon -> Vitality (Armor) -> Spirit (Tech) | ||
local SLOT_RANK = { Weapon = 1, Armor = 2, Tech = 3 } | local SLOT_RANK = { Weapon = 1, Armor = 2, Tech = 3 } | ||
-- | -- Default card scale passed to ItemBox (tier columns and counter cards). | ||
local CARD_SIZE = "0. | local CARD_SIZE = "0.875" | ||
local NAME_TO_KEY = {} | local NAME_TO_KEY, KEY_TO_NAME, RELEASED = {}, {}, {} | ||
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 52: | Line 54: | ||
end | end | ||
local function render_item(frame, code) | local function render_item(frame, code, style, size) | ||
local name = iname(code); if not name then return nil end | local name = iname(code); if not name then return nil end | ||
if style == "icon" then return frame:expandTemplate{title = "ItemIcon", args = {name}} end | |||
return frame:expandTemplate{title = "ItemBox", args = {name, showTierTag = "true", size = size or CARD_SIZE}} | |||
end | |||
local function render_hero(frame, key) | |||
local name = KEY_TO_NAME[key]; if not name then return nil end | |||
if | return frame:expandTemplate{title = "HeroIcon", args = {name}} | ||
return frame:expandTemplate{title = " | |||
end | end | ||
| Line 67: | Line 68: | ||
if #parts == 0 then return "" end | if #parts == 0 then return "" end | ||
return '<div class="' .. class .. '">' .. table.concat(parts) .. '</div>' | return '<div class="' .. class .. '">' .. table.concat(parts) .. '</div>' | ||
end | end | ||
local function hero_sets(hkey) | local function hero_sets(hkey) | ||
local favored, unfavored, counter = {}, {}, {} | local favored, unfavored, special, counter = {}, {}, {}, {} | ||
for _, o in ipairs(sb.Outliers) do | for _, o in ipairs(sb.Outliers) do | ||
if o.Hero == hkey then | if o.Hero == hkey then | ||
if o.Bucket == "Good" then favored[o.Item] = true | if o.Bucket == "Good" then favored[o.Item] = true; special[o.Item] = true | ||
elseif type(o.Weight) == "number" and o.Weight < 1 then unfavored[o.Item] = true end | elseif type(o.Weight) == "number" and o.Weight < 1 then unfavored[o.Item] = true; special[o.Item] = true end | ||
if o.Counter ~= nil then counter[#counter + 1] = o.Item end | if o.Counter ~= nil then counter[#counter + 1] = o.Item end | ||
end | end | ||
end | end | ||
return favored, unfavored, counter | return favored, unfavored, special, counter | ||
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 | ||
-- | -- {{#invoke:StreetBrawlItems|hero|HERO|GROUP|TIER|label=..|collapse=yes|style=card|icon}} | ||
local function | -- GROUP = favored | unfavored | common (use hero_counter for counters) | ||
-- Legacy: superseded by p.tier, kept for reference. | |||
function p.hero(frame) | |||
local hkey = hero_key(frame.args[1]); if not hkey then return "" end | |||
local group = mw.text.trim(frame.args[2] or "") | |||
local tier = tonumber(frame.args[3]) | |||
local style = frame.args.style | |||
if not style or style == "" then style = (group == "common") and "icon" or "card" end | |||
local collapse = (frame.args.collapse == "yes" or frame.args.collapse == "true") | |||
local label = frame.args.label or "" | |||
local favored, unfavored, special = hero_sets(hkey) | |||
local pred | |||
if group == "favored" then pred = function(c) return favored[c] end | |||
elseif group == "unfavored" then pred = function(c) return unfavored[c] end | |||
elseif group == "common" then pred = function(c) return not special[c] end | |||
else return "" end | |||
local codes = {} | |||
for _, c in ipairs(sb.AvailableItems) do | |||
if iok(c) and (tier == nil or itier(c) == tier) and pred(c) then codes[#codes + 1] = c end | |||
end | |||
table.sort(codes, item_less) | |||
local parts = {} | |||
for _, c in ipairs(codes) do local r = render_item(frame, c, style); if r then parts[#parts + 1] = r end end | |||
if #parts == 0 then return "" end | |||
if collapse then | |||
local id = "sbcommon-" .. hkey .. "-" .. tostring(tier or 0) | |||
local head = (label ~= "" and label) or "Common" | |||
return '<div class="sb-common mw-collapsible mw-collapsed" id="mw-customcollapsible-' .. id .. '">' | |||
.. '<div class="sb-common-head mw-customtoggle-' .. id .. '">' .. head .. '</div>' | |||
.. '<div class="sb-common-body mw-collapsible-content">' .. table.concat(parts, " · ") .. '</div>' | |||
.. '</div>' | |||
end | |||
local row_class = (style == "icon") and "sb-icons" or "sb-cards" | |||
local out = '<div class="sb-group">' | |||
if label ~= "" then out = out .. '<div class="sb-label">' .. label .. '</div>' end | |||
return out .. classdiv(parts, row_class) .. '</div>' | |||
end | |||
-- {{#invoke:StreetBrawlItems|tier|HERO|TIER|style=icon|card|size=..|theme=..|high=..|middle=..|low=..}} | |||
-- Renders one tier: a left side stacking High chance (favored, top) over Low chance | |||
-- (unfavored, bottom), beside Middle chance (the leftover pool). Empty columns still render. | |||
function p.tier(frame) | |||
local hkey = hero_key(frame.args[1]); if not hkey then return "" end | |||
local tier = tonumber(frame.args[2]) | |||
local style = (frame.args.style == "card") and "card" or "icon" | |||
local size = frame.args.size | |||
local theme = frame.args.theme or "" | |||
local favored, unfavored = hero_sets(hkey) | local favored, unfavored = hero_sets(hkey) | ||
local high, | |||
local high, normal, 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 | else normal[#normal + 1] = c end | ||
end | end | ||
end | end | ||
table.sort(high, item_less) | table.sort(high, item_less) | ||
table.sort( | table.sort(normal, item_less) | ||
table.sort(low, item_less) | table.sort(low, item_less) | ||
local body_class = (style == "card") and "sb-col-body sb-col-cards" or "sb-col-body" | |||
local sep = (style == "card") and "" or "<br>" | |||
-- | |||
-- | |||
local | |||
local function col(codes, cls, head) | local function col(codes, cls, head) | ||
local parts = {} | local parts = {} | ||
for _, c in ipairs(codes) do local r = render_item(frame, c); if r then parts[#parts + 1] = r end end | for _, c in ipairs(codes) do local r = render_item(frame, c, style, size); if r then parts[#parts + 1] = r end end | ||
return '<div class="sb-col ' .. cls .. '">' | return '<div class="sb-col ' .. cls .. '">' | ||
.. '<div class="sb-col-head">' .. head .. '</div>' | .. '<div class="sb-col-head">' .. head .. '</div>' | ||
.. '<div class=" | .. '<div class="' .. body_class .. '">' .. table.concat(parts, sep) .. '</div>' | ||
.. '</div>' | .. '</div>' | ||
end | end | ||
local hi = frame.args.high or "High chance" | |||
local mid = frame.args.middle or "Middle chance" | |||
local lo = frame.args.low or "Low chance" | |||
local cls = "sb-tier" | |||
if theme ~= "" then cls = cls .. " " .. theme end | |||
return '<div class="' .. cls .. '">' | |||
.. '<div class="sb-side">' | |||
.. col(high, "sb-col-high", hi) | |||
.. col(low, "sb-col-low", lo) | |||
.. '</div>' | |||
.. col(normal, "sb-col-normal", mid) | |||
.. '</div>' | |||
local hi = frame.args.high or "" | |||
local | |||
local lo = frame.args.low or "" | |||
local | |||
if | |||
end | end | ||
-- {{#invoke:StreetBrawlItems|hero_counter|HERO|heading=..|note=..}} | -- {{#invoke:StreetBrawlItems|hero_counter|HERO|heading=..|note=..}} | ||
-- | -- Returns the whole counter block (heading + note + cards), or "" when empty. | ||
function p.hero_counter(frame) | function p.hero_counter(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 _, _, counter = hero_sets(hkey) | local _, _, _, counter = hero_sets(hkey) | ||
local codes = {} | local codes = {} | ||
| Line 175: | Line 200: | ||
local parts = {} | local parts = {} | ||
for _, c in ipairs(codes) do local r = render_item(frame, c); if r then parts[#parts + 1] = r end end | for _, c in ipairs(codes) do local r = render_item(frame, c, "card"); if r then parts[#parts + 1] = r end end | ||
local out = {} | local out = {} | ||
local heading = frame.args.heading | local heading = frame.args.heading | ||
if heading and heading ~= "" then out[#out + 1] = | if heading and heading ~= "" then out[#out + 1] = "=== " .. heading .. " ===" end | ||
local note = frame.args.note | local note = frame.args.note | ||
if note and note ~= "" then out[#out + 1] = "''" .. note .. "''" end | if note and note ~= "" then out[#out + 1] = "''" .. note .. "''" end | ||
| Line 186: | Line 211: | ||
end | end | ||
-- {{#invoke:StreetBrawlItems| | -- {{#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 | |||
local fav, unf, ctr = {}, {}, {} | |||
for _, o in ipairs(sb.Outliers) do | for _, o in ipairs(sb.Outliers) do | ||
if o. | if o.Item == code and RELEASED[o.Hero] then | ||
if o.Bucket == "Good" then fav[#fav + 1] = o.Hero | |||
if | 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 | ||
end | end | ||
local list = (group == "favored" and fav) or (group == "unfavored" and unf) or (group == "counter" and ctr) | |||
table.sort( | 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 | 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) | |||
return | 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 | ||