196 lines
6.7 KiB
Lua
196 lines
6.7 KiB
Lua
|
Buff = {}
|
|||
|
|
|||
|
local floor = math.floor
|
|||
|
function Buff:New()
|
|||
|
local o = {}
|
|||
|
setmetatable(o, self)
|
|||
|
self.__index = self
|
|||
|
return o
|
|||
|
end
|
|||
|
|
|||
|
function Buff.Create(caster, type, duration, ...)
|
|||
|
local instance = require("Modules/Battle/Logic/Buff/"..type):New()
|
|||
|
|
|||
|
instance.type = type
|
|||
|
instance.id = BattleLogic.GenerateBuffId()
|
|||
|
instance.caster = caster
|
|||
|
instance.disperse = false
|
|||
|
instance.cover = false
|
|||
|
|
|||
|
instance.duration = duration --持续时间为0时buff永久存在
|
|||
|
instance.interval = -1 --间隔帧为0时每帧触发,小于0不触发 默认不触发OnTrigger
|
|||
|
instance.maxCount = 0 --限定效果最大数量
|
|||
|
instance.framePass = 0
|
|||
|
|
|||
|
instance:SetData(...)
|
|||
|
return instance
|
|||
|
end
|
|||
|
|
|||
|
BuffManager = {}
|
|||
|
BuffManager.__index = BuffManager
|
|||
|
|
|||
|
function BuffManager.New(owner)
|
|||
|
local instance = {}
|
|||
|
instance.owner = owner
|
|||
|
instance.buffQueue = BattleQueue.New()
|
|||
|
instance.buffList = BattleDictionary.New()
|
|||
|
|
|||
|
setmetatable(instance, BuffManager)
|
|||
|
|
|||
|
return instance
|
|||
|
end
|
|||
|
|
|||
|
function BuffManager:AddBuff(buff)
|
|||
|
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)
|
|||
|
end
|
|||
|
|
|||
|
function BuffManager:HasBuff(type, checkFunc)
|
|||
|
local v
|
|||
|
for i=1, self.buffList:Count() do
|
|||
|
v = self.buffList.vList[i]
|
|||
|
if #v > 0 then
|
|||
|
if v[1].type == type and (not checkFunc or (checkFunc and checkFunc(v[1]))) then
|
|||
|
return true
|
|||
|
end
|
|||
|
end
|
|||
|
end
|
|||
|
return false
|
|||
|
end
|
|||
|
|
|||
|
function BuffManager:ClearBuff(func)
|
|||
|
for i = 1, self.buffList.size do
|
|||
|
local k = self.buffList.kList[i]
|
|||
|
local v = self.buffList.vList[i]
|
|||
|
local count = #v
|
|||
|
if count > 0 then
|
|||
|
local removeCount = 0
|
|||
|
local idx = 1
|
|||
|
while idx <= count do
|
|||
|
if func(v[idx]) then
|
|||
|
table.remove(v, idx)
|
|||
|
count = count - 1
|
|||
|
removeCount = removeCount + 1
|
|||
|
else
|
|||
|
idx = idx + 1
|
|||
|
end
|
|||
|
end
|
|||
|
if removeCount > 0 then
|
|||
|
self.owner.Event:DispatchEvent(BattleEventName.BuffCountChange, k, count)
|
|||
|
end
|
|||
|
end
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
function BuffManager:GetBuffCount(id)
|
|||
|
if self.buffList[id] then
|
|||
|
return self.buffList[id]:Count()
|
|||
|
end
|
|||
|
return 0
|
|||
|
end
|
|||
|
|
|||
|
function BuffManager:Update()
|
|||
|
for i=1, self.buffQueue.size do
|
|||
|
local buff = self.buffQueue:Dequeue()
|
|||
|
if not buff.caster then
|
|||
|
--logErrorTrace("buff's caster can't be nil!")
|
|||
|
return
|
|||
|
end
|
|||
|
local buffList
|
|||
|
if not self.buffList.kvList[buff.id] then
|
|||
|
buffList = {}
|
|||
|
self.buffList:Add(buff.id, buffList)
|
|||
|
else
|
|||
|
buffList = self.buffList.kvList[buff.id]
|
|||
|
end
|
|||
|
local count = #buffList
|
|||
|
if buff.cover and count > 0 then
|
|||
|
if buffList[1]:OnCover(buff) then --判定该效果能否被覆盖
|
|||
|
buffList[1]:OnEnd(self.owner)
|
|||
|
self.owner.Event:DispatchEvent(BattleEventName.BuffEnd, buffList[1])
|
|||
|
buffList[1] = buff
|
|||
|
buff.target = self.owner
|
|||
|
buff:OnStart()
|
|||
|
self.owner.Event:DispatchEvent(BattleEventName.BuffStart, buff)
|
|||
|
self.owner.Event:DispatchEvent(BattleEventName.BuffCover, buff)
|
|||
|
end
|
|||
|
else
|
|||
|
if buff.maxCount == 0 or count < buff.maxCount then --限制相同效果的数量,为0则不限制
|
|||
|
count = count + 1
|
|||
|
buffList[count] = buff
|
|||
|
buff.target = self.owner
|
|||
|
buff:OnStart()
|
|||
|
self.owner.Event:DispatchEvent(BattleEventName.BuffStart, buff)
|
|||
|
self.owner.Event:DispatchEvent(BattleEventName.BuffCountChange, buff.id, count)
|
|||
|
end
|
|||
|
end
|
|||
|
end
|
|||
|
for i = 1, self.buffList.size do
|
|||
|
local k = self.buffList.kList[i]
|
|||
|
local v = self.buffList.vList[i]
|
|||
|
local count = #v
|
|||
|
if count > 0 then
|
|||
|
local removeCount = 0
|
|||
|
local idx = 1
|
|||
|
local buff
|
|||
|
while idx <= count do
|
|||
|
buff = v[idx]
|
|||
|
--印记类型的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)
|
|||
|
table.remove(v, idx)
|
|||
|
count = count - 1
|
|||
|
removeCount = removeCount + 1
|
|||
|
else
|
|||
|
idx = idx + 1
|
|||
|
end
|
|||
|
end
|
|||
|
if removeCount > 0 then
|
|||
|
self.owner.Event:DispatchEvent(BattleEventName.BuffCountChange, k, count)
|
|||
|
end
|
|||
|
end
|
|||
|
end
|
|||
|
end
|