模块:StyleAttributeGrowth
来自夜幕之下 Wiki - Reign of Nightfall 中文资料站
更多操作
此模块的文档可以在模块:StyleAttributeGrowth/doc创建
-- Module:StyleAttributeGrowth
-- 风格等级属性成长计算。只处理数据,不负责风格页样式。
local p = {}
local BREAK_LEVELS = {
[0] = 20,
[1] = 40,
[2] = 60,
[3] = 80,
[4] = 100,
}
local function num(value)
if value == nil or value == "" then return nil end
local n = tonumber(value)
if not n then return nil end
return n
end
local function firstGrowth(input)
if type(input) ~= "table" then return nil end
local rows = input.attribute_growths
if type(rows) == "table" then
for _, row in ipairs(rows) do
if type(row) == "table" and (row.status == "published" or row.status == nil) then
return row
end
end
return rows[1]
end
return input
end
function p.breakLevels()
return BREAK_LEVELS
end
function p.levelToBreakCount(level)
local lv = tonumber(level) or 1
if lv <= 20 then return 0 end
if lv <= 40 then return 1 end
if lv <= 60 then return 2 end
if lv <= 80 then return 3 end
return 4
end
function p.normalizeGrowth(input)
if type(input) == "table" and input.base and input.rate and input.break_bonus then
return input
end
local row = firstGrowth(input)
if type(row) ~= "table" then return nil end
local growth = {
status = row.status,
source_style_id = row.source_style_id,
source_hero_card_id = row.source_hero_card_id,
attr_rank = row.attr_rank,
formula_version = row.formula_version or "hero_level_growth_v1",
base = {
hp = num(row.base_hp),
atk = num(row.base_atk),
def = num(row.base_def),
},
rate = {
hp = num(row.hp_rate),
atk = num(row.atk_rate),
def = num(row.def_rate),
},
break_bonus = {
hp = num(row.break_hp),
atk = num(row.break_atk),
def = num(row.break_def),
},
}
if not growth.base.hp or not growth.base.atk or not growth.base.def
or not growth.rate.hp or not growth.rate.atk or not growth.rate.def
or not growth.break_bonus.hp or not growth.break_bonus.atk or not growth.break_bonus.def then
return nil
end
return growth
end
local function clamp(value, minValue, maxValue)
value = tonumber(value) or minValue
if value < minValue then return minValue end
if value > maxValue then return maxValue end
return value
end
local function calcOne(base, rate, breakBonus, level, breakCount)
return math.floor(base + (level - 1) * rate + breakCount * breakBonus)
end
function p.calculate(input, level, breakCount)
local growth = p.normalizeGrowth(input)
if not growth then return nil end
local lv = math.floor(clamp(level or 100, 1, 100))
local bc = breakCount
if bc == nil then
bc = p.levelToBreakCount(lv)
else
bc = math.floor(clamp(bc, 0, 4))
lv = math.floor(clamp(lv, 1, BREAK_LEVELS[bc] or 100))
end
local hpGrowth = (lv - 1) * growth.rate.hp
local atkGrowth = (lv - 1) * growth.rate.atk
local defGrowth = (lv - 1) * growth.rate.def
local hpBreak = bc * growth.break_bonus.hp
local atkBreak = bc * growth.break_bonus.atk
local defBreak = bc * growth.break_bonus.def
return {
level = lv,
break_count = bc,
max_level = BREAK_LEVELS[bc] or 100,
hp = calcOne(growth.base.hp, growth.rate.hp, growth.break_bonus.hp, lv, bc),
atk = calcOne(growth.base.atk, growth.rate.atk, growth.break_bonus.atk, lv, bc),
def = calcOne(growth.base.def, growth.rate.def, growth.break_bonus.def, lv, bc),
parts = {
hp = { base = growth.base.hp, growth = hpGrowth, break_bonus = hpBreak },
atk = { base = growth.base.atk, growth = atkGrowth, break_bonus = atkBreak },
def = { base = growth.base.def, growth = defGrowth, break_bonus = defBreak },
},
}
end
function p.payload(input, defaultLevel)
local growth = p.normalizeGrowth(input)
if not growth then return nil end
local result = p.calculate(growth, defaultLevel or 100)
return {
growth = growth,
result = result,
data = {
default_level = result.level,
formula_version = growth.formula_version,
base_hp = growth.base.hp,
base_atk = growth.base.atk,
base_def = growth.base.def,
hp_rate = growth.rate.hp,
atk_rate = growth.rate.atk,
def_rate = growth.rate.def,
break_hp = growth.break_bonus.hp,
break_atk = growth.break_bonus.atk,
break_def = growth.break_bonus.def,
},
}
end
return p