OnlineAwardLogic.lua 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  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 isOver(human)
  73. local OnlineRewardData = human.db.OnlineRewardData
  74. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  75. local targetCfg = onlineAardCfg[targetDay]
  76. --配置错误或者已经超过配置里的天数了都不显示
  77. if not targetCfg then
  78. return true
  79. end
  80. return false
  81. end
  82. --计算下一个未获得奖励需要的在线时间
  83. local function calcLeftTime(human)
  84. local OnlineRewardData = human.db.OnlineRewardData
  85. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  86. local targetCfg = onlineAardCfg[targetDay]
  87. if not targetCfg then
  88. return
  89. end
  90. local leftTime = 0
  91. local totalNeedTime = 0
  92. local timeCfg = targetCfg.onlineTimeVec
  93. local totalOnlineTime = calcTotalOnlineTime(human)
  94. for _, needTime in ipairs(timeCfg) do
  95. totalNeedTime = totalNeedTime + needTime * TIMEBASE
  96. if totalNeedTime > totalOnlineTime then
  97. leftTime = totalNeedTime - totalOnlineTime
  98. break
  99. end
  100. end
  101. return leftTime
  102. end
  103. --返回可领取奖励的index Vec
  104. local function getCanReceiveAwardVec(human, isRed)
  105. local OnlineRewardData = human.db.OnlineRewardData
  106. local dailyData = OnlineRewardData.dailyData
  107. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  108. local targetCfg = onlineAardCfg[targetDay]
  109. local todayRecordData = dailyData and dailyData[targetDay]
  110. if not targetCfg then
  111. if not isRed then
  112. Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
  113. end
  114. return
  115. end
  116. --充值金额是否符合
  117. local topupAcountDaily = human.db.topupAcountDaily
  118. if not topupAcountDaily or topupAcountDaily < targetCfg.needRecharge then
  119. if not isRed then
  120. Broadcast.sendErr(human, Lang.COMMON_DAY_RECHARGE_NOT_ENOUGH)
  121. end
  122. return
  123. end
  124. local totalNeedTime = 0
  125. local cfgOnlineTimeVec = targetCfg.onlineTimeVec
  126. local totalOnlineTime = calcTotalOnlineTime(human)
  127. local len = 0
  128. local awardIdxVec = {}
  129. for idx, needTime in ipairs(cfgOnlineTimeVec) do
  130. totalNeedTime = totalNeedTime + needTime * TIMEBASE
  131. if totalOnlineTime >= totalNeedTime and (not todayRecordData or not todayRecordData[idx]) then
  132. len = len + 1
  133. awardIdxVec[len] = idx
  134. end
  135. end
  136. if len == 0 then
  137. return
  138. end
  139. return awardIdxVec
  140. end
  141. --定时器任务
  142. local function timeFunc(human)
  143. if not IsOnline then
  144. return
  145. end
  146. local leftTime = calcLeftTime(human)
  147. if leftTime and leftTime > 0 then
  148. local now = os.time()
  149. local todayStartTi = Util.getDayStartTime(now)
  150. local nextDayStartTi = todayStartTi + DAYSEC
  151. --只有需要挂机时间 + 当前时间 < 下一天0点, 那么才加定时器
  152. if leftTime + now < nextDayStartTi then
  153. Timer.addLater(leftTime, function ()
  154. Query(human)
  155. --红点更新
  156. YunYingLogic.updateIcon(YYInfo[ACTID], human, true)
  157. timeFunc(human)
  158. end)
  159. end
  160. end
  161. end
  162. --红点判断
  163. function isRed(human, YYInfo, funcConfig)
  164. if not isHaveAct(human) then
  165. return false
  166. end
  167. if not getCanReceiveAwardVec(human, true) then
  168. return false
  169. end
  170. return true
  171. end
  172. --是否开启(外部调用)
  173. function isOpen(human)
  174. if not isHaveAct(human) then
  175. return false
  176. end
  177. if isOver(human) then
  178. return false
  179. end
  180. return true
  181. end
  182. --登录
  183. function onLogin(human, actID)
  184. if not isHaveAct(human) then
  185. return
  186. end
  187. IsOnline = true
  188. checkHaveTime(human)
  189. timeFunc(human)
  190. end
  191. --下线
  192. function onLogout(human, funcID, parameter, parameter2)
  193. IsOnline = false
  194. end
  195. --跨天
  196. function updateDaily(human, funcID)
  197. checkHaveTime(human)
  198. end
  199. --新跨天函数,这里用新的跨天函数是因为ObjHuman.lua中 重置每日在线时间代码会晚于运营活动中的 updateDaily()执行
  200. --这个活动中,会用到每日在线时间,所以需要重新定义一个跨天函数,在重置每日在线时间后再执行
  201. function NewUpdateDaily(human)
  202. if not isHaveAct(human) then
  203. return
  204. end
  205. if IsOnline then
  206. if isOver(human) then
  207. YunYingLogic.updateIcon(YYInfo[ACTID], human, true)
  208. return
  209. end
  210. --针对玩家在线跨天情况,下发一次最新数据
  211. Query(human)
  212. timeFunc(human)
  213. end
  214. end
  215. --充值
  216. function onCharge(human, price)
  217. local OnlineRewardData = human.db.OnlineRewardData
  218. if not OnlineRewardData or not OnlineRewardData.haveTime then
  219. checkHaveTime(human)
  220. timeFunc(human)
  221. YunYingLogic.updateIcon(YYInfo[ACTID], human, true)
  222. end
  223. OnlineRewardData = human.db.OnlineRewardData
  224. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  225. local targetCfg = onlineAardCfg[targetDay]
  226. local topupAcountDaily = human.db.topupAcountDaily
  227. if topupAcountDaily and topupAcountDaily >= targetCfg.needRecharge then
  228. Query(human)
  229. end
  230. return true
  231. end
  232. --查询
  233. function Query(human)
  234. if not isHaveAct(human) then
  235. return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
  236. end
  237. local OnlineRewardData = human.db.OnlineRewardData
  238. local dailyData = OnlineRewardData.dailyData
  239. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  240. local targetCfg = onlineAardCfg[targetDay]
  241. local todayData = dailyData and dailyData[targetDay]
  242. if not targetCfg then
  243. return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
  244. end
  245. local timeCfg = targetCfg.onlineTimeVec
  246. local awardCfg = targetCfg.awardVec
  247. if #timeCfg ~= #awardCfg then
  248. return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
  249. end
  250. local len = 0
  251. local totalNeedTime = 0
  252. local totalOnlineTime = calcTotalOnlineTime(human)
  253. local msgRet = Msg.gc.GC_ONLINEAWARD_QUERY
  254. msgRet.leftTime = 0
  255. msgRet.needRecharge = targetCfg.needRecharge
  256. msgRet.isReach = 0
  257. local topupAcountDaily = human.db.topupAcountDaily
  258. if topupAcountDaily and topupAcountDaily >= targetCfg.needRecharge then
  259. msgRet.isReach = 1
  260. end
  261. local msgAwardVec = msgRet.awardVec
  262. msgAwardVec[0] = 0
  263. for idx, needTime in ipairs(timeCfg) do
  264. len = len + 1
  265. msgAwardVec[len].state = 0
  266. Grid.makeItem(msgAwardVec[len].itemInfo, awardCfg[idx][1], awardCfg[idx][2])
  267. totalNeedTime = totalNeedTime + needTime * TIMEBASE
  268. if totalOnlineTime >= totalNeedTime then
  269. msgAwardVec[len].state = 1
  270. if todayData and todayData[idx] then
  271. msgAwardVec[len].state = 2
  272. end
  273. else
  274. if msgRet.leftTime == 0 then
  275. msgRet.leftTime = totalNeedTime - totalOnlineTime
  276. end
  277. end
  278. end
  279. msgAwardVec[0] = len
  280. Msg.send(msgRet, human.fd)
  281. end
  282. --领奖
  283. function ClaimAward(human)
  284. if not isHaveAct(human) then
  285. return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
  286. end
  287. local awardIdxVec = getCanReceiveAwardVec(human)
  288. if not awardIdxVec then
  289. return
  290. end
  291. local OnlineRewardData = human.db.OnlineRewardData
  292. local targetDay = getDiffDay(OnlineRewardData.haveTime)
  293. OnlineRewardData.dailyData = OnlineRewardData.dailyData or {}
  294. OnlineRewardData.dailyData[targetDay] = OnlineRewardData.dailyData[targetDay] or {}
  295. local todayRecoedData = OnlineRewardData.dailyData[targetDay]
  296. local len = 0
  297. local awardVec = {}
  298. local targetCfg = onlineAardCfg[targetDay]
  299. local awardCfg = targetCfg.awardVec
  300. for _, idx in ipairs(awardIdxVec) do
  301. len = len + 1
  302. awardVec[len] = {awardCfg[idx][1], awardCfg[idx][2]}
  303. todayRecoedData[idx] = true
  304. end
  305. BagLogic.addItemList(human, awardVec, LOGTYPE)
  306. --下发数据更新
  307. Query(human)
  308. --红点更新
  309. YunYingLogic.updateIcon(YYInfo[ACTID], human, true)
  310. end