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

Module:Game/Skills/Data/Effects

From Umamusume Wiki
Jump to navigation Jump to search

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

---@class SkillEffect
---@field preconditions SkillConditions|nil
---@field conditions SkillConditions|nil
---@field duration number|nil
---@field durationScaling string|nil
---@field durationScalingId string|nil
---@field cooldown number|nil
---@field abilities SkillEffectAbility[]

---@class SkillEffectAbility
---@field ability string
---@field abilityId string
---@field value number
---@field valueFormat string
---@field valueScaling string|nil
---@field valueScalingId string|nil
---@field additionalActivation string|nil
---@field target SkillEffectAbilityTarget|nil

---@class SkillEffectAbilityTarget
---@field target string
---@field maxTargets number|nil
---@field targetId string
---@field targetValue number

---Maps all the skill effects for the given skill_data database object
---@param skill_data table[]
---@return SkillEffect[]
function Effects.getSkillEffects(skill_data)
    local rawEffects = Effects._mapEffects(skill_data)

    local effects = {}
    for _, rawEffect in ipairs(rawEffects) do
        local abilities = {}
        for _, rawAbility in ipairs(rawEffect.abilities) do
            local abilityDesc, fmt = Values.getAbilityType(rawAbility.abilityType)
            if abilityDesc ~= nil then
                local target = Values.getAbilityTarget(rawAbility.targetType, rawAbility.targetValue)
                local valueScaling = Values.getAbilityValueScaling(rawAbility.abilityValueUsage)
                local additionalActivation = Values.getAbilityAdditionalActivation(rawAbility.additionalActivateType)

                local ability = { ---@type SkillEffectAbility
                    ability = abilityDesc,
                    abilityId = rawAbility.abilityType,
                    value = (tonumber(rawAbility.floatAbilityValue) or 0) / 10000,
                    valueFormat = fmt or "none",
                    valueScaling = valueScaling,
                    valueScalingId = valueScaling ~= nil and rawAbility.abilityValueUsage or nil,
                    target = target,
                    additionalActivation = additionalActivation
                }
                table.insert(abilities, ability)
            end
        end

        if #abilities > 0 then
            local cooldown = (tonumber(rawEffect.floatCooldownTime) or 0) / 10000
            local preconditions = nil
            if #rawEffect.precondition > 0 then preconditions = Conditions.parseConditions(rawEffect.precondition) end
            local conditions = Conditions.parseConditions(rawEffect.condition)
            local duration = rawEffect.floatAbilityTime ~= '0' and rawEffect.floatAbilityTime ~= '-1' and
                ((tonumber(rawEffect.floatAbilityTime) or 0) / 10000) or
                nil
            local durationScaling = Values.getEffectDurationScaling(rawEffect.abilityTimeUsage)

            local effect = { ---@type SkillEffect
                preconditions = preconditions,
                conditions = conditions,
                duration = duration,
                durationScaling = durationScaling,
                durationScalingId = durationScaling ~= nil and rawEffect.abilityTimeUsage or nil,
                cooldown = (cooldown < 500 and cooldown > 0) and cooldown or nil,
                abilities = abilities,
            }
            table.insert(effects, effect)
        end
    end
    return effects
end

---@class RawEffect
---@field precondition string
---@field condition string
---@field floatAbilityTime string
---@field abilityTimeUsage string
---@field floatCooldownTime string
---@field abilities RawEffectAbility[]

---@class RawEffectAbility
---@field abilityType string
---@field abilityValueUsage string
---@field additionalActivateType string
---@field abilityValueLevelUsage string
---@field floatAbilityValue string
---@field targetType string
---@field targetValue string

---@param skill_data table
---@return RawEffect[]
function Effects._mapEffects(skill_data)
    local effects = {}
    for i = 1, 2 do
        local abilities = {}
        for j = 1, 3 do
            local suff = i .. '_' .. j
            local ability = { ---@type RawEffectAbility
                abilityType = skill_data['ability_type_' .. suff],
                abilityValueLevelUsage = skill_data['ability_value_level_usage_' .. suff],
                abilityValueUsage = skill_data['ability_value_usage_' .. suff],
                additionalActivateType = skill_data['additional_activate_type_' .. suff],
                floatAbilityValue = skill_data['float_ability_value_' .. suff],
                targetType = skill_data['target_type_' .. suff],
                targetValue = skill_data['target_value_' .. suff]
            }
            table.insert(abilities, ability)
        end

        local effect = { ---@type RawEffect
            precondition = skill_data['precondition_' .. i],
            condition = skill_data['condition_' .. i],
            floatAbilityTime = skill_data['float_ability_time_' .. i],
            abilityTimeUsage = skill_data['ability_time_usage_' .. i],
            floatCooldownTime = skill_data['float_cooldown_time_' .. i],
            abilities = abilities,
        }
        table.insert(effects, effect)
    end
    return effects
end

return Effects