Buff.lua 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  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.framePass = 0
  37. buff.roundPass = 0
  38. buff.startRound = BattleLogic.GetCurRound()
  39. buff:SetData(...)
  40. return buff
  41. end
  42. -- 设置触发间隔
  43. function Buff:SetInterval(interval)
  44. self.interval = interval
  45. return self
  46. end
  47. -- 改变buff的轮次
  48. function Buff:ChangeBuffDuration(type, value)
  49. -- 永久存在改变无效
  50. if self.duration <= 0 then
  51. return
  52. end
  53. -- 计算
  54. local finalDuration = BattleUtil.ErrorCorrection(BattleUtil.CountValue(self.duration, value, type))
  55. self.duration = floor(finalDuration)
  56. if self.roundDuration then
  57. self.roundDuration = finalDuration
  58. end
  59. -- 发送事件
  60. self.caster.Event:DispatchEvent(BattleEventName.BuffDurationChange, self)
  61. end
  62. function Buff:CompareWith(buff)
  63. if self.type == buff.type then
  64. if self.OnCompare then
  65. return self:OnCompare(buff)
  66. else
  67. return true
  68. end
  69. else
  70. return false
  71. end
  72. end
  73. BuffManager = {}
  74. BuffManager.__index = BuffManager
  75. local curBuffId
  76. function BuffManager.New()
  77. local instance = {owner=0, buffQueue = BattleQueue.New(), buffDic = BattleDictionary.New()}
  78. setmetatable(instance, BuffManager)
  79. return instance
  80. end
  81. -- 根据类型获取buff的刷新级别
  82. -- local _TypeToLevel = {
  83. -- [] = ,
  84. -- }
  85. function BuffManager.GetLevelByType(type)
  86. end
  87. function BuffManager:Init()
  88. while self.buffQueue.size > 0 do
  89. putBuff(self.buffQueue:Dequeue())
  90. end
  91. for i = 1, self.buffDic.size do
  92. local list = self.buffDic.vList[i]
  93. for j=1, list.size do
  94. putBuff(list.buffer[j])
  95. end
  96. list:Clear()
  97. buffListPool:Put(list)
  98. end
  99. self.buffDic:Clear()
  100. curBuffId = 0
  101. end
  102. function BuffManager.GenerateBuffId()
  103. if not curBuffId then
  104. curBuffId = 0
  105. end
  106. curBuffId = curBuffId + 1
  107. return curBuffId
  108. end
  109. function BuffManager:AddBuff(target, buff)
  110. buff.target = target
  111. self.buffQueue:Enqueue(buff)
  112. -- buff.frameDuration = floor(buff.duration * BattleLogic.GameFrameRate)
  113. --if buff.isBuff then --TODO:增益buff持续时间加成
  114. -- local buffBocus = buff.caster:GetRoleData(RoleDataName.BuffBocus)
  115. -- buff.frameDuration = floor(buff.duration * (1 + buffBocus + buff.exCtrlTime) * BattleLogic.GameFrameRate)
  116. --end
  117. --
  118. --if buff.isDeBuff then --TODO:减益buff持续时间减免
  119. -- local debuffReduce = self.owner:GetRoleData(RoleDataName.DebuffReduce)
  120. -- buff.frameDuration = floor(buff.duration * (1 - debuffReduce - buff.exCtrlTime) * BattleLogic.GameFrameRate)
  121. --end
  122. -- buff.frameInterval = floor(buff.interval * BattleLogic.GameFrameRate)
  123. buff.roundDuration = buff.duration
  124. buff.roundInterval = buff.interval
  125. buff.caster.Event:DispatchEvent(BattleEventName.BuffCaster, buff)
  126. end
  127. function BuffManager:QueryBuff(target, checkFunc)
  128. for i=1, self.buffDic.size do
  129. local list = self.buffDic.vList[i]
  130. for j=1, list.size do
  131. local buff = list.buffer[j]
  132. if buff.target == target then
  133. if checkFunc then
  134. checkFunc(buff)
  135. end
  136. end
  137. end
  138. end
  139. end
  140. function BuffManager:GetBuff(target, checkFunc)
  141. local blist = {}
  142. for i=1, self.buffDic.size do
  143. local list = self.buffDic.vList[i]
  144. for j=1, list.size do
  145. local buff = list.buffer[j]
  146. if buff.target == target then
  147. if not checkFunc or checkFunc(buff)then
  148. table.insert(blist, buff)
  149. end
  150. end
  151. end
  152. end
  153. return blist
  154. end
  155. function BuffManager:HasBuff(target, type, checkFunc)
  156. if self.buffDic.kvList[type] then
  157. local buffList = self.buffDic.kvList[type]
  158. for i=1, buffList.size do
  159. local v = buffList.buffer[i]
  160. if v.target == target then
  161. if (not checkFunc or (checkFunc and checkFunc(v))) then
  162. return true
  163. end
  164. end
  165. end
  166. end
  167. return false
  168. end
  169. --func为nil时无条件清除,否则判定clear值,执行func
  170. function BuffManager:ClearBuff(target, func)
  171. for i = 1, self.buffDic.size do
  172. local list = self.buffDic.vList[i]
  173. if list.size > 0 then
  174. local idx = 1
  175. while idx <= list.size do
  176. local buff = list.buffer[idx]
  177. if buff.target == target and (not func or (func and buff.clear and func(buff))) then
  178. buff:OnEnd()
  179. buff.target.Event:DispatchEvent(BattleEventName.BuffEnd, buff)
  180. putBuff(buff)
  181. list:Remove(idx)
  182. else
  183. idx = idx + 1
  184. end
  185. end
  186. end
  187. end
  188. end
  189. function BuffManager:PutBuff(buff)
  190. putBuff(buff)
  191. end
  192. function BuffManager:GetBuffCount(type)
  193. if self.buffDic[type] then
  194. return self.buffDic[type].size
  195. end
  196. return 0
  197. end
  198. -- 每帧刷新
  199. function BuffManager:Update()
  200. -- 检测上一帧生成的buff,加入管理
  201. while self.buffQueue.size > 0 do
  202. local buff = self.buffQueue:Dequeue()
  203. local buffList
  204. if not self.buffDic.kvList[buff.type] then
  205. buffList = buffListPool:Get()
  206. self.buffDic:Add(buff.type, buffList)
  207. else
  208. buffList = self.buffDic.kvList[buff.type]
  209. end
  210. -- 是覆盖类型的buff且有老buff
  211. if buff.cover and buffList.size > 0 then
  212. local isCovered = false
  213. for i=1, buffList.size do
  214. local oldBuff = buffList.buffer[i]
  215. if oldBuff.cover and oldBuff.target == buff.target and oldBuff.clear == buff.clear and oldBuff:OnCover(buff) then --判定该效果能否被覆盖
  216. -- 结束并回收老buff
  217. oldBuff:OnEnd()
  218. oldBuff.target.Event:DispatchEvent(BattleEventName.BuffEnd, oldBuff)
  219. putBuff(oldBuff)
  220. -- 覆盖老buff
  221. buffList.buffer[i] = buff
  222. buff:OnStart()
  223. buff.target.Event:DispatchEvent(BattleEventName.BuffStart, buff)
  224. buff.target.Event:DispatchEvent(BattleEventName.BuffCover, buff)
  225. isCovered = true
  226. break
  227. end
  228. end
  229. -- 没有覆盖,新buff
  230. if not isCovered then
  231. buffList:Add(buff)
  232. buff:OnStart()
  233. buff.target.Event:DispatchEvent(BattleEventName.BuffStart, buff)
  234. end
  235. else
  236. -- 新buff
  237. buffList:Add(buff)
  238. buff:OnStart()
  239. buff.target.Event:DispatchEvent(BattleEventName.BuffStart, buff)
  240. end
  241. end
  242. -- 清除过期buff
  243. for i=1, self.buffDic.size do
  244. local buffList = self.buffDic.vList[i]
  245. if buffList.size > 0 then
  246. local index = 1
  247. while index <= buffList.size do
  248. local buff = buffList.buffer[index]
  249. if buff.disperse then
  250. buff:OnEnd()
  251. buff.target.Event:DispatchEvent(BattleEventName.BuffEnd, buff)
  252. putBuff(buff)
  253. buffList:Remove(index)
  254. else
  255. index = index + 1
  256. end
  257. end
  258. end
  259. end
  260. end
  261. -- 计算buff 剩余步数(根据当前回合人刷新其造成的所有buff回合数)
  262. function BuffManager:PassUpdate()
  263. local curCamp, curPos = BattleLogic.GetCurTurn()
  264. for i=1, self.buffDic.size do
  265. local buffList = self.buffDic.vList[i]
  266. if buffList.size > 0 then
  267. for index = 1, buffList.size do
  268. local buff = buffList.buffer[index]
  269. if not buff.disperse -- 没过期
  270. -- and buff.caster.camp == curCamp -- 释放者是当前轮到的人
  271. -- and buff.caster.position == curPos
  272. and buff.roundDuration > 0 -- 不是无限存在的buff
  273. then
  274. -- 当前轮释放的buff不结算
  275. if buff.startRound ~= BattleLogic.GetCurRound() then
  276. buff.roundPass = buff.roundPass + 1
  277. if buff.roundPass >= buff.roundDuration then
  278. buff.disperse = true
  279. end
  280. buff.target.Event:DispatchEvent(BattleEventName.BuffRoundChange, buff)
  281. end
  282. end
  283. end
  284. end
  285. end
  286. end
  287. -- 每一个人的轮次都刷新
  288. function BuffManager:TurnUpdate(sort)
  289. local curCamp, curPos = BattleLogic.GetCurTurn()
  290. for i=1, self.buffDic.size do
  291. local buffList = self.buffDic.vList[i]
  292. if buffList.size > 0 then
  293. for index = 1, buffList.size do
  294. local buff = buffList.buffer[index]
  295. if not buff.disperse -- 没有过期
  296. and buff.sort == sort -- 当前buff刷新等级
  297. -- and buff.target.camp == curCamp -- 当前阵营
  298. -- and buff.target.position == curPos -- 当前位置
  299. then
  300. --触发buff
  301. if buff.roundInterval >= 0 then
  302. if buff.roundInterval == 0 or buff.roundPass % buff.roundInterval == 0 then
  303. if not buff:OnTrigger() then
  304. buff.disperse = true
  305. end
  306. buff.target.Event:DispatchEvent(BattleEventName.BuffTrigger, buff)
  307. end
  308. end
  309. end
  310. end
  311. end
  312. end
  313. end