PGRData/Script/matrix/xmanager/XTeamManager.lua

689 lines
23 KiB
Lua
Raw Normal View History

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
function XTeamManager.GetXTeam(teamId)
return TeamDic[teamId]
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