SHARE
TWEET

Untitled

a guest Feb 17th, 2020 76 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. statemachine class W3PlayerWitcher extends CR4Player
  11. {  
  12.    
  13.     private saved var craftingSchematics                : array<name>;                 
  14.     private saved var expandedCraftingCategories        : array<name>;
  15.     private saved var craftingFilters : SCraftingFilters;
  16.    
  17.    
  18.     private saved var alchemyRecipes                    : array<name>;                 
  19.     private saved var expandedAlchemyCategories         : array<name>;
  20.     private saved var alchemyFilters : SCraftingFilters;
  21.    
  22.    
  23.     private saved var expandedBestiaryCategories        : array<name>;
  24.    
  25.     // AeroHD -- AutoLootMenu++
  26.     private var mAutoLootConfig : CAHDAutoLootConfig;
  27.     private var mAutoLootNotificationManager : CAHDAutoLootNotificationManager;
  28.     // AeroHD -- AutoLootMenu--
  29.    
  30.     private saved var booksRead                         : array<name>;                 
  31.    
  32.    
  33.     private             var fastAttackCounter, heavyAttackCounter   : int;     
  34.     private             var isInFrenzy : bool;
  35.     private             var hasRecentlyCountered : bool;
  36.     private saved       var cannotUseUndyingSkill : bool;                      
  37.     private saved       var cannotUseUndyingSkill2 : bool;     
  38.    
  39.     protected saved         var amountOfSetPiecesEquipped           : array<int>;
  40.    
  41.    
  42.     public              var canSwitchFocusModeTarget    : bool;
  43.     protected           var switchFocusModeTargetAllowed : bool;
  44.         default canSwitchFocusModeTarget = true;
  45.         default switchFocusModeTargetAllowed = true;
  46.    
  47.    
  48.     private editable    var signs                       : array< SWitcherSign >;
  49.     private saved       var equippedSign                : ESignType;
  50.     private             var currentlyCastSign           : ESignType; default currentlyCastSign = ST_None;
  51.     private             var signOwner                   : W3SignOwnerPlayer;
  52.     private             var usedQuenInCombat            : bool;
  53.     public              var yrdenEntities               : array<W3YrdenEntity>;
  54.     public saved        var m_quenReappliedCount        : int;
  55.     public saved        var m_quickInventorySaveData    : WmkQuickInventorySaveData; // -= WMK:modQuickSlots =-
  56.    
  57.     default             equippedSign    = ST_Aard;
  58.     default             m_quenReappliedCount = 1;
  59.    
  60.    
  61.    
  62.     private             var bDispalyHeavyAttackIndicator        : bool;
  63.     private             var bDisplayHeavyAttackFirstLevelTimer  : bool;
  64.     public              var specialAttackHeavyAllowed           : bool;
  65.  
  66.     default bIsCombatActionAllowed = true; 
  67.     default bDispalyHeavyAttackIndicator = false;
  68.     default bDisplayHeavyAttackFirstLevelTimer = true;
  69.    
  70.    
  71.    
  72.         default explorationInputContext = 'Exploration';
  73.         default combatInputContext = 'Combat';
  74.         default combatFistsInputContext = 'Combat';
  75.        
  76.    
  77.     private saved var companionNPCTag       : name;
  78.     private saved var companionNPCTag2      : name;
  79.    
  80.     private saved var companionNPCIconPath  : string;
  81.     private saved var companionNPCIconPath2 : string;  
  82.        
  83.    
  84.     private       saved var itemSlots                   : array<SItemUniqueId>;
  85.     private             var remainingBombThrowDelaySlot1    : float;
  86.     private             var remainingBombThrowDelaySlot2    : float;
  87.     private             var previouslyUsedBolt : SItemUniqueId;            
  88.     private       saved var questMarkedSelectedQuickslotItems : array< SSelectedQuickslotItem >;
  89.    
  90.     default isThrowingItem = false;
  91.     default remainingBombThrowDelaySlot1 = 0.f;
  92.     default remainingBombThrowDelaySlot2 = 0.f;
  93.    
  94.    
  95.    
  96.    
  97.    
  98.     private saved var tempLearnedSignSkills : array<SSimpleSkill>;     
  99.     public  saved var autoLevel             : bool;                    
  100.    
  101.    
  102.    
  103.    
  104.     protected saved var skillBonusPotionEffect          : CBaseGameplayEffect;         
  105.    
  106.    
  107.     public saved        var levelManager                : W3LevelManager;
  108.  
  109.    
  110.     saved var reputationManager : W3Reputation;
  111.    
  112.    
  113.     private editable    var medallionEntity         : CEntityTemplate;
  114.     private             var medallionController     : W3MedallionController;
  115.    
  116.    
  117.    
  118.    
  119.     public              var bShowRadialMenu : bool;
  120.  
  121.     private             var _HoldBeforeOpenRadialMenuTime : float;
  122.    
  123.     default _HoldBeforeOpenRadialMenuTime = 0.5f;
  124.    
  125.     public var MappinToHighlight : array<SHighlightMappin>;
  126.    
  127.    
  128.     protected saved var horseManagerHandle          : EntityHandle;    
  129.    
  130.  
  131.     private var isInitialized : bool;
  132.     private var timeForPerk21 : float;
  133.    
  134.         default isInitialized = false;
  135.        
  136.    
  137.     private var invUpdateTransaction : bool;
  138.         default invUpdateTransaction = false;
  139.    
  140.     event OnSpawned( spawnData : SEntitySpawnData )
  141.     {
  142.         var i               : int;
  143.         var items           : array<SItemUniqueId>;
  144.         var items2          : array<SItemUniqueId>;
  145.         var horseTemplate   : CEntityTemplate;
  146.         var horseManager    : W3HorseManager;
  147.        
  148.         AddAnimEventCallback( 'ActionBlend',            'OnAnimEvent_ActionBlend' );
  149.         AddAnimEventCallback('cast_begin',              'OnAnimEvent_Sign');
  150.         AddAnimEventCallback('cast_throw',              'OnAnimEvent_Sign');
  151.         AddAnimEventCallback('cast_end',                'OnAnimEvent_Sign');
  152.         AddAnimEventCallback('cast_friendly_begin',     'OnAnimEvent_Sign');
  153.         AddAnimEventCallback('cast_friendly_throw',     'OnAnimEvent_Sign');
  154.         AddAnimEventCallback('axii_ready',              'OnAnimEvent_Sign');
  155.         AddAnimEventCallback('axii_alternate_ready',    'OnAnimEvent_Sign');
  156.         AddAnimEventCallback('yrden_draw_ready',        'OnAnimEvent_Sign');
  157.        
  158.         AddAnimEventCallback( 'ProjectileThrow',    'OnAnimEvent_Throwable' );
  159.         AddAnimEventCallback( 'OnWeaponReload',     'OnAnimEvent_Throwable' );
  160.         AddAnimEventCallback( 'ProjectileAttach',   'OnAnimEvent_Throwable' );
  161.         AddAnimEventCallback( 'Mutation11AnimEnd',  'OnAnimEvent_Mutation11AnimEnd' );
  162.         AddAnimEventCallback( 'Mutation11ShockWave', 'OnAnimEvent_Mutation11ShockWave' );
  163.        
  164.  
  165.        
  166.         amountOfSetPiecesEquipped.Resize( EnumGetMax( 'EItemSetType' ) + 1 );
  167.        
  168.         runewordInfusionType = ST_None;
  169.                
  170.        
  171.         inv = GetInventory();          
  172.  
  173.        
  174.         signOwner = new W3SignOwnerPlayer in this;
  175.         signOwner.Init( this );
  176.        
  177.         itemSlots.Resize( EnumGetMax('EEquipmentSlots')+1 );
  178.  
  179.         if(!spawnData.restored)
  180.         {
  181.             levelManager = new W3LevelManager in this;         
  182.             levelManager.Initialize();
  183.            
  184.            
  185.             inv.GetAllItems(items);
  186.             for(i=0; i<items.Size(); i+=1)
  187.             {
  188.                 if(inv.IsItemMounted(items[i]) && ( !inv.IsItemBody(items[i]) || inv.GetItemCategory(items[i]) == 'hair' ) )
  189.                     EquipItem(items[i]);
  190.             }
  191.            
  192.            
  193.            
  194.            
  195.            
  196.             AddAlchemyRecipe('Recipe for Swallow 1',true,true);
  197.             AddAlchemyRecipe('Recipe for Cat 1',true,true);
  198.             AddAlchemyRecipe('Recipe for White Honey 1',true,true);
  199.            
  200.             AddAlchemyRecipe('Recipe for Samum 1',true,true);
  201.             AddAlchemyRecipe('Recipe for Grapeshot 1',true,true);
  202.            
  203.             AddAlchemyRecipe('Recipe for Specter Oil 1',true,true);
  204.             AddAlchemyRecipe('Recipe for Necrophage Oil 1',true,true);
  205.             AddAlchemyRecipe('Recipe for Alcohest 1',true,true);
  206.         }
  207.         else
  208.         {
  209.             AddTimer('DelayedOnItemMount', 0.1, true);
  210.            
  211.            
  212.             CheckHairItem();
  213.         }
  214.        
  215.        
  216.         AddStartingSchematics();
  217.  
  218.         super.OnSpawned( spawnData );
  219.        
  220.        
  221.         AddAlchemyRecipe('Recipe for Mutagen red',true,true);
  222.         AddAlchemyRecipe('Recipe for Mutagen green',true,true);
  223.         AddAlchemyRecipe('Recipe for Mutagen blue',true,true);
  224.         AddAlchemyRecipe('Recipe for Greater mutagen red',true,true);
  225.         AddAlchemyRecipe('Recipe for Greater mutagen green',true,true);
  226.         AddAlchemyRecipe('Recipe for Greater mutagen blue',true,true);
  227.        
  228.         AddCraftingSchematic('Starting Armor Upgrade schematic 1',true,true);
  229.        
  230.        
  231.         if( inputHandler )
  232.         {
  233.             inputHandler.BlockAllActions( 'being_ciri', false );
  234.         }
  235.         SetBehaviorVariable( 'test_ciri_replacer', 0.0f);
  236.        
  237.         if(!spawnData.restored)
  238.         {
  239.            
  240.             abilityManager.GainStat(BCS_Toxicity, 0);      
  241.         }      
  242.        
  243.         levelManager.PostInit(this, spawnData.restored, true);
  244.        
  245.         SetBIsCombatActionAllowed( true );     
  246.         SetBIsInputAllowed( true, 'OnSpawned' );               
  247.        
  248.        
  249.         if ( !reputationManager )
  250.         {
  251.             reputationManager = new W3Reputation in this;
  252.             reputationManager.Initialize();
  253.         }
  254.        
  255.         theSound.SoundParameter( "focus_aim", 1.0f, 1.0f );
  256.         theSound.SoundParameter( "focus_distance", 0.0f, 1.0f );
  257.        
  258.        
  259.         currentlyCastSign = ST_None;
  260.        
  261.        
  262.         if(!spawnData.restored)
  263.         {
  264.             horseTemplate = (CEntityTemplate)LoadResource("horse_manager");
  265.             horseManager = (W3HorseManager)theGame.CreateEntity(horseTemplate, GetWorldPosition(),,,,,PM_Persist);
  266.             horseManager.CreateAttachment(this);
  267.             horseManager.OnCreated();
  268.             EntityHandleSet( horseManagerHandle, horseManager );
  269.         }
  270.         else
  271.         {
  272.             AddTimer('DelayedHorseUpdate', 0.01, true);
  273.         }
  274.        
  275.        
  276.         RemoveAbility('Ciri_CombatRegen');
  277.         RemoveAbility('Ciri_Rage');
  278.         RemoveAbility('CiriBlink');
  279.         RemoveAbility('CiriCharge');
  280.         RemoveAbility('Ciri_Q205');
  281.         RemoveAbility('Ciri_Q305');
  282.         RemoveAbility('Ciri_Q403');
  283.         RemoveAbility('Ciri_Q111');
  284.         RemoveAbility('Ciri_Q501');
  285.         RemoveAbility('SkillCiri');
  286.        
  287.         if(spawnData.restored)
  288.         {
  289.             RestoreQuen(savedQuenHealth, savedQuenDuration);           
  290.         }
  291.         else
  292.         {
  293.             savedQuenHealth = 0.f;
  294.             savedQuenDuration = 0.f;
  295.         }
  296.        
  297.         if(spawnData.restored)
  298.         {
  299.             ApplyPatchFixes();
  300.         }
  301.         else
  302.         {
  303.            
  304.             FactsAdd( "new_game_started_in_1_20" );
  305.         }
  306.        
  307.         if ( spawnData.restored )
  308.         {
  309.             FixEquippedMutagens();
  310.         }
  311.        
  312.         if ( FactsQuerySum("NewGamePlus") > 0 )
  313.         {
  314.             NewGamePlusAdjustDLC1TemerianSet(inv);
  315.             NewGamePlusAdjustDLC5NilfgardianSet(inv);
  316.             NewGamePlusAdjustDLC10WolfSet(inv);
  317.             NewGamePlusAdjustDLC14SkelligeSet(inv);
  318.             if(horseManager)
  319.             {
  320.                 NewGamePlusAdjustDLC1TemerianSet(horseManager.GetInventoryComponent());
  321.                 NewGamePlusAdjustDLC5NilfgardianSet(horseManager.GetInventoryComponent());
  322.                 NewGamePlusAdjustDLC10WolfSet(horseManager.GetInventoryComponent());
  323.                 NewGamePlusAdjustDLC14SkelligeSet(horseManager.GetInventoryComponent());
  324.             }
  325.         }
  326.        
  327.        
  328.         ResumeStaminaRegen('WhirlSkill');
  329.        
  330.         if(HasAbility('Runeword 4 _Stats', true))
  331.             StartVitalityRegen();
  332.        
  333.        
  334.         if(HasAbility('sword_s19'))
  335.         {
  336.             RemoveTemporarySkills();
  337.         }
  338.        
  339.         HACK_UnequipWolfLiver();
  340.        
  341.         // AeroHD -- AutoLootMenu++
  342.         mAutoLootConfig = new CAHDAutoLootConfig in this;
  343.         mAutoLootNotificationManager = new CAHDAutoLootNotificationManager in this;
  344.         AddTimer('InitAHDAutoLoot', 3.0);
  345.         // AeroHD -- AutoLootMenu--
  346.        
  347.         if( HasBuff( EET_GryphonSetBonusYrden ) )
  348.         {
  349.             RemoveBuff( EET_GryphonSetBonusYrden, false, "GryphonSetBonusYrden" );
  350.         }
  351.        
  352.         // -= WMK:modQuickSlots =-
  353.         if (WmkGetQuickInventoryInstance()) {
  354.             WmkGetQuickInventoryInstance().OnPlayerWitcherSpawned();
  355.         }
  356.         // -= WMK:modQuickSlots =-
  357.        
  358.         if( spawnData.restored )
  359.         {
  360.            
  361.             UpdateEncumbrance();
  362.            
  363.            
  364.             RemoveBuff( EET_Mutation11Immortal );
  365.             RemoveBuff( EET_Mutation11Buff );
  366.         }
  367.        
  368.         //ModHoSBurningMark
  369.         AddTimer('HoSBurningMark', 0.5f, true);
  370.        
  371.         AddTimer('HoSBurningMarkStop', 90.f, true);
  372.         //ModHoSBurningMark        
  373.        
  374.         theGame.GameplayFactsAdd( "PlayerIsGeralt" );
  375.        
  376.         isInitialized = true;
  377.        
  378.         if(IsMutationActive( EPMT_Mutation6 ))
  379.             if(( ( W3PlayerAbilityManager ) abilityManager ).GetMutationSoundBank(( EPMT_Mutation6 ))!="")
  380.                 theSound.SoundLoadBank( ( ( W3PlayerAbilityManager ) abilityManager ).GetMutationSoundBank(( EPMT_Mutation6 )), true );
  381.     }
  382.    
  383.     //ModHoSBurningMark
  384.     timer function HoSBurningMark( dt : float, id : int )
  385.     {
  386.         var i                 : int;
  387.         var items             : array<SItemUniqueId>;
  388.         var head               : CEntity;
  389.        
  390.         items = inv.GetItemsByCategory('head');
  391.         for(i=0; i<items.Size(); i+=1)
  392.         {
  393.             head = inv.GetItemEntityUnsafe(items[i]);
  394.             head.PlayEffect('geralt_face_mark_branding');
  395.         }
  396.     }
  397.  
  398.     timer function HoSBurningMarkStop( dt : float, id : int )
  399.     {
  400.         var i                 : int;
  401.         var items             : array<SItemUniqueId>;
  402.         var head               : CEntity;
  403.         items = inv.GetItemsByCategory('head');
  404.         for(i=0; i<items.Size(); i+=1)
  405.         {
  406.             head = inv.GetItemEntityUnsafe(items[i]);
  407.             head.StopEffect('geralt_face_mark_branding');
  408.         }
  409.     }
  410.     //ModHoSBurningMark    
  411.     private function HACK_UnequipWolfLiver()
  412.     {
  413.         var itemName1, itemName2, itemName3, itemName4 : name;
  414.         var item1, item2, item3, item4 : SItemUniqueId;
  415.        
  416.         GetItemEquippedOnSlot( EES_Potion1, item1 );
  417.         GetItemEquippedOnSlot( EES_Potion2, item2 );
  418.         GetItemEquippedOnSlot( EES_Potion3, item3 );
  419.         GetItemEquippedOnSlot( EES_Potion4, item4 );
  420.  
  421.         if ( inv.IsIdValid( item1 ) )
  422.             itemName1 = inv.GetItemName( item1 );
  423.         if ( inv.IsIdValid( item2 ) )
  424.             itemName2 = inv.GetItemName( item2 );
  425.         if ( inv.IsIdValid( item3 ) )
  426.             itemName3 = inv.GetItemName( item3 );
  427.         if ( inv.IsIdValid( item4 ) )
  428.             itemName4 = inv.GetItemName( item4 );
  429.  
  430.         if ( itemName1 == 'Wolf liver' || itemName3 == 'Wolf liver' )
  431.         {
  432.             if ( inv.IsIdValid( item1 ) )
  433.                 UnequipItem( item1 );
  434.             if ( inv.IsIdValid( item3 ) )
  435.                 UnequipItem( item3 );
  436.         }
  437.         else if ( itemName2 == 'Wolf liver' || itemName4 == 'Wolf liver' )
  438.         {
  439.             if ( inv.IsIdValid( item2 ) )
  440.                 UnequipItem( item2 );
  441.             if ( inv.IsIdValid( item4 ) )
  442.                 UnequipItem( item4 );
  443.         }
  444.     }
  445.    
  446.    
  447.    
  448.    
  449.  
  450.     timer function DelayedHorseUpdate( dt : float, id : int )
  451.     {
  452.         var man : W3HorseManager;
  453.        
  454.         man = GetHorseManager();
  455.         if(man)
  456.         {
  457.             if ( man.ApplyHorseUpdateOnSpawn() )
  458.             {
  459.                
  460.                 UpdateEncumbrance();
  461.                
  462.                 RemoveTimer( 'DelayedHorseUpdate' );
  463.             }
  464.         }
  465.     }  
  466.    
  467.     event OnAbilityAdded( abilityName : name)
  468.     {
  469.         super.OnAbilityAdded(abilityName);
  470.        
  471.         if( HasAbility('Runeword 4 _Stats', true) )
  472.         {
  473.             StartVitalityRegen();
  474.         }
  475.            
  476.         if ( abilityName == 'Runeword 8 _Stats' && GetStat(BCS_Focus, true) >= GetStatMax(BCS_Focus) && !HasBuff(EET_Runeword8) )
  477.         {
  478.             AddEffectDefault(EET_Runeword8, this, "equipped item");
  479.         }
  480.  
  481.     }
  482.    
  483.     private final function AddStartingSchematics()
  484.     {
  485.         AddCraftingSchematic('Starting Armor Upgrade schematic 1',  true,true);
  486.         AddCraftingSchematic('Thread schematic',                    true, true);
  487.         AddCraftingSchematic('String schematic',                    true, true);
  488.         AddCraftingSchematic('Linen schematic',                     true, true);
  489.         AddCraftingSchematic('Silk schematic',                      true, true);
  490.         AddCraftingSchematic('Resin schematic',                     true, true);
  491.         AddCraftingSchematic('Blasting powder schematic',           true, true);
  492.         AddCraftingSchematic('Haft schematic',                      true, true);
  493.         AddCraftingSchematic('Hardened timber schematic',           true, true);
  494.         AddCraftingSchematic('Leather squares schematic',           true, true);
  495.         AddCraftingSchematic('Leather schematic',                   true, true);
  496.         AddCraftingSchematic('Hardened leather schematic',          true, true);
  497.         AddCraftingSchematic('Draconide leather schematic',         true, true);
  498.         AddCraftingSchematic('Iron ingot schematic',                true, true);
  499.         AddCraftingSchematic('Steel ingot schematic',               true, true);
  500.         AddCraftingSchematic('Steel ingot schematic 1',             true, true);
  501.         AddCraftingSchematic('Steel plate schematic',               true, true);
  502.         AddCraftingSchematic('Dark iron ingot schematic',           true, true);
  503.         AddCraftingSchematic('Dark iron plate schematic',           true, true);
  504.         AddCraftingSchematic('Dark steel ingot schematic',          true, true);
  505.         AddCraftingSchematic('Dark steel ingot schematic 1',        true, true);
  506.         AddCraftingSchematic('Dark steel plate schematic',          true, true);
  507.         AddCraftingSchematic('Silver ore schematic',                true, true);
  508.         AddCraftingSchematic('Silver ingot schematic',              true, true);
  509.         AddCraftingSchematic('Silver ingot schematic 1',            true, true);
  510.         AddCraftingSchematic('Silver plate schematic',              true, true);
  511.         AddCraftingSchematic('Meteorite ingot schematic',           true, true);
  512.         AddCraftingSchematic('Meteorite silver ingot schematic',    true, true);
  513.         AddCraftingSchematic('Meteorite silver plate schematic',    true, true);
  514.         AddCraftingSchematic('Glowing ingot schematic',             true, true);
  515.         AddCraftingSchematic('Dwimeryte ore schematic',             true, true);
  516.         AddCraftingSchematic('Dwimeryte ingot schematic',           true, true);
  517.         AddCraftingSchematic('Dwimeryte ingot schematic 1',         true, true);
  518.         AddCraftingSchematic('Dwimeryte plate schematic',           true, true);
  519.         AddCraftingSchematic('Infused dust schematic',              true, true);
  520.         AddCraftingSchematic('Infused shard schematic',             true, true);
  521.         AddCraftingSchematic('Infused crystal schematic',           true, true);
  522.  
  523.         if ( theGame.GetDLCManager().IsEP2Available() )
  524.         {
  525.             AddCraftingSchematic('Draconide infused leather schematic', true, true);
  526.             AddCraftingSchematic('Nickel ore schematic',                true, true);
  527.             AddCraftingSchematic('Cupronickel ore schematic',           true, true);
  528.             AddCraftingSchematic('Copper ore schematic',                true, true);
  529.             AddCraftingSchematic('Copper ingot schematic',              true, true);
  530.             AddCraftingSchematic('Copper plate schematic',              true, true);
  531.             AddCraftingSchematic('Green gold ore schematic',            true, true);
  532.             AddCraftingSchematic('Green gold ore schematic 1',          true, true);
  533.             AddCraftingSchematic('Green gold ingot schematic',          true, true);
  534.             AddCraftingSchematic('Green gold plate schematic',          true, true);
  535.             AddCraftingSchematic('Orichalcum ore schematic',            true, true);
  536.             AddCraftingSchematic('Orichalcum ore schematic 1',          true, true);
  537.             AddCraftingSchematic('Orichalcum ingot schematic',          true, true);
  538.             AddCraftingSchematic('Orichalcum plate schematic',          true, true);
  539.             AddCraftingSchematic('Dwimeryte enriched ore schematic',    true, true);
  540.             AddCraftingSchematic('Dwimeryte enriched ingot schematic',  true, true);
  541.             AddCraftingSchematic('Dwimeryte enriched plate schematic',  true, true);
  542.         }
  543.     }
  544.    
  545.     private final function ApplyPatchFixes()
  546.     {
  547.         var cnt, transmutationCount, mutagenCount, i, slot : int;
  548.         var transmutationAbility, itemName : name;
  549.         var pam : W3PlayerAbilityManager;
  550.         var slotId : int;
  551.         var offset : float;
  552.         var buffs : array<CBaseGameplayEffect>;
  553.         var mutagen : W3Mutagen_Effect;
  554.         var skill : SSimpleSkill;
  555.         var spentSkillPoints, swordSkillPointsSpent, alchemySkillPointsSpent, perkSkillPointsSpent, pointsToAdd : int;
  556.         var mutagens : array< W3Mutagen_Effect >;
  557.        
  558.         if(FactsQuerySum("ClearingPotionPassiveBonusFix") < 1)
  559.         {
  560.             pam = (W3PlayerAbilityManager)abilityManager;
  561.  
  562.             cnt = GetAbilityCount('sword_adrenalinegain') - pam.GetPathPointsSpent(ESP_Sword);
  563.             if(cnt > 0)
  564.                 RemoveAbilityMultiple('sword_adrenalinegain', cnt);
  565.                
  566.             cnt = GetAbilityCount('magic_staminaregen') - pam.GetPathPointsSpent(ESP_Signs);
  567.             if(cnt > 0)
  568.                 RemoveAbilityMultiple('magic_staminaregen', cnt);
  569.                
  570.             cnt = GetAbilityCount('alchemy_potionduration') - pam.GetPathPointsSpent(ESP_Alchemy);
  571.             if(cnt > 0)
  572.                 RemoveAbilityMultiple('alchemy_potionduration', cnt);
  573.        
  574.             FactsAdd("ClearingPotionPassiveBonusFix");
  575.         }
  576.                
  577.        
  578.         if(FactsQuerySum("DimeritiumSynergyFix") < 1)
  579.         {
  580.             slotId = GetSkillSlotID(S_Alchemy_s19);
  581.             if(slotId != -1)
  582.                 UnequipSkill(S_Alchemy_s19);
  583.                
  584.             RemoveAbilityAll('greater_mutagen_color_green_synergy_bonus');
  585.             RemoveAbilityAll('mutagen_color_green_synergy_bonus');
  586.             RemoveAbilityAll('mutagen_color_lesser_green_synergy_bonus');
  587.            
  588.             RemoveAbilityAll('greater_mutagen_color_blue_synergy_bonus');
  589.             RemoveAbilityAll('mutagen_color_blue_synergy_bonus');
  590.             RemoveAbilityAll('mutagen_color_lesser_blue_synergy_bonus');
  591.            
  592.             RemoveAbilityAll('greater_mutagen_color_red_synergy_bonus');
  593.             RemoveAbilityAll('mutagen_color_red_synergy_bonus');
  594.             RemoveAbilityAll('mutagen_color_lesser_red_synergy_bonus');
  595.            
  596.             if(slotId != -1)
  597.                 EquipSkill(S_Alchemy_s19, slotId);
  598.        
  599.             FactsAdd("DimeritiumSynergyFix");
  600.         }
  601.        
  602.        
  603.         if(FactsQuerySum("DontShowRecipePinTut") < 1)
  604.         {
  605.             FactsAdd( "DontShowRecipePinTut" );
  606.             TutorialScript('alchemyRecipePin', '');
  607.             TutorialScript('craftingRecipePin', '');
  608.         }
  609.        
  610.        
  611.         if(FactsQuerySum("LevelReqPotGiven") < 1)
  612.         {
  613.             FactsAdd("LevelReqPotGiven");
  614.             inv.AddAnItem('Wolf Hour', 1, false, false, true);
  615.         }
  616.        
  617.        
  618.         if(!HasBuff(EET_AutoStaminaRegen))
  619.         {
  620.             AddEffectDefault(EET_AutoStaminaRegen, this, 'autobuff', false);
  621.         }
  622.        
  623.        
  624.        
  625.         buffs = GetBuffs();
  626.         offset = 0;
  627.         mutagenCount = 0;
  628.         for(i=0; i<buffs.Size(); i+=1)
  629.         {
  630.             mutagen = (W3Mutagen_Effect)buffs[i];
  631.             if(mutagen)
  632.             {
  633.                 offset += mutagen.GetToxicityOffset();
  634.                 mutagenCount += 1;
  635.             }
  636.         }
  637.        
  638.        
  639.         if(offset != (GetStat(BCS_Toxicity) - GetStat(BCS_Toxicity, true)))
  640.             SetToxicityOffset(offset);
  641.            
  642.        
  643.         mutagenCount *= GetSkillLevel(S_Alchemy_s13);
  644.         transmutationAbility = GetSkillAbilityName(S_Alchemy_s13);
  645.         transmutationCount = GetAbilityCount(transmutationAbility);
  646.         if(mutagenCount < transmutationCount)
  647.         {
  648.             RemoveAbilityMultiple(transmutationAbility, transmutationCount - mutagenCount);
  649.         }
  650.         else if(mutagenCount > transmutationCount)
  651.         {
  652.             AddAbilityMultiple(transmutationAbility, mutagenCount - transmutationCount);
  653.         }
  654.        
  655.        
  656.         if(theGame.GetDLCManager().IsEP1Available())
  657.         {
  658.             theGame.GetJournalManager().ActivateEntryByScriptTag('TutorialJournalEnchanting', JS_Active);
  659.         }
  660.  
  661.        
  662.         if(HasAbility('sword_s19') && FactsQuerySum("Patch_Sword_s19") < 1)
  663.         {
  664.             pam = (W3PlayerAbilityManager)abilityManager;
  665.  
  666.            
  667.             skill.level = 0;
  668.             for(i = S_Magic_s01; i <= S_Magic_s20; i+=1)
  669.             {
  670.                 skill.skillType = i;               
  671.                 pam.RemoveTemporarySkill(skill);
  672.             }
  673.            
  674.            
  675.             spentSkillPoints = levelManager.GetPointsUsed(ESkillPoint);
  676.             swordSkillPointsSpent = pam.GetPathPointsSpent(ESP_Sword);
  677.             alchemySkillPointsSpent = pam.GetPathPointsSpent(ESP_Alchemy);
  678.             perkSkillPointsSpent = pam.GetPathPointsSpent(ESP_Perks);
  679.            
  680.             pointsToAdd = spentSkillPoints - swordSkillPointsSpent - alchemySkillPointsSpent - perkSkillPointsSpent;
  681.             if(pointsToAdd > 0)
  682.                 levelManager.UnspendPoints(ESkillPoint, pointsToAdd);
  683.            
  684.            
  685.             RemoveAbilityAll('sword_s19');
  686.            
  687.            
  688.             FactsAdd("Patch_Sword_s19");
  689.         }
  690.        
  691.        
  692.         if( HasAbility( 'sword_s19' ) )
  693.         {
  694.             RemoveAbilityAll( 'sword_s19' );
  695.         }
  696.        
  697.        
  698.         if(FactsQuerySum("Patch_Armor_Type_Glyphwords") < 1)
  699.         {
  700.             pam = (W3PlayerAbilityManager)abilityManager;
  701.            
  702.             pam.SetPerkArmorBonus( S_Perk_05, this );
  703.             pam.SetPerkArmorBonus( S_Perk_06, this );
  704.             pam.SetPerkArmorBonus( S_Perk_07, this );
  705.            
  706.             FactsAdd("Patch_Armor_Type_Glyphwords");
  707.         }
  708.         else if( FactsQuerySum("154999") < 1 )
  709.         {
  710.            
  711.             pam = (W3PlayerAbilityManager)abilityManager;
  712.            
  713.             pam.SetPerkArmorBonus( S_Perk_05, this );
  714.             pam.SetPerkArmorBonus( S_Perk_06, this );
  715.             pam.SetPerkArmorBonus( S_Perk_07, this );
  716.            
  717.             FactsAdd("154999");
  718.         }
  719.        
  720.         if( FactsQuerySum( "Patch_Decoction_Buff_Icons" ) < 1 )
  721.         {
  722.             mutagens = GetMutagenBuffs();
  723.             for( i=0; i<mutagens.Size(); i+=1 )
  724.             {
  725.                 itemName = DecoctionEffectTypeToItemName( mutagens[i].GetEffectType() );               
  726.                 mutagens[i].OverrideIcon( itemName );
  727.             }
  728.            
  729.             FactsAdd( "Patch_Decoction_Buff_Icons" );
  730.         }
  731.        
  732.        
  733.         if( FactsQuerySum( "154997" ) < 1 )
  734.         {
  735.             if( IsSkillEquipped( S_Alchemy_s18 ) )
  736.             {
  737.                 slot = GetSkillSlotID( S_Alchemy_s18 );
  738.                 UnequipSkill( slot );
  739.                 EquipSkill( S_Alchemy_s18, slot );
  740.             }
  741.             FactsAdd( "154997" );
  742.         }
  743.         if( FactsQuerySum( "Patch_Mutagen_Ing_Stacking" ) < 1 )
  744.         {
  745.             Patch_MutagenStacking();       
  746.             FactsAdd( "Patch_Mutagen_Ing_Stacking" );
  747.         }
  748.     }
  749.    
  750.     private final function Patch_MutagenStacking()
  751.     {
  752.         var i, j, quantity : int;
  753.         var muts : array< SItemUniqueId >;
  754.         var item : SItemUniqueId;
  755.         var mutName : name;
  756.         var wasInArray : bool;
  757.         var mutsToAdd : array< SItemParts >;
  758.         var mutToAdd : SItemParts;
  759.        
  760.         muts = inv.GetItemsByTag( 'MutagenIngredient' );
  761.         if( GetItemEquippedOnSlot( EES_SkillMutagen1, item ) )
  762.         {
  763.             muts.Remove( item );
  764.             inv.SetItemStackable( item, false );
  765.         }
  766.         if( GetItemEquippedOnSlot( EES_SkillMutagen2, item ) )
  767.         {
  768.             muts.Remove( item );
  769.             inv.SetItemStackable( item, false );
  770.         }
  771.         if( GetItemEquippedOnSlot( EES_SkillMutagen3, item ) )
  772.         {
  773.             muts.Remove( item );
  774.             inv.SetItemStackable( item, false );
  775.         }
  776.         if( GetItemEquippedOnSlot( EES_SkillMutagen4, item ) )
  777.         {
  778.             muts.Remove( item );
  779.             inv.SetItemStackable( item, false );
  780.         }
  781.        
  782.         for( i=0; i<muts.Size(); i+=1 )
  783.         {
  784.             mutName = inv.GetItemName( muts[i] );
  785.             quantity = inv.GetItemQuantity( muts[i] );
  786.            
  787.             wasInArray = false;
  788.             for( j=0; j<mutsToAdd.Size(); j+=1 )
  789.             {
  790.                 if( mutsToAdd[j].itemName == mutName )
  791.                 {
  792.                     mutsToAdd[j].quantity += quantity;
  793.                     wasInArray = true;
  794.                     break;
  795.                 }
  796.             }
  797.            
  798.             if( !wasInArray )
  799.             {
  800.                 mutToAdd.itemName = mutName;
  801.                 mutToAdd.quantity = quantity;
  802.                 mutsToAdd.PushBack( mutToAdd );
  803.             }
  804.            
  805.             inv.RemoveItem( muts[i], quantity );
  806.         }
  807.        
  808.         for( i=0; i<mutsToAdd.Size(); i+=1 )
  809.         {
  810.             inv.AddAnItem( mutsToAdd[i].itemName, mutsToAdd[i].quantity, true, true );
  811.         }
  812.     }
  813.    
  814.     private function FixEquippedMutagens()
  815.     {
  816.         var item : SItemUniqueId;
  817.         if( GetItemEquippedOnSlot( EES_SkillMutagen1, item ) )
  818.         {
  819.             inv.SetItemStackable( item, false );
  820.         }
  821.         if( GetItemEquippedOnSlot( EES_SkillMutagen2, item ) )
  822.         {
  823.             inv.SetItemStackable( item, false );
  824.         }
  825.         if( GetItemEquippedOnSlot( EES_SkillMutagen3, item ) )
  826.         {
  827.             inv.SetItemStackable( item, false );
  828.         }
  829.         if( GetItemEquippedOnSlot( EES_SkillMutagen4, item ) )
  830.         {
  831.             inv.SetItemStackable( item, false );
  832.         }
  833.     }
  834.  
  835.     public final function RestoreQuen( quenHealth : float, quenDuration : float, optional alternate : bool ) : bool
  836.     {
  837.         var restoredQuen    : W3QuenEntity;
  838.        
  839.         if(quenHealth > 0.f && quenDuration >= 3.f)
  840.         {
  841.             restoredQuen = (W3QuenEntity)theGame.CreateEntity( signs[ST_Quen].template, GetWorldPosition(), GetWorldRotation() );
  842.             restoredQuen.Init( signOwner, signs[ST_Quen].entity, true );
  843.            
  844.             if( alternate )
  845.             {
  846.                 restoredQuen.SetAlternateCast( S_Magic_s04 );
  847.             }
  848.            
  849.             restoredQuen.OnStarted();
  850.             restoredQuen.OnThrowing();
  851.            
  852.             if( !alternate )
  853.             {
  854.                 restoredQuen.OnEnded();
  855.             }
  856.            
  857.             restoredQuen.SetDataFromRestore(quenHealth, quenDuration);
  858.            
  859.             return true;
  860.         }
  861.        
  862.         return false;
  863.     }
  864.    
  865.     public function IsInitialized() : bool
  866.     {
  867.         return isInitialized;
  868.     }
  869.    
  870.     private function NewGamePlusInitialize()
  871.     {
  872.         var questItems : array<name>;
  873.         var horseManager : W3HorseManager;
  874.         var horseInventory : CInventoryComponent;
  875.         var i, missingLevels, expDiff : int;
  876.        
  877.         super.NewGamePlusInitialize();
  878.        
  879.        
  880.         horseManager = (W3HorseManager)EntityHandleGet(horseManagerHandle);
  881.         if(horseManager)
  882.             horseInventory = horseManager.GetInventoryComponent();
  883.        
  884.        
  885.         theGame.params.SetNewGamePlusLevel(GetLevel());
  886.        
  887.        
  888.         if (theGame.GetDLCManager().IsDLCAvailable('ep1'))
  889.             missingLevels = theGame.params.NEW_GAME_PLUS_EP1_MIN_LEVEL - GetLevel();
  890.         else
  891.             missingLevels = theGame.params.NEW_GAME_PLUS_MIN_LEVEL - GetLevel();
  892.            
  893.         for(i=0; i<missingLevels; i+=1)
  894.         {
  895.            
  896.             expDiff = levelManager.GetTotalExpForNextLevel() - levelManager.GetPointsTotal(EExperiencePoint);
  897.             expDiff = CeilF( ((float)expDiff) / 2 );
  898.             AddPoints(EExperiencePoint, expDiff, false);
  899.         }
  900.        
  901.        
  902.        
  903.        
  904.        
  905.         inv.RemoveItemByTag('Quest', -1);
  906.         horseInventory.RemoveItemByTag('Quest', -1);
  907.  
  908.        
  909.        
  910.         questItems = theGame.GetDefinitionsManager().GetItemsWithTag('Quest');
  911.         for(i=0; i<questItems.Size(); i+=1)
  912.         {
  913.             inv.RemoveItemByName(questItems[i], -1);
  914.             horseInventory.RemoveItemByName(questItems[i], -1);
  915.         }
  916.        
  917.        
  918.         inv.RemoveItemByName('mq1002_artifact_3', -1);
  919.         horseInventory.RemoveItemByName('mq1002_artifact_3', -1);
  920.        
  921.        
  922.         inv.RemoveItemByTag('NotTransferableToNGP', -1);
  923.         horseInventory.RemoveItemByTag('NotTransferableToNGP', -1);
  924.        
  925.        
  926.         inv.RemoveItemByTag('NoticeBoardNote', -1);
  927.         horseInventory.RemoveItemByTag('NoticeBoardNote', -1);
  928.        
  929.        
  930.         RemoveAllNonAutoBuffs();
  931.        
  932.        
  933.         RemoveAlchemyRecipe('Recipe for Trial Potion Kit');
  934.         RemoveAlchemyRecipe('Recipe for Pops Antidote');
  935.         RemoveAlchemyRecipe('Recipe for Czart Lure');
  936.         RemoveAlchemyRecipe('q603_diarrhea_potion_recipe');
  937.        
  938.        
  939.         inv.RemoveItemByTag('Trophy', -1);
  940.         horseInventory.RemoveItemByTag('Trophy', -1);
  941.        
  942.        
  943.         inv.RemoveItemByCategory('usable', -1);
  944.         horseInventory.RemoveItemByCategory('usable', -1);
  945.        
  946.        
  947.         RemoveAbility('StaminaTutorialProlog');
  948.         RemoveAbility('TutorialStaminaRegenHack');
  949.         RemoveAbility('area_novigrad');
  950.         RemoveAbility('NoRegenEffect');
  951.         RemoveAbility('HeavySwimmingStaminaDrain');
  952.         RemoveAbility('AirBoost');
  953.         RemoveAbility('area_nml');
  954.         RemoveAbility('area_skellige');
  955.        
  956.        
  957.         inv.RemoveItemByTag('GwintCard', -1);
  958.         horseInventory.RemoveItemByTag('GwintCard', -1);
  959.                
  960.        
  961.        
  962.         inv.RemoveItemByTag('ReadableItem', -1);
  963.         horseInventory.RemoveItemByTag('ReadableItem', -1);
  964.        
  965.        
  966.         abilityManager.RestoreStats();
  967.        
  968.        
  969.         ((W3PlayerAbilityManager)abilityManager).RemoveToxicityOffset(10000);
  970.        
  971.        
  972.         GetInventory().SingletonItemsRefillAmmo();
  973.        
  974.        
  975.         craftingSchematics.Clear();
  976.         AddStartingSchematics();
  977.        
  978.        
  979.         for( i=0; i<amountOfSetPiecesEquipped.Size(); i+=1 )
  980.         {
  981.             amountOfSetPiecesEquipped[i] = 0;
  982.         }
  983.  
  984.        
  985.         inv.AddAnItem('Clearing Potion', 1, true, false, false);
  986.        
  987.        
  988.         inv.RemoveItemByName('q203_broken_eyeofloki', -1);
  989.         horseInventory.RemoveItemByName('q203_broken_eyeofloki', -1);
  990.        
  991.        
  992.         NewGamePlusReplaceViperSet(inv);
  993.         NewGamePlusReplaceViperSet(horseInventory);
  994.         NewGamePlusReplaceLynxSet(inv);
  995.         NewGamePlusReplaceLynxSet(horseInventory);
  996.         NewGamePlusReplaceGryphonSet(inv);
  997.         NewGamePlusReplaceGryphonSet(horseInventory);
  998.         NewGamePlusReplaceBearSet(inv);
  999.         NewGamePlusReplaceBearSet(horseInventory);
  1000.         NewGamePlusReplaceEP1(inv);
  1001.         NewGamePlusReplaceEP1(horseInventory);
  1002.         NewGamePlusReplaceEP2WitcherSets(inv);
  1003.         NewGamePlusReplaceEP2WitcherSets(horseInventory);
  1004.         NewGamePlusReplaceEP2Items(inv);
  1005.         NewGamePlusReplaceEP2Items(horseInventory);
  1006.         NewGamePlusMarkItemsToNotAdjust(inv);
  1007.         NewGamePlusMarkItemsToNotAdjust(horseInventory);
  1008.        
  1009.        
  1010.         inputHandler.ClearLocksForNGP();
  1011.        
  1012.        
  1013.         buffImmunities.Clear();
  1014.         buffRemovedImmunities.Clear();
  1015.        
  1016.         newGamePlusInitialized = true;
  1017.        
  1018.        
  1019.         m_quenReappliedCount = 1;
  1020.     }
  1021.        
  1022.     private final function NewGamePlusMarkItemsToNotAdjust(out inv : CInventoryComponent)
  1023.     {
  1024.         var ids     : array<SItemUniqueId>;
  1025.         var i       : int;
  1026.         var n       : name;
  1027.        
  1028.         inv.GetAllItems(ids);
  1029.         for( i=0; i<ids.Size(); i+=1 )
  1030.         {
  1031.             inv.SetItemModifierInt(ids[i], 'NGPItemAdjusted', 1);
  1032.         }
  1033.     }
  1034.    
  1035.     private final function NewGamePlusReplaceItem( item : name, new_item : name, out inv : CInventoryComponent)
  1036.     {
  1037.         var i, j                    : int;
  1038.         var ids, new_ids, enh_ids   : array<SItemUniqueId>;
  1039.         var dye_ids                 : array<SItemUniqueId>;
  1040.         var enh                     : array<name>;
  1041.         var wasEquipped             : bool;
  1042.         var wasEnchanted            : bool;
  1043.         var wasDyed                 : bool;
  1044.         var enchantName, colorName  : name;
  1045.        
  1046.         if ( inv.HasItem( item ) )
  1047.         {
  1048.             ids = inv.GetItemsIds(item);
  1049.             for (i = 0; i < ids.Size(); i += 1)
  1050.             {
  1051.                 inv.GetItemEnhancementItems( ids[i], enh );
  1052.                 wasEnchanted = inv.IsItemEnchanted( ids[i] );
  1053.                 if ( wasEnchanted )
  1054.                     enchantName = inv.GetEnchantment( ids[i] );
  1055.                 wasEquipped = IsItemEquipped( ids[i] );
  1056.                 wasDyed = inv.IsItemColored( ids[i] );
  1057.                 if ( wasDyed )
  1058.                 {
  1059.                     colorName = inv.GetItemColor( ids[i] );
  1060.                 }
  1061.                
  1062.                 inv.RemoveItem( ids[i], 1 );
  1063.                 new_ids = inv.AddAnItem( new_item, 1, true, true, false );
  1064.                 if ( wasEquipped )
  1065.                 {
  1066.                     EquipItem( new_ids[0] );
  1067.                 }
  1068.                 if ( wasEnchanted )
  1069.                 {
  1070.                     inv.EnchantItem( new_ids[0], enchantName, getEnchamtmentStatName(enchantName) );
  1071.                 }
  1072.                 for (j = 0; j < enh.Size(); j += 1)
  1073.                 {
  1074.                     enh_ids = inv.AddAnItem( enh[j], 1, true, true, false );
  1075.                     inv.EnhanceItemScript( new_ids[0], enh_ids[0] );
  1076.                 }
  1077.                 if ( wasDyed )
  1078.                 {
  1079.                     dye_ids = inv.AddAnItem( colorName, 1, true, true, false );
  1080.                     inv.ColorItem( new_ids[0], dye_ids[0] );
  1081.                     inv.RemoveItem( dye_ids[0], 1 );
  1082.                 }
  1083.                
  1084.                 inv.SetItemModifierInt( new_ids[0], 'NGPItemAdjusted', 1 );
  1085.             }
  1086.         }
  1087.     }
  1088.    
  1089.     private final function NewGamePlusAdjustDLCItem(item : name, mod : name, inv : CInventoryComponent)
  1090.     {
  1091.         var ids     : array<SItemUniqueId>;
  1092.         var i       : int;
  1093.        
  1094.         if( inv.HasItem(item) )
  1095.         {
  1096.             ids = inv.GetItemsIds(item);
  1097.             for (i = 0; i < ids.Size(); i += 1)
  1098.             {
  1099.                 if ( inv.GetItemModifierInt(ids[i], 'DoNotAdjustNGPDLC') <= 0 )
  1100.                 {
  1101.                     inv.AddItemBaseAbility(ids[i], mod);
  1102.                     inv.SetItemModifierInt(ids[i], 'DoNotAdjustNGPDLC', 1);
  1103.                 }
  1104.             }
  1105.         }
  1106.        
  1107.     }
  1108.    
  1109.     private final function NewGamePlusAdjustDLC1TemerianSet(inv : CInventoryComponent)
  1110.     {
  1111.         NewGamePlusAdjustDLCItem('NGP DLC1 Temerian Armor', 'NGP DLC Compatibility Chest Armor Mod', inv);
  1112.         NewGamePlusAdjustDLCItem('NGP DLC1 Temerian Gloves', 'NGP DLC Compatibility Armor Mod', inv);
  1113.         NewGamePlusAdjustDLCItem('NGP DLC1 Temerian Pants', 'NGP DLC Compatibility Armor Mod', inv);
  1114.         NewGamePlusAdjustDLCItem('NGP DLC1 Temerian Boots', 'NGP DLC Compatibility Armor Mod', inv);
  1115.     }
  1116.    
  1117.     private final function NewGamePlusAdjustDLC5NilfgardianSet(inv : CInventoryComponent)
  1118.     {
  1119.         NewGamePlusAdjustDLCItem('NGP DLC5 Nilfgaardian Armor', 'NGP DLC Compatibility Chest Armor Mod', inv);
  1120.         NewGamePlusAdjustDLCItem('NGP DLC5 Nilfgaardian Gloves', 'NGP DLC Compatibility Armor Mod', inv);
  1121.         NewGamePlusAdjustDLCItem('NGP DLC5 Nilfgaardian Pants', 'NGP DLC Compatibility Armor Mod', inv);
  1122.         NewGamePlusAdjustDLCItem('NGP DLC5 Nilfgaardian Boots', 'NGP DLC Compatibility Armor Mod', inv);
  1123.     }
  1124.    
  1125.     private final function NewGamePlusAdjustDLC10WolfSet(inv : CInventoryComponent)
  1126.     {
  1127.         NewGamePlusAdjustDLCItem('NGP Wolf Armor',   'NGP DLC Compatibility Chest Armor Mod', inv);
  1128.         NewGamePlusAdjustDLCItem('NGP Wolf Armor 1', 'NGP DLC Compatibility Chest Armor Mod', inv);
  1129.         NewGamePlusAdjustDLCItem('NGP Wolf Armor 2', 'NGP DLC Compatibility Chest Armor Mod', inv);
  1130.         NewGamePlusAdjustDLCItem('NGP Wolf Armor 3', 'NGP DLC Compatibility Chest Armor Mod', inv);
  1131.        
  1132.         NewGamePlusAdjustDLCItem('NGP Wolf Boots 1', 'NGP DLC Compatibility Armor Mod', inv);
  1133.         NewGamePlusAdjustDLCItem('NGP Wolf Boots 2', 'NGP DLC Compatibility Armor Mod', inv);
  1134.         NewGamePlusAdjustDLCItem('NGP Wolf Boots 3', 'NGP DLC Compatibility Armor Mod', inv);
  1135.         NewGamePlusAdjustDLCItem('NGP Wolf Boots 4', 'NGP DLC Compatibility Armor Mod', inv);
  1136.        
  1137.         NewGamePlusAdjustDLCItem('NGP Wolf Gloves 1', 'NGP DLC Compatibility Armor Mod', inv);
  1138.         NewGamePlusAdjustDLCItem('NGP Wolf Gloves 2', 'NGP DLC Compatibility Armor Mod', inv);
  1139.         NewGamePlusAdjustDLCItem('NGP Wolf Gloves 3', 'NGP DLC Compatibility Armor Mod', inv);
  1140.         NewGamePlusAdjustDLCItem('NGP Wolf Gloves 4', 'NGP DLC Compatibility Armor Mod', inv);
  1141.        
  1142.         NewGamePlusAdjustDLCItem('NGP Wolf Pants 1', 'NGP DLC Compatibility Armor Mod', inv);
  1143.         NewGamePlusAdjustDLCItem('NGP Wolf Pants 2', 'NGP DLC Compatibility Armor Mod', inv);
  1144.         NewGamePlusAdjustDLCItem('NGP Wolf Pants 3', 'NGP DLC Compatibility Armor Mod', inv);
  1145.         NewGamePlusAdjustDLCItem('NGP Wolf Pants 4', 'NGP DLC Compatibility Armor Mod', inv);
  1146.        
  1147.         NewGamePlusAdjustDLCItem('NGP Wolf School steel sword',   'NGP Wolf Steel Sword Mod', inv);
  1148.         NewGamePlusAdjustDLCItem('NGP Wolf School steel sword 1', 'NGP Wolf Steel Sword Mod', inv);
  1149.         NewGamePlusAdjustDLCItem('NGP Wolf School steel sword 2', 'NGP Wolf Steel Sword Mod', inv);
  1150.         NewGamePlusAdjustDLCItem('NGP Wolf School steel sword 3', 'NGP Wolf Steel Sword Mod', inv);
  1151.        
  1152.         NewGamePlusAdjustDLCItem('NGP Wolf School silver sword',   'NGP Wolf Silver Sword Mod', inv);
  1153.         NewGamePlusAdjustDLCItem('NGP Wolf School silver sword 1', 'NGP Wolf Silver Sword Mod', inv);
  1154.         NewGamePlusAdjustDLCItem('NGP Wolf School silver sword 2', 'NGP Wolf Silver Sword Mod', inv);
  1155.         NewGamePlusAdjustDLCItem('NGP Wolf School silver sword 3', 'NGP Wolf Silver Sword Mod', inv);
  1156.     }
  1157.    
  1158.     private final function NewGamePlusAdjustDLC14SkelligeSet(inv : CInventoryComponent)
  1159.     {
  1160.         NewGamePlusAdjustDLCItem('NGP DLC14 Skellige Armor', 'NGP DLC Compatibility Chest Armor Mod', inv);
  1161.         NewGamePlusAdjustDLCItem('NGP DLC14 Skellige Gloves', 'NGP DLC Compatibility Armor Mod', inv);
  1162.         NewGamePlusAdjustDLCItem('NGP DLC14 Skellige Pants', 'NGP DLC Compatibility Armor Mod', inv);
  1163.         NewGamePlusAdjustDLCItem('NGP DLC14 Skellige Boots', 'NGP DLC Compatibility Armor Mod', inv);
  1164.     }
  1165.    
  1166.     private final function NewGamePlusReplaceViperSet(out inv : CInventoryComponent)
  1167.     {
  1168.         NewGamePlusReplaceItem('Viper School steel sword', 'NGP Viper School steel sword', inv);
  1169.        
  1170.         NewGamePlusReplaceItem('Viper School silver sword', 'NGP Viper School silver sword', inv);
  1171.     }
  1172.    
  1173.     private final function NewGamePlusReplaceLynxSet(out inv : CInventoryComponent)
  1174.     {
  1175.         NewGamePlusReplaceItem('Lynx Armor', 'NGP Lynx Armor', inv);
  1176.         NewGamePlusReplaceItem('Lynx Armor 1', 'NGP Lynx Armor 1', inv);
  1177.         NewGamePlusReplaceItem('Lynx Armor 2', 'NGP Lynx Armor 2', inv);
  1178.         NewGamePlusReplaceItem('Lynx Armor 3', 'NGP Lynx Armor 3', inv);
  1179.        
  1180.         NewGamePlusReplaceItem('Lynx Gloves 1', 'NGP Lynx Gloves 1', inv);
  1181.         NewGamePlusReplaceItem('Lynx Gloves 2', 'NGP Lynx Gloves 2', inv);
  1182.         NewGamePlusReplaceItem('Lynx Gloves 3', 'NGP Lynx Gloves 3', inv);
  1183.         NewGamePlusReplaceItem('Lynx Gloves 4', 'NGP Lynx Gloves 4', inv);
  1184.        
  1185.         NewGamePlusReplaceItem('Lynx Pants 1', 'NGP Lynx Pants 1', inv);
  1186.         NewGamePlusReplaceItem('Lynx Pants 2', 'NGP Lynx Pants 2', inv);
  1187.         NewGamePlusReplaceItem('Lynx Pants 3', 'NGP Lynx Pants 3', inv);
  1188.         NewGamePlusReplaceItem('Lynx Pants 4', 'NGP Lynx Pants 4', inv);
  1189.        
  1190.         NewGamePlusReplaceItem('Lynx Boots 1', 'NGP Lynx Boots 1', inv);
  1191.         NewGamePlusReplaceItem('Lynx Boots 2', 'NGP Lynx Boots 2', inv);
  1192.         NewGamePlusReplaceItem('Lynx Boots 3', 'NGP Lynx Boots 3', inv);
  1193.         NewGamePlusReplaceItem('Lynx Boots 4', 'NGP Lynx Boots 4', inv);
  1194.        
  1195.         NewGamePlusReplaceItem('Lynx School steel sword', 'NGP Lynx School steel sword', inv);
  1196.         NewGamePlusReplaceItem('Lynx School steel sword 1', 'NGP Lynx School steel sword 1', inv);
  1197.         NewGamePlusReplaceItem('Lynx School steel sword 2', 'NGP Lynx School steel sword 2', inv);
  1198.         NewGamePlusReplaceItem('Lynx School steel sword 3', 'NGP Lynx School steel sword 3', inv);
  1199.        
  1200.         NewGamePlusReplaceItem('Lynx School silver sword', 'NGP Lynx School silver sword', inv);
  1201.         NewGamePlusReplaceItem('Lynx School silver sword 1', 'NGP Lynx School silver sword 1', inv);
  1202.         NewGamePlusReplaceItem('Lynx School silver sword 2', 'NGP Lynx School silver sword 2', inv);
  1203.         NewGamePlusReplaceItem('Lynx School silver sword 3', 'NGP Lynx School silver sword 3', inv);
  1204.     }
  1205.    
  1206.     private final function NewGamePlusReplaceGryphonSet(out inv : CInventoryComponent)
  1207.     {
  1208.         NewGamePlusReplaceItem('Gryphon Armor', 'NGP Gryphon Armor', inv);
  1209.         NewGamePlusReplaceItem('Gryphon Armor 1', 'NGP Gryphon Armor 1', inv);
  1210.         NewGamePlusReplaceItem('Gryphon Armor 2', 'NGP Gryphon Armor 2', inv);
  1211.         NewGamePlusReplaceItem('Gryphon Armor 3', 'NGP Gryphon Armor 3', inv);
  1212.        
  1213.         NewGamePlusReplaceItem('Gryphon Gloves 1', 'NGP Gryphon Gloves 1', inv);
  1214.         NewGamePlusReplaceItem('Gryphon Gloves 2', 'NGP Gryphon Gloves 2', inv);
  1215.         NewGamePlusReplaceItem('Gryphon Gloves 3', 'NGP Gryphon Gloves 3', inv);
  1216.         NewGamePlusReplaceItem('Gryphon Gloves 4', 'NGP Gryphon Gloves 4', inv);
  1217.        
  1218.         NewGamePlusReplaceItem('Gryphon Pants 1', 'NGP Gryphon Pants 1', inv);
  1219.         NewGamePlusReplaceItem('Gryphon Pants 2', 'NGP Gryphon Pants 2', inv);
  1220.         NewGamePlusReplaceItem('Gryphon Pants 3', 'NGP Gryphon Pants 3', inv);
  1221.         NewGamePlusReplaceItem('Gryphon Pants 4', 'NGP Gryphon Pants 4', inv);
  1222.        
  1223.         NewGamePlusReplaceItem('Gryphon Boots 1', 'NGP Gryphon Boots 1', inv);
  1224.         NewGamePlusReplaceItem('Gryphon Boots 2', 'NGP Gryphon Boots 2', inv);
  1225.         NewGamePlusReplaceItem('Gryphon Boots 3', 'NGP Gryphon Boots 3', inv);
  1226.         NewGamePlusReplaceItem('Gryphon Boots 4', 'NGP Gryphon Boots 4', inv);
  1227.        
  1228.         NewGamePlusReplaceItem('Gryphon School steel sword', 'NGP Gryphon School steel sword', inv);
  1229.         NewGamePlusReplaceItem('Gryphon School steel sword 1', 'NGP Gryphon School steel sword 1', inv);
  1230.         NewGamePlusReplaceItem('Gryphon School steel sword 2', 'NGP Gryphon School steel sword 2', inv);
  1231.         NewGamePlusReplaceItem('Gryphon School steel sword 3', 'NGP Gryphon School steel sword 3', inv);
  1232.        
  1233.         NewGamePlusReplaceItem('Gryphon School silver sword', 'NGP Gryphon School silver sword', inv);
  1234.         NewGamePlusReplaceItem('Gryphon School silver sword 1', 'NGP Gryphon School silver sword 1', inv);
  1235.         NewGamePlusReplaceItem('Gryphon School silver sword 2', 'NGP Gryphon School silver sword 2', inv);
  1236.         NewGamePlusReplaceItem('Gryphon School silver sword 3', 'NGP Gryphon School silver sword 3', inv);
  1237.     }
  1238.    
  1239.     private final function NewGamePlusReplaceBearSet(out inv : CInventoryComponent)
  1240.     {
  1241.         NewGamePlusReplaceItem('Bear Armor', 'NGP Bear Armor', inv);
  1242.         NewGamePlusReplaceItem('Bear Armor 1', 'NGP Bear Armor 1', inv);
  1243.         NewGamePlusReplaceItem('Bear Armor 2', 'NGP Bear Armor 2', inv);
  1244.         NewGamePlusReplaceItem('Bear Armor 3', 'NGP Bear Armor 3', inv);
  1245.        
  1246.         NewGamePlusReplaceItem('Bear Gloves 1', 'NGP Bear Gloves 1', inv);
  1247.         NewGamePlusReplaceItem('Bear Gloves 2', 'NGP Bear Gloves 2', inv);
  1248.         NewGamePlusReplaceItem('Bear Gloves 3', 'NGP Bear Gloves 3', inv);
  1249.         NewGamePlusReplaceItem('Bear Gloves 4', 'NGP Bear Gloves 4', inv);
  1250.        
  1251.         NewGamePlusReplaceItem('Bear Pants 1', 'NGP Bear Pants 1', inv);
  1252.         NewGamePlusReplaceItem('Bear Pants 2', 'NGP Bear Pants 2', inv);
  1253.         NewGamePlusReplaceItem('Bear Pants 3', 'NGP Bear Pants 3', inv);
  1254.         NewGamePlusReplaceItem('Bear Pants 4', 'NGP Bear Pants 4', inv);
  1255.        
  1256.         NewGamePlusReplaceItem('Bear Boots 1', 'NGP Bear Boots 1', inv);
  1257.         NewGamePlusReplaceItem('Bear Boots 2', 'NGP Bear Boots 2', inv);
  1258.         NewGamePlusReplaceItem('Bear Boots 3', 'NGP Bear Boots 3', inv);
  1259.         NewGamePlusReplaceItem('Bear Boots 4', 'NGP Bear Boots 4', inv);
  1260.        
  1261.         NewGamePlusReplaceItem('Bear School steel sword', 'NGP Bear School steel sword', inv);
  1262.         NewGamePlusReplaceItem('Bear School steel sword 1', 'NGP Bear School steel sword 1', inv);
  1263.         NewGamePlusReplaceItem('Bear School steel sword 2', 'NGP Bear School steel sword 2', inv);
  1264.         NewGamePlusReplaceItem('Bear School steel sword 3', 'NGP Bear School steel sword 3', inv);
  1265.        
  1266.         NewGamePlusReplaceItem('Bear School silver sword', 'NGP Bear School silver sword', inv);
  1267.         NewGamePlusReplaceItem('Bear School silver sword 1', 'NGP Bear School silver sword 1', inv);
  1268.         NewGamePlusReplaceItem('Bear School silver sword 2', 'NGP Bear School silver sword 2', inv);
  1269.         NewGamePlusReplaceItem('Bear School silver sword 3', 'NGP Bear School silver sword 3', inv);
  1270.     }
  1271.        
  1272.     private final function NewGamePlusReplaceEP1(out inv : CInventoryComponent)
  1273.     {  
  1274.         NewGamePlusReplaceItem('Ofir Armor', 'NGP Ofir Armor', inv);
  1275.         NewGamePlusReplaceItem('Ofir Sabre 2', 'NGP Ofir Sabre 2', inv);
  1276.        
  1277.         NewGamePlusReplaceItem('Crafted Burning Rose Armor', 'NGP Crafted Burning Rose Armor', inv);
  1278.         NewGamePlusReplaceItem('Crafted Burning Rose Gloves', 'NGP Crafted Burning Rose Gloves', inv);
  1279.         NewGamePlusReplaceItem('Crafted Burning Rose Sword', 'NGP Crafted Burning Rose Sword', inv);
  1280.        
  1281.         NewGamePlusReplaceItem('Crafted Ofir Armor', 'NGP Crafted Ofir Armor', inv);
  1282.         NewGamePlusReplaceItem('Crafted Ofir Boots', 'NGP Crafted Ofir Boots', inv);
  1283.         NewGamePlusReplaceItem('Crafted Ofir Gloves', 'NGP Crafted Ofir Gloves', inv);
  1284.         NewGamePlusReplaceItem('Crafted Ofir Pants', 'NGP Crafted Ofir Pants', inv);
  1285.         NewGamePlusReplaceItem('Crafted Ofir Steel Sword', 'NGP Crafted Ofir Steel Sword', inv);
  1286.        
  1287.         NewGamePlusReplaceItem('EP1 Crafted Witcher Silver Sword', 'NGP EP1 Crafted Witcher Silver Sword', inv);
  1288.         NewGamePlusReplaceItem('Olgierd Sabre', 'NGP Olgierd Sabre', inv);
  1289.        
  1290.         NewGamePlusReplaceItem('EP1 Witcher Armor', 'NGP EP1 Witcher Armor', inv);
  1291.         NewGamePlusReplaceItem('EP1 Witcher Boots', 'NGP EP1 Witcher Boots', inv);
  1292.         NewGamePlusReplaceItem('EP1 Witcher Gloves', 'NGP EP1 Witcher Gloves', inv);
  1293.         NewGamePlusReplaceItem('EP1 Witcher Pants', 'NGP EP1 Witcher Pants', inv);
  1294.         NewGamePlusReplaceItem('EP1 Viper School steel sword', 'NGP EP1 Viper School steel sword', inv);
  1295.         NewGamePlusReplaceItem('EP1 Viper School silver sword', 'NGP EP1 Viper School silver sword', inv);
  1296.     }
  1297.    
  1298.     private final function NewGamePlusReplaceEP2WitcherSets(out inv : CInventoryComponent)
  1299.     {
  1300.         NewGamePlusReplaceItem('Lynx Armor 4', 'NGP Lynx Armor 4', inv);
  1301.         NewGamePlusReplaceItem('Gryphon Armor 4', 'NGP Gryphon Armor 4', inv);
  1302.         NewGamePlusReplaceItem('Bear Armor 4', 'NGP Bear Armor 4', inv);
  1303.         NewGamePlusReplaceItem('Wolf Armor 4', 'NGP Wolf Armor 4', inv);
  1304.         NewGamePlusReplaceItem('Red Wolf Armor 1', 'NGP Red Wolf Armor 1', inv);
  1305.        
  1306.         NewGamePlusReplaceItem('Lynx Gloves 5', 'NGP Lynx Gloves 5', inv);
  1307.         NewGamePlusReplaceItem('Gryphon Gloves 5', 'NGP Gryphon Gloves 5', inv);
  1308.         NewGamePlusReplaceItem('Bear Gloves 5', 'NGP Bear Gloves 5', inv);
  1309.         NewGamePlusReplaceItem('Wolf Gloves 5', 'NGP Wolf Gloves 5', inv);
  1310.         NewGamePlusReplaceItem('Red Wolf Gloves 1', 'NGP Red Wolf Gloves 1', inv);
  1311.        
  1312.         NewGamePlusReplaceItem('Lynx Pants 5', 'NGP Lynx Pants 5', inv);
  1313.         NewGamePlusReplaceItem('Gryphon Pants 5', 'NGP Gryphon Pants 5', inv);
  1314.         NewGamePlusReplaceItem('Bear Pants 5', 'NGP Bear Pants 5', inv);
  1315.         NewGamePlusReplaceItem('Wolf Pants 5', 'NGP Wolf Pants 5', inv);
  1316.         NewGamePlusReplaceItem('Red Wolf Pants 1', 'NGP Red Wolf Pants 1', inv);
  1317.        
  1318.         NewGamePlusReplaceItem('Lynx Boots 5', 'NGP Lynx Boots 5', inv);
  1319.         NewGamePlusReplaceItem('Gryphon Boots 5', 'NGP Gryphon Boots 5', inv);
  1320.         NewGamePlusReplaceItem('Bear Boots 5', 'NGP Bear Boots 5', inv);
  1321.         NewGamePlusReplaceItem('Wolf Boots 5', 'NGP Wolf Boots 5', inv);
  1322.         NewGamePlusReplaceItem('Red Wolf Boots 1', 'NGP Red Wolf Boots 1', inv);
  1323.        
  1324.        
  1325.         NewGamePlusReplaceItem('Lynx School steel sword 4', 'NGP Lynx School steel sword 4', inv);
  1326.         NewGamePlusReplaceItem('Gryphon School steel sword 4', 'NGP Gryphon School steel sword 4', inv);
  1327.         NewGamePlusReplaceItem('Bear School steel sword 4', 'NGP Bear School steel sword 4', inv);
  1328.         NewGamePlusReplaceItem('Wolf School steel sword 4', 'NGP Wolf School steel sword 4', inv);
  1329.         NewGamePlusReplaceItem('Red Wolf School steel sword 1', 'NGP Red Wolf School steel sword 1', inv);
  1330.        
  1331.         NewGamePlusReplaceItem('Lynx School silver sword 4', 'NGP Lynx School silver sword 4', inv);
  1332.         NewGamePlusReplaceItem('Gryphon School silver sword 4', 'NGP Gryphon School silver sword 4', inv);
  1333.         NewGamePlusReplaceItem('Bear School silver sword 4', 'NGP Bear School silver sword 4', inv);
  1334.         NewGamePlusReplaceItem('Wolf School silver sword 4', 'NGP Wolf School silver sword 4', inv);
  1335.         NewGamePlusReplaceItem('Red Wolf School silver sword 1', 'NGP Red Wolf School silver sword 1', inv);
  1336.     }
  1337.    
  1338.     private final function NewGamePlusReplaceEP2Items(out inv : CInventoryComponent)
  1339.     {
  1340.         NewGamePlusReplaceItem('Guard Lvl1 Armor 3', 'NGP Guard Lvl1 Armor 3', inv);
  1341.         NewGamePlusReplaceItem('Guard Lvl1 A Armor 3', 'NGP Guard Lvl1 A Armor 3', inv);
  1342.         NewGamePlusReplaceItem('Guard Lvl2 Armor 3', 'NGP Guard Lvl2 Armor 3', inv);
  1343.         NewGamePlusReplaceItem('Guard Lvl2 A Armor 3', 'NGP Guard Lvl2 A Armor 3', inv);
  1344.         NewGamePlusReplaceItem('Knight Geralt Armor 3', 'NGP Knight Geralt Armor 3', inv);
  1345.         NewGamePlusReplaceItem('Knight Geralt A Armor 3', 'NGP Knight Geralt A Armor 3', inv);
  1346.         NewGamePlusReplaceItem('q702_vampire_armor', 'NGP q702_vampire_armor', inv);
  1347.        
  1348.         NewGamePlusReplaceItem('Guard Lvl1 Gloves 3', 'NGP Guard Lvl1 Gloves 3', inv);
  1349.         NewGamePlusReplaceItem('Guard Lvl1 A Gloves 3', 'NGP Guard Lvl1 A Gloves 3', inv);
  1350.         NewGamePlusReplaceItem('Guard Lvl2 Gloves 3', 'NGP Guard Lvl2 Gloves 3', inv);
  1351.         NewGamePlusReplaceItem('Guard Lvl2 A Gloves 3', 'NGP Guard Lvl2 A Gloves 3', inv);
  1352.         NewGamePlusReplaceItem('Knight Geralt Gloves 3', 'NGP Knight Geralt Gloves 3', inv);
  1353.         NewGamePlusReplaceItem('Knight Geralt A Gloves 3', 'NGP Knight Geralt A Gloves 3', inv);
  1354.         NewGamePlusReplaceItem('q702_vampire_gloves', 'NGP q702_vampire_gloves', inv);
  1355.        
  1356.         NewGamePlusReplaceItem('Guard Lvl1 Pants 3', 'NGP Guard Lvl1 Pants 3', inv);
  1357.         NewGamePlusReplaceItem('Guard Lvl1 A Pants 3', 'NGP Guard Lvl1 A Pants 3', inv);
  1358.         NewGamePlusReplaceItem('Guard Lvl2 Pants 3', 'NGP Guard Lvl2 Pants 3', inv);
  1359.         NewGamePlusReplaceItem('Guard Lvl2 A Pants 3', 'NGP Guard Lvl2 A Pants 3', inv);
  1360.         NewGamePlusReplaceItem('Knight Geralt Pants 3', 'NGP Knight Geralt Pants 3', inv);
  1361.         NewGamePlusReplaceItem('Knight Geralt A Pants 3', 'NGP Knight Geralt A Pants 3', inv);
  1362.         NewGamePlusReplaceItem('q702_vampire_pants', 'NGP q702_vampire_pants', inv);
  1363.        
  1364.         NewGamePlusReplaceItem('Guard Lvl1 Boots 3', 'NGP Guard Lvl1 Boots 3', inv);
  1365.         NewGamePlusReplaceItem('Guard Lvl1 A Boots 3', 'NGP Guard Lvl1 A Boots 3', inv);
  1366.         NewGamePlusReplaceItem('Guard Lvl2 Boots 3', 'NGP Guard Lvl2 Boots 3', inv);
  1367.         NewGamePlusReplaceItem('Guard Lvl2 A Boots 3', 'NGP Guard Lvl2 A Boots 3', inv);
  1368.         NewGamePlusReplaceItem('Knight Geralt Boots 3', 'NGP Knight Geralt Boots 3', inv);
  1369.         NewGamePlusReplaceItem('Knight Geralt A Boots 3', 'NGP Knight Geralt A Boots 3', inv);
  1370.         NewGamePlusReplaceItem('q702_vampire_boots', 'NGP q702_vampire_boots', inv);
  1371.        
  1372.         NewGamePlusReplaceItem('Serpent Steel Sword 1', 'NGP Serpent Steel Sword 1', inv);
  1373.         NewGamePlusReplaceItem('Serpent Steel Sword 2', 'NGP Serpent Steel Sword 2', inv);
  1374.         NewGamePlusReplaceItem('Serpent Steel Sword 3', 'NGP Serpent Steel Sword 3', inv);
  1375.         NewGamePlusReplaceItem('Guard lvl1 steel sword 3', 'NGP Guard lvl1 steel sword 3', inv);
  1376.         NewGamePlusReplaceItem('Guard lvl2 steel sword 3', 'NGP Guard lvl2 steel sword 3', inv);
  1377.         NewGamePlusReplaceItem('Knights steel sword 3', 'NGP Knights steel sword 3', inv);
  1378.         NewGamePlusReplaceItem('Hanza steel sword 3', 'NGP Hanza steel sword 3', inv);
  1379.         NewGamePlusReplaceItem('Toussaint steel sword 3', 'NGP Toussaint steel sword 3', inv);
  1380.         NewGamePlusReplaceItem('q702 vampire steel sword', 'NGP q702 vampire steel sword', inv);
  1381.        
  1382.         NewGamePlusReplaceItem('Serpent Silver Sword 1', 'NGP Serpent Silver Sword 1', inv);
  1383.         NewGamePlusReplaceItem('Serpent Silver Sword 2', 'NGP Serpent Silver Sword 2', inv);
  1384.         NewGamePlusReplaceItem('Serpent Silver Sword 3', 'NGP Serpent Silver Sword 3', inv);
  1385.     }
  1386.    
  1387.     public function GetEquippedSword(steel : bool) : SItemUniqueId
  1388.     {
  1389.         var item : SItemUniqueId;
  1390.        
  1391.         if(steel)
  1392.             GetItemEquippedOnSlot(EES_SteelSword, item);
  1393.         else
  1394.             GetItemEquippedOnSlot(EES_SilverSword, item);
  1395.            
  1396.         return item;
  1397.     }
  1398.    
  1399.     timer function BroadcastRain( deltaTime : float, id : int )
  1400.     {
  1401.         var rainStrength : float = 0;
  1402.         rainStrength = GetRainStrength();
  1403.         if( rainStrength > 0.5 )
  1404.         {
  1405.             theGame.GetBehTreeReactionManager().CreateReactionEventIfPossible( thePlayer, 'RainAction', 2.0f , 50.0f, -1.f, -1, true);
  1406.             LogReactionSystem( "'RainAction' was sent by Player - single broadcast - distance: 50.0" );
  1407.         }
  1408.     }
  1409.    
  1410.     function InitializeParryType()
  1411.     {
  1412.         var i, j : int;
  1413.        
  1414.         parryTypeTable.Resize( EnumGetMax('EAttackSwingType')+1 );
  1415.         for( i = 0; i < EnumGetMax('EAttackSwingType')+1; i += 1 )
  1416.         {
  1417.             parryTypeTable[i].Resize( EnumGetMax('EAttackSwingDirection')+1 );
  1418.         }
  1419.         parryTypeTable[AST_Horizontal][ASD_UpDown] = PT_None;
  1420.         parryTypeTable[AST_Horizontal][ASD_DownUp] = PT_None;
  1421.         parryTypeTable[AST_Horizontal][ASD_LeftRight] = PT_Left;
  1422.         parryTypeTable[AST_Horizontal][ASD_RightLeft] = PT_Right;
  1423.         parryTypeTable[AST_Vertical][ASD_UpDown] = PT_Up;
  1424.         parryTypeTable[AST_Vertical][ASD_DownUp] = PT_Down;
  1425.         parryTypeTable[AST_Vertical][ASD_LeftRight] = PT_None;
  1426.         parryTypeTable[AST_Vertical][ASD_RightLeft] = PT_None;
  1427.         parryTypeTable[AST_DiagonalUp][ASD_UpDown] = PT_None;
  1428.         parryTypeTable[AST_DiagonalUp][ASD_DownUp] = PT_None;
  1429.         parryTypeTable[AST_DiagonalUp][ASD_LeftRight] = PT_UpLeft;
  1430.         parryTypeTable[AST_DiagonalUp][ASD_RightLeft] = PT_RightUp;
  1431.         parryTypeTable[AST_DiagonalDown][ASD_UpDown] = PT_None;
  1432.         parryTypeTable[AST_DiagonalDown][ASD_DownUp] = PT_None;
  1433.         parryTypeTable[AST_DiagonalDown][ASD_LeftRight] = PT_LeftDown;
  1434.         parryTypeTable[AST_DiagonalDown][ASD_RightLeft] = PT_DownRight;
  1435.         parryTypeTable[AST_Jab][ASD_UpDown] = PT_Jab;
  1436.         parryTypeTable[AST_Jab][ASD_DownUp] = PT_Jab;
  1437.         parryTypeTable[AST_Jab][ASD_LeftRight] = PT_Jab;
  1438.         parryTypeTable[AST_Jab][ASD_RightLeft] = PT_Jab;   
  1439.     }
  1440.    
  1441.    
  1442.    
  1443.    
  1444.    
  1445.    
  1446.     event OnDeath( damageAction : W3DamageAction )
  1447.     {
  1448.         var items       : array< SItemUniqueId >;
  1449.         var i, size     : int; 
  1450.         var slot        : EEquipmentSlots;
  1451.         var holdSlot    : name;
  1452.    
  1453.         super.OnDeath( damageAction );
  1454.    
  1455.         items = GetHeldItems();
  1456.                
  1457.         if( rangedWeapon && rangedWeapon.GetCurrentStateName() != 'State_WeaponWait')
  1458.         {
  1459.             OnRangedForceHolster( true, true, true );      
  1460.             rangedWeapon.ClearDeployedEntity(true);
  1461.         }
  1462.        
  1463.         size = items.Size();
  1464.        
  1465.         if ( size > 0 )
  1466.         {
  1467.             for ( i = 0; i < size; i += 1 )
  1468.             {
  1469.                 if ( this.inv.IsIdValid( items[i] ) && !( this.inv.IsItemCrossbow( items[i] ) ) )
  1470.                 {
  1471.                     holdSlot = this.inv.GetItemHoldSlot( items[i] );               
  1472.                
  1473.                     if (  holdSlot == 'l_weapon' && this.IsHoldingItemInLHand() )
  1474.                     {
  1475.                         this.OnUseSelectedItem( true );
  1476.                     }          
  1477.            
  1478.                     DropItemFromSlot( holdSlot, false );
  1479.                    
  1480.                     if ( holdSlot == 'r_weapon' )
  1481.                     {
  1482.                         slot = this.GetItemSlot( items[i] );
  1483.                         if ( UnequipItemFromSlot( slot ) )
  1484.                             Log( "Unequip" );
  1485.                     }
  1486.                 }
  1487.             }
  1488.         }
  1489.     }
  1490.    
  1491.    
  1492.    
  1493.    
  1494.    
  1495.    
  1496.    
  1497.     function HandleMovement( deltaTime : float )
  1498.     {
  1499.         super.HandleMovement( deltaTime );
  1500.        
  1501.         rawCameraHeading = theCamera.GetCameraHeading();
  1502.     }
  1503.        
  1504.    
  1505.    
  1506.    
  1507.    
  1508.    
  1509.    
  1510.     function ToggleSpecialAttackHeavyAllowed( toggle : bool)
  1511.     {
  1512.         specialAttackHeavyAllowed = toggle;
  1513.     }
  1514.    
  1515.     function GetReputationManager() : W3Reputation
  1516.     {
  1517.         return reputationManager;
  1518.     }
  1519.            
  1520.     function OnRadialMenuItemChoose( selectedItem : string )
  1521.     {
  1522.         var iSlotId : int;
  1523.         var item : SItemUniqueId;
  1524.        
  1525.         if ( selectedItem != "Crossbow" )
  1526.         {
  1527.             if ( rangedWeapon && rangedWeapon.GetCurrentStateName() != 'State_WeaponWait' )
  1528.                 OnRangedForceHolster( true, false );
  1529.         }
  1530.        
  1531.        
  1532.         switch(selectedItem)
  1533.         {
  1534.            
  1535.             case "Meditation":
  1536.                 theGame.RequestMenuWithBackground( 'MeditationClockMenu', 'CommonMenu' );
  1537.                 break;         
  1538.             // -= WMK:modQuickSlots =-
  1539.             /*
  1540.             case "Slot1":
  1541.                 GetItemEquippedOnSlot( EES_Petard1, item );
  1542.                 if( thePlayer.inv.IsIdValid( item ) )
  1543.                 {
  1544.                     SelectQuickslotItem( EES_Petard1 );
  1545.                 }
  1546.                 else
  1547.                 {
  1548.                     SelectQuickslotItem( EES_Petard2 );
  1549.                 }
  1550.                 break;
  1551.                
  1552.             case "Slot2":
  1553.                 GetItemEquippedOnSlot( EES_Petard2, item );
  1554.                 if( thePlayer.inv.IsIdValid( item ) )
  1555.                 {
  1556.                     SelectQuickslotItem( EES_Petard2 );
  1557.                 }
  1558.                 else
  1559.                 {
  1560.                     SelectQuickslotItem( EES_Petard1 );
  1561.                 }
  1562.                 break;
  1563.             */
  1564.             case "Slot1":
  1565.                 SelectQuickslotItem(EES_Petard1);
  1566.                 break;
  1567.             case "Slot2":
  1568.                 SelectQuickslotItem(EES_Petard2);
  1569.                 break;
  1570.             case "Slot5":
  1571.                 SelectQuickslotItem(EES_Petard3);
  1572.                 break;
  1573.             case "Slot6":
  1574.                 SelectQuickslotItem(EES_Petard4);
  1575.                 break;
  1576.             // -= WMK:modQuickSlots =-
  1577.                
  1578.             case "Crossbow":
  1579.                 SelectQuickslotItem(EES_RangedWeapon);
  1580.                 break;
  1581.                
  1582.             case "Slot3":
  1583.                 GetItemEquippedOnSlot( EES_Quickslot1, item );
  1584.                 if( thePlayer.inv.IsIdValid( item ) )
  1585.                 {
  1586.                     SelectQuickslotItem( EES_Quickslot1 );
  1587.                 }
  1588.                 else
  1589.                 {
  1590.                     SelectQuickslotItem( EES_Quickslot2 );
  1591.                 }
  1592.                 break;
  1593.                
  1594.             case "Slot4":
  1595.                 GetItemEquippedOnSlot( EES_Quickslot2, item );
  1596.                 if( thePlayer.inv.IsIdValid( item ) )
  1597.                 {
  1598.                     SelectQuickslotItem( EES_Quickslot2 );
  1599.                 }
  1600.                 else
  1601.                 {
  1602.                     SelectQuickslotItem( EES_Quickslot1 );
  1603.                 }
  1604.                 break;
  1605.                
  1606.             default:
  1607.                 SetEquippedSign(SignStringToEnum( selectedItem ));
  1608.                 FactsRemove("SignToggled");
  1609.                 break;
  1610.         }
  1611.     }
  1612.    
  1613.     function ToggleNextItem()
  1614.     {
  1615.         var quickSlotItems : array< EEquipmentSlots >;
  1616.         var currentSelectedItem : SItemUniqueId;
  1617.         var item : SItemUniqueId;
  1618.         var i : int;
  1619.        
  1620.         for( i = EES_Quickslot2; i > EES_Petard1 - 1; i -= 1 )
  1621.         {
  1622.             GetItemEquippedOnSlot( i, item );
  1623.             if( inv.IsIdValid( item ) )
  1624.             {
  1625.                 quickSlotItems.PushBack( i );
  1626.             }
  1627.         }
  1628.         if( !quickSlotItems.Size() )
  1629.         {
  1630.             return;
  1631.         }
  1632.        
  1633.         currentSelectedItem = GetSelectedItemId();
  1634.        
  1635.         if( inv.IsIdValid( currentSelectedItem ) )
  1636.         {
  1637.             for( i = 0; i < quickSlotItems.Size(); i += 1 )
  1638.             {
  1639.                 GetItemEquippedOnSlot( quickSlotItems[i], item );
  1640.                 if( currentSelectedItem == item )
  1641.                 {
  1642.                     if( i == quickSlotItems.Size() - 1 )
  1643.                     {
  1644.                         SelectQuickslotItem( quickSlotItems[ 0 ] );
  1645.                     }
  1646.                     else
  1647.                     {
  1648.                         SelectQuickslotItem( quickSlotItems[ i + 1 ] );
  1649.                     }
  1650.                     return;
  1651.                 }
  1652.             }
  1653.         }
  1654.         else
  1655.         {
  1656.             SelectQuickslotItem( quickSlotItems[ 0 ] );
  1657.         }
  1658.     }
  1659.        
  1660.    
  1661.     function SetEquippedSign( signType : ESignType )
  1662.     {
  1663.         if(!IsSignBlocked(signType))
  1664.         {
  1665.             equippedSign = signType;
  1666.             FactsSet("CurrentlySelectedSign", equippedSign);
  1667.         }
  1668.     }
  1669.    
  1670.     function GetEquippedSign() : ESignType
  1671.     {
  1672.         return equippedSign;
  1673.     }
  1674.    
  1675.     function GetCurrentlyCastSign() : ESignType
  1676.     {
  1677.         return currentlyCastSign;
  1678.     }
  1679.    
  1680.     function SetCurrentlyCastSign( type : ESignType, entity : W3SignEntity )
  1681.     {
  1682.         currentlyCastSign = type;
  1683.        
  1684.         if( type != ST_None )
  1685.         {
  1686.             signs[currentlyCastSign].entity = entity;
  1687.         }
  1688.     }
  1689.    
  1690.     function GetCurrentSignEntity() : W3SignEntity
  1691.     {
  1692.         if(currentlyCastSign == ST_None)
  1693.             return NULL;
  1694.            
  1695.         return signs[currentlyCastSign].entity;
  1696.     }
  1697.    
  1698.     public function GetSignEntity(type : ESignType) : W3SignEntity
  1699.     {
  1700.         if(type == ST_None)
  1701.             return NULL;
  1702.            
  1703.         return signs[type].entity;
  1704.     }
  1705.    
  1706.     public function GetSignTemplate(type : ESignType) : CEntityTemplate
  1707.     {
  1708.         if(type == ST_None)
  1709.             return NULL;
  1710.            
  1711.         return signs[type].template;
  1712.     }
  1713.    
  1714.     public function IsCurrentSignChanneled() : bool
  1715.     {
  1716.         if( currentlyCastSign != ST_None && signs[currentlyCastSign].entity)
  1717.             return signs[currentlyCastSign].entity.OnCheckChanneling();
  1718.        
  1719.         return false;
  1720.     }
  1721.    
  1722.     function IsCastingSign() : bool
  1723.     {
  1724.         return currentlyCastSign != ST_None;
  1725.     }
  1726.    
  1727.    
  1728.     protected function IsInCombatActionCameraRotationEnabled() : bool
  1729.     {
  1730.         if( IsInCombatAction() && ( GetCombatAction() == EBAT_EMPTY || GetCombatAction() == EBAT_Parry ) )
  1731.         {
  1732.             return true;
  1733.         }
  1734.        
  1735.         return !bIsInCombatAction;
  1736.     }
  1737.    
  1738.     function SetHoldBeforeOpenRadialMenuTime ( time : float )
  1739.     {
  1740.         _HoldBeforeOpenRadialMenuTime = time;
  1741.     }
  1742.    
  1743.    
  1744.    
  1745.    
  1746.    
  1747.    
  1748.    
  1749.     public function RepairItem (  rapairKitId : SItemUniqueId, usedOnItem : SItemUniqueId )
  1750.     {
  1751.         var itemMaxDurablity        : float;
  1752.         var itemCurrDurablity       : float;
  1753.         var baseRepairValue         : float;
  1754.         var reapirValue             : float;
  1755.         var itemAttribute           : SAbilityAttributeValue;
  1756.        
  1757.         itemMaxDurablity = inv.GetItemMaxDurability(usedOnItem);
  1758.         itemCurrDurablity = inv.GetItemDurability(usedOnItem);
  1759.         itemAttribute = inv.GetItemAttributeValue ( rapairKitId, 'repairValue' );
  1760.        
  1761.         if( itemCurrDurablity >= itemMaxDurablity )
  1762.         {
  1763.             return;
  1764.         }
  1765.        
  1766.         if ( inv.IsItemAnyArmor ( usedOnItem )|| inv.IsItemWeapon( usedOnItem ) )
  1767.         {          
  1768.            
  1769.             baseRepairValue = itemMaxDurablity * itemAttribute.valueMultiplicative;                
  1770.             reapirValue = MinF( itemCurrDurablity + baseRepairValue, itemMaxDurablity );
  1771.            
  1772.             inv.SetItemDurabilityScript ( usedOnItem, MinF ( reapirValue, itemMaxDurablity ));
  1773.         }
  1774.        
  1775.         inv.RemoveItem ( rapairKitId, 1 );
  1776.        
  1777.     }
  1778.     public function HasRepairAbleGearEquiped ( ) : bool
  1779.     {
  1780.         var curEquipedItem : SItemUniqueId;
  1781.        
  1782.         return ( GetItemEquippedOnSlot(EES_Armor, curEquipedItem) || GetItemEquippedOnSlot(EES_Boots, curEquipedItem) || GetItemEquippedOnSlot(EES_Pants, curEquipedItem) || GetItemEquippedOnSlot(EES_Gloves, curEquipedItem)) == true;
  1783.     }
  1784.     public function HasRepairAbleWaponEquiped () : bool
  1785.     {
  1786.         var curEquipedItem : SItemUniqueId;
  1787.        
  1788.         return ( GetItemEquippedOnSlot(EES_SilverSword, curEquipedItem) || GetItemEquippedOnSlot(EES_SteelSword, curEquipedItem) ) == true;
  1789.     }
  1790.     public function IsItemRepairAble ( item : SItemUniqueId ) : bool
  1791.     {
  1792.         return inv.GetItemDurabilityRatio(item) <= 0.99999f;
  1793.     }
  1794.    
  1795.    
  1796.    
  1797.    
  1798.    
  1799.    
  1800.        
  1801.    
  1802.     public function ApplyOil( oilId : SItemUniqueId, usedOnItem : SItemUniqueId ) : bool
  1803.     {
  1804.         var tutStateOil : W3TutorialManagerUIHandlerStateOils;     
  1805.        
  1806.         if( !super.ApplyOil( oilId, usedOnItem ))
  1807.             return false;
  1808.                
  1809.        
  1810.         if(ShouldProcessTutorial('TutorialOilCanEquip3'))
  1811.         {
  1812.             tutStateOil = (W3TutorialManagerUIHandlerStateOils)theGame.GetTutorialSystem().uiHandler.GetCurrentState();
  1813.             if(tutStateOil)
  1814.             {
  1815.                 tutStateOil.OnOilApplied();
  1816.             }
  1817.         }
  1818.        
  1819.         return true;
  1820.     }
  1821.    
  1822.     private final function RemoveExtraOilsFromItem( item : SItemUniqueId )
  1823.     {
  1824.         var oils : array< CBaseGameplayEffect >;
  1825.         var i, cnt : int;
  1826.         var buff : W3Effect_Oil;
  1827.    
  1828.         oils = GetBuffs( EET_Oil );
  1829.         for( i=0; i<oils.Size(); i+=1 )
  1830.         {          
  1831.             buff = (W3Effect_Oil) oils[ i ];
  1832.             if( buff && buff.GetSwordItemId() == item )
  1833.             {
  1834.                 cnt += 1;
  1835.             }
  1836.         }
  1837.         while( cnt > 1 )
  1838.         {
  1839.             inv.RemoveOldestOilFromItem( item );
  1840.             cnt -= 1;
  1841.         }
  1842.     }
  1843.    
  1844.    
  1845.    
  1846.    
  1847.    
  1848.    
  1849.    
  1850.    
  1851.     function ReduceDamage(out damageData : W3DamageAction)
  1852.     {
  1853.         var actorAttacker : CActor;
  1854.         var quen : W3QuenEntity;
  1855.         var attackRange : CAIAttackRange;
  1856.         var attackerMovementAdjustor : CMovementAdjustor;
  1857.         var dist, distToAttacker, actionHeading, attackerHeading, currAdrenaline, adrenReducedDmg, focus : float;
  1858.         var attackName : name;
  1859.         var useQuenForBleeding : bool;
  1860.         var min, max : SAbilityAttributeValue;
  1861.         var skillLevel : int;
  1862.        
  1863.         super.ReduceDamage(damageData);
  1864.        
  1865.        
  1866.        
  1867.         quen = (W3QuenEntity)signs[ST_Quen].entity;
  1868.         useQuenForBleeding = false;
  1869.         if(quen && !damageData.DealsAnyDamage() && ((W3Effect_Bleeding)damageData.causer) && damageData.GetDamageValue(theGame.params.DAMAGE_NAME_DIRECT) > 0.f)
  1870.             useQuenForBleeding = true;
  1871.        
  1872.        
  1873.         if(!useQuenForBleeding && !damageData.DealsAnyDamage())
  1874.             return;
  1875.        
  1876.         actorAttacker = (CActor)damageData.attacker;
  1877.        
  1878.        
  1879.         if(actorAttacker && IsCurrentlyDodging() && damageData.CanBeDodged())
  1880.         {
  1881.            
  1882.            
  1883.             actionHeading = evadeHeading;
  1884.             attackerHeading = actorAttacker.GetHeading();
  1885.             dist = AngleDistance(actionHeading, attackerHeading);
  1886.             distToAttacker = VecDistance(this.GetWorldPosition(),damageData.attacker.GetWorldPosition());
  1887.             attackName = actorAttacker.GetLastAttackRangeName();
  1888.             attackRange = theGame.GetAttackRangeForEntity( actorAttacker, attackName );
  1889.             attackerMovementAdjustor = actorAttacker.GetMovingAgentComponent().GetMovementAdjustor();
  1890.             if( ( AbsF(dist) < 150 && attackName != 'stomp' && attackName != 'anchor_special_far' && attackName != 'anchor_far' )
  1891.                 || ( ( attackName == 'stomp' || attackName == 'anchor_special_far' || attackName == 'anchor_far' ) && distToAttacker > attackRange.rangeMax * 0.75 ) )
  1892.             {
  1893.                 if ( theGame.CanLog() )
  1894.                 {
  1895.                     LogDMHits("W3PlayerWitcher.ReduceDamage: Attack dodged by player - no damage done", damageData);
  1896.                 }
  1897.                 damageData.SetAllProcessedDamageAs(0);
  1898.                 damageData.SetWasDodged();
  1899.             }
  1900.            
  1901.             else if( !damageData.IsActionEnvironment() && !damageData.IsDoTDamage() && CanUseSkill( S_Sword_s09 ) )
  1902.             {
  1903.                 skillLevel = GetSkillLevel( S_Sword_s09 );
  1904.                 if( skillLevel == GetSkillMaxLevel( S_Sword_s09 ) )
  1905.                 {
  1906.                     damageData.SetAllProcessedDamageAs(0);
  1907.                     damageData.SetWasDodged();
  1908.                 }
  1909.                 else
  1910.                 {
  1911.                     damageData.processedDmg.vitalityDamage *= 1 - CalculateAttributeValue(GetSkillAttributeValue(S_Sword_s09, 'damage_reduction', false, true)) * skillLevel;
  1912.                 }
  1913.                
  1914.                 if ( theGame.CanLog() )
  1915.                 {
  1916.                     LogDMHits("W3PlayerWitcher.ReduceDamage: skill S_Sword_s09 reduced damage while dodging", damageData );
  1917.                 }
  1918.             }
  1919.         }
  1920.        
  1921.        
  1922.         if(quen && damageData.GetBuffSourceName() != "FallingDamage")
  1923.         {
  1924.             if ( theGame.CanLog() )
  1925.             {      
  1926.                 LogDMHits("W3PlayerWitcher.ReduceDamage: Processing Quen sign damage reduction...", damageData);
  1927.             }
  1928.             quen.OnTargetHit( damageData );
  1929.         }  
  1930.        
  1931.        
  1932.         if( HasBuff( EET_GryphonSetBonusYrden ) )
  1933.         {
  1934.             min = GetAttributeValue( 'gryphon_set_bns_dmg_reduction' );
  1935.             damageData.processedDmg.vitalityDamage *= 1 - min.valueAdditive;
  1936.         }
  1937.        
  1938.        
  1939.         if( IsMutationActive( EPMT_Mutation5 ) && !IsAnyQuenActive() && !damageData.IsDoTDamage() )
  1940.         {
  1941.             focus = GetStat( BCS_Focus );
  1942.             currAdrenaline = FloorF( focus );
  1943.             if( currAdrenaline >= 1 )
  1944.             {
  1945.                 theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation5', 'mut5_dmg_red_perc', min, max );
  1946.                 adrenReducedDmg = ( currAdrenaline * min.valueAdditive );
  1947.                 damageData.processedDmg.vitalityDamage *= 1 - adrenReducedDmg;
  1948.                
  1949.                
  1950.                 theGame.MutationHUDFeedback( MFT_PlayOnce );
  1951.                
  1952.                 if( focus >= 3.f )
  1953.                 {
  1954.                     PlayEffect( 'mutation_5_stage_03' );
  1955.                 }
  1956.                 else if( focus >= 2.f )
  1957.                 {
  1958.                     PlayEffect( 'mutation_5_stage_02' );
  1959.                 }
  1960.                 else
  1961.                 {
  1962.                     PlayEffect( 'mutation_5_stage_01' );
  1963.                 }
  1964.             }
  1965.         }
  1966.        
  1967.        
  1968.         if(!damageData.GetIgnoreImmortalityMode())
  1969.         {
  1970.             if(!((W3PlayerWitcher)this))
  1971.                 Log("");
  1972.            
  1973.            
  1974.             if( IsInvulnerable() )
  1975.             {
  1976.                 if ( theGame.CanLog() )
  1977.                 {
  1978.                     LogDMHits("CActor.ReduceDamage: victim Invulnerable - no damage will be dealt", damageData );
  1979.                 }
  1980.                 damageData.SetAllProcessedDamageAs(0);
  1981.                 return;
  1982.             }
  1983.            
  1984.             if(actorAttacker && damageData.DealsAnyDamage() )
  1985.                 actorAttacker.SignalGameplayEventParamObject( 'DamageInstigated', damageData );
  1986.            
  1987.            
  1988.             if( IsImmortal() )
  1989.             {
  1990.                 if ( theGame.CanLog() )
  1991.                 {
  1992.                     LogDMHits("CActor.ReduceDamage: victim is Immortal, clamping damage", damageData );
  1993.                 }
  1994.                 damageData.processedDmg.vitalityDamage = ClampF(damageData.processedDmg.vitalityDamage, 0, GetStat(BCS_Vitality)-1 );
  1995.                 damageData.processedDmg.essenceDamage  = ClampF(damageData.processedDmg.essenceDamage, 0, GetStat(BCS_Essence)-1 );
  1996.                 return;
  1997.             }
  1998.         }
  1999.         else
  2000.         {
  2001.            
  2002.             if(actorAttacker && damageData.DealsAnyDamage() )
  2003.                 actorAttacker.SignalGameplayEventParamObject( 'DamageInstigated', damageData );
  2004.         }
  2005.     }
  2006.    
  2007.     timer function UndyingSkillCooldown(dt : float, id : int)
  2008.     {
  2009.         cannotUseUndyingSkill = false;
  2010.     }
  2011.    
  2012.     timer function UndyingSkillCooldown2(dt : float, id : int)
  2013.     {
  2014.         cannotUseUndyingSkill2 = false;
  2015.     }
  2016.    
  2017.    
  2018.    
  2019.    
  2020.     event OnTakeDamage( action : W3DamageAction)
  2021.     {
  2022.         var currVitality, rgnVitality, hpTriggerTreshold : float;
  2023.         var healingFactor : float;
  2024.         var abilityName : name;
  2025.         var abilityCount, maxStack, itemDurability : float;
  2026.         var addAbility : bool;
  2027.         var min, max : SAbilityAttributeValue;
  2028.         var mutagenQuen : W3SignEntity;
  2029.         var equipped : array<SItemUniqueId>;
  2030.         var i : int;
  2031.         var killSourceName : string;
  2032.         var aerondight  : W3Effect_Aerondight;
  2033.    
  2034.         currVitality = GetStat(BCS_Vitality);
  2035.        
  2036.        
  2037.         if(action.processedDmg.vitalityDamage >= currVitality)
  2038.         {
  2039.             killSourceName = action.GetBuffSourceName();
  2040.            
  2041.            
  2042.             if( killSourceName != "Quest" && killSourceName != "Kill Trigger" && killSourceName != "Trap" && killSourceName != "FallingDamage" )
  2043.             {          
  2044.                
  2045.                 if( IsMutationActive( EPMT_Mutation11 ) && !HasBuff( EET_Mutation11Debuff ) && !IsInAir() )
  2046.                 {
  2047.                     theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation11', 'health_prc', min, max );
  2048.  
  2049.                     action.SetAllProcessedDamageAs( 0 );
  2050.                    
  2051.                     OnMutation11Triggered();                   
  2052.                 }
  2053.                 else if(!cannotUseUndyingSkill && FloorF(GetStat(BCS_Focus)) >= 1 && CanUseSkill(S_Sword_s18) && HasBuff(EET_BattleTrance) )
  2054.  
  2055.                 {
  2056.                     healingFactor = CalculateAttributeValue( GetSkillAttributeValue(S_Sword_s18, 'healing_factor', false, true) );
  2057.                     healingFactor *= GetStatMax(BCS_Vitality);
  2058.                     healingFactor *= GetStat(BCS_Focus);
  2059.                     healingFactor *= 1 + CalculateAttributeValue( GetSkillAttributeValue(S_Sword_s18, 'healing_bonus', false, true) ) * (GetSkillLevel(S_Sword_s18) - 1);
  2060.                     ForceSetStat(BCS_Vitality, GetStatMax(BCS_Vitality));
  2061.                     DrainFocus(GetStat(BCS_Focus));
  2062.                     RemoveBuff(EET_BattleTrance);
  2063.                     cannotUseUndyingSkill = true;
  2064.                     AddTimer('UndyingSkillCooldown', CalculateAttributeValue( GetSkillAttributeValue(S_Sword_s18, 'trigger_delay', false, true) ), false, , , true);
  2065.                 }
  2066.                
  2067.                 else if(!cannotUseUndyingSkill2 && GetWitcherPlayer().IsMutationActive( EPMT_Mutation4 ) )
  2068.  
  2069.                 {
  2070.                     action.SetAllProcessedDamageAs( 0 );
  2071.                     ForceSetStat(BCS_Vitality, 1); //: heal 1 point of damage
  2072.                     cannotUseUndyingSkill2 = true;
  2073.                     AddTimer('UndyingSkillCooldown2', 180, false, , , true);
  2074.                 }
  2075.                
  2076.                
  2077.                 else
  2078.                 {
  2079.                    
  2080.                     equipped = GetEquippedItems();
  2081.                    
  2082.                     for(i=0; i<equipped.Size(); i+=1)
  2083.                     {
  2084.                         if ( !inv.IsIdValid( equipped[i] ) )
  2085.                         {
  2086.                             continue;
  2087.                         }
  2088.                         itemDurability = inv.GetItemDurability(equipped[i]);
  2089.                         if(inv.ItemHasAbility(equipped[i], 'MA_Reinforced') && itemDurability > 0)
  2090.                         {
  2091.                            
  2092.                             inv.SetItemDurabilityScript(equipped[i], MaxF(0, itemDurability - action.processedDmg.vitalityDamage) );
  2093.                            
  2094.                            
  2095.                             action.processedDmg.vitalityDamage = 0;
  2096.                             ForceSetStat(BCS_Vitality, 1);
  2097.                            
  2098.                             break;
  2099.                         }
  2100.                     }
  2101.                 }
  2102.             }
  2103.         }
  2104.        
  2105.        
  2106.         if(action.DealsAnyDamage() && !((W3Effect_Toxicity)action.causer) )
  2107.         {
  2108.             if(HasBuff(EET_Mutagen10))
  2109.                 RemoveAbilityAll( GetBuff(EET_Mutagen10).GetAbilityName() );
  2110.            
  2111.             if(HasBuff(EET_Mutagen15))
  2112.                 RemoveAbilityAll( GetBuff(EET_Mutagen15).GetAbilityName() );
  2113.         }
  2114.                
  2115.        
  2116.         if(HasBuff(EET_Mutagen19))
  2117.         {
  2118.             theGame.GetDefinitionsManager().GetAbilityAttributeValue(GetBuff(EET_Mutagen19).GetAbilityName(), 'max_hp_perc_trigger', min, max);
  2119.             hpTriggerTreshold = GetStatMax(BCS_Vitality) * CalculateAttributeValue(GetAttributeRandomizedValue(min, max));
  2120.            
  2121.             if(action.GetDamageDealt() >= hpTriggerTreshold)
  2122.             {
  2123.                 mutagenQuen = (W3SignEntity)theGame.CreateEntity( signs[ST_Quen].template, GetWorldPosition(), GetWorldRotation() );
  2124.                 mutagenQuen.Init( signOwner, signs[ST_Quen].entity, true );
  2125.                 mutagenQuen.OnStarted();
  2126.                 mutagenQuen.OnThrowing();
  2127.                 mutagenQuen.OnEnded();
  2128.             }
  2129.         }
  2130.        
  2131.        
  2132.         if(action.DealsAnyDamage() && !action.IsDoTDamage() && HasBuff(EET_Mutagen27))
  2133.         {
  2134.             abilityName = GetBuff(EET_Mutagen27).GetAbilityName();
  2135.             abilityCount = GetAbilityCount(abilityName);
  2136.            
  2137.             if(abilityCount == 0)
  2138.             {
  2139.                 addAbility = true;
  2140.             }
  2141.             else
  2142.             {
  2143.                 theGame.GetDefinitionsManager().GetAbilityAttributeValue(abilityName, 'mutagen27_max_stack', min, max);
  2144.                 maxStack = CalculateAttributeValue(GetAttributeRandomizedValue(min, max));
  2145.                
  2146.                 if(maxStack >= 0)
  2147.                 {
  2148.                     addAbility = (abilityCount < maxStack);
  2149.                 }
  2150.                 else
  2151.                 {
  2152.                     addAbility = true;
  2153.                 }
  2154.             }
  2155.            
  2156.             if(addAbility)
  2157.             {
  2158.                 AddAbility(abilityName, true);
  2159.             }
  2160.         }
  2161.        
  2162.         if(HasBuff(EET_Trap) && !action.IsDoTDamage() && action.attacker.HasAbility( 'mon_dettlaff_monster_base' ))
  2163.         {
  2164.             action.AddEffectInfo(EET_Knockdown);
  2165.             RemoveBuff(EET_Trap, true);
  2166.         }      
  2167.        
  2168.         super.OnTakeDamage(action);
  2169.        
  2170.        
  2171.         if( !action.WasDodged() && action.DealtDamage() && inv.ItemHasTag( inv.GetCurrentlyHeldSword(), 'Aerondight' ) && !action.IsDoTDamage() && !( (W3Effect_Toxicity) action.causer ) )
  2172.         {
  2173.             aerondight = (W3Effect_Aerondight)GetBuff( EET_Aerondight );
  2174.             if( aerondight && aerondight.GetCurrentCount() != 0 )
  2175.             {
  2176.                 aerondight.ReduceAerondightStacks();
  2177.             }
  2178.         }
  2179.        
  2180.         if( GetWitcherPlayer().GetHealthPercents() < 0.5f && IsMutationActive( EPMT_Mutation5 ))
  2181.         {
  2182.          action.SetAllProcessedDamageAs( 50 ); //
  2183.         }
  2184.        
  2185.         if( GetWitcherPlayer().GetHealthPercents() < 0.5f && IsMutationActive( EPMT_Mutation3 ))
  2186.         {
  2187.             RemoveBuff( EET_Mutation3 );
  2188.         }
  2189.        else if( !action.WasDodged() && action.DealtDamage() && !( (W3Effect_Toxicity) action.causer ) && IsMutationActive( EPMT_Mutation3 ) && GetWitcherPlayer().GetHealthPercents() > 0.5f )
  2190.         {
  2191.                         AddEffectDefault( EET_Mutation3, this, "", false );
  2192.  
  2193.         }
  2194.        
  2195.     }
  2196.    
  2197.    
  2198.    
  2199.    
  2200.    
  2201.    
  2202.    
  2203.     event OnStartFistfightMinigame()
  2204.     {
  2205.         var i : int;
  2206.         var buffs : array< CBaseGameplayEffect >;
  2207.        
  2208.        
  2209.         effectManager.RemoveAllPotionEffects();
  2210.        
  2211.         abilityManager.DrainToxicity(GetStatMax( BCS_Toxicity ));
  2212.        
  2213.         buffs = GetBuffs( EET_WellFed );
  2214.         for( i=buffs.Size()-1; i>=0; i-=1 )
  2215.         {
  2216.             RemoveEffect( buffs[i] );
  2217.         }
  2218.        
  2219.        
  2220.         buffs.Clear();
  2221.         buffs = GetBuffs( EET_WellHydrated );
  2222.         for( i=buffs.Size()-1; i>=0; i-=1 )
  2223.         {
  2224.             RemoveEffect( buffs[i] );
  2225.         }
  2226.        
  2227.         super.OnStartFistfightMinigame();
  2228.     }
  2229.    
  2230.     event OnEndFistfightMinigame()
  2231.     {
  2232.         super.OnEndFistfightMinigame();
  2233.     }
  2234.    
  2235.    
  2236.     public function GetCriticalHitChance( isLightAttack : bool, isHeavyAttack : bool, target : CActor, victimMonsterCategory : EMonsterCategory, isBolt : bool ) : float
  2237.     {
  2238.         var ret : float;
  2239.         var thunder : W3Potion_Thunderbolt;
  2240.         var min, max : SAbilityAttributeValue;
  2241.        
  2242.         ret = super.GetCriticalHitChance( isLightAttack, isHeavyAttack, target, victimMonsterCategory, isBolt );
  2243.        
  2244.        
  2245.        
  2246.        
  2247.        
  2248.        
  2249.        
  2250.         thunder = ( W3Potion_Thunderbolt )GetBuff( EET_Thunderbolt );
  2251.         if( thunder && thunder.GetBuffLevel() == 3 && GetCurWeather() == EWE_Storm )
  2252.         {
  2253.             ret += 1.0f;
  2254.         }
  2255.        
  2256.        
  2257.         if( isBolt && IsMutationActive( EPMT_Mutation9 ) )
  2258.         {
  2259.             theGame.GetDefinitionsManager().GetAbilityAttributeValue('Mutation9', 'critical_hit_chance', min, max);
  2260.             ret += min.valueMultiplicative;
  2261.         }
  2262.        
  2263.        
  2264.         if( isBolt && CanUseSkill( S_Sword_s07 ) )
  2265.         {
  2266.             ret += CalculateAttributeValue(GetSkillAttributeValue(S_Sword_s07, theGame.params.CRITICAL_HIT_CHANCE, false, true)) * GetSkillLevel(S_Sword_s07);
  2267.         }
  2268.            
  2269.         return ret;
  2270.     }
  2271.    
  2272.    
  2273.     public function GetCriticalHitDamageBonus(weaponId : SItemUniqueId, victimMonsterCategory : EMonsterCategory, isStrikeAtBack : bool) : SAbilityAttributeValue
  2274.     {
  2275.         var min, max, bonus, null, oilBonus : SAbilityAttributeValue;
  2276.         var mutagen : CBaseGameplayEffect;
  2277.         var monsterBonusType : name;
  2278.        
  2279.         bonus = super.GetCriticalHitDamageBonus(weaponId, victimMonsterCategory, isStrikeAtBack);
  2280.        
  2281.        
  2282.         if( inv.ItemHasActiveOilApplied( weaponId, victimMonsterCategory ) && GetStat( BCS_Focus ) >= 3 && CanUseSkill( S_Alchemy_s07 ) )
  2283.         {
  2284.             monsterBonusType = MonsterCategoryToAttackPowerBonus( victimMonsterCategory );
  2285.             oilBonus = inv.GetItemAttributeValue( weaponId, monsterBonusType );
  2286.             if(oilBonus != null)   
  2287.             {
  2288.                 bonus += GetSkillAttributeValue(S_Alchemy_s07, theGame.params.CRITICAL_HIT_DAMAGE_BONUS, false, true) * GetSkillLevel(S_Alchemy_s07);  
  2289.                
  2290.  
  2291.             }
  2292.         }
  2293.        
  2294.        
  2295.         if (isStrikeAtBack && HasBuff(EET_Mutagen11))
  2296.         {
  2297.             mutagen = GetBuff(EET_Mutagen11);
  2298.             theGame.GetDefinitionsManager().GetAbilityAttributeValue(mutagen.GetAbilityName(), 'damageIncrease', min, max);
  2299.             bonus += GetAttributeRandomizedValue(min, max);
  2300.         }
  2301.            
  2302.         return bonus;      
  2303.     }
  2304.    
  2305.     public function ProcessLockTarget( optional newLockTarget : CActor, optional checkLeftStickHeading : bool ) : bool
  2306.     {
  2307.         var newLockTargetFound  : bool;
  2308.    
  2309.         newLockTargetFound = super.ProcessLockTarget(newLockTarget, checkLeftStickHeading);
  2310.        
  2311.         if(GetCurrentlyCastSign() == ST_Axii)
  2312.         {
  2313.             ((W3AxiiEntity)GetCurrentSignEntity()).OnDisplayTargetChange(newLockTarget);
  2314.         }
  2315.        
  2316.         return newLockTargetFound;
  2317.     }
  2318.    
  2319.    
  2320.    
  2321.    
  2322.    
  2323.    
  2324.    
  2325.      event OnProcessActionPost(action : W3DamageAction)
  2326.     {
  2327.         var attackAction : W3Action_Attack;
  2328.         var rendLoad : float;
  2329.         var value : SAbilityAttributeValue;
  2330.         var actorVictim : CActor;
  2331.         var weaponId : SItemUniqueId;
  2332.         var usesSteel, usesSilver, usesVitality, usesEssence : bool;
  2333.         var abs : array<name>;
  2334.         var i : int;
  2335.         var dm : CDefinitionsManagerAccessor;
  2336.         var items : array<SItemUniqueId>;
  2337.         var weaponEnt : CEntity;
  2338.        
  2339.         var fxName : name;
  2340.         var pos : Vector;
  2341.        
  2342.         super.OnProcessActionPost(action);
  2343.        
  2344.         attackAction = (W3Action_Attack)action;
  2345.         actorVictim = (CActor)action.victim;
  2346.        
  2347.         if(attackAction)
  2348.         {
  2349.             if(attackAction.IsActionMelee())
  2350.             {
  2351.                
  2352.                 if(SkillNameToEnum(attackAction.GetAttackTypeName()) == S_Sword_s02)
  2353.                 {
  2354.                     rendLoad = GetSpecialAttackTimeRatio();
  2355.                    
  2356.                    
  2357.                     rendLoad = MinF(rendLoad * GetStatMax(BCS_Focus), GetStat(BCS_Focus));
  2358.                    
  2359.                    
  2360.                     rendLoad = FloorF(rendLoad);                   
  2361.                     DrainFocus(rendLoad);
  2362.                    
  2363.                     OnSpecialAttackHeavyActionProcess();
  2364.                 }
  2365.                 else if(actorVictim && IsRequiredAttitudeBetween(this, actorVictim, true))
  2366.                 {
  2367.                    
  2368.                    
  2369.                     value = GetAttributeValue('focus_gain');
  2370.                    
  2371.                     if( FactsQuerySum("debug_fact_focus_boy") > 0 )
  2372.                     {
  2373.                         Debug_FocusBoyFocusGain();
  2374.                     }
  2375.                    
  2376.                    
  2377.                     if ( CanUseSkill(S_Sword_s20) )
  2378.                     {
  2379.                         value += GetSkillAttributeValue(S_Sword_s20, 'focus_gain', false, true) * GetSkillLevel(S_Sword_s20);
  2380.                     }
  2381.                    
  2382.  
  2383.                
  2384.                     if( IsMutationActive( EPMT_Mutation3 ) && IsRequiredAttitudeBetween( this, action.victim, true ) && !action.victim.HasTag( 'Mutation3InvalidTarget' ) && !attackAction.IsParried() && !attackAction.WasDodged() && !attackAction.IsCountered() && !inv.IsItemFists( attackAction.GetWeaponId() ) && !attackAction.WasDamageReturnedToAttacker() && attackAction.DealtDamage() )
  2385.                     {
  2386.                         AddEffectDefault( EET_Mutation3, this, "", false );
  2387.                     }
  2388.                    
  2389.                     GainStat(BCS_Focus, 0.1f * (1 + CalculateAttributeValue(value)) );
  2390.                    
  2391.                     if (thePlayer.HasBuff(EET_Mutagen44) && GetStat(BCS_Focus) != GetStatMax(BCS_Focus))
  2392.                         GainStat(BCS_Focus, -(0.1f * GetStat(BCS_Focus) - 0.3f));
  2393.                 }
  2394.                
  2395.                
  2396.                 weaponId = attackAction.GetWeaponId();
  2397.                 if(actorVictim && (ShouldProcessTutorial('TutorialWrongSwordSteel') || ShouldProcessTutorial('TutorialWrongSwordSilver')) && GetAttitudeBetween(actorVictim, this) == AIA_Hostile)
  2398.                 {
  2399.                     usesSteel = inv.IsItemSteelSwordUsableByPlayer(weaponId);
  2400.                     usesSilver = inv.IsItemSilverSwordUsableByPlayer(weaponId);
  2401.                     usesVitality = actorVictim.UsesVitality();
  2402.                     usesEssence = actorVictim.UsesEssence();
  2403.                    
  2404.                     if(usesSilver && usesVitality)
  2405.                     {
  2406.                         FactsAdd('tut_wrong_sword_silver',1);
  2407.                     }
  2408.                     else if(usesSteel && usesEssence)
  2409.                     {
  2410.                         FactsAdd('tut_wrong_sword_steel',1);
  2411.                     }
  2412.                     else if(FactsQuerySum('tut_wrong_sword_steel') && usesSilver && usesEssence)
  2413.                     {
  2414.                         FactsAdd('tut_proper_sword_silver',1);
  2415.                         FactsRemove('tut_wrong_sword_steel');
  2416.                     }
  2417.                     else if(FactsQuerySum('tut_wrong_sword_silver') && usesSteel && usesVitality)
  2418.                     {
  2419.                         FactsAdd('tut_proper_sword_steel',1);
  2420.                         FactsRemove('tut_wrong_sword_silver');
  2421.                     }
  2422.                 }
  2423.                
  2424.                
  2425.  
  2426.  
  2427.                
  2428.                
  2429.                 if(!action.WasDodged() && HasAbility('Runeword 1 _Stats', true))
  2430.                 //if(!action.WasDodged() && IsMutationActive( EPMT_Mutation1 ))
  2431.                 {
  2432.  
  2433.                     if(runewordInfusionType == ST_Axii)
  2434.                     {
  2435.                         actorVictim.SoundEvent('sign_axii_release');
  2436.                     }
  2437.                     else if(runewordInfusionType == ST_Igni)
  2438.                     {
  2439.                         actorVictim.SoundEvent('sign_igni_charge_begin');
  2440.                     }
  2441.                     else if(runewordInfusionType == ST_Quen)
  2442.                     {
  2443.                         value = GetAttributeValue('runeword1_quen_heal');
  2444.                         Heal( action.GetDamageDealt() * value.valueMultiplicative );
  2445.                         PlayEffectSingle('drain_energy_caretaker_shovel');
  2446.  
  2447.                     }
  2448.                     else if(runewordInfusionType == ST_Yrden)
  2449.                     {
  2450.                         actorVictim.SoundEvent('sign_yrden_shock_activate');
  2451.  
  2452.                     }
  2453.                     items = inv.GetHeldWeapons();
  2454.                     weaponEnt = inv.GetItemEntityUnsafe(items[0]); 
  2455.                     if(IsMutationActive( EPMT_Mutation1 ))
  2456.                     {
  2457.                     AddTimer('UndyingSkillCooldown3',10,true);
  2458.                     }
  2459.                     else
  2460.                     {
  2461.  
  2462.                     weaponEnt.StopEffect('runeword_aard');
  2463.                     weaponEnt.StopEffect('runeword_axii');
  2464.                     weaponEnt.StopEffect('runeword_igni');
  2465.                     weaponEnt.StopEffect('runeword_quen');
  2466.                     weaponEnt.StopEffect('runeword_yrden');
  2467.                     runewordInfusionType = ST_None;
  2468.                     }
  2469.  
  2470.                     //runewordInfusionType = ST_None;
  2471.    
  2472.                    // if(IsInCombatAction() && GetStat(BCS_Focus) >= 0.1f)
  2473.                     //{
  2474.                     //}
  2475.                    // else
  2476.                     //{
  2477.  
  2478.                     //}
  2479.                 }
  2480.                
  2481.    
  2482.                
  2483.                 if(ShouldProcessTutorial('TutorialLightAttacks') || ShouldProcessTutorial('TutorialHeavyAttacks'))
  2484.                 {
  2485.                     if(IsLightAttack(attackAction.GetAttackName()))
  2486.                     {
  2487.                         theGame.GetTutorialSystem().IncreaseGeraltsLightAttacksCount(action.victim.GetTags());
  2488.                     }
  2489.                     else if(IsHeavyAttack(attackAction.GetAttackName()))
  2490.                     {
  2491.                         theGame.GetTutorialSystem().IncreaseGeraltsHeavyAttacksCount(action.victim.GetTags());
  2492.                     }
  2493.                 }
  2494.             }
  2495.             else if(attackAction.IsActionRanged())
  2496.             {
  2497.                
  2498.                 if(CanUseSkill(S_Sword_s15))
  2499.                 {              
  2500.                     value = GetSkillAttributeValue(S_Sword_s15, 'focus_gain', false, true) * GetSkillLevel(S_Sword_s15) ;
  2501.                     GainStat(BCS_Focus, CalculateAttributeValue(value) );
  2502.                 }
  2503.                
  2504.                
  2505.                 if(CanUseSkill(S_Sword_s12) && attackAction.IsCriticalHit() && actorVictim)
  2506.                 {
  2507.                    
  2508.                     actorVictim.GetCharacterStats().GetAbilities(abs, false);
  2509.                     dm = theGame.GetDefinitionsManager();
  2510.                     for(i=abs.Size()-1; i>=0; i-=1)
  2511.                     {
  2512.                         if(!dm.AbilityHasTag(abs[i], theGame.params.TAG_MONSTER_SKILL) || actorVictim.IsAbilityBlocked(abs[i]))
  2513.                         {
  2514.                             abs.EraseFast(i);
  2515.                         }
  2516.                     }
  2517.                    
  2518.                    
  2519.                     if(abs.Size() > 0)
  2520.                     {
  2521.                         value = GetSkillAttributeValue(S_Sword_s12, 'duration', true, true) * GetSkillLevel(S_Sword_s12);
  2522.                         actorVictim.BlockAbility(abs[ RandRange(abs.Size()) ], true, CalculateAttributeValue(value));
  2523.                     }
  2524.                 }
  2525.             }
  2526.         }
  2527.        
  2528.        
  2529.         if( IsMutationActive( EPMT_Mutation10 ) && !IsEffectActive( 'mutation_10_energy' ) && ( action.IsActionMelee() || action.IsActionWitcherSign() ) )
  2530.         {
  2531.             PlayEffect( 'mutation_10_energy' );
  2532.         }
  2533.        
  2534.        
  2535.         if(CanUseSkill(S_Perk_18) && ((W3Petard)action.causer) && action.DealsAnyDamage() && !action.IsDoTDamage())
  2536.         {
  2537.             value = GetSkillAttributeValue(S_Perk_18, 'focus_gain', false, true);
  2538.             GainStat(BCS_Focus, CalculateAttributeValue(value));
  2539.         }      
  2540.        
  2541.        
  2542.         if( attackAction && IsHeavyAttack( attackAction.GetAttackName() ) && !IsUsingHorse() && attackAction.DealtDamage() && IsSetBonusActive( EISB_Lynx_1 ) && !attackAction.WasDodged() && !attackAction.IsParried() && !attackAction.IsCountered() && ( inv.IsItemSteelSwordUsableByPlayer( attackAction.GetWeaponId() ) || inv.IsItemSilverSwordUsableByPlayer( attackAction.GetWeaponId() ) ) )
  2543.         {
  2544.             AddEffectDefault( EET_LynxSetBonus, NULL, "HeavyAttack" );
  2545.             SoundEvent( "ep2_setskill_lynx_activate" );
  2546.         }      
  2547.     }
  2548.    
  2549.     timer function UndyingSkillCooldown3(dt : float, id : int)
  2550.     {
  2551.         var attackAction : W3Action_Attack;
  2552.         var rendLoad : float;
  2553.         var value : SAbilityAttributeValue;
  2554.         var actorVictim : CActor;
  2555.         var weaponId : SItemUniqueId;
  2556.         var usesSteel, usesSilver, usesVitality, usesEssence : bool;
  2557.         var abs : array<name>;
  2558.         var i : int;
  2559.         var dm : CDefinitionsManagerAccessor;
  2560.         var items : array<SItemUniqueId>;
  2561.         var weaponEnt : CEntity;
  2562.  
  2563.        
  2564.         var fxName : name;
  2565.         var pos : Vector;
  2566.    
  2567.        
  2568.         items = inv.GetHeldWeapons();
  2569.         weaponEnt = inv.GetItemEntityUnsafe(items[0]);
  2570.         weaponEnt.StopEffect('runeword_aard');
  2571.         weaponEnt.StopEffect('runeword_axii');
  2572.         weaponEnt.StopEffect('runeword_igni');
  2573.         weaponEnt.StopEffect('runeword_quen');
  2574.         weaponEnt.StopEffect('runeword_yrden');
  2575.         runewordInfusionType = ST_None;
  2576.  
  2577.        
  2578.         }
  2579.    
  2580.  
  2581.     timer function Mutagen14Timer(dt : float, id : int)
  2582.     {
  2583.         var abilityName : name;
  2584.         var abilityCount, maxStack : float;
  2585.         var min, max : SAbilityAttributeValue;
  2586.         var addAbility : bool;
  2587.        
  2588.         abilityName = GetBuff(EET_Mutagen14).GetAbilityName();
  2589.         abilityCount = GetAbilityCount(abilityName);
  2590.        
  2591.         if(abilityCount == 0)
  2592.         {
  2593.             addAbility = true;
  2594.         }
  2595.         else
  2596.         {
  2597.             theGame.GetDefinitionsManager().GetAbilityAttributeValue(abilityName, 'mutagen14_max_stack', min, max);
  2598.             maxStack = CalculateAttributeValue(GetAttributeRandomizedValue(min, max));
  2599.            
  2600.             if(maxStack >= 0)
  2601.             {
  2602.                 addAbility = (abilityCount < maxStack);
  2603.             }
  2604.             else
  2605.             {
  2606.                 addAbility = true;
  2607.             }
  2608.         }
  2609.        
  2610.         if(addAbility)
  2611.         {
  2612.             AddAbility(abilityName, true);
  2613.         }
  2614.         else
  2615.         {
  2616.            
  2617.             RemoveTimer('Mutagen14Timer');
  2618.         }
  2619.     }
  2620.    
  2621.     public final function FailFundamentalsFirstAchievementCondition()
  2622.     {
  2623.         SetFailedFundamentalsFirstAchievementCondition(true);
  2624.     }
  2625.        
  2626.     public final function SetUsedQuenInCombat()
  2627.     {
  2628.         usedQuenInCombat = true;
  2629.     }
  2630.    
  2631.     public final function UsedQuenInCombat() : bool
  2632.     {
  2633.         return usedQuenInCombat;
  2634.     }
  2635.    
  2636.     event OnCombatStart()
  2637.     {
  2638.         var quenEntity, glyphQuen : W3QuenEntity;
  2639.         var focus, stamina : float;
  2640.         var glowTargets, moTargets, actors : array< CActor >;
  2641.         var delays : array< float >;
  2642.         var rand, i : int;
  2643.         var isHostile, isAlive, isUnconscious : bool;
  2644.        
  2645.        
  2646.         super.OnCombatStart();
  2647.        
  2648.         if ( IsInCombatActionFriendly() )
  2649.         {
  2650.             SetBIsCombatActionAllowed(true);
  2651.             SetBIsInputAllowed(true, 'OnCombatActionStart' );
  2652.         }
  2653.        
  2654.        
  2655.         if(HasBuff(EET_Mutagen14))
  2656.         {
  2657.             AddTimer('Mutagen14Timer', 2, true);
  2658.         }
  2659.        
  2660.        
  2661.         if(HasBuff(EET_Mutagen15))
  2662.         {
  2663.             AddAbility(GetBuff(EET_Mutagen15).GetAbilityName(), false);
  2664.         }
  2665.        
  2666.        
  2667.         mutation12IsOnCooldown = false;
  2668.        
  2669.        
  2670.         quenEntity = (W3QuenEntity)signs[ST_Quen].entity;      
  2671.        
  2672.        
  2673.         if(quenEntity)
  2674.         {
  2675.             usedQuenInCombat = quenEntity.IsAnyQuenActive();
  2676.         }
  2677.         else
  2678.         {
  2679.             usedQuenInCombat = false;
  2680.         }
  2681.        
  2682.         if(usedQuenInCombat || HasPotionBuff() || IsEquippedSwordUpgradedWithOil(true) || IsEquippedSwordUpgradedWithOil(false))
  2683.         {
  2684.             SetFailedFundamentalsFirstAchievementCondition(true);
  2685.         }
  2686.         else
  2687.         {
  2688.             if(IsAnyItemEquippedOnSlot(EES_PotionMutagen1) || IsAnyItemEquippedOnSlot(EES_PotionMutagen2) || IsAnyItemEquippedOnSlot(EES_PotionMutagen3) || IsAnyItemEquippedOnSlot(EES_PotionMutagen4))
  2689.                 SetFailedFundamentalsFirstAchievementCondition(true);
  2690.             else
  2691.                 SetFailedFundamentalsFirstAchievementCondition(false);
  2692.         }
  2693.        
  2694.         if(CanUseSkill(S_Sword_s20) && IsThreatened())
  2695.         {
  2696.             focus = GetStat(BCS_Focus);
  2697.             if(focus < 1)
  2698.             {
  2699.                 GainStat(BCS_Focus, 1 - focus);
  2700.             }
  2701.         }
  2702.  
  2703.         if ( HasAbility('Glyphword 17 _Stats', true) && RandF() < CalculateAttributeValue(GetAttributeValue('quen_apply_chance')) )
  2704.         {
  2705.             stamina = GetStat(BCS_Stamina);
  2706.             glyphQuen = (W3QuenEntity)theGame.CreateEntity( signs[ST_Quen].template, GetWorldPosition(), GetWorldRotation() );
  2707.             glyphQuen.Init( signOwner, signs[ST_Quen].entity, true );
  2708.             glyphQuen.OnStarted();
  2709.             glyphQuen.OnThrowing();
  2710.             glyphQuen.OnEnded();
  2711.             ForceSetStat(BCS_Stamina, stamina);
  2712.         }
  2713.        
  2714.        
  2715.         MeditationForceAbort(true);
  2716.        
  2717.        
  2718.        
  2719.  
  2720.        
  2721.         if( IsMutationActive( EPMT_Mutation4 ) )
  2722.         {
  2723.             AddEffectDefault( EET_Mutation4, this, "combat start", false );
  2724.         }
  2725.         else if( IsMutationActive( EPMT_Mutation5 ) && GetStat( BCS_Focus ) >= 1.f )
  2726.         {
  2727.             AddEffectDefault( EET_Mutation5, this, "", false );
  2728.             //
  2729.         }
  2730.        
  2731.         else if( IsMutationActive( EPMT_Mutation7 ) )
  2732.         {
  2733.            
  2734.                
  2735.                 RemoveTimer( 'Mutation7CombatStartHackFixGo' );
  2736.                
  2737.                
  2738.                 AddTimer( 'Mutation7CombatStartHackFix', 1.f, true, , , , true );
  2739.            
  2740.         }
  2741.         else if( IsMutationActive( EPMT_Mutation8 ) )
  2742.         {
  2743.             theGame.MutationHUDFeedback( MFT_PlayRepeat );
  2744.         }
  2745.        
  2746.         else if( IsMutationActive( EPMT_Mutation10 ) )
  2747.         {
  2748.             if( !HasBuff( EET_Mutation10 ) && GetStat( BCS_Toxicity ) > 0.f )
  2749.             {
  2750.                 AddEffectDefault( EET_Mutation10, this, "Mutation 10" );
  2751.             }
  2752.            
  2753.            
  2754.             PlayEffect( 'mutation_10' );
  2755.            
  2756.            
  2757.             PlayEffect( 'critical_toxicity' );
  2758.             AddTimer( 'Mutation10StopEffect', 5.f );
  2759.         }
  2760.     }
  2761.    
  2762.     timer function Mutation7CombatStartHackFix( dt : float, id : int )
  2763.     {
  2764.         var actors : array< CActor >;
  2765.        
  2766.         actors = GetEnemies();
  2767.        
  2768.         if( actors.Size() > 0 )
  2769.         {
  2770.            
  2771.             AddTimer( 'Mutation7CombatStartHackFixGo', 0.5f );
  2772.             RemoveTimer( 'Mutation7CombatStartHackFix' );
  2773.         }
  2774.     }
  2775.    
  2776.    
  2777.    
  2778.    
  2779.    
  2780.    
  2781.  
  2782.    
  2783.     timer function Mutation7CombatStartHackFixGo( dt : float, id : int )
  2784.     {
  2785.         var actors : array< CActor >;
  2786.        
  2787.         if( IsMutationActive( EPMT_Mutation7 ) )
  2788.         {
  2789.             actors = GetEnemies();
  2790.            
  2791.             if( actors.Size() > 1 )
  2792.             {      
  2793.                 AddEffectDefault( EET_Mutation7Buff, this, "Mutation 7, combat start" );           
  2794.             }
  2795.         }
  2796.     }
  2797.    
  2798.     public final function IsInFistFight() : bool
  2799.     {
  2800.         var enemies : array< CActor >;
  2801.         var i, j : int;
  2802.         var invent : CInventoryComponent;
  2803.         var weapons : array< SItemUniqueId >;
  2804.        
  2805.         if( IsInFistFightMiniGame() )
  2806.         {
  2807.             return true;
  2808.         }
  2809.        
  2810.         enemies = GetEnemies();
  2811.         for( i=0; i<enemies.Size(); i+=1 )
  2812.         {
  2813.             weapons.Clear();
  2814.             invent = enemies[i].GetInventory();
  2815.             weapons = invent.GetHeldWeapons();
  2816.            
  2817.             for( j=0; j<weapons.Size(); j+=1 )
  2818.             {
  2819.                 if( invent.IsItemFists( weapons[j] ) )
  2820.                 {
  2821.                     return true;
  2822.                 }
  2823.             }
  2824.         }
  2825.        
  2826.         return false;
  2827.     }
  2828.    
  2829.     timer function Mutation10StopEffect( dt : float, id : int )
  2830.     {
  2831.         StopEffect( 'critical_toxicity' );
  2832.     }
  2833.    
  2834.    
  2835.     event OnCombatFinished()
  2836.     {
  2837.         var mut17 : W3Mutagen17_Effect;
  2838.         var inGameConfigWrapper : CInGameConfigWrapper;
  2839.         var disableAutoSheathe : bool; 
  2840.        
  2841.         super.OnCombatFinished();
  2842.        
  2843.        
  2844.         if(HasBuff(EET_Mutagen10))
  2845.         {
  2846.             RemoveAbilityAll( GetBuff(EET_Mutagen10).GetAbilityName() );
  2847.         }
  2848.        
  2849.        
  2850.         if(HasBuff(EET_Mutagen14))
  2851.         {
  2852.             RemoveAbilityAll( GetBuff(EET_Mutagen14).GetAbilityName() );
  2853.         }
  2854.        
  2855.        
  2856.         if(HasBuff(EET_Mutagen15))
  2857.         {
  2858.             RemoveAbilityAll( GetBuff(EET_Mutagen15).GetAbilityName() );
  2859.         }
  2860.        
  2861.        
  2862.         if(HasBuff(EET_Mutagen17))
  2863.         {
  2864.             mut17 = (W3Mutagen17_Effect)GetBuff(EET_Mutagen17);
  2865.             mut17.ClearBoost();
  2866.         }
  2867.        
  2868.        
  2869.         if(HasBuff(EET_Mutagen18))
  2870.         {
  2871.             RemoveAbilityAll( GetBuff(EET_Mutagen18).GetAbilityName() );
  2872.         }
  2873.        
  2874.        
  2875.         if(HasBuff(EET_Mutagen22))
  2876.         {
  2877.             RemoveAbilityAll( GetBuff(EET_Mutagen22).GetAbilityName() );
  2878.         }
  2879.        
  2880.        
  2881.         if(HasBuff(EET_Mutagen27))
  2882.         {
  2883.             RemoveAbilityAll( GetBuff(EET_Mutagen27).GetAbilityName() );
  2884.         }
  2885.  
  2886.         if(HasBuff(EET_Mutagen32))
  2887.         {
  2888.             RemoveAbilityAll( GetBuff(EET_Mutagen32).GetAbilityName() );
  2889.         }
  2890.        
  2891.         RemoveBuff( EET_Mutation3 );
  2892.        
  2893.        
  2894.         RemoveBuff( EET_Mutation4 );
  2895.        
  2896.        
  2897.         RemoveBuff( EET_Mutation5 );
  2898.        
  2899.        
  2900.         RemoveBuff( EET_Mutation7Buff );
  2901.         RemoveBuff( EET_Mutation7Debuff );
  2902.            
  2903.         if( IsMutationActive( EPMT_Mutation7 ) )
  2904.         {
  2905.             theGame.MutationHUDFeedback( MFT_PlayHide );
  2906.         }
  2907.         else if( IsMutationActive( EPMT_Mutation8 ) )
  2908.         {
  2909.             theGame.MutationHUDFeedback( MFT_PlayHide );
  2910.         }
  2911.        
  2912.        
  2913.         RemoveBuff( EET_Mutation10 );
  2914.        
  2915.        
  2916.         RemoveBuff( EET_LynxSetBonus );
  2917.        
  2918.        
  2919.         if(GetStat(BCS_Focus) > 0)
  2920.         {
  2921.             AddTimer('DelayedAdrenalineDrain', theGame.params.ADRENALINE_DRAIN_AFTER_COMBAT_DELAY, , , , true);
  2922.         }
  2923.        
  2924.        
  2925.         thePlayer.abilityManager.ResetOverhealBonus();
  2926.        
  2927.         usedQuenInCombat = false;      
  2928.        
  2929.         theGame.GetGamerProfile().ResetStat(ES_FinesseKills);
  2930.        
  2931.         LogChannel( 'OnCombatFinished', "OnCombatFinished: DelayedSheathSword timer added" );
  2932.        
  2933.        
  2934.         inGameConfigWrapper = (CInGameConfigWrapper)theGame.GetInGameConfigWrapper();
  2935.         disableAutoSheathe = inGameConfigWrapper.GetVarValue( 'Gameplay', 'DisableAutomaticSwordSheathe' );        
  2936.         if( !disableAutoSheathe )
  2937.         {
  2938.             if ( ShouldAutoSheathSwordInstantly() )
  2939.                 AddTimer( 'DelayedSheathSword', 0.5f );
  2940.             else
  2941.                 AddTimer( 'DelayedSheathSword', 2.f );
  2942.         }
  2943.        
  2944.         OnBlockAllCombatTickets( false );
  2945.        
  2946.         // AeroHD -- AutoLootMenu++
  2947.         mAutoLootNotificationManager.ShowNotification(true);
  2948.         // AeroHD -- AutoLootMenu--
  2949.        
  2950.         runewordInfusionType = ST_None;
  2951.        
  2952.        
  2953.        
  2954.        
  2955.        
  2956.     }
  2957.    
  2958.     public function PlayHitEffect( damageAction : W3DamageAction )
  2959.     {
  2960.         var hitReactionType     : EHitReactionType;
  2961.         var isAtBack            : bool;
  2962.        
  2963.        
  2964.         if( damageAction.GetMutation4Triggered() )
  2965.         {
  2966.             hitReactionType = damageAction.GetHitReactionType();
  2967.             isAtBack = IsAttackerAtBack( damageAction.attacker );
  2968.            
  2969.             if( hitReactionType != EHRT_Heavy )
  2970.             {
  2971.                 if( isAtBack )
  2972.                 {
  2973.                     damageAction.SetHitEffect( 'light_hit_back_toxic', true );                 
  2974.                 }
  2975.                 else
  2976.                 {
  2977.                     damageAction.SetHitEffect( 'light_hit_toxic' );
  2978.                 }
  2979.             }
  2980.             else
  2981.             {
  2982.                 if( isAtBack )
  2983.                 {
  2984.                     damageAction.SetHitEffect( 'heavy_hit_back_toxic' ,true );
  2985.                 }
  2986.                 else
  2987.                 {
  2988.                     damageAction.SetHitEffect( 'heavy_hit_toxic' );
  2989.                 }
  2990.             }
  2991.         }
  2992.        
  2993.         super.PlayHitEffect( damageAction );
  2994.     }
  2995.    
  2996.     timer function DelayedAdrenalineDrain(dt : float, id : int)
  2997.     {
  2998.         if ( !HasBuff(EET_Runeword8) )
  2999.             AddEffectDefault(EET_AdrenalineDrain, this, "after_combat_adrenaline_drain");
  3000.     }
  3001.    
  3002.    
  3003.     protected function Attack( hitTarget : CGameplayEntity, animData : CPreAttackEventData, weaponId : SItemUniqueId, parried : bool, countered : bool, parriedBy : array<CActor>, attackAnimationName : name, hitTime : float, weaponEntity : CItemEntity)
  3004.     {
  3005.         var mutagen17 : W3Mutagen17_Effect;
  3006.        
  3007.         super.Attack(hitTarget, animData, weaponId, parried, countered, parriedBy, attackAnimationName, hitTime, weaponEntity);
  3008.        
  3009.         if( (CActor)hitTarget && HasBuff(EET_Mutagen17) )
  3010.         {
  3011.             mutagen17 = (W3Mutagen17_Effect)GetBuff(EET_Mutagen17);
  3012.             if(mutagen17.HasBoost())
  3013.             {
  3014.                 mutagen17.ClearBoost();
  3015.             }
  3016.         }
  3017.     }
  3018.    
  3019.     public final timer function SpecialAttackLightSustainCost(dt : float, id : int)
  3020.     {
  3021.         var focusPerSec, cost, delay : float;
  3022.         var reduction : SAbilityAttributeValue;
  3023.         var skillLevel : int;
  3024.        
  3025.         if(abilityManager && abilityManager.IsInitialized() && IsAlive())
  3026.         {
  3027.             PauseStaminaRegen('WhirlSkill');
  3028.            
  3029.             if(GetStat(BCS_Stamina) > 0)
  3030.             {
  3031.                 cost = GetStaminaActionCost(ESAT_Ability, GetSkillAbilityName(S_Sword_s01), dt);
  3032.                 delay = GetStaminaActionDelay(ESAT_Ability, GetSkillAbilityName(S_Sword_s01), dt);
  3033.                 skillLevel = GetSkillLevel(S_Sword_s01);
  3034.                
  3035.                 if(skillLevel > 1)
  3036.                 {
  3037.                     reduction = GetSkillAttributeValue(S_Sword_s01, 'cost_reduction', false, true) * (skillLevel - 1);
  3038.                     cost = MaxF(0, cost * (1 - reduction.valueMultiplicative) - reduction.valueAdditive);
  3039.                 }
  3040.                
  3041.                 DrainStamina(ESAT_FixedValue, cost, delay, GetSkillAbilityName(S_Sword_s01));
  3042.             }
  3043.             else               
  3044.             {              
  3045.                 GetSkillAttributeValue(S_Sword_s01, 'focus_cost_per_sec', false, true);
  3046.                 focusPerSec = GetWhirlFocusCostPerSec();
  3047.                 DrainFocus(focusPerSec * dt);
  3048.             }
  3049.         }
  3050.        
  3051.         if(GetStat(BCS_Stamina) <= 0 && GetStat(BCS_Focus) <= 0)
  3052.         {
  3053.             OnPerformSpecialAttack(true, false);
  3054.         }
  3055.     }
  3056.    
  3057.     public final function GetWhirlFocusCostPerSec() : float
  3058.     {
  3059.         var ability : SAbilityAttributeValue;
  3060.         var val : float;
  3061.         var skillLevel : int;
  3062.        
  3063.         ability = GetSkillAttributeValue(S_Sword_s01, 'focus_cost_per_sec_initial', false, false);
  3064.         skillLevel = GetSkillLevel(S_Sword_s01);
  3065.        
  3066.         if(skillLevel > 1)
  3067.             ability -= GetSkillAttributeValue(S_Sword_s01, 'cost_reduction', false, false) * (skillLevel-1);
  3068.            
  3069.         val = CalculateAttributeValue(ability);
  3070.        
  3071.         return val;
  3072.     }
  3073.    
  3074.     public final timer function SpecialAttackHeavySustainCost(dt : float, id : int)
  3075.     {
  3076.         var focusHighlight, ratio : float;
  3077.         var hud : CR4ScriptedHud;
  3078.         var hudWolfHeadModule : CR4HudModuleWolfHead;      
  3079.  
  3080.        
  3081.         DrainStamina(ESAT_Ability, 0, 0, GetSkillAbilityName(S_Sword_s02), dt);
  3082.  
  3083.        
  3084.         if(GetStat(BCS_Stamina) <= 0)
  3085.             OnPerformSpecialAttack(false, false);
  3086.            
  3087.        
  3088.         ratio = EngineTimeToFloat(theGame.GetEngineTime() - specialHeavyStartEngineTime) / specialHeavyChargeDuration;
  3089.        
  3090.        
  3091.         if(ratio > 0.95)
  3092.             ratio = 1;
  3093.            
  3094.         SetSpecialAttackTimeRatio(ratio);
  3095.        
  3096.        
  3097.         focusHighlight = ratio * GetStatMax(BCS_Focus);
  3098.         focusHighlight = MinF(focusHighlight, GetStat(BCS_Focus));
  3099.         focusHighlight = FloorF(focusHighlight);
  3100.        
  3101.         hud = (CR4ScriptedHud)theGame.GetHud();
  3102.         if ( hud )
  3103.         {
  3104.             hudWolfHeadModule = (CR4HudModuleWolfHead)hud.GetHudModule( "WolfHeadModule" );
  3105.             if ( hudWolfHeadModule )
  3106.             {
  3107.                 hudWolfHeadModule.LockFocusPoints((int)focusHighlight);
  3108.             }      
  3109.         }
  3110.     }
  3111.    
  3112.     public function OnSpecialAttackHeavyActionProcess()
  3113.     {
  3114.         var hud : CR4ScriptedHud;
  3115.         var hudWolfHeadModule : CR4HudModuleWolfHead;
  3116.        
  3117.         super.OnSpecialAttackHeavyActionProcess();
  3118.  
  3119.         hud = (CR4ScriptedHud)theGame.GetHud();
  3120.         if ( hud )
  3121.         {
  3122.             hudWolfHeadModule = (CR4HudModuleWolfHead)hud.GetHudModule( "WolfHeadModule" );
  3123.             if ( hudWolfHeadModule )
  3124.             {
  3125.                 hudWolfHeadModule.ResetFocusPoints();
  3126.             }      
  3127.         }
  3128.     }
  3129.    
  3130.     timer function IsSpecialLightAttackInputHeld ( time : float, id : int )
  3131.     {
  3132.         var hasResource : bool;
  3133.        
  3134.         if ( GetCurrentStateName() == 'CombatSteel' || GetCurrentStateName() == 'CombatSilver' )
  3135.         {
  3136.             if ( GetBIsCombatActionAllowed() && inputHandler.IsActionAllowed(EIAB_SwordAttack))
  3137.             {
  3138.                 if(GetStat(BCS_Stamina) > 0)
  3139.                 {
  3140.                     hasResource = true;
  3141.                 }
  3142.                 else
  3143.                 {
  3144.                     hasResource = (GetStat(BCS_Focus) >= GetWhirlFocusCostPerSec() * time);                
  3145.                 }
  3146.                
  3147.                 if(hasResource)
  3148.                 {
  3149.                     SetupCombatAction( EBAT_SpecialAttack_Light, BS_Pressed );
  3150.                     RemoveTimer('IsSpecialLightAttackInputHeld');
  3151.                 }
  3152.                 else if(!playedSpecialAttackMissingResourceSound)
  3153.                 {
  3154.                     IndicateTooLowAdrenaline();
  3155.                     playedSpecialAttackMissingResourceSound = true;
  3156.                 }
  3157.             }          
  3158.         }
  3159.         else
  3160.         {
  3161.             RemoveTimer('IsSpecialLightAttackInputHeld');
  3162.         }
  3163.     }  
  3164.    
  3165.     timer function IsSpecialHeavyAttackInputHeld ( time : float, id : int )
  3166.     {      
  3167.         var cost : float;
  3168.        
  3169.         if ( GetCurrentStateName() == 'CombatSteel' || GetCurrentStateName() == 'CombatSilver' )
  3170.         {
  3171.             cost = CalculateAttributeValue(GetSkillAttributeValue(S_Sword_s02, 'stamina_cost_per_sec', false, false));
  3172.            
  3173.             if( GetBIsCombatActionAllowed() && inputHandler.IsActionAllowed(EIAB_SwordAttack))
  3174.             {
  3175.                 if(GetStat(BCS_Stamina) >= cost)
  3176.                 {
  3177.                     SetupCombatAction( EBAT_SpecialAttack_Heavy, BS_Pressed );
  3178.                     RemoveTimer('IsSpecialHeavyAttackInputHeld');
  3179.                 }
  3180.                 else if(!playedSpecialAttackMissingResourceSound)
  3181.                 {
  3182.                     IndicateTooLowAdrenaline();
  3183.                     playedSpecialAttackMissingResourceSound = true;
  3184.                 }
  3185.             }
  3186.         }
  3187.         else
  3188.         {
  3189.             RemoveTimer('IsSpecialHeavyAttackInputHeld');
  3190.         }
  3191.     }
  3192.    
  3193.     public function EvadePressed( bufferAction : EBufferActionType )
  3194.     {
  3195.         var cat : float;
  3196.        
  3197.         if( (bufferAction == EBAT_Dodge && IsActionAllowed(EIAB_Dodge)) || (bufferAction == EBAT_Roll && IsActionAllowed(EIAB_Roll)) )
  3198.         {
  3199.            
  3200.             if(bufferAction != EBAT_Roll && ShouldProcessTutorial('TutorialDodge'))
  3201.             {
  3202.                 FactsAdd("tut_in_dodge", 1, 2);
  3203.                
  3204.                 if(FactsQuerySum("tut_fight_use_slomo") > 0)
  3205.                 {
  3206.                     theGame.RemoveTimeScale( theGame.GetTimescaleSource(ETS_TutorialFight) );
  3207.                     FactsRemove("tut_fight_slomo_ON");
  3208.                 }
  3209.             }              
  3210.             else if(bufferAction == EBAT_Roll && ShouldProcessTutorial('TutorialRoll'))
  3211.             {
  3212.                 FactsAdd("tut_in_roll", 1, 2);
  3213.                
  3214.                 if(FactsQuerySum("tut_fight_use_slomo") > 0)
  3215.                 {
  3216.                     theGame.RemoveTimeScale( theGame.GetTimescaleSource(ETS_TutorialFight) );
  3217.                     FactsRemove("tut_fight_slomo_ON");
  3218.                 }
  3219.             }
  3220.                
  3221.             if ( GetBIsInputAllowed() )
  3222.             {          
  3223.                 if ( GetBIsCombatActionAllowed() )
  3224.                 {
  3225.                     CriticalEffectAnimationInterrupted("Dodge 2");
  3226.                     PushCombatActionOnBuffer( bufferAction, BS_Released );
  3227.                     ProcessCombatActionBuffer();
  3228.                 }                  
  3229.                 else if ( IsInCombatAction() && GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Attack )
  3230.                 {
  3231.                     if ( CanPlayHitAnim() && IsThreatened() )
  3232.                     {
  3233.                         CriticalEffectAnimationInterrupted("Dodge 1");
  3234.                         PushCombatActionOnBuffer( bufferAction, BS_Released );
  3235.                         ProcessCombatActionBuffer();                           
  3236.                     }
  3237.                     else
  3238.                         PushCombatActionOnBuffer( bufferAction, BS_Released );
  3239.                 }
  3240.                
  3241.                 else if ( !( IsCurrentSignChanneled() ) )
  3242.                 {
  3243.                    
  3244.                     PushCombatActionOnBuffer( bufferAction, BS_Released );
  3245.                 }
  3246.             }
  3247.             else
  3248.             {
  3249.                 if ( IsInCombatAction() && GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Attack )
  3250.                 {
  3251.                     if ( CanPlayHitAnim() && IsThreatened() )
  3252.                     {
  3253.                         CriticalEffectAnimationInterrupted("Dodge 3");
  3254.                         PushCombatActionOnBuffer( bufferAction, BS_Released );
  3255.                         ProcessCombatActionBuffer();                           
  3256.                     }
  3257.                     else
  3258.                         PushCombatActionOnBuffer( bufferAction, BS_Released );
  3259.                 }
  3260.                 LogChannel( 'InputNotAllowed', "InputNotAllowed" );
  3261.             }
  3262.         }
  3263.         else
  3264.         {
  3265.             DisplayActionDisallowedHudMessage(EIAB_Dodge);
  3266.         }
  3267.     }
  3268.        
  3269.    
  3270.     public function ProcessCombatActionBuffer() : bool
  3271.     {
  3272.         var action              : EBufferActionType         = this.BufferCombatAction;
  3273.         var stage               : EButtonStage              = this.BufferButtonStage;      
  3274.         var throwStage          : EThrowStage;     
  3275.         var actionResult        : bool = true;
  3276.        
  3277.        
  3278.         if( isInFinisher )
  3279.         {
  3280.             return false;
  3281.         }
  3282.        
  3283.         if ( action != EBAT_SpecialAttack_Heavy )
  3284.             specialAttackCamera = false;           
  3285.        
  3286.        
  3287.         if(super.ProcessCombatActionBuffer())
  3288.             return true;       
  3289.            
  3290.         switch ( action )
  3291.         {          
  3292.             case EBAT_CastSign :
  3293.             {
  3294.                 switch ( stage )
  3295.                 {
  3296.                     case BS_Pressed :
  3297.                     {
  3298.  
  3299.  
  3300.  
  3301.  
  3302.    
  3303.    
  3304.                                 actionResult = this.CastSign();
  3305.                                 LogChannel('SignDebug', "CastSign()");
  3306.    
  3307.  
  3308.                     } break;
  3309.                    
  3310.                     default :
  3311.                     {
  3312.                         actionResult = false;
  3313.                     } break;
  3314.                 }
  3315.             } break;
  3316.            
  3317.             case EBAT_SpecialAttack_Light :
  3318.             {
  3319.                 switch ( stage )
  3320.                 {
  3321.                     case BS_Pressed :
  3322.                     {
  3323.                        
  3324.                         actionResult = this.OnPerformSpecialAttack( true, true );
  3325.                     } break;
  3326.                    
  3327.                     case BS_Released :
  3328.                     {                      
  3329.                         actionResult = this.OnPerformSpecialAttack( true, false );
  3330.                     } break;
  3331.                    
  3332.                     default :
  3333.                     {
  3334.                         actionResult = false;
  3335.                     } break;
  3336.                 }
  3337.             } break;
  3338.  
  3339.             case EBAT_SpecialAttack_Heavy :
  3340.             {
  3341.                 switch ( stage )
  3342.                 {
  3343.                     case BS_Pressed :
  3344.                     {
  3345.                        
  3346.                         actionResult = this.OnPerformSpecialAttack( false, true );
  3347.                     } break;
  3348.                    
  3349.                     case BS_Released :
  3350.                     {
  3351.                         actionResult = this.OnPerformSpecialAttack( false, false );
  3352.                     } break;
  3353.                    
  3354.                     default :
  3355.                     {
  3356.                         actionResult = false;
  3357.                     } break;
  3358.                 }
  3359.             } break;
  3360.            
  3361.             default:
  3362.                 return false;  
  3363.         }
  3364.        
  3365.        
  3366.         this.CleanCombatActionBuffer();
  3367.        
  3368.         if (actionResult)
  3369.         {
  3370.             SetCombatAction( action ) ;
  3371.         }
  3372.        
  3373.         return true;
  3374.     }
  3375.        
  3376.        
  3377.     event OnPerformSpecialAttack( isLightAttack : bool, enableAttack : bool ){}
  3378.    
  3379.     public final function GetEnemies() : array< CActor >
  3380.     {
  3381.         var actors, actors2 : array<CActor>;
  3382.         var i : int;
  3383.        
  3384.        
  3385.         actors = GetWitcherPlayer().GetHostileEnemies();
  3386.         ArrayOfActorsAppendUnique( actors, GetWitcherPlayer().GetMoveTargets() );
  3387.        
  3388.        
  3389.         thePlayer.GetVisibleEnemies( actors2 );
  3390.         ArrayOfActorsAppendUnique( actors, actors2 );
  3391.        
  3392.         for( i=actors.Size()-1; i>=0; i-=1 )
  3393.         {
  3394.             if( !IsRequiredAttitudeBetween( actors[i], this, true ) )
  3395.             {
  3396.                 actors.EraseFast( i );
  3397.             }
  3398.         }
  3399.        
  3400.         return actors;
  3401.     }
  3402.    
  3403.     event OnPlayerTickTimer( deltaTime : float )
  3404.     {
  3405.         super.OnPlayerTickTimer( deltaTime );
  3406.        
  3407.         if ( !IsInCombat() )
  3408.         {
  3409.             fastAttackCounter = 0;
  3410.             heavyAttackCounter = 0;        
  3411.         }      
  3412.     }
  3413.    
  3414.    
  3415.    
  3416.    
  3417.    
  3418.     protected function PrepareAttackAction( hitTarget : CGameplayEntity, animData : CPreAttackEventData, weaponId : SItemUniqueId, parried : bool, countered : bool, parriedBy : array<CActor>, attackAnimationName : name, hitTime : float, weaponEntity : CItemEntity, out attackAction : W3Action_Attack) : bool
  3419.     {
  3420.         var ret : bool;
  3421.         var skill : ESkill;
  3422.    
  3423.         ret = super.PrepareAttackAction(hitTarget, animData, weaponId, parried, countered, parriedBy, attackAnimationName, hitTime, weaponEntity, attackAction);
  3424.        
  3425.         if(!ret)
  3426.             return false;
  3427.        
  3428.        
  3429.         if(attackAction.IsActionMelee())
  3430.         {          
  3431.             skill = SkillNameToEnum( attackAction.GetAttackTypeName() );
  3432.             if( skill != S_SUndefined && CanUseSkill(skill))
  3433.             {
  3434.                 if(IsLightAttack(animData.attackName))
  3435.                     fastAttackCounter += 1;
  3436.                 else
  3437.                     fastAttackCounter = 0;
  3438.                
  3439.                 if(IsHeavyAttack(animData.attackName))
  3440.                     heavyAttackCounter += 1;
  3441.                 else
  3442.                     heavyAttackCounter = 0;            
  3443.             }      
  3444.         }
  3445.        
  3446.         AddTimer('FastAttackCounterDecay',5.0);
  3447.         AddTimer('HeavyAttackCounterDecay',5.0);
  3448.        
  3449.         return true;
  3450.     }
  3451.    
  3452.     protected function TestParryAndCounter(data : CPreAttackEventData, weaponId : SItemUniqueId, out parried : bool, out countered : bool) : array<CActor>
  3453.     {
  3454.        
  3455.         if(SkillNameToEnum(attackActionName) == S_Sword_s02)
  3456.             data.Can_Parry_Attack = false;
  3457.            
  3458.         return super.TestParryAndCounter(data, weaponId, parried, countered);
  3459.     }
  3460.        
  3461.     private timer function FastAttackCounterDecay(delta : float, id : int)
  3462.     {
  3463.         fastAttackCounter = 0;
  3464.     }
  3465.    
  3466.     private timer function HeavyAttackCounterDecay(delta : float, id : int)
  3467.     {
  3468.         heavyAttackCounter = 0;
  3469.     }
  3470.        
  3471.    
  3472.     public function GetCraftingSchematicsNames() : array<name>      {return craftingSchematics;}
  3473.    
  3474.     public function RemoveAllCraftingSchematics()
  3475.     {
  3476.         craftingSchematics.Clear();
  3477.     }
  3478.    
  3479.    
  3480.     function AddCraftingSchematic( nam : name, optional isSilent : bool, optional skipTutorialUpdate : bool ) : bool
  3481.     {
  3482.         var i : int;
  3483.        
  3484.         if(!skipTutorialUpdate && ShouldProcessTutorial('TutorialCraftingGotRecipe'))
  3485.         {
  3486.             FactsAdd("tut_received_schematic");
  3487.         }
  3488.        
  3489.         for(i=0; i<craftingSchematics.Size(); i+=1)
  3490.         {
  3491.             if(craftingSchematics[i] == nam)
  3492.                 return false;
  3493.            
  3494.            
  3495.             if(StrCmp(craftingSchematics[i],nam) > 0)
  3496.             {
  3497.                 craftingSchematics.Insert(i,nam);
  3498.                 AddCraftingHudNotification( nam, isSilent );
  3499.                 theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_CraftingSchematics );
  3500.                 return true;
  3501.             }          
  3502.         }  
  3503.  
  3504.        
  3505.         craftingSchematics.PushBack(nam);
  3506.         AddCraftingHudNotification( nam, isSilent );
  3507.         theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_CraftingSchematics );
  3508.         return true;   
  3509.     }
  3510.    
  3511.     function AddCraftingHudNotification( nam : name, isSilent : bool )
  3512.     {
  3513.         var hud : CR4ScriptedHud;
  3514.         if( !isSilent )
  3515.         {
  3516.             hud = (CR4ScriptedHud)theGame.GetHud();
  3517.             if( hud )
  3518.             {
  3519.                 hud.OnCraftingSchematicUpdate( nam );
  3520.             }
  3521.         }
  3522.     }  
  3523.    
  3524.     function AddAlchemyHudNotification( nam : name, isSilent : bool )
  3525.     {
  3526.         var hud : CR4ScriptedHud;
  3527.         if( !isSilent )
  3528.         {
  3529.             hud = (CR4ScriptedHud)theGame.GetHud();
  3530.             if( hud )
  3531.             {
  3532.                 hud.OnAlchemySchematicUpdate( nam );
  3533.             }
  3534.         }
  3535.     }
  3536.    
  3537.     public function GetExpandedCraftingCategories() : array< name >
  3538.     {
  3539.         return expandedCraftingCategories;
  3540.     }
  3541.    
  3542.     public function AddExpandedCraftingCategory( category : name )
  3543.     {
  3544.         if ( IsNameValid( category ) )
  3545.         {
  3546.             ArrayOfNamesPushBackUnique( expandedCraftingCategories, category );
  3547.         }
  3548.     }
  3549.  
  3550.     public function RemoveExpandedCraftingCategory( category : name )
  3551.     {
  3552.         if ( IsNameValid( category ) )
  3553.         {
  3554.             expandedCraftingCategories.Remove( category );
  3555.         }
  3556.     }
  3557.    
  3558.     public function SetCraftingFilters(showHasIngre : bool, showMissingIngre : bool, showAlreadyCrafted : bool )
  3559.     {
  3560.         craftingFilters.showCraftable = showHasIngre;
  3561.         craftingFilters.showMissingIngre = showMissingIngre;
  3562.         craftingFilters.showAlreadyCrafted = showAlreadyCrafted;
  3563.     }
  3564.    
  3565.     public function GetCraftingFilters() : SCraftingFilters
  3566.     {
  3567.        
  3568.         if ( craftingFilters.showCraftable == false && craftingFilters.showMissingIngre == false && craftingFilters.showAlreadyCrafted == false )
  3569.         {
  3570.             craftingFilters.showCraftable = true;
  3571.             craftingFilters.showMissingIngre = true;
  3572.             craftingFilters.showAlreadyCrafted = false;
  3573.         }
  3574.        
  3575.         return craftingFilters;
  3576.     }
  3577.  
  3578.    
  3579.    
  3580.    
  3581.    
  3582.     event OnMutation11Triggered()
  3583.     {
  3584.         var min, max : SAbilityAttributeValue;
  3585.         var healValue : float;
  3586.         var quenEntity : W3QuenEntity;
  3587.        
  3588.        
  3589.         if( IsSwimming() || IsDiving() || IsSailing() || IsUsingHorse() || IsUsingBoat() || IsUsingVehicle() || IsUsingExploration() )
  3590.         {
  3591.            
  3592.             ForceSetStat( BCS_Vitality, GetStatMax( BCS_Vitality ) );
  3593.            
  3594.            
  3595.             theGame.MutationHUDFeedback( MFT_PlayOnce );
  3596.            
  3597.            
  3598.             GCameraShake( 1.0f, , , , true, 'camera_shake_loop_lvl1_1' );
  3599.             AddTimer( 'StopMutation11CamShake', 2.f );
  3600.            
  3601.            
  3602.             theGame.VibrateControllerVeryHard( 2.f );
  3603.            
  3604.            
  3605.             Mutation11ShockWave( true );
  3606.            
  3607.            
  3608.             AddEffectDefault( EET_Mutation11Debuff, NULL, "Mutation 11 Debuff", false );
  3609.         }
  3610.         else
  3611.         {
  3612.             AddEffectDefault( EET_Mutation11Buff, this, "Mutation 11", false );
  3613.         }
  3614.     }
  3615.    
  3616.     timer function StopMutation11CamShake( dt : float, id : int )
  3617.     {
  3618.         theGame.GetGameCamera().StopAnimation( 'camera_shake_loop_lvl1_1' );
  3619.     }
  3620.    
  3621.     private var mutation12IsOnCooldown : bool;
  3622.    
  3623.     public final function AddMutation12Decoction()
  3624.     {
  3625.         var params : SCustomEffectParams;
  3626.         var buffs : array< EEffectType >;
  3627.         var existingDecoctionBuffs : array<CBaseGameplayEffect>;
  3628.         var i : int;
  3629.         var effectType : EEffectType;
  3630.         var decoctions : array< SItemUniqueId >;
  3631.         var tmpName : name;
  3632.         var min, max : SAbilityAttributeValue;
  3633.         var attValue            : SAbilityAttributeValue;
  3634.         var statValue           : SAbilityAttributeValue;
  3635.  
  3636.  
  3637.        
  3638.         if( mutation12IsOnCooldown )
  3639.         {
  3640.             return;
  3641.         }
  3642.        
  3643.        
  3644.         existingDecoctionBuffs = GetDrunkMutagens( "Mutation12" );
  3645.         theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation12', 'maxcap', min, max );
  3646.         if( existingDecoctionBuffs.Size() >= min.valueAdditive )
  3647.         {
  3648.             return;
  3649.         }
  3650.        
  3651.        
  3652.         mutation12IsOnCooldown = true;     
  3653.         theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation12', 'cooldown', min, max );
  3654.         AddTimer( 'Mutation12Cooldown', CalculateAttributeValue( min ) );
  3655.        
  3656.        
  3657.         decoctions = inv.GetItemsByTag( 'Mutagen' );
  3658.        
  3659.        
  3660.         for( i=decoctions.Size()-1; i>=0; i-=1 )
  3661.         {
  3662.             inv.GetPotionItemBuffData( decoctions[i], effectType, tmpName );
  3663.             if( HasBuff( effectType ) )
  3664.             {
  3665.                  //
  3666.                 attValue = GetAttributeValue( 'mutation10_stat_boost' ) ;
  3667.                 statValue.valueMultiplicative += 10;
  3668.                  //
  3669.                 decoctions.EraseFast( i );
  3670.                 continue;
  3671.             }
  3672.             buffs.PushBack( effectType );
  3673.         }
  3674.        
  3675.        
  3676.         if( buffs.Size() == 0 )
  3677.         {
  3678.             for( i=EET_Mutagen01; i<=EET_Mutagen28; i+=1 )
  3679.             {
  3680.                 if( !HasBuff( i ) )
  3681.                 {
  3682.                     buffs.PushBack( i );
  3683.                 }
  3684.             }
  3685.         }
  3686.        
  3687.        
  3688.         buffs.Remove( EET_Mutagen16 );
  3689.         buffs.Remove( EET_Mutagen24 );
  3690.        
  3691.        
  3692.         if( buffs.Size() == 0 )
  3693.         {
  3694.             return;
  3695.         }
  3696.        
  3697.        
  3698.         theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation12', 'duration', min, max );
  3699.         params.effectType = buffs[ RandRange( buffs.Size() ) ];
  3700.         params.creator = this;
  3701.         params.sourceName = "Mutation12";
  3702.         params.duration = min.valueAdditive;
  3703.         AddEffectCustom( params );
  3704.         ( ( W3Mutagen_Effect ) GetBuff( params.effectType, params.sourceName ) ).OverrideIcon( DecoctionEffectTypeToItemName( params.effectType ) );
  3705.        
  3706.        
  3707.         if ( !IsEffectActive( 'invisible' ) )
  3708.         {
  3709.             PlayEffect( 'use_potion' );
  3710.         }
  3711.        
  3712.         theGame.MutationHUDFeedback( MFT_PlayOnce );
  3713.     }
  3714.    
  3715.     timer function Mutation12Cooldown( dt : float, id : int )
  3716.     {
  3717.         mutation12IsOnCooldown = false;
  3718.     }
  3719.    
  3720.    
  3721.     public final function HasResourcesToStartAnyMutationResearch() : bool
  3722.     {
  3723.         var greenPoints, redPoints, bluePoints, count : int;
  3724.         var itemIDs : array< SItemUniqueId >;
  3725.        
  3726.         if( levelManager.GetPointsFree( ESkillPoint ) > 0 )
  3727.         {
  3728.             return true;
  3729.         }
  3730.        
  3731.        
  3732.         count = inv.GetItemQuantityByName( 'Greater mutagen green' );
  3733.         if( count > 0 )
  3734.         {
  3735.             itemIDs = inv.GetItemsByName( 'Greater mutagen green' );
  3736.             greenPoints = inv.GetMutationResearchPoints( SC_Green, itemIDs[0] );
  3737.             if( greenPoints > 0 )
  3738.             {
  3739.                 return true;
  3740.             }
  3741.         }  
  3742.         count = inv.GetItemQuantityByName( 'Greater mutagen red' );
  3743.         if( count > 0 )
  3744.         {
  3745.             itemIDs.Clear();
  3746.             itemIDs = inv.GetItemsByName( 'Greater mutagen red' );
  3747.             redPoints = inv.GetMutationResearchPoints( SC_Red, itemIDs[0] );
  3748.             if( redPoints > 0 )
  3749.             {
  3750.                 return true;
  3751.             }
  3752.         }      
  3753.         count = inv.GetItemQuantityByName( 'Greater mutagen blue' );
  3754.         if( count > 0 )
  3755.         {
  3756.             itemIDs.Clear();
  3757.             itemIDs = inv.GetItemsByName( 'Greater mutagen blue' );
  3758.             bluePoints = inv.GetMutationResearchPoints( SC_Blue, itemIDs[0] );
  3759.             if( bluePoints > 0 )
  3760.             {
  3761.                 return true;
  3762.             }
  3763.         }      
  3764.        
  3765.         return false;
  3766.     }
  3767.    
  3768.    
  3769.     public final function Mutation11StartAnimation()
  3770.     {
  3771.        
  3772.         thePlayer.ActionPlaySlotAnimationAsync( 'PLAYER_SLOT', 'geralt_mutation_11', 0.2, 0.2 );
  3773.        
  3774.        
  3775.         BlockAllActions( 'Mutation11', true );
  3776.        
  3777.        
  3778.         loopingCameraShakeAnimName = 'camera_shake_loop_lvl1_1';
  3779.         GCameraShake( 1.0f, , , , true, loopingCameraShakeAnimName );
  3780.        
  3781.        
  3782.         theGame.VibrateControllerVeryHard( 15.f );
  3783.        
  3784.        
  3785.         storedInteractionPriority = GetInteractionPriority();
  3786.         SetInteractionPriority( IP_Max_Unpushable );
  3787.     }
  3788.    
  3789.     event OnAnimEvent_Mutation11ShockWave( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3790.     {
  3791.         Mutation11ShockWave( false );
  3792.     }
  3793.    
  3794.     private final function Mutation11ShockWave( skipQuenSign : bool )
  3795.     {
  3796.         var action : W3DamageAction;
  3797.         var ents : array< CGameplayEntity >;
  3798.         var i, j : int;
  3799.         var damages : array< SRawDamage >;
  3800.         var min, max            : SAbilityAttributeValue;  
  3801.         var mutationAction : W3DamageAction;
  3802.         var dmgVal : float;
  3803.         var instaKill, hasKnockdown, applySlowdown : bool;
  3804.         var signPower, channelDmg : SAbilityAttributeValue;
  3805.         var focus, stamina : float;
  3806.         var focusDrain : float;
  3807.         var focusGain : float;
  3808.         var projectileVictim : CProjectileTrajectory;
  3809.         var maxHealth : float;
  3810.         var victimHealthPercBeforeHit, frozenAdditionalDamage : float;     
  3811.         var victim : CNewNPC;
  3812.         var actorVictim                 : CActor;                  
  3813.  
  3814.         FindGameplayEntitiesInSphere(ents, GetWorldPosition(), 5.f, 1000, '', FLAG_OnlyAliveActors + FLAG_ExcludeTarget + FLAG_Attitude_Hostile + FLAG_Attitude_Neutral, this);
  3815.         thePlayer.GainStat(BCS_Focus, 3.0f);
  3816.  
  3817.         if( ents.Size() > 0 )
  3818.         {
  3819.             damages = theGame.GetDefinitionsManager().GetDamagesFromAbility( 'Mutation11' );
  3820.             theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation11', 'ForceDamage', min, max );
  3821.  
  3822.         }
  3823.        
  3824.        
  3825.         for(i=0; i<ents.Size(); i+=1)
  3826.         {
  3827.             action = new W3DamageAction in theGame;
  3828.             action.Initialize( this, ents[i], NULL, "Mutation11", EHRT_Heavy, CPS_SpellPower, false, false, true, false );
  3829.  
  3830.             for( j=0; j<damages.Size(); j+=1 )
  3831.             {
  3832.             action.AddDamage( theGame.params.DAMAGE_NAME_FORCE, dmgVal );
  3833.             action.AddEffectInfo( EET_KnockdownTypeApplicator );
  3834.  
  3835.             }
  3836.  
  3837.           //  theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation11', 'ForceDamage', min, max );
  3838.             maxHealth = actorVictim.GetMaxHealth();
  3839.          // dmgVal = 50.0f * CalculateAttributeValue( min ) + 1000.0f * maxHealth + 100.0f * GetWitcherPlayer().GetLevel());
  3840.             dmgVal = 100.0f *  CalculateAttributeValue( min ) +  1 * GetMaxHealth() + 10.0f * GetWitcherPlayer().GetLevel();
  3841.             action.AddDamage( theGame.params.DAMAGE_NAME_FORCE, dmgVal );
  3842.             //action.AddDamage( theGame.params.DAMAGE_NAME_FORCE, dmgVal );
  3843.             action.AddEffectInfo( EET_KnockdownTypeApplicator );
  3844.             action.SetCannotReturnDamage( false );
  3845.             action.SetProcessBuffsIfNoDamage( true );
  3846.             action.SetHitAnimationPlayType( EAHA_ForceYes );
  3847.             action.SetCanPlayHitParticle( true );
  3848.            
  3849.             theGame.damageMgr.ProcessAction( action );
  3850.             delete action;
  3851.         }
  3852.        
  3853.        
  3854.        
  3855.        
  3856.        
  3857.         mutation11QuenEntity = ( W3QuenEntity )GetSignEntity( ST_Quen );
  3858.         if( !mutation11QuenEntity )
  3859.         {
  3860.             mutation11QuenEntity = (W3QuenEntity)theGame.CreateEntity( GetSignTemplate( ST_Quen ), GetWorldPosition(), GetWorldRotation() );
  3861.             mutation11QuenEntity.CreateAttachment( this, 'quen_sphere' );
  3862.             AddTimer( 'DestroyMutation11QuenEntity', 2.f );
  3863.         }
  3864.         mutation11QuenEntity.PlayHitEffect( 'quen_impulse_explode', mutation11QuenEntity.GetWorldRotation() );
  3865.        
  3866.         if( !skipQuenSign )
  3867.         {
  3868.            
  3869.             PlayEffect( 'mutation_11_second_life' );
  3870.            
  3871.            
  3872.             RestoreQuen( 1000000.f, 10.f, true );
  3873.         }
  3874.     }
  3875.    
  3876.     private var mutation11QuenEntity : W3QuenEntity;
  3877.     private var storedInteractionPriority : EInteractionPriority;
  3878.    
  3879.     timer function DestroyMutation11QuenEntity( dt : float, id : int )
  3880.     {
  3881.         if( mutation11QuenEntity )
  3882.         {
  3883.             mutation11QuenEntity.Destroy();
  3884.             thePlayer.GainStat(BCS_Stamina, thePlayer.GetStatMax(BCS_Stamina));
  3885.        
  3886.         }
  3887.  
  3888.     }
  3889.    
  3890.     event OnAnimEvent_Mutation11AnimEnd( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3891.     {
  3892.           thePlayer.GainStat(BCS_Stamina, thePlayer.GetStatMax(BCS_Stamina));
  3893.  
  3894.         if( animEventType == AET_DurationEnd )
  3895.         {
  3896.            
  3897.             BlockAllActions( 'Mutation11', false );        
  3898.        
  3899.  
  3900.             theGame.GetGameCamera().StopAnimation( 'camera_shake_loop_lvl1_1' );
  3901.            
  3902.            
  3903.             theGame.StopVibrateController();
  3904.            
  3905.            
  3906.             SetInteractionPriority( storedInteractionPriority );
  3907.            
  3908.             RemoveBuff( EET_Mutation11Buff, true );
  3909.         }
  3910.         else if ( animEventType == AET_DurationStart || animEventType == AET_DurationStartInTheMiddle )
  3911.         {
  3912.            
  3913.             SetBehaviorVariable( 'AIControlled', 0.f );
  3914.         }
  3915.     }
  3916.        
  3917.     public final function MutationSystemEnable( enable : bool )
  3918.     {
  3919.    
  3920.    
  3921.  
  3922.         ( ( W3PlayerAbilityManager ) abilityManager ).MutationSystemEnable( enable );
  3923.     }
  3924.    
  3925.     public final function IsMutationSystemEnabled() : bool
  3926.     {
  3927.         return ( ( W3PlayerAbilityManager ) abilityManager ).IsMutationSystemEnabled();
  3928.     }
  3929.    
  3930.     public final function GetMutation( mutationType : EPlayerMutationType ) : SMutation
  3931.     {
  3932.         return ( ( W3PlayerAbilityManager ) abilityManager ).GetMutation( mutationType );
  3933.     }
  3934.    
  3935.     public final function IsMutationActive( mutationType : EPlayerMutationType) : bool
  3936.     {
  3937.         var swordQuality : int;
  3938.         var sword : SItemUniqueId;
  3939.        
  3940.         if( GetEquippedMutationType() != mutationType )
  3941.         {
  3942.             return false;
  3943.         }
  3944.        
  3945.         switch( mutationType )
  3946.         {
  3947.             case EPMT_Mutation4 :
  3948.             case EPMT_Mutation5 :
  3949.             case EPMT_Mutation7 :
  3950.             case EPMT_Mutation8 :
  3951.             case EPMT_Mutation10 :
  3952.             case EPMT_Mutation11 :
  3953.             case EPMT_Mutation12 :
  3954.                 if( IsInFistFight() )
  3955.                 {
  3956.                     return false;
  3957.                 }
  3958.         }
  3959.        
  3960.         if( mutationType == EPMT_Mutation1 )
  3961.         {
  3962.             sword = inv.GetCurrentlyHeldSword();           
  3963.             swordQuality = inv.GetItemQuality( sword );
  3964.            
  3965.            
  3966.             if( swordQuality < 3 )
  3967.             {
  3968.                 return false;
  3969.             }
  3970.         }
  3971.        
  3972.         return true;
  3973.     }
  3974.        
  3975.     public final function SetEquippedMutation( mutationType : EPlayerMutationType ) : bool
  3976.     {
  3977.         return ( ( W3PlayerAbilityManager ) abilityManager ).SetEquippedMutation( mutationType );
  3978.     }
  3979.    
  3980.     public final function GetEquippedMutationType() : EPlayerMutationType
  3981.     {
  3982.         return ( ( W3PlayerAbilityManager ) abilityManager ).GetEquippedMutationType();
  3983.     }
  3984.    
  3985.     public final function CanEquipMutation(mutationType : EPlayerMutationType) : bool
  3986.     {
  3987.         return ( ( W3PlayerAbilityManager ) abilityManager ).CanEquipMutation( mutationType );
  3988.     }
  3989.    
  3990.     public final function CanResearchMutation( mutationType : EPlayerMutationType ) : bool
  3991.     {
  3992.         return ( ( W3PlayerAbilityManager ) abilityManager ).CanResearchMutation( mutationType );
  3993.     }
  3994.    
  3995.     public final function IsMutationResearched(mutationType : EPlayerMutationType) : bool
  3996.     {
  3997.         return ( ( W3PlayerAbilityManager ) abilityManager ).IsMutationResearched( mutationType );
  3998.     }
  3999.    
  4000.     public final function GetMutationResearchProgress(mutationType : EPlayerMutationType) : int
  4001.     {
  4002.         return ( ( W3PlayerAbilityManager ) abilityManager ).GetMutationResearchProgress( mutationType );
  4003.     }
  4004.    
  4005.     public final function GetMasterMutationStage() : int
  4006.     {
  4007.         return ( ( W3PlayerAbilityManager ) abilityManager ).GetMasterMutationStage();
  4008.     }
  4009.    
  4010.     public final function MutationResearchWithSkillPoints(mutation : EPlayerMutationType, skillPoints : int) : bool
  4011.     {
  4012.         return ( ( W3PlayerAbilityManager ) abilityManager ).MutationResearchWithSkillPoints( mutation, skillPoints );
  4013.     }
  4014.    
  4015.     public final function MutationResearchWithItem(mutation : EPlayerMutationType, item : SItemUniqueId, optional count: int) : bool
  4016.     {
  4017.         return ( ( W3PlayerAbilityManager ) abilityManager ).MutationResearchWithItem( mutation, item, count );
  4018.     }
  4019.    
  4020.     public final function GetMutationLocalizedName( mutationType : EPlayerMutationType ) : string
  4021.     {
  4022.         var pam : W3PlayerAbilityManager;
  4023.         var locKey : name;
  4024.    
  4025.         pam = (W3PlayerAbilityManager)GetWitcherPlayer().abilityManager;
  4026.         locKey = pam.GetMutationNameLocalizationKey( mutationType );
  4027.        
  4028.         return GetLocStringByKeyExt( locKey );
  4029.     }
  4030.    
  4031.     public final function GetMutationLocalizedDescription( mutationType : EPlayerMutationType ) : string
  4032.     {
  4033.         var pam : W3PlayerAbilityManager;
  4034.         var locKey : name;
  4035.         var arrStr : array< string >;
  4036.         var dm : CDefinitionsManagerAccessor;
  4037.         var min, max, sp : SAbilityAttributeValue;
  4038.         var tmp, tmp2, tox, critBonusDamage, val : float;
  4039.         var stats, stats2 : SPlayerOffenseStats;
  4040.         var buffPerc, exampleEnemyCount, debuffPerc : int;
  4041.    
  4042.         pam = (W3PlayerAbilityManager)GetWitcherPlayer().abilityManager;
  4043.         locKey = pam.GetMutationDescriptionLocalizationKey( mutationType );
  4044.         dm = theGame.GetDefinitionsManager();
  4045.        
  4046.         switch( mutationType )
  4047.         {
  4048.             case EPMT_Mutation1 :
  4049.                 dm.GetAbilityAttributeValue('Mutation1', 'dmg_bonus_factor', min, max);                        
  4050.                 arrStr.PushBack( NoTrailZeros( RoundMath( 100 * min.valueAdditive ) ) );
  4051.                 break;
  4052.                
  4053.             case EPMT_Mutation2 :
  4054.                 sp = GetPowerStatValue( CPS_SpellPower );
  4055.                
  4056.                
  4057.                 dm.GetAbilityAttributeValue( 'Mutation2', 'crit_chance_factor', min, max );
  4058.                 arrStr.PushBack( NoTrailZeros( RoundMath( 100 * ( min.valueAdditive + sp.valueMultiplicative * min.valueMultiplicative ) ) ) );
  4059.                
  4060.                
  4061.                 dm.GetAbilityAttributeValue( 'Mutation2', 'crit_damage_factor', min, max );
  4062.                 critBonusDamage = sp.valueMultiplicative * min.valueMultiplicative;
  4063.                
  4064.                 arrStr.PushBack( NoTrailZeros( RoundMath( 300 * critBonusDamage ) ) );
  4065.                 break;
  4066.                
  4067.             case EPMT_Mutation3 :
  4068.                
  4069.                 dm.GetAbilityAttributeValue( 'Mutation3', 'attack_power', min, max );
  4070.                 tmp = min.valueMultiplicative;
  4071.                 arrStr.PushBack( NoTrailZeros( RoundMath( 100 * tmp ) ) );
  4072.                
  4073.                
  4074.                 dm.GetAbilityAttributeValue( 'Mutation3', 'maxcap', min, max );
  4075.                 arrStr.PushBack( NoTrailZeros( RoundMath( 100 * tmp * min.valueAdditive ) ) );
  4076.                 break;
  4077.                
  4078.             case EPMT_Mutation4 :
  4079.                
  4080.                 dm.GetAbilityAttributeValue( 'AcidEffect', 'DirectDamage', min, max );
  4081.                 tmp2 = 100 * min.valueAdditive;
  4082.                 dm.GetAbilityAttributeValue( 'AcidEffect', 'duration', min, max );
  4083.                 tmp2 *= min.valueAdditive;
  4084.                 arrStr.PushBack( NoTrailZeros( tmp2 ) );
  4085.                
  4086.                
  4087.                 tox = GetStat( BCS_Toxicity );
  4088.                 if( tox > 0 )
  4089.                 {
  4090.                     tmp = RoundMath( tmp2 * tox );
  4091.                 }
  4092.                 else
  4093.                 {
  4094.                     tmp = tmp2;
  4095.                 }
  4096.                 arrStr.PushBack( NoTrailZeros( tmp ) );
  4097.                
  4098.                
  4099.                 tox = GetStatMax( BCS_Toxicity );
  4100.                 tmp = RoundMath( tmp2 * tox );
  4101.                 arrStr.PushBack( NoTrailZeros( tmp ) );
  4102.                 break;
  4103.                
  4104.             case EPMT_Mutation5 :
  4105.                
  4106.                 dm.GetAbilityAttributeValue( 'Mutation5', 'mut5_dmg_red_perc', min, max );
  4107.                 tmp = min.valueAdditive;
  4108.                 arrStr.PushBack( NoTrailZeros( 100 * tmp ) );
  4109.                
  4110.                
  4111.                 arrStr.PushBack( NoTrailZeros( 100 * tmp * 3 ) );
  4112.                
  4113.                 break;
  4114.            
  4115.             case EPMT_Mutation6 :  
  4116.                
  4117.                 theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation6', 'full_freeze_chance', min, max );
  4118.                 arrStr.PushBack( NoTrailZeros( 100 * min.valueMultiplicative ) );  
  4119.                
  4120.                
  4121.                 theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation6', 'ForceDamage', min, max );
  4122.                 sp = GetTotalSignSpellPower( S_Magic_1 );
  4123.                 val = sp.valueAdditive + 0.68f *  sp.valueMultiplicative * ( sp.valueBase + min.valueAdditive + 2.0f * GetLevel());
  4124.                 arrStr.PushBack( NoTrailZeros( RoundMath( val ) ) );   
  4125.            
  4126.                 break;
  4127.                
  4128.             case EPMT_Mutation7 :
  4129.                
  4130.                 dm.GetAbilityAttributeValue( 'Mutation7Buff', 'attack_power', min, max );
  4131.                 buffPerc = (int) ( 100 * min.valueMultiplicative );
  4132.                 arrStr.PushBack( NoTrailZeros( buffPerc ) );
  4133.                
  4134.                
  4135.                 dm.GetAbilityAttributeValue( 'Mutation7BuffEffect', 'duration', min, max );
  4136.                 arrStr.PushBack( NoTrailZeros( min.valueAdditive ) );
  4137.                
  4138.                
  4139.                 exampleEnemyCount = 9;
  4140.                 arrStr.PushBack( exampleEnemyCount );
  4141.                
  4142.                
  4143.                 arrStr.PushBack( buffPerc * ( exampleEnemyCount -1 ) );
  4144.                
  4145.                
  4146.                 dm.GetAbilityAttributeValue( 'Mutation7Debuff', 'attack_power', min, max );
  4147.                 debuffPerc = (int) ( - 100 * min.valueMultiplicative );
  4148.                 arrStr.PushBack( NoTrailZeros( debuffPerc ) );
  4149.                
  4150.                
  4151.                 theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation7Debuff', 'minCapStacks', min, max );
  4152.                 arrStr.PushBack( NoTrailZeros( debuffPerc * min.valueAdditive ) );
  4153.                
  4154.                
  4155.                 dm.GetAbilityAttributeValue( 'Mutation7DebuffEffect', 'duration', min, max );
  4156.                 arrStr.PushBack( NoTrailZeros( min.valueAdditive ) );
  4157.                    
  4158.                 break;
  4159.            
  4160.             case EPMT_Mutation8 :
  4161.                
  4162.                 dm.GetAbilityAttributeValue( 'Mutation8', 'dmg_bonus', min, max );
  4163.                 arrStr.PushBack( NoTrailZeros( 100 * min.valueMultiplicative ) );
  4164.                
  4165.                
  4166.                 dm.GetAbilityAttributeValue( 'Mutation8', 'hp_perc_trigger', min, max );
  4167.                 arrStr.PushBack( NoTrailZeros( 100 * min.valueMultiplicative ) );
  4168.                
  4169.                 break;
  4170.                
  4171.             case EPMT_Mutation9 :
  4172.                
  4173.                
  4174.                
  4175.                
  4176.                 stats = GetOffenseStatsList( 1 );
  4177.                 arrStr.PushBack( NoTrailZeros( RoundMath( stats.crossbowSteelDmg ) ) );
  4178.                
  4179.                
  4180.                 stats2 = GetOffenseStatsList( 2 );
  4181.                 arrStr.PushBack( NoTrailZeros( RoundMath( stats2.crossbowSteelDmg ) ) );
  4182.                
  4183.                
  4184.                 dm.GetAbilityAttributeValue( 'Mutation9', 'critical_hit_chance', min, max );
  4185.                 arrStr.PushBack( NoTrailZeros( 100 * min.valueMultiplicative ) );
  4186.                
  4187.                
  4188.                 dm.GetAbilityAttributeValue( 'Mutation9', 'health_reduction', min, max );
  4189.                 arrStr.PushBack( NoTrailZeros( 100 * min.valueMultiplicative ) );
  4190.                
  4191.                 break;
  4192.                
  4193.             case EPMT_Mutation10 :
  4194.                
  4195.                 dm.GetAbilityAttributeValue( 'Mutation10Effect', 'mutation10_stat_boost', min, max );
  4196.                 arrStr.PushBack( NoTrailZeros( 100 * min.valueMultiplicative ) );
  4197.                
  4198.                
  4199.                 arrStr.PushBack( NoTrailZeros( 100 * min.valueMultiplicative * GetStatMax( BCS_Toxicity ) ) );
  4200.                
  4201.                 break;
  4202.                
  4203.             case EPMT_Mutation11 :
  4204.                
  4205.                 arrStr.PushBack( 100 );
  4206.                
  4207.                
  4208.                 dm.GetAbilityAttributeValue( 'Mutation11DebuffEffect', 'duration', min, max);
  4209.                 arrStr.PushBack( NoTrailZeros( min.valueAdditive ) );
  4210.                 break;
  4211.                
  4212.             case EPMT_Mutation12 :
  4213.                
  4214.                 dm.GetAbilityAttributeValue( 'Mutation12', 'duration', min, max );
  4215.                 arrStr.PushBack( NoTrailZeros( min.valueAdditive ) );              
  4216.                
  4217.                
  4218.                 dm.GetAbilityAttributeValue( 'Mutation12', 'maxcap', min, max );
  4219.                 arrStr.PushBack( NoTrailZeros( min.valueAdditive ) );  
  4220.                 break;
  4221.                
  4222.             case EPMT_MutationMaster :
  4223.                
  4224.                 arrStr.PushBack( "4" );
  4225.                
  4226.                 break;
  4227.         }
  4228.        
  4229.         return GetLocStringByKeyExtWithParams( locKey, , , arrStr );
  4230.     }
  4231.        
  4232.     public final function ApplyMutation10StatBoost( out statValue : SAbilityAttributeValue )
  4233.     {
  4234.         var attValue            : SAbilityAttributeValue;
  4235.         var currToxicity        : float;
  4236.        
  4237.         if( IsMutationActive( EPMT_Mutation10 ) )
  4238.         {
  4239.             currToxicity = GetStat( BCS_Toxicity );
  4240.             if( currToxicity > 0.f )
  4241.             {
  4242.                 attValue = GetAttributeValue( 'mutation10_stat_boost' ) ;
  4243.                 currToxicity *= attValue.valueMultiplicative;
  4244.                 statValue.valueMultiplicative += currToxicity;
  4245.             }
  4246.         }
  4247.     }
  4248.  
  4249.    
  4250.    
  4251.    
  4252.    
  4253.    
  4254.  
  4255.     public final function IsBookRead( bookName : name ):bool
  4256.     {
  4257.         return booksRead.Contains( bookName );
  4258.     }  
  4259.    
  4260.     public final function AddReadBook( bookName : name ):void
  4261.     {
  4262.         if( !booksRead.Contains( bookName ) )
  4263.         {
  4264.             booksRead.PushBack( bookName );
  4265.         }
  4266.     }
  4267.    
  4268.     public final function RemoveReadBook( bookName : name ):void
  4269.     {
  4270.         var idx : int = booksRead.FindFirst( bookName );
  4271.        
  4272.         if( idx > -1 )
  4273.         {
  4274.             booksRead.Erase( idx );
  4275.         }
  4276.     }
  4277.    
  4278.    
  4279.    
  4280.    
  4281.    
  4282.    
  4283.    
  4284.     public final function GetMutagenBuffs() : array< W3Mutagen_Effect >
  4285.     {
  4286.         var null : array< W3Mutagen_Effect >;
  4287.        
  4288.         if(effectManager)
  4289.         {
  4290.             return effectManager.GetMutagenBuffs();
  4291.         }
  4292.    
  4293.         return null;
  4294.     }
  4295.    
  4296.     public function GetAlchemyRecipes() : array<name>
  4297.     {
  4298.         return alchemyRecipes;
  4299.     }
  4300.        
  4301.     public function CanLearnAlchemyRecipe(recipeName : name) : bool
  4302.     {
  4303.         var dm : CDefinitionsManagerAccessor;
  4304.         var recipeNode : SCustomNode;
  4305.         var i, tmpInt : int;
  4306.         var tmpName : name;
  4307.    
  4308.         dm = theGame.GetDefinitionsManager();
  4309.         if ( dm.GetSubNodeByAttributeValueAsCName( recipeNode, 'alchemy_recipes', 'name_name', recipeName ) )
  4310.         {
  4311.             return true;
  4312.            
  4313.         }
  4314.        
  4315.         return false;
  4316.     }
  4317.    
  4318.     private final function RemoveAlchemyRecipe(recipeName : name)
  4319.     {
  4320.         alchemyRecipes.Remove(recipeName);
  4321.     }
  4322.    
  4323.     private final function RemoveAllAlchemyRecipes()
  4324.     {
  4325.         alchemyRecipes.Clear();
  4326.     }
  4327.  
  4328.    
  4329.     function AddAlchemyRecipe(nam : name, optional isSilent : bool, optional skipTutorialUpdate : bool) : bool
  4330.     {
  4331.         var i, potions, bombs : int;
  4332.         var found : bool;
  4333.         var m_alchemyManager : W3AlchemyManager;
  4334.         var recipe : SAlchemyRecipe;
  4335.         var knownBombTypes : array<string>;
  4336.         var strRecipeName, recipeNameWithoutLevel : string;
  4337.        
  4338.         if(!IsAlchemyRecipe(nam))
  4339.             return false;
  4340.        
  4341.         found = false;
  4342.         for(i=0; i<alchemyRecipes.Size(); i+=1)
  4343.         {
  4344.             if(alchemyRecipes[i] == nam)
  4345.                 return false;
  4346.            
  4347.            
  4348.             if(StrCmp(alchemyRecipes[i],nam) > 0)
  4349.             {
  4350.                 alchemyRecipes.Insert(i,nam);
  4351.                 found = true;
  4352.                 AddAlchemyHudNotification(nam,isSilent);
  4353.                 break;
  4354.             }          
  4355.         }  
  4356.  
  4357.         if(!found)
  4358.         {
  4359.             alchemyRecipes.PushBack(nam);
  4360.             AddAlchemyHudNotification(nam,isSilent);
  4361.         }
  4362.        
  4363.         m_alchemyManager = new W3AlchemyManager in this;
  4364.         m_alchemyManager.Init(alchemyRecipes);
  4365.         m_alchemyManager.GetRecipe(nam, recipe);
  4366.            
  4367.        
  4368.         if(CanUseSkill(S_Alchemy_s18))
  4369.         {
  4370.             if ((recipe.cookedItemType != EACIT_Bolt) && (recipe.cookedItemType != EACIT_Undefined) && (recipe.cookedItemType != EACIT_Dye) && (recipe.level <= GetSkillLevel(S_Alchemy_s18)))
  4371.                 AddAbility(SkillEnumToName(S_Alchemy_s18), true);
  4372.            
  4373.         }
  4374.        
  4375.        
  4376.         if(recipe.cookedItemType == EACIT_Bomb)
  4377.         {
  4378.             bombs = 0;
  4379.             for(i=0; i<alchemyRecipes.Size(); i+=1)
  4380.             {
  4381.                 m_alchemyManager.GetRecipe(alchemyRecipes[i], recipe);
  4382.                
  4383.                
  4384.                 if(recipe.cookedItemType == EACIT_Bomb)
  4385.                 {
  4386.                     strRecipeName = NameToString(alchemyRecipes[i]);
  4387.                     recipeNameWithoutLevel = StrLeft(strRecipeName, StrLen(strRecipeName)-2);
  4388.                     if(!knownBombTypes.Contains(recipeNameWithoutLevel))
  4389.                     {
  4390.                         bombs += 1;
  4391.                         knownBombTypes.PushBack(recipeNameWithoutLevel);
  4392.                     }
  4393.                 }
  4394.             }
  4395.            
  4396.             theGame.GetGamerProfile().SetStat(ES_KnownBombRecipes, bombs);
  4397.         }      
  4398.        
  4399.         else if(recipe.cookedItemType == EACIT_Potion || recipe.cookedItemType == EACIT_MutagenPotion || recipe.cookedItemType == EACIT_Alcohol || recipe.cookedItemType == EACIT_Quest)
  4400.         {
  4401.             potions = 0;
  4402.             for(i=0; i<alchemyRecipes.Size(); i+=1)
  4403.             {
  4404.                 m_alchemyManager.GetRecipe(alchemyRecipes[i], recipe);
  4405.                
  4406.                
  4407.                 if(recipe.cookedItemType == EACIT_Potion || recipe.cookedItemType == EACIT_MutagenPotion || recipe.cookedItemType == EACIT_Alcohol || recipe.cookedItemType == EACIT_Quest)
  4408.                 {
  4409.                     potions += 1;
  4410.                 }              
  4411.             }      
  4412.             theGame.GetGamerProfile().SetStat(ES_KnownPotionRecipes, potions);
  4413.         }
  4414.        
  4415.         theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_AlchemyRecipe );
  4416.                
  4417.         return true;
  4418.     }
  4419.    
  4420.     public function GetExpandedAlchemyCategories() : array< name >
  4421.     {
  4422.         return expandedAlchemyCategories;
  4423.     }
  4424.    
  4425.     public function AddExpandedAlchemyCategory( category : name )
  4426.     {
  4427.         if ( IsNameValid( category ) )
  4428.         {
  4429.             ArrayOfNamesPushBackUnique( expandedAlchemyCategories, category );
  4430.         }
  4431.     }
  4432.  
  4433.     public function RemoveExpandedAlchemyCategory( category : name )
  4434.     {
  4435.         if ( IsNameValid( category ) )
  4436.         {
  4437.             expandedAlchemyCategories.Remove( category );
  4438.         }
  4439.     }
  4440.    
  4441.     public function SetAlchemyFilters(showHasIngre : bool, showMissingIngre : bool, showAlreadyCrafted : bool )
  4442.     {
  4443.         alchemyFilters.showCraftable = showHasIngre;
  4444.         alchemyFilters.showMissingIngre = showMissingIngre;
  4445.         alchemyFilters.showAlreadyCrafted = showAlreadyCrafted;
  4446.     }
  4447.    
  4448.     public function GetAlchemyFilters() : SCraftingFilters
  4449.     {
  4450.        
  4451.         if ( alchemyFilters.showCraftable == false && alchemyFilters.showMissingIngre == false && alchemyFilters.showAlreadyCrafted == false )
  4452.         {
  4453.             alchemyFilters.showCraftable = true;
  4454.             alchemyFilters.showMissingIngre = true;
  4455.             alchemyFilters.showAlreadyCrafted = false;
  4456.         }
  4457.  
  4458.         return alchemyFilters;
  4459.     }
  4460.    
  4461.    
  4462.    
  4463.    
  4464.    
  4465.    
  4466.  
  4467.     public function GetExpandedBestiaryCategories() : array< name >
  4468.     {
  4469.         return expandedBestiaryCategories;
  4470.     }
  4471.    
  4472.     public function AddExpandedBestiaryCategory( category : name )
  4473.     {
  4474.         if ( IsNameValid( category ) )
  4475.         {
  4476.             ArrayOfNamesPushBackUnique( expandedBestiaryCategories, category );
  4477.         }
  4478.     }
  4479.  
  4480.     public function RemoveExpandedBestiaryCategory( category : name )
  4481.     {
  4482.         if ( IsNameValid( category ) )
  4483.         {
  4484.             expandedBestiaryCategories.Remove( category );
  4485.         }
  4486.     }
  4487.    
  4488.    
  4489.    
  4490.    
  4491.    
  4492.    
  4493.    
  4494.     public function GetDisplayHeavyAttackIndicator() : bool
  4495.     {
  4496.         return bDispalyHeavyAttackIndicator;
  4497.     }
  4498.  
  4499.     public function SetDisplayHeavyAttackIndicator( val : bool )
  4500.     {
  4501.         bDispalyHeavyAttackIndicator = val;
  4502.     }
  4503.  
  4504.     public function GetDisplayHeavyAttackFirstLevelTimer() : bool
  4505.     {
  4506.         return bDisplayHeavyAttackFirstLevelTimer;
  4507.     }
  4508.  
  4509.     public function SetDisplayHeavyAttackFirstLevelTimer( val : bool )
  4510.     {
  4511.         bDisplayHeavyAttackFirstLevelTimer = val;
  4512.     }
  4513.    
  4514.    
  4515.    
  4516.    
  4517.    
  4518.    
  4519.  
  4520.     public function SelectQuickslotItem( slot : EEquipmentSlots )
  4521.     {
  4522.         var item : SItemUniqueId;
  4523.    
  4524.         GetItemEquippedOnSlot(slot, item);
  4525.         selectedItemId = item;         
  4526.     }  
  4527.    
  4528.    
  4529.    
  4530.    
  4531.    
  4532.    
  4533.    
  4534.     public function GetMedallion() : W3MedallionController
  4535.     {
  4536.         if ( !medallionController )
  4537.         {
  4538.             medallionController = new W3MedallionController in this;
  4539.         }
  4540.         return medallionController;
  4541.     }
  4542.    
  4543.    
  4544.     public final function HighlightObjects(range : float, optional highlightTime : float )
  4545.     {
  4546.         var ents : array<CGameplayEntity>;
  4547.         var i : int;
  4548.  
  4549.         FindGameplayEntitiesInSphere(ents, GetWorldPosition(), range, 100, 'HighlightedByMedalionFX', FLAG_ExcludePlayer);
  4550.  
  4551.         if(highlightTime == 0)
  4552.             highlightTime = 30;
  4553.        
  4554.         for(i=0; i<ents.Size(); i+=1)
  4555.         {
  4556.             if(!ents[i].IsHighlighted())
  4557.             {
  4558.                 ents[i].SetHighlighted( true );
  4559.                 ents[i].PlayEffectSingle( 'medalion_detection_fx' );
  4560.                 ents[i].AddTimer( 'MedallionEffectOff', highlightTime );
  4561.             }
  4562.         }
  4563.     }
  4564.    
  4565.    
  4566.     public final function HighlightEnemies(range : float, optional highlightTime : float )
  4567.     {
  4568.         var ents : array<CGameplayEntity>;
  4569.         var i : int;
  4570.         var catComponent : CGameplayEffectsComponent;
  4571.  
  4572.         FindGameplayEntitiesInSphere(ents, GetWorldPosition(), range, 100, , FLAG_ExcludePlayer + FLAG_OnlyAliveActors);
  4573.  
  4574.         if(highlightTime == 0)
  4575.             highlightTime = 5;
  4576.        
  4577.         for(i=0; i<ents.Size(); i+=1)
  4578.         {
  4579.             if(IsRequiredAttitudeBetween(this, ents[i], true))
  4580.             {
  4581.                 catComponent = GetGameplayEffectsComponent(ents[i]);
  4582.                 if(catComponent)
  4583.                 {
  4584.                     catComponent.SetGameplayEffectFlag(EGEF_CatViewHiglight, true);
  4585.                     ents[i].AddTimer( 'EnemyHighlightOff', highlightTime, , , , , true );
  4586.                 }
  4587.             }
  4588.         }
  4589.     }  
  4590.    
  4591.     function SpawnMedallionEntity()
  4592.     {
  4593.         var rot                 : EulerAngles;
  4594.         var spawnedMedallion    : CEntity;
  4595.                
  4596.         spawnedMedallion = theGame.GetEntityByTag( 'new_Witcher_medallion_FX' );
  4597.        
  4598.         if ( !spawnedMedallion )
  4599.             theGame.CreateEntity( medallionEntity, GetWorldPosition(), rot, true, false );
  4600.     }
  4601.    
  4602.    
  4603.    
  4604.    
  4605.    
  4606.    
  4607.    
  4608.    
  4609.    
  4610.     public final function InterruptCombatFocusMode()
  4611.     {
  4612.         if( this.GetCurrentStateName() == 'CombatFocusMode_SelectSpot' )
  4613.         {  
  4614.             SetCanPlayHitAnim( true );
  4615.             PopState();
  4616.         }
  4617.     }
  4618.    
  4619.     public final function IsInDarkPlace() : bool
  4620.     {
  4621.         var envs : array< string >;
  4622.        
  4623.         if( FactsQuerySum( "tut_in_dark_place" ) )
  4624.         {
  4625.             return true;
  4626.         }
  4627.        
  4628.         GetActiveAreaEnvironmentDefinitions( envs );
  4629.        
  4630.         if( envs.Contains( 'env_novigrad_cave' ) || envs.Contains( 'cave_catacombs' ) )
  4631.         {
  4632.             return true;
  4633.         }
  4634.        
  4635.         return false;
  4636.     }
  4637.    
  4638.    
  4639.    
  4640.    
  4641.    
  4642.     private saved var selectedPotionSlotUpper, selectedPotionSlotLower : EEquipmentSlots;
  4643.     private var potionDoubleTapTimerRunning, potionDoubleTapSlotIsUpper : bool;
  4644.         default selectedPotionSlotUpper = EES_Potion1;
  4645.         default selectedPotionSlotLower = EES_Potion2;
  4646.         default potionDoubleTapTimerRunning = false;
  4647.    
  4648.     public final function SetPotionDoubleTapRunning(b : bool, optional isUpperSlot : bool)
  4649.     {
  4650.         if(b)
  4651.         {
  4652.             AddTimer('PotionDoubleTap', 0.3);
  4653.         }
  4654.         else
  4655.         {
  4656.             RemoveTimer('PotionDoubleTap');
  4657.         }
  4658.        
  4659.         potionDoubleTapTimerRunning = b;
  4660.         potionDoubleTapSlotIsUpper = isUpperSlot;
  4661.     }
  4662.    
  4663.     public final function IsPotionDoubleTapRunning() : bool
  4664.     {
  4665.         return potionDoubleTapTimerRunning;
  4666.     }
  4667.    
  4668.     timer function PotionDoubleTap(dt : float, id : int)
  4669.     {
  4670.         potionDoubleTapTimerRunning = false;
  4671.         OnPotionDrinkInput(potionDoubleTapSlotIsUpper);
  4672.     }
  4673.    
  4674.     public final function OnPotionDrinkInput(fromUpperSlot : bool)
  4675.     {
  4676.         var slot : EEquipmentSlots;
  4677.        
  4678.         if(fromUpperSlot)
  4679.             slot = GetSelectedPotionSlotUpper();
  4680.         else
  4681.             slot = GetSelectedPotionSlotLower();
  4682.            
  4683.         DrinkPotionFromSlot(slot);
  4684.     }
  4685.    
  4686.     public final function OnPotionDrinkKeyboardsInput(slot : EEquipmentSlots)
  4687.     {
  4688.         DrinkPotionFromSlot(slot);
  4689.     }
  4690.    
  4691.     private function DrinkPotionFromSlot(slot : EEquipmentSlots):void
  4692.     {
  4693.         var item : SItemUniqueId;      
  4694.         var hud : CR4ScriptedHud;
  4695.         var module : CR4HudModuleItemInfo;
  4696.        
  4697.         GetItemEquippedOnSlot(slot, item);
  4698.         if(inv.ItemHasTag(item, 'Edibles'))
  4699.         {
  4700.             ConsumeItem( item );
  4701.         }
  4702.         else
  4703.         {          
  4704.             if (ToxicityLowEnoughToDrinkPotion(slot))
  4705.             {
  4706.                 DrinkPreparedPotion(slot);
  4707.             }
  4708.             else
  4709.             {
  4710.                 SendToxicityTooHighMessage();
  4711.             }
  4712.         }
  4713.        
  4714.         hud = (CR4ScriptedHud)theGame.GetHud();
  4715.         if ( hud )
  4716.         {
  4717.             module = (CR4HudModuleItemInfo)hud.GetHudModule("ItemInfoModule");
  4718.             if( module )
  4719.             {
  4720.                 module.ForceShowElement();
  4721.             }
  4722.         }
  4723.     }
  4724.    
  4725.     public function SendToxicityTooHighMessage(optional always : bool) // -= WMK:modQuickSlots =-
  4726.     {
  4727.         var messageText : string;
  4728.         var language : string;
  4729.         var audioLanguage : string;
  4730.        
  4731.         if ((GetHudMessagesSize() < 2) || always) // -= WMK:modQuickSlots =-
  4732.         {
  4733.             messageText = GetLocStringByKeyExt("menu_cannot_perform_action_now") + " " + GetLocStringByKeyExt("panel_common_statistics_tooltip_current_toxicity");
  4734.            
  4735.             theGame.GetGameLanguageName(audioLanguage,language);
  4736.             if (language == "AR")
  4737.             {
  4738.                 messageText += (int)(abilityManager.GetStat(BCS_Toxicity, false)) + " / " +  (int)(abilityManager.GetStatMax(BCS_Toxicity)) + " :";
  4739.             }
  4740.             else
  4741.             {
  4742.                 messageText += ": " + (int)(abilityManager.GetStat(BCS_Toxicity, false)) + " / " +  (int)(abilityManager.GetStatMax(BCS_Toxicity));
  4743.             }
  4744.            
  4745.             DisplayHudMessage(messageText);
  4746.         }
  4747.         theSound.SoundEvent("gui_global_denied");
  4748.     }
  4749.    
  4750.     public final function GetSelectedPotionSlotUpper() : EEquipmentSlots
  4751.     {
  4752.         return selectedPotionSlotUpper;
  4753.     }
  4754.    
  4755.     public final function GetSelectedPotionSlotLower() : EEquipmentSlots
  4756.     {
  4757.         return selectedPotionSlotLower;
  4758.     }
  4759.    
  4760.    
  4761.     public final function FlipSelectedPotion(isUpperSlot : bool) : bool
  4762.     {
  4763.         if(isUpperSlot)
  4764.         {
  4765.             if(selectedPotionSlotUpper == EES_Potion1 && IsAnyItemEquippedOnSlot(EES_Potion3))
  4766.             {
  4767.                 selectedPotionSlotUpper = EES_Potion3;
  4768.                 return true;
  4769.             }
  4770.             else if(selectedPotionSlotUpper == EES_Potion3 && IsAnyItemEquippedOnSlot(EES_Potion1))
  4771.             {
  4772.                 selectedPotionSlotUpper = EES_Potion1;
  4773.                 return true;
  4774.             }
  4775.         }
  4776.         else
  4777.         {
  4778.             if(selectedPotionSlotLower == EES_Potion2 && IsAnyItemEquippedOnSlot(EES_Potion4))
  4779.             {
  4780.                 selectedPotionSlotLower = EES_Potion4;
  4781.                 return true;
  4782.             }
  4783.             else if(selectedPotionSlotLower == EES_Potion4 && IsAnyItemEquippedOnSlot(EES_Potion2))
  4784.             {
  4785.                 selectedPotionSlotLower = EES_Potion2;
  4786.                 return true;
  4787.             }
  4788.         }
  4789.        
  4790.         return false;
  4791.     }
  4792.    
  4793.     public final function AddBombThrowDelay( bombId : SItemUniqueId )
  4794.     {
  4795.         var slot : EEquipmentSlots;
  4796.        
  4797.         slot = GetItemSlot( bombId );
  4798.        
  4799.         if( slot == EES_Unused )
  4800.         {
  4801.             return;
  4802.         }
  4803.            
  4804.         if( slot == EES_Petard1 || slot == EES_Quickslot1 || slot == EES_Petard3 ) // -= WMK:modQuickSlots =-
  4805.         {
  4806.             remainingBombThrowDelaySlot1 = theGame.params.BOMB_THROW_DELAY;
  4807.             AddTimer( 'BombDelay', 0.0f, true );
  4808.         }
  4809.         else if( slot == EES_Petard2 || slot == EES_Quickslot2 || slot == EES_Petard4 ) // -= WMK:modQuickSlots =-
  4810.         {
  4811.             remainingBombThrowDelaySlot2 = theGame.params.BOMB_THROW_DELAY;
  4812.             AddTimer( 'BombDelay', 0.0f, true );
  4813.         }
  4814.         else
  4815.         {
  4816.             return;
  4817.         }
  4818.     }
  4819.    
  4820.     public final function GetBombDelay( slot : EEquipmentSlots ) : float
  4821.     {
  4822.         if( slot == EES_Petard1 || slot == EES_Quickslot1 || slot == EES_Petard3 ) // -= WMK:modQuickSlots =-
  4823.         {
  4824.             return remainingBombThrowDelaySlot1;
  4825.         }
  4826.         else if( slot == EES_Petard2 || slot == EES_Quickslot2 || slot == EES_Petard4 ) // -= WMK:modQuickSlots =-
  4827.         {
  4828.             return remainingBombThrowDelaySlot2;
  4829.         }
  4830.        
  4831.         return 0;
  4832.     }
  4833.    
  4834.     timer function BombDelay( dt : float, id : int )
  4835.     {
  4836.         remainingBombThrowDelaySlot1 = MaxF( 0.f , remainingBombThrowDelaySlot1 - dt );
  4837.         remainingBombThrowDelaySlot2 = MaxF( 0.f , remainingBombThrowDelaySlot2 - dt );
  4838.        
  4839.         if( remainingBombThrowDelaySlot1 <= 0.0f && remainingBombThrowDelaySlot2  <= 0.0f )
  4840.         {
  4841.             RemoveTimer('BombDelay');
  4842.         }
  4843.     }
  4844.    
  4845.     public function ResetCharacterDev()
  4846.     {
  4847.        
  4848.         UnequipItemFromSlot(EES_SkillMutagen1);
  4849.         UnequipItemFromSlot(EES_SkillMutagen2);
  4850.         UnequipItemFromSlot(EES_SkillMutagen3);
  4851.         UnequipItemFromSlot(EES_SkillMutagen4);
  4852.        
  4853.         levelManager.ResetCharacterDev();
  4854.         ((W3PlayerAbilityManager)abilityManager).ResetCharacterDev();      
  4855.     }
  4856.    
  4857.     public final function ResetMutationsDev()
  4858.     {
  4859.         levelManager.ResetMutationsDev();
  4860.         ((W3PlayerAbilityManager)abilityManager).ResetMutationsDev();
  4861.     }
  4862.    
  4863.     public final function GetHeldSword() : SItemUniqueId
  4864.     {
  4865.         var i : int;
  4866.         var weapons : array< SItemUniqueId >;
  4867.        
  4868.         weapons = inv.GetHeldWeapons();
  4869.         for( i=0; i<weapons.Size(); i+=1 )
  4870.         {
  4871.             if( inv.IsItemSilverSwordUsableByPlayer( weapons[i] ) || inv.IsItemSteelSwordUsableByPlayer( weapons[i] ) )
  4872.             {
  4873.                 return weapons[i];
  4874.             }
  4875.         }
  4876.        
  4877.         return GetInvalidUniqueId();
  4878.     }
  4879.    
  4880.     public function ConsumeItem( itemId : SItemUniqueId ) : bool
  4881.     {
  4882.         var itemName : name;
  4883.         var removedItem, willRemoveItem : bool;
  4884.         var edibles : array<SItemUniqueId>;
  4885.         var toSlot : EEquipmentSlots;
  4886.         var i : int;
  4887.         var equippedNewEdible : bool;
  4888.        
  4889.         itemName = inv.GetItemName( itemId );
  4890.        
  4891.         if (itemName == 'q111_imlerith_acorn' )
  4892.         {
  4893.             AddPoints(ESkillPoint, 2, true);
  4894.             removedItem = inv.RemoveItem( itemId, 1 );
  4895.             theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt("panel_character_popup_title_buy_skill") + "<br>" + GetLocStringByKeyExt("panel_character_availablepoints") + " +2");
  4896.             theSound.SoundEvent("gui_character_buy_skill");
  4897.         }
  4898.         else if ( itemName == 'Clearing Potion' )
  4899.         {
  4900.             ResetCharacterDev();
  4901.             removedItem = inv.RemoveItem( itemId, 1 );
  4902.             theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt("panel_character_popup_character_cleared") );
  4903.             theSound.SoundEvent("gui_character_synergy_effect");
  4904.         }
  4905.         else if ( itemName == 'Restoring Potion' )
  4906.         {
  4907.             ResetMutationsDev();
  4908.             removedItem = inv.RemoveItem( itemId, 1 );
  4909.             theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt("panel_character_popup_character_cleared") );
  4910.             theSound.SoundEvent("gui_character_synergy_effect");
  4911.         }
  4912.         else if(itemName == 'Wolf Hour')
  4913.         {
  4914.             removedItem = inv.RemoveItem( itemId, 1 );
  4915.             theSound.SoundEvent("gui_character_synergy_effect");
  4916.             AddEffectDefault(EET_WolfHour, thePlayer, 'wolf hour');
  4917.         }
  4918.         else if ( itemName == 'q704_ft_golden_egg' )
  4919.         {
  4920.             AddPoints(ESkillPoint, 1, true);
  4921.             removedItem = inv.RemoveItem( itemId, 1 );
  4922.             theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt("panel_character_popup_title_buy_skill") + "<br>" + GetLocStringByKeyExt("panel_character_availablepoints") + " +1");
  4923.             theSound.SoundEvent("gui_character_buy_skill");
  4924.         }
  4925.         else if ( itemName == 'mq7023_cake' )
  4926.         {
  4927.             this.AddAbility('mq7023_cake_vitality_bonus');
  4928.             removedItem = inv.RemoveItem( itemId, 1 );
  4929.             theSound.SoundEvent("gui_character_synergy_effect");
  4930.         }
  4931.         else
  4932.         {
  4933.             willRemoveItem = inv.GetItemQuantity(itemId) == 1 && !inv.ItemHasTag(itemId, 'InfiniteUse');
  4934.            
  4935.             if(willRemoveItem)
  4936.                 toSlot = GetItemSlot(itemId);
  4937.                
  4938.             removedItem = super.ConsumeItem(itemId);
  4939.            
  4940.             if(willRemoveItem && removedItem)
  4941.             {
  4942.                 edibles = inv.GetItemsByTag('Edibles');
  4943.                 equippedNewEdible = false;
  4944.                
  4945.                
  4946.                 for(i=0; i<edibles.Size(); i+=1)
  4947.                 {
  4948.                     if(!IsItemEquipped(edibles[i]) && !inv.ItemHasTag(edibles[i], 'Alcohol') && inv.GetItemName(edibles[i]) != 'Clearing Potion' && inv.GetItemName(edibles[i]) != 'Wolf Hour')
  4949.                     {
  4950.                         EquipItemInGivenSlot(edibles[i], toSlot, true, false);
  4951.                         equippedNewEdible = true;
  4952.                         break;
  4953.                     }
  4954.                 }
  4955.                
  4956.                
  4957.                 if(!equippedNewEdible)
  4958.                 {
  4959.                     for(i=0; i<edibles.Size(); i+=1)
  4960.                     {
  4961.                         if(!IsItemEquipped(edibles[i]) && inv.GetItemName(edibles[i]) != 'Clearing Potion' && inv.GetItemName(edibles[i]) != 'Wolf Hour')
  4962.                         {
  4963.                             EquipItemInGivenSlot(edibles[i], toSlot, true, false);
  4964.                             break;
  4965.                         }
  4966.                     }
  4967.                 }
  4968.             }
  4969.         }
  4970.        
  4971.         return removedItem;
  4972.     }
  4973.    
  4974.    
  4975.     public final function GetAlcoholForAlchemicalItemsRefill() : SItemUniqueId
  4976.     {
  4977.         var alcos : array<SItemUniqueId>;
  4978.         var id : SItemUniqueId;
  4979.         var i, price, minPrice : int;
  4980.        
  4981.         alcos = inv.GetItemsByTag(theGame.params.TAG_ALCHEMY_REFILL_ALCO);
  4982.        
  4983.         if(alcos.Size() > 0)
  4984.         {
  4985.             if(inv.ItemHasTag(alcos[0], theGame.params.TAG_INFINITE_USE))
  4986.                 return alcos[0];
  4987.                
  4988.             minPrice = inv.GetItemPrice(alcos[0]);
  4989.             price = minPrice;
  4990.             id = alcos[0];
  4991.            
  4992.             for(i=1; i<alcos.Size(); i+=1)
  4993.             {
  4994.                 if(inv.ItemHasTag(alcos[i], theGame.params.TAG_INFINITE_USE))
  4995.                     return alcos[i];
  4996.                
  4997.                 price = inv.GetItemPrice(alcos[i]);
  4998.                
  4999.                 if(price < minPrice)
  5000.                 {
  5001.                     minPrice = price;
  5002.                     id = alcos[i];
  5003.                 }
  5004.             }
  5005.            
  5006.             return id;
  5007.         }
  5008.        
  5009.         return GetInvalidUniqueId();
  5010.     }
  5011.    
  5012.     public final function ClearPreviouslyUsedBolt()
  5013.     {
  5014.         previouslyUsedBolt = GetInvalidUniqueId();
  5015.     }
  5016.    
  5017.     public function ShouldUseInfiniteWaterBolts() : bool
  5018.     {
  5019.         return GetCurrentStateName() == 'Swimming' || IsSwimming() || IsDiving();
  5020.     }
  5021.    
  5022.     public function GetCurrentInfiniteBoltName( optional forceBodkin : bool, optional forceHarpoon : bool ) : name
  5023.     {
  5024.         if(!forceBodkin && (forceHarpoon || ShouldUseInfiniteWaterBolts()) )
  5025.         {
  5026.             return 'Harpoon Bolt';
  5027.         }
  5028.         return 'Bodkin Bolt';
  5029.     }
  5030.    
  5031.    
  5032.     public final function AddAndEquipInfiniteBolt(optional forceBodkin : bool, optional forceHarpoon : bool)
  5033.     {
  5034.         var bolt, bodkins, harpoons : array<SItemUniqueId>;
  5035.         var boltItemName : name;
  5036.         var i : int;
  5037.        
  5038.        
  5039.         bodkins = inv.GetItemsByName('Bodkin Bolt');
  5040.         harpoons = inv.GetItemsByName('Harpoon Bolt');
  5041.        
  5042.         for(i=bodkins.Size()-1; i>=0; i-=1)
  5043.             inv.RemoveItem(bodkins[i], inv.GetItemQuantity(bodkins[i]) );
  5044.            
  5045.         for(i=harpoons.Size()-1; i>=0; i-=1)
  5046.             inv.RemoveItem(harpoons[i], inv.GetItemQuantity(harpoons[i]) );
  5047.            
  5048.        
  5049.        
  5050.         boltItemName = GetCurrentInfiniteBoltName( forceBodkin, forceHarpoon );
  5051.        
  5052.        
  5053.         if(boltItemName == 'Bodkin Bolt' && inv.IsIdValid(previouslyUsedBolt))
  5054.         {
  5055.             bolt.PushBack(previouslyUsedBolt);
  5056.         }
  5057.         else
  5058.         {
  5059.            
  5060.             bolt = inv.AddAnItem(boltItemName, 1, true, true);
  5061.            
  5062.            
  5063.             if(boltItemName == 'Harpoon Bolt')
  5064.             {
  5065.                 GetItemEquippedOnSlot(EES_Bolt, previouslyUsedBolt);
  5066.             }
  5067.         }
  5068.        
  5069.         EquipItem(bolt[0], EES_Bolt);
  5070.     }
  5071.    
  5072.    
  5073.     event OnItemGiven(data : SItemChangedData)
  5074.     {
  5075.         var m_guiManager    : CR4GuiManager;
  5076.        
  5077.         super.OnItemGiven(data);
  5078.        
  5079.        
  5080.         if(!inv)
  5081.             inv = GetInventory();
  5082.        
  5083.        
  5084.         if(inv.IsItemEncumbranceItem(data.ids[0]))
  5085.             UpdateEncumbrance();
  5086.        
  5087.         m_guiManager = theGame.GetGuiManager();
  5088.         if(m_guiManager)
  5089.             m_guiManager.RegisterNewItem(data.ids[0]);
  5090.        
  5091.         // -= WMK:modQuickSlots =-
  5092.         if (WmkGetQuickInventoryInstance()) {
  5093.             WmkGetQuickInventoryInstance().RegisterNewItem(data.ids[0]);
  5094.         }
  5095.         // -= WMK:modQuickSlots =-
  5096.     }
  5097.        
  5098.    
  5099.     public final function CheckForFullyArmedAchievement()
  5100.     {
  5101.         if( HasAllItemsFromSet(theGame.params.ITEM_SET_TAG_BEAR) || HasAllItemsFromSet(theGame.params.ITEM_SET_TAG_GRYPHON) ||
  5102.             HasAllItemsFromSet(theGame.params.ITEM_SET_TAG_LYNX) || HasAllItemsFromSet(theGame.params.ITEM_SET_TAG_WOLF) ||
  5103.             HasAllItemsFromSet(theGame.params.ITEM_SET_TAG_VIPER)
  5104.         )
  5105.         {
  5106.             theGame.GetGamerProfile().AddAchievement(EA_FullyArmed);
  5107.         }
  5108.     }
  5109.    
  5110.    
  5111.     public final function HasAllItemsFromSet(setItemTag : name) : bool
  5112.     {
  5113.         var item : SItemUniqueId;
  5114.        
  5115.         if(!GetItemEquippedOnSlot(EES_SteelSword, item) || !inv.ItemHasTag(item, setItemTag))
  5116.             return false;
  5117.        
  5118.         if(!GetItemEquippedOnSlot(EES_SilverSword, item) || !inv.ItemHasTag(item, setItemTag))
  5119.             return false;
  5120.            
  5121.         if(!GetItemEquippedOnSlot(EES_Boots, item) || !inv.ItemHasTag(item, setItemTag))
  5122.             return false;
  5123.            
  5124.         if(!GetItemEquippedOnSlot(EES_Pants, item) || !inv.ItemHasTag(item, setItemTag))
  5125.             return false;
  5126.            
  5127.         if(!GetItemEquippedOnSlot(EES_Gloves, item) || !inv.ItemHasTag(item, setItemTag))
  5128.             return false;
  5129.            
  5130.         if(!GetItemEquippedOnSlot(EES_Armor, item) || !inv.ItemHasTag(item, setItemTag))
  5131.             return false;
  5132.            
  5133.        
  5134.         if(setItemTag == theGame.params.ITEM_SET_TAG_BEAR || setItemTag == theGame.params.ITEM_SET_TAG_LYNX)
  5135.         {
  5136.             if(!GetItemEquippedOnSlot(EES_RangedWeapon, item) || !inv.ItemHasTag(item, setItemTag))
  5137.                 return false;
  5138.         }
  5139.  
  5140.         return true;
  5141.     }
  5142.    
  5143.    
  5144.    
  5145.    
  5146.     public function GetTotalArmor() : SAbilityAttributeValue
  5147.     {
  5148.         var armor : SAbilityAttributeValue;
  5149.         var armorItem : SItemUniqueId;
  5150.        
  5151.         armor = super.GetTotalArmor();
  5152.        
  5153.         if(GetItemEquippedOnSlot(EES_Armor, armorItem))
  5154.         {
  5155.            
  5156.             armor -= inv.GetItemAttributeValue(armorItem, theGame.params.ARMOR_VALUE_NAME);
  5157.            
  5158.            
  5159.             armor += inv.GetItemArmorTotal(armorItem);         
  5160.         }
  5161.        
  5162.         if(GetItemEquippedOnSlot(EES_Pants, armorItem))
  5163.         {
  5164.            
  5165.             armor -= inv.GetItemAttributeValue(armorItem, theGame.params.ARMOR_VALUE_NAME);
  5166.            
  5167.            
  5168.             armor += inv.GetItemArmorTotal(armorItem);         
  5169.         }
  5170.            
  5171.         if(GetItemEquippedOnSlot(EES_Boots, armorItem))
  5172.         {
  5173.            
  5174.             armor -= inv.GetItemAttributeValue(armorItem, theGame.params.ARMOR_VALUE_NAME);
  5175.            
  5176.            
  5177.             armor += inv.GetItemArmorTotal(armorItem);         
  5178.         }
  5179.            
  5180.         if(GetItemEquippedOnSlot(EES_Gloves, armorItem))
  5181.         {
  5182.            
  5183.             armor -= inv.GetItemAttributeValue(armorItem, theGame.params.ARMOR_VALUE_NAME);
  5184.            
  5185.            
  5186.             armor += inv.GetItemArmorTotal(armorItem);         
  5187.         }
  5188.            
  5189.         return armor;
  5190.     }
  5191.    
  5192.    
  5193.    
  5194.     public function ReduceArmorDurability() : EEquipmentSlots
  5195.     {
  5196.         var r, sum : int;
  5197.         var slot : EEquipmentSlots;
  5198.         var id : SItemUniqueId;
  5199.         var prevDurMult, currDurMult, ratio : float;
  5200.    
  5201.        
  5202.         sum = theGame.params.DURABILITY_ARMOR_CHEST_WEIGHT;
  5203.         sum += theGame.params.DURABILITY_ARMOR_PANTS_WEIGHT;
  5204.         sum += theGame.params.DURABILITY_ARMOR_GLOVES_WEIGHT;
  5205.         sum += theGame.params.DURABILITY_ARMOR_BOOTS_WEIGHT;
  5206.         sum += theGame.params.DURABILITY_ARMOR_MISS_WEIGHT;
  5207.        
  5208.         r = RandRange(sum);
  5209.        
  5210.         if(r < theGame.params.DURABILITY_ARMOR_CHEST_WEIGHT)
  5211.             slot = EES_Armor;
  5212.         else if (r < theGame.params.DURABILITY_ARMOR_CHEST_WEIGHT + theGame.params.DURABILITY_ARMOR_PANTS_WEIGHT)
  5213.             slot = EES_Pants;
  5214.         else if (r < theGame.params.DURABILITY_ARMOR_CHEST_WEIGHT + theGame.params.DURABILITY_ARMOR_PANTS_WEIGHT + theGame.params.DURABILITY_ARMOR_GLOVES_WEIGHT)
  5215.             slot = EES_Gloves;
  5216.         else if (r < theGame.params.DURABILITY_ARMOR_CHEST_WEIGHT + theGame.params.DURABILITY_ARMOR_PANTS_WEIGHT + theGame.params.DURABILITY_ARMOR_GLOVES_WEIGHT + theGame.params.DURABILITY_ARMOR_BOOTS_WEIGHT)
  5217.             slot = EES_Boots;
  5218.         else
  5219.             return EES_InvalidSlot;                
  5220.        
  5221.         GetItemEquippedOnSlot(slot, id);               
  5222.         ratio = inv.GetItemDurabilityRatio(id);    
  5223.         if(inv.ReduceItemDurability(id))           
  5224.         {
  5225.             prevDurMult = theGame.params.GetDurabilityMultiplier(ratio, false);
  5226.            
  5227.             ratio = inv.GetItemDurabilityRatio(id);
  5228.             currDurMult = theGame.params.GetDurabilityMultiplier(ratio, false);
  5229.            
  5230.             if(currDurMult != prevDurMult)
  5231.             {
  5232.                
  5233.                
  5234.                
  5235.                
  5236.             }
  5237.                
  5238.             return slot;
  5239.         }
  5240.        
  5241.         return EES_InvalidSlot;
  5242.     }
  5243.    
  5244.    
  5245.     public function DismantleItem(dismantledItem : SItemUniqueId, toolItem : SItemUniqueId) : bool
  5246.     {
  5247.         var parts : array<SItemParts>;
  5248.         var i : int;
  5249.        
  5250.         if(!inv.IsItemDismantleKit(toolItem))
  5251.             return false;
  5252.        
  5253.         parts = inv.GetItemRecyclingParts(dismantledItem);
  5254.        
  5255.         if(parts.Size() <= 0)
  5256.             return false;
  5257.            
  5258.         for(i=0; i<parts.Size(); i+=1)
  5259.             inv.AddAnItem(parts[i].itemName, parts[i].quantity, true, false);
  5260.            
  5261.         inv.RemoveItem(toolItem);
  5262.         inv.RemoveItem(dismantledItem);
  5263.         return true;
  5264.     }
  5265.    
  5266.    
  5267.     public function GetItemEquippedOnSlot(slot : EEquipmentSlots, out item : SItemUniqueId) : bool
  5268.     {
  5269.         if(slot == EES_InvalidSlot || slot < 0 || slot > EnumGetMax('EEquipmentSlots'))
  5270.             return false;
  5271.        
  5272.         item = itemSlots[slot];
  5273.        
  5274.         return inv.IsIdValid(item);
  5275.     }
  5276.    
  5277.    
  5278.     public function GetItemSlotByItemName(itemName : name) : EEquipmentSlots
  5279.     {
  5280.         var ids : array<SItemUniqueId>;
  5281.         var i : int;
  5282.         var slot : EEquipmentSlots;
  5283.        
  5284.         ids = inv.GetItemsByName(itemName);
  5285.         for(i=0; i<ids.Size(); i+=1)
  5286.         {
  5287.             slot = GetItemSlot(ids[i]);
  5288.             if(slot != EES_InvalidSlot)
  5289.                 return slot;
  5290.         }
  5291.        
  5292.         return EES_InvalidSlot;
  5293.     }
  5294.    
  5295.    
  5296.     public function GetItemSlot(item : SItemUniqueId) : EEquipmentSlots
  5297.     {
  5298.         var i : int;
  5299.        
  5300.         if(!inv.IsIdValid(item))
  5301.             return EES_InvalidSlot;
  5302.            
  5303.         for(i=0; i<itemSlots.Size(); i+=1)
  5304.             if(itemSlots[i] == item)
  5305.                 return i;
  5306.        
  5307.         return EES_InvalidSlot;
  5308.     }
  5309.    
  5310.     public function GetEquippedItems() : array<SItemUniqueId>
  5311.     {
  5312.         return itemSlots;
  5313.     }
  5314.    
  5315.     public function IsItemEquipped(item : SItemUniqueId) : bool
  5316.     {
  5317.         if(!inv.IsIdValid(item))
  5318.             return false;
  5319.            
  5320.         return itemSlots.Contains(item);
  5321.     }
  5322.  
  5323.     public function IsItemHeld(item : SItemUniqueId) : bool
  5324.     {
  5325.         if(!inv.IsIdValid(item))
  5326.             return false;
  5327.            
  5328.         return inv.IsItemHeld(item);
  5329.     }
  5330.  
  5331.    
  5332.     public function IsAnyItemEquippedOnSlot(slot : EEquipmentSlots) : bool
  5333.     {
  5334.         if(slot == EES_InvalidSlot || slot < 0 || slot > EnumGetMax('EEquipmentSlots'))
  5335.             return false;
  5336.            
  5337.         return inv.IsIdValid(itemSlots[slot]);
  5338.     }
  5339.    
  5340.    
  5341.     public function GetFreeQuickslot() : EEquipmentSlots
  5342.     {
  5343.         if(!inv.IsIdValid(itemSlots[EES_Quickslot1]))       return EES_Quickslot1;
  5344.         if(!inv.IsIdValid(itemSlots[EES_Quickslot2]))       return EES_Quickslot2;
  5345.        
  5346.        
  5347.         return EES_InvalidSlot;
  5348.     }
  5349.    
  5350.    
  5351.     event OnEquipItemRequested(item : SItemUniqueId, ignoreMount : bool)
  5352.     {
  5353.         var slot : EEquipmentSlots;
  5354.        
  5355.         if(inv.IsIdValid(item))
  5356.         {
  5357.             slot = inv.GetSlotForItemId(item);
  5358.                
  5359.             if (slot != EES_InvalidSlot)
  5360.             {
  5361.                
  5362.                
  5363.                 EquipItemInGivenSlot(item, slot, ignoreMount);
  5364.             }
  5365.         }
  5366.     }
  5367.    
  5368.     event OnUnequipItemRequested(item : SItemUniqueId)
  5369.     {
  5370.         UnequipItem(item);
  5371.     }
  5372.    
  5373.    
  5374.     public function EquipItem(item : SItemUniqueId, optional slot : EEquipmentSlots, optional toHand : bool) : bool
  5375.     {
  5376.         if(!inv.IsIdValid(item))
  5377.             return false;
  5378.            
  5379.         if(slot == EES_InvalidSlot)
  5380.         {
  5381.             slot = inv.GetSlotForItemId(item);
  5382.            
  5383.             if(slot == EES_InvalidSlot)
  5384.                 return false;
  5385.         }
  5386.        
  5387.         ForceSoundAppearanceUpdate();
  5388.        
  5389.         return EquipItemInGivenSlot(item, slot, false, toHand);
  5390.     }
  5391.    
  5392.     protected function ShouldMount(slot : EEquipmentSlots, item : SItemUniqueId, category : name):bool
  5393.     {
  5394.        
  5395.        
  5396.         return !IsSlotPotionMutagen(slot) && category != 'usable' && category != 'potion' && category != 'petard' && !inv.ItemHasTag(item, 'PlayerUnwearable');
  5397.     }
  5398.        
  5399.     protected function ShouldMountItemWithName( itemName: name ): bool
  5400.     {
  5401.         var slot : EEquipmentSlots;
  5402.         var items : array<SItemUniqueId>;
  5403.         var category : name;
  5404.         var i : int;
  5405.        
  5406.         items = inv.GetItemsByName( itemName );
  5407.        
  5408.         category = inv.GetItemCategory( items[0] );
  5409.        
  5410.         slot = GetItemSlot( items[0] );
  5411.        
  5412.         return ShouldMount( slot, items[0], category );
  5413.     }  
  5414.    
  5415.     public function GetMountableItems( out items : array< SItemUniqueId > )
  5416.     {
  5417.         var i : int;
  5418.         var mountable : bool;
  5419.         var mountableItems : array< SItemUniqueId >;
  5420.         var slot : EEquipmentSlots;
  5421.         var category : name;
  5422.         var item: SItemUniqueId;
  5423.        
  5424.         for ( i = 0; i < items.Size(); i += 1 )
  5425.         {
  5426.             item = items[i];
  5427.        
  5428.             category = inv.GetItemCategory( item );
  5429.        
  5430.             slot = GetItemSlot( item );
  5431.        
  5432.             mountable = ShouldMount( slot, item, category );
  5433.        
  5434.             if ( mountable )
  5435.             {
  5436.                 mountableItems.PushBack( items[ i ] );
  5437.             }
  5438.         }
  5439.         items = mountableItems;
  5440.     }
  5441.    
  5442.     public final function AddAndEquipItem( item : name ) : bool
  5443.     {
  5444.         var ids : array< SItemUniqueId >;
  5445.        
  5446.         ids = inv.AddAnItem( item );
  5447.         if( inv.IsIdValid( ids[ 0 ] ) )
  5448.         {
  5449.             return EquipItem( ids[ 0 ] );
  5450.         }
  5451.        
  5452.         return false;
  5453.     }
  5454.    
  5455.     public final function AddQuestMarkedSelectedQuickslotItem( sel : SSelectedQuickslotItem )
  5456.     {
  5457.         questMarkedSelectedQuickslotItems.PushBack( sel );
  5458.     }
  5459.    
  5460.     public final function GetQuestMarkedSelectedQuickslotItem( sourceName : name ) : SItemUniqueId
  5461.     {
  5462.         var i : int;
  5463.        
  5464.         for( i=0; i<questMarkedSelectedQuickslotItems.Size(); i+=1 )
  5465.         {
  5466.             if( questMarkedSelectedQuickslotItems[i].sourceName == sourceName )
  5467.             {
  5468.                 return questMarkedSelectedQuickslotItems[i].itemID;
  5469.             }
  5470.         }
  5471.        
  5472.         return GetInvalidUniqueId();
  5473.     }
  5474.    
  5475.     public final function SwapEquippedItems(slot1 : EEquipmentSlots, slot2 : EEquipmentSlots)
  5476.     {
  5477.         var temp : SItemUniqueId;
  5478.         var pam : W3PlayerAbilityManager;
  5479.        
  5480.         temp = itemSlots[slot1];
  5481.         itemSlots[slot1] = itemSlots[slot2];
  5482.         itemSlots[slot2] = temp;
  5483.        
  5484.         if(IsSlotSkillMutagen(slot1))
  5485.         {
  5486.             pam = (W3PlayerAbilityManager)abilityManager;
  5487.             if(pam)
  5488.                 pam.OnSwappedMutagensPost(itemSlots[slot1], itemSlots[slot2]);
  5489.         }
  5490.     }
  5491.    
  5492.     public final function GetSlotForEquippedItem( itemID : SItemUniqueId ) : EEquipmentSlots
  5493.     {
  5494.         var i : int;
  5495.        
  5496.         for( i=0; i<itemSlots.Size(); i+=1 )
  5497.         {
  5498.             if( itemSlots[i] == itemID )
  5499.             {
  5500.                 return i;
  5501.             }
  5502.         }
  5503.        
  5504.         return EES_InvalidSlot;
  5505.     }
  5506.    
  5507.     public function EquipItemInGivenSlot(item : SItemUniqueId, slot : EEquipmentSlots, ignoreMounting : bool, optional toHand : bool) : bool
  5508.     {          
  5509.         var i, groupID, quantity : int;
  5510.         var fistsID : array<SItemUniqueId>;
  5511.         var pam : W3PlayerAbilityManager;
  5512.         var isSkillMutagen : bool;     
  5513.         var armorEntity : CItemEntity;
  5514.         var armorMeshComponent : CComponent;
  5515.         var armorSoundIdentification : name;
  5516.         var category : name;
  5517.         var prevSkillColor : ESkillColor;
  5518.         var containedAbilities : array<name>;
  5519.         var dm : CDefinitionsManagerAccessor;
  5520.         var armorType : EArmorType;
  5521.         var otherMask, previousItemInSlot : SItemUniqueId;
  5522.         var tutStatePot : W3TutorialManagerUIHandlerStatePotions;
  5523.         var tutStateFood : W3TutorialManagerUIHandlerStateFood;
  5524.         var tutStateSecondPotionEquip : W3TutorialManagerUIHandlerStateSecondPotionEquip;
  5525.         var boltItem : SItemUniqueId;
  5526.         var aerondight : W3Effect_Aerondight;
  5527.        
  5528.         if(!inv.IsIdValid(item))
  5529.         {
  5530.             LogAssert(false, "W3PlayerWitcher.EquipItemInGivenSlot: invalid item");
  5531.             return false;
  5532.         }
  5533.         if(slot == EES_InvalidSlot || slot == EES_HorseBlinders || slot == EES_HorseSaddle || slot == EES_HorseBag || slot == EES_HorseTrophy)
  5534.         {
  5535.             LogAssert(false, "W3PlayerWitcher.EquipItem: Cannot equip item <<" + inv.GetItemName(item) + ">> - provided slot <<" + slot + ">> is invalid");
  5536.             return false;
  5537.         }
  5538.         if(itemSlots[slot] == item)
  5539.         {
  5540.             return true;
  5541.         }  
  5542.        
  5543.         if(!HasRequiredLevelToEquipItem(item))
  5544.         {
  5545.            
  5546.             return false;
  5547.         }
  5548.        
  5549.         if(inv.ItemHasTag(item, 'PhantomWeapon') && !GetPhantomWeaponMgr())
  5550.         {
  5551.             InitPhantomWeaponMgr();
  5552.         }
  5553.        
  5554.        
  5555.         if( slot == EES_SilverSword && inv.ItemHasTag( item, 'Aerondight' ) )
  5556.         {
  5557.             AddEffectDefault( EET_Aerondight, this, "Aerondight" );
  5558.            
  5559.            
  5560.             aerondight = (W3Effect_Aerondight)GetBuff( EET_Aerondight );
  5561.             aerondight.Pause( 'ManageAerondightBuff' );
  5562.         }      
  5563.        
  5564.        
  5565.         previousItemInSlot = itemSlots[slot];
  5566.         if( IsItemEquipped(item))
  5567.         {
  5568.             SwapEquippedItems(slot, GetItemSlot(item));
  5569.             return true;
  5570.         }
  5571.        
  5572.        
  5573.         isSkillMutagen = IsSlotSkillMutagen(slot);
  5574.         if(isSkillMutagen)
  5575.         {
  5576.             pam = (W3PlayerAbilityManager)abilityManager;
  5577.             if(!pam.IsSkillMutagenSlotUnlocked(slot))
  5578.             {
  5579.                 return false;
  5580.             }
  5581.         }
  5582.        
  5583.        
  5584.         if(inv.IsIdValid(previousItemInSlot))
  5585.         {          
  5586.             if(!UnequipItemFromSlot(slot, true))
  5587.             {
  5588.                 LogAssert(false, "W3PlayerWitcher.EquipItem: Cannot equip item <<" + inv.GetItemName(item) + ">> !!");
  5589.                 return false;
  5590.             }
  5591.         }      
  5592.        
  5593.        
  5594.         if(inv.IsItemMask(item))
  5595.         {
  5596.             if(slot == EES_Quickslot1)
  5597.                 GetItemEquippedOnSlot(EES_Quickslot2, otherMask);
  5598.             else
  5599.                 GetItemEquippedOnSlot(EES_Quickslot1, otherMask);
  5600.                
  5601.             if(inv.IsItemMask(otherMask))
  5602.                 UnequipItem(otherMask);
  5603.         }
  5604.        
  5605.         if(isSkillMutagen)
  5606.         {
  5607.             groupID = pam.GetSkillGroupIdOfMutagenSlot(slot);
  5608.             prevSkillColor = pam.GetSkillGroupColor(groupID);
  5609.         }
  5610.        
  5611.         itemSlots[slot] = item;
  5612.        
  5613.         category = inv.GetItemCategory( item );
  5614.    
  5615.        
  5616.         if( !ignoreMounting && ShouldMount(slot, item, category) )
  5617.         {
  5618.            
  5619.             inv.MountItem( item, toHand, IsSlotSkillMutagen( slot ) );
  5620.         }      
  5621.        
  5622.         theTelemetry.LogWithLabelAndValue( TE_INV_ITEM_EQUIPPED, inv.GetItemName(item), slot );
  5623.                
  5624.         if(slot == EES_RangedWeapon)
  5625.         {          
  5626.             rangedWeapon = ( Crossbow )( inv.GetItemEntityUnsafe(item) );
  5627.             if(!rangedWeapon)
  5628.                 AddTimer('DelayedOnItemMount', 0.1, true);
  5629.            
  5630.             if ( IsSwimming() || IsDiving() )
  5631.             {
  5632.                 GetItemEquippedOnSlot(EES_Bolt, boltItem);
  5633.                
  5634.                 if(inv.IsIdValid(boltItem))
  5635.                 {
  5636.                     if ( !inv.ItemHasTag(boltItem, 'UnderwaterAmmo' ))
  5637.                     {
  5638.                         AddAndEquipInfiniteBolt(false, true);
  5639.                     }
  5640.                 }
  5641.                 else if(!IsAnyItemEquippedOnSlot(EES_Bolt))
  5642.                 {
  5643.                     AddAndEquipInfiniteBolt(false, true);
  5644.                 }
  5645.             }
  5646.            
  5647.             else if(!IsAnyItemEquippedOnSlot(EES_Bolt))
  5648.                 AddAndEquipInfiniteBolt();
  5649.         }
  5650.         else if(slot == EES_Bolt)
  5651.         {
  5652.             if(rangedWeapon)
  5653.             {   if ( !IsSwimming() || !IsDiving() )
  5654.                 {
  5655.                     rangedWeapon.OnReplaceAmmo();
  5656.                     rangedWeapon.OnWeaponReload();
  5657.                 }
  5658.                 else
  5659.                 {
  5660.                     DisplayHudMessage(GetLocStringByKeyExt( "menu_cannot_perform_action_now" ));
  5661.                 }
  5662.             }
  5663.         }      
  5664.        
  5665.         else if(isSkillMutagen)
  5666.         {
  5667.             theGame.GetGuiManager().IgnoreNewItemNotifications( true );
  5668.            
  5669.            
  5670.             quantity = inv.GetItemQuantity( item );
  5671.             if( quantity > 1 )
  5672.             {
  5673.                 inv.SplitItem( item, quantity - 1 );
  5674.             }
  5675.            
  5676.             pam.OnSkillMutagenEquipped(item, slot, prevSkillColor);
  5677.             LogSkillColors("Mutagen <<" + inv.GetItemName(item) + ">> equipped to slot <<" + slot + ">>");
  5678.             LogSkillColors("Group bonus color is now <<" + pam.GetSkillGroupColor(groupID) + ">>");
  5679.             LogSkillColors("");
  5680.            
  5681.             theGame.GetGuiManager().IgnoreNewItemNotifications( false );
  5682.         }
  5683.         else if(slot == EES_Gloves && HasWeaponDrawn(false))
  5684.         {
  5685.             PlayRuneword4FX(PW_Steel);
  5686.             PlayRuneword4FX(PW_Silver);
  5687.         }
  5688.        
  5689.         else if( ( slot == EES_Petard1 || slot == EES_Petard2 ) && inv.IsItemBomb( GetSelectedItemId() ) )
  5690.         {
  5691.             SelectQuickslotItem( slot );
  5692.         }
  5693.  
  5694.        
  5695.         if(inv.ItemHasAbility(item, 'MA_HtH'))
  5696.         {
  5697.             inv.GetItemContainedAbilities(item, containedAbilities);
  5698.             fistsID = inv.GetItemsByName('fists');
  5699.             dm = theGame.GetDefinitionsManager();
  5700.             for(i=0; i<containedAbilities.Size(); i+=1)
  5701.             {
  5702.                 if(dm.AbilityHasTag(containedAbilities[i], 'MA_HtH'))
  5703.                 {                  
  5704.                     inv.AddItemCraftedAbility(fistsID[0], containedAbilities[i], true);
  5705.                 }
  5706.             }
  5707.         }      
  5708.        
  5709.        
  5710.         if(inv.IsItemAnyArmor(item))
  5711.         {
  5712.             armorType = inv.GetArmorType(item);
  5713.             pam = (W3PlayerAbilityManager)abilityManager;
  5714.            
  5715.             if(armorType == EAT_Light)
  5716.             {
  5717.                 if(CanUseSkill(S_Perk_05))
  5718.                     pam.SetPerkArmorBonus(S_Perk_05);
  5719.             }
  5720.             else if(armorType == EAT_Medium)
  5721.             {
  5722.                 if(CanUseSkill(S_Perk_06))
  5723.                     pam.SetPerkArmorBonus(S_Perk_06);
  5724.             }
  5725.             else if(armorType == EAT_Heavy)
  5726.             {
  5727.                 if(CanUseSkill(S_Perk_07))
  5728.                     pam.SetPerkArmorBonus(S_Perk_07);
  5729.             }
  5730.         }
  5731.        
  5732.        
  5733.         UpdateItemSetBonuses( item, true );
  5734.                
  5735.        
  5736.         theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_OnItemEquipped );
  5737.    
  5738.        
  5739.         if(ShouldProcessTutorial('TutorialPotionCanEquip3'))
  5740.         {
  5741.             if(IsSlotPotionSlot(slot))
  5742.             {
  5743.                 tutStatePot = (W3TutorialManagerUIHandlerStatePotions)theGame.GetTutorialSystem().uiHandler.GetCurrentState();
  5744.                 if(tutStatePot)
  5745.                 {
  5746.                     tutStatePot.OnPotionEquipped(inv.GetItemName(item));
  5747.                 }
  5748.                
  5749.                 tutStateSecondPotionEquip = (W3TutorialManagerUIHandlerStateSecondPotionEquip)theGame.GetTutorialSystem().uiHandler.GetCurrentState();
  5750.                 if(tutStateSecondPotionEquip)
  5751.                 {
  5752.                     tutStateSecondPotionEquip.OnPotionEquipped(inv.GetItemName(item));
  5753.                 }
  5754.                
  5755.             }
  5756.         }
  5757.         ManageModShieldSkills( item, true ); //modShield
  5758.         ManageModShieldHoods( item, true ); //modShield                                              
  5759.         if(ShouldProcessTutorial('TutorialFoodSelectTab'))
  5760.         {
  5761.             if( IsSlotPotionSlot(slot) && inv.IsItemFood(item))
  5762.             {
  5763.                 tutStateFood = (W3TutorialManagerUIHandlerStateFood)theGame.GetTutorialSystem().uiHandler.GetCurrentState();
  5764.                 if(tutStateFood)
  5765.                 {
  5766.                     tutStateFood.OnFoodEquipped();
  5767.                 }
  5768.             }
  5769.         }
  5770.        
  5771.        
  5772.         if(inv.IsItemSetItem(item))
  5773.         {
  5774.             CheckForFullyArmedAchievement();   
  5775.         }
  5776.        
  5777.         return true;
  5778.     }
  5779.  
  5780.     private function CheckHairItem()
  5781.     {
  5782.         var ids : array<SItemUniqueId>;
  5783.         var i   : int;
  5784.         var itemName : name;
  5785.         var hairApplied : bool;
  5786.        
  5787.         ids = inv.GetItemsByCategory('hair');
  5788.        
  5789.         for(i=0; i<ids.Size(); i+= 1)
  5790.         {
  5791.             itemName = inv.GetItemName( ids[i] );
  5792.            
  5793.             if( itemName != 'Preview Hair' )
  5794.             {
  5795.                 if( hairApplied == false )
  5796.                 {
  5797.                     inv.MountItem( ids[i], false );
  5798.                     hairApplied = true;
  5799.                 }
  5800.                 else
  5801.                 {
  5802.                     inv.RemoveItem( ids[i], 1 );
  5803.                 }
  5804.                
  5805.             }
  5806.         }
  5807.        
  5808.         if( hairApplied == false )
  5809.         {
  5810.             ids = inv.AddAnItem('Half With Tail Hairstyle', 1, true, false);
  5811.             inv.MountItem( ids[0], false );
  5812.         }
  5813.        
  5814.     }
  5815.  
  5816.    
  5817.     timer function DelayedOnItemMount( dt : float, id : int )
  5818.     {
  5819.         var crossbowID : SItemUniqueId;
  5820.         var invent : CInventoryComponent;
  5821.        
  5822.         invent = GetInventory();
  5823.         if(!invent)
  5824.             return;
  5825.        
  5826.        
  5827.         GetItemEquippedOnSlot(EES_RangedWeapon, crossbowID);
  5828.                
  5829.         if(invent.IsIdValid(crossbowID))
  5830.         {
  5831.            
  5832.             rangedWeapon = ( Crossbow )(invent.GetItemEntityUnsafe(crossbowID) );
  5833.            
  5834.             if(rangedWeapon)
  5835.             {
  5836.                
  5837.                 RemoveTimer('DelayedOnItemMount');
  5838.             }
  5839.         }
  5840.         else
  5841.         {
  5842.            
  5843.             RemoveTimer('DelayedOnItemMount');
  5844.         }
  5845.     }
  5846.  
  5847.     public function GetHeldItems() : array<SItemUniqueId>
  5848.     {
  5849.         var items : array<SItemUniqueId>;
  5850.         var item : SItemUniqueId;
  5851.    
  5852.         if( inv.GetItemEquippedOnSlot(EES_SilverSword, item) && inv.IsItemHeld(item))
  5853.             items.PushBack(item);
  5854.            
  5855.         if( inv.GetItemEquippedOnSlot(EES_SteelSword, item) && inv.IsItemHeld(item))
  5856.             items.PushBack(item);
  5857.  
  5858.         if( inv.GetItemEquippedOnSlot(EES_RangedWeapon, item) && inv.IsItemHeld(item))
  5859.             items.PushBack(item);
  5860.  
  5861.         if( inv.GetItemEquippedOnSlot(EES_Quickslot1, item) && inv.IsItemHeld(item))
  5862.             items.PushBack(item);
  5863.  
  5864.         if( inv.GetItemEquippedOnSlot(EES_Quickslot2, item) && inv.IsItemHeld(item))
  5865.             items.PushBack(item);
  5866.  
  5867.         if( inv.GetItemEquippedOnSlot(EES_Petard1, item) && inv.IsItemHeld(item))
  5868.             items.PushBack(item);
  5869.  
  5870.         if( inv.GetItemEquippedOnSlot(EES_Petard2, item) && inv.IsItemHeld(item))
  5871.             items.PushBack(item);
  5872.        
  5873.         // -= WMK:modQuickSlots =-
  5874.         if (inv.GetItemEquippedOnSlot(EES_Petard3, item) && inv.IsItemHeld(item))
  5875.             items.PushBack(item);
  5876.         if (inv.GetItemEquippedOnSlot(EES_Petard4, item) && inv.IsItemHeld(item))
  5877.             items.PushBack(item);
  5878.         // -= WMK:modQuickSlots =-
  5879.        
  5880.         return items;          
  5881.     }
  5882.    
  5883.     public function MoveMutagenToSlot( item : SItemUniqueId, slotFrom : EEquipmentSlots, slotTo : EEquipmentSlots )
  5884.     {
  5885.         var pam : W3PlayerAbilityManager;
  5886.         var prevSkillColor : ESkillColor;
  5887.         var groupID : int;
  5888.        
  5889.         if( IsSlotSkillMutagen( slotTo ) )
  5890.         {  
  5891.             itemSlots[slotFrom] = GetInvalidUniqueId();
  5892.            
  5893.            
  5894.             groupID = pam.GetSkillGroupIdOfMutagenSlot(slotFrom);
  5895.             prevSkillColor = pam.GetSkillGroupColor(groupID);
  5896.             pam = (W3PlayerAbilityManager)abilityManager;
  5897.             pam.OnSkillMutagenUnequipped(item, slotFrom, prevSkillColor, true);
  5898.            
  5899.            
  5900.            
  5901.             EquipItemInGivenSlot( item, slotTo, false );
  5902.         }
  5903.     }
  5904.    
  5905.    
  5906.     public function UnequipItemFromSlot(slot : EEquipmentSlots, optional reequipped : bool) : bool
  5907.     {
  5908.         var item, bolts, id : SItemUniqueId;
  5909.         var items : array<SItemUniqueId>;
  5910.         var retBool : bool;
  5911.         var fistsID, bolt : array<SItemUniqueId>;
  5912.         var i, groupID : int;
  5913.         var pam : W3PlayerAbilityManager;
  5914.         var prevSkillColor : ESkillColor;
  5915.         var containedAbilities : array<name>;
  5916.         var dm : CDefinitionsManagerAccessor;
  5917.         var armorType : EArmorType;
  5918.         var isSwimming : bool;
  5919.         var hud                 : CR4ScriptedHud;
  5920.         var damagedItemModule   : CR4HudModuleDamagedItems;
  5921.        
  5922.         if(slot == EES_InvalidSlot || slot < 0 || slot > EnumGetMax('EEquipmentSlots') || !inv.IsIdValid(itemSlots[slot]))
  5923.             return false;
  5924.            
  5925.        
  5926.         if(IsSlotSkillMutagen(slot))
  5927.         {
  5928.            
  5929.             pam = (W3PlayerAbilityManager)abilityManager;
  5930.             groupID = pam.GetSkillGroupIdOfMutagenSlot(slot);
  5931.             prevSkillColor = pam.GetSkillGroupColor(groupID);
  5932.         }
  5933.        
  5934.        
  5935.         if(slot == EES_SilverSword  || slot == EES_SteelSword)
  5936.         {
  5937.             PauseOilBuffs( slot == EES_SteelSword );
  5938.         }
  5939.            
  5940.         item = itemSlots[slot];
  5941.         itemSlots[slot] = GetInvalidUniqueId();
  5942.        
  5943.        
  5944.         if(inv.ItemHasTag( item, 'PhantomWeapon' ) && GetPhantomWeaponMgr())
  5945.         {
  5946.             DestroyPhantomWeaponMgr();
  5947.         }
  5948.        
  5949.        
  5950.        
  5951.        
  5952.         if( slot == EES_SilverSword && inv.ItemHasTag( item, 'Aerondight' ) )
  5953.         {
  5954.             RemoveBuff( EET_Aerondight );
  5955.         }
  5956.        
  5957.        
  5958.         if(slot == EES_RangedWeapon)
  5959.         {
  5960.            
  5961.             this.OnRangedForceHolster( true, true );
  5962.             rangedWeapon.ClearDeployedEntity(true);
  5963.             rangedWeapon = NULL;
  5964.        
  5965.            
  5966.             if(GetItemEquippedOnSlot(EES_Bolt, bolts))
  5967.             {
  5968.                 if(inv.ItemHasTag(bolts, theGame.params.TAG_INFINITE_AMMO))
  5969.                 {
  5970.                     inv.RemoveItem(bolts, inv.GetItemQuantity(bolts) );
  5971.                 }
  5972.             }
  5973.         }
  5974.         else if(IsSlotSkillMutagen(slot))
  5975.         {          
  5976.             pam.OnSkillMutagenUnequipped(item, slot, prevSkillColor);
  5977.             LogSkillColors("Mutagen <<" + inv.GetItemName(item) + ">> unequipped from slot <<" + slot + ">>");
  5978.             LogSkillColors("Group bonus color is now <<" + pam.GetSkillGroupColor(groupID) + ">>");
  5979.             LogSkillColors("");
  5980.         }
  5981.        
  5982.        
  5983.         if(currentlyEquipedItem == item)
  5984.         {
  5985.             currentlyEquipedItem = GetInvalidUniqueId();
  5986.             RaiseEvent('ForcedUsableItemUnequip');
  5987.         }
  5988.         if(currentlyEquipedItemL == item)
  5989.         {
  5990.             if ( currentlyUsedItemL )
  5991.             {
  5992.                 currentlyUsedItemL.OnHidden( this );
  5993.             }
  5994.             HideUsableItem ( true );
  5995.         }
  5996.                
  5997.        
  5998.         if( !IsSlotPotionMutagen(slot) )
  5999.         {
  6000.             GetInventory().UnmountItem(item, true);
  6001.         }
  6002.        
  6003.         retBool = true;
  6004.                
  6005.        
  6006.         if(IsAnyItemEquippedOnSlot(EES_RangedWeapon) && slot == EES_Bolt)
  6007.         {          
  6008.             if(inv.ItemHasTag(item, theGame.params.TAG_INFINITE_AMMO))
  6009.             {
  6010.                
  6011.                 inv.RemoveItem(item, inv.GetItemQuantityByName( inv.GetItemName(item) ) );
  6012.             }
  6013.             else if (!reequipped)
  6014.             {
  6015.                
  6016.                 AddAndEquipInfiniteBolt();
  6017.             }
  6018.         }
  6019.        
  6020.        
  6021.         if(slot == EES_SilverSword  || slot == EES_SteelSword)
  6022.         {
  6023.             OnEquipMeleeWeapon(PW_None, true);         
  6024.         }
  6025.        
  6026.         if(  GetSelectedItemId() == item )
  6027.         {
  6028.             ClearSelectedItemId();
  6029.         }
  6030.        
  6031.         if(inv.IsItemBody(item))
  6032.         {
  6033.             retBool = true;
  6034.         }      
  6035.        
  6036.         if(retBool && !reequipped)
  6037.         {
  6038.             theTelemetry.LogWithLabelAndValue( TE_INV_ITEM_UNEQUIPPED, inv.GetItemName(item), slot );
  6039.            
  6040.            
  6041.             if(slot == EES_SteelSword && !IsAnyItemEquippedOnSlot(EES_SilverSword))
  6042.             {
  6043.                 RemoveBuff(EET_EnhancedWeapon);
  6044.             }
  6045.             else if(slot == EES_SilverSword && !IsAnyItemEquippedOnSlot(EES_SteelSword))
  6046.             {
  6047.                 RemoveBuff(EET_EnhancedWeapon);
  6048.             }
  6049.             else if(inv.IsItemAnyArmor(item))
  6050.             {
  6051.                 if( !IsAnyItemEquippedOnSlot(EES_Armor) && !IsAnyItemEquippedOnSlot(EES_Gloves) && !IsAnyItemEquippedOnSlot(EES_Boots) && !IsAnyItemEquippedOnSlot(EES_Pants))
  6052.                     RemoveBuff(EET_EnhancedArmor);
  6053.             }
  6054.         }
  6055.        
  6056.        
  6057.         if(inv.ItemHasAbility(item, 'MA_HtH'))
  6058.         {
  6059.             inv.GetItemContainedAbilities(item, containedAbilities);
  6060.             fistsID = inv.GetItemsByName('fists');
  6061.             dm = theGame.GetDefinitionsManager();
  6062.             for(i=0; i<containedAbilities.Size(); i+=1)
  6063.             {
  6064.                 if(dm.AbilityHasTag(containedAbilities[i], 'MA_HtH'))
  6065.                 {
  6066.                     inv.RemoveItemCraftedAbility(fistsID[0], containedAbilities[i]);
  6067.                 }
  6068.             }
  6069.         }
  6070.        
  6071.        
  6072.         if(inv.IsItemAnyArmor(item))
  6073.         {
  6074.             armorType = inv.GetArmorType(item);
  6075.             pam = (W3PlayerAbilityManager)abilityManager;
  6076.            
  6077.             if(CanUseSkill(S_Perk_05) && (armorType == EAT_Light || GetCharacterStats().HasAbility('Glyphword 2 _Stats', true) || inv.ItemHasAbility(item, 'Glyphword 2 _Stats')))
  6078.             {
  6079.                 pam.SetPerkArmorBonus(S_Perk_05);
  6080.             }
  6081.             if(CanUseSkill(S_Perk_06) && (armorType == EAT_Medium || GetCharacterStats().HasAbility('Glyphword 3 _Stats', true) || inv.ItemHasAbility(item, 'Glyphword 3 _Stats')) )
  6082.             {
  6083.                 pam.SetPerkArmorBonus(S_Perk_06);
  6084.             }
  6085.             if(CanUseSkill(S_Perk_07) && (armorType == EAT_Heavy || GetCharacterStats().HasAbility('Glyphword 4 _Stats', true) || inv.ItemHasAbility(item, 'Glyphword 4 _Stats')) )
  6086.             {
  6087.                 pam.SetPerkArmorBonus(S_Perk_07);
  6088.             }
  6089.         }
  6090.        
  6091.        
  6092.         UpdateItemSetBonuses( item, false );
  6093.        
  6094.        
  6095.         if( inv.ItemHasTag( item, theGame.params.ITEM_SET_TAG_BONUS ) && !IsSetBonusActive( EISB_RedWolf_2 ) )
  6096.         {
  6097.             SkillReduceBombAmmoBonus();
  6098.         }
  6099.         ManageModShieldSkills( item, false ); //modShield
  6100.         ManageModShieldHoods( item, false ); //modShield                                                 
  6101.         if( slot == EES_Gloves )
  6102.         {
  6103.             thePlayer.DestroyEffect('runeword_4');
  6104.         }
  6105.        
  6106.        
  6107.         hud = (CR4ScriptedHud)theGame.GetHud();
  6108.         if ( hud )
  6109.         {
  6110.             damagedItemModule = hud.GetDamagedItemModule();
  6111.             if ( damagedItemModule )
  6112.             {
  6113.                 damagedItemModule.OnItemUnequippedFromSlot( slot );
  6114.             }
  6115.         }
  6116.        
  6117.        
  6118.         theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_OnItemEquipped );
  6119.        
  6120.         return retBool;
  6121.     }
  6122.        
  6123.     public function UnequipItem(item : SItemUniqueId) : bool
  6124.     {
  6125.         if(!inv.IsIdValid(item))
  6126.             return false;
  6127.        
  6128.         return UnequipItemFromSlot( itemSlots.FindFirst(item) );
  6129.     }
  6130.    
  6131.     public function DropItem( item : SItemUniqueId, quantity : int ) : bool
  6132.     {
  6133.         if(!inv.IsIdValid(item))
  6134.             return false;
  6135.         if(IsItemEquipped(item))
  6136.             return UnequipItem(item);
  6137.        
  6138.         return true;
  6139.     }  
  6140.    
  6141.    
  6142.     public function IsItemEquippedByName(itemName : name) : bool
  6143.     {
  6144.         var i : int;
  6145.    
  6146.         for(i=0; i<itemSlots.Size(); i+=1)
  6147.             if(inv.GetItemName(itemSlots[i]) == itemName)
  6148.                 return true;
  6149.  
  6150.         return false;
  6151.     }
  6152.  
  6153.    
  6154.     public function IsItemEquippedByCategoryName(categoryName : name) : bool
  6155.     {
  6156.         var i : int;
  6157.    
  6158.         for(i=0; i<itemSlots.Size(); i+=1)
  6159.             if(inv.GetItemCategory(itemSlots[i]) == categoryName)
  6160.                 return true;
  6161.                
  6162.         return false;
  6163.     }
  6164.    
  6165.     public function GetMaxRunEncumbrance(out usesHorseBonus : bool) : float
  6166.     {
  6167.         var value : float;
  6168.        
  6169.         value = CalculateAttributeValue(GetHorseManager().GetHorseAttributeValue('encumbrance', false));
  6170.         usesHorseBonus = (value > 0);
  6171.         value += CalculateAttributeValue( GetAttributeValue('encumbrance') );
  6172.        
  6173.         return value;
  6174.     }
  6175.        
  6176.     public function GetEncumbrance() : float
  6177.     {
  6178.         var i: int;
  6179.         var encumbrance : float;
  6180.         var items : array<SItemUniqueId>;
  6181.         var inve : CInventoryComponent;
  6182.    
  6183.         inve = GetInventory();         
  6184.         inve.GetAllItems(items);
  6185.  
  6186.         for(i=0; i<items.Size(); i+=1)
  6187.         {
  6188.             encumbrance += inve.GetItemEncumbrance( items[i] );
  6189.            
  6190.            
  6191.            
  6192.         }      
  6193.         return encumbrance;
  6194.     }
  6195.    
  6196.    
  6197.    
  6198.     public function StartInvUpdateTransaction():void
  6199.     {
  6200.         invUpdateTransaction = true;
  6201.     }
  6202.    
  6203.     public function FinishInvUpdateTransaction():void
  6204.     {
  6205.         invUpdateTransaction = false;
  6206.        
  6207.        
  6208.        
  6209.         UpdateEncumbrance();
  6210.     }
  6211.    
  6212.    
  6213.     public function UpdateEncumbrance()
  6214.     {
  6215.         var temp : bool;
  6216.        
  6217.         if (invUpdateTransaction)
  6218.         {
  6219.            
  6220.             return;
  6221.         }
  6222.        
  6223.        
  6224.        
  6225.         if ( GetEncumbrance() >= (GetMaxRunEncumbrance(temp) + 1) )
  6226.         {
  6227.             if( !HasBuff(EET_OverEncumbered) && FactsQuerySum( "DEBUG_EncumbranceBoy" ) == 0 )
  6228.             {
  6229.                 AddEffectDefault(EET_OverEncumbered, NULL, "OverEncumbered");
  6230.             }
  6231.         }
  6232.         else if(HasBuff(EET_OverEncumbered))
  6233.         {
  6234.             RemoveAllBuffsOfType(EET_OverEncumbered);
  6235.         }
  6236.     }
  6237.    
  6238.     public final function GetSkillGroupIDFromIndex(idx : int) : int
  6239.     {
  6240.         var pam : W3PlayerAbilityManager;
  6241.        
  6242.         pam = (W3PlayerAbilityManager)abilityManager;
  6243.         if(pam && pam.IsInitialized())
  6244.             return pam.GetSkillGroupIDFromIndex(idx);
  6245.            
  6246.         return -1;
  6247.     }
  6248.    
  6249.     public final function GetSkillGroupColor(groupID : int) : ESkillColor
  6250.     {
  6251.         var pam : W3PlayerAbilityManager;
  6252.        
  6253.         pam = (W3PlayerAbilityManager)abilityManager;
  6254.         if(pam && pam.IsInitialized())
  6255.             return pam.GetSkillGroupColor(groupID);
  6256.            
  6257.         return SC_None;
  6258.     }
  6259.    
  6260.     public final function GetSkillGroupsCount() : int
  6261.     {
  6262.         var pam : W3PlayerAbilityManager;
  6263.        
  6264.         pam = (W3PlayerAbilityManager)abilityManager;
  6265.         if(pam && pam.IsInitialized())
  6266.             return pam.GetSkillGroupsCount();
  6267.            
  6268.         return 0;
  6269.     }
  6270.    
  6271.    
  6272.    
  6273.    
  6274.    
  6275.    
  6276.    
  6277.    
  6278.     function CycleSelectSign( bIsCyclingLeft : bool ) : ESignType
  6279.     {
  6280.         var signOrder : array<ESignType>;
  6281.         var i : int;
  6282.        
  6283.         signOrder.PushBack( ST_Yrden );
  6284.         signOrder.PushBack( ST_Quen );
  6285.         signOrder.PushBack( ST_Igni );
  6286.         signOrder.PushBack( ST_Axii );
  6287.         signOrder.PushBack( ST_Aard );
  6288.            
  6289.         for( i = 0; i < signOrder.Size(); i += 1 )
  6290.             if( signOrder[i] == equippedSign )
  6291.                 break;
  6292.        
  6293.         if(bIsCyclingLeft)
  6294.             return signOrder[ (4 + i) % 5 ];   
  6295.         else
  6296.             return signOrder[ (6 + i) % 5 ];
  6297.     }
  6298.    
  6299.     function ToggleNextSign()
  6300.     {
  6301.         SetEquippedSign(CycleSelectSign( false ));
  6302.         FactsAdd("SignToggled", 1, 1);
  6303.     }
  6304.    
  6305.     function TogglePreviousSign()
  6306.     {
  6307.         SetEquippedSign(CycleSelectSign( true ));
  6308.         FactsAdd("SignToggled", 1, 1);
  6309.     }
  6310.    
  6311.     function ProcessSignEvent( eventName : name ) : bool
  6312.     {
  6313.         if( currentlyCastSign != ST_None && signs[currentlyCastSign].entity)
  6314.         {
  6315.             return signs[currentlyCastSign].entity.OnProcessSignEvent( eventName );
  6316.         }
  6317.        
  6318.         return false;
  6319.     }
  6320.    
  6321.     var findActorTargetTimeStamp : float;
  6322.     var pcModeChanneledSignTimeStamp    : float;
  6323.     event OnProcessCastingOrientation( isContinueCasting : bool )
  6324.     {
  6325.         var customOrientationTarget : EOrientationTarget;
  6326.         var checkHeading            : float;
  6327.         var rotHeading              : float;
  6328.         var playerToHeadingDist     : float;
  6329.         var slideTargetActor        : CActor;
  6330.         var newLockTarget           : CActor;
  6331.        
  6332.         var enableNoTargetOrientation   : bool;
  6333.        
  6334.         var currTime : float;
  6335.        
  6336.         enableNoTargetOrientation = true;
  6337.         if ( GetDisplayTarget() && this.IsDisplayTargetTargetable() )
  6338.         {
  6339.             enableNoTargetOrientation = false;
  6340.             if ( theInput.GetActionValue( 'CastSignHold' ) > 0 || this.IsCurrentSignChanneled() )
  6341.             {
  6342.                 if ( IsPCModeEnabled() )
  6343.                 {
  6344.                     if ( EngineTimeToFloat( theGame.GetEngineTime() ) >  pcModeChanneledSignTimeStamp + 1.f )
  6345.                         enableNoTargetOrientation = true;
  6346.                 }
  6347.                 else
  6348.                 {
  6349.                     if ( GetCurrentlyCastSign() == ST_Igni || GetCurrentlyCastSign() == ST_Axii )
  6350.                     {
  6351.                         slideTargetActor = (CActor)GetDisplayTarget();
  6352.                         if ( slideTargetActor
  6353.                             && ( !slideTargetActor.GetGameplayVisibility() || !CanBeTargetedIfSwimming( slideTargetActor ) || !slideTargetActor.IsAlive() ) )
  6354.                         {
  6355.                             SetSlideTarget( NULL );
  6356.                             if ( ProcessLockTarget() )
  6357.                                 slideTargetActor = (CActor)slideTarget;
  6358.                         }              
  6359.                        
  6360.                         if ( !slideTargetActor )
  6361.                         {
  6362.                             LockToTarget( false );
  6363.                             enableNoTargetOrientation = true;
  6364.                         }
  6365.                         else if ( IsThreat( slideTargetActor ) || GetCurrentlyCastSign() == ST_Axii )
  6366.                             LockToTarget( true );
  6367.                         else
  6368.                         {
  6369.                             LockToTarget( false );
  6370.                             enableNoTargetOrientation = true;
  6371.                         }
  6372.                     }
  6373.                 }
  6374.             }
  6375.  
  6376.             if ( !enableNoTargetOrientation )
  6377.             {          
  6378.                 customOrientationTarget = OT_Actor;
  6379.             }
  6380.         }
  6381.        
  6382.         if ( enableNoTargetOrientation )
  6383.         {
  6384.             if ( GetPlayerCombatStance() == PCS_AlertNear && theInput.GetActionValue( 'CastSignHold' ) > 0 )
  6385.             {
  6386.                 if ( GetDisplayTarget() && !slideTargetActor )
  6387.                 {
  6388.                     currTime = EngineTimeToFloat( theGame.GetEngineTime() );
  6389.                     if ( currTime > findActorTargetTimeStamp + 1.5f )
  6390.                     {
  6391.                         findActorTargetTimeStamp = currTime;
  6392.                        
  6393.                         newLockTarget = GetScreenSpaceLockTarget( GetDisplayTarget(), 180.f, 1.f, 0.f, true );
  6394.                        
  6395.                         if ( newLockTarget && IsThreat( newLockTarget ) && IsCombatMusicEnabled() )
  6396.                         {
  6397.                             SetTarget( newLockTarget, true );
  6398.                             SetMoveTargetChangeAllowed( true );
  6399.                             SetMoveTarget( newLockTarget );
  6400.                             SetMoveTargetChangeAllowed( false );
  6401.                             SetSlideTarget( newLockTarget );                           
  6402.                         }  
  6403.                     }
  6404.                 }
  6405.                 else
  6406.                     ProcessLockTarget();
  6407.             }
  6408.            
  6409.             if ( wasBRAxisPushed )
  6410.                 customOrientationTarget = OT_CameraOffset;
  6411.             else
  6412.             {
  6413.                 if ( !lastAxisInputIsMovement || theInput.LastUsedPCInput() )
  6414.                     customOrientationTarget = OT_CameraOffset;
  6415.                 else if ( theInput.GetActionValue( 'CastSignHold' ) > 0 )
  6416.                 {
  6417.                     if ( GetOrientationTarget() == OT_CameraOffset )
  6418.                         customOrientationTarget = OT_CameraOffset;
  6419.                     else if ( GetPlayerCombatStance() == PCS_AlertNear || GetPlayerCombatStance() == PCS_Guarded )
  6420.                         customOrientationTarget = OT_CameraOffset;
  6421.                     else
  6422.                         customOrientationTarget = OT_Player;   
  6423.                 }
  6424.                 else
  6425.                     customOrientationTarget = OT_CustomHeading;
  6426.             }          
  6427.         }      
  6428.        
  6429.         if ( GetCurrentlyCastSign() == ST_Quen )
  6430.         {
  6431.             if ( theInput.LastUsedPCInput() )
  6432.             {
  6433.                 customOrientationTarget = OT_Camera;
  6434.             }
  6435.             else if ( IsCurrentSignChanneled() )
  6436.             {
  6437.                 if ( bLAxisReleased )
  6438.                     customOrientationTarget = OT_Player;
  6439.                 else
  6440.                     customOrientationTarget = OT_Camera;
  6441.             }
  6442.             else
  6443.                 customOrientationTarget = OT_Player;
  6444.         }  
  6445.        
  6446.         if ( GetCurrentlyCastSign() == ST_Axii && IsCurrentSignChanneled() )
  6447.         {  
  6448.             if ( slideTarget && (CActor)slideTarget )
  6449.             {
  6450.                 checkHeading = VecHeading( slideTarget.GetWorldPosition() - this.GetWorldPosition() );
  6451.                 rotHeading = checkHeading;
  6452.                 playerToHeadingDist = AngleDistance( GetHeading(), checkHeading );
  6453.                
  6454.                 if ( playerToHeadingDist > 45 )
  6455.                     SetCustomRotation( 'ChanneledSignAxii', rotHeading, 0.0, 0.5, false );
  6456.                 else if ( playerToHeadingDist < -45 )
  6457.                     SetCustomRotation( 'ChanneledSignAxii', rotHeading, 0.0, 0.5, false );                 
  6458.             }
  6459.             else
  6460.             {
  6461.                 checkHeading = VecHeading( theCamera.GetCameraDirection() );
  6462.                 rotHeading = GetHeading();
  6463.                 playerToHeadingDist = AngleDistance( GetHeading(), checkHeading );
  6464.                
  6465.                 if ( playerToHeadingDist > 45 )
  6466.                     SetCustomRotation( 'ChanneledSignAxii', rotHeading - 22.5, 0.0, 0.5, false );
  6467.                 else if ( playerToHeadingDist < -45 )
  6468.                     SetCustomRotation( 'ChanneledSignAxii', rotHeading + 22.5, 0.0, 0.5, false );              
  6469.             }
  6470.         }      
  6471.            
  6472.         if ( IsActorLockedToTarget() )
  6473.             customOrientationTarget = OT_Actor;
  6474.        
  6475.         //modEnhancedTargeting BEGIN
  6476.         if ( theGame.GetInGameConfigWrapper().GetVarValue('EnhancedTargeting', 'ETSignsTowardsCamera') )
  6477.             customOrientationTarget = OT_CameraOffset; // shitty tweak, oh well
  6478.         //modEnhancedTargeting END
  6479.        
  6480.         AddCustomOrientationTarget( customOrientationTarget, 'Signs' );
  6481.        
  6482.         if ( customOrientationTarget == OT_CustomHeading )
  6483.             SetOrientationTargetCustomHeading( GetCombatActionHeading(), 'Signs' );        
  6484.     }
  6485.    
  6486.     event OnRaiseSignEvent()
  6487.     {
  6488.         var newTarget : CActor;
  6489.    
  6490.         if ( ( !IsCombatMusicEnabled() && !CanAttackWhenNotInCombat( EBAT_CastSign, false, newTarget ) ) || ( IsOnBoat() && !IsCombatMusicEnabled() ) )
  6491.         {      
  6492.             if ( CastSignFriendly() )
  6493.                 return true;
  6494.         }
  6495.         else
  6496.         {
  6497.             RaiseEvent('CombatActionFriendlyEnd');
  6498.             SetBehaviorVariable( 'SignNum', (int)equippedSign );
  6499.             SetBehaviorVariable( 'combatActionType', (int)CAT_CastSign );
  6500.  
  6501.             if ( IsPCModeEnabled() )
  6502.                 pcModeChanneledSignTimeStamp = EngineTimeToFloat( theGame.GetEngineTime() );
  6503.        
  6504.             if( RaiseForceEvent('CombatAction') )
  6505.             {
  6506.                 OnCombatActionStart();
  6507.                 findActorTargetTimeStamp = EngineTimeToFloat( theGame.GetEngineTime() );
  6508.                 theTelemetry.LogWithValueStr(TE_FIGHT_PLAYER_USE_SIGN, SignEnumToString( equippedSign ));
  6509.                 return true;
  6510.             }
  6511.         }
  6512.        
  6513.         return false;
  6514.     }
  6515.    
  6516.     function CastSignFriendly() : bool
  6517.     {
  6518.         var actor : CActor;
  6519.    
  6520.         SetBehaviorVariable( 'combatActionTypeForOverlay', (int)CAT_CastSign );        
  6521.         if ( RaiseCombatActionFriendlyEvent() )
  6522.         {
  6523.                        
  6524.             return true;
  6525.         }  
  6526.        
  6527.         return false;
  6528.     }
  6529.    
  6530.     function CastSign() : bool
  6531.     {
  6532.         var equippedSignStr : string;
  6533.         var newSignEnt : W3SignEntity;
  6534.         var spawnPos : Vector;
  6535.         var slotMatrix : Matrix;
  6536.         var target : CActor;
  6537.        
  6538.         if ( IsInAir() )
  6539.         {
  6540.             return false;
  6541.         }
  6542.        
  6543.         AddTemporarySkills();
  6544.        
  6545.        
  6546.        
  6547.         if(equippedSign == ST_Aard)
  6548.         {
  6549.             CalcEntitySlotMatrix('l_weapon', slotMatrix);
  6550.             spawnPos = MatrixGetTranslation(slotMatrix);
  6551.         }
  6552.         else
  6553.         {
  6554.             spawnPos = GetWorldPosition();
  6555.         }
  6556.        
  6557.         if( equippedSign == ST_Aard || equippedSign == ST_Igni )
  6558.         {
  6559.             target = GetTarget();
  6560.             if(target)
  6561.                 target.SignalGameplayEvent( 'DodgeSign' );
  6562.         }
  6563.        
  6564.         newSignEnt = (W3SignEntity)theGame.CreateEntity( signs[equippedSign].template, spawnPos, GetWorldRotation() );
  6565.         return newSignEnt.Init( signOwner, signs[equippedSign].entity );
  6566.     }
  6567.    
  6568.    
  6569.     private function HAX_SignToThrowItemRestore()
  6570.     {
  6571.         var action : SInputAction;
  6572.        
  6573.         action.value = theInput.GetActionValue('ThrowItemHold');
  6574.         action.lastFrameValue = 0;
  6575.        
  6576.         if(IsPressed(action) && CanSetupCombatAction_Throw())
  6577.         {
  6578.             if(inv.IsItemBomb(selectedItemId))
  6579.             {
  6580.                 BombThrowStart();
  6581.             }
  6582.             else
  6583.             {
  6584.                 UsableItemStart();
  6585.             }
  6586.            
  6587.             SetThrowHold( true );
  6588.         }
  6589.     }
  6590.    
  6591.     event OnCFMCameraZoomFail(){}
  6592.        
  6593.    
  6594.  
  6595.     public final function GetDrunkMutagens( optional sourceName : string ) : array<CBaseGameplayEffect>
  6596.     {
  6597.         return effectManager.GetDrunkMutagens( sourceName );
  6598.     }
  6599.    
  6600.     public final function GetPotionBuffs() : array<CBaseGameplayEffect>
  6601.     {
  6602.         return effectManager.GetPotionBuffs();
  6603.     }
  6604.    
  6605.     public final function RecalcPotionsDurations()
  6606.     {
  6607.         var i : int;
  6608.         var buffs : array<CBaseGameplayEffect>;
  6609.        
  6610.         buffs = GetPotionBuffs();
  6611.         for(i=0; i<buffs.Size(); i+=1)
  6612.         {
  6613.             buffs[i].RecalcPotionDuration();
  6614.         }
  6615.     }
  6616.  
  6617.     public function StartFrenzy()
  6618.     {
  6619.         var ratio, duration : float;
  6620.         var skillLevel : int;
  6621.    
  6622.         isInFrenzy = true;
  6623.         skillLevel = GetSkillLevel(S_Alchemy_s16);
  6624.         ratio = 0.48f - skillLevel * CalculateAttributeValue(GetSkillAttributeValue(S_Alchemy_s16, 'slowdown_ratio', false, true));
  6625.         duration = skillLevel * CalculateAttributeValue(GetSkillAttributeValue(S_Alchemy_s16, 'slowdown_duration', false, true));
  6626.    
  6627.         theGame.SetTimeScale(ratio, theGame.GetTimescaleSource(ETS_SkillFrenzy), theGame.GetTimescalePriority(ETS_SkillFrenzy) );
  6628.         AddTimer('SkillFrenzyFinish', duration * ratio, , , , true);
  6629.     }
  6630.    
  6631.     timer function SkillFrenzyFinish(dt : float, optional id : int)
  6632.     {      
  6633.         theGame.RemoveTimeScale( theGame.GetTimescaleSource(ETS_SkillFrenzy) );
  6634.         isInFrenzy = false;
  6635.     }
  6636.    
  6637.     public function GetToxicityDamageThreshold() : float
  6638.     {
  6639.         var ret : float;
  6640.        
  6641.         ret = theGame.params.TOXICITY_DAMAGE_THRESHOLD;
  6642.        
  6643.         if(CanUseSkill(S_Alchemy_s01))
  6644.             ret += CalculateAttributeValue(GetSkillAttributeValue(S_Alchemy_s01, 'threshold', false, true)) * GetSkillLevel(S_Alchemy_s01);
  6645.        
  6646.         return ret;
  6647.     }
  6648.    
  6649.    
  6650.    
  6651.     public final function AddToxicityOffset( val : float)
  6652.     {
  6653.         ((W3PlayerAbilityManager)abilityManager).AddToxicityOffset(val);       
  6654.     }
  6655.    
  6656.     public final function SetToxicityOffset( val : float)
  6657.     {
  6658.         ((W3PlayerAbilityManager)abilityManager).SetToxicityOffset(val);
  6659.     }
  6660.    
  6661.     public final function RemoveToxicityOffset( val : float)
  6662.     {
  6663.         ((W3PlayerAbilityManager)abilityManager).RemoveToxicityOffset(val);    
  6664.     }
  6665.    
  6666.    
  6667.     public final function CalculatePotionDuration(item : SItemUniqueId, isMutagenPotion : bool, optional itemName : name) : float
  6668.     {
  6669.         var duration, skillPassiveMod, mutagenSkillMod : float;
  6670.         var val, min, max : SAbilityAttributeValue;
  6671.        
  6672.        
  6673.         if(inv.IsIdValid(item))
  6674.         {
  6675.             duration = CalculateAttributeValue(inv.GetItemAttributeValue(item, 'duration'));           
  6676.         }
  6677.         else
  6678.         {
  6679.             theGame.GetDefinitionsManager().GetItemAttributeValueNoRandom(itemName, true, 'duration', min, max);
  6680.             duration = CalculateAttributeValue(GetAttributeRandomizedValue(min, max));
  6681.         }
  6682.            
  6683.         skillPassiveMod = CalculateAttributeValue(GetAttributeValue('potion_duration'));
  6684.        
  6685.         if(isMutagenPotion && CanUseSkill(S_Alchemy_s14))
  6686.         {
  6687.             val = GetSkillAttributeValue(S_Alchemy_s14, 'duration', false, true);
  6688.             mutagenSkillMod = val.valueMultiplicative * GetSkillLevel(S_Alchemy_s14);
  6689.         }
  6690.        
  6691.         duration = duration * (1 + skillPassiveMod + mutagenSkillMod);
  6692.        
  6693.         return duration;
  6694.     }
  6695.    
  6696.     public function ToxicityLowEnoughToDrinkPotion( slotid : EEquipmentSlots, optional itemId : SItemUniqueId ) : bool
  6697.     {
  6698.         var item                : SItemUniqueId;
  6699.         var maxTox              : float;
  6700.         var potionToxicity      : float;
  6701.         var toxicityOffset      : float;
  6702.         var effectType          : EEffectType;
  6703.         var customAbilityName   : name;
  6704.        
  6705.         // modMetabolismBoostPatch
  6706.         var adrenaline          : float;
  6707.         var costReduction       : SAbilityAttributeValue;
  6708.         // modMetabolismBoostPatch
  6709.        
  6710.         if(itemId != GetInvalidUniqueId())
  6711.             item = itemId;
  6712.         else
  6713.             item = itemSlots[slotid];
  6714.        
  6715.         inv.GetPotionItemBuffData(item, effectType, customAbilityName);
  6716.         maxTox = abilityManager.GetStatMax(BCS_Toxicity);
  6717.         potionToxicity = CalculateAttributeValue(inv.GetItemAttributeValue(item, 'toxicity'));
  6718.         toxicityOffset = CalculateAttributeValue(inv.GetItemAttributeValue(item, 'toxicity_offset'));
  6719.  
  6720.         // modMetabolismBoostPatch
  6721.         if(CanUseSkill(S_Perk_13))
  6722.         {
  6723.             costReduction = GetSkillAttributeValue(S_Perk_13, 'cost_reduction', false, true);
  6724.             adrenaline = FloorF(GetStat(BCS_Focus));
  6725.             costReduction = costReduction * adrenaline;
  6726.             potionToxicity = potionToxicity * (1.0f - costReduction.valueMultiplicative);
  6727.             potionToxicity = MaxF(0.f, potionToxicity);
  6728.         }
  6729.         // modMetabolismBoostPatch
  6730.        
  6731.         if(effectType != EET_WhiteHoney)
  6732.         {
  6733.             if(abilityManager.GetStat(BCS_Toxicity, false) + potionToxicity + toxicityOffset > maxTox )
  6734.             {
  6735.                 return false;
  6736.             }
  6737.         }
  6738.        
  6739.         return true;
  6740.     }
  6741.    
  6742.     // modMetabolismBoostPatch
  6743.     public final function HasFreeToxicityToDrinkPotion( item : SItemUniqueId, effectType : EEffectType, out finalPotionToxicity : float, out usedAdrenaline : float ) : bool
  6744.     // modMetabolismBoostPatch
  6745.     {
  6746.         var i : int;
  6747.         var maxTox, toxicityOffset, adrenaline : float;
  6748.         var costReduction : SAbilityAttributeValue;
  6749.  
  6750.         // modMetabolismBoostPatch
  6751.         usedAdrenaline = 0.f;
  6752.         // modMetabolismBoostPatch
  6753.        
  6754.         if( effectType == EET_WhiteHoney )
  6755.         {
  6756.             return true;
  6757.         }
  6758.        
  6759.        
  6760.         maxTox = abilityManager.GetStatMax(BCS_Toxicity);
  6761.         finalPotionToxicity = CalculateAttributeValue(inv.GetItemAttributeValue(item, 'toxicity'));
  6762.         toxicityOffset = CalculateAttributeValue(inv.GetItemAttributeValue(item, 'toxicity_offset'));
  6763.        
  6764.         // modMetabolismBoostPatch
  6765.         if(abilityManager.GetStat(BCS_Toxicity, false) + finalPotionToxicity + toxicityOffset <= maxTox )
  6766.         {
  6767.             return true;
  6768.         }
  6769.         // modMetabolismBoostPatch
  6770.        
  6771.         if(CanUseSkill(S_Perk_13))
  6772.         {
  6773.             costReduction = GetSkillAttributeValue(S_Perk_13, 'cost_reduction', false, true);
  6774.             adrenaline = FloorF(GetStat(BCS_Focus));
  6775.             costReduction = costReduction * adrenaline;
  6776.             // modMetabolismBoostPatch
  6777.             finalPotionToxicity = finalPotionToxicity * (1.0f - costReduction.valueMultiplicative);
  6778.             // modMetabolismBoostPatch
  6779.             finalPotionToxicity = MaxF(0.f, finalPotionToxicity);
  6780.         }
  6781.        
  6782.        
  6783.         if(abilityManager.GetStat(BCS_Toxicity, false) + finalPotionToxicity + toxicityOffset > maxTox )
  6784.         {
  6785.             return false;
  6786.         }
  6787.        
  6788.         // modMetabolismBoostPatch
  6789.         usedAdrenaline = adrenaline;
  6790.         // modMetabolismBoostPatch
  6791.         return true;
  6792.     }
  6793.    
  6794.     public function DrinkPreparedPotion( slotid : EEquipmentSlots, optional itemId : SItemUniqueId )
  6795.     {  
  6796.         var potParams : W3PotionParams;
  6797.         var potionParams : SCustomEffectParams;
  6798.         var factPotionParams : W3Potion_Fact_Params;
  6799.         var adrenaline, hpGainValue, duration, finalPotionToxicity : float;
  6800.         var ret : EEffectInteract;
  6801.         var effectType : EEffectType;
  6802.         var item : SItemUniqueId;
  6803.         var customAbilityName, factId : name;
  6804.         var atts : array<name>;
  6805.         var i : int;
  6806.         var mutagenParams : W3MutagenBuffCustomParams;
  6807.        
  6808.        
  6809.         if(itemId != GetInvalidUniqueId())
  6810.             item = itemId;
  6811.         else
  6812.             item = itemSlots[slotid];
  6813.        
  6814.        
  6815.         if(!inv.IsIdValid(item))
  6816.             return;
  6817.            
  6818.        
  6819.         if( inv.SingletonItemGetAmmo(item) == 0 )
  6820.             return;
  6821.            
  6822.        
  6823.         inv.GetPotionItemBuffData(item, effectType, customAbilityName);
  6824.            
  6825.        
  6826.         // modMetabolismBoostPatch
  6827.         if( !HasFreeToxicityToDrinkPotion( item, effectType, finalPotionToxicity, adrenaline ) )
  6828.         // modMetabolismBoostPatch
  6829.         {
  6830.             return;
  6831.         }
  6832.                
  6833.        
  6834.         if(effectType == EET_Fact)
  6835.         {
  6836.             inv.GetItemAttributes(item, atts);
  6837.            
  6838.             for(i=0; i<atts.Size(); i+=1)
  6839.             {
  6840.                 if(StrBeginsWith(NameToString(atts[i]), "fact_"))
  6841.                 {
  6842.                     factId = atts[i];
  6843.                     break;
  6844.                 }
  6845.             }
  6846.            
  6847.             factPotionParams = new W3Potion_Fact_Params in theGame;
  6848.             factPotionParams.factName = factId;
  6849.             factPotionParams.potionItemName = inv.GetItemName(item);
  6850.            
  6851.             potionParams.buffSpecificParams = factPotionParams;
  6852.         }
  6853.        
  6854.         else if(inv.ItemHasTag( item, 'Mutagen' ))
  6855.         {
  6856.             mutagenParams = new W3MutagenBuffCustomParams in theGame;
  6857.             mutagenParams.toxicityOffset = CalculateAttributeValue(inv.GetItemAttributeValue(item, 'toxicity_offset'));
  6858.             mutagenParams.potionItemName = inv.GetItemName(item);
  6859.            
  6860.             potionParams.buffSpecificParams = mutagenParams;
  6861.            
  6862.             if( IsMutationActive( EPMT_Mutation10 ) && !HasBuff( EET_Mutation10 ) )
  6863.             {
  6864.                 AddEffectDefault( EET_Mutation10, this, "Mutation 10" );
  6865.             }
  6866.         }
  6867.        
  6868.         else
  6869.         {
  6870.             potParams = new W3PotionParams in theGame;
  6871.             potParams.potionItemName = inv.GetItemName(item);
  6872.            
  6873.             potionParams.buffSpecificParams = potParams;
  6874.         }
  6875.    
  6876.        
  6877.         duration = CalculatePotionDuration(item, inv.ItemHasTag( item, 'Mutagen' ));       
  6878.  
  6879.        
  6880.         potionParams.effectType = effectType;
  6881.         potionParams.creator = this;
  6882.         potionParams.sourceName = "drank_potion";
  6883.         potionParams.duration = duration;
  6884.         potionParams.customAbilityName = customAbilityName;
  6885.         ret = AddEffectCustom(potionParams);
  6886.  
  6887.        
  6888.         if(factPotionParams)
  6889.             delete factPotionParams;
  6890.            
  6891.         if(mutagenParams)
  6892.             delete mutagenParams;
  6893.            
  6894.        
  6895.         inv.SingletonItemRemoveAmmo(item);
  6896.        
  6897.        
  6898.         if(ret == EI_Pass || ret == EI_Override || ret == EI_Cumulate)
  6899.         {
  6900.             if( finalPotionToxicity > 0.f )
  6901.             {
  6902.                 abilityManager.GainStat(BCS_Toxicity, finalPotionToxicity );
  6903.             }
  6904.            
  6905.             // modMetabolismBoostPatch
  6906.             if(CanUseSkill(S_Perk_13) && adrenaline > 0.f)
  6907.             // modMetabolismBoostPatch
  6908.             {
  6909.                 abilityManager.DrainFocus(adrenaline);
  6910.             }
  6911.            
  6912.             if (!IsEffectActive('invisible'))
  6913.             {
  6914.                 PlayEffect('use_potion');
  6915.             }
  6916.            
  6917.             if ( inv.ItemHasTag( item, 'Mutagen' ) )
  6918.             {
  6919.                
  6920.                 theGame.GetGamerProfile().CheckTrialOfGrasses();
  6921.                
  6922.                
  6923.                 SetFailedFundamentalsFirstAchievementCondition(true);
  6924.             }
  6925.            
  6926.            
  6927.             if(CanUseSkill(S_Alchemy_s02))
  6928.             {
  6929.                 hpGainValue = ClampF(GetStatMax(BCS_Vitality) * CalculateAttributeValue(GetSkillAttributeValue(S_Alchemy_s02, 'vitality_gain_perc', false, true)) * GetSkillLevel(S_Alchemy_s02), 0, GetStatMax(BCS_Vitality));
  6930.                 GainStat(BCS_Vitality, hpGainValue);
  6931.             }          
  6932.            
  6933.            
  6934.             if(CanUseSkill(S_Alchemy_s04) && !skillBonusPotionEffect && (RandF() < CalculateAttributeValue(GetSkillAttributeValue(S_Alchemy_s04, 'apply_chance', false, true)) * GetSkillLevel(S_Alchemy_s04)))
  6935.             {
  6936.                 AddRandomPotionEffectFromAlch4Skill( effectType );             
  6937.             }
  6938.            
  6939.             theGame.GetGamerProfile().SetStat(ES_ActivePotions, effectManager.GetPotionBuffsCount());
  6940.         }
  6941.        
  6942.         theTelemetry.LogWithLabel(TE_ELIXIR_USED, inv.GetItemName(item));
  6943.        
  6944.         if(ShouldProcessTutorial('TutorialPotionAmmo'))
  6945.         {
  6946.             FactsAdd("tut_used_potion");
  6947.         }
  6948.        
  6949.         SetFailedFundamentalsFirstAchievementCondition(true);
  6950.     }
  6951.    
  6952.    
  6953.     private final function AddRandomPotionEffectFromAlch4Skill( currentlyDrankPotion : EEffectType )
  6954.     {
  6955.         var randomPotions : array<EEffectType>;
  6956.         var currentPotion : CBaseGameplayEffect;
  6957.         var effectsOld, effectsNew : array<CBaseGameplayEffect>;
  6958.         var i, ind : int;
  6959.         var duration : float;
  6960.         var params : SCustomEffectParams;
  6961.         var ret : EEffectInteract;
  6962.        
  6963.        
  6964.         randomPotions.PushBack( EET_BlackBlood );
  6965.         randomPotions.PushBack( EET_Blizzard );
  6966.         randomPotions.PushBack( EET_FullMoon );
  6967.         randomPotions.PushBack( EET_GoldenOriole );
  6968.         randomPotions.PushBack( EET_KillerWhale );
  6969.         randomPotions.PushBack( EET_MariborForest );
  6970.         randomPotions.PushBack( EET_PetriPhiltre );
  6971.         randomPotions.PushBack( EET_Swallow );
  6972.         randomPotions.PushBack( EET_TawnyOwl );
  6973.         randomPotions.PushBack( EET_Thunderbolt );
  6974.        
  6975.        
  6976.         randomPotions.Remove( currentlyDrankPotion );
  6977.        
  6978.        
  6979.         ind = RandRange( randomPotions.Size() );
  6980.  
  6981.        
  6982.         if( HasBuff( randomPotions[ ind ] ) )
  6983.         {
  6984.             currentPotion = GetBuff( randomPotions[ ind ] );
  6985.             currentPotion.SetTimeLeft( currentPotion.GetInitialDurationAfterResists() );
  6986.         }
  6987.        
  6988.         else
  6989.         {          
  6990.             duration = BonusPotionGetDurationFromXML( randomPotions[ ind ] );
  6991.            
  6992.             if(duration > 0)
  6993.             {
  6994.                 effectsOld = GetCurrentEffects();
  6995.                                    
  6996.                 params.effectType = randomPotions[ ind ];
  6997.                 params.creator = this;
  6998.                 params.sourceName = SkillEnumToName( S_Alchemy_s04 );
  6999.                 params.duration = duration;
  7000.                 ret = AddEffectCustom( params );
  7001.                
  7002.                
  7003.                 if( ret != EI_Undefined && ret != EI_Deny )
  7004.                 {
  7005.                     effectsNew = GetCurrentEffects();
  7006.                    
  7007.                     ind = -1;
  7008.                     for( i=effectsNew.Size()-1; i>=0; i-=1)
  7009.                     {
  7010.                         if( !effectsOld.Contains( effectsNew[i] ) )
  7011.                         {
  7012.                             ind = i;
  7013.                             break;
  7014.                         }
  7015.                     }
  7016.                    
  7017.                     if(ind > -1)
  7018.                     {
  7019.                         skillBonusPotionEffect = effectsNew[ind];
  7020.                     }
  7021.                 }
  7022.             }      
  7023.         }
  7024.     }
  7025.    
  7026.    
  7027.     private function BonusPotionGetDurationFromXML(type : EEffectType) : float
  7028.     {
  7029.         var dm : CDefinitionsManagerAccessor;
  7030.         var main, ingredients : SCustomNode;
  7031.         var tmpName, typeName, itemName : name;
  7032.         var abs : array<name>;
  7033.         var min, max : SAbilityAttributeValue;
  7034.         var tmpInt : int;
  7035.         var temp                                : array<float>;
  7036.         var i, temp2, temp3 : int;
  7037.                        
  7038.         dm = theGame.GetDefinitionsManager();
  7039.         main = dm.GetCustomDefinition('alchemy_recipes');
  7040.         typeName = EffectTypeToName(type);
  7041.        
  7042.        
  7043.         for(i=0; i<main.subNodes.Size(); i+=1)
  7044.         {
  7045.             if(dm.GetCustomNodeAttributeValueName(main.subNodes[i], 'type_name', tmpName))
  7046.             {
  7047.                
  7048.                 if(tmpName == typeName)
  7049.                 {
  7050.                     if(dm.GetCustomNodeAttributeValueInt(main.subNodes[i], 'level', tmpInt))
  7051.                     {
  7052.                        
  7053.                         if(tmpInt == 1)
  7054.                         {
  7055.                             if(dm.GetCustomNodeAttributeValueName(main.subNodes[i], 'cookedItem_name', itemName))
  7056.                             {
  7057.                                
  7058.                                 if(IsNameValid(itemName))
  7059.                                 {
  7060.                                     break;
  7061.                                 }
  7062.                             }
  7063.                         }
  7064.                     }
  7065.                 }
  7066.             }
  7067.         }
  7068.        
  7069.         if(!IsNameValid(itemName))
  7070.             return 0;
  7071.        
  7072.        
  7073.         dm.GetItemAbilitiesWithWeights(itemName, true, abs, temp, temp2, temp3);
  7074.         dm.GetAbilitiesAttributeValue(abs, 'duration', min, max);                      
  7075.         return CalculateAttributeValue(GetAttributeRandomizedValue(min, max));
  7076.     }
  7077.    
  7078.     public function ClearSkillBonusPotionEffect()
  7079.     {
  7080.         skillBonusPotionEffect = NULL;
  7081.     }
  7082.    
  7083.     public function GetSkillBonusPotionEffect() : CBaseGameplayEffect
  7084.     {
  7085.         return skillBonusPotionEffect;
  7086.     }
  7087.    
  7088.    
  7089.    
  7090.    
  7091.    
  7092.    
  7093.    
  7094.     public final function HasRunewordActive(abilityName : name) : bool
  7095.     {
  7096.         var item : SItemUniqueId;
  7097.         var hasRuneword : bool;
  7098.        
  7099.         if(GetItemEquippedOnSlot(EES_SteelSword, item))
  7100.         {
  7101.             hasRuneword = inv.ItemHasAbility(item, abilityName);               
  7102.         }
  7103.        
  7104.         if(!hasRuneword)
  7105.         {
  7106.             if(GetItemEquippedOnSlot(EES_SilverSword, item))
  7107.             {
  7108.                 hasRuneword = inv.ItemHasAbility(item, abilityName);
  7109.             }
  7110.         }
  7111.        
  7112.         return hasRuneword;
  7113.     }
  7114.    
  7115.     public final function GetShrineBuffs() : array<CBaseGameplayEffect>
  7116.     {
  7117.         var null : array<CBaseGameplayEffect>;
  7118.        
  7119.         if(effectManager && effectManager.IsReady())
  7120.             return effectManager.GetShrineBuffs();
  7121.            
  7122.         return null;
  7123.     }
  7124.    
  7125.     public final function AddRepairObjectBuff(armor : bool, weapon : bool) : bool
  7126.     {
  7127.         var added : bool;
  7128.        
  7129.         added = false;
  7130.        
  7131.         if(weapon && (IsAnyItemEquippedOnSlot(EES_SilverSword) || IsAnyItemEquippedOnSlot(EES_SteelSword)) )
  7132.         {
  7133.             AddEffectDefault(EET_EnhancedWeapon, this, "repair_object", false);
  7134.             added = true;
  7135.         }
  7136.        
  7137.         if(armor && (IsAnyItemEquippedOnSlot(EES_Armor) || IsAnyItemEquippedOnSlot(EES_Gloves) || IsAnyItemEquippedOnSlot(EES_Boots) || IsAnyItemEquippedOnSlot(EES_Pants)) )
  7138.         {
  7139.             AddEffectDefault(EET_EnhancedArmor, this, "repair_object", false);
  7140.             added = true;
  7141.         }
  7142.        
  7143.         return added;
  7144.     }
  7145.    
  7146.    
  7147.     public function StartCSAnim(buff : CBaseGameplayEffect) : bool
  7148.     {
  7149.        
  7150.         if(IsAnyQuenActive() && (W3CriticalDOTEffect)buff)
  7151.             return false;
  7152.            
  7153.         return super.StartCSAnim(buff);
  7154.     }
  7155.    
  7156.     public function GetPotionBuffLevel(effectType : EEffectType) : int
  7157.     {
  7158.         if(effectManager && effectManager.IsReady())
  7159.             return effectManager.GetPotionBuffLevel(effectType);
  7160.            
  7161.         return 0;
  7162.     }  
  7163.  
  7164.    
  7165.    
  7166.    
  7167.    
  7168.    
  7169.    
  7170.     event OnLevelGained(currentLevel : int, show : bool)
  7171.     {
  7172.         var hud : CR4ScriptedHud;
  7173.         hud = (CR4ScriptedHud)theGame.GetHud();
  7174.        
  7175.         if(abilityManager && abilityManager.IsInitialized())
  7176.         {
  7177.             ((W3PlayerAbilityManager)abilityManager).OnLevelGained(currentLevel);
  7178.         }
  7179.        
  7180.         if ( theGame.GetDifficultyMode() != EDM_Hardcore )
  7181.         {
  7182.             Heal(GetStatMax(BCS_Vitality));
  7183.         }
  7184.    
  7185.        
  7186.         if(currentLevel >= 35)
  7187.         {
  7188.             theGame.GetGamerProfile().AddAchievement(EA_Immortal);
  7189.         }
  7190.    
  7191.         if ( hud && currentLevel < levelManager.GetMaxLevel() && FactsQuerySum( "DebugNoLevelUpUpdates" ) == 0 )
  7192.         {
  7193.             hud.OnLevelUpUpdate(currentLevel, show);
  7194.         }
  7195.        
  7196.         theGame.RequestAutoSave( "level gained", false );
  7197.     }
  7198.    
  7199.     public function GetSignStats(skill : ESkill, out damageType : name, out damageVal : float, out spellPower : SAbilityAttributeValue)
  7200.     {
  7201.         var i, size : int;
  7202.         var dm : CDefinitionsManagerAccessor;
  7203.         var attrs : array<name>;
  7204.    
  7205.         spellPower = GetPowerStatValue(CPS_SpellPower);
  7206.        
  7207.         dm = theGame.GetDefinitionsManager();
  7208.         dm.GetAbilityAttributes(GetSkillAbilityName(skill), attrs);
  7209.         size = attrs.Size();
  7210.        
  7211.         for( i = 0; i < size; i += 1 )
  7212.         {
  7213.             if( IsDamageTypeNameValid(attrs[i]) )
  7214.             {
  7215.                 damageVal = CalculateAttributeValue(GetSkillAttributeValue(skill, attrs[i], false, true));
  7216.                 damageType = attrs[i];
  7217.                 break;
  7218.             }
  7219.         }
  7220.     }
  7221.        
  7222.    
  7223.     public function SetIgnorePainMaxVitality(val : float)
  7224.     {
  7225.         if(abilityManager && abilityManager.IsInitialized())
  7226.             abilityManager.SetStatPointMax(BCS_Vitality, val);
  7227.     }
  7228.    
  7229.     event OnAnimEvent_ActionBlend( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  7230.     {
  7231.         if ( animEventType == AET_DurationStart && !disableActionBlend )
  7232.         {
  7233.             if ( this.IsCastingSign() )
  7234.                 ProcessSignEvent( 'cast_end' );
  7235.            
  7236.            
  7237.             FindMoveTarget();
  7238.             SetCanPlayHitAnim( true );
  7239.             this.SetBIsCombatActionAllowed( true );
  7240.            
  7241.             if ( this.GetFinisherVictim() && this.GetFinisherVictim().HasAbility( 'ForceFinisher' ) && !isInFinisher )
  7242.             {
  7243.                 this.GetFinisherVictim().SignalGameplayEvent( 'Finisher' );
  7244.             }
  7245.             else if (this.BufferCombatAction != EBAT_EMPTY )
  7246.             {
  7247.                
  7248.                
  7249.                    
  7250.                     if ( !IsCombatMusicEnabled() )
  7251.                     {
  7252.                         SetCombatActionHeading( ProcessCombatActionHeading( this.BufferCombatAction ) );
  7253.                         FindTarget();
  7254.                         UpdateDisplayTarget( true );
  7255.                     }
  7256.            
  7257.                     if ( AllowAttack( GetTarget(), this.BufferCombatAction ) )
  7258.                         this.ProcessCombatActionBuffer();
  7259.             }
  7260.             else
  7261.             {
  7262.                
  7263.                 ResumeStaminaRegen( 'InsideCombatAction' );
  7264.                
  7265.                
  7266.                
  7267.             }
  7268.         }
  7269.         else if ( disableActionBlend )
  7270.         {
  7271.             disableActionBlend = false;
  7272.         }
  7273.     }
  7274.    
  7275.    
  7276.     event OnAnimEvent_Sign( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  7277.     {
  7278.         if( animEventType == AET_Tick )
  7279.         {
  7280.             ProcessSignEvent( animEventName );
  7281.         }
  7282.     }
  7283.    
  7284.     event OnAnimEvent_Throwable( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  7285.     {
  7286.         var thrownEntity        : CThrowable;  
  7287.        
  7288.         thrownEntity = (CThrowable)EntityHandleGet( thrownEntityHandle );
  7289.            
  7290.         if ( inv.IsItemCrossbow( inv.GetItemFromSlot('l_weapon') ) &&  rangedWeapon.OnProcessThrowEvent( animEventName ) )
  7291.         {      
  7292.             return true;
  7293.         }
  7294.         else if( thrownEntity && IsThrowingItem() && thrownEntity.OnProcessThrowEvent( animEventName ) )
  7295.         {
  7296.             return true;
  7297.         }
  7298.     }
  7299.    
  7300.     event OnTaskSyncAnim( npc : CNewNPC, animNameLeft : name )
  7301.     {
  7302.         var tmpBool : bool;
  7303.         var tmpName : name;
  7304.         var damage, points, resistance : float;
  7305.         var min, max : SAbilityAttributeValue;
  7306.         var mc : EMonsterCategory;
  7307.        
  7308.         super.OnTaskSyncAnim( npc, animNameLeft );
  7309.        
  7310.         if( animNameLeft == 'BruxaBite' && IsMutationActive( EPMT_Mutation4 ) )
  7311.         {
  7312.             theGame.GetMonsterParamsForActor( npc, mc, tmpName, tmpBool, tmpBool, tmpBool );
  7313.            
  7314.             if( mc == MC_Vampire )
  7315.             {
  7316.                 GetResistValue( CDS_BleedingRes, points, resistance );
  7317.                
  7318.                 theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'BleedingEffect', 'DirectDamage', min, max );
  7319.                 damage = MaxF( 0.f, max.valueMultiplicative * GetMaxHealth() - points );
  7320.                
  7321.                 theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'BleedingEffect', 'duration', min, max );
  7322.                 damage *= min.valueAdditive * ( 1 - MinF( 1.f, resistance ) );
  7323.                
  7324.                 if( damage > 0.f )
  7325.                 {
  7326.                     npc.AddAbility( 'Mutation4BloodDebuff' );
  7327.                     ProcessActionMutation4ReturnedDamage( damage, npc, EAHA_ForceNo );                 
  7328.                     npc.AddTimer( 'RemoveMutation4BloodDebuff', 15.f, , , , , true );
  7329.                 }
  7330.             }
  7331.         }
  7332.     }
  7333.    
  7334.    
  7335.     public function ProcessActionMutation4ReturnedDamage( damageDealt : float, attacker : CActor, hitAnimationType : EActionHitAnim, optional action : W3DamageAction ) : bool
  7336.     {
  7337.         var customParams                : SCustomEffectParams;
  7338.         var currToxicity                : float;
  7339.         var min, max, customDamageValue : SAbilityAttributeValue;
  7340.         var dm                          : CDefinitionsManagerAccessor;
  7341.         var animAction                  : W3DamageAction;
  7342.  
  7343.         if( damageDealt <= 0 )
  7344.         {
  7345.             return false;
  7346.         }
  7347.        
  7348.         if( action )
  7349.         {
  7350.             action.SetMutation4Triggered();
  7351.         }
  7352.            
  7353.         dm = theGame.GetDefinitionsManager();
  7354.         currToxicity = GetStat( BCS_Toxicity );
  7355.        
  7356.         dm.GetAbilityAttributeValue( 'AcidEffect', 'DirectDamage', min, max );
  7357.         customDamageValue.valueAdditive = damageDealt * min.valueAdditive;
  7358.        
  7359.         if( currToxicity > 0 )
  7360.         {
  7361.             customDamageValue.valueAdditive *= currToxicity;
  7362.         }
  7363.        
  7364.         dm.GetAbilityAttributeValue( 'AcidEffect', 'duration', min, max );
  7365.         customDamageValue.valueAdditive /= min.valueAdditive;
  7366.        
  7367.         customParams.effectType = EET_Acid;
  7368.         customParams.effectValue = customDamageValue;
  7369.         customParams.duration = min.valueAdditive;
  7370.         customParams.creator = this;
  7371.         customParams.sourceName = 'Mutation4';
  7372.        
  7373.         attacker.AddEffectCustom( customParams );
  7374.        
  7375.        
  7376.         animAction = new W3DamageAction in theGame;
  7377.         animAction.Initialize( this, attacker, NULL, 'Mutation4', EHRT_Reflect, CPS_Undefined, true, false, false, false );
  7378.         animAction.SetCannotReturnDamage( true );
  7379.         animAction.SetCanPlayHitParticle( false );
  7380.         animAction.SetHitAnimationPlayType( hitAnimationType );
  7381.         theGame.damageMgr.ProcessAction( animAction );
  7382.         delete animAction;
  7383.        
  7384.         theGame.MutationHUDFeedback( MFT_PlayOnce );
  7385.        
  7386.         return true;
  7387.     }
  7388.    
  7389.     event OnPlayerActionEnd()
  7390.     {
  7391.         var l_i             : int;
  7392.         var l_bed           : W3WitcherBed;
  7393.        
  7394.         l_i = (int)GetBehaviorVariable( 'playerExplorationAction' );
  7395.        
  7396.         if( l_i == PEA_GoToSleep )
  7397.         {
  7398.             l_bed = (W3WitcherBed)theGame.GetEntityByTag( 'witcherBed' );
  7399.             BlockAllActions( 'WitcherBed', false );
  7400.             l_bed.ApplyAppearance( "collision" );
  7401.             l_bed.GotoState( 'WakeUp' );
  7402.             theGame.ReleaseNoSaveLock( l_bed.m_bedSaveLock );
  7403.            
  7404.            
  7405.             substateManager.m_MovementCorrectorO.disallowRotWhenGoingToSleep = false;
  7406.         }
  7407.        
  7408.         super.OnPlayerActionEnd();
  7409.     }
  7410.    
  7411.     event OnPlayerActionStartFinished()
  7412.     {
  7413.         var l_initData          : W3SingleMenuInitData;    
  7414.         var l_i                 : int;
  7415.        
  7416.         l_i = (int)GetBehaviorVariable( 'playerExplorationAction' );
  7417.        
  7418.         if( l_i == PEA_GoToSleep )
  7419.         {
  7420.             l_initData = new W3SingleMenuInitData in this;
  7421.             l_initData.SetBlockOtherPanels( true );
  7422.             l_initData.ignoreSaveSystem = true;
  7423.             l_initData.ignoreMeditationCheck = true;
  7424.             l_initData.setDefaultState( '' );
  7425.             l_initData.isBonusMeditationAvailable = true;
  7426.             l_initData.fixedMenuName = 'MeditationClockMenu';
  7427.            
  7428.             theGame.RequestMenuWithBackground( 'MeditationClockMenu', 'CommonMenu', l_initData );
  7429.         }
  7430.        
  7431.         super.OnPlayerActionStartFinished();
  7432.     }
  7433.    
  7434.     public function IsInCombatAction_SpecialAttack() : bool
  7435.     {
  7436.         if ( IsInCombatAction() && ( GetCombatAction() == EBAT_SpecialAttack_Light || GetCombatAction() == EBAT_SpecialAttack_Heavy ) )
  7437.             return true;
  7438.         else
  7439.             return false;
  7440.     }
  7441.    
  7442.     public function IsInCombatAction_SpecialAttackHeavy() : bool
  7443.     {
  7444.         if ( IsInCombatAction() && GetCombatAction() == EBAT_SpecialAttack_Heavy )
  7445.             return true;
  7446.         else
  7447.             return false;
  7448.     }
  7449.    
  7450.     protected function WhenCombatActionIsFinished()
  7451.     {
  7452.         super.WhenCombatActionIsFinished();
  7453.         RemoveTimer( 'ProcessAttackTimer' );
  7454.         RemoveTimer( 'AttackTimerEnd' );
  7455.         CastSignAbort();
  7456.         specialAttackCamera = false;
  7457.         this.OnPerformSpecialAttack( true, false );
  7458.     }
  7459.    
  7460.     event OnCombatActionEnd()
  7461.     {
  7462.         this.CleanCombatActionBuffer();    
  7463.         super.OnCombatActionEnd();
  7464.        
  7465.         RemoveTemporarySkills();
  7466.     }
  7467.    
  7468.     event OnCombatActionFriendlyEnd()
  7469.     {
  7470.         if ( IsCastingSign() )
  7471.         {
  7472.             SetBehaviorVariable( 'IsCastingSign', 0 );
  7473.             SetCurrentlyCastSign( ST_None, NULL );
  7474.             LogChannel( 'ST_None', "ST_None" );                
  7475.         }
  7476.  
  7477.         super.OnCombatActionFriendlyEnd();
  7478.     }
  7479.    
  7480.     public function GetPowerStatValue( stat : ECharacterPowerStats, optional ablName : name, optional ignoreDeath : bool ) : SAbilityAttributeValue
  7481.     {
  7482.         var result :  SAbilityAttributeValue;
  7483.        
  7484.        
  7485.         result = super.GetPowerStatValue( stat, ablName, ignoreDeath );
  7486.         if( !IsNameValid(ablName) && stat != CPS_Undefined )
  7487.             ApplyMutation10StatBoost( result );
  7488.        
  7489.         return result;
  7490.     }
  7491.    
  7492.    
  7493.    
  7494.     timer function OpenRadialMenu( time: float, id : int )
  7495.     {
  7496.        
  7497.         if( GetBIsCombatActionAllowed() && !IsUITakeInput() )
  7498.         {
  7499.             bShowRadialMenu = true;
  7500.         }
  7501.        
  7502.         this.RemoveTimer('OpenRadialMenu');
  7503.     }
  7504.    
  7505.     public function OnAddRadialMenuOpenTimer(  )
  7506.     {
  7507.        
  7508.        
  7509.        
  7510.            
  7511.            
  7512.             this.AddTimer('OpenRadialMenu', _HoldBeforeOpenRadialMenuTime * theGame.GetTimeScale() );
  7513.        
  7514.     }
  7515.  
  7516.     public function SetShowRadialMenuOpenFlag( bSet : bool  )
  7517.     {
  7518.        
  7519.         bShowRadialMenu = bSet;
  7520.     }
  7521.    
  7522.     public function OnRemoveRadialMenuOpenTimer()
  7523.     {
  7524.        
  7525.         this.RemoveTimer('OpenRadialMenu');
  7526.     }
  7527.    
  7528.     public function ResetRadialMenuOpenTimer()
  7529.     {
  7530.        
  7531.         this.RemoveTimer('OpenRadialMenu');
  7532.         if( GetBIsCombatActionAllowed() )
  7533.         {
  7534.            
  7535.            
  7536.             AddTimer('OpenRadialMenu', _HoldBeforeOpenRadialMenuTime * theGame.GetTimeScale() );
  7537.         }
  7538.     }
  7539.  
  7540.    
  7541.    
  7542.     timer function ResendCompanionDisplayName(dt : float, id : int)
  7543.     {
  7544.         var hud : CR4ScriptedHud;
  7545.         var companionModule : CR4HudModuleCompanion;
  7546.        
  7547.         hud = (CR4ScriptedHud)theGame.GetHud();
  7548.         if( hud )
  7549.         {
  7550.             companionModule = (CR4HudModuleCompanion)hud.GetHudModule("CompanionModule");
  7551.             if( companionModule )
  7552.             {
  7553.                 companionModule.ResendDisplayName();
  7554.             }
  7555.         }
  7556.     }
  7557.  
  7558.     timer function ResendCompanionDisplayNameSecond(dt : float, id : int)
  7559.     {
  7560.         var hud : CR4ScriptedHud;
  7561.         var companionModule : CR4HudModuleCompanion;
  7562.        
  7563.         hud = (CR4ScriptedHud)theGame.GetHud();
  7564.         if( hud )
  7565.         {
  7566.             companionModule = (CR4HudModuleCompanion)hud.GetHudModule("CompanionModule");
  7567.             if( companionModule )
  7568.             {
  7569.                 companionModule.ResendDisplayNameSecond();
  7570.             }
  7571.         }
  7572.     }
  7573.    
  7574.     public function RemoveCompanionDisplayNameTimer()
  7575.     {
  7576.         this.RemoveTimer('ResendCompanionDisplayName');
  7577.     }
  7578.        
  7579.     public function RemoveCompanionDisplayNameTimerSecond()
  7580.     {
  7581.         this.RemoveTimer('ResendCompanionDisplayNameSecond');
  7582.     }
  7583.    
  7584.        
  7585.     public function GetCompanionNPCTag() : name
  7586.     {
  7587.         return companionNPCTag;
  7588.     }
  7589.  
  7590.     public function SetCompanionNPCTag( value : name )
  7591.     {
  7592.         companionNPCTag = value;
  7593.     }  
  7594.  
  7595.     public function GetCompanionNPCTag2() : name
  7596.     {
  7597.         return companionNPCTag2;
  7598.     }
  7599.  
  7600.     public function SetCompanionNPCTag2( value : name )
  7601.     {
  7602.         companionNPCTag2 = value;
  7603.     }
  7604.  
  7605.     public function GetCompanionNPCIconPath() : string
  7606.     {
  7607.         return companionNPCIconPath;
  7608.     }
  7609.  
  7610.     public function SetCompanionNPCIconPath( value : string )
  7611.     {
  7612.         companionNPCIconPath = value;
  7613.     }
  7614.  
  7615.     public function GetCompanionNPCIconPath2() : string
  7616.     {
  7617.         return companionNPCIconPath2;
  7618.     }
  7619.  
  7620.     public function SetCompanionNPCIconPath2( value : string )
  7621.     {
  7622.         companionNPCIconPath2 = value;
  7623.     }
  7624.    
  7625.    
  7626.  
  7627.     public function ReactToBeingHit(damageAction : W3DamageAction, optional buffNotApplied : bool) : bool
  7628.     {
  7629.         var chance : float;
  7630.         var procQuen : W3SignEntity;
  7631.        
  7632.         if(!damageAction.IsDoTDamage() && damageAction.DealsAnyDamage())
  7633.         {
  7634.             if(inv.IsItemBomb(selectedItemId))
  7635.             {
  7636.                 BombThrowAbort();
  7637.             }
  7638.             else
  7639.             {
  7640.                
  7641.                 ThrowingAbort();
  7642.             }          
  7643.         }      
  7644.        
  7645.        
  7646.         if(damageAction.IsActionRanged())
  7647.         {
  7648.             chance = CalculateAttributeValue(GetAttributeValue('quen_chance_on_projectile'));
  7649.             if(chance > 0)
  7650.             {
  7651.                 chance = ClampF(chance, 0, 1);
  7652.                
  7653.                 if(RandF() < chance)
  7654.                 {
  7655.                     procQuen = (W3SignEntity)theGame.CreateEntity(signs[ST_Quen].template, GetWorldPosition(), GetWorldRotation() );
  7656.                     procQuen.Init(signOwner, signs[ST_Quen].entity, true );
  7657.                     procQuen.OnStarted();
  7658.                     procQuen.OnThrowing();
  7659.                     procQuen.OnEnded();
  7660.                 }
  7661.             }
  7662.         }
  7663.        
  7664.        
  7665.         if( !((W3Effect_Toxicity)damageAction.causer) )
  7666.             MeditationForceAbort(true);
  7667.        
  7668.        
  7669.         if(IsDoingSpecialAttack(false))
  7670.             damageAction.SetHitAnimationPlayType(EAHA_ForceNo);
  7671.        
  7672.         return super.ReactToBeingHit(damageAction, buffNotApplied);
  7673.     }
  7674.    
  7675.     protected function ShouldPauseHealthRegenOnHit() : bool
  7676.     {
  7677.        
  7678.         if( ( HasBuff( EET_Swallow ) && GetPotionBuffLevel( EET_Swallow ) >= 3 ) || HasBuff( EET_Runeword8 ) || HasBuff( EET_Mutation11Buff ) )
  7679.         {
  7680.             return false;
  7681.         }
  7682.            
  7683.         return true;
  7684.     }
  7685.        
  7686.     public function SetMappinToHighlight( mappinName : name, mappinState : bool )
  7687.     {
  7688.         var mappinDef : SHighlightMappin;
  7689.         mappinDef.MappinName = mappinName;
  7690.         mappinDef.MappinState = mappinState;
  7691.         MappinToHighlight.PushBack(mappinDef);
  7692.     }  
  7693.  
  7694.     public function ClearMappinToHighlight()
  7695.     {
  7696.         MappinToHighlight.Clear();
  7697.     }
  7698.    
  7699.     public function CastSignAbort()
  7700.     {
  7701.         if( currentlyCastSign != ST_None && signs[currentlyCastSign].entity)
  7702.         {
  7703.             signs[currentlyCastSign].entity.OnSignAborted();
  7704.         }
  7705.        
  7706.        
  7707.     }
  7708.    
  7709.     event OnBlockingSceneStarted( scene: CStoryScene )
  7710.     {
  7711.         var med : W3PlayerWitcherStateMeditationWaiting;
  7712.                
  7713.        
  7714.         med = (W3PlayerWitcherStateMeditationWaiting)GetCurrentState();
  7715.         if(med)
  7716.         {
  7717.             med.StopRequested(true);
  7718.         }
  7719.        
  7720.        
  7721.         super.OnBlockingSceneStarted( scene );
  7722.     }
  7723.    
  7724.    
  7725.    
  7726.    
  7727.    
  7728.     public function GetHorseManager() : W3HorseManager
  7729.     {
  7730.         return (W3HorseManager)EntityHandleGet( horseManagerHandle );
  7731.     }
  7732.    
  7733.    
  7734.     public function HorseEquipItem(horsesItemId : SItemUniqueId) : bool
  7735.     {
  7736.         var man : W3HorseManager;
  7737.        
  7738.         man = GetHorseManager();
  7739.         if(man)
  7740.             return man.EquipItem(horsesItemId) != GetInvalidUniqueId();
  7741.            
  7742.         return false;
  7743.     }
  7744.    
  7745.    
  7746.     public function HorseUnequipItem(slot : EEquipmentSlots) : bool
  7747.     {
  7748.         var man : W3HorseManager;
  7749.        
  7750.         man = GetHorseManager();
  7751.         if(man)
  7752.             return man.UnequipItem(slot) != GetInvalidUniqueId();
  7753.            
  7754.         return false;
  7755.     }
  7756.    
  7757.    
  7758.     public final function HorseRemoveItemByName(itemName : name, quantity : int)
  7759.     {
  7760.         var man : W3HorseManager;
  7761.        
  7762.         man = GetHorseManager();
  7763.         if(man)
  7764.             man.HorseRemoveItemByName(itemName, quantity);
  7765.     }
  7766.    
  7767.    
  7768.     public final function HorseRemoveItemByCategory(itemCategory : name, quantity : int)
  7769.     {
  7770.         var man : W3HorseManager;
  7771.        
  7772.         man = GetHorseManager();
  7773.         if(man)
  7774.             man.HorseRemoveItemByCategory(itemCategory, quantity);
  7775.     }
  7776.    
  7777.    
  7778.     public final function HorseRemoveItemByTag(itemTag : name, quantity : int)
  7779.     {
  7780.         var man : W3HorseManager;
  7781.        
  7782.         man = GetHorseManager();
  7783.         if(man)
  7784.             man.HorseRemoveItemByTag(itemTag, quantity);
  7785.     }
  7786.    
  7787.     public function GetAssociatedInventory() : CInventoryComponent
  7788.     {
  7789.         var man : W3HorseManager;
  7790.        
  7791.         man = GetHorseManager();
  7792.         if(man)
  7793.             return man.GetInventoryComponent();
  7794.            
  7795.         return NULL;
  7796.     }
  7797.    
  7798.    
  7799.    
  7800.    
  7801.    
  7802.     public final function TutorialMutagensUnequipPlayerSkills() : array<STutorialSavedSkill>
  7803.     {
  7804.         var pam : W3PlayerAbilityManager;
  7805.        
  7806.         pam = (W3PlayerAbilityManager)abilityManager;
  7807.         return pam.TutorialMutagensUnequipPlayerSkills();
  7808.     }
  7809.    
  7810.     public final function TutorialMutagensEquipOneGoodSkill()
  7811.     {
  7812.         var pam : W3PlayerAbilityManager;
  7813.        
  7814.         pam = (W3PlayerAbilityManager)abilityManager;
  7815.         pam.TutorialMutagensEquipOneGoodSkill();
  7816.     }
  7817.    
  7818.     public final function TutorialMutagensEquipOneGoodOneBadSkill()
  7819.     {
  7820.         var pam : W3PlayerAbilityManager;
  7821.        
  7822.         pam = (W3PlayerAbilityManager)abilityManager;
  7823.         if(pam)
  7824.             pam.TutorialMutagensEquipOneGoodOneBadSkill();
  7825.     }
  7826.    
  7827.     public final function TutorialMutagensEquipThreeGoodSkills()
  7828.     {
  7829.         var pam : W3PlayerAbilityManager;
  7830.        
  7831.         pam = (W3PlayerAbilityManager)abilityManager;
  7832.         if(pam)
  7833.             pam.TutorialMutagensEquipThreeGoodSkills();
  7834.     }
  7835.    
  7836.     public final function TutorialMutagensCleanupTempSkills(savedEquippedSkills : array<STutorialSavedSkill>)
  7837.     {
  7838.         var pam : W3PlayerAbilityManager;
  7839.        
  7840.         pam = (W3PlayerAbilityManager)abilityManager;
  7841.         return pam.TutorialMutagensCleanupTempSkills(savedEquippedSkills);
  7842.     }
  7843.    
  7844.    
  7845.    
  7846.    
  7847.    
  7848.     public final function CalculatedArmorStaminaRegenBonus() : float
  7849.     {
  7850.         var armorEq, glovesEq, pantsEq, bootsEq : bool;
  7851.         var tempItem : SItemUniqueId;
  7852.         var staminaRegenVal : float;
  7853.         var armorRegenVal : SAbilityAttributeValue;
  7854.        
  7855.         if( HasAbility( 'Glyphword 2 _Stats', true ) )
  7856.         {
  7857.             armorEq = inv.GetItemEquippedOnSlot( EES_Armor, tempItem );
  7858.             glovesEq = inv.GetItemEquippedOnSlot( EES_Gloves, tempItem );
  7859.             pantsEq = inv.GetItemEquippedOnSlot( EES_Pants, tempItem );
  7860.             bootsEq = inv.GetItemEquippedOnSlot( EES_Boots, tempItem );
  7861.            
  7862.             if ( armorEq )
  7863.                 staminaRegenVal += 0.1;
  7864.             if ( glovesEq )
  7865.                 staminaRegenVal += 0.02;
  7866.             if ( pantsEq )
  7867.                 staminaRegenVal += 0.1;
  7868.             if ( bootsEq )
  7869.                 staminaRegenVal += 0.03;
  7870.            
  7871.         }
  7872.         else if( HasAbility( 'Glyphword 3 _Stats', true ) )
  7873.         {
  7874.             staminaRegenVal = 0;
  7875.         }
  7876.         else if( HasAbility( 'Glyphword 4 _Stats', true ) )
  7877.         {
  7878.             armorEq = inv.GetItemEquippedOnSlot( EES_Armor, tempItem );
  7879.             glovesEq = inv.GetItemEquippedOnSlot( EES_Gloves, tempItem );
  7880.             pantsEq = inv.GetItemEquippedOnSlot( EES_Pants, tempItem );
  7881.             bootsEq = inv.GetItemEquippedOnSlot( EES_Boots, tempItem );
  7882.            
  7883.             if ( armorEq )
  7884.                 staminaRegenVal -= 0.1;
  7885.             if ( glovesEq )
  7886.                 staminaRegenVal -= 0.02;
  7887.             if ( pantsEq )
  7888.                 staminaRegenVal -= 0.1;
  7889.             if ( bootsEq )
  7890.                 staminaRegenVal -= 0.03;
  7891.         }
  7892.         else
  7893.         {
  7894.             armorRegenVal = GetAttributeValue('staminaRegen_armor_mod');
  7895.             staminaRegenVal = armorRegenVal.valueMultiplicative;
  7896.         }
  7897.        
  7898.         return staminaRegenVal;
  7899.     }
  7900.    
  7901.     public function GetOffenseStatsList( optional hackMode : int ) : SPlayerOffenseStats
  7902.     {
  7903.         var playerOffenseStats:SPlayerOffenseStats;
  7904.         var steelDmg, silverDmg, elementalSteel, elementalSilver : float;
  7905.         var steelCritChance, steelCritDmg : float;
  7906.         var silverCritChance, silverCritDmg : float;
  7907.         var attackPower : SAbilityAttributeValue;
  7908.         var fastCritChance, fastCritDmg : float;
  7909.         var strongCritChance, strongCritDmg : float;
  7910.         var fastAP, strongAP, min, max : SAbilityAttributeValue;
  7911.         var item, crossbow : SItemUniqueId;
  7912.         var value : SAbilityAttributeValue;
  7913.         var mutagen : CBaseGameplayEffect;
  7914.         var thunder : W3Potion_Thunderbolt;
  7915.        
  7916.         if(!abilityManager || !abilityManager.IsInitialized())
  7917.             return playerOffenseStats;
  7918.        
  7919.         if (CanUseSkill(S_Sword_s21))
  7920.             fastAP += GetSkillAttributeValue(S_Sword_s21, PowerStatEnumToName(CPS_AttackPower), false, true) * GetSkillLevel(S_Sword_s21);
  7921.         if (CanUseSkill(S_Perk_05))
  7922.         {
  7923.             fastAP += GetAttributeValue('attack_power_fast_style');
  7924.             fastCritDmg += CalculateAttributeValue(GetAttributeValue('critical_hit_chance_fast_style'));
  7925.             strongCritDmg += CalculateAttributeValue(GetAttributeValue('critical_hit_chance_fast_style'));
  7926.         }
  7927.         if (CanUseSkill(S_Sword_s04))
  7928.             strongAP += GetSkillAttributeValue(S_Sword_s04, PowerStatEnumToName(CPS_AttackPower), false, true) * GetSkillLevel(S_Sword_s04);
  7929.         if (CanUseSkill(S_Perk_07))
  7930.             strongAP += GetAttributeValue('attack_power_heavy_style');
  7931.            
  7932.         if (CanUseSkill(S_Sword_s17))
  7933.         {
  7934.             fastCritChance += CalculateAttributeValue(GetSkillAttributeValue(S_Sword_s17, theGame.params.CRITICAL_HIT_CHANCE, false, true)) * GetSkillLevel(S_Sword_s17);
  7935.             fastCritDmg += CalculateAttributeValue(GetSkillAttributeValue(S_Sword_s17, theGame.params.CRITICAL_HIT_DAMAGE_BONUS, false, true)) * GetSkillLevel(S_Sword_s17);
  7936.         }
  7937.        
  7938.         if (CanUseSkill(S_Sword_s08))
  7939.         {
  7940.             strongCritChance += CalculateAttributeValue(GetSkillAttributeValue(S_Sword_s08, theGame.params.CRITICAL_HIT_CHANCE, false, true)) * GetSkillLevel(S_Sword_s08);
  7941.             strongCritDmg += CalculateAttributeValue(GetSkillAttributeValue(S_Sword_s08, theGame.params.CRITICAL_HIT_DAMAGE_BONUS, false, true)) * GetSkillLevel(S_Sword_s08);
  7942.         }
  7943.        
  7944.         if ( HasBuff(EET_Mutagen05) && (GetStat(BCS_Vitality) == GetStatMax(BCS_Vitality)) )
  7945.         {
  7946.             attackPower += GetAttributeValue('damageIncrease');
  7947.         }
  7948.        
  7949.         steelCritChance += CalculateAttributeValue(GetAttributeValue(theGame.params.CRITICAL_HIT_CHANCE));
  7950.         silverCritChance += CalculateAttributeValue(GetAttributeValue(theGame.params.CRITICAL_HIT_CHANCE));
  7951.         steelCritDmg += CalculateAttributeValue(GetAttributeValue(theGame.params.CRITICAL_HIT_DAMAGE_BONUS));
  7952.         silverCritDmg += CalculateAttributeValue(GetAttributeValue(theGame.params.CRITICAL_HIT_DAMAGE_BONUS));
  7953.         attackPower += GetPowerStatValue(CPS_AttackPower);
  7954.        
  7955.         if (GetItemEquippedOnSlot(EES_SteelSword, item))
  7956.         {
  7957.             steelDmg = GetTotalWeaponDamage(item, theGame.params.DAMAGE_NAME_SLASHING, GetInvalidUniqueId());
  7958.             steelDmg += GetTotalWeaponDamage(item, theGame.params.DAMAGE_NAME_PIERCING, GetInvalidUniqueId());
  7959.             steelDmg += GetTotalWeaponDamage(item, theGame.params.DAMAGE_NAME_BLUDGEONING, GetInvalidUniqueId());
  7960.             elementalSteel = CalculateAttributeValue(GetInventory().GetItemAttributeValue(item, theGame.params.DAMAGE_NAME_FIRE));
  7961.             elementalSteel += CalculateAttributeValue(GetInventory().GetItemAttributeValue(item, theGame.params.DAMAGE_NAME_FROST));
  7962.             if ( GetInventory().IsItemHeld(item) )
  7963.             {
  7964.                 steelCritChance -= CalculateAttributeValue(GetInventory().GetItemAttributeValue(item, theGame.params.CRITICAL_HIT_CHANCE));
  7965.                 silverCritChance -= CalculateAttributeValue(GetInventory().GetItemAttributeValue(item, theGame.params.CRITICAL_HIT_CHANCE));
  7966.                 steelCritDmg -= CalculateAttributeValue(GetInventory().GetItemAttributeValue(item, theGame.params.CRITICAL_HIT_DAMAGE_BONUS));
  7967.                 silverCritDmg -= CalculateAttributeValue(GetInventory().GetItemAttributeValue(item, theGame.params.CRITICAL_HIT_DAMAGE_BONUS));
  7968.             }
  7969.             steelCritChance += CalculateAttributeValue(GetInventory().GetItemAttributeValue(item, theGame.params.CRITICAL_HIT_CHANCE));
  7970.             steelCritDmg += CalculateAttributeValue(GetInventory().GetItemAttributeValue(item, theGame.params.CRITICAL_HIT_DAMAGE_BONUS));
  7971.            
  7972.             thunder = (W3Potion_Thunderbolt)GetBuff(EET_Thunderbolt);
  7973.             if(thunder && thunder.GetBuffLevel() == 3 && GetCurWeather() == EWE_Storm)
  7974.             {
  7975.                 steelCritChance += 1.0f;
  7976.             }
  7977.         }
  7978.         else
  7979.         {
  7980.             steelDmg += 0;
  7981.             steelCritChance += 0;
  7982.             steelCritDmg +=0;
  7983.         }
  7984.        
  7985.         if (GetItemEquippedOnSlot(EES_SilverSword, item))
  7986.         {
  7987.             silverDmg = GetTotalWeaponDamage(item, theGame.params.DAMAGE_NAME_SILVER, GetInvalidUniqueId());
  7988.             elementalSilver = CalculateAttributeValue(GetInventory().GetItemAttributeValue(item, theGame.params.DAMAGE_NAME_FIRE));
  7989.             elementalSilver += CalculateAttributeValue(GetInventory().GetItemAttributeValue(item, theGame.params.DAMAGE_NAME_FROST));
  7990.             if ( GetInventory().IsItemHeld(item) )
  7991.             {
  7992.                 steelCritChance -= CalculateAttributeValue(GetInventory().GetItemAttributeValue(item, theGame.params.CRITICAL_HIT_CHANCE));
  7993.                 silverCritChance -= CalculateAttributeValue(GetInventory().GetItemAttributeValue(item, theGame.params.CRITICAL_HIT_CHANCE));
  7994.                 steelCritDmg -= CalculateAttributeValue(GetInventory().GetItemAttributeValue(item, theGame.params.CRITICAL_HIT_DAMAGE_BONUS));
  7995.                 silverCritDmg -= CalculateAttributeValue(GetInventory().GetItemAttributeValue(item, theGame.params.CRITICAL_HIT_DAMAGE_BONUS));
  7996.             }
  7997.             silverCritChance += CalculateAttributeValue(GetInventory().GetItemAttributeValue(item, theGame.params.CRITICAL_HIT_CHANCE));
  7998.             silverCritDmg += CalculateAttributeValue(GetInventory().GetItemAttributeValue(item, theGame.params.CRITICAL_HIT_DAMAGE_BONUS));
  7999.            
  8000.             thunder = (W3Potion_Thunderbolt)GetBuff(EET_Thunderbolt);
  8001.             if(thunder && thunder.GetBuffLevel() == 3 && GetCurWeather() == EWE_Storm)
  8002.             {
  8003.                 silverCritChance += 1.0f;
  8004.             }
  8005.         }
  8006.         else
  8007.         {
  8008.             silverDmg += 0;
  8009.             silverCritChance += 0;
  8010.             silverCritDmg +=0;
  8011.         }
  8012.        
  8013.         if ( HasAbility('Runeword 4 _Stats', true) )
  8014.         {
  8015.             steelDmg += steelDmg * (abilityManager.GetOverhealBonus() / GetStatMax(BCS_Vitality));
  8016.             silverDmg += silverDmg * (abilityManager.GetOverhealBonus() / GetStatMax(BCS_Vitality));
  8017.         }
  8018.        
  8019.         fastAP += attackPower;
  8020.         strongAP += attackPower;
  8021.        
  8022.         playerOffenseStats.steelFastCritChance = (steelCritChance + fastCritChance) * 100;
  8023.         playerOffenseStats.steelFastCritDmg = steelCritDmg + fastCritDmg;
  8024.         if ( steelDmg != 0 )
  8025.         {
  8026.             playerOffenseStats.steelFastDmg = (steelDmg + fastAP.valueBase) * fastAP.valueMultiplicative + fastAP.valueAdditive + elementalSteel;
  8027.             playerOffenseStats.steelFastCritDmg = (steelDmg + fastAP.valueBase) * (fastAP.valueMultiplicative + playerOffenseStats.steelFastCritDmg) + fastAP.valueAdditive + elementalSteel;
  8028.         }
  8029.         else
  8030.         {
  8031.             playerOffenseStats.steelFastDmg = 0;
  8032.             playerOffenseStats.steelFastCritDmg = 0;
  8033.         }
  8034.         playerOffenseStats.steelFastDPS = (playerOffenseStats.steelFastDmg * (100 - playerOffenseStats.steelFastCritChance) + playerOffenseStats.steelFastCritDmg * playerOffenseStats.steelFastCritChance) / 100;
  8035.         playerOffenseStats.steelFastDPS = playerOffenseStats.steelFastDPS / 0.6;
  8036.        
  8037.        
  8038.         playerOffenseStats.steelStrongCritChance = (steelCritChance + strongCritChance) * 100;
  8039.         playerOffenseStats.steelStrongCritDmg = steelCritDmg + strongCritDmg;
  8040.         if ( steelDmg != 0 )
  8041.         {
  8042.             playerOffenseStats.steelStrongDmg = (steelDmg + strongAP.valueBase) * strongAP.valueMultiplicative + strongAP.valueAdditive + elementalSteel;
  8043.             playerOffenseStats.steelStrongDmg *= 1.833f;
  8044.             playerOffenseStats.steelStrongCritDmg = (steelDmg + strongAP.valueBase) * (strongAP.valueMultiplicative + playerOffenseStats.steelStrongCritDmg) + strongAP.valueAdditive + elementalSteel;
  8045.             playerOffenseStats.steelStrongCritDmg *= 1.833f;        }
  8046.         else
  8047.         {
  8048.             playerOffenseStats.steelStrongDmg = 0;
  8049.             playerOffenseStats.steelStrongCritDmg = 0;
  8050.         }
  8051.         playerOffenseStats.steelStrongDPS = (playerOffenseStats.steelStrongDmg * (100 - playerOffenseStats.steelStrongCritChance) + playerOffenseStats.steelStrongCritDmg * playerOffenseStats.steelStrongCritChance) / 100;
  8052.         playerOffenseStats.steelStrongDPS = playerOffenseStats.steelStrongDPS / 1.1;
  8053.        
  8054.    
  8055.        
  8056.         playerOffenseStats.silverFastCritChance = (silverCritChance + fastCritChance) * 100;
  8057.         playerOffenseStats.silverFastCritDmg = silverCritDmg + fastCritDmg;
  8058.         if ( silverDmg != 0 )
  8059.         {
  8060.             playerOffenseStats.silverFastDmg = (silverDmg + fastAP.valueBase) * fastAP.valueMultiplicative + fastAP.valueAdditive + elementalSilver;
  8061.             playerOffenseStats.silverFastCritDmg = (silverDmg + fastAP.valueBase) * (fastAP.valueMultiplicative + playerOffenseStats.silverFastCritDmg) + fastAP.valueAdditive + elementalSilver;  
  8062.         }
  8063.         else
  8064.         {
  8065.             playerOffenseStats.silverFastDmg = 0;
  8066.             playerOffenseStats.silverFastCritDmg = 0;  
  8067.         }
  8068.         playerOffenseStats.silverFastDPS = (playerOffenseStats.silverFastDmg * (100 - playerOffenseStats.silverFastCritChance) + playerOffenseStats.silverFastCritDmg * playerOffenseStats.silverFastCritChance) / 100;
  8069.         playerOffenseStats.silverFastDPS = playerOffenseStats.silverFastDPS / 0.6;
  8070.        
  8071.        
  8072.         playerOffenseStats.silverStrongCritChance = (silverCritChance + strongCritChance) * 100;
  8073.         playerOffenseStats.silverStrongCritDmg = silverCritDmg + strongCritDmg;    
  8074.         if ( silverDmg != 0 )
  8075.         {
  8076.             playerOffenseStats.silverStrongDmg = (silverDmg + strongAP.valueBase) * strongAP.valueMultiplicative + strongAP.valueAdditive + elementalSilver;
  8077.             playerOffenseStats.silverStrongDmg *= 1.833f;
  8078.             playerOffenseStats.silverStrongCritDmg = (silverDmg + strongAP.valueBase) * (strongAP.valueMultiplicative + playerOffenseStats.silverStrongCritDmg) + strongAP.valueAdditive + elementalSilver;
  8079.             playerOffenseStats.silverStrongCritDmg *= 1.833f;
  8080.         }
  8081.         else
  8082.         {
  8083.             playerOffenseStats.silverStrongDmg = 0;
  8084.             playerOffenseStats.silverStrongCritDmg = 0;
  8085.         }
  8086.         playerOffenseStats.silverStrongDPS = (playerOffenseStats.silverStrongDmg * (100 - playerOffenseStats.silverStrongCritChance) + playerOffenseStats.silverStrongCritDmg * playerOffenseStats.silverStrongCritChance) / 100;
  8087.         playerOffenseStats.silverStrongDPS = playerOffenseStats.silverStrongDPS / 1.1;
  8088.        
  8089.        
  8090.         playerOffenseStats.crossbowCritChance = GetCriticalHitChance( false, false, NULL, MC_NotSet, true );
  8091.    
  8092.        
  8093.         playerOffenseStats.crossbowSteelDmgType = theGame.params.DAMAGE_NAME_PIERCING;
  8094.         if (GetItemEquippedOnSlot(EES_Bolt, item))
  8095.         {
  8096.            
  8097.            
  8098.             steelDmg = CalculateAttributeValue(GetInventory().GetItemAttributeValue(item, theGame.params.DAMAGE_NAME_FIRE));
  8099.             if(steelDmg > 0)
  8100.             {
  8101.                 playerOffenseStats.crossbowSteelDmg = steelDmg;
  8102.                
  8103.                 playerOffenseStats.crossbowSteelDmgType = theGame.params.DAMAGE_NAME_FIRE;
  8104.                 playerOffenseStats.crossbowSilverDmg = steelDmg;
  8105.             }
  8106.             else
  8107.             {
  8108.                 playerOffenseStats.crossbowSilverDmg = CalculateAttributeValue(GetInventory().GetItemAttributeValue(item, theGame.params.DAMAGE_NAME_SILVER));
  8109.                
  8110.                 steelDmg = CalculateAttributeValue(GetInventory().GetItemAttributeValue(item, theGame.params.DAMAGE_NAME_PIERCING));
  8111.                 if(steelDmg > 0)
  8112.                 {
  8113.                     playerOffenseStats.crossbowSteelDmg = steelDmg;
  8114.                     playerOffenseStats.crossbowSteelDmgType = theGame.params.DAMAGE_NAME_PIERCING;
  8115.                 }
  8116.                 else
  8117.                 {
  8118.                     playerOffenseStats.crossbowSteelDmg = CalculateAttributeValue(GetInventory().GetItemAttributeValue(item, theGame.params.DAMAGE_NAME_BLUDGEONING));
  8119.                     playerOffenseStats.crossbowSteelDmgType = theGame.params.DAMAGE_NAME_BLUDGEONING;
  8120.                 }
  8121.             }
  8122.         }
  8123.        
  8124.         if (GetItemEquippedOnSlot(EES_RangedWeapon, item))
  8125.         {
  8126.             attackPower += GetInventory().GetItemAttributeValue(item, PowerStatEnumToName(CPS_AttackPower));
  8127.             if(CanUseSkill(S_Perk_02))
  8128.             {              
  8129.            
  8130.             if( IsMutationActive( EPMT_Mutation9 ) )
  8131.                 {  
  8132.                 attackPower += (GetSkillAttributeValue(S_Perk_02, PowerStatEnumToName(CPS_AttackPower), false, true) * 2.0f);
  8133.                 }
  8134.                 else
  8135.                 {
  8136.                 attackPower += GetSkillAttributeValue(S_Perk_02, PowerStatEnumToName(CPS_AttackPower), false, true);
  8137.                 }
  8138.             }
  8139.  
  8140.            
  8141.             if( hackMode != 1 && ( IsMutationActive( EPMT_Mutation9 ) || hackMode == 2 ) )
  8142.             {
  8143.                 theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation9', 'damage', min, max );
  8144.                 playerOffenseStats.crossbowSteelDmg += min.valueAdditive;
  8145.                 playerOffenseStats.crossbowSilverDmg += min.valueAdditive;
  8146.             }      
  8147.            
  8148.             playerOffenseStats.crossbowSteelDmg = (playerOffenseStats.crossbowSteelDmg + attackPower.valueBase) * attackPower.valueMultiplicative + attackPower.valueAdditive;
  8149.             playerOffenseStats.crossbowSilverDmg = (playerOffenseStats.crossbowSilverDmg + attackPower.valueBase) * attackPower.valueMultiplicative + attackPower.valueAdditive;
  8150.         }
  8151.         else
  8152.         {
  8153.             playerOffenseStats.crossbowSteelDmg = 0;
  8154.             playerOffenseStats.crossbowSilverDmg = 0;
  8155.             playerOffenseStats.crossbowSteelDmgType = theGame.params.DAMAGE_NAME_PIERCING;
  8156.         }
  8157.        
  8158.         return playerOffenseStats;
  8159.     }
  8160.    
  8161.     public function GetTotalWeaponDamage(weaponId : SItemUniqueId, damageTypeName : name, crossbowId : SItemUniqueId) : float
  8162.     {
  8163.         var damage, durRatio, durMod, itemMod : float;
  8164.         var repairObjectBonus, min, max : SAbilityAttributeValue;
  8165.        
  8166.         durMod = 0;
  8167.         damage = super.GetTotalWeaponDamage(weaponId, damageTypeName, crossbowId);
  8168.        
  8169.        
  8170.         if( IsMutationActive( EPMT_Mutation9 ) && inv.IsItemBolt( weaponId ) && IsDamageTypeAnyPhysicalType( damageTypeName ) )
  8171.         {
  8172.             theGame.GetDefinitionsManager().GetAbilityAttributeValue('Mutation9', 'damage', min, max);
  8173.             damage += min.valueAdditive;
  8174.         }
  8175.        
  8176.        
  8177.         if(IsPhysicalResistStat(GetResistForDamage(damageTypeName, false)))
  8178.         {
  8179.             repairObjectBonus = inv.GetItemAttributeValue(weaponId, theGame.params.REPAIR_OBJECT_BONUS);
  8180.             durRatio = -1;
  8181.            
  8182.             if(inv.IsIdValid(crossbowId) && inv.HasItemDurability(crossbowId))
  8183.             {
  8184.                 durRatio = inv.GetItemDurabilityRatio(crossbowId);
  8185.             }
  8186.             else if(inv.IsIdValid(weaponId) && inv.HasItemDurability(weaponId))
  8187.             {
  8188.                 durRatio = inv.GetItemDurabilityRatio(weaponId);
  8189.             }
  8190.            
  8191.            
  8192.             if(durRatio >= 0)
  8193.                 durMod = theGame.params.GetDurabilityMultiplier(durRatio, true);
  8194.             else
  8195.                 durMod = 1;
  8196.         }
  8197.        
  8198.        
  8199.         if( damageTypeName == 'SilverDamage' && inv.ItemHasTag( weaponId, 'Aerondight' ) )
  8200.         {
  8201.             itemMod = inv.GetItemModifierFloat( weaponId, 'PermDamageBoost' );
  8202.             if( itemMod > 0.f )
  8203.             {
  8204.                 damage += itemMod;
  8205.             }
  8206.         }
  8207.        
  8208.         return damage * (durMod + repairObjectBonus.valueMultiplicative);
  8209.     }
  8210.    
  8211.    
  8212.    
  8213.    
  8214.    
  8215.     public final function GetSkillPathType(skill : ESkill) : ESkillPath
  8216.     {
  8217.         if(abilityManager && abilityManager.IsInitialized())
  8218.             return ((W3PlayerAbilityManager)abilityManager).GetSkillPathType(skill);
  8219.            
  8220.         return ESP_NotSet;
  8221.     }
  8222.    
  8223.     public function GetSkillLevel(s : ESkill) : int
  8224.     {
  8225.         if(abilityManager && abilityManager.IsInitialized())
  8226.             return ((W3PlayerAbilityManager)abilityManager).GetSkillLevel(s);
  8227.            
  8228.         return -1;
  8229.     }
  8230.    
  8231.     public function GetSkillMaxLevel(s : ESkill) : int
  8232.     {
  8233.         if(abilityManager && abilityManager.IsInitialized())
  8234.             return ((W3PlayerAbilityManager)abilityManager).GetSkillMaxLevel(s);
  8235.            
  8236.         return -1;
  8237.     }
  8238.    
  8239.     public function GetBoughtSkillLevel(s : ESkill) : int
  8240.     {
  8241.         if(abilityManager && abilityManager.IsInitialized())
  8242.             return ((W3PlayerAbilityManager)abilityManager).GetBoughtSkillLevel(s);
  8243.            
  8244.         return -1;
  8245.     }
  8246.    
  8247.    
  8248.     public function GetAxiiLevel() : int
  8249.     {
  8250.         var level : int;
  8251.        
  8252.         level = 1;
  8253.        
  8254.         if(CanUseSkill(S_Magic_s17)) level += GetSkillLevel(S_Magic_s17);
  8255.            
  8256.         return Clamp(level, 1, 4);
  8257.     }
  8258.    
  8259.     public function IsInFrenzy() : bool
  8260.     {
  8261.         return isInFrenzy;
  8262.     }
  8263.    
  8264.     public function HasRecentlyCountered() : bool
  8265.     {
  8266.         return hasRecentlyCountered;
  8267.     }
  8268.    
  8269.     public function SetRecentlyCountered(counter : bool)
  8270.     {
  8271.         hasRecentlyCountered = counter;
  8272.     }
  8273.    
  8274.     timer function CheckBlockedSkills(dt : float, id : int)
  8275.     {
  8276.         var nextCallTime : float;
  8277.        
  8278.         nextCallTime = ((W3PlayerAbilityManager)abilityManager).CheckBlockedSkills(dt);
  8279.         if(nextCallTime != -1)
  8280.             AddTimer('CheckBlockedSkills', nextCallTime, , , , true);
  8281.     }
  8282.        
  8283.    
  8284.     public function RemoveTemporarySkills()
  8285.     {
  8286.         var i : int;
  8287.         var pam : W3PlayerAbilityManager;
  8288.    
  8289.         if(tempLearnedSignSkills.Size() > 0)
  8290.         {
  8291.             pam = (W3PlayerAbilityManager)abilityManager;
  8292.             for(i=0; i<tempLearnedSignSkills.Size(); i+=1)
  8293.             {
  8294.                 pam.RemoveTemporarySkill(tempLearnedSignSkills[i]);
  8295.             }
  8296.            
  8297.             tempLearnedSignSkills.Clear();                     
  8298.         }
  8299.         RemoveAbilityAll(SkillEnumToName(S_Sword_s19));
  8300.     }
  8301.    
  8302.     public function RemoveTemporarySkill(skill : SSimpleSkill) : bool
  8303.     {
  8304.         var pam : W3PlayerAbilityManager;
  8305.        
  8306.         pam = (W3PlayerAbilityManager)abilityManager;
  8307.         if(pam && pam.IsInitialized())
  8308.             return pam.RemoveTemporarySkill(skill);
  8309.            
  8310.         return false;
  8311.     }
  8312.    
  8313.    
  8314.     private function AddTemporarySkills()
  8315.     {
  8316.         if(CanUseSkill(S_Sword_s19) && GetStat(BCS_Focus) >= 3)
  8317.         {
  8318.             tempLearnedSignSkills = ((W3PlayerAbilityManager)abilityManager).AddTempNonAlchemySkills();                    
  8319.             DrainFocus(GetStat(BCS_Focus));
  8320.             AddAbilityMultiple(SkillEnumToName(S_Sword_s19), GetSkillLevel(S_Sword_s19));          
  8321.         }
  8322.     }
  8323.  
  8324.    
  8325.    
  8326.     public function HasAlternateQuen() : bool
  8327.     {
  8328.         var quenEntity : W3QuenEntity;
  8329.        
  8330.         quenEntity = (W3QuenEntity)GetCurrentSignEntity();
  8331.         if(quenEntity)
  8332.         {
  8333.             return quenEntity.IsAlternateCast();
  8334.         }
  8335.        
  8336.         return false;
  8337.     }
  8338.    
  8339.    
  8340.    
  8341.    
  8342.    
  8343.     public function AddPoints(type : ESpendablePointType, amount : int, show : bool)
  8344.     {
  8345.         levelManager.AddPoints(type, amount, show);
  8346.     }
  8347.    
  8348.     public function GetLevel() : int                                            {return levelManager.GetLevel();}
  8349.     public function GetMaxLevel() : int                                         {return levelManager.GetMaxLevel();}
  8350.     public function GetTotalExpForNextLevel() : int                             {return levelManager.GetTotalExpForNextLevel();}   
  8351.     public function GetPointsTotal(type : ESpendablePointType) : int            {return levelManager.GetPointsTotal(type);}
  8352.     public function IsAutoLeveling() : bool                                     {return autoLevel;}
  8353.     public function SetAutoLeveling( b : bool )                                 {autoLevel = b;}
  8354.    
  8355.     public function GetMissingExpForNextLevel() : int
  8356.     {
  8357.         return Max(0, GetTotalExpForNextLevel() - GetPointsTotal(EExperiencePoint));
  8358.     }
  8359.    
  8360.    
  8361.    
  8362.    
  8363.     private saved var runewordInfusionType : ESignType;
  8364.     default runewordInfusionType = ST_None;
  8365.    
  8366.     public final function GetRunewordInfusionType() : ESignType
  8367.     {
  8368.         return runewordInfusionType;
  8369.     }
  8370.    
  8371.    
  8372.     public function QuenImpulse( isAlternate : bool, signEntity : W3QuenEntity, source : string, optional forceSkillLevel : int )
  8373.     {
  8374.         var level, i, j : int;
  8375.         var atts, damages : array<name>;
  8376.         var ents : array<CGameplayEntity>;
  8377.         var action : W3DamageAction;
  8378.         var dm : CDefinitionsManagerAccessor;
  8379.         var skillAbilityName : name;
  8380.         var dmg : float;
  8381.         var min, max : SAbilityAttributeValue;
  8382.         var pos : Vector;
  8383.        
  8384.         if( forceSkillLevel > 0 )
  8385.         {
  8386.             level = forceSkillLevel;
  8387.         }
  8388.         else
  8389.         {
  8390.             level = GetSkillLevel(S_Magic_s13);
  8391.         }
  8392.        
  8393.         dm = theGame.GetDefinitionsManager();
  8394.         skillAbilityName = GetSkillAbilityName(S_Magic_s13);
  8395.        
  8396.         if(level >= 2)
  8397.         {
  8398.            
  8399.             dm.GetAbilityAttributes(skillAbilityName, atts);
  8400.             for(i=0; i<atts.Size(); i+=1)
  8401.             {
  8402.                 if(IsDamageTypeNameValid(atts[i]))
  8403.                 {
  8404.                     damages.PushBack(atts[i]);
  8405.                 }
  8406.             }
  8407.         }
  8408.        
  8409.        
  8410.         pos = signEntity.GetWorldPosition();
  8411.         FindGameplayEntitiesInSphere(ents, pos, 3, 1000, '', FLAG_OnlyAliveActors + FLAG_ExcludeTarget + FLAG_Attitude_Hostile + FLAG_Attitude_Neutral + FLAG_TestLineOfSight, this);
  8412.        
  8413.        
  8414.         for(i=0; i<ents.Size(); i+=1)
  8415.         {
  8416.             action = new W3DamageAction in theGame;
  8417.             action.Initialize(this, ents[i], signEntity, source, EHRT_Heavy, CPS_SpellPower, false, false, true, false);
  8418.             action.SetSignSkill(S_Magic_s13);
  8419.             action.SetCannotReturnDamage(true);
  8420.             action.SetProcessBuffsIfNoDamage(true);
  8421.            
  8422.            
  8423.             if(!isAlternate && level >= 2)
  8424.             {
  8425.                 action.SetHitEffect('hit_electric_quen');
  8426.                 action.SetHitEffect('hit_electric_quen', true);
  8427.                 action.SetHitEffect('hit_electric_quen', false, true);
  8428.                 action.SetHitEffect('hit_electric_quen', true, true);
  8429.             }
  8430.            
  8431.             if(level >= 1)
  8432.             {
  8433.                 action.AddEffectInfo(EET_Stagger);
  8434.             }
  8435.             if(level >= 2)
  8436.             {
  8437.                 for(j=0; j<damages.Size(); j+=1)
  8438.                 {
  8439.                     dm.GetAbilityAttributeValue(skillAbilityName, damages[j], min, max);
  8440.                     dmg = CalculateAttributeValue(GetAttributeRandomizedValue(min, max));
  8441.  
  8442.                              
  8443.                    
  8444.                  
  8445.                                                          
  8446.                            
  8447.          
  8448.                            
  8449.                     if( IsSetBonusActive( EISB_Bear_2 ) )
  8450.                     {
  8451.                         dm.GetAbilityAttributeValue( GetSetBonusAbility( EISB_Bear_2 ), 'quen_dmg_boost', min, max );
  8452.                         dmg *= 1 + min.valueMultiplicative;                    
  8453.                     }                  
  8454.                     action.AddDamage(damages[j], dmg);
  8455.                 }
  8456.             }
  8457.             if(level == 3)
  8458.             {
  8459.                 action.AddEffectInfo(EET_KnockdownTypeApplicator);
  8460.             }
  8461.            
  8462.             theGame.damageMgr.ProcessAction( action );
  8463.             delete action;
  8464.         }
  8465.        
  8466.        
  8467.         if(isAlternate)
  8468.         {
  8469.             signEntity.PlayHitEffect('quen_impulse_explode', signEntity.GetWorldRotation());
  8470.             signEntity.EraseFirstTimeStamp();
  8471.                        
  8472.            
  8473.             if(level >= 2)
  8474.             {
  8475.                 if( !IsSetBonusActive( EISB_Bear_2 ) )
  8476.                 {
  8477.                     signEntity.PlayHitEffect('quen_electric_explode', signEntity.GetWorldRotation());
  8478.                 }
  8479.                 else
  8480.                 {
  8481.                     signEntity.PlayHitEffect('quen_electric_explode_bear_abl2', signEntity.GetWorldRotation());
  8482.                 }
  8483.             }
  8484.         }
  8485.         else
  8486.         {
  8487.             signEntity.PlayEffect('lasting_shield_impulse');
  8488.         }      
  8489.     }
  8490.  
  8491.     public function OnSignCastPerformed(signType : ESignType, isAlternate : bool)
  8492.     {
  8493.         var items : array<SItemUniqueId>;
  8494.         var weaponEnt : CEntity;
  8495.         var fxName : name;
  8496.         var pos : Vector;
  8497.        
  8498.         super.OnSignCastPerformed(signType, isAlternate);
  8499.        
  8500.         //if(HasAbility('Runeword 1 _Stats', true))
  8501.         // if(IsMutationActive( EPMT_Mutation1 ) && GetStat(BCS_Focus) >= 1.0f)
  8502.          if(HasAbility('Runeword 1 _Stats', true) && GetStat(BCS_Focus) >= 1.0f)
  8503.         {
  8504.             DrainFocus(1.0f);
  8505.             runewordInfusionType = signType;
  8506.             items = inv.GetHeldWeapons();
  8507.             weaponEnt = inv.GetItemEntityUnsafe(items[0]);
  8508.    
  8509.             RemoveTimer('UndyingSkillCooldown3');
  8510.             weaponEnt.StopEffect('runeword_aard');
  8511.             weaponEnt.StopEffect('runeword_axii');
  8512.             weaponEnt.StopEffect('runeword_igni');
  8513.             weaponEnt.StopEffect('runeword_quen');
  8514.             weaponEnt.StopEffect('runeword_yrden');
  8515.                    
  8516.            
  8517.             if(signType == ST_Aard)
  8518.                 fxName = 'runeword_aard';
  8519.             else if(signType == ST_Axii)
  8520.                 fxName = 'runeword_axii';
  8521.             else if(signType == ST_Igni)
  8522.                 fxName = 'runeword_igni';
  8523.             else if(signType == ST_Quen)
  8524.                 fxName = 'runeword_quen';
  8525.             else if(signType == ST_Yrden)
  8526.                 fxName = 'runeword_yrden';
  8527.                
  8528.             weaponEnt.PlayEffect(fxName);
  8529.             //AddTimer('UndyingSkillCooldown3',15,true);
  8530.         }
  8531.        
  8532.        
  8533.         //addTomes
  8534.         if( GetWitcherPlayer().IsItemEquippedByName( 'permafrost_tome' ) &&
  8535.             GetWitcherPlayer().GetInventory().GetItemId( 'permafrost_tome' ) == GetWitcherPlayer().GetSelectedItemId() && signType == ST_Aard && !isAlternate )
  8536.         {
  8537.             pos = GetWorldPosition() + GetWorldForward() * 2;
  8538.             theSound.SoundLoadBank( ( ( W3PlayerAbilityManager ) abilityManager ).GetMutationSoundBank(( EPMT_Mutation6 )), true );
  8539.             theGame.GetSurfacePostFX().AddSurfacePostFXGroup( pos, 0.f, 3.f, 2.f, 5.f, 0 );
  8540.         }
  8541.         else //addTomes
  8542.        
  8543.        
  8544.         if( IsMutationActive( EPMT_Mutation6 ) && signType == ST_Aard && !isAlternate )
  8545.         {
  8546.             pos = GetWorldPosition() + GetWorldForward() * 2;
  8547.            
  8548.             theGame.GetSurfacePostFX().AddSurfacePostFXGroup( pos, 0.f, 3.f, 2.f, 5.f, 0 );
  8549.         }
  8550.     }
  8551.    
  8552.     public saved var savedQuenHealth, savedQuenDuration : float;
  8553.    
  8554.     timer function HACK_QuenSaveStatus(dt : float, id : int)
  8555.     {
  8556.         var quenEntity : W3QuenEntity;
  8557.        
  8558.         quenEntity = (W3QuenEntity)signs[ST_Quen].entity;
  8559.         savedQuenHealth = quenEntity.GetShieldHealth();
  8560.         savedQuenDuration = quenEntity.GetShieldRemainingDuration();
  8561.     }
  8562.    
  8563.     timer function DelayedRestoreQuen(dt : float, id : int)
  8564.     {
  8565.         RestoreQuen(savedQuenHealth, savedQuenDuration);
  8566.     }
  8567.    
  8568.     public final function OnBasicQuenFinishing()
  8569.     {
  8570.         RemoveTimer('HACK_QuenSaveStatus');
  8571.         savedQuenHealth = 0.f;
  8572.         savedQuenDuration = 0.f;
  8573.     }
  8574.    
  8575.     public final function IsAnyQuenActive() : bool
  8576.     {
  8577.         var quen : W3QuenEntity;
  8578.        
  8579.         quen = (W3QuenEntity)GetSignEntity(ST_Quen);
  8580.         if(quen)
  8581.             return quen.IsAnyQuenActive();
  8582.            
  8583.         return false;
  8584.     }
  8585.    
  8586.     public final function IsQuenActive(alternateMode : bool) : bool
  8587.     {
  8588.         if(IsAnyQuenActive() && GetSignEntity(ST_Quen).IsAlternateCast() == alternateMode)
  8589.             return true;
  8590.            
  8591.         return false;
  8592.     }
  8593.    
  8594.     public function FinishQuen( skipVisuals : bool, optional forceNoBearSetBonus : bool )
  8595.     {
  8596.         var quen : W3QuenEntity;
  8597.        
  8598.         quen = (W3QuenEntity)GetSignEntity(ST_Quen);
  8599.         if(quen)
  8600.             quen.ForceFinishQuen( skipVisuals, forceNoBearSetBonus );
  8601.     }
  8602.    
  8603.    
  8604.     public function GetTotalSignSpellPower(signSkill : ESkill) : SAbilityAttributeValue
  8605.     {
  8606.         var sp : SAbilityAttributeValue;
  8607.         var penalty : SAbilityAttributeValue;
  8608.         var penaltyReduction : float;
  8609.         var penaltyReductionLevel : int;
  8610.        
  8611.        
  8612.         sp = GetSkillAttributeValue(signSkill, PowerStatEnumToName(CPS_SpellPower), true, true);
  8613.        
  8614.  
  8615.                                  
  8616.    
  8617.    
  8618.                                                          
  8619.                                
  8620.    
  8621.                                                                                                                                                              
  8622.                                                                                                      
  8623.                                      
  8624.    
  8625.    
  8626.  
  8627.  
  8628.         if(signSkill == S_Magic_1 || signSkill == S_Magic_s01)
  8629.         {
  8630.             sp += GetAttributeValue('spell_power_aard');
  8631.         }
  8632.         else if(signSkill == S_Magic_2 || signSkill == S_Magic_s02)
  8633.         {
  8634.             sp += GetAttributeValue('spell_power_igni');
  8635.         }
  8636.         else if(signSkill == S_Magic_3 || signSkill == S_Magic_s03)
  8637.         {
  8638.             sp += GetAttributeValue('spell_power_yrden');
  8639.         }
  8640.         else if(signSkill == S_Magic_4 || signSkill == S_Magic_s04)
  8641.         {
  8642.             sp += GetAttributeValue('spell_power_quen');
  8643.  
  8644.             if(thePlayer.HasBuff(EET_Mutagen48))
  8645.                 sp.valueMultiplicative += 0.2;
  8646.         }
  8647.         else if(signSkill == S_Magic_5 || signSkill == S_Magic_s05)
  8648.         {
  8649.             sp += GetAttributeValue('spell_power_axii');
  8650.  
  8651.             if(thePlayer.HasBuff(EET_Mutagen49))
  8652.                 sp.valueMultiplicative += 0.2;
  8653.         }
  8654.        
  8655.        
  8656.         ApplyMutation10StatBoost( sp );
  8657.    
  8658.         return sp;
  8659.     }
  8660.    
  8661.    
  8662.    
  8663.    
  8664.    
  8665.     public final function GetGwentCardIndex( cardName : name ) : int
  8666.     {
  8667.         var dm : CDefinitionsManagerAccessor;
  8668.        
  8669.         dm = theGame.GetDefinitionsManager();
  8670.        
  8671.         if(dm.ItemHasTag( cardName , 'GwintCardLeader' ))
  8672.         {
  8673.             return theGame.GetGwintManager().GwentLeadersNametoInt( cardName );
  8674.         }
  8675.         else if(dm.ItemHasTag( cardName , 'GwintCardNrkd' ))
  8676.         {
  8677.             return theGame.GetGwintManager().GwentNrkdNameToInt( cardName );
  8678.         }
  8679.         else if(dm.ItemHasTag( cardName , 'GwintCardNlfg' ))
  8680.         {
  8681.             return theGame.GetGwintManager().GwentNlfgNameToInt( cardName );
  8682.         }
  8683.         else if(dm.ItemHasTag( cardName , 'GwintCardSctl' ))
  8684.         {
  8685.             return theGame.GetGwintManager().GwentSctlNameToInt( cardName );
  8686.         }
  8687.         else if(dm.ItemHasTag( cardName , 'GwintCardMstr' ))
  8688.         {
  8689.             return theGame.GetGwintManager().GwentMstrNameToInt( cardName );
  8690.         }
  8691.         else if(dm.ItemHasTag( cardName , 'GwintCardSke' ))
  8692.         {
  8693.             return theGame.GetGwintManager().GwentSkeNameToInt( cardName );
  8694.         }  
  8695.         else if(dm.ItemHasTag( cardName , 'GwintCardNeutral' ))
  8696.         {
  8697.             return theGame.GetGwintManager().GwentNeutralNameToInt( cardName );
  8698.         }
  8699.         else if(dm.ItemHasTag( cardName , 'GwintCardSpcl' ))
  8700.         {
  8701.             return theGame.GetGwintManager().GwentSpecialNameToInt( cardName );
  8702.         }
  8703.        
  8704.         return -1;
  8705.     }
  8706.    
  8707.     public final function AddGwentCard(cardName : name, amount : int) : bool
  8708.     {
  8709.         var dm : CDefinitionsManagerAccessor;
  8710.         var cardIndex, i : int;
  8711.         var tut : STutorialMessage;
  8712.         var gwintManager : CR4GwintManager;
  8713.        
  8714.        
  8715.        
  8716.         if(FactsQuerySum("q001_nightmare_ended") > 0 && ShouldProcessTutorial('TutorialGwentDeckBuilder2'))
  8717.         {
  8718.             tut.type = ETMT_Hint;
  8719.             tut.tutorialScriptTag = 'TutorialGwentDeckBuilder2';
  8720.             tut.journalEntryName = 'TutorialGwentDeckBuilder2';
  8721.             tut.hintPositionType = ETHPT_DefaultGlobal;
  8722.             tut.markAsSeenOnShow = true;
  8723.             tut.hintDurationType = ETHDT_Long;
  8724.  
  8725.             theGame.GetTutorialSystem().DisplayTutorial(tut);
  8726.         }
  8727.        
  8728.         dm = theGame.GetDefinitionsManager();
  8729.        
  8730.         cardIndex = GetGwentCardIndex(cardName);
  8731.        
  8732.         if (cardIndex != -1)
  8733.         {
  8734.             FactsAdd("Gwint_Card_Looted");
  8735.            
  8736.             for(i = 0; i < amount; i += 1)
  8737.             {
  8738.                 theGame.GetGwintManager().AddCardToCollection( cardIndex );
  8739.             }
  8740.         }
  8741.        
  8742.         if( dm.ItemHasTag( cardName, 'GwentTournament' ) )
  8743.         {
  8744.             if ( dm.ItemHasTag( cardName, 'GT1' ) )
  8745.             {
  8746.                 FactsAdd( "GwentTournament", 1 );
  8747.             }
  8748.            
  8749.             else if ( dm.ItemHasTag( cardName, 'GT2' ) )
  8750.             {
  8751.                 FactsAdd( "GwentTournament", 2 );
  8752.             }
  8753.            
  8754.             else if ( dm.ItemHasTag( cardName, 'GT3' ) )
  8755.             {
  8756.                 FactsAdd( "GwentTournament", 3 );
  8757.             }
  8758.            
  8759.             else if ( dm.ItemHasTag( cardName, 'GT4' ) )
  8760.             {
  8761.                 FactsAdd( "GwentTournament", 4 );
  8762.             }
  8763.            
  8764.             else if ( dm.ItemHasTag( cardName, 'GT5' ) )
  8765.             {
  8766.                 FactsAdd( "GwentTournament", 5 );
  8767.             }
  8768.            
  8769.             else if ( dm.ItemHasTag( cardName, 'GT6' ) )
  8770.             {
  8771.                 FactsAdd( "GwentTournament", 6 );
  8772.             }
  8773.            
  8774.             else if ( dm.ItemHasTag( cardName, 'GT7' ) )
  8775.             {
  8776.                 FactsAdd( "GwentTournament", 7 );
  8777.             }
  8778.            
  8779.             CheckGwentTournamentDeck();
  8780.         }
  8781.        
  8782.         if( dm.ItemHasTag( cardName, 'EP2Tournament' ) )
  8783.         {
  8784.             if ( dm.ItemHasTag( cardName, 'GT1' ) )
  8785.             {
  8786.                 FactsAdd( "EP2Tournament", 1 );
  8787.             }
  8788.            
  8789.             else if ( dm.ItemHasTag( cardName, 'GT2' ) )
  8790.             {
  8791.                 FactsAdd( "EP2Tournament", 2 );
  8792.             }
  8793.            
  8794.             else if ( dm.ItemHasTag( cardName, 'GT3' ) )
  8795.             {
  8796.                 FactsAdd( "EP2Tournament", 3 );
  8797.             }
  8798.            
  8799.             else if ( dm.ItemHasTag( cardName, 'GT4' ) )
  8800.             {
  8801.                 FactsAdd( "EP2Tournament", 4 );
  8802.             }
  8803.            
  8804.             else if ( dm.ItemHasTag( cardName, 'GT5' ) )
  8805.             {
  8806.                 FactsAdd( "EP2Tournament", 5 );
  8807.             }
  8808.            
  8809.             else if ( dm.ItemHasTag( cardName, 'GT6' ) )
  8810.             {
  8811.                 FactsAdd( "EP2Tournament", 6 );
  8812.             }
  8813.            
  8814.             else if ( dm.ItemHasTag( cardName, 'GT7' ) )
  8815.             {
  8816.                 FactsAdd( "EP2Tournament", 7 );
  8817.             }
  8818.            
  8819.             CheckEP2TournamentDeck();
  8820.         }
  8821.        
  8822.         gwintManager = theGame.GetGwintManager();
  8823.         if( !gwintManager.IsDeckUnlocked( GwintFaction_Skellige ) &&
  8824.             gwintManager.HasCardsOfFactionInCollection( GwintFaction_Skellige, false ) )
  8825.         {
  8826.             gwintManager.UnlockDeck( GwintFaction_Skellige );
  8827.         }
  8828.        
  8829.         return true;
  8830.     }
  8831.    
  8832.    
  8833.     public final function RemoveGwentCard(cardName : name, amount : int) : bool
  8834.     {
  8835.         var dm : CDefinitionsManagerAccessor;
  8836.         var cardIndex, i : int;
  8837.        
  8838.         dm = theGame.GetDefinitionsManager();
  8839.        
  8840.         if(dm.ItemHasTag( cardName , 'GwintCardLeader' ))
  8841.         {
  8842.             cardIndex = theGame.GetGwintManager().GwentLeadersNametoInt( cardName );
  8843.             for(i=0; i<amount; i+=1)
  8844.                 theGame.GetGwintManager().RemoveCardFromCollection( cardIndex );
  8845.         }
  8846.         else if(dm.ItemHasTag( cardName , 'GwintCardNrkd' ))
  8847.         {
  8848.             cardIndex = theGame.GetGwintManager().GwentNrkdNameToInt( cardName );
  8849.             for(i=0; i<amount; i+=1)
  8850.                 theGame.GetGwintManager().RemoveCardFromCollection( cardIndex );
  8851.         }
  8852.         else if(dm.ItemHasTag( cardName , 'GwintCardNlfg' ))
  8853.         {
  8854.             cardIndex = theGame.GetGwintManager().GwentNlfgNameToInt( cardName );
  8855.             for(i=0; i<amount; i+=1)
  8856.                 theGame.GetGwintManager().RemoveCardFromCollection( cardIndex );
  8857.         }
  8858.         else if(dm.ItemHasTag( cardName , 'GwintCardSctl' ))
  8859.         {
  8860.             cardIndex = theGame.GetGwintManager().GwentSctlNameToInt( cardName );
  8861.             for(i=0; i<amount; i+=1)
  8862.                 theGame.GetGwintManager().RemoveCardFromCollection( cardIndex );
  8863.         }
  8864.         else if(dm.ItemHasTag( cardName , 'GwintCardMstr' ))
  8865.         {
  8866.             cardIndex = theGame.GetGwintManager().GwentMstrNameToInt( cardName );
  8867.             for(i=0; i<amount; i+=1)
  8868.                 theGame.GetGwintManager().RemoveCardFromCollection( cardIndex );
  8869.         }
  8870.         else if(dm.ItemHasTag( cardName , 'GwintCardNeutral' ))
  8871.         {
  8872.             cardIndex = theGame.GetGwintManager().GwentNeutralNameToInt( cardName );
  8873.             for(i=0; i<amount; i+=1)
  8874.                 theGame.GetGwintManager().RemoveCardFromCollection( cardIndex );
  8875.         }
  8876.         else if(dm.ItemHasTag( cardName , 'GwintCardSpcl' ))
  8877.         {
  8878.             cardIndex = theGame.GetGwintManager().GwentSpecialNameToInt( cardName );
  8879.             for(i=0; i<amount; i+=1)
  8880.                 theGame.GetGwintManager().RemoveCardFromCollection( cardIndex );
  8881.         }
  8882.        
  8883.         if( dm.ItemHasTag( cardName, 'GwentTournament' ) )
  8884.         {
  8885.             if ( dm.ItemHasTag( cardName, 'GT1' ) )
  8886.             {
  8887.                 FactsSubstract( "GwentTournament", 1 );
  8888.             }
  8889.            
  8890.             else if ( dm.ItemHasTag( cardName, 'GT2' ) )
  8891.             {
  8892.                 FactsSubstract( "GwentTournament", 2 );
  8893.             }
  8894.            
  8895.             else if ( dm.ItemHasTag( cardName, 'GT3' ) )
  8896.             {
  8897.                 FactsSubstract( "GwentTournament", 3 );
  8898.             }
  8899.            
  8900.             else if ( dm.ItemHasTag( cardName, 'GT4' ) )
  8901.             {
  8902.                 FactsSubstract( "GwentTournament", 4 );
  8903.             }
  8904.            
  8905.             else if ( dm.ItemHasTag( cardName, 'GT5' ) )
  8906.             {
  8907.                 FactsSubstract( "GwentTournament", 5 );
  8908.             }
  8909.            
  8910.             else if ( dm.ItemHasTag( cardName, 'GT6' ) )
  8911.             {
  8912.                 FactsSubstract( "GwentTournament", 6 );
  8913.             }
  8914.            
  8915.             else if ( dm.ItemHasTag( cardName, 'GT7' ) )
  8916.             {
  8917.                 FactsSubstract( "GwentTournament", 7 );
  8918.             }
  8919.            
  8920.             CheckGwentTournamentDeck();
  8921.         }
  8922.            
  8923.            
  8924.         if( dm.ItemHasTag( cardName, 'EP2Tournament' ) )
  8925.         {
  8926.             if ( dm.ItemHasTag( cardName, 'GT1' ) )
  8927.             {
  8928.                 FactsSubstract( "EP2Tournament", 1 );
  8929.             }
  8930.            
  8931.             else if ( dm.ItemHasTag( cardName, 'GT2' ) )
  8932.             {
  8933.                 FactsSubstract( "EP2Tournament", 2 );
  8934.             }
  8935.            
  8936.             else if ( dm.ItemHasTag( cardName, 'GT3' ) )
  8937.             {
  8938.                 FactsSubstract( "EP2Tournament", 3 );
  8939.             }
  8940.            
  8941.             else if ( dm.ItemHasTag( cardName, 'GT4' ) )
  8942.             {
  8943.                 FactsSubstract( "EP2Tournament", 4 );
  8944.             }
  8945.            
  8946.             else if ( dm.ItemHasTag( cardName, 'GT5' ) )
  8947.             {
  8948.                 FactsSubstract( "EP2Tournament", 5 );
  8949.             }
  8950.            
  8951.             else if ( dm.ItemHasTag( cardName, 'GT6' ) )
  8952.             {
  8953.                 FactsSubstract( "EP2Tournament", 6 );
  8954.             }
  8955.            
  8956.             else if ( dm.ItemHasTag( cardName, 'GT7' ) )
  8957.             {
  8958.                 FactsSubstract( "EP2Tournament", 7 );
  8959.             }
  8960.            
  8961.             CheckEP2TournamentDeck();
  8962.         }
  8963.        
  8964.         return true;
  8965.     }
  8966.    
  8967.     function CheckGwentTournamentDeck()
  8968.     {
  8969.         var gwentPower          : int;
  8970.         var neededGwentPower    : int;
  8971.         var checkBreakpoint     : int;
  8972.        
  8973.         neededGwentPower = 70;
  8974.        
  8975.         checkBreakpoint = neededGwentPower/5;
  8976.         gwentPower = FactsQuerySum( "GwentTournament" );
  8977.        
  8978.         if ( gwentPower >= neededGwentPower )
  8979.         {
  8980.             FactsAdd( "HasGwentTournamentDeck", 1 );
  8981.         }
  8982.         else
  8983.         {
  8984.             if( FactsDoesExist( "HasGwentTournamentDeck" ) )
  8985.             {
  8986.                 FactsRemove( "HasGwentTournamentDeck" );
  8987.             }
  8988.            
  8989.             if ( gwentPower >= checkBreakpoint )
  8990.             {
  8991.                 FactsAdd( "GwentTournamentObjective1", 1 );
  8992.             }
  8993.             else if ( FactsDoesExist( "GwentTournamentObjective1" ) )
  8994.             {
  8995.                 FactsRemove( "GwentTournamentObjective1" );
  8996.             }
  8997.            
  8998.             if ( gwentPower >= checkBreakpoint*2 )
  8999.             {
  9000.                 FactsAdd( "GwentTournamentObjective2", 1 );
  9001.             }
  9002.             else if ( FactsDoesExist( "GwentTournamentObjective2" ) )
  9003.             {
  9004.                 FactsRemove( "GwentTournamentObjective2" );
  9005.             }
  9006.            
  9007.             if ( gwentPower >= checkBreakpoint*3 )
  9008.             {
  9009.                 FactsAdd( "GwentTournamentObjective3", 1 );
  9010.             }
  9011.             else if ( FactsDoesExist( "GwentTournamentObjective3" ) )
  9012.             {
  9013.                 FactsRemove( "GwentTournamentObjective3" );
  9014.             }
  9015.            
  9016.             if ( gwentPower >= checkBreakpoint*4 )
  9017.             {
  9018.                 FactsAdd( "GwentTournamentObjective4", 1 );
  9019.             }
  9020.             else if ( FactsDoesExist( "GwentTournamentObjective4" ) )
  9021.             {
  9022.                 FactsRemove( "GwentTournamentObjective4" );
  9023.             }
  9024.         }
  9025.     }
  9026.    
  9027.     function CheckEP2TournamentDeck()
  9028.     {
  9029.         var gwentPower          : int;
  9030.         var neededGwentPower    : int;
  9031.         var checkBreakpoint     : int;
  9032.        
  9033.         neededGwentPower = 24;
  9034.        
  9035.         checkBreakpoint = neededGwentPower/5;
  9036.         gwentPower = FactsQuerySum( "EP2Tournament" );
  9037.        
  9038.         if ( gwentPower >= neededGwentPower )
  9039.         {
  9040.             if( FactsQuerySum( "HasEP2TournamentDeck") == 0 )
  9041.             {
  9042.                 FactsAdd( "HasEP2TournamentDeck", 1 );
  9043.             }
  9044.            
  9045.         }
  9046.         else
  9047.         {
  9048.             if( FactsDoesExist( "HasEP2TournamentDeck" ) )
  9049.             {
  9050.                 FactsRemove( "HasEP2TournamentDeck" );
  9051.             }
  9052.            
  9053.             if ( gwentPower >= checkBreakpoint )
  9054.             {
  9055.                 FactsAdd( "EP2TournamentObjective1", 1 );
  9056.             }
  9057.             else if ( FactsDoesExist( "EP2TournamentObjective1" ) )
  9058.             {
  9059.                 FactsRemove( "EP2TournamentObjective1" );
  9060.             }
  9061.            
  9062.             if ( gwentPower >= checkBreakpoint*2 )
  9063.             {
  9064.                 FactsAdd( "EP2TournamentObjective2", 1 );
  9065.             }
  9066.             else if ( FactsDoesExist( "EP2TournamentObjective2" ) )
  9067.             {
  9068.                 FactsRemove( "EP2TournamentObjective2" );
  9069.             }
  9070.            
  9071.             if ( gwentPower >= checkBreakpoint*3 )
  9072.             {
  9073.                 FactsAdd( "EP2TournamentObjective3", 1 );
  9074.             }
  9075.             else if ( FactsDoesExist( "EP2TournamentObjective3" ) )
  9076.             {
  9077.                 FactsRemove( "EP2TournamentObjective3" );
  9078.             }
  9079.            
  9080.             if ( gwentPower >= checkBreakpoint*4 )
  9081.             {
  9082.                 FactsAdd( "EP2TournamentObjective4", 1 );
  9083.             }
  9084.             else if ( FactsDoesExist( "EP2TournamentObjective4" ) )
  9085.             {
  9086.                 FactsRemove( "EP2TournamentObjective4" );
  9087.             }
  9088.         }
  9089.     }
  9090.    
  9091.    
  9092.    
  9093.    
  9094.    
  9095.    
  9096.     public function SimulateBuffTimePassing(simulatedTime : float)
  9097.     {
  9098.         super.SimulateBuffTimePassing(simulatedTime);
  9099.        
  9100.         FinishQuen(true);
  9101.     }
  9102.    
  9103.    
  9104.     public function CanMeditate() : bool
  9105.     {
  9106.         var currentStateName : name;
  9107.        
  9108.         currentStateName = GetCurrentStateName();
  9109.        
  9110.        
  9111.         if(currentStateName == 'Exploration' && !CanPerformPlayerAction())
  9112.             return false;
  9113.        
  9114.        
  9115.         if(GetCurrentStateName() != 'Exploration' && GetCurrentStateName() != 'Meditation' && GetCurrentStateName() != 'MeditationWaiting')
  9116.             return false;
  9117.            
  9118.        
  9119.         if(GetUsedVehicle())
  9120.             return false;
  9121.            
  9122.        
  9123.         return CanMeditateHere();
  9124.     }
  9125.    
  9126.    
  9127.     public final function CanMeditateWait(optional skipMeditationStateCheck : bool) : bool
  9128.     {
  9129.         var currState : name;
  9130.        
  9131.         currState = GetCurrentStateName();
  9132.        
  9133.        
  9134.        
  9135.         if(!skipMeditationStateCheck && currState != 'Meditation')
  9136.             return false;
  9137.            
  9138.        
  9139.         if(theGame.IsGameTimePaused())
  9140.             return false;
  9141.            
  9142.         if(!IsActionAllowed( EIAB_MeditationWaiting ))
  9143.             return false;
  9144.            
  9145.         return true;
  9146.     }
  9147.  
  9148.    
  9149.     public final function CanMeditateHere() : bool
  9150.     {
  9151.         var pos : Vector;
  9152.        
  9153.         pos = GetWorldPosition();
  9154.         if(pos.Z <= theGame.GetWorld().GetWaterLevel(pos, true) && IsInShallowWater())
  9155.             return false;
  9156.        
  9157.         if(IsThreatened())
  9158.             return false;
  9159.        
  9160.         return true;
  9161.     }
  9162.    
  9163.    
  9164.     public function Meditate() : bool
  9165.     {
  9166.         var medState            : W3PlayerWitcherStateMeditation;
  9167.         var stateName           : name;
  9168.    
  9169.         stateName = GetCurrentStateName();
  9170.    
  9171.        
  9172.         if (!CanMeditate()  || stateName == 'MeditationWaiting' )
  9173.             return false;
  9174.    
  9175.         GotoState('Meditation');
  9176.         medState = (W3PlayerWitcherStateMeditation)GetState('Meditation');     
  9177.         medState.SetMeditationPointHeading(GetHeading());
  9178.        
  9179.         return true;
  9180.     }
  9181.    
  9182.    
  9183.     public final function MeditationRestoring(simulatedTime : float)
  9184.     {          
  9185.        
  9186.         if ( theGame.GetDifficultyMode() != EDM_Hard && theGame.GetDifficultyMode() != EDM_Hardcore )
  9187.         {
  9188.             Heal(GetStatMax(BCS_Vitality));
  9189.         }
  9190.        
  9191.        
  9192.         abilityManager.DrainToxicity( abilityManager.GetStat( BCS_Toxicity ) );
  9193.         abilityManager.DrainFocus( abilityManager.GetStat( BCS_Focus ) );
  9194.        
  9195.        
  9196.         inv.SingletonItemsRefillAmmo();
  9197.        
  9198.        
  9199.         SimulateBuffTimePassing(simulatedTime);
  9200.        
  9201.        
  9202.         ApplyWitcherHouseBuffs();
  9203.     }
  9204.    
  9205.     var clockMenu : CR4MeditationClockMenu;
  9206.    
  9207.     public function MeditationClockStart(m : CR4MeditationClockMenu)
  9208.     {
  9209.         clockMenu = m;
  9210.         AddTimer('UpdateClockTime',0.1,true);
  9211.     }
  9212.    
  9213.     public function MeditationClockStop()
  9214.     {
  9215.         clockMenu = NULL;
  9216.         RemoveTimer('UpdateClockTime');
  9217.     }
  9218.    
  9219.     public timer function UpdateClockTime(dt : float, id : int)
  9220.     {
  9221.         if(clockMenu)
  9222.             clockMenu.UpdateCurrentHours();
  9223.         else
  9224.             RemoveTimer('UpdateClockTime');
  9225.     }
  9226.    
  9227.     private var waitTimeHour : int;
  9228.     public function SetWaitTargetHour(t : int)
  9229.     {
  9230.         waitTimeHour = t;
  9231.     }
  9232.     public function GetWaitTargetHour() : int
  9233.     {
  9234.         return waitTimeHour;
  9235.     }
  9236.    
  9237.     public function MeditationForceAbort(forceCloseUI : bool)
  9238.     {
  9239.         var waitt : W3PlayerWitcherStateMeditationWaiting;
  9240.         var medd : W3PlayerWitcherStateMeditation;
  9241.         var currentStateName : name;
  9242.        
  9243.         currentStateName = GetCurrentStateName();
  9244.        
  9245.         if(currentStateName == 'MeditationWaiting')
  9246.         {
  9247.             waitt = (W3PlayerWitcherStateMeditationWaiting)GetCurrentState();
  9248.             if(waitt)
  9249.             {
  9250.                 waitt.StopRequested(forceCloseUI);
  9251.             }
  9252.         }
  9253.         else if(currentStateName == 'Meditation')
  9254.         {
  9255.             medd = (W3PlayerWitcherStateMeditation)GetCurrentState();
  9256.             if(medd)
  9257.             {
  9258.                 medd.StopRequested(forceCloseUI);
  9259.             }
  9260.         }
  9261.        
  9262.        
  9263.        
  9264.         if(forceCloseUI && theGame.GetGuiManager().IsAnyMenu())
  9265.         {
  9266.             theGame.GetGuiManager().GetRootMenu().CloseMenu();
  9267.             DisplayActionDisallowedHudMessage(EIAB_MeditationWaiting, false, false, true, false);
  9268.         }
  9269.     }
  9270.    
  9271.     public function Runeword10Triggerred()
  9272.     {
  9273.         var min, max : SAbilityAttributeValue;
  9274.        
  9275.         theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Runeword 10 _Stats', 'stamina', min, max );
  9276.         GainStat(BCS_Stamina, min.valueMultiplicative * GetStatMax(BCS_Stamina));
  9277.         PlayEffect('runeword_10_stamina');
  9278.     }
  9279.    
  9280.     public function Runeword12Triggerred()
  9281.     {
  9282.         var min, max : SAbilityAttributeValue;
  9283.        
  9284.         theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Runeword 12 _Stats', 'focus', min, max );
  9285.         GainStat(BCS_Focus, RandRangeF(max.valueAdditive, min.valueAdditive));
  9286.         PlayEffect('runeword_20_adrenaline');  
  9287.     }
  9288.    
  9289.     var runeword10TriggerredOnFinisher, runeword12TriggerredOnFinisher : bool;
  9290.    
  9291.     event OnFinisherStart()
  9292.     {
  9293.         super.OnFinisherStart();
  9294.        
  9295.         runeword10TriggerredOnFinisher = false;
  9296.         runeword12TriggerredOnFinisher = false;
  9297.     }
  9298.    
  9299.     public function ApplyWitcherHouseBuffs()
  9300.     {
  9301.         var l_bed           : W3WitcherBed;
  9302.        
  9303.         if( FactsQuerySum( "PlayerInsideInnerWitcherHouse" ) > 0 )
  9304.         {
  9305.             l_bed = (W3WitcherBed)theGame.GetEntityByTag( 'witcherBed' );
  9306.            
  9307.             if( l_bed.GetWasUsed() )
  9308.             {
  9309.                 if( l_bed.GetBedLevel() != 0 )
  9310.                 {
  9311.                     AddEffectDefault( EET_WellRested, this, "Bed Buff" );
  9312.                 }
  9313.  
  9314.                 if( FactsQuerySum( "StablesExists" ) )
  9315.                 {
  9316.                     AddEffectDefault( EET_HorseStableBuff, this, "Stables" );
  9317.                 }
  9318.                
  9319.                 if( l_bed.GetWereItemsRefilled() )
  9320.                 {
  9321.                     theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt( "message_common_alchemy_table_buff_applied" ),, true );
  9322.                     l_bed.SetWereItemsRefilled( false );
  9323.                 }
  9324.                
  9325.                 AddEffectDefault( EET_BookshelfBuff, this, "Bookshelf" );
  9326.                
  9327.                 Heal( GetStatMax( BCS_Vitality ) );
  9328.             }
  9329.         }
  9330.     }
  9331.    
  9332.    
  9333.    
  9334.    
  9335.    
  9336.     public function CheatResurrect()
  9337.     {
  9338.         super.CheatResurrect();
  9339.         theGame.ReleaseNoSaveLock(theGame.deathSaveLockId);
  9340.         theInput.RestoreContext( 'Exploration', true );
  9341.     }
  9342.    
  9343.    
  9344.     public function Debug_EquipTestingSkills(equip : bool, force : bool)
  9345.     {
  9346.         var skills : array<ESkill>;
  9347.         var i, slot : int;
  9348.        
  9349.        
  9350.         ((W3PlayerAbilityManager)abilityManager).OnLevelGained(36);
  9351.        
  9352.         skills.PushBack(S_Magic_s01);
  9353.         skills.PushBack(S_Magic_s02);
  9354.         skills.PushBack(S_Magic_s03);
  9355.         skills.PushBack(S_Magic_s04);
  9356.         skills.PushBack(S_Magic_s05);
  9357.         skills.PushBack(S_Sword_s01);
  9358.         skills.PushBack(S_Sword_s02);
  9359.        
  9360.        
  9361.         if(equip)
  9362.         {
  9363.             for(i=0; i<skills.Size(); i+=1)
  9364.             {
  9365.                 if(!force && IsSkillEquipped(skills[i]))
  9366.                     continue;
  9367.                    
  9368.                
  9369.                 if(GetSkillLevel(skills[i]) == 0)
  9370.                     AddSkill(skills[i]);
  9371.                
  9372.                
  9373.                 if(force)
  9374.                     slot = i+1;    
  9375.                 else
  9376.                     slot = GetFreeSkillSlot();
  9377.                
  9378.                
  9379.                 EquipSkill(skills[i], slot);
  9380.             }
  9381.         }
  9382.         else
  9383.         {
  9384.             for(i=0; i<skills.Size(); i+=1)
  9385.             {
  9386.                 UnequipSkill(GetSkillSlotID(skills[i]));
  9387.             }
  9388.         }
  9389.     }
  9390.    
  9391.     public function Debug_ClearCharacterDevelopment(optional keepInv : bool)
  9392.     {
  9393.         var template : CEntityTemplate;
  9394.         var entity : CEntity;
  9395.         var invTesting : CInventoryComponent;
  9396.         var i : int;
  9397.         var items : array<SItemUniqueId>;
  9398.         var abs : array<name>;
  9399.    
  9400.         delete abilityManager;
  9401.         delete levelManager;
  9402.         delete effectManager;
  9403.        
  9404.        
  9405.         GetCharacterStats().GetAbilities(abs, false);
  9406.         for(i=0; i<abs.Size(); i+=1)
  9407.             RemoveAbility(abs[i]);
  9408.            
  9409.        
  9410.         abs.Clear();
  9411.         GetCharacterStatsParam(abs);       
  9412.         for(i=0; i<abs.Size(); i+=1)
  9413.             AddAbility(abs[i]);
  9414.                    
  9415.        
  9416.         levelManager = new W3LevelManager in this;         
  9417.         levelManager.Initialize();
  9418.         levelManager.PostInit(this, false, true);      
  9419.                        
  9420.        
  9421.         AddAbility('GeraltSkills_Testing');
  9422.         SetAbilityManager();       
  9423.         abilityManager.Init(this, GetCharacterStats(), false, theGame.GetDifficultyMode());
  9424.        
  9425.         SetEffectManager();
  9426.        
  9427.         abilityManager.PostInit();                     
  9428.        
  9429.        
  9430.        
  9431.        
  9432.        
  9433.         if(!keepInv)
  9434.         {
  9435.             inv.RemoveAllItems();
  9436.         }      
  9437.        
  9438.        
  9439.         template = (CEntityTemplate)LoadResource("geralt_inventory_release");
  9440.         entity = theGame.CreateEntity(template, Vector(0,0,0));
  9441.         invTesting = (CInventoryComponent)entity.GetComponentByClassName('CInventoryComponent');
  9442.         invTesting.GiveAllItemsTo(inv, true);
  9443.         entity.Destroy();
  9444.        
  9445.        
  9446.         inv.GetAllItems(items);
  9447.         for(i=0; i<items.Size(); i+=1)
  9448.         {
  9449.             if(!inv.ItemHasTag(items[i], 'NoDrop'))        
  9450.                 EquipItem(items[i]);
  9451.         }
  9452.            
  9453.        
  9454.         Debug_GiveTestingItems(0);
  9455.     }
  9456.    
  9457.     function Debug_BearSetBonusQuenSkills()
  9458.     {
  9459.         var skills  : array<ESkill>;
  9460.         var i, slot : int;
  9461.        
  9462.         skills.PushBack(S_Magic_s04);
  9463.         skills.PushBack(S_Magic_s14);
  9464.        
  9465.         for(i=0; i<skills.Size(); i+=1)
  9466.         {              
  9467.            
  9468.             if(GetSkillLevel(skills[i]) == 0)
  9469.             {
  9470.                 AddSkill(skills[i]);
  9471.             }
  9472.            
  9473.             slot = GetFreeSkillSlot();
  9474.            
  9475.            
  9476.             EquipSkill(skills[i], slot);
  9477.         }
  9478.     }
  9479.    
  9480.     final function Debug_HAX_UnlockSkillSlot(slotIndex : int) : bool
  9481.     {
  9482.         if(abilityManager && abilityManager.IsInitialized())
  9483.             return ((W3PlayerAbilityManager)abilityManager).Debug_HAX_UnlockSkillSlot(slotIndex);
  9484.            
  9485.         return false;
  9486.     }
  9487.    
  9488.    
  9489.     public function GetLevelupAbility( id : int) : name
  9490.     {
  9491.         switch(id)
  9492.         {
  9493.             case 1: return 'Lvl1';
  9494.             case 2: return 'Lvl2';
  9495.             case 3: return 'Lvl3';
  9496.             case 4: return 'Lvl4';
  9497.             case 5: return 'Lvl5';
  9498.             case 6: return 'Lvl6';
  9499.             case 7: return 'Lvl7';
  9500.             case 8: return 'Lvl8';
  9501.             case 9: return 'Lvl9';
  9502.             case 10: return 'Lvl10';
  9503.             case 11: return 'Lvl11';
  9504.             case 12: return 'Lvl12';
  9505.             case 13: return 'Lvl13';
  9506.             case 14: return 'Lvl14';
  9507.             case 15: return 'Lvl15';
  9508.             case 16: return 'Lvl16';
  9509.             case 17: return 'Lvl17';
  9510.             case 18: return 'Lvl18';
  9511.             case 19: return 'Lvl19';
  9512.             case 20: return 'Lvl20';
  9513.             case 21: return 'Lvl21';
  9514.             case 22: return 'Lvl22';
  9515.             case 23: return 'Lvl23';
  9516.             case 24: return 'Lvl24';
  9517.             case 25: return 'Lvl25';
  9518.             case 26: return 'Lvl26';
  9519.             case 27: return 'Lvl27';
  9520.             case 28: return 'Lvl28';
  9521.             case 29: return 'Lvl29';
  9522.             case 30: return 'Lvl30';
  9523.             case 31: return 'Lvl31';
  9524.             case 32: return 'Lvl32';
  9525.             case 33: return 'Lvl33';
  9526.             case 34: return 'Lvl34';
  9527.             case 35: return 'Lvl35';
  9528.             case 36: return 'Lvl36';
  9529.             case 37: return 'Lvl37';
  9530.             case 38: return 'Lvl38';
  9531.             case 39: return 'Lvl39';
  9532.             case 40: return 'Lvl40';
  9533.             case 41: return 'Lvl41';
  9534.             case 42: return 'Lvl42';
  9535.             case 43: return 'Lvl43';
  9536.             case 44: return 'Lvl44';
  9537.             case 45: return 'Lvl45';
  9538.             case 46: return 'Lvl46';
  9539.             case 47: return 'Lvl47';
  9540.             case 48: return 'Lvl48';
  9541.             case 49: return 'Lvl49';
  9542.             case 50: return 'Lvl50';
  9543.        
  9544.             default: return '';
  9545.         }
  9546.        
  9547.         return '';
  9548.     }  
  9549.    
  9550.     public function CanSprint( speed : float ) : bool
  9551.     {
  9552.         if( !super.CanSprint( speed ) )
  9553.         {
  9554.             return false;
  9555.         }      
  9556.         if( rangedWeapon && rangedWeapon.GetCurrentStateName() != 'State_WeaponWait' )
  9557.         {
  9558.             if ( this.GetPlayerCombatStance() ==  PCS_AlertNear )
  9559.             {
  9560.                 if ( IsSprintActionPressed() )
  9561.                     OnRangedForceHolster( true, false );
  9562.             }
  9563.             else
  9564.                 return false;
  9565.         }
  9566.         if( GetCurrentStateName() != 'Swimming' && GetStat(BCS_Stamina) <= 0 )
  9567.         {
  9568.             SetSprintActionPressed(false,true);
  9569.             return false;
  9570.         }
  9571.        
  9572.         return true;
  9573.     }
  9574.    
  9575.     public function ManageSleeping()
  9576.     {
  9577.         thePlayer.RemoveBuffImmunity_AllCritical( 'Bed' );
  9578.         thePlayer.RemoveBuffImmunity_AllNegative( 'Bed' );
  9579.  
  9580.         thePlayer.PlayerStopAction( PEA_GoToSleep );
  9581.     }
  9582.    
  9583.    
  9584.    
  9585.     public function RestoreHorseManager() : bool
  9586.     {
  9587.         var horseTemplate   : CEntityTemplate;
  9588.         var horseManager    : W3HorseManager;  
  9589.        
  9590.         if ( GetHorseManager() )
  9591.         {
  9592.             return false;
  9593.         }
  9594.        
  9595.         horseTemplate = (CEntityTemplate)LoadResource("horse_manager");
  9596.         horseManager = (W3HorseManager)theGame.CreateEntity(horseTemplate, GetWorldPosition(),,,,,PM_Persist);
  9597.         horseManager.CreateAttachment(this);
  9598.         horseManager.OnCreated();
  9599.         EntityHandleSet( horseManagerHandle, horseManager );   
  9600.        
  9601.         return true;
  9602.     }
  9603.    
  9604.    
  9605.    
  9606.    
  9607.    
  9608.    
  9609.     final function PerformParryCheck( parryInfo : SParryInfo ) : bool
  9610.     {
  9611.         if( super.PerformParryCheck( parryInfo ) )
  9612.         {
  9613.             GainAdrenalineFromPerk21( 'parry' );
  9614.             return true;
  9615.         }
  9616.         return false;
  9617.     }  
  9618.    
  9619.     protected final function PerformCounterCheck( parryInfo: SParryInfo ) : bool
  9620.     {
  9621.         var fistFightCheck, isInFistFight       : bool;
  9622.        
  9623.         if( super.PerformCounterCheck( parryInfo ) )
  9624.         {
  9625.             GainAdrenalineFromPerk21( 'counter' );
  9626.            
  9627.             isInFistFight = FistFightCheck( parryInfo.target, parryInfo.attacker, fistFightCheck );
  9628.            
  9629.             if( isInFistFight && fistFightCheck )
  9630.             {
  9631.                 FactsAdd( "statistics_fist_fight_counter" );
  9632.                 AddTimer( 'FistFightCounterTimer', 0.5f, , , , true );
  9633.             }
  9634.            
  9635.             return true;
  9636.         }
  9637.         return false;
  9638.     }
  9639.    
  9640.     public function GainAdrenalineFromPerk21( n : name )
  9641.     {
  9642.         var perkStats, perkTime : SAbilityAttributeValue;
  9643.         var targets : array<CActor>;
  9644.        
  9645.         targets = GetHostileEnemies();
  9646.        
  9647.         if( !CanUseSkill( S_Perk_21 ) || targets.Size() == 0 )
  9648.         {
  9649.             return;
  9650.         }
  9651.        
  9652.         perkTime = GetSkillAttributeValue( S_Perk_21, 'perk21Time', false, false );
  9653.        
  9654.         if( theGame.GetEngineTimeAsSeconds() >= timeForPerk21 + perkTime.valueAdditive )
  9655.         {
  9656.             perkStats = GetSkillAttributeValue( S_Perk_21, n , false, false );
  9657.             GainStat( BCS_Focus, perkStats.valueAdditive );
  9658.             timeForPerk21 = theGame.GetEngineTimeAsSeconds();
  9659.            
  9660.             AddEffectDefault( EET_Perk21InternalCooldown, this, "Perk21", false );
  9661.         }  
  9662.     }
  9663.    
  9664.     timer function FistFightCounterTimer( dt : float, id : int )
  9665.     {
  9666.         FactsRemove( "statistics_fist_fight_counter" );
  9667.     }
  9668.    
  9669.     public final function IsSignBlocked(signType : ESignType) : bool
  9670.     {
  9671.         switch( signType )
  9672.         {
  9673.             case ST_Aard :
  9674.                 return IsRadialSlotBlocked ( 'Aard');
  9675.                 break;
  9676.             case ST_Axii :
  9677.                 return IsRadialSlotBlocked ( 'Axii');
  9678.                 break;
  9679.             case ST_Igni :
  9680.                 return IsRadialSlotBlocked ( 'Igni');
  9681.                 break;
  9682.             case ST_Quen :
  9683.                 return IsRadialSlotBlocked ( 'Quen');
  9684.                 break;
  9685.             case ST_Yrden :
  9686.                 return IsRadialSlotBlocked ( 'Yrden');
  9687.                 break;
  9688.             default:
  9689.                 break;
  9690.         }
  9691.         return false;
  9692.        
  9693.     }
  9694.    
  9695.     public final function AddAnItemWithAutogenLevelAndQuality(itemName : name, desiredLevel : int, minQuality : int, optional equipItem : bool)
  9696.     {
  9697.         var itemLevel, quality : int;
  9698.         var ids : array<SItemUniqueId>;
  9699.         var attemptCounter : int;
  9700.        
  9701.         itemLevel = 0;
  9702.         quality = 0;
  9703.         attemptCounter = 0;
  9704.         while(itemLevel != desiredLevel || quality < minQuality)
  9705.         {
  9706.             attemptCounter += 1;
  9707.             ids.Clear();
  9708.             ids = inv.AddAnItem(itemName, 1, true);
  9709.             itemLevel = inv.GetItemLevel(ids[0]);
  9710.             quality = RoundMath(CalculateAttributeValue(inv.GetItemAttributeValue(ids[0], 'quality')));
  9711.            
  9712.            
  9713.             if(attemptCounter >= 1000)
  9714.                 break;
  9715.            
  9716.             if(itemLevel != desiredLevel || quality < minQuality)
  9717.                 inv.RemoveItem(ids[0]);
  9718.         }
  9719.        
  9720.         if(equipItem)
  9721.             EquipItem(ids[0]);
  9722.     }
  9723.    
  9724.     public final function AddAnItemWithAutogenLevel(itemName : name, desiredLevel : int)
  9725.     {
  9726.         var itemLevel : int;
  9727.         var ids : array<SItemUniqueId>;
  9728.         var attemptCounter : int;
  9729.  
  9730.         itemLevel = 0;
  9731.         while(itemLevel != desiredLevel)
  9732.         {
  9733.             attemptCounter += 1;
  9734.             ids.Clear();
  9735.             ids = inv.AddAnItem(itemName, 1, true);
  9736.             itemLevel = inv.GetItemLevel(ids[0]);
  9737.            
  9738.            
  9739.             if(attemptCounter >= 1000)
  9740.                 break;
  9741.                
  9742.             if(itemLevel != desiredLevel)
  9743.                 inv.RemoveItem(ids[0]);
  9744.         }
  9745.     }
  9746.    
  9747.     public final function AddAnItemWithMinQuality(itemName : name, minQuality : int, optional equip : bool)
  9748.     {
  9749.         var quality : int;
  9750.         var ids : array<SItemUniqueId>;
  9751.         var attemptCounter : int;
  9752.  
  9753.         quality = 0;
  9754.         while(quality < minQuality)
  9755.         {
  9756.             attemptCounter += 1;
  9757.             ids.Clear();
  9758.             ids = inv.AddAnItem(itemName, 1, true);
  9759.             quality = RoundMath(CalculateAttributeValue(inv.GetItemAttributeValue(ids[0], 'quality')));
  9760.            
  9761.            
  9762.             if(attemptCounter >= 1000)
  9763.                 break;
  9764.                
  9765.             if(quality < minQuality)
  9766.                 inv.RemoveItem(ids[0]);
  9767.         }
  9768.        
  9769.         if(equip)
  9770.             EquipItem(ids[0]);
  9771.     }
  9772.    
  9773.    
  9774.    
  9775.    
  9776.    
  9777.    
  9778.     public function IsSetBonusActive( bonus : EItemSetBonus ) : bool
  9779.     {
  9780.         switch(bonus)
  9781.         {
  9782.             case EISB_Lynx_1:           return amountOfSetPiecesEquipped[ EIST_Lynx ] >= theGame.params.ITEMS_REQUIRED_FOR_MINOR_SET_BONUS;
  9783.             case EISB_Lynx_2:           return amountOfSetPiecesEquipped[ EIST_Lynx ] >= theGame.params.ITEMS_REQUIRED_FOR_MAJOR_SET_BONUS;
  9784.             case EISB_Gryphon_1:        return amountOfSetPiecesEquipped[ EIST_Gryphon ] >= theGame.params.ITEMS_REQUIRED_FOR_MINOR_SET_BONUS;
  9785.             case EISB_Gryphon_2:        return amountOfSetPiecesEquipped[ EIST_Gryphon ] >= theGame.params.ITEMS_REQUIRED_FOR_MAJOR_SET_BONUS;
  9786.             case EISB_Bear_1:           return amountOfSetPiecesEquipped[ EIST_Bear ] >= theGame.params.ITEMS_REQUIRED_FOR_MINOR_SET_BONUS;
  9787.             case EISB_Bear_2:           return amountOfSetPiecesEquipped[ EIST_Bear ] >= theGame.params.ITEMS_REQUIRED_FOR_MAJOR_SET_BONUS;
  9788.             case EISB_Wolf_1:           return amountOfSetPiecesEquipped[ EIST_Wolf ] >= theGame.params.ITEMS_REQUIRED_FOR_MINOR_SET_BONUS;
  9789.             case EISB_Wolf_2:           return amountOfSetPiecesEquipped[ EIST_Wolf ] >= theGame.params.ITEMS_REQUIRED_FOR_MAJOR_SET_BONUS;
  9790.             case EISB_RedWolf_1:        return amountOfSetPiecesEquipped[ EIST_RedWolf ] >= theGame.params.ITEMS_REQUIRED_FOR_MINOR_SET_BONUS;
  9791.             case EISB_RedWolf_2:        return amountOfSetPiecesEquipped[ EIST_RedWolf ] >= theGame.params.ITEMS_REQUIRED_FOR_MAJOR_SET_BONUS;
  9792.             case EISB_Vampire:          return amountOfSetPiecesEquipped[ EIST_Vampire ] >= theGame.params.ITEMS_REQUIRED_FOR_MINOR_SET_BONUS;
  9793.             default:                    return false;
  9794.         }
  9795.     }
  9796.    
  9797.     public function GetSetPartsEquipped( setType : EItemSetType ) : int
  9798.     {
  9799.         return amountOfSetPiecesEquipped[ setType ];
  9800.     }
  9801.    
  9802.     protected function UpdateItemSetBonuses( item : SItemUniqueId, increment : bool )
  9803.     {
  9804.         var setType : EItemSetType;
  9805.         var tutorialStateSets : W3TutorialManagerUIHandlerStateSetItemsUnlocked;
  9806.         var id : SItemUniqueId;
  9807.                    
  9808.         if( !inv.IsIdValid( item ) || !inv.ItemHasTag(item, theGame.params.ITEM_SET_TAG_BONUS ) )  
  9809.         {
  9810.            
  9811.             if( !IsSetBonusActive( EISB_Wolf_1 ) )
  9812.             {
  9813.                 if( GetItemEquippedOnSlot( EES_SteelSword, id ) )
  9814.                 {
  9815.                     RemoveExtraOilsFromItem( id );
  9816.                 }
  9817.                 if( GetItemEquippedOnSlot( EES_SilverSword, id ) )
  9818.                 {
  9819.                     RemoveExtraOilsFromItem( id );
  9820.                 }
  9821.             }
  9822.        
  9823.             return;
  9824.         }
  9825.        
  9826.         setType = CheckSetType( item );
  9827.        
  9828.         if( increment )
  9829.         {
  9830.             amountOfSetPiecesEquipped[ setType ] += 1;
  9831.            
  9832.             if( amountOfSetPiecesEquipped[ setType ] >= theGame.params.ITEMS_REQUIRED_FOR_MINOR_SET_BONUS && ShouldProcessTutorial( 'TutorialSetBonusesUnlocked' ) && theGame.GetTutorialSystem().uiHandler && theGame.GetTutorialSystem().uiHandler.GetCurrentStateName() == 'SetItemsUnlocked' )
  9833.             {
  9834.                 tutorialStateSets = ( W3TutorialManagerUIHandlerStateSetItemsUnlocked )theGame.GetTutorialSystem().uiHandler.GetCurrentState();
  9835.                 tutorialStateSets.OnSetBonusCompleted();
  9836.             }
  9837.         }
  9838.         else if( amountOfSetPiecesEquipped[ setType ] > 0 )
  9839.         {
  9840.             amountOfSetPiecesEquipped[ setType ] -= 1;
  9841.         }
  9842.        
  9843.        
  9844.         if( setType != EIST_Vampire && amountOfSetPiecesEquipped[ setType ] == theGame.params.ITEMS_REQUIRED_FOR_MAJOR_SET_BONUS )
  9845.         {
  9846.             theGame.GetGamerProfile().AddAchievement( EA_ReadyToRoll );
  9847.         }
  9848.        
  9849.        
  9850.         if( !IsSetBonusActive( EISB_Wolf_1 ) )
  9851.         {
  9852.             if( GetItemEquippedOnSlot( EES_SteelSword, id ) )
  9853.             {
  9854.                 RemoveExtraOilsFromItem( id );
  9855.             }
  9856.             if( GetItemEquippedOnSlot( EES_SilverSword, id ) )
  9857.             {
  9858.                 RemoveExtraOilsFromItem( id );
  9859.             }
  9860.         }
  9861.        
  9862.         ManageActiveSetBonuses( setType );
  9863.        
  9864.        
  9865.         ManageSetBonusesSoundbanks( setType );
  9866.     }
  9867.    
  9868.     public function ManageActiveSetBonuses( setType : EItemSetType )
  9869.     {
  9870.         var l_i             : int;
  9871.        
  9872.        
  9873.         if( setType == EIST_Lynx )
  9874.         {
  9875.            
  9876.             if( HasBuff( EET_LynxSetBonus ) && !IsSetBonusActive( EISB_Lynx_1 ) )
  9877.             {
  9878.                 RemoveBuff( EET_LynxSetBonus );
  9879.             }
  9880.         }
  9881.        
  9882.         else if( setType == EIST_Gryphon )
  9883.         {
  9884.            
  9885.             if( !IsSetBonusActive( EISB_Gryphon_1 ) )
  9886.             {
  9887.                 RemoveBuff( EET_GryphonSetBonus );
  9888.             }
  9889.            
  9890.             if( IsSetBonusActive( EISB_Gryphon_2 ) && !HasBuff( EET_GryphonSetBonusYrden ) )
  9891.             {
  9892.                 for( l_i = 0 ; l_i < yrdenEntities.Size() ; l_i += 1 )
  9893.                 {
  9894.                     if( yrdenEntities[ l_i ].GetIsPlayerInside() && !yrdenEntities[ l_i ].IsAlternateCast() )
  9895.                     {
  9896.                         AddEffectDefault( EET_GryphonSetBonusYrden, this, "GryphonSetBonusYrden" );
  9897.                         break;
  9898.                     }
  9899.                 }
  9900.             }
  9901.             else
  9902.             {
  9903.                 RemoveBuff( EET_GryphonSetBonusYrden );
  9904.             }
  9905.         }
  9906.     }
  9907.    
  9908.     public function CheckSetTypeByName( itemName : name ) : EItemSetType
  9909.     {
  9910.         var dm : CDefinitionsManagerAccessor;
  9911.        
  9912.         dm = theGame.GetDefinitionsManager();
  9913.        
  9914.         if( dm.ItemHasTag( itemName, theGame.params.ITEM_SET_TAG_LYNX ) )
  9915.         {
  9916.             return EIST_Lynx;
  9917.         }
  9918.         else
  9919.         if( dm.ItemHasTag( itemName, theGame.params.ITEM_SET_TAG_GRYPHON ) )
  9920.         {
  9921.             return EIST_Gryphon;
  9922.         }
  9923.         else
  9924.         if( dm.ItemHasTag( itemName, theGame.params.ITEM_SET_TAG_BEAR ) )
  9925.         {
  9926.             return EIST_Bear;
  9927.         }
  9928.         else
  9929.         if( dm.ItemHasTag( itemName, theGame.params.ITEM_SET_TAG_WOLF ) )
  9930.         {
  9931.             return EIST_Wolf;
  9932.         }
  9933.         else
  9934.         if( dm.ItemHasTag( itemName, theGame.params.ITEM_SET_TAG_RED_WOLF ) )
  9935.         {
  9936.             return EIST_RedWolf;
  9937.         }
  9938.         else
  9939.         if( dm.ItemHasTag( itemName, theGame.params.ITEM_SET_TAG_VAMPIRE ) )
  9940.         {
  9941.             return EIST_Vampire;
  9942.         }
  9943.         else
  9944.         if( dm.ItemHasTag( itemName, theGame.params.ITEM_SET_TAG_VIPER ) )
  9945.         {
  9946.             return EIST_Viper;
  9947.         }
  9948.         else
  9949.         {
  9950.             return EIST_Undefined;
  9951.         }
  9952.     }
  9953.    
  9954.     public function CheckSetType( item : SItemUniqueId ) : EItemSetType
  9955.     {
  9956.         var stopLoop    : bool;
  9957.         var tags        : array<name>;
  9958.         var i           : int;
  9959.         var setType     : EItemSetType;
  9960.        
  9961.         stopLoop = false;
  9962.        
  9963.         inv.GetItemTags( item, tags );
  9964.        
  9965.        
  9966.         for( i=0; i<tags.Size(); i+=1 )
  9967.         {
  9968.             switch( tags[i] )
  9969.             {
  9970.                 case theGame.params.ITEM_SET_TAG_LYNX:
  9971.                 case theGame.params.ITEM_SET_TAG_GRYPHON:
  9972.                 case theGame.params.ITEM_SET_TAG_BEAR:
  9973.                 case theGame.params.ITEM_SET_TAG_WOLF:
  9974.                 case theGame.params.ITEM_SET_TAG_RED_WOLF:
  9975.                 case theGame.params.ITEM_SET_TAG_VAMPIRE:
  9976.                 case theGame.params.ITEM_SET_TAG_VIPER:
  9977.                     setType = SetItemNameToType( tags[i] );
  9978.                     stopLoop = true;
  9979.                     break;
  9980.             }      
  9981.             if ( stopLoop )
  9982.             {
  9983.                 break;
  9984.             }
  9985.         }
  9986.   &nbs