1
0
This commit is contained in:
GenZmeY 2023-10-05 22:10:47 +03:00
commit 3fd6bcf7d8
Signed by: GenZmeY
GPG Key ID: 424DA4BC3CB2CF39
9 changed files with 362 additions and 0 deletions

120
Classes/SkinReplicator.uc Normal file
View File

@ -0,0 +1,120 @@
class SkinReplicator extends Info;
var private Array<SkinReplicatorRepInfo> RepInfos;
var private E_LogLevel LogLevel;
public simulated function bool SafeDestroy()
{
`Log_Trace();
return (bPendingDelete || bDeleteMe || Destroy());
}
public event PreBeginPlay()
{
`Log_Trace();
if (WorldInfo.NetMode == NM_Client)
{
`Log_Fatal("NetMode == NM_Client, Destroy...");
SafeDestroy();
return;
}
Super.PreBeginPlay();
PreInit();
}
public event PostBeginPlay()
{
`Log_Trace();
if (bPendingDelete || bDeleteMe) return;
Super.PostBeginPlay();
PostInit();
}
private function PreInit()
{
`Log_Trace();
if (LogLevel == LL_WrongLevel)
{
LogLevel = LL_Info;
`Log_Warn("Wrong 'LogLevel', return to default value");
SaveConfig();
}
`Log_Base("LogLevel:" @ LogLevel);
}
private function PostInit()
{
`Log_Trace();
}
public function NotifyLogin(Controller C)
{
`Log_Trace();
if (!CreateRepInfo(C))
{
`Log_Error("Can't create RepInfo for:" @ C);
}
}
public function NotifyLogout(Controller C)
{
`Log_Trace();
DestroyRepInfo(C);
}
public function bool CreateRepInfo(Controller C)
{
local SkinReplicatorRepInfo RepInfo;
`Log_Trace();
if (C == None || KFPlayerController(C) == None) return false;
RepInfo = Spawn(class'SkinReplicatorRepInfo', C);
if (RepInfo == None) return false;
RepInfo.LogLevel = LogLevel;
RepInfo.SkinReplicator = Self;
RepInfos.AddItem(RepInfo);
return true;
}
public function bool DestroyRepInfo(Controller C)
{
local SkinReplicatorRepInfo RepInfo;
`Log_Trace();
if (C == None) return false;
foreach RepInfos(RepInfo)
{
if (RepInfo.Owner == C)
{
RepInfos.RemoveItem(RepInfo);
RepInfo.SafeDestroy();
return true;
}
}
return false;
}
DefaultProperties
{
LogLevel = LL_Info
}

View File

@ -0,0 +1,4 @@
[Flags]
AllowDownload=True
ClientOptional=False
ServerSideOnly=False

View File

@ -0,0 +1,60 @@
class SkinReplicatorMut extends KFMutator;
var private SkinReplicator SkinReplicator;
public simulated function bool SafeDestroy()
{
return (bPendingDelete || bDeleteMe || Destroy());
}
public event PreBeginPlay()
{
Super.PreBeginPlay();
if (WorldInfo.NetMode == NM_Client) return;
foreach WorldInfo.DynamicActors(class'SkinReplicator', SkinReplicator)
{
break;
}
if (SkinReplicator == None)
{
SkinReplicator = WorldInfo.Spawn(class'SkinReplicator');
}
if (SkinReplicator == None)
{
`Log_Base("FATAL: Can't Spawn 'SkinReplicator'");
SafeDestroy();
}
}
public function AddMutator(Mutator Mut)
{
if (Mut == Self) return;
if (Mut.Class == Class)
SkinReplicatorMut(Mut).SafeDestroy();
else
Super.AddMutator(Mut);
}
public function NotifyLogin(Controller C)
{
SkinReplicator.NotifyLogin(C);
Super.NotifyLogin(C);
}
public function NotifyLogout(Controller C)
{
SkinReplicator.NotifyLogout(C);
Super.NotifyLogout(C);
}
DefaultProperties
{
}

View File

@ -0,0 +1,106 @@
class SkinReplicatorRepInfo extends ReplicationInfo
dependson(WeaponReplacements);
const Replacements = class'WeaponReplacements';
var public E_LogLevel LogLevel;
var public SkinReplicator SkinReplicator;
var private KFPlayerController KFPC;
var private KFPlayerReplicationInfo KFPRI;
replication
{
if (bNetInitial && Role == ROLE_Authority)
LogLevel;
}
public simulated function bool SafeDestroy()
{
`Log_Trace();
return (bPendingDelete || bDeleteMe || Destroy());
}
public simulated event PostBeginPlay()
{
if (WorldInfo.NetMode == NM_StandAlone || Role <= ROLE_Authority)
{
SetTimer(1.0f, true, nameof(UpdateSkinsDLC));
}
}
private simulated function UpdateSkinsDLC()
{
local SWeapReplace WeapReplace;
`Log_Debug("Wait for spawn");
if (GetKFPRI() != None && KFPRI.bHasSpawnedIn)
{
foreach Replacements.default.List(WeapReplace)
{
if (WeapReplace.WeapParent.default.SkinItemId > 0 && WeapReplace.Weap.default.SkinItemId != WeapReplace.WeapParent.default.SkinItemId)
{
`Log_Debug("Update skin for:" @ String(WeapReplace.WeapDef) @ "SkinId:" @ WeapReplace.WeapParent.default.SkinItemId);
class'KFWeaponSkinList'.static.SaveWeaponSkin(WeapReplace.WeapDef, WeapReplace.WeapParent.default.SkinItemId);
}
}
ClearTimer(nameof(UpdateSkinsDLC));
ClientCleanup();
}
}
private simulated function KFPlayerController GetKFPC()
{
`Log_Trace();
if (KFPC != None) return KFPC;
KFPC = KFPlayerController(Owner);
if (KFPC == None && ROLE < ROLE_Authority)
{
KFPC = KFPlayerController(GetALocalPlayerController());
}
return KFPC;
}
private simulated function KFPlayerReplicationInfo GetKFPRI()
{
`Log_Trace();
if (KFPRI != None) return KFPRI;
if (GetKFPC() == None) return None;
KFPRI = KFPlayerReplicationInfo(KFPC.PlayerReplicationInfo);
return KFPRI;
}
private simulated function ClientCleanup()
{
ServerCleanup();
SafeDestroy();
}
private reliable server function ServerCleanup()
{
`Log_Trace();
`Log_Debug("Cleanup");
if (!SkinReplicator.DestroyRepInfo(GetKFPC()))
{
`Log_Debug("Cleanup (forced)");
SafeDestroy();
}
}
defaultproperties
{
bAlwaysRelevant = false
bOnlyRelevantToOwner = true
bSkipActorPropertyReplication = false
}

View File

@ -0,0 +1,32 @@
class WeaponReplacements extends Object;
struct SWeapReplace
{
var const class<KFWeaponDefinition> WeapDef;
var const class<KFWeaponDefinition> WeapDefParent;
var const class<KFWeapon> Weap;
var const class<KFWeapon> WeapParent;
};
var public const Array<SWeapReplace> List;
// Example defaultproperties:
/*
List.Add({(
WeapDef=class'CTI_WeapDef_AutoTurret',
WeapDefParent=class'KFWeapDef_AutoTurret',
Weap=class'CTI_Weap_AutoTurret',
WeapParent=class'KFWeap_AutoTurret'
)})
List.Add({(
WeapDef=class'CTI_WeapDef_BladedPistol',
WeapDefParent=class'KFWeapDef_BladedPistol',
Weap=class'CTI_Weap_Pistol_Bladed',
WeapParent=class'KFWeap_Pistol_Bladed'
)})
*/
defaultproperties
{
}

20
Classes/_Logger.uc Normal file
View File

@ -0,0 +1,20 @@
class _Logger extends Object
abstract;
enum E_LogLevel
{
LL_WrongLevel,
LL_None,
LL_Fatal,
LL_Error,
LL_Warning,
LL_Info,
LL_Debug,
LL_Trace,
LL_All
};
defaultproperties
{
}

2
Constants.uci Normal file
View File

@ -0,0 +1,2 @@
// Constants
`define NO_CONFIG 0

3
Globals.uci Normal file
View File

@ -0,0 +1,3 @@
// Imports
`include(Logger.uci)
`include(Constants.uci)

15
Logger.uci Normal file
View File

@ -0,0 +1,15 @@
// Logger
`define Log_Tag 'SkinReplicator'
`define LocationStatic "`{ClassName}::" $ GetFuncName()
`define Log_Base(msg, cond) `log(`msg `if(`cond), `cond`{endif}, `Log_Tag)
`define Log_Fatal(msg) `log("FATAL:" @ `msg, (LogLevel >= LL_Fatal), `Log_Tag)
`define Log_Error(msg) `log("ERROR:" @ `msg, (LogLevel >= LL_Error), `Log_Tag)
`define Log_Warn(msg) `log("WARN:" @ `msg, (LogLevel >= LL_Warning), `Log_Tag)
`define Log_Info(msg) `log("INFO:" @ `msg, (LogLevel >= LL_Info), `Log_Tag)
`define Log_Debug(msg) `log("DEBUG:" @ `msg, (LogLevel >= LL_Debug), `Log_Tag)
`define Log_Trace(msg) `log("TRACE:" @ `Location `if(`msg) @ `msg`{endif}, (LogLevel >= LL_Trace), `Log_Tag)
`define Log_TraceStatic(msg) `log("TRACE:" @ `LocationStatic `if(`msg) @ `msg`{endif}, (LogLevel >= LL_Trace), `Log_Tag)