2023-05-12 23:33:32 +00:00
|
|
|
class Trader extends Object
|
|
|
|
abstract;
|
|
|
|
|
2023-09-19 19:31:08 +00:00
|
|
|
// Bug:
|
|
|
|
// The wrong weapon is purchased if the index is greater than 256 😡
|
|
|
|
// Some greedy guy saved 3 bytes for no reason again
|
|
|
|
const ITEMS_LIMIT = 256;
|
|
|
|
|
2023-05-12 23:33:32 +00:00
|
|
|
private delegate int ByPrice(class<KFWeaponDefinition> A, class<KFWeaponDefinition> B)
|
|
|
|
{
|
|
|
|
return A.default.BuyPrice > B.default.BuyPrice ? -1 : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function KFGFxObject_TraderItems GetTraderItems(optional KFGameReplicationInfo KFGRI = None, optional E_LogLevel LogLevel = LL_Trace)
|
|
|
|
{
|
|
|
|
local String TraderItemsPath;
|
|
|
|
|
|
|
|
if (KFGRI == None)
|
|
|
|
{
|
|
|
|
TraderItemsPath = class'KFGameReplicationInfo'.default.TraderItemsPath;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TraderItemsPath = KFGRI.TraderItemsPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
return KFGFxObject_TraderItems(DynamicLoadObject(TraderItemsPath, class'KFGFxObject_TraderItems'));
|
|
|
|
}
|
|
|
|
|
2023-09-19 19:31:08 +00:00
|
|
|
public static function Array<class<KFWeaponDefinition> > GetTraderWeapDefs(optional KFGameReplicationInfo KFGRI = None, optional E_LogLevel LogLevel = LL_Trace)
|
2023-05-12 23:33:32 +00:00
|
|
|
{
|
|
|
|
local Array<class<KFWeaponDefinition> > KFWeapDefs;
|
|
|
|
local KFGFxObject_TraderItems TraderItems;
|
|
|
|
local STraderItem Item;
|
|
|
|
|
|
|
|
TraderItems = GetTraderItems(KFGRI, LogLevel);
|
|
|
|
|
|
|
|
foreach TraderItems.SaleItems(Item)
|
|
|
|
{
|
|
|
|
if (Item.WeaponDef != None)
|
|
|
|
{
|
|
|
|
KFWeapDefs.AddItem(Item.WeaponDef);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return KFWeapDefs;
|
|
|
|
}
|
|
|
|
|
2023-09-19 19:31:08 +00:00
|
|
|
public static function Array<class<KFWeapon> > GetTraderWeapons(optional KFGameReplicationInfo KFGRI = None, optional E_LogLevel LogLevel = LL_Trace)
|
2023-05-12 23:33:32 +00:00
|
|
|
{
|
|
|
|
local Array<class<KFWeapon> > KFWeapons;
|
|
|
|
local class<KFWeapon> KFWeapon;
|
|
|
|
local KFGFxObject_TraderItems TraderItems;
|
|
|
|
local STraderItem Item;
|
|
|
|
|
|
|
|
TraderItems = GetTraderItems(KFGRI, LogLevel);
|
|
|
|
|
|
|
|
foreach TraderItems.SaleItems(Item)
|
|
|
|
{
|
|
|
|
if (Item.WeaponDef != None)
|
|
|
|
{
|
|
|
|
KFWeapon = class<KFWeapon> (DynamicLoadObject(Item.WeaponDef.default.WeaponClassPath, class'Class'));
|
|
|
|
if (KFWeapon != None)
|
|
|
|
{
|
|
|
|
KFWeapons.AddItem(KFWeapon);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return KFWeapons;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function Array<class<KFWeaponDefinition> > GetTraderWeapDefsDLC(KFGameReplicationInfo KFGRI, E_LogLevel LogLevel)
|
|
|
|
{
|
|
|
|
local KFGFxObject_TraderItems TraderItems;
|
|
|
|
local STraderItem Item;
|
|
|
|
local Array<class<KFWeaponDefinition> > WeapDefs;
|
|
|
|
|
|
|
|
`Log_TraceStatic();
|
|
|
|
|
|
|
|
TraderItems = GetTraderItems(KFGRI, LogLevel);
|
|
|
|
|
|
|
|
foreach TraderItems.SaleItems(Item)
|
|
|
|
{
|
|
|
|
if (Item.WeaponDef != None && Item.WeaponDef.default.SharedUnlockId != SCU_None)
|
|
|
|
{
|
|
|
|
WeapDefs.AddItem(Item.WeaponDef);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return WeapDefs;
|
|
|
|
}
|
|
|
|
|
2023-10-20 19:53:11 +00:00
|
|
|
public static simulated function Array< class<KFWeaponDefinition> > GenerateWeapDefList(
|
2023-05-12 23:33:32 +00:00
|
|
|
KFGameReplicationInfo KFGRI,
|
2023-09-19 19:31:08 +00:00
|
|
|
const out Array<class<KFWeaponDefinition> > RemoveItems,
|
|
|
|
const out Array<class<KFWeaponDefinition> > AddItems,
|
2023-10-20 19:53:11 +00:00
|
|
|
bool RemoveAll,
|
2023-05-12 23:33:32 +00:00
|
|
|
bool RemoveHRG,
|
|
|
|
bool RemoveDLC,
|
2023-09-19 19:31:08 +00:00
|
|
|
bool bDisableItemLimitCheck,
|
2023-05-12 23:33:32 +00:00
|
|
|
E_LogLevel LogLevel)
|
|
|
|
{
|
|
|
|
local KFGFxObject_TraderItems TraderItems;
|
|
|
|
local STraderItem Item;
|
2023-10-20 19:53:11 +00:00
|
|
|
local Array< class<KFWeaponDefinition> > WeapDefs;
|
2023-05-12 23:33:32 +00:00
|
|
|
local int Index;
|
|
|
|
|
|
|
|
`Log_TraceStatic();
|
|
|
|
|
|
|
|
TraderItems = GetTraderItems(KFGRI, LogLevel);
|
|
|
|
|
2023-10-20 19:53:11 +00:00
|
|
|
if (!RemoveAll)
|
2023-05-12 23:33:32 +00:00
|
|
|
{
|
|
|
|
foreach TraderItems.SaleItems(Item)
|
|
|
|
{
|
|
|
|
if (Item.WeaponDef != None
|
|
|
|
&& RemoveItems.Find(Item.WeaponDef) == INDEX_NONE
|
|
|
|
&& (!RemoveHRG || (RemoveHRG && InStr(Item.WeaponDef, "_HRG", true) == INDEX_NONE))
|
|
|
|
&& (!RemoveDLC || (RemoveDLC && Item.WeaponDef.default.SharedUnlockId == SCU_None))
|
|
|
|
&& WeaponClassIsUnique(Item.WeaponDef.default.WeaponClassPath, AddItems, LogLevel))
|
|
|
|
{
|
|
|
|
WeapDefs.AddItem(Item.WeaponDef);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (Index = 0; Index < AddItems.Length; ++Index)
|
|
|
|
{
|
2023-10-20 19:53:11 +00:00
|
|
|
if (WeaponClassIsUnique(AddItems[Index].default.WeaponClassPath, WeapDefs, LogLevel))
|
|
|
|
{
|
|
|
|
WeapDefs.AddItem(AddItems[Index]);
|
|
|
|
}
|
2023-05-12 23:33:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
WeapDefs.Sort(ByPrice);
|
|
|
|
|
2023-09-19 19:31:08 +00:00
|
|
|
if (!bDisableItemLimitCheck && WeapDefs.Length > ITEMS_LIMIT)
|
|
|
|
{
|
|
|
|
`Log_Warn("The total number of items has reached the limit (" $ ITEMS_LIMIT $ ")," @ (WeapDefs.Length - ITEMS_LIMIT) @ "items will not be added.");
|
|
|
|
`Log_Warn("Excluded items:");
|
|
|
|
for (Index = ITEMS_LIMIT; Index < WeapDefs.Length; ++Index)
|
|
|
|
{
|
|
|
|
`Log_Warn("[" $ Index + 1 $ "]" @ String(WeapDefs[Index]));
|
|
|
|
}
|
|
|
|
WeapDefs.Length = ITEMS_LIMIT;
|
|
|
|
}
|
|
|
|
|
2023-10-20 19:53:11 +00:00
|
|
|
return WeapDefs;
|
2023-09-19 19:31:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public static simulated function OverwriteTraderItems(
|
|
|
|
KFGameReplicationInfo KFGRI,
|
|
|
|
const out Array<class<KFWeaponDefinition> > WeapDefs,
|
2024-01-07 16:40:23 +00:00
|
|
|
bool ApplyPatch,
|
2023-09-19 19:31:08 +00:00
|
|
|
E_LogLevel LogLevel)
|
|
|
|
{
|
2024-01-03 22:45:36 +00:00
|
|
|
local CTI_GFxObject_TraderItems TraderItemsCTI;
|
|
|
|
local KFGFxObject_TraderItems TraderItemsDef;
|
2023-09-19 19:31:08 +00:00
|
|
|
local STraderItem Item;
|
|
|
|
local class<KFWeaponDefinition> WeapDef;
|
|
|
|
local int MaxItemID;
|
|
|
|
|
|
|
|
`Log_TraceStatic();
|
|
|
|
|
2024-01-03 22:45:36 +00:00
|
|
|
TraderItemsDef = GetTraderItems(KFGRI, LogLevel);
|
|
|
|
TraderItemsCTI = new class'CTI_GFxObject_TraderItems';
|
|
|
|
TraderItemsCTI.AllItems = TraderItemsDef.SaleItems;
|
2023-09-19 19:31:08 +00:00
|
|
|
|
2024-01-03 22:45:36 +00:00
|
|
|
TraderItemsCTI.SaleItems.Length = 0;
|
2023-05-12 23:33:32 +00:00
|
|
|
MaxItemID = 0;
|
2023-09-19 19:31:08 +00:00
|
|
|
|
|
|
|
`Log_Debug("Trader Items:");
|
2023-05-12 23:33:32 +00:00
|
|
|
foreach WeapDefs(WeapDef)
|
|
|
|
{
|
|
|
|
Item.WeaponDef = WeapDef;
|
2023-09-19 19:31:08 +00:00
|
|
|
Item.ItemID = MaxItemID++;
|
2024-01-03 22:45:36 +00:00
|
|
|
TraderItemsCTI.SaleItems.AddItem(Item);
|
|
|
|
TraderItemsCTI.AllItems.AddItem(Item);
|
2023-09-19 19:31:08 +00:00
|
|
|
`Log_Debug("[" $ MaxItemID $ "]" @ String(WeapDef));
|
2023-05-12 23:33:32 +00:00
|
|
|
}
|
|
|
|
|
2024-01-03 22:45:36 +00:00
|
|
|
foreach TraderItemsDef.SaleItems(Item)
|
|
|
|
{
|
|
|
|
Item.ItemID = MaxItemID++;
|
|
|
|
TraderItemsCTI.AllItems.AddItem(Item);
|
|
|
|
}
|
|
|
|
|
|
|
|
TraderItemsCTI.SetItemsInfo(TraderItemsCTI.SaleItems);
|
|
|
|
TraderItemsCTI.SetItemsInfo(TraderItemsCTI.AllItems);
|
2023-05-12 23:33:32 +00:00
|
|
|
|
2024-01-07 16:40:23 +00:00
|
|
|
if (ApplyPatch)
|
|
|
|
{
|
|
|
|
KFGRI.TraderItems = TraderItemsCTI;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
KFGRI.TraderItems.SaleItems = TraderItemsCTI.SaleItems;
|
|
|
|
}
|
2023-05-12 23:33:32 +00:00
|
|
|
}
|
|
|
|
|
2023-09-19 19:31:08 +00:00
|
|
|
private static function bool WeaponClassIsUnique(String WeaponClassPath, const out Array<class<KFWeaponDefinition> > WeapDefs, E_LogLevel LogLevel)
|
2023-05-12 23:33:32 +00:00
|
|
|
{
|
|
|
|
local class<KFWeaponDefinition> WeapDef;
|
|
|
|
|
|
|
|
`Log_TraceStatic();
|
|
|
|
|
|
|
|
foreach WeapDefs(WeapDef)
|
|
|
|
{
|
|
|
|
if (WeapDef.default.WeaponClassPath == WeaponClassPath)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
defaultproperties
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|