OnlineAwardLogic.lua 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. --在线奖励活动
  2. --db
  3. --[=[
  4. human.db.OnlineRewardData = {
  5. haveTime = nil, --活动获得时间, 即首充时间
  6. dailyData = { --每日数据,key为当前时间距离 haveTime 的天数
  7. [1] = {
  8. [1] = nil, --记录当天某个档位奖励的领取情况, key 为档位,有记录表示已经领取了(不可领取和可领取两种状态不存db)
  9. [2] = nil,
  10. },
  11. [2] = {
  12. [1] = nil,
  13. [2] = nil,
  14. },
  15. }
  16. }
  17. ]=]--
  18. local Msg = require("core.Msg")
  19. local Grid = require("bag.Grid")
  20. local Util = require("common.Util")
  21. local BagLogic = require("bag.BagLogic")
  22. local Broadcast = require("broadcast.Broadcast")
  23. local Lang = require("common.Lang")
  24. local onlineAardCfg = require("excel.onlineAward").onlineAward
  25. local YunYingLogic = require("yunying.YunYingLogic")
  26. local PanelDefine = require("broadcast.PanelDefine")
  27. local Timer = require("core.Timer")
  28. --分钟转秒
  29. local TIMEBASE = 60
  30. --一天的秒数
  31. local DAYSEC = 86400
  32. --本活动日志标识
  33. local LOGTYPE = "OnlineAwardLogic"
  34. --是否在线
  35. IsOnline = false
  36. --活动ID
  37. local ACTID = 18001
  38. --检查活动获得时间, 如果没有初始化则初始化
  39. local function checkHaveTime(human)
  40. local OnlineRewardData = human.db.OnlineRewardData
  41. if not OnlineRewardData or not OnlineRewardData.haveTime then
  42. human.db.OnlineRewardData = human.db.OnlineRewardData or {}
  43. human.db.OnlineRewardData.haveTime = os.time()
  44. end
  45. end
  46. --计算当天到目前为止的总在线时长
  47. local function calcTotalOnlineTime(human)
  48. local lastOnlineTime = human.db.onlineTimeDay or 0
  49. local loginTime = human.db.lastLoginTime
  50. --可能存在玩家在线跨天情况,需要判断登录时间与当前时间是否属于同一天,如果不是, 那么在此活动中,当天的登录时间应该为当天0点
  51. local now = os.time()
  52. if not Util.isSameDay(loginTime) then
  53. loginTime = Util.getDayStartTime(now)
  54. end
  55. local totalOnlineTime = now - loginTime + lastOnlineTime
  56. return totalOnlineTime
  57. end
  58. --获取当前时间距离startTime相差多少天
  59. local function getDiffDay(startTime)
  60. local passDay = Util.diffDay(startTime) + 1
  61. return passDay
  62. end
  63. --是否获得该活动
  64. local function isHaveAct(human)
  65. local topupAcount = human.db.topupAcount
  66. if topupAcount and topupAcount > 0 then
  67. return true
  68. end
  69. return false
  70. end
  71. --计算下一个未获得奖励需要的在线时间
  72. local function calcLeftTime(human)
  73. local OnlineRewardData = human.db.OnlineRewardData
  74. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  75. local targetCfg = onlineAardCfg[targetDay]
  76. if not targetCfg then
  77. return
  78. end
  79. local leftTime = 0
  80. local totalNeedTime = 0
  81. local timeCfg = targetCfg.onlineTimeVec
  82. local totalOnlineTime = calcTotalOnlineTime(human)
  83. for _, needTime in ipairs(timeCfg) do
  84. totalNeedTime = totalNeedTime + needTime * TIMEBASE
  85. if totalNeedTime > totalOnlineTime then
  86. leftTime = totalNeedTime - totalOnlineTime
  87. break
  88. end
  89. end
  90. return leftTime
  91. end
  92. --返回可领取奖励的index Vec
  93. local function getCanReceiveAwardVec(human, isRed)
  94. local OnlineRewardData = human.db.OnlineRewardData
  95. local dailyData = OnlineRewardData.dailyData
  96. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  97. local targetCfg = onlineAardCfg[targetDay]
  98. local todayRecordData = dailyData and dailyData[targetDay]
  99. if not targetCfg then
  100. if not isRed then
  101. Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
  102. end
  103. return
  104. end
  105. --充值金额是否符合
  106. local topupAcountDaily = human.db.topupAcountDaily
  107. if not topupAcountDaily or topupAcountDaily < targetCfg.needRecharge then
  108. if not isRed then
  109. Broadcast.sendErr(human, Lang.COMMON_DAY_RECHARGE_NOT_ENOUGH)
  110. end
  111. return
  112. end
  113. local totalNeedTime = 0
  114. local cfgOnlineTimeVec = targetCfg.onlineTimeVec
  115. local totalOnlineTime = calcTotalOnlineTime(human)
  116. local len = 0
  117. local awardIdxVec = {}
  118. for idx, needTime in ipairs(cfgOnlineTimeVec) do
  119. totalNeedTime = totalNeedTime + needTime * TIMEBASE
  120. if totalOnlineTime >= totalNeedTime and (not todayRecordData or not todayRecordData[idx]) then
  121. len = len + 1
  122. awardIdxVec[len] = idx
  123. end
  124. end
  125. if len == 0 then
  126. return
  127. end
  128. return awardIdxVec
  129. end
  130. --定时器任务
  131. local function timeFunc(human)
  132. if not IsOnline then
  133. return
  134. end
  135. local leftTime = calcLeftTime(human)
  136. if leftTime and leftTime > 0 then
  137. local now = os.time()
  138. local todayStartTi = Util.getDayStartTime(now)
  139. local nextDayStartTi = todayStartTi + DAYSEC
  140. --只有需要挂机时间 + 当前时间 < 下一天0点, 那么才加定时器
  141. if leftTime + now < nextDayStartTi then
  142. Timer.addLater(leftTime, function ()
  143. Query(human)
  144. --红点更新
  145. YunYingLogic.updateIcon(YYInfo[ACTID], human, true)
  146. timeFunc(human)
  147. end)
  148. end
  149. end
  150. end
  151. --红点判断
  152. function isRed(human, YYInfo, funcConfig)
  153. if not isHaveAct(human) then
  154. return false
  155. end
  156. if not getCanReceiveAwardVec(human, true) then
  157. return false
  158. end
  159. return true
  160. end
  161. --是否开启(外部调用)
  162. function isOpen(human)
  163. if not isHaveAct(human) then
  164. return false
  165. end
  166. local OnlineRewardData = human.db.OnlineRewardData
  167. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  168. local targetCfg = onlineAardCfg[targetDay]
  169. --配置错误或者已经超过配置里的天数了都不显示
  170. if not targetCfg then
  171. return false
  172. end
  173. return true
  174. end
  175. --登录
  176. function onLogin(human, actID)
  177. if not isHaveAct(human) then
  178. return
  179. end
  180. IsOnline = true
  181. checkHaveTime(human)
  182. timeFunc(human)
  183. end
  184. --下线
  185. function onLogout(human, funcID, parameter, parameter2)
  186. IsOnline = false
  187. end
  188. --跨天
  189. function updateDaily(human, funcID)
  190. checkHaveTime(human)
  191. end
  192. --新跨天函数,这里用新的跨天函数是因为ObjHuman.lua中 重置每日在线时间代码会晚于运营活动中的 updateDaily()执行
  193. --这个活动中,会用到每日在线时间,所以需要重新定义一个跨天函数,在重置每日在线时间后再执行
  194. function NewUpdateDaily(human)
  195. if not isHaveAct(human) then
  196. return
  197. end
  198. if IsOnline then
  199. --针对玩家在线跨天情况,下发一次最新数据
  200. Query(human)
  201. timeFunc(human)
  202. end
  203. end
  204. --充值
  205. function onCharge(human, price)
  206. local OnlineRewardData = human.db.OnlineRewardData
  207. if not OnlineRewardData or not OnlineRewardData.haveTime then
  208. checkHaveTime(human)
  209. timeFunc(human)
  210. YunYingLogic.updateIcon(YYInfo[ACTID], human, true)
  211. end
  212. OnlineRewardData = human.db.OnlineRewardData
  213. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  214. local targetCfg = onlineAardCfg[targetDay]
  215. local topupAcountDaily = human.db.topupAcountDaily
  216. if topupAcountDaily and topupAcountDaily >= targetCfg.needRecharge then
  217. Query(human)
  218. end
  219. return true
  220. end
  221. --查询
  222. function Query(human)
  223. if not isHaveAct(human) then
  224. return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
  225. end
  226. local OnlineRewardData = human.db.OnlineRewardData
  227. local dailyData = OnlineRewardData.dailyData
  228. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  229. local targetCfg = onlineAardCfg[targetDay]
  230. local todayData = dailyData and dailyData[targetDay]
  231. if not targetCfg then
  232. return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
  233. end
  234. local timeCfg = targetCfg.onlineTimeVec
  235. local awardCfg = targetCfg.awardVec
  236. if #timeCfg ~= #awardCfg then
  237. return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
  238. end
  239. local len = 0
  240. local totalNeedTime = 0
  241. local totalOnlineTime = calcTotalOnlineTime(human)
  242. local msgRet = Msg.gc.GC_ONLINEAWARD_QUERY
  243. msgRet.leftTime = 0
  244. msgRet.needRecharge = targetCfg.needRecharge
  245. msgRet.isReach = 0
  246. local topupAcountDaily = human.db.topupAcountDaily
  247. if topupAcountDaily and topupAcountDaily >= targetCfg.needRecharge then
  248. msgRet.isReach = 1
  249. end
  250. local msgAwardVec = msgRet.awardVec
  251. msgAwardVec[0] = 0
  252. for idx, needTime in ipairs(timeCfg) do
  253. len = len + 1
  254. msgAwardVec[len].state = 0
  255. Grid.makeItem(msgAwardVec[len].itemInfo, awardCfg[idx][1], awardCfg[idx][2])
  256. totalNeedTime = totalNeedTime + needTime * TIMEBASE
  257. if totalOnlineTime >= totalNeedTime then
  258. msgAwardVec[len].state = 1
  259. if todayData and todayData[idx] then
  260. msgAwardVec[len].state = 2
  261. end
  262. else
  263. if msgRet.leftTime == 0 then
  264. msgRet.leftTime = totalNeedTime - totalOnlineTime
  265. end
  266. end
  267. end
  268. msgAwardVec[0] = len
  269. Msg.send(msgRet, human.fd)
  270. end
  271. --领奖
  272. function ClaimAward(human)
  273. if not isHaveAct(human) then
  274. return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
  275. end
  276. local awardIdxVec = getCanReceiveAwardVec(human)
  277. if not awardIdxVec then
  278. return
  279. end
  280. local OnlineRewardData = human.db.OnlineRewardData
  281. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  282. OnlineRewardData.dailyData = OnlineRewardData.dailyData or {}
  283. OnlineRewardData.dailyData[targetDay] = OnlineRewardData.dailyData[targetDay] or {}
  284. local todayRecoedData = OnlineRewardData.dailyData[targetDay]
  285. local len = 0
  286. local awardVec = {}
  287. local targetCfg = onlineAardCfg[targetDay]
  288. local awardCfg = targetCfg.awardVec
  289. for _, idx in ipairs(awardIdxVec) do
  290. len = len + 1
  291. awardVec[len] = {awardCfg[idx][1], awardCfg[idx][2]}
  292. todayRecoedData[idx] = true
  293. end
  294. BagLogic.addItemList(human, awardVec, LOGTYPE)
  295. --下发数据更新
  296. Query(human)
  297. --红点更新
  298. YunYingLogic.updateIcon(YYInfo[ACTID], human, true)
  299. end