-------------------------------- -- 文件名 : TreasureChestLogic.lua -- 文件说明 : 宝箱系统 -- 创建时间 : 2025/03/10 -- 创建人 : FC -------------------------------- --- local Util = require("common.Util") local Msg = require("core.Msg") local BagLogic = require("bag.BagLogic") local Log = require("common.Log") local TreasureConf = require("excel.treasurechest") local CommonDefine = require("common.CommonDefine") local Grid = require("bag.Grid") local MainDianLogic = require("MaiDian.MaiDianLogic") local MaiDianDefine = require("MaiDian.MaiDianDefine") local TriggerDefine = require("trigger.TriggerDefine") local TriggerLogic = require("trigger.TriggerLogic") local WeekTaskLogic = require("dailyTask.WeekTaskLogic") -- 奖励缓存有序 key为宝箱类型 local tCacheBoxPrize = nil -- 一次性最多打开宝箱数量 local TREASURECHEST_OPEN_NUM = 9999 -- 自动开宝箱解锁条件 local TREASURECHEST_OPEN_AUTO_TYPE = 5 -- 钻石 local TREASURECHEST_OPEN_AUTO_NUM = 2 -- 开两次 local TREASURECHEST_OPEN_ONETOUCH_NUM = 10 -- 激活一键开启宝箱功能, 需要开启钻石宝箱数量 ----------------------------------------- 内部处理开始 ------------------------------------- -- 写日志 local function TreasureChestLogic_WriteLog(human, szText) Log.write(Log.LOGID_OSS_COMMON, "name = "..human.db.name.." id = "..human.db._id..szText) end -- 获取宝箱配置 local function TreasureChestLogic_GetBoxTypeConf() return TreasureConf.boxtype end -- 获取宝箱积分配置 local function TreasureChestLogic_GetPointConf() return TreasureConf.boxpoint end -- 重置积分奖励数据 local function TreasureChestLogic_ResetDBPointPrize(human) local tBoxPoint = TreasureChestLogic_GetPointConf() for key, v in pairs(tBoxPoint) do human.db.TreasureChest.tPointPrize[key] = CommonDefine.COMMON_PRIZE_STATE_NOGET end end -- 创建DB数据 local function TreasureChestLogic_CreateDB(human) human.db.TreasureChest = { nPoint = 0, nOpenNum = 0, tPointPrize = {}, tItem = {}, -- 宝箱数量 openBoxSumNum = 0, -- 开启宝箱总数量 } TreasureChestLogic_ResetDBPointPrize(human) end -- 获取开启总宝箱数量 local function TreasureChestLogic_GetDBOpenBoxSumNum(human) if not human.db.TreasureChest then TreasureChestLogic_CreateDB(human) end return human.db.TreasureChest.openBoxSumNum end -- 增加宝箱开启数量 local function TreasureChestLogic_AddDBOpenBoxSumNum(human, nValue) if not human.db.TreasureChest then TreasureChestLogic_CreateDB(human) end human.db.TreasureChest.openBoxSumNum = (human.db.TreasureChest.openBoxSumNum or 0) + nValue end -- 获取宝箱奖励配置 local function TreasureChestLogic_GetPointPrizeConf(human) local openBoxSumNum = TreasureChestLogic_GetDBOpenBoxSumNum(human) --if not tCacheBoxPrize then tCacheBoxPrize = {} for _, v in pairs(TreasureConf.boxprize) do local nType = v.nType if not tCacheBoxPrize[nType] then tCacheBoxPrize[nType] = {} end -- table.insert(tCacheBoxPrize[nType], v) if openBoxSumNum >= v.count then table.insert(tCacheBoxPrize[nType], v) end end -- 变成有序 for _, v in pairs(tCacheBoxPrize) do table.sort(v, function (l, r) return l.nPro < r.nPro end) end -- 整合权重 for _, data in ipairs(tCacheBoxPrize) do local nAllWeight = 0 for _, v in ipairs(data) do if nAllWeight == 0 then nAllWeight = v.nPro else nAllWeight = nAllWeight + v.nPro end v.nAllPro = nAllWeight end end --end return tCacheBoxPrize end -- 获取当前积分 local function TreasureChestLogic_GetDBPoint(human) if not human.db.TreasureChest then TreasureChestLogic_CreateDB(human) end return human.db.TreasureChest.nPoint end -- 设置当前积分 local function TreasureChestLogic_SetDBPoint(human, nValue) if not human.db.TreasureChest then TreasureChestLogic_CreateDB(human) end human.db.TreasureChest.nPoint = nValue end -- 获取当前积分奖励状态 local function TreasureChestLogic_GetDBPointPrize(human, nID) if not human.db.TreasureChest then TreasureChestLogic_CreateDB(human) end return human.db.TreasureChest.tPointPrize[nID] end -- 设置当前积分奖励状态 local function TreasureChestLogic_SetDBPointPrize(human, nID, nState) if not human.db.TreasureChest then TreasureChestLogic_CreateDB(human) end human.db.TreasureChest.tPointPrize[nID] = nState end -- 更新积分奖励状态 local function TreasureChestLogic_UpdatePointPrize(human) local nNowPoint = TreasureChestLogic_GetDBPoint(human) local tBoxPointCof = TreasureChestLogic_GetPointConf() for nID, v in ipairs(tBoxPointCof) do local nState = TreasureChestLogic_GetDBPointPrize(human, nID) if nNowPoint >= v.nPoint then --print("[TreasureChestLogic_UpdatePointPrize] nID = "..nID.." nNowPoint "..nNowPoint.." nPoint "..v.nPoint.." nState "..nState) if CommonDefine.COMMON_PRIZE_STATE_NOGET == nState then TreasureChestLogic_SetDBPointPrize(human, nID, CommonDefine.COMMON_PRIZE_STATE_CANGET) nNowPoint = nNowPoint - v.nPoint elseif CommonDefine.COMMON_PRIZE_STATE_CANGET == nState then nNowPoint = nNowPoint - v.nPoint end else if CommonDefine.COMMON_PRIZE_STATE_NOGET == nState then break end end end end -- 打开宝箱操作 local function TreasureChestLogic_OpenBox(human, nType, nBoxNum) local tBoxTypeConf = TreasureChestLogic_GetBoxTypeConf() local tBoxPrize = TreasureChestLogic_GetPointPrizeConf(human) if not tBoxTypeConf[nType] or not tBoxPrize[nType] then return nil end local nOpenNum = tBoxTypeConf[nType].nOpenNum -- 获取的表是有序的 local tBoxTypePrize = tBoxPrize[nType] local nLen = #tBoxTypePrize local nAllWeight = tBoxTypePrize[nLen].nAllPro --print("[TreasureChestLogic_OpenBox] nAllWeight = "..nAllWeight) local tOpenPrize = {} for i = 1, nBoxNum, 1 do for j = 1, nOpenNum, 1 do -- 随机权重 local nRandNum = math.random(1, nAllWeight) --print("[TreasureChestLogic_OpenBox] j = "..j.." nRandNum = "..nRandNum) for _, v in pairs(tBoxTypePrize) do --print("[TreasureChestLogic_OpenBox] nAllPro = "..v.nAllPro.." ID = "..v.tPrize[1].." num = "..v.tPrize[2].."\n") if nRandNum <= v.nAllPro then table.insert(tOpenPrize, v.tPrize) --print("[TreasureChestLogic_OpenBox] 获得的道具 nID = "..v.tPrize[1].." nNum = "..v.tPrize[2].." nKey "..v.nAllPro) TreasureChestLogic_AddDBOpenBoxSumNum(human, 1) break end end tBoxPrize = TreasureChestLogic_GetPointPrizeConf(human) tBoxTypePrize = tBoxPrize[nType] nLen = #tBoxTypePrize nAllWeight = tBoxTypePrize[nLen].nAllPro end end return tOpenPrize end -- 获取宝箱数量 local function TreasureChestLogic_GetGoodsNum(human, nGoodsID) if not human.db.TreasureChest.tItem[nGoodsID] then human.db.TreasureChest.tItem[nGoodsID] = 0 end return human.db.TreasureChest.tItem[nGoodsID] end -- 添加宝箱物品 local function TreasureChestLogic_AddGoods(human, nGoodsID, nGoodsNum) if not human.db.TreasureChest.tItem[nGoodsID] then human.db.TreasureChest.tItem[nGoodsID] = 0 end human.db.TreasureChest.tItem[nGoodsID] = human.db.TreasureChest.tItem[nGoodsID] + nGoodsNum end -- 删除物品 local function TreasureChestLogic_DelGoods(human, nGoodsID, nGoodsNum) human.db.TreasureChest.tItem[nGoodsID] = human.db.TreasureChest.tItem[nGoodsID] - nGoodsNum if 0 > human.db.TreasureChest.tItem[nGoodsID] then human.db.TreasureChest.tItem[nGoodsID] = 0 end TreasureChestLogic_WriteLog(human, "减少了宝箱道具 nItemID "..nGoodsID.." nDelNum "..nGoodsNum) end -- 获取当前打开的钻石宝箱数量 local function TreasureChestLogic_GetAutoOpenNum(human) if not human.db.TreasureChest then TreasureChestLogic_CreateDB(human) end return human.db.TreasureChest.nOpenNum end -- 记录打开钻石宝箱数量 local function TreasureChestLogic_AddAutoNum(human, nType, nNum) if TREASURECHEST_OPEN_AUTO_TYPE ~= nType then print("[TreasureChestLogic_AddAutoNum] 类型不正确返回") return end -- local nNowNum = TreasureChestLogic_GetAutoOpenNum(human) -- if TREASURECHEST_OPEN_AUTO_NUM <= nNowNum then -- print("[TreasureChestLogic_AddAutoNum] 数量已经足够 nNowNum = "..nNowNum) -- return -- end local nNowNum = TreasureChestLogic_GetAutoOpenNum(human) if TREASURECHEST_OPEN_ONETOUCH_NUM <= nNowNum then print("[TreasureChestLogic_AddAutoNum] 数量已经足够 nNowNum = "..nNowNum) return end human.db.TreasureChest.nOpenNum = human.db.TreasureChest.nOpenNum + nNum if human.db.TreasureChest.nOpenNum >= TREASURECHEST_OPEN_ONETOUCH_NUM then TreasureChestLogic_Query(human) end end -- 处理老数据 local function openBoxSumNumCheck(human) local num = TreasureChestLogic_GetDBOpenBoxSumNum(human) if not num then TreasureChestLogic_AddDBOpenBoxSumNum(human, 2300) end end ----------------------------------------- 客户端请求 ------------------------------------- -- 请求宝箱界面信息 function TreasureChestLogic_Query(human) if not human then return end if not human.db.TreasureChest then TreasureChestLogic_CreateDB(human) end TreasureChestLogic_UpdatePointPrize(human) -- table.print_lua_table(human.db.TreasureChest) -- print("\n") --local nOpenNum = TreasureChestLogic_GetAutoOpenNum(human) local tMsgData = Msg.gc.GC_TEEASURECHEST_QUERY tMsgData.nNowPoint = TreasureChestLogic_GetDBPoint(human) -- tMsgData.nAuto = TreasureChestLogic_GetAutoOpenNum(human) >= TREASURECHEST_OPEN_AUTO_NUM and 1 or 0 tMsgData.nAuto = 1 --改为默认开启 tMsgData.nOneTouch = TreasureChestLogic_GetAutoOpenNum(human) >= TREASURECHEST_OPEN_ONETOUCH_NUM and 1 or 0 tMsgData.nID = 0 tMsgData.nNextPoint = 0 tMsgData.nState = 0 local tBoxPointConf = TreasureChestLogic_GetPointConf() local tBoxTypeConf = TreasureChestLogic_GetBoxTypeConf() --print("[TreasureChestLogic_Query] nAuto = "..tMsgData.nAuto.." num = "..nOpenNum) -- 下一阶段需要的积分信息 for nID, v in ipairs(tBoxPointConf) do local nState = TreasureChestLogic_GetDBPointPrize(human, nID) if CommonDefine.COMMON_PRIZE_STATE_NOGET == nState or CommonDefine.COMMON_PRIZE_STATE_CANGET == nState then tMsgData.nID = nID tMsgData.nNextPoint = v.nPoint tMsgData.nState = nState Grid.makeItem(tMsgData.tPointPirze, v.tPrize[1], v.tPrize[2]) break end end -- 奖励信息 local nLen = 0 for nType, v in pairs(tBoxTypeConf) do nLen = nLen + 1 tMsgData.tList[0] = nLen local tData = tMsgData.tList[nLen] tData.nType = nType local nGoodsID = v.nItemID local nGoodsNum = TreasureChestLogic_GetGoodsNum(human, nGoodsID) Grid.makeItem(tData.tItemData, nGoodsID, nGoodsNum) end Msg.send(tMsgData, human.fd) end -- 请求宝箱内奖励信息 function TreasureChestLogic_QueryPrize(human, nBoxType) local tBoxPrize = TreasureChestLogic_GetPointPrizeConf() if not tBoxPrize[nBoxType] then print("[TreasureChestLogic_QueryPrize] 不存在对应的奖励配置 nBoxType = "..nBoxType) return end local tBoxTypePrize = tBoxPrize[nBoxType] local tMsgData = Msg.gc.GC_TEEASURECHEST_PRIZE_QUERY local nLen = 0 tMsgData.tItemData[0] = nLen for _, v in pairs(tBoxTypePrize) do nLen = nLen + 1 tMsgData.tItemData[0] = nLen local tData = tMsgData.tItemData[nLen] local nGoodsID = v.prize[1] local nGoodsNum = v.prize[2] local quality = v.prize[3] Grid.makeItem(tData, nGoodsID, nGoodsNum, nil, nil, nil, nil, quality) end Msg.send(tMsgData, human.fd) end -- 请求打开宝箱 function TreasureChestLogic_Open(human, nBoxType, nBoxNum) openBoxSumNumCheck(human) print("[TreasureChestLogic_Open]玩家当前请求打开的宝箱类型 ntyepe = "..nBoxType) local szText = "[TreasureChestLogic_Open] 玩家请求打开宝箱 nBoxType = "..nBoxType.." nBoxNum = "..nBoxNum TreasureChestLogic_WriteLog(human, szText) if nBoxNum >= TREASURECHEST_OPEN_NUM or 0 >= nBoxNum then szText = szText .. " 失败不正确的打开数量 nBoxNum "..nBoxNum TreasureChestLogic_WriteLog(human, szText) return end -- 检测配置 local tBoxTypeConf = TreasureChestLogic_GetBoxTypeConf() if not tBoxTypeConf[nBoxType] then print("[TreasureChestLogic_Open] 不存在对应的宝箱类型 nBoxType = "..nBoxType) szText = szText.." 失败不存在对应宝箱类型" TreasureChestLogic_WriteLog(human, szText) return end local nGoodsID = tBoxTypeConf[nBoxType].nItemID local nGoodsNum = TreasureChestLogic_GetGoodsNum(human, nGoodsID) if nBoxNum > nGoodsNum or 0 >= nGoodsNum then print("[TreasureChestLogic_Open] 玩家拥有宝箱数量不足 nBoxType = " ..nBoxType.." nBoxNum = "..nBoxNum.." nGoodsNum = "..nGoodsNum) szText = szText.." 数量不正确 nGoodsNum = "..nGoodsNum TreasureChestLogic_WriteLog(human, szText) return end local tPrize = TreasureChestLogic_OpenBox(human, nBoxType, nBoxNum) -- 发送奖励 BagLogic.addItemList(human, tPrize, "treasurechest") --BagLogic.sendItemGetList(human, tPrize, "treasurechest") szText = szText .." 发送奖励成功" TreasureChestLogic_WriteLog(human, szText) -- 加积分 local nAddPoint = nBoxNum * tBoxTypeConf[nBoxType].nPoint local nNowPoint = TreasureChestLogic_GetDBPoint(human) nNowPoint = nAddPoint + nNowPoint TreasureChestLogic_SetDBPoint(human, nNowPoint) szText = szText.." 增加积分 nAddPoint = "..nAddPoint.." nNowPoint = "..nNowPoint TreasureChestLogic_WriteLog(human, szText) -- 删除使用了的物品 TreasureChestLogic_DelGoods(human, nGoodsID, nBoxNum) -- 更新积分奖励状态 TreasureChestLogic_UpdatePointPrize(human) MainDianLogic.MaiDian_Begin(human, MaiDianDefine.MAIDIAN_TYPE_CHEST_OPEN,{nValue = nBoxNum}) if TREASURECHEST_OPEN_AUTO_TYPE == nBoxType then TreasureChestLogic_AddAutoNum(human, nBoxType, nBoxNum) end TriggerLogic.PublishEvent(TriggerDefine.EVENT_TYPE_OPENBOX, human.db._id, nBoxNum,nBoxType) print("TreasureChestLogic..当前已经进入商业活动注册事件",nBoxType) --周任务开启宝箱 WeekTaskLogic.recordWeekTaskFinishCnt(human, WeekTaskLogic.WEEK_TASK_ID_5, nBoxNum) TreasureChestLogic_Query(human) TreasureChestLogic_GetAllBoxNum(human) end -- 请求自动打开宝箱 function TreasureChestLogic_AutoOpen(human, nBoxType) local szText = "[TreasureChestLogic_AutoOpen] 玩家请求打开宝箱开始 nBoxType = "..nBoxType local tBoxTypeConf = TreasureChestLogic_GetBoxTypeConf() if not tBoxTypeConf[nBoxType] then print("[TreasureChestLogic_AutoOpen] 不存在对应的宝箱类型 nBoxType = "..nBoxType) szText = szText.." 失败不存在对应宝箱类型" TreasureChestLogic_WriteLog(human, szText) return end local nGoodsID = tBoxTypeConf[nBoxType].nItemID local nGoodsNum = TreasureChestLogic_GetGoodsNum(human, nGoodsID) if 0 >= nGoodsNum then return end -- 改为默认开启 -- if TreasureChestLogic_GetAutoOpenNum(human) < TREASURECHEST_OPEN_AUTO_NUM then -- return -- end TreasureChestLogic_WriteLog(human, szText) TreasureChestLogic_Open(human, nBoxType, 1) TreasureChestLogic_GetAllBoxNum(human) end -- 请求领取积分奖励 function TreasureChestLogic_GetPointPrize(human, nID) local szText = "[TreasureChestLogic_GetPointPrize] 玩家请求领取积分奖励 nID = "..nID local tPointPrize = TreasureChestLogic_GetPointConf() if not tPointPrize[nID] then print("[TreasureChestLogic_GetPointPrize] 不存在对应的积分ID nID = "..nID) return end -- 积分检测 local nNowPoint = TreasureChestLogic_GetDBPoint(human) if nNowPoint < tPointPrize[nID].nPoint then print("[TreasureChestLogic_GetPointPrize] 玩家当前积分不足 nNowPoint = " ..nNowPoint.." nNeedPoint = "..tPointPrize[nID].nPoint) return end local nState = TreasureChestLogic_GetDBPointPrize(human, nID) if CommonDefine.COMMON_PRIZE_STATE_CANGET ~= nState then print("[TreasureChestLogic_GetPointPrize] 玩家奖励状态不正确 nNowPoint = " ..nNowPoint.." nState = "..nState.."nID = "..nID) return end local tGoodsInfo = { [tPointPrize[nID].tPrize[1]] = tPointPrize[nID].tPrize[2] } -- 添加奖励 BagLogic.addItemList(human, tGoodsInfo, "treasurechest") -- BagLogic.sendItemGetList(human, tGoodsInfo, "treasurechest") TreasureChestLogic_SetDBPointPrize(human, nID, CommonDefine.COMMON_PRIZE_STATE_GET) local szSendPrize = szText .. " 发送奖励成功 nGoodsID = "..tPointPrize[nID].tPrize[1] .." nGoodsNum = "..tPointPrize[nID].tPrize[2] TreasureChestLogic_WriteLog(human, szSendPrize) -- 改变积分 local nNewPoint = nNowPoint - tPointPrize[nID].nPoint TreasureChestLogic_SetDBPoint(human, nNewPoint) local szPointPrize = szText.." nNowPoint = "..nNowPoint.." nDelPoint = " ..tPointPrize[nID].nPoint.." nNewPoint = "..nNewPoint TreasureChestLogic_WriteLog(human, szPointPrize) if 0 == tPointPrize[nID].nNextID then TreasureChestLogic_ResetDBPointPrize(human) local szResetText = szText.." 玩家领取完最后的奖励进行重置" TreasureChestLogic_WriteLog(human, szResetText) end -- 更新积分奖励状态 TreasureChestLogic_UpdatePointPrize(human) TreasureChestLogic_Query(human) TreasureChestLogic_GetAllBoxNum(human) end --请求一件开启宝箱 function TreasureChestLogic_OneTouchOpen(human) local boxCfg = TreasureChestLogic_GetBoxTypeConf() for boxType, boxInfo in ipairs(boxCfg) do local nGoodsID = boxInfo.nItemID local nGoodsNum = TreasureChestLogic_GetGoodsNum(human, nGoodsID) if nGoodsNum > 0 then TreasureChestLogic_Open(human, boxType, nGoodsNum) end end TreasureChestLogic_GetAllBoxNum(human) end function TreasureChestLogic_GmClear(human) TreasureChestLogic_CreateDB(human) end -- 增加道具 function TreasureChestLogic_AddItem(human, nItemID, nAddNum) if not human.db.TreasureChest then TreasureChestLogic_CreateDB(human) end if 0 >= nAddNum then return end TreasureChestLogic_AddGoods(human, nItemID, nAddNum) TreasureChestLogic_WriteLog(human, "增加了宝箱道具 nItemID "..nItemID.." nAddNum "..nAddNum) end -- 购买终身月卡解锁自动开宝箱 function TreasureChestLogic_BuyOpenAuto(human) --local nOpenNum = TreasureChestLogic_GetAutoOpenNum(human) --print("[TreasureChestLogic_BuyOpenAuto] nOpenNum = "..nOpenNum) -- TreasureChestLogic_AddAutoNum(human, TREASURECHEST_OPEN_AUTO_TYPE, TREASURECHEST_OPEN_AUTO_NUM) TreasureChestLogic_AddAutoNum(human, TREASURECHEST_OPEN_AUTO_TYPE, TREASURECHEST_OPEN_ONETOUCH_NUM) end function TreasureChestLogic_GetAllBoxNum(human) if not human.db.TreasureChest then TreasureChestLogic_CreateDB(human) end local tBoxTypeConf = TreasureChestLogic_GetBoxTypeConf() local tMsgData = Msg.gc.GC_GET_ALL_GJBOX_NUM local nAllNum = 0 for nType, v in pairs(tBoxTypeConf) do local nGoodsID = v.nItemID local nGoodsNum = TreasureChestLogic_GetGoodsNum(human, nGoodsID) nAllNum = nAllNum + nGoodsNum end tMsgData.nAllNum = nAllNum Msg.send(tMsgData, human.fd) end