first version
This commit is contained in:
parent
590270cf89
commit
7edd65b3e0
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "tools"]
|
||||
path = tools
|
||||
url = https://github.com/GenZmeY/KF2-BuildTools
|
66
CTI/Classes/AddItems.uc
Normal file
66
CTI/Classes/AddItems.uc
Normal file
@ -0,0 +1,66 @@
|
||||
class AddItems extends Object
|
||||
dependson(CTI)
|
||||
config(CTI);
|
||||
|
||||
var private config Array<String> Item;
|
||||
|
||||
public static function InitConfig(int Version, int LatestVersion)
|
||||
{
|
||||
switch (Version)
|
||||
{
|
||||
case `NO_CONFIG:
|
||||
ApplyDefault();
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (LatestVersion != Version)
|
||||
{
|
||||
StaticSaveConfig();
|
||||
}
|
||||
}
|
||||
|
||||
private static function ApplyDefault()
|
||||
{
|
||||
default.Item.Length = 0;
|
||||
default.Item.AddItem("SomePackage.SomeWeapon");
|
||||
}
|
||||
|
||||
public static function Array<class<KFWeaponDefinition> > Load(E_LogLevel LogLevel)
|
||||
{
|
||||
local Array<class<KFWeaponDefinition> > ItemList;
|
||||
local class<KFWeaponDefinition> ItemClass;
|
||||
local String ItemRaw;
|
||||
local int Line;
|
||||
|
||||
`Log_Info("Load Items to add:");
|
||||
foreach default.Item(ItemRaw, Line)
|
||||
{
|
||||
ItemClass = class<KFWeaponDefinition>(DynamicLoadObject(ItemRaw, class'Class'));
|
||||
if (ItemClass == None)
|
||||
{
|
||||
`Log_Warn("[" $ Line + 1 $ "]" @ "Can't load Item class:" @ ItemRaw);
|
||||
}
|
||||
else
|
||||
{
|
||||
ItemList.AddItem(ItemClass);
|
||||
`Log_Debug("[" $ Line + 1 $ "]" @ "Loaded successfully:" @ ItemRaw);
|
||||
}
|
||||
}
|
||||
|
||||
if (ItemList.Length == default.Item.Length)
|
||||
{
|
||||
`Log_Info("Items to add list loaded successfully (" $ default.Item.Length @ "entries)");
|
||||
}
|
||||
else
|
||||
{
|
||||
`Log_Info("Items to add list: loaded" @ ItemList.Length @ "of" @ default.Item.Length @ "entries");
|
||||
}
|
||||
|
||||
return ItemList;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
|
||||
}
|
247
CTI/Classes/CTI.uc
Normal file
247
CTI/Classes/CTI.uc
Normal file
@ -0,0 +1,247 @@
|
||||
class CTI extends Info
|
||||
config(CTI);
|
||||
|
||||
const LatestVersion = 1;
|
||||
|
||||
const CfgRemoveItems = class'RemoveItems';
|
||||
const CfgAddItems = class'AddItems';
|
||||
const Helper = class'Helper';
|
||||
|
||||
var private config int Version;
|
||||
var private config E_LogLevel LogLevel;
|
||||
var private config bool bPreloadContent;
|
||||
var private config bool bForcePreloadContent;
|
||||
var private config bool UnlockDLC;
|
||||
|
||||
var private KFGameInfo KFGI;
|
||||
var private KFGameReplicationInfo KFGRI;
|
||||
|
||||
var private Array<class<KFWeaponDefinition> > RemoveItems;
|
||||
var private Array<class<KFWeaponDefinition> > AddItems;
|
||||
|
||||
var private Array<CTI_RepInfo> RepInfos;
|
||||
|
||||
var private bool ReadyToSync;
|
||||
|
||||
public simulated function bool SafeDestroy()
|
||||
{
|
||||
`Log_Trace(`Location);
|
||||
|
||||
return (bPendingDelete || bDeleteMe || Destroy());
|
||||
}
|
||||
|
||||
public event PreBeginPlay()
|
||||
{
|
||||
`Log_Trace(`Location);
|
||||
|
||||
`Log_Debug("PreBeginPlay readyToSync" @ ReadyToSync);
|
||||
|
||||
if (WorldInfo.NetMode == NM_Client)
|
||||
{
|
||||
`Log_Fatal("NetMode == NM_Client, Destroy...");
|
||||
SafeDestroy();
|
||||
return;
|
||||
}
|
||||
|
||||
Super.PreBeginPlay();
|
||||
|
||||
PreInit();
|
||||
}
|
||||
|
||||
public event PostBeginPlay()
|
||||
{
|
||||
`Log_Trace(`Location);
|
||||
|
||||
if (bPendingDelete || bDeleteMe) return;
|
||||
|
||||
Super.PostBeginPlay();
|
||||
|
||||
PostInit();
|
||||
}
|
||||
|
||||
private function PreInit()
|
||||
{
|
||||
`Log_Trace(`Location);
|
||||
|
||||
if (Version == `NO_CONFIG)
|
||||
{
|
||||
LogLevel = LL_Info;
|
||||
bPreloadContent = true;
|
||||
bForcePreloadContent = true;
|
||||
UnlockDLC = false;
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
CfgRemoveItems.static.InitConfig(Version, LatestVersion);
|
||||
CfgAddItems.static.InitConfig(Version, LatestVersion);
|
||||
|
||||
switch (Version)
|
||||
{
|
||||
case `NO_CONFIG:
|
||||
`Log_Info("Config created");
|
||||
|
||||
case MaxInt:
|
||||
`Log_Info("Config updated to version"@LatestVersion);
|
||||
break;
|
||||
|
||||
case LatestVersion:
|
||||
`Log_Info("Config is up-to-date");
|
||||
break;
|
||||
|
||||
default:
|
||||
`Log_Warn("The config version is higher than the current version (are you using an old mutator?)");
|
||||
`Log_Warn("Config version is" @ Version @ "but current version is" @ LatestVersion);
|
||||
`Log_Warn("The config version will be changed to" @ LatestVersion);
|
||||
break;
|
||||
}
|
||||
|
||||
if (LatestVersion != Version)
|
||||
{
|
||||
Version = LatestVersion;
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
if (LogLevel == LL_WrongLevel)
|
||||
{
|
||||
LogLevel = LL_Info;
|
||||
`Log_Warn("Wrong 'LogLevel', return to default value");
|
||||
SaveConfig();
|
||||
}
|
||||
`Log_Base("LogLevel:" @ LogLevel);
|
||||
|
||||
RemoveItems = CfgRemoveItems.static.Load(LogLevel);
|
||||
AddItems = CfgAddItems.static.Load(LogLevel);
|
||||
}
|
||||
|
||||
private function PostInit()
|
||||
{
|
||||
local CTI_RepInfo RepLink;
|
||||
|
||||
`Log_Trace(`Location);
|
||||
|
||||
if (WorldInfo == None || WorldInfo.Game == None)
|
||||
{
|
||||
SetTimer(1.0f, false, nameof(PostInit));
|
||||
return;
|
||||
}
|
||||
|
||||
KFGI = KFGameInfo(WorldInfo.Game);
|
||||
if (KFGI == None)
|
||||
{
|
||||
`Log_Fatal("Incompatible gamemode:" @ WorldInfo.Game);
|
||||
SafeDestroy();
|
||||
return;
|
||||
}
|
||||
|
||||
if (UnlockDLC && KFGI.KFGFxManagerClass != class'CTI_GFxMoviePlayer_Manager')
|
||||
{
|
||||
KFGI.KFGFxManagerClass = class'CTI_GFxMoviePlayer_Manager';
|
||||
`Log_Info("DLC unlocked");
|
||||
}
|
||||
|
||||
if (KFGI.GameReplicationInfo == None)
|
||||
{
|
||||
SetTimer(1.0f, false, nameof(PostInit));
|
||||
return;
|
||||
}
|
||||
|
||||
KFGRI = KFGameReplicationInfo(KFGI.GameReplicationInfo);
|
||||
if (KFGRI == None)
|
||||
{
|
||||
`Log_Fatal("Incompatible Replication info:" @ KFGI.GameReplicationInfo);
|
||||
SafeDestroy();
|
||||
return;
|
||||
}
|
||||
|
||||
Helper.static.ModifyTrader(KFGRI, RemoveItems, AddItems, CfgRemoveItems.default.bAll);
|
||||
|
||||
if (bPreloadContent)
|
||||
{
|
||||
Helper.static.PreloadContent(AddItems);
|
||||
}
|
||||
|
||||
ReadyToSync = true;
|
||||
|
||||
foreach RepInfos(RepLink)
|
||||
{
|
||||
if (RepLink.PendingSync)
|
||||
{
|
||||
RepLink.ServerSync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function NotifyLogin(Controller C)
|
||||
{
|
||||
`Log_Trace(`Location);
|
||||
|
||||
CreateRepLink(C);
|
||||
}
|
||||
|
||||
public function NotifyLogout(Controller C)
|
||||
{
|
||||
`Log_Trace(`Location);
|
||||
|
||||
DestroyRepLink(C);
|
||||
}
|
||||
|
||||
public function bool CreateRepLink(Controller C)
|
||||
{
|
||||
local CTI_RepInfo RepLink;
|
||||
|
||||
`Log_Trace(`Location);
|
||||
|
||||
if (C == None) return false;
|
||||
|
||||
RepLink = Spawn(class'CTI_RepInfo', C);
|
||||
|
||||
if (RepLink == None) return false;
|
||||
|
||||
RepLink.PrepareSync(
|
||||
Self,
|
||||
LogLevel,
|
||||
RemoveItems,
|
||||
AddItems,
|
||||
CfgRemoveItems.default.bAll,
|
||||
bPreloadContent,
|
||||
bForcePreloadContent);
|
||||
|
||||
RepInfos.AddItem(RepLink);
|
||||
|
||||
if (ReadyToSync)
|
||||
{
|
||||
RepLink.ServerSync();
|
||||
}
|
||||
else
|
||||
{
|
||||
RepLink.PendingSync = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function bool DestroyRepLink(Controller C)
|
||||
{
|
||||
local CTI_RepInfo RepLink;
|
||||
|
||||
`Log_Trace(`Location);
|
||||
|
||||
if (C == None) return false;
|
||||
|
||||
foreach RepInfos(RepLink)
|
||||
{
|
||||
if (RepLink.Owner == C)
|
||||
{
|
||||
RepLink.SafeDestroy();
|
||||
RepInfos.RemoveItem(RepLink);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
ReadyToSync = false
|
||||
}
|
4
CTI/Classes/CTI.upkg
Normal file
4
CTI/Classes/CTI.upkg
Normal file
@ -0,0 +1,4 @@
|
||||
[Flags]
|
||||
AllowDownload=True
|
||||
ClientOptional=False
|
||||
ServerSideOnly=False
|
62
CTI/Classes/CTIMut.uc
Normal file
62
CTI/Classes/CTIMut.uc
Normal file
@ -0,0 +1,62 @@
|
||||
class CTIMut extends KFMutator;
|
||||
|
||||
var private CTI CTI;
|
||||
|
||||
public simulated function bool SafeDestroy()
|
||||
{
|
||||
return (bPendingDelete || bDeleteMe || Destroy());
|
||||
}
|
||||
|
||||
public event PreBeginPlay()
|
||||
{
|
||||
Super.PreBeginPlay();
|
||||
|
||||
if (WorldInfo.NetMode == NM_Client) return;
|
||||
|
||||
foreach WorldInfo.DynamicActors(class'CTI', CTI)
|
||||
{
|
||||
`Log_Base("Found 'CTI'");
|
||||
break;
|
||||
}
|
||||
|
||||
if (CTI == None)
|
||||
{
|
||||
`Log_Base("Spawn 'CTI'");
|
||||
CTI = WorldInfo.Spawn(class'CTI');
|
||||
}
|
||||
|
||||
if (CTI == None)
|
||||
{
|
||||
`Log_Base("Can't Spawn 'CTI', Destroy...");
|
||||
SafeDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
public function AddMutator(Mutator Mut)
|
||||
{
|
||||
if (Mut == Self) return;
|
||||
|
||||
if (Mut.Class == Class)
|
||||
Mut.Destroy();
|
||||
else
|
||||
Super.AddMutator(Mut);
|
||||
}
|
||||
|
||||
public function NotifyLogin(Controller C)
|
||||
{
|
||||
Super.NotifyLogin(C);
|
||||
|
||||
CTI.NotifyLogin(C);
|
||||
}
|
||||
|
||||
public function NotifyLogout(Controller C)
|
||||
{
|
||||
Super.NotifyLogout(C);
|
||||
|
||||
CTI.NotifyLogout(C);
|
||||
}
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
|
||||
}
|
8
CTI/Classes/CTI_GFxMenu_Trader.uc
Normal file
8
CTI/Classes/CTI_GFxMenu_Trader.uc
Normal file
@ -0,0 +1,8 @@
|
||||
class CTI_GFxMenu_Trader extends KFGFxMenu_Trader
|
||||
dependsOn(CTI_GFxTraderContainer_Store);
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
SubWidgetBindings.Remove((WidgetName="shopContainer",WidgetClass=class'KFGFxTraderContainer_Store'))
|
||||
SubWidgetBindings.Add((WidgetName="shopContainer",WidgetClass=class'CTI_GFxTraderContainer_Store'))
|
||||
}
|
8
CTI/Classes/CTI_GFxMoviePlayer_Manager.uc
Normal file
8
CTI/Classes/CTI_GFxMoviePlayer_Manager.uc
Normal file
@ -0,0 +1,8 @@
|
||||
class CTI_GFxMoviePlayer_Manager extends KFGFxMoviePlayer_Manager
|
||||
dependsOn(CTI_GFxMenu_Trader);
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
WidgetBindings.Remove((WidgetName="traderMenu",WidgetClass=class'KFGFxMenu_Trader'))
|
||||
WidgetBindings.Add((WidgetName="traderMenu",WidgetClass=class'CTI_GFxMenu_Trader'))
|
||||
}
|
20
CTI/Classes/CTI_GFxTraderContainer_Store.uc
Normal file
20
CTI/Classes/CTI_GFxTraderContainer_Store.uc
Normal file
@ -0,0 +1,20 @@
|
||||
class CTI_GFxTraderContainer_Store extends KFGFxTraderContainer_Store;
|
||||
|
||||
function bool IsItemFiltered(STraderItem Item, optional bool bDebug)
|
||||
{
|
||||
if (KFPC.GetPurchaseHelper().IsInOwnedItemList(Item.ClassName))
|
||||
return true;
|
||||
if (KFPC.GetPurchaseHelper().IsInOwnedItemList(Item.DualClassName))
|
||||
return true;
|
||||
if (!KFPC.GetPurchaseHelper().IsSellable(Item))
|
||||
return true;
|
||||
if (Item.WeaponDef.default.PlatformRestriction != PR_All && class'KFUnlockManager'.static.IsPlatformRestricted(Item.WeaponDef.default.PlatformRestriction))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
|
||||
}
|
309
CTI/Classes/CTI_RepInfo.uc
Normal file
309
CTI/Classes/CTI_RepInfo.uc
Normal file
@ -0,0 +1,309 @@
|
||||
class CTI_RepInfo extends ReplicationInfo;
|
||||
|
||||
const Helper = class'Helper';
|
||||
|
||||
var public bool PendingSync;
|
||||
|
||||
var private CTI CTI;
|
||||
var private E_LogLevel LogLevel;
|
||||
var private Array<class<KFWeaponDefinition> > RemoveItems;
|
||||
var private Array<class<KFWeaponDefinition> > AddItems;
|
||||
var private bool ReplaceMode;
|
||||
var private bool PreloadContent;
|
||||
var private bool ForcePreloadContent;
|
||||
|
||||
var private int Recieved;
|
||||
var private int SyncSize;
|
||||
|
||||
var private KFGFxWidget_PartyInGame PartyInGameWidget;
|
||||
var private GFxObject Notification;
|
||||
|
||||
replication
|
||||
{
|
||||
if (bNetInitial && Role == ROLE_Authority)
|
||||
LogLevel, ReplaceMode, PreloadContent, ForcePreloadContent, SyncSize;
|
||||
}
|
||||
|
||||
public simulated function bool SafeDestroy()
|
||||
{
|
||||
`Log_Trace(`Location);
|
||||
|
||||
return (bPendingDelete || bDeleteMe || Destroy());
|
||||
}
|
||||
|
||||
public function PrepareSync(
|
||||
CTI _CTI,
|
||||
E_LogLevel _LogLevel,
|
||||
Array<class<KFWeaponDefinition> > _RemoveItems,
|
||||
Array<class<KFWeaponDefinition> > _AddItems,
|
||||
bool _ReplaceMode,
|
||||
bool _PreloadContent,
|
||||
bool _ForcePreloadContent)
|
||||
{
|
||||
CTI = _CTI;
|
||||
LogLevel = _LogLevel;
|
||||
RemoveItems = _RemoveItems;
|
||||
AddItems = _AddItems;
|
||||
ReplaceMode = _ReplaceMode;
|
||||
PreloadContent = _PreloadContent;
|
||||
ForcePreloadContent = _ForcePreloadContent;
|
||||
SyncSize = RemoveItems.Length + AddItems.Length;
|
||||
}
|
||||
|
||||
private simulated function PlayerController GetPlayerController()
|
||||
{
|
||||
local PlayerController PC;
|
||||
|
||||
PC = PlayerController(Owner);
|
||||
|
||||
if (PC == None && ROLE < ROLE_Authority)
|
||||
{
|
||||
PC = GetALocalPlayerController();
|
||||
}
|
||||
|
||||
return PC;
|
||||
}
|
||||
|
||||
private simulated function SetPartyInGameWidget()
|
||||
{
|
||||
local KFPlayerController KFPC;
|
||||
|
||||
`Log_Trace(`Location);
|
||||
|
||||
KFPC = KFPlayerController(GetPlayerController());
|
||||
if (KFPC == None) return;
|
||||
if (KFPC.MyGFxManager == None) return;
|
||||
if (KFPC.MyGFxManager.PartyWidget == None) return;
|
||||
|
||||
PartyInGameWidget = KFGFxWidget_PartyInGame(KFPC.MyGFxManager.PartyWidget);
|
||||
Notification = PartyInGameWidget.Notification;
|
||||
}
|
||||
|
||||
private simulated function bool CheckPartyInGameWidget()
|
||||
{
|
||||
if (PartyInGameWidget == None)
|
||||
{
|
||||
SetPartyInGameWidget();
|
||||
}
|
||||
|
||||
return (PartyInGameWidget != None);
|
||||
}
|
||||
|
||||
private simulated function UpdateNotification(String Title, String Downloading, String Remainig, int Percent)
|
||||
{
|
||||
if (Notification != None)
|
||||
{
|
||||
Notification.SetString("itemName", Title);
|
||||
Notification.SetFloat("percent", Percent);
|
||||
Notification.SetInt("queue", 0);
|
||||
Notification.SetString("downLoading", Downloading);
|
||||
Notification.SetString("remaining", Remainig);
|
||||
Notification.SetObject("notificationInfo", Notification);
|
||||
Notification.SetVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
private reliable client function ClientSync(class<KFWeaponDefinition> WeapDef, optional bool Remove = false)
|
||||
{
|
||||
`Log_Trace(`Location);
|
||||
|
||||
if (WeapDef == None)
|
||||
{
|
||||
`Log_Fatal("WeapDef is:" @ WeapDef);
|
||||
SafeDestroy();
|
||||
return;
|
||||
}
|
||||
|
||||
if (CheckPartyInGameWidget())
|
||||
{
|
||||
PartyInGameWidget.SetReadyButtonVisibility(false);
|
||||
}
|
||||
|
||||
if (Remove)
|
||||
{
|
||||
RemoveItems.AddItem(WeapDef);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddItems.AddItem(WeapDef);
|
||||
}
|
||||
|
||||
Recieved = RemoveItems.Length + AddItems.Length;
|
||||
if (CheckPartyInGameWidget())
|
||||
{
|
||||
UpdateNotification(
|
||||
"Sync items, please wait...",
|
||||
Remove ? "-" : "+" @ Repl(String(WeapDef), "KFWeapDef_", ""),
|
||||
Recieved @ "/" @ SyncSize,
|
||||
(float(Recieved) / float(SyncSize)) * 100);
|
||||
}
|
||||
|
||||
if (Recieved == SyncSize && (PreloadContent || ForcePreloadContent))
|
||||
{
|
||||
if (CheckPartyInGameWidget())
|
||||
{
|
||||
UpdateNotification(
|
||||
"Preload Content, please wait...",
|
||||
"Game isn't frozen",
|
||||
"Don't panic",
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
ServerSync();
|
||||
}
|
||||
|
||||
private simulated reliable client function SyncFinished()
|
||||
{
|
||||
local KFGameReplicationInfo KFGRI;
|
||||
|
||||
`Log_Trace(`Location);
|
||||
|
||||
if (WorldInfo == None || WorldInfo.GRI == None)
|
||||
{
|
||||
SetTimer(1.0f, false, nameof(SyncFinished));
|
||||
return;
|
||||
}
|
||||
|
||||
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
|
||||
if (KFGRI == None)
|
||||
{
|
||||
`Log_Fatal("Incompatible Replication info:" @ WorldInfo.GRI);
|
||||
SafeDestroy();
|
||||
return;
|
||||
}
|
||||
|
||||
Helper.static.ModifyTrader(KFGRI, RemoveItems, AddItems, ReplaceMode);
|
||||
|
||||
if (PreloadContent)
|
||||
{
|
||||
Helper.static.PreloadContent(AddItems);
|
||||
}
|
||||
if (ForcePreloadContent)
|
||||
{
|
||||
PreloadContentWorkaround();
|
||||
}
|
||||
|
||||
if (CheckPartyInGameWidget())
|
||||
{
|
||||
Notification.SetVisible(false);
|
||||
PartyInGameWidget.SetReadyButtonVisibility(true);
|
||||
PartyInGameWidget.UpdateReadyButtonText();
|
||||
PartyInGameWidget.UpdateReadyButtonVisibility();
|
||||
}
|
||||
|
||||
SafeDestroy();
|
||||
}
|
||||
|
||||
public reliable server function ServerSync()
|
||||
{
|
||||
`Log_Trace(`Location);
|
||||
|
||||
PendingSync = false;
|
||||
|
||||
if (bPendingDelete || bDeleteMe) return;
|
||||
|
||||
if (SyncSize <= Recieved || WorldInfo.NetMode == NM_StandAlone)
|
||||
{
|
||||
SyncFinished();
|
||||
if (!CTI.DestroyRepLink(Controller(Owner)))
|
||||
{
|
||||
SafeDestroy();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Recieved < RemoveItems.Length)
|
||||
{
|
||||
ClientSync(RemoveItems[Recieved++], true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClientSync(AddItems[Recieved++ - RemoveItems.Length], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private simulated function PreloadContentWorkaround()
|
||||
{
|
||||
local PlayerController PC;
|
||||
local Pawn P;
|
||||
local KFInventoryManager KFIM;
|
||||
local class<Weapon> CW;
|
||||
local Weapon W;
|
||||
local int Index;
|
||||
local DroppedPickup DP;
|
||||
local float Time;
|
||||
|
||||
`Log_Trace(`Location);
|
||||
|
||||
PC = GetPlayerController();
|
||||
|
||||
if (PC == None)
|
||||
{
|
||||
SetTimer(0.1f, false, nameof(PreloadContentWorkaround));
|
||||
return;
|
||||
}
|
||||
|
||||
P = PC.Pawn;
|
||||
if (P == None)
|
||||
{
|
||||
SetTimer(0.1f, false, nameof(PreloadContentWorkaround));
|
||||
return;
|
||||
}
|
||||
|
||||
KFIM = KFInventoryManager(P.InvManager);
|
||||
if (KFIM == None)
|
||||
{
|
||||
SetTimer(0.1f, false, nameof(PreloadContentWorkaround));
|
||||
return;
|
||||
}
|
||||
|
||||
KFIM.bInfiniteWeight = true;
|
||||
Time = WorldInfo.TimeSeconds - 1.0f;
|
||||
|
||||
for (Index = 0; Index < AddItems.Length; Index++)
|
||||
{
|
||||
CW = class<Weapon> (DynamicLoadObject(AddItems[Index].default.WeaponClassPath, class'Class'));
|
||||
if (CW != None && Weapon(P.FindInventoryType(CW)) == None)
|
||||
{
|
||||
P.CreateInventory(CW);
|
||||
}
|
||||
}
|
||||
|
||||
foreach KFIM.InventoryActors(class'Weapon', W)
|
||||
{
|
||||
if (W != None)
|
||||
{
|
||||
KFIM.PendingWeapon = W;
|
||||
KFIM.ChangedWeapon();
|
||||
if (W.CanThrow())
|
||||
{
|
||||
P.TossInventory(W);
|
||||
W.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach WorldInfo.DynamicActors(class'DroppedPickup', DP)
|
||||
{
|
||||
if (DP.Instigator == P && DP.CreationTime > Time)
|
||||
{
|
||||
DP.Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
KFIM.bInfiniteWeight = false;
|
||||
|
||||
`Log_Info("Force Preload Finished");
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
bAlwaysRelevant = false
|
||||
bOnlyRelevantToOwner = true
|
||||
bSkipActorPropertyReplication = false
|
||||
|
||||
PendingSync = false
|
||||
Recieved = 0
|
||||
}
|
73
CTI/Classes/Helper.uc
Normal file
73
CTI/Classes/Helper.uc
Normal file
@ -0,0 +1,73 @@
|
||||
class Helper extends Object;
|
||||
|
||||
private delegate int ByPrice(class<KFWeaponDefinition> A, class<KFWeaponDefinition> B)
|
||||
{
|
||||
return A.default.BuyPrice > B.default.BuyPrice ? -1 : 0;
|
||||
}
|
||||
|
||||
public static simulated function ModifyTrader(
|
||||
KFGameReplicationInfo KFGRI,
|
||||
Array<class<KFWeaponDefinition> > RemoveItems,
|
||||
Array<class<KFWeaponDefinition> > AddItems,
|
||||
bool ReplaceMode)
|
||||
{
|
||||
local KFGFxObject_TraderItems TraderItems;
|
||||
local STraderItem Item;
|
||||
local class<KFWeaponDefinition> WeapDef;
|
||||
local Array<class<KFWeaponDefinition> > WeapDefs;
|
||||
local int Index;
|
||||
local int MaxItemID;
|
||||
|
||||
if (KFGRI == None) return;
|
||||
|
||||
TraderItems = KFGFxObject_TraderItems(DynamicLoadObject(KFGRI.TraderItemsPath, class'KFGFxObject_TraderItems'));
|
||||
|
||||
if (!ReplaceMode)
|
||||
{
|
||||
foreach TraderItems.SaleItems(Item)
|
||||
{
|
||||
if (Item.WeaponDef != None && RemoveItems.Find(Item.WeaponDef) == INDEX_NONE)
|
||||
{
|
||||
WeapDefs.AddItem(Item.WeaponDef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Index = 0; Index < AddItems.Length; Index++)
|
||||
WeapDefs.AddItem(AddItems[Index]);
|
||||
|
||||
WeapDefs.Sort(ByPrice);
|
||||
|
||||
TraderItems.SaleItems.Length = 0;
|
||||
MaxItemID = 0;
|
||||
foreach WeapDefs(WeapDef)
|
||||
{
|
||||
Item.WeaponDef = WeapDef;
|
||||
Item.ItemID = ++MaxItemID;
|
||||
TraderItems.SaleItems.AddItem(Item);
|
||||
}
|
||||
|
||||
TraderItems.SetItemsInfo(TraderItems.SaleItems);
|
||||
|
||||
KFGRI.TraderItems = TraderItems;
|
||||
}
|
||||
|
||||
public static function PreloadContent(Array<class<KFWeaponDefinition> > WeapDefs)
|
||||
{
|
||||
local class<KFWeapon> KFW;
|
||||
local int Index;
|
||||
|
||||
for (Index = 0; Index < WeapDefs.Length; Index++)
|
||||
{
|
||||
KFW = class<KFWeapon> (DynamicLoadObject(WeapDefs[Index].default.WeaponClassPath, class'Class'));
|
||||
if (KFW != None)
|
||||
{
|
||||
class'KFWeapon'.static.TriggerAsyncContentLoad(KFW);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
|
||||
}
|
75
CTI/Classes/RemoveItems.uc
Normal file
75
CTI/Classes/RemoveItems.uc
Normal file
@ -0,0 +1,75 @@
|
||||
class RemoveItems extends Object
|
||||
dependson(CTI)
|
||||
config(CTI);
|
||||
|
||||
var public config bool bAll;
|
||||
var private config Array<String> Item;
|
||||
|
||||
public static function InitConfig(int Version, int LatestVersion)
|
||||
{
|
||||
switch (Version)
|
||||
{
|
||||
case `NO_CONFIG:
|
||||
ApplyDefault();
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (LatestVersion != Version)
|
||||
{
|
||||
StaticSaveConfig();
|
||||
}
|
||||
}
|
||||
|
||||
private static function ApplyDefault()
|
||||
{
|
||||
default.bAll = false;
|
||||
default.Item.Length = 0;
|
||||
default.Item.AddItem("KFGame.KFWeapDef_9mmDual");
|
||||
}
|
||||
|
||||
public static function Array<class<KFWeaponDefinition> > Load(E_LogLevel LogLevel)
|
||||
{
|
||||
local Array<class<KFWeaponDefinition> > ItemList;
|
||||
local class<KFWeaponDefinition> ItemClass;
|
||||
local String ItemRaw;
|
||||
local int Line;
|
||||
|
||||
`Log_Info("Load items to remove:");
|
||||
if (default.bAll)
|
||||
{
|
||||
`Log_Info("Remove all default items");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach default.Item(ItemRaw, Line)
|
||||
{
|
||||
ItemClass = class<KFWeaponDefinition>(DynamicLoadObject(ItemRaw, class'Class'));
|
||||
if (ItemClass == None)
|
||||
{
|
||||
`Log_Warn("[" $ Line + 1 $ "]" @ "Can't load item class:" @ ItemRaw);
|
||||
}
|
||||
else
|
||||
{
|
||||
ItemList.AddItem(ItemClass);
|
||||
`Log_Debug("[" $ Line + 1 $ "]" @ "Loaded successfully:" @ ItemRaw);
|
||||
}
|
||||
}
|
||||
|
||||
if (ItemList.Length == default.Item.Length)
|
||||
{
|
||||
`Log_Info("Items to remove list loaded successfully (" $ default.Item.Length @ "entries)");
|
||||
}
|
||||
else
|
||||
{
|
||||
`Log_Info("Items to remove list: loaded" @ ItemList.Length @ "of" @ default.Item.Length @ "entries");
|
||||
}
|
||||
}
|
||||
|
||||
return ItemList;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
|
||||
}
|
19
CTI/Classes/_Logger.uc
Normal file
19
CTI/Classes/_Logger.uc
Normal file
@ -0,0 +1,19 @@
|
||||
class _Logger extends Object
|
||||
abstract;
|
||||
|
||||
enum E_LogLevel
|
||||
{
|
||||
LL_WrongLevel,
|
||||
LL_Fatal,
|
||||
LL_Error,
|
||||
LL_Warning,
|
||||
LL_Info,
|
||||
LL_Debug,
|
||||
LL_Trace,
|
||||
LL_All
|
||||
};
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
|
||||
}
|
2
CTI/Constants.uci
Normal file
2
CTI/Constants.uci
Normal file
@ -0,0 +1,2 @@
|
||||
// Constants
|
||||
`define NO_CONFIG 0
|
3
CTI/Globals.uci
Normal file
3
CTI/Globals.uci
Normal file
@ -0,0 +1,3 @@
|
||||
// Imports
|
||||
`include(Logger.uci)
|
||||
`include(Constants.uci)
|
11
CTI/Logger.uci
Normal file
11
CTI/Logger.uci
Normal file
@ -0,0 +1,11 @@
|
||||
// Logger
|
||||
`define Log_Tag 'CTI'
|
||||
|
||||
`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:" @ `msg, (LogLevel >= LL_Trace), `Log_Tag)
|
9
PublicationContent/description.txt
Normal file
9
PublicationContent/description.txt
Normal file
@ -0,0 +1,9 @@
|
||||
[h1]Custom Trader Inventory[/h1]
|
||||
|
||||
[h1]Description[/h1]
|
||||
description will come later...
|
||||
|
||||
[b]Mutator:[/b] CTI.CTIMut
|
||||
|
||||
[h1]Sources[/h1]
|
||||
[url=https://github.com/GenZmeY/KF2-CustomTraderInventory]https://github.com/GenZmeY/KF2-CustomTraderInventory[/url]
|
BIN
PublicationContent/preview.png
Normal file
BIN
PublicationContent/preview.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
1
PublicationContent/tags.txt
Normal file
1
PublicationContent/tags.txt
Normal file
@ -0,0 +1 @@
|
||||
Mutators
|
1
PublicationContent/title.txt
Normal file
1
PublicationContent/title.txt
Normal file
@ -0,0 +1 @@
|
||||
Custom Trader Inventory
|
52
builder.cfg
Normal file
52
builder.cfg
Normal file
@ -0,0 +1,52 @@
|
||||
### Build parameters ###
|
||||
|
||||
# If True - compresses the mutator when compiling
|
||||
# Scripts will be stored in binary form
|
||||
# (reduces the size of the output file)
|
||||
StripSource="True"
|
||||
|
||||
# Mutators to be compiled
|
||||
# Specify them with a space as a separator,
|
||||
# Mutators will be compiled in the specified order
|
||||
PackageBuildOrder="CTI"
|
||||
|
||||
|
||||
### Steam Workshop upload parameters ###
|
||||
|
||||
# Mutators that will be uploaded to the workshop
|
||||
# Specify them with a space as a separator,
|
||||
# The order doesn't matter
|
||||
PackageUpload="CTI"
|
||||
|
||||
|
||||
### Test parameters ###
|
||||
|
||||
# Map:
|
||||
Map="KF-Nuked"
|
||||
|
||||
# Game:
|
||||
# Survival: KFGameContent.KFGameInfo_Survival
|
||||
# WeeklyOutbreak: KFGameContent.KFGameInfo_WeeklySurvival
|
||||
# Endless: KFGameContent.KFGameInfo_Endless
|
||||
# Objective: KFGameContent.KFGameInfo_Objective
|
||||
# Versus: KFGameContent.KFGameInfo_VersusSurvival
|
||||
Game="KFGameContent.KFGameInfo_Endless"
|
||||
|
||||
# Difficulty:
|
||||
# Normal: 0
|
||||
# Hard: 1
|
||||
# Suicide: 2
|
||||
# Hell: 3
|
||||
Difficulty="0"
|
||||
|
||||
# GameLength:
|
||||
# 4 waves: 0
|
||||
# 7 waves: 1
|
||||
# 10 waves: 2
|
||||
GameLength="0"
|
||||
|
||||
# Mutators
|
||||
Mutators="CTI.CTIMut"
|
||||
|
||||
# Additional parameters
|
||||
Args=""
|
1
tools
Submodule
1
tools
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 2f173aad7a6f4578574764801136a0d86e830653
|
Loading…
x
Reference in New Issue
Block a user