Merge pull request #15 from GenZmeY/weapon-limits

add a patch for inventory and purchase classes
This commit is contained in:
GenZmeY 2024-01-04 09:14:59 +03:00 committed by GitHub
commit 557b93d272
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 1238 additions and 67 deletions

View File

@ -1,7 +1,7 @@
class CTI extends Info class CTI extends Info
config(CTI); config(CTI);
const LatestVersion = 4; const LatestVersion = 5;
const CfgRemoveItems = class'RemoveItems'; const CfgRemoveItems = class'RemoveItems';
const CfgAddItems = class'AddItems'; const CfgAddItems = class'AddItems';
@ -23,6 +23,7 @@ var private config String UnlockDLC;
var private config bool bPreloadContent; var private config bool bPreloadContent;
var private config bool bOfficialWeaponsList; var private config bool bOfficialWeaponsList;
var private config bool bDisableItemLimitCheck; var private config bool bDisableItemLimitCheck;
var private config bool bApplyPatch;
var private KFGameInfo KFGI; var private KFGameInfo KFGI;
var private KFGameReplicationInfo KFGRI; var private KFGameReplicationInfo KFGRI;
@ -111,6 +112,9 @@ private function PreInit()
case 3: case 3:
bDisableItemLimitCheck = false; bDisableItemLimitCheck = false;
case 4:
bApplyPatch = false;
case MaxInt: case MaxInt:
`Log_Info("Config updated to version" @ LatestVersion); `Log_Info("Config updated to version" @ LatestVersion);
break; break;
@ -206,6 +210,11 @@ private function PostInit()
} }
`Log_Debug("DLCSkinUpdateRequired:" @ String(DLCSkinUpdateRequired.Value)); `Log_Debug("DLCSkinUpdateRequired:" @ String(DLCSkinUpdateRequired.Value));
if (bApplyPatch)
{
ServerPatch();
}
Trader.static.OverwriteTraderItems(KFGRI, WeapDefs, LogLevel); Trader.static.OverwriteTraderItems(KFGRI, WeapDefs, LogLevel);
`Log_Info("Trader items:" @ WeapDefs.Length); `Log_Info("Trader items:" @ WeapDefs.Length);
@ -226,6 +235,41 @@ private function PostInit()
} }
} }
private function ServerPatch()
{
local class<KFAutoPurchaseHelper> AutoPurchaseHelper;
local class<KFInventoryManager> InventoryManager;
if (KFGI.KFGFxManagerClass.GetPackageName() != 'CTI')
{
if (Unlocker.static.CustomGFxManager(KFGI))
{
`Log_Warn("Custom KFGFxMoviePlayer_Manager detected:" @ String(KFGI.KFGFxManagerClass) $ ". There may be compatibility issues.");
}
if (KFGameInfo_VersusSurvival(KFGI) != None)
{
KFGI.KFGFxManagerClass = class'CTI_GFxMoviePlayer_Manager_Versus';
}
else
{
KFGI.KFGFxManagerClass = class'CTI_GFxMoviePlayer_Manager';
}
}
AutoPurchaseHelper = class<KFPlayerController>(KFGI.PlayerControllerClass).default.PurchaseHelperClass;
if (AutoPurchaseHelper != class'KFPlayerController'.default.PurchaseHelperClass)
{
`Log_Warn("Custom PurchaseHelperClass detected:" @ String(AutoPurchaseHelper) $ ". There may be compatibility issues.");
}
InventoryManager = class<KFInventoryManager>(KFGI.DefaultPawnClass.default.InventoryManagerClass);
if (InventoryManager != class'KFPawn'.default.InventoryManagerClass)
{
`Log_Warn("Custom InventoryManagerClass detected:" @ String(InventoryManager) $ ". There may be compatibility issues.");
}
}
private function Preload(const out Array<class<KFWeaponDefinition> > Content) private function Preload(const out Array<class<KFWeaponDefinition> > Content)
{ {
local Array<S_PreloadContent> PreloadContent; local Array<S_PreloadContent> PreloadContent;
@ -299,7 +343,7 @@ public function bool CreateRepInfo(Controller C)
if (RepInfo == None) return false; if (RepInfo == None) return false;
RepInfo.PrepareSync(Self, KFPlayerController(C), LogLevel, DLCSkinUpdateRequired.Value); RepInfo.PrepareSync(Self, KFPlayerController(C), LogLevel, DLCSkinUpdateRequired.Value, bApplyPatch);
RepInfos.AddItem(RepInfo); RepInfos.AddItem(RepInfo);
@ -339,4 +383,4 @@ public function bool DestroyRepInfo(Controller C)
DefaultProperties DefaultProperties
{ {
ReadyToSync = false ReadyToSync = false
} }

View File

@ -0,0 +1,284 @@
class CTI_AutoPurchaseHelper extends KFAutoPurchaseHelper;
var private CTI_GFxObject_TraderItems CTI_TraderItems;
var private CTI_InventoryManager CTI_IM;
private function CTI_GFxObject_TraderItems GetCTI_TraderItems()
{
if (CTI_TraderItems == None)
{
if (TraderItems == None)
{
GetTraderItems();
}
if (TraderItems != None)
{
CTI_TraderItems = CTI_GFxObject_TraderItems(TraderItems);
}
}
return CTI_TraderItems;
}
private function CTI_InventoryManager GetCTI_IM()
{
if (CTI_IM == None)
{
CTI_IM = CTI_InventoryManager(Pawn.InvManager);
}
return CTI_IM;
}
public function Initialize(optional bool bInitializeOwned = true)
{
Super.Initialize(bInitializeOwned);
GetCTI_IM();
GetCTI_TraderItems();
}
public function bool UpgradeWeapon(int OwnedItemIndex)
{
local int ItemIndex;
local STraderItem DefaultItemInfo;
local SItemInformation ItemInfo;
local int Test1, Test2;
ItemInfo = OwnedItemList[OwnedItemIndex];
DefaultItemInfo = ItemInfo.DefaultItem;
if (ItemInfo.bIsSecondaryAmmo || !CanUpgrade(DefaultItemInfo, Test1, Test2, true))
{
return false;
}
if (GetCTI_IM() == None) return false;
CTI_GetItemIndicesFromArche(ItemIndex, DefaultItemInfo.ClassName);
CTI_IM.CTI_BuyUpgrade(ItemIndex, ItemInfo.ItemUpgradeLevel);
OwnedItemList[OwnedItemIndex].SellPrice = GetAdjustedSellPriceFor(DefaultItemInfo);
if (MyGfxManager != None && MyGfxManager.TraderMenu != None)
{
MyGfxManager.TraderMenu.OwnedItemList = OwnedItemList;
}
return true;
}
public function BoughtAmmo(float AmountPurchased, int Price, EItemType ItemType, optional name ClassName, optional bool bIsSecondaryAmmo)
{
local int ItemIndex;
AddDosh(-Price);
if (ItemType == EIT_Weapon)
{
CTI_GetItemIndicesFromArche(ItemIndex, ClassName);
}
if (GetCTI_IM() == None) return;
CTI_IM.CTI_BuyAmmo(AmountPurchased, ItemType, ItemIndex, bIsSecondaryAmmo);
}
private function float AmmoCostScale()
{
local KFGameReplicationInfo KFGRI;
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
return KFGRI == None? 1.0f : KFGRI.GameAmmoCostScale;
}
public function int AddWeaponToOwnedItemList(STraderItem DefaultItem, optional bool bDoNotBuy, optional int OverrideItemUpgradeLevel = INDEX_NONE)
{
local SItemInformation WeaponInfo;
local int ItemIndex, AddedWeaponIndex, OwnedSingleIdx, SingleDualAmmoDiff;
local bool bAddingDual;
WeaponInfo.MagazineCapacity = DefaultItem.MagazineCapacity;
CurrentPerk.ModifyMagSizeAndNumber(None, WeaponInfo.MagazineCapacity, DefaultItem.AssociatedPerkClasses,, DefaultItem.ClassName);
WeaponInfo.MaxSpareAmmo = DefaultItem.MaxSpareAmmo;
CurrentPerk.ModifyMaxSpareAmmoAmount(none, WeaponInfo.MaxSpareAmmo, DefaultItem);
WeaponInfo.MaxSpareAmmo += WeaponInfo.MagazineCapacity;
WeaponInfo.SpareAmmoCount = DefaultItem.InitialSpareMags * DefaultItem.MagazineCapacity;
CurrentPerk.ModifySpareAmmoAmount(none, WeaponInfo.SpareAmmoCount, DefaultItem);
WeaponInfo.SpareAmmoCount += WeaponInfo.MagazineCapacity;
bAddingDual = DefaultItem.SingleClassName != '';
if (bAddingDual)
{
for (OwnedSingleIdx = 0; OwnedSingleIdx < OwnedItemList.Length; ++OwnedSingleIdx)
{
if (OwnedItemList[OwnedSingleIdx].DefaultItem.ClassName != DefaultItem.SingleClassName) continue;
SingleDualAmmoDiff = OwnedItemList[OwnedSingleIdx].SpareAmmoCount - WeaponInfo.SpareAmmoCount;
SingleDualAmmoDiff = Max(0, SingleDualAmmoDiff);
if (WeaponInfo.SpareAmmoCount > OwnedItemList[OwnedSingleIdx].SpareAmmoCount)
{
OwnedItemList[OwnedSingleIdx].SpareAmmoCount = WeaponInfo.SpareAmmoCount;
}
else
{
WeaponInfo.SpareAmmoCount = Min(OwnedItemList[OwnedSingleIdx].SpareAmmoCount, WeaponInfo.MaxSpareAmmo);
}
WeaponInfo.ItemUpgradeLevel = OwnedItemList[OwnedSingleIdx].ItemUpgradeLevel;
break;
}
}
CurrentPerk.MaximizeSpareAmmoAmount(DefaultItem.AssociatedPerkClasses, WeaponInfo.SpareAmmoCount, DefaultItem.MaxSpareAmmo + DefaultItem.MagazineCapacity);
WeaponInfo.SecondaryAmmoCount = DefaultItem.InitialSecondaryAmmo;
CurrentPerk.ModifyMagSizeAndNumber(None, WeaponInfo.MagazineCapacity, DefaultItem.AssociatedPerkClasses, true, DefaultItem.ClassName);
CurrentPerk.ModifySpareAmmoAmount(None, WeaponInfo.SecondaryAmmoCount, DefaultItem, true);
WeaponInfo.MaxSecondaryAmmo = DefaultItem.MaxSecondaryAmmo;
CurrentPerk.ModifyMaxSpareAmmoAmount(None, WeaponInfo.MaxSecondaryAmmo, DefaultItem, true);
WeaponInfo.AmmoPricePerMagazine = AmmoCostScale() * DefaultItem.WeaponDef.default.AmmoPricePerMag;
WeaponInfo.SellPrice = GetAdjustedSellPriceFor(DefaultItem);
WeaponInfo.DefaultItem = DefaultItem;
if (OverrideItemUpgradeLevel > INDEX_NONE)
{
WeaponInfo.ItemUpgradeLevel = OverrideItemUpgradeLevel;
}
AddedWeaponIndex = AddItemByPriority(WeaponInfo);
if (GetCTI_IM() == None) return AddedWeaponIndex;
CTI_GetItemIndicesFromArche(ItemIndex, DefaultItem.ClassName);
if (!bDoNotBuy)
{
CTI_IM.CTI_ServerBuyWeapon(ItemIndex, WeaponInfo.ItemUpgradeLevel);
}
else
{
CTI_IM.CTI_ServerAddTransactionItem(ItemIndex, WeaponInfo.ItemUpgradeLevel);
AddBlocks(CTI_IM.GetWeaponBlocks(DefaultItem, WeaponInfo.ItemUpgradeLevel));
}
if (bAddingDual)
{
CTI_AddTransactionAmmo(ItemIndex, SingleDualAmmoDiff, false);
RemoveWeaponFromOwnedItemList(, DefaultItem.SingleClassName, true);
}
return AddedWeaponIndex;
}
public function RemoveWeaponFromOwnedItemList(optional int OwnedListIdx = INDEX_NONE, optional name ClassName, optional bool bDoNotSell)
{
local SItemInformation ItemInfo;
local int ItemIndex;
local int SingleOwnedIndex;
if (OwnedListIdx == INDEX_NONE && ClassName != '')
{
for (OwnedListIdx = 0; OwnedListIdx < OwnedItemList.length; ++OwnedListIdx)
{
if (OwnedItemList[OwnedListIdx].DefaultItem.ClassName == ClassName) break;
}
}
if (OwnedListIdx >= OwnedItemList.length) return;
ItemInfo = OwnedItemList[OwnedListIdx];
if (GetCTI_IM() == None) return;
if (!bDoNotSell)
{
CTI_GetItemIndicesFromArche(ItemIndex, ItemInfo.DefaultItem.ClassName);
CTI_IM.CTI_ServerSellWeapon(ItemIndex);
}
else
{
AddBlocks(-CTI_IM.GetDisplayedBlocksRequiredFor(ItemInfo.DefaultItem));
CTI_GetItemIndicesFromArche(ItemIndex, ItemInfo.DefaultItem.ClassName);
CTI_IM.CTI_ServerRemoveTransactionItem(ItemIndex);
}
if (OwnedItemList[OwnedListIdx].bIsSecondaryAmmo)
{
OwnedItemList.Remove(OwnedListIdx, 1);
if (OwnedListIdx - 1 >= 0)
{
OwnedItemList.Remove(OwnedListIdx - 1, 1);
}
}
else if (OwnedItemList[OwnedListIdx].DefaultItem.WeaponDef.static.UsesSecondaryAmmo())
{
if (OwnedListIdx + 1 < OwnedItemList.Length)
{
OwnedItemList.Remove(OwnedListIdx + 1, 1);
OwnedItemList.Remove(OwnedListIdx, 1);
}
}
else
{
OwnedItemList.Remove(OwnedListIdx, 1);
}
if (ItemInfo.DefaultItem.SingleClassName == 'KFWeap_Pistol_9mm' || ItemInfo.DefaultItem.SingleClassName == 'KFWeap_HRG_93R')
{
if (CTI_GetItemIndicesFromArche(ItemIndex, ItemInfo.DefaultItem.SingleClassName))
{
SingleOwnedIndex = AddWeaponToOwnedItemList(CTI_TraderItems.AllItems[ItemIndex], true, ItemInfo.ItemUpgradeLevel);
CTI_AddTransactionAmmo(ItemIndex, ItemInfo.SpareAmmoCount - (ItemInfo.MaxSpareAmmo / 2.0) + ((ItemInfo.MaxSpareAmmo / 2.0) - OwnedItemList[SingleOwnedIndex].SpareAmmoCount), false);
OwnedItemList[SingleOwnedIndex].SpareAmmoCount = ItemInfo.SpareAmmoCount;
}
}
if (MyGfxManager != None && MyGfxManager.TraderMenu != None)
{
MyGfxManager.TraderMenu.OwnedItemList = OwnedItemList;
}
}
public function SetWeaponInformation(KFWeapon KFW)
{
local int i;
GetCTI_TraderItems();
for (i = 0; i < CTI_TraderItems.AllItems.Length; i++)
{
if (KFW.Class.name == CTI_TraderItems.AllItems[i].ClassName)
{
SetWeaponInfo(KFW, CTI_TraderItems.AllItems[i]);
return;
}
}
}
// native private final function AddTransactionAmmo( byte ItemIndex, int Amount, bool bSecondaryAmmo );
private function CTI_AddTransactionAmmo(int ItemIndex, int Amount, bool bSecondaryAmmo); // TODO: impl
private function bool CTI_GetItemIndicesFromArche(out int ItemIndex, name WeaponClassName)
{
local int Index;
if (GetCTI_TraderItems() == None) return false;
Index = CTI_TraderItems.AllItems.Find('ClassName', WeaponClassName);
if (Index == INDEX_NONE) return false;
ItemIndex = Index;
return true;
}
defaultproperties
{
}

View File

@ -1,8 +1,219 @@
class CTI_GFxMenu_Trader extends KFGFxMenu_Trader class CTI_GFxMenu_Trader extends KFGFxMenu_Trader
dependsOn(CTI_GFxTraderContainer_Store); dependsOn(CTI_GFxTraderContainer_Store);
var private int SelectedItemIndexInt;
private function UpdateByteSelectedIndex()
{
SelectedItemIndex = Clamp(SelectedItemIndexInt, 0, 255);
}
public function SetTraderItemDetails(int ItemIndex)
{
local STraderItem SelectedItem;
local bool bCanAfford, bCanBuyItem, bCanCarry;
SelectedList = TL_Shop;
if (ItemDetails == None || ShopContainer == None) return;
if (MyKFPC.GetPurchaseHelper().TraderItems.SaleItems.length >= 0 && ItemIndex < MyKFPC.GetPurchaseHelper().TraderItems.SaleItems.length)
{
SelectedItemIndexInt = ItemIndex;
SelectedItem = MyKFPC.GetPurchaseHelper().TraderItems.SaleItems[ItemIndex];
bCanAfford = MyKFPC.GetPurchaseHelper().GetCanAfford(MyKFPC.GetPurchaseHelper().GetAdjustedBuyPriceFor(SelectedItem));
bCanCarry = MyKFPC.GetPurchaseHelper().CanCarry(SelectedItem);
bCanBuyItem = bCanAfford && bCanCarry;
PurchaseError(!bCanAfford, !bCanCarry);
ItemDetails.SetShopItemDetails(SelectedItem, MyKFPC.GetPurchaseHelper().GetAdjustedBuyPriceFor(SelectedItem), bCanCarry, bCanBuyItem);
bCanBuyOrSellItem = bCanBuyItem;
}
else
{
ItemDetails.SetVisible(false);
}
UpdateByteSelectedIndex();
}
public function SetPlayerItemDetails(int ItemIndex)
{
local STraderItem SelectedItem;
SelectedList = TL_Player;
if (ItemDetails == None || ItemIndex >= OwnedItemList.length) return;
bGenericItemSelected = false;
SelectedItemIndexInt = ItemIndex;
SelectedItem = OwnedItemList[ItemIndex].DefaultItem;
ItemDetails.SetPlayerItemDetails(SelectedItem, OwnedItemList[ItemIndex].SellPrice, OwnedItemList[ItemIndex].ItemUpgradeLevel);
bCanBuyOrSellItem = MyKFPC.GetPurchaseHelper().IsSellable(SelectedItem);
PurchaseError(false, false);
UpdateByteSelectedIndex();
}
public function SetNewSelectedIndex(int ListLength)
{
if (SelectedItemIndexInt >= ListLength)
{
if (SelectedItemIndexInt != 0)
{
SelectedItemIndexInt--;
}
}
UpdateByteSelectedIndex();
}
public function RefreshItemComponents(optional bool bInitOwnedItems = false)
{
if (PlayerInventoryContainer == None || PlayerInfoContainer == None) return;
if (bInitOwnedItems)
{
MyKFPC.GetPurchaseHelper().InitializeOwnedItemList();
}
OwnedItemList = MyKFPC.GetPurchaseHelper().OwnedItemList;
PlayerInventoryContainer.RefreshPlayerInventory();
RefreshShopItemList(CurrentTab, CurrentFilterIndex);
GameInfoContainer.UpdateGameInfo();
GameInfoContainer.SetDosh(MyKFPC.GetPurchaseHelper().TotalDosh);
GameInfoContainer.SetCurrentWeight(MyKFPC.GetPurchaseHelper().TotalBlocks, MyKFPC.GetPurchaseHelper().MaxBlocks);
if (SelectedList == TL_Shop)
{
SetTraderItemDetails(SelectedItemIndexInt);
}
else if (bGenericItemSelected)
{
SetGenericItemDetails(LastDefaultItemInfo, LastItemInfo);
}
else
{
SetPlayerItemDetails(SelectedItemIndexInt);
}
}
public function RefreshShopItemList(TabIndices TabIndex, byte FilterIndex)
{
if (ShopContainer == None || FilterContainer == None) return;
switch (TabIndex)
{
case (TI_Perks):
ShopContainer.RefreshWeaponListByPerk(FilterIndex, MyKFPC.GetPurchaseHelper().TraderItems.SaleItems);
FilterContainer.SetPerkFilterData(FilterIndex);
break;
case (TI_Type):
ShopContainer.RefreshItemsByType(FilterIndex, MyKFPC.GetPurchaseHelper().TraderItems.SaleItems);
FilterContainer.SetTypeFilterData(FilterIndex);
break;
case (TI_Favorites):
ShopContainer.RefreshFavoriteItems(MyKFPC.GetPurchaseHelper().TraderItems.SaleItems);
FilterContainer.ClearFilters();
break;
case (TI_All):
ShopContainer.RefreshAllItems(MyKFPC.GetPurchaseHelper().TraderItems.SaleItems);
FilterContainer.ClearFilters();
break;
}
FilterContainer.SetInt("selectedTab", TabIndex);
FilterContainer.SetInt("selectedFilter", FilterIndex);
if (SelectedList == TL_Shop)
{
if (SelectedItemIndexInt >= MyKFPC.GetPurchaseHelper().TraderItems.SaleItems.length)
{
SelectedItemIndexInt = MyKFPC.GetPurchaseHelper().TraderItems.SaleItems.length - 1;
}
SetTraderItemDetails(SelectedItemIndexInt);
ShopContainer.SetSelectedIndex(SelectedItemIndexInt);
}
}
public function Callback_BuyOrSellItem()
{
local STraderItem ShopItem;
local SItemInformation ItemInfo;
if (bCanBuyOrSellItem)
{
if (SelectedList == TL_Shop)
{
ShopItem = MyKFPC.GetPurchaseHelper().TraderItems.SaleItems[SelectedItemIndexInt];
MyKFPC.GetPurchaseHelper().PurchaseWeapon(ShopItem);
SetNewSelectedIndex(MyKFPC.GetPurchaseHelper().TraderItems.SaleItems.length);
SetTraderItemDetails(SelectedItemIndexInt);
ShopContainer.ActionScriptVoid("itemBought");
}
else
{
`log("Callback_BuyOrSellItem: SelectedItemIndex="$SelectedItemIndexInt, MyKFIM.bLogInventory);
ItemInfo = OwnedItemList[SelectedItemIndexInt];
`log("Callback_BuyOrSellItem: ItemInfo="$ItemInfo.DefaultItem.ClassName, MyKFIM.bLogInventory);
MyKFPC.GetPurchaseHelper().SellWeapon(ItemInfo, SelectedItemIndexInt);
SetNewSelectedIndex(OwnedItemList.length);
SetPlayerItemDetails(SelectedItemIndexInt);
PlayerInventoryContainer.ActionScriptVoid("itemSold");
}
}
else if (SelectedList == TL_Shop)
{
ShopItem = MyKFPC.GetPurchaseHelper().TraderItems.SaleItems[SelectedItemIndexInt];
MyKFPC.PlayTraderSelectItemDialog(!MyKFPC.GetPurchaseHelper().GetCanAfford(MyKFPC.GetPurchaseHelper().GetAdjustedBuyPriceFor(ShopItem)), !MyKFPC.GetPurchaseHelper().CanCarry(ShopItem));
}
RefreshItemComponents();
}
public function Callback_FavoriteItem()
{
if (SelectedList == TL_Shop)
{
ToggleFavorite(MyKFPC.GetPurchaseHelper().TraderItems.SaleItems[SelectedItemIndexInt].ClassName);
if (CurrentTab == TI_Favorites)
{
SetNewSelectedIndex(MyKFPC.GetPurchaseHelper().TraderItems.SaleItems.length);
}
SetTraderItemDetails(SelectedItemIndexInt);
}
else
{
ToggleFavorite(OwnedItemList[SelectedItemIndexInt].DefaultItem.ClassName);
SetPlayerItemDetails(SelectedItemIndexInt);
}
RefreshItemComponents();
}
public function Callback_UpgradeItem()
{
local SItemInformation ItemInfo;
local KFAutoPurchaseHelper PurchaseHelper;
if (SelectedList != TL_Player) return;
PurchaseHelper = MyKFPC.GetPurchaseHelper();
if (PurchaseHelper.UpgradeWeapon(SelectedItemIndexInt))
{
ItemInfo = PurchaseHelper.OwnedItemList[SelectedItemIndexInt];
PurchaseHelper.OwnedItemList[SelectedItemIndexInt].ItemUpgradeLevel++;
PurchaseHelper.OwnedItemList[SelectedItemIndexInt].SellPrice =
PurchaseHelper.GetAdjustedSellPriceFor(ItemInfo.DefaultItem);
RefreshItemComponents();
ShopContainer.ActionScriptVoid("itemBought");
class'KFMusicStingerHelper'.static.PlayWeaponUpgradeStinger(MyKFPC);
}
}
defaultproperties defaultproperties
{ {
SubWidgetBindings.Remove((WidgetName="shopContainer",WidgetClass=class'KFGFxTraderContainer_Store'))
SubWidgetBindings.Add((WidgetName="shopContainer",WidgetClass=class'CTI_GFxTraderContainer_Store'))
} }

View File

@ -0,0 +1,8 @@
class CTI_GFxMenu_Trader_DLC extends CTI_GFxMenu_Trader
dependsOn(CTI_GFxTraderContainer_Store);
defaultproperties
{
SubWidgetBindings.Remove((WidgetName="shopContainer",WidgetClass=class'KFGFxTraderContainer_Store'))
SubWidgetBindings.Add((WidgetName="shopContainer",WidgetClass=class'CTI_GFxTraderContainer_Store'))
}

View File

@ -0,0 +1,8 @@
class CTI_GFxMoviePlayer_Manager_DLC 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_DLC'))
}

View File

@ -0,0 +1,8 @@
class CTI_GFxMoviePlayer_Manager_Versus_DLC extends KFGFxMoviePlayer_Manager_Versus
dependsOn(CTI_GFxMenu_Trader);
defaultproperties
{
WidgetBindings.Remove((WidgetName="traderMenu",WidgetClass=class'KFGFxMenu_Trader'))
WidgetBindings.Add((WidgetName="traderMenu",WidgetClass=class'CTI_GFxMenu_Trader_DLC'))
}

View File

@ -0,0 +1,21 @@
class CTI_GFxObject_TraderItems extends KFGFxObject_TraderItems;
var() Array<STraderItem> AllItems;
public function bool CTI_GetItemIndicesFromArche(out int ItemIndex, name WeaponClassName)
{
local int Index;
Index = AllItems.Find('ClassName', WeaponClassName);
if (Index == INDEX_NONE) return false;
ItemIndex = Index;
return true;
}
DefaultProperties
{
}

View File

@ -0,0 +1,463 @@
class CTI_InventoryManager extends KFInventoryManager;
// simulated function final BuyAmmo( float AmountPurchased, EItemType ItemType, optional byte ItemIndex, optional bool bSecondaryAmmo )
public simulated function CTI_BuyAmmo(float AmountPurchased, EItemType ItemType, optional int ItemIndex, optional bool bSecondaryAmmo)
{
local STraderItem WeaponItem;
local KFWeapon KFW;
local int MagAmmoCount;
switch (ItemType)
{
case EIT_Weapon:
MagAmmoCount = INDEX_NONE;
if (CTI_GetTraderItemFromWeaponLists(WeaponItem, ItemIndex) && GetWeaponFromClass(KFW, WeaponItem.ClassName))
{
MagAmmoCount = bSecondaryAmmo ? KFW.AmmoCount[1] : KFW.AmmoCount[0];
}
CTI_ServerBuyAmmo(int(AmountPurchased), MagAmmoCount, ItemIndex, bSecondaryAmmo);
break;
case EIT_Armor: CTI_ServerBuyArmor(AmountPurchased); break;
case EIT_Grenade: CTI_ServerBuyGrenade(int(AmountPurchased)); break;
}
}
// reliable server final private function ServerBuyAmmo(int AmountPurchased, byte ClientAmmoCount, byte ItemIndex, bool bSecondaryAmmo)
private reliable server function CTI_ServerBuyAmmo(int AmountPurchased, int ClientAmmoCount, int ItemIndex, bool bSecondaryAmmo)
{
local STraderItem WeaponItem;
local KFWeapon KFW;
local int ClientMaxMagCapacity;
if (Role != ROLE_Authority || !bServerTraderMenuOpen) return;
if (!CTI_GetTraderItemFromWeaponLists(WeaponItem, ItemIndex)) return;
if (!CTI_ProcessAmmoDosh(WeaponItem, AmountPurchased, bSecondaryAmmo)) return;
if (!GetWeaponFromClass(KFW, WeaponItem.ClassName))
{
CTI_ServerAddTransactionAmmo(AmountPurchased, ItemIndex, bSecondaryAmmo);
return;
}
if (bSecondaryAmmo)
{
KFW.AddSecondaryAmmo(AmountPurchased);
}
else
{
if (ClientAmmoCount != INDEX_NONE)
{
ClientMaxMagCapacity = KFW.default.MagazineCapacity[0];
if (KFW.GetPerk() != None)
{
KFW.GetPerk().ModifyMagSizeAndNumber(KFW, ClientMaxMagCapacity);
}
KFW.AmmoCount[0] = Clamp(ClientAmmoCount, 0, ClientMaxMagCapacity);
}
KFW.AddAmmo(AmountPurchased);
}
}
// reliable server final private event ServerAddTransactionAmmo( int AmountAdded, byte ItemIndex, bool bSecondaryAmmo )
private reliable server event CTI_ServerAddTransactionAmmo(int AmountAdded, int ItemIndex, bool bSecondaryAmmo)
{
local STraderItem WeaponItem;
local int TransactionIndex;
if (!bServerTraderMenuOpen) return;
if (!CTI_GetTraderItemFromWeaponLists(WeaponItem, ItemIndex)) return;
TransactionIndex = GetTransactionItemIndex(WeaponItem.ClassName);
if (TransactionIndex == INDEX_NONE) return;
TransactionItems[TransactionIndex].AddedAmmo[byte(bSecondaryAmmo)] += AmountAdded;
}
// simulated function final BuyUpgrade(byte ItemIndex, int CurrentUpgradeLevel)
public simulated function CTI_BuyUpgrade(int ItemIndex, int CurrentUpgradeLevel)
{
local STraderItem WeaponItem;
local KFPlayerController KFPC;
KFPC = KFPlayerController(Instigator.Owner);
if (!CTI_GetTraderItemFromWeaponLists(WeaponItem, ItemIndex)) return;
KFPC.GetPurchaseHelper().AddDosh(-WeaponItem.WeaponDef.static.GetUpgradePrice(CurrentUpgradeLevel)); //client tracking
KFPC.GetPurchaseHelper().AddBlocks(-GetDisplayedBlocksRequiredFor(WeaponItem));//remove the old weight
KFPC.GetPurchaseHelper().AddBlocks(GetDisplayedBlocksRequiredFor(WeaponItem, CurrentUpgradeLevel + 1)); //add the new
CTI_ServerBuyUpgrade(ItemIndex, CurrentUpgradeLevel);
}
// reliable server final private function ServerBuyUpgrade(byte ItemIndex, int CurrentUpgradeLevel)
private reliable server function CTI_ServerBuyUpgrade(int ItemIndex, int CurrentUpgradeLevel)
{
local STraderItem WeaponItem;
local KFWeapon KFW;
local int NewUpgradeLevel;
if (Role != ROLE_Authority || !bServerTraderMenuOpen) return;
if (!CTI_GetTraderItemFromWeaponLists(WeaponItem, ItemIndex)) return;
if (!CTI_ProcessUpgradeDosh(WeaponItem, CurrentUpgradeLevel)) return;
NewUpgradeLevel = CurrentUpgradeLevel + 1;
if (GetWeaponFromClass(KFW, WeaponItem.ClassName))
{
if (KFW == None) return;
KFW.SetWeaponUpgradeLevel(NewUpgradeLevel);
if (CurrentUpgradeLevel > 0)
{
AddCurrentCarryBlocks(-KFW.GetUpgradeStatAdd(EWUS_Weight, CurrentUpgradeLevel));
}
AddCurrentCarryBlocks(KFW.GetUpgradeStatAdd(EWUS_Weight, NewUpgradeLevel));
}
else
{
CTI_ServerAddTransactionUpgrade(ItemIndex, NewUpgradeLevel);
}
}
// reliable server final function ServerBuyWeapon( byte ItemIndex, optional byte WeaponUpgrade )
public reliable server function CTI_ServerBuyWeapon(int ItemIndex, optional int WeaponUpgrade )
{
local STraderItem PurchasedItem;
local int BlocksRequired;
if (Role != ROLE_Authority || !bServerTraderMenuOpen) return;
if (!CTI_GetTraderItemFromWeaponLists(PurchasedItem, ItemIndex)) return;
BlocksRequired = GetWeaponBlocks(PurchasedItem, WeaponUpgrade);
if (CurrentCarryBlocks > CurrentCarryBlocks + BlocksRequired) return;
if (!CTI_ProcessWeaponDosh(PurchasedItem)) return;
CTI_AddTransactionItem( PurchasedItem, WeaponUpgrade);
}
// final function AddTransactionItem( const out STraderItem ItemToAdd, optional byte WeaponUpgrade )
public function CTI_AddTransactionItem(const out STraderItem ItemToAdd, optional int WeaponUpgrade)
{
local TransactionItem NewTransactionItem;
if (Role < ROLE_Authority || !bServerTraderMenuOpen) return;
NewTransactionItem.ClassName = ItemToAdd.ClassName;
NewTransactionItem.DLOString = ItemToAdd.WeaponDef.default.WeaponClassPath;
NewTransactionItem.AddedAmmo[0] = 0;
NewTransactionItem.AddedAmmo[1] = 0;
NewTransactionItem.WeaponUpgradeLevel = WeaponUpgrade;
TransactionItems.AddItem(NewTransactionItem);
AddCurrentCarryBlocks(GetWeaponBlocks(ItemToAdd, WeaponUpgrade));
}
// reliable server final function ServerAddTransactionItem( byte ItemIndex, optional byte WeaponUpgrade)
public reliable server function CTI_ServerAddTransactionItem(int ItemIndex, optional int WeaponUpgrade)
{
local STraderItem PurchasedItem;
if (Role != ROLE_Authority || !bServerTraderMenuOpen) return;
if (CTI_GetTraderItemFromWeaponLists(PurchasedItem, ItemIndex))
{
CTI_AddTransactionItem(PurchasedItem, WeaponUpgrade);
}
}
// final function RemoveTransactionItem( const out STraderItem ItemToRemove )
final function CTI_RemoveTransactionItem(const out STraderItem ItemToRemove)
{
local int Index;
if (Role < ROLE_Authority || !bServerTraderMenuOpen) return;
Index = GetTransactionItemIndex( ItemToRemove.ClassName );
if (Index == INDEX_NONE) return;
AddCurrentCarryBlocks(-GetDisplayedBlocksRequiredFor(ItemToRemove, TransactionItems[Index].WeaponUpgradeLevel));
TransactionItems.Remove(Index, 1);
}
// reliable server final function ServerRemoveTransactionItem( int ItemIndex )
public reliable server final function CTI_ServerRemoveTransactionItem(int ItemIndex)
{
local STraderItem ItemToRemove;
local KFWeapon InvWeap;
if (!bServerTraderMenuOpen) return;
if (!CTI_GetTraderItemFromWeaponLists(ItemToRemove, ItemIndex)) return;
CTI_RemoveTransactionItem(ItemToRemove);
if (!GetWeaponFromClass(InvWeap, ItemToRemove.ClassName)) return;
RemoveFromInventory(InvWeap);
}
// reliable server final function ServerSellWeapon( byte ItemIndex )
public reliable server function CTI_ServerSellWeapon(int ItemIndex)
{
local STraderItem SoldItem;
local int SellPrice, TransactionIndex;
local KFWeapon KFW;
local KFPlayerReplicationInfo KFPRI;
if (Role != ROLE_Authority || !bServerTraderMenuOpen) return;
KFPRI = KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if (KFPRI == None) return;
if (!CTI_GetTraderItemFromWeaponLists(SoldItem, ItemIndex)) return;
if (GetWeaponFromClass(KFW, SoldItem.ClassName))
{
SellPrice = GetAdjustedSellPriceFor(SoldItem);
KFPRI.AddDosh(SellPrice);
ServerRemoveFromInventory(KFW);
KFW.Destroy();
}
else
{
TransactionIndex = GetTransactionItemIndex(SoldItem.ClassName);
if (TransactionIndex == INDEX_NONE) return;
SellPrice = GetAdjustedSellPriceFor(SoldItem);
KFPRI.AddDosh(SellPrice);
CTI_RemoveTransactionItem(SoldItem);
}
}
// private final simulated function bool GetTraderItemFromWeaponLists(out STraderItem TraderItem, byte ItemIndex )
private simulated function bool CTI_GetTraderItemFromWeaponLists(out STraderItem TraderItem, int ItemIndex)
{
local CTI_GFxObject_TraderItems TraderItems;
if (WorldInfo.GRI == None) return false;
TraderItems = CTI_GFxObject_TraderItems(KFGameReplicationInfo(WorldInfo.GRI).TraderItems);
if (TraderItems == None) return false;
if (ItemIndex < TraderItems.AllItems.Length)
{
TraderItem = TraderItems.AllItems[ItemIndex];
return true;
}
return false;
}
// private final function bool ProcessWeaponDosh(out STraderItem PurchasedItem)
private function bool CTI_ProcessWeaponDosh(out STraderItem PurchasedItem)
{
local int BuyPrice;
local KFPlayerReplicationInfo KFPRI;
KFPRI = KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if (KFPRI == None) return false;
BuyPrice = GetAdjustedBuyPriceFor(PurchasedItem);
if (KFPRI.Score - BuyPrice >= 0)
{
KFPRI.AddDosh(-BuyPrice);
return true;
}
return false;
}
private function float AmmoCostScale()
{
local KFGameReplicationInfo KFGRI;
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
return KFGRI == None ? 1.0f : KFGRI.GameAmmoCostScale;
}
// private final function bool ProcessAmmoDosh(out STraderItem PurchasedItem, int AdditionalAmmo, optional bool bSecondaryAmmo)
private function bool CTI_ProcessAmmoDosh(out STraderItem PurchasedItem, int AdditionalAmmo, optional bool bSecondaryAmmo)
{
local int BuyPrice;
local float PricePerMag, MagSize;
local KFPlayerReplicationInfo KFPRI;
KFPRI = KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if (KFPRI == None) return false;
if (bSecondaryAmmo)
{
PricePerMag = AmmoCostScale() * PurchasedItem.WeaponDef.default.SecondaryAmmoMagPrice;
MagSize = PurchasedItem.WeaponDef.default.SecondaryAmmoMagSize;
BuyPrice = FCeil((PricePerMag / MagSize) * float(AdditionalAmmo));
}
else
{
PricePerMag = AmmoCostScale() * PurchasedItem.WeaponDef.default.AmmoPricePerMag;
MagSize = PurchasedItem.MagazineCapacity;
BuyPrice = FCeil((PricePerMag / MagSize) * float(AdditionalAmmo));
}
if (KFPRI.Score - BuyPrice >= 0)
{
KFPRI.AddDosh(-BuyPrice);
return true;
}
return false;
}
// private final function bool ProcessUpgradeDosh(const out STraderItem PurchasedItem, int NewUpgradeLevel)
private function bool CTI_ProcessUpgradeDosh(const out STraderItem PurchasedItem, int NewUpgradeLevel)
{
local int BuyPrice;
local KFPlayerController KFPC;
local KFPlayerReplicationInfo KFPRI;
KFPC = KFPlayerController(Instigator.Owner);
KFPRI = KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if (KFPC == None || KFPRI == none) return false;
BuyPrice = PurchasedItem.WeaponDef.static.GetUpgradePrice(NewUpgradeLevel);
if (BuyPrice <= KFPRI.Score)
{
KFPRI.AddDosh(-BuyPrice);
return true;
}
return false;
}
// private final function bool ProcessGrenadeDosh(int AmountPurchased)
private function bool CTI_ProcessGrenadeDosh(int AmountPurchased)
{
local int BuyPrice;
local KFGFxObject_TraderItems TraderItems;
local KFPlayerController KFPC;
local KFPlayerReplicationInfo KFPRI;
KFPC = KFPlayerController(Instigator.Owner);
KFPRI = KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if (KFPC == None || KFPRI == None) return false;
TraderItems = KFGameReplicationInfo(WorldInfo.GRI).TraderItems;
BuyPrice = TraderItems.GrenadePrice * AmountPurchased;
if (BuyPrice <= KFPRI.Score)
{
KFPRI.AddDosh(-BuyPrice);
return true;
}
return false;
}
// reliable server final private function ServerBuyArmor( float PercentPurchased )
private reliable server function CTI_ServerBuyArmor(float PercentPurchased)
{
local KFPawn_Human KFP;
local int AmountPurchased;
local float MaxArmor;
KFP = KFPawn_Human(Instigator);
if (Role != ROLE_Authority || KFP == none || !bServerTraderMenuOpen) return;
if (!CTI_ProcessArmorDosh(PercentPurchased)) return;
MaxArmor = KFP.GetMaxArmor();
AmountPurchased = FCeil(MaxArmor * (PercentPurchased / 100.0));
KFP.AddArmor(AmountPurchased);
}
// private final function bool ProcessArmorDosh(float PercentPurchased)
private function bool CTI_ProcessArmorDosh(float PercentPurchased)
{
local int BuyPrice;
local KFGFxObject_TraderItems TraderItems;
local KFPlayerController KFPC;
local KFPerk CurrentPerk;
local int ArmorPricePerPercent;
local KFPlayerReplicationInfo KFPRI;
KFPRI = KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if (KFPRI == None) return false;
TraderItems = KFGameReplicationInfo(WorldInfo.GRI).TraderItems;
ArmorPricePerPercent = TraderItems.ArmorPrice;
KFPC = KFPlayerController(Instigator.Owner);
if (KFPC != None)
{
CurrentPerk = KFPC.GetPerk();
if (CurrentPerk != None)
{
ArmorPricePerPercent *= CurrentPerk.GetArmorDiscountMod();
}
}
BuyPrice = FCeil(ArmorPricePerPercent * PercentPurchased);
if (BuyPrice <= KFPRI.Score)
{
KFPRI.AddDosh(-BuyPrice);
return true;
}
return false;
}
// reliable server final private event ServerAddTransactionUpgrade(int ItemIndex, int NewUpgradeLevel)
private reliable server event CTI_ServerAddTransactionUpgrade(int ItemIndex, int NewUpgradeLevel)
{
if (bServerTraderMenuOpen)
{
CTI_AddTransactionUpgrade(ItemIndex, NewUpgradeLevel);
}
}
// final function AddTransactionUpgrade(int ItemIndex, int NewUpgradeLevel)
private function CTI_AddTransactionUpgrade(int ItemIndex, int NewUpgradeLevel)
{
local STraderItem WeaponItem;
local int TransactionIndex;
if (Role < ROLE_Authority || !bServerTraderMenuOpen) return;
if (CTI_GetTraderItemFromWeaponLists(WeaponItem, ItemIndex))
{
TransactionIndex = GetTransactionItemIndex(WeaponItem.ClassName);
if (TransactionIndex == INDEX_NONE) return;
TransactionItems[TransactionIndex].WeaponUpgradeLevel = NewUpgradeLevel;
TransactionItems[TransactionIndex].AddedWeight = WeaponItem.WeaponUpgradeWeight[NewUpgradeLevel];
if (NewUpgradeLevel > 0)
{
AddCurrentCarryBlocks(-WeaponItem.WeaponUpgradeWeight[NewUpgradeLevel-1]);
}
AddCurrentCarryBlocks(WeaponItem.WeaponUpgradeWeight[NewUpgradeLevel]);
}
}
// reliable server final private function ServerBuyGrenade( int AmountPurchased )
private reliable server function CTI_ServerBuyGrenade(int AmountPurchased)
{
if (Role != ROLE_Authority || !bServerTraderMenuOpen) return;
if (CTI_ProcessGrenadeDosh(AmountPurchased))
{
AddGrenades(AmountPurchased);
}
}
defaultproperties
{
}

View File

@ -0,0 +1,6 @@
class CTI_PawnHuman extends KFPawn_Human;
defaultproperties
{
InventoryManagerClass=class'CTI_InventoryManager'
}

View File

@ -3,9 +3,11 @@ class CTI_RepInfo extends ReplicationInfo
const CAPACITY = 64; // max: 128 const CAPACITY = 64; // max: 128
const Trader = class'Trader'; const Trader = class'Trader';
const LocalMessage = class'CTI_LocalMessage'; const LocalMessage = class'CTI_LocalMessage';
const Replacements = class'WeaponReplacements'; const Replacements = class'WeaponReplacements';
const PurchaseHelper = class'CTI_AutoPurchaseHelper';
const InventoryManager = class'CTI_InventoryManager';
struct ReplicationStruct struct ReplicationStruct
{ {
@ -40,11 +42,14 @@ var private ReplicationStruct RepData;
var private Array<class<KFWeaponDefinition> > RepArray; var private Array<class<KFWeaponDefinition> > RepArray;
var private bool SkinUpdateRequired; var private bool SkinUpdateRequired;
var private bool PatchRequired;
var private bool ClientReady, ServerReady;
replication replication
{ {
if (bNetInitial && Role == ROLE_Authority) if (bNetInitial && Role == ROLE_Authority)
LogLevel, SkinUpdateRequired; LogLevel, SkinUpdateRequired, PatchRequired;
} }
public simulated function bool SafeDestroy() public simulated function bool SafeDestroy()
@ -54,10 +59,36 @@ public simulated function bool SafeDestroy()
return (bPendingDelete || bDeleteMe || Destroy()); return (bPendingDelete || bDeleteMe || Destroy());
} }
public function PrepareSync(
CTI _CTI, KFPlayerController _KFPC, E_LogLevel _LogLevel,
bool _SkinUpdateRequired, bool _PatchRequired)
{
`Log_Trace();
CTI = _CTI;
KFPC = _KFPC;
LogLevel = _LogLevel;
SkinUpdateRequired = _SkinUpdateRequired;
PatchRequired = _PatchRequired;
}
public function Replicate(const out Array<class<KFWeaponDefinition> > WeapDefs) public function Replicate(const out Array<class<KFWeaponDefinition> > WeapDefs)
{ {
`Log_Trace(); `Log_Trace();
ServerReady = !PatchRequired;
if (PatchRequired)
{
if (GetKFPC() != None)
{
KFPC.PurchaseHelperClass = PurchaseHelper;
KFPC.PurchaseHelper = None;
}
InitInventoryManager();
}
RepArray = WeapDefs; RepArray = WeapDefs;
RepData.Size = RepArray.Length; RepData.Size = RepArray.Length;
@ -111,16 +142,6 @@ private reliable client function Send(ReplicationStruct RD)
Sync(); Sync();
} }
public function PrepareSync(CTI _CTI, KFPlayerController _KFPC, E_LogLevel _LogLevel, bool _SkinUpdateRequired)
{
`Log_Trace();
CTI = _CTI;
KFPC = _KFPC;
LogLevel = _LogLevel;
SkinUpdateRequired = _SkinUpdateRequired;
}
private simulated function Progress(int Value, int Size) private simulated function Progress(int Value, int Size)
{ {
`Log_Trace(); `Log_Trace();
@ -140,7 +161,7 @@ private simulated function Finished()
`Log_Trace(); `Log_Trace();
if (GetGRI(WaitingGRI > WaitingGRIThreshold) == None && WaitingGRI++ < WaitingGRILimit) if ((GetGRI(WaitingGRI > WaitingGRIThreshold) == None) && WaitingGRI++ < WaitingGRILimit)
{ {
`Log_Debug("Finished: Waiting GRI" @ WaitingGRI); `Log_Debug("Finished: Waiting GRI" @ WaitingGRI);
NotifyWaitingGRI(); NotifyWaitingGRI();
@ -148,6 +169,12 @@ private simulated function Finished()
return; return;
} }
if (PatchRequired && GetKFPC() != None)
{
KFPC.PurchaseHelperClass = PurchaseHelper;
KFPC.PurchaseHelper = None;
}
KFGRI = KFGameReplicationInfo(GRI); KFGRI = KFGameReplicationInfo(GRI);
if (KFGRI != None) if (KFGRI != None)
{ {
@ -165,39 +192,42 @@ private simulated function Finished()
if (SkinUpdateRequired) if (SkinUpdateRequired)
{ {
SetTimer(1.0f, true, nameof(UpdateSkinsDLC)); SkinUpdate();
} }
else else
{ {
ClientCleanup(); ClientFinished();
} }
} }
private simulated function UpdateSkinsDLC() private simulated function SkinUpdate()
{ {
local SWeapReplace WeapReplace; local SWeapReplace WeapReplace;
`Log_Debug("Wait for spawn"); if (GetKFPRI() == None || !KFPRI.bHasSpawnedIn)
if (GetKFPRI() != None && KFPRI.bHasSpawnedIn)
{ {
foreach Replacements.default.DLC(WeapReplace) `Log_Debug("Wait for spawn (SkinUpdate)");
{ SetTimer(1.0f, false, nameof(SkinUpdate));
// sometimes "WeapReplace.Weap.default.SkinItemId" can give values greater than zero while actually being zero return;
// this is the same bug that prevents creating the correct default config
// so for now lets shorten the check a little so that the skinId of the WeapReplace is guaranteed to be correct
// but if this bug is ever fixed, then its worth replacing the check with this one:
// if (WeapReplace.WeapParent.default.SkinItemId > 0 && WeapReplace.Weap.default.SkinItemId != WeapReplace.WeapParent.default.SkinItemId)
// to reduce the number of meaningless disk writes
if (WeapReplace.WeapParent.default.SkinItemId > 0)
{
`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();
} }
foreach Replacements.default.DLC(WeapReplace)
{
// sometimes "WeapReplace.Weap.default.SkinItemId" can give values greater than zero while actually being zero
// this is the same bug that prevents creating the correct default config
// so for now lets shorten the check a little so that the skinId of the WeapReplace is guaranteed to be correct
// but if this bug is ever fixed, then its worth replacing the check with this one:
// if (WeapReplace.WeapParent.default.SkinItemId > 0 && WeapReplace.Weap.default.SkinItemId != WeapReplace.WeapParent.default.SkinItemId)
// to reduce the number of meaningless disk writes
if (WeapReplace.WeapParent.default.SkinItemId > 0)
{
`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(SkinUpdate));
ClientFinished();
} }
private simulated function GameReplicationInfo GetGRI(optional bool ForcedSearch = false) private simulated function GameReplicationInfo GetGRI(optional bool ForcedSearch = false)
@ -361,14 +391,19 @@ private simulated function KeepNotification()
NotificationPercent); NotificationPercent);
} }
private simulated function ClientCleanup() private reliable server function ClientFinished()
{ {
`Log_Debug("Cleanup"); ClientReady = true;
ServerCleanup(); if (ClientReady && ServerReady) Cleanup();
SafeDestroy();
} }
private reliable server function ServerCleanup() private function ServerFinished()
{
ServerReady = true;
if (ClientReady && ServerReady) Cleanup();
}
private reliable server function Cleanup()
{ {
`Log_Trace(); `Log_Trace();
@ -380,6 +415,69 @@ private reliable server function ServerCleanup()
} }
} }
public function InitInventoryManager()
{
local InventoryManager PrevInventoryManger;
local InventoryManager NextInventoryManger;
local KFInventoryManager PrevKFInventoryManger;
local KFInventoryManager NextKFInventoryManger;
local Inventory Item;
`Log_Trace();
if (GetKFPRI() == None || !KFPRI.bHasSpawnedIn)
{
`Log_Debug("Wait for spawn (InventoryManager)");
SetTimer(1.0f, false, nameof(InitInventoryManager));
return;
}
PrevInventoryManger = KFPC.Pawn.InvManager;
KFPC.Pawn.InventoryManagerClass = InventoryManager;
NextInventoryManger = Spawn(KFPC.Pawn.InventoryManagerClass, KFPC.Pawn);
if (NextInventoryManger == None)
{
`Log_Error("Can't spawn" @ String(KFPC.Pawn.InventoryManagerClass));
ServerFinished();
return;
}
KFPC.Pawn.InvManager = NextInventoryManger;
KFPC.Pawn.InvManager.SetupFor(KFPC.Pawn);
if (PrevInventoryManger == None)
{
KFPC.Pawn.AddDefaultInventory();
}
else
{
for (Item = PrevInventoryManger.InventoryChain; Item != None; Item = PrevInventoryManger.InventoryChain)
{
PrevInventoryManger.RemoveFromInventory(Item);
NextInventoryManger.AddInventory(Item);
}
}
PrevKFInventoryManger = KFInventoryManager(PrevInventoryManger);
NextKFInventoryManger = KFInventoryManager(NextInventoryManger);
if (PrevKFInventoryManger != None && NextKFInventoryManger != None)
{
NextKFInventoryManger.GrenadeCount = PrevKFInventoryManger.GrenadeCount;
}
PrevKFInventoryManger.InventoryChain = None;
PrevKFInventoryManger.Destroy();
`Log_Debug("InventoryManager initialized");
ServerFinished();
}
private simulated function NotifyWaitingGRI() private simulated function NotifyWaitingGRI()
{ {
if (!IsTimerActive(nameof(KeepNotification))) if (!IsTimerActive(nameof(KeepNotification)))
@ -431,4 +529,7 @@ defaultproperties
WaitingGRI = 0 WaitingGRI = 0
WaitingGRIThreshold = 15 WaitingGRIThreshold = 15
WaitingGRILimit = 30 WaitingGRILimit = 30
ClientReady = false
ServerReady = false
} }

View File

@ -154,16 +154,19 @@ public static simulated function OverwriteTraderItems(
const out Array<class<KFWeaponDefinition> > WeapDefs, const out Array<class<KFWeaponDefinition> > WeapDefs,
E_LogLevel LogLevel) E_LogLevel LogLevel)
{ {
local KFGFxObject_TraderItems TraderItems; local CTI_GFxObject_TraderItems TraderItemsCTI;
local KFGFxObject_TraderItems TraderItemsDef;
local STraderItem Item; local STraderItem Item;
local class<KFWeaponDefinition> WeapDef; local class<KFWeaponDefinition> WeapDef;
local int MaxItemID; local int MaxItemID;
`Log_TraceStatic(); `Log_TraceStatic();
TraderItems = GetTraderItems(KFGRI, LogLevel); TraderItemsDef = GetTraderItems(KFGRI, LogLevel);
TraderItemsCTI = new class'CTI_GFxObject_TraderItems';
TraderItemsCTI.AllItems = TraderItemsDef.SaleItems;
TraderItems.SaleItems.Length = 0; TraderItemsCTI.SaleItems.Length = 0;
MaxItemID = 0; MaxItemID = 0;
`Log_Debug("Trader Items:"); `Log_Debug("Trader Items:");
@ -171,13 +174,21 @@ public static simulated function OverwriteTraderItems(
{ {
Item.WeaponDef = WeapDef; Item.WeaponDef = WeapDef;
Item.ItemID = MaxItemID++; Item.ItemID = MaxItemID++;
TraderItems.SaleItems.AddItem(Item); TraderItemsCTI.SaleItems.AddItem(Item);
TraderItemsCTI.AllItems.AddItem(Item);
`Log_Debug("[" $ MaxItemID $ "]" @ String(WeapDef)); `Log_Debug("[" $ MaxItemID $ "]" @ String(WeapDef));
} }
TraderItems.SetItemsInfo(TraderItems.SaleItems); foreach TraderItemsDef.SaleItems(Item)
{
Item.ItemID = MaxItemID++;
TraderItemsCTI.AllItems.AddItem(Item);
}
KFGRI.TraderItems = TraderItems; TraderItemsCTI.SetItemsInfo(TraderItemsCTI.SaleItems);
TraderItemsCTI.SetItemsInfo(TraderItemsCTI.AllItems);
KFGRI.TraderItems = TraderItemsCTI;
} }
private static function bool WeaponClassIsUnique(String WeaponClassPath, const out Array<class<KFWeaponDefinition> > WeapDefs, E_LogLevel LogLevel) private static function bool WeaponClassIsUnique(String WeaponClassPath, const out Array<class<KFWeaponDefinition> > WeapDefs, E_LogLevel LogLevel)

View File

@ -63,22 +63,11 @@ private static function bool Auto(
out BoolWrapper DLCSkinUpdateRequired, out BoolWrapper DLCSkinUpdateRequired,
E_LogLevel LogLevel) E_LogLevel LogLevel)
{ {
local bool CustomGFxManager;
`Log_TraceStatic(); `Log_TraceStatic();
if (KFGI == None) return false; if (KFGI == None) return false;
if (KFGameInfo_VersusSurvival(KFGI) != None) if (CustomGFxManager(KFGI))
{
CustomGFxManager = (KFGI.KFGFxManagerClass != class'KFGameInfo_VersusSurvival'.default.KFGFxManagerClass);
}
else
{
CustomGFxManager = (KFGI.KFGFxManagerClass != class'KFGameInfo'.default.KFGFxManagerClass);
}
if (CustomGFxManager)
{ {
return ReplaceWeapons(KFGRI, WeapDefs, DLCSkinUpdateRequired, LogLevel); return ReplaceWeapons(KFGRI, WeapDefs, DLCSkinUpdateRequired, LogLevel);
} }
@ -89,6 +78,18 @@ private static function bool Auto(
} }
} }
public static function bool CustomGFxManager(KFGameInfo KFGI)
{
if (KFGameInfo_VersusSurvival(KFGI) != None)
{
return (KFGI.KFGFxManagerClass != class'KFGameInfo_VersusSurvival'.default.KFGFxManagerClass);
}
else
{
return (KFGI.KFGFxManagerClass != class'KFGameInfo'.default.KFGFxManagerClass);
}
}
private static function bool ReplaceWeapons( private static function bool ReplaceWeapons(
KFGameReplicationInfo KFGRI, KFGameReplicationInfo KFGRI,
out Array<class<KFWeaponDefinition> > WeapDefs, out Array<class<KFWeaponDefinition> > WeapDefs,
@ -170,13 +171,18 @@ private static function bool ReplaceFilter(KFGameInfo KFGI, E_LogLevel LogLevel)
if (KFGI == None) return false; if (KFGI == None) return false;
if (CustomGFxManager(KFGI))
{
`Log_Warn("Custom KFGFxMoviePlayer_Manager detected:" @ String(KFGI.KFGFxManagerClass) $ ". There may be compatibility issues.");
}
if (KFGameInfo_VersusSurvival(KFGI) != None) if (KFGameInfo_VersusSurvival(KFGI) != None)
{ {
KFGI.KFGFxManagerClass = class'CTI_GFxMoviePlayer_Manager_Versus'; KFGI.KFGFxManagerClass = class'CTI_GFxMoviePlayer_Manager_Versus_DLC';
} }
else else
{ {
KFGI.KFGFxManagerClass = class'CTI_GFxMoviePlayer_Manager'; KFGI.KFGFxManagerClass = class'CTI_GFxMoviePlayer_Manager_DLC';
} }
return true; return true;