local effect = require("Modules/Battle/Logic/Base/Effect") local floor = math.floor local max = math.max local min = math.min --local BattleConst = BattleConst --local RoleDataName = RoleDataName --local BattleEventName = BattleEventName local effectPool = BattleObjectPool.New(function () return { type = 0, args = {}} -- type, {args, ...} end) local effectGroupPool = BattleObjectPool.New(function () return { chooseId = 0, duration = 0, effects = {}} -- chooseId, duration, {effect1, effect2, ...} end) Skill = {} function Skill:New() local o = {cd=0,effectList = BattleList.New(),owner=0,sp=0,spPass = 0,isTeamSkill=false,teamSkillType=0 } setmetatable(o, self) self.__index = self return o end function Skill:Init(role, effectData, isTeamSkill) self.cd = isTeamSkill and effectData[1] % 100 or effectData[1] --异妖技能的cd数据为:类型*100 + cd --skill = {cd, {目标id1, 效果时间, 效果1, 效果2, ...},{目标id2, 效果时间, 效果3, 效果4, ...}, ...} --效果 = {效果类型id, 效果参数1, 效果参数2, ...} self.effectList:Clear() self.owner = role self.sp = isTeamSkill and floor(self.cd * BattleLogic.GameFrameRate) or 0 self.spPass = self.sp self.isTeamSkill = isTeamSkill self.teamSkillType = isTeamSkill and floor(effectData[1] / 100) or 0 self.isManual = false for i=2, #effectData do local v = effectData[i] local effectGroup = effectGroupPool:Get() -- chooseId, duration, {effect1, effect2, ...} effectGroup.chooseId = v[1] --chooseId effectGroup.duration = v[2] --duration for j=3, #v do --effectList local effect = effectPool:Get() -- type, {args, ...} effect.type = v[j][1] for k=2, #v[j] do effect.args[k-1] = v[j][k] end effectGroup.effects[j-2] = effect end self.effectList:Add(effectGroup) end end function Skill:Dispose() while self.effectList.size > 0 do local effectGroup = self.effectList.buffer[self.effectList.size] for k=1, #effectGroup.effects do local effect = effectGroup.effects[k] for j=1, #effect.args do effect.args[j] = nil end effectPool:Put(effect) effectGroup.effects[k] = nil end effectGroupPool:Put(effectGroup) self.effectList:Remove(self.effectList.size) end end local function takeEffect(caster, target, effects, duration) for k=1, #effects do local e = effects[k] effect[e.type](caster, target, e.args, duration) if BattleLogic.IsOpenBattleRecord then BattleLogic.RecordEffect(caster, target, e.type, e.args, duration) end end end function Skill:Cast() for i=1, self.effectList.size do local effectGroup = self.effectList.buffer[i] local chooseId = effectGroup.chooseId local arr = BattleUtil.ChooseTarget(self.owner, chooseId) if #arr > 0 then --效果延迟1帧生效 BattleLogic.WaitForTrigger(BattleLogic.GameDeltaTime, function() local duration = effectGroup.duration local effects = effectGroup.effects local nn = floor(chooseId / 10000) % 10 local count = min(chooseId % 10, #arr) if count == 0 then count = #arr end if self.owner.camp == 0 and nn == 2 then --我方释放效果开始切镜头 BattleLogic.Event:DispatchEvent(BattleEventName.ZoomIn, 0.3) BattleLogic.WaitForTrigger(duration, function() BattleLogic.Event:DispatchEvent(BattleEventName.ZoomOut, 0.3) end) end if chooseId == 10000 or chooseId == 20000 then --10000 我方aoe 20000 敌方aoe local camp = chooseId == 10000 and self.owner.camp or 1 - self.owner.camp self.owner.Event:DispatchEvent(BattleEventName.AOE, camp) for j=1, count do takeEffect(self.owner, arr[j], effects, duration) end elseif nn == 1 or nn == 3 then for j=1, count do takeEffect(self.owner, arr[j], effects, duration) end else local d = duration / (count + 1) --分割多人目标施加效果的时间,按照(1+1+..+2)的时间权重占比分配 for j=1, count do local index = j local cd = j == count and d * 2 or d BattleLogic.WaitForTrigger(d * (j-1), function() local r = arr[index] if not r or r.isDead then --当被选取的目标已经死亡或者没有,则重新选取,若重新选取的目标也死亡或者没有,则从之前的目标中选取第一个不死亡的 arr = BattleUtil.ChooseTarget(self.owner, chooseId) r = arr[index] if not r then --当没有新增的被选取目标时,可能为空 for i=1, #arr do if not arr[i].isDead then takeEffect(self.owner, arr[i], effects, cd) return end end if not r then return end end end takeEffect(self.owner, r, effects, cd) end) end end end) end end BattleLogic.SetAggro(self.owner) if not self.isTeamSkill then local time = max(8-self.owner:GetRoleData(RoleDataName.Speed)/(8*(self.owner:GetRoleData(RoleDataName.Level)+10)), 1.5) time = BattleUtil.ErrorCorrection(time) if self.owner.superSkill == self then self.sp = 0 self.spPass = floor(self.cd * BattleLogic.GameFrameRate) BattleLogic.AddMP(self.owner.camp, 10) if self.owner.skill then local skill = self.owner.skill skill.sp = 0 skill.spPass = floor(time * BattleLogic.GameFrameRate) end else self.sp = 0 self.spPass = floor(time * BattleLogic.GameFrameRate) BattleLogic.AddMP(self.owner.camp, 5) end self.owner.Event:DispatchEvent(BattleEventName.SkillCast, self) else self.sp = 0 self.owner.curSkill = self BattleLogic.Event:DispatchEvent(BattleEventName.SkillCast, self) end --技能的施法时间计算,根据当前目标id关联的持续时间,取其中时间最长的一个 local duration = 0 for i=1, self.effectList.size do duration = max(duration, self.effectList.buffer[i].duration) end BattleLogic.SetSkillUsable(self.owner.camp, false) self.isManual = false BattleLogic.WaitForTrigger(duration, function() BattleLogic.SetSkillUsable(self.owner.camp, true) if not self.isTeamSkill then self.owner.Event:DispatchEvent(BattleEventName.SkillCastEnd, self) else BattleLogic.Event:DispatchEvent(BattleEventName.SkillCastEnd, self.cd) end end) end --表现层调用 function Skill:CanManualCast() return not self.isManual and self.owner.enable and not self.owner.ctrl_slient and self.owner.camp == 0 and not self.owner.Auto and self.sp >= self.spPass end --表现层调用 function Skill:ManualCast() --非调试模式下,只有我方阵营角色,且处在非自动状态下可手动释放技能 local b = self:CanManualCast() --调试模式下,可无条件手动释放技能 local b2 = self.owner.IsDebug if b or b2 then if self.owner.skill == self then BattleLogic.AddOption(2, self.owner.uid) else BattleLogic.AddOption(3, self.owner.uid) end self.isManual = true end end