Facebook
From MMPCheater, 4 Years ago, written in C++.
Embed
Download Paste or View Raw
Hits: 289
  1. /***********************************************************************/
  2. /**     © 2015 CD PROJEKT S.A. All rights reserved.
  3. /**     THE WITCHER® is a trademark of CD PROJEKT S. A.
  4. /**     The Witcher game is based on the prose of Andrzej Sapkowski.
  5. /***********************************************************************/
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12. class IInventoryScriptedListener
  13. {
  14.         event OnInventoryScriptedEvent( eventType : EInventoryEventType, itemId : SItemUniqueId, quantity : int, fromAssociatedInventory : bool ) {}
  15. }
  16.  
  17. import struct SItemNameProperty
  18. {
  19.         import editable var itemName : name;
  20. };
  21.  
  22. import struct SR4LootNameProperty
  23. {
  24.         import editable var lootName : name;
  25. };
  26.  
  27. struct SItemExt
  28. {
  29.         editable var itemName : SItemNameProperty;
  30.         editable var quantity : int;
  31.                 default quantity = 1;
  32. };
  33.  
  34. struct SCardSourceData
  35. {
  36.         var cardName    : name;
  37.         var source              : string;
  38.         var originArea  : string;
  39.         var originQuest : string;
  40.         var details             : string;
  41.         var coords              : string;
  42. };
  43.  
  44.  
  45. import struct SItemChangedData
  46. {
  47.         import const var itemName : name;                              
  48.         import const var quantity : int;                               
  49.         import const var informGui : bool;                             
  50.         import const var ids : array< SItemUniqueId >; 
  51. };
  52.  
  53. import class CInventoryComponent extends CComponent
  54. {   editable            var priceMult                   : float;
  55.         editable                var priceRepairMult             : float;
  56.         editable                var priceRepair                 : float;
  57.         editable                var fundsType                   : EInventoryFundsType;
  58.  
  59.         private                 var recentlyAddedItems  : array<SItemUniqueId>;
  60.         private                 var fundsMax                    : int;
  61.         private                 var daysToIncreaseFunds : int;
  62.  
  63.         default priceMult = 1.0;
  64.         default priceRepairMult = 1.0;
  65.         default priceRepair = 10.0;
  66.         default fundsType = EInventoryFunds_Avg;
  67.         default daysToIncreaseFunds = 5;
  68.  
  69.        
  70.        
  71.        
  72.         public function GetFundsType() : EInventoryFundsType
  73.         {
  74.                 return fundsType;
  75.         }
  76.  
  77.         public function GetDaysToIncreaseFunds() : int
  78.         {
  79.                 return daysToIncreaseFunds;
  80.         }
  81.  
  82.         public function GetFundsMax() : float
  83.         {
  84.                 if ( EInventoryFunds_Broke == fundsType )
  85.                 {
  86.                         return 0;
  87.                 }
  88.                 else if ( EInventoryFunds_Avg == fundsType )
  89.                 {
  90.                         return 5000;
  91.                 }
  92.                 else if ( EInventoryFunds_Poor == fundsType )
  93.                 {
  94.                         return 2500;
  95.                 }
  96.                 else if ( EInventoryFunds_Rich == fundsType )
  97.                 {
  98.                         return 7500;
  99.                 }
  100.                 else if ( EInventoryFunds_RichQuickStart == fundsType )
  101.                 {
  102.                         return 15000;
  103.                 }
  104.                 return -1;
  105.         }
  106.  
  107.         public function SetupFunds()
  108.         {
  109.                 if ( EInventoryFunds_Broke == fundsType )
  110.                 {
  111.                         AddMoney( 0 );
  112.                 }
  113.                 else if ( EInventoryFunds_Poor == fundsType )
  114.                 {
  115.                         AddMoney( (int)( 200 * GetFundsModifier() ) );
  116.                 }
  117.                 else if ( EInventoryFunds_Avg == fundsType )
  118.                 {
  119.                         AddMoney( (int)( 500 * GetFundsModifier() ) );
  120.                 }
  121.                 else if ( EInventoryFunds_Rich == fundsType )
  122.                 {
  123.                         AddMoney( (int)( 1000 * GetFundsModifier() ) );
  124.                 }
  125.                 else if ( EInventoryFunds_RichQuickStart == fundsType )
  126.                 {
  127.                         AddMoney( (int)( 5000 * GetFundsModifier() ) );
  128.                 }
  129.         }
  130.  
  131.         public function IncreaseFunds()
  132.         {
  133.                 if ( GetMoney() < GetFundsMax() )
  134.                 {
  135.                         if ( EInventoryFunds_Avg == fundsType )
  136.                         {
  137.                                 AddMoney( (int)( 150 * GetFundsModifier()) );
  138.                         }
  139.                         else if ( EInventoryFunds_Poor == fundsType )
  140.                         {
  141.                                 AddMoney( (int)( 100 * GetFundsModifier() ) );
  142.                         }
  143.                         else if ( EInventoryFunds_Rich == fundsType )
  144.                         {
  145.                                 AddMoney( (int)( 1000 * GetFundsModifier() ) );
  146.                         }
  147.                         else if ( EInventoryFunds_RichQuickStart == fundsType )
  148.                         {
  149.                                 AddMoney( 1000 + (int)( 2500 * GetFundsModifier() ) );
  150.                         }
  151.                 }
  152.         }
  153.  
  154.         public function GetMoney() : int
  155.         {
  156.                 return GetItemQuantityByName( 'Crowns' );
  157.         }
  158.        
  159.         public function SetMoney( amount : int )
  160.         {
  161.                 var currentMoney : int;
  162.                
  163.                 if ( amount >= 0 )
  164.                 {
  165.                         currentMoney = GetMoney();
  166.                         RemoveMoney( currentMoney );
  167.  
  168.                         AddAnItem( 'Crowns', amount );
  169.                 }
  170.         }
  171.  
  172.         public function AddMoney( amount : int )
  173.         {
  174.                 if ( amount > 0 )
  175.                 {
  176.                         AddAnItem( 'Crowns', amount );
  177.                        
  178.                         if ( thePlayer == GetEntity() )
  179.                         {
  180.                                 theTelemetry.LogWithValue( TE_HERO_CASH_CHANGED, amount );
  181.                         }
  182.                 }
  183.         }
  184.        
  185.         public function RemoveMoney( amount : int )
  186.         {
  187.                 if ( amount > 0 )
  188.                 {
  189.                         RemoveItemByName( 'Crowns', amount );
  190.                        
  191.                         if ( thePlayer == GetEntity() )
  192.                         {
  193.                                 theTelemetry.LogWithValue( TE_HERO_CASH_CHANGED, -amount );
  194.                         }
  195.                 }
  196.         }
  197.  
  198.        
  199.        
  200.        
  201.        
  202.         import final function GetItemAbilityAttributeValue( itemId : SItemUniqueId, attributeName : name, abilityName : name) : SAbilityAttributeValue;
  203.        
  204.         import final function GetItemFromSlot( slotName : name ) : SItemUniqueId;
  205.                
  206.        
  207.         import final function IsIdValid( itemId : SItemUniqueId ) : bool;
  208.  
  209.        
  210.         import final function GetItemCount( optional useAssociatedInventory : bool  ) : int;
  211.        
  212.        
  213.         import final function GetItemsNames() : array< name >;
  214.        
  215.        
  216.         import final function GetAllItems( out items : array< SItemUniqueId > );
  217.        
  218.        
  219.         import public function GetItemId( itemName : name ) : SItemUniqueId;
  220.        
  221.        
  222.         import public function GetItemsIds( itemName : name ) : array< SItemUniqueId >;
  223.        
  224.        
  225.         import final function GetItemsByTag( tag : name ) : array< SItemUniqueId >;
  226.        
  227.        
  228.         import final function GetItemsByCategory( category : name ) : array< SItemUniqueId >;
  229.        
  230.        
  231.         import final function GetSchematicIngredients(itemName : SItemUniqueId, out quantity : array<int>, out names : array<name>);
  232.        
  233.        
  234.         import final function GetSchematicRequiredCraftsmanType(craftName : SItemUniqueId) : name;
  235.        
  236.        
  237.         import final function GetSchematicRequiredCraftsmanLevel(craftName : SItemUniqueId) : name;
  238.    
  239.    
  240.     import final function GetNumOfStackedItems( itemUniqueId: SItemUniqueId ) : int;
  241.        
  242.         import final function InitInvFromTemplate( resource : CEntityTemplate );
  243.        
  244.        
  245.        
  246.        
  247.         import final function SplitItem( itemID : SItemUniqueId, quantity : int ) : SItemUniqueId;
  248.        
  249.        
  250.        
  251.         import final function SetItemStackable( itemID : SItemUniqueId, flag : bool );
  252.        
  253.        
  254.         import final function GetCategoryDefaultItem( category : name ) : name;
  255.        
  256.        
  257.        
  258.        
  259.        
  260.        
  261.         import final function GetItemLocalizedNameByName( itemName : CName ) : string;
  262.        
  263.        
  264.     import final function GetItemLocalizedDescriptionByName( itemName : CName ) : string;
  265.    
  266.        
  267.         import final function GetItemLocalizedNameByUniqueID( itemUniqueId : SItemUniqueId ) : string;
  268.        
  269.        
  270.     import final function GetItemLocalizedDescriptionByUniqueID( itemUniqueId : SItemUniqueId ) : string;
  271.    
  272.    
  273.     import final function GetItemIconPathByUniqueID( itemUniqueId : SItemUniqueId ) : string;
  274.    
  275.    
  276.     import final function GetItemIconPathByName( itemName : CName ) : string;
  277.    
  278.     import final function AddSlot( itemUniqueId : SItemUniqueId ) : bool;
  279.    
  280.         import final function GetSlotItemsLimit( itemUniqueId : SItemUniqueId ) : int;
  281.        
  282.     import private final function BalanceItemsWithPlayerLevel( playerLevel : int );
  283.    
  284.     public function ForceSpawnItemOnStart( itemId : SItemUniqueId ) : bool     
  285.         {
  286.                 return ItemHasTag(itemId, 'MutagenIngredient');
  287.         }
  288.        
  289.    
  290.     public final function GetItemArmorTotal(item : SItemUniqueId) : SAbilityAttributeValue
  291.     {
  292.                 var armor, armorBonus : SAbilityAttributeValue;
  293.                 var durMult : float;
  294.                
  295.                 armor = GetItemAttributeValue(item, theGame.params.ARMOR_VALUE_NAME);
  296.                 armorBonus = GetRepairObjectBonusValueForArmor(item);
  297.                 durMult = theGame.params.GetDurabilityMultiplier( GetItemDurabilityRatio(item), false);
  298.                
  299.                 return armor * durMult + armorBonus;
  300.     }
  301.    
  302.     public final function GetItemLevel(item : SItemUniqueId) : int
  303.     {
  304.                 var itemCategory : name;
  305.                 var itemAttributes : array<SAbilityAttributeValue>;
  306.                 var itemName : name;
  307.                 var isWitcherGear : bool;
  308.                 var isRelicGear : bool;
  309.                 var level, baseLevel : int;
  310.                
  311.                 itemCategory = GetItemCategory(item);
  312.                 itemName = GetItemName(item);
  313.                
  314.                 isWitcherGear = false;
  315.                 isRelicGear = false;
  316.                 if ( RoundMath(CalculateAttributeValue( GetItemAttributeValue(item, 'quality' ) )) == 5 ) isWitcherGear = true;
  317.                 if ( RoundMath(CalculateAttributeValue( GetItemAttributeValue(item, 'quality' ) )) == 4 ) isRelicGear = true;
  318.                
  319.                 switch(itemCategory)
  320.                 {
  321.                         case 'armor' :
  322.                         case 'boots' :
  323.                         case 'gloves' :
  324.                         case 'pants' :
  325.                                 itemAttributes.PushBack( GetItemAttributeValue(item, 'armor') );
  326.                                 break;
  327.                                
  328.                         case 'silversword' :
  329.                                 itemAttributes.PushBack( GetItemAttributeValue(item, 'SilverDamage') );
  330.                                 itemAttributes.PushBack( GetItemAttributeValue(item, 'BludgeoningDamage') );
  331.                                 itemAttributes.PushBack( GetItemAttributeValue(item, 'RendingDamage') );
  332.                                 itemAttributes.PushBack( GetItemAttributeValue(item, 'ElementalDamage') );
  333.                                 itemAttributes.PushBack( GetItemAttributeValue(item, 'FireDamage') );
  334.                                 itemAttributes.PushBack( GetItemAttributeValue(item, 'PiercingDamage') );
  335.                                 break;
  336.                                
  337.                         case 'steelsword' :
  338.                                 itemAttributes.PushBack( GetItemAttributeValue(item, 'SlashingDamage') );
  339.                                 itemAttributes.PushBack( GetItemAttributeValue(item, 'BludgeoningDamage') );
  340.                                 itemAttributes.PushBack( GetItemAttributeValue(item, 'RendingDamage') );
  341.                                 itemAttributes.PushBack( GetItemAttributeValue(item, 'ElementalDamage') );
  342.                                 itemAttributes.PushBack( GetItemAttributeValue(item, 'FireDamage') );
  343.                                 itemAttributes.PushBack( GetItemAttributeValue(item, 'SilverDamage') );
  344.                                 itemAttributes.PushBack( GetItemAttributeValue(item, 'PiercingDamage') );
  345.                                 break;
  346.                                
  347.                         case 'crossbow' :
  348.                                 itemAttributes.PushBack( GetItemAttributeValue(item, 'attack_power') );
  349.                                 break;
  350.                                  
  351.                         default :
  352.                                 break;
  353.                 }
  354.                
  355.                 level = theGame.params.GetItemLevel(itemCategory, itemAttributes, itemName, baseLevel);
  356.                
  357.                 if ( FactsQuerySum("NewGamePlus") > 0 )
  358.                 {
  359.                         if ( baseLevel > GetWitcherPlayer().GetMaxLevel() )
  360.                         {
  361.                                 level = baseLevel;
  362.                         }
  363.                 }
  364.                
  365.                 if ( isWitcherGear ) level = level - 2;
  366.                 if ( isRelicGear ) level = level - 1;
  367.                 if ( level < 1 ) level = 1;
  368.                 if ( ItemHasTag(item, 'OlgierdSabre') ) level = level - 3;
  369.                 if ( (isRelicGear || isWitcherGear) && ItemHasTag(item, 'EP1') ) level = level - 1;
  370.                
  371.                 if ( FactsQuerySum("NewGamePlus") > 0 )
  372.                 {
  373.                         if ( level > GetWitcherPlayer().GetMaxLevel() )
  374.                         {
  375.                                 level = GetWitcherPlayer().GetMaxLevel();
  376.                         }
  377.                 }
  378.                
  379.                 return level;
  380.     }
  381.    
  382.     public function GetItemLevelColorById( itemId : SItemUniqueId ) : string
  383.     {
  384.                 var color : string;
  385.                
  386.                 if (GetItemLevel(itemId) <= thePlayer.GetLevel())
  387.                 {
  388.                         color = "<font color = '#A09588'>";
  389.                 }
  390.                 else
  391.                 {
  392.                         color = "<font color = '#9F1919'>";
  393.                 }
  394.                
  395.                 return color;
  396.     }
  397.        
  398.         public function GetItemLevelColor( lvl_item : int ) : string
  399.         {
  400.                 var color : string;
  401.  
  402.                 if ( lvl_item > thePlayer.GetLevel() )
  403.                 {
  404.                         color = "<font color = '#9F1919'>";
  405.                 } else
  406.                 {
  407.                         color = "<font color = '#A09588'>";
  408.                 }
  409.                
  410.                 return color;
  411.         }      
  412.        
  413.     public final function AutoBalanaceItemsWithPlayerLevel()
  414.     {
  415.                 var playerLevel : int;
  416.  
  417.                 playerLevel = thePlayer.GetLevel();
  418.  
  419.                 if( playerLevel < 0 )
  420.                 {
  421.                         playerLevel = 0;
  422.                 }
  423.                
  424.                 BalanceItemsWithPlayerLevel( playerLevel );
  425.     }
  426.    
  427.     public function GetItemsByName(itemName : name) : array<SItemUniqueId>
  428.     {
  429.                 var ret : array<SItemUniqueId>;
  430.                 var i : int;
  431.    
  432.                 if(!IsNameValid(itemName))
  433.                         return ret;
  434.                        
  435.                 GetAllItems(ret);
  436.                
  437.                 for(i=ret.Size()-1; i>=0; i-=1)
  438.                 {
  439.                         if(GetItemName(ret[i]) != itemName)
  440.                         {
  441.                                 ret.EraseFast( i );
  442.                         }
  443.                 }
  444.                                
  445.                 return ret;
  446.     }
  447.    
  448.     public final function GetSingletonItems() : array<SItemUniqueId>
  449.     {
  450.                 return GetItemsByTag(theGame.params.TAG_ITEM_SINGLETON);
  451.         }
  452.        
  453.        
  454.         import final function GetItemQuantityByName( itemName : name, optional useAssociatedInventory : bool , optional ignoreTags : array< name > ) : int;
  455.        
  456.        
  457.         import final function GetItemQuantityByCategory( itemCategory : name, optional useAssociatedInventory : bool , optional ignoreTags : array< name > ) : int;
  458.  
  459.        
  460.         import final function GetItemQuantityByTag( itemTag : name, optional useAssociatedInventory : bool , optional ignoreTags : array< name > ) : int;
  461.  
  462.        
  463.         import final function GetAllItemsQuantity( optional useAssociatedInventory : bool , optional ignoreTags : array< name > ) : int;
  464.  
  465.        
  466.         public function IsEmpty(optional bSkipNoDropNoShow : bool) : bool
  467.         {
  468.                 var i : int;
  469.                 var itemIds : array<SItemUniqueId>;
  470.                
  471.                 if(bSkipNoDropNoShow)
  472.                 {
  473.                         GetAllItems( itemIds );
  474.                         for( i = itemIds.Size() - 1; i >= 0; i -= 1 )
  475.                         {
  476.                                 if( !ItemHasTag( itemIds[ i ],theGame.params.TAG_DONT_SHOW ) && !ItemHasTag( itemIds[ i ], 'NoDrop' ) )
  477.                                 {
  478.                                         return false;
  479.                                 }
  480.                                 else if ( ItemHasTag( itemIds[ i ], 'Lootable') )
  481.                                 {
  482.                                         return false;
  483.                                 }
  484.                         }
  485.                        
  486.                         return true;
  487.                 }
  488.  
  489.                 return GetItemCount() <= 0;
  490.         }
  491.                
  492.        
  493.         public function GetAllHeldAndMountedItemsCategories( out heldItems : array<name>, optional out mountedItems : array<name> )
  494.         {
  495.                 var allItems : array<SItemUniqueId>;
  496.                 var i : int;
  497.                
  498.                 GetAllItems(allItems);
  499.                 for(i=allItems.Size()-1; i >= 0; i-=1)
  500.                 {
  501.                         if ( IsItemHeld(allItems[i]) )
  502.                                 heldItems.PushBack(GetItemCategory(allItems[i]));
  503.                         else if ( IsItemMounted(allItems[i]) )
  504.                                 mountedItems.PushBack(GetItemCategory(allItems[i]));
  505.                 }
  506.         }
  507.        
  508.         public function GetAllHeldItemsNames( out heldItems : array<name> )
  509.         {
  510.                 var allItems : array<SItemUniqueId>;
  511.                 var i : int;
  512.                
  513.                 GetAllItems(allItems);
  514.                 for(i=allItems.Size()-1; i >= 0; i-=1)
  515.                 {
  516.                         if ( IsItemHeld(allItems[i]) )
  517.                                 heldItems.PushBack(GetItemName(allItems[i]));
  518.                 }
  519.         }
  520.        
  521.         public function HasMountedItemByTag(tag : name) : bool
  522.         {
  523.                 var i : int;
  524.                 var allItems : array<SItemUniqueId>;
  525.                
  526.                 if(!IsNameValid(tag))
  527.                         return false;
  528.                        
  529.                 allItems = GetItemsByTag(tag);
  530.                 for(i=0; i<allItems.Size(); i+=1)
  531.                         if(IsItemMounted(allItems[i]))
  532.                                 return true;
  533.                                
  534.                 return false;
  535.         }
  536.        
  537.         public function HasHeldOrMountedItemByTag(tag : name) : bool
  538.         {
  539.                 var i : int;
  540.                 var allItems : array<SItemUniqueId>;
  541.                
  542.                 if(!IsNameValid(tag))
  543.                         return false;
  544.                        
  545.                 allItems = GetItemsByTag(tag);
  546.                 for(i=0; i<allItems.Size(); i+=1)
  547.                         if( IsItemMounted(allItems[i]) || IsItemHeld(allItems[i]) )
  548.                                 return true;
  549.                                
  550.                 return false;
  551.         }
  552.        
  553.        
  554.         import final function GetItem( itemId : SItemUniqueId ) : SInventoryItem;
  555.        
  556.        
  557.         import final function GetItemName( itemId : SItemUniqueId ) : name;
  558.        
  559.        
  560.         import final function GetItemCategory( itemId : SItemUniqueId ) : name;
  561.        
  562.        
  563.         import final function GetItemClass( itemId : SItemUniqueId ) : EInventoryItemClass;
  564.        
  565.        
  566.         import final function GetItemTags( itemId : SItemUniqueId, out tags : array<name> ) : bool;
  567.  
  568.        
  569.         import final function GetCraftedItemName( itemId : SItemUniqueId ) : name;
  570.        
  571.        
  572.         import final function TotalItemStats( invItem : SInventoryItem ) : float;
  573.  
  574.         import final function GetItemPrice( itemId : SItemUniqueId ) : int;
  575.  
  576.        
  577.         import final function GetItemPriceModified( itemId : SItemUniqueId, optional playerSellingItem : Bool ) : int;
  578.  
  579.        
  580.         import final function GetInventoryItemPriceModified( invItem : SInventoryItem, optional playerSellingItem : Bool ) : int;
  581.  
  582.        
  583.         import final function GetItemPriceRepair( invItem : SInventoryItem, out costRepairPoint : int, out costRepairTotal : int );    
  584.        
  585.        
  586.         import final function GetItemPriceRemoveUpgrade( invItem : SInventoryItem ) : int;
  587.        
  588.        
  589.         import final function GetItemPriceDisassemble( invItem : SInventoryItem ) : int;
  590.        
  591.        
  592.         import final function GetItemPriceAddSlot( invItem : SInventoryItem ) : int;
  593.  
  594.        
  595.         import final function GetItemPriceCrafting( invItem : SInventoryItem ) : int;
  596.  
  597.        
  598.         import final function GetItemPriceEnchantItem( invItem : SInventoryItem ) : int;
  599.        
  600.        
  601.         import final function GetItemPriceRemoveEnchantment( invItem : SInventoryItem ) : int;
  602.        
  603.         import final function GetFundsModifier() : float;
  604.  
  605.        
  606.         import final function GetItemQuantity( itemId : SItemUniqueId ) : int;
  607.        
  608.        
  609.         import final function ItemHasTag( itemId : SItemUniqueId, tag : name ) : bool;
  610.  
  611.        
  612.         import final function AddItemTag( itemId : SItemUniqueId, tag : name ) : bool;
  613.  
  614.        
  615.         import final function RemoveItemTag( itemId : SItemUniqueId, tag : name ) : bool;
  616.        
  617.        
  618.         public final function ManageItemsTag( items : array<SItemUniqueId>, tag : name, add : bool )
  619.         {
  620.                 var i           : int;
  621.                
  622.                 if( add )
  623.                 {
  624.                         for( i = 0 ; i < items.Size() ; i += 1 )
  625.                         {
  626.                                 AddItemTag( items[ i ], tag );
  627.                         }
  628.                 }
  629.                 else
  630.                 {
  631.                         for( i = 0 ; i < items.Size() ; i += 1 )
  632.                         {
  633.                                 RemoveItemTag( items[ i ], tag );
  634.                         }
  635.                 }
  636.         }
  637.  
  638.        
  639.         import final function GetItemByItemEntity( itemEntity : CItemEntity ) : SItemUniqueId;  
  640.                
  641.        
  642.         public function ItemHasAbility(item : SItemUniqueId, abilityName : name) : bool
  643.         {
  644.                 var abilities : array<name>;
  645.                
  646.                 GetItemAbilities(item, abilities);
  647.                 return abilities.Contains(abilityName);
  648.         }
  649.        
  650.         import final function GetItemAttributeValue( itemId : SItemUniqueId, attributeName : name, optional abilityTags : array< name >, optional withoutTags : bool ) : SAbilityAttributeValue;
  651.        
  652.        
  653.         import final function GetItemBaseAttributes( itemId : SItemUniqueId, out attributes : array<name> );
  654.        
  655.        
  656.         import final function GetItemAttributes( itemId : SItemUniqueId, out attributes : array<name> );
  657.        
  658.        
  659.         import final function GetItemAbilities( itemId : SItemUniqueId, out abilities : array<name> );
  660.        
  661.        
  662.         import final function GetItemContainedAbilities( itemId : SItemUniqueId, out abilities : array<name> );
  663.        
  664.        
  665.         public function GetItemAbilitiesWithAttribute(id : SItemUniqueId, attributeName : name, attributeVal : float) : array<name>
  666.         {
  667.                 var i : int;
  668.                 var abs, ret : array<name>;
  669.                 var dm : CDefinitionsManagerAccessor;
  670.                 var val : float;
  671.                 var min, max : SAbilityAttributeValue;
  672.        
  673.                 GetItemAbilities(id, abs);
  674.                 dm = theGame.GetDefinitionsManager();
  675.                
  676.                 for(i=0; i<abs.Size(); i+=1)
  677.                 {
  678.                         dm.GetAbilityAttributeValue(abs[i], attributeName, min, max);
  679.                         val = CalculateAttributeValue(GetAttributeRandomizedValue(min, max));
  680.                        
  681.                         if(val == attributeVal)
  682.                                 ret.PushBack(abs[i]);
  683.                 }
  684.                
  685.                 return ret;
  686.         }
  687.         public function GetItemAbilitiesWithTag( itemId : SItemUniqueId, tag : name, out abilities : array<name> )
  688.         {
  689.                 var i : int;
  690.                 var dm : CDefinitionsManagerAccessor;
  691.                 var allAbilities : array<name>;
  692.                
  693.                 dm = theGame.GetDefinitionsManager();
  694.                 GetItemAbilities(itemId, allAbilities);
  695.                
  696.                 for(i=0; i<allAbilities.Size(); i+=1)
  697.                 {
  698.                         if(dm.AbilityHasTag(allAbilities[i], tag))
  699.                         {
  700.                                 abilities.PushBack(allAbilities[i]);
  701.                         }
  702.                 }
  703.         }
  704.        
  705.        
  706.        
  707.        
  708.         import private final function GiveItem( otherInventory : CInventoryComponent, itemId : SItemUniqueId, optional quantity : int ) : array<SItemUniqueId>;
  709.        
  710.         public final function GiveMoneyTo(otherInventory : CInventoryComponent, optional quantity : int, optional informGUI : bool )
  711.         {
  712.                 var moneyId : array<SItemUniqueId>;
  713.                
  714.                 moneyId = GetItemsByName('Crowns');
  715.                 GiveItemTo(otherInventory, moneyId[0], quantity, false, true, informGUI);
  716.         }
  717.        
  718.         public final function GiveItemTo( otherInventory : CInventoryComponent, itemId : SItemUniqueId, optional quantity : int, optional refreshNewFlag : bool, optional forceTransferNoDrops : bool, optional informGUI : bool ) : SItemUniqueId
  719.         {
  720.                 var arr : array<SItemUniqueId>;
  721.                 var itemName : name;
  722.                 var i : int;
  723.                 var uiData : SInventoryItemUIData;
  724.                 var isQuestItem : bool;
  725.                
  726.                
  727.                 if(quantity == 0)
  728.                         quantity = 1;
  729.                
  730.                 quantity = Clamp(quantity, 0, GetItemQuantity(itemId));        
  731.                 if(quantity == 0)
  732.                         return GetInvalidUniqueId();
  733.                        
  734.                 itemName = GetItemName(itemId);
  735.                
  736.                 if(!forceTransferNoDrops && ( ItemHasTag(itemId, 'NoDrop') && !ItemHasTag(itemId, 'Lootable') ))
  737.                 {
  738.                         LogItems("Cannot transfer item <<" + itemName + ">> as it has the NoDrop tag set!!!");
  739.                         return GetInvalidUniqueId();
  740.                 }
  741.                
  742.                
  743.                 if(IsItemSingletonItem(itemId))
  744.                 {
  745.                        
  746.                         if(otherInventory == thePlayer.inv && otherInventory.GetItemQuantityByName(itemName) > 0)
  747.                         {
  748.                                 LogAssert(false, "CInventoryComponent.GiveItemTo: cannot add singleton item as player already has this item!");
  749.                                 return GetInvalidUniqueId();
  750.                         }
  751.                        
  752.                         else
  753.                         {
  754.                                 arr = GiveItem(otherInventory, itemId, quantity);
  755.                         }                      
  756.                 }
  757.                 else
  758.                 {
  759.                        
  760.                         arr = GiveItem(otherInventory, itemId, quantity);
  761.                 }
  762.                
  763.                
  764.                 if(otherInventory == thePlayer.inv)
  765.                 {
  766.                         isQuestItem = this.IsItemQuest( itemId );
  767.                         theTelemetry.LogWithLabelAndValue(TE_INV_ITEM_PICKED, itemName, quantity);
  768.                        
  769.                         if ( !theGame.AreSavesLocked() && ( isQuestItem || this.GetItemQuality( itemId ) >= 4 ) )
  770.                         {
  771.                                 theGame.RequestAutoSave( "item gained", false );
  772.                         }
  773.                 }
  774.                
  775.                 if (refreshNewFlag)
  776.                 {
  777.                         for (i = 0; i < arr.Size(); i += 1)
  778.                         {
  779.                                 uiData = otherInventory.GetInventoryItemUIData( arr[i] );
  780.                                 uiData.isNew = true;
  781.                                 otherInventory.SetInventoryItemUIData( arr[i], uiData );
  782.                         }
  783.                 }
  784.                
  785.                 return arr[0];
  786.         }
  787.        
  788.         public final function GiveAllItemsTo(otherInventory : CInventoryComponent, optional forceTransferNoDrops : bool, optional informGUI : bool)
  789.         {
  790.                 var items : array<SItemUniqueId>;
  791.                
  792.                 GetAllItems(items);
  793.                 GiveItemsTo(otherInventory, items, forceTransferNoDrops, informGUI);
  794.         }
  795.        
  796.         public final function GiveItemsTo(otherInventory : CInventoryComponent, items : array<SItemUniqueId>, optional forceTransferNoDrops : bool, optional informGUI : bool) : array<SItemUniqueId>
  797.         {
  798.                 var i : int;
  799.                 var ret : array<SItemUniqueId>;
  800.                
  801.                 for( i = 0; i < items.Size(); i += 1 )
  802.                 {
  803.                         ret.PushBack(GiveItemTo(otherInventory, items[i], GetItemQuantity(items[i]), true, forceTransferNoDrops, informGUI));
  804.                 }
  805.                
  806.                 return ret;
  807.         }
  808.                
  809.        
  810.         import final function HasItem( item : name ) : bool;
  811.        
  812.        
  813.        
  814.         final function HasItemById(id : SItemUniqueId) : bool
  815.         {              
  816.                 var arr : array<SItemUniqueId>;
  817.                
  818.                 GetAllItems(arr);
  819.                 return arr.Contains(id);
  820.         }
  821.        
  822.         public function HasItemByTag(tag : name) : bool
  823.         {
  824.                 var quantity : int;
  825.                
  826.                 quantity = GetItemQuantityByTag( tag );
  827.                 return quantity > 0;
  828.         }
  829.  
  830.         public function HasItemByCategory(category : name) : bool
  831.         {
  832.                 var quantity : int;
  833.                
  834.                 quantity = GetItemQuantityByCategory( category );
  835.                 return quantity > 0;
  836.         }
  837.        
  838.        
  839.         public function HasInfiniteBolts() : bool
  840.         {
  841.                 var ids : array<SItemUniqueId>;
  842.                 var i : int;
  843.                
  844.                 ids = GetItemsByTag(theGame.params.TAG_INFINITE_AMMO);
  845.                 for(i=0; i<ids.Size(); i+=1)
  846.                 {
  847.                         if(IsItemBolt(ids[i]))
  848.                         {
  849.                                 return true;
  850.                         }
  851.                 }
  852.                
  853.                 return false;
  854.         }
  855.        
  856.        
  857.         public function HasGroundBolts() : bool
  858.         {
  859.                 var ids : array<SItemUniqueId>;
  860.                 var i : int;
  861.                
  862.                 ids = GetItemsByTag(theGame.params.TAG_GROUND_AMMO);
  863.                 for(i=0; i<ids.Size(); i+=1)
  864.                 {
  865.                         if(IsItemBolt(ids[i]))
  866.                         {
  867.                                 return true;
  868.                         }
  869.                 }
  870.                
  871.                 return false;
  872.         }
  873.        
  874.        
  875.         public function HasUnderwaterBolts() : bool
  876.         {
  877.                 var ids : array<SItemUniqueId>;
  878.                 var i : int;
  879.                
  880.                 ids = GetItemsByTag(theGame.params.TAG_UNDERWATER_AMMO);
  881.                 for(i=0; i<ids.Size(); i+=1)
  882.                 {
  883.                         if(IsItemBolt(ids[i]))
  884.                         {
  885.                                 return true;
  886.                         }
  887.                 }
  888.                
  889.                 return false;
  890.         }
  891.        
  892.        
  893.        
  894.         import private final function AddMultiItem( item : name, optional quantity : int, optional informGui : bool , optional markAsNew : bool , optional lootable : bool  ) : array<SItemUniqueId>;
  895.         import private final function AddSingleItem( item : name, optional informGui : bool , optional markAsNew : bool , optional lootable : bool   ) : SItemUniqueId;
  896.        
  897.        
  898.         public final function AddAnItem(item : name, optional quantity : int, optional dontInformGui : bool, optional dontMarkAsNew : bool, optional showAsRewardInUIHax : bool) : array<SItemUniqueId>
  899.         {
  900.                 var arr : array<SItemUniqueId>;
  901.                 var i : int;
  902.                 var isReadableItem : bool;
  903.                
  904.                
  905.                 if( theGame.GetDefinitionsManager().IsItemSingletonItem(item) && GetEntity() == thePlayer)                     
  906.                 {
  907.                         if(GetItemQuantityByName(item) > 0)
  908.                         {
  909.                                 arr = GetItemsIds(item);
  910.                         }
  911.                         else
  912.                         {
  913.                                 arr.PushBack(AddSingleItem(item, !dontInformGui, !dontMarkAsNew));                             
  914.                         }
  915.                        
  916.                         quantity = 1;                  
  917.                 }
  918.                 else
  919.                 {
  920.                         if(quantity < 2 )
  921.                         {
  922.                                 arr.PushBack(AddSingleItem(item, !dontInformGui, !dontMarkAsNew));
  923.                         }
  924.                         else   
  925.                         {
  926.                                 arr = AddMultiItem(item, quantity, !dontInformGui, !dontMarkAsNew);
  927.                         }
  928.                 }
  929.                
  930.                
  931.                 if(this == thePlayer.GetInventory())
  932.                 {
  933.                         if(ItemHasTag(arr[0],'ReadableItem'))
  934.                                 UpdateInitialReadState(arr[0]);
  935.                        
  936.                        
  937.                         if(showAsRewardInUIHax || ItemHasTag(arr[0],'GwintCard'))
  938.                                 thePlayer.DisplayItemRewardNotification(GetItemName(arr[0]), quantity );
  939.                 }
  940.                
  941.                 return arr;
  942.         }
  943.                
  944.        
  945.         import final function RemoveItem( itemId : SItemUniqueId, optional quantity : int ) : bool;
  946.        
  947.        
  948.         private final function InternalRemoveItems(ids : array<SItemUniqueId>, quantity : int)
  949.         {
  950.                 var i, currQuantityToTake : int;
  951.        
  952.                
  953.                 for(i=0; i<ids.Size(); i+=1 )
  954.                 {                      
  955.                        
  956.                         currQuantityToTake = Min(quantity, GetItemQuantity(ids[i]) );
  957.                        
  958.                        
  959.                         if( GetEntity() == thePlayer )
  960.                         {
  961.                                 GetWitcherPlayer().RemoveGwentCard( GetItemName(ids[i]) , currQuantityToTake);
  962.                         }                      
  963.                        
  964.                        
  965.                         RemoveItem(ids[i], currQuantityToTake);
  966.                        
  967.                        
  968.                         quantity -= currQuantityToTake;
  969.                        
  970.                        
  971.                         if ( quantity == 0 )
  972.                         {
  973.                                 return;
  974.                         }
  975.                        
  976.                        
  977.                         LogAssert(quantity>0, "CInventoryComponent.InternalRemoveItems(" + GetItemName(ids[i]) + "): somehow took too many items! Should be " + (-quantity) + " less... Investigate!");
  978.                 }
  979.         }
  980.        
  981.        
  982.        
  983.         public function RemoveItemByName(itemName : name, optional quantity : int) : bool
  984.         {
  985.                 var totalItemCount : int;
  986.                 var ids : array<SItemUniqueId>;
  987.        
  988.                
  989.                 totalItemCount = GetItemQuantityByName(itemName);
  990.                 if(totalItemCount < quantity || quantity == 0)
  991.                 {
  992.                         return false;
  993.                 }
  994.                
  995.                 if(quantity == 0)
  996.                 {
  997.                         quantity = 1;
  998.                 }
  999.                 else if(quantity < 0)
  1000.                 {
  1001.                         quantity = totalItemCount;
  1002.                 }
  1003.                
  1004.                 ids = GetItemsIds(itemName);
  1005.                
  1006.                 if(GetEntity() == thePlayer && thePlayer.GetSelectedItemId() == ids[0] )
  1007.                 {
  1008.                         thePlayer.ClearSelectedItemId();
  1009.                 }
  1010.                
  1011.                 InternalRemoveItems(ids, quantity);
  1012.                
  1013.                 return true;
  1014.         }
  1015.        
  1016.        
  1017.        
  1018.         public function RemoveItemByCategory(itemCategory : name, optional quantity : int) : bool
  1019.         {
  1020.                 var totalItemCount : int;
  1021.                 var ids : array<SItemUniqueId>;
  1022.                 var selectedItemId : SItemUniqueId;
  1023.                 var i : int;
  1024.        
  1025.                
  1026.                 totalItemCount = GetItemQuantityByCategory(itemCategory);
  1027.                 if(totalItemCount < quantity)
  1028.                 {
  1029.                         return false;
  1030.                 }
  1031.                
  1032.                 if(quantity == 0)
  1033.                 {
  1034.                         quantity = 1;
  1035.                 }
  1036.                 else if(quantity < 0)
  1037.                 {
  1038.                         quantity = totalItemCount;
  1039.                 }
  1040.                
  1041.                 ids = GetItemsByCategory(itemCategory);
  1042.                
  1043.                 if(GetEntity() == thePlayer)
  1044.                 {
  1045.                         selectedItemId = thePlayer.GetSelectedItemId();
  1046.                         for(i=0; i<ids.Size(); i+=1)
  1047.                         {
  1048.                                 if(selectedItemId == ids[i] )
  1049.                                 {
  1050.                                         thePlayer.ClearSelectedItemId();
  1051.                                         break;
  1052.                                 }
  1053.                         }
  1054.                 }
  1055.                        
  1056.                 InternalRemoveItems(ids, quantity);
  1057.                
  1058.                 return true;
  1059.         }
  1060.        
  1061.        
  1062.        
  1063.         public function RemoveItemByTag(itemTag : name, optional quantity : int) : bool
  1064.         {
  1065.                 var totalItemCount : int;
  1066.                 var ids : array<SItemUniqueId>;
  1067.                 var i : int;
  1068.                 var selectedItemId : SItemUniqueId;
  1069.        
  1070.                
  1071.                 totalItemCount = GetItemQuantityByTag(itemTag);
  1072.                 if(totalItemCount < quantity)
  1073.                 {
  1074.                         return false;
  1075.                 }
  1076.                
  1077.                 if(quantity == 0)
  1078.                 {
  1079.                         quantity = 1;
  1080.                 }
  1081.                 else if(quantity < 0)
  1082.                 {
  1083.                         quantity = totalItemCount;
  1084.                 }
  1085.                
  1086.                 ids = GetItemsByTag(itemTag);
  1087.                
  1088.                 if(GetEntity() == thePlayer)
  1089.                 {
  1090.                         selectedItemId = thePlayer.GetSelectedItemId();
  1091.                         for(i=0; i<ids.Size(); i+=1)
  1092.                         {                              
  1093.                                 if(selectedItemId == ids[i] )
  1094.                                 {
  1095.                                         thePlayer.ClearSelectedItemId();
  1096.                                         break;
  1097.                                 }
  1098.                         }
  1099.                 }
  1100.                
  1101.                 InternalRemoveItems(ids, quantity);
  1102.                
  1103.                 return true;
  1104.         }
  1105.        
  1106.        
  1107.         import final function RemoveAllItems();
  1108.        
  1109.        
  1110.         import final function GetItemEntityUnsafe( itemId : SItemUniqueId ) : CItemEntity;
  1111.        
  1112.        
  1113.         import final function GetDeploymentItemEntity( itemId : SItemUniqueId, optional position : Vector, optional rotation : EulerAngles, optional allocateIdTag : bool ) : CEntity;
  1114.        
  1115.        
  1116.         import final function MountItem( itemId : SItemUniqueId, optional toHand : bool, optional force : bool ) : bool;
  1117.        
  1118.        
  1119.         import final function UnmountItem( itemId : SItemUniqueId, optional destroyEntity : bool ) : bool;
  1120.        
  1121.        
  1122.        
  1123.         import final function IsItemMounted(  itemId : SItemUniqueId ) : bool; 
  1124.        
  1125.        
  1126.        
  1127.         import final function IsItemHeld(  itemId : SItemUniqueId ) : bool;    
  1128.        
  1129.        
  1130.         import final function DropItem( itemId : SItemUniqueId, optional removeFromInv  : bool );
  1131.        
  1132.        
  1133.         import final function GetItemHoldSlot( itemId : SItemUniqueId ) : name;
  1134.        
  1135.        
  1136.         import final function PlayItemEffect( itemId : SItemUniqueId, effectName : name );
  1137.         import final function StopItemEffect( itemId : SItemUniqueId, effectName : name );
  1138.        
  1139.        
  1140.         import final function ThrowAwayItem( itemId : SItemUniqueId, optional quantity : int ) : bool;
  1141.        
  1142.        
  1143.         import final function ThrowAwayAllItems() : CEntity;
  1144.        
  1145.        
  1146.         import final function ThrowAwayItemsFiltered( excludedTags : array< name > ) : CEntity;
  1147.  
  1148.        
  1149.         import final function ThrowAwayLootableItems( optional skipNoDropNoShow : bool ) : CEntity;
  1150.        
  1151.        
  1152.         import final function GetItemRecyclingParts( itemId : SItemUniqueId ) : array<SItemParts>;
  1153.        
  1154.         import final function GetItemWeight( id : SItemUniqueId ) : float;
  1155.  
  1156.        
  1157.         public final function HasQuestItem() : bool
  1158.         {
  1159.                 var allItems            : array< SItemUniqueId >;
  1160.                 var i                           : int;
  1161.                
  1162.                 allItems = GetItemsByTag('Quest');
  1163.                 for ( i=0; i<allItems.Size(); i+=1 )
  1164.                 {
  1165.                         if(!ItemHasTag(allItems[i], theGame.params.TAG_DONT_SHOW))
  1166.                         {
  1167.                                 return true;
  1168.                         }
  1169.                 }
  1170.                
  1171.                 return false;
  1172.         }
  1173.        
  1174.        
  1175.        
  1176.        
  1177.        
  1178.        
  1179.         import final function HasItemDurability( itemId : SItemUniqueId ) : bool;
  1180.         import final function GetItemDurability( itemId : SItemUniqueId ) : float;
  1181.         import private final function SetItemDurability( itemId : SItemUniqueId, durability : float );
  1182.         import final function GetItemInitialDurability( itemId : SItemUniqueId ) : float;
  1183.         import final function GetItemMaxDurability( itemId : SItemUniqueId ) : float;
  1184.         import final function GetItemGridSize( itemId : SItemUniqueId ) : int;
  1185.                
  1186.                
  1187.         import final function NotifyItemLooted( item : SItemUniqueId );
  1188.         import final function ResetContainerData();
  1189.                
  1190.         public function SetItemDurabilityScript( itemId : SItemUniqueId, durability : float )
  1191.         {
  1192.                 var oldDur : float;
  1193.        
  1194.                 oldDur = GetItemDurability(itemId);
  1195.                
  1196.                 if(oldDur == durability)
  1197.                         return;
  1198.                        
  1199.                 if(durability < oldDur)
  1200.                 {
  1201.                         if ( ItemHasAbility( itemId, 'MA_Indestructible' ) )
  1202.                         {
  1203.                                 return;
  1204.                         }
  1205.  
  1206.                         if(GetEntity() == thePlayer && ShouldProcessTutorial('TutorialDurability'))
  1207.                         {
  1208.                                 if ( durability <= theGame.params.ITEM_DAMAGED_DURABILITY && oldDur > theGame.params.ITEM_DAMAGED_DURABILITY )
  1209.                                 {
  1210.                                         FactsAdd( "tut_item_damaged", 1 );
  1211.                                 }
  1212.                         }
  1213.                 }
  1214.                        
  1215.                 SetItemDurability( itemId, durability );               
  1216.         }
  1217.        
  1218.        
  1219.         public function ReduceItemDurability(itemId : SItemUniqueId, optional forced : bool) : bool
  1220.         {
  1221.                 var dur, value, durabilityDiff, itemToughness, indestructible : float;
  1222.                 var chance : int;
  1223.                 //LZ_SLOTS_BEGIN
  1224.                 var min, max : SAbilityAttributeValue;
  1225.                 //LZ_SLOTS_END
  1226.                
  1227.                 if(!IsIdValid(itemId) || !HasItemDurability(itemId) || ItemHasAbility(itemId, 'MA_Indestructible'))
  1228.                 {
  1229.                         return false;
  1230.                 }
  1231.                
  1232.                
  1233.                 if(IsItemWeapon(itemId))
  1234.                 {      
  1235.                         chance = theGame.params.DURABILITY_WEAPON_LOSE_CHANCE;
  1236.                         value = theGame.params.GetWeaponDurabilityLoseValue();
  1237.                 }
  1238.                 else if(IsItemAnyArmor(itemId))
  1239.                 {
  1240.                         chance = theGame.params.DURABILITY_ARMOR_LOSE_CHANCE;                  
  1241.                         value = theGame.params.DURABILITY_ARMOR_LOSE_VALUE;
  1242.                 }
  1243.                
  1244.                 dur = GetItemDurability(itemId);
  1245.                
  1246.                 if ( dur == 0 )
  1247.                 {
  1248.                         return false;
  1249.                 }
  1250.  
  1251.                
  1252.                 if ( forced || RandRange( 100 ) < chance )
  1253.                 {
  1254.                         itemToughness = CalculateAttributeValue( GetItemAttributeValue( itemId, 'toughness' ) );
  1255.                         indestructible = CalculateAttributeValue( GetItemAttributeValue( itemId, 'indestructible' ) );
  1256.  
  1257.                         value = value * ( 1 - indestructible );
  1258.                        
  1259.                         //LZ_SLOTS_BEGIN
  1260.                         if( GetWitcherPlayer().IsMutationActive( EPMT_Mutation17 ) ){
  1261.                                 theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation17', 'equip_degrade_factor', min, max );
  1262.                                 value *= min.valueMultiplicative;}
  1263.                         //LZ_SLOTS_END
  1264.  
  1265.                         if ( itemToughness > 0.0f && itemToughness <= 1.0f )
  1266.                         {
  1267.                                 durabilityDiff = ( dur - value ) * itemToughness;
  1268.                                
  1269.                                 SetItemDurabilityScript( itemId, MaxF(durabilityDiff, 0 ) );
  1270.                         }
  1271.                         else
  1272.                         {
  1273.                                 SetItemDurabilityScript( itemId, MaxF( dur - value, 0 ) );
  1274.                         }
  1275.                 }
  1276.  
  1277.                 return true;
  1278.         }
  1279.  
  1280.         public function GetItemDurabilityRatio(itemId : SItemUniqueId) : float
  1281.         {      
  1282.                 if ( !IsIdValid( itemId ) || !HasItemDurability( itemId ) )
  1283.                         return -1;
  1284.                        
  1285.                 return GetItemDurability(itemId) / GetItemMaxDurability(itemId);
  1286.         }
  1287.        
  1288.        
  1289.        
  1290.        
  1291.        
  1292.        
  1293.         public function GetItemResistStatWithDurabilityModifiers(itemId : SItemUniqueId, stat : ECharacterDefenseStats, out points : SAbilityAttributeValue, out percents : SAbilityAttributeValue)
  1294.         {
  1295.                 var mult : float;
  1296.                 var null : SAbilityAttributeValue;
  1297.                
  1298.                 points = null;
  1299.                 percents = null;
  1300.                 if(!IsItemAnyArmor(itemId))
  1301.                         return;
  1302.        
  1303.                 mult = theGame.params.GetDurabilityMultiplier(GetItemDurabilityRatio(itemId), false);
  1304.                
  1305.                 points = GetItemAttributeValue(itemId, ResistStatEnumToName(stat, true));
  1306.                 percents = GetItemAttributeValue(itemId, ResistStatEnumToName(stat, false));           
  1307.                
  1308.                 points = points * mult;
  1309.                 percents = percents * mult;
  1310.         }
  1311.        
  1312.        
  1313.         public function GetItemResistanceTypes(id : SItemUniqueId) : array<ECharacterDefenseStats>
  1314.         {
  1315.                 var ret : array<ECharacterDefenseStats>;
  1316.                 var i : int;
  1317.                 var stat : ECharacterDefenseStats;
  1318.                 var atts : array<name>;
  1319.                 var tmpBool : bool;
  1320.        
  1321.                 if(!IsIdValid(id))
  1322.                         return ret;
  1323.                        
  1324.                 GetItemAttributes(id, atts);
  1325.                 for(i=0; i<atts.Size(); i+=1)
  1326.                 {
  1327.                         stat = ResistStatNameToEnum(atts[i], tmpBool);
  1328.                         if(stat != CDS_None && !ret.Contains(stat))
  1329.                                 ret.PushBack(stat);
  1330.                 }
  1331.                
  1332.                 return ret;
  1333.         }
  1334.        
  1335.         import final function GetItemModifierFloat( itemId : SItemUniqueId, modName : name, optional defValue : float ) : float;
  1336.         import final function SetItemModifierFloat( itemId : SItemUniqueId, modName : name, val : float);
  1337.         import final function GetItemModifierInt  ( itemId : SItemUniqueId, modName : name, optional defValue : int ) : int;   
  1338.         import final function SetItemModifierInt  ( itemId : SItemUniqueId, modName : name, val : int );
  1339.        
  1340.        
  1341.         import final function ActivateQuestBonus();
  1342.  
  1343.        
  1344.         import final function GetItemSetName( itemId : SItemUniqueId ) : name;
  1345.        
  1346.        
  1347.         import final function AddItemCraftedAbility( itemId : SItemUniqueId, abilityName : name, optional allowDuplicate : bool );
  1348.        
  1349.        
  1350.         import final function RemoveItemCraftedAbility( itemId : SItemUniqueId, abilityName : name );
  1351.        
  1352.        
  1353.         import final function AddItemBaseAbility(item : SItemUniqueId, abilityName : name);
  1354.        
  1355.        
  1356.         import final function RemoveItemBaseAbility(item : SItemUniqueId, abilityName : name);
  1357.                
  1358.        
  1359.         import final function DespawnItem( itemId : SItemUniqueId );
  1360.        
  1361.        
  1362.        
  1363.        
  1364.        
  1365.        
  1366.         import final function GetInventoryItemUIData( item : SItemUniqueId ) : SInventoryItemUIData;
  1367.        
  1368.        
  1369.         import final function SetInventoryItemUIData( item : SItemUniqueId, data : SInventoryItemUIData );
  1370.        
  1371.         import final function SortInventoryUIData();
  1372.        
  1373.        
  1374.        
  1375.        
  1376.        
  1377.        
  1378.         import final function PrintInfo();
  1379.  
  1380.        
  1381.        
  1382.        
  1383.  
  1384.        
  1385.         import final function EnableLoot( enable : bool );
  1386.  
  1387.        
  1388.         import final function UpdateLoot();
  1389.        
  1390.        
  1391.         import final function AddItemsFromLootDefinition( lootDefinitionName : name );
  1392.                
  1393.        
  1394.         import final function IsLootRenewable() : bool;
  1395.        
  1396.        
  1397.         import final function IsReadyToRenew() : bool;
  1398.        
  1399.        
  1400.        
  1401.        
  1402.        
  1403.        
  1404.         function Created()
  1405.         {              
  1406.                 LoadBooksDefinitions();
  1407.         }
  1408.        
  1409.         function ClearGwintCards()
  1410.         {
  1411.                 var attr : SAbilityAttributeValue;
  1412.                 var allItems : array<SItemUniqueId>;
  1413.                 var card : array<SItemUniqueId>;
  1414.                 var iHave, shopHave, cardLimit, delta : int;
  1415.                 var curItem : SItemUniqueId;
  1416.                 var i : int;
  1417.                
  1418.                 allItems = GetItemsByCategory('gwint');
  1419.                 for(i=allItems.Size()-1; i >= 0; i-=1)
  1420.                 {      
  1421.                         curItem = allItems[i];
  1422.                        
  1423.                         attr = GetItemAttributeValue( curItem, 'max_count');
  1424.                         card = thePlayer.GetInventory().GetItemsByName( GetItemName( curItem ) );
  1425.                         iHave = thePlayer.GetInventory().GetItemQuantity( card[0] );
  1426.                         cardLimit = RoundF(attr.valueBase);
  1427.                         shopHave = GetItemQuantity( curItem );
  1428.                        
  1429.                         if (iHave > 0 && shopHave > 0)
  1430.                         {
  1431.                                 delta = shopHave - (cardLimit - iHave);
  1432.                                
  1433.                                 if ( delta > 0 )
  1434.                                 {
  1435.                                         RemoveItem( curItem, delta );
  1436.                                 }
  1437.                         }
  1438.                 }
  1439.         }
  1440.        
  1441.         function ClearTHmaps()
  1442.         {
  1443.                 var attr : SAbilityAttributeValue;
  1444.                 var allItems : array<SItemUniqueId>;
  1445.                 var map : array<SItemUniqueId>;
  1446.                 var i : int;
  1447.                 var thCompleted : bool;
  1448.                 var iHave, shopHave : int;
  1449.                
  1450.                 allItems = GetItemsByTag('ThMap');
  1451.                 for(i=allItems.Size()-1; i >= 0; i-=1)
  1452.                 {      
  1453.                         attr = GetItemAttributeValue( allItems[i], 'max_count');
  1454.                         map = thePlayer.GetInventory().GetItemsByName( GetItemName( allItems[i] ) );
  1455.                         thCompleted = FactsDoesExist(GetItemName(allItems[i]));
  1456.                         iHave = thePlayer.GetInventory().GetItemQuantity( map[0] );
  1457.                         shopHave = RoundF(attr.valueBase);
  1458.                        
  1459.                         if ( iHave >= shopHave || thCompleted )
  1460.                         {
  1461.                                 RemoveItem( allItems[i], GetItemQuantity(  allItems[i] ) );
  1462.                         }
  1463.                 }
  1464.         }
  1465.        
  1466.        
  1467.         public final function ClearKnownRecipes()
  1468.         {
  1469.                 var witcher : W3PlayerWitcher;
  1470.                 var recipes, craftRecipes : array<name>;
  1471.                 var i : int;
  1472.                 var itemName : name;
  1473.                 var allItems : array<SItemUniqueId>;
  1474.                
  1475.                 witcher = GetWitcherPlayer();
  1476.                 if(!witcher)
  1477.                         return;
  1478.                
  1479.                
  1480.                 recipes = witcher.GetAlchemyRecipes();
  1481.                 craftRecipes = witcher.GetCraftingSchematicsNames();
  1482.                 ArrayOfNamesAppend(recipes, craftRecipes);
  1483.                
  1484.                
  1485.                 GetAllItems(allItems);
  1486.                
  1487.                
  1488.                 for(i=allItems.Size()-1; i>=0; i-=1)
  1489.                 {
  1490.                         itemName = GetItemName(allItems[i]);
  1491.                         if(recipes.Contains(itemName))
  1492.                                 RemoveItem(allItems[i], GetItemQuantity(allItems[i]));
  1493.                 }
  1494.         }
  1495.  
  1496.        
  1497.        
  1498.        
  1499.  
  1500.         function LoadBooksDefinitions() : void
  1501.         {
  1502.                 var readableArray : array<SItemUniqueId>;
  1503.                 var i : int;
  1504.                
  1505.                 readableArray = GetItemsByTag('ReadableItem');
  1506.                
  1507.                 for( i = 0; i < readableArray.Size(); i += 1 )
  1508.                 {
  1509.                         if( IsBookRead(readableArray[i]))
  1510.                         {
  1511.                                 continue;
  1512.                         }
  1513.                         UpdateInitialReadState(readableArray[i]);
  1514.                 }
  1515.         }
  1516.        
  1517.         function UpdateInitialReadState( item : SItemUniqueId )
  1518.         {
  1519.                 var abilitiesArray : array<name>;
  1520.                 var i : int;
  1521.                 GetItemAbilities(item,abilitiesArray);
  1522.                        
  1523.                 for( i = 0; i < abilitiesArray.Size(); i += 1 )
  1524.                 {
  1525.                         if( abilitiesArray[i] == 'WasRead' )
  1526.                         {
  1527.                                 ReadBook(item);
  1528.                                 break;
  1529.                         }
  1530.                 }
  1531.         }
  1532.        
  1533.         function IsBookRead( item : SItemUniqueId ) : bool
  1534.         {
  1535.                 var bookName : name;
  1536.                 var bResult : bool;
  1537.                
  1538.                 bookName = GetItemName( item );
  1539.                
  1540.                 bResult = IsBookReadByName( bookName );
  1541.                 return bResult;
  1542.         }
  1543.        
  1544.         function IsBookReadByName( bookName : name ) : bool
  1545.         {
  1546.                 var bookFactName : string;
  1547.                
  1548.                 bookFactName = GetBookReadFactName( bookName );
  1549.                 if( FactsDoesExist(bookFactName) )
  1550.                 {
  1551.                         return FactsQuerySum( bookFactName );
  1552.                 }
  1553.                
  1554.                 return false;
  1555.         }
  1556.  
  1557.         function ReadBook( item : SItemUniqueId, optional noNotification : bool )
  1558.         {
  1559.                
  1560.                 var bookName : name;
  1561.                 var abilitiesArray : array<name>;
  1562.                 var i : int;
  1563.                 var commonMapManager : CCommonMapManager = theGame.GetCommonMapManager();              
  1564.                
  1565.                 bookName = GetItemName( item );
  1566.                
  1567.                 if ( !IsBookRead ( item ) && ItemHasTag ( item, 'FastTravel' ))
  1568.                 {
  1569.                         GetItemAbilities(item, abilitiesArray);
  1570.                        
  1571.                         for ( i = 0; i < abilitiesArray.Size(); i+=1 )
  1572.                         {
  1573.                                 commonMapManager.SetEntityMapPinDiscoveredScript(true, abilitiesArray[i], true );
  1574.                         }
  1575.                 }
  1576.                 ReadBookByNameId( bookName, item, false, noNotification );
  1577.                
  1578.                
  1579.                
  1580.                
  1581.                 if(ItemHasTag(item, 'PerkBook'))
  1582.                 {
  1583.                        
  1584.                 }      
  1585.         }
  1586.        
  1587.         public function GetBookText(item : SItemUniqueId) : string
  1588.         {
  1589.                 if ( GetItemName( item ) != 'Gwent Almanac' )
  1590.                 {
  1591.                         return ReplaceTagsToIcons(GetLocStringByKeyExt(GetItemLocalizedNameByUniqueID(item)+"_text"));
  1592.                 }
  1593.                 else
  1594.                 {
  1595.                         return GetGwentAlmanacContents();
  1596.                 }
  1597.         }
  1598.        
  1599.         public function GetBookTextByName( bookName : name ) : string
  1600.         {
  1601.                 if( bookName != 'Gwent Almanac' )
  1602.                 {
  1603.                         return ReplaceTagsToIcons( GetLocStringByKeyExt( GetItemLocalizedNameByName( bookName ) + "_text" ) );
  1604.                 }
  1605.                 else
  1606.                 {
  1607.                         return GetGwentAlmanacContents();
  1608.                 }
  1609.         }
  1610.        
  1611.         function ReadSchematicsAndRecipes( item : SItemUniqueId )
  1612.         {
  1613.                 var itemCategory : name;
  1614.                 var itemName : name;
  1615.                 var player : W3PlayerWitcher;
  1616.                
  1617.                 ReadBook( item );
  1618.                
  1619.                 player = GetWitcherPlayer();
  1620.                 if ( !player )
  1621.                 {
  1622.                         return;
  1623.                 }
  1624.  
  1625.                 itemName = GetItemName( item );
  1626.                 itemCategory = GetItemCategory( item );
  1627.                 if ( itemCategory == 'alchemy_recipe' )
  1628.                 {
  1629.                         if ( player.CanLearnAlchemyRecipe( itemName ) )
  1630.                         {
  1631.                                 player.AddAlchemyRecipe( itemName );
  1632.                                 player.GetInventory().AddItemTag(item, 'NoShow');
  1633.                                
  1634.                         }
  1635.                 }
  1636.                 else if ( itemCategory == 'crafting_schematic' )
  1637.                 {
  1638.                         player.AddCraftingSchematic( itemName );
  1639.                         player.GetInventory().AddItemTag(item, 'NoShow');
  1640.                        
  1641.                 }
  1642.         }
  1643.        
  1644.         function ReadBookByName( bookName : name , unread : bool, optional noNotification : bool )
  1645.         {
  1646.                 var defMgr               : CDefinitionsManagerAccessor;
  1647.                 var bookFactName : string;
  1648.                
  1649.                 if( IsBookReadByName( bookName ) != unread )
  1650.                 {
  1651.                         return;
  1652.                 }
  1653.                
  1654.                 bookFactName = "BookReadState_"+bookName;
  1655.                 bookFactName = StrReplace(bookFactName," ","_");
  1656.                
  1657.                 if( unread )
  1658.                 {
  1659.                         FactsSubstract( bookFactName, 1 );
  1660.                 }
  1661.                 else
  1662.                 {
  1663.                         FactsAdd( bookFactName, 1 );
  1664.                        
  1665.                        
  1666.                         defMgr = theGame.GetDefinitionsManager();
  1667.                         if(!IsAlchemyRecipe(bookName) && !IsCraftingSchematic(bookName) && !defMgr.ItemHasTag( bookName, 'Painting' ) )
  1668.                         {
  1669.                                 theGame.GetGamerProfile().IncStat(ES_ReadBooks);
  1670.                                
  1671.                                 if( !noNotification )
  1672.                                 {
  1673.                                         theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt( "notification_book_moved" ), 0, false );
  1674.                                 }
  1675.                         }
  1676.                        
  1677.                        
  1678.                         if ( AddBestiaryFromBook(bookName) )
  1679.                                 return;
  1680.                        
  1681.                                
  1682.                        
  1683.                 }
  1684.         }
  1685.        
  1686.         function ReadBookByNameId( bookName : name, itemId:SItemUniqueId, unread : bool, optional noNotification : bool )
  1687.         {
  1688.                 var bookFactName : string;
  1689.                
  1690.                 if( IsBookReadByName( bookName ) != unread )
  1691.                 {
  1692.                         return;
  1693.                 }
  1694.                
  1695.                 bookFactName = "BookReadState_"+bookName;
  1696.                 bookFactName = StrReplace(bookFactName," ","_");
  1697.                
  1698.                 if( unread )
  1699.                 {
  1700.                         FactsSubstract( bookFactName, 1 );
  1701.                 }
  1702.                 else
  1703.                 {
  1704.                         FactsAdd( bookFactName, 1 );
  1705.                        
  1706.                        
  1707.                         if( !IsAlchemyRecipe( bookName ) && !IsCraftingSchematic( bookName ) )
  1708.                         {
  1709.                                 theGame.GetGamerProfile().IncStat(ES_ReadBooks);
  1710.                                
  1711.                                 if( !noNotification )
  1712.                                 {                                      
  1713.                                        
  1714.                                         GetWitcherPlayer().AddReadBook( bookName );
  1715.                                 }
  1716.                         }
  1717.                        
  1718.                        
  1719.                         if ( AddBestiaryFromBook(bookName) )
  1720.                                 return;
  1721.                         else
  1722.                                 ReadSchematicsAndRecipes( itemId );
  1723.                 }
  1724.         }
  1725.        
  1726.        
  1727.         private function AddBestiaryFromBook( bookName : name ) : bool
  1728.         {
  1729.                 var i, j, r, len : int;
  1730.                 var manager : CWitcherJournalManager;
  1731.                 var resource : array<CJournalResource>;
  1732.                 var entryBase : CJournalBase;
  1733.                 var childGroups : array<CJournalBase>;
  1734.                 var childEntries : array<CJournalBase>;
  1735.                 var descriptionGroup : CJournalCreatureDescriptionGroup;
  1736.                 var descriptionEntry : CJournalCreatureDescriptionEntry;
  1737.        
  1738.                 manager = theGame.GetJournalManager();
  1739.                
  1740.                 switch ( bookName )
  1741.                 {
  1742.                         case 'Beasts vol 1':
  1743.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryWolf" ) );
  1744.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryDog" ) );
  1745.                                 break;
  1746.                         case 'Beasts vol 2':
  1747.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryBear" ) );
  1748.                                 break;
  1749.                         case 'Cursed Monsters vol 1':
  1750.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryWerewolf" ) );
  1751.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryLycanthrope" ) );
  1752.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 24');
  1753.                                 break;
  1754.                         case 'Cursed Monsters vol 2':
  1755.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryWerebear" ) );
  1756.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryMiscreant" ) );
  1757.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 11');
  1758.                                 break;
  1759.                         case 'Draconides vol 1':
  1760.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryCockatrice" ) );
  1761.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryBasilisk" ) );
  1762.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 3');
  1763.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 23');
  1764.                                 break;
  1765.                         case 'Draconides vol 2':
  1766.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryWyvern" ) );
  1767.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryForktail" ) );
  1768.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 10');
  1769.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 17');
  1770.                                 break;
  1771.                         case 'Hybrid Monsters vol 1':
  1772.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryHarpy" ) );
  1773.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryErynia" ) );
  1774.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiarySiren" ) );
  1775.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiarySuccubus" ) );
  1776.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 14');
  1777.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 21');
  1778.                                 break;
  1779.                         case 'Hybrid Monsters vol 2':
  1780.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryGriffin" ) );
  1781.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 4');
  1782.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 27');
  1783.                                 break;
  1784.                         case 'Insectoids vol 1':
  1785.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryEndriagaWorker" ) );
  1786.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryEndriagaTruten" ) );
  1787.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryEndriaga" ) );
  1788.                                 break;
  1789.                         case 'Insectoids vol 2':
  1790.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryCrabSpider" ) );
  1791.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryArmoredArachas" ) );
  1792.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryPoisonousArachas" ) );
  1793.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 2');
  1794.                                 break;
  1795.                         case 'Magical Monsters vol 1':
  1796.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryGolem" ) );
  1797.                                 break;
  1798.                         case 'Magical Monsters vol 2':
  1799.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryElemental" ) );
  1800.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryIceGolem" ) );
  1801.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryFireElemental" ) );
  1802.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryWhMinion" ) );
  1803.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 20');
  1804.                                 break;
  1805.                         case 'Necrophage vol 1':
  1806.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryGhoul" ) );
  1807.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryAlghoul" ) );
  1808.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryGreaterRotFiend" ) );
  1809.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryDrowner" ) );
  1810.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 15');
  1811.                                 break;
  1812.                         case 'Necrophage vol 2':
  1813.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryGraveHag" ) );
  1814.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryWaterHag" ) );
  1815.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryFogling" ) );
  1816.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 5');
  1817.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 9');
  1818.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 18');
  1819.                                 break;
  1820.                         case 'Relict Monsters vol 1':
  1821.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryBies" ) );
  1822.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryCzart" ) );
  1823.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 8');
  1824.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 16');
  1825.                                 break;
  1826.                         case 'Relict Monsters vol 2':
  1827.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryLeshy" ) );
  1828.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiarySilvan" ) );
  1829.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 22');
  1830.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 26');
  1831.                                 break;
  1832.                         case 'Specters vol 1':
  1833.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryMoonwright" ) );
  1834.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryNoonwright" ) );
  1835.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryPesta" ) );
  1836.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 6');
  1837.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 13');
  1838.                                 break;
  1839.                         case 'Specters vol 2':
  1840.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryWraith" ) );
  1841.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryHim" ) );
  1842.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 19');
  1843.                                 break;
  1844.                         case 'Ogres vol 1':
  1845.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryNekker" ) );
  1846.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryIceTroll" ) );
  1847.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryCaveTroll" ) );
  1848.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 12');
  1849.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 25');
  1850.                                 break;
  1851.                         case 'Ogres vol 2':
  1852.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryCyclop" ) );
  1853.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryIceGiant" ) );
  1854.                                 break;
  1855.                         case 'Vampires vol 1':
  1856.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryEkkima" ) );
  1857.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryHigherVampire" ) );
  1858.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 7');
  1859.                                 break;
  1860.                         case 'Vampires vol 2':
  1861.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryKatakan" ) );
  1862.                                 GetWitcherPlayer().AddAlchemyRecipe('Recipe for Mutagen 1');
  1863.                                 break;
  1864.                        
  1865.                         case 'bestiary_sharley_book':
  1866.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiarySharley" ) );
  1867.                                 break;
  1868.                         case 'bestiary_barghest_book':
  1869.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryBarghest" ) );
  1870.                                 break;
  1871.                         case 'bestiary_garkain_book':
  1872.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryGarkain" ) );
  1873.                                 break;
  1874.                         case 'bestiary_alp_book':
  1875.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryAlp" ) );
  1876.                                 break;
  1877.                         case 'bestiary_bruxa_book':
  1878.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryBruxa" ) );
  1879.                                 break;
  1880.                         case 'bestiary_spriggan_book':
  1881.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiarySpriggan" ) );
  1882.                                 break;
  1883.                         case 'bestiary_fleder_book':
  1884.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryFleder" ) );
  1885.                                 break;
  1886.                         case 'bestiary_wight_book':
  1887.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryWicht" ) );
  1888.                                 break;
  1889.                         case 'bestiary_dracolizard_book':
  1890.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryDracolizard" ) );
  1891.                                 break;
  1892.                         case 'bestiary_panther_book':
  1893.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryPanther" ) );
  1894.                                 break;
  1895.                         case 'bestiary_kikimore_book':
  1896.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryKikimoraWarrior" ) );
  1897.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryKikimoraWorker" ) );
  1898.                                 break;
  1899.                         case 'bestiary_scolopendromorph_book':
  1900.                         case 'mq7023_fluff_book_scolopendromorphs':
  1901.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryScolopendromorph" ) );
  1902.                                 break;
  1903.                         case 'bestiary_archespore_book':
  1904.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryArchespore" ) );
  1905.                                 break;
  1906.                         case 'bestiary_protofleder_book':
  1907.                                 resource.PushBack( (CJournalResource)LoadResource( "BestiaryProtofleder" ) );
  1908.                                 break;
  1909.                         default:
  1910.                                 return false;
  1911.                 }
  1912.                
  1913.                
  1914.                
  1915.                
  1916.                 len = resource.Size();
  1917.                 if( len > 0)
  1918.                 {
  1919.                        
  1920.                         theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt( "panel_hud_journal_entry_bestiary_new" ), 0, true );
  1921.                         theSound.SoundEvent("gui_ingame_new_journal");
  1922.                 }
  1923.                
  1924.                 for (r=0; r < len; r += 1 )
  1925.                 {
  1926.                         if ( !resource[ r ] )
  1927.                         {
  1928.                                
  1929.                                 continue;
  1930.                         }
  1931.                         entryBase = resource[r].GetEntry();
  1932.                         if ( entryBase )
  1933.                         {
  1934.                                 manager.ActivateEntry( entryBase, JS_Active );
  1935.                                 manager.SetEntryHasAdvancedInfo( entryBase, true );
  1936.                                
  1937.                                
  1938.                                 manager.GetAllChildren( entryBase, childGroups );
  1939.                                 for ( i = 0; i < childGroups.Size(); i += 1 )
  1940.                                 {      
  1941.                                         descriptionGroup = ( CJournalCreatureDescriptionGroup )childGroups[ i ];
  1942.                                         if ( descriptionGroup )
  1943.                                         {
  1944.                                                 manager.GetAllChildren( descriptionGroup, childEntries );
  1945.                                                 for ( j = 0; j < childEntries.Size(); j += 1 )
  1946.                                                 {
  1947.                                                         descriptionEntry = ( CJournalCreatureDescriptionEntry )childEntries[ j ];
  1948.                                                         if ( descriptionEntry )
  1949.                                                         {
  1950.                                                                 manager.ActivateEntry( descriptionEntry, JS_Active );
  1951.                                                         }
  1952.                                                 }
  1953.                                                 break;
  1954.                                         }
  1955.                                 }
  1956.                         }
  1957.                 }      
  1958.                
  1959.                 if ( resource.Size() > 0 )
  1960.                         return true;
  1961.                 else
  1962.                         return false;
  1963.         }
  1964.        
  1965.        
  1966.        
  1967.        
  1968.        
  1969.        
  1970.  
  1971.        
  1972.         function GetWeaponDTNames( id : SItemUniqueId, out dmgNames : array< name > ) : int
  1973.         {
  1974.                 var attrs : array< name >;
  1975.                 var i, size : int;
  1976.        
  1977.                 dmgNames.Clear();
  1978.        
  1979.                 if( IsIdValid(id) )
  1980.                 {
  1981.                         GetItemAttributes( id, attrs );
  1982.                         size = attrs.Size();
  1983.                        
  1984.                         for( i = 0; i < size; i += 1 )
  1985.                                 if( IsDamageTypeNameValid(attrs[i]) )
  1986.                                         dmgNames.PushBack( attrs[i] );
  1987.                        
  1988.                         if(dmgNames.Size() == 0)
  1989.                                 LogAssert(false, "CInventoryComponent.GetWeaponDTNames: weapon <<" + GetItemName(id) + ">> has no damage types defined!");
  1990.                 }
  1991.                 return dmgNames.Size();
  1992.         }
  1993.        
  1994.         public function GetWeapons() : array<SItemUniqueId>
  1995.         {
  1996.                 var ids, ids2 : array<SItemUniqueId>;
  1997.        
  1998.                 ids = GetItemsByCategory('monster_weapon');
  1999.                 ids2 = GetItemsByTag('Weapon');
  2000.                 ArrayOfIdsAppend(ids, ids2);
  2001.                
  2002.                 return ids;
  2003.         }
  2004.        
  2005.         public function GetHeldWeapons() : array<SItemUniqueId>
  2006.         {
  2007.                 var i : int;
  2008.                 var w : array<SItemUniqueId>;
  2009.        
  2010.                 w = GetWeapons();
  2011.                
  2012.                 for(i=w.Size()-1; i>=0; i-=1)
  2013.                 {
  2014.                         if(!IsItemHeld(w[i]))
  2015.                         {
  2016.                                 w.EraseFast( i );
  2017.                         }
  2018.                 }
  2019.                
  2020.                 return w;
  2021.         }
  2022.        
  2023.         public function GetCurrentlyHeldSword() : SItemUniqueId
  2024.         {
  2025.                 var i   : int;
  2026.                 var w   : array<SItemUniqueId>;
  2027.                
  2028.                 w = GetHeldWeapons();
  2029.                
  2030.                 for( i = 0 ; i < w.Size() ; i+=1 )
  2031.                 {
  2032.                         if( IsItemSteelSwordUsableByPlayer( w[i] ) || IsItemSilverSwordUsableByPlayer( w[i] ) )
  2033.                         {
  2034.                                 return w[i];
  2035.                         }
  2036.                 }
  2037.                
  2038.                 return GetInvalidUniqueId();           
  2039.         }
  2040.        
  2041.         public function GetCurrentlyHeldSwordEntity( out ent : CItemEntity ) : bool
  2042.         {
  2043.                 var id          : SItemUniqueId;
  2044.                
  2045.                 id = GetCurrentlyHeldSword();
  2046.                
  2047.                 if( IsIdValid( id ) )
  2048.                 {
  2049.                         ent = GetItemEntityUnsafe( id );
  2050.                        
  2051.                         if( ent )
  2052.                         {
  2053.                                 return true;
  2054.                         }
  2055.                         else
  2056.                         {
  2057.                                 return false;
  2058.                         }
  2059.                 }
  2060.                 return false;
  2061.         }
  2062.        
  2063.         public function GetHeldWeaponsWithCategory( category : name, out items : array<SItemUniqueId> )
  2064.         {
  2065.                 var i : int;
  2066.        
  2067.                 items = GetItemsByCategory( category );
  2068.                
  2069.                 for ( i = items.Size()-1; i >= 0; i -= 1)
  2070.                 {
  2071.                         if ( !IsItemHeld( items[i] ) )
  2072.                         {
  2073.                                 items.EraseFast( i );
  2074.                         }
  2075.                 }
  2076.         }
  2077.                
  2078.         public function GetPotionItemBuffData(id : SItemUniqueId, out type : EEffectType, out customAbilityName : name) : bool
  2079.         {
  2080.                 var size, i : int;
  2081.                 var arr : array<name>;
  2082.        
  2083.                 if(IsIdValid(id))
  2084.                 {
  2085.                         GetItemContainedAbilities( id, arr );
  2086.                         size = arr.Size();
  2087.                        
  2088.                         for( i = 0; i < size; i += 1 )
  2089.                         {
  2090.                                 if( IsEffectNameValid(arr[i]) )
  2091.                                 {
  2092.                                         EffectNameToType(arr[i], type, customAbilityName);
  2093.                                         return true;
  2094.                                 }
  2095.                         }
  2096.                 }
  2097.                
  2098.                 return false;
  2099.         }
  2100.  
  2101.        
  2102.         public function RecycleItem( id : SItemUniqueId, level : ECraftsmanLevel ) :  array<SItemUniqueId>
  2103.         {
  2104.                 var itemsAdded : array<SItemUniqueId>;
  2105.                 var currentAdded : array<SItemUniqueId>;
  2106.                
  2107.                 var parts : array<SItemParts>;
  2108.                 var i : int;
  2109.                
  2110.                 parts = GetItemRecyclingParts( id );
  2111.                
  2112.                 for ( i = 0; i < parts.Size(); i += 1 )
  2113.                 {
  2114.                         if ( ECL_Grand_Master == level || ECL_Arch_Master == level )
  2115.                         {
  2116.                                 currentAdded = AddAnItem( parts[i].itemName, parts[i].quantity );
  2117.                         }
  2118.                         else if ( ECL_Master == level && parts[i].quantity > 1 )
  2119.                         {
  2120.                                 currentAdded = AddAnItem( parts[i].itemName, RandRange( parts[i].quantity, 1 ) );
  2121.                         }
  2122.                         else
  2123.                         {
  2124.                                 currentAdded = AddAnItem( parts[i].itemName, 1 );
  2125.                         }
  2126.                         itemsAdded.PushBack(currentAdded[0]);
  2127.                 }
  2128.  
  2129.                 RemoveItem(id);
  2130.                
  2131.                 return itemsAdded;
  2132.         }
  2133.                
  2134.        
  2135.        
  2136.        
  2137.        
  2138.        
  2139.         public function GetItemBuffs( id : SItemUniqueId, out buffs : array<SEffectInfo>) : int
  2140.         {
  2141.                 var attrs, abs, absFast : array< name >;
  2142.                 var i, k : int;
  2143.                 var type : EEffectType;
  2144.                 var abilityName : name;
  2145.                 var buff : SEffectInfo;
  2146.                 var dm : CDefinitionsManagerAccessor;
  2147.                
  2148.                 buffs.Clear();
  2149.                
  2150.                 if( !IsIdValid(id) )
  2151.                         return 0;
  2152.                
  2153.                
  2154.                 GetItemContainedAbilities(id, absFast);
  2155.                 if(absFast.Size() == 0)
  2156.                         return 0;
  2157.                
  2158.                 GetItemAbilities(id, abs);
  2159.                 dm = theGame.GetDefinitionsManager();
  2160.                 for(k=0; k<abs.Size(); k+=1)
  2161.                 {
  2162.                         dm.GetContainedAbilities(abs[k], attrs);
  2163.                         buff.applyChance = CalculateAttributeValue(GetItemAbilityAttributeValue(id, 'buff_apply_chance', abs[k])) * ArrayOfNamesCount(abs, abs[k]);
  2164.                        
  2165.                         for( i = 0; i < attrs.Size(); i += 1 )
  2166.                         {
  2167.                                 if( IsEffectNameValid(attrs[i]) )
  2168.                                 {
  2169.                                         EffectNameToType(attrs[i], type, abilityName);
  2170.                                        
  2171.                                         buff.effectType = type;
  2172.                                         buff.effectAbilityName = abilityName;                                  
  2173.                                        
  2174.                                         buffs.PushBack(buff);
  2175.                                        
  2176.                                        
  2177.                                         if(absFast.Size() == 1)
  2178.                                                 return buffs.Size();
  2179.                                         else
  2180.                                                 absFast.EraseFast(0);                                  
  2181.                                 }
  2182.                         }
  2183.                 }
  2184.                
  2185.                 return buffs.Size();
  2186.         }      
  2187.        
  2188.        
  2189.         public function DropItemInBag( item : SItemUniqueId, quantity : int )
  2190.         {
  2191.                 var entities : array<CGameplayEntity>;
  2192.                 var i : int;
  2193.                 var owner : CActor;
  2194.                 var bag : W3ActorRemains;
  2195.                 var template : CEntityTemplate;
  2196.                 var bagtags : array <name>;
  2197.                 var bagPosition : Vector;
  2198.                 var tracedPosition, tracedNormal : Vector;
  2199.                                
  2200.                 if(ItemHasTag(item, 'NoDrop'))
  2201.                         return;        
  2202.                
  2203.                 owner = (CActor)GetEntity();
  2204.                 FindGameplayEntitiesInRange(entities, owner, 0.5, 100);
  2205.                
  2206.                 for(i=0; i<entities.Size(); i+=1)
  2207.                 {
  2208.                         bag = (W3ActorRemains)entities[i];
  2209.                        
  2210.                         if(bag)
  2211.                                 break;
  2212.                 }
  2213.                
  2214.                
  2215.                 if(!bag)
  2216.                 {
  2217.                         template = (CEntityTemplate)LoadResource("lootbag");
  2218.                         bagtags.PushBack('lootbag');
  2219.                        
  2220.                        
  2221.                         bagPosition = owner.GetWorldPosition();
  2222.                         if ( theGame.GetWorld().StaticTrace( bagPosition, bagPosition + Vector( 0.0f, 0.0f, -10.0f, 0.0f ), tracedPosition, tracedNormal ) )
  2223.                         {
  2224.                                 bagPosition = tracedPosition;
  2225.                         }
  2226.                         bag = (W3ActorRemains)theGame.CreateEntity(template, bagPosition, owner.GetWorldRotation(), true, false, false, PM_Persist,bagtags);
  2227.                 }
  2228.        
  2229.                
  2230.                 GiveItemTo(bag.GetInventory(), item, quantity, false);
  2231.                
  2232.                
  2233.                 if(bag.GetInventory().IsEmpty())
  2234.                 {
  2235.                         delete bag;
  2236.                         return;
  2237.                 }              
  2238.                
  2239.                 bag.LootDropped();             
  2240.                 theTelemetry.LogWithLabelAndValue(TE_INV_ITEM_DROPPED, GetItemName(item), quantity);
  2241.                
  2242.                
  2243.                 if( thePlayer.IsSwimming() )
  2244.                 {
  2245.                         bag.PlayPropertyAnimation( 'float', 0 );
  2246.                 }
  2247.         }
  2248.        
  2249.        
  2250.        
  2251.        
  2252.        
  2253.        
  2254.         public final function AddRepairObjectItemBonuses(buffArmor : bool, buffSwords : bool, ammoArmor : int, ammoWeapon : int) : bool
  2255.         {
  2256.                 var upgradedSomething, isArmor : bool;
  2257.                 var i, ammo, currAmmo : int;
  2258.                 var items, items2 : array<SItemUniqueId>;
  2259.                
  2260.                
  2261.                 if(buffArmor)
  2262.                 {
  2263.                         items = GetItemsByTag(theGame.params.TAG_ARMOR);
  2264.                 }
  2265.                 if(buffSwords)
  2266.                 {
  2267.                         items2 = GetItemsByTag(theGame.params.TAG_PLAYER_STEELSWORD);
  2268.                         ArrayOfIdsAppend(items, items2);
  2269.                         items2.Clear();
  2270.                         items2 = GetItemsByTag(theGame.params.TAG_PLAYER_SILVERSWORD);
  2271.                         ArrayOfIdsAppend(items, items2);
  2272.                 }
  2273.                
  2274.                 upgradedSomething = false;
  2275.                
  2276.                 for(i=0; i<items.Size(); i+=1)
  2277.                 {
  2278.                        
  2279.                         if(IsItemAnyArmor(items[i]))
  2280.                         {
  2281.                                 isArmor = true;
  2282.                                 ammo = ammoArmor;
  2283.                         }
  2284.                         else
  2285.                         {
  2286.                                 isArmor = false;
  2287.                                 ammo = ammoWeapon;
  2288.                         }
  2289.                        
  2290.                        
  2291.                         currAmmo = GetItemModifierInt(items[i], 'repairObjectBonusAmmo', 0);
  2292.                        
  2293.                        
  2294.                         if(ammo > currAmmo)
  2295.                         {
  2296.                                 SetItemModifierInt(items[i], 'repairObjectBonusAmmo', ammo);
  2297.                                 upgradedSomething = true;
  2298.                                
  2299.                                
  2300.                                 if(currAmmo == 0)
  2301.                                 {
  2302.                                         if(isArmor)
  2303.                                                 AddItemCraftedAbility(items[i], theGame.params.REPAIR_OBJECT_BONUS_ARMOR_ABILITY, false);
  2304.                                         else
  2305.                                                 AddItemCraftedAbility(items[i], theGame.params.REPAIR_OBJECT_BONUS_WEAPON_ABILITY, false);
  2306.                                 }
  2307.                         }
  2308.                 }
  2309.                
  2310.                 return upgradedSomething;
  2311.         }
  2312.        
  2313.         public final function ReduceItemRepairObjectBonusCharge(item : SItemUniqueId)  
  2314.         {
  2315.                 var currAmmo : int;
  2316.                
  2317.                 currAmmo = GetItemModifierInt(item, 'repairObjectBonusAmmo', 0);
  2318.                
  2319.                 if(currAmmo > 0)
  2320.                 {
  2321.                         SetItemModifierInt(item, 'repairObjectBonusAmmo', currAmmo - 1);
  2322.                
  2323.                         if(currAmmo == 1)
  2324.                         {
  2325.                                 if(IsItemAnyArmor(item))
  2326.                                         RemoveItemCraftedAbility(item, theGame.params.REPAIR_OBJECT_BONUS_ARMOR_ABILITY);
  2327.                                 else
  2328.                                         RemoveItemCraftedAbility(item, theGame.params.REPAIR_OBJECT_BONUS_WEAPON_ABILITY);
  2329.                         }
  2330.                 }
  2331.         }
  2332.        
  2333.        
  2334.         public final function GetRepairObjectBonusValueForArmor(armor : SItemUniqueId) : SAbilityAttributeValue
  2335.         {
  2336.                 var retVal, bonusValue, baseArmor : SAbilityAttributeValue;
  2337.                
  2338.                 if(GetItemModifierInt(armor, 'repairObjectBonusAmmo', 0) > 0)
  2339.                 {
  2340.                         bonusValue = GetItemAttributeValue(armor, theGame.params.REPAIR_OBJECT_BONUS);         
  2341.                         baseArmor = GetItemAttributeValue(armor, theGame.params.ARMOR_VALUE_NAME);
  2342.                        
  2343.                         baseArmor.valueMultiplicative += 1;            
  2344.                         retVal.valueAdditive = bonusValue.valueAdditive + CalculateAttributeValue(baseArmor) * bonusValue.valueMultiplicative;
  2345.                 }
  2346.                
  2347.                 return retVal;
  2348.         }
  2349.        
  2350.        
  2351.        
  2352.        
  2353.        
  2354.                
  2355.         public function CanItemHaveOil(id : SItemUniqueId) : bool
  2356.         {
  2357.                 return IsItemSteelSwordUsableByPlayer(id) || IsItemSilverSwordUsableByPlayer(id);
  2358.         }
  2359.        
  2360.         public final function RemoveAllOilsFromItem( id : SItemUniqueId )
  2361.         {
  2362.                 var i : int;
  2363.                 var oils : array< W3Effect_Oil >;
  2364.                 var actor : CActor;
  2365.                
  2366.                 actor = ( CActor ) GetEntity();
  2367.                 oils = GetOilsAppliedOnItem( id );
  2368.                 for( i = oils.Size() - 1; i >= 0; i -= 1 )
  2369.                 {
  2370.                         actor.RemoveEffect( oils[ i ] );
  2371.                 }
  2372.         }
  2373.        
  2374.         public final function GetActiveOilsAppliedOnItemCount( id : SItemUniqueId ) : int
  2375.         {
  2376.                 var oils : array< W3Effect_Oil >;
  2377.                 var i, count : int;
  2378.                
  2379.                 count = 0;
  2380.                 oils = GetOilsAppliedOnItem( id );
  2381.                 for( i=0; i<oils.Size(); i+=1 )
  2382.                 {
  2383.                         if( oils[ i ].GetAmmoCurrentCount() > 0 )
  2384.                         {
  2385.                                 count += 1;
  2386.                         }
  2387.                 }
  2388.                 return count;
  2389.         }
  2390.        
  2391.         public final function RemoveOldestOilFromItem( id : SItemUniqueId )
  2392.         {
  2393.                 var buffToRemove : W3Effect_Oil;
  2394.                 var actor : CActor;
  2395.                
  2396.                 actor = ( CActor ) GetEntity();
  2397.                 if(! actor )
  2398.                         return;
  2399.                        
  2400.                 buffToRemove = GetOldestOilAppliedOnItem(id, false);
  2401.                
  2402.                 if(buffToRemove)
  2403.                 {
  2404.                         actor.RemoveEffect( buffToRemove );
  2405.                 }
  2406.         }
  2407.        
  2408.         public final function GetOilsAppliedOnItem( id : SItemUniqueId ) : array< W3Effect_Oil >
  2409.         {
  2410.                 var i : int;
  2411.                 var oils : array< CBaseGameplayEffect >;
  2412.                 var buff : W3Effect_Oil;
  2413.                 var ret : array < W3Effect_Oil >;
  2414.                 var actor : CActor;
  2415.                
  2416.                 actor = ( CActor ) GetEntity();
  2417.                 if(! actor )
  2418.                         return ret;
  2419.                        
  2420.                 oils = actor.GetBuffs( EET_Oil );
  2421.                 for( i = oils.Size() - 1; i >= 0; i -= 1 )
  2422.                 {
  2423.                         buff = ( W3Effect_Oil ) oils[ i ];
  2424.                         if(buff && buff.GetSwordItemId() == id )
  2425.                         {
  2426.                                 ret.PushBack( buff );
  2427.                         }
  2428.                 }
  2429.                
  2430.                 return ret;
  2431.         }
  2432.        
  2433.         public final function GetNewestOilAppliedOnItem( id : SItemUniqueId, onlyShowable : bool ) : W3Effect_Oil
  2434.         {
  2435.                 return GetOilAppliedOnItemInternal( id, onlyShowable, true );
  2436.         }
  2437.        
  2438.         public final function GetOldestOilAppliedOnItem( id : SItemUniqueId, onlyShowable : bool ) : W3Effect_Oil
  2439.         {
  2440.                 return GetOilAppliedOnItemInternal( id, onlyShowable, false );
  2441.         }
  2442.        
  2443.         private final function GetOilAppliedOnItemInternal( id : SItemUniqueId, onlyShowable : bool, newest : bool ) : W3Effect_Oil
  2444.         {
  2445.                 var oils : array< W3Effect_Oil >;
  2446.                 var i, lastIndex : int;
  2447.                
  2448.                 oils = GetOilsAppliedOnItem( id );
  2449.                 lastIndex = -1;
  2450.                
  2451.                 for( i=0; i<oils.Size(); i+=1 )
  2452.                 {
  2453.                         if( onlyShowable && !oils[i].GetShowOnHUD() )
  2454.                         {
  2455.                                 continue;
  2456.                         }
  2457.                        
  2458.                         if( lastIndex == -1 )
  2459.                         {
  2460.                                 lastIndex = i;
  2461.                         }
  2462.                         else if( newest && oils[i].GetQueueTimer() < oils[lastIndex].GetQueueTimer() )
  2463.                         {
  2464.                                 lastIndex = i;
  2465.                         }
  2466.                         else if( !newest && oils[i].GetQueueTimer() > oils[lastIndex].GetQueueTimer() )
  2467.                         {
  2468.                                 lastIndex = i;
  2469.                         }
  2470.                 }
  2471.                
  2472.                 if( lastIndex == -1 )
  2473.                 {
  2474.                         return NULL;
  2475.                 }
  2476.                
  2477.                 return oils[lastIndex];
  2478.         }
  2479.        
  2480.         public final function ItemHasAnyActiveOilApplied( id : SItemUniqueId ) : bool
  2481.         {
  2482.                 return GetActiveOilsAppliedOnItemCount( id );
  2483.         }
  2484.        
  2485.         public final function ItemHasActiveOilApplied( id : SItemUniqueId, monsterCategory : EMonsterCategory ) : bool
  2486.         {
  2487.                 var i : int;
  2488.                 var oils : array< W3Effect_Oil >;
  2489.                
  2490.                 oils = GetOilsAppliedOnItem( id );
  2491.                 for( i=0; i<oils.Size(); i+=1 )
  2492.                 {
  2493.                         if( oils[ i ].GetMonsterCategory() == monsterCategory && oils[ i ].GetAmmoCurrentCount() > 0 )
  2494.                         {
  2495.                                 return true;
  2496.                         }
  2497.                 }
  2498.                
  2499.                 return false;
  2500.         }
  2501.        
  2502.        
  2503.        
  2504.        
  2505.        
  2506.         public final function GetParamsForRunewordTooltip(runewordName : name, out i : array<int>, out f : array<float>, out s : array<string>)
  2507.         {
  2508.                 var min, max : SAbilityAttributeValue;
  2509.                 var val : float;
  2510.                 var attackRangeBase, attackRangeExt : CAIAttackRange;
  2511.                
  2512.                 i.Clear();
  2513.                 f.Clear();
  2514.                 s.Clear();
  2515.                
  2516.                 switch(runewordName)
  2517.                 {
  2518.                         case 'Glyphword 5':
  2519.                                 theGame.GetDefinitionsManager().GetAbilityAttributeValue('Glyphword 5 _Stats', 'glyphword5_chance', min, max);                         
  2520.                                 i.PushBack( RoundMath( CalculateAttributeValue(min) * 100) );
  2521.                                 break;
  2522.                         case 'Glyphword 6' :
  2523.                                 theGame.GetDefinitionsManager().GetAbilityAttributeValue('Glyphword 6 _Stats', 'glyphword6_stamina_drain_perc', min, max);                             
  2524.                                 i.PushBack( RoundMath( CalculateAttributeValue(min) * 100) );
  2525.                                 break;
  2526.                         case 'Glyphword 12' :
  2527.                                 theGame.GetDefinitionsManager().GetAbilityAttributeValue('Glyphword 12 _Stats', 'glyphword12_range', min, max);
  2528.                                 val = CalculateAttributeValue(min);
  2529.                                 s.PushBack( NoTrailZeros(val) );
  2530.                                
  2531.                                 theGame.GetDefinitionsManager().GetAbilityAttributeValue('Glyphword 12 _Stats', 'glyphword12_chance', min, max);
  2532.                                 i.PushBack( RoundMath( min.valueAdditive * 100) );
  2533.                                 break;
  2534.                         case 'Glyphword 17' :
  2535.                                 theGame.GetDefinitionsManager().GetAbilityAttributeValue('Glyphword 17 _Stats', 'quen_apply_chance', min, max);
  2536.                                 val = CalculateAttributeValue(min);
  2537.                                 i.PushBack( RoundMath(val * 100) );
  2538.                                 break;
  2539.                         case 'Glyphword 14' :
  2540.                         case 'Glyphword 18' :
  2541.                                 theGame.GetDefinitionsManager().GetAbilityAttributeValue('Glyphword 18 _Stats', 'increas_duration', min, max);
  2542.                                 val = CalculateAttributeValue(min);
  2543.                                 s.PushBack( NoTrailZeros(val) );
  2544.                                 break;
  2545.                                
  2546.                         case 'Runeword 2' :
  2547.                                 attackRangeBase = theGame.GetAttackRangeForEntity(GetWitcherPlayer(), 'specialattacklight');
  2548.                                 attackRangeExt = theGame.GetAttackRangeForEntity(GetWitcherPlayer(), 'runeword2_light');                               
  2549.                                 s.PushBack( NoTrailZeros(attackRangeExt.rangeMax - attackRangeBase.rangeMax) );
  2550.                                
  2551.                                 attackRangeBase = theGame.GetAttackRangeForEntity(GetWitcherPlayer(), 'slash_long');
  2552.                                 attackRangeExt = theGame.GetAttackRangeForEntity(GetWitcherPlayer(), 'runeword2_heavy');                               
  2553.                                 s.PushBack( NoTrailZeros(attackRangeExt.rangeMax - attackRangeBase.rangeMax) );
  2554.                                
  2555.                                 break;
  2556.                         case 'Runeword 4' :
  2557.                                 theGame.GetDefinitionsManager().GetAbilityAttributeValue('Runeword 4 _Stats', 'max_bonus', min, max);
  2558.                                 i.PushBack( RoundMath(max.valueMultiplicative * 100) );
  2559.                                 break;
  2560.                         case 'Runeword 6' :
  2561.                                 theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Runeword 6 _Stats', 'runeword6_duration_bonus', min, max );
  2562.                                 i.PushBack( RoundMath(min.valueMultiplicative * 100) );
  2563.                                 break;
  2564.                         case 'Runeword 7' :
  2565.                                 theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Runeword 7 _Stats', 'stamina', min, max );
  2566.                                 i.PushBack( RoundMath(min.valueMultiplicative * 100) );
  2567.                                 break;
  2568.                         case 'Runeword 10' :
  2569.                                 theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Runeword 10 _Stats', 'stamina', min, max );
  2570.                                 i.PushBack( RoundMath(min.valueMultiplicative * 100) );
  2571.                                 break;
  2572.                         case 'Runeword 11' :
  2573.                                 theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Runeword 11 _Stats', 'duration', min, max );
  2574.                                 s.PushBack( NoTrailZeros(min.valueAdditive) );
  2575.                                 break;
  2576.                         case 'Runeword 12' :
  2577.                                 theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Runeword 12 _Stats', 'focus', min, max );
  2578.                                 f.PushBack(min.valueAdditive);
  2579.                                 f.PushBack(max.valueAdditive);
  2580.                                 break;
  2581.                         default:
  2582.                                 break;
  2583.                 }
  2584.         }
  2585.        
  2586.         public final function GetPotionAttributesForTooltip(potionId : SItemUniqueId, out tips : array<SAttributeTooltip>):void
  2587.         {
  2588.                 var i, j, settingsSize : int;
  2589.                 var buffType : EEffectType;
  2590.                 var abilityName : name;
  2591.                 var abs, attrs : array<name>;
  2592.                 var val : SAbilityAttributeValue;
  2593.                 var newAttr : SAttributeTooltip;
  2594.                 var attributeString : string;
  2595.                
  2596.                
  2597.                 if(!( IsItemPotion(potionId) || IsItemFood(potionId) ) )
  2598.                         return;
  2599.                        
  2600.                
  2601.                 GetItemContainedAbilities(potionId, abs);
  2602.                 for(i=0; i<abs.Size(); i+=1)
  2603.                 {
  2604.                         EffectNameToType(abs[i], buffType, abilityName);
  2605.                        
  2606.                        
  2607.                         if(buffType == EET_Undefined)
  2608.                                 continue;
  2609.                                
  2610.                        
  2611.                         theGame.GetDefinitionsManager().GetAbilityAttributes(abs[i], attrs);
  2612.                         break;
  2613.                 }
  2614.                
  2615.                
  2616.                 attrs.Remove('duration');
  2617.                 attrs.Remove('level');
  2618.                
  2619.                 if(buffType == EET_Cat)
  2620.                 {
  2621.                        
  2622.                         attrs.Remove('highlightObjectsRange');
  2623.                 }
  2624.                 else if(buffType == EET_GoldenOriole)
  2625.                 {
  2626.                        
  2627.                         attrs.Remove('poison_resistance_perc');
  2628.                 }
  2629.                 else if(buffType == EET_MariborForest)
  2630.                 {
  2631.                        
  2632.                         attrs.Remove('focus_on_drink');
  2633.                 }
  2634.                 else if(buffType == EET_KillerWhale)
  2635.                 {
  2636.                        
  2637.                         attrs.Remove('swimmingStamina');
  2638.                         attrs.Remove('vision_strength');
  2639.                 }
  2640.                 else if(buffType == EET_Thunderbolt)
  2641.                 {
  2642.                        
  2643.                         attrs.Remove('critical_hit_chance');
  2644.                 }
  2645.                 else if(buffType == EET_WhiteRaffardDecoction)
  2646.                 {
  2647.                         val = GetItemAttributeValue(potionId, 'level');
  2648.                         if(val.valueAdditive == 3)
  2649.                                 attrs.Insert(0, 'duration');
  2650.                 }
  2651.                 else if(buffType == EET_Mutagen20)
  2652.                 {
  2653.                         attrs.Remove('burning_DoT_damage_resistance_perc');
  2654.                         attrs.Remove('poison_DoT_damage_resistance_perc');
  2655.                         attrs.Remove('bleeding_DoT_damage_resistance_perc');
  2656.                 }
  2657.                 else if(buffType == EET_Mutagen27)
  2658.                 {
  2659.                         attrs.Remove('mutagen27_max_stack');
  2660.                 }
  2661.                 else if(buffType == EET_Mutagen18)
  2662.                 {
  2663.                         attrs.Remove('mutagen18_max_stack');
  2664.                 }
  2665.                 else if(buffType == EET_Mutagen19)
  2666.                 {
  2667.                         attrs.Remove('max_hp_perc_trigger');
  2668.                 }
  2669.                 else if(buffType == EET_Mutagen21)
  2670.                 {
  2671.                         attrs.Remove('healingRatio');
  2672.                 }
  2673.                 else if(buffType == EET_Mutagen22)
  2674.                 {
  2675.                         attrs.Remove('mutagen22_max_stack');
  2676.                 }
  2677.                 else if(buffType == EET_Mutagen02)
  2678.                 {
  2679.                         attrs.Remove('resistGainRate');
  2680.                 }
  2681.                 else if(buffType == EET_Mutagen04)
  2682.                 {
  2683.                         attrs.Remove('staminaCostPerc');
  2684.                         attrs.Remove('healthReductionPerc');
  2685.                 }
  2686.                 else if(buffType == EET_Mutagen08)
  2687.                 {
  2688.                         attrs.Remove('resistGainRate');
  2689.                 }
  2690.                 else if(buffType == EET_Mutagen10)
  2691.                 {
  2692.                         attrs.Remove('mutagen10_max_stack');
  2693.                 }
  2694.                 else if(buffType == EET_Mutagen14)
  2695.                 {
  2696.                         attrs.Remove('mutagen14_max_stack');
  2697.                 }
  2698.                
  2699.                
  2700.                 for(j=0; j<attrs.Size(); j+=1)
  2701.                 {
  2702.                         val = GetItemAbilityAttributeValue(potionId, attrs[j], abs[i]);
  2703.                        
  2704.                         newAttr.originName = attrs[j];
  2705.                         newAttr.attributeName = GetAttributeNameLocStr(attrs[j], false);
  2706.                        
  2707.                         if(buffType == EET_MariborForest && attrs[j] == 'focus_gain')
  2708.                         {
  2709.                                 newAttr.value = val.valueAdditive;
  2710.                                 newAttr.percentageValue = false;
  2711.                         }
  2712.                         else if(val.valueMultiplicative != 0)
  2713.                         {
  2714.                                 if(buffType == EET_Mutagen26)
  2715.                                 {
  2716.                                        
  2717.                                         newAttr.value = val.valueAdditive;
  2718.                                         newAttr.percentageValue = false;
  2719.                                         tips.PushBack(newAttr);
  2720.                                        
  2721.                                         newAttr.value = val.valueMultiplicative;
  2722.                                         newAttr.percentageValue = true;
  2723.                                        
  2724.                                         attrs.Erase(1);                                
  2725.                                 }
  2726.                                 else if(buffType == EET_Mutagen07)
  2727.                                 {
  2728.                                        
  2729.                                         attrs.Erase(1);
  2730.                                         newAttr.value = val.valueBase;
  2731.                                         newAttr.percentageValue = true;
  2732.                                 }
  2733.                                 else
  2734.                                 {
  2735.                                         newAttr.value = val.valueMultiplicative;
  2736.                                         newAttr.percentageValue = true;
  2737.                                 }
  2738.                         }
  2739.                         else if(val.valueAdditive != 0)
  2740.                         {
  2741.                                 if(buffType == EET_Thunderbolt)
  2742.                                 {
  2743.                                         newAttr.value = val.valueAdditive * 100;
  2744.                                         newAttr.percentageValue = true;
  2745.                                 }
  2746.                                 else if(buffType == EET_Blizzard)
  2747.                                 {
  2748.                                         newAttr.value = 1 - val.valueAdditive;
  2749.                                         newAttr.percentageValue = true;
  2750.                                 }
  2751.                                 else if(buffType == EET_Mutagen01 || buffType == EET_Mutagen15 || buffType == EET_Mutagen28 || buffType == EET_Mutagen27)
  2752.                                 {
  2753.                                         newAttr.value = val.valueAdditive;
  2754.                                         newAttr.percentageValue = true;
  2755.                                 }
  2756.                                 else
  2757.                                 {
  2758.                                         newAttr.value = val.valueAdditive;
  2759.                                         newAttr.percentageValue = false;
  2760.                                 }
  2761.                         }
  2762.                         else if(buffType == EET_GoldenOriole)
  2763.                         {
  2764.                                 newAttr.value = val.valueBase;
  2765.                                 newAttr.percentageValue = true;
  2766.                         }
  2767.                         else
  2768.                         {
  2769.                                 newAttr.value = val.valueBase;
  2770.                                 newAttr.percentageValue = false;
  2771.                         }
  2772.                        
  2773.                         tips.PushBack(newAttr);
  2774.                 }
  2775.         }
  2776.        
  2777.        
  2778.         public function GetItemRelativeTooltipType(id :SItemUniqueId, invOther : CInventoryComponent, idOther : SItemUniqueId) : ECompareType
  2779.         {      
  2780.                
  2781.                 if( (GetItemCategory(id) == invOther.GetItemCategory(idOther)) ||
  2782.                     ItemHasTag(id, 'PlayerSteelWeapon') && invOther.ItemHasTag(idOther, 'PlayerSteelWeapon') ||
  2783.                     ItemHasTag(id, 'PlayerSilverWeapon') && invOther.ItemHasTag(idOther, 'PlayerSilverWeapon') ||
  2784.                     ItemHasTag(id, 'PlayerSecondaryWeapon') && invOther.ItemHasTag(idOther, 'PlayerSecondaryWeapon')
  2785.                 )
  2786.                 {
  2787.                         return ECT_Compare;
  2788.                 }
  2789.                 return ECT_Incomparable;
  2790.         }
  2791.        
  2792.        
  2793.         private function FormatFloatForTooltip(fValue : float) : string
  2794.         {
  2795.                 var valueInt, valueDec : int;
  2796.                 var strValue : string;
  2797.                
  2798.                 if(fValue < 0)
  2799.                 {
  2800.                         valueInt = CeilF(fValue);
  2801.                         valueDec = RoundMath((fValue - valueInt)*(-100));
  2802.                 }
  2803.                 else
  2804.                 {
  2805.                         valueInt = FloorF(fValue);
  2806.                         valueDec = RoundMath((fValue - valueInt)*(100));
  2807.                 }
  2808.                 strValue = valueInt+".";
  2809.                 if(valueDec < 10)
  2810.                         strValue += "0"+valueDec;
  2811.                 else
  2812.                         strValue += ""+valueDec;
  2813.                
  2814.                 return strValue;
  2815.         }
  2816.  
  2817.         public function SetPriceMultiplier( mult : float )
  2818.         {
  2819.                 priceMult = mult;
  2820.         }
  2821.        
  2822.        
  2823.         public function GetMerchantPriceModifier( shopNPC : CNewNPC, item : SItemUniqueId ) : float
  2824.         {
  2825.                 var areaPriceMult               : float;
  2826.                 var itemPriceMult               : float;
  2827.                 var importPriceMult             : float;
  2828.                 var finalPriceMult              : float;
  2829.                 var tag                                 : name;
  2830.                 var zoneName                    : EZoneName;
  2831.                
  2832.                 zoneName = theGame.GetCurrentZone();
  2833.                
  2834.                 switch ( zoneName )
  2835.                 {
  2836.                         case ZN_NML_CrowPerch                   : areaPriceMult = CalculateAttributeValue(thePlayer.GetAttributeValue('crow_perch_price_mult'));
  2837.                         case ZN_NML_SpitfireBluff               : areaPriceMult = CalculateAttributeValue(thePlayer.GetAttributeValue('spitfire_bluff_price_mult'));
  2838.                         case ZN_NML_TheMire                     : areaPriceMult = CalculateAttributeValue(thePlayer.GetAttributeValue('the_mire_price_mult'));
  2839.                         case ZN_NML_Mudplough                   : areaPriceMult = CalculateAttributeValue(thePlayer.GetAttributeValue('mudplough_price_mult'));
  2840.                         case ZN_NML_Grayrocks                   : areaPriceMult = CalculateAttributeValue(thePlayer.GetAttributeValue('grayrocks_price_mult'));
  2841.                         case ZN_NML_TheDescent                  : areaPriceMult = CalculateAttributeValue(thePlayer.GetAttributeValue('the_descent_price_mult'));
  2842.                         case ZN_NML_CrookbackBog                : areaPriceMult = CalculateAttributeValue(thePlayer.GetAttributeValue('crookback_bog_price_mult'));
  2843.                         case ZN_NML_BaldMountain                : areaPriceMult = CalculateAttributeValue(thePlayer.GetAttributeValue('bald_mountain_price_mult'));
  2844.                         case ZN_NML_Novigrad                    : areaPriceMult = CalculateAttributeValue(thePlayer.GetAttributeValue('novigrad_price_mult'));
  2845.                         case ZN_NML_Homestead                   : areaPriceMult = CalculateAttributeValue(thePlayer.GetAttributeValue('homestead_price_mult'));
  2846.                         case ZN_NML_Gustfields                  : areaPriceMult = CalculateAttributeValue(thePlayer.GetAttributeValue('gustfields_price_mult'));
  2847.                         case ZN_NML_Oxenfurt                    : areaPriceMult = CalculateAttributeValue(thePlayer.GetAttributeValue('oxenfurt_price_mult'));
  2848.                         case ZN_Undefined                               : areaPriceMult = 1;
  2849.                 }
  2850.                
  2851.                 if              (ItemHasTag(item,'weapon'))     { itemPriceMult = CalculateAttributeValue(shopNPC.GetAttributeValue('weapon_price_mult')); }
  2852.                 else if (ItemHasTag(item,'armor'))              { itemPriceMult = CalculateAttributeValue(shopNPC.GetAttributeValue('armor_price_mult')); }
  2853.                 else if (ItemHasTag(item,'crafting'))   { itemPriceMult = CalculateAttributeValue(shopNPC.GetAttributeValue('crafting_price_mult')); }
  2854.                 else if (ItemHasTag(item,'alchemy'))    { itemPriceMult = CalculateAttributeValue(shopNPC.GetAttributeValue('alchemy_price_mult')); }
  2855.                 else if (ItemHasTag(item,'alcohol'))    { itemPriceMult = CalculateAttributeValue(shopNPC.GetAttributeValue('alcohol_price_mult')); }
  2856.                 else if (ItemHasTag(item,'food'))               { itemPriceMult = CalculateAttributeValue(shopNPC.GetAttributeValue('food_price_mult')); }
  2857.                 else if (ItemHasTag(item,'fish'))               { itemPriceMult = CalculateAttributeValue(shopNPC.GetAttributeValue('fish_price_mult')); }
  2858.                 else if (ItemHasTag(item,'books'))              { itemPriceMult = CalculateAttributeValue(shopNPC.GetAttributeValue('books_price_mult')); }
  2859.                 else if (ItemHasTag(item,'valuables'))  { itemPriceMult = CalculateAttributeValue(shopNPC.GetAttributeValue('valuables_price_mult')); }
  2860.                 else if (ItemHasTag(item,'junk'))               { itemPriceMult = CalculateAttributeValue(shopNPC.GetAttributeValue('junk_price_mult')); }
  2861.                 else if (ItemHasTag(item,'orens'))              { itemPriceMult = CalculateAttributeValue(shopNPC.GetAttributeValue('orens_price_mult')); }
  2862.                 else if (ItemHasTag(item,'florens'))    { itemPriceMult = CalculateAttributeValue(shopNPC.GetAttributeValue('florens_price_mult')); }
  2863.                 else { itemPriceMult = 1; }
  2864.                
  2865.                 if              (ItemHasTag(item,'novigrad'))   { importPriceMult = CalculateAttributeValue(shopNPC.GetAttributeValue('novigrad_price_mult')); }
  2866.                 else if (ItemHasTag(item,'nilfgard'))   { importPriceMult = CalculateAttributeValue(shopNPC.GetAttributeValue('nilfgard_price_mult')); }
  2867.                 else if (ItemHasTag(item,'nomansland')) { importPriceMult = CalculateAttributeValue(shopNPC.GetAttributeValue('nomansland_price_mult')); }
  2868.                 else if (ItemHasTag(item,'skellige'))   { importPriceMult = CalculateAttributeValue(shopNPC.GetAttributeValue('skellige_price_mult')); }
  2869.                 else if (ItemHasTag(item,'nonhuman'))   { importPriceMult = CalculateAttributeValue(shopNPC.GetAttributeValue('nonhuman_price_mult')); }
  2870.                 else { importPriceMult = 1; }
  2871.                
  2872.                 finalPriceMult = areaPriceMult*itemPriceMult*importPriceMult*priceMult;
  2873.                 return  finalPriceMult;
  2874.         }      
  2875.  
  2876.         public function SetRepairPriceMultiplier( mult : float )
  2877.         {
  2878.                 priceRepairMult = mult;
  2879.         }
  2880.        
  2881.        
  2882.         public function GetRepairPriceModifier( repairNPC : CNewNPC ) : float
  2883.         {
  2884.                 return priceRepairMult;
  2885.         }      
  2886.        
  2887.         public function GetRepairPrice( item : SItemUniqueId ) : float
  2888.         {
  2889.                 var currDiff : float;
  2890.                 currDiff = GetItemMaxDurability(item) - GetItemDurability(item);
  2891.                
  2892.                 return priceRepair * currDiff;
  2893.         }
  2894.        
  2895.        
  2896.         public function GetTooltipData(itemId : SItemUniqueId, out localizedName : string, out localizedDescription : string, out price : int, out localizedCategory : string,
  2897.                                                                         out itemStats : array<SAttributeTooltip>, out localizedFluff : string)
  2898.         {
  2899.                 if( !IsIdValid(itemId) )
  2900.                 {
  2901.                         return;
  2902.                 }
  2903.                 localizedName = GetItemLocalizedNameByUniqueID(itemId);
  2904.                 localizedDescription = GetItemLocalizedDescriptionByUniqueID(itemId);
  2905.                 localizedFluff = "IMPLEMENT ME - fluff text";
  2906.                 price = GetItemPriceModified( itemId, false );
  2907.                 localizedCategory = GetItemCategoryLocalisedString(GetItemCategory(itemId));
  2908.                 GetItemStats(itemId, itemStats);
  2909.         }
  2910.        
  2911.        
  2912.         public function GetItemBaseStats(itemId : SItemUniqueId, out itemStats : array<SAttributeTooltip>)
  2913.         {
  2914.                 var attributes : array<name>;
  2915.                
  2916.                 var dm  : CDefinitionsManagerAccessor;
  2917.                 var oilAbilities, oilAttributes : array<name>;
  2918.                 var weights : array<float>;
  2919.                 var i, j : int;
  2920.                 var tmpI, tmpJ : int;
  2921.                
  2922.                 var idx                   : int;
  2923.                 var oilStatsCount : int;
  2924.                 var oilName       : name;
  2925.                 var oilStats      : array<SAttributeTooltip>;
  2926.                 var oilStatFirst  : SAttributeTooltip;
  2927.                 var oils                  : array< W3Effect_Oil >;
  2928.                
  2929.                 GetItemBaseAttributes(itemId, attributes);
  2930.                
  2931.                
  2932.                 oils = GetOilsAppliedOnItem( itemId );
  2933.                 dm = theGame.GetDefinitionsManager();
  2934.                 for( i=0; i<oils.Size(); i+=1 )
  2935.                 {
  2936.                         oilName = oils[ i ].GetOilItemName();
  2937.                        
  2938.                         oilAbilities.Clear();
  2939.                         weights.Clear();
  2940.                         dm.GetItemAbilitiesWithWeights(oilName, GetEntity() == thePlayer, oilAbilities, weights, tmpI, tmpJ);
  2941.                        
  2942.                         oilAttributes.Clear();
  2943.                         oilAttributes = dm.GetAbilitiesAttributes(oilAbilities);
  2944.                        
  2945.                         oilStatsCount = oilAttributes.Size();
  2946.                         for (idx = 0; idx < oilStatsCount; idx+=1)
  2947.                         {
  2948.                                 attributes.Remove(oilAttributes[idx]);
  2949.                         }
  2950.                 }
  2951.                
  2952.                 GetItemTooltipAttributes(itemId, attributes, itemStats);
  2953.         }
  2954.        
  2955.        
  2956.         public function GetItemStats(itemId : SItemUniqueId, out itemStats : array<SAttributeTooltip>)
  2957.         {
  2958.                 var attributes : array<name>;
  2959.                
  2960.                 GetItemAttributes(itemId, attributes);
  2961.                 GetItemTooltipAttributes(itemId, attributes, itemStats);
  2962.         }
  2963.        
  2964.         private function GetItemTooltipAttributes(itemId : SItemUniqueId, attributes : array<name>, out itemStats : array<SAttributeTooltip>):void
  2965.         {
  2966.                 var itemCategory:name;
  2967.                 var i, j, settingsSize : int;
  2968.                 var attributeString : string;
  2969.                 var attributeColor : string;
  2970.                 var attributeName : name;
  2971.                 var isPercentageValue : string;
  2972.                 var primaryStatLabel : string;
  2973.                 var statLabel            : string;
  2974.                
  2975.                 var stat : SAttributeTooltip;
  2976.                 var attributeVal : SAbilityAttributeValue;
  2977.                
  2978.                 settingsSize = theGame.tooltipSettings.GetNumRows();
  2979.                 itemStats.Clear();
  2980.                 itemCategory = GetItemCategory(itemId);
  2981.                 for(i=0; i<settingsSize; i+=1)
  2982.                 {
  2983.                        
  2984.                         attributeString = theGame.tooltipSettings.GetValueAt(0,i);
  2985.                         if(StrLen(attributeString) <= 0)
  2986.                                 continue;                                              
  2987.                        
  2988.                         attributeName = '';
  2989.                        
  2990.                        
  2991.                         for(j=0; j<attributes.Size(); j+=1)
  2992.                         {
  2993.                                 if(NameToString(attributes[j]) == attributeString)
  2994.                                 {
  2995.                                         attributeName = attributes[j];
  2996.                                         break;
  2997.                                 }
  2998.                         }
  2999.                         if(!IsNameValid(attributeName))
  3000.                                 continue;
  3001.                        
  3002.                        
  3003.                         if(itemCategory == 'silversword' && attributeName == 'SlashingDamage') continue;
  3004.                         if(itemCategory == 'steelsword' && attributeName == 'SilverDamage') continue;
  3005.                        
  3006.                        
  3007.                         attributeColor = theGame.tooltipSettings.GetValueAt(1,i);
  3008.                        
  3009.                         isPercentageValue = theGame.tooltipSettings.GetValueAt(2,i);   
  3010.                        
  3011.                        
  3012.                         attributeVal = GetItemAttributeValue(itemId, attributeName);
  3013.                         stat.attributeColor = attributeColor;
  3014.                         stat.percentageValue = isPercentageValue;                      
  3015.                         stat.primaryStat = IsPrimaryStatById(itemId, attributeName, primaryStatLabel);
  3016.                         stat.value = 0;
  3017.                         stat.originName = attributeName;
  3018.                         if(attributeVal.valueBase != 0)
  3019.                         {
  3020.                                 statLabel = GetAttributeNameLocStr(attributeName, false);
  3021.                                 stat.value = attributeVal.valueBase;
  3022.                         }
  3023.                         if(attributeVal.valueMultiplicative != 0)
  3024.                         {                              
  3025.                                
  3026.                                
  3027.                                 statLabel = GetAttributeNameLocStr(attributeName, false);
  3028.                                 stat.value = attributeVal.valueMultiplicative;
  3029.                                 stat.percentageValue = true;
  3030.                         }
  3031.                         if(attributeVal.valueAdditive != 0)
  3032.                         {                              
  3033.                                 statLabel = GetAttributeNameLocStr(attributeName, false);
  3034.                                 stat.value = attributeVal.valueAdditive;
  3035.                         }
  3036.                         if (stat.value != 0)
  3037.                         {
  3038.                                 stat.attributeName = statLabel;
  3039.                                
  3040.                                 itemStats.PushBack(stat);
  3041.                         }
  3042.                 }
  3043.         }
  3044.        
  3045.        
  3046.         public function GetItemStatsFromName(itemName : name, out itemStats : array<SAttributeTooltip>)
  3047.         {
  3048.                 var itemCategory : name;
  3049.                 var i, j, settingsSize : int;
  3050.                 var attributeString : string;
  3051.                 var attributeColor : string;
  3052.                 var attributeName : name;
  3053.                 var isPercentageValue : string;
  3054.                 var attributes, itemAbilities, tmpArray : array<name>;
  3055.                 var weights : array<float>;
  3056.                 var stat : SAttributeTooltip;
  3057.                 var attributeVal, min, max : SAbilityAttributeValue;
  3058.                 var dm  : CDefinitionsManagerAccessor;
  3059.                 var primaryStatLabel : string;
  3060.                 var statLabel            : string;
  3061.                
  3062.                 settingsSize = theGame.tooltipSettings.GetNumRows();
  3063.                 dm = theGame.GetDefinitionsManager();
  3064.                 dm.GetItemAbilitiesWithWeights(itemName, GetEntity() == thePlayer, itemAbilities, weights, i, j);
  3065.                 attributes = dm.GetAbilitiesAttributes(itemAbilities);
  3066.                
  3067.                 itemStats.Clear();
  3068.                 itemCategory = dm.GetItemCategory(itemName);
  3069.                 for(i=0; i<settingsSize; i+=1)
  3070.                 {
  3071.                        
  3072.                         attributeString = theGame.tooltipSettings.GetValueAt(0,i);
  3073.                         if(StrLen(attributeString) <= 0)
  3074.                                 continue;                                              
  3075.                        
  3076.                         attributeName = '';
  3077.                        
  3078.                        
  3079.                         for(j=0; j<attributes.Size(); j+=1)
  3080.                         {
  3081.                                 if(NameToString(attributes[j]) == attributeString)
  3082.                                 {
  3083.                                         attributeName = attributes[j];
  3084.                                         break;
  3085.                                 }
  3086.                         }
  3087.                         if(!IsNameValid(attributeName))
  3088.                                 continue;
  3089.                        
  3090.                        
  3091.                         if(itemCategory == 'silversword' && attributeName == 'SlashingDamage') continue;
  3092.                         if(itemCategory == 'steelsword' && attributeName == 'SilverDamage') continue;
  3093.                        
  3094.                        
  3095.                         attributeColor = theGame.tooltipSettings.GetValueAt(1,i);
  3096.                        
  3097.                         isPercentageValue = theGame.tooltipSettings.GetValueAt(2,i);
  3098.                        
  3099.                        
  3100.                         dm.GetAbilitiesAttributeValue(itemAbilities, attributeName, min, max);
  3101.                         attributeVal = GetAttributeRandomizedValue(min, max);
  3102.                        
  3103.                         stat.attributeColor = attributeColor;
  3104.                         stat.percentageValue = isPercentageValue;
  3105.                        
  3106.                         stat.primaryStat = IsPrimaryStat(itemCategory, attributeName, primaryStatLabel);
  3107.                        
  3108.                         stat.value = 0;
  3109.                         stat.originName = attributeName;
  3110.                        
  3111.                         if(attributeVal.valueBase != 0)
  3112.                         {
  3113.                                 stat.value = attributeVal.valueBase;
  3114.                         }
  3115.                         if(attributeVal.valueMultiplicative != 0)
  3116.                         {
  3117.                                 stat.value = attributeVal.valueMultiplicative;
  3118.                                 stat.percentageValue = true;
  3119.                         }
  3120.                         if(attributeVal.valueAdditive != 0)
  3121.                         {                              
  3122.                                 statLabel = GetAttributeNameLocStr(attributeName, false);
  3123.                                 stat.value = attributeVal.valueBase + attributeVal.valueAdditive;
  3124.                         }
  3125.                        
  3126.                         if (attributeName == 'toxicity_offset')
  3127.                         {
  3128.                                 statLabel = GetAttributeNameLocStr('toxicity', false);
  3129.                                 stat.percentageValue = false;
  3130.                         }
  3131.                         else
  3132.                         {
  3133.                                 statLabel = GetAttributeNameLocStr(attributeName, false);
  3134.                         }
  3135.                        
  3136.                         if (stat.value != 0)
  3137.                         {
  3138.                                 stat.attributeName = statLabel;
  3139.                                
  3140.                                 itemStats.PushBack(stat);
  3141.                         }
  3142.                        
  3143.                        
  3144.                 }
  3145.         }
  3146.        
  3147.         public function IsThereItemOnSlot(slot : EEquipmentSlots) : bool
  3148.         {
  3149.                 var player : W3PlayerWitcher;
  3150.                        
  3151.                 player = ((W3PlayerWitcher)GetEntity());
  3152.                 if(player)
  3153.                 {              
  3154.                         return player.IsAnyItemEquippedOnSlot(slot);
  3155.                 }
  3156.                 else
  3157.                 {
  3158.                         return false;
  3159.                 }
  3160.         }
  3161.        
  3162.         public function GetItemEquippedOnSlot(slot : EEquipmentSlots, out item : SItemUniqueId) : bool
  3163.         {
  3164.                 var player : W3PlayerWitcher;
  3165.                        
  3166.                 player = ((W3PlayerWitcher)GetEntity());
  3167.                 if(player)
  3168.                 {
  3169.                         return player.GetItemEquippedOnSlot(slot, item);
  3170.                 }
  3171.                 else
  3172.                 {
  3173.                         return false;
  3174.                 }
  3175.         }
  3176.        
  3177.         public function IsItemExcluded ( itemID : SItemUniqueId, excludedItems : array < SItemNameProperty > ) : bool
  3178.         {
  3179.                 var i                           : int;
  3180.                 var currItemName        : name;
  3181.                
  3182.                 currItemName = GetItemName( itemID );
  3183.                
  3184.                 for ( i = 0; i < excludedItems.Size(); i+=1 )
  3185.                 {
  3186.                         if ( currItemName == excludedItems[i].itemName )
  3187.                         {
  3188.                                 return true;
  3189.                         }
  3190.                 }
  3191.                 return false;
  3192.         }
  3193.        
  3194.        
  3195.         public function GetItemPrimaryStat(itemId : SItemUniqueId, out attributeLabel : string, out attributeVal : float ) : void
  3196.         {
  3197.                 var attributeName : name;
  3198.                 var attributeValue:SAbilityAttributeValue;
  3199.                
  3200.                 GetItemPrimaryStatImplById(itemId, attributeLabel, attributeVal, attributeName);
  3201.                
  3202.                 attributeValue = GetItemAttributeValue(itemId, attributeName);
  3203.                
  3204.                 if(attributeValue.valueBase != 0)
  3205.                 {
  3206.                         attributeVal = attributeValue.valueBase;
  3207.                 }
  3208.                 if(attributeValue.valueMultiplicative != 0)
  3209.                 {
  3210.                         attributeVal = attributeValue.valueMultiplicative;
  3211.                 }
  3212.                 if(attributeValue.valueAdditive != 0)
  3213.                 {
  3214.                         attributeVal = attributeValue.valueAdditive;
  3215.                 }
  3216.         }
  3217.        
  3218.         public function GetItemStatByName(itemName : name, statName : name, out resultValue : float) : void
  3219.         {
  3220.                 var dm : CDefinitionsManagerAccessor;
  3221.                 var attributes, itemAbilities : array<name>;
  3222.                 var min, max, attributeValue : SAbilityAttributeValue;
  3223.                 var tmpInt : int;
  3224.                 var tmpArray : array<float>;
  3225.                
  3226.                 dm = theGame.GetDefinitionsManager();
  3227.                 dm.GetItemAbilitiesWithWeights(itemName, GetEntity() == thePlayer, itemAbilities, tmpArray, tmpInt, tmpInt);
  3228.                 attributes = dm.GetAbilitiesAttributes(itemAbilities);
  3229.                
  3230.                 dm.GetAbilitiesAttributeValue(itemAbilities, statName, min, max);
  3231.                 attributeValue = GetAttributeRandomizedValue(min, max);
  3232.                
  3233.                 if(attributeValue.valueBase != 0)
  3234.                 {
  3235.                         resultValue = attributeValue.valueBase;
  3236.                 }
  3237.                 if(attributeValue.valueMultiplicative != 0)
  3238.                 {                                                              
  3239.                         resultValue = attributeValue.valueMultiplicative;
  3240.                 }
  3241.                 if(attributeValue.valueAdditive != 0)
  3242.                 {
  3243.                         resultValue = attributeValue.valueAdditive;
  3244.                 }
  3245.         }
  3246.        
  3247.         public function GetItemPrimaryStatFromName(itemName : name,  out attributeLabel : string, out attributeVal : float, out primAttrName : name) : void
  3248.         {
  3249.                 var dm : CDefinitionsManagerAccessor;
  3250.                 var attributeName : name;
  3251.                 var attributes, itemAbilities : array<name>;
  3252.                 var attributeValue, min, max : SAbilityAttributeValue;
  3253.                
  3254.                 var tmpInt : int;
  3255.                 var tmpArray : array<float>;
  3256.                
  3257.                 dm = theGame.GetDefinitionsManager();
  3258.                
  3259.                 GetItemPrimaryStatImpl(dm.GetItemCategory(itemName), attributeLabel, attributeVal, attributeName);
  3260.                 dm.GetItemAbilitiesWithWeights(itemName, GetEntity() == thePlayer, itemAbilities, tmpArray, tmpInt, tmpInt);
  3261.                 attributes = dm.GetAbilitiesAttributes(itemAbilities);
  3262.                 for (tmpInt = 0; tmpInt < attributes.Size(); tmpInt += 1)
  3263.                         if (attributes[tmpInt] == attributeName)
  3264.                         {
  3265.                                 dm.GetAbilitiesAttributeValue(itemAbilities, attributeName, min, max);
  3266.                                 attributeValue = GetAttributeRandomizedValue(min, max);
  3267.                                 primAttrName = attributeName;
  3268.                                 break;
  3269.                         }
  3270.                        
  3271.                 if(attributeValue.valueBase != 0)
  3272.                 {
  3273.                         attributeVal = attributeValue.valueBase;
  3274.                 }
  3275.                 if(attributeValue.valueMultiplicative != 0)
  3276.                 {                                                              
  3277.                         attributeVal = attributeValue.valueMultiplicative;
  3278.                 }
  3279.                 if(attributeValue.valueAdditive != 0)
  3280.                 {
  3281.                         attributeVal = attributeValue.valueAdditive;
  3282.                 }
  3283.                
  3284.         }
  3285.        
  3286.         public function IsPrimaryStatById(itemId : SItemUniqueId, attributeName : name, out attributeLabel : string) : bool
  3287.         {
  3288.                 var attrValue : float;
  3289.                 var attrName  : name;
  3290.                
  3291.                 GetItemPrimaryStatImplById(itemId, attributeLabel, attrValue, attrName);
  3292.                 return attrName == attributeName;
  3293.         }
  3294.        
  3295.         private function GetItemPrimaryStatImplById(itemId : SItemUniqueId, out attributeLabel : string, out attributeVal : float, out attributeName : name ) : void
  3296.         {
  3297.                 var itemOnSlot   : SItemUniqueId;
  3298.                 var categoryName : name;
  3299.                 var abList       : array<name>;
  3300.                
  3301.                 attributeName = '';
  3302.                 attributeLabel = "";
  3303.                 categoryName = GetItemCategory(itemId);
  3304.                
  3305.                
  3306.                 if (categoryName == 'bolt' || categoryName == 'petard')
  3307.                 {
  3308.                         GetItemAttributes(itemId, abList);
  3309.                         if (abList.Contains('FireDamage'))
  3310.                         {
  3311.                                 attributeName = 'FireDamage';
  3312.                         }
  3313.                         else if (abList.Contains('PiercingDamage'))
  3314.                         {
  3315.                                 attributeName = 'PiercingDamage';
  3316.                         }
  3317.                         else if (abList.Contains('PiercingDamage'))
  3318.                         {
  3319.                                 attributeName = 'PiercingDamage';
  3320.                         }
  3321.                         else if (abList.Contains('PoisonDamage'))
  3322.                         {
  3323.                                 attributeName = 'PoisonDamage';
  3324.                         }
  3325.                         else if (abList.Contains('BludgeoningDamage'))
  3326.                         {
  3327.                                 attributeName = 'BludgeoningDamage';
  3328.                         }
  3329.                         else                   
  3330.                         {
  3331.                                 attributeName = 'PhysicalDamage';
  3332.                         }
  3333.                         attributeLabel = GetAttributeNameLocStr(attributeName, false);
  3334.                 }
  3335.                 else if (categoryName == 'secondary')
  3336.                 {
  3337.                         GetItemAttributes(itemId, abList);
  3338.                         if (abList.Contains('BludgeoningDamage'))
  3339.                         {
  3340.                                 attributeName = 'BludgeoningDamage';
  3341.                         }
  3342.                         else
  3343.                         {
  3344.                                 attributeName = 'PhysicalDamage';
  3345.                         }
  3346.                         attributeLabel = GetAttributeNameLocStr(attributeName, false);
  3347.                 }
  3348.                 else if (categoryName == 'steelsword')
  3349.                 {
  3350.                         GetItemAttributes(itemId, abList);
  3351.                         if (abList.Contains('SlashingDamage'))
  3352.                         {
  3353.                                 attributeName = 'SlashingDamage';
  3354.                                 attributeLabel = GetLocStringByKeyExt("panel_inventory_tooltip_damage");
  3355.                         }
  3356.                         else if (abList.Contains('BludgeoningDamage'))
  3357.                         {
  3358.                                 attributeName = 'BludgeoningDamage';
  3359.                         }
  3360.                         else if (abList.Contains('PiercingDamage'))
  3361.                         {
  3362.                                 attributeName = 'PiercingDamage';
  3363.                         }
  3364.                         else
  3365.                         {
  3366.                                 attributeName = 'PhysicalDamage';
  3367.                         }
  3368.                         if (attributeLabel == "")
  3369.                         {
  3370.                                 attributeLabel = GetAttributeNameLocStr(attributeName, false);
  3371.                         }
  3372.                 }
  3373.                 else
  3374.                 {
  3375.                         GetItemPrimaryStatImpl(categoryName, attributeLabel, attributeVal, attributeName);
  3376.                 }
  3377.         }
  3378.        
  3379.         public function IsPrimaryStat(categoryName : name, attributeName : name, out attributeLabel : string) : bool
  3380.         {
  3381.                 var attrValue : float;
  3382.                 var attrName  : name;
  3383.                
  3384.                 GetItemPrimaryStatImpl(categoryName, attributeLabel, attrValue, attrName);
  3385.                 return attrName == attributeName;
  3386.         }
  3387.        
  3388.         private function GetItemPrimaryStatImpl(categoryName : name,  out attributeLabel : string, out attributeVal : float, out attributeName : name ) : void
  3389.         {
  3390.                 attributeName = '';
  3391.                 attributeLabel = "";
  3392.                 switch (categoryName)
  3393.                 {
  3394.                         case 'steelsword':
  3395.                                 attributeName = 'SlashingDamage';
  3396.                                 attributeLabel = GetLocStringByKeyExt("panel_inventory_tooltip_damage");
  3397.                                 break;
  3398.                         case 'silversword':
  3399.                                 attributeName = 'SilverDamage';
  3400.                                 attributeLabel = GetLocStringByKeyExt("panel_inventory_tooltip_damage");
  3401.                                 break;
  3402.                         case 'armor':
  3403.                         case 'gloves':
  3404.                         case 'gloves':
  3405.                         case 'boots':
  3406.                         case 'pants':
  3407.                                 attributeName = 'armor';
  3408.                                 break;
  3409.                         case 'potion':
  3410.                         case 'oil':
  3411.                                
  3412.                                 break;
  3413.                         case 'bolt':
  3414.                         case 'petard':
  3415.                                 attributeName = 'PhysicalDamage';
  3416.                                 break;
  3417.                         case 'crossbow':
  3418.                         default:
  3419.                                 attributeLabel = "";
  3420.                                 attributeVal = 0;
  3421.                                 return;
  3422.                                 break;
  3423.                 }
  3424.                
  3425.                 if (attributeLabel == "")
  3426.                 {
  3427.                         attributeLabel = GetAttributeNameLocStr(attributeName, false);
  3428.                 }
  3429.         }
  3430.        
  3431.         public function CanBeCompared(itemId : SItemUniqueId) : bool
  3432.         {
  3433.                 var wplayer                     : W3PlayerWitcher;
  3434.                 var itemSlot                    : EEquipmentSlots;
  3435.                 var equipedItem                 : SItemUniqueId;
  3436.                 var horseManager                : W3HorseManager;
  3437.                
  3438.                 var isArmorOrWeapon : bool;
  3439.                
  3440.                 if (IsItemHorseItem(itemId))
  3441.                 {
  3442.                         horseManager = GetWitcherPlayer().GetHorseManager();
  3443.                        
  3444.                         if (!horseManager)
  3445.                         {
  3446.                                 return false;
  3447.                         }
  3448.                        
  3449.                         if (horseManager.IsItemEquipped(itemId))
  3450.                         {
  3451.                                 return false;
  3452.                         }
  3453.                        
  3454.                         itemSlot = GetHorseSlotForItem(itemId);
  3455.                         equipedItem = horseManager.GetItemInSlot(itemSlot);
  3456.                         if (!horseManager.GetInventoryComponent().IsIdValid(equipedItem))
  3457.                         {
  3458.                                 return false;
  3459.                         }
  3460.                 }
  3461.                 else
  3462.                 {
  3463.                         isArmorOrWeapon = IsItemAnyArmor(itemId) || IsItemWeapon(itemId);
  3464.                         if (!isArmorOrWeapon)
  3465.                         {
  3466.                                 return false;
  3467.                         }
  3468.                        
  3469.                         wplayer = GetWitcherPlayer();
  3470.                         if (wplayer.IsItemEquipped(itemId))
  3471.                         {
  3472.                                 return false;
  3473.                         }
  3474.                        
  3475.                         itemSlot = GetSlotForItemId(itemId);           
  3476.                         wplayer.GetItemEquippedOnSlot(itemSlot, equipedItem);
  3477.                         if (!wplayer.inv.IsIdValid(equipedItem))
  3478.                         {
  3479.                                 return false;
  3480.                         }
  3481.                 }
  3482.                
  3483.                 return true;
  3484.         }
  3485.        
  3486.         public function GetHorseSlotForItem(id : SItemUniqueId) : EEquipmentSlots
  3487.         {
  3488.                 var tags : array<name>;
  3489.                
  3490.                 GetItemTags(id, tags);
  3491.                
  3492.                 if(tags.Contains('Saddle'))                             return EES_HorseSaddle;
  3493.                 else if(tags.Contains('HorseBag'))              return EES_HorseBag;
  3494.                 else if(tags.Contains('Trophy'))                return EES_HorseTrophy;
  3495.                 else if(tags.Contains('Blinders'))              return EES_HorseBlinders;
  3496.                 else                                                                    return EES_InvalidSlot;
  3497.         }
  3498.        
  3499.        
  3500.        
  3501.        
  3502.        
  3503.         public final function SingletonItemRefillAmmo( id : SItemUniqueId, optional alchemyTableUsed : bool )
  3504.         {
  3505.                 var l_bed               : W3WitcherBed;
  3506.                 var refilledByBed : bool;
  3507.                
  3508.                 refilledByBed = false;
  3509.                
  3510.                
  3511.                 if( FactsQuerySum( "PlayerInsideOuterWitcherHouse" ) >= 1 && FactsQuerySum( "AlchemyTableExists" ) >= 1 && !IsItemMutagenPotion( id ) )
  3512.                 {
  3513.                         l_bed = (W3WitcherBed)theGame.GetEntityByTag( 'witcherBed' );
  3514.                        
  3515.                         if( l_bed.GetWasUsed() || alchemyTableUsed )
  3516.                         {
  3517.                                 SetItemModifierInt( id, 'ammo_current', SingletonItemGetMaxAmmo(id) + theGame.params.QUANTITY_INCREASED_BY_ALCHEMY_TABLE ) ;
  3518.                                 refilledByBed = true;
  3519.                                 if( !l_bed.GetWereItemsRefilled() )
  3520.                                 {
  3521.                                         l_bed.SetWereItemsRefilled( true );
  3522.                                 }
  3523.                         }                      
  3524.                 }
  3525.                
  3526.                
  3527.                 if( !refilledByBed && SingletonItemGetAmmo( id ) < SingletonItemGetMaxAmmo( id ) )
  3528.                 {
  3529.                         SetItemModifierInt(id, 'ammo_current', SingletonItemGetMaxAmmo(id));
  3530.                 }
  3531.                
  3532.                 theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_OnAmmoChanged );
  3533.         }
  3534.        
  3535.         public function SingletonItemSetAmmo(id : SItemUniqueId, quantity : int)
  3536.         {
  3537.                 var amount : int;
  3538.                
  3539.                 if(ItemHasTag(id, theGame.params.TAG_INFINITE_AMMO))
  3540.                 {
  3541.                         amount = -1;
  3542.                 }
  3543.                 else
  3544.                 {
  3545.                         amount = Clamp(quantity, 0, SingletonItemGetMaxAmmo(id));
  3546.                 }
  3547.                
  3548.                 SetItemModifierInt(id, 'ammo_current', amount);
  3549.                 theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_OnAmmoChanged );
  3550.         }
  3551.        
  3552.         public function SingletonItemAddAmmo(id : SItemUniqueId, quantity : int)
  3553.         {
  3554.                 var ammo : int;
  3555.                
  3556.                 if(quantity <= 0)
  3557.                         return;
  3558.                        
  3559.                 ammo = GetItemModifierInt(id, 'ammo_current');
  3560.                
  3561.                 if(ammo == -1)
  3562.                         return;
  3563.                        
  3564.                 ammo = Clamp(ammo + quantity, 0, SingletonItemGetMaxAmmo(id));
  3565.                 SetItemModifierInt(id, 'ammo_current', ammo);
  3566.                 theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_OnAmmoChanged );
  3567.         }
  3568.        
  3569.         public function SingletonItemsRefillAmmo( optional alchemyTableUsed : bool ) : bool
  3570.         {
  3571.                 var i : int;
  3572.                 var singletonItems : array<SItemUniqueId>;
  3573.                 var alco : SItemUniqueId;
  3574.                 var arrStr : array<string>;
  3575.                 var witcher : W3PlayerWitcher;
  3576.                 var itemLabel : string;
  3577.        
  3578.                 witcher = GetWitcherPlayer();
  3579.                 if(GetEntity() == witcher && HasNotFilledSingletonItem( alchemyTableUsed ) )
  3580.                 {
  3581.                         alco = witcher.GetAlcoholForAlchemicalItemsRefill();
  3582.                
  3583.                         if(!IsIdValid(alco))
  3584.                         {
  3585.                                
  3586.                                 theGame.GetGuiManager().ShowNotification(GetLocStringByKeyExt("message_common_alchemy_items_cannot_refill"));
  3587.                                 theSound.SoundEvent("gui_global_denied");
  3588.                                
  3589.                                 return false;
  3590.                         }
  3591.                         else
  3592.                         {
  3593.                                
  3594.                                 arrStr.PushBack(GetItemName(alco));
  3595.                                 itemLabel = GetLocStringByKeyExt(GetItemLocalizedNameByUniqueID(alco));
  3596.                                 theGame.GetGuiManager().ShowNotification( itemLabel + " - " + GetLocStringByKeyExtWithParams("message_common_alchemy_items_refilled", , , arrStr));
  3597.                                 theSound.SoundEvent("gui_alchemy_brew");
  3598.                                
  3599.                                 if(!ItemHasTag(alco, theGame.params.TAG_INFINITE_USE))
  3600.                                         RemoveItem(alco);
  3601.                         }
  3602.                 }
  3603.                
  3604.                 singletonItems = GetSingletonItems();
  3605.                 for(i=0; i<singletonItems.Size(); i+=1)
  3606.                 {                      
  3607.                         SingletonItemRefillAmmo( singletonItems[i], alchemyTableUsed );
  3608.                 }
  3609.                
  3610.                 return true;
  3611.         }
  3612.        
  3613.         public function SingletonItemsRefillAmmoNoAlco(optional dontUpdateUI : bool)
  3614.         {
  3615.                 var i : int;
  3616.                 var singletonItems : array<SItemUniqueId>;
  3617.                 var alco : SItemUniqueId;
  3618.                 var arrStr : array<string>;
  3619.                 var witcher : W3PlayerWitcher;
  3620.                 var itemLabel : string;
  3621.        
  3622.                 witcher = GetWitcherPlayer();
  3623.                 if(!dontUpdateUI && GetEntity() == witcher && HasNotFilledSingletonItem())
  3624.                 {
  3625.                        
  3626.                         arrStr.PushBack(GetItemName(alco));
  3627.                         itemLabel = GetLocStringByKeyExt(GetItemLocalizedNameByUniqueID(alco));
  3628.                         theGame.GetGuiManager().ShowNotification( itemLabel + " - " + GetLocStringByKeyExtWithParams("message_common_alchemy_items_refilled", , , arrStr));
  3629.                         theSound.SoundEvent("gui_alchemy_brew");
  3630.                 }
  3631.                
  3632.                 singletonItems = GetSingletonItems();
  3633.                 for(i=0; i<singletonItems.Size(); i+=1)
  3634.                 {                      
  3635.                         SingletonItemRefillAmmo(singletonItems[i]);
  3636.                 }
  3637.         }      
  3638.        
  3639.        
  3640.         private final function HasNotFilledSingletonItem( optional alchemyTableUsed : bool ) : bool
  3641.         {
  3642.                 var i : int;
  3643.                 var singletonItems : array<SItemUniqueId>;
  3644.                 var hasLab : bool;
  3645.                 var l_bed : W3WitcherBed;
  3646.                
  3647.                
  3648.                 hasLab = false;
  3649.                 if( FactsQuerySum( "PlayerInsideOuterWitcherHouse" ) >= 1 && FactsQuerySum( "AlchemyTableExists" ) >= 1 )
  3650.                 {
  3651.                         l_bed = (W3WitcherBed)theGame.GetEntityByTag( 'witcherBed' );                  
  3652.                         if( l_bed.GetWasUsed() || alchemyTableUsed )
  3653.                         {
  3654.                                 hasLab = true;
  3655.                         }
  3656.                 }
  3657.                
  3658.                 singletonItems = GetSingletonItems();
  3659.                 for(i=0; i<singletonItems.Size(); i+=1)
  3660.                 {                      
  3661.                         if( hasLab && !IsItemMutagenPotion( singletonItems[i] ) )
  3662.                         {
  3663.                                 if(SingletonItemGetAmmo(singletonItems[i]) <= SingletonItemGetMaxAmmo(singletonItems[i]))
  3664.                                 {
  3665.                                         return true;
  3666.                                 }
  3667.                         }
  3668.                         else if(SingletonItemGetAmmo(singletonItems[i]) < SingletonItemGetMaxAmmo(singletonItems[i]))
  3669.                         {
  3670.                                 return true;
  3671.                         }
  3672.                 }
  3673.                
  3674.                 return false;
  3675.         }
  3676.        
  3677.         public function SingletonItemRemoveAmmo(itemID : SItemUniqueId, optional quantity : int)
  3678.         {
  3679.                 var ammo : int;
  3680.                
  3681.                 if(!IsItemSingletonItem(itemID) || ItemHasTag(itemID, theGame.params.TAG_INFINITE_AMMO))
  3682.                         return;
  3683.                
  3684.                 if(quantity <= 0)
  3685.                         quantity = 1;
  3686.                        
  3687.                 ammo = GetItemModifierInt(itemID, 'ammo_current');
  3688.                 ammo = Max(0, ammo - quantity);
  3689.                 SetItemModifierInt(itemID, 'ammo_current', ammo);
  3690.                
  3691.                
  3692.                 if(ammo == 0 && ShouldProcessTutorial('TutorialAlchemyRefill') && FactsQuerySum("q001_nightmare_ended") > 0)
  3693.                 {
  3694.                         FactsAdd('tut_alch_refill', 1);
  3695.                 }
  3696.                 theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_OnAmmoChanged );
  3697.         }
  3698.        
  3699.         public function SingletonItemGetAmmo(itemID : SItemUniqueId) : int
  3700.         {
  3701.                 if(!IsItemSingletonItem(itemID))
  3702.                         return 0;
  3703.                
  3704.                 return GetItemModifierInt(itemID, 'ammo_current');
  3705.         }
  3706.        
  3707.         public function SingletonItemGetMaxAmmo(itemID : SItemUniqueId) : int
  3708.         {
  3709.                 var ammo, i : int;
  3710.                 var perk20Bonus, min, max : SAbilityAttributeValue;
  3711.                 var atts : array<name>;
  3712.                 var canUseSkill : bool;
  3713.                
  3714.                 ammo = RoundMath(CalculateAttributeValue(GetItemAttributeValue(itemID, 'ammo')));
  3715.                
  3716.                 if( !ItemHasTag( itemID, 'NoAdditionalAmmo' ) )
  3717.                 {
  3718.                         if(GetEntity() == GetWitcherPlayer() && ammo > 0)
  3719.                         {
  3720.                                 if(IsItemBomb(itemID) && thePlayer.CanUseSkill(S_Alchemy_s08) )
  3721.                                 {
  3722.                                         ammo += thePlayer.GetSkillLevel(S_Alchemy_s08);
  3723.                                 }
  3724.                                
  3725.                                 if(thePlayer.HasBuff(EET_Mutagen03) && (IsItemBomb(itemID) || (!IsItemMutagenPotion(itemID) && IsItemPotion(itemID))) )
  3726.                                 {
  3727.                                         ammo += 1;
  3728.                                 }
  3729.                                
  3730.                                 //LZ_SLOTS_BEGIN
  3731.                                 if( GetWitcherPlayer().IsMutationActive( EPMT_Mutation15 ) && IsItemMutagenPotion(itemID) )
  3732.                                 {
  3733.                                         theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation15', 'extra_charges', min, max );
  3734.                                         ammo += (int)min.valueAdditive;
  3735.                                 }
  3736.                                 //LZ_SLOTS_END
  3737.  
  3738.                                 if( GetWitcherPlayer().IsSetBonusActive( EISB_RedWolf_2 ) && !IsItemMutagenPotion(itemID) )
  3739.                                 {
  3740.                                         theGame.GetDefinitionsManager().GetAbilityAttributeValue( GetSetBonusAbility( EISB_RedWolf_2 ), 'amount', min, max);
  3741.                                         ammo += (int)min.valueAdditive;
  3742.                                 }
  3743.                                                        
  3744.                                
  3745.                                 if( IsItemBomb( itemID ) && thePlayer.CanUseSkill( S_Perk_20 ) &&  GetItemName( itemID ) != 'Snow Ball' )
  3746.                                 {
  3747.                                         GetItemAttributes( itemID, atts );
  3748.                                         canUseSkill = thePlayer.CanUseSkill( S_Alchemy_s10 );
  3749.                                         perk20Bonus = GetWitcherPlayer().GetSkillAttributeValue( S_Perk_20, 'stack_multiplier', false, false );
  3750.                                        
  3751.                                         for( i=0 ; i<atts.Size() ; i+=1 )
  3752.                                         {
  3753.                                                 if( canUseSkill || IsDamageTypeNameValid( atts[i] ) )
  3754.                                                 {
  3755.                                                         ammo = RoundMath( ammo * perk20Bonus.valueMultiplicative );
  3756.                                                         break;
  3757.                                                 }
  3758.                                         }                              
  3759.                                 }
  3760.                         }
  3761.                 }
  3762.                
  3763.                 return ammo;
  3764.         }
  3765.        
  3766.         public function ManageSingletonItemsBonus()
  3767.         {
  3768.                 var l_items                     : array<SItemUniqueId>;
  3769.                 var l_i                         : int;
  3770.                 var l_haveBombOrPot     : bool;
  3771.                
  3772.                 l_items = GetSingletonItems();
  3773.  
  3774.                 for( l_i = 0 ; l_i < l_items.Size() ; l_i += 1 )
  3775.                 {
  3776.                         if( IsItemPotion( l_items[ l_i ] ) || IsItemBomb( l_items[ l_i ] ) )
  3777.                         {
  3778.                                 l_haveBombOrPot = true;
  3779.                                 if( SingletonItemGetMaxAmmo( l_items[ l_i ] ) >= SingletonItemGetAmmo( l_items[ l_i ] ) )
  3780.                                 {
  3781.                                         if( SingletonItemsRefillAmmo( true ) )
  3782.                                         {
  3783.                                                 theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt( "message_common_alchemy_table_buff_applied" ),, true );
  3784.                                         }
  3785.                                        
  3786.                                         return;
  3787.                                 }
  3788.                         }
  3789.                 }
  3790.                
  3791.                 if( !l_haveBombOrPot )
  3792.                 {
  3793.                         theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt( "message_common_alchemy_table_buff_no_items" ),, true );
  3794.                         return;
  3795.                 }
  3796.                
  3797.                 theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt( "message_common_alchemy_table_buff_already_on" ),, true );
  3798.         }
  3799.        
  3800.        
  3801.        
  3802.        
  3803.        
  3804.         public final function IsItemSteelSwordUsableByPlayer(item : SItemUniqueId) : bool
  3805.         {
  3806.                 return ItemHasTag(item, theGame.params.TAG_PLAYER_STEELSWORD) && !ItemHasTag(item, 'SecondaryWeapon');
  3807.         }
  3808.        
  3809.         public final function IsItemSilverSwordUsableByPlayer(item : SItemUniqueId) : bool
  3810.         {
  3811.                 return ItemHasTag(item, theGame.params.TAG_PLAYER_SILVERSWORD) && !ItemHasTag(item, 'SecondaryWeapon');
  3812.         }
  3813.  
  3814.         public final function IsItemFists(item : SItemUniqueId) : bool                                                  {return GetItemCategory(item) == 'fist';}
  3815.         public final function IsItemWeapon(item : SItemUniqueId) : bool                                                 {return ItemHasTag(item, 'Weapon') || ItemHasTag(item, 'WeaponTab');}
  3816.         public final function IsItemCrossbow(item : SItemUniqueId) : bool                                               {return GetItemCategory(item) == 'crossbow';}
  3817.         public final function IsItemChestArmor(item : SItemUniqueId) : bool                                             {return GetItemCategory(item) == 'armor';}
  3818.         public final function IsItemBody(item : SItemUniqueId) : bool                                                   {return ItemHasTag(item, 'Body');}
  3819.         public final function IsRecipeOrSchematic( item : SItemUniqueId ) : bool                                {return GetItemCategory(item) == 'alchemy_recipe' || GetItemCategory(item) == 'crafting_schematic'; }
  3820.         public final function IsItemBoots(item : SItemUniqueId) : bool                                                  {return GetItemCategory(item) == 'boots';}
  3821.         public final function IsItemGloves(item : SItemUniqueId) : bool                                                 {return GetItemCategory(item) == 'gloves';}
  3822.         public final function IsItemPants(item : SItemUniqueId) : bool                                                  {return GetItemCategory(item) == 'trousers' || GetItemCategory(item) == 'pants';}
  3823.         public final function IsItemTrophy(item : SItemUniqueId) : bool                                                 {return GetItemCategory(item) == 'trophy';}
  3824.         public final function IsItemMask(item : SItemUniqueId) : bool                                                   {return GetItemCategory(item) == 'mask';}
  3825.         public final function IsItemBomb(item : SItemUniqueId) : bool                                                   {return GetItemCategory(item) == 'petard';}
  3826.         public final function IsItemBolt(item : SItemUniqueId) : bool                                                   {return GetItemCategory(item) == 'bolt';}
  3827.         public final function IsItemUpgrade(item : SItemUniqueId) : bool                                                {return GetItemCategory(item) ==  'upgrade';}
  3828.         public final function IsItemTool(item : SItemUniqueId) : bool                                                   {return GetItemCategory(item) ==  'tool';}
  3829.         public final function IsItemPotion(item : SItemUniqueId) : bool                                                 {return ItemHasTag(item, 'Potion');}
  3830.         public final function IsItemOil(item : SItemUniqueId) : bool                                                    {return ItemHasTag(item, 'SilverOil') || ItemHasTag(item, 'SteelOil');}
  3831.         public final function IsItemAnyArmor(item : SItemUniqueId) : bool                                               {return ItemHasTag(item, theGame.params.TAG_ARMOR);}
  3832.         public final function IsItemUpgradeable(item : SItemUniqueId) : bool                                    {return ItemHasTag(item, theGame.params.TAG_ITEM_UPGRADEABLE);}
  3833.         public final function IsItemIngredient(item : SItemUniqueId) : bool                                             {return ItemHasTag(item, 'AlchemyIngredient') || ItemHasTag(item, 'CraftingIngredient');}
  3834.         public final function IsItemDismantleKit(item : SItemUniqueId) : bool                                   {return ItemHasTag(item, 'DismantleKit');}
  3835.         public final function IsItemHorseBag(item : SItemUniqueId) : bool                                               {return ItemHasTag(item, 'HorseBag');} 
  3836.         public final function IsItemReadable(item : SItemUniqueId) : bool                                               {return ItemHasTag(item, 'ReadableItem');}
  3837.         public final function IsItemAlchemyItem(item : SItemUniqueId) : bool                                    {return IsItemOil(item) || IsItemPotion(item) || IsItemBomb(item);  }  
  3838.         public final function IsItemSingletonItem(item : SItemUniqueId) : bool                                  {return ItemHasTag(item, theGame.params.TAG_ITEM_SINGLETON);}
  3839.         public final function IsItemQuest(item : SItemUniqueId) : bool                                                  {return ItemHasTag(item, 'Quest');}
  3840.         public final function IsItemFood(item : SItemUniqueId) : bool                                                   {return ItemHasTag(item, 'Edibles') || ItemHasTag(item, 'Drinks');}
  3841.         public final function IsItemSecondaryWeapon(item : SItemUniqueId) : bool                                {return ItemHasTag(item, 'SecondaryWeapon');}
  3842.         public final function IsItemHorseItem(item: SItemUniqueId) : bool                                               {return ItemHasTag(item, 'Saddle') || ItemHasTag(item, 'HorseBag') || ItemHasTag(item, 'Trophy') || ItemHasTag(item, 'Blinders'); }
  3843.         public final function IsItemSaddle(item: SItemUniqueId) : bool                                                  {return ItemHasTag(item, 'Saddle');}
  3844.         public final function IsItemBlinders(item: SItemUniqueId) : bool                                                {return ItemHasTag(item, 'Blinders');}
  3845.         public final function IsItemDye( item : SItemUniqueId ) : bool                                                  { return ItemHasTag( item, 'mod_dye' ); }
  3846.         public final function IsItemUsable( item : SItemUniqueId ) : bool                                               { return GetItemCategory( item ) == 'usable'; }
  3847.         public final function IsItemJunk( item : SItemUniqueId ) : bool                                                 { return ItemHasTag( item,'junk' ) || GetItemCategory( item ) == 'junk' ; }
  3848.         public final function IsItemAlchemyIngredient(item : SItemUniqueId) : bool                              { return ItemHasTag( item, 'AlchemyIngredient' ); }
  3849.         public final function IsItemCraftingIngredient(item : SItemUniqueId) : bool                             { return ItemHasTag( item, 'CraftingIngredient' ); }
  3850.         public final function IsItemArmorReapairKit(item : SItemUniqueId) : bool                                { return ItemHasTag( item, 'ArmorReapairKit' ); }
  3851.         public final function IsItemWeaponReapairKit(item : SItemUniqueId) : bool                               { return ItemHasTag( item, 'WeaponReapairKit' ); }
  3852.         public final function IsQuickSlotItem( item : SItemUniqueId ) : bool                                    { return ItemHasTag( item, 'QuickSlot' ); }
  3853.        
  3854.         public final function IsItemNew( item : SItemUniqueId ) : bool
  3855.         {
  3856.                 var uiData : SInventoryItemUIData;
  3857.                
  3858.                 uiData = GetInventoryItemUIData( item );
  3859.                 return uiData.isNew;
  3860.         }
  3861.        
  3862.         public final function IsItemMutagenPotion(item : SItemUniqueId) : bool
  3863.         {
  3864.                 return IsItemPotion(item) && ItemHasTag(item, 'Mutagen');
  3865.         }
  3866.        
  3867.         public final function CanItemBeColored( item : SItemUniqueId) : bool
  3868.         {
  3869.                 if ( RoundMath( CalculateAttributeValue( GetItemAttributeValue( item, 'quality' ) ) ) == 5 )
  3870.                 {
  3871.                         return true;
  3872.                 }
  3873.                 return false;  
  3874.         }
  3875.  
  3876.         public final function IsItemSetItem(item : SItemUniqueId) : bool
  3877.         {
  3878.                 return
  3879.                         ItemHasTag(item, theGame.params.ITEM_SET_TAG_BEAR) ||
  3880.                         ItemHasTag(item, theGame.params.ITEM_SET_TAG_GRYPHON) ||
  3881.                         ItemHasTag(item, theGame.params.ITEM_SET_TAG_LYNX) ||
  3882.                         ItemHasTag(item, theGame.params.ITEM_SET_TAG_WOLF) ||
  3883.                         ItemHasTag(item, theGame.params.ITEM_SET_TAG_RED_WOLF) ||
  3884.                         ItemHasTag( item, theGame.params.ITEM_SET_TAG_VAMPIRE ) ||
  3885.                         ItemHasTag(item, theGame.params.ITEM_SET_TAG_VIPER);
  3886.         }
  3887.        
  3888.         public function GetArmorType(item : SItemUniqueId) : EArmorType
  3889.         {
  3890.                 var isItemEquipped : bool;
  3891.                
  3892.                 isItemEquipped = GetWitcherPlayer().IsItemEquipped(item);
  3893.                
  3894.                
  3895.                 if( thePlayer.HasAbility('Glyphword 2 _Stats', true) && isItemEquipped )
  3896.                 {return EAT_Light;}
  3897.                 if( thePlayer.HasAbility('Glyphword 3 _Stats', true) && isItemEquipped )
  3898.                 {return EAT_Medium;}
  3899.                 if( thePlayer.HasAbility('Glyphword 4 _Stats', true) && isItemEquipped )
  3900.                 {return EAT_Heavy;}
  3901.        
  3902.                 if(ItemHasTag(item, 'LightArmor'))
  3903.                         return EAT_Light;
  3904.                 else if(ItemHasTag(item, 'MediumArmor'))
  3905.                         return EAT_Medium;
  3906.                 else if(ItemHasTag(item, 'HeavyArmor'))
  3907.                         return EAT_Heavy;
  3908.                
  3909.                 return EAT_Undefined;
  3910.         }
  3911.        
  3912.         public final function GetAlchemyCraftableItems() : array<SItemUniqueId>
  3913.         {
  3914.                 var items : array<SItemUniqueId>;
  3915.                 var i : int;
  3916.                
  3917.                 GetAllItems(items);
  3918.                
  3919.                 for(i=items.Size()-1; i>=0; i-=1)
  3920.                 {
  3921.                         if(!IsItemPotion(items[i]) && !IsItemBomb(items[i]) && !IsItemOil(items[i]))
  3922.                                 items.EraseFast(i);
  3923.                 }
  3924.                
  3925.                 return items;
  3926.         }
  3927.        
  3928.         public function IsItemEncumbranceItem(item : SItemUniqueId) : bool
  3929.         {
  3930.                 if(ItemHasTag(item, theGame.params.TAG_ENCUMBRANCE_ITEM_FORCE_YES))
  3931.                         return true;
  3932.                        
  3933.                 if(ItemHasTag(item, theGame.params.TAG_ENCUMBRANCE_ITEM_FORCE_NO))
  3934.                         return false;
  3935.  
  3936.                
  3937.                 if (
  3938.                                 IsRecipeOrSchematic( item )
  3939.                         ||      IsItemBody( item )
  3940.                
  3941.                
  3942.                
  3943.                
  3944.                
  3945.                
  3946.                
  3947.                
  3948.                
  3949.                
  3950.                
  3951.                
  3952.                         )
  3953.                         return false;
  3954.  
  3955.                 return true;
  3956.         }
  3957.        
  3958.         public function GetItemEncumbrance(item : SItemUniqueId) : float
  3959.         {
  3960.                 var itemCategory : name;
  3961.                 if ( IsItemEncumbranceItem( item ) )
  3962.                 {
  3963.                         itemCategory = GetItemCategory( item );
  3964.                         if ( itemCategory == 'quest' || itemCategory == 'key' )
  3965.                         {
  3966.                                 return 0.01 * GetItemQuantity( item );
  3967.                         }
  3968.                         else if ( itemCategory == 'usable' || itemCategory == 'upgrade' || itemCategory == 'junk' )
  3969.                         {
  3970.                                 return 0.01 + GetItemWeight( item ) * GetItemQuantity( item ) * 0.2;
  3971.                         }
  3972.                         else if ( IsItemAlchemyItem( item ) || IsItemIngredient( item ) || IsItemFood( item ) || IsItemReadable( item ) )
  3973.                         {
  3974.                                 return 0.0;
  3975.                         }
  3976.                         else
  3977.                         {
  3978.                                 return 0.01 + GetItemWeight( item ) * GetItemQuantity( item ) * 0.5;
  3979.                         }
  3980.                 }
  3981.                 return 0;
  3982.         }
  3983.        
  3984.         public function GetFilterTypeByItem( item : SItemUniqueId ) : EInventoryFilterType
  3985.         {
  3986.                 var filterType : EInventoryFilterType;
  3987.                                        
  3988.                 if( ItemHasTag( item, 'Quest' ) )
  3989.                 {
  3990.                         return IFT_QuestItems;
  3991.                 }                              
  3992.                 else if( IsItemIngredient( item ) )
  3993.                 {
  3994.                         return IFT_Ingredients;
  3995.                 }                              
  3996.                 else if( IsItemAlchemyItem(item) )
  3997.                 {
  3998.                         return IFT_AlchemyItems;
  3999.                 }                              
  4000.                 else if( IsItemAnyArmor(item) )
  4001.                 {
  4002.                         return IFT_Armors;
  4003.                 }                              
  4004.                 else if( IsItemWeapon( item ) )
  4005.                 {
  4006.                         return IFT_Weapons;
  4007.                 }                              
  4008.                 else
  4009.                 {
  4010.                         return IFT_Default;
  4011.                 }
  4012.         }      
  4013.        
  4014.        
  4015.         public function IsItemQuickslotItem(item : SItemUniqueId) : bool
  4016.         {
  4017.                 return IsSlotQuickslot( GetSlotForItemId(item) );
  4018.         }
  4019.        
  4020.         public function GetCrossbowAmmo(id : SItemUniqueId) : int
  4021.         {
  4022.                 if(!IsItemCrossbow(id))
  4023.                         return -1;
  4024.                        
  4025.                 return (int)CalculateAttributeValue(GetItemAttributeValue(id, 'ammo'));
  4026.         }
  4027.                
  4028.        
  4029.        
  4030.         public function GetSlotForItemId(item : SItemUniqueId) : EEquipmentSlots
  4031.         {
  4032.                 var tags : array<name>;
  4033.                 var player : W3PlayerWitcher;
  4034.                 var slot : EEquipmentSlots;
  4035.                
  4036.                 player = ((W3PlayerWitcher)GetEntity());
  4037.                
  4038.                 GetItemTags(item, tags);
  4039.                 slot = GetSlotForItem( GetItemCategory(item), tags, player );
  4040.                
  4041.                 if(!player)
  4042.                         return slot;
  4043.                
  4044.                 if(IsMultipleSlot(slot))
  4045.                 {
  4046.                         if(slot == EES_Petard1 && player.IsAnyItemEquippedOnSlot(slot))
  4047.                         {
  4048.                                 if(!player.IsAnyItemEquippedOnSlot(EES_Petard2))
  4049.                                         slot = EES_Petard2;
  4050.                         }
  4051.                         else if(slot == EES_Quickslot1 && player.IsAnyItemEquippedOnSlot(slot))
  4052.                         {
  4053.                                 if(!player.IsAnyItemEquippedOnSlot(EES_Quickslot2))
  4054.                                         slot = EES_Quickslot2;
  4055.                         }
  4056.                         else if(slot == EES_Potion1 && player.IsAnyItemEquippedOnSlot(EES_Potion1))
  4057.                         {
  4058.                                 if(!player.IsAnyItemEquippedOnSlot(EES_Potion2))
  4059.                                 {
  4060.                                         slot = EES_Potion2;
  4061.                                 }
  4062.                                 else
  4063.                                 {
  4064.                                         if(!player.IsAnyItemEquippedOnSlot(EES_Potion3))
  4065.                                         {
  4066.                                                 slot = EES_Potion3;
  4067.                                         }
  4068.                                         else
  4069.                                         {
  4070.                                                 if(!player.IsAnyItemEquippedOnSlot(EES_Potion4))
  4071.                                                 {
  4072.                                                         slot = EES_Potion4;
  4073.                                                 }
  4074.                                         }
  4075.                                 }
  4076.                         }
  4077.                         else if(slot == EES_PotionMutagen1 && player.IsAnyItemEquippedOnSlot(slot))
  4078.                         {
  4079.                                 if(!player.IsAnyItemEquippedOnSlot(EES_PotionMutagen2))
  4080.                                 {
  4081.                                         slot = EES_PotionMutagen2;
  4082.                                 }
  4083.                                 else
  4084.                                 {
  4085.                                         if(!player.IsAnyItemEquippedOnSlot(EES_PotionMutagen3))
  4086.                                         {
  4087.                                                 slot = EES_PotionMutagen3;
  4088.                                         }
  4089.                                         else
  4090.                                         {
  4091.                                                 if(!player.IsAnyItemEquippedOnSlot(EES_PotionMutagen4))
  4092.                                                 {
  4093.                                                         slot = EES_PotionMutagen4;
  4094.                                                 }
  4095.                                         }
  4096.                                 }
  4097.                         }
  4098.                         else if(slot == EES_SkillMutagen1 && player.IsAnyItemEquippedOnSlot(slot))
  4099.                         {
  4100.                                 if(!player.IsAnyItemEquippedOnSlot(EES_SkillMutagen2))
  4101.                                 {
  4102.                                         slot = EES_SkillMutagen2;
  4103.                                 }
  4104.                                 else
  4105.                                 {
  4106.                                         if(!player.IsAnyItemEquippedOnSlot(EES_SkillMutagen3))
  4107.                                         {
  4108.                                                 slot = EES_SkillMutagen3;
  4109.                                         }
  4110.                                         else
  4111.                                         {
  4112.                                                 if(!player.IsAnyItemEquippedOnSlot(EES_SkillMutagen4))
  4113.                                                 {
  4114.                                                         slot = EES_SkillMutagen4;
  4115.                                                 }
  4116.                                         }
  4117.                                 }
  4118.                         }
  4119.                 }
  4120.                
  4121.                 return slot;
  4122.         }
  4123.        
  4124.        
  4125.        
  4126.         public function GetAllWeapons() : array<SItemUniqueId>
  4127.         {
  4128.                 return GetItemsByTag('Weapon');
  4129.         }
  4130.        
  4131.        
  4132.         public function GetSpecifiedPlayerItemsQuest(steelSword, silverSword, armor, boots, gloves, pants, trophy, mask, bombs, crossbow, secondaryWeapon, equippedOnly : bool) : array<SItemUniqueId>
  4133.         {      
  4134.                 var items, allItems : array<SItemUniqueId>;
  4135.                 var i : int;
  4136.        
  4137.                 GetAllItems(allItems);
  4138.                
  4139.                 for(i=0; i<allItems.Size(); i+=1)
  4140.                 {
  4141.                         if(
  4142.                                 (steelSword && IsItemSteelSwordUsableByPlayer(allItems[i])) ||
  4143.                                 (silverSword && IsItemSilverSwordUsableByPlayer(allItems[i])) ||
  4144.                                 (armor && IsItemChestArmor(allItems[i])) ||
  4145.                                 (boots && IsItemBoots(allItems[i])) ||
  4146.                                 (gloves && IsItemGloves(allItems[i])) ||
  4147.                                 (pants && IsItemPants(allItems[i])) ||
  4148.                                 (trophy && IsItemTrophy(allItems[i])) ||
  4149.                                 (mask && IsItemMask(allItems[i])) ||
  4150.                                 (bombs && IsItemBomb(allItems[i])) ||
  4151.                                 (crossbow && (IsItemCrossbow(allItems[i]) || IsItemBolt(allItems[i]))) ||
  4152.                                 (secondaryWeapon && IsItemSecondaryWeapon(allItems[i]))
  4153.                         )
  4154.                         {
  4155.                                 if(!equippedOnly || (equippedOnly && ((W3PlayerWitcher)GetEntity()) && GetWitcherPlayer().IsItemEquipped(allItems[i])) )
  4156.                                 {
  4157.                                         if(!ItemHasTag(allItems[i], 'NoDrop'))
  4158.                                                 items.PushBack(allItems[i]);
  4159.                                 }
  4160.                         }
  4161.                 }
  4162.                
  4163.                 return items;          
  4164.         }      
  4165.        
  4166.  
  4167.         event OnItemAboutToGive( itemId : SItemUniqueId, quantity : int )
  4168.         {
  4169.                 if(GetEntity() == GetWitcherPlayer())
  4170.                 {
  4171.                         if( IsItemSteelSwordUsableByPlayer( itemId ) || IsItemSilverSwordUsableByPlayer( itemId ) )
  4172.                         {
  4173.                                 RemoveAllOilsFromItem( itemId );
  4174.                         }
  4175.                 }
  4176.         }
  4177.        
  4178.        
  4179.         event OnItemRemoved( itemId : SItemUniqueId, quantity : int )
  4180.         {
  4181.                 var ent                         : CGameplayEntity;
  4182.                 var crossbows : array<SItemUniqueId>;
  4183.                 var witcher : W3PlayerWitcher;
  4184.                 var refill : W3RefillableContainer;
  4185.                
  4186.                 witcher = GetWitcherPlayer();
  4187.                
  4188.                 if(GetEntity() == witcher)
  4189.                 {
  4190.                        
  4191.                        
  4192.                        
  4193.                        
  4194.                        
  4195.                         if(IsItemCrossbow(itemId) && HasInfiniteBolts())
  4196.                         {
  4197.                                 crossbows = GetItemsByCategory('crossbow');
  4198.                                 crossbows.Remove(itemId);
  4199.                                
  4200.                                 if(crossbows.Size() == 0)
  4201.                                 {
  4202.                                         RemoveItemByName('Bodkin Bolt', GetItemQuantityByName('Bodkin Bolt'));
  4203.                                         RemoveItemByName('Harpoon Bolt', GetItemQuantityByName('Harpoon Bolt'));
  4204.                                 }
  4205.                         }
  4206.                         else if(IsItemBolt(itemId) && witcher.IsItemEquipped(itemId) && witcher.inv.GetItemQuantity(itemId) == quantity)
  4207.                         {
  4208.                                
  4209.                                 witcher.UnequipItem(itemId);
  4210.                         }
  4211.                        
  4212.                        
  4213.                         if(IsItemCrossbow(itemId) && witcher.IsItemEquipped(itemId) && witcher.rangedWeapon)
  4214.                         {
  4215.                                 witcher.rangedWeapon.ClearDeployedEntity(true);
  4216.                                 witcher.rangedWeapon = NULL;
  4217.                         }
  4218.                         if( GetItemCategory(itemId) == 'usable' )
  4219.                         {
  4220.                                 if(witcher.IsHoldingItemInLHand() && itemId ==  witcher.currentlyEquipedItemL )
  4221.                                 {
  4222.                                         witcher.HideUsableItem(true);
  4223.                                 }
  4224.                         }
  4225.                         if( IsItemSteelSwordUsableByPlayer( itemId ) || IsItemSilverSwordUsableByPlayer( itemId ) )
  4226.                         {
  4227.                                 RemoveAllOilsFromItem( itemId );
  4228.                         }
  4229.                        
  4230.                        
  4231.                         if(witcher.IsItemEquipped(itemId) && quantity >= witcher.inv.GetItemQuantity(itemId))
  4232.                                 witcher.UnequipItem(itemId);
  4233.                 }
  4234.                
  4235.                
  4236.                 if(GetEntity() == thePlayer && IsItemWeapon(itemId) && (IsItemHeld(itemId) || IsItemMounted(itemId) ))
  4237.                 {
  4238.                         thePlayer.OnHolsteredItem(GetItemCategory(itemId),'r_weapon');
  4239.                 }
  4240.                
  4241.                
  4242.                 ent = (CGameplayEntity)GetEntity();
  4243.                 if(ent)
  4244.                         ent.OnItemTaken( itemId, quantity );
  4245.                        
  4246.                
  4247.                 if(IsLootRenewable())
  4248.                 {
  4249.                         refill = (W3RefillableContainer)GetEntity();
  4250.                         if(refill)
  4251.                                 refill.AddTimer('Refill', 20, true);
  4252.                 }
  4253.         }
  4254.        
  4255.        
  4256.                 function GenerateItemLevel( item : SItemUniqueId, rewardItem : bool )           //modified by GeniusViking -- modIncreasedItemLevels
  4257.         {
  4258.                 var stat : SAbilityAttributeValue;
  4259.                 var playerLevel : int;
  4260.                 var lvl, i : int;
  4261.                 var quality : int;
  4262.                 var ilMin, ilMax : int;
  4263.                
  4264.                 playerLevel = GetWitcherPlayer().GetLevel();
  4265.                
  4266.                 //GeniusViking -- modIncreasedItemLevels++
  4267.                 lvl = playerLevel + 1;
  4268.                
  4269.                 if ( ( W3MerchantNPC )GetEntity() )
  4270.                 {
  4271.                         lvl = RoundF( playerLevel + RandRangeF( 4, 2 ) );
  4272.                         AddItemTag( item, 'AutogenUseLevelRange' );
  4273.                 }
  4274.                 else if ( rewardItem )
  4275.                 {
  4276.                         lvl = RoundF( playerLevel + RandRangeF( 2, 1 ) );
  4277.                 }
  4278.                 else if ( ItemHasTag( item, 'AutogenUseLevelRange') )
  4279.                 {
  4280.                         quality = RoundMath( CalculateAttributeValue( GetItemAttributeValue( item, 'quality' ) ) );
  4281.                         ilMin = RoundMath(CalculateAttributeValue( GetItemAttributeValue( item, 'item_level_min' ) ));
  4282.                         ilMax = RoundMath(CalculateAttributeValue( GetItemAttributeValue( item, 'item_level_max' ) ));
  4283.                        
  4284.                         lvl += 1;
  4285.                         if ( !ItemHasTag( item, 'AutogenForceLevel') )
  4286.                                 lvl += RoundMath(RandRangeF( 2, 1 ));
  4287.                        
  4288.                         if ( FactsQuerySum("NewGamePlus") > 0 )
  4289.                         {
  4290.                                 if ( lvl < ilMin + theGame.params.GetNewGamePlusLevel() ) lvl = ilMin + theGame.params.GetNewGamePlusLevel();
  4291.                                 if ( lvl > ilMax + theGame.params.GetNewGamePlusLevel() ) lvl = ilMax + theGame.params.GetNewGamePlusLevel();
  4292.                         }
  4293.                         else
  4294.                         {
  4295.                                 if ( lvl < ilMin ) lvl = ilMin;
  4296.                                 if ( lvl > ilMax ) lvl = ilMax;
  4297.                         }
  4298.                        
  4299.                         if ( quality == 5 ) lvl += 2;
  4300.                         if ( quality == 4 ) lvl += 2;
  4301.                         if ( (quality == 5 || quality == 4) && ItemHasTag(item, 'EP1') ) lvl += 1;
  4302.                 }
  4303.                 else if ( !ItemHasTag( item, 'AutogenForceLevel') )
  4304.                 {
  4305.                         quality = RoundMath( CalculateAttributeValue( GetItemAttributeValue( item, 'quality' ) ) );
  4306.  
  4307.                         if ( quality == 5 )
  4308.                         {
  4309.                                 lvl = RoundF( playerLevel + RandRangeF( 5, 2 ) );
  4310.                         }
  4311.                         else if ( quality == 4 )
  4312.                         {
  4313.                                 lvl = RoundF( playerLevel + RandRangeF( 4, 2 ) );
  4314.                         }
  4315.                         else if ( quality == 3 )
  4316.                         {
  4317.                                 lvl = RoundF( playerLevel + RandRangeF( 1, -1 ) );
  4318.                                
  4319.                                 /*if ( RandF() > 0.9 )
  4320.                                 {
  4321.                                         lvl =  playerLevel;
  4322.                                 }*/
  4323.                         }
  4324.                         else if ( quality == 2 )
  4325.                         {
  4326.                                 lvl = RoundF( playerLevel + RandRangeF( 1, -2 ) );
  4327.                                
  4328.                                 /*if ( RandF() > 0.95 )
  4329.                                 {
  4330.                                         lvl =  playerLevel;
  4331.                                 }*/
  4332.                         }
  4333.                         else
  4334.                         {
  4335.                                 lvl = RoundF( playerLevel + RandRangeF( 0, -4 ) );
  4336.                                
  4337.                                 /*if ( RandF() == 0 )
  4338.                                 {
  4339.                                         lvl = playerLevel;
  4340.                                 }*/
  4341.                         }
  4342.                 }
  4343.                 }
  4344.                
  4345.                 if (FactsQuerySum("StandAloneEP1") > 0)
  4346.                         lvl = GetWitcherPlayer().GetLevel() - 1;
  4347.                
  4348.                 //if (FactsQuerySum("StandAloneEP1") > 0)
  4349.                 //      lvl = GetWitcherPlayer().GetLevel();
  4350.                 //GeniusViking -- modIncreasedItemLevels--                     
  4351.                
  4352.                 if ( FactsQuerySum("NewGamePlus") > 0 && !ItemHasTag( item, 'AutogenUseLevelRange') )
  4353.                 {      
  4354.                         if ( quality == 5 ) lvl += 2;
  4355.                         if ( quality == 4 ) lvl += 1;
  4356.                 }
  4357.                        
  4358.                 if ( lvl < 1 ) lvl = 1;
  4359.                 if ( lvl > GetWitcherPlayer().GetMaxLevel() ) lvl = GetWitcherPlayer().GetMaxLevel();
  4360.                
  4361.                 if ( ItemHasTag( item, 'PlayerSteelWeapon' ) && !( ItemHasAbility( item, 'autogen_steel_base' ) || ItemHasAbility( item, 'autogen_fixed_steel_base' ) )  )
  4362.                 {
  4363.                         if ( ItemHasTag(item, 'AutogenUseLevelRange') && ItemHasAbility(item, 'autogen_fixed_steel_base') )
  4364.                                 return;
  4365.                
  4366.                         if ( ItemHasTag(item, 'AutogenUseLevelRange') )
  4367.                                 AddItemCraftedAbility(item, 'autogen_fixed_steel_base' );
  4368.                         else
  4369.                                 AddItemCraftedAbility(item, 'autogen_steel_base' );
  4370.                                
  4371.                         for( i=0; i<lvl; i+=1 )
  4372.                         {
  4373.                                 if (FactsQuerySum("StandAloneEP1") > 0)
  4374.                                 {
  4375.                                         AddItemCraftedAbility(item, 'autogen_fixed_steel_dmg', true );
  4376.                                         continue;
  4377.                                 }
  4378.                                
  4379.                                 if ( ItemHasTag( item, 'AutogenForceLevel') || ItemHasTag(item, 'AutogenUseLevelRange') || FactsQuerySum("NewGamePlus") > 0 )
  4380.                                         AddItemCraftedAbility(item, 'autogen_fixed_steel_dmg', true );
  4381.                                 else
  4382.                                         AddItemCraftedAbility(item, 'autogen_steel_dmg', true );
  4383.                         }
  4384.                 }
  4385.                 else if ( ItemHasTag( item, 'PlayerSilverWeapon' ) && !( ItemHasAbility( item, 'autogen_silver_base' ) || ItemHasAbility( item, 'autogen_fixed_silver_base' ) ) )
  4386.                 {
  4387.                         if ( ItemHasTag(item, 'AutogenUseLevelRange') && ItemHasAbility(item, 'autogen_fixed_silver_base') )
  4388.                                 return;
  4389.                        
  4390.                         if ( ItemHasTag(item, 'AutogenUseLevelRange') )
  4391.                                 AddItemCraftedAbility(item, 'autogen_fixed_silver_base' );
  4392.                         else
  4393.                                 AddItemCraftedAbility(item, 'autogen_silver_base' );
  4394.                                
  4395.                         for( i=0; i<lvl; i+=1 )
  4396.                         {
  4397.                                 if (FactsQuerySum("StandAloneEP1") > 0)
  4398.                                 {
  4399.                                         AddItemCraftedAbility(item, 'autogen_fixed_silver_dmg', true );
  4400.                                         continue;
  4401.                                 }
  4402.                        
  4403.                                 if ( ItemHasTag( item, 'AutogenForceLevel') || ItemHasTag(item, 'AutogenUseLevelRange') || FactsQuerySum("NewGamePlus") > 0 )
  4404.                                         AddItemCraftedAbility(item, 'autogen_fixed_silver_dmg', true );
  4405.                                 else
  4406.                                         AddItemCraftedAbility(item, 'autogen_silver_dmg', true );
  4407.                         }
  4408.                 }
  4409.                 else if ( GetItemCategory( item ) == 'armor' && !( ItemHasAbility( item, 'autogen_armor_base' ) || ItemHasAbility( item, 'autogen_fixed_armor_base' ) ) )
  4410.                 {
  4411.                         if ( ItemHasTag(item, 'AutogenUseLevelRange') && ItemHasAbility(item, 'autogen_fixed_armor_base') )
  4412.                                 return;
  4413.                                
  4414.                         if ( ItemHasTag(item, 'AutogenUseLevelRange') )
  4415.                                 AddItemCraftedAbility(item, 'autogen_fixed_armor_base' );
  4416.                         else
  4417.                                 AddItemCraftedAbility(item, 'autogen_armor_base' );
  4418.                                
  4419.                         for( i=0; i<lvl; i+=1 )
  4420.                         {
  4421.                                 if (FactsQuerySum("StandAloneEP1") > 0)
  4422.                                 {
  4423.                                         AddItemCraftedAbility(item, 'autogen_fixed_armor_armor', true );
  4424.                                         continue;
  4425.                                 }
  4426.                        
  4427.                                 if ( ItemHasTag( item, 'AutogenForceLevel') || ItemHasTag( item, 'AutogenUseLevelRange') || FactsQuerySum("NewGamePlus") > 0 )
  4428.                                         AddItemCraftedAbility(item, 'autogen_fixed_armor_armor', true );
  4429.                                 else
  4430.                                         AddItemCraftedAbility(item, 'autogen_armor_armor', true );             
  4431.                         }
  4432.                 }
  4433.                 else if ( ( GetItemCategory( item ) == 'boots' || GetItemCategory( item ) == 'pants' ) && !( ItemHasAbility( item, 'autogen_pants_base' ) || ItemHasAbility( item, 'autogen_fixed_pants_base' ) ) )
  4434.                 {
  4435.                         if ( ItemHasTag(item, 'AutogenUseLevelRange') && ItemHasAbility(item, 'autogen_fixed_pants_base') )
  4436.                                 return;
  4437.                                
  4438.                         if ( ItemHasTag(item, 'AutogenUseLevelRange') )
  4439.                                 AddItemCraftedAbility(item, 'autogen_fixed_pants_base' );
  4440.                         else
  4441.                                 AddItemCraftedAbility(item, 'autogen_pants_base' );
  4442.                                
  4443.                         for( i=0; i<lvl; i+=1 )
  4444.                         {
  4445.                                 if (FactsQuerySum("StandAloneEP1") > 0)
  4446.                                 {
  4447.                                         AddItemCraftedAbility(item, 'autogen_fixed_pants_armor', true );
  4448.                                         continue;
  4449.                                 }
  4450.                        
  4451.                                 if ( ItemHasTag( item, 'AutogenForceLevel') || ItemHasTag( item, 'AutogenUseLevelRange') || FactsQuerySum("NewGamePlus") > 0 )
  4452.                                         AddItemCraftedAbility(item, 'autogen_fixed_pants_armor', true );
  4453.                                 else
  4454.                                         AddItemCraftedAbility(item, 'autogen_pants_armor', true );
  4455.                         }
  4456.                 }
  4457.                 else if ( GetItemCategory( item ) == 'gloves' && !( ItemHasAbility( item, 'autogen_gloves_base' ) || ItemHasAbility( item, 'autogen_fixed_gloves_base' ) ) )
  4458.                 {
  4459.                         if ( ItemHasTag(item, 'AutogenUseLevelRange') && ItemHasAbility(item, 'autogen_fixed_gloves_base') )
  4460.                                 return;
  4461.                                
  4462.                         if ( ItemHasTag(item, 'AutogenUseLevelRange') )
  4463.                                 AddItemCraftedAbility(item, 'autogen_fixed_gloves_base' );
  4464.                         else
  4465.                                 AddItemCraftedAbility(item, 'autogen_gloves_base' );
  4466.                                
  4467.                         for( i=0; i<lvl; i+=1 )
  4468.                         {
  4469.                                 if (FactsQuerySum("StandAloneEP1") > 0)
  4470.                                 {
  4471.                                         AddItemCraftedAbility(item, 'autogen_fixed_gloves_armor', true );
  4472.                                         continue;
  4473.                                 }
  4474.                        
  4475.                                 if ( ItemHasTag( item, 'AutogenForceLevel') || ItemHasTag(item, 'AutogenUseLevelRange') || FactsQuerySum("NewGamePlus") > 0 )
  4476.                                         AddItemCraftedAbility(item, 'autogen_fixed_gloves_armor', true );
  4477.                                 else
  4478.                                         AddItemCraftedAbility(item, 'autogen_gloves_armor', true );
  4479.                         }
  4480.                 }      
  4481.         }
  4482.                
  4483.        
  4484.         event OnItemAdded(data : SItemChangedData)
  4485.         {
  4486.                 var i, j : int;
  4487.                 var ent : CGameplayEntity;
  4488.                 var allCardsNames, foundCardsNames : array<name>;
  4489.                 var allStringNamesOfCards : array<string>;
  4490.                 var foundCardsStringNames : array<string>;
  4491.                 var gwintCards : array<SItemUniqueId>;
  4492.                 var itemName : name;
  4493.                 var witcher : W3PlayerWitcher;
  4494.                 var itemCategory : name;
  4495.                 var dm : CDefinitionsManagerAccessor;
  4496.                 var locKey : string;
  4497.                 var leaderCardsHack : array<name>;
  4498.                
  4499.                 var hud : CR4ScriptedHud;
  4500.                 var journalUpdateModule : CR4HudModuleJournalUpdate;
  4501.                 var itemId : SItemUniqueId;
  4502.                
  4503.                 var isItemShematic : bool;
  4504.                
  4505.                 var ngp : bool;
  4506.                
  4507.                 ent = (CGameplayEntity)GetEntity();
  4508.                
  4509.                 itemId = data.ids[0];
  4510.                
  4511.                
  4512.                 if( data.informGui )
  4513.                 {
  4514.                         recentlyAddedItems.PushBack( itemId );
  4515.                         if( ItemHasTag( itemId, 'FocusObject' ) )
  4516.                         {
  4517.                                 GetWitcherPlayer().GetMedallion().Activate( true, 3.0);
  4518.                         }
  4519.                 }
  4520.                
  4521.                
  4522.                 if ( ItemHasTag(itemId, 'Autogen') )
  4523.                 {
  4524.                         GenerateItemLevel( itemId, false );
  4525.                 }
  4526.                
  4527.                 witcher = GetWitcherPlayer();
  4528.                
  4529.                
  4530.                 if(ent == witcher || ((W3MerchantNPC)ent) )
  4531.                 {
  4532.                         ngp = FactsQuerySum("NewGamePlus") > 0;
  4533.                         for(i=0; i<data.ids.Size(); i+=1)
  4534.                         {
  4535.                                
  4536.                                 if ( GetItemModifierInt(data.ids[i], 'ItemQualityModified') <= 0 )
  4537.                                         AddRandomEnhancementToItem(data.ids[i]);
  4538.                                
  4539.                                 if ( ngp )
  4540.                                         SetItemModifierInt(data.ids[i], 'DoNotAdjustNGPDLC', 1);       
  4541.                                
  4542.                                 itemName = GetItemName(data.ids[i]);
  4543.                                
  4544.                                 if ( ngp && GetItemModifierInt(data.ids[i], 'NGPItemAdjusted') <= 0 && !ItemHasTag(data.ids[i], 'Autogen') )
  4545.                                 {
  4546.                                         IncreaseNGPItemlevel(data.ids[i]);
  4547.                                 }
  4548.                                
  4549.                         }
  4550.                 }
  4551.                 if(ent == witcher)
  4552.                 {
  4553.                         for(i=0; i<data.ids.Size(); i+=1)
  4554.                         {      
  4555.                                
  4556.                                 if( ItemHasTag( itemId, theGame.params.GWINT_CARD_ACHIEVEMENT_TAG ) || !FactsDoesExist( "fix_for_gwent_achievement_bug_121588" ) )
  4557.                                 {
  4558.                                        
  4559.                                         leaderCardsHack.PushBack('gwint_card_emhyr_gold');
  4560.                                         leaderCardsHack.PushBack('gwint_card_emhyr_silver');
  4561.                                         leaderCardsHack.PushBack('gwint_card_emhyr_bronze');
  4562.                                         leaderCardsHack.PushBack('gwint_card_foltest_gold');
  4563.                                         leaderCardsHack.PushBack('gwint_card_foltest_silver');
  4564.                                         leaderCardsHack.PushBack('gwint_card_foltest_bronze');
  4565.                                         leaderCardsHack.PushBack('gwint_card_francesca_gold');
  4566.                                         leaderCardsHack.PushBack('gwint_card_francesca_silver');
  4567.                                         leaderCardsHack.PushBack('gwint_card_francesca_bronze');
  4568.                                         leaderCardsHack.PushBack('gwint_card_eredin_gold');
  4569.                                         leaderCardsHack.PushBack('gwint_card_eredin_silver');
  4570.                                         leaderCardsHack.PushBack('gwint_card_eredin_bronze');
  4571.                                        
  4572.                                         dm = theGame.GetDefinitionsManager();
  4573.                                        
  4574.                                         allCardsNames = theGame.GetDefinitionsManager().GetItemsWithTag(theGame.params.GWINT_CARD_ACHIEVEMENT_TAG);
  4575.                                        
  4576.                                        
  4577.                                         gwintCards = GetItemsByTag(theGame.params.GWINT_CARD_ACHIEVEMENT_TAG);
  4578.  
  4579.                                        
  4580.                                         allStringNamesOfCards.PushBack('gwint_name_emhyr');
  4581.                                         allStringNamesOfCards.PushBack('gwint_name_emhyr');
  4582.                                         allStringNamesOfCards.PushBack('gwint_name_emhyr');
  4583.                                         allStringNamesOfCards.PushBack('gwint_name_foltest');
  4584.                                         allStringNamesOfCards.PushBack('gwint_name_foltest');
  4585.                                         allStringNamesOfCards.PushBack('gwint_name_foltest');
  4586.                                         allStringNamesOfCards.PushBack('gwint_name_francesca');
  4587.                                         allStringNamesOfCards.PushBack('gwint_name_francesca');
  4588.                                         allStringNamesOfCards.PushBack('gwint_name_francesca');
  4589.                                         allStringNamesOfCards.PushBack('gwint_name_eredin');
  4590.                                         allStringNamesOfCards.PushBack('gwint_name_eredin');
  4591.                                         allStringNamesOfCards.PushBack('gwint_name_eredin');
  4592.                                        
  4593.                                        
  4594.                                         for(j=0; j<allCardsNames.Size(); j+=1)
  4595.                                         {
  4596.                                                 itemName = allCardsNames[j];
  4597.                                                 locKey = dm.GetItemLocalisationKeyName(allCardsNames[j]);
  4598.                                                 if (!allStringNamesOfCards.Contains(locKey))
  4599.                                                 {
  4600.                                                         allStringNamesOfCards.PushBack(locKey);
  4601.                                                 }
  4602.                                         }
  4603.                                        
  4604.                                        
  4605.                                         if(gwintCards.Size() >= allStringNamesOfCards.Size())
  4606.                                         {
  4607.                                                 foundCardsNames.Clear();
  4608.                                                 for(j=0; j<gwintCards.Size(); j+=1)
  4609.                                                 {
  4610.                                                         itemName = GetItemName(gwintCards[j]);
  4611.                                                         locKey = dm.GetItemLocalisationKeyName(itemName);
  4612.                                                        
  4613.                                                         if(!foundCardsStringNames.Contains(locKey) || leaderCardsHack.Contains(itemName))
  4614.                                                         {
  4615.                                                                 foundCardsStringNames.PushBack(locKey);
  4616.                                                         }
  4617.                                                 }
  4618.  
  4619.                                                 if(foundCardsStringNames.Size() >= allStringNamesOfCards.Size())
  4620.                                                 {
  4621.                                                         theGame.GetGamerProfile().AddAchievement(EA_GwintCollector);
  4622.                                                         FactsAdd("gwint_all_cards_collected", 1, -1);
  4623.                                                 }
  4624.                                         }
  4625.                                        
  4626.                                         if(!FactsDoesExist("fix_for_gwent_achievement_bug_121588"))
  4627.                                                 FactsAdd("fix_for_gwent_achievement_bug_121588", 1, -1);
  4628.                                 }
  4629.                                
  4630.                                 itemCategory = GetItemCategory( itemId );
  4631.                                 isItemShematic = itemCategory == 'alchemy_recipe' ||  itemCategory == 'crafting_schematic';
  4632.                                
  4633.                                 if( isItemShematic )
  4634.                                 {
  4635.                                         ReadSchematicsAndRecipes( itemId );
  4636.                                 }                                      
  4637.                                
  4638.                                
  4639.                                 if( ItemHasTag( data.ids[i], 'GwintCard'))
  4640.                                 {
  4641.                                         witcher.AddGwentCard(GetItemName(data.ids[i]), data.quantity);
  4642.                                 }
  4643.                                
  4644.                                
  4645.                                
  4646.                                 if( !isItemShematic && ( this.ItemHasTag( itemId, 'ReadableItem' ) || this.ItemHasTag( itemId, 'Painting' ) ) && !this.ItemHasTag( itemId, 'NoNotification' ) )
  4647.                                 {
  4648.                                         hud = (CR4ScriptedHud)theGame.GetHud();
  4649.                                         if( hud )
  4650.                                         {
  4651.                                                 journalUpdateModule = (CR4HudModuleJournalUpdate)hud.GetHudModule( "JournalUpdateModule" );
  4652.                                                 if( journalUpdateModule )
  4653.                                                 {
  4654.                                                         journalUpdateModule.AddQuestBookInfo( itemId );
  4655.                                                 }
  4656.                                         }
  4657.                                 }                              
  4658.                         }
  4659.                 }
  4660.                
  4661.                
  4662.                 if( IsItemSingletonItem( itemId ) )
  4663.                 {
  4664.                         for(i=0; i<data.ids.Size(); i+=1)
  4665.                         {
  4666.                                 if(!GetItemModifierInt(data.ids[i], 'is_initialized', 0))
  4667.                                 {
  4668.                                         SingletonItemRefillAmmo(data.ids[i]);
  4669.                                         SetItemModifierInt(data.ids[i], 'is_initialized', 1);
  4670.                                 }
  4671.                         }                      
  4672.                 }
  4673.                
  4674.                
  4675.                 if(ent)
  4676.                         ent.OnItemGiven(data);
  4677.         }
  4678.        
  4679.         public function AddRandomEnhancementToItem(item : SItemUniqueId)
  4680.         {
  4681.                 var itemCategory        : name;
  4682.                 var itemQuality         : int;
  4683.                 var ability                     : name;
  4684.                 var ent                         : CGameplayEntity;
  4685.                
  4686.                
  4687.                
  4688.                
  4689.                 if( ItemHasTag(item, 'DoNotEnhance') )
  4690.                 {
  4691.                         SetItemModifierInt(item, 'ItemQualityModified', 1);
  4692.                         return;
  4693.                 }
  4694.                
  4695.                 itemCategory = GetItemCategory(item);
  4696.                 itemQuality = RoundMath(CalculateAttributeValue(GetItemAttributeValue(item, 'quality' )));
  4697.                
  4698.                 if ( itemCategory == 'armor' )
  4699.                 {
  4700.                         switch ( itemQuality )
  4701.                         {
  4702.                                 case 2 :
  4703.                                         ability = 'quality_masterwork_armor';                  
  4704.                                         AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkArmorAbility(), true);
  4705.                                         break;
  4706.                                 case 3 :
  4707.                                         ability = 'quality_magical_armor';      
  4708.                                         if ( ItemHasTag(item, 'EP1') )
  4709.                                         {
  4710.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMagicalArmorAbility(), true);
  4711.                                                 break;
  4712.                                         }
  4713.                                        
  4714.                                         if ( RandF() > 0.5 )
  4715.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMagicalArmorAbility(), true);
  4716.                                         else
  4717.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkArmorAbility(), true);
  4718.                                        
  4719.                                         if ( RandF() > 0.5 )
  4720.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMagicalArmorAbility(), true);
  4721.                                         else
  4722.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkArmorAbility(), true);
  4723.                                         break;
  4724.                                 default : break;
  4725.                         }
  4726.                 }
  4727.                 else if ( itemCategory == 'gloves' )
  4728.                 {
  4729.                         switch ( itemQuality )
  4730.                         {
  4731.                                 case 2 :
  4732.                                         ability = 'quality_masterwork_gloves';         
  4733.                                         AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkGlovesAbility(), true);
  4734.                                         break;
  4735.                                 case 3 :
  4736.                                         ability = 'quality_magical_gloves';    
  4737.                                         if ( ItemHasTag(item, 'EP1') )
  4738.                                         {
  4739.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMagicalArmorAbility(), true);
  4740.                                                 break;
  4741.                                         }              
  4742.                                        
  4743.                                         if ( RandF() > 0.5 )
  4744.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMagicalGlovesAbility(), true);
  4745.                                         else
  4746.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkGlovesAbility(), true);
  4747.                                        
  4748.                                         if ( RandF() > 0.5 )
  4749.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMagicalGlovesAbility(), true);
  4750.                                         else
  4751.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkGlovesAbility(), true);
  4752.                                         break;
  4753.                                 default : break;
  4754.                         }
  4755.                 }
  4756.                 else if ( itemCategory == 'pants' )
  4757.                 {
  4758.                         switch ( itemQuality )
  4759.                         {
  4760.                                 case 2 :
  4761.                                         ability = 'quality_masterwork_pants';                  
  4762.                                         AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkPantsAbility(), true);
  4763.                                         break;
  4764.                                 case 3 :
  4765.                                         ability = 'quality_magical_pants';      
  4766.                                         if ( ItemHasTag(item, 'EP1') )
  4767.                                         {
  4768.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMagicalArmorAbility(), true);
  4769.                                                 break;
  4770.                                         }
  4771.                                        
  4772.                                         if ( RandF() > 0.5 )
  4773.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMagicalPantsAbility(), true);
  4774.                                         else
  4775.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkPantsAbility(), true);
  4776.                                        
  4777.                                         if ( RandF() > 0.5 )
  4778.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMagicalPantsAbility(), true);
  4779.                                         else
  4780.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkPantsAbility(), true);
  4781.                                         break;
  4782.                                 default : break;
  4783.                         }
  4784.                 }
  4785.                 else if ( itemCategory == 'boots' )
  4786.                 {
  4787.                         switch ( itemQuality )
  4788.                         {
  4789.                                 case 2 :
  4790.                                         ability = 'quality_masterwork_boots';                  
  4791.                                         AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkBootsAbility(), true);
  4792.                                         break;
  4793.                                 case 3 :
  4794.                                         ability = 'quality_magical_boots';             
  4795.                                         if ( ItemHasTag(item, 'EP1') )
  4796.                                         {
  4797.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMagicalArmorAbility(), true);
  4798.                                                 break;
  4799.                                         }
  4800.                                        
  4801.                                         if ( RandF() > 0.5 )
  4802.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMagicalBootsAbility(), true);
  4803.                                         else
  4804.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkBootsAbility(), true);
  4805.                                        
  4806.                                         if ( RandF() > 0.5 )
  4807.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMagicalBootsAbility(), true);
  4808.                                         else
  4809.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkBootsAbility(), true);
  4810.                                         break;
  4811.                                 default : break;
  4812.                         }
  4813.                 }
  4814.                 else if ( itemCategory == 'steelsword' )
  4815.                 {
  4816.                         switch ( itemQuality )
  4817.                         {
  4818.                                 case 2 :
  4819.                                         ability = 'quality_masterwork_steelsword';      
  4820.                                         AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkWeaponAbility(), true);
  4821.                                         break;
  4822.                                 case 3 :
  4823.                                         ability = 'quality_magical_steelsword';        
  4824.                                         if ( ItemHasTag(item, 'EP1') )
  4825.                                         {
  4826.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMagicalArmorAbility(), true);
  4827.                                                 break;
  4828.                                         }
  4829.                                        
  4830.                                         if ( RandF() > 0.5 )
  4831.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMagicalWeaponAbility(), true);
  4832.                                         else
  4833.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkWeaponAbility(), true);
  4834.                                        
  4835.                                         if ( RandF() > 0.5 )
  4836.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMagicalWeaponAbility(), true);
  4837.                                         else
  4838.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkWeaponAbility(), true);
  4839.                                         break;
  4840.                                 default : break;
  4841.                         }
  4842.                 }
  4843.                 else if ( itemCategory == 'silversword' )
  4844.                 {
  4845.                         switch ( itemQuality )
  4846.                         {
  4847.                                 case 2 :
  4848.                                         ability = 'quality_masterwork_silversword';    
  4849.                                         AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkWeaponAbility(), true);
  4850.                                         break;
  4851.                                 case 3 :
  4852.                                         ability = 'quality_magical_silversword';        
  4853.                                         if ( ItemHasTag(item, 'EP1') )
  4854.                                         {
  4855.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMagicalArmorAbility(), true);
  4856.                                                 break;
  4857.                                         }
  4858.                                        
  4859.                                         if ( RandF() > 0.5 )
  4860.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMagicalWeaponAbility(), true);
  4861.                                         else
  4862.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkWeaponAbility(), true);
  4863.                                        
  4864.                                         if ( RandF() > 0.5 )
  4865.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMagicalWeaponAbility(), true);
  4866.                                         else
  4867.                                                 AddItemCraftedAbility(item, theGame.params.GetRandomMasterworkWeaponAbility(), true);
  4868.                                         break;
  4869.                                        
  4870.                                 default : break;
  4871.                         }
  4872.                 }
  4873.                        
  4874.                 if(IsNameValid(ability))
  4875.                 {
  4876.                         AddItemCraftedAbility(item, ability, false);
  4877.                         SetItemModifierInt(item, 'ItemQualityModified', 1);
  4878.                 }
  4879.         }
  4880.        
  4881.         public function IncreaseNGPItemlevel(item : SItemUniqueId)
  4882.         {
  4883.                 var i, diff : int;
  4884.                
  4885.                 diff = theGame.params.NewGamePlusLevelDifference();
  4886.                
  4887.                 if (diff > 0)
  4888.                 {
  4889.                         if ( ItemHasTag( item, 'PlayerSteelWeapon' ) )
  4890.                         {      
  4891.                                 for( i=0; i<diff; i+=1 )
  4892.                                 {
  4893.                                         AddItemCraftedAbility(item, 'autogen_fixed_steel_dmg', true );
  4894.                                 }
  4895.                         }
  4896.                         else if ( ItemHasTag( item, 'PlayerSilverWeapon' ) )
  4897.                         {
  4898.                                 for( i=0; i<diff; i+=1 )
  4899.                                 {
  4900.                                         AddItemCraftedAbility(item, 'autogen_fixed_silver_dmg', true );
  4901.                                 }
  4902.                         }
  4903.                         else if ( IsItemChestArmor(item) )
  4904.                         {      
  4905.                                 for( i=0; i<diff; i+=1 )
  4906.                                 {
  4907.                                         AddItemCraftedAbility(item, 'autogen_fixed_armor_armor', true );               
  4908.                                 }
  4909.                         }
  4910.                         else if ( IsItemBoots(item) || IsItemPants(item) )
  4911.                         {                              
  4912.                                 for( i=0; i<diff; i+=1 )
  4913.                                 {
  4914.                                         AddItemCraftedAbility(item, 'autogen_fixed_pants_armor', true );
  4915.                                 }
  4916.                         }
  4917.                         else if ( IsItemGloves(item) )
  4918.                         {                      
  4919.                                 for( i=0; i<diff; i+=1 )
  4920.                                 {
  4921.                                         AddItemCraftedAbility(item, 'autogen_fixed_gloves_armor', true );
  4922.                                 }
  4923.                         }      
  4924.                 }
  4925.                
  4926.                 SetItemModifierInt(item, 'NGPItemAdjusted', 1);
  4927.         }
  4928.        
  4929.         public function GetItemQuality( itemId : SItemUniqueId ) : int
  4930.         {
  4931.                 var itemQuality : float;
  4932.                 var itemQualityAtribute : SAbilityAttributeValue;
  4933.                 var excludedTags : array<name>;
  4934.                 var tempItemQualityAtribute     : SAbilityAttributeValue;
  4935.        
  4936.                
  4937.                 excludedTags.PushBack(theGame.params.OIL_ABILITY_TAG);
  4938.                 itemQualityAtribute = GetItemAttributeValue( itemId, 'quality', excludedTags, true );
  4939.                
  4940.                 itemQuality = itemQualityAtribute.valueAdditive;
  4941.                 if( itemQuality == 0 )
  4942.                 {
  4943.                         itemQuality = 1;
  4944.                 }
  4945.                 return RoundMath(itemQuality);
  4946.         }
  4947.        
  4948.         public function GetItemQualityFromName( itemName : name, out min : int, out max : int)
  4949.         {
  4950.                 var dm : CDefinitionsManagerAccessor;
  4951.                 var attributeName : name;
  4952.                 var attributes, itemAbilities : array<name>;
  4953.                 var attributeMin, attributeMax : SAbilityAttributeValue;
  4954.                
  4955.                 var tmpInt : int;
  4956.                 var tmpArray : array<float>;
  4957.                
  4958.                 dm = theGame.GetDefinitionsManager();
  4959.                
  4960.                 dm.GetItemAbilitiesWithWeights(itemName, GetEntity() == thePlayer, itemAbilities, tmpArray, tmpInt, tmpInt);
  4961.                 attributes = dm.GetAbilitiesAttributes(itemAbilities);
  4962.                 for (tmpInt = 0; tmpInt < attributes.Size(); tmpInt += 1)
  4963.                 {
  4964.                         if (attributes[tmpInt] == 'quality')
  4965.                         {
  4966.                                 dm.GetAbilitiesAttributeValue(itemAbilities, 'quality', attributeMin, attributeMax);
  4967.                                 min = RoundMath(CalculateAttributeValue(attributeMin));
  4968.                                 max = RoundMath(CalculateAttributeValue(attributeMax));
  4969.                                 break;
  4970.                         }
  4971.                 }
  4972.         }
  4973.        
  4974.         public function GetRecentlyAddedItems() : array<SItemUniqueId>
  4975.         {
  4976.                 return recentlyAddedItems;
  4977.         }
  4978.        
  4979.         public function GetRecentlyAddedItemsListSize() : int
  4980.         {
  4981.                 return recentlyAddedItems.Size();
  4982.         }
  4983.        
  4984.         public function RemoveItemFromRecentlyAddedList( itemId : SItemUniqueId ) : bool
  4985.         {
  4986.                 var i : int;
  4987.                
  4988.                 for( i = 0; i < recentlyAddedItems.Size(); i += 1 )
  4989.                 {
  4990.                         if( recentlyAddedItems[i] == itemId )
  4991.                         {
  4992.                                 recentlyAddedItems.EraseFast( i );
  4993.                                 return true;
  4994.                         }
  4995.                 }
  4996.                
  4997.                 return false;
  4998.         }
  4999.        
  5000.        
  5001.        
  5002.        
  5003.         import final function NotifyScriptedListeners( notify : bool );
  5004.        
  5005.         var listeners : array< IInventoryScriptedListener >;
  5006.        
  5007.         function AddListener( listener : IInventoryScriptedListener )
  5008.         {      
  5009.                 if ( listeners.FindFirst( listener ) == -1 )
  5010.                 {
  5011.                         listeners.PushBack( listener );
  5012.                         if ( listeners.Size() == 1 )
  5013.                         {
  5014.                                 NotifyScriptedListeners( true );
  5015.                         }              
  5016.                 }      
  5017.         }
  5018.        
  5019.         function RemoveListener( listener : IInventoryScriptedListener )
  5020.         {      
  5021.                 if ( listeners.Remove( listener ) )
  5022.                 {
  5023.                         if ( listeners.Size() == 0 )
  5024.                         {
  5025.                                 NotifyScriptedListeners( false );
  5026.                         }              
  5027.                 }      
  5028.         }
  5029.        
  5030.         event OnInventoryScriptedEvent( eventType : EInventoryEventType, itemId : SItemUniqueId, quantity : int, fromAssociatedInventory : bool )
  5031.         {
  5032.                 var i, size : int;
  5033.                
  5034.                 size = listeners.Size();
  5035.                 for (i=size-1; i>=0; i-=1 )            
  5036.                 {
  5037.                         listeners[i].OnInventoryScriptedEvent( eventType, itemId, quantity, fromAssociatedInventory );
  5038.                 }
  5039.                
  5040.                
  5041.                 if(GetEntity() == GetWitcherPlayer() && (eventType == IET_ItemRemoved || eventType == IET_ItemQuantityChanged) )
  5042.                         GetWitcherPlayer().UpdateEncumbrance();
  5043.         }
  5044.        
  5045.        
  5046.        
  5047.        
  5048.         public final function GetMutationResearchPoints( color : ESkillColor, item : SItemUniqueId ) : int
  5049.         {
  5050.                 var val : SAbilityAttributeValue;
  5051.                 var colorAttribute : name;
  5052.                
  5053.                
  5054.                 if( color == SC_None || color == SC_Yellow || !IsIdValid( item ) )
  5055.                 {
  5056.                         return 0;
  5057.                 }
  5058.                
  5059.                
  5060.                 switch( color )
  5061.                 {
  5062.                         case SC_Red:
  5063.                                 colorAttribute = 'mutation_research_points_red';
  5064.                                 break;
  5065.                         case SC_Blue:
  5066.                                 colorAttribute = 'mutation_research_points_blue';
  5067.                                 break;
  5068.                         case SC_Green:
  5069.                                 colorAttribute = 'mutation_research_points_green';
  5070.                                 break;
  5071.                 }
  5072.                
  5073.                
  5074.                 val = GetItemAttributeValue( item, colorAttribute );
  5075.                
  5076.                 return ( int )val.valueAdditive;
  5077.         }
  5078.        
  5079.         public function GetSkillMutagenColor(item : SItemUniqueId) : ESkillColor
  5080.         {              
  5081.                 var abs : array<name>;
  5082.        
  5083.                
  5084.                 if(!ItemHasTag(item, 'MutagenIngredient'))
  5085.                         return SC_None;
  5086.                        
  5087.                 GetItemAbilities(item, abs);
  5088.                
  5089.                 if(abs.Contains('mutagen_color_green'))                 return SC_Green;
  5090.                 if(abs.Contains('mutagen_color_blue'))                  return SC_Blue;
  5091.                 if(abs.Contains('mutagen_color_red'))                   return SC_Red;
  5092.                 if(abs.Contains('lesser_mutagen_color_green'))  return SC_Green;
  5093.                 if(abs.Contains('lesser_mutagen_color_blue'))   return SC_Blue;
  5094.                 if(abs.Contains('lesser_mutagen_color_red'))    return SC_Red;
  5095.                 if(abs.Contains('greater_mutagen_color_green')) return SC_Green;
  5096.                 if(abs.Contains('greater_mutagen_color_blue'))  return SC_Blue;
  5097.                 if(abs.Contains('greater_mutagen_color_red'))   return SC_Red;
  5098.                
  5099.                 return SC_None;
  5100.         }
  5101.  
  5102.        
  5103.        
  5104.        
  5105.  
  5106.        
  5107.        
  5108.        
  5109.        
  5110.         import final function GetItemEnhancementSlotsCount( itemId : SItemUniqueId ) : int;
  5111.         import final function GetItemEnhancementItems( itemId : SItemUniqueId, out names : array< name > );
  5112.         import final function GetItemEnhancementCount( itemId : SItemUniqueId ) : int;
  5113.         import final function GetItemColor( itemId : SItemUniqueId ) : name;
  5114.         import final function IsItemColored( itemId : SItemUniqueId ) : bool;
  5115.         import final function SetPreviewColor( itemId : SItemUniqueId, colorId : int );
  5116.         import final function ClearPreviewColor( itemId : SItemUniqueId ) : bool;
  5117.         import final function ColorItem( itemId : SItemUniqueId, dyeId : SItemUniqueId );
  5118.         import final function ClearItemColor( itemId : SItemUniqueId ) : bool;
  5119.         import final function EnchantItem( enhancedItemId : SItemUniqueId, enchantmentName : name, enchantmentStat : name ) : bool;
  5120.         import final function GetEnchantment( enhancedItemId : SItemUniqueId ) : name;
  5121.         import final function IsItemEnchanted( enhancedItemId : SItemUniqueId ) : bool;
  5122.         import final function UnenchantItem( enhancedItemId : SItemUniqueId ) : bool;
  5123.         import private function EnhanceItem( enhancedItemId : SItemUniqueId, extensionItemId : SItemUniqueId ) : bool;
  5124.         import private function RemoveItemEnhancementByIndex( enhancedItemId : SItemUniqueId, slotIndex : int ) : bool;
  5125.         import private function RemoveItemEnhancementByName( enhancedItemId : SItemUniqueId, extensionItemName : name ) : bool;
  5126.         import final function PreviewItemAttributeAfterUpgrade( baseItemId : SItemUniqueId, upgradeItemId : SItemUniqueId, attributeName : name, optional baseInventory : CInventoryComponent, optional upgradeInventory : CInventoryComponent ) : SAbilityAttributeValue;
  5127.         import final function HasEnhancementItemTag( enhancedItemId : SItemUniqueId, slotIndex : int, tag : name ) : bool;
  5128.        
  5129.        
  5130.         function NotifyEnhancedItem( enhancedItemId : SItemUniqueId )
  5131.         {
  5132.                 var weapons : array<SItemUniqueId>;
  5133.                 var sword : CWitcherSword;
  5134.                 var i : int;
  5135.                
  5136.                 sword = (CWitcherSword) GetItemEntityUnsafe( enhancedItemId );
  5137.                 sword.UpdateEnhancements( this );
  5138.         }
  5139.        
  5140.         function EnhanceItemScript( enhancedItemId : SItemUniqueId, extensionItemId : SItemUniqueId ) : bool
  5141.         {
  5142.                 var i : int;
  5143.                 var enhancements : array<name>;
  5144.                 var runeword : Runeword;
  5145.                
  5146.                 if ( EnhanceItem( enhancedItemId, extensionItemId ) )
  5147.                 {
  5148.                         NotifyEnhancedItem( enhancedItemId );
  5149.                        
  5150.                         GetItemEnhancementItems( enhancedItemId, enhancements );
  5151.                         if ( theGame.runewordMgr.GetRuneword( enhancements, runeword ) )
  5152.                         {
  5153.                                 for ( i = 0; i < runeword.abilities.Size(); i+=1 )
  5154.                                 {
  5155.                                         AddItemBaseAbility( enhancedItemId, runeword.abilities[i] );
  5156.                                 }
  5157.                         }
  5158.                         return true;
  5159.                 }
  5160.                 return false;
  5161.         }
  5162.        
  5163.         function RemoveItemEnhancementByIndexScript( enhancedItemId : SItemUniqueId, slotIndex : int ) : bool
  5164.         {
  5165.                 var i : int;
  5166.                 var enhancements : array<name>;
  5167.                 var runeword : Runeword;
  5168.                 var hasRuneword : bool;
  5169.                 var names : array< name >;
  5170.  
  5171.                 GetItemEnhancementItems( enhancedItemId, enhancements );
  5172.                 hasRuneword = theGame.runewordMgr.GetRuneword( enhancements, runeword );
  5173.                
  5174.                 GetItemEnhancementItems( enhancedItemId, names );
  5175.                
  5176.                 if ( RemoveItemEnhancementByIndex( enhancedItemId, slotIndex ) )
  5177.                 {
  5178.                         NotifyEnhancedItem( enhancedItemId );
  5179.                        
  5180.                        
  5181.                        
  5182.                         if ( hasRuneword )
  5183.                         {
  5184.                                
  5185.                                 for ( i = 0; i < runeword.abilities.Size(); i+=1 )
  5186.                                 {
  5187.                                         RemoveItemBaseAbility( enhancedItemId, runeword.abilities[i] );
  5188.                                 }
  5189.                         }
  5190.                         return true;
  5191.                 }
  5192.                 return false;
  5193.         }
  5194.        
  5195.        
  5196.         function RemoveItemEnhancementByNameScript( enhancedItemId : SItemUniqueId, extensionItemName : name ) : bool
  5197.         {
  5198.                 var i : int;
  5199.                 var enhancements : array<name>;
  5200.                 var runeword : Runeword;
  5201.                 var hasRuneword : bool;
  5202.  
  5203.                 GetItemEnhancementItems( enhancedItemId, enhancements );
  5204.                 hasRuneword = theGame.runewordMgr.GetRuneword( enhancements, runeword );
  5205.                
  5206.                
  5207.                 if ( RemoveItemEnhancementByName( enhancedItemId, extensionItemName ) )
  5208.                 {
  5209.                         NotifyEnhancedItem( enhancedItemId );
  5210.                        
  5211.                        
  5212.                         AddAnItem( extensionItemName, 1, true, true );
  5213.                         if ( hasRuneword )
  5214.                         {
  5215.                                
  5216.                                 for ( i = 0; i < runeword.abilities.Size(); i+=1 )
  5217.                                 {
  5218.                                         RemoveItemBaseAbility( enhancedItemId, runeword.abilities[i] );
  5219.                                 }
  5220.                         }
  5221.                         return true;
  5222.                 }
  5223.                 return false;
  5224.         }
  5225.        
  5226.         function RemoveAllItemEnhancements( enhancedItemId : SItemUniqueId )
  5227.         {
  5228.                 var count, i : int;
  5229.                
  5230.                 count = GetItemEnhancementCount( enhancedItemId );
  5231.                 for ( i = count - 1; i >= 0; i-=1 )
  5232.                 {
  5233.                         RemoveItemEnhancementByIndexScript( enhancedItemId, i );
  5234.                 }
  5235.         }
  5236.        
  5237.         function GetHeldAndMountedItems( out items : array< SItemUniqueId > )
  5238.         {
  5239.                 var allItems : array< SItemUniqueId >;
  5240.                 var i : int;
  5241.                 var itemName : name;
  5242.        
  5243.                 GetAllItems( allItems );
  5244.  
  5245.                 items.Clear();
  5246.                 for( i = 0; i < allItems.Size(); i += 1 )
  5247.                 {
  5248.                         if ( IsItemHeld( allItems[ i ] ) || IsItemMounted( allItems[ i ] ) )
  5249.                         {
  5250.                                 items.PushBack( allItems[ i ] );
  5251.                         }
  5252.                 }
  5253.         }
  5254.        
  5255.        
  5256.         public function GetHasValidDecorationItems( items : array<SItemUniqueId>, decoration : W3HouseDecorationBase ) : bool
  5257.         {
  5258.                 var i, size : int;
  5259.                
  5260.                 size = items.Size();
  5261.                
  5262.                
  5263.                 if(size == 0 )
  5264.                 {
  5265.                         LogChannel( 'houseDecorations', "No items with valid tag were found!" );
  5266.                         return false;
  5267.                 }
  5268.                
  5269.                
  5270.                 for( i=0; i < size; i+= 1 )
  5271.                 {      
  5272.                        
  5273.                         if( GetWitcherPlayer().IsItemEquipped( items[i] ) )
  5274.                         {
  5275.                                 LogChannel( 'houseDecorations', "Found item is equipped, erasing..." );
  5276.                                 continue;
  5277.                         }
  5278.                        
  5279.                        
  5280.                         if( IsItemQuest( items[i] ) && decoration.GetAcceptQuestItems() == false )
  5281.                         {
  5282.                                 LogChannel( 'houseDecorations', "Found item is quest item, and quest items are not accepted, erasing..." );
  5283.                                 continue;
  5284.                         }
  5285.                        
  5286.                        
  5287.                         if( decoration.GetItemHasForbiddenTag( items[i] ) )
  5288.                         {
  5289.                                 LogChannel( 'houseDecorations', "Found item has a forbidden tag, erasing..." );
  5290.                                 continue;
  5291.                         }
  5292.                        
  5293.                         LogChannel( 'houseDecorations', "Item checks out: "+ GetItemName( items[i] ) );
  5294.                         return true;
  5295.                 }
  5296.                 LogChannel( 'houseDecorations', "No valid items were found!" );
  5297.                
  5298.                 return false;  
  5299.         }      
  5300.        
  5301.        
  5302.         function GetMissingCards() : array< name >
  5303.         {
  5304.                 var defMgr                      : CDefinitionsManagerAccessor   = theGame.GetDefinitionsManager();
  5305.                 var allCardNames        : array< name >                                 = defMgr.GetItemsWithTag(theGame.params.GWINT_CARD_ACHIEVEMENT_TAG);
  5306.                 var playersCards        : array< SItemUniqueId >                = GetItemsByTag(theGame.params.GWINT_CARD_ACHIEVEMENT_TAG);
  5307.                 var playersCardLocs     : array< string >;
  5308.                 var missingCardLocs     : array< string >;
  5309.                 var missingCards        : array< name >;
  5310.                 var i, j                        : int;
  5311.                 var found                       : bool;
  5312.                
  5313.                
  5314.                 for ( i = 0; i < allCardNames.Size(); i+=1 )
  5315.                 {
  5316.                         found = false;
  5317.                        
  5318.                         for ( j = 0; j < playersCards.Size(); j+=1 )
  5319.                         {
  5320.                                 if ( allCardNames[i] == GetItemName( playersCards[j] ) )
  5321.                                 {
  5322.                                         found = true;
  5323.                                         playersCardLocs.PushBack( defMgr.GetItemLocalisationKeyName ( allCardNames[i] ) );
  5324.                                         break;
  5325.                                 }
  5326.                         }
  5327.                        
  5328.                         if ( !found )
  5329.                         {
  5330.                                 missingCardLocs.PushBack( defMgr.GetItemLocalisationKeyName( allCardNames[i] ) );
  5331.                                 missingCards.PushBack( allCardNames[i] );
  5332.                         }
  5333.                 }
  5334.                
  5335.                 if( missingCardLocs.Size() < 2 )
  5336.                 {
  5337.                         return missingCards;
  5338.                 }
  5339.                
  5340.                
  5341.                 for ( i = missingCardLocs.Size()-1 ; i >= 0 ; i-=1 )
  5342.                 {
  5343.                         for ( j = 0 ; j < playersCardLocs.Size() ; j+=1 )
  5344.                         {
  5345.                                 if ( missingCardLocs[i] == playersCardLocs[j]
  5346.                                         && missingCardLocs[i] != "gwint_name_emhyr" && missingCardLocs[i] != "gwint_name_foltest"
  5347.                                         && missingCardLocs[i] != "gwint_name_francesca" && missingCardLocs[i] != "gwint_name_eredin" )
  5348.                                 {
  5349.                                         missingCardLocs.EraseFast( i );
  5350.                                         missingCards.EraseFast( i );
  5351.                                         break;
  5352.                                 }
  5353.                         }
  5354.                 }
  5355.                
  5356.                 return missingCards;
  5357.         }
  5358.        
  5359.         public function FindCardSources( missingCards : array< name > ) : array< SCardSourceData >
  5360.         {
  5361.                 var sourceCSV                   : C2dArray;
  5362.                 var sourceTable                 : array< SCardSourceData >;
  5363.                 var sourceRemaining             : array< SCardSourceData >;
  5364.                 var sourceCount, i, j   : int;
  5365.                
  5366.                 if ( theGame.IsFinalBuild() )
  5367.                 {
  5368.                         sourceCSV = LoadCSV("gameplay\globals\card_sources.csv");
  5369.                 }
  5370.                 else
  5371.                 {
  5372.                         sourceCSV = LoadCSV("qa\card_sources.csv");
  5373.                 }
  5374.  
  5375.                 sourceCount = sourceCSV.GetNumRows();
  5376.                 sourceTable.Resize(sourceCount);
  5377.                
  5378.                 for ( i = 0 ; i < sourceCount ; i+=1 )
  5379.                 {
  5380.                         sourceTable[i].cardName = sourceCSV.GetValueAsName("CardName",i);
  5381.                         sourceTable[i].source = sourceCSV.GetValue("Source",i);
  5382.                         sourceTable[i].originArea = sourceCSV.GetValue("OriginArea",i);
  5383.                         sourceTable[i].originQuest = sourceCSV.GetValue("OriginQuest",i);
  5384.                         sourceTable[i].details = sourceCSV.GetValue("Details",i);
  5385.                         sourceTable[i].coords = sourceCSV.GetValue("Coords",i);
  5386.                 }
  5387.                
  5388.                 for ( i = 0 ; i < missingCards.Size() ; i+=1 )
  5389.                 {
  5390.                         for ( j = 0 ; j < sourceCount ; j+=1 )
  5391.                         {
  5392.                                 if ( sourceTable[j].cardName == missingCards[i] )
  5393.                                 {
  5394.                                         sourceRemaining.PushBack( sourceTable[j] );
  5395.                                 }
  5396.                         }
  5397.                 }
  5398.                
  5399.                 return sourceRemaining;
  5400.         }
  5401.        
  5402.         public function GetGwentAlmanacContents() : string
  5403.         {
  5404.                 var sourcesRemaining    : array< SCardSourceData >;
  5405.                 var missingCards                : array< string >;
  5406.                 var almanacContents             : string;
  5407.                 var i                                   : int;
  5408.                 var NML, Novigrad, Skellige, Prologue, Vizima, KaerMorhen, Random : int;
  5409.  
  5410.                 sourcesRemaining = FindCardSources( GetMissingCards() );
  5411.                
  5412.                 for ( i = 0 ; i < sourcesRemaining.Size() ; i+=1 )
  5413.                 {
  5414.                         switch ( sourcesRemaining[i].originArea )
  5415.                         {
  5416.                                 case "NML":
  5417.                                         NML += 1;
  5418.                                         break;
  5419.                                 case "Novigrad":
  5420.                                         Novigrad += 1;
  5421.                                         break;
  5422.                                 case "Skellige":
  5423.                                         Skellige += 1;
  5424.                                         break;
  5425.                                 case "Prologue":
  5426.                                         Prologue += 1;
  5427.                                         break;
  5428.                                 case "Vizima":
  5429.                                         Vizima += 1;
  5430.                                         break;
  5431.                                 case "KaerMorhen":
  5432.                                         KaerMorhen += 1;
  5433.                                         break;
  5434.                                 case "Random":
  5435.                                         Random += 1;
  5436.                                         break;
  5437.                                 default:
  5438.                                         break;
  5439.                         }
  5440.                 }
  5441.                
  5442.                 if ( NML + Novigrad + Skellige + Prologue + Vizima + KaerMorhen + Random == 0 )
  5443.                 {
  5444.                         almanacContents = GetLocStringByKeyExt( "gwent_almanac_text" ) + "<br>";
  5445.                         almanacContents += GetLocStringByKeyExt( "gwent_almanac_completed_text" );
  5446.                 }
  5447.                 else
  5448.                 {
  5449.                         almanacContents = GetLocStringByKeyExt( "gwent_almanac_text" ) + "<br>";
  5450.                         if ( NML > 0 )
  5451.                         {
  5452.                                 almanacContents += GetLocStringByKeyExt( "location_name_velen" ) + ": " + NML + "<br>";
  5453.                         }
  5454.                         if ( Novigrad > 0 )
  5455.                         {
  5456.                                 almanacContents += GetLocStringByKeyExt( "map_location_novigrad" ) + ": " + Novigrad + "<br>";
  5457.                         }
  5458.                         if ( Skellige > 0 )
  5459.                         {
  5460.                                 almanacContents += GetLocStringByKeyExt( "map_location_skellige" ) + ": " + Skellige + "<br>";
  5461.                         }
  5462.                         if ( Prologue > 0 )
  5463.                         {
  5464.                                 almanacContents += GetLocStringByKeyExt( "map_location_prolog_village" ) + ": " + Prologue + "<br>";
  5465.                         }
  5466.                         if ( Vizima > 0 )
  5467.                         {
  5468.                                 almanacContents += GetLocStringByKeyExt( "map_location_wyzima_castle" ) + ": " + Vizima + "<br>";
  5469.                         }
  5470.                         if ( KaerMorhen > 0 )
  5471.                         {
  5472.                                 almanacContents += GetLocStringByKeyExt( "map_location_kaer_morhen" ) + ": " + KaerMorhen + "<br>";
  5473.                         }
  5474.                         almanacContents += GetLocStringByKeyExt( "gwent_source_random" ) + ": " + Random;
  5475.                 }
  5476.                
  5477.                 return almanacContents;
  5478.         }
  5479.        
  5480.         public function GetUnusedMutagensCount(itemName:name):int
  5481.         {
  5482.                 var items  : array<SItemUniqueId>;
  5483.                 var equippedOnSlot : EEquipmentSlots;
  5484.                 var availableCount : int;
  5485.                 var res, i : int = 0;
  5486.                
  5487.                 items = thePlayer.inv.GetItemsByName(itemName);
  5488.                
  5489.                 for(i=0; i<items.Size(); i+=1)
  5490.                 {
  5491.                         equippedOnSlot = GetWitcherPlayer().GetItemSlot( items[i] );                   
  5492.                        
  5493.                         if(equippedOnSlot == EES_InvalidSlot)
  5494.                         {
  5495.                                 availableCount = thePlayer.inv.GetItemQuantity( items[i] );
  5496.                                 res = res + availableCount;
  5497.                         }
  5498.                 }
  5499.                
  5500.                 return res;
  5501.         }
  5502.        
  5503.         public function GetFirstUnusedMutagenByName( itemName : name ):SItemUniqueId
  5504.         {
  5505.                 var items  : array<SItemUniqueId>;
  5506.                 var equippedOnSlot : EEquipmentSlots;
  5507.                 var availableCount : int;
  5508.                 var res, i : int = 0;
  5509.                
  5510.                 items = thePlayer.inv.GetItemsByName(itemName);
  5511.                
  5512.                 for(i=0; i<items.Size(); i+=1)
  5513.                 {
  5514.                         equippedOnSlot = GetWitcherPlayer().GetItemSlot( items[i] );                   
  5515.                        
  5516.                         if( equippedOnSlot == EES_InvalidSlot )
  5517.                         {
  5518.                                 return items[i];
  5519.                         }
  5520.                 }
  5521.                
  5522.                 return GetInvalidUniqueId();
  5523.         }
  5524.        
  5525.         public function RemoveUnusedMutagensCountById( itemId:SItemUniqueId, count:int ):void
  5526.         {
  5527.                 RemoveUnusedMutagensCount( thePlayer.inv.GetItemName( itemId ), count );
  5528.         }
  5529.        
  5530.         public function RemoveUnusedMutagensCount( itemName:name, count:int ):void
  5531.         {
  5532.                 var items                       : array<SItemUniqueId>;
  5533.                 var curItem             : SItemUniqueId;
  5534.                 var equippedOnSlot  : EEquipmentSlots;
  5535.                
  5536.                 var i                              : int;
  5537.                 var itemRemoved            : int;
  5538.                 var availableToRemoved : int;
  5539.                 var removedRes             : bool;
  5540.                
  5541.                 itemRemoved = 0;
  5542.                 items = thePlayer.inv.GetItemsByName( itemName );
  5543.                
  5544.                 for( i=0; i < items.Size(); i+=1 )
  5545.                 {
  5546.                         curItem = items[ i ];
  5547.                         equippedOnSlot = GetWitcherPlayer().GetItemSlot( curItem );
  5548.                        
  5549.                         if( equippedOnSlot == EES_InvalidSlot )
  5550.                         {
  5551.                                 availableToRemoved = Min( thePlayer.inv.GetItemQuantity( curItem ), ( count - itemRemoved ) );
  5552.                                 removedRes = thePlayer.inv.RemoveItem(items[i], availableToRemoved);
  5553.                                
  5554.                                 if (removedRes)
  5555.                                 {
  5556.                                         itemRemoved = itemRemoved + availableToRemoved;
  5557.                                        
  5558.                                         if (itemRemoved >= count)
  5559.                                         {
  5560.                                                 return;
  5561.                                         }
  5562.                                 }
  5563.                                
  5564.                         }
  5565.                 }              
  5566.         }
  5567.        
  5568. }
  5569.  
  5570. exec function findMissingCards( optional card : name )
  5571. {
  5572.         var inv                                 : CInventoryComponent = thePlayer.GetInventory();
  5573.         var sourcesRemaining    : array< SCardSourceData >;
  5574.         var missingCards                : array< name >;
  5575.         var i                                   : int;
  5576.         var sourceLogString             : string;
  5577.        
  5578.         if ( card != '' )
  5579.         {
  5580.                 missingCards.PushBack( card );
  5581.         }
  5582.         else
  5583.         {
  5584.                 missingCards = inv.GetMissingCards();
  5585.         }
  5586.        
  5587.         sourcesRemaining = inv.FindCardSources( missingCards );
  5588.  
  5589.         for ( i = 0 ; i < sourcesRemaining.Size() ; i+=1 )
  5590.         {
  5591.                 sourceLogString = sourcesRemaining[i].cardName + " is a " + sourcesRemaining[i].source ;
  5592.                 if ( sourcesRemaining[i].originArea == "Random" )
  5593.                 {
  5594.                         sourceLogString += " card from a random merchant.";
  5595.                 }
  5596.                 else
  5597.                 {
  5598.                         sourceLogString += " item in " + sourcesRemaining[i].originArea + " from ";
  5599.                        
  5600.                         if ( sourcesRemaining[i].originQuest != "" )
  5601.                         {
  5602.                                 sourceLogString += sourcesRemaining[i].originQuest + " , ";
  5603.                         }
  5604.                        
  5605.                         sourceLogString += sourcesRemaining[i].details;
  5606.                 }
  5607.                 Log( sourceLogString );
  5608.                
  5609.                 if ( sourcesRemaining[i].coords != "" )
  5610.                 {
  5611.                         Log( sourcesRemaining[i].coords );
  5612.                 }
  5613.         }
  5614. }
  5615.  
  5616. exec function slotTest()
  5617. {
  5618.         var inv : CInventoryComponent = thePlayer.inv;
  5619.         var weaponItemId : SItemUniqueId;
  5620.         var upgradeItemId : SItemUniqueId;
  5621.         var i : int;
  5622.        
  5623.         LogChannel('SlotTest', "----------------------------------------------------------------");
  5624.  
  5625.        
  5626.         inv.AddAnItem( 'Perun rune', 1);
  5627.         inv.AddAnItem( 'Svarog rune', 1);
  5628.        
  5629.  
  5630.         for ( i = 0; i < 2; i += 1 )
  5631.         {
  5632.                
  5633.                 if ( !GetItem( inv, 'steelsword', weaponItemId ) ||
  5634.                          !GetItem( inv, 'upgrade', upgradeItemId ) )
  5635.                 {
  5636.                         return;
  5637.                 }
  5638.  
  5639.                
  5640.                 PrintItem( inv, weaponItemId );
  5641.        
  5642.                
  5643.                 if ( inv.EnhanceItemScript( weaponItemId, upgradeItemId ) )
  5644.                 {
  5645.                         LogChannel('SlotTest', "Enhanced item");
  5646.                 }
  5647.                 else
  5648.                 {
  5649.                         LogChannel('SlotTest', "Failed to enhance item!");
  5650.                 }
  5651.         }
  5652.        
  5653.        
  5654.         if ( !GetItem( inv, 'steelsword', weaponItemId ) )
  5655.         {
  5656.                 return;
  5657.         }
  5658.  
  5659.        
  5660.         PrintItem( inv, weaponItemId );
  5661.        
  5662.        
  5663.         if ( inv.RemoveItemEnhancementByNameScript( weaponItemId, 'Svarog rune' ) )
  5664.         {
  5665.                 LogChannel('SlotTest', "Removed enhancement");
  5666.         }
  5667.         else
  5668.         {
  5669.                 LogChannel('SlotTest', "Failed to remove enhancement!");
  5670.         }
  5671.  
  5672.        
  5673.         if ( !GetItem( inv, 'steelsword', weaponItemId ) )
  5674.         {
  5675.                 return;
  5676.         }
  5677.  
  5678.        
  5679.         PrintItem( inv, weaponItemId );
  5680.  
  5681.        
  5682.         if ( inv.RemoveItemEnhancementByIndexScript( weaponItemId, 0 ) )
  5683.         {
  5684.                 LogChannel('SlotTest', "Removed enhancement");
  5685.         }
  5686.         else
  5687.         {
  5688.                 LogChannel('SlotTest', "Failed to remove enhancement!");
  5689.         }
  5690.        
  5691.        
  5692.         if ( !GetItem( inv, 'steelsword', weaponItemId ) )
  5693.         {
  5694.                 return;
  5695.         }
  5696.  
  5697.        
  5698.         PrintItem( inv, weaponItemId );
  5699. }
  5700.  
  5701. function GetItem( inv : CInventoryComponent, category : name, out itemId : SItemUniqueId ) : bool
  5702. {
  5703.         var itemIds : array< SItemUniqueId >;
  5704.  
  5705.         itemIds = inv.GetItemsByCategory( category );
  5706.         if ( itemIds.Size() > 0 )
  5707.         {
  5708.                 itemId = itemIds[ 0 ];
  5709.                 return true;
  5710.         }
  5711.         LogChannel( 'SlotTest', "Failed to get item with GetItemsByCategory( '" + category + "' )" );
  5712.         return false;
  5713. }
  5714.  
  5715. function PrintItem( inv : CInventoryComponent, weaponItemId : SItemUniqueId )
  5716. {
  5717.         var names : array< name >;
  5718.         var tags : array< name >;
  5719.         var i : int;
  5720.         var line : string;
  5721.         var attribute : SAbilityAttributeValue;
  5722.  
  5723.         LogChannel('SlotTest', "Slots:                         " + inv.GetItemEnhancementCount( weaponItemId ) + "/" + inv.GetItemEnhancementSlotsCount( weaponItemId ) );
  5724.         inv.GetItemEnhancementItems( weaponItemId, names );
  5725.         if ( names.Size() > 0 )
  5726.         {
  5727.                 for ( i = 0; i < names.Size(); i += 1 )
  5728.                 {
  5729.                         if ( i == 0 )
  5730.                         {
  5731.                                 line += "[";
  5732.                         }
  5733.                         line += names[ i ];
  5734.                         if ( i < names.Size() - 1 )
  5735.                         {
  5736.                                 line += ", ";
  5737.                         }
  5738.                         if ( i == names.Size() - 1 )
  5739.                         {
  5740.                                 line += "]";
  5741.                         }
  5742.                 }
  5743.         }
  5744.         else
  5745.         {
  5746.                 line += "[]";
  5747.         }
  5748.         LogChannel('SlotTest', "Upgrade item names             " + line );
  5749.        
  5750.         tags.PushBack('Upgrade');
  5751.  
  5752.         attribute = inv.GetItemAttributeValue( weaponItemId, 'PhysicalDamage' );
  5753.         LogChannel('SlotTest', "Attribute '" + 'PhysicalDamage' + "'      " + attribute.valueBase + " " + attribute.valueMultiplicative + " " + attribute.valueAdditive );
  5754.         attribute = inv.GetItemAttributeValue( weaponItemId, 'SilverDamage' );
  5755.         LogChannel('SlotTest', "Attribute '" + 'SilverDamage' + "'      " + attribute.valueBase + " " + attribute.valueMultiplicative + " " + attribute.valueAdditive );
  5756.        
  5757.         attribute = inv.GetItemAttributeValue( weaponItemId, 'PhysicalDamage', tags, true );
  5758.         LogChannel('SlotTest', "Attribute '" + 'PhysicalDamage' + "'      " + attribute.valueBase + " " + attribute.valueMultiplicative + " " + attribute.valueAdditive );
  5759.         attribute = inv.GetItemAttributeValue( weaponItemId, 'SilverDamage', tags, true  );
  5760.         LogChannel('SlotTest', "Attribute '" + 'SilverDamage' + "'      " + attribute.valueBase + " " + attribute.valueMultiplicative + " " + attribute.valueAdditive );
  5761.  
  5762.         attribute = inv.GetItemAttributeValue( weaponItemId, 'PhysicalDamage', tags );
  5763.         LogChannel('SlotTest', "Attribute '" + 'PhysicalDamage' + "'      " + attribute.valueBase + " " + attribute.valueMultiplicative + " " + attribute.valueAdditive );
  5764.         attribute = inv.GetItemAttributeValue( weaponItemId, 'SilverDamage', tags );
  5765.         LogChannel('SlotTest', "Attribute '" + 'SilverDamage' + "'      " + attribute.valueBase + " " + attribute.valueMultiplicative + " " + attribute.valueAdditive );
  5766.  
  5767. }
  5768.  
  5769. function PlayItemEquipSound( itemCategory : name ) : void
  5770. {
  5771.         switch( itemCategory )
  5772.         {
  5773.                 case 'steelsword' :
  5774.                         theSound.SoundEvent("gui_inventory_steelsword_attach");
  5775.                         return;
  5776.                 case 'silversword' :
  5777.                         theSound.SoundEvent("gui_inventory_silversword_attach");
  5778.                         return;
  5779.                 case 'secondary' :
  5780.                         theSound.SoundEvent("gui_inventory_weapon_attach");
  5781.                         return;
  5782.                 case 'armor' :
  5783.                         theSound.SoundEvent("gui_inventory_armor_attach");
  5784.                         return;
  5785.                 case 'pants' :
  5786.                         theSound.SoundEvent("gui_inventory_pants_attach");
  5787.                         return;
  5788.                 case 'boots' :
  5789.                         theSound.SoundEvent("gui_inventory_boots_attach");
  5790.                         return;
  5791.                 case 'gloves' :
  5792.                         theSound.SoundEvent("gui_inventory_gauntlet_attach");
  5793.                         return;
  5794.                 case 'potion' :
  5795.                         theSound.SoundEvent("gui_inventory_potion_attach");
  5796.                         return;
  5797.                 case 'petard' :
  5798.                         theSound.SoundEvent("gui_inventory_bombs_attach");
  5799.                         return;                
  5800.                 case 'ranged' :
  5801.                         theSound.SoundEvent("gui_inventory_ranged_attach");
  5802.                         return;
  5803.                 case 'herb' :
  5804.                         theSound.SoundEvent("gui_pick_up_herbs");
  5805.                         return;
  5806.                 case 'trophy' :
  5807.                 case 'horse_bag' :
  5808.                         theSound.SoundEvent("gui_inventory_horse_bage_attach");
  5809.                         return;
  5810.                 case 'horse_blinder' :
  5811.                         theSound.SoundEvent("gui_inventory_horse_blinder_attach");
  5812.                         return;
  5813.                 case 'horse_saddle'     :      
  5814.                         theSound.SoundEvent("gui_inventory_horse_saddle_attach");
  5815.                         return;
  5816.                 default :
  5817.                         theSound.SoundEvent("gui_inventory_other_attach");
  5818.                         return;
  5819.         }
  5820. }
  5821.  
  5822. function PlayItemUnequipSound( itemCategory : name ) : void
  5823. {      
  5824.         switch( itemCategory )
  5825.         {
  5826.                 case 'steelsword' :
  5827.                         theSound.SoundEvent("gui_inventory_steelsword_back");
  5828.                         return;
  5829.                 case 'silversword' :
  5830.                         theSound.SoundEvent("gui_inventory_silversword_back");
  5831.                         return;
  5832.                 case 'secondary' :
  5833.                         theSound.SoundEvent("gui_inventory_weapon_back");
  5834.                         return;
  5835.                 case 'armor' :
  5836.                         theSound.SoundEvent("gui_inventory_armor_back");
  5837.                         return;
  5838.                 case 'pants' :
  5839.                         theSound.SoundEvent("gui_inventory_pants_back");
  5840.                         return;
  5841.                 case 'boots' :
  5842.                         theSound.SoundEvent("gui_inventory_boots_back");
  5843.                         return;
  5844.                 case 'gloves' :
  5845.                         theSound.SoundEvent("gui_inventory_gauntlet_back");
  5846.                         return;
  5847.                 case 'petard' :
  5848.                         theSound.SoundEvent("gui_inventory_bombs_back");
  5849.                         return;                
  5850.                 case 'potion' :
  5851.                         theSound.SoundEvent("gui_inventory_potion_back");
  5852.                         return;
  5853.                 case 'ranged' :
  5854.                         theSound.SoundEvent("gui_inventory_ranged_back");
  5855.                         return;
  5856.                 case 'trophy' :
  5857.                 case 'horse_bag' :
  5858.                         theSound.SoundEvent("gui_inventory_horse_bage_back");
  5859.                         return;
  5860.                 case 'horse_blinder' :
  5861.                         theSound.SoundEvent("gui_inventory_horse_blinder_back");
  5862.                         return;
  5863.                 case 'horse_saddle'     :      
  5864.                         theSound.SoundEvent("gui_inventory_horse_saddle_back");
  5865.                         return;
  5866.                 default :
  5867.                         theSound.SoundEvent("gui_inventory_other_back");
  5868.                         return;
  5869.         }
  5870. }
  5871.  
  5872. function PlayItemConsumeSound( item : SItemUniqueId ) : void
  5873. {
  5874.         if( thePlayer.GetInventory().ItemHasTag( item, 'Drinks' ) || thePlayer.GetInventory().ItemHasTag( item, 'Alcohol' ) )
  5875.         {
  5876.                 theSound.SoundEvent('gui_inventory_drink');
  5877.         }
  5878.         else
  5879.         {
  5880.                 theSound.SoundEvent('gui_inventory_eat');
  5881.         }
  5882. }
  5883.  
  5884.  
  5885.  
  5886.  
  5887.