PGRData/Script/matrix/xentity/xtheatre/adventure/XAdventureManager.lua

697 lines
24 KiB
Lua
Raw Permalink Normal View History

local XAdventureChapter = require("XEntity/XTheatre/Adventure/XAdventureChapter")
local XAdventureDifficulty = require("XEntity/XTheatre/Adventure/XAdventureDifficulty")
local XAdventureMultiDeploy = require("XEntity/XTheatre/Adventure/Deploy/XAdventureMultiDeploy")
local XTheatreToken = require("XEntity/XTheatre/Token/XTheatreToken")
local XTheatreTeam = require("XEntity/XTheatre/XTheatreTeam")
local XAdventureRole = require("XEntity/XTheatre/Adventure/XAdventureRole")
local XAdventureSkill = require("XEntity/XTheatre/Adventure/XAdventureSkill")
local XAdventureEnd = require("XEntity/XTheatre/Adventure/XAdventureEnd")
2024-09-01 20:49:41 +00:00
---@class XTheatreAdventureManager
local XAdventureManager = XClass(nil, "XAdventureManager")
function XAdventureManager:Ctor()
-- 当前难度数据 XAdventureDifficulty
self.CurrentDifficulty = nil
-- 当前章节数据 XAdventureChapter
self.CurrentChapter = nil
-- 当前选择的信物 XTheatreToken
self.CurrentToken = nil
-- 当前可用的角色 XAdventureRole
self.CurrentRoles = {}
-- 多队伍编队管理
self.AdventureMultiDeploy = XAdventureMultiDeploy.New()
-- 当前冒险等级,可通过升级节点增加
self.CurrentLevel = XTheatreConfigs.GetInitLevel()
-- 已重开的次数
self.ReopenedCount = 0
-- 单队伍数据 XTheatreTeam
self.SingleTeam = nil
-- 当前的获取的技能 XAdventureSkill
self.CurrentSkills = nil
-- 当前操作队列
self.OperationQueue = XQueue.New()
-- 是否能够使用自己的角色
self.CanUseLocalRole = false
-- 当前获取的好感度
self.CurrentFavorCoin = 0
-- 当前获得的装修点
self.CurrentDecorationCoin = 0
end
function XAdventureManager:InitWithServerData(data)
local chapaterData = data.CurChapterDb
-- 更新当前章节数据
self.CurrentChapter = XAdventureChapter.New(chapaterData.ChapterId)
self.CurrentChapter:InitWithServerData({
RefreshRoleCount = chapaterData.RefreshRoleCount, -- 刷新角色次数
CurNodeDb = chapaterData.CurNodeDb, -- 当前节点数据
RefreshRole = chapaterData.RefreshRole, -- 已刷新的角色
-- 选择技能,战斗结束,发放选择技能奖励,重新登录恢复这页面
SkillToSelect = chapaterData.SkillToSelect,
PassNodeCount = data.PassNodeCount -- 当前已通过的节点数
-- FavorCoin = data.FavorCoin, -- 当前章节获取的好感度
-- DecorationCoin = data.DecorationCoin, -- 当前章节获取的装修点
})
-- 更新当前难度
self.CurrentDifficulty = XAdventureDifficulty.New(data.DifficultyId)
-- 更新当前选择的信物
if data.KeepsakeId > 0 then
local tokenId = XDataCenter.TheatreManager.GetTokenManager():GetTokenId(data.KeepsakeId)
self.CurrentToken = XTheatreToken.New(tokenId)
end
-- 更新当前冒险等级
self:UpdateCurrentLevel(data.CurRoleLv)
-- 更新已重开的次数
self.ReopenedCount = data.ReopenCount
-- 更新当前拥有的技能
self.CurrentSkills = nil
for _, skillId in ipairs(data.Skills) do
self:AddSkill(skillId)
end
-- 更新当前可用的角色
for _, roleId in ipairs(data.RecruitRole) do
self:AddRoleById(roleId)
end
-- 更新是否能够使用自己的角色
self.CanUseLocalRole = data.UseOwnCharacter == 1
-- 更新好感度
self.CurrentFavorCoin = data.FavorCoin
-- 更新装修点
self.CurrentDecorationCoin = data.DecorationCoin
-- 更新单队伍数据
self:UpdateTeamByServerData(self:GetSingleTeam(), data.SingleTeamData)
-- 更新多队伍数据
if data.MultiTeamDatas then
for i, v in ipairs(data.MultiTeamDatas) do
self:UpdateTeamByServerData(self:GetMultipleTeamByIndex(v.TeamIndex)
, data.MultiTeamDatas[i])
end
end
end
function XAdventureManager:UpdateTeamByServerData(team, data)
team:Clear()
if data == nil then return end
team:UpdateCaptainPos(data.CaptainPos)
team:UpdateFirstFightPos(data.FirstFightPos)
-- 本地角色处理
for pos, id in ipairs(data.CardIds) do
if id > 0 then
team:UpdateEntityTeamPos(id, pos, true)
end
end
-- 机器人角色处理
for pos, id in ipairs(data.RobotIds) do
if id > 0 then
team:UpdateEntityTeamPos(self:GetRoleIdByRobotId(id)
, pos, true)
end
end
end
function XAdventureManager:UpdateReopenCount(value)
self.ReopenedCount = value
end
function XAdventureManager:UpdateUseOwnCharacter(value)
self.CanUseLocalRole = value == 1
end
function XAdventureManager:UpdateCurrentFavorCoin(value)
self.CurrentFavorCoin = value
end
function XAdventureManager:UpdateCurrentDecorationCoin(value)
self.CurrentDecorationCoin = value
end
function XAdventureManager:GetCurrentFavorCoin()
return self.CurrentFavorCoin
end
function XAdventureManager:GetCurrentDecorationCoin()
return self.CurrentDecorationCoin
end
function XAdventureManager:Enter()
if self.CurrentDifficulty == nil then
-- 未选择难度
XUiManager.TipErrorWithKey("TheatreNotSelectDifficulty")
return
end
XDataCenter.TheatreManager.UpdateCurrentAdventureManager(self)
-- 请求开始冒险
self:RequestStartAdventure(function()
self:EnterChapter()
end)
end
function XAdventureManager:Release()
self:ClearTeam()
end
function XAdventureManager:ClearTeam()
if self.SingleTeam then
self.SingleTeam:Clear()
self.SingleTeam = nil
end
self.AdventureMultiDeploy:ClearTeam()
end
function XAdventureManager:AddNextOperationData(data, isFront)
if isFront then
self.OperationQueue:EnqueueFront(data)
else
self.OperationQueue:Enqueue(data)
end
end
function XAdventureManager:ShowNextOperation(callback)
if self.OperationQueue:IsEmpty() then
if callback then callback() end
return
end
local data = self.OperationQueue:Dequeue()
local chapter = self:GetCurrentChapter()
if data.OperationQueueType == XTheatreConfigs.OperationQueueType.NodeReward then
-- 技能选择奖励
if data.RewardType == XTheatreConfigs.AdventureRewardType.SelectSkill then
if table.nums(data.Skills) <= 0 then
self:RequestOpenSkill(function(res)
XLuaUiManager.Open("UiTheatreChooseBuff", res.Skills
, function() self:ShowNextOperation(callback) end)
end)
else
XLuaUiManager.Open("UiTheatreChooseBuff", data.Skills
, function() self:ShowNextOperation(callback) end)
end
-- 升级
elseif data.RewardType == XTheatreConfigs.AdventureRewardType.LevelUp then
XLuaUiManager.Open("UiTheatreTeamUp", data.LastLevel, data.LastAveragePower
, function() self:ShowNextOperation(callback) end)
-- 装修点
elseif data.RewardType == XTheatreConfigs.AdventureRewardType.Decoration then
XUiManager.OpenUiObtain({{
RewardType = XRewardManager.XRewardType.Item,
TemplateId = XTheatreConfigs.TheatreDecorationCoin,
Count = data.DecorationPoint
}}, nil, function() self:ShowNextOperation(callback) end)
-- 好感度
elseif data.RewardType == XTheatreConfigs.AdventureRewardType.PowerFavor then
XUiManager.OpenUiObtain({{
RewardType = XRewardManager.XRewardType.Item,
TemplateId = XTheatreConfigs.TheatreFavorCoin,
Count = data.FavorPoint
}}, nil, function() self:ShowNextOperation(callback) end)
end
elseif data.OperationQueueType == XTheatreConfigs.OperationQueueType.ChapterSettle then
XScheduleManager.ScheduleOnce(function()
XLuaUiManager.Remove("UiTheatrePlayMain")
-- 进入下一个章节
self:EnterChapter(data.LastChapteEndStoryId)
end, 1)
-- if callback then callback() end
elseif data.OperationQueueType == XTheatreConfigs.OperationQueueType.AdventureSettle then
XDataCenter.TheatreManager.SetCurLoadSceneChapterId(nil)
XLuaUiManager.Remove("UiTheatreContinue")
XLuaUiManager.Remove("UiTheatreOutpost")
XLuaUiManager.Remove("UiTheatrePlayMain")
local adventureEnd = XAdventureEnd.New(data.SettleData.Ending)
adventureEnd:InitWithServerData(data.SettleData)
XLuaUiManager.Open("UiTheatreInfiniteSettleWin", adventureEnd, data.LastChapteEndStoryId)
-- if callback then callback() end
elseif data.OperationQueueType == XTheatreConfigs.OperationQueueType.BattleSettle then
if table.nums(data.RewardGoodsList) > 0 then
XUiManager.OpenUiObtain(data.RewardGoodsList
, nil, function() self:ShowNextOperation(callback) end)
else
self:ShowNextOperation(callback)
end
end
end
function XAdventureManager:GetCurrentChapter(autoCreatre)
if autoCreatre == nil then autoCreatre = true end
if self.CurrentChapter == nil and autoCreatre then
self:UpdateNextChapter()
end
return self.CurrentChapter
end
function XAdventureManager:CreatreChapterById(id)
self.CurrentChapter = XAdventureChapter.New(id)
return self.CurrentChapter
end
function XAdventureManager:UpdateNextChapter()
if self.CurrentChapter == nil then
self.CurrentChapter = XAdventureChapter.New(self:GetDefaultChapterId())
else
local nextChapterId = self.CurrentChapter:GetId() + 1
if XTheatreConfigs.GetTheatreChapter(nextChapterId) then
self.CurrentChapter = XAdventureChapter.New(nextChapterId)
end
end
end
-- 进入下一个章节
function XAdventureManager:EnterChapter(lastChapterStoryId)
local currentChapter = self:GetCurrentChapter()
-- 如果当前章节没有开启,直接触发冒险结算
if not currentChapter:GetIsOpen(true) then
-- 触发冒险结算
self:RequestSettleAdventure()
return
end
-- 打开章节开启界面
XLuaUiManager.Remove("UiTheatreChoose")
XLuaUiManager.Open("UiTheatreLoading", function()
XDataCenter.TheatreManager.SetCurLoadSceneChapterId(currentChapter:GetId())
currentChapter:SetIsReady(true)
-- 如果有招募,打开成员招募界面
if currentChapter:GetIsCanRecruit() then
XLuaUiManager.Remove("UiTheatreContinue")
XLuaUiManager.Open("UiTheatreRecruit", currentChapter:GetId(), true)
else
-- 进入选择界面
XLuaUiManager.Open("UiTheatrePlayMain")
end
end, lastChapterStoryId)
end
function XAdventureManager:GetDefaultChapterId()
return 1
end
-- token : XTheatreToken
function XAdventureManager:UpdateCurrentToken(token)
self.CurrentToken = token
end
function XAdventureManager:GetCurrentToken()
return self.CurrentToken
end
-- 检查是否能够使用本地角色
function XAdventureManager:CheckCanUseLocalRole()
return self.CanUseLocalRole
end
-- includeLocal : 是否包含本地角色
2024-09-01 20:49:41 +00:00
---@return XTheatreAdventureRole[]
function XAdventureManager:GetCurrentRoles(includeLocal)
if includeLocal == nil then includeLocal = false end
local canUseLocal = false
if includeLocal then
canUseLocal = self:CheckCanUseLocalRole()
if canUseLocal then
for _, role in ipairs(self.CurrentRoles) do
role:GenerateLocalRole()
end
end
end
if includeLocal then return self.CurrentRoles end
local result = {}
for _, role in ipairs(self.CurrentRoles) do
if not role:GetIsLocalRole() then
table.insert(result, role)
end
end
return result
end
-- 获得已招募角色和剩余可招募的格子数
function XAdventureManager:GetRecruitTotalRoles()
local adventureChapter = self:GetCurrentChapter()
local currentRoles = self:GetCurrentRoles()
local recruitGridCount = XTheatreConfigs.GetChapterRecruitGrid(adventureChapter:GetId())
local lastGridCount = recruitGridCount - #currentRoles
2024-09-01 20:49:41 +00:00
local result = {}
2024-09-01 20:49:41 +00:00
if not XTool.IsTableEmpty(currentRoles) then
for _, grid in ipairs(currentRoles) do
table.insert(result, grid)
end
end
for i = 1, lastGridCount do
2024-09-01 20:49:41 +00:00
table.insert(result, {})
end
2024-09-01 20:49:41 +00:00
return result
end
function XAdventureManager:AddRoleById(roleId, configId)
if configId == nil then configId = roleId end
for _, role in ipairs(self.CurrentRoles or {}) do
if role:GetId() == roleId then
-- 重复添加
return role
end
end
table.insert(self.CurrentRoles, XAdventureRole.New(configId))
return self.CurrentRoles[#self.CurrentRoles]
end
2024-09-01 20:49:41 +00:00
---@return XTheatreAdventureRole
function XAdventureManager:GetRole(id)
for _, role in ipairs(self:GetCurrentRoles(true)) do
if role:GetId() == id then
return role
end
end
end
2024-09-01 20:49:41 +00:00
---BattleRoom用
---@param id number characterId or robotId
---@return XTheatreAdventureRole
function XAdventureManager:GetRoleByRobotId(id)
for _, role in ipairs(self:GetCurrentRoles(true)) do
if role:GetId() == id or role:GetRawDataId() == id then
return role
end
end
end
-- 获取角色平均战力
function XAdventureManager:GeRoleAveragePower()
local result = 0
local roles = self:GetCurrentRoles(false)
for _, role in ipairs(roles) do
result = result + role:GetAbility()
end
if result == 0 then
return 0
end
result = math.floor(result / #roles)
return result
end
-- 获取开启的所有难度数据
function XAdventureManager:GetDifficulties(checkOpen)
if checkOpen == nil then checkOpen = false end
if self.__Difficulties == nil then
self.__Difficulties = {}
local difficultyConfigDic = XTheatreConfigs.GetTheatreDifficulty()
for id, _ in pairs(difficultyConfigDic) do
table.insert(self.__Difficulties, XAdventureDifficulty.New(id))
end
table.sort(self.__Difficulties, function(a, b)
return a:GetId() < b:GetId()
end)
end
if checkOpen then
local result = {}
for _, difficulty in ipairs(self.__Difficulties) do
if difficulty:GetIsOpen() then
table.insert(result, difficulty)
end
end
return result
end
return self.__Difficulties
end
function XAdventureManager:UpdateCurrentDifficulty(value)
self.CurrentDifficulty = value
end
function XAdventureManager:GetCurrentDifficulty()
return self.CurrentDifficulty
end
function XAdventureManager:GetPlayableCount()
local currentDifficulty = self:GetCurrentDifficulty()
local reopenCount = currentDifficulty and currentDifficulty:GetReopenCount() or 0
XDataCenter.TheatreManager.GetDecorationManager():HandleActiveDecorationTypeParam(XTheatreConfigs.DecorationReopenOptionType
, function(param)
reopenCount = reopenCount + tonumber(param)
end)
return math.max(reopenCount - self.ReopenedCount, 0)
end
function XAdventureManager:GetSingleTeam()
if self.SingleTeam == nil then
self.SingleTeam = XTheatreTeam.New("Theatre_Adventure_Single_Team")
end
return self.SingleTeam
end
function XAdventureManager:GetMultipleTeamByIndex(index)
return self.AdventureMultiDeploy:GetMultipleTeamByIndex(index)
end
function XAdventureManager:GetTeamById(id)
if self.SingleTeam and self.SingleTeam:GetId() == id then
return self.SingleTeam
end
return self.AdventureMultiDeploy:GetTeamById(id)
end
function XAdventureManager:GetAdventureMultiDeploy()
return self.AdventureMultiDeploy
end
-- 获取冒险等级
function XAdventureManager:GetCurrentLevel()
return self.CurrentLevel
end
function XAdventureManager:UpdateCurrentLevel(value)
self.CurrentLevel = value
self:UpdateCurrentRoleRobots(value)
end
function XAdventureManager:UpdateCurrentRoleRobots(level)
for _, role in ipairs(self.CurrentRoles) do
if not role:GetIsLocalRole() then
role:GenerateNewRobot(level)
end
end
end
function XAdventureManager:GetCurrentSkills()
return self.CurrentSkills or {}
end
function XAdventureManager:GetCoreSkills()
local result = {}
local additionalSkillCount = 0
for _, skill in ipairs(self:GetCurrentSkills()) do
if skill:GetSkillType() == XTheatreConfigs.SkillType.Core then
table.insert(result, skill)
else
additionalSkillCount = additionalSkillCount + 1
end
end
table.sort(result, function(aSkill, bSkill)
return aSkill:GetPos() < bSkill:GetPos()
end)
return result, additionalSkillCount
end
--获得对应位置的技能
function XAdventureManager:GetCoreSkillByPos(pos)
local coreSkills = self:GetCoreSkills()
for i, v in ipairs(coreSkills) do
if v:GetPos() == pos then
return v
end
end
end
function XAdventureManager:GetCoreSkillLv(skillType)
local coreSkills = self:GetCoreSkills()
for _, v in ipairs(coreSkills) do
local skillTypeList = XTheatreConfigs.GetTheatreSkillPosDefineSkillType(v:GetPos())
for _, skillTypeTemp in ipairs(skillTypeList) do
if skillType == skillTypeTemp then
return v:GetCurrentLevel()
end
end
end
end
function XAdventureManager:GetAdditionSkillDic()
local result = {}
local powerCountDic = {}
local powerId = nil
for _, skill in ipairs(self:GetCurrentSkills()) do
if skill:GetSkillType() == XTheatreConfigs.SkillType.Additional then
powerId = skill:GetPowerId()
if not powerCountDic[powerId] then
table.insert(result, skill)
end
powerCountDic[powerId] = powerCountDic[powerId] and powerCountDic[powerId] + 1 or 1
end
end
return result, powerCountDic
end
function XAdventureManager:AddSkill(id)
self.CurrentSkills = self.CurrentSkills or {}
table.insert(self.CurrentSkills, XAdventureSkill.New(id))
end
-- 获取当前所有技能附加的战力
function XAdventureManager:GetCurrentSkillsPower()
local result = 0
for _, skill in ipairs(self:GetCurrentSkills()) do
result = result + skill:GetAdditionalPower()
end
return result
end
function XAdventureManager:EnterFight(inStageId, index, callback)
if index == nil then index = 1 end
local theatreStageConfig = XTheatreConfigs.GetTheatreStage(inStageId)
-- 获取关卡id
local stageId = theatreStageConfig and theatreStageConfig.StageId[index] or inStageId
local team = nil
local isMultiFight = theatreStageConfig and theatreStageConfig.StageCount > 1
if isMultiFight then -- 使用多队伍的队伍数据
team = self:GetMultipleTeamByIndex(index)
else
team = self:GetSingleTeam()
end
local stageConfig = XDataCenter.FubenManager.GetStageCfg(stageId)
if stageConfig == nil then return end
local teamId = team:GetId()
local isAssist = false
local challengeCount = 1
XDataCenter.FubenManager.EnterFight(stageConfig, teamId, isAssist, challengeCount, nil, callback)
end
function XAdventureManager:GetCardIdsAndRobotIdsFromTeam(team)
local cardIds = {0, 0, 0}
local robotIds = {0, 0, 0}
local role
for pos, entityId in ipairs(team:GetEntityIds()) do
if entityId > 0 then
role = self:GetRole(entityId)
if role then
if role:GetIsLocalRole() then -- 本地角色
cardIds[pos] = role:GetRawDataId()
else
robotIds[pos] = role:GetRawDataId()
end
else
XLog.Error("肉鸽找不到角色Id为" .. entityId)
end
end
end
return cardIds, robotIds
end
function XAdventureManager:GetRoleIdByRobotId(robotId)
local configs
for _, role in ipairs(self:GetCurrentRoles(false)) do
configs = role:GetAllRobotConfigs()
for _, config in ipairs(configs) do
if config.RobotId == robotId then
return config.RoleId
end
end
end
end
-- function XAdventureManager:GetCurrentState()
-- return self.CurrentState
-- end
--######################## 协议 begin ########################
-- 请求开始冒险
function XAdventureManager:RequestStartAdventure(callback)
local requestBody = {
Difficulty = self.CurrentDifficulty:GetId(), -- 难度Id
KeepsakeId = self.CurrentToken and self.CurrentToken:GetKeepsakeId() or nil, -- 信物id
2024-09-01 20:49:41 +00:00
Mode = XDataCenter.TheatreManager.GetSPMode() and 1 or 0 -- 冒险模式
}
self.CurrentChapter = nil -- 避免其他GetChapter时创建了默认的章节数据
XNetwork.CallWithAutoHandleErrorCode("TheatreStartAdventureRequest", requestBody, function(res)
-- hack : 服务器通知节点有可能比该请求返回还要快,因此如果不为空就用节点通知的
if self.CurrentChapter == nil then
self.CurrentChapter = XAdventureChapter.New(res.ChapterId)
end
-- 进入默认章节
if callback then callback() end
end)
end
-- 请求结束冒险
function XAdventureManager:RequestSettleAdventure(callback)
local requestBody = {}
XNetwork.CallWithAutoHandleErrorCode("TheatreSettleAdventureRequest", requestBody, function(res)
-- 更新全局通过的章节和事件数据
local theatreManager = XDataCenter.TheatreManager
theatreManager.SetCurLoadSceneChapterId(nil)
theatreManager.UpdatePassChapterIds(res.SettleData.PassChapterId)
theatreManager.UpdatePassEventRecord(res.SettleData.PassEventRecord)
theatreManager.UpdateEndingIdRecords(res.SettleData.EndingRecord)
-- 清除队伍数据
self:ClearTeam()
-- 打开结算冒险界面
local adventureEnd = XAdventureEnd.New(res.SettleData.Ending)
adventureEnd:InitWithServerData(res.SettleData)
if callback then callback() end
XLuaUiManager.Open("UiTheatreInfiniteSettleWin", adventureEnd)
end)
end
function XAdventureManager:RequestOpenSkill(callback)
XNetwork.CallWithAutoHandleErrorCode("TheatreNodeShopOpenSkillRequest", {}, function(res)
if callback then callback(res) end
end)
end
-- operationType : XTheatreConfigs.SkillOperationType
-- fromSkill : XAdventureSkill
function XAdventureManager:RequestSelectSkill(skillId, operationType, fromSkill, callback)
local requestBody = {
SkillId = skillId,
}
XNetwork.CallWithAutoHandleErrorCode("TheatreSelectSkillRequest", requestBody, function(res)
if (operationType == XTheatreConfigs.SkillOperationType.LevelUp and skillId ~= fromSkill:GetId())
or operationType == XTheatreConfigs.SkillOperationType.Replace then
local currentSkills = self:GetCurrentSkills()
for i = #currentSkills, 1, -1 do
if currentSkills[i]:GetId() == fromSkill:GetId() then
table.remove(currentSkills, i)
break
end
end
end
XDataCenter.TheatreManager.GetTokenManager():UpdateSkillPowerAndPosToSkillIdDic({skillId})
self:AddSkill(skillId)
if callback then callback() end
end)
end
function XAdventureManager:RequestSkipSelectSkill(callback)
XNetwork.CallWithAutoHandleErrorCode("TheatreSkipSelectSkillRequest", {}, function(res)
if callback then callback() end
end)
end
-- 请求设置单队伍
function XAdventureManager:RequestSetSingleTeam(callback)
local cardIds, robotIds = self:GetCardIdsAndRobotIdsFromTeam(self.SingleTeam)
local requestBody = {
TeamData = {
TeamIndex = 0,
CaptainPos = self.SingleTeam:GetCaptainPos(),
FirstFightPos = self.SingleTeam:GetFirstFightPos(),
CardIds = cardIds,
RobotIds = robotIds,
}
}
XNetwork.CallWithAutoHandleErrorCode("TheatreSetSingleTeamRequest", requestBody, function(res)
if callback then callback() end
end)
end
--######################## 协议 end ########################
return XAdventureManager