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

Module:Game/TrainingEvents

From Umamusume Wiki
Jump to navigation Jump to search

Documentation for this module may be created at Module:Game/TrainingEvents/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 Game = require("Module:Game")
local Data = require("Module:Game/TrainingEvents/Data")
local SupportData = require("Module:Game/Supports/Data")
local SupportEvents = require("Module:Game/Supports/Data/Events")
local Cargo = require("Module:Cargo")
local Utils = require("Module:Utils")

---@param event TrainingEventData
---@param description string|nil
---@param choiceData table[]
---@return table
function p._getDisplayText(frame, event, description, choiceData)
    local function wrapNowiki(text)
        if text == nil then return nil end
        return tostring(frame:preprocess(string.format("<nowiki>%s</nowiki>", text)))
    end

    local templateArgs = {
        story_id = event.storyId,
        title_jp = wrapNowiki(event.titleJP),
        title_en = wrapNowiki(event.titleEN),
        description = description,
        chain_num = event.chainNum,
        chain_max = event.chainMax,
        is_group_chain = event.isGroupChain,
    }
    for idx, choice in ipairs(choiceData) do
        templateArgs['choice_' .. idx] = choice.text_en and
            frame:expandTemplate { title = "Tooltip", args = { choice.text_en, choice.text_jp } } or choice.text_jp
        templateArgs['effect_' .. idx] = p.replaceDescriptionText(frame, choice.description or '')
    end
    return frame:expandTemplate {
        title = "Game Training Event Display",
        args = templateArgs
    }
end

function p.eventPage(frame)
    local pageName = mw.text.decode(frame.args[1])
    if not pageName then return end
    local description = mw.text.decode(frame.args['description'] or '')
    local storyId = Utils.normalString(frame.args['storyId'] or '')
    local event = Data.getTrainingEventsByStoryIds({ storyId })[storyId]
    if not event then return end

    local choiceResults = Cargo.query {
        from = 'Game_Training_Event_Choice',
        fields = { 'number', 'text_jp', 'text_en', 'description' },
        where = string.format('_pageName = "%s"', pageName),
        orderBy = 'number',
        groupBy = 'number'
    }

    return p._getDisplayText(frame, event, description, choiceResults)
end

function p.supportPageInsert(frame)
    local supportId = Utils.normalString(frame.args[1])
    local supportData = SupportData.getSupport(supportId)
    if not supportData then return end
    local charIds = supportData.groupCharacterIds or { supportData.characterId }
    local supportEvents = SupportEvents.getSupportCardEvents({ supportId }, charIds)

    local cardSupportEvents = supportEvents[1][supportId] or {}
    local characterSupportEventsMap = supportEvents[2]

    local allEvents = {}
    local storyIds = {}
    for _, event in ipairs(cardSupportEvents) do
        table.insert(allEvents, event)
        table.insert(storyIds, event.storyId)
    end
    for _, charId in ipairs(charIds) do
        local charEvents = characterSupportEventsMap[charId]
        for _, event in ipairs(charEvents) do
            table.insert(allEvents, event)
            table.insert(storyIds, event.storyId)
        end
    end

    local chainEvents = {}
    local groupChainEvents = {}
    local randomEvents = {}
    for _, event in ipairs(allEvents) do
        if event.isGroupChain then
            table.insert(groupChainEvents, event)
        elseif event.chainMax > 0 then
            chainEvents[event.chainNum] = event
        else
            table.insert(randomEvents, event)
        end
    end

    local storyIdsInsert = table.concat(storyIds, ',')
    local cargoEventResults = Cargo.query {
        from = 'Game_Training_Event',
        fields = { '_pageName=eventPage', 'story_id', 'description' },
        where = string.format('story_id IN (%s)', storyIdsInsert)
    }
    local storyIdCargoMap = {}
    local pageNames = {}
    for _, cargoEvent in ipairs(cargoEventResults) do
        storyIdCargoMap[cargoEvent.story_id] = cargoEvent
        table.insert(pageNames, string.format('"%s"', cargoEvent.eventPage))
    end

    local pageNamesInsert = table.concat(pageNames, ',')
    local cargoEventChoicesResults = Cargo.query {
        from = 'Game_Training_Event_Choice',
        fields = { '_pageName=eventPage', 'number', 'text_jp', 'text_en', 'description' },
        where = string.format('_pageName IN (%s)', #pageNamesInsert > 0 and pageNamesInsert or '""'),
        orderBy = 'number'
    }
    local pageNameChoiceMap = {}
    for _, choice in ipairs(cargoEventChoicesResults) do
        local key = choice.eventPage
        if not pageNameChoiceMap[key] then pageNameChoiceMap[key] = {} end
        table.insert(pageNameChoiceMap[key], choice)
    end

    ---@param event TrainingEventData
    local function getText(event)
        local cargoData = storyIdCargoMap[event.storyId] or {}
        local choices = pageNameChoiceMap[cargoData.eventPage] or {}
        return p._getDisplayText(frame, event, cargoData.description, choices)
    end

    local text = ''
    if #chainEvents + #groupChainEvents > 0 then
        text = text .. "=== Event Chain ===\n\n\n"
        for _, event in ipairs(chainEvents) do
            text = text .. getText(event) .. '\n\n\n'
        end
        for _, event in ipairs(groupChainEvents) do
            text = text .. getText(event) .. '\n\n\n'
        end
    end
    if #randomEvents > 0 then
        text = text .. "=== Other Events ===\n\n\n"
        for _, event in ipairs(randomEvents) do
            text = text .. getText(event) .. '\n\n\n'
        end
    end
    return mw.text.trim(text)
end

function p.replaceDescriptionText(frame, text)
    local done = false
    while not done do
        local skillS, skillE = string.find(text, "<skill:%w+>")
        if skillS ~= nil and skillE ~= nil then
            local skillId = text:sub(skillS + 7, skillE - 1)
            local expanded = frame:expandTemplate { title = "Game Skill", args = { skillId } }
            text = text:sub(1, skillS - 1) .. expanded .. text:sub(skillE + 1)
        else
            done = true
        end
    end
    return text
end

return p