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

867 lines
25 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.

---@type table<string, UClass>
---@private
UE.CachedClasses = {};
--- 组件位置
UE.ComponentPath = {
Camera = "/Script/Engine.CameraComponent",
SpringArm = "/Script/Engine.SpringArmComponent",
ChildActor = "/Script/Engine.ChildActorComponent",
Scene = "/Script/Engine.SceneComponent",
Actor = "/Script/Engine.ActorComponent",
}
UE.ResetClassPath = {
"PlayerTombBox", -- 玩家死亡盒子基类
"PickUpWrapperActor", -- 可拾取物的基类
"EliteProjectile", -- 投掷物的基类
"BurningSpreading", -- 燃烧弹的东西
"TslDamageField", -- 燃烧弹的东西
};
UE.DoorClassBaseName = "PUBGDoor";
UE.HouseClassBaseName = "STExtraHouseActor";
---@param InInfo PlayerAccountInfo
---@return PlayerAccountInfo
function UE.HandleAccountInfo(InInfo)
return {
UID = InInfo.UID,
PlayerName = InInfo.PlayerName,
TeamID = InInfo.TeamID,
Gender = InInfo.Gender,
--PlatformGender = InInfo.PlatformGender,
PlayerLevel = InInfo.PlayerLevel,
--SegmentLevel = InInfo.SegmentLevel,
IconURL = InInfo.IconURL,
};
end
function UE.GetPlayerUID(PlayerKey)
local Info = UE.GetAccountInfo(PlayerKey);
if Info then return Info.UID; end
return -1;
end
function UE.GetPlayerName(PlayerKey)
local Info = UE.GetAccountInfo(PlayerKey);
if Info then return Info.PlayerName; end
return "";
end
function UE.GetPlayerIconURL(PlayerKey)
local Info = UE.GetAccountInfo(PlayerKey);
if Info then return Info.IconURL; end
return '';
end
function UE.GetTeamID(PlayerKey)
local Info = UE.GetAccountInfo(PlayerKey);
if Info then return Info.TeamID end
UGCLogSystem.Log("[UE.GetTeamID] 无法找到 PlayerKey = %s", tostring(PlayerKey));
return nil;
end
function UE.GetPlayerGender(PlayerKey)
local Info = UE.GetAccountInfo(PlayerKey);
if Info then return Info.Gender end
return nil;
end
function UE.GetPlayerAvatarBoxId(PlayerKey)
local Info = UE.GetAccountInfo(PlayerKey);
if Info then return Info.AvatarBoxId; end
return nil;
end
function UE.GetPlayerLevel(PlayerKey)
local Info = UE.GetAccountInfo(PlayerKey);
if Info then return Info.PlayerLevel; end
return nil;
end
function UE.GetPlayerTeamID(PlayerKey)
return UE.GetTeamID(PlayerKey);
end
---@class SoloKingArchiveData
---@field TotalGameTimes int32
---@field GameTimes int32
---@field Weapons table<ItemId, ItemId[]>
---@field Score int32
---@field WinTimes int32
---@field GameWinTimes int32
---@field Kill int32
---@field Dead int32
---@field Last10Games table<any>
---@field HideScore int32
---@field CurSeason int32
---@field Seasons table
---@field Friends table
---@field IsNewSeason table
---@field LastSelectMap table
---@field Disables
---@field SelectWeapons table 选择的武器
---@field LastSelectWeapons table 最后选择过的武器
---@field SelectMaps table 选择过的地图
---@field sw_version int32 选择武器版本
---@field PlayerEnableShovel bool 玩家是否可以滑铲
---@field SeasonInfo table 补分用
---@field NoSelectMaps table 未选中的地图
---@return SoloKingArchiveData
function UE.InitArchiveData()
return {
TotalGameTimes = 0; -- 经典模式游玩次数,同步
GameTimes = 0, -- 游玩次数(包含所有模式)不同步
Weapons = {}, -- 武器配件 不同步
Score = DefaultSettings.RankScore, -- 默认 2000分 同步
WinTimes = 0, -- 一共获胜次数 不同步
GameWinTimes = 0, -- 经典模式获胜次数 同步
Kill = 0, -- 总击杀数 同步
Dead = 0, -- 总死亡数 同步
HideScore = 0, -- 隐藏分 同步
Disables = {};
-- 最后十局战绩
Last10Games = {}, -- 历史十局 同步
CurSeason = 0; -- 默认赛季 不同步
--- 赛季信息
Seasons = {}; -- 历史赛季 同步
IsNewSeason = false; -- 是否是新的赛季,在游戏结束的时候 同步
Friends = {}; -- 玩家对战过的玩家 同步
SeasonInfo = {}, -- 赛季信息现在使用第1槽
sw_version = 1; -- 选择武器的版本 不同步
SelectWeapons = {}; -- 玩家选择过的武器以及胜率 同步
NoSelectMaps = {};
};
end
UE.ValidRepNames = {
"TotalGameTimes",
"Score",
};
function UE.MakeSelectWeapon(InList)
if InList[7] then
return UE.MakeSelectWeapon_Archive(InList);
end
return {
SelectCount = InList[1][1], -- 选择的次数 可以证明喜好程度
UseCount = InList[1][2], -- 使用次数,局数
WinCount = InList[1][3], -- 获胜次数 胜率 = 获胜次数 / 使用次数
ShootCount = InList[2][1], -- 射击数
HitCount = InList[2][2], -- 击中数:击中率 = 击中数 / 射击数
HeavyHit = InList[2][3], -- 暴击数:暴击率 = 暴击数 / 击中数
TotalDamage = InList[3][1], -- 总伤害
}
end
function UE.MakeSelectWeapon_Archive(InList)
return {
SelectCount = InList[1] or 0,
UseCount = InList[2] or 0,
WinCount = InList[3] or 0,
ShootCount = InList[4] or 0,
HitCount = InList[5] or 0,
HeavyHit = InList[6] or 0,
TotalDamage = InList[7] or 0,
}
end
function UE.MakeSelectWeapon_Old2New(InList)
if InList[7] == nil then
return {
[1] = InList[1][1] or 0, -- 选择的次数 可以证明喜好程度
[2] = InList[1][2] or 0, -- 使用次数,局数
[3] = InList[1][3] or 0, -- 获胜次数 胜率 = 获胜次数 / 使用次数
[4] = InList[2][1] or 0, -- 射击数
[5] = InList[2][2] or 0, -- 击中数:击中率 = 击中数 / 射击数
[6] = InList[2][3] or 0, -- 暴击数:暴击率 = 暴击数 / 击中数
[7] = InList[3][1] or 0, -- 总伤害
}
else
return InList;
end
end
function UE.MakeSeason(InList)
return {
SeasonIndex = InList[1],
Score = InList[2][1], -- 分数
HideScore = InList[2][2],
GameTimes = InList[3][1],
WinTimes = InList[3][2],
Kill = InList[4][1],
Dead = InList[4][2],
--KD = InList[4][1] / (InList[4][2] == 0 and 1 or InList[4][2]);
};
end
--- 创建朋友属性(怕在局外不能获取,所以才保存的)
function UE.MakeFriend(InList)
return {
PlayerName = InList[1],
IconURL = InList[2],
}
end
--- 注意结构不能发生改变,否则会出错
function UE.MakeLastGame(InList)
UGCLogSystem.LogTree(string.format("[UE.MakeLastGame] InList ="), InList)
local GameInfos = InList[6];
local GameInfo = { };
for i = 1, #GameInfos do
local Info = GameInfos[i];
table.insert(GameInfo, {
IsWin = Info[1],
WeaponID = Info[2],
RoundScore = {
MyScore = Info[3][1],
EnemyScore = Info[3][2],
},
})
end
return {
IsWin = InList[1],
UID = InList[2][1],
GameScore = {
MyScore = InList[3][1],
EnemyScore = InList[3][2],
},
Score = InList[4][1],
AddScore = InList[4][2],
KD = InList[5][1] / (InList[5][2] == 0 and 1 or InList[5][2]),
GameInfo = GameInfo,
}
end
function UE.MakeLastGame_Archive(InList)
local GameInfos = InList[9];
local GameInfo = { };
for i = 1, #GameInfos do
local Info = GameInfos[i];
table.insert(GameInfo, {
IsWin = Info[1],
WeaponID = Info[2],
RoundScore = {
MyScore = Info[3],
EnemyScore = Info[4],
},
})
end
local Kill = InList[7]
local Dead = InList[8]
return {
IsWin = InList[1],
UID = InList[2],
GameScore = {
MyScore = InList[3],
EnemyScore = InList[4],
},
Score = InList[5],
AddScore = InList[6],
KD = (Kill or 0) / (Dead == 0 and 1 or Dead),
GameInfo = GameInfo,
}
end
-- 转化为单一数组
function UE.MakeArchive_LastGame(InList)
local List = {};
if InList[6] then
for i = 1, #(InList[6]) do
List[i] = {
InList[6][1],
InList[6][2],
InList[6][3][1],
InList[6][3][2],
}
end
end
return {
[1] = InList[1],
[2] = InList[2][1],
[3] = InList[3][1],
[4] = InList[3][2],
[5] = InList[4][1],
[6] = InList[4][2],
[7] = InList[5][1],
[8] = InList[5][2],
[9] = List,
}
end
--- 转化回原来的
function UE.MakeList_LastGame(InList)
local GameInfo = {};
for i = 1, #(InList[11]) do
local Info = InList[11][i];
GameInfo[i] = {
[1] = Info[1],
[2] = Info[2],
[3] = {
Info[3],
Info[4],
}
}
end
return {
[1] = InList[1],
[2] = {
InList[2],
InList[3],
InList[4],
},
[3] = {
InList[5],
InList[6],
},
[4] = {
InList[7],
InList[8],
},
[5] = {
InList[9],
InList[10],
},
[6] = GameInfo,
}
end
---@param InClass UClass<AActor>
---@param InTable table<int32, AActor> 获得的
---@param InFunc fun(InIndex:int32, InActor:AActor): bool
---@return table<int32, AActor>
function UE.FindActorsByClass(InClass, InTable, InFunc)
if InTable == nil then InTable = {}; end
local AllActors = {};
GameplayStatics.GetAllActorsOfClass(UGCGameSystem.GameState, InClass, AllActors);
for i, v in pairs(AllActors) do if InFunc == nil or InFunc(i, v) then table.insert(InTable, v); end end
return InTable;
end
---@param InTable table<int32, AActor>
---@param InTag FName
---@param InFunc fun(InActor: AActor): bool
---@return table<int32, AActor>
function UE.FindActorsByTag(InTag, InTable, InFunc)
if table.isEmpty(InTable) then InTable = {}; end
local AllActors = {};
GameplayStatics.GetAllActorsWithTag(UGCGameSystem.GameState, InTag, AllActors);
for i, v in pairs(AllActors) do if InFunc == nil or InFunc(v) then table.insert(InTable, v); end end
return InTable;
end
---@param InTag FName
---@param InFunc fun(InActor: AActor): bool
---@return table<int32, AActor>
function UE.FindActorByTag(InTag, InFunc)
local AllActors = {};
GameplayStatics.GetAllActorsWithTag(UGCGameSystem.GameState, InTag, AllActors);
for i, v in pairs(AllActors) do if InFunc == nil or InFunc(v) then return v; end end
return nil;
end
---@param InClass UClass<AActor>
---@param InFunc fun(InIndex:int32, InActor:AActor): bool
---@return AActor
function UE.FindActorByClass(InClass, InFunc)
local Table = {};
UE.FindActorsByClass(InClass, Table, InFunc);
if table.isEmpty(Table) then return nil; end
return Table[1];
end
---@type table<UClass, AActor>
UE.GlobalCachedActor = {};
---@param InClass UClass
---@return nil | AActor
function UE.FindOrCreateActorByClass(InClass, bDestroyOther)
print(string.format('[UE.FindOrCreateActorByClass] 开始执行, ClassName = %s', UE.GetName(InClass)));
if InClass == nil then return nil; end
local CachedActor = UE.GlobalCachedActor[InClass];
if CachedActor ~= nil and UE.IsValid(CachedActor) then return CachedActor; end
local Actors = {}
UE.FindActorsByClass(InClass, Actors);
local Actor = nil;
for i, v in pairs(Actors) do
Actor = v;
if Actor ~= v and bDestroyOther then v:K2_DestroyActor(); end
end
if Actor ~= nil then
UE.GlobalCachedActor[InClass] = Actor;
return Actor;
end
return UE.CreateActor(InClass);
end
---@param ClassPath string 类路径
---@return UClass | nil
function UE.CachedLoadClass(ClassPath)
if UE.CachedClasses[ClassPath] == nil then UE.CachedClasses[ClassPath] = UE.LoadClass(ClassPath); end
if UE.CachedClasses[ClassPath] == nil then
print(string.format('[UE.CachedLoadClass] Error Cant Load Class By Path: %s', ClassPath));
return nil;
end
return UE.CachedClasses[ClassPath];
end
function UE.CreateActor(InClass, InCount, InOuter)
if InOuter == nil then InOuter = UGCGameSystem.GameState; end
if InCount == nil then InCount = 1 end
local Actors = {};
for i = 1, InCount do table.insert(Actors, UE.SpawnActor(InClass, InOuter)) end
if InCount == 1 then return Actors[1]; end
return Actors;
end
---@param InClass UClass
---@param Loc FVector
---@param Rot FRotator
---@param Scale FVector
function UE.SpawnActor(InClass, InOuter, Loc, Rot, Scale)
Loc = Loc == nil and VectorHelper.MakeVector1(0);
Rot = Rot == nil and VectorHelper.MakeRotator(VectorHelper.MakeVector1(0));
Scale = Scale == nil and VectorHelper.MakeVector1(1);
if InOuter == nil then InOuter = GameState; end
return ScriptGameplayStatics.SpawnActor(InOuter, InClass, Loc, Rot, Scale);
end
--- 玩家重生
---@param InPlayerKey PlayerKey
---@param InTime float
function UE.RespawnPlayer(InPlayerKey, InTime)
if InTime <= 0 then
local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(InPlayerKey);
if Pawn then Pawn:K2_DestroyActor(); end
UGCGameSystem.RespawnPlayer(InPlayerKey);
else
UGCEventSystem.SetTimer(GameState, function()
local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(InPlayerKey);
if Pawn then Pawn:K2_DestroyActor(); end
UGCGameSystem.RespawnPlayer(InPlayerKey);
end, InTime);
end
end
--- 获取当前时间
function UE.GetCurrentTime() return KismetSystemLibrary.GetGameTimeInSeconds(UGCGameSystem.GameState); end
---@param InPlayerKey PlayerKey|nil
---@return PlayerAccountInfo|table<PlayerKey, PlayerAccountInfo>
function UE.GetAccountInfo(InPlayerKey)
if InPlayerKey == nil then return AccountTable; end
return AccountTable[InPlayerKey];
end
---@param InPlayerKey PlayerKey | nil
---@return table<PlayerKey, PlayerAccountInfo> | PlayerAccountInfo
function UE.GetArchiveData(InPlayerKey)
if InPlayerKey == nil then return ArchiveTable; end
return ArchiveTable[InPlayerKey];
end
--- 移动玩家到某个地方
---@param InPawn UGCPlayerPawn_C
---@param Location FVector
---@param Rotation FRotator
function UE.MovePlayerToLocation(InPawn, Location, Rotation)
if InPawn == nil then return end
InPawn:bShouldDumpCallstackWhenMovingfast_Tofalse()
InPawn:SetClientLocationOrRotation(Location, Rotation, true, Rotation ~= nil, false);
InPawn:bShouldDumpCallstackWhenMovingfast_ToTrue()
end
function UE.GetComponentClass(InName)
if UE.ComponentClasses[InName] == nil then
local Path = UE.ComponentPath[InName] == nil and InName or UE.ComponentPath[InName];
UE.ComponentClasses[InName] = LoadClass(Path);
end
return UE.ComponentClasses[InName]
end
UE.ComponentClasses = {};
--- 遍历 Actor 上面的所有组件
---@param InActor AActor
---@param InComponent UActorComponent
---@param cb fun(c: UActorComponent)
function UE.ForeachComponent(InActor, InComponent, cb)
local Class = UE.GetComponentClass(InComponent)
UGCLogSystem.Log("[UE.ForeachComponent] ClassName = %s", UE.GetName(Class));
for i, v in pairs(InActor:GetComponentsByClass(Class)) do
UGCLogSystem.Log("[UE.ForeachComponent] Component Name = %s", UE.GetName(v))
cb(v);
end
end
function UE.GetActorComponents(InActor, InTable)
local Components = InActor:GetComponentsByClass(UE.GetComponentClass("Actor"));
if InTable == nil then InTable = {}; end
for i, Comp in pairs(Components) do
UE.GetChildComponents(Comp, InTable);
end
return InTable;
end
---@param InComponent USceneComponent
function UE.GetChildComponents(InComponent, InTable)
-- 拿到所有
if InTable == nil then InTable = {}; end
local Count = InComponent:GetNumChildrenComponents()
if Count > 0 then
for i = 1, Count do
local Comp = InComponent:GetChildComponent(i - 1);
table.insert(InTable, Comp);
UE.GetChildComponents(Comp, InTable);
end
end
end
--- 组件朝向玩家, 如果朝向玩家,那么锁的是 Pitch 轴
---@param InComponent USceneComponent
---@param InActor AActor
---@param Lock string
function UE.ComponentTowardActor(InComponent, InActor, Lock)
if InComponent == nil then return ; end
local Rot = KismetMathLibrary.Conv_VectorToRotator(VectorHelper.Sub(InActor:K2_GetActorLocation(), InComponent:GetOwner():K2_GetActorLocation()));
if Lock ~= nil then
if Lock == 'Z' or Lock == 'Yaw' then
Rot = { Roll = Rot.Roll, Pitch = Rot.Pitch, Yaw = 0 };
elseif Lock == 'Y' or Lock == 'Pitch' then
Rot = { Roll = Rot.Roll, Pitch = 0, Yaw = Rot.Yaw };
elseif Lock == 'X' or Lock == 'Roll' then
Rot = { Roll = 0, Pitch = Rot.Pitch, Yaw = Rot.Yaw };
end
end
InComponent:K2_SetWorldRotation(Rot);
end
--- 获取服务器时间
function UE.GetServerTime()
if UGCGameSystem.GameState then return UGCGameSystem.GameState:GetServerTime(); end
return nil
end
---@param InTable table<int32|string, AActor>
---@param InFunc fun(InActor:AActor):bool
function UE.DestroyTable(InTable, InFunc)
if table.isEmpty(InTable) then return ; end
for i, v in pairs(InTable) do if InFunc == nil or InFunc(v) then v:K2_DestroyActor(); end end
InTable = {};
end
function UE.IsPlayerPawn(InPawn) return UE.IsA(InPawn, ObjectPath.UGCPlayerPawn) end
function UE.ReturnToLobby()
NetUtil.SendPkg("giveup_enter_game");
LobbySystem.ReturnToLobby();
end
function UE.LoadClass1(Path, cb)
local Class
UE.LoadClass(Path);
if cb ~= nil then cb(Class); end
return Class
end
UE.AsyncCachedItems = {};
---@param Path string
---@param cb fun(TargetClass: UClass)
function UE.AsyncLoadClass(Path, cb)
if cb == nil then return end
if UE.AsyncCachedItems[Path] then
cb(UE.AsyncCachedItems[Path]);
return ;
end
CommonUtils:AsyncLoadClass(UGCGameSystem.GameState, Path, function(TargetClass)
if TargetClass and UE.IsValid(TargetClass) then cb(TargetClass); end
end)
end
---@param Path string
---@param cb fun(TargetClass: UClass)
function UE.AsyncLoadClass_Cached(Path, cb)
if UE.AsyncCachedItems[Path] ~= nil then
if cb then cb(UE.AsyncCachedItems[Path]); end
return ;
end
if cb == nil then return end
CommonUtils:AsyncLoadClass(UGCGameSystem.GameState, Path, function(TargetClass)
if TargetClass and UE.IsValid(TargetClass) then
UE.AsyncCachedItems[Path] = TargetClass;
if cb then cb(UE.AsyncCachedItems[Path]); end
end
end)
end
---@param Path string
---@param cb fun(TargetObject: UObject)
function UE.AsyncLoadObject(Path, cb)
if cb == nil then return end
if UE.AsyncCachedItems[Path] then
cb(UE.AsyncCachedItems[Path]);
return ;
end
CommonUtils:AsyncLoadObject(UGCGameSystem.GameState, Path, function(TargetObject)
if TargetObject and UE.IsValid(TargetObject) then cb(TargetObject); end
end)
end
---@param Path string
---@param cb fun(TargetObject: UObject)
function UE.AsyncLoadObject_Cached(Path, cb)
if UE.AsyncCachedItems[Path] ~= nil then
if cb then cb(UE.AsyncCachedItems[Path]); end
return ;
end
CommonUtils:AsyncLoadObject(UGCGameSystem.GameState, Path, function(TargetObject)
if TargetObject and UE.IsValid(TargetObject) then
UE.AsyncCachedItems[Path] = TargetObject;
if cb then cb(TargetObject); end
end
end)
end
-- New ---------------------------------------
-- 20241020写入
---@param AssetPath:string
---@param CallBackFunc:fun(LoadObject:UObject,resID:int32)
---@param Obj:table CallBackFunc拥有者
---@param SaveAsset:bool 是否保存
function UE.AsyncLoadAsset_New(AssetPath, CallBackFunc, Obj, SaveAsset)
if not UE.IsValid(UE.AsyncCachedItems[AssetPath]) then
local softObjPath = KismetSystemLibrary.MakeSoftObjectPath(AssetPath);
STExtraBlueprintFunctionLibrary.GetAssetByAssetReferenceAsync(softObjPath,
ObjectExtend.CreateDelegate(UGCGameSystem.GameState, function(LoadObject, resID)
if CallBackFunc then
if Obj ~= nil then CallBackFunc(Obj, LoadObject) else CallBackFunc(LoadObject) end
end
if UE.IsValid(LoadObject) and SaveAsset then UE.AsyncCachedItems[AssetPath] = LoadObject end
end), true);
else
if CallBackFunc then
if Obj ~= nil then CallBackFunc(Obj, UE.AsyncCachedItems[AssetPath]) else CallBackFunc(UE.AsyncCachedItems[AssetPath]) end
end
end
end
---@param AssetPath:string
---@param SaveAsset:bool 是否保存
function UE.LoadAsset_New(AssetPath, SaveAsset)
if SaveAsset == nil then SaveAsset = true end
if not UE.IsValid(UE.AsyncCachedItems[AssetPath]) then
local TargetAsset = UE.LoadObject(AssetPath)
if SaveAsset and UE.IsValid(TargetAsset) then UE.AsyncCachedItems[AssetPath] = TargetAsset end
return TargetAsset
else
return UE.AsyncCachedItems[AssetPath]
end
end
-- New End -------------------------------------
function UE.AsyncLoadObj(Path, cb)
CommonUtils:AsyncLoadObject(UGCGameSystem.GameState, Path, function(TargetObject)
if TargetObject and UE.IsValid(TargetObject) then
if cb then cb(TargetObject); end
end
end)
end
--- 移除
function UE.ClearSceneObjects()
for i, v in pairs(UE.ResetClassPath) do
local Class = ScriptGameplayStatics.FindClass(v);
if UE.IsValid(Class) then
local Actors = {};
UE.FindActorsByClass(Class, Actors);
for c, Actor in pairs(Actors) do
Actor:K2_DestroyActor();
end
end
end
end
---@param InFunc fun(Pawn:UGCPlayerPawn_C)
function UE.ForeachAllPawns(InFunc)
for i, Pawn in pairs(UGCGameSystem.GetAllPlayerPawn()) do
if UE.IsValidPawn(Pawn) then InFunc(Pawn); end
end
end
---@param InPawn UGCPlayerPawn_C
function UE.IsValidPawn(InPawn)
return InPawn ~= nil and UE.IsValid(InPawn) and InPawn:IsAlive();
end
UE.ResetGameTimer = nil;
--- 游戏重置
function UE.ResetGame(InTime)
UGCLogSystem.Log("[UE.ResetGame] 重置游戏")
UE.ClearSceneObjects()
if IsServer then
-- 检测是否人数够
if GlobalCheckPlayers then GlobalCheckPlayers:OnCheckPlayers(); end
UE.RespawnAllPlayer(InTime);
end
end
UE.RespawnPlayersTimer = nil;
function UE.RespawnPlayers(InPlayerList, InTime)
if InTime <= 0 then
-- 立刻重生
for i, v in pairs(InPlayerList) do
UE.RespawnPlayer(v, 0);
end
else
UGCEventSystem.SetTimer(GameState, function()
for _, PlayerKey in pairs(InPlayerList) do
UE.RespawnPlayer(v, 0);
end
end, InTime);
end
end
---@param InFunc fun(PC:UGCPlayerController_C)
function UE.ForeachAllPCs(InFunc)
for i, PC in pairs(UGCGameSystem.GetAllPlayerController(false)) do
if PC and UE.IsValid(PC) then InFunc(PC); end
end
end
function UE.RespawnAllPlayer(InTime)
if InTime == nil or InTime <= 0 then
UE.ForeachAllPCs(function(PC)
local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PC.PlayerKey);
if Pawn then Pawn:K2_DestroyActor(); end
UGCGameSystem.RespawnPlayer(PC.PlayerKey);
end);
else
UGCEventSystem.SetTimer(GameState, function()
UE.ForeachAllPCs(function(PC)
local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PC.PlayerKey);
if Pawn then Pawn:K2_DestroyActor(); end
UGCGameSystem.RespawnPlayer(PC.PlayerKey);
end)
end, InTime);
end
end
-- 防止鞭尸
function UE.ClearWeapons(InPawn)
ItemTool.ClearAllWeapon(InPawn);
end
function UE.HasPlayer(InPlayerKey)
return UE.GetAccountInfo(InPlayerKey) ~= nil;
end
UE.ResetGameTimer = nil;
function UE.CanReset()
return UE.ResetGameTimer == nil;
end
function UE.ResetGameInterval(Force, InTime, InFunc)
local PawnCount = 0;
for i, v in pairs(UGCGameSystem.GetAllPlayerPawn()) do
if UE.IsValidPawn(v) then PawnCount = PawnCount + 1; end
end
if PawnCount < 2 or Force then
UGCLogSystem.Log("[UE.ResetGameInterval] 所有玩家重置")
-- 检查是否是只有一个玩家
local AlivePawnCount = table.getCount(UGCGameSystem.GetAllPlayerController(false));
if AlivePawnCount <= 1 then
-- 关闭
if GlobalCheckPlayers then
GlobalCheckPlayers:OnCheckPlayers();
end
if UE.ResetGameTimer ~= nil then
-- 关闭重置 Timer
if InFunc then InFunc(); end
UGCLogSystem.Log("[UE.ResetGameInterval] 关闭重置玩家 Timer")
UGCEventSystem.StopTimer(UE.ResetGameTimer);
UE.ResetGameTimer = nil;
end
return ;
end
UE.ResetGame(InTime); -- 检查是否可以复活
if PoisonManager then
UGCLogSystem.Log("[UE.ResetGameInterval] 重置毒圈")
PoisonManager:Toggle(true); -- 确保没事了再刷新毒圈
end
end
if PawnCount == 2 and not Force then
-- 关闭
if UE.ResetGameTimer ~= nil then
-- 关闭重置 Timer
if InFunc then InFunc(); end
UGCLogSystem.Log("[UE.ResetGameInterval] 关闭重置玩家 Timer")
UGCEventSystem.StopTimer(UE.ResetGameTimer);
UE.ResetGameTimer = nil;
end
end
end
---@param InFunc fun() 完全重置之后再执行的函数
function UE.ResetGame1(InTime, InFunc)
-- 首先执行一遍,
UGCLogSystem.Log("[UE.ResetGame1] 开始重置")
UE.ResetGameInterval(true, InTime, InFunc);
if UE.CanReset() then
UGCLogSystem.Log("[UE.ResetGame1] 可以执行重置")
UE.ResetGameTimer = UGCEventSystem.SetTimerLoop(GameState, function()
UE.ResetGameInterval(false, InTime, InFunc);
end, 1);
end
end
function UE.GetMiniRepData(InKey)
if not table.isEmpty(GameState.MiniInfo) then
return GameState.MiniInfo[InKey];
end
return nil;
end
function UE.CloseServer()
-- 检查玩家是否退出了
UGCEventSystem.SetTimer(UGCGameSystem.GameState, function()
UGCGameSystem.SendModeCustomEvent("GameOver"); -- 直接关闭
end, 6);
end
function UE.GetClassByName(InName)
local Class = ScriptGameplayStatics.FindClass(InName)
if Class and UE.IsValid(Class) then return Class; end
return nil;
end
function UE.OnCloseDS()
--停止检测DS连接
if NetUtil then NetUtil.StopCheckDSActive(); end
--忽略DS链接报错
if BattleResult then BattleResult.IgnoreDSError = true; end
end