226 lines
7.7 KiB
Lua
226 lines
7.7 KiB
Lua
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, effects = {}} -- chooseId, {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, targets, isAdd, isRage) --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.hitTime = effectData[2] -- 效果命中需要的时间
|
||
self.continueTime = effectData[3] -- 命中后伤害持续时间
|
||
self.attackCount = effectData[4] -- 伤害持续时间内伤害次数
|
||
|
||
self.targets = targets or {}
|
||
self.isAdd = isAdd
|
||
self.isRage = isRage
|
||
|
||
for i=5, #effectData do
|
||
local v = effectData[i]
|
||
local effectGroup = effectGroupPool:Get() -- chooseId, {effect1, effect2, ...}
|
||
effectGroup.chooseId = v[1] -- chooseId
|
||
for j=2, #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-1] = 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 = {type = 0, args = {}}
|
||
e.type = effects[k].type
|
||
for i=1, #effects[k].args do
|
||
e.args[i] = effects[k].args[i]
|
||
end
|
||
|
||
-- 检测被动技能对技能参数的影响
|
||
local function _PassiveCheck(pe)
|
||
if pe then
|
||
e = pe
|
||
end
|
||
end
|
||
caster.Event:DispatchEvent(BattleEventName.SkillEffectBefore, skill, e, _PassiveCheck)
|
||
target.Event:DispatchEvent(BattleEventName.BeSkillEffectBefore, skill, e, _PassiveCheck)
|
||
|
||
--
|
||
if effect[e.type] then
|
||
effect[e.type](caster, target, e.args, duration, skill)
|
||
|
||
BattleLogManager.Log(
|
||
"Take Effect",
|
||
"tcamp", target.camp,
|
||
"tpos", target.position,
|
||
"type", e.type
|
||
)
|
||
end
|
||
end
|
||
end
|
||
|
||
-- 释放技能
|
||
-- func 技能释放完成回调
|
||
function Skill:Cast(func)
|
||
self.castDoneFunc = func
|
||
self.effectTargets = {}
|
||
|
||
-- 先计算出技能的目标
|
||
for i=1, self.effectList.size do
|
||
-- 是否重新选择目标
|
||
local isReTarget = true
|
||
if self.targets and self.targets[i] then
|
||
self.effectTargets[i] = self.targets[i]
|
||
-- 判断是否有有效目标
|
||
for _, role in ipairs(self.effectTargets[i]) do
|
||
if not role:IsRealDead() then
|
||
isReTarget = false
|
||
end
|
||
end
|
||
end
|
||
-- 重新选择目标a
|
||
if isReTarget then
|
||
local effectGroup = self.effectList.buffer[i]
|
||
local chooseId = effectGroup.chooseId
|
||
self.effectTargets[i] = BattleUtil.ChooseTarget(self.owner, chooseId)
|
||
-- 检测被动对攻击目标的影响
|
||
if i == 1 then
|
||
local function _PassiveTarget(targets)
|
||
self.effectTargets[i] = targets
|
||
end
|
||
self.owner.Event:DispatchEvent(BattleEventName.SkillTargetCheck, _PassiveTarget)
|
||
end
|
||
end
|
||
end
|
||
--
|
||
BattleLogManager.Log(
|
||
"Cast Skill",
|
||
"camp", self.owner.camp,
|
||
"pos", self.owner.position,
|
||
"type", self.type,
|
||
"isRage", tostring(self.isRage),
|
||
"isAdd", tostring(self.isAdd)
|
||
)
|
||
|
||
-- 对目标造成相应的效果
|
||
for i=1, self.effectList.size do
|
||
local effectGroup = self.effectList.buffer[i]
|
||
local chooseId = effectGroup.chooseId
|
||
local arr = self.effectTargets[i]
|
||
if arr and #arr > 0 then
|
||
--效果延迟1帧生效
|
||
BattleLogic.WaitForTrigger(BattleLogic.GameDeltaTime, function()
|
||
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]:IsRealDead() then
|
||
takeEffect(self.owner, arr[j], effects, self.hitTime, self)
|
||
end
|
||
end
|
||
end)
|
||
end
|
||
end
|
||
|
||
if self.isTeamSkill then
|
||
self.owner.curSkill = self
|
||
end
|
||
|
||
-- 释放技能开始
|
||
self.owner.Event:DispatchEvent(BattleEventName.SkillCast, self)
|
||
BattleLogic.Event:DispatchEvent(BattleEventName.SkillCast, self)
|
||
-- 只对效果1的目标发送事件,效果1是技能的直接伤害目标
|
||
for _, tr in ipairs(self.effectTargets[1]) do
|
||
tr.Event:DispatchEvent(BattleEventName.BeSkillCast, self)
|
||
end
|
||
--技能的施法时间计算,根据当前目标id关联的持续时间,取其中时间最长的一个
|
||
local duration = self.hitTime + self.continueTime
|
||
-- 结算时间向后延长0.2秒,避免在效果结算完成前就结束了技能释放
|
||
BattleLogic.WaitForTrigger(duration + 0.2, function()
|
||
self.owner.Event:DispatchEvent(BattleEventName.SkillCastEnd, self)
|
||
BattleLogic.Event:DispatchEvent(BattleEventName.SkillCastEnd, self)
|
||
|
||
-- 只对效果1的目标发送事件,效果1是技能的直接伤害目标
|
||
for _, tr in ipairs(self.effectTargets[1]) do
|
||
tr.Event:DispatchEvent(BattleEventName.BeSkillCastEnd, self)
|
||
end
|
||
-- 技能结束
|
||
self:EndSkill()
|
||
end)
|
||
|
||
end
|
||
|
||
|
||
-- 获取技能的直接目标,和策划规定第一个效果的目标为直接效果目标
|
||
function Skill:GetDirectTargets()
|
||
return self.effectTargets[1]
|
||
end
|
||
-- 获取技能目标最大人数
|
||
function Skill:GetMaxTargetNum()
|
||
local mainEffect = self.effectList.buffer[1]
|
||
if not mainEffect then
|
||
return 0
|
||
end
|
||
return BattleUtil.GetMaxTargetNum(mainEffect.chooseId)
|
||
end
|
||
|
||
-- 结束技能
|
||
function Skill:EndSkill()
|
||
-- 技能后摇
|
||
-- 技能结束后摇后结束技能释放
|
||
BattleLogic.WaitForTrigger(0.3, function()
|
||
-- 结束回调
|
||
if self.castDoneFunc then self.castDoneFunc() end
|
||
|
||
end)
|
||
--
|
||
self.effectTargets = {}
|
||
end |