CombatCalc.lua 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954
  1. ----------------------------------
  2. -- 战斗计算
  3. -- calcHurt 计算伤害
  4. ----------------------------------
  5. local CombatDefine = require("combat.CombatDefine")
  6. local CombatObj = require("combat.CombatObj")
  7. local RoleDefine = require("role.RoleDefine")
  8. local Util = require("common.Util")
  9. local CombatBuff = require("combat.CombatBuff")
  10. local CombatImpl = require("combat.CombatImpl")
  11. -- local SkillExcel = require("excel.skill").skill
  12. local Gm = require("chat.Gm")
  13. -- local BufferExcel = require("excel.buffer").buffer
  14. local BeSkill = require("combat.BeSkill")
  15. local CombatPosLogic = require("combat.CombatPosLogic")
  16. local CmdTypeExcel = require("excel.buffer").cmdType
  17. local WinnerRelicLogic = require("winnerRelic.WinnerRelicLogic")
  18. -- 基础攻击
  19. local function getBaseAtk(attacker)
  20. local baseAtk = attacker.attr[RoleDefine.ATK]
  21. return baseAtk
  22. end
  23. -- 攻击加成
  24. local function getAtkRate(attacker)
  25. local atkRate = attacker.attr[RoleDefine.ATK_RATE] or 0
  26. return atkRate / 10000
  27. end
  28. function getOutAtk(attacker)
  29. --local baseAtk = getBaseAtk(attacker)
  30. --local atkRate = getAtkRate(attacker)
  31. --local outAtk = baseAtk *(1 + atkRate)
  32. local outAtk = getBaseAtk(attacker)
  33. outAtk = outAtk + attacker.attr[RoleDefine.STEAL_ATK]
  34. outAtk = outAtk > 0 and outAtk or 0
  35. return outAtk
  36. end
  37. -- 护甲
  38. function getDef(defender, skillConfig)
  39. local def = defender.attr[RoleDefine.DEF]
  40. local rate = defender.attr[RoleDefine.DEF_RATE]
  41. def = def *(10000 + rate) / 10000
  42. def = def + defender.attr[RoleDefine.STEAL_DEF]
  43. def = def > 0 and def or 0
  44. return def
  45. end
  46. -- 破甲率
  47. local function getPojia(attacker, defender, skillConfig)
  48. local hushiHujia = skillConfig and skillConfig.otherArgs.hushiHujia or 0
  49. -- 职业忽视护甲
  50. local jobhushiHujia = skillConfig.otherArgs.jobhushiHujia
  51. if jobhushiHujia then
  52. for k, v in ipairs(jobhushiHujia[1]) do
  53. if defender.job == v then
  54. hushiHujia = hushiHujia + jobhushiHujia[2]
  55. break
  56. end
  57. end
  58. end
  59. -- 本阵容职业数破甲率提升
  60. local jobCamphushiHujia = skillConfig.otherArgs.jobCamphushiHujia
  61. if jobCamphushiHujia then
  62. for _,pos in ipairs(CombatDefine.SIDE2POS[attacker.side]) do
  63. local obj = CombatImpl.objList[pos]
  64. if obj and obj.job == jobCamphushiHujia[1] then
  65. hushiHujia = hushiHujia + jobCamphushiHujia[2]
  66. end
  67. end
  68. end
  69. local statusPoJia = BeSkill.getStatusPojia(attacker, defender)
  70. local pojia = attacker.attr[RoleDefine.POJIA] or 0
  71. local pojia_dk = defender.attr[RoleDefine.POJIA_DK] or 0
  72. local total = hushiHujia + pojia + statusPoJia - pojia_dk
  73. total = total < 0 and 0 or total
  74. return total/10000
  75. end
  76. -- 神圣伤害
  77. local function getShenshengHurtRate(attacker)
  78. local shenshengHurtRate = attacker.attr[RoleDefine.SHENSHENG_HURT_RATE] or 0
  79. return shenshengHurtRate / 10000
  80. end
  81. -- 是否格挡
  82. local function isGedang(defender)
  83. -- return false
  84. local geDangRate = CombatObj.getValue(defender, RoleDefine.GEDANG)
  85. if geDangRate <= 0 then
  86. return false
  87. end
  88. local randValue = math.random(0, 10000)
  89. if geDangRate > randValue then
  90. return true
  91. end
  92. return false
  93. end
  94. -- 减伤率proel
  95. local function getJianshangRate(attacker, defender)
  96. local jianshangRate = defender.attr[RoleDefine.JIANSHANG_RATE] or 0
  97. jianshangRate = jianshangRate + attacker.attr[RoleDefine.ATK_JIANSHANG_RATE] or 0
  98. if attacker.hurtType == CombatDefine.PHY_HURT_TYPE then
  99. jianshangRate = jianshangRate +(defender.attr[RoleDefine.JIANSHANG_PHY_RATE] or 0)
  100. elseif attacker.hurtType == CombatDefine.MAGIC_HURT_TYPE then
  101. jianshangRate = jianshangRate +(defender.attr[RoleDefine.JIANSHANG_MAGIC_RATE] or 0)
  102. end
  103. jianshangRate = jianshangRate + CombatObj.getJobJianshangRate(attacker, defender)
  104. jianshangRate = jianshangRate + CombatObj.getCampJianshangRate(attacker,defender)
  105. return jianshangRate/10000
  106. end
  107. -- 是否暴击
  108. local function isBaoji(attacker, defender, skillConfig)
  109. --if CombatImpl.isFanji or CombatImpl.comboType > 0 then
  110. -- return false
  111. --end
  112. if skillConfig.otherArgs and skillConfig.otherArgs.noBaoji == 1 then
  113. return false
  114. end
  115. if CombatBuff.isStatus(attacker, { "feng" }) then
  116. return false
  117. end
  118. local baoji = attacker.attr[RoleDefine.BAOJI] or 0
  119. baoji = baoji + CombatObj.getStatusBaoji(attacker, defender)
  120. -- 被动技能暴击加成
  121. baoji = baoji + BeSkill.getStatusBaoji(attacker, defender, skillConfig)
  122. local antiBaoji = defender.attr[RoleDefine.ANTI_BAOJI] or 0
  123. baoji = baoji - antiBaoji
  124. if skillConfig.otherArgs.addBaoji then
  125. baoji = baoji + skillConfig.otherArgs.addBaoji
  126. end
  127. if skillConfig.otherArgs.selfHpBaoJi then
  128. local cmpValue =(attacker.hp * 10000) / CombatObj.getHpMax(attacker) - skillConfig.otherArgs.selfHpBaoJi[2]
  129. if skillConfig.otherArgs.selfHpBaoJi[1] == 1 then
  130. if cmpValue >= 0 then
  131. baoji = baoji + skillConfig.otherArgs.selfHpBaoJi[3]
  132. end
  133. else
  134. if cmpValue <= 0 then
  135. baoji = baoji + skillConfig.otherArgs.selfHpBaoJi[3]
  136. end
  137. end
  138. end
  139. if skillConfig.otherArgs.addStatusBaoji then
  140. local status = CombatBuff.getStatus(defender)
  141. local isStatus = false
  142. for k, v in ipairs(skillConfig.otherArgs.addStatusBaoji[1]) do
  143. if status[v] then
  144. isStatus = true
  145. break
  146. end
  147. end
  148. if isStatus then
  149. baoji = baoji + skillConfig.otherArgs.addStatusBaoji[2]
  150. end
  151. end
  152. if skillConfig.otherArgs.addNotBaoji then
  153. if attacker.notSkillBaoJi and attacker.notSkillBaoJi[skillConfig.id] then
  154. baoji = baoji + skillConfig.otherArgs.addNotBaoji
  155. end
  156. end
  157. local r = math.random(0, 10000)
  158. if r <= baoji then
  159. attacker.notBaoJi = nil
  160. if attacker.notSkillBaoJi and attacker.notSkillBaoJi[skillConfig.id] then
  161. attacker.notSkillBaoJi[skillConfig.id] = nil
  162. end
  163. return true
  164. end
  165. attacker.notBaoJi = true
  166. if skillConfig.otherArgs.addNotBaoji then
  167. attacker.notSkillBaoJi = attacker.notSkillBaoJi or {}
  168. attacker.notSkillBaoJi[skillConfig.id] = true
  169. end
  170. end
  171. local function getBaojiHurtRate(attacker, defender, skillConfig)
  172. local baojiRate = 10000
  173. local isBaoji = isBaoji(attacker, defender, skillConfig)
  174. if isBaoji then
  175. baojiRate = attacker.attr[RoleDefine.BAOJI_HURT_RATE]
  176. if skillConfig.otherArgs and skillConfig.otherArgs.baojiHurtRate then
  177. baojiRate = baojiRate + skillConfig.otherArgs.baojiHurtRate
  178. end
  179. -- 对指定控制状态暴击加成 走的角色属性
  180. baojiRate = baojiRate + CombatObj.getStatusBaojiHurtRate(attacker, defender)
  181. -- 对指定状态暴击加成 走的技能状态属性
  182. if skillConfig.otherArgs.addStatusBaoji and skillConfig.otherArgs.addStatusBaoji[3] then
  183. local status = CombatBuff.getStatus(defender)
  184. local isStatus = false
  185. for k, v in ipairs(skillConfig.otherArgs.addStatusBaoji[1]) do
  186. if status[v] then
  187. isStatus = true
  188. break
  189. end
  190. end
  191. if isStatus then
  192. baojiRate = baojiRate + skillConfig.otherArgs.addStatusBaoji[3]
  193. end
  194. end
  195. baojiRate = baojiRate - defender.attr[RoleDefine.ANTI_BAOJI_HURT_RATE]
  196. baojiRate = baojiRate < 0 and 10000 or baojiRate
  197. end
  198. return isBaoji, baojiRate / 10000
  199. end
  200. -- 分摊比率
  201. FENTAN_TYPE1 = 1 -- 对所有攻击对象进行平摊
  202. local function getFentanRate(skillConfig, targets)
  203. local fentanParam = skillConfig.otherArgs and skillConfig.otherArgs.fentan
  204. if fentanParam then
  205. if fentanParam.type == 1 then
  206. return 1 / #targets
  207. end
  208. end
  209. return 1
  210. end
  211. --计算怒火层数
  212. local function getnuohuorate(attacker)
  213. local relicid = attacker.relic.relicID or 0
  214. local star = attacker.relic.star or 0
  215. local cengshu = 0
  216. if attacker.buffcmd["winner_nuhuo"] then
  217. local nIndex = attacker.buffcmd["winner_nuhuo"][1]
  218. local tBuffData = attacker.buffer[nIndex]
  219. if tBuffData.cnt < 10 then
  220. cengshu = tBuffData.cnt
  221. end
  222. end
  223. local addrate = 1
  224. if cengshu >= 0 then
  225. addrate = WinnerRelicLogic.WinnerRelic_GetRateLife(relicid,star)
  226. addrate = addrate * cengshu
  227. end
  228. -- print("getnuohuorate addrate = "..addrate.." cengshu = "..cengshu)
  229. return addrate
  230. end
  231. -- 被动技能影响的输出率
  232. local function getBeSkillOutRate(attacker, defender, skillConfig, index, targets)
  233. -- 被动技能影响的输出率
  234. local outBeSkillRate = BeSkill.getOutAtkRate(attacker, defender)
  235. outBeSkillRate = 10000 - outBeSkillRate
  236. outBeSkillRate = outBeSkillRate < 0 and 0 or outBeSkillRate
  237. return outBeSkillRate / 10000
  238. end
  239. -- 输出率(英雄技能伤害率+所有技能伤害率)
  240. local function getOutRate(attacker, defender, skillConfig, index, targets)
  241. -- 普攻技能伤害率
  242. -- if skillConfig.type == CombatDefine.SKILL_TYPE1 then
  243. -- return 10000
  244. -- en
  245. local hurtRate = index and skillConfig.hurtRate[index] or skillConfig.hurtRate[1]
  246. if not hurtRate or hurtRate == 0 then
  247. if CombatImpl.fightMode[1] == CombatDefine.FIGHT_MODE1 then
  248. return 10000 + CombatImpl.fightMode[4]
  249. end
  250. return 10000
  251. end
  252. if CombatImpl.fightMode[1] == CombatDefine.FIGHT_MODE1 then
  253. hurtRate = hurtRate + CombatImpl.fightMode[4]
  254. end
  255. local outBeSkillRate = BeSkill.getOutAtkRate2(attacker, skillConfig)
  256. hurtRate = hurtRate + outBeSkillRate
  257. -- 战斗模式的伤害加成(死战)
  258. local fentanRate = getFentanRate(skillConfig, targets)
  259. --怒火对伤害的加成
  260. -- local nuhuo = getnuohuorate(attacker)
  261. hurtRate = hurtRate * fentanRate
  262. local confHurtRate = skillConfig.otherArgs.extraHurtRate
  263. if confHurtRate then
  264. local r = math.random(0, 10000)
  265. for k, v in ipairs(confHurtRate) do
  266. if r <= v[1] then
  267. hurtRate = hurtRate *(1 + v[2] / 10000)
  268. break
  269. else
  270. r = r - v[1]
  271. end
  272. end
  273. end
  274. confHurtRate = skillConfig.otherArgs.extraSpeedHurt
  275. if confHurtRate then
  276. local atkSpeed = CombatObj.getValue(attacker, RoleDefine.SPEED)
  277. local defSpeed = CombatObj.getValue(defender, RoleDefine.SPEED)
  278. if atkSpeed > defSpeed then
  279. hurtRate = hurtRate + confHurtRate
  280. end
  281. end
  282. if skillConfig.otherArgs.targetHp then
  283. local cmpValue =(defender.hp * 10000) / CombatObj.getHpMax(defender) - skillConfig.otherArgs.targetHp[2]
  284. if skillConfig.otherArgs.targetHp[1] == 1 then
  285. if cmpValue >= 0 then
  286. hurtRate = hurtRate + skillConfig.otherArgs.targetHp[3]
  287. end
  288. else
  289. if cmpValue <= 0 then
  290. hurtRate = hurtRate + skillConfig.otherArgs.targetHp[3]
  291. end
  292. end
  293. end
  294. if skillConfig.otherArgs.selfHpHurt then
  295. local cmpValue =(attacker.hp * 10000) / CombatObj.getHpMax(attacker) - skillConfig.otherArgs.selfHpHurt[2]
  296. if skillConfig.otherArgs.selfHpHurt[1] == 1 then
  297. if cmpValue >= 0 then
  298. hurtRate = hurtRate + skillConfig.otherArgs.selfHpHurt[3]
  299. end
  300. else
  301. if cmpValue <= 0 then
  302. hurtRate = hurtRate + skillConfig.otherArgs.selfHpHurt[3]
  303. end
  304. end
  305. end
  306. if skillConfig.type == CombatDefine.SKILL_TYPE1 then
  307. return hurtRate
  308. end
  309. return hurtRate + attacker.attr[RoleDefine.SKILL_HURT_RATE]
  310. end
  311. -- 额外伤害加成百分比
  312. local function getExtraHurtRate(attacker, defender, skillConfig)
  313. local extraHurtRate = 0
  314. -- 虚弱
  315. extraHurtRate = extraHurtRate + defender.attr[RoleDefine.XURUO]
  316. -- 伤害加成
  317. extraHurtRate = extraHurtRate + attacker.attr[RoleDefine.HURT_RATE] + CombatPosLogic.getRestrict(attacker,defender,RoleDefine.HURT_RATE)
  318. -- buffer相关额外伤害加成
  319. extraHurtRate = extraHurtRate + CombatBuff.getExtraHurtRate(attacker, defender, skillConfig)
  320. -- 职业相关额外伤害加成
  321. extraHurtRate = extraHurtRate + CombatObj.getJobHurtRate(attacker, defender)
  322. -- 状态相关额外伤害加成
  323. extraHurtRate = extraHurtRate + CombatObj.getStatusHurtRate(attacker, defender)
  324. -- 被动技能伤害加成
  325. extraHurtRate = extraHurtRate + BeSkill.getExtraHurtRate(attacker, defender, skillConfig)
  326. -- 被动技能48伤害加成
  327. extraHurtRate = extraHurtRate + BeSkill.getExtraHurtRateEx(attacker, defender)
  328. -- 阵营相关额外伤害加成
  329. extraHurtRate = extraHurtRate + CombatObj.getCampHurtRate(attacker, defender)
  330. local jobHurt = skillConfig.otherArgs.jobHurt
  331. if jobHurt then
  332. for k, v in ipairs(jobHurt[1]) do
  333. if defender.job == v then
  334. extraHurtRate = extraHurtRate + jobHurt[2]
  335. break
  336. end
  337. end
  338. end
  339. if skillConfig.otherArgs.statusHurt then
  340. local status = CombatBuff.getStatus(defender)
  341. local isStatus = false
  342. for k, v in ipairs(skillConfig.otherArgs.statusHurt[1]) do
  343. if status[v] then
  344. isStatus = true
  345. break
  346. end
  347. end
  348. if isStatus then
  349. extraHurtRate = extraHurtRate + skillConfig.otherArgs.statusHurt[2]
  350. end
  351. end
  352. if skillConfig.otherArgs.statusHurt2 then
  353. local status = CombatBuff.getStatus(defender)
  354. local cmdList = CmdTypeExcel[skillConfig.otherArgs.statusHurt2[1]].cmd
  355. for k, v in ipairs(cmdList) do
  356. if status[v] then
  357. extraHurtRate = extraHurtRate + skillConfig.otherArgs.statusHurt2[2] * #status[v]
  358. end
  359. end
  360. end
  361. -- 负面状态 计算伤害率
  362. if skillConfig.otherArgs.statusHurt3 then
  363. local bufferCnt = CombatBuff.getCombatBufferCnt(defender, skillConfig.otherArgs.statusHurt3[1])
  364. if bufferCnt > 0 then
  365. extraHurtRate = extraHurtRate + skillConfig.otherArgs.statusHurt3[2] * bufferCnt
  366. end
  367. end
  368. return extraHurtRate / 10000
  369. end
  370. -- 额外伤害加成
  371. local function getExtraHurt(attacker, defender, skillConfig)
  372. local extraHurt = 0
  373. -- buffer相关额外伤害
  374. extraHurt = extraHurt + CombatBuff.getExtraHurt(attacker, defender, skillConfig)
  375. -- 被动技能额外伤害
  376. extraHurt = extraHurt + BeSkill.getExtraHurt(attacker, defender, skillConfig)
  377. return extraHurt
  378. end
  379. function initAttacker(attacker)
  380. if attacker.isPet then
  381. return
  382. end
  383. attacker.isBaoji = nil
  384. attacker.baojiHurtRate = nil
  385. attacker.handleAttr = nil
  386. CombatObj.setValue(attacker, RoleDefine.ATK_COMBAT_NOW, nil)
  387. CombatObj.setValue(attacker, RoleDefine.RATE_COMBAT_NOW, nil)
  388. CombatObj.setValue(attacker, RoleDefine.HURT_COMBAT_NOW, nil)
  389. attacker.beskill40 = nil
  390. end
  391. function calcPhyHurt(attacker, index, targets, skillConfig)
  392. local hurt = 0
  393. local flag = 0
  394. -- 技能是否无视护甲
  395. local noHuJia = false
  396. if skillConfig.otherArgs and skillConfig.otherArgs.noHuJia == 1 then
  397. noHuJia = true
  398. end
  399. local targetCnt = 1
  400. if skillConfig.otherArgs and skillConfig.otherArgs.hurtFenTan and skillConfig.otherArgs.hurtFenTan[1] == 1 then
  401. targetCnt = #targets
  402. end
  403. local defender = targets[index]
  404. local outRate = getOutRate(attacker, defender, skillConfig, index, targets)
  405. outRate = outRate / 10000
  406. local beSkillHurtRate = getBeSkillOutRate(attacker, defender, skillConfig)
  407. local pojia = getPojia(attacker, defender, skillConfig)
  408. local outAtk = attacker.attr[RoleDefine.ATK_COMBAT_NOW] or getOutAtk(attacker, skillConfig)
  409. local def = noHuJia == true and 0 or getDef(defender, skillConfig)
  410. local jianshangRate = getJianshangRate(attacker, defender)
  411. local extraHurtRate = getExtraHurtRate(attacker, defender, skillConfig)
  412. local extraHurt = getExtraHurt(attacker, defender, skillConfig)
  413. local isBaoji, baojiHurtRate = getBaojiHurtRate(attacker, defender, skillConfig)
  414. defender.isBaoji = isBaoji
  415. attacker.isBaoji = attacker.isBaoji or isBaoji
  416. if isBaoji then
  417. flag = Util.setBit(flag, CombatDefine.FLAG_BAOJI)
  418. end
  419. local shanghaiRate = 1 + extraHurtRate - jianshangRate
  420. shanghaiRate = shanghaiRate < 0 and 0 or shanghaiRate
  421. local coefDef = def * (1 - pojia)
  422. coefDef = coefDef < 0 and 0 or coefDef
  423. local rateCombatNow = (1 - coefDef / (coefDef + 600) ) * shanghaiRate
  424. hurt = outAtk * outRate * rateCombatNow * baojiHurtRate * beSkillHurtRate / targetCnt
  425. hurt = hurt + extraHurt
  426. CombatObj.setValue(attacker, RoleDefine.ATK_COMBAT_NOW, outAtk)
  427. -- 当伤害超过百分比 的 伤害 加深或者减免
  428. local parcentRate = BeSkill.getHurtPercentRate(attacker, defender, hurt, skillConfig)
  429. hurt = hurt *(1 + parcentRate / 10000)
  430. -- 测试用
  431. if Gm.wudi and attacker.pos <= 10 then
  432. hurt = 1000000000
  433. end
  434. -- 连击模式
  435. if CombatImpl.comboType > 0 then
  436. hurt = hurt * CombatImpl.comboHurtRate / 10000
  437. end
  438. if defender.fentq then
  439. hurt = math.ceil(hurt / defender.fentq)
  440. else
  441. --修正
  442. if hurt <= 10000 then
  443. hurt = hurt * math.random(100,500)/10000 + hurt
  444. else
  445. hurt = hurt * math.random(100,300)/10000 + hurt
  446. end
  447. end
  448. hurt = math.ceil(hurt)
  449. if defender.attr[RoleDefine.HURT_RATE_MAX] > 0 then
  450. local hurtMax = CombatObj.getHpMax(defender) * defender.attr[RoleDefine.HURT_RATE_MAX] / 10000
  451. if hurt > hurtMax then
  452. hurt = hurtMax
  453. end
  454. end
  455. -- 剧情模式
  456. if CombatImpl.fightMode[1] == CombatDefine.FIGHT_MODE2 then
  457. local skillList = CombatImpl.fightMode[2]
  458. for k, v in pairs(skillList) do
  459. if skillConfig.id == v then
  460. hurt = defender.hp * 0.9
  461. break
  462. end
  463. end
  464. end
  465. --是否触发格挡
  466. if isGedang(defender) then
  467. hurt = hurt * 0.5
  468. end
  469. hurt = math.max(hurt, 1)
  470. CombatObj.updateValue(attacker, RoleDefine.HURT_COMBAT_NOW, hurt)
  471. return hurt, flag
  472. end
  473. function calcMagicHurt(attacker, index, targets, skillConfig)
  474. local hurt = 0
  475. local flag = 0
  476. -- 技能是否无视护甲
  477. local noHuJia = false
  478. if skillConfig.otherArgs and skillConfig.otherArgs.noHuJia == 1 then
  479. noHuJia = true
  480. end
  481. local targetCnt = 1
  482. if skillConfig.otherArgs and skillConfig.otherArgs.hurtFenTan and skillConfig.otherArgs.hurtFenTan[1] == 1 then
  483. targetCnt = #targets
  484. end
  485. local defender = targets[index]
  486. local outRate = getOutRate(attacker, defender, skillConfig, index, targets)
  487. outRate = outRate / 10000
  488. local beSkillHurtRate = getBeSkillOutRate(attacker, defender, skillConfig)
  489. local pojia = getPojia(attacker, defender, skillConfig)
  490. local outAtk = attacker.attr[RoleDefine.ATK_COMBAT_NOW] or getOutAtk(attacker, skillConfig)
  491. local def = noHuJia == true and 0 or getDef(defender, skillConfig)
  492. local jianshangRate = getJianshangRate(attacker, defender)
  493. local extraHurtRate = getExtraHurtRate(attacker, defender, skillConfig)
  494. local extraHurt = getExtraHurt(attacker, defender, skillConfig)
  495. local isBaoji, baojiHurtRate = getBaojiHurtRate(attacker, defender, skillConfig)
  496. defender.isBaoji = isBaoji
  497. attacker.isBaoji = attacker.isBaoji or isBaoji
  498. if isBaoji then
  499. flag = Util.setBit(flag, CombatDefine.FLAG_BAOJI)
  500. end
  501. local shanghaiRate = 1 + extraHurtRate - jianshangRate
  502. shanghaiRate = shanghaiRate < 0 and 0 or shanghaiRate
  503. local coefDef = def * (1 - pojia)
  504. coefDef = coefDef < 0 and 0 or coefDef
  505. local rateCombatNow = (1 - coefDef / (coefDef + 600) ) * shanghaiRate
  506. hurt = outAtk * outRate * rateCombatNow * baojiHurtRate * beSkillHurtRate / targetCnt
  507. hurt = hurt + extraHurt
  508. CombatObj.setValue(attacker, RoleDefine.ATK_COMBAT_NOW, outAtk)
  509. -- 当伤害超过百分比 的 伤害 加深或者减免
  510. local parcentRate = BeSkill.getHurtPercentRate(attacker, defender, hurt, skillConfig)
  511. hurt = hurt *(1 + parcentRate / 10000)
  512. -- 测试用
  513. if Gm.wudi and attacker.pos <= 10 then
  514. hurt = 1000000000
  515. end
  516. -- 连击模式
  517. if CombatImpl.comboType > 0 then
  518. hurt = hurt * CombatImpl.comboHurtRate / 10000
  519. end
  520. if defender.fentq then
  521. hurt = math.ceil(hurt / defender.fentq)
  522. else
  523. --修正
  524. if hurt <= 10000 then
  525. hurt = hurt * math.random(100,500)/10000 + hurt
  526. else
  527. hurt = hurt * math.random(100,300)/10000 + hurt
  528. end
  529. end
  530. hurt = math.ceil(hurt)
  531. if defender.attr[RoleDefine.HURT_RATE_MAX] > 0 then
  532. local hurtMax = CombatObj.getHpMax(defender) * defender.attr[RoleDefine.HURT_RATE_MAX] / 10000
  533. if hurt > hurtMax then
  534. hurt = hurtMax
  535. end
  536. end
  537. -- 剧情模式
  538. if CombatImpl.fightMode[1] == CombatDefine.FIGHT_MODE2 then
  539. local skillList = CombatImpl.fightMode[2]
  540. for k, v in pairs(skillList) do
  541. if skillConfig.id == v then
  542. hurt = defender.hp * 0.9
  543. break
  544. end
  545. end
  546. end
  547. --是否触发格挡
  548. if isGedang(defender) then
  549. hurt = hurt * 0.5
  550. end
  551. hurt = hurt > 0 and hurt or 1
  552. CombatObj.updateValue(attacker, RoleDefine.HURT_COMBAT_NOW, hurt)
  553. return hurt, flag
  554. end
  555. --[[
  556. 防守方最终闪避 =防守方闪避 * (1 - 攻击方额外命中)
  557. ]]
  558. local function isShanbi(attacker, index, targets)
  559. local defender = targets[index]
  560. local jingzhun = CombatObj.getValue(attacker, RoleDefine.JINGZHUN) + CombatPosLogic.getRestrict(attacker,defender,RoleDefine.JINGZHUN)
  561. local shanbi = CombatObj.getValue(defender, RoleDefine.SHANBI)
  562. if jingzhun >= 10000 then
  563. local mingZhong = jingzhun - 10000
  564. mingZhong = mingZhong < 0 and 0 or mingZhong
  565. -- 强制设定额外命中不超过 99%
  566. if mingZhong >= 9900 then
  567. mingZhong = 9900
  568. end
  569. local shanbiRatio = 10000 - mingZhong
  570. shanbiRatio = shanbiRatio < 0 and 0 or shanbiRatio
  571. shanbi = math.floor(shanbi *(shanbiRatio / 10000))
  572. else
  573. shanbi = 10000 - jingzhun + shanbi
  574. end
  575. local r = math.random(1, 10000)
  576. if r < shanbi then
  577. return true
  578. end
  579. return false
  580. end
  581. function calcHurt(attacker, index, targets, skillConfig)
  582. -- 魔兽主动攻击伤害值为战前算出来的固定值
  583. if skillConfig.type == CombatDefine.SKILL_TYPE4 then
  584. return attacker.hurt or skillConfig.hurtRate[1], 0
  585. end
  586. if not skillConfig.otherArgs.absoluteHit and isShanbi(attacker, index, targets) then
  587. local flag = 0
  588. flag = Util.setBit(flag, CombatDefine.FLAG_SHANBI)
  589. return 0, flag
  590. end
  591. if attacker.hurtType == CombatDefine.MAGIC_HURT_TYPE then
  592. return calcMagicHurt(attacker, index, targets, skillConfig)
  593. elseif attacker.hurtType == CombatDefine.PHY_HURT_TYPE then
  594. return calcPhyHurt(attacker, index, targets, skillConfig)
  595. else
  596. return calcPhyHurt(attacker, index, targets, skillConfig)
  597. end
  598. end
  599. -- 额外作用,buff的伤害加成
  600. local function getCmdBuffHurtRate(attacker, defender)
  601. local extraHurtRate = 0
  602. if attacker and defender.pos and attacker.pos ~= defender.pos then
  603. extraHurtRate = extraHurtRate + CombatObj.getJobHurtRate(attacker, defender)
  604. -- 职业相关额外伤害加成
  605. extraHurtRate = extraHurtRate + CombatObj.getStatusHurtRate(attacker, defender)
  606. -- 状态相关额外伤害加成
  607. extraHurtRate = extraHurtRate + BeSkill.getExtraHurtRateEx(attacker, defender)
  608. --
  609. end
  610. return extraHurtRate / 10000
  611. end
  612. NO_EXCALC_LIST = {
  613. [7] = 1,
  614. [8] = 1,
  615. [11] = 1,
  616. [13] = 1,
  617. [14] = 1,
  618. [15] = 1,
  619. [16] = 1,
  620. [17] = 1,
  621. [18] = 1,
  622. [19] = 1,
  623. }
  624. function calcHp(attacker, defender, calcType, rate, isAddHp, flag)
  625. local hp
  626. -- 魔兽技能是 具体值 不需要 除以一万
  627. if calcType ~= 8 then
  628. rate = rate / 10000
  629. end
  630. local isCmdBuffHurtRate = nil
  631. local baoJi = 1
  632. if calcType == 1 then
  633. -- 攻击百分比(技能释放者)
  634. -- local atk = CombatObj.getValue(attacker,RoleDefine.ATK_COMBAT_NOW)
  635. -- hp = atk * rate
  636. local atk = CombatObj.getValue(attacker, RoleDefine.ATK)
  637. local atkRate = CombatObj.getValue(attacker, RoleDefine.ATK_RATE) / 10000
  638. local extraHurtRate = 0
  639. if not isAddHp then
  640. extraHurtRate = defender.attr[RoleDefine.XURUO] / 10000
  641. end
  642. hp = atk *(1 + extraHurtRate) * rate
  643. elseif calcType == 2 then
  644. -- 生命上限百分比(技能释放者)
  645. hp = CombatObj.getHpMax(attacker) * rate
  646. elseif calcType == 3 then
  647. -- 当前生命百分比(技能释放者)
  648. hp = attacker.hp * rate
  649. elseif calcType == 4 then
  650. -- 损失生命百分比(技能释放者)
  651. hp =(CombatObj.getHpMax(attacker) - attacker.hp) * rate
  652. elseif calcType == 5 then
  653. -- 目标生命百分比(技能目标)
  654. hp = defender.hp * rate
  655. elseif calcType == 6 then
  656. -- 目标生命上限百分比(技能目标)
  657. hp = CombatObj.getHpMax(defender) * rate
  658. if flag ~= nil and flag > 0 then
  659. local atk = CombatObj.getValue(defender, RoleDefine.ATK)
  660. local atkMax = flag * atk / 10000
  661. if hp > atkMax then
  662. hp = atkMax
  663. end
  664. end
  665. elseif calcType == 7 then
  666. -- 伤害百分比
  667. local realAttacker = CombatImpl.nowAttacker or attacker
  668. hp = CombatObj.getValue(realAttacker, RoleDefine.HURT_COMBAT_NOW) * rate
  669. isCmdBuffHurtRate = true
  670. elseif calcType == 8 then
  671. -- 具体值(魔兽用)
  672. hp = rate
  673. elseif calcType == 9 then
  674. -- 当前攻击力百分比
  675. local atk = CombatObj.getValue(defender, RoleDefine.ATK)
  676. hp = atk * rate
  677. elseif calcType == 10 then
  678. -- 技能暴击时伤害的百分比
  679. hp = getOutAtk(attacker)
  680. local baojiRate = 10000
  681. baojiRate = attacker.attr[RoleDefine.BAOJI_HURT_RATE]
  682. baojiRate = baojiRate / 10000
  683. baoJi = baojiRate * rate
  684. elseif calcType == 11 then
  685. -- 生命上限百分比不走公式(技能释放者)
  686. hp = CombatObj.getHpMax(attacker) * rate
  687. elseif calcType == 12 then
  688. -- 当前战斗回合造成的总伤害
  689. if attacker.combatResult[4] then
  690. hp = - attacker.combatResult[4] * rate
  691. else
  692. hp = 1
  693. end
  694. elseif calcType == 13 then
  695. -- 当前生命百分比(技能释放者,不算减伤)
  696. hp = attacker.hp * rate
  697. elseif calcType == 14 then
  698. -- 损失生命百分比(技能释放者,不算减伤)
  699. hp =(CombatObj.getHpMax(attacker) - attacker.hp) * rate
  700. elseif calcType == 15 then
  701. -- 目标生命百分比(技能目标,不算减伤)
  702. hp = defender.hp * rate
  703. elseif calcType == 16 then
  704. -- 目标生命上限百分比(技能目标,不算减伤)
  705. hp = CombatObj.getHpMax(defender) * rate
  706. if flag ~= nil and flag > 0 then
  707. local atk = CombatObj.getValue(defender, RoleDefine.ATK)
  708. local atkMax = flag * atk / 10000
  709. if hp > atkMax then
  710. hp = atkMax
  711. end
  712. end
  713. elseif calcType == 17 then
  714. -- 回合内 目标上一次对我造成的伤害
  715. if defender.combatResult[5] and defender.combatResult[5][attacker.pos] then
  716. hp = - defender.combatResult[5][attacker.pos] * rate
  717. else
  718. hp = 1
  719. end
  720. elseif calcType == 18 then
  721. -- 当前攻击力百分比(不算减伤)
  722. local atk = CombatObj.getValue(defender, RoleDefine.ATK)
  723. hp = atk * rate
  724. elseif calcType == 19 then
  725. -- 攻击百分比(技能释放者,不算减伤)
  726. local atk = CombatObj.getValue(attacker, RoleDefine.ATK)
  727. local atkRate = CombatObj.getValue(attacker, RoleDefine.ATK_RATE) / 10000
  728. local extraHurtRate = 0
  729. if not isAddHp then
  730. extraHurtRate = defender.attr[RoleDefine.XURUO] / 10000
  731. end
  732. hp = atk *(1 + atkRate) *(1 + extraHurtRate) * rate
  733. elseif calcType == 20 then
  734. -- 触发了被动技能类型40的攻击对象的伤害加成
  735. hp = 0
  736. if attacker.beskill40 then
  737. for pos in pairs(attacker.beskill40) do
  738. local hpAdd = attacker.combatResult[5][pos] or 0
  739. hp = hp + hpAdd
  740. end
  741. end
  742. hp = - hp * rate
  743. elseif calcType == 21 then
  744. -- 回合内 我对目标造成造成的伤害
  745. if attacker.combatResult[5] and attacker.combatResult[5][defender.pos] then
  746. hp = - attacker.combatResult[5][defender.pos] * rate
  747. else
  748. hp = 1
  749. end
  750. elseif calcType == 22 then
  751. -- 目标生命上限百分比(上限是自己的攻击)
  752. hp = CombatObj.getHpMax(defender) * rate
  753. if flag ~= nil and flag > 0 then
  754. local atk = CombatObj.getValue(attacker, RoleDefine.ATK)
  755. local atkMax = flag * atk / 10000
  756. if hp > atkMax then
  757. hp = atkMax
  758. end
  759. end
  760. elseif calcType == 23 then
  761. -- 目标损失生命上限百分比 上限时攻击的4倍
  762. hp = (CombatObj.getHpMax(defender) - defender.hp) * rate
  763. elseif calcType == 24 then
  764. -- 目标损失生命上限百分比 上限时攻击的4倍
  765. hp = CombatObj.getValue(defender, RoleDefine.RATE_COMBAT_NOW) * rate
  766. elseif calcType == 25 then
  767. -- 目标当前生命百分比,不超过攻击者攻击力的10倍
  768. local atk = CombatObj.getValue(attacker, RoleDefine.ATK)
  769. local nMaxHp = atk * 10
  770. hp = defender.hp * rate
  771. if hp > nMaxHp then
  772. hp = nMaxHp
  773. end
  774. elseif calcType == 26 then
  775. -- 当前攻击者攻击力百分比
  776. local atk = CombatObj.getValue(attacker, RoleDefine.ATK)
  777. hp = atk * rate
  778. end
  779. if not NO_EXCALC_LIST[calcType] then
  780. if isAddHp then
  781. if defender.type == CombatDefine.COMBAT_OBJ_TYPE3 then
  782. hp = 0
  783. else
  784. local hpAddRate = CombatObj.getValue(defender, RoleDefine.HP_ADD_RATE) / 10000
  785. hp = hp *(1 + hpAddRate)
  786. hp = hp < 0 and 1 or hp
  787. end
  788. --[[
  789. else
  790. local defRate = getDef(defender)
  791. local jianshangRate = getJianshangRate(attacker, defender)
  792. local rateCombatNow =(1 -(defRate /(defRate + 600))) *(1 - jianshangRate)
  793. hp = hp * rateCombatNow * baoJi
  794. ]]--
  795. end
  796. end
  797. if not isAddHp and not isCmdBuffHurtRate then
  798. hp = hp * (1 + getCmdBuffHurtRate(attacker, defender))
  799. end
  800. if isAddHp and CombatImpl.comboType > 0 then
  801. hp = math.ceil(hp * 0.5)
  802. end
  803. hp = hp > 0 and hp or 0
  804. return hp
  805. end
  806. function calcBufferHp(attacker, defender, bufferID, isAddHp)
  807. --local conf = BufferExcel[bufferID]
  808. local conf = CombatBuff.GetBuffConfig(bufferID)
  809. local args
  810. if attacker.isPet then
  811. args = attacker.buffers[bufferID].args
  812. else
  813. args = conf.args
  814. end
  815. local hp = calcHp(attacker, defender, args[1], args[2], isAddHp)
  816. if args[5] then
  817. local limit = args[5] * CombatObj.getValue(attacker, RoleDefine.ATK_COMBAT_NOW) / 10000
  818. if hp > limit then
  819. hp = limit
  820. end
  821. end
  822. return hp
  823. end
  824. function calcValue(attacker, defender, calcType, rate)
  825. local value = 0
  826. rate = rate / 10000
  827. if calcType == 1 then
  828. -- 攻击百分比(技能防守)
  829. local atk = CombatObj.getValue(defender, RoleDefine.ATK)
  830. local atkValue = atk * rate
  831. if attacker.pos == defender.pos then
  832. value = value + atkValue
  833. else
  834. value = value - atkValue
  835. end
  836. end
  837. return value
  838. end