1
0
KF2-Dev-Scripts/KFGame/Classes/KFGFxMenu_Inventory.uc
2022-09-01 18:58:51 +03:00

1540 lines
43 KiB
Ucode

//=============================================================================
// KFGFxMenu_Inventory
//=============================================================================
// This menu is used to show the player's inventory and crafting.
//=============================================================================
// Killing Floor 2
// Copyright (C) 2015 Tripwire Interactive LLC
// Zane Gholson - 09/30/2015
//=============================================================================
class KFGFxMenu_Inventory extends KFGFxObject_Menu;
var localized string RecycleOneString;
var localized string RecycleDuplicatesString;
var localized string NoItemsString;
var localized string InventoryPopulatingString;
var localized string InventoryString;
var localized string EquipString;
var localized string UnequipString;
var localized string UseString;
var localized string RecycleString;
var localized string CraftString;
var localized string AllString;
var localized string WeaponSkinString;
var localized string CosmeticString;
var localized string EmotesString;
var localized string CraftingMatsString;
var localized string ItemString;
var localized string FiltersString;
var localized string CraftWeaponString;
var localized string CraftCosmeticString;
var localized string CraftItemString;
var localized string ConfirmCraftItemString;
var localized string RecycleWarningString;
var localized string RecycleItemString;
var localized array<string> CraftWeaponStrings;
var localized array<string> CraftCosmeticStrings;
var localized string FailedToExchangeString;
var localized string MoreItemsString;
var localized string ItemExchangeTimeOutString;
var localized string TryAgainString;
var localized string FailedToCraftItemString;
var localized string CraftRequirementString;
var localized string CraftCosmeticDescriptionString;
var localized string CraftWeaponDescriptionString;
var localized string RequiresString;
var localized string PurchaseKeyString;
var localized string LookUpOnMarketString;
var localized string RarityFilterString;
var localized string WeaponTypeFilterString;
var localized string PerkFilterString;
var GFxObject CraftingSubMenu;
var GFxObject ItemListContainer;
var GFxObject ItemDetailsContainer;
var GFxObject EquipButton; //item deatils container
var GFxObject CraftWeaponButton;
var GFxObject CraftCosmeticButton;
var OnlineSubsystem OnlineSub;
var PlayfabInterface PlayfabInter;
var KFPawn_Customization KFPH;
var bool bInitialInventoryPassComplete;
var int TempItemIdHolder; //used to cache id when crafting / recycling (pop ups)
var int UncommonCosmeticID;
var int RareCosmeticID;
var int ExceptionalCosmeticID;
var int MasterCosmeticID;
var int UncommonWeaponID;
var int RareWeaponID;
var int ExceptionalWeaponID;
var int MasterWeaponID;
var name SoundEvent_Common;
var name SoundEvent_Uncommon;
var name SoundEvent_Rare;
var name SoundEvent_Legendary;
var name SoundEvent_ExceedinglyRare;
var name SoundEvent_Mythical;
var name SoundThemeName;
var KFPlayerController KFPC;
var int ValueToPromptDuplicateRecycle;
var array<int> SpecialEventItemIDs;
var array<int> KeylessCrateIDs;
var AkEvent KillThatDangSoundEvent;
enum EINventory_Filter
{
EInv_WeaponSkins,
EInv_Cosmetics,
EInv_Consumables,
EInv_Items,
EInv_CraftingMats,
EInv_Emotes,
EInv_SFX,
EInv_All,
};
enum EInventoryWeaponType_Filter
{
EInvWT_Pistol,
EInvWT_Shotgun,
EInvWT_Rifle,
EInvWT_Projectile,
EInvWT_Fire,
EInvWT_Tech,
EInvWT_Launcher,
EInvWT_AssaultRifle,
EInvWT_Melee,
EInvWT_SMG,
EInvWT_None
};
struct InventoryHelper
{
var int ItemDefinition;
var int ItemIndex;
var int ItemCount;
var ItemType Type;
var GFxObject GfxItemObject;
// For ordering in weapon skins
var int WeaponDef;
var int Price;
//var string FullName;
var int SkinType;
var ItemRarity Rarity;
var int Quality;
// For ordering items
var string KeyName;
var bool IsKey;
};
var array<InventoryHelper> SkinListWeaponsSearchCache;
var array<InventoryHelper> SkinListOrderedCache;
var bool NeedToRegenerateSkinList;
struct ByTypeItemsHelper
{
var() array<InventoryHelper> ItemsOnType;
};
var EInventoryWeaponType_Filter CurrentWeaponTypeFilter;
var int CurrentPerkIndexFilter;
var ItemRarity CurrentRarityFilter;
var EINventory_Filter CurrentInventoryFilter;
var ExchangeRuleSets RuleToExchange;
var private int CrcTable[256];
function InitializeMenu( KFGFxMoviePlayer_Manager InManager )
{
super.InitializeMenu( InManager );
CrcInit();
KFPC = KFPlayerController(GetPC());
CurrentPerkIndexFilter = KFPC.PerkList.length; //default value
LocalizeText();
OnlineSub = class'GameEngine'.static.GetOnlineSubsystem();
PlayfabInter = class'GameEngine'.static.GetPlayfabInterface();
//@SABER_EGS IsEosBuild() case added
if( class'WorldInfo'.static.IsConsoleBuild() || class'WorldInfo'.static.IsEosBuild() )
{
PlayfabInter.AddInventoryReadCompleteDelegate( OnReadPlayfabInventoryComplete );
}
else
{
OnlineSub.AddOnInventoryReadCompleteDelegate(OnInventoryReadComplete);
}
KFPH = KFPawn_Customization(KFPC.Pawn);
CraftingSubMenu = GetObject("craftingPanelContainer");
ItemDetailsContainer = GetObject("itemDetailsContainer");
EquipButton = ItemDetailsContainer.GetObject("equipButton");
UpdateCraftButtons();
}
function UpdateCraftButtons()
{
ItemListContainer = GetObject("inventoryListContainer");
if(ItemListContainer != none)
{
CraftWeaponButton = ItemListContainer.GetObject("craftWeaponsButton");
if(CraftWeaponButton != none)
{
CraftWeaponButton.SetBool("enabled", class'WorldInfo'.static.IsMenuLevel());
}
CraftCosmeticButton = ItemListContainer.GetObject("craftCosmeticsButton");
if(CraftCosmeticButton != none)
{
CraftCosmeticButton.SetBool("enabled", class'WorldInfo'.static.IsMenuLevel());
}
}
}
function OnOpen()
{
//@SABER_EGS IsEosBuild() case added
if( class'WorldInfo'.static.IsConsoleBuild() || class'WorldInfo'.static.IsEosBuild() )
{
PlayfabInter.AddInventoryReadCompleteDelegate( OnReadPlayfabInventoryComplete );
}
else if( OnlineSub != none )
{
OnlineSub.AddOnInventoryReadCompleteDelegate(OnInventoryReadComplete);
}
InitInventory();
if ( class'WorldInfo'.static.IsMenuLevel() )
{
Manager.ManagerObject.SetBool("backgroundVisible", false);
}
KFPC.ConsoleCommand("CE Idle");
}
function OnClose()
{
ClearMatinee();
//@SABER_EGS IsEosBuild() case added
if( class'WorldInfo'.static.IsConsoleBuild() || class'WorldInfo'.static.IsEosBuild() )
{
PlayfabInter.ClearInventoryReadCompleteDelegate( OnReadPlayfabInventoryComplete );
}
else if( OnlineSub != none )
{
OnlineSub.ClearOnInventoryReadCompleteDelegate(OnInventoryReadComplete);
}
if ( class'WorldInfo'.static.IsMenuLevel() )
{
Manager.ManagerObject.SetBool("backgroundVisible", true);
}
}
final function CrcInit() {
const CrcPolynomial = 0xedb88320;
local int CrcValue;
local int IndexBit;
local int IndexEntry;
for (IndexEntry = 0; IndexEntry < 256; IndexEntry++) {
CrcValue = IndexEntry;
for (IndexBit = 8; IndexBit > 0; IndexBit--)
if ((CrcValue & 1) != 0)
CrcValue = (CrcValue >>> 1) ^ CrcPolynomial;
else
CrcValue = CrcValue >>> 1;
CrcTable[IndexEntry] = CrcValue;
}
}
final function int Crc(coerce string Text)
{
local int CrcValue;
local int IndexChar;
local int StrLen;
CrcValue = 0xffffffff;
StrLen = Len(Text);
for (IndexChar = 0; IndexChar < StrLen; IndexChar++)
CrcValue = (CrcValue >>> 8) ^ CrcTable[(Asc(Mid(Text, IndexChar, 1)) ^ CrcValue) & 0xff];
return CrcValue;
}
delegate int SortSkinList(InventoryHelper A, InventoryHelper B)
{
/** Format: Compare lower ? -1 : (Compare upper) : 1 : (Equal case, repeat formula with the next sort condition) */
return A.Price > B.Price ? -1 : (A.Price < B.Price ? 1 : (
A.WeaponDef < B.WeaponDef ? -1 : (A.WeaponDef > B.WeaponDef ? 1 : (
A.Rarity > B.Rarity ? -1 : (A.Rarity < B.Rarity ? 1 : (
A.SkinType > B.SkinType ? -1 : (A.SkinType < B.SkinType ? 1 : (
A.Quality < B.Quality ? -1 : 1
))
))
))
));
}
delegate int SortItemList(InventoryHelper A, InventoryHelper B)
{
if (A.IsKey && B.IsKey)
{
return 0;
}
if (A.IsKey == false && B.IsKey == false)
{
return 0;
}
if (A.IsKey)
{
return 1;
}
return -1;
}
function InitInventory()
{
local int i, j, z, ItemIndex, HelperIndex, WeaponItemID, SearchWeaponSkinIndex, SearchKeyKeywordIndex;
local ItemProperties TempItemDetailsHolder;
local GFxObject ItemArray, ItemObject;
local bool bActiveItem;
local ByTypeItemsHelper ByTypeItems[7];
local InventoryHelper HelperItem;
local array<ExchangeRuleSets> ExchangeRules;
local class<KFWeaponDefinition> WeaponDef;
local string SkinType;
local GFxObject PendingItem;
ItemArray = CreateArray();
if(OnlineSub == none)
{
// If there is no OnlineSubsystem just send an empty array. HSL_BB
SetObject("inventoryList", ItemArray);
return;
}
// While reading from the profile we also order by type, then we might want to order again some stuff that's inside the same item type later
//`Log("NEW MENU OPEN: " $CurrentInventoryFilter);
for (i = 0; i < OnlineSub.CurrentInventory.length; i++)
{
//look item up to get info on it.
ItemIndex = OnlineSub.ItemPropertiesList.Find('Definition', OnlineSub.CurrentInventory[i].Definition);
// BWJ - 12-21-16 - Hide items that have no definition
if(ItemIndex != INDEX_NONE && OnlineSub.CurrentInventory[i].Definition != 0 )
{
TempItemDetailsHolder = OnlineSub.ItemPropertiesList[ItemIndex];
if (((CurrentInventoryFilter == EInv_All || Int(CurrentInventoryFilter) == Int(TempItemDetailsHolder.Type))
&& DoesMatchFilter(TempItemDetailsHolder))
|| bool(OnlineSub.CurrentInventory[i].NewlyAdded))
{
ItemObject = CreateObject("Object");
HelperIndex = ByTypeItems[TempItemDetailsHolder.Type].ItemsOnType.Find('ItemDefinition', onlineSub.CurrentInventory[i].Definition);
if (HelperIndex == INDEX_NONE)
{
HelperItem.Type = TempItemDetailsHolder.Type;
//HelperItem.FullName = TempItemDetailsHolder.Name;
HelperItem.ItemDefinition = onlineSub.CurrentInventory[i].Definition;
HelperItem.ItemCount = onlineSub.CurrentInventory[i].Quantity;
if (TempItemDetailsHolder.Type == ITP_WeaponSkin)
{
// Copy required stuff
HelperItem.Rarity = TempItemDetailsHolder.Rarity;
HelperItem.Quality = TempItemDetailsHolder.Quality;
if (bool(OnlineSub.CurrentInventory[i].NewlyAdded))
{
NeedToRegenerateSkinList = true;
}
// Search on the cache, to speed up
WeaponItemID = SkinListWeaponsSearchCache.Find('ItemDefinition', HelperItem.ItemDefinition);
if (WeaponItemID != INDEX_NONE)
{
HelperItem.WeaponDef = SkinListWeaponsSearchCache[WeaponItemID].WeaponDef;
HelperItem.Price = SkinListWeaponsSearchCache[WeaponItemID].Price;
HelperItem.SkinType = SkinListWeaponsSearchCache[WeaponItemID].SkinType;
}
else
{
// Get right part of the string without from the first "| "
SearchWeaponSkinIndex = InStr(TempItemDetailsHolder.Name, "|");
SkinType = Right(TempItemDetailsHolder.Name, Len(TempItemDetailsHolder.Name) - SearchWeaponSkinIndex - 2);
// Get the left part of the string without the next "| "
SearchWeaponSkinIndex = InStr(SkinType, "|");
// Store as CRC, that speeds up comparisons later
HelperItem.SkinType = CrC(Left(SkinType, SearchWeaponSkinIndex));
WeaponItemID = class'KFWeaponSkinList'.default.Skins.Find('Id', HelperItem.ItemDefinition);
if (WeaponItemID != INDEX_NONE)
{
WeaponDef = class'KFWeaponSkinList'.default.Skins[WeaponItemID].WeaponDef;
// All Weapons start by KFGameContent.KFWeap_ Skip that prefix.
// Store as CRC, that speeds up comparisons later
HelperItem.WeaponDef = CrC(Mid(WeaponDef.default.WeaponClassPath, 21));
HelperItem.Price = WeaponDef.default.BuyPrice;
}
else
{
HelperItem.WeaponDef = -1;
HelperItem.Price = 0;
}
SkinListWeaponsSearchCache.AddItem(HelperItem);
}
}
else
{
HelperItem.KeyName = TempItemDetailsHolder.KeyName;
}
ByTypeItems[TempItemDetailsHolder.Type].ItemsOnType.AddItem(HelperItem);
HelperIndex = ByTypeItems[TempItemDetailsHolder.Type].ItemsOnType.Length - 1;
}
else
{
ByTypeItems[TempItemDetailsHolder.Type].ItemsOnType[HelperIndex].ItemCount += onlineSub.CurrentInventory[i].Quantity;
}
OnlineSub.IsExchangeable(onlineSub.CurrentInventory[i].Definition, ExchangeRules);
ItemObject.SetInt("count", ByTypeItems[TempItemDetailsHolder.Type].ItemsOnType[HelperIndex].ItemCount);
ItemObject.SetString("label", TempItemDetailsHolder.Name);
ItemObject.SetString("price", TempItemDetailsHolder.price);
ItemObject.Setstring("typeRarity", TempItemDetailsHolder.ShortDescription);
ItemObject.SetInt("type", TempItemDetailsHolder.Type);
ItemObject.SetBool("exchangeable", IsItemExchangeable(TempItemDetailsHolder, ExchangeRules) && class'WorldInfo'.static.IsMenuLevel() );
ItemObject.SetBool("recyclable", IsItemRecyclable(TempItemDetailsHolder, ExchangeRules) && class'WorldInfo'.static.IsMenuLevel());
bActiveItem = IsItemActive(onlineSub.CurrentInventory[i].Definition) || IsSFXActive(onlineSub.CurrentInventory[i].Definition);
ItemObject.SetBool("active", bActiveItem );
ItemObject.SetInt("rarity", TempItemDetailsHolder.Rarity);
ItemObject.SetString("description", TempItemDetailsHolder.Description);
ItemObject.SetString("iconURLSmall", "img://"$TempItemDetailsHolder.IconURL);
ItemObject.SetString("iconURLLarge", "img://"$TempItemDetailsHolder.IconURLLarge);
ItemObject.SetInt("definition", TempItemDetailsHolder.Definition);
ItemObject.SetBool("newlyAdded", bool(OnlineSub.CurrentInventory[i].NewlyAdded) );
ByTypeItems[TempItemDetailsHolder.Type].ItemsOnType[HelperIndex].GfxItemObject = ItemObject;
if(onlineSub.CurrentInventory[i].Definition == Manager.SelectIDOnOpen)
{
PendingItem = ItemObject;
}
if(bool(OnlineSub.CurrentInventory[i].NewlyAdded) && bInitialInventoryPassComplete)
{
SetMatineeColor(TempItemDetailsHolder.Rarity);
KFPC.ConsoleCommand("CE gotitem");
SetObject("details", ItemObject);
}
}
}
}
OnlineSub.ClearNewlyAdded();
if (CurrentInventoryFilter == EInv_All || CurrentInventoryFilter == EInv_WeaponSkins)
{
// If need to refresh... we regenerate the list, if not reuse our Cache
NeedToRegenerateSkinList = NeedToRegenerateSkinList || ByTypeItems[ITP_WeaponSkin].ItemsOnType.Length != SkinListOrderedCache.Length;
if (NeedToRegenerateSkinList)
{
NeedToRegenerateSkinList = false;
// We want to order by Price - Weapon Def - Rarity - Quality
// So we order inverse that way we keep the final list with the design intention
ByTypeItems[ITP_WeaponSkin].ItemsOnType.Sort(SortSkinList);
SkinListOrderedCache = ByTypeItems[ITP_WeaponSkin].ItemsOnType;
/*`Log("----------");*/
/*for (i = 0 ; i < SkinListOrderedCache.Length; i++)
{
`Log("ID : " $SkinListOrderedCache[i].ItemDefinition);
`Log("Weapon Def : " $SkinListOrderedCache[i].WeaponDef);
`Log("Price : " $SkinListOrderedCache[i].Price);
`Log("Full Name : " $SkinListOrderedCache[i].FullName);
`Log("Skin : " $SkinListOrderedCache[i].SkinType);
`Log("Rarity : " $SkinListOrderedCache[i].Rarity);
`Log("Quality : " $SkinListOrderedCache[i].Quality);
`Log("----------");
}
`Log("----------");*/
}
else
{
//`Log("USING SKIN LIST CACHE!!!");
ByTypeItems[ITP_WeaponSkin].ItemsOnType = SkinListOrderedCache;
}
}
if (CurrentInventoryFilter == EInv_All || CurrentInventoryFilter == EInv_Consumables)
{
// Consumables is the type for the "Items" category on the UI
// First we have to distinguish if the Item is a KEY or not
for (i = 0; i < ByTypeItems[ITP_KeyCrate].ItemsOnType.Length; i++)
{
// KeyName is something like : "NameItem:KeyCrate", we first remove the part from the : to the right
SearchKeyKeywordIndex = InStr(ByTypeItems[ITP_KeyCrate].ItemsOnType[i].KeyName, ":");
ByTypeItems[ITP_KeyCrate].ItemsOnType[i].KeyName = Left(ByTypeItems[ITP_KeyCrate].ItemsOnType[i].KeyName, SearchKeyKeywordIndex);
// Then we search if the name of the Item contains "Key"
SearchKeyKeywordIndex = InStr(ByTypeItems[ITP_KeyCrate].ItemsOnType[i].KeyName, "Key");
if (SearchKeyKeywordIndex != -1)
{
ByTypeItems[ITP_KeyCrate].ItemsOnType[i].IsKey = true;
}
else
{
ByTypeItems[ITP_KeyCrate].ItemsOnType[i].IsKey = false;
}
}
ByTypeItems[ITP_KeyCrate].ItemsOnType.Sort(SortItemList);
}
//`Log("--------------------------------");
z = 0;
for (i = 0; i < ArrayCount(ByTypeItems); i++)
{
for (j = 0 ; j < ByTypeItems[i].ItemsOnType.Length; j++)
{
ItemArray.SetElementObject(z, ByTypeItems[i].ItemsOnType[j].GfxItemObject);
++z;
}
}
SetObject("inventoryList", ItemArray);
if(Manager.SelectIDOnOpen != INDEX_NONE )
{
CallBack_ItemDetailsClicked(Manager.SelectIDOnOpen);
SetObject("details", PendingItem);
Manager.SelectIDOnOpen = INDEX_NONE;
}
bInitialInventoryPassComplete = true;
}
function bool DoesMatchFilter(ItemProperties InventoryItem)
{
if(CurrentInventoryFilter == EInv_All || CurrentInventoryFilter == EInv_WeaponSkins)
{
if ((CurrentWeaponTypeFilter != EInvWT_None || CurrentPerkIndexFilter != KFPC.PerkList.length) && InventoryItem.Type != ITP_WeaponSkin )
{
return false;
}
if (CurrentWeaponTypeFilter != EInvWT_None && CurrentWeaponTypeFilter != InventoryItem.WeaponType )
{
return false;
}
// doesn't match filter if the perk id doesn't match (unless it's set to any or survivalist)
if (CurrentPerkIndexFilter != KFPC.PerkList.length && !(CurrentPerkIndexFilter == InventoryItem.PerkId || CurrentPerkIndexFilter == InventoryItem.AltPerkId) && KFPC.PerkList[CurrentPerkIndexFilter].PerkClass != class'KFPerk_Survivalist') //perk
{
return false;
}
}
if (CurrentRarityFilter != ITR_NONE && InventoryItem.Rarity != CurrentRarityFilter && CurrentInventoryFilter != EInv_Consumables)
{
if ((CurrentInventoryFilter == EInv_CraftingMats || CurrentInventoryFilter == EInv_Consumables) && (CurrentInventoryFilter == InventoryItem.Type + 1))
{
return true;
}
return false;
}
return true;
}
function OnItemExhangeTimeOut()
{
if( !class'WorldInfo'.static.IsConsoleBuild() )
{
Manager.DelayedOpenPopup(ENotification, EDPPID_Misc, ItemExchangeTimeOutString, TryAgainString, class'KFCommon_LocalizedStrings'.default.OKString);
SetVisible(true);
}
}
function FinishCraft()
{
SetVisible(true);
`Log("FinishCraft");
NeedToRegenerateSkinList = true;
}
function SetMatineeColor(int ItemRarity)
{
switch (ItemRarity)
{
case ITR_Common:
KFPC.ConsoleCommand("CE rarityCommon");
break;
case ITR_Uncommon:
KFPC.ConsoleCommand("CE rarityUncommon");
break;
case ITR_Rare:
KFPC.ConsoleCommand("CE rarityRare");
break;
case ITR_Legendary:
KFPC.ConsoleCommand("CE rarityMasterCrafted");
break;
case ITR_ExceedinglyRare:
KFPC.ConsoleCommand("CE rarityPrecious");
break;
case ITR_Mythical:
KFPC.ConsoleCommand("CE rarityExceptional");
break;
default:
KFPC.ConsoleCommand("CE rarityCommon");
}
}
function ClearMatinee()
{
KFPC.PlaySoundBase(KillThatDangSoundEvent);
KFPC.ConsoleCommand("CE Abort");
KFPC.ResetCustomizationCamera();
}
function OnReadPlayfabInventoryComplete( bool bSuccess )
{
if( bSuccess )
{
LocalizeText();
InitInventory();
}
else
{
Manager.DelayedOpenPopup(ENotification, EDPPID_Misc, class'KFCommon_LocalizedStrings'.default.NoticeString, class'KFCommon_LocalizedStrings'.default.FailedToReachInventoryServerString, class'KFCommon_LocalizedStrings'.default.OKString);
}
}
function OnInventoryReadComplete()
{
InitInventory();
}
function bool IsItemRecyclable( ItemProperties ItemDetailsHolder, out const array<ExchangeRuleSets> ExchangeRules )
{
local int i;
for( i = 0; i < ExchangeRules.Length; i++ )
{
if ( ExchangeRules[i].Type == ITP_CraftingComponent )
{
//`log("recycle Yes ["$ItemDetailsHolder.Definition$"] ");
return true;
}
}
//`log("recycle No ["$ItemDetailsHolder.Definition$"] ");
return false;
}
function bool IsItemExchangeable( out ItemProperties ItemDetailsHolder, out const array<ExchangeRuleSets> ExchangeRules )
{
local int i;
for( i = 0; i < ExchangeRules.Length; i++ )
{
if (OnlineSub.ExchangeReady(ExchangeRules[i]))
{
//`log("exchange Yes ["$ItemDetailsHolder.Definition$"] ");
return true;
}
}
//`log("exchange no ["$ItemDetailsHolder.Definition$"] ");
return false;
}
function bool IsSpecialEventItem(int ItemID)
{
return SpecialEventItemIDs.Find(ItemID) != INDEX_NONE;
}
function bool IsKeylessCrate(int ItemID)
{
return KeylessCrateIDs.Find(ItemID) != INDEX_NONE;
}
function bool IsItemActive(int ItemDefinition)
{
local class<KFWeaponDefinition> WeaponDef;
local int ItemIndex;
ItemIndex = class'KFWeaponSkinList'.default.Skins.Find('Id', ItemDefinition);
if(ItemIndex == INDEX_NONE)
{
return false;
}
WeaponDef = class'KFWeaponSkinList'.default.Skins[ItemIndex].WeaponDef;
if(WeaponDef != none)
{
if (class'KFWeaponSkinList'.Static.IsSkinEquip(WeaponDef, ItemDefinition))
{
return true;
}
}
return false;
}
function bool IsSFXActive(int ItemDefinition)
{
local int ItemIndex;
ItemIndex = class'KFHeadShotEffectList'.static.GetHeadShotEffectIndex(ItemDefinition);
if (ItemIndex == INDEX_NONE)
{
return false;
}
return class'KFHeadShotEffectList'.Static.IsHeadShotEffectEquipped(ItemDefinition);
}
function LocalizeText()
{
local GFxObject LocalizedObject;
local GFxObject WeaponTypeList;
local GFxObject RarityList;
local GFxObject PerkList;
local GFxObject TempObject;
local int i;
LocalizedObject = CreateObject( "Object" );
LocalizedObject.SetString("noItems", KFGameEngine(class'Engine'.static.GetEngine()).bReadingPlayfabStoreData ? InventoryPopulatingString : NoItemsString);
LocalizedObject.SetString("inventory", InventoryString);
LocalizedObject.SetString("back", Class'KFCommon_LocalizedStrings'.default.BackString);
LocalizedObject.SetString("ok", Class'KFCommon_LocalizedStrings'.default.OKString);
LocalizedObject.SetString("equip", EquipString);
LocalizedObject.SetString("unequip", UnequipString);
LocalizedObject.SetString("useString", UseString);
LocalizedObject.SetString("recycle", RecycleString);
LocalizedObject.SetString("sfx", Class'KFCommon_LocalizedStrings'.default.SpecialEffectsString);
LocalizedObject.SetString("all", AllString);
LocalizedObject.SetString("weaponSkins", WeaponSkinString);
LocalizedObject.SetString("cosmetics", CosmeticString);
LocalizedObject.SetString("emotes", EmotesString);
LocalizedObject.SetString("craftingMats", CraftingMatsString);
LocalizedObject.SetString("items", ItemString);
LocalizedObject.SetString("filters", FiltersString);
LocalizedObject.SetString("craftWeapon", CraftWeaponString);
LocalizedObject.SetString("craftCosmetic", CraftCosmeticString);
LocalizedObject.SetString("filterName_0", RarityFilterString);
LocalizedObject.SetString("filterName_1", PerkFilterString);
LocalizedObject.SetString("filterName_2", WeaponTypeFilterString);
RarityList = CreateArray();
for (i = 0; i <= ITR_NONE; i++)
{
TempObject = CreateObject("Object");
if(i == ITR_NONE)
{
//dont forget the no preference string
TempObject.SetString("label", class'KFCommon_LocalizedStrings'.default.NoPreferenceString);
}
else
{
TempObject.SetString("label", class'KFCommon_LocalizedStrings'.default.RarityStrings[i]);
}
RarityList.SetElementObject(i, TempObject);
}
PerkList = CreateArray();
for (i = 0; i <= KFPC.PerkList.length; i++)
{
TempObject = CreateObject("Object");
if(i == KFPC.PerkList.length)
{
//dont forget the no preference string
TempObject.SetString("label", class'KFCommon_LocalizedStrings'.default.NoPreferenceString);
}
else
{
TempObject.SetString("label", KFPC.PerkList[i].PerkClass.default.PerkName);
}
PerkList.SetElementObject(i, TempObject);
}
WeaponTypeList = CreateArray();
for (i = 0; i <= EInvWT_None; i++)
{
TempObject = CreateObject("Object");
if(i == EInvWT_None)
{
//dont forget the no preference string
TempObject.SetString("label", class'KFCommon_LocalizedStrings'.default.NoPreferenceString);
}
else
{
TempObject.SetString("label", class'KFCommon_LocalizedStrings'.default.WeaponTypeStrings[i]);
}
WeaponTypeList.SetElementObject(i, TempObject);
}
LocalizedObject.SetInt("filterIndex_0", int(CurrentRarityFilter) );
LocalizedObject.SetInt("filterIndex_1", CurrentPerkIndexFilter );
LocalizedObject.SetInt("filterIndex_2", int(CurrentWeaponTypeFilter) );
LocalizedObject.SetObject("filterData_0", RarityList);
LocalizedObject.SetObject("filterData_1", PerkList);
LocalizedObject.SetObject("filterData_2", WeaponTypeList);
SetObject("localizedText", LocalizedObject);
}
function SetWeaponCraftDetails()
{
local GFxObject CraftOptionsObject;
local ItemProperties CommonItemDetailsHolder, RareItemDetailsHolder, ExceptionalItemDetailsHolder, MasterItemDetailsHolder;
local int ItemIndex, i;
local array<ItemProperties> ItemArray;
ItemIndex = OnlineSub.ItemPropertiesList.Find('Definition', UncommonWeaponID);
if(ItemIndex != INDEX_NONE)
{
CommonItemDetailsHolder = OnlineSub.ItemPropertiesList[ItemIndex];
ItemArray.AddItem(CommonItemDetailsHolder);
}
ItemIndex = OnlineSub.ItemPropertiesList.Find('Definition', RareWeaponID);
if(ItemIndex != INDEX_NONE)
{
RareItemDetailsHolder = OnlineSub.ItemPropertiesList[ItemIndex];
ItemArray.AddItem(RareItemDetailsHolder);
}
ItemIndex = OnlineSub.ItemPropertiesList.Find('Definition', ExceptionalWeaponID);
if(ItemIndex != INDEX_NONE)
{
ExceptionalItemDetailsHolder = OnlineSub.ItemPropertiesList[ItemIndex];
ItemArray.AddItem(ExceptionalItemDetailsHolder);
}
ItemIndex = OnlineSub.ItemPropertiesList.Find('Definition', MasterWeaponID);
if(ItemIndex != INDEX_NONE)
{
MasterItemDetailsHolder = OnlineSub.ItemPropertiesList[ItemIndex];
ItemArray.AddItem(MasterItemDetailsHolder);
}
CraftOptionsObject = CreateObject("Object");
CraftOptionsObject.SetString("title", CraftWeaponString);
CraftOptionsObject.SetString("description", CraftWeaponDescriptionString);
CraftOptionsObject.SetString("craft", CraftString);
for (i = 0; i < ItemArray.length; i++)
{
CraftOptionsObject.SetString("label_"$i, CraftWeaponStrings[i]);
CraftOptionsObject.SetString("requirement_"$i, RequiresString$"10"@ItemArray[i].Name);
CraftOptionsObject.SetInt("itemCount_"$i, GetCountOfItem(ItemArray[i].Definition));
CraftOptionsObject.SetString("itemImage_"$i, "img://"$ItemArray[i].IconURL);
CraftOptionsObject.SetInt("itemID_"$i, ItemArray[i].Definition);
}
SetObject("craftOptions", CraftOptionsObject);
}
function SetCosmeticCraftDetails()
{
local GFxObject CraftOptionsObject;
local ItemProperties CommonItemDetailsHolder, RareItemDetailsHolder, ExceptionalItemDetailsHolder, MasterItemDetailsHolder;
local int ItemIndex, i;
local array<ItemProperties> ItemArray;
ItemIndex = OnlineSub.ItemPropertiesList.Find('Definition', UncommonCosmeticID);
if(ItemIndex != INDEX_NONE)
{
CommonItemDetailsHolder = OnlineSub.ItemPropertiesList[ItemIndex];
ItemArray.AddItem(CommonItemDetailsHolder);
}
ItemIndex = OnlineSub.ItemPropertiesList.Find('Definition', RareCosmeticID);
if(ItemIndex != INDEX_NONE)
{
RareItemDetailsHolder = OnlineSub.ItemPropertiesList[ItemIndex];
ItemArray.AddItem(RareItemDetailsHolder);
}
ItemIndex = OnlineSub.ItemPropertiesList.Find('Definition', ExceptionalCosmeticID);
if(ItemIndex != INDEX_NONE)
{
ExceptionalItemDetailsHolder = OnlineSub.ItemPropertiesList[ItemIndex];
ItemArray.AddItem(ExceptionalItemDetailsHolder);
}
ItemIndex = OnlineSub.ItemPropertiesList.Find('Definition', MasterCosmeticID);
if(ItemIndex != INDEX_NONE)
{
MasterItemDetailsHolder = OnlineSub.ItemPropertiesList[ItemIndex];
ItemArray.AddItem(MasterItemDetailsHolder);
}
CraftOptionsObject = CreateObject("Object");
CraftOptionsObject.SetString("title", CraftCosmeticString);
CraftOptionsObject.SetString("description", CraftCosmeticDescriptionString);
CraftOptionsObject.SetString("craft", CraftString);
for (i = 0; i < ItemArray.length; i++)
{
CraftOptionsObject.SetString("label_"$i, CraftCosmeticStrings[i]);
CraftOptionsObject.SetString("requirement_"$i, RequiresString$"10"@ItemArray[i].Name);
CraftOptionsObject.SetInt("itemCount_"$i, GetCountOfItem(ItemArray[i].Definition));
CraftOptionsObject.SetString("itemImage_"$i, "img://"$ItemArray[i].IconURL);
CraftOptionsObject.SetInt("itemID_"$i, ItemArray[i].Definition);
}
SetObject("craftOptions", CraftOptionsObject);
}
function int GetCountOfItem(int ItemDefinition)
{
local int i;
local int Count;
for (i = 0; i < onlineSub.CurrentInventory.length; i++)
{
if( onlineSub.CurrentInventory[i].Definition == ItemDefinition)
{
count += onlineSub.CurrentInventory[i].Quantity;
}
}
return count;
}
function PerformExchange( ExchangeRuleSets ForRuleset, optional bool AllButOne =false )
{
//@SABER_EGS IsEosBuild() case added
if( class'WorldInfo'.static.IsConsoleBuild() || class'WorldInfo'.static.IsEosBuild() )
{
PlayfabInter.PerformRuleExchange( ForRuleset, AllButOne );
}
else
{
OnlineSub.Exchange( ForRuleset, AllButOne );
}
}
function ConfirmRecycle()
{
local array<ExchangeRuleSets> ExchangeRules;
local int RuleIndex;
//`log("confirming ["$TempItemIdHolder$"] ");
OnlineSub.IsExchangeable( TempItemIdHolder, ExchangeRules );
for (RuleIndex = 0; RuleIndex < ExchangeRules.length; RuleIndex++)
{
if( OnlineSub.ExchangeReady(ExchangeRules[RuleIndex]) && ExchangeRules[RuleIndex].Type == ITP_CraftingComponent )
{
OnlineSub.ClearInFlight();
PerformExchange( ExchangeRules[RuleIndex], false );
SetVisible(false);
KFPC.ConsoleCommand( "CE Recycle_Start" );
return;
}
}
}
function ConfirmDuplicatesRecycle()
{
local array<ExchangeRuleSets> ExchangeRules;
local int RuleIndex;
OnlineSub.IsExchangeable( TempItemIdHolder, ExchangeRules );
for (RuleIndex = 0; RuleIndex < ExchangeRules.length; RuleIndex++)
{
if( OnlineSub.ExchangeReady(ExchangeRules[RuleIndex]) && ExchangeRules[RuleIndex].Type == ITP_CraftingComponent )
{
OnlineSub.ClearInFlight();
PerformExchange( ExchangeRules[RuleIndex], true );
SetVisible(false);
KFPC.ConsoleCommand( "CE Recycle_Start" );
return;
}
}
}
function CancelRecycle()
{
TempItemIdHolder=INDEX_NONE;
}
function ConfirmCraft()
{
local array<ExchangeRuleSets> ExchangeRules;
local int RuleIndex;
OnlineSub.IsExchangeable(TempItemIdHolder, ExchangeRules);
for (RuleIndex = 0; RuleIndex < ExchangeRules.length; RuleIndex++)
{
if(OnlineSub.ExchangeReady(ExchangeRules[RuleIndex]))
{
OnlineSub.ClearInFlight();
PerformExchange( ExchangeRules[RuleIndex], false );
SetVisible(false);
KFPC.ConsoleCommand("CE Craft_Start");
return;
}
}
`log("CRAFTING == SAD");
}
//Only do this on one item, this is too expensive to do in a loop
function int GetItemCount(int ItemDefinition)
{
local int i, ItemCount;
if(OnlineSub == none)
{
// If there is no OnlineSubsystem just send an empty array. HSL_BB
return 0;
}
for (i = 0; i < OnlineSub.CurrentInventory.length; i++)
{
//look item up to get info on it.
if(OnlineSub.CurrentInventory[i].Definition != ItemDefinition)
{
continue;
}
ItemCount += onlineSub.CurrentInventory[i].Quantity;
}
return ItemCount;
}
function Callback_CrateOpenComplete(int Rarity)
{
local name EventName;
switch (Rarity)
{
case ITR_Common:
EventName=SoundEvent_Common;
break;
case ITR_Uncommon:
EventName=SoundEvent_Uncommon;
break;
case ITR_Rare:
EventName=SoundEvent_Rare;
break;
case ITR_Legendary:
EventName=SoundEvent_Legendary;
break;
case ITR_ExceedinglyRare:
EventName=SoundEvent_ExceedinglyRare;
break;
case ITR_Mythical:
EventName=SoundEvent_Mythical;
break;
default:
EventName=SoundEvent_Common;
}
Manager.PlaySoundFromTheme(EventName, SoundThemeName);
}
function Callback_RequestInitialnventory()
{
InitInventory();
}
function Callback_InventoryFilter( int FilterIndex )
{
local EINventory_Filter NewFilter;
switch (FilterIndex)
{
case 0:
NewFilter = EInv_All;
break;
case 1:
NewFilter = EInv_WeaponSkins;
break;
case 2:
NewFilter = EInv_Cosmetics;
break;
case 3:
NewFilter = EInv_Consumables;
break;
case 4:
NewFilter = EInv_CraftingMats;
break;
case 5:
NewFilter = EInv_Emotes;
break;
case 6:
NewFilter = EInv_SFX;
break;
}
if(NewFilter != CurrentInventoryFilter)
{
CurrentInventoryFilter = NewFilter;
InitInventory();
}
}
function Callback_Equip( int ItemDefinition )
{
local class<KFWeaponDefinition> WeaponDef;
local int ItemIndex;
ItemIndex = class'KFWeaponSkinList'.default.Skins.Find('Id', ItemDefinition);
if(ItemIndex == INDEX_NONE)
{
return;
}
WeaponDef = class'KFWeaponSkinList'.default.Skins[ItemIndex].WeaponDef;
if(WeaponDef != none)
{
if(IsItemActive(ItemDefinition))
{
class'KFWeaponSkinList'.Static.SaveWeaponSkin(WeaponDef, 0);
if(class'WorldInfo'.static.IsConsoleBuild( ))
{
Manager.CachedProfile.ClearWeaponSkin(WeaponDef.default.WeaponClassPath);
}
}
else
{
class'KFWeaponSkinList'.Static.SaveWeaponSkin(WeaponDef, ItemDefinition);
if(class'WorldInfo'.static.IsConsoleBuild( ))
{
Manager.CachedProfile.SaveWeaponSkin(WeaponDef.default.WeaponClassPath, ItemDefinition);
}
}
}
//refresh inventory
NeedToRegenerateSkinList = true; // need to regenerate as the equipped state changed
InitInventory();
}
function Callback_EquipSFX(int ItemDefinition)
{
local int ItemIndex;
ItemIndex = class'KFHeadShotEffectList'.static.GetHeadShotEffectIndex(ItemDefinition);
if (ItemIndex == INDEX_NONE)
{
return;
}
if (IsSFXActive(ItemDefinition))
{
class'KFHeadShotEffectList'.Static.SaveEquippedHeadShotEffect(0);
}
else
{
class'KFHeadShotEffectList'.Static.SaveEquippedHeadShotEffect(ItemDefinition);
}
//refresh inventory
InitInventory();
}
function CallBack_ItemDetailsClicked(int ItemDefinition)
{
//get the item and then set the use button label based on if the exchange rule is ready
local array<ExchangeRuleSets> ExchangeRules;
local ItemProperties NeededItem, CurrItem;
local Int NeededItemID;
CurrItem = OnlineSub.ItemPropertiesList[OnlineSub.ItemPropertiesList.Find('Definition', ItemDefinition)];
if( CurrItem.RequiredKeyId != "" )
{
OnlineSub.HasKeyForItem( ItemDefinition, NeededItemID );
}
else
{
OnlineSub.IsExchangeable(ItemDefinition, ExchangeRules);
if(ExchangeRules.length <= 0)
{
//`log("NO RULES EXIST FOR THIS ITEM!" @ItemDefinition);
return;
}
if(!OnlineSub.ExchangeReady(ExchangeRules[0]))
{
///get needed item from rule set
if(ExchangeRules[0].Sources[0].Definition == ItemDefinition)
{
if(ExchangeRules[0].Sources.length > 1)
{
NeededItemID = ExchangeRules[0].Sources[1].Definition;
}
}
else
{
NeededItemID = ExchangeRules[0].Sources[0].Definition;
}
}
}
// Set equip button if we need an item
if( NeededItemID > 0 )
{
NeededItem = OnlineSub.ItemPropertiesList[OnlineSub.ItemPropertiesList.Find('Definition', NeededItemID)];
if(NeededItem.Price == "")
{
EquipButton.SetString("label", LookUpOnMarketString);
}
else
{
EquipButton.SetString("label", PurchaseKeyString @ ((class'WorldInfo'.static.IsConsoleBuild() || class'WorldInfo'.static.isEosBuild()) ? "" : (":"@NeededItem.Price)));
}
}
}
function Callback_UseItem( int ItemDefinition )
{
local array<ExchangeRuleSets> ExchangeRules;
local string ItemSeriesCommand;
local ItemProperties NeededItem, CurrItem;
local Int NeededItemID;
//local bool bExchangeFound;
local int RuleIndex;
//`log("using item ["$ItemDefinition$"]");
// Some playfab items require keys
TempItemIdHolder = ItemDefinition;
CurrItem = OnlineSub.ItemPropertiesList[OnlineSub.ItemPropertiesList.Find('Definition', ItemDefinition)];
if (CurrItem.Type == ITP_CraftingComponent)
{
Callback_CraftOption(ItemDefinition);
return;
}
if( IsSpecialEventItem(TempItemIdHolder) )
{
//`log("is special");
Callback_CraftOption(TempItemIdHolder);
return;
}
// any recipes involving this item? return only those
if ( OnlineSub.IsExchangeable(TempItemIdHolder, ExchangeRules) == 0 )
{
//`log("is not exchangeable");
return;
}
// run through the rules (there will typically be only one) and
// pick the one that is NOT the recycle recipe, as defined by
// having a CraftingComponent target
for (RuleIndex = 0; RuleIndex < ExchangeRules.length; RuleIndex++)
{
if ( ExchangeRules[RuleIndex].Type == ITP_CraftingComponent )
{
//`log("crafting, no go ["$ExchangeRules[RuleIndex].Type$"]" );
continue;
}
// Check to see if we have the key, if not, record what we DO
// need and prompt the user to spend money
if ( OnlineSub.ExchangeReady(ExchangeRules[RuleIndex]) )
{
//`log("ready");
SetVisible(false);
PerformExchange( ExchangeRules[RuleIndex], false );
ItemSeriesCommand = "CE open_"$class'KFInventoryCatalog'.static.GetItemSeries(ItemDefinition);
KFPC.ConsoleCommand( ItemSeriesCommand );
}
else if ( ExchangeRules[RuleIndex].Sources.length > 1 )
{
//`log("not ready <1> length ["$ExchangeRules[RuleIndex].Sources.length$"]" );
if( ExchangeRules[RuleIndex].Sources[0].Definition == ItemDefinition )
{
NeededItemID = ExchangeRules[RuleIndex].Sources[1].Definition;
//`log("need <1> ["$NeededItemID$"]");
}
else
{
NeededItemID = ExchangeRules[RuleIndex].Sources[0].Definition;
//`log("need <2> ["$NeededItemID$"]");
}
}
else
{
//`log("not ready <2>");
}
}
if( NeededItemID > 0 )
{
NeededItem = OnlineSub.ItemPropertiesList[OnlineSub.ItemPropertiesList.Find('Definition', NeededItemID)];
if(NeededItem.Price == "" || NeededItem.SignedOfferId != "")
{
if( class'WorldInfo'.static.IsConsoleBuild( CONSOLE_Durango ) )
{
OnlineSub.PlayerInterfaceEx.ShowProductDetailsUI( GetLP().ControllerId, NeededItem.ProductID );
}
else
{
if (OnlineSub.IsGameOwned())
{
//open market place item
OnlineSub.OpenMarketPlaceSearch(NeededItem);
}
else
{
Manager.DisplayFreeTrialFeatureBlockedPopUp();
}
}
}
else
{
if (OnlineSub.IsGameOwned())
{
//open key purchase
OnlineSub.OpenItemPurchaseOverlay(NeededItemID);
}
else
{
Manager.DisplayFreeTrialFeatureBlockedPopUp();
}
}
}
}
function Callback_CharacterSkin( int ItemDefinition )
{
}
function Callback_RecycleItem( int ItemDefinition )
{
local int MatchingItemCount;
TempItemIdHolder = ItemDefinition;
//Get how man we have.
MatchingItemCount = GetItemCount(ItemDefinition);
//If we have more than X number,
if(MatchingItemCount >= ValueToPromptDuplicateRecycle)
{
//give a third choice to recycle duplicates
Manager.DelayedOpenPopup( EConfirmation,EDPPID_Misc,
RecycleItemString,
RecycleWarningString,
RecycleDuplicatesString,
class'KFCommon_LocalizedStrings'.default.CancelString,
ConfirmDuplicatesRecycle,
CancelRecycle,
RecycleOneString,
ConfirmRecycle );
}
else
{
//else give standard recycle pop up
Manager.DelayedOpenPopup( EConfirmation,EDPPID_Misc,
RecycleItemString,
RecycleWarningString,
class'KFCommon_LocalizedStrings'.default.ConfirmString,
class'KFCommon_LocalizedStrings'.default.CancelString,
ConfirmRecycle );
}
}
function Callback_CraftOption(int ItemDefinition)
{
local array<ExchangeRuleSets> ExchangeRules;
local int RuleIndex;
TempItemIdHolder = ItemDefinition;
//`log("CRAFT OPTION CALLED!");
OnlineSub.IsExchangeable(TempItemIdHolder, ExchangeRules);
for (RuleIndex = 0; RuleIndex < ExchangeRules.length; RuleIndex++)
{
if(OnlineSub.ExchangeReady(ExchangeRules[RuleIndex]))
{
//`log("FOUND THE RULES!!");
Manager.DelayedOpenPopup(EConfirmation,EDPPID_Misc, CraftItemString, ConfirmCraftItemString, class'KFCommon_LocalizedStrings'.default.ConfirmString, class'KFCommon_LocalizedStrings'.default.CancelString, ConfirmCraft );
return;
}
}
//`log("NO DICE SHOW BAD POP UP!");
Manager.DelayedOpenPopup(ENotification,EDPPID_Misc, FailedToCraftItemString, CraftRequirementString, class'KFCommon_LocalizedStrings'.default.OKString);
}
function Callback_WeaponTypeFilterChanged(int NewFilterIndex)
{
CurrentWeaponTypeFilter = EInventoryWeaponType_Filter(NewFilterIndex);
//refresh
InitInventory();
}
function Callback_RarityTypeFilterChanged(int NewFilterIndex)
{
CurrentRarityFilter = ItemRarity(NewFilterIndex);
InitInventory();
}
function Callback_PerkTypeFilterChanged(int NewFilterIndex)
{
CurrentPerkIndexFilter = NewFilterIndex;
InitInventory();
}
function CallBack_RequestCosmeticCraftInfo()
{
SetCosmeticCraftDetails();
}
function CallBack_RequestWeaponCraftInfo()
{
SetWeaponCraftDetails();
}
function Callback_PreviewItem( int ItemDefinition )
{
if(KFPH != none)
{
//KFPH.AttachWeaponByItemDefinition(ItemDefinition);
}
}
defaultproperties
{
NeedToRegenerateSkinList=false
CurrentWeaponTypeFilter = EInvWT_None;
CurrentRarityFilter = ITR_NONE;
ValueToPromptDuplicateRecycle=3
SoundEvent_Common=Crate_End_Common
SoundEvent_Uncommon=Crate_End_Uncommon
SoundEvent_Rare=Crate_End_Rare
SoundEvent_Legendary=Crate_End_Lengendary
SoundEvent_ExceedinglyRare=Crate_End_ExeedinglyRare
SoundEvent_Mythical=Crate_End_Mythical
SoundThemeName=SoundTheme_Crate
UncommonCosmeticID=3708
RareCosmeticID=3709
ExceptionalCosmeticID=3710
MasterCosmeticID=3711
UncommonWeaponID=3712
RareWeaponID=3713
ExceptionalWeaponID=3714
MasterWeaponID=3715
SpecialEventItemIDs(0)=4896
SpecialEventItemIDs(1)=4928
SpecialEventItemIDs(2)=4929
SpecialEventItemIDs(3)=5247
SpecialEventItemIDs(4)=5246
SpecialEventItemIDs(5)=5245
SpecialEventItemIDs(6)=5304
SpecialEventItemIDs(7)=5587
SpecialEventItemIDs(8)=5588
SpecialEventItemIDs(9)=5589
SpecialEventItemIDs(10)=5802
SpecialEventItemIDs(11)=5803
SpecialEventItemIDs(12)=5804
KeylessCrateIDs(0)=5313
KillThatDangSoundEvent=AkEvent'WW_UI_Menu.Play_UI_Trader_Build_Stop_No_Sound'
}