PGRData/Script/matrix/xmanager/XGachaManager.lua

492 lines
20 KiB
Lua
Raw Normal View History

XGachaManagerCreator = function()
local GET_GACHA_DATA_INTERVAL = 15
local XGachaManager = {}
2024-09-01 20:49:41 +00:00
local ParseToTimestamp = XTime.ParseToTimestamp
-- 以下数据都要通过gachaId查找因为可能同时开多个卡池
local LastGetGachaRewardInfoTimes = {}
local GachaProbShows = {}
local GachaLogList = {}
2024-09-01 20:49:41 +00:00
local GachaRewardInfos = {}
local IsInfinite = {}
local CurCountOfAll = {}
local MaxCountOfAll = {}
local CurExchangeItemCount = {} -- 当前购买过的gacha币数量
local TotalGachaTimes = {}
local MissTimes = {} -- 保底次数
--
-- 卡池组状态
-- Key:number OrganizeId
-- Value:Table { gachaId = XGachaConfigs.OrganizeGachaStatus }
local GachaOrganizeStatus = {}
local METHOD_NAME = {
GetGachaInfo = "GetGachaInfoRequest",
Gacha = "GachaRequest",
GetGachaOrganizeInfo = "GetGachaOrganizeInfoRequest",
2024-09-01 20:49:41 +00:00
GachaItemExchangeRequest = "GachaItemExchangeRequest",
}
function XGachaManager.Init()
XGachaManager.SetGachaProbShowInfo()
2024-09-01 20:49:41 +00:00
local gachaCfg = XGachaConfigs.GetGachas()
for k, v in pairs(gachaCfg) do
XGachaManager.SetGachaRewardInfo(k)
IsInfinite[k] = false
CurCountOfAll[k] = 0
MaxCountOfAll[k] = 0
CurExchangeItemCount[k] = 0
TotalGachaTimes[k] = 0
MissTimes[k] = 0
end
end
function XGachaManager.GetMissTimes(gachaId)
return MissTimes[gachaId] or 0
end
function XGachaManager.GetCurExchangeItemCount(gachaId)
return CurExchangeItemCount[gachaId] or 0
end
function XGachaManager.GetTotalGachaTimes(gachaId)
return TotalGachaTimes[gachaId] or 0
end
function XGachaManager.GetGachaRewardInfoById(gaChaId)
local gachaCfg = XGachaConfigs.GetGachas()
2024-09-01 20:49:41 +00:00
MaxCountOfAll[gaChaId] = 0
CurCountOfAll[gaChaId] = 0
IsInfinite[gaChaId] = false
local groupIdList = {}
for _, groupId in pairs(gachaCfg[gaChaId].GroupId) do
table.insert(groupIdList, groupId)
end
local list = {}
2024-09-01 20:49:41 +00:00
for _, v in pairs(GachaRewardInfos[gaChaId]) do
for _, groupId in pairs(groupIdList) do
if v.GroupId == groupId then
table.insert(list, v)
break
end
end
end
for _, v in pairs(list) do
if v.RewardType == XGachaConfigs.RewardType.NotCount then
2024-09-01 20:49:41 +00:00
IsInfinite[gaChaId] = true
end
2024-09-01 20:49:41 +00:00
MaxCountOfAll[gaChaId] = MaxCountOfAll[gaChaId] + v.UsableTimes
CurCountOfAll[gaChaId] = CurCountOfAll[gaChaId] + (v.UsableTimes - v.CurCount)
end
table.sort(list, function(a, b)
if a.Priority == b.Priority then
return a.Id < b.Id
else
return a.Priority > b.Priority
end
end)
return list
end
2024-09-01 20:49:41 +00:00
function XGachaManager.IsClearMinimumGuarantee(gaChaId)
local gachaCfg = XGachaConfigs.GetGachaCfgById(gaChaId)
local data = XGachaManager.GetGachaRewardInfoById(gaChaId)
local isAllClear = true
for k, v in pairs(data) do
if v.CurCount > 0 and v.GroupId == gachaCfg.PropAddGroupId then
isAllClear = false
end
end
return isAllClear
end
-- 1核心层2第一层、、、
function XGachaManager.GetGachaRewardSplitByRareLevel(gaChaId)
local list = XGachaManager.GetGachaRewardInfoById(gaChaId)
local res = {}
for k, v in pairs(list) do
if XTool.IsNumberValid(v.Rarelevel) then
if not res[v.Rarelevel] then
res[v.Rarelevel] = {}
end
table.insert(res[v.Rarelevel], v)
end
end
return res
end
function XGachaManager.GetGachaProbShowById(gaChaId)
local gachaProbShowInfo = GachaProbShows[gaChaId]
if gachaProbShowInfo then
table.sort(gachaProbShowInfo, function(a, b)
if a.IsRare == b.IsRare then
return a.Id < b.Id
else
return a.IsRare == XGachaConfigs.RareType.Rare
end
end)
else
XLog.Error("ProbShows's Data Is Null By GachaId :"..gaChaId)
end
return gachaProbShowInfo
end
2024-09-01 20:49:41 +00:00
function XGachaManager.GetCurCountOfAll(gachaId)
return CurCountOfAll[gachaId] or 0
end
2024-09-01 20:49:41 +00:00
function XGachaManager.GetMaxCountOfAll(gachaId)
return MaxCountOfAll[gachaId] or 0
end
2024-09-01 20:49:41 +00:00
function XGachaManager.GetIsInfinite(gachaId)
if IsInfinite[gachaId] then
return true
end
return false
end
function XGachaManager.GetGachaLogById(gachaId)
return GachaLogList[gachaId] or {}
end
---
---@param notCheckDraw boolean 是否检测活动研发功能开启true:不检测false:检测
function XGachaManager.CheckGachaIsOpenById(id, IsShowText, notCheckDraw)
if IsShowText then
if not notCheckDraw and not XFunctionManager.DetectionFunction(XFunctionManager.FunctionName.ActivityDrawCard) then
return false
end
else
if not notCheckDraw and not XFunctionManager.JudgeCanOpen(XFunctionManager.FunctionName.ActivityDrawCard) then
return false
end
end
local gachaCfg = XGachaConfigs.GetGachas()
if not gachaCfg[id] then
XLog.Error("GachaId Is Not Exist :"..id)
return false
end
2024-09-01 20:49:41 +00:00
local timeId = gachaCfg[id].TimeId
local IsInTime = XFunctionManager.CheckInTimeByTimeId(timeId)
if IsShowText and not IsInTime then
local str = CS.XTextManager.GetText("GachaIsClose")
XUiManager.TipMsg(str)
end
2024-09-01 20:49:41 +00:00
-- if IsShowText and IsClose then
-- XUiManager.TipText("GachaIsClose")
-- end
return IsInTime
end
---
--- 检测扭蛋组是否开启
function XGachaManager.CheckGachaOrganizeIsOpen(organizeId, isShowText)
local startTimeStr, endTimeStr = XGachaConfigs.GetOrganizeTime(organizeId)
if not startTimeStr or not endTimeStr then
return false
end
local nowTime = XTime.GetServerNowTimestamp()
local startTime = ParseToTimestamp(startTimeStr)
local endTime = ParseToTimestamp(endTimeStr)
local IsNotOpen = startTime > nowTime
if isShowText and IsNotOpen then
local str = CS.XTextManager.GetText("GachaIsNotOpen", startTimeStr, endTimeStr)
XUiManager.TipMsg(str)
end
local IsClose = nowTime > endTime
if isShowText and IsClose then
XUiManager.TipText("GachaIsClose")
end
return (not IsClose) and (not IsNotOpen)
end
2024-09-01 20:49:41 +00:00
function XGachaManager.UpdateGachaRewardInfo(gridInfoList, gachaId)
for _, v in pairs(gridInfoList or {}) do
2024-09-01 20:49:41 +00:00
if GachaRewardInfos[gachaId][v.Id] then
GachaRewardInfos[gachaId][v.Id].CurCount = GachaRewardInfos[gachaId][v.Id].UsableTimes - v.Times
end
end
end
function XGachaManager.UpdateGachaLog(gachaId, logList)
GachaLogList = GachaLogList or {}
GachaLogList[gachaId] = logList
end
2024-09-01 20:49:41 +00:00
function XGachaManager.SetGachaRewardInfo(gachaId)
local gachaRewardCfg = XGachaConfigs.GetGachaReward()
2024-09-01 20:49:41 +00:00
local tempGachaInfo = GachaRewardInfos[gachaId]
if not tempGachaInfo then
GachaRewardInfos[gachaId] = {}
tempGachaInfo = GachaRewardInfos[gachaId]
end
for id, reward in pairs(gachaRewardCfg) do
2024-09-01 20:49:41 +00:00
tempGachaInfo[id] = {}
for k, v in pairs(reward) do
2024-09-01 20:49:41 +00:00
tempGachaInfo[id][k] = v
end
2024-09-01 20:49:41 +00:00
tempGachaInfo[id].CurCount = tempGachaInfo[id].UsableTimes
end
end
function XGachaManager.SetGachaProbShowInfo()
local gachaProbShowCfg = XGachaConfigs.GetGachaProbShows()
for _, probShow in pairs(gachaProbShowCfg) do
GachaProbShows[probShow.GachaId] = GachaProbShows[probShow.GachaId] or {}
table.insert(GachaProbShows[probShow.GachaId],probShow)
end
end
function XGachaManager.GetGachaRewardInfoRequest(gaChaId, cb)
local now = XTime.GetServerNowTimestamp()
if LastGetGachaRewardInfoTimes[gaChaId] and now - LastGetGachaRewardInfoTimes[gaChaId] <= GET_GACHA_DATA_INTERVAL then
cb()
return
end
XNetwork.Call(METHOD_NAME.GetGachaInfo, { Id = gaChaId }, function(res)
if res.Code ~= XCode.Success then
XUiManager.TipCode(res.Code)
return
end
2024-09-01 20:49:41 +00:00
XGachaManager.UpdateGachaRewardInfo(res.GridInfoList, gaChaId)
XGachaManager.UpdateGachaLog(gaChaId, res.GachaRecordList)
LastGetGachaRewardInfoTimes[gaChaId] = XTime.GetServerNowTimestamp()
2024-09-01 20:49:41 +00:00
CurExchangeItemCount[gaChaId] = res.CurExchangeItemCount
TotalGachaTimes[gaChaId] = res.TotalTimes
MissTimes[gaChaId] = res.MissTimes
cb(res)
end)
end
function XGachaManager.DoGacha(gaChaId, count, cb, errorCb, organizeId)
XNetwork.Call(METHOD_NAME.Gacha, { Id = gaChaId, Times = count }, function(res)
if res.Code ~= XCode.Success then
XUiManager.TipCode(res.Code)
if errorCb then
errorCb()
end
return
end
2024-09-01 20:49:41 +00:00
XGachaManager.UpdateGachaRewardInfo(res.GridInfoList, gaChaId)
XGachaManager.UpdateGachaLog(gaChaId, res.GachaRecordList)
2024-09-01 20:49:41 +00:00
TotalGachaTimes[gaChaId] = res.GachaCourseResult.TotalTimes
MissTimes[gaChaId] = res.MissTimes
local newUnlockGachaId
if organizeId then
newUnlockGachaId = XGachaManager.DrawUpdateOrganizeStatus(organizeId, gaChaId)
end
if cb then
cb(res.RewardList, newUnlockGachaId)
end
end)
end
---
--- 在进入界面的时候请求'organizeId'卡池组里的已售罄池子,以及最新解锁的池子的奖励信息
function XGachaManager.GetGachaOrganizeInfoRequest(organizeId, cb)
XNetwork.Call(METHOD_NAME.GetGachaOrganizeInfo, { OrganizeId = organizeId }, function(res)
if res.Code ~= XCode.Success then
XUiManager.TipCode(res.Code)
return
end
2024-09-01 20:49:41 +00:00
XGachaManager.UpdateGachaRewardInfo(res.GridInfoList, organizeId)
XGachaManager.UpdateGachaLog(res.CurrentId, res.GachaRecordList)
XGachaManager.OpenUpdateOrganizeStatus(organizeId, res.CurrentId, res.OutOfStockIdList)
if cb then
cb(res.CurrentId)
end
end)
end
--------------------------------------------Organize卡池状态相关------------------------------------------------------
---
--- 进入界面时更新卡池组的卡池状态
---
--- 'newestGachaId'为最新解锁的卡池Id它前面的卡池状态为正常或售罄后面的卡池状态为锁定
--- 'outSoldList'为已售罄卡池Id数组这样就不用发送所有卡池的奖励信息就能知道所有卡池的状态
function XGachaManager.OpenUpdateOrganizeStatus(organizeId, newestGachaId, outSoldList)
if not GachaOrganizeStatus[organizeId] then
GachaOrganizeStatus[organizeId] = {}
end
-- 设置已售罄卡池
for _, gachaId in ipairs(outSoldList) do
if not GachaOrganizeStatus[organizeId][gachaId] then
GachaOrganizeStatus[organizeId][gachaId] = XGachaConfigs.OrganizeGachaStatus.SoldOut
end
-- 进入界面时,客户端缓存的售馨卡池与服务器下发的售罄卡池不同步
if GachaOrganizeStatus[organizeId][gachaId] ~= XGachaConfigs.OrganizeGachaStatus.SoldOut then
XLog.Error(string.format("XGachaManager.UpdateOrganizeGachaStatus函数错误服务器下发的最新卡池Id为%s卡池组%s的卡池%s状态与服务器不同步客户端的为未售罄状态",
tostring(newestGachaId), tostring(organizeId), tostring(gachaId)))
GachaOrganizeStatus[organizeId][gachaId] = XGachaConfigs.OrganizeGachaStatus.SoldOut
end
end
local organizeGachaIdList = XGachaConfigs.GetOrganizeGahcaIdList(organizeId) -- organizeId组的所有gachaId数组已根据Sort排序
local newestGachaIndex = XGachaConfigs.GetOrganizeIndex(organizeId, newestGachaId) -- 最新解锁卡池在organizeGachaIdList数组里的序号
if not newestGachaIndex then
return
end
-- 最新解锁卡池前面的卡池为已解锁或售罄,后面的为锁定
for index, gachaId in ipairs(organizeGachaIdList) do
if index <= newestGachaIndex then
if not GachaOrganizeStatus[organizeId][gachaId] then
GachaOrganizeStatus[organizeId][gachaId] = XGachaConfigs.OrganizeGachaStatus.Normal
end
-- 进入界面时,客户端缓存的 newestGachaId卡池前面的卡池的状态 为锁定,说明状态与服务器不同步
if GachaOrganizeStatus[organizeId][gachaId] == XGachaConfigs.OrganizeGachaStatus.Lock then
XLog.Error(string.format("XGachaManager.UpdateOrganizeGachaStatus函数错误服务器下发的最新卡池Id为%s卡池组%s的卡池%s状态与服务器不同步客户端的为上锁状态",
tostring(newestGachaId), tostring(organizeId), tostring(gachaId)))
GachaOrganizeStatus[organizeId][gachaId] = XGachaConfigs.OrganizeGachaStatus.Normal
end
else
if not GachaOrganizeStatus[organizeId][gachaId] then
GachaOrganizeStatus[organizeId][gachaId] = XGachaConfigs.OrganizeGachaStatus.Lock
end
-- 进入界面时,客户端缓存的 newestGachaId卡池后面的卡池的状态为正常说明状态与服务器不同步
if GachaOrganizeStatus[organizeId][gachaId] == XGachaConfigs.OrganizeGachaStatus.Normal then
XLog.Error(string.format("XGachaManager.UpdateOrganizeGachaStatus函数错误服务器下发的最新卡池Id为%s卡池组%s的卡池%s状态与服务器不同步客户端的为正常状态",
tostring(newestGachaId), tostring(organizeId), tostring(gachaId)))
GachaOrganizeStatus[organizeId][gachaId] = XGachaConfigs.OrganizeGachaStatus.Lock
end
end
end
end
--- 抽卡后更新卡池组的卡池状态
--- 如果解锁了新卡池则返回该卡池Id
---@return number
function XGachaManager.DrawUpdateOrganizeStatus(organizeId, DrawingGachaId)
if not GachaOrganizeStatus[organizeId] then
XLog.Error(string.format("XGachaManager.DrawUpdateOrganizeStatus函数错误卡池组%s的状态数据为空",
tostring(organizeId)))
GachaOrganizeStatus[organizeId] = {}
end
local isSoldOutRare = true -- 特殊奖励是否售罄
local isSoldOut = true -- 全部奖励是否售罄
local groupIdList = {}
-- 是否无限次数
2024-09-01 20:49:41 +00:00
if IsInfinite[DrawingGachaId] then
isSoldOut = false
else
-- 找出DrawingGachaId的奖励
local gachaCfg = XGachaConfigs.GetGachas()
for _, groupId in pairs(gachaCfg[DrawingGachaId].GroupId) do
table.insert(groupIdList, groupId)
end
2024-09-01 20:49:41 +00:00
for _, v in pairs(GachaRewardInfos[DrawingGachaId]) do
-- 是否属于DrawingGachaId的奖励组
for _, groupId in pairs(groupIdList) do
if v.GroupId == groupId and v.CurCount ~= 0 then
isSoldOut = false
if v.Rare then
isSoldOutRare = false
end
break
end
end
end
end
if isSoldOut then
GachaOrganizeStatus[organizeId][DrawingGachaId] = XGachaConfigs.OrganizeGachaStatus.SoldOut
end
local isUnlockNext
if isSoldOutRare then
-- 是否解锁了新的卡池62504
local nextGachaStatus, nextGachaId = XGachaManager.GetOrganizeNextGachaStatus(organizeId, DrawingGachaId)
if nextGachaStatus and nextGachaId then
if nextGachaStatus == XGachaConfigs.OrganizeGachaStatus.Lock then
GachaOrganizeStatus[organizeId][nextGachaId] = XGachaConfigs.OrganizeGachaStatus.Normal
isUnlockNext = nextGachaId
end
end
end
return isUnlockNext
end
---
--- 获取''organizeId'卡池组内'gachaId'卡池的状态
function XGachaManager.GetOrganizeGachaStatus(organizeId, gachaId)
if not gachaId or gachaId == 0 then
return
end
if GachaOrganizeStatus[organizeId] then
if GachaOrganizeStatus[organizeId][gachaId] then
return GachaOrganizeStatus[organizeId][gachaId]
else
XLog.Error(string.format("XGachaManager.GetOrganizeGachaStatus函数错误卡池%s的状态数据为空", gachaId))
end
else
XLog.Error(string.format("XGachaManager.GetOrganizeGachaStatus函数错误卡池组%s的状态数据为空", organizeId))
end
return XGachaConfigs.OrganizeGachaStatus.Lock
end
---
--- 获取''organizeId'卡池组内'gachaId'前一个卡池的状态与Id
---
--- 如果'gachaId'是第一个卡池则返回nil
function XGachaManager.GetOrganizePreGachaStatus(organizeId, gachaId)
local preGachaId = XGachaConfigs.GetOrganizePreGachaId(organizeId, gachaId)
local status = XGachaManager.GetOrganizeGachaStatus(organizeId, preGachaId)
if status then
return status, preGachaId
end
end
---
--- 获取''organizeId'卡池组内'gachaId'后一个卡池的状态与Id
---
--- 如果'gachaId'是最后一个卡池则返回nil
function XGachaManager.GetOrganizeNextGachaStatus(organizeId, gachaId)
local nextGachaId = XGachaConfigs.GetOrganizeNextGachaId(organizeId, gachaId)
local status = XGachaManager.GetOrganizeGachaStatus(organizeId, nextGachaId)
if status then
return status, nextGachaId
end
end
2024-09-01 20:49:41 +00:00
function XGachaManager.BuyTicket(gachaId, buyCount, ticketKey, cb)
XNetwork.Call(METHOD_NAME.GachaItemExchangeRequest, { Id = gachaId, ExchangeNum = buyCount, SelectIndex = ticketKey }, function(res)
if res.Code ~= XCode.Success then
XUiManager.TipCode(res.Code)
return
end
CurExchangeItemCount[gachaId] = res.CurExchangeItemCount
local reward = XRewardManager.CreateRewardGoodsByTemplate({ TemplateId = res.GainItemId, Count = res.GainItemCount })
if cb then cb({ reward }) end
end)
end
--------------------------------------------------------------------------------------------------------------------
XGachaManager.Init()
return XGachaManager
end