Module:StreetBrawlItems: Difference between revisions

p.tier columns: conditional widths (drop empty Low; 35/65; narrow one-card Low when High present, fit-content Low when High absent); card size 0.8 (with help from vergir-bot LLM)
Card size 0.75; extract tier logic; add p.tiers (all tiers for a hero) (with help from vergir-bot LLM)
Line 8: Line 8:
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).
-- Default card scale passed to ItemBox (tier columns and counter cards).
local CARD_SIZE = "0.8"
local CARD_SIZE = "0.75"


local NAME_TO_KEY, KEY_TO_NAME, RELEASED = {}, {}, {}
local NAME_TO_KEY, KEY_TO_NAME, RELEASED = {}, {}, {}
Line 80: Line 80:
end
end
return favored, unfavored, special, counter
return favored, unfavored, special, counter
end
-- Returns sorted high (favored), normal (pool), low (unfavored) item-code lists for a tier.
local function collect(hkey, tier)
local favored, unfavored = hero_sets(hkey)
local high, normal, low = {}, {}, {}
for _, c in ipairs(sb.AvailableItems) do
if iok(c) and (tier == nil or itier(c) == tier) then
if favored[c] then high[#high + 1] = c
elseif unfavored[c] then low[#low + 1] = c
else normal[#normal + 1] = c end
end
end
table.sort(high, item_less)
table.sort(normal, item_less)
table.sort(low, item_less)
return high, normal, low
end
end


Line 93: Line 110:
end
end
return nil
return nil
end
-- Builds one tier as conditional columns:
--  High chance (favored) 35% and Middle chance (pool) fill the rest.
--  Low chance (unfavored) is dropped when empty; a narrow one-card column on the right
--  when High is present; a fit-content column on the right when High is absent.
local function tier_columns(frame, hkey, tier, style, size, theme, hi, mid, lo)
local high, normal, low = collect(hkey, tier)
local body_class = (style == "card") and "sb-col-body sb-col-cards" or "sb-col-body"
local sep = (style == "card") and "" or "<br>"
local function col(codes, cls, head)
local parts = {}
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 .. '">'
.. '<div class="sb-col-head">' .. head .. '</div>'
.. '<div class="' .. body_class .. '">' .. table.concat(parts, sep) .. '</div>'
.. '</div>'
end
local cls = "sb-tier"
if theme ~= "" then cls = cls .. " " .. theme end
local out = {}
if #high > 0 then
out[#out + 1] = col(high, "sb-col-high sb-w-high", hi)
end
out[#out + 1] = col(normal, "sb-col-normal sb-w-fill", mid)
if #low > 0 then
local low_w = (#high > 0) and "sb-low-narrow" or "sb-low-wide"
out[#out + 1] = col(low, "sb-col-low " .. low_w, lo)
end
return '<div class="' .. cls .. '">' .. table.concat(out) .. '</div>'
end
end


-- {{#invoke:StreetBrawlItems|hero|HERO|GROUP|TIER|label=..|collapse=yes|style=card|icon}}
-- {{#invoke:StreetBrawlItems|hero|HERO|GROUP|TIER|label=..|collapse=yes|style=card|icon}}
-- GROUP = favored | unfavored | common  (use hero_counter for counters)
-- Legacy: superseded by p.tier, kept for reference.
-- Legacy: superseded by p.tier, kept for reference.
function p.hero(frame)
function p.hero(frame)
Line 123: Line 172:
for _, c in ipairs(codes) do local r = render_item(frame, c, style); if r then parts[#parts + 1] = r end end
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 #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 row_class = (style == "icon") and "sb-icons" or "sb-cards"
Line 140: Line 180:


-- {{#invoke:StreetBrawlItems|tier|HERO|TIER|style=icon|card|size=..|theme=..|layout=grid|high=..|middle=..|low=..}}
-- {{#invoke:StreetBrawlItems|tier|HERO|TIER|style=icon|card|size=..|theme=..|layout=grid|high=..|middle=..|low=..}}
-- Default: conditional columns. High chance (favored) 35% and Middle chance (pool) fill
-- the rest. Low chance (unfavored) is dropped when empty; when present alongside High it
-- becomes a narrow one-card column on the right; when High is absent it sits on the right
-- sized to fit its cards on one line. layout=grid: one grid, cards outlined by chance.
function p.tier(frame)
function p.tier(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
Line 150: Line 186:
local size = frame.args.size
local size = frame.args.size
local theme = frame.args.theme or ""
local theme = frame.args.theme or ""
local favored, unfavored = hero_sets(hkey)
local hi = frame.args.high or "High chance"
 
local mid = frame.args.middle or "Middle chance"
local high, normal, low = {}, {}, {}
local lo = frame.args.low or "Low chance"
for _, c in ipairs(sb.AvailableItems) do
if iok(c) and (tier == nil or itier(c) == tier) then
if favored[c] then high[#high + 1] = c
elseif unfavored[c] then low[#low + 1] = c
else normal[#normal + 1] = c end
end
end
table.sort(high, item_less)
table.sort(normal, item_less)
table.sort(low, item_less)


-- layout=grid: single wrapping grid, cards outlined by chance (High, then Middle, then Low).
if frame.args.layout == "grid" then
if frame.args.layout == "grid" then
local high, normal, low = collect(hkey, tier)
local function chips(codes, chance)
local function chips(codes, chance)
local out = {}
local out = {}
Line 181: Line 207:
end
end


local body_class = (style == "card") and "sb-col-body sb-col-cards" or "sb-col-body"
return tier_columns(frame, hkey, tier, style, size, theme, hi, mid, lo)
local sep = (style == "card") and "" or "<br>"
end
 
local function col(codes, cls, head)
local parts = {}
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 .. '">'
.. '<div class="sb-col-head">' .. head .. '</div>'
.. '<div class="' .. body_class .. '">' .. table.concat(parts, sep) .. '</div>'
.. '</div>'
end


-- {{#invoke:StreetBrawlItems|tiers|HERO|style=..|size=..|theme=..}} -> all five tiers stacked.
function p.tiers(frame)
local hkey = hero_key(frame.args[1]); if not hkey then return "" end
local style = (frame.args.style == "card") and "card" or "icon"
local size = frame.args.size
local theme = frame.args.theme or ""
local hi = frame.args.high or "High chance"
local hi = frame.args.high or "High chance"
local mid = frame.args.middle or "Middle chance"
local mid = frame.args.middle or "Middle chance"
local lo = frame.args.low or "Low chance"
local lo = frame.args.low or "Low chance"
local cls = "sb-tier"
if theme ~= "" then cls = cls .. " " .. theme end


-- Conditional columns per the presence of High and Low.
local labels = { "Tier 1", "Tier 2", "Tier 3", "Tier 4", "Legendary" }
local out = {}
local out = {}
if #high > 0 then
for t = 1, 5 do
out[#out + 1] = col(high, "sb-col-high sb-w-high", hi)
out[#out + 1] = "'''" .. labels[t] .. "'''\n" .. tier_columns(frame, hkey, t, style, size, theme, hi, mid, lo)
end
out[#out + 1] = col(normal, "sb-col-normal sb-w-fill", mid)
if #low > 0 then
local low_w = (#high > 0) and "sb-low-narrow" or "sb-low-wide"
out[#out + 1] = col(low, "sb-col-low " .. low_w, lo)
end
end
return '<div class="' .. cls .. '">' .. table.concat(out) .. '</div>'
return table.concat(out, "\n\n")
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
Line 236: Line 251:


-- {{#invoke:StreetBrawlItems|item|ITEM|GROUP|label=..|note=..}}
-- {{#invoke:StreetBrawlItems|item|ITEM|GROUP|label=..|note=..}}
-- GROUP = favored | unfavored | counter
function p.item(frame)
function p.item(frame)
local code = item_code(frame.args[1]); if not code then return "" end
local code = item_code(frame.args[1]); if not code then return "" end