PGRData/Script/matrix/xentity/xescape/XEscapeData.lua
2024-09-01 22:49:41 +02:00

425 lines
No EOL
13 KiB
Lua

local XEscapeCharacterState = require("XEntity/XEscape/XEscapeCharacterState")
local XEscapeStageResult = require("XEntity/XEscape/XEscapeStageResult")
local XEscapeChapterResult = require("XEntity/XEscape/XEscapeChapterResult")
local XEscapeTacticsNodeData = require("XEntity/XEscape/Tactics/XEscapeTacticsNodeData")
local type = type
local tableInsert = table.insert
local tableRemove = table.remove
--大逃杀基础信息
---@class XEscapeData
local XEscapeData = XClass(nil, "XEscapeData")
local Default = {
_ChapterId = 0, --进行中的章节
_RemainTime = 0, --剩余时间
_MaxRemainTime = 0, --最大上限
_Score = 0, --评分
_SelectedCardIds = {}, --选择的角色
_SelectedRobotIds = {}, --选择的机器人
_PrefightCaptainPos = 1, --队长位置
_PrefightFirstPos = 1, --首发位置
_OldRemainTime = 0, --旧时长
_CharacterStates = {}, --角色/机器人状态
_StageResults = {}, --当前通关结果
_PassStageIds = {}, --已通关关卡ID
_ChapterResults = {}, --章节结果
_TacticsNodes = {}, --策略节点
}
function XEscapeData:Ctor()
self:Init()
end
function XEscapeData:Init()
for key, value in pairs(Default) do
if type(value) == "table" then
self[key] = {}
else
self[key] = value
end
end
self.PassStageIdDic = {} --已通关关卡ID字典
self.ChapterResultsDic = {}
end
--region Setter
function XEscapeData:UpdateData(data)
if not XTool.IsNumberValid(data.ActivityId) then
self:Init()
return
end
self:SetChapterId(data.ChapterId)
self:SetRemainTime(data.RemainTime)
self:SetMaxRemainTime(data.MaxRemainTime)
self._Score = data.Score
self._SelectedCardIds = data.SelectedCardIds
self._SelectedRobotIds = data.SelectedRobotIds
self._PassStageIds = data.PassStageIds
if XTool.IsNumberValid(data.PrefightCaptainPos) then
self._PrefightCaptainPos = data.PrefightCaptainPos
end
if XTool.IsNumberValid(data.PrefightFirstFightPos) then
self._PrefightFirstPos = data.PrefightFirstFightPos
end
self:UpdateStageResults(data.StageResults)
self:UpdatePassStageIdDic(data.PassStageIds)
self:UpdateChapterResults(data.ChapterResults)
self:UpdateTacticsNodes(data.TacticsNodes)
self:UpdateTeam()
end
function XEscapeData:UpdateTeam()
if XTool.IsTableEmpty(self._SelectedCardIds) and XTool.IsTableEmpty(self._SelectedRobotIds) then
return
end
-- 减少同步请求
local team = XDataCenter.EscapeManager.GetTeam()
local EntityIds = {}
for i, characterId in ipairs(self._SelectedCardIds) do
if XTool.IsNumberValid(characterId) then
EntityIds[i] = characterId or 0
end
end
for i, robotId in ipairs(self._SelectedRobotIds) do
if XTool.IsNumberValid(robotId) then
EntityIds[i] = robotId or 0
end
end
local teamData = {
FirstFightPos = self._PrefightFirstPos,
CaptainPos = self._PrefightCaptainPos,
TeamData = EntityIds,
TeamName = team:GetName()
}
team:UpdateFromTeamData(teamData)
end
function XEscapeData:UpdateChapterResults(chapterResults)
self.ChapterResultsDic = {}
for _, data in ipairs(chapterResults or {}) do
local chapterResult = XEscapeChapterResult.New()
chapterResult:UpdateData(data)
self.ChapterResultsDic[data.ChapterId] = chapterResult
end
end
function XEscapeData:UpdatePassStageIdDic(passStageIds)
for _, stageId in ipairs(passStageIds) do
self:UpdatePassStageId(stageId)
end
end
function XEscapeData:UpdatePassStageId(stageId)
self.PassStageIdDic[stageId] = true
end
---角色状态更新(1期不开放中途换角,2期开发后弃用)
function XEscapeData:UpdateCharacterStateData(characterStates)
self._CharacterStates = {}
for _, data in ipairs(characterStates) do
local characterState = XEscapeCharacterState.New()
characterState:UpdateData(data)
tableInsert(self._CharacterStates, characterState)
end
end
function XEscapeData:UpdateStageResults(stageResults)
self._StageResults = {}
if XTool.IsTableEmpty(stageResults) then
return
end
for _, data in ipairs(stageResults) do
self:UpdateStageResult(data)
end
end
function XEscapeData:UpdateStageResult(stageResult)
local characterState = XEscapeStageResult.New()
characterState:UpdateData(stageResult)
tableInsert(self._StageResults, characterState)
end
function XEscapeData:UpdateTacticsNodes(tacticsNodes)
---@type XEscapeTacticsNodeData[]
self._TacticsNodes = {}
if XTool.IsTableEmpty(tacticsNodes) then
return
end
for i, tacticsNode in ipairs(tacticsNodes) do
---@type XEscapeTacticsNodeData
local tacticsNodeData = XEscapeTacticsNodeData.New()
tacticsNodeData:UpdateData(tacticsNode)
self._TacticsNodes[#self._TacticsNodes+1] = tacticsNodeData
end
end
function XEscapeData:AddTacticsNodes(data)
if XTool.IsTableEmpty(self._TacticsNodes) then
self._TacticsNodes = {}
end
local tacticsNodeData = XEscapeTacticsNodeData.New()
self._TacticsNodes[#self._TacticsNodes + 1] = tacticsNodeData
tacticsNodeData:UpdateData(data)
end
function XEscapeData:TacticsNodeSelectTactics(tacticsNodeId, tacticsId)
local data = self:GetTacticsNodeData(tacticsNodeId)
if not data then
return
end
data:SetSelectTacticsId(tacticsId)
end
function XEscapeData:SetChapterId(chapterId)
self._ChapterId = chapterId
end
function XEscapeData:SetMaxRemainTime(maxRemainTime)
self._MaxRemainTime = maxRemainTime
end
function XEscapeData:SetRemainTime(remainTime)
self._OldRemainTime = self._RemainTime
self._RemainTime = remainTime
end
--endregion
--region Getter
function XEscapeData:GetScore()
return self._Score
end
function XEscapeData:GetRemainTime()
return self._RemainTime
end
function XEscapeData:GetOldRemainTime()
return self._OldRemainTime
end
function XEscapeData:GetMaxRemainTime()
return self._MaxRemainTime
end
function XEscapeData:GetChapterId()
return self._ChapterId
end
function XEscapeData:GetCurLayer()
local curChapterId = self:GetChapterId()
if not XTool.IsNumberValid(curChapterId) then
return false
end
local layerIds = XEscapeConfigs.GetChapterLayerIds(curChapterId)
for _, layerId in ipairs(layerIds) do
if not self:IsLayerClear(layerId, true) then
return layerId
end
end
return false
end
function XEscapeData:GetLayerClearNodeCount(layerId, isCurChallengeChapter)
local stageCount = self:_GetLayerClearStageCount(layerId, isCurChallengeChapter)
local tacticsCount = self:_GetLayerClearTacticsCount(layerId, isCurChallengeChapter)
return stageCount + tacticsCount
end
function XEscapeData:_GetLayerClearStageCount(layerId, isCurChallengeChapter)
local stageIds = XEscapeConfigs.GetLayerStageIds(layerId)
local count = 0
if XTool.IsTableEmpty(stageIds) then
return count
end
for _, stageId in ipairs(stageIds) do
if isCurChallengeChapter then
count = self:IsCurChapterStageClear(stageId) and count + 1 or count
elseif self:IsStageClear(stageId) then
count = count + 1
end
end
return count
end
function XEscapeData:_GetLayerClearTacticsCount(layerId, isCurChallengeChapter)
local tacticsNodeIds = XEscapeConfigs.GetLayerTacticsNodeIds(layerId)
local count = 0
if XTool.IsTableEmpty(tacticsNodeIds) then
return count
end
for _, nodeId in ipairs(tacticsNodeIds) do
if isCurChallengeChapter then
count = self:IsCurChapterTacticsNodeClear(nodeId) and count + 1 or count
end
end
return count
end
---@return XEscapeCharacterState
function XEscapeData:GetCharacterState(entityId)
for _, characterState in ipairs(self._CharacterStates) do
if characterState:GetCharacterId() == XEntityHelper.GetCharacterIdByEntityId(entityId) then
return characterState
end
end
end
function XEscapeData:GetAllHit()
local allHit = 0
for _, stageResult in ipairs(self._StageResults) do
allHit = allHit + stageResult:GetHit()
end
return allHit
end
function XEscapeData:GetAllTrapHit()
local allTrapHit = 0
for _, stageResult in ipairs(self._StageResults) do
allTrapHit = allTrapHit + stageResult:GetTrapHit()
end
return allTrapHit
end
---@return XEscapeChapterResult
function XEscapeData:GetChapterResult(chapterId)
return self.ChapterResultsDic[chapterId]
end
---@return XEscapeTacticsNodeData
function XEscapeData:GetTacticsNodeData(nodeId)
if XTool.IsTableEmpty(self._TacticsNodes) then
return false
end
for _, tacticsNode in ipairs(self._TacticsNodes) do
if nodeId == tacticsNode:GetNodeId() then
return tacticsNode
end
end
return false
end
---@return XEscapeTactics[]
function XEscapeData:GetCurSelectTactics()
local result = {}
for _, tacticsNode in ipairs(self._TacticsNodes) do
if tacticsNode:GetSelectTactics() then
result[#result + 1] = tacticsNode:GetSelectTacticsId()
end
end
return XDataCenter.EscapeManager.GetTacticsByList(result)
end
---@return XEscapeTactics[]
function XEscapeData:GetTacticsNodeTacticsList(nodeId)
if XTool.IsTableEmpty(self._TacticsNodes) then
return false
end
for _, tacticsNode in ipairs(self._TacticsNodes) do
if nodeId == tacticsNode:GetNodeId() then
return tacticsNode:GetTacticsList()
end
end
return false
end
--endregion
--region Check
---当前正在进行中的章节,关卡是否通关
function XEscapeData:IsCurChapterStageClear(stageId)
for _, stageResult in ipairs(self._StageResults) do
if stageId == stageResult:GetStageId() then
return true
end
end
return false
end
---当前正在进行中的章节,是否选择策略
function XEscapeData:IsCurChapterTacticsNodeClear(tacticsNodeId)
for _, tacticsNodeData in ipairs(self._TacticsNodes) do
if tacticsNodeId == tacticsNodeData:GetNodeId() and tacticsNodeData:IsSelect() then
return true
end
end
return false
end
---当前正在进行中的章节,策略节点是否被选择
function XEscapeData:IsCurChapterTacticsNodeSelect(layerId, tacticsNodeId)
for _, tacticsNodeData in ipairs(self._TacticsNodes) do
if layerId == tacticsNodeData:GetLayerId() and tacticsNodeData:GetNodeId() == tacticsNodeId then
return true, true
end
end
return false
end
---当前正在进行中的章节是否通关
function XEscapeData:IsCurChapterClear()
local curChapterId = self:GetChapterId()
if not XTool.IsNumberValid(curChapterId) then
return false
end
local layerIds = XEscapeConfigs.GetChapterLayerIds(curChapterId)
for _, layerId in ipairs(layerIds) do
if not self:IsLayerClear(layerId, true) then
return false
end
end
return true
end
function XEscapeData:IsLayerClear(layerId, isCurChapter)
local clearNodeCount = XEscapeConfigs.GetLayerNodeCount(layerId)
local clearStageCount = XEscapeConfigs.GetLayerClearStageCount(layerId)
local stageIds = XEscapeConfigs.GetLayerStageIds(layerId)
local nodeIds = XEscapeConfigs.GetLayerTacticsNodeIds(layerId)
for _, stageId in ipairs(stageIds) do
if isCurChapter then
if self:IsCurChapterStageClear(stageId) then
clearNodeCount = clearNodeCount - 1
end
elseif self:IsStageClear(stageId) then
clearStageCount = clearStageCount - 1
end
end
-- 不是挑战中的章节不需要考虑策略节点
if not isCurChapter then
return clearStageCount <= 0
end
for _, tacticsNodeId in ipairs(nodeIds) do
if isCurChapter then
if self:IsCurChapterTacticsNodeClear(tacticsNodeId) then
clearNodeCount = clearNodeCount - 1
end
end
end
return clearNodeCount <= 0
end
function XEscapeData:IsStageClear(stageId)
return self.PassStageIdDic[stageId] or false
end
function XEscapeData:IsInChallengeChapter(chapterId)
return self:GetChapterId() == chapterId
end
function XEscapeData:IsChapterClear(chapterId)
local layerIds = XEscapeConfigs.GetChapterLayerIds(chapterId)
for _, layerId in ipairs(layerIds) do
if not self:IsLayerClear(layerId) then
return false
end
end
return true
end
--endregion
return XEscapeData