2025-01-04 23:00:19 +08:00

884 lines
28 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.

---@class UGCGameState_C:BP_UGCGameState_C
---@field WrapperClass UClass
---@field ShootWeaponClass 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 = {}; };
--- 玩家数据
UGCGameState.PlayerDatas = {
---@type table<PlayerKey, any>
ArchiveData = {};
---@type table<PlayerKey, PlayerAccountInfo>
AccountInfo = {};
};
---@type table<TeamId, table<int32, PlayerKey>> 玩家 Key 列表
UGCGameState.PlayerList = {};
---@type table<int32, PlayerKDA_DamageItem> 支持排序功能
UGCGameState.PlayerKDA_Damages = {};
--- 游戏进程数据
UGCGameState.CountDownTime = 0;
UGCGameState.ProgressType = DefaultSettings.EGameProgress.NON_START;
---@type table<PlayerKey, PlayerAttributeItem_BigFight> 玩家属性
UGCGameState.PlayerAttribute = {};
--- Level 模式
UGCGameState.LevelMode = ModeTable.EModeType.Common;
function UGCGameState:ReceiveBeginPlay()
--- 初始化
self.bIsOpenShovelingAbility = DefaultSettings.OpenShovel;
GlobalInit.InitGlobalVar();
if IsServer then
-- 补人
UGCMultiMode.SetPlayerFill(DefaultSettings.TotalPlayerCount > 0);
self.ServerTime = 1; -- 设置好
DOREPONCE(self, "ServerTime")
else
end
if self.MiniGameManager == nil then
self.MiniGameManager = require("Script.Blueprint.Mini.MiniGameManager");
end
if GlobalBeginTool then GlobalBeginTool:ReceiveBeginPlay(); end
table.func(self.MiniGameManager, "ReceiveBeginPlay", self);
TestTool:Test_UE_Props();
self.SuperClass.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;
LocalTeamPlayers = nil;
EnemyTeamPlayers = nil;
UnableTable();
UnableTool();
UnableWidgetManager();
UGCGameSystem.GameState = nil;
end
function UGCGameState:GetAvailableServerRPCs()
return "LoadMap"
, "Server_SaveOrGetButtonSetting"
, "CheckServerTime"
, "SelectMap"
end
function UGCGameState:GetReplicatedProperties()
return { "MapData", "Lazy" }
, { "PlayerDatas", "Lazy" }
, { "PlayerKDA_Damages", "Lazy" }
, { "ProgressType", "Lazy" }
, { "CountDownTime", "Lazy" }
, { "PlayerList", "Lazy" }
, { "PlayerAttribute", "Lazy" }
, { "ServerTime", "Lazy" }
, { "MiniModeState", "Lazy" }
, { "LoadMapName", "Lazy" }
, { "CurrMiniType", "Lazy" }
, { "MiniInfo", "Lazy" }
end
----------------------------------------- 玩家属性 -----------------------------------------
---@param InPlayerKey PlayerKey
---@param InArchiveData table<ArchiveData>
---@param InAccountData table<PlayerAccountInfo>
function UGCGameState:HandlePlayerDatas(InPlayerKey, InArchiveData, InAccountData)
InArchiveData.GameTimes = InArchiveData.GameTimes + 1; -- 又多玩了一局游戏
self.PlayerDatas.ArchiveData[InPlayerKey] = InArchiveData;
self.PlayerDatas.AccountInfo[InPlayerKey] = InAccountData;
DOREPONCE(self, "PlayerDatas");
end
function UGCGameState:OnRep_PlayerDatas()
-- 检查当前玩了多少局
if LocalPlayerKey == nil then return end
if self.PlayerDatas.ArchiveData[LocalPlayerKey] == nil then return end
-- 显示拍脸图
UGCLogSystem.LogTree(string.format("[UGCGameState:OnRep_PlayerDatas] self.PlayerDatas ="), self.PlayerDatas)
if self.PlayerDatas.ArchiveData[LocalPlayerKey].GameTimes <= DefaultSettings.ShowFaceNoticeGameTimes then
UGCLogSystem.Log("[UGCGameState:OnRep_PlayerDatas] 执行")
if not DefaultSettings.EnableTest then
WidgetManager:ShowPanel(WidgetConfig.EUIType.FaceNotice, false);
end
end
UGCEventSystem.SendEvent(EventTypes.UpdatePlayerDatas, self.PlayerDatas)
end
function UGCGameState:FindPlayerKDA_DamagesByPlayerKey(InPlayerKey)
for i, v in pairs(self.PlayerKDA_Damages) do
if v.PlayerKey == InPlayerKey then return i; end
end
return -1;
end
---@param IsLogin bool
---@param InPlayerKey PlayerKey
function UGCGameState:PlayerLoginOrLeave(IsLogin, InPlayerKey)
local TeamId = UGCPlayerStateSystem.GetTeamID(InPlayerKey);
local LogOut = false;
local AlivePlayerCount = 0;
if IsLogin then
if self.PlayerList[TeamId] == nil then self.PlayerList[TeamId] = {}; end
self.PlayerList[TeamId][#(self.PlayerList[TeamId]) + 1] = InPlayerKey;
local index = self:FindPlayerKDA_DamagesByPlayerKey(InPlayerKey)
if index == -1 then
table.insert(self.PlayerKDA_Damages, {
Damage = 0,
KDA = { Kill = 0, Dead = 0, Assist = 0, },
PlayerKey = InPlayerKey,
});
DOREPONCE(self, "PlayerKDA_Damages");
end
if self.PlayerAttribute[InPlayerKey] == nil then
self.PlayerAttribute[InPlayerKey] = {};
for i, v in pairs(DefaultSettings.BenefitInto) do
self.PlayerAttribute[InPlayerKey][i] = v.DefaultValue;
end
DOREPONCE(self, "PlayerAttribute");
end
else
if self.PlayerList[TeamId] ~= nil then
local RemoveIndex = 0;
for i, v in pairs(self.PlayerList[TeamId]) do
if v == InPlayerKey then RemoveIndex = i; end
end
table.remove(self.PlayerList[TeamId], RemoveIndex);
end
--- 进行保存数据
UGCPlayerStateSystem.SavePlayerArchiveData(self.PlayerDatas.AccountInfo[InPlayerKey].UID, self.PlayerDatas.ArchiveData[InPlayerKey]);
end
for i, v in pairs(self.PlayerList) do
AlivePlayerCount = table.getCount(v) + AlivePlayerCount;
end
if AlivePlayerCount == 0 then LogOut = true; end
UGCLogSystem.LogTree(string.format("[UGCGameState:PlayerLoginOrLeave] self.PlayerKDA_Damages ="), self.PlayerKDA_Damages)
DOREPONCE(self, "PlayerList");
return LogOut, AlivePlayerCount;
end
---@param HasLeave bool 是否包含退出游戏的玩家
---@return int32 玩家数量
function UGCGameState:GetPlayerCount(HasLeave)
return table.getCount(HasLeave and self.PlayerKDA_Damages or self.PlayerList)
end
---@param InOld table<PlayerKey, PlayerAttributeItem_BigFight>
function UGCGameState:OnRep_PlayerAttribute(InOld)
UGCEventSystem.SendEvent(EventTypes.PlayerAttributeChanged, self.PlayerAttribute);
if table.isEmpty(InOld) then return end
for c, Table in pairs(self.PlayerAttribute) do
if InOld[c] ~= nil then
for i, v in pairs(Table) do
if InOld[c][i] ~= v then
UGCEventSystem.SendEvent(DefaultSettings.BenefitInto[v].Type, c, InOld[c][i], v);
end
end
else
for i, v in pairs(Table) do
UGCEventSystem.SendEvent(DefaultSettings.BenefitInto[v].Type, c, nil, v);
end
end
end
end
function UGCGameState:OnRep_PlayerList()
if table.isEmpty(self.PlayerList) then return ; end
if LocalPlayerKey == nil then return end
-- 其他玩家
EnemyTeamPlayers = {};
LocalTeamPlayers = {};
LocalTeamId = UGCPlayerStateSystem.GetTeamID(LocalPlayerKey);
for TeamId, PlayerArr in pairs(self.PlayerList) do
if TeamId == LocalTeamId then
for i, v in pairs(PlayerArr) do LocalTeamPlayers[#LocalTeamPlayers + 1] = v; end
else
for i, v in pairs(PlayerArr) do EnemyTeamPlayers[#EnemyTeamPlayers + 1] = v; end
end
end
UGCEventSystem.SendEvent(EventTypes.PlayerListChanged, self.PlayerList)
end
function UGCGameState:OnRep_PlayerKDA_Damages()
-- 刷新 KDA 和伤害
if table.isEmpty(self.PlayerKDA_Damages) then return ; end
UGCLogSystem.LogTree(string.format("[UGCGameState:OnRep_PlayerKDA_Damages] self.PlayerKDA_Damages ="), self.PlayerKDA_Damages)
UGCEventSystem.SendEvent(EventTypes.AllPlayerKDAChange, self.PlayerKDA_Damages)
end
--- 获取玩家 KDA
---@param InPlayerKey PlayerKey
---@return PlayerKDAItem1
function UGCGameState:GetPlayerKDA(InPlayerKey)
UGCLogSystem.LogTree(string.format("[UGCGameState:GetPlayerKDA] self.PlayerKDA_Damages ="), self.PlayerKDA_Damages)
local Item = self.PlayerKDA_Damages[self:FindPlayerKDA_DamagesByPlayerKey(InPlayerKey)];
if Item ~= nil then return Item.KDA; end
return nil;
end
---获取玩家伤害
---@param InPlayerKey PlayerKey
---@return float
function UGCGameState:GetPlayerDamage(InPlayerKey)
local Item = self.PlayerKDA_Damages[InPlayerKey]
if Item ~= nil then return Item.Damage; end
return 0;
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);
self.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:LoadRandomMap] 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
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] 地图卸载成功")
self.MiniGameManager:OnMapUnLoadedComplete();
end
--- 加载小地图
function UGCGameState:LoadMinimap(InType)
if type(InType) == 'nil' then
for i, v in pairs(LevelTable.LevelInfo) do
if v.MapName == self.LoadMapName[1].Name then
UGCLogSystem.Log("[UGCGameState:LoadMinimap] 执行")
self:LoadMinimap(i);
return ;
end
end
end
UGCLogSystem.Log("[UGCGameState:LoadMinimap] 开始加载 %s 的小地图", tostring(InType));
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);
-- 检测一下是否有默认地图
self.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 = {};
function UGCGameState:PostOnMapLoaded()
end
----------------------------------------- 游戏进程 -----------------------------------------
---@param InTime int32 初始化倒计时
function UGCGameState:OnGameActive(InTime)
if self.MiniGameManager then
table.func(self.MiniGameManager, "OnGameActive", InTime);
end
end
function UGCGameState:OnBeforeGameStart(InTime)
--if InTime == 2 then self:BeforeReset(InTime) end
if self.MiniGameManager then
table.func(self.MiniGameManager, "OnBeforeGameStart", InTime);
end
end
---游戏正式开始
function UGCGameState:OnGameStart()
UGCLogSystem.Log("[UGCGameState:OnGameStart] 执行 ")
end
--- 游戏结束
function UGCGameState:OnGameEnded()
-- 打开结算界面
if IsServer then
for i, v in pairs(UGCGameSystem.GetAllPlayerPawn()) do
UGCPawnSystem.LeavePawnState(v, EPawnState.Move);
v:K2_DestroyActor()
end
UnrealNetwork.CallUnrealRPC_Multicast(self, "OnGameEnded");
self:ShowUIByType(WidgetConfig.EUIType.GameEnd, true)
end
end
--- 倒计时
function UGCGameState:OnGameProgress_Tick(InTime)
self.CountDownTime = InTime;
--UGCLogSystem.Log("[UGCGameState:OnGameProgress_Tick] InTime = %s", InTime);
DOREPONCE(self, "CountDownTime");
end
---@param InState EGameProgress 游戏进度
function UGCGameState:ChangeGameProgressState(InState)
if self.ProgressType ~= InState then
if InState == DefaultSettings.EGameProgress.PREPARE then
elseif InState == DefaultSettings.EGameProgress.GAMING then
LuaQuickFireEvent("GameActive", self)
elseif InState == DefaultSettings.EGameProgress.ENDED then
LuaQuickFireEvent("GameEnd", self)
end
self.ProgressType = InState;
DOREPONCE(self, "ProgressType")
end
end
function UGCGameState:OnRep_ProgressType(InOldType)
UGCEventSystem.SendEvent(EventTypes.GameProgressChange, self.ProgressType);
if self.ProgressType == DefaultSettings.EGameProgress.GAMING then
UGCEventSystem.SendEvent(EventTypes.GameProgressChange_Gaming)
-- 当到这个的时候游戏就正式开始了,发 RPC 断线重连会执行不到
--table.func(self.MiniGameManager, "OnGameStart");
self:OnGameStart()
end
if WidgetManager then
if self.ProgressType ~= DefaultSettings.EGameProgress.ENDED then
if not WidgetManager:IsVisiblePanel(WidgetConfig.EUIType.Main) then
WidgetManager:ShowPanel(WidgetConfig.EUIType.Main, false);
end
--if self.ProgressType == DefaultSettings.EGameProgress.GAMING then
-- WidgetManager:ClosePanel(WidgetConfig.EUIType.FaceNotice);
--end
else
if WidgetManager:IsVisiblePanel(WidgetConfig.EUIType.Main) then
WidgetManager:ClosePanel(WidgetConfig.EUIType.Main);
end
if not WidgetManager:IsVisiblePanel(WidgetConfig.EUIType.GameEnd) then
WidgetManager:ShowPanel(WidgetConfig.EUIType.GameEnd, false);
end
end
end
end
function UGCGameState:OnRep_CountDownTime()
UGCEventSystem.SendEvent(EventTypes.GameProgressCountDownTimeChange, self.CountDownTime);
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
self:LoadResource();
if GlobalBeginTool then
GlobalBeginTool:ReceiveClientAlready()
GlobalBeginTool = nil;
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)
UGCLogSystem.Log("[UGCGameState:BeforeReset] 重置玩家")
for i, v in pairs(UGCGameSystem.GetAllPlayerController(false)) do
local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(v.PlayerKey);
if Pawn and UE.IsValid(Pawn) and Pawn:IsAlive() then
Pawn:K2_DestroyActor();
end
UE.RespawnPlayer(v.PlayerKey, InTime);
end
--LuaQuickFireEvent("AllPlayerReset", self);
self:ResetKill();
end
function UGCGameState:ResetKill()
-- 重置伤害
for i, v in pairs(self.PlayerKDA_Damages) do
v.Damage = 0;
v.KDA = { Kill = 0, Dead = 0, Assist = 0, }
end
for i, v in pairs(self.PlayerAttribute) do
for c, d in pairs(v) do v[c] = DefaultSettings.BenefitInto[c].DefaultValue; end
end
-- 重置其他的
for i, v in pairs(UGCGameSystem.GetAllPlayerController(false)) do v:ResetGame(); end
DOREPONCE(self, "PlayerKDA_Damages")
DOREPONCE(self, "PlayerAttribute")
end
--- 重置游戏
function UGCGameState:ResetGame()
if IsServer then
UnrealNetwork.CallUnrealRPC_Multicast(self, "ResetGame");
-- 重置击杀数
for i, v in pairs(UGCGameSystem.GetAllPlayerState(false)) do
v:ResetKillNum();
end
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
--- 显示 UI
---@param InUIType EUIType
---@param IsShow bool
---@param InPlayerKey PlayerKey
function UGCGameState:PlayerShowUIByType(InUIType, IsShow, InPlayerKey, ...)
if IsServer then
if InPlayerKey == nil then
UnrealNetwork.CallUnrealRPC_Multicast(self, "PlayerShowUIByType", InUIType, IsShow, ...);
else
UnrealNetwork.CallUnrealRPC(UGCGameSystem.GetPlayerControllerByPlayerKey(InPlayerKey), self, "PlayerShowUIByType", InUIType, IsShow, ...);
end
else
if IsShow then
WidgetManager:ShowPanel(InUIType, false, InPlayerKey, ...);
else
WidgetManager:ClosePanel(InUIType);
end
end
end
--- 保存或者获取数据
function UGCGameState:Server_SaveOrGetButtonSetting(PlayerKey, ButtonsRender)
if ButtonsRender == nil then
ButtonsRender = self.PlayerDatas.ArchiveData[PlayerKey].ButtonSettings;
else
self.PlayerDatas.ArchiveData[PlayerKey].ButtonSettings = ButtonsRender;
end
-- 提醒已经好了
self:SendEvent(true, PlayerKey, EventTypes.ButtonSettingCallBack, ButtonsRender);
end
----------------------------------------- 场景物品 -----------------------------------------
---@type BP_ResourceBase_C
UGCGameState.ResourceActor = nil;
--- 加载资源类,服务器,客户端都需要加载一次
---@return BP_ResourceBase_C
function UGCGameState:LoadResource()
if self.ResourceActor == nil then self.ResourceActor = UE.FindActorByClass(ObjectPath.BP_ResourceBase); end
UGCLogSystem.Log("[UGCGameState:LoadResource] %s", UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/UGCPlayerPawn.UGCPlayerPawn_C'))
return self.ResourceActor;
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
----------------------------------------- BUFF -----------------------------------------
---@type AActor
UGCGameState.MapCenterActor = nil;
--- 获取中心点
---@return AActor
function UGCGameState:GetCenterPointLocation()
if self.MapCenterActor ~= nil then return self.MapCenterActor:K2_GetActorLocation() end
local CenterActors = {};
UE.FindActorsByClass(ObjectPath.BP_ActorStart, CenterActors, function(InIndex, InActor)
return InActor:ActorHasTag("MapCenter");
end);
UGCLogSystem.LogTree(string.format("[UGCGameState:GetCenterPointLocation] CenterActors ="), CenterActors)
self.MapCenterActor = CenterActors[1];
if self.MapCenterActor == nil then
return VectorHelper.ToLuaTable(DefaultSettings.MapCenterLocation)
end
return CenterActors[1]:K2_GetActorLocation();
end
----------------------------------------- 武器 -----------------------------------------
--- 获取武器基类
---@return UClass 武器基类
function UGCGameState:GetShootWeaponClass()
return self.ShootWeaponClass;
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
----------------------------------------- 信号圈 -----------------------------------------
---@type PoisonCircleSystem_C
UGCGameState.PoisonSystemActor = nil;
---@return PoisonCircleSystem_C
function UGCGameState:FindPoisonCircle()
if self.PoisonSystemActor == nil then
self.PoisonSystemActor = UE.FindActorByClass(ObjectPath.PoisonCircleSystem);
end
return self.PoisonSystemActor;
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
----------------------------------------- 玩家属性 -----------------------------------------
--- 获取属性值和属性名称
---@param InPlayerKey PlayerKey
---@param InAttributeName EPawnBenefitType
function UGCGameState:GetPlayerAttribute(InPlayerKey, InAttributeName)
if InAttributeName then
if self.PlayerAttribute[InPlayerKey] ~= nil then return self.PlayerAttribute[InPlayerKey][InAttributeName]; end
return nil;
end
return self.PlayerAttribute[InPlayerKey];
end
function UGCGameState:AddPlayerAttribute(InPlayerKey, InAttributeName, InVal)
self.PlayerAttribute[InPlayerKey][InAttributeName] = self.PlayerAttribute[InPlayerKey][InAttributeName] + InVal;
if IsServer then DOREPONCE(self, "PlayerAttribute") end
end
function UGCGameState:MultiPlayerAttribute(InPlayerKey, InAttributeName, InVal)
self.PlayerAttribute[InPlayerKey][InAttributeName] = self.PlayerAttribute[InPlayerKey][InAttributeName] * InVal;
if IsServer then DOREPONCE(self, "PlayerAttribute") end
end
function UGCGameState:InitAttribute()
local Table = {};
for i, v in pairs(DefaultSettings.EPawnBenefitType) do Table[v] = 1; end
Table[DefaultSettings.EPawnBenefitType.Shield] = 0;
return Table;
end
---@param InPlayerKey PlayerKey
function UGCGameState:PawnApplyBuff(InPlayerKey)
local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(InPlayerKey);
Pawn:ApplyBuff("ApplyKillChange");
end
----------------------------------------- MINI -----------------------------------------
UGCGameState.MiniModeState = nil;
--- 当前选择的 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 self.MiniGameManager then
self.MiniGameManager:LoadMiniGame(self.CurrMiniType);
end
end
function UGCGameState:SetMiniModeState(InState)
self.MiniModeState = InState;
DOREPONCE(self, "MiniModeState");
end
function UGCGameState:GetMiniModeState()
return self.MiniModeState;
end
function UGCGameState:OnRep_MiniModeState(Old)
if self.MiniGameManager then
self.MiniGameManager.State = self.MiniModeState;
self.MiniGameManager:OnRep_State(Old);
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, ...)
table.func(self.MiniGameManager, InFuncName, ...)
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
-- 发送出去
if self.MiniGameManager then
self.MiniGameManager.MiniInfo = self.MiniInfo;
self.MiniGameManager:OnRep_MiniInfo(InOld);
end
end
--- 获取 MiniGame 的数据
function UGCGameState:GetMiniInfo(Name)
if self.MiniGameManager then
return table.func(self.MiniGameManager, "GetMiniInfo", Name);
end
return nil;
end
--- 获取配置
function UGCGameState:GetMiniConfig(Name)
if self.MiniGameManager then
return table.func(self.MiniGameManager, "GetMiniInfo", Name);
end
return nil;
end
return UGCGameState;