Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Module:Format: Difference between revisions

From eSportsAmaze
No edit summary
No edit summary
 
(One intermediate revision 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 (1st, 2nd, 3rd)
-- Helper: Add ordinal suffix
local function getOrdinal(n)
local function getOrdinal(n)
     local last = n % 10
     local last = n % 10
Line 14: Line 15:


-- ============================================================
-- ============================================================
-- 1. STAGE TIMELINE (Unchanged)
-- 1. STAGE TIMELINE (Collapsible Headers)
-- ============================================================
-- ============================================================
function p.timeline(frame)
function p.timeline(frame)
Line 20: Line 21:
     local container = html.create('div'):addClass('fmt-timeline')
     local container = html.create('div'):addClass('fmt-timeline')


     for i = 1, 10 do
    -- 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 26: 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
             node:tag('div'):addClass('fmt-marker')
             node:tag('div'):addClass('fmt-marker')
           
            -- Content Box
             local content = node:tag('div'):addClass('fmt-content')
             local content = node:tag('div'):addClass('fmt-content')
             local header = content:tag('div'):addClass('fmt-header-row')
           
             header: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
                 header:tag('div'):addClass('fmt-date'):wikitext(date)
                 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(frame:preprocess(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
     end
     end
   
     return tostring(container)
     return tostring(container)
end
end


-- ============================================================
-- ============================================================
-- 2. POINTS DISTRIBUTION (Updated: Column Flow 1,2,3,4...)
-- 2. POINTS DISTRIBUTION (Column Major + Dark Mode Ready)
-- ============================================================
-- ============================================================
function p.points(frame)
function p.points(frame)
Line 49: Line 83:
     local system = args.type or "10"
     local system = args.type or "10"
      
      
    -- 1. Define Distribution
     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}
        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
        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')
     local container = html.create('div'):addClass('fmt-points-container')
     container:tag('div'):addClass('fmt-points-header'):wikitext('Points Distribution')
     container:tag('div'):addClass('fmt-points-header'):wikitext('Points Distribution')
      
      
    -- 2. Logic: Group Ranks
     local groups = {}
     local groups = {}
     local currentPts = -1
     local currentPts = -1
     local rangeStart = 1
     local rangeStart = 1
   
     for i = 1, #dist + 1 do
     for i = 1, #dist + 1 do
         local pts = dist[i]
         local pts = dist[i]
Line 77: Line 102:
                 local rangeEnd = i - 1
                 local rangeEnd = i - 1
                 local rankLabel = (rangeStart == rangeEnd) and getOrdinal(rangeStart) or (getOrdinal(rangeStart) .. " – " .. getOrdinal(rangeEnd))
                 local rankLabel = (rangeStart == rangeEnd) and getOrdinal(rangeStart) or (getOrdinal(rangeStart) .. " – " .. getOrdinal(rangeEnd))
                 table.insert(groups, {
                 table.insert(groups, { label = rankLabel, val = currentPts, isTop3 = (rangeStart <= 3) })
                    label = rankLabel,
                    val = currentPts,
                    isTop3 = (rangeStart <= 3)
                })
             end
             end
             rangeStart = i
             rangeStart = i
Line 88: Line 109:
     end
     end
      
      
    -- 3. Render: Two Columns (Split groups in half)
     local midPoint = math.ceil(#groups / 2)
     local midPoint = math.ceil(#groups / 2)
     local flexWrapper = container:tag('div'):addClass('fmt-points-columns')
     local flexWrapper = container:tag('div'):addClass('fmt-points-columns')
   
     local leftCol = flexWrapper:tag('div'):addClass('fmt-points-col')
     local leftCol = flexWrapper:tag('div'):addClass('fmt-points-col')
     local rightCol = flexWrapper:tag('div'):addClass('fmt-points-col')
     local rightCol = flexWrapper:tag('div'):addClass('fmt-points-col')
      
      
     for i, grp in ipairs(groups) do
     for i, grp in ipairs(groups) do
        -- Decide which column to put this row in
         local target = (i <= midPoint) and leftCol or rightCol
         local target = (i <= midPoint) and leftCol or rightCol
       
         local row = target:tag('div'):addClass('fmt-pt-row')
         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-rank-v'):wikitext(grp.label)
         row:tag('div'):addClass('fmt-pt-val-v'):wikitext(grp.val)
         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.isTop3 and grp.val > 0 then row:addClass('row-top3') end
         if grp.val == 0 then row:addClass('row-zero') end
         if grp.val == 0 then row:addClass('row-zero') end
Line 114: Line 129:
end
end


-- ============================================================
-- 3. MAP ROTATION (Unchanged)
-- 3. MAP ROTATION (Unchanged)
-- ============================================================
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
        container:tag('div'):addClass('fmt-maps-header'):wikitext(args.title)
    end
   
     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"},
        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"}
        v = {name="Vikendi", class="map-vikendi"},
         r = {name="Rondo",  class="map-rondo"},
        tbd = {name="TBD",  class="map-tbd"}
     }
     }
   
     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]

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