Welcome to the Umamusume Wiki! If you want to contribute, please read the guidelines.
Module:Game/Supports/Data/Leveled
Documentation for this module may be created at Module:Game/Supports/Data/Leveled/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 Leveled = {}
local Game = require("Module:Game")
local Utils = require("Module:Utils")
local Effects = require("Module:Game/Supports/Data/Effects")
---@class SupportDataEffectLeveled
---@field typeId string
---@field values SupportDataEffectLeveledEntry[]
---@class SupportDataEffectLeveledEntry
---@field level number
---@field value number|nil
---@class SupportDataEffectCalculated
---@field typeId string
---@field typeNameJP string
---@field typeDescriptionJP string
---@field typeNameEN string|nil
---@field typeDescriptionEN string|nil
---@field typePrettyName string
---@field levels SupportDataEffectCalculatedLevel[]
---@class SupportDataEffectCalculatedLevel
---@field level number
---@field base number|nil
---@field unique number|nil
---@param support_datas table[]
---@return SupportDataEffectLeveled[][]
function Leveled.getSupportLevels(support_datas)
local supportIds = {}
local effectTableIds = {}
for _, support_data in ipairs(support_datas) do
table.insert(supportIds, support_data.id)
table.insert(effectTableIds, support_data.effect_table_id)
end
local effectTableIdsInsert = table.concat(effectTableIds, ',')
local maxLevels = {
['1'] = 40,
['2'] = 45,
['3'] = 50,
}
local effectTableMap = {}
local support_card_effect_tables = Game.queryMaster {
from = "support_card_effect_table",
where = string.format("id IN (%s)", effectTableIdsInsert)
}
for _, support_card_effect_table in ipairs(support_card_effect_tables) do
local key = support_card_effect_table.id
if effectTableMap[key] == nil then effectTableMap[key] = {} end
table.insert(effectTableMap[key], support_card_effect_table)
end
local datas = {}
for _, support_data in ipairs(support_datas) do
local effectTables = effectTableMap[support_data.id]
local maxLevel = maxLevels[support_data.rarity]
local effects = {}
for _, effectTable in ipairs(effectTables) do
local segments = {} ---@type SupportDataEffectLeveledEntry[]
local init = tonumber(effectTable.init) or -1
table.insert(segments, { level = 0, value = (init > -1) and init or nil })
for i = 5, maxLevel, 5 do
local val = tonumber(effectTable[string.format("limit_lv%s", i)]) or -1
table.insert(segments, { level = i, value = (val > -1) and val or nil })
end
local values = {}
local lastValue = segments[1]
for i, segment in ipairs(segments) do
local value = segment.value
if value ~= nil then
lastValue = segment
elseif lastValue.value ~= nil then
--- no value listed, interpolate between last and next valid segments
local nextValue = nil
for j = i + 1, #segments do
if segments[j].value ~= nil then
nextValue = segments[j]
break
end
end
if nextValue ~= nil then
local levelScale = (segment.level - lastValue.level) /
(nextValue.level - lastValue.level)
local valueScale = nextValue.value - lastValue.value
value = math.floor(valueScale * levelScale) + lastValue.value
else
value = lastValue.value
end
end
table.insert(values, { level = segment.level, value = value })
end
local effect = { ---@type SupportDataEffectLeveled
typeId = effectTable.type,
values = values
}
table.insert(effects, effect)
end
datas[support_data.id] = effects
end
return datas
end
---@param uniqueMap SupportDataEffectUnique[]
---@param leveledMap SupportDataEffectLeveled[][]
---@return SupportDataEffectCalculated[][]
function Leveled.getCalculatedLevels(uniqueMap, leveledMap)
local supportIds = {}
local allTypeIds = {}
local typeIdsMap = {}
local maxLevelMap = {}
for id, leveled in pairs(leveledMap) do
table.insert(supportIds, id)
typeIdsMap[id] = {}
maxLevelMap[id] = 0
for _, level in ipairs(leveled) do
table.insert(allTypeIds, level.typeId)
table.insert(typeIdsMap[id], level.typeId)
for _, entry in ipairs(level.values) do
if entry.level > maxLevelMap[id] then maxLevelMap[id] = entry.level end
end
end
end
--- add type ids from unique effects if they do not appear in leveling
for id, unique in pairs(uniqueMap) do
for _, bonus in ipairs(unique.bonuses) do
table.insert(allTypeIds, bonus.typeId)
table.insert(typeIdsMap[id], bonus.typeId)
end
typeIdsMap[id] = Utils.dedupe(typeIdsMap[id])
end
allTypeIds = Utils.dedupe(allTypeIds)
local typeNamesJP = Game.getJPText(151, allTypeIds)
local typeDescriptionsJP = Game.getJPText(154, allTypeIds)
local typeNamesEN = Game.getENText(151, allTypeIds)
local typeDescriptionsEN = Game.getENText(154, allTypeIds)
local datas = {}
for _, supportId in ipairs(supportIds) do
local unique = uniqueMap[supportId]
local leveled = leveledMap[supportId]
local maxLevel = maxLevelMap[supportId]
local typeIds = typeIdsMap[supportId]
table.sort(typeIds, function(a, b) return tonumber(a) < tonumber(b) end)
local calculated = {}
for _, typeId in ipairs(typeIds) do
local typeNameJP = typeNamesJP[typeId] or ''
local typeDescriptionJP = typeDescriptionsJP[typeId] or ''
local typeNameEN = typeNamesEN[typeId]
local typeDescriptionEN = typeDescriptionsEN[typeId]
local typedBonus = nil ---@type SupportDataEffectUniqueBonus|nil
if unique ~= nil then
for _, bonus in ipairs(unique.bonuses) do
if bonus.typeId == typeId then
typedBonus = bonus
break
end
end
end
local typedLevels = {} ---@type SupportDataEffectLeveledEntry[]
for _, level in ipairs(leveled) do
if level.typeId == typeId then
typedLevels = level.values
break
end
end
local levels = {}
for lvl = 0, maxLevel, 5 do
local baseVal = nil
local uniqueVal = nil
for _, typedLevel in ipairs(typedLevels) do
if typedLevel.level == lvl then
baseVal = typedLevel.value
end
end
if unique ~= nil and typedBonus ~= nil and lvl >= unique.level then
uniqueVal = typedBonus.value
end
local level = { ---@type SupportDataEffectCalculatedLevel
level = lvl,
base = baseVal,
unique = uniqueVal
}
table.insert(levels, level)
end
local data = { ---@type SupportDataEffectCalculated
typeId = typeId,
typeNameJP = typeNameJP,
typeDescriptionJP = typeDescriptionJP,
typeNameEN = typeNameEN,
typeDescriptionEN = typeDescriptionEN,
typePrettyName = Effects.getPrettyName(typeId),
levels = levels
}
table.insert(calculated, data)
end
datas[supportId] = calculated
end
return datas
end
return Leveled