Advertisement
lufusol

npc.ws for E3 Wolf Follower for Witcher 3 4.01

Feb 12th, 2023
1,563
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /***********************************************************************/
  2. /**     © 2015 CD PROJEKT S.A. All rights reserved.
  3. /**     THE WITCHER® is a trademark of CD PROJEKT S. A.
  4. /**     The Witcher game is based on the prose of Andrzej Sapkowski.
  5. /***********************************************************************/
  6.  
  7.  
  8.  
  9. enum EConverserType
  10. {
  11.     CT_General,
  12.     CT_Nobleman,
  13.     CT_Guard,
  14.     CT_Mage,
  15.     CT_Bandit,
  16.     CT_Scoiatael,
  17.     CT_Peasant,
  18.     CT_Poor,
  19.     CT_Child
  20. };
  21.  
  22.  
  23. statemachine import class CNewNPC extends CActor
  24. {
  25.    
  26.    
  27.    
  28.     editable var isImmortal         : bool;            
  29.     editable var isInvulnerable     : bool;            
  30.     editable var willBeUnconscious  : bool;            
  31.     editable var minUnconsciousTime : float;            default minUnconsciousTime = 20.f;
  32.    
  33.     editable var unstoppable        : bool;             hint unstoppable = "won't play hit reaction nor critical state reaction";
  34.    
  35.     editable var RemainsTags        : array<name>;      hint RemainsTags="If set then the NPC's remains will be tagged with given tags";
  36.     editable var level              : int;              default level = 1;
  37.     var currentLevel        : int;
  38.     editable saved var levelFakeAddon     : int;                default levelFakeAddon = 0;
  39.     private  saved var newGamePlusFakeLevelAddon : bool;        default newGamePlusFakeLevelAddon = false;
  40.     private  saved var xmlLevel     : SAbilityAttributeValue;
  41.     private  var isXmlLevelSet      : bool;                     default isXmlLevelSet = false;
  42.     editable var isMiniBossLevel    : bool;                     default isMiniBossLevel = false;
  43.     import var suppressBroadcastingReactions        : bool;
  44.     editable saved var dontUseReactionOneLiners     : bool;     default dontUseReactionOneLiners = false;
  45.     editable saved var disableConstrainLookat       : bool;     default disableConstrainLookat = false;
  46.    
  47.     editable var isMonsterType_Group   : bool;                  default isMonsterType_Group = false;
  48.    
  49.     editable var useSoundValue      : bool;                     default useSoundValue = false;
  50.     editable var soundValue         : int; 
  51.    
  52.    
  53.     editable var clearInvOnDeath            : bool;
  54.     default clearInvOnDeath = false;
  55.    
  56.     editable var noAdaptiveBalance : bool;
  57.     default noAdaptiveBalance = false;
  58.    
  59.     editable var grantNoExperienceAfterKill : bool;
  60.     default grantNoExperienceAfterKill = false;
  61.    
  62.     editable var abilityBuffStackedOnEnemyHitName : name;
  63.    
  64.    
  65.     private var levelBonusesComputedAtPlayerLevel : int;        default levelBonusesComputedAtPlayerLevel = -1;
  66.    
  67.     hint abilityBuffStackedOnEnemyHitName = "Stackable ability added on hitting enemies. Mainly for damage scaling of followers.";
  68.     hint disableConstrainLookat = "It will disable lookats form reactions and from QuestLookat block";
  69.     hint useSoundValue = "If true it will add the SoundValue to the threat Rating used for combat music control";
  70.     hint soundValue = "This value will be added or subtracted from sound system to achieve final threat Rating";
  71.    
  72.    
  73.    
  74.     import private saved var npcGroupType       : ENPCGroupType;    default npcGroupType = ENGT_Enemy;
  75.    
  76.    
  77.     private optional autobind   horseComponent      : W3HorseComponent = single;
  78.     private var         isHorse             : bool;
  79.     private saved var   canFlee             : bool;     default     canFlee = true;
  80.     private var         isFallingFromHorse  : bool;     default     isFallingFromHorse = false;
  81.    
  82.     private var     immortalityInitialized  : bool;
  83.    
  84.    
  85.     private var     canBeFollowed           : bool;     default         canBeFollowed = false;
  86.  
  87.    
  88.     private var     bAgony                  : bool;     default         bAgony  = false;
  89.     private var     bFinisher               : bool;     default         bFinisher = false;
  90.     private var     bPlayDeathAnim          : bool;     default         bPlayDeathAnim = true;
  91.     private var     bAgonyDisabled          : bool;     default         bAgonyDisabled = false;
  92.     private var     bFinisherInterrupted    : bool;
  93.    
  94.     private var     bIsInHitAnim : bool;
  95.    
  96.    
  97.     private var     threatLevel                 : int;              default         threatLevel = 10;
  98.     private var     counterWindowStartTime      : EngineTime;      
  99.     private var     bIsCountering               : bool;
  100.     private var     allowBehGraphChange         : bool;             default         allowBehGraphChange = true;
  101.     private var     aardedFlight                : bool;            
  102.     public var      lastMeleeHitTime            : EngineTime;      
  103.    
  104.     private saved var preferedCombatStyle : EBehaviorGraph;
  105.    
  106.    
  107.     private var     previousStance              : ENpcStance;       default         previousStance  = NS_Normal;
  108.     private var     regularStance               : ENpcStance;       default         regularStance   = NS_Normal;
  109.    
  110.    
  111.     private var     currentFightStage           : ENPCFightStage;
  112.    
  113.    
  114.     private var     currentState                : CName;            default         autoState = 'NewIdle';
  115.  
  116.     private var     behaviorGraphEventListened  : array<name>;
  117.    
  118.    
  119.     private var     isTemporaryOffGround        : bool;
  120.    
  121.    
  122.     private var     npc_health_bar              : float;
  123.    
  124.    
  125.     private var     isUnderwater                : bool;     default isUnderwater = false;
  126.    
  127.    
  128.     private var isTranslationScaled             : bool;
  129.    
  130.    
  131.     private var tauntedToAttackTimeStamp        : float;
  132.    
  133.    
  134.    
  135.    
  136.    
  137.     public var isTeleporting                    : bool;         default isTeleporting = false;
  138.    
  139.    
  140.    
  141.    
  142.    
  143.    
  144.    
  145.     public var itemToEquip                      : SItemUniqueId;
  146.    
  147.    
  148.     private saved var wasBleedingBurningPoisoned    : bool;     default wasBleedingBurningPoisoned = false;
  149.    
  150.    
  151.     public  var wasInTalkInteraction                : bool;
  152.     private var wasInCutscene                       : bool;
  153.     public  var shieldDebris                        : CItemEntity;
  154.     public  var lastMealTime                        : float;    default lastMealTime = -1;
  155.     public  var packName                            : name;    
  156.     public  var isPackLeader                        : bool;    
  157.     private var mac                                 : CMovingPhysicalAgentComponent;
  158.     private var parentEncounter                     : CEncounter;
  159.     private var npcLevelToUpscaledLevelDifference   : int;     
  160.    
  161.    
  162.     private saved  var isTalkDisabled               : bool; default isTalkDisabled = false;
  163.     private        var isTalkDisabledTemporary      : bool; default isTalkDisabledTemporary = false;
  164.    
  165.    
  166.     private var wasNGPlusLevelAdded                 : bool; default wasNGPlusLevelAdded = false;
  167.    
  168.     private var deathTimestamp : float;
  169.    
  170.     event OnGameDifficultyChanged( previousDifficulty : int, currentDifficulty : int )
  171.     {
  172.         if ( HasAbility('difficulty_CommonEasy') ) RemoveAbility('difficulty_CommonEasy');
  173.         if ( HasAbility('difficulty_CommonMedium') )  RemoveAbility('difficulty_CommonMedium');
  174.         if ( HasAbility('difficulty_CommonHard') )  RemoveAbility('difficulty_CommonHard');
  175.         if ( HasAbility('difficulty_CommonHardcore') )  RemoveAbility('difficulty_CommonHardcore');
  176.        
  177.         switch ( theGame.GetSpawnDifficultyMode() )
  178.         {
  179.         case EDM_Easy:
  180.             AddAbility('difficulty_CommonEasy');
  181.             break;
  182.         case EDM_Medium:
  183.             AddAbility('difficulty_CommonMedium');
  184.             break;
  185.         case EDM_Hard:
  186.             AddAbility('difficulty_CommonHard');
  187.             break;
  188.         case EDM_Hardcore:
  189.             AddAbility('difficulty_CommonHardcore');
  190.             break;
  191.         }  
  192.        
  193.         levelBonusesComputedAtPlayerLevel = -1;
  194.         AddTimer('AddLevelBonuses', 0.1, true, false, , true);
  195.     }
  196.    
  197.     event OnLevelUpscalingChanged()
  198.     {
  199.         levelBonusesComputedAtPlayerLevel = -1;
  200.         AddTimer('AddLevelBonuses', RandRangeF(0.05,0.2), true, false, , true);
  201.     }
  202.    
  203.     timer function ResetTalkInteractionFlag( td : float , id : int)
  204.     {
  205.         if ( !IsSpeaking() )
  206.         {
  207.             wasInTalkInteraction = false;
  208.             RemoveTimer('ResetTalkInteractionFlag');
  209.         }
  210.     }
  211.        
  212.     protected function OnCombatModeSet( toggle : bool )
  213.     {
  214.         super.OnCombatModeSet( toggle );
  215.        
  216.         if( toggle )
  217.         {
  218.             SetCombatStartTime();
  219.             SetCombatPartStartTime();
  220.            
  221.            
  222.            
  223.            
  224.             RecalcLevel();
  225.         }
  226.         else
  227.         {
  228.             ResetCombatStartTime();
  229.             ResetCombatPartStartTime();
  230.            
  231.            
  232.             StopEffectIfActive('hand_fx');
  233.         }      
  234.     }
  235.    
  236.     public function SetImmortalityInitialized(){ immortalityInitialized = true; }
  237.    
  238.     public function SetNPCType( type : ENPCGroupType ) { npcGroupType = type; }
  239.     public function GetNPCType() : ENPCGroupType { return npcGroupType; }
  240.    
  241.     public function GetBloodType() : EBloodType
  242.     {
  243.         var tmpName : name;
  244.         var tmpBool : bool;
  245.         var mc : EMonsterCategory;
  246.         var blood : EBloodType;
  247.        
  248.         theGame.GetMonsterParamsForActor(this, mc, tmpName, tmpBool, tmpBool, tmpBool);
  249.        
  250.         switch( mc )
  251.         {
  252.             case MC_Specter :
  253.             case MC_Vampire :
  254.             case MC_Magicals :
  255.                 blood = BT_Black;
  256.                 break;
  257.                
  258.             case MC_Cursed :
  259.                 blood = BT_Yellow;
  260.                 break;
  261.                
  262.             case MC_Insectoid :
  263.                 blood = BT_Green;
  264.                 break;
  265.                
  266.             case MC_Troll :
  267.             case MC_Human :
  268.             case MC_Animal :
  269.             case MC_Necrophage :
  270.             case MC_Hybrid :
  271.             case MC_Relic :
  272.             case MC_Beast :
  273.             case MC_Draconide :
  274.             default :
  275.                 blood = BT_Red;
  276.         }
  277.        
  278.         return blood;
  279.     }
  280.    
  281.     public function SetCanBeFollowed( val : bool ) { canBeFollowed = val; }
  282.     public function CanBeFollowed() : bool { return canBeFollowed; }
  283.    
  284.     event OnPreAttackEvent(animEventName : name, animEventType : EAnimationEventType, data : CPreAttackEventData, animInfo : SAnimationEventAnimInfo )
  285.     {
  286.         var witcher : W3PlayerWitcher;
  287.         var levelDiff : int;
  288.    
  289.         super.OnPreAttackEvent(animEventName, animEventType, data, animInfo);
  290.        
  291.         if(animEventType == AET_DurationStart )
  292.         {
  293.            
  294.            
  295.             witcher = GetWitcherPlayer();
  296.            
  297.            
  298.            
  299.             if(GetTarget() == witcher )
  300.             {
  301.                 levelDiff = GetLevel() - witcher.GetLevel();
  302.                
  303.                
  304.                
  305.                 if ( levelDiff < 100 )
  306.                     this.SetDodgeFeedback( true );
  307.             }
  308.            
  309.             if ( IsCountering() )
  310.             {
  311.                
  312.                 if(GetTarget() == witcher && ( thePlayer.IsActionAllowed(EIAB_Dodge) || thePlayer.IsActionAllowed(EIAB_Roll) ) && witcher.GetStat(BCS_Toxicity) > 0 && witcher.CanUseSkill(S_Alchemy_s16))
  313.                     witcher.StartFrenzy();
  314.             }
  315.         }
  316.         else if(animEventType == AET_DurationEnd )
  317.         {
  318.             witcher = GetWitcherPlayer();
  319.            
  320.             if(GetTarget() == witcher )
  321.             {      
  322.                 this.SetDodgeFeedback( false );
  323.             }
  324.         }
  325.     }
  326.    
  327.     public function SetDodgeFeedback( flag : bool )
  328.     {
  329.        
  330.         if ( flag )
  331.         {
  332.             thePlayer.SetDodgeFeedbackTarget( this );
  333.         }
  334.         else
  335.         {
  336.             thePlayer.SetDodgeFeedbackTarget( NULL );
  337.         }
  338.     }
  339.    
  340.     event OnBlockingSceneEnded( optional output : CStorySceneOutput)
  341.     {
  342.         super.OnBlockingSceneEnded( output );
  343.         wasInCutscene = true;
  344.     }
  345.    
  346.     public function WasInCutscene() : bool
  347.     {
  348.         return wasInCutscene;
  349.     }
  350.    
  351.    
  352.     public function IsVIP() : bool
  353.     {
  354.         var tags : array<name>;
  355.         var i : int;
  356.        
  357.        
  358.         tags = GetTags();
  359.         for ( i = 0; i < tags.Size(); i+=1 )
  360.         {
  361.             if ( tags[i] == 'vip' )
  362.             {
  363.                 return true;
  364.             }
  365.         }
  366.        
  367.         return false;
  368.     }
  369.    
  370.    
  371.    
  372.    
  373.    
  374.    
  375.     event OnSpawned(spawnData : SEntitySpawnData )
  376.     {
  377.         var lvlDiff, playerLevel: int;
  378.         var heading         : float;
  379.         var remainingDuration : float;
  380.         var oldLevel : int;
  381.        
  382.         currentLevel = level;
  383.         levelBonusesComputedAtPlayerLevel = -1;
  384.        
  385.         super.OnSpawned(spawnData);
  386.        
  387.        
  388.         SetThreatLevel();
  389.        
  390.        
  391.         GotoStateAuto();       
  392.        
  393.        
  394.         isTalkDisabledTemporary = false;
  395.        
  396.        
  397.         if ( HasTag( 'fergus_graem' ) )
  398.         {
  399.             if ( !isTalkDisabled )
  400.             {
  401.                 GetComponent( 'talk' ).SetEnabled( true );
  402.             }
  403.         }
  404.        
  405.        
  406.         if(!spawnData.restored )
  407.         {
  408.             if( !isXmlLevelSet )
  409.             {
  410.                 xmlLevel = GetAttributeValue( 'level',,true );
  411.                 isXmlLevelSet = true;
  412.             }
  413.             if ( !immortalityInitialized )
  414.             {
  415.                 SetCanPlayHitAnim( true );
  416.                
  417.                 if(isInvulnerable)
  418.                 {
  419.                     SetImmortalityMode(AIM_Invulnerable, AIC_Default);
  420.                 }
  421.                 else if(isImmortal)
  422.                 {
  423.                     SetImmortalityMode(AIM_Immortal, AIC_Default);
  424.                 }
  425.                 else if( willBeUnconscious )
  426.                 {
  427.                     SetImmortalityMode(AIM_Unconscious, AIC_Default);
  428.                     SignalGameplayEventParamFloat('ChangeUnconsciousDuration',minUnconsciousTime);
  429.                 }
  430.                 else if ( npcGroupType == ENGT_Commoner || npcGroupType == ENGT_Guard || npcGroupType == ENGT_Quest )
  431.                 {
  432.                     SetImmortalityMode(AIM_Unconscious, AIC_Default);  
  433.                 }
  434.             }
  435.         }
  436.        
  437.        
  438.         if( npcGroupType == ENGT_Guard )
  439.         {
  440.             SetOriginalInteractionPriority( IP_Prio_5 );
  441.             RestoreOriginalInteractionPriority();
  442.         }
  443.         else if( npcGroupType == ENGT_Quest )
  444.         {
  445.             SetOriginalInteractionPriority( IP_Max_Unpushable );
  446.             RestoreOriginalInteractionPriority();
  447.         }
  448.        
  449.        
  450.        
  451.         mac = (CMovingPhysicalAgentComponent)GetMovingAgentComponent();
  452.         if(mac && IsFlying() )
  453.             mac.SetAnimatedMovement( true );
  454.        
  455.        
  456.         RegisterCollisionEventsListener();     
  457.        
  458.        
  459.         if (focusModeSoundEffectType == FMSET_None)
  460.             SetFocusModeSoundEffectType( FMSET_Gray );
  461.        
  462.         heading = AngleNormalize( GetHeading() );
  463.        
  464.         SetBehaviorVariable( 'requestedFacingDirection', heading );
  465.        
  466.         if ( disableConstrainLookat )
  467.             SetBehaviorVariable( 'disableConstraintLookat', 1.f);
  468.            
  469.        
  470.         SoundSwitch( "vo_3d", 'vo_3d_long', 'head' );
  471.        
  472.         AddAnimEventCallback('EquipItemL' ,                         'OnAnimEvent_EquipItemL');
  473.         AddAnimEventCallback('HideItemL' ,                          'OnAnimEvent_HideItemL');
  474.         AddAnimEventCallback('HideWeapons' ,                        'OnAnimEvent_HideWeapons');
  475.         AddAnimEventCallback('TemporaryOffGround' ,                 'OnAnimEvent_TemporaryOffGround');
  476.         AddAnimEventCallback('NullifyBurning' ,                     'OnAnimEvent_NullifyBurning');
  477.         AddAnimEventCallback('setVisible' ,                         'OnAnimEvent_setVisible');
  478.         AddAnimEventCallback('extensionWalk' ,                      'OnAnimEvent_extensionWalk');
  479.         AddAnimEventCallback('extensionWalkNormalSpeed' ,           'OnAnimEvent_extensionWalkNormalSpeed');
  480.         AddAnimEventCallback('extensionWalkRightHandOnly' ,         'OnAnimEvent_extensionWalkRightHandOnly');
  481.         AddAnimEventCallback('extensionWalkStartStopNormalSpeed' ,  'OnAnimEvent_extensionWalkStartStopNormalSpeed');
  482.         AddAnimEventCallback('weaponSoundType' ,                    'OnAnimEvent_weaponSoundType');
  483.         AddAnimEventCallback('disableCrowdOverride' ,               'OnAnimEvent_disableCrowdOverride');
  484.        
  485.         if ( IsAnimal() )
  486.         {
  487.             AddAnimEventCallback('OwlSwitchOpen' ,                  'OnAnimEvent_OwlSwitchOpen');
  488.             AddAnimEventCallback('OwlSwitchClose' ,                 'OnAnimEvent_OwlSwitchClose');
  489.             AddAnimEventCallback('Goose01OpenWings' ,               'OnAnimEvent_Goose01OpenWings');
  490.             AddAnimEventCallback('Goose01CloseWings' ,              'OnAnimEvent_Goose01CloseWings');
  491.             AddAnimEventCallback('Goose02OpenWings' ,               'OnAnimEvent_Goose02OpenWings');
  492.             AddAnimEventCallback('Goose02CloseWings' ,              'OnAnimEvent_Goose02CloseWings');
  493.         }
  494.        
  495.         if( HasTag( 'olgierd_gpl' ) )
  496.         {
  497.             AddAnimEventCallback('IdleDown' ,                       'OnAnimEvent_IdleDown');
  498.             AddAnimEventCallback('IdleForward' ,                    'OnAnimEvent_IdleForward');
  499.             AddAnimEventCallback('IdleCombat' ,                     'OnAnimEvent_IdleCombat');
  500.             AddAnimEventCallback('WeakenedState' ,                  'OnAnimEvent_WeakenedState');
  501.             AddAnimEventCallback('WeakenedStateOff' ,               'OnAnimEvent_WeakenedStateOff');
  502.             AddAnimEventCallback('SlideAway' ,                      'OnAnimEvent_SlideAway');
  503.             AddAnimEventCallback('SlideForward' ,                   'OnAnimEvent_SlideForward');
  504.             AddAnimEventCallback('SlideTowards' ,                   'OnAnimEvent_SlideTowards');
  505.             AddAnimEventCallback('OpenHitWindow' ,                  'OnAnimEvent_WindowManager');
  506.             AddAnimEventCallback('CloseHitWindow' ,                 'OnAnimEvent_WindowManager');
  507.             AddAnimEventCallback('OpenCounterWindow' ,              'OnAnimEvent_WindowManager');
  508.             AddAnimEventCallback('BC_Weakened' ,                    'OnAnimEvent_PlayBattlecry');
  509.             AddAnimEventCallback('BC_Attack' ,                      'OnAnimEvent_PlayBattlecry');
  510.             AddAnimEventCallback('BC_Parry' ,                       'OnAnimEvent_PlayBattlecry');
  511.             AddAnimEventCallback('BC_Sign' ,                        'OnAnimEvent_PlayBattlecry');
  512.             AddAnimEventCallback('BC_Taunt' ,                       'OnAnimEvent_PlayBattlecry');
  513.         }
  514.         else if( HasTag( 'scolopendromorph' ) || HasTag( 'archespor' ) )
  515.         {
  516.             AddAnimEventCallback('SetIsUnderground' ,           'OnAnimEvent_ToggleIsOverground');
  517.             AddAnimEventCallback('SetIsOverground' ,            'OnAnimEvent_ToggleIsOverground');
  518.             AddAnimEventCallback('IdleDown' ,                   'OnAnimEvent_IdleDown');
  519.             AddAnimEventCallback('IdleForward' ,                'OnAnimEvent_IdleForward');
  520.             AddAnimEventCallback('CannotBeAttacked' ,           'OnAnimEvent_CannotBeAttacked');
  521.            
  522.             if( HasTag( 'scolopendromorph' ) )
  523.             {
  524.                 ToggleIsOverground( false );
  525.             }
  526.         }
  527.         else if( HasTag( 'dettlaff_vampire' ) )
  528.         {
  529.             AddAnimEventCallback('OpenHitWindow' ,                  'OnAnimEvent_WindowManager');
  530.             AddAnimEventCallback('CloseHitWindow' ,                 'OnAnimEvent_WindowManager');
  531.             AddAnimEventCallback('OpenCounterWindow' ,              'OnAnimEvent_WindowManager');
  532.             AddAnimEventCallback('SlideAway' ,                      'OnAnimEvent_SlideAway');
  533.             AddAnimEventCallback('SlideForward' ,                   'OnAnimEvent_SlideForward');
  534.             AddAnimEventCallback('WeakenedState' ,                  'OnAnimEvent_WeakenedState');
  535.             AddAnimEventCallback('WeakenedStateOff' ,               'OnAnimEvent_WeakenedStateOff');
  536.         }
  537.         else if( HasTag( 'fairytale_witch' ) )
  538.         {
  539.             AddAnimEventCallback('CauldronDropped' ,                'OnAnimEvent_CauldronDropped');
  540.             AddAnimEventCallback('OpenHitWindow' ,                  'OnAnimEvent_WindowManager');
  541.             AddAnimEventCallback('CloseHitWindow' ,                 'OnAnimEvent_WindowManager');
  542.         }
  543.         else if( HasTag( 'fairytaleWitchBroom' ) )
  544.         {
  545.             AddAnimEventCallback('BroomDeath' ,                     'OnAnimEvent_BroomDeath');
  546.         }
  547.         else if( HasTag( 'q703_ofir_mage' ) )
  548.         {
  549.             AddAnimEventCallback('ActivateSide' ,                   'OnAnimEvent_ActivateSide');
  550.             AddAnimEventCallback('ActivateUp' ,                     'OnAnimEvent_ActivateUp');
  551.         }
  552.         else if ( HasTag( 'q703_dolphin' ) )
  553.         {
  554.             AddAnimEventCallback('DeactivateSide' ,                 'OnAnimEvent_DeactivateSide');
  555.             AddAnimEventCallback('DeactivateUp' ,                   'OnAnimEvent_DeactivateUp');
  556.         }
  557.         else if ( HasAbility( 'mon_vampiress_base' ) )
  558.         {
  559.             AddAnimEventCallback('bruxa_jump_failsafe' ,            'OnAnimEvent_BruxaJumpFailsafe' );
  560.         }
  561.         else if ( HasAbility( 'mon_werewolf_base' ) )
  562.         {
  563.             AddAnimEventCallback('ResetOneTimeSpawnActivation' ,    'OnAnimEvent_ResetOneTimeSpawnActivation' );
  564.         }
  565.        
  566.         if( HasAbility( 'NoShadows' ) )
  567.         {
  568.             SetGroupShadows( false );
  569.         }
  570.        
  571.         if(HasAbility('_canBeFollower') && theGame.GetDifficultyMode() != EDM_Hardcore)
  572.             RemoveAbility('_canBeFollower');
  573.        
  574.        
  575.            
  576.            
  577.        
  578.         if( (FactsQuerySum("NewGamePlus") > 0 || (!HasAbility('NoAdaptBalance') && currentLevel > 1 ) ) )
  579.         {
  580.            
  581.            
  582.             if ( theGame.IsActive() )
  583.             {
  584.                 if(  ( ( FactsQuerySum("NewGamePlus") > 0 ) && !HasTag('animal') ))
  585.                 {
  586.                     if( !HasAbility('NPCDoNotGainBoost') && !HasAbility('NewGamePlusFakeLevel') )
  587.                     {
  588.                         currentLevel += theGame.params.GetNewGamePlusLevel();
  589.                         if ( currentLevel > ( theGame.params.GetPlayerMaxLevel() + 5 ) )
  590.                         {
  591.                             currentLevel = theGame.params.GetPlayerMaxLevel() + 5;
  592.                         }
  593.                     }
  594.                     else if ( !HasAbility('NPCDoNotGainNGPlusLevel') )
  595.                     {
  596.                         newGamePlusFakeLevelAddon = true;
  597.                     }
  598.                    
  599.                    
  600.                 }
  601.                 else
  602.                 {
  603.                    
  604.                     if ( ( theGame.GetDifficultyMode() == EDM_Easy || theGame.GetDifficultyMode() == EDM_Medium ) && playerLevel == 1 && npcGroupType != ENGT_Guard && !HasAbility('PrologModifier'))
  605.                     {
  606.                         AddAbility('PrologModifier');
  607.                     }
  608.                 }
  609.             }  
  610.         }  
  611.  
  612.        
  613.         if( IsHorse() )
  614.         {
  615.             AddTimer('NGE_HorseEquipWeaponHack',0.5f,false);           
  616.         }
  617.        
  618.     }
  619.    
  620.    
  621.    
  622.     timer function NGE_HorseEquipWeaponHack(dt:float,id:int)
  623.     {
  624.         var arr : array<SItemUniqueId>;
  625.    
  626.         arr = GetInventory().GetItemsByName('mon_horse_weapon');
  627.         if(arr.Size() <= 0)
  628.             arr = GetInventory().AddAnItem('mon_horse_weapon');
  629.         EquipItem(arr[0],EES_InvalidSlot, true);
  630.     }
  631.    
  632.    
  633.    
  634.     protected function SetAbilityManager()
  635.     {
  636.         if(npcGroupType != ENGT_Commoner)
  637.             abilityManager = new W3NonPlayerAbilityManager in this;    
  638.     }
  639.    
  640.     protected function SetEffectManager()
  641.     {
  642.         if(npcGroupType != ENGT_Commoner)
  643.             super.SetEffectManager();
  644.     }
  645.    
  646.     public function  SetLevel ( _level : int )
  647.     {
  648.         currentLevel = _level;
  649.         levelBonusesComputedAtPlayerLevel = -1;
  650.         AddTimer('AddLevelBonuses', 0.1, true, false, , true);
  651.     }
  652.    
  653.     private function SetThreatLevel()
  654.     {
  655.         var temp : float;
  656.        
  657.         temp = CalculateAttributeValue(GetAttributeValue('threat_level'));
  658.         if ( temp >= 0.f )
  659.         {
  660.             threatLevel = (int)temp;
  661.         }
  662.         else
  663.         {
  664.             LogAssert(false,"No threat_level attribute set. Threat level set to 0");
  665.             threatLevel = 0;
  666.         }
  667.     }
  668.     public function ChangeThreatLevel( newValue : int )
  669.     {
  670.         threatLevel = newValue;
  671.     }
  672.    
  673.    
  674.     public function SetNpcHealthBar()
  675.     {
  676.         npc_health_bar = GetHealthPercents();
  677.         SoundParameter( 'npc_health_bar', npc_health_bar, 'all' );
  678.     }
  679.    
  680.     public function GetNpcHealthBar() : float
  681.     {
  682.         return npc_health_bar;
  683.     }
  684.    
  685.      public function GetHorseUser() : CActor
  686.     {
  687.         if( horseComponent )
  688.         {
  689.             return horseComponent.GetCurrentUser();
  690.         }
  691.        
  692.         return NULL;
  693.     }
  694.    
  695.  
  696.  
  697.    
  698.    
  699.    
  700.    
  701.     public function GetPreferedCombatStyle() : EBehaviorGraph
  702.     {
  703.         return preferedCombatStyle;
  704.     }
  705.    
  706.     public function SetPreferedCombatStyle( _preferedCombatStyle : EBehaviorGraph )
  707.     {
  708.         preferedCombatStyle = _preferedCombatStyle;
  709.     }
  710.    
  711.    
  712.     timer function WeatherBonusCheck(dt : float, id : int)
  713.     {
  714.         var curGameTime : GameTime;
  715.         var dayPart : EDayPart;
  716.         var bonusName : name;
  717.         var curEffect : CBaseGameplayEffect;
  718.         var moonState : EMoonState;
  719.         var weather : EWeatherEffect;
  720.         var params : SCustomEffectParams;
  721.        
  722.         if ( !IsAlive() )
  723.         {
  724.             return;
  725.         }
  726.        
  727.         moonState = GetCurMoonState();
  728.        
  729.         curGameTime = GameTimeCreate();
  730.         dayPart = GetDayPart(curGameTime);
  731.        
  732.         weather = GetCurWeather();
  733.        
  734.         bonusName = ((W3NonPlayerAbilityManager)abilityManager).GetWeatherBonus(dayPart, weather, moonState);
  735.        
  736.         curEffect = GetBuff(EET_WeatherBonus);
  737.         if (curEffect)
  738.         {
  739.             if ( curEffect.GetAbilityName() == bonusName )
  740.             {
  741.                 return;
  742.             }
  743.             else
  744.             {
  745.                 RemoveBuff(EET_WeatherBonus);
  746.             }
  747.         }
  748.        
  749.         if (bonusName != 'None')
  750.         {
  751.             params.effectType = EET_WeatherBonus;
  752.             params.creator = this;
  753.             params.sourceName = "WeatherBonus";
  754.             params.customAbilityName = bonusName;
  755.             AddEffectCustom(params);
  756.         }
  757.     }
  758.    
  759.     public function IsFlying() : bool
  760.     {
  761.         var result : bool;
  762.         result = ( this.GetCurrentStance() == NS_Fly );
  763.         return result;
  764.     }
  765.    
  766.     public function IsRanged() : bool
  767.     {
  768.         var weapon : SItemUniqueId;
  769.         var weapon2 : SItemUniqueId;
  770.        
  771.         if( HasAbility( 'Ranged' ) )
  772.         {
  773.             return true;
  774.         }
  775.        
  776.         weapon = this.GetInventory().GetItemFromSlot( 'l_weapon' );
  777.         weapon2 = this.GetInventory().GetItemFromSlot( 'r_weapon' );
  778.        
  779.         return ( this.GetInventory().GetItemCategory( weapon ) == 'bow' || this.GetInventory().GetItemCategory( weapon2 ) == 'crossbow' );
  780.        
  781.     }
  782.    
  783.    
  784.    
  785.     public function IsVisuallyOffGround() : bool
  786.     {
  787.         if( isTemporaryOffGround )
  788.             return true;
  789.         if( IsFlying() )
  790.             return true;
  791.            
  792.         return false;
  793.     }
  794.  
  795.     public function SetIsHorse()
  796.     {
  797.         if ( horseComponent )
  798.             isHorse = true;
  799.     }
  800.    
  801.     public function IsHorse() : bool
  802.     {
  803.         return isHorse;
  804.     }
  805.    
  806.     public function GetHorseComponent() : W3HorseComponent
  807.     {
  808.         if ( isHorse )
  809.             return horseComponent;
  810.         else
  811.             return NULL;
  812.     }
  813.    
  814.     public function HideHorseAfter( time : float )
  815.     {
  816.         if( !isHorse )
  817.             return;
  818.        
  819.         SetVisibility( false );
  820.         SetGameplayVisibility( false );
  821.        
  822.         AddTimer( 'HideHorse', time );
  823.     }
  824.    
  825.     private timer function HideHorse( delta : float , id : int )
  826.     {
  827.         Teleport( thePlayer.GetWorldPosition() + thePlayer.GetHeadingVector() * 1000.0 );
  828.        
  829.         SetVisibility( true );
  830.         SetGameplayVisibility( true );
  831.     }
  832.    
  833.     public function KillHorseAfter( time : float )
  834.     {
  835.         if( !isHorse )
  836.             return;
  837.         AddTimer( 'KillHorse', time );
  838.     }
  839.    
  840.     private timer function KillHorse( delta : float , id : int )
  841.     {
  842.         SetKinematic( false );
  843.         Kill( 'KillHorse', true );
  844.         SetAlive( false );
  845.         GetComponentByClassName( 'CInteractionComponent' ).SetEnabled( false );
  846.         PlayEffect( 'hit_ground' );
  847.     }
  848.    
  849.     public timer function RemoveAxiiFromHorse( delta : float , id : int )
  850.     {
  851.         RemoveAbility( 'HorseAxiiBuff' );
  852.     }
  853.    
  854.     public function ToggleCanFlee( val : bool ) { canFlee = val; }
  855.     public function GetCanFlee() : bool         { return canFlee; }
  856.    
  857.     public function SetIsFallingFromHorse( val : bool )        
  858.     {
  859.         if( val )
  860.         {
  861.             AddBuffImmunity( EET_HeavyKnockdown, 'SetIsFallingFromHorse', true );
  862.             isFallingFromHorse = true;
  863.         }
  864.         else
  865.         {
  866.             RemoveBuffImmunity( EET_HeavyKnockdown, 'SetIsFallingFromHorse' );
  867.             isFallingFromHorse = false;
  868.         }
  869.     }
  870.     public function GetIsFallingFromHorse() : bool              { return isFallingFromHorse; }
  871.    
  872.     public function SetCounterWindowStartTime(time : EngineTime)    {counterWindowStartTime = time;}
  873.     public function GetCounterWindowStartTime() : EngineTime        {return counterWindowStartTime;}
  874.    
  875.    
  876.     function GetThreatLevel() : int
  877.     {
  878.         return threatLevel;
  879.     }
  880.    
  881.     function GetSoundValue() : int
  882.     {
  883.         return soundValue;
  884.     }
  885.        
  886.     public function WasTauntedToAttack()
  887.     {
  888.         tauntedToAttackTimeStamp = theGame.GetEngineTimeAsSeconds();
  889.     }
  890.    
  891.    
  892.    
  893.     timer function MaintainSpeedTimer( d : float , id : int)
  894.     {
  895.         this.SetBehaviorVariable( 'Editor_MovementSpeed', 0 );
  896.     }
  897.     timer function MaintainFlySpeedTimer( d : float , id : int)
  898.     {
  899.         this.SetBehaviorVariable( 'Editor_FlySpeed', 0 );
  900.     }
  901.    
  902.    
  903.    
  904.    
  905.     public function SetIsInHitAnim( toggle : bool )
  906.     {
  907.         bIsInHitAnim = toggle;
  908.         if ( !toggle )
  909.             this.SignalGameplayEvent('WasHit');
  910.     }
  911.    
  912.     public function IsInHitAnim() : bool
  913.     {
  914.         return bIsInHitAnim;
  915.     }
  916.    
  917.     public function CanChangeBehGraph() : bool
  918.     {
  919.         return allowBehGraphChange;
  920.     }
  921.    
  922.     public function WeaponSoundType() : CItemEntity
  923.     {
  924.         var weapon : SItemUniqueId;
  925.         weapon = GetInventory().GetItemFromSlot( 'r_weapon' );
  926.        
  927.         return GetInventory().GetItemEntityUnsafe(weapon);
  928.     }
  929.  
  930.    
  931.    
  932.    
  933.     function EnableCounterParryFor( time : float )
  934.     {
  935.         bCanPerformCounter = true;
  936.         AddTimer('DisableCounterParry',time,false);
  937.     }
  938.    
  939.     timer function DisableCounterParry( td : float , id : int)
  940.     {
  941.         bCanPerformCounter = false;
  942.     }
  943.    
  944.     var combatStorage : CBaseAICombatStorage;
  945.    
  946.     public final function IsAttacking() : bool
  947.     {
  948.         if ( !combatStorage )
  949.             combatStorage = (CBaseAICombatStorage)GetScriptStorageObject('CombatData');
  950.            
  951.         if(combatStorage)
  952.         {
  953.             return combatStorage.GetIsAttacking();
  954.         }
  955.        
  956.         return false;
  957.     }
  958.        
  959.     public final function RecalcLevel()
  960.     {
  961.         if(!IsAlive())
  962.             return;
  963.            
  964.         AddLevelBonuses(0, 0);
  965.     }
  966.    
  967.    
  968.     protected function PerformCounterCheck(parryInfo: SParryInfo) : bool
  969.     {
  970.         return false;
  971.     }
  972.    
  973.    
  974.     protected function PerformParryCheck(parryInfo : SParryInfo) : bool
  975.     {
  976.         var mult : float;
  977.         var isHeavy : bool;
  978.         var npcTarget : CNewNPC;
  979.         var fistFightParry : bool;
  980.        
  981.         if ( !parryInfo.canBeParried )
  982.             return false;
  983.        
  984.         if( this.IsHuman() && ((CHumanAICombatStorage)this.GetScriptStorageObject('CombatData')).IsProtectedByQuen() )
  985.             return false;
  986.         if( !CanParryAttack() )
  987.             return false;
  988.         if( !FistFightCheck(parryInfo.target, parryInfo.attacker, fistFightParry) )
  989.             return false;
  990.         if( IsInHitAnim() && HasTag( 'imlerith' ) )
  991.             return false;  
  992.        
  993.         npcTarget = (CNewNPC)parryInfo.target;
  994.        
  995.         if( npcTarget.IsShielded(parryInfo.attacker) || ( !npcTarget.HasShieldedAbility() && parryInfo.targetToAttackerAngleAbs < 90 ) || (  npcTarget.HasTag( 'olgierd_gpl' ) && parryInfo.targetToAttackerAngleAbs < 120 ) )
  996.         {  
  997.             isHeavy = IsHeavyAttack(parryInfo.attackActionName);
  998.                        
  999.            
  1000.             if( HasStaminaToParry( parryInfo.attackActionName ) && ( HasAbility( 'ablParryHeavyAttacks' ) || !isHeavy ) )
  1001.             {
  1002.                
  1003.                 SetBehaviorVariable( 'parryAttackType', (int)PAT_Light );
  1004.                
  1005.                 if( isHeavy )
  1006.                     SignalGameplayEventParamInt( 'ParryPerform', 1 );
  1007.                 else
  1008.                     SignalGameplayEventParamInt( 'ParryPerform', 0 );
  1009.             }
  1010.             else
  1011.             {
  1012.                
  1013.                 SetBehaviorVariable( 'parryAttackType', (int)PAT_Heavy );
  1014.            
  1015.                 if( isHeavy )
  1016.                     SignalGameplayEventParamInt( 'ParryStagger', 1 );
  1017.                 else
  1018.                     SignalGameplayEventParamInt( 'ParryStagger', 0 );
  1019.             }
  1020.            
  1021.             if( parryInfo.attacker == thePlayer && parryInfo.attacker.IsWeaponHeld( 'fist' ) && !parryInfo.target.IsWeaponHeld( 'fist' ) )
  1022.             {
  1023.                 parryInfo.attacker.SetBehaviorVariable( 'reflectAnim', 1.f );
  1024.                 parryInfo.attacker.ReactToReflectedAttack(this);               
  1025.             }
  1026.             else
  1027.             {
  1028.                 if( isHeavy )
  1029.                 {
  1030.                     ToggleEffectOnShield( 'heavy_block', true );
  1031.                 }
  1032.                 else
  1033.                 {
  1034.                     ToggleEffectOnShield( 'light_block', true );
  1035.                 }
  1036.             }
  1037.            
  1038.             return true;
  1039.         }      
  1040.        
  1041.         return false;
  1042.     }
  1043.        
  1044.     public function GetTotalSignSpellPower(signSkill : ESkill) : SAbilityAttributeValue
  1045.     {      
  1046.         return GetPowerStatValue(CPS_SpellPower);
  1047.     }
  1048.    
  1049.      event OnProcessActionPost(action : W3DamageAction)
  1050.     {
  1051.         var actorVictim : CActor;
  1052.         var time, maxTox, toxToAdd : float;
  1053.         var gameplayEffect : CBaseGameplayEffect;
  1054.         var template : CEntityTemplate;
  1055.         var fxEnt : CEntity;
  1056.         var toxicity : SAbilityAttributeValue;
  1057.        
  1058.         super.OnProcessActionPost(action);
  1059.        
  1060.        
  1061.         actorVictim = (CActor)action.victim;
  1062.         if(HasBuff(EET_AxiiGuardMe) && (thePlayer.HasAbility('Glyphword 14 _Stats', true) || thePlayer.HasAbility('Glyphword 18 _Stats', true)) && action.DealtDamage())
  1063.         {
  1064.             time = CalculateAttributeValue(thePlayer.GetAttributeValue('increas_duration'));
  1065.             gameplayEffect = GetBuff(EET_AxiiGuardMe);
  1066.             gameplayEffect.SetTimeLeft( gameplayEffect.GetTimeLeft() + time );
  1067.            
  1068.             template = (CEntityTemplate)LoadResource('glyphword_10_18');
  1069.            
  1070.             if(GetBoneIndex('head') != -1)
  1071.             {              
  1072.                 fxEnt = theGame.CreateEntity(template, GetBoneWorldPosition('head'), GetWorldRotation(), , , true);
  1073.                 fxEnt.CreateAttachmentAtBoneWS(this, 'head', GetBoneWorldPosition('head'), GetWorldRotation());
  1074.             }
  1075.             else
  1076.             {
  1077.                 fxEnt = theGame.CreateEntity(template, GetBoneWorldPosition('k_head_g'), GetWorldRotation(), , , true);
  1078.                 fxEnt.CreateAttachmentAtBoneWS(this, 'k_head_g', GetBoneWorldPosition('k_head_g'), GetWorldRotation());
  1079.                
  1080.             }
  1081.            
  1082.             fxEnt.PlayEffect('axii_extra_time');
  1083.             fxEnt.DestroyAfter(5);
  1084.         }
  1085.        
  1086.        
  1087.         if( action.victim && action.victim == GetWitcherPlayer() && action.DealtDamage() )
  1088.         {
  1089.             toxicity = GetAttributeValue( 'toxicity_increase_on_hit' );
  1090.             if( toxicity.valueAdditive > 0.f || toxicity.valueMultiplicative > 0.f )
  1091.             {
  1092.                 maxTox = GetWitcherPlayer().GetStatMax( BCS_Toxicity );
  1093.                 toxToAdd = maxTox * toxicity.valueMultiplicative + toxicity.valueAdditive;
  1094.                 GetWitcherPlayer().GainStat( BCS_Toxicity, toxToAdd );
  1095.             }
  1096.         }
  1097.     }
  1098.    
  1099.     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
  1100.     {
  1101.         var containedAbs, abs, tmp : array< name >;
  1102.         var i : int;
  1103.         var ret : bool;
  1104.         var effectType : EEffectType;
  1105.         var customAbilityName : name;
  1106.        
  1107.         ret = super.PrepareAttackAction( hitTarget, animData, weaponId, parried, countered, parriedBy, attackAnimationName, hitTime, weaponEntity, attackAction );
  1108.        
  1109.        
  1110.         GetCharacterStats().GetAbilities( abs, false );
  1111.         for( i=0; i<abs.Size(); i+=1 )
  1112.         {
  1113.             theGame.GetDefinitionsManager().GetContainedAbilities( abs[i], tmp );
  1114.             ArrayOfNamesAppendUnique( containedAbs, tmp );
  1115.             tmp.Clear();
  1116.         }      
  1117.        
  1118.         for( i=0; i<containedAbs.Size(); i+=1 )
  1119.         {
  1120.             EffectNameToType( containedAbs[i], effectType, customAbilityName );
  1121.            
  1122.             if( effectType == EET_ToxicityVenom )
  1123.             {
  1124.                 attackAction.AddEffectInfo( effectType, , GetAttributeValue( 'toxicityVenom' ) );
  1125.                 break;
  1126.             }
  1127.         }
  1128.        
  1129.         return ret;
  1130.     }
  1131.    
  1132.    
  1133.    
  1134.    
  1135.     var fistFightForcedFromQuest : bool;
  1136.    
  1137.    
  1138.    
  1139.     private var initialPointsRes        : float;
  1140.     private var initialForcePercRes     : float;
  1141.     private var initialBurningPercRes   : float;
  1142.     private var initialWillPercRes      : float;
  1143.     private var initialShockPercRes     : float;
  1144.    
  1145.     public function CheckInitialPercResistances()
  1146.     {
  1147.         GetResistValue( CDS_ForceRes, initialPointsRes, initialForcePercRes );
  1148.         GetResistValue( CDS_BurningRes, initialPointsRes, initialBurningPercRes );
  1149.         GetResistValue( CDS_WillRes, initialPointsRes, initialWillPercRes );
  1150.         GetResistValue( CDS_ShockRes, initialPointsRes, initialShockPercRes );
  1151.     }
  1152.    
  1153.     public function GetInitialForceResistancePerc()     : float { return initialForcePercRes; }
  1154.     public function GetInitialBurningResistancePerc()   : float { return initialBurningPercRes; }
  1155.     public function GetInitialWillResistancePerc()      : float { return initialWillPercRes; }
  1156.     public function GetInitialShockResistancePerc()     : float { return initialShockPercRes; }
  1157.    
  1158.    
  1159.    
  1160.     timer function AddLevelBonuses (dt : float, id : int)
  1161.     {
  1162.         var ciriEntity          : W3ReplacerCiri;
  1163.         var ignoreLowLevelCheck : bool;
  1164.         var lvlDiff             : int;
  1165.         var npcLevel            : int;
  1166.         var ngpLevel            : int;
  1167.         var i                   : int;
  1168.         var playerLevel         : int;
  1169.         var stats               : CCharacterStats;
  1170.         var npcGroupType        : ENPCGroupType;
  1171.        
  1172.         //++E3WolfFollower
  1173.         if( (CWolfNPC)this )
  1174.         {
  1175.             AddTimer('AddWolfieBonuses', 0.1, true, false,, true);
  1176.             return;
  1177.         }
  1178.         //--E3WolfFollower
  1179.        
  1180.         RemoveTimer( 'AddLevelBonuses' );
  1181.        
  1182.         playerLevel = thePlayer.GetLevel();
  1183.        
  1184.        
  1185.         if ( levelBonusesComputedAtPlayerLevel == playerLevel && !fistFightForcedFromQuest )
  1186.         {
  1187.             return;
  1188.         }
  1189.         stats = GetCharacterStats();
  1190.        
  1191.        
  1192.         if ( stats.HasAbility( 'NPCDoNotGainBoost' ) ) return;
  1193.         if ( stats.HasAbility( 'animal_rat_base' ) ) return;
  1194.         if ( stats.HasAbility( 'mon_djinn' ) ) return;
  1195.         if ( IsAnimal() ) return;
  1196.        
  1197.        
  1198.         levelBonusesComputedAtPlayerLevel = playerLevel;
  1199.        
  1200.         ciriEntity = (W3ReplacerCiri)thePlayer;
  1201.         npcLevel = currentLevel;
  1202.         npcGroupType = GetNPCType();
  1203.         ignoreLowLevelCheck = thePlayer.GetEnemyUpscaling() && ( npcGroupType == ENGT_Enemy || npcGroupType == ENGT_Quest );
  1204.        
  1205.         if ( npcGroupType != ENGT_Guard && !ignoreLowLevelCheck && npcLevel + (int)CalculateAttributeValue( GetAttributeValue( 'level',,true ) ) <= 2 ) return;
  1206.         if ( stats.HasAbilityWithTag('Boss') && !ciriEntity )
  1207.         {
  1208.             if ( thePlayer.GetEnemyUpscaling() && npcLevel < playerLevel )
  1209.             {
  1210.                 stats.AddAbilityMultiple( theGame.params.BOSS_NGP_BONUS, playerLevel - npcLevel );
  1211.             }
  1212.             else if ( FactsQuerySum( "NewGamePlus" ) > 0 && theGame.params.NewGamePlusLevelDifference() > 0 )
  1213.             {
  1214.                 stats.AddAbilityMultiple( theGame.params.BOSS_NGP_BONUS, theGame.params.NewGamePlusLevelDifference() );
  1215.                 return ;
  1216.             }
  1217.         }
  1218.  
  1219.        
  1220.        
  1221.         if ( !ciriEntity && thePlayer.GetEnemyUpscaling() && npcLevel + levelFakeAddon < playerLevel
  1222.             && !stats.HasAbility( 'fistfight_minigame' ) && !fistFightForcedFromQuest )
  1223.         {
  1224.            
  1225.             npcLevelToUpscaledLevelDifference = playerLevel - npcLevel;
  1226.             if ( xmlLevel.valueAdditive != npcLevel )
  1227.             {
  1228.                 npcLevel = playerLevel - (int)xmlLevel.valueAdditive + 1 - levelFakeAddon;
  1229.             }
  1230.             else
  1231.             {
  1232.                 npcLevel = playerLevel - levelFakeAddon;
  1233.             }
  1234.         }
  1235.         else
  1236.         {
  1237.             npcLevelToUpscaledLevelDifference = 0;
  1238.         }
  1239.        
  1240.         if ( stats.HasAbility(theGame.params.ENEMY_BONUS_DEADLY) ) stats.RemoveAbility(theGame.params.ENEMY_BONUS_DEADLY); else
  1241.         if ( stats.HasAbility(theGame.params.ENEMY_BONUS_HIGH) ) stats.RemoveAbility(theGame.params.ENEMY_BONUS_HIGH); else
  1242.         if ( stats.HasAbility(theGame.params.ENEMY_BONUS_LOW) ) stats.RemoveAbility(theGame.params.ENEMY_BONUS_LOW); else
  1243.         if ( stats.HasAbility(theGame.params.MONSTER_BONUS_DEADLY) ) stats.RemoveAbility(theGame.params.MONSTER_BONUS_DEADLY); else
  1244.         if ( stats.HasAbility(theGame.params.MONSTER_BONUS_HIGH) ) stats.RemoveAbility(theGame.params.MONSTER_BONUS_HIGH); else
  1245.         if ( stats.HasAbility(theGame.params.MONSTER_BONUS_LOW) ) stats.RemoveAbility(theGame.params.MONSTER_BONUS_LOW);
  1246.         stats.RemoveAbilityAll(theGame.params.ENEMY_BONUS_PER_LEVEL);
  1247.         stats.RemoveAbilityAll(theGame.params.MONSTER_BONUS_PER_LEVEL_GROUP_ARMORED);
  1248.         stats.RemoveAbilityAll(theGame.params.MONSTER_BONUS_PER_LEVEL_GROUP);
  1249.         stats.RemoveAbilityAll(theGame.params.MONSTER_BONUS_PER_LEVEL_ARMORED );
  1250.         stats.RemoveAbilityAll(theGame.params.MONSTER_BONUS_PER_LEVEL);
  1251.        
  1252.         CheckInitialPercResistances();
  1253.        
  1254.         if ( IsHuman() && GetStat( BCS_Essence, true ) < 0 )
  1255.         {
  1256.             if ( npcGroupType != ENGT_Guard )
  1257.             {
  1258.                 if ( !stats.HasAbility(theGame.params.ENEMY_BONUS_PER_LEVEL) )
  1259.                 {
  1260.                     stats.AddAbilityMultiple(theGame.params.ENEMY_BONUS_PER_LEVEL, npcLevel-1);
  1261.                 }
  1262.             }
  1263.             else
  1264.             {
  1265.                 if ( !stats.HasAbility(theGame.params.ENEMY_BONUS_PER_LEVEL) )
  1266.                 {
  1267.                    
  1268.                    
  1269.                     stats.AddAbilityMultiple(theGame.params.ENEMY_BONUS_PER_LEVEL, 1 + GetWitcherPlayer().GetLevel() + RandRange( 1, 4 ) );
  1270.                      
  1271.                 }
  1272.             }
  1273.            
  1274.             if ( thePlayer.IsCiri() && theGame.GetDifficultyMode() == EDM_Hardcore && !stats.HasAbility('CiriHardcoreDebuffHuman') )
  1275.             {
  1276.                 stats.AddAbility('CiriHardcoreDebuffHuman');
  1277.             }
  1278.            
  1279.             if ( !ciriEntity )
  1280.             {
  1281.                 lvlDiff = (int)CalculateAttributeValue( GetAttributeValue( 'level',,true ) ) - playerLevel;
  1282.                 if ( lvlDiff >= theGame.params.LEVEL_DIFF_DEADLY ) { if ( !stats.HasAbility(theGame.params.ENEMY_BONUS_DEADLY) )
  1283.                 {
  1284.                     stats.AddAbility(theGame.params.ENEMY_BONUS_DEADLY, true); }
  1285.                    
  1286.                    
  1287.                    
  1288.                 }  
  1289.                 else if ( lvlDiff >= theGame.params.LEVEL_DIFF_HIGH )
  1290.                 {
  1291.                     if ( !stats.HasAbility(theGame.params.ENEMY_BONUS_HIGH) )
  1292.                     {
  1293.                         stats.AddAbility(theGame.params.ENEMY_BONUS_HIGH, true);
  1294.                     }
  1295.                 }
  1296.                 else if ( lvlDiff > -theGame.params.LEVEL_DIFF_HIGH )
  1297.                 {
  1298.                 }
  1299.                 else
  1300.                 {
  1301.                     if ( !stats.HasAbility(theGame.params.ENEMY_BONUS_LOW) )
  1302.                     {
  1303.                         stats.AddAbility(theGame.params.ENEMY_BONUS_LOW, true);
  1304.                     }
  1305.                 }
  1306.             }    
  1307.         }
  1308.         else
  1309.         {
  1310.             if ( GetStat( BCS_Vitality, true ) > 0 )
  1311.             {
  1312.                 if ( !ciriEntity )
  1313.                 {
  1314.                     lvlDiff = (int)CalculateAttributeValue( GetAttributeValue( 'level',,true ) ) - playerLevel;
  1315.                    
  1316.                    
  1317.                     if ( lvlDiff >= theGame.params.LEVEL_DIFF_DEADLY ) { if ( !stats.HasAbility(theGame.params.ENEMY_BONUS_DEADLY) ) { stats.AddAbility(theGame.params.ENEMY_BONUS_DEADLY, true); } }  
  1318.                    
  1319.                     else if ( lvlDiff >= theGame.params.LEVEL_DIFF_HIGH )  { if ( !stats.HasAbility(theGame.params.ENEMY_BONUS_HIGH) ) stats.AddAbility(theGame.params.ENEMY_BONUS_HIGH, true);}
  1320.                     else if ( lvlDiff > -theGame.params.LEVEL_DIFF_HIGH )  { }
  1321.                     else                      { if ( !stats.HasAbility(theGame.params.ENEMY_BONUS_LOW) ) stats.AddAbility(theGame.params.ENEMY_BONUS_LOW, true); }
  1322.                    
  1323.                     if ( !stats.HasAbility(theGame.params.ENEMY_BONUS_PER_LEVEL) ) stats.AddAbilityMultiple(theGame.params.ENEMY_BONUS_PER_LEVEL, npcLevel-1);
  1324.                 }
  1325.             }
  1326.             else
  1327.             {
  1328.                
  1329.                 if( !stats.HasAbility(theGame.params.MONSTER_BONUS_PER_LEVEL_GROUP_ARMORED) &&
  1330.                     !stats.HasAbility(theGame.params.MONSTER_BONUS_PER_LEVEL_ARMORED) &&
  1331.                     !stats.HasAbility(theGame.params.MONSTER_BONUS_PER_LEVEL_GROUP) &&
  1332.                     !stats.HasAbility(theGame.params.MONSTER_BONUS_PER_LEVEL)
  1333.                 )
  1334.                 {              
  1335.                     if ( CalculateAttributeValue(GetTotalArmor()) > 0.f )
  1336.                     {
  1337.                         if ( GetIsMonsterTypeGroup() )
  1338.                         {
  1339.                             stats.AddAbilityMultiple(theGame.params.MONSTER_BONUS_PER_LEVEL_GROUP_ARMORED, npcLevel-1);
  1340.                         }
  1341.                         else
  1342.                         {
  1343.                             stats.AddAbilityMultiple(theGame.params.MONSTER_BONUS_PER_LEVEL_ARMORED, npcLevel-1);
  1344.                         }
  1345.                     }
  1346.                     else
  1347.                     {
  1348.                         if ( GetIsMonsterTypeGroup() )
  1349.                         {
  1350.                             stats.AddAbilityMultiple(theGame.params.MONSTER_BONUS_PER_LEVEL_GROUP, npcLevel-1);
  1351.                         }
  1352.                         else
  1353.                         {
  1354.                             stats.AddAbilityMultiple(theGame.params.MONSTER_BONUS_PER_LEVEL, npcLevel-1);
  1355.                         }
  1356.                     }
  1357.                 }
  1358.                
  1359.                 if ( thePlayer.IsCiri() && theGame.GetDifficultyMode() == EDM_Hardcore && !stats.HasAbility('CiriHardcoreDebuffMonster') ) stats.AddAbility('CiriHardcoreDebuffMonster');
  1360.                    
  1361.                 if ( !ciriEntity )
  1362.                 {
  1363.                     lvlDiff = (int)CalculateAttributeValue(GetAttributeValue('level',,true)) - playerLevel;
  1364.                    
  1365.                    
  1366.                     if ( lvlDiff >= theGame.params.LEVEL_DIFF_DEADLY ) { if ( !stats.HasAbility(theGame.params.MONSTER_BONUS_DEADLY) ) { stats.AddAbility(theGame.params.MONSTER_BONUS_DEADLY, true); } }  
  1367.                    
  1368.                     else if ( lvlDiff >= theGame.params.LEVEL_DIFF_HIGH )  { if ( !stats.HasAbility(theGame.params.MONSTER_BONUS_HIGH) ) stats.AddAbility(theGame.params.MONSTER_BONUS_HIGH, true); }
  1369.                     else if ( lvlDiff > -theGame.params.LEVEL_DIFF_HIGH )  { }
  1370.                     else                      { if ( !stats.HasAbility(theGame.params.MONSTER_BONUS_LOW) ) stats.AddAbility(theGame.params.MONSTER_BONUS_LOW, true); }     
  1371.                 }
  1372.             }    
  1373.            
  1374.         }
  1375.        
  1376.     }
  1377.    
  1378.     public function SetParentEncounter( encounter : CEncounter )
  1379.     {
  1380.         parentEncounter = encounter;
  1381.     }
  1382.    
  1383.     public function GetParentEncounter() : CEncounter
  1384.     {
  1385.         return parentEncounter;
  1386.     }
  1387.    
  1388.     public function GainStat( stat : EBaseCharacterStats, amount : float )
  1389.     {
  1390.        
  1391.         if(stat == BCS_Panic && IsHorse() && thePlayer.GetUsedVehicle() == this && thePlayer.HasBuff(EET_Mutagen25))
  1392.         {
  1393.             return;
  1394.         }
  1395.        
  1396.         super.GainStat(stat, amount);
  1397.     }
  1398.    
  1399.     public function ForceSetStat(stat : EBaseCharacterStats, val : float)
  1400.     {
  1401.        
  1402.         if(stat == BCS_Panic && IsHorse() && thePlayer.GetUsedVehicle() == this && thePlayer.HasBuff(EET_Mutagen25) && val >= GetStat(BCS_Panic))
  1403.         {
  1404.             return;
  1405.         }
  1406.        
  1407.         super.ForceSetStat(stat, val);
  1408.     }
  1409.    
  1410.    
  1411.    
  1412.    
  1413.    
  1414.     timer function FundamentalsAchFailTimer(dt : float, id : int)
  1415.     {
  1416.         RemoveTag('failedFundamentalsAchievement');
  1417.     }
  1418.    
  1419.    
  1420.    
  1421.    
  1422.    
  1423.     event OnCriticalStateAnimStop()
  1424.     {
  1425.         isRecoveringFromKnockdown = false;
  1426.     }
  1427.    
  1428.     protected function CriticalBuffInformBehavior(buff : CBaseGameplayEffect)
  1429.     {
  1430.         SignalGameplayEventParamInt('CriticalState',(int)GetBuffCriticalType(buff));
  1431.     }
  1432.    
  1433.    
  1434.     public function StartCSAnim(buff : CBaseGameplayEffect) : bool
  1435.     {
  1436.         if(super.StartCSAnim(buff))
  1437.         {
  1438.             CriticalBuffInformBehavior(buff);
  1439.             return true;
  1440.         }
  1441.          
  1442.         return false;
  1443.     }
  1444.    
  1445.     public function CSAnimStarted(buff : CBaseGameplayEffect) : bool
  1446.     {
  1447.         return super.StartCSAnim(buff);
  1448.     }
  1449.    
  1450.     function SetCanPlayHitAnim( flag : bool )
  1451.     {
  1452.         if( !flag && this.IsHuman() && this.GetAttitude( thePlayer ) != AIA_Friendly )
  1453.         {
  1454.             super.SetCanPlayHitAnim( flag );
  1455.         }
  1456.         else
  1457.         {
  1458.             super.SetCanPlayHitAnim( flag );
  1459.         }
  1460.     }
  1461.  
  1462.    
  1463.    
  1464.     event OnStartFistfightMinigame()
  1465.     {
  1466.         super.OnStartFistfightMinigame();
  1467.        
  1468.         thePlayer.ProcessLockTarget( this );
  1469.         SignalGameplayEventParamInt('ChangePreferedCombatStyle',(int)EBG_Combat_Fists );
  1470.         SetTemporaryAttitudeGroup( 'fistfight_opponent', AGP_Fistfight );
  1471.         ForceVulnerableImmortalityMode();
  1472.         if ( !thePlayer.IsFistFightMinigameToTheDeath() )
  1473.             SetImmortalityMode(AIM_Unconscious, AIC_Fistfight);
  1474.         if(FactsQuerySum("NewGamePlus") > 0)
  1475.         {FistFightNewGamePlusSetup();}
  1476.         FistFightHealthSetup();
  1477.        
  1478.     }
  1479.    
  1480.     event OnEndFistfightMinigame()
  1481.     {  
  1482.         SignalGameplayEvent('ResetPreferedCombatStyle');
  1483.         ResetTemporaryAttitudeGroup( AGP_Fistfight );
  1484.         RestoreImmortalityMode();
  1485.         LowerGuard();
  1486.         if ( IsKnockedUnconscious() )
  1487.         {
  1488.             SignalGameplayEvent('ForceStopUnconscious');
  1489.         }
  1490.         if ( !IsAlive() )
  1491.         {
  1492.             Revive();
  1493.         }
  1494.         FistFightHealthSetup();
  1495.        
  1496.         super.OnEndFistfightMinigame();
  1497.     }
  1498.        
  1499.     private function FistFightHealthSetup()
  1500.     {
  1501.        
  1502.         if ( HasAbility( 'fistfight_minigame' ) )
  1503.         {
  1504.             FistFightersHealthDiff();
  1505.         }
  1506.         else return;
  1507.  
  1508.     }
  1509.    
  1510.     private function FistFightersHealthDiff()
  1511.     {
  1512.         var vitality        : float;
  1513.         var stats : CCharacterStats;
  1514.         stats = GetCharacterStats();
  1515.        
  1516.         if ( stats.HasAbility( 'StatsFistsTutorial' ) )
  1517.         {
  1518.             stats.AddAbility( 'HealthFistFightTutorial', false );
  1519.         }
  1520.         else if ( stats.HasAbility( 'StatsFistsEasy' ) )
  1521.         {
  1522.             stats.AddAbility( 'HealthFistFightEasy', false );
  1523.         }
  1524.         else if ( stats.HasAbility( 'StatsFistsMedium' ) )
  1525.         {
  1526.             stats.AddAbility( 'HealthFistFightMedium', false );
  1527.         }
  1528.         else if ( stats.HasAbility( 'StatsFistsHard' ) )
  1529.         {
  1530.             stats.AddAbility( 'HealthFistFightHard', false );
  1531.         }
  1532.         vitality = abilityManager.GetStatMax( BCS_Vitality );
  1533.         SetHealthPerc( 100 );
  1534.     }
  1535.    
  1536.     private function FistFightNewGamePlusSetup()
  1537.     {
  1538.         if ( HasAbility( 'NPCLevelBonus' ) )
  1539.         {
  1540.             RemoveAbilityMultiple( 'NPCLevelBonus', theGame.params.GetNewGamePlusLevel() );
  1541.             newGamePlusFakeLevelAddon = true;
  1542.             currentLevel -= theGame.params.GetNewGamePlusLevel();
  1543.             RecalcLevel();
  1544.         }
  1545.     }
  1546.    
  1547.     private function ApplyFistFightLevelDiff()
  1548.     {
  1549.         var lvlDiff     : int;
  1550.         var i           : int;
  1551.         var attribute   : SAbilityAttributeValue;
  1552.         var min, max    : SAbilityAttributeValue;
  1553.         var ffHP, ffAP  : SAbilityAttributeValue;
  1554.         var dm          : CDefinitionsManagerAccessor;
  1555.        
  1556.         lvlDiff = (int)CalculateAttributeValue(GetAttributeValue('level',,true)) - thePlayer.GetLevel();
  1557.        
  1558.         if ( !HasAbility('NPC fists _Stats') )
  1559.         {
  1560.             dm = theGame.GetDefinitionsManager();
  1561.             dm.GetAbilityAttributeValue('NPC fists _Stats', 'vitality', min, max);
  1562.             ffHP = GetAttributeRandomizedValue(min, max);
  1563.             dm.GetAbilityAttributeValue('NPC fists _Stats', 'attack_power', min, max);
  1564.             ffAP = GetAttributeRandomizedValue(min, max);
  1565.         }
  1566.        
  1567.         if ( lvlDiff < -theGame.params.LEVEL_DIFF_HIGH )
  1568.         {
  1569.             for (i=0; i < 5; i+=1)
  1570.             {
  1571.                 AddAbility(theGame.params.ENEMY_BONUS_FISTFIGHT_LOW, true);
  1572.                 attribute = GetAttributeValue('vitality');
  1573.                 attribute += ffHP;
  1574.                 if (attribute.valueMultiplicative <= 0)
  1575.                 {
  1576.                     RemoveAbility(theGame.params.ENEMY_BONUS_FISTFIGHT_LOW);
  1577.                     return;
  1578.                 }
  1579.                 attribute = GetAttributeValue('attack_power');
  1580.                 attribute += ffAP;
  1581.                 if (attribute.valueMultiplicative <= 0)
  1582.                 {
  1583.                     RemoveAbility(theGame.params.ENEMY_BONUS_FISTFIGHT_LOW);
  1584.                     return;
  1585.                 }
  1586.             }
  1587.         }
  1588.         else if ( lvlDiff < 0 )
  1589.         {
  1590.             for (i=0; i < -lvlDiff; i+=1)
  1591.             {
  1592.                 AddAbility(theGame.params.ENEMY_BONUS_FISTFIGHT_LOW, true);
  1593.                 attribute = GetAttributeValue('vitality');
  1594.                 if (attribute.valueMultiplicative <= 0)
  1595.                 {
  1596.                     RemoveAbility(theGame.params.ENEMY_BONUS_FISTFIGHT_LOW);
  1597.                     return;
  1598.                 }
  1599.                 attribute = GetAttributeValue('attack_power');
  1600.                 if (attribute.valueMultiplicative <= 0)
  1601.                 {
  1602.                     RemoveAbility(theGame.params.ENEMY_BONUS_FISTFIGHT_LOW);
  1603.                     return;
  1604.                 }
  1605.             }
  1606.         }
  1607.         else if ( lvlDiff > theGame.params.LEVEL_DIFF_HIGH )
  1608.             AddAbilityMultiple(theGame.params.ENEMY_BONUS_FISTFIGHT_HIGH, 5);
  1609.         else if ( lvlDiff > 0  )
  1610.             AddAbilityMultiple(theGame.params.ENEMY_BONUS_FISTFIGHT_HIGH, lvlDiff);
  1611.     }
  1612.    
  1613.     private function RemoveFistFightLevelDiff()
  1614.     {
  1615.         RemoveAbilityMultiple(theGame.params.ENEMY_BONUS_FISTFIGHT_LOW, 5);
  1616.         RemoveAbilityMultiple(theGame.params.ENEMY_BONUS_FISTFIGHT_HIGH, 5);
  1617.     }
  1618.  
  1619.    
  1620.    
  1621.    
  1622.    
  1623.     private function IsThisStanceRegular( Stance : ENpcStance ) : bool
  1624.     {
  1625.         if( Stance == NS_Normal ||
  1626.             Stance == NS_Strafe ||
  1627.             Stance == NS_Retreat )
  1628.         {
  1629.             return true;
  1630.         }
  1631.        
  1632.         return false;
  1633.     }
  1634.    
  1635.     private function IsThisStanceDefensive( Stance : ENpcStance ) : bool
  1636.     {
  1637.         if( Stance == NS_Guarded ||
  1638.             Stance == NS_Guarded )
  1639.         {
  1640.             return true;
  1641.         }
  1642.        
  1643.         return false;
  1644.     }
  1645.    
  1646.     function GetCurrentStance() : ENpcStance
  1647.     {
  1648.         var l_currentStance : int;
  1649.         l_currentStance = (int)this.GetBehaviorVariable( 'npcStance');
  1650.         return l_currentStance;
  1651.     }
  1652.    
  1653.     function GetRegularStance() : ENpcStance
  1654.     {
  1655.         return this.regularStance;
  1656.     }
  1657.    
  1658.     function ReturnToRegularStance()
  1659.     {
  1660.         this.SetBehaviorVariable( 'npcStance',(int)this.regularStance);
  1661.     }
  1662.    
  1663.     function IsInRegularStance() : bool
  1664.     {
  1665.         if( GetCurrentStance() == GetRegularStance() )
  1666.         {
  1667.             return true;
  1668.         }
  1669.        
  1670.         return false;
  1671.     }
  1672.    
  1673.     function ChangeStance( newStance : ENpcStance ) : bool
  1674.     {
  1675.         if ( IsThisStanceDefensive( newStance ) )
  1676.         {
  1677.             LogChannel('NPC ChangeStance', "You shouldn't use this function to change to this stance - " + newStance );
  1678.         }
  1679.         else if ( IsThisStanceRegular( newStance ) )
  1680.         {
  1681.             if ( this.SetBehaviorVariable( 'npcStance',(int)newStance) )
  1682.             {
  1683.                 this.regularStance = newStance;
  1684.                 return true;
  1685.             }
  1686.         }
  1687.         else
  1688.         {
  1689.             return this.SetBehaviorVariable( 'npcStance',(int)newStance);
  1690.         }
  1691.         return false;
  1692.     }
  1693.    
  1694.     function RaiseGuard() : bool
  1695.     {
  1696.         SetGuarded( true );
  1697.         return true;
  1698.     }
  1699.    
  1700.     function LowerGuard() : bool
  1701.     {
  1702.         SetGuarded( false );
  1703.         return true;
  1704.     }
  1705.    
  1706.    
  1707.    
  1708.    
  1709.    
  1710.     function IsInAgony() : bool
  1711.     {
  1712.         return bAgony;
  1713.     }
  1714.    
  1715.     function EnterAgony()
  1716.     {
  1717.         bAgony = true;
  1718.     }
  1719.    
  1720.     function EndAgony()
  1721.     {
  1722.         bAgony = false;
  1723.     }
  1724.    
  1725.     function EnableDeathAndAgony()
  1726.     {
  1727.         bPlayDeathAnim = true;
  1728.         bAgonyDisabled = false;
  1729.     }
  1730.    
  1731.     function EnableDeath()
  1732.     {
  1733.         bPlayDeathAnim = true;
  1734.     }
  1735.    
  1736.     function EnableAgony()
  1737.     {
  1738.         bAgonyDisabled = false;
  1739.     }
  1740.    
  1741.     function DisableDeathAndAgony()
  1742.     {
  1743.         bPlayDeathAnim = false;
  1744.         bAgonyDisabled = true;
  1745.     }
  1746.     function DisableAgony()
  1747.     {
  1748.         bAgonyDisabled = true;
  1749.     }
  1750.    
  1751.     function IsAgonyDisabled() : bool
  1752.     {
  1753.         return bAgonyDisabled;
  1754.     }
  1755.    
  1756.     function IsInFinisherAnim() : bool
  1757.     {
  1758.         return bFinisher;
  1759.     }
  1760.    
  1761.     function FinisherAnimStart()
  1762.     {
  1763.         bPlayDeathAnim = false;    
  1764.         bFinisher = true;
  1765.         SetBehaviorMimicVariable( 'gameplayMimicsMode', (float)(int)GMM_Death );
  1766.     }
  1767.    
  1768.     function FinisherAnimInterrupted()
  1769.     {
  1770.         bPlayDeathAnim          = true;    
  1771.         bFinisher               = false;
  1772.         bFinisherInterrupted    = true;
  1773.     }
  1774.    
  1775.     function ResetFinisherAnimInterruptionState()
  1776.     {
  1777.         bFinisherInterrupted = false;
  1778.     }
  1779.    
  1780.     function WasFinisherAnimInterrupted() : bool
  1781.     {
  1782.         return bFinisherInterrupted;
  1783.     }
  1784.    
  1785.     function FinisherAnimEnd()
  1786.     {
  1787.         bFinisher = false;
  1788.     }
  1789.    
  1790.     function ShouldPlayDeathAnim() : bool
  1791.     {
  1792.         return bPlayDeathAnim;
  1793.     }
  1794.    
  1795.     function NPCGetAgonyAnim() : CName
  1796.     {
  1797.         var agonyType : float;
  1798.         agonyType = GetBehaviorVariable( 'AgonyType');
  1799.        
  1800.         if (agonyType == (int)AT_ThroatCut)
  1801.         {
  1802.             return 'man_throat_cut_start';
  1803.         }
  1804.         else if(agonyType == (int)AT_Knockdown)
  1805.         {
  1806.             return 'man_wounded_crawl_killed';
  1807.         }
  1808.         else
  1809.             return '';
  1810.     }
  1811.    
  1812.     function GeraltGetAgonyAnim() : CName
  1813.     {
  1814.         var agonyType : float;
  1815.         agonyType = GetBehaviorVariable( 'AgonyType');
  1816.        
  1817.         if (agonyType == (int)AT_ThroatCut)
  1818.         {
  1819.             return 'man_ger_throat_cut_attack_01';
  1820.         }
  1821.         else if(agonyType == (int)AT_Knockdown)
  1822.         {
  1823.             return 'man_ger_crawl_finish';
  1824.         }
  1825.         else
  1826.             return '';
  1827.     }
  1828.    
  1829.    
  1830.    
  1831.    
  1832.    
  1833.     protected function PlayHitAnimation(damageAction : W3DamageAction, animType : EHitReactionType)
  1834.     {
  1835.         var node : CNode;
  1836.        
  1837.         SetBehaviorVariable( 'HitReactionWeapon', ProcessSwordOrFistHitReaction( this, (CActor)damageAction.attacker ) );
  1838.         SetBehaviorVariable( 'HitReactionType',(int)animType);
  1839.        
  1840.         if ( damageAction.attacker )
  1841.         {
  1842.             super.PlayHitAnimation( damageAction, animType );
  1843.             node = (CNode)damageAction.causer;
  1844.             if (node)
  1845.             {
  1846.                 SetHitReactionDirection(node);
  1847.             }
  1848.             else
  1849.             {
  1850.                 SetHitReactionDirection(damageAction.attacker);
  1851.             }
  1852.             SetDetailedHitReaction(damageAction.GetSwingType(), damageAction.GetSwingDirection());
  1853.         }
  1854.        
  1855.         if ( this.customHits )
  1856.         {
  1857.             damageAction.customHitReactionRequested = true;
  1858.         }
  1859.         else
  1860.         {
  1861.             damageAction.hitReactionAnimRequested = true;
  1862.         }
  1863.     }
  1864.    
  1865.     public function GetAbilityBuffStackedOnEnemyHitName() : name
  1866.     {
  1867.         return abilityBuffStackedOnEnemyHitName;
  1868.     }
  1869.    
  1870.     public function ReactToBeingHit(damageAction : W3DamageAction, optional buffNotApplied : bool) : bool
  1871.     {
  1872.         var ret                             : bool;
  1873.         var percentageLoss                  : float;
  1874.         var totalHealth                     : float;
  1875.         var damaveValue                     : float;
  1876.         var healthLossToForceLand_perc      : SAbilityAttributeValue;
  1877.         var witcher                         : W3PlayerWitcher;
  1878.         var node                            : CNode;
  1879.         var boltCauser                      : W3ArrowProjectile;
  1880.         var yrdenCauser                     : W3YrdenEntityStateYrdenShock;
  1881.         var attackAction                    : W3Action_Attack;
  1882.        
  1883.         damaveValue                  = damageAction.GetDamageDealt();
  1884.         totalHealth                  = GetMaxHealth();
  1885.         percentageLoss              = damaveValue / totalHealth;
  1886.         healthLossToForceLand_perc   = GetAttributeValue( 'healthLossToForceLand_perc' );
  1887.        
  1888.        
  1889.         if( percentageLoss >= healthLossToForceLand_perc.valueBase && ( GetCurrentStance() == NS_Fly || ( !IsUsingVehicle() && GetCurrentStance() != NS_Swim && !((CMovingPhysicalAgentComponent) GetMovingAgentComponent()).IsOnGround()) ) && !(damageAction.IsDoTDamage() && !damageAction.DealsAnyDamage()) )
  1890.         {
  1891.            
  1892.             if( !((CBaseGameplayEffect) damageAction.causer ) )
  1893.             {
  1894.                 damageAction.AddEffectInfo( EET_Knockdown);
  1895.             }
  1896.         }
  1897.        
  1898.        
  1899.         boltCauser = (W3ArrowProjectile)( damageAction.causer );
  1900.         yrdenCauser = (W3YrdenEntityStateYrdenShock)( damageAction.causer );
  1901.         if( boltCauser || yrdenCauser )
  1902.         {
  1903.             if( HasAbility( 'AdditiveHits' ) )
  1904.             {
  1905.                 SetUseAdditiveHit( true, GetCriticalCancelAdditiveHit(), true );
  1906.                 ret = super.ReactToBeingHit(damageAction, buffNotApplied);
  1907.                
  1908.                 if( ret || damageAction.DealsAnyDamage())
  1909.                     SignalGameplayDamageEvent('BeingHit', damageAction );
  1910.             }
  1911.             else if( HasAbility( 'mon_wild_hunt_default' ) )
  1912.             {
  1913.                 ret = false;
  1914.             }
  1915.             else if( !boltCauser.HasTag( 'bodkinbolt' ) || this.IsUsingHorse() || RandRange(100) < 75.f )
  1916.             {
  1917.                 ret = super.ReactToBeingHit(damageAction, buffNotApplied);
  1918.                
  1919.                 if( ret || damageAction.DealsAnyDamage())
  1920.                     SignalGameplayDamageEvent('BeingHit', damageAction );
  1921.             }
  1922.             else
  1923.             {
  1924.                 ret = false;
  1925.             }
  1926.         }
  1927.         else
  1928.         {
  1929.             ret = super.ReactToBeingHit(damageAction, buffNotApplied);
  1930.            
  1931.             if( ret || damageAction.DealsAnyDamage() )
  1932.                 SignalGameplayDamageEvent('BeingHit', damageAction );
  1933.         }
  1934.        
  1935.         if( damageAction.additiveHitReactionAnimRequested == true )
  1936.         {
  1937.             node = (CNode)damageAction.causer;
  1938.             if (node)
  1939.             {
  1940.                 SetHitReactionDirection(node);
  1941.             }
  1942.             else
  1943.             {
  1944.                 SetHitReactionDirection(damageAction.attacker);
  1945.             }
  1946.         }
  1947.        
  1948.         if(((CPlayer)damageAction.attacker || !((CNewNPC)damageAction.attacker)) && damageAction.DealsAnyDamage())
  1949.             theTelemetry.LogWithLabelAndValue( TE_FIGHT_ENEMY_GETS_HIT, damageAction.victim.ToString(), (int)damageAction.processedDmg.vitalityDamage + (int)damageAction.processedDmg.essenceDamage );
  1950.        
  1951.        
  1952.         witcher = GetWitcherPlayer();
  1953.         if ( damageAction.attacker == witcher && HasBuff( EET_AxiiGuardMe ) )
  1954.         {
  1955.            
  1956.             if(!witcher.CanUseSkill(S_Magic_s05) || witcher.GetSkillLevel(S_Magic_s05) < 3)
  1957.                 RemoveBuff(EET_AxiiGuardMe, true);
  1958.         }
  1959.        
  1960.         if(damageAction.attacker == thePlayer && damageAction.DealsAnyDamage() && !damageAction.IsDoTDamage())
  1961.         {
  1962.             attackAction = (W3Action_Attack) damageAction;
  1963.            
  1964.            
  1965.            
  1966.             if(SkillNameToEnum(attackAction.GetAttackTypeName()) == S_Sword_s02)
  1967.                 theGame.VibrateControllerLight();
  1968.            
  1969.            
  1970.             if(attackAction && attackAction.UsedZeroStaminaPerk())
  1971.             {
  1972.                 ForceSetStat(BCS_Stamina, 0.f);
  1973.             }
  1974.         }
  1975.        
  1976.         return ret;
  1977.     }
  1978.    
  1979.    
  1980.    
  1981.    
  1982.    
  1983.     function Kill( source : name, optional ignoreImmortalityMode : bool, optional attacker : CGameplayEntity )
  1984.     {
  1985.         var action : W3DamageAction;
  1986.        
  1987.         if ( theGame.CanLog() )
  1988.         {      
  1989.             LogDMHits( "CActor.Kill: called for actor <<" + this + ">> with source <<" + source + ">>" );
  1990.         }
  1991.        
  1992.         action = GetKillAction( source, ignoreImmortalityMode, attacker );
  1993.        
  1994.         if ( this.IsKnockedUnconscious() )
  1995.         {
  1996.             DisableDeathAndAgony();
  1997.             OnDeath(action);
  1998.         }
  1999.         else if ( !abilityManager )
  2000.         {
  2001.             OnDeath(action);
  2002.         }
  2003.         else
  2004.         {
  2005.             if ( ignoreImmortalityMode )
  2006.                 this.immortalityFlags = 0;
  2007.                
  2008.             theGame.damageMgr.ProcessAction(action);
  2009.         }
  2010.        
  2011.         delete action;
  2012.     }
  2013.    
  2014.     public final function GetLevel() : int
  2015.     {
  2016.         return (int)CalculateAttributeValue(GetAttributeValue('level',,true));
  2017.     }
  2018.    
  2019.     public final function GetLevelFromLocalVar() : int
  2020.     {
  2021.         return currentLevel;
  2022.     }
  2023.    
  2024.     function GetExperienceDifferenceLevelName( out strLevel : string ) : string
  2025.     {
  2026.         var lvlDiff : int;
  2027.         var currentLevel : int;
  2028.         var ciriEntity  : W3ReplacerCiri;
  2029.        
  2030.         currentLevel = GetLevel() + levelFakeAddon;
  2031.        
  2032.         if ( newGamePlusFakeLevelAddon )
  2033.         {
  2034.             currentLevel += theGame.params.GetNewGamePlusLevel();
  2035.         }
  2036.        
  2037.         if ( currentLevel > ( theGame.params.GetPlayerMaxLevel() + 5 ) )
  2038.         {
  2039.             currentLevel = theGame.params.GetPlayerMaxLevel() + 5;
  2040.         }      
  2041.         lvlDiff = currentLevel - thePlayer.GetLevel();
  2042.            
  2043.         if( GetAttitude( thePlayer ) != AIA_Hostile )
  2044.         {
  2045.             if( ( GetAttitudeGroup() != 'npc_charmed' ) )
  2046.             {
  2047.                 strLevel = "";
  2048.                 return "none";
  2049.             }
  2050.         }
  2051.        
  2052.         ciriEntity = (W3ReplacerCiri)thePlayer;
  2053.         if ( ciriEntity )
  2054.         {
  2055.             strLevel = "<font color=\"#66FF66\">" + currentLevel + "</font>";
  2056.             return "normalLevel";
  2057.         }
  2058.  
  2059.        
  2060.          if ( lvlDiff >= theGame.params.LEVEL_DIFF_DEADLY )
  2061.         {
  2062.             strLevel = "";
  2063.             return "deadlyLevel";
  2064.         }  
  2065.         else if ( lvlDiff >= theGame.params.LEVEL_DIFF_HIGH )
  2066.         {
  2067.             strLevel = "<font color=\"#FF1919\">" + currentLevel + "</font>";
  2068.             return "highLevel";
  2069.         }
  2070.         else if ( lvlDiff > -theGame.params.LEVEL_DIFF_HIGH )
  2071.         {
  2072.             strLevel = "<font color=\"#66FF66\">" + currentLevel + "</font>";
  2073.             return "normalLevel";
  2074.         }
  2075.         else
  2076.         {
  2077.             strLevel = "<font color=\"#E6E6E6\">" + currentLevel + "</font>";
  2078.             return "lowLevel";
  2079.         }
  2080.         return "none";
  2081.     }
  2082.    
  2083.    
  2084.     private function ShouldGiveExp(attacker : CGameplayEntity) : bool
  2085.     {
  2086.         var actor : CActor;
  2087.         var npc : CNewNPC;
  2088.         var victimAt : EAIAttitude;
  2089.         var giveExp : bool;
  2090.        
  2091.         victimAt = GetAttitudeBetween(thePlayer, this);
  2092.         giveExp = false;
  2093.        
  2094.        
  2095.         if(victimAt == AIA_Hostile)
  2096.         {
  2097.             if(attacker == thePlayer && !((W3PlayerWitcher)thePlayer) )
  2098.             {
  2099.                
  2100.                 giveExp = false;
  2101.             }
  2102.             else if(attacker == thePlayer || (GetAttitudeBetween( thePlayer, attacker ) == AIA_Friendly && VecDistance(thePlayer.GetWorldPosition(), GetWorldPosition()) <= 30) )  
  2103.             {
  2104.                
  2105.                 giveExp = true;
  2106.             }
  2107.            
  2108.             else if(VecDistance(thePlayer.GetWorldPosition(), GetWorldPosition()) <= 20)
  2109.             {
  2110.                 npc = (CNewNPC)attacker;
  2111.                 if(!npc || npc.npcGroupType != ENGT_Guard) 
  2112.                 {
  2113.                     actor = (CActor)attacker;
  2114.                     if(!actor)
  2115.                     {
  2116.                        
  2117.                         giveExp = true;
  2118.                     }
  2119.                     else if(actor.HasTag(theGame.params.TAG_NPC_IN_PARTY) || actor.HasBuff(EET_AxiiGuardMe))
  2120.                     {
  2121.                        
  2122.                         giveExp = true;
  2123.                     }                          
  2124.                 }
  2125.             }
  2126.         }
  2127.        
  2128.         return giveExp;
  2129.     }
  2130.    
  2131.     function AddBestiaryKnowledge()
  2132.     {
  2133.         var manager : CWitcherJournalManager;
  2134.         var resource : CJournalResource;
  2135.         var entryBase : CJournalBase;
  2136.        
  2137.         manager = theGame.GetJournalManager();
  2138.        
  2139.         if ( AddBestiaryKnowledgeEP2() ) return;
  2140.        
  2141.         if ( HasAbility( 'NoJournalEntry' )) return; else
  2142.         if ( GetSfxTag() == 'sfx_arachas' && HasAbility('mon_arachas_armored') )    activateBaseBestiaryEntryWithAlias("BestiaryArmoredArachas", manager); else
  2143.         if ( GetSfxTag() == 'sfx_arachas' && HasAbility('mon_poison_arachas')  )    activateBaseBestiaryEntryWithAlias("BestiaryPoisonousArachas", manager); else
  2144.         if ( GetSfxTag() == 'sfx_bear' )                                            activateBaseBestiaryEntryWithAlias("BestiaryBear", manager); else
  2145.         if ( GetSfxTag() == 'sfx_alghoul' )                                         activateBaseBestiaryEntryWithAlias("BestiaryAlghoul", manager); else
  2146.         if ( HasAbility('mon_greater_miscreant') )                                  activateBaseBestiaryEntryWithAlias("BestiaryMiscreant", manager); else
  2147.         if ( HasAbility('mon_basilisk') )                                           activateBaseBestiaryEntryWithAlias("BestiaryBasilisk", manager); else
  2148.         if ( HasAbility('mon_boar_base') )                                         
  2149.         {
  2150.             resource = (CJournalResource)LoadResource( "BestiaryBoarEP2" );
  2151.             if ( resource )
  2152.             {
  2153.                 entryBase = resource.GetEntry();
  2154.                 if ( entryBase )
  2155.                 {
  2156.                     if ( manager.GetEntryStatus( entryBase ) == JS_Inactive )
  2157.                     {
  2158.                         activateBaseBestiaryEntryWithAlias("BestiaryBoar", manager);
  2159.                     }
  2160.                 }
  2161.             }
  2162.         } else
  2163.         if ( HasAbility('mon_black_spider_base') )
  2164.         {
  2165.             resource = (CJournalResource)LoadResource( "BestiarySpiderEP2" );
  2166.             if ( resource )
  2167.             {
  2168.                 entryBase = resource.GetEntry();
  2169.                 if ( entryBase )
  2170.                 {
  2171.                     if ( manager.GetEntryStatus( entryBase ) == JS_Inactive )
  2172.                     {
  2173.                         activateBaseBestiaryEntryWithAlias("BestiarySpider", manager);
  2174.                     }
  2175.                 }
  2176.             }
  2177.         } else
  2178.         if ( HasAbility('mon_toad_base') )                                          activateBaseBestiaryEntryWithAlias("BestiaryToad", manager); else
  2179.         if ( HasAbility('q604_caretaker') )                                         activateBaseBestiaryEntryWithAlias("Bestiarycaretaker", manager); else
  2180.         if ( HasAbility('mon_nightwraith_iris') )                                   activateBaseBestiaryEntryWithAlias("BestiaryIris", manager); else
  2181.         if ( GetSfxTag() == 'sfx_cockatrice' )                                      activateBaseBestiaryEntryWithAlias("BestiaryCockatrice", manager); else
  2182.         if ( GetSfxTag() == 'sfx_arachas' && !HasAbility('mon_arachas_armored') && !HasAbility('mon_poison_arachas') ) activateBaseBestiaryEntryWithAlias("BestiaryCrabSpider", manager); else
  2183.         if ( GetSfxTag() == 'sfx_katakan' && HasAbility('mon_ekimma') )             activateBaseBestiaryEntryWithAlias("BestiaryEkkima", manager); else
  2184.         if ( GetSfxTag() == 'sfx_elemental_dao' )                                   activateBaseBestiaryEntryWithAlias("BestiaryElemental", manager); else
  2185.         if ( GetSfxTag() == 'sfx_endriaga' && HasAbility('mon_endriaga_soldier_tailed') ) activateBaseBestiaryEntryWithAlias("BestiaryEndriaga", manager); else
  2186.         if ( GetSfxTag() == 'sfx_endriaga' && HasAbility('mon_endriaga_worker') )   activateBaseBestiaryEntryWithAlias("BestiaryEndriagaWorker", manager); else
  2187.         if ( GetSfxTag() == 'sfx_endriaga' && HasAbility('mon_endriaga_soldier_spikey') ) activateBaseBestiaryEntryWithAlias("BestiaryEndriagaTruten", manager); else
  2188.         if ( HasAbility('mon_forktail_young') || HasAbility('mon_forktail') || HasAbility('mon_forktail_mh') ) activateBaseBestiaryEntryWithAlias("BestiaryForktail", manager); else
  2189.         if ( GetSfxTag() == 'sfx_ghoul' )                                       activateBaseBestiaryEntryWithAlias("BestiaryGhoul", manager); else
  2190.         if ( GetSfxTag() == 'sfx_golem' )                                       activateBaseBestiaryEntryWithAlias("BestiaryGolem", manager); else
  2191.         if ( GetSfxTag() == 'sfx_katakan' && !HasAbility('mon_ekimma') )        activateBaseBestiaryEntryWithAlias("BestiaryKatakan", manager); else
  2192.         if ( GetSfxTag() == 'sfx_ghoul' && HasAbility('mon_greater_miscreant') )    activateBaseBestiaryEntryWithAlias("BestiaryMiscreant", manager); else
  2193.         if ( HasAbility('mon_nightwraith')|| HasAbility('mon_nightwraith_mh') ) activateBaseBestiaryEntryWithAlias("BestiaryMoonwright", manager); else
  2194.         if ( HasAbility('mon_noonwraith') && !HasAbility('mon_noonwraith_doppelganger') )   activateBaseBestiaryEntryWithAlias("BestiaryNoonwright", manager); else
  2195.         if ( HasAbility('mon_lycanthrope') )                                    activateBaseBestiaryEntryWithAlias("BestiaryLycanthrope", manager); else
  2196.         if ( GetSfxTag() == 'sfx_werewolf' )                                    activateBaseBestiaryEntryWithAlias("BestiaryWerewolf", manager); else
  2197.         if ( GetSfxTag() == 'sfx_wyvern' )                                      activateBaseBestiaryEntryWithAlias("BestiaryWyvern", manager); else
  2198.         if ( HasAbility('mon_czart') )                                          activateBaseBestiaryEntryWithAlias("BestiaryCzart", manager); else
  2199.         if ( GetSfxTag() == 'sfx_bies' )                                        activateBaseBestiaryEntryWithAlias("BestiaryBies", manager); else
  2200.         if ( GetSfxTag() == 'sfx_wild_dog' )                                    activateBaseBestiaryEntryWithAlias("BestiaryDog", manager); else
  2201.         if ( GetSfxTag() == 'sfx_drowner' )                                     activateBaseBestiaryEntryWithAlias("BestiaryDrowner", manager);  else
  2202.         if ( GetSfxTag() == 'sfx_elemental_ifryt' )                             activateBaseBestiaryEntryWithAlias("BestiaryFireElemental", manager); else
  2203.         if ( GetSfxTag() == 'sfx_fogling' )                                     activateBaseBestiaryEntryWithAlias("BestiaryFogling", manager); else
  2204.         if ( GetSfxTag() == 'sfx_gravehag' )                                    activateBaseBestiaryEntryWithAlias("BestiaryGraveHag", manager); else
  2205.         if ( GetSfxTag() == 'sfx_gryphon' )                                     activateBaseBestiaryEntryWithAlias("BestiaryGriffin", manager); else
  2206.         if ( HasAbility('mon_erynia') )                                         activateBaseBestiaryEntryWithAlias("BestiaryErynia", manager); else
  2207.         if ( GetSfxTag() == 'sfx_harpy' )                                       activateBaseBestiaryEntryWithAlias("BestiaryHarpy", manager); else
  2208.         if ( GetSfxTag() == 'sfx_ice_giant' )                                   activateBaseBestiaryEntryWithAlias("BestiaryIceGiant", manager); else
  2209.         if ( GetSfxTag() == 'sfx_lessog' )                                      activateBaseBestiaryEntryWithAlias("BestiaryLeshy", manager); else
  2210.         if ( GetSfxTag() == 'sfx_nekker' )                                      activateBaseBestiaryEntryWithAlias("BestiaryNekker", manager); else
  2211.         if ( GetSfxTag() == 'sfx_siren' )                                       activateBaseBestiaryEntryWithAlias("BestiarySiren", manager); else
  2212.         if ( HasTag('ice_troll') )                                              activateBaseBestiaryEntryWithAlias("BestiaryIceTroll", manager); else
  2213.         if ( GetSfxTag() == 'sfx_troll_cave' )                                  activateBaseBestiaryEntryWithAlias("BestiaryCaveTroll", manager); else
  2214.         if ( GetSfxTag() == 'sfx_waterhag' )                                    activateBaseBestiaryEntryWithAlias("BestiaryWaterHag", manager); else
  2215.         if ( GetSfxTag() == 'sfx_wildhunt_minion' )                             activateBaseBestiaryEntryWithAlias("BestiaryWhMinion", manager); else
  2216.         if ( GetSfxTag() == 'sfx_wolf' )                                        activateBaseBestiaryEntryWithAlias("BestiaryWolf", manager); else
  2217.         if ( GetSfxTag() == 'sfx_wraith' )                                      activateBaseBestiaryEntryWithAlias("BestiaryWraith", manager); else
  2218.         if ( HasAbility('mon_cyclops') )                                        activateBaseBestiaryEntryWithAlias("BestiaryCyclop", manager); else
  2219.         if ( HasAbility('mon_ice_golem') )                                      activateBaseBestiaryEntryWithAlias("BestiaryIceGolem", manager); else
  2220.         if ( HasAbility('mon_gargoyle') )                                       activateBaseBestiaryEntryWithAlias("BestiaryGargoyle", manager); else
  2221.         if ( HasAbility('mon_rotfiend') || HasAbility('mon_rotfiend_large'))    activateBaseBestiaryEntryWithAlias("BestiaryGreaterRotFiend", manager); else
  2222.         if ( HasAbility('mon_gravier') )                                        activateJournalBestiaryEntryWithAlias("BestiaryGraveir", manager);
  2223.     }
  2224.    
  2225.     function AddBestiaryKnowledgeEP2() : bool
  2226.     {
  2227.         var manager : CWitcherJournalManager;
  2228.         var resource : CJournalResource;
  2229.         var entryBase : CJournalBase;
  2230.         manager = theGame.GetJournalManager();
  2231.        
  2232.         if ( HasAbility('mon_mq7010_dracolizard') )                                     { activateBaseBestiaryEntryWithAlias("BestiaryDracolizardMatriarch", manager); return true; } else
  2233.         if ( HasAbility('mon_draco_base') )                                             { activateBaseBestiaryEntryWithAlias("BestiaryDracolizard", manager); return true; } else
  2234.         if ( HasAbility('mon_sprigan') )                                                { activateBaseBestiaryEntryWithAlias("BestiarySpriggan", manager); return true; } else
  2235.         if ( HasAbility('mon_garkain') )                                                { activateBaseBestiaryEntryWithAlias("BestiaryGarkain", manager); return true; } else
  2236.         if ( HasAbility('mon_panther_base') && !HasAbility('mon_panther_ghost') )       { activateBaseBestiaryEntryWithAlias("BestiaryPanther", manager); return true; } else
  2237.         if ( HasAbility('mon_sharley_base') )                                           { activateBaseBestiaryEntryWithAlias("BestiarySharley", manager); return true; } else
  2238.         if ( HasAbility('mon_barghest_base') )                                          { activateBaseBestiaryEntryWithAlias("BestiaryBarghest", manager); return true; } else
  2239.         if ( HasAbility('mon_bruxa') )                                                  { activateBaseBestiaryEntryWithAlias("BestiaryBruxa", manager); return true; } else
  2240.         if ( HasAbility('mon_fleder') )                                                 { activateBaseBestiaryEntryWithAlias("BestiaryFleder", manager); return true; } else
  2241.         if ( HasAbility('q704_mon_protofleder') )                                       { activateBaseBestiaryEntryWithAlias("BestiaryProtofleder", manager); return true; } else
  2242.         if ( HasAbility('mon_alp') )                                                    { activateBaseBestiaryEntryWithAlias("BestiaryAlp", manager); return true; } else
  2243.         if ( HasTag('mq7023_pale_widow') )                                              { activateBaseBestiaryEntryWithAlias("BestiaryPaleWidow", manager); return true; } else
  2244.         if ( HasAbility('mon_scolopendromorph_base') )                                  { activateBaseBestiaryEntryWithAlias("BestiaryScolopendromorph", manager); return true; } else
  2245.         if ( HasAbility('mon_kikimora_warrior') )                                       { activateBaseBestiaryEntryWithAlias("BestiaryKikimoraWarrior", manager); return true; } else
  2246.         if ( HasAbility('mon_kikimora_worker') )                                        { activateBaseBestiaryEntryWithAlias("BestiaryKikimoraWorker", manager); return true; } else
  2247.         if ( HasAbility('mon_archespor_base') )                                         { activateBaseBestiaryEntryWithAlias("BestiaryArchespore", manager); return true; } else
  2248.         if ( HasAbility('mon_dark_pixie_base') || HasAbility('mon_q704_ft_pixies') )    { activateBaseBestiaryEntryWithAlias("BestiaryDarkPixie", manager); return true; } else
  2249.         if ( HasAbility('mon_graveir') )                                                { activateBaseBestiaryEntryWithAlias("BestiaryDarkPixie", manager); return true; } else
  2250.         if ( HasAbility('mon_wight') )                                                  { activateBaseBestiaryEntryWithAlias("BestiaryWicht", manager); return true; } else
  2251.         if ( HasAbility('mon_knight_giant') )                                           { activateBaseBestiaryEntryWithAlias("BestiaryDagonet", manager); return true; } else
  2252.         if ( HasAbility('mon_q704_ft_wilk') )                                           { activateBaseBestiaryEntryWithAlias("BestiaryBigBadWolf", manager); return true; } else
  2253.         if ( HasAbility('mon_q704_ft_pigs_evil') )                                      { activateBaseBestiaryEntryWithAlias("BestiaryPigsEvil", manager); return true; } else
  2254.         if ( HasAbility('mon_mq7018_basilisk') )                                        { activateBaseBestiaryEntryWithAlias("BestiaryLastBasilisk", manager); return true; } else
  2255.         if ( HasAbility('mon_fairytale_witch') )                                        { activateBaseBestiaryEntryWithAlias("BestiaryFairtaleWitch", manager); return true; } else
  2256.         if ( HasAbility('banshee_rapunzel') )                                           { activateBaseBestiaryEntryWithAlias("BestiaryRapunzel", manager); return true; } else
  2257.         if ( HasAbility('mon_nightwraith_banshee') )                                    { activateBaseBestiaryEntryWithAlias("BestiaryBeanshie", manager); return true; } else
  2258.         if ( HasAbility('mon_black_spider_ep2_base') )                                 
  2259.         {
  2260.             resource = (CJournalResource)LoadResource( "BestiarySpider" );
  2261.             if ( resource )
  2262.             {
  2263.                 entryBase = resource.GetEntry();
  2264.                 if ( entryBase )
  2265.                 {
  2266.                     if ( manager.GetEntryStatus( entryBase ) == JS_Inactive )
  2267.                     {
  2268.                         activateBaseBestiaryEntryWithAlias("BestiarySpiderEP2", manager);
  2269.                         return true;
  2270.                     }
  2271.                 }
  2272.             }
  2273.         } else
  2274.         if ( HasAbility('mon_boar_ep2_base') )                                         
  2275.         {
  2276.             resource = (CJournalResource)LoadResource( "BestiaryBoar" );
  2277.             if ( resource )
  2278.             {
  2279.                 entryBase = resource.GetEntry();
  2280.                 if ( entryBase )
  2281.                 {
  2282.                     if ( manager.GetEntryStatus( entryBase ) == JS_Inactive )
  2283.                     {
  2284.                         activateBaseBestiaryEntryWithAlias("BestiaryBoarEP2", manager);
  2285.                         return true;
  2286.                     }
  2287.                 }
  2288.             }
  2289.         } else
  2290.         if ( HasAbility('mon_cloud_giant') )                                            { activateBaseBestiaryEntryWithAlias("BestiaryCloudGiant", manager); return true; }
  2291.        
  2292.         return false;
  2293.        
  2294.     }
  2295.    
  2296.    
  2297.     public function CalculateExperiencePoints(optional skipLog : bool) : int
  2298.     {
  2299.         var finalExp : int;
  2300.         var exp : float;
  2301.         var lvlDiff : int;
  2302.         var modDamage, modArmor, modVitality, modOther : float;
  2303.         var stats : CCharacterStats;
  2304.        
  2305.         if ( grantNoExperienceAfterKill || HasAbility('Zero_XP' ) || GetNPCType() == ENGT_Guard ) return 0;
  2306.        
  2307.         modDamage = CalculateAttributeValue(GetAttributeValue('RendingDamage',,true));
  2308.         modDamage += CalculateAttributeValue(GetAttributeValue('BludgeoningDamage',,true));
  2309.         modDamage += CalculateAttributeValue(GetAttributeValue('FireDamage',,true));
  2310.         modDamage += CalculateAttributeValue(GetAttributeValue('ElementalDamage',,true));
  2311.         modDamage += CalculateAttributeValue(GetPowerStatValue(CPS_AttackPower, , true));
  2312.         modDamage *= 5;
  2313.        
  2314.         modArmor = CalculateAttributeValue(GetTotalArmor()) * 100;
  2315.        
  2316.         modVitality = GetStatMax(BCS_Essence) + 3 * GetStatMax(BCS_Vitality);
  2317.        
  2318.         stats = GetCharacterStats();
  2319.  
  2320.         if ( stats.HasAbility('AcidSpit' ) ) modOther = modOther + 2;
  2321.         if ( stats.HasAbility('Aggressive' ) ) modOther = modOther + 2;
  2322.         if ( stats.HasAbility('Charge' ) ) modOther = modOther + 3;
  2323.         if ( stats.HasAbility('ContactBlindness' ) ) modOther = modOther + 2;
  2324.         if ( stats.HasAbility('ContactSlowdown' ) ) modOther = modOther + 2;
  2325.         if ( stats.HasAbility('Cursed' ) ) modOther = modOther + 2;
  2326.         if ( stats.HasAbility('BurnIgnore' ) ) modOther = modOther + 2;
  2327.         if ( stats.HasAbility('DamageBuff' ) ) modOther = modOther + 2;
  2328.         if ( stats.HasAbility('Draconide' ) ) modOther = modOther + 2;
  2329.         if ( stats.HasAbility('Fireball' ) ) modOther = modOther + 2;
  2330.         if ( stats.HasAbility('Flashstep' ) ) modOther = modOther + 2;
  2331.         if ( stats.HasAbility('Flying' ) ) modOther = modOther + 10;
  2332.         if ( stats.HasAbility('Frost' ) ) modOther = modOther + 4;
  2333.         if ( stats.HasAbility('EssenceRegen' ) ) modOther = modOther + 2;
  2334.         if ( stats.HasAbility('Gargoyle' ) ) modOther = modOther + 2;
  2335.         if ( stats.HasAbility('Hypnosis' ) ) modOther = modOther + 2;
  2336.         if ( stats.HasAbility('IceArmor' ) ) modOther = modOther + 5;
  2337.         if ( stats.HasAbility('InstantKillImmune' ) ) modOther = modOther + 2;
  2338.         if ( stats.HasAbility('JumpAttack' ) ) modOther = modOther + 2;
  2339.         if ( stats.HasAbility('Magical' ) ) modOther = modOther + 2;
  2340.         if ( stats.HasAbility('MistForm' ) ) modOther = modOther + 2;
  2341.         if ( stats.HasAbility('MudTeleport' ) ) modOther = modOther + 2;
  2342.         if ( stats.HasAbility('MudAttack' ) ) modOther = modOther + 2;
  2343.         if ( stats.HasAbility('PoisonCloud' ) ) modOther = modOther + 2;
  2344.         if ( stats.HasAbility('PoisonDeath' ) ) modOther = modOther + 2;
  2345.         if ( stats.HasAbility('Rage' ) ) modOther = modOther + 2;
  2346.         if ( stats.HasAbility('Relic' ) ) modOther = modOther + 5;
  2347.         if ( stats.HasAbility('Scream' ) ) modOther = modOther + 2;
  2348.         if ( stats.HasAbility('Shapeshifter' ) ) modOther = modOther + 5;
  2349.         if ( stats.HasAbility('Shout' ) ) modOther = modOther + 2;
  2350.         if ( stats.HasAbility('Spikes' ) ) modOther = modOther + 2;
  2351.         if ( stats.HasAbility('StaggerCounter' ) ) modOther = modOther + 2;
  2352.         if ( stats.HasAbility('StinkCloud' ) ) modOther = modOther + 2;
  2353.         if ( stats.HasAbility('Summon' ) ) modOther = modOther + 2;
  2354.         if ( stats.HasAbility('Tail' ) ) modOther = modOther + 5;
  2355.         if ( stats.HasAbility('Teleport' ) ) modOther = modOther + 5;
  2356.         if ( stats.HasAbility('Thorns' ) ) modOther = modOther + 2;
  2357.         if ( stats.HasAbility('Throw' ) ) modOther = modOther + 2;
  2358.         if ( stats.HasAbility('ThrowFire' ) ) modOther = modOther + 2;
  2359.         if ( stats.HasAbility('ThrowIce' ) ) modOther = modOther + 2;
  2360.         if ( stats.HasAbility('Vampire' ) ) modOther = modOther + 2;
  2361.         if ( stats.HasAbility('Venom' ) ) modOther = modOther + 2;
  2362.         if ( stats.HasAbility('VitalityRegen' ) ) modOther = modOther + 5;
  2363.         if ( stats.HasAbility('Wave' ) ) modOther = modOther + 2;
  2364.         if ( stats.HasAbility('WeakToAard' ) ) modOther = modOther - 2;
  2365.         if ( stats.HasAbility('TongueAttack' ) ) modOther = modOther + 2;
  2366.        
  2367.         exp = ( modDamage + modArmor + modVitality + modOther ) / 99;
  2368.        
  2369.         if( thePlayer.GetEnemyUpscaling() && npcLevelToUpscaledLevelDifference > 0 ) currentLevel -= npcLevelToUpscaledLevelDifference;
  2370.         if( FactsQuerySum("NewGamePlus") > 0 ) currentLevel -= theGame.params.GetNewGamePlusLevel();
  2371.        
  2372.         if  ( IsHuman() )
  2373.         {
  2374.             if ( exp > 1 + ( currentLevel * 2 ) ) { exp = 1 + ( currentLevel * 2 ); }
  2375.         } else
  2376.         {
  2377.             if ( exp > 5 + ( currentLevel * 4 ) ) { exp = 5 + ( currentLevel * 4 ); }
  2378.         }
  2379.                
  2380.        
  2381.         exp += 1;
  2382.        
  2383.         if( ( FactsQuerySum("NewGamePlus") > 0 ) )
  2384.         {
  2385.             if ( thePlayer.GetLevel() - theGame.params.GetNewGamePlusLevel() < 30 ) exp = ( exp / 4 ); else exp = ( exp / 2 );
  2386.         }
  2387.         else if ( thePlayer.GetLevel() < 30 ) exp = ( exp / 4 ); else exp = ( exp / 2 );
  2388.                
  2389.        
  2390.        
  2391.         if( ( FactsQuerySum("NewGamePlus") > 0 ) )
  2392.             lvlDiff = currentLevel - thePlayer.GetLevel() + theGame.params.GetNewGamePlusLevel();
  2393.         else
  2394.             lvlDiff = currentLevel - thePlayer.GetLevel();
  2395.         if      ( lvlDiff >= theGame.params.LEVEL_DIFF_DEADLY ) { exp = 25 + exp * 1.5; }  
  2396.         else if ( lvlDiff >= theGame.params.LEVEL_DIFF_HIGH )  { exp = exp * 1.05; }
  2397.         else if ( lvlDiff > -theGame.params.LEVEL_DIFF_HIGH )  { }
  2398.         else { exp = 2; }
  2399.        
  2400.        
  2401.         if ( (FactsQuerySum("NewGamePlus") > 0 && thePlayer.GetLevel() >= (35 + theGame.params.GetNewGamePlusLevel()) ) || (FactsQuerySum("NewGamePlus") < 1 && thePlayer.GetLevel() >= 35) )
  2402.         {
  2403.             if ( thePlayer.GetLevel() < 45 || lvlDiff < 0 )
  2404.                 exp = exp * (1 + lvlDiff * theGame.params.LEVEL_DIFF_XP_MOD);
  2405.             exp /= 2;
  2406.             if (exp < 2) exp = 2;
  2407.         }
  2408.        
  2409.         if ( exp > 50 ) exp = 50;
  2410.         if ( theGame.GetDifficultyMode() == EDM_Easy ) exp = exp * 1.2; else
  2411.         if ( theGame.GetDifficultyMode() == EDM_Hard ) exp = exp * 0.9; else
  2412.         if ( theGame.GetDifficultyMode() == EDM_Hardcore ) exp = exp * 0.8;
  2413.         finalExp = RoundF( exp );
  2414.        
  2415.         if(!skipLog)
  2416.         {
  2417.             LogStats("--------------------------------");
  2418.             LogStats("-      [CALCULATED EXP]        -");
  2419.             LogStats("- base, without difficulty and -");
  2420.             LogStats("-   level difference bonuses   -");
  2421.             LogStats("--------------------------------");
  2422.             LogStats(" -> for entity : " + GetName());
  2423.             LogStats("--------------------------------");
  2424.             LogStats("* modDamage : " + modDamage);
  2425.             LogStats("* modArmor : " + modArmor);
  2426.             LogStats("* modVitality : " + modVitality);
  2427.             LogStats("+ modOther : " + modOther);
  2428.             LogStats("--------------------------------");
  2429.             LogStats(" BASE EXPERIENCE POINTS = [ " + finalExp + " ]");
  2430.             LogStats("--------------------------------");
  2431.         }
  2432.        
  2433.         return finalExp;
  2434.     }
  2435.    
  2436.    
  2437.     timer function StopMutation6FX( dt : float, id : int )
  2438.     {
  2439.         StopEffect( 'critical_frozen' );
  2440.     }
  2441.    
  2442.     event OnDeath( damageAction : W3DamageAction  )
  2443.     {      
  2444.         var inWater, fists, tmpBool, addAbility, isFinisher : bool;    
  2445.         var expPoints, npcLevel, lvlDiff, i, j, swank       : int;
  2446.         var abilityName, tmpName                            : name;
  2447.         var abilityCount, maxStack, minDist                 : float;
  2448.         var itemExpBonus, radius                            : float;
  2449.        
  2450.         var allItems                                        : array<SItemUniqueId>;
  2451.         var damages                                         : array<SRawDamage>;
  2452.         var atts                                            : array<name>;
  2453.         var entities                                        : array< CGameplayEntity >;
  2454.        
  2455.         var params                                          : SCustomEffectParams;
  2456.         var dmg                                             : SRawDamage;
  2457.         var weaponID                                        : SItemUniqueId;
  2458.         var min, max, bonusExp                              : SAbilityAttributeValue;
  2459.  
  2460.         var monsterCategory                                 : EMonsterCategory;
  2461.         var attitudeToPlayer                                : EAIAttitude;
  2462.        
  2463.         var actor , targetEntity                            : CActor;
  2464.         var gameplayEffect                                  : CBaseGameplayEffect;
  2465.         var fxEnt                                           : CEntity;
  2466.        
  2467.         var attackAction                                    : W3Action_Attack; 
  2468.         var ciriEntity                                      : W3ReplacerCiri;
  2469.         var witcher                                         : W3PlayerWitcher;
  2470.         var blizzard                                        : W3Potion_Blizzard;
  2471.         var act                                             : W3DamageAction;
  2472.         var burningCauser                                   : W3Effect_Burning;
  2473.         var vfxEnt                                          : W3VisualFx;
  2474.         var aerondight                                      : W3Effect_Aerondight;
  2475.        
  2476.        
  2477.         var damageAttr                                      : SAbilityAttributeValue;
  2478.         var inv                                             : CInventoryComponent;
  2479.         var weaponId                                        : SItemUniqueId;
  2480.         var damageNames                                     : array < CName >;
  2481.         var damageValue                                     : float;
  2482.         var attribute                                       : name;
  2483.        
  2484.  
  2485.         ciriEntity = (W3ReplacerCiri)thePlayer;
  2486.         witcher = GetWitcherPlayer();
  2487.        
  2488.         deathTimestamp = theGame.GetEngineTimeAsSeconds();
  2489.        
  2490.        
  2491.         if( damageAction.GetBuffSourceName() == "Mutation 6" )
  2492.         {
  2493.             PlayEffect( 'critical_frozen' );
  2494.             AddTimer( 'StopMutation6FX', 3.f );
  2495.         }
  2496.        
  2497.         if ( (thePlayer.HasAbility('Glyphword 10 _Stats', true) || thePlayer.HasAbility('Glyphword 18 _Stats', true)) && (HasBuff(EET_AxiiGuardMe) || HasBuff(EET_Confusion)) )
  2498.         {
  2499.             if(thePlayer.HasAbility('Glyphword 10 _Stats', true))
  2500.                 abilityName = 'Glyphword 10 _Stats';
  2501.             else
  2502.                 abilityName = 'Glyphword 18 _Stats';
  2503.                
  2504.             min = thePlayer.GetAbilityAttributeValue(abilityName, 'glyphword_range');
  2505.             FindGameplayEntitiesInRange(entities, this, CalculateAttributeValue(min), 10,, FLAG_OnlyAliveActors + FLAG_ExcludeTarget, this);    
  2506.            
  2507.             minDist = 10000;
  2508.             for (i = 0; i < entities.Size(); i += 1)
  2509.             {
  2510.                 if ( entities[i] == thePlayer.GetHorseWithInventory() || entities[i] == thePlayer || !IsRequiredAttitudeBetween(thePlayer, entities[i], true) )
  2511.                     continue;
  2512.                    
  2513.                 if ( VecDistance2D(this.GetWorldPosition(), entities[i].GetWorldPosition()) < minDist)
  2514.                 {
  2515.                     minDist = VecDistance2D(this.GetWorldPosition(), entities[i].GetWorldPosition());
  2516.                     targetEntity = (CActor)entities[i];
  2517.                 }
  2518.             }
  2519.            
  2520.             if ( targetEntity )
  2521.             {
  2522.                 if ( HasBuff(EET_AxiiGuardMe) )
  2523.                     gameplayEffect = GetBuff(EET_AxiiGuardMe);
  2524.                 else if ( HasBuff(EET_Confusion) )
  2525.                     gameplayEffect = GetBuff(EET_Confusion);
  2526.                
  2527.                 params.effectType               = gameplayEffect.GetEffectType();
  2528.                 params.creator                  = gameplayEffect.GetCreator();
  2529.                 params.sourceName               = gameplayEffect.GetSourceName();
  2530.                 params.duration                 = gameplayEffect.GetDurationLeft();
  2531.                 if ( params.duration < 5.0f )   params.duration = 5.0f;
  2532.                 params.effectValue              = gameplayEffect.GetEffectValue();
  2533.                 params.customAbilityName        = gameplayEffect.GetAbilityName();
  2534.                 params.customFXName             = gameplayEffect.GetTargetEffectName();
  2535.                 params.isSignEffect             = gameplayEffect.IsSignEffect();
  2536.                 params.customPowerStatValue     = gameplayEffect.GetCreatorPowerStat();
  2537.                 params.vibratePadLowFreq        = gameplayEffect.GetVibratePadLowFreq();
  2538.                 params.vibratePadHighFreq       = gameplayEffect.GetVibratePadHighFreq();
  2539.                
  2540.                 targetEntity.AddEffectCustom(params);
  2541.                 gameplayEffect = targetEntity.GetBuff(params.effectType);
  2542.                 gameplayEffect.SetTimeLeft(params.duration);
  2543.                
  2544.                 fxEnt = CreateFXEntityAtPelvis( 'glyphword_10_18', true );
  2545.                 fxEnt.PlayEffect('out');
  2546.                 fxEnt.DestroyAfter(5);
  2547.                
  2548.                 fxEnt = targetEntity.CreateFXEntityAtPelvis( 'glyphword_10_18', true );
  2549.                 fxEnt.PlayEffect('in');
  2550.                 fxEnt.DestroyAfter(5);
  2551.             }
  2552.         }
  2553.        
  2554.         super.OnDeath( damageAction );
  2555.        
  2556.         if (!IsHuman() && (damageAction.attacker == thePlayer || GetAttitudeBetween( thePlayer, damageAction.attacker ) == AIA_Friendly) && !ciriEntity && !HasTag('NoBestiaryEntry') ) AddBestiaryKnowledge();
  2557.        
  2558.         if ( !WillBeUnconscious() && !HasTag( 'NoHitFx' ) )
  2559.         {
  2560.             if ( theGame.GetWorld().GetWaterDepth( this.GetWorldPosition() ) > 0 )
  2561.             {
  2562.                 if ( this.HasEffect( 'water_death' ) ) this.PlayEffectSingle( 'water_death' );
  2563.             }
  2564.             else
  2565.             {
  2566.                 if ( this.HasEffect( 'blood_spill' ) && !HasAbility ( 'NoBloodSpill' ) ) this.PlayEffectSingle( 'blood_spill' );
  2567.             }
  2568.         }
  2569.        
  2570.        
  2571.         if ( ( ( CMovingPhysicalAgentComponent ) this.GetMovingAgentComponent() ).HasRagdoll() )
  2572.         {
  2573.             SetBehaviorVariable('HasRagdoll', 1 );
  2574.         }
  2575.        
  2576.        
  2577.         if ( (W3AardProjectile)( damageAction.causer ) )
  2578.         {
  2579.             DropItemFromSlot( 'r_weapon' );
  2580.             DropItemFromSlot( 'l_weapon' );
  2581.             this.BreakAttachment();
  2582.         }
  2583.        
  2584.         SignalGameplayEventParamObject( 'OnDeath', damageAction );
  2585.         theGame.GetBehTreeReactionManager().CreateReactionEvent( this, 'BattlecryGroupDeath', 1.0f, 20.0f, -1.0f, 1 );
  2586.        
  2587.         attackAction = (W3Action_Attack)damageAction;
  2588.        
  2589.        
  2590.         if ( ((CMovingPhysicalAgentComponent)GetMovingAgentComponent()).GetSubmergeDepth() < 0 )
  2591.         {
  2592.             inWater = true;
  2593.             DisableAgony();
  2594.         }
  2595.        
  2596.        
  2597.         if( IsUsingHorse() )
  2598.         {
  2599.             SoundEvent( "cmb_play_hit_heavy" );
  2600.             SoundEvent( "grunt_vo_death" );
  2601.         }
  2602.                        
  2603.         if(damageAction.attacker == thePlayer && ((W3PlayerWitcher)thePlayer) && thePlayer.GetStat(BCS_Toxicity) > 0 && thePlayer.CanUseSkill(S_Alchemy_s17))
  2604.         {
  2605.             thePlayer.AddAbilityMultiple( SkillEnumToName(S_Alchemy_s17), thePlayer.GetSkillLevel(S_Alchemy_s17) );
  2606.         }
  2607.        
  2608.         OnChangeDyingInteractionPriorityIfNeeded();
  2609.        
  2610.         actor = (CActor)damageAction.attacker;
  2611.        
  2612.        
  2613.         if(ShouldGiveExp(damageAction.attacker))
  2614.         {
  2615.             npcLevel = (int)CalculateAttributeValue(GetAttributeValue('level',,true));
  2616.             lvlDiff = npcLevel - witcher.GetLevel();
  2617.             expPoints = CalculateExperiencePoints();
  2618.            
  2619.            
  2620.             if(expPoints > 0)
  2621.             {              
  2622.                 theGame.GetMonsterParamsForActor(this, monsterCategory, tmpName, tmpBool, tmpBool, tmpBool);
  2623.                 if(MonsterCategoryIsMonster(monsterCategory))
  2624.                 {
  2625.                     bonusExp = thePlayer.GetAttributeValue('nonhuman_exp_bonus_when_fatal');
  2626.                 }
  2627.                 else
  2628.                 {
  2629.                     bonusExp = thePlayer.GetAttributeValue('human_exp_bonus_when_fatal');
  2630.                 }              
  2631.                
  2632.                 expPoints = RoundMath( expPoints * (1 + CalculateAttributeValue(bonusExp)) );
  2633.                
  2634.                 witcher.AddPoints(EExperiencePoint, RoundF( expPoints * theGame.expGlobalMod_kills ), false );
  2635.             }          
  2636.         }
  2637.                
  2638.        
  2639.         attitudeToPlayer = GetAttitudeBetween(this, thePlayer);
  2640.        
  2641.         if(attitudeToPlayer == AIA_Hostile && !HasTag('AchievementKillDontCount'))
  2642.         {
  2643.            
  2644.             if(actor && actor.HasBuff(EET_AxiiGuardMe))
  2645.             {
  2646.                 theGame.GetGamerProfile().IncStat(ES_CharmedNPCKills);
  2647.                 FactsAdd("statistics_cerberus_sign");
  2648.             }
  2649.            
  2650.            
  2651.             if( aardedFlight && damageAction.GetBuffSourceName() == "FallingDamage" )
  2652.             {
  2653.                 theGame.GetGamerProfile().IncStat(ES_AardFallKills);
  2654.             }
  2655.                
  2656.            
  2657.             if(damageAction.IsActionEnvironment())
  2658.             {
  2659.                 theGame.GetGamerProfile().IncStat(ES_EnvironmentKills);
  2660.                 FactsAdd("statistics_cerberus_environment");
  2661.             }
  2662.         }
  2663.        
  2664.        
  2665.         if(HasTag('cow'))
  2666.         {
  2667.             if( (damageAction.attacker == thePlayer) ||
  2668.                 ((W3SignEntity)damageAction.attacker && ((W3SignEntity)damageAction.attacker).GetOwner() == thePlayer) ||
  2669.                 ((W3SignProjectile)damageAction.attacker && ((W3SignProjectile)damageAction.attacker).GetCaster() == thePlayer) ||
  2670.                 ( (W3Petard)damageAction.attacker && ((W3Petard)damageAction.attacker).GetOwner() == thePlayer)
  2671.             ){
  2672.                 theGame.GetGamerProfile().IncStat(ES_KilledCows);
  2673.             }
  2674.         }
  2675.        
  2676.        
  2677.         if ( damageAction.attacker == thePlayer )
  2678.         {
  2679.             theGame.GetMonsterParamsForActor(this, monsterCategory, tmpName, tmpBool, tmpBool, tmpBool);
  2680.            
  2681.            
  2682.             if(thePlayer.HasBuff(EET_Mutagen18))
  2683.             {
  2684.                
  2685.                
  2686.                 if(monsterCategory != MC_Animal || IsRequiredAttitudeBetween(this, thePlayer, true))
  2687.                 {          
  2688.                     abilityName = thePlayer.GetBuff(EET_Mutagen18).GetAbilityName();
  2689.                     abilityCount = thePlayer.GetAbilityCount(abilityName);
  2690.                    
  2691.                     if(abilityCount == 0)
  2692.                     {
  2693.                         addAbility = true;
  2694.                     }
  2695.                     else
  2696.                     {
  2697.                         theGame.GetDefinitionsManager().GetAbilityAttributeValue(abilityName, 'mutagen18_max_stack', min, max);
  2698.                         maxStack = CalculateAttributeValue(GetAttributeRandomizedValue(min, max));
  2699.                        
  2700.                         if(maxStack >= 0)
  2701.                         {
  2702.                             addAbility = (abilityCount < maxStack);
  2703.                         }
  2704.                         else
  2705.                         {
  2706.                             addAbility = true;
  2707.                         }
  2708.                     }
  2709.                    
  2710.                     if(addAbility)
  2711.                     {
  2712.                         thePlayer.AddAbility(abilityName, true);
  2713.                     }
  2714.                 }
  2715.             }
  2716.            
  2717.            
  2718.             if (thePlayer.HasBuff(EET_Mutagen06))
  2719.             {
  2720.                
  2721.                 if(monsterCategory != MC_Animal || IsRequiredAttitudeBetween(this, thePlayer, true))
  2722.                 {  
  2723.                     gameplayEffect = thePlayer.GetBuff(EET_Mutagen06);
  2724.                     thePlayer.AddAbility( gameplayEffect.GetAbilityName(), true);
  2725.                 }
  2726.             }
  2727.            
  2728.            
  2729.             if(IsRequiredAttitudeBetween(this, thePlayer, true))
  2730.             {
  2731.                 blizzard = (W3Potion_Blizzard)thePlayer.GetBuff(EET_Blizzard);
  2732.                 if(blizzard)
  2733.                     blizzard.KilledEnemy();
  2734.             }
  2735.            
  2736.            
  2737.             if( witcher.IsSetBonusActive( EISB_Vampire ) && !witcher.IsInFistFight() && !WillBeUnconscious() )
  2738.             {
  2739.                 witcher.VampiricSetAbilityRegeneration();
  2740.             }
  2741.            
  2742.             if(!HasTag('AchievementKillDontCount'))
  2743.             {
  2744.                 if (damageAction.GetIsHeadShot() && monsterCategory == MC_Human )      
  2745.                     theGame.GetGamerProfile().IncStat(ES_HeadShotKills);
  2746.                    
  2747.                
  2748.                 if( (W3SignEntity)damageAction.causer || (W3SignProjectile)damageAction.causer)
  2749.                 {
  2750.                     FactsAdd("statistics_cerberus_sign");
  2751.                 }
  2752.                 else if( (CBaseGameplayEffect)damageAction.causer && ((CBaseGameplayEffect)damageAction.causer).IsSignEffect())
  2753.                 {
  2754.                     FactsAdd("statistics_cerberus_sign");
  2755.                 }
  2756.                 else if( (W3Petard)damageAction.causer )
  2757.                 {
  2758.                     FactsAdd("statistics_cerberus_petard");
  2759.                 }
  2760.                 else if( (W3BoltProjectile)damageAction.causer )
  2761.                 {
  2762.                     FactsAdd("statistics_cerberus_bolt");
  2763.                 }              
  2764.                 else
  2765.                 {
  2766.                     if(!attackAction)
  2767.                         attackAction = (W3Action_Attack)damageAction;
  2768.                        
  2769.                     fists = false;
  2770.                     if(attackAction)
  2771.                     {
  2772.                         weaponID = attackAction.GetWeaponId();
  2773.                         if(damageAction.attacker.GetInventory().IsItemFists(weaponID))
  2774.                         {
  2775.                             FactsAdd("statistics_cerberus_fists");
  2776.                             fists = true;
  2777.                         }                      
  2778.                     }
  2779.                    
  2780.                     if(!fists && damageAction.IsActionMelee())
  2781.                     {
  2782.                         FactsAdd("statistics_cerberus_melee");
  2783.                     }
  2784.                 }
  2785.             }
  2786.            
  2787.            
  2788.             if( expPoints > 0 && !HasTag( 'AchievementKillDontCount' ) && thePlayer.inv.HasItem( 'q705_tissue_extractor' ) )
  2789.             {
  2790.                 thePlayer.TissueExtractorIncCharge();
  2791.             }
  2792.            
  2793.            
  2794.             if( (W3BoltProjectile)damageAction.causer && damageAction.GetWasFrozen() && !WillBeUnconscious() )
  2795.             {
  2796.                 theGame.GetGamerProfile().AddAchievement( EA_HastaLaVista );
  2797.                 thePlayer.PlayVoiceset( 100, "HastaLaVista", true );
  2798.             }
  2799.                        
  2800.            
  2801.            
  2802.         }
  2803.        
  2804.        
  2805.         if( damageAction.attacker == thePlayer || !((CNewNPC)damageAction.attacker) )
  2806.         {
  2807.             theTelemetry.LogWithLabelAndValue(TE_FIGHT_ENEMY_DIES, this.ToString(), GetLevel());
  2808.         }
  2809.        
  2810.        
  2811.         if(damageAction.attacker == thePlayer && !HasTag('AchievementKillDontCount'))
  2812.         {
  2813.             if ( attitudeToPlayer == AIA_Hostile )
  2814.             {
  2815.                
  2816.                 if(!HasTag('AchievementSwankDontCount'))
  2817.                 {
  2818.                     swank = FactsQuerySum("statistic_killed_in_10_sec");
  2819.                     if(swank >= 4)
  2820.                         theGame.GetGamerProfile().AddAchievement(EA_Swank);
  2821.                     else
  2822.                     {
  2823.                         FactsAdd("statistic_killed_in_10_sec", 1, 10);
  2824.                         if(swank > 0)
  2825.                             theGame.GetGamerProfile().NoticeAchievementProgress(EA_Swank, swank);
  2826.                     }
  2827.                 }
  2828.                
  2829.                
  2830.                 if( witcher && !thePlayer.ReceivedDamageInCombat() && !witcher.UsedQuenInCombat())
  2831.                 {
  2832.                     theGame.GetGamerProfile().IncStat(ES_FinesseKills);
  2833.                 }
  2834.             }
  2835.            
  2836.            
  2837.             if((W3PlayerWitcher)thePlayer)
  2838.             {
  2839.                 if(!thePlayer.DidFailFundamentalsFirstAchievementCondition() && HasTag(theGame.params.MONSTER_HUNT_ACTOR_TAG) && !HasTag('failedFundamentalsAchievement'))
  2840.                 {
  2841.                     theGame.GetGamerProfile().IncStat(ES_FundamentalsFirstKills);
  2842.                 }
  2843.             }
  2844.         }
  2845.                    
  2846.        
  2847.         if(!inWater && (W3IgniProjectile)damageAction.causer)
  2848.         {
  2849.            
  2850.             if(RandF() < 0.3 && !WillBeUnconscious() )
  2851.             {
  2852.                 AddEffectDefault(EET_Burning, this, 'IgniKill', true);
  2853.                 EnableAgony();
  2854.                 SignalGameplayEvent('ForceAgony');         
  2855.             }
  2856.         }
  2857.        
  2858.        
  2859.         OnDeathMutation2( damageAction );      
  2860.        
  2861.        
  2862.         if(damageAction.attacker == thePlayer && thePlayer.HasAbility('Glyphword 20 _Stats', true) && damageAction.GetBuffSourceName() != "Glyphword 20")
  2863.         {
  2864.             burningCauser = (W3Effect_Burning)damageAction.causer;         
  2865.            
  2866.             if(IsRequiredAttitudeBetween(thePlayer, damageAction.victim, true, false, false) && ((burningCauser && burningCauser.IsSignEffect()) || (W3IgniProjectile)damageAction.causer))
  2867.             {
  2868.                 damageAction.SetForceExplosionDismemberment();
  2869.                
  2870.                
  2871.                 radius = CalculateAttributeValue(thePlayer.GetAbilityAttributeValue('Glyphword 20 _Stats', 'radius'));
  2872.                
  2873.                
  2874.                 theGame.GetDefinitionsManager().GetAbilityAttributes('Glyphword 20 _Stats', atts);
  2875.                 for(i=0; i<atts.Size(); i+=1)
  2876.                 {
  2877.                     if(IsDamageTypeNameValid(atts[i]))
  2878.                     {
  2879.                         dmg.dmgType = atts[i];
  2880.                         dmg.dmgVal = CalculateAttributeValue(thePlayer.GetAbilityAttributeValue('Glyphword 20 _Stats', dmg.dmgType));
  2881.                         damages.PushBack(dmg);
  2882.                     }
  2883.                 }
  2884.                
  2885.                
  2886.                 inv         = GetInventory();      
  2887.                 weaponId    = inv.GetItemFromSlot( 'r_weapon' );
  2888.                 inv.GetWeaponDTNames( weaponId, damageNames );
  2889.                 attribute = GetBasicAttackDamageAttributeName( theGame.params.ATTACK_NAME_HEAVY, theGame.params.DAMAGE_NAME_FIRE);
  2890.                 damageAttr = GetAttributeValue( attribute );
  2891.                 damageAttr.valueBase = GetTotalWeaponDamage( weaponId, damageNames[0], GetInvalidUniqueId() );
  2892.  
  2893.                 if( damageAttr.valueBase <= 0 )
  2894.                 {
  2895.                     damageAttr.valueBase = 10;
  2896.                 }
  2897.                
  2898.                 if(damageAttr.valueMultiplicative <= 0)
  2899.                 {
  2900.                     damageAttr.valueMultiplicative = 1;
  2901.                 }
  2902.                
  2903.                 damageValue = ( damageAttr.valueBase * damageAttr.valueMultiplicative + damageAttr.valueAdditive ) * 5;
  2904.                
  2905.                
  2906.                
  2907.                 FindGameplayEntitiesInSphere(entities, GetWorldPosition(), radius, 1000, , FLAG_OnlyAliveActors);
  2908.                
  2909.                
  2910.                 for(i=0; i<entities.Size(); i+=1)
  2911.                 {
  2912.                     if(IsRequiredAttitudeBetween(thePlayer, entities[i], true, false, false))
  2913.                     {
  2914.                         act = new W3DamageAction in this;
  2915.                         act.Initialize(thePlayer, entities[i], damageAction.causer, "Glyphword 20", EHRT_Heavy, CPS_SpellPower, false, false, true, false);
  2916.                        
  2917.                         for(j=0; j<damages.Size(); j+=1)
  2918.                         {
  2919.                             act.AddDamage(damages[j].dmgType, damages[j].dmgVal);
  2920.                         }
  2921.                        
  2922.                        
  2923.                         act.AddDamage(damageNames[0], damageValue);
  2924.                        
  2925.                        
  2926.                         act.AddEffectInfo(EET_Burning, , , , , 0.5f);
  2927.                        
  2928.                         theGame.damageMgr.ProcessAction(act);
  2929.                         delete act;
  2930.                     }
  2931.                 }
  2932.                
  2933.                 CreateFXEntityAtPelvis( 'glyphword_20_explosion', false );             
  2934.             }
  2935.         }
  2936.        
  2937.        
  2938.         if(attackAction && IsWeaponHeld('fist') && damageAction.attacker == thePlayer && !thePlayer.ReceivedDamageInCombat() && !HasTag('AchievementKillDontCount'))
  2939.         {
  2940.             weaponID = attackAction.GetWeaponId();
  2941.             if(thePlayer.inv.IsItemFists(weaponID))
  2942.                 theGame.GetGamerProfile().AddAchievement(EA_FistOfTheSouthStar);
  2943.         }
  2944.        
  2945.        
  2946.         if(damageAction.IsActionRanged() && damageAction.IsBouncedArrow())
  2947.         {
  2948.             theGame.GetGamerProfile().IncStat(ES_SelfArrowKills);
  2949.         }
  2950.        
  2951.        
  2952.         isFinisher = ( damageAction.GetBuffSourceName() == "Finisher" || damageAction.GetBuffSourceName() == "AutoFinisher" );
  2953.         if( damageAction.attacker == thePlayer && ( damageAction.IsActionMelee() || isFinisher ) )
  2954.         {          
  2955.             weaponID = attackAction.GetWeaponId();
  2956.            
  2957.             if( isFinisher && !thePlayer.inv.IsIdValid( weaponID ) )
  2958.             {
  2959.                 weaponID = thePlayer.inv.GetCurrentlyHeldSword();
  2960.             }
  2961.            
  2962.             if( damageAction.attacker.GetInventory().ItemHasTag( weaponID, 'Aerondight' ) )
  2963.             {
  2964.                 aerondight = (W3Effect_Aerondight)thePlayer.GetBuff( EET_Aerondight );
  2965.                
  2966.                 if( aerondight )               
  2967.                 {
  2968.                     if( aerondight.IsFullyCharged() )
  2969.                     {
  2970.                         if( aerondight.DischargeAerondight() )
  2971.                         {
  2972.                             PlayEffect( 'hit_electric_quen' );
  2973.                         }
  2974.                     }
  2975.                     else if( isFinisher )
  2976.                     {
  2977.                         aerondight.IncreaseAerondightCharges( theGame.params.ATTACK_NAME_LIGHT );
  2978.                     }
  2979.                 }
  2980.             }
  2981.         }      
  2982.     }
  2983.    
  2984.    
  2985.     private final function OnDeathMutation2( out damageAction : W3DamageAction )
  2986.     {
  2987.         var burning : W3Effect_Burning;
  2988.         var vfxEnt : W3VisualFx;
  2989.         var fxName : name;
  2990.        
  2991.        
  2992.         if( !damageAction.IsMutation2PotentialKill() )
  2993.         {
  2994.             return;
  2995.         }
  2996.        
  2997.        
  2998.         burning = ( W3Effect_Burning ) damageAction.causer;    
  2999.         if( burning && burning.IsFromMutation2() )
  3000.         {              
  3001.             damageAction.SetSignSkill( S_Magic_2 );
  3002.         }
  3003.        
  3004.        
  3005.         damageAction.SetForceExplosionDismemberment();
  3006.         vfxEnt = ( W3VisualFx ) CreateFXEntityAtPelvis( 'mutation_2_explode', false );
  3007.         if( vfxEnt )
  3008.         {
  3009.             if ( (W3IgniProjectile)damageAction.causer )
  3010.             {
  3011.                 fxName = 'mutation_2_igni';
  3012.             }
  3013.             else if ( (W3YrdenEntityStateYrdenShock)damageAction.causer )
  3014.             {
  3015.                 fxName = 'mutation_2_yrden';
  3016.             }
  3017.             else if ( (W3QuenEntity)damageAction.causer )
  3018.             {
  3019.                 fxName = 'mutation_2_quen';
  3020.             }
  3021.             else if ( (W3AardProjectile)damageAction.causer )
  3022.             {
  3023.                 fxName = 'mutation_2_aard';
  3024.             }
  3025.            
  3026.             vfxEnt.PlayEffect( fxName );
  3027.             vfxEnt.DestroyOnFxEnd( fxName );
  3028.         }
  3029.     }
  3030.    
  3031.     event OnChangeDyingInteractionPriorityIfNeeded()
  3032.     {
  3033.         if ( WillBeUnconscious() )
  3034.             return true;
  3035.         if ( HasTag('animal') )
  3036.         {
  3037.             return true;
  3038.         }
  3039.            
  3040.        
  3041.         this.SetInteractionPriority(IP_Max_Unpushable);
  3042.     }
  3043.    
  3044.    
  3045.    
  3046.     public final function IsImmuneToMutation8Finisher() : bool
  3047.     {
  3048.         var min, max : SAbilityAttributeValue;
  3049.         var str : string;
  3050.        
  3051.         if( !IsHuman() || !IsAlive() || !IsRequiredAttitudeBetween( thePlayer, this, true ) )
  3052.         {
  3053.             return true;
  3054.         }
  3055.        
  3056.         if( HasAbility( 'SkillBoss' ) )
  3057.         {
  3058.             return true;
  3059.         }
  3060.         if( HasAbility( 'Boss' ) )
  3061.         {
  3062.             return true;
  3063.         }
  3064.         if( HasAbility( 'InstantKillImmune' ) )
  3065.         {
  3066.             return true;
  3067.         }
  3068.         if( HasTag( 'olgierd_gpl' ) )
  3069.         {
  3070.             return true;
  3071.         }
  3072.         if( HasAbility( 'DisableFinishers' ) )
  3073.         {
  3074.             return true;
  3075.         }
  3076.         if( HasTag( 'Mutation8CounterImmune' ) )
  3077.         {
  3078.             return true;
  3079.         }
  3080.        
  3081.         if( WillBeUnconscious() )
  3082.         {
  3083.             return true;
  3084.         }
  3085.        
  3086.         str = GetName();
  3087.         if( StrStartsWith( str, "rosa_var_attre" ) )
  3088.         {
  3089.             return true;
  3090.         }
  3091.                
  3092.         theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation8', 'hp_perc_trigger', min, max );
  3093.         if( GetHealthPercents() > min.valueMultiplicative )
  3094.         {
  3095.             return true;
  3096.         }
  3097.        
  3098.         return false;
  3099.     }
  3100.    
  3101.     event OnFireHit(source : CGameplayEntity)
  3102.     {  
  3103.         super.OnFireHit(source);
  3104.        
  3105.         if ( HasTag('animal') )
  3106.         {
  3107.             Kill( 'Animal hit by fire', source );
  3108.         }
  3109.        
  3110.         if ( !IsAlive() && IsInAgony() )
  3111.         {
  3112.            
  3113.             SignalGameplayEvent('AbandonAgony');
  3114.            
  3115.             SetKinematic(false);
  3116.         }
  3117.     }
  3118.    
  3119.     event OnAardHit( sign : W3AardProjectile )
  3120.     {
  3121.         var staminaDrainPerc : float;      
  3122.        
  3123.         SignalGameplayEvent( 'AardHitReceived' );
  3124.        
  3125.         aardedFlight = true;
  3126.        
  3127.        
  3128.         if( !sign.GetOwner().GetPlayer() || !GetWitcherPlayer().IsMutationActive( EPMT_Mutation6 ) )
  3129.         {
  3130.             RemoveAllBuffsOfType(EET_Frozen);
  3131.         }
  3132.        
  3133.        
  3134.        
  3135.        
  3136.         super.OnAardHit(sign);
  3137.        
  3138.         if ( HasTag('small_animal') )
  3139.         {
  3140.             Kill( 'Small Animal Aard Hit' );
  3141.         }
  3142.         if ( IsShielded(sign.GetCaster()) )
  3143.         {
  3144.             ToggleEffectOnShield('aard_cone_hit', true);
  3145.         }
  3146.         else if ( HasAbility('ablIgnoreSigns') )
  3147.         {
  3148.             this.SignalGameplayEvent( 'IgnoreSigns' );
  3149.             this.SetBehaviorVariable( 'bIgnoreSigns',1.f );
  3150.             AddTimer('IgnoreSignsTimeOut',0.2,false);
  3151.         }
  3152.        
  3153.        
  3154.         staminaDrainPerc = sign.GetStaminaDrainPerc();
  3155.         if(IsAlive() && staminaDrainPerc > 0.f && IsRequiredAttitudeBetween(this, sign.GetCaster(), true))
  3156.         {
  3157.             DrainStamina(ESAT_FixedValue, staminaDrainPerc * GetStatMax(BCS_Stamina));
  3158.            
  3159.         }
  3160.        
  3161.         if ( !IsAlive() && deathTimestamp + 0.2 < theGame.GetEngineTimeAsSeconds() )
  3162.         {
  3163.            
  3164.             SignalGameplayEvent('AbandonAgony');
  3165.            
  3166.            
  3167.            
  3168.             if( !HasAbility( 'mon_bear_base' )
  3169.                 && !HasAbility( 'mon_golem_base' )
  3170.                 && !HasAbility( 'mon_endriaga_base' )
  3171.                 && !HasAbility( 'mon_gryphon_base' )
  3172.                 && !HasAbility( 'q604_shades' )
  3173.                 && !IsAnimal()  )
  3174.             {          
  3175.                
  3176.                 SetKinematic( false );
  3177.             }
  3178.         }
  3179.     }
  3180.  
  3181.     event OnAxiiHit( sign : W3AxiiProjectile )
  3182.     {
  3183.         super.OnAxiiHit(sign);
  3184.        
  3185.         if ( HasAbility('ablIgnoreSigns') )
  3186.         {
  3187.             this.SignalGameplayEvent( 'IgnoreSigns' );
  3188.             this.SetBehaviorVariable( 'bIgnoreSigns',1.f );
  3189.             AddTimer('IgnoreSignsTimeOut',0.2,false);
  3190.         }
  3191.     }
  3192.    
  3193.     private const var SHIELD_BURN_TIMER : float;
  3194.     default SHIELD_BURN_TIMER = 1.0;
  3195.    
  3196.     private var beingHitByIgni : bool;
  3197.     private var firstIgniTick, lastIgniTick : float;
  3198.    
  3199.     event OnIgniHit( sign : W3IgniProjectile )
  3200.     {
  3201.         var horseComponent : W3HorseComponent;
  3202.         super.OnIgniHit( sign );
  3203.        
  3204.         SignalGameplayEvent( 'IgniHitReceived' );
  3205.        
  3206.         if ( HasAbility( 'ablIgnoreSigns') )
  3207.         {
  3208.             this.SignalGameplayEvent( 'IgnoreSigns' );
  3209.             this.SetBehaviorVariable('bIgnoreSigns',1.f);
  3210.             AddTimer('IgnoreSignsTimeOut',0.2,false);
  3211.         }
  3212.        
  3213.         if ( HasAbility( 'IceArmor') )
  3214.         {
  3215.             this.RemoveAbility( 'IceArmor' );
  3216.             this.StopEffect( 'ice_armor' );
  3217.             this.PlayEffect( 'ice_armor_hit' );
  3218.         }
  3219.        
  3220.         if( IsShielded( sign.GetCaster() ) )
  3221.         {
  3222.             if( sign.IsProjectileFromChannelMode() )
  3223.             {
  3224.                 SignalGameplayEvent( 'BeingHitByIgni' );
  3225.                
  3226.                 if( !beingHitByIgni )
  3227.                 {
  3228.                     beingHitByIgni = true;
  3229.                     firstIgniTick = theGame.GetEngineTimeAsSeconds();
  3230.                     ToggleEffectOnShield( 'burn', true );
  3231.                     RaiseShield();
  3232.                 }
  3233.                
  3234.                 if( firstIgniTick + SHIELD_BURN_TIMER < theGame.GetEngineTimeAsSeconds() )
  3235.                 {
  3236.                     ProcessShieldDestruction();
  3237.                     return false;
  3238.                 }
  3239.  
  3240.                 AddTimer( 'IgniCleanup', 0.2, false );
  3241.             }
  3242.             else
  3243.             {
  3244.                 ToggleEffectOnShield( 'igni_cone_hit', true );
  3245.             }
  3246.         }
  3247.        
  3248.         horseComponent = GetHorseComponent();
  3249.         if ( horseComponent )
  3250.             horseComponent.OnIgniHit(sign);
  3251.         else
  3252.         {
  3253.             horseComponent = GetUsedHorseComponent();
  3254.             if ( horseComponent )
  3255.                 horseComponent.OnIgniHit(sign);
  3256.         }
  3257.     }
  3258.    
  3259.     public function IsBeingHitByIgni() : bool
  3260.     {
  3261.         return beingHitByIgni;
  3262.     }
  3263.    
  3264.     function ToggleEffectOnShield(effectName : name, toggle : bool)
  3265.     {
  3266.         var itemID : SItemUniqueId;
  3267.         var inv : CInventoryComponent;
  3268.        
  3269.         inv = GetInventory();
  3270.         itemID = inv.GetItemFromSlot('l_weapon');
  3271.         if ( toggle )
  3272.             inv.PlayItemEffect(itemID,effectName);
  3273.         else
  3274.             inv.StopItemEffect(itemID,effectName);
  3275.     }
  3276.    
  3277.     timer function IgniCleanup( dt : float , id : int)
  3278.     {
  3279.         if( beingHitByIgni )
  3280.         {
  3281.             ToggleEffectOnShield( 'burn', false );
  3282.             AddTimer( 'LowerShield', 0.5 );
  3283.             beingHitByIgni = false;
  3284.         }
  3285.     }
  3286.    
  3287.     timer function IgnoreSignsTimeOut( dt : float , id : int)
  3288.     {
  3289.         this.SignalGameplayEvent( 'IgnoreSignsEnd' );
  3290.         this.SetBehaviorVariable( 'bIgnoreSigns',0.f);
  3291.     }
  3292.    
  3293.        
  3294.    
  3295.     function SetIsTeleporting( b : bool )
  3296.     {
  3297.         isTeleporting = b;
  3298.     }
  3299.    
  3300.     function IsTeleporting() : bool
  3301.     {
  3302.         return isTeleporting;
  3303.     }
  3304.  
  3305.     final function SetUnstoppable( toggle : bool )
  3306.     {
  3307.         unstoppable = toggle;
  3308.     }
  3309.    
  3310.     final function IsUnstoppable() : bool
  3311.     {
  3312.         return unstoppable;
  3313.     }
  3314.    
  3315.     final function SetIsCountering( toggle : bool )
  3316.     {
  3317.         bIsCountering = toggle;
  3318.     }
  3319.    
  3320.     final function IsCountering() : bool
  3321.     {
  3322.         return bIsCountering;
  3323.     }
  3324.    
  3325.    
  3326.     timer function Tick(deltaTime : float, id : int)
  3327.     {
  3328.        
  3329.        
  3330.     }
  3331.    
  3332.     private function UpdateBumpCollision()
  3333.     {
  3334.         var npc             : CNewNPC;
  3335.         var collisionData   : SCollisionData;
  3336.         var collisionNum    : int;
  3337.         var i               : int;
  3338.        
  3339.        
  3340.        
  3341.        
  3342.        
  3343.         if( mac )
  3344.         {
  3345.            
  3346.             collisionNum    = mac.GetCollisionCharacterDataCount();
  3347.             for( i = 0; i < collisionNum; i += 1 )
  3348.             {
  3349.                 collisionData   = mac.GetCollisionCharacterData( i );
  3350.                 npc = ( CNewNPC ) collisionData.entity;
  3351.                 if( npc )
  3352.                 {
  3353.                     this.SignalGameplayEvent( 'AI_GetOutOfTheWay' );                   
  3354.                     this.SignalGameplayEventParamObject( 'CollideWithPlayer', npc );   
  3355.                     theGame.GetBehTreeReactionManager().CreateReactionEvent( this, 'BumpAction', 1, 1, 1, 1, false );
  3356.                    
  3357.                    
  3358.                     break;
  3359.                 }
  3360.             }
  3361.         }
  3362.     }
  3363.  
  3364.  
  3365.     public function SetIsTranslationScaled(b : bool)                        {isTranslationScaled = b;}
  3366.     public function GetIsTranslationScaled() : bool                     {return isTranslationScaled;}  
  3367.    
  3368.    
  3369.     import final function GetActiveActionPoint() : SActionPointId;
  3370.  
  3371.  
  3372.    
  3373.    
  3374.    
  3375.  
  3376.    
  3377.    
  3378.    
  3379.     import final function IsInInterior() : bool;   
  3380.    
  3381.    
  3382.     import final function IsInDanger() : bool;
  3383.    
  3384.    
  3385.     import final function IsSeeingNonFriendlyNPC() : bool;
  3386.  
  3387.    
  3388.     import final function IsAIEnabled() : bool;
  3389.    
  3390.    
  3391.     import final function FindActionPoint( out apID : SActionPointId, out category : name );
  3392.            
  3393.    
  3394.     import final function GetDefaultDespawnPoint( out spawnPoint : Vector ) : bool;
  3395.    
  3396.  
  3397.    
  3398.     import final function NoticeActor( actor : CActor );
  3399.    
  3400.    
  3401.     import final function ForgetActor( actor : CActor );
  3402.    
  3403.    
  3404.     import final function ForgetAllActors();
  3405.    
  3406.    
  3407.     import final function GetNoticedObject( index : int) : CActor;
  3408.    
  3409.    
  3410.  
  3411.     import final function GetPerceptionRange() : float;
  3412.        
  3413.    
  3414.    
  3415.     import final function PlayDialog( optional forceSpawnedActors : bool ) : bool;
  3416.  
  3417.    
  3418.    
  3419.    
  3420.     import final function GetReactionScript( index : int ) : CReactionScript;
  3421.    
  3422.     import final function IfCanSeePlayer() : bool;
  3423.    
  3424.     import final function GetGuardArea() : CAreaComponent;
  3425.     import final function SetGuardArea( areaComponent : CAreaComponent );
  3426.     import final function DeriveGuardArea( ncp : CNewNPC ) : bool;
  3427.    
  3428.     import final function IsConsciousAtWork() : bool;
  3429.     import final function GetCurrentJTType() : int;
  3430.     import final function IsInLeaveAction() : bool;
  3431.     import final function IsSittingAtWork() : bool;
  3432.     import final function IsAtWork() : bool;
  3433.     import final function IsPlayingChatScene() : bool;
  3434.     import final function CanUseChatInCurrentAP() : bool;
  3435.    
  3436.    
  3437.     import final function NoticeActorInGuardArea( actor : CActor );
  3438.    
  3439.    
  3440.    
  3441.     import final function IsMountedByPlayer( isMountedByPlayer : bool ) : void;
  3442.    
  3443.    
  3444.    
  3445.     event OnAnimEvent_EquipItemL( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3446.     {
  3447.         GetInventory().MountItem( itemToEquip, true );
  3448.     }
  3449.     event OnAnimEvent_HideItemL( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3450.     {
  3451.         GetInventory().UnmountItem( itemToEquip, true );
  3452.     }
  3453.     event OnAnimEvent_HideWeapons( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3454.     {
  3455.         var inventory   : CInventoryComponent = GetInventory();
  3456.         var ids         : array<SItemUniqueId>;
  3457.         var i           : int;
  3458.        
  3459.         ids = inventory.GetAllWeapons();
  3460.         for( i = 0; i < ids.Size() ; i += 1 )
  3461.         {
  3462.             if( inventory.IsItemHeld( ids[i] ) || inventory.IsItemMounted( ids[i] ) )
  3463.                 inventory.UnmountItem( ids[i], true );
  3464.         }
  3465.     }
  3466.    
  3467.     event OnAnimEvent_TemporaryOffGround( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3468.     {
  3469.         if( animEventType == AET_DurationEnd )
  3470.         {
  3471.             isTemporaryOffGround = false;
  3472.         }
  3473.         else
  3474.         {
  3475.             isTemporaryOffGround = true;
  3476.         }
  3477.     }
  3478.     event OnAnimEvent_weaponSoundType( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3479.     {
  3480.         WeaponSoundType().SetupDrawHolsterSounds();
  3481.     }
  3482.    
  3483.     event OnAnimEvent_IdleDown( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3484.     {
  3485.         SetBehaviorVariable( 'idleType', 0.0 );
  3486.     }
  3487.    
  3488.     event OnAnimEvent_IdleForward( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3489.     {
  3490.         SetBehaviorVariable( 'idleType', 1.0 );
  3491.     }
  3492.    
  3493.     event OnAnimEvent_IdleCombat( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3494.     {
  3495.         SetBehaviorVariable( 'idleType', 2.0 );
  3496.     }
  3497.    
  3498.     event OnAnimEvent_WeakenedState( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3499.     {
  3500.         SetWeakenedState( true );
  3501.     }
  3502.    
  3503.     event OnAnimEvent_WeakenedStateOff( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3504.     {
  3505.         SetWeakenedState( false );
  3506.     }
  3507.    
  3508.     public function SetWeakenedState( val : bool )
  3509.     {
  3510.         if( val )
  3511.         {
  3512.             if( HasTag( 'olgierd_gpl' ) )
  3513.             {
  3514.                 AddAbility( 'WeakenedState', false );
  3515.                 SetBehaviorVariable( 'weakenedState', 1.0 );
  3516.                 PlayEffect( 'olgierd_energy_blast' );
  3517.                
  3518.                 if( HasTag( 'ethereal' ) && !HasAbility( 'EtherealSkill_4' ) )
  3519.                 {
  3520.                     AddAbility( 'EtherealMashingFixBeforeSkill4' );
  3521.                 }
  3522.             }
  3523.             else if( HasTag( 'dettlaff_vampire' ) )
  3524.             {
  3525.                 AddAbility( 'DettlaffWeakenedState', false );
  3526.                 StopEffect( 'shadowdash' );
  3527.                 PlayEffect( 'weakened' );
  3528.                 SetHitWindowOpened( false );
  3529.             }
  3530.            
  3531.             AddTimer( 'ResetHitCounter', 0.0, false );
  3532.         }
  3533.         else
  3534.         {
  3535.             if( HasTag( 'olgierd_gpl' ) )
  3536.             {
  3537.                 RemoveAbility( 'WeakenedState' );
  3538.                 SetBehaviorVariable( 'weakenedState', 0.0 );
  3539.                 StopEffect( 'olgierd_energy_blast' );
  3540.                
  3541.                 if( HasTag( 'ethereal' ) && !HasAbility( 'EtherealSkill_4' ) )
  3542.                 {
  3543.                     RemoveAbility( 'EtherealMashingFixBeforeSkill4' );
  3544.                 }
  3545.             }
  3546.             else if( HasTag( 'dettlaff_vampire' ) )
  3547.             {
  3548.                 RemoveAbility( 'DettlaffWeakenedState' );
  3549.                 StopEffect( 'weakened' );
  3550.             }
  3551.         }
  3552.     }
  3553.    
  3554.     public function SetHitWindowOpened( val : bool )
  3555.     {
  3556.         if( val )
  3557.         {
  3558.             AddAbility( 'HitWindowOpened', false );
  3559.             SetBehaviorVariable( 'hitWindowOpened', 1.0 );
  3560.            
  3561.             if( HasTag( 'fairytale_witch' ) )
  3562.             {
  3563.                 SetImmortalityMode( AIM_None, AIC_Combat );
  3564.             }
  3565.            
  3566.             if( HasTag( 'dettlaff_vampire' ) )
  3567.             {
  3568.                 AddBuffImmunity( EET_Burning, 'SetHitWindowOpened', true );
  3569.             }
  3570.         }
  3571.         else
  3572.         {
  3573.             RemoveAbility( 'HitWindowOpened' );
  3574.             SetBehaviorVariable( 'hitWindowOpened', 0.0 );
  3575.            
  3576.             if( HasTag( 'fairytale_witch' ) )
  3577.             {
  3578.                 SetImmortalityMode( AIM_Invulnerable, AIC_Combat );
  3579.             }
  3580.            
  3581.             if( HasTag( 'dettlaff_vampire' ) )
  3582.             {
  3583.                 RemoveBuffImmunity( EET_Burning, 'SetHitWindowOpened' );
  3584.             }
  3585.         }
  3586.     }
  3587.  
  3588.     event OnAnimEvent_WindowManager( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3589.     {
  3590.         if( animEventName == 'OpenHitWindow' )
  3591.         {
  3592.             SetHitWindowOpened( true );
  3593.         }
  3594.         else if( animEventName == 'CloseHitWindow' )
  3595.         {
  3596.             SetHitWindowOpened( false );
  3597.         }
  3598.         else if( animEventName == 'OpenCounterWindow' )
  3599.         {
  3600.             SetBehaviorVariable( 'counterHitType', 1.0 );
  3601.             AddTimer( 'CloseHitWindowAfter', 0.75 );
  3602.         }
  3603.     }
  3604.    
  3605.     event OnAnimEvent_CauldronDropped( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3606.     {
  3607.         DropItemFromSlot( 'l_weapon', true );
  3608.         SetBehaviorVariable( 'cauldronDropped', 1.0 );
  3609.     }
  3610.    
  3611.     event OnAnimEvent_BroomDeath( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3612.     {
  3613.         var witch : CNewNPC;
  3614.        
  3615.         witch = theGame.GetNPCByTag( 'fairytale_witch' );
  3616.         if( witch )
  3617.         {
  3618.             witch.SetBehaviorVariable( 'canDropCauldron', 1.0 );
  3619.         }
  3620.     }
  3621.    
  3622.     event OnAnimEvent_ToggleIsOverground( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3623.     {
  3624.         if( animEventName == 'SetIsUnderground' )
  3625.         {
  3626.             ToggleIsOverground( false );
  3627.         }
  3628.         else if( animEventName == 'SetIsOverground' )
  3629.         {
  3630.             ToggleIsOverground( true );
  3631.         }
  3632.     }
  3633.    
  3634.     public function ToggleIsOverground( val : bool )
  3635.     {
  3636.         if( val )
  3637.         {
  3638.             SetBehaviorVariable( 'isOverground', 1.0 );
  3639.             EnableCollisions( true );
  3640.             EnableCharacterCollisions( true );
  3641.             SetGameplayVisibility( true );
  3642.             SetImmortalityMode( AIM_None, AIC_Combat );
  3643.             SetUnstoppable( false );
  3644.             RemoveTag( 'isHiddenUnderground' );
  3645.             RemoveBuffImmunity( EET_Frozen, 'ToggleIsOverground' );
  3646.         }
  3647.         else
  3648.         {
  3649.             SetBehaviorVariable( 'isOverground', 0.0 );
  3650.             EnableCollisions( false );
  3651.             EnableCharacterCollisions( false );
  3652.             SetGameplayVisibility( false );
  3653.             SetImmortalityMode( AIM_Invulnerable, AIC_Combat );
  3654.             SetUnstoppable( true );
  3655.             AddTag( 'isHiddenUnderground' );
  3656.             AddBuffImmunity( EET_Frozen, 'ToggleIsOverground', true );
  3657.         }
  3658.     }
  3659.    
  3660.     event OnAnimEvent_CannotBeAttacked( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3661.     {
  3662.         AddAbility( 'CannotBeAttackedFromAllSides', false );
  3663.     }
  3664.  
  3665.     event OnAnimEvent_SlideAway( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3666.     {
  3667.         var ticket              : SMovementAdjustmentRequestTicket;
  3668.         var movementAdjustor    : CMovementAdjustor;
  3669.         var slidePos            : Vector;
  3670.         var slideDuration       : float;
  3671.        
  3672.         movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor();
  3673.         movementAdjustor.CancelByName( 'SlideAway' );
  3674.        
  3675.         ticket = movementAdjustor.CreateNewRequest( 'SlideAway' );
  3676.         slidePos = GetWorldPosition() + ( VecNormalize2D( GetWorldPosition() - thePlayer.GetWorldPosition() ) * 0.75 );
  3677.        
  3678.         if( theGame.GetWorld().NavigationLineTest( GetWorldPosition(), slidePos, GetRadius(), false, true ) )
  3679.         {
  3680.             slideDuration = VecDistance2D( GetWorldPosition(), slidePos ) / 35;
  3681.            
  3682.             movementAdjustor.Continuous( ticket );
  3683.             movementAdjustor.AdjustmentDuration( ticket, slideDuration );
  3684.             movementAdjustor.AdjustLocationVertically( ticket, true );
  3685.             movementAdjustor.BlendIn( ticket, 0.25 );
  3686.             movementAdjustor.SlideTo( ticket, slidePos );
  3687.             movementAdjustor.RotateTowards( ticket, GetTarget() );
  3688.         }
  3689.  
  3690.         return true;   
  3691.     }
  3692.    
  3693.     event OnAnimEvent_SlideForward( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3694.     {
  3695.         var ticket              : SMovementAdjustmentRequestTicket;
  3696.         var movementAdjustor    : CMovementAdjustor;
  3697.         var slidePos            : Vector;
  3698.         var slideDuration       : float;
  3699.        
  3700.         movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor();
  3701.         movementAdjustor.CancelByName( 'SlideForward' );
  3702.        
  3703.         ticket = movementAdjustor.CreateNewRequest( 'SlideForward' );
  3704.         slidePos = GetWorldPosition() + ( VecNormalize2D( GetWorldPosition() - thePlayer.GetWorldPosition() ) * 0.75 );
  3705.        
  3706.         if( theGame.GetWorld().NavigationLineTest( GetWorldPosition(), slidePos, GetRadius(), false, true ) )
  3707.         {
  3708.             slideDuration = VecDistance2D( GetWorldPosition(), slidePos ) / 35;
  3709.            
  3710.             movementAdjustor.Continuous( ticket );
  3711.             movementAdjustor.AdjustmentDuration( ticket, slideDuration );
  3712.             movementAdjustor.AdjustLocationVertically( ticket, true );
  3713.             movementAdjustor.BlendIn( ticket, 0.25 );
  3714.             movementAdjustor.SlideTo( ticket, slidePos );
  3715.         }
  3716.  
  3717.         return true;   
  3718.     }
  3719.    
  3720.     event OnAnimEvent_SlideTowards( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3721.     {
  3722.         var ticket              : SMovementAdjustmentRequestTicket;
  3723.         var movementAdjustor    : CMovementAdjustor;
  3724.        
  3725.         movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor();
  3726.         movementAdjustor.CancelByName( 'SlideTowards' );
  3727.        
  3728.         ticket = movementAdjustor.CreateNewRequest( 'SlideTowards' );
  3729.  
  3730.         movementAdjustor.AdjustLocationVertically( ticket, true );
  3731.         movementAdjustor.BindToEventAnimInfo( ticket, animInfo );
  3732.         movementAdjustor.MaxLocationAdjustmentSpeed( ticket, 4 );
  3733.         movementAdjustor.ScaleAnimation( ticket );
  3734.         movementAdjustor.SlideTowards( ticket, thePlayer, 1.0, 1.25 );
  3735.         movementAdjustor.RotateTowards( ticket, GetTarget() );
  3736.  
  3737.         return true;   
  3738.     }
  3739.    
  3740.     event OnAnimEvent_PlayBattlecry( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3741.     {
  3742.         if( animEventName == 'BC_Sign' )
  3743.         {
  3744.             PlayVoiceset( 100, "q601_olgierd_taunt_sign" );
  3745.         }
  3746.         else if( animEventName == 'BC_Taunt' )
  3747.         {
  3748.             PlayVoiceset( 100, "q601_olgierd_taunt" );
  3749.         }
  3750.         else
  3751.         {
  3752.             if( RandRange( 100 ) < 75 )
  3753.             {
  3754.                 if( animEventName == 'BC_Weakened' )
  3755.                 {
  3756.                     PlayVoiceset( 100, "q601_olgierd_weakened" );
  3757.                 }
  3758.                 else if( animEventName == 'BC_Attack' )
  3759.                 {
  3760.                     PlayVoiceset( 100, "q601_olgierd_fast_attack" );
  3761.                 }
  3762.                 else if( animEventName == 'BC_Parry' )
  3763.                 {
  3764.                     PlayVoiceset( 100, "q601_olgierd_taunt_parry" );
  3765.                 }
  3766.                 else
  3767.                 {
  3768.                     return false;
  3769.                 }
  3770.             }
  3771.         }
  3772.     }
  3773.    
  3774.    
  3775.     event OnAnimEvent_OwlSwitchOpen( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3776.     {
  3777.         SetAppearance('owl_01');
  3778.     }
  3779.    
  3780.     event OnAnimEvent_OwlSwitchClose( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3781.     {
  3782.         SetAppearance('owl_02');
  3783.     }
  3784.    
  3785.     event OnAnimEvent_Goose01OpenWings( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3786.     {
  3787.         SetAppearance('goose_01_wings');
  3788.     }
  3789.    
  3790.     event OnAnimEvent_Goose01CloseWings( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3791.     {
  3792.         SetAppearance('goose_01');
  3793.     }
  3794.    
  3795.     event OnAnimEvent_Goose02OpenWings( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3796.     {
  3797.         SetAppearance('goose_02_wings');
  3798.     }
  3799.    
  3800.     event OnAnimEvent_Goose02CloseWings( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3801.     {
  3802.         SetAppearance('goose_02');
  3803.     }
  3804.  
  3805.     event OnAnimEvent_NullifyBurning( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3806.     {
  3807.         RemoveAllBuffsOfType(EET_Burning);
  3808.     }
  3809.  
  3810.     event OnAnimEvent_setVisible( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3811.     {
  3812.         SetVisibility( true );
  3813.         SetGameplayVisibility( true );
  3814.     }
  3815.    
  3816.     event OnAnimEvent_extensionWalk( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3817.     {
  3818.         SetBehaviorVariable( 'UsesExtension', 1 );
  3819.         SetBehaviorVariable( 'WalkExtensionAnimSpeed', 0.1 );
  3820.         SetBehaviorVariable( 'WalkTransitionAnimSpeed', 0.5 );
  3821.     }
  3822.    
  3823.     event OnAnimEvent_extensionWalkNormalSpeed( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3824.     {
  3825.         SetBehaviorVariable( 'UsesExtension', 1 );
  3826.         SetBehaviorVariable( 'WalkExtensionAnimSpeed', 1.0 );
  3827.         SetBehaviorVariable( 'WalkTransitionAnimSpeed', 0.5 );
  3828.     }
  3829.    
  3830.     event OnAnimEvent_extensionWalkRightHandOnly( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3831.     {
  3832.         SetBehaviorVariable( 'UsesExtension', 2 );
  3833.         SetBehaviorVariable( 'WalkExtensionAnimSpeed', 0.1 );
  3834.     }
  3835.    
  3836.     event OnAnimEvent_extensionWalkStartStopNormalSpeed( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3837.     {
  3838.         SetBehaviorVariable( 'UsesExtension', 3 );
  3839.         SetBehaviorVariable( 'WalkExtensionAnimSpeed', 1.0 );
  3840.         SetBehaviorVariable( 'WalkTransitionAnimSpeed', 0.5 );
  3841.     }
  3842.    
  3843.     event OnAnimEvent_disableCrowdOverride( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3844.     {
  3845.         SetBehaviorVariable( 'disableCrowdOverride', 1 );
  3846.     }
  3847.    
  3848.     event OnAnimEvent_ActivateSide( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3849.     {
  3850.         var template    : CEntityTemplate;
  3851.         var entity      : CEntity;
  3852.         var spawnPos    : Vector;
  3853.         var spawnRot    : EulerAngles;
  3854.        
  3855.         template = ( CEntityTemplate )LoadResource( 'dolphin' );
  3856.        
  3857.        
  3858.         spawnRot = GetWorldRotation();
  3859.         spawnRot.Yaw += 180;
  3860.         spawnPos = GetWorldPosition() - 1.5 * VecNormalize( VecFromHeading( spawnRot.Yaw + 180 )) + 1 * VecNormalize( VecFromHeading( spawnRot.Yaw + 90 ));
  3861.         entity = theGame.CreateEntity( template, spawnPos, spawnRot );
  3862.         entity.SetBehaviorVariable( 'side', 1 );
  3863.         entity.SetBehaviorVariable( 'alternate', 0 );
  3864.        
  3865.        
  3866.        
  3867.         spawnPos = GetWorldPosition() + 1.5 * VecNormalize( VecFromHeading( spawnRot.Yaw + 180 )) + 1 * VecNormalize( VecFromHeading( spawnRot.Yaw + 90 ));
  3868.         entity = theGame.CreateEntity( template, spawnPos, spawnRot );
  3869.         entity.SetBehaviorVariable( 'side', 1 );
  3870.         entity.SetBehaviorVariable( 'alternate', 1 );
  3871.        
  3872.     }
  3873.    
  3874.     event OnAnimEvent_ActivateUp( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3875.     {
  3876.         var template    : CEntityTemplate;
  3877.         var entity      : CEntity;
  3878.         var spawnPos    : Vector;
  3879.         var spawnRot    : EulerAngles;
  3880.        
  3881.         template = ( CEntityTemplate )LoadResource( 'dolphin' );
  3882.        
  3883.        
  3884.         spawnRot = GetWorldRotation();
  3885.         spawnRot.Yaw += 180;
  3886.         spawnPos = GetWorldPosition() + 0.0 * VecNormalize( VecFromHeading( spawnRot.Yaw + 180 )) - 8 * VecNormalize( VecFromHeading( spawnRot.Yaw + 90 ));
  3887.         entity = theGame.CreateEntity( template, spawnPos, spawnRot );
  3888.         entity.SetBehaviorVariable( 'up', 1 );
  3889.         entity.SetBehaviorVariable( 'alternate', 0 );
  3890.        
  3891.        
  3892.        
  3893.         spawnPos = GetWorldPosition() + 0.0 * VecNormalize( VecFromHeading( spawnRot.Yaw + 180 )) + 8 * VecNormalize( VecFromHeading( spawnRot.Yaw + 90 ));
  3894.         entity = theGame.CreateEntity( template, spawnPos, spawnRot );
  3895.         entity.SetBehaviorVariable( 'up', 1 );
  3896.         entity.SetBehaviorVariable( 'alternate', 1 );
  3897.        
  3898.     }
  3899.    
  3900.     event OnAnimEvent_DeactivateSide( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3901.     {
  3902.         SetBehaviorVariable( 'up', 0 );
  3903.         SetBehaviorVariable( 'side', 0 );
  3904.         DestroyAfter( 5.0 );
  3905.         SetVisibility( false );
  3906.        
  3907.     }
  3908.    
  3909.     event OnAnimEvent_DeactivateUp( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3910.     {
  3911.         SetBehaviorVariable( 'up', 0 );
  3912.         SetBehaviorVariable( 'side', 0 );
  3913.         DestroyAfter( 5.0 );
  3914.         SetVisibility( false );
  3915.        
  3916.     }
  3917.    
  3918.     event OnAnimEvent_BruxaJumpFailsafe( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3919.     {
  3920.         PlayEffect( 'appear' );
  3921.         SignalGameplayEvent( 'appeared' );
  3922.         SetBehaviorVariable( 'inAir', 0, true );
  3923.         SetBehaviorVariable( 'vanished', 0, true );
  3924.         SetBehaviorVariable( 'invisible', 0, true );
  3925.         SetGameplayVisibility( true );
  3926.     }
  3927.    
  3928.     event OnAnimEvent_ResetOneTimeSpawnActivation( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3929.     {
  3930.         SignalGameplayEvent( 'ResetOneTimeSpawnActivation' );
  3931.     }
  3932.    
  3933.    
  3934.    
  3935.     event OnEquippedItem( category : name, slotName : name )
  3936.     {
  3937.         if ( slotName == 'r_weapon' )
  3938.         {
  3939.             switch( category )
  3940.             {          
  3941.                 case 'axe1h':
  3942.                 case 'axe2h':
  3943.                     SetBehaviorVariable( 'EquippedItemR', (int) RIT_Axe );
  3944.                     break;     
  3945.                 case 'halberd2h':
  3946.                     SetBehaviorVariable( 'EquippedItemR', (int) RIT_Halberd );
  3947.                     break;
  3948.                 case 'steelsword' :
  3949.                 case 'silversword' :
  3950.                     SetBehaviorVariable( 'EquippedItemR', (int) RIT_Sword );
  3951.                     break;
  3952.                 case 'crossbow' :
  3953.                     SetBehaviorVariable( 'EquippedItemR', (int) RIT_Crossbow );
  3954.                     break;
  3955.                 default:
  3956.                     SetBehaviorVariable( 'EquippedItemR', (int) RIT_None );
  3957.                     break;
  3958.             }
  3959.         }
  3960.         else if ( slotName == 'l_weapon' )
  3961.         {
  3962.             switch( category )
  3963.             {
  3964.                 case 'shield' :
  3965.                     SetBehaviorVariable( 'EquippedItemL', (int) LIT_Shield );
  3966.                     break;
  3967.                 case 'bow' :
  3968.                     SetBehaviorVariable( 'EquippedItemL', (int) LIT_Bow );
  3969.                     break;
  3970.                 case 'usable' :
  3971.                     SetBehaviorVariable( 'EquippedItemL', (int) LIT_Torch );
  3972.                     break;
  3973.                 default:
  3974.                     SetBehaviorVariable( 'EquippedItemL', (int) LIT_None );
  3975.                     break;
  3976.             }
  3977.         }
  3978.        
  3979.         if ( category != 'fist' && category != 'work' && category != 'usable' && IsInCombat() && GetTarget() == thePlayer && thePlayer.GetTarget() == this )
  3980.             thePlayer.OnTargetWeaponDrawn();
  3981.     }
  3982.    
  3983.     event OnHolsteredItem( category : name, slotName : name )
  3984.     {
  3985.         if ( slotName == 'r_weapon' )
  3986.         {
  3987.             SetBehaviorVariable( 'EquippedItemR', (int) RIT_None );
  3988.         }
  3989.         else if ( slotName == 'l_weapon' )
  3990.         {
  3991.             SetBehaviorVariable( 'EquippedItemL', (int) LIT_None );
  3992.         }
  3993.     }
  3994.    
  3995.     function IsTalkDisabled () : bool
  3996.     {
  3997.         return isTalkDisabled || isTalkDisabledTemporary;
  3998.     }
  3999.    
  4000.     public function DisableTalking( disable : bool, optional temporary : bool )
  4001.     {      
  4002.         if ( temporary )
  4003.         {
  4004.             isTalkDisabledTemporary = disable;
  4005.         }
  4006.         else
  4007.         {
  4008.             isTalkDisabled = disable;
  4009.         }
  4010.     }
  4011.  
  4012.     public function CanStartTalk() : bool
  4013.     {
  4014.        
  4015.         if( IsAtWork() && !IsConsciousAtWork() || IsTalkDisabled () )
  4016.             return false;
  4017.            
  4018.         if(HasBuff(EET_AxiiGuardMe) || HasBuff(EET_Confusion))
  4019.             return false;
  4020.            
  4021.         return !IsFrozen() && CanTalk( true );
  4022.     }
  4023.    
  4024.     event OnInteraction( actionName : string, activator : CEntity )
  4025.     {
  4026.         var horseComponent      : W3HorseComponent;
  4027.         var ciriEntity          : W3ReplacerCiri;
  4028.         var isAtWork            : bool;
  4029.         var isConciousAtWork    : bool;
  4030.        
  4031.         LogChannel( 'DialogueTest', "Event Interaction Used" );
  4032.         if ( actionName == "Talk" )
  4033.         {  
  4034.             LogChannel( 'DialogueTest', "Activating TALK Interaction - PLAY DIALOGUE" );
  4035.            
  4036.             if ( !PlayDialog() )
  4037.             {
  4038.                
  4039.                
  4040.                 EnableDynamicLookAt( thePlayer, 5 );
  4041.                 ciriEntity = (W3ReplacerCiri)thePlayer;
  4042.                 if ( ciriEntity )
  4043.                 {
  4044.                 }
  4045.                 else
  4046.                 {
  4047.                    
  4048.                     if( !IsAtWork() || IsConsciousAtWork() )
  4049.                     {
  4050.                         PlayVoiceset(100, "greeting_geralt" );
  4051.                     }
  4052.                     else
  4053.                         PlayVoiceset(100, "sleeping" );
  4054.                    
  4055.                     wasInTalkInteraction = true;
  4056.                     AddTimer( 'ResetTalkInteractionFlag', 1.0, true, , , true);
  4057.                 }
  4058.             }
  4059.         }
  4060.         if ( actionName == "Finish" )
  4061.         {
  4062.            
  4063.         }
  4064.         else if( actionName == "AxiiCalmHorse" )
  4065.         {
  4066.             SignalGameplayEvent( 'HorseAxiiCalmDownStart' );
  4067.         }
  4068.     }
  4069.    
  4070.     event OnInteractionActivationTest( interactionComponentName : string, activator : CEntity )
  4071.     {
  4072.         var stateName : name;
  4073.         var horseComp : W3HorseComponent;
  4074.        
  4075.         if( interactionComponentName == "talk" )
  4076.         {
  4077.             if( activator == thePlayer && thePlayer.CanStartTalk() && CanStartTalk() )
  4078.             {  
  4079.                 return true;
  4080.             }
  4081.         }
  4082.         else if( interactionComponentName == "Finish" && activator == thePlayer )
  4083.         {
  4084.             stateName = thePlayer.GetCurrentStateName();
  4085.             if( stateName == 'CombatSteel' || stateName == 'CombatSilver' )
  4086.                 return true;
  4087.         }
  4088.         else if( interactionComponentName == "horseMount" && activator == thePlayer )
  4089.         {
  4090.             if( !thePlayer.IsActionAllowed( EIAB_MountVehicle ) || thePlayer.IsInAir() )
  4091.                 return false;
  4092.             if ( horseComponent.IsInHorseAction() || !IsAlive() )
  4093.                 return false;
  4094.             if ( GetAttitudeBetween(this,thePlayer) == AIA_Hostile && !( HasBuff(EET_Confusion) || HasBuff(EET_AxiiGuardMe) ) )
  4095.                 return false;
  4096.            
  4097.             if( mac.IsOnNavigableSpace() )
  4098.             {
  4099.                 if( theGame.GetWorld().NavigationLineTest( activator.GetWorldPosition(), this.GetWorldPosition(), 0.05, false, true ) )
  4100.                 {
  4101.                    
  4102.                     if( theGame.TestNoCreaturesOnLine( activator.GetWorldPosition(), this.GetWorldPosition(), 0.4, (CActor)activator, this, true ) )
  4103.                     {
  4104.                         return true;
  4105.                     }
  4106.                    
  4107.                     return false;
  4108.                 }
  4109.             }
  4110.             else
  4111.             {
  4112.                 horseComp = this.GetHorseComponent();
  4113.                
  4114.                 if( horseComp )
  4115.                 {
  4116.                     horseComp.mountTestPlayerPos = activator.GetWorldPosition();
  4117.                     horseComp.mountTestPlayerPos.Z += 0.5;
  4118.                     horseComp.mountTestHorsePos = this.GetWorldPosition();
  4119.                     horseComp.mountTestHorsePos.Z += 0.5;
  4120.                    
  4121.                     if( !theGame.GetWorld().StaticTrace( horseComp.mountTestPlayerPos, horseComp.mountTestHorsePos, horseComp.mountTestEndPos, horseComp.mountTestNormal, horseComp.mountTestCollisionGroups ) )
  4122.                     {
  4123.                         return true;
  4124.                     }
  4125.                 }
  4126.                
  4127.                 return false;
  4128.             }
  4129.         }
  4130.        
  4131.        
  4132.        
  4133.         return false;  
  4134.     }
  4135.    
  4136.     event OnInteractionTalkTest()
  4137.     {
  4138.         return CanStartTalk();     
  4139.     }
  4140.  
  4141.    
  4142.     event OnInteractionActivated( interactionComponentName : string, activator : CEntity )
  4143.     {
  4144.        
  4145.        
  4146.        
  4147.        
  4148.        
  4149.        
  4150.     }
  4151.    
  4152.     event OnInteractionDeactivated( interactionComponentName : string, activator : CEntity )
  4153.     {
  4154.        
  4155.        
  4156.        
  4157.        
  4158.     }
  4159.  
  4160.    
  4161.    
  4162.    
  4163.    
  4164.    
  4165.        
  4166.        
  4167.        
  4168.    
  4169.    
  4170.     event OnBehaviorGraphNotification( notificationName : name, stateName : name )
  4171.     {
  4172.         var i: int;    
  4173.         for ( i = 0; i < behaviorGraphEventListened.Size(); i += 1 )
  4174.         {
  4175.             if( behaviorGraphEventListened[i] == notificationName )
  4176.             {
  4177.                 SignalGameplayEventParamCName( notificationName, stateName );
  4178.             }
  4179.         }
  4180.         super.OnBehaviorGraphNotification( notificationName, stateName );
  4181.     }
  4182.    
  4183.     public function ActivateSignalBehaviorGraphNotification( notificationName : name )
  4184.     {
  4185.         if( !behaviorGraphEventListened.Contains( notificationName ) )
  4186.         {
  4187.             behaviorGraphEventListened.PushBack( notificationName );
  4188.         }
  4189.     }
  4190.    
  4191.     public function DeactivateSignalBehaviorGraphNotification( notificationName : name )
  4192.     {
  4193.         behaviorGraphEventListened.Remove( notificationName );
  4194.     }
  4195.    
  4196.    
  4197.    
  4198.    
  4199.    
  4200.     timer function RemoveMutation4BloodDebuff( dt : float, id : int )
  4201.     {
  4202.         RemoveAbility( 'Mutation4BloodDebuff' );
  4203.     }
  4204.    
  4205.     function IsShielded( target : CNode ) : bool
  4206.     {
  4207.         var targetToSourceAngle : float;
  4208.         var protectionAngleLeft, protectionAngleRight : float;
  4209.        
  4210.         if( target )
  4211.         {
  4212.             if( HasShieldedAbility() && IsGuarded() )
  4213.             {
  4214.                 targetToSourceAngle = NodeToNodeAngleDistance(target, this);
  4215.                 protectionAngleLeft = CalculateAttributeValue( this.GetAttributeValue( 'protection_angle_left' ) );
  4216.                 protectionAngleRight = CalculateAttributeValue( this.GetAttributeValue( 'protection_angle_right' ) );
  4217.                
  4218.                
  4219.                 if( targetToSourceAngle < protectionAngleRight && targetToSourceAngle > protectionAngleLeft )
  4220.                 {
  4221.                     return true;
  4222.                 }
  4223.             }
  4224.             return false;
  4225.         }
  4226.         else
  4227.             return HasShieldedAbility() && IsGuarded();
  4228.     }
  4229.    
  4230.     function HasShieldedAbility() : bool
  4231.     {
  4232.         var attval : float;
  4233.         attval = CalculateAttributeValue( this.GetAttributeValue( 'shielded' ) );
  4234.         if( attval >= 1.f )
  4235.             return true;
  4236.         else
  4237.             return false;
  4238.     }
  4239.    
  4240.     function RaiseShield()
  4241.     {
  4242.         SetBehaviorVariable( 'bShieldUp', 1.f );
  4243.     }
  4244.    
  4245.     timer function LowerShield( td : float , id : int)
  4246.     {
  4247.         SetBehaviorVariable( 'bShieldUp', 0.f );
  4248.     }
  4249.        
  4250.     public function ProcessShieldDestruction()
  4251.     {  
  4252.         var shield : CEntity;
  4253.        
  4254.         if( HasTag( 'imlerith' ) )
  4255.             return;
  4256.            
  4257.         SetBehaviorVariable( 'bShieldbreak', 1.0 );
  4258.         AddEffectDefault( EET_Stagger, thePlayer, "ParryStagger" );
  4259.         shield = GetInventory().GetItemEntityUnsafe( GetInventory().GetItemFromSlot( 'l_weapon' ) );
  4260.         ToggleEffectOnShield( 'heavy_block', true );
  4261.         DropItemFromSlot( 'l_weapon', true );
  4262.     }
  4263.  
  4264.     event OnIncomingProjectile( isBomb : bool )
  4265.     {
  4266.         if( IsShielded( thePlayer ) )
  4267.         {
  4268.             RaiseShield();
  4269.             AddTimer( 'LowerShield', 3.0 );
  4270.         }
  4271.     }
  4272.    
  4273.     function ShouldAttackImmidiately() : bool
  4274.     {
  4275.         return  tauntedToAttackTimeStamp > 0 && ( tauntedToAttackTimeStamp + 10 > theGame.GetEngineTimeAsSeconds() );
  4276.     }
  4277.    
  4278.     function CanAttackKnockeddownTarget() : bool
  4279.     {
  4280.         var attval : float;
  4281.         attval = CalculateAttributeValue(this.GetAttributeValue('attackKnockeddownTarget'));
  4282.         if ( attval >= 1.f )
  4283.             return true;
  4284.         else
  4285.             return false;
  4286.     }
  4287.    
  4288.     event OnProcessRequiredItemsFinish()
  4289.     {
  4290.         var inv : CInventoryComponent = this.GetInventory();
  4291.         var heldItems, heldItemsNames, mountedItems : array<name>;
  4292.        
  4293.         if ( thePlayer.GetTarget() == this )
  4294.             thePlayer.OnTargetWeaponDrawn();
  4295.        
  4296.        
  4297.         SetBehaviorVariable( 'bIsGuarded', (int)IsGuarded() );
  4298.        
  4299.         inv.GetAllHeldAndMountedItemsCategories(heldItems, mountedItems);
  4300.                
  4301.        
  4302.         if ( this.HasShieldedAbility() )
  4303.         {
  4304.             RaiseGuard();
  4305.         }
  4306.        
  4307.         inv.GetAllHeldItemsNames( heldItemsNames );
  4308.        
  4309.         if ( heldItemsNames.Contains('fists_lightning') || heldItemsNames.Contains('fists_fire') )
  4310.         {
  4311.             this.PlayEffect('hand_fx');
  4312.             theGame.GetBehTreeReactionManager().CreateReactionEventIfPossible( this, 'FireDanger', -1, 5.0f, 1, -1, true, true );
  4313.         }
  4314.         else
  4315.         {
  4316.             this.StopEffect('hand_fx');
  4317.             theGame.GetBehTreeReactionManager().RemoveReactionEvent( this, 'FireDanger' );
  4318.         }
  4319.        
  4320.         if ( mountedItems.Contains('shield') )
  4321.         {
  4322.             this.AddAbility('CannotBeAttackedFromBehind', false);
  4323.             LowerGuard();
  4324.         }
  4325.         else
  4326.         {
  4327.             this.RemoveAbility('CannotBeAttackedFromBehind');
  4328.         }
  4329.     }
  4330.    
  4331.    
  4332.     private var spear : CEntity;
  4333.     timer function SpearImpulse(dt : float, id : int)
  4334.     {
  4335.         spear.GetComponent("CMeshComponent0").ApplyLocalImpulseToPhysicalObject(Vector(50,0,50));  
  4336.     }
  4337.    
  4338.    
  4339.     public function ProcessSpearDestruction() : bool
  4340.     {
  4341.         var appearanceName : name;
  4342.         var shouldDrop : bool;
  4343.        
  4344.        
  4345.         var ids : array<SItemUniqueId>;
  4346.        
  4347.         appearanceName = 'broken';
  4348.         spear = GetInventory().GetItemEntityUnsafe( GetInventory().GetItemFromSlot( 'r_weapon' ) );
  4349.         spear.ApplyAppearance( appearanceName );
  4350.         DropItemFromSlot('r_weapon', true);
  4351.        
  4352.        
  4353.         spear.PlayEffect('wood_break');
  4354.         ids = GetInventory().GetItemsByName('Q1_brokenSpear');
  4355.         if(ids.Size() <= 0)
  4356.             ids = GetInventory().AddAnItem( 'Q1_brokenSpear', 1, true, true, false );
  4357.         GetInventory().MountItem(ids[0], true);
  4358.         AddTimer('SpearImpulse', 0.05, false);
  4359.        
  4360.        
  4361.         return true;
  4362.        
  4363.     }  
  4364.    
  4365.    
  4366.    
  4367.    
  4368.    
  4369.     function PlayVitalSpotAmbientSound( soundEvent : string )
  4370.     {
  4371.         SoundEvent( soundEvent, 'pelvis' );
  4372.     }
  4373.    
  4374.     function StopVitalSpotAmbientSound( soundEvent : string)
  4375.     {
  4376.         SoundEvent( soundEvent, 'pelvis' );
  4377.     }
  4378.    
  4379.     event OnScriptReloaded()
  4380.     {
  4381.        
  4382.     }
  4383.        
  4384.  
  4385.    
  4386.    
  4387.    
  4388.    
  4389.    
  4390.     public function ChangeFightStage( fightStage : ENPCFightStage )
  4391.     {
  4392.         currentFightStage =  fightStage;
  4393.         SetCurrentFightStage();
  4394.     }
  4395.    
  4396.     public function SetCurrentFightStage()
  4397.     {
  4398.         SetBehaviorVariable( 'npcFightStage', (float)(int)currentFightStage, true );
  4399.     }
  4400.    
  4401.     public function GetCurrentFightStage() : ENPCFightStage
  4402.     {
  4403.         return currentFightStage;
  4404.     }
  4405.    
  4406.    
  4407.     public function SetBleedBurnPoison()
  4408.     {
  4409.         wasBleedingBurningPoisoned = true;
  4410.     }
  4411.    
  4412.     public function WasBurnedBleedingPoisoned() : bool
  4413.     {
  4414.         return wasBleedingBurningPoisoned;
  4415.     }
  4416.    
  4417.    
  4418.     public function HasAlternateQuen() : bool
  4419.     {
  4420.         var npcStorage : CHumanAICombatStorage;
  4421.        
  4422.         npcStorage = (CHumanAICombatStorage)GetScriptStorageObject('CombatData');
  4423.         if(npcStorage && npcStorage.IsProtectedByQuen() )
  4424.         {
  4425.             return true;
  4426.         }      
  4427.        
  4428.         return false;
  4429.     }
  4430.    
  4431.    
  4432.     public function GetIsMonsterTypeGroup() : bool  { return isMonsterType_Group; }
  4433.  
  4434.     timer function AardDismemberForce( dt : float, id : int )
  4435.     {
  4436.         var ent : CEntity;
  4437.         var template : CEntityTemplate;
  4438.         var pos, toPlayerVec : Vector;
  4439.        
  4440.        
  4441.         template = (CEntityTemplate) LoadResource( "explosion_dismember_force" );
  4442.         toPlayerVec = GetWorldPosition() - thePlayer.GetWorldPosition();
  4443.         pos = GetWorldPosition() + toPlayerVec / VecDistance2D( GetWorldPosition(), thePlayer.GetWorldPosition() * 3 );
  4444.         ent = theGame.CreateEntity( template, pos, , , , true );
  4445.         ent.DestroyAfter( 5.f );
  4446.     }
  4447.  
  4448.    
  4449.    
  4450.    
  4451.     function UpdateAIVisualDebug()
  4452.     {  
  4453.     }
  4454.  
  4455.    
  4456.     event OnAllowBehGraphChange()
  4457.     {
  4458.         allowBehGraphChange = true;
  4459.     }
  4460.    
  4461.     event OnDisallowBehGraphChange()
  4462.     {
  4463.         allowBehGraphChange = false;
  4464.     }
  4465.  
  4466.     event OnObstacleCollision( object : CObject, physicalActorindex : int, shapeIndex : int  )
  4467.     {
  4468.         var  ent : CEntity;
  4469.         var component : CComponent;
  4470.         component = (CComponent) object;
  4471.         if( !component )
  4472.         {
  4473.             return false;
  4474.         }
  4475.        
  4476.         ent = component.GetEntity();
  4477.        
  4478.         if ( (CActor)ent != this )
  4479.         {
  4480.            
  4481.             this.SignalGameplayEventParamObject('CollisionWithObstacle',ent);
  4482.         }
  4483.     }
  4484.    
  4485.     event OnObstacleCollisionProbe( object : CObject, physicalActorindex : int, shapeIndex : int  )
  4486.     {
  4487.         var  ent : CEntity;
  4488.         var component : CComponent;
  4489.         component = (CComponent) object;
  4490.         if( !component )
  4491.         {
  4492.             return false;
  4493.         }
  4494.        
  4495.         ent = component.GetEntity();
  4496.         if ( (CActor)ent != this )
  4497.         {
  4498.             this.SignalGameplayEventParamObject('CollisionWithObstacleProbe',ent);
  4499.         }
  4500.     }
  4501.    
  4502.     event OnProjectileCustomCollision( object : CObject, physicalActorindex : int, shapeIndex : int  )
  4503.     {
  4504.         var  ent : CEntity;
  4505.         var component : CComponent;
  4506.         component = (CComponent) object;
  4507.         if( !component )
  4508.         {
  4509.             return false;
  4510.         }
  4511.        
  4512.         ent = component.GetEntity();
  4513.         if ( (CActor)ent != this )
  4514.         {
  4515.             this.SignalGameplayEventParamObject('CollisionWithProjectileCustom',ent);
  4516.         }
  4517.     }
  4518.    
  4519.    
  4520.     event OnActorCollision( object : CObject, physicalActorindex : int, shapeIndex : int  )
  4521.     {
  4522.         var  ent : CEntity;
  4523.         var component : CComponent;
  4524.         component = (CComponent) object;
  4525.         if( !component )
  4526.         {
  4527.             return false;
  4528.         }
  4529.        
  4530.         ent = component.GetEntity();
  4531.         if ( ent != this )
  4532.         {
  4533.             this.SignalGameplayEventParamObject('CollisionWithActor', ent );
  4534.            
  4535.            
  4536.             if( horseComponent )
  4537.             {
  4538.                 horseComponent.OnCharacterCollision( ent );
  4539.             }
  4540.         }
  4541.     }
  4542.    
  4543.     event OnActorSideCollision( object : CObject, physicalActorindex : int, shapeIndex : int  )
  4544.     {
  4545.         var  ent : CEntity;
  4546.         var horseComp : W3HorseComponent;
  4547.         var component : CComponent;
  4548.         component = (CComponent) object;
  4549.         if( !component )
  4550.         {
  4551.             return false;
  4552.         }
  4553.        
  4554.         ent = component.GetEntity();
  4555.         if ( ent != this )
  4556.         {
  4557.             this.SignalGameplayEventParamObject('CollisionWithActor', ent );
  4558.            
  4559.            
  4560.             if( horseComponent )
  4561.             {
  4562.                 horseComponent.OnCharacterSideCollision( ent );
  4563.             }
  4564.         }
  4565.     }
  4566.    
  4567.     event OnStaticCollision( component : CComponent )
  4568.     {
  4569.         SignalGameplayEventParamObject('CollisionWithStatic',component);
  4570.     }
  4571.    
  4572.     event OnBoatCollision( object : CObject, physicalActorindex : int, shapeIndex : int  )
  4573.     {
  4574.         var  ent : CEntity;
  4575.         var component : CComponent;
  4576.         component = (CComponent) object;
  4577.         if( !component )
  4578.         {
  4579.             return false;
  4580.         }
  4581.        
  4582.         ent = component.GetEntity();
  4583.         if ( ent != this )
  4584.         {
  4585.             this.SignalGameplayEventParamObject('CollisionWithBoat', ent );
  4586.         }
  4587.     }
  4588.    
  4589.    
  4590.    
  4591.    
  4592.    
  4593.     public function IsUnderwater() : bool { return isUnderwater; }
  4594.     public function ToggleIsUnderwater ( toggle : bool ) { isUnderwater = toggle; }
  4595.    
  4596.     event OnOceanTriggerEnter()
  4597.     {
  4598.         SignalGameplayEvent('EnterWater');
  4599.     }
  4600.    
  4601.     event OnOceanTriggerLeave()
  4602.     {
  4603.         SignalGameplayEvent('LeaveWater');
  4604.     }
  4605.    
  4606.    
  4607.    
  4608.    
  4609.        
  4610.     var isRagdollOn : bool; default isRagdollOn = false;
  4611.    
  4612.     event OnInAirStarted()
  4613.     {      
  4614.        
  4615.     }
  4616.    
  4617.     event OnRagdollOnGround()
  4618.     {      
  4619.         var params : SCustomEffectParams;
  4620.        
  4621.         if( GetIsFallingFromHorse() )
  4622.         {
  4623.             params.effectType = EET_Ragdoll;
  4624.             params.creator = this;
  4625.             params.sourceName = "ragdoll_dismount";
  4626.             params.duration = 0.5;
  4627.             AddEffectCustom( params );
  4628.             SignalGameplayEvent( 'RagdollFromHorse' );
  4629.             SetIsFallingFromHorse( false );
  4630.         }
  4631.         else if( IsInAir() )
  4632.         {
  4633.             SetIsInAir(false);
  4634.         }
  4635.     }
  4636.    
  4637.     var m_storedInteractionPri : EInteractionPriority;
  4638.     default m_storedInteractionPri = IP_NotSet;
  4639.    
  4640.     event OnRagdollStart()
  4641.     {
  4642.         var currentPri : EInteractionPriority;
  4643.    
  4644.        
  4645.         currentPri = GetInteractionPriority();
  4646.         if ( currentPri != IP_Max_Unpushable && IsAlive() )
  4647.         {
  4648.             m_storedInteractionPri = currentPri;
  4649.             SetInteractionPriority( IP_Max_Unpushable );
  4650.         }
  4651.     }
  4652.    
  4653.     event OnNoLongerInRagdoll()
  4654.     {
  4655.         aardedFlight = false;
  4656.        
  4657.        
  4658.         if ( m_storedInteractionPri != IP_NotSet && IsAlive() )
  4659.         {
  4660.             SetInteractionPriority( m_storedInteractionPri );
  4661.             m_storedInteractionPri = IP_NotSet;
  4662.         }
  4663.     }
  4664.    
  4665.     timer function DelayRagdollSwitch( td : float , id : int)
  4666.     {
  4667.         var params : SCustomEffectParams;
  4668.    
  4669.         if( IsInAir() )
  4670.         {
  4671.             isRagdollOn = true;
  4672.             params.effectType = EET_Ragdoll;
  4673.             params.duration = 5;
  4674.            
  4675.             AddEffectCustom(params);
  4676.         }
  4677.     }
  4678.  
  4679.     event OnRagdollIsAwayFromCapsule( ragdollPosition : Vector, entityPosition : Vector )
  4680.     {
  4681.     }
  4682.    
  4683.     event OnRagdollCloseToCapsule( ragdollPosition : Vector, entityPosition : Vector )
  4684.     {
  4685.     }
  4686.    
  4687.     event OnTakeDamage( action : W3DamageAction )
  4688.     {
  4689.         var i : int;
  4690.         var abilityName : name;
  4691.         var abilityCount, maxStack : float;
  4692.         var min, max : SAbilityAttributeValue;
  4693.         var addAbility : bool;
  4694.         var witcher : W3PlayerWitcher;
  4695.         var attackAction : W3Action_Attack;
  4696.         var gameplayEffects : array<CBaseGameplayEffect>;
  4697.         var template : CEntityTemplate;
  4698.         var hud : CR4ScriptedHud;
  4699.         var ent : CEntity;
  4700.         var weaponId : SItemUniqueId;
  4701.  
  4702.         super.OnTakeDamage(action);
  4703.        
  4704.        
  4705.         if(action.IsActionMelee() && action.DealsAnyDamage())
  4706.         {
  4707.             witcher = (W3PlayerWitcher)action.attacker;
  4708.             if(witcher && witcher.HasBuff(EET_Mutagen10))
  4709.             {
  4710.                 abilityName = thePlayer.GetBuff(EET_Mutagen10).GetAbilityName();
  4711.                 abilityCount = thePlayer.GetAbilityCount(abilityName);
  4712.                
  4713.                 if(abilityCount == 0)
  4714.                 {
  4715.                     addAbility = true;
  4716.                 }
  4717.                 else
  4718.                 {
  4719.                     theGame.GetDefinitionsManager().GetAbilityAttributeValue(abilityName, 'mutagen10_max_stack', min, max);
  4720.                     maxStack = CalculateAttributeValue(GetAttributeRandomizedValue(min, max));
  4721.                    
  4722.                     if(maxStack >= 0)
  4723.                     {
  4724.                         addAbility = (abilityCount < maxStack);
  4725.                     }
  4726.                     else
  4727.                     {
  4728.                         addAbility = true;
  4729.                     }
  4730.                 }
  4731.                
  4732.                 if(addAbility)
  4733.                 {
  4734.                     thePlayer.AddAbility(abilityName, true);
  4735.                 }
  4736.             }
  4737.            
  4738.             attackAction = (W3Action_Attack)action;
  4739.  
  4740.             if ( witcher && attackAction && attackAction.attacker == witcher )
  4741.             {
  4742.                 if ( !attackAction.IsParried() && !attackAction.IsCountered() )
  4743.                 {
  4744.                     if ( witcher.HasAbility( 'Runeword 11 _Stats', true ) )
  4745.                     {
  4746.                         gameplayEffects = witcher.GetPotionBuffs();
  4747.                         theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Runeword 11 _Stats', 'duration', min, max );
  4748.                        
  4749.                         for ( i = 0; i < gameplayEffects.Size(); i+=1 )
  4750.                         {
  4751.                             gameplayEffects[i].SetTimeLeft( gameplayEffects[i].GetTimeLeft() + min.valueAdditive );
  4752.                            
  4753.                             hud = (CR4ScriptedHud)theGame.GetHud();
  4754.                             if (hud)
  4755.                             {
  4756.                                 hud.ShowBuffUpdate();
  4757.                             }
  4758.                         }
  4759.                     }
  4760.                 }
  4761.             }
  4762.         }
  4763.        
  4764.         if(action.IsActionMelee())
  4765.             lastMeleeHitTime = theGame.GetEngineTime();
  4766.        
  4767.        
  4768.         if( (W3PlayerWitcher)action.attacker && action.IsActionRanged() && GetWitcherPlayer().IsMutationActive( EPMT_Mutation9 ) )
  4769.         {
  4770.             attackAction = (W3Action_Attack)action;
  4771.             if( attackAction )
  4772.             {
  4773.                 weaponId = attackAction.GetWeaponId();
  4774.                 if( thePlayer.inv.IsItemCrossbow( weaponId ) || thePlayer.inv.IsItemBolt( weaponId ) )
  4775.                 {
  4776.                     theGame.MutationHUDFeedback( MFT_PlayOnce );
  4777.                 }
  4778.             }
  4779.         }
  4780.     }
  4781.    
  4782.     public function GetInteractionData( out actionName : name, out text : string ) : bool
  4783.     {
  4784.         if ( CanStartTalk() && !IsInCombat() && !HasTag( 'no_talk' ) )
  4785.         {
  4786.             actionName  = 'Talk';
  4787.             text        = "panel_button_common_talk";
  4788.             return true;
  4789.         }
  4790.         return false;
  4791.     }
  4792.    
  4793.     public function IsAtWorkDependentOnFireSource() : bool
  4794.     {
  4795.         if ( IsAPValid(GetActiveActionPoint()) )
  4796.         {
  4797.             return theGame.GetAPManager().IsFireSourceDependent( GetActiveActionPoint() );
  4798.         }
  4799.        
  4800.         return false;
  4801.     }
  4802.    
  4803.     public function FinishQuen( skipVisuals : bool, optional forceNoBearSetBonus : bool )
  4804.     {
  4805.         SignalGameplayEvent('FinishQuen');
  4806.     }
  4807.  
  4808.     public function IsAxiied() : Bool
  4809.     {
  4810.         return HasBuff( EET_AxiiGuardMe ) || HasBuff( EET_Confusion );
  4811.     }
  4812.    
  4813.     private timer function CloseHitWindowAfter( dt : float, id : int )
  4814.     {
  4815.         SetBehaviorVariable( 'counterHitType', 0.0 );
  4816.     }
  4817.    
  4818.    
  4819.    
  4820.    
  4821.    
  4822.    
  4823.    
  4824.     public timer function SetShowAllHorseItems( dt : float, id : int )
  4825.     {
  4826.         var hiddenItems : bool;
  4827.        
  4828.         hiddenItems = TryToHideAllHorseItems();
  4829.        
  4830.        
  4831.         if( !hiddenItems )
  4832.         {
  4833.             AddTimer( 'SetShowAllHorseItems', 0.1f, true );
  4834.         }
  4835.         else
  4836.         {
  4837.             RemoveTimer( 'SetShowAllHorseItems' );
  4838.         }
  4839.     }
  4840.    
  4841.    
  4842.    
  4843.    
  4844.     public final function TryToHideAllHorseItems() : bool
  4845.     {
  4846.         var items : array< SItemUniqueId >;
  4847.         var itemEntity : CItemEntity;
  4848.         var i, k : int;
  4849.         var drawableComp : CDrawableComponent;
  4850.         var drawableComps : array<CComponent>;
  4851.         var inv : CInventoryComponent;
  4852.         var itemVisibility : bool;
  4853.         var foundTail, foundReins, foundHair : bool;
  4854.         var itemName : name;
  4855.        
  4856.         inv = GetInventory();
  4857.         inv.GetAllItems( items );
  4858.         itemVisibility = !GetWitcherPlayer().GetHorseManager().GetShouldHideAllItems();
  4859.        
  4860.         foundTail   = false;
  4861.         foundReins  = false;
  4862.         foundHair   = false;
  4863.        
  4864.         for( i=0; i<items.Size(); i+=1 )
  4865.         {
  4866.             itemName = inv.GetItemName( items[ i ] );
  4867.             itemEntity = inv.GetItemEntityUnsafe( items[ i ] );
  4868.             if( itemEntity )
  4869.             {
  4870.                 if( inv.ItemHasTag( items[i], 'HorseTail' ) )
  4871.                 {
  4872.                     foundTail = true;
  4873.                 }
  4874.                 else if( inv.ItemHasTag( items[i], 'HorseReins' ) )
  4875.                 {
  4876.                     foundReins = true;
  4877.                 }
  4878.                 else if( inv.GetItemCategory( items[i] ) == 'horse_hair' )
  4879.                 {
  4880.                     foundHair = true;
  4881.                 }
  4882.                
  4883.                 drawableComps = itemEntity.GetComponentsByClassName( 'CDrawableComponent' );
  4884.                
  4885.                 for( k = 0; k < drawableComps.Size(); k += 1 )
  4886.                 {
  4887.                     drawableComp = ( CDrawableComponent )drawableComps[ k ];
  4888.                     if( drawableComp )
  4889.                     {
  4890.                         drawableComp.SetVisible( itemVisibility );
  4891.                     }
  4892.                 }
  4893.             }
  4894.         }
  4895.        
  4896.        
  4897.         return items.Size() == 0 || ( foundTail && foundReins && foundHair );
  4898.     }
  4899.    
  4900.     timer function SetUnconsciousFinisher( time : float , id : int )
  4901.     {
  4902.         SetBehaviorVariable( 'unconsciousFinisher', 1.0 );
  4903.         SetBehaviorVariable( 'prepareForUnconsciousFinisher', 0.0f );
  4904.     }
  4905.    
  4906.     timer function EvadeFinisherTimer( dt : float, id : int )
  4907.     {
  4908.         var ticketS, ticketR    : SMovementAdjustmentRequestTicket;
  4909.         var movementAdjustor    : CMovementAdjustor;
  4910.        
  4911.         PlayEffectSingle( 'disappear' );
  4912.        
  4913.         movementAdjustor = this.GetMovingAgentComponent().GetMovementAdjustor();
  4914.        
  4915.         ticketS = movementAdjustor.CreateNewRequest( 'FinisherSlide' );
  4916.         movementAdjustor.MaxLocationAdjustmentSpeed( ticketS, 9999 );
  4917.         movementAdjustor.AdjustLocationVertically( ticketS, true );
  4918.         movementAdjustor.AdjustmentDuration( ticketS, 0.6 );
  4919.         movementAdjustor.BlendIn( ticketS, 0.25 );
  4920.         movementAdjustor.SlideTowards( ticketS, GetTarget(), 5, 7 );
  4921.        
  4922.         ticketR = movementAdjustor.CreateNewRequest( 'FinisherRotate' );
  4923.         movementAdjustor.MaxLocationAdjustmentSpeed( ticketR, 9999 );
  4924.         movementAdjustor.AdjustmentDuration( ticketR, 0.1 );
  4925.         movementAdjustor.RotateTowards( ticketR, GetTarget() );
  4926.        
  4927.         this.AddTimer( 'EvadeFinisherTimerStop', 0.6, false );
  4928.     }
  4929.    
  4930.     timer function EvadeFinisherTimerStop( dt : float, id : int )
  4931.     {
  4932.         PlayEffectSingle( 'appear' );
  4933.     }
  4934. }
  4935.  
  4936. exec function IsFireSource( tag : name )
  4937. {
  4938.     var npc : CNewNPC;
  4939.  
  4940.     npc = ( CNewNPC )theGame.GetEntityByTag( tag );
  4941.    
  4942.     LogChannel('SD', "" + npc.IsAtWorkDependentOnFireSource() );
  4943. }  
  4944.  
  4945.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement