DuoBaoQiBingLogic.lua 12 KB

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