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, type) --type 0 异妖 1 点技 2 滑技 local isTeamSkill = type == 0 if type == 0 then --异妖 self.cd = effectData[1] % 100 --异妖技能的cd数据为:类型*100 + 站位 self.randomInStage2 = 0 elseif type == 1 then --点技 self.cd = 0 --点技 cd为0 self.randomInStage2 = 0 elseif type == 2 then --滑技 self.cd = effectData[1] % 100 --上滑技的cd数据为:中期上滑概率*100000 + cd self.randomInStage2 = (effectData[1] - self.cd) / 100000 end --skill = {cd, {目标id1, 效果时间, 效果1, 效果2, ...},{目标id2, 效果时间, 效果3, 效果4, ...}, ...} --效果 = {效果类型id, 效果参数1, 效果参数2, ...} self.effectList:Clear() self.owner = role self.isTeamSkill = isTeamSkill self.teamSkillType = isTeamSkill and floor(effectData[1] / 100) or 0 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 weight = floor(chooseId % 10000 / 100) local count = min(chooseId % 10, #arr) if count == 0 then count = #arr 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 weight == 8 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 if not self.isTeamSkill then local type = BattleLogic.Type local isPVEMonster = self.owner.camp == 1 and (type == 1 or type == 2 or type == 4 or type == 5 or type == 8) local time = 0 if isPVEMonster then if self.owner.superSkill == self then --怪物绝技读条时间=max(10-速度/(8*(等级+10)),2) time = max(10-self.owner:GetRoleData(RoleDataName.Speed)/(8*(self.owner:GetRoleData(RoleDataName.Level)+10)), 2) else --怪物普技读条时间==max(9-速度/(8*(等级+10)),1) time = max(9-self.owner:GetRoleData(RoleDataName.Speed)/(8*(self.owner:GetRoleData(RoleDataName.Level)+10)), 1) end else if self.owner.superSkill == self then --绝技读条时间=max(9-速度/(8*(等级+10)),3) time = max(9-self.owner:GetRoleData(RoleDataName.Speed)/(8*(self.owner:GetRoleData(RoleDataName.Level)+10)), 3) else --普技读条时间=max(7-速度/(8*(等级+10)),1.5) time = max(7-self.owner:GetRoleData(RoleDataName.Speed)/(8*(self.owner:GetRoleData(RoleDataName.Level)+10)), 1.5) end end self.owner.sp = 0 self.owner.spPass = floor(BattleUtil.ErrorCorrection(time) * BattleLogic.GameFrameRate) else self.owner.curSkill = self end self.owner.Event:DispatchEvent(BattleEventName.SkillCast, self) BattleLogic.Event:DispatchEvent(BattleEventName.SkillCast, self) --技能的施法时间计算,根据当前目标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) BattleLogic.WaitForTrigger(duration, function() BattleLogic.SetSkillUsable(self.owner.camp, true) self.owner.Event:DispatchEvent(BattleEventName.SkillCastEnd, self) BattleLogic.Event:DispatchEvent(BattleEventName.SkillCastEnd, self) end) end