DuoBaoQiBingLogic.lua 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. --夺宝奇兵活动
  2. --玩法: 从四条配置中各随机一个奖励, 然后把这4个奖励按照一定数量组成一个奖池给玩家抽奖, 奖励抽到后就减少
  3. --注意事项:活动开启期间, 不能改4条配置中prizeData里各个奖励的顺序,因为服务器存储的是随机到的奖励的index
  4. --db
  5. --[=[
  6. human.db.absAct[id] = {
  7. awardData = {
  8. [type] = {idx = 1, cnt = 1}, --key为奖池类型,idx为配置中随机到的奖励index,cnt表示当前奖励数量
  9. },
  10. isFreeReset = nil, --免费重置标识, 1-免费
  11. posData = { --已经抽奖的位置, pos为位置
  12. [pos] = {poolType = poolType, idx = idx}
  13. },
  14. isStart = nil, --是否开始游戏
  15. isTips = nil, --提示, 为0时不提示,其他情况都提示
  16. dailyFreeState = nil, --每日单抽免费标识,为0时不免费,其他情况免费
  17. }
  18. }
  19. ]=]--
  20. local Msg = require("core.Msg")
  21. local Grid = require("bag.Grid")
  22. local Util = require("common.Util")
  23. local BagLogic = require("bag.BagLogic")
  24. local ItemDefine = require("bag.ItemDefine")
  25. local AbsActLogic = require("absAct.AbsActLogic")
  26. local Broadcast = require("broadcast.Broadcast")
  27. local Lang = require("common.Lang")
  28. local duobaoCfg = require("excel.absAct").DuoBaoQiBing
  29. local YunYingLogic = require("yunying.YunYingLogic")
  30. local AbsActExcel = require("excel.absAct")
  31. local TriggerDefine = require("trigger.TriggerDefine")
  32. local TriggerLogic = require("trigger.TriggerLogic")
  33. local CycleActivityLogic = require("yunying.CycleActivity")
  34. local LOGTYPE = "duobaoqibing" --日志标识
  35. local POOL1CNT = 30 --从奖池1中抽取的奖励数量
  36. local POOL2CNT = 12 --从奖池2中抽取的奖励数量
  37. local POOL3CNT = 2 --从奖池3中抽取的奖励数量
  38. local POOL4CNT = 1 --从奖池4中抽取的奖励数量
  39. local LOTTERYCOSTCNT = 400 --单抽消耗数量
  40. local RESETCOSTCNT = 1000 --重置消耗数量
  41. local COSTITEMID = ItemDefine.ITEM_ZUANSHI_ID --单抽/重置消耗的道具id
  42. local function getAwardNumByType(poolType)
  43. local num = 0
  44. if not poolType then
  45. return num
  46. end
  47. if poolType == 1 then
  48. num = POOL1CNT
  49. elseif poolType == 2 then
  50. num = POOL2CNT
  51. elseif poolType == 3 then
  52. num = POOL3CNT
  53. elseif poolType == 4 then
  54. num = POOL4CNT
  55. end
  56. return num
  57. end
  58. --从配置中随机一个奖励,并返回奖励的index
  59. local function getAwardIdx(awardCfg)
  60. local totalWeight = 0
  61. for _, v in ipairs(awardCfg.prizeData) do
  62. totalWeight = totalWeight + v[3]
  63. end
  64. local randWeight = math.random(0, totalWeight)
  65. local weight, randIdx = 0, 0
  66. for idx, data in ipairs(awardCfg.prizeData) do
  67. weight = weight + data[3]
  68. if randWeight <= weight then
  69. randIdx = idx
  70. break
  71. end
  72. end
  73. return randIdx
  74. end
  75. --生成奖励数据
  76. local function generateAwardData(human, id)
  77. human.db.absAct[id] = human.db.absAct[id] or {}
  78. local actData = human.db.absAct[id]
  79. actData.awardData = actData.awardData or {}
  80. local awardData = actData.awardData
  81. for type, cfg in ipairs(duobaoCfg) do
  82. local awardIdx = getAwardIdx(cfg)
  83. awardData[type] = {
  84. idx = awardIdx,
  85. cnt = getAwardNumByType(type),
  86. --type = type
  87. }
  88. end
  89. end
  90. --填充协议数据
  91. local function populateMsg(actData, msgTb)
  92. local awardData = actData.awardData
  93. local posData = actData.posData
  94. local awardNum, len = 0, 0
  95. for i=1, 4 do
  96. awardNum = getAwardNumByType(i)
  97. local awardIdx = awardData[i].idx
  98. local awardInfo = duobaoCfg[i].prizeData[awardIdx]
  99. for j=1, awardNum do
  100. len = len + 1
  101. msgTb[len].isGet = 0
  102. msgTb[len].poolType = i
  103. msgTb[len].index = len
  104. Grid.makeItem(msgTb[len].item, awardInfo[1], awardInfo[2])
  105. if posData and posData[len] then
  106. msgTb[len].isGet = 1
  107. local poolType = posData[len].poolType
  108. --奖池类型不一样, 说明该位置抽到的是别的奖池的道具, 需要修改道具信息
  109. if poolType ~= i then
  110. msgTb[len].poolType = poolType
  111. awardIdx = posData[len].idx
  112. local realAwardInfo = duobaoCfg[poolType].prizeData[awardIdx]
  113. Grid.makeItem(msgTb[len].item, realAwardInfo[1], realAwardInfo[2])
  114. end
  115. end
  116. end
  117. end
  118. msgTb[0] = len
  119. end
  120. --生成抽奖数据
  121. local function generateLotteryData(actData)
  122. local awardVec = {}
  123. local len, totalWeight = 0,0
  124. local awardData = actData.awardData
  125. for type, data in ipairs(awardData) do
  126. if data.cnt > 0 then
  127. local awardInfo = duobaoCfg[type].prizeData[data.idx]
  128. local itemId = awardInfo[1]
  129. local itemNum = awardInfo[2]
  130. local weight = awardInfo[3]
  131. for i=1, data.cnt do
  132. len = len + 1
  133. totalWeight = totalWeight + weight
  134. awardVec[len] = {itemId, itemNum, weight, type, data.idx}
  135. end
  136. end
  137. end
  138. return awardVec, totalWeight
  139. end
  140. --刷天处理
  141. function updateDaily(human, id)
  142. -- local state = AbsActLogic.isStarted(human, id)
  143. local state = CycleActivityLogic.isStarted(human, id)
  144. if not state then
  145. return
  146. end
  147. local actData = human.db.absAct[id]
  148. if not actData then
  149. return
  150. end
  151. actData.isTips = 1
  152. actData.dailyFreeState = 1
  153. end
  154. function isRed(human, YYInfo, absActConfig)
  155. local id = absActConfig.funcID
  156. -- local state = AbsActLogic.isStarted(human, id)
  157. local state = CycleActivityLogic.isStarted(human, id)
  158. if not state then
  159. return false
  160. end
  161. local actData = human.db.absAct[id]
  162. if not actData then
  163. return false
  164. end
  165. if actData.dailyFreeState and actData.dailyFreeState == 0 then
  166. return false
  167. end
  168. return true
  169. end
  170. --查询
  171. function Query(human, id)
  172. -- local state = AbsActLogic.isStarted(human, id)
  173. -- print("[DuoBaoQiBing_Query ] id = "..id.." name = "..human.db.name)
  174. local state = CycleActivityLogic.isStarted(human, id)
  175. if not state then
  176. return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
  177. end
  178. local actData = human.db.absAct[id]
  179. if not actData then
  180. return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
  181. end
  182. local msgRet = Msg.gc.GC_DBQB_QUERY
  183. msgRet.isFreeReset = actData.isFreeReset or 0
  184. msgRet.isStart = actData.isStart or 0
  185. msgRet.isTips = 1
  186. if actData.isTips and actData.isTips == 0 then
  187. msgRet.isTips = 0
  188. end
  189. msgRet.isFree = 0
  190. if not actData.dailyFreeState or actData.dailyFreeState == 1 then
  191. msgRet.isFree = 1
  192. end
  193. if not actData or not actData.awardData then
  194. generateAwardData(human, id)
  195. end
  196. Grid.makeItem(msgRet.lotteryCost, COSTITEMID, LOTTERYCOSTCNT)
  197. Grid.makeItem(msgRet.resetCost, COSTITEMID, RESETCOSTCNT)
  198. populateMsg(actData, msgRet.awardPoolData)
  199. Msg.send(msgRet, human.fd)
  200. end
  201. --奖池重置
  202. function ResetAwardPool(human, id, resetType)
  203. if not id or not resetType then
  204. return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
  205. end
  206. -- local state = AbsActLogic.isStarted(human, id)
  207. local state = CycleActivityLogic.isStarted(human, id)
  208. if not state then
  209. return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
  210. end
  211. local actData = human.db.absAct[id]
  212. if not actData then
  213. return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
  214. end
  215. if resetType == 1 then
  216. if not actData.isFreeReset or actData.isFreeReset <= 0 then
  217. return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
  218. end
  219. actData.isFreeReset = 0
  220. elseif resetType == 2 then
  221. if BagLogic.getItemCnt(human, COSTITEMID) < RESETCOSTCNT then
  222. return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH)
  223. end
  224. BagLogic.delItem(human, COSTITEMID, RESETCOSTCNT, LOGTYPE)
  225. else
  226. return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
  227. end
  228. --重置数据
  229. generateAwardData(human, id)
  230. actData.posData = nil
  231. actData.isStart = 0
  232. --通知客户端
  233. local msgRet = Msg.gc.GC_DBQB_RESET
  234. msgRet.isFreeReset = actData.isFreeReset or 0
  235. msgRet.isStart = actData.isStart or 0
  236. populateMsg(actData, msgRet.awardPoolData)
  237. Msg.send(msgRet, human.fd)
  238. end
  239. --抽奖
  240. function Lottery(human, id, pos)
  241. if not id or not pos then
  242. return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
  243. end
  244. if 1 > pos or pos > (POOL1CNT + POOL2CNT + POOL3CNT + POOL4CNT) then
  245. return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
  246. end
  247. -- local state = AbsActLogic.isStarted(human, id)
  248. local state = CycleActivityLogic.isStarted(human, id)
  249. if not state then
  250. return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
  251. end
  252. local actData = human.db.absAct[id]
  253. if not actData then
  254. return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
  255. end
  256. local posData = actData.posData
  257. if posData and posData[pos] then
  258. return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
  259. end
  260. local itemCnt = LOTTERYCOSTCNT
  261. if not actData.dailyFreeState or actData.dailyFreeState == 1 then
  262. itemCnt = 0
  263. actData.dailyFreeState = 0
  264. end
  265. --扣消耗
  266. if itemCnt > 0 then
  267. if BagLogic.getItemCnt(human, COSTITEMID) < itemCnt then
  268. return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH)
  269. end
  270. BagLogic.delItem(human, COSTITEMID, itemCnt, LOGTYPE)
  271. end
  272. --抽奖
  273. local awardVec, totalWeight = generateLotteryData(actData)
  274. if #awardVec <= 0 then
  275. return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
  276. end
  277. local itemId, itemCnt, weight, poolType, awardIdx = 0,0,0,0,0
  278. local randWeight = math.random(0, totalWeight)
  279. for _,v in ipairs(awardVec) do
  280. weight = weight + v[3]
  281. if randWeight <= weight then
  282. itemId = v[1]
  283. itemCnt = v[2]
  284. poolType = v[4]
  285. awardIdx = v[5]
  286. break
  287. end
  288. end
  289. --BagLogic.addItem(human, itemId, itemCnt, LOGTYPE)
  290. BagLogic.addItemList(human, { {itemId, itemCnt}}, LOGTYPE)
  291. --更新db
  292. actData.posData = actData.posData or {}
  293. actData.posData[pos] = { poolType = poolType, idx = awardIdx }
  294. actData.awardData[poolType].cnt = actData.awardData[poolType].cnt - 1
  295. if poolType == 4 then --抽到特殊奖励, 获得免费刷新奖池一次
  296. actData.isFreeReset = 1
  297. TriggerLogic.PublishEvent(TriggerDefine.DRAGON_PEARL, human.db._id, 1)
  298. end
  299. --通知客户端
  300. local msgRet = Msg.gc.GC_DBQB_LOTTERY
  301. msgRet.isFreeReset = actData.isFreeReset or 0
  302. msgRet.isFree = 0 --有免费次数会优先使用免费次数, 所以抽奖后,免费次数就没有了
  303. --populateMsg(actData, msgRet.awardPoolData)
  304. local posInfo = msgRet.posInfo
  305. posInfo.isGet = 1
  306. posInfo.poolType = poolType
  307. posInfo.index = pos
  308. Grid.makeItem(posInfo.item, itemId, itemCnt)
  309. Msg.send(msgRet, human.fd)
  310. --红点刷新
  311. if itemCnt == 0 then
  312. local config = AbsActExcel.absActivity[id]
  313. YunYingLogic.sendGroupUpdate(YYInfo[id], human, config.panelID)
  314. end
  315. end
  316. --点击开始游戏
  317. function StartGame(human, id)
  318. if not id then
  319. return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
  320. end
  321. -- local state = AbsActLogic.isStarted(human, id)
  322. local state = CycleActivityLogic.isStarted(human, id)
  323. if not state then
  324. return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
  325. end
  326. local actData = human.db.absAct[id]
  327. if not actData then
  328. return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
  329. end
  330. --修改状态
  331. actData.isStart = 1
  332. --通知客户端
  333. local msgRet = Msg.gc.GC_DBQB_START_GAME
  334. msgRet.isStart = actData.isStart or 0
  335. Msg.send(msgRet, human.fd)
  336. end
  337. --关闭提示
  338. function CloseTips(human, id)
  339. if not id then
  340. return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
  341. end
  342. -- local state = AbsActLogic.isStarted(human, id)
  343. local state = CycleActivityLogic.isStarted(human, id)
  344. if not state then
  345. return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
  346. end
  347. local actData = human.db.absAct[id]
  348. if not actData then
  349. return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
  350. end
  351. --修改状态
  352. actData.isTips = 0
  353. --通知客户端
  354. local msgRet = Msg.gc.GC_DBQB_TIPS
  355. msgRet.isTips = actData.isTips or 0
  356. Msg.send(msgRet, human.fd)
  357. end