forked from endernon/PGRData
493 lines
18 KiB
Lua
493 lines
18 KiB
Lua
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
|
||
---@param errorCb function
|
||
function XCollectionWallManager.RequestEditCollectionWall(wallId, pedestalId, backgroundId, setInfo, cb, errorCb)
|
||
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)
|
||
if errorCb then
|
||
errorCb()
|
||
end
|
||
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
|
||
|