1812 lines
42 KiB
Lua
1812 lines
42 KiB
Lua
---@class UGCGameState_C:BP_UGCGameState_C
|
||
---@field DataTables TArray<UDataTable*>
|
||
--Edit Below--
|
||
UGCGameSystem.UGCRequire('Script.Common.ue_enum_custom')
|
||
UGCGameSystem.UGCRequire('Script.Common.ue_struct_custom')
|
||
UGCGameSystem.UGCRequire('Script.Global.Global')
|
||
|
||
local UGCGameState = {
|
||
|
||
IsRunOnServer = false,
|
||
|
||
--玩家数据列表
|
||
PlayerDataList = {},
|
||
|
||
--玩家难度选择
|
||
PlayerDifficultySelection = {
|
||
},
|
||
|
||
--游戏难度
|
||
GameDifficulty = 0,
|
||
|
||
--首领血量系数
|
||
BossHealthMultiplier = 1.0,
|
||
|
||
--怪物血量及攻击力系数
|
||
MonsterHealthAndAttackValueMultiplier = {
|
||
["Health"] = 1.0,
|
||
["Attack"] = 1.0,
|
||
},
|
||
|
||
--游戏是否胜利
|
||
GameIsWin = false,
|
||
|
||
--游戏开始时间
|
||
GameStartTimeStamp = 0,
|
||
|
||
--游戏结束时间
|
||
GameEndTimeStamp = 0,
|
||
|
||
--当前游戏时长
|
||
GameDuration = 0.0,
|
||
|
||
--是否应用初始角色属性
|
||
bHasApplyedAttribute = false,
|
||
|
||
--在场地中央的玩家们
|
||
PlayerPawnInArena = {},
|
||
|
||
--水晶
|
||
Crystal = nil,
|
||
|
||
--等待玩家进入剩余时间
|
||
WaitPlayerJoinTime = -1,
|
||
|
||
--游戏阶段
|
||
GameStage = -1,
|
||
|
||
--准备阶段各个状态
|
||
GameReadyStage = -1,
|
||
|
||
--准备阶段各个状态剩余时间
|
||
GameReadyStageRemainTime = -1,
|
||
|
||
--进攻波次是否存在
|
||
IsInAttackWave = false,
|
||
|
||
--总进攻波次
|
||
TotalAttackWave = -1,
|
||
|
||
--进攻波次
|
||
CurAttackWave = -1,
|
||
|
||
--战斗阶段各个波次剩余时间
|
||
GameFightStageRemainTime = -1,
|
||
|
||
--Item全局唯一ID
|
||
CurDropItemThisID = 1,
|
||
|
||
--掉落物全局表
|
||
GlobalDropItemActorList = {},
|
||
|
||
--根据玩家进行区分掉落物,除了玩家以外掉落的为 InArena: 0;玩家本身使用 PlayerKey
|
||
DropItemList = {
|
||
[0] = {},
|
||
};
|
||
|
||
--玩家伤害 {[PlayerKey] = {[BossID] = number} ... }
|
||
PlayerDamageList = {},
|
||
|
||
--首领列表
|
||
BossList = {},
|
||
|
||
--玩家伤害 {[PlayerKey] = {[Level] = number, [CurExp] = number}, ... }
|
||
PlayerLevelAndExpList = {},
|
||
|
||
--玩家战力值
|
||
PlayerCombatPointList = {},
|
||
|
||
-- 本局游戏玩家死亡次数 { PlayerKey: DieCount }
|
||
PlayerDieTimes = {},
|
||
|
||
-- 玩家重生数据 { Type: Value }
|
||
PlayerArchiveDatas = {},
|
||
|
||
-- 练功房物品数量上限
|
||
ExerciseRoomItemLimit = 50;
|
||
|
||
PlayerInitDatas = {};
|
||
|
||
GameResultData = {}; --游戏结算信息
|
||
};
|
||
|
||
require('Script.Manager.CommandQueneManager')
|
||
|
||
--设置同步的属性
|
||
function UGCGameState:GetReplicatedProperties()
|
||
return
|
||
"GameDuration",
|
||
"PlayerDataList",
|
||
"PlayerDifficultySelection",
|
||
"GameStage",
|
||
"WaitPlayerJoinTime",
|
||
"TotalAttackWave",
|
||
"CurAttackWave",
|
||
"IsInAttackWave",
|
||
"GameFightStageRemainTime",
|
||
{"GameResultData", "Lazy"},
|
||
{"GameReadyStage", "Lazy"},
|
||
"GameReadyStageRemainTime",
|
||
"PlayerDamageList",
|
||
{"BossList", "Lazy"},
|
||
"GameDifficulty",
|
||
"PlayerLevelAndExpList",
|
||
"PlayerCombatPointList",
|
||
"PlayerDieTimes"
|
||
end
|
||
|
||
function UGCGameState:GetAvailableServerRPCs()
|
||
return
|
||
-- "Client_MulticastRPC_ShowGeneralNoticeTips",
|
||
-- "Client_MulticastRPC_ShowNoticeTips",
|
||
-- "Client_MulticastRPC_SendEvent",
|
||
-- "Client_MulticastRPC_ShowPanel",
|
||
-- "Client_MulticastRPC_ClosePanel",
|
||
-- "Client_MulticastRPC_ShowCrystalAttackedByBoss",
|
||
|
||
---Sound
|
||
-- "Client_MulticastRPC_PlaySound2D",
|
||
-- "Client_MulticastRPC_PlaySoundAtLocation",
|
||
-- "Client_MulticastRPC_PlaySoundAttachActor",
|
||
-- "Client_MulticastRPC_StopAllSound",
|
||
-- "Client_MulticastRPC_StopSoundByActor",
|
||
-- "Client_MulticastRPC_StopSoundByID"
|
||
|
||
---Unpacking
|
||
-- "Client_RPC_UnpackingResults",
|
||
"Server_RPC_Unpacking"
|
||
end
|
||
|
||
function UGCGameState:ReceiveBeginPlay()
|
||
UGCGameSystem.UGCRequire('Script.Global.Global')
|
||
|
||
UGCGameState.SuperClass.ReceiveBeginPlay(self)
|
||
|
||
self.IsRunOnServer = UGCGameSystem.IsServer()
|
||
|
||
self.IsShowDeadBox = false
|
||
|
||
--游戏数据初始化
|
||
GameDataManager:Init()
|
||
|
||
if self:HasAuthority() == true then
|
||
EventSystem:AddListener(EventType.PlayerPawnInArenaChanged, UGCGameState.OnPlayerPawnInArenaChanged, self)
|
||
EventSystem:AddListener(EventType.SpawnDropItem, UGCGameState.SpawnDropItem, self)
|
||
EventSystem:AddListener(EventType.SpawnDropItemByID, UGCGameState.SpawnDropItemByID, self)
|
||
EventSystem:AddListener(EventType.ServerOnLevelAndExpChanged, UGCGameState.OnPlayerLevelAndExpChanged, self)
|
||
EventSystem:AddListener(EventType.ServerOnCombatPointChanged, UGCGameState.OnCombatPointChanged, self)
|
||
|
||
GameEndManager:Init()
|
||
else
|
||
--预加载资源
|
||
AsyncLoadTools:Init()
|
||
|
||
local CommandManager = require('Script.Manager.CommandQueneManager')
|
||
CommandManager:AddInitCommand(self, self.Client_Init)
|
||
end
|
||
end
|
||
|
||
function UGCGameState:ReceiveEndPlay()
|
||
if self:HasAuthority() == true then
|
||
EventSystem:RemoveListener(EventType.SpawnDropItemByID, UGCGameState.SpawnDropItemByID, self)
|
||
EventSystem:RemoveListener(EventType.SpawnDropItem, UGCGameState.SpawnDropItem, self)
|
||
EventSystem:RemoveListener(EventType.PlayerPawnInArenaChanged, UGCGameState.OnPlayerPawnInArenaChanged, self)
|
||
EventSystem:RemoveListener(EventType.ServerOnLevelAndExpChanged, UGCGameState.OnPlayerLevelAndExpChanged, self)
|
||
EventSystem:RemoveListener(EventType.ServerOnCombatPointChanged, UGCGameState.OnCombatPointChanged, self)
|
||
|
||
else
|
||
AsyncLoadTools:UnInit()
|
||
|
||
if NewPlayerGuideManager then
|
||
NewPlayerGuideManager:UnInit()
|
||
end
|
||
end
|
||
|
||
GameDataManager:UnInit()
|
||
|
||
UGCGameState.SuperClass.ReceiveEndPlay(self)
|
||
end
|
||
|
||
function UGCGameState:ReceiveTick(DeltaTime)
|
||
UGCGameState.SuperClass.ReceiveTick(self, DeltaTime)
|
||
|
||
if not self.IsRunOnServer then
|
||
if self.bHasInitClient == nil then
|
||
CommandQueneManager.bGameStateReady = true
|
||
self.bHasInitClient = true
|
||
UE.Log("[UGCGameState] *** UGCGameState Tick Init Ready")
|
||
end
|
||
CommandQueneManager:Update()
|
||
else
|
||
end
|
||
end
|
||
|
||
function UGCGameState:Client_Init()
|
||
self:OnRep_BossList()
|
||
self:OnRep_PlayerDamageList()
|
||
self:OnRep_GameStage()
|
||
self:OnRep_PlayerLevelAndExpList()
|
||
self:OnRep_PlayerCombatPointList()
|
||
end
|
||
|
||
-- 使用默认属性
|
||
function UGCGameState:ApplyDefaultAttributes()
|
||
local AllPlayerStates = UGCGameSystem.GetAllPlayerState(false)
|
||
for _, PlayerState in pairs(AllPlayerStates) do
|
||
-- 将属性设置到PlayerState
|
||
local Temp = {}
|
||
|
||
for i = 0, AttributeType.WeaponSpecial do
|
||
local Attribute = {}
|
||
for j, v in pairs(GlobalConfigs.Attributes) do
|
||
if i == 0 then
|
||
Attribute[j] = v.Value
|
||
else
|
||
Attribute[j] = 0
|
||
end
|
||
end
|
||
Temp[i] = Attribute
|
||
end
|
||
|
||
PlayerState.Attributes = Temp
|
||
|
||
-- 在初始化属性结束后(GameState:ApplyDefaultAttributes())进行玩家存档属性的初始化
|
||
PlayerState:InitData()
|
||
PlayerState:ApplyAttributes()
|
||
end
|
||
self.bHasApplyedAttribute = true
|
||
end
|
||
|
||
-- 进行通知应用玩家属性
|
||
function UGCGameState:ApplyPlayerWeaponAttributes(InPlayerKey)
|
||
-- 找到对应 PlayerState
|
||
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(InPlayerKey)
|
||
PlayerState:ApplyAttributes()
|
||
end
|
||
|
||
function UGCGameState:CheckAllPlayersGameDifficultySelection()
|
||
local ValidVoteInfo = {}
|
||
if table.getCount(self.PlayerDifficultySelection) > 0 then
|
||
for Index, VoteNum in pairs(self.PlayerDifficultySelection) do
|
||
if VoteNum > 0 then
|
||
table.insert(ValidVoteInfo, { VoteType = Index, VoteNum = VoteNum })
|
||
end
|
||
end
|
||
end
|
||
|
||
if table.getCount(ValidVoteInfo) > 0 then
|
||
--有效投票(有人投票)
|
||
table.sort(ValidVoteInfo,
|
||
function(a, b)
|
||
if a.VoteNum > b.VoteNum then
|
||
return true
|
||
elseif a.VoteNum == b.VoteNum then
|
||
return a.VoteType > b.VoteType
|
||
else
|
||
return false
|
||
end
|
||
end)
|
||
for _, v in pairs(ValidVoteInfo) do
|
||
UE.Log("[UGCGameState:CheckAllPlayersGameDifficultySelection] VoteIndex = %s, VoteNum = %d", v.VoteType, v.VoteNum)
|
||
end
|
||
|
||
if table.getCount(ValidVoteInfo) > 0 then
|
||
for index, v in pairs(ValidVoteInfo) do
|
||
--self.GameDifficulty = GlobalConfigs.GameDifficulty[v.VoteType]
|
||
self.GameDifficulty = v.VoteType
|
||
break
|
||
end
|
||
else
|
||
self.GameDifficulty = 1
|
||
end
|
||
|
||
else
|
||
--无有效投票(所有人都没投票)则固定难度1
|
||
self.GameDifficulty = 1
|
||
end
|
||
|
||
if self.GameDifficulty <= 0 then
|
||
NoticeTipsTools.MulticastGeneralNoticeTips("游戏难度配置错误,请检查逻辑,游戏终止", true, 4.0)
|
||
return
|
||
end
|
||
|
||
UE.Log("[UGCGameState:CheckAllPlayersGameDifficultySelection] GameDifficulty = "..tostring(self.GameDifficulty))
|
||
NoticeTipsTools.MulticastGeneralNoticeTips("游戏难度:难"..tostring(self.GameDifficulty))
|
||
|
||
local FightStageConfig = Tables.GameFightStageConfig[math.clamp(self.GameDifficulty, 1, 4)]
|
||
self.TotalAttackWave = table.getCount(FightStageConfig)
|
||
UE.Log("[UGCGameState:CheckAllPlayersGameDifficultySelection] TotalAttackWave = %d", self.TotalAttackWave)
|
||
|
||
local BossTotaNum = 0
|
||
for _, Config in pairs(FightStageConfig) do
|
||
BossTotaNum = BossTotaNum + Config.MonsterNum.Boss
|
||
end
|
||
|
||
-- Boss难度表
|
||
local BossSort = {
|
||
{ ID = 10001, Diff = 3 },
|
||
{ ID = 10002, Diff = 4 },
|
||
{ ID = 10003, Diff = 2 },
|
||
{ ID = 10004, Diff = 9 },
|
||
{ ID = 10005, Diff = 1 },
|
||
{ ID = 10006, Diff = 10 },
|
||
};
|
||
|
||
table.sort(BossSort, function(a, b)
|
||
return a.Diff < b.Diff;
|
||
end)
|
||
|
||
for i = 1, BossTotaNum do
|
||
local BossInfo = nil
|
||
if i <= 2 then
|
||
BossInfo = table.remove(BossSort, math.random(1, #BossSort - 2));
|
||
else
|
||
BossInfo = table.remove(BossSort, math.random(1, #BossSort))
|
||
end
|
||
if BossInfo then
|
||
table.insert(self.BossList, BossInfo.ID)
|
||
end
|
||
end
|
||
|
||
UnrealNetwork.RepLazyProperty(self, "BossList")
|
||
|
||
local AllPlayerStates = UGCGameSystem.GetAllPlayerState(false)
|
||
for _, PlayerState in pairs(AllPlayerStates) do
|
||
self.PlayerDamageList[PlayerState.PlayerKey] = {}
|
||
for _, BossID in pairs(self.BossList) do
|
||
self.PlayerDamageList[PlayerState.PlayerKey][BossID] = 0.0
|
||
end
|
||
end
|
||
|
||
end
|
||
|
||
function UGCGameState:CheckAllPlayersDefaultWeaponSelection()
|
||
local AllPlayerStates = UGCGameSystem.GetAllPlayerState(false)
|
||
for _, PlayerState in pairs(AllPlayerStates) do
|
||
local InPlayerKey = PlayerState.PlayerKey
|
||
if table.getCount(PlayerState.OwnerWeapons) <= 0 then
|
||
-- 设置初始武器
|
||
local PlayerController = UGCGameSystem.GetPlayerControllerByPlayerKey(InPlayerKey)
|
||
PlayerController:ServerRPC_SelectDefaultWeapon(101) ---配置默认武器R1895
|
||
end
|
||
end
|
||
end
|
||
|
||
function UGCGameState:CheckAllPlayersDefaultTelentSelection()
|
||
local AllPlayerController = UGCGameSystem.GetAllPlayerController(false)
|
||
for _, PC in pairs(AllPlayerController) do
|
||
local InPlayerKey = PC.PlayerKey
|
||
if next(PC.ActiveSkillNameList) == nil then
|
||
PC:GiveSkillList({ESkillName.Heal, ESkillName.Dash})
|
||
NoticeTipsTools.ServerGeneralNoticeTips(InPlayerKey, "已选择默认天赋技能:冲刺")
|
||
else
|
||
PC:GiveSkill(ESkillName.Heal)
|
||
end
|
||
end
|
||
|
||
NoticeTipsTools.MulticastGeneralNoticeTips("所有玩家已准备完毕,练功房激活! 等待进攻波次开始!", false, 8.0)
|
||
end
|
||
|
||
function UGCGameState:GetGameDuration()
|
||
return math.ceil(self.GameEndTimeStamp - self.GameStartTimeStamp)
|
||
end
|
||
|
||
function UGCGameState:SetIsGameWin(IsWin)
|
||
self.GameIsWin = IsWin
|
||
end
|
||
|
||
function UGCGameState:GetIsGameWin()
|
||
return self.GameIsWin
|
||
end
|
||
|
||
function UGCGameState:GetCrystal()
|
||
if self.Crystal == nil or UE.IsValid(self.Crystal) == false then
|
||
local CrystalClass = UE.LoadClass(BPClassPath.Crystal)
|
||
local Crystals = GameplayStatics.GetAllActorsOfClass(self, CrystalClass, {})
|
||
local Crystal = Crystals[1]
|
||
self.Crystal = Crystal
|
||
end
|
||
return self.Crystal
|
||
end
|
||
|
||
function UGCGameState:GetAttackWaveSpawner()
|
||
if self.AttackWaveSpawner == nil or UE.IsValid(self.AttackWaveSpawner) == false then
|
||
local SpawnerClass = UE.LoadClass(BPClassPath.MonsterSpawner)
|
||
local Spawners = GameplayStatics.GetAllActorsOfClass(self, SpawnerClass, {})
|
||
for _, Spawner in pairs(Spawners) do
|
||
if Spawner.Type == EMonsterSpawnerType.AttackWave then
|
||
self.AttackWaveSpawner = Spawner
|
||
break
|
||
end
|
||
end
|
||
end
|
||
return self.AttackWaveSpawner
|
||
end
|
||
|
||
function UGCGameState:GetAllHangUpRoomSpawners()
|
||
if self.HangUpRoomSpawners == nil then
|
||
self.HangUpRoomSpawners = {}
|
||
local Spawners = GameplayStatics.GetAllActorsOfClass(self, UE.LoadClass(BPClassPath.MonsterSpawner), {})
|
||
for _, Spawner in pairs(Spawners) do
|
||
if Spawner.Type == EMonsterSpawnerType.HangUpRoom then
|
||
self.HangUpRoomSpawners[Spawner.TargetPlayerKey] = Spawner
|
||
end
|
||
end
|
||
end
|
||
return self.HangUpRoomSpawners
|
||
end
|
||
|
||
function UGCGameState:GetAllSpawners()
|
||
local AttackWaveSpawner = self:GetAttackWaveSpawner()
|
||
local HangUpRoomSpawners = self:GetAllHangUpRoomSpawners()
|
||
|
||
local AllSpawners = {}
|
||
table.insert(AllSpawners, AttackWaveSpawner)
|
||
for _, Spawner in pairs(HangUpRoomSpawners) do
|
||
table.insert(AllSpawners, Spawner)
|
||
end
|
||
return AllSpawners
|
||
end
|
||
|
||
function UGCGameState:GetSpawnerByPlayerKey(InPlayerKey)
|
||
if self.HangUpRoomSpawners == nil then
|
||
self.HangUpRoomSpawners = {}
|
||
local Spawners = GameplayStatics.GetAllActorsOfClass(self, UE.LoadClass(BPClassPath.MonsterSpawner), {})
|
||
for _, Spawner in pairs(Spawners) do
|
||
if Spawner.Type == EMonsterSpawnerType.HangUpRoom then
|
||
self.HangUpRoomSpawners[Spawner.TargetPlayerKey] = Spawner
|
||
end
|
||
end
|
||
end
|
||
return self.HangUpRoomSpawners[InPlayerKey]
|
||
end
|
||
|
||
function UGCGameState:GetAllTeleporters()
|
||
if self.Teleporters == nil then
|
||
self.Teleporters = {}
|
||
local Teleporters = GameplayStatics.GetAllActorsOfClass(self, UE.LoadClass(BPClassPath.Teleporter), {})
|
||
for _, Teleporter in pairs(Teleporters) do
|
||
table.insert(self.Teleporters, Teleporter)
|
||
end
|
||
end
|
||
return self.Teleporters
|
||
end
|
||
|
||
function UGCGameState:GetAllPlayerStarts()
|
||
if self.PlayerStarts == nil then
|
||
self.PlayerStarts = {}
|
||
self.PlayerStarts[ETeleportType.InArena] = {}
|
||
self.PlayerStarts[ETeleportType.InHangupRoom] = {}
|
||
local AllPlayerStarts = GameplayStatics.GetAllActorsOfClass(self, UE.LoadClass(BPClassPath.PlayerStart), {})
|
||
print(string.format('[UGCGameState:GetAllPlayerStarts] 一共有%d个 PlayerStart', table.getCount(AllPlayerStarts)))
|
||
for _, PlayerStart in pairs(AllPlayerStarts) do
|
||
|
||
table.insert(self.PlayerStarts[PlayerStart:GetType()], PlayerStart)
|
||
end
|
||
end
|
||
return self.PlayerStarts
|
||
end
|
||
|
||
function UGCGameState:GetPlayersInArena()
|
||
return self.PlayerPawnInArena
|
||
end
|
||
|
||
function UGCGameState:OnPlayerPawnInArenaChanged(InRangePlayerPawn)
|
||
self.PlayerPawnInArena = InRangePlayerPawn
|
||
end
|
||
|
||
function UGCGameState:OnPlayerLevelAndExpChanged(PlayerKey, InLevel, InCurExp, InTotalExp)
|
||
if self.PlayerLevelAndExpList[PlayerKey] == nil then
|
||
self.PlayerLevelAndExpList[PlayerKey] = {}
|
||
end
|
||
self.PlayerLevelAndExpList[PlayerKey] = {Level = InLevel, CurExp = InCurExp, TotalExp = InTotalExp}
|
||
end
|
||
|
||
function UGCGameState:OnCombatPointChanged(PlayerKey, CombatPoint)
|
||
self.PlayerCombatPointList[PlayerKey] = CombatPoint
|
||
end
|
||
|
||
-- 生成一个掉落物
|
||
function UGCGameState:SpawnDropItem(InLoc, InRot, InPlayerKey, InData)
|
||
local ItemData
|
||
if InData == nil then
|
||
ItemData = GenerateDropItemData()
|
||
else
|
||
ItemData = InData
|
||
end
|
||
|
||
if InPlayerKey ~= nil then
|
||
-- 判断是否生成在 InArena:如果玩家此时在场内,说明就生成在场内
|
||
local ThePawn = UGCGameSystem.GetPlayerPawnByPlayerKey(InPlayerKey)
|
||
if ThePawn then
|
||
if not ThePawn.IsInArena then
|
||
-- 说明在场内
|
||
self:SpawnDropItem_ExerciseRoom(InLoc, InRot, InPlayerKey, ItemData)
|
||
--self.DropItemList[0][self.CurDropItemThisID] = DropItemActor;
|
||
else
|
||
self:SpawnDropItem_InArena(InLoc, InRot, InPlayerKey, ItemData)
|
||
--if self.DropItemList[InPlayerKey] == nil then
|
||
-- self.DropItemList[InPlayerKey] = {}
|
||
--end
|
||
---- 添加到数组中,可以设置为当玩家在练功房的时候自动拾取里面的所有东西
|
||
--self.DropItemList[InPlayerKey][self.CurDropItemThisID] = DropItemActor;
|
||
end
|
||
else
|
||
print(string.format('[UGCGameState:SpawnDropItem] 无法找到当前玩家'))
|
||
end
|
||
return
|
||
end
|
||
end
|
||
|
||
function UGCGameState:SpawnDropItem_InArena(InLoc, InRot, InPlayerKey, InData)
|
||
local ItemBaseClass = UE.LoadClass(BPClassPath.PickupItemClass)
|
||
local Location = self:GetDropLocation(InLoc)
|
||
local Scale = VectorHelper.ScaleOne()
|
||
|
||
--此处生成了一个具体的 Item
|
||
local DropItemActor = UGCGameSystem.SpawnActor(
|
||
self,
|
||
ItemBaseClass,
|
||
Location,
|
||
InRot,
|
||
Scale,
|
||
self
|
||
)
|
||
|
||
if DropItemActor then
|
||
DropItemActor:SetPickItemData(string.format("%d;%d", InData.ItemID, InData.Count))
|
||
DropItemActor:SetThisID(self.CurDropItemThisID)
|
||
|
||
self.GlobalDropItemActorList[self.CurDropItemThisID] = DropItemActor
|
||
self.CurDropItemThisID = self.CurDropItemThisID + 1
|
||
end
|
||
end
|
||
|
||
function UGCGameState:SpawnDropItem_ExerciseRoom(InLoc, InRot, InPlayerKey, InData)
|
||
-- 判断场景中的物品数量是否超过指定数量
|
||
if not self:CanExerciseCreateDropItem(InPlayerKey) then
|
||
return
|
||
end
|
||
log_tree('InData = ', InData)
|
||
-- 加入到数组中,场景中的不加入
|
||
if self.DropItemList[InPlayerKey] == nil then
|
||
self.DropItemList[InPlayerKey] = {}
|
||
end
|
||
if self.DropItemList[InPlayerKey][InData.ItemID] == nil then
|
||
self.DropItemList[InPlayerKey][InData.ItemID] = InData.Count
|
||
else
|
||
self.DropItemList[InPlayerKey][InData.ItemID] = self.DropItemList[InPlayerKey][InData.ItemID] + InData.Count
|
||
end
|
||
log_tree("DropItemList", self.DropItemList)
|
||
-- 发送 RPC 通知客户端创建东西
|
||
local PC = UGCGameSystem.GetPlayerControllerByPlayerKey(InPlayerKey)
|
||
InLoc = self:GetDropLocation(InLoc)
|
||
PC:RequestExerciseDropItem(InPlayerKey, InLoc, InRot, InData, true)
|
||
end
|
||
|
||
--是否可以在练功房创建掉落物
|
||
function UGCGameState:CanExerciseCreateDropItem(InPlayerKey)
|
||
if self.DropItemList[InPlayerKey] ~= nil then
|
||
-- i: ItemID, v: ItemCount
|
||
local TotalCount = 0
|
||
for i, v in pairs(self.DropItemList[InPlayerKey]) do
|
||
TotalCount = TotalCount + v;
|
||
end
|
||
return self.ExerciseRoomItemLimit > TotalCount;
|
||
else
|
||
return true;
|
||
end
|
||
end
|
||
|
||
--玩家丢弃的时候生成
|
||
function UGCGameState:SpawnDropItemByID(InItemID, InCount, InLoc, InRot, InPlayerKey, IsFromDiscard)
|
||
UE.Log("[UGCGameState:SpawnDropItemByID] 开始执行")
|
||
local ItemBaseClass = UE.LoadClass(BPClassPath.PickupItemClass)
|
||
local Location = self:GetDropLocation(InLoc)
|
||
local Rotation = InRot
|
||
local Scale = VectorHelper.ScaleOne()
|
||
local DropItemActor = UGCGameSystem.SpawnActor(
|
||
self,
|
||
ItemBaseClass,
|
||
Location,
|
||
Rotation,
|
||
Scale,
|
||
self
|
||
)
|
||
|
||
if DropItemActor then
|
||
UE.Log("[UGCGameState:SpawnDropItemByID] 执行掉落方法")
|
||
UE.Log("{ItemID类型是 = %s, Count = %s}", type(InItemID), type(InCount))
|
||
|
||
DropItemActor:SetPickItemData(string.format("%d;%d", InItemID, InCount))
|
||
DropItemActor:SetThisID(self.CurDropItemThisID)
|
||
if IsFromDiscard then
|
||
DropItemActor:SetAutoPickupDisabled(InPlayerKey)
|
||
end
|
||
|
||
self.GlobalDropItemActorList[self.CurDropItemThisID] = DropItemActor
|
||
self.CurDropItemThisID = self.CurDropItemThisID + 1
|
||
end
|
||
UE.Log("[UGCGameState:SpawnDropItemByID] 执行完成")
|
||
end
|
||
|
||
function UGCGameState:GetDropLocation(InStartLocation)
|
||
local StartPos = VectorHelper.Add(InStartLocation, {X=0,Y=0,Z=50})
|
||
local EndPos = VectorHelper.Sub(InStartLocation, {X=0,Y=0,Z=500})
|
||
local ObjectTypes = {EObjectTypeQuery.ObjectTypeQuery1}
|
||
local AllWeapons = GameplayStatics.GetAllActorsOfClass(self, UE.LoadClass(BPClassPath.Weapon), {})
|
||
local bHit, HitResult = KismetSystemLibrary.LineTraceSingleForObjects(self, StartPos, EndPos, ObjectTypes, false, AllWeapons, EDrawDebugTrace.None, nil, true, nil,nil, nil)
|
||
local DropPos = {}
|
||
if bHit then
|
||
DropPos = HitResult.ImpactPoint
|
||
else
|
||
DropPos = InStartLocation
|
||
end
|
||
return DropPos
|
||
end
|
||
|
||
--S
|
||
function UGCGameState:UpdatePlayerDamage(InPlayerKey, InBossID, InDeltaDamage)
|
||
if self.PlayerDamageList[InPlayerKey] == nil then
|
||
self.PlayerDamageList[InPlayerKey] = {}
|
||
end
|
||
if self.PlayerDamageList[InPlayerKey][InBossID] == nil then
|
||
self.PlayerDamageList[InPlayerKey][InBossID] = 0
|
||
end
|
||
local CurDamage = self.PlayerDamageList[InPlayerKey][InBossID]
|
||
self.PlayerDamageList[InPlayerKey][InBossID] = CurDamage + InDeltaDamage
|
||
end
|
||
|
||
--S
|
||
function UGCGameState:UpdateIsInAttackWave(bNewIsInAttackWave)
|
||
if self.IsInAttackWave ~= bNewIsInAttackWave then
|
||
self.IsInAttackWave = bNewIsInAttackWave
|
||
EventSystem:SendEvent(EventType.OnIsInAttackWaveChanged, self.IsInAttackWave)
|
||
if bNewIsInAttackWave == false then
|
||
-- 提示当前过3秒传回练功房
|
||
EventSystem.SetTimer(self, function()
|
||
-- 发送到练功房
|
||
EventSystem:SendEvent(EventType.SendPlayersToExercise)
|
||
end, 3)
|
||
end
|
||
end
|
||
end
|
||
|
||
function UGCGameState:GetAllPlayerLevel()
|
||
local LevelTable = {}
|
||
for PlayerKey, Info in pairs(self.PlayerLevelAndExpList) do
|
||
LevelTable[PlayerKey] = Info.Level
|
||
end
|
||
return LevelTable
|
||
end
|
||
|
||
function UGCGameState:GetAllPlayerExp()
|
||
local ExpTable = {}
|
||
for PlayerKey, Info in pairs(self.PlayerLevelAndExpList) do
|
||
ExpTable[PlayerKey] = {CurExp = Info.CurExp, TotalExp = Info.TotalExp}
|
||
end
|
||
return ExpTable
|
||
end
|
||
|
||
function UGCGameState:OnRep_PlayerDataList()
|
||
for k,v in pairs(self.PlayerDataList) do
|
||
UE.Log("[UGCGameState:OnRep_PlayerDataList] PlayerKey = "..tostring(v.PlayerKey).." PlayerName = "..v.PlayerName)
|
||
end
|
||
|
||
EventSystem:SendEvent(EventType.PlayerDataListChanged, self.PlayerDataList)
|
||
end
|
||
|
||
function UGCGameState:OnRep_PlayerDifficultySelection()
|
||
if table.getCount(self.PlayerDifficultySelection) > 0 then
|
||
for k, v in pairs(self.PlayerDifficultySelection) do
|
||
UE.Log("[UGCGameState:OnRep_PlayerDifficultySelection] key = %s, value = %d", tostring(k), v)
|
||
end
|
||
end
|
||
|
||
EventSystem:SendEvent(EventType.PlayerDifficultySelectionChanged, self.PlayerDifficultySelection)
|
||
end
|
||
|
||
function UGCGameState:OnRep_WaitPlayerJoinTime()
|
||
UE.Log("[UGCGameState:OnRep_WaitPlayerJoinTime] WaitPlayerJoinTime = %d", self.WaitPlayerJoinTime)
|
||
|
||
EventSystem:SendEvent(EventType.OnWaitPlayerJoinTimeChanged, self.WaitPlayerJoinTime)
|
||
end
|
||
|
||
function UGCGameState:OnRep_GameStage()
|
||
UE.Log("[UGCGameState:OnRep_GameStage] GameStage = %d", self.GameStage)
|
||
|
||
EventSystem:SendEvent(EventType.OnGameStageChanged, self.GameStage);
|
||
end
|
||
|
||
function UGCGameState:OnRep_GameReadyStage()
|
||
UE.Log("[UGCGameState:OnRep_GameReadyStage] GameReadyStage = %s", tostring(self.GameReadyStage))
|
||
|
||
-- 这里只发了一次
|
||
if UIManager and UIManager.HasInitialized then
|
||
if self.GameReadyStage >= 0 then
|
||
for _, Config in pairs(Tables.GameReadyStageConfig) do
|
||
if Config.Stage == self.GameReadyStage then
|
||
local TriggerUI = Config.TriggerUI
|
||
UIManager:ShowPanel(TriggerUI)
|
||
break
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function UGCGameState:OnRep_GameReadyStageRemainTime()
|
||
UE.Log("[UGCGameState:OnRep_GameReadyStageRemainTime] GameReadyStageRemainTime = %s", tostring(self.GameReadyStageRemainTime))
|
||
|
||
EventSystem:SendEvent(EventType.OnGameReadyStageRemainTimeChanged, self.GameReadyStageRemainTime)
|
||
end
|
||
|
||
function UGCGameState:OnRep_CurAttackWave()
|
||
UE.Log("[UGCGameState:OnRep_CurAttackWave] CurAttackWave = %s", tostring(self.CurAttackWave))
|
||
|
||
EventSystem:SendEvent(EventType.OnCurAttackWaveChanged, self.CurAttackWave, self.TotalAttackWave)
|
||
|
||
if self.CurAttackWave > 0 and self.TotalAttackWave > 0 and UIManager then
|
||
UIManager:ShowNotice(ECustomNoticeType.GeneralNotice, string.format("第%d波进攻开始", self.CurAttackWave), false, 3.0)
|
||
UIManager:ShowNotice(ECustomNoticeType.AttackWaveNotice, self.CurAttackWave, self.TotalAttackWave)
|
||
end
|
||
end
|
||
|
||
function UGCGameState:OnRep_IsInAttackWave()
|
||
UE.Log("[UGCGameState:OnRep_IsInAttackWave] IsInAttackWave = %s", tostring(self.IsInAttackWave))
|
||
|
||
EventSystem:SendEvent(EventType.OnIsInAttackWaveChanged, self.IsInAttackWave)
|
||
|
||
if self.GameStage >= EGameStage.GameFight then
|
||
for _, Teleporter in pairs(self:GetAllTeleporters()) do
|
||
if self.IsInAttackWave == false then
|
||
Teleporter:SetRingColor(Teleporter.Type == ETeleportType.InHangupRoom)
|
||
else
|
||
Teleporter:SetRingColor(Teleporter.Type == ETeleportType.InArena)
|
||
end
|
||
end
|
||
end
|
||
|
||
if self.GameStage == EGameStage.GameFight and self.IsInAttackWave == false then
|
||
UIManager:ShowNotice(ECustomNoticeType.GeneralNotice, "进攻波次已清理完毕,可回到练功房继续提升等级", false, 3.0)
|
||
end
|
||
end
|
||
|
||
function UGCGameState:OnRep_GameFightStageRemainTime()
|
||
UE.Log("[UGCGameState:OnRep_GameFightStageRemainTime] GameFightStageRemainTime = %s", tostring(self.GameFightStageRemainTime))
|
||
|
||
EventSystem:SendEvent(EventType.OnGameFightStageRemainTimeChanged, self.GameFightStageRemainTime)
|
||
|
||
if self.GameFightStageRemainTime > 5 then
|
||
self.bHasNoticedAttackWave = false
|
||
end
|
||
|
||
if UIManager and UIManager.HasInitialized then
|
||
if self.GameFightStageRemainTime >= 0 then
|
||
UIManager:ShowNotice(ECustomNoticeType.AttackWaveRemainTimeNotice, self.GameFightStageRemainTime)
|
||
end
|
||
if self.GameFightStageRemainTime <= 5 and not self.bHasNoticedAttackWave then
|
||
UIManager:ShowNotice(ECustomNoticeType.CountDownNotice, "怪物进攻倒计时", self.GameFightStageRemainTime, true)
|
||
self.bHasNoticedAttackWave = true
|
||
end
|
||
end
|
||
end
|
||
|
||
function UGCGameState:OnRep_PlayerDamageList()
|
||
log_tree("[OnRep_PlayerDamageList] PlayerDamageList = ", self.PlayerDamageList)
|
||
|
||
EventSystem:SendEvent(EventType.OnPlayerDamageChanged, self.PlayerDamageList)
|
||
end
|
||
|
||
function UGCGameState:OnRep_BossList()
|
||
log_tree_dev("[OnRep_BossList] BossList = ", self.BossList)
|
||
EventSystem:SendEvent(EventType.ChangeBossList, self.BossList)
|
||
end
|
||
|
||
function UGCGameState:OnRep_PlayerLevelAndExpList()
|
||
local LevelTable = {}
|
||
local ExpTable = {}
|
||
for PlayerKey, Info in pairs(self.PlayerLevelAndExpList) do
|
||
LevelTable[PlayerKey] = Info.Level
|
||
ExpTable[PlayerKey] = Info.CurExp
|
||
end
|
||
EventSystem:SendEvent(EventType.OnPlayerLevelChanged, self:GetAllPlayerLevel())
|
||
EventSystem:SendEvent(EventType.OnPlayerExpChanged, self:GetAllPlayerExp())
|
||
end
|
||
|
||
function UGCGameState:OnRep_PlayerCombatPointList()
|
||
EventSystem:SendEvent(EventType.OnPlayerCombatPointChanged, self.PlayerCombatPointList)
|
||
end
|
||
|
||
function UGCGameState:OnRep_GameDuration()
|
||
EventSystem:SendEvent(EventType.OnGameDurationChanged, self.GameDuration)
|
||
end
|
||
|
||
--------------------------------------------RPC--------------------------------------------
|
||
|
||
function UGCGameState:Client_MulticastRPC_ShowGeneralNoticeTips(InText, ShowAlert, ShowTime)
|
||
if self:HasAuthority() then return end
|
||
|
||
UIManager:ShowGeneralNotice(InText, ShowAlert, ShowTime)
|
||
end
|
||
|
||
function UGCGameState:Client_MulticastRPC_ShowNoticeTips(InNoticeType, ...)
|
||
if self:HasAuthority() then return end
|
||
|
||
UIManager:ShowNotice(InNoticeType, ...)
|
||
end
|
||
|
||
function UGCGameState:Client_MulticastRPC_SendEvent(InEventType, ...)
|
||
if self:HasAuthority() then return end
|
||
|
||
EventSystem:SendEvent(InEventType, ...)
|
||
end
|
||
|
||
function UGCGameState:Client_MulticastRPC_ShowPanel(InUIType, ...)
|
||
if self:HasAuthority() then return end
|
||
|
||
EventSystem:SendEvent(EventType.RequestShowPanel, InUIType, ...)
|
||
end
|
||
|
||
function UGCGameState:Client_MulticastRPC_ClosePanel(InUIType)
|
||
if self:HasAuthority() then return end
|
||
UIManager:ClosePanel(EUIType.DifficultInfo)
|
||
EventSystem:SendEvent(EventType.RequestClosePanel, InUIType)
|
||
end
|
||
|
||
function UGCGameState:Client_MulticastRPC_ShowCrystalAttackedByBoss()
|
||
if self:HasAuthority() then return end
|
||
|
||
local Crystal = self:GetCrystal()
|
||
Crystal.NarrationWidget.Widget:UpdateNarrationText("来看看是哪来的小东西,是在帮我挠痒痒吗?")
|
||
end
|
||
|
||
function UGCGameState:Server_RPC_Unpacking(PlayerKey, UnpackingLevel, InTimes)
|
||
local TargetPlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(PlayerKey)
|
||
local Val = Tables.Unpacking.LevelCoinPoint[UnpackingLevel].CoinPoint1
|
||
if InTimes == 10 then
|
||
Val = Tables.Unpacking.LevelCoinPoint[UnpackingLevel].CoinPoint10
|
||
end
|
||
local Func = function(InValue)
|
||
if InValue > 0 then
|
||
InValue = -InValue
|
||
end
|
||
InValue = math.clamp(InValue, -1, 0)
|
||
return InValue
|
||
end
|
||
-- 计算开箱所需金币
|
||
local Temp, Temp1, Temp2, Temp3 = 0, 0, 0, 0
|
||
for i, v in pairs(TargetPlayerState.Attributes) do
|
||
Temp = Temp + v.Unpacking_Cost
|
||
Temp1 = Temp1 + v.Primary_Raffle_Cost
|
||
Temp2 = Temp2 + v.Middle_Raffle_Cost
|
||
Temp3 = Temp3 + v.Senior_Raffle_Cost
|
||
end
|
||
|
||
local Func1 = function(TheTime, InPlayerState, Num)
|
||
if TheTime == 10 then
|
||
if InPlayerState.EasterEggsData[Num] == nil then
|
||
InPlayerState.EasterEggsData[Num] = 1
|
||
else
|
||
InPlayerState.EasterEggsData[Num] = InPlayerState.EasterEggsData[Num] + 1
|
||
end
|
||
-- 比较一下
|
||
ArchiveTable.Funcs[ArchiveTable.ArchiveType.EasterEggs](InPlayerState, Num)
|
||
end
|
||
end
|
||
|
||
local Val1 = 0
|
||
if UnpackingLevel == 1 then
|
||
Val1 = Temp1
|
||
elseif UnpackingLevel == 2 then
|
||
Val1 = Temp2
|
||
elseif UnpackingLevel == 3 then
|
||
Val1 = Temp3
|
||
end
|
||
|
||
Val = Val * (1 + Temp) * (1 + Val1)
|
||
if TargetPlayerState.CoinPoint.Current > Val then
|
||
-- 可以扣金币
|
||
local UnpackingResults = {}
|
||
for i = 1, InTimes do
|
||
local UnpackingResult = self:Unpacking(PlayerKey, UnpackingLevel)
|
||
table.insert(UnpackingResults, {Name = UnpackingResult.Name, UnpackingLevel = UnpackingResult.UnpackingLevel})
|
||
end
|
||
|
||
TargetPlayerState:UpdateCoinPoint(- Val)
|
||
|
||
if UnpackingLevel == 1 then
|
||
Func1(InTimes, TargetPlayerState, 13)
|
||
elseif UnpackingLevel == 2 then
|
||
Func1(InTimes, TargetPlayerState, 12)
|
||
elseif UnpackingLevel == 3 then
|
||
Func1(InTimes, TargetPlayerState, 11)
|
||
end
|
||
|
||
local TargetPawn = ScriptGameplayStatics.GetPlayerPawnByPlayerKey(self, PlayerKey)
|
||
local TargetController = TargetPawn:GetController()
|
||
|
||
TargetPlayerState.ArchiveData.TotalUnpackTimes = TargetPlayerState.ArchiveData.TotalUnpackTimes + InTimes;
|
||
|
||
--
|
||
--local CurItemMap = TargetController:GetItemMap()
|
||
--UnrealNetwork.CallUnrealRPC(TargetController, TargetController, "ClientRPC_UpdateBackpackItemMap", CurItemMap)
|
||
UnrealNetwork.CallUnrealRPC(TargetController, self, "Client_RPC_UnpackingResults", PlayerKey, UnpackingResults)
|
||
else
|
||
UE.LogError("[UGCGameState:Server_RPC_Unpacking] 金币不足")
|
||
end
|
||
end
|
||
|
||
function UGCGameState:Client_RPC_UnpackingResults(PlayerKey, UnpackingResults)
|
||
EventSystem:SendEvent(EventType.UnpackingResult, PlayerKey, UnpackingResults)
|
||
end
|
||
|
||
function UGCGameState:Unpacking(PlayerKey, UnpackingLevel, Drop)
|
||
if Drop == nil then
|
||
Drop = Tables.Unpacking.CardDropping
|
||
end
|
||
while 1 do
|
||
local RateList = {}
|
||
if Drop.Children then
|
||
for k, Child in pairs(Drop.Children) do
|
||
if Child.Rate then
|
||
RateList[k] = Child.Rate
|
||
else
|
||
print("UGCGameState_Fun_" .. "Unpacking_" .. "Error_" .. "Rate is nil")
|
||
return
|
||
end
|
||
end
|
||
|
||
local TargetIndex = self:GetRandomIndex(RateList)
|
||
Drop = Drop.Children[TargetIndex]
|
||
else
|
||
if Drop.AddDataFun then
|
||
local TargetController = ScriptGameplayStatics.GetPlayerPawnByPlayerKey(self,PlayerKey):GetController()
|
||
return Drop.AddDataFun(TargetController, UnpackingLevel)
|
||
else
|
||
print("UGCGameState_Fun_" .. "Unpacking_" .. "Error_" .. "Children is nil and AddDataFun is nil")
|
||
return
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function UGCGameState:GetRandomIndex(probabilityList)
|
||
local totalProbability = 0
|
||
for i=1, #probabilityList do
|
||
totalProbability = totalProbability + probabilityList[i]
|
||
end
|
||
local randomValue = math.random() * totalProbability
|
||
local currentIndex = 1
|
||
for i=1, #probabilityList do
|
||
randomValue = randomValue - probabilityList[i]
|
||
if randomValue <= 0 then
|
||
currentIndex = i
|
||
break
|
||
end
|
||
end
|
||
return currentIndex
|
||
end
|
||
|
||
-- 保存玩家数据
|
||
function UGCGameState:SavePlayersData(InPlayerKey)
|
||
local Func = function(v)
|
||
print(string.format('[UGCGameState:SavePlayersData] 开始保存数据'))
|
||
-- 进行测试
|
||
--self:TestPlayerSaveData(v)
|
||
|
||
local SaveData = v.ArchiveData
|
||
local Version_Temp
|
||
if Version == nil then
|
||
Version_Temp = require('Script.Global.Version')
|
||
else
|
||
Version_Temp = Version
|
||
end
|
||
local SavedData = {
|
||
ArchiveData = SaveData,
|
||
Version = Version_Temp.GetCurrentVersion()
|
||
}
|
||
log_tree("SaveData = ", SavedData)
|
||
UGCPlayerStateSystem.SavePlayerArchiveData(v.UID, SavedData)
|
||
end
|
||
|
||
if InPlayerKey ~= nil then
|
||
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(InPlayerKey)
|
||
Func(PlayerState)
|
||
else
|
||
local AllPlayerStates = UGCGameSystem.GetAllPlayerState(false)
|
||
print(string.format('[UGCGameState:SavePlayersData] 保存数据'))
|
||
for _, v in pairs(AllPlayerStates) do
|
||
Func(v)
|
||
end
|
||
end
|
||
end
|
||
|
||
function UGCGameState:TestPlayerSaveData(InPlayerState)
|
||
InPlayerState.ArchiveData = {
|
||
--GameTimes = 100, --游玩局数
|
||
GameTimes = 1000, --游玩局数
|
||
GameClearanceTimes = 200, --游戏通关数
|
||
TotalCoinPoint = 200000000, --获取总金币数
|
||
TotalKillPoint = 1300000, --获取总杀敌点数
|
||
TotalBossKilledTimes = 500, --击杀 Boss 次数
|
||
TotalSuperSkill = 2000, --获取总超级技能数
|
||
TotalSuperFitting = 0, --获取超级配件数
|
||
TotalUnpackTimes = 40000, --总开箱次数
|
||
Score = 200000, --积分
|
||
|
||
PlayedGames = { --游玩过的游戏
|
||
[1] = 6,
|
||
[2] = 6,
|
||
[3] = 6,
|
||
[4] = 6,
|
||
[5] = 6,
|
||
[6] = 6,
|
||
[7] = 6,
|
||
[8] = 6,
|
||
[9] = 6,
|
||
[10] = 6,
|
||
[11] = 6,
|
||
[12] = 6,
|
||
[13] = 6,
|
||
[14] = 6,
|
||
[15] = 6,
|
||
[16] = 6,
|
||
[17] = 6,
|
||
[18] = 6,
|
||
[19] = 6,
|
||
[20] = 6,
|
||
[21] = 6,
|
||
[22] = 6,
|
||
[23] = 6,
|
||
[24] = 6,
|
||
[25] = 6,
|
||
[26] = 6,
|
||
[27] = 6,
|
||
[28] = 6,
|
||
[29] = 6,
|
||
[30] = 6,
|
||
[31] = 6,
|
||
[32] = 6,
|
||
[33] = 6,
|
||
[34] = 6,
|
||
[35] = 6,
|
||
[36] = 6,
|
||
[37] = 6,
|
||
[38] = 6,
|
||
[39] = 6,
|
||
[40] = 6,
|
||
[41] = 6,
|
||
[42] = 6,
|
||
[43] = 6,
|
||
[44] = 6,
|
||
[45] = 6,
|
||
[46] = 6,
|
||
[47] = 6,
|
||
[48] = 6,
|
||
[49] = 6,
|
||
[50] = 6,
|
||
[51] = 6,
|
||
[52] = 6,
|
||
[53] = 6,
|
||
[54] = 6,
|
||
[55] = 6,
|
||
[56] = 6,
|
||
[57] = 6,
|
||
[58] = 6,
|
||
[59] = 6,
|
||
[60] = 6,
|
||
[61] = 6,
|
||
[62] = 6,
|
||
[63] = 6,
|
||
[64] = 6,
|
||
[65] = 6,
|
||
[66] = 6,
|
||
},
|
||
|
||
BossDropItems = { -- BOSS 掉落物
|
||
['慎'] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
},
|
||
['魅'] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
},
|
||
['春'] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
},
|
||
['瞬'] = {
|
||
[1] = 1,
|
||
[2] = 2,
|
||
[3] = 1,
|
||
[4] = 2,
|
||
},
|
||
['蛮'] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
},
|
||
['幻'] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
},
|
||
},
|
||
|
||
GameDropItems = { -- 游戏掉落物
|
||
[1] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[2] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[3] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[4] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[5] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[6] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[7] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[8] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[9] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[10] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[11] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[12] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[13] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[14] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[15] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[16] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[17] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[18] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[19] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[20] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[21] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[22] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[23] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[24] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[25] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[26] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[27] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[28] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[29] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[30] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[31] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[32] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[33] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[34] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[35] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[36] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[37] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[38] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[39] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[40] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[41] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[42] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[43] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[44] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[45] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[46] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[47] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[48] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[49] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[50] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[51] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[52] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[53] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[54] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[55] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[56] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[57] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[58] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[59] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[60] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[61] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[62] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[63] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[64] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[65] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
[66] = {
|
||
[1] = 1,
|
||
[2] = 1,
|
||
[3] = 1,
|
||
[4] = 1,
|
||
[5] = 1,
|
||
[6] = 6,
|
||
},
|
||
},
|
||
--
|
||
EasterEggs = { --彩蛋类
|
||
[1] = {
|
||
Active = true,
|
||
},
|
||
[2] = {
|
||
Active = true,
|
||
},
|
||
[3] = {
|
||
Active = true,
|
||
},
|
||
[4] = {
|
||
Active = true,
|
||
},
|
||
[5] = {
|
||
Active = true,
|
||
},
|
||
[6] = {
|
||
Active = true,
|
||
},
|
||
[7] = {
|
||
Active = true,
|
||
},
|
||
[8] = {
|
||
Active = true,
|
||
},
|
||
-- [9] = {
|
||
-- Active = false,
|
||
-- },
|
||
[10] = {
|
||
Active = true,
|
||
},
|
||
[11] = {
|
||
Active = true,
|
||
},
|
||
[12] = {
|
||
Active = true,
|
||
},
|
||
[13] = {
|
||
Active = true,
|
||
},
|
||
--[14] = {
|
||
-- Active = false,
|
||
--},
|
||
},
|
||
}
|
||
-- 测试存档
|
||
--for i = 1, table.getCount(ArchiveTable.EasterEggs) do
|
||
-- InPlayerState.ArchiveData.EasterEggs[i] = {
|
||
-- Active = false, -- 是否激活
|
||
-- }
|
||
--end
|
||
|
||
end
|
||
|
||
-- 加载所有玩家数据
|
||
function UGCGameState:LoadPlayerData()
|
||
local AllPlayerStates = UGCGameSystem.GetAllPlayerState(false)
|
||
for i = 1, #AllPlayerStates do
|
||
-- 获取玩家存档信息
|
||
local PlayerData = UGCPlayerStateSystem.GetPlayerArchiveData(AllPlayerStates[i].UID)
|
||
if PlayerData ~= nil then
|
||
-- 解析 PlayerData
|
||
-- 依次检查对应版本
|
||
self.PlayerArchiveDatas[AllPlayerStates[i].UID] = self:HandlePlayerArchiveData(PlayerData)
|
||
end
|
||
end
|
||
end
|
||
|
||
-- 根据版本处理具体数据
|
||
function UGCGameState:HandlePlayerArchiveData(InPlayerData)
|
||
-- 说明是最新版本,直接操作
|
||
if InPlayerData.Version == self.VersionId then
|
||
return InPlayerData
|
||
elseif InPlayerData.Version == '0.1' then
|
||
return InPlayerData
|
||
end
|
||
return nil
|
||
end
|
||
|
||
-----------------------------------Sound-----------------------------------
|
||
|
||
function UGCGameState:Client_MulticastRPC_PlaySound2D(ConfigId)
|
||
if self:HasAuthority() then return end
|
||
|
||
SoundManager.PlaySound2D(ConfigId)
|
||
end
|
||
|
||
function UGCGameState:Client_MulticastRPC_PlaySoundAtLocation(ConfigId, Location, Rotation)
|
||
if self:HasAuthority() then return end
|
||
|
||
SoundManager.PlaySoundAtLocation(ConfigId, Location, Rotation)
|
||
end
|
||
|
||
function UGCGameState:Client_MulticastRPC_PlaySoundAttachActor(ConfigId, AttachedActor, StopWhenAttachedToDestroyed)
|
||
if self:HasAuthority() then return end
|
||
|
||
SoundManager.PlaySoundAttachActor(ConfigId, AttachedActor, StopWhenAttachedToDestroyed)
|
||
end
|
||
|
||
function UGCGameState:Client_MulticastRPC_StopAllSound()
|
||
if self:HasAuthority() then return end
|
||
|
||
SoundManager.StopAllSound()
|
||
end
|
||
|
||
function UGCGameState:Client_MulticastRPC_StopSoundByActor(Actor)
|
||
if self:HasAuthority() then return end
|
||
|
||
SoundManager.StopSoundByActor(Actor)
|
||
end
|
||
|
||
function UGCGameState:Client_MulticastRPC_StopSoundByID(ID)
|
||
if self:HasAuthority() then return end
|
||
|
||
SoundManager.StopSoundByID(ID)
|
||
end
|
||
|
||
function UGCGameState:CloseNoticeUI()
|
||
local PlayerControllerList = UGCGameSystem.GetAllPlayerController()
|
||
for i, v in pairs(PlayerControllerList) do
|
||
UnrealNetwork.CallUnrealRPC(v, v, "ClientRPC_ShowInitialPanel", false)
|
||
end
|
||
end
|
||
|
||
function UGCGameState:SetInitialOver(InPlayerKey)
|
||
self.PlayerInitDatas[InPlayerKey] = true
|
||
local PSs = UGCGameSystem.GetAllPlayerState(false)
|
||
if table.getCount(PSs) == table.getCount(self.PlayerInitDatas) and table.getCount(self.PlayerInitDatas) >= 4 then
|
||
-- 执行操作
|
||
EventSystem:SendEvent(EventType.UpdateInitialWidget)
|
||
UGCGameSystem.GameState.GameStage = EGameStage.GameReady;
|
||
end
|
||
end
|
||
|
||
return UGCGameState;
|