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

219 lines
7.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.

Buff = {}
local floor = math.floor
local buffPoolList = {}
local getBuff = function(type)
if not buffPoolList[type] then
buffPoolList[type] = BattleObjectPool.New(function (type)
return require("Modules/Battle/Logic/Buff/"..type):New()
end)
end
return buffPoolList[type]:Get(type)
end
local putBuff = function(buff)
if buffPoolList[buff.type] then
buffPoolList[buff.type]:Put(buff)
end
end
local buffListPool = BattleObjectPool.New(function ()
return BattleList.New()
end)
function Buff:New()
local o = {}
setmetatable(o, self)
self.__index = self
return o
end
function Buff.Create(caster, type, duration, ...)
local buff = getBuff(type)
buff.type = type
buff.id = BattleLogic.GenerateBuffId()
buff.caster = caster
buff.disperse = false
buff.cover = false
buff.duration = duration --持续时间为0时buff永久存在
buff.interval = -1 --间隔帧为0时每帧触发小于0不触发 默认不触发OnTrigger
buff.framePass = 0
buff:SetData(...)
return buff
end
BuffManager = {}
BuffManager.__index = BuffManager
function BuffManager.New()
local instance = {owner=0, buffQueue = BattleQueue.New(), buffList = BattleDictionary.New()}
setmetatable(instance, BuffManager)
return instance
end
function BuffManager:Init()
while self.buffQueue.size > 0 do
putBuff:Put(self.buffQueue:Dequeue())
end
for i = 1, self.buffList.size do
local list = self.buffList.vList[i]
for j=1, list.size do
list.buffer[j]:OnEnd()
putBuff(list.buffer[j])
end
list:Clear()
buffListPool:Put(list)
end
self.buffList:Clear()
end
function BuffManager:AddBuff(target, buff)
buff.target = target
self.buffQueue:Enqueue(buff)
if not buff.exCtrlTime then
buff.exCtrlTime = 0
end
buff.frameDuration = floor(buff.duration * (1 + buff.exCtrlTime) * BattleLogic.GameFrameRate)
--if buff.isBuff then --TODO:增益buff持续时间加成
-- local buffBocus = buff.caster:GetRoleData(RoleDataName.BuffBocus)
-- buff.frameDuration = floor(buff.duration * (1 + buffBocus + buff.exCtrlTime) * BattleLogic.GameFrameRate)
--end
--
--if buff.isDeBuff then --TODO:减益buff持续时间减免
-- local debuffReduce = self.owner:GetRoleData(RoleDataName.DebuffReduce)
-- buff.frameDuration = floor(buff.duration * (1 - debuffReduce - buff.exCtrlTime) * BattleLogic.GameFrameRate)
--end
buff.frameInterval = floor(buff.interval * BattleLogic.GameFrameRate)
buff.caster.Event:DispatchEvent(BattleEventName.BuffCaster, buff)
end
function BuffManager:HasBuff(target, type, checkFunc)
if self.buffList.kvList[type] then
local buffList = self.buffList.kvList[type]
for i=1, buffList.size do
local v = buffList.buffer[i]
if v.target == target then
if (not checkFunc or (checkFunc and checkFunc(v))) then
return true
end
end
end
end
return false
end
function BuffManager:ClearBuff(target, func)
for i = 1, self.buffList.size do
local list = self.buffList.vList[i]
if list.size > 0 then
local idx = 1
while idx <= list.size do
local buff = list.buffer[idx]
if buff.target == target and (not func or (func and func(buff))) then
buff:OnEnd()
buff.target.Event:DispatchEvent(BattleEventName.BuffEnd, buff)
putBuff(buff)
list:Remove(idx)
else
idx = idx + 1
end
end
end
end
end
function BuffManager:GetBuffCount(type)
if self.buffList[type] then
return self.buffList[type].size
end
return 0
end
function BuffManager:Update()
while self.buffQueue.size > 0 do
local buff = self.buffQueue:Dequeue()
local buffList
if not self.buffList.kvList[buff.type] then
buffList = buffListPool:Get()
self.buffList:Add(buff.type, buffList)
else
buffList = self.buffList.kvList[buff.type]
end
if buff.cover and buffList.size > 0 then
local isCovered = false
for i=1, buffList.size do
local oldBuff = buffList.buffer[i]
if oldBuff.cover and oldBuff.target == buff.target and oldBuff:OnCover(buff) then --判定该效果能否被覆盖
oldBuff:OnEnd()
oldBuff.target.Event:DispatchEvent(BattleEventName.BuffEnd, oldBuff)
putBuff(oldBuff)
buffList.buffer[i] = buff
buff:OnStart()
buff.target.Event:DispatchEvent(BattleEventName.BuffStart, buff)
buff.target.Event:DispatchEvent(BattleEventName.BuffCover, buff)
isCovered = true
break
end
end
if not isCovered then
buffList:Add(buff)
buff:OnStart()
buff.target.Event:DispatchEvent(BattleEventName.BuffStart, buff)
end
else
buffList:Add(buff)
buff:OnStart()
buff.target.Event:DispatchEvent(BattleEventName.BuffStart, buff)
end
end
for i=1, self.buffList.size do
local buffList = self.buffList.vList[i]
if buffList.size > 0 then
local index = 1
while index <= buffList.size do
local buff = buffList.buffer[index]
--印记类型的buff不处理更新逻辑
if buff.frameDuration == 0 and buff.frameInterval < 0 then
else
buff.framePass = buff.framePass + 1
if buff.frameDuration == 0 then
if buff.frameInterval == 0 or buff.framePass % buff.frameInterval == 0 then
if not buff:OnTrigger() then
buff.disperse = true
end
buff.target.Event:DispatchEvent(BattleEventName.BuffTrigger, buff)
end
elseif buff.frameInterval < 0 then
if buff.framePass > buff.frameDuration then
buff.disperse = true
end
else
if buff.frameInterval == 0 or buff.framePass % buff.frameInterval == 0 then
if not buff:OnTrigger() then
buff.disperse = true
end
buff.target.Event:DispatchEvent(BattleEventName.BuffTrigger, buff)
end
if buff.framePass > buff.frameDuration then
buff.disperse = true
end
end
end
if buff.disperse then
buff:OnEnd()
buff.target.Event:DispatchEvent(BattleEventName.BuffEnd, buff)
putBuff(buff)
buffList:Remove(index)
else
index = index + 1
end
end
end
end
end