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

Module:Game/Skills/Data/Conditions

From Umamusume Wiki
Jump to navigation Jump to search

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

---@alias SkillConditions ConditionCheck[][]

---@class ConditionCheck
---@field condition string
---@field compare string
---@field value number
---@field hint string|nil

---Parse a skill conditions string into a list
---@param text string the conditions string
---@return SkillConditions
function Conditions.parseConditions(text)
    local ors = {}
    for orTxt in string.gmatch(text, "([^@]+)") do
        local ands = {}
        for andTxt in string.gmatch(orTxt, "([^&]+)") do
            local parsed = Conditions._parseCompare(andTxt)
            table.insert(ands, parsed)
        end
        table.insert(ors, ands)
    end
    return ors
end

---Gets the hint text for a given condition
---@param condition string
---@param compare string
---@param value number
---@return string|nil
function Conditions.getHintFor(condition, compare, value)
    local orderRateDir, orderRateVal = string.gmatch(condition, "order_rate_(%a+)(%d+)_continue")()
    if orderRateDir ~= nil and orderRateVal ~= nil then
        return Conditions._orderRateHint(orderRateVal, orderRateDir == 'in' and '<=' or ">=")
    end

    if condition == 'order_rate' then
        return Conditions._orderRateHint(value, compare)
    elseif condition == 'phase'
        or condition == 'phase_random'
        or condition == 'phase_firsthalf_random'
        or condition == 'phase_laterhalf_random'
        or condition == 'phase_firstquarter_random'
        or condition == 'phase_corner_random' then
        if value == 0 then
            return compare .. "Early"
        elseif value == 1 then
            return compare .. "Middle"
        elseif value == 2 then
            return compare .. "Late"
        elseif value == 3 then
            return compare .. "Last Spurt"
        end
    elseif condition == 'distance_type' then
        if value == 1 then
            return "Short"
        elseif value == 2 then
            return "Mile"
        elseif value == 3 then
            return "Mid"
        elseif value == 4 then
            return "Long"
        end
    elseif condition == 'running_style' then
        if value == 1 then
            return "Front Runner"
        elseif value == 2 then
            return "Pace Chaser"
        elseif value == 3 then
            return "Late Surger"
        elseif value == 4 then
            return "End Closer"
        end
    elseif condition == 'track_id' then
        if value == 10001 then
            return "Sapporo"
        elseif value == 10002 then
            return "Hakodate"
        elseif value == 10003 then
            return "Niigata"
        elseif value == 10004 then
            return "Fukushima"
        elseif value == 10005 then
            return "Nakayama"
        elseif value == 10006 then
            return "Tokyo"
        elseif value == 10007 then
            return "Chukyo"
        elseif value == 10008 then
            return "Kyoto"
        elseif value == 10009 then
            return "Hanshin"
        elseif value == 10010 then
            return "Kokura"
        elseif value == 10101 then
            return "Ooi"
        elseif value == 10103 then
            return "Kawasaki"
        elseif value == 10104 then
            return "Funabashi"
        elseif value == 10105 then
            return "Morioka"
        elseif value == 10201 then
            return "Longchamp"
        else
            return Game.getJPText(35, { value })[value]
        end
    elseif condition == "slope" then
        if value == 0 then
            return "Flat"
        elseif value == 1 then
            return "Uphill"
        elseif value == 2 then
            return "Downhill"
        end
    end

    return nil
end

---@param value number
---@param cmp string
function Conditions._orderRateHint(value, cmp)
    local place9 = math.floor((value / 100 * 9) + 0.5)
    local place12 = math.floor((value / 100 * 12) + 0.5)
    return string.format("CM%s%s LoH/PvP%s%s", cmp, place9, cmp, place12)
end

Conditions.compareTypes = { "==", "!=", ">=", "<=", ">", "<" }

---@param text string individual compare text
---@return ConditionCheck
function Conditions._parseCompare(text)
    for _, cmp in ipairs(Conditions.compareTypes) do
        local cond, value = string.gmatch(text, "([%w_]+)" .. cmp .. "(%d+)")()
        if cond ~= nil and value ~= nil then
            local valueNum = tonumber(value) or 0
            local hint = Conditions.getHintFor(cond, cmp, valueNum)
            return { ---@type ConditionCheck
                condition = cond,
                compare = cmp,
                value = valueNum,
                hint = hint
            }
        end
    end
    return { ---@type ConditionCheck
        condition = text,
        compare = "",
        value = 0,
    }
end

return Conditions