PGRData/Script/matrix/xmodule/xtheatre3/xentity/XTheatre3Activity.lua
2024-09-01 22:49:41 +02:00

735 lines
No EOL
20 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 XTheatre3Chapter = require("XModule/XTheatre3/XEntity/XTheatre3Chapter")
local XTheatre3Team = require("XModule/XTheatre3/XEntity/XTheatre3Team")
local XTheatre3Character = require("XModule/XTheatre3/XEntity/XTheatre3Character")
local XTheatre3EquipPos = require("XModule/XTheatre3/XEntity/XTheatre3EquipPos")
local XTheatre3Equip = require("XModule/XTheatre3/XEntity/XTheatre3Equip")
local XTheatre3Settle = require("XModule/XTheatre3/XEntity/XTheatre3Settle")
-- 肉鸽1号位位于最左边对应颜色为蓝色所以需要把红蓝两个颜色交换下
local ColorMap = { [1] = 2, [2] = 1, [3] = 3 }
---@class XTheatre3Activity
local XTheatre3Activity = XClass(nil, "XTheatre3Activity")
function XTheatre3Activity:Ctor()
-- 当前活动ID
self.CurActivityId = 0
-- 当前章节ID
self.CurChapterId = 0
-- 选择的难度ID
self.DifficultyId = 0
-- 能量石上限
self.MaxEnergy = 0
-- 当前章节数据
---@type XTheatre3Chapter
self.CurChapterDb = nil
-- 当前编队数据
---@type XTheatre3Team
self.CurTeamData = nil
-- 角色系统
---@type XTheatre3Character[]
self.Characters = {}
-- 装备系统
---@type XTheatre3Equip[]
self.Equips = {}
-- 装备槽位
---@type XTheatre3EquipPos[]
self.EquipPos = {}
-- 本局拥有道具 { Uid, ItemId }[]
self.Items = {}
-- 已解锁物品ID用于图鉴
---@type number[]
self.UnlockItemId = {}
-- 已解锁装备ID用于图鉴
---@type number[]
self.UnlockEquipId = {}
-- 领取的BattlePassId
---@type number[]
self.GetRewardIds = {}
-- 已经解锁的天赋树Id
---@type number[]
self.UnlockStrengthTree = {}
-- 累计BattlePass 经验
self.TotalBattlePassExp = 0
-- 保存结算前的BP经验用于判断BP等级是否满级
self.TempTotalBattlePassExp = nil
-- 槽位容量 key=槽位Id,value=容量
---@type table<number,number>
self.SlotCapacity = {}
--- 难度通关结局字典
---@type table<number,table>
self.PassDifficultyRecords = {}
---解锁的难度
self.UnlockDifficultyId = {}
---首通标记
self.FirstPassFlag = false
---首次通过章节字典
self.FirstPassChapterDir = {}
---@type XTheatre3Settle
self.Settle = nil
end
function XTheatre3Activity:NotifyTheatre3Activity(data)
self.CurActivityId = data.CurActivityId
self.CurChapterId = data.CurChapterId
self.DifficultyId = data.DifficultyId
self.MaxEnergy = data.MaxEnergy
self.FirstPassFlag = XTool.IsNumberValid(data.FirstPassFlag)
self:UpdateChapterData(data.CurChapterDb)
self:UpdateTeamData(data.CurTeamData)
self:UpdateCharacterData(data.Characters)
self:UpdateEquipData(data.Equips)
self:UpdateEquipPosData(data.EquipPos, true)
self:UpdateItemData(data.Items)
self:UpdateUnlockItemIdData(data.UnlockItemId)
self:UpdateUnlockEquipIdData(data.UnlockEquipId)
self:UpdateGetRewardIdData(data.GetRewardIds)
self:UpdateUnlockStrengthTreeData(data.UnlockStrengthTree)
self:UpdatePassDifficultyRecords(data.PassDifficultyRecords)
self:UpdateUnlockDifficultyId(data.UnlockDifficultyId)
self:UpdateFirstPassChapter(data.PassChapterIds)
self.TotalBattlePassExp = data.TotalBattlePassExp
end
function XTheatre3Activity:NotifyTheatre3AddStep(data)
if not self.CurChapterDb then
self.CurChapterDb = XTheatre3Chapter.New()
end
if XTool.IsTableEmpty(data) then
return
end
local chapterId = self.CurChapterDb.ChapterId
self.CurChapterDb:NotifyAddStep(data)
if XTool.IsNumberValid(chapterId) and chapterId ~= self.CurChapterDb.ChapterId then
self:SetAdventureChapterFirstPass(chapterId)
end
end
function XTheatre3Activity:NotifyTheatre3AddItem(data)
if XTool.IsTableEmpty(data) then
return
end
for _, item in ipairs(data) do
self.Items[#self.Items + 1] = item
end
end
function XTheatre3Activity:NotifyTheatre3NodeNextStep(data)
if XTool.IsTableEmpty(data) then
return
end
local lastNodeSlot, step = self.CurChapterDb:GetLastNodeSlot()
if lastNodeSlot and lastNodeSlot:GetEventId() == data.EventId then
lastNodeSlot:AddPassedStepId(lastNodeSlot:GetCurStepId())
lastNodeSlot:SetCurStepId(data.NextStepId)
if not XTool.IsNumberValid(data.NextStepId) then
step:SetIsOver()
end
end
end
function XTheatre3Activity:UpdateChapterData(data)
if not self.CurChapterDb then
self.CurChapterDb = XTheatre3Chapter.New()
end
if XTool.IsTableEmpty(data) then
return
end
self.CurChapterDb:NotifyTheatre3Chapter(data)
end
function XTheatre3Activity:UpdateTeamData(data)
if not self.CurTeamData then
self.CurTeamData = XTheatre3Team.New("XTheatre3Team")
if not self.CurTeamData:GetIsEmpty() then
return --登录时使用本地保存的数据
end
end
if XTool.IsTableEmpty(data) then
self.CurTeamData:Clear()
return
end
self.CurTeamData:UpdateCaptainPosAndFirstFightPos(data.CaptainPos, data.FirstFightPos)
self.CurTeamData:UpdateCardIdsAndRobotIds(data.CardIds, data.RobotIds)
end
function XTheatre3Activity:UpdateCharacterData(data)
if not data then
return
end
for _, v in pairs(data) do
local character = self.Characters[v.CharacterId]
if not character then
character = XTheatre3Character.New()
self.Characters[v.CharacterId] = character
end
character:NotifyTheatre3Character(v)
end
end
function XTheatre3Activity:UpdateEquipData(data)
if not data then
return
end
local temp = {}
for _, v in pairs(data) do
local pos = v.Pos
if not temp[pos] then
temp[pos] = {}
end
table.insert(temp[pos], v)
end
for pos, v in pairs(temp) do
local slot = self.Equips[pos]
if not slot then
slot = XTheatre3Equip.New()
self.Equips[pos] = slot
end
slot:NotifyTheatre3Equip(pos, v)
end
CsXGameEventManager.Instance:Notify(XEventId.EVENT_THEATRE3_UPDATE_EQUIP)
end
function XTheatre3Activity:UpdateEquipPosData(data, isTeamRoleId)
if XTool.IsTableEmpty(data) then
self:SetDefaultEquipPosData() -- 设置下默认值
return
end
for _, v in ipairs(data) do
local equip = self.EquipPos[v.PosId]
if not equip then
equip = XTheatre3EquipPos.New()
self.EquipPos[v.PosId] = equip
end
self:UpdateEquipPos(equip, v, isTeamRoleId)
self.SlotCapacity[v.PosId] = v.Capacity
end
end
---@param equip XTheatre3EquipPos
function XTheatre3Activity:UpdateEquipPos(equip, data, isTeamRoleId)
-- 初始化的时候ColorId为0需要赋值默认值
if not XTool.IsNumberValid(data.ColorId) then
data.ColorId = ColorMap[data.PosId]
end
if not equip then
return
end
equip:UpdateEquipPosIdAndColorId(data.PosId, data.ColorId)
local roleId = 0
if XTool.IsNumberValid(data.CardId) then
roleId = data.CardId
elseif XTool.IsNumberValid(data.RobotId) then
roleId = data.RobotId
end
local entityId = self.CurTeamData:GetEntityIdByTeamPos(data.ColorId)
if entityId ~= roleId then
XLog.Debug("槽位角色id和编队角色Id不一致", entityId, roleId)
end
equip:UpdateEquipPosRoleId(isTeamRoleId and entityId or roleId)
end
function XTheatre3Activity:SetDefaultEquipPosData()
if not XTool.IsTableEmpty(self.EquipPos) then
return
end
for i = 1, 3 do
local equip = self.EquipPos[i]
if not equip then
equip = XTheatre3EquipPos.New()
self.EquipPos[i] = equip
end
self:UpdateEquipPos(equip, {PosId = i})
end
end
function XTheatre3Activity:UpdateEquipPosRoleId(roleId, slotId, isJoin)
if isJoin then
local slotInfo = self:GetSlotInfo(slotId)
slotInfo:UpdateEquipPosRoleId(roleId)
else
for _, slotInfo in pairs(self:GetSlotInfoList()) do
if slotInfo:GetRoleId() == roleId then
slotInfo:UpdateEquipPosRoleId(0)
break
end
end
end
end
function XTheatre3Activity:UpdateItemData(data)
self.Items = {}
if not XTool.IsTableEmpty(data) then
self.Items = data
end
end
function XTheatre3Activity:UpdateUnlockItemIdData(data)
if not data then
return
end
self.UnlockItemId = {}
for _, itemId in pairs(data) do
if XTool.IsNumberValid(itemId) then
self.UnlockItemId[itemId] = itemId
end
end
end
function XTheatre3Activity:UpdateUnlockEquipIdData(data)
if not data then
return
end
self.UnlockEquipId = {}
for _, itemId in pairs(data) do
if XTool.IsNumberValid(itemId) then
self.UnlockEquipId[itemId] = itemId
end
end
end
function XTheatre3Activity:UpdateGetRewardIdData(data)
if not data then
return
end
self.GetRewardIds = {}
for _, rewardId in pairs(data) do
self:AddGetRewardId(rewardId)
end
end
function XTheatre3Activity:AddGetRewardId(rewardId)
if XTool.IsNumberValid(rewardId) then
self.GetRewardIds[rewardId] = rewardId
end
end
function XTheatre3Activity:UpdateUnlockStrengthTreeData(data)
if not data then
return
end
for _, treeId in pairs(data) do
self:AddUnlockStrengthTreeId(treeId)
end
end
function XTheatre3Activity:AddUnlockStrengthTreeId(treeId)
if XTool.IsNumberValid(treeId) then
self.UnlockStrengthTree[treeId] = treeId
end
end
function XTheatre3Activity:UpdateTotalBattlePassExp(exp)
self.TempTotalBattlePassExp = self.TotalBattlePassExp
self.TotalBattlePassExp = exp
end
function XTheatre3Activity:UpdateSettle(data)
if not self.Settle then
self.Settle = XTheatre3Settle.New()
end
self.Settle:NotifyTheatre3Settle(data)
if data.Items then
-- 本局拥有道具
self:UpdateItemData(data.Items)
end
if data.Equips then
-- 已获得装备
self:UpdateEquipData(data.Equips)
end
if data.EquipPos then
-- 装备槽位
self:UpdateEquipPosData(data.EquipPos)
end
if data.Characters then
-- 角色数据
self:UpdateCharacterData(data.Characters)
end
if data.UnlockItemId then
-- 所有已解锁道具ID
self:UpdateUnlockItemIdData(data.UnlockItemId)
end
if data.UnlockDifficultyId then
-- 已解锁难度ID
self:UpdateUnlockDifficultyId(data.UnlockDifficultyId)
end
if data.UnlockEquipId then
-- 已解锁的装备
self:UpdateUnlockEquipIdData(data.UnlockEquipId)
end
if data.PassDifficultyRecords then
self:UpdatePassDifficultyRecords(data.PassDifficultyRecords)
end
if data.PassChapterIds then
self:UpdateFirstPassChapter(data.PassChapterIds)
self:SetAdventurePassChapterDir({})
end
if XTool.IsNumberValid(data.FirstPassFlag) then
self.FirstPassFlag = true
end
end
function XTheatre3Activity:GetCurActivityId()
return self.CurActivityId
end
function XTheatre3Activity:GetCurChapterId()
return self.CurChapterId
end
function XTheatre3Activity:GetDifficultyId()
return self.DifficultyId
end
function XTheatre3Activity:GetMaxEnergy()
return self.MaxEnergy
end
function XTheatre3Activity:GetTotalBattlePassExp()
return self.TotalBattlePassExp
end
function XTheatre3Activity:CheckUnlockItemId(itemId)
return self.UnlockItemId[itemId] and true or false
end
function XTheatre3Activity:CheckUnlockEquipId(equipId)
return self.UnlockEquipId[equipId] and true or false
end
function XTheatre3Activity:CheckGetRewardId(rewardId)
return self.GetRewardIds[rewardId] and true or false
end
function XTheatre3Activity:CheckUnlockStrengthTree(treeId)
return self.UnlockStrengthTree[treeId] and true or false
end
---@return XTheatre3EquipPos[]
function XTheatre3Activity:GetSlotInfoList()
return self.EquipPos
end
---@return XTheatre3EquipPos
function XTheatre3Activity:GetSlotInfo(slotId)
return self.EquipPos[slotId]
end
function XTheatre3Activity:GetSlotPosIdByColorId(colorId)
for _, v in ipairs(self.EquipPos) do
if v:GetColorId() == colorId then
return v:GetPos()
end
end
return 1
end
function XTheatre3Activity:GetSlotIndexByPos(pos)
for _, v in ipairs(self.EquipPos) do
if v:GetPos() == pos then
return v:GetColorId()
end
end
return 1
end
---@return XTheatre3Character
function XTheatre3Activity:GetCharacterInfo(charId)
return self.Characters[charId]
end
---@return XTheatre3Character[]
function XTheatre3Activity:GetCharacterInfoList()
return self.Characters
end
function XTheatre3Activity:GetMaxCapacity(slotId)
return self.SlotCapacity[slotId] or 0
end
function XTheatre3Activity:_GetSlot(slotId)
local slot = self.Equips[slotId]
if not slot then
slot = XTheatre3Equip.New()
slot:NotifyTheatre3Equip(slotId, {}) -- 初始化
self.Equips[slotId] = slot
end
return slot
end
---@return number[]
function XTheatre3Activity:GetSuitListBySlot(slotId)
local slot = self:_GetSlot(slotId)
return slot.SuitIds
end
function XTheatre3Activity:AddSlotEquip(slotId, equipId, suitId)
local slot = self:_GetSlot(slotId)
slot:AddEquipAndSuit(equipId, suitId)
end
function XTheatre3Activity:ExchangeSlotSuit(srcSuitId, srcPos, srcEquips, dstSuitId, dstPos, dstEquips)
local src = self:_GetSlot(srcPos)
local dst = self:_GetSlot(dstPos)
src:ExchangeSuit(srcSuitId, srcEquips, dstSuitId, dstEquips)
dst:ExchangeSuit(dstSuitId, dstEquips, srcSuitId, srcEquips)
end
function XTheatre3Activity:RebuildSlotEquip(srcSuitId, srcPos, srcEquip, dstSuitId, dstPos, dstEquip)
local src = self:_GetSlot(srcPos)
local dst = self:_GetSlot(dstPos)
src:LoseEquip(srcEquip, srcSuitId)
dst:AddEquipAndSuit(dstEquip, dstSuitId)
end
--region Team
function XTheatre3Activity:GetTeamsEntityIds()
return self.CurTeamData and self.CurTeamData:GetEntityIds() or {}
end
function XTheatre3Activity:GetTeamsCharIds()
return self.CurTeamData and self.CurTeamData:GetCharacterIdsOrder() or {}
end
function XTheatre3Activity:GetTeamRobotIds()
return self.CurTeamData and self.CurTeamData:GetRobotIdsOrder() or {}
end
function XTheatre3Activity:GetCaptainPos()
return self.CurTeamData and self.CurTeamData:GetCaptainPos() or 1
end
function XTheatre3Activity:GetFirstFightPos()
return self.CurTeamData and self.CurTeamData:GetFirstFightPos() or 1
end
function XTheatre3Activity:GetEntityIdIsInTeam(entityId)
return self.CurTeamData:GetEntityIdIsInTeam(entityId)
end
function XTheatre3Activity:UpdateEntityTeamPos(entityId, teamPos, isJoin)
self.CurTeamData:UpdateEntityTeamPos(entityId, teamPos, isJoin)
end
function XTheatre3Activity:UpdateCaptainPosAndFirstFightPos(cPos, fPos)
self.CurTeamData:UpdateCaptainPosAndFirstFightPos(cPos, fPos)
end
function XTheatre3Activity:CheckCaptainHasEntityId()
local entityId = self.CurTeamData:GetCaptainPosEntityId()
return XTool.IsNumberValid(entityId)
end
function XTheatre3Activity:CheckFirstFightHasEntityId()
local entityId = self.CurTeamData:GetFirstFightPosEntityId()
return XTool.IsNumberValid(entityId)
end
function XTheatre3Activity:ResetTeam()
-- 结束冒险后需要重置编队数据
if self.CurTeamData then
self.CurTeamData:Clear()
end
end
--endregion
--region Checker
function XTheatre3Activity:CheckFirstOpenChapterId(chapterId)
if not XTool.IsNumberValid(chapterId - 1) then
return true
end
return self.FirstPassChapterDir[chapterId - 1]
end
function XTheatre3Activity:CheckHasFirstPassFlag()
return self.FirstPassFlag
end
function XTheatre3Activity:CheckHasPassEnding(difficultyId, endingId)
if not self.PassDifficultyRecords[difficultyId] then
return false
end
-- endingId = 0表示任意结局
if not XTool.IsNumberValid(endingId) then
return true
end
return table.indexof(self.PassDifficultyRecords[difficultyId], endingId)
end
function XTheatre3Activity:CheckEndingIsPass(endingId)
if XTool.IsTableEmpty(self.PassDifficultyRecords) then
return false
end
if not XTool.IsNumberValid(endingId) then
return true
end
for _, list in pairs(self.PassDifficultyRecords) do
if table.indexof(list, endingId) then
return true
end
end
return false
end
function XTheatre3Activity:CheckDifficultyIdUnlock(difficultyId)
if XTool.IsTableEmpty(self.UnlockDifficultyId) then
return false
end
return table.indexof(self.UnlockDifficultyId, difficultyId)
end
function XTheatre3Activity:CheckAdventureHasPassEventStep(eventStepId)
-- 不在冒险则为false
if not XTool.IsNumberValid(self.DifficultyId) then
return false
end
return self.CurChapterDb:CheckIsPassEventStep(eventStepId)
end
function XTheatre3Activity:CheckAdventureHasPassChapter(chapterId)
-- 不在冒险则为false
if not XTool.IsNumberValid(self.DifficultyId) then
return false
end
XLog.Error("当前通关章节数据未同步!")
end
function XTheatre3Activity:CheckAdventureHasPassNode(nodeId)
-- 不在冒险则为false
if not XTool.IsNumberValid(self.DifficultyId) then
return false
end
return self.CurChapterDb:CheckIsPassNodeId(nodeId)
end
--endregion
--region EndingRecord
function XTheatre3Activity:UpdatePassDifficultyRecords(data)
self.PassDifficultyRecords = {}
if XTool.IsTableEmpty(data) then
return
end
self.PassDifficultyRecords = data
end
--endregion
--region Difficulty
function XTheatre3Activity:UpdateUnlockDifficultyId(data)
self.UnlockDifficultyId = {}
if XTool.IsTableEmpty(data) then
return
end
self.UnlockDifficultyId = data
end
--endregion
--region Adventure
function XTheatre3Activity:InitAdventureData()
self.DifficultyId = 0
self.MaxEnergy = 0
self.CurChapterId = 0
self.CurChapterDb = nil
end
function XTheatre3Activity:InitAdventureSettleData()
self.Settle = nil
self.Equips = {}
for i = 1, 3 do
self.Equips[i] = XTheatre3Equip.New()
self.Equips[i]:NotifyTheatre3Equip(i, {})
end
self.EquipPos = {}
self.Items = {}
self.TempTotalBattlePassExp = nil
end
function XTheatre3Activity:UpdateDifficulty(difficultyId)
self.DifficultyId = difficultyId
end
function XTheatre3Activity:UpdateMaxEnergy(maxEnergy)
self.MaxEnergy = maxEnergy
end
function XTheatre3Activity:UpdateFirstPassChapter(data)
self.FirstPassChapterDir = {}
if not XTool.IsTableEmpty(data) then
for _, chapterId in ipairs(data) do
self:SetAdventureChapterFirstPass(chapterId, true)
end
end
local dir = self:GetAdventurePassChapterDir()
for chapterId, _ in ipairs(dir) do
self:SetAdventureChapterFirstPass(chapterId, true)
end
end
function XTheatre3Activity:SetAdventureChapterFirstPass(chapterId, isNotSave)
if not XTool.IsNumberValid(chapterId) then
return
end
if not self.FirstPassChapterDir[chapterId] then
self.FirstPassChapterDir[chapterId] = true
end
if isNotSave then
return
end
self:SetAdventurePassChapterDir(self.FirstPassChapterDir)
end
function XTheatre3Activity:GetCurChapterDb()
return self.CurChapterDb
end
function XTheatre3Activity:GetAdventureItemList()
return self.Items
end
function XTheatre3Activity:GetAdventurePassChapterIdSaveKey()
return string.format("GetAdventurePassChapterIdSaveKey_%s_%s", XPlayer.Id, self:GetCurActivityId())
end
function XTheatre3Activity:GetAdventurePassChapterDir()
local key = self:GetAdventurePassChapterIdSaveKey()
return XSaveTool.GetData(key) or {}
end
function XTheatre3Activity:SetAdventurePassChapterDir(dir)
local key = self:GetAdventurePassChapterIdSaveKey()
return XSaveTool.SaveData(key, dir)
end
function XTheatre3Activity:GetAdventureItemCount(itemId)
local result = 0
if XTool.IsTableEmpty(self.Items) then
return result
end
for _, itemData in ipairs(self.Items) do
if itemData.ItemId == itemId then
result = result + 1
end
end
return result
end
--endregion
--region 结算
function XTheatre3Activity:GetSettleData()
return self.Settle
end
function XTheatre3Activity:SignSettleTip()
if self.Settle then
self.Settle.IsNeedShowTip = false
end
end
function XTheatre3Activity:GetOldBpExp()
return self.TempTotalBattlePassExp
end
--endregion
return XTheatre3Activity