BattleUtil.lua 71 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840
  1. BattleUtil = {}
  2. -- local GameSetting = ConfigManager.GetConfig(ConfigName.GameSetting)
  3. --local BattleUtil = BattleUtil
  4. local floor = math.floor
  5. local max = math.max
  6. local min = math.min
  7. --local Random = Random
  8. --local RoleDataName = RoleDataName
  9. --local BattleEventName = BattleEventName
  10. BattleUtil.Passivity = require("Modules/Battle/Logic/Base/Passivity")
  11. local function clamp(v, minValue, maxValue)
  12. if v < minValue then
  13. return minValue
  14. end
  15. if v > maxValue then
  16. return maxValue
  17. end
  18. return v
  19. end
  20. function BattleUtil.ErrorCorrection(f) --进行精度处理,避免前后端计算不一致
  21. return floor(f * 100000 + 0.5) / 100000
  22. end
  23. function BattleUtil.FP_Mul(...)
  24. local f = 1
  25. for i, v in ipairs{...} do
  26. f = floor(f * v * 100000 + 0.5) / 100000
  27. end
  28. return f
  29. end
  30. -- 选择前排
  31. function BattleUtil.ChooseFRow(arr)
  32. local tempArr = {}
  33. for _, r in ipairs(arr) do
  34. if r.position <= 3 and not r:IsRealDead() then
  35. table.insert(tempArr, r)
  36. end
  37. end
  38. table.sort(tempArr, function(a, b)
  39. return a.position < b.position
  40. end)
  41. return tempArr
  42. end
  43. --> 选择中排
  44. function BattleUtil.ChooseMRow(arr)
  45. local tempArr = {}
  46. for _, r in ipairs(arr) do
  47. if r.position > 3 and r.position <= 6 and not r:IsRealDead() then
  48. table.insert(tempArr, r)
  49. end
  50. end
  51. table.sort(tempArr, function(a, b)
  52. return a.position < b.position
  53. end)
  54. return tempArr
  55. end
  56. -- 选择后排
  57. function BattleUtil.ChooseBRow(arr)
  58. local tempArr = {}
  59. for _, r in ipairs(arr) do
  60. if r.position > 6 and not r:IsRealDead() then
  61. table.insert(tempArr, r)
  62. end
  63. end
  64. table.sort(tempArr, function(a, b)
  65. return a.position < b.position
  66. end)
  67. return tempArr
  68. end
  69. --> 选择前两排
  70. function BattleUtil.ChooseF2Row(arr)
  71. local tempArr = {}
  72. for _, r in ipairs(arr) do
  73. if r.position <= 6 and not r:IsRealDead() then
  74. table.insert(tempArr, r)
  75. end
  76. end
  77. table.sort(tempArr, function(a, b)
  78. return a.position < b.position
  79. end)
  80. return tempArr
  81. end
  82. --> 选择后两排
  83. function BattleUtil.ChooseB2Row(arr)
  84. local tempArr = {}
  85. for _, r in ipairs(arr) do
  86. if r.position > 3 and not r:IsRealDead() then
  87. table.insert(tempArr, r)
  88. end
  89. end
  90. table.sort(tempArr, function(a, b)
  91. return a.position < b.position
  92. end)
  93. return tempArr
  94. end
  95. -- 选择一列(col == 0 表示第三列哦)
  96. function BattleUtil.ChooseCol(arr, col)
  97. local tempArr = {}
  98. for _, role in ipairs(arr) do
  99. if role.position % 3 == col then
  100. table.insert(tempArr, role)
  101. end
  102. end
  103. table.sort(tempArr, function(a, b)
  104. return a.position < b.position
  105. end)
  106. return tempArr
  107. end
  108. --> 数量最多列 0第三
  109. function BattleUtil.GetMaxCol(arr)
  110. local tempArr = {0, 0, 0}
  111. for _, role in ipairs(arr) do
  112. local idx = role.position % 3
  113. if idx == 0 then
  114. tempArr[3] = tempArr[3] + 1
  115. else
  116. tempArr[idx] = tempArr[idx] + 1
  117. end
  118. end
  119. local maxNum = -1
  120. local col = -1
  121. for i = 1, #tempArr do
  122. if tempArr[i] > maxNum then
  123. col = i
  124. maxNum = tempArr[i]
  125. if i == 3 then
  126. col = 0
  127. end
  128. end
  129. end
  130. return col
  131. end
  132. -- 根据属性排序
  133. function BattleUtil.SortByProp(arr, prop, sort)
  134. BattleUtil.Sort(arr, function(a, b)
  135. local r1 = a:GetRoleData(prop)
  136. local r2 = b:GetRoleData(prop)
  137. if sort == 1 then return r1 > r2 else return r1 < r2 end
  138. end)
  139. return arr
  140. end
  141. -- 按血量排序
  142. function BattleUtil.SortByHpFactor(arr, sort)
  143. BattleUtil.Sort(arr, function(a, b)
  144. local r1 = a:GetRoleData(RoleDataName.Hp) / a:GetRoleData(RoleDataName.MaxHp)
  145. local r2 = b:GetRoleData(RoleDataName.Hp) / b:GetRoleData(RoleDataName.MaxHp)
  146. if sort == 1 then return r1 > r2 else return r1 < r2 end
  147. end)
  148. return arr
  149. end
  150. --> 按职业排序
  151. function BattleUtil.SortByProfessionId(arr, sort, _professionId)
  152. -- 角色职业
  153. -- 1、防御
  154. -- 2、高爆
  155. -- 3、穿甲
  156. -- 4,辅助
  157. BattleUtil.Sort(arr, function(a, b)
  158. local aa = a.professionId == _professionId and 1 or 0
  159. local bb = b.professionId == _professionId and 1 or 0
  160. if sort == 1 then return aa > bb else return aa < bb end
  161. end)
  162. return arr
  163. end
  164. function BattleUtil.ShuffleDead(arr)
  165. local hpZero = {}
  166. for i = 1, #arr do
  167. if arr[i]:GetRoleData(RoleDataName.Hp) <= 0 then
  168. table.insert(hpZero, arr[i])
  169. end
  170. end
  171. Random.RandomList(hpZero)
  172. local idx = 0
  173. for i = 1, #arr do
  174. if arr[i]:GetRoleData(RoleDataName.Hp) <= 0 then
  175. idx = idx + 1
  176. arr[i] = hpZero[idx]
  177. end
  178. end
  179. return arr
  180. end
  181. -- 获取技能最大目标数
  182. function BattleUtil.GetMaxTargetNum(chooseId)
  183. local chooseType = floor(chooseId / 100000) % 10
  184. local chooseLimit = floor(chooseId / 10000) % 10
  185. local chooseWeight = floor(chooseId / 100) % 100
  186. local sort = floor(chooseId / 10) % 10
  187. local num = chooseId % 10
  188. --
  189. if chooseType == 3 or chooseType == 4 then
  190. return 1
  191. else
  192. if num == 0 then
  193. if chooseLimit == 0 then
  194. if chooseWeight == 7 then
  195. return 4
  196. elseif chooseLimit == 8 then
  197. return 1
  198. else
  199. return 6
  200. end
  201. elseif chooseLimit == 1 or chooseLimit == 2 then
  202. return 3
  203. elseif chooseLimit == 3 then
  204. return 2
  205. end
  206. else
  207. return num
  208. end
  209. end
  210. end
  211. function BattleUtil.excludeSelfList(arr,role)
  212. local tempArr = {}
  213. for _, r in ipairs(arr) do
  214. if not r:Equle(role) and not r:IsRealDead() then
  215. table.insert(tempArr, r)
  216. end
  217. end
  218. table.sort(tempArr, function(a, b)
  219. return a.position < b.position
  220. end)
  221. return tempArr
  222. end
  223. --
  224. function BattleUtil.ChooseTarget(role, chooseId)
  225. local chooseType = floor(chooseId / 100000) % 10
  226. local chooseLimit = floor(chooseId / 10000) % 10
  227. local chooseWeight = floor(chooseId / 100) % 100
  228. local sort = floor(chooseId / 10) % 10
  229. local num = chooseId % 10
  230. local arr
  231. if role.ctrl_chaos then --< 混乱自残
  232. return {role}
  233. end
  234. -- 选择类型
  235. if chooseType == 1 then
  236. arr = RoleManager.Query(function (r) return r.camp == role.camp end)
  237. elseif chooseType == 2 then
  238. if role.lockTarget and not role.lockTarget:IsRealDead() and num == 1 then --嘲讽时对单个敌军生效
  239. return {role.lockTarget}
  240. end
  241. arr = RoleManager.Query(function (r) return r.camp ~= role.camp end)
  242. elseif chooseType == 3 then
  243. if role.ctrl_blind then --致盲时自身变随机友军
  244. arr = RoleManager.Query(function (r) return r.camp == role.camp end)
  245. BattleUtil.RandomList(arr)
  246. return {arr[1]}
  247. end
  248. return {role}
  249. elseif chooseType == 4 then
  250. if role.lockTarget and not role.lockTarget:IsRealDead() then --嘲讽时对仇恨目标生效
  251. return {role.lockTarget}
  252. end
  253. if role.ctrl_blind then --致盲时仇恨目标变随机
  254. arr = RoleManager.Query(function (r) return r.camp ~= role.camp end)
  255. BattleUtil.RandomList(arr)
  256. return {arr[1]}
  257. end
  258. return {RoleManager.GetAggro(role)}
  259. elseif chooseType == 5 then --< 我方阵亡
  260. arr = RoleManager.QueryDead(function (r) return r.camp == role.camp end)
  261. elseif chooseType == 6 then --< 我方全体
  262. arr = RoleManager.Query(function (r) return r.camp == role.camp end, true)
  263. elseif chooseType == 7 then --< 我方阵亡可复活英雄
  264. local reliveFunc = function (ro)
  265. return (ro.IsDead or ro.isRealDead) and ro.reliveFilter
  266. end
  267. arr = RoleManager.Query(function (r) return r.camp == role.camp and reliveFunc(r) and r.isDead end,true)
  268. if arr==nil or #arr==0 then
  269. arr =RoleManager.Query(function (r) return r.camp == role.camp end, false)
  270. end
  271. else
  272. arr = RoleManager.Query()
  273. end
  274. --选择范围
  275. if chooseLimit == 0 then --选择全体不做任何操作
  276. elseif chooseLimit == 1 then-- 前排
  277. local tempArr = BattleUtil.ChooseFRow(arr)
  278. if #tempArr == 0 then
  279. tempArr = BattleUtil.ChooseMRow(arr)
  280. end
  281. if #tempArr == 0 then -- 没有选择后排
  282. tempArr = BattleUtil.ChooseBRow(arr)
  283. end
  284. arr = tempArr
  285. elseif chooseLimit == 2 then-- 后排
  286. local tempArr = BattleUtil.ChooseBRow(arr)
  287. if #tempArr == 0 then
  288. tempArr = BattleUtil.ChooseMRow(arr)
  289. end
  290. if #tempArr == 0 then -- 没有选择前排
  291. tempArr = BattleUtil.ChooseFRow(arr)
  292. end
  293. arr = tempArr
  294. elseif chooseLimit == 3 then-- 对列
  295. local myCol = role.position % 3
  296. local tempArr = BattleUtil.ChooseCol(arr, myCol)
  297. if #tempArr == 0 then -- 对列没有人,按顺序找到有人得列
  298. for i = 1, 3 do
  299. local col = i % 3 -- 0 表示第三列嗷
  300. tempArr = BattleUtil.ChooseCol(arr, col)
  301. if #tempArr ~= 0 then
  302. break
  303. end
  304. end
  305. end
  306. arr = tempArr
  307. elseif chooseLimit == 4 then --< 前二
  308. local tempArr = BattleUtil.ChooseF2Row(arr)
  309. if #tempArr == 0 then -- 没有选择最后一排
  310. tempArr = BattleUtil.ChooseBRow(arr)
  311. end
  312. arr = tempArr
  313. elseif chooseLimit == 5 then --< 后二
  314. local tempArr = BattleUtil.ChooseB2Row(arr)
  315. if #tempArr == 0 then -- 没有选择第一排
  316. tempArr = BattleUtil.ChooseFRow(arr)
  317. end
  318. arr = tempArr
  319. elseif chooseLimit == 6 then --< 全体,优先4职业
  320. elseif chooseLimit == 7 then --< 人数最多列
  321. local tempArr = BattleUtil.ChooseCol(arr, BattleUtil.GetMaxCol(arr))
  322. arr = tempArr
  323. elseif chooseLimit == 8 then --< 除自己外
  324. local tempArr = BattleUtil.excludeSelfList(arr,role)
  325. if #tempArr == 0 then
  326. tempArr = arr
  327. end
  328. -- LogError("#tempArr"..#tempArr)
  329. arr = tempArr
  330. elseif chooseLimit == 9 then --< 9全体,优先2职业
  331. arr = BattleUtil.SortByProfessionId(arr, sort, 2)
  332. end
  333. if chooseWeight == 9 then --< 随机某属性 定死或走表
  334. chooseWeight = Random.RangeInt(1, 6)
  335. end
  336. -- 选择条件
  337. if chooseWeight == 0 or role.ctrl_blind then --致盲时排序无效
  338. BattleUtil.RandomList(arr)
  339. elseif chooseWeight == 1 then -- 生命值
  340. BattleUtil.SortByProp(arr, RoleDataName.Hp, sort)
  341. if chooseType == 6 then
  342. BattleUtil.ShuffleDead(arr)
  343. end
  344. elseif chooseWeight == 2 then -- 血量百分比
  345. BattleUtil.SortByHpFactor(arr, sort)
  346. elseif chooseWeight == 3 then -- 攻击力
  347. arr = BattleUtil.SortByProp(arr, RoleDataName.Attack, sort)
  348. -- RoleManager.LogRoles("attack",arr)
  349. elseif chooseWeight == 4 then -- 防御
  350. BattleUtil.SortByProp(arr, RoleDataName.PhysicalDefence, sort)
  351. elseif chooseWeight == 5 then -- 护甲
  352. BattleUtil.SortByProp(arr, RoleDataName.PhysicalDefence, sort)
  353. elseif chooseWeight == 6 then -- 魔抗
  354. BattleUtil.SortByProp(arr, RoleDataName.MagicDefence, sort)
  355. elseif chooseWeight == 7 then -- 对位及其相邻目标
  356. arr = RoleManager.GetNeighbor(role, chooseType)
  357. elseif chooseWeight == 8 then -- 对位
  358. arr = RoleManager.GetArrAggroList(role, arr)
  359. elseif chooseWeight == 11 then --< 防御
  360. arr = BattleUtil.SortByProfessionId(arr, sort, 1)
  361. elseif chooseWeight == 12 then --< 高爆
  362. arr = BattleUtil.SortByProfessionId(arr, sort, 2)
  363. elseif chooseWeight == 13 then --< 穿甲
  364. arr = BattleUtil.SortByProfessionId(arr, sort, 3)
  365. elseif chooseWeight == 14 then --< 辅助
  366. arr = BattleUtil.SortByProfessionId(arr, sort, 4)
  367. elseif chooseWeight == 21 then --< 负面状态(控制状态、减益状态和持续伤害状态)
  368. local searchFunc = function(role)
  369. local list = BattleLogic.BuffMgr:GetBuff(role, function (buff)
  370. return buff.type == BuffName.Control or buff.isDeBuff or buff.type == BuffName.DOT
  371. end)
  372. return list and #list > 0
  373. end
  374. arr = RoleManager.Query(searchFunc, false)
  375. end
  376. if chooseLimit == 6 then --< 全体,优先4职业
  377. local tempArr = {}
  378. for i = 1, #arr do
  379. if arr[i].roleData.professionId == 4 then
  380. table.insert(tempArr, arr[i])
  381. end
  382. end
  383. for i = 1, #arr do
  384. if arr[i].roleData.professionId ~= 4 then
  385. table.insert(tempArr, arr[i])
  386. end
  387. end
  388. arr = tempArr
  389. -- elseif chooseLimit == 8 then --< 除自己
  390. -- local tempArr = {}
  391. -- for _, r in ipairs(arr) do
  392. -- if not (r == role) then
  393. -- table.insert(tempArr, r)
  394. -- end
  395. -- end
  396. -- table.sort(tempArr, function(a, b)
  397. -- return a.position < b.position
  398. -- end)
  399. -- arr = tempArr
  400. elseif chooseLimit == 9 then --< 全体,优先2职业
  401. local tempArr = {}
  402. for i = 1, #arr do
  403. if arr[i].roleData.professionId == 2 then
  404. table.insert(tempArr, arr[i])
  405. end
  406. end
  407. for i = 1, #arr do
  408. if arr[i].roleData.professionId ~= 2 then
  409. table.insert(tempArr, arr[i])
  410. end
  411. end
  412. arr = tempArr
  413. end
  414. local finalArr = {}
  415. if sort == 3 then --< 3随机(可重复,单体最多被选3次)
  416. local randArr = {}
  417. local randtimes = num == 0 and #arr or num
  418. local randTimesArr = {}
  419. for i = 1, #arr do
  420. table.insert(randTimesArr, 0)
  421. end
  422. local idx = 0
  423. while #randArr < randtimes
  424. do
  425. while true
  426. do
  427. local randIdx = Random.RangeInt(1, #arr)
  428. if randTimesArr[randIdx] >= 3 then
  429. break
  430. end
  431. randTimesArr[randIdx] = randTimesArr[randIdx] + 1
  432. table.insert(randArr, arr[randIdx])
  433. break
  434. end
  435. idx = idx + 1
  436. if idx > 5 then
  437. break
  438. end
  439. end
  440. finalArr = randArr
  441. else
  442. --> 不随机按顺序
  443. if num == 0 then
  444. finalArr = arr
  445. else
  446. for i = 1, num do
  447. if arr[i] then
  448. table.insert(finalArr, arr[i])
  449. end
  450. end
  451. end
  452. end
  453. --LogError(string.format("chooseid: %s chooseType:== %s chooseLimit:== %s chooseWeight:== %s sort:== %s num:== %s,"
  454. --,tostring(chooseId),tostring(chooseType),tostring(chooseLimit),tostring(chooseWeight),tostring(sort),tostring(num)))
  455. -- LogError("chooseType:"..chooseType)
  456. -- LogError("chooseLimit:"..chooseLimit)
  457. -- LogError("chooseWeight:"..chooseWeight)
  458. -- LogError("sort:"..sort)
  459. -- LogError("num:"..num)
  460. -- table.sort(finalArr, function(a, b)
  461. -- return a.position < b.position
  462. -- end)
  463. return finalArr
  464. end
  465. --> 打乱角色队列
  466. function BattleUtil.ShufferRoles(arr,singleTime)
  467. if not arr or #arr==0 then return nil end
  468. local num = Random.RangeInt(1,5) --> 打乱次数
  469. local randArr = {}
  470. local randtimes = num == 0 and #arr or num
  471. local randTimesArr = {}
  472. for i = 1, #arr do
  473. table.insert(randTimesArr, 0)
  474. end
  475. local idx = 0
  476. while #randArr < randtimes
  477. do
  478. while true
  479. do
  480. local randIdx = Random.RangeInt(1, #arr)
  481. if randTimesArr[randIdx] >= singleTime then
  482. break
  483. end
  484. randTimesArr[randIdx] = randTimesArr[randIdx] + 1
  485. table.insert(randArr, arr[randIdx])
  486. break
  487. end
  488. idx = idx + 1
  489. if idx > 5 then
  490. break
  491. end
  492. end
  493. return randArr
  494. end
  495. --> 选择单个对象
  496. function BattleUtil.ChooseOneTarget(role, chooseId, excludeAttackList)
  497. local chooseType = floor(chooseId / 100000) % 10
  498. local chooseLimit = floor(chooseId / 10000) % 10
  499. local chooseWeight = floor(chooseId / 100) % 100
  500. local sort = floor(chooseId / 10) % 10
  501. local num = chooseId % 10
  502. local arr
  503. if role.ctrl_chaos then --< 混乱自残
  504. return role
  505. end
  506. -- 选择类型
  507. if chooseType == 1 then
  508. arr = RoleManager.Query(function (r) return r.camp == role.camp end)
  509. elseif chooseType == 2 then
  510. if role.lockTarget and not role.lockTarget:IsRealDead() and num == 1 then --嘲讽时对单个敌军生效
  511. return role.lockTarget
  512. end
  513. arr = RoleManager.Query(function (r) return r.camp ~= role.camp end)
  514. elseif chooseType == 3 then
  515. if role.ctrl_blind then --致盲时自身变随机友军
  516. arr = RoleManager.Query(function (r) return r.camp == role.camp end)
  517. BattleUtil.RandomList(arr)
  518. return arr[1]
  519. end
  520. return role
  521. elseif chooseType == 4 then
  522. if role.lockTarget and not role.lockTarget:IsRealDead() then --嘲讽时对仇恨目标生效
  523. return role.lockTarget
  524. end
  525. if role.ctrl_blind then --致盲时仇恨目标变随机
  526. arr = RoleManager.Query(function (r) return r.camp ~= role.camp end)
  527. BattleUtil.RandomList(arr)
  528. return arr[1]
  529. end
  530. return RoleManager.GetAggro(role)
  531. elseif chooseType == 5 then --< 我方阵亡
  532. arr = RoleManager.QueryDead(function (r) return r.camp == role.camp end)
  533. elseif chooseType == 6 then --< 我方全体
  534. arr = RoleManager.Query(function (r) return r.camp == role.camp end, true)
  535. else
  536. arr = RoleManager.Query()
  537. end
  538. --选择范围
  539. if chooseLimit == 0 then --选择全体不做任何操作
  540. elseif chooseLimit == 1 then-- 前排
  541. local tempArr = BattleUtil.ChooseFRow(arr)
  542. if #tempArr == 0 then
  543. tempArr = BattleUtil.ChooseMRow(arr)
  544. end
  545. if #tempArr == 0 then -- 没有选择后排
  546. tempArr = BattleUtil.ChooseBRow(arr)
  547. end
  548. arr = tempArr
  549. elseif chooseLimit == 2 then-- 后排
  550. local tempArr = BattleUtil.ChooseBRow(arr)
  551. if #tempArr == 0 then
  552. tempArr = BattleUtil.ChooseMRow(arr)
  553. end
  554. if #tempArr == 0 then -- 没有选择前排
  555. tempArr = BattleUtil.ChooseFRow(arr)
  556. end
  557. arr = tempArr
  558. elseif chooseLimit == 3 then-- 对列
  559. local myCol = role.position % 3
  560. local tempArr = BattleUtil.ChooseCol(arr, myCol)
  561. if #tempArr == 0 then -- 对列没有人,按顺序找到有人得列
  562. for i = 1, 3 do
  563. local col = i % 3 -- 0 表示第三列嗷
  564. tempArr = BattleUtil.ChooseCol(arr, col)
  565. if #tempArr ~= 0 then
  566. break
  567. end
  568. end
  569. end
  570. arr = tempArr
  571. elseif chooseLimit == 4 then --< 前二
  572. local tempArr = BattleUtil.ChooseF2Row(arr)
  573. if #tempArr == 0 then -- 没有选择最后一排
  574. tempArr = BattleUtil.ChooseBRow(arr)
  575. end
  576. arr = tempArr
  577. elseif chooseLimit == 5 then --< 后二
  578. local tempArr = BattleUtil.ChooseB2Row(arr)
  579. if #tempArr == 0 then -- 没有选择第一排
  580. tempArr = BattleUtil.ChooseFRow(arr)
  581. end
  582. arr = tempArr
  583. elseif chooseLimit == 6 then --< 全体,优先4职业
  584. elseif chooseLimit == 7 then --< 人数最多列
  585. local tempArr = BattleUtil.ChooseCol(arr, BattleUtil.GetMaxCol(arr))
  586. arr = tempArr
  587. elseif chooseLimit == 8 then --< 除自己外
  588. elseif chooseLimit == 9 then --< 9全体,优先2职业
  589. end
  590. if chooseWeight == 9 then --< 随机某属性 定死或走表
  591. chooseWeight = Random.RangeInt(1, 6)
  592. end
  593. -- 选择条件
  594. if chooseWeight == 0 or role.ctrl_blind then --致盲时排序无效
  595. BattleUtil.RandomList(arr)
  596. elseif chooseWeight == 1 then -- 生命值
  597. BattleUtil.SortByProp(arr, RoleDataName.Hp, sort)
  598. if chooseType == 6 then
  599. BattleUtil.ShuffleDead(arr)
  600. end
  601. elseif chooseWeight == 2 then -- 血量百分比
  602. BattleUtil.SortByHpFactor(arr, sort)
  603. elseif chooseWeight == 3 then -- 攻击力
  604. BattleUtil.SortByProp(arr, RoleDataName.Attack, sort)
  605. elseif chooseWeight == 4 then -- 防御
  606. BattleUtil.SortByProp(arr, RoleDataName.PhysicalDefence, sort)
  607. elseif chooseWeight == 5 then -- 护甲
  608. BattleUtil.SortByProp(arr, RoleDataName.PhysicalDefence, sort)
  609. elseif chooseWeight == 6 then -- 魔抗
  610. BattleUtil.SortByProp(arr, RoleDataName.MagicDefence, sort)
  611. elseif chooseWeight == 7 then -- 对位及其相邻目标
  612. arr = RoleManager.GetNeighbor(role, chooseType)
  613. elseif chooseWeight == 8 then -- 对位
  614. arr = RoleManager.GetArrAggroList(role, arr)
  615. end
  616. if chooseLimit == 6 then --< 全体,优先4职业
  617. local tempArr = {}
  618. for i = 1, #arr do
  619. if arr[i].roleData.professionId == 4 then
  620. table.insert(tempArr, arr[i])
  621. end
  622. end
  623. for i = 1, #arr do
  624. if arr[i].roleData.professionId ~= 4 then
  625. table.insert(tempArr, arr[i])
  626. end
  627. end
  628. arr = tempArr
  629. elseif chooseLimit == 8 then --< 除自己
  630. local tempArr = {}
  631. for _, r in ipairs(arr) do
  632. if not (r == role) then
  633. table.insert(tempArr, r)
  634. end
  635. end
  636. table.sort(tempArr, function(a, b)
  637. return a.position < b.position
  638. end)
  639. arr = tempArr
  640. elseif chooseLimit == 9 then --< 全体,优先2职业
  641. local tempArr = {}
  642. for i = 1, #arr do
  643. if arr[i].roleData.professionId == 2 then
  644. table.insert(tempArr, arr[i])
  645. end
  646. end
  647. for i = 1, #arr do
  648. if arr[i].roleData.professionId ~= 2 then
  649. table.insert(tempArr, arr[i])
  650. end
  651. end
  652. arr = tempArr
  653. end
  654. local finalArr = {}
  655. --> 不随机按顺序
  656. if num == 0 then
  657. finalArr = arr
  658. else
  659. for i = 1, num do
  660. if arr[i] then
  661. table.insert(finalArr, arr[i])
  662. end
  663. end
  664. end
  665. --> 刨除
  666. for i = #finalArr, 1, -1 do
  667. for j = 1, #excludeAttackList do
  668. if excludeAttackList[j].uid == finalArr[i].uid then
  669. table.remove(finalArr, i)
  670. break
  671. end
  672. end
  673. end
  674. if #finalArr <= 0 then
  675. return nil
  676. end
  677. if sort == 3 then --< 随机类型
  678. local idx = Random.RangeInt(1, #finalArr)
  679. return finalArr[idx]
  680. else
  681. return finalArr[1]
  682. end
  683. end
  684. function BattleUtil.CreateBuffId(skill, index)
  685. local id = 0
  686. if skill.preAI then --主动技能生成buff
  687. id = skill.owner.uid * 10000 + index
  688. else --被动技能生成buff
  689. id = skill.owner.uid * 1000 + index
  690. end
  691. return id
  692. end
  693. -- 计算命中率
  694. function BattleUtil.CalHit(atkRole, defRole)
  695. --命中率 = clamp(自身命中率-敌方闪避率,0,1)
  696. local hit = atkRole:GetRoleData(RoleDataName.Hit)
  697. local dodge = defRole:GetRoleData(RoleDataName.Dodge)
  698. local bHit = Random.Range01() <= clamp(hit - dodge, 0, 1)
  699. if bHit then
  700. else
  701. atkRole.Event:DispatchEvent(BattleEventName.RoleDodge)
  702. defRole.Event:DispatchEvent(BattleEventName.RoleBeDodge)
  703. end
  704. return bHit
  705. end
  706. -- 计算护盾
  707. function BattleUtil.CalShield(atkRole, defRole, damage)
  708. for i=1, defRole.shield.size do
  709. local buff = defRole.shield.buffer[i]
  710. damage = buff:CountShield(damage, atkRole)
  711. end
  712. return damage
  713. end
  714. -- 提前计算护盾后伤害
  715. function BattleUtil.PreCountShield(defRole, damage)
  716. for i=1, defRole.shield.size do
  717. local buff = defRole.shield.buffer[i]
  718. damage = buff:PreCountShield(damage)
  719. end
  720. return damage
  721. end
  722. -- 秒杀
  723. function BattleUtil.Seckill(skill, atkRole, defRole)
  724. local damage = defRole:GetRoleData(RoleDataName.Hp)
  725. local finalDmg = defRole.data:SubValue(RoleDataName.Hp, damage)
  726. if finalDmg >= 0 then
  727. if defRole:GetRoleData(RoleDataName.Hp) <= 0 and not defRole:IsDead() then
  728. defRole:SetDead()
  729. defRole.Event:DispatchEvent(BattleEventName.RoleDead, atkRole)
  730. atkRole.Event:DispatchEvent(BattleEventName.RoleKill, defRole)
  731. BattleLogic.Event:DispatchEvent(BattleEventName.BattleRoleDead, defRole, atkRole)
  732. atkRole.Event:DispatchEvent(BattleEventName.Seckill, defRole)
  733. defRole.Event:DispatchEvent(BattleEventName.BeSeckill, atkRole)
  734. BattleLogic.Event:DispatchEvent(BattleEventName.Seckill, atkRole, defRole)
  735. end
  736. atkRole.Event:DispatchEvent(BattleEventName.RoleDamage, defRole, damage, false, finalDmg, 0, false, skill)
  737. defRole.Event:DispatchEvent(BattleEventName.RoleBeDamaged, atkRole, damage, false, finalDmg, 0, false, skill)
  738. BattleLogic.Event:DispatchEvent(BattleEventName.RoleDamage, atkRole, defRole, damage, false, finalDmg, 0, false, skill)
  739. BattleLogic.Event:DispatchEvent(BattleEventName.RoleBeDamaged, defRole, atkRole, damage, false, finalDmg, 0, false, skill)
  740. if skill then
  741. atkRole.Event:DispatchEvent(BattleEventName.RoleHit, defRole, damage, nil, finalDmg, nil, skill)
  742. defRole.Event:DispatchEvent(BattleEventName.RoleBeHit, atkRole, damage, nil, finalDmg, nil, skill)
  743. end
  744. end
  745. end
  746. -- 计算真实伤害
  747. function BattleUtil.ApplyDamage(skill, atkRole, defRole, damage, bCrit, damageType, dotType, changeIsForbear)
  748. if defRole.position == 99999 then
  749. return
  750. end
  751. bCrit = bCrit or false
  752. if atkRole.ctrl_seal then --封印 无法暴击
  753. bCrit = false
  754. end
  755. --加入被动效果
  756. local damagingFunc = function(dmgDeduction)
  757. damage = floor(damage - dmgDeduction)
  758. end
  759. SYSLog(string.format("ApplyDamage === damage: %s, damageType: %s,",tostring(damage),tostring(damageType)))
  760. atkRole.Event:DispatchEvent(BattleEventName.PassiveDamaging, damagingFunc, defRole, damage, skill, dotType, bCrit)
  761. defRole.Event:DispatchEvent(BattleEventName.PassiveBeDamaging, damagingFunc, atkRole, damage, skill, dotType, bCrit)
  762. BattleLogic.Event:DispatchEvent(BattleEventName.PassiveDamaging, damagingFunc, atkRole, defRole, damage, skill, dotType, bCrit)
  763. -- 计算护盾减伤
  764. damage = BattleUtil.CalShield(atkRole, defRole, damage)
  765. SYSLog(string.format("ApplyDamage CalShield === damage: %s, damageType: %s,",tostring(damage),tostring(damageType)))
  766. -- 造成的最终伤害
  767. local damagingFunc = function(dmgDeduction)
  768. damage = floor(damage - dmgDeduction)
  769. end
  770. --SYSLog(string.format("ApplyDamage CalShield final === damage: %s, damageType: %s,",tostring(damage),tostring(damageType)))
  771. atkRole.Event:DispatchEvent(BattleEventName.FinalDamage, damagingFunc, defRole, damage, skill, dotType, bCrit, damageType)
  772. defRole.Event:DispatchEvent(BattleEventName.FinalBeDamage, damagingFunc, atkRole, damage, skill, dotType, bCrit, damageType)
  773. BattleLogic.Event:DispatchEvent(BattleEventName.FinalDamage, damagingFunc, atkRole, defRole, damage, skill, dotType, bCrit, damageType)
  774. return BattleUtil.FinalDamage(skill, atkRole, defRole, damage, bCrit, damageType, dotType, changeIsForbear)
  775. end
  776. --检测是否有是金翅大鹏有不灭效果
  777. function BattleUtil.CheckIsNoDead(target)
  778. if target then
  779. return target:IsAssignHeroAndHeroStar(10086,10)==false and BattleLogic.BuffMgr:HasBuff(target,BuffName.NoDead)==false
  780. end
  781. return false
  782. end
  783. function BattleUtil.FinalDamage(skill, atkRole, defRole, damage, bCrit, damageType, dotType, changeIsForbear)
  784. if damage < 0 then damage = 0 end
  785. local finalDmg = defRole.data:SubValue(RoleDataName.Hp, damage)
  786. if atkRole.ctrl_seal then --封印 无法暴击
  787. bCrit = false
  788. atkRole.Event:DispatchEvent(BattleEventName.RoleBeSeal, defRole, damage, bCrit, finalDmg, damageType, skill)
  789. defRole.Event:DispatchEvent(BattleEventName.RoleSeal, atkRole, damage, bCrit, finalDmg, damageType, skill)
  790. end
  791. if finalDmg >= 0 then
  792. if defRole:GetRoleData(RoleDataName.Hp) <= 0 and not defRole:IsDead() then
  793. defRole:SetDead()
  794. defRole.Event:DispatchEvent(BattleEventName.RoleDead, atkRole)
  795. atkRole.Event:DispatchEvent(BattleEventName.RoleKill, defRole, damage, bCrit, damageType, dotType, skill)
  796. BattleLogic.Event:DispatchEvent(BattleEventName.BattleRoleDead, defRole, atkRole)
  797. end
  798. --被伤害是要知道是不是受克制
  799. local isForbear, damageAdd, hitAdd = BattleUtil.CheckForbear(atkRole, defRole)
  800. isForbear = changeIsForbear == nil and isForbear or changeIsForbear
  801. atkRole.Event:DispatchEvent(BattleEventName.RoleDamage, defRole, damage, bCrit, finalDmg, damageType, dotType, skill,atkRole)
  802. defRole.Event:DispatchEvent(BattleEventName.RoleBeDamaged, atkRole, damage, bCrit, finalDmg, damageType, dotType, skill, isForbear,defRole)
  803. BattleLogic.Event:DispatchEvent(BattleEventName.RoleDamage, atkRole, defRole, damage, bCrit, finalDmg, damageType, dotType, skill)
  804. BattleLogic.Event:DispatchEvent(BattleEventName.RoleBeDamaged, defRole, atkRole, damage, bCrit, finalDmg, damageType, dotType, skill)
  805. if bCrit then
  806. atkRole.Event:DispatchEvent(BattleEventName.RoleCrit, defRole, damage, bCrit, finalDmg, damageType, skill)
  807. defRole.Event:DispatchEvent(BattleEventName.RoleBeCrit, atkRole, damage, bCrit, finalDmg, damageType, skill)
  808. end
  809. if skill then
  810. atkRole.Event:DispatchEvent(BattleEventName.RoleHit, defRole, damage, bCrit, finalDmg, damageType, skill)
  811. defRole.Event:DispatchEvent(BattleEventName.RoleBeHit, atkRole, damage, bCrit, finalDmg, damageType, skill)
  812. end
  813. end
  814. --
  815. -- BattleLogManager.Log(
  816. -- "Final Damage",
  817. -- "acamp", atkRole.camp,
  818. -- "apos", atkRole.position,
  819. -- "tcamp", defRole.camp,
  820. -- "tpos", defRole.position,
  821. -- "damage", damage,
  822. -- "dotType", tostring(dotType)
  823. -- )
  824. return finalDmg, damage
  825. end
  826. --执行完整的命中,伤害,暴击计算,返回命中,暴击 simple不包含事件仅做计算用
  827. function BattleUtil.CalSimpleDamage(skill, atkRole, defRole, damageType, baseFactor, ignoreDef, dotType,SimpleCaculate)
  828. if defRole.position == 99999 then
  829. return
  830. end
  831. -- 判断是否命中
  832. if skill and not skill:CheckTargetIsHit(defRole) then
  833. BattleLogic.Event:DispatchEvent(BattleEventName.HitMiss, atkRole, defRole, skill)
  834. atkRole.Event:DispatchEvent(BattleEventName.HitMiss, defRole, skill)
  835. defRole.Event:DispatchEvent(BattleEventName.BeHitMiss, atkRole, skill)
  836. return 0
  837. end
  838. -- 如果是队伍技能,计算真实伤害,则damageType为伤害值
  839. -- if atkRole.isTeam and not defRole:IsDead() then
  840. -- return BattleUtil.ApplyDamage(skill, atkRole, defRole, damageType), false
  841. -- end
  842. -- 计算技能额外伤害系数加成
  843. SYSLog(string.format("baseFactor 1 === baseFactor: %s",baseFactor))
  844. baseFactor = baseFactor or 1
  845. baseFactor = BattleUtil.ErrorCorrection(baseFactor)
  846. SYSLog(string.format("baseFactor 2 === baseFactor: %s",baseFactor))
  847. local baseDamage
  848. -- 防御(据伤害类型决定)
  849. --> damageType depracated 只有物防
  850. local defence = defRole:GetRoleData(RoleDataName.PhysicalDefence)
  851. -- if damageType == 1 then --1 物理 2 魔法
  852. -- defence = defRole:GetRoleData(RoleDataName.PhysicalDefence)
  853. -- else
  854. -- defence = defRole:GetRoleData(RoleDataName.MagicDefence)
  855. -- end
  856. -- 攻击力
  857. local attack = atkRole:GetRoleData(RoleDataName.Attack)
  858. -- 无视防御系数
  859. ignoreDef = 1 - (ignoreDef or 0)
  860. local onIgnoreDefFactor = function(outIgnoreDef)
  861. ignoreDef = 1 - math.max(0, outIgnoreDef)
  862. end
  863. -- 基础伤害 = 攻击力 - 防御力
  864. -- baseDamage = max(attack - BattleUtil.FP_Mul(0.5, defence, ignoreDef), 0)
  865. -- baseDamage = max(attack - BattleUtil.FP_Mul(defence, ignoreDef), 0)
  866. baseDamage = attack * (1 - (BattleUtil.FP_Mul(defence, ignoreDef) / (defence + 598 + 2 * defRole:GetRoleData(RoleDataName.Level))))
  867. -- baseDamage = attack * (1 - (BattleUtil.FP_Mul(defence, ignoreDef) / (defence + GameSetting[1].DefenseLevvalue2 + GameSetting[1].DefenseLevvalue1 * defRole:GetRoleData(RoleDataName.Level))))
  868. -- 基础伤害增加系数 --< 伤害加成
  869. local addDamageFactor = atkRole:GetRoleData(RoleDataName.DamageBocusFactor) - defRole:GetRoleData(RoleDataName.DamageReduceFactor)
  870. -- 是否暴击: 暴击率 = 自身暴击率 - 对方抗暴率
  871. local bCrit = false
  872. local critRandom = Random.Range01()
  873. local critCondition = clamp(atkRole:GetRoleData(RoleDataName.Crit) - defRole:GetRoleData(RoleDataName.Tenacity), 0, 1)
  874. bCrit = critRandom <= critCondition
  875. bCrit = bCrit or defRole.isFlagCrit == true -- 必定暴击
  876. --< 封印状态大于必定暴击 锁死无法暴击
  877. if atkRole.ctrl_seal then bCrit=false end
  878. defRole.Event:DispatchEvent(BattleEventName.FlagCritReset)
  879. --> 暴击抵抗 miss次数
  880. local onCritMiss = function(newbCrit)
  881. bCrit = newbCrit
  882. end
  883. -- 计算暴伤害系数
  884. local critDamageFactor = 0
  885. local critDamageReduceFactor = 0 -- 暴击伤害减免
  886. --计算暴击
  887. if bCrit then
  888. --加入被动效果 触发暴击被动
  889. local cl = {}
  890. local onCritDamageReduceFactor = function(v, ct)
  891. if v then
  892. table.insert(cl, {v, ct})
  893. end
  894. end
  895. BattleLogic.Event:DispatchEvent(BattleEventName.CritDamageReduceFactor, onCritDamageReduceFactor, atkRole, defRole)
  896. critDamageReduceFactor = max(BattleUtil.CountChangeList(critDamageReduceFactor, cl), 0)
  897. -- 计算额外暴击伤害
  898. -- critDamageFactor = 1.3 + atkRole:GetRoleData(RoleDataName.CritDamageFactor) - critDamageReduceFactor
  899. critDamageFactor = max(atkRole:GetRoleData(RoleDataName.CritDamageFactor) - defRole:GetRoleData(RoleDataName.CriDamageReduceRate) - critDamageReduceFactor, 0)
  900. end
  901. local atkProFactor = 0
  902. local defProFactor = 0
  903. if defRole.professionId == 1 then --< 防御
  904. atkProFactor = atkRole:GetRoleData(RoleDataName.DamageToDefender)
  905. elseif defRole.professionId == 2 then --< 高爆
  906. atkProFactor = atkRole:GetRoleData(RoleDataName.DamageToMage)
  907. elseif defRole.professionId == 3 then --< 穿甲
  908. atkProFactor = atkRole:GetRoleData(RoleDataName.DamageToFighter)
  909. elseif defRole.professionId == 4 then --< 辅助
  910. atkProFactor = atkRole:GetRoleData(RoleDataName.DamageToHealer)
  911. end
  912. if atkRole.professionId == 1 then --< 防御
  913. defProFactor = defRole:GetRoleData(RoleDataName.DefenceFromDefender)
  914. elseif atkRole.professionId == 2 then --< 高爆
  915. defProFactor = defRole:GetRoleData(RoleDataName.DefenceFromMage)
  916. elseif atkRole.professionId == 3 then --< 穿甲
  917. defProFactor = defRole:GetRoleData(RoleDataName.DefenceFromFighter)
  918. elseif atkRole.professionId == 4 then --< 辅助
  919. defProFactor = defRole:GetRoleData(RoleDataName.DefenceFromHealer)
  920. end
  921. local professionFactor = atkProFactor - defProFactor
  922. --> 克制
  923. local isForbear, damageAdd, hitAdd = BattleUtil.CheckForbear(atkRole, defRole)
  924. local forbearFactor = 0
  925. if isForbear then
  926. forbearFactor = forbearFactor + damageAdd
  927. end
  928. -- 老公式
  929. --local fixDamage = floor(BattleUtil.FP_Mul(baseDamage, baseFactor, addDamageFactor, critDamageFactor))
  930. --> 修改公式
  931. --> 物
  932. -- (自己攻击 - 目标护甲)*(自己56暴击伤害 - 目标113暴击抵抗)*(自己114物伤加成/116法伤加成 - 目标115物伤减免/117法伤减免)
  933. -- *(1+ 自己职业伤害124\125\126\127 -目标职业减伤130\131\132\133)*(自己51伤害加成-目标52伤害减免)*(1+阵营克制系数)
  934. --> 法
  935. -- (自己攻击 - 目标护甲)*(自己56暴击伤害 - 目标113暴击抵抗)*(自己114物伤加成/116法伤加成 - 目标115物伤减免/117法伤减免)
  936. -- *(1+ 自己职业伤害124\125\126\127 -目标职业减伤130\131\132\133)*(1 + 自己123技能伤害)*(自己51伤害加成-目标52伤害减免)*(1+阵营克制系数)
  937. -- 老公式END
  938. local fixDamage = 0
  939. -- 公式伤害 = 基础伤害 * 基础伤害系数 * (1 + 增伤系数 + 爆伤系数 + 职业系数 + 物理损伤系数 + 克制系数)
  940. if damageType == 1 then
  941. local physicalDamageFactor = atkRole:GetRoleData(RoleDataName.PhysicalDamage) - defRole:GetRoleData(RoleDataName.PhysicalImmune)
  942. fixDamage = floor(BattleUtil.FP_Mul(baseDamage, baseFactor, (1 + addDamageFactor+critDamageFactor+professionFactor+physicalDamageFactor+forbearFactor)))
  943. SYSLog(string.format("damageType 1 === baseDamage: %s, baseFactor: %s, addDamageFactor: %s, critDamageFactor: %s, professionFactor: %s, physicalDamageFactor: %s, forbearFactor: %s",
  944. tostring(baseDamage), tostring(baseFactor), tostring(addDamageFactor), tostring(critDamageFactor), tostring(professionFactor), tostring(physicalDamageFactor), tostring(forbearFactor)))
  945. -- 公式伤害 = 基础伤害 * 基础伤害系数 * (1 +增伤系数 + 爆伤系数 + 职业系数 + 魔法损伤系数 + 技能 + 克制系数)
  946. elseif damageType == 2 then
  947. local magicDamageFactor = atkRole:GetRoleData(RoleDataName.MagicDamage) - defRole:GetRoleData(RoleDataName.MagicImmune)
  948. local skillFactor = atkRole:GetRoleData(RoleDataName.SkillDamage)
  949. fixDamage = floor(BattleUtil.FP_Mul(baseDamage, baseFactor, (1 + addDamageFactor+critDamageFactor+professionFactor+magicDamageFactor+skillFactor+forbearFactor)))
  950. SYSLog(string.format("damageType 2 === baseDamage: %s, baseFactor: %s, addDamageFactor: %s, critDamageFactor: %s, professionFactor: %s, magicDamageFactor: %s, skillFactor: %s, forbearFactor: %s",
  951. tostring(baseDamage), tostring(baseFactor), tostring(addDamageFactor), tostring(critDamageFactor), tostring(professionFactor), tostring(magicDamageFactor), tostring(skillFactor), tostring(forbearFactor)))
  952. end
  953. fixDamage = max(floor(attack * 0.1), fixDamage)
  954. if SimpleCaculate then --未计算护盾等返回的伤害指数 不触发伤害
  955. return fixDamage, bCrit
  956. end
  957. local finalDmg = 0 --计算实际造成的扣血
  958. local dmg = 0 --< 造成伤害值
  959. if not defRole:IsRealDead() then
  960. --finalDmg = BattleUtil.ApplyDamage(skill, atkRole, defRole, fixDamage, bCrit, damageType, dotType)
  961. finalDmg, dmg = BattleUtil.TriggerDamage(skill, atkRole, defRole, fixDamage, bCrit, damageType, dotType)
  962. end
  963. -- RoleManager.LogCa(
  964. -- "frame:"..BattleLogic.CurFrame(),
  965. -- "finalDmg:"..finalDmg,
  966. -- "bCrit:",bCrit,
  967. -- "dmg:",dmg
  968. -- )
  969. return finalDmg, bCrit, dmg
  970. end
  971. --执行完整的命中,伤害,暴击计算,返回命中,暴击
  972. --skill造成伤害的技能 atkRole攻击者 defRole受击者 damageType伤害类型 baseFactor伤害系数 ignoreDef无视防御参数 dotType是持续伤害类型
  973. function BattleUtil.CalDamage(skill, atkRole, defRole, damageType, baseFactor, ignoreDef, dotType)
  974. if defRole.position == 99999 then
  975. return
  976. end
  977. -- 判断是否命中
  978. if skill and not skill:CheckTargetIsHit(defRole) then
  979. BattleLogic.Event:DispatchEvent(BattleEventName.HitMiss, atkRole, defRole, skill)
  980. atkRole.Event:DispatchEvent(BattleEventName.HitMiss, defRole, skill)
  981. defRole.Event:DispatchEvent(BattleEventName.BeHitMiss, atkRole, skill)
  982. return 0
  983. end
  984. -- 如果是队伍技能,计算真实伤害,则damageType为伤害值
  985. -- if atkRole.isTeam and not defRole:IsDead() then
  986. -- return BattleUtil.ApplyDamage(skill, atkRole, defRole, damageType), false
  987. -- end
  988. -- 计算技能额外伤害系数加成
  989. SYSLog(string.format("baseFactor 1 === baseFactor: %s === attackrole: %s ",baseFactor,atkRole.roleId))
  990. baseFactor = baseFactor or 1
  991. -- 计算技能额外伤害系数加成
  992. SYSLog(string.format("baseFactor 2 === baseFactor: %s",baseFactor))
  993. local factorFunc = function(exFactor) baseFactor = baseFactor + exFactor end
  994. atkRole.Event:DispatchEvent(BattleEventName.RoleDamageBefore, defRole, factorFunc, damageType, skill,baseFactor,atkRole)
  995. defRole.Event:DispatchEvent(BattleEventName.RoleBeDamagedBefore, atkRole, factorFunc, damageType, skill,baseFactor,defRole)
  996. baseFactor = BattleUtil.ErrorCorrection(baseFactor)
  997. SYSLog(string.format("baseFactor 3 === baseFactor: %s",baseFactor))
  998. local baseDamage
  999. -- 防御(据伤害类型决定)
  1000. --> damageType depracated 只有物防
  1001. local defence = defRole:GetRoleData(RoleDataName.PhysicalDefence)
  1002. -- if damageType == 1 then --1 物理 2 魔法
  1003. -- defence = defRole:GetRoleData(RoleDataName.PhysicalDefence)
  1004. -- else
  1005. -- defence = defRole:GetRoleData(RoleDataName.MagicDefence)
  1006. -- end
  1007. -- 攻击力
  1008. local attack = atkRole:GetRoleData(RoleDataName.Attack)
  1009. -- 无视防御系数
  1010. ignoreDef = 1 - (ignoreDef or 0)
  1011. local onIgnoreDefFactor = function(outIgnoreDef)
  1012. ignoreDef = 1 - math.max(0, outIgnoreDef)
  1013. end
  1014. atkRole.Event:DispatchEvent(BattleEventName.IgnoreDefFactor, onIgnoreDefFactor, atkRole, defRole)
  1015. defRole.Event:DispatchEvent(BattleEventName.BeIgnoreDefFactor, onIgnoreDefFactor, atkRole, defRole)
  1016. -- 基础伤害 = 攻击力 - 防御力
  1017. -- baseDamage = max(attack - BattleUtil.FP_Mul(0.5, defence, ignoreDef), 0)
  1018. -- baseDamage = max(attack - BattleUtil.FP_Mul(defence, ignoreDef), 0)
  1019. -- LogError(" defence:"..defence)
  1020. baseDamage = attack * (1 - (BattleUtil.FP_Mul(defence, ignoreDef) / (defence + 598 + 2 * defRole:GetRoleData(RoleDataName.Level))))
  1021. -- baseDamage = attack * (1 - (BattleUtil.FP_Mul(defence, ignoreDef) / (defence + GameSetting[1].DefenseLevvalue2 + GameSetting[1].DefenseLevvalue1 * defRole:GetRoleData(RoleDataName.Level))))
  1022. -- LogError(" baseDamage:"..baseDamage)
  1023. -- 基础伤害增加系数 --< 伤害加成
  1024. local addDamageFactor = atkRole:GetRoleData(RoleDataName.DamageBocusFactor) - defRole:GetRoleData(RoleDataName.DamageReduceFactor)
  1025. -- 是否暴击: 暴击率 = 自身暴击率 - 对方抗暴率
  1026. local bCrit = false
  1027. local critRandom = Random.Range01()
  1028. local critCondition = clamp(atkRole:GetRoleData(RoleDataName.Crit) - defRole:GetRoleData(RoleDataName.Tenacity), 0, 1)
  1029. bCrit = critRandom <= critCondition
  1030. bCrit = bCrit or defRole.isFlagCrit == true -- 必定暴击
  1031. if atkRole.ctrl_seal then --封印 无法暴击
  1032. bCrit = false
  1033. atkRole.Event:DispatchEvent(BattleEventName.RoleBeSeal)
  1034. end
  1035. defRole.Event:DispatchEvent(BattleEventName.FlagCritReset)
  1036. --> 暴击抵抗 miss次数
  1037. local onCritMiss = function(newbCrit)
  1038. bCrit = newbCrit
  1039. end
  1040. atkRole.Event:DispatchEvent(BattleEventName.CritMiss, onCritMiss, atkRole, defRole, bCrit)
  1041. defRole.Event:DispatchEvent(BattleEventName.BeCritMiss, onCritMiss, atkRole, defRole, bCrit)
  1042. -- 计算暴伤害系数
  1043. local critDamageFactor = 0
  1044. local critDamageReduceFactor = 0 -- 暴击伤害减免
  1045. --计算暴击
  1046. if bCrit then
  1047. --加入被动效果 触发暴击被动
  1048. local cl = {}
  1049. local onCritDamageReduceFactor = function(v, ct)
  1050. if v then
  1051. table.insert(cl, {v, ct})
  1052. end
  1053. end
  1054. atkRole.Event:DispatchEvent(BattleEventName.CritDamageReduceFactor, onCritDamageReduceFactor, atkRole, defRole)
  1055. defRole.Event:DispatchEvent(BattleEventName.CritDamageReduceFactor, onCritDamageReduceFactor, atkRole, defRole)
  1056. BattleLogic.Event:DispatchEvent(BattleEventName.CritDamageReduceFactor, onCritDamageReduceFactor, atkRole, defRole)
  1057. critDamageReduceFactor = max(BattleUtil.CountChangeList(critDamageReduceFactor, cl), 0)
  1058. -- 计算额外暴击伤害
  1059. -- critDamageFactor = 1.3 + atkRole:GetRoleData(RoleDataName.CritDamageFactor) - critDamageReduceFactor
  1060. critDamageFactor = max(atkRole:GetRoleData(RoleDataName.CritDamageFactor) - defRole:GetRoleData(RoleDataName.CriDamageReduceRate) - critDamageReduceFactor, 0)
  1061. --加入被动效果 触发暴击被动
  1062. local critFunc = function(critEx) critDamageFactor = critEx end
  1063. atkRole.Event:DispatchEvent(BattleEventName.PassiveCriting, critFunc)
  1064. end
  1065. local atkProFactor = 0
  1066. local defProFactor = 0
  1067. if defRole.professionId == 1 then --< 防御
  1068. atkProFactor = atkRole:GetRoleData(RoleDataName.DamageToDefender)
  1069. elseif defRole.professionId == 2 then --< 高爆
  1070. atkProFactor = atkRole:GetRoleData(RoleDataName.DamageToMage)
  1071. elseif defRole.professionId == 3 then --< 穿甲
  1072. atkProFactor = atkRole:GetRoleData(RoleDataName.DamageToFighter)
  1073. elseif defRole.professionId == 4 then --< 辅助
  1074. atkProFactor = atkRole:GetRoleData(RoleDataName.DamageToHealer)
  1075. end
  1076. if atkRole.professionId == 1 then --< 防御
  1077. defProFactor = defRole:GetRoleData(RoleDataName.DefenceFromDefender)
  1078. elseif atkRole.professionId == 2 then --< 高爆
  1079. defProFactor = defRole:GetRoleData(RoleDataName.DefenceFromMage)
  1080. elseif atkRole.professionId == 3 then --< 穿甲
  1081. defProFactor = defRole:GetRoleData(RoleDataName.DefenceFromFighter)
  1082. elseif atkRole.professionId == 4 then --< 辅助
  1083. defProFactor = defRole:GetRoleData(RoleDataName.DefenceFromHealer)
  1084. end
  1085. local professionFactor = atkProFactor - defProFactor
  1086. --> 克制
  1087. local isForbear, damageAdd, hitAdd = BattleUtil.CheckForbear(atkRole, defRole)
  1088. local forbearFactor = 0
  1089. if isForbear then
  1090. forbearFactor = forbearFactor + damageAdd
  1091. end
  1092. -- 老公式
  1093. --local fixDamage = floor(BattleUtil.FP_Mul(baseDamage, baseFactor, addDamageFactor, critDamageFactor))
  1094. --> 修改公式
  1095. --> 物
  1096. -- (自己攻击 - 目标护甲)*(自己56暴击伤害 - 目标113暴击抵抗)*(自己114物伤加成/116法伤加成 - 目标115物伤减免/117法伤减免)
  1097. -- *(1+ 自己职业伤害124\125\126\127 -目标职业减伤130\131\132\133)*(自己51伤害加成-目标52伤害减免)*(1+阵营克制系数)
  1098. --> 法
  1099. -- (自己攻击 - 目标护甲)*(自己56暴击伤害 - 目标113暴击抵抗)*(自己114物伤加成/116法伤加成 - 目标115物伤减免/117法伤减免)
  1100. -- *(1+ 自己职业伤害124\125\126\127 -目标职业减伤130\131\132\133)*(1 + 自己123技能伤害)*(自己51伤害加成-目标52伤害减免)*(1+阵营克制系数)
  1101. -- 老公式END
  1102. local fixDamage = 0
  1103. -- 公式伤害 = 基础伤害 * 基础伤害系数 * (1 + 增伤系数 + 爆伤系数 + 职业系数 + 物理损伤系数 + 克制系数)
  1104. if damageType == 1 then
  1105. local physicalDamageFactor = atkRole:GetRoleData(RoleDataName.PhysicalDamage) - defRole:GetRoleData(RoleDataName.PhysicalImmune)
  1106. fixDamage = floor(BattleUtil.FP_Mul(baseDamage, baseFactor, (1 + addDamageFactor+critDamageFactor+professionFactor+physicalDamageFactor+forbearFactor)))
  1107. SYSLog(string.format("damageType 1 === baseDamage: %s, baseFactor: %s, addDamageFactor: %s, critDamageFactor: %s, professionFactor: %s, physicalDamageFactor: %s, forbearFactor: %s",
  1108. tostring(baseDamage), tostring(baseFactor), tostring(addDamageFactor), tostring(critDamageFactor), tostring(professionFactor), tostring(physicalDamageFactor), tostring(forbearFactor)))
  1109. -- 公式伤害 = 基础伤害 * 基础伤害系数 * (1 +增伤系数 + 爆伤系数 + 职业系数 + 魔法损伤系数 + 技能 + 克制系数)
  1110. elseif damageType == 2 then
  1111. local magicDamageFactor = atkRole:GetRoleData(RoleDataName.MagicDamage) - defRole:GetRoleData(RoleDataName.MagicImmune)
  1112. local skillFactor = atkRole:GetRoleData(RoleDataName.SkillDamage)
  1113. fixDamage = floor(BattleUtil.FP_Mul(baseDamage, baseFactor, (1 + addDamageFactor+critDamageFactor+professionFactor+magicDamageFactor+skillFactor+forbearFactor)))
  1114. SYSLog(string.format("damageType 2 === baseDamage: %s, baseFactor: %s, addDamageFactor: %s, critDamageFactor: %s, professionFactor: %s, magicDamageFactor: %s, skillFactor: %s, forbearFactor: %s",
  1115. tostring(baseDamage), tostring(baseFactor), tostring(addDamageFactor), tostring(critDamageFactor), tostring(professionFactor), tostring(magicDamageFactor), tostring(skillFactor), tostring(forbearFactor)))
  1116. end
  1117. -- 公式计算完成
  1118. local damageFunc = function(damage) fixDamage = damage end
  1119. atkRole.Event:DispatchEvent(BattleEventName.RoleDamageAfter, defRole, damageFunc, fixDamage)
  1120. defRole.Event:DispatchEvent(BattleEventName.RoleBeDamagedAfter, atkRole, damageFunc, fixDamage)
  1121. fixDamage = max(floor(attack * 0.1), fixDamage)
  1122. local finalDmg = 0 --计算实际造成的扣血
  1123. local dmg = 0 --< 造成伤害值
  1124. if not defRole:IsRealDead() then
  1125. --finalDmg = BattleUtil.ApplyDamage(skill, atkRole, defRole, fixDamage, bCrit, damageType, dotType)
  1126. finalDmg, dmg = BattleUtil.TriggerDamage(skill, atkRole, defRole, fixDamage, bCrit, damageType, dotType)
  1127. end
  1128. return finalDmg, bCrit, dmg
  1129. end
  1130. function BattleUtil.TriggerDamage(skill, atkRole, defRole, damage, bCrit, damageType, dotType)
  1131. if atkRole.ctrl_seal then --封印 无法暴击
  1132. bCrit = false
  1133. end
  1134. --> 应对触发伤害 效果 被动
  1135. local damagingFunc = function(dmgDeduction)
  1136. damage = damage - dmgDeduction
  1137. end
  1138. SYSLog(string.format("TriggerDamage === damage: %s, dmgDeduction: %s,",tostring(damage),tostring(damageType)))
  1139. atkRole.Event:DispatchEvent(BattleEventName.TriggerDamaging, damagingFunc, defRole, damage, skill, dotType, bCrit)
  1140. defRole.Event:DispatchEvent(BattleEventName.TriggerBeDamaging, damagingFunc, atkRole, damage, skill, dotType, bCrit)
  1141. BattleLogic.Event:DispatchEvent(BattleEventName.TriggerDamaging, damagingFunc, atkRole, defRole, damage, skill, dotType, bCrit)
  1142. return BattleUtil.ApplyDamage(skill, atkRole, defRole, damage, bCrit, damageType, dotType)
  1143. end
  1144. function BattleUtil.CalTreat(castRole, targetRole, value, baseFactor)
  1145. if targetRole.ctrl_noheal or targetRole:IsDead() then --禁疗和死亡无法加血
  1146. return
  1147. end
  1148. targetRole.Event:DispatchEvent(BattleEventName.RoleBeHealed, castRole)
  1149. BattleUtil.ApplyTreat(castRole, targetRole, value, baseFactor)
  1150. end
  1151. function BattleUtil.ApplyTreat(castRole, targetRole, value, baseFactor)
  1152. if targetRole.ctrl_noheal or targetRole:IsDead() then --禁疗和死亡无法加血
  1153. return
  1154. end
  1155. baseFactor = baseFactor or 1
  1156. local maxHp = targetRole:GetRoleData(RoleDataName.MaxHp)
  1157. local hp = targetRole:GetRoleData(RoleDataName.Hp)
  1158. -- 计算被动对治疗系数的影响
  1159. local treatFactorFunc = function(df, dt)
  1160. baseFactor = BattleUtil.CountValue(baseFactor, df, dt)
  1161. end
  1162. castRole.Event:DispatchEvent(BattleEventName.PassiveTreatingFactor, treatFactorFunc, targetRole)
  1163. targetRole.Event:DispatchEvent(BattleEventName.PassiveBeTreatedFactor, treatFactorFunc, castRole)
  1164. local factor = castRole:GetRoleData(RoleDataName.TreatFacter)
  1165. local factor2 = targetRole:GetRoleData(RoleDataName.CureFacter)
  1166. -- 是否修理暴击
  1167. local bTreatCrit = false
  1168. local critRandom = Random.Range01()
  1169. local critCondition = clamp(castRole:GetRoleData(RoleDataName.HealCritical), 0, 1)
  1170. bTreatCrit = critRandom <= critCondition
  1171. local treatCritFactor = 1
  1172. if bTreatCrit then
  1173. treatCritFactor = 1 + castRole:GetRoleData(RoleDataName.HealCriEffect)
  1174. end
  1175. -- local baseTreat = BattleUtil.FP_Mul(value, baseFactor, factor, factor2)
  1176. --> 改
  1177. --> 自己攻击(即治疗value) * (1+自己58治疗加成 + 目标57受疗加成)*自己129治疗暴击效果
  1178. local baseTreat = BattleUtil.FP_Mul(value, baseFactor, (1 + factor + factor2), treatCritFactor)
  1179. --加入被动效果
  1180. local cl = {}
  1181. local function treatingFunc(v, ct)
  1182. if v then
  1183. table.insert(cl, {v, ct})
  1184. end
  1185. end
  1186. -- local treatingFunc = function(exFactor) baseTreat = floor(baseTreat * (exFactor + 1) + 0.5) end
  1187. castRole.Event:DispatchEvent(BattleEventName.PassiveTreating, treatingFunc, targetRole)
  1188. targetRole.Event:DispatchEvent(BattleEventName.PassiveBeTreated, treatingFunc, castRole)
  1189. baseTreat = BattleUtil.CountChangeList(baseTreat, cl)
  1190. -- 取整
  1191. local baseTreat = floor(baseTreat + 0.5)
  1192. -- LogError("baseTreat:"..baseTreat)
  1193. local treat = min(baseTreat, maxHp - hp)
  1194. if treat > 0 then
  1195. targetRole.data:AddValue(RoleDataName.Hp, treat)
  1196. end
  1197. castRole.Event:DispatchEvent(BattleEventName.RoleTreat, targetRole, treat, baseTreat)
  1198. targetRole.Event:DispatchEvent(BattleEventName.RoleBeTreated, castRole, treat, baseTreat)
  1199. -- else
  1200. -- targetRole.data:AddValue(RoleDataName.Hp, 0)
  1201. -- castRole.Event:DispatchEvent(BattleEventName.RoleTreat, targetRole, 0, 0)
  1202. -- targetRole.Event:DispatchEvent(BattleEventName.RoleBeTreated, castRole, 0, 0)
  1203. --
  1204. -- BattleLogManager.Log(
  1205. -- "Final Damage",
  1206. -- "acamp", castRole.camp,
  1207. -- "apos", castRole.position,
  1208. -- "tcamp", targetRole.camp,
  1209. -- "tpos", targetRole.position,
  1210. -- "value", value
  1211. -- )
  1212. end
  1213. -- 检测命中
  1214. function BattleUtil.CheckIsHit(atkRole, defRole)
  1215. -- 是否命中: 命中 = 自身命中率 - 对方闪避率
  1216. local isHit = false
  1217. local hitRandom = Random.Range01()
  1218. --> 克制
  1219. local isForbear, damageAdd, hitAdd = BattleUtil.CheckForbear(atkRole, defRole)
  1220. local addHit = 0
  1221. if isForbear then
  1222. addHit = addHit + hitAdd
  1223. end
  1224. local hitCondition = clamp(atkRole:GetRoleData(RoleDataName.Hit) + addHit - defRole:GetRoleData(RoleDataName.Dodge), 0, 1)
  1225. isHit = hitRandom <= hitCondition
  1226. --如果攻击方和防守方是同一阵营 直接命中
  1227. isHit = atkRole.camp == defRole.camp and true or isHit
  1228. return isHit
  1229. end
  1230. --> 克制
  1231. function BattleUtil.CheckForbear(atkRole, defRole)
  1232. local damageAdd = 0.25
  1233. local hitAdd = 0.2
  1234. -- 1 Y系
  1235. -- 2 S系
  1236. -- 3 F系
  1237. -- 4 M系
  1238. -- 5 D系
  1239. local arrForbear = {[1] = 3, [2] = 1, [3] = 2, [4] = 5, [5] = 4}
  1240. local tempChecker = nil
  1241. local ChangeForbear=function(forceBear)
  1242. tempChecker = forceBear
  1243. end
  1244. atkRole.Event:DispatchEvent(BattleEventName.RoleCheckForbear, atkRole,defRole,ChangeForbear)
  1245. defRole.Event:DispatchEvent(BattleEventName.RoleBeCheckForbear, atkRole,defRole,ChangeForbear)
  1246. if tempChecker ~= nil then
  1247. return tempChecker,damageAdd, hitAdd
  1248. end
  1249. if atkRole and defRole then
  1250. return arrForbear[atkRole.element] == defRole.element, damageAdd, hitAdd
  1251. else
  1252. return false, damageAdd, hitAdd
  1253. end
  1254. end
  1255. function BattleUtil.RandomAction(rand, action)
  1256. if Random.Range01() <= rand and action then
  1257. action()
  1258. return true
  1259. end
  1260. return false
  1261. end
  1262. function BattleUtil.RandomAction2(rand, action)
  1263. if BattleLogic.RoundRandom <= rand and action then
  1264. action()
  1265. return true
  1266. end
  1267. return false
  1268. end
  1269. --
  1270. function BattleUtil.RandomControl(rand, ctrl, caster, target, round)
  1271. local cl = {}
  1272. local function _CallBack(v, ct)
  1273. if v then
  1274. table.insert(cl, {v, ct})
  1275. end
  1276. end
  1277. caster.Event:DispatchEvent(BattleEventName.PassiveRandomControl, _CallBack, ctrl, target)
  1278. target.Event:DispatchEvent(BattleEventName.PassiveBeRandomControl, _CallBack, ctrl, target)
  1279. --> 技能控制几率 + 自己118控制几率 - 目标119控制抵抗
  1280. rand = BattleUtil.CountChangeList(rand, cl) + caster:GetRoleData(RoleDataName.ControlProbability) - target:GetRoleData(RoleDataName.ControlResist)
  1281. --修改最终控制几率
  1282. local function fixControl(deRand)
  1283. rand = deRand
  1284. end
  1285. caster.Event:DispatchEvent(BattleEventName.PassiveRandomFinalControl, fixControl, rand, ctrl, target)
  1286. target.Event:DispatchEvent(BattleEventName.PassiveBeRandomFinalControl, fixControl,rand, ctrl, target)
  1287. return BattleUtil.RandomAction(rand, function()
  1288. local buff = Buff.Create(caster, BuffName.Control, round, ctrl)
  1289. target:AddBuff(buff)
  1290. end)
  1291. end
  1292. --
  1293. function BattleUtil.RandomDot(rand, dot, caster, target, round, interval, damage, func)
  1294. local cl = {}
  1295. local dcl = {}
  1296. local function _CallBack(v, ct, dv, dct)
  1297. if v then
  1298. table.insert(cl, {v, ct})
  1299. end
  1300. if dv then
  1301. table.insert(dcl, {dv, dct})
  1302. end
  1303. end
  1304. caster.Event:DispatchEvent(BattleEventName.PassiveRandomDot, _CallBack, dot)
  1305. target.Event:DispatchEvent(BattleEventName.PassiveBeRandomDot, _CallBack, dot)
  1306. rand = BattleUtil.CountChangeList(rand, cl)
  1307. damage = BattleUtil.CountChangeList(damage, dcl)
  1308. return BattleUtil.RandomAction(rand, function()
  1309. local buff = Buff.Create(caster, BuffName.DOT, round, interval, dot, damage)
  1310. if func then func(buff) end
  1311. target:AddBuff(buff)
  1312. end)
  1313. end
  1314. function BattleUtil.RandomList(arr)
  1315. if #arr <= 1 then return end
  1316. local index
  1317. for i=#arr, 1, -1 do
  1318. index = Random.RangeInt(1, i)
  1319. arr[i], arr[index] = arr[index], arr[i]
  1320. end
  1321. end
  1322. function BattleUtil.Sort(arr, comp)
  1323. if #arr <= 1 then return arr end
  1324. for i=1, #arr do
  1325. for j = #arr, i+1, -1 do
  1326. if comp(arr[j-1], arr[j]) then
  1327. arr[j-1], arr[j] = arr[j], arr[j-1]
  1328. end
  1329. end
  1330. end
  1331. return arr
  1332. end
  1333. function BattleUtil.GetPropertyName(type)
  1334. if type == 1 then
  1335. return RoleDataName.Strength
  1336. elseif type == 2 then
  1337. return RoleDataName.Energy
  1338. elseif type == 3 then
  1339. return RoleDataName.Vitality
  1340. elseif type == 4 then
  1341. return RoleDataName.Dexterity
  1342. elseif type == 5 then
  1343. return RoleDataName.Speed
  1344. elseif type == 6 then
  1345. return RoleDataName.PhysicalAttack
  1346. elseif type == 7 then
  1347. return RoleDataName.MagicAttack
  1348. elseif type == 8 then
  1349. return RoleDataName.PhysicalDefence
  1350. elseif type == 9 then
  1351. return RoleDataName.MagicDefence
  1352. end
  1353. end
  1354. function BattleUtil.GetHPPencent(role)
  1355. return role:GetRoleData(RoleDataName.Hp) / role:GetRoleData(RoleDataName.MaxHp)
  1356. end
  1357. -- 计算数值
  1358. function BattleUtil.CountValue(v1, v2, ct)
  1359. local v = v1
  1360. if ct == 1 then --加算
  1361. v = v + v2
  1362. elseif ct == 2 then --乘加算(百分比属性加算)
  1363. v = v * (1 + v2)
  1364. elseif ct == 3 then --减算
  1365. v = v - v2
  1366. elseif ct == 4 then --乘减算(百分比属性减算)
  1367. v = v * (1 - v2)
  1368. elseif ct == 5 then -- 覆盖
  1369. v = v2
  1370. end
  1371. -- 做一个正确性检测
  1372. -- v = BattleUtil.ErrorCorrection(v)
  1373. return v
  1374. end
  1375. -- 计算数值改变
  1376. function BattleUtil.CountChangeList(v, changeList)
  1377. local aplist = {}
  1378. local splist = {}
  1379. local cplist = {}
  1380. local fv = v
  1381. -- 先算绝对值
  1382. for _, change in ipairs(changeList) do
  1383. local cv = change[1]
  1384. local ct = change[2]
  1385. if ct then
  1386. if ct == 1 or ct == 3 then
  1387. fv = BattleUtil.CountValue(fv, cv, ct)
  1388. elseif ct == 2 then
  1389. table.insert(aplist, change)
  1390. elseif ct == 4 then
  1391. table.insert(splist, change)
  1392. elseif ct == 5 then
  1393. table.insert(cplist, change)
  1394. end
  1395. end
  1396. end
  1397. -- 加乘(对基数进行加乘)
  1398. for _, change in ipairs(aplist) do
  1399. local cv = change[1]
  1400. local ct = change[2]
  1401. fv = fv + (BattleUtil.CountValue(v, cv, ct) - v)
  1402. end
  1403. -- 减乘(对最终数值进行减乘算)
  1404. for _, change in ipairs(splist) do
  1405. local cv = change[1]
  1406. local ct = change[2]
  1407. fv = BattleUtil.CountValue(fv, cv, ct)
  1408. end
  1409. -- 覆盖
  1410. for _, change in ipairs(cplist) do
  1411. local cv = change[1]
  1412. local ct = change[2]
  1413. fv = BattleUtil.CountValue(fv, cv, ct)
  1414. end
  1415. return fv
  1416. end
  1417. -- 检测技能伤害治疗加乘
  1418. function BattleUtil.CheckSkillDamageHeal(f, caster, target)
  1419. local cl = {}
  1420. local function _CallBack(v, ct)
  1421. if v then
  1422. table.insert(cl, {v, ct})
  1423. end
  1424. end
  1425. caster.Event:DispatchEvent(BattleEventName.PassiveSkillDamageHeal, _CallBack)
  1426. target.Event:DispatchEvent(BattleEventName.PassiveBeSkillDamageHeal, _CallBack)
  1427. f = BattleUtil.CountChangeList(f, cl)
  1428. return f
  1429. end
  1430. -- 检测技能伤害治疗加乘
  1431. function BattleUtil.CheckSeckill(bf, kf, caster, target)
  1432. local bcl = {}
  1433. local kcl = {}
  1434. local function _CallBack(bv, bct, kv, kct)
  1435. if bv and bct then
  1436. table.insert(bcl, {bv, bct})
  1437. end
  1438. if kv and kct then
  1439. table.insert(kcl, {kv, kct})
  1440. end
  1441. end
  1442. caster.Event:DispatchEvent(BattleEventName.PassiveSeckill, _CallBack)
  1443. target.Event:DispatchEvent(BattleEventName.PassiveBeSeckill, _CallBack)
  1444. bf = BattleUtil.CountChangeList(bf, bcl)
  1445. kf = BattleUtil.CountChangeList(kf, kcl)
  1446. return bf, kf
  1447. end
  1448. -- 获取位置类型
  1449. -- 1 前排
  1450. -- 2 后排
  1451. function BattleUtil.GetRolePosType(pos)
  1452. if pos <= 3 then
  1453. return 1
  1454. elseif pos > 3 then
  1455. return 2
  1456. end
  1457. end
  1458. -- 根据位置类型获取数据
  1459. function BattleUtil.GetRoleListByPosType(camp, posType)
  1460. if posType == 1 then
  1461. return RoleManager.Query(function (r) return r.camp == camp and r.position <= 3 end)
  1462. elseif posType == 2 then
  1463. return RoleManager.Query(function (r) return r.camp == camp and r.position > 3 end)
  1464. end
  1465. end
  1466. -- 通用增加属性的方法
  1467. function BattleUtil.AddProp(role, prop, value, ct)
  1468. if ct == 1 then --加算
  1469. role.data:AddValue(BattlePropList[prop], value)
  1470. elseif ct == 2 then --乘加算(百分比属性加算)
  1471. role.data:AddPencentValue(BattlePropList[prop], value)
  1472. elseif ct == 3 then --减算
  1473. role.data:SubValue(BattlePropList[prop], value)
  1474. elseif ct == 4 then --乘减算(百分比属性减算)
  1475. role.data:SubPencentValue(BattlePropList[prop], value)
  1476. end
  1477. end
  1478. --> 还原属性
  1479. function BattleUtil.RevertProp(role, prop, value, ct)
  1480. if ct == 3 or ct == 4 then
  1481. role.data:AddValue(BattlePropList[prop], value)
  1482. elseif ct == 2 then
  1483. role.data:SubPencentValue(BattlePropList[prop], value)
  1484. else
  1485. role.data:SubDeltaValue(BattlePropList[prop], value)
  1486. end
  1487. end
  1488. -- 规范基础伤害效果修改方法
  1489. function BattleUtil.ChangeBaseSkillDamage(role,percent,damagetype,ct)
  1490. -- 由于仅修改原始参数每次修改会叠加 所以增加镜像数据镜像为原始数据不会修改
  1491. local tempBaseDamgePercent = 1
  1492. local tempBaseDamgeType = 1
  1493. for i=9, #role.skillArrayBase[1] do
  1494. local v = role.skillArrayBase[1][i]
  1495. for j=2, #v do
  1496. for k=2, #v[j] do
  1497. if k == 2 then
  1498. tempBaseDamgePercent = v[j][k]
  1499. elseif k == 3 then
  1500. tempBaseDamgeType = v[j][k]
  1501. end
  1502. end
  1503. end
  1504. end
  1505. for i=9, #role.skillArray[1] do
  1506. local v = role.skillArray[1][i]
  1507. for j=2, #v do
  1508. for k=2, #v[j] do
  1509. if k == 2 then
  1510. if ct == 1 then --加算
  1511. v[j][k] = tempBaseDamgePercent + percent
  1512. elseif ct == 2 then --乘加算(百分比属性加算)
  1513. v[j][k] = tempBaseDamgePercent + floor(tempBaseDamgePercent * percent)
  1514. elseif ct == 3 then --减算
  1515. v[j][k] = tempBaseDamgePercent - percent
  1516. elseif ct == 4 then --乘减算(百分比属性减算)
  1517. v[j][k] = tempBaseDamgePercent - floor(tempBaseDamgePercent * percent)
  1518. end
  1519. v[j][k] = tempBaseDamgePercent * percent; --会叠加
  1520. elseif k == 3 then
  1521. v[j][k] = damagetype;
  1522. end
  1523. end
  1524. end
  1525. end
  1526. end
  1527. -- 规范基础伤害效果修改方法
  1528. function BattleUtil.ChangeSkillArrayDamage(skillArray,percent,damagetype,ct)
  1529. -- 由于仅修改原始参数每次修改会叠加 所以增加镜像数据镜像为原始数据不会修改
  1530. local tempBaseDamgePercent = 1
  1531. local tempBaseDamgeType = 1
  1532. local skillArrayBase = BattleUtil.cloneTable(skillArray)
  1533. for i=9, #skillArrayBase[1] do
  1534. local v =skillArrayBase[1][i]
  1535. for j=2, #v do
  1536. for k=2, #v[j] do
  1537. if k == 2 then
  1538. tempBaseDamgePercent = v[j][k]
  1539. elseif k == 3 then
  1540. tempBaseDamgeType = v[j][k]
  1541. end
  1542. end
  1543. end
  1544. end
  1545. for i=9, #skillArray[1] do
  1546. local v = skillArray[1][i]
  1547. for j=2, #v do
  1548. for k=2, #v[j] do
  1549. if k == 2 then
  1550. if ct == 1 then --加算
  1551. v[j][k] = tempBaseDamgePercent + percent
  1552. elseif ct == 2 then --乘加算(百分比属性加算)
  1553. v[j][k] = tempBaseDamgePercent + floor(tempBaseDamgePercent * percent)
  1554. elseif ct == 3 then --减算
  1555. v[j][k] = tempBaseDamgePercent - percent
  1556. elseif ct == 4 then --乘减算(百分比属性减算)
  1557. v[j][k] = tempBaseDamgePercent - floor(tempBaseDamgePercent * percent)
  1558. end
  1559. v[j][k] = tempBaseDamgePercent * percent; --会叠加
  1560. elseif k == 3 then
  1561. v[j][k] = damagetype;
  1562. end
  1563. end
  1564. end
  1565. end
  1566. return skillArray
  1567. end
  1568. -- 规范基础伤害效果还原方法 基础伤害固定只有2个参数 参照effect 1
  1569. function BattleUtil.RevertBaseSkillDamage(role)
  1570. -- 由于仅修改原始参数每次修改会叠加 所以增加镜像数据镜像为原始数据不会修改
  1571. local tempBaseDamgePercent = 1
  1572. local tempBaseDamgeType = 1
  1573. for i=9, #role.skillArrayBase[1] do
  1574. local v = role.skillArrayBase[1][i]
  1575. for j=2, #v do
  1576. for k=2, #v[j] do
  1577. if k == 2 then
  1578. tempBaseDamgePercent = v[j][k]
  1579. elseif k == 3 then
  1580. tempBaseDamgeType = v[j][k]
  1581. end
  1582. end
  1583. end
  1584. end
  1585. for i=9, #role.skillArray[1] do
  1586. local v = role.skillArray[1][i]
  1587. for j=2, #v do
  1588. for k=2, #v[j] do
  1589. if k == 2 then
  1590. v[j][k] = tempBaseDamgePercent
  1591. elseif k == 3 then
  1592. v[j][k] = tempBaseDamgeType;
  1593. end
  1594. end
  1595. end
  1596. end
  1597. end
  1598. --> 条件下增加属性
  1599. function BattleUtil.AddPropOnFunc(role, prop, value, ct,func)
  1600. if func and func(role) then
  1601. BattleUtil.AddProp(role, prop, value, ct)
  1602. end
  1603. end
  1604. --> 条件下还原属性
  1605. function BattleUtil.RevertPropOnFunc(role, prop, value, ct,func)
  1606. if func and func(role) then
  1607. BattleUtil.RevertProp(role, prop, value, ct)
  1608. end
  1609. end
  1610. -- 触发某一方法后注销此方法 -- 方法统一参数 @role @args
  1611. function BattleUtil.TirggerOnceAtEvent(role,func,_tirggerBattleEventName,args)
  1612. local SubFunc
  1613. SubFunc = function()
  1614. if func then func(role,args) end
  1615. role.Event:RemoveEvent(_tirggerBattleEventName, SubFunc)
  1616. end
  1617. role.Event:AddEvent(_tirggerBattleEventName, SubFunc)
  1618. end
  1619. --克隆表单
  1620. function BattleUtil.cloneTable(object)
  1621. local lookup_table = {}
  1622. local function _copy(object)
  1623. if type(object) ~= "table" then
  1624. return object
  1625. elseif lookup_table[object] then
  1626. return lookup_table[object]
  1627. end
  1628. local newObject = {}
  1629. lookup_table[object] = newObject
  1630. for key, value in pairs(object) do
  1631. newObject[_copy(key)] = _copy(value)
  1632. end
  1633. return setmetatable(newObject, getmetatable(object))
  1634. end
  1635. return _copy(object)
  1636. end
  1637. -- 逻辑回合触发某一方法后注销此方法 -- 方法统一参数 @role @args
  1638. function BattleUtil.LogicTrigerOnceAtEvent(role,func,_tirggerBattleEventName,args)
  1639. local SubFunc
  1640. SubFunc = function()
  1641. if func then func(role,args) end
  1642. BattleLogic.Event:RemoveEvent(_tirggerBattleEventName, SubFunc)
  1643. end
  1644. BattleLogic.Event:AddEvent(_tirggerBattleEventName, SubFunc)
  1645. end