Files
Endfield-Data/LuaScripts/Common/Utils/RedDotUtils.lua
2026-01-31 21:42:01 +07:00

448 lines
14 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
local RedDotUtils = {}
function RedDotUtils.hasGemNotEquipped()
local gemDepot = GameInstance.player.inventory.valuableDepots[GEnums.ItemValuableDepotType.WeaponGem]:GetOrFallback(Utils.getCurrentScope())
if not gemDepot then
return false
end
local gemInstDict = gemDepot.instItems
for _, itemBundle in pairs(gemInstDict) do
local gemInst = itemBundle.instData
if gemInst and gemInst.weaponInstId <= 0 then
return true
end
end
return false
end
function RedDotUtils.hasBlocShopDiscountShopItem(blocId)
local shopInfo = GameInstance.player.blocManager:GetBlocShopInfo(blocId)
if not shopInfo then
logger.error("RedDotUtils->hasBlocShopDiscountShopItem: shopInfo is nil, blocId", blocId)
return false
end
local shopId = shopInfo.Shopid
local discountInfoMaps = {}
for k = 0, shopInfo.DiscountInfo.Count - 1 do
local v = shopInfo.DiscountInfo[k]
discountInfoMaps[v.Posid] = v.Discount
end
local shopItemMap = Tables.blocShopItemTable[shopId]
if not shopItemMap then
logger.error("RedDotUtils->hasBlocShopDiscountShopItem: shopItemMap is nil, shopId", shopId)
return false
end
local blocInfo = GameInstance.player.blocManager:GetBlocInfo(blocId)
if not blocInfo then
logger.error("RedDotUtils->hasBlocShopDiscountShopItem: blocInfo is nil, blocId", blocId)
return false
end
local blocLv = blocInfo.Level
for lv, items in pairs(shopItemMap.map) do
if lv <= blocLv then
for _, v in pairs(items.list) do
local _, soldCount = shopInfo.AlreadySellCount:TryGetValue(v.id)
local count = v.availCount - soldCount
local isDiscount = discountInfoMaps[v.id] ~= nil
if isDiscount and count > 0 then
return true
end
end
end
end
return false
end
function RedDotUtils.hasCheckInRewardsNotCollected()
local activitySystem = GameInstance.player.activitySystem;
local checkInSystem = activitySystem:GetActivity(UIConst.CHECK_IN_CONST.CBT2_CHECK_IN_ID)
if not checkInSystem then
return false
end
if checkInSystem.rewardDays >= checkInSystem.loginDays then
return false
end
local maxRewardDays = #Tables.checkInRewardTable
return checkInSystem.rewardDays < maxRewardDays
end
function RedDotUtils.hasCheckInRewardsNotCollectedInRange(args)
if args.checkInActivity.loginDays == args.checkInActivity.rewardDays then
return false
end
if args.checkInActivity.rewardDays >= args.lastDay then
return false
end
if args.checkInActivity.loginDays < args.firstDay then
return false
end
return true
end
function RedDotUtils.hasCraftRedDot(craftId)
return false
end
function RedDotUtils.readRedDot(systemType, id)
if isRead(systemType, id) then
return
end
local msg = LegacyMockNet.ReadRedDot()
msg.type = systemType
msg.ids = {id}
LegacyLuaNetBus.Send(msg)
end
function RedDotUtils.readRedDots(systemType, ids)
local msg = LegacyMockNet.ReadRedDot()
msg.type = systemType
msg.ids = ids
LegacyLuaNetBus.Send(msg)
end
function RedDotUtils.hasPrtsNoteRedDot(investCfg)
for _, data in pairs(investCfg.categoryDataList) do
for _, id in pairs(data.noteIdList) do
if GameInstance.player.prts:IsNoteUnread(id) then
return true
end
end
end
return false
end
function RedDotUtils.hasSettlementCanUpgradeRedDot(settlementId)
local stlData = GameInstance.player.settlementSystem:GetUnlockSettlementData(settlementId)
if stlData == nil then
return false
end
local stlCfg = Tables.settlementBasicDataTable[settlementId]
local stlLevelCfg = stlCfg.settlementLevelMap[stlData.level]
local curExp = stlData.exp
local maxExp = stlLevelCfg.levelUpExp
local canUpgrade = maxExp ~= 0 and curExp >= maxExp
return canUpgrade
end
function RedDotUtils.hasActivityNormalChallengeSeriesRedDot(seriesId)
local activitySystem = GameInstance.player.activitySystem
local isUnlock = activitySystem:IsGameEntranceSeriesUnlock(seriesId)
if not isUnlock then
return false
end
if ActivityUtils.isNewGameEntranceSeries(seriesId) then
return true, UIConst.RED_DOT_TYPE.New
end
local gameMechanicsSystem = GameInstance.player.subGameSys
local _, activityGameCfg = Tables.activityGameEntranceGameTable:TryGetValue(seriesId)
for _, gameCfg in pairs(activityGameCfg.gameList) do
if gameMechanicsSystem:IsGameUnlocked(gameCfg.gameId) and gameMechanicsSystem:IsGameUnread(gameCfg.gameId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
return false
end
function RedDotUtils.hasActivityBaseMultiStageRedDot(activityId)
local activity = GameInstance.player.activitySystem:GetActivity(activityId)
if not activity then
return false
end
if activity.completeStageList.Count ~= activity.receiveStageList.Count then
return true,UIConst.RED_DOT_TYPE.Normal
end
if ActivityUtils.isNewActivity(activityId) then
return true,UIConst.RED_DOT_TYPE.New
end
return false
end
function RedDotUtils.hasActivityGachaBeginnerRedDot(activityId)
local hasRedDot, type = RedDotUtils.hasActivityBaseMultiStageRedDot(activityId)
if hasRedDot then
return hasRedDot, type
end
if RedDotUtils.hasGachaBeginnerTicketNotUesRedDot() then
return true, UIConst.RED_DOT_TYPE.Normal
end
return RedDotUtils.hasGachaStarterCumulateRedDot(Tables.charGachaConst.beginnerGachaActivityPoolId)
end
function RedDotUtils.hasGachaBeginnerTicketNotUesRedDot()
local poolId = Tables.charGachaConst.beginnerGachaActivityPoolId
local poolCfg = Tables.gachaCharPoolTable[poolId]
local poolTypeCfg = Tables.gachaCharPoolTypeTable[poolCfg.type]
local gachaTenTicketId = poolTypeCfg.tenPullCostItemIds[0]
return Utils.getItemCount(gachaTenTicketId) > 0, UIConst.RED_DOT_TYPE.Normal
end
function RedDotUtils.hasGachaRedDot()
for poolId, poolInfo in cs_pairs(GameInstance.player.gacha.poolInfos) do
if poolInfo.isChar then
local has, type = RedDotUtils.hasGachaSinglePoolRedDot(poolId)
if has then
return has, type
end
end
end
return false
end
function RedDotUtils.hasGachaSinglePoolRedDot(poolId)
local hasInfo, poolInfo = GameInstance.player.gacha.poolInfos:TryGetValue(poolId)
if not hasInfo or not poolInfo.isOpenValid then
return false
end
if not RedDotUtils.isGachaSinglePoolRead(poolId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
if poolInfo.type == GEnums.CharacterGachaPoolType.Beginner then
return RedDotUtils.hasGachaStarterRedDot(poolId)
elseif poolInfo.type == GEnums.CharacterGachaPoolType.Special then
return RedDotUtils.hasGachaSpecialPoolRedDot(poolId)
elseif poolInfo.type == GEnums.CharacterGachaPoolType.Standard then
return RedDotUtils.hasGachaStandardPoolRedDot(poolId)
end
return false
end
function RedDotUtils.isGachaSinglePoolRead(poolId)
local _, isNewOpenedPoolRead, _ = ClientDataManagerInst:GetBool("IS_NEW_OPENED_POOL_READ_" .. poolId, true, false)
return isNewOpenedPoolRead
end
function RedDotUtils.setGachaSinglePoolRead(poolId)
if RedDotUtils.isGachaSinglePoolRead(poolId) then
return
end
ClientDataManagerInst:SetBool("IS_NEW_OPENED_POOL_READ_" .. poolId, true, true)
Notify(MessageConst.ON_GACHA_POOL_NEW_OPENED_READ, poolId)
end
function RedDotUtils.hasGachaStarterRedDot(poolId)
local hasRedDot, type = RedDotUtils.hasGachaStarterCumulateRedDot(poolId)
if hasRedDot then
return hasRedDot, type
end
local activityCfg = Tables.activityLevelRewardsTable[Tables.charGachaConst.gachaBeginnerActivityId]
for _, stageCfg in pairs(activityCfg.stageList) do
local stageId = stageCfg.stageId
hasRedDot, type = RedDotUtils.hasGachaStarterActivityStageRedDot(stageId)
if hasRedDot then
return hasRedDot, type
end
end
return false
end
function RedDotUtils.hasGachaStarterCumulateRedDot(poolId)
local hasInfo, poolInfo = GameInstance.player.gacha.poolInfos:TryGetValue(poolId)
if not hasInfo then
return false
end
local isGet = poolInfo.roleDataMsg and poolInfo.roleDataMsg.CumulativeRewardList:Contains(0)
if isGet then
return false
end
local poolCfg = Tables.gachaCharPoolTable[poolId]
local poolTypeCfg = Tables.gachaCharPoolTypeTable[poolCfg.type]
if poolInfo.totalPullCountNoShare >= poolTypeCfg.cumulativeRewardsPullCount[0] then
return true, UIConst.RED_DOT_TYPE.Normal
end
local gachaTenTicketId = poolTypeCfg.tenPullCostItemIds[0]
if Utils.getItemCount(gachaTenTicketId) > 0 then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end
function RedDotUtils.hasGachaStarterActivityStageRedDot(stageId)
local activityData = GameInstance.player.activitySystem:GetActivity(Tables.charGachaConst.gachaBeginnerActivityId)
if not activityData then
return false
end
local isRewarded = activityData.receiveStageList:Contains(stageId)
local isComplete = activityData.completeStageList:Contains(stageId)
if isRewarded then
return false
elseif isComplete then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end
function RedDotUtils.hasGachaSpecialPoolRedDot(poolId)
local _, poolInfo = GameInstance.player.gacha.poolInfos:TryGetValue(poolId)
return poolInfo.freeTenPullCount > 0, UIConst.RED_DOT_TYPE.Normal
end
function RedDotUtils.hasGachaStandardPoolRedDot(poolId)
local _, poolInfo = GameInstance.player.gacha.poolInfos:TryGetValue(poolId)
return poolInfo.choicePackCount > 0, UIConst.RED_DOT_TYPE.Normal
end
function RedDotUtils.hasSingleDomainDevelopmentRedDot(checkDomainId)
local hasCfg, domainCfg = Tables.domainDataTable:TryGetValue(checkDomainId)
if hasCfg then
for poiType, getRedDotInfoFunc in pairs(DomainPOIUtils.GetRedDotInfoFunc) do
local checkCanOpenFuncName = DomainPOIUtils.CheckCanOpenPOIFunc[poiType]
if string.isEmpty(checkCanOpenFuncName) or not DomainPOIUtils[checkCanOpenFuncName] then
logger.error("【地区发展系统红点】 checkCanOpenFunc不存在poiType为" .. tostring(poiType))
else
if DomainPOIUtils[checkCanOpenFuncName](checkDomainId) then
local redDotInfo = DomainPOIUtils[getRedDotInfoFunc](checkDomainId)
local hasRedDot, redDotType = RedDotManager:GetRedDotState(redDotInfo.redDotName, redDotInfo.redDotArgs)
if hasRedDot then
return true, redDotType
end
end
end
end
for _, stlId in pairs(domainCfg.settlementGroup) do
if RedDotUtils.hasSettlementCanUpgradeRedDot(stlId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
return GameInstance.player.domainDevelopmentSystem:HasLevelNotGerReward(checkDomainId), UIConst.RED_DOT_TYPE.Normal
else
logger.error("domainDataTable missing cfg, id: " .. checkDomainId)
return false
end
return false
end
function RedDotUtils.hasSingleDomainGradeRedDot(checkDomainId)
local hasCfg, domainCfg = Tables.domainDataTable:TryGetValue(checkDomainId)
if hasCfg then
return GameInstance.player.domainDevelopmentSystem:HasLevelNotGerReward(checkDomainId), UIConst.RED_DOT_TYPE.Normal
else
logger.error("domainDataTable missing cfg, id: " .. checkDomainId)
return false
end
return false
end
function RedDotUtils.hasValuableDepotTabCommercialItemRedDot()
local minExpireTs = math.maxinteger
local needShowExpire = false
local depotType = GEnums.ItemValuableDepotType.CommercialItem
local mainScope = CS.Beyond.Gameplay.Scope.Create(GEnums.ScopeName.Main)
local inventory = GameInstance.player.inventory
local depot = inventory.valuableDepots[depotType]:GetOrFallback(mainScope)
if depot then
local curTime = DateTimeUtils.GetCurrentTimestampBySeconds()
for instId, itemBundle in pairs(depot.instItems) do
if itemBundle.isLimitTimeItem then
local itemCfg = Tables.itemTable[itemBundle.id]
local ltItemCfg = Tables.lTItemTypeTable[itemCfg.type]
local almostExpireTime = ltItemCfg.daysBeforeExpireToNotify * Const.SEC_PER_DAY
if (itemBundle.instData.expireTs - curTime) <= almostExpireTime then
minExpireTs = math.min(minExpireTs, itemBundle.instData.expireTs)
needShowExpire = true
end
end
end
end
if needShowExpire then
return true, UIConst.RED_DOT_TYPE.Expire, minExpireTs
end
if RedDotUtils.isValuableDepotTabHasNewObtainedImportantItem(GEnums.ItemValuableDepotType.CommercialItem) then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end
function RedDotUtils.isValuableDepotTabHasNewObtainedImportantItem(type)
if not GameInstance.player.inventory.valuableDepots:TryGetValue(type) then
return false
end
local commercialItemList = GameInstance.player.inventory.valuableDepots[type]:GetOrFallback(Utils.getCurrentScope())
for id, _ in cs_pairs(commercialItemList.normalItems) do
local success, redDotType = RedDotManager:GetRedDotState("ValuableDepotItem", id)
if success and redDotType == UIConst.RED_DOT_TYPE.Normal then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
return false
end
local newObtainedImportantValuableDepotItemText = "NewObtainedImportantValuableDepotItem"
function RedDotUtils.isNewObtainedImportantValuableDepotItem(id)
local suc, value = ClientDataManagerInst:GetBool(newObtainedImportantValuableDepotItemText .. id,false)
return suc and value
end
function RedDotUtils.setNewObtainedImportantValuableDepotItem(id, value)
ClientDataManagerInst:SetBool(newObtainedImportantValuableDepotItemText .. id, value, false, EClientDataTimeValidType.Permanent)
Notify(MessageConst.ON_VALUABLE_DEPOT_IMPORT_ITEM_CHANGED)
end
_G.RedDotUtils = RedDotUtils
return RedDotUtils