PGRData/Script/matrix/xmanager/XTeamManager.lua
2024-09-01 22:49:41 +02:00

702 lines
No EOL
24 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

local XTeam = require("XEntity/XTeam/XTeam")
local XPartnerPrefab = require("XEntity/XPartner/XPartnerPrefab")
XTeamManagerCreator = function()
local XTeamManager = {}
local TeamDataKey = "STAGE_TEAM_DATA_"
local MaxPos = CS.XGame.Config:GetInt("TeamMaxPos") -- 默认一个队伍的位置数
local CaptainPos -- 队长位
local FirstFightPos -- 首发位
local EmptyTeam = {
TeamData = {},
CaptainPos = 1,
FirstFightPos = 1,
-- 0表示仅保存在本地
TeamId = 0,
}
local PlayerTeamGroupData = {}
local PlayerTeamPrefabData = {}
local METHOD_NAME = {
SetTeam = "TeamSetTeamRequest",
SetPrefabTeam = "TeamPrefabSetTeamRequest"
}
-- XTeam
-- 缓存队伍数据
local TeamDic = {}
-- XTeam
-- 缓存预设队伍数据
local TeamPrefabDic = {}
--SetTeamPos
function XTeamManager.Init()
CaptainPos = 0
FirstFightPos = 0
for _, cfg in pairs(XTeamConfig.GetTeamCfg()) do
if cfg.IsCaptain and CaptainPos == 0 then
CaptainPos = cfg.Id
end
if cfg.IsFirstFight and FirstFightPos == 0 then
FirstFightPos = cfg.Id
end
end
for i = 1, MaxPos do
EmptyTeam.TeamData[i] = 0
end
--EmptyTeam = XReadOnlyTable.Create(EmptyTeam)
XTeamManager.EmptyTeam = EmptyTeam
end
function XTeamManager.GetTeamId(typeId, stageId)
local teams = XTeamConfig.GetTeamsByTypeId(typeId)
if teams == nil then
return nil
end
local sectionId = 0
local chapterId = 0
if stageId ~= nil then
local stageInfo = XDataCenter.FubenManager.GetStageInfo(stageId)
sectionId = stageInfo.SectionId
chapterId = stageInfo.ChpaterId
if sectionId == nil or chapterId == nil then
return nil
end
end
-- 匹配规则chapterId, sectionId, stageId 逐级查找,某一项为 nil 时,表示匹配上一级
for _, val in pairs(teams) do
if #val.ChapterId <= 0 then
return val.TeamId -- 匹配 TypeId
end
for _, cId in pairs(val.ChapterId) do
if chapterId > 0 and cId == chapterId then
if #val.SectionId <= 0 then
return val.TeamId -- 匹配 chapterId
end
for _, sId in pairs(val.SectionId) do
if sectionId > 0 and sId == sectionId then
if #val.StageId <= 0 then
return val.TeamId -- 匹配 sectionId
end
for _, stId in pairs(val.StageId) do
if stId == stageId then
return val.TeamId -- 匹配 stageId
end
end
end
end
end
end
end
return nil
end
-- 玩家队伍中队长的位置Id
-- 已废弃
function XTeamManager.GetTeamCaptainKey(teamId)
return teamId << 8
end
-- 已废弃
function XTeamManager.GetValidPos(teamData)
local posId = 1
for k, v in pairs(teamData) do
if v > 0 then
posId = k
break
end
end
return posId
end
local function GetTeamKey(stageId)
local info = XDataCenter.FubenManager.GetStageInfo(stageId)
return string.format("%s%s_%d_%s", TeamDataKey, tostring(XPlayer.Id), info.Type, tostring(stageId))
end
-- 使用stageId作为Key本地保存编队信息
function XTeamManager.SaveTeamLocal(curTeam, stageId)
if not stageId then
XLog.Warning("stageId is nil !!")
return
end
XSaveTool.SaveData(GetTeamKey(stageId), curTeam)
end
-- 使用stageId作为Key读取本地编队信息
function XTeamManager.LoadTeamLocal(stageId)
if not stageId then
XLog.Warning("stageId is nil")
return EmptyTeam
end
local team = XSaveTool.GetData(GetTeamKey(stageId)) or EmptyTeam
for _, v in ipairs(team.TeamData) do
if v ~= 0 and not XRobotManager.CheckIsRobotId(v) and not XDataCenter.CharacterManager.IsOwnCharacter(v) then
return EmptyTeam
end
end
return team
end
-- 使用TeamSetTeamRequest协议保存使用TeamId的XTeamData
function XTeamManager.SetPlayerTeam(curTeam, isPrefab, cb)
local curTeamId = curTeam.TeamId
if curTeamId == 0 then
XTeamManager.SetPlayerTeamLocal(curTeam, isPrefab, cb)
return
end
local params = {}
params.TeamData = {}
params.TeamId = curTeamId
XMessagePack.MarkAsTable(params.TeamData)
for k, v in pairs(curTeam.TeamData) do
params.TeamData[k] = v
end
params.CaptainPos = curTeam.CaptainPos
params.FirstFightPos = curTeam.FirstFightPos
params.TeamName = curTeam.TeamName
local methodName, req
if isPrefab then
local partnerPrefab = XTeamManager.GetPartnerPrefab(curTeamId)
params.PartnerData = partnerPrefab:GetPartnerData()
XMessagePack.MarkAsTable(params.PartnerData)
methodName = METHOD_NAME.SetPrefabTeam
req = { TeamPrefabData = params }
else
methodName = METHOD_NAME.SetTeam
req = { TeamData = params }
end
--local req = { TeamData = params, IsPrefab = isPrefab }
XNetwork.Call(methodName, req, function(res)
if res.Code ~= XCode.Success then
XUiManager.TipCode(res.Code)
return
end
XTeamManager.SetPlayerTeamLocal(curTeam, isPrefab, cb)
end)
end
-- 更新TeamId的数据缓存服务器的XTeamData只在登录的时候下发
function XTeamManager.SetPlayerTeamLocal(curTeam, isPrefab, cb, saveXTeam)
if saveXTeam == nil then saveXTeam = true end
if saveXTeam then
XTeamManager.SaveXTeam(curTeam.TeamId)
end
local curTeamId = curTeam.TeamId
local characterCheckTable = {}
local changeCharacter = {} -- 更改成员的Id数组
local playCvCharacterInfo = {} -- 要播放语音的角色信息
playCvCharacterInfo.Id = 0
playCvCharacterInfo.IsCaptain = false
-- 更改成员数数量等于1播放该角色的入队语音数量大于等于2只播放队长语音没有队长就不播放语音
local changeCount = 0
local playerTeamData = isPrefab and PlayerTeamPrefabData or PlayerTeamGroupData
-- 更新客户端队伍缓存
if playerTeamData[curTeamId] == nil then
playerTeamData[curTeamId] = {}
else
for _, characterId in pairs(playerTeamData[curTeamId].TeamData) do
characterCheckTable[characterId] = true
end
for pos, characterId in pairs(curTeam.TeamData) do
if (not characterCheckTable[characterId]) and (characterId ~= 0) then
changeCount = changeCount + 1
if pos == curTeam.CaptainPos then
playCvCharacterInfo.Id = characterId
playCvCharacterInfo.IsCaptain = true
break
end
table.insert(changeCharacter, characterId)
end
end
-- 更改角色不是队长,但只更改了一个角色,播放该角色的入队语音
if playCvCharacterInfo.Id == 0 and changeCount == 1 then
playCvCharacterInfo.Id = changeCharacter[1]
end
XEventManager.DispatchEvent(XEventId.EVENT_TEAM_MEMBER_CHANGE, curTeamId, playCvCharacterInfo.Id, playCvCharacterInfo.IsCaptain)
end
playerTeamData[curTeamId].TeamId = curTeamId
playerTeamData[curTeamId].CaptainPos = curTeam.CaptainPos
playerTeamData[curTeamId].FirstFightPos = curTeam.FirstFightPos
playerTeamData[curTeamId].TeamData = curTeam.TeamData
playerTeamData[curTeamId].TeamName = curTeam.TeamName
if isPrefab then
playerTeamData[curTeamId].PartnerPrefab = XDataCenter.TeamManager.GetPartnerPrefab(curTeamId)
end
if cb then cb() end
XEventManager.DispatchEvent(XEventId.EVENT_TEAM_PREFAB_CHANGE, curTeamId, playerTeamData[curTeamId])
end
-- todo 特别优化
function XTeamManager.SetExpeditionTeamData(curTeam, cb)
local curTeamId = curTeam.TeamId
local params = {}
params.TeamData = {}
params.TeamId = curTeamId
XMessagePack.MarkAsTable(params.TeamData)
for k, v in pairs(curTeam.TeamData) do
params.TeamData[k] = v
end
params.CaptainPos = curTeam.CaptainPos
params.FirstFightPos = curTeam.FirstFightPos
local req = { TeamData = params}
XNetwork.Call(METHOD_NAME.SetTeam, req, function(res)
if res.Code ~= XCode.Success then
XUiManager.TipCode(res.Code)
return
end
local characterCheckTable = {}
local playerTeamData = PlayerTeamGroupData
-- 更新客户端队伍缓存
if playerTeamData[curTeamId] == nil then
playerTeamData[curTeamId] = {}
else
for _, baseId in pairs(playerTeamData[curTeamId].TeamData) do
characterCheckTable[baseId] = true
end
for pos, baseId in pairs(curTeam.TeamData) do
if not characterCheckTable[baseId] then
local charId = XExpeditionConfig.GetCharacterIdByBaseId(baseId)
XEventManager.DispatchEvent(XEventId.EVENT_TEAM_MEMBER_CHANGE, curTeamId, charId, pos == curTeam.CaptainPos)
end
end
end
playerTeamData[curTeamId].TeamId = curTeamId
playerTeamData[curTeamId].CaptainPos = curTeam.CaptainPos
playerTeamData[curTeamId].FirstFightPos = curTeam.FirstFightPos
playerTeamData[curTeamId].TeamData = curTeam.TeamData
playerTeamData[curTeamId].TeamName = curTeam.TeamName
if cb then cb() end
XEventManager.DispatchEvent(XEventId.EVENT_TEAM_PREFAB_CHANGE, curTeamId, playerTeamData[curTeamId])
end)
end
function XTeamManager.GetPlayerTeamData(teamId)
return PlayerTeamGroupData[teamId] or false
end
function XTeamManager.GetTeamData(teamId)
local teamData = XTeamManager.GetXTeamEntityIds(teamId)
if teamData then return teamData end
if not XTeamConfig.GetTeamTypeCfg(teamId) and teamId ~= 0 then
XLog.Error("XTeamManager.GetTeamCaptainPos, 缺少TeamTypeCfgteamId = ", tostring(teamId))
return
end
if PlayerTeamGroupData[teamId] ~= nil then
teamData = PlayerTeamGroupData[teamId].TeamData
end
if teamData == nil or next(teamData) == nil then
teamData = {}
for i = 1, MaxPos do
teamData[i] = 0
end
end
return teamData
end
function XTeamManager.GetTeamCaptainPos(teamId)
local captainPos = XTeamManager.GetXTeamCaptainPos(teamId)
if captainPos then return captainPos end
if not XTeamConfig.GetTeamTypeCfg(teamId) and teamId ~= 0 then
XLog.Error("XTeamManager.GetTeamCaptainPos, 缺少TeamTypeCfgteamId = ", tostring(teamId))
return
end
captainPos = XTeamManager.GetCaptainPos()
if PlayerTeamGroupData[teamId] ~= nil then
captainPos = PlayerTeamGroupData[teamId].CaptainPos
end
return captainPos
end
---==========================================
--- 根据'teamId'得到当前的首发位置中间是1左边是2右边是3
--- 若第一次进入玩法,没有设置相应的'teamId数据则初始位置为1
---@param teamId number
---@return number
---==========================================
function XTeamManager.GetTeamFirstFightPos(teamId)
local posId = XTeamManager.GetXTeamFirstFightPos(teamId)
if posId then return posId end
if not XTeamConfig.GetTeamTypeCfg(teamId) and teamId ~= 0 then
XLog.Error("XTeamManager.GetTeamFirstFightPos, 缺少TeamTypeCfgteamId = ", tostring(teamId))
return
end
-- 初始位置为1
posId = 1
-- 是否设置过该teamId数据
if PlayerTeamGroupData[teamId] ~= nil then
posId = PlayerTeamGroupData[teamId].FirstFightPos
end
return posId
end
function XTeamManager.GetTeamCaptainId(teamId)
local xTeam = XTeamManager.GetXTeam(teamId)
if xTeam then
return xTeam:GetCaptainPosEntityId()
end
if not XTeamConfig.GetTeamTypeCfg(teamId) and teamId ~= 0 then
XLog.Error("XTeamManager.GetTeamCaptainId, 缺少TeamTypeCfgteamId = ", tostring(teamId))
return
end
if PlayerTeamGroupData[teamId] == nil then
return nil
end
local captainPos = PlayerTeamGroupData[teamId].CaptainPos
return PlayerTeamGroupData[teamId].TeamData[captainPos]
end
---==========================================
--- 根据'teamId'得到当前的首发位的角色Id
---@param teamId number
---@return number
---==========================================
function XTeamManager.GetTeamFirstFightId(teamId)
local xTeam = XTeamManager.GetXTeam(teamId)
if xTeam then
return xTeam:GetFirstFightPosEntityId()
end
if not XTeamConfig.GetTeamTypeCfg(teamId) and teamId ~= 0 then
XLog.Error("XTeamManager.GetTeamFirstFightId, 缺少TeamTypeCfgteamId = ", tostring(teamId))
return
end
if PlayerTeamGroupData[teamId] == nil then
return nil
end
local firstFightPos = PlayerTeamGroupData[teamId].FirstFightPos
return PlayerTeamGroupData[teamId].TeamData[firstFightPos]
end
-- 得到对应玩法的TeamId与Team数据
-- stageId : 获取stageInfo后找到TeamType相匹配的TeamId
function XTeamManager.GetPlayerTeam(typeId, stageId)
local curTeamId = XTeamManager.GetTeamId(typeId, stageId)
if curTeamId == nil then
XLog.ErrorTableDataNotFound("XTeamManager.GetPlayerTeam", "curTeamId",
TABLE_PATH, "typeId stageId ", tostring(typeId) .. tostring(stageId))
return nil
end
local CurTeam = {
["TeamId"] = curTeamId,
["TeamData"] = XTeamManager.GetTeamData(curTeamId),
["CaptainPos"] = XTeamManager.GetTeamCaptainPos(curTeamId),
["FirstFightPos"] = XTeamManager.GetTeamFirstFightPos(curTeamId),
}
return CurTeam
end
function XTeamManager.CheckInTeam(characterId)
local typeId = CS.XGame.Config:GetInt("TypeIdMainLine")
local curTeamId = XTeamManager.GetTeamId(typeId)
if curTeamId == nil then
XLog.ErrorTableDataNotFound("XTeamManager.CheckInTeam", "curTeamId", TABLE_PATH, "typeId stageId ", tostring(typeId))
return nil
end
local teamData = XTeamManager.GetTeamData(curTeamId)
for _, v in pairs(teamData) do
if characterId == v then
return true
end
end
return false
end
function XTeamManager.GetInTeamCheckTable()
local inTeamCheckTable = {}
local typeId = CS.XGame.Config:GetInt("TypeIdMainLine")
local curTeamId = XTeamManager.GetTeamId(typeId)
local teamData = XTeamManager.GetTeamData(curTeamId)
for _, v in pairs(teamData) do
if v > 0 then
inTeamCheckTable[v] = true
end
end
return inTeamCheckTable
end
-- 在NotifyLogin中获取队伍数据
function XTeamManager.InitTeamGroupData(teamGroupData)
if teamGroupData == nil then
return
end
for key, value in pairs(teamGroupData) do
local teamTemp = {}
for teamDataKey, teamDataValue in pairs(value.TeamData) do
teamTemp[teamDataKey] = teamDataValue
end
PlayerTeamGroupData[key] = {}
PlayerTeamGroupData[key].TeamId = value.TeamId
PlayerTeamGroupData[key].CaptainPos = value.CaptainPos
PlayerTeamGroupData[key].FirstFightPos = value.FirstFightPos
PlayerTeamGroupData[key].TeamData = teamTemp
end
end
-- 在NotifyLogin中获取预编译队伍
function XTeamManager.InitTeamPrefabData(teamPrefabData)
if teamPrefabData == nil then
return
end
for key, value in pairs(teamPrefabData) do
local teamTemp = {}
for teamDataKey, teamDataValue in pairs(value.TeamData) do
teamTemp[teamDataKey] = teamDataValue
end
local partnerPrefab = XPartnerPrefab.New(key, value.PartnerData)
PlayerTeamPrefabData[key] = {}
PlayerTeamPrefabData[key].TeamId = value.TeamId
PlayerTeamPrefabData[key].CaptainPos = value.CaptainPos
PlayerTeamPrefabData[key].FirstFightPos = value.FirstFightPos
PlayerTeamPrefabData[key].TeamData = teamTemp
PlayerTeamPrefabData[key].TeamName = value.TeamName
PlayerTeamPrefabData[key].PartnerPrefab = partnerPrefab
end
end
--==============================
---@desc 获取辅助机预设
---@teamId teamId
---@return table @class XPartnerPrefab
--==============================
function XTeamManager.GetPartnerPrefab(teamId)
local teamData = PlayerTeamPrefabData[teamId]
if not teamData then
local maxPos = XTeamManager.GetMaxPos()
teamData = {}
teamData.TeamId = teamId
teamData.CaptainPos = XTeamManager.GetCaptainPos()
teamData.FirstFightPos = XTeamManager.GetFirstFightPos()
teamData.TeamName = CS.XTextManager.GetText("TeamPrefabDefaultName", teamId)
teamData.TeamData = {}
for idx = 1, maxPos do
teamData.TeamData[idx] = 0
end
PlayerTeamPrefabData[teamId] = teamData
end
local partnerPrefab = teamData.PartnerPrefab
if not partnerPrefab then
partnerPrefab = XPartnerPrefab.New(teamId)
PlayerTeamPrefabData[teamId].PartnerPrefab = partnerPrefab
end
return partnerPrefab
end
function XTeamManager.GetCaptainPos()
return CaptainPos
end
function XTeamManager.GetFirstFightPos()
return FirstFightPos
end
function XTeamManager.GetMaxPos()
return MaxPos
end
function XTeamManager.GetTeamMemberColor(id)
local colorStr = XTeamConfig.GetTeamCfgById(id).Color
local color = XUiHelper.Hexcolor2Color(colorStr)
return color
end
function XTeamManager.GetTeamPrefabData()
return PlayerTeamPrefabData
end
function XTeamManager.ResetTeamData(teamId)
local teamInfos = XTeamManager.GetPlayerTeamData(teamId)
if not teamInfos then return end
teamInfos.CaptainPos = 1
for index in pairs(teamInfos.TeamData) do
teamInfos.TeamData[index] = 0
end
end
--######################## 新队伍逻辑代码 ########################
-- return : XTeam
function XTeamManager.GetMainLineTeam()
return XTeamManager.GetXTeamByTypeId(CS.XGame.Config:GetInt("TypeIdMainLine"))
end
function XTeamManager.GetXTeamByTypeId(typeId)
local teamData = XTeamManager.GetPlayerTeam(typeId)
local result = TeamDic[teamData.TeamId]
if result == nil then
result = XTeam.New(teamData.TeamId)
result:UpdateSaveCallback(function(inTeam)
XTeamManager.RequestSaveTeam(inTeam)
end)
TeamDic[teamData.TeamId] = result
end
result:UpdateFromTeamData(teamData)
return result
end
function XTeamManager.GetXTeamByStageId(stageId)
local teamData = XTeamManager.LoadTeamLocal(stageId)
local teamId = GetTeamKey(stageId)
local result = TeamDic[teamId]
if result == nil then
result = XTeam.New(teamId)
result:UpdateFromTeamData(teamData)
TeamDic[teamId] = result
end
return result
end
--根据teamID从内存获取XTeam
function XTeamManager.GetXTeam(teamId)
return TeamDic[teamId]
end
--把XTeam根据其TeamID存到内存
---@param xTeam
function XTeamManager.SetXTeam(xTeam)
TeamDic[xTeam:GetId()] = xTeam
end
--把XTeam从内存引用中移除
---@param xTeam
function XTeamManager.RemoveXTeam(xTeam)
TeamDic[xTeam:GetId()] = nil
end
function XTeamManager.GetXTeamEntityIds(teamId)
-- 截断旧队伍逻辑处理
local team = XTeamManager.GetXTeam(teamId)
if team then
return team:GetEntityIds()
end
return nil
end
function XTeamManager.GetXTeamCaptainPos(teamId)
local team = XTeamManager.GetXTeam(teamId)
if team then
return team:GetCaptainPos()
end
return nil
end
function XTeamManager.GetXTeamFirstFightPos(teamId)
local team = XTeamManager.GetXTeam(teamId)
if team then
return team:GetFirstFightPos()
end
return nil
end
function XTeamManager.SaveXTeam(teamId)
local team = XTeamManager.GetXTeam(teamId)
if team then
team:ManualSave()
end
end
-- 创建临时使用的队伍实体
function XTeamManager.CreateTempTeam(entityIds)
local result = XTeam.New(XTime.GetServerNowTimestamp())
result:UpdateAutoSave(false)
result:UpdateEntityIds(entityIds)
return result
end
function XTeamManager.CreateTeam(teamId)
local result = XTeam.New(teamId)
result:UpdateLocalSave(false)
return result
end
function XTeamManager.GetXTeamWithPrefab(teamId)
local result
for _, teamData in pairs(PlayerTeamPrefabData) do
if teamData.TeamId == teamId then
result = XTeam.New(XTime.GetServerNowTimestamp())
result:UpdateAutoSave(false)
result:UpdateFromTeamData(teamData)
return result
end
end
return result
end
-- team : XTeam
function XTeamManager.RequestSaveTeam(team)
local entityIds = {}
XMessagePack.MarkAsTable(entityIds)
for i, v in ipairs(team:GetEntityIds()) do
entityIds[i] = v
end
local requestBody = {
TeamData = {
TeamData = entityIds,
TeamId = team:GetId(),
CaptainPos = team:GetCaptainPos(),
FirstFightPos = team:GetFirstFightPos(),
TeamName = team:GetName()
}
}
XNetwork.CallWithAutoHandleErrorCode(METHOD_NAME.SetTeam, requestBody)
end
XTeamManager.Init()
return XTeamManager
end
XRpc.NotifyTeamClear = function(data)
XDataCenter.TeamManager.ResetTeamData(data.TeamId)
end