Buff.lua 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. Buff = {}
  2. local floor = math.floor
  3. local buffPoolList = {}
  4. local getBuff = function(type)
  5. if not buffPoolList[type] then
  6. buffPoolList[type] = BattleObjectPool.New(function (type)
  7. return require("Modules/Battle/Logic/Buff/"..type):New()
  8. end)
  9. end
  10. return buffPoolList[type]:Get(type)
  11. end
  12. local putBuff = function(buff)
  13. if buffPoolList[buff.type] then
  14. buffPoolList[buff.type]:Put(buff)
  15. end
  16. end
  17. local buffListPool = BattleObjectPool.New(function ()
  18. return BattleList.New()
  19. end)
  20. function Buff:New()
  21. local o = {}
  22. setmetatable(o, self)
  23. self.__index = self
  24. return o
  25. end
  26. function Buff.Create(caster, type, duration, ...)
  27. local buff = getBuff(type)
  28. buff.type = type
  29. buff.id = BuffManager.GenerateBuffId()
  30. buff.caster = caster
  31. buff.disperse = false --该值为true时,buff在下一帧被清除
  32. buff.cover = false --该值为true时,同类型新buff会覆盖旧buff
  33. buff.clear = true --该值为false时,buff不可被驱散,除非无条件驱散
  34. buff.duration = duration or 0 --持续时间为0时buff永久存在
  35. buff.interval = -1 --间隔帧为0时每回合触发,小于0不触发 默认不触发OnTrigger
  36. buff.cdRound = -1 --冷却回合,-1为没有冷却回合
  37. buff.effectRound = -1 --生效回合,与冷却回合搭配使用
  38. buff.isEffect = false --是否生效
  39. buff.countRound = 0 --计算回合
  40. -- buff.framePass = 0
  41. buff.roundPass = 0
  42. buff.startRound = BattleLogic.GetCurRound()
  43. buff:SetData(...)
  44. return buff
  45. end
  46. -- 设置触发间隔
  47. function Buff:SetInterval(interval)
  48. self.interval = interval
  49. return self
  50. end
  51. -- 改变buff的轮次
  52. function Buff:ChangeBuffDuration(type, value)
  53. -- 永久存在改变无效
  54. if self.duration <= 0 then
  55. return
  56. end
  57. -- RoleManager.LogCa(
  58. -- "frame:"..BattleLogic.CurFrame(),
  59. -- "step1-buff-ca:"..type,
  60. -- "vale:",value
  61. -- "duration:",self.duration
  62. -- )
  63. -- 计算
  64. local finalDuration = BattleUtil.ErrorCorrection(BattleUtil.CountValue(self.duration, value, type))
  65. -- RoleManager.LogCa(
  66. -- "frame:"..BattleLogic.CurFrame(),
  67. -- "step2-buff-ca:"..type,
  68. -- "finalDuration:",finalDuration
  69. -- )
  70. self.duration = floor(finalDuration)
  71. -- RoleManager.LogCa(
  72. -- "frame:"..BattleLogic.CurFrame(),
  73. -- "step3-buff-ca:"..type,
  74. -- "finalDuration:",self.duration
  75. -- )
  76. if self.roundDuration then
  77. self.roundDuration = finalDuration
  78. end
  79. -- 发送事件
  80. self.caster.Event:DispatchEvent(BattleEventName.BuffDurationChange, self)
  81. end
  82. function Buff:CompareWith(buff)
  83. if self.type == buff.type then
  84. if self.OnCompare then
  85. return self:OnCompare(buff)
  86. else
  87. return true
  88. end
  89. else
  90. return false
  91. end
  92. end
  93. BuffManager = {}
  94. BuffManager.__index = BuffManager
  95. local curBuffId
  96. function BuffManager.New()
  97. local instance = {owner=0, buffQueue = BattleQueue.New(), buffDic = BattleDictionary.New()}
  98. setmetatable(instance, BuffManager)
  99. return instance
  100. end
  101. -- 根据类型获取buff的刷新级别
  102. -- local _TypeToLevel = {
  103. -- [] = ,
  104. -- }
  105. function BuffManager.GetLevelByType(type)
  106. end
  107. function BuffManager:Init()
  108. while self.buffQueue.size > 0 do
  109. putBuff(self.buffQueue:Dequeue())
  110. end
  111. for i = 1, self.buffDic.size do
  112. local list = self.buffDic.vList[i]
  113. for j=1, list.size do
  114. putBuff(list.buffer[j])
  115. end
  116. list:Clear()
  117. buffListPool:Put(list)
  118. end
  119. self.buffDic:Clear()
  120. curBuffId = 0
  121. end
  122. function BuffManager.GenerateBuffId()
  123. if not curBuffId then
  124. curBuffId = 0
  125. end
  126. curBuffId = curBuffId + 1
  127. return curBuffId
  128. end
  129. function BuffManager:AddBuff(target, buff)
  130. buff.target = target
  131. self.buffQueue:Enqueue(buff)
  132. -- buff.frameDuration = floor(buff.duration * BattleLogic.GameFrameRate)
  133. --if buff.isBuff then --TODO:增益buff持续时间加成
  134. -- local buffBocus = buff.caster:GetRoleData(RoleDataName.BuffBocus)
  135. -- buff.frameDuration = floor(buff.duration * (1 + buffBocus + buff.exCtrlTime) * BattleLogic.GameFrameRate)
  136. --end
  137. --
  138. --if buff.isDeBuff then --TODO:减益buff持续时间减免
  139. -- local debuffReduce = self.owner:GetRoleData(RoleDataName.DebuffReduce)
  140. -- buff.frameDuration = floor(buff.duration * (1 - debuffReduce - buff.exCtrlTime) * BattleLogic.GameFrameRate)
  141. --end
  142. -- buff.frameInterval = floor(buff.interval * BattleLogic.GameFrameRate)
  143. buff.roundDuration = buff.duration
  144. buff.roundInterval = buff.interval
  145. buff.caster.Event:DispatchEvent(BattleEventName.BuffCaster, buff)
  146. end
  147. function BuffManager:TestTempQuene(caster,target)
  148. BattleUtil.RandomControl(1, 1, caster, target, 10)
  149. BattleUtil.RandomControl(1, 2, caster, target, 10)
  150. BattleUtil.RandomControl(1, 3, caster, target, 10)
  151. BattleUtil.RandomControl(1, 4, caster, target, 10)
  152. target:AddBuff( Buff.Create(caster, BuffName.Brand, 0, "sign"))
  153. target:AddBuff( Buff.Create(caster, BuffName.Brand, 0, "sign"))
  154. target:AddBuff( Buff.Create(caster, BuffName.Brand, 0, "sign"))
  155. target:AddBuff( Buff.Create(caster, BuffName.Brand, 0, "sign"))
  156. BattleUtil.RandomControl(1, 5, caster, target, 10)
  157. BattleUtil.RandomControl(1, 6, caster, target, 10)
  158. BattleUtil.RandomControl(1, 7, caster, target, 10)
  159. BattleUtil.RandomControl(1, 8, caster, target, 10)
  160. BattleUtil.RandomControl(1, 9, caster, target, 10)
  161. BattleUtil.RandomControl(1, 10, caster, target, 10)
  162. -- local logbuff =function(buff)
  163. -- if buff.type == BuffName.Control then
  164. -- LogRed(string.format("buffid: %s bufftype: %s ctrl: %s",buff.id,buff.type,buff.ctrlType))
  165. -- else
  166. -- LogRed(string.format("buffid: %s bufftype: %s ",buff.id,buff.type))
  167. -- end
  168. -- end
  169. -- BattleLogic.BuffMgr:QueryTempQuene(logbuff)
  170. -- @@以下为案例
  171. local delete = function(buff)
  172. if buff.type == BuffName.Brand then
  173. return true
  174. end
  175. return false
  176. end
  177. BattleLogic.BuffMgr:RemoveBuffQueneBy(delete)
  178. BattleLogic.BuffMgr:QueryTempQuene(logbuff)
  179. end
  180. function BuffManager:RemoveAtBuffQuene(buff)
  181. -- LogError("RemoveAtBuffQuene!!!!!")
  182. self.buffQueue:DeleteObj(buff)
  183. end
  184. function BuffManager:RemoveBuffQueneBy(delete)
  185. -- LogError("DeleteTempQueneBy!!!!!")
  186. self.buffQueue:DeleteFunc(delete)
  187. end
  188. function BuffManager:QueryTempQuene(logbuff)
  189. -- LogError("QueryTempQuene!!!!!")
  190. -- @@以下为案例
  191. -- LogError(self.buffQueue:Count())
  192. self.buffQueue:Foreach(logbuff)
  193. end
  194. function BuffManager:RemoveBuff(target, checkFunc)
  195. for i=1, self.buffDic.size do
  196. local list = self.buffDic.vList[i]
  197. for j=1, list.size do
  198. local buff = list.buffer[j]
  199. if buff.target == target then
  200. if checkFunc then
  201. local result = checkFunc(buff)
  202. if result then
  203. buff.disperse = true
  204. end
  205. end
  206. end
  207. end
  208. end
  209. end
  210. function BuffManager:QueryBuff(target, checkFunc)
  211. for i=1, self.buffDic.size do
  212. local list = self.buffDic.vList[i]
  213. for j=1, list.size do
  214. local buff = list.buffer[j]
  215. if buff.target == target then
  216. if checkFunc then
  217. checkFunc(buff)
  218. end
  219. end
  220. end
  221. end
  222. end
  223. function BuffManager:GetBuff(target, checkFunc)
  224. local blist = {}
  225. for i=1, self.buffDic.size do
  226. local list = self.buffDic.vList[i]
  227. for j=1, list.size do
  228. local buff = list.buffer[j]
  229. if buff.target == target then
  230. if not checkFunc or checkFunc(buff)then
  231. table.insert(blist, buff)
  232. end
  233. end
  234. end
  235. end
  236. return blist
  237. end
  238. function BuffManager:HasBuff(target, type, checkFunc)
  239. if self.buffDic.kvList[type] then
  240. local buffList = self.buffDic.kvList[type]
  241. for i=1, buffList.size do
  242. local v = buffList.buffer[i]
  243. if v.target == target then
  244. if (not checkFunc or (checkFunc and checkFunc(v))) then
  245. return true
  246. end
  247. end
  248. end
  249. end
  250. return false
  251. end
  252. --func为nil时无条件清除,否则判定clear值,执行func
  253. function BuffManager:ClearBuff(target, func)
  254. for i = 1, self.buffDic.size do
  255. local list = self.buffDic.vList[i]
  256. if list.size > 0 then
  257. local idx = 1
  258. while idx <= list.size do
  259. local buff = list.buffer[idx]
  260. if buff.target == target and (not func or (func and buff.clear and func(buff))) then
  261. buff:OnEnd()
  262. buff.target.Event:DispatchEvent(BattleEventName.BuffEnd, buff)
  263. putBuff(buff)
  264. list:Remove(idx)
  265. else
  266. idx = idx + 1
  267. end
  268. end
  269. end
  270. end
  271. end
  272. function BuffManager:PutBuff(buff)
  273. putBuff(buff)
  274. end
  275. function BuffManager:GetBuffCount(type)
  276. if self.buffDic[type] then
  277. return self.buffDic[type].size
  278. end
  279. return 0
  280. end
  281. -- 每帧刷新
  282. function BuffManager:Update()
  283. -- 检测上一帧生成的buff,加入管理
  284. while self.buffQueue.size > 0 do
  285. local buff = self.buffQueue:Dequeue()
  286. local buffList
  287. if not self.buffDic.kvList[buff.type] then
  288. buffList = buffListPool:Get()
  289. self.buffDic:Add(buff.type, buffList)
  290. else
  291. buffList = self.buffDic.kvList[buff.type]
  292. end
  293. -- 是覆盖类型的buff且有老buff
  294. if buff.cover and buffList.size > 0 then
  295. local isCovered = false
  296. for i=1, buffList.size do
  297. local oldBuff = buffList.buffer[i]
  298. if oldBuff.cover and oldBuff.target == buff.target and oldBuff.clear == buff.clear and oldBuff:OnCover(buff) then --判定该效果能否被覆盖
  299. if buff.type == BuffName.Shield
  300. and buff.isValueCover
  301. and oldBuff.isValueCover
  302. and buff.shieldType == ShieldTypeName.NormalReduce
  303. and not oldBuff:OnCompareShielValue(buff)
  304. then
  305. isCovered = true
  306. break
  307. end
  308. -- 结束并回收老buff
  309. oldBuff:OnEnd()
  310. oldBuff.target.Event:DispatchEvent(BattleEventName.BuffEnd, oldBuff)
  311. putBuff(oldBuff)
  312. -- 覆盖老buff
  313. buffList.buffer[i] = buff
  314. buff:OnStart()
  315. buff.target.Event:DispatchEvent(BattleEventName.BuffStart, buff)
  316. buff.target.Event:DispatchEvent(BattleEventName.BuffCover, buff)
  317. isCovered = true
  318. break
  319. end
  320. end
  321. -- 没有覆盖,新buff
  322. if not isCovered then
  323. buffList:Add(buff)
  324. buff:OnStart()
  325. buff.target.Event:DispatchEvent(BattleEventName.BuffStart, buff)
  326. end
  327. else
  328. -- 新buff
  329. buffList:Add(buff)
  330. buff:OnStart()
  331. buff.target.Event:DispatchEvent(BattleEventName.BuffStart, buff)
  332. end
  333. end
  334. -- 清除过期buff
  335. for i=1, self.buffDic.size do
  336. local buffList = self.buffDic.vList[i]
  337. if buffList.size > 0 then
  338. local index = 1
  339. while index <= buffList.size do
  340. local buff = buffList.buffer[index]
  341. if buff.disperse then
  342. if (buff.cdRound > 0 and buff.isEffect) or (buff.cdRound < 0) then
  343. buff:OnEnd(true)
  344. buff.target.Event:DispatchEvent(BattleEventName.BuffEnd, buff)
  345. end
  346. putBuff(buff)
  347. buffList:Remove(index)
  348. else
  349. index = index + 1
  350. end
  351. end
  352. end
  353. end
  354. end
  355. -- 计算buff 剩余步数(根据当前回合人刷新其造成的所有buff回合数)
  356. function BuffManager:PassUpdate()
  357. local curCamp, curPos = BattleLogic.GetCurTurn()
  358. for i=1, self.buffDic.size do
  359. local buffList = self.buffDic.vList[i]
  360. if buffList.size > 0 then
  361. for index = 1, buffList.size do
  362. local buff = buffList.buffer[index]
  363. if not buff.disperse -- 没过期
  364. -- and buff.caster.camp == curCamp -- 释放者是当前轮到的人
  365. -- and buff.caster.position == curPos
  366. and buff.roundDuration > 0 -- 不是无限存在的buff
  367. then
  368. -- 当前轮释放的buff不结算
  369. if buff.startRound ~= BattleLogic.GetCurRound() then
  370. buff.roundPass = buff.roundPass + 1
  371. if buff.roundPass >= buff.roundDuration then
  372. buff.disperse = true
  373. end
  374. buff.target.Event:DispatchEvent(BattleEventName.BuffRoundChange, buff)
  375. end
  376. --零时单独处理
  377. if buff.type == BuffName.Brand and buff.flag == BrandType.curse then
  378. if (BattleLogic.GetCurRound() - buff.startRound) % buff.roundInterval == 0 then
  379. if buff.TriggerFunc then
  380. buff.TriggerFunc()
  381. end
  382. buff.target.Event:DispatchEvent(BattleEventName.BuffTrigger, buff)
  383. end
  384. end
  385. elseif not buff.disperse and buff.roundDuration == 0 and buff.cdRound > 0 then
  386. if buff.startRound ~= BattleLogic.GetCurRound() then
  387. buff.roundPass = buff.roundPass + 1
  388. end
  389. end
  390. end
  391. end
  392. end
  393. end
  394. -- 每一个人的轮次都刷新
  395. function BuffManager:TurnUpdate(sort)
  396. local curCamp, curPos = BattleLogic.GetCurTurn()
  397. for i=1, self.buffDic.size do
  398. local buffList = self.buffDic.vList[i]
  399. if buffList.size > 0 then
  400. for index = 1, buffList.size do
  401. local buff = buffList.buffer[index]
  402. if not buff.disperse -- 没有过期
  403. and buff.sort == sort -- 当前buff刷新等级
  404. -- and buff.target.camp == curCamp -- 当前阵营
  405. -- and buff.target.position == curPos -- 当前位置
  406. then
  407. --触发buff
  408. if buff.roundInterval >= 0 then
  409. if buff.roundInterval == 0 or buff.roundPass % buff.roundInterval == 0 then
  410. if not buff:OnTrigger() then
  411. buff.disperse = true
  412. end
  413. buff.target.Event:DispatchEvent(BattleEventName.BuffTrigger, buff)
  414. end
  415. end
  416. --冷却和重新触发buff(目前支持被动技能buff开始回合从0开始)
  417. if buff.cdRound > 0 and not buff.disperse then
  418. if buff.isEffect then
  419. if buff.countRound == buff.effectRound then
  420. buff:OnEnd()
  421. buff.target.Event:DispatchEvent(BattleEventName.BuffEnd, buff)
  422. buff.countRound = 0
  423. buff.isEffect = not buff.isEffect
  424. end
  425. elseif not buff.isEffect then
  426. if buff.countRound == buff.cdRound then
  427. buff:OnTrigger()
  428. buff.target.Event:DispatchEvent(BattleEventName.BuffStart, buff)
  429. buff.countRound = 0
  430. buff.isEffect = not buff.isEffect
  431. end
  432. end
  433. buff.countRound = buff.countRound + 1
  434. end
  435. end
  436. end
  437. end
  438. end
  439. end