206 lines
6.2 KiB
Lua
206 lines
6.2 KiB
Lua
local Effect = require("Modules/Battle/Logic/Base/Effect")
|
||
EffectCaster = {}
|
||
|
||
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)
|
||
|
||
function EffectCaster:New()
|
||
local o = {}
|
||
setmetatable(o, {__index = self})
|
||
return o
|
||
end
|
||
|
||
function EffectCaster:Init(skill, effects, targets)
|
||
self.skill = skill
|
||
self.targets = targets or {}
|
||
self.effectList = {}
|
||
for i=1, #effects do
|
||
local v = effects[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
|
||
table.insert(self.effectList, effectGroup)
|
||
end
|
||
end
|
||
|
||
|
||
function EffectCaster:DoEffect(caster, target, eff, duration, skill)
|
||
local e = {type = 0, args = {}}
|
||
e.type = eff.type
|
||
for i=1, #eff.args do
|
||
e.args[i] = eff.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)
|
||
end
|
||
end
|
||
|
||
|
||
function EffectCaster:takeEffect(caster, target, effects, effectIndex, duration, skill)
|
||
for k=1, #effects do
|
||
-- 如果不是第一个效果对列的第一个效果则判断是否命中
|
||
if k ~= 1 and effectIndex == 1 then
|
||
if self:CheckTargetIsHit(target) then
|
||
self:DoEffect(caster, target, effects[k], duration, skill)
|
||
end
|
||
else
|
||
self:DoEffect(caster, target, effects[k], duration, skill)
|
||
end
|
||
end
|
||
end
|
||
|
||
|
||
function EffectCaster:ChooseTarget()
|
||
--
|
||
self.effectTargets = {}
|
||
self.targetIsHit = {}
|
||
-- 先计算出技能的目标
|
||
for i=1, #self.effectList 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
|
||
-- 重新选择目标
|
||
if isReTarget then
|
||
local effectGroup = self.effectList[i]
|
||
local chooseId = effectGroup.chooseId
|
||
self.effectTargets[i] = BattleUtil.ChooseTarget(self.skill.owner, chooseId)
|
||
-- 检测被动对攻击目标的影响
|
||
if i == 1 then
|
||
local function _PassiveTarget(targets)
|
||
self.effectTargets[i] = targets
|
||
end
|
||
self.skill.owner.Event:DispatchEvent(BattleEventName.SkillTargetCheck, _PassiveTarget)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
-- 释放技能
|
||
-- func 技能释放完成回调
|
||
function EffectCaster:Cast()
|
||
-- 选择目标
|
||
self:ChooseTarget()
|
||
|
||
-- 对目标造成相应的效果
|
||
for i=1, #self.effectList do
|
||
local effectGroup = self.effectList[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 = math.floor(chooseId % 10000 / 100)
|
||
local count = math.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
|
||
-- 检测是否命中
|
||
if i == 1 then
|
||
self.targetIsHit[arr[j]] = BattleUtil.CheckIsHit(self.skill.owner, arr[j])
|
||
end
|
||
self:takeEffect(self.skill.owner, arr[j], effects, i, self.skill.hitTime, self.skill)
|
||
end
|
||
end
|
||
end)
|
||
end
|
||
end
|
||
end
|
||
|
||
-- 遍历技能命中目标
|
||
function EffectCaster:ForeachTargets(func)
|
||
local targets = self:GetDirectTargets()
|
||
for _, role in ipairs(targets) do
|
||
if func then
|
||
func(role)
|
||
end
|
||
end
|
||
end
|
||
|
||
-- 获取直接选择目标Id
|
||
function EffectCaster:GetDirectChooseId()
|
||
local effectGroup = self.effectList[1]
|
||
local chooseId = effectGroup.chooseId
|
||
return chooseId
|
||
end
|
||
|
||
|
||
-- 获取技能的直接目标,和策划规定第一个效果的目标为直接效果目标,(包含miss的目标)
|
||
function EffectCaster:GetDirectTargets()
|
||
return self.effectTargets[1]
|
||
end
|
||
|
||
-- 获取直接目标,不包含miss的目标,可能为空
|
||
function EffectCaster:GetDirectTargetsNoMiss()
|
||
local list = {}
|
||
for _, role in ipairs(self.effectTargets[1]) do
|
||
if self:CheckTargetIsHit(role) then
|
||
table.insert(list, role)
|
||
end
|
||
end
|
||
return list
|
||
end
|
||
|
||
-- 获取技能目标最大人数
|
||
function EffectCaster:GetMaxTargetNum()
|
||
local mainEffect = self.effectList[1]
|
||
if not mainEffect then
|
||
return 0
|
||
end
|
||
return BattleUtil.GetMaxTargetNum(mainEffect.chooseId)
|
||
end
|
||
|
||
-- 判断是否命中
|
||
function EffectCaster:CheckTargetIsHit(role)
|
||
return self.targetIsHit[role]
|
||
end
|
||
|
||
function EffectCaster:Dispose()
|
||
for _, effectGroup in ipairs(self.effectList) do
|
||
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)
|
||
end
|
||
self.effectList = {}
|
||
end
|
||
|
||
return EffectCaster |