AnniversaryVoucherWheel.lua 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. -- 周年活动 - 代金转转乐
  2. -- db
  3. --[=[
  4. human.db.absAct[ACT_ID] = {
  5. lotteryTimes = 0, -- 可用抽奖次数(每累充100元+1,可叠加,活动结束清空)
  6. totalRecharge = 0, -- 活动期间累充总额(跨天持续累加)
  7. processedDaily = 0, -- 本日已从 topupAcountDaily 处理过的金额,跨天由 updateDaily 清零
  8. }
  9. ]=]--
  10. local Msg = require("core.Msg")
  11. local Grid = require("bag.Grid")
  12. local BagLogic = require("bag.BagLogic")
  13. local AbsActLogic = require("absAct.AbsActLogic")
  14. local Broadcast = require("broadcast.Broadcast")
  15. local Lang = require("common.Lang")
  16. local YunYingLogic = require("yunying.YunYingLogic")
  17. local AbsActExcel = require("excel.absAct")
  18. local RewardCfg = require("excel.anniversaryAct").voucherWheel
  19. local variablesCfg = require("excel.anniversaryAct").var
  20. local LOGTYPE = "AnniversaryVoucherWheel"
  21. local ACT_ID = 7702
  22. local function getData(human)
  23. return human.db.absAct[ACT_ID]
  24. end
  25. local function addTimes(human, val)
  26. local d = getData(human)
  27. d.lotteryTimes = (d.lotteryTimes or 0) + val
  28. end
  29. local function isOpenAct(human, funcID)
  30. return AbsActLogic.isStarted(human, funcID or ACT_ID)
  31. end
  32. -- 每累充x, 获得1次机会
  33. local function getRechargeUnit()
  34. local cfg = variablesCfg[1]
  35. return cfg.rechargeUnit
  36. end
  37. local function updateRedDot(human)
  38. YunYingLogic.sendBanner(human)
  39. local config = AbsActExcel.absActivity[ACT_ID]
  40. YunYingLogic.sendGroupUpdate(YYInfo[ACT_ID], human, config.panelID)
  41. end
  42. local function doLottery()
  43. local totalWeight = 0
  44. for _, row in ipairs(RewardCfg) do
  45. totalWeight = totalWeight + row.nWeight
  46. end
  47. if totalWeight <= 0 then return 0 end
  48. local r, acc = math.random(1, totalWeight), 0
  49. for i, row in ipairs(RewardCfg) do
  50. acc = acc + row.nWeight
  51. if r <= acc then return i end
  52. end
  53. return 0
  54. end
  55. local function doMultiLottery(count)
  56. local results = {}
  57. for _ = 1, count do
  58. local idx = doLottery()
  59. if idx == 0 then return nil end
  60. local row = RewardCfg[idx]
  61. results[#results + 1] = { itemId = row.reward[1], itemNum = row.reward[2] }
  62. end
  63. return results
  64. end
  65. -- config 为第一参数(框架固定传入),human 为新增第二参数
  66. function genAbsActData(config, human)
  67. local initRecharge = (human and human.db.topupAcountDaily) or 0
  68. local rechargeUnit = getRechargeUnit()
  69. local initTimes = math.floor(initRecharge / rechargeUnit)
  70. return {
  71. lotteryTimes = initTimes, -- 活动开启前当天已充的次数直接算入
  72. totalRecharge = initRecharge, -- 以当天已充金额为起点
  73. processedDaily = initRecharge, -- 标记已处理到此刻,避免 onCharge 重复计算
  74. }
  75. end
  76. -- 跨天回调(玩家在线或上线时由框架调用一次)
  77. -- topupAcountDaily 已跨天清零,同步重置 processedDaily,确保 onCharge 计算正确
  78. function updateDaily(human, funcID)
  79. if not isOpenAct(human, funcID) then return end
  80. local d = getData(human)
  81. if not d then return end
  82. d.processedDaily = 0
  83. end
  84. function isRed(human, YYInfo, funcConfig)
  85. if not isOpenAct(human, funcConfig and funcConfig.funcID) then return false end
  86. local d = getData(human)
  87. if not d then return false end
  88. return (d.lotteryTimes or 0) > 0
  89. end
  90. function isOpen(human, YYInfo, funcConfig)
  91. return isOpenAct(human, funcConfig and funcConfig.funcID)
  92. end
  93. function isActive(human, YYInfo, funcConfig)
  94. return not isOpen(human, YYInfo, funcConfig)
  95. end
  96. -- 充值回调
  97. -- 框架在充值成功并更新 topupAcountDaily 后自动调用
  98. -- 活动开启当天0点起计算,活动开启前当天的充值因 processedDaily=0 会在首次触发时自动补算
  99. function onCharge(human, price, funcID, buyID, buyNum)
  100. if not isOpenAct(human) then return end
  101. local d = getData(human)
  102. local dailyTotal = human.db.topupAcountDaily -- 今日0点起累计(已含本次充值)
  103. local processed = d.processedDaily or 0
  104. local delta = dailyTotal - processed
  105. if delta <= 0 then return end
  106. local oldTotal = d.totalRecharge or 0
  107. local newTotal = oldTotal + delta
  108. d.totalRecharge = newTotal
  109. d.processedDaily = dailyTotal
  110. local rechargeUnit = getRechargeUnit()
  111. local oldTimes = math.floor(oldTotal / rechargeUnit)
  112. local newTimes = math.floor(newTotal / rechargeUnit)
  113. local gained = newTimes - oldTimes
  114. if gained > 0 then
  115. addTimes(human, gained)
  116. updateRedDot(human)
  117. end
  118. end
  119. function VoucherWheel_Query(human)
  120. if not isOpenAct(human) then
  121. return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
  122. end
  123. local d = getData(human)
  124. local _, endTime, startTime = isOpenAct(human)
  125. local msgRet = Msg.gc.GC_ANNIV_VOUCHER_WHEEL_QUERY
  126. msgRet.lotteryTimes = d.lotteryTimes or 0
  127. msgRet.totalRecharge = d.totalRecharge or 0
  128. msgRet.startTime = startTime or 0
  129. msgRet.endTime = endTime or 0
  130. -- 下发完整奖励配置表
  131. msgRet.rewardList[0] = 0
  132. for i, row in ipairs(RewardCfg) do
  133. msgRet.rewardList[0] = i
  134. Grid.makeItem(msgRet.rewardList[i].item, row.reward[1], row.reward[2])
  135. msgRet.rewardList[i].weight = row.nWeight
  136. end
  137. Msg.send(msgRet, human.fd)
  138. end
  139. local function doSpin(human, count)
  140. if not isOpenAct(human) then
  141. return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
  142. end
  143. local d = getData(human)
  144. local curTimes = d.lotteryTimes or 0
  145. if curTimes < count then
  146. return Broadcast.sendErr(human, Lang.JINBI_EXCHANGE_ERR_CNT)
  147. end
  148. local results = doMultiLottery(count)
  149. if not results then
  150. return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
  151. end
  152. d.lotteryTimes = curTimes - count
  153. for _, res in ipairs(results) do
  154. BagLogic.addItem(human, res.itemId, res.itemNum, LOGTYPE)
  155. end
  156. -- 告知客户端完整结果列表,客户端据此播放动画
  157. local msgRet = Msg.gc.GC_ANNIV_VOUCHER_WHEEL_RESULT
  158. msgRet.count = count
  159. msgRet.results[0] = 0
  160. for i, res in ipairs(results) do
  161. msgRet.results[0] = i
  162. Grid.makeItem(msgRet.results[i], res.itemId, res.itemNum)
  163. end
  164. msgRet.lotteryTimes = d.lotteryTimes
  165. Msg.send(msgRet, human.fd)
  166. updateRedDot(human)
  167. end
  168. function VoucherWheel_Single(human)
  169. doSpin(human, 1)
  170. end
  171. function VoucherWheel_Ten(human)
  172. doSpin(human, 10)
  173. end