SHARE
TWEET

Untitled

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