SHARE
TWEET

Untitled

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