-- v1.30 通用构造体角色过滤筛选管理器,包括筛选和排序功能(逐渐替换旧筛选器) -- 该标签类型用于查找CharacterManager的方法,用于搜索方法和规定标签,数字序号与 CharacterFilterTagGroup 对应 CharacterFilterTagTypeNum = { InitialQuality = 5, Career = 1, Element = 2, } CharacterFilterGroupType = -- 该参数决定当前筛选界面使用哪些标签进行显示,对应 CharacterFilterCommonGroup.tab的id { Default = 1, --默认泛用型 Isomer = 2, --授格者专用 Prequel = 3, --支线间章 Fragment = 4, --资源收集角色碎片 Draw = 5, --抽武器/辅助机筛选适配角色 } CharacterSortTagType = { Default = 1, Level = 2, Quality = 3, Ability = 4, } XCommonCharacterFiltManagerCreator = function() ---@class XCommonCharacterFiltManager XCommonCharacterFiltManager local XCommonCharacterFiltManager = {} local SelectTagData = {} -- 记录缓存用 local SelectListData = {} local SortTagData = {} local SortFunction = {} local tagMethodName = "GetCharacter" function XCommonCharacterFiltManager.Init() XCommonCharacterFiltManager.InitSortFunction() end function XCommonCharacterFiltManager.GetTagNameByTagGroupId(id) for k, v in pairs(CharacterFilterTagTypeNum) do if v == id then return k end end end ---@param characterList 传入以有存在字段名为Id值为CharacterID数据组成的构造体角色顺序表list etc:{ [1] = {Id = CharacterId},[2] = {Id = CharacterId}...} ---@param selectTagData 筛选项数据 function XCommonCharacterFiltManager.DoFilter(charaterList, selectTagData) local resultList = {} for k, charaData in ipairs(charaterList) do if XCommonCharacterFiltManager.IsCharaInTag(charaData, selectTagData, "InitialQuality") --检测稀有度筛选项 and XCommonCharacterFiltManager.IsCharaInTag(charaData, selectTagData, "Career") --检测职业筛选项 and XCommonCharacterFiltManager.IsCharaInTag(charaData, selectTagData, "Element") --检测元素筛选项 then table.insert(resultList, charaData) end end return resultList end -- 检测筛选项是否满足条件 ---@param charaData 构造体角色数据 ---@param tagTypeName 筛选项名称 function XCommonCharacterFiltManager.IsCharaInTag(charaData, selectTagData, tagTypeName) local tagData = selectTagData[tagTypeName] --拿到该筛选项的数据 if not tagData or not next(tagData) then -- 如果该筛选项为空则不启用该筛选项,默认为全选该筛选项 return true end -- tagTypeName筛选项的字段名和characterManager对应方法的字段名一样 -- 构造体角色数据一定要通过characterManager接口去拿,不要通过XCharacter去拿,因为传进来的构造体角色可能是机器人 for k, v in pairs(tagData) do if XDataCenter.CharacterManager[tagMethodName..tagTypeName](charaData.Id) == v then return true end end return false end -- 缓存筛选项数据(需要手动缓存和清除,因为无法区分混合筛选还是单类型构造体筛选(类型指泛用和独域))退出界面时要手动调用Clear清除 function XCommonCharacterFiltManager.SetSelectTagData(selectTagData, keyName) if not keyName then return end SelectTagData[keyName] = XTool.Clone(selectTagData) --缓存记录筛选项(keyName可以和构造体类型(独域、泛用)耦合,也可以自定义keyName) end -- 缓存筛选后的列表数据 function XCommonCharacterFiltManager.SetSelectListData(sortList, keyName) if not keyName then return end SelectListData[keyName] = sortList end function XCommonCharacterFiltManager.GetSelectTagData(keyName) return XTool.Clone(SelectTagData[keyName]) end function XCommonCharacterFiltManager.GetSelectListData(keyName) return SelectListData[keyName] end function XCommonCharacterFiltManager.ClearSelectTagData(keyName) if keyName then SelectTagData[keyName] = nil SelectListData[keyName] = nil else SelectTagData = {} SelectListData = {} end end -- 缓存排序数据(需要手动缓存和清除),退出界面时要手动调用Clear清除 function XCommonCharacterFiltManager.SetSortData(sortTypeName, keyName) if not keyName then return end SortTagData[keyName] = sortTypeName --缓存记录筛选项(keyName仅和构造体类型(独域、泛用)耦合) end function XCommonCharacterFiltManager.GetSortData(keyName) return SortTagData[keyName] end function XCommonCharacterFiltManager.ClearSortData(keyName) if keyName then SortTagData[keyName] = nil else SortTagData = {} end end function XCommonCharacterFiltManager.ClearCacheData() XCommonCharacterFiltManager.ClearSelectTagData() XCommonCharacterFiltManager.ClearSortData() end function XCommonCharacterFiltManager.InitSortFunction() local LevelSort = function(idA, idB, isAscendOrder) local levelA = XDataCenter.CharacterManager.GetCharacterLevel(idA) local levelB = XDataCenter.CharacterManager.GetCharacterLevel(idB) local isSort = false if levelA ~= levelB then isSort = true if isAscendOrder then return isSort, levelA < levelB end return isSort, levelA > levelB end return isSort end local QualitySort = function(idA, idB, isAscendOrder) local qualityA = XDataCenter.CharacterManager.GetCharacterQuality(idA) local qualityB = XDataCenter.CharacterManager.GetCharacterQuality(idB) local isSort = false if qualityA ~= qualityB then isSort = true if isAscendOrder then return isSort, qualityA < qualityB end return isSort, qualityA > qualityB end return isSort end local AbilitySort = function(idA, idB, isAscendOrder) local abilityA = XDataCenter.CharacterManager.GetCharacterHaveRobotAbilityById(idA) local abilityB = XDataCenter.CharacterManager.GetCharacterHaveRobotAbilityById(idB) local isSort = false if abilityA ~= abilityB then isSort = true if isAscendOrder then return isSort, abilityA < abilityB end return isSort, abilityA > abilityB end return isSort end SortFunction[CharacterSortTagType.Default] = function(idA, idB, isAscendOrder, alreadySortTag, isSortAbility) local isSort, sortResult if alreadySortTag ~= XRoomCharFilterTipsConfigs.EnumSortTag.Level then isSort, sortResult = LevelSort(idA, idB, isAscendOrder) if isSort then return sortResult end end if isSortAbility and alreadySortTag ~= XRoomCharFilterTipsConfigs.EnumSortTag.Ability then isSort, sortResult = AbilitySort(idA, idB, isAscendOrder) if isSort then return sortResult end end if alreadySortTag ~= XRoomCharFilterTipsConfigs.EnumSortTag.Quality then isSort, sortResult = QualitySort(idA, idB, isAscendOrder) if isSort then return sortResult end end local priorityA = XCharacterConfigs.GetCharacterPriority(idA) local priorityB = XCharacterConfigs.GetCharacterPriority(idB) if priorityA ~= priorityB then if isAscendOrder then return priorityA < priorityB end return priorityA > priorityB end return idA > idB end SortFunction[CharacterSortTagType.Quality] = function(idA, idB, isAscendOrder) local isSort, sortResult = QualitySort(idA, idB, isAscendOrder) if isSort then return sortResult end return SortFunction[CharacterSortTagType.Default](idA, idB, isAscendOrder, CharacterSortTagType.Quality, true) end SortFunction[CharacterSortTagType.Level] = function(idA, idB, isAscendOrder) local isSort, sortResult = LevelSort(idA, idB, isAscendOrder) if isSort then return sortResult end return SortFunction[CharacterSortTagType.Default](idA, idB, isAscendOrder, CharacterSortTagType.Level, true) end SortFunction[CharacterSortTagType.Ability] = function(idA, idB, isAscendOrder) local isSort, sortResult = AbilitySort(idA, idB, isAscendOrder) if isSort then return sortResult end return SortFunction[CharacterSortTagType.Default](idA, idB, isAscendOrder, CharacterSortTagType.Ability) end end -- 排序 ---@param characterList 传入以有存在字段名为Id值为CharacterID数据组成的构造体角色顺序表list etc:{ [1] = {Id = CharacterId},[2] = {Id = CharacterId}...} ---@param sortTypeName 排序标签 ---@param isAscendOrder 是否升序 function XCommonCharacterFiltManager.DoSort(charaterList, sortTypeName, isAscendOrder) if not sortTypeName then sortTypeName = CharacterSortTagType.Default end -- 该排序兼容角色碎片 -- 以下列表按顺序最后合并 local targetCharacterInTeam = {} --目标角色在队伍(有蓝色圆形标签的角色,目前只有成员界面会有这种角色,且仅有一个) local inTeamList = {} -- 在队伍的角色 local canUnlockFragmentList = {} -- 可解锁的碎片 local targetCharacterNotInTeam = {} --目标角色不在队伍 local nmOwnCharaList = {} -- 不在队伍的拥有角色/机器人角色 local normalFragmentList = {} -- 不可解锁的碎片 for k, v in ipairs(charaterList) do if (not XDataCenter.CharacterManager.GetCharacter(v.Id)) and (not XRobotManager.CheckIsRobotId(v.Id)) then -- 分开碎片和角色 local curFragmentA = XDataCenter.CharacterManager.GetCharUnlockFragment(v.Id) local bornQualityA = XCharacterConfigs.GetCharMinQuality(v.Id) local characterTypeA = XCharacterConfigs.GetCharacterType(v.Id) local needFragmentA = XCharacterConfigs.GetComposeCount(characterTypeA, bornQualityA) local isCanUnlockA = curFragmentA >= needFragmentA -- 是否可解锁碎片 if isCanUnlockA then table.insert(canUnlockFragmentList, v) else table.insert(normalFragmentList, v) end else if XDataCenter.TeamManager.CheckInTeam(v.Id) then if XDataCenter.EquipGuideManager.IsEquipGuideCharacter(v.Id) then table.insert(targetCharacterInTeam, v) else table.insert(inTeamList, v) end else if XDataCenter.EquipGuideManager.IsEquipGuideCharacter(v.Id) then table.insert(targetCharacterNotInTeam, v) else table.insert(nmOwnCharaList, v) end end end end -- 需要使用标签排序功能的仅为 【不在队伍的拥有角色/机器人角色】和【不可解锁的碎片】 table.sort(nmOwnCharaList, function (dataA, dataB) local idA, idB = dataA.Id, dataB.Id return SortFunction[sortTypeName](idA, idB, isAscendOrder) end) table.sort(normalFragmentList, function (dataA, dataB) local idA, idB = dataA.Id, dataB.Id return SortFunction[sortTypeName](idA, idB, isAscendOrder) end) local resultList = {} resultList = appendArray(targetCharacterInTeam, inTeamList) resultList = appendArray(resultList, canUnlockFragmentList) resultList = appendArray(resultList, targetCharacterNotInTeam) resultList = appendArray(resultList, nmOwnCharaList) resultList = appendArray(resultList, normalFragmentList) return resultList end XCommonCharacterFiltManager.Init() return XCommonCharacterFiltManager end