miduo_client/Assets/ManagedResources/~Lua/Modules/Battle/Logic/Base/EffectCaster.lua

206 lines
6.2 KiB
Lua
Raw Normal View History

2020-11-01 15:46:48 +08:00
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