Skill.lua 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747
  1. local effect = require("Modules/Battle/Logic/Base/Effect")
  2. local floor = math.floor
  3. local max = math.max
  4. local min = math.min
  5. --local BattleConst = BattleConst
  6. --local RoleDataName = RoleDataName
  7. --local BattleEventName = BattleEventName
  8. -- local CombatControl = ConfigManager.GetConfig(ConfigName.CombatControl)
  9. local effectPool = BattleObjectPool.New(function ()
  10. return { type = 0, args = {}} -- type, {args, ...}
  11. end)
  12. local effectGroupPool = BattleObjectPool.New(function ()
  13. return { chooseId = 0, effects = {}} -- chooseId, {effect1, effect2, ...}
  14. end)
  15. Skill = {}
  16. function Skill:New()
  17. local o = {cd=0,effectList = BattleList.New(),owner=0,sp=0,spPass=0,isTeamSkill=false,teamSkillType=0 }
  18. setmetatable(o, self)
  19. self.__index = self
  20. return o
  21. end
  22. function Skill:Init(role, effectData, type, targets, isAdd, skillSubType) --type 0 异妖 1 点技 2 滑技
  23. local isTeamSkill = type == 0
  24. self.type = type
  25. --skill = {技能ID, 命中时间, 持续时间, 伤害次数, {目标id1, 效果1, 效果2, ...},{目标id2, 效果3, 效果4, ...}, ...}
  26. --效果 = {效果类型id, 效果参数1, 效果参数2, ...}
  27. self.effectList:Clear()
  28. self.owner = role
  29. self.isTeamSkill = isTeamSkill
  30. self.teamSkillType = isTeamSkill and floor(effectData[1] / 100) or 0
  31. self.id = tonumber(effectData[1]) -- 技能ID
  32. self.hitTime = effectData[2] -- 效果命中需要的时间
  33. self.continueTime = effectData[3] -- 命中后伤害持续时间
  34. self.attackCount = effectData[4] -- 伤害持续时间内伤害次数
  35. -- self.ReturnTime = CombatControl[self.id].ReturnTime
  36. self.ReturnTime = effectData[5] --< 技能总时长
  37. self.CastBullet = effectData[6] --< 技能释放时间点 起点为动作开始
  38. self.repeatAttackTimes = effectData[7] --< 技能伤害次数
  39. --> ext参数
  40. self.ext_slot = effectData[8].slot --< 技能槽位
  41. self.isCannon = effectData[8].isCannon --< 技能表现是否为开炮类型
  42. self.targets = targets or {}
  43. self.isAdd = isAdd
  44. -- self.isRage = isRage
  45. if skillSubType then
  46. self.skillSubType = skillSubType
  47. else
  48. self.skillSubType = SkillSubType.Normal
  49. end
  50. self.totalDmg = {}
  51. for i=9, #effectData do
  52. local v = effectData[i]
  53. local effectGroup = effectGroupPool:Get() -- chooseId, {effect1, effect2, ...}
  54. effectGroup.chooseId = v[1] -- chooseId
  55. for j=2, #v do -- effectList
  56. local effect = effectPool:Get() -- type, {args, ...}
  57. effect.type = v[j][1]
  58. for k=2, #v[j] do
  59. effect.args[k-1] = v[j][k]
  60. end
  61. effectGroup.effects[j-1] = effect
  62. end
  63. self.effectList:Add(effectGroup)
  64. end
  65. --> skillArray={{50201,0.3,{0},1,1200,0,1,{cd=0,isCannon=1,release=1,slot=0},{400000,{1,1,2}}}
  66. end
  67. function Skill:Dispose()
  68. while self.effectList.size > 0 do
  69. local effectGroup = self.effectList.buffer[self.effectList.size]
  70. for k=1, #effectGroup.effects do
  71. local effect = effectGroup.effects[k]
  72. for j=1, #effect.args do
  73. effect.args[j] = nil
  74. end
  75. effectPool:Put(effect)
  76. effectGroup.effects[k] = nil
  77. end
  78. effectGroupPool:Put(effectGroup)
  79. self.effectList:Remove(self.effectList.size)
  80. end
  81. end
  82. local function DoEffect(tarIdx, caster, target, eff, duration, skill)
  83. local e = {type = 0, args = {}}
  84. e.type = eff.type
  85. for i=1, #eff.args do
  86. e.args[i] = eff.args[i]
  87. end
  88. -- 检测被动技能对技能参数的影响
  89. local function _PassiveCheck(pe)
  90. if pe then
  91. e = pe
  92. end
  93. end
  94. caster.Event:DispatchEvent(BattleEventName.SkillEffectBefore, skill, e, _PassiveCheck, tarIdx)
  95. target.Event:DispatchEvent(BattleEventName.BeSkillEffectBefore, skill, e, _PassiveCheck, tarIdx)
  96. --
  97. if effect[e.type] then
  98. effect[e.type](tarIdx, caster, target, e.args, duration, skill)
  99. local arg=""
  100. for i,ar in pairs(e.args) do
  101. arg = arg.." "..i..": "..ar
  102. end
  103. -- BattleLogManager.Log(
  104. -- "Take Effect idx:"..tarIdx.." "..arg.." du:"..duration,
  105. -- "tcamp", target.camp,
  106. -- "tpos", target.position,
  107. -- "type", e.type
  108. -- )
  109. end
  110. end
  111. function Skill:takeEffect(tarIdx, caster, target, effects, effectIndex, duration, skill)
  112. for k=1, #effects do
  113. -- 如果不是第一个效果对列的第一个效果则判断是否命中
  114. if k ~= 1 and effectIndex == 1 then
  115. if self:CheckTargetIsHit(target) or self:CheckEffectExecute(effects[k].type) then
  116. DoEffect(tarIdx, caster, target, effects[k], duration + (k-1)*BattleLogic.GameDeltaTime, skill)
  117. end
  118. else
  119. if self:CheckTargetIsHit(target) or self:CheckEffectExecute(effects[k].type) then
  120. DoEffect(tarIdx, caster, target, effects[k], duration, skill)
  121. end
  122. end
  123. end
  124. end
  125. --检测技能效果的执行(和策划规定 技能闪避后 只有伤害类型的效果才飘闪避,其他附加效果不执行)
  126. function Skill:CheckEffectExecute(effectId)
  127. --219 269 250 285 1 10 244
  128. local isHitEffect = effectId == 219
  129. or effectId == 269
  130. or effectId == 250
  131. or effectId == 285
  132. or effectId == 1
  133. or effectId == 10
  134. or effectId == 244
  135. return isHitEffect
  136. end
  137. --和策划约定阵上只有一个英雄时释放技能的对象为己方所有人而攻击目标是除自己外的逻辑互斥
  138. function Skill:CheckSkillChooseId(chooseId, targets, role)
  139. local chooseType = floor(chooseId / 100000) % 10
  140. local chooseLimit = floor(chooseId / 10000) % 10
  141. if chooseType == 1 and chooseLimit == 8 and #targets == 1 then
  142. if targets[1].roleId == role.roleId then
  143. return false
  144. end
  145. end
  146. return true
  147. end
  148. -- 释放技能
  149. -- func 技能释放完成回调
  150. function Skill:Cast(func)
  151. -- if self.isCannon ~= 0 then
  152. -- self:CastOneByOne(func)
  153. -- return
  154. -- end
  155. local chooseId = self.effectList.buffer[1].chooseId
  156. if chooseId then
  157. local sort = floor(chooseId / 10) % 10
  158. if sort == 3 then
  159. self:CastOneByOne(func)
  160. return
  161. end
  162. end
  163. self.castDoneFunc = func
  164. --
  165. -- BattleLogManager.Log(
  166. -- "Cast Skill",
  167. -- "camp", self.owner.camp,
  168. -- "pos", self.owner.position,
  169. -- "type", self.type,
  170. -- -- "isRage", tostring(self.isRage),
  171. -- "isAdd", tostring(self.isAdd)
  172. -- )
  173. local repeatTimes = self.repeatAttackTimes or 1 --< 多段
  174. repeatTimes = math.max(1, repeatTimes) --< repeatTimes need > 1
  175. --> 单次攻击 可能多个目标
  176. local function AttackOnce()
  177. self.effectTargets = {}
  178. self.targetIsHit = {}
  179. -- 先计算出技能的目标
  180. for i=1, self.effectList.size do
  181. -- 是否重新选择目标
  182. local isReTarget = true
  183. if self.targets and self.targets[i] then
  184. self.effectTargets[i] = self.targets[i]
  185. -- 判断是否有有效目标
  186. for _, role in ipairs(self.effectTargets[i]) do
  187. if role and role.IsRealDead then
  188. if not role:IsRealDead() then
  189. isReTarget = false
  190. end
  191. end
  192. end
  193. --> 传参形式目标固定 直接下一轮技能 主针对怒气 todo
  194. if isReTarget then
  195. self:EndSkill()
  196. return
  197. end
  198. end
  199. -- 重新选择目标a
  200. if isReTarget then
  201. local effectGroup = self.effectList.buffer[i]
  202. local chooseId = effectGroup.chooseId
  203. self.effectTargets[i] = {}
  204. self.effectTargets[i] = BattleUtil.ChooseTarget(self.owner, chooseId)
  205. -- 检测被动对攻击目标的影响
  206. if i == 1 then
  207. local function _PassiveTarget(targets)
  208. self.effectTargets[i] = targets
  209. end
  210. self.owner.Event:DispatchEvent(BattleEventName.SkillTargetCheck, _PassiveTarget, self)
  211. end
  212. end
  213. end
  214. -- 对目标造成相应的效果
  215. for i=1, self.effectList.size do
  216. local effectGroup = self.effectList.buffer[i]
  217. local chooseId = effectGroup.chooseId
  218. local arr = self.effectTargets[i]
  219. if arr and #arr > 0 and self:CheckSkillChooseId(chooseId, arr, self.owner) then
  220. -- for _, role in pairs(arr) do
  221. -- end
  222. -- 效果延迟1帧生效
  223. BattleLogic.WaitForTrigger(BattleLogic.GameDeltaTime, function()
  224. local effects = effectGroup.effects
  225. -- local weight = floor(chooseId % 10000 / 100)
  226. local count = #arr--min(chooseId % 10, #arr)
  227. if count == 0 then
  228. count = #arr
  229. end
  230. -- 全部同时生效
  231. for j=1, count do
  232. local funcHit = function()
  233. --if arr[j] and not arr[j]:IsRealDead() then
  234. if arr[j] then
  235. -- 检测是否命中
  236. if i == 1 then
  237. self.targetIsHit[arr[j]] = BattleUtil.CheckIsHit(self.owner, arr[j])
  238. if j == 1 then--< 技能第一效果到位时触发 在效果前触发
  239. BattleLogic.WaitForTrigger(self.hitTime, function ()
  240. self.owner.Event:DispatchEvent(BattleEventName.SkillFirstEffectTrigger, self)
  241. end)
  242. end
  243. if j == count then
  244. BattleLogic.WaitForTrigger(self.hitTime, function ()
  245. self.owner.Event:DispatchEvent(BattleEventName.SkillLastEffectTrigger, self)
  246. end)
  247. end
  248. else
  249. self.targetIsHit[arr[j]] = BattleUtil.CheckIsHit(self.owner, arr[j])
  250. end
  251. if i ~= 1 then
  252. self:takeEffect(j, self.owner, arr[j], effects, i, 0, self, chooseId)
  253. else
  254. self:takeEffect(j, self.owner, arr[j], effects, i, self.hitTime, self, chooseId)
  255. end
  256. end
  257. end
  258. --> 第一作用效果 有延时 第二效果后全部技能开始时触发
  259. if i == 1 then
  260. --> 不开炮类型
  261. if self.isCannon == 0 then
  262. funcHit()
  263. else
  264. BattleLogic.WaitForTrigger(self.ReturnTime / 1000 * (j - 1), function()
  265. funcHit()
  266. end)
  267. end
  268. else
  269. funcHit()
  270. end
  271. end
  272. -- self.totalDmg = {}
  273. -- local function floatTotalDmg(idx)
  274. -- if not self.totalDmg[idx] then
  275. -- return
  276. -- end
  277. -- local totalnum = 0
  278. -- for i = 1, #self.totalDmg do
  279. -- totalnum = totalnum + self.totalDmg[i]
  280. -- end
  281. -- BattleLogic.Event:DispatchEvent(BattleEventName.FloatTotal, totalnum)
  282. -- end
  283. -- BattleLogic.WaitForTrigger(self.hitTime, function ()
  284. -- if self.totalDmg then
  285. -- if self.attackCount ~= 1 then
  286. -- for i = 1, #self.continueTime do
  287. -- local time = 0
  288. -- for j = 1, i do
  289. -- time = time + self.continueTime[j] / 1000
  290. -- end
  291. -- BattleLogic.WaitForTrigger(time, function()
  292. -- floatTotalDmg(i + 1)
  293. -- end)
  294. -- end
  295. -- floatTotalDmg(1)
  296. -- else
  297. -- floatTotalDmg(1)
  298. -- end
  299. -- end
  300. -- end)
  301. end)
  302. end
  303. end
  304. -- if self.isTeamSkill then
  305. -- self.owner.curSkill = self
  306. -- end
  307. -- 释放技能开始
  308. -- self.owner.Event:DispatchEvent(BattleEventName.SkillCast, self)
  309. -- BattleLogic.Event:DispatchEvent(BattleEventName.SkillCast, self)
  310. self.owner.Event:DispatchEvent(BattleEventName.SkillCast, self)
  311. BattleLogic.Event:DispatchEvent(BattleEventName.SkillCast, self)
  312. local targetNum = #self.effectTargets[1]
  313. if not self.owner.ctrl_chaos or self.owner.ctrl_chaos_beatBack then --< 混乱状态不表现(除了混乱状态中的反击)
  314. self.owner.ctrl_chaos_beatBack = false
  315. if self.isCannon == 0 then
  316. self.owner.Event:DispatchEvent(BattleEventName.SkillFireAll, self)
  317. else
  318. for i = 1, targetNum do
  319. BattleLogic.WaitForTrigger(self.ReturnTime / 1000 * (i - 1), function()
  320. self.owner.Event:DispatchEvent(BattleEventName.SkillFireOnce, self, i)
  321. end)
  322. end
  323. end
  324. end
  325. -- 只对效果1的目标发送事件,效果1是技能的直接伤害目标
  326. -- for _, tr in ipairs(self.effectTargets[1]) do
  327. -- tr.Event:DispatchEvent(BattleEventName.BeSkillCast, self)
  328. -- end
  329. local EndSkillProcess = function()
  330. self.owner.Event:DispatchEvent(BattleEventName.SkillCastEnd, self)
  331. BattleLogic.Event:DispatchEvent(BattleEventName.SkillCastEnd, self)
  332. -- 只对效果1的目标发送事件,效果1是技能的直接伤害目标
  333. for _, tr in ipairs(self.effectTargets[1]) do
  334. tr.Event:DispatchEvent(BattleEventName.BeSkillCastEnd, self)
  335. end
  336. -- 技能结束
  337. self:EndSkill()
  338. end
  339. if self.isCannon == 0 then
  340. BattleLogic.WaitForTrigger(self.ReturnTime / 1000, function()
  341. EndSkillProcess()
  342. end)
  343. else
  344. BattleLogic.WaitForTrigger(self.ReturnTime / 1000 * targetNum, function()
  345. repeatTimes = repeatTimes - 1
  346. if repeatTimes == 0 then
  347. EndSkillProcess()
  348. else
  349. AttackOnce()
  350. end
  351. end)
  352. end
  353. end
  354. self.owner.Event:DispatchEvent(BattleEventName.SkillSelectBefore, self)
  355. AttackOnce()
  356. end
  357. -- func 技能释放完成回调
  358. function Skill:CastUnit(func)
  359. self.castDoneFunc = func
  360. local function SkillPlay()
  361. self.effectTargets = {}
  362. self.targetIsHit = {}
  363. -- 先计算出技能的目标
  364. for i=1, self.effectList.size do
  365. -- 是否重新选择目标
  366. local isReTarget = true
  367. if self.targets and self.targets[i] then
  368. self.effectTargets[i] = self.targets[i]
  369. -- 判断是否有有效目标
  370. for _, role in ipairs(self.effectTargets[i]) do
  371. if role and role.IsRealDead then
  372. if not role:IsRealDead() then
  373. isReTarget = false
  374. end
  375. end
  376. end
  377. --> 传参形式目标固定 直接下一轮技能 主针对怒气 todo
  378. if isReTarget then
  379. self:EndSkill()
  380. return
  381. end
  382. end
  383. -- 重新选择目标a
  384. if isReTarget then
  385. local effectGroup = self.effectList.buffer[i]
  386. local chooseId = effectGroup.chooseId
  387. self.effectTargets[i] = {}
  388. self.effectTargets[i] = BattleUtil.ChooseTarget(self.owner, chooseId)
  389. -- 检测被动对攻击目标的影响
  390. if i == 1 then
  391. local function _PassiveTarget(targets)
  392. self.effectTargets[i] = targets
  393. end
  394. self.owner.Event:DispatchEvent(BattleEventName.SkillTargetCheck, _PassiveTarget, self)
  395. end
  396. end
  397. end
  398. -- 对目标造成相应的效果
  399. for i=1, self.effectList.size do
  400. local effectGroup = self.effectList.buffer[i]
  401. local chooseId = effectGroup.chooseId
  402. local arr = self.effectTargets[i]
  403. if arr and #arr > 0 then
  404. -- 效果延迟1帧生效
  405. BattleLogic.WaitForTrigger(BattleLogic.GameDeltaTime, function()
  406. local effects = effectGroup.effects
  407. -- local weight = floor(chooseId % 10000 / 100)
  408. local count = min(chooseId % 10, #arr)
  409. if count == 0 then
  410. count = #arr
  411. end
  412. -- 全部同时生效
  413. for j=1, count do
  414. if arr[j] and not arr[j]:IsRealDead() then
  415. -- 检测是否命中
  416. if i == 1 then
  417. self.targetIsHit[arr[j]] = BattleUtil.CheckIsHit(self.owner, arr[j])
  418. if j == 1 then--< 技能第一效果到位时触发 在效果前触发
  419. BattleLogic.WaitForTrigger(self.hitTime, function ()
  420. self.owner.Event:DispatchEvent(BattleEventName.SkillFirstEffectTrigger, self)
  421. end)
  422. end
  423. if j == count then
  424. BattleLogic.WaitForTrigger(self.hitTime, function ()
  425. self.owner.Event:DispatchEvent(BattleEventName.SkillLastEffectTrigger, self)
  426. end)
  427. end
  428. end
  429. if i ~= 1 then
  430. self:takeEffect(j, self.owner, arr[j], effects, i, 0, self)
  431. else
  432. self:takeEffect(j, self.owner, arr[j], effects, i, self.hitTime, self)
  433. end
  434. end
  435. end
  436. end)
  437. end
  438. end
  439. self.owner.Event:DispatchEvent(BattleEventName.SkillCast, self)
  440. BattleLogic.Event:DispatchEvent(BattleEventName.SkillCast, self)
  441. local EndSkillProcess = function()
  442. self.owner.Event:DispatchEvent(BattleEventName.SkillCastEnd, self)
  443. BattleLogic.Event:DispatchEvent(BattleEventName.SkillCastEnd, self)
  444. -- 只对效果1的目标发送事件,效果1是技能的直接伤害目标
  445. for _, tr in ipairs(self.effectTargets[1]) do
  446. tr.Event:DispatchEvent(BattleEventName.BeSkillCastEnd, self)
  447. end
  448. -- 技能结束
  449. self:EndSkill()
  450. end
  451. BattleLogic.WaitForTrigger(self.ReturnTime / 1000, function()
  452. EndSkillProcess()
  453. end)
  454. end
  455. SkillPlay()
  456. end
  457. -- 释放技能
  458. -- func 技能释放完成回调
  459. function Skill:CastOneByOne(func)
  460. self.castDoneFunc = func
  461. --
  462. -- BattleLogManager.Log(
  463. -- "Cast Skill",
  464. -- "camp", self.owner.camp,
  465. -- "pos", self.owner.position,
  466. -- "type", self.type,
  467. -- "isAdd", tostring(self.isAdd)
  468. -- )
  469. self.effectTargets = {}
  470. self.targetIsHit = {}
  471. self.beEndTargets = {}
  472. self.hit3TimesCheck = {} --< 3次攻击限定
  473. self.excludeAttackList = {}
  474. local effectGroup = self.effectList.buffer[1]
  475. local chooseId = effectGroup.chooseId
  476. local targets = BattleUtil.ChooseTarget(self.owner, chooseId)
  477. --> 2+...目标组效果
  478. for i = 2, self.effectList.size do
  479. local effectGroup = self.effectList.buffer[i]
  480. local chooseId = effectGroup.chooseId
  481. self.effectTargets[i] = BattleUtil.ChooseTarget(self.owner, chooseId)
  482. local arr = self.effectTargets[i]
  483. if arr and #arr > 0 then
  484. -- 效果延迟1帧生效
  485. BattleLogic.WaitForTrigger(BattleLogic.GameDeltaTime, function()
  486. local effects = effectGroup.effects
  487. local count = min(chooseId % 10, #arr)
  488. if count == 0 then
  489. count = #arr
  490. end
  491. -- 全部同时生效
  492. for j = 1, count do
  493. if arr[j] then
  494. --> 此处非第一组目标效果都在 hitTime 时触发所有(可改为0释放时即触发 未改因为可能策划有填hitTime时触发的2+...效果 如没有可改0)
  495. self:takeEffect(j, self.owner, arr[j], effects, i, 0, self)
  496. end
  497. end
  498. end)
  499. end
  500. end
  501. self.owner.Event:DispatchEvent(BattleEventName.SkillCast, self)
  502. BattleLogic.Event:DispatchEvent(BattleEventName.SkillCast, self)
  503. local targetNum = #targets
  504. if self.targets and self.targets[1] then
  505. targetNum = #self.targets[1]
  506. end
  507. for i = 1, targetNum do
  508. BattleLogic.WaitForTrigger(self.ReturnTime / 1000 * (i - 1), function()
  509. local sort = floor(chooseId / 10) % 10
  510. local target = BattleUtil.ChooseOneTarget(self.owner, chooseId, self.excludeAttackList)
  511. local function ReTarget(targets)
  512. for i = 1, #targets do
  513. local isHave = false
  514. for j = 1, #self.excludeAttackList do
  515. if targets[i] == self.excludeAttackList[j] then
  516. isHave = true
  517. break
  518. end
  519. end
  520. if not isHave and not targets[i]:IsRealDead() then --< 无重复&未死亡 死亡按原有选择目标
  521. target = targets[i]
  522. break
  523. end
  524. end
  525. end
  526. if self.targets and self.targets[1] then
  527. ReTarget(self.targets[1])
  528. end
  529. -- 检测被动对攻击目标的影响
  530. local function _PassiveTarget(targets)
  531. ReTarget(targets)
  532. end
  533. self.owner.Event:DispatchEvent(BattleEventName.SkillTargetCheck, _PassiveTarget, self)
  534. if sort ~= 3 then
  535. table.insert(self.excludeAttackList, target)
  536. else
  537. --> 单体攻击限定3次内
  538. if self.hit3TimesCheck[target] == nil then
  539. self.hit3TimesCheck[target] = 0
  540. end
  541. self.hit3TimesCheck[target] = self.hit3TimesCheck[target] + 1
  542. if self.hit3TimesCheck[target] >= 3 then
  543. table.insert(self.excludeAttackList, target)
  544. end
  545. end
  546. if target then
  547. self.beEndTargets[target] = target
  548. end
  549. --> 第一目标组效果
  550. self.effectTargets[1] = {target}
  551. -- 效果延迟1帧生效
  552. BattleLogic.WaitForTrigger(BattleLogic.GameDeltaTime, function()
  553. local effects = effectGroup.effects
  554. if self.effectTargets[1][1] then
  555. -- 检测是否命中
  556. self.targetIsHit[self.effectTargets[1][1]] = BattleUtil.CheckIsHit(self.owner, self.effectTargets[1][1])
  557. self:takeEffect(i, self.owner, target, effects, 1, self.hitTime, self)
  558. end
  559. end)
  560. if not self.owner.ctrl_chaos then --< 混乱状态不表现
  561. self.owner.Event:DispatchEvent(BattleEventName.SkillFireOnce, self, 1)
  562. end
  563. end)
  564. end
  565. local EndSkillProcess = function()
  566. self.owner.Event:DispatchEvent(BattleEventName.SkillCastEnd, self)
  567. BattleLogic.Event:DispatchEvent(BattleEventName.SkillCastEnd, self)
  568. -- 只对效果1的目标发送事件,效果1是技能的直接伤害目标
  569. for _, tr in pairs(self.beEndTargets) do
  570. tr.Event:DispatchEvent(BattleEventName.BeSkillCastEnd, self)
  571. end
  572. -- 技能结束
  573. self:EndSkill()
  574. end
  575. BattleLogic.WaitForTrigger(self.ReturnTime / 1000 * targetNum, function()
  576. EndSkillProcess()
  577. end)
  578. end
  579. -- 获取技能的直接目标,和策划规定第一个效果的目标为直接效果目标,(包含miss的目标)
  580. function Skill:GetDirectTargets()
  581. return self.effectTargets[1]
  582. end
  583. -- 获取直接目标,不包含miss的目标,可能为空
  584. function Skill:GetDirectTargetsNoMiss()
  585. local list = {}
  586. for _, role in ipairs(self.effectTargets[1]) do
  587. if self:CheckTargetIsHit(role) then
  588. table.insert(list, role)
  589. end
  590. end
  591. return list
  592. end
  593. -- 获取技能目标最大人数
  594. function Skill:GetMaxTargetNum()
  595. local mainEffect = self.effectList.buffer[1]
  596. if not mainEffect then
  597. return 0
  598. end
  599. return BattleUtil.GetMaxTargetNum(mainEffect.chooseId)
  600. end
  601. -- 判断是否命中
  602. function Skill:CheckTargetIsHit(role)
  603. return self.targetIsHit[role]
  604. end
  605. -- 结束技能
  606. function Skill:EndSkill()
  607. -- 技能后摇
  608. -- 技能结束后摇后结束技能释放
  609. BattleLogic.WaitForTrigger(0.3, function()
  610. -- 结束回调
  611. if self.castDoneFunc then self.castDoneFunc() end
  612. end)
  613. --
  614. self.effectTargets = {}
  615. end