684 lines
20 KiB
Lua
684 lines
20 KiB
Lua
---@class UGCGameState_C:BP_UGCGameState_C
|
||
---@field WrapperClass UClass
|
||
---@field ShootWeaponClass UClass
|
||
---@field ActorClass UClass
|
||
--Edit Below--
|
||
UGCGameSystem.UGCRequire('Script.Common.ue_enum_custom')
|
||
require('Script.Global.Global')
|
||
|
||
local UGCGameState = {};
|
||
|
||
--- 服务器时间
|
||
UGCGameState.ServerTime = 0;
|
||
--- 服务器时间 - 客户端时间的差值;如果想在服务器求客户端时间:当前时间 - 该值;
|
||
UGCGameState.ServerTimeDiff = 0;
|
||
--- 地图数据
|
||
UGCGameState.MapData = { SelectMapIndex = {}; };
|
||
---@type table<TeamId, table<int32, PlayerKey>> 玩家 Key 列表
|
||
UGCGameState.PlayerList = {};
|
||
--- 游戏进程数据
|
||
UGCGameState.CountDownTime = 0;
|
||
UGCGameState.AccountTable = {};
|
||
UGCGameState.ArchiveTable = {};
|
||
UGCGameState.PlayerKDAs = {};
|
||
|
||
function UGCGameState:ReceiveBeginPlay()
|
||
--- 初始化
|
||
GlobalInit.InitGlobalVar();
|
||
if IsServer then
|
||
self.ServerTime = 1; -- 设置好
|
||
DOREPONCE(self, "ServerTime")
|
||
end
|
||
self.bIsOpenShovelingAbility = DefaultSettings.OpenShovel;
|
||
if MiniGameManager == nil then
|
||
MiniGameManager = require("Script.Blueprint.Mini.MiniGameManager")
|
||
end
|
||
if GlobalBeginTool then GlobalBeginTool:ReceiveBeginPlay(); end
|
||
table.func(MiniGameManager, "ReceiveBeginPlay", self);
|
||
end
|
||
|
||
function UGCGameState:ReceiveTick(DeltaTime)
|
||
if GlobalTickTool then GlobalTickTool:ReceiveTick(DeltaTime, self:GetServerTime()); end
|
||
end
|
||
|
||
function UGCGameState:ReceiveEndPlay()
|
||
DefaultSettings = nil;
|
||
EventTypes = nil;
|
||
GameState = nil;
|
||
LocalPlayerKey = nil;
|
||
LocalPlayerController = nil;
|
||
UnableTable();
|
||
UnableTool();
|
||
UnableWidgetManager();
|
||
UGCGameSystem.GameState = nil;
|
||
end
|
||
|
||
function UGCGameState:GetAvailableServerRPCs()
|
||
return "LoadMap"
|
||
, "CheckServerTime"
|
||
, "SelectLevelMode"
|
||
, "SelectMap"
|
||
, "MiniGameReceiveRPC"
|
||
end
|
||
|
||
function UGCGameState:GetReplicatedProperties()
|
||
return { "MapData", "Lazy" }
|
||
, { "CountDownTime", "Lazy" }
|
||
, { "ServerTime", "Lazy" }
|
||
, { "LoadMapName", "Lazy" }
|
||
, { "CurrMiniType", "Lazy" }
|
||
, { "MiniInfo", "Lazy" }
|
||
, { "ArchiveTable", "Lazy" }
|
||
, { "AccountTable", "Lazy" }
|
||
, { "PlayerKDAs", "Lazy" }
|
||
end
|
||
|
||
----------------------------------------- 玩家属性 -----------------------------------------
|
||
---@param InPlayerKey PlayerKey
|
||
---@param InArchiveData table<ArchiveData>
|
||
---@param InAccountData table<PlayerAccountInfo>
|
||
function UGCGameState:HandlePlayerDatas(InPlayerKey, InArchiveData, InAccountData, IgnoreList)
|
||
InArchiveData.GameTimes = (InArchiveData.GameTimes or 0) + 1; -- 又多玩了一局游戏
|
||
self.ArchiveTable[InPlayerKey] = InArchiveData;
|
||
for i, v in pairs(IgnoreList) do
|
||
self.ArchiveTable[InPlayerKey][v] = nil;
|
||
end
|
||
self.AccountTable[InPlayerKey] = InAccountData;
|
||
|
||
DOREPONCE(self, "ArchiveTable");
|
||
DOREPONCE(self, "AccountTable");
|
||
end
|
||
|
||
function UGCGameState:OnRep_PlayerKDAs()
|
||
if table.isEmpty(self.PlayerKDAs) then return end
|
||
UGCEventSystem.SendEvent(EventTypes.AllPlayerKDAChange, self:HandleAllKDAs());
|
||
end
|
||
|
||
function UGCGameState:HandleAllKDAs()
|
||
if table.isEmpty(self.PlayerKDAs) then return; end
|
||
local AllKDAs = {};
|
||
local Max = 0;
|
||
for PlayerKey, KD in pairs(self.PlayerKDAs) do
|
||
local Kill = KD[1] or 0;
|
||
local Dead = KD[2] or 0;
|
||
table.insert(AllKDAs, {
|
||
Kill = Kill,
|
||
Dead = Dead,
|
||
IsSelf = LocalPlayerKey == PlayerKey,
|
||
PlayerKey = PlayerKey,
|
||
});
|
||
if PlayerKey == LocalPlayerKey then
|
||
LocalKillNum = Kill;
|
||
end
|
||
if Max < Kill then Max = Kill; end
|
||
end
|
||
MaxKillNum = Max;
|
||
table.sort(AllKDAs, function(a, b)
|
||
if a.Kill == b.Kill then
|
||
if a.Dead == b.Dead then
|
||
return a.IsSelf;
|
||
end
|
||
return a.Dead < b.Dead;
|
||
end
|
||
return a.Kill > b.Kill;
|
||
end);
|
||
|
||
local No, Kill = -1, 1;
|
||
for i = 1, #AllKDAs do
|
||
local Item = AllKDAs[i];
|
||
if Kill == Item.Kill then
|
||
else
|
||
No = i;
|
||
Kill = Item.Kill;
|
||
end
|
||
AllKDAs[i].No = No;
|
||
end
|
||
UGCLogSystem.LogTree(string.format("[UGCGameState:OnRep_PlayerKDAs] AllKDAs ="), AllKDAs)
|
||
return AllKDAs;
|
||
end
|
||
|
||
function UGCGameState:OnRep_ArchiveTable()
|
||
ArchiveTable = self.ArchiveTable;
|
||
if table.isEmpty(ArchiveTable) then return ; end
|
||
if LocalPlayerKey == nil then return ; end
|
||
if ArchiveTable[LocalPlayerKey] == nil then return; end
|
||
local GameTimes = ArchiveTable[LocalPlayerKey].GameTimes
|
||
if GameTimes ~= nil and GameTimes <= DefaultSettings.ShowFaceNoticeGameTimes then
|
||
if not DefaultSettings.EnableTest then
|
||
WidgetManager:ShowPanel(WidgetConfig.EUIType.FaceNotice, false);
|
||
end
|
||
end
|
||
end
|
||
|
||
function UGCGameState:OnRep_AccountTable()
|
||
AccountTable = self.AccountTable;
|
||
end
|
||
|
||
----------------------------------------- 地图加载 -----------------------------------------
|
||
UGCGameState.PlayerLevelModes = {};
|
||
|
||
function UGCGameState:SelectLevelMode(InLevelMode, InPlayerKey)
|
||
if IsServer then
|
||
self.PlayerLevelModes[InPlayerKey] = InLevelMode;
|
||
else
|
||
end
|
||
end
|
||
|
||
--- 已经加载了的地图名称
|
||
UGCGameState.LoadMapName = {};
|
||
|
||
--- 加载地图(服务器/客户端都可以执行)
|
||
---@param MapNameList table<int32, string> 地图索引
|
||
function UGCGameState:LoadMap(MapNameList)
|
||
-- 找到对应地图,然后进行加载
|
||
if not table.isEmpty(self.LoadMapName) then
|
||
-- 先卸载,再安装
|
||
local List = {};
|
||
for i, v in pairs(self.LoadMapName) do
|
||
table.insert(List, v.Name);
|
||
end
|
||
self:UnloadMap(List);
|
||
end
|
||
for i, v in pairs(MapNameList) do
|
||
table.insert(self.LoadMapName, {
|
||
Name = v,
|
||
Load = false,
|
||
});
|
||
end
|
||
LevelStreamTool.LoadStreamLevels(MapNameList, { Object = self, Func = self.LoadMapFinish }, false);
|
||
DOREPONCE(self, "LoadMapName")
|
||
end
|
||
|
||
function UGCGameState:OnRep_LoadMapName()
|
||
if table.isEmpty(self.LoadMapName) then return ; end
|
||
UGCLogSystem.LogTree(string.format("[UGCGameState:OnRep_LoadMapName] self.LoadMapName ="), self.LoadMapName);
|
||
local LoadedMaps = {};
|
||
for i, v in pairs(self.LoadMapName) do
|
||
if v.Load then table.insert(LoadedMaps, v.Name); end
|
||
end
|
||
if table.isEmpty(LoadedMaps) then return ; end
|
||
UGCEventSystem.SendEvent(EventTypes.OnMapLoaded, LoadedMaps);
|
||
MiniGameManager:OnMapLoadComplete()
|
||
-- 加载小地图
|
||
UGCLogSystem.Log("[UGCGameState:OnRep_LoadMapName] 开始加载小地图")
|
||
for i, v in pairs(LevelTable.LevelInfo) do
|
||
if v.MapName == self.LoadMapName[1].Name then
|
||
UGCLogSystem.Log("[UGCGameState:OnRep_LoadMapName] 执行")
|
||
self:LoadMinimap(i);
|
||
break ;
|
||
end
|
||
end
|
||
end
|
||
|
||
--- 随机加载地图
|
||
---@param
|
||
function UGCGameState:LoadRandomMap(InIndex)
|
||
if IsServer then
|
||
self:UnloadMap();
|
||
-- 判断当前是不是随即关卡
|
||
UGCLogSystem.LogTree(string.format("[UGCGameState:LoadMap] LevelTable.LevelInfo ="), LevelTable.LevelInfo)
|
||
if InIndex == nil or InIndex == LevelTable.ELevelType.Random then
|
||
self.MapData.SelectMapIndex = LevelTable.GetRandomLevel(true, 1);
|
||
else
|
||
self.MapData.SelectMapIndex = { InIndex };
|
||
end
|
||
local MapNames = {};
|
||
for i, v in pairs(self.MapData.SelectMapIndex) do
|
||
table.insert(MapNames, LevelTable.LevelInfo[v].MapName);
|
||
end
|
||
LevelStreamTool.LoadStreamLevels(MapNames, { Object = self, Func = self.LoadMapFinish }, false);
|
||
DOREPONCE(self, "MapData");
|
||
else
|
||
-- 发送 RPC 到服务器
|
||
UnrealNetwork.CallUnrealRPC(LocalPlayerController, self, "LoadMap", InIndex);
|
||
end
|
||
end
|
||
|
||
--- 卸载地图
|
||
function UGCGameState:UnloadMap()
|
||
if table.isEmpty(self.MapData.SelectMapIndex) then
|
||
local MapNames = {};
|
||
for i, v in pairs(self.MapData.SelectMapIndex) do
|
||
table.insert(MapNames, LevelTable.LevelInfo[v].MapName)
|
||
end
|
||
LevelStreamTool.UnLoadStreamLevels(MapNames, { Object = self, Func = self.UnLoadMapFinish }, false);
|
||
self.MapData.SelectMapIndex = {};
|
||
-- 重置 ClientAlready
|
||
self.bInitOnce = false;
|
||
end
|
||
end
|
||
|
||
function UGCGameState:OnRep_MapData()
|
||
if table.isEmpty(self.MapData.SelectMapIndex) then return end
|
||
--self:LoadMinimap(self.MapData.SelectMapIndex);
|
||
end
|
||
|
||
--- 地图加载完成
|
||
function UGCGameState:LoadMapFinish()
|
||
UGCLogSystem.Log("[UGCGameState:LoadMapFinish] 地图加载完成");
|
||
-- 写一个通知
|
||
UGCEventSystem.SendEvent(EventTypes.MapLoad, self.MapData.SelectMapIndex, true);
|
||
self:OnMapLoaded();
|
||
end
|
||
|
||
function UGCGameState:UnLoadMapFinish()
|
||
UGCLogSystem.Log("[UGCGameState:UnLoadMapFinish] 地图卸载成功")
|
||
MiniGameManager:OnMapUnLoadedComplete();
|
||
end
|
||
|
||
--- 加载小地图
|
||
function UGCGameState:LoadMinimap(InType)
|
||
UGCLogSystem.Log("[UGCGameState:LoadMinimap] 开始加载 %s 的小地图", LevelTable.LevelInfo[InType].MapName);
|
||
local MinimapInfo = LevelTable.LevelInfo[InType].MiniMapInfo;
|
||
if not table.isEmpty(MinimapInfo) then
|
||
UGCLogSystem.Log("[UGCGameState:LoadMinimap] 开始添加")
|
||
UGCWidgetManagerSystem.ChangeMap(MinimapInfo.MapPath, MinimapInfo.MapCentre, MinimapInfo.MapSize, MinimapInfo.MapScale);
|
||
end
|
||
end
|
||
|
||
function UGCGameState:OnMapLoaded()
|
||
--- 加载地图上的东西
|
||
UGCLogSystem.Log("[UGCGameState:OnMapLoaded] 执行")
|
||
UGCEventSystem.SetTimer(self, function() self:PostOnMapLoaded(); end, 2);
|
||
-- 检测一下是否有默认地图
|
||
MiniGameManager:OnMapLoadComplete();
|
||
for i, v in pairs(self.LoadMapName) do
|
||
v.Load = true;
|
||
end
|
||
DOREPONCE(self, "LoadMapName");
|
||
end
|
||
|
||
---@type table<int32, BP_ActorStart_C> 玩家中心点
|
||
UGCGameState.CenterActors = {};
|
||
|
||
---@return table<int32, BP_ActorStart_C> 玩家中心点
|
||
function UGCGameState:FindCenters()
|
||
if table.isEmpty(self.CenterActors) then
|
||
UE.FindActorsByClass(ObjectPath.BP_ActorStart, self.CenterActors, function(InIndex, InActor)
|
||
return InActor:ActorHasTag("Poison");
|
||
end);
|
||
end
|
||
return self.CenterActors;
|
||
end
|
||
|
||
function UGCGameState:PostOnMapLoaded()
|
||
end
|
||
|
||
----------------------------------------- 游戏进程 -----------------------------------------
|
||
---@param InTime int32 初始化倒计时
|
||
function UGCGameState:OnGameActive(InTime)
|
||
if MiniGameManager then
|
||
table.func(MiniGameManager, "OnGameActive", InTime);
|
||
end
|
||
end
|
||
|
||
function UGCGameState:OnBeforeGameStart(InTime)
|
||
if MiniGameManager then
|
||
table.func(MiniGameManager, "OnBeforeGameStart", InTime);
|
||
end
|
||
end
|
||
|
||
--- 游戏结束
|
||
function UGCGameState:OnGameEnded()
|
||
-- 打开结算界面
|
||
if IsServer then
|
||
for i, v in pairs(UGCGameSystem.GetAllPlayerController(false)) do
|
||
local PlayerKey = v.PlayerKey;
|
||
-- 保存一下存档
|
||
UGCPlayerStateSystem.SavePlayerArchiveData(AccountTable[PlayerKey].UID, ArchiveTable[PlayerKey]);
|
||
UGCGameSystem.SendPlayerSettlement(PlayerKey);
|
||
end
|
||
UGCLogSystem.Log("[UGCGameState:OnGameEnded] 执行")
|
||
for i, v in pairs(UGCGameSystem.GetAllPlayerPawn()) do
|
||
UGCPawnSystem.LeavePawnState(v, EPawnState.Move);
|
||
v:K2_DestroyActor()
|
||
end
|
||
|
||
self:ShowUIByType(WidgetConfig.EUIType.GameEnd, true)
|
||
end
|
||
end
|
||
|
||
--- 倒计时
|
||
function UGCGameState:OnGameProgress_Tick(InTime)
|
||
self.CountDownTime = InTime;
|
||
DOREPONCE(self, "CountDownTime");
|
||
end
|
||
|
||
function UGCGameState:OnRep_CountDownTime()
|
||
UGCEventSystem.SendEvent(EventTypes.CountDownTimeChange, self.CountDownTime);
|
||
-- 执行客户端调用
|
||
if MiniGameManager then
|
||
MiniGameManager:OnMiniGameTimeCount(self.CountDownTime);
|
||
end
|
||
end
|
||
|
||
--- 当前游戏时间,以服务器为基准(因为服务器不会改变)
|
||
---客户端准备好之后会发送一个 RPC 过来,之后就是
|
||
function UGCGameState:CheckServerTime(InPlayerKey, InTime)
|
||
if IsServer then
|
||
local PC = UGCGameSystem.GetPlayerControllerByPlayerKey(InPlayerKey)
|
||
UnrealNetwork.CallUnrealRPC(PC, self, "CheckClientTime", UE.GetCurrentTime());
|
||
self:OnClientAlready();
|
||
else
|
||
UnrealNetwork.CallUnrealRPC(LocalPlayerController, self, "CheckServerTime", InPlayerKey, InTime);
|
||
end
|
||
end
|
||
|
||
function UGCGameState:OnRep_ServerTime()
|
||
-- 接收到之后就立刻发送 RPC 到服务器,或者也可以等一会
|
||
if self.ServerTime == 1 then
|
||
if LocalPlayerKey == nil or LocalPlayerController == nil then
|
||
UGCEventSystem.SetTimer(self, function()
|
||
self:CheckServerTime(LocalPlayerKey, UE.GetCurrentTime())
|
||
end, 1.);
|
||
return ;
|
||
end
|
||
self:CheckServerTime(LocalPlayerKey, UE.GetCurrentTime())
|
||
elseif self.ServerTime == 0 then
|
||
else
|
||
local Diff = self.ServerTime - UE.GetCurrentTime();
|
||
UGCLogSystem.Log("[UGCGameState:CheckClientTime] Diff = %f", Diff)
|
||
self:OnClientAlready();
|
||
end
|
||
end
|
||
|
||
function UGCGameState:CheckClientTime(InTime)
|
||
self.ServerTimeDiff = InTime - UE.GetCurrentTime();
|
||
UGCLogSystem.Log("[UGCGameState:CheckClientTime] self.ServerTimeDiff = %f", self.ServerTimeDiff);
|
||
self:OnClientAlready();
|
||
end
|
||
|
||
UGCGameState.bInitOnce = false;
|
||
--- 是否有毒圈:0表示未知,1表示存在,-1 表示不存在
|
||
UGCGameState.HasPoison = 0;
|
||
|
||
function UGCGameState:OnClientAlready()
|
||
if self.bInitOnce then return end
|
||
UGCEventSystem.SendEvent(EventTypes.ClientAlready)
|
||
|
||
local ServerTime = self:GetServerTime()
|
||
UGCLogSystem.Log("[UGCGameState:OnClientAlready] 执行 ServerTime = %f", ServerTime);
|
||
|
||
if IsServer then
|
||
UGCLogSystem.Log("[UGCGameState:OnClientAlready] 执行")
|
||
self:OnGameActive(-1)
|
||
end
|
||
if GlobalBeginTool then
|
||
GlobalBeginTool:ReceiveClientAlready()
|
||
GlobalBeginTool = nil;
|
||
end
|
||
|
||
if MiniGameManager then
|
||
table.func(MiniGameManager, "OnClientAlready");
|
||
end
|
||
|
||
self.bInitOnce = true;
|
||
end
|
||
|
||
--- S & C : 获取服务器时间
|
||
---@return float|nil
|
||
function UGCGameState:GetServerTime()
|
||
if IsServer then
|
||
return UE.GetCurrentTime();
|
||
else
|
||
if self.ServerTimeDiff == 0 then
|
||
return nil;
|
||
else
|
||
return self.ServerTimeDiff + UE.GetCurrentTime();
|
||
end
|
||
end
|
||
end
|
||
|
||
--- 获取客户端时间
|
||
function UGCGameState:GetClientTime(InPlayerKey)
|
||
if IsClient then
|
||
return UE.GetCurrentTime();
|
||
else
|
||
end
|
||
end
|
||
|
||
function UGCGameState:ClearAll()
|
||
UnableTable()
|
||
end
|
||
|
||
--- 提前重置操作
|
||
function UGCGameState:BeforeReset(InTime)
|
||
for i, v in pairs(UGCGameSystem.GetAllPlayerController(false)) do
|
||
local PlayerKey = v.PlayerKey;
|
||
local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey);
|
||
if UE.IsValidPawn(Pawn) then
|
||
Pawn:K2_DestroyActor();
|
||
end
|
||
UE.RespawnPlayer(PlayerKey, InTime);
|
||
end
|
||
self:ResetKill();
|
||
end
|
||
|
||
function UGCGameState:ResetKill()
|
||
-- 重置其他的
|
||
for i, v in pairs(UGCGameSystem.GetAllPlayerController(false)) do v:ResetGame(); end
|
||
end
|
||
|
||
--- 重置游戏
|
||
function UGCGameState:ResetGame()
|
||
if IsServer then
|
||
UnrealNetwork.CallUnrealRPC_Multicast(self, "ResetGame");
|
||
-- 重置击杀数
|
||
for i, v in pairs(UGCGameSystem.GetAllPlayerState(false)) do
|
||
v:ResetKillNum();
|
||
end
|
||
else
|
||
WidgetManager:GetPanel(WidgetConfig.EUIType.Main):OnGameStart();
|
||
end
|
||
end
|
||
|
||
----------------------------------------- 界面 UI -----------------------------------------
|
||
--- 显示 UI
|
||
---@param InUIType EUIType
|
||
---@param IsShow boolean
|
||
function UGCGameState:ShowUIByType(InUIType, IsShow, ...)
|
||
if IsServer then
|
||
UnrealNetwork.CallUnrealRPC_Multicast(self, "ShowUIByType", InUIType, IsShow, ...);
|
||
else
|
||
if IsShow then
|
||
WidgetManager:ShowPanel(InUIType, false, ...);
|
||
else
|
||
WidgetManager:ClosePanel(InUIType);
|
||
end
|
||
end
|
||
end
|
||
|
||
----------------------------------------- 场景物品 -----------------------------------------
|
||
|
||
-- 清除场景上的 Wrappers
|
||
function UGCGameState:ClearWrappers()
|
||
local InTable = {};
|
||
UE.FindActorsByClass(self:GetWrapperClass(), InTable, function(InIndex, InActor)
|
||
return InActor:GetOwner() == nil;
|
||
end);
|
||
for i, v in pairs(InTable) do v:K2_DestroyActor(); end
|
||
end
|
||
|
||
----------------------------------------- 武器 -----------------------------------------
|
||
---@return UClass
|
||
function UGCGameState:GetWrapperClass()
|
||
return self.WrapperClass;
|
||
end
|
||
|
||
----------------------------------------- 载具 -----------------------------------------
|
||
--- 清空地面上的载具
|
||
function UGCGameState:ClearVehicles()
|
||
if table.isEmpty(self.Vehicles) then self:FindVehicles(); end
|
||
for i, v in pairs(self.Vehicles) do v:K2_DestroyActor(); end
|
||
self.Vehicles = {};
|
||
end
|
||
|
||
--- 加载地面上的载具,通过 ActorStart 进行查找
|
||
function UGCGameState:LoadVehicles()
|
||
self:ClearVehicles();
|
||
local AllStarts = {};
|
||
UE.FindActorsByClass(ObjectPath.BP_ActorStart, AllStarts, function(InIndex, InActor)
|
||
table.insert(self.Vehicles, UGCVehicleSystem.SpawnVehicleNew(VehicleTable.Car[InActor.Index].Path, InActor:K2_GetActorLocation(), InActor:K2_GetActorRotation(), false, false));
|
||
return true;
|
||
end)
|
||
end
|
||
|
||
-- 查找载具
|
||
function UGCGameState:FindVehicles()
|
||
if table.isEmpty(self.Vehicles) then self:LoadVehicles(); end
|
||
return self.Vehicles;
|
||
end
|
||
|
||
----------------------------------------- FUNCTIONAL -----------------------------------------
|
||
|
||
--- 发送自定义事件
|
||
function UGCGameState:SendEvent(IsSend, InPlayerKey, InEvent, ...)
|
||
if IsServer then
|
||
if IsSend then
|
||
if InPlayerKey == nil then
|
||
UnrealNetwork.CallUnrealRPC_Multicast(self, "SendEvent", false, nil, InEvent, ...);
|
||
else
|
||
UnrealNetwork.CallUnrealRPC(UGCGameSystem.GetPlayerControllerByPlayerKey(InPlayerKey), UGCGameSystem.GameState, "SendEvent", false, InPlayerKey, InEvent, ...);
|
||
end
|
||
else
|
||
UGCEventSystem.SendEvent(InEvent, InPlayerKey, ...)
|
||
end
|
||
else
|
||
-- 从客户端发送出去
|
||
if IsSend then
|
||
UnrealNetwork.CallUnrealRPC(DefaultSettings.LocalPlayerController, UGCGameSystem.GameState, "SendEvent", false, DefaultSettings.LocalPlayerKey, InEvent, ...);
|
||
else
|
||
UGCEventSystem.SendEvent(InEvent, InPlayerKey, ...);
|
||
end
|
||
end
|
||
end
|
||
|
||
----------------------------------------- MINI -----------------------------------------
|
||
--- 当前选择的 MiniType
|
||
UGCGameState.CurrMiniType = -1;
|
||
|
||
---@param InMiniType int32
|
||
function UGCGameState:SelectMiniType(InMiniType)
|
||
self.CurrMiniType = InMiniType;
|
||
DOREPONCE(self, "CurrMiniType");
|
||
end
|
||
|
||
function UGCGameState:OnRep_CurrMiniType()
|
||
if self.CurrMiniType < 0 then return ; end
|
||
if MiniGameManager ~= nil then
|
||
MiniGameManager:LoadMiniGame(self.CurrMiniType);
|
||
end
|
||
end
|
||
|
||
--- 发送 MiniGame RPC
|
||
---@param InFuncName string 函数名称
|
||
---@vararg any
|
||
function UGCGameState:SendMiniGameRPC(InFuncName, ...)
|
||
if IsServer then
|
||
UnrealNetwork.CallUnrealRPC_Multicast(self, "MiniGameReceiveRPC", InFuncName, true, ...);
|
||
else
|
||
UnrealNetwork.CallUnrealRPC(LocalPlayerController, self, "MiniGameReceiveRPC", InFuncName, false, ...);
|
||
end
|
||
end
|
||
|
||
--- Mini Game 接收到 RPC
|
||
---@param InFuncName string 函数名称
|
||
---@param SendFromServer bool 是否发自服务器
|
||
function UGCGameState:MiniGameReceiveRPC(InFuncName, SendFromServer, ...)
|
||
if table.hasFunc(MiniGameManager, InFuncName) then
|
||
table.func(MiniGameManager, InFuncName, ...)
|
||
else
|
||
if MiniGameManager ~= nil and MiniGameManager.CurrMiniMode then
|
||
table.func(MiniGameManager.CurrMiniMode, InFuncName, ...)
|
||
end
|
||
end
|
||
end
|
||
|
||
--- 小游戏需要同步的数据
|
||
UGCGameState.MiniInfo = {};
|
||
|
||
function UGCGameState:SetMiniInfo(InMiniInfo)
|
||
self.MiniInfo = InMiniInfo;
|
||
DOREPONCE(self, "MiniInfo");
|
||
end
|
||
|
||
function UGCGameState:OnRep_MiniInfo(InOld)
|
||
if table.isEmpty(self.MiniInfo) then return ; end
|
||
-- 发送出去
|
||
UGCLogSystem.LogTree(string.format("[UGCGameState:OnRep_MiniInfo] MiniInfo"), self.MiniInfo)
|
||
if MiniGameManager then
|
||
MiniGameManager.MiniInfo = self.MiniInfo;
|
||
MiniGameManager:OnRep_MiniInfo(InOld);
|
||
end
|
||
end
|
||
|
||
--- 获取 MiniGame 的数据
|
||
function UGCGameState:GetMiniInfo(Name)
|
||
if MiniGameManager then
|
||
return table.func(MiniGameManager, "GetMiniInfo", Name);
|
||
end
|
||
return nil;
|
||
end
|
||
|
||
--- 获取配置
|
||
function UGCGameState:GetMiniConfig(Name)
|
||
if MiniGameManager then
|
||
return table.func(MiniGameManager, "GetMiniInfo", Name);
|
||
end
|
||
return nil;
|
||
end
|
||
|
||
function UGCGameState:MiniFunc(InFuncName, ...)
|
||
UGCLogSystem.Log("[UGCGameState:MiniFunc] FuncName = %s", InFuncName)
|
||
if MiniGameManager then
|
||
UGCLogSystem.Log("[UGCGameState:MiniFunc] 执行")
|
||
return table.func(MiniGameManager, "DoMiniFunc", InFuncName, ...)
|
||
end
|
||
end
|
||
|
||
----------------------------------------- 自定义函数 -----------------------------------------
|
||
---显示TipsUI
|
||
function UGCGameState:ShowTipsUI(InStr, ...)
|
||
if IsServer then
|
||
UnrealNetwork.CallUnrealRPC_Multicast_Unreliable(self, "ShowTipsUI", string.format(InStr, ...));
|
||
else
|
||
UGCWidgetManagerSystem.ShowTipsUI(string.format(InStr, ...));
|
||
end
|
||
end
|
||
|
||
function UGCGameState:CustomLog(Color, InStr, ...)
|
||
if DefaultSettings.EnableTest then
|
||
if IsServer then
|
||
-- 组装一下
|
||
if self.CustomLogList == nil then
|
||
self.CustomLogList = {};
|
||
GlobalTickTool:AddTick(self, function(o, dt, st)
|
||
if table.isEmpty(o.CustomLogList) then return ; end
|
||
-- 发送 RPC
|
||
UnrealNetwork.CallUnrealRPC_Multicast(self, "CustomLog", o.CustomLogList);
|
||
o.CustomLogList = {};
|
||
end, 1);
|
||
end
|
||
-- 开始添加,然后启动函数
|
||
local Item = {
|
||
c = Color,
|
||
s = string.format('[Server]' .. string.format('[%0.1f]', UE.GetServerTime()) .. InStr:format(...)),
|
||
};
|
||
table.insert(self.CustomLogList, Item);
|
||
else
|
||
if type(Color) == 'table' then
|
||
WidgetManager:GetPanel(WidgetConfig.EUIType.Main, function(Widget)
|
||
Widget:AddLogItems(Color);
|
||
end);
|
||
else
|
||
local Params = { ... };
|
||
WidgetManager:GetPanel(WidgetConfig.EUIType.Main, function(Widget)
|
||
Widget:AddLogItem(Color, InStr, table.unpackTable(Params));
|
||
end);
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
return UGCGameState;
|