| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494 |
- 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 = BuffManager.GenerateBuffId()
- buff.caster = caster
- buff.disperse = false --该值为true时,buff在下一帧被清除
- buff.cover = false --该值为true时,同类型新buff会覆盖旧buff
- buff.clear = true --该值为false时,buff不可被驱散,除非无条件驱散
- buff.duration = duration or 0 --持续时间为0时buff永久存在
- buff.interval = -1 --间隔帧为0时每回合触发,小于0不触发 默认不触发OnTrigger
- buff.cdRound = -1 --冷却回合,-1为没有冷却回合
- buff.effectRound = -1 --生效回合,与冷却回合搭配使用
- buff.isEffect = false --是否生效
- buff.countRound = 0 --计算回合
- -- buff.framePass = 0
- buff.roundPass = 0
- buff.startRound = BattleLogic.GetCurRound()
- buff:SetData(...)
- return buff
- end
- -- 设置触发间隔
- function Buff:SetInterval(interval)
- self.interval = interval
- return self
- end
- -- 改变buff的轮次
- function Buff:ChangeBuffDuration(type, value)
- -- 永久存在改变无效
- if self.duration <= 0 then
- return
- end
- -- RoleManager.LogCa(
- -- "frame:"..BattleLogic.CurFrame(),
- -- "step1-buff-ca:"..type,
- -- "vale:",value
- -- "duration:",self.duration
- -- )
- -- 计算
- local finalDuration = BattleUtil.ErrorCorrection(BattleUtil.CountValue(self.duration, value, type))
- -- RoleManager.LogCa(
- -- "frame:"..BattleLogic.CurFrame(),
- -- "step2-buff-ca:"..type,
- -- "finalDuration:",finalDuration
- -- )
- self.duration = floor(finalDuration)
- -- RoleManager.LogCa(
- -- "frame:"..BattleLogic.CurFrame(),
- -- "step3-buff-ca:"..type,
- -- "finalDuration:",self.duration
- -- )
- if self.roundDuration then
- self.roundDuration = finalDuration
- end
- -- 发送事件
- self.caster.Event:DispatchEvent(BattleEventName.BuffDurationChange, self)
- end
- function Buff:CompareWith(buff)
- if self.type == buff.type then
- if self.OnCompare then
- return self:OnCompare(buff)
- else
- return true
- end
- else
- return false
- end
- end
- BuffManager = {}
- BuffManager.__index = BuffManager
- local curBuffId
- function BuffManager.New()
- local instance = {owner=0, buffQueue = BattleQueue.New(), buffDic = BattleDictionary.New()}
- setmetatable(instance, BuffManager)
- return instance
- end
- -- 根据类型获取buff的刷新级别
- -- local _TypeToLevel = {
- -- [] = ,
- -- }
- function BuffManager.GetLevelByType(type)
-
- end
- function BuffManager:Init()
- while self.buffQueue.size > 0 do
- putBuff(self.buffQueue:Dequeue())
- end
- for i = 1, self.buffDic.size do
- local list = self.buffDic.vList[i]
- for j=1, list.size do
- putBuff(list.buffer[j])
- end
- list:Clear()
- buffListPool:Put(list)
- end
- self.buffDic:Clear()
- curBuffId = 0
- end
- function BuffManager.GenerateBuffId()
- if not curBuffId then
- curBuffId = 0
- end
- curBuffId = curBuffId + 1
- return curBuffId
- end
- function BuffManager:AddBuff(target, buff)
- buff.target = target
- self.buffQueue:Enqueue(buff)
- -- buff.frameDuration = floor(buff.duration * 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.roundDuration = buff.duration
- buff.roundInterval = buff.interval
- buff.caster.Event:DispatchEvent(BattleEventName.BuffCaster, buff)
- end
- function BuffManager:TestTempQuene(caster,target)
- BattleUtil.RandomControl(1, 1, caster, target, 10)
- BattleUtil.RandomControl(1, 2, caster, target, 10)
- BattleUtil.RandomControl(1, 3, caster, target, 10)
- BattleUtil.RandomControl(1, 4, caster, target, 10)
- target:AddBuff( Buff.Create(caster, BuffName.Brand, 0, "sign"))
- target:AddBuff( Buff.Create(caster, BuffName.Brand, 0, "sign"))
- target:AddBuff( Buff.Create(caster, BuffName.Brand, 0, "sign"))
- target:AddBuff( Buff.Create(caster, BuffName.Brand, 0, "sign"))
- BattleUtil.RandomControl(1, 5, caster, target, 10)
- BattleUtil.RandomControl(1, 6, caster, target, 10)
- BattleUtil.RandomControl(1, 7, caster, target, 10)
- BattleUtil.RandomControl(1, 8, caster, target, 10)
- BattleUtil.RandomControl(1, 9, caster, target, 10)
- BattleUtil.RandomControl(1, 10, caster, target, 10)
- -- local logbuff =function(buff)
- -- if buff.type == BuffName.Control then
- -- LogRed(string.format("buffid: %s bufftype: %s ctrl: %s",buff.id,buff.type,buff.ctrlType))
- -- else
- -- LogRed(string.format("buffid: %s bufftype: %s ",buff.id,buff.type))
- -- end
- -- end
- -- BattleLogic.BuffMgr:QueryTempQuene(logbuff)
- -- @@以下为案例
- local delete = function(buff)
- if buff.type == BuffName.Brand then
- return true
- end
- return false
- end
- BattleLogic.BuffMgr:RemoveBuffQueneBy(delete)
- BattleLogic.BuffMgr:QueryTempQuene(logbuff)
- end
- function BuffManager:RemoveAtBuffQuene(buff)
- -- LogError("RemoveAtBuffQuene!!!!!")
- self.buffQueue:DeleteObj(buff)
- end
- function BuffManager:RemoveBuffQueneBy(delete)
- -- LogError("DeleteTempQueneBy!!!!!")
- self.buffQueue:DeleteFunc(delete)
- end
- function BuffManager:QueryTempQuene(logbuff)
- -- LogError("QueryTempQuene!!!!!")
- -- @@以下为案例
- -- LogError(self.buffQueue:Count())
- self.buffQueue:Foreach(logbuff)
- end
- function BuffManager:RemoveBuff(target, checkFunc)
- for i=1, self.buffDic.size do
- local list = self.buffDic.vList[i]
- for j=1, list.size do
- local buff = list.buffer[j]
- if buff.target == target then
- if checkFunc then
- local result = checkFunc(buff)
- if result then
- buff.disperse = true
- end
- end
- end
- end
- end
- end
- function BuffManager:QueryBuff(target, checkFunc)
- for i=1, self.buffDic.size do
- local list = self.buffDic.vList[i]
- for j=1, list.size do
- local buff = list.buffer[j]
- if buff.target == target then
- if checkFunc then
- checkFunc(buff)
- end
- end
- end
- end
- end
- function BuffManager:GetBuff(target, checkFunc)
- local blist = {}
- for i=1, self.buffDic.size do
- local list = self.buffDic.vList[i]
- for j=1, list.size do
- local buff = list.buffer[j]
- if buff.target == target then
- if not checkFunc or checkFunc(buff)then
- table.insert(blist, buff)
- end
- end
- end
- end
- return blist
- end
- function BuffManager:HasBuff(target, type, checkFunc)
- if self.buffDic.kvList[type] then
- local buffList = self.buffDic.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
- --func为nil时无条件清除,否则判定clear值,执行func
- function BuffManager:ClearBuff(target, func)
- for i = 1, self.buffDic.size do
- local list = self.buffDic.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 buff.clear 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:PutBuff(buff)
- putBuff(buff)
- end
- function BuffManager:GetBuffCount(type)
- if self.buffDic[type] then
- return self.buffDic[type].size
- end
- return 0
- end
- -- 每帧刷新
- function BuffManager:Update()
- -- 检测上一帧生成的buff,加入管理
- while self.buffQueue.size > 0 do
- local buff = self.buffQueue:Dequeue()
- local buffList
- if not self.buffDic.kvList[buff.type] then
- buffList = buffListPool:Get()
- self.buffDic:Add(buff.type, buffList)
- else
- buffList = self.buffDic.kvList[buff.type]
- end
- -- 是覆盖类型的buff且有老buff
- 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.clear == buff.clear and oldBuff:OnCover(buff) then --判定该效果能否被覆盖
- if buff.type == BuffName.Shield
- and buff.isValueCover
- and oldBuff.isValueCover
- and buff.shieldType == ShieldTypeName.NormalReduce
- and not oldBuff:OnCompareShielValue(buff)
- then
- isCovered = true
- break
- end
- -- 结束并回收老buff
- oldBuff:OnEnd()
- oldBuff.target.Event:DispatchEvent(BattleEventName.BuffEnd, oldBuff)
- putBuff(oldBuff)
- -- 覆盖老buff
- 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
- -- 没有覆盖,新buff
- if not isCovered then
- buffList:Add(buff)
- buff:OnStart()
- buff.target.Event:DispatchEvent(BattleEventName.BuffStart, buff)
- end
- else
- -- 新buff
- buffList:Add(buff)
- buff:OnStart()
- buff.target.Event:DispatchEvent(BattleEventName.BuffStart, buff)
- end
- end
- -- 清除过期buff
- for i=1, self.buffDic.size do
- local buffList = self.buffDic.vList[i]
- if buffList.size > 0 then
- local index = 1
- while index <= buffList.size do
- local buff = buffList.buffer[index]
- if buff.disperse then
- if (buff.cdRound > 0 and buff.isEffect) or (buff.cdRound < 0) then
- buff:OnEnd(true)
- buff.target.Event:DispatchEvent(BattleEventName.BuffEnd, buff)
- end
-
- putBuff(buff)
- buffList:Remove(index)
- else
- index = index + 1
- end
- end
- end
- end
- end
- -- 计算buff 剩余步数(根据当前回合人刷新其造成的所有buff回合数)
- function BuffManager:PassUpdate()
- local curCamp, curPos = BattleLogic.GetCurTurn()
- for i=1, self.buffDic.size do
- local buffList = self.buffDic.vList[i]
- if buffList.size > 0 then
- for index = 1, buffList.size do
- local buff = buffList.buffer[index]
- if not buff.disperse -- 没过期
- -- and buff.caster.camp == curCamp -- 释放者是当前轮到的人
- -- and buff.caster.position == curPos
- and buff.roundDuration > 0 -- 不是无限存在的buff
- then
- -- 当前轮释放的buff不结算
- if buff.startRound ~= BattleLogic.GetCurRound() then
- buff.roundPass = buff.roundPass + 1
- if buff.roundPass >= buff.roundDuration then
- buff.disperse = true
- end
- buff.target.Event:DispatchEvent(BattleEventName.BuffRoundChange, buff)
- end
-
- --零时单独处理
- if buff.type == BuffName.Brand and buff.flag == BrandType.curse then
- if (BattleLogic.GetCurRound() - buff.startRound) % buff.roundInterval == 0 then
- if buff.TriggerFunc then
- buff.TriggerFunc()
- end
- buff.target.Event:DispatchEvent(BattleEventName.BuffTrigger, buff)
- end
- end
- elseif not buff.disperse and buff.roundDuration == 0 and buff.cdRound > 0 then
- if buff.startRound ~= BattleLogic.GetCurRound() then
- buff.roundPass = buff.roundPass + 1
- end
-
- end
- end
- end
- end
- end
- -- 每一个人的轮次都刷新
- function BuffManager:TurnUpdate(sort)
- local curCamp, curPos = BattleLogic.GetCurTurn()
- for i=1, self.buffDic.size do
- local buffList = self.buffDic.vList[i]
- if buffList.size > 0 then
- for index = 1, buffList.size do
- local buff = buffList.buffer[index]
- if not buff.disperse -- 没有过期
- and buff.sort == sort -- 当前buff刷新等级
- -- and buff.target.camp == curCamp -- 当前阵营
- -- and buff.target.position == curPos -- 当前位置
- then
- --触发buff
- if buff.roundInterval >= 0 then
- if buff.roundInterval == 0 or buff.roundPass % buff.roundInterval == 0 then
- if not buff:OnTrigger() then
- buff.disperse = true
- end
- buff.target.Event:DispatchEvent(BattleEventName.BuffTrigger, buff)
- end
- end
- --冷却和重新触发buff(目前支持被动技能buff开始回合从0开始)
- if buff.cdRound > 0 and not buff.disperse then
- if buff.isEffect then
- if buff.countRound == buff.effectRound then
- buff:OnEnd()
- buff.target.Event:DispatchEvent(BattleEventName.BuffEnd, buff)
- buff.countRound = 0
- buff.isEffect = not buff.isEffect
- end
- elseif not buff.isEffect then
- if buff.countRound == buff.cdRound then
- buff:OnTrigger()
- buff.target.Event:DispatchEvent(BattleEventName.BuffStart, buff)
- buff.countRound = 0
- buff.isEffect = not buff.isEffect
- end
- end
- buff.countRound = buff.countRound + 1
- end
- end
- end
- end
- end
- end
|