Welcome to the Umamusume Wiki! If you want to contribute, please read the guidelines.

Module:Game/Banners

From Umamusume Wiki
Jump to navigation Jump to search

Documentation for this module may be created at Module:Game/Banners/doc

--[[
    !! THIS PAGE IS MANAGED BY GITLAB !!
    ANY EDITS TO PAGE CONTENT WILL BE OVERWRITTEN
    TO MAKE CHANGES, PLEASE SUBMIT A MERGE REQUEST AT https://gitlab.com/umamusume-wiki/lua-modules
]]

local p = {}
local Data = require("Module:Game/Banners/Data")
local Utils = require("Module:Utils")
local Cards = require("Module:Game/Cards")
local Supports = require("Module:Game/Supports")

function p.bannerListTable(frame)
    local en = frame.args[1] == 'en'
    local year = frame.args['year'] or nil

    local bannerMap = (en and Data.getBannersEN or Data.getBannersJP)()
    local bannerList = {} ---@type BannerData[]
    for _, banner in pairs(bannerMap) do
        if year == nil or string.match(banner.startDateFormat, year) then
            table.insert(bannerList, banner)
        end
    end
    table.sort(bannerList, function(a, b)
        if a.startDateTime < b.startDateTime then
            return true
        elseif a.startDateTime > b.startDateTime then
            return false
        elseif tonumber(a.id) < tonumber(b.id) then
            return true
        end
        return false
    end)

    local mwtable = mw.html.create('table'):addClass('wikitable'):addClass('sortable'):addClass('mw-collapsible')
    local headerRow = mw.html.create('tr')
    local headerTexts = { 'Banner', 'Type', 'Start Date', 'End Date', 'Pickups' }
    for _, value in ipairs(headerTexts) do
        headerRow:node(mw.html.create('th'):wikitext(value))
    end
    mwtable:node(headerRow)

    local cardIds = {}
    local supportIds = {}
    for _, banner in ipairs(bannerList) do
        local toInsert = banner.cardType == 'Trainee' and cardIds or supportIds
        for _, pickup in ipairs(banner.pickups) do
            table.insert(toInsert, pickup.cardId)
        end
        for _, select in ipairs(banner.selects) do
            table.insert(toInsert, select.cardId)
        end
    end
    cardIds = Utils.dedupe(cardIds)
    supportIds = Utils.dedupe(supportIds)

    local cardTemplateArgs = Cards.generateCardLinks(cardIds)
    local supportTemplateArgs = Supports.generateSupportLinks(supportIds)

    for _, banner in ipairs(bannerList) do
        local pickupTexts = p._generatePickupList(frame, banner, cardTemplateArgs, supportTemplateArgs)

        local diffDays = math.floor(os.difftime(banner.endDateTime, banner.startDateTime) / (24 * 60 * 60) + 0.5)

        local renderTexts = {
            string.format('[[File:' .. banner.imagePage .. '|180px]]<br/>%s', banner.name),
            banner.cardType,
            banner.startDateFormat,
            string.format("%s (%s)", banner.endDateFormat, diffDays > 1000 and "Permanent" or diffDays .. " days"),
            table.concat(pickupTexts, '<br/>')
        }
        local renderValues = { 0, 0, banner.startDateTime, banner.endDateTime, 0 }

        local row = mw.html.create('tr')
        for i, value in ipairs(renderTexts) do
            local nodeTd = mw.html.create('td'):wikitext(value)
            if i == 1 then nodeTd:attr('style', 'max-width: 200px; text-align: center;') end
            if renderValues[i] > 0 then
                nodeTd = nodeTd:attr('data-sort-value', renderValues[i])
            end
            row:node(nodeTd)
        end
        mwtable:node(row)
    end

    return tostring(mwtable)
end

---@param frame any
---@param banner BannerData
---@param cardTemplateArgs table
---@param supportTemplateArgs table
---@return table
function p._generatePickupList(frame, banner, cardTemplateArgs, supportTemplateArgs)
    local pickupTexts = {}
    if #banner.selects > 0 then
        table.insert(pickupTexts, string.format("'''Select %d from:'''", #banner.pickups))
        for _, pickup in ipairs(banner.selects) do
            local template = frame:expandTemplate {
                title = banner.cardType == "Trainee" and "Game Card/link" or "Game Support/link",
                args = (banner.cardType == "Trainee" and cardTemplateArgs or supportTemplateArgs)[pickup.cardId]
            }
            table.insert(pickupTexts, template)
        end
        table.insert(pickupTexts, string.format("(at %.2f%%)", banner.pickups[1].odds))
    elseif banner.hasRateup or banner.bannerType == 'Twinkle Collection' then
        for _, pickup in ipairs(banner.pickups) do
            local template = frame:expandTemplate {
                title = banner.cardType == "Trainee" and "Game Card/link" or "Game Support/link",
                args = (banner.cardType == "Trainee" and cardTemplateArgs or supportTemplateArgs)[pickup.cardId]
            }
            table.insert(pickupTexts, string.format("%s (%.2f%%)", template, pickup.odds))
        end
    else
        table.insert(pickupTexts, "''No rateups.''")
    end
    return pickupTexts
end

function p.currentBannerList(frame)
    local en = frame.args[1] == 'en'

    local bannerMap = (en and Data.getCurrentBannersEN or Data.getCurrentBannersJP)()
    local bannerList = {} ---@type BannerData[]
    for _, banner in pairs(bannerMap) do
        table.insert(bannerList, banner)
    end
    table.sort(bannerList, function(a, b)
        if a.endDateTime < b.endDateTime then
            return true
        elseif a.endDateTime > b.endDateTime then
            return false
        elseif tonumber(a.id) < tonumber(b.id) then
            return true
        end
        return false
    end)

    local cardIds = {}
    local supportIds = {}
    for _, banner in ipairs(bannerList) do
        local toInsert = banner.cardType == 'Trainee' and cardIds or supportIds
        for _, pickup in ipairs(banner.pickups) do
            table.insert(toInsert, pickup.cardId)
        end
        for _, select in ipairs(banner.selects) do
            table.insert(toInsert, select.cardId)
        end
    end
    cardIds = Utils.dedupe(cardIds)
    supportIds = Utils.dedupe(supportIds)

    local cardTemplateArgs = Cards.generateCardLinks(cardIds)
    local supportTemplateArgs = Supports.generateSupportLinks(supportIds)

    local outerDivNode = mw.html.create('div'):addClass('banner-list')
    for _, banner in ipairs(bannerList) do
        local pickupTexts = p._generatePickupList(frame, banner, cardTemplateArgs, supportTemplateArgs)

        local bannerDivNode = mw.html.create('div'):addClass('banner-list-el')

        local imageDivNode = mw.html.create('div'):addClass('banner-list-el-img'):wikitext(string.format(
            "[[File:%s|180px]]", banner.imagePage))
        bannerDivNode:node(imageDivNode)

        local textDivNode = mw.html.create('div'):addClass('banner-list-el-title'):wikitext(string.format(
            "'''%s'''<br/>''Ends %s''", banner.name, banner.endDateFormat))
        bannerDivNode:node(textDivNode)

        local pickupText = table.concat(pickupTexts, '<br/>')
        local rateupTextOuterNode = mw.html.create('div'):addClass('mw-collapsible'):addClass('mw-collapsed')
        local rateupTextTitleNode = mw.html.create('div'):wikitext("'''Pickups'''")
        rateupTextOuterNode:node(rateupTextTitleNode)
        local rateupTextInnerNode = mw.html.create('div'):addClass('mw-collapsible-content'):wikitext(pickupText)
        rateupTextOuterNode:node(rateupTextInnerNode)
        bannerDivNode:node(rateupTextOuterNode)

        outerDivNode:node(bannerDivNode)
    end
    return outerDivNode
end

return p