CombatCalc.lua 42 KB

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