故事背景,上次屬性計算用的配置,這次傷害計算也走配置,下面是測試代碼和測試數據
local formulas =
{[100001]={id = 100001,name = "基礎傷害",formula = "function (self,tag,ishit,iscritial,counterratio)\n if ishit==1 then\n if tag.defence_inbattle*(1-self.armorpenetration_inbattle)<self.attack_inbattle then\n return math.max((self.attack_inbattle-tag.defence_inbattle*(1-self.armorpenetration_inbattle))*self.skillratio*(1+iscritial*(math.max(self.criticaldamage_inbattle-tag.recriticaldamage_inbattle,1)-1))*(1+counterratio)*(1+self.damageincreasemul-tag.damagedecreasemul)+self.damageincreaseadj-tag.damagedecreaseadj,1)\n else\n return math.max(self.attack_inbattle*self.attack_inbattle/(tag.defence_inbattle*(1-self.armorpenetration_inbattle)*5+self.attack_inbattle)*self.skillratio*(1+iscritial*(math.max(self.criticaldamage_inbattle-tag.recriticaldamage_inbattle,1)-1))*(1+counterratio)*(1+self.damageincreasemul-tag.damagedecreasemul)+self.damageincreaseadj-tag.damagedecreaseadj,1) \n end \n else\n return 0\n end\nend",},[100002]={id = 100002,name = "傷害/攻擊治療暴擊率計算公式",formula = "function(self,tag)\n return math.min(math.max(self.criticalrate_inbattle-tag.recriticalrate_inbattle,5%),1)\nend",},[100003]={id = 100003,name = "命中公式",formula = "function(self,tag)\n return math.min(math.max(self.hitrate_inbattle-tag.recriticalrate_inbattle,0),1)\nend",},[100004]={id = 100004,name = "效果命中公式",formula = "function(self,tag,basicprobability)\n return math.min(basicprobability*(1+self.effectrate_inbattle)/(1+tag.reeffectrate_inbattle),1)\nend",},[100005]={id = 100005,name = "治療公式-以我方最大生命治療",formula = "function(self)\n return self.hp_inbattle*self.skillratiomul+self.skillratioadj\nend",},[100006]={id = 100006,name = "治療公式-以我方攻擊治療",formula = "function(self,iscritial)\n return (self.attack_inbattle*self.skillratiomul+self.skillratioadj)*(1+iscritial*(self.criticaldamage_inbattle-1))\nend",},[100007]={id = 100007,name = "護盾公式-生命護盾",formula = "function(self)\n return self.hp_inbattle*self.skillratiomul+self.skillratioadj\nend",},[100008]={id = 100008,name = "護盾公式-防御護盾",formula = "function(self)\n return self.defence_inbattle*self.skillratiomul+self.skillratioadj\nend",},
}local function loadFormula(formulaStr)-- 1. 替換所有中文標點為英文標點formulaStr = formulaStr:gsub(")", ")")formulaStr = formulaStr:gsub("(", "(")formulaStr = formulaStr:gsub(",", ",")-- 2. 修正百分比符號問題(5% -> 0.05)formulaStr = formulaStr:gsub("(%d+)%%", function(n) return n/100 end)-- 3. 修正雙減號問題(--tag 應該是 - tag)formulaStr = formulaStr:gsub("%-%-", "- -")-- 4. 確保函數字符串格式正確if not formulaStr:match("^function%s*%(") thenformulaStr = "function" .. formulaStr:match("%b()") .. formulaStr:match("do.-\n") or formulaStr:match("%b{}") or formulaStr:match("return.-\n") or formulaStrend-- 5. 嘗試加載函數local chunk, err = load("return " .. formulaStr, "formula", "t")if not chunk thenchunk, err = load(formulaStr, "formula", "t")endif not chunk thenprint("Failed to load formula: " .. err)end-- 6. 執行并返回函數local success, func = pcall(chunk)if not success thenerror("Failed to execute formula: " .. func)endreturn func
endlocal formulas_list = {}
-- 預處理所有公式
for id, config in pairs(formulas) doif(config.formula)thenlocal success, result = pcall(loadFormula, config.formula)if success thenformulas_list[id] = resultelseprint("Error compiling formula", id, ":", result)endend
end-- 測試用例數據準備
local testSelf = {attack_inbattle = 1000,defence_inbattle = 500,armorpenetration_inbattle = 0.2,skillratio = 1.5,criticaldamage_inbattle = 2.0,damageincreasemul = 0.1,damageincreaseadj = 50,criticalrate_inbattle = 0.3,hitrate_inbattle = 0.9,effectrate_inbattle = 0.2,hp_inbattle = 10000,skillratiomul = 0.1,skillratioadj = 100
}local testTag = {defence_inbattle = 400,recriticaldamage_inbattle = 0.5,damagedecreasemul = 0.05,damagedecreaseadj = 20,recriticalrate_inbattle = 0.1,reeffectrate_inbattle = 0.1
}-- 測試每個公式
print("===== 開始測試公式 =====")-- 測試基礎傷害公式 (100001)
local baseDamage = formulas_list[100001](testSelf, testTag, 1, 1, 0)
print(string.format("基礎傷害 (命中+暴擊): %.2f", baseDamage))
baseDamage = formulas_list[100001](testSelf, testTag, 1, 0, 0)
print(string.format("基礎傷害 (命中無暴擊): %.2f", baseDamage))
baseDamage = formulas_list[100001](testSelf, testTag, 0, 1, 0)
print(string.format("基礎傷害 (未命中): %.2f", baseDamage))-- 測試暴擊率公式 (100002)
local critRate = formulas_list[100002](testSelf, testTag)
print(string.format("暴擊率: %.2f%%", critRate * 100))-- 測試命中率公式 (100003)
local hitRate = formulas_list[100003](testSelf, testTag)
print(string.format("命中率: %.2f%%", hitRate * 100))-- 測試效果命中公式 (100004)
local effectRate = formulas_list[100004](testSelf, testTag, 0.5)
print(string.format("效果命中率 (基礎50%%): %.2f%%", effectRate * 100))-- 測試治療公式 (100005)
local healByHP = formulas_list[100005](testSelf)
print(string.format("生命治療量: %.2f", healByHP))-- 測試攻擊治療公式 (100006)
local healByAttack = formulas_list[100006](testSelf, 1)
print(string.format("攻擊治療量 (暴擊): %.2f", healByAttack))
healByAttack = formulas_list[100006](testSelf, 0)
print(string.format("攻擊治療量 (無暴擊): %.2f", healByAttack))-- 測試護盾公式 (100007)
local hpShield = formulas_list[100007](testSelf)
print(string.format("生命護盾值: %.2f", hpShield))-- 測試防御護盾公式 (100008)
local defShield = formulas_list[100008](testSelf)
print(string.format("防御護盾值: %.2f", defShield))print("===== 測試完成 =====")