DuoBaoQiBingLogic.lua 12 KB

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