/***********************************************************************/ /** © 2015 CD PROJEKT S.A. All rights reserved. /** THE WITCHER® is a trademark of CD PROJEKT S. A. /** The Witcher game is based on the prose of Andrzej Sapkowski. /***********************************************************************/ class IInventoryScriptedListener { event OnInventoryScriptedEvent( eventType : EInventoryEventType, itemId : SItemUniqueId, quantity : int, fromAssociatedInventory : bool ) {} } import struct SItemNameProperty { import editable var itemName : name; }; import struct SR4LootNameProperty { import editable var lootName : name; }; struct SItemExt { editable var itemName : SItemNameProperty; editable var quantity : int; default quantity = 1; }; struct SCardSourceData { var cardName : name; var source : string; var originArea : string; var originQuest : string; var details : string; var coords : string; }; import struct SItemChangedData { import const var itemName : name; import const var quantity : int; import const var informGui : bool; import const var ids : array< SItemUniqueId >; }; import class CInventoryComponent extends CComponent { editable var priceMult : float; editable var priceRepairMult : float; editable var priceRepair : float; editable var fundsType : EInventoryFundsType; private var recentlyAddedItems : array; private var fundsMax : int; private var daysToIncreaseFunds : int; default priceMult = 1.0; default priceRepairMult = 1.0; default priceRepair = 10.0; default fundsType = EInventoryFunds_Avg; default daysToIncreaseFunds = 5; public function GetFundsType() : EInventoryFundsType { return fundsType; } public function GetDaysToIncreaseFunds() : int { return daysToIncreaseFunds; } public function GetFundsMax() : float { if ( EInventoryFunds_Broke == fundsType ) { return 0; } else if ( EInventoryFunds_Avg == fundsType ) { return 5000; } else if ( EInventoryFunds_Poor == fundsType ) { return 2500; } else if ( EInventoryFunds_Rich == fundsType ) { return 7500; } else if ( EInventoryFunds_RichQuickStart == fundsType ) { return 15000; } return -1; } public function SetupFunds() { if ( EInventoryFunds_Broke == fundsType ) { AddMoney( 0 ); } else if ( EInventoryFunds_Poor == fundsType ) { AddMoney( (int)( 200 * GetFundsModifier() ) ); } else if ( EInventoryFunds_Avg == fundsType ) { AddMoney( (int)( 500 * GetFundsModifier() ) ); } else if ( EInventoryFunds_Rich == fundsType ) { AddMoney( (int)( 1000 * GetFundsModifier() ) ); } else if ( EInventoryFunds_RichQuickStart == fundsType ) { AddMoney( (int)( 5000 * GetFundsModifier() ) ); } } public function IncreaseFunds() { if ( GetMoney() < GetFundsMax() ) { if ( EInventoryFunds_Avg == fundsType ) { AddMoney( (int)( 150 * GetFundsModifier()) ); } else if ( EInventoryFunds_Poor == fundsType ) { AddMoney( (int)( 100 * GetFundsModifier() ) ); } else if ( EInventoryFunds_Rich == fundsType ) { AddMoney( (int)( 1000 * GetFundsModifier() ) ); } else if ( EInventoryFunds_RichQuickStart == fundsType ) { AddMoney( 1000 + (int)( 2500 * GetFundsModifier() ) ); } } } public function GetMoney() : int { return GetItemQuantityByName( 'Crowns' ); } public function SetMoney( amount : int ) { var currentMoney : int; if ( amount >= 0 ) { currentMoney = GetMoney(); RemoveMoney( currentMoney ); AddAnItem( 'Crowns', amount ); } } public function AddMoney( amount : int ) { if ( amount > 0 ) { AddAnItem( 'Crowns', amount ); if ( thePlayer == GetEntity() ) { theTelemetry.LogWithValue( TE_HERO_CASH_CHANGED, amount ); } } } public function RemoveMoney( amount : int ) { if ( amount > 0 ) { RemoveItemByName( 'Crowns', amount ); if ( thePlayer == GetEntity() ) { theTelemetry.LogWithValue( TE_HERO_CASH_CHANGED, -amount ); } } } import final function GetItemAbilityAttributeValue( itemId : SItemUniqueId, attributeName : name, abilityName : name) : SAbilityAttributeValue; import final function GetItemFromSlot( slotName : name ) : SItemUniqueId; import final function IsIdValid( itemId : SItemUniqueId ) : bool; import final function GetItemCount( optional useAssociatedInventory : bool ) : int; import final function GetItemsNames() : array< name >; import final function GetAllItems( out items : array< SItemUniqueId > ); import public function GetItemId( itemName : name ) : SItemUniqueId; import public function GetItemsIds( itemName : name ) : array< SItemUniqueId >; import final function GetItemsByTag( tag : name ) : array< SItemUniqueId >; import final function GetItemsByCategory( category : name ) : array< SItemUniqueId >; import final function GetSchematicIngredients(itemName : SItemUniqueId, out quantity : array, out names : array); import final function GetSchematicRequiredCraftsmanType(craftName : SItemUniqueId) : name; import final function GetSchematicRequiredCraftsmanLevel(craftName : SItemUniqueId) : name; import final function GetNumOfStackedItems( itemUniqueId: SItemUniqueId ) : int; import final function InitInvFromTemplate( resource : CEntityTemplate ); import final function SplitItem( itemID : SItemUniqueId, quantity : int ) : SItemUniqueId; import final function SetItemStackable( itemID : SItemUniqueId, flag : bool ); import final function GetCategoryDefaultItem( category : name ) : name; import final function GetItemLocalizedNameByName( itemName : CName ) : string; import final function GetItemLocalizedDescriptionByName( itemName : CName ) : string; import final function GetItemLocalizedNameByUniqueID( itemUniqueId : SItemUniqueId ) : string; import final function GetItemLocalizedDescriptionByUniqueID( itemUniqueId : SItemUniqueId ) : string; import final function GetItemIconPathByUniqueID( itemUniqueId : SItemUniqueId ) : string; import final function GetItemIconPathByName( itemName : CName ) : string; import final function AddSlot( itemUniqueId : SItemUniqueId ) : bool; import final function GetSlotItemsLimit( itemUniqueId : SItemUniqueId ) : int; import private final function BalanceItemsWithPlayerLevel( playerLevel : int ); public function ForceSpawnItemOnStart( itemId : SItemUniqueId ) : bool { return ItemHasTag(itemId, 'MutagenIngredient'); } public final function GetItemArmorTotal(item : SItemUniqueId) : SAbilityAttributeValue { var armor, armorBonus : SAbilityAttributeValue; var durMult : float; armor = GetItemAttributeValue(item, theGame.params.ARMOR_VALUE_NAME); armorBonus = GetRepairObjectBonusValueForArmor(item); durMult = theGame.params.GetDurabilityMultiplier( GetItemDurabilityRatio(item), false); return armor * durMult + armorBonus; } public final function GetItemLevel(item : SItemUniqueId) : int { var itemCategory : name; var itemAttributes : array; var itemName : name; var isWitcherGear : bool; var isRelicGear : bool; var level, baseLevel : int; itemCategory = GetItemCategory(item); itemName = GetItemName(item); isWitcherGear = false; isRelicGear = false; if ( RoundMath(CalculateAttributeValue( GetItemAttributeValue(item, 'quality' ) )) == 5 ) isWitcherGear = true; if ( RoundMath(CalculateAttributeValue( GetItemAttributeValue(item, 'quality' ) )) == 4 ) isRelicGear = true; switch(itemCategory) { case 'armor' : case 'boots' : case 'gloves' : case 'pants' : itemAttributes.PushBack( GetItemAttributeValue(item, 'armor') ); break; case 'silversword' : itemAttributes.PushBack( GetItemAttributeValue(item, 'SilverDamage') ); itemAttributes.PushBack( GetItemAttributeValue(item, 'BludgeoningDamage') ); itemAttributes.PushBack( GetItemAttributeValue(item, 'RendingDamage') ); itemAttributes.PushBack( GetItemAttributeValue(item, 'ElementalDamage') ); itemAttributes.PushBack( GetItemAttributeValue(item, 'FireDamage') ); itemAttributes.PushBack( GetItemAttributeValue(item, 'PiercingDamage') ); break; case 'steelsword' : itemAttributes.PushBack( GetItemAttributeValue(item, 'SlashingDamage') ); itemAttributes.PushBack( GetItemAttributeValue(item, 'BludgeoningDamage') ); itemAttributes.PushBack( GetItemAttributeValue(item, 'RendingDamage') ); itemAttributes.PushBack( GetItemAttributeValue(item, 'ElementalDamage') ); itemAttributes.PushBack( GetItemAttributeValue(item, 'FireDamage') ); itemAttributes.PushBack( GetItemAttributeValue(item, 'SilverDamage') ); itemAttributes.PushBack( GetItemAttributeValue(item, 'PiercingDamage') ); break; case 'crossbow' : itemAttributes.PushBack( GetItemAttributeValue(item, 'attack_power') ); break; default : break; } level = theGame.params.GetItemLevel(itemCategory, itemAttributes, itemName, baseLevel); if ( FactsQuerySum("NewGamePlus") > 0 ) { if ( baseLevel > GetWitcherPlayer().GetMaxLevel() ) { level = baseLevel; } } if ( isWitcherGear ) level = level - 2; if ( isRelicGear ) level = level - 1; if ( level < 1 ) level = 1; if ( ItemHasTag(item, 'OlgierdSabre') ) level = level - 3; if ( (isRelicGear || isWitcherGear) && ItemHasTag(item, 'EP1') ) level = level - 1; if ( FactsQuerySum("NewGamePlus") > 0 ) { if ( level > GetWitcherPlayer().GetMaxLevel() ) { level = GetWitcherPlayer().GetMaxLevel(); } } return level; } public function GetItemLevelColorById( itemId : SItemUniqueId ) : string { var color : string; if (GetItemLevel(itemId) <= thePlayer.GetLevel()) { color = ""; } else { color = ""; } return color; } public function GetItemLevelColor( lvl_item : int ) : string { var color : string; if ( lvl_item > thePlayer.GetLevel() ) { color = ""; } else { color = ""; } return color; } public final function AutoBalanaceItemsWithPlayerLevel() { var playerLevel : int; playerLevel = thePlayer.GetLevel(); if( playerLevel < 0 ) { playerLevel = 0; } BalanceItemsWithPlayerLevel( playerLevel ); } public function GetItemsByName(itemName : name) : array { var ret : array; var i : int; if(!IsNameValid(itemName)) return ret; GetAllItems(ret); for(i=ret.Size()-1; i>=0; i-=1) { if(GetItemName(ret[i]) != itemName) { ret.EraseFast( i ); } } return ret; } public final function GetSingletonItems() : array { return GetItemsByTag(theGame.params.TAG_ITEM_SINGLETON); } import final function GetItemQuantityByName( itemName : name, optional useAssociatedInventory : bool , optional ignoreTags : array< name > ) : int; import final function GetItemQuantityByCategory( itemCategory : name, optional useAssociatedInventory : bool , optional ignoreTags : array< name > ) : int; import final function GetItemQuantityByTag( itemTag : name, optional useAssociatedInventory : bool , optional ignoreTags : array< name > ) : int; import final function GetAllItemsQuantity( optional useAssociatedInventory : bool , optional ignoreTags : array< name > ) : int; public function IsEmpty(optional bSkipNoDropNoShow : bool) : bool { var i : int; var itemIds : array; if(bSkipNoDropNoShow) { GetAllItems( itemIds ); for( i = itemIds.Size() - 1; i >= 0; i -= 1 ) { if( !ItemHasTag( itemIds[ i ],theGame.params.TAG_DONT_SHOW ) && !ItemHasTag( itemIds[ i ], 'NoDrop' ) ) { return false; } else if ( ItemHasTag( itemIds[ i ], 'Lootable') ) { return false; } } return true; } return GetItemCount() <= 0; } public function GetAllHeldAndMountedItemsCategories( out heldItems : array, optional out mountedItems : array ) { var allItems : array; var i : int; GetAllItems(allItems); for(i=allItems.Size()-1; i >= 0; i-=1) { if ( IsItemHeld(allItems[i]) ) heldItems.PushBack(GetItemCategory(allItems[i])); else if ( IsItemMounted(allItems[i]) ) mountedItems.PushBack(GetItemCategory(allItems[i])); } } public function GetAllHeldItemsNames( out heldItems : array ) { var allItems : array; var i : int; GetAllItems(allItems); for(i=allItems.Size()-1; i >= 0; i-=1) { if ( IsItemHeld(allItems[i]) ) heldItems.PushBack(GetItemName(allItems[i])); } } public function HasMountedItemByTag(tag : name) : bool { var i : int; var allItems : array; if(!IsNameValid(tag)) return false; allItems = GetItemsByTag(tag); for(i=0; i; if(!IsNameValid(tag)) return false; allItems = GetItemsByTag(tag); for(i=0; i ) : bool; import final function GetCraftedItemName( itemId : SItemUniqueId ) : name; import final function TotalItemStats( invItem : SInventoryItem ) : float; import final function GetItemPrice( itemId : SItemUniqueId ) : int; import final function GetItemPriceModified( itemId : SItemUniqueId, optional playerSellingItem : Bool ) : int; import final function GetInventoryItemPriceModified( invItem : SInventoryItem, optional playerSellingItem : Bool ) : int; import final function GetItemPriceRepair( invItem : SInventoryItem, out costRepairPoint : int, out costRepairTotal : int ); import final function GetItemPriceRemoveUpgrade( invItem : SInventoryItem ) : int; import final function GetItemPriceDisassemble( invItem : SInventoryItem ) : int; import final function GetItemPriceAddSlot( invItem : SInventoryItem ) : int; import final function GetItemPriceCrafting( invItem : SInventoryItem ) : int; import final function GetItemPriceEnchantItem( invItem : SInventoryItem ) : int; import final function GetItemPriceRemoveEnchantment( invItem : SInventoryItem ) : int; import final function GetFundsModifier() : float; import final function GetItemQuantity( itemId : SItemUniqueId ) : int; import final function ItemHasTag( itemId : SItemUniqueId, tag : name ) : bool; import final function AddItemTag( itemId : SItemUniqueId, tag : name ) : bool; import final function RemoveItemTag( itemId : SItemUniqueId, tag : name ) : bool; public final function ManageItemsTag( items : array, tag : name, add : bool ) { var i : int; if( add ) { for( i = 0 ; i < items.Size() ; i += 1 ) { AddItemTag( items[ i ], tag ); } } else { for( i = 0 ; i < items.Size() ; i += 1 ) { RemoveItemTag( items[ i ], tag ); } } } import final function GetItemByItemEntity( itemEntity : CItemEntity ) : SItemUniqueId; public function ItemHasAbility(item : SItemUniqueId, abilityName : name) : bool { var abilities : array; GetItemAbilities(item, abilities); return abilities.Contains(abilityName); } import final function GetItemAttributeValue( itemId : SItemUniqueId, attributeName : name, optional abilityTags : array< name >, optional withoutTags : bool ) : SAbilityAttributeValue; import final function GetItemBaseAttributes( itemId : SItemUniqueId, out attributes : array ); import final function GetItemAttributes( itemId : SItemUniqueId, out attributes : array ); import final function GetItemAbilities( itemId : SItemUniqueId, out abilities : array ); import final function GetItemContainedAbilities( itemId : SItemUniqueId, out abilities : array ); public function GetItemAbilitiesWithAttribute(id : SItemUniqueId, attributeName : name, attributeVal : float) : array { var i : int; var abs, ret : array; var dm : CDefinitionsManagerAccessor; var val : float; var min, max : SAbilityAttributeValue; GetItemAbilities(id, abs); dm = theGame.GetDefinitionsManager(); for(i=0; i ) { var i : int; var dm : CDefinitionsManagerAccessor; var allAbilities : array; dm = theGame.GetDefinitionsManager(); GetItemAbilities(itemId, allAbilities); for(i=0; i; public final function GiveMoneyTo(otherInventory : CInventoryComponent, optional quantity : int, optional informGUI : bool ) { var moneyId : array; moneyId = GetItemsByName('Crowns'); GiveItemTo(otherInventory, moneyId[0], quantity, false, true, informGUI); } public final function GiveItemTo( otherInventory : CInventoryComponent, itemId : SItemUniqueId, optional quantity : int, optional refreshNewFlag : bool, optional forceTransferNoDrops : bool, optional informGUI : bool ) : SItemUniqueId { var arr : array; var itemName : name; var i : int; var uiData : SInventoryItemUIData; var isQuestItem : bool; if(quantity == 0) quantity = 1; quantity = Clamp(quantity, 0, GetItemQuantity(itemId)); if(quantity == 0) return GetInvalidUniqueId(); itemName = GetItemName(itemId); if(!forceTransferNoDrops && ( ItemHasTag(itemId, 'NoDrop') && !ItemHasTag(itemId, 'Lootable') )) { LogItems("Cannot transfer item <<" + itemName + ">> as it has the NoDrop tag set!!!"); return GetInvalidUniqueId(); } if(IsItemSingletonItem(itemId)) { if(otherInventory == thePlayer.inv && otherInventory.GetItemQuantityByName(itemName) > 0) { LogAssert(false, "CInventoryComponent.GiveItemTo: cannot add singleton item as player already has this item!"); return GetInvalidUniqueId(); } else { arr = GiveItem(otherInventory, itemId, quantity); } } else { arr = GiveItem(otherInventory, itemId, quantity); } if(otherInventory == thePlayer.inv) { isQuestItem = this.IsItemQuest( itemId ); theTelemetry.LogWithLabelAndValue(TE_INV_ITEM_PICKED, itemName, quantity); if ( !theGame.AreSavesLocked() && ( isQuestItem || this.GetItemQuality( itemId ) >= 4 ) ) { theGame.RequestAutoSave( "item gained", false ); } } if (refreshNewFlag) { for (i = 0; i < arr.Size(); i += 1) { uiData = otherInventory.GetInventoryItemUIData( arr[i] ); uiData.isNew = true; otherInventory.SetInventoryItemUIData( arr[i], uiData ); } } return arr[0]; } public final function GiveAllItemsTo(otherInventory : CInventoryComponent, optional forceTransferNoDrops : bool, optional informGUI : bool) { var items : array; GetAllItems(items); GiveItemsTo(otherInventory, items, forceTransferNoDrops, informGUI); } public final function GiveItemsTo(otherInventory : CInventoryComponent, items : array, optional forceTransferNoDrops : bool, optional informGUI : bool) : array { var i : int; var ret : array; for( i = 0; i < items.Size(); i += 1 ) { ret.PushBack(GiveItemTo(otherInventory, items[i], GetItemQuantity(items[i]), true, forceTransferNoDrops, informGUI)); } return ret; } import final function HasItem( item : name ) : bool; final function HasItemById(id : SItemUniqueId) : bool { var arr : array; GetAllItems(arr); return arr.Contains(id); } public function HasItemByTag(tag : name) : bool { var quantity : int; quantity = GetItemQuantityByTag( tag ); return quantity > 0; } public function HasItemByCategory(category : name) : bool { var quantity : int; quantity = GetItemQuantityByCategory( category ); return quantity > 0; } public function HasInfiniteBolts() : bool { var ids : array; var i : int; ids = GetItemsByTag(theGame.params.TAG_INFINITE_AMMO); for(i=0; i; var i : int; ids = GetItemsByTag(theGame.params.TAG_GROUND_AMMO); for(i=0; i; var i : int; ids = GetItemsByTag(theGame.params.TAG_UNDERWATER_AMMO); for(i=0; i; import private final function AddSingleItem( item : name, optional informGui : bool , optional markAsNew : bool , optional lootable : bool ) : SItemUniqueId; public final function AddAnItem(item : name, optional quantity : int, optional dontInformGui : bool, optional dontMarkAsNew : bool, optional showAsRewardInUIHax : bool) : array { var arr : array; var i : int; var isReadableItem : bool; if( theGame.GetDefinitionsManager().IsItemSingletonItem(item) && GetEntity() == thePlayer) { if(GetItemQuantityByName(item) > 0) { arr = GetItemsIds(item); } else { arr.PushBack(AddSingleItem(item, !dontInformGui, !dontMarkAsNew)); } quantity = 1; } else { if(quantity < 2 ) { arr.PushBack(AddSingleItem(item, !dontInformGui, !dontMarkAsNew)); } else { arr = AddMultiItem(item, quantity, !dontInformGui, !dontMarkAsNew); } } if(this == thePlayer.GetInventory()) { if(ItemHasTag(arr[0],'ReadableItem')) UpdateInitialReadState(arr[0]); if(showAsRewardInUIHax || ItemHasTag(arr[0],'GwintCard')) thePlayer.DisplayItemRewardNotification(GetItemName(arr[0]), quantity ); } return arr; } import final function RemoveItem( itemId : SItemUniqueId, optional quantity : int ) : bool; private final function InternalRemoveItems(ids : array, quantity : int) { var i, currQuantityToTake : int; for(i=0; i0, "CInventoryComponent.InternalRemoveItems(" + GetItemName(ids[i]) + "): somehow took too many items! Should be " + (-quantity) + " less... Investigate!"); } } public function RemoveItemByName(itemName : name, optional quantity : int) : bool { var totalItemCount : int; var ids : array; totalItemCount = GetItemQuantityByName(itemName); if(totalItemCount < quantity || quantity == 0) { return false; } if(quantity == 0) { quantity = 1; } else if(quantity < 0) { quantity = totalItemCount; } ids = GetItemsIds(itemName); if(GetEntity() == thePlayer && thePlayer.GetSelectedItemId() == ids[0] ) { thePlayer.ClearSelectedItemId(); } InternalRemoveItems(ids, quantity); return true; } public function RemoveItemByCategory(itemCategory : name, optional quantity : int) : bool { var totalItemCount : int; var ids : array; var selectedItemId : SItemUniqueId; var i : int; totalItemCount = GetItemQuantityByCategory(itemCategory); if(totalItemCount < quantity) { return false; } if(quantity == 0) { quantity = 1; } else if(quantity < 0) { quantity = totalItemCount; } ids = GetItemsByCategory(itemCategory); if(GetEntity() == thePlayer) { selectedItemId = thePlayer.GetSelectedItemId(); for(i=0; i; var i : int; var selectedItemId : SItemUniqueId; totalItemCount = GetItemQuantityByTag(itemTag); if(totalItemCount < quantity) { return false; } if(quantity == 0) { quantity = 1; } else if(quantity < 0) { quantity = totalItemCount; } ids = GetItemsByTag(itemTag); if(GetEntity() == thePlayer) { selectedItemId = thePlayer.GetSelectedItemId(); for(i=0; i ) : CEntity; import final function ThrowAwayLootableItems( optional skipNoDropNoShow : bool ) : CEntity; import final function GetItemRecyclingParts( itemId : SItemUniqueId ) : array; import final function GetItemWeight( id : SItemUniqueId ) : float; public final function HasQuestItem() : bool { var allItems : array< SItemUniqueId >; var i : int; allItems = GetItemsByTag('Quest'); for ( i=0; i theGame.params.ITEM_DAMAGED_DURABILITY ) { FactsAdd( "tut_item_damaged", 1 ); } } } SetItemDurability( itemId, durability ); } public function ReduceItemDurability(itemId : SItemUniqueId, optional forced : bool) : bool { var dur, value, durabilityDiff, itemToughness, indestructible : float; var chance : int; //LZ_SLOTS_BEGIN var min, max : SAbilityAttributeValue; //LZ_SLOTS_END if(!IsIdValid(itemId) || !HasItemDurability(itemId) || ItemHasAbility(itemId, 'MA_Indestructible')) { return false; } if(IsItemWeapon(itemId)) { chance = theGame.params.DURABILITY_WEAPON_LOSE_CHANCE; value = theGame.params.GetWeaponDurabilityLoseValue(); } else if(IsItemAnyArmor(itemId)) { chance = theGame.params.DURABILITY_ARMOR_LOSE_CHANCE; value = theGame.params.DURABILITY_ARMOR_LOSE_VALUE; } dur = GetItemDurability(itemId); if ( dur == 0 ) { return false; } if ( forced || RandRange( 100 ) < chance ) { itemToughness = CalculateAttributeValue( GetItemAttributeValue( itemId, 'toughness' ) ); indestructible = CalculateAttributeValue( GetItemAttributeValue( itemId, 'indestructible' ) ); value = value * ( 1 - indestructible ); //LZ_SLOTS_BEGIN if( GetWitcherPlayer().IsMutationActive( EPMT_Mutation17 ) ){ theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation17', 'equip_degrade_factor', min, max ); value *= min.valueMultiplicative;} //LZ_SLOTS_END if ( itemToughness > 0.0f && itemToughness <= 1.0f ) { durabilityDiff = ( dur - value ) * itemToughness; SetItemDurabilityScript( itemId, MaxF(durabilityDiff, 0 ) ); } else { SetItemDurabilityScript( itemId, MaxF( dur - value, 0 ) ); } } return true; } public function GetItemDurabilityRatio(itemId : SItemUniqueId) : float { if ( !IsIdValid( itemId ) || !HasItemDurability( itemId ) ) return -1; return GetItemDurability(itemId) / GetItemMaxDurability(itemId); } public function GetItemResistStatWithDurabilityModifiers(itemId : SItemUniqueId, stat : ECharacterDefenseStats, out points : SAbilityAttributeValue, out percents : SAbilityAttributeValue) { var mult : float; var null : SAbilityAttributeValue; points = null; percents = null; if(!IsItemAnyArmor(itemId)) return; mult = theGame.params.GetDurabilityMultiplier(GetItemDurabilityRatio(itemId), false); points = GetItemAttributeValue(itemId, ResistStatEnumToName(stat, true)); percents = GetItemAttributeValue(itemId, ResistStatEnumToName(stat, false)); points = points * mult; percents = percents * mult; } public function GetItemResistanceTypes(id : SItemUniqueId) : array { var ret : array; var i : int; var stat : ECharacterDefenseStats; var atts : array; var tmpBool : bool; if(!IsIdValid(id)) return ret; GetItemAttributes(id, atts); for(i=0; i; var card : array; var iHave, shopHave, cardLimit, delta : int; var curItem : SItemUniqueId; var i : int; allItems = GetItemsByCategory('gwint'); for(i=allItems.Size()-1; i >= 0; i-=1) { curItem = allItems[i]; attr = GetItemAttributeValue( curItem, 'max_count'); card = thePlayer.GetInventory().GetItemsByName( GetItemName( curItem ) ); iHave = thePlayer.GetInventory().GetItemQuantity( card[0] ); cardLimit = RoundF(attr.valueBase); shopHave = GetItemQuantity( curItem ); if (iHave > 0 && shopHave > 0) { delta = shopHave - (cardLimit - iHave); if ( delta > 0 ) { RemoveItem( curItem, delta ); } } } } function ClearTHmaps() { var attr : SAbilityAttributeValue; var allItems : array; var map : array; var i : int; var thCompleted : bool; var iHave, shopHave : int; allItems = GetItemsByTag('ThMap'); for(i=allItems.Size()-1; i >= 0; i-=1) { attr = GetItemAttributeValue( allItems[i], 'max_count'); map = thePlayer.GetInventory().GetItemsByName( GetItemName( allItems[i] ) ); thCompleted = FactsDoesExist(GetItemName(allItems[i])); iHave = thePlayer.GetInventory().GetItemQuantity( map[0] ); shopHave = RoundF(attr.valueBase); if ( iHave >= shopHave || thCompleted ) { RemoveItem( allItems[i], GetItemQuantity( allItems[i] ) ); } } } public final function ClearKnownRecipes() { var witcher : W3PlayerWitcher; var recipes, craftRecipes : array; var i : int; var itemName : name; var allItems : array; witcher = GetWitcherPlayer(); if(!witcher) return; recipes = witcher.GetAlchemyRecipes(); craftRecipes = witcher.GetCraftingSchematicsNames(); ArrayOfNamesAppend(recipes, craftRecipes); GetAllItems(allItems); for(i=allItems.Size()-1; i>=0; i-=1) { itemName = GetItemName(allItems[i]); if(recipes.Contains(itemName)) RemoveItem(allItems[i], GetItemQuantity(allItems[i])); } } function LoadBooksDefinitions() : void { var readableArray : array; var i : int; readableArray = GetItemsByTag('ReadableItem'); for( i = 0; i < readableArray.Size(); i += 1 ) { if( IsBookRead(readableArray[i])) { continue; } UpdateInitialReadState(readableArray[i]); } } function UpdateInitialReadState( item : SItemUniqueId ) { var abilitiesArray : array; var i : int; GetItemAbilities(item,abilitiesArray); for( i = 0; i < abilitiesArray.Size(); i += 1 ) { if( abilitiesArray[i] == 'WasRead' ) { ReadBook(item); break; } } } function IsBookRead( item : SItemUniqueId ) : bool { var bookName : name; var bResult : bool; bookName = GetItemName( item ); bResult = IsBookReadByName( bookName ); return bResult; } function IsBookReadByName( bookName : name ) : bool { var bookFactName : string; bookFactName = GetBookReadFactName( bookName ); if( FactsDoesExist(bookFactName) ) { return FactsQuerySum( bookFactName ); } return false; } function ReadBook( item : SItemUniqueId, optional noNotification : bool ) { var bookName : name; var abilitiesArray : array; var i : int; var commonMapManager : CCommonMapManager = theGame.GetCommonMapManager(); bookName = GetItemName( item ); if ( !IsBookRead ( item ) && ItemHasTag ( item, 'FastTravel' )) { GetItemAbilities(item, abilitiesArray); for ( i = 0; i < abilitiesArray.Size(); i+=1 ) { commonMapManager.SetEntityMapPinDiscoveredScript(true, abilitiesArray[i], true ); } } ReadBookByNameId( bookName, item, false, noNotification ); if(ItemHasTag(item, 'PerkBook')) { } } public function GetBookText(item : SItemUniqueId) : string { if ( GetItemName( item ) != 'Gwent Almanac' ) { return ReplaceTagsToIcons(GetLocStringByKeyExt(GetItemLocalizedNameByUniqueID(item)+"_text")); } else { return GetGwentAlmanacContents(); } } public function GetBookTextByName( bookName : name ) : string { if( bookName != 'Gwent Almanac' ) { return ReplaceTagsToIcons( GetLocStringByKeyExt( GetItemLocalizedNameByName( bookName ) + "_text" ) ); } else { return GetGwentAlmanacContents(); } } function ReadSchematicsAndRecipes( item : SItemUniqueId ) { var itemCategory : name; var itemName : name; var player : W3PlayerWitcher; ReadBook( item ); player = GetWitcherPlayer(); if ( !player ) { return; } itemName = GetItemName( item ); itemCategory = GetItemCategory( item ); if ( itemCategory == 'alchemy_recipe' ) { if ( player.CanLearnAlchemyRecipe( itemName ) ) { player.AddAlchemyRecipe( itemName ); player.GetInventory().AddItemTag(item, 'NoShow'); } } else if ( itemCategory == 'crafting_schematic' ) { player.AddCraftingSchematic( itemName ); player.GetInventory().AddItemTag(item, 'NoShow'); } } function ReadBookByName( bookName : name , unread : bool, optional noNotification : bool ) { var defMgr : CDefinitionsManagerAccessor; var bookFactName : string; if( IsBookReadByName( bookName ) != unread ) { return; } bookFactName = "BookReadState_"+bookName; bookFactName = StrReplace(bookFactName," ","_"); if( unread ) { FactsSubstract( bookFactName, 1 ); } else { FactsAdd( bookFactName, 1 ); defMgr = theGame.GetDefinitionsManager(); if(!IsAlchemyRecipe(bookName) && !IsCraftingSchematic(bookName) && !defMgr.ItemHasTag( bookName, 'Painting' ) ) { theGame.GetGamerProfile().IncStat(ES_ReadBooks); if( !noNotification ) { theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt( "notification_book_moved" ), 0, false ); } } if ( AddBestiaryFromBook(bookName) ) return; } } function ReadBookByNameId( bookName : name, itemId:SItemUniqueId, unread : bool, optional noNotification : bool ) { var bookFactName : string; if( IsBookReadByName( bookName ) != unread ) { return; } bookFactName = "BookReadState_"+bookName; bookFactName = StrReplace(bookFactName," ","_"); if( unread ) { FactsSubstract( bookFactName, 1 ); } else { FactsAdd( bookFactName, 1 ); if( !IsAlchemyRecipe( bookName ) && !IsCraftingSchematic( bookName ) ) { theGame.GetGamerProfile().IncStat(ES_ReadBooks); if( !noNotification ) { GetWitcherPlayer().AddReadBook( bookName ); } } if ( AddBestiaryFromBook(bookName) ) return; else ReadSchematicsAndRecipes( itemId ); } } private function AddBestiaryFromBook( bookName : name ) : bool { var i, j, r, len : int; var manager : CWitcherJournalManager; var resource : array; var entryBase : CJournalBase; var childGroups : array; var childEntries : array; var descriptionGroup : CJournalCreatureDescriptionGroup; var descriptionEntry : CJournalCreatureDescriptionEntry; manager = theGame.GetJournalManager(); switch ( bookName ) { case 'Beasts vol 1': resource.PushBack( (CJournalResource)LoadResource( "BestiaryWolf" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryDog" ) ); break; case 'Beasts vol 2': resource.PushBack( (CJournalResource)LoadResource( "BestiaryBear" ) ); break; case 'Cursed Monsters vol 1': resource.PushBack( (CJournalResource)LoadResource( "BestiaryWerewolf" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryLycanthrope" ) ); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 24'); break; case 'Cursed Monsters vol 2': resource.PushBack( (CJournalResource)LoadResource( "BestiaryWerebear" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryMiscreant" ) ); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 11'); break; case 'Draconides vol 1': resource.PushBack( (CJournalResource)LoadResource( "BestiaryCockatrice" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryBasilisk" ) ); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 3'); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 23'); break; case 'Draconides vol 2': resource.PushBack( (CJournalResource)LoadResource( "BestiaryWyvern" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryForktail" ) ); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 10'); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 17'); break; case 'Hybrid Monsters vol 1': resource.PushBack( (CJournalResource)LoadResource( "BestiaryHarpy" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryErynia" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiarySiren" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiarySuccubus" ) ); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 14'); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 21'); break; case 'Hybrid Monsters vol 2': resource.PushBack( (CJournalResource)LoadResource( "BestiaryGriffin" ) ); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 4'); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 27'); break; case 'Insectoids vol 1': resource.PushBack( (CJournalResource)LoadResource( "BestiaryEndriagaWorker" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryEndriagaTruten" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryEndriaga" ) ); break; case 'Insectoids vol 2': resource.PushBack( (CJournalResource)LoadResource( "BestiaryCrabSpider" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryArmoredArachas" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryPoisonousArachas" ) ); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 2'); break; case 'Magical Monsters vol 1': resource.PushBack( (CJournalResource)LoadResource( "BestiaryGolem" ) ); break; case 'Magical Monsters vol 2': resource.PushBack( (CJournalResource)LoadResource( "BestiaryElemental" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryIceGolem" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryFireElemental" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryWhMinion" ) ); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 20'); break; case 'Necrophage vol 1': resource.PushBack( (CJournalResource)LoadResource( "BestiaryGhoul" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryAlghoul" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryGreaterRotFiend" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryDrowner" ) ); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 15'); break; case 'Necrophage vol 2': resource.PushBack( (CJournalResource)LoadResource( "BestiaryGraveHag" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryWaterHag" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryFogling" ) ); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 5'); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 9'); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 18'); break; case 'Relict Monsters vol 1': resource.PushBack( (CJournalResource)LoadResource( "BestiaryBies" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryCzart" ) ); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 8'); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 16'); break; case 'Relict Monsters vol 2': resource.PushBack( (CJournalResource)LoadResource( "BestiaryLeshy" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiarySilvan" ) ); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 22'); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 26'); break; case 'Specters vol 1': resource.PushBack( (CJournalResource)LoadResource( "BestiaryMoonwright" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryNoonwright" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryPesta" ) ); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 6'); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 13'); break; case 'Specters vol 2': resource.PushBack( (CJournalResource)LoadResource( "BestiaryWraith" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryHim" ) ); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 19'); break; case 'Ogres vol 1': resource.PushBack( (CJournalResource)LoadResource( "BestiaryNekker" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryIceTroll" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryCaveTroll" ) ); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 12'); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 25'); break; case 'Ogres vol 2': resource.PushBack( (CJournalResource)LoadResource( "BestiaryCyclop" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryIceGiant" ) ); break; case 'Vampires vol 1': resource.PushBack( (CJournalResource)LoadResource( "BestiaryEkkima" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryHigherVampire" ) ); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 7'); break; case 'Vampires vol 2': resource.PushBack( (CJournalResource)LoadResource( "BestiaryKatakan" ) ); GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 1'); break; case 'bestiary_sharley_book': resource.PushBack( (CJournalResource)LoadResource( "BestiarySharley" ) ); break; case 'bestiary_barghest_book': resource.PushBack( (CJournalResource)LoadResource( "BestiaryBarghest" ) ); break; case 'bestiary_garkain_book': resource.PushBack( (CJournalResource)LoadResource( "BestiaryGarkain" ) ); break; case 'bestiary_alp_book': resource.PushBack( (CJournalResource)LoadResource( "BestiaryAlp" ) ); break; case 'bestiary_bruxa_book': resource.PushBack( (CJournalResource)LoadResource( "BestiaryBruxa" ) ); break; case 'bestiary_spriggan_book': resource.PushBack( (CJournalResource)LoadResource( "BestiarySpriggan" ) ); break; case 'bestiary_fleder_book': resource.PushBack( (CJournalResource)LoadResource( "BestiaryFleder" ) ); break; case 'bestiary_wight_book': resource.PushBack( (CJournalResource)LoadResource( "BestiaryWicht" ) ); break; case 'bestiary_dracolizard_book': resource.PushBack( (CJournalResource)LoadResource( "BestiaryDracolizard" ) ); break; case 'bestiary_panther_book': resource.PushBack( (CJournalResource)LoadResource( "BestiaryPanther" ) ); break; case 'bestiary_kikimore_book': resource.PushBack( (CJournalResource)LoadResource( "BestiaryKikimoraWarrior" ) ); resource.PushBack( (CJournalResource)LoadResource( "BestiaryKikimoraWorker" ) ); break; case 'bestiary_scolopendromorph_book': case 'mq7023_fluff_book_scolopendromorphs': resource.PushBack( (CJournalResource)LoadResource( "BestiaryScolopendromorph" ) ); break; case 'bestiary_archespore_book': resource.PushBack( (CJournalResource)LoadResource( "BestiaryArchespore" ) ); break; case 'bestiary_protofleder_book': resource.PushBack( (CJournalResource)LoadResource( "BestiaryProtofleder" ) ); break; default: return false; } len = resource.Size(); if( len > 0) { theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt( "panel_hud_journal_entry_bestiary_new" ), 0, true ); theSound.SoundEvent("gui_ingame_new_journal"); } for (r=0; r < len; r += 1 ) { if ( !resource[ r ] ) { continue; } entryBase = resource[r].GetEntry(); if ( entryBase ) { manager.ActivateEntry( entryBase, JS_Active ); manager.SetEntryHasAdvancedInfo( entryBase, true ); manager.GetAllChildren( entryBase, childGroups ); for ( i = 0; i < childGroups.Size(); i += 1 ) { descriptionGroup = ( CJournalCreatureDescriptionGroup )childGroups[ i ]; if ( descriptionGroup ) { manager.GetAllChildren( descriptionGroup, childEntries ); for ( j = 0; j < childEntries.Size(); j += 1 ) { descriptionEntry = ( CJournalCreatureDescriptionEntry )childEntries[ j ]; if ( descriptionEntry ) { manager.ActivateEntry( descriptionEntry, JS_Active ); } } break; } } } } if ( resource.Size() > 0 ) return true; else return false; } function GetWeaponDTNames( id : SItemUniqueId, out dmgNames : array< name > ) : int { var attrs : array< name >; var i, size : int; dmgNames.Clear(); if( IsIdValid(id) ) { GetItemAttributes( id, attrs ); size = attrs.Size(); for( i = 0; i < size; i += 1 ) if( IsDamageTypeNameValid(attrs[i]) ) dmgNames.PushBack( attrs[i] ); if(dmgNames.Size() == 0) LogAssert(false, "CInventoryComponent.GetWeaponDTNames: weapon <<" + GetItemName(id) + ">> has no damage types defined!"); } return dmgNames.Size(); } public function GetWeapons() : array { var ids, ids2 : array; ids = GetItemsByCategory('monster_weapon'); ids2 = GetItemsByTag('Weapon'); ArrayOfIdsAppend(ids, ids2); return ids; } public function GetHeldWeapons() : array { var i : int; var w : array; w = GetWeapons(); for(i=w.Size()-1; i>=0; i-=1) { if(!IsItemHeld(w[i])) { w.EraseFast( i ); } } return w; } public function GetCurrentlyHeldSword() : SItemUniqueId { var i : int; var w : array; w = GetHeldWeapons(); for( i = 0 ; i < w.Size() ; i+=1 ) { if( IsItemSteelSwordUsableByPlayer( w[i] ) || IsItemSilverSwordUsableByPlayer( w[i] ) ) { return w[i]; } } return GetInvalidUniqueId(); } public function GetCurrentlyHeldSwordEntity( out ent : CItemEntity ) : bool { var id : SItemUniqueId; id = GetCurrentlyHeldSword(); if( IsIdValid( id ) ) { ent = GetItemEntityUnsafe( id ); if( ent ) { return true; } else { return false; } } return false; } public function GetHeldWeaponsWithCategory( category : name, out items : array ) { var i : int; items = GetItemsByCategory( category ); for ( i = items.Size()-1; i >= 0; i -= 1) { if ( !IsItemHeld( items[i] ) ) { items.EraseFast( i ); } } } public function GetPotionItemBuffData(id : SItemUniqueId, out type : EEffectType, out customAbilityName : name) : bool { var size, i : int; var arr : array; if(IsIdValid(id)) { GetItemContainedAbilities( id, arr ); size = arr.Size(); for( i = 0; i < size; i += 1 ) { if( IsEffectNameValid(arr[i]) ) { EffectNameToType(arr[i], type, customAbilityName); return true; } } } return false; } public function RecycleItem( id : SItemUniqueId, level : ECraftsmanLevel ) : array { var itemsAdded : array; var currentAdded : array; var parts : array; var i : int; parts = GetItemRecyclingParts( id ); for ( i = 0; i < parts.Size(); i += 1 ) { if ( ECL_Grand_Master == level || ECL_Arch_Master == level ) { currentAdded = AddAnItem( parts[i].itemName, parts[i].quantity ); } else if ( ECL_Master == level && parts[i].quantity > 1 ) { currentAdded = AddAnItem( parts[i].itemName, RandRange( parts[i].quantity, 1 ) ); } else { currentAdded = AddAnItem( parts[i].itemName, 1 ); } itemsAdded.PushBack(currentAdded[0]); } RemoveItem(id); return itemsAdded; } public function GetItemBuffs( id : SItemUniqueId, out buffs : array) : int { var attrs, abs, absFast : array< name >; var i, k : int; var type : EEffectType; var abilityName : name; var buff : SEffectInfo; var dm : CDefinitionsManagerAccessor; buffs.Clear(); if( !IsIdValid(id) ) return 0; GetItemContainedAbilities(id, absFast); if(absFast.Size() == 0) return 0; GetItemAbilities(id, abs); dm = theGame.GetDefinitionsManager(); for(k=0; k; var i : int; var owner : CActor; var bag : W3ActorRemains; var template : CEntityTemplate; var bagtags : array ; var bagPosition : Vector; var tracedPosition, tracedNormal : Vector; if(ItemHasTag(item, 'NoDrop')) return; owner = (CActor)GetEntity(); FindGameplayEntitiesInRange(entities, owner, 0.5, 100); for(i=0; i; if(buffArmor) { items = GetItemsByTag(theGame.params.TAG_ARMOR); } if(buffSwords) { items2 = GetItemsByTag(theGame.params.TAG_PLAYER_STEELSWORD); ArrayOfIdsAppend(items, items2); items2.Clear(); items2 = GetItemsByTag(theGame.params.TAG_PLAYER_SILVERSWORD); ArrayOfIdsAppend(items, items2); } upgradedSomething = false; for(i=0; i currAmmo) { SetItemModifierInt(items[i], 'repairObjectBonusAmmo', ammo); upgradedSomething = true; if(currAmmo == 0) { if(isArmor) AddItemCraftedAbility(items[i], theGame.params.REPAIR_OBJECT_BONUS_ARMOR_ABILITY, false); else AddItemCraftedAbility(items[i], theGame.params.REPAIR_OBJECT_BONUS_WEAPON_ABILITY, false); } } } return upgradedSomething; } public final function ReduceItemRepairObjectBonusCharge(item : SItemUniqueId) { var currAmmo : int; currAmmo = GetItemModifierInt(item, 'repairObjectBonusAmmo', 0); if(currAmmo > 0) { SetItemModifierInt(item, 'repairObjectBonusAmmo', currAmmo - 1); if(currAmmo == 1) { if(IsItemAnyArmor(item)) RemoveItemCraftedAbility(item, theGame.params.REPAIR_OBJECT_BONUS_ARMOR_ABILITY); else RemoveItemCraftedAbility(item, theGame.params.REPAIR_OBJECT_BONUS_WEAPON_ABILITY); } } } public final function GetRepairObjectBonusValueForArmor(armor : SItemUniqueId) : SAbilityAttributeValue { var retVal, bonusValue, baseArmor : SAbilityAttributeValue; if(GetItemModifierInt(armor, 'repairObjectBonusAmmo', 0) > 0) { bonusValue = GetItemAttributeValue(armor, theGame.params.REPAIR_OBJECT_BONUS); baseArmor = GetItemAttributeValue(armor, theGame.params.ARMOR_VALUE_NAME); baseArmor.valueMultiplicative += 1; retVal.valueAdditive = bonusValue.valueAdditive + CalculateAttributeValue(baseArmor) * bonusValue.valueMultiplicative; } return retVal; } public function CanItemHaveOil(id : SItemUniqueId) : bool { return IsItemSteelSwordUsableByPlayer(id) || IsItemSilverSwordUsableByPlayer(id); } public final function RemoveAllOilsFromItem( id : SItemUniqueId ) { var i : int; var oils : array< W3Effect_Oil >; var actor : CActor; actor = ( CActor ) GetEntity(); oils = GetOilsAppliedOnItem( id ); for( i = oils.Size() - 1; i >= 0; i -= 1 ) { actor.RemoveEffect( oils[ i ] ); } } public final function GetActiveOilsAppliedOnItemCount( id : SItemUniqueId ) : int { var oils : array< W3Effect_Oil >; var i, count : int; count = 0; oils = GetOilsAppliedOnItem( id ); for( i=0; i 0 ) { count += 1; } } return count; } public final function RemoveOldestOilFromItem( id : SItemUniqueId ) { var buffToRemove : W3Effect_Oil; var actor : CActor; actor = ( CActor ) GetEntity(); if(! actor ) return; buffToRemove = GetOldestOilAppliedOnItem(id, false); if(buffToRemove) { actor.RemoveEffect( buffToRemove ); } } public final function GetOilsAppliedOnItem( id : SItemUniqueId ) : array< W3Effect_Oil > { var i : int; var oils : array< CBaseGameplayEffect >; var buff : W3Effect_Oil; var ret : array < W3Effect_Oil >; var actor : CActor; actor = ( CActor ) GetEntity(); if(! actor ) return ret; oils = actor.GetBuffs( EET_Oil ); for( i = oils.Size() - 1; i >= 0; i -= 1 ) { buff = ( W3Effect_Oil ) oils[ i ]; if(buff && buff.GetSwordItemId() == id ) { ret.PushBack( buff ); } } return ret; } public final function GetNewestOilAppliedOnItem( id : SItemUniqueId, onlyShowable : bool ) : W3Effect_Oil { return GetOilAppliedOnItemInternal( id, onlyShowable, true ); } public final function GetOldestOilAppliedOnItem( id : SItemUniqueId, onlyShowable : bool ) : W3Effect_Oil { return GetOilAppliedOnItemInternal( id, onlyShowable, false ); } private final function GetOilAppliedOnItemInternal( id : SItemUniqueId, onlyShowable : bool, newest : bool ) : W3Effect_Oil { var oils : array< W3Effect_Oil >; var i, lastIndex : int; oils = GetOilsAppliedOnItem( id ); lastIndex = -1; for( i=0; i oils[lastIndex].GetQueueTimer() ) { lastIndex = i; } } if( lastIndex == -1 ) { return NULL; } return oils[lastIndex]; } public final function ItemHasAnyActiveOilApplied( id : SItemUniqueId ) : bool { return GetActiveOilsAppliedOnItemCount( id ); } public final function ItemHasActiveOilApplied( id : SItemUniqueId, monsterCategory : EMonsterCategory ) : bool { var i : int; var oils : array< W3Effect_Oil >; oils = GetOilsAppliedOnItem( id ); for( i=0; i 0 ) { return true; } } return false; } public final function GetParamsForRunewordTooltip(runewordName : name, out i : array, out f : array, out s : array) { var min, max : SAbilityAttributeValue; var val : float; var attackRangeBase, attackRangeExt : CAIAttackRange; i.Clear(); f.Clear(); s.Clear(); switch(runewordName) { case 'Glyphword 5': theGame.GetDefinitionsManager().GetAbilityAttributeValue('Glyphword 5 _Stats', 'glyphword5_chance', min, max); i.PushBack( RoundMath( CalculateAttributeValue(min) * 100) ); break; case 'Glyphword 6' : theGame.GetDefinitionsManager().GetAbilityAttributeValue('Glyphword 6 _Stats', 'glyphword6_stamina_drain_perc', min, max); i.PushBack( RoundMath( CalculateAttributeValue(min) * 100) ); break; case 'Glyphword 12' : theGame.GetDefinitionsManager().GetAbilityAttributeValue('Glyphword 12 _Stats', 'glyphword12_range', min, max); val = CalculateAttributeValue(min); s.PushBack( NoTrailZeros(val) ); theGame.GetDefinitionsManager().GetAbilityAttributeValue('Glyphword 12 _Stats', 'glyphword12_chance', min, max); i.PushBack( RoundMath( min.valueAdditive * 100) ); break; case 'Glyphword 17' : theGame.GetDefinitionsManager().GetAbilityAttributeValue('Glyphword 17 _Stats', 'quen_apply_chance', min, max); val = CalculateAttributeValue(min); i.PushBack( RoundMath(val * 100) ); break; case 'Glyphword 14' : case 'Glyphword 18' : theGame.GetDefinitionsManager().GetAbilityAttributeValue('Glyphword 18 _Stats', 'increas_duration', min, max); val = CalculateAttributeValue(min); s.PushBack( NoTrailZeros(val) ); break; case 'Runeword 2' : attackRangeBase = theGame.GetAttackRangeForEntity(GetWitcherPlayer(), 'specialattacklight'); attackRangeExt = theGame.GetAttackRangeForEntity(GetWitcherPlayer(), 'runeword2_light'); s.PushBack( NoTrailZeros(attackRangeExt.rangeMax - attackRangeBase.rangeMax) ); attackRangeBase = theGame.GetAttackRangeForEntity(GetWitcherPlayer(), 'slash_long'); attackRangeExt = theGame.GetAttackRangeForEntity(GetWitcherPlayer(), 'runeword2_heavy'); s.PushBack( NoTrailZeros(attackRangeExt.rangeMax - attackRangeBase.rangeMax) ); break; case 'Runeword 4' : theGame.GetDefinitionsManager().GetAbilityAttributeValue('Runeword 4 _Stats', 'max_bonus', min, max); i.PushBack( RoundMath(max.valueMultiplicative * 100) ); break; case 'Runeword 6' : theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Runeword 6 _Stats', 'runeword6_duration_bonus', min, max ); i.PushBack( RoundMath(min.valueMultiplicative * 100) ); break; case 'Runeword 7' : theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Runeword 7 _Stats', 'stamina', min, max ); i.PushBack( RoundMath(min.valueMultiplicative * 100) ); break; case 'Runeword 10' : theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Runeword 10 _Stats', 'stamina', min, max ); i.PushBack( RoundMath(min.valueMultiplicative * 100) ); break; case 'Runeword 11' : theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Runeword 11 _Stats', 'duration', min, max ); s.PushBack( NoTrailZeros(min.valueAdditive) ); break; case 'Runeword 12' : theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Runeword 12 _Stats', 'focus', min, max ); f.PushBack(min.valueAdditive); f.PushBack(max.valueAdditive); break; default: break; } } public final function GetPotionAttributesForTooltip(potionId : SItemUniqueId, out tips : array):void { var i, j, settingsSize : int; var buffType : EEffectType; var abilityName : name; var abs, attrs : array; var val : SAbilityAttributeValue; var newAttr : SAttributeTooltip; var attributeString : string; if(!( IsItemPotion(potionId) || IsItemFood(potionId) ) ) return; GetItemContainedAbilities(potionId, abs); for(i=0; i, out localizedFluff : string) { if( !IsIdValid(itemId) ) { return; } localizedName = GetItemLocalizedNameByUniqueID(itemId); localizedDescription = GetItemLocalizedDescriptionByUniqueID(itemId); localizedFluff = "IMPLEMENT ME - fluff text"; price = GetItemPriceModified( itemId, false ); localizedCategory = GetItemCategoryLocalisedString(GetItemCategory(itemId)); GetItemStats(itemId, itemStats); } public function GetItemBaseStats(itemId : SItemUniqueId, out itemStats : array) { var attributes : array; var dm : CDefinitionsManagerAccessor; var oilAbilities, oilAttributes : array; var weights : array; var i, j : int; var tmpI, tmpJ : int; var idx : int; var oilStatsCount : int; var oilName : name; var oilStats : array; var oilStatFirst : SAttributeTooltip; var oils : array< W3Effect_Oil >; GetItemBaseAttributes(itemId, attributes); oils = GetOilsAppliedOnItem( itemId ); dm = theGame.GetDefinitionsManager(); for( i=0; i) { var attributes : array; GetItemAttributes(itemId, attributes); GetItemTooltipAttributes(itemId, attributes, itemStats); } private function GetItemTooltipAttributes(itemId : SItemUniqueId, attributes : array, out itemStats : array):void { var itemCategory:name; var i, j, settingsSize : int; var attributeString : string; var attributeColor : string; var attributeName : name; var isPercentageValue : string; var primaryStatLabel : string; var statLabel : string; var stat : SAttributeTooltip; var attributeVal : SAbilityAttributeValue; settingsSize = theGame.tooltipSettings.GetNumRows(); itemStats.Clear(); itemCategory = GetItemCategory(itemId); for(i=0; i) { var itemCategory : name; var i, j, settingsSize : int; var attributeString : string; var attributeColor : string; var attributeName : name; var isPercentageValue : string; var attributes, itemAbilities, tmpArray : array; var weights : array; var stat : SAttributeTooltip; var attributeVal, min, max : SAbilityAttributeValue; var dm : CDefinitionsManagerAccessor; var primaryStatLabel : string; var statLabel : string; settingsSize = theGame.tooltipSettings.GetNumRows(); dm = theGame.GetDefinitionsManager(); dm.GetItemAbilitiesWithWeights(itemName, GetEntity() == thePlayer, itemAbilities, weights, i, j); attributes = dm.GetAbilitiesAttributes(itemAbilities); itemStats.Clear(); itemCategory = dm.GetItemCategory(itemName); for(i=0; i ) : bool { var i : int; var currItemName : name; currItemName = GetItemName( itemID ); for ( i = 0; i < excludedItems.Size(); i+=1 ) { if ( currItemName == excludedItems[i].itemName ) { return true; } } return false; } public function GetItemPrimaryStat(itemId : SItemUniqueId, out attributeLabel : string, out attributeVal : float ) : void { var attributeName : name; var attributeValue:SAbilityAttributeValue; GetItemPrimaryStatImplById(itemId, attributeLabel, attributeVal, attributeName); attributeValue = GetItemAttributeValue(itemId, attributeName); if(attributeValue.valueBase != 0) { attributeVal = attributeValue.valueBase; } if(attributeValue.valueMultiplicative != 0) { attributeVal = attributeValue.valueMultiplicative; } if(attributeValue.valueAdditive != 0) { attributeVal = attributeValue.valueAdditive; } } public function GetItemStatByName(itemName : name, statName : name, out resultValue : float) : void { var dm : CDefinitionsManagerAccessor; var attributes, itemAbilities : array; var min, max, attributeValue : SAbilityAttributeValue; var tmpInt : int; var tmpArray : array; dm = theGame.GetDefinitionsManager(); dm.GetItemAbilitiesWithWeights(itemName, GetEntity() == thePlayer, itemAbilities, tmpArray, tmpInt, tmpInt); attributes = dm.GetAbilitiesAttributes(itemAbilities); dm.GetAbilitiesAttributeValue(itemAbilities, statName, min, max); attributeValue = GetAttributeRandomizedValue(min, max); if(attributeValue.valueBase != 0) { resultValue = attributeValue.valueBase; } if(attributeValue.valueMultiplicative != 0) { resultValue = attributeValue.valueMultiplicative; } if(attributeValue.valueAdditive != 0) { resultValue = attributeValue.valueAdditive; } } public function GetItemPrimaryStatFromName(itemName : name, out attributeLabel : string, out attributeVal : float, out primAttrName : name) : void { var dm : CDefinitionsManagerAccessor; var attributeName : name; var attributes, itemAbilities : array; var attributeValue, min, max : SAbilityAttributeValue; var tmpInt : int; var tmpArray : array; dm = theGame.GetDefinitionsManager(); GetItemPrimaryStatImpl(dm.GetItemCategory(itemName), attributeLabel, attributeVal, attributeName); dm.GetItemAbilitiesWithWeights(itemName, GetEntity() == thePlayer, itemAbilities, tmpArray, tmpInt, tmpInt); attributes = dm.GetAbilitiesAttributes(itemAbilities); for (tmpInt = 0; tmpInt < attributes.Size(); tmpInt += 1) if (attributes[tmpInt] == attributeName) { dm.GetAbilitiesAttributeValue(itemAbilities, attributeName, min, max); attributeValue = GetAttributeRandomizedValue(min, max); primAttrName = attributeName; break; } if(attributeValue.valueBase != 0) { attributeVal = attributeValue.valueBase; } if(attributeValue.valueMultiplicative != 0) { attributeVal = attributeValue.valueMultiplicative; } if(attributeValue.valueAdditive != 0) { attributeVal = attributeValue.valueAdditive; } } public function IsPrimaryStatById(itemId : SItemUniqueId, attributeName : name, out attributeLabel : string) : bool { var attrValue : float; var attrName : name; GetItemPrimaryStatImplById(itemId, attributeLabel, attrValue, attrName); return attrName == attributeName; } private function GetItemPrimaryStatImplById(itemId : SItemUniqueId, out attributeLabel : string, out attributeVal : float, out attributeName : name ) : void { var itemOnSlot : SItemUniqueId; var categoryName : name; var abList : array; attributeName = ''; attributeLabel = ""; categoryName = GetItemCategory(itemId); if (categoryName == 'bolt' || categoryName == 'petard') { GetItemAttributes(itemId, abList); if (abList.Contains('FireDamage')) { attributeName = 'FireDamage'; } else if (abList.Contains('PiercingDamage')) { attributeName = 'PiercingDamage'; } else if (abList.Contains('PiercingDamage')) { attributeName = 'PiercingDamage'; } else if (abList.Contains('PoisonDamage')) { attributeName = 'PoisonDamage'; } else if (abList.Contains('BludgeoningDamage')) { attributeName = 'BludgeoningDamage'; } else { attributeName = 'PhysicalDamage'; } attributeLabel = GetAttributeNameLocStr(attributeName, false); } else if (categoryName == 'secondary') { GetItemAttributes(itemId, abList); if (abList.Contains('BludgeoningDamage')) { attributeName = 'BludgeoningDamage'; } else { attributeName = 'PhysicalDamage'; } attributeLabel = GetAttributeNameLocStr(attributeName, false); } else if (categoryName == 'steelsword') { GetItemAttributes(itemId, abList); if (abList.Contains('SlashingDamage')) { attributeName = 'SlashingDamage'; attributeLabel = GetLocStringByKeyExt("panel_inventory_tooltip_damage"); } else if (abList.Contains('BludgeoningDamage')) { attributeName = 'BludgeoningDamage'; } else if (abList.Contains('PiercingDamage')) { attributeName = 'PiercingDamage'; } else { attributeName = 'PhysicalDamage'; } if (attributeLabel == "") { attributeLabel = GetAttributeNameLocStr(attributeName, false); } } else { GetItemPrimaryStatImpl(categoryName, attributeLabel, attributeVal, attributeName); } } public function IsPrimaryStat(categoryName : name, attributeName : name, out attributeLabel : string) : bool { var attrValue : float; var attrName : name; GetItemPrimaryStatImpl(categoryName, attributeLabel, attrValue, attrName); return attrName == attributeName; } private function GetItemPrimaryStatImpl(categoryName : name, out attributeLabel : string, out attributeVal : float, out attributeName : name ) : void { attributeName = ''; attributeLabel = ""; switch (categoryName) { case 'steelsword': attributeName = 'SlashingDamage'; attributeLabel = GetLocStringByKeyExt("panel_inventory_tooltip_damage"); break; case 'silversword': attributeName = 'SilverDamage'; attributeLabel = GetLocStringByKeyExt("panel_inventory_tooltip_damage"); break; case 'armor': case 'gloves': case 'gloves': case 'boots': case 'pants': attributeName = 'armor'; break; case 'potion': case 'oil': break; case 'bolt': case 'petard': attributeName = 'PhysicalDamage'; break; case 'crossbow': default: attributeLabel = ""; attributeVal = 0; return; break; } if (attributeLabel == "") { attributeLabel = GetAttributeNameLocStr(attributeName, false); } } public function CanBeCompared(itemId : SItemUniqueId) : bool { var wplayer : W3PlayerWitcher; var itemSlot : EEquipmentSlots; var equipedItem : SItemUniqueId; var horseManager : W3HorseManager; var isArmorOrWeapon : bool; if (IsItemHorseItem(itemId)) { horseManager = GetWitcherPlayer().GetHorseManager(); if (!horseManager) { return false; } if (horseManager.IsItemEquipped(itemId)) { return false; } itemSlot = GetHorseSlotForItem(itemId); equipedItem = horseManager.GetItemInSlot(itemSlot); if (!horseManager.GetInventoryComponent().IsIdValid(equipedItem)) { return false; } } else { isArmorOrWeapon = IsItemAnyArmor(itemId) || IsItemWeapon(itemId); if (!isArmorOrWeapon) { return false; } wplayer = GetWitcherPlayer(); if (wplayer.IsItemEquipped(itemId)) { return false; } itemSlot = GetSlotForItemId(itemId); wplayer.GetItemEquippedOnSlot(itemSlot, equipedItem); if (!wplayer.inv.IsIdValid(equipedItem)) { return false; } } return true; } public function GetHorseSlotForItem(id : SItemUniqueId) : EEquipmentSlots { var tags : array; GetItemTags(id, tags); if(tags.Contains('Saddle')) return EES_HorseSaddle; else if(tags.Contains('HorseBag')) return EES_HorseBag; else if(tags.Contains('Trophy')) return EES_HorseTrophy; else if(tags.Contains('Blinders')) return EES_HorseBlinders; else return EES_InvalidSlot; } public final function SingletonItemRefillAmmo( id : SItemUniqueId, optional alchemyTableUsed : bool ) { var l_bed : W3WitcherBed; var refilledByBed : bool; refilledByBed = false; if( FactsQuerySum( "PlayerInsideOuterWitcherHouse" ) >= 1 && FactsQuerySum( "AlchemyTableExists" ) >= 1 && !IsItemMutagenPotion( id ) ) { l_bed = (W3WitcherBed)theGame.GetEntityByTag( 'witcherBed' ); if( l_bed.GetWasUsed() || alchemyTableUsed ) { SetItemModifierInt( id, 'ammo_current', SingletonItemGetMaxAmmo(id) + theGame.params.QUANTITY_INCREASED_BY_ALCHEMY_TABLE ) ; refilledByBed = true; if( !l_bed.GetWereItemsRefilled() ) { l_bed.SetWereItemsRefilled( true ); } } } if( !refilledByBed && SingletonItemGetAmmo( id ) < SingletonItemGetMaxAmmo( id ) ) { SetItemModifierInt(id, 'ammo_current', SingletonItemGetMaxAmmo(id)); } theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_OnAmmoChanged ); } public function SingletonItemSetAmmo(id : SItemUniqueId, quantity : int) { var amount : int; if(ItemHasTag(id, theGame.params.TAG_INFINITE_AMMO)) { amount = -1; } else { amount = Clamp(quantity, 0, SingletonItemGetMaxAmmo(id)); } SetItemModifierInt(id, 'ammo_current', amount); theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_OnAmmoChanged ); } public function SingletonItemAddAmmo(id : SItemUniqueId, quantity : int) { var ammo : int; if(quantity <= 0) return; ammo = GetItemModifierInt(id, 'ammo_current'); if(ammo == -1) return; ammo = Clamp(ammo + quantity, 0, SingletonItemGetMaxAmmo(id)); SetItemModifierInt(id, 'ammo_current', ammo); theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_OnAmmoChanged ); } public function SingletonItemsRefillAmmo( optional alchemyTableUsed : bool ) : bool { var i : int; var singletonItems : array; var alco : SItemUniqueId; var arrStr : array; var witcher : W3PlayerWitcher; var itemLabel : string; witcher = GetWitcherPlayer(); if(GetEntity() == witcher && HasNotFilledSingletonItem( alchemyTableUsed ) ) { alco = witcher.GetAlcoholForAlchemicalItemsRefill(); if(!IsIdValid(alco)) { theGame.GetGuiManager().ShowNotification(GetLocStringByKeyExt("message_common_alchemy_items_cannot_refill")); theSound.SoundEvent("gui_global_denied"); return false; } else { arrStr.PushBack(GetItemName(alco)); itemLabel = GetLocStringByKeyExt(GetItemLocalizedNameByUniqueID(alco)); theGame.GetGuiManager().ShowNotification( itemLabel + " - " + GetLocStringByKeyExtWithParams("message_common_alchemy_items_refilled", , , arrStr)); theSound.SoundEvent("gui_alchemy_brew"); if(!ItemHasTag(alco, theGame.params.TAG_INFINITE_USE)) RemoveItem(alco); } } singletonItems = GetSingletonItems(); for(i=0; i; var alco : SItemUniqueId; var arrStr : array; var witcher : W3PlayerWitcher; var itemLabel : string; witcher = GetWitcherPlayer(); if(!dontUpdateUI && GetEntity() == witcher && HasNotFilledSingletonItem()) { arrStr.PushBack(GetItemName(alco)); itemLabel = GetLocStringByKeyExt(GetItemLocalizedNameByUniqueID(alco)); theGame.GetGuiManager().ShowNotification( itemLabel + " - " + GetLocStringByKeyExtWithParams("message_common_alchemy_items_refilled", , , arrStr)); theSound.SoundEvent("gui_alchemy_brew"); } singletonItems = GetSingletonItems(); for(i=0; i; var hasLab : bool; var l_bed : W3WitcherBed; hasLab = false; if( FactsQuerySum( "PlayerInsideOuterWitcherHouse" ) >= 1 && FactsQuerySum( "AlchemyTableExists" ) >= 1 ) { l_bed = (W3WitcherBed)theGame.GetEntityByTag( 'witcherBed' ); if( l_bed.GetWasUsed() || alchemyTableUsed ) { hasLab = true; } } singletonItems = GetSingletonItems(); for(i=0; i 0) { FactsAdd('tut_alch_refill', 1); } theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_OnAmmoChanged ); } public function SingletonItemGetAmmo(itemID : SItemUniqueId) : int { if(!IsItemSingletonItem(itemID)) return 0; return GetItemModifierInt(itemID, 'ammo_current'); } public function SingletonItemGetMaxAmmo(itemID : SItemUniqueId) : int { var ammo, i : int; var perk20Bonus, min, max : SAbilityAttributeValue; var atts : array; var canUseSkill : bool; ammo = RoundMath(CalculateAttributeValue(GetItemAttributeValue(itemID, 'ammo'))); if( !ItemHasTag( itemID, 'NoAdditionalAmmo' ) ) { if(GetEntity() == GetWitcherPlayer() && ammo > 0) { if(IsItemBomb(itemID) && thePlayer.CanUseSkill(S_Alchemy_s08) ) { ammo += thePlayer.GetSkillLevel(S_Alchemy_s08); } if(thePlayer.HasBuff(EET_Mutagen03) && (IsItemBomb(itemID) || (!IsItemMutagenPotion(itemID) && IsItemPotion(itemID))) ) { ammo += 1; } //LZ_SLOTS_BEGIN if( GetWitcherPlayer().IsMutationActive( EPMT_Mutation15 ) && IsItemMutagenPotion(itemID) ) { theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation15', 'extra_charges', min, max ); ammo += (int)min.valueAdditive; } //LZ_SLOTS_END if( GetWitcherPlayer().IsSetBonusActive( EISB_RedWolf_2 ) && !IsItemMutagenPotion(itemID) ) { theGame.GetDefinitionsManager().GetAbilityAttributeValue( GetSetBonusAbility( EISB_RedWolf_2 ), 'amount', min, max); ammo += (int)min.valueAdditive; } if( IsItemBomb( itemID ) && thePlayer.CanUseSkill( S_Perk_20 ) && GetItemName( itemID ) != 'Snow Ball' ) { GetItemAttributes( itemID, atts ); canUseSkill = thePlayer.CanUseSkill( S_Alchemy_s10 ); perk20Bonus = GetWitcherPlayer().GetSkillAttributeValue( S_Perk_20, 'stack_multiplier', false, false ); for( i=0 ; i; var l_i : int; var l_haveBombOrPot : bool; l_items = GetSingletonItems(); for( l_i = 0 ; l_i < l_items.Size() ; l_i += 1 ) { if( IsItemPotion( l_items[ l_i ] ) || IsItemBomb( l_items[ l_i ] ) ) { l_haveBombOrPot = true; if( SingletonItemGetMaxAmmo( l_items[ l_i ] ) >= SingletonItemGetAmmo( l_items[ l_i ] ) ) { if( SingletonItemsRefillAmmo( true ) ) { theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt( "message_common_alchemy_table_buff_applied" ),, true ); } return; } } } if( !l_haveBombOrPot ) { theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt( "message_common_alchemy_table_buff_no_items" ),, true ); return; } theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt( "message_common_alchemy_table_buff_already_on" ),, true ); } public final function IsItemSteelSwordUsableByPlayer(item : SItemUniqueId) : bool { return ItemHasTag(item, theGame.params.TAG_PLAYER_STEELSWORD) && !ItemHasTag(item, 'SecondaryWeapon'); } public final function IsItemSilverSwordUsableByPlayer(item : SItemUniqueId) : bool { return ItemHasTag(item, theGame.params.TAG_PLAYER_SILVERSWORD) && !ItemHasTag(item, 'SecondaryWeapon'); } public final function IsItemFists(item : SItemUniqueId) : bool {return GetItemCategory(item) == 'fist';} public final function IsItemWeapon(item : SItemUniqueId) : bool {return ItemHasTag(item, 'Weapon') || ItemHasTag(item, 'WeaponTab');} public final function IsItemCrossbow(item : SItemUniqueId) : bool {return GetItemCategory(item) == 'crossbow';} public final function IsItemChestArmor(item : SItemUniqueId) : bool {return GetItemCategory(item) == 'armor';} public final function IsItemBody(item : SItemUniqueId) : bool {return ItemHasTag(item, 'Body');} public final function IsRecipeOrSchematic( item : SItemUniqueId ) : bool {return GetItemCategory(item) == 'alchemy_recipe' || GetItemCategory(item) == 'crafting_schematic'; } public final function IsItemBoots(item : SItemUniqueId) : bool {return GetItemCategory(item) == 'boots';} public final function IsItemGloves(item : SItemUniqueId) : bool {return GetItemCategory(item) == 'gloves';} public final function IsItemPants(item : SItemUniqueId) : bool {return GetItemCategory(item) == 'trousers' || GetItemCategory(item) == 'pants';} public final function IsItemTrophy(item : SItemUniqueId) : bool {return GetItemCategory(item) == 'trophy';} public final function IsItemMask(item : SItemUniqueId) : bool {return GetItemCategory(item) == 'mask';} public final function IsItemBomb(item : SItemUniqueId) : bool {return GetItemCategory(item) == 'petard';} public final function IsItemBolt(item : SItemUniqueId) : bool {return GetItemCategory(item) == 'bolt';} public final function IsItemUpgrade(item : SItemUniqueId) : bool {return GetItemCategory(item) == 'upgrade';} public final function IsItemTool(item : SItemUniqueId) : bool {return GetItemCategory(item) == 'tool';} public final function IsItemPotion(item : SItemUniqueId) : bool {return ItemHasTag(item, 'Potion');} public final function IsItemOil(item : SItemUniqueId) : bool {return ItemHasTag(item, 'SilverOil') || ItemHasTag(item, 'SteelOil');} public final function IsItemAnyArmor(item : SItemUniqueId) : bool {return ItemHasTag(item, theGame.params.TAG_ARMOR);} public final function IsItemUpgradeable(item : SItemUniqueId) : bool {return ItemHasTag(item, theGame.params.TAG_ITEM_UPGRADEABLE);} public final function IsItemIngredient(item : SItemUniqueId) : bool {return ItemHasTag(item, 'AlchemyIngredient') || ItemHasTag(item, 'CraftingIngredient');} public final function IsItemDismantleKit(item : SItemUniqueId) : bool {return ItemHasTag(item, 'DismantleKit');} public final function IsItemHorseBag(item : SItemUniqueId) : bool {return ItemHasTag(item, 'HorseBag');} public final function IsItemReadable(item : SItemUniqueId) : bool {return ItemHasTag(item, 'ReadableItem');} public final function IsItemAlchemyItem(item : SItemUniqueId) : bool {return IsItemOil(item) || IsItemPotion(item) || IsItemBomb(item); } public final function IsItemSingletonItem(item : SItemUniqueId) : bool {return ItemHasTag(item, theGame.params.TAG_ITEM_SINGLETON);} public final function IsItemQuest(item : SItemUniqueId) : bool {return ItemHasTag(item, 'Quest');} public final function IsItemFood(item : SItemUniqueId) : bool {return ItemHasTag(item, 'Edibles') || ItemHasTag(item, 'Drinks');} public final function IsItemSecondaryWeapon(item : SItemUniqueId) : bool {return ItemHasTag(item, 'SecondaryWeapon');} public final function IsItemHorseItem(item: SItemUniqueId) : bool {return ItemHasTag(item, 'Saddle') || ItemHasTag(item, 'HorseBag') || ItemHasTag(item, 'Trophy') || ItemHasTag(item, 'Blinders'); } public final function IsItemSaddle(item: SItemUniqueId) : bool {return ItemHasTag(item, 'Saddle');} public final function IsItemBlinders(item: SItemUniqueId) : bool {return ItemHasTag(item, 'Blinders');} public final function IsItemDye( item : SItemUniqueId ) : bool { return ItemHasTag( item, 'mod_dye' ); } public final function IsItemUsable( item : SItemUniqueId ) : bool { return GetItemCategory( item ) == 'usable'; } public final function IsItemJunk( item : SItemUniqueId ) : bool { return ItemHasTag( item,'junk' ) || GetItemCategory( item ) == 'junk' ; } public final function IsItemAlchemyIngredient(item : SItemUniqueId) : bool { return ItemHasTag( item, 'AlchemyIngredient' ); } public final function IsItemCraftingIngredient(item : SItemUniqueId) : bool { return ItemHasTag( item, 'CraftingIngredient' ); } public final function IsItemArmorReapairKit(item : SItemUniqueId) : bool { return ItemHasTag( item, 'ArmorReapairKit' ); } public final function IsItemWeaponReapairKit(item : SItemUniqueId) : bool { return ItemHasTag( item, 'WeaponReapairKit' ); } public final function IsQuickSlotItem( item : SItemUniqueId ) : bool { return ItemHasTag( item, 'QuickSlot' ); } public final function IsItemNew( item : SItemUniqueId ) : bool { var uiData : SInventoryItemUIData; uiData = GetInventoryItemUIData( item ); return uiData.isNew; } public final function IsItemMutagenPotion(item : SItemUniqueId) : bool { return IsItemPotion(item) && ItemHasTag(item, 'Mutagen'); } public final function CanItemBeColored( item : SItemUniqueId) : bool { if ( RoundMath( CalculateAttributeValue( GetItemAttributeValue( item, 'quality' ) ) ) == 5 ) { return true; } return false; } public final function IsItemSetItem(item : SItemUniqueId) : bool { return ItemHasTag(item, theGame.params.ITEM_SET_TAG_BEAR) || ItemHasTag(item, theGame.params.ITEM_SET_TAG_GRYPHON) || ItemHasTag(item, theGame.params.ITEM_SET_TAG_LYNX) || ItemHasTag(item, theGame.params.ITEM_SET_TAG_WOLF) || ItemHasTag(item, theGame.params.ITEM_SET_TAG_RED_WOLF) || ItemHasTag( item, theGame.params.ITEM_SET_TAG_VAMPIRE ) || ItemHasTag(item, theGame.params.ITEM_SET_TAG_VIPER); } public function GetArmorType(item : SItemUniqueId) : EArmorType { var isItemEquipped : bool; isItemEquipped = GetWitcherPlayer().IsItemEquipped(item); if( thePlayer.HasAbility('Glyphword 2 _Stats', true) && isItemEquipped ) {return EAT_Light;} if( thePlayer.HasAbility('Glyphword 3 _Stats', true) && isItemEquipped ) {return EAT_Medium;} if( thePlayer.HasAbility('Glyphword 4 _Stats', true) && isItemEquipped ) {return EAT_Heavy;} if(ItemHasTag(item, 'LightArmor')) return EAT_Light; else if(ItemHasTag(item, 'MediumArmor')) return EAT_Medium; else if(ItemHasTag(item, 'HeavyArmor')) return EAT_Heavy; return EAT_Undefined; } public final function GetAlchemyCraftableItems() : array { var items : array; var i : int; GetAllItems(items); for(i=items.Size()-1; i>=0; i-=1) { if(!IsItemPotion(items[i]) && !IsItemBomb(items[i]) && !IsItemOil(items[i])) items.EraseFast(i); } return items; } public function IsItemEncumbranceItem(item : SItemUniqueId) : bool { if(ItemHasTag(item, theGame.params.TAG_ENCUMBRANCE_ITEM_FORCE_YES)) return true; if(ItemHasTag(item, theGame.params.TAG_ENCUMBRANCE_ITEM_FORCE_NO)) return false; if ( IsRecipeOrSchematic( item ) || IsItemBody( item ) ) return false; return true; } public function GetItemEncumbrance(item : SItemUniqueId) : float { var itemCategory : name; if ( IsItemEncumbranceItem( item ) ) { itemCategory = GetItemCategory( item ); if ( itemCategory == 'quest' || itemCategory == 'key' ) { return 0.01 * GetItemQuantity( item ); } else if ( itemCategory == 'usable' || itemCategory == 'upgrade' || itemCategory == 'junk' ) { return 0.01 + GetItemWeight( item ) * GetItemQuantity( item ) * 0.2; } else if ( IsItemAlchemyItem( item ) || IsItemIngredient( item ) || IsItemFood( item ) || IsItemReadable( item ) ) { return 0.0; } else { return 0.01 + GetItemWeight( item ) * GetItemQuantity( item ) * 0.5; } } return 0; } public function GetFilterTypeByItem( item : SItemUniqueId ) : EInventoryFilterType { var filterType : EInventoryFilterType; if( ItemHasTag( item, 'Quest' ) ) { return IFT_QuestItems; } else if( IsItemIngredient( item ) ) { return IFT_Ingredients; } else if( IsItemAlchemyItem(item) ) { return IFT_AlchemyItems; } else if( IsItemAnyArmor(item) ) { return IFT_Armors; } else if( IsItemWeapon( item ) ) { return IFT_Weapons; } else { return IFT_Default; } } public function IsItemQuickslotItem(item : SItemUniqueId) : bool { return IsSlotQuickslot( GetSlotForItemId(item) ); } public function GetCrossbowAmmo(id : SItemUniqueId) : int { if(!IsItemCrossbow(id)) return -1; return (int)CalculateAttributeValue(GetItemAttributeValue(id, 'ammo')); } public function GetSlotForItemId(item : SItemUniqueId) : EEquipmentSlots { var tags : array; var player : W3PlayerWitcher; var slot : EEquipmentSlots; player = ((W3PlayerWitcher)GetEntity()); GetItemTags(item, tags); slot = GetSlotForItem( GetItemCategory(item), tags, player ); if(!player) return slot; if(IsMultipleSlot(slot)) { if(slot == EES_Petard1 && player.IsAnyItemEquippedOnSlot(slot)) { if(!player.IsAnyItemEquippedOnSlot(EES_Petard2)) slot = EES_Petard2; } else if(slot == EES_Quickslot1 && player.IsAnyItemEquippedOnSlot(slot)) { if(!player.IsAnyItemEquippedOnSlot(EES_Quickslot2)) slot = EES_Quickslot2; } else if(slot == EES_Potion1 && player.IsAnyItemEquippedOnSlot(EES_Potion1)) { if(!player.IsAnyItemEquippedOnSlot(EES_Potion2)) { slot = EES_Potion2; } else { if(!player.IsAnyItemEquippedOnSlot(EES_Potion3)) { slot = EES_Potion3; } else { if(!player.IsAnyItemEquippedOnSlot(EES_Potion4)) { slot = EES_Potion4; } } } } else if(slot == EES_PotionMutagen1 && player.IsAnyItemEquippedOnSlot(slot)) { if(!player.IsAnyItemEquippedOnSlot(EES_PotionMutagen2)) { slot = EES_PotionMutagen2; } else { if(!player.IsAnyItemEquippedOnSlot(EES_PotionMutagen3)) { slot = EES_PotionMutagen3; } else { if(!player.IsAnyItemEquippedOnSlot(EES_PotionMutagen4)) { slot = EES_PotionMutagen4; } } } } else if(slot == EES_SkillMutagen1 && player.IsAnyItemEquippedOnSlot(slot)) { if(!player.IsAnyItemEquippedOnSlot(EES_SkillMutagen2)) { slot = EES_SkillMutagen2; } else { if(!player.IsAnyItemEquippedOnSlot(EES_SkillMutagen3)) { slot = EES_SkillMutagen3; } else { if(!player.IsAnyItemEquippedOnSlot(EES_SkillMutagen4)) { slot = EES_SkillMutagen4; } } } } } return slot; } public function GetAllWeapons() : array { return GetItemsByTag('Weapon'); } public function GetSpecifiedPlayerItemsQuest(steelSword, silverSword, armor, boots, gloves, pants, trophy, mask, bombs, crossbow, secondaryWeapon, equippedOnly : bool) : array { var items, allItems : array; var i : int; GetAllItems(allItems); for(i=0; i; var witcher : W3PlayerWitcher; var refill : W3RefillableContainer; witcher = GetWitcherPlayer(); if(GetEntity() == witcher) { if(IsItemCrossbow(itemId) && HasInfiniteBolts()) { crossbows = GetItemsByCategory('crossbow'); crossbows.Remove(itemId); if(crossbows.Size() == 0) { RemoveItemByName('Bodkin Bolt', GetItemQuantityByName('Bodkin Bolt')); RemoveItemByName('Harpoon Bolt', GetItemQuantityByName('Harpoon Bolt')); } } else if(IsItemBolt(itemId) && witcher.IsItemEquipped(itemId) && witcher.inv.GetItemQuantity(itemId) == quantity) { witcher.UnequipItem(itemId); } if(IsItemCrossbow(itemId) && witcher.IsItemEquipped(itemId) && witcher.rangedWeapon) { witcher.rangedWeapon.ClearDeployedEntity(true); witcher.rangedWeapon = NULL; } if( GetItemCategory(itemId) == 'usable' ) { if(witcher.IsHoldingItemInLHand() && itemId == witcher.currentlyEquipedItemL ) { witcher.HideUsableItem(true); } } if( IsItemSteelSwordUsableByPlayer( itemId ) || IsItemSilverSwordUsableByPlayer( itemId ) ) { RemoveAllOilsFromItem( itemId ); } if(witcher.IsItemEquipped(itemId) && quantity >= witcher.inv.GetItemQuantity(itemId)) witcher.UnequipItem(itemId); } if(GetEntity() == thePlayer && IsItemWeapon(itemId) && (IsItemHeld(itemId) || IsItemMounted(itemId) )) { thePlayer.OnHolsteredItem(GetItemCategory(itemId),'r_weapon'); } ent = (CGameplayEntity)GetEntity(); if(ent) ent.OnItemTaken( itemId, quantity ); if(IsLootRenewable()) { refill = (W3RefillableContainer)GetEntity(); if(refill) refill.AddTimer('Refill', 20, true); } } function GenerateItemLevel( item : SItemUniqueId, rewardItem : bool ) //modified by GeniusViking -- modIncreasedItemLevels { var stat : SAbilityAttributeValue; var playerLevel : int; var lvl, i : int; var quality : int; var ilMin, ilMax : int; playerLevel = GetWitcherPlayer().GetLevel(); //GeniusViking -- modIncreasedItemLevels++ lvl = playerLevel + 1; if ( ( W3MerchantNPC )GetEntity() ) { lvl = RoundF( playerLevel + RandRangeF( 4, 2 ) ); AddItemTag( item, 'AutogenUseLevelRange' ); } else if ( rewardItem ) { lvl = RoundF( playerLevel + RandRangeF( 2, 1 ) ); } else if ( ItemHasTag( item, 'AutogenUseLevelRange') ) { quality = RoundMath( CalculateAttributeValue( GetItemAttributeValue( item, 'quality' ) ) ); ilMin = RoundMath(CalculateAttributeValue( GetItemAttributeValue( item, 'item_level_min' ) )); ilMax = RoundMath(CalculateAttributeValue( GetItemAttributeValue( item, 'item_level_max' ) )); lvl += 1; if ( !ItemHasTag( item, 'AutogenForceLevel') ) lvl += RoundMath(RandRangeF( 2, 1 )); if ( FactsQuerySum("NewGamePlus") > 0 ) { if ( lvl < ilMin + theGame.params.GetNewGamePlusLevel() ) lvl = ilMin + theGame.params.GetNewGamePlusLevel(); if ( lvl > ilMax + theGame.params.GetNewGamePlusLevel() ) lvl = ilMax + theGame.params.GetNewGamePlusLevel(); } else { if ( lvl < ilMin ) lvl = ilMin; if ( lvl > ilMax ) lvl = ilMax; } if ( quality == 5 ) lvl += 2; if ( quality == 4 ) lvl += 2; if ( (quality == 5 || quality == 4) && ItemHasTag(item, 'EP1') ) lvl += 1; } else if ( !ItemHasTag( item, 'AutogenForceLevel') ) { quality = RoundMath( CalculateAttributeValue( GetItemAttributeValue( item, 'quality' ) ) ); if ( quality == 5 ) { lvl = RoundF( playerLevel + RandRangeF( 5, 2 ) ); } else if ( quality == 4 ) { lvl = RoundF( playerLevel + RandRangeF( 4, 2 ) ); } else if ( quality == 3 ) { lvl = RoundF( playerLevel + RandRangeF( 1, -1 ) ); /*if ( RandF() > 0.9 ) { lvl = playerLevel; }*/ } else if ( quality == 2 ) { lvl = RoundF( playerLevel + RandRangeF( 1, -2 ) ); /*if ( RandF() > 0.95 ) { lvl = playerLevel; }*/ } else { lvl = RoundF( playerLevel + RandRangeF( 0, -4 ) ); /*if ( RandF() == 0 ) { lvl = playerLevel; }*/ } } } if (FactsQuerySum("StandAloneEP1") > 0) lvl = GetWitcherPlayer().GetLevel() - 1; //if (FactsQuerySum("StandAloneEP1") > 0) // lvl = GetWitcherPlayer().GetLevel(); //GeniusViking -- modIncreasedItemLevels-- if ( FactsQuerySum("NewGamePlus") > 0 && !ItemHasTag( item, 'AutogenUseLevelRange') ) { if ( quality == 5 ) lvl += 2; if ( quality == 4 ) lvl += 1; } if ( lvl < 1 ) lvl = 1; if ( lvl > GetWitcherPlayer().GetMaxLevel() ) lvl = GetWitcherPlayer().GetMaxLevel(); if ( ItemHasTag( item, 'PlayerSteelWeapon' ) && !( ItemHasAbility( item, 'autogen_steel_base' ) || ItemHasAbility( item, 'autogen_fixed_steel_base' ) ) ) { if ( ItemHasTag(item, 'AutogenUseLevelRange') && ItemHasAbility(item, 'autogen_fixed_steel_base') ) return; if ( ItemHasTag(item, 'AutogenUseLevelRange') ) AddItemCraftedAbility(item, 'autogen_fixed_steel_base' ); else AddItemCraftedAbility(item, 'autogen_steel_base' ); for( i=0; i 0) { AddItemCraftedAbility(item, 'autogen_fixed_steel_dmg', true ); continue; } if ( ItemHasTag( item, 'AutogenForceLevel') || ItemHasTag(item, 'AutogenUseLevelRange') || FactsQuerySum("NewGamePlus") > 0 ) AddItemCraftedAbility(item, 'autogen_fixed_steel_dmg', true ); else AddItemCraftedAbility(item, 'autogen_steel_dmg', true ); } } else if ( ItemHasTag( item, 'PlayerSilverWeapon' ) && !( ItemHasAbility( item, 'autogen_silver_base' ) || ItemHasAbility( item, 'autogen_fixed_silver_base' ) ) ) { if ( ItemHasTag(item, 'AutogenUseLevelRange') && ItemHasAbility(item, 'autogen_fixed_silver_base') ) return; if ( ItemHasTag(item, 'AutogenUseLevelRange') ) AddItemCraftedAbility(item, 'autogen_fixed_silver_base' ); else AddItemCraftedAbility(item, 'autogen_silver_base' ); for( i=0; i 0) { AddItemCraftedAbility(item, 'autogen_fixed_silver_dmg', true ); continue; } if ( ItemHasTag( item, 'AutogenForceLevel') || ItemHasTag(item, 'AutogenUseLevelRange') || FactsQuerySum("NewGamePlus") > 0 ) AddItemCraftedAbility(item, 'autogen_fixed_silver_dmg', true ); else AddItemCraftedAbility(item, 'autogen_silver_dmg', true ); } } else if ( GetItemCategory( item ) == 'armor' && !( ItemHasAbility( item, 'autogen_armor_base' ) || ItemHasAbility( item, 'autogen_fixed_armor_base' ) ) ) { if ( ItemHasTag(item, 'AutogenUseLevelRange') && ItemHasAbility(item, 'autogen_fixed_armor_base') ) return; if ( ItemHasTag(item, 'AutogenUseLevelRange') ) AddItemCraftedAbility(item, 'autogen_fixed_armor_base' ); else AddItemCraftedAbility(item, 'autogen_armor_base' ); for( i=0; i 0) { AddItemCraftedAbility(item, 'autogen_fixed_armor_armor', true ); continue; } if ( ItemHasTag( item, 'AutogenForceLevel') || ItemHasTag( item, 'AutogenUseLevelRange') || FactsQuerySum("NewGamePlus") > 0 ) AddItemCraftedAbility(item, 'autogen_fixed_armor_armor', true ); else AddItemCraftedAbility(item, 'autogen_armor_armor', true ); } } else if ( ( GetItemCategory( item ) == 'boots' || GetItemCategory( item ) == 'pants' ) && !( ItemHasAbility( item, 'autogen_pants_base' ) || ItemHasAbility( item, 'autogen_fixed_pants_base' ) ) ) { if ( ItemHasTag(item, 'AutogenUseLevelRange') && ItemHasAbility(item, 'autogen_fixed_pants_base') ) return; if ( ItemHasTag(item, 'AutogenUseLevelRange') ) AddItemCraftedAbility(item, 'autogen_fixed_pants_base' ); else AddItemCraftedAbility(item, 'autogen_pants_base' ); for( i=0; i 0) { AddItemCraftedAbility(item, 'autogen_fixed_pants_armor', true ); continue; } if ( ItemHasTag( item, 'AutogenForceLevel') || ItemHasTag( item, 'AutogenUseLevelRange') || FactsQuerySum("NewGamePlus") > 0 ) AddItemCraftedAbility(item, 'autogen_fixed_pants_armor', true ); else AddItemCraftedAbility(item, 'autogen_pants_armor', true ); } } else if ( GetItemCategory( item ) == 'gloves' && !( ItemHasAbility( item, 'autogen_gloves_base' ) || ItemHasAbility( item, 'autogen_fixed_gloves_base' ) ) ) { if ( ItemHasTag(item, 'AutogenUseLevelRange') && ItemHasAbility(item, 'autogen_fixed_gloves_base') ) return; if ( ItemHasTag(item, 'AutogenUseLevelRange') ) AddItemCraftedAbility(item, 'autogen_fixed_gloves_base' ); else AddItemCraftedAbility(item, 'autogen_gloves_base' ); for( i=0; i 0) { AddItemCraftedAbility(item, 'autogen_fixed_gloves_armor', true ); continue; } if ( ItemHasTag( item, 'AutogenForceLevel') || ItemHasTag(item, 'AutogenUseLevelRange') || FactsQuerySum("NewGamePlus") > 0 ) AddItemCraftedAbility(item, 'autogen_fixed_gloves_armor', true ); else AddItemCraftedAbility(item, 'autogen_gloves_armor', true ); } } } event OnItemAdded(data : SItemChangedData) { var i, j : int; var ent : CGameplayEntity; var allCardsNames, foundCardsNames : array; var allStringNamesOfCards : array; var foundCardsStringNames : array; var gwintCards : array; var itemName : name; var witcher : W3PlayerWitcher; var itemCategory : name; var dm : CDefinitionsManagerAccessor; var locKey : string; var leaderCardsHack : array; var hud : CR4ScriptedHud; var journalUpdateModule : CR4HudModuleJournalUpdate; var itemId : SItemUniqueId; var isItemShematic : bool; var ngp : bool; ent = (CGameplayEntity)GetEntity(); itemId = data.ids[0]; if( data.informGui ) { recentlyAddedItems.PushBack( itemId ); if( ItemHasTag( itemId, 'FocusObject' ) ) { GetWitcherPlayer().GetMedallion().Activate( true, 3.0); } } if ( ItemHasTag(itemId, 'Autogen') ) { GenerateItemLevel( itemId, false ); } witcher = GetWitcherPlayer(); if(ent == witcher || ((W3MerchantNPC)ent) ) { ngp = FactsQuerySum("NewGamePlus") > 0; for(i=0; i= allStringNamesOfCards.Size()) { foundCardsNames.Clear(); for(j=0; j= allStringNamesOfCards.Size()) { theGame.GetGamerProfile().AddAchievement(EA_GwintCollector); FactsAdd("gwint_all_cards_collected", 1, -1); } } if(!FactsDoesExist("fix_for_gwent_achievement_bug_121588")) FactsAdd("fix_for_gwent_achievement_bug_121588", 1, -1); } itemCategory = GetItemCategory( itemId ); isItemShematic = itemCategory == 'alchemy_recipe' || itemCategory == 'crafting_schematic'; if( isItemShematic ) { ReadSchematicsAndRecipes( itemId ); } if( ItemHasTag( data.ids[i], 'GwintCard')) { witcher.AddGwentCard(GetItemName(data.ids[i]), data.quantity); } if( !isItemShematic && ( this.ItemHasTag( itemId, 'ReadableItem' ) || this.ItemHasTag( itemId, 'Painting' ) ) && !this.ItemHasTag( itemId, 'NoNotification' ) ) { hud = (CR4ScriptedHud)theGame.GetHud(); if( hud ) { journalUpdateModule = (CR4HudModuleJournalUpdate)hud.GetHudModule( "JournalUpdateModule" ); if( journalUpdateModule ) { journalUpdateModule.AddQuestBookInfo( itemId ); } } } } } if( IsItemSingletonItem( itemId ) ) { for(i=0; i 0.5 ) AddItemCraftedAbility(item, theGame.params.GetRandomMagicalArmorAbility(), true); else AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkArmorAbility(), true); if ( RandF() > 0.5 ) AddItemCraftedAbility(item, theGame.params.GetRandomMagicalArmorAbility(), true); else AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkArmorAbility(), true); break; default : break; } } else if ( itemCategory == 'gloves' ) { switch ( itemQuality ) { case 2 : ability = 'quality_masterwork_gloves'; AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkGlovesAbility(), true); break; case 3 : ability = 'quality_magical_gloves'; if ( ItemHasTag(item, 'EP1') ) { AddItemCraftedAbility(item, theGame.params.GetRandomMagicalArmorAbility(), true); break; } if ( RandF() > 0.5 ) AddItemCraftedAbility(item, theGame.params.GetRandomMagicalGlovesAbility(), true); else AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkGlovesAbility(), true); if ( RandF() > 0.5 ) AddItemCraftedAbility(item, theGame.params.GetRandomMagicalGlovesAbility(), true); else AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkGlovesAbility(), true); break; default : break; } } else if ( itemCategory == 'pants' ) { switch ( itemQuality ) { case 2 : ability = 'quality_masterwork_pants'; AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkPantsAbility(), true); break; case 3 : ability = 'quality_magical_pants'; if ( ItemHasTag(item, 'EP1') ) { AddItemCraftedAbility(item, theGame.params.GetRandomMagicalArmorAbility(), true); break; } if ( RandF() > 0.5 ) AddItemCraftedAbility(item, theGame.params.GetRandomMagicalPantsAbility(), true); else AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkPantsAbility(), true); if ( RandF() > 0.5 ) AddItemCraftedAbility(item, theGame.params.GetRandomMagicalPantsAbility(), true); else AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkPantsAbility(), true); break; default : break; } } else if ( itemCategory == 'boots' ) { switch ( itemQuality ) { case 2 : ability = 'quality_masterwork_boots'; AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkBootsAbility(), true); break; case 3 : ability = 'quality_magical_boots'; if ( ItemHasTag(item, 'EP1') ) { AddItemCraftedAbility(item, theGame.params.GetRandomMagicalArmorAbility(), true); break; } if ( RandF() > 0.5 ) AddItemCraftedAbility(item, theGame.params.GetRandomMagicalBootsAbility(), true); else AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkBootsAbility(), true); if ( RandF() > 0.5 ) AddItemCraftedAbility(item, theGame.params.GetRandomMagicalBootsAbility(), true); else AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkBootsAbility(), true); break; default : break; } } else if ( itemCategory == 'steelsword' ) { switch ( itemQuality ) { case 2 : ability = 'quality_masterwork_steelsword'; AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkWeaponAbility(), true); break; case 3 : ability = 'quality_magical_steelsword'; if ( ItemHasTag(item, 'EP1') ) { AddItemCraftedAbility(item, theGame.params.GetRandomMagicalArmorAbility(), true); break; } if ( RandF() > 0.5 ) AddItemCraftedAbility(item, theGame.params.GetRandomMagicalWeaponAbility(), true); else AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkWeaponAbility(), true); if ( RandF() > 0.5 ) AddItemCraftedAbility(item, theGame.params.GetRandomMagicalWeaponAbility(), true); else AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkWeaponAbility(), true); break; default : break; } } else if ( itemCategory == 'silversword' ) { switch ( itemQuality ) { case 2 : ability = 'quality_masterwork_silversword'; AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkWeaponAbility(), true); break; case 3 : ability = 'quality_magical_silversword'; if ( ItemHasTag(item, 'EP1') ) { AddItemCraftedAbility(item, theGame.params.GetRandomMagicalArmorAbility(), true); break; } if ( RandF() > 0.5 ) AddItemCraftedAbility(item, theGame.params.GetRandomMagicalWeaponAbility(), true); else AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkWeaponAbility(), true); if ( RandF() > 0.5 ) AddItemCraftedAbility(item, theGame.params.GetRandomMagicalWeaponAbility(), true); else AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkWeaponAbility(), true); break; default : break; } } if(IsNameValid(ability)) { AddItemCraftedAbility(item, ability, false); SetItemModifierInt(item, 'ItemQualityModified', 1); } } public function IncreaseNGPItemlevel(item : SItemUniqueId) { var i, diff : int; diff = theGame.params.NewGamePlusLevelDifference(); if (diff > 0) { if ( ItemHasTag( item, 'PlayerSteelWeapon' ) ) { for( i=0; i; var tempItemQualityAtribute : SAbilityAttributeValue; excludedTags.PushBack(theGame.params.OIL_ABILITY_TAG); itemQualityAtribute = GetItemAttributeValue( itemId, 'quality', excludedTags, true ); itemQuality = itemQualityAtribute.valueAdditive; if( itemQuality == 0 ) { itemQuality = 1; } return RoundMath(itemQuality); } public function GetItemQualityFromName( itemName : name, out min : int, out max : int) { var dm : CDefinitionsManagerAccessor; var attributeName : name; var attributes, itemAbilities : array; var attributeMin, attributeMax : SAbilityAttributeValue; var tmpInt : int; var tmpArray : array; dm = theGame.GetDefinitionsManager(); dm.GetItemAbilitiesWithWeights(itemName, GetEntity() == thePlayer, itemAbilities, tmpArray, tmpInt, tmpInt); attributes = dm.GetAbilitiesAttributes(itemAbilities); for (tmpInt = 0; tmpInt < attributes.Size(); tmpInt += 1) { if (attributes[tmpInt] == 'quality') { dm.GetAbilitiesAttributeValue(itemAbilities, 'quality', attributeMin, attributeMax); min = RoundMath(CalculateAttributeValue(attributeMin)); max = RoundMath(CalculateAttributeValue(attributeMax)); break; } } } public function GetRecentlyAddedItems() : array { return recentlyAddedItems; } public function GetRecentlyAddedItemsListSize() : int { return recentlyAddedItems.Size(); } public function RemoveItemFromRecentlyAddedList( itemId : SItemUniqueId ) : bool { var i : int; for( i = 0; i < recentlyAddedItems.Size(); i += 1 ) { if( recentlyAddedItems[i] == itemId ) { recentlyAddedItems.EraseFast( i ); return true; } } return false; } import final function NotifyScriptedListeners( notify : bool ); var listeners : array< IInventoryScriptedListener >; function AddListener( listener : IInventoryScriptedListener ) { if ( listeners.FindFirst( listener ) == -1 ) { listeners.PushBack( listener ); if ( listeners.Size() == 1 ) { NotifyScriptedListeners( true ); } } } function RemoveListener( listener : IInventoryScriptedListener ) { if ( listeners.Remove( listener ) ) { if ( listeners.Size() == 0 ) { NotifyScriptedListeners( false ); } } } event OnInventoryScriptedEvent( eventType : EInventoryEventType, itemId : SItemUniqueId, quantity : int, fromAssociatedInventory : bool ) { var i, size : int; size = listeners.Size(); for (i=size-1; i>=0; i-=1 ) { listeners[i].OnInventoryScriptedEvent( eventType, itemId, quantity, fromAssociatedInventory ); } if(GetEntity() == GetWitcherPlayer() && (eventType == IET_ItemRemoved || eventType == IET_ItemQuantityChanged) ) GetWitcherPlayer().UpdateEncumbrance(); } public final function GetMutationResearchPoints( color : ESkillColor, item : SItemUniqueId ) : int { var val : SAbilityAttributeValue; var colorAttribute : name; if( color == SC_None || color == SC_Yellow || !IsIdValid( item ) ) { return 0; } switch( color ) { case SC_Red: colorAttribute = 'mutation_research_points_red'; break; case SC_Blue: colorAttribute = 'mutation_research_points_blue'; break; case SC_Green: colorAttribute = 'mutation_research_points_green'; break; } val = GetItemAttributeValue( item, colorAttribute ); return ( int )val.valueAdditive; } public function GetSkillMutagenColor(item : SItemUniqueId) : ESkillColor { var abs : array; if(!ItemHasTag(item, 'MutagenIngredient')) return SC_None; GetItemAbilities(item, abs); if(abs.Contains('mutagen_color_green')) return SC_Green; if(abs.Contains('mutagen_color_blue')) return SC_Blue; if(abs.Contains('mutagen_color_red')) return SC_Red; if(abs.Contains('lesser_mutagen_color_green')) return SC_Green; if(abs.Contains('lesser_mutagen_color_blue')) return SC_Blue; if(abs.Contains('lesser_mutagen_color_red')) return SC_Red; if(abs.Contains('greater_mutagen_color_green')) return SC_Green; if(abs.Contains('greater_mutagen_color_blue')) return SC_Blue; if(abs.Contains('greater_mutagen_color_red')) return SC_Red; return SC_None; } import final function GetItemEnhancementSlotsCount( itemId : SItemUniqueId ) : int; import final function GetItemEnhancementItems( itemId : SItemUniqueId, out names : array< name > ); import final function GetItemEnhancementCount( itemId : SItemUniqueId ) : int; import final function GetItemColor( itemId : SItemUniqueId ) : name; import final function IsItemColored( itemId : SItemUniqueId ) : bool; import final function SetPreviewColor( itemId : SItemUniqueId, colorId : int ); import final function ClearPreviewColor( itemId : SItemUniqueId ) : bool; import final function ColorItem( itemId : SItemUniqueId, dyeId : SItemUniqueId ); import final function ClearItemColor( itemId : SItemUniqueId ) : bool; import final function EnchantItem( enhancedItemId : SItemUniqueId, enchantmentName : name, enchantmentStat : name ) : bool; import final function GetEnchantment( enhancedItemId : SItemUniqueId ) : name; import final function IsItemEnchanted( enhancedItemId : SItemUniqueId ) : bool; import final function UnenchantItem( enhancedItemId : SItemUniqueId ) : bool; import private function EnhanceItem( enhancedItemId : SItemUniqueId, extensionItemId : SItemUniqueId ) : bool; import private function RemoveItemEnhancementByIndex( enhancedItemId : SItemUniqueId, slotIndex : int ) : bool; import private function RemoveItemEnhancementByName( enhancedItemId : SItemUniqueId, extensionItemName : name ) : bool; import final function PreviewItemAttributeAfterUpgrade( baseItemId : SItemUniqueId, upgradeItemId : SItemUniqueId, attributeName : name, optional baseInventory : CInventoryComponent, optional upgradeInventory : CInventoryComponent ) : SAbilityAttributeValue; import final function HasEnhancementItemTag( enhancedItemId : SItemUniqueId, slotIndex : int, tag : name ) : bool; function NotifyEnhancedItem( enhancedItemId : SItemUniqueId ) { var weapons : array; var sword : CWitcherSword; var i : int; sword = (CWitcherSword) GetItemEntityUnsafe( enhancedItemId ); sword.UpdateEnhancements( this ); } function EnhanceItemScript( enhancedItemId : SItemUniqueId, extensionItemId : SItemUniqueId ) : bool { var i : int; var enhancements : array; var runeword : Runeword; if ( EnhanceItem( enhancedItemId, extensionItemId ) ) { NotifyEnhancedItem( enhancedItemId ); GetItemEnhancementItems( enhancedItemId, enhancements ); if ( theGame.runewordMgr.GetRuneword( enhancements, runeword ) ) { for ( i = 0; i < runeword.abilities.Size(); i+=1 ) { AddItemBaseAbility( enhancedItemId, runeword.abilities[i] ); } } return true; } return false; } function RemoveItemEnhancementByIndexScript( enhancedItemId : SItemUniqueId, slotIndex : int ) : bool { var i : int; var enhancements : array; var runeword : Runeword; var hasRuneword : bool; var names : array< name >; GetItemEnhancementItems( enhancedItemId, enhancements ); hasRuneword = theGame.runewordMgr.GetRuneword( enhancements, runeword ); GetItemEnhancementItems( enhancedItemId, names ); if ( RemoveItemEnhancementByIndex( enhancedItemId, slotIndex ) ) { NotifyEnhancedItem( enhancedItemId ); if ( hasRuneword ) { for ( i = 0; i < runeword.abilities.Size(); i+=1 ) { RemoveItemBaseAbility( enhancedItemId, runeword.abilities[i] ); } } return true; } return false; } function RemoveItemEnhancementByNameScript( enhancedItemId : SItemUniqueId, extensionItemName : name ) : bool { var i : int; var enhancements : array; var runeword : Runeword; var hasRuneword : bool; GetItemEnhancementItems( enhancedItemId, enhancements ); hasRuneword = theGame.runewordMgr.GetRuneword( enhancements, runeword ); if ( RemoveItemEnhancementByName( enhancedItemId, extensionItemName ) ) { NotifyEnhancedItem( enhancedItemId ); AddAnItem( extensionItemName, 1, true, true ); if ( hasRuneword ) { for ( i = 0; i < runeword.abilities.Size(); i+=1 ) { RemoveItemBaseAbility( enhancedItemId, runeword.abilities[i] ); } } return true; } return false; } function RemoveAllItemEnhancements( enhancedItemId : SItemUniqueId ) { var count, i : int; count = GetItemEnhancementCount( enhancedItemId ); for ( i = count - 1; i >= 0; i-=1 ) { RemoveItemEnhancementByIndexScript( enhancedItemId, i ); } } function GetHeldAndMountedItems( out items : array< SItemUniqueId > ) { var allItems : array< SItemUniqueId >; var i : int; var itemName : name; GetAllItems( allItems ); items.Clear(); for( i = 0; i < allItems.Size(); i += 1 ) { if ( IsItemHeld( allItems[ i ] ) || IsItemMounted( allItems[ i ] ) ) { items.PushBack( allItems[ i ] ); } } } public function GetHasValidDecorationItems( items : array, decoration : W3HouseDecorationBase ) : bool { var i, size : int; size = items.Size(); if(size == 0 ) { LogChannel( 'houseDecorations', "No items with valid tag were found!" ); return false; } for( i=0; i < size; i+= 1 ) { if( GetWitcherPlayer().IsItemEquipped( items[i] ) ) { LogChannel( 'houseDecorations', "Found item is equipped, erasing..." ); continue; } if( IsItemQuest( items[i] ) && decoration.GetAcceptQuestItems() == false ) { LogChannel( 'houseDecorations', "Found item is quest item, and quest items are not accepted, erasing..." ); continue; } if( decoration.GetItemHasForbiddenTag( items[i] ) ) { LogChannel( 'houseDecorations', "Found item has a forbidden tag, erasing..." ); continue; } LogChannel( 'houseDecorations', "Item checks out: "+ GetItemName( items[i] ) ); return true; } LogChannel( 'houseDecorations', "No valid items were found!" ); return false; } function GetMissingCards() : array< name > { var defMgr : CDefinitionsManagerAccessor = theGame.GetDefinitionsManager(); var allCardNames : array< name > = defMgr.GetItemsWithTag(theGame.params.GWINT_CARD_ACHIEVEMENT_TAG); var playersCards : array< SItemUniqueId > = GetItemsByTag(theGame.params.GWINT_CARD_ACHIEVEMENT_TAG); var playersCardLocs : array< string >; var missingCardLocs : array< string >; var missingCards : array< name >; var i, j : int; var found : bool; for ( i = 0; i < allCardNames.Size(); i+=1 ) { found = false; for ( j = 0; j < playersCards.Size(); j+=1 ) { if ( allCardNames[i] == GetItemName( playersCards[j] ) ) { found = true; playersCardLocs.PushBack( defMgr.GetItemLocalisationKeyName ( allCardNames[i] ) ); break; } } if ( !found ) { missingCardLocs.PushBack( defMgr.GetItemLocalisationKeyName( allCardNames[i] ) ); missingCards.PushBack( allCardNames[i] ); } } if( missingCardLocs.Size() < 2 ) { return missingCards; } for ( i = missingCardLocs.Size()-1 ; i >= 0 ; i-=1 ) { for ( j = 0 ; j < playersCardLocs.Size() ; j+=1 ) { if ( missingCardLocs[i] == playersCardLocs[j] && missingCardLocs[i] != "gwint_name_emhyr" && missingCardLocs[i] != "gwint_name_foltest" && missingCardLocs[i] != "gwint_name_francesca" && missingCardLocs[i] != "gwint_name_eredin" ) { missingCardLocs.EraseFast( i ); missingCards.EraseFast( i ); break; } } } return missingCards; } public function FindCardSources( missingCards : array< name > ) : array< SCardSourceData > { var sourceCSV : C2dArray; var sourceTable : array< SCardSourceData >; var sourceRemaining : array< SCardSourceData >; var sourceCount, i, j : int; if ( theGame.IsFinalBuild() ) { sourceCSV = LoadCSV("gameplay\globals\card_sources.csv"); } else { sourceCSV = LoadCSV("qa\card_sources.csv"); } sourceCount = sourceCSV.GetNumRows(); sourceTable.Resize(sourceCount); for ( i = 0 ; i < sourceCount ; i+=1 ) { sourceTable[i].cardName = sourceCSV.GetValueAsName("CardName",i); sourceTable[i].source = sourceCSV.GetValue("Source",i); sourceTable[i].originArea = sourceCSV.GetValue("OriginArea",i); sourceTable[i].originQuest = sourceCSV.GetValue("OriginQuest",i); sourceTable[i].details = sourceCSV.GetValue("Details",i); sourceTable[i].coords = sourceCSV.GetValue("Coords",i); } for ( i = 0 ; i < missingCards.Size() ; i+=1 ) { for ( j = 0 ; j < sourceCount ; j+=1 ) { if ( sourceTable[j].cardName == missingCards[i] ) { sourceRemaining.PushBack( sourceTable[j] ); } } } return sourceRemaining; } public function GetGwentAlmanacContents() : string { var sourcesRemaining : array< SCardSourceData >; var missingCards : array< string >; var almanacContents : string; var i : int; var NML, Novigrad, Skellige, Prologue, Vizima, KaerMorhen, Random : int; sourcesRemaining = FindCardSources( GetMissingCards() ); for ( i = 0 ; i < sourcesRemaining.Size() ; i+=1 ) { switch ( sourcesRemaining[i].originArea ) { case "NML": NML += 1; break; case "Novigrad": Novigrad += 1; break; case "Skellige": Skellige += 1; break; case "Prologue": Prologue += 1; break; case "Vizima": Vizima += 1; break; case "KaerMorhen": KaerMorhen += 1; break; case "Random": Random += 1; break; default: break; } } if ( NML + Novigrad + Skellige + Prologue + Vizima + KaerMorhen + Random == 0 ) { almanacContents = GetLocStringByKeyExt( "gwent_almanac_text" ) + "
"; almanacContents += GetLocStringByKeyExt( "gwent_almanac_completed_text" ); } else { almanacContents = GetLocStringByKeyExt( "gwent_almanac_text" ) + "
"; if ( NML > 0 ) { almanacContents += GetLocStringByKeyExt( "location_name_velen" ) + ": " + NML + "
"; } if ( Novigrad > 0 ) { almanacContents += GetLocStringByKeyExt( "map_location_novigrad" ) + ": " + Novigrad + "
"; } if ( Skellige > 0 ) { almanacContents += GetLocStringByKeyExt( "map_location_skellige" ) + ": " + Skellige + "
"; } if ( Prologue > 0 ) { almanacContents += GetLocStringByKeyExt( "map_location_prolog_village" ) + ": " + Prologue + "
"; } if ( Vizima > 0 ) { almanacContents += GetLocStringByKeyExt( "map_location_wyzima_castle" ) + ": " + Vizima + "
"; } if ( KaerMorhen > 0 ) { almanacContents += GetLocStringByKeyExt( "map_location_kaer_morhen" ) + ": " + KaerMorhen + "
"; } almanacContents += GetLocStringByKeyExt( "gwent_source_random" ) + ": " + Random; } return almanacContents; } public function GetUnusedMutagensCount(itemName:name):int { var items : array; var equippedOnSlot : EEquipmentSlots; var availableCount : int; var res, i : int = 0; items = thePlayer.inv.GetItemsByName(itemName); for(i=0; i; var equippedOnSlot : EEquipmentSlots; var availableCount : int; var res, i : int = 0; items = thePlayer.inv.GetItemsByName(itemName); for(i=0; i; var curItem : SItemUniqueId; var equippedOnSlot : EEquipmentSlots; var i : int; var itemRemoved : int; var availableToRemoved : int; var removedRes : bool; itemRemoved = 0; items = thePlayer.inv.GetItemsByName( itemName ); for( i=0; i < items.Size(); i+=1 ) { curItem = items[ i ]; equippedOnSlot = GetWitcherPlayer().GetItemSlot( curItem ); if( equippedOnSlot == EES_InvalidSlot ) { availableToRemoved = Min( thePlayer.inv.GetItemQuantity( curItem ), ( count - itemRemoved ) ); removedRes = thePlayer.inv.RemoveItem(items[i], availableToRemoved); if (removedRes) { itemRemoved = itemRemoved + availableToRemoved; if (itemRemoved >= count) { return; } } } } } } exec function findMissingCards( optional card : name ) { var inv : CInventoryComponent = thePlayer.GetInventory(); var sourcesRemaining : array< SCardSourceData >; var missingCards : array< name >; var i : int; var sourceLogString : string; if ( card != '' ) { missingCards.PushBack( card ); } else { missingCards = inv.GetMissingCards(); } sourcesRemaining = inv.FindCardSources( missingCards ); for ( i = 0 ; i < sourcesRemaining.Size() ; i+=1 ) { sourceLogString = sourcesRemaining[i].cardName + " is a " + sourcesRemaining[i].source ; if ( sourcesRemaining[i].originArea == "Random" ) { sourceLogString += " card from a random merchant."; } else { sourceLogString += " item in " + sourcesRemaining[i].originArea + " from "; if ( sourcesRemaining[i].originQuest != "" ) { sourceLogString += sourcesRemaining[i].originQuest + " , "; } sourceLogString += sourcesRemaining[i].details; } Log( sourceLogString ); if ( sourcesRemaining[i].coords != "" ) { Log( sourcesRemaining[i].coords ); } } } exec function slotTest() { var inv : CInventoryComponent = thePlayer.inv; var weaponItemId : SItemUniqueId; var upgradeItemId : SItemUniqueId; var i : int; LogChannel('SlotTest', "----------------------------------------------------------------"); inv.AddAnItem( 'Perun rune', 1); inv.AddAnItem( 'Svarog rune', 1); for ( i = 0; i < 2; i += 1 ) { if ( !GetItem( inv, 'steelsword', weaponItemId ) || !GetItem( inv, 'upgrade', upgradeItemId ) ) { return; } PrintItem( inv, weaponItemId ); if ( inv.EnhanceItemScript( weaponItemId, upgradeItemId ) ) { LogChannel('SlotTest', "Enhanced item"); } else { LogChannel('SlotTest', "Failed to enhance item!"); } } if ( !GetItem( inv, 'steelsword', weaponItemId ) ) { return; } PrintItem( inv, weaponItemId ); if ( inv.RemoveItemEnhancementByNameScript( weaponItemId, 'Svarog rune' ) ) { LogChannel('SlotTest', "Removed enhancement"); } else { LogChannel('SlotTest', "Failed to remove enhancement!"); } if ( !GetItem( inv, 'steelsword', weaponItemId ) ) { return; } PrintItem( inv, weaponItemId ); if ( inv.RemoveItemEnhancementByIndexScript( weaponItemId, 0 ) ) { LogChannel('SlotTest', "Removed enhancement"); } else { LogChannel('SlotTest', "Failed to remove enhancement!"); } if ( !GetItem( inv, 'steelsword', weaponItemId ) ) { return; } PrintItem( inv, weaponItemId ); } function GetItem( inv : CInventoryComponent, category : name, out itemId : SItemUniqueId ) : bool { var itemIds : array< SItemUniqueId >; itemIds = inv.GetItemsByCategory( category ); if ( itemIds.Size() > 0 ) { itemId = itemIds[ 0 ]; return true; } LogChannel( 'SlotTest', "Failed to get item with GetItemsByCategory( '" + category + "' )" ); return false; } function PrintItem( inv : CInventoryComponent, weaponItemId : SItemUniqueId ) { var names : array< name >; var tags : array< name >; var i : int; var line : string; var attribute : SAbilityAttributeValue; LogChannel('SlotTest', "Slots: " + inv.GetItemEnhancementCount( weaponItemId ) + "/" + inv.GetItemEnhancementSlotsCount( weaponItemId ) ); inv.GetItemEnhancementItems( weaponItemId, names ); if ( names.Size() > 0 ) { for ( i = 0; i < names.Size(); i += 1 ) { if ( i == 0 ) { line += "["; } line += names[ i ]; if ( i < names.Size() - 1 ) { line += ", "; } if ( i == names.Size() - 1 ) { line += "]"; } } } else { line += "[]"; } LogChannel('SlotTest', "Upgrade item names " + line ); tags.PushBack('Upgrade'); attribute = inv.GetItemAttributeValue( weaponItemId, 'PhysicalDamage' ); LogChannel('SlotTest', "Attribute '" + 'PhysicalDamage' + "' " + attribute.valueBase + " " + attribute.valueMultiplicative + " " + attribute.valueAdditive ); attribute = inv.GetItemAttributeValue( weaponItemId, 'SilverDamage' ); LogChannel('SlotTest', "Attribute '" + 'SilverDamage' + "' " + attribute.valueBase + " " + attribute.valueMultiplicative + " " + attribute.valueAdditive ); attribute = inv.GetItemAttributeValue( weaponItemId, 'PhysicalDamage', tags, true ); LogChannel('SlotTest', "Attribute '" + 'PhysicalDamage' + "' " + attribute.valueBase + " " + attribute.valueMultiplicative + " " + attribute.valueAdditive ); attribute = inv.GetItemAttributeValue( weaponItemId, 'SilverDamage', tags, true ); LogChannel('SlotTest', "Attribute '" + 'SilverDamage' + "' " + attribute.valueBase + " " + attribute.valueMultiplicative + " " + attribute.valueAdditive ); attribute = inv.GetItemAttributeValue( weaponItemId, 'PhysicalDamage', tags ); LogChannel('SlotTest', "Attribute '" + 'PhysicalDamage' + "' " + attribute.valueBase + " " + attribute.valueMultiplicative + " " + attribute.valueAdditive ); attribute = inv.GetItemAttributeValue( weaponItemId, 'SilverDamage', tags ); LogChannel('SlotTest', "Attribute '" + 'SilverDamage' + "' " + attribute.valueBase + " " + attribute.valueMultiplicative + " " + attribute.valueAdditive ); } function PlayItemEquipSound( itemCategory : name ) : void { switch( itemCategory ) { case 'steelsword' : theSound.SoundEvent("gui_inventory_steelsword_attach"); return; case 'silversword' : theSound.SoundEvent("gui_inventory_silversword_attach"); return; case 'secondary' : theSound.SoundEvent("gui_inventory_weapon_attach"); return; case 'armor' : theSound.SoundEvent("gui_inventory_armor_attach"); return; case 'pants' : theSound.SoundEvent("gui_inventory_pants_attach"); return; case 'boots' : theSound.SoundEvent("gui_inventory_boots_attach"); return; case 'gloves' : theSound.SoundEvent("gui_inventory_gauntlet_attach"); return; case 'potion' : theSound.SoundEvent("gui_inventory_potion_attach"); return; case 'petard' : theSound.SoundEvent("gui_inventory_bombs_attach"); return; case 'ranged' : theSound.SoundEvent("gui_inventory_ranged_attach"); return; case 'herb' : theSound.SoundEvent("gui_pick_up_herbs"); return; case 'trophy' : case 'horse_bag' : theSound.SoundEvent("gui_inventory_horse_bage_attach"); return; case 'horse_blinder' : theSound.SoundEvent("gui_inventory_horse_blinder_attach"); return; case 'horse_saddle' : theSound.SoundEvent("gui_inventory_horse_saddle_attach"); return; default : theSound.SoundEvent("gui_inventory_other_attach"); return; } } function PlayItemUnequipSound( itemCategory : name ) : void { switch( itemCategory ) { case 'steelsword' : theSound.SoundEvent("gui_inventory_steelsword_back"); return; case 'silversword' : theSound.SoundEvent("gui_inventory_silversword_back"); return; case 'secondary' : theSound.SoundEvent("gui_inventory_weapon_back"); return; case 'armor' : theSound.SoundEvent("gui_inventory_armor_back"); return; case 'pants' : theSound.SoundEvent("gui_inventory_pants_back"); return; case 'boots' : theSound.SoundEvent("gui_inventory_boots_back"); return; case 'gloves' : theSound.SoundEvent("gui_inventory_gauntlet_back"); return; case 'petard' : theSound.SoundEvent("gui_inventory_bombs_back"); return; case 'potion' : theSound.SoundEvent("gui_inventory_potion_back"); return; case 'ranged' : theSound.SoundEvent("gui_inventory_ranged_back"); return; case 'trophy' : case 'horse_bag' : theSound.SoundEvent("gui_inventory_horse_bage_back"); return; case 'horse_blinder' : theSound.SoundEvent("gui_inventory_horse_blinder_back"); return; case 'horse_saddle' : theSound.SoundEvent("gui_inventory_horse_saddle_back"); return; default : theSound.SoundEvent("gui_inventory_other_back"); return; } } function PlayItemConsumeSound( item : SItemUniqueId ) : void { if( thePlayer.GetInventory().ItemHasTag( item, 'Drinks' ) || thePlayer.GetInventory().ItemHasTag( item, 'Alcohol' ) ) { theSound.SoundEvent('gui_inventory_drink'); } else { theSound.SoundEvent('gui_inventory_eat'); } }