local effect = require("Modules/Battle/Logic/Base/Effect") local floor = math.floor local max = math.max local min = math.min local gameFrameRate = BattleLogic.GameFrameRate --local BattleConst = BattleConst --local RoleDataName = RoleDataName --local BattleEventName = BattleEventName local function chooseTarget(role, chooseId, exceptList) local chooseType = floor(chooseId / 10000) % 10 local chooseWeight = floor(chooseId / 100) % 10 local sort = floor(chooseId / 10) % 10 local exceptNum = exceptList.size local num = chooseId % 10 local arr if chooseType == 1 then arr = BattleLogic.Query(function (r) for i=1, exceptList.size do if r.uid == exceptList.buffer[i].uid then return false end end return r.camp == role.camp end) elseif chooseType == 2 then if role.lockTarget and num == 1 then return {role.lockTarget} end arr = BattleLogic.Query(function (r) for i=1, exceptList.size do if r.uid == exceptList.buffer[i].uid then return false end end return r.camp ~= role.camp end) elseif chooseType == 3 then return {role} elseif chooseType == 4 then return {BattleLogic.GetAggro(role.camp)} else arr = BattleLogic.Query() end BattleUtil.RandomList(arr) if chooseWeight == 0 then BattleUtil.RandomList(arr) elseif chooseWeight == 1 then BattleUtil.Sort(arr, function(a, b) local r1 = a:GetRoleData(RoleDataName.Hp) local r2 = b:GetRoleData(RoleDataName.Hp) return sort == 1 and r1 < r2 or r1 > r2 end) elseif chooseWeight == 2 then BattleUtil.Sort(arr, function(a, b) local r1 = a:GetRoleData(RoleDataName.Hp) / a:GetRoleData(RoleDataName.MaxHp) local r2 = b:GetRoleData(RoleDataName.Hp) / b:GetRoleData(RoleDataName.MaxHp) return sort == 1 and r1 < r2 or r1 > r2 end) elseif chooseWeight == 3 then BattleUtil.Sort(arr, function(a, b) local r1 = a:GetRoleData(RoleDataName.Attack) local r2 = b:GetRoleData(RoleDataName.Attack) return sort == 1 and r1 < r2 or r1 > r2 end) elseif chooseWeight == 4 then BattleUtil.Sort(arr, function(a, b) local r1 = a:GetRoleData(RoleDataName.PhysicalDefence) local r2 = b:GetRoleData(RoleDataName.PhysicalDefence) return sort == 1 and r1 < r2 or r1 > r2 end) elseif chooseWeight == 5 then BattleUtil.Sort(arr, function(a, b) local r1 = a:GetRoleData(RoleDataName.PhysicalDefence) local r2 = b:GetRoleData(RoleDataName.PhysicalDefence) return sort == 1 and r1 < r2 or r1 > r2 end) elseif chooseWeight == 6 then BattleUtil.Sort(arr, function(a, b) local r1 = a:GetRoleData(RoleDataName.MagicDefence) local r2 = b:GetRoleData(RoleDataName.MagicDefence) return sort == 1 and r1 < r2 or r1 > r2 end) elseif chooseWeight == 7 then BattleUtil.Sort(arr, function(a, b) local r1 = a:GetRoleData(RoleDataName.MagicDefence) local r2 = b:GetRoleData(RoleDataName.MagicDefence) return sort == 1 and r1 < r2 or r1 > r2 end) end if exceptNum > 0 then local count = #arr for i=1, min(exceptNum, count) do for j=count, i+1, -1 do arr[j] = arr[j-1] end arr[i] = exceptList.buffer[i] end end return arr end Skill = {} function Skill:New() local o = {cd=0,effectList = BattleList.New(),owner=0,sp=0,spPass = 0,choosedList = BattleList.New(),isTeamSkill=false } setmetatable(o, self) self.__index = self return o end function Skill:Init(role, effectData) self.cd = effectData[1] --skill = {cd, {目标id1, 效果时间, 效果1, 效果2, ...},{目标id2, 效果时间, 效果3, 效果4, ...}, ...} --效果 = {效果类型id, 效果参数1, 效果参数2, ...} self.effectList:Clear() self.owner = role self.sp = 0 self.spPass = 0 self.choosedList:Clear() self.isTeamSkill = false local v for i=2, #effectData do v = effectData[i] local effectGroup = { 0, 0, {}} -- chooseId, duration, {effect1, effect2, ...} effectGroup[1] = v[1] --chooseId effectGroup[2] = v[2] --duration for j=3, #v do --effectList local effect = {0, {}} -- type, {args, ...} effect[1] = v[j][1] for k=2, #v[j] do effect[2][k-1] = v[j][k] end effectGroup[3][j-2] = effect end self.effectList:Add(effectGroup) end end function Skill:ResetCD() if not self.isTeamSkill then if self.owner.superSkill == self then self.sp = 0 self.spPass = floor(self.cd * BattleLogic.GameFrameRate) self.owner.Event:DispatchEvent(BattleEventName.SkillCast, self) BattleLogic.AddMP(self.owner.camp, 10) if self.owner.skill then local skill = self.owner.skill local time = max(6-self.owner:GetRoleData(RoleDataName.Speed)/(8*(self.owner:GetRoleData(RoleDataName.Level)+10)), 1.5) skill.sp = 0 skill.spPass = floor(time * BattleLogic.GameFrameRate) end else local time = max(6-self.owner:GetRoleData(RoleDataName.Speed)/(8*(self.owner:GetRoleData(RoleDataName.Level)+10)), 1.5) self.sp = 0 self.spPass = floor(time * BattleLogic.GameFrameRate) BattleLogic.AddMP(self.owner.camp, 8) self.owner.Event:DispatchEvent(BattleEventName.SkillCast, self) end else BattleLogic.Event:DispatchEvent(BattleEventName.SkillCast, self.cd) --队伍技能结构和其他相同,只是cd项为对应异妖类型 end local duration = 0 for i=1, self.effectList.size do duration = max(duration, self.effectList.buffer[i][2]) end BattleLogic.SetSkillUsable(self.owner.camp, false) BattleLogic.WaitForTrigger(duration, function() BattleLogic.SetSkillUsable(self.owner.camp, true) end) BattleLogic.SetAggro(self.owner, 0) end local function takeEffect(type, caster, target, args, interval) effect[type](caster, target, args, interval) if BattleLogic.IsOpenBattleRecord then BattleLogic.RecordEffect(caster, target, type, args, interval) end end function Skill:Cast() for i=1, self.effectList.size do local effectGroup = self.effectList.buffer[i] local chooseId = effectGroup[1] local duration = effectGroup[2] local arr = chooseTarget(self.owner, chooseId, self.choosedList) if #arr > 0 then --延迟1帧释放效果 BattleLogic.WaitForTrigger(BattleLogic.GameDeltaTime, function () local nn = floor(chooseId / 10000) % 10 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 then --我方aoe self.owner.Event:DispatchEvent(BattleEventName.AOE, 0) for j=1, #arr do for k=1, #effectGroup[3] do local v = effectGroup[3][k] takeEffect(v[1], self.owner, arr[j], v[2], duration) end end elseif chooseId == 20000 then --敌方aoe self.owner.Event:DispatchEvent(BattleEventName.AOE, 1) for j=1, #arr do for k=1, #effectGroup[3] do local v = effectGroup[3][k] takeEffect(v[1], self.owner, arr[j], v[2], duration) end end elseif nn == 1 or nn == 3 then for j=1, #arr do for k=1, #effectGroup[3] do local v = effectGroup[3][k] takeEffect(v[1], self.owner, arr[j], v[2], duration) end end else local count = chooseId % 10 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 = chooseTarget(self.owner, chooseId, self.choosedList) r = arr[index] if not r then --当没有新增的被选取目标时,可能为空 for i=1, #arr do if not arr[i].isDead then r = arr[i] for k=1, #effectGroup[3] do local v = effectGroup[3][k] takeEffect(v[1], self.owner, r, v[2], cd) end return end end if not r then return end end end self.choosedList:Add(r) for k=1, #effectGroup[3] do local v = effectGroup[3][k] takeEffect(v[1], self.owner, r, v[2], cd) end end) end BattleLogic.WaitForTrigger(duration, function() self.choosedList:Clear() end) end end) end end self:ResetCD() end --表现层调用 function Skill:CanManualCast() return not self.owner.IsDebug and self.owner.camp == 0 and not self.owner.Auto and self.sp >= self.spPass and BattleLogic.GetSkillUsable(self.owner.camp) 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 end end