miduo_server/luafight/Modules/Battle/Logic/Base/Skill.lua

207 lines
8.3 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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