Welcome to the Umamusume Wiki! If you want to contribute, please read the guidelines.
Module:Game/Supports
Jump to navigation
Jump to search
Documentation for this module may be created at Module:Game/Supports/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/Supports/Data")
local Characters = require("Module:Game/Characters")
local Effects = require("Module:Game/Supports/Data/Effects")
local Cargo = require("Module:Cargo")
local Utils = require("Module:Utils")
local Game = require("Module:Game")
---Generate lists of arguments for the Game Support/link template
---Use to batch create lots of support links for pages that need them
---@param supportIds string[]
---@return any[] templateArgs keyed by support ID
function p.generateSupportLinks(supportIds)
local results = {}
if #supportIds > 0 then
local supportIdsInsert = table.concat(supportIds, ',')
results = Cargo.query {
from = 'Game_Supports',
fields = { '_pageName=supportPage', 'support_id', 'name_ro', 'name_ww' },
where = string.format('support_id IN (%s)', supportIdsInsert),
limit = #supportIds
}
end
local supportDatas = Data.getBatch(supportIds)
local merged = Utils.pairObjects(supportDatas, 'id', results, 'support_id', true)
-- fetch required character info (no page exists or need for display name)
local charIds = {}
for _, pair in ipairs(merged) do
local cargoData, supportData = pair[2], pair[1] ---@type any
if not cargoData or (not (supportData.displayNameEN or cargoData.name_ww) and supportData.groupCharacterIds == nil) then
table.insert(charIds, supportData.characterId)
end
end
local charInfos = Characters.getCharacterInfos(charIds)
local datas = {}
for _, pair in ipairs(merged) do
local cargoData, supportData = pair[2], pair[1] ---@type any
local charData = charInfos[supportData.characterId]
if not cargoData then
-- Generate expected page name for easy creation if the page does not exist
cargoData = {
supportPage = string.format("Game:%s %s (%s)", supportData.rarity,
charData and charData.nameEN or '',
string.gsub(supportData.nameEN or supportData.nameJP, "[%[%]]", ""))
}
end
local displayName = supportData.displayNameEN or cargoData.name_ww
if displayName == nil then
if supportData.groupCharacterIds ~= nil then
displayName = supportData.displayNameJP
else
local charName = (charData and charData.nameEN) or ''
local romanName = cargoData.name_ro and string.format("[%s]", cargoData.name_ro) or nil
displayName = string.format("%s %s", romanName or supportData.nameJP, charName)
end
end
displayName = supportData.rarity .. ' ' .. displayName
local templateArgs = {
icon = supportData.iconPage,
page = cargoData.supportPage,
display = displayName,
type = supportData.attribute
}
datas[supportData.id] = templateArgs
end
return datas
end
function p.supportLink(frame)
local supportId = Utils.normalString(mw.text.decode(frame.args[1]))
if not supportId then return end
local templateArgs = p.generateSupportLinks({ supportId })[supportId]
if not templateArgs then return end
local text = frame:expandTemplate {
title = "Game Support/link",
args = templateArgs
}
return text
end
function p.characterSupportLinks(frame)
local charId = Utils.normalString(mw.text.decode(frame.args[1]))
if not charId then return end
local support_card_datas = Game.queryMaster {
from = "support_card_data",
where = string.format("chara_id = %s and support_card_type <> 3", charId),
data = {
id = "id"
}
}
local supportIds = {}
for _, support_card_data in ipairs(support_card_datas) do
table.insert(supportIds, support_card_data.id)
end
table.sort(supportIds)
local supportLinks = p.generateSupportLinks(supportIds)
local text = ''
for _, supportId in ipairs(supportIds) do
local templateArgs = supportLinks[supportId]
text = text .. frame:expandTemplate {
title = "Game Support/link",
args = templateArgs
} .. '\n\n'
end
if #text == 0 then
return "''None.''"
end
return mw.text.trim(text)
end
function p.supportPage(frame)
local supportId = mw.text.decode(frame.args[1])
if not supportId then return end
local supportData = Data.getSupport(supportId)
if not supportData then return end
local charIds = { supportData.characterId }
if supportData.groupCharacterIds ~= nil then
charIds = supportData.groupCharacterIds or {}
end
local charInfos = Characters.getCharacterInfos(charIds)
local nameRO = frame.args['name_ro']
local nameWW = frame.args['name_ww']
local displayEN = nil
if #nameRO > 0 then displayEN = nameRO end
if #nameWW > 0 then displayEN = nameWW end
if supportData.displayNameEN then displayEN = supportData.displayNameEN end
local function wrapEpisode(textList)
local text = table.concat(textList, "\n")
text = string.gsub(text, "\n", "<br/>")
text = string.gsub(string.gsub(text, "<I>", "''"), "</I>", "''")
return tostring(mw.html.create('div'):addClass('episode-text'):wikitext(text))
end
local function wrapNowiki(text)
if text == nil then return nil end
return tostring(frame:preprocess(string.format("<nowiki>%s</nowiki>", text)))
end
local templateArgs = {
support_id = supportData.id,
name_jp = wrapNowiki(supportData.displayNameJP),
name_en = wrapNowiki(displayEN),
available_en = supportData.availableEN,
release_date_jp = supportData.releaseDateJP,
release_date_en = supportData.releaseDateEN,
rarity = supportData.rarity,
type = supportData.attribute,
full_page = supportData.fullPage,
episode_jp = wrapEpisode(supportData.episodeJP),
episode_en = supportData.episodeEN and wrapEpisode(supportData.episodeEN) or nil
}
local unique = supportData.effects.unique
if unique ~= nil then
templateArgs.unique_level = unique.level
local description = unique.descriptionEN or unique.descriptionJP
templateArgs.unique_description = table.concat(description, "")
for i, bonus in ipairs(unique.bonuses) do
local prettyName = Effects.getPrettyName(bonus.typeId)
templateArgs['unique_effect_' .. i] = prettyName
local val = tostring(bonus.value)
if bonus.hint ~= nil then
val = string.format("%s (%s)", val, bonus.hint)
end
templateArgs['unique_val_' .. i] = val
end
end
local c = 1
for _, char in pairs(charInfos) do
templateArgs["character_" .. c] = char.pageName
c = c + 1
end
for i, hint in ipairs(supportData.hintSkillIds) do
templateArgs["hint_" .. i] = hint
end
local text = frame:expandTemplate {
title = "Game Support Definition/page",
args = templateArgs
}
return text
end
function p.supportList(frame)
local results = Cargo.query {
from = 'Game_Supports',
fields = { '_pageName=supportPage', 'support_id', 'name_ro', 'name_ww' },
orderBy = "support_id",
limit = '9999',
}
local supportIds = {}
for _, data in ipairs(results) do
table.insert(supportIds, tostring(data.support_id))
end
local supportDatas = Data.getBatch(supportIds)
local paired = Utils.pairObjects(results, 'support_id', supportDatas, 'id')
local groups = {}
for _, pair in ipairs(paired) do
local cargoData, supportData = pair[1], pair[2] ---@type any
local text = string.format("[[File:%s|100px|link=%s]]", supportData.cardPage, cargoData.supportPage)
if groups[supportData.rarity] == nil then groups[supportData.rarity] = {} end
local rarityGroup = groups[supportData.rarity]
if rarityGroup[supportData.attribute] == nil then rarityGroup[supportData.attribute] = {} end
local attribGroup = rarityGroup[supportData.attribute]
table.insert(attribGroup, text)
end
local raritiesOrder = { 'SSR', 'SR', 'R' }
local attribsOrder = { 'Speed', 'Stamina', 'Power', 'Guts', 'Wit', 'Pal', 'Group' }
local text = ''
for _, rarity in ipairs(raritiesOrder) do
local rarityGroup = groups[rarity]
if rarityGroup ~= nil then
text = text .. string.format('== %s Supports ==\n\n', rarity)
for _, attrib in ipairs(attribsOrder) do
local attribGroup = rarityGroup[attrib]
if attribGroup ~= nil and #attribGroup > 0 then
text = text .. string.format('=== %s ===\n\n', attrib)
local root = mw.html.create('div'):cssText('display:flex; flex-flow:row wrap; gap: 10px;')
for _, cardText in ipairs(attribGroup) do
root:wikitext(cardText)
end
text = text .. tostring(root) .. '\n\n'
end
end
end
end
return text
end
function p.bonusTable(frame)
local supportId = mw.text.decode(frame.args[1])
if not supportId then return end
local supportData = Data.getSupport(supportId)
if not supportData then return end
local levels = {}
local minLevel = 30
local maxLevel = 50
if supportData.rarity == 'SR' then
minLevel = 25
maxLevel = 45
end
if supportData.rarity == 'R' then
minLevel = 20
maxLevel = 40
end
for i = minLevel, maxLevel, 5 do
table.insert(levels, i)
end
local nodeTable = mw.html.create('table'):addClass('wikitable'):addClass('uma-theme')
local nodeCaption = mw.html.create('caption'):wikitext('Bonuses')
nodeTable:node(nodeCaption)
-- Create Header Row
local nodeRowHead = mw.html.create('tr')
local headerText = { "Effect" }
for _, level in ipairs(levels) do
table.insert(headerText, "Lv" .. level)
end
for _, txt in ipairs(headerText) do
nodeRowHead:node(mw.html.create('th'):wikitext(txt))
end
nodeTable:node(nodeRowHead)
-- Create Effects Rows
for _, calc in ipairs(supportData.effects.calculated) do
local nodeRow = mw.html.create('tr')
local effectName = calc.typeNameEN or calc.typePrettyName
local effectDesc = calc.typeDescriptionEN or calc.typeDescriptionJP
local rowHeadText = frame:expandTemplate { title = "Tooltip", args = { effectName, effectDesc } }
local nodeHead = mw.html.create('th'):wikitext(rowHeadText)
nodeRow:node(nodeHead)
for _, lvl in ipairs(levels) do
for _, data in ipairs(calc.levels) do
if data.level == lvl then
local text = data.base or '-'
if data.unique ~= nil then
local add = string.format('(+%d)', data.unique)
if data.base ~= nil then
text = text .. ' ' .. add
else
text = add
end
end
local nodeData = mw.html.create('td'):wikitext(text)
nodeRow:node(nodeData)
end
end
end
nodeTable:node(nodeRow)
end
return nodeTable
end
return p