311 lines
No EOL
13 KiB
Lua
311 lines
No EOL
13 KiB
Lua
-- 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 |