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 self.type = type --skill = {技能ID, {目标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 self.id = effectData[1] -- 技能ID -- self.EffectDuration = 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, skill) for k=1, #effects do local e = effects[k] effect[e.type](caster, target, e.args, duration, skill) if BattleLogic.IsOpenBattleRecord then BattleLogic.RecordEffect(caster, target, e.type, e.args, duration) end end end -- 释放技能 -- func 技能释放完成回调 -- targets 指定技能释放目标 -- isAdd 是否是追加技能 function Skill:Cast(func, targets, isAdd) self.castDoneFunc = func self.effectTargets = {} self.isAdd = isAdd for i=1, self.effectList.size do local effectGroup = self.effectList.buffer[i] local chooseId = effectGroup.chooseId local arr = targets or 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 -- 全部同时生效 for j=1, count do if arr[j] and not arr[j].isDead then takeEffect(self.owner, arr[j], effects, duration, self) -- 加入目标列表 table.insert(self.effectTargets, arr[j]) end end -- if chooseId == 100000 or chooseId == 200000 then --10000 我方aoe 20000 敌方aoe -- local camp = chooseId == 100000 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, self) -- -- 加入目标列表 -- table.insert(self.effectTargets, arr[j]) -- end -- elseif weight == 7 then --对位相邻的目标同时触发效果 -- for j=1, count do -- takeEffect(self.owner, arr[j], effects, duration, self) -- -- 加入目标列表 -- table.insert(self.effectTargets, arr[j]) -- end -- else -- for j = 1, count do -- local index = j -- local r = arr[index] -- -- if not r or r.isDead then --当被选取的目标已经死亡或者没有,则重新选取,若重新选取的目标也死亡或者没有,则从之前的目标中选取第一个不死亡的 -- -- if not targets 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 -- -- r = arr[i] -- -- break -- -- end -- -- end -- -- end -- -- end -- -- end -- -- -- if r and not r.isDead then -- takeEffect(self.owner, r, effects, duration, self) -- -- 加入目标列表 -- table.insert(self.effectTargets, r) -- end -- end -- end end) end end -- 计算技能CD的没有用了 -- 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 -- if self.isTeamSkill then self.owner.curSkill = self end -- 延时一帧执行,避免战斗还没开始就释放了技能 -- BattleLogic.WaitForTrigger(BattleLogic.GameDeltaTime, function() self.owner.Event:DispatchEvent(BattleEventName.SkillCast, 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) BattleLogic.WaitForTrigger(duration, function() BattleLogic.SetSkillUsable(self.owner.camp, true) self.owner.Event:DispatchEvent(BattleEventName.SkillCastEnd, self) BattleLogic.Event:DispatchEvent(BattleEventName.SkillCastEnd, self) for _, tr in ipairs(self.effectTargets) do tr.Event:DispatchEvent(BattleEventName.BeSkillCastEnd, self) end -- 技能结束 self:EndSkill() end) end -- 结束技能 function Skill:EndSkill() -- 技能结束后摇后结束技能释放 -- if self.isAdd then -- if self.castDoneFunc then self.castDoneFunc() end -- else -- 非追加技能加入技能后摇 BattleLogic.WaitForTrigger(0.5, function() if self.castDoneFunc then self.castDoneFunc() end end) -- end -- self.effectTargets = {} self.isAdd = nil end