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

219 lines
6.6 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")
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,eff)
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,self.skill)
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],self.skill)
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
-- 获取直接目标和没有被放逐的目标不包含miss的目标可能为空
function EffectCaster:GetDirectTargetsNoExile()
local list = {}
for _, role in ipairs(self.effectTargets[1]) do
if not role.isExile 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