TreasureChestLogic.lua 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. --------------------------------
  2. -- 文件名 : TreasureChestLogic.lua
  3. -- 文件说明 : 宝箱系统
  4. -- 创建时间 : 2025/03/10
  5. -- 创建人 : FC
  6. --------------------------------
  7. ---
  8. local Util = require("common.Util")
  9. local Msg = require("core.Msg")
  10. local BagLogic = require("bag.BagLogic")
  11. local Log = require("common.Log")
  12. local TreasureConf = require("excel.treasurechest")
  13. local CommonDefine = require("common.CommonDefine")
  14. local Grid = require("bag.Grid")
  15. -- 奖励缓存有序 key为宝箱类型
  16. local tCacheBoxPrize = nil
  17. -- 一次性最多打开宝箱数量
  18. local TREASURECHEST_OPEN_NUM = 9999
  19. -- 自动开宝箱解锁条件
  20. local TREASURECHEST_OPEN_AUTO_TYPE = 5 -- 钻石
  21. local TREASURECHEST_OPEN_AUTO_NUM = 2 -- 开两次
  22. ----------------------------------------- 内部处理开始 -------------------------------------
  23. -- 写日志
  24. local function TreasureChestLogic_WriteLog(human, szText)
  25. Log.write(Log.LOGID_OSS_COMMON, "name = "..human.db.name.." id = "..human.db._id..szText)
  26. end
  27. -- 获取宝箱配置
  28. local function TreasureChestLogic_GetBoxTypeConf()
  29. return TreasureConf.boxtype
  30. end
  31. -- 获取宝箱积分配置
  32. local function TreasureChestLogic_GetPointConf()
  33. return TreasureConf.boxpoint
  34. end
  35. -- 获取宝箱奖励配置
  36. local function TreasureChestLogic_GetPointPrizeConf()
  37. if not tCacheBoxPrize then
  38. tCacheBoxPrize = {}
  39. for _, v in pairs(TreasureConf.boxprize) do
  40. local nType = v.nType
  41. if not tCacheBoxPrize[nType] then
  42. tCacheBoxPrize[nType] = {}
  43. end
  44. table.insert(tCacheBoxPrize[nType], v)
  45. end
  46. -- 变成有序
  47. for _, v in pairs(tCacheBoxPrize) do
  48. table.sort(v, function (l, r)
  49. return l.nPro < r.nPro
  50. end)
  51. end
  52. -- 整合权重
  53. for _, data in ipairs(tCacheBoxPrize) do
  54. local nAllWeight = 0
  55. for _, v in ipairs(data) do
  56. if nAllWeight == 0 then
  57. nAllWeight = v.nPro
  58. else
  59. nAllWeight = nAllWeight + v.nPro
  60. end
  61. v.nAllPro = nAllWeight
  62. end
  63. end
  64. end
  65. return tCacheBoxPrize
  66. end
  67. -- 重置积分奖励数据
  68. local function TreasureChestLogic_ResetDBPointPrize(human)
  69. local tBoxPoint = TreasureChestLogic_GetPointConf()
  70. for key, v in pairs(tBoxPoint) do
  71. human.db.TreasureChest.tPointPrize[key] = CommonDefine.COMMON_PRIZE_STATE_NOGET
  72. end
  73. end
  74. -- 创建DB数据
  75. local function TreasureChestLogic_CreateDB(human)
  76. human.db.TreasureChest = {
  77. nPoint = 0,
  78. nOpenNum = 0,
  79. tPointPrize = {},
  80. tItem = {}, -- 宝箱数量
  81. }
  82. TreasureChestLogic_ResetDBPointPrize(human)
  83. end
  84. -- 获取当前积分
  85. local function TreasureChestLogic_GetDBPoint(human)
  86. if not human.db.TreasureChest then
  87. TreasureChestLogic_CreateDB(human)
  88. end
  89. return human.db.TreasureChest.nPoint
  90. end
  91. -- 设置当前积分
  92. local function TreasureChestLogic_SetDBPoint(human, nValue)
  93. if not human.db.TreasureChest then
  94. TreasureChestLogic_CreateDB(human)
  95. end
  96. human.db.TreasureChest.nPoint = nValue
  97. end
  98. -- 获取当前积分奖励状态
  99. local function TreasureChestLogic_GetDBPointPrize(human, nID)
  100. if not human.db.TreasureChest then
  101. TreasureChestLogic_CreateDB(human)
  102. end
  103. return human.db.TreasureChest.tPointPrize[nID]
  104. end
  105. -- 设置当前积分奖励状态
  106. local function TreasureChestLogic_SetDBPointPrize(human, nID, nState)
  107. if not human.db.TreasureChest then
  108. TreasureChestLogic_CreateDB(human)
  109. end
  110. human.db.TreasureChest.tPointPrize[nID] = nState
  111. end
  112. -- 更新积分奖励状态
  113. local function TreasureChestLogic_UpdatePointPrize(human)
  114. local nNowPoint = TreasureChestLogic_GetDBPoint(human)
  115. local tBoxPointCof = TreasureChestLogic_GetPointConf()
  116. for nID, v in ipairs(tBoxPointCof) do
  117. if nNowPoint >= v.nPoint then
  118. local nState = TreasureChestLogic_GetDBPointPrize(human, nID)
  119. if CommonDefine.COMMON_PRIZE_STATE_NOGET == nState then
  120. TreasureChestLogic_SetDBPointPrize(human, nID, CommonDefine.COMMON_PRIZE_STATE_CANGET)
  121. nNowPoint = nNowPoint - v.nPoint
  122. elseif CommonDefine.COMMON_PRIZE_STATE_CANGET == nState then
  123. nNowPoint = nNowPoint - v.nPoint
  124. end
  125. end
  126. end
  127. end
  128. -- 打开宝箱操作
  129. local function TreasureChestLogic_OpenBox(nType, nBoxNum)
  130. local tBoxTypeConf = TreasureChestLogic_GetBoxTypeConf()
  131. local tBoxPrize = TreasureChestLogic_GetPointPrizeConf()
  132. if not tBoxTypeConf[nType] or not tBoxPrize[nType] then
  133. return nil
  134. end
  135. local nOpenNum = tBoxTypeConf[nType].nOpenNum
  136. -- 获取的表是有序的
  137. local tBoxTypePrize = tBoxPrize[nType]
  138. local nLen = #tBoxTypePrize
  139. local nAllWeight = tBoxTypePrize[nLen].nAllPro
  140. --print("[TreasureChestLogic_OpenBox] nAllWeight = "..nAllWeight)
  141. local tOpenPrize = {}
  142. for i = 1, nBoxNum, 1 do
  143. for j = 1, nOpenNum, 1 do
  144. -- 随机权重
  145. local nRandNum = math.random(1, nAllWeight)
  146. --print("[TreasureChestLogic_OpenBox] j = "..j.." nRandNum = "..nRandNum)
  147. for _, v in pairs(tBoxTypePrize) do
  148. --print("[TreasureChestLogic_OpenBox] nAllPro = "..v.nAllPro.." ID = "..v.tPrize[1].." num = "..v.tPrize[2].."\n")
  149. if nRandNum <= v.nAllPro then
  150. table.insert(tOpenPrize, v.tPrize)
  151. --print("[TreasureChestLogic_OpenBox] 获得的道具 nID = "..v.tPrize[1].." nNum = "..v.tPrize[2].." nKey "..v.nAllPro)
  152. break
  153. end
  154. end
  155. end
  156. end
  157. return tOpenPrize
  158. end
  159. -- 获取宝箱数量
  160. local function TreasureChestLogic_GetGoodsNum(human, nGoodsID)
  161. if not human.db.TreasureChest.tItem[nGoodsID] then
  162. human.db.TreasureChest.tItem[nGoodsID] = 0
  163. end
  164. return human.db.TreasureChest.tItem[nGoodsID]
  165. end
  166. -- 添加宝箱物品
  167. local function TreasureChestLogic_AddGoods(human, nGoodsID, nGoodsNum)
  168. if not human.db.TreasureChest.tItem[nGoodsID] then
  169. human.db.TreasureChest.tItem[nGoodsID] = 0
  170. end
  171. human.db.TreasureChest.tItem[nGoodsID] = human.db.TreasureChest.tItem[nGoodsID] + nGoodsNum
  172. end
  173. -- 删除物品
  174. local function TreasureChestLogic_DelGoods(human, nGoodsID, nGoodsNum)
  175. human.db.TreasureChest.tItem[nGoodsID] = human.db.TreasureChest.tItem[nGoodsID] - nGoodsNum
  176. if 0 > human.db.TreasureChest.tItem[nGoodsID] then
  177. human.db.TreasureChest.tItem[nGoodsID] = 0
  178. end
  179. TreasureChestLogic_WriteLog(human, "减少了宝箱道具 nItemID "..nGoodsID.." nDelNum "..nGoodsNum)
  180. end
  181. -- 获取当前打开的钻石宝箱数量
  182. local function TreasureChestLogic_GetAutoOpenNum(human)
  183. return human.db.TreasureChest.nOpenNum
  184. end
  185. -- 记录打开钻石宝箱数量
  186. local function TreasureChestLogic_AddAutoNum(human, nType, nNum)
  187. if TREASURECHEST_OPEN_AUTO_TYPE ~= nType then
  188. return
  189. end
  190. local nNowNum = TreasureChestLogic_GetAutoOpenNum(human)
  191. if TREASURECHEST_OPEN_AUTO_NUM <= nNowNum then
  192. return
  193. end
  194. human.db.TreasureChest.nOpenNum = human.db.TreasureChest.nOpenNum + nNum
  195. end
  196. ----------------------------------------- 客户端请求 -------------------------------------
  197. -- 请求宝箱界面信息
  198. function TreasureChestLogic_Query(human)
  199. if not human then
  200. return
  201. end
  202. if not human.db.TreasureChest then
  203. TreasureChestLogic_CreateDB(human)
  204. end
  205. local tMsgData = Msg.gc.GC_TEEASURECHEST_QUERY
  206. tMsgData.nNowPoint = TreasureChestLogic_GetDBPoint(human)
  207. tMsgData.nAuto = TreasureChestLogic_GetAutoOpenNum(human) >= TREASURECHEST_OPEN_AUTO_NUM and 1 or 0
  208. tMsgData.nID = 0
  209. tMsgData.nNextPoint = 0
  210. tMsgData.nState = 0
  211. local tBoxPointConf = TreasureChestLogic_GetPointConf()
  212. local tBoxTypeConf = TreasureChestLogic_GetBoxTypeConf()
  213. -- 下一阶段需要的积分信息
  214. for nID, v in ipairs(tBoxPointConf) do
  215. local nState = TreasureChestLogic_GetDBPointPrize(human, nID)
  216. if CommonDefine.COMMON_PRIZE_STATE_NOGET == nState or CommonDefine.COMMON_PRIZE_STATE_CANGET == nState then
  217. tMsgData.nID = nID
  218. tMsgData.nNextPoint = v.nPoint
  219. tMsgData.nState = nState
  220. Grid.makeItem(tMsgData.tPointPirze, v.tPrize[1], v.tPrize[2])
  221. break
  222. end
  223. end
  224. -- 奖励信息
  225. local nLen = 0
  226. for nType, v in pairs(tBoxTypeConf) do
  227. nLen = nLen + 1
  228. tMsgData.tList[0] = nLen
  229. local tData = tMsgData.tList[nLen]
  230. tData.nType = nType
  231. local nGoodsID = v.nItemID
  232. local nGoodsNum = TreasureChestLogic_GetGoodsNum(human, nGoodsID)
  233. Grid.makeItem(tData.tItemData, nGoodsID, nGoodsNum)
  234. end
  235. Msg.send(tMsgData, human.fd)
  236. end
  237. -- 请求宝箱内奖励信息
  238. function TreasureChestLogic_QueryPrize(human, nBoxType)
  239. local tBoxPrize = TreasureChestLogic_GetPointPrizeConf()
  240. if not tBoxPrize[nBoxType] then
  241. print("[TreasureChestLogic_QueryPrize] 不存在对应的奖励配置 nBoxType = "..nBoxType)
  242. return
  243. end
  244. local tBoxTypePrize = tBoxPrize[nBoxType]
  245. local tMsgData = Msg.gc.GC_TEEASURECHEST_PRIZE_QUERY
  246. local nLen = 0
  247. tMsgData.tItemData[0] = nLen
  248. for _, v in pairs(tBoxTypePrize) do
  249. nLen = nLen + 1
  250. tMsgData.tItemData[0] = nLen
  251. local tData = tMsgData.tItemData[nLen]
  252. local nGoodsID = v.prize[1]
  253. local nGoodsNum = v.prize[2]
  254. local quality = v.prize[3]
  255. Grid.makeItem(tData, nGoodsID, nGoodsNum, nil, nil, nil, nil, quality)
  256. end
  257. Msg.send(tMsgData, human.fd)
  258. end
  259. -- 请求打开宝箱
  260. function TreasureChestLogic_Open(human, nBoxType, nBoxNum)
  261. local szText = "[TreasureChestLogic_Open] 玩家请求打开宝箱 nBoxType = "..nBoxType.." nBoxNum = "..nBoxNum
  262. TreasureChestLogic_WriteLog(human, szText)
  263. if nBoxNum >= TREASURECHEST_OPEN_NUM then
  264. szText = szText .. " 失败不正确的打开数量"
  265. TreasureChestLogic_WriteLog(human, szText)
  266. return
  267. end
  268. -- 检测配置
  269. local tBoxTypeConf = TreasureChestLogic_GetBoxTypeConf()
  270. if not tBoxTypeConf[nBoxType] then
  271. print("[TreasureChestLogic_Open] 不存在对应的宝箱类型 nBoxType = "..nBoxType)
  272. szText = szText.." 失败不存在对应宝箱类型"
  273. TreasureChestLogic_WriteLog(human, szText)
  274. return
  275. end
  276. local nGoodsID = tBoxTypeConf[nBoxType].nItemID
  277. local nGoodsNum = TreasureChestLogic_GetGoodsNum(human, nGoodsID)
  278. if nBoxNum > nGoodsNum then
  279. print("[TreasureChestLogic_Open] 玩家拥有宝箱数量不足 nBoxType = "
  280. ..nBoxType.." nBoxNum = "..nBoxNum.." nGoodsNum = "..nGoodsNum)
  281. szText = szText.." 数量不正确 nGoodsNum = "..nGoodsNum
  282. TreasureChestLogic_WriteLog(human, szText)
  283. return
  284. end
  285. local tPrize = TreasureChestLogic_OpenBox(nBoxType, nBoxNum)
  286. -- 发送奖励
  287. BagLogic.addItemList(human, tPrize, "treasurechest")
  288. --BagLogic.sendItemGetList(human, tPrize, "treasurechest")
  289. szText = szText .." 发送奖励成功"
  290. TreasureChestLogic_WriteLog(human, szText)
  291. -- 加积分
  292. local nAddPoint = nBoxNum * tBoxTypeConf[nBoxType].nPoint
  293. local nNowPoint = TreasureChestLogic_GetDBPoint(human)
  294. nNowPoint = nAddPoint + nNowPoint
  295. TreasureChestLogic_SetDBPoint(human, nNowPoint)
  296. szText = szText.." 增加积分 nAddPoint = "..nAddPoint.." nNowPoint = "..nNowPoint
  297. TreasureChestLogic_WriteLog(human, szText)
  298. -- 删除使用了的物品
  299. TreasureChestLogic_DelGoods(human, nGoodsID, nBoxNum)
  300. -- 更新积分奖励状态
  301. TreasureChestLogic_UpdatePointPrize(human)
  302. if TREASURECHEST_OPEN_AUTO_TYPE == nBoxType then
  303. TreasureChestLogic_AddAutoNum(human, nBoxType, nBoxNum)
  304. end
  305. TreasureChestLogic_Query(human)
  306. end
  307. -- 请求自动打开宝箱
  308. function TreasureChestLogic_AutoOpen(human, nBoxType)
  309. local szText = "[TreasureChestLogic_AutoOpen] 玩家请求打开宝箱开始 nBoxType = "..nBoxType
  310. local tBoxTypeConf = TreasureChestLogic_GetBoxTypeConf()
  311. if not tBoxTypeConf[nBoxType] then
  312. print("[TreasureChestLogic_AutoOpen] 不存在对应的宝箱类型 nBoxType = "..nBoxType)
  313. szText = szText.." 失败不存在对应宝箱类型"
  314. TreasureChestLogic_WriteLog(human, szText)
  315. return
  316. end
  317. local nGoodsID = tBoxTypeConf[nBoxType].nItemID
  318. local nGoodsNum = TreasureChestLogic_GetGoodsNum(human, nGoodsID)
  319. if 0 >= nGoodsNum then
  320. return
  321. end
  322. if TreasureChestLogic_GetAutoOpenNum(human) < TREASURECHEST_OPEN_AUTO_NUM then
  323. return
  324. end
  325. TreasureChestLogic_WriteLog(human, szText)
  326. TreasureChestLogic_Open(human, nBoxType, 1)
  327. end
  328. -- 请求领取积分奖励
  329. function TreasureChestLogic_GetPointPrize(human, nID)
  330. local szText = "[TreasureChestLogic_GetPointPrize] 玩家请求领取积分奖励 nID = "..nID
  331. local tPointPrize = TreasureChestLogic_GetPointConf()
  332. if not tPointPrize[nID] then
  333. print("[TreasureChestLogic_GetPointPrize] 不存在对应的积分ID nID = "..nID)
  334. return
  335. end
  336. -- 积分检测
  337. local nNowPoint = TreasureChestLogic_GetDBPoint(human)
  338. if nNowPoint < tPointPrize[nID].nPoint then
  339. print("[TreasureChestLogic_GetPointPrize] 玩家当前积分不足 nNowPoint = "
  340. ..nNowPoint.." nNeedPoint = "..tPointPrize[nID].nPoint)
  341. return
  342. end
  343. local nState = TreasureChestLogic_GetDBPointPrize(human, nID)
  344. if CommonDefine.COMMON_PRIZE_STATE_CANGET ~= nState then
  345. print("[TreasureChestLogic_GetPointPrize] 玩家奖励状态不正确 nNowPoint = "
  346. ..nNowPoint.." nState = "..nState.."nID = "..nID)
  347. return
  348. end
  349. local tGoodsInfo =
  350. {
  351. [tPointPrize[nID].tPrize[1]] = tPointPrize[nID].tPrize[2]
  352. }
  353. -- 添加奖励
  354. BagLogic.addItemList(human, tGoodsInfo, "treasurechest")
  355. -- BagLogic.sendItemGetList(human, tGoodsInfo, "treasurechest")
  356. TreasureChestLogic_SetDBPointPrize(human, nID, CommonDefine.COMMON_PRIZE_STATE_GET)
  357. local szSendPrize = szText .. " 发送奖励成功 nGoodsID = "..tPointPrize[nID].tPrize[1]
  358. .." nGoodsNum = "..tPointPrize[nID].tPrize[2]
  359. TreasureChestLogic_WriteLog(human, szSendPrize)
  360. -- 改变积分
  361. local nNewPoint = nNowPoint - tPointPrize[nID].nPoint
  362. TreasureChestLogic_SetDBPoint(human, nNewPoint)
  363. local szPointPrize = szText.." nNowPoint = "..nNowPoint.." nDelPoint = "
  364. ..tPointPrize[nID].nPoint.." nNewPoint = "..nNewPoint
  365. TreasureChestLogic_WriteLog(human, szPointPrize)
  366. if 0 == tPointPrize[nID].nNextID then
  367. TreasureChestLogic_ResetDBPointPrize(human)
  368. local szResetText = szText.." 玩家领取完最后的奖励进行重置"
  369. TreasureChestLogic_WriteLog(human, szResetText)
  370. end
  371. -- 更新积分奖励状态
  372. TreasureChestLogic_UpdatePointPrize(human)
  373. TreasureChestLogic_Query(human)
  374. end
  375. function TreasureChestLogic_GmClear(human)
  376. TreasureChestLogic_CreateDB(human)
  377. end
  378. -- 增加道具
  379. function TreasureChestLogic_AddItem(human, nItemID, nAddNum)
  380. if not human.db.TreasureChest then
  381. TreasureChestLogic_CreateDB(human)
  382. end
  383. if 0 >= nAddNum then
  384. return
  385. end
  386. TreasureChestLogic_AddGoods(human, nItemID, nAddNum)
  387. TreasureChestLogic_WriteLog(human, "增加了宝箱道具 nItemID "..nItemID.." nAddNum "..nAddNum)
  388. end