Advertisement
Guest User

playerWitcher.ws script

a guest
Sep 2nd, 2019
276
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 371.36 KB | None | 0 0
  1. /***********************************************************************/
  2. /**     © 2015 CD PROJEKT S.A. All rights reserved.
  3. /**     THE WITCHER® is a trademark of CD PROJEKT S. A.
  4. /**     The Witcher game is based on the prose of Andrzej Sapkowski.
  5. /***********************************************************************/
  6.  
  7.  
  8.  
  9.  
  10. statemachine class W3PlayerWitcher extends CR4Player
  11. {  
  12.     var ftPack : FastTravelPack; // mod Fast Travel Pack
  13.     //---=== modPreparations ===---
  14.     var openFireEnt                                     : CGameplayEntity;
  15.     var prepConfig                                      : CModPreparationsConfig;
  16.     //---=== modPreparations ===---
  17.     private saved var craftingSchematics                : array<name>;                 
  18.     private saved var expandedCraftingCategories        : array<name>;
  19.     private saved var craftingFilters : SCraftingFilters;
  20.    
  21.    
  22.     private saved var alchemyRecipes                    : array<name>;                 
  23.     private saved var expandedAlchemyCategories         : array<name>;
  24.     private saved var alchemyFilters : SCraftingFilters;
  25.    
  26.     // -= WMK:modAQOOM =-
  27.     public saved var wmkMapMenuData : WmkMapMenuData;
  28.     public var wmkMapMenu : WmkMapMenuEx;
  29.     // -= WMK:modAQOOM =-
  30.    
  31.     private saved var expandedBestiaryCategories        : array<name>;
  32.    
  33.    
  34.     private saved var booksRead                         : array<name>;                 
  35.    
  36.     private saved var enemiesKilledByType               : array<int>; //modSigns
  37.    
  38.    
  39.     //---=== modFriendlyMeditation ===---
  40.     public              var fMeditationConfig           : CModFMeditationConfig;
  41.     //---=== modFriendlyMeditation ===---
  42.    
  43.     private             var fastAttackCounter, heavyAttackCounter   : int;     
  44.     private             var isInFrenzy : bool;
  45.     private             var hasRecentlyCountered : bool;
  46.     //private saved         var cannotUseUndyingSkill : bool;                      
  47.    
  48.    
  49.     protected saved         var amountOfSetPiecesEquipped           : array<int>;
  50.    
  51.    
  52.     //---=== modFriendlyMeditation ===---
  53.                         var spawnedCampFire                 : W3Campfire;
  54.                         var fmedCanSpawnCampfire            : bool;
  55.                         default fmedCanSpawnCampfire = true;
  56.                         var fmedAutorefillAlchemy           : bool;
  57.                         default fmedAutorefillAlchemy = true;
  58.                         var fmedRefillIntervalSeconds       : float;
  59.                         default fmedRefillIntervalSeconds = 3600.0;
  60.                         var fmedApplyWitcherHouseBuffs      : bool;
  61.                         default fmedApplyWitcherHouseBuffs = true;
  62.                         var fmedWitcherHouseBuffsHours  : int;
  63.                         default fmedWitcherHouseBuffsHours = 1;
  64.     //---=== modFriendlyMeditation ===---
  65.    
  66.    
  67.     public              var canSwitchFocusModeTarget    : bool;
  68.     protected           var switchFocusModeTargetAllowed : bool;
  69.         default canSwitchFocusModeTarget = true;
  70.         default switchFocusModeTargetAllowed = true;
  71.    
  72.    
  73.     private editable    var signs                       : array< SWitcherSign >;
  74.     private saved       var equippedSign                : ESignType;
  75.     private             var currentlyCastSign           : ESignType; default currentlyCastSign = ST_None;
  76.     private             var signOwner                   : W3SignOwnerPlayer;
  77.     private             var usedQuenInCombat            : bool;
  78.     public              var yrdenEntities               : array<W3YrdenEntity>;
  79.     public saved        var m_quenReappliedCount        : int;
  80.    
  81.     default             equippedSign    = ST_Aard;
  82.     default             m_quenReappliedCount = 1;
  83.    
  84.    
  85.    
  86.     private             var bDispalyHeavyAttackIndicator        : bool;
  87.     private             var bDisplayHeavyAttackFirstLevelTimer  : bool;
  88.     public              var specialAttackHeavyAllowed           : bool;
  89.  
  90.     default bIsCombatActionAllowed = true; 
  91.     default bDispalyHeavyAttackIndicator = false;
  92.     default bDisplayHeavyAttackFirstLevelTimer = true;
  93.    
  94.     //modFriendlyStash begin
  95.     public              var fStashConfig                : CModFriendlyStashConfig;
  96.     //modFriendlyStash end
  97.    
  98.    
  99.    
  100.         default explorationInputContext = 'Exploration';
  101.         default combatInputContext = 'Combat';
  102.         default combatFistsInputContext = 'Combat';
  103.        
  104.    
  105.     private saved var companionNPCTag       : name;
  106.     private saved var companionNPCTag2      : name;
  107.    
  108.     private saved var companionNPCIconPath  : string;
  109.     private saved var companionNPCIconPath2 : string;  
  110.        
  111.    
  112.     private       saved var itemSlots                   : array<SItemUniqueId>;
  113.     private             var remainingBombThrowDelaySlot1    : float;
  114.     private             var remainingBombThrowDelaySlot2    : float;
  115.     private             var previouslyUsedBolt : SItemUniqueId;            
  116.     private       saved var questMarkedSelectedQuickslotItems : array< SSelectedQuickslotItem >;
  117.    
  118.     default isThrowingItem = false;
  119.     default remainingBombThrowDelaySlot1 = 0.f;
  120.     default remainingBombThrowDelaySlot2 = 0.f;
  121.    
  122.    
  123.    
  124.    
  125.    
  126.     private saved var tempLearnedSignSkills : array<SSimpleSkill>;     
  127.     public  saved var autoLevel             : bool;                    
  128.    
  129.    
  130.    
  131.    
  132.     protected saved var skillBonusPotionEffect          : CBaseGameplayEffect;         
  133.    
  134.    
  135.     public saved        var levelManager                : W3LevelManager;
  136.    
  137.     //---=== modFriendlyHUD ===---
  138.     public              var prepDisallowOilsInCombat    : bool;     default prepDisallowOilsInCombat = false;
  139.     public              var prepOilsHaveAmmo            : bool;     default prepOilsHaveAmmo = false;
  140.     //---=== modFriendlyHUD ===---
  141.  
  142.    
  143.     saved var reputationManager : W3Reputation;
  144.    
  145.    
  146.     private editable    var medallionEntity         : CEntityTemplate;
  147.     private             var medallionController     : W3MedallionController;
  148.    
  149.    
  150.    
  151.    
  152.     public              var bShowRadialMenu : bool;
  153.  
  154.     private             var _HoldBeforeOpenRadialMenuTime : float;
  155.    
  156.     default _HoldBeforeOpenRadialMenuTime = 0.5f;
  157.    
  158.     public var MappinToHighlight : array<SHighlightMappin>;
  159.    
  160.    
  161.     protected saved var horseManagerHandle          : EntityHandle;    
  162.    
  163.  
  164.     private var isInitialized : bool;
  165.     private var timeForPerk21 : float;
  166.    
  167.         default isInitialized = false;
  168.        
  169.    
  170.     private var invUpdateTransaction : bool;
  171.         default invUpdateTransaction = false;
  172.    
  173.     //modToggleCatNoPotion++
  174.     public var catToggler : CatToggler;
  175.     //modToggleCatNoPotion--
  176.    
  177.    
  178.    
  179.    
  180.    
  181.    
  182.    
  183.    
  184.    
  185.    
  186.    
  187.     event OnSpawned( spawnData : SEntitySpawnData )
  188.     {
  189.         var i               : int;
  190.         var items           : array<SItemUniqueId>;
  191.         var items2          : array<SItemUniqueId>;
  192.         var horseTemplate   : CEntityTemplate;
  193.         var horseManager    : W3HorseManager;
  194.         var currWorld       : CWorld = theGame.GetWorld(); // mod Fast Travel Pack
  195.        
  196.         AddAnimEventCallback( 'ActionBlend',            'OnAnimEvent_ActionBlend' );
  197.         AddAnimEventCallback('cast_begin',              'OnAnimEvent_Sign');
  198.         AddAnimEventCallback('cast_throw',              'OnAnimEvent_Sign');
  199.         AddAnimEventCallback('cast_end',                'OnAnimEvent_Sign');
  200.         AddAnimEventCallback('cast_friendly_begin',     'OnAnimEvent_Sign');
  201.         AddAnimEventCallback('cast_friendly_throw',     'OnAnimEvent_Sign');
  202.         AddAnimEventCallback('axii_ready',              'OnAnimEvent_Sign');
  203.         AddAnimEventCallback('axii_alternate_ready',    'OnAnimEvent_Sign');
  204.         AddAnimEventCallback('yrden_draw_ready',        'OnAnimEvent_Sign');
  205.        
  206.         AddAnimEventCallback( 'ProjectileThrow',    'OnAnimEvent_Throwable' );
  207.         AddAnimEventCallback( 'OnWeaponReload',     'OnAnimEvent_Throwable' );
  208.         AddAnimEventCallback( 'ProjectileAttach',   'OnAnimEvent_Throwable' );
  209.         AddAnimEventCallback( 'Mutation11AnimEnd',  'OnAnimEvent_Mutation11AnimEnd' );
  210.         AddAnimEventCallback( 'Mutation11ShockWave', 'OnAnimEvent_Mutation11ShockWave' );
  211.        
  212.         spawnMyLovelyStashes(); // Additional Stash Locations
  213.        
  214.         amountOfSetPiecesEquipped.Resize( EnumGetMax( 'EItemSetType' ) + 1 );
  215.        
  216.         runewordInfusionType = ST_None;
  217.                
  218.        
  219.         inv = GetInventory();          
  220.  
  221.        
  222.         signOwner = new W3SignOwnerPlayer in this;
  223.         signOwner.Init( this );
  224.        
  225.         itemSlots.Resize( EnumGetMax('EEquipmentSlots')+1 );
  226.  
  227.         //modSigns
  228.         if( FactsQuerySum("ModSignsRecipesAdded") < 1 )
  229.         {
  230.             AddAlchemyRecipe('Recipe for Tawny Owl 1', true, true); // fix missing Tawny Owl recipe
  231.             AddCraftingSchematic('Meteorite plate schematic', true, true); //add missing meteorite plate schematic
  232.             FactsAdd("ModSignsRecipesAdded");
  233.         }
  234.        
  235.         //modSigns
  236.         if( FactsQuerySum("ModSignsKMSetSchematicsAdded") < 1 )
  237.         {
  238.             AddCraftingSchematic('Kaer Morhen Armor 1 schematic',true, true);
  239.             AddCraftingSchematic('Kaer Morhen Armor 2 schematic',true, true);
  240.             AddCraftingSchematic('Kaer Morhen Armor 3 schematic',true, true);
  241.             AddCraftingSchematic('Kaer Morhen Pants schematic',true, true);
  242.             AddCraftingSchematic('Kaer Morhen Pants 1 schematic',true, true);
  243.             AddCraftingSchematic('Kaer Morhen Pants 2 schematic',true, true);
  244.             AddCraftingSchematic('Kaer Morhen Pants 3 schematic',true, true);
  245.             AddCraftingSchematic('Kaer Morhen Boots schematic',true, true);
  246.             AddCraftingSchematic('Kaer Morhen Boots 1 schematic',true, true);
  247.             AddCraftingSchematic('Kaer Morhen Boots 2 schematic',true, true);
  248.             AddCraftingSchematic('Kaer Morhen Boots 3 schematic',true, true);
  249.             AddCraftingSchematic('Kaer Morhen Gloves schematic',true, true);
  250.             AddCraftingSchematic('Kaer Morhen Gloves 1 schematic',true, true);
  251.             AddCraftingSchematic('Kaer Morhen Gloves 2 schematic',true, true);
  252.             AddCraftingSchematic('Kaer Morhen Gloves 3 schematic',true, true);
  253.             FactsAdd("ModSignsKMSetSchematicsAdded");
  254.         }
  255.        
  256.         if(!spawnData.restored)
  257.         {
  258.             levelManager = new W3LevelManager in this;         
  259.             levelManager.Initialize();
  260.            
  261.            
  262.             inv.GetAllItems(items);
  263.             for(i=0; i<items.Size(); i+=1)
  264.             {
  265.                 if(inv.IsItemMounted(items[i]) && ( !inv.IsItemBody(items[i]) || inv.GetItemCategory(items[i]) == 'hair' ) )
  266.                     EquipItem(items[i]);
  267.             }
  268.            
  269.            
  270.            
  271.            
  272.            
  273.             AddAlchemyRecipe('Recipe for Swallow 1',true,true);
  274.             AddAlchemyRecipe('Recipe for Cat 1',true,true);
  275.             AddAlchemyRecipe('Recipe for White Honey 1',true,true);
  276.            
  277.             AddAlchemyRecipe('Recipe for Samum 1',true,true);
  278.             AddAlchemyRecipe('Recipe for Grapeshot 1',true,true);
  279.            
  280.             AddAlchemyRecipe('Recipe for Specter Oil 1',true,true);
  281.             AddAlchemyRecipe('Recipe for Necrophage Oil 1',true,true);
  282.             AddAlchemyRecipe('Recipe for Alcohest 1',true,true);
  283.         }
  284.         else
  285.         {
  286.             AddTimer('DelayedOnItemMount', 0.1, true);
  287.            
  288.            
  289.             CheckHairItem();
  290.         }
  291.        
  292.        
  293.         AddStartingSchematics();
  294.  
  295.         super.OnSpawned( spawnData );
  296.        
  297.        
  298.         AddAlchemyRecipe('Recipe for Mutagen red',true,true);
  299.         AddAlchemyRecipe('Recipe for Mutagen green',true,true);
  300.         AddAlchemyRecipe('Recipe for Mutagen blue',true,true);
  301.         AddAlchemyRecipe('Recipe for Greater mutagen red',true,true);
  302.         AddAlchemyRecipe('Recipe for Greater mutagen green',true,true);
  303.         AddAlchemyRecipe('Recipe for Greater mutagen blue',true,true);
  304.        
  305.         AddCraftingSchematic('Starting Armor Upgrade schematic 1',true,true);
  306.        
  307.        
  308.         if( inputHandler )
  309.         {
  310.             inputHandler.BlockAllActions( 'being_ciri', false );
  311.         }
  312.         SetBehaviorVariable( 'test_ciri_replacer', 0.0f);
  313.        
  314.         if(!spawnData.restored)
  315.         {
  316.            
  317.             abilityManager.GainStat(BCS_Toxicity, 0);      
  318.         }      
  319.        
  320.         levelManager.PostInit(this, spawnData.restored, true);
  321.        
  322.         SetBIsCombatActionAllowed( true );     
  323.         SetBIsInputAllowed( true, 'OnSpawned' );               
  324.        
  325.        
  326.         if ( !reputationManager )
  327.         {
  328.             reputationManager = new W3Reputation in this;
  329.             reputationManager.Initialize();
  330.         }
  331.        
  332.         theSound.SoundParameter( "focus_aim", 1.0f, 1.0f );
  333.         theSound.SoundParameter( "focus_distance", 0.0f, 1.0f );
  334.        
  335.        
  336.        
  337.        
  338.            
  339.        
  340.         currentlyCastSign = ST_None;
  341.        
  342.        
  343.         if(!spawnData.restored)
  344.         {
  345.             horseTemplate = (CEntityTemplate)LoadResource("horse_manager");
  346.             horseManager = (W3HorseManager)theGame.CreateEntity(horseTemplate, GetWorldPosition(),,,,,PM_Persist);
  347.             horseManager.CreateAttachment(this);
  348.             horseManager.OnCreated();
  349.             EntityHandleSet( horseManagerHandle, horseManager );
  350.         }
  351.         else
  352.         {
  353.             AddTimer('DelayedHorseUpdate', 0.01, true);
  354.         }
  355.        
  356.         //---=== modFriendlyMeditation ===---
  357.         fMeditationConfig = new CModFMeditationConfig in this;
  358.         fMeditationConfig.Init();
  359.         //---=== modFriendlyMeditation ===---
  360.        
  361.        
  362.         RemoveAbility('Ciri_CombatRegen');
  363.         RemoveAbility('Ciri_Rage');
  364.         RemoveAbility('CiriBlink');
  365.         RemoveAbility('CiriCharge');
  366.         RemoveAbility('Ciri_Q205');
  367.         RemoveAbility('Ciri_Q305');
  368.         RemoveAbility('Ciri_Q403');
  369.         RemoveAbility('Ciri_Q111');
  370.         RemoveAbility('Ciri_Q501');
  371.         RemoveAbility('SkillCiri');
  372.        
  373.         //modSigns: remove passive bonuses
  374.         RemoveAbilityAll('sword_adrenalinegain');
  375.         RemoveAbilityAll('magic_staminaregen');
  376.         RemoveAbilityAll('alchemy_potionduration');
  377.        
  378.         /*if(spawnData.restored)
  379.         {
  380.             RestoreQuen(savedQuenHealth, savedQuenDuration);           
  381.         }
  382.         else
  383.         {
  384.             savedQuenHealth = 0.f;
  385.             savedQuenDuration = 0.f;
  386.         }*/ //modSigns: removed, params aren't saved properly anyway
  387.         savedQuenHealth = 0.f;
  388.         savedQuenDuration = 0.f;
  389.        
  390.         if(spawnData.restored)
  391.         {
  392.             ApplyPatchFixes();
  393.         }
  394.         else
  395.         {
  396.            
  397.             FactsAdd( "new_game_started_in_1_20" );
  398.         }
  399.        
  400.         if ( spawnData.restored )
  401.         {
  402.             FixEquippedMutagens();
  403.         }
  404.        
  405.         //modFriendlyStash begin
  406.         fStashConfig = new CModFriendlyStashConfig in this;
  407.         fStashConfig.Init();
  408.         //modFriendlyStash end
  409.        
  410.         if ( FactsQuerySum("NewGamePlus") > 0 )
  411.         {
  412.             NewGamePlusAdjustDLC1TemerianSet(inv);
  413.             NewGamePlusAdjustDLC5NilfgardianSet(inv);
  414.             NewGamePlusAdjustDLC10WolfSet(inv);
  415.             NewGamePlusAdjustDLC14SkelligeSet(inv);
  416.             if(horseManager)
  417.             {
  418.                 NewGamePlusAdjustDLC1TemerianSet(horseManager.GetInventoryComponent());
  419.                 NewGamePlusAdjustDLC5NilfgardianSet(horseManager.GetInventoryComponent());
  420.                 NewGamePlusAdjustDLC10WolfSet(horseManager.GetInventoryComponent());
  421.                 NewGamePlusAdjustDLC14SkelligeSet(horseManager.GetInventoryComponent());
  422.             }
  423.         }
  424.        
  425.        
  426.         ResumeStaminaRegen('WhirlSkill');
  427.         ResumeStaminaRegen('RendSkill'); //modSigns
  428.        
  429.         if(HasRunewordActive('Runeword 4 _Stats')) //modSigns
  430.             StartVitalityRegen();
  431.        
  432.        
  433.         if(HasAbility('sword_s19'))
  434.         {
  435.             RemoveTemporarySkills();
  436.         }
  437.        
  438.         //HACK_UnequipWolfLiver(); //modSigns
  439.        
  440.         if( enemiesKilledByType.Size() == 0 )
  441.         {
  442.             enemiesKilledByType.Resize(EENT_MAX_TYPES);
  443.         }
  444.  
  445.         //---=== modPreparations ===---
  446.         prepConfig = new CModPreparationsConfig in this;
  447.         //prepConfig.Init(this);
  448.         //ApplyModPrepFixes();
  449.         AddTimer('ModPrepDelayedInit', 0.00001, true, , , true);
  450.         //---=== modPreparations ===---
  451.        
  452.        
  453.         if( HasBuff( EET_GryphonSetBonusYrden ) )
  454.         {
  455.             RemoveBuff( EET_GryphonSetBonusYrden, false, "GryphonSetBonusYrden" );
  456.         }
  457.        
  458.         if( HasBuff( EET_GryphonSetBonus ) ) //modSigns: remove on spawn
  459.         {
  460.             RemoveBuff( EET_GryphonSetBonus );
  461.         }
  462.        
  463.         if( HasBuff(EET_KaerMorhenSetBonus) ) //modSigns: remove on spawn
  464.         {
  465.             RemoveBuff(EET_KaerMorhenSetBonus);
  466.         }
  467.        
  468.         //modSigns
  469.         if( FactsQuerySum("standalone_ep1") > 0 && FactsQuerySum("standalone_ep1_inv") < 1 )
  470.         {
  471.             AddTimer('GiveStandAloneEP1Items', 0.00001, true, , , true);
  472.         }
  473.         //modSigns
  474.         if( FactsQuerySum("standalone_ep2") > 0 && FactsQuerySum("standalone_ep2_inv") < 1 )
  475.         {
  476.             AddTimer('GiveStandAloneEP2Items', 0.00001, true, , , true);
  477.         }
  478.        
  479.         if( spawnData.restored )
  480.         {
  481.            
  482.             UpdateEncumbrance();
  483.            
  484.            
  485.             RemoveBuff( EET_Mutation11Immortal );
  486.             RemoveBuff( EET_Mutation11Buff );
  487.            
  488.             //modSigns:
  489.             RemoveBuff( EET_UndyingSkillImmortal );
  490.         }
  491.        
  492.        
  493.         theGame.GameplayFactsAdd( "PlayerIsGeralt" );
  494.        
  495.         isInitialized = true;
  496.        
  497.         // mod Fast Travel Pack
  498.             ftPack = new FastTravelPack in this;
  499.             ftPack.Init();
  500.         // mod Fast Travel Pack
  501.     }
  502.     // mod Fast Travel Pack
  503.     public function GetFTPack() : FastTravelPack
  504.     {
  505.         return ftPack;
  506.     }
  507.     // mod Fast Travel Pack
  508.  
  509.     //---=== modPreparations ===---
  510.     timer function ModPrepDelayedInit(dt : float, timerId : int)
  511.     {
  512.         if( !GetWitcherPlayer() ) //why on Earth is this even a thing?!?!?!
  513.             return;
  514.        
  515.         prepConfig.Init(this);
  516.         ApplyModPrepFixes();
  517.         RemoveTimer('ModPrepDelayedInit');
  518.    
  519.     private function ApplyModPrepFixes()
  520.     {
  521.         if( FactsQuerySum("MissingTawnyOwlRecipeAdded") < 1 )
  522.         {
  523.             AddAlchemyRecipe('Recipe for Tawny Owl 1', true, true); // fix missing Tawny Owl recipe
  524.             FactsAdd("MissingTawnyOwlRecipeAdded");
  525.         }
  526.     }
  527.  
  528.     public function SetupFHUD() //FHUD compatibility
  529.     {
  530.         prepDisallowOilsInCombat = prepConfig.disallowOilsInCombat;
  531.         prepOilsHaveAmmo = prepConfig.OilsHaveAmmo();
  532.     }
  533.         //modToggleCatNoPotion++
  534.         catToggler = new CatToggler in this;
  535.         catToggler.Init(this);
  536.         AddTimer('updateCat', .33, true);
  537.         //modToggleCatNoPotion--
  538.  
  539.     public function SetupFMed() //FMeditation compatibility
  540.     {
  541.         fmedCanSpawnCampfire = false;
  542.         fmedAutorefillAlchemy = prepConfig.BombsAutorefillEnabled() ||
  543.                                 prepConfig.OilsAutorefillEnabled() ||
  544.                                 prepConfig.MutagensAutorefillEnabled() ||
  545.                                 prepConfig.PotionsAutorefillEnabled();
  546.     }
  547.     //---=== modPreparations ===---
  548.  
  549.     //modToggleCatNoPotion++
  550.     timer function updateCat( deltaTime : float, id : int )
  551.     {
  552.         catToggler.Update(deltaTime);
  553.     }
  554.     //modToggleCatNoPotion--
  555.  
  556.     private function HACK_UnequipWolfLiver()
  557.     {
  558.         var itemName1, itemName2, itemName3, itemName4 : name;
  559.         var item1, item2, item3, item4 : SItemUniqueId;
  560.        
  561.         GetItemEquippedOnSlot( EES_Potion1, item1 );
  562.         GetItemEquippedOnSlot( EES_Potion2, item2 );
  563.         GetItemEquippedOnSlot( EES_Potion3, item3 );
  564.         GetItemEquippedOnSlot( EES_Potion4, item4 );
  565.  
  566.         if ( inv.IsIdValid( item1 ) )
  567.             itemName1 = inv.GetItemName( item1 );
  568.         if ( inv.IsIdValid( item2 ) )
  569.             itemName2 = inv.GetItemName( item2 );
  570.         if ( inv.IsIdValid( item3 ) )
  571.             itemName3 = inv.GetItemName( item3 );
  572.         if ( inv.IsIdValid( item4 ) )
  573.             itemName4 = inv.GetItemName( item4 );
  574.  
  575.         if ( itemName1 == 'Wolf liver' || itemName3 == 'Wolf liver' )
  576.         {
  577.             if ( inv.IsIdValid( item1 ) )
  578.                 UnequipItem( item1 );
  579.             if ( inv.IsIdValid( item3 ) )
  580.                 UnequipItem( item3 );
  581.         }
  582.         else if ( itemName2 == 'Wolf liver' || itemName4 == 'Wolf liver' )
  583.         {
  584.             if ( inv.IsIdValid( item2 ) )
  585.                 UnequipItem( item2 );
  586.             if ( inv.IsIdValid( item4 ) )
  587.                 UnequipItem( item4 );
  588.         }
  589.     }
  590.    
  591.     public function IncKills( et : EEnemyType ) //modSigns
  592.     {
  593.         enemiesKilledByType[et] += 1;
  594.         //theGame.witcherLog.AddMessage(et + ": " + enemiesKilledByType[et]);
  595.     }
  596.    
  597.     public function GetKills( et : EEnemyType ) : int //modSigns
  598.     {
  599.         return enemiesKilledByType[et];
  600.     }
  601.    
  602.     public function GetExpModifierByEnemyType( et : EEnemyType ) : float //modSigns
  603.     {
  604.         switch(et)
  605.         {
  606.             case EENT_BOSS:
  607.                 return 1;
  608.             case EENT_GENERIC:
  609.             case EENT_ANIMAL:
  610.                 return 0;
  611.             default:
  612.                 return 1 - MinF(100.0f, (float)GetKills(et))/100.0f;
  613.         }
  614.     }
  615.    
  616.    
  617.    
  618.    
  619.  
  620.     timer function DelayedHorseUpdate( dt : float, id : int )
  621.     {
  622.         var man : W3HorseManager;
  623.        
  624.         man = GetHorseManager();
  625.         if(man)
  626.         {
  627.             if ( man.ApplyHorseUpdateOnSpawn() )
  628.             {
  629.                
  630.                 UpdateEncumbrance();
  631.                
  632.                 RemoveTimer( 'DelayedHorseUpdate' );
  633.             }
  634.         }
  635.     }  
  636.    
  637.     event OnAbilityAdded( abilityName : name)
  638.     {
  639.         super.OnAbilityAdded(abilityName);
  640.        
  641.         if( HasRunewordActive('Runeword 4 _Stats') ) //modSigns
  642.         {
  643.             StartVitalityRegen();
  644.         }
  645.            
  646.         if ( abilityName == 'Runeword 8 _Stats' && GetStat(BCS_Focus, true) >= GetStatMax(BCS_Focus) && !HasBuff(EET_Runeword8) ) //modSigns
  647.         {
  648.             AddEffectDefault(EET_Runeword8, this, "equipped item");
  649.         }
  650.  
  651.     }
  652.    
  653.     private final function AddStartingSchematics()
  654.     {
  655.         AddCraftingSchematic('Starting Armor Upgrade schematic 1',  true,true);
  656.         AddCraftingSchematic('Thread schematic',                    true, true);
  657.         AddCraftingSchematic('String schematic',                    true, true);
  658.         AddCraftingSchematic('Linen schematic',                     true, true);
  659.         AddCraftingSchematic('Silk schematic',                      true, true);
  660.         AddCraftingSchematic('Resin schematic',                     true, true);
  661.         AddCraftingSchematic('Blasting powder schematic',           true, true);
  662.         AddCraftingSchematic('Haft schematic',                      true, true);
  663.         AddCraftingSchematic('Hardened timber schematic',           true, true);
  664.         AddCraftingSchematic('Leather squares schematic',           true, true);
  665.         AddCraftingSchematic('Leather schematic',                   true, true);
  666.         AddCraftingSchematic('Hardened leather schematic',          true, true);
  667.         AddCraftingSchematic('Draconide leather schematic',         true, true);
  668.         AddCraftingSchematic('Iron ingot schematic',                true, true);
  669.         AddCraftingSchematic('Steel ingot schematic',               true, true);
  670.         AddCraftingSchematic('Steel ingot schematic 1',             true, true);
  671.         AddCraftingSchematic('Steel plate schematic',               true, true);
  672.         AddCraftingSchematic('Dark iron ingot schematic',           true, true);
  673.         AddCraftingSchematic('Dark iron plate schematic',           true, true);
  674.         AddCraftingSchematic('Dark steel ingot schematic',          true, true);
  675.         AddCraftingSchematic('Dark steel ingot schematic 1',        true, true);
  676.         AddCraftingSchematic('Dark steel plate schematic',          true, true);
  677.         AddCraftingSchematic('Silver ore schematic',                true, true);
  678.         AddCraftingSchematic('Silver ingot schematic',              true, true);
  679.         AddCraftingSchematic('Silver ingot schematic 1',            true, true);
  680.         AddCraftingSchematic('Silver plate schematic',              true, true);
  681.         AddCraftingSchematic('Meteorite ingot schematic',           true, true);
  682.         AddCraftingSchematic('Meteorite silver ingot schematic',    true, true);
  683.         AddCraftingSchematic('Meteorite silver plate schematic',    true, true);
  684.         AddCraftingSchematic('Glowing ingot schematic',             true, true);
  685.         AddCraftingSchematic('Dwimeryte ore schematic',             true, true);
  686.         AddCraftingSchematic('Dwimeryte ingot schematic',           true, true);
  687.         AddCraftingSchematic('Dwimeryte ingot schematic 1',         true, true);
  688.         AddCraftingSchematic('Dwimeryte plate schematic',           true, true);
  689.         AddCraftingSchematic('Infused dust schematic',              true, true);
  690.         AddCraftingSchematic('Infused shard schematic',             true, true);
  691.         AddCraftingSchematic('Infused crystal schematic',           true, true);
  692.  
  693.         if ( theGame.GetDLCManager().IsEP2Available() )
  694.         {
  695.             AddCraftingSchematic('Draconide infused leather schematic', true, true);
  696.             AddCraftingSchematic('Nickel ore schematic',                true, true);
  697.             AddCraftingSchematic('Cupronickel ore schematic',           true, true);
  698.             AddCraftingSchematic('Copper ore schematic',                true, true);
  699.             AddCraftingSchematic('Copper ingot schematic',              true, true);
  700.             AddCraftingSchematic('Copper plate schematic',              true, true);
  701.             AddCraftingSchematic('Green gold ore schematic',            true, true);
  702.             AddCraftingSchematic('Green gold ore schematic 1',          true, true);
  703.             AddCraftingSchematic('Green gold ingot schematic',          true, true);
  704.             AddCraftingSchematic('Green gold plate schematic',          true, true);
  705.             AddCraftingSchematic('Orichalcum ore schematic',            true, true);
  706.             AddCraftingSchematic('Orichalcum ore schematic 1',          true, true);
  707.             AddCraftingSchematic('Orichalcum ingot schematic',          true, true);
  708.             AddCraftingSchematic('Orichalcum plate schematic',          true, true);
  709.             AddCraftingSchematic('Dwimeryte enriched ore schematic',    true, true);
  710.             AddCraftingSchematic('Dwimeryte enriched ingot schematic',  true, true);
  711.             AddCraftingSchematic('Dwimeryte enriched plate schematic',  true, true);
  712.         }
  713.     }
  714.    
  715.     private final function ApplyPatchFixes()
  716.     {
  717.         var cnt, transmutationCount, mutagenCount, i, slot : int;
  718.         var transmutationAbility, itemName : name;
  719.         var pam : W3PlayerAbilityManager;
  720.         var slotId : int;
  721.         var offset : float;
  722.         var buffs : array<CBaseGameplayEffect>;
  723.         var mutagen : W3Mutagen_Effect;
  724.         var skill : SSimpleSkill;
  725.         var spentSkillPoints, swordSkillPointsSpent, alchemySkillPointsSpent, perkSkillPointsSpent, pointsToAdd : int;
  726.         var mutagens : array< W3Mutagen_Effect >;
  727.        
  728.         /*if(FactsQuerySum("ClearingPotionPassiveBonusFix") < 1)
  729.         {
  730.             pam = (W3PlayerAbilityManager)abilityManager;
  731.  
  732.             cnt = GetAbilityCount('sword_adrenalinegain') - pam.GetPathPointsSpent(ESP_Sword);
  733.             if(cnt > 0)
  734.                 RemoveAbilityMultiple('sword_adrenalinegain', cnt);
  735.                
  736.             cnt = GetAbilityCount('magic_staminaregen') - pam.GetPathPointsSpent(ESP_Signs);
  737.             if(cnt > 0)
  738.                 RemoveAbilityMultiple('magic_staminaregen', cnt);
  739.                
  740.             cnt = GetAbilityCount('alchemy_potionduration') - pam.GetPathPointsSpent(ESP_Alchemy);
  741.             if(cnt > 0)
  742.                 RemoveAbilityMultiple('alchemy_potionduration', cnt);
  743.        
  744.             FactsAdd("ClearingPotionPassiveBonusFix");
  745.         }*/ //modSigns
  746.                
  747.        
  748.         if(FactsQuerySum("DimeritiumSynergyFix") < 1)
  749.         {
  750.             slotId = GetSkillSlotID(S_Alchemy_s19);
  751.             if(slotId != -1)
  752.                 UnequipSkill(S_Alchemy_s19);
  753.                
  754.             RemoveAbilityAll('greater_mutagen_color_green_synergy_bonus');
  755.             RemoveAbilityAll('mutagen_color_green_synergy_bonus');
  756.             RemoveAbilityAll('mutagen_color_lesser_green_synergy_bonus');
  757.            
  758.             RemoveAbilityAll('greater_mutagen_color_blue_synergy_bonus');
  759.             RemoveAbilityAll('mutagen_color_blue_synergy_bonus');
  760.             RemoveAbilityAll('mutagen_color_lesser_blue_synergy_bonus');
  761.            
  762.             RemoveAbilityAll('greater_mutagen_color_red_synergy_bonus');
  763.             RemoveAbilityAll('mutagen_color_red_synergy_bonus');
  764.             RemoveAbilityAll('mutagen_color_lesser_red_synergy_bonus');
  765.            
  766.             if(slotId != -1)
  767.                 EquipSkill(S_Alchemy_s19, slotId);
  768.        
  769.             FactsAdd("DimeritiumSynergyFix");
  770.         }
  771.        
  772.        
  773.         if(FactsQuerySum("DontShowRecipePinTut") < 1)
  774.         {
  775.             FactsAdd( "DontShowRecipePinTut" );
  776.             TutorialScript('alchemyRecipePin', '');
  777.             TutorialScript('craftingRecipePin', '');
  778.         }
  779.        
  780.        
  781.         if(FactsQuerySum("LevelReqPotGiven") < 1)
  782.         {
  783.             FactsAdd("LevelReqPotGiven");
  784.             inv.AddAnItem('Wolf Hour', 1, false, false, true);
  785.         }
  786.        
  787.        
  788.         if(!HasBuff(EET_AutoStaminaRegen))
  789.         {
  790.             AddEffectDefault(EET_AutoStaminaRegen, this, 'autobuff', false);
  791.         }
  792.        
  793.        
  794.        
  795.         buffs = GetBuffs();
  796.         offset = 0;
  797.         mutagenCount = 0;
  798.         for(i=0; i<buffs.Size(); i+=1)
  799.         {
  800.             mutagen = (W3Mutagen_Effect)buffs[i];
  801.             if(mutagen)
  802.             {
  803.                 offset += mutagen.GetToxicityOffset();
  804.                 mutagenCount += 1;
  805.             }
  806.         }
  807.        
  808.        
  809.         if(offset != (GetStat(BCS_Toxicity) - GetStat(BCS_Toxicity, true)))
  810.             SetToxicityOffset(offset);
  811.            
  812.        
  813.         mutagenCount *= GetSkillLevel(S_Alchemy_s13);
  814.         transmutationAbility = GetSkillAbilityName(S_Alchemy_s13);
  815.         transmutationCount = GetAbilityCount(transmutationAbility);
  816.         if(mutagenCount < transmutationCount)
  817.         {
  818.             RemoveAbilityMultiple(transmutationAbility, transmutationCount - mutagenCount);
  819.         }
  820.         else if(mutagenCount > transmutationCount)
  821.         {
  822.             AddAbilityMultiple(transmutationAbility, mutagenCount - transmutationCount);
  823.         }
  824.        
  825.        
  826.         if(theGame.GetDLCManager().IsEP1Available())
  827.         {
  828.             theGame.GetJournalManager().ActivateEntryByScriptTag('TutorialJournalEnchanting', JS_Active);
  829.         }
  830.  
  831.        
  832.         if(HasAbility('sword_s19') && FactsQuerySum("Patch_Sword_s19") < 1)
  833.         {
  834.             pam = (W3PlayerAbilityManager)abilityManager;
  835.  
  836.            
  837.             skill.level = 0;
  838.             for(i = S_Magic_s01; i <= S_Magic_s20; i+=1)
  839.             {
  840.                 skill.skillType = i;               
  841.                 pam.RemoveTemporarySkill(skill);
  842.             }
  843.            
  844.            
  845.             spentSkillPoints = levelManager.GetPointsUsed(ESkillPoint);
  846.             swordSkillPointsSpent = pam.GetPathPointsSpent(ESP_Sword);
  847.             alchemySkillPointsSpent = pam.GetPathPointsSpent(ESP_Alchemy);
  848.             perkSkillPointsSpent = pam.GetPathPointsSpent(ESP_Perks);
  849.            
  850.             pointsToAdd = spentSkillPoints - swordSkillPointsSpent - alchemySkillPointsSpent - perkSkillPointsSpent;
  851.             if(pointsToAdd > 0)
  852.                 levelManager.UnspendPoints(ESkillPoint, pointsToAdd);
  853.            
  854.            
  855.             RemoveAbilityAll('sword_s19');
  856.            
  857.            
  858.             FactsAdd("Patch_Sword_s19");
  859.         }
  860.        
  861.        
  862.         if( HasAbility( 'sword_s19' ) )
  863.         {
  864.             RemoveAbilityAll( 'sword_s19' );
  865.         }
  866.        
  867.        
  868.         if(FactsQuerySum("Patch_Armor_Type_Glyphwords") < 1)
  869.         {
  870.             pam = (W3PlayerAbilityManager)abilityManager;
  871.            
  872.             pam.SetPerkArmorBonus( S_Perk_05, this );
  873.             pam.SetPerkArmorBonus( S_Perk_06, this );
  874.             pam.SetPerkArmorBonus( S_Perk_07, this );
  875.            
  876.             FactsAdd("Patch_Armor_Type_Glyphwords");
  877.         }
  878.         else if( FactsQuerySum("154999") < 1 )
  879.         {
  880.            
  881.             pam = (W3PlayerAbilityManager)abilityManager;
  882.            
  883.             pam.SetPerkArmorBonus( S_Perk_05, this );
  884.             pam.SetPerkArmorBonus( S_Perk_06, this );
  885.             pam.SetPerkArmorBonus( S_Perk_07, this );
  886.            
  887.             FactsAdd("154999");
  888.         }
  889.        
  890.         if( FactsQuerySum( "Patch_Decoction_Buff_Icons" ) < 1 )
  891.         {
  892.             mutagens = GetMutagenBuffs();
  893.             for( i=0; i<mutagens.Size(); i+=1 )
  894.             {
  895.                 itemName = DecoctionEffectTypeToItemName( mutagens[i].GetEffectType() );               
  896.                 mutagens[i].OverrideIcon( itemName );
  897.             }
  898.            
  899.             FactsAdd( "Patch_Decoction_Buff_Icons" );
  900.         }
  901.        
  902.        
  903.         if( FactsQuerySum( "154997" ) < 1 )
  904.         {
  905.             if( IsSkillEquipped( S_Alchemy_s18 ) )
  906.             {
  907.                 slot = GetSkillSlotID( S_Alchemy_s18 );
  908.                 UnequipSkill( slot );
  909.                 EquipSkill( S_Alchemy_s18, slot );
  910.             }
  911.             FactsAdd( "154997" );
  912.         }
  913.         if( FactsQuerySum( "Patch_Mutagen_Ing_Stacking" ) < 1 )
  914.         {
  915.             Patch_MutagenStacking();       
  916.             FactsAdd( "Patch_Mutagen_Ing_Stacking" );
  917.         }
  918.        
  919.         //modSigns
  920.         if( FactsQuerySum( "modSigns_S_Alchemy_s05_Fix_2" ) < 1 )
  921.         {
  922.             pam = (W3PlayerAbilityManager)abilityManager;
  923.             pam.ResetAlchemy05SkillMaxLevel();
  924.             FactsAdd( "modSigns_S_Alchemy_s05_Fix_2" );
  925.         }
  926.         if( FactsQuerySum( "modSigns_S_Alchemy_s18_Fix" ) < 1 )
  927.         {
  928.             if( IsSkillEquipped( S_Alchemy_s18 ) )
  929.             {
  930.                 slot = GetSkillSlotID( S_Alchemy_s18 );
  931.                 UnequipSkill( slot );
  932.                 EquipSkill( S_Alchemy_s18, slot );
  933.             }
  934.             FactsAdd( "modSigns_S_Alchemy_s18_Fix" );
  935.         }
  936.         if( FactsQuerySum( "modSigns_ArmorTypeSetsIntroduced" ) < 1 )
  937.         {
  938.             pam = (W3PlayerAbilityManager)abilityManager;
  939.             pam.ManageSetArmorTypeBonus();
  940.             RecalcSetItemsEquipped();
  941.             FactsAdd( "modSigns_ArmorTypeSetsIntroduced" );
  942.         }
  943.     }
  944.    
  945.     private final function Patch_MutagenStacking()
  946.     {
  947.         var i, j, quantity : int;
  948.         var muts : array< SItemUniqueId >;
  949.         var item : SItemUniqueId;
  950.         var mutName : name;
  951.         var wasInArray : bool;
  952.         var mutsToAdd : array< SItemParts >;
  953.         var mutToAdd : SItemParts;
  954.        
  955.         muts = inv.GetItemsByTag( 'MutagenIngredient' );
  956.         if( GetItemEquippedOnSlot( EES_SkillMutagen1, item ) )
  957.         {
  958.             muts.Remove( item );
  959.             inv.SetItemStackable( item, false );
  960.         }
  961.         if( GetItemEquippedOnSlot( EES_SkillMutagen2, item ) )
  962.         {
  963.             muts.Remove( item );
  964.             inv.SetItemStackable( item, false );
  965.         }
  966.         if( GetItemEquippedOnSlot( EES_SkillMutagen3, item ) )
  967.         {
  968.             muts.Remove( item );
  969.             inv.SetItemStackable( item, false );
  970.         }
  971.         if( GetItemEquippedOnSlot( EES_SkillMutagen4, item ) )
  972.         {
  973.             muts.Remove( item );
  974.             inv.SetItemStackable( item, false );
  975.         }
  976.        
  977.         for( i=0; i<muts.Size(); i+=1 )
  978.         {
  979.             mutName = inv.GetItemName( muts[i] );
  980.             quantity = inv.GetItemQuantity( muts[i] );
  981.            
  982.             wasInArray = false;
  983.             for( j=0; j<mutsToAdd.Size(); j+=1 )
  984.             {
  985.                 if( mutsToAdd[j].itemName == mutName )
  986.                 {
  987.                     mutsToAdd[j].quantity += quantity;
  988.                     wasInArray = true;
  989.                     break;
  990.                 }
  991.             }
  992.            
  993.             if( !wasInArray )
  994.             {
  995.                 mutToAdd.itemName = mutName;
  996.                 mutToAdd.quantity = quantity;
  997.                 mutsToAdd.PushBack( mutToAdd );
  998.             }
  999.            
  1000.             inv.RemoveItem( muts[i], quantity );
  1001.         }
  1002.        
  1003.         for( i=0; i<mutsToAdd.Size(); i+=1 )
  1004.         {
  1005.             inv.AddAnItem( mutsToAdd[i].itemName, mutsToAdd[i].quantity, true, true );
  1006.         }
  1007.     }
  1008.    
  1009.     private function FixEquippedMutagens()
  1010.     {
  1011.         var item : SItemUniqueId;
  1012.         if( GetItemEquippedOnSlot( EES_SkillMutagen1, item ) )
  1013.         {
  1014.             inv.SetItemStackable( item, false );
  1015.         }
  1016.         if( GetItemEquippedOnSlot( EES_SkillMutagen2, item ) )
  1017.         {
  1018.             inv.SetItemStackable( item, false );
  1019.         }
  1020.         if( GetItemEquippedOnSlot( EES_SkillMutagen3, item ) )
  1021.         {
  1022.             inv.SetItemStackable( item, false );
  1023.         }
  1024.         if( GetItemEquippedOnSlot( EES_SkillMutagen4, item ) )
  1025.         {
  1026.             inv.SetItemStackable( item, false );
  1027.         }
  1028.     }
  1029.  
  1030.     public final function RestoreQuen( quenHealth : float, quenDuration : float, optional alternate : bool ) : bool
  1031.     {
  1032.         var restoredQuen    : W3QuenEntity;
  1033.        
  1034.         if(quenHealth > 0.f && quenDuration >= 3.f)
  1035.         {
  1036.             restoredQuen = (W3QuenEntity)theGame.CreateEntity( signs[ST_Quen].template, GetWorldPosition(), GetWorldRotation() );
  1037.             restoredQuen.Init( signOwner, signs[ST_Quen].entity, true );
  1038.            
  1039.             if( alternate )
  1040.             {
  1041.                 restoredQuen.SetAlternateCast( S_Magic_s04 );
  1042.             }
  1043.            
  1044.             restoredQuen.freeCast = true; //modSigns
  1045.             restoredQuen.OnStarted();
  1046.             restoredQuen.OnThrowing();
  1047.            
  1048.             if( !alternate )
  1049.             {
  1050.                 restoredQuen.OnEnded();
  1051.             }
  1052.            
  1053.             restoredQuen.SetDataFromRestore(quenHealth, quenDuration);
  1054.            
  1055.             return true;
  1056.         }
  1057.        
  1058.         return false;
  1059.     }
  1060.    
  1061.     public function IsInitialized() : bool
  1062.     {
  1063.         return isInitialized;
  1064.     }
  1065.    
  1066.     private function NewGamePlusInitialize()
  1067.     {
  1068.         var questItems : array<name>;
  1069.         var horseManager : W3HorseManager;
  1070.         var horseInventory : CInventoryComponent;
  1071.         var i, missingLevels, expDiff : int;
  1072.        
  1073.         super.NewGamePlusInitialize();
  1074.        
  1075.        
  1076.         horseManager = (W3HorseManager)EntityHandleGet(horseManagerHandle);
  1077.         if(horseManager)
  1078.             horseInventory = horseManager.GetInventoryComponent();
  1079.        
  1080.        
  1081.         theGame.params.SetNewGamePlusLevel(GetLevel());
  1082.        
  1083.        
  1084.         if (theGame.GetDLCManager().IsDLCAvailable('ep1'))
  1085.             missingLevels = theGame.params.NEW_GAME_PLUS_EP1_MIN_LEVEL - GetLevel();
  1086.         else
  1087.             missingLevels = theGame.params.NEW_GAME_PLUS_MIN_LEVEL - GetLevel();
  1088.            
  1089.         for(i=0; i<missingLevels; i+=1)
  1090.         {
  1091.            
  1092.             expDiff = levelManager.GetTotalExpForNextLevel() - levelManager.GetPointsTotal(EExperiencePoint);
  1093.             expDiff = CeilF( ((float)expDiff) / 2 );
  1094.             AddPoints(EExperiencePoint, expDiff, false);
  1095.         }
  1096.        
  1097.        
  1098.        
  1099.        
  1100.        
  1101.         inv.RemoveItemByTag('Quest', -1);
  1102.         horseInventory.RemoveItemByTag('Quest', -1);
  1103.  
  1104.        
  1105.        
  1106.         questItems = theGame.GetDefinitionsManager().GetItemsWithTag('Quest');
  1107.         for(i=0; i<questItems.Size(); i+=1)
  1108.         {
  1109.             inv.RemoveItemByName(questItems[i], -1);
  1110.             horseInventory.RemoveItemByName(questItems[i], -1);
  1111.         }
  1112.        
  1113.        
  1114.         inv.RemoveItemByName('mq1002_artifact_3', -1);
  1115.         horseInventory.RemoveItemByName('mq1002_artifact_3', -1);
  1116.        
  1117.        
  1118.         inv.RemoveItemByTag('NotTransferableToNGP', -1);
  1119.         horseInventory.RemoveItemByTag('NotTransferableToNGP', -1);
  1120.        
  1121.        
  1122.         inv.RemoveItemByTag('NoticeBoardNote', -1);
  1123.         horseInventory.RemoveItemByTag('NoticeBoardNote', -1);
  1124.        
  1125.        
  1126.         RemoveAllNonAutoBuffs();
  1127.        
  1128.        
  1129.         RemoveAlchemyRecipe('Recipe for Trial Potion Kit');
  1130.         RemoveAlchemyRecipe('Recipe for Pops Antidote');
  1131.         RemoveAlchemyRecipe('Recipe for Czart Lure');
  1132.         RemoveAlchemyRecipe('q603_diarrhea_potion_recipe');
  1133.        
  1134.        
  1135.         inv.RemoveItemByTag('Trophy', -1);
  1136.         horseInventory.RemoveItemByTag('Trophy', -1);
  1137.        
  1138.        
  1139.         inv.RemoveItemByCategory('usable', -1);
  1140.         horseInventory.RemoveItemByCategory('usable', -1);
  1141.        
  1142.        
  1143.         RemoveAbility('StaminaTutorialProlog');
  1144.         RemoveAbility('TutorialStaminaRegenHack');
  1145.         RemoveAbility('area_novigrad');
  1146.         RemoveAbility('NoRegenEffect');
  1147.         RemoveAbility('HeavySwimmingStaminaDrain');
  1148.         RemoveAbility('AirBoost');
  1149.         RemoveAbility('area_nml');
  1150.         RemoveAbility('area_skellige');
  1151.        
  1152.        
  1153.         inv.RemoveItemByTag('GwintCard', -1);
  1154.         horseInventory.RemoveItemByTag('GwintCard', -1);
  1155.                
  1156.        
  1157.        
  1158.         inv.RemoveItemByTag('ReadableItem', -1);
  1159.         horseInventory.RemoveItemByTag('ReadableItem', -1);
  1160.        
  1161.        
  1162.         abilityManager.RestoreStats();
  1163.        
  1164.        
  1165.         ((W3PlayerAbilityManager)abilityManager).RemoveToxicityOffset(10000);
  1166.        
  1167.        
  1168.         //---=== modPreparations ===---
  1169.         inv.SingletonItemsRefillAmmoNoAlco(true);
  1170.         //---=== modPreparations ===---
  1171.        
  1172.         craftingSchematics.Clear();
  1173.         AddStartingSchematics();
  1174.        
  1175.        
  1176.         for( i=0; i<amountOfSetPiecesEquipped.Size(); i+=1 )
  1177.         {
  1178.             amountOfSetPiecesEquipped[i] = 0;
  1179.         }
  1180.  
  1181.        
  1182.         inv.AddAnItem('Clearing Potion', 1, true, false, false);
  1183.        
  1184.        
  1185.         inv.RemoveItemByName('q203_broken_eyeofloki', -1);
  1186.         horseInventory.RemoveItemByName('q203_broken_eyeofloki', -1);
  1187.        
  1188.        
  1189.         NewGamePlusReplaceViperSet(inv);
  1190.         NewGamePlusReplaceViperSet(horseInventory);
  1191.         NewGamePlusReplaceKaerMorhenSet(inv); //modSigns
  1192.         NewGamePlusReplaceKaerMorhenSet(horseInventory); //modSigns
  1193.         NewGamePlusReplaceLynxSet(inv);
  1194.         NewGamePlusReplaceLynxSet(horseInventory);
  1195.         NewGamePlusReplaceGryphonSet(inv);
  1196.         NewGamePlusReplaceGryphonSet(horseInventory);
  1197.         NewGamePlusReplaceBearSet(inv);
  1198.         NewGamePlusReplaceBearSet(horseInventory);
  1199.         NewGamePlusReplaceEP1(inv);
  1200.         NewGamePlusReplaceEP1(horseInventory);
  1201.         NewGamePlusReplaceEP2WitcherSets(inv);
  1202.         NewGamePlusReplaceEP2WitcherSets(horseInventory);
  1203.         NewGamePlusReplaceEP2Items(inv);
  1204.         NewGamePlusReplaceEP2Items(horseInventory);
  1205.         NewGamePlusMarkItemsToNotAdjust(inv);
  1206.         NewGamePlusMarkItemsToNotAdjust(horseInventory);
  1207.        
  1208.        
  1209.         inputHandler.ClearLocksForNGP();
  1210.        
  1211.        
  1212.         buffImmunities.Clear();
  1213.         buffRemovedImmunities.Clear();
  1214.        
  1215.         newGamePlusInitialized = true;
  1216.        
  1217.        
  1218.         m_quenReappliedCount = 1;
  1219.     }
  1220.        
  1221.     private final function NewGamePlusMarkItemsToNotAdjust(out inv : CInventoryComponent)
  1222.     {
  1223.         var ids     : array<SItemUniqueId>;
  1224.         var i       : int;
  1225.         var n       : name;
  1226.        
  1227.         inv.GetAllItems(ids);
  1228.         for( i=0; i<ids.Size(); i+=1 )
  1229.         {
  1230.             inv.SetItemModifierInt(ids[i], 'NGPItemAdjusted', 1);
  1231.         }
  1232.     }
  1233.    
  1234.     private final function NewGamePlusReplaceItem( item : name, new_item : name, out inv : CInventoryComponent)
  1235.     {
  1236.         var i, j                    : int;
  1237.         var ids, new_ids, enh_ids   : array<SItemUniqueId>;
  1238.         var dye_ids                 : array<SItemUniqueId>;
  1239.         var enh                     : array<name>;
  1240.         var wasEquipped             : bool;
  1241.         var wasEnchanted            : bool;
  1242.         var wasDyed                 : bool;
  1243.         var enchantName, colorName  : name;
  1244.        
  1245.         if ( inv.HasItem( item ) )
  1246.         {
  1247.             ids = inv.GetItemsIds(item);
  1248.             for (i = 0; i < ids.Size(); i += 1)
  1249.             {
  1250.                 inv.GetItemEnhancementItems( ids[i], enh );
  1251.                 wasEnchanted = inv.IsItemEnchanted( ids[i] );
  1252.                 if ( wasEnchanted )
  1253.                     enchantName = inv.GetEnchantment( ids[i] );
  1254.                 wasEquipped = IsItemEquipped( ids[i] );
  1255.                 wasDyed = inv.IsItemColored( ids[i] );
  1256.                 if ( wasDyed )
  1257.                 {
  1258.                     colorName = inv.GetItemColor( ids[i] );
  1259.                 }
  1260.                
  1261.                 inv.RemoveItem( ids[i], 1 );
  1262.                 new_ids = inv.AddAnItem( new_item, 1, true, true, false );
  1263.                 if ( wasEquipped )
  1264.                 {
  1265.                     EquipItem( new_ids[0] );
  1266.                 }
  1267.                 if ( wasEnchanted )
  1268.                 {
  1269.                     inv.EnchantItem( new_ids[0], enchantName, getEnchamtmentStatName(enchantName) );
  1270.                 }
  1271.                 for (j = 0; j < enh.Size(); j += 1)
  1272.                 {
  1273.                     enh_ids = inv.AddAnItem( enh[j], 1, true, true, false );
  1274.                     inv.EnhanceItemScript( new_ids[0], enh_ids[0] );
  1275.                 }
  1276.                 if ( wasDyed )
  1277.                 {
  1278.                     dye_ids = inv.AddAnItem( colorName, 1, true, true, false );
  1279.                     inv.ColorItem( new_ids[0], dye_ids[0] );
  1280.                     inv.RemoveItem( dye_ids[0], 1 );
  1281.                 }
  1282.                
  1283.                 inv.SetItemModifierInt( new_ids[0], 'NGPItemAdjusted', 1 );
  1284.             }
  1285.         }
  1286.     }
  1287.    
  1288.     private final function NewGamePlusAdjustDLCItem(item : name, mod : name, inv : CInventoryComponent)
  1289.     {
  1290.         var ids     : array<SItemUniqueId>;
  1291.         var i       : int;
  1292.        
  1293.         if( inv.HasItem(item) )
  1294.         {
  1295.             ids = inv.GetItemsIds(item);
  1296.             for (i = 0; i < ids.Size(); i += 1)
  1297.             {
  1298.                 if ( inv.GetItemModifierInt(ids[i], 'DoNotAdjustNGPDLC') <= 0 )
  1299.                 {
  1300.                     inv.AddItemBaseAbility(ids[i], mod);
  1301.                     inv.SetItemModifierInt(ids[i], 'DoNotAdjustNGPDLC', 1);
  1302.                 }
  1303.             }
  1304.         }
  1305.        
  1306.     }
  1307.    
  1308.     private final function NewGamePlusAdjustDLC1TemerianSet(inv : CInventoryComponent)
  1309.     {
  1310.         NewGamePlusAdjustDLCItem('NGP DLC1 Temerian Armor', 'NGP DLC Compatibility Chest Armor Mod', inv);
  1311.         NewGamePlusAdjustDLCItem('NGP DLC1 Temerian Gloves', 'NGP DLC Compatibility Armor Mod', inv);
  1312.         NewGamePlusAdjustDLCItem('NGP DLC1 Temerian Pants', 'NGP DLC Compatibility Armor Mod', inv);
  1313.         NewGamePlusAdjustDLCItem('NGP DLC1 Temerian Boots', 'NGP DLC Compatibility Armor Mod', inv);
  1314.     }
  1315.    
  1316.     private final function NewGamePlusAdjustDLC5NilfgardianSet(inv : CInventoryComponent)
  1317.     {
  1318.         NewGamePlusAdjustDLCItem('NGP DLC5 Nilfgaardian Armor', 'NGP DLC Compatibility Chest Armor Mod', inv);
  1319.         NewGamePlusAdjustDLCItem('NGP DLC5 Nilfgaardian Gloves', 'NGP DLC Compatibility Armor Mod', inv);
  1320.         NewGamePlusAdjustDLCItem('NGP DLC5 Nilfgaardian Pants', 'NGP DLC Compatibility Armor Mod', inv);
  1321.         NewGamePlusAdjustDLCItem('NGP DLC5 Nilfgaardian Boots', 'NGP DLC Compatibility Armor Mod', inv);
  1322.     }
  1323.    
  1324.     private final function NewGamePlusAdjustDLC10WolfSet(inv : CInventoryComponent)
  1325.     {
  1326.         NewGamePlusAdjustDLCItem('NGP Wolf Armor',   'NGP DLC Compatibility Chest Armor Mod', inv);
  1327.         NewGamePlusAdjustDLCItem('NGP Wolf Armor 1', 'NGP DLC Compatibility Chest Armor Mod', inv);
  1328.         NewGamePlusAdjustDLCItem('NGP Wolf Armor 2', 'NGP DLC Compatibility Chest Armor Mod', inv);
  1329.         NewGamePlusAdjustDLCItem('NGP Wolf Armor 3', 'NGP DLC Compatibility Chest Armor Mod', inv);
  1330.        
  1331.         NewGamePlusAdjustDLCItem('NGP Wolf Boots 1', 'NGP DLC Compatibility Armor Mod', inv);
  1332.         NewGamePlusAdjustDLCItem('NGP Wolf Boots 2', 'NGP DLC Compatibility Armor Mod', inv);
  1333.         NewGamePlusAdjustDLCItem('NGP Wolf Boots 3', 'NGP DLC Compatibility Armor Mod', inv);
  1334.         NewGamePlusAdjustDLCItem('NGP Wolf Boots 4', 'NGP DLC Compatibility Armor Mod', inv);
  1335.        
  1336.         NewGamePlusAdjustDLCItem('NGP Wolf Gloves 1', 'NGP DLC Compatibility Armor Mod', inv);
  1337.         NewGamePlusAdjustDLCItem('NGP Wolf Gloves 2', 'NGP DLC Compatibility Armor Mod', inv);
  1338.         NewGamePlusAdjustDLCItem('NGP Wolf Gloves 3', 'NGP DLC Compatibility Armor Mod', inv);
  1339.         NewGamePlusAdjustDLCItem('NGP Wolf Gloves 4', 'NGP DLC Compatibility Armor Mod', inv);
  1340.        
  1341.         NewGamePlusAdjustDLCItem('NGP Wolf Pants 1', 'NGP DLC Compatibility Armor Mod', inv);
  1342.         NewGamePlusAdjustDLCItem('NGP Wolf Pants 2', 'NGP DLC Compatibility Armor Mod', inv);
  1343.         NewGamePlusAdjustDLCItem('NGP Wolf Pants 3', 'NGP DLC Compatibility Armor Mod', inv);
  1344.         NewGamePlusAdjustDLCItem('NGP Wolf Pants 4', 'NGP DLC Compatibility Armor Mod', inv);
  1345.        
  1346.         NewGamePlusAdjustDLCItem('NGP Wolf School steel sword',   'NGP Wolf Steel Sword Mod', inv);
  1347.         NewGamePlusAdjustDLCItem('NGP Wolf School steel sword 1', 'NGP Wolf Steel Sword Mod', inv);
  1348.         NewGamePlusAdjustDLCItem('NGP Wolf School steel sword 2', 'NGP Wolf Steel Sword Mod', inv);
  1349.         NewGamePlusAdjustDLCItem('NGP Wolf School steel sword 3', 'NGP Wolf Steel Sword Mod', inv);
  1350.        
  1351.         NewGamePlusAdjustDLCItem('NGP Wolf School silver sword',   'NGP Wolf Silver Sword Mod', inv);
  1352.         NewGamePlusAdjustDLCItem('NGP Wolf School silver sword 1', 'NGP Wolf Silver Sword Mod', inv);
  1353.         NewGamePlusAdjustDLCItem('NGP Wolf School silver sword 2', 'NGP Wolf Silver Sword Mod', inv);
  1354.         NewGamePlusAdjustDLCItem('NGP Wolf School silver sword 3', 'NGP Wolf Silver Sword Mod', inv);
  1355.     }
  1356.    
  1357.     private final function NewGamePlusAdjustDLC14SkelligeSet(inv : CInventoryComponent)
  1358.     {
  1359.         NewGamePlusAdjustDLCItem('NGP DLC14 Skellige Armor', 'NGP DLC Compatibility Chest Armor Mod', inv);
  1360.         NewGamePlusAdjustDLCItem('NGP DLC14 Skellige Gloves', 'NGP DLC Compatibility Armor Mod', inv);
  1361.         NewGamePlusAdjustDLCItem('NGP DLC14 Skellige Pants', 'NGP DLC Compatibility Armor Mod', inv);
  1362.         NewGamePlusAdjustDLCItem('NGP DLC14 Skellige Boots', 'NGP DLC Compatibility Armor Mod', inv);
  1363.     }
  1364.    
  1365.     //modSigns
  1366.     private final function NewGamePlusReplaceKaerMorhenSet(out inv : CInventoryComponent)
  1367.     {
  1368.         NewGamePlusReplaceItem('Kaer Morhen Armor','NGP Kaer Morhen Armor', inv);
  1369.         NewGamePlusReplaceItem('Kaer Morhen Armor 1','NGP Kaer Morhen Armor 1', inv);
  1370.         NewGamePlusReplaceItem('Kaer Morhen Armor 2','NGP Kaer Morhen Armor 2', inv);
  1371.         NewGamePlusReplaceItem('Kaer Morhen Armor 3','NGP Kaer Morhen Armor 3', inv);
  1372.         NewGamePlusReplaceItem('Kaer Morhen Pants','NGP Kaer Morhen Pants', inv);
  1373.         NewGamePlusReplaceItem('Kaer Morhen Pants 1','NGP Kaer Morhen Pants 1', inv);
  1374.         NewGamePlusReplaceItem('Kaer Morhen Pants 2','NGP Kaer Morhen Pants 2', inv);
  1375.         NewGamePlusReplaceItem('Kaer Morhen Pants 3','NGP Kaer Morhen Pants 3', inv);
  1376.         NewGamePlusReplaceItem('Kaer Morhen Boots','NGP Kaer Morhen Boots', inv);
  1377.         NewGamePlusReplaceItem('Kaer Morhen Boots 1','NGP Kaer Morhen Boots 1', inv);
  1378.         NewGamePlusReplaceItem('Kaer Morhen Boots 2','NGP Kaer Morhen Boots 2', inv);
  1379.         NewGamePlusReplaceItem('Kaer Morhen Boots 3','NGP Kaer Morhen Boots 3', inv);
  1380.         NewGamePlusReplaceItem('Kaer Morhen Gloves','NGP Kaer Morhen Gloves', inv);
  1381.         NewGamePlusReplaceItem('Kaer Morhen Gloves 1','NGP Kaer Morhen Gloves 1', inv);
  1382.         NewGamePlusReplaceItem('Kaer Morhen Gloves 2','NGP Kaer Morhen Gloves 2', inv);
  1383.         NewGamePlusReplaceItem('Kaer Morhen Gloves 3','NGP Kaer Morhen Gloves 3', inv);
  1384.     }
  1385.    
  1386.     private final function NewGamePlusReplaceViperSet(out inv : CInventoryComponent)
  1387.     {
  1388.         NewGamePlusReplaceItem('Viper School steel sword', 'NGP Viper School steel sword', inv);
  1389.        
  1390.         NewGamePlusReplaceItem('Viper School silver sword', 'NGP Viper School silver sword', inv);
  1391.     }
  1392.    
  1393.     private final function NewGamePlusReplaceLynxSet(out inv : CInventoryComponent)
  1394.     {
  1395.         NewGamePlusReplaceItem('Lynx Armor', 'NGP Lynx Armor', inv);
  1396.         NewGamePlusReplaceItem('Lynx Armor 1', 'NGP Lynx Armor 1', inv);
  1397.         NewGamePlusReplaceItem('Lynx Armor 2', 'NGP Lynx Armor 2', inv);
  1398.         NewGamePlusReplaceItem('Lynx Armor 3', 'NGP Lynx Armor 3', inv);
  1399.        
  1400.         NewGamePlusReplaceItem('Lynx Gloves 1', 'NGP Lynx Gloves 1', inv);
  1401.         NewGamePlusReplaceItem('Lynx Gloves 2', 'NGP Lynx Gloves 2', inv);
  1402.         NewGamePlusReplaceItem('Lynx Gloves 3', 'NGP Lynx Gloves 3', inv);
  1403.         NewGamePlusReplaceItem('Lynx Gloves 4', 'NGP Lynx Gloves 4', inv);
  1404.        
  1405.         NewGamePlusReplaceItem('Lynx Pants 1', 'NGP Lynx Pants 1', inv);
  1406.         NewGamePlusReplaceItem('Lynx Pants 2', 'NGP Lynx Pants 2', inv);
  1407.         NewGamePlusReplaceItem('Lynx Pants 3', 'NGP Lynx Pants 3', inv);
  1408.         NewGamePlusReplaceItem('Lynx Pants 4', 'NGP Lynx Pants 4', inv);
  1409.        
  1410.         NewGamePlusReplaceItem('Lynx Boots 1', 'NGP Lynx Boots 1', inv);
  1411.         NewGamePlusReplaceItem('Lynx Boots 2', 'NGP Lynx Boots 2', inv);
  1412.         NewGamePlusReplaceItem('Lynx Boots 3', 'NGP Lynx Boots 3', inv);
  1413.         NewGamePlusReplaceItem('Lynx Boots 4', 'NGP Lynx Boots 4', inv);
  1414.        
  1415.         NewGamePlusReplaceItem('Lynx School steel sword', 'NGP Lynx School steel sword', inv);
  1416.         NewGamePlusReplaceItem('Lynx School steel sword 1', 'NGP Lynx School steel sword 1', inv);
  1417.         NewGamePlusReplaceItem('Lynx School steel sword 2', 'NGP Lynx School steel sword 2', inv);
  1418.         NewGamePlusReplaceItem('Lynx School steel sword 3', 'NGP Lynx School steel sword 3', inv);
  1419.        
  1420.         NewGamePlusReplaceItem('Lynx School silver sword', 'NGP Lynx School silver sword', inv);
  1421.         NewGamePlusReplaceItem('Lynx School silver sword 1', 'NGP Lynx School silver sword 1', inv);
  1422.         NewGamePlusReplaceItem('Lynx School silver sword 2', 'NGP Lynx School silver sword 2', inv);
  1423.         NewGamePlusReplaceItem('Lynx School silver sword 3', 'NGP Lynx School silver sword 3', inv);
  1424.     }
  1425.    
  1426.     private final function NewGamePlusReplaceGryphonSet(out inv : CInventoryComponent)
  1427.     {
  1428.         NewGamePlusReplaceItem('Gryphon Armor', 'NGP Gryphon Armor', inv);
  1429.         NewGamePlusReplaceItem('Gryphon Armor 1', 'NGP Gryphon Armor 1', inv);
  1430.         NewGamePlusReplaceItem('Gryphon Armor 2', 'NGP Gryphon Armor 2', inv);
  1431.         NewGamePlusReplaceItem('Gryphon Armor 3', 'NGP Gryphon Armor 3', inv);
  1432.        
  1433.         NewGamePlusReplaceItem('Gryphon Gloves 1', 'NGP Gryphon Gloves 1', inv);
  1434.         NewGamePlusReplaceItem('Gryphon Gloves 2', 'NGP Gryphon Gloves 2', inv);
  1435.         NewGamePlusReplaceItem('Gryphon Gloves 3', 'NGP Gryphon Gloves 3', inv);
  1436.         NewGamePlusReplaceItem('Gryphon Gloves 4', 'NGP Gryphon Gloves 4', inv);
  1437.        
  1438.         NewGamePlusReplaceItem('Gryphon Pants 1', 'NGP Gryphon Pants 1', inv);
  1439.         NewGamePlusReplaceItem('Gryphon Pants 2', 'NGP Gryphon Pants 2', inv);
  1440.         NewGamePlusReplaceItem('Gryphon Pants 3', 'NGP Gryphon Pants 3', inv);
  1441.         NewGamePlusReplaceItem('Gryphon Pants 4', 'NGP Gryphon Pants 4', inv);
  1442.        
  1443.         NewGamePlusReplaceItem('Gryphon Boots 1', 'NGP Gryphon Boots 1', inv);
  1444.         NewGamePlusReplaceItem('Gryphon Boots 2', 'NGP Gryphon Boots 2', inv);
  1445.         NewGamePlusReplaceItem('Gryphon Boots 3', 'NGP Gryphon Boots 3', inv);
  1446.         NewGamePlusReplaceItem('Gryphon Boots 4', 'NGP Gryphon Boots 4', inv);
  1447.        
  1448.         NewGamePlusReplaceItem('Gryphon School steel sword', 'NGP Gryphon School steel sword', inv);
  1449.         NewGamePlusReplaceItem('Gryphon School steel sword 1', 'NGP Gryphon School steel sword 1', inv);
  1450.         NewGamePlusReplaceItem('Gryphon School steel sword 2', 'NGP Gryphon School steel sword 2', inv);
  1451.         NewGamePlusReplaceItem('Gryphon School steel sword 3', 'NGP Gryphon School steel sword 3', inv);
  1452.        
  1453.         NewGamePlusReplaceItem('Gryphon School silver sword', 'NGP Gryphon School silver sword', inv);
  1454.         NewGamePlusReplaceItem('Gryphon School silver sword 1', 'NGP Gryphon School silver sword 1', inv);
  1455.         NewGamePlusReplaceItem('Gryphon School silver sword 2', 'NGP Gryphon School silver sword 2', inv);
  1456.         NewGamePlusReplaceItem('Gryphon School silver sword 3', 'NGP Gryphon School silver sword 3', inv);
  1457.     }
  1458.    
  1459.     private final function NewGamePlusReplaceBearSet(out inv : CInventoryComponent)
  1460.     {
  1461.         NewGamePlusReplaceItem('Bear Armor', 'NGP Bear Armor', inv);
  1462.         NewGamePlusReplaceItem('Bear Armor 1', 'NGP Bear Armor 1', inv);
  1463.         NewGamePlusReplaceItem('Bear Armor 2', 'NGP Bear Armor 2', inv);
  1464.         NewGamePlusReplaceItem('Bear Armor 3', 'NGP Bear Armor 3', inv);
  1465.        
  1466.         NewGamePlusReplaceItem('Bear Gloves 1', 'NGP Bear Gloves 1', inv);
  1467.         NewGamePlusReplaceItem('Bear Gloves 2', 'NGP Bear Gloves 2', inv);
  1468.         NewGamePlusReplaceItem('Bear Gloves 3', 'NGP Bear Gloves 3', inv);
  1469.         NewGamePlusReplaceItem('Bear Gloves 4', 'NGP Bear Gloves 4', inv);
  1470.        
  1471.         NewGamePlusReplaceItem('Bear Pants 1', 'NGP Bear Pants 1', inv);
  1472.         NewGamePlusReplaceItem('Bear Pants 2', 'NGP Bear Pants 2', inv);
  1473.         NewGamePlusReplaceItem('Bear Pants 3', 'NGP Bear Pants 3', inv);
  1474.         NewGamePlusReplaceItem('Bear Pants 4', 'NGP Bear Pants 4', inv);
  1475.        
  1476.         NewGamePlusReplaceItem('Bear Boots 1', 'NGP Bear Boots 1', inv);
  1477.         NewGamePlusReplaceItem('Bear Boots 2', 'NGP Bear Boots 2', inv);
  1478.         NewGamePlusReplaceItem('Bear Boots 3', 'NGP Bear Boots 3', inv);
  1479.         NewGamePlusReplaceItem('Bear Boots 4', 'NGP Bear Boots 4', inv);
  1480.        
  1481.         NewGamePlusReplaceItem('Bear School steel sword', 'NGP Bear School steel sword', inv);
  1482.         NewGamePlusReplaceItem('Bear School steel sword 1', 'NGP Bear School steel sword 1', inv);
  1483.         NewGamePlusReplaceItem('Bear School steel sword 2', 'NGP Bear School steel sword 2', inv);
  1484.         NewGamePlusReplaceItem('Bear School steel sword 3', 'NGP Bear School steel sword 3', inv);
  1485.        
  1486.         NewGamePlusReplaceItem('Bear School silver sword', 'NGP Bear School silver sword', inv);
  1487.         NewGamePlusReplaceItem('Bear School silver sword 1', 'NGP Bear School silver sword 1', inv);
  1488.         NewGamePlusReplaceItem('Bear School silver sword 2', 'NGP Bear School silver sword 2', inv);
  1489.         NewGamePlusReplaceItem('Bear School silver sword 3', 'NGP Bear School silver sword 3', inv);
  1490.     }
  1491.        
  1492.     private final function NewGamePlusReplaceEP1(out inv : CInventoryComponent)
  1493.     {  
  1494.         NewGamePlusReplaceItem('Ofir Armor', 'NGP Ofir Armor', inv);
  1495.         NewGamePlusReplaceItem('Ofir Sabre 2', 'NGP Ofir Sabre 2', inv);
  1496.        
  1497.         NewGamePlusReplaceItem('Crafted Burning Rose Armor', 'NGP Crafted Burning Rose Armor', inv);
  1498.         NewGamePlusReplaceItem('Crafted Burning Rose Gloves', 'NGP Crafted Burning Rose Gloves', inv);
  1499.         NewGamePlusReplaceItem('Crafted Burning Rose Sword', 'NGP Crafted Burning Rose Sword', inv);
  1500.        
  1501.         NewGamePlusReplaceItem('Crafted Ofir Armor', 'NGP Crafted Ofir Armor', inv);
  1502.         NewGamePlusReplaceItem('Crafted Ofir Boots', 'NGP Crafted Ofir Boots', inv);
  1503.         NewGamePlusReplaceItem('Crafted Ofir Gloves', 'NGP Crafted Ofir Gloves', inv);
  1504.         NewGamePlusReplaceItem('Crafted Ofir Pants', 'NGP Crafted Ofir Pants', inv);
  1505.         NewGamePlusReplaceItem('Crafted Ofir Steel Sword', 'NGP Crafted Ofir Steel Sword', inv);
  1506.        
  1507.         NewGamePlusReplaceItem('EP1 Crafted Witcher Silver Sword', 'NGP EP1 Crafted Witcher Silver Sword', inv);
  1508.         //NewGamePlusReplaceItem('Olgierd Sabre', 'NGP Olgierd Sabre', inv);
  1509.        
  1510.         NewGamePlusReplaceItem('EP1 Witcher Armor', 'NGP EP1 Witcher Armor', inv);
  1511.         NewGamePlusReplaceItem('EP1 Witcher Boots', 'NGP EP1 Witcher Boots', inv);
  1512.         NewGamePlusReplaceItem('EP1 Witcher Gloves', 'NGP EP1 Witcher Gloves', inv);
  1513.         NewGamePlusReplaceItem('EP1 Witcher Pants', 'NGP EP1 Witcher Pants', inv);
  1514.         NewGamePlusReplaceItem('EP1 Viper School steel sword', 'NGP EP1 Viper School steel sword', inv);
  1515.         NewGamePlusReplaceItem('EP1 Viper School silver sword', 'NGP EP1 Viper School silver sword', inv);
  1516.     }
  1517.    
  1518.     private final function NewGamePlusReplaceEP2WitcherSets(out inv : CInventoryComponent)
  1519.     {
  1520.         NewGamePlusReplaceItem('Lynx Armor 4', 'NGP Lynx Armor 4', inv);
  1521.         NewGamePlusReplaceItem('Gryphon Armor 4', 'NGP Gryphon Armor 4', inv);
  1522.         NewGamePlusReplaceItem('Bear Armor 4', 'NGP Bear Armor 4', inv);
  1523.         NewGamePlusReplaceItem('Wolf Armor 4', 'NGP Wolf Armor 4', inv);
  1524.         NewGamePlusReplaceItem('Red Wolf Armor 1', 'NGP Red Wolf Armor 1', inv);
  1525.        
  1526.         NewGamePlusReplaceItem('Lynx Gloves 5', 'NGP Lynx Gloves 5', inv);
  1527.         NewGamePlusReplaceItem('Gryphon Gloves 5', 'NGP Gryphon Gloves 5', inv);
  1528.         NewGamePlusReplaceItem('Bear Gloves 5', 'NGP Bear Gloves 5', inv);
  1529.         NewGamePlusReplaceItem('Wolf Gloves 5', 'NGP Wolf Gloves 5', inv);
  1530.         NewGamePlusReplaceItem('Red Wolf Gloves 1', 'NGP Red Wolf Gloves 1', inv);
  1531.        
  1532.         NewGamePlusReplaceItem('Lynx Pants 5', 'NGP Lynx Pants 5', inv);
  1533.         NewGamePlusReplaceItem('Gryphon Pants 5', 'NGP Gryphon Pants 5', inv);
  1534.         NewGamePlusReplaceItem('Bear Pants 5', 'NGP Bear Pants 5', inv);
  1535.         NewGamePlusReplaceItem('Wolf Pants 5', 'NGP Wolf Pants 5', inv);
  1536.         NewGamePlusReplaceItem('Red Wolf Pants 1', 'NGP Red Wolf Pants 1', inv);
  1537.        
  1538.         NewGamePlusReplaceItem('Lynx Boots 5', 'NGP Lynx Boots 5', inv);
  1539.         NewGamePlusReplaceItem('Gryphon Boots 5', 'NGP Gryphon Boots 5', inv);
  1540.         NewGamePlusReplaceItem('Bear Boots 5', 'NGP Bear Boots 5', inv);
  1541.         NewGamePlusReplaceItem('Wolf Boots 5', 'NGP Wolf Boots 5', inv);
  1542.         NewGamePlusReplaceItem('Red Wolf Boots 1', 'NGP Red Wolf Boots 1', inv);
  1543.        
  1544.        
  1545.         NewGamePlusReplaceItem('Lynx School steel sword 4', 'NGP Lynx School steel sword 4', inv);
  1546.         NewGamePlusReplaceItem('Gryphon School steel sword 4', 'NGP Gryphon School steel sword 4', inv);
  1547.         NewGamePlusReplaceItem('Bear School steel sword 4', 'NGP Bear School steel sword 4', inv);
  1548.         NewGamePlusReplaceItem('Wolf School steel sword 4', 'NGP Wolf School steel sword 4', inv);
  1549.         NewGamePlusReplaceItem('Red Wolf School steel sword 1', 'NGP Red Wolf School steel sword 1', inv);
  1550.        
  1551.         NewGamePlusReplaceItem('Lynx School silver sword 4', 'NGP Lynx School silver sword 4', inv);
  1552.         NewGamePlusReplaceItem('Gryphon School silver sword 4', 'NGP Gryphon School silver sword 4', inv);
  1553.         NewGamePlusReplaceItem('Bear School silver sword 4', 'NGP Bear School silver sword 4', inv);
  1554.         NewGamePlusReplaceItem('Wolf School silver sword 4', 'NGP Wolf School silver sword 4', inv);
  1555.         NewGamePlusReplaceItem('Red Wolf School silver sword 1', 'NGP Red Wolf School silver sword 1', inv);
  1556.     }
  1557.    
  1558.     private final function NewGamePlusReplaceEP2Items(out inv : CInventoryComponent)
  1559.     {
  1560.         NewGamePlusReplaceItem('Guard Lvl1 Armor 3', 'NGP Guard Lvl1 Armor 3', inv);
  1561.         NewGamePlusReplaceItem('Guard Lvl1 A Armor 3', 'NGP Guard Lvl1 A Armor 3', inv);
  1562.         NewGamePlusReplaceItem('Guard Lvl2 Armor 3', 'NGP Guard Lvl2 Armor 3', inv);
  1563.         NewGamePlusReplaceItem('Guard Lvl2 A Armor 3', 'NGP Guard Lvl2 A Armor 3', inv);
  1564.         NewGamePlusReplaceItem('Knight Geralt Armor 3', 'NGP Knight Geralt Armor 3', inv);
  1565.         NewGamePlusReplaceItem('Knight Geralt A Armor 3', 'NGP Knight Geralt A Armor 3', inv);
  1566.         //NewGamePlusReplaceItem('q702_vampire_armor', 'NGP q702_vampire_armor', inv);
  1567.        
  1568.         NewGamePlusReplaceItem('Guard Lvl1 Gloves 3', 'NGP Guard Lvl1 Gloves 3', inv);
  1569.         NewGamePlusReplaceItem('Guard Lvl1 A Gloves 3', 'NGP Guard Lvl1 A Gloves 3', inv);
  1570.         NewGamePlusReplaceItem('Guard Lvl2 Gloves 3', 'NGP Guard Lvl2 Gloves 3', inv);
  1571.         NewGamePlusReplaceItem('Guard Lvl2 A Gloves 3', 'NGP Guard Lvl2 A Gloves 3', inv);
  1572.         NewGamePlusReplaceItem('Knight Geralt Gloves 3', 'NGP Knight Geralt Gloves 3', inv);
  1573.         NewGamePlusReplaceItem('Knight Geralt A Gloves 3', 'NGP Knight Geralt A Gloves 3', inv);
  1574.         //NewGamePlusReplaceItem('q702_vampire_gloves', 'NGP q702_vampire_gloves', inv);
  1575.        
  1576.         NewGamePlusReplaceItem('Guard Lvl1 Pants 3', 'NGP Guard Lvl1 Pants 3', inv);
  1577.         NewGamePlusReplaceItem('Guard Lvl1 A Pants 3', 'NGP Guard Lvl1 A Pants 3', inv);
  1578.         NewGamePlusReplaceItem('Guard Lvl2 Pants 3', 'NGP Guard Lvl2 Pants 3', inv);
  1579.         NewGamePlusReplaceItem('Guard Lvl2 A Pants 3', 'NGP Guard Lvl2 A Pants 3', inv);
  1580.         NewGamePlusReplaceItem('Knight Geralt Pants 3', 'NGP Knight Geralt Pants 3', inv);
  1581.         NewGamePlusReplaceItem('Knight Geralt A Pants 3', 'NGP Knight Geralt A Pants 3', inv);
  1582.         //NewGamePlusReplaceItem('q702_vampire_pants', 'NGP q702_vampire_pants', inv);
  1583.        
  1584.         NewGamePlusReplaceItem('Guard Lvl1 Boots 3', 'NGP Guard Lvl1 Boots 3', inv);
  1585.         NewGamePlusReplaceItem('Guard Lvl1 A Boots 3', 'NGP Guard Lvl1 A Boots 3', inv);
  1586.         NewGamePlusReplaceItem('Guard Lvl2 Boots 3', 'NGP Guard Lvl2 Boots 3', inv);
  1587.         NewGamePlusReplaceItem('Guard Lvl2 A Boots 3', 'NGP Guard Lvl2 A Boots 3', inv);
  1588.         NewGamePlusReplaceItem('Knight Geralt Boots 3', 'NGP Knight Geralt Boots 3', inv);
  1589.         NewGamePlusReplaceItem('Knight Geralt A Boots 3', 'NGP Knight Geralt A Boots 3', inv);
  1590.         //NewGamePlusReplaceItem('q702_vampire_boots', 'NGP q702_vampire_boots', inv);
  1591.        
  1592.         NewGamePlusReplaceItem('Serpent Steel Sword 1', 'NGP Serpent Steel Sword 1', inv);
  1593.         NewGamePlusReplaceItem('Serpent Steel Sword 2', 'NGP Serpent Steel Sword 2', inv);
  1594.         NewGamePlusReplaceItem('Serpent Steel Sword 3', 'NGP Serpent Steel Sword 3', inv);
  1595.         NewGamePlusReplaceItem('Guard lvl1 steel sword 3', 'NGP Guard lvl1 steel sword 3', inv);
  1596.         NewGamePlusReplaceItem('Guard lvl2 steel sword 3', 'NGP Guard lvl2 steel sword 3', inv);
  1597.         NewGamePlusReplaceItem('Knights steel sword 3', 'NGP Knights steel sword 3', inv);
  1598.         NewGamePlusReplaceItem('Hanza steel sword 3', 'NGP Hanza steel sword 3', inv);
  1599.         NewGamePlusReplaceItem('Toussaint steel sword 3', 'NGP Toussaint steel sword 3', inv);
  1600.         //NewGamePlusReplaceItem('q702 vampire steel sword', 'NGP q702 vampire steel sword', inv);
  1601.        
  1602.         NewGamePlusReplaceItem('Serpent Silver Sword 1', 'NGP Serpent Silver Sword 1', inv);
  1603.         NewGamePlusReplaceItem('Serpent Silver Sword 2', 'NGP Serpent Silver Sword 2', inv);
  1604.         NewGamePlusReplaceItem('Serpent Silver Sword 3', 'NGP Serpent Silver Sword 3', inv);
  1605.     }
  1606.    
  1607.     public function GetEquippedSword(steel : bool) : SItemUniqueId
  1608.     {
  1609.         var item : SItemUniqueId;
  1610.        
  1611.         if(steel)
  1612.             GetItemEquippedOnSlot(EES_SteelSword, item);
  1613.         else
  1614.             GetItemEquippedOnSlot(EES_SilverSword, item);
  1615.            
  1616.         return item;
  1617.     }
  1618.    
  1619.     timer function BroadcastRain( deltaTime : float, id : int )
  1620.     {
  1621.         var rainStrength : float = 0;
  1622.         rainStrength = GetRainStrength();
  1623.         if( rainStrength > 0.5 )
  1624.         {
  1625.             theGame.GetBehTreeReactionManager().CreateReactionEventIfPossible( thePlayer, 'RainAction', 2.0f , 50.0f, -1.f, -1, true);
  1626.             LogReactionSystem( "'RainAction' was sent by Player - single broadcast - distance: 50.0" );
  1627.         }
  1628.     }
  1629.    
  1630.     function InitializeParryType()
  1631.     {
  1632.         var i, j : int;
  1633.        
  1634.         parryTypeTable.Resize( EnumGetMax('EAttackSwingType')+1 );
  1635.         for( i = 0; i < EnumGetMax('EAttackSwingType')+1; i += 1 )
  1636.         {
  1637.             parryTypeTable[i].Resize( EnumGetMax('EAttackSwingDirection')+1 );
  1638.         }
  1639.         parryTypeTable[AST_Horizontal][ASD_UpDown] = PT_None;
  1640.         parryTypeTable[AST_Horizontal][ASD_DownUp] = PT_None;
  1641.         parryTypeTable[AST_Horizontal][ASD_LeftRight] = PT_Left;
  1642.         parryTypeTable[AST_Horizontal][ASD_RightLeft] = PT_Right;
  1643.         parryTypeTable[AST_Vertical][ASD_UpDown] = PT_Up;
  1644.         parryTypeTable[AST_Vertical][ASD_DownUp] = PT_Down;
  1645.         parryTypeTable[AST_Vertical][ASD_LeftRight] = PT_None;
  1646.         parryTypeTable[AST_Vertical][ASD_RightLeft] = PT_None;
  1647.         parryTypeTable[AST_DiagonalUp][ASD_UpDown] = PT_None;
  1648.         parryTypeTable[AST_DiagonalUp][ASD_DownUp] = PT_None;
  1649.         parryTypeTable[AST_DiagonalUp][ASD_LeftRight] = PT_UpLeft;
  1650.         parryTypeTable[AST_DiagonalUp][ASD_RightLeft] = PT_RightUp;
  1651.         parryTypeTable[AST_DiagonalDown][ASD_UpDown] = PT_None;
  1652.         parryTypeTable[AST_DiagonalDown][ASD_DownUp] = PT_None;
  1653.         parryTypeTable[AST_DiagonalDown][ASD_LeftRight] = PT_LeftDown;
  1654.         parryTypeTable[AST_DiagonalDown][ASD_RightLeft] = PT_DownRight;
  1655.         parryTypeTable[AST_Jab][ASD_UpDown] = PT_Jab;
  1656.         parryTypeTable[AST_Jab][ASD_DownUp] = PT_Jab;
  1657.         parryTypeTable[AST_Jab][ASD_LeftRight] = PT_Jab;
  1658.         parryTypeTable[AST_Jab][ASD_RightLeft] = PT_Jab;   
  1659.     }
  1660.    
  1661.    
  1662.    
  1663.    
  1664.    
  1665.    
  1666.     event OnDeath( damageAction : W3DamageAction )
  1667.     {
  1668.         var items       : array< SItemUniqueId >;
  1669.         var i, size     : int; 
  1670.         var slot        : EEquipmentSlots;
  1671.         var holdSlot    : name;
  1672.    
  1673.         super.OnDeath( damageAction );
  1674.    
  1675.         items = GetHeldItems();
  1676.                
  1677.         if( rangedWeapon && rangedWeapon.GetCurrentStateName() != 'State_WeaponWait')
  1678.         {
  1679.             OnRangedForceHolster( true, true, true );      
  1680.             rangedWeapon.ClearDeployedEntity(true);
  1681.         }
  1682.        
  1683.         size = items.Size();
  1684.        
  1685.         if ( size > 0 )
  1686.         {
  1687.             for ( i = 0; i < size; i += 1 )
  1688.             {
  1689.                 if ( this.inv.IsIdValid( items[i] ) && !( this.inv.IsItemCrossbow( items[i] ) ) )
  1690.                 {
  1691.                     holdSlot = this.inv.GetItemHoldSlot( items[i] );               
  1692.                
  1693.                     if (  holdSlot == 'l_weapon' && this.IsHoldingItemInLHand() )
  1694.                     {
  1695.                         this.OnUseSelectedItem( true );
  1696.                     }          
  1697.            
  1698.                     DropItemFromSlot( holdSlot, false );
  1699.                    
  1700.                     if ( holdSlot == 'r_weapon' )
  1701.                     {
  1702.                         slot = this.GetItemSlot( items[i] );
  1703.                         if ( UnequipItemFromSlot( slot ) )
  1704.                             Log( "Unequip" );
  1705.                     }
  1706.                 }
  1707.             }
  1708.         }
  1709.     }
  1710.    
  1711.    
  1712.    
  1713.    
  1714.    
  1715.    
  1716.    
  1717.     function HandleMovement( deltaTime : float )
  1718.     {
  1719.         super.HandleMovement( deltaTime );
  1720.        
  1721.         rawCameraHeading = theCamera.GetCameraHeading();
  1722.     }
  1723.        
  1724.    
  1725.    
  1726.    
  1727.    
  1728.    
  1729.    
  1730.     function ToggleSpecialAttackHeavyAllowed( toggle : bool)
  1731.     {
  1732.         specialAttackHeavyAllowed = toggle;
  1733.     }
  1734.    
  1735.     function GetReputationManager() : W3Reputation
  1736.     {
  1737.         return reputationManager;
  1738.     }
  1739.            
  1740.     function OnRadialMenuItemChoose( selectedItem : string )
  1741.     {
  1742.         var iSlotId : int;
  1743.         var item : SItemUniqueId;
  1744.        
  1745.         if ( selectedItem != "Crossbow" )
  1746.         {
  1747.             if ( rangedWeapon && rangedWeapon.GetCurrentStateName() != 'State_WeaponWait' )
  1748.                 OnRangedForceHolster( true, false );
  1749.         }
  1750.        
  1751.        
  1752.         switch(selectedItem)
  1753.         {
  1754.            
  1755.             case "Meditation":
  1756.                 theGame.RequestMenuWithBackground( 'MeditationClockMenu', 'CommonMenu' );
  1757.                 break;         
  1758.             case "Slot1":
  1759.                 GetItemEquippedOnSlot( EES_Petard1, item );
  1760.                 if( thePlayer.inv.IsIdValid( item ) )
  1761.                 {
  1762.                     SelectQuickslotItem( EES_Petard1 );
  1763.                 }
  1764.                 else
  1765.                 {
  1766.                     SelectQuickslotItem( EES_Petard2 );
  1767.                 }
  1768.                 break;
  1769.                
  1770.             case "Slot2":
  1771.                 GetItemEquippedOnSlot( EES_Petard2, item );
  1772.                 if( thePlayer.inv.IsIdValid( item ) )
  1773.                 {
  1774.                     SelectQuickslotItem( EES_Petard2 );
  1775.                 }
  1776.                 else
  1777.                 {
  1778.                     SelectQuickslotItem( EES_Petard1 );
  1779.                 }
  1780.                 break;
  1781.                
  1782.             case "Crossbow":
  1783.                 SelectQuickslotItem(EES_RangedWeapon);
  1784.                 break;
  1785.                
  1786.             case "Slot3":
  1787.                 GetItemEquippedOnSlot( EES_Quickslot1, item );
  1788.                 if( thePlayer.inv.IsIdValid( item ) )
  1789.                 {
  1790.                     SelectQuickslotItem( EES_Quickslot1 );
  1791.                 }
  1792.                 else
  1793.                 {
  1794.                     SelectQuickslotItem( EES_Quickslot2 );
  1795.                 }
  1796.                 break;
  1797.                
  1798.             case "Slot4":
  1799.                 GetItemEquippedOnSlot( EES_Quickslot2, item );
  1800.                 if( thePlayer.inv.IsIdValid( item ) )
  1801.                 {
  1802.                     SelectQuickslotItem( EES_Quickslot2 );
  1803.                 }
  1804.                 else
  1805.                 {
  1806.                     SelectQuickslotItem( EES_Quickslot1 );
  1807.                 }
  1808.                 break;
  1809.                
  1810.             default:
  1811.                 SetEquippedSign(SignStringToEnum( selectedItem ));
  1812.                 FactsRemove("SignToggled");
  1813.                 break;
  1814.         }
  1815.     }
  1816.    
  1817.     function ToggleNextItem()
  1818.     {
  1819.         var quickSlotItems : array< EEquipmentSlots >;
  1820.         var currentSelectedItem : SItemUniqueId;
  1821.         var item : SItemUniqueId;
  1822.         var i : int;
  1823.        
  1824.         for( i = EES_Quickslot2; i > EES_Petard1 - 1; i -= 1 )
  1825.         {
  1826.             GetItemEquippedOnSlot( i, item );
  1827.             if( inv.IsIdValid( item ) )
  1828.             {
  1829.                 quickSlotItems.PushBack( i );
  1830.             }
  1831.         }
  1832.         if( !quickSlotItems.Size() )
  1833.         {
  1834.             return;
  1835.         }
  1836.        
  1837.         currentSelectedItem = GetSelectedItemId();
  1838.        
  1839.         if( inv.IsIdValid( currentSelectedItem ) )
  1840.         {
  1841.             for( i = 0; i < quickSlotItems.Size(); i += 1 )
  1842.             {
  1843.                 GetItemEquippedOnSlot( quickSlotItems[i], item );
  1844.                 if( currentSelectedItem == item )
  1845.                 {
  1846.                     if( i == quickSlotItems.Size() - 1 )
  1847.                     {
  1848.                         SelectQuickslotItem( quickSlotItems[ 0 ] );
  1849.                     }
  1850.                     else
  1851.                     {
  1852.                         SelectQuickslotItem( quickSlotItems[ i + 1 ] );
  1853.                     }
  1854.                     return;
  1855.                 }
  1856.             }
  1857.         }
  1858.         else
  1859.         {
  1860.             SelectQuickslotItem( quickSlotItems[ 0 ] );
  1861.         }
  1862.     }
  1863.        
  1864.    
  1865.     function SetEquippedSign( signType : ESignType )
  1866.     {
  1867.         if(!IsSignBlocked(signType))
  1868.         {
  1869.             equippedSign = signType;
  1870.             FactsSet("CurrentlySelectedSign", equippedSign);
  1871.         }
  1872.     }
  1873.    
  1874.     function GetEquippedSign() : ESignType
  1875.     {
  1876.         return equippedSign;
  1877.     }
  1878.    
  1879.     function GetCurrentlyCastSign() : ESignType
  1880.     {
  1881.         return currentlyCastSign;
  1882.     }
  1883.    
  1884.     function SetCurrentlyCastSign( type : ESignType, entity : W3SignEntity )
  1885.     {
  1886.         currentlyCastSign = type;
  1887.        
  1888.         if( type != ST_None )
  1889.         {
  1890.             signs[currentlyCastSign].entity = entity;
  1891.         }
  1892.     }
  1893.    
  1894.     function GetCurrentSignEntity() : W3SignEntity
  1895.     {
  1896.         if(currentlyCastSign == ST_None)
  1897.             return NULL;
  1898.            
  1899.         return signs[currentlyCastSign].entity;
  1900.     }
  1901.    
  1902.     public function GetSignEntity(type : ESignType) : W3SignEntity
  1903.     {
  1904.         if(type == ST_None)
  1905.             return NULL;
  1906.            
  1907.         return signs[type].entity;
  1908.     }
  1909.    
  1910.     public function GetSignTemplate(type : ESignType) : CEntityTemplate
  1911.     {
  1912.         if(type == ST_None)
  1913.             return NULL;
  1914.            
  1915.         return signs[type].template;
  1916.     }
  1917.    
  1918.     public function IsCurrentSignChanneled() : bool
  1919.     {
  1920.         if( currentlyCastSign != ST_None && signs[currentlyCastSign].entity)
  1921.             return signs[currentlyCastSign].entity.OnCheckChanneling();
  1922.        
  1923.         return false;
  1924.     }
  1925.    
  1926.     function IsCastingSign() : bool
  1927.     {
  1928.         return currentlyCastSign != ST_None;
  1929.     }
  1930.    
  1931.    
  1932.     protected function IsInCombatActionCameraRotationEnabled() : bool
  1933.     {
  1934.         if( IsInCombatAction() && ( GetCombatAction() == EBAT_EMPTY || GetCombatAction() == EBAT_Parry ) )
  1935.         {
  1936.             return true;
  1937.         }
  1938.        
  1939.         return !bIsInCombatAction;
  1940.     }
  1941.    
  1942.     function SetHoldBeforeOpenRadialMenuTime ( time : float )
  1943.     {
  1944.         _HoldBeforeOpenRadialMenuTime = time;
  1945.     }
  1946.    
  1947.    
  1948.    
  1949.    
  1950.    
  1951.    
  1952.    
  1953.     public function RepairItem (  rapairKitId : SItemUniqueId, usedOnItem : SItemUniqueId )
  1954.     {
  1955.         var itemMaxDurablity        : float;
  1956.         var itemCurrDurablity       : float;
  1957.         var baseRepairValue         : float;
  1958.         var reapirValue             : float;
  1959.         var itemAttribute           : SAbilityAttributeValue;
  1960.         var dmgBoost                : float; //modSigns
  1961.        
  1962.         itemMaxDurablity = inv.GetItemMaxDurability(usedOnItem);
  1963.         itemCurrDurablity = inv.GetItemDurability(usedOnItem);
  1964.         itemAttribute = inv.GetItemAttributeValue ( rapairKitId, 'repairValue' );
  1965.        
  1966.         /*if( itemCurrDurablity >= itemMaxDurablity )
  1967.         {
  1968.             return;
  1969.         }*/ //modSigns
  1970.        
  1971.         if ( inv.IsItemAnyArmor ( usedOnItem )|| inv.IsItemWeapon( usedOnItem ) )
  1972.         {          
  1973.             //modSigns: master repair kits increase item level
  1974.             if( inv.ItemHasTag( rapairKitId, 'ArmorReapairKit_Master' ) || inv.ItemHasTag( rapairKitId, 'WeaponReapairKit_Master' ) )
  1975.             {
  1976.                 inv.AddItemLevelAbility( usedOnItem );
  1977.                 if( inv.ItemHasTag( usedOnItem, 'Aerondight' ) )
  1978.                 {
  1979.                     dmgBoost = inv.GetItemModifierFloat( usedOnItem, 'PermDamageBoost' );
  1980.                     if( dmgBoost > 10 )
  1981.                         inv.SetItemModifierFloat( usedOnItem, 'PermDamageBoost', dmgBoost - 10 );
  1982.                 }
  1983.             }
  1984.            
  1985.             baseRepairValue = itemMaxDurablity * itemAttribute.valueMultiplicative;                
  1986.             reapirValue = MinF( itemCurrDurablity + baseRepairValue, itemMaxDurablity );
  1987.            
  1988.             inv.SetItemDurabilityScript ( usedOnItem, MinF ( reapirValue, itemMaxDurablity ));
  1989.         }
  1990.        
  1991.         inv.RemoveItem ( rapairKitId, 1 );
  1992.        
  1993.     }
  1994.     public function HasRepairAbleGearEquiped ( ) : bool
  1995.     {
  1996.         var curEquipedItem : SItemUniqueId;
  1997.        
  1998.         return ( GetItemEquippedOnSlot(EES_Armor, curEquipedItem) || GetItemEquippedOnSlot(EES_Boots, curEquipedItem) || GetItemEquippedOnSlot(EES_Pants, curEquipedItem) || GetItemEquippedOnSlot(EES_Gloves, curEquipedItem)) == true;
  1999.     }
  2000.     public function HasRepairAbleWaponEquiped () : bool
  2001.     {
  2002.         var curEquipedItem : SItemUniqueId;
  2003.        
  2004.         return ( GetItemEquippedOnSlot(EES_SilverSword, curEquipedItem) || GetItemEquippedOnSlot(EES_SteelSword, curEquipedItem) ) == true;
  2005.     }
  2006.     public function IsItemRepairAble ( item : SItemUniqueId ) : bool
  2007.     {
  2008.         return inv.HasItemDurability(item); //inv.GetItemDurabilityRatio(item) <= 0.99999f; //modSigns
  2009.     }
  2010.    
  2011.    
  2012.    
  2013.    
  2014.    
  2015.    
  2016.        
  2017.    
  2018.     public function ApplyOil( oilId : SItemUniqueId, usedOnItem : SItemUniqueId ) : bool
  2019.     {
  2020.         var tutStateOil : W3TutorialManagerUIHandlerStateOils;     
  2021.        
  2022.         if( !super.ApplyOil( oilId, usedOnItem ))
  2023.             return false;
  2024.                
  2025.        
  2026.         if(ShouldProcessTutorial('TutorialOilCanEquip3'))
  2027.         {
  2028.             tutStateOil = (W3TutorialManagerUIHandlerStateOils)theGame.GetTutorialSystem().uiHandler.GetCurrentState();
  2029.             if(tutStateOil)
  2030.             {
  2031.                 tutStateOil.OnOilApplied();
  2032.             }
  2033.         }
  2034.        
  2035.         return true;
  2036.     }
  2037.    
  2038.     private final function RemoveExtraOilsFromItem( item : SItemUniqueId )
  2039.     {
  2040.         var oils : array< CBaseGameplayEffect >;
  2041.         var i, cnt : int;
  2042.         var buff : W3Effect_Oil;
  2043.    
  2044.         oils = GetBuffs( EET_Oil );
  2045.         for( i=0; i<oils.Size(); i+=1 )
  2046.         {          
  2047.             buff = (W3Effect_Oil) oils[ i ];
  2048.             if( buff && buff.GetSwordItemId() == item )
  2049.             {
  2050.                 cnt += 1;
  2051.             }
  2052.         }
  2053.         while( cnt > 1 )
  2054.         {
  2055.             inv.RemoveOldestOilFromItem( item );
  2056.             cnt -= 1;
  2057.         }
  2058.     }
  2059.    
  2060.    
  2061.    
  2062.    
  2063.    
  2064.    
  2065.    
  2066.    
  2067.     //modSigns: rewritten
  2068.     function ReduceDamage(out damageData : W3DamageAction)
  2069.     {
  2070.         var actorAttacker : CActor;
  2071.         var quen : W3QuenEntity;
  2072.         var attackRange : CAIAttackRange;
  2073.         var safeAngleDist, armorAngleBonus, angleDist, distToAttacker, damageReduction, currAdrenaline, adrenReducedDmg, focus, chance : float;
  2074.         var attackName : name;
  2075.         var isDodging, isRolling, isAttackerHuge, isIceGiantSpecial : bool;
  2076.         var min, max : SAbilityAttributeValue;
  2077.         var skillLevel : int;
  2078.         var attackAction : W3Action_Attack;
  2079.         var whirlDmgReduction : SAbilityAttributeValue; //modSigns
  2080.        
  2081.         super.ReduceDamage(damageData);
  2082.        
  2083.         //damage prevented in super
  2084.         if(!damageData.DealsAnyDamage())
  2085.             return;
  2086.        
  2087.         quen = (W3QuenEntity)signs[ST_Quen].entity;
  2088.         actorAttacker = (CActor)damageData.attacker;
  2089.         attackAction = (W3Action_Attack)damageData;
  2090.         //modSigns: fix dodge detection bug - shouldn't be needed anymore, but leaving it here just in case
  2091.         isDodging = IsCurrentlyDodging() || IsInCombatAction() && ((int)GetBehaviorVariable( 'combatActionType' ) == CAT_Dodge || (int)GetBehaviorVariable( 'combatActionType' ) == CAT_Roll);
  2092.         //check if the player is rolling
  2093.         isRolling = isDodging && ( GetBehaviorVariable( 'isRolling' ) == 1.f || (int)GetBehaviorVariable( 'combatActionType' ) == CAT_Roll );
  2094.        
  2095.         //modSigns: debug
  2096.         if( FactsQuerySum( "modSigns_debug_reduce_damage" ) > 0 )
  2097.         {
  2098.             theGame.witcherLog.AddMessage("Is in combat action: " + (int)IsInCombatAction());
  2099.             theGame.witcherLog.AddMessage("Player action: " + GetBehaviorVariable( 'combatActionType' ));
  2100.             theGame.witcherLog.AddMessage("Player is dodging: " + isDodging);
  2101.             theGame.witcherLog.AddMessage("Player is rolling: " + isRolling);
  2102.         }
  2103.        
  2104.         if(actorAttacker && isDodging && !(damageData.IsActionEnvironment() || damageData.IsDoTDamage()))
  2105.         {
  2106.             attackName = actorAttacker.GetLastAttackRangeName();
  2107.             angleDist = AbsF(AngleDistance(evadeHeading, actorAttacker.GetHeading()));
  2108.             attackRange = theGame.GetAttackRangeForEntity(actorAttacker, attackName);
  2109.             distToAttacker = VecDistance(this.GetWorldPosition(), damageData.attacker.GetWorldPosition());
  2110.             isAttackerHuge = actorAttacker.IsHuge();
  2111.             if( CanUseSkill(S_Sword_s09) )
  2112.             {
  2113.                 skillLevel = GetSkillLevel(S_Sword_s09);
  2114.                 //damageReduction = CalculateAttributeValue(GetSkillAttributeValue(S_Sword_s09, 'damage_reduction', false, true)) * skillLevel;
  2115.             }
  2116.             else
  2117.             {
  2118.                 skillLevel = 0;
  2119.                 //damageReduction = 0;
  2120.             }
  2121.             //set up safe angle distance depending on attacker size and Fleet Footed skill
  2122.             isIceGiantSpecial = ( attackName == 'stomp' || attackName == 'anchor_special_far' || attackName == 'anchor_far' );
  2123.             if( !damageData.CanBeDodged() || isIceGiantSpecial )
  2124.                 safeAngleDist =  30 + skillLevel * 10; // 30 ->  80
  2125.             if( isAttackerHuge )
  2126.                 safeAngleDist =  90 + skillLevel * 10; // 90 -> 140
  2127.             else
  2128.                 safeAngleDist = 120 + skillLevel * 10; //120 -> 170
  2129.             if( HasAbility('ArmorTypeLightSetBonusAbility') )
  2130.                 armorAngleBonus = CalculateAttributeValue(GetAbilityAttributeValue('ArmorTypeLightSetBonusAbility', 'dodge_safe_ange_dist_deg'));
  2131.             safeAngleDist += armorAngleBonus;
  2132.             safeAngleDist = ClampF( safeAngleDist, 0, 180 );
  2133.             //handle undodgeable attacks
  2134.             if( !damageData.CanBeDodged() )
  2135.             {
  2136.                 if( isRolling && angleDist <= safeAngleDist )
  2137.                 {
  2138.                     if( attackRange.rangeMax > 0 )
  2139.                         damageReduction = ClampF( distToAttacker/attackRange.rangeMax, 0, 1 );
  2140.                     else
  2141.                         damageReduction = 0;
  2142.                     damageData.processedDmg.vitalityDamage *= ClampF( 1 - damageReduction, 0.05, 1 );
  2143.                     if( theGame.CanLog() )
  2144.                     {
  2145.                         LogDMHits("W3PlayerWitcher.ReduceDamage: reduced damage while dodging an attack", damageData );
  2146.                     }
  2147.                 }
  2148.             }
  2149.             //dodgeable attacks: check if the damage was avoided completely
  2150.             else if( angleDist <= safeAngleDist )
  2151.             {
  2152.                 if( theGame.CanLog() )
  2153.                 {
  2154.                     LogDMHits("W3PlayerWitcher.ReduceDamage: Attack dodged by player - no damage done", damageData);
  2155.                 }
  2156.                 damageData.SetAllProcessedDamageAs(0);
  2157.                 damageData.SetWasDodged();
  2158.             }
  2159.             //dodgeable attacks: reduce damage based on angle distance
  2160.             else
  2161.             {
  2162.                 damageReduction = ClampF( (180 - angleDist)/(180 - safeAngleDist), 0, 1 );
  2163.                 damageData.processedDmg.vitalityDamage *= ClampF( 1 - damageReduction, 0.05, 1 );
  2164.                 if( theGame.CanLog() )
  2165.                 {
  2166.                     LogDMHits("W3PlayerWitcher.ReduceDamage: reduced damage while dodging an attack", damageData );
  2167.                 }
  2168.             }
  2169.             //modSigns: debug
  2170.             if( FactsQuerySum( "modSigns_debug_reduce_damage" ) > 0 )
  2171.             {
  2172.                 theGame.witcherLog.AddMessage("Player Fleet Footed level = " + skillLevel);
  2173.                 //theGame.witcherLog.AddMessage("Skill damage reduction: " + damageReduction);
  2174.                 theGame.witcherLog.AddMessage("Attacker is huge: " + isAttackerHuge);
  2175.                 theGame.witcherLog.AddMessage("Attack name: " + attackName);
  2176.                 theGame.witcherLog.AddMessage("Attack can be dodged: " + damageData.CanBeDodged());
  2177.                 theGame.witcherLog.AddMessage("Armor angle bonus: " + armorAngleBonus);
  2178.                 theGame.witcherLog.AddMessage("Safe angle distance: " + safeAngleDist);
  2179.                 theGame.witcherLog.AddMessage("Attacker and evade angle distance: " + angleDist);
  2180.                 theGame.witcherLog.AddMessage("Attack range: " + attackRange.rangeMax);
  2181.                 theGame.witcherLog.AddMessage("Distance to attacker: " + distToAttacker);
  2182.                 if( damageReduction > 0 )
  2183.                     theGame.witcherLog.AddMessage("Damage reduction for an attack: " + damageReduction);
  2184.                 theGame.witcherLog.AddMessage("Damage was dodged completely: " + damageData.WasDodged());
  2185.             }
  2186.         }
  2187.        
  2188.         //Mutated Skin passive ability
  2189.         if( IsMutationActive( EPMT_Mutation5 ) && !IsAnyQuenActive() && !damageData.IsDoTDamage() )
  2190.         {
  2191.             focus = GetStat( BCS_Focus );
  2192.             currAdrenaline = FloorF( focus );
  2193.             if( currAdrenaline >= 1 )
  2194.             {
  2195.                 theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation5', 'mut5_dmg_red_perc', min, max );
  2196.                 adrenReducedDmg = ( currAdrenaline * min.valueAdditive );
  2197.                 damageData.processedDmg.vitalityDamage *= ClampF(1 - adrenReducedDmg, 0, 1);
  2198.                
  2199.                
  2200.                 theGame.MutationHUDFeedback( MFT_PlayOnce );
  2201.                
  2202.                 if( focus >= 3.f )
  2203.                 {
  2204.                     PlayEffect( 'mutation_5_stage_03' );
  2205.                 }
  2206.                 else if( focus >= 2.f )
  2207.                 {
  2208.                     PlayEffect( 'mutation_5_stage_02' );
  2209.                 }
  2210.                 else
  2211.                 {
  2212.                     PlayEffect( 'mutation_5_stage_01' );
  2213.                 }
  2214.             }
  2215.         }
  2216.        
  2217.         //modSigns: whirl incoming damage reduction
  2218.         if( GetStat(BCS_Focus) >= 1 && IsDoingSpecialAttack(false) )
  2219.         {
  2220.             whirlDmgReduction = GetSkillAttributeValue(S_Sword_s01, 'whirl_dmg_reduction', false, true)
  2221.                 + GetSkillAttributeValue(S_Sword_s01, 'whirl_dmg_reduction_bonus_after_1', false, true) * (GetSkillLevel(S_Sword_s01) - 1);
  2222.             damageData.processedDmg.vitalityDamage *= ClampF(1 - whirlDmgReduction.valueMultiplicative, 0.f, 1.f);
  2223.             DrainFocus(1);
  2224.             PauseFocusGain( true );
  2225.             AddTimer( 'ResumeFocusGain', 1.f );
  2226.             //theGame.witcherLog.AddMessage("Whirl damage reduction."); //modSigns: debug
  2227.         }
  2228.        
  2229.         //modSigns: cast quen on projectile ability, moved here
  2230.         if((!quen || !quen.IsAnyQuenActive()) && damageData.IsActionRanged() && !damageData.IsActionWitcherSign() && !damageData.IsDoTDamage() && !damageData.WasDodged())
  2231.         {
  2232.             chance = CalculateAttributeValue(GetAttributeValue('quen_chance_on_projectile'));
  2233.             if(chance > 0)
  2234.             {
  2235.                 chance = ClampF(chance, 0, 1);
  2236.                
  2237.                 if(RandF() < chance)
  2238.                 {
  2239.                     if(!quen)
  2240.                     {
  2241.                         quen = (W3QuenEntity)theGame.CreateEntity(signs[ST_Quen].template, GetWorldPosition(), GetWorldRotation() );
  2242.                     }
  2243.                     quen.Init(signOwner, signs[ST_Quen].entity, true );
  2244.                     quen.freeCast = true;
  2245.                     quen.OnStarted();
  2246.                     quen.OnThrowing();
  2247.                     quen.OnEnded();
  2248.                     if ( theGame.CanLog() )
  2249.                     {      
  2250.                         LogDMHits("W3PlayerWitcher.ReduceDamage: Processing Quen On Projectile armor ability...", damageData);
  2251.                     }
  2252.                     quen.OnTargetHit( damageData );
  2253.                     damageData.SetEndsQuen(true);
  2254.                 }
  2255.             }
  2256.         }
  2257.         //damage reduction from signs
  2258.         else if((quen && quen.IsAnyQuenActive()) && damageData.GetBuffSourceName() != "FallingDamage")
  2259.         {
  2260.             if ( theGame.CanLog() )
  2261.             {      
  2262.                 LogDMHits("W3PlayerWitcher.ReduceDamage: Processing Quen sign damage reduction...", damageData);
  2263.             }
  2264.             quen.OnTargetHit( damageData );
  2265.         }
  2266.        
  2267.         //modSigns: gryphon set tier 2 damage reduction - removed, adds resistances instead
  2268.         /*if( HasBuff( EET_GryphonSetBonusYrden ) )
  2269.         {
  2270.             min = GetAttributeValue( 'gryphon_set_bns_dmg_reduction' );
  2271.             damageData.processedDmg.vitalityDamage *= ClampF(1 - min.valueAdditive, 0, 1);
  2272.         }*/
  2273.        
  2274.        
  2275.         if(!damageData.GetIgnoreImmortalityMode())
  2276.         {
  2277.             if(!((W3PlayerWitcher)this))
  2278.                 Log("");
  2279.            
  2280.            
  2281.             if( IsInvulnerable() )
  2282.             {
  2283.                 if ( theGame.CanLog() )
  2284.                 {
  2285.                     LogDMHits("CActor.ReduceDamage: victim Invulnerable - no damage will be dealt", damageData );
  2286.                 }
  2287.                 damageData.SetAllProcessedDamageAs(0);
  2288.                 return;
  2289.             }
  2290.            
  2291.             if(actorAttacker && damageData.DealsAnyDamage() )
  2292.                 actorAttacker.SignalGameplayEventParamObject( 'DamageInstigated', damageData );
  2293.            
  2294.            
  2295.             if( IsImmortal() )
  2296.             {
  2297.                 if ( theGame.CanLog() )
  2298.                 {
  2299.                     LogDMHits("CActor.ReduceDamage: victim is Immortal, clamping damage", damageData );
  2300.                 }
  2301.                 damageData.processedDmg.vitalityDamage = ClampF(damageData.processedDmg.vitalityDamage, 0, GetStat(BCS_Vitality)-1 );
  2302.                 damageData.processedDmg.essenceDamage  = ClampF(damageData.processedDmg.essenceDamage, 0, GetStat(BCS_Essence)-1 );
  2303.                 return;
  2304.             }
  2305.         }
  2306.         else
  2307.         {
  2308.            
  2309.             if(actorAttacker && damageData.DealsAnyDamage() )
  2310.                 actorAttacker.SignalGameplayEventParamObject( 'DamageInstigated', damageData );
  2311.         }
  2312.     }
  2313.    
  2314.     /*timer function UndyingSkillCooldown(dt : float, id : int)
  2315.     {
  2316.         cannotUseUndyingSkill = false;
  2317.     }*/
  2318.    
  2319.     event OnTakeDamage( action : W3DamageAction)
  2320.     {
  2321.         var currVitality, rgnVitality, hpTriggerTreshold : float;
  2322.         var healingFactor : float;
  2323.         var abilityName : name;
  2324.         var abilityCount, maxStack, itemDurability : float;
  2325.         var addAbility : bool;
  2326.         var min, max : SAbilityAttributeValue;
  2327.         //var mutagenQuen : W3SignEntity; //modSigns
  2328.         var equipped : array<SItemUniqueId>;
  2329.         var i : int;
  2330.         var killSourceName : string;
  2331.         var aerondight  : W3Effect_Aerondight;
  2332.         var quen : W3QuenEntity; //modSigns
  2333.    
  2334.         currVitality = GetStat(BCS_Vitality);
  2335.        
  2336.        
  2337.         if(action.processedDmg.vitalityDamage >= currVitality)
  2338.         {
  2339.             killSourceName = action.GetBuffSourceName();
  2340.            
  2341.            
  2342.             if( killSourceName != "Quest" && killSourceName != "Kill Trigger" && killSourceName != "Trap" && killSourceName != "FallingDamage" )
  2343.             {          
  2344.                 //modSigns: Second Live mutation will now have priority over Undying skill
  2345.                 if( IsMutationActive( EPMT_Mutation11 ) && !HasBuff( EET_Mutation11Debuff ) && !IsInAir() )
  2346.                 {
  2347.                     theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation11', 'health_prc', min, max );
  2348.  
  2349.                     action.SetAllProcessedDamageAs( 0 );
  2350.                    
  2351.                     OnMutation11Triggered();                   
  2352.                 }
  2353.                 else if(/*!cannotUseUndyingSkill*/ !HasBuff( EET_UndyingSkillImmortal ) && !HasBuff( EET_UndyingSkillCooldown ) && GetStat(BCS_Focus) >= 1 && CanUseSkill(S_Sword_s18) /*&& HasBuff(EET_BattleTrance)*/ )
  2354.                 {
  2355.                     //healingFactor = CalculateAttributeValue( GetSkillAttributeValue(S_Sword_s18, 'healing_factor', false, true) );
  2356.                     //healingFactor *= GetStatMax(BCS_Vitality);
  2357.                     //healingFactor *= GetStat(BCS_Focus);
  2358.                     //healingFactor *= 1 + CalculateAttributeValue( GetSkillAttributeValue(S_Sword_s18, 'healing_bonus', false, true) ) * (GetSkillLevel(S_Sword_s18) - 1);
  2359.                     action.SetAllProcessedDamageAs( 0 ); //modSigns
  2360.                     ForceSetStat(BCS_Vitality, 1); //modSigns: heal 1 point of damage
  2361.                     //DrainFocus(GetStat(BCS_Focus));
  2362.                     //RemoveBuff(EET_BattleTrance);
  2363.                     //cannotUseUndyingSkill = true;
  2364.                     AddEffectDefault( EET_UndyingSkillImmortal, NULL, "UndyingSkill" ); //modSigns: brief immortality
  2365.                     //AddTimer('UndyingSkillCooldown', CalculateAttributeValue( GetSkillAttributeValue(S_Sword_s18, 'trigger_delay', false, true) ), false, , , true);
  2366.                 }
  2367.                 else
  2368.                 {
  2369.                    
  2370.                     equipped = GetEquippedItems();
  2371.                    
  2372.                     for(i=0; i<equipped.Size(); i+=1)
  2373.                     {
  2374.                         if ( !inv.IsIdValid( equipped[i] ) )
  2375.                         {
  2376.                             continue;
  2377.                         }
  2378.                         itemDurability = inv.GetItemDurability(equipped[i]);
  2379.                         if(inv.ItemHasAbility(equipped[i], 'MA_Reinforced') && itemDurability > 0)
  2380.                         {
  2381.                            
  2382.                             inv.SetItemDurabilityScript(equipped[i], MaxF(0, itemDurability - action.processedDmg.vitalityDamage) );
  2383.                            
  2384.                            
  2385.                             action.processedDmg.vitalityDamage = 0;
  2386.                             ForceSetStat(BCS_Vitality, 1);
  2387.                            
  2388.                             break;
  2389.                         }
  2390.                     }
  2391.                 }
  2392.             }
  2393.         }
  2394.        
  2395.        
  2396.         if(action.DealsAnyDamage() && !((W3Effect_Toxicity)action.causer) )
  2397.         {
  2398.             if(HasBuff(EET_Mutagen10))
  2399.                 RemoveAbilityAll( GetBuff(EET_Mutagen10).GetAbilityName() );
  2400.            
  2401.             if(HasBuff(EET_Mutagen15))
  2402.                 RemoveAbilityAll( GetBuff(EET_Mutagen15).GetAbilityName() );
  2403.         }
  2404.                
  2405.        
  2406.         quen = (W3QuenEntity)signs[ST_Quen].entity; //modSigns
  2407.         if(HasBuff(EET_Mutagen19) && (!quen || !quen.IsAnyQuenActive())) //modSigns
  2408.         {
  2409.             theGame.GetDefinitionsManager().GetAbilityAttributeValue(GetBuff(EET_Mutagen19).GetAbilityName(), 'max_hp_perc_trigger', min, max);
  2410.             hpTriggerTreshold = GetStatMax(BCS_Vitality) * CalculateAttributeValue(GetAttributeRandomizedValue(min, max));
  2411.            
  2412.             //theGame.witcherLog.AddMessage( "hpTriggerTreshold = " + hpTriggerTreshold );
  2413.             //theGame.witcherLog.AddMessage( "damage = " + action.GetDamageDealt() );
  2414.            
  2415.             if(action.GetDamageDealt() >= hpTriggerTreshold)
  2416.             {
  2417.                 if(!quen) //modSigns
  2418.                 {
  2419.                     quen = (W3QuenEntity)theGame.CreateEntity( signs[ST_Quen].template, GetWorldPosition(), GetWorldRotation() );
  2420.                 }
  2421.                 quen.Init( signOwner, signs[ST_Quen].entity, true );
  2422.                 quen.freeCast = true; //modSigns
  2423.                 quen.OnStarted();
  2424.                 quen.OnThrowing();
  2425.                 quen.OnEnded();
  2426.             }
  2427.         }
  2428.        
  2429.        
  2430.         if(action.DealsAnyDamage() && !action.IsDoTDamage() && HasBuff(EET_Mutagen27))
  2431.         {
  2432.             abilityName = GetBuff(EET_Mutagen27).GetAbilityName();
  2433.             abilityCount = GetAbilityCount(abilityName);
  2434.            
  2435.             if(abilityCount == 0)
  2436.             {
  2437.                 addAbility = true;
  2438.             }
  2439.             else
  2440.             {
  2441.                 theGame.GetDefinitionsManager().GetAbilityAttributeValue(abilityName, 'mutagen27_max_stack', min, max);
  2442.                 maxStack = CalculateAttributeValue(GetAttributeRandomizedValue(min, max));
  2443.                
  2444.                 if(maxStack >= 0)
  2445.                 {
  2446.                     addAbility = (abilityCount < maxStack);
  2447.                 }
  2448.                 else
  2449.                 {
  2450.                     addAbility = true;
  2451.                 }
  2452.             }
  2453.            
  2454.             if(addAbility)
  2455.             {
  2456.                 AddAbility(abilityName, true);
  2457.             }
  2458.         }
  2459.        
  2460.         if(HasBuff(EET_Trap) && !action.IsDoTDamage() && action.attacker.HasAbility( 'mon_dettlaff_monster_base' ))
  2461.         {
  2462.             action.AddEffectInfo(EET_Knockdown);
  2463.             RemoveBuff(EET_Trap, true);
  2464.         }      
  2465.        
  2466.         super.OnTakeDamage(action);
  2467.        
  2468.        
  2469.         if( !action.WasDodged() && action.DealtDamage() && inv.ItemHasTag( inv.GetCurrentlyHeldSword(), 'Aerondight' ) && !action.IsDoTDamage() && !( (W3Effect_Toxicity) action.causer ) )
  2470.         {
  2471.             aerondight = (W3Effect_Aerondight)GetBuff( EET_Aerondight );
  2472.             if( aerondight && aerondight.GetCurrentCount() != 0 )
  2473.             {
  2474.                 aerondight.ReduceAerondightStacks();
  2475.             }
  2476.         }
  2477.        
  2478.        
  2479.         if( !action.WasDodged() && action.DealtDamage() && !( (W3Effect_Toxicity) action.causer ) )
  2480.         {
  2481.             RemoveBuff( EET_Mutation3 );
  2482.         }
  2483.     }
  2484.    
  2485.    
  2486.    
  2487.    
  2488.    
  2489.    
  2490.    
  2491.     event OnStartFistfightMinigame()
  2492.     {
  2493.         var i : int;
  2494.         var buffs : array< CBaseGameplayEffect >;
  2495.        
  2496.        
  2497.         effectManager.RemoveAllPotionEffects();
  2498.        
  2499.         abilityManager.DrainToxicity(GetStatMax( BCS_Toxicity ));
  2500.        
  2501.         buffs = GetBuffs( EET_WellFed );
  2502.         for( i=buffs.Size()-1; i>=0; i-=1 )
  2503.         {
  2504.             RemoveEffect( buffs[i] );
  2505.         }
  2506.        
  2507.        
  2508.         buffs.Clear();
  2509.         buffs = GetBuffs( EET_WellHydrated );
  2510.         for( i=buffs.Size()-1; i>=0; i-=1 )
  2511.         {
  2512.             RemoveEffect( buffs[i] );
  2513.         }
  2514.        
  2515.         super.OnStartFistfightMinigame();
  2516.     }
  2517.    
  2518.     event OnEndFistfightMinigame()
  2519.     {
  2520.         super.OnEndFistfightMinigame();
  2521.     }
  2522.    
  2523.    
  2524.     public function GetCriticalHitChance( isLightAttack : bool, isHeavyAttack : bool, target : CActor, victimMonsterCategory : EMonsterCategory, isBolt : bool ) : float
  2525.     {
  2526.         var ret : float;
  2527.         var thunder : W3Potion_Thunderbolt;
  2528.         var min, max : SAbilityAttributeValue;
  2529.        
  2530.         ret = super.GetCriticalHitChance( isLightAttack, isHeavyAttack, target, victimMonsterCategory, isBolt );
  2531.        
  2532.        
  2533.        
  2534.        
  2535.        
  2536.        
  2537.        
  2538.         thunder = ( W3Potion_Thunderbolt )GetBuff( EET_Thunderbolt );
  2539.         if( thunder && thunder.GetBuffLevel() == 3 && GetCurWeather() == EWE_Storm )
  2540.         {
  2541.             ret += 1.0f;
  2542.         }
  2543.        
  2544.        
  2545.         if( isBolt && IsMutationActive( EPMT_Mutation9 ) )
  2546.         {
  2547.             theGame.GetDefinitionsManager().GetAbilityAttributeValue('Mutation9', 'critical_hit_chance', min, max);
  2548.             ret += min.valueMultiplicative;
  2549.         }
  2550.        
  2551.        
  2552.         if( isBolt && CanUseSkill( S_Sword_s07 ) )
  2553.         {
  2554.             ret += CalculateAttributeValue(GetSkillAttributeValue(S_Sword_s07, theGame.params.CRITICAL_HIT_CHANCE, false, true)) * GetSkillLevel(S_Sword_s07);
  2555.         }
  2556.            
  2557.         return ret;
  2558.     }
  2559.    
  2560.    
  2561.     public function GetCriticalHitDamageBonus(weaponId : SItemUniqueId, victimMonsterCategory : EMonsterCategory, isStrikeAtBack : bool) : SAbilityAttributeValue
  2562.     {
  2563.         var min, max, bonus, null, oilBonus : SAbilityAttributeValue;
  2564.         var mutagen : CBaseGameplayEffect;
  2565.         var monsterBonusType : name;
  2566.        
  2567.         bonus = super.GetCriticalHitDamageBonus(weaponId, victimMonsterCategory, isStrikeAtBack);
  2568.        
  2569.         if( inv.ItemHasActiveOilApplied( weaponId, victimMonsterCategory ) && GetStat( BCS_Focus ) >= 3 && CanUseSkill( S_Alchemy_s07 ) )
  2570.         {
  2571.             monsterBonusType = MonsterCategoryToAttackPowerBonus( victimMonsterCategory );
  2572.             oilBonus = inv.GetItemAttributeValue( weaponId, monsterBonusType );
  2573.             if(oilBonus != null)   
  2574.             {
  2575.                 //bonus += GetSkillAttributeValue(S_Alchemy_s07, theGame.params.CRITICAL_HIT_DAMAGE_BONUS, false, true);
  2576.                 //modSigns: fix crit bonus
  2577.                 bonus += GetSkillAttributeValue(S_Alchemy_s07, theGame.params.CRITICAL_HIT_DAMAGE_BONUS, false, false) * GetSkillLevel(S_Alchemy_s07);
  2578.             }
  2579.             //combat log
  2580.             //theGame.witcherLog.AddCombatMessage("Crit dmg bonus: " + FloatToString(bonus.valueAdditive), thePlayer, NULL);
  2581.         }
  2582.        
  2583.         // Mutagen 11 - back strike bonus
  2584.         if (isStrikeAtBack && HasBuff(EET_Mutagen11))
  2585.         {
  2586.             mutagen = GetBuff(EET_Mutagen11);
  2587.             theGame.GetDefinitionsManager().GetAbilityAttributeValue(mutagen.GetAbilityName(), 'damageIncrease', min, max);
  2588.             bonus += GetAttributeRandomizedValue(min, max);
  2589.         }
  2590.            
  2591.         return bonus;      
  2592.     }
  2593.    
  2594.     public function ProcessLockTarget( optional newLockTarget : CActor, optional checkLeftStickHeading : bool ) : bool
  2595.     {
  2596.         var newLockTargetFound  : bool;
  2597.    
  2598.         newLockTargetFound = super.ProcessLockTarget(newLockTarget, checkLeftStickHeading);
  2599.        
  2600.         if(GetCurrentlyCastSign() == ST_Axii)
  2601.         {
  2602.             ((W3AxiiEntity)GetCurrentSignEntity()).OnDisplayTargetChange(newLockTarget);
  2603.         }
  2604.        
  2605.         return newLockTargetFound;
  2606.     }
  2607.    
  2608.    
  2609.    
  2610.    
  2611.    
  2612.    
  2613.    
  2614.      event OnProcessActionPost(action : W3DamageAction)
  2615.     {
  2616.         var attackAction : W3Action_Attack;
  2617.         var rendLoad, focusVal : float; //modSigns
  2618.         var value : SAbilityAttributeValue;
  2619.         var actorVictim : CActor;
  2620.         var weaponId : SItemUniqueId;
  2621.         var usesSteel, usesSilver, usesVitality, usesEssence : bool;
  2622.         var abs : array<name>;
  2623.         var i : int;
  2624.         var dm : CDefinitionsManagerAccessor;
  2625.         var items : array<SItemUniqueId>;
  2626.         var weaponEnt : CEntity;
  2627.         //var lynxSetBuff : W3Effect_LynxSetBonus; //modSigns
  2628.         var min, max, nullBonus, oilBonus : SAbilityAttributeValue; //modSigns
  2629.         var victimMonsterCategory : EMonsterCategory; //modSigns
  2630.         var monsterBonusType : name; //modSigns
  2631.         var tmpName : name; //modSigns
  2632.         var tmpBool : bool; //modSigns
  2633.        
  2634.         super.OnProcessActionPost(action);
  2635.        
  2636.         attackAction = (W3Action_Attack)action;
  2637.         actorVictim = (CActor)action.victim;
  2638.        
  2639.         if(attackAction)
  2640.         {
  2641.             if(attackAction.IsActionMelee())
  2642.             {
  2643.                
  2644.                 if(SkillNameToEnum(attackAction.GetAttackTypeName()) == S_Sword_s02)
  2645.                 {
  2646.                     //rendLoad = GetSpecialAttackTimeRatio();
  2647.                    
  2648.                    
  2649.                     //rendLoad = MinF(rendLoad * GetStatMax(BCS_Focus), GetStat(BCS_Focus));
  2650.                    
  2651.                    
  2652.                     //rendLoad = FloorF(rendLoad);                 
  2653.                    
  2654.                     //modSigns
  2655.                     rendLoad = GetSpecialAttackTimeRatio() * GetStat(BCS_Focus);
  2656.  
  2657.                     DrainFocus(rendLoad);
  2658.                    
  2659.                     OnSpecialAttackHeavyActionProcess();
  2660.                 }
  2661.                 else if(actorVictim && IsRequiredAttitudeBetween(this, actorVictim, true))
  2662.                 {
  2663.                    
  2664.                    
  2665.                     value = GetAttributeValue('focus_gain');
  2666.                    
  2667.                     if( FactsQuerySum("debug_fact_focus_boy") > 0 )
  2668.                     {
  2669.                         Debug_FocusBoyFocusGain();
  2670.                     }
  2671.                    
  2672.                    
  2673.                     if ( CanUseSkill(S_Sword_s20) )
  2674.                     {
  2675.                         value += GetSkillAttributeValue(S_Sword_s20, 'focus_gain', false, true) * GetSkillLevel(S_Sword_s20);
  2676.                     }
  2677.                    
  2678.                    
  2679.                     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() )
  2680.                     {
  2681.                         AddEffectDefault( EET_Mutation3, this, "", false );
  2682.                     }
  2683.                    
  2684.                     focusVal = 0.1f * (1 + CalculateAttributeValue(value));
  2685.                    
  2686.                     if(attackAction.DealtDamage() && !inv.IsItemFists( attackAction.GetWeaponId() ) && !attackAction.WasDodged() && !attackAction.IsParried() && !attackAction.IsCountered()) //modSigns
  2687.                     {
  2688.                         //modSigns: lynx set tier 2 bonus - doubled adrenaline gain for critical hits
  2689.                         if( attackAction.IsCriticalHit() && IsSetBonusActive( EISB_Lynx_2 ) )
  2690.                         {
  2691.                             focusVal *= 2;
  2692.                         }
  2693.                        
  2694.                         //modSigns: additional adrenaline for bear school perk
  2695.                         focusVal += CalculateAttributeValue(GetAttributeValue('bonus_focus_gain'));
  2696.                     }
  2697.                    
  2698.                     GainStat(BCS_Focus, focusVal);
  2699.                 }
  2700.                
  2701.                
  2702.                 weaponId = attackAction.GetWeaponId();
  2703.                 if(actorVictim && (ShouldProcessTutorial('TutorialWrongSwordSteel') || ShouldProcessTutorial('TutorialWrongSwordSilver')) && GetAttitudeBetween(actorVictim, this) == AIA_Hostile)
  2704.                 {
  2705.                     usesSteel = inv.IsItemSteelSwordUsableByPlayer(weaponId);
  2706.                     usesSilver = inv.IsItemSilverSwordUsableByPlayer(weaponId);
  2707.                     usesVitality = actorVictim.UsesVitality();
  2708.                     usesEssence = actorVictim.UsesEssence();
  2709.                    
  2710.                     if(usesSilver && usesVitality)
  2711.                     {
  2712.                         FactsAdd('tut_wrong_sword_silver',1);
  2713.                     }
  2714.                     else if(usesSteel && usesEssence)
  2715.                     {
  2716.                         FactsAdd('tut_wrong_sword_steel',1);
  2717.                     }
  2718.                     else if(FactsQuerySum('tut_wrong_sword_steel') && usesSilver && usesEssence)
  2719.                     {
  2720.                         FactsAdd('tut_proper_sword_silver',1);
  2721.                         FactsRemove('tut_wrong_sword_steel');
  2722.                     }
  2723.                     else if(FactsQuerySum('tut_wrong_sword_silver') && usesSteel && usesVitality)
  2724.                     {
  2725.                         FactsAdd('tut_proper_sword_steel',1);
  2726.                         FactsRemove('tut_wrong_sword_silver');
  2727.                     }
  2728.                 }
  2729.                
  2730.                
  2731.                 if(!action.WasDodged() && HasRunewordActive('Runeword 1 _Stats')) //modSigns
  2732.                 {
  2733.                     if(runewordInfusionType == ST_Axii)
  2734.                     {
  2735.                         actorVictim.SoundEvent('sign_axii_release');
  2736.                     }
  2737.                     else if(runewordInfusionType == ST_Igni)
  2738.                     {
  2739.                         actorVictim.SoundEvent('sign_igni_charge_begin');
  2740.                     }
  2741.                     else if(runewordInfusionType == ST_Quen)
  2742.                     {
  2743.                         value = GetAttributeValue('runeword1_quen_heal');
  2744.                         Heal( action.GetDamageDealt() * value.valueMultiplicative );
  2745.                         PlayEffectSingle('drain_energy_caretaker_shovel');
  2746.                     }
  2747.                     else if(runewordInfusionType == ST_Yrden)
  2748.                     {
  2749.                         actorVictim.SoundEvent('sign_yrden_shock_activate');
  2750.                     }
  2751.                     runewordInfusionType = ST_None;
  2752.                    
  2753.                    
  2754.                     items = inv.GetHeldWeapons();
  2755.                     weaponEnt = inv.GetItemEntityUnsafe(items[0]);
  2756.                     weaponEnt.StopEffect('runeword_aard');
  2757.                     weaponEnt.StopEffect('runeword_axii');
  2758.                     weaponEnt.StopEffect('runeword_igni');
  2759.                     weaponEnt.StopEffect('runeword_quen');
  2760.                     weaponEnt.StopEffect('runeword_yrden');
  2761.                 }
  2762.                
  2763.                
  2764.                 if(ShouldProcessTutorial('TutorialLightAttacks') || ShouldProcessTutorial('TutorialHeavyAttacks'))
  2765.                 {
  2766.                     if(IsLightAttack(attackAction.GetAttackName()))
  2767.                     {
  2768.                         theGame.GetTutorialSystem().IncreaseGeraltsLightAttacksCount(action.victim.GetTags());
  2769.                     }
  2770.                     else if(IsHeavyAttack(attackAction.GetAttackName()))
  2771.                     {
  2772.                         theGame.GetTutorialSystem().IncreaseGeraltsHeavyAttacksCount(action.victim.GetTags());
  2773.                     }
  2774.                 }
  2775.             }
  2776.             else if(attackAction.IsActionRanged())
  2777.             {
  2778.                
  2779.                 if(CanUseSkill(S_Sword_s15))
  2780.                 {              
  2781.                     value = GetSkillAttributeValue(S_Sword_s15, 'focus_gain', false, true) * GetSkillLevel(S_Sword_s15) ;
  2782.                     GainStat(BCS_Focus, CalculateAttributeValue(value) );
  2783.                 }
  2784.                
  2785.                
  2786.                 if(CanUseSkill(S_Sword_s12) && attackAction.IsCriticalHit() && actorVictim)
  2787.                 {
  2788.                    
  2789.                     actorVictim.GetCharacterStats().GetAbilities(abs, false);
  2790.                     dm = theGame.GetDefinitionsManager();
  2791.                     for(i=abs.Size()-1; i>=0; i-=1)
  2792.                     {
  2793.                         if(!dm.AbilityHasTag(abs[i], theGame.params.TAG_MONSTER_SKILL) || actorVictim.IsAbilityBlocked(abs[i]))
  2794.                         {
  2795.                             abs.EraseFast(i);
  2796.                         }
  2797.                     }
  2798.                    
  2799.                    
  2800.                     if(abs.Size() > 0)
  2801.                     {
  2802.                         value = GetSkillAttributeValue(S_Sword_s12, 'duration', true, true) * GetSkillLevel(S_Sword_s12);
  2803.                         actorVictim.BlockAbility(abs[ RandRange(abs.Size()) ], true, CalculateAttributeValue(value));
  2804.                     }
  2805.                 }
  2806.             }
  2807.         }
  2808.        
  2809.        
  2810.         if( IsMutationActive( EPMT_Mutation10 ) && ( action.IsActionMelee() || action.IsActionWitcherSign() ) )
  2811.         {
  2812.             PlayEffect( 'mutation_10_energy' );
  2813.         }
  2814.        
  2815.        
  2816.         if(CanUseSkill(S_Perk_18) && ((W3Petard)action.causer) && action.DealsAnyDamage() && !action.IsDoTDamage())
  2817.         {
  2818.             value = GetSkillAttributeValue(S_Perk_18, 'focus_gain', false, true);
  2819.             GainStat(BCS_Focus, CalculateAttributeValue(value));
  2820.         }      
  2821.        
  2822.        
  2823.         //modSigns: light attacks boosts heavy attacks and vice versa - lynx set bonus 1
  2824.         if( !HasBuff( EET_LynxSetBonus ) && IsSetBonusActive( EISB_Lynx_1 ) && attackAction && attackAction.IsActionMelee() && !IsUsingHorse() && attackAction.DealtDamage() && !attackAction.WasDodged() && !attackAction.IsParried() && !attackAction.IsCountered() && ( inv.IsItemSteelSwordUsableByPlayer( attackAction.GetWeaponId() ) || inv.IsItemSilverSwordUsableByPlayer( attackAction.GetWeaponId() ) ) )
  2825.         {
  2826.             //lynxSetBuff = (W3Effect_LynxSetBonus)GetBuff( EET_LynxSetBonus );
  2827.             if( IsHeavyAttack( attackAction.GetAttackName() ) )
  2828.             {
  2829.                 /*if( lynxSetBuff && lynxSetBuff.GetSourceName() == "LightAttack" )
  2830.                 {
  2831.                     RemoveEffect( lynxSetBuff );
  2832.                 }*/
  2833.                 AddEffectDefault( EET_LynxSetBonus, NULL, "HeavyAttack" );
  2834.             }
  2835.             else
  2836.             {
  2837.                 /*if( lynxSetBuff && lynxSetBuff.GetSourceName() == "HeavyAttack" )
  2838.                 {
  2839.                     RemoveEffect( lynxSetBuff );
  2840.                 }*/
  2841.                 AddEffectDefault( EET_LynxSetBonus, NULL, "LightAttack" );
  2842.             }
  2843.             SoundEvent( "ep2_setskill_lynx_activate" );
  2844.         }      
  2845.        
  2846.         //modSigns: move PhantomWeapon charging here
  2847.         if( attackAction && attackAction.IsActionMelee() && inv.ItemHasTag( attackAction.GetWeaponId(), 'PhantomWeapon' )
  2848.             && IsLightAttack( attackAction.GetAttackName() ) && !IsUsingHorse()
  2849.             && attackAction.DealtDamage() && !attackAction.WasDodged() && !attackAction.IsParried() && !attackAction.IsCountered() )
  2850.         {
  2851.             GetPhantomWeaponMgr().IncrementHitCounter();
  2852.         }
  2853.     }
  2854.    
  2855.    
  2856.     timer function Mutagen14Timer(dt : float, id : int)
  2857.     {
  2858.         var abilityName : name;
  2859.         var abilityCount, maxStack : float;
  2860.         var min, max : SAbilityAttributeValue;
  2861.         var addAbility : bool;
  2862.        
  2863.         abilityName = GetBuff(EET_Mutagen14).GetAbilityName();
  2864.         abilityCount = GetAbilityCount(abilityName);
  2865.        
  2866.         if(abilityCount == 0)
  2867.         {
  2868.             addAbility = true;
  2869.         }
  2870.         else
  2871.         {
  2872.             theGame.GetDefinitionsManager().GetAbilityAttributeValue(abilityName, 'mutagen14_max_stack', min, max);
  2873.             maxStack = CalculateAttributeValue(GetAttributeRandomizedValue(min, max));
  2874.            
  2875.             if(maxStack >= 0)
  2876.             {
  2877.                 addAbility = (abilityCount < maxStack);
  2878.             }
  2879.             else
  2880.             {
  2881.                 addAbility = true;
  2882.             }
  2883.         }
  2884.        
  2885.         if(addAbility)
  2886.         {
  2887.             AddAbility(abilityName, true);
  2888.         }
  2889.         else
  2890.         {
  2891.            
  2892.             RemoveTimer('Mutagen14Timer');
  2893.         }
  2894.     }
  2895.    
  2896.     public final function FailFundamentalsFirstAchievementCondition()
  2897.     {
  2898.         SetFailedFundamentalsFirstAchievementCondition(true);
  2899.     }
  2900.        
  2901.     public final function SetUsedQuenInCombat()
  2902.     {
  2903.         usedQuenInCombat = true;
  2904.     }
  2905.    
  2906.     public final function UsedQuenInCombat() : bool
  2907.     {
  2908.         return usedQuenInCombat;
  2909.     }
  2910.    
  2911.     event OnCombatStart()
  2912.     {
  2913.         var quenEntity/*, glyphQuen*/ : W3QuenEntity; //modSigns
  2914.         var focus, stamina : float;
  2915.         var glowTargets, moTargets, actors : array< CActor >;
  2916.         var delays : array< float >;
  2917.         var rand, i : int;
  2918.         var isHostile, isAlive, isUnconscious : bool;
  2919.        
  2920.         super.OnCombatStart();
  2921.        
  2922.         if ( IsInCombatActionFriendly() )
  2923.         {
  2924.             SetBIsCombatActionAllowed(true);
  2925.             SetBIsInputAllowed(true, 'OnCombatActionStart' );
  2926.         }
  2927.        
  2928.        
  2929.         if(HasBuff(EET_Mutagen14))
  2930.         {
  2931.             AddTimer('Mutagen14Timer', 2, true);
  2932.         }
  2933.        
  2934.        
  2935.         if(HasBuff(EET_Mutagen15))
  2936.         {
  2937.             AddAbility(GetBuff(EET_Mutagen15).GetAbilityName(), false);
  2938.         }
  2939.        
  2940.         //modSigns
  2941.         if( IsSetBonusActive(EISB_KaerMorhen) && !HasBuff(EET_KaerMorhenSetBonus) )
  2942.         {
  2943.             AddEffectDefault(EET_KaerMorhenSetBonus, this, "KaerMorhenSetBonus");
  2944.         }
  2945.        
  2946.        
  2947.         mutation12IsOnCooldown = false;
  2948.        
  2949.        
  2950.         quenEntity = (W3QuenEntity)signs[ST_Quen].entity;      
  2951.        
  2952.        
  2953.         if(quenEntity)
  2954.         {
  2955.             usedQuenInCombat = quenEntity.IsAnyQuenActive();
  2956.         }
  2957.         else
  2958.         {
  2959.             usedQuenInCombat = false;
  2960.         }
  2961.        
  2962.         if(usedQuenInCombat || HasPotionBuff() || IsEquippedSwordUpgradedWithOil(true) || IsEquippedSwordUpgradedWithOil(false))
  2963.         {
  2964.             SetFailedFundamentalsFirstAchievementCondition(true);
  2965.         }
  2966.         else
  2967.         {
  2968.             if(IsAnyItemEquippedOnSlot(EES_PotionMutagen1) || IsAnyItemEquippedOnSlot(EES_PotionMutagen2) || IsAnyItemEquippedOnSlot(EES_PotionMutagen3) || IsAnyItemEquippedOnSlot(EES_PotionMutagen4))
  2969.                 SetFailedFundamentalsFirstAchievementCondition(true);
  2970.             else
  2971.                 SetFailedFundamentalsFirstAchievementCondition(false);
  2972.         }
  2973.        
  2974.         if(CanUseSkill(S_Sword_s20) && IsThreatened())
  2975.         {
  2976.             focus = GetStat(BCS_Focus);
  2977.             if(focus < 1)
  2978.             {
  2979.                 GainStat(BCS_Focus, 1 - focus);
  2980.             }
  2981.         }
  2982.  
  2983.         if ( HasGlyphwordActive('Glyphword 17 _Stats') && (!quenEntity || !quenEntity.IsAnyQuenActive()) && RandF() < CalculateAttributeValue(GetAttributeValue('quen_apply_chance')) ) //modSigns
  2984.         {
  2985.             //stamina = GetStat(BCS_Stamina); //modSigns
  2986.             if(!quenEntity)
  2987.             {
  2988.                 quenEntity = (W3QuenEntity)theGame.CreateEntity( signs[ST_Quen].template, GetWorldPosition(), GetWorldRotation() );
  2989.             }
  2990.             quenEntity.Init( signOwner, signs[ST_Quen].entity, true );
  2991.             quenEntity.freeCast = true; //modSigns
  2992.             quenEntity.OnStarted();
  2993.             quenEntity.OnThrowing();
  2994.             quenEntity.OnEnded();
  2995.             //ForceSetStat(BCS_Stamina, stamina); //modSigns
  2996.         }
  2997.        
  2998.        
  2999.         MeditationForceAbort(true);
  3000.        
  3001.        
  3002.        
  3003.  
  3004.        
  3005.         if( IsMutationActive( EPMT_Mutation4 ) )
  3006.         {
  3007.             AddEffectDefault( EET_Mutation4, this, "combat start", false );
  3008.         }
  3009.         else if( IsMutationActive( EPMT_Mutation5 ) && GetStat( BCS_Focus ) >= 1.f )
  3010.         {
  3011.             AddEffectDefault( EET_Mutation5, this, "", false );
  3012.         }
  3013.        
  3014.         else if( IsMutationActive( EPMT_Mutation7 ) )
  3015.         {
  3016.            
  3017.                
  3018.                 RemoveTimer( 'Mutation7CombatStartHackFixGo' );
  3019.                
  3020.                
  3021.                 AddTimer( 'Mutation7CombatStartHackFix', 1.f, true, , , , true );
  3022.            
  3023.         }
  3024.         else if( IsMutationActive( EPMT_Mutation8 ) )
  3025.         {
  3026.             theGame.MutationHUDFeedback( MFT_PlayRepeat );
  3027.         }
  3028.        
  3029.         else if( IsMutationActive( EPMT_Mutation10 ) )
  3030.         {
  3031.             /*if( !HasBuff( EET_Mutation10 ) && GetStat( BCS_Toxicity ) > 0.f )
  3032.             {
  3033.                 AddEffectDefault( EET_Mutation10, this, "Mutation 10" );
  3034.             }*/
  3035.            
  3036.            
  3037.             PlayEffect( 'mutation_10' );
  3038.            
  3039.            
  3040.             PlayEffect( 'critical_toxicity' );
  3041.             AddTimer( 'Mutation10StopEffect', 5.f );
  3042.             //modSigns
  3043.             if( !HasBuff( EET_Mutation10 ) )
  3044.             {
  3045.                 AddEffectDefault( EET_Mutation10, NULL, "Mutation 10" );
  3046.             }
  3047.         }
  3048.     }
  3049.    
  3050.     timer function Mutation7CombatStartHackFix( dt : float, id : int )
  3051.     {
  3052.         var actors : array< CActor >;
  3053.        
  3054.         actors = GetEnemies();
  3055.        
  3056.         if( actors.Size() > 0 )
  3057.         {
  3058.            
  3059.             AddTimer( 'Mutation7CombatStartHackFixGo', 0.5f );
  3060.             RemoveTimer( 'Mutation7CombatStartHackFix' );
  3061.         }
  3062.     }
  3063.    
  3064.     timer function Mutation7CombatStartHackFixGo( dt : float, id : int )
  3065.     {
  3066.         var actors : array< CActor >;
  3067.        
  3068.         if( IsMutationActive( EPMT_Mutation7 ) )
  3069.         {
  3070.             actors = GetEnemies();
  3071.            
  3072.             if( actors.Size() > 1 )
  3073.             {      
  3074.                 AddEffectDefault( EET_Mutation7Buff, this, "Mutation 7, combat start" );           
  3075.             }
  3076.         }
  3077.     }
  3078.    
  3079.     public final function IsInFistFight() : bool
  3080.     {
  3081.         var enemies : array< CActor >;
  3082.         var i, j : int;
  3083.         var invent : CInventoryComponent;
  3084.         var weapons : array< SItemUniqueId >;
  3085.        
  3086.         if( IsInFistFightMiniGame() )
  3087.         {
  3088.             return true;
  3089.         }
  3090.        
  3091.         enemies = GetEnemies();
  3092.         for( i=0; i<enemies.Size(); i+=1 )
  3093.         {
  3094.             weapons.Clear();
  3095.             invent = enemies[i].GetInventory();
  3096.             weapons = invent.GetHeldWeapons();
  3097.            
  3098.             for( j=0; j<weapons.Size(); j+=1 )
  3099.             {
  3100.                 if( invent.IsItemFists( weapons[j] ) )
  3101.                 {
  3102.                     return true;
  3103.                 }
  3104.             }
  3105.         }
  3106.        
  3107.         return false;
  3108.     }
  3109.    
  3110.     timer function Mutation10StopEffect( dt : float, id : int )
  3111.     {
  3112.         StopEffect( 'critical_toxicity' );
  3113.     }
  3114.    
  3115.    
  3116.     event OnCombatFinished()
  3117.     {
  3118.         var mut17 : W3Mutagen17_Effect;
  3119.         var inGameConfigWrapper : CInGameConfigWrapper;
  3120.         var disableAutoSheathe : bool;
  3121.        
  3122.         super.OnCombatFinished();
  3123.        
  3124.        
  3125.         if(HasBuff(EET_Mutagen10))
  3126.         {
  3127.             RemoveAbilityAll( GetBuff(EET_Mutagen10).GetAbilityName() );
  3128.         }
  3129.        
  3130.        
  3131.         if(HasBuff(EET_Mutagen14))
  3132.         {
  3133.             RemoveAbilityAll( GetBuff(EET_Mutagen14).GetAbilityName() );
  3134.         }
  3135.        
  3136.        
  3137.         if(HasBuff(EET_Mutagen15))
  3138.         {
  3139.             RemoveAbilityAll( GetBuff(EET_Mutagen15).GetAbilityName() );
  3140.         }
  3141.        
  3142.        
  3143.         if(HasBuff(EET_Mutagen17))
  3144.         {
  3145.             mut17 = (W3Mutagen17_Effect)GetBuff(EET_Mutagen17);
  3146.             mut17.ClearBoost();
  3147.         }
  3148.        
  3149.        
  3150.         if(HasBuff(EET_Mutagen18))
  3151.         {
  3152.             RemoveAbilityAll( GetBuff(EET_Mutagen18).GetAbilityName() );
  3153.         }
  3154.        
  3155.        
  3156.         if(HasBuff(EET_Mutagen22))
  3157.         {
  3158.             RemoveAbilityAll( GetBuff(EET_Mutagen22).GetAbilityName() );
  3159.         }
  3160.        
  3161.        
  3162.         if(HasBuff(EET_Mutagen27))
  3163.         {
  3164.             RemoveAbilityAll( GetBuff(EET_Mutagen27).GetAbilityName() );
  3165.         }
  3166.        
  3167.        
  3168.         RemoveBuff( EET_Mutation3 );
  3169.        
  3170.        
  3171.         RemoveBuff( EET_Mutation4 );
  3172.        
  3173.        
  3174.         RemoveBuff( EET_Mutation5 );
  3175.        
  3176.        
  3177.         RemoveBuff( EET_Mutation7Buff );
  3178.         RemoveBuff( EET_Mutation7Debuff );
  3179.            
  3180.         if( IsMutationActive( EPMT_Mutation7 ) )
  3181.         {
  3182.             theGame.MutationHUDFeedback( MFT_PlayHide );
  3183.         }
  3184.         else if( IsMutationActive( EPMT_Mutation8 ) )
  3185.         {
  3186.             theGame.MutationHUDFeedback( MFT_PlayHide );
  3187.         }
  3188.        
  3189.        
  3190.         RemoveBuff( EET_Mutation10 );
  3191.        
  3192.        
  3193.         RemoveBuff( EET_LynxSetBonus );
  3194.        
  3195.         //modSigns
  3196.         RemoveBuff(EET_KaerMorhenSetBonus);
  3197.        
  3198.        
  3199.         if(GetStat(BCS_Focus) > 0)
  3200.         {
  3201.             AddTimer('DelayedAdrenalineDrain', theGame.params.ADRENALINE_DRAIN_AFTER_COMBAT_DELAY, , , , true);
  3202.         }
  3203.        
  3204.        
  3205.         thePlayer.abilityManager.ResetOverhealBonus();
  3206.        
  3207.         usedQuenInCombat = false;      
  3208.        
  3209.         theGame.GetGamerProfile().ResetStat(ES_FinesseKills);
  3210.        
  3211.         LogChannel( 'OnCombatFinished', "OnCombatFinished: DelayedSheathSword timer added" );
  3212.        
  3213.         inGameConfigWrapper = (CInGameConfigWrapper)theGame.GetInGameConfigWrapper();
  3214.         disableAutoSheathe = inGameConfigWrapper.GetVarValue( 'Gameplay', 'DisableAutomaticSwordSheathe' );        
  3215.         if( !disableAutoSheathe )
  3216.         {
  3217.             if ( ShouldAutoSheathSwordInstantly() )
  3218.                 AddTimer( 'DelayedSheathSword', 0.5f );
  3219.             else
  3220.                 AddTimer( 'DelayedSheathSword', 2.f );
  3221.         }
  3222.        
  3223.         OnBlockAllCombatTickets( false );
  3224.        
  3225.        
  3226.         runewordInfusionType = ST_None;
  3227.        
  3228.        
  3229.        
  3230.        
  3231.        
  3232.     }
  3233.    
  3234.     public function PlayHitEffect( damageAction : W3DamageAction )
  3235.     {
  3236.         var hitReactionType     : EHitReactionType;
  3237.         var isAtBack            : bool;
  3238.        
  3239.        
  3240.         if( damageAction.GetMutation4Triggered() )
  3241.         {
  3242.             hitReactionType = damageAction.GetHitReactionType();
  3243.             isAtBack = IsAttackerAtBack( damageAction.attacker );
  3244.            
  3245.             if( hitReactionType != EHRT_Heavy )
  3246.             {
  3247.                 if( isAtBack )
  3248.                 {
  3249.                     damageAction.SetHitEffect( 'light_hit_back_toxic', true );                 
  3250.                 }
  3251.                 else
  3252.                 {
  3253.                     damageAction.SetHitEffect( 'light_hit_toxic' );
  3254.                 }
  3255.             }
  3256.             else
  3257.             {
  3258.                 if( isAtBack )
  3259.                 {
  3260.                     damageAction.SetHitEffect( 'heavy_hit_back_toxic' ,true );
  3261.                 }
  3262.                 else
  3263.                 {
  3264.                     damageAction.SetHitEffect( 'heavy_hit_toxic' );
  3265.                 }
  3266.             }
  3267.         }
  3268.        
  3269.         super.PlayHitEffect( damageAction );
  3270.     }
  3271.    
  3272.     timer function DelayedAdrenalineDrain(dt : float, id : int)
  3273.     {
  3274.         if ( !HasBuff(EET_Runeword8) )
  3275.             AddEffectDefault(EET_AdrenalineDrain, this, "after_combat_adrenaline_drain");
  3276.     }
  3277.    
  3278.    
  3279.     protected function Attack( hitTarget : CGameplayEntity, animData : CPreAttackEventData, weaponId : SItemUniqueId, parried : bool, countered : bool, parriedBy : array<CActor>, attackAnimationName : name, hitTime : float, weaponEntity : CItemEntity)
  3280.     {
  3281.         var mutagen17 : W3Mutagen17_Effect;
  3282.        
  3283.         //modSigns: check for mutagen17 activation
  3284.         if(HasBuff(EET_Mutagen17))
  3285.         {
  3286.             mutagen17 = (W3Mutagen17_Effect)GetBuff(EET_Mutagen17);
  3287.             if(mutagen17.IsBoostAvailable())
  3288.             {
  3289.                 mutagen17.ActivateBoost();
  3290.                 //theGame.witcherLog.AddMessage("mutagen17 boost activated: attack"); //modSigns: debug
  3291.             }
  3292.         }
  3293.        
  3294.         super.Attack(hitTarget, animData, weaponId, parried, countered, parriedBy, attackAnimationName, hitTime, weaponEntity);
  3295.        
  3296.         /*if( (CActor)hitTarget && HasBuff(EET_Mutagen17) )
  3297.         {
  3298.             mutagen17 = (W3Mutagen17_Effect)GetBuff(EET_Mutagen17);
  3299.             if(mutagen17.HasBoost())
  3300.             {
  3301.                 mutagen17.ClearBoost();
  3302.             }
  3303.         }*/ //modSigns: move to other place
  3304.     }
  3305.    
  3306.     //modSigns: redone completely
  3307.     public final timer function SpecialAttackLightSustainCost(dt : float, id : int)
  3308.     {
  3309.         if(abilityManager && abilityManager.IsInitialized() && IsAlive() && HasResourcesForWhirl(dt))
  3310.         {
  3311.             PauseStaminaRegen('WhirlSkill');
  3312.             WhirlDrainResources(dt);
  3313.         }
  3314.         else
  3315.         {
  3316.             OnPerformSpecialAttack(true, false);
  3317.         }
  3318.         /*var focusPerSec, cost, delay : float;
  3319.         var reduction : SAbilityAttributeValue;
  3320.         var skillLevel : int;
  3321.        
  3322.         if(abilityManager && abilityManager.IsInitialized() && IsAlive())
  3323.         {
  3324.             PauseStaminaRegen('WhirlSkill');
  3325.            
  3326.             if(GetStat(BCS_Stamina) > 0)
  3327.             {
  3328.                 cost = GetStaminaActionCost(ESAT_Ability, GetSkillAbilityName(S_Sword_s01), dt);
  3329.                 delay = GetStaminaActionDelay(ESAT_Ability, GetSkillAbilityName(S_Sword_s01), dt);
  3330.                 skillLevel = GetSkillLevel(S_Sword_s01);
  3331.                
  3332.                 if(skillLevel > 1)
  3333.                 {
  3334.                     reduction = GetSkillAttributeValue(S_Sword_s01, 'cost_reduction', false, true) * (skillLevel - 1);
  3335.                     cost = MaxF(0, cost * (1 - reduction.valueMultiplicative) - reduction.valueAdditive);
  3336.                 }
  3337.                
  3338.                 DrainStamina(ESAT_FixedValue, cost, delay, GetSkillAbilityName(S_Sword_s01));
  3339.             }
  3340.             else               
  3341.             {              
  3342.                 GetSkillAttributeValue(S_Sword_s01, 'focus_cost_per_sec', false, true);
  3343.                 focusPerSec = GetWhirlFocusCostPerSec();
  3344.                 DrainFocus(focusPerSec * dt);
  3345.             }
  3346.         }
  3347.        
  3348.         if(GetStat(BCS_Stamina) <= 0 && GetStat(BCS_Focus) <= 0)
  3349.         {
  3350.             OnPerformSpecialAttack(true, false);
  3351.         }*/
  3352.     }
  3353.    
  3354.     /*public final function GetWhirlFocusCostPerSec() : float
  3355.     {
  3356.         var ability : SAbilityAttributeValue;
  3357.         var val : float;
  3358.         var skillLevel : int;
  3359.        
  3360.         ability = GetSkillAttributeValue(S_Sword_s01, 'focus_cost_per_sec_initial', false, false);
  3361.         skillLevel = GetSkillLevel(S_Sword_s01);
  3362.        
  3363.         if(skillLevel > 1)
  3364.             ability -= GetSkillAttributeValue(S_Sword_s01, 'cost_reduction', false, false) * (skillLevel-1);
  3365.            
  3366.         val = CalculateAttributeValue(ability);
  3367.        
  3368.         return val;
  3369.     }*/ //modSigns: redone
  3370.    
  3371.     //modSigns
  3372.     public final function HasResourcesForWhirl(dt : float) : bool
  3373.     {
  3374.         return GetStat(BCS_Stamina) >= GetWhirlStaminaCost(dt);
  3375.     }
  3376.    
  3377.     public final function GetWhirlStaminaCost(dt : float) : float
  3378.     {
  3379.         var cost : float;
  3380.         cost = GetStaminaActionCost(ESAT_Ability, GetSkillAbilityName(S_Sword_s01), dt);
  3381.         cost *= 1 - CalculateAttributeValue(GetSkillAttributeValue(S_Sword_s01, 'stamina_cost_reduction_after_1', false, false)) * (GetSkillLevel(S_Sword_s01) - 1);
  3382.         return cost;
  3383.     }
  3384.    
  3385.     //modSigns
  3386.     private final function WhirlDrainResources(dt : float)
  3387.     {
  3388.         var delay : float;
  3389.         delay = GetStaminaActionDelay(ESAT_Ability, GetSkillAbilityName(S_Sword_s01), dt);
  3390.         DrainStamina(ESAT_FixedValue, GetWhirlStaminaCost(dt), delay, GetSkillAbilityName(S_Sword_s01));
  3391.     }
  3392.    
  3393.     //modSigns
  3394.     public final function GetHostilesInRange() : int
  3395.     {
  3396.         var actors : array< CActor >;
  3397.         var i : int;
  3398.        
  3399.         actors = GetActorsInRange( this, 30, 50, '', true );
  3400.        
  3401.         for(i = actors.Size() - 1; i >= 0; i -= 1)
  3402.         {
  3403.             if( GetAttitudeBetween( this, actors[i] ) != AIA_Hostile )
  3404.             {
  3405.                 actors.Erase( i );
  3406.             }
  3407.         }
  3408.        
  3409.         return actors.Size();
  3410.     }
  3411.    
  3412.     //modSigns
  3413.     public final function GetWhirlDamageBonus() : float
  3414.     {
  3415.         var bonusCount : int;
  3416.         var ability : SAbilityAttributeValue;
  3417.         var damageBonus : float;
  3418.        
  3419.         bonusCount = Clamp(GetHostilesInRange() - 1, 0, 5);
  3420.         ability = GetSkillAttributeValue(S_Sword_s01, 'whirl_dmg_bonus', false, true) * GetSkillLevel(S_Sword_s01);
  3421.         damageBonus = ability.valueMultiplicative * bonusCount;
  3422.        
  3423.         return damageBonus;
  3424.     }
  3425.    
  3426.     public final timer function SpecialAttackHeavySustainCost(dt : float, id : int)
  3427.     {
  3428.         var focusHighlight, ratio : float;
  3429.         var hud : CR4ScriptedHud;
  3430.         var hudWolfHeadModule : CR4HudModuleWolfHead;      
  3431.  
  3432.         PauseStaminaRegen('RendSkill'); //modSigns
  3433.        
  3434.         DrainStamina(ESAT_Ability, 0, 0, GetSkillAbilityName(S_Sword_s02), dt);
  3435.  
  3436.        
  3437.         if(GetStat(BCS_Stamina) <= 0)
  3438.             OnPerformSpecialAttack(false, false);
  3439.            
  3440.        
  3441.         ratio = EngineTimeToFloat(theGame.GetEngineTime() - specialHeavyStartEngineTime) / specialHeavyChargeDuration;
  3442.        
  3443.        
  3444.         if(ratio > 0.95)
  3445.             ratio = 1;
  3446.            
  3447.         SetSpecialAttackTimeRatio(ratio);
  3448.        
  3449.        
  3450.         //focusHighlight = ratio * GetStatMax(BCS_Focus);
  3451.         //focusHighlight = MinF(focusHighlight, GetStat(BCS_Focus));
  3452.         //focusHighlight = FloorF(focusHighlight);
  3453.         //modSigns
  3454.         /*focusHighlight = FloorF(ratio * GetStat(BCS_Focus));
  3455.        
  3456.         hud = (CR4ScriptedHud)theGame.GetHud();
  3457.         if ( hud )
  3458.         {
  3459.             hudWolfHeadModule = (CR4HudModuleWolfHead)hud.GetHudModule( "WolfHeadModule" );
  3460.             if ( hudWolfHeadModule )
  3461.             {
  3462.                 hudWolfHeadModule.LockFocusPoints((int)focusHighlight);
  3463.             }      
  3464.         }*/
  3465.     }
  3466.    
  3467.     public function OnSpecialAttackHeavyActionProcess()
  3468.     {
  3469.         var hud : CR4ScriptedHud;
  3470.         var hudWolfHeadModule : CR4HudModuleWolfHead;
  3471.        
  3472.         super.OnSpecialAttackHeavyActionProcess();
  3473.  
  3474.         hud = (CR4ScriptedHud)theGame.GetHud();
  3475.         if ( hud )
  3476.         {
  3477.             hudWolfHeadModule = (CR4HudModuleWolfHead)hud.GetHudModule( "WolfHeadModule" );
  3478.             if ( hudWolfHeadModule )
  3479.             {
  3480.                 hudWolfHeadModule.ResetFocusPoints();
  3481.             }      
  3482.         }
  3483.     }
  3484.    
  3485.     timer function IsSpecialLightAttackInputHeld ( time : float, id : int )
  3486.     {
  3487.         var hasResource : bool;
  3488.        
  3489.         if ( GetCurrentStateName() == 'CombatSteel' || GetCurrentStateName() == 'CombatSilver' )
  3490.         {
  3491.             if ( GetBIsCombatActionAllowed() && inputHandler.IsActionAllowed(EIAB_SwordAttack))
  3492.             {
  3493.                 /*if(GetStat(BCS_Stamina) > 0)
  3494.                 {
  3495.                     hasResource = true;
  3496.                 }
  3497.                 else
  3498.                 {
  3499.                     hasResource = (GetStat(BCS_Focus) >= GetWhirlFocusCostPerSec() * time);                
  3500.                 }*/ //modSigns: redone
  3501.                 hasResource = HasResourcesForWhirl(time);
  3502.                
  3503.                 if(hasResource)
  3504.                 {
  3505.                     SetupCombatAction( EBAT_SpecialAttack_Light, BS_Pressed );
  3506.                     RemoveTimer('IsSpecialLightAttackInputHeld');
  3507.                 }
  3508.                 else if(!playedSpecialAttackMissingResourceSound)
  3509.                 {
  3510.                     IndicateTooLowAdrenaline();
  3511.                     playedSpecialAttackMissingResourceSound = true;
  3512.                 }
  3513.             }          
  3514.         }
  3515.         else
  3516.         {
  3517.             RemoveTimer('IsSpecialLightAttackInputHeld');
  3518.         }
  3519.     }  
  3520.    
  3521.     timer function IsSpecialHeavyAttackInputHeld ( time : float, id : int )
  3522.     {      
  3523.         var cost : float;
  3524.        
  3525.         if ( GetCurrentStateName() == 'CombatSteel' || GetCurrentStateName() == 'CombatSilver' )
  3526.         {
  3527.             cost = CalculateAttributeValue(GetSkillAttributeValue(S_Sword_s02, 'stamina_cost_per_sec', false, false));
  3528.            
  3529.             if( GetBIsCombatActionAllowed() && inputHandler.IsActionAllowed(EIAB_SwordAttack))
  3530.             {
  3531.                 if(GetStat(BCS_Stamina) >= cost)
  3532.                 {
  3533.                     SetupCombatAction( EBAT_SpecialAttack_Heavy, BS_Pressed );
  3534.                     RemoveTimer('IsSpecialHeavyAttackInputHeld');
  3535.                 }
  3536.                 else if(!playedSpecialAttackMissingResourceSound)
  3537.                 {
  3538.                     IndicateTooLowAdrenaline();
  3539.                     playedSpecialAttackMissingResourceSound = true;
  3540.                 }
  3541.             }
  3542.         }
  3543.         else
  3544.         {
  3545.             RemoveTimer('IsSpecialHeavyAttackInputHeld');
  3546.         }
  3547.     }
  3548.    
  3549.     public function EvadePressed( bufferAction : EBufferActionType )
  3550.     {
  3551.         var cat : float;
  3552.        
  3553.         if( (bufferAction == EBAT_Dodge && IsActionAllowed(EIAB_Dodge)) || (bufferAction == EBAT_Roll && IsActionAllowed(EIAB_Roll)) )
  3554.         {
  3555.             //modSigns: check for stamina
  3556.             if( bufferAction == EBAT_Dodge && !HasStaminaToUseAction(ESAT_Dodge, '', 0, 0 ) ||
  3557.                 bufferAction == EBAT_Roll && !HasStaminaToUseAction(ESAT_Roll, '', 0, 0 ) )
  3558.             {
  3559.                 thePlayer.SoundEvent("gui_no_stamina");
  3560.                 return;
  3561.             }
  3562.            
  3563.             if(bufferAction != EBAT_Roll && ShouldProcessTutorial('TutorialDodge'))
  3564.             {
  3565.                 FactsAdd("tut_in_dodge", 1, 2);
  3566.                
  3567.                 if(FactsQuerySum("tut_fight_use_slomo") > 0)
  3568.                 {
  3569.                     theGame.RemoveTimeScale( theGame.GetTimescaleSource(ETS_TutorialFight) );
  3570.                     FactsRemove("tut_fight_slomo_ON");
  3571.                 }
  3572.             }              
  3573.             else if(bufferAction == EBAT_Roll && ShouldProcessTutorial('TutorialRoll'))
  3574.             {
  3575.                 FactsAdd("tut_in_roll", 1, 2);
  3576.                
  3577.                 if(FactsQuerySum("tut_fight_use_slomo") > 0)
  3578.                 {
  3579.                     theGame.RemoveTimeScale( theGame.GetTimescaleSource(ETS_TutorialFight) );
  3580.                     FactsRemove("tut_fight_slomo_ON");
  3581.                 }
  3582.             }
  3583.                
  3584.             if ( GetBIsInputAllowed() )
  3585.             {          
  3586.                 if ( GetBIsCombatActionAllowed() )
  3587.                 {
  3588.                     CriticalEffectAnimationInterrupted("Dodge 2");
  3589.                     PushCombatActionOnBuffer( bufferAction, BS_Released );
  3590.                     ProcessCombatActionBuffer();
  3591.                 }                  
  3592.                 else if ( IsInCombatAction() && GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Attack )
  3593.                 {
  3594.                     if ( CanPlayHitAnim() && IsThreatened() )
  3595.                     {
  3596.                         CriticalEffectAnimationInterrupted("Dodge 1");
  3597.                         PushCombatActionOnBuffer( bufferAction, BS_Released );
  3598.                         ProcessCombatActionBuffer();                           
  3599.                     }
  3600.                     else
  3601.                         PushCombatActionOnBuffer( bufferAction, BS_Released );
  3602.                 }
  3603.                
  3604.                 else if ( !( IsCurrentSignChanneled() ) )
  3605.                 {
  3606.                    
  3607.                     PushCombatActionOnBuffer( bufferAction, BS_Released );
  3608.                 }
  3609.             }
  3610.             else
  3611.             {
  3612.                 if ( IsInCombatAction() && GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Attack )
  3613.                 {
  3614.                     if ( CanPlayHitAnim() && IsThreatened() )
  3615.                     {
  3616.                         CriticalEffectAnimationInterrupted("Dodge 3");
  3617.                         PushCombatActionOnBuffer( bufferAction, BS_Released );
  3618.                         ProcessCombatActionBuffer();                           
  3619.                     }
  3620.                     else
  3621.                         PushCombatActionOnBuffer( bufferAction, BS_Released );
  3622.                 }
  3623.                 LogChannel( 'InputNotAllowed', "InputNotAllowed" );
  3624.             }
  3625.         }
  3626.         else
  3627.         {
  3628.             DisplayActionDisallowedHudMessage(EIAB_Dodge);
  3629.         }
  3630.     }
  3631.        
  3632.    
  3633.     public function ProcessCombatActionBuffer() : bool
  3634.     {
  3635.         var action              : EBufferActionType         = this.BufferCombatAction;
  3636.         var stage               : EButtonStage              = this.BufferButtonStage;      
  3637.         var throwStage          : EThrowStage;     
  3638.         var actionResult        : bool = true;
  3639.        
  3640.        
  3641.         if( isInFinisher )
  3642.         {
  3643.             return false;
  3644.         }
  3645.        
  3646.         if ( action != EBAT_SpecialAttack_Heavy )
  3647.             specialAttackCamera = false;           
  3648.        
  3649.        
  3650.         if(super.ProcessCombatActionBuffer())
  3651.             return true;       
  3652.            
  3653.         switch ( action )
  3654.         {          
  3655.             case EBAT_CastSign :
  3656.             {
  3657.                 switch ( stage )
  3658.                 {
  3659.                     case BS_Pressed :
  3660.                     {
  3661.  
  3662.  
  3663.  
  3664.  
  3665.    
  3666.    
  3667.                                 actionResult = this.CastSign();
  3668.                                 LogChannel('SignDebug', "CastSign()");
  3669.    
  3670.  
  3671.                     } break;
  3672.                    
  3673.                     default :
  3674.                     {
  3675.                         actionResult = false;
  3676.                     } break;
  3677.                 }
  3678.             } break;
  3679.            
  3680.             case EBAT_SpecialAttack_Light :
  3681.             {
  3682.                 switch ( stage )
  3683.                 {
  3684.                     case BS_Pressed :
  3685.                     {
  3686.                        
  3687.                         actionResult = this.OnPerformSpecialAttack( true, true );
  3688.                     } break;
  3689.                    
  3690.                     case BS_Released :
  3691.                     {                      
  3692.                         actionResult = this.OnPerformSpecialAttack( true, false );
  3693.                     } break;
  3694.                    
  3695.                     default :
  3696.                     {
  3697.                         actionResult = false;
  3698.                     } break;
  3699.                 }
  3700.             } break;
  3701.  
  3702.             case EBAT_SpecialAttack_Heavy :
  3703.             {
  3704.                 switch ( stage )
  3705.                 {
  3706.                     case BS_Pressed :
  3707.                     {
  3708.                        
  3709.                         actionResult = this.OnPerformSpecialAttack( false, true );
  3710.                     } break;
  3711.                    
  3712.                     case BS_Released :
  3713.                     {
  3714.                         actionResult = this.OnPerformSpecialAttack( false, false );
  3715.                     } break;
  3716.                    
  3717.                     default :
  3718.                     {
  3719.                         actionResult = false;
  3720.                     } break;
  3721.                 }
  3722.             } break;
  3723.            
  3724.             default:
  3725.                 return false;  
  3726.         }
  3727.        
  3728.        
  3729.         this.CleanCombatActionBuffer();
  3730.        
  3731.         if (actionResult)
  3732.         {
  3733.             SetCombatAction( action ) ;
  3734.         }
  3735.        
  3736.         return true;
  3737.     }
  3738.        
  3739.        
  3740.     event OnPerformSpecialAttack( isLightAttack : bool, enableAttack : bool ){}
  3741.    
  3742.     public final function GetEnemies() : array< CActor >
  3743.     {
  3744.         var actors, actors2 : array<CActor>;
  3745.         var i : int;
  3746.        
  3747.        
  3748.         actors = GetWitcherPlayer().GetHostileEnemies();
  3749.         ArrayOfActorsAppendUnique( actors, GetWitcherPlayer().GetMoveTargets() );
  3750.        
  3751.        
  3752.         thePlayer.GetVisibleEnemies( actors2 );
  3753.         ArrayOfActorsAppendUnique( actors, actors2 );
  3754.        
  3755.         for( i=actors.Size()-1; i>=0; i-=1 )
  3756.         {
  3757.             if( !IsRequiredAttitudeBetween( actors[i], this, true ) )
  3758.             {
  3759.                 actors.EraseFast( i );
  3760.             }
  3761.         }
  3762.        
  3763.         return actors;
  3764.     }
  3765.    
  3766.     event OnPlayerTickTimer( deltaTime : float )
  3767.     {
  3768.         super.OnPlayerTickTimer( deltaTime );
  3769.        
  3770.         if ( !IsInCombat() )
  3771.         {
  3772.             fastAttackCounter = 0;
  3773.             heavyAttackCounter = 0;        
  3774.         }      
  3775.         WmkGetMapMenuInstance().OnTick(deltaTime); // -= WMK:modAQOOM =-
  3776.     }
  3777.    
  3778.    
  3779.    
  3780.    
  3781.    
  3782.     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
  3783.     {
  3784.         var ret : bool;
  3785.         var skill : ESkill;
  3786.    
  3787.         ret = super.PrepareAttackAction(hitTarget, animData, weaponId, parried, countered, parriedBy, attackAnimationName, hitTime, weaponEntity, attackAction);
  3788.        
  3789.         if(!ret)
  3790.             return false;
  3791.        
  3792.        
  3793.         if(attackAction.IsActionMelee())
  3794.         {          
  3795.             skill = SkillNameToEnum( attackAction.GetAttackTypeName() );
  3796.             if( skill != S_SUndefined && CanUseSkill(skill))
  3797.             {
  3798.                 if(IsLightAttack(animData.attackName))
  3799.                     fastAttackCounter += 1;
  3800.                 else
  3801.                     fastAttackCounter = 0;
  3802.                
  3803.                 if(IsHeavyAttack(animData.attackName))
  3804.                     heavyAttackCounter += 1;
  3805.                 else
  3806.                     heavyAttackCounter = 0;            
  3807.             }      
  3808.         }
  3809.        
  3810.         AddTimer('FastAttackCounterDecay',5.0);
  3811.         AddTimer('HeavyAttackCounterDecay',5.0);
  3812.        
  3813.         return true;
  3814.     }
  3815.    
  3816.     protected function TestParryAndCounter(data : CPreAttackEventData, weaponId : SItemUniqueId, out parried : bool, out countered : bool) : array<CActor>
  3817.     {
  3818.        
  3819.         if(SkillNameToEnum(attackActionName) == S_Sword_s02)
  3820.             data.Can_Parry_Attack = false;
  3821.            
  3822.         return super.TestParryAndCounter(data, weaponId, parried, countered);
  3823.     }
  3824.        
  3825.     private timer function FastAttackCounterDecay(delta : float, id : int)
  3826.     {
  3827.         fastAttackCounter = 0;
  3828.     }
  3829.    
  3830.     private timer function HeavyAttackCounterDecay(delta : float, id : int)
  3831.     {
  3832.         heavyAttackCounter = 0;
  3833.     }
  3834.        
  3835.    
  3836.     public function GetCraftingSchematicsNames() : array<name>      {return craftingSchematics;}
  3837.    
  3838.     public function RemoveAllCraftingSchematics()
  3839.     {
  3840.         craftingSchematics.Clear();
  3841.     }
  3842.    
  3843.    
  3844.     function AddCraftingSchematic( nam : name, optional isSilent : bool, optional skipTutorialUpdate : bool ) : bool
  3845.     {
  3846.         var i : int;
  3847.        
  3848.         if(!skipTutorialUpdate && ShouldProcessTutorial('TutorialCraftingGotRecipe'))
  3849.         {
  3850.             FactsAdd("tut_received_schematic");
  3851.         }
  3852.        
  3853.         for(i=0; i<craftingSchematics.Size(); i+=1)
  3854.         {
  3855.             if(craftingSchematics[i] == nam)
  3856.                 return false;
  3857.            
  3858.            
  3859.             if(StrCmp(craftingSchematics[i],nam) > 0)
  3860.             {
  3861.                 craftingSchematics.Insert(i,nam);
  3862.                 AddCraftingHudNotification( nam, isSilent );
  3863.                 theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_CraftingSchematics );
  3864.                 return true;
  3865.             }          
  3866.         }  
  3867.  
  3868.        
  3869.         craftingSchematics.PushBack(nam);
  3870.         AddCraftingHudNotification( nam, isSilent );
  3871.         theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_CraftingSchematics );
  3872.         return true;   
  3873.     }
  3874.    
  3875.     function AddCraftingHudNotification( nam : name, isSilent : bool )
  3876.     {
  3877.         var hud : CR4ScriptedHud;
  3878.         if( !isSilent )
  3879.         {
  3880.             hud = (CR4ScriptedHud)theGame.GetHud();
  3881.             if( hud )
  3882.             {
  3883.                 hud.OnCraftingSchematicUpdate( nam );
  3884.             }
  3885.         }
  3886.     }  
  3887.    
  3888.     function AddAlchemyHudNotification( nam : name, isSilent : bool )
  3889.     {
  3890.         var hud : CR4ScriptedHud;
  3891.         if( !isSilent )
  3892.         {
  3893.             hud = (CR4ScriptedHud)theGame.GetHud();
  3894.             if( hud )
  3895.             {
  3896.                 hud.OnAlchemySchematicUpdate( nam );
  3897.             }
  3898.         }
  3899.     }
  3900.    
  3901.     public function GetExpandedCraftingCategories() : array< name >
  3902.     {
  3903.         return expandedCraftingCategories;
  3904.     }
  3905.    
  3906.     public function AddExpandedCraftingCategory( category : name )
  3907.     {
  3908.         if ( IsNameValid( category ) )
  3909.         {
  3910.             ArrayOfNamesPushBackUnique( expandedCraftingCategories, category );
  3911.         }
  3912.     }
  3913.  
  3914.     public function RemoveExpandedCraftingCategory( category : name )
  3915.     {
  3916.         if ( IsNameValid( category ) )
  3917.         {
  3918.             expandedCraftingCategories.Remove( category );
  3919.         }
  3920.     }
  3921.    
  3922.     public function SetCraftingFilters(showHasIngre : bool, showMissingIngre : bool, showAlreadyCrafted : bool )
  3923.     {
  3924.         craftingFilters.showCraftable = showHasIngre;
  3925.         craftingFilters.showMissingIngre = showMissingIngre;
  3926.         craftingFilters.showAlreadyCrafted = showAlreadyCrafted;
  3927.     }
  3928.    
  3929.     public function GetCraftingFilters() : SCraftingFilters
  3930.     {
  3931.        
  3932.         if ( craftingFilters.showCraftable == false && craftingFilters.showMissingIngre == false && craftingFilters.showAlreadyCrafted == false )
  3933.         {
  3934.             craftingFilters.showCraftable = true;
  3935.             craftingFilters.showMissingIngre = true;
  3936.             craftingFilters.showAlreadyCrafted = false;
  3937.         }
  3938.        
  3939.         return craftingFilters;
  3940.     }
  3941.  
  3942.    
  3943.    
  3944.    
  3945.    
  3946.     event OnMutation11Triggered()
  3947.     {
  3948.         var min, max : SAbilityAttributeValue;
  3949.         var healValue : float;
  3950.         var quenEntity : W3QuenEntity;
  3951.        
  3952.        
  3953.         if( IsSwimming() || IsDiving() || IsSailing() || IsUsingHorse() || IsUsingBoat() || IsUsingVehicle() || IsUsingExploration() )
  3954.         {
  3955.            
  3956.             ForceSetStat( BCS_Vitality, GetStatMax( BCS_Vitality ) );
  3957.            
  3958.            
  3959.             theGame.MutationHUDFeedback( MFT_PlayOnce );
  3960.            
  3961.            
  3962.             GCameraShake( 1.0f, , , , true, 'camera_shake_loop_lvl1_1' );
  3963.             AddTimer( 'StopMutation11CamShake', 2.f );
  3964.            
  3965.            
  3966.             theGame.VibrateControllerVeryHard( 2.f );
  3967.            
  3968.            
  3969.             Mutation11ShockWave( true );
  3970.            
  3971.            
  3972.             AddEffectDefault( EET_Mutation11Debuff, NULL, "Mutation 11 Debuff", false );
  3973.         }
  3974.         else
  3975.         {
  3976.             AddEffectDefault( EET_Mutation11Buff, this, "Mutation 11", false );
  3977.         }
  3978.     }
  3979.    
  3980.     timer function StopMutation11CamShake( dt : float, id : int )
  3981.     {
  3982.         theGame.GetGameCamera().StopAnimation( 'camera_shake_loop_lvl1_1' );
  3983.     }
  3984.    
  3985.     private var mutation12IsOnCooldown : bool;
  3986.    
  3987.     public final function AddMutation12Decoction()
  3988.     {
  3989.         var params : SCustomEffectParams;
  3990.         var buffs : array< EEffectType >;
  3991.         var existingDecoctionBuffs : array<CBaseGameplayEffect>;
  3992.         var i : int;
  3993.         var effectType : EEffectType;
  3994.         var decoctions : array< SItemUniqueId >;
  3995.         var tmpName : name;
  3996.         var min, max : SAbilityAttributeValue;
  3997.        
  3998.         if( mutation12IsOnCooldown )
  3999.         {
  4000.             return;
  4001.         }
  4002.        
  4003.        
  4004.         existingDecoctionBuffs = GetDrunkMutagens( "Mutation12" );
  4005.         theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation12', 'maxcap', min, max );
  4006.         if( existingDecoctionBuffs.Size() >= min.valueAdditive )
  4007.         {
  4008.             return;
  4009.         }
  4010.        
  4011.        
  4012.         mutation12IsOnCooldown = true;     
  4013.         theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation12', 'cooldown', min, max );
  4014.         AddTimer( 'Mutation12Cooldown', CalculateAttributeValue( min ) );
  4015.        
  4016.        
  4017.         decoctions = inv.GetItemsByTag( 'Mutagen' );
  4018.        
  4019.        
  4020.         for( i=decoctions.Size()-1; i>=0; i-=1 )
  4021.         {
  4022.             inv.GetPotionItemBuffData( decoctions[i], effectType, tmpName );
  4023.             if( HasBuff( effectType ) )
  4024.             {
  4025.                 decoctions.EraseFast( i );
  4026.                 continue;
  4027.             }
  4028.             buffs.PushBack( effectType );
  4029.         }
  4030.        
  4031.        
  4032.         if( buffs.Size() == 0 )
  4033.         {
  4034.             for( i=EET_Mutagen01; i<=EET_Mutagen28; i+=1 )
  4035.             {
  4036.                 if( !HasBuff( i ) )
  4037.                 {
  4038.                     buffs.PushBack( i );
  4039.                 }
  4040.             }
  4041.         }
  4042.        
  4043.        
  4044.         buffs.Remove( EET_Mutagen16 );
  4045.         buffs.Remove( EET_Mutagen24 );
  4046.        
  4047.        
  4048.         if( buffs.Size() == 0 )
  4049.         {
  4050.             return;
  4051.         }
  4052.        
  4053.        
  4054.         theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation12', 'duration', min, max );
  4055.         params.effectType = buffs[ RandRange( buffs.Size() ) ];
  4056.         params.creator = this;
  4057.         params.sourceName = "Mutation12";
  4058.         params.duration = min.valueAdditive;
  4059.         AddEffectCustom( params );
  4060.         ( ( W3Mutagen_Effect ) GetBuff( params.effectType, params.sourceName ) ).OverrideIcon( DecoctionEffectTypeToItemName( params.effectType ) );
  4061.        
  4062.        
  4063.         if ( !IsEffectActive( 'invisible' ) )
  4064.         {
  4065.             PlayEffect( 'use_potion' );
  4066.         }
  4067.        
  4068.         theGame.MutationHUDFeedback( MFT_PlayOnce );
  4069.     }
  4070.    
  4071.     timer function Mutation12Cooldown( dt : float, id : int )
  4072.     {
  4073.         mutation12IsOnCooldown = false;
  4074.     }
  4075.    
  4076.    
  4077.     public final function HasResourcesToStartAnyMutationResearch() : bool
  4078.     {
  4079.         var greenPoints, redPoints, bluePoints, count : int;
  4080.         var itemIDs : array< SItemUniqueId >;
  4081.        
  4082.         if( levelManager.GetPointsFree( ESkillPoint ) > 0 )
  4083.         {
  4084.             return true;
  4085.         }
  4086.        
  4087.        
  4088.         count = inv.GetItemQuantityByName( 'Greater mutagen green' );
  4089.         if( count > 0 )
  4090.         {
  4091.             itemIDs = inv.GetItemsByName( 'Greater mutagen green' );
  4092.             greenPoints = inv.GetMutationResearchPoints( SC_Green, itemIDs[0] );
  4093.             if( greenPoints > 0 )
  4094.             {
  4095.                 return true;
  4096.             }
  4097.         }  
  4098.         count = inv.GetItemQuantityByName( 'Greater mutagen red' );
  4099.         if( count > 0 )
  4100.         {
  4101.             itemIDs.Clear();
  4102.             itemIDs = inv.GetItemsByName( 'Greater mutagen red' );
  4103.             redPoints = inv.GetMutationResearchPoints( SC_Red, itemIDs[0] );
  4104.             if( redPoints > 0 )
  4105.             {
  4106.                 return true;
  4107.             }
  4108.         }      
  4109.         count = inv.GetItemQuantityByName( 'Greater mutagen blue' );
  4110.         if( count > 0 )
  4111.         {
  4112.             itemIDs.Clear();
  4113.             itemIDs = inv.GetItemsByName( 'Greater mutagen blue' );
  4114.             bluePoints = inv.GetMutationResearchPoints( SC_Blue, itemIDs[0] );
  4115.             if( bluePoints > 0 )
  4116.             {
  4117.                 return true;
  4118.             }
  4119.         }      
  4120.        
  4121.         return false;
  4122.     }
  4123.    
  4124.    
  4125.     public final function Mutation11StartAnimation()
  4126.     {
  4127.        
  4128.         thePlayer.ActionPlaySlotAnimationAsync( 'PLAYER_SLOT', 'geralt_mutation_11', 0.2, 0.2 );
  4129.        
  4130.        
  4131.         BlockAllActions( 'Mutation11', true );
  4132.        
  4133.        
  4134.         loopingCameraShakeAnimName = 'camera_shake_loop_lvl1_1';
  4135.         GCameraShake( 1.0f, , , , true, loopingCameraShakeAnimName );
  4136.        
  4137.        
  4138.         theGame.VibrateControllerVeryHard( 15.f );
  4139.        
  4140.        
  4141.         storedInteractionPriority = GetInteractionPriority();
  4142.         SetInteractionPriority( IP_Max_Unpushable );
  4143.     }
  4144.    
  4145.     event OnAnimEvent_Mutation11ShockWave( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  4146.     {
  4147.         Mutation11ShockWave( false );
  4148.     }
  4149.    
  4150.     private final function Mutation11ShockWave( skipQuenSign : bool )
  4151.     {
  4152.         var action : W3DamageAction;
  4153.         var ents : array< CGameplayEntity >;
  4154.         var i, j : int;
  4155.         var damages : array< SRawDamage >;
  4156.    
  4157.        
  4158.         FindGameplayEntitiesInSphere(ents, GetWorldPosition(), 5.f, 1000, '', FLAG_OnlyAliveActors + FLAG_ExcludeTarget + FLAG_Attitude_Hostile + FLAG_Attitude_Neutral, this);
  4159.        
  4160.         if( ents.Size() > 0 )
  4161.         {
  4162.             damages = theGame.GetDefinitionsManager().GetDamagesFromAbility( 'Mutation11' );
  4163.         }
  4164.        
  4165.        
  4166.         for(i=0; i<ents.Size(); i+=1)
  4167.         {
  4168.             action = new W3DamageAction in theGame;
  4169.             action.Initialize( this, ents[i], NULL, "Mutation11", EHRT_Heavy, CPS_SpellPower, false, false, true, false );
  4170.            
  4171.             for( j=0; j<damages.Size(); j+=1 )
  4172.             {
  4173.                 action.AddDamage( damages[j].dmgType, damages[j].dmgVal );
  4174.             }
  4175.            
  4176.             action.SetCannotReturnDamage( true );
  4177.             action.SetProcessBuffsIfNoDamage( true );
  4178.             action.AddEffectInfo( EET_KnockdownTypeApplicator );
  4179.             action.SetHitAnimationPlayType( EAHA_ForceYes );
  4180.             action.SetCanPlayHitParticle( false );
  4181.            
  4182.             theGame.damageMgr.ProcessAction( action );
  4183.             delete action;
  4184.         }
  4185.        
  4186.        
  4187.        
  4188.        
  4189.        
  4190.         mutation11QuenEntity = ( W3QuenEntity )GetSignEntity( ST_Quen );
  4191.         if( !mutation11QuenEntity )
  4192.         {
  4193.             mutation11QuenEntity = (W3QuenEntity)theGame.CreateEntity( GetSignTemplate( ST_Quen ), GetWorldPosition(), GetWorldRotation() );
  4194.             mutation11QuenEntity.CreateAttachment( this, 'quen_sphere' );
  4195.             AddTimer( 'DestroyMutation11QuenEntity', 2.f );
  4196.         }
  4197.         mutation11QuenEntity.PlayHitEffect( 'quen_impulse_explode', mutation11QuenEntity.GetWorldRotation() );
  4198.        
  4199.         if( !skipQuenSign )
  4200.         {
  4201.            
  4202.             PlayEffect( 'mutation_11_second_life' );
  4203.            
  4204.            
  4205.             RestoreQuen( 1000000.f, 10.f, true );
  4206.         }
  4207.     }
  4208.    
  4209.     private var mutation11QuenEntity : W3QuenEntity;
  4210.     private var storedInteractionPriority : EInteractionPriority;
  4211.    
  4212.     timer function DestroyMutation11QuenEntity( dt : float, id : int )
  4213.     {
  4214.         if( mutation11QuenEntity )
  4215.         {
  4216.             mutation11QuenEntity.Destroy();
  4217.         }
  4218.     }
  4219.    
  4220.     event OnAnimEvent_Mutation11AnimEnd( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  4221.     {
  4222.         if( animEventType == AET_DurationEnd )
  4223.         {
  4224.            
  4225.             BlockAllActions( 'Mutation11', false );        
  4226.            
  4227.            
  4228.             theGame.GetGameCamera().StopAnimation( 'camera_shake_loop_lvl1_1' );
  4229.            
  4230.            
  4231.             theGame.StopVibrateController();
  4232.            
  4233.            
  4234.             SetInteractionPriority( storedInteractionPriority );
  4235.            
  4236.            
  4237.             RemoveBuff( EET_Mutation11Buff, true );
  4238.         }
  4239.         else if ( animEventType == AET_DurationStart || animEventType == AET_DurationStartInTheMiddle )
  4240.         {
  4241.            
  4242.             SetBehaviorVariable( 'AIControlled', 0.f );
  4243.         }
  4244.     }
  4245.        
  4246.     public final function MutationSystemEnable( enable : bool )
  4247.     {
  4248.         ( ( W3PlayerAbilityManager ) abilityManager ).MutationSystemEnable( enable );
  4249.     }
  4250.    
  4251.     public final function IsMutationSystemEnabled() : bool
  4252.     {
  4253.         return ( ( W3PlayerAbilityManager ) abilityManager ).IsMutationSystemEnabled();
  4254.     }
  4255.    
  4256.     public final function GetMutation( mutationType : EPlayerMutationType ) : SMutation
  4257.     {
  4258.         return ( ( W3PlayerAbilityManager ) abilityManager ).GetMutation( mutationType );
  4259.     }
  4260.    
  4261.     public final function IsMutationActive( mutationType : EPlayerMutationType) : bool
  4262.     {
  4263.         var swordQuality : int;
  4264.         var sword : SItemUniqueId;
  4265.        
  4266.         if( GetEquippedMutationType() != mutationType )
  4267.         {
  4268.             return false;
  4269.         }
  4270.        
  4271.         switch( mutationType )
  4272.         {
  4273.             case EPMT_Mutation4 :
  4274.             case EPMT_Mutation5 :
  4275.             case EPMT_Mutation7 :
  4276.             case EPMT_Mutation8 :
  4277.             case EPMT_Mutation10 :
  4278.             case EPMT_Mutation11 :
  4279.             case EPMT_Mutation12 :
  4280.                 if( IsInFistFight() )
  4281.                 {
  4282.                     return false;
  4283.                 }
  4284.         }
  4285.        
  4286.         if( mutationType == EPMT_Mutation1 )
  4287.         {
  4288.             sword = inv.GetCurrentlyHeldSword();           
  4289.             swordQuality = inv.GetItemQuality( sword );
  4290.            
  4291.            
  4292.             if( swordQuality < 3 )
  4293.             {
  4294.                 return false;
  4295.             }
  4296.         }
  4297.        
  4298.         return true;
  4299.     }
  4300.        
  4301.     public final function SetEquippedMutation( mutationType : EPlayerMutationType ) : bool
  4302.     {
  4303.         return ( ( W3PlayerAbilityManager ) abilityManager ).SetEquippedMutation( mutationType );
  4304.     }
  4305.    
  4306.     public final function GetEquippedMutationType() : EPlayerMutationType
  4307.     {
  4308.         return ( ( W3PlayerAbilityManager ) abilityManager ).GetEquippedMutationType();
  4309.     }
  4310.    
  4311.     public final function CanEquipMutation(mutationType : EPlayerMutationType) : bool
  4312.     {
  4313.         return ( ( W3PlayerAbilityManager ) abilityManager ).CanEquipMutation( mutationType );
  4314.     }
  4315.    
  4316.     public final function CanResearchMutation( mutationType : EPlayerMutationType ) : bool
  4317.     {
  4318.         return ( ( W3PlayerAbilityManager ) abilityManager ).CanResearchMutation( mutationType );
  4319.     }
  4320.    
  4321.     public final function IsMutationResearched(mutationType : EPlayerMutationType) : bool
  4322.     {
  4323.         return ( ( W3PlayerAbilityManager ) abilityManager ).IsMutationResearched( mutationType );
  4324.     }
  4325.    
  4326.     public final function GetMutationResearchProgress(mutationType : EPlayerMutationType) : int
  4327.     {
  4328.         return ( ( W3PlayerAbilityManager ) abilityManager ).GetMutationResearchProgress( mutationType );
  4329.     }
  4330.    
  4331.     public final function GetMasterMutationStage() : int
  4332.     {
  4333.         return ( ( W3PlayerAbilityManager ) abilityManager ).GetMasterMutationStage();
  4334.     }
  4335.    
  4336.     public final function MutationResearchWithSkillPoints(mutation : EPlayerMutationType, skillPoints : int) : bool
  4337.     {
  4338.         return ( ( W3PlayerAbilityManager ) abilityManager ).MutationResearchWithSkillPoints( mutation, skillPoints );
  4339.     }
  4340.    
  4341.     public final function MutationResearchWithItem(mutation : EPlayerMutationType, item : SItemUniqueId, optional count: int) : bool
  4342.     {
  4343.         return ( ( W3PlayerAbilityManager ) abilityManager ).MutationResearchWithItem( mutation, item, count );
  4344.     }
  4345.    
  4346.     public final function GetMutationLocalizedName( mutationType : EPlayerMutationType ) : string
  4347.     {
  4348.         var pam : W3PlayerAbilityManager;
  4349.         var locKey : name;
  4350.    
  4351.         pam = (W3PlayerAbilityManager)GetWitcherPlayer().abilityManager;
  4352.         locKey = pam.GetMutationNameLocalizationKey( mutationType );
  4353.        
  4354.         return GetLocStringByKeyExt( locKey );
  4355.     }
  4356.    
  4357.     public final function GetMutationLocalizedDescription( mutationType : EPlayerMutationType ) : string
  4358.     {
  4359.         var pam : W3PlayerAbilityManager;
  4360.         var locKey : name;
  4361.         var arrStr : array< string >;
  4362.         var dm : CDefinitionsManagerAccessor;
  4363.         var min, max, sp : SAbilityAttributeValue;
  4364.         var tmp, tmp2, tox, critBonusDamage, val : float;
  4365.         var stats, stats2 : SPlayerOffenseStats;
  4366.         var buffPerc, exampleEnemyCount, debuffPerc : int;
  4367.    
  4368.         pam = (W3PlayerAbilityManager)GetWitcherPlayer().abilityManager;
  4369.         locKey = pam.GetMutationDescriptionLocalizationKey( mutationType );
  4370.         dm = theGame.GetDefinitionsManager();
  4371.        
  4372.         switch( mutationType )
  4373.         {
  4374.             case EPMT_Mutation1 :
  4375.                 dm.GetAbilityAttributeValue('Mutation1', 'dmg_bonus_factor', min, max);                        
  4376.                 arrStr.PushBack( NoTrailZeros( RoundMath( 100 * min.valueAdditive ) ) );
  4377.                 break;
  4378.                
  4379.             case EPMT_Mutation2 :
  4380.                 sp = GetPowerStatValue( CPS_SpellPower );
  4381.                
  4382.                
  4383.                 dm.GetAbilityAttributeValue( 'Mutation2', 'crit_chance_factor', min, max );
  4384.                 arrStr.PushBack( NoTrailZeros( RoundMath( 100 * ( min.valueAdditive + sp.valueMultiplicative * min.valueMultiplicative ) ) ) );
  4385.                
  4386.                
  4387.                 dm.GetAbilityAttributeValue( 'Mutation2', 'crit_damage_factor', min, max );
  4388.                 critBonusDamage = sp.valueMultiplicative * min.valueMultiplicative;
  4389.                
  4390.                 arrStr.PushBack( NoTrailZeros( RoundMath( 100 * critBonusDamage ) ) );
  4391.                 break;
  4392.                
  4393.             case EPMT_Mutation3 :
  4394.                
  4395.                 dm.GetAbilityAttributeValue( 'Mutation3', 'attack_power', min, max );
  4396.                 tmp = min.valueMultiplicative;
  4397.                 arrStr.PushBack( NoTrailZeros( RoundMath( 100 * tmp ) ) );
  4398.                
  4399.                
  4400.                 dm.GetAbilityAttributeValue( 'Mutation3', 'maxcap', min, max );
  4401.                 arrStr.PushBack( NoTrailZeros( RoundMath( 100 * tmp * min.valueAdditive ) ) );
  4402.                 break;
  4403.                
  4404.             case EPMT_Mutation4 :
  4405.                
  4406.                 dm.GetAbilityAttributeValue( 'AcidEffect', 'DirectDamage', min, max );
  4407.                 tmp2 = 100 * min.valueAdditive;
  4408.                 dm.GetAbilityAttributeValue( 'AcidEffect', 'duration', min, max );
  4409.                 tmp2 *= min.valueAdditive;
  4410.                 arrStr.PushBack( NoTrailZeros( tmp2 ) );
  4411.                
  4412.                
  4413.                 tox = GetStat( BCS_Toxicity );
  4414.                 if( tox > 0 )
  4415.                 {
  4416.                     tmp = RoundMath( tmp2 * tox );
  4417.                 }
  4418.                 else
  4419.                 {
  4420.                     tmp = tmp2;
  4421.                 }
  4422.                 arrStr.PushBack( NoTrailZeros( tmp ) );
  4423.                
  4424.                
  4425.                 tox = GetStatMax( BCS_Toxicity );
  4426.                 tmp = RoundMath( tmp2 * tox );
  4427.                 arrStr.PushBack( NoTrailZeros( tmp ) );
  4428.                 break;
  4429.                
  4430.             case EPMT_Mutation5 :
  4431.                
  4432.                 dm.GetAbilityAttributeValue( 'Mutation5', 'mut5_dmg_red_perc', min, max );
  4433.                 tmp = min.valueAdditive;
  4434.                 arrStr.PushBack( NoTrailZeros( 100 * tmp ) );
  4435.                
  4436.                
  4437.                 arrStr.PushBack( NoTrailZeros( 100 * tmp * 3 ) );
  4438.                
  4439.                 break;
  4440.            
  4441.             case EPMT_Mutation6 :  
  4442.                 //modSigns: raw and total damage
  4443.                 theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation6', 'full_freeze_chance', min, max );
  4444.                 arrStr.PushBack( RoundMath( 100 * min.valueMultiplicative ) );
  4445.                 theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation6', 'ForceDamage', min, max );
  4446.                 val = CalculateAttributeValue( min );
  4447.                 arrStr.PushBack( RoundMath( val ) );
  4448.                 sp = GetTotalSignSpellPower( S_Magic_1 );
  4449.                 arrStr.PushBack( RoundMath( val * sp.valueMultiplicative ) );
  4450.            
  4451.                 break;
  4452.                
  4453.             case EPMT_Mutation7 :
  4454.                
  4455.                 dm.GetAbilityAttributeValue( 'Mutation7Buff', 'attack_power', min, max );
  4456.                 buffPerc = (int) ( 100 * min.valueMultiplicative );
  4457.                 arrStr.PushBack( NoTrailZeros( buffPerc ) );
  4458.                
  4459.                
  4460.                 dm.GetAbilityAttributeValue( 'Mutation7BuffEffect', 'duration', min, max );
  4461.                 arrStr.PushBack( NoTrailZeros( min.valueAdditive ) );
  4462.                
  4463.                
  4464.                 exampleEnemyCount = 11;
  4465.                 arrStr.PushBack( exampleEnemyCount );
  4466.                
  4467.                
  4468.                 arrStr.PushBack( buffPerc * ( exampleEnemyCount -1 ) );
  4469.                
  4470.                
  4471.                 dm.GetAbilityAttributeValue( 'Mutation7Debuff', 'attack_power', min, max );
  4472.                 debuffPerc = (int) ( - 100 * min.valueMultiplicative );
  4473.                 arrStr.PushBack( NoTrailZeros( debuffPerc ) );
  4474.                
  4475.                
  4476.                 theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation7Debuff', 'minCapStacks', min, max );
  4477.                 arrStr.PushBack( NoTrailZeros( debuffPerc * min.valueAdditive ) );
  4478.                
  4479.                
  4480.                 dm.GetAbilityAttributeValue( 'Mutation7DebuffEffect', 'duration', min, max );
  4481.                 arrStr.PushBack( NoTrailZeros( min.valueAdditive ) );
  4482.                    
  4483.                 break;
  4484.            
  4485.             case EPMT_Mutation8 :
  4486.                
  4487.                 dm.GetAbilityAttributeValue( 'Mutation8', 'dmg_bonus', min, max );
  4488.                 arrStr.PushBack( NoTrailZeros( 100 * min.valueMultiplicative ) );
  4489.                
  4490.                
  4491.                 dm.GetAbilityAttributeValue( 'Mutation8', 'hp_perc_trigger', min, max );
  4492.                 arrStr.PushBack( NoTrailZeros( 100 * min.valueMultiplicative ) );
  4493.                
  4494.                 break;
  4495.                
  4496.             case EPMT_Mutation9 :
  4497.                
  4498.                
  4499.                
  4500.                
  4501.                 //stats = GetOffenseStatsList( 1 ); //modSigns
  4502.                 //arrStr.PushBack( NoTrailZeros( RoundMath( stats.crossbowSteelDmg ) ) );
  4503.                
  4504.                
  4505.                 //stats2 = GetOffenseStatsList( 2 ); //modSigns
  4506.                 //arrStr.PushBack( NoTrailZeros( RoundMath( stats2.crossbowSteelDmg ) ) );
  4507.                
  4508.                
  4509.                 dm.GetAbilityAttributeValue( 'Mutation9', 'critical_hit_chance', min, max );
  4510.                 arrStr.PushBack( NoTrailZeros( 100 * min.valueMultiplicative ) );
  4511.                
  4512.                 //modSigns: crit damage
  4513.                 dm.GetAbilityAttributeValue( 'Mutation9', 'critical_damage', min, max );
  4514.                 arrStr.PushBack( NoTrailZeros( 100 * min.valueAdditive ) );
  4515.                
  4516.                
  4517.                 dm.GetAbilityAttributeValue( 'Mutation9', 'health_reduction', min, max );
  4518.                 arrStr.PushBack( NoTrailZeros( 100 * min.valueMultiplicative ) );
  4519.                
  4520.                 break;
  4521.                
  4522.             case EPMT_Mutation10 :
  4523.                
  4524.                 dm.GetAbilityAttributeValue( 'Mutation10Effect', 'mutation10_stat_boost', min, max );
  4525.                 arrStr.PushBack( NoTrailZeros( 100 * min.valueMultiplicative ) );
  4526.                
  4527.                
  4528.                 arrStr.PushBack( NoTrailZeros( 100 * min.valueMultiplicative * GetStatMax( BCS_Toxicity ) ) );
  4529.                
  4530.                 break;
  4531.                
  4532.             case EPMT_Mutation11 :
  4533.                
  4534.                 arrStr.PushBack( 100 );
  4535.                
  4536.                
  4537.                 dm.GetAbilityAttributeValue( 'Mutation11DebuffEffect', 'duration', min, max);
  4538.                 arrStr.PushBack( NoTrailZeros( min.valueAdditive ) );
  4539.                 break;
  4540.                
  4541.             case EPMT_Mutation12 :
  4542.                
  4543.                 dm.GetAbilityAttributeValue( 'Mutation12', 'duration', min, max );
  4544.                 arrStr.PushBack( NoTrailZeros( min.valueAdditive ) );              
  4545.                
  4546.                
  4547.                 dm.GetAbilityAttributeValue( 'Mutation12', 'maxcap', min, max );
  4548.                 arrStr.PushBack( NoTrailZeros( min.valueAdditive ) );  
  4549.                 break;
  4550.                
  4551.             case EPMT_MutationMaster :
  4552.                
  4553.                 arrStr.PushBack( "4" );
  4554.                
  4555.                 break;
  4556.         }
  4557.        
  4558.         return GetLocStringByKeyExtWithParams( locKey, , , arrStr );
  4559.     }
  4560.        
  4561.     public final function ApplyMutation10StatBoost( out statValue : SAbilityAttributeValue )
  4562.     {
  4563.         var attValue            : SAbilityAttributeValue;
  4564.         var currToxicity        : float;
  4565.        
  4566.         if( IsMutationActive( EPMT_Mutation10 ) )
  4567.         {
  4568.             currToxicity = GetStat( BCS_Toxicity );
  4569.             if( currToxicity > 0.f )
  4570.             {
  4571.                 attValue = GetAttributeValue( 'mutation10_stat_boost' );
  4572.                 currToxicity *= attValue.valueMultiplicative;
  4573.                 statValue.valueMultiplicative += currToxicity;
  4574.             }
  4575.         }
  4576.     }
  4577.  
  4578.    
  4579.    
  4580.    
  4581.    
  4582.    
  4583.  
  4584.     public final function IsBookRead( bookName : name ):bool
  4585.     {
  4586.         return booksRead.Contains( bookName );
  4587.     }  
  4588.    
  4589.     public final function AddReadBook( bookName : name ):void
  4590.     {
  4591.         if( !booksRead.Contains( bookName ) )
  4592.         {
  4593.             booksRead.PushBack( bookName );
  4594.         }
  4595.     }
  4596.    
  4597.     public final function RemoveReadBook( bookName : name ):void
  4598.     {
  4599.         var idx : int = booksRead.FindFirst( bookName );
  4600.        
  4601.         if( idx > -1 )
  4602.         {
  4603.             booksRead.Erase( idx );
  4604.         }
  4605.     }
  4606.    
  4607.    
  4608.    
  4609.    
  4610.    
  4611.    
  4612.    
  4613.     public final function GetMutagenBuffs() : array< W3Mutagen_Effect >
  4614.     {
  4615.         var null : array< W3Mutagen_Effect >;
  4616.        
  4617.         if(effectManager)
  4618.         {
  4619.             return effectManager.GetMutagenBuffs();
  4620.         }
  4621.    
  4622.         return null;
  4623.     }
  4624.    
  4625.     public function GetAlchemyRecipes() : array<name>
  4626.     {
  4627.         return alchemyRecipes;
  4628.     }
  4629.        
  4630.     public function CanLearnAlchemyRecipe(recipeName : name) : bool
  4631.     {
  4632.         var dm : CDefinitionsManagerAccessor;
  4633.         var recipeNode : SCustomNode;
  4634.         var i, tmpInt : int;
  4635.         var tmpName : name;
  4636.    
  4637.         dm = theGame.GetDefinitionsManager();
  4638.         if ( dm.GetSubNodeByAttributeValueAsCName( recipeNode, 'alchemy_recipes', 'name_name', recipeName ) )
  4639.         {
  4640.             return true;
  4641.            
  4642.         }
  4643.        
  4644.         return false;
  4645.     }
  4646.    
  4647.     private final function RemoveAlchemyRecipe(recipeName : name)
  4648.     {
  4649.         alchemyRecipes.Remove(recipeName);
  4650.     }
  4651.    
  4652.     private final function RemoveAllAlchemyRecipes()
  4653.     {
  4654.         alchemyRecipes.Clear();
  4655.     }
  4656.  
  4657.    
  4658.     function AddAlchemyRecipe(nam : name, optional isSilent : bool, optional skipTutorialUpdate : bool) : bool
  4659.     {
  4660.         var i, potions, bombs : int;
  4661.         var found : bool;
  4662.         var m_alchemyManager : W3AlchemyManager;
  4663.         var recipe : SAlchemyRecipe;
  4664.         var knownBombTypes : array<string>;
  4665.         var strRecipeName, recipeNameWithoutLevel : string;
  4666.        
  4667.         if(!IsAlchemyRecipe(nam))
  4668.             return false;
  4669.        
  4670.         found = false;
  4671.         for(i=0; i<alchemyRecipes.Size(); i+=1)
  4672.         {
  4673.             if(alchemyRecipes[i] == nam)
  4674.                 return false;
  4675.            
  4676.            
  4677.             if(StrCmp(alchemyRecipes[i],nam) > 0)
  4678.             {
  4679.                 alchemyRecipes.Insert(i,nam);
  4680.                 found = true;
  4681.                 AddAlchemyHudNotification(nam,isSilent);
  4682.                 break;
  4683.             }          
  4684.         }  
  4685.  
  4686.         if(!found)
  4687.         {
  4688.             alchemyRecipes.PushBack(nam);
  4689.             AddAlchemyHudNotification(nam,isSilent);
  4690.         }
  4691.        
  4692.         m_alchemyManager = new W3AlchemyManager in this;
  4693.         m_alchemyManager.Init(alchemyRecipes);
  4694.         m_alchemyManager.GetRecipe(nam, recipe);
  4695.            
  4696.        
  4697.         if(CanUseSkill(S_Alchemy_s18))
  4698.         {
  4699.             //modSigns
  4700.             //if ((recipe.cookedItemType != EACIT_Bolt) && (recipe.cookedItemType != EACIT_Undefined) && (recipe.cookedItemType != EACIT_Dye) && (recipe.level <= GetSkillLevel(S_Alchemy_s18)))
  4701.             if(IsAlchemy18Recipe(recipe.cookedItemType) && recipe.level <= GetSkillLevel(S_Alchemy_s18))
  4702.                 AddAbility(SkillEnumToName(S_Alchemy_s18), true);
  4703.            
  4704.         }
  4705.        
  4706.        
  4707.         if(recipe.cookedItemType == EACIT_Bomb)
  4708.         {
  4709.             bombs = 0;
  4710.             for(i=0; i<alchemyRecipes.Size(); i+=1)
  4711.             {
  4712.                 m_alchemyManager.GetRecipe(alchemyRecipes[i], recipe);
  4713.                
  4714.                
  4715.                 if(recipe.cookedItemType == EACIT_Bomb)
  4716.                 {
  4717.                     strRecipeName = NameToString(alchemyRecipes[i]);
  4718.                     recipeNameWithoutLevel = StrLeft(strRecipeName, StrLen(strRecipeName)-2);
  4719.                     if(!knownBombTypes.Contains(recipeNameWithoutLevel))
  4720.                     {
  4721.                         bombs += 1;
  4722.                         knownBombTypes.PushBack(recipeNameWithoutLevel);
  4723.                     }
  4724.                 }
  4725.             }
  4726.            
  4727.             theGame.GetGamerProfile().SetStat(ES_KnownBombRecipes, bombs);
  4728.         }      
  4729.        
  4730.         else if(recipe.cookedItemType == EACIT_Potion || recipe.cookedItemType == EACIT_MutagenPotion || recipe.cookedItemType == EACIT_Alcohol || recipe.cookedItemType == EACIT_Quest)
  4731.         {
  4732.             potions = 0;
  4733.             for(i=0; i<alchemyRecipes.Size(); i+=1)
  4734.             {
  4735.                 m_alchemyManager.GetRecipe(alchemyRecipes[i], recipe);
  4736.                
  4737.                
  4738.                 if(recipe.cookedItemType == EACIT_Potion || recipe.cookedItemType == EACIT_MutagenPotion || recipe.cookedItemType == EACIT_Alcohol || recipe.cookedItemType == EACIT_Quest)
  4739.                 {
  4740.                     potions += 1;
  4741.                 }              
  4742.             }      
  4743.             theGame.GetGamerProfile().SetStat(ES_KnownPotionRecipes, potions);
  4744.         }
  4745.        
  4746.         theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_AlchemyRecipe );
  4747.                
  4748.         return true;
  4749.     }
  4750.    
  4751.     public function GetExpandedAlchemyCategories() : array< name >
  4752.     {
  4753.         return expandedAlchemyCategories;
  4754.     }
  4755.    
  4756.     public function AddExpandedAlchemyCategory( category : name )
  4757.     {
  4758.         if ( IsNameValid( category ) )
  4759.         {
  4760.             ArrayOfNamesPushBackUnique( expandedAlchemyCategories, category );
  4761.         }
  4762.     }
  4763.  
  4764.     public function RemoveExpandedAlchemyCategory( category : name )
  4765.     {
  4766.         if ( IsNameValid( category ) )
  4767.         {
  4768.             expandedAlchemyCategories.Remove( category );
  4769.         }
  4770.     }
  4771.    
  4772.     public function SetAlchemyFilters(showHasIngre : bool, showMissingIngre : bool, showAlreadyCrafted : bool )
  4773.     {
  4774.         alchemyFilters.showCraftable = showHasIngre;
  4775.         alchemyFilters.showMissingIngre = showMissingIngre;
  4776.         alchemyFilters.showAlreadyCrafted = showAlreadyCrafted;
  4777.     }
  4778.    
  4779.     public function GetAlchemyFilters() : SCraftingFilters
  4780.     {
  4781.        
  4782.         if ( alchemyFilters.showCraftable == false && alchemyFilters.showMissingIngre == false && alchemyFilters.showAlreadyCrafted == false )
  4783.         {
  4784.             alchemyFilters.showCraftable = true;
  4785.             alchemyFilters.showMissingIngre = true;
  4786.             alchemyFilters.showAlreadyCrafted = false;
  4787.         }
  4788.  
  4789.         return alchemyFilters;
  4790.     }
  4791.    
  4792.    
  4793.    
  4794.    
  4795.    
  4796.    
  4797.  
  4798.     public function GetExpandedBestiaryCategories() : array< name >
  4799.     {
  4800.         return expandedBestiaryCategories;
  4801.     }
  4802.    
  4803.     public function AddExpandedBestiaryCategory( category : name )
  4804.     {
  4805.         if ( IsNameValid( category ) )
  4806.         {
  4807.             ArrayOfNamesPushBackUnique( expandedBestiaryCategories, category );
  4808.         }
  4809.     }
  4810.  
  4811.     public function RemoveExpandedBestiaryCategory( category : name )
  4812.     {
  4813.         if ( IsNameValid( category ) )
  4814.         {
  4815.             expandedBestiaryCategories.Remove( category );
  4816.         }
  4817.     }
  4818.    
  4819.    
  4820.    
  4821.    
  4822.    
  4823.    
  4824.    
  4825.     public function GetDisplayHeavyAttackIndicator() : bool
  4826.     {
  4827.         return bDispalyHeavyAttackIndicator;
  4828.     }
  4829.  
  4830.     public function SetDisplayHeavyAttackIndicator( val : bool )
  4831.     {
  4832.         bDispalyHeavyAttackIndicator = val;
  4833.     }
  4834.  
  4835.     public function GetDisplayHeavyAttackFirstLevelTimer() : bool
  4836.     {
  4837.         return bDisplayHeavyAttackFirstLevelTimer;
  4838.     }
  4839.  
  4840.     public function SetDisplayHeavyAttackFirstLevelTimer( val : bool )
  4841.     {
  4842.         bDisplayHeavyAttackFirstLevelTimer = val;
  4843.     }
  4844.    
  4845.    
  4846.    
  4847.    
  4848.    
  4849.    
  4850.  
  4851.     public function SelectQuickslotItem( slot : EEquipmentSlots )
  4852.     {
  4853.         var item : SItemUniqueId;
  4854.    
  4855.         GetItemEquippedOnSlot(slot, item);
  4856.         selectedItemId = item;         
  4857.     }  
  4858.    
  4859.    
  4860.    
  4861.    
  4862.    
  4863.    
  4864.    
  4865.     public function GetMedallion() : W3MedallionController
  4866.     {
  4867.         if ( !medallionController )
  4868.         {
  4869.             medallionController = new W3MedallionController in this;
  4870.         }
  4871.         return medallionController;
  4872.     }
  4873.    
  4874.    
  4875.     public final function HighlightObjects(range : float, optional highlightTime : float )
  4876.     {
  4877.         var ents : array<CGameplayEntity>;
  4878.         var i : int;
  4879.  
  4880.         FindGameplayEntitiesInSphere(ents, GetWorldPosition(), range, 100, 'HighlightedByMedalionFX', FLAG_ExcludePlayer);
  4881.  
  4882.         if(highlightTime == 0)
  4883.             highlightTime = 30;
  4884.        
  4885.         for(i=0; i<ents.Size(); i+=1)
  4886.         {
  4887.             if(!ents[i].IsHighlighted())
  4888.             {
  4889.                 ents[i].SetHighlighted( true );
  4890.                 ents[i].PlayEffectSingle( 'medalion_detection_fx' );
  4891.                 ents[i].AddTimer( 'MedallionEffectOff', highlightTime );
  4892.             }
  4893.         }
  4894.     }
  4895.    
  4896.    
  4897.     public final function HighlightEnemies(range : float, optional highlightTime : float )
  4898.     {
  4899.         var ents : array<CGameplayEntity>;
  4900.         var i : int;
  4901.         var catComponent : CGameplayEffectsComponent;
  4902.  
  4903.         FindGameplayEntitiesInSphere(ents, GetWorldPosition(), range, 100, , FLAG_ExcludePlayer + FLAG_OnlyAliveActors);
  4904.  
  4905.         if(highlightTime == 0)
  4906.             highlightTime = 5;
  4907.        
  4908.         for(i=0; i<ents.Size(); i+=1)
  4909.         {
  4910.             if(IsRequiredAttitudeBetween(this, ents[i], true))
  4911.             {
  4912.                 catComponent = GetGameplayEffectsComponent(ents[i]);
  4913.                 if(catComponent)
  4914.                 {
  4915.                     catComponent.SetGameplayEffectFlag(EGEF_CatViewHiglight, true);
  4916.                     ents[i].AddTimer( 'EnemyHighlightOff', highlightTime, , , , , true );
  4917.                 }
  4918.             }
  4919.         }
  4920.     }  
  4921.    
  4922.     function SpawnMedallionEntity()
  4923.     {
  4924.         var rot                 : EulerAngles;
  4925.         var spawnedMedallion    : CEntity;
  4926.                
  4927.         spawnedMedallion = theGame.GetEntityByTag( 'new_Witcher_medallion_FX' );
  4928.        
  4929.         if ( !spawnedMedallion )
  4930.             theGame.CreateEntity( medallionEntity, GetWorldPosition(), rot, true, false );
  4931.     }
  4932.    
  4933.    
  4934.    
  4935.    
  4936.    
  4937.    
  4938.    
  4939.    
  4940.    
  4941.     public final function InterruptCombatFocusMode()
  4942.     {
  4943.         if( this.GetCurrentStateName() == 'CombatFocusMode_SelectSpot' )
  4944.         {  
  4945.             SetCanPlayHitAnim( true );
  4946.             PopState();
  4947.         }
  4948.     }
  4949.    
  4950.     public final function IsInDarkPlace() : bool
  4951.     {
  4952.         var envs : array< string >;
  4953.        
  4954.         if( FactsQuerySum( "tut_in_dark_place" ) )
  4955.         {
  4956.             return true;
  4957.         }
  4958.        
  4959.         GetActiveAreaEnvironmentDefinitions( envs );
  4960.        
  4961.         if( envs.Contains( 'env_novigrad_cave' ) || envs.Contains( 'cave_catacombs' ) )
  4962.         {
  4963.             return true;
  4964.         }
  4965.        
  4966.         return false;
  4967.     }
  4968.    
  4969.    
  4970.    
  4971.    
  4972.    
  4973.     private saved var selectedPotionSlotUpper, selectedPotionSlotLower : EEquipmentSlots;
  4974.     private var potionDoubleTapTimerRunning, potionDoubleTapSlotIsUpper : bool;
  4975.         default selectedPotionSlotUpper = EES_Potion1;
  4976.         default selectedPotionSlotLower = EES_Potion2;
  4977.         default potionDoubleTapTimerRunning = false;
  4978.    
  4979.     public final function SetPotionDoubleTapRunning(b : bool, optional isUpperSlot : bool)
  4980.     {
  4981.         if(b)
  4982.         {
  4983.             AddTimer('PotionDoubleTap', 0.3);
  4984.         }
  4985.         else
  4986.         {
  4987.             RemoveTimer('PotionDoubleTap');
  4988.         }
  4989.        
  4990.         potionDoubleTapTimerRunning = b;
  4991.         potionDoubleTapSlotIsUpper = isUpperSlot;
  4992.     }
  4993.    
  4994.     public final function IsPotionDoubleTapRunning() : bool
  4995.     {
  4996.         return potionDoubleTapTimerRunning;
  4997.     }
  4998.    
  4999.     timer function PotionDoubleTap(dt : float, id : int)
  5000.     {
  5001.         potionDoubleTapTimerRunning = false;
  5002.         OnPotionDrinkInput(potionDoubleTapSlotIsUpper);
  5003.     }
  5004.    
  5005.     public final function OnPotionDrinkInput(fromUpperSlot : bool)
  5006.     {
  5007.         var slot : EEquipmentSlots;
  5008.        
  5009.         if(fromUpperSlot)
  5010.             slot = GetSelectedPotionSlotUpper();
  5011.         else
  5012.             slot = GetSelectedPotionSlotLower();
  5013.            
  5014.         DrinkPotionFromSlot(slot);
  5015.     }
  5016.    
  5017.     public final function OnPotionDrinkKeyboardsInput(slot : EEquipmentSlots)
  5018.     {
  5019.         DrinkPotionFromSlot(slot);
  5020.     }
  5021.    
  5022.     private function DrinkPotionFromSlot(slot : EEquipmentSlots):void
  5023.     {
  5024.         var item : SItemUniqueId;      
  5025.         var hud : CR4ScriptedHud;
  5026.         var module : CR4HudModuleItemInfo;
  5027.        
  5028.         GetItemEquippedOnSlot(slot, item);
  5029.         if(inv.ItemHasTag(item, 'Edibles'))
  5030.         {
  5031.             //modSigns
  5032.             if(inv.ItemHasTag(item, 'Alcohol') || inv.ItemHasTag(item, 'Uncooked'))
  5033.             {
  5034.                 if(ToxicityLowEnoughToDrinkPotion(slot))
  5035.                     ConsumeItem(item);
  5036.                 else
  5037.                     SendToxicityTooHighMessage();
  5038.             }
  5039.             else
  5040.                 ConsumeItem(item);
  5041.         }
  5042.         else
  5043.         {          
  5044.             if (ToxicityLowEnoughToDrinkPotion(slot))
  5045.             {
  5046.                 DrinkPreparedPotion(slot);
  5047.             }
  5048.             else
  5049.             {
  5050.                 SendToxicityTooHighMessage();
  5051.             }
  5052.         }
  5053.        
  5054.         hud = (CR4ScriptedHud)theGame.GetHud();
  5055.         if ( hud )
  5056.         {
  5057.             module = (CR4HudModuleItemInfo)hud.GetHudModule("ItemInfoModule");
  5058.             if( module )
  5059.             {
  5060.                 module.ForceShowElement();
  5061.             }
  5062.         }
  5063.     }
  5064.    
  5065.     private function SendToxicityTooHighMessage()
  5066.     {
  5067.         var messageText : string;
  5068.         var language : string;
  5069.         var audioLanguage : string;
  5070.        
  5071.         if (GetHudMessagesSize() < 2)
  5072.         {
  5073.             messageText = GetLocStringByKeyExt("menu_cannot_perform_action_now") + " " + GetLocStringByKeyExt("panel_common_statistics_tooltip_current_toxicity");
  5074.            
  5075.             theGame.GetGameLanguageName(audioLanguage,language);
  5076.             if (language == "AR")
  5077.             {
  5078.                 messageText += (int)(abilityManager.GetStat(BCS_Toxicity, false)) + " / " +  (int)(abilityManager.GetStatMax(BCS_Toxicity)) + " :";
  5079.             }
  5080.             else
  5081.             {
  5082.                 messageText += ": " + (int)(abilityManager.GetStat(BCS_Toxicity, false)) + " / " +  (int)(abilityManager.GetStatMax(BCS_Toxicity));
  5083.             }
  5084.            
  5085.             DisplayHudMessage(messageText);
  5086.         }
  5087.         theSound.SoundEvent("gui_global_denied");
  5088.     }
  5089.    
  5090.     public final function GetSelectedPotionSlotUpper() : EEquipmentSlots
  5091.     {
  5092.         return selectedPotionSlotUpper;
  5093.     }
  5094.    
  5095.     public final function GetSelectedPotionSlotLower() : EEquipmentSlots
  5096.     {
  5097.         return selectedPotionSlotLower;
  5098.     }
  5099.    
  5100.    
  5101.     public final function FlipSelectedPotion(isUpperSlot : bool) : bool
  5102.     {
  5103.         if(isUpperSlot)
  5104.         {
  5105.             if(selectedPotionSlotUpper == EES_Potion1 && IsAnyItemEquippedOnSlot(EES_Potion3))
  5106.             {
  5107.                 selectedPotionSlotUpper = EES_Potion3;
  5108.                 return true;
  5109.             }
  5110.             else if(selectedPotionSlotUpper == EES_Potion3 && IsAnyItemEquippedOnSlot(EES_Potion1))
  5111.             {
  5112.                 selectedPotionSlotUpper = EES_Potion1;
  5113.                 return true;
  5114.             }
  5115.         }
  5116.         else
  5117.         {
  5118.             if(selectedPotionSlotLower == EES_Potion2 && IsAnyItemEquippedOnSlot(EES_Potion4))
  5119.             {
  5120.                 selectedPotionSlotLower = EES_Potion4;
  5121.                 return true;
  5122.             }
  5123.             else if(selectedPotionSlotLower == EES_Potion4 && IsAnyItemEquippedOnSlot(EES_Potion2))
  5124.             {
  5125.                 selectedPotionSlotLower = EES_Potion2;
  5126.                 return true;
  5127.             }
  5128.         }
  5129.        
  5130.         return false;
  5131.     }
  5132.    
  5133.     public final function AddBombThrowDelay( bombId : SItemUniqueId )
  5134.     {
  5135.         var slot : EEquipmentSlots;
  5136.        
  5137.         slot = GetItemSlot( bombId );
  5138.        
  5139.         if( slot == EES_Unused )
  5140.         {
  5141.             return;
  5142.         }
  5143.            
  5144.         if( slot == EES_Petard1 || slot == EES_Quickslot1 )
  5145.         {
  5146.             remainingBombThrowDelaySlot1 = theGame.params.BOMB_THROW_DELAY;
  5147.             AddTimer( 'BombDelay', 0.0f, true );
  5148.         }
  5149.         else if( slot == EES_Petard2 || slot == EES_Quickslot2 )
  5150.         {
  5151.             remainingBombThrowDelaySlot2 = theGame.params.BOMB_THROW_DELAY;
  5152.             AddTimer( 'BombDelay', 0.0f, true );
  5153.         }
  5154.         else
  5155.         {
  5156.             return;
  5157.         }
  5158.     }
  5159.    
  5160.     public final function GetBombDelay( slot : EEquipmentSlots ) : float
  5161.     {
  5162.         if( slot == EES_Petard1 || slot == EES_Quickslot1 )
  5163.         {
  5164.             return remainingBombThrowDelaySlot1;
  5165.         }
  5166.         else if( slot == EES_Petard2 || slot == EES_Quickslot2 )
  5167.         {
  5168.             return remainingBombThrowDelaySlot2;
  5169.         }
  5170.        
  5171.         return 0;
  5172.     }
  5173.    
  5174.     timer function BombDelay( dt : float, id : int )
  5175.     {
  5176.         remainingBombThrowDelaySlot1 = MaxF( 0.f , remainingBombThrowDelaySlot1 - dt );
  5177.         remainingBombThrowDelaySlot2 = MaxF( 0.f , remainingBombThrowDelaySlot2 - dt );
  5178.        
  5179.         if( remainingBombThrowDelaySlot1 <= 0.0f && remainingBombThrowDelaySlot2  <= 0.0f )
  5180.         {
  5181.             RemoveTimer('BombDelay');
  5182.         }
  5183.     }
  5184.    
  5185.     public function ResetCharacterDev()
  5186.     {
  5187.        
  5188.         UnequipItemFromSlot(EES_SkillMutagen1);
  5189.         UnequipItemFromSlot(EES_SkillMutagen2);
  5190.         UnequipItemFromSlot(EES_SkillMutagen3);
  5191.         UnequipItemFromSlot(EES_SkillMutagen4);
  5192.        
  5193.         levelManager.ResetCharacterDev();
  5194.         ((W3PlayerAbilityManager)abilityManager).ResetCharacterDev();      
  5195.     }
  5196.    
  5197.     public final function ResetMutationsDev()
  5198.     {
  5199.         levelManager.ResetMutationsDev();
  5200.         ((W3PlayerAbilityManager)abilityManager).ResetMutationsDev();
  5201.     }
  5202.    
  5203.     public final function GetHeldSword() : SItemUniqueId
  5204.     {
  5205.         var i : int;
  5206.         var weapons : array< SItemUniqueId >;
  5207.        
  5208.         weapons = inv.GetHeldWeapons();
  5209.         for( i=0; i<weapons.Size(); i+=1 )
  5210.         {
  5211.             if( inv.IsItemSilverSwordUsableByPlayer( weapons[i] ) || inv.IsItemSteelSwordUsableByPlayer( weapons[i] ) )
  5212.             {
  5213.                 return weapons[i];
  5214.             }
  5215.         }
  5216.        
  5217.         return GetInvalidUniqueId();
  5218.     }
  5219.    
  5220.     public function ConsumeItem( itemId : SItemUniqueId ) : bool
  5221.     {
  5222.         var itemName : name;
  5223.         var removedItem, willRemoveItem : bool;
  5224.         var edibles : array<SItemUniqueId>;
  5225.         var toSlot : EEquipmentSlots;
  5226.         var i : int;
  5227.         var equippedNewEdible : bool;
  5228.        
  5229.         itemName = inv.GetItemName( itemId );
  5230.        
  5231.         if (itemName == 'q111_imlerith_acorn' )
  5232.         {
  5233.             AddPoints(ESkillPoint, 2, true);
  5234.             removedItem = inv.RemoveItem( itemId, 1 );
  5235.             theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt("panel_character_popup_title_buy_skill") + "<br>" + GetLocStringByKeyExt("panel_character_availablepoints") + " +2");
  5236.             theSound.SoundEvent("gui_character_buy_skill");
  5237.         }
  5238.         else if ( itemName == 'Clearing Potion' )
  5239.         {
  5240.             ResetCharacterDev();
  5241.             removedItem = inv.RemoveItem( itemId, 1 );
  5242.             theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt("panel_character_popup_character_cleared") );
  5243.             theSound.SoundEvent("gui_character_synergy_effect");
  5244.         }
  5245.         else if ( itemName == 'Restoring Potion' )
  5246.         {
  5247.             ResetMutationsDev();
  5248.             removedItem = inv.RemoveItem( itemId, 1 );
  5249.             theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt("panel_character_popup_character_cleared") );
  5250.             theSound.SoundEvent("gui_character_synergy_effect");
  5251.         }
  5252.         else if(itemName == 'Wolf Hour')
  5253.         {
  5254.             removedItem = inv.RemoveItem( itemId, 1 );
  5255.             theSound.SoundEvent("gui_character_synergy_effect");
  5256.             AddEffectDefault(EET_WolfHour, thePlayer, 'wolf hour');
  5257.         }
  5258.         else if ( itemName == 'q704_ft_golden_egg' )
  5259.         {
  5260.             AddPoints(ESkillPoint, 1, true);
  5261.             removedItem = inv.RemoveItem( itemId, 1 );
  5262.             theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt("panel_character_popup_title_buy_skill") + "<br>" + GetLocStringByKeyExt("panel_character_availablepoints") + " +1");
  5263.             theSound.SoundEvent("gui_character_buy_skill");
  5264.         }
  5265.         else if ( itemName == 'mq7023_cake' )
  5266.         {
  5267.             this.AddAbility('mq7023_cake_vitality_bonus');
  5268.             removedItem = inv.RemoveItem( itemId, 1 );
  5269.             theSound.SoundEvent("gui_character_synergy_effect");
  5270.         }
  5271.         else
  5272.         {
  5273.             willRemoveItem = inv.GetItemQuantity(itemId) == 1 && !inv.ItemHasTag(itemId, 'InfiniteUse');
  5274.            
  5275.             if(willRemoveItem)
  5276.                 toSlot = GetItemSlot(itemId);
  5277.                
  5278.             removedItem = super.ConsumeItem(itemId);
  5279.            
  5280.             if(willRemoveItem && removedItem)
  5281.             {
  5282.                 edibles = inv.GetItemsByTag('Edibles');
  5283.                 equippedNewEdible = false;
  5284.                
  5285.                
  5286.                 for(i=0; i<edibles.Size(); i+=1)
  5287.                 {
  5288.                     if(!IsItemEquipped(edibles[i]) && !inv.ItemHasTag(edibles[i], 'Alcohol') && inv.GetItemName(edibles[i]) != 'Clearing Potion' && inv.GetItemName(edibles[i]) != 'Wolf Hour')
  5289.                     {
  5290.                         EquipItemInGivenSlot(edibles[i], toSlot, true, false);
  5291.                         equippedNewEdible = true;
  5292.                         break;
  5293.                     }
  5294.                 }
  5295.                
  5296.                
  5297.                 if(!equippedNewEdible)
  5298.                 {
  5299.                     for(i=0; i<edibles.Size(); i+=1)
  5300.                     {
  5301.                         if(!IsItemEquipped(edibles[i]) && inv.GetItemName(edibles[i]) != 'Clearing Potion' && inv.GetItemName(edibles[i]) != 'Wolf Hour')
  5302.                         {
  5303.                             EquipItemInGivenSlot(edibles[i], toSlot, true, false);
  5304.                             break;
  5305.                         }
  5306.                     }
  5307.                 }
  5308.             }
  5309.         }
  5310.        
  5311.         return removedItem;
  5312.     }
  5313.    
  5314.    
  5315.     public final function GetAlcoholForAlchemicalItemsRefill() : SItemUniqueId
  5316.     {
  5317.         var alcos : array<SItemUniqueId>;
  5318.         var id : SItemUniqueId;
  5319.         var i, price, minPrice : int;
  5320.        
  5321.         alcos = inv.GetItemsByTag(theGame.params.TAG_ALCHEMY_REFILL_ALCO);
  5322.        
  5323.         if(alcos.Size() > 0)
  5324.         {
  5325.             if(inv.ItemHasTag(alcos[0], theGame.params.TAG_INFINITE_USE))
  5326.                 return alcos[0];
  5327.                
  5328.             minPrice = inv.GetItemPrice(alcos[0]);
  5329.             price = minPrice;
  5330.             id = alcos[0];
  5331.            
  5332.             for(i=1; i<alcos.Size(); i+=1)
  5333.             {
  5334.                 if(inv.ItemHasTag(alcos[i], theGame.params.TAG_INFINITE_USE))
  5335.                     return alcos[i];
  5336.                
  5337.                 price = inv.GetItemPrice(alcos[i]);
  5338.                
  5339.                 if(price < minPrice)
  5340.                 {
  5341.                     minPrice = price;
  5342.                     id = alcos[i];
  5343.                 }
  5344.             }
  5345.            
  5346.             return id;
  5347.         }
  5348.        
  5349.         return GetInvalidUniqueId();
  5350.     }
  5351.    
  5352.     public final function ClearPreviouslyUsedBolt()
  5353.     {
  5354.         previouslyUsedBolt = GetInvalidUniqueId();
  5355.     }
  5356.    
  5357.     public function ShouldUseInfiniteWaterBolts() : bool
  5358.     {
  5359.         return GetCurrentStateName() == 'Swimming' || IsSwimming() || IsDiving();
  5360.     }
  5361.    
  5362.     public function GetCurrentInfiniteBoltName( optional forceBodkin : bool, optional forceHarpoon : bool ) : name
  5363.     {
  5364.         if(!forceBodkin && (forceHarpoon || ShouldUseInfiniteWaterBolts()) )
  5365.         {
  5366.             return 'Harpoon Bolt';
  5367.         }
  5368.         return 'Bodkin Bolt';
  5369.     }
  5370.    
  5371.    
  5372.     public final function AddAndEquipInfiniteBolt(optional forceBodkin : bool, optional forceHarpoon : bool)
  5373.     {
  5374.         var bolt, bodkins, harpoons : array<SItemUniqueId>;
  5375.         var boltItemName : name;
  5376.         var i : int;
  5377.        
  5378.        
  5379.         bodkins = inv.GetItemsByName('Bodkin Bolt');
  5380.         harpoons = inv.GetItemsByName('Harpoon Bolt');
  5381.        
  5382.         for(i=bodkins.Size()-1; i>=0; i-=1)
  5383.             inv.RemoveItem(bodkins[i], inv.GetItemQuantity(bodkins[i]) );
  5384.            
  5385.         for(i=harpoons.Size()-1; i>=0; i-=1)
  5386.             inv.RemoveItem(harpoons[i], inv.GetItemQuantity(harpoons[i]) );
  5387.            
  5388.        
  5389.        
  5390.         boltItemName = GetCurrentInfiniteBoltName( forceBodkin, forceHarpoon );
  5391.        
  5392.        
  5393.         if(boltItemName == 'Bodkin Bolt' && inv.IsIdValid(previouslyUsedBolt))
  5394.         {
  5395.             bolt.PushBack(previouslyUsedBolt);
  5396.         }
  5397.         else
  5398.         {
  5399.            
  5400.             bolt = inv.AddAnItem(boltItemName, 1, true, true);
  5401.            
  5402.            
  5403.             if(boltItemName == 'Harpoon Bolt')
  5404.             {
  5405.                 GetItemEquippedOnSlot(EES_Bolt, previouslyUsedBolt);
  5406.             }
  5407.         }
  5408.        
  5409.         EquipItem(bolt[0], EES_Bolt);
  5410.     }
  5411.    
  5412.    
  5413.     event OnItemGiven(data : SItemChangedData)
  5414.     {
  5415.         var m_guiManager    : CR4GuiManager;
  5416.        
  5417.         super.OnItemGiven(data);
  5418.        
  5419.        
  5420.         if(!inv)
  5421.             inv = GetInventory();
  5422.        
  5423.        
  5424.         if(inv.IsItemEncumbranceItem(data.ids[0]))
  5425.             UpdateEncumbrance();
  5426.        
  5427.         m_guiManager = theGame.GetGuiManager();
  5428.         if(m_guiManager)
  5429.             m_guiManager.RegisterNewItem(data.ids[0]);
  5430.     }
  5431.        
  5432.    
  5433.     public final function CheckForFullyArmedAchievement()
  5434.     {
  5435.         if( HasAllItemsFromSet(theGame.params.ITEM_SET_TAG_BEAR) || HasAllItemsFromSet(theGame.params.ITEM_SET_TAG_GRYPHON) ||
  5436.             HasAllItemsFromSet(theGame.params.ITEM_SET_TAG_LYNX) || HasAllItemsFromSet(theGame.params.ITEM_SET_TAG_WOLF) ||
  5437.             /* modSigns */
  5438.             /*HasAllItemsFromSet(theGame.params.ITEM_SET_TAG_VIPER)*/
  5439.             HasAllItemsFromSet(theGame.params.ITEM_SET_TAG_BEAR_MINOR) || HasAllItemsFromSet(theGame.params.ITEM_SET_TAG_GRYPHON_MINOR) ||
  5440.             HasAllItemsFromSet(theGame.params.ITEM_SET_TAG_LYNX_MINOR) || HasAllItemsFromSet(theGame.params.ITEM_SET_TAG_WOLF_MINOR)
  5441.         )
  5442.         {
  5443.             theGame.GetGamerProfile().AddAchievement(EA_FullyArmed);
  5444.         }
  5445.     }
  5446.    
  5447.    
  5448.     public final function HasAllItemsFromSet(setItemTag : name) : bool
  5449.     {
  5450.         var item : SItemUniqueId;
  5451.        
  5452.         if(!GetItemEquippedOnSlot(EES_SteelSword, item) || !inv.ItemHasTag(item, setItemTag))
  5453.             return false;
  5454.        
  5455.         if(!GetItemEquippedOnSlot(EES_SilverSword, item) || !inv.ItemHasTag(item, setItemTag))
  5456.             return false;
  5457.            
  5458.         if(!GetItemEquippedOnSlot(EES_Boots, item) || !inv.ItemHasTag(item, setItemTag))
  5459.             return false;
  5460.            
  5461.         if(!GetItemEquippedOnSlot(EES_Pants, item) || !inv.ItemHasTag(item, setItemTag))
  5462.             return false;
  5463.            
  5464.         if(!GetItemEquippedOnSlot(EES_Gloves, item) || !inv.ItemHasTag(item, setItemTag))
  5465.             return false;
  5466.            
  5467.         if(!GetItemEquippedOnSlot(EES_Armor, item) || !inv.ItemHasTag(item, setItemTag))
  5468.             return false;
  5469.            
  5470.        
  5471.         /*if(setItemTag == theGame.params.ITEM_SET_TAG_BEAR || setItemTag == theGame.params.ITEM_SET_TAG_LYNX)
  5472.         {
  5473.             if(!GetItemEquippedOnSlot(EES_RangedWeapon, item) || !inv.ItemHasTag(item, setItemTag))
  5474.                 return false;
  5475.         }*/ //modSigns: removed due to set changes
  5476.  
  5477.         return true;
  5478.     }
  5479.    
  5480.    
  5481.    
  5482.    
  5483.     public function GetTotalArmor() : SAbilityAttributeValue
  5484.     {
  5485.         var armor : SAbilityAttributeValue;
  5486.         var armorItem : SItemUniqueId;
  5487.        
  5488.         armor = super.GetTotalArmor();
  5489.        
  5490.         if(GetItemEquippedOnSlot(EES_Armor, armorItem))
  5491.         {
  5492.            
  5493.             armor -= inv.GetItemAttributeValue(armorItem, theGame.params.ARMOR_VALUE_NAME);
  5494.            
  5495.            
  5496.             armor += inv.GetItemArmorTotal(armorItem);         
  5497.         }
  5498.        
  5499.         if(GetItemEquippedOnSlot(EES_Pants, armorItem))
  5500.         {
  5501.            
  5502.             armor -= inv.GetItemAttributeValue(armorItem, theGame.params.ARMOR_VALUE_NAME);
  5503.            
  5504.            
  5505.             armor += inv.GetItemArmorTotal(armorItem);         
  5506.         }
  5507.            
  5508.         if(GetItemEquippedOnSlot(EES_Boots, armorItem))
  5509.         {
  5510.            
  5511.             armor -= inv.GetItemAttributeValue(armorItem, theGame.params.ARMOR_VALUE_NAME);
  5512.            
  5513.            
  5514.             armor += inv.GetItemArmorTotal(armorItem);         
  5515.         }
  5516.            
  5517.         if(GetItemEquippedOnSlot(EES_Gloves, armorItem))
  5518.         {
  5519.            
  5520.             armor -= inv.GetItemAttributeValue(armorItem, theGame.params.ARMOR_VALUE_NAME);
  5521.            
  5522.            
  5523.             armor += inv.GetItemArmorTotal(armorItem);         
  5524.         }
  5525.            
  5526.         return armor;
  5527.     }
  5528.    
  5529.    
  5530.    
  5531.     public function ReduceArmorDurability() : EEquipmentSlots
  5532.     {
  5533.         var r, sum : int;
  5534.         var slot : EEquipmentSlots;
  5535.         var id : SItemUniqueId;
  5536.         var prevDurMult, currDurMult, ratio : float;
  5537.    
  5538.        
  5539.         sum = theGame.params.DURABILITY_ARMOR_CHEST_WEIGHT;
  5540.         sum += theGame.params.DURABILITY_ARMOR_PANTS_WEIGHT;
  5541.         sum += theGame.params.DURABILITY_ARMOR_GLOVES_WEIGHT;
  5542.         sum += theGame.params.DURABILITY_ARMOR_BOOTS_WEIGHT;
  5543.         sum += theGame.params.DURABILITY_ARMOR_MISS_WEIGHT;
  5544.        
  5545.         r = RandRange(sum);
  5546.        
  5547.         if(r < theGame.params.DURABILITY_ARMOR_CHEST_WEIGHT)
  5548.             slot = EES_Armor;
  5549.         else if (r < theGame.params.DURABILITY_ARMOR_CHEST_WEIGHT + theGame.params.DURABILITY_ARMOR_PANTS_WEIGHT)
  5550.             slot = EES_Pants;
  5551.         else if (r < theGame.params.DURABILITY_ARMOR_CHEST_WEIGHT + theGame.params.DURABILITY_ARMOR_PANTS_WEIGHT + theGame.params.DURABILITY_ARMOR_GLOVES_WEIGHT)
  5552.             slot = EES_Gloves;
  5553.         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)
  5554.             slot = EES_Boots;
  5555.         else
  5556.             return EES_InvalidSlot;                
  5557.        
  5558.         GetItemEquippedOnSlot(slot, id);               
  5559.         ratio = inv.GetItemDurabilityRatio(id);    
  5560.         if(inv.ReduceItemDurability(id))           
  5561.         {
  5562.             prevDurMult = theGame.params.GetDurabilityMultiplier(ratio, false);
  5563.            
  5564.             ratio = inv.GetItemDurabilityRatio(id);
  5565.             currDurMult = theGame.params.GetDurabilityMultiplier(ratio, false);
  5566.            
  5567.             if(currDurMult != prevDurMult)
  5568.             {
  5569.                
  5570.                
  5571.                
  5572.                
  5573.             }
  5574.                
  5575.             return slot;
  5576.         }
  5577.        
  5578.         return EES_InvalidSlot;
  5579.     }
  5580.    
  5581.    
  5582.     public function DismantleItem(dismantledItem : SItemUniqueId, toolItem : SItemUniqueId) : bool
  5583.     {
  5584.         var parts : array<SItemParts>;
  5585.         var i : int;
  5586.        
  5587.         if(!inv.IsItemDismantleKit(toolItem))
  5588.             return false;
  5589.        
  5590.         parts = inv.GetItemRecyclingParts(dismantledItem);
  5591.        
  5592.         if(parts.Size() <= 0)
  5593.             return false;
  5594.            
  5595.         for(i=0; i<parts.Size(); i+=1)
  5596.             inv.AddAnItem(parts[i].itemName, parts[i].quantity, true, false);
  5597.            
  5598.         inv.RemoveItem(toolItem);
  5599.         inv.RemoveItem(dismantledItem);
  5600.         return true;
  5601.     }
  5602.    
  5603.    
  5604.     public function GetItemEquippedOnSlot(slot : EEquipmentSlots, out item : SItemUniqueId) : bool
  5605.     {
  5606.         if(slot == EES_InvalidSlot || slot < 0 || slot > EnumGetMax('EEquipmentSlots'))
  5607.             return false;
  5608.        
  5609.         item = itemSlots[slot];
  5610.        
  5611.         return inv.IsIdValid(item);
  5612.     }
  5613.    
  5614.    
  5615.     public function GetItemSlotByItemName(itemName : name) : EEquipmentSlots
  5616.     {
  5617.         var ids : array<SItemUniqueId>;
  5618.         var i : int;
  5619.         var slot : EEquipmentSlots;
  5620.        
  5621.         ids = inv.GetItemsByName(itemName);
  5622.         for(i=0; i<ids.Size(); i+=1)
  5623.         {
  5624.             slot = GetItemSlot(ids[i]);
  5625.             if(slot != EES_InvalidSlot)
  5626.                 return slot;
  5627.         }
  5628.        
  5629.         return EES_InvalidSlot;
  5630.     }
  5631.    
  5632.    
  5633.     public function GetItemSlot(item : SItemUniqueId) : EEquipmentSlots
  5634.     {
  5635.         var i : int;
  5636.        
  5637.         if(!inv.IsIdValid(item))
  5638.             return EES_InvalidSlot;
  5639.            
  5640.         for(i=0; i<itemSlots.Size(); i+=1)
  5641.             if(itemSlots[i] == item)
  5642.                 return i;
  5643.        
  5644.         return EES_InvalidSlot;
  5645.     }
  5646.    
  5647.     public function GetEquippedItems() : array<SItemUniqueId>
  5648.     {
  5649.         return itemSlots;
  5650.     }
  5651.    
  5652.     public function IsItemEquipped(item : SItemUniqueId) : bool
  5653.     {
  5654.         if(!inv.IsIdValid(item))
  5655.             return false;
  5656.            
  5657.         return itemSlots.Contains(item);
  5658.     }
  5659.  
  5660.     public function IsItemHeld(item : SItemUniqueId) : bool
  5661.     {
  5662.         if(!inv.IsIdValid(item))
  5663.             return false;
  5664.            
  5665.         return inv.IsItemHeld(item);
  5666.     }
  5667.  
  5668.    
  5669.     public function IsAnyItemEquippedOnSlot(slot : EEquipmentSlots) : bool
  5670.     {
  5671.         if(slot == EES_InvalidSlot || slot < 0 || slot > EnumGetMax('EEquipmentSlots'))
  5672.             return false;
  5673.            
  5674.         return inv.IsIdValid(itemSlots[slot]);
  5675.     }
  5676.    
  5677.    
  5678.     public function GetFreeQuickslot() : EEquipmentSlots
  5679.     {
  5680.         if(!inv.IsIdValid(itemSlots[EES_Quickslot1]))       return EES_Quickslot1;
  5681.         if(!inv.IsIdValid(itemSlots[EES_Quickslot2]))       return EES_Quickslot2;
  5682.        
  5683.        
  5684.         return EES_InvalidSlot;
  5685.     }
  5686.    
  5687.    
  5688.     event OnEquipItemRequested(item : SItemUniqueId, ignoreMount : bool)
  5689.     {
  5690.         var slot : EEquipmentSlots;
  5691.        
  5692.         if(inv.IsIdValid(item))
  5693.         {
  5694.             slot = inv.GetSlotForItemId(item);
  5695.                
  5696.             if (slot != EES_InvalidSlot)
  5697.             {
  5698.                
  5699.                
  5700.                 EquipItemInGivenSlot(item, slot, ignoreMount);
  5701.             }
  5702.         }
  5703.     }
  5704.    
  5705.     event OnUnequipItemRequested(item : SItemUniqueId)
  5706.     {
  5707.         UnequipItem(item);
  5708.     }
  5709.    
  5710.    
  5711.     public function EquipItem(item : SItemUniqueId, optional slot : EEquipmentSlots, optional toHand : bool) : bool
  5712.     {
  5713.         if(!inv.IsIdValid(item))
  5714.             return false;
  5715.            
  5716.         if(slot == EES_InvalidSlot)
  5717.         {
  5718.             slot = inv.GetSlotForItemId(item);
  5719.            
  5720.             if(slot == EES_InvalidSlot)
  5721.                 return false;
  5722.         }
  5723.        
  5724.         ForceSoundAppearanceUpdate();
  5725.        
  5726.         return EquipItemInGivenSlot(item, slot, false, toHand);
  5727.     }
  5728.    
  5729.     protected function ShouldMount(slot : EEquipmentSlots, item : SItemUniqueId, category : name):bool
  5730.     {
  5731.        
  5732.        
  5733.         return !IsSlotPotionMutagen(slot) && category != 'usable' && category != 'potion' && category != 'petard' && !inv.ItemHasTag(item, 'PlayerUnwearable');
  5734.     }
  5735.        
  5736.     protected function ShouldMountItemWithName( itemName: name ): bool
  5737.     {
  5738.         var slot : EEquipmentSlots;
  5739.         var items : array<SItemUniqueId>;
  5740.         var category : name;
  5741.         var i : int;
  5742.        
  5743.         items = inv.GetItemsByName( itemName );
  5744.        
  5745.         category = inv.GetItemCategory( items[0] );
  5746.        
  5747.         slot = GetItemSlot( items[0] );
  5748.        
  5749.         return ShouldMount( slot, items[0], category );
  5750.     }  
  5751.    
  5752.     public function GetMountableItems( out items : array< SItemUniqueId > )
  5753.     {
  5754.         var i : int;
  5755.         var mountable : bool;
  5756.         var mountableItems : array< SItemUniqueId >;
  5757.         var slot : EEquipmentSlots;
  5758.         var category : name;
  5759.         var item: SItemUniqueId;
  5760.        
  5761.         for ( i = 0; i < items.Size(); i += 1 )
  5762.         {
  5763.             item = items[i];
  5764.        
  5765.             category = inv.GetItemCategory( item );
  5766.        
  5767.             slot = GetItemSlot( item );
  5768.        
  5769.             mountable = ShouldMount( slot, item, category );
  5770.        
  5771.             if ( mountable )
  5772.             {
  5773.                 mountableItems.PushBack( items[ i ] );
  5774.             }
  5775.         }
  5776.         items = mountableItems;
  5777.     }
  5778.    
  5779.     public final function AddAndEquipItem( item : name ) : bool
  5780.     {
  5781.         var ids : array< SItemUniqueId >;
  5782.        
  5783.         ids = inv.AddAnItem( item );
  5784.         if( inv.IsIdValid( ids[ 0 ] ) )
  5785.         {
  5786.             return EquipItem( ids[ 0 ] );
  5787.         }
  5788.        
  5789.         return false;
  5790.     }
  5791.    
  5792.     public final function AddQuestMarkedSelectedQuickslotItem( sel : SSelectedQuickslotItem )
  5793.     {
  5794.         questMarkedSelectedQuickslotItems.PushBack( sel );
  5795.     }
  5796.    
  5797.     public final function GetQuestMarkedSelectedQuickslotItem( sourceName : name ) : SItemUniqueId
  5798.     {
  5799.         var i : int;
  5800.        
  5801.         for( i=0; i<questMarkedSelectedQuickslotItems.Size(); i+=1 )
  5802.         {
  5803.             if( questMarkedSelectedQuickslotItems[i].sourceName == sourceName )
  5804.             {
  5805.                 return questMarkedSelectedQuickslotItems[i].itemID;
  5806.             }
  5807.         }
  5808.        
  5809.         return GetInvalidUniqueId();
  5810.     }
  5811.    
  5812.     public final function SwapEquippedItems(slot1 : EEquipmentSlots, slot2 : EEquipmentSlots)
  5813.     {
  5814.         var temp : SItemUniqueId;
  5815.         var pam : W3PlayerAbilityManager;
  5816.        
  5817.         temp = itemSlots[slot1];
  5818.         itemSlots[slot1] = itemSlots[slot2];
  5819.         itemSlots[slot2] = temp;
  5820.        
  5821.         if(IsSlotSkillMutagen(slot1))
  5822.         {
  5823.             pam = (W3PlayerAbilityManager)abilityManager;
  5824.             if(pam)
  5825.                 pam.OnSwappedMutagensPost(itemSlots[slot1], itemSlots[slot2]);
  5826.         }
  5827.     }
  5828.    
  5829.     public final function GetSlotForEquippedItem( itemID : SItemUniqueId ) : EEquipmentSlots
  5830.     {
  5831.         var i : int;
  5832.        
  5833.         for( i=0; i<itemSlots.Size(); i+=1 )
  5834.         {
  5835.             if( itemSlots[i] == itemID )
  5836.             {
  5837.                 return i;
  5838.             }
  5839.         }
  5840.        
  5841.         return EES_InvalidSlot;
  5842.     }
  5843.    
  5844.     public function EquipItemInGivenSlot(item : SItemUniqueId, slot : EEquipmentSlots, ignoreMounting : bool, optional toHand : bool) : bool
  5845.     {          
  5846.         var i, groupID, quantity : int;
  5847.         var fistsID : array<SItemUniqueId>;
  5848.         var pam : W3PlayerAbilityManager;
  5849.         var isSkillMutagen : bool;     
  5850.         var armorEntity : CItemEntity;
  5851.         var armorMeshComponent : CComponent;
  5852.         var armorSoundIdentification : name;
  5853.         var category : name;
  5854.         var prevSkillColor : ESkillColor;
  5855.         var containedAbilities : array<name>;
  5856.         var dm : CDefinitionsManagerAccessor;
  5857.         var armorType : EArmorType;
  5858.         var otherMask, previousItemInSlot : SItemUniqueId;
  5859.         var tutStatePot : W3TutorialManagerUIHandlerStatePotions;
  5860.         var tutStateFood : W3TutorialManagerUIHandlerStateFood;
  5861.         var tutStateSecondPotionEquip : W3TutorialManagerUIHandlerStateSecondPotionEquip;
  5862.         var boltItem : SItemUniqueId;
  5863.         var aerondight : W3Effect_Aerondight;
  5864.        
  5865.         if(!inv.IsIdValid(item))
  5866.         {
  5867.             LogAssert(false, "W3PlayerWitcher.EquipItemInGivenSlot: invalid item");
  5868.             return false;
  5869.         }
  5870.         if(slot == EES_InvalidSlot || slot == EES_HorseBlinders || slot == EES_HorseSaddle || slot == EES_HorseBag || slot == EES_HorseTrophy)
  5871.         {
  5872.             LogAssert(false, "W3PlayerWitcher.EquipItem: Cannot equip item <<" + inv.GetItemName(item) + ">> - provided slot <<" + slot + ">> is invalid");
  5873.             return false;
  5874.         }
  5875.         if(itemSlots[slot] == item)
  5876.         {
  5877.             return true;
  5878.         }  
  5879.        
  5880.         if(!HasRequiredLevelToEquipItem(item))
  5881.         {
  5882.            
  5883.             return false;
  5884.         }
  5885.        
  5886.         if(inv.ItemHasTag(item, 'PhantomWeapon') && !GetPhantomWeaponMgr())
  5887.         {
  5888.             InitPhantomWeaponMgr();
  5889.         }
  5890.        
  5891.        
  5892.         if( slot == EES_SilverSword && inv.ItemHasTag( item, 'Aerondight' ) )
  5893.         {
  5894.             AddEffectDefault( EET_Aerondight, this, "Aerondight" );
  5895.            
  5896.            
  5897.             aerondight = (W3Effect_Aerondight)GetBuff( EET_Aerondight );
  5898.             aerondight.Pause( 'ManageAerondightBuff' );
  5899.         }      
  5900.        
  5901.        
  5902.         previousItemInSlot = itemSlots[slot];
  5903.         if( IsItemEquipped(item))
  5904.         {
  5905.             SwapEquippedItems(slot, GetItemSlot(item));
  5906.             return true;
  5907.         }
  5908.        
  5909.        
  5910.         isSkillMutagen = IsSlotSkillMutagen(slot);
  5911.         if(isSkillMutagen)
  5912.         {
  5913.             pam = (W3PlayerAbilityManager)abilityManager;
  5914.             if(!pam.IsSkillMutagenSlotUnlocked(slot))
  5915.             {
  5916.                 return false;
  5917.             }
  5918.         }
  5919.        
  5920.        
  5921.         if(inv.IsIdValid(previousItemInSlot))
  5922.         {          
  5923.             if(!UnequipItemFromSlot(slot, true))
  5924.             {
  5925.                 LogAssert(false, "W3PlayerWitcher.EquipItem: Cannot equip item <<" + inv.GetItemName(item) + ">> !!");
  5926.                 return false;
  5927.             }
  5928.         }      
  5929.        
  5930.        
  5931.         if(inv.IsItemMask(item))
  5932.         {
  5933.             if(slot == EES_Quickslot1)
  5934.                 GetItemEquippedOnSlot(EES_Quickslot2, otherMask);
  5935.             else
  5936.                 GetItemEquippedOnSlot(EES_Quickslot1, otherMask);
  5937.                
  5938.             if(inv.IsItemMask(otherMask))
  5939.                 UnequipItem(otherMask);
  5940.         }
  5941.        
  5942.         if(isSkillMutagen)
  5943.         {
  5944.             groupID = pam.GetSkillGroupIdOfMutagenSlot(slot);
  5945.             prevSkillColor = pam.GetSkillGroupColor(groupID);
  5946.         }
  5947.        
  5948.         itemSlots[slot] = item;
  5949.        
  5950.         category = inv.GetItemCategory( item );
  5951.    
  5952.        
  5953.         if( !ignoreMounting && ShouldMount(slot, item, category) )
  5954.         {
  5955.            
  5956.             inv.MountItem( item, toHand, IsSlotSkillMutagen( slot ) );
  5957.         }      
  5958.        
  5959.         theTelemetry.LogWithLabelAndValue( TE_INV_ITEM_EQUIPPED, inv.GetItemName(item), slot );
  5960.                
  5961.         if(slot == EES_RangedWeapon)
  5962.         {          
  5963.             rangedWeapon = ( Crossbow )( inv.GetItemEntityUnsafe(item) );
  5964.             if(!rangedWeapon)
  5965.                 AddTimer('DelayedOnItemMount', 0.1, true);
  5966.            
  5967.             if ( IsSwimming() || IsDiving() )
  5968.             {
  5969.                 GetItemEquippedOnSlot(EES_Bolt, boltItem);
  5970.                
  5971.                 if(inv.IsIdValid(boltItem))
  5972.                 {
  5973.                     if ( !inv.ItemHasTag(boltItem, 'UnderwaterAmmo' ))
  5974.                     {
  5975.                         AddAndEquipInfiniteBolt(false, true);
  5976.                     }
  5977.                 }
  5978.                 else if(!IsAnyItemEquippedOnSlot(EES_Bolt))
  5979.                 {
  5980.                     AddAndEquipInfiniteBolt(false, true);
  5981.                 }
  5982.             }
  5983.            
  5984.             else if(!IsAnyItemEquippedOnSlot(EES_Bolt))
  5985.                 AddAndEquipInfiniteBolt();
  5986.         }
  5987.         else if(slot == EES_Bolt)
  5988.         {
  5989.             if(rangedWeapon)
  5990.             {   if ( !IsSwimming() || !IsDiving() )
  5991.                 {
  5992.                     rangedWeapon.OnReplaceAmmo();
  5993.                     rangedWeapon.OnWeaponReload();
  5994.                 }
  5995.                 else
  5996.                 {
  5997.                     DisplayHudMessage(GetLocStringByKeyExt( "menu_cannot_perform_action_now" ));
  5998.                 }
  5999.             }
  6000.         }      
  6001.        
  6002.         else if(isSkillMutagen)
  6003.         {
  6004.             theGame.GetGuiManager().IgnoreNewItemNotifications( true );
  6005.            
  6006.            
  6007.             quantity = inv.GetItemQuantity( item );
  6008.             if( quantity > 1 )
  6009.             {
  6010.                 inv.SplitItem( item, quantity - 1 );
  6011.             }
  6012.            
  6013.             pam.OnSkillMutagenEquipped(item, slot, prevSkillColor);
  6014.             LogSkillColors("Mutagen <<" + inv.GetItemName(item) + ">> equipped to slot <<" + slot + ">>");
  6015.             LogSkillColors("Group bonus color is now <<" + pam.GetSkillGroupColor(groupID) + ">>");
  6016.             LogSkillColors("");
  6017.            
  6018.             theGame.GetGuiManager().IgnoreNewItemNotifications( false );
  6019.         }
  6020.         else if(slot == EES_Gloves && HasWeaponDrawn(false))
  6021.         {
  6022.             PlayRuneword4FX(PW_Steel);
  6023.             PlayRuneword4FX(PW_Silver);
  6024.         }
  6025.        
  6026.         else if( ( slot == EES_Petard1 || slot == EES_Petard2 ) && inv.IsItemBomb( GetSelectedItemId() ) )
  6027.         {
  6028.             SelectQuickslotItem( slot );
  6029.         }
  6030.  
  6031.        
  6032.         if(inv.ItemHasAbility(item, 'MA_HtH'))
  6033.         {
  6034.             inv.GetItemContainedAbilities(item, containedAbilities);
  6035.             fistsID = inv.GetItemsByName('fists');
  6036.             dm = theGame.GetDefinitionsManager();
  6037.             for(i=0; i<containedAbilities.Size(); i+=1)
  6038.             {
  6039.                 if(dm.AbilityHasTag(containedAbilities[i], 'MA_HtH'))
  6040.                 {                  
  6041.                     inv.AddItemCraftedAbility(fistsID[0], containedAbilities[i], true);
  6042.                 }
  6043.             }
  6044.         }      
  6045.        
  6046.        
  6047.         if(inv.IsItemAnyArmor(item))
  6048.         {
  6049.             armorType = inv.GetArmorType(item);
  6050.             pam = (W3PlayerAbilityManager)abilityManager;
  6051.            
  6052.             pam.ManageSetArmorTypeBonus(); //modSigns
  6053.            
  6054.             if(armorType == EAT_Light)
  6055.             {
  6056.                 if(CanUseSkill(S_Perk_05))
  6057.                     pam.SetPerkArmorBonus(S_Perk_05);
  6058.             }
  6059.             else if(armorType == EAT_Medium)
  6060.             {
  6061.                 if(CanUseSkill(S_Perk_06))
  6062.                     pam.SetPerkArmorBonus(S_Perk_06);
  6063.             }
  6064.             else if(armorType == EAT_Heavy)
  6065.             {
  6066.                 if(CanUseSkill(S_Perk_07))
  6067.                     pam.SetPerkArmorBonus(S_Perk_07);
  6068.             }
  6069.         }
  6070.        
  6071.        
  6072.         UpdateItemSetBonuses( item, true );
  6073.                
  6074.        
  6075.         theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_OnItemEquipped );
  6076.    
  6077.        
  6078.         if(ShouldProcessTutorial('TutorialPotionCanEquip3'))
  6079.         {
  6080.             if(IsSlotPotionSlot(slot))
  6081.             {
  6082.                 tutStatePot = (W3TutorialManagerUIHandlerStatePotions)theGame.GetTutorialSystem().uiHandler.GetCurrentState();
  6083.                 if(tutStatePot)
  6084.                 {
  6085.                     tutStatePot.OnPotionEquipped(inv.GetItemName(item));
  6086.                 }
  6087.                
  6088.                 tutStateSecondPotionEquip = (W3TutorialManagerUIHandlerStateSecondPotionEquip)theGame.GetTutorialSystem().uiHandler.GetCurrentState();
  6089.                 if(tutStateSecondPotionEquip)
  6090.                 {
  6091.                     tutStateSecondPotionEquip.OnPotionEquipped(inv.GetItemName(item));
  6092.                 }
  6093.                
  6094.             }
  6095.         }
  6096.        
  6097.         if(ShouldProcessTutorial('TutorialFoodSelectTab'))
  6098.         {
  6099.             if( IsSlotPotionSlot(slot) && inv.IsItemFood(item))
  6100.             {
  6101.                 tutStateFood = (W3TutorialManagerUIHandlerStateFood)theGame.GetTutorialSystem().uiHandler.GetCurrentState();
  6102.                 if(tutStateFood)
  6103.                 {
  6104.                     tutStateFood.OnFoodEquipped();
  6105.                 }
  6106.             }
  6107.         }
  6108.        
  6109.        
  6110.         if(inv.IsItemSetItem(item))
  6111.         {
  6112.             CheckForFullyArmedAchievement();   
  6113.         }
  6114.        
  6115.         return true;
  6116.     }
  6117.  
  6118.     private function CheckHairItem()
  6119.     {
  6120.         var ids : array<SItemUniqueId>;
  6121.         var i   : int;
  6122.         var itemName : name;
  6123.         var hairApplied : bool;
  6124.        
  6125.         ids = inv.GetItemsByCategory('hair');
  6126.        
  6127.         for(i=0; i<ids.Size(); i+= 1)
  6128.         {
  6129.             itemName = inv.GetItemName( ids[i] );
  6130.            
  6131.             if( itemName != 'Preview Hair' )
  6132.             {
  6133.                 if( hairApplied == false )
  6134.                 {
  6135.                     inv.MountItem( ids[i], false );
  6136.                     hairApplied = true;
  6137.                 }
  6138.                 else
  6139.                 {
  6140.                     inv.RemoveItem( ids[i], 1 );
  6141.                 }
  6142.                
  6143.             }
  6144.         }
  6145.        
  6146.         if( hairApplied == false )
  6147.         {
  6148.             ids = inv.AddAnItem('Half With Tail Hairstyle', 1, true, false);
  6149.             inv.MountItem( ids[0], false );
  6150.         }
  6151.        
  6152.     }
  6153.  
  6154.    
  6155.     timer function DelayedOnItemMount( dt : float, id : int )
  6156.     {
  6157.         var crossbowID : SItemUniqueId;
  6158.         var invent : CInventoryComponent;
  6159.        
  6160.         invent = GetInventory();
  6161.         if(!invent)
  6162.             return;
  6163.        
  6164.        
  6165.         GetItemEquippedOnSlot(EES_RangedWeapon, crossbowID);
  6166.                
  6167.         if(invent.IsIdValid(crossbowID))
  6168.         {
  6169.            
  6170.             rangedWeapon = ( Crossbow )(invent.GetItemEntityUnsafe(crossbowID) );
  6171.            
  6172.             if(rangedWeapon)
  6173.             {
  6174.                
  6175.                 RemoveTimer('DelayedOnItemMount');
  6176.             }
  6177.         }
  6178.         else
  6179.         {
  6180.            
  6181.             RemoveTimer('DelayedOnItemMount');
  6182.         }
  6183.     }
  6184.  
  6185.     public function GetHeldItems() : array<SItemUniqueId>
  6186.     {
  6187.         var items : array<SItemUniqueId>;
  6188.         var item : SItemUniqueId;
  6189.    
  6190.         if( inv.GetItemEquippedOnSlot(EES_SilverSword, item) && inv.IsItemHeld(item))
  6191.             items.PushBack(item);
  6192.            
  6193.         if( inv.GetItemEquippedOnSlot(EES_SteelSword, item) && inv.IsItemHeld(item))
  6194.             items.PushBack(item);
  6195.  
  6196.         if( inv.GetItemEquippedOnSlot(EES_RangedWeapon, item) && inv.IsItemHeld(item))
  6197.             items.PushBack(item);
  6198.  
  6199.         if( inv.GetItemEquippedOnSlot(EES_Quickslot1, item) && inv.IsItemHeld(item))
  6200.             items.PushBack(item);
  6201.  
  6202.         if( inv.GetItemEquippedOnSlot(EES_Quickslot2, item) && inv.IsItemHeld(item))
  6203.             items.PushBack(item);
  6204.  
  6205.         if( inv.GetItemEquippedOnSlot(EES_Petard1, item) && inv.IsItemHeld(item))
  6206.             items.PushBack(item);
  6207.  
  6208.         if( inv.GetItemEquippedOnSlot(EES_Petard2, item) && inv.IsItemHeld(item))
  6209.             items.PushBack(item);
  6210.  
  6211.         return items;          
  6212.     }
  6213.    
  6214.     public function MoveMutagenToSlot( item : SItemUniqueId, slotFrom : EEquipmentSlots, slotTo : EEquipmentSlots )
  6215.     {
  6216.         var pam : W3PlayerAbilityManager;
  6217.         var prevSkillColor : ESkillColor;
  6218.         var groupID : int;
  6219.        
  6220.         if( IsSlotSkillMutagen( slotTo ) )
  6221.         {  
  6222.             itemSlots[slotFrom] = GetInvalidUniqueId();
  6223.            
  6224.            
  6225.             groupID = pam.GetSkillGroupIdOfMutagenSlot(slotFrom);
  6226.             prevSkillColor = pam.GetSkillGroupColor(groupID);
  6227.             pam = (W3PlayerAbilityManager)abilityManager;
  6228.             pam.OnSkillMutagenUnequipped(item, slotFrom, prevSkillColor, true);
  6229.            
  6230.            
  6231.            
  6232.             EquipItemInGivenSlot( item, slotTo, false );
  6233.         }
  6234.     }
  6235.    
  6236.    
  6237.     public function UnequipItemFromSlot(slot : EEquipmentSlots, optional reequipped : bool) : bool
  6238.     {
  6239.         var item, bolts, id : SItemUniqueId;
  6240.         var items : array<SItemUniqueId>;
  6241.         var retBool : bool;
  6242.         var fistsID, bolt : array<SItemUniqueId>;
  6243.         var i, groupID : int;
  6244.         var pam : W3PlayerAbilityManager;
  6245.         var prevSkillColor : ESkillColor;
  6246.         var containedAbilities : array<name>;
  6247.         var dm : CDefinitionsManagerAccessor;
  6248.         var armorType : EArmorType;
  6249.         var isSwimming : bool;
  6250.         var hud                 : CR4ScriptedHud;
  6251.         var damagedItemModule   : CR4HudModuleDamagedItems;
  6252.        
  6253.         if(slot == EES_InvalidSlot || slot < 0 || slot > EnumGetMax('EEquipmentSlots') || !inv.IsIdValid(itemSlots[slot]))
  6254.             return false;
  6255.            
  6256.        
  6257.         if(IsSlotSkillMutagen(slot))
  6258.         {
  6259.            
  6260.             pam = (W3PlayerAbilityManager)abilityManager;
  6261.             groupID = pam.GetSkillGroupIdOfMutagenSlot(slot);
  6262.             prevSkillColor = pam.GetSkillGroupColor(groupID);
  6263.         }
  6264.        
  6265.        
  6266.         if(slot == EES_SilverSword  || slot == EES_SteelSword)
  6267.         {
  6268.             PauseOilBuffs( slot == EES_SteelSword );
  6269.         }
  6270.            
  6271.         item = itemSlots[slot];
  6272.         itemSlots[slot] = GetInvalidUniqueId();
  6273.        
  6274.        
  6275.         if(inv.ItemHasTag( item, 'PhantomWeapon' ) && GetPhantomWeaponMgr())
  6276.         {
  6277.             DestroyPhantomWeaponMgr();
  6278.         }
  6279.        
  6280.        
  6281.        
  6282.        
  6283.         if( slot == EES_SilverSword && inv.ItemHasTag( item, 'Aerondight' ) )
  6284.         {
  6285.             RemoveBuff( EET_Aerondight );
  6286.         }
  6287.        
  6288.        
  6289.         if(slot == EES_RangedWeapon)
  6290.         {
  6291.            
  6292.             this.OnRangedForceHolster( true, true );
  6293.             rangedWeapon.ClearDeployedEntity(true);
  6294.             rangedWeapon = NULL;
  6295.        
  6296.            
  6297.             if(GetItemEquippedOnSlot(EES_Bolt, bolts))
  6298.             {
  6299.                 if(inv.ItemHasTag(bolts, theGame.params.TAG_INFINITE_AMMO))
  6300.                 {
  6301.                     inv.RemoveItem(bolts, inv.GetItemQuantity(bolts) );
  6302.                 }
  6303.             }
  6304.         }
  6305.         else if(IsSlotSkillMutagen(slot))
  6306.         {          
  6307.             pam.OnSkillMutagenUnequipped(item, slot, prevSkillColor);
  6308.             LogSkillColors("Mutagen <<" + inv.GetItemName(item) + ">> unequipped from slot <<" + slot + ">>");
  6309.             LogSkillColors("Group bonus color is now <<" + pam.GetSkillGroupColor(groupID) + ">>");
  6310.             LogSkillColors("");
  6311.         }
  6312.        
  6313.        
  6314.         if(currentlyEquipedItem == item)
  6315.         {
  6316.             currentlyEquipedItem = GetInvalidUniqueId();
  6317.             RaiseEvent('ForcedUsableItemUnequip');
  6318.         }
  6319.         if(currentlyEquipedItemL == item)
  6320.         {
  6321.             if ( currentlyUsedItemL )
  6322.             {
  6323.                 currentlyUsedItemL.OnHidden( this );
  6324.             }
  6325.             HideUsableItem ( true );
  6326.         }
  6327.                
  6328.        
  6329.         if( !IsSlotPotionMutagen(slot) )
  6330.         {
  6331.             GetInventory().UnmountItem(item, true);
  6332.         }
  6333.        
  6334.         retBool = true;
  6335.                
  6336.        
  6337.         if(IsAnyItemEquippedOnSlot(EES_RangedWeapon) && slot == EES_Bolt)
  6338.         {          
  6339.             if(inv.ItemHasTag(item, theGame.params.TAG_INFINITE_AMMO))
  6340.             {
  6341.                
  6342.                 inv.RemoveItem(item, inv.GetItemQuantityByName( inv.GetItemName(item) ) );
  6343.             }
  6344.             else if (!reequipped)
  6345.             {
  6346.                
  6347.                 AddAndEquipInfiniteBolt();
  6348.             }
  6349.         }
  6350.        
  6351.        
  6352.         if(slot == EES_SilverSword  || slot == EES_SteelSword)
  6353.         {
  6354.             OnEquipMeleeWeapon(PW_None, true);         
  6355.         }
  6356.        
  6357.         if(  GetSelectedItemId() == item )
  6358.         {
  6359.             ClearSelectedItemId();
  6360.         }
  6361.        
  6362.         if(inv.IsItemBody(item))
  6363.         {
  6364.             retBool = true;
  6365.         }      
  6366.        
  6367.         /*if(retBool && !reequipped)
  6368.         {
  6369.             theTelemetry.LogWithLabelAndValue( TE_INV_ITEM_UNEQUIPPED, inv.GetItemName(item), slot );
  6370.            
  6371.            
  6372.             if(slot == EES_SteelSword && !IsAnyItemEquippedOnSlot(EES_SilverSword))
  6373.             {
  6374.                 RemoveBuff(EET_EnhancedWeapon);
  6375.             }
  6376.             else if(slot == EES_SilverSword && !IsAnyItemEquippedOnSlot(EES_SteelSword))
  6377.             {
  6378.                 RemoveBuff(EET_EnhancedWeapon);
  6379.             }
  6380.             else if(inv.IsItemAnyArmor(item))
  6381.             {
  6382.                 if( !IsAnyItemEquippedOnSlot(EES_Armor) && !IsAnyItemEquippedOnSlot(EES_Gloves) && !IsAnyItemEquippedOnSlot(EES_Boots) && !IsAnyItemEquippedOnSlot(EES_Pants))
  6383.                     RemoveBuff(EET_EnhancedArmor);
  6384.             }
  6385.         }*/ //modSigns: removed
  6386.        
  6387.        
  6388.         if(inv.ItemHasAbility(item, 'MA_HtH'))
  6389.         {
  6390.             inv.GetItemContainedAbilities(item, containedAbilities);
  6391.             fistsID = inv.GetItemsByName('fists');
  6392.             dm = theGame.GetDefinitionsManager();
  6393.             for(i=0; i<containedAbilities.Size(); i+=1)
  6394.             {
  6395.                 if(dm.AbilityHasTag(containedAbilities[i], 'MA_HtH'))
  6396.                 {
  6397.                     inv.RemoveItemCraftedAbility(fistsID[0], containedAbilities[i]);
  6398.                 }
  6399.             }
  6400.         }
  6401.        
  6402.        
  6403.         if(inv.IsItemAnyArmor(item))
  6404.         {
  6405.             armorType = inv.GetArmorType(item);
  6406.             pam = (W3PlayerAbilityManager)abilityManager;
  6407.            
  6408.             pam.ManageSetArmorTypeBonus(); //modSigns
  6409.            
  6410.             if(CanUseSkill(S_Perk_05) && (armorType == EAT_Light || GetCharacterStats().HasAbility('Glyphword 2 _Stats', true) || inv.ItemHasAbility(item, 'Glyphword 2 _Stats')))
  6411.             {
  6412.                 pam.SetPerkArmorBonus(S_Perk_05);
  6413.             }
  6414.             if(CanUseSkill(S_Perk_06) && (armorType == EAT_Medium || GetCharacterStats().HasAbility('Glyphword 3 _Stats', true) || inv.ItemHasAbility(item, 'Glyphword 3 _Stats')) )
  6415.             {
  6416.                 pam.SetPerkArmorBonus(S_Perk_06);
  6417.             }
  6418.             if(CanUseSkill(S_Perk_07) && (armorType == EAT_Heavy || GetCharacterStats().HasAbility('Glyphword 4 _Stats', true) || inv.ItemHasAbility(item, 'Glyphword 4 _Stats')) )
  6419.             {
  6420.                 pam.SetPerkArmorBonus(S_Perk_07);
  6421.             }
  6422.         }
  6423.        
  6424.        
  6425.         UpdateItemSetBonuses( item, false );
  6426.        
  6427.        
  6428.         if( inv.ItemHasTag( item, theGame.params.ITEM_SET_TAG_BONUS ) && !IsSetBonusActive( EISB_RedWolf_2 ) )
  6429.         {
  6430.             SkillReduceBombAmmoBonus();
  6431.         }
  6432.  
  6433.         if( slot == EES_Gloves )
  6434.         {
  6435.             thePlayer.DestroyEffect('runeword_4');
  6436.         }
  6437.        
  6438.        
  6439.         hud = (CR4ScriptedHud)theGame.GetHud();
  6440.         if ( hud )
  6441.         {
  6442.             damagedItemModule = hud.GetDamagedItemModule();
  6443.             if ( damagedItemModule )
  6444.             {
  6445.                 damagedItemModule.OnItemUnequippedFromSlot( slot );
  6446.             }
  6447.         }
  6448.        
  6449.        
  6450.         theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_OnItemEquipped );
  6451.        
  6452.         return retBool;
  6453.     }
  6454.        
  6455.     public function UnequipItem(item : SItemUniqueId) : bool
  6456.     {
  6457.         if(!inv.IsIdValid(item))
  6458.             return false;
  6459.        
  6460.         return UnequipItemFromSlot( itemSlots.FindFirst(item) );
  6461.     }
  6462.    
  6463.     public function DropItem( item : SItemUniqueId, quantity : int ) : bool
  6464.     {
  6465.         if(!inv.IsIdValid(item))
  6466.             return false;
  6467.         if(IsItemEquipped(item))
  6468.             return UnequipItem(item);
  6469.        
  6470.         return true;
  6471.     }  
  6472.    
  6473.    
  6474.     public function IsItemEquippedByName(itemName : name) : bool
  6475.     {
  6476.         var i : int;
  6477.    
  6478.         for(i=0; i<itemSlots.Size(); i+=1)
  6479.             if(inv.GetItemName(itemSlots[i]) == itemName)
  6480.                 return true;
  6481.  
  6482.         return false;
  6483.     }
  6484.  
  6485.    
  6486.     public function IsItemEquippedByCategoryName(categoryName : name) : bool
  6487.     {
  6488.         var i : int;
  6489.    
  6490.         for(i=0; i<itemSlots.Size(); i+=1)
  6491.             if(inv.GetItemCategory(itemSlots[i]) == categoryName)
  6492.                 return true;
  6493.                
  6494.         return false;
  6495.     }
  6496.    
  6497.     //modFriendlyStash begin
  6498.     //Not actually used by Preparations (allowStash == false), but needed for modFriendlyStash compatibility
  6499.     //Used by modFriendlyStash to allow using stash items for crafting and alchemy
  6500.     public function GetItemQuantityByNameForCrafting(itemName : name, allowStash : bool) : int
  6501.     {
  6502.         if( allowStash )
  6503.         {
  6504.             return inv.GetItemQuantityByName(itemName) + GetHorseManager().GetInventoryComponent().GetItemQuantityByName(itemName);
  6505.         }
  6506.         return inv.GetItemQuantityByName(itemName);
  6507.     }
  6508.    
  6509.     public function GetMutagenQuantityByNameForCrafting(itemName : name, allowStash : bool) : int
  6510.     {
  6511.         if( allowStash )
  6512.         {
  6513.             return inv.GetUnusedMutagensCount(itemName) + GetHorseManager().GetInventoryComponent().GetItemQuantityByName(itemName);
  6514.         }
  6515.         return inv.GetUnusedMutagensCount(itemName);
  6516.     }
  6517.    
  6518.     public function RemoveItemByNameForCrafting(itemName : name, quantity : int, allowStash : bool) : bool
  6519.     {
  6520.         var playerQuantity, horseQuantity, quantityToRemove, removedQuantity : int;
  6521.         if( allowStash )
  6522.         {
  6523.             quantityToRemove = quantity;
  6524.             playerQuantity = inv.GetItemQuantityByName(itemName);
  6525.             if( playerQuantity < quantityToRemove )
  6526.             {
  6527.                 quantityToRemove = playerQuantity;
  6528.             }
  6529.             if( quantityToRemove > 0 && inv.RemoveItemByName(itemName, quantityToRemove) )
  6530.             {
  6531.                 removedQuantity = quantityToRemove;
  6532.             }
  6533.             quantityToRemove = quantity - removedQuantity;
  6534.             if( quantityToRemove > 0 )
  6535.             {
  6536.                 horseQuantity = GetHorseManager().GetInventoryComponent().GetItemQuantityByName(itemName);
  6537.                 if( horseQuantity < quantityToRemove )
  6538.                 {
  6539.                     quantityToRemove = horseQuantity;
  6540.                 }
  6541.                 if( quantityToRemove > 0 && GetHorseManager().GetInventoryComponent().RemoveItemByName(itemName, quantityToRemove) )
  6542.                 {
  6543.                     removedQuantity += quantityToRemove;
  6544.                 }
  6545.             }
  6546.             if( removedQuantity == quantity )
  6547.             {
  6548.                 return true;
  6549.             }
  6550.             return false;
  6551.         }
  6552.         return inv.RemoveItemByName(itemName, quantity);
  6553.     }
  6554.    
  6555.     public function RemoveMutagenByNameForCrafting(itemName : name, quantity : int, allowStash : bool) : bool
  6556.     {
  6557.         var playerQuantity, horseQuantity, quantityToRemove, removedQuantity : int;
  6558.         if( allowStash )
  6559.         {
  6560.             quantityToRemove = quantity;
  6561.             playerQuantity = inv.GetUnusedMutagensCount(itemName);
  6562.             if( playerQuantity < quantityToRemove )
  6563.             {
  6564.                 quantityToRemove = playerQuantity;
  6565.             }
  6566.             if( quantityToRemove > 0 && inv.RemoveUnusedMutagensCount(itemName, quantityToRemove) )
  6567.             {
  6568.                 removedQuantity = quantityToRemove;
  6569.             }
  6570.             quantityToRemove = quantity - removedQuantity;
  6571.             if( quantityToRemove > 0 )
  6572.             {
  6573.                 horseQuantity = GetHorseManager().GetInventoryComponent().GetItemQuantityByName(itemName);
  6574.                 if( horseQuantity < quantityToRemove )
  6575.                 {
  6576.                     quantityToRemove = horseQuantity;
  6577.                 }
  6578.                 if( quantityToRemove > 0 && GetHorseManager().GetInventoryComponent().RemoveItemByName(itemName, quantityToRemove) )
  6579.                 {
  6580.                     removedQuantity += quantityToRemove;
  6581.                 }
  6582.             }
  6583.             if( removedQuantity == quantity )
  6584.             {
  6585.                 return true;
  6586.             }
  6587.             return false;
  6588.         }
  6589.         return inv.RemoveUnusedMutagensCount(itemName, quantity);
  6590.     }
  6591.     //modFriendlyStash end
  6592.    
  6593.     public function GetMaxRunEncumbrance(out usesHorseBonus : bool) : float
  6594.     {
  6595.         var value : float;
  6596.        
  6597.         //modFriendlyStash begin
  6598.         if( fStashConfig.bagsRoach == false )
  6599.             value = GetHorseManager().GetMaxEncumbrance();
  6600.         usesHorseBonus = (value > 0);
  6601.         value += CalculateAttributeValue( GetAttributeValue('encumbrance') - GetAbilityAttributeValue('ConGeralt', 'encumbrance') );
  6602.         value += fStashConfig.baseWeightGeralt;
  6603.         //modFriendlyStash end
  6604.        
  6605.         return value;
  6606.     }
  6607.        
  6608.     public function GetEncumbrance() : float
  6609.     {
  6610.         var i: int;
  6611.         var encumbrance : float;
  6612.         var items : array<SItemUniqueId>;
  6613.         var inve : CInventoryComponent;
  6614.    
  6615.         inve = GetInventory();         
  6616.         inve.GetAllItems(items);
  6617.  
  6618.         for(i=0; i<items.Size(); i+=1)
  6619.         {
  6620.             encumbrance += inve.GetItemEncumbrance( items[i] );
  6621.            
  6622.            
  6623.            
  6624.         }      
  6625.         return encumbrance;
  6626.     }
  6627.    
  6628.    
  6629.    
  6630.     public function StartInvUpdateTransaction():void
  6631.     {
  6632.         invUpdateTransaction = true;
  6633.     }
  6634.    
  6635.     public function FinishInvUpdateTransaction():void
  6636.     {
  6637.         invUpdateTransaction = false;
  6638.        
  6639.        
  6640.        
  6641.         UpdateEncumbrance();
  6642.     }
  6643.    
  6644.    
  6645.     public function UpdateEncumbrance()
  6646.     {
  6647.         var temp : bool;
  6648.        
  6649.         if (invUpdateTransaction)
  6650.         {
  6651.            
  6652.             return;
  6653.         }
  6654.        
  6655.        
  6656.        
  6657.         if ( GetEncumbrance() >= (GetMaxRunEncumbrance(temp) + 1) )
  6658.         {
  6659.             if( !HasBuff(EET_OverEncumbered) && FactsQuerySum( "DEBUG_EncumbranceBoy" ) == 0 )
  6660.             {
  6661.                 AddEffectDefault(EET_OverEncumbered, NULL, "OverEncumbered");
  6662.             }
  6663.         }
  6664.         else if(HasBuff(EET_OverEncumbered))
  6665.         {
  6666.             RemoveAllBuffsOfType(EET_OverEncumbered);
  6667.         }
  6668.        
  6669.         GetWitcherPlayer().GetHorseManager().UpdateHorseEncumbrance(); //modFriendlyStash
  6670.     }
  6671.    
  6672.     public final function GetSkillGroupIDFromIndex(idx : int) : int
  6673.     {
  6674.         var pam : W3PlayerAbilityManager;
  6675.        
  6676.         pam = (W3PlayerAbilityManager)abilityManager;
  6677.         if(pam && pam.IsInitialized())
  6678.             return pam.GetSkillGroupIDFromIndex(idx);
  6679.            
  6680.         return -1;
  6681.     }
  6682.    
  6683.     public final function GetSkillGroupColor(groupID : int) : ESkillColor
  6684.     {
  6685.         var pam : W3PlayerAbilityManager;
  6686.        
  6687.         pam = (W3PlayerAbilityManager)abilityManager;
  6688.         if(pam && pam.IsInitialized())
  6689.             return pam.GetSkillGroupColor(groupID);
  6690.            
  6691.         return SC_None;
  6692.     }
  6693.    
  6694.     public final function GetSkillGroupsCount() : int
  6695.     {
  6696.         var pam : W3PlayerAbilityManager;
  6697.        
  6698.         pam = (W3PlayerAbilityManager)abilityManager;
  6699.         if(pam && pam.IsInitialized())
  6700.             return pam.GetSkillGroupsCount();
  6701.            
  6702.         return 0;
  6703.     }
  6704.    
  6705.    
  6706.    
  6707.    
  6708.    
  6709.    
  6710.    
  6711.    
  6712.     function CycleSelectSign( bIsCyclingLeft : bool ) : ESignType
  6713.     {
  6714.         var signOrder : array<ESignType>;
  6715.         var i : int;
  6716.        
  6717.         signOrder.PushBack( ST_Yrden );
  6718.         signOrder.PushBack( ST_Quen );
  6719.         signOrder.PushBack( ST_Igni );
  6720.         signOrder.PushBack( ST_Axii );
  6721.         signOrder.PushBack( ST_Aard );
  6722.            
  6723.         for( i = 0; i < signOrder.Size(); i += 1 )
  6724.             if( signOrder[i] == equippedSign )
  6725.                 break;
  6726.        
  6727.         if(bIsCyclingLeft)
  6728.             return signOrder[ (4 + i) % 5 ];   
  6729.         else
  6730.             return signOrder[ (6 + i) % 5 ];
  6731.     }
  6732.    
  6733.     function ToggleNextSign()
  6734.     {
  6735.         SetEquippedSign(CycleSelectSign( false ));
  6736.         FactsAdd("SignToggled", 1, 1);
  6737.     }
  6738.    
  6739.     function TogglePreviousSign()
  6740.     {
  6741.         SetEquippedSign(CycleSelectSign( true ));
  6742.         FactsAdd("SignToggled", 1, 1);
  6743.     }
  6744.    
  6745.     function ProcessSignEvent( eventName : name ) : bool
  6746.     {
  6747.         if( currentlyCastSign != ST_None && signs[currentlyCastSign].entity)
  6748.         {
  6749.             return signs[currentlyCastSign].entity.OnProcessSignEvent( eventName );
  6750.         }
  6751.        
  6752.         return false;
  6753.     }
  6754.    
  6755.     var findActorTargetTimeStamp : float;
  6756.     var pcModeChanneledSignTimeStamp    : float;
  6757.     event OnProcessCastingOrientation( isContinueCasting : bool )
  6758.     {
  6759.         var customOrientationTarget : EOrientationTarget;
  6760.         var checkHeading            : float;
  6761.         var rotHeading              : float;
  6762.         var playerToHeadingDist     : float;
  6763.         var slideTargetActor        : CActor;
  6764.         var newLockTarget           : CActor;
  6765.        
  6766.         var enableNoTargetOrientation   : bool;
  6767.        
  6768.         var currTime : float;
  6769.        
  6770.         enableNoTargetOrientation = true;
  6771.         if ( GetDisplayTarget() && this.IsDisplayTargetTargetable() )
  6772.         {
  6773.             enableNoTargetOrientation = false;
  6774.             if ( theInput.GetActionValue( 'CastSignHold' ) > 0 || this.IsCurrentSignChanneled() )
  6775.             {
  6776.                 if ( IsPCModeEnabled() )
  6777.                 {
  6778.                     if ( EngineTimeToFloat( theGame.GetEngineTime() ) >  pcModeChanneledSignTimeStamp + 1.f )
  6779.                         enableNoTargetOrientation = true;
  6780.                 }
  6781.                 else
  6782.                 {
  6783.                     if ( GetCurrentlyCastSign() == ST_Igni || GetCurrentlyCastSign() == ST_Axii )
  6784.                     {
  6785.                         slideTargetActor = (CActor)GetDisplayTarget();
  6786.                         if ( slideTargetActor
  6787.                             && ( !slideTargetActor.GetGameplayVisibility() || !CanBeTargetedIfSwimming( slideTargetActor ) || !slideTargetActor.IsAlive() ) )
  6788.                         {
  6789.                             SetSlideTarget( NULL );
  6790.                             if ( ProcessLockTarget() )
  6791.                                 slideTargetActor = (CActor)slideTarget;
  6792.                         }              
  6793.                        
  6794.                         if ( !slideTargetActor )
  6795.                         {
  6796.                             LockToTarget( false );
  6797.                             enableNoTargetOrientation = true;
  6798.                         }
  6799.                         else if ( IsThreat( slideTargetActor ) || GetCurrentlyCastSign() == ST_Axii )
  6800.                             LockToTarget( true );
  6801.                         else
  6802.                         {
  6803.                             LockToTarget( false );
  6804.                             enableNoTargetOrientation = true;
  6805.                         }
  6806.                     }
  6807.                 }
  6808.             }
  6809.  
  6810.             if ( !enableNoTargetOrientation )
  6811.             {          
  6812.                 customOrientationTarget = OT_Actor;
  6813.             }
  6814.         }
  6815.        
  6816.         if ( enableNoTargetOrientation )
  6817.         {
  6818.             if ( GetPlayerCombatStance() == PCS_AlertNear && theInput.GetActionValue( 'CastSignHold' ) > 0 )
  6819.             {
  6820.                 if ( GetDisplayTarget() && !slideTargetActor )
  6821.                 {
  6822.                     currTime = EngineTimeToFloat( theGame.GetEngineTime() );
  6823.                     if ( currTime > findActorTargetTimeStamp + 1.5f )
  6824.                     {
  6825.                         findActorTargetTimeStamp = currTime;
  6826.                        
  6827.                         newLockTarget = GetScreenSpaceLockTarget( GetDisplayTarget(), 180.f, 1.f, 0.f, true );
  6828.                        
  6829.                         if ( newLockTarget && IsThreat( newLockTarget ) && IsCombatMusicEnabled() )
  6830.                         {
  6831.                             SetTarget( newLockTarget, true );
  6832.                             SetMoveTargetChangeAllowed( true );
  6833.                             SetMoveTarget( newLockTarget );
  6834.                             SetMoveTargetChangeAllowed( false );
  6835.                             SetSlideTarget( newLockTarget );                           
  6836.                         }  
  6837.                     }
  6838.                 }
  6839.                 else
  6840.                     ProcessLockTarget();
  6841.             }
  6842.            
  6843.             if ( wasBRAxisPushed )
  6844.                 customOrientationTarget = OT_CameraOffset;
  6845.             else
  6846.             {
  6847.                 if ( !lastAxisInputIsMovement || theInput.LastUsedPCInput() )
  6848.                     customOrientationTarget = OT_CameraOffset;
  6849.                 else if ( theInput.GetActionValue( 'CastSignHold' ) > 0 )
  6850.                 {
  6851.                     if ( GetOrientationTarget() == OT_CameraOffset )
  6852.                         customOrientationTarget = OT_CameraOffset;
  6853.                     else if ( GetPlayerCombatStance() == PCS_AlertNear || GetPlayerCombatStance() == PCS_Guarded )
  6854.                         customOrientationTarget = OT_CameraOffset;
  6855.                     else
  6856.                         customOrientationTarget = OT_Player;   
  6857.                 }
  6858.                 else
  6859.                     customOrientationTarget = OT_CustomHeading;
  6860.             }          
  6861.         }      
  6862.        
  6863.         if ( GetCurrentlyCastSign() == ST_Quen )
  6864.         {
  6865.             if ( theInput.LastUsedPCInput() )
  6866.             {
  6867.                 customOrientationTarget = OT_Camera;
  6868.             }
  6869.             else if ( IsCurrentSignChanneled() )
  6870.             {
  6871.                 if ( bLAxisReleased )
  6872.                     customOrientationTarget = OT_Player;
  6873.                 else
  6874.                     customOrientationTarget = OT_Camera;
  6875.             }
  6876.             else
  6877.                 customOrientationTarget = OT_Player;
  6878.         }  
  6879.        
  6880.         if ( GetCurrentlyCastSign() == ST_Axii && IsCurrentSignChanneled() )
  6881.         {  
  6882.             if ( slideTarget && (CActor)slideTarget )
  6883.             {
  6884.                 checkHeading = VecHeading( slideTarget.GetWorldPosition() - this.GetWorldPosition() );
  6885.                 rotHeading = checkHeading;
  6886.                 playerToHeadingDist = AngleDistance( GetHeading(), checkHeading );
  6887.                
  6888.                 if ( playerToHeadingDist > 45 )
  6889.                     SetCustomRotation( 'ChanneledSignAxii', rotHeading, 0.0, 0.5, false );
  6890.                 else if ( playerToHeadingDist < -45 )
  6891.                     SetCustomRotation( 'ChanneledSignAxii', rotHeading, 0.0, 0.5, false );                 
  6892.             }
  6893.             else
  6894.             {
  6895.                 checkHeading = VecHeading( theCamera.GetCameraDirection() );
  6896.                 rotHeading = GetHeading();
  6897.                 playerToHeadingDist = AngleDistance( GetHeading(), checkHeading );
  6898.                
  6899.                 if ( playerToHeadingDist > 45 )
  6900.                     SetCustomRotation( 'ChanneledSignAxii', rotHeading - 22.5, 0.0, 0.5, false );
  6901.                 else if ( playerToHeadingDist < -45 )
  6902.                     SetCustomRotation( 'ChanneledSignAxii', rotHeading + 22.5, 0.0, 0.5, false );              
  6903.             }
  6904.         }      
  6905.            
  6906.         if ( IsActorLockedToTarget() )
  6907.             customOrientationTarget = OT_Actor;
  6908.        
  6909.         //modEnhancedTargeting BEGIN
  6910.         if ( theGame.GetInGameConfigWrapper().GetVarValue('EnhancedTargeting', 'ETSignsTowardsCamera') )
  6911.             customOrientationTarget = OT_CameraOffset; // shitty tweak, oh well
  6912.         //modEnhancedTargeting END
  6913.        
  6914.         AddCustomOrientationTarget( customOrientationTarget, 'Signs' );
  6915.        
  6916.         if ( customOrientationTarget == OT_CustomHeading )
  6917.             SetOrientationTargetCustomHeading( GetCombatActionHeading(), 'Signs' );        
  6918.     }
  6919.    
  6920.     event OnRaiseSignEvent()
  6921.     {
  6922.         var newTarget : CActor;
  6923.    
  6924.         if ( ( !IsCombatMusicEnabled() && !CanAttackWhenNotInCombat( EBAT_CastSign, false, newTarget ) ) || ( IsOnBoat() && !IsCombatMusicEnabled() ) )
  6925.         {      
  6926.             if ( CastSignFriendly() )
  6927.                 return true;
  6928.         }
  6929.         else
  6930.         {
  6931.             RaiseEvent('CombatActionFriendlyEnd');
  6932.             SetBehaviorVariable( 'SignNum', (int)equippedSign );
  6933.             SetBehaviorVariable( 'combatActionType', (int)CAT_CastSign );
  6934.  
  6935.             if ( IsPCModeEnabled() )
  6936.                 pcModeChanneledSignTimeStamp = EngineTimeToFloat( theGame.GetEngineTime() );
  6937.        
  6938.             if( RaiseForceEvent('CombatAction') )
  6939.             {
  6940.                 OnCombatActionStart();
  6941.                 findActorTargetTimeStamp = EngineTimeToFloat( theGame.GetEngineTime() );
  6942.                 theTelemetry.LogWithValueStr(TE_FIGHT_PLAYER_USE_SIGN, SignEnumToString( equippedSign ));
  6943.                 return true;
  6944.             }
  6945.         }
  6946.        
  6947.         return false;
  6948.     }
  6949.    
  6950.     function CastSignFriendly() : bool
  6951.     {
  6952.         var actor : CActor;
  6953.    
  6954.         SetBehaviorVariable( 'combatActionTypeForOverlay', (int)CAT_CastSign );        
  6955.         if ( RaiseCombatActionFriendlyEvent() )
  6956.         {
  6957.                        
  6958.             return true;
  6959.         }  
  6960.        
  6961.         return false;
  6962.     }
  6963.    
  6964.     function CastSign() : bool
  6965.     {
  6966.         var equippedSignStr : string;
  6967.         var newSignEnt : W3SignEntity;
  6968.         var spawnPos : Vector;
  6969.         var slotMatrix : Matrix;
  6970.         var target : CActor;
  6971.         var mutagen17 : W3Mutagen17_Effect; //modSigns
  6972.        
  6973.         if ( IsInAir() )
  6974.         {
  6975.             return false;
  6976.         }
  6977.        
  6978.         AddTemporarySkills();
  6979.        
  6980.         //modSigns: check for mutagen17 activation
  6981.         if(HasBuff(EET_Mutagen17))
  6982.         {
  6983.             mutagen17 = (W3Mutagen17_Effect)GetBuff(EET_Mutagen17);
  6984.             if(mutagen17.IsBoostAvailable())
  6985.             {
  6986.                 mutagen17.ActivateBoost();
  6987.                 //theGame.witcherLog.AddMessage("mutagen17 boost activated: sign"); //modSigns: debug
  6988.             }
  6989.         }
  6990.        
  6991.        
  6992.        
  6993.         if(equippedSign == ST_Aard)
  6994.         {
  6995.             CalcEntitySlotMatrix('l_weapon', slotMatrix);
  6996.             spawnPos = MatrixGetTranslation(slotMatrix);
  6997.         }
  6998.         else
  6999.         {
  7000.             spawnPos = GetWorldPosition();
  7001.         }
  7002.        
  7003.         if( equippedSign == ST_Aard || equippedSign == ST_Igni )
  7004.         {
  7005.             target = GetTarget();
  7006.             if(target)
  7007.                 target.SignalGameplayEvent( 'DodgeSign' );
  7008.         }
  7009.        
  7010.         newSignEnt = (W3SignEntity)theGame.CreateEntity( signs[equippedSign].template, spawnPos, GetWorldRotation() );
  7011.         return newSignEnt.Init( signOwner, signs[equippedSign].entity );
  7012.     }
  7013.    
  7014.    
  7015.     private function HAX_SignToThrowItemRestore()
  7016.     {
  7017.         var action : SInputAction;
  7018.        
  7019.         action.value = theInput.GetActionValue('ThrowItemHold');
  7020.         action.lastFrameValue = 0;
  7021.        
  7022.         if(IsPressed(action) && CanSetupCombatAction_Throw())
  7023.         {
  7024.             if(inv.IsItemBomb(selectedItemId))
  7025.             {
  7026.                 BombThrowStart();
  7027.             }
  7028.             else
  7029.             {
  7030.                 UsableItemStart();
  7031.             }
  7032.            
  7033.             SetThrowHold( true );
  7034.         }
  7035.     }
  7036.    
  7037.     event OnCFMCameraZoomFail(){}
  7038.        
  7039.    
  7040.  
  7041.     public final function GetDrunkMutagens( optional sourceName : string ) : array<CBaseGameplayEffect>
  7042.     {
  7043.         return effectManager.GetDrunkMutagens( sourceName );
  7044.     }
  7045.    
  7046.     public final function GetPotionBuffs() : array<CBaseGameplayEffect>
  7047.     {
  7048.         return effectManager.GetPotionBuffs();
  7049.     }
  7050.    
  7051.     public final function RecalcPotionsDurations()
  7052.     {
  7053.         var i : int;
  7054.         var buffs : array<CBaseGameplayEffect>;
  7055.        
  7056.         buffs = GetPotionBuffs();
  7057.         for(i=0; i<buffs.Size(); i+=1)
  7058.         {
  7059.             buffs[i].RecalcPotionDuration();
  7060.         }
  7061.     }
  7062.  
  7063.     public function StartFrenzy()
  7064.     {
  7065.         var ratio, duration : float;
  7066.         var skillLevel : int;
  7067.    
  7068.         isInFrenzy = true;
  7069.         skillLevel = GetSkillLevel(S_Alchemy_s16);
  7070.         //modSigns: direct slowdown percentage
  7071.         ratio = 1.0f - skillLevel * CalculateAttributeValue(GetSkillAttributeValue(S_Alchemy_s16, 'slowdown_ratio', false, true));
  7072.         duration = skillLevel * CalculateAttributeValue(GetSkillAttributeValue(S_Alchemy_s16, 'slowdown_duration', false, true));
  7073.    
  7074.         theGame.SetTimeScale(ratio, theGame.GetTimescaleSource(ETS_SkillFrenzy), theGame.GetTimescalePriority(ETS_SkillFrenzy) );
  7075.         AddTimer('SkillFrenzyFinish', duration * ratio, , , , true);
  7076.     }
  7077.    
  7078.     timer function SkillFrenzyFinish(dt : float, optional id : int)
  7079.     {      
  7080.         theGame.RemoveTimeScale( theGame.GetTimescaleSource(ETS_SkillFrenzy) );
  7081.         isInFrenzy = false;
  7082.     }
  7083.    
  7084.     public function GetToxicityDamageThreshold() : float
  7085.     {
  7086.         var ret : float;
  7087.        
  7088.         ret = theGame.params.TOXICITY_DAMAGE_THRESHOLD;
  7089.        
  7090.         if(CanUseSkill(S_Alchemy_s01))
  7091.             ret += CalculateAttributeValue(GetSkillAttributeValue(S_Alchemy_s01, 'threshold', false, true)) * GetSkillLevel(S_Alchemy_s01);
  7092.        
  7093.         return ret;
  7094.     }
  7095.    
  7096.    
  7097.    
  7098.     public final function AddToxicityOffset( val : float)
  7099.     {
  7100.         ((W3PlayerAbilityManager)abilityManager).AddToxicityOffset(val);       
  7101.     }
  7102.    
  7103.     public final function SetToxicityOffset( val : float)
  7104.     {
  7105.         ((W3PlayerAbilityManager)abilityManager).SetToxicityOffset(val);
  7106.     }
  7107.    
  7108.     public final function RemoveToxicityOffset( val : float)
  7109.     {
  7110.         ((W3PlayerAbilityManager)abilityManager).RemoveToxicityOffset(val);    
  7111.     }
  7112.    
  7113.    
  7114.     public final function CalculatePotionDuration(item : SItemUniqueId, isMutagenPotion : bool, optional itemName : name) : float
  7115.     {
  7116.         var duration, skillPassiveMod, mutagenSkillMod : float;
  7117.         var val, min, max : SAbilityAttributeValue;
  7118.        
  7119.        
  7120.         if(inv.IsIdValid(item))
  7121.         {
  7122.             duration = CalculateAttributeValue(inv.GetItemAttributeValue(item, 'duration'));           
  7123.         }
  7124.         else
  7125.         {
  7126.             theGame.GetDefinitionsManager().GetItemAttributeValueNoRandom(itemName, true, 'duration', min, max);
  7127.             duration = CalculateAttributeValue(GetAttributeRandomizedValue(min, max));
  7128.         }
  7129.            
  7130.         skillPassiveMod = CalculateAttributeValue(GetAttributeValue('potion_duration'));
  7131.        
  7132.         if(isMutagenPotion && CanUseSkill(S_Alchemy_s14))
  7133.         {
  7134.             val = GetSkillAttributeValue(S_Alchemy_s14, 'duration', false, true);
  7135.             mutagenSkillMod = val.valueMultiplicative * GetSkillLevel(S_Alchemy_s14);
  7136.         }
  7137.        
  7138.         //modSigns: don't add passive skill mod to mutagen potions
  7139.         //duration = duration * (1 + skillPassiveMod + mutagenSkillMod);
  7140.         if(isMutagenPotion)
  7141.             duration = duration * (1 + mutagenSkillMod);
  7142.         else
  7143.             duration = duration * (1 + skillPassiveMod);
  7144.        
  7145.         return duration;
  7146.     }
  7147.    
  7148.     public function ToxicityLowEnoughToDrinkPotion( slotid : EEquipmentSlots, optional itemId : SItemUniqueId ) : bool
  7149.     {
  7150.         var item                : SItemUniqueId;
  7151.         var maxTox              : float;
  7152.         var potionToxicity      : float;
  7153.         var toxicityOffset      : float;
  7154.         var effectType          : EEffectType;
  7155.         var customAbilityName   : name;
  7156.        
  7157.         if(itemId != GetInvalidUniqueId())
  7158.             item = itemId;
  7159.         else
  7160.             item = itemSlots[slotid];
  7161.        
  7162.         inv.GetPotionItemBuffData(item, effectType, customAbilityName);
  7163.         maxTox = abilityManager.GetStatMax(BCS_Toxicity);
  7164.         potionToxicity = CalculateAttributeValue(inv.GetItemAttributeValue(item, 'toxicity'));
  7165.         //modSigns begin
  7166.         if(CanUseSkill(S_Alchemy_s15))
  7167.         {
  7168.             potionToxicity *= 1 - CalculateAttributeValue(GetSkillAttributeValue(S_Alchemy_s15, 'toxicityReduction', false, false)) * GetSkillLevel(S_Alchemy_s15);
  7169.         }
  7170.         //modSigns end
  7171.         toxicityOffset = CalculateAttributeValue(inv.GetItemAttributeValue(item, 'toxicity_offset'));
  7172.        
  7173.         if(effectType != EET_WhiteHoney)
  7174.         {
  7175.             if(abilityManager.GetStat(BCS_Toxicity, false) + potionToxicity + toxicityOffset > maxTox )
  7176.             {
  7177.                 return false;
  7178.             }
  7179.         }
  7180.        
  7181.         return true;
  7182.     }
  7183.    
  7184.     public final function HasFreeToxicityToDrinkPotion( item : SItemUniqueId, effectType : EEffectType, out finalPotionToxicity : float ) : bool
  7185.     {
  7186.         var i : int;
  7187.         var maxTox, toxicityOffset, adrenaline : float;
  7188.         var costReduction : SAbilityAttributeValue;
  7189.        
  7190.        
  7191.         if( effectType == EET_WhiteHoney )
  7192.         {
  7193.             return true;
  7194.         }
  7195.        
  7196.        
  7197.         maxTox = abilityManager.GetStatMax(BCS_Toxicity);
  7198.         finalPotionToxicity = CalculateAttributeValue(inv.GetItemAttributeValue(item, 'toxicity'));
  7199.         //modSigns begin
  7200.         if(CanUseSkill(S_Alchemy_s15))
  7201.         {
  7202.             finalPotionToxicity *= 1 - CalculateAttributeValue(GetSkillAttributeValue(S_Alchemy_s15, 'toxicityReduction', false, false)) * GetSkillLevel(S_Alchemy_s15);
  7203.         }
  7204.         //modSigns end
  7205.         toxicityOffset = CalculateAttributeValue(inv.GetItemAttributeValue(item, 'toxicity_offset'));
  7206.        
  7207.        
  7208.         /*if(CanUseSkill(S_Perk_13))
  7209.         {
  7210.             costReduction = GetSkillAttributeValue(S_Perk_13, 'cost_reduction', false, true);
  7211.             adrenaline = FloorF(GetStat(BCS_Focus));
  7212.             costReduction = costReduction * adrenaline;
  7213.             finalPotionToxicity = (finalPotionToxicity - costReduction.valueBase) * (1 - costReduction.valueMultiplicative) - costReduction.valueAdditive;
  7214.             finalPotionToxicity = MaxF(0.f, finalPotionToxicity);
  7215.         }*/ //modSigns: effect changed
  7216.        
  7217.        
  7218.         if(abilityManager.GetStat(BCS_Toxicity, false) + finalPotionToxicity + toxicityOffset > maxTox )
  7219.         {
  7220.             return false;
  7221.         }
  7222.        
  7223.         return true;
  7224.     }
  7225.    
  7226.     public function DrinkPreparedPotion( slotid : EEquipmentSlots, optional itemId : SItemUniqueId )
  7227.     {  
  7228.         var potParams : W3PotionParams;
  7229.         var potionParams : SCustomEffectParams;
  7230.         var factPotionParams : W3Potion_Fact_Params;
  7231.         var adrenaline, hpGainValue, duration, finalPotionToxicity : float;
  7232.         var ret : EEffectInteract;
  7233.         var effectType : EEffectType;
  7234.         var item : SItemUniqueId;
  7235.         var customAbilityName, factId : name;
  7236.         var atts : array<name>;
  7237.         var i : int;
  7238.         var mutagenParams : W3MutagenBuffCustomParams;
  7239.        
  7240.        
  7241.         if(itemId != GetInvalidUniqueId())
  7242.             item = itemId;
  7243.         else
  7244.             item = itemSlots[slotid];
  7245.        
  7246.        
  7247.         if(!inv.IsIdValid(item))
  7248.             return;
  7249.            
  7250.        
  7251.         if( inv.SingletonItemGetAmmo(item) == 0 )
  7252.             return;
  7253.            
  7254.        
  7255.         inv.GetPotionItemBuffData(item, effectType, customAbilityName);
  7256.            
  7257.        
  7258.         if( !HasFreeToxicityToDrinkPotion( item, effectType, finalPotionToxicity ) )
  7259.         {
  7260.             return;
  7261.         }
  7262.                
  7263.        
  7264.         if(effectType == EET_Fact)
  7265.         {
  7266.             inv.GetItemAttributes(item, atts);
  7267.            
  7268.             for(i=0; i<atts.Size(); i+=1)
  7269.             {
  7270.                 if(StrBeginsWith(NameToString(atts[i]), "fact_"))
  7271.                 {
  7272.                     factId = atts[i];
  7273.                     break;
  7274.                 }
  7275.             }
  7276.            
  7277.             factPotionParams = new W3Potion_Fact_Params in theGame;
  7278.             factPotionParams.factName = factId;
  7279.             factPotionParams.potionItemName = inv.GetItemName(item);
  7280.            
  7281.             potionParams.buffSpecificParams = factPotionParams;
  7282.         }
  7283.        
  7284.         else if(inv.ItemHasTag( item, 'Mutagen' ))
  7285.         {
  7286.             mutagenParams = new W3MutagenBuffCustomParams in theGame;
  7287.             mutagenParams.toxicityOffset = CalculateAttributeValue(inv.GetItemAttributeValue(item, 'toxicity_offset'));
  7288.             mutagenParams.potionItemName = inv.GetItemName(item);
  7289.            
  7290.             potionParams.buffSpecificParams = mutagenParams;
  7291.            
  7292.             if( IsMutationActive( EPMT_Mutation10 ) && !HasBuff( EET_Mutation10 ) && IsInCombat() ) //modSigns
  7293.             {
  7294.                 AddEffectDefault( EET_Mutation10, this, "Mutation 10" );
  7295.             }
  7296.         }
  7297.        
  7298.         else
  7299.         {
  7300.             potParams = new W3PotionParams in theGame;
  7301.             potParams.potionItemName = inv.GetItemName(item);
  7302.            
  7303.             potionParams.buffSpecificParams = potParams;
  7304.         }
  7305.    
  7306.        
  7307.         duration = CalculatePotionDuration(item, inv.ItemHasTag( item, 'Mutagen' ));       
  7308.  
  7309.        
  7310.         potionParams.effectType = effectType;
  7311.         potionParams.creator = this;
  7312.         potionParams.sourceName = "drank_potion";
  7313.         potionParams.duration = duration;
  7314.         potionParams.customAbilityName = customAbilityName;
  7315.         ret = AddEffectCustom(potionParams);
  7316.  
  7317.        
  7318.         if(factPotionParams)
  7319.             delete factPotionParams;
  7320.            
  7321.         if(mutagenParams)
  7322.             delete mutagenParams;
  7323.            
  7324.        
  7325.         inv.SingletonItemRemoveAmmo(item);
  7326.        
  7327.        
  7328.         if(ret == EI_Pass || ret == EI_Override || ret == EI_Cumulate)
  7329.         {
  7330.             if(CanUseSkill(S_Perk_13) && finalPotionToxicity > 0.f) //modSigns: new effect
  7331.             {
  7332.                 if(GetStat(BCS_Focus) >= 3.0)
  7333.                 {
  7334.                     AddEffectDefault(EET_Perk13Effect, this, "perk13", false);
  7335.                 }
  7336.             }
  7337.            
  7338.             if( finalPotionToxicity > 0.f )
  7339.             {
  7340.                 abilityManager.GainStat(BCS_Toxicity, finalPotionToxicity );
  7341.             }
  7342.            
  7343.            
  7344.             /*if(CanUseSkill(S_Perk_13))
  7345.             {
  7346.                 abilityManager.DrainFocus(adrenaline);
  7347.             }*/ //modSigns: effect reworked
  7348.            
  7349.             if (!IsEffectActive('invisible'))
  7350.             {
  7351.                 PlayEffect('use_potion');
  7352.             }
  7353.            
  7354.             if ( inv.ItemHasTag( item, 'Mutagen' ) )
  7355.             {
  7356.                
  7357.                 theGame.GetGamerProfile().CheckTrialOfGrasses();
  7358.                
  7359.                
  7360.                 SetFailedFundamentalsFirstAchievementCondition(true);
  7361.             }
  7362.            
  7363.            
  7364.             if(CanUseSkill(S_Alchemy_s02))
  7365.             {
  7366.                 hpGainValue = ClampF(GetStatMax(BCS_Vitality) * CalculateAttributeValue(GetSkillAttributeValue(S_Alchemy_s02, 'vitality_gain_perc', false, true)) * GetSkillLevel(S_Alchemy_s02), 0, GetStatMax(BCS_Vitality));
  7367.                 GainStat(BCS_Vitality, hpGainValue);
  7368.             }          
  7369.            
  7370.            
  7371.             /*if(CanUseSkill(S_Alchemy_s04) && !skillBonusPotionEffect && (RandF() < CalculateAttributeValue(GetSkillAttributeValue(S_Alchemy_s04, 'apply_chance', false, true)) * GetSkillLevel(S_Alchemy_s04)))
  7372.             {
  7373.                 AddRandomPotionEffectFromAlch4Skill( effectType );             
  7374.             }*/ //modSigns: removed
  7375.            
  7376.             theGame.GetGamerProfile().SetStat(ES_ActivePotions, effectManager.GetPotionBuffsCount());
  7377.         }
  7378.        
  7379.         theTelemetry.LogWithLabel(TE_ELIXIR_USED, inv.GetItemName(item));
  7380.        
  7381.         if(ShouldProcessTutorial('TutorialPotionAmmo'))
  7382.         {
  7383.             FactsAdd("tut_used_potion");
  7384.         }
  7385.        
  7386.         SetFailedFundamentalsFirstAchievementCondition(true);
  7387.     }
  7388.    
  7389.    
  7390.     /*private final function AddRandomPotionEffectFromAlch4Skill( currentlyDrankPotion : EEffectType )
  7391.     {
  7392.         var randomPotions : array<EEffectType>;
  7393.         var currentPotion : CBaseGameplayEffect;
  7394.         var effectsOld, effectsNew : array<CBaseGameplayEffect>;
  7395.         var i, ind : int;
  7396.         var duration : float;
  7397.         var params : SCustomEffectParams;
  7398.         var ret : EEffectInteract;
  7399.        
  7400.        
  7401.         randomPotions.PushBack( EET_BlackBlood );
  7402.         randomPotions.PushBack( EET_Blizzard );
  7403.         randomPotions.PushBack( EET_FullMoon );
  7404.         randomPotions.PushBack( EET_GoldenOriole );
  7405.         //randomPotions.PushBack( EET_KillerWhale ); //modSigns
  7406.         randomPotions.PushBack( EET_MariborForest );
  7407.         randomPotions.PushBack( EET_PetriPhiltre );
  7408.         randomPotions.PushBack( EET_Swallow );
  7409.         randomPotions.PushBack( EET_TawnyOwl );
  7410.         randomPotions.PushBack( EET_Thunderbolt );
  7411.        
  7412.        
  7413.         randomPotions.Remove( currentlyDrankPotion );
  7414.        
  7415.        
  7416.         ind = RandRange( randomPotions.Size() );
  7417.  
  7418.        
  7419.         if( HasBuff( randomPotions[ ind ] ) )
  7420.         {
  7421.             currentPotion = GetBuff( randomPotions[ ind ] );
  7422.             currentPotion.SetTimeLeft( currentPotion.GetInitialDurationAfterResists() );
  7423.         }
  7424.        
  7425.         else
  7426.         {          
  7427.             duration = BonusPotionGetDurationFromXML( randomPotions[ ind ] );
  7428.            
  7429.             if(duration > 0)
  7430.             {
  7431.                 effectsOld = GetCurrentEffects();
  7432.                                    
  7433.                 params.effectType = randomPotions[ ind ];
  7434.                 params.creator = this;
  7435.                 params.sourceName = SkillEnumToName( S_Alchemy_s04 );
  7436.                 params.duration = duration;
  7437.                 ret = AddEffectCustom( params );
  7438.                
  7439.                
  7440.                 if( ret != EI_Undefined && ret != EI_Deny )
  7441.                 {
  7442.                     effectsNew = GetCurrentEffects();
  7443.                    
  7444.                     ind = -1;
  7445.                     for( i=effectsNew.Size()-1; i>=0; i-=1)
  7446.                     {
  7447.                         if( !effectsOld.Contains( effectsNew[i] ) )
  7448.                         {
  7449.                             ind = i;
  7450.                             break;
  7451.                         }
  7452.                     }
  7453.                    
  7454.                     if(ind > -1)
  7455.                     {
  7456.                         skillBonusPotionEffect = effectsNew[ind];
  7457.                     }
  7458.                 }
  7459.             }      
  7460.         }
  7461.     }*/ //modSigns: removed
  7462.    
  7463.    
  7464.     private function BonusPotionGetDurationFromXML(type : EEffectType) : float
  7465.     {
  7466.         var dm : CDefinitionsManagerAccessor;
  7467.         var main, ingredients : SCustomNode;
  7468.         var tmpName, typeName, itemName : name;
  7469.         var abs : array<name>;
  7470.         var min, max : SAbilityAttributeValue;
  7471.         var tmpInt : int;
  7472.         var temp                                : array<float>;
  7473.         var i, temp2, temp3 : int;
  7474.                        
  7475.         dm = theGame.GetDefinitionsManager();
  7476.         main = dm.GetCustomDefinition('alchemy_recipes');
  7477.         typeName = EffectTypeToName(type);
  7478.        
  7479.        
  7480.         for(i=0; i<main.subNodes.Size(); i+=1)
  7481.         {
  7482.             if(dm.GetCustomNodeAttributeValueName(main.subNodes[i], 'type_name', tmpName))
  7483.             {
  7484.                
  7485.                 if(tmpName == typeName)
  7486.                 {
  7487.                     if(dm.GetCustomNodeAttributeValueInt(main.subNodes[i], 'level', tmpInt))
  7488.                     {
  7489.                        
  7490.                         if(tmpInt == 1)
  7491.                         {
  7492.                             if(dm.GetCustomNodeAttributeValueName(main.subNodes[i], 'cookedItem_name', itemName))
  7493.                             {
  7494.                                
  7495.                                 if(IsNameValid(itemName))
  7496.                                 {
  7497.                                     break;
  7498.                                 }
  7499.                             }
  7500.                         }
  7501.                     }
  7502.                 }
  7503.             }
  7504.         }
  7505.        
  7506.         if(!IsNameValid(itemName))
  7507.             return 0;
  7508.        
  7509.        
  7510.         dm.GetItemAbilitiesWithWeights(itemName, true, abs, temp, temp2, temp3);
  7511.         dm.GetAbilitiesAttributeValue(abs, 'duration', min, max);                      
  7512.         return CalculateAttributeValue(GetAttributeRandomizedValue(min, max));
  7513.     }
  7514.    
  7515.     public function ClearSkillBonusPotionEffect()
  7516.     {
  7517.         skillBonusPotionEffect = NULL;
  7518.     }
  7519.    
  7520.     public function GetSkillBonusPotionEffect() : CBaseGameplayEffect
  7521.     {
  7522.         return skillBonusPotionEffect;
  7523.     }
  7524.    
  7525.    
  7526.    
  7527.    
  7528.    
  7529.    
  7530.    
  7531.     public final function HasRunewordActive(abilityName : name) : bool
  7532.     {
  7533.         var item : SItemUniqueId;
  7534.         var hasRuneword : bool;
  7535.        
  7536.         hasRuneword = false;
  7537.        
  7538.         if(GetItemEquippedOnSlot(EES_SteelSword, item) && (IsItemHeld(item) || abilityName == 'Runeword 5 _Stats' || abilityName == 'Runeword 6 _Stats')) //modSigns: only drawn sword (or equipped - for runeword 5 and 6)
  7539.         {
  7540.             hasRuneword = inv.ItemHasAbility(item, abilityName);               
  7541.         }
  7542.        
  7543.         if(!hasRuneword)
  7544.         {
  7545.             if(GetItemEquippedOnSlot(EES_SilverSword, item) && (IsItemHeld(item) || abilityName == 'Runeword 5 _Stats' || abilityName == 'Runeword 6 _Stats')) //modSigns: only drawn sword (or equipped - for runeword 5 and 6)
  7546.             {
  7547.                 hasRuneword = inv.ItemHasAbility(item, abilityName);
  7548.             }
  7549.         }
  7550.        
  7551.         return hasRuneword;
  7552.     }
  7553.    
  7554.     public final function HasGlyphwordActive(abilityName : name) : bool //modSigns
  7555.     {
  7556.         var item : SItemUniqueId;
  7557.         var hasGlyphword : bool;
  7558.        
  7559.         hasGlyphword = false;
  7560.        
  7561.         if(GetItemEquippedOnSlot(EES_Armor, item))
  7562.         {
  7563.             hasGlyphword = inv.ItemHasAbility(item, abilityName);
  7564.         }
  7565.        
  7566.         return hasGlyphword;
  7567.     }
  7568.    
  7569.     public final function GetShrineBuffs() : array<CBaseGameplayEffect>
  7570.     {
  7571.         var null : array<CBaseGameplayEffect>;
  7572.        
  7573.         if(effectManager && effectManager.IsReady())
  7574.             return effectManager.GetShrineBuffs();
  7575.            
  7576.         return null;
  7577.     }
  7578.    
  7579.     public final function AddRepairObjectBuff(armor : bool, weapon : bool) : bool
  7580.     {
  7581.         var added : bool;
  7582.        
  7583.         added = false;
  7584.        
  7585.         if(weapon /*&& (IsAnyItemEquippedOnSlot(EES_SilverSword) || IsAnyItemEquippedOnSlot(EES_SteelSword))*/ ) //modSigns: restrictions removed
  7586.         {
  7587.             AddEffectDefault(EET_EnhancedWeapon, this, "repair_object", false);
  7588.             added = true;
  7589.         }
  7590.        
  7591.         if(armor /*&& (IsAnyItemEquippedOnSlot(EES_Armor) || IsAnyItemEquippedOnSlot(EES_Gloves) || IsAnyItemEquippedOnSlot(EES_Boots) || IsAnyItemEquippedOnSlot(EES_Pants))*/ ) //modSigns: restrictions removed
  7592.         {
  7593.             AddEffectDefault(EET_EnhancedArmor, this, "repair_object", false);
  7594.             added = true;
  7595.         }
  7596.        
  7597.         return added;
  7598.     }
  7599.    
  7600.    
  7601.     public function StartCSAnim(buff : CBaseGameplayEffect) : bool
  7602.     {
  7603.        
  7604.         if(IsAnyQuenActive() && (W3CriticalDOTEffect)buff)
  7605.             return false;
  7606.            
  7607.         return super.StartCSAnim(buff);
  7608.     }
  7609.    
  7610.     public function GetPotionBuffLevel(effectType : EEffectType) : int
  7611.     {
  7612.         if(effectManager && effectManager.IsReady())
  7613.             return effectManager.GetPotionBuffLevel(effectType);
  7614.            
  7615.         return 0;
  7616.     }  
  7617.  
  7618.    
  7619.    
  7620.    
  7621.    
  7622.    
  7623.    
  7624.     event OnLevelGained(currentLevel : int, show : bool)
  7625.     {
  7626.         var hud : CR4ScriptedHud;
  7627.         hud = (CR4ScriptedHud)theGame.GetHud();
  7628.        
  7629.         if(abilityManager && abilityManager.IsInitialized())
  7630.         {
  7631.             ((W3PlayerAbilityManager)abilityManager).OnLevelGained(currentLevel);
  7632.         }
  7633.        
  7634.         if ( theGame.GetDifficultyMode() != EDM_Hardcore )
  7635.         {
  7636.             Heal(GetStatMax(BCS_Vitality));
  7637.         }
  7638.    
  7639.        
  7640.         if(currentLevel >= 35)
  7641.         {
  7642.             theGame.GetGamerProfile().AddAchievement(EA_Immortal);
  7643.         }
  7644.    
  7645.         if ( hud && currentLevel < levelManager.GetMaxLevel() && FactsQuerySum( "DebugNoLevelUpUpdates" ) == 0 )
  7646.         {
  7647.             hud.OnLevelUpUpdate(currentLevel, show);
  7648.         }
  7649.        
  7650.         theGame.RequestAutoSave( "level gained", false );
  7651.     }
  7652.    
  7653.     public function GetSignStats(skill : ESkill, out damageType : name, out damageVal : float, out spellPower : SAbilityAttributeValue)
  7654.     {
  7655.         var i, size : int;
  7656.         var dm : CDefinitionsManagerAccessor;
  7657.         var attrs : array<name>;
  7658.    
  7659.         spellPower = GetPowerStatValue(CPS_SpellPower);
  7660.        
  7661.         dm = theGame.GetDefinitionsManager();
  7662.         dm.GetAbilityAttributes(GetSkillAbilityName(skill), attrs);
  7663.         size = attrs.Size();
  7664.        
  7665.         for( i = 0; i < size; i += 1 )
  7666.         {
  7667.             if( IsDamageTypeNameValid(attrs[i]) )
  7668.             {
  7669.                 damageVal = CalculateAttributeValue(GetSkillAttributeValue(skill, attrs[i], false, true));
  7670.                 damageType = attrs[i];
  7671.                 break;
  7672.             }
  7673.         }
  7674.     }
  7675.        
  7676.    
  7677.     public function SetIgnorePainMaxVitality(val : float)
  7678.     {
  7679.         if(abilityManager && abilityManager.IsInitialized())
  7680.             abilityManager.SetStatPointMax(BCS_Vitality, val);
  7681.     }
  7682.    
  7683.     event OnAnimEvent_ActionBlend( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  7684.     {
  7685.         if ( animEventType == AET_DurationStart && !disableActionBlend )
  7686.         {
  7687.             if ( this.IsCastingSign() )
  7688.                 ProcessSignEvent( 'cast_end' );
  7689.            
  7690.            
  7691.             FindMoveTarget();
  7692.             SetCanPlayHitAnim( true );
  7693.             this.SetBIsCombatActionAllowed( true );
  7694.            
  7695.             if ( this.GetFinisherVictim() && this.GetFinisherVictim().HasAbility( 'ForceFinisher' ) && !isInFinisher )
  7696.             {
  7697.                 this.GetFinisherVictim().SignalGameplayEvent( 'Finisher' );
  7698.             }
  7699.             else if (this.BufferCombatAction != EBAT_EMPTY )
  7700.             {
  7701.                
  7702.                
  7703.                    
  7704.                     if ( !IsCombatMusicEnabled() )
  7705.                     {
  7706.                         SetCombatActionHeading( ProcessCombatActionHeading( this.BufferCombatAction ) );
  7707.                         FindTarget();
  7708.                         UpdateDisplayTarget( true );
  7709.                     }
  7710.            
  7711.                     if ( AllowAttack( GetTarget(), this.BufferCombatAction ) )
  7712.                         this.ProcessCombatActionBuffer();
  7713.             }
  7714.             else
  7715.             {
  7716.                
  7717.                 ResumeStaminaRegen( 'InsideCombatAction' );
  7718.                
  7719.                
  7720.                
  7721.             }
  7722.         }
  7723.         else if ( disableActionBlend )
  7724.         {
  7725.             disableActionBlend = false;
  7726.         }
  7727.     }
  7728.    
  7729.    
  7730.     event OnAnimEvent_Sign( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  7731.     {
  7732.         if( animEventType == AET_Tick )
  7733.         {
  7734.             ProcessSignEvent( animEventName );
  7735.         }
  7736.     }
  7737.    
  7738.     event OnAnimEvent_Throwable( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  7739.     {
  7740.         var thrownEntity        : CThrowable;  
  7741.        
  7742.         thrownEntity = (CThrowable)EntityHandleGet( thrownEntityHandle );
  7743.            
  7744.         if ( inv.IsItemCrossbow( inv.GetItemFromSlot('l_weapon') ) &&  rangedWeapon.OnProcessThrowEvent( animEventName ) )
  7745.         {      
  7746.             return true;
  7747.         }
  7748.         else if( thrownEntity && IsThrowingItem() && thrownEntity.OnProcessThrowEvent( animEventName ) )
  7749.         {
  7750.             return true;
  7751.         }
  7752.     }
  7753.    
  7754.     event OnTaskSyncAnim( npc : CNewNPC, animNameLeft : name )
  7755.     {
  7756.         var tmpBool : bool;
  7757.         var tmpName : name;
  7758.         var damage, points, resistance : float;
  7759.         var min, max : SAbilityAttributeValue;
  7760.         var mc : EMonsterCategory;
  7761.        
  7762.         super.OnTaskSyncAnim( npc, animNameLeft );
  7763.        
  7764.         if( animNameLeft == 'BruxaBite' && IsMutationActive( EPMT_Mutation4 ) )
  7765.         {
  7766.             theGame.GetMonsterParamsForActor( npc, mc, tmpName, tmpBool, tmpBool, tmpBool );
  7767.            
  7768.             if( mc == MC_Vampire )
  7769.             {
  7770.                 GetResistValue( CDS_BleedingRes, points, resistance );
  7771.                
  7772.                 theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'BleedingEffect', 'DirectDamage', min, max );
  7773.                 damage = MaxF( 0.f, max.valueMultiplicative * GetMaxHealth() - points );
  7774.                
  7775.                 theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'BleedingEffect', 'duration', min, max );
  7776.                 damage *= min.valueAdditive * ( 1 - MinF( 1.f, resistance ) );
  7777.                
  7778.                 if( damage > 0.f )
  7779.                 {
  7780.                     npc.AddAbility( 'Mutation4BloodDebuff' );
  7781.                     ProcessActionMutation4ReturnedDamage( damage, npc, EAHA_ForceNo );                 
  7782.                     npc.AddTimer( 'RemoveMutation4BloodDebuff', 15.f, , , , , true );
  7783.                 }
  7784.             }
  7785.         }
  7786.     }
  7787.    
  7788.    
  7789.     public function ProcessActionMutation4ReturnedDamage( damageDealt : float, attacker : CActor, hitAnimationType : EActionHitAnim, optional action : W3DamageAction ) : bool
  7790.     {
  7791.         var customParams                : SCustomEffectParams;
  7792.         var currToxicity                : float;
  7793.         var min, max, customDamageValue : SAbilityAttributeValue;
  7794.         var dm                          : CDefinitionsManagerAccessor;
  7795.         var animAction                  : W3DamageAction;
  7796.  
  7797.         if( damageDealt <= 0 )
  7798.         {
  7799.             return false;
  7800.         }
  7801.        
  7802.         if( action )
  7803.         {
  7804.             action.SetMutation4Triggered();
  7805.         }
  7806.            
  7807.         dm = theGame.GetDefinitionsManager();
  7808.         currToxicity = GetStat( BCS_Toxicity );
  7809.        
  7810.         dm.GetAbilityAttributeValue( 'AcidEffect', 'DirectDamage', min, max );
  7811.         customDamageValue.valueAdditive = damageDealt * min.valueAdditive;
  7812.        
  7813.         if( currToxicity > 0 )
  7814.         {
  7815.             customDamageValue.valueAdditive *= currToxicity;
  7816.         }
  7817.        
  7818.         dm.GetAbilityAttributeValue( 'AcidEffect', 'duration', min, max );
  7819.         customDamageValue.valueAdditive /= min.valueAdditive;
  7820.        
  7821.         customParams.effectType = EET_Acid;
  7822.         customParams.effectValue = customDamageValue;
  7823.         customParams.duration = min.valueAdditive;
  7824.         customParams.creator = this;
  7825.         customParams.sourceName = 'Mutation4';
  7826.        
  7827.         attacker.AddEffectCustom( customParams );
  7828.        
  7829.        
  7830.         animAction = new W3DamageAction in theGame;
  7831.         animAction.Initialize( this, attacker, NULL, 'Mutation4', EHRT_Reflect, CPS_Undefined, true, false, false, false );
  7832.         animAction.SetCannotReturnDamage( true );
  7833.         animAction.SetCanPlayHitParticle( false );
  7834.         animAction.SetHitAnimationPlayType( hitAnimationType );
  7835.         theGame.damageMgr.ProcessAction( animAction );
  7836.         delete animAction;
  7837.        
  7838.         theGame.MutationHUDFeedback( MFT_PlayOnce );
  7839.        
  7840.         return true;
  7841.     }
  7842.    
  7843.     event OnPlayerActionEnd()
  7844.     {
  7845.         var l_i             : int;
  7846.         var l_bed           : W3WitcherBed;
  7847.        
  7848.         l_i = (int)GetBehaviorVariable( 'playerExplorationAction' );
  7849.        
  7850.         if( l_i == PEA_GoToSleep )
  7851.         {
  7852.             l_bed = (W3WitcherBed)theGame.GetEntityByTag( 'witcherBed' );
  7853.             BlockAllActions( 'WitcherBed', false );
  7854.             l_bed.ApplyAppearance( "collision" );
  7855.             l_bed.GotoState( 'WakeUp' );
  7856.             theGame.ReleaseNoSaveLock( l_bed.m_bedSaveLock );
  7857.            
  7858.            
  7859.             substateManager.m_MovementCorrectorO.disallowRotWhenGoingToSleep = false;
  7860.         }
  7861.        
  7862.         super.OnPlayerActionEnd();
  7863.     }
  7864.    
  7865.     event OnPlayerActionStartFinished()
  7866.     {
  7867.         var l_initData          : W3SingleMenuInitData;    
  7868.         var l_i                 : int;
  7869.        
  7870.         l_i = (int)GetBehaviorVariable( 'playerExplorationAction' );
  7871.        
  7872.         if( l_i == PEA_GoToSleep )
  7873.         {
  7874.             //modFriendlyMeditation begin
  7875.             UnblockAction( EIAB_OpenMeditation, 'WitcherBed' );
  7876.             UnblockAction( EIAB_MeditationWaiting, 'WitcherBed' );
  7877.             //modFriendlyMeditation end
  7878.        
  7879.             l_initData = new W3SingleMenuInitData in this;
  7880.             l_initData.SetBlockOtherPanels( true );
  7881.             l_initData.ignoreSaveSystem = true;
  7882.             l_initData.ignoreMeditationCheck = true;
  7883.             l_initData.setDefaultState( '' );
  7884.             l_initData.isBonusMeditationAvailable = true;
  7885.             l_initData.fixedMenuName = 'MeditationClockMenu';
  7886.            
  7887.             theGame.RequestMenuWithBackground( 'MeditationClockMenu', 'CommonMenu', l_initData );
  7888.         }
  7889.        
  7890.         super.OnPlayerActionStartFinished();
  7891.     }
  7892.    
  7893.     public function IsInCombatAction_SpecialAttack() : bool
  7894.     {
  7895.         if ( IsInCombatAction() && ( GetCombatAction() == EBAT_SpecialAttack_Light || GetCombatAction() == EBAT_SpecialAttack_Heavy ) )
  7896.             return true;
  7897.         else
  7898.             return false;
  7899.     }
  7900.    
  7901.     public function IsInCombatAction_SpecialAttackHeavy() : bool
  7902.     {
  7903.         if ( IsInCombatAction() && GetCombatAction() == EBAT_SpecialAttack_Heavy )
  7904.             return true;
  7905.         else
  7906.             return false;
  7907.     }
  7908.    
  7909.     protected function WhenCombatActionIsFinished()
  7910.     {
  7911.         super.WhenCombatActionIsFinished();
  7912.         RemoveTimer( 'ProcessAttackTimer' );
  7913.         RemoveTimer( 'AttackTimerEnd' );
  7914.         CastSignAbort();
  7915.         specialAttackCamera = false;
  7916.         this.OnPerformSpecialAttack( true, false );
  7917.     }
  7918.    
  7919.     event OnCombatActionEnd()
  7920.     {
  7921.         var mutagen17 : W3Mutagen17_Effect; //modSigns
  7922.  
  7923.         //theGame.witcherLog.AddMessage("OnCombatActionEnd"); //modSigns: debug
  7924.  
  7925.         this.CleanCombatActionBuffer();    
  7926.         super.OnCombatActionEnd();
  7927.        
  7928.         RemoveTemporarySkills();
  7929.        
  7930.         //modSigns: clear mutagen17 effect
  7931.         if(HasBuff(EET_Mutagen17))
  7932.         {
  7933.             mutagen17 = (W3Mutagen17_Effect)GetBuff(EET_Mutagen17);
  7934.             if(mutagen17.HasBoost())
  7935.             {
  7936.                 mutagen17.ClearBoost();
  7937.                 //theGame.witcherLog.AddMessage("mutagen17 boost removed"); //modSigns: debug
  7938.             }
  7939.         }
  7940.     }
  7941.    
  7942.     event OnCombatActionFriendlyEnd()
  7943.     {
  7944.         if ( IsCastingSign() )
  7945.         {
  7946.             SetBehaviorVariable( 'IsCastingSign', 0 );
  7947.             SetCurrentlyCastSign( ST_None, NULL );
  7948.             LogChannel( 'ST_None', "ST_None" );                
  7949.         }
  7950.  
  7951.         super.OnCombatActionFriendlyEnd();
  7952.     }
  7953.    
  7954.     public function GetPowerStatValue( stat : ECharacterPowerStats, optional ablName : name, optional ignoreDeath : bool ) : SAbilityAttributeValue
  7955.     {
  7956.         var result :  SAbilityAttributeValue;
  7957.        
  7958.        
  7959.         result = super.GetPowerStatValue( stat, ablName, ignoreDeath );
  7960.         //modSigns: W3DamageAction.GetPowerStatValue calls for actor.GetPowerStatValue twice:
  7961.         //second time with attackName as ablName to obtain attack specific boosts, so Euphoria boost ends up
  7962.         //being applied twice. Character stats for popup menu don't use ablName as there is no attack and no attackName,
  7963.         //so bonus is displayed properly there, but gets doubled when actual damage is calculated in combat.
  7964.         //To fix this we need to check for non-ability specific calls:
  7965.         if( !IsNameValid(ablName) && stat != CPS_Undefined )
  7966.             ApplyMutation10StatBoost( result );
  7967.        
  7968.         return result;
  7969.     }
  7970.    
  7971.    
  7972.    
  7973.     timer function OpenRadialMenu( time: float, id : int )
  7974.     {
  7975.        
  7976.         if( GetBIsCombatActionAllowed() && !IsUITakeInput() )
  7977.         {
  7978.             bShowRadialMenu = true;
  7979.         }
  7980.        
  7981.         this.RemoveTimer('OpenRadialMenu');
  7982.     }
  7983.    
  7984.     public function OnAddRadialMenuOpenTimer(  )
  7985.     {
  7986.        
  7987.        
  7988.        
  7989.            
  7990.            
  7991.             this.AddTimer('OpenRadialMenu', _HoldBeforeOpenRadialMenuTime * theGame.GetTimeScale() );
  7992.        
  7993.     }
  7994.  
  7995.     public function SetShowRadialMenuOpenFlag( bSet : bool  )
  7996.     {
  7997.        
  7998.         bShowRadialMenu = bSet;
  7999.     }
  8000.    
  8001.     public function OnRemoveRadialMenuOpenTimer()
  8002.     {
  8003.        
  8004.         this.RemoveTimer('OpenRadialMenu');
  8005.     }
  8006.    
  8007.     public function ResetRadialMenuOpenTimer()
  8008.     {
  8009.        
  8010.         this.RemoveTimer('OpenRadialMenu');
  8011.         if( GetBIsCombatActionAllowed() )
  8012.         {
  8013.            
  8014.            
  8015.             AddTimer('OpenRadialMenu', _HoldBeforeOpenRadialMenuTime * theGame.GetTimeScale() );
  8016.         }
  8017.     }
  8018.  
  8019.    
  8020.    
  8021.     timer function ResendCompanionDisplayName(dt : float, id : int)
  8022.     {
  8023.         var hud : CR4ScriptedHud;
  8024.         var companionModule : CR4HudModuleCompanion;
  8025.        
  8026.         hud = (CR4ScriptedHud)theGame.GetHud();
  8027.         if( hud )
  8028.         {
  8029.             companionModule = (CR4HudModuleCompanion)hud.GetHudModule("CompanionModule");
  8030.             if( companionModule )
  8031.             {
  8032.                 companionModule.ResendDisplayName();
  8033.             }
  8034.         }
  8035.     }
  8036.  
  8037.     timer function ResendCompanionDisplayNameSecond(dt : float, id : int)
  8038.     {
  8039.         var hud : CR4ScriptedHud;
  8040.         var companionModule : CR4HudModuleCompanion;
  8041.        
  8042.         hud = (CR4ScriptedHud)theGame.GetHud();
  8043.         if( hud )
  8044.         {
  8045.             companionModule = (CR4HudModuleCompanion)hud.GetHudModule("CompanionModule");
  8046.             if( companionModule )
  8047.             {
  8048.                 companionModule.ResendDisplayNameSecond();
  8049.             }
  8050.         }
  8051.     }
  8052.    
  8053.     public function RemoveCompanionDisplayNameTimer()
  8054.     {
  8055.         this.RemoveTimer('ResendCompanionDisplayName');
  8056.     }
  8057.        
  8058.     public function RemoveCompanionDisplayNameTimerSecond()
  8059.     {
  8060.         this.RemoveTimer('ResendCompanionDisplayNameSecond');
  8061.     }
  8062.    
  8063.        
  8064.     public function GetCompanionNPCTag() : name
  8065.     {
  8066.         return companionNPCTag;
  8067.     }
  8068.  
  8069.     public function SetCompanionNPCTag( value : name )
  8070.     {
  8071.         companionNPCTag = value;
  8072.     }  
  8073.  
  8074.     public function GetCompanionNPCTag2() : name
  8075.     {
  8076.         return companionNPCTag2;
  8077.     }
  8078.  
  8079.     public function SetCompanionNPCTag2( value : name )
  8080.     {
  8081.         companionNPCTag2 = value;
  8082.     }
  8083.  
  8084.     public function GetCompanionNPCIconPath() : string
  8085.     {
  8086.         return companionNPCIconPath;
  8087.     }
  8088.  
  8089.     public function SetCompanionNPCIconPath( value : string )
  8090.     {
  8091.         companionNPCIconPath = value;
  8092.     }
  8093.  
  8094.     public function GetCompanionNPCIconPath2() : string
  8095.     {
  8096.         return companionNPCIconPath2;
  8097.     }
  8098.  
  8099.     public function SetCompanionNPCIconPath2( value : string )
  8100.     {
  8101.         companionNPCIconPath2 = value;
  8102.     }
  8103.    
  8104.    
  8105.  
  8106.     //modSigns: chance to ignore hit anim
  8107.     /*public function GetChanceToIgnoreHitAnim() : float
  8108.     {
  8109.         var armorPieces : array<int>;
  8110.        
  8111.         inv.CountArmorPieces(armorPieces);
  8112.         return armorPieces[0] * 0 + armorPieces[1] * 2.5 + armorPieces[2] * 10;
  8113.     }*/
  8114.    
  8115.     public function ReactToBeingHit(damageAction : W3DamageAction, optional buffNotApplied : bool) : bool
  8116.     {
  8117.         //var chance : float;
  8118.         //var procQuen : W3SignEntity;
  8119.        
  8120.         if(IsThrowingItem() || IsThrowingItemWithAim()) //modSigns: no need to abort throwing if not in fact throwing
  8121.         {
  8122.             if(!damageAction.IsDoTDamage() && damageAction.DealsAnyDamage() && damageAction.GetHitAnimationPlayType() != EAHA_ForceNo) //modSigns
  8123.             {
  8124.                 if(inv.IsItemBomb(selectedItemId))
  8125.                 {
  8126.                     BombThrowAbort();
  8127.                 }
  8128.                 else
  8129.                 {
  8130.                     ThrowingAbort();
  8131.                 }          
  8132.             }
  8133.         }
  8134.        
  8135.        
  8136.         /*if(damageAction.IsActionRanged())
  8137.         {
  8138.             chance = CalculateAttributeValue(GetAttributeValue('quen_chance_on_projectile'));
  8139.             if(chance > 0)
  8140.             {
  8141.                 chance = ClampF(chance, 0, 1);
  8142.                
  8143.                 if(RandF() < chance)
  8144.                 {
  8145.                     procQuen = (W3SignEntity)theGame.CreateEntity(signs[ST_Quen].template, GetWorldPosition(), GetWorldRotation() );
  8146.                     procQuen.Init(signOwner, signs[ST_Quen].entity, true );
  8147.                     procQuen.OnStarted();
  8148.                     procQuen.OnThrowing();
  8149.                     procQuen.OnEnded();
  8150.                 }
  8151.             }
  8152.         }*/ //modSigns: moved to reduce damage
  8153.        
  8154.        
  8155.         if( !((W3Effect_Toxicity)damageAction.causer) )
  8156.             MeditationForceAbort(true);
  8157.        
  8158.        
  8159.         if(IsDoingSpecialAttack(false))
  8160.             damageAction.SetHitAnimationPlayType(EAHA_ForceNo);
  8161.        
  8162.         return super.ReactToBeingHit(damageAction, buffNotApplied);
  8163.     }
  8164.    
  8165.     protected function ShouldPauseHealthRegenOnHit() : bool
  8166.     {
  8167.        
  8168.         if( ( HasBuff( EET_Swallow ) && GetPotionBuffLevel( EET_Swallow ) >= 3 ) || HasBuff( EET_Runeword8 ) || HasBuff( EET_Mutation11Buff ) || HasBuff( EET_UndyingSkillImmortal ) ) //modSigns
  8169.         {
  8170.             return false;
  8171.         }
  8172.            
  8173.         return true;
  8174.     }
  8175.        
  8176.     public function SetMappinToHighlight( mappinName : name, mappinState : bool )
  8177.     {
  8178.         var mappinDef : SHighlightMappin;
  8179.         mappinDef.MappinName = mappinName;
  8180.         mappinDef.MappinState = mappinState;
  8181.         MappinToHighlight.PushBack(mappinDef);
  8182.     }  
  8183.  
  8184.     public function ClearMappinToHighlight()
  8185.     {
  8186.         MappinToHighlight.Clear();
  8187.     }
  8188.    
  8189.     public function CastSignAbort()
  8190.     {
  8191.         if( currentlyCastSign != ST_None && signs[currentlyCastSign].entity)
  8192.         {
  8193.             signs[currentlyCastSign].entity.OnSignAborted();
  8194.         }
  8195.        
  8196.        
  8197.     }
  8198.    
  8199.     event OnBlockingSceneStarted( scene: CStoryScene )
  8200.     {
  8201.         //---=== modFriendlyMeditation ===---
  8202.         //var med : W3PlayerWitcherStateMeditationWaiting;
  8203.         //     
  8204.         //
  8205.         //med = (W3PlayerWitcherStateMeditationWaiting)GetCurrentState();
  8206.         //if(med)
  8207.         //{
  8208.         //  med.StopRequested(true);
  8209.         //}
  8210.         ModEndMeditation();
  8211.         //---=== modFriendlyMeditation ===---
  8212.        
  8213.        
  8214.         super.OnBlockingSceneStarted( scene );
  8215.     }
  8216.    
  8217.    
  8218.    
  8219.    
  8220.    
  8221.     public function GetHorseManager() : W3HorseManager
  8222.     {
  8223.         return (W3HorseManager)EntityHandleGet( horseManagerHandle );
  8224.     }
  8225.    
  8226.    
  8227.     public function HorseEquipItem(horsesItemId : SItemUniqueId) : bool
  8228.     {
  8229.         var man : W3HorseManager;
  8230.        
  8231.         man = GetHorseManager();
  8232.         if(man)
  8233.             return man.EquipItem(horsesItemId) != GetInvalidUniqueId();
  8234.            
  8235.         return false;
  8236.     }
  8237.    
  8238.    
  8239.     public function HorseUnequipItem(slot : EEquipmentSlots) : bool
  8240.     {
  8241.         var man : W3HorseManager;
  8242.        
  8243.         man = GetHorseManager();
  8244.         if(man)
  8245.             return man.UnequipItem(slot) != GetInvalidUniqueId();
  8246.            
  8247.         return false;
  8248.     }
  8249.    
  8250.    
  8251.     public final function HorseRemoveItemByName(itemName : name, quantity : int)
  8252.     {
  8253.         var man : W3HorseManager;
  8254.        
  8255.         man = GetHorseManager();
  8256.         if(man)
  8257.             man.HorseRemoveItemByName(itemName, quantity);
  8258.     }
  8259.    
  8260.    
  8261.     public final function HorseRemoveItemByCategory(itemCategory : name, quantity : int)
  8262.     {
  8263.         var man : W3HorseManager;
  8264.        
  8265.         man = GetHorseManager();
  8266.         if(man)
  8267.             man.HorseRemoveItemByCategory(itemCategory, quantity);
  8268.     }
  8269.    
  8270.    
  8271.     public final function HorseRemoveItemByTag(itemTag : name, quantity : int)
  8272.     {
  8273.         var man : W3HorseManager;
  8274.        
  8275.         man = GetHorseManager();
  8276.         if(man)
  8277.             man.HorseRemoveItemByTag(itemTag, quantity);
  8278.     }
  8279.    
  8280.     public function GetAssociatedInventory() : CInventoryComponent
  8281.     {
  8282.         var man : W3HorseManager;
  8283.        
  8284.         man = GetHorseManager();
  8285.         if(man)
  8286.             return man.GetInventoryComponent();
  8287.            
  8288.         return NULL;
  8289.     }
  8290.    
  8291.    
  8292.    
  8293.    
  8294.    
  8295.     public final function TutorialMutagensUnequipPlayerSkills() : array<STutorialSavedSkill>
  8296.     {
  8297.         var pam : W3PlayerAbilityManager;
  8298.        
  8299.         pam = (W3PlayerAbilityManager)abilityManager;
  8300.         return pam.TutorialMutagensUnequipPlayerSkills();
  8301.     }
  8302.    
  8303.     public final function TutorialMutagensEquipOneGoodSkill()
  8304.     {
  8305.         var pam : W3PlayerAbilityManager;
  8306.        
  8307.         pam = (W3PlayerAbilityManager)abilityManager;
  8308.         pam.TutorialMutagensEquipOneGoodSkill();
  8309.     }
  8310.    
  8311.     public final function TutorialMutagensEquipOneGoodOneBadSkill()
  8312.     {
  8313.         var pam : W3PlayerAbilityManager;
  8314.        
  8315.         pam = (W3PlayerAbilityManager)abilityManager;
  8316.         if(pam)
  8317.             pam.TutorialMutagensEquipOneGoodOneBadSkill();
  8318.     }
  8319.    
  8320.     public final function TutorialMutagensEquipThreeGoodSkills()
  8321.     {
  8322.         var pam : W3PlayerAbilityManager;
  8323.        
  8324.         pam = (W3PlayerAbilityManager)abilityManager;
  8325.         if(pam)
  8326.             pam.TutorialMutagensEquipThreeGoodSkills();
  8327.     }
  8328.    
  8329.     public final function TutorialMutagensCleanupTempSkills(savedEquippedSkills : array<STutorialSavedSkill>)
  8330.     {
  8331.         var pam : W3PlayerAbilityManager;
  8332.        
  8333.         pam = (W3PlayerAbilityManager)abilityManager;
  8334.         return pam.TutorialMutagensCleanupTempSkills(savedEquippedSkills);
  8335.     }
  8336.    
  8337.    
  8338.    
  8339.    
  8340.    
  8341.     //modSigns: redone
  8342.     public final function CalculatedArmorStaminaRegenBonus() : float
  8343.     {
  8344.         var armorEq, glovesEq, pantsEq, bootsEq : bool;
  8345.         var armorId, glovesId, pantsId, bootsId : SItemUniqueId;
  8346.         var staminaRegenVal : float;
  8347.         var armorRegenVal : SAbilityAttributeValue;
  8348.        
  8349.         //base armor stamina regen bonus/penalty
  8350.         armorRegenVal = GetAttributeValue('staminaRegen_armor_mod');
  8351.         staminaRegenVal = armorRegenVal.valueMultiplicative;
  8352.  
  8353.         //equipped pieces
  8354.         armorEq = inv.GetItemEquippedOnSlot( EES_Armor, armorId );
  8355.         glovesEq = inv.GetItemEquippedOnSlot( EES_Gloves, glovesId );
  8356.         pantsEq = inv.GetItemEquippedOnSlot( EES_Pants, pantsId );
  8357.         bootsEq = inv.GetItemEquippedOnSlot( EES_Boots, bootsId );
  8358.        
  8359.         //glyphwords change stamina, not replace it
  8360.         if( HasGlyphwordActive( 'Glyphword 2 _Stats' ) )
  8361.         {
  8362.             if ( armorEq && !inv.ItemHasTag(armorId, 'LightArmor') )
  8363.                 staminaRegenVal += 0.07;
  8364.             if ( glovesEq && !inv.ItemHasTag(glovesId, 'LightArmor') )
  8365.                 staminaRegenVal += 0.01;
  8366.             if ( pantsEq && !inv.ItemHasTag(pantsId, 'LightArmor') )
  8367.                 staminaRegenVal += 0.01;
  8368.             if ( bootsEq && !inv.ItemHasTag(bootsId, 'LightArmor') )
  8369.                 staminaRegenVal += 0.01;
  8370.         }
  8371.         else if( HasGlyphwordActive( 'Glyphword 3 _Stats' ) )
  8372.         {
  8373.         }
  8374.         else if( HasGlyphwordActive( 'Glyphword 4 _Stats' ) )
  8375.         {
  8376.             if ( armorEq && !inv.ItemHasTag(armorId, 'HeavyArmor') )
  8377.                 staminaRegenVal -= 0.20;
  8378.             if ( glovesEq && !inv.ItemHasTag(glovesId, 'HeavyArmor') )
  8379.                 staminaRegenVal -= 0.025;
  8380.             if ( pantsEq && !inv.ItemHasTag(pantsId, 'HeavyArmor') )
  8381.                 staminaRegenVal -= 0.025;
  8382.             if ( bootsEq && !inv.ItemHasTag(bootsId, 'HeavyArmor') )
  8383.                 staminaRegenVal -= 0.05;
  8384.         }
  8385.  
  8386.         //stamina regen bonus for missing armor pieces
  8387.         if ( !armorEq )
  8388.             staminaRegenVal += 0.11;
  8389.         if ( !glovesEq )
  8390.             staminaRegenVal += 0.02;
  8391.         if ( !pantsEq )
  8392.             staminaRegenVal += 0.03;
  8393.         if ( !bootsEq )
  8394.             staminaRegenVal += 0.04;
  8395.        
  8396.         //debug
  8397.         //theGame.witcherLog.AddMessage( "staminaRegenVal = " + staminaRegenVal );
  8398.  
  8399.         return staminaRegenVal;
  8400.     }
  8401.    
  8402.     //modSigns: reworked
  8403.     public function GetOffenseStatsList( optional hackMode : int ) : SPlayerOffenseStats
  8404.     {
  8405.         var playerOffenseStats : SPlayerOffenseStats;
  8406.         var min, max, value : SAbilityAttributeValue;
  8407.         var attackPower : SAbilityAttributeValue;
  8408.         var fastAPBonus, strongAPBonus, steelAPBonus, silverAPBonus : SAbilityAttributeValue;
  8409.         var critChance, critPowerBonus, fastCritChanceBonus, strongCritChanceBonus, fastCritPowerBonus, strongCritPowerBonus : float;
  8410.         var steelCritChanceBonus, silverCritChanceBonus, steelCritPowerBonus, silverCritPowerBonus : float;
  8411.         var steelDmg, silverDmg, elementalSteel, elementalSilver : float;
  8412.         var attackPowerCrossbow : SAbilityAttributeValue;
  8413.         var silverSword, steelSword, crossbow, bolt : SItemUniqueId;
  8414.         var mutagen : CBaseGameplayEffect;
  8415.         var thunder : W3Potion_Thunderbolt;
  8416.         var strongDmgMult, bonusDmgMult, bonusDmgMultCrossbow, bonusDmgMultSteel, bonusDmgMultSilver : float;
  8417.         var steelFastAP, silverFastAP, steelStrongAP, silverStrongAP, steelFastCritAP, silverFastCritAP, steelStrongCritAP, silverStrongCritAP : SAbilityAttributeValue;
  8418.         var steelFastCritChance, silverFastCritChance, steelStrongCritChance, silverStrongCritChance : float;
  8419.        
  8420.         if(!abilityManager || !abilityManager.IsInitialized())
  8421.             return playerOffenseStats;
  8422.        
  8423.         //base damage increase for heavy attacks
  8424.         value = GetSkillAttributeValue(S_Sword_2, 'heavy_attack_dmg_boost', false, true);
  8425.         strongDmgMult = 1 + value.valueMultiplicative;
  8426.  
  8427.         //generic bonuses
  8428.         attackPower = GetPowerStatValue(CPS_AttackPower);
  8429.         critChance = CalculateAttributeValue(GetAttributeValue(theGame.params.CRITICAL_HIT_CHANCE));
  8430.         critPowerBonus = CalculateAttributeValue(GetAttributeValue(theGame.params.CRITICAL_HIT_DAMAGE_BONUS));
  8431.        
  8432.         //attack type specific bonuses
  8433.         fastAPBonus = GetSkillAttributeValue(S_Sword_1, PowerStatEnumToName(CPS_AttackPower), false, true);
  8434.         strongAPBonus = GetSkillAttributeValue(S_Sword_2, PowerStatEnumToName(CPS_AttackPower), false, true);
  8435.         if (CanUseSkill(S_Sword_s21))
  8436.             fastAPBonus += GetSkillAttributeValue(S_Sword_s21, PowerStatEnumToName(CPS_AttackPower), false, true) * GetSkillLevel(S_Sword_s21);
  8437.         if (CanUseSkill(S_Sword_s04))
  8438.             strongAPBonus += GetSkillAttributeValue(S_Sword_s04, PowerStatEnumToName(CPS_AttackPower), false, true) * GetSkillLevel(S_Sword_s04);
  8439.         if (CanUseSkill(S_Sword_s17))
  8440.         {
  8441.             fastCritChanceBonus = CalculateAttributeValue(GetSkillAttributeValue(S_Sword_s17, theGame.params.CRITICAL_HIT_CHANCE, false, true)) * GetSkillLevel(S_Sword_s17);
  8442.             fastCritPowerBonus = CalculateAttributeValue(GetSkillAttributeValue(S_Sword_s17, theGame.params.CRITICAL_HIT_DAMAGE_BONUS, false, true)) * GetSkillLevel(S_Sword_s17);
  8443.         }
  8444.         if (CanUseSkill(S_Sword_s08))
  8445.         {
  8446.             strongCritChanceBonus = CalculateAttributeValue(GetSkillAttributeValue(S_Sword_s08, theGame.params.CRITICAL_HIT_CHANCE, false, true)) * GetSkillLevel(S_Sword_s08);
  8447.             strongCritPowerBonus = CalculateAttributeValue(GetSkillAttributeValue(S_Sword_s08, theGame.params.CRITICAL_HIT_DAMAGE_BONUS, false, true)) * GetSkillLevel(S_Sword_s08);
  8448.         }
  8449.        
  8450.         //steel sword specific bonuses
  8451.         if (GetItemEquippedOnSlot(EES_SteelSword, steelSword))
  8452.         {
  8453.             steelDmg = GetTotalWeaponDamage(steelSword, theGame.params.DAMAGE_NAME_SLASHING, GetInvalidUniqueId());
  8454.             steelDmg += GetTotalWeaponDamage(steelSword, theGame.params.DAMAGE_NAME_PIERCING, GetInvalidUniqueId());
  8455.             steelDmg += GetTotalWeaponDamage(steelSword, theGame.params.DAMAGE_NAME_BLUDGEONING, GetInvalidUniqueId());
  8456.             elementalSteel = CalculateAttributeValue(GetInventory().GetItemAttributeValue(steelSword, theGame.params.DAMAGE_NAME_FIRE));
  8457.             elementalSteel += CalculateAttributeValue(GetInventory().GetItemAttributeValue(steelSword, theGame.params.DAMAGE_NAME_FROST));
  8458.             elementalSteel += CalculateAttributeValue(GetInventory().GetItemAttributeValue(steelSword, theGame.params.DAMAGE_NAME_POISON)); //modSigns
  8459.             //weapon bonuses are added OnHold, so we need to retrieve them specifically if we want to show them
  8460.             if (!GetInventory().IsItemHeld(steelSword))
  8461.             {
  8462.                 steelCritChanceBonus += CalculateAttributeValue(GetInventory().GetItemAttributeValue(steelSword, theGame.params.CRITICAL_HIT_CHANCE));
  8463.                 steelCritPowerBonus += CalculateAttributeValue(GetInventory().GetItemAttributeValue(steelSword, theGame.params.CRITICAL_HIT_DAMAGE_BONUS));
  8464.                 steelAPBonus += GetInventory().GetItemAttributeValue(steelSword, 'attack_power');
  8465.             }
  8466.             //New bonus for Chernobog rune
  8467.             bonusDmgMultSteel += CalculateAttributeValue(GetInventory().GetItemAttributeValue(steelSword, 'sword_dmg_bonus'));
  8468.         }
  8469.        
  8470.         //silver sword specific bonuses
  8471.         if (GetItemEquippedOnSlot(EES_SilverSword, silverSword))
  8472.         {
  8473.             silverDmg = GetTotalWeaponDamage(silverSword, theGame.params.DAMAGE_NAME_SILVER, GetInvalidUniqueId());
  8474.             elementalSilver = CalculateAttributeValue(GetInventory().GetItemAttributeValue(silverSword, theGame.params.DAMAGE_NAME_FIRE));
  8475.             elementalSilver += CalculateAttributeValue(GetInventory().GetItemAttributeValue(silverSword, theGame.params.DAMAGE_NAME_FROST));
  8476.             elementalSilver += CalculateAttributeValue(GetInventory().GetItemAttributeValue(silverSword, theGame.params.DAMAGE_NAME_POISON)); //modSigns
  8477.             //weapon bonuses are added OnHold, so we need to retrieve them specifically if we want to show them
  8478.             if (!GetInventory().IsItemHeld(silverSword))
  8479.             {
  8480.                 silverCritChanceBonus += CalculateAttributeValue(GetInventory().GetItemAttributeValue(silverSword, theGame.params.CRITICAL_HIT_CHANCE));
  8481.                 silverCritPowerBonus += CalculateAttributeValue(GetInventory().GetItemAttributeValue(silverSword, theGame.params.CRITICAL_HIT_DAMAGE_BONUS));
  8482.                 silverAPBonus += GetInventory().GetItemAttributeValue(silverSword, 'attack_power');
  8483.             }
  8484.             //New bonus for Chernobog rune
  8485.             bonusDmgMultSilver += CalculateAttributeValue(GetInventory().GetItemAttributeValue(silverSword, 'sword_dmg_bonus'));
  8486.         }
  8487.        
  8488.         //since drawn sword adds its stats to character stats, we now need to do this hackiest shit ever
  8489.         if (GetInventory().IsItemHeld(steelSword))
  8490.         {
  8491.             //remove steel bonuses from silver stats
  8492.             silverCritChanceBonus -= CalculateAttributeValue(GetInventory().GetItemAttributeValue(steelSword, theGame.params.CRITICAL_HIT_CHANCE));
  8493.             silverCritPowerBonus -= CalculateAttributeValue(GetInventory().GetItemAttributeValue(steelSword, theGame.params.CRITICAL_HIT_DAMAGE_BONUS));
  8494.             silverAPBonus -= GetInventory().GetItemAttributeValue(steelSword, 'attack_power');
  8495.         }
  8496.         if (GetInventory().IsItemHeld(silverSword))
  8497.         {
  8498.             //remove silver bonuses from steel stats
  8499.             steelCritChanceBonus -= CalculateAttributeValue(GetInventory().GetItemAttributeValue(silverSword, theGame.params.CRITICAL_HIT_CHANCE));
  8500.             steelCritPowerBonus -= CalculateAttributeValue(GetInventory().GetItemAttributeValue(silverSword, theGame.params.CRITICAL_HIT_DAMAGE_BONUS));
  8501.             steelAPBonus -= GetInventory().GetItemAttributeValue(silverSword, 'attack_power');
  8502.         }
  8503.  
  8504.         //Overheal bonus from the enchantment
  8505.         if ( HasRunewordActive('Runeword 4 _Stats') ) //modSigns
  8506.         {
  8507.             if( GetInventory().IsItemHeld(steelSword) )
  8508.                 bonusDmgMultSteel += abilityManager.GetOverhealBonus() / GetStatMax(BCS_Vitality);
  8509.             else if (GetInventory().IsItemHeld(silverSword))
  8510.                 bonusDmgMultSilver += abilityManager.GetOverhealBonus() / GetStatMax(BCS_Vitality);
  8511.         }
  8512.         //Thunderbolt lvl 3 crit chance
  8513.         thunder = (W3Potion_Thunderbolt)GetBuff(EET_Thunderbolt);
  8514.         if(thunder && thunder.GetBuffLevel() == 3 && GetCurWeather() == EWE_Storm)
  8515.         {
  8516.             critPowerBonus += 1.0f;
  8517.         }
  8518.         //Water Hag decoction
  8519.         if ( HasBuff(EET_Mutagen05) && GetHealthPercents() > 0.99 )
  8520.         {
  8521.             mutagen = GetBuff(EET_Mutagen05);
  8522.             theGame.GetDefinitionsManager().GetAbilityAttributeValue(mutagen.GetAbilityName(), 'damageIncrease', min, max);
  8523.             bonusDmgMult += min.valueMultiplicative;
  8524.         }
  8525.         //new bonus for grindstone
  8526.         if(HasBuff(EET_EnhancedWeapon))
  8527.             bonusDmgMult += CalculateAttributeValue(GetAbilityAttributeValue('EnhancedWeaponEffect', 'sword_dmg_bonus'));
  8528.        
  8529.         //final attributes
  8530.         steelFastAP = attackPower + fastAPBonus + steelAPBonus;
  8531.         silverFastAP = attackPower + fastAPBonus + silverAPBonus;
  8532.         steelStrongAP = attackPower + strongAPBonus + steelAPBonus;
  8533.         silverStrongAP = attackPower + strongAPBonus + silverAPBonus;
  8534.         steelFastCritAP = steelFastAP;
  8535.         steelFastCritAP.valueMultiplicative += critPowerBonus + fastCritPowerBonus + steelCritPowerBonus;
  8536.         silverFastCritAP = silverFastAP;
  8537.         silverFastCritAP.valueMultiplicative += critPowerBonus + fastCritPowerBonus + silverCritPowerBonus;
  8538.         steelStrongCritAP = steelStrongAP;
  8539.         steelStrongCritAP.valueMultiplicative += critPowerBonus + strongCritPowerBonus + steelCritPowerBonus;
  8540.         silverStrongCritAP = silverStrongAP;
  8541.         silverStrongCritAP.valueMultiplicative += critPowerBonus + strongCritPowerBonus + silverCritPowerBonus;
  8542.         steelFastCritChance = critChance + fastCritChanceBonus + steelCritChanceBonus;
  8543.         silverFastCritChance = critChance + fastCritChanceBonus + silverCritChanceBonus;
  8544.         steelStrongCritChance = critChance + strongCritChanceBonus + steelCritChanceBonus;
  8545.         silverStrongCritChance = critChance + strongCritChanceBonus + silverCritChanceBonus;
  8546.        
  8547.         //fill offense stats
  8548.         playerOffenseStats.steelFastAP = steelFastAP.valueMultiplicative;
  8549.         playerOffenseStats.silverFastAP = silverFastAP.valueMultiplicative;
  8550.         playerOffenseStats.steelStrongAP = steelStrongAP.valueMultiplicative;
  8551.         playerOffenseStats.silverStrongAP = silverStrongAP.valueMultiplicative;
  8552.         playerOffenseStats.steelFastCritAP = steelFastCritAP.valueMultiplicative;
  8553.         playerOffenseStats.silverFastCritAP = silverFastCritAP.valueMultiplicative;
  8554.         playerOffenseStats.steelStrongCritAP = steelStrongCritAP.valueMultiplicative;
  8555.         playerOffenseStats.silverStrongCritAP = silverStrongCritAP.valueMultiplicative;
  8556.         playerOffenseStats.steelFastCritChance = steelFastCritChance * 100;
  8557.         playerOffenseStats.silverFastCritChance = silverFastCritChance * 100;
  8558.         playerOffenseStats.steelStrongCritChance = steelStrongCritChance * 100;
  8559.         playerOffenseStats.silverStrongCritChance = silverStrongCritChance * 100;
  8560.         if ( steelDmg != 0 )
  8561.         {
  8562.             playerOffenseStats.steelFastDmg = ((steelDmg + elementalSteel) * (1 + bonusDmgMult + bonusDmgMultSteel) + steelFastAP.valueBase) * steelFastAP.valueMultiplicative + steelFastAP.valueAdditive;
  8563.             playerOffenseStats.steelFastCritDmg = ((steelDmg + elementalSteel) * (1 + bonusDmgMult + bonusDmgMultSteel) + steelFastCritAP.valueBase) * steelFastCritAP.valueMultiplicative + steelFastCritAP.valueAdditive;
  8564.             playerOffenseStats.steelFastDPS = playerOffenseStats.steelFastDmg * (1 - steelFastCritChance) + playerOffenseStats.steelFastCritDmg * steelFastCritChance;
  8565.             playerOffenseStats.steelStrongDmg = ((steelDmg + elementalSteel) * (strongDmgMult + bonusDmgMult + bonusDmgMultSteel) + steelStrongAP.valueBase) * steelStrongAP.valueMultiplicative + steelStrongAP.valueAdditive;
  8566.             playerOffenseStats.steelStrongCritDmg = ((steelDmg + elementalSteel) * (strongDmgMult + bonusDmgMult + bonusDmgMultSteel) + steelStrongCritAP.valueBase) * steelStrongCritAP.valueMultiplicative + steelStrongCritAP.valueAdditive;
  8567.             playerOffenseStats.steelStrongDPS = playerOffenseStats.steelStrongDmg * (1 - steelStrongCritChance) + playerOffenseStats.steelStrongCritDmg * steelStrongCritChance;
  8568.         }
  8569.         if ( silverDmg != 0 )
  8570.         {
  8571.             playerOffenseStats.silverFastDmg = ((silverDmg + elementalSilver) * (1 + bonusDmgMult + bonusDmgMultSilver) + silverFastAP.valueBase) * silverFastAP.valueMultiplicative + silverFastAP.valueAdditive;
  8572.             playerOffenseStats.silverFastCritDmg = ((silverDmg + elementalSilver) * (1 + bonusDmgMult + bonusDmgMultSilver) + silverFastCritAP.valueBase) * silverFastCritAP.valueMultiplicative + silverFastCritAP.valueAdditive;
  8573.             playerOffenseStats.silverFastDPS = playerOffenseStats.silverFastDmg * (1 - silverFastCritChance) + playerOffenseStats.silverFastCritDmg * silverFastCritChance;
  8574.             playerOffenseStats.silverStrongDmg = ((silverDmg + elementalSilver) * (strongDmgMult + bonusDmgMult + bonusDmgMultSilver) + silverStrongAP.valueBase) * silverStrongAP.valueMultiplicative + silverStrongAP.valueAdditive;
  8575.             playerOffenseStats.silverStrongCritDmg = ((silverDmg + elementalSilver) * (strongDmgMult + bonusDmgMult + bonusDmgMultSilver) + silverStrongCritAP.valueBase) * silverStrongCritAP.valueMultiplicative + silverStrongCritAP.valueAdditive;
  8576.             playerOffenseStats.silverStrongDPS = playerOffenseStats.silverStrongDmg * (1 - silverStrongCritChance) + playerOffenseStats.silverStrongCritDmg * silverStrongCritChance;
  8577.         }
  8578.        
  8579.         //modSigns: crossbow redone
  8580.         playerOffenseStats.crossbowSteelDmgType = theGame.params.DAMAGE_NAME_PIERCING;
  8581.         playerOffenseStats.crossbowElementaDmgType = '';
  8582.         if (GetItemEquippedOnSlot(EES_RangedWeapon, crossbow))
  8583.         {
  8584.             attackPowerCrossbow = attackPower + GetInventory().GetItemAttributeValue(crossbow, PowerStatEnumToName(CPS_AttackPower));
  8585.             playerOffenseStats.crossbowAttackPower = attackPowerCrossbow.valueMultiplicative;
  8586.             playerOffenseStats.crossbowCritChance = GetCriticalHitChance( false, false, NULL, MC_NotSet, true );
  8587.  
  8588.             value = GetCriticalHitDamageBonus( crossbow, MC_NotSet, false );
  8589.             //Cat Eyes mutation crit damage boost
  8590.             if( IsMutationActive( EPMT_Mutation9 ) )
  8591.             {
  8592.                 theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation9', 'critical_damage', min, max );
  8593.                 value += min;
  8594.             }
  8595.             if( CanUseSkill(S_Sword_s07) )
  8596.             {
  8597.                 value += GetSkillAttributeValue(S_Sword_s07, theGame.params.CRITICAL_HIT_DAMAGE_BONUS, false, true) * GetSkillLevel(S_Sword_s07);
  8598.             }
  8599.             playerOffenseStats.crossbowCritDmgBonus = CalculateAttributeValue(value);
  8600.            
  8601.             //bolt stats
  8602.             if (GetItemEquippedOnSlot(EES_Bolt, bolt))
  8603.             {
  8604.                 playerOffenseStats.crossbowSteelDmgType = GetCrossbowSteelDmgName();
  8605.                 inv.GetItemStatByName(inv.GetItemName(bolt), playerOffenseStats.crossbowSteelDmgType, playerOffenseStats.crossbowSteelDmg);
  8606.                 inv.GetItemStatByName(inv.GetItemName(bolt), 'SilverDamage', playerOffenseStats.crossbowSilverDmg);
  8607.                 playerOffenseStats.crossbowElementaDmgType = GetCrossbowElementaDmgName();
  8608.                 if(IsNameValid(playerOffenseStats.crossbowElementaDmgType))
  8609.                     inv.GetItemStatByName(inv.GetItemName(bolt), playerOffenseStats.crossbowElementaDmgType, playerOffenseStats.crossbowElementaDmg);
  8610.             }
  8611.            
  8612.             //Water Hag decoction
  8613.             if ( HasBuff(EET_Mutagen05) && GetHealthPercents() > 0.99 )
  8614.             {
  8615.                 mutagen = GetBuff(EET_Mutagen05);
  8616.                 theGame.GetDefinitionsManager().GetAbilityAttributeValue(mutagen.GetAbilityName(), 'damageIncrease', min, max);
  8617.                 bonusDmgMultCrossbow += min.valueMultiplicative;
  8618.             }
  8619.            
  8620.             //perk 2
  8621.             if( CanUseSkill(S_Perk_02) )
  8622.             {
  8623.                 min = GetSkillAttributeValue(S_Perk_02, 'xbow_dmg_bonus', false, true);
  8624.                 bonusDmgMultCrossbow += min.valueMultiplicative;
  8625.             }
  8626.            
  8627.             playerOffenseStats.crossbowSteelDmg = (playerOffenseStats.crossbowSteelDmg * (1 + bonusDmgMultCrossbow) + attackPowerCrossbow.valueBase) * attackPowerCrossbow.valueMultiplicative;
  8628.             playerOffenseStats.crossbowSilverDmg = (playerOffenseStats.crossbowSilverDmg * (1 + bonusDmgMultCrossbow) + attackPowerCrossbow.valueBase) * attackPowerCrossbow.valueMultiplicative;
  8629.             playerOffenseStats.crossbowElementaDmg = (playerOffenseStats.crossbowElementaDmg * (1 + bonusDmgMultCrossbow) + attackPowerCrossbow.valueBase) * attackPowerCrossbow.valueMultiplicative;
  8630.         }
  8631.        
  8632.         return playerOffenseStats;
  8633.     }
  8634.    
  8635.     public function GetTotalWeaponDamage(weaponId : SItemUniqueId, damageTypeName : name, crossbowId : SItemUniqueId) : float
  8636.     {
  8637.         var damage, durRatio, durMod, itemMod : float;
  8638.         var repairObjectBonus, min, max : SAbilityAttributeValue;
  8639.        
  8640.         //durMod = 0;
  8641.         durMod = 1; //modSigns: zero value effectively removes all non-physical damages from weapon
  8642.         damage = super.GetTotalWeaponDamage(weaponId, damageTypeName, crossbowId);
  8643.        
  8644.        
  8645.         /*if( IsMutationActive( EPMT_Mutation9 ) && inv.IsItemBolt( weaponId ) && IsDamageTypeAnyPhysicalType( damageTypeName ) )
  8646.         {
  8647.             theGame.GetDefinitionsManager().GetAbilityAttributeValue('Mutation9', 'damage', min, max);
  8648.             damage += min.valueAdditive;
  8649.         }*/ //modSigns
  8650.        
  8651.        
  8652.         if(IsPhysicalResistStat(GetResistForDamage(damageTypeName, false)))
  8653.         {
  8654.             repairObjectBonus = inv.GetItemAttributeValue(weaponId, theGame.params.REPAIR_OBJECT_BONUS);
  8655.             durRatio = -1;
  8656.            
  8657.             if(inv.IsIdValid(crossbowId) && inv.HasItemDurability(crossbowId))
  8658.             {
  8659.                 durRatio = inv.GetItemDurabilityRatio(crossbowId);
  8660.             }
  8661.             else if(inv.IsIdValid(weaponId) && inv.HasItemDurability(weaponId))
  8662.             {
  8663.                 durRatio = inv.GetItemDurabilityRatio(weaponId);
  8664.             }
  8665.            
  8666.            
  8667.             if(durRatio >= 0)
  8668.                 durMod = theGame.params.GetDurabilityMultiplier(durRatio, true);
  8669.             else
  8670.                 durMod = 1;
  8671.         }
  8672.        
  8673.        
  8674.         if( damageTypeName == 'SilverDamage' && inv.ItemHasTag( weaponId, 'Aerondight' ) )
  8675.         {
  8676.             itemMod = inv.GetItemModifierFloat( weaponId, 'PermDamageBoost' );
  8677.             if( itemMod > 0.f )
  8678.             {
  8679.                 damage += itemMod;
  8680.             }
  8681.         }
  8682.        
  8683.         return damage * (durMod + repairObjectBonus.valueMultiplicative);
  8684.     }
  8685.    
  8686.    
  8687.    
  8688.    
  8689.    
  8690.     public final function GetSkillPathType(skill : ESkill) : ESkillPath
  8691.     {
  8692.         if(abilityManager && abilityManager.IsInitialized())
  8693.             return ((W3PlayerAbilityManager)abilityManager).GetSkillPathType(skill);
  8694.            
  8695.         return ESP_NotSet;
  8696.     }
  8697.    
  8698.     public function GetSkillLevel(s : ESkill) : int
  8699.     {
  8700.         if(abilityManager && abilityManager.IsInitialized())
  8701.             return ((W3PlayerAbilityManager)abilityManager).GetSkillLevel(s);
  8702.            
  8703.         return -1;
  8704.     }
  8705.    
  8706.     public function GetSkillMaxLevel(s : ESkill) : int
  8707.     {
  8708.         if(abilityManager && abilityManager.IsInitialized())
  8709.             return ((W3PlayerAbilityManager)abilityManager).GetSkillMaxLevel(s);
  8710.            
  8711.         return -1;
  8712.     }
  8713.    
  8714.     public function GetBoughtSkillLevel(s : ESkill) : int
  8715.     {
  8716.         if(abilityManager && abilityManager.IsInitialized())
  8717.             return ((W3PlayerAbilityManager)abilityManager).GetBoughtSkillLevel(s);
  8718.            
  8719.         return -1;
  8720.     }
  8721.    
  8722.    
  8723.     public function GetAxiiLevel() : int
  8724.     {
  8725.         var level : int;
  8726.        
  8727.         level = 1;
  8728.        
  8729.         if(CanUseSkill(S_Magic_s17)) level += GetSkillLevel(S_Magic_s17);
  8730.            
  8731.         return Clamp(level, 1, 4);
  8732.     }
  8733.    
  8734.     public function IsInFrenzy() : bool
  8735.     {
  8736.         return isInFrenzy;
  8737.     }
  8738.    
  8739.     public function HasRecentlyCountered() : bool
  8740.     {
  8741.         return hasRecentlyCountered;
  8742.     }
  8743.    
  8744.     public function SetRecentlyCountered(counter : bool)
  8745.     {
  8746.         hasRecentlyCountered = counter;
  8747.     }
  8748.    
  8749.     timer function CheckBlockedSkills(dt : float, id : int)
  8750.     {
  8751.         var nextCallTime : float;
  8752.        
  8753.         nextCallTime = ((W3PlayerAbilityManager)abilityManager).CheckBlockedSkills(dt);
  8754.         if(nextCallTime != -1)
  8755.             AddTimer('CheckBlockedSkills', nextCallTime, , , , true);
  8756.     }
  8757.        
  8758.    
  8759.     public function RemoveTemporarySkills()
  8760.     {
  8761.         var i : int;
  8762.         var pam : W3PlayerAbilityManager;
  8763.         var drain : bool;
  8764.    
  8765.         if(tempLearnedSignSkills.Size() > 0)
  8766.         {
  8767.             pam = (W3PlayerAbilityManager)abilityManager;
  8768.             for(i=0; i<tempLearnedSignSkills.Size(); i+=1)
  8769.             {
  8770.                 //modSigns: drain focus after the cast, not before
  8771.                 if(pam.RemoveTemporarySkill(tempLearnedSignSkills[i]))
  8772.                     drain = true;
  8773.             }
  8774.            
  8775.             tempLearnedSignSkills.Clear();                     
  8776.         }
  8777.         RemoveAbilityAll(SkillEnumToName(S_Sword_s19));
  8778.         if(drain)
  8779.             DrainFocus(GetStat(BCS_Focus));
  8780.     }
  8781.    
  8782.     public function RemoveTemporarySkill(skill : SSimpleSkill) : bool
  8783.     {
  8784.         var pam : W3PlayerAbilityManager;
  8785.        
  8786.         pam = (W3PlayerAbilityManager)abilityManager;
  8787.         if(pam && pam.IsInitialized())
  8788.             return pam.RemoveTemporarySkill(skill);
  8789.            
  8790.         return false;
  8791.     }
  8792.    
  8793.    
  8794.     // modSigns: do not drain focus immediately
  8795.     private function AddTemporarySkills()
  8796.     {
  8797.         if(CanUseSkill(S_Sword_s19) && GetStat(BCS_Focus) >= 3)
  8798.         {
  8799.             //DrainFocus(GetStat(BCS_Focus));
  8800.             tempLearnedSignSkills = ((W3PlayerAbilityManager)abilityManager).AddTempNonAlchemySkills();
  8801.             AddAbilityMultiple(SkillEnumToName(S_Sword_s19), GetSkillLevel(S_Sword_s19));
  8802.         }
  8803.     }
  8804.  
  8805.    
  8806.    
  8807.     public function HasAlternateQuen() : bool
  8808.     {
  8809.         var quenEntity : W3QuenEntity;
  8810.        
  8811.         quenEntity = (W3QuenEntity)GetCurrentSignEntity();
  8812.         if(quenEntity)
  8813.         {
  8814.             return quenEntity.IsAlternateCast();
  8815.         }
  8816.        
  8817.         return false;
  8818.     }
  8819.    
  8820.    
  8821.    
  8822.    
  8823.    
  8824.     public function AddPoints(type : ESpendablePointType, amount : int, show : bool)
  8825.     {
  8826.         levelManager.AddPoints(type, amount, show);
  8827.     }
  8828.    
  8829.     public function GetLevel() : int                                            {return levelManager.GetLevel();}
  8830.     public function GetMaxLevel() : int                                         {return levelManager.GetMaxLevel();}
  8831.     public function GetTotalExpForNextLevel() : int                             {return levelManager.GetTotalExpForNextLevel();}   
  8832.     public function GetPointsTotal(type : ESpendablePointType) : int            {return levelManager.GetPointsTotal(type);}
  8833.     public function IsAutoLeveling() : bool                                     {return autoLevel;}
  8834.     public function SetAutoLeveling( b : bool )                                 {autoLevel = b;}
  8835.    
  8836.     public function GetMissingExpForNextLevel() : int
  8837.     {
  8838.         return Max(0, GetTotalExpForNextLevel() - GetPointsTotal(EExperiencePoint));
  8839.     }
  8840.    
  8841.    
  8842.    
  8843.    
  8844.     private saved var runewordInfusionType : ESignType;
  8845.     default runewordInfusionType = ST_None;
  8846.    
  8847.     public final function GetRunewordInfusionType() : ESignType
  8848.     {
  8849.         return runewordInfusionType;
  8850.     }
  8851.    
  8852.    
  8853.     public function QuenImpulse( isAlternate : bool, signEntity : W3QuenEntity, source : string, optional forceSkillLevel : int, optional forceSpellPower : SAbilityAttributeValue /*modSigns*/ )
  8854.     {
  8855.         var level, i, j : int;
  8856.         var atts, damages : array<name>;
  8857.         var ents : array<CGameplayEntity>;
  8858.         var action : W3DamageAction;
  8859.         var dm : CDefinitionsManagerAccessor;
  8860.         var skillAbilityName : name;
  8861.         var dmg : float;
  8862.         var min, max : SAbilityAttributeValue;
  8863.         var pos : Vector;
  8864.         var spellPower : SAbilityAttributeValue; //modSigns: spell power
  8865.         var staminaPrc : float; //modSigns
  8866.        
  8867.         if( forceSkillLevel > 0 )
  8868.         {
  8869.             level = forceSkillLevel;
  8870.         }
  8871.         else
  8872.         {
  8873.             level = GetSkillLevel(S_Magic_s13);
  8874.         }
  8875.        
  8876.         dm = theGame.GetDefinitionsManager();
  8877.         skillAbilityName = GetSkillAbilityName(S_Magic_s13);
  8878.        
  8879.         if( forceSpellPower.valueMultiplicative > 0 ) //modSigns
  8880.         {
  8881.             spellPower = forceSpellPower;
  8882.         }
  8883.         else
  8884.         {
  8885.             spellPower = GetTotalSignSpellPower(S_Magic_4);
  8886.         }
  8887.        
  8888.         if(level >= 2)
  8889.         {
  8890.             dm.GetAbilityAttributes(skillAbilityName, atts);
  8891.             for(i=0; i<atts.Size(); i+=1)
  8892.             {
  8893.                 if(IsDamageTypeNameValid(atts[i]))
  8894.                 {
  8895.                     damages.PushBack(atts[i]);
  8896.                 }
  8897.             }
  8898.         }
  8899.        
  8900.        
  8901.         //pos = signEntity.GetWorldPosition();
  8902.         //FindGameplayEntitiesInSphere(ents, pos, 3, 1000, '', FLAG_OnlyAliveActors + FLAG_ExcludeTarget + FLAG_Attitude_Hostile + FLAG_Attitude_Neutral + FLAG_TestLineOfSight, this);
  8903.         //modSigns: the above variant doesn't work properly. Use box instead of a sphere.
  8904.         FindGameplayEntitiesInRange(ents, this, 3, 100, , FLAG_OnlyAliveActors + FLAG_ExcludeTarget + FLAG_Attitude_Hostile, this);
  8905.        
  8906.        
  8907.         for(i=0; i<ents.Size(); i+=1)
  8908.         {
  8909.             //combat log
  8910.             //theGame.witcherLog.AddCombatMessage("Quen impulse:", this, ents[i]);
  8911.             //theGame.witcherLog.AddCombatMessage("Target # " + IntToString(i + 1) + ": " + ents[i].GetDisplayName(), this, ents[i]);
  8912.            
  8913.             action = new W3DamageAction in theGame;
  8914.             action.Initialize(this, ents[i], signEntity, source, EHRT_None, CPS_SpellPower, false, false, true, false); //modSigns
  8915.             action.SetSignSkill(S_Magic_s13);
  8916.             action.SetCannotReturnDamage(true);
  8917.             action.SetProcessBuffsIfNoDamage(true);
  8918.            
  8919.            
  8920.             if(!isAlternate && level >= 2)
  8921.             {
  8922.                 action.SetHitEffect('hit_electric_quen');
  8923.                 action.SetHitEffect('hit_electric_quen', true);
  8924.                 action.SetHitEffect('hit_electric_quen', false, true);
  8925.                 action.SetHitEffect('hit_electric_quen', true, true);
  8926.             }
  8927.            
  8928.             if(level >= 1)
  8929.             {
  8930.                 action.AddEffectInfo(EET_Stagger);
  8931.             }
  8932.             if(level >= 2)
  8933.             {
  8934.                 for(j=0; j<damages.Size(); j+=1)
  8935.                 {
  8936.                     dm.GetAbilityAttributeValue(skillAbilityName, damages[j], min, max);
  8937.                     //dmg = CalculateAttributeValue(GetAttributeRandomizedValue(min, max));
  8938.                     //modSigns: damage scales with ability level
  8939.                     dmg = CalculateAttributeValue(GetAttributeRandomizedValue(min, max)) * (level - 1);
  8940.                     //modSigns: scale direct damage with sign power
  8941.                     if(damages[j] == theGame.params.DAMAGE_NAME_DIRECT && spellPower.valueMultiplicative > 1)
  8942.                         dmg *= spellPower.valueMultiplicative;
  8943.                     if( isAlternate ) //modSigns: scale alt quen dmg with stamina spent
  8944.                     {
  8945.                         staminaPrc = 1 - GetStaminaPercents();
  8946.                         dmg *= staminaPrc;
  8947.                         //combat log
  8948.                         //theGame.witcherLog.AddMessage("Quen impulse stamina used %: " + staminaPrc * 100);
  8949.                     }
  8950.                     if( IsSetBonusActive( EISB_Bear_2 ) )
  8951.                     {
  8952.                         dm.GetAbilityAttributeValue( GetSetBonusAbility( EISB_Bear_2 ), 'quen_dmg_boost', min, max );
  8953.                         dmg *= 1 + min.valueMultiplicative;                    
  8954.                     }
  8955.                     //combat log
  8956.                     //theGame.witcherLog.AddMessage("Quen impulse dmg: " + FloatToString(dmg) + " (" + NameToString(damages[j]) + ")");
  8957.                     action.AddDamage(damages[j], dmg);
  8958.                 }
  8959.             }
  8960.             if(level == 3)
  8961.             {
  8962.                 action.AddEffectInfo(EET_KnockdownTypeApplicator);
  8963.                 //combat log
  8964.                 //theGame.witcherLog.AddCombatMessage("Knockdown effect added", ownerActor, ents[i]);
  8965.             }
  8966.            
  8967.             theGame.damageMgr.ProcessAction( action );
  8968.             delete action;
  8969.         }
  8970.        
  8971.        
  8972.         if(isAlternate)
  8973.         {
  8974.             signEntity.PlayHitEffect('quen_impulse_explode', signEntity.GetWorldRotation());
  8975.             signEntity.EraseFirstTimeStamp();
  8976.                        
  8977.            
  8978.             if(level >= 2)
  8979.             {
  8980.                 if( !IsSetBonusActive( EISB_Bear_2 ) )
  8981.                 {
  8982.                     signEntity.PlayHitEffect('quen_electric_explode', signEntity.GetWorldRotation());
  8983.                 }
  8984.                 else
  8985.                 {
  8986.                     signEntity.PlayHitEffect('quen_electric_explode_bear_abl2', signEntity.GetWorldRotation());
  8987.                 }
  8988.             }
  8989.             //modSigns: drain all remaining stamina - removed: Impulse is no longer triggered for aborted sign
  8990.             //DrainStamina( ESAT_FixedValue, GetStat(BCS_Stamina), 2 );
  8991.         }
  8992.         else
  8993.         {
  8994.             signEntity.PlayEffect('lasting_shield_impulse');
  8995.         }      
  8996.     }
  8997.  
  8998.     //called after both Aard casts, after normal Igni cast, for alt Igni called at the beginning of channeling,
  8999.     //after normal Yrden cast, for alt Yrden - at the end of channeling if it wasn't aborted,
  9000.     //after normal Quen cast, for alt Quen - at the beginning of channeling,
  9001.     //after normal Axii cast, for alt Axii - at the end of channeling if it wasn't aborted
  9002.     public function OnSignCastPerformed(signType : ESignType, isAlternate : bool)
  9003.     {
  9004.         var items : array<SItemUniqueId>;
  9005.         var weaponEnt : CEntity;
  9006.         var fxName : name;
  9007.         var pos : Vector;
  9008.         //modSigns: new vars
  9009.         //var abilityName : name;
  9010.         //var abilityCount, maxStack : float;
  9011.         //var min, max : SAbilityAttributeValue;
  9012.         //var addAbility : bool;
  9013.        
  9014.         super.OnSignCastPerformed(signType, isAlternate);
  9015.        
  9016.         if(HasRunewordActive('Runeword 1 _Stats') && GetStat(BCS_Focus) >= 1.0f) //modSigns
  9017.         {
  9018.             DrainFocus(1.0f);
  9019.             runewordInfusionType = signType;
  9020.             items = inv.GetHeldWeapons();
  9021.             weaponEnt = inv.GetItemEntityUnsafe(items[0]);
  9022.            
  9023.            
  9024.             weaponEnt.StopEffect('runeword_aard');
  9025.             weaponEnt.StopEffect('runeword_axii');
  9026.             weaponEnt.StopEffect('runeword_igni');
  9027.             weaponEnt.StopEffect('runeword_quen');
  9028.             weaponEnt.StopEffect('runeword_yrden');
  9029.                    
  9030.            
  9031.             if(signType == ST_Aard)
  9032.                 fxName = 'runeword_aard';
  9033.             else if(signType == ST_Axii)
  9034.                 fxName = 'runeword_axii';
  9035.             else if(signType == ST_Igni)
  9036.                 fxName = 'runeword_igni';
  9037.             else if(signType == ST_Quen)
  9038.                 fxName = 'runeword_quen';
  9039.             else if(signType == ST_Yrden)
  9040.                 fxName = 'runeword_yrden';
  9041.                
  9042.             weaponEnt.PlayEffect(fxName);
  9043.         }
  9044.        
  9045.        
  9046.         if( IsMutationActive( EPMT_Mutation6 ) && signType == ST_Aard && !isAlternate )
  9047.         {
  9048.             pos = GetWorldPosition() + GetWorldForward() * 2;
  9049.            
  9050.             theGame.GetSurfacePostFX().AddSurfacePostFXGroup( pos, 0.f, 3.f, 2.f, 5.f, 0 );
  9051.         }
  9052.        
  9053.         //modSigns: ancient leshed decoction fix -> decoction changed
  9054.         /*if(HasBuff(EET_Mutagen22) && IsInCombat() && IsThreatened() && !isAlternate)
  9055.         {
  9056.             abilityName = GetBuff(EET_Mutagen22).GetAbilityName();
  9057.             abilityCount = GetAbilityCount(abilityName);
  9058.            
  9059.             if(abilityCount == 0)
  9060.             {
  9061.                 addAbility = true;
  9062.             }
  9063.             else
  9064.             {
  9065.                 theGame.GetDefinitionsManager().GetAbilityAttributeValue(abilityName, 'mutagen22_max_stack', min, max);
  9066.                 maxStack = CalculateAttributeValue(GetAttributeRandomizedValue(min, max));
  9067.                
  9068.                 if(maxStack >= 0)
  9069.                 {
  9070.                     addAbility = (abilityCount < maxStack);
  9071.                 }
  9072.                 else
  9073.                 {
  9074.                     addAbility = true;
  9075.                 }
  9076.             }
  9077.            
  9078.             if(addAbility)
  9079.             {
  9080.                 AddAbility(abilityName, true);
  9081.             }
  9082.         }*/
  9083.        
  9084.         //modSigns
  9085.         if(!HasBuff(EET_GryphonSetBonus) && IsSetBonusActive( EISB_Gryphon_1 ))
  9086.         {
  9087.             AddEffectDefault( EET_GryphonSetBonus, NULL, signType );
  9088.         }
  9089.        
  9090.         //theGame.witcherLog.AddMessage("OnSignCastPerformed: " + signType + "; isAlternate: " + isAlternate); //modSigns: debug
  9091.     }
  9092.    
  9093.     public saved var savedQuenHealth, savedQuenDuration : float;
  9094.    
  9095.     timer function HACK_QuenSaveStatus(dt : float, id : int)
  9096.     {
  9097.         var quenEntity : W3QuenEntity;
  9098.        
  9099.         quenEntity = (W3QuenEntity)signs[ST_Quen].entity;
  9100.         savedQuenHealth = quenEntity.GetShieldHealth();
  9101.         savedQuenDuration = quenEntity.GetShieldRemainingDuration();
  9102.     }
  9103.    
  9104.     timer function DelayedRestoreQuen(dt : float, id : int)
  9105.     {
  9106.         RestoreQuen(savedQuenHealth, savedQuenDuration);
  9107.     }
  9108.    
  9109.     public final function OnBasicQuenFinishing()
  9110.     {
  9111.         RemoveTimer('HACK_QuenSaveStatus');
  9112.         savedQuenHealth = 0.f;
  9113.         savedQuenDuration = 0.f;
  9114.     }
  9115.    
  9116.     public final function IsAnyQuenActive() : bool
  9117.     {
  9118.         var quen : W3QuenEntity;
  9119.        
  9120.         quen = (W3QuenEntity)GetSignEntity(ST_Quen);
  9121.         if(quen)
  9122.             return quen.IsAnyQuenActive();
  9123.            
  9124.         return false;
  9125.     }
  9126.    
  9127.     public final function IsQuenActive(alternateMode : bool) : bool
  9128.     {
  9129.         if(IsAnyQuenActive() && GetSignEntity(ST_Quen).IsAlternateCast() == alternateMode)
  9130.             return true;
  9131.            
  9132.         return false;
  9133.     }
  9134.    
  9135.     public function FinishQuen( skipVisuals : bool, optional forceNoBearSetBonus : bool )
  9136.     {
  9137.         var quen : W3QuenEntity;
  9138.        
  9139.         quen = (W3QuenEntity)GetSignEntity(ST_Quen);
  9140.         if(quen)
  9141.             quen.ForceFinishQuen( skipVisuals, forceNoBearSetBonus );
  9142.     }
  9143.    
  9144.    
  9145.     public function GetTotalSignSpellPower(signSkill : ESkill) : SAbilityAttributeValue
  9146.     {
  9147.         var sp : SAbilityAttributeValue;
  9148.         var penalty : SAbilityAttributeValue;
  9149.         var penaltyReduction : float;
  9150.         var penaltyReductionLevel : int;
  9151.         var mutagen : CBaseGameplayEffect; //modSigns
  9152.         var min, max : SAbilityAttributeValue; //modSigns
  9153.  
  9154.         //character SP + spell specific skills
  9155.         sp = GetSkillAttributeValue(signSkill, PowerStatEnumToName(CPS_SpellPower), true, true);
  9156.        
  9157.         //Gryphon set tier 1 bonus
  9158.         sp.valueMultiplicative += GetGryphonSetSignPowerBonus(SignSkillToSignType(signSkill));
  9159.        
  9160.         //skill custom
  9161.         if ( signSkill == S_Magic_s01 )
  9162.         {
  9163.             //wave leveling penalty reduction
  9164.             /*penaltyReductionLevel = GetSkillLevel(S_Magic_s01) + 1;
  9165.             if(penaltyReductionLevel > 0)
  9166.             {
  9167.                 penaltyReduction = 1 - penaltyReductionLevel * CalculateAttributeValue(GetSkillAttributeValue(S_Magic_s01, 'spell_power_penalty_reduction', true, true));
  9168.                 penalty = GetSkillAttributeValue(S_Magic_s01, PowerStatEnumToName(CPS_SpellPower), false, false);
  9169.                 sp += penalty * penaltyReduction;   //add amount equal to penalty reduction (since full penalty is already applied)
  9170.             }*/
  9171.             //modSigns: fix percentages as they are completely off from what skill description says
  9172.             penaltyReductionLevel = GetSkillLevel(S_Magic_s01) - 1;
  9173.             if(penaltyReductionLevel > 0)
  9174.             {
  9175.                 penaltyReduction = penaltyReductionLevel * CalculateAttributeValue(GetSkillAttributeValue(S_Magic_s01, 'spell_power_penalty_reduction', false, false));
  9176.                 //penalty was already applied, so we revert it based on penalty reduction and skill level
  9177.                 sp.valueMultiplicative += penaltyReduction;
  9178.             }
  9179.         }
  9180.        
  9181.        
  9182.         if(signSkill == S_Magic_1 || signSkill == S_Magic_s01)
  9183.         {
  9184.             sp += GetAttributeValue('spell_power_aard');
  9185.         }
  9186.         else if(signSkill == S_Magic_2 || signSkill == S_Magic_s02)
  9187.         {
  9188.             sp += GetAttributeValue('spell_power_igni');
  9189.         }
  9190.         else if(signSkill == S_Magic_3 || signSkill == S_Magic_s03)
  9191.         {
  9192.             sp += GetAttributeValue('spell_power_yrden');
  9193.         }
  9194.         else if(signSkill == S_Magic_4 || signSkill == S_Magic_s04)
  9195.         {
  9196.             sp += GetAttributeValue('spell_power_quen');
  9197.         }
  9198.         else if(signSkill == S_Magic_5 || signSkill == S_Magic_s05)
  9199.         {
  9200.             sp += GetAttributeValue('spell_power_axii');
  9201.         }
  9202.        
  9203.        
  9204.         ApplyMutation10StatBoost( sp );
  9205.    
  9206.         return sp;
  9207.     }
  9208.    
  9209.    
  9210.    
  9211.    
  9212.    
  9213.     public final function GetGwentCardIndex( cardName : name ) : int
  9214.     {
  9215.         var dm : CDefinitionsManagerAccessor;
  9216.        
  9217.         dm = theGame.GetDefinitionsManager();
  9218.        
  9219.         if(dm.ItemHasTag( cardName , 'GwintCardLeader' ))
  9220.         {
  9221.             return theGame.GetGwintManager().GwentLeadersNametoInt( cardName );
  9222.         }
  9223.         else if(dm.ItemHasTag( cardName , 'GwintCardNrkd' ))
  9224.         {
  9225.             return theGame.GetGwintManager().GwentNrkdNameToInt( cardName );
  9226.         }
  9227.         else if(dm.ItemHasTag( cardName , 'GwintCardNlfg' ))
  9228.         {
  9229.             return theGame.GetGwintManager().GwentNlfgNameToInt( cardName );
  9230.         }
  9231.         else if(dm.ItemHasTag( cardName , 'GwintCardSctl' ))
  9232.         {
  9233.             return theGame.GetGwintManager().GwentSctlNameToInt( cardName );
  9234.         }
  9235.         else if(dm.ItemHasTag( cardName , 'GwintCardMstr' ))
  9236.         {
  9237.             return theGame.GetGwintManager().GwentMstrNameToInt( cardName );
  9238.         }
  9239.         else if(dm.ItemHasTag( cardName , 'GwintCardSke' ))
  9240.         {
  9241.             return theGame.GetGwintManager().GwentSkeNameToInt( cardName );
  9242.         }  
  9243.         else if(dm.ItemHasTag( cardName , 'GwintCardNeutral' ))
  9244.         {
  9245.             return theGame.GetGwintManager().GwentNeutralNameToInt( cardName );
  9246.         }
  9247.         else if(dm.ItemHasTag( cardName , 'GwintCardSpcl' ))
  9248.         {
  9249.             return theGame.GetGwintManager().GwentSpecialNameToInt( cardName );
  9250.         }
  9251.        
  9252.         return -1;
  9253.     }
  9254.    
  9255.     public final function AddGwentCard(cardName : name, amount : int) : bool
  9256.     {
  9257.         var dm : CDefinitionsManagerAccessor;
  9258.         var cardIndex, i : int;
  9259.         var tut : STutorialMessage;
  9260.         var gwintManager : CR4GwintManager;
  9261.        
  9262.        
  9263.        
  9264.         if(FactsQuerySum("q001_nightmare_ended") > 0 && ShouldProcessTutorial('TutorialGwentDeckBuilder2'))
  9265.         {
  9266.             tut.type = ETMT_Hint;
  9267.             tut.tutorialScriptTag = 'TutorialGwentDeckBuilder2';
  9268.             tut.journalEntryName = 'TutorialGwentDeckBuilder2';
  9269.             tut.hintPositionType = ETHPT_DefaultGlobal;
  9270.             tut.markAsSeenOnShow = true;
  9271.             tut.hintDurationType = ETHDT_Long;
  9272.  
  9273.             theGame.GetTutorialSystem().DisplayTutorial(tut);
  9274.         }
  9275.        
  9276.         dm = theGame.GetDefinitionsManager();
  9277.        
  9278.         cardIndex = GetGwentCardIndex(cardName);
  9279.        
  9280.         if (cardIndex != -1)
  9281.         {
  9282.             FactsAdd("Gwint_Card_Looted");
  9283.            
  9284.             for(i = 0; i < amount; i += 1)
  9285.             {
  9286.                 theGame.GetGwintManager().AddCardToCollection( cardIndex );
  9287.             }
  9288.         }
  9289.        
  9290.         if( dm.ItemHasTag( cardName, 'GwentTournament' ) )
  9291.         {
  9292.             if ( dm.ItemHasTag( cardName, 'GT1' ) )
  9293.             {
  9294.                 FactsAdd( "GwentTournament", 1 );
  9295.             }
  9296.            
  9297.             else if ( dm.ItemHasTag( cardName, 'GT2' ) )
  9298.             {
  9299.                 FactsAdd( "GwentTournament", 2 );
  9300.             }
  9301.            
  9302.             else if ( dm.ItemHasTag( cardName, 'GT3' ) )
  9303.             {
  9304.                 FactsAdd( "GwentTournament", 3 );
  9305.             }
  9306.            
  9307.             else if ( dm.ItemHasTag( cardName, 'GT4' ) )
  9308.             {
  9309.                 FactsAdd( "GwentTournament", 4 );
  9310.             }
  9311.            
  9312.             else if ( dm.ItemHasTag( cardName, 'GT5' ) )
  9313.             {
  9314.                 FactsAdd( "GwentTournament", 5 );
  9315.             }
  9316.            
  9317.             else if ( dm.ItemHasTag( cardName, 'GT6' ) )
  9318.             {
  9319.                 FactsAdd( "GwentTournament", 6 );
  9320.             }
  9321.            
  9322.             else if ( dm.ItemHasTag( cardName, 'GT7' ) )
  9323.             {
  9324.                 FactsAdd( "GwentTournament", 7 );
  9325.             }
  9326.            
  9327.             CheckGwentTournamentDeck();
  9328.         }
  9329.        
  9330.         if( dm.ItemHasTag( cardName, 'EP2Tournament' ) )
  9331.         {
  9332.             if ( dm.ItemHasTag( cardName, 'GT1' ) )
  9333.             {
  9334.                 FactsAdd( "EP2Tournament", 1 );
  9335.             }
  9336.            
  9337.             else if ( dm.ItemHasTag( cardName, 'GT2' ) )
  9338.             {
  9339.                 FactsAdd( "EP2Tournament", 2 );
  9340.             }
  9341.            
  9342.             else if ( dm.ItemHasTag( cardName, 'GT3' ) )
  9343.             {
  9344.                 FactsAdd( "EP2Tournament", 3 );
  9345.             }
  9346.            
  9347.             else if ( dm.ItemHasTag( cardName, 'GT4' ) )
  9348.             {
  9349.                 FactsAdd( "EP2Tournament", 4 );
  9350.             }
  9351.            
  9352.             else if ( dm.ItemHasTag( cardName, 'GT5' ) )
  9353.             {
  9354.                 FactsAdd( "EP2Tournament", 5 );
  9355.             }
  9356.            
  9357.             else if ( dm.ItemHasTag( cardName, 'GT6' ) )
  9358.             {
  9359.                 FactsAdd( "EP2Tournament", 6 );
  9360.             }
  9361.            
  9362.             else if ( dm.ItemHasTag( cardName, 'GT7' ) )
  9363.             {
  9364.                 FactsAdd( "EP2Tournament", 7 );
  9365.             }
  9366.            
  9367.             CheckEP2TournamentDeck();
  9368.         }
  9369.        
  9370.         gwintManager = theGame.GetGwintManager();
  9371.         if( !gwintManager.IsDeckUnlocked( GwintFaction_Skellige ) &&
  9372.             gwintManager.HasCardsOfFactionInCollection( GwintFaction_Skellige, false ) )
  9373.         {
  9374.             gwintManager.UnlockDeck( GwintFaction_Skellige );
  9375.         }
  9376.        
  9377.         return true;
  9378.     }
  9379.    
  9380.    
  9381.     public final function RemoveGwentCard(cardName : name, amount : int) : bool
  9382.     {
  9383.         var dm : CDefinitionsManagerAccessor;
  9384.         var cardIndex, i : int;
  9385.        
  9386.         dm = theGame.GetDefinitionsManager();
  9387.        
  9388.         if(dm.ItemHasTag( cardName , 'GwintCardLeader' ))
  9389.         {
  9390.             cardIndex = theGame.GetGwintManager().GwentLeadersNametoInt( cardName );
  9391.             for(i=0; i<amount; i+=1)
  9392.                 theGame.GetGwintManager().RemoveCardFromCollection( cardIndex );
  9393.         }
  9394.         else if(dm.ItemHasTag( cardName , 'GwintCardNrkd' ))
  9395.         {
  9396.             cardIndex = theGame.GetGwintManager().GwentNrkdNameToInt( cardName );
  9397.             for(i=0; i<amount; i+=1)
  9398.                 theGame.GetGwintManager().RemoveCardFromCollection( cardIndex );
  9399.         }
  9400.         else if(dm.ItemHasTag( cardName , 'GwintCardNlfg' ))
  9401.         {
  9402.             cardIndex = theGame.GetGwintManager().GwentNlfgNameToInt( cardName );
  9403.             for(i=0; i<amount; i+=1)
  9404.                 theGame.GetGwintManager().RemoveCardFromCollection( cardIndex );
  9405.         }
  9406.         else if(dm.ItemHasTag( cardName , 'GwintCardSctl' ))
  9407.         {
  9408.             cardIndex = theGame.GetGwintManager().GwentSctlNameToInt( cardName );
  9409.             for(i=0; i<amount; i+=1)
  9410.                 theGame.GetGwintManager().RemoveCardFromCollection( cardIndex );
  9411.         }
  9412.         else if(dm.ItemHasTag( cardName , 'GwintCardMstr' ))
  9413.         {
  9414.             cardIndex = theGame.GetGwintManager().GwentMstrNameToInt( cardName );
  9415.             for(i=0; i<amount; i+=1)
  9416.                 theGame.GetGwintManager().RemoveCardFromCollection( cardIndex );
  9417.         }
  9418.         else if(dm.ItemHasTag( cardName , 'GwintCardNeutral' ))
  9419.         {
  9420.             cardIndex = theGame.GetGwintManager().GwentNeutralNameToInt( cardName );
  9421.             for(i=0; i<amount; i+=1)
  9422.                 theGame.GetGwintManager().RemoveCardFromCollection( cardIndex );
  9423.         }
  9424.         else if(dm.ItemHasTag( cardName , 'GwintCardSpcl' ))
  9425.         {
  9426.             cardIndex = theGame.GetGwintManager().GwentSpecialNameToInt( cardName );
  9427.             for(i=0; i<amount; i+=1)
  9428.                 theGame.GetGwintManager().RemoveCardFromCollection( cardIndex );
  9429.         }
  9430.        
  9431.         if( dm.ItemHasTag( cardName, 'GwentTournament' ) )
  9432.         {
  9433.             if ( dm.ItemHasTag( cardName, 'GT1' ) )
  9434.             {
  9435.                 FactsSubstract( "GwentTournament", 1 );
  9436.             }
  9437.            
  9438.             else if ( dm.ItemHasTag( cardName, 'GT2' ) )
  9439.             {
  9440.                 FactsSubstract( "GwentTournament", 2 );
  9441.             }
  9442.            
  9443.             else if ( dm.ItemHasTag( cardName, 'GT3' ) )
  9444.             {
  9445.                 FactsSubstract( "GwentTournament", 3 );
  9446.             }
  9447.            
  9448.             else if ( dm.ItemHasTag( cardName, 'GT4' ) )
  9449.             {
  9450.                 FactsSubstract( "GwentTournament", 4 );
  9451.             }
  9452.            
  9453.             else if ( dm.ItemHasTag( cardName, 'GT5' ) )
  9454.             {
  9455.                 FactsSubstract( "GwentTournament", 5 );
  9456.             }
  9457.            
  9458.             else if ( dm.ItemHasTag( cardName, 'GT6' ) )
  9459.             {
  9460.                 FactsSubstract( "GwentTournament", 6 );
  9461.             }
  9462.            
  9463.             else if ( dm.ItemHasTag( cardName, 'GT7' ) )
  9464.             {
  9465.                 FactsSubstract( "GwentTournament", 7 );
  9466.             }
  9467.            
  9468.             CheckGwentTournamentDeck();
  9469.         }
  9470.            
  9471.            
  9472.         if( dm.ItemHasTag( cardName, 'EP2Tournament' ) )
  9473.         {
  9474.             if ( dm.ItemHasTag( cardName, 'GT1' ) )
  9475.             {
  9476.                 FactsSubstract( "EP2Tournament", 1 );
  9477.             }
  9478.            
  9479.             else if ( dm.ItemHasTag( cardName, 'GT2' ) )
  9480.             {
  9481.                 FactsSubstract( "EP2Tournament", 2 );
  9482.             }
  9483.            
  9484.             else if ( dm.ItemHasTag( cardName, 'GT3' ) )
  9485.             {
  9486.                 FactsSubstract( "EP2Tournament", 3 );
  9487.             }
  9488.            
  9489.             else if ( dm.ItemHasTag( cardName, 'GT4' ) )
  9490.             {
  9491.                 FactsSubstract( "EP2Tournament", 4 );
  9492.             }
  9493.            
  9494.             else if ( dm.ItemHasTag( cardName, 'GT5' ) )
  9495.             {
  9496.                 FactsSubstract( "EP2Tournament", 5 );
  9497.             }
  9498.            
  9499.             else if ( dm.ItemHasTag( cardName, 'GT6' ) )
  9500.             {
  9501.                 FactsSubstract( "EP2Tournament", 6 );
  9502.             }
  9503.            
  9504.             else if ( dm.ItemHasTag( cardName, 'GT7' ) )
  9505.             {
  9506.                 FactsSubstract( "EP2Tournament", 7 );
  9507.             }
  9508.            
  9509.             CheckEP2TournamentDeck();
  9510.         }
  9511.        
  9512.         return true;
  9513.     }
  9514.    
  9515.     function CheckGwentTournamentDeck()
  9516.     {
  9517.         var gwentPower          : int;
  9518.         var neededGwentPower    : int;
  9519.         var checkBreakpoint     : int;
  9520.        
  9521.         neededGwentPower = 70;
  9522.        
  9523.         checkBreakpoint = neededGwentPower/5;
  9524.         gwentPower = FactsQuerySum( "GwentTournament" );
  9525.        
  9526.         if ( gwentPower >= neededGwentPower )
  9527.         {
  9528.             FactsAdd( "HasGwentTournamentDeck", 1 );
  9529.         }
  9530.         else
  9531.         {
  9532.             if( FactsDoesExist( "HasGwentTournamentDeck" ) )
  9533.             {
  9534.                 FactsRemove( "HasGwentTournamentDeck" );
  9535.             }
  9536.            
  9537.             if ( gwentPower >= checkBreakpoint )
  9538.             {
  9539.                 FactsAdd( "GwentTournamentObjective1", 1 );
  9540.             }
  9541.             else if ( FactsDoesExist( "GwentTournamentObjective1" ) )
  9542.             {
  9543.                 FactsRemove( "GwentTournamentObjective1" );
  9544.             }
  9545.            
  9546.             if ( gwentPower >= checkBreakpoint*2 )
  9547.             {
  9548.                 FactsAdd( "GwentTournamentObjective2", 1 );
  9549.             }
  9550.             else if ( FactsDoesExist( "GwentTournamentObjective2" ) )
  9551.             {
  9552.                 FactsRemove( "GwentTournamentObjective2" );
  9553.             }
  9554.            
  9555.             if ( gwentPower >= checkBreakpoint*3 )
  9556.             {
  9557.                 FactsAdd( "GwentTournamentObjective3", 1 );
  9558.             }
  9559.             else if ( FactsDoesExist( "GwentTournamentObjective3" ) )
  9560.             {
  9561.                 FactsRemove( "GwentTournamentObjective3" );
  9562.             }
  9563.            
  9564.             if ( gwentPower >= checkBreakpoint*4 )
  9565.             {
  9566.                 FactsAdd( "GwentTournamentObjective4", 1 );
  9567.             }
  9568.             else if ( FactsDoesExist( "GwentTournamentObjective4" ) )
  9569.             {
  9570.                 FactsRemove( "GwentTournamentObjective4" );
  9571.             }
  9572.         }
  9573.     }
  9574.    
  9575.     function CheckEP2TournamentDeck()
  9576.     {
  9577.         var gwentPower          : int;
  9578.         var neededGwentPower    : int;
  9579.         var checkBreakpoint     : int;
  9580.        
  9581.         neededGwentPower = 24;
  9582.        
  9583.         checkBreakpoint = neededGwentPower/5;
  9584.         gwentPower = FactsQuerySum( "EP2Tournament" );
  9585.        
  9586.         if ( gwentPower >= neededGwentPower )
  9587.         {
  9588.             if( FactsQuerySum( "HasEP2TournamentDeck") == 0 )
  9589.             {
  9590.                 FactsAdd( "HasEP2TournamentDeck", 1 );
  9591.             }
  9592.            
  9593.         }
  9594.         else
  9595.         {
  9596.             if( FactsDoesExist( "HasEP2TournamentDeck" ) )
  9597.             {
  9598.                 FactsRemove( "HasEP2TournamentDeck" );
  9599.             }
  9600.            
  9601.             if ( gwentPower >= checkBreakpoint )
  9602.             {
  9603.                 FactsAdd( "EP2TournamentObjective1", 1 );
  9604.             }
  9605.             else if ( FactsDoesExist( "EP2TournamentObjective1" ) )
  9606.             {
  9607.                 FactsRemove( "EP2TournamentObjective1" );
  9608.             }
  9609.            
  9610.             if ( gwentPower >= checkBreakpoint*2 )
  9611.             {
  9612.                 FactsAdd( "EP2TournamentObjective2", 1 );
  9613.             }
  9614.             else if ( FactsDoesExist( "EP2TournamentObjective2" ) )
  9615.             {
  9616.                 FactsRemove( "EP2TournamentObjective2" );
  9617.             }
  9618.            
  9619.             if ( gwentPower >= checkBreakpoint*3 )
  9620.             {
  9621.                 FactsAdd( "EP2TournamentObjective3", 1 );
  9622.             }
  9623.             else if ( FactsDoesExist( "EP2TournamentObjective3" ) )
  9624.             {
  9625.                 FactsRemove( "EP2TournamentObjective3" );
  9626.             }
  9627.            
  9628.             if ( gwentPower >= checkBreakpoint*4 )
  9629.             {
  9630.                 FactsAdd( "EP2TournamentObjective4", 1 );
  9631.             }
  9632.             else if ( FactsDoesExist( "EP2TournamentObjective4" ) )
  9633.             {
  9634.                 FactsRemove( "EP2TournamentObjective4" );
  9635.             }
  9636.         }
  9637.     }
  9638.    
  9639.    
  9640.    
  9641.    
  9642.    
  9643.    
  9644.     //---=== modFriendlyMeditation ===---
  9645.     public function IsMeditating() : bool
  9646.     {
  9647.         return ( GetCurrentStateName() == 'Meditation' );
  9648.     }
  9649.  
  9650.     public function IsSkippingTime() : bool
  9651.     {
  9652.         return ( GetCurrentStateName() == 'MeditationWaiting' );
  9653.     }
  9654.    
  9655.     public function UpdateEffectsAccelerated( realTimeSecs, acceleration : float )
  9656.     {
  9657.         effectManager.PerformUpdate( realTimeSecs * acceleration );
  9658.     }
  9659.     //---=== modFriendlyMeditation ===---
  9660.    
  9661.     public function SimulateBuffTimePassing(simulatedTime : float)
  9662.     {
  9663.         //---=== modPreparations ===---
  9664.         /*super.SimulateBuffTimePassing(simulatedTime);
  9665.        
  9666.         FinishQuen(true);*/
  9667.         if( simulatedTime > 0 )
  9668.         {
  9669.             effectManager.PerformUpdate( simulatedTime );
  9670.         }
  9671.         //---=== modPreparations ===---
  9672.     }
  9673.    
  9674.    
  9675.     public function CanMeditate() : bool
  9676.     {
  9677.         //---=== modPreparations ===---
  9678.         /*var currentStateName : name;
  9679.        
  9680.         currentStateName = GetCurrentStateName();
  9681.        
  9682.        
  9683.         if(currentStateName == 'Exploration' && !CanPerformPlayerAction())
  9684.             return false;
  9685.        
  9686.        
  9687.         if(GetCurrentStateName() != 'Exploration' && GetCurrentStateName() != 'Meditation' && GetCurrentStateName() != 'MeditationWaiting')
  9688.             return false;
  9689.            
  9690.        
  9691.         if(GetUsedVehicle())
  9692.             return false;
  9693.            
  9694.        
  9695.         return CanMeditateHere();*/
  9696.         if(!IsMeditationAllowed())
  9697.         {
  9698.             theGame.GetGuiManager().ShowNotification(GetLocStringByKeyExt(prepConfig.GetMeditationError()));
  9699.             return false;
  9700.         }
  9701.         return true;
  9702.         //---=== modPreparations ===---
  9703.     }
  9704.    
  9705.    
  9706.     public final function CanMeditateWait(optional skipMeditationStateCheck : bool) : bool
  9707.     {
  9708.         //---=== modPreparations ===---
  9709.         /*var currState : name;
  9710.        
  9711.         currState = GetCurrentStateName();
  9712.        
  9713.        
  9714.        
  9715.         if(!skipMeditationStateCheck && currState != 'Meditation')
  9716.             return false;
  9717.            
  9718.        
  9719.         if(theGame.IsGameTimePaused())
  9720.             return false;
  9721.            
  9722.         if(!IsActionAllowed( EIAB_MeditationWaiting ))
  9723.             return false;
  9724.            
  9725.         return true;*/
  9726.         if(!IsMeditationAllowed())
  9727.         {
  9728.             theGame.GetGuiManager().ShowNotification(GetLocStringByKeyExt(prepConfig.GetMeditationError()));
  9729.             return false;
  9730.         }
  9731.         return true;
  9732.         //---=== modPreparations ===---
  9733.     }
  9734.  
  9735.    
  9736.     public final function CanMeditateHere() : bool
  9737.     {
  9738.         //---=== modPreparations ===---
  9739.         /*var pos   : Vector;
  9740.        
  9741.         pos = GetWorldPosition();
  9742.         if(pos.Z <= theGame.GetWorld().GetWaterLevel(pos, true) && IsInShallowWater())
  9743.             return false;
  9744.        
  9745.         if(IsThreatened())
  9746.             return false;
  9747.        
  9748.         return true;*/
  9749.         if(!IsMeditationAllowed())
  9750.         {
  9751.             theGame.GetGuiManager().ShowNotification(GetLocStringByKeyExt(prepConfig.GetMeditationError()));
  9752.             return false;
  9753.         }
  9754.         return true;
  9755.         //---=== modPreparations ===---
  9756.     }
  9757.    
  9758.    
  9759.     //---=== modPreparations ===---
  9760.     public function IsMeditationAllowed() : bool
  9761.     {
  9762.         var curState : name = GetCurrentStateName();
  9763.        
  9764.         fmedCanSpawnCampfire = false;
  9765.        
  9766.         if(theGame.IsGameTimePaused())
  9767.             return false;
  9768.        
  9769.         if(GetUsedVehicle())
  9770.             return false;
  9771.        
  9772.         if(!IsActionAllowed(EIAB_MeditationWaiting))
  9773.             return false;
  9774.        
  9775.         if(curState != 'Exploration' && curState != 'Meditation' && curState != 'MeditationWaiting')
  9776.             return false;
  9777.        
  9778.         if(curState == 'Exploration' && !CanPerformPlayerAction())
  9779.             return false;
  9780.        
  9781.         if(IsThreatened())
  9782.             return false;
  9783.        
  9784.         if(((CMovingPhysicalAgentComponent)GetMovingAgentComponent()).GetSubmergeDepth() < 0)
  9785.             return false;
  9786.        
  9787.         if(prepConfig.disallowNPCs && HasNonAlliedActorsNearby())
  9788.             return false;
  9789.        
  9790.         if(prepConfig.disallowSettlement && IsInSettlement() && !IsInInterior())
  9791.             return false;
  9792.        
  9793.         if(prepConfig.disallowInterior && IsInInterior())
  9794.             return false;
  9795.        
  9796.         if(prepConfig.disallowMeditation && !HasCampfire() && !CanSpawnCampfire())
  9797.             return false;
  9798.  
  9799.         fmedCanSpawnCampfire = CanSpawnCampfire(); //meditation is allowed, but we need to determine if spawning a campfire is allowed (for Friendly Meditation)
  9800.        
  9801.         return true;
  9802.     }
  9803.    
  9804.     public function HasNonAlliedActorsNearby() : bool
  9805.     {
  9806.         var entities : array< CGameplayEntity >;
  9807.         var i : int;
  9808.         var actor : CActor;
  9809.        
  9810.         FindGameplayEntitiesInRange( entities, thePlayer, prepConfig.npcDistance, 1000,, FLAG_ExcludePlayer + FLAG_OnlyAliveActors,, 'CActor' );
  9811.         for( i = 0; i < entities.Size(); i += 1 )
  9812.         {
  9813.             actor = (CActor)entities[i];
  9814.             if( actor.IsAnimal() || ((CNewNPC)actor).IsHorse() || GetAttitudeBetween( thePlayer, actor ) != AIA_Hostile && ((CNewNPC)actor).IsVIP() )
  9815.                 continue;
  9816.             else
  9817.                 return true;
  9818.         }
  9819.         return false;
  9820.     }
  9821.    
  9822.     public function GetFmedCanSpawnCampfire() : bool
  9823.     {
  9824.         return fmedCanSpawnCampfire;
  9825.     }
  9826.    
  9827.     public function GetOpenFireEnt() : CGameplayEntity
  9828.     {
  9829.         return openFireEnt;
  9830.     }
  9831.    
  9832.     public function HasCampfire() : bool
  9833.     {
  9834.         var entities : array< CGameplayEntity >;
  9835.         var i : int;
  9836.         var dist : float;
  9837.         var glComponent : CGameplayLightComponent;
  9838.        
  9839.         if( IsInInterior() )
  9840.         {
  9841.             dist = 1.5;
  9842.         }
  9843.         else
  9844.         {
  9845.             dist = 3.0;
  9846.         }
  9847.         if( openFireEnt && VecDistanceSquared2D(openFireEnt.GetWorldPosition(), GetWorldPosition()) <= dist*dist )
  9848.         {
  9849.             return true;
  9850.         }
  9851.         if( spawnedCampFire && VecDistanceSquared2D(spawnedCampFire.GetWorldPosition(), GetWorldPosition()) <= dist*dist )
  9852.         {
  9853.             openFireEnt = spawnedCampFire;
  9854.             return true;
  9855.         }
  9856.         if( !prepConfig.disallowCampFire )
  9857.         {
  9858.             FindGameplayEntitiesInRange( entities, thePlayer, dist, 1,, FLAG_ExcludePlayer,, 'W3Campfire' );
  9859.             if( entities.Size() > 0 )
  9860.             {
  9861.                 openFireEnt = entities[0];
  9862.                 return true;
  9863.             }
  9864.         }
  9865.         if( !prepConfig.disallowFireSource )
  9866.         {
  9867.             FindGameplayEntitiesInRange( entities, thePlayer, dist, 1,, FLAG_ExcludePlayer,, 'W3FireSource' );
  9868.             if( entities.Size() > 0 )
  9869.             {
  9870.                 openFireEnt = entities[0];
  9871.                 return true;
  9872.             }
  9873.         }
  9874.         if( !prepConfig.disallowLightSource )
  9875.         {
  9876.             FindGameplayEntitiesInRange( entities, thePlayer, dist, 10,, FLAG_ExcludePlayer,, 'CGameplayEntity' );
  9877.             for( i = 0; i < entities.Size(); i += 1 )
  9878.             {
  9879.                 glComponent = (CGameplayLightComponent)entities[i].GetComponentByClassName( 'CGameplayLightComponent' );
  9880.                 if( glComponent )
  9881.                 {
  9882.                     openFireEnt = entities[i];
  9883.                     return true;
  9884.                 }
  9885.             }
  9886.         }
  9887.         openFireEnt = NULL;
  9888.         return false;
  9889.     }
  9890.    
  9891.     public function CanSpawnCampfire() : bool
  9892.     {
  9893.         fmedCanSpawnCampfire = false;
  9894.        
  9895.         if( HasCampfire() )
  9896.             return false;
  9897.    
  9898.         if( !prepConfig.fmedSpawnCampFire() )
  9899.             return false;
  9900.        
  9901.         if( prepConfig.disallowCampFireInInterior && IsInInterior() )
  9902.             return false;
  9903.        
  9904.         if( prepConfig.disallowCampFireInSettlement && IsInSettlement() )
  9905.             return false;
  9906.        
  9907.         fmedCanSpawnCampfire = prepConfig.HasResourcesForCampfire();
  9908.        
  9909.         return fmedCanSpawnCampfire;
  9910.     }
  9911.    
  9912.     timer function CampFireErrorMessageTimer(dt : float, id : int)
  9913.     {
  9914.         if( !HasCampfire() )
  9915.             theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt( prepConfig.GetSpawnCampfireError() ) );
  9916.     }
  9917.    
  9918.     timer function CampFireResourcesTimer(dt : float, id : int)
  9919.     {
  9920.         prepConfig.RemoveResourcesForCampfire();
  9921.     }
  9922.    
  9923.     public function AdvanceTimeSeconds( seconds : int )
  9924.     {
  9925.         if( seconds > 0 )
  9926.         {
  9927.             theGame.SetGameTime( theGame.GetGameTime() + GameTimeCreateFromGameSeconds( seconds ), false );
  9928.             UpdateEffectsAccelerated( ConvertGameSecondsToRealTimeSeconds( seconds ), 1 );
  9929.         }
  9930.     }
  9931.     //---=== modPreparations ===---
  9932.    
  9933.     public function Meditate() : bool
  9934.     {
  9935.         //---=== modFriendlyMeditation ===---
  9936.         //var medState          : W3PlayerWitcherStateMeditation;
  9937.         //var stateName             : name;
  9938.         //
  9939.         //stateName = GetCurrentStateName();
  9940.         //
  9941.         //
  9942.         //if (!CanMeditate()  || stateName == 'MeditationWaiting' )
  9943.         //  return false;
  9944.         //
  9945.         //GotoState('Meditation');
  9946.         //medState = (W3PlayerWitcherStateMeditation)GetState('Meditation');       
  9947.         //medState.SetMeditationPointHeading(GetHeading());
  9948.         //
  9949.         //return true;
  9950.        
  9951.         if ( !ModCanMeditate() )
  9952.             return false;
  9953.        
  9954.         theGame.RequestMenuWithBackground( 'MeditationClockMenu', 'CommonMenu' );
  9955.        
  9956.         return true;
  9957.         //---=== modFriendlyMeditation ===---
  9958.     }
  9959.    
  9960.    
  9961.     public final function MeditationRestoring(simulatedTime : float)
  9962.     {          
  9963.         //---=== modPreparations ===---
  9964.         if( !prepConfig.disableRegenFullHealth )
  9965.         {
  9966.             Heal( GetStatMax( BCS_Vitality ) );
  9967.         }
  9968.        
  9969.         if( simulatedTime > 0 )
  9970.         {
  9971.             if( prepConfig.disableCleanupCharStatus )
  9972.             {
  9973.                 SimulateBuffTimePassing(simulatedTime);
  9974.             }
  9975.             else
  9976.             {
  9977.                 abilityManager.DrainToxicity( abilityManager.GetStat( BCS_Toxicity ) );
  9978.                 abilityManager.DrainFocus( abilityManager.GetStat( BCS_Focus ) );
  9979.                 FinishQuen(true);
  9980.                 RemoveAllNonAutoBuffs();
  9981.             }
  9982.             inv.SingletonItemsRefillAmmo();
  9983.         }
  9984.         else if( !prepConfig.disableAutorefillQuest )
  9985.         {
  9986.             abilityManager.DrainToxicity( abilityManager.GetStat( BCS_Toxicity ) );
  9987.             abilityManager.DrainFocus( abilityManager.GetStat( BCS_Focus ) );
  9988.             FinishQuen(true);
  9989.             RemoveAllNonAutoBuffs();
  9990.             inv.SingletonItemsRefillAmmo(, true);
  9991.         }
  9992.        
  9993.         ApplyWitcherHouseBuffs();
  9994.         //---=== modPreparations ===---
  9995.     }
  9996.    
  9997.     var clockMenu : CR4MeditationClockMenu;
  9998.    
  9999.     public function MeditationClockStart(m : CR4MeditationClockMenu)
  10000.     {
  10001.         clockMenu = m;
  10002.         AddTimer('UpdateClockTime',0.1,true);
  10003.     }
  10004.    
  10005.     public function MeditationClockStop()
  10006.     {
  10007.         clockMenu = NULL;
  10008.         RemoveTimer('UpdateClockTime');
  10009.     }
  10010.    
  10011.     public timer function UpdateClockTime(dt : float, id : int)
  10012.     {
  10013.         if(clockMenu)
  10014.             clockMenu.UpdateCurrentHours();
  10015.         else
  10016.             RemoveTimer('UpdateClockTime');
  10017.     }
  10018.    
  10019.     private var waitTimeHour : int;
  10020.     public function SetWaitTargetHour(t : int)
  10021.     {
  10022.         waitTimeHour = t;
  10023.     }
  10024.     public function GetWaitTargetHour() : int
  10025.     {
  10026.         return waitTimeHour;
  10027.     }
  10028.    
  10029.     public function MeditationForceAbort(forceCloseUI : bool)
  10030.     {
  10031.         //---=== modFriendlyMeditation ===---
  10032.         //var waitt : W3PlayerWitcherStateMeditationWaiting;
  10033.         //var medd : W3PlayerWitcherStateMeditation;
  10034.         //var currentStateName : name;
  10035.         //
  10036.         //currentStateName = GetCurrentStateName();
  10037.         //
  10038.         //if(currentStateName == 'MeditationWaiting')
  10039.         //{
  10040.         //  waitt = (W3PlayerWitcherStateMeditationWaiting)GetCurrentState();
  10041.         //  if(waitt)
  10042.         //  {
  10043.         //      waitt.StopRequested(forceCloseUI);
  10044.         //  }
  10045.         //}
  10046.         //else if(currentStateName == 'Meditation')
  10047.         //{
  10048.         //  medd = (W3PlayerWitcherStateMeditation)GetCurrentState();
  10049.         //  if(medd)
  10050.         //  {
  10051.         //      medd.StopRequested(forceCloseUI);
  10052.         //  }
  10053.         //}
  10054.         ModEndMeditation();
  10055.         //---=== modFriendlyMeditation ===---
  10056.        
  10057.        
  10058.        
  10059.         if(forceCloseUI && theGame.GetGuiManager().IsAnyMenu())
  10060.         {
  10061.             theGame.GetGuiManager().GetRootMenu().CloseMenu();
  10062.             DisplayActionDisallowedHudMessage(EIAB_MeditationWaiting, false, false, true, false);
  10063.         }
  10064.     }
  10065.    
  10066.     //---=== modFriendlyMeditation ===---
  10067.     public function ModCanMeditate(optional isPlayerMeditatingInBed : bool) : bool
  10068.     {
  10069.         if( isPlayerMeditatingInBed )
  10070.             return true;
  10071.        
  10072.         //checking everything for Preparations compatibility
  10073.         if( !CanMeditate() )
  10074.             return false;
  10075.        
  10076.         if( !CanMeditateWait(true) )
  10077.             return false;
  10078.        
  10079.         if( !CanMeditateHere() )
  10080.             return false;
  10081.        
  10082.         if( !ModCanMeditateHereExt() )
  10083.             return false;
  10084.        
  10085.         return true;
  10086.     }
  10087.    
  10088.     public function ModCanMeditateHereExt() : bool
  10089.     {
  10090.         if( ((CMovingPhysicalAgentComponent)GetMovingAgentComponent()).GetSubmergeDepth() < 0 )
  10091.             return false;
  10092.        
  10093.         return true;
  10094.     }
  10095.    
  10096.     public function ModStartMeditation(optional isPlayerMeditatingInBed : bool, optional isFromClock : bool, optional endTime : float) : bool
  10097.     {
  10098.         if( !ModCanMeditate(isPlayerMeditatingInBed) )
  10099.             return false;
  10100.            
  10101.         if( theGame.GetGuiManager().IsAnyMenu() )
  10102.             theGame.GetGuiManager().GetRootMenu().CloseMenu();
  10103.            
  10104.         if( !IsMeditating() && !IsSkippingTime() )
  10105.         {
  10106.             medIsPlayerMeditatingInBed = isPlayerMeditatingInBed;
  10107.             medIsFromClock = isFromClock;
  10108.             medEndTime = endTime;
  10109.             SetBehaviorVariable('MeditateAbort', 0);
  10110.             PushState('Meditation');
  10111.             return true;
  10112.         }
  10113.         else
  10114.         {
  10115.             if( IsSkippingTime() )
  10116.             {
  10117.                 MeditationEndFastforward();
  10118.             }
  10119.             if( IsMeditating() )
  10120.             {
  10121.                 medIsPlayerMeditatingInBed = isPlayerMeditatingInBed;
  10122.                 medIsFromClock = isFromClock;
  10123.                 medEndTime = endTime;
  10124.                 SetBehaviorVariable('MeditateAbort', 0);
  10125.                 if( isFromClock )
  10126.                     ((W3PlayerWitcherStateMeditation)GetState( 'Meditation' )).StartFastforward();
  10127.                 return true;
  10128.             }
  10129.         }
  10130.        
  10131.         return false;
  10132.     }
  10133.    
  10134.     public function ModEndMeditation()
  10135.     {
  10136.         if( IsMeditating() || IsSkippingTime() )
  10137.         {
  10138.             SetBehaviorVariable('MeditateAbort', 1);
  10139.             PopState();
  10140.             medIsPlayerMeditatingInBed = false;
  10141.             medIsFromClock = false;
  10142.             medEndTime = -1;
  10143.             if( theGame.GetGuiManager().IsAnyMenu() )
  10144.                 theGame.GetGuiManager().GetRootMenu().CloseMenu();
  10145.         }
  10146.     }
  10147.    
  10148.     private var medIsPlayerMeditatingInBed : bool;
  10149.     default medIsPlayerMeditatingInBed = false;
  10150.     public function GetIsPlayerMeditatingInBed() : bool
  10151.     {
  10152.         return medIsPlayerMeditatingInBed;
  10153.     }
  10154.    
  10155.     private var medEndTime : float;
  10156.     default medEndTime = -1;
  10157.     public function GetMeditationTargetTime() : float
  10158.     {
  10159.         return medEndTime;
  10160.     }
  10161.    
  10162.     private var medIsFromClock : bool;
  10163.     default medIsFromClock = false;
  10164.     public function GetMeditationStartedByClock() : bool
  10165.     {
  10166.         return medIsFromClock;
  10167.     }
  10168.    
  10169.     public function MeditationRefill( gameTimeSecs : float ) : bool
  10170.     {
  10171.         if ( fmedAutorefillAlchemy && gameTimeSecs >= fmedRefillIntervalSeconds )
  10172.         {
  10173.             inv.SingletonItemsRefillAmmo();
  10174.             return true;
  10175.         }
  10176.         return false;
  10177.     }
  10178.    
  10179.     public function CheckWitcherHouseBuffs( gameTimeSecs : float ) : bool
  10180.     {
  10181.         if ( fmedApplyWitcherHouseBuffs && GetIsPlayerMeditatingInBed() && CeilF(gameTimeSecs/3600.0) >= fmedWitcherHouseBuffsHours )
  10182.         {
  10183.             ApplyWitcherHouseBuffs();
  10184.             return true;
  10185.         }
  10186.         return false;
  10187.     }
  10188.    
  10189.     timer function DeSpawnCampFireTimer(dt : float, id : int)
  10190.     {
  10191.         spawnedCampFire.ToggleFire( false );
  10192.         spawnedCampFire.Destroy();
  10193.         spawnedCampFire = NULL;
  10194.     }
  10195.    
  10196.     public function MeditationStartFastforward()
  10197.     {
  10198.         if( IsMeditating() )
  10199.         {
  10200.             medIsFromClock = false;
  10201.             ((W3PlayerWitcherStateMeditation)GetState( 'Meditation' )).StartFastforward();
  10202.         }
  10203.     }
  10204.    
  10205.     public function MeditationEndFastforward()
  10206.     {
  10207.         if( IsSkippingTime() )
  10208.         {
  10209.             ((W3PlayerWitcherStateMeditation)GetState( 'Meditation' )).EndFastforward();
  10210.             medIsFromClock = false;
  10211.         }
  10212.     }
  10213.     //---=== modFriendlyMeditation ===---
  10214.    
  10215.     public function Runeword10Triggerred()
  10216.     {
  10217.         var min, max : SAbilityAttributeValue;
  10218.        
  10219.         theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Runeword 10 _Stats', 'stamina', min, max );
  10220.         GainStat(BCS_Stamina, min.valueMultiplicative * GetStatMax(BCS_Stamina));
  10221.         PlayEffect('runeword_10_stamina');
  10222.     }
  10223.    
  10224.     public function Runeword12Triggerred()
  10225.     {
  10226.         var min, max : SAbilityAttributeValue;
  10227.        
  10228.         theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Runeword 12 _Stats', 'focus', min, max );
  10229.         GainStat(BCS_Focus, RandRangeF(max.valueAdditive, min.valueAdditive));
  10230.         PlayEffect('runeword_20_adrenaline');  
  10231.     }
  10232.    
  10233.     var runeword10TriggerredOnFinisher, runeword12TriggerredOnFinisher : bool;
  10234.    
  10235.     event OnFinisherStart()
  10236.     {
  10237.         super.OnFinisherStart();
  10238.        
  10239.         runeword10TriggerredOnFinisher = false;
  10240.         runeword12TriggerredOnFinisher = false;
  10241.     }
  10242.    
  10243.     public function ApplyWitcherHouseBuffs()
  10244.     {
  10245.         var l_bed           : W3WitcherBed;
  10246.        
  10247.         if( FactsQuerySum( "PlayerInsideInnerWitcherHouse" ) > 0 )
  10248.         {
  10249.             l_bed = (W3WitcherBed)theGame.GetEntityByTag( 'witcherBed' );
  10250.            
  10251.             if( l_bed.GetWasUsed() )
  10252.             {
  10253.                 //---=== modPreparations ===---
  10254.                 abilityManager.DrainToxicity( abilityManager.GetStat( BCS_Toxicity ) );
  10255.                 abilityManager.DrainFocus( abilityManager.GetStat( BCS_Focus ) );
  10256.                 //inv.SingletonItemsRefillAmmo();
  10257.                 SimulateBuffTimePassing(0);
  10258.                 //---=== modPreparations ===---
  10259.                 if( l_bed.GetBedLevel() != 0 )
  10260.                 {
  10261.                     AddEffectDefault( EET_WellRested, this, "Bed Buff" );
  10262.                 }
  10263.  
  10264.                 if( FactsQuerySum( "StablesExists" ) )
  10265.                 {
  10266.                     AddEffectDefault( EET_HorseStableBuff, this, "Stables" );
  10267.                 }
  10268.                
  10269.                 //---=== modPreparations ===---
  10270.                 if( FactsQuerySum( "AlchemyTableExists" ) )
  10271.                 {
  10272.                     ManageAlchemyTableBonus();
  10273.                 }
  10274.                
  10275.                 /*if( l_bed.GetWereItemsRefilled() )
  10276.                 {
  10277.                     theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt( "message_common_alchemy_table_buff_applied" ),, true );
  10278.                     l_bed.SetWereItemsRefilled( false );
  10279.                 }*/
  10280.                 //---=== modPreparations ===---
  10281.                
  10282.                 AddEffectDefault( EET_BookshelfBuff, this, "Bookshelf" );
  10283.                
  10284.                 Heal( GetStatMax( BCS_Vitality ) );
  10285.             }
  10286.         }
  10287.     }
  10288.    
  10289.     //---=== modPreparations ===---
  10290.     public function ManageAlchemyTableBonus()
  10291.     {
  10292.         AddEffectDefault( EET_AlchemyTable, this, "Alchemy Table" );
  10293.         theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt( "message_common_alchemy_table_buff_applied" ),, true );
  10294.     }
  10295.     //---=== modPreparations ===---
  10296.    
  10297.    
  10298.    
  10299.    
  10300.     public function CheatResurrect()
  10301.     {
  10302.         super.CheatResurrect();
  10303.         theGame.ReleaseNoSaveLock(theGame.deathSaveLockId);
  10304.         theInput.RestoreContext( 'Exploration', true );
  10305.     }
  10306.    
  10307.    
  10308.     public function Debug_EquipTestingSkills(equip : bool, force : bool)
  10309.     {
  10310.         var skills : array<ESkill>;
  10311.         var i, slot : int;
  10312.        
  10313.        
  10314.         ((W3PlayerAbilityManager)abilityManager).OnLevelGained(36);
  10315.        
  10316.         skills.PushBack(S_Magic_s01);
  10317.         skills.PushBack(S_Magic_s02);
  10318.         skills.PushBack(S_Magic_s03);
  10319.         skills.PushBack(S_Magic_s04);
  10320.         skills.PushBack(S_Magic_s05);
  10321.         skills.PushBack(S_Sword_s01);
  10322.         skills.PushBack(S_Sword_s02);
  10323.        
  10324.        
  10325.         if(equip)
  10326.         {
  10327.             for(i=0; i<skills.Size(); i+=1)
  10328.             {
  10329.                 if(!force && IsSkillEquipped(skills[i]))
  10330.                     continue;
  10331.                    
  10332.                
  10333.                 if(GetSkillLevel(skills[i]) == 0)
  10334.                     AddSkill(skills[i]);
  10335.                
  10336.                
  10337.                 if(force)
  10338.                     slot = i+1;    
  10339.                 else
  10340.                     slot = GetFreeSkillSlot();
  10341.                
  10342.                
  10343.                 EquipSkill(skills[i], slot);
  10344.             }
  10345.         }
  10346.         else
  10347.         {
  10348.             for(i=0; i<skills.Size(); i+=1)
  10349.             {
  10350.                 UnequipSkill(GetSkillSlotID(skills[i]));
  10351.             }
  10352.         }
  10353.     }
  10354.    
  10355.     //modSigns
  10356.     public function Debug_RestoreMutagensSpent()
  10357.     {
  10358.         var total : array<int>;
  10359.        
  10360.         total = ((W3PlayerAbilityManager)abilityManager).GetMutationsUsedMutagens();
  10361.        
  10362.         if(total[0] > 0) inv.AddAnItem('Greater mutagen red', total[0]);
  10363.         if(total[1] > 0) inv.AddAnItem('Greater mutagen blue', total[1]);
  10364.         if(total[2] > 0) inv.AddAnItem('Greater mutagen green', total[2]);
  10365.     }
  10366.  
  10367.     //modSigns
  10368.     public function Debug_ClearCharacterDevelopment( optional resetLevels : bool )
  10369.     {
  10370.         var template : CEntityTemplate;
  10371.         var entity : CEntity;
  10372.         var invTesting : CInventoryComponent;
  10373.         var i, totalExp, currentLevel, totalSkillPoints : int;
  10374.         var items : array<SItemUniqueId>;
  10375.         var abs : array<name>;
  10376.         var isMutationSystemEnabled : bool;
  10377.        
  10378.         UnequipItemFromSlot(EES_SilverSword);
  10379.         UnequipItemFromSlot(EES_SteelSword);
  10380.         UnequipItemFromSlot(EES_Bolt);
  10381.         UnequipItemFromSlot(EES_RangedWeapon);
  10382.         UnequipItemFromSlot(EES_Armor);
  10383.         UnequipItemFromSlot(EES_Boots);
  10384.         UnequipItemFromSlot(EES_Pants);
  10385.         UnequipItemFromSlot(EES_Gloves);
  10386.         UnequipItemFromSlot(EES_Petard1);
  10387.         UnequipItemFromSlot(EES_Petard2);
  10388.         UnequipItemFromSlot(EES_Quickslot1);
  10389.         UnequipItemFromSlot(EES_Quickslot2);
  10390.         UnequipItemFromSlot(EES_Potion1);
  10391.         UnequipItemFromSlot(EES_Potion2);
  10392.         UnequipItemFromSlot(EES_Potion3);
  10393.         UnequipItemFromSlot(EES_Potion4);
  10394.         UnequipItemFromSlot(EES_Mask);
  10395.         UnequipItemFromSlot(EES_SkillMutagen1);
  10396.         UnequipItemFromSlot(EES_SkillMutagen2);
  10397.         UnequipItemFromSlot(EES_SkillMutagen3);
  10398.         UnequipItemFromSlot(EES_SkillMutagen4);
  10399.         HorseUnequipItem(EES_HorseBlinders);
  10400.         HorseUnequipItem(EES_HorseSaddle);
  10401.         HorseUnequipItem(EES_HorseBag);
  10402.         HorseUnequipItem(EES_HorseTrophy);
  10403.        
  10404.         currentLevel = levelManager.GetLevel();
  10405.         totalExp = levelManager.GetPointsTotal(EExperiencePoint);
  10406.         totalSkillPoints = levelManager.GetPointsTotal(ESkillPoint);
  10407.         isMutationSystemEnabled = ((W3PlayerAbilityManager)abilityManager).IsMutationSystemEnabled();
  10408.        
  10409.         Debug_RestoreMutagensSpent();
  10410.        
  10411.         GetCharacterStats().GetAbilities(abs, false);
  10412.         for(i = 0; i < abs.Size(); i+=1)
  10413.             RemoveAbility(abs[i]);
  10414.        
  10415.         abs.Clear();
  10416.         GetCharacterStatsParam(abs);       
  10417.         for(i = 0; i < abs.Size(); i +=1 )
  10418.             AddAbility(abs[i]);
  10419.        
  10420.         delete levelManager;
  10421.         levelManager = new W3LevelManager in this;
  10422.         levelManager.Initialize();
  10423.         levelManager.PostInit(this, false, true);
  10424.        
  10425.         if(!resetLevels)
  10426.         {
  10427.             levelManager.AddPoints(EExperiencePoint, totalExp, false, true);
  10428.             levelManager.AddPoints(ESkillPoint, Max(0, totalSkillPoints - levelManager.GetPointsTotal(ESkillPoint)), false);
  10429.         }
  10430.        
  10431.         delete abilityManager;
  10432.         SetAbilityManager();
  10433.         abilityManager.Init(this, GetCharacterStats(), false, theGame.GetDifficultyMode());
  10434.        
  10435.         delete effectManager;
  10436.         SetEffectManager();
  10437.        
  10438.         abilityManager.PostInit();
  10439.         ((W3PlayerAbilityManager)abilityManager).MutationSystemEnable(isMutationSystemEnabled);
  10440.     }
  10441.    
  10442.     function Debug_BearSetBonusQuenSkills()
  10443.     {
  10444.         var skills  : array<ESkill>;
  10445.         var i, slot : int;
  10446.        
  10447.         skills.PushBack(S_Magic_s04);
  10448.         skills.PushBack(S_Magic_s14);
  10449.        
  10450.         for(i=0; i<skills.Size(); i+=1)
  10451.         {              
  10452.            
  10453.             if(GetSkillLevel(skills[i]) == 0)
  10454.             {
  10455.                 AddSkill(skills[i]);
  10456.             }
  10457.            
  10458.             slot = GetFreeSkillSlot();
  10459.            
  10460.            
  10461.             EquipSkill(skills[i], slot);
  10462.         }
  10463.     }
  10464.    
  10465.     final function Debug_HAX_UnlockSkillSlot(slotIndex : int) : bool
  10466.     {
  10467.         if(abilityManager && abilityManager.IsInitialized())
  10468.             return ((W3PlayerAbilityManager)abilityManager).Debug_HAX_UnlockSkillSlot(slotIndex);
  10469.            
  10470.         return false;
  10471.     }
  10472.    
  10473.    
  10474.     public function GetLevelupAbility( id : int) : name
  10475.     {
  10476.         switch(id)
  10477.         {
  10478.             case 1: return 'Lvl1';
  10479.             case 2: return 'Lvl2';
  10480.             case 3: return 'Lvl3';
  10481.             case 4: return 'Lvl4';
  10482.             case 5: return 'Lvl5';
  10483.             case 6: return 'Lvl6';
  10484.             case 7: return 'Lvl7';
  10485.             case 8: return 'Lvl8';
  10486.             case 9: return 'Lvl9';
  10487.             case 10: return 'Lvl10';
  10488.             case 11: return 'Lvl11';
  10489.             case 12: return 'Lvl12';
  10490.             case 13: return 'Lvl13';
  10491.             case 14: return 'Lvl14';
  10492.             case 15: return 'Lvl15';
  10493.             case 16: return 'Lvl16';
  10494.             case 17: return 'Lvl17';
  10495.             case 18: return 'Lvl18';
  10496.             case 19: return 'Lvl19';
  10497.             case 20: return 'Lvl20';
  10498.             case 21: return 'Lvl21';
  10499.             case 22: return 'Lvl22';
  10500.             case 23: return 'Lvl23';
  10501.             case 24: return 'Lvl24';
  10502.             case 25: return 'Lvl25';
  10503.             case 26: return 'Lvl26';
  10504.             case 27: return 'Lvl27';
  10505.             case 28: return 'Lvl28';
  10506.             case 29: return 'Lvl29';
  10507.             case 30: return 'Lvl30';
  10508.             case 31: return 'Lvl31';
  10509.             case 32: return 'Lvl32';
  10510.             case 33: return 'Lvl33';
  10511.             case 34: return 'Lvl34';
  10512.             case 35: return 'Lvl35';
  10513.             case 36: return 'Lvl36';
  10514.             case 37: return 'Lvl37';
  10515.             case 38: return 'Lvl38';
  10516.             case 39: return 'Lvl39';
  10517.             case 40: return 'Lvl40';
  10518.             case 41: return 'Lvl41';
  10519.             case 42: return 'Lvl42';
  10520.             case 43: return 'Lvl43';
  10521.             case 44: return 'Lvl44';
  10522.             case 45: return 'Lvl45';
  10523.             case 46: return 'Lvl46';
  10524.             case 47: return 'Lvl47';
  10525.             case 48: return 'Lvl48';
  10526.             case 49: return 'Lvl49';
  10527.             case 50: return 'Lvl50';
  10528.        
  10529.             default: return '';
  10530.         }
  10531.        
  10532.         return '';
  10533.     }  
  10534.    
  10535.     public function CanSprint( speed : float ) : bool
  10536.     {
  10537.         if( !super.CanSprint( speed ) )
  10538.         {
  10539.             return false;
  10540.         }      
  10541.         if( rangedWeapon && rangedWeapon.GetCurrentStateName() != 'State_WeaponWait' )
  10542.         {
  10543.             if ( this.GetPlayerCombatStance() ==  PCS_AlertNear )
  10544.             {
  10545.                 if ( IsSprintActionPressed() )
  10546.                     OnRangedForceHolster( true, false );
  10547.             }
  10548.             else
  10549.                 return false;
  10550.         }
  10551.         if( GetCurrentStateName() != 'Swimming' && GetStat(BCS_Stamina) <= 0 )
  10552.         {
  10553.             SetSprintActionPressed(false,true);
  10554.             return false;
  10555.         }
  10556.        
  10557.         return true;
  10558.     }
  10559.    
  10560.     public function ManageSleeping()
  10561.     {
  10562.         thePlayer.RemoveBuffImmunity_AllCritical( 'Bed' );
  10563.         thePlayer.RemoveBuffImmunity_AllNegative( 'Bed' );
  10564.  
  10565.         thePlayer.PlayerStopAction( PEA_GoToSleep );
  10566.     }
  10567.    
  10568.    
  10569.    
  10570.     public function RestoreHorseManager() : bool
  10571.     {
  10572.         var horseTemplate   : CEntityTemplate;
  10573.         var horseManager    : W3HorseManager;  
  10574.        
  10575.         if ( GetHorseManager() )
  10576.         {
  10577.             return false;
  10578.         }
  10579.        
  10580.         horseTemplate = (CEntityTemplate)LoadResource("horse_manager");
  10581.         horseManager = (W3HorseManager)theGame.CreateEntity(horseTemplate, GetWorldPosition(),,,,,PM_Persist);
  10582.         horseManager.CreateAttachment(this);
  10583.         horseManager.OnCreated();
  10584.         EntityHandleSet( horseManagerHandle, horseManager );   
  10585.        
  10586.         return true;
  10587.     }
  10588.    
  10589.    
  10590.    
  10591.    
  10592.    
  10593.    
  10594.     final function PerformParryCheck( parryInfo : SParryInfo ) : bool
  10595.     {
  10596.         if( super.PerformParryCheck( parryInfo ) )
  10597.         {
  10598.             GainAdrenalineFromPerk21( 'parry' );
  10599.             return true;
  10600.         }
  10601.         return false;
  10602.     }  
  10603.    
  10604.     protected final function PerformCounterCheck( parryInfo: SParryInfo ) : bool
  10605.     {
  10606.         var fistFightCheck, isInFistFight       : bool;
  10607.        
  10608.         if( super.PerformCounterCheck( parryInfo ) )
  10609.         {
  10610.             GainAdrenalineFromPerk21( 'counter' );
  10611.            
  10612.             isInFistFight = FistFightCheck( parryInfo.target, parryInfo.attacker, fistFightCheck );
  10613.            
  10614.             if( isInFistFight && fistFightCheck )
  10615.             {
  10616.                 FactsAdd( "statistics_fist_fight_counter" );
  10617.                 AddTimer( 'FistFightCounterTimer', 0.5f, , , , true );
  10618.             }
  10619.            
  10620.             return true;
  10621.         }
  10622.         return false;
  10623.     }
  10624.    
  10625.     public function GainAdrenalineFromPerk21( n : name )
  10626.     {
  10627.         var perkStats, perkTime : SAbilityAttributeValue;
  10628.         var targets : array<CActor>;
  10629.        
  10630.         targets = GetHostileEnemies();
  10631.        
  10632.         if( !CanUseSkill( S_Perk_21 ) || targets.Size() == 0 )
  10633.         {
  10634.             return;
  10635.         }
  10636.        
  10637.         perkTime = GetSkillAttributeValue( S_Perk_21, 'perk21Time', false, false );
  10638.        
  10639.         if( theGame.GetEngineTimeAsSeconds() >= timeForPerk21 + perkTime.valueAdditive )
  10640.         {
  10641.             perkStats = GetSkillAttributeValue( S_Perk_21, n , false, false );
  10642.             GainStat( BCS_Focus, perkStats.valueAdditive );
  10643.             timeForPerk21 = theGame.GetEngineTimeAsSeconds();
  10644.            
  10645.             AddEffectDefault( EET_Perk21InternalCooldown, this, "Perk21", false );
  10646.         }  
  10647.     }
  10648.    
  10649.     timer function FistFightCounterTimer( dt : float, id : int )
  10650.     {
  10651.         FactsRemove( "statistics_fist_fight_counter" );
  10652.     }
  10653.    
  10654.     public final function IsSignBlocked(signType : ESignType) : bool
  10655.     {
  10656.         switch( signType )
  10657.         {
  10658.             case ST_Aard :
  10659.                 return IsRadialSlotBlocked ( 'Aard');
  10660.                 break;
  10661.             case ST_Axii :
  10662.                 return IsRadialSlotBlocked ( 'Axii');
  10663.                 break;
  10664.             case ST_Igni :
  10665.                 return IsRadialSlotBlocked ( 'Igni');
  10666.                 break;
  10667.             case ST_Quen :
  10668.                 return IsRadialSlotBlocked ( 'Quen');
  10669.                 break;
  10670.             case ST_Yrden :
  10671.                 return IsRadialSlotBlocked ( 'Yrden');
  10672.                 break;
  10673.             default:
  10674.                 break;
  10675.         }
  10676.         return false;
  10677.        
  10678.     }
  10679.    
  10680.     public final function AddAnItemWithAutogenLevelAndQuality(itemName : name, desiredLevel : int, minQuality : int, optional equipItem : bool)
  10681.     {
  10682.         var itemLevel, quality : int;
  10683.         var ids : array<SItemUniqueId>;
  10684.         var attemptCounter : int;
  10685.        
  10686.         itemLevel = 0;
  10687.         quality = 0;
  10688.         attemptCounter = 0;
  10689.         while(itemLevel != desiredLevel || quality < minQuality)
  10690.         {
  10691.             attemptCounter += 1;
  10692.             ids.Clear();
  10693.             ids = inv.AddAnItem(itemName, 1, true);
  10694.             itemLevel = inv.GetItemLevel(ids[0]);
  10695.             quality = RoundMath(CalculateAttributeValue(inv.GetItemAttributeValue(ids[0], 'quality')));
  10696.            
  10697.            
  10698.             if(attemptCounter >= 1000)
  10699.                 break;
  10700.            
  10701.             if(itemLevel != desiredLevel || quality < minQuality)
  10702.                 inv.RemoveItem(ids[0]);
  10703.         }
  10704.        
  10705.         if(equipItem)
  10706.             EquipItem(ids[0]);
  10707.     }
  10708.    
  10709.     public final function AddAnItemWithAutogenLevel(itemName : name, desiredLevel : int)
  10710.     {
  10711.         var itemLevel : int;
  10712.         var ids : array<SItemUniqueId>;
  10713.         var attemptCounter : int;
  10714.  
  10715.         itemLevel = 0;
  10716.         while(itemLevel != desiredLevel)
  10717.         {
  10718.             attemptCounter += 1;
  10719.             ids.Clear();
  10720.             ids = inv.AddAnItem(itemName, 1, true);
  10721.             itemLevel = inv.GetItemLevel(ids[0]);
  10722.            
  10723.            
  10724.             if(attemptCounter >= 1000)
  10725.                 break;
  10726.                
  10727.             if(itemLevel != desiredLevel)
  10728.                 inv.RemoveItem(ids[0]);
  10729.         }
  10730.     }
  10731.    
  10732.     public final function AddAnItemWithMinQuality(itemName : name, minQuality : int, optional equip : bool)
  10733.     {
  10734.         var quality : int;
  10735.         var ids : array<SItemUniqueId>;
  10736.         var attemptCounter : int;
  10737.  
  10738.         quality = 0;
  10739.         while(quality < minQuality)
  10740.         {
  10741.             attemptCounter += 1;
  10742.             ids.Clear();
  10743.             ids = inv.AddAnItem(itemName, 1, true);
  10744.             quality = RoundMath(CalculateAttributeValue(inv.GetItemAttributeValue(ids[0], 'quality')));
  10745.            
  10746.            
  10747.             if(attemptCounter >= 1000)
  10748.                 break;
  10749.                
  10750.             if(quality < minQuality)
  10751.                 inv.RemoveItem(ids[0]);
  10752.         }
  10753.        
  10754.         if(equip)
  10755.             EquipItem(ids[0]);
  10756.     }
  10757.    
  10758.    
  10759.    
  10760.    
  10761.    
  10762.    
  10763.     //modSigns: fix equipped, only once
  10764.     private function RecalcSetItemsEquipped()
  10765.     {
  10766.         var slotsToCheck : array<EEquipmentSlots>;
  10767.         var setType : EItemSetType;
  10768.         var item : SItemUniqueId;
  10769.         var i : int;
  10770.        
  10771.         for(i = 0; i < amountOfSetPiecesEquipped.Size(); i += 1)
  10772.             amountOfSetPiecesEquipped[i] = 0;
  10773.        
  10774.         slotsToCheck.PushBack(EES_Armor);
  10775.         slotsToCheck.PushBack(EES_Boots);
  10776.         slotsToCheck.PushBack(EES_Pants);
  10777.         slotsToCheck.PushBack(EES_Gloves);
  10778.         slotsToCheck.PushBack(EES_SilverSword);
  10779.         slotsToCheck.PushBack(EES_SteelSword);
  10780.    
  10781.         for(i = 0; i < slotsToCheck.Size(); i += 1)
  10782.         {
  10783.             if(GetItemEquippedOnSlot(slotsToCheck[i], item) && inv.ItemHasTag(item, 'SetBonusPiece'))
  10784.             {
  10785.                 setType = CheckSetType( item );
  10786.                 amountOfSetPiecesEquipped[ setType ] += 1;
  10787.                 ManageSetBonusesSoundbanks( setType );
  10788.             }
  10789.         }
  10790.     }
  10791.    
  10792.     //modSigns: minor sets added
  10793.     public function IsSetBonusActive( bonus : EItemSetBonus ) : bool
  10794.     {
  10795.         switch(bonus)
  10796.         {
  10797.             case EISB_Lynx_1:
  10798.                 return amountOfSetPiecesEquipped[ EIST_Lynx ] + amountOfSetPiecesEquipped[ EIST_Lynx_Minor ] >= theGame.params.ITEMS_REQUIRED_FOR_MINOR_SET_BONUS;
  10799.             case EISB_Lynx_2:
  10800.                 return amountOfSetPiecesEquipped[ EIST_Lynx ] >= theGame.params.ITEMS_REQUIRED_FOR_MAJOR_SET_BONUS;
  10801.             case EISB_Gryphon_1:
  10802.                 return amountOfSetPiecesEquipped[ EIST_Gryphon ] + amountOfSetPiecesEquipped[ EIST_Gryphon_Minor ] >= theGame.params.ITEMS_REQUIRED_FOR_MINOR_SET_BONUS;
  10803.             case EISB_Gryphon_2:
  10804.                 return amountOfSetPiecesEquipped[ EIST_Gryphon ] >= theGame.params.ITEMS_REQUIRED_FOR_MAJOR_SET_BONUS;
  10805.             case EISB_Bear_1:
  10806.                 return amountOfSetPiecesEquipped[ EIST_Bear ] + amountOfSetPiecesEquipped[ EIST_Bear_Minor ] >= theGame.params.ITEMS_REQUIRED_FOR_MINOR_SET_BONUS;
  10807.             case EISB_Bear_2:
  10808.                 return amountOfSetPiecesEquipped[ EIST_Bear ] >= theGame.params.ITEMS_REQUIRED_FOR_MAJOR_SET_BONUS;
  10809.             case EISB_Wolf_1:
  10810.                 return amountOfSetPiecesEquipped[ EIST_Wolf ] + amountOfSetPiecesEquipped[ EIST_Wolf_Minor ] >= theGame.params.ITEMS_REQUIRED_FOR_MINOR_SET_BONUS;
  10811.             case EISB_Wolf_2:
  10812.                 return amountOfSetPiecesEquipped[ EIST_Wolf ] >= theGame.params.ITEMS_REQUIRED_FOR_MAJOR_SET_BONUS;
  10813.             case EISB_RedWolf_1:
  10814.                 return amountOfSetPiecesEquipped[ EIST_RedWolf ] >= theGame.params.ITEMS_REQUIRED_FOR_MINOR_SET_BONUS;
  10815.             case EISB_RedWolf_2:
  10816.                 return amountOfSetPiecesEquipped[ EIST_RedWolf ] >= theGame.params.ITEMS_REQUIRED_FOR_MAJOR_SET_BONUS;
  10817.             case EISB_Vampire:
  10818.                 return amountOfSetPiecesEquipped[ EIST_Vampire ] >= theGame.params.ITEMS_REQUIRED_FOR_MINOR_SET_BONUS;
  10819.             //modSigns
  10820.             case EISB_Viper:
  10821.                 return amountOfSetPiecesEquipped[ EIST_Viper ] >= GetNumItemsRequiredForSetActivation(EIST_Viper);
  10822.             case EISB_KaerMorhen:
  10823.                 return amountOfSetPiecesEquipped[ EIST_KaerMorhen ] >= GetNumItemsRequiredForSetActivation(EIST_KaerMorhen);
  10824.             default:                    return false;
  10825.         }
  10826.     }
  10827.    
  10828.     //modSigns: minor sets
  10829.     public function GetSetPartsEquipped( setType : EItemSetType ) : int
  10830.     {
  10831.         switch( setType )
  10832.         {
  10833.             case EIST_Lynx:
  10834.             case EIST_Lynx_Minor:
  10835.                 return amountOfSetPiecesEquipped[ EIST_Lynx ] + amountOfSetPiecesEquipped[ EIST_Lynx_Minor ];
  10836.             case EIST_Gryphon:
  10837.             case EIST_Gryphon_Minor:
  10838.                 return amountOfSetPiecesEquipped[ EIST_Gryphon ] + amountOfSetPiecesEquipped[ EIST_Gryphon_Minor ];
  10839.             case EIST_Bear:
  10840.             case EIST_Bear_Minor:
  10841.                 return amountOfSetPiecesEquipped[ EIST_Bear ] + amountOfSetPiecesEquipped[ EIST_Bear_Minor ];
  10842.             case EIST_Wolf:
  10843.             case EIST_Wolf_Minor:
  10844.                 return amountOfSetPiecesEquipped[ EIST_Wolf ] + amountOfSetPiecesEquipped[ EIST_Wolf_Minor ];
  10845.             default:
  10846.                 return amountOfSetPiecesEquipped[ setType ];
  10847.         }
  10848.     }
  10849.    
  10850.     //modSigns
  10851.     public function GetSetPartsEquippedRaw( setType : EItemSetType ) : int
  10852.     {
  10853.         return amountOfSetPiecesEquipped[ setType ];
  10854.     }
  10855.    
  10856.     //modSigns
  10857.     public function HasMixedSetsEquipped() : bool
  10858.     {
  10859.         return  amountOfSetPiecesEquipped[ EIST_Lynx ] > 0 && amountOfSetPiecesEquipped[ EIST_Lynx_Minor ] > 0 ||
  10860.                 amountOfSetPiecesEquipped[ EIST_Gryphon ] > 0 && amountOfSetPiecesEquipped[ EIST_Gryphon_Minor ] > 0 ||
  10861.                 amountOfSetPiecesEquipped[ EIST_Bear ] > 0 && amountOfSetPiecesEquipped[ EIST_Bear_Minor ] > 0 ||
  10862.                 amountOfSetPiecesEquipped[ EIST_Wolf ] > 0 && amountOfSetPiecesEquipped[ EIST_Wolf_Minor ] > 0;
  10863.     }
  10864.    
  10865.     protected function UpdateItemSetBonuses( item : SItemUniqueId, increment : bool )
  10866.     {
  10867.         var setType : EItemSetType;
  10868.         var tutorialStateSets : W3TutorialManagerUIHandlerStateSetItemsUnlocked;
  10869.         var id : SItemUniqueId;
  10870.                    
  10871.         if( !inv.IsIdValid( item ) || !inv.ItemHasTag(item, theGame.params.ITEM_SET_TAG_BONUS ) )  
  10872.         {
  10873.            
  10874.             if( !IsSetBonusActive( EISB_Wolf_2 ) ) //modSigns
  10875.             {
  10876.                 if( GetItemEquippedOnSlot( EES_SteelSword, id ) )
  10877.                 {
  10878.                     RemoveExtraOilsFromItem( id );
  10879.                 }
  10880.                 if( GetItemEquippedOnSlot( EES_SilverSword, id ) )
  10881.                 {
  10882.                     RemoveExtraOilsFromItem( id );
  10883.                 }
  10884.             }
  10885.        
  10886.             return;
  10887.         }
  10888.        
  10889.         setType = CheckSetType( item );
  10890.        
  10891.         if( increment )
  10892.         {
  10893.             amountOfSetPiecesEquipped[ setType ] += 1;
  10894.            
  10895.             //modSigns
  10896.             if( GetSetPartsEquipped(setType) >= GetNumItemsRequiredForSetActivation(setType) && ShouldProcessTutorial( 'TutorialSetBonusesUnlocked' ) && theGame.GetTutorialSystem().uiHandler && theGame.GetTutorialSystem().uiHandler.GetCurrentStateName() == 'SetItemsUnlocked' )
  10897.             {
  10898.                 tutorialStateSets = ( W3TutorialManagerUIHandlerStateSetItemsUnlocked )theGame.GetTutorialSystem().uiHandler.GetCurrentState();
  10899.                 tutorialStateSets.OnSetBonusCompleted();
  10900.             }
  10901.         }
  10902.         else if( amountOfSetPiecesEquipped[ setType ] > 0 )
  10903.         {
  10904.             amountOfSetPiecesEquipped[ setType ] -= 1;
  10905.         }
  10906.        
  10907.        
  10908.         //modSigns
  10909.         //if( setType < EIST_Viper && amountOfSetPiecesEquipped[ setType ] == theGame.params.ITEMS_REQUIRED_FOR_MAJOR_SET_BONUS )
  10910.         if( IsSetBonusActive(EISB_Lynx_2) || IsSetBonusActive(EISB_Gryphon_2) || IsSetBonusActive(EISB_Bear_2) || IsSetBonusActive(EISB_Wolf_2) || IsSetBonusActive(EISB_RedWolf_2) )
  10911.         {
  10912.             theGame.GetGamerProfile().AddAchievement( EA_ReadyToRoll );
  10913.         }
  10914.        
  10915.        
  10916.         if( !IsSetBonusActive( EISB_Wolf_2 ) ) //modSigns
  10917.         {
  10918.             if( GetItemEquippedOnSlot( EES_SteelSword, id ) )
  10919.             {
  10920.                 RemoveExtraOilsFromItem( id );
  10921.             }
  10922.             if( GetItemEquippedOnSlot( EES_SilverSword, id ) )
  10923.             {
  10924.                 RemoveExtraOilsFromItem( id );
  10925.             }
  10926.         }
  10927.        
  10928.         ManageActiveSetBonuses( setType );
  10929.        
  10930.        
  10931.         ManageSetBonusesSoundbanks( setType );
  10932.     }
  10933.    
  10934.     public function ManageActiveSetBonuses( setType : EItemSetType )
  10935.     {
  10936.         var l_i             : int;
  10937.        
  10938.        
  10939.         if( setType == EIST_Lynx || setType == EIST_Lynx_Minor ) //modSigns
  10940.         {
  10941.            
  10942.             if( HasBuff( EET_LynxSetBonus ) && !IsSetBonusActive( EISB_Lynx_1 ) )
  10943.             {
  10944.                 RemoveBuff( EET_LynxSetBonus );
  10945.             }
  10946.         }
  10947.        
  10948.         else if( setType == EIST_Gryphon )
  10949.         {
  10950.            
  10951.             if( !IsSetBonusActive( EISB_Gryphon_1 ) )
  10952.             {
  10953.                 RemoveBuff( EET_GryphonSetBonus );
  10954.             }
  10955.            
  10956.             if( IsSetBonusActive( EISB_Gryphon_2 ) && !HasBuff( EET_GryphonSetBonusYrden ) )
  10957.             {
  10958.                 for( l_i = 0 ; l_i < yrdenEntities.Size() ; l_i += 1 )
  10959.                 {
  10960.                     if( yrdenEntities[ l_i ].GetIsPlayerInside() && !yrdenEntities[ l_i ].IsAlternateCast() )
  10961.                     {
  10962.                         AddEffectDefault( EET_GryphonSetBonusYrden, this, "GryphonSetBonusYrden" );
  10963.                         break;
  10964.                     }
  10965.                 }
  10966.             }
  10967.             else
  10968.             {
  10969.                 RemoveBuff( EET_GryphonSetBonusYrden );
  10970.             }
  10971.         }
  10972.        
  10973.         //modSigns
  10974.         else if( setType == EIST_KaerMorhen )
  10975.         {
  10976.             if( !IsSetBonusActive(EISB_KaerMorhen) && HasBuff(EET_KaerMorhenSetBonus) )
  10977.             {
  10978.                 RemoveBuff(EET_KaerMorhenSetBonus);
  10979.             }
  10980.             else if( IsSetBonusActive(EISB_KaerMorhen) && !HasBuff(EET_KaerMorhenSetBonus) && IsInCombat() )
  10981.             {
  10982.                 AddEffectDefault(EET_KaerMorhenSetBonus, this, "KaerMorhenSetBonus");
  10983.             }
  10984.         }
  10985.     }
  10986.    
  10987.     public function CheckSetTypeByName( itemName : name ) : EItemSetType
  10988.     {
  10989.         var dm : CDefinitionsManagerAccessor;
  10990.        
  10991.         dm = theGame.GetDefinitionsManager();
  10992.        
  10993.         if( dm.ItemHasTag( itemName, theGame.params.ITEM_SET_TAG_LYNX ) )
  10994.         {
  10995.             return EIST_Lynx;
  10996.         }
  10997.         else
  10998.         if( dm.ItemHasTag( itemName, theGame.params.ITEM_SET_TAG_GRYPHON ) )
  10999.         {
  11000.             return EIST_Gryphon;
  11001.         }
  11002.         else
  11003.         if( dm.ItemHasTag( itemName, theGame.params.ITEM_SET_TAG_BEAR ) )
  11004.         {
  11005.             return EIST_Bear;
  11006.         }
  11007.         else
  11008.         if( dm.ItemHasTag( itemName, theGame.params.ITEM_SET_TAG_WOLF ) )
  11009.         {
  11010.             return EIST_Wolf;
  11011.         }
  11012.         else
  11013.         if( dm.ItemHasTag( itemName, theGame.params.ITEM_SET_TAG_RED_WOLF ) )
  11014.         {
  11015.             return EIST_RedWolf;
  11016.         }
  11017.         else
  11018.         if( dm.ItemHasTag( itemName, theGame.params.ITEM_SET_TAG_VAMPIRE ) )
  11019.         {
  11020.             return EIST_Vampire;
  11021.         }
  11022.         else
  11023.         if( dm.ItemHasTag( itemName, theGame.params.ITEM_SET_TAG_VIPER ) )
  11024.         {
  11025.             return EIST_Viper;
  11026.         }
  11027.         else
  11028.         //modSigns
  11029.         if( dm.ItemHasTag( itemName, theGame.params.ITEM_SET_TAG_KAER_MORHEN ) )
  11030.         {
  11031.             return EIST_KaerMorhen;
  11032.         }
  11033.         else
  11034.         if( dm.ItemHasTag( itemName, theGame.params.ITEM_SET_TAG_LYNX_MINOR ) )
  11035.         {
  11036.             return EIST_Lynx_Minor;
  11037.         }
  11038.         else
  11039.         if( dm.ItemHasTag( itemName, theGame.params.ITEM_SET_TAG_GRYPHON_MINOR ) )
  11040.         {
  11041.             return EIST_Gryphon_Minor;
  11042.         }
  11043.         else
  11044.         if( dm.ItemHasTag( itemName, theGame.params.ITEM_SET_TAG_BEAR_MINOR ) )
  11045.         {
  11046.             return EIST_Bear_Minor;
  11047.         }
  11048.         else
  11049.         if( dm.ItemHasTag( itemName, theGame.params.ITEM_SET_TAG_WOLF_MINOR ) )
  11050.         {
  11051.             return EIST_Wolf_Minor;
  11052.         }
  11053.         else
  11054.         {
  11055.             return EIST_Undefined;
  11056.         }
  11057.     }
  11058.    
  11059.     public function CheckSetType( item : SItemUniqueId ) : EItemSetType
  11060.     {
  11061.         var stopLoop    : bool;
  11062.         var tags        : array<name>;
  11063.         var i           : int;
  11064.         var setType     : EItemSetType;
  11065.        
  11066.         stopLoop = false;
  11067.        
  11068.         inv.GetItemTags( item, tags );
  11069.        
  11070.        
  11071.         for( i=0; i<tags.Size(); i+=1 )
  11072.         {
  11073.             switch( tags[i] )
  11074.             {
  11075.                 case theGame.params.ITEM_SET_TAG_LYNX:
  11076.                 case theGame.params.ITEM_SET_TAG_GRYPHON:
  11077.                 case theGame.params.ITEM_SET_TAG_BEAR:
  11078.                 case theGame.params.ITEM_SET_TAG_WOLF:
  11079.                 case theGame.params.ITEM_SET_TAG_RED_WOLF:
  11080.                 case theGame.params.ITEM_SET_TAG_VAMPIRE:
  11081.                 case theGame.params.ITEM_SET_TAG_VIPER:
  11082.                 //modSigns
  11083.                 case theGame.params.ITEM_SET_TAG_KAER_MORHEN:
  11084.                 case theGame.params.ITEM_SET_TAG_LYNX_MINOR:
  11085.                 case theGame.params.ITEM_SET_TAG_GRYPHON_MINOR:
  11086.                 case theGame.params.ITEM_SET_TAG_BEAR_MINOR:
  11087.                 case theGame.params.ITEM_SET_TAG_WOLF_MINOR:
  11088.                     setType = SetItemNameToType( tags[i] );
  11089.                     stopLoop = true;
  11090.                     break;
  11091.             }      
  11092.             if ( stopLoop )
  11093.             {
  11094.                 break;
  11095.             }
  11096.         }
  11097.        
  11098.         return setType;
  11099.     }
  11100.    
  11101.     public function GetSetBonusStatusByName( itemName : name, out desc1, desc2 : string, out isActive1, isActive2 : bool ) : EItemSetType
  11102.     {
  11103.         var setType : EItemSetType;
  11104.        
  11105.         if( theGame.GetDLCManager().IsEP2Enabled() )
  11106.         {
  11107.             setType = CheckSetTypeByName( itemName );
  11108.             SetBonusStatusByType( setType, desc1, desc2, isActive1, isActive2 );
  11109.            
  11110.             return setType;    
  11111.         }
  11112.         else
  11113.         {
  11114.             return EIST_Undefined;
  11115.         }
  11116.     }
  11117.    
  11118.     public function GetSetBonusStatus( item : SItemUniqueId, out desc1, desc2 : string, out isActive1, isActive2 : bool ) : EItemSetType
  11119.     {
  11120.         var setType : EItemSetType;
  11121.        
  11122.         if( theGame.GetDLCManager().IsEP2Enabled() )
  11123.         {
  11124.             setType = CheckSetType( item );
  11125.             SetBonusStatusByType( setType, desc1, desc2, isActive1, isActive2 );
  11126.            
  11127.             return setType;
  11128.         }
  11129.         else
  11130.         {
  11131.             return EIST_Undefined;
  11132.         }
  11133.     }
  11134.    
  11135.     private function SetBonusStatusByType(setType : EItemSetType, out desc1, desc2 : string, out isActive1, isActive2 : bool):void
  11136.     {
  11137.         var setBonus : EItemSetBonus;
  11138.        
  11139.         //modSigns
  11140.         isActive1 = (GetSetPartsEquipped(setType) >= GetNumItemsRequiredForSetActivation(setType));
  11141.         isActive2 = (amountOfSetPiecesEquipped[ setType ] >= theGame.params.ITEMS_REQUIRED_FOR_MAJOR_SET_BONUS);
  11142.        
  11143.         setBonus = ItemSetTypeToItemSetBonus( setType, 1 );
  11144.         desc1 = GetSetBonusTooltipDescription( setBonus );
  11145.        
  11146.         setBonus = ItemSetTypeToItemSetBonus( setType, 2 );
  11147.         desc2 = GetSetBonusTooltipDescription( setBonus );
  11148.     }
  11149.    
  11150.     public function ItemSetTypeToItemSetBonus( setType : EItemSetType, nr : int ) : EItemSetBonus
  11151.     {
  11152.         var setBonus : EItemSetBonus;
  11153.    
  11154.         if( nr == 1 )
  11155.         {
  11156.             switch( setType )
  11157.             {
  11158.                 case EIST_Lynx:             setBonus = EISB_Lynx_1;     break;
  11159.                 case EIST_Gryphon:          setBonus = EISB_Gryphon_1;  break;
  11160.                 case EIST_Bear:             setBonus = EISB_Bear_1;     break;
  11161.                 case EIST_Wolf:             setBonus = EISB_Wolf_1;     break;
  11162.                 case EIST_RedWolf:          setBonus = EISB_RedWolf_1;  break;
  11163.                 case EIST_Vampire:          setBonus = EISB_Vampire;    break;
  11164.                 //modSigns
  11165.                 case EIST_Viper:            setBonus = EISB_Viper;      break;
  11166.                 case EIST_KaerMorhen:       setBonus = EISB_KaerMorhen; break;
  11167.                 case EIST_Lynx_Minor:       setBonus = EISB_Lynx_1;     break;
  11168.                 case EIST_Gryphon_Minor:    setBonus = EISB_Gryphon_1;  break;
  11169.                 case EIST_Bear_Minor:       setBonus = EISB_Bear_1;     break;
  11170.                 case EIST_Wolf_Minor:       setBonus = EISB_Wolf_1;     break;
  11171.             }
  11172.         }
  11173.         else
  11174.         {
  11175.             switch( setType )
  11176.             {
  11177.                 case EIST_Lynx:             setBonus = EISB_Lynx_2;     break;
  11178.                 case EIST_Gryphon:          setBonus = EISB_Gryphon_2;  break;
  11179.                 case EIST_Bear:             setBonus = EISB_Bear_2;     break;
  11180.                 case EIST_Wolf:             setBonus = EISB_Wolf_2;     break;
  11181.                 case EIST_RedWolf:          setBonus = EISB_RedWolf_2;  break;
  11182.                 case EIST_Vampire:          setBonus = EISB_Undefined;  break;
  11183.                 //modSigns
  11184.                 case EIST_Viper:            setBonus = EISB_Undefined;  break;
  11185.                 case EIST_KaerMorhen:       setBonus = EISB_Undefined;  break;
  11186.                 case EIST_Lynx_Minor:       setBonus = EISB_Undefined;  break;
  11187.                 case EIST_Gryphon_Minor:    setBonus = EISB_Undefined;  break;
  11188.                 case EIST_Bear_Minor:       setBonus = EISB_Undefined;  break;
  11189.                 case EIST_Wolf_Minor:       setBonus = EISB_Undefined;  break;
  11190.             }
  11191.         }
  11192.    
  11193.         return setBonus;
  11194.     }
  11195.    
  11196.     public function GetSetBonusTooltipDescription( bonus : EItemSetBonus ) : string
  11197.     {
  11198.         var finalString : string;
  11199.         var arrString   : array<string>;
  11200.         var dm          : CDefinitionsManagerAccessor;
  11201.         var min, max    : SAbilityAttributeValue;
  11202.         var tempString  : string;
  11203.         var tmpVal      : float; //modSigns
  11204.        
  11205.         switch( bonus )
  11206.         {
  11207.             case EISB_Lynx_1:           tempString = "skill_desc_lynx_set_ability1"; break;
  11208.             case EISB_Lynx_2:           tempString = "skill_desc_lynx_set_ability2"; break;
  11209.             case EISB_Gryphon_1:        tempString = "skill_desc_gryphon_set_ability1"; break;
  11210.             case EISB_Gryphon_2:        tempString = "skill_desc_gryphon_set_ability2"; break;
  11211.             case EISB_Bear_1:           tempString = "skill_desc_bear_set_ability1"; break;
  11212.             case EISB_Bear_2:           tempString = "skill_desc_bear_set_ability2"; break;
  11213.             case EISB_Wolf_1:           tempString = "skill_desc_wolf_set_ability1"; break;
  11214.             case EISB_Wolf_2:           tempString = "skill_desc_wolf_set_ability2"; break;
  11215.             case EISB_RedWolf_1:        tempString = "skill_desc_red_wolf_set_ability1"; break;
  11216.             case EISB_RedWolf_2:        tempString = "skill_desc_red_wolf_set_ability2"; break;
  11217.             case EISB_Vampire:          tempString = "skill_desc_vampire_set_ability1"; break;
  11218.             //modSigns
  11219.             case EISB_Viper:            tempString = "skill_desc_viper_set_ability1"; break;
  11220.             case EISB_KaerMorhen:       tempString = "skill_desc_kaer_morhen_set_ability1"; break;
  11221.             default:                    tempString = ""; break;
  11222.         }
  11223.        
  11224.         dm = theGame.GetDefinitionsManager();
  11225.        
  11226.         switch( bonus )
  11227.         {
  11228.         case EISB_Lynx_1:
  11229.             dm.GetAbilityAttributeValue( 'LynxSetBonusEffect', 'duration', min, max );
  11230.             arrString.PushBack( FloatToString( min.valueAdditive ) );
  11231.             dm.GetAbilityAttributeValue( 'LynxSetBonusEffect', 'lynx_dmg_boost', min, max );
  11232.             arrString.PushBack( FloatToString( min.valueAdditive * 100 ) );
  11233.             arrString.PushBack( FloatToString( min.valueAdditive * 100 * GetSetPartsEquipped( EIST_Lynx ) ) );
  11234.             finalString = GetLocStringByKeyExtWithParams( tempString,,,arrString );
  11235.             break;
  11236.         case EISB_Lynx_2:
  11237.             /*dm.GetAbilityAttributeValue( GetSetBonusAbility( EISB_Lynx_2 ), 'lynx_2_dmg_boost', min, max );
  11238.             arrString.PushBack( FloatToString( min.valueAdditive * 100 ) );
  11239.            
  11240.             dm.GetAbilityAttributeValue( GetSetBonusAbility( EISB_Lynx_2 ), 'lynx_2_adrenaline_cost', min, max );
  11241.             arrString.PushBack( FloatToString( min.valueAdditive ) );*/
  11242.             //modSigns: bonus changed
  11243.            
  11244.             finalString = GetLocStringByKeyExtWithParams( tempString,,,arrString );
  11245.             break;
  11246.         case EISB_Gryphon_1:
  11247.             //modSigns: new mechanic
  11248.             dm.GetAbilityAttributeValue( 'GryphonSetBonusEffect', 'duration', min, max );
  11249.             arrString.PushBack( FloatToString( min.valueAdditive ) );
  11250.             dm.GetAbilityAttributeValue( 'GryphonSetBonusEffect', 'gryphon_sign_power_boost', min, max );
  11251.             arrString.PushBack( FloatToString( min.valueAdditive * 100 ) );
  11252.             arrString.PushBack( FloatToString( min.valueAdditive * 100 * GetSetPartsEquipped( EIST_Gryphon ) ) );
  11253.             finalString = GetLocStringByKeyExtWithParams( tempString,,,arrString );
  11254.             break;     
  11255.         case EISB_Gryphon_2:
  11256.             dm.GetAbilityAttributeValue( 'GryphonSetBonusYrdenEffect', 'trigger_scale', min, max );
  11257.             arrString.PushBack( FloatToString( ( min.valueAdditive - 1 )* 100) );
  11258.             //dm.GetAbilityAttributeValue( 'GryphonSetBonusYrdenEffect', 'staminaRegen', min, max ); //modSigns: removed
  11259.             //arrString.PushBack( FloatToString( min.valueMultiplicative * 100) );
  11260.             dm.GetAbilityAttributeValue( 'GryphonSetBonusYrdenEffect', 'spell_power', min, max );
  11261.             arrString.PushBack( FloatToString( min.valueMultiplicative * 100) );
  11262.             dm.GetAbilityAttributeValue( 'GryphonSetBonusYrdenEffect', 'slashing_resistance_perc', min, max );
  11263.             arrString.PushBack( FloatToString( min.valueAdditive * 100) );
  11264.             finalString = GetLocStringByKeyExtWithParams( tempString,,,arrString );
  11265.             break;
  11266.         case EISB_Bear_1: //modSigns: full set redesign
  11267.             dm.GetAbilityAttributeValue( 'setBonusAbilityBear_1', 'bear_set_reduce_dmg_per_piece', min, max );
  11268.             arrString.PushBack( FloatToString( CalculateAttributeValue(min) * 100 ) );
  11269.             arrString.PushBack( FloatToString( CalculateAttributeValue(min) * 100 * GetSetPartsEquipped( EIST_Bear ) ) );
  11270.             finalString = GetLocStringByKeyExtWithParams( tempString,,,arrString );
  11271.             break;
  11272.         case EISB_Bear_2:
  11273.             dm.GetAbilityAttributeValue( 'setBonusAbilityBear_2', 'quen_dmg_boost', min, max );
  11274.             arrString.PushBack( FloatToString( min.valueMultiplicative * 100 ) );
  11275.             finalString = GetLocStringByKeyExtWithParams( tempString,,,arrString );
  11276.             break;
  11277.         //modSigns
  11278.         case EISB_Wolf_1:
  11279.             dm.GetAbilityAttributeValue( 'SetBonusAbilityWolf_1', 'per_piece_oil_bonus', min, max );
  11280.             arrString.PushBack( FloatToString( CalculateAttributeValue(min) * 100 ) );
  11281.             arrString.PushBack( FloatToString( CalculateAttributeValue(min) * 100 * GetSetPartsEquipped( EIST_Wolf ) ) );
  11282.             finalString = GetLocStringByKeyExtWithParams( tempString,,,arrString );
  11283.             break;
  11284.         case EISB_Wolf_2:
  11285.             dm.GetAbilityAttributeValue( 'SetBonusAbilityWolf_2', 'per_oil_crit_chance_bonus', min, max );
  11286.             arrString.PushBack( FloatToString( CalculateAttributeValue(min) * 100 ) );
  11287.             dm.GetAbilityAttributeValue( 'SetBonusAbilityWolf_2', 'per_oil_crit_power_bonus', min, max );
  11288.             arrString.PushBack( FloatToString( CalculateAttributeValue(min) * 100 ) );
  11289.             finalString = GetLocStringByKeyExtWithParams( tempString,,,arrString );
  11290.             break;
  11291.         case EISB_RedWolf_1:
  11292.             dm.GetAbilityAttributeValue( 'setBonusAbilityRedWolf_1', 'per_redwolf_piece_crit_chance_bonus', min, max );
  11293.             arrString.PushBack( FloatToString( CalculateAttributeValue(min) * 100 ) );
  11294.             arrString.PushBack( FloatToString( CalculateAttributeValue(min) * 100 * GetSetPartsEquipped( EIST_RedWolf ) ) );
  11295.             dm.GetAbilityAttributeValue( 'setBonusAbilityRedWolf_1', 'per_redwolf_piece_crit_power_bonus', min, max );
  11296.             arrString.PushBack( FloatToString( CalculateAttributeValue(min) * 100 ) );
  11297.             arrString.PushBack( FloatToString( CalculateAttributeValue(min) * 100 * GetSetPartsEquipped( EIST_RedWolf ) ) );
  11298.             finalString = GetLocStringByKeyExtWithParams( tempString,,,arrString );
  11299.             break;
  11300.         case EISB_RedWolf_2:
  11301.             dm.GetAbilityAttributeValue( 'setBonusAbilityRedWolf_2', 'amount', min, max );
  11302.             arrString.PushBack( FloatToString( min.valueAdditive ) );
  11303.             finalString = GetLocStringByKeyExtWithParams( tempString,,,arrString );
  11304.             break;
  11305.         case EISB_Vampire:
  11306.             dm.GetAbilityAttributeValue( 'setBonusAbilityVampire', 'life_percent', min, max );
  11307.             arrString.PushBack( FloatToString( min.valueAdditive ) );
  11308.             arrString.PushBack( FloatToString( min.valueAdditive * GetSetPartsEquipped( EIST_Vampire ) ) );
  11309.             finalString = GetLocStringByKeyExtWithParams( tempString,,,arrString );
  11310.             break;
  11311.         //modSigns
  11312.         case EISB_Viper:
  11313.             dm.GetAbilityAttributeValue( 'setBonusAbilityViper_1', 'per_viper_piece_poison_healing_rate', min, max );
  11314.             arrString.PushBack( FloatToString( CalculateAttributeValue(min) * 100 ) );
  11315.             arrString.PushBack( FloatToString( CalculateAttributeValue(min) * 100 * GetSetPartsEquipped( EIST_Viper ) ) );
  11316.             finalString = GetLocStringByKeyExtWithParams( tempString,,,arrString );
  11317.             break;
  11318.         case EISB_KaerMorhen:
  11319.             dm.GetAbilityAttributeValue( 'KaerMorhenSetBonusEffect', 'staminaRegen', min, max );
  11320.             tmpVal = CalculateAttributeValue(min);
  11321.             arrString.PushBack( FloatToString( tmpVal ) );
  11322.             dm.GetAbilityAttributeValue( 'KaerMorhenSetBonusEffect', 'maxStacks', min, max );
  11323.             arrString.PushBack( FloatToString( tmpVal * CalculateAttributeValue(min) ) );
  11324.             finalString = GetLocStringByKeyExtWithParams( tempString,,,arrString );
  11325.             break;
  11326.         default:
  11327.             finalString = GetLocStringByKeyExtWithParams( tempString );
  11328.         }
  11329.        
  11330.         return finalString;
  11331.     }
  11332.    
  11333.     public function ManageSetBonusesSoundbanks( setType : EItemSetType )
  11334.     {
  11335.         //modSigns
  11336.         if( GetSetPartsEquipped(setType) >= GetNumItemsRequiredForSetActivation(setType) )
  11337.         {
  11338.             switch( setType )
  11339.             {
  11340.                 case EIST_Lynx:
  11341.                     LoadSetBonusSoundBank( "ep2_setbonus_lynx.bnk" );
  11342.                     break;
  11343.                 case EIST_Gryphon:
  11344.                     LoadSetBonusSoundBank( "ep2_setbonus_gryphon.bnk" );
  11345.                     break;
  11346.                 case EIST_Bear:
  11347.                     LoadSetBonusSoundBank( "ep2_setbonus_bear.bnk" );
  11348.                     break;
  11349.             }
  11350.         }
  11351.         else
  11352.         {
  11353.             switch( setType )
  11354.             {
  11355.                 case EIST_Lynx:
  11356.                     UnloadSetBonusSoundBank( "ep2_setbonus_lynx.bnk" );
  11357.                     break;
  11358.                 case EIST_Gryphon:
  11359.                     UnloadSetBonusSoundBank( "ep2_setbonus_gryphon.bnk" );
  11360.                     break;
  11361.                 case EIST_Bear:
  11362.                     UnloadSetBonusSoundBank( "ep2_setbonus_bear.bnk" );
  11363.                     break;
  11364.             }
  11365.         }
  11366.     }
  11367.    
  11368.     public function VampiricSetAbilityRegeneration()
  11369.     {
  11370.         var healthMax       : float;
  11371.         var healthToReg     : float;
  11372.        
  11373.         healthMax = GetStatMax( BCS_Vitality );
  11374.        
  11375.         healthToReg = ( GetSetPartsEquipped(EIST_Vampire) * healthMax ) / 100;
  11376.        
  11377.         PlayEffect('drain_energy_caretaker_shovel');
  11378.         GainStat( BCS_Vitality, healthToReg );
  11379.     }
  11380.    
  11381.     private function LoadSetBonusSoundBank( bankName : string )
  11382.     {
  11383.         if( !theSound.SoundIsBankLoaded( bankName ) )
  11384.         {
  11385.             theSound.SoundLoadBank( bankName, true );
  11386.         }
  11387.     }
  11388.    
  11389.     private function UnloadSetBonusSoundBank( bankName : string )
  11390.     {
  11391.         if( theSound.SoundIsBankLoaded( bankName ) )
  11392.         {
  11393.             theSound.SoundUnloadBank( bankName );
  11394.         }
  11395.     }
  11396.    
  11397.     timer function BearSetBonusQuenReapply( dt : float, id : int )
  11398.     {
  11399.         var newQuen     : W3QuenEntity;
  11400.        
  11401.         newQuen = (W3QuenEntity)theGame.CreateEntity( GetSignTemplate( ST_Quen ), GetWorldPosition(), GetWorldRotation() );
  11402.         newQuen.Init( signOwner, GetSignEntity( ST_Quen ), true );
  11403.         newQuen.freeCast = true; //modSigns
  11404.         newQuen.OnStarted();
  11405.         newQuen.OnThrowing();
  11406.         newQuen.OnEnded();
  11407.        
  11408.         m_quenReappliedCount += 1;
  11409.        
  11410.         RemoveTimer( 'BearSetBonusQuenReapply');
  11411.     }
  11412.    
  11413.     //modSigns: gryphon set tier 1 bonus
  11414.     public function GetGryphonSetSignPowerBonus(signT : ESignType) : float
  11415.     {
  11416.         var buff        : W3Effect_GryphonSetBonus;
  11417.         var abl         : SAbilityAttributeValue;
  11418.         var bonus       : float;
  11419.        
  11420.         //theGame.witcherLog.AddMessage("sign type: " + signT);
  11421.  
  11422.         if( !HasBuff( EET_GryphonSetBonus ) || signT == ST_None )
  11423.             return 0.0f;
  11424.            
  11425.         buff = (W3Effect_GryphonSetBonus)GetBuff( EET_GryphonSetBonus );
  11426.        
  11427.         //theGame.witcherLog.AddMessage("source: " + buff.GetSourceName());
  11428.  
  11429.         if( buff.GetSourceName() == ("" + signT) )
  11430.             return 0.0f;
  11431.  
  11432.         abl = GetAttributeValue( 'gryphon_sign_power_boost' );
  11433.         bonus = abl.valueAdditive * GetSetPartsEquipped( EIST_Gryphon );
  11434.        
  11435.         //theGame.witcherLog.AddMessage("sign power bonus: " + bonus);
  11436.        
  11437.         return bonus;
  11438.     }
  11439.    
  11440.     //modSigns: griffin school perk bonus
  11441.     public function GetPerk6StaminaCostReduction() : float
  11442.     {
  11443.         var abl         : SAbilityAttributeValue;
  11444.         var bonus       : float;
  11445.        
  11446.         abl = GetAttributeValue('perk_6_stamina_cost_reduction');
  11447.         bonus = abl.valueMultiplicative;
  11448.         bonus = ClampF(bonus, 0, 1);
  11449.        
  11450.         //theGame.witcherLog.AddMessage("stamina reduction bonus: " + bonus);
  11451.        
  11452.         return bonus;
  11453.     }
  11454.    
  11455.     //modSigns
  11456.     timer function GiveStandAloneEP1Items(dt : float, timerId : int)
  11457.     {
  11458.         var items : array<SItemUniqueId>;
  11459.        
  11460.         if( inv )
  11461.         {          
  11462.             inv.GetAllItems(items);
  11463.             if( items.Size() <= 0 )
  11464.                 return;
  11465.         }
  11466.         else
  11467.             return;
  11468.        
  11469.         StandaloneEp1_1();
  11470.        
  11471.         FactsAdd("standalone_ep1_inv", 1);
  11472.            
  11473.         RemoveTimer('GiveStandAloneEP1Items');
  11474.     }
  11475.    
  11476.     //modSigns
  11477.     timer function GiveStandAloneEP2Items(dt : float, timerId : int)
  11478.     {
  11479.         var items : array<SItemUniqueId>;
  11480.        
  11481.         if( inv )
  11482.         {          
  11483.             inv.GetAllItems(items);
  11484.             if( items.Size() <= 0 )
  11485.                 return;
  11486.         }
  11487.         else
  11488.             return;
  11489.        
  11490.         StandaloneEp2_1();
  11491.        
  11492.         FactsAdd("standalone_ep2_inv", 1);
  11493.            
  11494.         RemoveTimer('GiveStandAloneEP2Items');
  11495.     }
  11496.    
  11497.     public final function StandaloneEp1_1()
  11498.     {
  11499.         var i, inc, quantityLow, randLow, quantityMedium, randMedium, quantityHigh, randHigh, startingMoney : int;
  11500.         var pam : W3PlayerAbilityManager;
  11501.         var ids : array<SItemUniqueId>;
  11502.         var STARTING_LEVEL : int;
  11503.        
  11504.         FactsAdd("StandAloneEP1", 1);
  11505.        
  11506.        
  11507.         inv.RemoveAllItems();
  11508.        
  11509.        
  11510.         inv.AddAnItem('Illusion Medallion', 1, true, true, false);
  11511.         inv.AddAnItem('q103_safe_conduct', 1, true, true, false);
  11512.        
  11513.        
  11514.         theGame.GetGamerProfile().ClearAllAchievementsForEP1();
  11515.        
  11516.        
  11517.         STARTING_LEVEL = 32;
  11518.         inc = STARTING_LEVEL - GetLevel();
  11519.         for(i=0; i<inc; i+=1)
  11520.         {
  11521.             levelManager.AddPoints(EExperiencePoint, levelManager.GetTotalExpForNextLevel() - levelManager.GetPointsTotal(EExperiencePoint), false);
  11522.         }
  11523.        
  11524.        
  11525.         levelManager.ResetCharacterDev();
  11526.         pam = (W3PlayerAbilityManager)abilityManager;
  11527.         if(pam)
  11528.         {
  11529.             pam.ResetCharacterDev();
  11530.         }
  11531.         levelManager.SetFreeSkillPoints(levelManager.GetLevel() - 1 + 11); 
  11532.        
  11533.        
  11534.         //modSigns
  11535.         inv.AddAnItem('Greater mutagen red', 1);
  11536.         inv.AddAnItem('Greater mutagen green', 1);
  11537.         inv.AddAnItem('Greater mutagen blue', 1);
  11538.         inv.AddAnItem('Mutagen red', 2);
  11539.         inv.AddAnItem('Mutagen green', 2);
  11540.         inv.AddAnItem('Mutagen blue', 2);
  11541.         inv.AddAnItem('Lesser mutagen red', 2);
  11542.         inv.AddAnItem('Lesser mutagen green', 2);
  11543.         inv.AddAnItem('Lesser mutagen blue', 2);
  11544.        
  11545.        
  11546.         startingMoney = 4000;
  11547.         if(GetMoney() > startingMoney)
  11548.         {
  11549.             RemoveMoney(GetMoney() - startingMoney);
  11550.         }
  11551.         else
  11552.         {
  11553.             AddMoney( 4000 - GetMoney() );
  11554.         }
  11555.        
  11556.        
  11557.        
  11558.        
  11559.        
  11560.         ids.Clear();
  11561.         ids = inv.AddAnItem('EP1 Standalone Starting Armor');
  11562.         EquipItem(ids[0]);
  11563.         ids.Clear();
  11564.         ids = inv.AddAnItem('EP1 Standalone Starting Boots');
  11565.         EquipItem(ids[0]);
  11566.         ids.Clear();
  11567.         ids = inv.AddAnItem('EP1 Standalone Starting Gloves');
  11568.         EquipItem(ids[0]);
  11569.         ids.Clear();
  11570.         ids = inv.AddAnItem('EP1 Standalone Starting Pants');
  11571.         EquipItem(ids[0]);
  11572.        
  11573.        
  11574.         ids.Clear();
  11575.         ids = inv.AddAnItem('EP1 Standalone Starting Steel Sword');
  11576.         EquipItem(ids[0]);
  11577.         ids.Clear();
  11578.         ids = inv.AddAnItem('EP1 Standalone Starting Silver Sword');
  11579.         EquipItem(ids[0]);
  11580.        
  11581.        
  11582.         inv.AddAnItem('Torch', 1, true, true, false);
  11583.        
  11584.        
  11585.         //modSigns
  11586.         quantityLow = 1;
  11587.         randLow = 2;
  11588.         quantityMedium = 2;
  11589.         randMedium = 2;
  11590.         quantityHigh = 3;
  11591.         randHigh = 2;
  11592.        
  11593.         inv.AddAnItem('Alghoul bone marrow',quantityMedium+RandRange(randMedium));
  11594.         inv.AddAnItem('Amethyst dust',quantityLow+RandRange(randLow));
  11595.         inv.AddAnItem('Arachas eyes',quantityLow+RandRange(randLow));
  11596.         inv.AddAnItem('Arachas venom',quantityLow+RandRange(randLow));
  11597.         inv.AddAnItem('Basilisk hide',quantityLow+RandRange(randLow));
  11598.         inv.AddAnItem('Basilisk venom',quantityLow+RandRange(randLow));
  11599.         inv.AddAnItem('Berserker pelt',quantityLow+RandRange(randLow));
  11600.         inv.AddAnItem('Coal',quantityHigh+RandRange(randHigh));
  11601.         inv.AddAnItem('Cotton',quantityHigh+RandRange(randHigh));
  11602.         inv.AddAnItem('Dark iron ingot',quantityLow+RandRange(randLow));
  11603.         inv.AddAnItem('Dark iron ore',quantityLow+RandRange(randLow));
  11604.         inv.AddAnItem('Diamond dust',quantityLow+RandRange(randLow));
  11605.         inv.AddAnItem('Draconide leather',quantityLow+RandRange(randLow));
  11606.         inv.AddAnItem('Drowned dead tongue',quantityLow+RandRange(randLow));
  11607.         inv.AddAnItem('Drowner brain',quantityMedium+RandRange(randMedium));
  11608.         inv.AddAnItem('Dwimeryte ingot',quantityLow+RandRange(randLow));
  11609.         inv.AddAnItem('Dwimeryte ore',quantityLow+RandRange(randLow));
  11610.         inv.AddAnItem('Emerald dust',quantityLow+RandRange(randLow));
  11611.         inv.AddAnItem('Endriag chitin plates',quantityMedium+RandRange(randMedium));
  11612.         inv.AddAnItem('Endriag embryo',quantityLow+RandRange(randLow));
  11613.         inv.AddAnItem('Ghoul blood',quantityMedium+RandRange(randMedium));
  11614.         inv.AddAnItem('Hag teeth',quantityMedium+RandRange(randMedium));
  11615.         inv.AddAnItem('Hardened leather',quantityMedium+RandRange(randMedium));
  11616.         inv.AddAnItem('Hardened timber',quantityMedium+RandRange(randMedium));
  11617.         inv.AddAnItem('Harpy feathers',quantityMedium+RandRange(randMedium));
  11618.         inv.AddAnItem('Iron ore',quantityHigh+RandRange(randHigh));
  11619.         inv.AddAnItem('Leather straps',quantityHigh+RandRange(randHigh));
  11620.         inv.AddAnItem('Leather',quantityHigh+RandRange(randHigh));
  11621.         inv.AddAnItem('Linen',quantityMedium+RandRange(randMedium));
  11622.         inv.AddAnItem('Meteorite ingot',quantityLow+RandRange(randLow));
  11623.         inv.AddAnItem('Meteorite ore',quantityMedium+RandRange(randMedium));
  11624.         inv.AddAnItem('Necrophage skin',quantityLow+RandRange(randLow));
  11625.         inv.AddAnItem('Nekker blood',quantityHigh+RandRange(randHigh));
  11626.         inv.AddAnItem('Nekker heart',quantityMedium+RandRange(randMedium));
  11627.         inv.AddAnItem('Oil',quantityHigh+RandRange(randHigh));
  11628.         inv.AddAnItem('Phosphorescent crystal',quantityLow+RandRange(randLow));
  11629.         inv.AddAnItem('Pure silver',quantityMedium+RandRange(randMedium));
  11630.         inv.AddAnItem('Rotfiend blood',quantityMedium+RandRange(randMedium));
  11631.         inv.AddAnItem('Sapphire dust',quantityLow+RandRange(randLow));
  11632.         inv.AddAnItem('Silk',quantityHigh+RandRange(randHigh));
  11633.         inv.AddAnItem('Silver ingot',quantityMedium+RandRange(randMedium));
  11634.         inv.AddAnItem('Silver ore',quantityHigh+RandRange(randHigh));
  11635.         inv.AddAnItem('Specter dust',quantityMedium+RandRange(randMedium));
  11636.         inv.AddAnItem('Steel ingot',quantityHigh+RandRange(randHigh));
  11637.         inv.AddAnItem('String',quantityHigh+RandRange(randHigh));
  11638.         inv.AddAnItem('Thread',quantityHigh+RandRange(randHigh));
  11639.         inv.AddAnItem('Timber',quantityHigh+RandRange(randHigh));
  11640.         inv.AddAnItem('Twine',quantityMedium+RandRange(randMedium));
  11641.         inv.AddAnItem('Venom extract',quantityMedium+RandRange(randMedium));
  11642.         inv.AddAnItem('Water essence',quantityMedium+RandRange(randMedium));
  11643.         inv.AddAnItem('Wolf liver',quantityHigh+RandRange(randHigh));
  11644.         inv.AddAnItem('Alcohest', 3);
  11645.         inv.AddAnItem('Dwarven spirit', 4);
  11646.    
  11647.        
  11648.         ids.Clear();
  11649.         ids = inv.AddAnItem('Crossbow 5');
  11650.         EquipItem(ids[0]);
  11651.         ids.Clear();
  11652.         ids = inv.AddAnItem('Blunt Bolt', 20);
  11653.         EquipItem(ids[0]);
  11654.         inv.AddAnItem('Broadhead Bolt', 20);
  11655.         inv.AddAnItem('Split Bolt', 20);
  11656.        
  11657.        
  11658.         RemoveAllAlchemyRecipes();
  11659.         RemoveAllCraftingSchematics();
  11660.        
  11661.        
  11662.        
  11663.        
  11664.         AddAlchemyRecipe('Recipe for Cat 1');
  11665.        
  11666.        
  11667.        
  11668.         AddAlchemyRecipe('Recipe for Maribor Forest 1');
  11669.         AddAlchemyRecipe('Recipe for Petris Philtre 1');
  11670.         AddAlchemyRecipe('Recipe for Swallow 1');
  11671.         AddAlchemyRecipe('Recipe for Tawny Owl 1');
  11672.        
  11673.         AddAlchemyRecipe('Recipe for White Gull 1');
  11674.         AddAlchemyRecipe('Recipe for White Honey 1');
  11675.         AddAlchemyRecipe('Recipe for White Raffards Decoction 1');
  11676.        
  11677.        
  11678.        
  11679.         AddAlchemyRecipe('Recipe for Beast Oil 1');
  11680.         AddAlchemyRecipe('Recipe for Cursed Oil 1');
  11681.         AddAlchemyRecipe('Recipe for Hanged Man Venom 1');
  11682.         AddAlchemyRecipe('Recipe for Hybrid Oil 1');
  11683.         AddAlchemyRecipe('Recipe for Insectoid Oil 1');
  11684.         AddAlchemyRecipe('Recipe for Magicals Oil 1');
  11685.         AddAlchemyRecipe('Recipe for Necrophage Oil 1');
  11686.         AddAlchemyRecipe('Recipe for Specter Oil 1');
  11687.         AddAlchemyRecipe('Recipe for Vampire Oil 1');
  11688.         AddAlchemyRecipe('Recipe for Draconide Oil 1');
  11689.         AddAlchemyRecipe('Recipe for Ogre Oil 1');
  11690.         AddAlchemyRecipe('Recipe for Relic Oil 1');
  11691.         AddAlchemyRecipe('Recipe for Beast Oil 2');
  11692.         AddAlchemyRecipe('Recipe for Cursed Oil 2');
  11693.         AddAlchemyRecipe('Recipe for Hanged Man Venom 2');
  11694.         AddAlchemyRecipe('Recipe for Hybrid Oil 2');
  11695.         AddAlchemyRecipe('Recipe for Insectoid Oil 2');
  11696.         AddAlchemyRecipe('Recipe for Magicals Oil 2');
  11697.         AddAlchemyRecipe('Recipe for Necrophage Oil 2');
  11698.         AddAlchemyRecipe('Recipe for Specter Oil 2');
  11699.         AddAlchemyRecipe('Recipe for Vampire Oil 2');
  11700.         AddAlchemyRecipe('Recipe for Draconide Oil 2');
  11701.         AddAlchemyRecipe('Recipe for Ogre Oil 2');
  11702.         AddAlchemyRecipe('Recipe for Relic Oil 2');
  11703.        
  11704.        
  11705.         AddAlchemyRecipe('Recipe for Dancing Star 1');
  11706.        
  11707.         AddAlchemyRecipe('Recipe for Dwimeritum Bomb 1');
  11708.        
  11709.         AddAlchemyRecipe('Recipe for Grapeshot 1');
  11710.         AddAlchemyRecipe('Recipe for Samum 1');
  11711.        
  11712.         AddAlchemyRecipe('Recipe for White Frost 1');
  11713.        
  11714.        
  11715.        
  11716.         AddAlchemyRecipe('Recipe for Dwarven spirit 1');
  11717.         AddAlchemyRecipe('Recipe for Alcohest 1');
  11718.         AddAlchemyRecipe('Recipe for White Gull 1');
  11719.        
  11720.        
  11721.         AddStartingSchematics();
  11722.        
  11723.        
  11724.         ids.Clear();
  11725.         ids = inv.AddAnItem('Swallow 2');
  11726.         EquipItem(ids[0]);
  11727.         ids.Clear();
  11728.         ids = inv.AddAnItem('Thunderbolt 2');
  11729.         EquipItem(ids[0]);
  11730.         ids.Clear();
  11731.         ids = inv.AddAnItem('Tawny Owl 2');
  11732.         EquipItem(ids[0]);
  11733.         ids.Clear();
  11734.        
  11735.         ids = inv.AddAnItem('Grapeshot 2');
  11736.         EquipItem(ids[0]);
  11737.         ids.Clear();
  11738.         ids = inv.AddAnItem('Samum 2');
  11739.         EquipItem(ids[0]);
  11740.        
  11741.         inv.AddAnItem('Dwimeritum Bomb 1');
  11742.         inv.AddAnItem('Dragons Dream 1');
  11743.         inv.AddAnItem('Silver Dust Bomb 1');
  11744.         inv.AddAnItem('White Frost 2');
  11745.         inv.AddAnItem('Devils Puffball 2');
  11746.         inv.AddAnItem('Dancing Star 2');
  11747.         inv.AddAnItem('Beast Oil 1');
  11748.         inv.AddAnItem('Cursed Oil 1');
  11749.         inv.AddAnItem('Hanged Man Venom 2');
  11750.         inv.AddAnItem('Hybrid Oil 1');
  11751.         inv.AddAnItem('Insectoid Oil 1');
  11752.         inv.AddAnItem('Magicals Oil 1');
  11753.         inv.AddAnItem('Necrophage Oil 2');
  11754.         inv.AddAnItem('Specter Oil 1');
  11755.         inv.AddAnItem('Vampire Oil 1');
  11756.         inv.AddAnItem('Draconide Oil 1');
  11757.         inv.AddAnItem('Relic Oil 1');
  11758.         inv.AddAnItem('Black Blood 1');
  11759.         inv.AddAnItem('Blizzard 1');
  11760.         inv.AddAnItem('Cat 2');
  11761.         inv.AddAnItem('Full Moon 1');
  11762.         inv.AddAnItem('Maribor Forest 1');
  11763.         inv.AddAnItem('Petris Philtre 1');
  11764.         inv.AddAnItem('White Gull 1', 2);
  11765.         inv.AddAnItem('White Honey 2');
  11766.         inv.AddAnItem('White Raffards Decoction 1');
  11767.        
  11768.        
  11769.         inv.AddAnItem('Mutagen 17');   
  11770.         inv.AddAnItem('Mutagen 19');   
  11771.         inv.AddAnItem('Mutagen 27');   
  11772.         inv.AddAnItem('Mutagen 26');   
  11773.        
  11774.        
  11775.         inv.AddAnItem('weapon_repair_kit_1', 3);
  11776.         inv.AddAnItem('weapon_repair_kit_2', 2);
  11777.         inv.AddAnItem('armor_repair_kit_1', 3);
  11778.         inv.AddAnItem('armor_repair_kit_2', 2);
  11779.        
  11780.        
  11781.         quantityMedium = 1;
  11782.         quantityLow = 1;
  11783.         inv.AddAnItem('Rune stribog lesser', quantityMedium);
  11784.         inv.AddAnItem('Rune stribog', quantityLow);
  11785.         inv.AddAnItem('Rune dazhbog lesser', quantityMedium);
  11786.         inv.AddAnItem('Rune dazhbog', quantityLow);
  11787.         inv.AddAnItem('Rune devana lesser', quantityMedium);
  11788.         inv.AddAnItem('Rune devana', quantityLow);
  11789.         inv.AddAnItem('Rune zoria lesser', quantityMedium);
  11790.         inv.AddAnItem('Rune zoria', quantityLow);
  11791.         inv.AddAnItem('Rune morana lesser', quantityMedium);
  11792.         inv.AddAnItem('Rune morana', quantityLow);
  11793.         inv.AddAnItem('Rune triglav lesser', quantityMedium);
  11794.         inv.AddAnItem('Rune triglav', quantityLow);
  11795.         inv.AddAnItem('Rune svarog lesser', quantityMedium);
  11796.         inv.AddAnItem('Rune svarog', quantityLow);
  11797.         inv.AddAnItem('Rune veles lesser', quantityMedium);
  11798.         inv.AddAnItem('Rune veles', quantityLow);
  11799.         inv.AddAnItem('Rune perun lesser', quantityMedium);
  11800.         inv.AddAnItem('Rune perun', quantityLow);
  11801.         inv.AddAnItem('Rune elemental lesser', quantityMedium);
  11802.         inv.AddAnItem('Rune elemental', quantityLow);
  11803.        
  11804.         inv.AddAnItem('Glyph aard lesser', quantityMedium);
  11805.         inv.AddAnItem('Glyph aard', quantityLow);
  11806.         inv.AddAnItem('Glyph axii lesser', quantityMedium);
  11807.         inv.AddAnItem('Glyph axii', quantityLow);
  11808.         inv.AddAnItem('Glyph igni lesser', quantityMedium);
  11809.         inv.AddAnItem('Glyph igni', quantityLow);
  11810.         inv.AddAnItem('Glyph quen lesser', quantityMedium);
  11811.         inv.AddAnItem('Glyph quen', quantityLow);
  11812.         inv.AddAnItem('Glyph yrden lesser', quantityMedium);
  11813.         inv.AddAnItem('Glyph yrden', quantityLow);
  11814.        
  11815.        
  11816.         StandaloneEp1_2();
  11817.     }
  11818.    
  11819.     public final function StandaloneEp1_2()
  11820.     {
  11821.         var horseId : SItemUniqueId;
  11822.         var ids : array<SItemUniqueId>;
  11823.         var ents : array< CJournalBase >;
  11824.         var i : int;
  11825.         var manager : CWitcherJournalManager;
  11826.        
  11827.        
  11828.         inv.AddAnItem( 'Cows milk', 5 );
  11829.         ids.Clear();
  11830.         ids = inv.AddAnItem( 'Dumpling', 5 );
  11831.         EquipItem(ids[0]);
  11832.        
  11833.        
  11834.         inv.AddAnItem('Clearing Potion', 2, true, false, false);
  11835.        
  11836.        
  11837.         GetHorseManager().RemoveAllItems();
  11838.        
  11839.         ids.Clear();
  11840.         ids = inv.AddAnItem('Horse Bag 2');
  11841.         horseId = GetHorseManager().MoveItemToHorse(ids[0]);
  11842.         GetHorseManager().EquipItem(horseId);
  11843.        
  11844.         ids.Clear();
  11845.         ids = inv.AddAnItem('Horse Blinder 2');
  11846.         horseId = GetHorseManager().MoveItemToHorse(ids[0]);
  11847.         GetHorseManager().EquipItem(horseId);
  11848.        
  11849.         ids.Clear();
  11850.         ids = inv.AddAnItem('Horse Saddle 2');
  11851.         horseId = GetHorseManager().MoveItemToHorse(ids[0]);
  11852.         GetHorseManager().EquipItem(horseId);
  11853.        
  11854.         manager = theGame.GetJournalManager();
  11855.  
  11856.        
  11857.         manager.GetActivatedOfType( 'CJournalCreature', ents );
  11858.         for(i=0; i<ents.Size(); i+=1)
  11859.         {
  11860.             manager.ActivateEntry(ents[i], JS_Inactive, false, true);
  11861.         }
  11862.        
  11863.        
  11864.         ents.Clear();
  11865.         manager.GetActivatedOfType( 'CJournalCharacter', ents );
  11866.         for(i=0; i<ents.Size(); i+=1)
  11867.         {
  11868.             manager.ActivateEntry(ents[i], JS_Inactive, false, true);
  11869.         }
  11870.        
  11871.        
  11872.         ents.Clear();
  11873.         manager.GetActivatedOfType( 'CJournalQuest', ents );
  11874.         for(i=0; i<ents.Size(); i+=1)
  11875.         {
  11876.            
  11877.             if( StrStartsWith(ents[i].baseName, "q60"))
  11878.                 continue;
  11879.                
  11880.             manager.ActivateEntry(ents[i], JS_Inactive, false, true);
  11881.         }
  11882.        
  11883.        
  11884.         manager.ActivateEntryByScriptTag('TutorialAard', JS_Active);
  11885.         manager.ActivateEntryByScriptTag('TutorialAdrenaline', JS_Active);
  11886.         manager.ActivateEntryByScriptTag('TutorialAxii', JS_Active);
  11887.         manager.ActivateEntryByScriptTag('TutorialAxiiDialog', JS_Active);
  11888.         manager.ActivateEntryByScriptTag('TutorialCamera', JS_Active);
  11889.         manager.ActivateEntryByScriptTag('TutorialCamera_pad', JS_Active);
  11890.         manager.ActivateEntryByScriptTag('TutorialCiriBlink', JS_Active);
  11891.         manager.ActivateEntryByScriptTag('TutorialCiriCharge', JS_Active);
  11892.         manager.ActivateEntryByScriptTag('TutorialCiriStamina', JS_Active);
  11893.         manager.ActivateEntryByScriptTag('TutorialCounter', JS_Active);
  11894.         manager.ActivateEntryByScriptTag('TutorialDialogClose', JS_Active);
  11895.         manager.ActivateEntryByScriptTag('TutorialFallingRoll', JS_Active);
  11896.         manager.ActivateEntryByScriptTag('TutorialFocus', JS_Active);
  11897.         manager.ActivateEntryByScriptTag('TutorialFocusClues', JS_Active);
  11898.         manager.ActivateEntryByScriptTag('TutorialFocusClues', JS_Active);
  11899.         manager.ActivateEntryByScriptTag('TutorialHorseRoad', JS_Active);
  11900.         manager.ActivateEntryByScriptTag('TutorialHorseSpeed0', JS_Active);
  11901.         manager.ActivateEntryByScriptTag('TutorialHorseSpeed0_pad', JS_Active);
  11902.         manager.ActivateEntryByScriptTag('TutorialHorseSpeed1', JS_Active);
  11903.         manager.ActivateEntryByScriptTag('TutorialHorseSpeed2', JS_Active);
  11904.         manager.ActivateEntryByScriptTag('TutorialHorseSummon', JS_Active);
  11905.         manager.ActivateEntryByScriptTag('TutorialHorseSummon_pad', JS_Active);
  11906.         manager.ActivateEntryByScriptTag('TutorialIgni', JS_Active);
  11907.         manager.ActivateEntryByScriptTag('TutorialJournalAlternateSings', JS_Active);
  11908.         manager.ActivateEntryByScriptTag('TutorialJournalBoatDamage', JS_Active);
  11909.         manager.ActivateEntryByScriptTag('TutorialJournalBoatMount', JS_Active);
  11910.         manager.ActivateEntryByScriptTag('TutorialJournalBuffs', JS_Active);
  11911.         manager.ActivateEntryByScriptTag('TutorialJournalCharDevLeveling', JS_Active);
  11912.         manager.ActivateEntryByScriptTag('TutorialJournalCharDevSkills', JS_Active);
  11913.         manager.ActivateEntryByScriptTag('TutorialJournalCrafting', JS_Active);
  11914.         manager.ActivateEntryByScriptTag('TutorialJournalCrossbow', JS_Active);
  11915.         manager.ActivateEntryByScriptTag('TutorialJournalDialogGwint', JS_Active);
  11916.         manager.ActivateEntryByScriptTag('TutorialJournalDialogShop', JS_Active);
  11917.         manager.ActivateEntryByScriptTag('TutorialJournalDive', JS_Active);
  11918.         manager.ActivateEntryByScriptTag('TutorialJournalDodge', JS_Active);
  11919.         manager.ActivateEntryByScriptTag('TutorialJournalDodge_pad', JS_Active);
  11920.         manager.ActivateEntryByScriptTag('TutorialJournalDrawWeapon', JS_Active);
  11921.         manager.ActivateEntryByScriptTag('TutorialJournalDrawWeapon_pad', JS_Active);
  11922.         manager.ActivateEntryByScriptTag('TutorialJournalDurability', JS_Active);
  11923.         manager.ActivateEntryByScriptTag('TutorialJournalExplorations', JS_Active);
  11924.         manager.ActivateEntryByScriptTag('TutorialJournalExplorations_pad', JS_Active);
  11925.         manager.ActivateEntryByScriptTag('TutorialJournalFastTravel', JS_Active);
  11926.         manager.ActivateEntryByScriptTag('TutorialJournalFocusRedObjects', JS_Active);
  11927.         manager.ActivateEntryByScriptTag('TutorialJournalGasClouds', JS_Active);
  11928.         manager.ActivateEntryByScriptTag('TutorialJournalHeavyAttacks', JS_Active);
  11929.         manager.ActivateEntryByScriptTag('TutorialJournalHorse', JS_Active);
  11930.         manager.ActivateEntryByScriptTag('TutorialJournalHorseStamina', JS_Active);
  11931.         manager.ActivateEntryByScriptTag('TutorialJournalJump', JS_Active);
  11932.         manager.ActivateEntryByScriptTag('TutorialJournalLightAttacks', JS_Active);
  11933.         manager.ActivateEntryByScriptTag('TutorialJournalLightAttacks_pad', JS_Active);
  11934.         manager.ActivateEntryByScriptTag('TutorialJournalMeditation', JS_Active);
  11935.         manager.ActivateEntryByScriptTag('TutorialJournalMeditation_pad', JS_Active);
  11936.         manager.ActivateEntryByScriptTag('TutorialJournalMonsterThreatLevels', JS_Active);
  11937.         manager.ActivateEntryByScriptTag('TutorialJournalMovement', JS_Active);
  11938.         manager.ActivateEntryByScriptTag('TutorialJournalMovement_pad', JS_Active);
  11939.         manager.ActivateEntryByScriptTag('TutorialJournalMutagenIngredient', JS_Active);
  11940.         manager.ActivateEntryByScriptTag('TutorialJournalMutagenPotion', JS_Active);
  11941.         manager.ActivateEntryByScriptTag('TutorialJournalOils', JS_Active);
  11942.         manager.ActivateEntryByScriptTag('TutorialJournalPetards', JS_Active);
  11943.         manager.ActivateEntryByScriptTag('TutorialJournalPotions', JS_Active);
  11944.         manager.ActivateEntryByScriptTag('TutorialJournalPotions_pad', JS_Active);
  11945.         manager.ActivateEntryByScriptTag('TutorialJournalQuestArea', JS_Active);
  11946.         manager.ActivateEntryByScriptTag('TutorialJournalRadial', JS_Active);
  11947.         manager.ActivateEntryByScriptTag('TutorialJournalRifts', JS_Active);
  11948.         manager.ActivateEntryByScriptTag('TutorialJournalRun', JS_Active);
  11949.         manager.ActivateEntryByScriptTag('TutorialJournalShopDescription', JS_Active);
  11950.         manager.ActivateEntryByScriptTag('TutorialJournalSignCast', JS_Active);
  11951.         manager.ActivateEntryByScriptTag('TutorialJournalSignCast_pad', JS_Active);
  11952.         manager.ActivateEntryByScriptTag('TutorialJournalSpecialAttacks', JS_Active);
  11953.         manager.ActivateEntryByScriptTag('TutorialJournalStaminaExploration', JS_Active);
  11954.         manager.ActivateEntryByScriptTag('TutorialJumpHang', JS_Active);
  11955.         manager.ActivateEntryByScriptTag('TutorialLadder', JS_Active);
  11956.         manager.ActivateEntryByScriptTag('TutorialLadderMove', JS_Active);
  11957.         manager.ActivateEntryByScriptTag('TutorialLadderMove_pad', JS_Active);
  11958.         manager.ActivateEntryByScriptTag('TutorialObjectiveSwitching', JS_Active);
  11959.         manager.ActivateEntryByScriptTag('TutorialOxygen', JS_Active);
  11960.         manager.ActivateEntryByScriptTag('TutorialParry', JS_Active);
  11961.         manager.ActivateEntryByScriptTag('TutorialPOIUncovered', JS_Active);
  11962.         manager.ActivateEntryByScriptTag('TutorialQuen', JS_Active);
  11963.         manager.ActivateEntryByScriptTag('TutorialRoll', JS_Active);
  11964.         manager.ActivateEntryByScriptTag('TutorialRoll_pad', JS_Active);
  11965.         manager.ActivateEntryByScriptTag('TutorialSpeedPairing', JS_Active);
  11966.         manager.ActivateEntryByScriptTag('TutorialSprint', JS_Active);
  11967.         manager.ActivateEntryByScriptTag('TutorialStaminaSigns', JS_Active);
  11968.         manager.ActivateEntryByScriptTag('TutorialStealing', JS_Active);
  11969.         manager.ActivateEntryByScriptTag('TutorialSwimmingSpeed', JS_Active);
  11970.         manager.ActivateEntryByScriptTag('TutorialTimedChoiceDialog', JS_Active);
  11971.         manager.ActivateEntryByScriptTag('TutorialYrden', JS_Active);
  11972.        
  11973.        
  11974.         FactsAdd('kill_base_tutorials');
  11975.        
  11976.        
  11977.         theGame.GetTutorialSystem().RemoveAllQueuedTutorials();
  11978.        
  11979.         if( FactsQuerySum("standalone_ep1") < 1 ) //modSigns
  11980.             FactsAdd("standalone_ep1");
  11981.         FactsRemove("StandAloneEP1");
  11982.        
  11983.         theGame.GetJournalManager().ForceUntrackingQuestForEP1Savegame();
  11984.     }
  11985.    
  11986.     final function Debug_FocusBoyFocusGain()
  11987.     {
  11988.         var focusGain : float;
  11989.        
  11990.         focusGain = FactsQuerySum( "debug_fact_focus_boy" ) ;
  11991.         GainStat( BCS_Focus, focusGain );
  11992.     }
  11993.    
  11994.     public final function StandaloneEp2_1()
  11995.     {
  11996.         var i, inc, quantityLow, randLow, quantityMedium, randMedium, quantityHigh, randHigh, startingMoney : int;
  11997.         var pam : W3PlayerAbilityManager;
  11998.         var ids : array<SItemUniqueId>;
  11999.         var STARTING_LEVEL : int;
  12000.        
  12001.         FactsAdd( "StandAloneEP2", 1 );
  12002.        
  12003.        
  12004.         inv.RemoveAllItems();
  12005.        
  12006.        
  12007.         inv.AddAnItem( 'Illusion Medallion', 1, true, true, false );
  12008.         inv.AddAnItem( 'q103_safe_conduct', 1, true, true, false );
  12009.        
  12010.        
  12011.         theGame.GetGamerProfile().ClearAllAchievementsForEP2();
  12012.        
  12013.        
  12014.         levelManager.Hack_EP2StandaloneLevelShrink( 35 );
  12015.        
  12016.        
  12017.         levelManager.ResetCharacterDev();
  12018.         pam = ( W3PlayerAbilityManager )abilityManager;
  12019.         if( pam )
  12020.         {
  12021.             pam.ResetCharacterDev();
  12022.         }
  12023.         levelManager.SetFreeSkillPoints( levelManager.GetLevel() - 1 + 11 );   
  12024.        
  12025.        
  12026.         //modSigns
  12027.         inv.AddAnItem('Greater mutagen red', 1);
  12028.         inv.AddAnItem('Greater mutagen green', 1);
  12029.         inv.AddAnItem('Greater mutagen blue', 1);
  12030.         inv.AddAnItem('Mutagen red', 2);
  12031.         inv.AddAnItem('Mutagen green', 2);
  12032.         inv.AddAnItem('Mutagen blue', 2);
  12033.         inv.AddAnItem('Lesser mutagen red', 2);
  12034.         inv.AddAnItem('Lesser mutagen green', 2);
  12035.         inv.AddAnItem('Lesser mutagen blue', 2);
  12036.        
  12037.        
  12038.         startingMoney = 5000;
  12039.         if( GetMoney() > startingMoney )
  12040.         {
  12041.             RemoveMoney( GetMoney() - startingMoney );
  12042.         }
  12043.         else
  12044.         {
  12045.             AddMoney( 5000 - GetMoney() );
  12046.         }
  12047.        
  12048.        
  12049.         ids.Clear();
  12050.         ids = inv.AddAnItem( 'EP2 Standalone Starting Armor' );
  12051.         EquipItem( ids[0] );
  12052.         ids.Clear();
  12053.         ids = inv.AddAnItem( 'EP2 Standalone Starting Boots' );
  12054.         EquipItem( ids[0] );
  12055.         ids.Clear();
  12056.         ids = inv.AddAnItem( 'EP2 Standalone Starting Gloves' );
  12057.         EquipItem( ids[0] );
  12058.         ids.Clear();
  12059.         ids = inv.AddAnItem( 'EP2 Standalone Starting Pants' );
  12060.         EquipItem( ids[0] );
  12061.        
  12062.        
  12063.         ids.Clear();
  12064.         ids = inv.AddAnItem( 'EP2 Standalone Starting Steel Sword' );
  12065.         EquipItem( ids[0] );
  12066.         ids.Clear();
  12067.         ids = inv.AddAnItem( 'EP2 Standalone Starting Silver Sword' );
  12068.         EquipItem( ids[0] );
  12069.        
  12070.        
  12071.         inv.AddAnItem( 'Torch', 1, true, true, false );
  12072.        
  12073.        
  12074.         //modSigns
  12075.         quantityLow = 1;
  12076.         randLow = 2;
  12077.         quantityMedium = 2;
  12078.         randMedium = 2;
  12079.         quantityHigh = 3;
  12080.         randHigh = 2;
  12081.        
  12082.         inv.AddAnItem( 'Alghoul bone marrow',quantityMedium+RandRange( randMedium ) );
  12083.         inv.AddAnItem( 'Amethyst dust',quantityLow+RandRange( randLow ) );
  12084.         inv.AddAnItem( 'Arachas eyes',quantityLow+RandRange( randLow ) );
  12085.         inv.AddAnItem( 'Arachas venom',quantityLow+RandRange( randLow ) );
  12086.         inv.AddAnItem( 'Basilisk hide',quantityLow+RandRange( randLow ) );
  12087.         inv.AddAnItem( 'Basilisk venom',quantityLow+RandRange( randLow ) );
  12088.         inv.AddAnItem( 'Berserker pelt',quantityLow+RandRange( randLow ) );
  12089.         inv.AddAnItem( 'Coal',quantityHigh+RandRange( randHigh ) );
  12090.         inv.AddAnItem( 'Cotton',quantityHigh+RandRange( randHigh ) );
  12091.         inv.AddAnItem( 'Diamond dust',quantityLow+RandRange( randLow ) );
  12092.         inv.AddAnItem( 'Drowned dead tongue',quantityLow+RandRange( randLow ) );
  12093.         inv.AddAnItem( 'Drowner brain',quantityMedium+RandRange( randMedium ) );
  12094.         inv.AddAnItem( 'Endriag chitin plates',quantityMedium+RandRange( randMedium ) );
  12095.         inv.AddAnItem( 'Endriag embryo',quantityLow+RandRange( randLow ) );
  12096.         inv.AddAnItem( 'Ghoul blood',quantityMedium+RandRange( randMedium ) );
  12097.         inv.AddAnItem( 'Hag teeth',quantityMedium+RandRange( randMedium ) );
  12098.         inv.AddAnItem( 'Hardened leather',quantityMedium+RandRange( randMedium ) );
  12099.         inv.AddAnItem( 'Hardened timber',quantityMedium+RandRange( randMedium ) );
  12100.         inv.AddAnItem( 'Harpy feathers',quantityMedium+RandRange( randMedium ) );
  12101.         inv.AddAnItem( 'Necrophage skin',quantityLow+RandRange( randLow ) );
  12102.         inv.AddAnItem( 'Nekker blood',quantityHigh+RandRange( randHigh ) );
  12103.         inv.AddAnItem( 'Nekker heart',quantityMedium+RandRange( randMedium ) );
  12104.         inv.AddAnItem( 'Phosphorescent crystal',quantityLow+RandRange( randLow ) );
  12105.         inv.AddAnItem( 'Rotfiend blood',quantityMedium+RandRange( randMedium ) );
  12106.         inv.AddAnItem( 'Sapphire dust',quantityLow+RandRange( randLow ) );
  12107.         inv.AddAnItem( 'Specter dust',quantityMedium+RandRange( randMedium ) );
  12108.         inv.AddAnItem( 'Water essence',quantityMedium+RandRange( randMedium ) );
  12109.         inv.AddAnItem( 'Wolf liver',quantityHigh+RandRange( randHigh ) );
  12110.         inv.AddAnItem( 'Alcohest', 3 );
  12111.         inv.AddAnItem( 'Dwarven spirit', 4 );
  12112.    
  12113.        
  12114.         ids.Clear();
  12115.         ids = inv.AddAnItem( 'Crossbow 5' );
  12116.         EquipItem( ids[0] );
  12117.         ids.Clear();
  12118.         ids = inv.AddAnItem( 'Blunt Bolt', 20 );
  12119.         EquipItem( ids[0] );
  12120.         inv.AddAnItem( 'Broadhead Bolt', 20 );
  12121.         inv.AddAnItem( 'Split Bolt', 20 );
  12122.        
  12123.        
  12124.         RemoveAllAlchemyRecipes();
  12125.         RemoveAllCraftingSchematics();
  12126.        
  12127.        
  12128.        
  12129.        
  12130.        
  12131.        
  12132.        
  12133.        
  12134.        
  12135.         AddAlchemyRecipe( 'Recipe for Petris Philtre 2' );
  12136.         AddAlchemyRecipe( 'Recipe for Swallow 1' );
  12137.         AddAlchemyRecipe( 'Recipe for Tawny Owl 1' );
  12138.        
  12139.         AddAlchemyRecipe( 'Recipe for White Gull 1' );
  12140.        
  12141.        
  12142.        
  12143.        
  12144.        
  12145.         AddAlchemyRecipe( 'Recipe for Beast Oil 1' );
  12146.         AddAlchemyRecipe( 'Recipe for Cursed Oil 1' );
  12147.         AddAlchemyRecipe( 'Recipe for Hanged Man Venom 1' );
  12148.         AddAlchemyRecipe( 'Recipe for Hybrid Oil 1' );
  12149.         AddAlchemyRecipe( 'Recipe for Insectoid Oil 2' );
  12150.         AddAlchemyRecipe( 'Recipe for Magicals Oil 1' );
  12151.         AddAlchemyRecipe( 'Recipe for Necrophage Oil 1' );
  12152.         AddAlchemyRecipe( 'Recipe for Specter Oil 1' );
  12153.         AddAlchemyRecipe( 'Recipe for Vampire Oil 2' );
  12154.         AddAlchemyRecipe( 'Recipe for Draconide Oil 2' );
  12155.         AddAlchemyRecipe( 'Recipe for Ogre Oil 1' );
  12156.         AddAlchemyRecipe( 'Recipe for Relic Oil 1' );
  12157.         AddAlchemyRecipe( 'Recipe for Beast Oil 2' );
  12158.         AddAlchemyRecipe( 'Recipe for Cursed Oil 2' );
  12159.         AddAlchemyRecipe( 'Recipe for Hanged Man Venom 2' );
  12160.         AddAlchemyRecipe( 'Recipe for Hybrid Oil 2' );
  12161.         AddAlchemyRecipe( 'Recipe for Insectoid Oil 2' );
  12162.         AddAlchemyRecipe( 'Recipe for Magicals Oil 2' );
  12163.         AddAlchemyRecipe( 'Recipe for Necrophage Oil 2' );
  12164.         AddAlchemyRecipe( 'Recipe for Specter Oil 2' );
  12165.         AddAlchemyRecipe( 'Recipe for Vampire Oil 2' );
  12166.         AddAlchemyRecipe( 'Recipe for Draconide Oil 2' );
  12167.         AddAlchemyRecipe( 'Recipe for Ogre Oil 2' );
  12168.         AddAlchemyRecipe( 'Recipe for Relic Oil 2' );
  12169.        
  12170.        
  12171.         AddAlchemyRecipe( 'Recipe for Dancing Star 1' );
  12172.        
  12173.         AddAlchemyRecipe( 'Recipe for Dwimeritum Bomb 1' );
  12174.        
  12175.         AddAlchemyRecipe( 'Recipe for Grapeshot 1' );
  12176.         AddAlchemyRecipe( 'Recipe for Samum 1' );
  12177.        
  12178.         AddAlchemyRecipe( 'Recipe for White Frost 1' );
  12179.        
  12180.        
  12181.        
  12182.         AddAlchemyRecipe( 'Recipe for Dwarven spirit 1' );
  12183.         AddAlchemyRecipe( 'Recipe for Alcohest 1' );
  12184.         AddAlchemyRecipe( 'Recipe for White Gull 1' );
  12185.        
  12186.        
  12187.         AddStartingSchematics();
  12188.        
  12189.        
  12190.         ids.Clear();
  12191.         ids = inv.AddAnItem( 'Swallow 2' );
  12192.         EquipItem( ids[0] );
  12193.         ids.Clear();
  12194.         ids = inv.AddAnItem( 'Thunderbolt 2' );
  12195.         EquipItem( ids[0] );
  12196.         ids.Clear();
  12197.         ids = inv.AddAnItem( 'Tawny Owl 2' );
  12198.         EquipItem( ids[0] );
  12199.         ids.Clear();
  12200.        
  12201.         ids = inv.AddAnItem( 'Grapeshot 2' );
  12202.         EquipItem( ids[0] );
  12203.         ids.Clear();
  12204.         ids = inv.AddAnItem( 'Samum 2' );
  12205.         EquipItem( ids[0] );
  12206.        
  12207.         inv.AddAnItem( 'Dwimeritum Bomb 1' );
  12208.         inv.AddAnItem( 'Dragons Dream 1' );
  12209.         inv.AddAnItem( 'Silver Dust Bomb 1' );
  12210.         inv.AddAnItem( 'White Frost 2' );
  12211.         inv.AddAnItem( 'Devils Puffball 2' );
  12212.         inv.AddAnItem( 'Dancing Star 2' );
  12213.         inv.AddAnItem( 'Beast Oil 1' );
  12214.         inv.AddAnItem( 'Cursed Oil 1' );
  12215.         inv.AddAnItem( 'Hanged Man Venom 2' );
  12216.         inv.AddAnItem( 'Hybrid Oil 2' );
  12217.         inv.AddAnItem( 'Insectoid Oil 2' );
  12218.         inv.AddAnItem( 'Magicals Oil 1' );
  12219.         inv.AddAnItem( 'Necrophage Oil 2' );
  12220.         inv.AddAnItem( 'Ogre Oil 1' );
  12221.         inv.AddAnItem( 'Specter Oil 1' );
  12222.         inv.AddAnItem( 'Vampire Oil 2' );
  12223.         inv.AddAnItem( 'Draconide Oil 2' );
  12224.         inv.AddAnItem( 'Relic Oil 1' );
  12225.         inv.AddAnItem( 'Black Blood 1' );
  12226.         inv.AddAnItem( 'Blizzard 1' );
  12227.         inv.AddAnItem( 'Cat 2' );
  12228.         inv.AddAnItem( 'Full Moon 1' );
  12229.         inv.AddAnItem( 'Golden Oriole 1' );
  12230.         inv.AddAnItem( 'Killer Whale 1' );
  12231.         inv.AddAnItem( 'Maribor Forest 1' );
  12232.         inv.AddAnItem( 'Petris Philtre 2' );
  12233.         inv.AddAnItem( 'White Gull 1', 2 );
  12234.         inv.AddAnItem( 'White Honey 2' );
  12235.         inv.AddAnItem( 'White Raffards Decoction 1' );
  12236.        
  12237.        
  12238.         inv.AddAnItem( 'Mutagen 17' ); 
  12239.         inv.AddAnItem( 'Mutagen 19' ); 
  12240.         inv.AddAnItem( 'Mutagen 27' ); 
  12241.         inv.AddAnItem( 'Mutagen 26' ); 
  12242.        
  12243.        
  12244.         inv.AddAnItem( 'weapon_repair_kit_1', 3 );
  12245.         inv.AddAnItem( 'weapon_repair_kit_2', 2 );
  12246.         inv.AddAnItem( 'armor_repair_kit_1', 3 );
  12247.         inv.AddAnItem( 'armor_repair_kit_2', 2 );
  12248.        
  12249.        
  12250.         quantityMedium = 1;
  12251.         quantityLow = 1;
  12252.         inv.AddAnItem( 'Rune stribog lesser', quantityMedium );
  12253.         inv.AddAnItem( 'Rune stribog', quantityLow );
  12254.         inv.AddAnItem( 'Rune dazhbog lesser', quantityMedium );
  12255.         inv.AddAnItem( 'Rune dazhbog', quantityLow );
  12256.         inv.AddAnItem( 'Rune devana lesser', quantityMedium );
  12257.         inv.AddAnItem( 'Rune devana', quantityLow );
  12258.         inv.AddAnItem( 'Rune zoria lesser', quantityMedium );
  12259.         inv.AddAnItem( 'Rune zoria', quantityLow );
  12260.         inv.AddAnItem( 'Rune morana lesser', quantityMedium );
  12261.         inv.AddAnItem( 'Rune morana', quantityLow );
  12262.         inv.AddAnItem( 'Rune triglav lesser', quantityMedium );
  12263.         inv.AddAnItem( 'Rune triglav', quantityLow );
  12264.         inv.AddAnItem( 'Rune svarog lesser', quantityMedium );
  12265.         inv.AddAnItem( 'Rune svarog', quantityLow );
  12266.         inv.AddAnItem( 'Rune veles lesser', quantityMedium );
  12267.         inv.AddAnItem( 'Rune veles', quantityLow );
  12268.         inv.AddAnItem( 'Rune perun lesser', quantityMedium );
  12269.         inv.AddAnItem( 'Rune perun', quantityLow );
  12270.         inv.AddAnItem( 'Rune elemental lesser', quantityMedium );
  12271.         inv.AddAnItem( 'Rune elemental', quantityLow );
  12272.        
  12273.         inv.AddAnItem( 'Glyph aard lesser', quantityMedium );
  12274.         inv.AddAnItem( 'Glyph aard', quantityLow );
  12275.         inv.AddAnItem( 'Glyph axii lesser', quantityMedium );
  12276.         inv.AddAnItem( 'Glyph axii', quantityLow );
  12277.         inv.AddAnItem( 'Glyph igni lesser', quantityMedium );
  12278.         inv.AddAnItem( 'Glyph igni', quantityLow );
  12279.         inv.AddAnItem( 'Glyph quen lesser', quantityMedium );
  12280.         inv.AddAnItem( 'Glyph quen', quantityLow );
  12281.         inv.AddAnItem( 'Glyph yrden lesser', quantityMedium );
  12282.         inv.AddAnItem( 'Glyph yrden', quantityLow );
  12283.        
  12284.        
  12285.         StandaloneEp2_2();
  12286.     }
  12287.    
  12288.     public final function StandaloneEp2_2()
  12289.     {
  12290.         var horseId : SItemUniqueId;
  12291.         var ids : array<SItemUniqueId>;
  12292.         var ents : array< CJournalBase >;
  12293.         var i : int;
  12294.         var manager : CWitcherJournalManager;
  12295.        
  12296.        
  12297.         inv.AddAnItem( 'Cows milk', 5 );
  12298.         ids.Clear();
  12299.         ids = inv.AddAnItem( 'Dumpling', 5 );
  12300.         EquipItem( ids[0] );
  12301.        
  12302.        
  12303.         inv.AddAnItem( 'Clearing Potion', 2, true, false, false );
  12304.        
  12305.        
  12306.         GetHorseManager().RemoveAllItems();
  12307.        
  12308.         ids.Clear();
  12309.         ids = inv.AddAnItem( 'Horse Bag 2' );
  12310.         horseId = GetHorseManager( ).MoveItemToHorse( ids[0] );
  12311.         GetHorseManager().EquipItem( horseId );
  12312.        
  12313.         ids.Clear();
  12314.         ids = inv.AddAnItem( 'Horse Blinder 2' );
  12315.         horseId = GetHorseManager().MoveItemToHorse( ids[0] );
  12316.         GetHorseManager().EquipItem( horseId );
  12317.        
  12318.         ids.Clear();
  12319.         ids = inv.AddAnItem( 'Horse Saddle 2' );
  12320.         horseId = GetHorseManager().MoveItemToHorse( ids[0] );
  12321.         GetHorseManager().EquipItem( horseId );
  12322.        
  12323.         manager = theGame.GetJournalManager();
  12324.  
  12325.        
  12326.         manager.GetActivatedOfType( 'CJournalCreature', ents );
  12327.         for(i=0; i<ents.Size(); i+=1)
  12328.         {
  12329.             manager.ActivateEntry( ents[i], JS_Inactive, false, true );
  12330.         }
  12331.        
  12332.        
  12333.         ents.Clear();
  12334.         manager.GetActivatedOfType( 'CJournalCharacter', ents );
  12335.         for(i=0; i<ents.Size(); i+=1)
  12336.         {
  12337.             manager.ActivateEntry( ents[i], JS_Inactive, false, true );
  12338.         }
  12339.        
  12340.        
  12341.         ents.Clear();
  12342.         manager.GetActivatedOfType( 'CJournalQuest', ents );
  12343.         for(i=0; i<ents.Size(); i+=1)
  12344.         {
  12345.            
  12346.             if( StrStartsWith( ents[i].baseName, "q60" ) )
  12347.                 continue;
  12348.                
  12349.             manager.ActivateEntry( ents[i], JS_Inactive, false, true );
  12350.         }
  12351.        
  12352.        
  12353.         manager.ActivateEntryByScriptTag( 'TutorialAard', JS_Active );
  12354.         manager.ActivateEntryByScriptTag( 'TutorialAdrenaline', JS_Active );
  12355.         manager.ActivateEntryByScriptTag( 'TutorialAxii', JS_Active );
  12356.         manager.ActivateEntryByScriptTag( 'TutorialAxiiDialog', JS_Active );
  12357.         manager.ActivateEntryByScriptTag( 'TutorialCamera', JS_Active );
  12358.         manager.ActivateEntryByScriptTag( 'TutorialCamera_pad', JS_Active );
  12359.         manager.ActivateEntryByScriptTag( 'TutorialCiriBlink', JS_Active );
  12360.         manager.ActivateEntryByScriptTag( 'TutorialCiriCharge', JS_Active );
  12361.         manager.ActivateEntryByScriptTag( 'TutorialCiriStamina', JS_Active );
  12362.         manager.ActivateEntryByScriptTag( 'TutorialCounter', JS_Active );
  12363.         manager.ActivateEntryByScriptTag( 'TutorialDialogClose', JS_Active );
  12364.         manager.ActivateEntryByScriptTag( 'TutorialFallingRoll', JS_Active );
  12365.         manager.ActivateEntryByScriptTag( 'TutorialFocus', JS_Active );
  12366.         manager.ActivateEntryByScriptTag( 'TutorialFocusClues', JS_Active );
  12367.         manager.ActivateEntryByScriptTag( 'TutorialFocusClues', JS_Active );
  12368.         manager.ActivateEntryByScriptTag( 'TutorialHorseRoad', JS_Active );
  12369.         manager.ActivateEntryByScriptTag( 'TutorialHorseSpeed0', JS_Active );
  12370.         manager.ActivateEntryByScriptTag( 'TutorialHorseSpeed0_pad', JS_Active );
  12371.         manager.ActivateEntryByScriptTag( 'TutorialHorseSpeed1', JS_Active );
  12372.         manager.ActivateEntryByScriptTag( 'TutorialHorseSpeed2', JS_Active );
  12373.         manager.ActivateEntryByScriptTag( 'TutorialHorseSummon', JS_Active );
  12374.         manager.ActivateEntryByScriptTag( 'TutorialHorseSummon_pad', JS_Active );
  12375.         manager.ActivateEntryByScriptTag( 'TutorialIgni', JS_Active );
  12376.         manager.ActivateEntryByScriptTag( 'TutorialJournalAlternateSings', JS_Active );
  12377.         manager.ActivateEntryByScriptTag( 'TutorialJournalBoatDamage', JS_Active );
  12378.         manager.ActivateEntryByScriptTag( 'TutorialJournalBoatMount', JS_Active );
  12379.         manager.ActivateEntryByScriptTag( 'TutorialJournalBuffs', JS_Active );
  12380.         manager.ActivateEntryByScriptTag( 'TutorialJournalCharDevLeveling', JS_Active );
  12381.         manager.ActivateEntryByScriptTag( 'TutorialJournalCharDevSkills', JS_Active );
  12382.         manager.ActivateEntryByScriptTag( 'TutorialJournalCrafting', JS_Active );
  12383.         manager.ActivateEntryByScriptTag( 'TutorialJournalCrossbow', JS_Active );
  12384.         manager.ActivateEntryByScriptTag( 'TutorialJournalDialogGwint', JS_Active );
  12385.         manager.ActivateEntryByScriptTag( 'TutorialJournalDialogShop', JS_Active );
  12386.         manager.ActivateEntryByScriptTag( 'TutorialJournalDive', JS_Active );
  12387.         manager.ActivateEntryByScriptTag( 'TutorialJournalDodge', JS_Active );
  12388.         manager.ActivateEntryByScriptTag( 'TutorialJournalDodge_pad', JS_Active );
  12389.         manager.ActivateEntryByScriptTag( 'TutorialJournalDrawWeapon', JS_Active );
  12390.         manager.ActivateEntryByScriptTag( 'TutorialJournalDrawWeapon_pad', JS_Active );
  12391.         manager.ActivateEntryByScriptTag( 'TutorialJournalDurability', JS_Active );
  12392.         manager.ActivateEntryByScriptTag( 'TutorialJournalExplorations', JS_Active );
  12393.         manager.ActivateEntryByScriptTag( 'TutorialJournalExplorations_pad', JS_Active );
  12394.         manager.ActivateEntryByScriptTag( 'TutorialJournalFastTravel', JS_Active );
  12395.         manager.ActivateEntryByScriptTag( 'TutorialJournalFocusRedObjects', JS_Active );
  12396.         manager.ActivateEntryByScriptTag( 'TutorialJournalGasClouds', JS_Active );
  12397.         manager.ActivateEntryByScriptTag( 'TutorialJournalHeavyAttacks', JS_Active );
  12398.         manager.ActivateEntryByScriptTag( 'TutorialJournalHorse', JS_Active );
  12399.         manager.ActivateEntryByScriptTag( 'TutorialJournalHorseStamina', JS_Active );
  12400.         manager.ActivateEntryByScriptTag( 'TutorialJournalJump', JS_Active );
  12401.         manager.ActivateEntryByScriptTag( 'TutorialJournalLightAttacks', JS_Active );
  12402.         manager.ActivateEntryByScriptTag( 'TutorialJournalLightAttacks_pad', JS_Active );
  12403.         manager.ActivateEntryByScriptTag( 'TutorialJournalMeditation', JS_Active );
  12404.         manager.ActivateEntryByScriptTag( 'TutorialJournalMeditation_pad', JS_Active );
  12405.         manager.ActivateEntryByScriptTag( 'TutorialJournalMonsterThreatLevels', JS_Active );
  12406.         manager.ActivateEntryByScriptTag( 'TutorialJournalMovement', JS_Active );
  12407.         manager.ActivateEntryByScriptTag( 'TutorialJournalMovement_pad', JS_Active );
  12408.         manager.ActivateEntryByScriptTag( 'TutorialJournalMutagenIngredient', JS_Active );
  12409.         manager.ActivateEntryByScriptTag( 'TutorialJournalMutagenPotion', JS_Active );
  12410.         manager.ActivateEntryByScriptTag( 'TutorialJournalOils', JS_Active );
  12411.         manager.ActivateEntryByScriptTag( 'TutorialJournalPetards', JS_Active );
  12412.         manager.ActivateEntryByScriptTag( 'TutorialJournalPotions', JS_Active );
  12413.         manager.ActivateEntryByScriptTag( 'TutorialJournalPotions_pad', JS_Active );
  12414.         manager.ActivateEntryByScriptTag( 'TutorialJournalQuestArea', JS_Active );
  12415.         manager.ActivateEntryByScriptTag( 'TutorialJournalRadial', JS_Active );
  12416.         manager.ActivateEntryByScriptTag( 'TutorialJournalRifts', JS_Active );
  12417.         manager.ActivateEntryByScriptTag( 'TutorialJournalRun', JS_Active );
  12418.         manager.ActivateEntryByScriptTag( 'TutorialJournalShopDescription', JS_Active );
  12419.         manager.ActivateEntryByScriptTag( 'TutorialJournalSignCast', JS_Active );
  12420.         manager.ActivateEntryByScriptTag( 'TutorialJournalSignCast_pad', JS_Active );
  12421.         manager.ActivateEntryByScriptTag( 'TutorialJournalSpecialAttacks', JS_Active );
  12422.         manager.ActivateEntryByScriptTag( 'TutorialJournalStaminaExploration', JS_Active );
  12423.         manager.ActivateEntryByScriptTag( 'TutorialJumpHang', JS_Active );
  12424.         manager.ActivateEntryByScriptTag( 'TutorialLadder', JS_Active );
  12425.         manager.ActivateEntryByScriptTag( 'TutorialLadderMove', JS_Active );
  12426.         manager.ActivateEntryByScriptTag( 'TutorialLadderMove_pad', JS_Active );
  12427.         manager.ActivateEntryByScriptTag( 'TutorialObjectiveSwitching', JS_Active );
  12428.         manager.ActivateEntryByScriptTag( 'TutorialOxygen', JS_Active );
  12429.         manager.ActivateEntryByScriptTag( 'TutorialParry', JS_Active );
  12430.         manager.ActivateEntryByScriptTag( 'TutorialPOIUncovered', JS_Active );
  12431.         manager.ActivateEntryByScriptTag( 'TutorialQuen', JS_Active );
  12432.         manager.ActivateEntryByScriptTag( 'TutorialRoll', JS_Active );
  12433.         manager.ActivateEntryByScriptTag( 'TutorialRoll_pad', JS_Active );
  12434.         manager.ActivateEntryByScriptTag( 'TutorialSpeedPairing', JS_Active );
  12435.         manager.ActivateEntryByScriptTag( 'TutorialSprint', JS_Active );
  12436.         manager.ActivateEntryByScriptTag( 'TutorialStaminaSigns', JS_Active );
  12437.         manager.ActivateEntryByScriptTag( 'TutorialStealing', JS_Active );
  12438.         manager.ActivateEntryByScriptTag( 'TutorialSwimmingSpeed', JS_Active );
  12439.         manager.ActivateEntryByScriptTag( 'TutorialTimedChoiceDialog', JS_Active );
  12440.         manager.ActivateEntryByScriptTag( 'TutorialYrden', JS_Active );
  12441.        
  12442.         //modSigns
  12443.         inv.AddAnItem( 'Geralt Shirt', 1 );
  12444.         inv.AddAnItem( 'Thread', 3 );
  12445.         inv.AddAnItem( 'String', 3 );
  12446.         inv.AddAnItem( 'Linen', 2 );
  12447.         inv.AddAnItem( 'Silk', 1 );
  12448.         inv.AddAnItem( 'Nigredo', 1 );
  12449.         inv.AddAnItem( 'Albedo', 1 );
  12450.         inv.AddAnItem( 'Rubedo', 1 );
  12451.         inv.AddAnItem( 'Rebis', 1 );
  12452.         inv.AddAnItem( 'Dog tallow', 3 );
  12453.         inv.AddAnItem( 'Lunar shards', 1 );
  12454.         inv.AddAnItem( 'Quicksilver solution', 1 );
  12455.         inv.AddAnItem( 'Aether', 1 );
  12456.         inv.AddAnItem( 'Optima mater', 1 );
  12457.         inv.AddAnItem( 'Fifth essence', 1 );
  12458.         inv.AddAnItem( 'Hardened timber', 2 );
  12459.         inv.AddAnItem( 'Fur square', 1 );
  12460.         inv.AddAnItem( 'Leather straps', 4 );
  12461.         inv.AddAnItem( 'Leather squares', 1 );
  12462.         inv.AddAnItem( 'Leather', 2 );
  12463.         inv.AddAnItem( 'Hardened leather', 2 );
  12464.         inv.AddAnItem( 'Chitin scale', 2 );
  12465.         inv.AddAnItem( 'Draconide leather', 1 );
  12466.         inv.AddAnItem( 'Infused draconide leather', 0 );
  12467.         inv.AddAnItem( 'Steel ingot', 2 );
  12468.         inv.AddAnItem( 'Dark iron ore', 2 );
  12469.         inv.AddAnItem( 'Dark iron ingot', 1 );
  12470.         inv.AddAnItem( 'Dark steel ingot', 1 );
  12471.         inv.AddAnItem( 'Silver ore', 2 );
  12472.         inv.AddAnItem( 'Silver ingot', 2 );
  12473.         inv.AddAnItem( 'Meteorite ore', 2 );
  12474.         inv.AddAnItem( 'Meteorite ingot', 1 );
  12475.         inv.AddAnItem( 'Meteorite silver ingot', 1 );
  12476.         inv.AddAnItem( 'Dwimeryte ingot', 2 );
  12477.         inv.AddAnItem( 'Emerald dust', 2 );
  12478.         inv.AddAnItem( 'Ruby dust', 2 );
  12479.         inv.AddAnItem( 'Ruby', 1 );
  12480.         inv.AddAnItem( 'Sapphire dust', 2 );
  12481.         inv.AddAnItem( 'Sapphire', 1 );
  12482.         inv.AddAnItem( 'Monstrous brain', 4 );
  12483.         inv.AddAnItem( 'Monstrous blood', 3 );
  12484.         inv.AddAnItem( 'Monstrous bone', 4 );
  12485.         inv.AddAnItem( 'Monstrous claw', 3 );
  12486.         inv.AddAnItem( 'Monstrous dust', 3 );
  12487.         inv.AddAnItem( 'Monstrous ear', 4 );
  12488.         inv.AddAnItem( 'Monstrous egg', 2 );
  12489.         inv.AddAnItem( 'Monstrous eye', 2 );
  12490.         inv.AddAnItem( 'Monstrous essence', 3 );
  12491.         inv.AddAnItem( 'Monstrous feather', 4 );
  12492.         inv.AddAnItem( 'Monstrous hair', 3 );
  12493.         inv.AddAnItem( 'Monstrous heart', 2 );
  12494.         inv.AddAnItem( 'Monstrous hide', 3 );
  12495.         inv.AddAnItem( 'Monstrous liver', 2 );
  12496.         inv.AddAnItem( 'Monstrous plate', 1 );
  12497.         inv.AddAnItem( 'Monstrous saliva', 4 );
  12498.         inv.AddAnItem( 'Monstrous stomach', 2 );
  12499.         inv.AddAnItem( 'Monstrous tongue', 2 );
  12500.         inv.AddAnItem( 'Monstrous tooth', 3 );
  12501.         inv.AddAnItem( 'Venom extract', 1 );
  12502.         inv.AddAnItem( 'Siren vocal cords', 1 );
  12503.        
  12504.        
  12505.         SelectQuickslotItem( EES_RangedWeapon );
  12506.        
  12507.        
  12508.         FactsAdd( 'kill_base_tutorials' );
  12509.        
  12510.        
  12511.         theGame.GetTutorialSystem().RemoveAllQueuedTutorials();
  12512.        
  12513.        
  12514.         if( FactsQuerySum("standalone_ep2") < 1 ) //modSigns
  12515.             FactsAdd("standalone_ep2");
  12516.         FactsRemove( "StandAloneEP2" );
  12517.        
  12518.         theGame.GetJournalManager().ForceUntrackingQuestForEP1Savegame();
  12519.     }
  12520. }
  12521.  
  12522. exec function fuqfep1()
  12523. {
  12524.     theGame.GetJournalManager().ForceUntrackingQuestForEP1Savegame();
  12525. }
  12526.  
  12527.  
  12528.  
  12529.  
  12530.  
  12531. function GetWitcherPlayer() : W3PlayerWitcher
  12532. {
  12533.     return (W3PlayerWitcher)thePlayer;
  12534. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement