CombatCalc.lua 34 KB

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