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

Module:Game/Skills/Data

From Umamusume Wiki
Jump to navigation Jump to search

Documentation for this module may be created at Module:Game/Skills/Data/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 Data = {}
local Game = require("Module:Game")
local Utils = require("Module:Utils")
local Effects = require("Module:Game/Skills/Data/Effects")
local Groups = require("Module:Game/Skills/Data/Groups")
local Evolved = require("Module:Game/Skills/Data/Evolved")

---@class SkillData
---@field id string
---@field nameJP string
---@field descriptionJP string[]
---@field nameEN string|nil
---@field descriptionEN string[]|nil
---@field availableEN boolean
---@field iconPage string
---@field category string
---@field effects SkillEffect[]
---@field rarity number
---@field skillPointCost number
---@field skillPointCostAddl number|nil
---@field evalPoint number
---@field valueRatio number|nil
---@field upgradedTo string|nil
---@field upgradedFrom string|nil
---@field ultForCard string|nil
---@field evolvedFrom string|nil
---@field evolvedForCard string|nil
---@field inheritedInto string|nil
---@field inheritedVersionOf string|nil
---@field displayOrder number

---Get a single skill by its ID
---@param skillId string|number
---@return SkillData|nil
function Data.getSkill(skillId)
    local skill_data = Game.queryMaster {
        from = "skill_data",
        where = string.format("id = %s", skillId),
        limit = 1
    }
    if #skill_data == 0 then return nil end
    return Data._mapDatas(skill_data)[Utils.normalString(skillId)]
end

---Get a batch of skills by list of IDs
---@param skillIds string[]
---@return SkillData[]
function Data.getBatch(skillIds)
    local skillIdsInsert = table.concat(skillIds, ",")
    local skill_datas = Game.queryMaster {
        from = "skill_data",
        where = string.format("id IN (%s)", skillIdsInsert)
    }
    local mapped = Data._mapDatas(skill_datas)
    local datas = {}
    for _, skillId in ipairs(skillIds) do
        table.insert(datas, mapped[Utils.normalString(skillId)])
    end
    return datas
end

---@param skill_datas table[]
---@return SkillData[]
function Data._mapDatas(skill_datas)
    local skillIds = {}
    local skillGroupIdPairs = {}
    for i, skill_data in ipairs(skill_datas) do
        skillIds[i] = skill_data.id
        table.insert(skillGroupIdPairs, { skill_data.group_id, skill_data.id })
    end

    local skillIdsInsert = table.concat(skillIds, ",")

    local namesJP = Game.getJPText(47, skillIds)
    local descriptionsJP = Game.getJPText(48, skillIds)

    local namesEN = Game.getENText(47, skillIds)
    local descriptionsEN = Game.getENText(48, skillIds)

    local skill_datas_en = Game.queryMasterEN {
        from = "skill_data",
        where = string.format("id IN (%s)", skillIdsInsert),
        data = { "id" }
    }
    local availabilityEN = {}
    for _, skill_data in ipairs(skill_datas_en) do
        if skill_data[1] ~= nil then -- single results will mess up the iteration
            availabilityEN[skill_data[1]] = true
        end
    end

    local skillPointCosts = {}
    local needSkillPoints = Game.queryMaster {
        from = "single_mode_skill_need_point",
        where = string.format("id IN (%s)", skillIdsInsert),
    }
    for _, needSkillPoint in ipairs(needSkillPoints) do
        skillPointCosts[needSkillPoint.id] = tonumber(needSkillPoint.need_skill_point) or 0
    end

    local skillPointCostsAddl = Groups.getUpgradePathCosts(skillGroupIdPairs)
    local upgrades, downgrades = Groups.getUpgradesAndDowngrades(skillGroupIdPairs)

    local ultsForCards = Groups.getUltimateForCards(skillIds)
    local inheritsForSkills = Groups.getInheritForSkills(skillIds)
    local evolvedFroms, evolvedForCards = Evolved.getEvolvedFromSkillAndCard(skillIds)

    local datas = {}
    for _, skill_data in ipairs(skill_datas) do
        local nameJP = namesJP[skill_data.id] or ''
        local rawDescriptionJP = descriptionsJP[skill_data.id] or ''
        local descriptionJP = Utils.splitLines(rawDescriptionJP)

        local nameEN = namesEN[skill_data.id]
        local rawDescriptionEN = descriptionsEN[skill_data.id]
        local descriptionEN = rawDescriptionEN and Utils.splitLines(rawDescriptionEN) or nil

        local effects = Effects.getSkillEffects(skill_data)

        local skillPointCost = skillPointCosts[skill_data.id] or 0
        local skillPointCostAddl = skillPointCostsAddl[skill_data.id]

        local valueRatio = nil
        if skillPointCost or skillPointCostAddl then
            local totalCost = skillPointCost + (skillPointCostAddl or 0)
            if totalCost == 0 then totalCost = 1 end
            valueRatio = skill_data.grade_value / totalCost
        end

        local inheritedVersionOf = skill_data.unique_skill_id_1 ~= '0' and skill_data.unique_skill_id_1 or nil
        local inheritedInto = inheritsForSkills[skill_data.id]
        local upgradedTo = upgrades[skill_data.id]
        local upgradedFrom = downgrades[skill_data.id]
        local ultForCard = ultsForCards[skill_data.id]

        local evolvedFrom = evolvedFroms[skill_data.id]
        local evolvedForCard = evolvedForCards[skill_data.id]

        local category = "basic"
        if skill_data.rarity == '1' then
            if inheritedVersionOf then
                category = "ult_inherit"
            elseif (tonumber(skill_data.grade_value) or 0) < 0 then
                category = "debuff"
            end
        elseif skill_data.rarity == '2' then
            category = "rare"
        elseif skill_data.rarity == '3' then
            category = "ult_2"
        elseif skill_data.rarity == '4' or skill_data.rarity == '5' then
            category = "ult"
        elseif skill_data.rarity == '6' then
            category = "upgraded_scenario"
            if evolvedForCard ~= nil then
                category = "upgraded_card"
            end
        end

        local data = { ---@type SkillData
            id = skill_data.id,
            nameJP = nameJP,
            descriptionJP = descriptionJP,
            nameEN = nameEN,
            descriptionEN = descriptionEN,
            availableEN = availabilityEN[skill_data.id] == true,
            iconPage = string.format('Game Skill Icon %s.png', skill_data.icon_id),
            category = category,
            effects = effects,
            rarity = tonumber(skill_data.rarity) or 0,
            skillPointCost = skillPointCost,
            skillPointCostAddl = skillPointCostAddl,
            evalPoint = tonumber(skill_data.grade_value) or 0,
            valueRatio = valueRatio,
            upgradedTo = upgradedTo,
            upgradedFrom = upgradedFrom,
            ultForCard = ultForCard,
            evolvedFrom = evolvedFrom,
            evolvedForCard = evolvedForCard,
            inheritedInto = inheritedInto,
            inheritedVersionOf = inheritedVersionOf,
            displayOrder = tonumber(skill_data.disp_order) or 0,
        }
        datas[skill_data.id] = data
    end
    return datas
end

return Data