CombatCalc.lua 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005
  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 total = hushiHujia + pojia + statusPoJia
  72. total = total < 0 and 0 or total
  73. return total/10000
  74. end
  75. -- 神圣伤害
  76. local function getShenshengHurtRate(attacker)
  77. local shenshengHurtRate = attacker.attr[RoleDefine.SHENSHENG_HURT_RATE] or 0
  78. return shenshengHurtRate / 10000
  79. end
  80. -- 是否格挡
  81. local function isGedang(defender)
  82. -- return false
  83. local geDangRate = CombatObj.getValue(defender, RoleDefine.GEDANG)
  84. if geDangRate <= 0 then
  85. return false
  86. end
  87. local randValue = math.random(0, 10000)
  88. if geDangRate > randValue then
  89. return true
  90. end
  91. return false
  92. end
  93. -- 减伤率proel
  94. local function getJianshangRate(attacker, defender)
  95. local jianshangRate = defender.attr[RoleDefine.JIANSHANG_RATE] or 0
  96. jianshangRate = jianshangRate + attacker.attr[RoleDefine.ATK_JIANSHANG_RATE] or 0
  97. if attacker.hurtType == CombatDefine.PHY_HURT_TYPE then
  98. jianshangRate = jianshangRate +(defender.attr[RoleDefine.JIANSHANG_PHY_RATE] or 0)
  99. elseif attacker.hurtType == CombatDefine.MAGIC_HURT_TYPE then
  100. jianshangRate = jianshangRate +(defender.attr[RoleDefine.JIANSHANG_MAGIC_RATE] or 0)
  101. end
  102. jianshangRate = jianshangRate + CombatObj.getJobJianshangRate(attacker, defender)
  103. jianshangRate = jianshangRate + CombatObj.getCampJianshangRate(attacker,defender)
  104. return jianshangRate/10000
  105. end
  106. -- 是否暴击
  107. local function isBaoji(attacker, defender, skillConfig)
  108. --if CombatImpl.isFanji or CombatImpl.comboType > 0 then
  109. -- return false
  110. --end
  111. if skillConfig.otherArgs and skillConfig.otherArgs.noBaoji == 1 then
  112. return false
  113. end
  114. if CombatBuff.isStatus(attacker, { "feng" }) then
  115. return false
  116. end
  117. local baoji = attacker.attr[RoleDefine.BAOJI] or 0
  118. baoji = baoji + CombatObj.getStatusBaoji(attacker, defender)
  119. -- 被动技能暴击加成
  120. baoji = baoji + BeSkill.getStatusBaoji(attacker, defender, skillConfig)
  121. local antiBaoji = defender.attr[RoleDefine.ANTI_BAOJI] or 0
  122. baoji = baoji - antiBaoji
  123. if skillConfig.otherArgs.addBaoji then
  124. baoji = baoji + skillConfig.otherArgs.addBaoji
  125. end
  126. if skillConfig.otherArgs.selfHpBaoJi then
  127. local cmpValue =(attacker.hp * 10000) / CombatObj.getHpMax(attacker) - skillConfig.otherArgs.selfHpBaoJi[2]
  128. if skillConfig.otherArgs.selfHpBaoJi[1] == 1 then
  129. if cmpValue >= 0 then
  130. baoji = baoji + skillConfig.otherArgs.selfHpBaoJi[3]
  131. end
  132. else
  133. if cmpValue <= 0 then
  134. baoji = baoji + skillConfig.otherArgs.selfHpBaoJi[3]
  135. end
  136. end
  137. end
  138. if skillConfig.otherArgs.addStatusBaoji then
  139. local status = CombatBuff.getStatus(defender)
  140. local isStatus = false
  141. for k, v in ipairs(skillConfig.otherArgs.addStatusBaoji[1]) do
  142. if status[v] then
  143. isStatus = true
  144. break
  145. end
  146. end
  147. if isStatus then
  148. baoji = baoji + skillConfig.otherArgs.addStatusBaoji[2]
  149. end
  150. end
  151. if skillConfig.otherArgs.addNotBaoji then
  152. if attacker.notSkillBaoJi and attacker.notSkillBaoJi[skillConfig.id] then
  153. baoji = baoji + skillConfig.otherArgs.addNotBaoji
  154. end
  155. end
  156. local r = math.random(0, 10000)
  157. if r <= baoji then
  158. attacker.notBaoJi = nil
  159. if attacker.notSkillBaoJi and attacker.notSkillBaoJi[skillConfig.id] then
  160. attacker.notSkillBaoJi[skillConfig.id] = nil
  161. end
  162. return true
  163. end
  164. attacker.notBaoJi = true
  165. if skillConfig.otherArgs.addNotBaoji then
  166. attacker.notSkillBaoJi = attacker.notSkillBaoJi or {}
  167. attacker.notSkillBaoJi[skillConfig.id] = true
  168. end
  169. end
  170. local function getBaojiHurtRate(attacker, defender, skillConfig)
  171. local baojiRate = 10000
  172. local isBaoji = isBaoji(attacker, defender, skillConfig)
  173. if isBaoji then
  174. baojiRate = attacker.attr[RoleDefine.BAOJI_HURT_RATE]
  175. if skillConfig.otherArgs and skillConfig.otherArgs.baojiHurtRate then
  176. baojiRate = baojiRate + skillConfig.otherArgs.baojiHurtRate
  177. end
  178. -- 对指定控制状态暴击加成 走的角色属性
  179. baojiRate = baojiRate + CombatObj.getStatusBaojiHurtRate(attacker, defender)
  180. -- 对指定状态暴击加成 走的技能状态属性
  181. if skillConfig.otherArgs.addStatusBaoji and skillConfig.otherArgs.addStatusBaoji[3] then
  182. local status = CombatBuff.getStatus(defender)
  183. local isStatus = false
  184. for k, v in ipairs(skillConfig.otherArgs.addStatusBaoji[1]) do
  185. if status[v] then
  186. isStatus = true
  187. break
  188. end
  189. end
  190. if isStatus then
  191. baojiRate = baojiRate + skillConfig.otherArgs.addStatusBaoji[3]
  192. end
  193. end
  194. baojiRate = baojiRate - defender.attr[RoleDefine.ANTI_BAOJI_HURT_RATE]
  195. baojiRate = baojiRate < 0 and 10000 or baojiRate
  196. end
  197. return isBaoji, baojiRate / 10000
  198. end
  199. -- 分摊比率
  200. FENTAN_TYPE1 = 1 -- 对所有攻击对象进行平摊
  201. local function getFentanRate(skillConfig, targets)
  202. local fentanParam = skillConfig.otherArgs and skillConfig.otherArgs.fentan
  203. if fentanParam then
  204. if fentanParam.type == 1 then
  205. return 1 / #targets
  206. end
  207. end
  208. return 1
  209. end
  210. --计算怒火层数
  211. local function getnuohuorate(attacker)
  212. local relicid = attacker.relic.relicID or 0
  213. local star = attacker.relic.star or 0
  214. local cengshu = 0
  215. if attacker.buffcmd["winner_nuhuo"] then
  216. local nIndex = attacker.buffcmd["winner_nuhuo"][1]
  217. local tBuffData = attacker.buffer[nIndex]
  218. if tBuffData.cnt < 10 then
  219. cengshu = tBuffData.cnt
  220. end
  221. end
  222. local addrate = 1
  223. if cengshu >= 0 then
  224. addrate = WinnerRelicLogic.WinnerRelic_GetRateLife(relicid,star)
  225. addrate = addrate * cengshu
  226. end
  227. -- print("getnuohuorate addrate = "..addrate.." cengshu = "..cengshu)
  228. return addrate
  229. end
  230. -- 被动技能影响的输出率
  231. local function getBeSkillOutRate(attacker, defender, skillConfig, index, targets)
  232. -- 被动技能影响的输出率
  233. local outBeSkillRate = BeSkill.getOutAtkRate(attacker, defender)
  234. outBeSkillRate = 10000 - outBeSkillRate
  235. outBeSkillRate = outBeSkillRate < 0 and 0 or outBeSkillRate
  236. return outBeSkillRate / 10000
  237. end
  238. -- 输出率(英雄技能伤害率+所有技能伤害率)
  239. local function getOutRate(attacker, defender, skillConfig, index, targets)
  240. -- 普攻技能伤害率
  241. -- if skillConfig.type == CombatDefine.SKILL_TYPE1 then
  242. -- return 10000
  243. -- en
  244. local hurtRate = index and skillConfig.hurtRate[index] or skillConfig.hurtRate[1]
  245. if not hurtRate or hurtRate == 0 then
  246. if CombatImpl.fightMode[1] == CombatDefine.FIGHT_MODE1 then
  247. return 10000 + CombatImpl.fightMode[4]
  248. end
  249. return 10000
  250. end
  251. if CombatImpl.fightMode[1] == CombatDefine.FIGHT_MODE1 then
  252. hurtRate = hurtRate + CombatImpl.fightMode[4]
  253. end
  254. -- 战斗模式的伤害加成(死战)
  255. local fentanRate = getFentanRate(skillConfig, targets)
  256. --怒火对伤害的加成
  257. -- local nuhuo = getnuohuorate(attacker)
  258. hurtRate = hurtRate * fentanRate
  259. local confHurtRate = skillConfig.otherArgs.extraHurtRate
  260. if confHurtRate then
  261. local r = math.random(0, 10000)
  262. for k, v in ipairs(confHurtRate) do
  263. if r <= v[1] then
  264. hurtRate = hurtRate *(1 + v[2] / 10000)
  265. break
  266. else
  267. r = r - v[1]
  268. end
  269. end
  270. end
  271. confHurtRate = skillConfig.otherArgs.extraSpeedHurt
  272. if confHurtRate then
  273. local atkSpeed = CombatObj.getValue(attacker, RoleDefine.SPEED)
  274. local defSpeed = CombatObj.getValue(defender, RoleDefine.SPEED)
  275. if atkSpeed > defSpeed then
  276. hurtRate = hurtRate + confHurtRate
  277. end
  278. end
  279. if skillConfig.otherArgs.targetHp then
  280. local cmpValue =(defender.hp * 10000) / CombatObj.getHpMax(defender) - skillConfig.otherArgs.targetHp[2]
  281. if skillConfig.otherArgs.targetHp[1] == 1 then
  282. if cmpValue >= 0 then
  283. hurtRate = hurtRate + skillConfig.otherArgs.targetHp[3]
  284. end
  285. else
  286. if cmpValue <= 0 then
  287. hurtRate = hurtRate + skillConfig.otherArgs.targetHp[3]
  288. end
  289. end
  290. end
  291. if skillConfig.otherArgs.selfHpHurt then
  292. local cmpValue =(attacker.hp * 10000) / CombatObj.getHpMax(attacker) - skillConfig.otherArgs.selfHpHurt[2]
  293. if skillConfig.otherArgs.selfHpHurt[1] == 1 then
  294. if cmpValue >= 0 then
  295. hurtRate = hurtRate + skillConfig.otherArgs.selfHpHurt[3]
  296. end
  297. else
  298. if cmpValue <= 0 then
  299. hurtRate = hurtRate + skillConfig.otherArgs.selfHpHurt[3]
  300. end
  301. end
  302. end
  303. if skillConfig.type == CombatDefine.SKILL_TYPE1 then
  304. return hurtRate
  305. end
  306. return hurtRate + attacker.attr[RoleDefine.SKILL_HURT_RATE]
  307. end
  308. -- 额外伤害加成百分比
  309. local function getExtraHurtRate(attacker, defender, skillConfig)
  310. local extraHurtRate = 0
  311. -- 虚弱
  312. extraHurtRate = extraHurtRate + defender.attr[RoleDefine.XURUO]
  313. -- 伤害加成
  314. extraHurtRate = extraHurtRate + attacker.attr[RoleDefine.HURT_RATE] + CombatPosLogic.getRestrict(attacker,defender,RoleDefine.HURT_RATE)
  315. -- buffer相关额外伤害加成
  316. extraHurtRate = extraHurtRate + CombatBuff.getExtraHurtRate(attacker, defender, skillConfig)
  317. -- 职业相关额外伤害加成
  318. extraHurtRate = extraHurtRate + CombatObj.getJobHurtRate(attacker, defender)
  319. -- 状态相关额外伤害加成
  320. extraHurtRate = extraHurtRate + CombatObj.getStatusHurtRate(attacker, defender)
  321. -- 被动技能伤害加成
  322. extraHurtRate = extraHurtRate + BeSkill.getExtraHurtRate(attacker, defender, skillConfig)
  323. -- 被动技能48伤害加成
  324. extraHurtRate = extraHurtRate + BeSkill.getExtraHurtRateEx(attacker, defender)
  325. -- 阵营相关额外伤害加成
  326. extraHurtRate = extraHurtRate + CombatObj.getCampHurtRate(attacker, defender)
  327. local jobHurt = skillConfig.otherArgs.jobHurt
  328. if jobHurt then
  329. for k, v in ipairs(jobHurt[1]) do
  330. if defender.job == v then
  331. extraHurtRate = extraHurtRate + jobHurt[2]
  332. break
  333. end
  334. end
  335. end
  336. if skillConfig.otherArgs.statusHurt then
  337. local status = CombatBuff.getStatus(defender)
  338. local isStatus = false
  339. for k, v in ipairs(skillConfig.otherArgs.statusHurt[1]) do
  340. if status[v] then
  341. isStatus = true
  342. break
  343. end
  344. end
  345. if isStatus then
  346. extraHurtRate = extraHurtRate + skillConfig.otherArgs.statusHurt[2]
  347. end
  348. end
  349. if skillConfig.otherArgs.statusHurt2 then
  350. local status = CombatBuff.getStatus(defender)
  351. local cmdList = CmdTypeExcel[skillConfig.otherArgs.statusHurt2[1]].cmd
  352. for k, v in ipairs(cmdList) do
  353. if status[v] then
  354. extraHurtRate = extraHurtRate + skillConfig.otherArgs.statusHurt2[2] * #status[v]
  355. end
  356. end
  357. end
  358. -- 负面状态 计算伤害率
  359. if skillConfig.otherArgs.statusHurt3 then
  360. local bufferCnt = CombatBuff.getCombatBufferCnt(defender, skillConfig.otherArgs.statusHurt3[1])
  361. if bufferCnt > 0 then
  362. extraHurtRate = extraHurtRate + skillConfig.otherArgs.statusHurt3[2] * bufferCnt
  363. end
  364. end
  365. return extraHurtRate / 10000
  366. end
  367. -- 额外伤害加成
  368. local function getExtraHurt(attacker, defender, skillConfig)
  369. local extraHurt = 0
  370. -- buffer相关额外伤害
  371. extraHurt = extraHurt + CombatBuff.getExtraHurt(attacker, defender, skillConfig)
  372. -- 被动技能额外伤害
  373. extraHurt = extraHurt + BeSkill.getExtraHurt(attacker, defender, skillConfig)
  374. --buff, debuff 数量差的额外伤害
  375. if skillConfig.otherArgs.buffDiffHurt then
  376. local condInfo = skillConfig.otherArgs.buffDiffHurt
  377. local buffType1 = condInfo[1] --buff类型1, 对应配置表buff中qusan分页中的type
  378. local buffType2 = condInfo[2] --buff类型2, 对应配置表buff中qusan分页中的type
  379. local chooseType1 = condInfo[3] --选择类型, 1-表示取被攻击者的某个属性, 2-取攻击者的某个属性
  380. local calAttrType = condInfo[4] --用来计算伤害的属性类型, 与RoleDefine.lua中一致, 为0表示生命最大值
  381. local calAttrRate = condInfo[5] --用来计算伤害的属性倍率, 万分比
  382. local chooseType2 = condInfo[6] --选择类型, 1-表示取被攻击者的某个属性, 2-取攻击者的某个属性
  383. local limitAttrType = condInfo[7] --用来判断伤害上限的属性类型, 与RoleDefine.lua中属性一致
  384. local limitAttrRate = condInfo[8] --用来判断伤害上限的属性倍率, 多少倍就配多少
  385. if buffType1 and buffType2 and chooseType1 and calAttrType and calAttrRate then
  386. local buffCnt1 = CombatBuff.getCombatBufferCnt(defender, buffType1)
  387. local buffCnt2 = CombatBuff.getCombatBufferCnt(defender, buffType2)
  388. if buffCnt1 > buffCnt2 then
  389. local calAttrValue = 0
  390. local targetObj1 = defender
  391. if chooseType1 == 2 then
  392. targetObj1 = attacker
  393. end
  394. if calAttrType == 0 then
  395. calAttrValue = CombatObj.getHpMax(targetObj1)
  396. else
  397. calAttrValue = CombatObj.getValue(targetObj1, calAttrType)
  398. end
  399. local hurt = calAttrValue * (calAttrRate / 10000)
  400. hurt = hurt * (buffCnt1 - buffCnt2)
  401. --上限判断
  402. if chooseType2 and limitAttrType and limitAttrRate then
  403. local limitAttrVale = 0
  404. local targetObj2 = attacker
  405. if chooseType2 == 1 then
  406. targetObj2 = defender
  407. end
  408. if limitAttrType == 0 then
  409. limitAttrVale = CombatObj.getHpMax(targetObj2)
  410. else
  411. limitAttrVale = CombatObj.getValue(targetObj2, limitAttrType)
  412. end
  413. local limitHurt = limitAttrVale * limitAttrRate
  414. if hurt > limitHurt then
  415. hurt = limitHurt
  416. end
  417. end
  418. extraHurt = extraHurt + hurt
  419. end
  420. end
  421. end
  422. return extraHurt
  423. end
  424. function initAttacker(attacker)
  425. if attacker.isPet then
  426. return
  427. end
  428. attacker.isBaoji = nil
  429. attacker.baojiHurtRate = nil
  430. attacker.handleAttr = nil
  431. CombatObj.setValue(attacker, RoleDefine.ATK_COMBAT_NOW, nil)
  432. CombatObj.setValue(attacker, RoleDefine.RATE_COMBAT_NOW, nil)
  433. CombatObj.setValue(attacker, RoleDefine.HURT_COMBAT_NOW, nil)
  434. attacker.beskill40 = nil
  435. end
  436. function calcPhyHurt(attacker, index, targets, skillConfig)
  437. local hurt = 0
  438. local flag = 0
  439. -- 技能是否无视护甲
  440. local noHuJia = false
  441. if skillConfig.otherArgs and skillConfig.otherArgs.noHuJia == 1 then
  442. noHuJia = true
  443. end
  444. local targetCnt = 1
  445. if skillConfig.otherArgs and skillConfig.otherArgs.hurtFenTan and skillConfig.otherArgs.hurtFenTan[1] == 1 then
  446. targetCnt = #targets
  447. end
  448. local defender = targets[index]
  449. local outRate = getOutRate(attacker, defender, skillConfig, index, targets)
  450. outRate = outRate / 10000
  451. local beSkillHurtRate = getBeSkillOutRate(attacker, defender, skillConfig)
  452. local pojia = getPojia(attacker, defender, skillConfig)
  453. local outAtk = attacker.attr[RoleDefine.ATK_COMBAT_NOW] or getOutAtk(attacker, skillConfig)
  454. local def = noHuJia == true and 0 or getDef(defender, skillConfig)
  455. local jianshangRate = getJianshangRate(attacker, defender)
  456. local extraHurtRate = getExtraHurtRate(attacker, defender, skillConfig)
  457. local extraHurt = getExtraHurt(attacker, defender, skillConfig)
  458. local isBaoji, baojiHurtRate = getBaojiHurtRate(attacker, defender, skillConfig)
  459. defender.isBaoji = isBaoji
  460. attacker.isBaoji = attacker.isBaoji or isBaoji
  461. if isBaoji then
  462. flag = Util.setBit(flag, CombatDefine.FLAG_BAOJI)
  463. end
  464. local shanghaiRate = 1 + extraHurtRate - jianshangRate
  465. shanghaiRate = shanghaiRate < 0 and 0 or shanghaiRate
  466. local coefDef = def * (1 - pojia)
  467. coefDef = coefDef < 0 and 0 or coefDef
  468. local rateCombatNow = (1 - coefDef / (coefDef + 600) ) * shanghaiRate
  469. hurt = outAtk * outRate * rateCombatNow * baojiHurtRate * beSkillHurtRate / targetCnt
  470. hurt = hurt + extraHurt
  471. CombatObj.setValue(attacker, RoleDefine.ATK_COMBAT_NOW, outAtk)
  472. -- 当伤害超过百分比 的 伤害 加深或者减免
  473. local parcentRate = BeSkill.getHurtPercentRate(attacker, defender, hurt, skillConfig)
  474. hurt = hurt *(1 + parcentRate / 10000)
  475. -- 测试用
  476. if Gm.wudi and attacker.pos <= 10 then
  477. hurt = 1000000000
  478. end
  479. -- 连击模式
  480. if CombatImpl.comboType > 0 then
  481. hurt = hurt * CombatImpl.comboHurtRate / 10000
  482. end
  483. if defender.fentq then
  484. hurt = math.ceil(hurt / defender.fentq)
  485. else
  486. --修正
  487. if hurt <= 10000 then
  488. hurt = hurt * math.random(100,500)/10000 + hurt
  489. else
  490. hurt = hurt * math.random(100,300)/10000 + hurt
  491. end
  492. end
  493. hurt = math.ceil(hurt)
  494. if defender.attr[RoleDefine.HURT_RATE_MAX] > 0 then
  495. local hurtMax = CombatObj.getHpMax(defender) * defender.attr[RoleDefine.HURT_RATE_MAX] / 10000
  496. if hurt > hurtMax then
  497. hurt = hurtMax
  498. end
  499. end
  500. -- 剧情模式
  501. if CombatImpl.fightMode[1] == CombatDefine.FIGHT_MODE2 then
  502. local skillList = CombatImpl.fightMode[2]
  503. for k, v in pairs(skillList) do
  504. if skillConfig.id == v then
  505. hurt = defender.hp * 0.9
  506. break
  507. end
  508. end
  509. end
  510. --是否触发格挡
  511. if isGedang(defender) then
  512. hurt = hurt * 0.5
  513. end
  514. CombatObj.updateValue(attacker, RoleDefine.HURT_COMBAT_NOW, hurt)
  515. return hurt, flag
  516. end
  517. function calcMagicHurt(attacker, index, targets, skillConfig)
  518. local hurt = 0
  519. local flag = 0
  520. -- 技能是否无视护甲
  521. local noHuJia = false
  522. if skillConfig.otherArgs and skillConfig.otherArgs.noHuJia == 1 then
  523. noHuJia = true
  524. end
  525. local targetCnt = 1
  526. if skillConfig.otherArgs and skillConfig.otherArgs.hurtFenTan and skillConfig.otherArgs.hurtFenTan[1] == 1 then
  527. targetCnt = #targets
  528. end
  529. local defender = targets[index]
  530. local outRate = getOutRate(attacker, defender, skillConfig, index, targets)
  531. outRate = outRate / 10000
  532. local beSkillHurtRate = getBeSkillOutRate(attacker, defender, skillConfig)
  533. local pojia = getPojia(attacker, defender, skillConfig)
  534. local outAtk = attacker.attr[RoleDefine.ATK_COMBAT_NOW] or getOutAtk(attacker, skillConfig)
  535. local def = noHuJia == true and 0 or getDef(defender, skillConfig)
  536. local jianshangRate = getJianshangRate(attacker, defender)
  537. local extraHurtRate = getExtraHurtRate(attacker, defender, skillConfig)
  538. local extraHurt = getExtraHurt(attacker, defender, skillConfig)
  539. local isBaoji, baojiHurtRate = getBaojiHurtRate(attacker, defender, skillConfig)
  540. defender.isBaoji = isBaoji
  541. attacker.isBaoji = attacker.isBaoji or isBaoji
  542. if isBaoji then
  543. flag = Util.setBit(flag, CombatDefine.FLAG_BAOJI)
  544. end
  545. local shanghaiRate = 1 + extraHurtRate - jianshangRate
  546. shanghaiRate = shanghaiRate < 0 and 0 or shanghaiRate
  547. local coefDef = def * (1 - pojia)
  548. coefDef = coefDef < 0 and 0 or coefDef
  549. local rateCombatNow = (1 - coefDef / (coefDef + 600) ) * shanghaiRate
  550. hurt = outAtk * outRate * rateCombatNow * baojiHurtRate * beSkillHurtRate / targetCnt
  551. hurt = hurt + extraHurt
  552. CombatObj.setValue(attacker, RoleDefine.ATK_COMBAT_NOW, outAtk)
  553. -- 当伤害超过百分比 的 伤害 加深或者减免
  554. local parcentRate = BeSkill.getHurtPercentRate(attacker, defender, hurt, skillConfig)
  555. hurt = hurt *(1 + parcentRate / 10000)
  556. -- 测试用
  557. if Gm.wudi and attacker.pos <= 10 then
  558. hurt = 1000000000
  559. end
  560. -- 连击模式
  561. if CombatImpl.comboType > 0 then
  562. hurt = hurt * CombatImpl.comboHurtRate / 10000
  563. end
  564. if defender.fentq then
  565. hurt = math.ceil(hurt / defender.fentq)
  566. else
  567. --修正
  568. if hurt <= 10000 then
  569. hurt = hurt * math.random(100,500)/10000 + hurt
  570. else
  571. hurt = hurt * math.random(100,300)/10000 + hurt
  572. end
  573. end
  574. hurt = math.ceil(hurt)
  575. if defender.attr[RoleDefine.HURT_RATE_MAX] > 0 then
  576. local hurtMax = CombatObj.getHpMax(defender) * defender.attr[RoleDefine.HURT_RATE_MAX] / 10000
  577. if hurt > hurtMax then
  578. hurt = hurtMax
  579. end
  580. end
  581. -- 剧情模式
  582. if CombatImpl.fightMode[1] == CombatDefine.FIGHT_MODE2 then
  583. local skillList = CombatImpl.fightMode[2]
  584. for k, v in pairs(skillList) do
  585. if skillConfig.id == v then
  586. hurt = defender.hp * 0.9
  587. break
  588. end
  589. end
  590. end
  591. --是否触发格挡
  592. if isGedang(defender) then
  593. hurt = hurt * 0.5
  594. end
  595. hurt = hurt > 0 and hurt or 1
  596. CombatObj.updateValue(attacker, RoleDefine.HURT_COMBAT_NOW, hurt)
  597. return hurt, flag
  598. end
  599. --[[
  600. 防守方最终闪避 =防守方闪避 * (1 - 攻击方额外命中)
  601. ]]
  602. local function isShanbi(attacker, index, targets)
  603. local defender = targets[index]
  604. local jingzhun = CombatObj.getValue(attacker, RoleDefine.JINGZHUN) + CombatPosLogic.getRestrict(attacker,defender,RoleDefine.JINGZHUN)
  605. local shanbi = CombatObj.getValue(defender, RoleDefine.SHANBI)
  606. if jingzhun >= 10000 then
  607. local mingZhong = jingzhun - 10000
  608. mingZhong = mingZhong < 0 and 0 or mingZhong
  609. -- 强制设定额外命中不超过 99%
  610. if mingZhong >= 9900 then
  611. mingZhong = 9900
  612. end
  613. local shanbiRatio = 10000 - mingZhong
  614. shanbiRatio = shanbiRatio < 0 and 0 or shanbiRatio
  615. shanbi = math.floor(shanbi *(shanbiRatio / 10000))
  616. else
  617. shanbi = 10000 - jingzhun + shanbi
  618. end
  619. local r = math.random(1, 10000)
  620. if r < shanbi then
  621. return true
  622. end
  623. return false
  624. end
  625. function calcHurt(attacker, index, targets, skillConfig)
  626. -- 魔兽主动攻击伤害值为战前算出来的固定值
  627. if skillConfig.type == CombatDefine.SKILL_TYPE4 then
  628. return attacker.hurt or skillConfig.hurtRate[1], 0
  629. end
  630. if isShanbi(attacker, index, targets) then
  631. local flag = 0
  632. flag = Util.setBit(flag, CombatDefine.FLAG_SHANBI)
  633. return 0, flag
  634. end
  635. if attacker.hurtType == CombatDefine.MAGIC_HURT_TYPE then
  636. return calcMagicHurt(attacker, index, targets, skillConfig)
  637. elseif attacker.hurtType == CombatDefine.PHY_HURT_TYPE then
  638. return calcPhyHurt(attacker, index, targets, skillConfig)
  639. else
  640. return calcPhyHurt(attacker, index, targets, skillConfig)
  641. end
  642. end
  643. -- 额外作用,buff的伤害加成
  644. local function getCmdBuffHurtRate(attacker, defender)
  645. local extraHurtRate = 0
  646. if attacker and attacker.pos ~= defender.pos then
  647. extraHurtRate = extraHurtRate + CombatObj.getJobHurtRate(attacker, defender)
  648. -- 职业相关额外伤害加成
  649. extraHurtRate = extraHurtRate + CombatObj.getStatusHurtRate(attacker, defender)
  650. -- 状态相关额外伤害加成
  651. extraHurtRate = extraHurtRate + BeSkill.getExtraHurtRateEx(attacker, defender)
  652. --
  653. end
  654. return extraHurtRate / 10000
  655. end
  656. NO_EXCALC_LIST = {
  657. [7] = 1,
  658. [8] = 1,
  659. [11] = 1,
  660. [13] = 1,
  661. [14] = 1,
  662. [15] = 1,
  663. [16] = 1,
  664. [17] = 1,
  665. [18] = 1,
  666. [19] = 1,
  667. }
  668. function calcHp(attacker, defender, calcType, rate, isAddHp, flag)
  669. local hp
  670. -- 魔兽技能是 具体值 不需要 除以一万
  671. if calcType ~= 8 then
  672. rate = rate / 10000
  673. end
  674. local isCmdBuffHurtRate = nil
  675. local baoJi = 1
  676. if calcType == 1 then
  677. -- 攻击百分比(技能释放者)
  678. -- local atk = CombatObj.getValue(attacker,RoleDefine.ATK_COMBAT_NOW)
  679. -- hp = atk * rate
  680. local atk = CombatObj.getValue(attacker, RoleDefine.ATK)
  681. local atkRate = CombatObj.getValue(attacker, RoleDefine.ATK_RATE) / 10000
  682. local extraHurtRate = 0
  683. if not isAddHp then
  684. extraHurtRate = defender.attr[RoleDefine.XURUO] / 10000
  685. end
  686. print("[calcHp] 计算回血 atk = "..atk.." rate = "..rate.." extraHurtRate = "..extraHurtRate)
  687. hp = atk *(1 + extraHurtRate) * rate
  688. print("[calcHp] 计算回血 hp = "..hp)
  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. end
  825. if not NO_EXCALC_LIST[calcType] then
  826. if isAddHp then
  827. if defender.type == CombatDefine.COMBAT_OBJ_TYPE3 then
  828. hp = 0
  829. else
  830. local hpAddRate = CombatObj.getValue(defender, RoleDefine.HP_ADD_RATE) / 10000
  831. hp = hp *(1 + hpAddRate)
  832. hp = hp < 0 and 1 or hp
  833. end
  834. --[[
  835. else
  836. local defRate = getDef(defender)
  837. local jianshangRate = getJianshangRate(attacker, defender)
  838. local rateCombatNow =(1 -(defRate /(defRate + 600))) *(1 - jianshangRate)
  839. hp = hp * rateCombatNow * baoJi
  840. ]]--
  841. end
  842. end
  843. if not isAddHp and not isCmdBuffHurtRate then
  844. hp = hp * (1 + getCmdBuffHurtRate(attacker, defender))
  845. end
  846. if isAddHp and CombatImpl.comboType > 0 then
  847. hp = math.ceil(hp * 0.5)
  848. end
  849. hp = hp > 0 and hp or 0
  850. return hp
  851. end
  852. function calcBufferHp(attacker, defender, bufferID, isAddHp)
  853. --local conf = BufferExcel[bufferID]
  854. local conf = CombatBuff.GetBuffConfig(bufferID)
  855. local args
  856. if attacker.isPet then
  857. args = attacker.buffers[bufferID].args
  858. else
  859. args = conf.args
  860. end
  861. local hp = calcHp(attacker, defender, args[1], args[2], isAddHp)
  862. if args[5] then
  863. local limit = args[5] * CombatObj.getValue(attacker, RoleDefine.ATK_COMBAT_NOW) / 10000
  864. if hp > limit then
  865. hp = limit
  866. end
  867. end
  868. return hp
  869. end
  870. function calcValue(attacker, defender, calcType, rate)
  871. local value = 0
  872. rate = rate / 10000
  873. if calcType == 1 then
  874. -- 攻击百分比(技能防守)
  875. local atk = CombatObj.getValue(defender, RoleDefine.ATK)
  876. local atkValue = atk * rate
  877. if attacker.pos == defender.pos then
  878. value = value + atkValue
  879. else
  880. value = value - atkValue
  881. end
  882. end
  883. return value
  884. end