Module:Format: Difference between revisions
From eSportsAmaze
More actions
Esportsamaze (talk | contribs) Created page with "local p = {} local html = mw.html -- ============================================================ -- 1. STAGE TIMELINE (Vertical Flow) -- ============================================================ function p.timeline(frame) local args = frame:getParent().args local container = html.create('div'):addClass('fmt-timeline') for i = 1, 10 do local name = args['stage' .. i] local date = args['date' .. i] local desc = args['desc' .. i]..." |
Esportsamaze (talk | contribs) No edit summary |
||
| (3 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
local _id_counter = 0 | |||
local html = mw.html | local html = mw.html | ||
-- Helper: Add ordinal suffix | |||
local function getOrdinal(n) | |||
local last = n % 10 | |||
local lastTwo = n % 100 | |||
if lastTwo >= 11 and lastTwo <= 13 then return n .. "th" end | |||
if last == 1 then return n .. "st" end | |||
if last == 2 then return n .. "nd" end | |||
if last == 3 then return n .. "rd" end | |||
return n .. "th" | |||
end | |||
-- ============================================================ | -- ============================================================ | ||
-- 1. STAGE TIMELINE ( | -- 1. STAGE TIMELINE (Collapsible Headers) | ||
-- ============================================================ | -- ============================================================ | ||
function p.timeline(frame) | function p.timeline(frame) | ||
| Line 9: | Line 21: | ||
local container = html.create('div'):addClass('fmt-timeline') | local container = html.create('div'):addClass('fmt-timeline') | ||
for i = 1, | -- Generate a base random ID to prevent conflicts on same page | ||
_id_counter = _id_counter + 1 | |||
local baseID = "fmt-" .. _id_counter | |||
for i = 1, 15 do | |||
local name = args['stage' .. i] | local name = args['stage' .. i] | ||
local date = args['date' .. i] | local date = args['date' .. i] | ||
| Line 15: | Line 31: | ||
if name and name ~= "" then | if name and name ~= "" then | ||
local uniqueID = "stg-" .. baseID .. "-" .. i | |||
local node = container:tag('div'):addClass('fmt-node') | local node = container:tag('div'):addClass('fmt-node') | ||
-- Left Marker | -- Left Marker | ||
node:tag('div'):addClass('fmt-marker') | node:tag('div'):addClass('fmt-marker') | ||
-- Content Box | -- Content Box | ||
local content = node:tag('div'):addClass('fmt-content') | local content = node:tag('div'):addClass('fmt-content') | ||
content:tag('div'):addClass('fmt-stage-title'):wikitext(name) | |||
-- HEADER (The Trigger) | |||
local header = content:tag('div') | |||
:addClass('fmt-header-row') | |||
:addClass('mw-customtoggle-' .. uniqueID) -- Makes it clickable | |||
:attr('title', 'Click to expand/collapse') | |||
-- Title Wrapper | |||
local titleWrap = header:tag('div'):addClass('fmt-title-wrap') | |||
titleWrap:tag('div'):addClass('fmt-stage-title'):wikitext(name) | |||
-- Right Side (Date + Icon) | |||
local metaWrap = header:tag('div'):addClass('fmt-meta-wrap') | |||
if date and date ~= "" then | if date and date ~= "" then | ||
metaWrap:tag('div'):addClass('fmt-date'):wikitext(date) | |||
end | end | ||
-- Chevron Icon (Visual cue) | |||
if desc and desc ~= "" then | if desc and desc ~= "" then | ||
content:tag('div'):addClass('fmt-desc'):wikitext(desc) | metaWrap:tag('i'):addClass('fa-solid fa-chevron-down fmt-toggle-icon') | ||
end | |||
-- DESCRIPTION (The Target) | |||
if desc and desc ~= "" then | |||
content:tag('div') | |||
:addClass('fmt-desc mw-collapsible mw-collapsed') -- Hidden by default | |||
:attr('id', 'mw-customcollapsible-' .. uniqueID) | |||
:wikitext(frame:preprocess(desc)) | |||
end | end | ||
end | end | ||
| Line 38: | Line 77: | ||
-- ============================================================ | -- ============================================================ | ||
-- 2. POINTS | -- 2. POINTS DISTRIBUTION (Column Major + Dark Mode Ready) | ||
-- ============================================================ | -- ============================================================ | ||
function p.points(frame) | function p.points(frame) | ||
local args = frame:getParent().args | local args = frame:getParent().args | ||
local system = args.type or "10" | local system = args.type or "10" | ||
local dist = {} | local dist = {} | ||
local killPts = args.kill_pts or 1 | local killPts = args.kill_pts or 1 | ||
if system == "15" then | if system == "15" then dist = {15, 12, 10, 8, 6, 4, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0} | ||
elseif system == "10" then dist = {10, 6, 5, 4, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0} | |||
elseif system == "10" then | else for i = 1, 20 do if args['p' .. i] then table.insert(dist, tonumber(args['p' .. i])) end end end | ||
else | |||
local container = html.create('div'):addClass('fmt-points-container') | local container = html.create('div'):addClass('fmt-points-container') | ||
container:tag('div'):addClass('fmt-points-header'):wikitext('Points Distribution') | |||
-- | local groups = {} | ||
local currentPts = -1 | |||
local rangeStart = 1 | |||
for i = 1, #dist + 1 do | |||
local pts = dist[i] | |||
if pts ~= currentPts then | |||
if i > 1 then | |||
local rangeEnd = i - 1 | |||
local rankLabel = (rangeStart == rangeEnd) and getOrdinal(rangeStart) or (getOrdinal(rangeStart) .. " – " .. getOrdinal(rangeEnd)) | |||
table.insert(groups, { label = rankLabel, val = currentPts, isTop3 = (rangeStart <= 3) }) | |||
end | |||
rangeStart = i | |||
currentPts = pts | |||
end | |||
end | |||
-- | local midPoint = math.ceil(#groups / 2) | ||
local | local flexWrapper = container:tag('div'):addClass('fmt-points-columns') | ||
local leftCol = flexWrapper:tag('div'):addClass('fmt-points-col') | |||
local rightCol = flexWrapper:tag('div'):addClass('fmt-points-col') | |||
for i, | for i, grp in ipairs(groups) do | ||
local | local target = (i <= midPoint) and leftCol or rightCol | ||
local row = target:tag('div'):addClass('fmt-pt-row') | |||
row:tag('div'):addClass('fmt-pt-rank-v'):wikitext(grp.label) | |||
row:tag('div'):addClass('fmt-pt-val-v'):wikitext(grp.val) | |||
if grp.isTop3 and grp.val > 0 then row:addClass('row-top3') end | |||
if grp.val == 0 then row:addClass('row-zero') end | |||
end | end | ||
local killBox = container:tag('div'):addClass('fmt-kill-box') | local killBox = container:tag('div'):addClass('fmt-kill-box') | ||
killBox:wikitext('Each Finish: <b>' .. killPts .. ' Point</b>') | killBox:wikitext('Each Finish: <b>' .. killPts .. ' Point</b>') | ||
| Line 89: | Line 129: | ||
end | end | ||
-- 3. MAP ROTATION (Unchanged) | |||
-- 3. MAP ROTATION ( | |||
function p.maps(frame) | function p.maps(frame) | ||
local args = frame:getParent().args | local args = frame:getParent().args | ||
local container = html.create('div'):addClass('fmt-maps-container') | local container = html.create('div'):addClass('fmt-maps-container') | ||
if args.title then container:tag('div'):addClass('fmt-maps-header'):wikitext(args.title) end | |||
if args.title then | |||
local list = container:tag('div'):addClass('fmt-maps-list') | local list = container:tag('div'):addClass('fmt-maps-list') | ||
local mapDict = { | local mapDict = { | ||
e = {name="Erangel", class="map-erangel"}, | e = {name="Erangel", class="map-erangel"}, m = {name="Miramar", class="map-miramar"}, | ||
s = {name="Sanhok", class="map-sanhok"}, v = {name="Vikendi", class="map-vikendi"}, | |||
s = {name="Sanhok", class="map-sanhok"}, | r = {name="Rondo", class="map-rondo"}, tbd = {name="TBD", class="map-tbd"} | ||
r = {name="Rondo", class="map-rondo"}, | |||
} | } | ||
for i = 1, 10 do | for i = 1, 10 do | ||
local m = args[i] or args['m' .. i] | local m = args[i] or args['m' .. i] | ||
if m and m ~= "" then | if m and m ~= "" then | ||
local key = m:lower():sub(1,1) | local key = m:lower():sub(1,1) | ||
local data = mapDict[key] or {name=m, class="map-tbd"} | local data = mapDict[key] or {name=m, class="map-tbd"} | ||
if m:lower() == "rondo" then data = mapDict['r'] end | if m:lower() == "rondo" then data = mapDict['r'] end | ||
if m:lower() == "erangel" then data = mapDict['e'] end | if m:lower() == "erangel" then data = mapDict['e'] end | ||
| Line 124: | Line 150: | ||
if m:lower() == "sanhok" then data = mapDict['s'] end | if m:lower() == "sanhok" then data = mapDict['s'] end | ||
if m:lower() == "vikendi" then data = mapDict['v'] end | if m:lower() == "vikendi" then data = mapDict['v'] end | ||
list:tag('div'):addClass('fmt-map-item'):tag('span'):addClass('fmt-map-badge ' .. data.class):wikitext(data.name) | |||
end | end | ||
end | end | ||
return tostring(container) | return tostring(container) | ||
end | end | ||
return p | return p | ||
Latest revision as of 01:09, 3 March 2026
Documentation for this module may be created at Module:Format/doc
local p = {}
local _id_counter = 0
local html = mw.html
-- Helper: Add ordinal suffix
local function getOrdinal(n)
local last = n % 10
local lastTwo = n % 100
if lastTwo >= 11 and lastTwo <= 13 then return n .. "th" end
if last == 1 then return n .. "st" end
if last == 2 then return n .. "nd" end
if last == 3 then return n .. "rd" end
return n .. "th"
end
-- ============================================================
-- 1. STAGE TIMELINE (Collapsible Headers)
-- ============================================================
function p.timeline(frame)
local args = frame:getParent().args
local container = html.create('div'):addClass('fmt-timeline')
-- Generate a base random ID to prevent conflicts on same page
_id_counter = _id_counter + 1
local baseID = "fmt-" .. _id_counter
for i = 1, 15 do
local name = args['stage' .. i]
local date = args['date' .. i]
local desc = args['desc' .. i]
if name and name ~= "" then
local uniqueID = "stg-" .. baseID .. "-" .. i
local node = container:tag('div'):addClass('fmt-node')
-- Left Marker
node:tag('div'):addClass('fmt-marker')
-- Content Box
local content = node:tag('div'):addClass('fmt-content')
-- HEADER (The Trigger)
local header = content:tag('div')
:addClass('fmt-header-row')
:addClass('mw-customtoggle-' .. uniqueID) -- Makes it clickable
:attr('title', 'Click to expand/collapse')
-- Title Wrapper
local titleWrap = header:tag('div'):addClass('fmt-title-wrap')
titleWrap:tag('div'):addClass('fmt-stage-title'):wikitext(name)
-- Right Side (Date + Icon)
local metaWrap = header:tag('div'):addClass('fmt-meta-wrap')
if date and date ~= "" then
metaWrap:tag('div'):addClass('fmt-date'):wikitext(date)
end
-- Chevron Icon (Visual cue)
if desc and desc ~= "" then
metaWrap:tag('i'):addClass('fa-solid fa-chevron-down fmt-toggle-icon')
end
-- DESCRIPTION (The Target)
if desc and desc ~= "" then
content:tag('div')
:addClass('fmt-desc mw-collapsible mw-collapsed') -- Hidden by default
:attr('id', 'mw-customcollapsible-' .. uniqueID)
:wikitext(frame:preprocess(desc))
end
end
end
return tostring(container)
end
-- ============================================================
-- 2. POINTS DISTRIBUTION (Column Major + Dark Mode Ready)
-- ============================================================
function p.points(frame)
local args = frame:getParent().args
local system = args.type or "10"
local dist = {}
local killPts = args.kill_pts or 1
if system == "15" then dist = {15, 12, 10, 8, 6, 4, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0}
elseif system == "10" then dist = {10, 6, 5, 4, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}
else for i = 1, 20 do if args['p' .. i] then table.insert(dist, tonumber(args['p' .. i])) end end end
local container = html.create('div'):addClass('fmt-points-container')
container:tag('div'):addClass('fmt-points-header'):wikitext('Points Distribution')
local groups = {}
local currentPts = -1
local rangeStart = 1
for i = 1, #dist + 1 do
local pts = dist[i]
if pts ~= currentPts then
if i > 1 then
local rangeEnd = i - 1
local rankLabel = (rangeStart == rangeEnd) and getOrdinal(rangeStart) or (getOrdinal(rangeStart) .. " – " .. getOrdinal(rangeEnd))
table.insert(groups, { label = rankLabel, val = currentPts, isTop3 = (rangeStart <= 3) })
end
rangeStart = i
currentPts = pts
end
end
local midPoint = math.ceil(#groups / 2)
local flexWrapper = container:tag('div'):addClass('fmt-points-columns')
local leftCol = flexWrapper:tag('div'):addClass('fmt-points-col')
local rightCol = flexWrapper:tag('div'):addClass('fmt-points-col')
for i, grp in ipairs(groups) do
local target = (i <= midPoint) and leftCol or rightCol
local row = target:tag('div'):addClass('fmt-pt-row')
row:tag('div'):addClass('fmt-pt-rank-v'):wikitext(grp.label)
row:tag('div'):addClass('fmt-pt-val-v'):wikitext(grp.val)
if grp.isTop3 and grp.val > 0 then row:addClass('row-top3') end
if grp.val == 0 then row:addClass('row-zero') end
end
local killBox = container:tag('div'):addClass('fmt-kill-box')
killBox:wikitext('Each Finish: <b>' .. killPts .. ' Point</b>')
return tostring(container)
end
-- 3. MAP ROTATION (Unchanged)
function p.maps(frame)
local args = frame:getParent().args
local container = html.create('div'):addClass('fmt-maps-container')
if args.title then container:tag('div'):addClass('fmt-maps-header'):wikitext(args.title) end
local list = container:tag('div'):addClass('fmt-maps-list')
local mapDict = {
e = {name="Erangel", class="map-erangel"}, m = {name="Miramar", class="map-miramar"},
s = {name="Sanhok", class="map-sanhok"}, v = {name="Vikendi", class="map-vikendi"},
r = {name="Rondo", class="map-rondo"}, tbd = {name="TBD", class="map-tbd"}
}
for i = 1, 10 do
local m = args[i] or args['m' .. i]
if m and m ~= "" then
local key = m:lower():sub(1,1)
local data = mapDict[key] or {name=m, class="map-tbd"}
if m:lower() == "rondo" then data = mapDict['r'] end
if m:lower() == "erangel" then data = mapDict['e'] end
if m:lower() == "miramar" then data = mapDict['m'] end
if m:lower() == "sanhok" then data = mapDict['s'] end
if m:lower() == "vikendi" then data = mapDict['v'] end
list:tag('div'):addClass('fmt-map-item'):tag('span'):addClass('fmt-map-badge ' .. data.class):wikitext(data.name)
end
end
return tostring(container)
end
return p