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

321 lines
10 KiB
Lua

---@type table<string, UClass>
---@private
UE.CachedClasses = {};
--- 组件位置
UE.ComponentPath = {
Camera = "/Script/Engine.CameraComponent",
SpringArm = "/Script/Engine.SpringArmComponent",
}
---@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
---@return table
function UE.InitArchiveData()
return {
GameTimes = 0,
}
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 == nil or InTime <= 0 then
local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(InPlayerKey);
if Pawn then Pawn:K2_DestroyActor(); end
UGCGameSystem.RespawnPlayer(InPlayerKey);
return;
end
UGCEventSystem.SetTimer(GameState, function()
local Pawn = UGCGameSystem.GetPlayerPawnByPlayerKey(InPlayerKey);
if Pawn then Pawn:K2_DestroyActor(); end
UGCGameSystem.RespawnPlayer(InPlayerKey);
end, InTime);
end
--- 获取当前时间
function UE.GetCurrentTime() return KismetSystemLibrary.GetGameTimeInSeconds(UGCGameSystem.GameState); end
---@param InPlayerKey PlayerKey
---@return PlayerAccountInfo
function UE.GetAccountInfo(InPlayerKey) return GameState.PlayerDatas.AccountInfo[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
--- 激活对应的 Camera
---@param InPawn UGCPlayerPawn_C
---@param InCamera UCameraComponent
---@param InArm USpringArmComponent
function UE.ActiveCamera(InPawn, InCamera, InArm)
if InPawn == nil then return end
UE.ForeachComponent(InPawn, UE.ComponentPath.Camera, function(c) c:Deactivate() end)
UE.ForeachComponent(InPawn, UE.ComponentPath.SpringArm, function(c) c:Deactivate() end)
InCamera:Activate();
InArm:Activate();
table.func(InPawn, "SetCurrentCamera", InCamera, InArm);
end
--- 遍历 Actor 上面的所有组件
---@param InActor AActor
---@param InComponent UActorComponent
---@param cb fun(c: UActorComponent)
function UE.ForeachComponent(InActor, InComponent, cb)
local Path = UE.ComponentPath[InComponent] == nil and InComponent or UE.ComponentPath[InComponent];
for i, v in pairs(InActor:GetComponentsByClass(LoadClass(Path))) do cb(v); end
end
---清空地图上的 Wrapper
function UE.ClearWrappers(bWeapon, bPart, bBullet, bEquipment, bSkin, bSupplies)
local AllActors = {};
local Func = function(b) if b == nil then return true end return b; end
bWeapon = Func(bWeapon);
bPart = Func(bPart);
bBullet = Func(bBullet);
bEquipment = Func(bEquipment);
bSkin = Func(bSkin);
bSupplies = Func(bSupplies);
UE.FindActorsByClass(GameState:GetWrapperClass(), AllActors, function(InIndex, InActor)
if InActor.DefineID == nil then return true; end
local ItemId = InActor.DefineID.TypeSpecificID;
if ItemId == nil or (not InActor.DefineID.bValidItem) then return true; end
UGCLogSystem.Log("[UE.ClearWrappers] ItemId = %s", tostring(ItemId));
local Type = GetCustomItemType(ItemId);
if (bWeapon and Type == ECustomItemType.Weapon) or
(bPart and Type == ECustomItemType.Part) or
(bBullet and Type == ECustomItemType.Bullet) or
(bEquipment and Type == ECustomItemType.Equipment) or
(bSkin and Type == ECustomItemType.Skin) or
(bSupplies and Type == ECustomItemType.Supplies) then
InActor:K2_DestroyActor()
end
end);
end
--- 组件朝向玩家
---@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