Files
Endfield-Data/LuaScripts/UI/RedDot/RedDotConfig.lua
2025-12-02 20:37:18 +07:00

3324 lines
110 KiB
Lua

local Config = {
NormalItem = {
msgs = {
MessageConst.ON_READ_NEW_ITEM,
},
readLike = true,
needArg = true,
Check = function(id)
return GameInstance.player.inventory:IsNewItem(id), UIConst.RED_DOT_TYPE.New
end,
},
InstItem = {
msgs = {
MessageConst.ON_READ_NEW_INST_ITEM,
},
readLike = true,
needArg = true,
Check = function(info)
return GameInstance.player.inventory:IsNewItem(info.id, info.instId), UIConst.RED_DOT_TYPE.New
end,
},
BlocShopDiscountShopItem = {
msgs = {
MessageConst.ON_BUY_ITEM_SUCC,
MessageConst.ON_SYNC_ALL_BLOC,
},
readLike = false,
needArg = true,
Check = function(blocId)
return RedDotUtils.hasBlocShopDiscountShopItem(blocId)
end
},
WeaponEmptyGem = {
msgs = {
MessageConst.ON_GEM_DETACH,
MessageConst.ON_GEM_ATTACH,
},
readLike = true,
needArg = true,
Check = function(weaponInstId)
local weaponInst = CharInfoUtils.getWeaponByInstId(weaponInstId)
if weaponInst.attachedGemInstId > 0 then
return false
end
return RedDotUtils.hasGemNotEquipped()
end
},
WeaponCanUpgrade = {
msgs = {
MessageConst.ON_WEAPON_GAIN_EXP,
MessageConst.ON_WEAPON_BREAKTHROUGH,
},
readLike = true,
needArg = true,
Check = function(weaponInstId)
return WeaponUtils.canWeaponBreakthrough(weaponInstId) or WeaponUtils.canWeaponUpgrade(weaponInstId)
end
},
Formula = {
msgs = {
MessageConst.ON_ADD_NEW_UNREAD_FORMULA,
MessageConst.ON_READ_FORMULA,
},
readLike = true,
needArg = true,
Check = function(formulaId)
return GameInstance.player.remoteFactory.core:IsFormulaUnread(formulaId), UIConst.RED_DOT_TYPE.New
end,
},
BuildingFormula = {
sons = {
Formula = false,
},
readLike = false,
needArg = true,
Check = function(arg)
local buildingId = arg.buildingId
local modeName = arg.modeName
local core = GameInstance.player.remoteFactory.core
local bData = Tables.factoryBuildingTable:GetValue(buildingId)
local bType = bData.type
if bType == GEnums.FacBuildingType.MachineCrafter or bType == GEnums.FacBuildingType.FluidReaction then
local machineCrafterData = FactoryUtils.getMachineCraftGroupData(buildingId, modeName)
for _, craftId in pairs(machineCrafterData.craftList) do
if core:IsFormulaUnread(craftId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
end
return false
end,
},
TechTree = {
msgs = {
MessageConst.ON_UNLOCK_FAC_TECH_PACKAGE,
MessageConst.ON_UNHIDDEN_FAC_TECH_PACKAGE,
MessageConst.ON_CHANGE_SPACESHIP_DOMAIN_ID,
},
readLike = false,
needArg = false,
Check = function()
local levelId = GameWorld.worldInfo.curLevelId
if string.isEmpty(levelId) then
logger.warn("RedDotConfig->TechTree Check->levelId is None")
return false
end
local _, levelBasicInfo = DataManager.levelBasicInfoTable:TryGetValue(levelId)
local isInSpaceShip = Utils.isInSpaceShip()
local domainId = isInSpaceShip and GameInstance.player.inventory.spaceshipDomainId or levelBasicInfo.domainName
local hasDomain, domainCfg = Tables.domainDataTable:TryGetValue(domainId)
if not hasDomain then
return false
end
local facTechPackageId = domainCfg.facTechPackageId
local techTreeSystem = GameInstance.player.facTechTreeSystem
if techTreeSystem:PackageIsHidden(facTechPackageId) then
return false
end
if techTreeSystem:PackageIsLocked(facTechPackageId) then
return false
end
local packageCfg = Tables.facSTTGroupTable[facTechPackageId]
for _, layerId in pairs(packageCfg.layerIds) do
local groupState = RedDotManager:GetRedDotState("TechTreeLayer", layerId)
if groupState then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
for _, techId in pairs(packageCfg.techIds) do
local groupState = RedDotManager:GetRedDotState("TechTreeNode", techId)
if groupState then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
local blackboxEntryState = RedDotManager:GetRedDotState("BlackboxEntry", facTechPackageId)
if blackboxEntryState then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end,
sons = {
TechTreeNode = false,
TechTreeLayer = false,
BlackboxEntry = false,
}
},
TechTreeLayer = {
msgs = {
MessageConst.FAC_ON_REFRESH_TECH_TREE_UI,
MessageConst.ON_ITEM_COUNT_CHANGED,
},
readLike = false,
needArg = true,
Check = function(layerId)
local techTreeSystem = GameInstance.player.facTechTreeSystem
if not techTreeSystem:LayerIsLocked(layerId) then
return false
end
local layerCfg = Tables.facSTTLayerTable[layerId]
local isEnough = true
for _, costItem in pairs(layerCfg.costItems) do
local ownCount = Utils.getItemCount(costItem.costItemId)
local costCount = costItem.costItemCount
if ownCount < costCount then
isEnough = false
break
end
end
return isEnough, UIConst.RED_DOT_TYPE.Normal
end
},
TechTreeNode = {
msgs = {
MessageConst.FAC_ON_REFRESH_TECH_TREE_UI,
MessageConst.ON_ITEM_COUNT_CHANGED,
},
readLike = false,
needArg = true,
Check = function(techId)
local techTreeSystem = GameInstance.player.facTechTreeSystem
local nodeData = Tables.facSTTNodeTable:GetValue(techId)
if not techTreeSystem:NodeIsLocked(techId) then
return false
end
if techTreeSystem:PreNodeIsLocked(techId) then
return false
end
if techTreeSystem:LayerIsLocked(nodeData.layer) then
return false
end
local isMatchCondition = true
if nodeData.conditions.Count > 0 then
for i = 1, nodeData.conditions.Count do
if not techTreeSystem:GetConditionIsCompleted(techId,
nodeData.conditions[CSIndex(i)].conditionId) then
isMatchCondition = false
break
end
end
end
if not isMatchCondition then
return false
end
local isEnough = Utils.getItemCount(Tables.facSTTGroupTable[nodeData.groupId].costPointType)
>= nodeData.costPointCount
if not isEnough then
return false
end
return true, UIConst.RED_DOT_TYPE.Normal
end
},
BlackboxPreDependencies = {
readLike = true,
needArg = true,
Check = function(blackboxIds)
for _, blackboxId in pairs(blackboxIds) do
if not GameInstance.dungeonManager:IsDungeonPassed(blackboxId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
return false
end,
sons = {
BlackboxSelectionCellPassed = false,
}
},
BlackboxSelectionCellPassed = {
msgs = {
},
readLike = true,
needArg = true,
Check = function(blackboxId)
if not GameInstance.dungeonManager:IsDungeonPassed(blackboxId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end
},
BlackboxEntry = {
readLike = false,
needArg = true,
Check = function(packageId)
local packageCfg = Tables.facSTTGroupTable[packageId]
for _, blackboxId in pairs(packageCfg.blackboxIds) do
local hasReadDotState = RedDotManager:GetRedDotState("BlackboxSelectionCellRead", blackboxId)
if hasReadDotState then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
return false
end,
sons = {
BlackboxSelectionCellRead = false,
},
},
BlackboxSelectionCellRead = {
msgs = {
MessageConst.ON_BLACKBOX_ACTIVE,
MessageConst.ON_BLACKBOX_READ,
},
readLike = true,
needArg = true,
Check = function(blackboxId)
local dungeonMgr = GameInstance.dungeonManager
if not dungeonMgr:IsDungeonActive(blackboxId) then
return false
end
if dungeonMgr:IsBlackboxRead(blackboxId) then
return false
end
return true, UIConst.RED_DOT_TYPE.New
end
},
SingleBlueprint = {
msgs = {
MessageConst.FAC_ON_READ_BLUEPRINT,
},
readLike = true,
needArg = true,
Check = function(id)
local isNew
local t = type(id)
if t == "number" then
isNew = GameInstance.player.remoteFactory.blueprint:IsNewMyBlueprint(id)
elseif t == "string" then
isNew = GameInstance.player.remoteFactory.blueprint:IsNewSysBlueprint(id)
else
isNew = GameInstance.player.remoteFactory.blueprint:IsNewGiftBlueprint(id)
end
if isNew then
return true, UIConst.RED_DOT_TYPE.New
else
return false
end
end,
},
SingleMail = {
msgs = {
MessageConst.ON_ALL_MAIL_INITED,
MessageConst.ON_READ_MAIL,
MessageConst.ON_GET_MAIL_ATTACHMENT,
MessageConst.ON_GET_NEW_MAILS,
},
readLike = true,
needArg = true,
Check = function(mailId)
local mailSys = GameInstance.player.mail
if not mailSys:IsAllMailInited() then
return false
end
local mail = mailSys.mails[mailId]
if mail.isExpired then
return false
end
if not mail.isRead then
return true, UIConst.RED_DOT_TYPE.New
end
if not mail.collected then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end,
},
MailTab = {
sons = {
SingleMail = false,
},
readLike = false,
needArg = false,
Check = function()
local mailSys = GameInstance.player.mail
if not mailSys:IsAllMailInited() then
return false
end
for _, mail in pairs(mailSys.mails) do
if (not mail.isExpired) and (not mail.collected or not mail.isRead) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
return false
end,
},
MailTabGetAllBtn = {
sons = {
SingleMail = false,
},
readLike = false,
needArg = false,
Check = function()
local mailSys = GameInstance.player.mail
if not mailSys:IsAllMailInited() then
return false
end
for _, mail in pairs(mailSys.mails) do
if (not mail.isExpired) and (not mail.collected) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
return false
end,
},
Mail = {
sons = {
SingleMail = false,
LostAndFoundBtn = false,
},
readLike = false,
needArg = false,
Check = function()
local hasRedDot = GameInstance.player.mail:HasNewMail() or not GameInstance.player.inventory.lostAndFound:IsEmpty()
return hasRedDot, UIConst.RED_DOT_TYPE.Normal
end,
},
LostAndFoundBtn = {
msgs = {
MessageConst.ON_GET_LOST_AND_FOUND,
MessageConst.ON_ADD_LOST_AND_FOUND,
},
Check = function()
return not GameInstance.player.inventory.lostAndFound:IsEmpty(), UIConst.RED_DOT_TYPE.Normal
end,
needArg = false,
readLike = false,
},
Gacha = {
msgs = {
MessageConst.ON_GACHA_POOL_INFO_CHANGED,
MessageConst.ON_GACHA_POOL_ROLE_DATA_CHANGED,
MessageConst.ON_ACTIVITY_GACHA_BEGINNER_STAGE_MODIFY,
MessageConst.ON_GACHA_POOL_NEW_OPENED_READ,
},
needArg = false,
Check = function()
return RedDotUtils.hasGachaRedDot()
end,
readLike = false,
sons = {
GachaSinglePool = false,
}
},
GachaSinglePool = {
msgs = {
MessageConst.ON_GACHA_POOL_INFO_CHANGED,
MessageConst.ON_GACHA_POOL_ROLE_DATA_CHANGED,
MessageConst.ON_ACTIVITY_GACHA_BEGINNER_STAGE_MODIFY,
MessageConst.ON_GACHA_POOL_NEW_OPENED_READ,
},
needArg = true,
Check = function(poolId)
return RedDotUtils.hasGachaSinglePoolRedDot(poolId)
end,
readLike = false,
},
PRTSReading = {
msgs = {
MessageConst.ON_PRTS_TERMINAL_READ,
},
readLike = true,
needArg = true,
Check = function(uniqId)
return not GameInstance.player.prts.prtsTerminalContentSet:Contains(uniqId), UIConst.RED_DOT_TYPE.Normal
end
},
PRTSWatch = {
readLike = false,
needArg = false,
Check = function()
local prtsSys = GameInstance.player.prts
for id, _ in pairs(Tables.prtsInvestigate) do
if not prtsSys:IsInvestigateFinished(id) and prtsSys:IsInvestigateCanFinish(id) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
local unreadSet = GameInstance.player.prts.prtsUnReadSet
if unreadSet.Count > 0 then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end,
sons = {
PRTSDocument = false,
PRTSText = false,
PRTSMultimedia = false,
PRTSInvestigateTab = false,
},
},
PRTSDocument = {
readLike = false,
needArg = false,
Check = function()
local unlockSet = GameInstance.player.prts.prtsUnlockSet
local unreadSet = GameInstance.player.prts.prtsUnReadSet
for _, unreadId in pairs(unreadSet) do
if unlockSet:Contains(unreadId) and Tables.prtsDocument:ContainsKey(unreadId) then
return true, UIConst.RED_DOT_TYPE.New
end
end
return false
end,
sons = {
PRTSItem = false
},
},
PRTSText = {
readLike = false,
needArg = false,
Check = function()
local unlockSet = GameInstance.player.prts.prtsUnlockSet
local unreadSet = GameInstance.player.prts.prtsUnReadSet
for _, unreadId in pairs(unreadSet) do
if unlockSet:Contains(unreadId) and Tables.prtsRecord:ContainsKey(unreadId) then
return true, UIConst.RED_DOT_TYPE.New
end
end
return false
end,
sons = {
PRTSItem = false
},
},
PRTSStoryCollCategory = {
readLike = false,
needArg = true,
Check = function(categoryId)
local unreadSet = GameInstance.player.prts.prtsUnReadSet
local prtsSystem = GameInstance.player.prts
for _, unreadId in pairs(unreadSet) do
local id = prtsSystem:GetCategoryIdByPrtsId(unreadId)
if categoryId == id then
return true, UIConst.RED_DOT_TYPE.New
end
end
return false
end,
sons = {
PRTSItem = false
},
},
PRTSMultimedia = {
readLike = false,
needArg = false,
Check = function()
local unlockSet = GameInstance.player.prts.prtsUnlockSet
local unreadSet = GameInstance.player.prts.prtsUnReadSet
for _, unreadId in pairs(unreadSet) do
if unlockSet:Contains(unreadId) and Tables.prtsMultimedia:ContainsKey(unreadId) then
return true, UIConst.RED_DOT_TYPE.New
end
end
return false
end,
sons = {
PRTSItem = false
},
},
PRTSFirstLv = {
readLike = false,
needArg = true,
Check = function(firstLvId)
local unreadSet = GameInstance.player.prts.prtsUnReadSet
for _, unreadId in pairs(unreadSet) do
local _, prtsData = Tables.prtsAllItem:TryGetValue(unreadId)
if prtsData and prtsData.firstLvId == firstLvId then
return true, UIConst.RED_DOT_TYPE.New
end
end
return false
end,
sons = {
PRTSItem = false
},
},
PRTSItem = {
msgs = {
MessageConst.ON_UNREAD_PRTS,
MessageConst.ON_READ_PRTS,
},
readLike = false,
needArg = true,
Check = function(prtsId)
local unlockSet = GameInstance.player.prts.prtsUnlockSet
local unreadSet = GameInstance.player.prts.prtsUnReadSet
if unlockSet:Contains(prtsId) and unreadSet:Contains(prtsId) then
return true, UIConst.RED_DOT_TYPE.New
end
return false
end,
},
PRTSInvestigateTab = {
readLike = true,
needArg = false,
Check = function()
local prtsSys = GameInstance.player.prts
local hasUnread = false
for investId, _ in pairs(Tables.prtsInvestigate) do
local cfg = Utils.tryGetTableCfg(Tables.prtsInvestigate, investId)
if cfg then
local isFinished = prtsSys:IsInvestigateFinished(investId)
if isFinished then
if not hasUnread then
for _, collId in pairs(cfg.collectionIdList) do
if prtsSys:IsPrtsUnread(collId) then
hasUnread = true
break ;
end
end
if not hasUnread and RedDotUtils.hasPrtsNoteRedDot(cfg) then
hasUnread = true
end
end
else
local unlockCount = 0
for _, collId in pairs(cfg.collectionIdList) do
unlockCount = prtsSys:IsPrtsUnlocked(collId) and unlockCount + 1 or unlockCount
if prtsSys:IsPrtsUnread(collId) then
hasUnread = true
end
end
if unlockCount >= cfg.collectionIdList.Count then
return true, UIConst.RED_DOT_TYPE.Normal
end
if not hasUnread and RedDotUtils.hasPrtsNoteRedDot(cfg) then
hasUnread = true
end
end
end
end
if hasUnread then
return true, UIConst.RED_DOT_TYPE.New
end
return false
end,
sons = {
PRTSInvestigate = false,
},
},
PRTSInvestigate = {
msgs = {
MessageConst.ON_INVESTIGATE_FINISHED,
MessageConst.ON_READ_PRTS_NOTE_BATCH,
MessageConst.ON_READ_PRTS,
},
readLike = true,
needArg = true,
Check = function(investId)
local cfg = Utils.tryGetTableCfg(Tables.prtsInvestigate, investId)
if not cfg then
return false
end
local prtsSys = GameInstance.player.prts
local isFinished = prtsSys:IsInvestigateFinished(investId)
if isFinished then
for _, collId in pairs(cfg.collectionIdList) do
if prtsSys:IsPrtsUnread(collId) then
return true, UIConst.RED_DOT_TYPE.New
end
end
if RedDotUtils.hasPrtsNoteRedDot(cfg) then
return true, UIConst.RED_DOT_TYPE.New
end
else
local unlockCount = 0
local hasUnread = false
for _, collId in pairs(cfg.collectionIdList) do
unlockCount = prtsSys:IsPrtsUnlocked(collId) and unlockCount + 1 or unlockCount
if prtsSys:IsPrtsUnread(collId) then
hasUnread = true
end
end
if unlockCount >= cfg.collectionIdList.Count then
return true, UIConst.RED_DOT_TYPE.Normal
end
if hasUnread then
return true, UIConst.RED_DOT_TYPE.New
end
if RedDotUtils.hasPrtsNoteRedDot(cfg) then
return true, UIConst.RED_DOT_TYPE.New
end
end
return false
end,
sons = {
PRTSItem = false,
},
},
PRTSNote = {
msgs = {
MessageConst.ON_READ_PRTS_NOTE_BATCH,
MessageConst.ON_UNREAD_PRTS_NOTE_BATCH,
},
readLike = true,
needArg = true,
Check = function(noteId)
local prtsSys = GameInstance.player.prts
if prtsSys:IsNoteUnread(noteId) then
return true, UIConst.RED_DOT_TYPE.New
end
return false
end,
},
AllCharInfo = {
msgs = {
MessageConst.SHOW_FOCUS_MODE_TOAST,
MessageConst.GAME_MODE_ENABLE,
MessageConst.ENTER_FOCUS_MODE_READY,
},
readLike = false,
needArg = false,
Check = function()
local isFullLockedTeam = CharInfoUtils.IsFullLockedTeam()
if isFullLockedTeam then
return false
end
if not Utils.isInMainScope() then
return false
end
local charBag = GameInstance.player.charBag
if charBag.newCharListSet.Count > 0 then
return true, UIConst.RED_DOT_TYPE.Normal
end
for charInstId, charInfo in pairs(charBag.charInfos) do
if charInfo.charType == GEnums.CharType.Default and
RedDotManager:GetRedDotState("CharInfoPotential", charInstId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
return false
end,
sons = {
CharNew = false,
CharInfoPotential = false,
},
},
CharInfo = {
msgs = {
MessageConst.ON_SYSTEM_UNLOCK_CHANGED,
},
readLike = false,
needArg = true,
Check = function(charInstId)
if not CharInfoUtils.isCharDevAvailable(charInstId) then
return false
end
local charInst = CharInfoUtils.getPlayerCharInfoByInstId(charInstId)
if RedDotManager:GetRedDotState("CharNew", charInst.templateId) then
return true, UIConst.RED_DOT_TYPE.New
end
if RedDotManager:GetRedDotState("CharInfoPotential", charInstId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end,
sons = {
CharNew = false,
CharInfoPotential = false,
},
},
CharNew = {
msgs = {
MessageConst.ON_CHAR_NEW_TAG_CHANGED,
},
readLike = true,
needArg = true,
Check = function(templateId)
local res = GameInstance.player.charBag:CheckCharIsNew(templateId)
return res, UIConst.RED_DOT_TYPE.New
end,
},
CharBreak = {
readLike = false,
needArg = true,
Check = function(charInstId)
if not CharInfoUtils.isCharDevAvailable(charInstId) then
return false
end
local charInst = CharInfoUtils.getPlayerCharInfoByInstId(charInstId)
for nodeId, nodeData in pairs(Tables.charBreakNodeTable) do
if nodeData.talentNodeType == GEnums.TalentNodeType.CharBreak then
if nodeData.breakStage == charInst.breakStage + 1 and
nodeData.equipTierLimit <= charInst.equipTierLimit then
local _, breakStageData = Tables.charBreakStageTable:TryGetValue(nodeData.breakStage)
if breakStageData and breakStageData.minCharLevel <= charInst.level and
CharInfoUtils.isCharBreakCostEnough(charInst.templateId, nodeId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
elseif nodeData.talentNodeType == GEnums.TalentNodeType.EquipBreak then
if nodeData.breakStage == charInst.breakStage and
nodeId ~= charInst.talentInfo.latestBreakNode and
CharInfoUtils.isCharBreakCostEnough(charInst.templateId, nodeId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
end
local talentState = RedDotManager:GetRedDotState("CharTalent", charInstId)
if talentState then
return talentState, UIConst.RED_DOT_TYPE.Normal
end
local skillState = RedDotManager:GetRedDotState("CharSkill", charInstId)
if skillState then
return skillState, UIConst.RED_DOT_TYPE.Normal
end
return false
end,
sons = {
CharBreakNode = false,
EquipBreakNode = false,
CharAttrNode = false,
PassiveSkillNode = false,
ShipSkillNode = false,
CharSkillNode = false,
},
},
CharTalent = {
readLike = false,
needArg = true,
Check = function(charInstId)
if not CharInfoUtils.isCharDevAvailable(charInstId) then
return false
end
local charInst = CharInfoUtils.getPlayerCharInfoByInstId(charInstId)
local charGrowthData = CharInfoUtils.getCharGrowthData(charInst.templateId)
if charGrowthData then
local passiveSkillNodeTable = {}
local shipSkillNodeIndexTable = {}
for nodeId, nodeData in pairs(charGrowthData.talentNodeMap) do
if nodeData.nodeType == GEnums.TalentNodeType.Attr then
if not charInst.talentInfo.attributeNodes:Contains(nodeId) and
CSPlayerDataUtil.GetCharFriendship(charInstId) >= nodeData.attributeNodeInfo.favorability and
charInst.breakStage >= nodeData.attributeNodeInfo.breakStage and
CharInfoUtils.isCharTalentCostEnough(charInst.templateId, nodeId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
elseif nodeData.nodeType == GEnums.TalentNodeType.PassiveSkill then
local index = nodeData.passiveSkillNodeInfo.index
local data = passiveSkillNodeTable[index]
if not data then
data = {}
passiveSkillNodeTable[index] = data
end
data[nodeData.passiveSkillNodeInfo.level] = nodeData
elseif nodeData.nodeType == GEnums.TalentNodeType.FactorySkill then
local index = nodeData.factorySkillNodeInfo.index
local data = shipSkillNodeIndexTable[index]
if not data then
data = {}
shipSkillNodeIndexTable[index] = data
end
data[nodeData.factorySkillNodeInfo.level] = nodeData
end
end
for _, nodeDataTable in pairs(passiveSkillNodeTable) do
local maxLv = #nodeDataTable
for i = maxLv, 1, -1 do
local nodeData = nodeDataTable[i]
if charInst.talentInfo.latestPassiveSkillNodes:Contains(nodeData.nodeId) then
break
end
local preNodeData = nodeDataTable[i - 1]
if charInst.breakStage >= nodeData.passiveSkillNodeInfo.breakStage and
(preNodeData == nil or charInst.talentInfo.latestPassiveSkillNodes:Contains(preNodeData.nodeId)) and
CharInfoUtils.isCharTalentCostEnough(charInst.templateId, nodeData.nodeId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
end
for _, nodeDataTable in pairs(shipSkillNodeIndexTable) do
local maxLv = #nodeDataTable
for i = maxLv, 1, -1 do
local nodeData = nodeDataTable[i]
if charInst.talentInfo.latestFactorySkillNodes:Contains(nodeData.nodeId) then
break
end
local preNodeData = nodeDataTable[i - 1]
if charInst.breakStage >= nodeData.factorySkillNodeInfo.breakStage and
(preNodeData == nil or charInst.talentInfo.latestFactorySkillNodes:Contains(preNodeData.nodeId)) and
CharInfoUtils.isCharTalentCostEnough(charInst.templateId, nodeData.nodeId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
end
end
return false
end,
sons = {
CharAttrNode = false,
PassiveSkillNode = false,
ShipSkillNode = false,
},
},
CharSkill = {
readLike = false,
needArg = true,
Check = function(charInstId)
if not CharInfoUtils.isCharDevAvailable(charInstId) then
return false
end
local charInst = CharInfoUtils.getPlayerCharInfoByInstId(charInstId)
for _, skillGroupLevelInfo in pairs(charInst.skillGroupLevelInfoList) do
if skillGroupLevelInfo.level < skillGroupLevelInfo.maxLevel then
if CharInfoUtils.isSkillGroupLevelUpCostEnough(charInst.templateId, skillGroupLevelInfo.skillGroupId, skillGroupLevelInfo.level + 1) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
end
return false
end,
sons = {
CharSkillNode = false,
},
},
CharBreakNode = {
msgs = {
MessageConst.ON_ITEM_COUNT_CHANGED,
MessageConst.ON_WALLET_CHANGED,
MessageConst.ON_CHAR_LEVEL_UP,
MessageConst.ON_CHAR_TALENT_UPGRADE,
},
readLike = false,
needArg = true,
Check = function(args)
local charInstId, nodeId = unpack(args)
if not CharInfoUtils.isCharDevAvailable(charInstId) then
return false
end
local isActive, isLock = CharInfoUtils.getCharBreakNodeStatus(charInstId, nodeId)
if isActive or isLock then
return false
end
local charInst = CharInfoUtils.getPlayerCharInfoByInstId(charInstId)
if charInst.charType == GEnums.CharType.Trial then
return false
end
if not CharInfoUtils.isCharBreakCostEnough(charInst.templateId, nodeId) then
return false
end
return true, UIConst.RED_DOT_TYPE.Normal
end
},
EquipBreakNode = {
msgs = {
MessageConst.ON_ITEM_COUNT_CHANGED,
MessageConst.ON_WALLET_CHANGED,
MessageConst.ON_CHAR_LEVEL_UP,
MessageConst.ON_CHAR_TALENT_UPGRADE,
},
readLike = false,
needArg = true,
Check = function(args)
local charInstId, nodeId = unpack(args)
if not CharInfoUtils.isCharDevAvailable(charInstId) then
return false
end
local isActive, isLock = CharInfoUtils.getEquipBreakNodeStatus(charInstId, nodeId)
if isActive or isLock then
return false
end
local charInst = CharInfoUtils.getPlayerCharInfoByInstId(charInstId)
if charInst.charType == GEnums.CharType.Trial then
return false
end
if not CharInfoUtils.isCharBreakCostEnough(charInst.templateId, nodeId) then
return false
end
return true, UIConst.RED_DOT_TYPE.Normal
end
},
CharAttrNode = {
msgs = {
MessageConst.ON_ITEM_COUNT_CHANGED,
MessageConst.ON_WALLET_CHANGED,
MessageConst.ON_CHAR_TALENT_UPGRADE,
},
readLike = false,
needArg = true,
Check = function(args)
local charInstId, nodeId = unpack(args)
if not CharInfoUtils.isCharDevAvailable(charInstId) then
return false
end
local isActive, isLock = CharInfoUtils.getAttributeNodeStatus(charInstId, nodeId)
if isActive or isLock then
return false
end
local charInst = CharInfoUtils.getPlayerCharInfoByInstId(charInstId)
if charInst.charType == GEnums.CharType.Trial then
return false
end
if not CharInfoUtils.isCharTalentCostEnough(charInst.templateId, nodeId) then
return false
end
return true, UIConst.RED_DOT_TYPE.Normal
end
},
PassiveSkillNode = {
msgs = {
MessageConst.ON_ITEM_COUNT_CHANGED,
MessageConst.ON_WALLET_CHANGED,
MessageConst.ON_CHAR_TALENT_UPGRADE,
},
readLike = false,
needArg = true,
Check = function(args)
local charInstId, nodeId = unpack(args)
if not CharInfoUtils.isCharDevAvailable(charInstId) then
return false
end
local isActive, isLock = CharInfoUtils.getPassiveSkillNodeStatus(charInstId, nodeId)
if isActive or isLock then
return false
end
local charInst = CharInfoUtils.getPlayerCharInfoByInstId(charInstId)
if charInst.charType == GEnums.CharType.Trial then
return false
end
if not CharInfoUtils.isCharTalentCostEnough(charInst.templateId, nodeId) then
return false
end
return true, UIConst.RED_DOT_TYPE.Normal
end
},
ShipSkillNode = {
msgs = {
MessageConst.ON_ITEM_COUNT_CHANGED,
MessageConst.ON_WALLET_CHANGED,
MessageConst.ON_CHAR_TALENT_UPGRADE,
},
readLike = false,
needArg = true,
Check = function(args)
local charInstId, nodeId = unpack(args)
if not CharInfoUtils.isCharDevAvailable(charInstId) then
return false
end
local isActive, isLock = CharInfoUtils.getShipSkillNodeStatus(charInstId, nodeId)
if isActive or isLock then
return false
end
local charInst = CharInfoUtils.getPlayerCharInfoByInstId(charInstId)
if charInst.charType == GEnums.CharType.Trial then
return false
end
if not CharInfoUtils.isCharTalentCostEnough(charInst.templateId, nodeId) then
return false
end
return true, UIConst.RED_DOT_TYPE.Normal
end
},
CharSkillNode = {
msgs = {
MessageConst.ON_ITEM_COUNT_CHANGED,
MessageConst.ON_WALLET_CHANGED,
MessageConst.ON_SKILL_UPGRADE_SUCCESS,
},
readLike = false,
needArg = true,
Check = function(args)
local charInstId, skillGroupId = unpack(args)
if not CharInfoUtils.isCharDevAvailable(charInstId) then
return false
end
local charInst = CharInfoUtils.getPlayerCharInfoByInstId(charInstId)
local skillGroupLevelInfo = CharInfoUtils.getCharSkillLevelInfo(charInst, skillGroupId)
if skillGroupLevelInfo.level < skillGroupLevelInfo.maxLevel then
if CharInfoUtils.isSkillGroupLevelUpCostEnough(charInst.templateId, skillGroupId, skillGroupLevelInfo.level + 1) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
return false
end
},
EquipTab = {
readLike = false,
needArg = true,
Check = function(charInstId)
if not CharInfoUtils.isCharDevAvailable(charInstId) then
return false
end
for slotIndex, _ in pairs(UIConst.EQUIP_PART_TYPE_2_CELL_CONFIG) do
local groupState = RedDotManager:GetRedDotState("Equip", { charInstId, slotIndex })
if groupState then
return groupState, UIConst.RED_DOT_TYPE.Normal
end
end
return false
end,
sons = {
Equip = false,
},
},
Equip = {
msgs = {
MessageConst.ON_EQUIP_DEPOT_CHANGED,
MessageConst.ON_PUT_ON_EQUIP,
MessageConst.ON_PUT_OFF_EQUIP,
MessageConst.ON_ITEM_COUNT_CHANGED,
MessageConst.ON_TACTICAL_ITEM_CHANGE,
},
readLike = false,
needArg = true,
Check = function(args)
local charInstId, equipSlotIndex = unpack(args)
if not CharInfoUtils.isCharDevAvailable(charInstId) then
return false
end
local equipCellCfg = UIConst.EQUIP_PART_TYPE_2_CELL_CONFIG[equipSlotIndex]
if not equipCellCfg then
return false
end
local charInst = CharInfoUtils.getPlayerCharInfoByInstId(charInstId)
if equipCellCfg.isTacticalItem then
if not string.isEmpty(charInst.tacticalItemId) then
return false
end
for _, itemEquipData in pairs(Tables.equipItemTable) do
if GameInstance.player.inventory:IsItemFound(itemEquipData.itemId) and
Utils.getBagItemCount(itemEquipData.itemId) > 0 then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
else
local isEquipped, equipInstId = charInst.equipCol:TryGetValue(equipCellCfg.equipIndex)
if isEquipped and equipInstId > 0 then
return false
end
local equipDepot = GameInstance.player.inventory.valuableDepots[GEnums.ItemValuableDepotType.Equip]:GetOrFallback(Utils.getCurrentScope())
if not equipDepot then
return false
end
for _, itemBundle in pairs(equipDepot.instItems) do
if itemBundle.instData.equippedCharServerId == 0 then
local templateId = itemBundle.instData.templateId
local _, equipCfg = Tables.equipTable:TryGetValue(templateId)
if equipCfg and equipCfg.partType == equipCellCfg.slotPartType then
local _, itemData = Tables.itemTable:TryGetValue(templateId)
if itemData and itemData.rarity <= charInst.equipTierLimit then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
end
end
end
return false
end,
},
WatchBtn = {
readLike = false,
needArg = false,
sons = {
},
},
WatchBtnList = {
readLike = false,
needArg = true,
Check = function(redDots)
for i = 1, #redDots do
if RedDotManager:GetRedDotState(redDots[i]) then
return true
end
end
return false
end,
},
InventoryBtn = {
readLike = false,
needArg = false,
sons = {
ManualCraftBtn = true,
},
},
ShopSeeGoodsInfo = {
msgs = {
MessageConst.ON_SHOP_GOODS_SEE_GOODS_INFO_CHANGE,
},
readLike = false,
needArg = true,
Check = function(info)
return GameInstance.player.shopSystem:IsNewGoodsId(info.goodsId), UIConst.RED_DOT_TYPE.New
end,
},
ManualCraftBtn = {
readLike = false,
needArg = false,
Check = function()
if Utils.isInBlackbox() or Utils.isInWeekRaid() then
return false
end
local isUnlocked = Utils.isSystemUnlocked(GEnums.UnlockSystemType.ProductManual)
if isUnlocked and GameInstance.player.facManualCraft.unreadFormulaIds.Count > 0 then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end,
sons = {
ManualCraftType = false,
ManualCraftRewardEntry = true,
},
},
ManualCraftType = {
readLike = false,
needArg = true,
Check = function(formulaType)
local blackboxData = GameWorld.worldInfo.curLevel.levelData.blackbox
if blackboxData then
return false, UIConst.RED_DOT_TYPE.Normal
end
if GameInstance.player.facManualCraft:ExistUnreadFormulaByType(formulaType) then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end,
sons = {
ManualCraftItem = false,
},
},
ManualCraftItem = {
msgs = {
MessageConst.ON_UNREAD_MANUAL_CRAFT,
MessageConst.ON_READ_MANUAL_CRAFT,
},
readLike = false,
needArg = true,
Check = function(formulaId)
local blackboxData = GameWorld.worldInfo.curLevel.levelData.blackbox
if blackboxData then
return false, UIConst.RED_DOT_TYPE.Normal
end
if not GameInstance.player.facManualCraft:IsCraftRead(formulaId) then
return true, UIConst.RED_DOT_TYPE.New
end
return false
end,
},
ManualCraftRewardItem = {
msgs = {
MessageConst.ON_UNREAD_MANUAL_CRAFT_REWARD,
MessageConst.ON_READ_MANUAL_CRAFT_REWARD,
},
readLike = false,
needArg = true,
Check = function(arg)
local blackboxData = GameWorld.worldInfo.curLevel.levelData.blackbox
if blackboxData then
return false, UIConst.RED_DOT_TYPE.Normal
end
if arg.rewardId then
if GameInstance.player.facManualCraft:CheckHaveReadReward(arg.rewardId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
else
if GameInstance.player.facManualCraft:CheckHaveReadRewardByItem(arg.itemId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end
end,
},
ManualCraftReward = {
readLike = false,
needArg = true,
penetrateLevel = UIConst.RED_DOT_TYPE.Normal,
Check = function(arg)
local blackboxData = GameWorld.worldInfo.curLevel.levelData.blackbox
if blackboxData then
return false, UIConst.RED_DOT_TYPE.Normal
end
if GameInstance.player.facManualCraft:CheckHaveRewardByItemNoGet(arg.itemId) > 0 then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end,
sons = {
ManualCraftRewardItem = false,
},
},
ManualCraftRewardEntry = {
msgs = {
MessageConst.ON_SYSTEM_UNLOCK_CHANGED,
},
readLike = false,
needArg = false,
penetrateLevel = UIConst.RED_DOT_TYPE.Normal,
Check = function()
if Utils.isInBlackbox() or Utils.isInWeekRaid() then
return false
end
if Utils.isSystemUnlocked(GEnums.UnlockSystemType.ProductManual) and GameInstance.player.facManualCraft:CheckRewardRedDot() then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end,
sons = {
ManualCraftReward = false,
},
},
Announcement = {
msgs = {
MessageConst.ON_ANNOUNCEMENT_RED_DOT_CHANGED,
},
readLike = false,
needArg = false,
Check = function()
return GameInstance.player.announcement:HasNewAnnouncement()
end,
},
FacBuildModeMenuItem = {
readLike = true,
needArg = true,
Check = function(id)
local _, hasSaved = ClientDataManagerInst:GetBool(FacConst.FAC_BUILD_LIST_REDDOT_DATA_CATEGORY .. id, false, false, FacConst.FAC_BUILD_LIST_REDDOT_DATA_CATEGORY)
if not hasSaved then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false, UIConst.RED_DOT_TYPE.Normal
end,
},
FacBuildModeMenuLogisticTab = {
msgs = {
MessageConst.ON_SYSTEM_UNLOCK_CHANGED,
MessageConst.ON_IN_FAC_MAIN_REGION_CHANGE,
},
sons = {
FacBuildModeMenuItem = false,
},
readLike = false,
needArg = false,
Check = function()
if not Utils.isInFacMainRegion() then
return false
end
for id, _ in pairs(Tables.factoryGridConnecterTable) do
if Utils.isSystemUnlocked(FacConst.LOGISTIC_UNLOCK_SYSTEM_MAP[id]) then
if RedDotManager:GetRedDotState("FacBuildModeMenuItem", id) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
end
for id, _ in pairs(Tables.factoryGridRouterTable) do
if Utils.isSystemUnlocked(FacConst.LOGISTIC_UNLOCK_SYSTEM_MAP[id]) then
if RedDotManager:GetRedDotState("FacBuildModeMenuItem", id) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
end
return false
end,
},
SNSNormalDialogSubCell = {
msgs = {
MessageConst.ON_READ_SNS_DIALOG,
},
needArg = true,
readLike = true,
Check = function(dialogId)
local dialogHasRead = GameInstance.player.sns:DialogHasRead(dialogId)
if not dialogHasRead then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end,
},
SNSMissionDialogCell = {
msgs = {
MessageConst.ON_READ_SNS_DIALOG,
},
needArg = true,
readLike = true,
Check = function(dialogId)
local dialogHasRead = GameInstance.player.sns:DialogHasRead(dialogId)
if not dialogHasRead then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end,
},
SNSContactNpcCellTopic = {
msgs = {
MessageConst.ON_READ_SNS_DIALOG,
},
needArg = true,
readLike = true,
Check = function(chatId)
local showingTopicDialogInfos = SNSUtils.getShowingTopicDialogInfos(chatId)
for _, info in ipairs(showingTopicDialogInfos) do
local topicDialogId = info.dialogId
local dialogHasRead = GameInstance.player.sns:DialogHasRead(topicDialogId)
if not dialogHasRead then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
return false
end,
},
SNSContactNpcCell = {
sons = {
SNSNormalDialogSubCell = false,
},
needArg = true,
readLike = true,
Check = function(chatId)
local succ, chatInfo = GameInstance.player.sns.chatInfoDic:TryGetValue(chatId)
if not succ then
return false
end
for _, dialogId in pairs(chatInfo.dialogIds) do
local dialogCfg = Tables.sNSDialogTable[dialogId]
if string.isEmpty(dialogCfg.topicId) then
local redDotState = RedDotManager:GetRedDotState("SNSNormalDialogSubCell", dialogId)
if redDotState then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
end
return false
end,
},
SNSBarkerTabCell = {
sons = {
SNSContactNpcCellTopic = false,
SNSContactNpcCell = false,
},
msgs = {
MessageConst.ON_SNS_BARKER_TAB_READ_STATE_CHANGE,
},
needArg = false,
readLike = true,
Check = function()
local succ, read = ClientDataManagerInst:GetBool(SNSUtils.NORMAL_TAB_READ, false, false, SNSUtils.SNS_CATEGORY)
if succ and read then
return false
end
local chatInfoDic = GameInstance.player.sns.chatInfoDic
for chatId, chatInfo in pairs(chatInfoDic) do
local topicRedDotState = RedDotManager:GetRedDotState("SNSContactNpcCellTopic", chatId)
if topicRedDotState then
return true, UIConst.RED_DOT_TYPE.Normal
end
local hasRedDot = RedDotManager:GetRedDotState("SNSContactNpcCell", chatId)
if hasRedDot then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
return false
end
},
SNSMissionTabCell = {
sons = {
SNSMissionDialogCell = false,
},
msgs = {
MessageConst.ON_SNS_MISSION_TAB_READ_STATE_CHANGE,
},
needArg = false,
readLike = true,
Check = function()
local succ, read = ClientDataManagerInst:GetBool(SNSUtils.MISSION_TAB_READ, false, false, SNSUtils.SNS_CATEGORY)
if succ and read then
return false
end
local missionRelatedSNSDialogIds = GameInstance.player.sns.missionRelatedSNSDialogIds
for _, dialogId in pairs(missionRelatedSNSDialogIds) do
local hasRedDot = RedDotManager:GetRedDotState("SNSMissionDialogCell", dialogId)
if hasRedDot then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
return false
end
},
SNSHudEntry = {
sons = {
SNSBarkerTabCell = false,
SNSMissionTabCell = false,
FriendChatUnRead = false,
},
needArg = false,
readLike = false,
Check = function()
local hasRedDot = RedDotManager:GetRedDotState("FriendChatUnRead")
if hasRedDot then
return true, UIConst.RED_DOT_TYPE.Normal
end
hasRedDot = RedDotManager:GetRedDotState("SNSMissionTabCell")
if hasRedDot then
return true, UIConst.RED_DOT_TYPE.Normal
end
hasRedDot = RedDotManager:GetRedDotState("SNSBarkerTabCell")
if hasRedDot then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end
},
CharInfoPotential = {
msgs = {
MessageConst.ON_ITEM_COUNT_CHANGED,
},
readLike = false,
needArg = true,
Check = function(charInstId)
if not CharInfoUtils.isCharDevAvailable(charInstId) then
return false
end
local charInfo = CharInfoUtils.getPlayerCharInfoByInstId(charInstId)
local hasValue
local characterPotentialList
hasValue, characterPotentialList = Tables.characterPotentialTable:TryGetValue(charInfo.templateId)
if not hasValue or charInfo.potentialLevel >= #characterPotentialList.potentialUnlockBundle then
return false
end
local potentialData = characterPotentialList.potentialUnlockBundle[charInfo.potentialLevel]
local itemId = potentialData.itemIds[0]
local itemCount = Utils.getItemCount(itemId)
local needCount = potentialData.itemCnts[0]
if itemCount >= needCount then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end
},
CharInfoPotentialSkill = {
msgs = {
MessageConst.ON_ITEM_COUNT_CHANGED,
},
readLike = false,
needArg = true,
Check = function(args)
local charInstId = args.charInstId
if not CharInfoUtils.isCharDevAvailable(charInstId) then
return false
end
local potentialLevel = args.potentialLevel
local charInfo = CharInfoUtils.getPlayerCharInfoByInstId(charInstId)
if not charInfo or charInfo.charType == GEnums.CharType.Trial or potentialLevel ~= charInfo.potentialLevel + 1 then
return false
end
local _, characterPotentialList = Tables.characterPotentialTable:TryGetValue(charInfo.templateId)
if not characterPotentialList or potentialLevel > #characterPotentialList.potentialUnlockBundle then
return false
end
local potentialData = characterPotentialList.potentialUnlockBundle[CSIndex(potentialLevel)]
local itemId = potentialData.itemIds[0]
local itemCount = Utils.getItemCount(itemId)
local needCount = potentialData.itemCnts[0]
if itemCount >= needCount then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end
},
CharInfoPotentialPicture = {
msgs = {
MessageConst.ON_CHAR_POTENTIAL_PICTURE_READ,
MessageConst.ON_CHAR_POTENTIAL_PICTURE_UNREAD,
},
readLike = true,
needArg = true,
Check = function(args)
local charInstId = args.charInstId
if not CharInfoUtils.isCharDevAvailable(charInstId) then
return false
end
local potentialLevel = args.potentialLevel
local charInfo = CharInfoUtils.getPlayerCharInfoByInstId(charInstId)
if not charInfo or charInfo.charType == GEnums.CharType.Trial or potentialLevel > charInfo.potentialLevel then
return false
end
local _, characterPotentialList = Tables.characterPotentialTable:TryGetValue(charInfo.templateId)
if not characterPotentialList or potentialLevel > #characterPotentialList.potentialUnlockBundle then
return false
end
local potentialData = characterPotentialList.potentialUnlockBundle[CSIndex(potentialLevel)]
for _, itemId in pairs(potentialData.unlockCharPictureItemList) do
local _, pictureId = Tables.pictureItemTable:TryGetValue(itemId)
if pictureId and not GameInstance.player.charBag:IsCharPotentialPictureRead(pictureId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
return false
end,
},
EquipTech = {
msgs = {
MessageConst.ON_SYSTEM_UNLOCK_CHANGED,
},
readLike = false,
needArg = false,
Check = function()
if Utils.isInBlackbox() then
return false
end
if RedDotManager:GetRedDotState("EquipProducer", nil) then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end,
sons = {
EquipFormula = false,
}
},
EquipProducer = {
msgs = {
MessageConst.ON_SYSTEM_UNLOCK_CHANGED,
},
readLike = false,
needArg = true,
Check = function(isSuit)
if Utils.isInBlackbox() then
return false
end
for packId, _ in pairs(Tables.equipPackFormulaTable) do
local _, packData = Tables.equipPackTable:TryGetValue(packId)
if packData and (isSuit == nil or packData.isSuit == isSuit) then
if RedDotManager:GetRedDotState("EquipPack", packId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
end
return false
end,
sons = {
EquipFormula = false,
}
},
EquipPack = {
readLike = false,
needArg = true,
Check = function(packId)
if Utils.isInBlackbox() then
return false
end
local equipTechSystem = GameInstance.player.equipTechSystem
if not equipTechSystem:IsEquipPackUnlocked(packId) then
return false
end
local _, packDataList = Tables.equipPackFormulaTable:TryGetValue(packId)
if not packDataList then
return false
end
local isPackNew = true
local hasNew = false
local isUnread = false
for _, packFormulaData in pairs(packDataList.itemList) do
local formulaId = packFormulaData.formulaId
if not isUnread and equipTechSystem:IsFormulaUnread(formulaId) then
isUnread = true
end
local _, formulaData = Tables.equipFormulaTable:TryGetValue(formulaId)
if formulaData and formulaData.isNew then
local isVersionNewRead = equipTechSystem:IsNewVersionFormulaRead(formulaId)
if not isVersionNewRead then
hasNew = true
end
else
isPackNew = false
end
end
if hasNew then
if isPackNew then
return true, EquipTechConst.EQUIP_PRODUCE_PACK_RED_DOT_TYPE.AllNew
else
return true, EquipTechConst.EQUIP_PRODUCE_PACK_RED_DOT_TYPE.PartialNew
end
elseif isUnread then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end,
sons = {
EquipFormula = false,
}
},
EquipFormula = {
msgs = {
MessageConst.ON_EQUIP_FORMULA_UNREAD,
MessageConst.ON_EQUIP_FORMULA_READ,
MessageConst.ON_NEW_VERSION_EQUIP_FORMULA_READ,
MessageConst.ON_NEW_VERSION_EQUIP_FORMULA_UNREAD,
},
readLike = true,
needArg = true,
Check = function(formulaId)
if Utils.isInBlackbox() then
return false
end
local _, formulaData = Tables.equipFormulaTable:TryGetValue(formulaId)
if formulaData and formulaData.isNew and not GameInstance.player.equipTechSystem:IsNewVersionFormulaRead(formulaId) then
return true, UIConst.RED_DOT_TYPE.New
end
return GameInstance.player.equipTechSystem:IsFormulaUnread(formulaId), UIConst.RED_DOT_TYPE.Normal
end
},
CharInfoProfile = {
readLike = false,
needArg = true,
sons = {
CharVoice = true,
CharDoc = true,
CharInfoDungeon = true,
}
},
CharInfoDungeon = {
readLike = true,
Check = function(charTemplateId)
local dungeonId
local success, _ = pcall(function()
dungeonId = Tables.CharId2DungeonIdTable[charTemplateId]
end)
if success then
return not GameInstance.dungeonManager:IsDungeonPassed(dungeonId)
else
return false
end
end,
needArg = true,
msgs = {
}
},
CharVoice = {
readLike = false,
needArg = true,
Check = function(charTemplateId)
local hasValue
local charData
hasValue, charData = Tables.characterTable:TryGetValue(charTemplateId)
if hasValue then
for _, voiceData in pairs(charData.profileVoice) do
if GameInstance.player.charBag:IsCharVoiceUnread(voiceData.id) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
end
return false
end,
sons = {
CharVoiceEntry = false
}
},
CharVoiceEntry = {
msgs = {
MessageConst.ON_CHAR_VOICE_READ,
MessageConst.ON_CHAR_VOICE_UNREAD,
MessageConst.ON_CHAR_VOICE_LOCKED,
MessageConst.ON_CHAR_VOICE_UNLOCKED,
},
readLike = true,
needArg = true,
Check = function(charVoiceId)
return GameInstance.player.charBag:IsCharVoiceUnread(charVoiceId), UIConst.RED_DOT_TYPE.New
end
},
CharDoc = {
readLike = false,
needArg = true,
Check = function(charTemplateId)
local hasValue
local charData
hasValue, charData = Tables.characterTable:TryGetValue(charTemplateId)
if hasValue then
for _, recordData in pairs(charData.profileRecord) do
if GameInstance.player.charBag:IsCharDocUnread(recordData.id) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
end
return false
end,
sons = {
CharDocEntry = false
}
},
CharDocEntry = {
msgs = {
MessageConst.ON_CHAR_DOC_READ,
MessageConst.ON_CHAR_DOC_UNREAD,
MessageConst.ON_CHAR_DOC_LOCKED,
MessageConst.ON_CHAR_DOC_UNLOCKED,
},
readLike = true,
needArg = true,
Check = function(charDocId)
return GameInstance.player.charBag:IsCharDocUnread(charDocId), UIConst.RED_DOT_TYPE.New
end
},
AdventureBook = {
readLike = false,
needArg = false,
sons = {
AdventureBookTabDaily = true,
AdventureBookTabStage = true,
AdventureBookTabDungeon = true,
AdventureBookTabWeekRaid = true,
},
},
AdventureBookTabStage = {
msgs = {
MessageConst.ON_ADVENTURE_TASK_MODIFY,
MessageConst.ON_ADVENTURE_BOOK_STAGE_MODIFY,
},
readLike = false,
needArg = false,
Check = AdventureBookUtils.CheckRedDotAdventureBookTabStage
},
AdventureBookTabStageTaskCell = {
msgs = {
MessageConst.ON_ADVENTURE_TASK_MODIFY,
MessageConst.ON_ADVENTURE_BOOK_STAGE_MODIFY,
},
readLike = true,
needArg = true,
Check = function(taskId)
return GameInstance.player.adventure:IsTaskComplete(taskId)
end
},
AdventureBookTabDaily = {
msgs = {
MessageConst.ON_ADVENTURE_TASK_MODIFY,
MessageConst.ON_DAILY_ACTIVATION_MODIFY,
},
readLike = false,
needArg = false,
Check = AdventureBookUtils.CheckRedDotAdventureBookTabDaily
},
AdventureBookTabDailyTaskCell = {
msgs = {
MessageConst.ON_ADVENTURE_TASK_MODIFY,
MessageConst.ON_DAILY_ACTIVATION_MODIFY,
},
readLike = false,
needArg = true,
Check = function(taskId)
local curActivation = GameInstance.player.adventure.adventureBookData.dailyActivation
local maxActivation = 0
for _, cfg in pairs(Tables.dailyActivationRewardTable) do
if cfg.activation > maxActivation then
maxActivation = cfg.activation
end
end
if curActivation >= maxActivation then
return false
end
local taskDic = GameInstance.player.adventure.adventureBookData.adventureTasks
local csTask = taskDic:get_Item(taskId)
return csTask.isComplete
end
},
AdventureBookTabDungeon = {
msgs = {
MessageConst.ON_SUB_GAME_READ,
},
readLike = false,
needArg = false,
Check = AdventureBookUtils.CheckRedDotAdventureBookTabDungeon
},
AdventureDungeonTab = {
msgs = {
MessageConst.ON_SUB_GAME_READ,
},
readLike = false,
needArg = true,
Check = function(ids)
for _, id in pairs(ids) do
if GameInstance.player.subGameSys:IsGameUnread(id) then
return true
end
end
return false
end
},
AdventureDungeonCell = {
msgs = {
MessageConst.ON_SUB_GAME_READ,
},
readLike = false,
needArg = true,
Check = function(ids)
for _, id in pairs(ids) do
if GameInstance.player.subGameSys:IsGameUnlocked(id) and
GameInstance.player.subGameSys:IsGameUnread(id) then
return true, UIConst.RED_DOT_TYPE.New
end
end
return false
end
},
AdventureBookTabTrain = {
msgs = {
MessageConst.ON_SUB_GAME_READ,
},
readLike = false,
needArg = false,
Check = AdventureBookUtils.CheckRedDotAdventureBookTabTrain
},
AdventureBookTabBlackbox = {
msgs = {
MessageConst.ON_BLACKBOX_ACTIVE,
MessageConst.ON_BLACKBOX_READ,
},
readLike = false,
needArg = false,
Check = AdventureBookUtils.CheckRedDotAdventureBookTabBlackbox
},
DungeonRead = {
msgs = {
MessageConst.ON_SUB_GAME_READ,
},
readLike = true,
needArg = true,
Check = function(dungeonIds)
for _, id in pairs(dungeonIds) do
if DungeonUtils.isDungeonUnlock(id) and
GameInstance.player.subGameSys:IsGameUnread(id) then
return true, UIConst.RED_DOT_TYPE.New
end
end
return false
end
},
DungeonReadNormal = {
msgs = {
MessageConst.ON_SUB_GAME_READ,
},
readLike = true,
needArg = true,
Check = function(dungeonIds)
for _, id in pairs(dungeonIds) do
if DungeonUtils.isDungeonUnlock(id) and
GameInstance.player.subGameSys:IsGameUnread(id) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
return false
end
},
AdventureBlackboxCell = {
msgs = {
MessageConst.ON_BLACKBOX_ACTIVE,
MessageConst.ON_BLACKBOX_READ,
},
readLike = false,
needArg = true,
Check = function(blackboxIds)
local dungeonMgr = GameInstance.dungeonManager
for _, blackboxId in ipairs(blackboxIds) do
if dungeonMgr:IsDungeonUnlocked(blackboxId) and not dungeonMgr:IsBlackboxRead(blackboxId) then
return true
end
end
return false
end
},
AdventureBookTabWeekRaid = {
sons = {
WeekRaidBattlePass = true,
},
readLike = false,
},
RecycleBinCanPickUp = {
msgs = {
MessageConst.ON_RECYCLE_BIN_CAN_PICK_UP,
},
readLike = false,
needArg = false,
Check = function()
local pickUpList = GameInstance.player.recycleBinSystem.canPickUpInstIds
return pickUpList.Count > 0, UIConst.RED_DOT_TYPE.Normal
end
},
SettlementDefenseTerminal = {
msgs = {
MessageConst.ON_TOWER_DEFENSE_LEVEL_UNLOCKED,
MessageConst.ON_TOWER_DEFENSE_LEVEL_COMPLETED,
},
readLike = false,
needArg = false,
Check = function()
if not Utils.isSettlementDefenseGuideCompleted() then
return false
end
local dangerSettlementIds = GameInstance.player.towerDefenseSystem.dangerSettlementIds
return dangerSettlementIds.Count > 0, UIConst.RED_DOT_TYPE.Normal
end,
},
CheckIn = {
readLike = false,
needArg = false,
Check = RedDotUtils.hasCheckInRewardsNotCollected,
msgs = {
MessageConst.ON_ACTIVITY_UPDATED
}
},
CheckInTab = {
readLike = false,
needArg = true,
Check = RedDotUtils.hasCheckInRewardsNotCollectedInRange,
msgs = {
MessageConst.ON_CHECK_IN_UPDATED
},
},
MapUnreadLevel = {
msgs = {
MessageConst.ON_READ_LEVEL,
},
readLike = true,
needArg = false,
Check = function(levelId)
return not GameInstance.player.mapManager:IsLevelRead(levelId), UIConst.RED_DOT_TYPE.Normal
end
},
MapRemind = {
readLike = false,
needArg = false,
sons = {
MapImportantMatters = true,
MapCollectionTips = true,
},
},
MapImportantMatters = {
readLike = false,
needArg = false,
},
MapCollectionTips = {
readLike = false,
needArg = false
},
CommonMapRemind = {
msgs = {
MessageConst.ON_MAP_REMIND_UPDATE,
},
readLike = false,
needArg = true,
Check = function(args)
return MapUtils.mapRemindRedDotCheck(args)
end,
},
CommonMapRemindReadLike = {
msgs = {
MessageConst.ON_MAP_REMIND_UPDATE,
},
readLike = true,
needArg = true,
Check = function(args)
return MapUtils.mapRemindRedDotCheck(args)
end,
},
Wiki = {
readLike = false,
needArg = false,
Check = function()
if not Utils.isSystemUnlocked(GEnums.UnlockSystemType.Wiki) then
return false
end
for _, categoryData in pairs(Tables.wikiCategoryTable) do
local isUnread = RedDotManager:GetRedDotState("WikiCategory", categoryData.categoryId)
if isUnread then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
return false
end,
sons = {
WikiCategory = false,
}
},
WikiCategory = {
readLike = false,
needArg = true,
Check = function(categoryId)
if not Utils.isSystemUnlocked(GEnums.UnlockSystemType.Wiki) then
return false
end
local _, wikiGroupData = Tables.wikiGroupTable:TryGetValue(categoryId)
if not wikiGroupData then
return false
end
for _, groupData in pairs(wikiGroupData.list) do
local isUnread = RedDotManager:GetRedDotState("WikiGroup", groupData.groupId)
if isUnread then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
return false
end,
sons = {
WikiGroup = false
}
},
WikiGroup = {
readLike = false,
needArg = true,
Check = function(groupId)
if not Utils.isSystemUnlocked(GEnums.UnlockSystemType.Wiki) then
return false
end
local _, wikiEntryList = Tables.wikiEntryTable:TryGetValue(groupId)
if not wikiEntryList then
return false
end
for _, wikiEntryId in pairs(wikiEntryList.list) do
if WikiUtils.isWikiEntryUnread(wikiEntryId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
return false
end,
sons = {
WikiEntry = false,
},
},
WikiEntry = {
msgs = {
MessageConst.ON_WIKI_ENTRY_UNLOCKED,
MessageConst.ON_WIKI_ENTRY_READ,
},
readLike = true,
needArg = true,
Check = function(entryId)
if not Utils.isSystemUnlocked(GEnums.UnlockSystemType.Wiki) then
return false
end
return WikiUtils.isWikiEntryUnread(entryId), UIConst.RED_DOT_TYPE.New
end
},
WikiGuideEntry = {
msgs = {
MessageConst.ON_WIKI_ENTRY_UNLOCKED,
MessageConst.ON_WIKI_ENTRY_READ,
},
readLike = true,
needArg = true,
Check = function(entryId)
if not Utils.isSystemUnlocked(GEnums.UnlockSystemType.Wiki) then
return false
end
return WikiUtils.isWikiEntryUnread(entryId), UIConst.RED_DOT_TYPE.Normal
end
},
WikiLimitedGuide = {
msgs = {
MessageConst.ON_LIMITED_GUIDE_WIKI_ENTRY_READ_STATE_CHANGE,
},
readLike = false,
needArg = false,
Check = function()
local guideLimitedCtrl = require_ex('UI/Panels/GuideLimited/GuideLimitedCtrl')
return not string.isEmpty(guideLimitedCtrl.GuideLimitedCtrl.s_waitReadGuideWikiEntry), UIConst.RED_DOT_TYPE.Normal
end
},
Friend = {
sons = {
NewFriendRequest = true,
},
readLike = false,
},
NewFriendRequest = {
msgs = {
MessageConst.ON_FRIEND_REQUEST_CHANGE,
},
readLike = false,
needArg = false,
Check = function()
return GameInstance.player.friendSystem:NeedFriendRequestRedDot(), UIConst.RED_DOT_TYPE.Normal
end
},
FriendChatUnRead = {
Check = function()
local chatPanelShow = false
local res, ctrl = UIManager:IsOpen(PanelId.SNSFriend)
if res then
chatPanelShow = ctrl:IsShow()
end
for index, roleId in pairs(GameInstance.player.friendChatSystem.luaShowValidRoleIds) do
if GameInstance.player.friendChatSystem.luaShowRoleId ~= roleId or not chatPanelShow then
local chatInfo = GameInstance.player.friendChatSystem:GetChatInfo(roleId)
if chatInfo then
if chatInfo.unReadNum > 0 then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
end
end
return false
end,
needArg = false,
readLike = false,
msgs = {
MessageConst.FRIEND_CHAT_MSG_READ,
},
},
NewBusinessCard = {
msgs = {
MessageConst.ON_BUSINESS_CARD_UNLOCK,
MessageConst.ON_BUSINESS_CARD_READ,
},
readLike = false,
needArg = true,
Check = function(id)
return GameInstance.player.friendSystem:IsBusinessCardUnlock(CS.Beyond.Gameplay.FriendBusinessCardUnlockType.BusinessCardTopic, id) and
not GameInstance.player.friendSystem:IsBusinessCardReadRedDot(CS.Beyond.Gameplay.FriendBusinessCardUnlockType.BusinessCardTopic, id), UIConst.RED_DOT_TYPE.Normal
end
},
NewAvatar = {
msgs = {
MessageConst.ON_AVATAR_UNLOCK,
MessageConst.ON_AVATAR_READ,
},
readLike = false,
needArg = true,
Check = function(id)
return GameInstance.player.friendSystem:IsBusinessCardUnlock(CS.Beyond.Gameplay.FriendBusinessCardUnlockType.Avatar, id) and
not GameInstance.player.friendSystem:IsBusinessCardReadRedDot(CS.Beyond.Gameplay.FriendBusinessCardUnlockType.Avatar, id), UIConst.RED_DOT_TYPE.Normal
end
},
NewAvatarFrame = {
msgs = {
MessageConst.ON_AVATAR_FRAME_UNLOCK,
MessageConst.ON_AVATAR_FRAME_READ,
},
readLike = false,
needArg = true,
Check = function(id)
return GameInstance.player.friendSystem:IsBusinessCardUnlock(CS.Beyond.Gameplay.FriendBusinessCardUnlockType.AvatarFrame, id) and
not GameInstance.player.friendSystem:IsBusinessCardReadRedDot(CS.Beyond.Gameplay.FriendBusinessCardUnlockType.AvatarFrame, id), UIConst.RED_DOT_TYPE.Normal
end
},
BusinessCard = {
sons = {
NewBusinessCard = true,
NewAvatar = true,
NewAvatarFrame = true,
},
readLike = false,
},
NewAvatarInfo = {
sons = {
NewAvatar = true,
NewAvatarFrame = true,
},
readLike = false,
},
SettlementMainTab = {
msgs = {
MessageConst.ON_SETTLEMENT_MODIFY,
},
readLike = false,
needArg = true,
Check = function(arg)
local stlId
if type(arg) == "string" then
stlId = arg
else
stlId = unpack(arg)
end
return RedDotUtils.hasSettlementCanUpgradeRedDot(stlId), UIConst.RED_DOT_TYPE.Normal
end,
},
DomainGradeReward = {
msgs = {
MessageConst.ON_DOMAIN_DEVELOPMENT_EXP_CHANGE,
MessageConst.ON_DOMAIN_DEVELOPMENT_LEVEL_REWARD_GET,
},
readLike = false,
needArg = true,
Check = function(domainId)
return RedDotUtils.hasSingleDomainGradeRedDot(domainId)
end,
},
DomainSingleMap = {
msgs = {
MessageConst.ON_SETTLEMENT_MODIFY,
MessageConst.ON_PACK_ITEM_END,
MessageConst.ON_SELECT_BUYER_END,
MessageConst.ON_DOMAIN_DEVELOPMENT_EXP_CHANGE,
MessageConst.ON_DOMAIN_DEVELOPMENT_LEVEL_REWARD_GET,
},
readLike = false,
needArg = true,
Check = function(domainId)
return RedDotUtils.hasSingleDomainDevelopmentRedDot(domainId)
end,
},
DomainOtherMap = {
msgs = {
MessageConst.ON_SETTLEMENT_MODIFY,
MessageConst.ON_PACK_ITEM_END,
MessageConst.ON_SELECT_BUYER_END,
MessageConst.ON_DOMAIN_DEVELOPMENT_EXP_CHANGE,
MessageConst.ON_DOMAIN_DEVELOPMENT_LEVEL_REWARD_GET,
MessageConst.ON_DOMAIN_DEPOT_DELIVERY_REWARD,
},
readLike = false,
needArg = true,
Check = function(domainId)
for checkDomainId, _ in cs_pairs(GameInstance.player.domainDevelopmentSystem.domainDevDataDic) do
if checkDomainId ~= domainId and RedDotUtils.hasSingleDomainDevelopmentRedDot(checkDomainId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
return false
end,
},
DomainEntry = {
msgs = {
MessageConst.ON_SETTLEMENT_MODIFY,
MessageConst.ON_PACK_ITEM_END,
MessageConst.ON_SELECT_BUYER_END,
MessageConst.ON_DOMAIN_DEVELOPMENT_EXP_CHANGE,
MessageConst.ON_DOMAIN_DEVELOPMENT_LEVEL_REWARD_GET,
},
sons = {
},
readLike = false,
needArg = false,
Check = function()
for checkDomainId, _ in cs_pairs(GameInstance.player.domainDevelopmentSystem.domainDevDataDic) do
if RedDotUtils.hasSingleDomainDevelopmentRedDot(checkDomainId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
return false
end,
},
KiteStationCollectionReward = {
msgs = {
MessageConst.ON_KITE_STATION_COLLECTION_REWARD
},
readLike = false,
needArg = true,
Check = function(stationId)
return GameInstance.player.kiteStationSystem:CheckKiteStationCollectionReward(stationId), UIConst.RED_DOT_TYPE.Normal
end,
},
AchievementMain = {
readLike = false,
needArg = false,
Check = function()
for _, achievementData in pairs(Tables.achievementTable) do
if achievementData ~= nil and GameInstance.player.achievementSystem:IsAchievementUnread(achievementData.achieveId) then
return true, UIConst.RED_DOT_TYPE.New
end
end
return false
end,
sons = {
AchievementGroup = false,
},
},
AchievementCategory = {
readLike = false,
needArg = true,
Check = function(categoryId)
local suc, categoryData = Tables.achievementTypeTable:TryGetValue(categoryId)
if not suc then
return false
end
for _, achievementData in pairs(Tables.achievementTable) do
if achievementData ~= nil then
for i, groupData in pairs(categoryData.achievementGroupData) do
if achievementData.groupId == groupData.groupId
and GameInstance.player.achievementSystem:IsAchievementUnread(achievementData.achieveId) then
return true, UIConst.RED_DOT_TYPE.New
end
end
end
end
return false
end,
sons = {
AchievementItem = false,
},
},
AchievementGroup = {
readLike = false,
needArg = true,
Check = function(groupId)
for _, achievementData in pairs(Tables.achievementTable) do
if achievementData ~= nil then
if achievementData.groupId == groupId
and GameInstance.player.achievementSystem:IsAchievementUnread(achievementData.achieveId) then
return true, UIConst.RED_DOT_TYPE.New
end
end
end
return false
end,
sons = {
AchievementItem = false,
},
},
AchievementItem = {
msgs = {
MessageConst.ON_UNREAD_ACHIEVEMENT,
MessageConst.ON_READ_ACHIEVEMENT,
},
readLike = true,
needArg = true,
Check = function(achievementId)
return GameInstance.player.achievementSystem:IsAchievementUnread(achievementId), UIConst.RED_DOT_TYPE.New
end,
},
WeekRaid = {
sons = {
WeekRaidBattlePass = true,
WeekRaidDelegate = false,
},
readLike = false,
},
WeekRaidBattlePass = {
msgs = {
MessageConst.ON_WEEK_RAID_BATTLE_PASS_UPDATE,
},
readLike = false,
needArg = false,
Check = function()
local isAnyReceivable = GameInstance.player.weekRaidSystem:IsAnyBattlePassRewardReceivable()
return isAnyReceivable, UIConst.RED_DOT_TYPE.Normal
end,
},
WeekRaidBattlePassRefresh = {
msgs = {
MessageConst.ON_WEEK_RAID_BATTLE_PASS_UPDATE,
},
readLike = false,
needArg = false,
Check = function()
local mapMarkInstIds = GameInstance.player.weekRaidSystem:GetWeekRaidEntryMapMarkInstIds()
if mapMarkInstIds.Count == 0 then
return false
end
local isAnyReceivable = GameInstance.player.weekRaidSystem:IsAnyBattlePassRewardReceivable()
if not isAnyReceivable then
return false
end
local nextRefreshTime = Utils.getNextWeeklyServerRefreshTime()
local currentTime = DateTimeUtils.GetCurrentTimestampBySeconds()
local deltaTime = nextRefreshTime - currentTime
local notify = deltaTime <= Tables.weekRaidConst.weekRaidBattlePassRefreshMapRemindTime
return notify, UIConst.RED_DOT_TYPE.Normal
end,
},
WeekRaidDelegate = {
msgs = {
MessageConst.ON_QUEST_STATE_CHANGE,
MessageConst.ON_QUEST_OBJECTIVE_UPDATE,
},
readLike = false,
needArg = true,
Check = function(args)
if args == nil then
local isAnyCompleted = GameInstance.player.weekRaidSystem:IsAnyMissionCompleted()
return isAnyCompleted, UIConst.RED_DOT_TYPE.Normal
end
if args and args.missionId ~= nil then
local isCompleted = GameInstance.player.weekRaidSystem:IsMissionCompleted(args.missionId)
if isCompleted then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end
if args and args.missionType ~= nil then
local delegateList = WeeklyRaidUtils.TabConfig[args.missionType].getDelegate()
local isAnyCompleted = GameInstance.player.weekRaidSystem:IsAnyMissionCompleted(delegateList)
return isAnyCompleted, UIConst.RED_DOT_TYPE.Normal
end
return false, UIConst.RED_DOT_TYPE.Normal
end,
},
ActivityCenter = {
msgs = {
MessageConst.ON_ACTIVITY_CENTER_CLOSE,
MessageConst.ON_ACTIVITY_UPDATED,
},
readLike = false,
needArg = false,
Check = function()
local activities = GameInstance.player.activitySystem:GetAllActivities()
for _, activity in cs_pairs(activities) do
local _, activityData = Tables.activityTable:TryGetValue(activity.id)
if activityData then
if ActivityConst.ACTIVITY_TABLE[activityData.type] then
local redDotName = ActivityConst.ACTIVITY_TABLE[activityData.type].redDot
if RedDotManager:GetRedDotState(redDotName, activity.id) then
return true
end
end
end
end
return false
end,
sons = ActivityConst.ACTIVITY_COMMON_SONS,
},
ActivityTableMore = {
msgs = {
MessageConst.ON_ACTIVITY_NEW_RED_DOT_SET_FALSE,
MessageConst.ON_ACTIVITY_UPDATED,
},
readLike = false,
needArg = true,
Check = function(moreActivityData)
for i = 1, #moreActivityData do
local activityData = moreActivityData[i]
if not activityData then
return false
end
local redDotName = ActivityConst.ACTIVITY_TABLE[activityData.type].redDot
if RedDotManager:GetRedDotState(redDotName, activityData.id) then
return true
end
end
return false
end,
sons = ActivityConst.ACTIVITY_COMMON_SONS,
},
ActivityIntroMission = {
msgs = {
MessageConst.ON_ACTIVITY_NEW_RED_DOT_SET_FALSE,
MessageConst.ON_ACTIVITY_UPDATED,
},
readLike = true,
needArg = true,
Check = function(id)
return ActivityUtils.isNewIntroMissionActivity(id)
end,
},
ActivityBasic = {
msgs = {
MessageConst.ON_ACTIVITY_NEW_RED_DOT_SET_FALSE,
MessageConst.ON_ACTIVITY_UPDATED,
},
readLike = false,
needArg = true,
Check = function(id)
return ActivityUtils.checkActivityRedDot(id)
end
},
ActivityBaseMultiStage = {
msgs = {
MessageConst.ON_ACTIVITY_NEW_RED_DOT_SET_FALSE,
MessageConst.ON_LEVEL_REWARD_UPDATE,
},
readLike = false,
needArg = true,
Check = function(id)
return RedDotUtils.hasActivityBaseMultiStageRedDot(id)
end
},
ActivityGachaBeginner = {
msgs = {
MessageConst.ON_ACTIVITY_NEW_RED_DOT_SET_FALSE,
MessageConst.ON_GACHA_POOL_ROLE_DATA_CHANGED,
MessageConst.ON_LEVEL_REWARD_UPDATE,
MessageConst.ON_ACTIVITY_UPDATED,
},
readLike = false,
needArg = true,
Check = function(id)
return RedDotUtils.hasActivityGachaBeginnerRedDot(id)
end
},
ActivityGachaBeginnerJumpPoolBtn = {
msgs = {
MessageConst.ON_ACTIVITY_NEW_RED_DOT_SET_FALSE,
MessageConst.ON_GACHA_POOL_ROLE_DATA_CHANGED,
MessageConst.ON_LEVEL_REWARD_UPDATE,
MessageConst.ON_ACTIVITY_UPDATED,
},
readLike = false,
needArg = false,
Check = function()
if RedDotUtils.hasGachaBeginnerTicketNotUesRedDot() then
return true, UIConst.RED_DOT_TYPE.Normal
end
return RedDotUtils.hasGachaStarterCumulateRedDot(Tables.charGachaConst.beginnerGachaActivityPoolId)
end
},
ActivityBaseMultiStageReward = {
msgs = {
MessageConst.ON_ACTIVITY_NEW_RED_DOT_SET_FALSE,
MessageConst.ON_LEVEL_REWARD_UPDATE,
},
readLike = true,
needArg = true,
Check = function(canReceive)
return canReceive
end
},
ActivityCheckIn = {
msgs = {
MessageConst.ON_ACTIVITY_NEW_RED_DOT_SET_FALSE,
MessageConst.ON_ACTIVITY_CHECK_IN,
MessageConst.ON_ACTIVITY_UPDATED,
},
readLike = false,
needArg = true,
Check = function(id)
local activity = GameInstance.player.activitySystem:GetActivity(id)
if activity and activity.loginDays ~= activity.rewardDays.Count then
return true, UIConst.RED_DOT_TYPE.Normal
end
return ActivityUtils.checkActivityRedDot(id)
end
},
ActivityCheckInReward = {
msgs = {
MessageConst.ON_ACTIVITY_NEW_RED_DOT_SET_FALSE,
MessageConst.ON_ACTIVITY_CHECK_IN,
},
readLike = true,
needArg = true,
Check = function(canReceive)
return canReceive
end
},
ActivityGlobalEffect = {
msgs = {
MessageConst.ON_ACTIVITY_NEW_RED_DOT_SET_FALSE,
MessageConst.ON_ACTIVITY_UPDATED,
},
readLike = false,
needArg = true,
Check = function(id)
local suc,type = ActivityUtils.checkActivityRedDot(id)
if suc then
return suc, type
elseif ActivityUtils.isNewActivityStaminaDiscountDay(id) then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end
},
ActivityNormalChallenge = {
msgs = {
MessageConst.ON_ACTIVITY_NEW_RED_DOT_SET_FALSE,
MessageConst.ON_READ_GAME_ENTRANCE_SERIES,
MessageConst.ON_SUB_GAME_READ,
MessageConst.ON_ACTIVITY_UPDATED,
},
sons = {
ActivityNormalChallengeSeries = false,
},
readLike = false,
needArg = true,
Check = function(activityId)
local activityData = GameInstance.player.activitySystem:GetActivity(activityId)
if not activityData then
return false
end
if ActivityUtils.hasIntroMissionAndComplete(activityId) then
local _, activitySeriesCfg = Tables.activityGameEntranceSeriesTable:TryGetValue(activityId)
for seriesId, seriesCfg in pairs(activitySeriesCfg.seriesMap) do
local hasRedDot = RedDotUtils.hasActivityNormalChallengeSeriesRedDot(seriesId)
if hasRedDot then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
end
return ActivityUtils.checkActivityRedDot(activityId)
end
},
ActivityNormalChallengeSeries = {
msgs = {
MessageConst.ON_READ_GAME_ENTRANCE_SERIES,
MessageConst.ON_SUB_GAME_READ,
},
readLike = false,
needArg = true,
Check = function(seriesId)
return RedDotUtils.hasActivityNormalChallengeSeriesRedDot(seriesId)
end
},
ActivityNormalChallengeGotoDetailBtn = {
msgs = {
MessageConst.ON_READ_GAME_ENTRANCE_SERIES,
MessageConst.ON_SUB_GAME_READ,
},
sons = {
ActivityNormalChallengeSeries = false,
},
readLike = false,
needArg = true,
Check = function(activityId)
local activityData = GameInstance.player.activitySystem:GetActivity(activityId)
if not activityData or not activityData.isUnlocked then
return false
end
local _, activitySeriesCfg = Tables.activityGameEntranceSeriesTable:TryGetValue(activityId)
for seriesId, seriesCfg in pairs(activitySeriesCfg.seriesMap) do
local hasRedDot = RedDotUtils.hasActivityNormalChallengeSeriesRedDot(seriesId)
if hasRedDot then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
return false
end
},
ActivityCharacterGuideLine = {
msgs = {
MessageConst.ON_ACTIVITY_NEW_RED_DOT_SET_FALSE,
MessageConst.ON_ACTIVITY_UPDATED,
},
readLike = false,
needArg = true,
Check = function(activityId)
return ActivityUtils.checkActivityRedDot(activityId)
end
},
ActivityCharTrial = {
msgs = {
MessageConst.ON_CHARACTER_TRIAL_INFO_CHANGE,
MessageConst.ON_ACTIVITY_NEW_RED_DOT_SET_FALSE,
MessageConst.ON_ACTIVITY_UPDATED,
},
readLike = true,
needArg = true,
Check = function(activityId)
local activityData = GameInstance.player.activitySystem:GetActivity(activityId)
if not activityData or not activityData.isUnlocked then
return false
end
for dungeonId, trialData in pairs(Tables.activityCharTrial) do
if trialData.activityId == activityId then
local trialStatus = GameInstance.player.activitySystem:CheckCharacterTrial(activityId, dungeonId)
if trialStatus == CS.Beyond.Gameplay.ActivitySystem.CharacterTrialStatus.CanGetReward then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
end
return ActivityUtils.checkActivityRedDot(activityId)
end
},
ActivityCharTrialGetReward = {
Check = function(args)
local trialStatus = GameInstance.player.activitySystem:CheckCharacterTrial(args.activityId, args.dungeonId)
if trialStatus == CS.Beyond.Gameplay.ActivitySystem.CharacterTrialStatus.CanGetReward then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end,
readLike = true,
needArg = true,
msgs = {
MessageConst.ON_CHARACTER_TRIAL_INFO_CHANGE,
},
},
ActivityHighDifficultyChallenge = {
msgs = {
MessageConst.ON_ACTIVITY_NEW_RED_DOT_SET_FALSE,
MessageConst.ON_ACTIVITY_HIGH_DIFFICULTY_NEW_RED_DOT_SET_FALSE,
MessageConst.ON_ACTIVITY_UPDATED,
},
readLike = false,
needArg = true,
Check = function(id)
if GameInstance.player.activitySystem:GetActivityStatus(id) == GEnums.ActivityStatus.InProgress then
local activity = GameInstance.player.activitySystem:GetActivity(id)
for _, seriesInfo in pairs(activity.seriesDataMap) do
if ActivityUtils.isNewActivityHighDifficultySeries(id, seriesInfo.SeriesId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
end
return ActivityUtils.checkActivityRedDot(id)
end
},
ActivityHighDifficultyChallengeCell = {
msgs = {
MessageConst.ON_ACTIVITY_HIGH_DIFFICULTY_NEW_RED_DOT_SET_FALSE,
},
readLike = true,
needArg = true,
Check = function(arg)
local id, seriesId = unpack(arg)
if ActivityUtils.isNewActivityHighDifficultySeries(id, seriesId) then
return true, UIConst.RED_DOT_TYPE.New
end
return false
end
},
ActivityConditionalMultiStage = {
msgs = {
MessageConst.ON_READ_ACTIVITY_CONDITION_STAGE,
MessageConst.ON_CONDITIONAL_MULTI_STAGE_UPDATE,
MessageConst.ON_ACTIVITY_NEW_RED_DOT_SET_FALSE,
MessageConst.ON_ACTIVITY_UPDATED,
},
readLike = false,
needArg = true,
Check = function(id)
local activityData = GameInstance.player.activitySystem:GetActivity(id)
if not activityData then
return false
end
if activityData.status == GEnums.ActivityStatus.InProgress then
for stageId, stageData in cs_pairs(activityData.stageDataDict) do
local status = GEnums.ActivityConditionalStageState.__CastFrom(stageData.Status)
if status == GEnums.ActivityConditionalStageState.Completed then
return true, UIConst.RED_DOT_TYPE.Normal
elseif status == GEnums.ActivityConditionalStageState.Unlocked
and ActivityUtils.isNewActivityConditionalStage(stageId) then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
end
return ActivityUtils.checkActivityRedDot(id)
end
},
DomainDepot = {
readLike = false,
needArg = true,
Check = function(domainId)
if RedDotManager:GetRedDotState("DomainDepotInstList", domainId) then
return true
end
if RedDotManager:GetRedDotState("DomainDepotMyOrder") then
return true
end
return false
end,
sons = {
DomainDepotInstList = false,
DomainDepotMyOrder = false,
}
},
DomainDepotInstList = {
readLike = false,
needArg = true,
Check = function(domainId)
local allDepotIdList = GameInstance.player.domainDepotSystem:GetDomainDepotIdListByDomainId(domainId)
if allDepotIdList == nil then
return false
end
for index = 0, allDepotIdList.Count - 1 do
local depotId = allDepotIdList[index]
if DomainDepotUtils.IsDomainDepotDeliverInTradingState(depotId) then
return true
end
end
return false
end,
sons = {
DomainDepotInstCell = false,
}
},
DomainDepotInstCell = {
readLike = false,
needArg = true,
msgs = {
MessageConst.ON_PACK_ITEM_END,
MessageConst.ON_SELECT_BUYER_END,
},
Check = function(depotId)
return DomainDepotUtils.IsDomainDepotDeliverInTradingState(depotId)
end
},
DomainDepotMyOrder = {
msgs = {
MessageConst.ON_DOMAIN_DEPOT_DELIVERY_REWARD
},
readLike = false,
needArg = false,
Check = function()
for _, info in cs_pairs(GameInstance.player.domainDepotSystem.myDelegateDeliverList) do
if info.packageProgress == GEnums.DomainDepotPackageProgress.SendPackageTimeout or
info.packageProgress == GEnums.DomainDepotPackageProgress.WaitingRecvFinalPayment then
return true
end
end
return false
end
},
BattlePass = {
readLike = false,
msgs = {
MessageConst.ON_DOMAIN_DEPOT_DELIVERY_REWARD
},
needArg = false,
Check = function()
if not BattlePassUtils.CheckBattlePassSeasonValid() then
return false
end
local bpSystem = GameInstance.player.battlePassSystem
local seasonRedDot = bpSystem:IsSeasonUnread(bpSystem.seasonData.seasonId)
if seasonRedDot then
return true, UIConst.RED_DOT_TYPE.Normal
end
local planRedDot = BattlePassUtils.CheckHasAvailBpPlanReward()
local taskRedDot = false
for labelId, labelInfo in pairs(bpSystem.taskData.taskLabels) do
local hasRedDot = BattlePassUtils.CheckLabelRedDot(labelId)
if hasRedDot then
taskRedDot = true
break
end
end
if planRedDot or taskRedDot then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end,
sons = {
BattlePassPlan = false,
BattlePassTask = false,
}
},
BattlePassPlan = {
readLike = false,
msgs = {
MessageConst.ON_BATTLE_PASS_LEVEL_UPDATE,
MessageConst.ON_BATTLE_PASS_TRACK_UPDATE,
},
needArg = false,
Check = function()
if BattlePassUtils.CheckHasAvailBpPlanReward() then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end,
},
BattlePassTask = {
readLike = false,
msgs = {
},
needArg = false,
Check = function()
local bpSystem = GameInstance.player.battlePassSystem
for labelId, labelInfo in pairs(bpSystem.taskData.taskLabels) do
local hasLabelRedDot, labelRedDotType = BattlePassUtils.CheckLabelRedDot(labelId)
if hasLabelRedDot then
return true, UIConst.RED_DOT_TYPE.Normal
end
end
return false
end,
sons = {
BattlePassTaskLabel = false
}
},
BattlePassTaskLabel = {
readLike = false,
msgs = {
},
needArg = true,
Check = function(labelId)
return BattlePassUtils.CheckLabelRedDot(labelId)
end,
sons = {
BattlePassTaskItem = false,
}
},
BattlePassTaskItem = {
readLike = false,
msgs = {
MessageConst.ON_BATTLE_PASS_TASK_UPDATE,
MessageConst.ON_BATTLE_PASS_TASK_BASIC_INFO_UPDATE,
MessageConst.ON_BATTLE_PASS_TASK_READ_UPDATE,
},
needArg = true,
Check = function(taskId)
if BattlePassUtils.CheckTaskUnread(taskId) then
return true, UIConst.RED_DOT_TYPE.New
end
return false
end
},
CashShop = {
readLike = false,
needArg = false,
sons = {
CashShopCreditShopGetCredit = true,
},
},
CashShopNewCashGoods = {
readLike = false,
msgs = {
MessageConst.ON_READ_CASH_SHOP_GOODS,
},
needArg = true,
Check = function(goodsIds)
return CashShopUtils.CheckCashShopNewCashGoodsRedDot(goodsIds)
end
},
CashShopToken = {
readLike = false,
msgs = {
MessageConst.ON_SHOP_GOODS_SEE_GOODS_INFO_CHANGE,
},
needArg = true,
Check = function(goodsIds)
for _, goodsId in ipairs(goodsIds) do
local isNew = GameInstance.player.shopSystem:IsNewGoodsId(goodsId)
if isNew then
return true, UIConst.RED_DOT_TYPE.New
end
end
return false
end
},
CashShopTokenNormal = {
readLike = false,
msgs = {
MessageConst.ON_SHOP_GOODS_SEE_GOODS_INFO_CHANGE,
},
needArg = true,
Check = function(goodsIds)
for _, goodsId in ipairs(goodsIds) do
local isNew = GameInstance.player.shopSystem:IsNewGoodsId(goodsId)
if isNew then
return true
end
end
return false
end
},
CashShopCreditShopGetCredit = {
readLike = false,
msgs = {
MessageConst.ON_SPACESHIP_GUEST_ROOM_RECV_VISIT_LIST_REWARD,
MessageConst.ON_SPACESHIP_RECV_QUERY_VISIT_INFO,
},
needArg = false,
Check = function()
return CashShopUtils.CheckSpaceshipCreditShopGetCreditRedDot()
end
},
SSControlCenterRoot = {
readLike = true,
msgs = {
MessageConst.ON_SPACESHIP_ASSIST_DATA_MODIFY,
MessageConst.ON_SPACESHIP_GROW_CABIN_MODIFY,
MessageConst.ON_SPACESHIP_GROW_CABIN_BREED,
MessageConst.ON_SPACESHIP_MANUFACTURING_STATION_SYNC,
MessageConst.ON_SPACESHIP_MANUFACTURING_STATION_COLLECT,
},
needArg = true,
Check = function(roomIndex)
local state = true
for id, index in pairs(roomIndex) do
local succ, roomInfo = GameInstance.player.spaceship:TryGetRoom(id)
if succ then
if roomInfo.type == GEnums.SpaceshipRoomType.GrowCabin then
if not RedDotManager:GetRedDotState("SSGrowCabin", id) then
return false
end
elseif roomInfo.type == GEnums.SpaceshipRoomType.ManufacturingStation then
if not RedDotManager:GetRedDotState("SSManufacturingStation", id) then
return false
end
end
end
end
return state
end,
sons = {
SSGrowCabin = false,
SSManufacturingStation = false,
}
},
SSGrowCabin = {
readLike = true,
needArg = true,
Check = function(roomId)
return GameInstance.player.spaceship:HasGrowCabinProduct(roomId)
end,
msgs = {
MessageConst.ON_SPACESHIP_GROW_CABIN_MODIFY,
MessageConst.ON_SPACESHIP_GROW_CABIN_BREED,
},
},
SSManufacturingStation = {
readLike = true,
needArg = true,
Check = function(roomId)
local beHelpedCreditLeft, _ = GameInstance.player.spaceship:GetCabinAssistedTime(roomId)
local hasProduct = GameInstance.player.spaceship:HasProductToCollect(roomId)
return hasProduct or beHelpedCreditLeft > 0
end,
msgs = {
MessageConst.ON_SPACESHIP_ASSIST_DATA_MODIFY,
MessageConst.ON_SPACESHIP_MANUFACTURING_STATION_SYNC,
MessageConst.ON_SPACESHIP_MANUFACTURING_STATION_COLLECT,
},
},
ValuableDepotInMainHud = {
msgs = {
MessageConst.ON_VALUABLE_DEPOT_CHANGED,
MessageConst.ON_ITEM_LOCKED_STATE_CHANGED,
},
readLike = false,
needArg = false,
Check = function()
local hasRedDot = RedDotUtils.hasValuableDepotTabCommercialItemRedDot()
if hasRedDot then
return true, UIConst.RED_DOT_TYPE.Normal
end
return false
end,
},
ValuableDepot = {
msgs = {},
readLike = false,
needArg = false,
sons = {
ValuableDepotTabCommercialItem = true,
},
},
ValuableDepotTabCommercialItem = {
msgs = {
MessageConst.ON_VALUABLE_DEPOT_CHANGED,
MessageConst.ON_ITEM_LOCKED_STATE_CHANGED,
},
readLike = false,
needArg = false,
Check = function()
return RedDotUtils.hasValuableDepotTabCommercialItemRedDot()
end,
}
}
return Config