PGRData/Script/matrix/xmanager/XCollectionWallManager.lua

490 lines
18 KiB
Lua
Raw Normal View History

local XCollectionWall = require("XEntity/XCollectionWall/XCollectionWall")
XCollectionWallManagerCreator = function()
local XCollectionWallManager = {}
local METHOD_NAME = {
RequestEditCollectionWall = "EditCollectionWallRequest", -- 保存墙编辑
RequestEditCollectionWallIsShow = "EditCollectionWallIsShowRequest", -- 保存展示设置
}
local WallEntity = {} -- 所有收藏品墙的数据Id做索引
local BackgroundIsUnLock = {} -- 墙面是否解锁Id做索引
local PedestalIsUnLock = {} -- 底座是否解锁Id做索引
local LocalCaptureCache = {} -- 本地截图缓存
function XCollectionWallManager.Init()
-- 构建WallEntity
local collectionWallIdList = XCollectionWallConfigs.GetCollectionWallIdList()
for _, id in ipairs(collectionWallIdList) do
local collectionWall = XCollectionWall.New(id)
WallEntity[id] = collectionWall
end
-- 获取配置表数据,按种类来初始化饰品数据
local backgroundDecorationList = XCollectionWallConfigs.GetColDecCfgListByType(XCollectionWallConfigs.EnumDecorationType.Background)
local pedestalDecorationList = XCollectionWallConfigs.GetColDecCfgListByType(XCollectionWallConfigs.EnumDecorationType.Pedestal)
-- 全部初始化为未解锁
for _, data in ipairs(backgroundDecorationList) do
BackgroundIsUnLock[data.Id] = false
end
for _, data in ipairs(pedestalDecorationList) do
PedestalIsUnLock[data.Id] = false
end
end
---
--- 使用服务器下发的数据来更新收藏品墙
function XCollectionWallManager.SyncWallEntityData(dataList)
if dataList == nil then
XLog.Error("XCollectionWallManager.SyncWallEntityData函数错误参数dataList为 nil")
return
end
for _, data in pairs(dataList) do
-- 更新收藏品墙的状态
XCollectionWallManager.UpdateWallEntityList(data.Id, data)
end
end
---
--- 使用服务器下发的数据来更新装饰品
function XCollectionWallManager.SyncDecorationData(decorationsList)
if decorationsList == nil then
XLog.Error("XCollectionWallManager.SyncDecorationData函数错误参数decorationsList为 nil")
return
end
for _, id in pairs(decorationsList) do
local type = XCollectionWallConfigs.GetColDecType(id)
if type == XCollectionWallConfigs.EnumDecorationType.Background then
BackgroundIsUnLock[id] = true
elseif type == XCollectionWallConfigs.EnumDecorationType.Pedestal then
PedestalIsUnLock[id] = true
else
XLog.Error("XCollectionWallManager.SyncDecorationData函数错误type不是XCollectionWallConfigs.EnumDecorationType类型的值")
end
end
end
---
--- 根据'data'的key来更新'wallId'收藏品墙数据实体(XCollectionWall)对应的属性
--- 需要注意的是两者的key名称需要保持一致
--- @param data table
function XCollectionWallManager.UpdateWallEntityList(wallId, data)
if WallEntity[wallId] == nil then
XLog.Error(string.format("XCollectionWallManager.GetWallEntityData函数错误,没有Id:%的收藏品实体数据", wallId))
return
end
if data == nil then
XLog.Error("XCollectionWallManager.GetWallEntityData函数错误,参数data为 nil")
return
end
WallEntity[wallId]:UpdateDate(data)
if data.CollectionSetInfos then
local state
if next(data.CollectionSetInfos) == nil then
state = XCollectionWallConfigs.EnumWallState.None
else
state = XCollectionWallConfigs.EnumWallState.Normal
end
WallEntity[wallId]:UpdateDate({ State = state })
end
end
---
--- 按Rank值排序'data',存放的值是XCollectionWall数据实体
---@param data table
function XCollectionWallManager.SortWallEntityByRank(data)
table.sort(data, function(a, b)
return a:GetRank() < b:GetRank()
end)
end
---
--- 获取所有收藏品墙的数据数组
--- 按配置表Rank值排序
---@return table
function XCollectionWallManager.GetWallEntityList()
local result = {}
if WallEntity == nil then
XLog.Error("XCollectionWallManager:GetWallEntityList函数错误WallEntity为 nil")
return result
end
for _, v in pairs(WallEntity) do
table.insert(result, v)
end
XCollectionWallManager.SortWallEntityByRank(result)
return result
end
---
--- 获取已解锁并摆放了收藏品的收藏品墙数据数组
--- 按配置表Rank值排序
---@return table
function XCollectionWallManager.GetNormalWallEntityList()
local result = {}
if WallEntity == nil then
XLog.Error("XCollectionWallManager:GetNormalWallEntityList函数错误WallEntity为 nil")
return result
end
for _, v in pairs(WallEntity) do
if v.State == XCollectionWallConfigs.EnumWallState.Normal then
table.insert(result, v)
end
end
XCollectionWallManager.SortWallEntityByRank(result)
return result
end
---
--- 获取'wallId'收藏品墙数据实体
--- @param wallId number
function XCollectionWallManager.GetWallEntityData(wallId)
if WallEntity[wallId] == nil then
XLog.Error(string.format("XCollectionWallManager.GetWallEntityData函数错误,没有Id:%的收藏品实体数据", wallId))
return nil
end
return WallEntity[wallId]
end
---
--- 根据'data'上的数据来获取对应的selectType的数据数组
---'data'是当前墙上数据来生成的
---
--- 收藏品不显示正在使用与未解锁的,装饰品有使用与未解锁的状态
--- 装饰品返回的结构:{ index = { Id, IsUnlock } }
--- 收藏品返回的是Id数组
---@param data table
---@param selectType number
---@return table
function XCollectionWallManager.GetItemList(data, selectType)
local result = {}
local isDecoration
if selectType == XCollectionWallConfigs.EnumSelectType.BACKGROUND then
isDecoration = true
for id,isUnlock in pairs(BackgroundIsUnLock) do
local temp = {}
temp.Id = id
temp.IsUnlock = isUnlock
table.insert(result, temp)
end
elseif selectType == XCollectionWallConfigs.EnumSelectType.PEDESTAL then
isDecoration = true
for id,isUnlock in pairs(PedestalIsUnLock) do
local temp = {}
temp.Id = id
temp.IsUnlock = isUnlock
table.insert(result, temp)
end
elseif selectType == XCollectionWallConfigs.EnumSelectType.BIG then
-- 质量为6的收藏品
isDecoration = false
local list = XDataCenter.MedalManager.GetScoreTitleByQuality(6)
result = XCollectionWallManager.FilterUseCollection(data.CollectionSetInfos,list)
elseif selectType == XCollectionWallConfigs.EnumSelectType.MIDDLE then
-- 质量为5的收藏品
isDecoration = false
local list = XDataCenter.MedalManager.GetScoreTitleByQuality(5)
result = XCollectionWallManager.FilterUseCollection(data.CollectionSetInfos,list)
elseif selectType == XCollectionWallConfigs.EnumSelectType.LITTL then
-- 质量为2、3、4的收藏品
isDecoration = false
local list = XDataCenter.MedalManager.GetScoreTitleByQuality(2,4)
result = XCollectionWallManager.FilterUseCollection(data.CollectionSetInfos,list)
end
if isDecoration then
table.sort(result, function(a, b)
local aRank = XCollectionWallConfigs.GetColDecRank(a.Id)
local bRank = XCollectionWallConfigs.GetColDecRank(b.Id)
if aRank == bRank then
return a.Id < b.Id
else
return aRank < bRank
end
end)
else
-- 过滤掉其他收藏品墙正在使用的收藏品
result = XCollectionWallManager.FilterOtherUseCollection(data.Id, result)
table.sort(result, function(a, b)
local aPriority = XMedalConfigs.GetCollectionPriorityById(a)
local bPriority = XMedalConfigs.GetCollectionPriorityById(b)
if aPriority == bPriority then
return a < b
else
return aPriority < bPriority
end
end)
end
return result
end
---
--- 过滤掉'collectionSetInfo'中使用的收藏品
---@param collectionSetInfo table
---@param filterList table
---@return table
function XCollectionWallManager.FilterUseCollection(collectionSetInfo, filterList)
local result = {}
local useDic = {} -- id字典
local useGroup = {} -- 组id字典同一个组的收藏品视为同一个收藏品
for _, data in pairs(collectionSetInfo) do
useDic[data.Id] = true
local groupId = XMedalConfigs.GetCollectionGroupById(data.Id)
if groupId ~= 0 and not useGroup[groupId] then
useGroup[groupId] = data.Id
end
end
-- 过滤掉使用着的收藏品
for _, filter in pairs(filterList) do
if not useDic[filter.Id] then
local groupId = XMedalConfigs.GetCollectionGroupById(filter.Id)
if not useGroup[groupId] then
table.insert(result, filter.Id)
end
end
end
return result
end
---
--- 过滤掉其他收藏品墙正在使用的收藏品
--- 'filterList'为等待过滤的列表
---@param curWallDataId table
---@param filterList table
---@return table
function XCollectionWallManager.FilterOtherUseCollection(curWallDataId, filterList)
local result = {}
local useDic = {} -- id字典
local useGroup = {} -- 组id字典同一个组的收藏品视为同一个收藏品
for _, wallData in pairs(WallEntity) do
if wallData:GetId() ~= curWallDataId then
local collectionInfo = wallData:GetCollectionSetInfos()
for _, info in pairs(collectionInfo) do
if useDic[info.Id] then
XLog.Error(string.format("XCollectionWallManager.FilterOtherUseCollection函数错误有相同Id的收藏品被多个墙重复使用ID:%s", info.Id))
end
useDic[info.Id] = info
local groupId = XMedalConfigs.GetCollectionGroupById(info.Id)
if groupId ~= 0 and not useGroup[groupId] then
useGroup[groupId] = info.Id
end
end
end
end
-- 过滤掉使用着的收藏品
for _, id in pairs(filterList) do
if not useDic[id] then
local groupId = XMedalConfigs.GetCollectionGroupById(id)
if not useGroup[groupId] then
table.insert(result, id)
end
end
end
return result
end
---
--- 通过中心本地坐标获取左下角格子坐标
--- GridPos = (CenterLocalPos - ItemSize/2) / GridSize
function XCollectionWallManager.GetGridPosByLocalPos(localPos, gridSize)
-- 利用中心本地坐标算出左下角本地坐标
local leftBottomLocalPos = CS.UnityEngine.Vector2(localPos.x - gridSize / 2, localPos.y - gridSize / 2)
-- 0.5是格子大小一半的偏移,使坐标的计算区域称向中心区域(超出这个区域gridPos就换成其他坐标)
local gridPos = CS.UnityEngine.Vector2Int(math.floor((leftBottomLocalPos.x) / XCollectionWallConfigs.CellSize + 0.5),
math.floor(leftBottomLocalPos.y / XCollectionWallConfigs.CellSize + 0.5));
return gridPos
end
---
--- 通过左下角格子坐标获取中心本地坐标
--- CenterLocalPos = GirdPos * GridSize + ItemSize/2
function XCollectionWallManager.GetLocalPosByGridPos(gridPos, gridSize)
local localPos
-- 左下角本地坐标为格子坐标*格子长度
local leftBottomLocalPos = CS.UnityEngine.Vector2(gridPos.x * XCollectionWallConfigs.CellSize, gridPos.y * XCollectionWallConfigs.CellSize)
-- 中心本地坐标相对左下角本地坐标的偏移为物体尺寸的一半
localPos = CS.UnityEngine.Vector2(leftBottomLocalPos.x + gridSize / 2, leftBottomLocalPos.y + gridSize / 2)
return localPos
end
function XCollectionWallManager.IsNeedSave(wallDataId, curWallData)
local wallData = XCollectionWallManager.GetWallEntityData(wallDataId)
local lastCollectionSetInfo = wallData:GetCollectionSetInfos()
if #curWallData.CollectionSetInfos ~= #lastCollectionSetInfo then
return true
end
-- 墙面与底面
if curWallData.BackgroundId ~= wallData:GetBackgroundId()
or curWallData.PedestalId ~= wallData:GetPedestalId() then
return true
end
-- 摆放的收藏品
local curCollectionSetInfoDic = {}
for _, v in pairs(curWallData.CollectionSetInfos) do
curCollectionSetInfoDic[v.Id] = v
end
for _, v in pairs(lastCollectionSetInfo) do
local curCollection = curCollectionSetInfoDic[v.Id]
if curCollection == nil then
return true
end
if v.X ~= curCollection.X or v.Y ~= curCollection.Y or v.SizeId ~= curCollection.SizeId then
return true
end
end
return false
end
function XCollectionWallManager.GetCaptureImgName(wallDataId)
return string.format("%s%s", tostring(XPlayer.Id), tostring(wallDataId))
end
function XCollectionWallManager.GetLocalCaptureCache(id)
local texture = LocalCaptureCache[id]
return texture or nil
end
function XCollectionWallManager.SetLocalCaptureCache(id, texture)
LocalCaptureCache[id] = texture
end
function XCollectionWallManager.ClearLocalCaptureCache()
for _, texture in pairs(LocalCaptureCache) do
if not XTool.UObjIsNil(texture) then
CS.UnityEngine.Object.Destroy(texture)
end
end
LocalCaptureCache = {}
end
function XCollectionWallManager.CaptureCamera(imgName, cb)
if not imgName then
return nil
end
CS.XScreenCapture.ScreenCaptureWithCallBack(CS.XUiManager.Instance.UiCamera,function(texture)
CS.XTool.SaveCaptureImg(imgName, texture);
XCollectionWallManager.SetLocalCaptureCache(imgName, texture)
if cb then
cb()
end
end)
end
function XCollectionWallManager.GetShowWallList()
local result = {}
for _, wallData in pairs(WallEntity) do
if wallData:GetIsShow() then
local collectionInfo = wallData:GetCollectionSetInfos()
if next(collectionInfo) then
table.insert(result, wallData)
end
end
end
return result
end
------------------------------------------------------------------ 请求协议 -------------------------------------------------------
---
--- 请求保存收藏品墙的展示设置
--- 'isShowInfos' = { Id IsShow }
---@param isShowInfos table
---@param cb function
function XCollectionWallManager.RequestEditCollectionWallIsShow(isShowInfos, cb)
XNetwork.Call(METHOD_NAME.RequestEditCollectionWallIsShow, { CollectionWallIsShowInfos = isShowInfos }, function(res)
if res.Code ~= XCode.Success then
XUiManager.TipCode(res.Code)
return
end
for _, showInfo in pairs(isShowInfos) do
XCollectionWallManager.UpdateWallEntityList(showInfo.Id, { IsShow = showInfo.IsShow })
end
if cb then
cb()
end
end)
end
---
--- 请求编辑收藏品墙,'wallId'是收藏品墙Id'pedestalId'是底座Id'backgroundId'是背景Id
--- 'setInfo'是收藏品信息,结构为{ Id, X, Y, SizeId }
---@param wallId number
---@param pedestalId number
---@param backgroundId number
---@param setInfo table
---@param cb function
function XCollectionWallManager.RequestEditCollectionWall(wallId, pedestalId, backgroundId, setInfo, cb)
local req = { Id = wallId, PedestalId = pedestalId, BackgroundId = backgroundId, CollectionSetInfos = setInfo }
local state
if next(setInfo) == nil then
state = XCollectionWallConfigs.EnumWallState.None
else
state = XCollectionWallConfigs.EnumWallState.Normal
end
XNetwork.Call(METHOD_NAME.RequestEditCollectionWall, req, function(res)
if res.Code ~= XCode.Success then
XUiManager.TipCode(res.Code)
return
end
XCollectionWallManager.UpdateWallEntityList(wallId,
{ PedestalId = pedestalId, BackgroundId = backgroundId, State = state, CollectionSetInfos = setInfo })
if cb then
cb()
end
end)
end
XCollectionWallManager.Init()
return XCollectionWallManager
end
-- 解锁底座或背景时推送(数据包括之前解锁的饰品)
XRpc.NotifyWallDecoration = function(data)
XDataCenter.CollectionWallManager.SyncDecorationData(data.UnlockedDecorationIds)
end
-- 解锁收藏品墙时推送(数据只有新解锁的墙)
XRpc.NotifyWallInfo = function(data)
XDataCenter.CollectionWallManager.SyncWallEntityData(data.Walls)
end