daily pastebin goal
55%
SHARE
TWEET

witcher 3 error

a guest Aug 11th, 2018 86 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. statemachine abstract import class CR4Player extends CPlayer
  7. {
  8.     // BEHAVIOR INITIALIZATION
  9.     protected       var pcGamePlayInitialized           : bool;                 // MS: hack variable to fix Tpose when initially spawning Geralt (Consult Tomsin)
  10.     public saved    var newCraftables                   : array<name>;
  11.     //---=== modFriendlyHUD ===---
  12.  
  13.     // PC Controls
  14.     private         var pcMode                          : bool;                 // MS: Use control/camera modifications for keyboard/mouse
  15.     default pcMode = true;
  16.  
  17.     // COMBAT MECHANICS
  18.     protected saved var weaponHolster                   : WeaponHolster;        // Makes Geralt holster and unholster the swords
  19.     public          var rangedWeapon                    : Crossbow;             // Handles ranged weapons
  20.     public          var crossbowDontPopStateHack        : bool;                 default crossbowDontPopStateHack = false;
  21.    
  22.     private         var hitReactTransScale              : float;                //dynamic scale for npc's hitreaction animation translation to force CloseCombat
  23.    
  24.     private         var bIsCombatActionAllowed          : bool;
  25.     private         var currentCombatAction             : EBufferActionType;
  26.    
  27.     private         var uninterruptedHitsCount          : int;                  //amount of uninterrupted hints performed by the player (gets reset when we get hit or stop attacking etc.)
  28.     private         var uninterruptedHitsCameraStarted  : bool;                 //set to true once we enable the uninterrupted hits camera effect
  29.     private         var uninterruptedHitsCurrentCameraEffect : name;            //currently used camera blurr effect for uninterrupted hits
  30.    
  31.     private         var counterTimestamps               : array<EngineTime>;    //times when player pressed counter attack button - we check it later to prevent spamming
  32.    
  33.     private         var hitReactionEffect               : bool;                 //blurr
  34.    
  35.     private         var lookAtPosition                  : Vector;               //Position that Geralt is looking at, also where he will shoot
  36.     private         var orientationTarget               : EOrientationTarget;
  37.     private         var customOrientationTarget         : EOrientationTarget;
  38.     protected       var customOrientationStack          : array<SCustomOrientationParams>;
  39.    
  40.     public          var delayOrientationChange          : bool;
  41.     protected       var delayCameraOrientationChange    : bool;
  42.     private         var actionType                      : int; // 0 = sign, 1 = guard, 2 = specialAttack, 3 = throwItem
  43.     private         var customOrientationStackIndex     : int; //Used by Player only: will disable the previous combat action's orientation target and add to the stack everytime he performs a new combat action
  44.    
  45.     private         var emptyMoveTargetTimer            : float;
  46.    
  47.     private         var onlyOneEnemyLeft                : bool;
  48.    
  49.     public          var isInFinisher                    : bool;
  50.     private         var finisherTarget                  : CGameplayEntity;
  51.  
  52.     private         var combatStance                    : EPlayerCombatStance; 
  53.  
  54.     public          var approachAttack                  : int;                  //Enable/Disable approach attack prototype, 0 = enabled, 1 = disabled with no far attack limit, 2 = disabled with far attack limit
  55.                     default approachAttack              = 1;
  56.     protected       var specialAttackCamera             : bool;
  57.    
  58.     private         var specialAttackTimeRatio          : float;
  59.        
  60.     public saved    var itemsPerLevel                   : array<name>;  
  61.     public          var itemsPerLevelGiven              : array<bool>;  
  62.    
  63.     private         var playerTickTimerPhase            : int;
  64.         default playerTickTimerPhase = 0;
  65.        
  66.     protected       var evadeHeading                    : float;
  67.  
  68.     public          var vehicleCbtMgrAiming             : bool;     //MS: hack variable to pass vehicleCbtMgr aiming variable to UseGenericVehicle
  69.    
  70.     public          var specialHeavyChargeDuration      : float;                //duration of charge-up event
  71.     public          var specialHeavyStartEngineTime     : EngineTime;           //timestamp of when the charge-up started
  72.     public          var playedSpecialAttackMissingResourceSound : bool;         //if missing resource sound was played or not (used in loop)
  73.     public function SetPlayedSpecialAttackMissingResourceSound(b : bool) {playedSpecialAttackMissingResourceSound = b;}
  74.    
  75.     public var counterCollisionGroupNames : array<name>;
  76.    
  77.     public saved    var lastInstantKillTime             : GameTime;
  78.    
  79.     // Save locks
  80.     private         var noSaveLockCombatActionName      : string;       default noSaveLockCombatActionName  = 'combat_action'; 
  81.     private         var noSaveLockCombatAction          : int; 
  82.     private         var deathNoSaveLock                 : int; 
  83.     private         var noSaveLock                      : int;
  84.    
  85.     //new game plus
  86.     protected saved var newGamePlusInitialized          : bool;
  87.         default newGamePlusInitialized = false;
  88.    
  89.     //  action buffer
  90.     protected           var BufferAllSteps                  : bool;
  91.     protected           var BufferCombatAction              : EBufferActionType;
  92.     protected           var BufferButtonStage               : EButtonStage;
  93.    
  94.         default BufferAllSteps = false;
  95.         default customOrientationTarget = OT_None; 
  96.         default hitReactionEffect = true;  
  97.         default uninterruptedHitsCount = 0;
  98.         default uninterruptedHitsCameraStarted = false;
  99.         default customOrientationStackIndex = -1;
  100.            
  101.     // CRITICAL STATES
  102.     private var keepRequestingCriticalAnimStart : bool;             //set to true while we are trying to start critical anim
  103.    
  104.         default keepRequestingCriticalAnimStart = false;
  105.    
  106.     // EXPLORATION
  107.     private     var currentCustomAction     : EPlayerExplorationAction;
  108.     public      var substateManager         : CExplorationStateManager;
  109.     protected   var isOnBoat                : bool;                         //set to true if player is on boat (but not necessarily sailing, but e.g. standing)
  110.     protected   var isInShallowWater        : bool;
  111.     public      var medallion               : W3MedallionFX;
  112.     protected   var lastMedallionEffect     : float;
  113.     private     var isInRunAnimation        : bool;
  114.     public      var interiorTracker         :CPlayerInteriorTracker;
  115.     public      var m_SettlementBlockCanter : int;
  116.    
  117.    
  118.     // FISTFIGHT MINIGAME
  119.     private var fistFightMinigameEnabled    : bool;
  120.     private var isFFMinigameToTheDeath      : bool;
  121.     private var FFMinigameEndsithBS         : bool;
  122.     public  var fistFightTeleportNode       : CNode;
  123.     public  var isStartingFistFightMinigame : bool;
  124.     public  var GeraltMaxHealth             : float;
  125.     public  var fistsItems                  : array< SItemUniqueId >;
  126.    
  127.         default FFMinigameEndsithBS = false;
  128.         default fistFightMinigameEnabled = false;
  129.         default isFFMinigameToTheDeath = false;
  130.    
  131.     // GWINT MINIGAME
  132.     private var gwintAiDifficulty           : EGwintDifficultyMode; default gwintAiDifficulty = EGDM_Easy;
  133.     private var gwintAiAggression           : EGwintAggressionMode; default gwintAiAggression = EGAM_Defensive;
  134.     private var gwintMinigameState          : EMinigameState;       default gwintMinigameState  = EMS_None;
  135.  
  136.     // HORSE
  137.     import private  var horseWithInventory      : EntityHandle;         // if spawned handle is valid ( horse with inventory )
  138.     private         var currentlyMountedHorse   : CNewNPC; 
  139.     private         var horseSummonTimeStamp    : float;
  140.     private saved   var isHorseRacing           : bool;
  141.     private         var horseCombatSlowMo       : bool;
  142.     default isHorseRacing = false;
  143.     default horseCombatSlowMo = true;
  144.    
  145.     // HUD  FIXME - shouldn't this all be in hud / ui rather than player?
  146.     private var HudMessages : array <string>; //#B change to struct with message type, message duration etc
  147.     protected var fShowToLowStaminaIndication   : float;
  148.     public var showTooLowAdrenaline : bool;
  149.     private var HAXE3Container : W3Container; //#B temp for E3
  150.     private var HAXE3bAutoLoot: bool; //#B temp for E3
  151.     private var bShowHud : bool;
  152.     private var dodgeFeedbackTarget : CActor;
  153.    
  154.         default HAXE3bAutoLoot = false;
  155.         default fShowToLowStaminaIndication = 0.0f;
  156.         default bShowHud = true;
  157.        
  158.     saved var displayedQuestsGUID : array< CGUID >; // #B moved here because saved in journal doesn't work.
  159.     saved var rewardsMultiplier : array< SRewardMultiplier >; // #B moved here because saved in journal doesn't work.s
  160.     saved var glossaryImageOverride : array< SGlossaryImageOverride >; // #B moved here because saved in journal doesn't work.s
  161.    
  162.     // INPUT
  163.     private             var prevRawLeftJoyRot           : float;
  164.     protected           var explorationInputContext     : name;
  165.     protected           var combatInputContext          : name;
  166.     protected           var combatFistsInputContext     : name;
  167.  
  168.     // INTERACTIONS
  169.     private var isInsideInteraction         : bool;                         //set to true when player is inside any interaction range, used to prioritize input
  170.     private var isInsideHorseInteraction    : bool;                        
  171.     public  var horseInteractionSource      : CEntity;
  172.     public  var nearbyLockedContainersNoKey : array<W3LockableEntity>;      //to update tooltip if player is close to a locked container and is THEN given a key
  173.    
  174.     // MOVEMENT
  175.     private var bMoveTargetChangeAllowed    : bool;     default bMoveTargetChangeAllowed = true;
  176.     private var moveAdj                     : CMovementAdjustor;
  177.     private var defaultLocomotionController : CR4LocomotionPlayerControllerScript;
  178.     //private var isFollowing                   : bool;
  179.     //private var followingStartTime            : float;
  180.     private var canFollowNpc                : bool;
  181.     private var actorToFollow               : CActor;
  182.     public var terrainPitch                 : float;
  183.     public var steepSlopeNormalPitch        : float;    default steepSlopeNormalPitch = 65.f;
  184.     public var disableSprintTerrainPitch    : float;    default disableSprintTerrainPitch = 54.f;
  185.     private var submergeDepth           : float;
  186.    
  187.     private var m_useSelectedItemIfSpawned  : bool; default m_useSelectedItemIfSpawned = false; // Used only in WaitForItemSpawnAndProccesTask
  188.    
  189.    
  190.     var navQuery : CNavigationReachabilityQueryInterface;
  191.    
  192.     // BARBER
  193.     public saved var rememberedCustomHead : name;
  194.  
  195.     // WEATHER DISPLAY
  196.     public saved var disableWeatherDisplay : bool;
  197.    
  198.     // EPISODE1
  199.     public saved var proudWalk : bool;
  200.     private var etherealCount : int;
  201.     default etherealCount = 0;
  202.    
  203.     // EPISODE2
  204.     public saved var injuredWalk : bool;
  205.     public saved var tiedWalk : bool;
  206.     private var insideDiveAttackArea : bool;
  207.     default insideDiveAttackArea = false;
  208.     private var diveAreaNumber : int;
  209.     default diveAreaNumber = -1;
  210.    
  211.     // CAMERA
  212.     private var flyingBossCamera : bool;
  213.     default flyingBossCamera = false;
  214.    
  215.     public function SetFlyingBossCamera( val : bool ) { flyingBossCamera = val; }
  216.     public function GetFlyingBossCamera() : bool { return flyingBossCamera; }
  217.    
  218.     // TOOLTIP
  219.     public saved var upscaledTooltipState : bool;
  220.     default upscaledTooltipState = false;
  221.    
  222.     // PHANTOM WEAPON
  223.     private var phantomWeaponMgr : CPhantomWeaponManager;
  224.    
  225.     /*public var    bonePositionCam     : Vector;
  226.    
  227.     public function SetBonePositionCam( pos : Vector )
  228.     {
  229.         bonePositionCam = pos;
  230.     }*/
  231.  
  232.     function EnablePCMode( flag : bool )
  233.     {
  234.         pcMode = flag;
  235.     }
  236.    
  237.     public function IsPCModeEnabled() : bool
  238.     {
  239.         return pcMode && theInput.LastUsedPCInput();
  240.     }  
  241.    
  242.     public function ShouldUsePCModeTargeting() : bool
  243.     {
  244.         return IsPCModeEnabled() && !lastAxisInputIsMovement;
  245.     }      
  246.    
  247.     public function SetDodgeFeedbackTarget( target : CActor )
  248.     {
  249.         dodgeFeedbackTarget = target;
  250.     }
  251.  
  252.     public function GetDodgeFeedbackTarget() : CActor
  253.     {
  254.         return dodgeFeedbackTarget;
  255.     }
  256.    
  257.     public function SetSubmergeDepth( depth : float )
  258.     {
  259.         submergeDepth = depth;
  260.     }
  261.  
  262.     public function GetSubmergeDepth() : float
  263.     {
  264.         return submergeDepth;
  265.     }  
  266.    
  267.     // ONELINERS
  268.     editable var delayBetweenIllusionOneliners : float;
  269.        
  270.         hint delayBetweenIllusionOneliners = "delay in secs between oneliners about illusionary objects";
  271.        
  272.         default delayBetweenIllusionOneliners = 5;
  273.    
  274.     // Battlecry
  275.     private         var battlecry_timeForNext           : float;
  276.     private         var battlecry_delayMin              : float;    default battlecry_delayMin = 15;
  277.     private         var battlecry_delayMax              : float;    default battlecry_delayMax = 60;
  278.     private         var battlecry_lastTry               : name;
  279.    
  280.     // Weather 
  281.     private         var previousWeather                 : name;
  282.     private         var previousRainStrength            : float;
  283.    
  284.     //OTHER
  285.     protected var receivedDamageInCombat    : bool;         //set when you got hit
  286.     protected var prevDayNightIsNight       : bool;         //Day-Night cycle check - value of previous check
  287.     //Shaedhen - Atmospheric Nights - Starts here
  288.     var environmentDN : CEnvironmentDefinition; //Will be used to store darkness_upon_us
  289.     var environmentDN2 : CEnvironmentDefinition; //Will be used to store darkness_upon_us
  290.     var environmentDNegated : CEnvironmentDefinition; //Will be used to store darkness_upon_us
  291.     private var envIdDN                                 : Int32; //Id to deactivate darkness_upon_us
  292.     default envIdDN = -1;
  293.     private var envIdDN2                                : Int32; //Id to deactivate darkness_upon_us
  294.     default envIdDN2 = -1;
  295.     private var envIdDNegated                               : Int32; //Id to deactivate darkness_upon_us
  296.     default envIdDNegated = -1;
  297.     private var inGameConfigWrapperDN               : CInGameConfigWrapper;
  298.     var intensityDN :           array<float>;
  299.     var startDN : int;
  300.     default startDN = 1200;
  301.     var startTimeDN : int;
  302.     default startTimeDN = 120;
  303.     var endDN : int;
  304.     default endDN = 180;
  305.     var endTimeDN : int;
  306.     default endTimeDN = 180;
  307.     public var realHoursPerMinutesDN : float;
  308.     default realHoursPerMinutesDN = 0.25;
  309.     private var justSpawnedDN : bool;
  310.     private var isEnabledDN : bool;
  311.     private var listOfStartTimesDK              : array<int>;
  312.     private var listOfStartDurationTimesDK      : array<int>;
  313.     private var listOfEndTimesDK                : array<int>;
  314.     private var listOfEndDurationTimesDK        : array<int>;
  315.     //Shaedhen - Atmospheric Nights - Ends here    
  316.     public  var failedFundamentalsFirstAchievementCondition : bool;    
  317.    
  318.     private var spawnedTime                 : float;
  319.  
  320.     public  var currentMonsterHuntInvestigationArea : W3MonsterHuntInvestigationArea;      
  321.  
  322.     private var isPerformingPhaseChangeAnimation : bool;    // flag for suppressing game camera update during synced animation in eredin fight
  323.     default isPerformingPhaseChangeAnimation = false;
  324.    
  325.         default receivedDamageInCombat = false;
  326.        
  327.     // PLAYER MODE
  328.     public              var playerMode                  : W3PlayerMode;
  329.        
  330.     // QUICKSLOTS
  331.     protected saved var selectedItemId                  : SItemUniqueId;    //id of item selected from quickslots
  332.     protected saved var blockedRadialSlots              : array < SRadialSlotDef >; // radial menu slots blocked by different sources
  333.    
  334.     // SOFT LOCK TARGETING
  335.     public              var enemyCollectionDist         : float;
  336.     public              var findMoveTargetDistMin       : float;            //distance from player to get softlocked targets
  337.     public              var findMoveTargetDistMax       : float;            //distance from player that target gets disengaged from soft lock
  338.     private             var findMoveTargetScaledFrame   : float;            //xaxis scale to find non-hostile targets when stationary
  339.     public              var interactDist                : float;            //distance from player to attack or interact with a non-hostile npc
  340.     protected           var bCanFindTarget              : bool;
  341.     private             var bIsConfirmingEmptyTarget    : bool;
  342.     private             var displayTarget               : CGameplayEntity;  //entity to show health bar on hud;
  343.     private             var isShootingFriendly          : bool;
  344.    
  345.         // W3EE- Begin
  346.         default findMoveTargetDistMax = 30.f;
  347.         // W3EE - End
  348.         default findMoveTargetScaledFrame = 0.5f;
  349.         default interactDist = 3.5f;
  350.    
  351.     //Target Selection
  352.     private var currentSelectedTarget           : CActor;
  353.     private var selectedTargetToConfirm         : CActor;
  354.     private var bConfirmTargetTimerIsEnabled    : bool;
  355.        
  356.     // THROWABLES  
  357.     public saved        var thrownEntityHandle          : EntityHandle;     //entity of currently thrown item (in aiming)  
  358.     private             var isThrowingItemWithAim       : bool;
  359.     private saved       var isThrowingItem              : bool;             //used for aim mode to check if we're in throwing logic
  360.     private             var isThrowHoldPressed          : bool;
  361.    
  362.     // CROSSBOW
  363.     private             var isAimingCrossbow            : bool;
  364.    
  365.         default isThrowingItemWithAim = false;
  366.        
  367.     // AIMING MODE
  368.     public              var playerAiming                : PlayerAiming;
  369.            
  370.     // DISMEMBERMENT
  371.     public var forceDismember           : bool;
  372.     public var forceDismemberName       : name;
  373.     public var forceDismemberChance     : int;
  374.     public var forceDismemberExplosion  : bool;
  375.    
  376.     // FINISHER
  377.     private var finisherVictim          : CActor;
  378.     public var forceFinisher            : bool;
  379.     public var forceFinisherAnimName    : name;
  380.     public var forceFinisherChance      : int; 
  381.     public var forcedStance             : bool;
  382.  
  383.     // WEAPON COLLISION FX
  384.     private var m_WeaponFXCollisionGroupNames   : array <name>;
  385.     private var m_CollisionEffect               : CEntity;
  386.     private var m_LastWeaponTipPos              : Vector;
  387.     private var m_CollisionFxTemplate           : CEntityTemplate;
  388.     private var m_RefreshWeaponFXType           : bool;
  389.     private var m_PlayWoodenFX                  : bool;
  390.    
  391.     // POSTERS
  392.     private var m_activePoster                  : W3Poster;
  393.    
  394.     public function SetActivePoster ( poster :  W3Poster )
  395.     {
  396.         m_activePoster = poster;
  397.     }
  398.    
  399.     public function RemoveActivePoster ()
  400.     {
  401.         m_activePoster = NULL;
  402.     }
  403.    
  404.     public function GetActivePoster () : W3Poster
  405.     {
  406.         return m_activePoster;
  407.     }
  408.     // SAVE / LOAD
  409.     //private saved var safePositionStored: bool;           default safePositionStored = false;
  410.     //private saved var lastSafePosition    : Vector;
  411.     //private saved var lastSafeRotation    : EulerAngles;
  412.    
  413.     public var horseOnNavMesh : bool;
  414.     default horseOnNavMesh = true;
  415.    
  416.     public function SetHorseNav( val : bool ) { horseOnNavMesh = val; }
  417.    
  418.     // TEST
  419.     public var testAdjustRequestedMovementDirection : bool; // TEST
  420.         default testAdjustRequestedMovementDirection = false;
  421.        
  422.     // State
  423.     default autoState   = 'Exploration';
  424.    
  425.     ///////////////////////////////////////////////////////////////////////////
  426.     ///////////////////  IMPORTED C++ FUNCTIONS  //////////////////////////////
  427.     ///////////////////////////////////////////////////////////////////////////
  428.    
  429.     // All following functions give cached data from previous frame
  430.     import final function GetEnemiesInRange( out enemies : array< CActor > );
  431.     import final function GetVisibleEnemies( out enemies : array< CActor > );
  432.     import final function IsEnemyVisible( enemy : CActor ) : bool;
  433.    
  434.     // Set this up in order to use above functions and get the proper data
  435.     import final function SetupEnemiesCollection(   range, heightTolerance  : float,
  436.                                                     maxEnemies              : int,
  437.                                                     optional tag            : name,
  438.                                                     optional flags          : int ); // please combine EScriptQueryFlags - FLAG_ExcludePlayer is always on
  439.  
  440.     import final function IsInInterior() : bool;
  441.     import final function IsInSettlement() : bool;
  442.     import final function EnterSettlement( isEntering : bool );
  443.     import final function ActionDirectControl( controller : CR4LocomotionDirectController ) : bool;
  444.     import final function SetPlayerTarget( target : CActor );
  445.     import final function SetPlayerCombatTarget( target : CActor );
  446.     import final function ObtainTicketFromCombatTarget( ticketName : CName, ticketsCount : int );
  447.     import final function FreeTicketAtCombatTarget();
  448.     import final function SetScriptMoveTarget( target : CActor );
  449.     import final function GetRiderData() : CAIStorageRiderData;
  450.     import final function SetIsInCombat( inCombat : bool );
  451.     import final function SaveLastMountedHorse( mountedHorse : CActor );
  452.    
  453.     import final function SetBacklightFromHealth( healthPercentage : float );
  454.     import private final function SetBacklightColor( color : Vector );
  455.    
  456.     import final function GetCombatDataComponent() : CCombatDataComponent;
  457.    
  458.     import final function GetTemplatePathAndAppearance( out templatePath : string, out appearance : name );
  459.    
  460.     import final function HACK_BoatDismountPositionCorrection( slotPos : Vector );
  461.    
  462.     import final function HACK_ForceGetBonePosition( boneIndex : int ) : Vector;
  463.    
  464.    
  465.     public function GetLevel() : int
  466.     {
  467.         return 0;
  468.     }
  469.    
  470.     ///////////////////////////////////////////////////////////////////////////
  471.     // (new) targeting
  472.    
  473.     var targeting               : CR4PlayerTargeting;
  474.     var targetingPrecalcs       : SR4PlayerTargetingPrecalcs;
  475.     var targetingIn             : SR4PlayerTargetingIn;
  476.     var targetingOut            : SR4PlayerTargetingOut;   
  477.     var useNativeTargeting      : bool;
  478.     default useNativeTargeting  = true;
  479.    
  480.     var visibleActors           : array< CActor >;
  481.     var visibleActorsTime       : array< float >;
  482.    
  483.     ///////////////////////////////////////////////////////////////////////////
  484.     // W3EE - Begin
  485.     timer function RefreshDamSett( dt : float, id : int )
  486.     {  
  487.         Options().FirstTimeOptionSetup();
  488.         Damage().RefreshSettings();
  489.     }
  490.     // W3EE - End
  491.        
  492.     event OnSpawned( spawnData : SEntitySpawnData )
  493.     {
  494.         var atts : array<name>;
  495.         var skill : ESkill;
  496.         var i : int;
  497.         var item : SItemUniqueId;
  498.        
  499.         //---=== modFriendlyHUD ===---
  500.         fHUDConfig = new CModFriendlyHUDConfig in this;
  501.         fHUDConfig.Init();
  502.         //---=== modFriendlyHUD ===---
  503.        
  504.         AddAnimEventCallback('ThrowHoldTest',           'OnAnimEvent_ThrowHoldTest');
  505.         AddAnimEventCallback('OnWeaponDrawReady',       'OnAnimEvent_OnWeaponDrawReady');
  506.         AddAnimEventCallback('OnWeaponHolsterReady',    'OnAnimEvent_OnWeaponHolsterReady');
  507.         AddAnimEventCallback('AllowTempLookAt',         'OnAnimEvent_AllowTempLookAt');
  508.         AddAnimEventCallback('SlideToTarget',           'OnAnimEvent_SlideToTarget');
  509.         AddAnimEventCallback('PlayFinisherBlood',       'OnAnimEvent_PlayFinisherBlood');
  510.         AddAnimEventCallback('SlowMo',                  'OnAnimEvent_SlowMo');
  511.         AddAnimEventCallback('BloodTrailForced',        'OnAnimEvent_BloodTrailForced');
  512.         AddAnimEventCallback('FadeOut',                 'OnAnimEvent_FadeOut');
  513.         AddAnimEventCallback('FadeIn',                  'OnAnimEvent_FadeIn');
  514.         AddAnimEventCallback('DisallowHitAnim',         'OnAnimEvent_DisallowHitAnim');
  515.         AddAnimEventCallback('AllowFall',               'OnAnimEvent_AllowFall');
  516.         AddAnimEventCallback('AllowFall2',              'OnAnimEvent_AllowFall2'); 
  517.         AddAnimEventCallback('DettachGround',           'OnAnimEvent_DettachGround');  
  518.         AddAnimEventCallback('KillWithRagdoll',         'OnAnimEvent_KillWithRagdoll');
  519.         AddAnimEventCallback('pad_vibration',           'OnAnimEvent_pad_vibration');  
  520.         AddAnimEventCallback('pad_vibration_light',     'OnAnimEvent_pad_vibration_light');
  521.         AddAnimEventCallback('RemoveBurning',           'OnAnimEvent_RemoveBurning');
  522.         AddAnimEventCallback('RemoveTangled',           'OnAnimEvent_RemoveTangled');
  523.         AddAnimEventCallback('MoveNoise',               'OnAnimEvent_MoveNoise');
  524.        
  525.         AddItemPerLevelList();
  526.        
  527.         enemyCollectionDist = findMoveTargetDistMax;
  528.        
  529.         //retrofix - removing saved timescale
  530.         theGame.RemoveTimeScale('horse_melee');
  531.        
  532.         //give items
  533.         if(!spawnData.restored && !((W3ReplacerCiri)this) )
  534.         {
  535.             AddTimer('GiveStartingItems', 0.00001, true, , , true);
  536.            
  537.             if(!theGame.IsFinalBuild())
  538.             {
  539.                 //unlock skills for testing purposes
  540.                 AddAbility('GeraltSkills_Testing');            
  541.                 AddTimer('Debug_GiveTestingItems',0.0001,true);        
  542.             }
  543.            
  544.             //disable retro-stash-tutorial on fresh playthroughs
  545.             FactsAdd("tut_stash_fresh_playthrough");
  546.         }
  547.        
  548.         InitTargeting();
  549.        
  550.         // After load
  551.         if( spawnData.restored )
  552.         {
  553.             // ED this line was not called before, because of extra if conditions regarding "safe position stored"  but it was uncommented
  554.             //OnUseSelectedItem(); 
  555.            
  556.             theGame.GameplayFactsRemove( "in_combat" );
  557.         }
  558.        
  559.        
  560.         // Create the sword holster (it is a saved property, there is no need of re-creating it when playing from save)
  561.         if ( !weaponHolster )
  562.         {
  563.             weaponHolster = new WeaponHolster in this;
  564.         }      
  565.         // temp workaround of not saving states:
  566.         weaponHolster.Initialize( this, spawnData.restored );
  567.        
  568.         if ( !interiorTracker )
  569.         {
  570.             interiorTracker = new CPlayerInteriorTracker in this;
  571.         }
  572.         interiorTracker.Init( spawnData.restored );
  573.        
  574.        
  575.         super.OnSpawned( spawnData );
  576.  
  577.         // Create medallion
  578.         medallion = new W3MedallionFX in this;
  579.        
  580.         playerMode = new W3PlayerMode in this;
  581.         playerMode.Initialize( this );
  582.        
  583.         // Initialize Aiming Mode
  584.         playerAiming = new PlayerAiming in this;
  585.         playerAiming.Initialize( this );
  586.        
  587.         // Initialize reachability query
  588.         navQuery = new CNavigationReachabilityQueryInterface in this;
  589.        
  590.         // Start looking for soft-lock targets
  591.         EnableFindTarget( true );
  592.         AddTimer( 'CombatCheck', 0.2f, true );
  593.        
  594.         // Get the exploration state manager component
  595.         substateManager = ( CExplorationStateManager ) GetComponentByClassName( 'CExplorationStateManager' );
  596.        
  597.         findMoveTargetDist = findMoveTargetDistMax;
  598.        
  599.         SetupEnemiesCollection( enemyCollectionDist, findMoveTargetDist, 10, 'None', FLAG_Attitude_Neutral + FLAG_Attitude_Hostile + FLAG_Attitude_Friendly + FLAG_OnlyAliveActors );
  600.        
  601.         //for geralt-replacer switching
  602.         inputHandler.RemoveLocksOnSpawn();
  603.        
  604.         // Player has the lowest push priority
  605.         ((CActor) this ).SetInteractionPriority( IP_Prio_0 );
  606.        
  607.         prevDayNightIsNight = theGame.envMgr.IsNight();
  608.         //Shaedhen - Atmospheric Nights - Starts here
  609.         environmentDN = (CEnvironmentDefinition)LoadResource("fx\demos_and_temp_fx\darkness_upon_us.env",true);
  610.         environmentDN2 = (CEnvironmentDefinition)LoadResource("fx\demos_and_temp_fx\darkness_upon_us.env",true);
  611.         environmentDNegated = (CEnvironmentDefinition)LoadResource("fx\demos_and_temp_fx\darkness_upon_us.env",true);
  612.         envIdDN = -1;
  613.         envIdDN2 = -1; 
  614.         envIdDNegated = -1;
  615.         justSpawnedDN = true;
  616.         InitAtmosphericNights();
  617.         UpdateValuesDK();
  618.         //Shaedhen - Atmospheric Nights - Ends here
  619.         CheckDayNightCycle();
  620.         justSpawnedDN = false; //Shaedhen - Atmospheric Nights
  621.        
  622.         // Debug
  623.         EnableVisualDebug( SHOW_AI, true );
  624.        
  625.         //oneliners delay
  626.         FactsRemove("blocked_illusion_oneliner");  
  627.        
  628.         SetFailedFundamentalsFirstAchievementCondition(false);
  629.         m_CollisionFxTemplate   = (CEntityTemplate) LoadResource( 'sword_colision_fx' );
  630.         if( m_WeaponFXCollisionGroupNames.Size() == 0 )
  631.         {
  632.             m_WeaponFXCollisionGroupNames.PushBack('Static');
  633.             m_WeaponFXCollisionGroupNames.PushBack('Foliage');
  634.             m_WeaponFXCollisionGroupNames.PushBack('Fence');
  635.             m_WeaponFXCollisionGroupNames.PushBack('BoatSide');
  636.             m_WeaponFXCollisionGroupNames.PushBack('Door');
  637.             m_WeaponFXCollisionGroupNames.PushBack('RigidBody');
  638.             m_WeaponFXCollisionGroupNames.PushBack('Dynamic');
  639.             m_WeaponFXCollisionGroupNames.PushBack('Destructible');
  640.         }
  641.        
  642.         if ( counterCollisionGroupNames.Size() == 0 )
  643.         {
  644.             counterCollisionGroupNames.PushBack('Static');
  645.             counterCollisionGroupNames.PushBack('Foliage');
  646.             counterCollisionGroupNames.PushBack('Fence');
  647.             counterCollisionGroupNames.PushBack('Terrain');
  648.             counterCollisionGroupNames.PushBack('Door');
  649.             counterCollisionGroupNames.PushBack('RigidBody');
  650.             counterCollisionGroupNames.PushBack('Dynamic');
  651.             counterCollisionGroupNames.PushBack('Destructible');
  652.         }
  653.        
  654.         //ps4 pad backlight color
  655.         ResetPadBacklightColor();
  656.        
  657.         if( spawnData.restored )
  658.         {
  659.             if (IsCurrentlyUsingItemL())
  660.             {
  661.                 if (inv.HasItemById( currentlyEquipedItemL ))
  662.                 {
  663.                     OnUseSelectedItem();
  664.                 }
  665.                 else
  666.                 {
  667.                     HideUsableItem(true);
  668.                 }
  669.             }
  670.             if ( GetCurrentMeleeWeaponType() == PW_Steel || GetCurrentMeleeWeaponType() == PW_Silver )
  671.             {
  672.                 OnEquipMeleeWeapon(GetCurrentMeleeWeaponType(), true, true);
  673.             }
  674.            
  675.             AddTimer( 'UnmountCrossbowTimer', 0.01, true );
  676.            
  677.             ClearBlockedSlots();
  678.         }
  679.        
  680.         ((CR4PlayerStateSwimming)this.GetState('Swimming')).OnParentSpawned();
  681.        
  682.         //hack for possible immortality from finishers
  683.         SetImmortalityMode( AIM_None, AIC_SyncedAnim );
  684.        
  685.         //disable Dimeritium Bomb skill locks after load
  686.         theGame.GetDefinitionsManager().GetContainedAbilities('DwimeritiumBomb_3', atts);
  687.         for(i=0; i<atts.Size(); i+=1)
  688.         {
  689.             skill = SkillNameToEnum(atts[i]);
  690.             if(skill != S_SUndefined)
  691.                 BlockSkill(skill, false);      
  692.         }
  693.        
  694.         // phantom weapon manager
  695.         this.GetInventory().GetItemEquippedOnSlot( EES_SteelSword, item );
  696.         if( this.GetInventory().ItemHasTag( item, 'PhantomWeapon' ) )
  697.         {
  698.             this.InitPhantomWeaponMgr();
  699.         }
  700.  
  701.         //retoractive fix
  702.         if(FactsQuerySum("mq3036_fact_done") > 0)
  703.             BlockAllActions('mq3036', false);
  704.        
  705.         spawnedTime = theGame.GetEngineTimeAsSeconds();
  706.        
  707.         if ( theGame.GetInGameConfigWrapper().GetVarValue('Gameplay', 'EnableUberMovement' ) == "1" )
  708.             theGame.EnableUberMovement( true );
  709.         else
  710.             theGame.EnableUberMovement( false );
  711.        
  712.         // Initial level for Gwint Difficulty (Normal)
  713.         if ( !FactsDoesExist("gwent_difficulty") )
  714.             FactsAdd("gwent_difficulty", 2);
  715.            
  716.         //NG+
  717.         if(!newGamePlusInitialized && FactsQuerySum("NewGamePlus") > 0)
  718.         {
  719.             NewGamePlusInitialize();
  720.         }
  721.        
  722.         // W3EE - Begin
  723.         AddTimer('RefreshDamSett', 2, false);
  724.         UnblockAction(EIAB_OpenMeditation, 'ExplorationMeditation');
  725.         // W3EE - End
  726.        
  727.         if( lastInstantKillTime > theGame.GetGameTime() )
  728.         {
  729.             SetLastInstantKillTime( GameTimeCreate(0) );
  730.         }
  731.     }
  732.    
  733.     public function NewGamePlusInitialize()
  734.     {
  735.         //reset instant kill cooldown
  736.         SetLastInstantKillTime( GameTimeCreate(0) );
  737.     }
  738.    
  739.     public function GetTimeSinceSpawned() : float
  740.     {
  741.         return theGame.GetEngineTimeAsSeconds() - spawnedTime;
  742.     }
  743.    
  744.     timer function UnmountCrossbowTimer( dt : float, id : int )
  745.     {
  746.         var itemId : SItemUniqueId;
  747.        
  748.         itemId = this.inv.GetItemFromSlot( 'l_weapon' );
  749.         if ( inv.IsIdValid( itemId ) && inv.IsItemCrossbow( itemId ) )
  750.         {
  751.             rangedWeapon = (Crossbow)( inv.GetItemEntityUnsafe( itemId ) );
  752.            
  753.             if (rangedWeapon)
  754.             {  
  755.                 rangedWeapon.Initialize( (CActor)( rangedWeapon.GetParentEntity() ) );
  756.                 OnRangedForceHolster( true, true );
  757.                 RemoveTimer( 'UnmountCrossbowTimer' );
  758.             }
  759.         }
  760.         else
  761.             RemoveTimer( 'UnmountCrossbowTimer' );
  762.     }
  763.    
  764.     event OnDestroyed()
  765.     {
  766.         playerAiming.RemoveAimingSloMo();
  767.        
  768.         if(rangedWeapon)
  769.             rangedWeapon.ClearDeployedEntity(true);
  770.            
  771.         ResetPadBacklightColor();
  772.        
  773.         //remove combat mode no-save lock
  774.         theGame.ReleaseNoSaveLock( noSaveLock );
  775.     }
  776.    
  777.     /////////////////////////////////////////////////////////////////////
  778.     ////////////////////////Radial Menu//////////////////////////////////
  779.     ////////////////////////////////////////////////////////////////////
  780.    
  781.     public function GetBlockedSlots () : array < SRadialSlotDef >
  782.     {
  783.         return blockedRadialSlots;
  784.     }
  785.    
  786.     public function  ClearBlockedSlots()
  787.     {
  788.         var i                : int;
  789.         //var blockedSigns   : array<ESignType>;
  790.         //var playerWitcher  : W3PlayerWitcher;
  791.        
  792.         for ( i = 0; i < blockedRadialSlots.Size(); i+=1 )
  793.         {
  794.             if( !IsSwimming() )
  795.             {
  796.                 if ( EnableRadialSlot(blockedRadialSlots[i].slotName, 'swimming'))
  797.                 {
  798.                     i-=1;
  799.                     continue;
  800.                 }
  801.             }
  802.             if (!IsUsingVehicle())
  803.             {
  804.                 if ( EnableRadialSlot(blockedRadialSlots[i].slotName, 'useVehicle'))
  805.                 {
  806.                     i-=1;
  807.                     continue;
  808.                 }
  809.             }
  810.             if ( !IsCurrentlyUsingItemL() || !IsUsableItemLBlocked() )
  811.             {
  812.                 if ( EnableRadialSlot(blockedRadialSlots[i].slotName, 'usableItemL'))
  813.                 {
  814.                     i-=1;
  815.                     continue;
  816.                 }
  817.             }
  818.             if ( !IsThrowingItem() )
  819.             {
  820.                 if ( EnableRadialSlot(blockedRadialSlots[i].slotName, 'throwBomb'))
  821.                 {
  822.                     i-=1;
  823.                     continue;
  824.                 }
  825.             }
  826.         }
  827.         // this is a hack that had to be added because someone ignored existing functionality of blocking radial slots propely and created BlockSignSelection. Unfortunately to keep the backwawrd compatibility I had to hack it.
  828.         /*playerWitcher = (W3PlayerWitcher)this;
  829.        
  830.         if ( playerWitcher )
  831.         {
  832.             blockedSigns = playerWitcher.GetBlockedSigns();
  833.            
  834.             i = 0;
  835.             for ( i = 0; i < blockedSigns.Size(); i+=1 )
  836.             {
  837.                 switch( blockedSigns[i] )
  838.                 {
  839.                     case ST_Aard :
  840.                         if ( !IsRadialSlotBlocked ( 'Aard') )
  841.                         {
  842.                             playerWitcher.BlockSignSelection(ST_Aard, false);
  843.                         }
  844.                         break;
  845.                     case ST_Axii :
  846.                         if ( !IsRadialSlotBlocked ( 'Axii') )
  847.                         {
  848.                             playerWitcher.BlockSignSelection(ST_Axii, false );
  849.                         }
  850.                         break;
  851.                     case ST_Igni :
  852.                         if ( !IsRadialSlotBlocked ( 'Igni') )
  853.                         {
  854.                             playerWitcher.BlockSignSelection(ST_Igni, false );
  855.                         }
  856.                         break;
  857.                     case ST_Quen :
  858.                         if ( !IsRadialSlotBlocked ( 'Quen') )
  859.                         {
  860.                             playerWitcher.BlockSignSelection(ST_Quen, false );
  861.                         }
  862.                         break;
  863.                     case ST_Yrden :
  864.                         if ( !IsRadialSlotBlocked ( 'Yrden') )
  865.                         {
  866.                             playerWitcher.BlockSignSelection(ST_Yrden, false );
  867.                         }
  868.                         break;
  869.                     default:
  870.                         break;
  871.                 }
  872.             }
  873.         }*/
  874.        
  875.     }
  876.    
  877.     public function RestoreBlockedSlots ()
  878.     {
  879.         var i : int;
  880.         var slotsToBlock : array<name>;
  881.        
  882.         for ( i = 0; i < blockedRadialSlots.Size(); i+=1 )
  883.         {
  884.             slotsToBlock.PushBack ( blockedRadialSlots[i].slotName );
  885.         }
  886.         if ( slotsToBlock.Size() > 0 )
  887.         {
  888.             EnableRadialSlots ( false, slotsToBlock );
  889.         }
  890.     }
  891.     private function DisableRadialSlot ( slotName : name, sourceName : name ) : bool
  892.     {
  893.         var i : int;
  894.         var k : int;
  895.         var slotsToBlock : array<name>;
  896.        
  897.         var blockedRadialSlotEntry : SRadialSlotDef;
  898.        
  899.         slotsToBlock.PushBack ( slotName );
  900.        
  901.         for ( i = 0; i < blockedRadialSlots.Size(); i+=1 )
  902.         {
  903.             if ( blockedRadialSlots[i].slotName == slotName )
  904.             {
  905.                 if ( sourceName != '' )
  906.                 {
  907.                     for ( k = 0; k < blockedRadialSlots[i].disabledBySources.Size(); k += 1 )
  908.                     {
  909.                         if ( blockedRadialSlots[i].disabledBySources[k] == sourceName )
  910.                         {
  911.                             return false;
  912.                         }
  913.                     }
  914.                     blockedRadialSlots[i].disabledBySources.PushBack ( sourceName );
  915.                     return false;
  916.                 }
  917.                
  918.                 return false;
  919.             }
  920.         }
  921.        
  922.         blockedRadialSlotEntry = InitBlockedRadialSlotEntry ( slotName );
  923.        
  924.         if ( sourceName != '' )
  925.         {
  926.             blockedRadialSlotEntry.disabledBySources.PushBack ( sourceName );
  927.         }
  928.         blockedRadialSlots.PushBack ( blockedRadialSlotEntry );
  929.         EnableRadialSlots ( false, slotsToBlock );
  930.         return true;
  931.     }
  932.    
  933.     public function EnableRadialSlot ( slotName : name, sourceName : name ) : bool
  934.     {
  935.         var i : int;
  936.         var k : int;
  937.        
  938.         var slotsToBlock : array<name>;
  939.        
  940.         slotsToBlock.PushBack ( slotName );
  941.        
  942.         for ( i = 0; i < blockedRadialSlots.Size(); i+=1 )
  943.         {
  944.             if ( blockedRadialSlots[i].slotName == slotName )
  945.             {
  946.            
  947.                 if ( sourceName != '' )
  948.                 {
  949.                     for ( k = 0; k < blockedRadialSlots[i].disabledBySources.Size(); k += 1 )
  950.                     {
  951.                         if ( blockedRadialSlots[i].disabledBySources[k] == sourceName  )
  952.                         {                          
  953.                             blockedRadialSlots[i].disabledBySources.Remove ( blockedRadialSlots[i].disabledBySources[k] );                         
  954.                         }
  955.                     }
  956.                 }
  957.                 if ( blockedRadialSlots[i].disabledBySources.Size() <= 0  )
  958.                 {
  959.                     blockedRadialSlots.Remove( blockedRadialSlots[i] );
  960.                     EnableRadialSlots ( true, slotsToBlock );
  961.                     return true;
  962.                 }
  963.                 return false;
  964.             }
  965.         }
  966.         return false;
  967.        
  968.     }
  969.    
  970.     private function InitBlockedRadialSlotEntry ( slotName : name ) : SRadialSlotDef
  971.     {
  972.         var blockedRadialSlotEntry : SRadialSlotDef;
  973.        
  974.         blockedRadialSlotEntry.slotName = slotName;
  975.        
  976.         return blockedRadialSlotEntry;
  977.        
  978.     }
  979.    
  980.     public function EnableRadialSlotsWithSource ( enable : bool, slotsToBlock : array < name >, sourceName : name )
  981.     {
  982.         var i : int;
  983.        
  984.         for ( i = 0; i < slotsToBlock.Size(); i+=1 )
  985.         {
  986.             if ( enable )
  987.             {
  988.                 EnableRadialSlot ( slotsToBlock[i], sourceName );
  989.             }
  990.             else
  991.             {
  992.                 DisableRadialSlot ( slotsToBlock[i], sourceName );
  993.             }
  994.         }
  995.         if ( blockedRadialSlots.Size() <= 0 )
  996.         {
  997.             blockedRadialSlots.Clear();
  998.         }
  999.     }
  1000.    
  1001.     public function IsRadialSlotBlocked ( slotName : name ) : bool
  1002.     {
  1003.         var i : int;
  1004.        
  1005.         for ( i = 0; i < blockedRadialSlots.Size(); i+=1 )
  1006.         {
  1007.             if ( blockedRadialSlots[i].slotName == slotName )
  1008.             {
  1009.                 return true;
  1010.             }
  1011.         }
  1012.         return false;
  1013.     }
  1014.    
  1015.    
  1016.     /////////////////////////////////////////////////////////////////////
  1017.     ////////////////////////////////////////////////////////////////////
  1018.     ///////////////////////  @Reapir Kits  ////////////////////////////////////
  1019.     ////////////////////////////////////////////////////////////////////
  1020.     public function RepairItem (  rapairKitId : SItemUniqueId, usedOnItem : SItemUniqueId );
  1021.     public function HasRepairAbleGearEquiped () : bool;
  1022.     public function HasRepairAbleWaponEquiped () : bool;
  1023.     public function IsItemRepairAble ( item : SItemUniqueId ) : bool;
  1024.    
  1025.     /////////////////////////////////////////////////////////////////////
  1026.     ////////////////////////////////////////////////////////////////////
  1027.     ///////////////////////  @OILS  ////////////////////////////////////
  1028.     ////////////////////////////////////////////////////////////////////
  1029.     // W3EE - Begin
  1030.     public final function ReduceAllOilsAmmo( id : SItemUniqueId, isHeavyAttack : bool )
  1031.     {
  1032.         var i : int;
  1033.         var oils : array< W3Effect_Oil >;
  1034.        
  1035.         oils = inv.GetOilsAppliedOnItem( id );
  1036.        
  1037.         for( i=0; i<oils.Size(); i+=1 )
  1038.         {
  1039.             oils[ i ].ReduceAmmo(isHeavyAttack);
  1040.         }
  1041.     }
  1042.     // W3EE - End
  1043.    
  1044.     public final function ResumeOilBuffs( steel : bool )
  1045.     {
  1046.         var item : SItemUniqueId;
  1047.         var oils : array< CBaseGameplayEffect >;
  1048.         var buff, recentOil : W3Effect_Oil;
  1049.         var i : int;
  1050.        
  1051.         item = GetEquippedSword( steel );
  1052.         oils = GetBuffs( EET_Oil );
  1053.        
  1054.         if( oils.Size() > 1 )
  1055.         {
  1056.             //if we have more than 1 oil applied on sword, we need to resume most recent one as the last one
  1057.             //in order to show proper oil color on the blade
  1058.             recentOil = inv.GetNewestOilAppliedOnItem( item, false );
  1059.         }
  1060.        
  1061.         for( i=0; i<oils.Size(); i+=1 )
  1062.         {
  1063.             buff = ( W3Effect_Oil ) oils[ i ];
  1064.            
  1065.             if( recentOil && recentOil == buff )
  1066.             {
  1067.                 continue;
  1068.             }
  1069.            
  1070.             if(buff && buff.GetSwordItemId() == item )
  1071.             {
  1072.                 buff.Resume( '' );
  1073.             }
  1074.         }
  1075.        
  1076.         if( recentOil )
  1077.         {
  1078.             recentOil.Resume( '' );
  1079.         }
  1080.     }
  1081.    
  1082.     protected final function PauseOilBuffs( isSteel : bool )
  1083.     {
  1084.         var item : SItemUniqueId;
  1085.         var oils : array< CBaseGameplayEffect >;
  1086.         var buff : W3Effect_Oil;
  1087.         var i : int;
  1088.        
  1089.         item = GetEquippedSword( isSteel );
  1090.         oils = GetBuffs( EET_Oil );
  1091.        
  1092.         for( i=0; i<oils.Size(); i+=1 )
  1093.         {
  1094.             buff = ( W3Effect_Oil ) oils[ i ];
  1095.             if(buff && buff.GetSwordItemId() == item )
  1096.             {
  1097.                 buff.Pause( '', true );
  1098.             }
  1099.         }
  1100.     }
  1101.    
  1102.     public final function ManageAerondightBuff( apply : bool )
  1103.     {
  1104.         var aerondight      : W3Effect_Aerondight;
  1105.         var item            : SItemUniqueId;
  1106.        
  1107.         item = inv.GetCurrentlyHeldSword();
  1108.        
  1109.         if( inv.ItemHasTag( item, 'Aerondight' ) )
  1110.         {
  1111.             aerondight = (W3Effect_Aerondight)GetBuff( EET_Aerondight );
  1112.            
  1113.             if( apply )
  1114.             {
  1115.                 if( !aerondight )
  1116.                 {
  1117.                     AddEffectDefault( EET_Aerondight, this, "Aerondight" );
  1118.                 }
  1119.                 else
  1120.                 {
  1121.                     aerondight.Resume( 'ManageAerondightBuff' );
  1122.                 }
  1123.             }
  1124.             else
  1125.             {
  1126.                 aerondight.Pause( 'ManageAerondightBuff' );
  1127.             }
  1128.         }
  1129.     }
  1130.    
  1131.     //applies oil on given player item
  1132.     public function ApplyOil( oilId : SItemUniqueId, usedOnItem : SItemUniqueId ) : bool
  1133.     {
  1134.         var oilAbilities : array< name >;
  1135.         var ammo, ammoBonus : float;
  1136.         var dm : CDefinitionsManagerAccessor;      
  1137.         var buffParams : SCustomEffectParams;
  1138.         var oilParams : W3OilBuffParams;
  1139.         var oilName : name;
  1140.         var min, max : SAbilityAttributeValue;
  1141.         var i : int;
  1142.         var oils : array< W3Effect_Oil >;
  1143.         var existingOil : W3Effect_Oil;
  1144.        
  1145.         // W3EE - Begin
  1146.         /*
  1147.         if( !CanApplyOilOnItem( oilId, usedOnItem ) )
  1148.         {
  1149.             return false;
  1150.         }
  1151.         */
  1152.         // W3EE - End
  1153.        
  1154.         dm = theGame.GetDefinitionsManager();
  1155.         inv.GetItemAbilitiesWithTag( oilId, theGame.params.OIL_ABILITY_TAG, oilAbilities );
  1156.         oilName = inv.GetItemName( oilId );
  1157.         oils = inv.GetOilsAppliedOnItem( usedOnItem );
  1158.        
  1159.         //check if oil is already applied
  1160.         for( i=0; i<oils.Size(); i+=1 )
  1161.         {
  1162.             if( oils[ i ].GetOilItemName() == oilName )
  1163.             {
  1164.                 existingOil = oils[ i ];
  1165.                 break;
  1166.             }
  1167.         }
  1168.        
  1169.         //remove previous oil
  1170.         if( !existingOil )
  1171.         {
  1172.             if( !GetWitcherPlayer() || !GetWitcherPlayer().IsSetBonusActive( EISB_Wolf_1 ) )
  1173.             {
  1174.                 inv.RemoveAllOilsFromItem( usedOnItem );
  1175.             }
  1176.             else
  1177.             {
  1178.                 dm.GetAbilityAttributeValue( GetSetBonusAbility( EISB_Wolf_1 ), 'max_oils_count', min, max );
  1179.                 if( inv.GetActiveOilsAppliedOnItemCount( usedOnItem ) >= CalculateAttributeValue( max ) )
  1180.                 {
  1181.                     inv.RemoveOldestOilFromItem( usedOnItem );
  1182.                 }
  1183.             }
  1184.         }
  1185.        
  1186.         //set charges
  1187.         ammo = CalculateAttributeValue(inv.GetItemAttributeValue(oilId, 'ammo'));
  1188.        
  1189.         // W3EE - Begin
  1190.         if( Options().GetGlobalOilDuration() )
  1191.             ammo = Options().GetGlobalOilDuration();
  1192.         else
  1193.         if( Options().GetMinimumOilDuration() )
  1194.             ammo += Options().GetMinimumOilDuration();
  1195.        
  1196.         ammo *= Options().GetOilDurationMult();
  1197.        
  1198.         if( ((W3PlayerWitcher)this).IsMeditating() )
  1199.             ammo *= 1.2f;
  1200.         // W3EE - End
  1201.        
  1202.         if(CanUseSkill(S_Alchemy_s06))
  1203.         {
  1204.             // W3EE - Begin
  1205.             ammoBonus = 0.3f; //CalculateAttributeValue(GetSkillAttributeValue(S_Alchemy_s06, 'ammo_bonus', false, false));
  1206.             // W3EE - End
  1207.             ammo *= 1 + ammoBonus * GetSkillLevel(S_Alchemy_s06);
  1208.         }
  1209.        
  1210.         //add new oil
  1211.         if( existingOil )
  1212.         {
  1213.             existingOil.Reapply( RoundMath( ammo ) );
  1214.         }
  1215.         else
  1216.         {
  1217.             buffParams.effectType = EET_Oil;
  1218.             buffParams.creator = this;
  1219.             oilParams = new W3OilBuffParams in this;
  1220.             oilParams.iconPath = dm.GetItemIconPath( oilName );
  1221.             oilParams.localizedName = dm.GetItemLocalisationKeyName( oilName );
  1222.             oilParams.localizedDescription = dm.GetItemLocalisationKeyName( oilName );
  1223.             oilParams.sword = usedOnItem;
  1224.             oilParams.maxCount = RoundMath( ammo );
  1225.             oilParams.currCount = RoundMath( ammo );
  1226.             oilParams.oilAbilityName = oilAbilities[ 0 ];
  1227.             oilParams.oilItemName = oilName;
  1228.             buffParams.buffSpecificParams = oilParams;
  1229.            
  1230.             AddEffectCustom( buffParams );
  1231.            
  1232.             delete oilParams;
  1233.         }
  1234.        
  1235.         LogOils("Added oil <<" + oilName + ">> to <<" + inv.GetItemName( usedOnItem ) + ">>");
  1236.        
  1237.         //fundamentals first achievement
  1238.         SetFailedFundamentalsFirstAchievementCondition( true );    
  1239.        
  1240.         theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_OnOilApplied );
  1241.        
  1242.         if( !inv.IsItemHeld( usedOnItem ) )
  1243.         {
  1244.             PauseOilBuffs( inv.IsItemSteelSwordUsableByPlayer( usedOnItem ) );
  1245.         }
  1246.        
  1247.         // W3EE - Begin
  1248.         inv.SingletonItemRemoveAmmo(oilId, 1);
  1249.         if( !inv.GetItemModifierInt(oilId, 'ammo_current') )
  1250.             inv.RemoveItem(oilId, 1);
  1251.         ((CR4InventoryMenu)((CR4MenuBase)theGame.GetGuiManager().GetRootMenu() ).GetSubMenu()).updateCurrentTab();
  1252.         // W3EE - End
  1253.        
  1254.         return true;
  1255.     }
  1256.    
  1257.     // Returns true if given sword type is upgraded with given oil
  1258.     public final function IsEquippedSwordUpgradedWithOil(steel : bool, optional oilName : name) : bool
  1259.     {
  1260.         var sword : SItemUniqueId;
  1261.         var i : int;
  1262.         var oils : array< W3Effect_Oil >;
  1263.    
  1264.         sword = GetEquippedSword( steel );             
  1265.         if( !inv.IsIdValid( sword ) )
  1266.         {
  1267.             return false;
  1268.         }
  1269.    
  1270.         if( oilName == '' )
  1271.         {
  1272.             return inv.ItemHasAnyActiveOilApplied( sword );
  1273.         }
  1274.        
  1275.         oils = inv.GetOilsAppliedOnItem( sword );
  1276.         for( i=0; i<oils.Size(); i+=1 )
  1277.         {
  1278.             if( oils[ i ].GetOilItemName() == oilName )
  1279.             {
  1280.                 return true;
  1281.             }
  1282.         }
  1283.        
  1284.         return false;
  1285.     }
  1286.    
  1287.     public function CanApplyOilOnItem(oilId : SItemUniqueId, usedOnItem : SItemUniqueId) : bool
  1288.     {
  1289.         if(inv.ItemHasTag(oilId, theGame.params.TAG_STEEL_OIL) && inv.IsItemSteelSwordUsableByPlayer(usedOnItem))
  1290.             return true;
  1291.            
  1292.         if(inv.ItemHasTag(oilId, theGame.params.TAG_SILVER_OIL) && inv.IsItemSilverSwordUsableByPlayer(usedOnItem))
  1293.             return true;
  1294.            
  1295.         return false;
  1296.     }
  1297.     ////////////////////////////////////////////////////////////////////
  1298.    
  1299.     public final function DidFailFundamentalsFirstAchievementCondition() : bool
  1300.     {
  1301.         return failedFundamentalsFirstAchievementCondition;
  1302.     }
  1303.    
  1304.     public final function SetFailedFundamentalsFirstAchievementCondition(b : bool)
  1305.     {
  1306.         var i : int;
  1307.         var npc : CNewNPC;
  1308.        
  1309.         failedFundamentalsFirstAchievementCondition = b;
  1310.        
  1311.         //save info in enemy since we might run away from combat and return, triggering new combat encounter
  1312.         if(failedFundamentalsFirstAchievementCondition)
  1313.         {
  1314.             for(i=0; i<hostileEnemies.Size(); i+=1)
  1315.             {
  1316.                 if(hostileEnemies[i].HasTag(theGame.params.MONSTER_HUNT_ACTOR_TAG))
  1317.                 {
  1318.                     npc = (CNewNPC)hostileEnemies[i];
  1319.                     npc.AddTag('failedFundamentalsAchievement');
  1320.                     npc.AddTimer('FundamentalsAchFailTimer', 30*60, , , , true, true);
  1321.                 }
  1322.             }
  1323.         }
  1324.     }
  1325.    
  1326.     public function IsInCombatFist() : bool
  1327.     {
  1328.         return this.GetCurrentStateName() == 'CombatFists';
  1329.     }
  1330.    
  1331.     public function IsInitialized() : bool;
  1332.    
  1333.     public function IsCiri() : bool
  1334.     {
  1335.         return ((W3ReplacerCiri)this);
  1336.     }
  1337.    
  1338.     protected function WouldLikeToMove() : bool
  1339.     {
  1340.         var speedVec : Vector;
  1341.         var speed, speedMult : float;
  1342.  
  1343.         // Get speed from input
  1344.         speedVec.X = theInput.GetActionValue( 'GI_AxisLeftX' ); //player.mainInput.aLeftJoyX;
  1345.         speedVec.Y = theInput.GetActionValue( 'GI_AxisLeftY' );//player.mainInput.aLeftJoyY;
  1346.         speed = VecLength2D( speedVec );
  1347.        
  1348.         return speed > 0.1f;
  1349.     }
  1350.  
  1351.     function HandleMovement( deltaTime : float )
  1352.     {
  1353.         // just to see if player would like to move if there would be possibility
  1354.         // example of use: movement is blocked when in critical state, but it can end earlier only if it would be desired by player
  1355.         // and this is nothing but desire to move
  1356.         // note: for some reason, when doing WouldLikeToMove()? 1.0f : 0.0f it just doesn't care and gives 0.0f
  1357.         if (WouldLikeToMove())
  1358.             SetBehaviorVariable( 'playerWouldLikeToMove', 1.0f);
  1359.         else
  1360.             SetBehaviorVariable( 'playerWouldLikeToMove', 0.0f);
  1361.  
  1362.         super.HandleMovement( deltaTime );
  1363.     }
  1364.    
  1365.     function BattleCryIsReady( ) : bool
  1366.     {
  1367.         var l_currentTime : float;
  1368.        
  1369.         l_currentTime = theGame.GetEngineTimeAsSeconds();
  1370.        
  1371.         if( l_currentTime >= battlecry_timeForNext )
  1372.         {
  1373.             return true;
  1374.         }      
  1375.         return false;
  1376.     }
  1377.    
  1378.     function PlayBattleCry( _BattleCry : name , _Chance : float, optional _IgnoreDelay, ignoreRepeatCheck : bool )
  1379.     {  
  1380.         var l_randValue         : float;
  1381.         var fact                : int;
  1382.        
  1383.         fact = FactsQuerySum("force_stance_normal");
  1384.        
  1385.         if( IsSwimming()
  1386.             || theGame.IsDialogOrCutscenePlaying()
  1387.             || IsInNonGameplayCutscene()
  1388.             || IsInGameplayScene()
  1389.             || theGame.IsCurrentlyPlayingNonGameplayScene()
  1390.             || theGame.IsFading()
  1391.             || theGame.IsBlackscreen()
  1392.             || FactsQuerySum("force_stance_normal") > 0 )
  1393.         {
  1394.             return;
  1395.         }
  1396.        
  1397.         // To avoid calling too often the same type of battle cry
  1398.         if ( !ignoreRepeatCheck )
  1399.         {
  1400.             if( battlecry_lastTry == _BattleCry )
  1401.                 return;
  1402.         }
  1403.        
  1404.         battlecry_lastTry = _BattleCry;
  1405.        
  1406.         l_randValue = RandF();
  1407.        
  1408.         // Either use delay or chance
  1409.         if( l_randValue < _Chance && ( _IgnoreDelay || BattleCryIsReady() )  )
  1410.         {
  1411.             thePlayer.PlayVoiceset( 90, _BattleCry );          
  1412.             // Restart counter
  1413.             battlecry_timeForNext = theGame.GetEngineTimeAsSeconds() + RandRangeF( battlecry_delayMax, battlecry_delayMin );
  1414.         }
  1415.        
  1416.     }
  1417.    
  1418.     public final function OnWeatherChanged()
  1419.     {
  1420.         if( IsInInterior()
  1421.             || GetCurrentStateName() != 'Exploration'
  1422.             || theGame.IsDialogOrCutscenePlaying()
  1423.             || IsInNonGameplayCutscene()
  1424.             || IsInGameplayScene()
  1425.             || theGame.IsCurrentlyPlayingNonGameplayScene()
  1426.             || theGame.IsFading()
  1427.             || theGame.IsBlackscreen()
  1428.             || GetTimeSinceSpawned() < 60 )
  1429.         {
  1430.             return;
  1431.         }
  1432.        
  1433.         AddTimer( 'CommentOnWeather', 1 );
  1434.     }
  1435.    
  1436.     public final timer function CommentOnWeather( _Delta : float, _Id : int )
  1437.     {
  1438.         var l_weather               : name;
  1439.         var l_currentArea           : EAreaName;
  1440.         var l_rand                  : float;
  1441.        
  1442.         l_weather           = GetWeatherConditionName();
  1443.        
  1444.         l_currentArea = theGame.GetCommonMapManager().GetCurrentArea();
  1445.        
  1446.         switch ( l_weather )
  1447.         {
  1448.             case 'WT_Clear':
  1449.            
  1450.                 l_rand = RandF();
  1451.                
  1452.                 if( l_rand > 0.66f && !AreaIsCold() && theGame.envMgr.IsDay() )
  1453.                 {
  1454.                     thePlayer.PlayVoiceset( 90, 'WeatherHot' );
  1455.                 }
  1456.                 else if ( l_rand > 0.33f )
  1457.                 {
  1458.                     thePlayer.PlayVoiceset( 90, 'WeatherClearingUp' );
  1459.                 }              
  1460.             break;
  1461.            
  1462.             case 'WT_Rain_Storm':
  1463.                 thePlayer.PlayVoiceset( 90, 'WeatherStormy' );
  1464.             break;
  1465.            
  1466.             case 'WT_Light_Clouds':
  1467.                 if( previousRainStrength < GetRainStrength() )
  1468.                 {
  1469.                     thePlayer.PlayVoiceset( 90, 'WeatherLooksLikeRain' );
  1470.                 }
  1471.                 else if( AreaIsCold() && previousWeather == 'WT_Clear' )
  1472.                 {
  1473.                     thePlayer.PlayVoiceset( 90, 'WeatherCold' );
  1474.                 }
  1475.             break;
  1476.            
  1477.             case 'WT_Mid_Clouds':
  1478.                 if( previousRainStrength < GetRainStrength() )
  1479.                 {
  1480.                     thePlayer.PlayVoiceset( 90, 'WeatherRaining' );
  1481.                 }
  1482.                 else if( AreaIsCold() && previousWeather == 'WT_Clear' )
  1483.                 {
  1484.                     thePlayer.PlayVoiceset( 90, 'WeatherCold' );
  1485.                 }
  1486.             break;
  1487.            
  1488.             case 'WT_Mid_Clouds_Dark':
  1489.                 if( previousWeather != 'WT_Heavy_Clouds' && previousWeather != 'WT_Heavy_Clouds_Dark' )
  1490.                     thePlayer.PlayVoiceset( 90, 'WeatherWindy' );
  1491.             break;
  1492.            
  1493.             case 'WT_Heavy_Clouds':
  1494.                 if( previousWeather != 'WT_Mid_Clouds_Dark' && previousWeather != 'WT_Heavy_Clouds_Dark' )
  1495.                     thePlayer.PlayVoiceset( 90, 'WeatherWindy' );
  1496.             break;
  1497.            
  1498.             case 'WT_Heavy_Clouds_Dark':
  1499.                 if( thePlayer.IsOnBoat() )
  1500.                 {
  1501.                     thePlayer.PlayVoiceset( 90, 'WeatherSeaWillStorm' );
  1502.                 }
  1503.                 else if( previousRainStrength < GetRainStrength() )
  1504.                 {
  1505.                     thePlayer.PlayVoiceset( 90, 'WeatherLooksLikeRain' );
  1506.                 }
  1507.                 else
  1508.                 {
  1509.                     thePlayer.PlayVoiceset( 90, 'WeatherWindy' );
  1510.                 }
  1511.             break;
  1512.            
  1513.             case 'WT_Snow':
  1514.                 if( RandF() > 0.5f )
  1515.                     thePlayer.PlayVoiceset( 90, 'WeatherSnowy' );
  1516.                 else
  1517.                     thePlayer.PlayVoiceset( 90, 'WeatherCold' );
  1518.             break;
  1519.         }  
  1520.        
  1521.         previousRainStrength    = GetRainStrength();
  1522.         previousWeather         = l_weather;
  1523.     }
  1524.    
  1525.     function CanUpdateMovement() : bool
  1526.     {
  1527.         if ( rangedWeapon
  1528.             && GetBehaviorVariable( 'fullBodyAnimWeight' ) >= 1.f
  1529.             && rangedWeapon.GetCurrentStateName() != 'State_WeaponWait' )
  1530.             return false;
  1531.            
  1532.         return true;
  1533.     }
  1534.    
  1535.     public function SetDefaultLocomotionController()
  1536.     {
  1537.         if( !defaultLocomotionController )
  1538.         {
  1539.             defaultLocomotionController = new CR4LocomotionPlayerControllerScript in this;
  1540.         }
  1541.        
  1542.         ActionDirectControl( defaultLocomotionController );
  1543.     }
  1544.        
  1545.     event OnPlayerTickTimer( deltaTime : float )
  1546.     {
  1547.         var focusModeController : CFocusModeController;
  1548.         var cnt : int;
  1549.        
  1550.         super.OnPlayerTickTimer( deltaTime );
  1551.            
  1552.         HandleMovement( deltaTime );
  1553.        
  1554.         if ( playerAiming.GetCurrentStateName() == 'Aiming' )
  1555.         {
  1556.             FindTarget();
  1557.             FindNonActorTarget( false );
  1558.             UpdateDisplayTarget();
  1559.             UpdateLookAtTarget();          
  1560.         }
  1561.         else
  1562.         {
  1563.             if( playerTickTimerPhase == 0 )
  1564.             {
  1565.                 FindTarget();
  1566.             }
  1567.             else if( playerTickTimerPhase == 1 )
  1568.             {
  1569.                 FindNonActorTarget( false );
  1570.             }
  1571.             else if ( playerTickTimerPhase == 2 )
  1572.             {
  1573.                 UpdateDisplayTarget();
  1574.                 UpdateLookAtTarget();
  1575.             }
  1576.         }
  1577.        
  1578.         //CombatModeDebug();
  1579.        
  1580.         playerTickTimerPhase = ( playerTickTimerPhase + 1 ) % 3;
  1581.        
  1582.         focusModeController = theGame.GetFocusModeController();
  1583.         focusModeController.UpdateFocusInteractions( deltaTime );
  1584.        
  1585.         //some behavior hack for critical states, moved from effectsManager.PerformUpdate() since it does not tick continuously anymore
  1586.         cnt = (int)( effectManager.GetCriticalBuffsCount() > 0 );      
  1587.         SetBehaviorVariable('hasCriticalBuff', cnt);
  1588.     }
  1589.    
  1590.     event OnDeath( damageAction : W3DamageAction )
  1591.     {
  1592.         super.OnDeath( damageAction );
  1593.        
  1594.         RemoveTimer('RequestCriticalAnimStart');
  1595.         //theInput.SetContext('Death');    
  1596.         EnableFindTarget( false );
  1597.         BlockAllActions('Death', true);
  1598.        
  1599.         EnableHardLock( false );
  1600.        
  1601.         theGame.CreateNoSaveLock( 'player_death', deathNoSaveLock, false, false );
  1602.         theGame.SetDeathSaveLockId( deathNoSaveLock );
  1603.        
  1604.         ClearHostileEnemiesList();
  1605.         RemoveReactions();
  1606.         SetPlayerCombatTarget(NULL);
  1607.         OnEnableAimingMode( false );   
  1608.        
  1609.         theGame.EnableFreeCamera( false );
  1610.     }
  1611.    
  1612.     // Called when the actor gets out of unconscious state
  1613.     function OnRevived()
  1614.     {
  1615.         super.OnRevived();
  1616.         BlockAllActions('Death', false);
  1617.        
  1618.         theGame.ReleaseNoSaveLock(deathNoSaveLock);
  1619.        
  1620.         this.RestartReactionsIfNeeded();
  1621.     }
  1622.    
  1623.     public function CanStartTalk() : bool
  1624.     {
  1625.         if ( beingWarnedBy.Size() > 0 )
  1626.             return false;
  1627.        
  1628.         return super.CanStartTalk();
  1629.     }
  1630.    
  1631.     ///////////////////////////////////////////////////////////////////////////
  1632.     // @Counters
  1633.     ///////////////////////////////////////////////////////////////////////////
  1634.    
  1635.     //caches timestamp of counter use (button press)
  1636.     public function AddCounterTimeStamp(time : EngineTime)      {counterTimestamps.PushBack(time);}
  1637.    
  1638.     /*
  1639.         This function checks if we have performed a counter
  1640.         It checks timestamps of moments when we pressed the parry/counter button in order
  1641.         to determine if the player was spamming the button. If so then this is not a counter.
  1642.        
  1643.         Returns true if the counter is valid
  1644.     */
  1645.     public function CheckCounterSpamming(attacker : CActor) : bool
  1646.     {
  1647.         var counterWindowStartTime : EngineTime;        //the time when the counter window (in anim) started
  1648.         var i, spamCounter : int;
  1649.         var reflexAction : bool;
  1650.         var testEngineTime : EngineTime;
  1651.        
  1652.         if(!attacker)
  1653.             return false;
  1654.        
  1655.         counterWindowStartTime = ((CNewNPC)attacker).GetCounterWindowStartTime();
  1656.         spamCounter = 0;
  1657.         reflexAction = false;
  1658.        
  1659.         //if counterWindowStartTime was never set return false - PF
  1660.         if ( counterWindowStartTime == testEngineTime )
  1661.         {
  1662.             return false;
  1663.         }
  1664.        
  1665.         for(i = counterTimestamps.Size() - 1; i>=0; i-=1)
  1666.         {
  1667.             //log number of button presses since 0.4 seconds before the counter timewindow
  1668.             if(counterTimestamps[i] >= (counterWindowStartTime - EngineTimeFromFloat(0.4)) )
  1669.             {
  1670.                 spamCounter += 1;
  1671.             }
  1672.             //and at the same time remove all outdated data on the fly
  1673.             else
  1674.             {
  1675.                 counterTimestamps.Remove(counterTimestamps[i]);
  1676.                 continue;
  1677.             }
  1678.            
  1679.             //set info that we have a potential parry if this press was after the counter timewindow started
  1680.             if(!reflexAction && (counterTimestamps[i] >= counterWindowStartTime))
  1681.                 reflexAction = true;
  1682.         }
  1683.        
  1684.         /*
  1685.             If reflexAction is set then we have at least 1 button press within the counter timewindow.
  1686.            
  1687.             As for the spam counter:
  1688.             0 means no button was pressed - no counter
  1689.             1 means exactly one button press - a potential counter (if reflexAction is set as well)
  1690.             >1 means spamming
  1691.         */
  1692.         if(spamCounter == 1 && reflexAction)
  1693.             return true;
  1694.            
  1695.         return false;
  1696.     }
  1697.    
  1698.     protected function PerformCounterCheck(parryInfo: SParryInfo) : bool
  1699.     {
  1700.         var mult                        : float;
  1701.         var parryType                   : EParryType;
  1702.         var validCounter, useKnockdown  : bool;
  1703.         var slideDistance, duration     : float;
  1704.         var playerToTargetRot           : EulerAngles;
  1705.         var zDifference, mutation8TriggerHP : float;
  1706.         var effectType                  : EEffectType;
  1707.         var repelType                   : EPlayerRepelType = PRT_Random;
  1708.         var params                      : SCustomEffectParams;
  1709.         var thisPos, attackerPos        : Vector;
  1710.         var fistFightCheck, isMutation8 : bool;
  1711.         var fistFightCounter            : bool;
  1712.         var attackerInventory           : CInventoryComponent;
  1713.         var weaponId                    : SItemUniqueId;
  1714.         var weaponTags                  : array<name>;
  1715.         var playerToAttackerVector      : Vector;
  1716.         var tracePosStart               : Vector;
  1717.         var tracePosEnd                 : Vector;
  1718.         var hitPos                      : Vector;
  1719.         var hitNormal                   : Vector;
  1720.         var min, max                    : SAbilityAttributeValue;
  1721.         var npc                         : CNewNPC;
  1722.        
  1723.         if(ShouldProcessTutorial('TutorialDodge') || ShouldProcessTutorial('TutorialCounter'))
  1724.         {
  1725.             theGame.RemoveTimeScale( theGame.GetTimescaleSource(ETS_TutorialFight) );
  1726.             FactsRemove("tut_fight_slomo_ON");
  1727.         }
  1728.        
  1729.         //W3EE - Begin
  1730.         if( IsSuperHeavyAttack(parryInfo.attackActionName) )
  1731.             mult = 1.3f;
  1732.         else
  1733.         if( IsHeavyAttack(parryInfo.attackActionName) )
  1734.             mult = 1.15f;
  1735.         else
  1736.             mult = 1.f;
  1737.        
  1738.         if( !HasStaminaToUseAction(ESAT_Counterattack, , mult) )
  1739.             return false;
  1740.         //W3EE - End
  1741.        
  1742.         fistFightCheck = FistFightCheck( parryInfo.target, parryInfo.attacker, fistFightCounter );
  1743.        
  1744.         if( ParryCounterCheck() && parryInfo.targetToAttackerAngleAbs < theGame.params.PARRY_HALF_ANGLE && fistFightCheck )
  1745.         {
  1746.             //check if this is a valid counter
  1747.             validCounter = CheckCounterSpamming(parryInfo.attacker);
  1748.            
  1749.             if(validCounter)
  1750.             {
  1751.                 if ( IsInCombatActionFriendly() )
  1752.                     RaiseEvent('CombatActionFriendlyEnd');
  1753.                
  1754.                 SetBehaviorVariable( 'parryType', ChooseParryTypeIndex( parryInfo ) );
  1755.                 SetBehaviorVariable( 'counter', (float)validCounter);           //1/true when the parry is a counter/reflex_parry          
  1756.                
  1757.                 //PPPP counter success sound
  1758.                 //SoundEvent("global_machines_lift_wood1_mechanism_stop" );
  1759.                 SetBehaviorVariable( 'parryType', ChooseParryTypeIndex( parryInfo ) );
  1760.                 SetBehaviorVariable( 'counter', (float)validCounter);           //1/true when the parry is a counter/reflex_parry      
  1761.                 this.SetBehaviorVariable( 'combatActionType', (int)CAT_Parry );
  1762.                
  1763.                
  1764.                 if ( !fistFightCounter )
  1765.                 {
  1766.                     attackerInventory = parryInfo.attacker.GetInventory();
  1767.                     weaponId = attackerInventory.GetItemFromSlot('r_weapon');
  1768.                     attackerInventory.GetItemTags( weaponId , weaponTags );
  1769.                    
  1770.                     if( GetWitcherPlayer().IsMutationActive( EPMT_Mutation8 ) )
  1771.                     {
  1772.                         isMutation8 = true;
  1773.                         theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation8', 'hp_perc_trigger', min, max );
  1774.                         mutation8TriggerHP = min.valueMultiplicative;
  1775.                     }
  1776.                    
  1777.                     /*if( parryInfo.attacker.HasTag( 'olgierd_gpl' ) && parryInfo.attackActionName == 'attack_heavy' )
  1778.                     {
  1779.                         //DealCounterDamageToOlgierd();
  1780.                         GetTarget().AddAbility( 'HitCounterEnabled', false );
  1781.                         GetTarget().AddTimer( 'DisableHitCounterAfter', 3.0 );
  1782.                     }*/
  1783.                    
  1784.                     npc = (CNewNPC)parryInfo.attacker;
  1785.                    
  1786.                     //don't look at me like that. It is NOT a hack... follow the white rabbit...
  1787.                     /*if ( parryInfo.attacker.HasAbility('mon_gravehag') )
  1788.                     {
  1789.                         repelType = PRT_Slash;
  1790.                         parryInfo.attacker.AddEffectDefault(EET_CounterStrikeHit, this, 'ReflexParryPerformed');
  1791.                         //parryInfo.attacker.RemoveAbility('TongueAttack');
  1792.                     }
  1793.                     else if ( npc && !npc.IsHuman() && !npc.HasTag( 'dettlaff_vampire' ) )
  1794.                     {
  1795.                         repelType = PRT_SideStepSlash;
  1796.                     }
  1797.                     else if ( weaponTags.Contains('spear2h') )
  1798.                     {
  1799.                         repelType = PRT_SideStepSlash;
  1800.                         parryInfo.attacker.AddEffectDefault(EET_CounterStrikeHit, this, "ReflexParryPerformed");
  1801.                         parryInfo.attacker.SignalGameplayEvent( 'SpearDestruction');
  1802.                     }
  1803.                     else if( isMutation8 && npc && !npc.IsImmuneToMutation8Finisher() )
  1804.                     {
  1805.                         repelType = PRT_RepelToFinisher;
  1806.                         npc.AddEffectDefault( EET_CounterStrikeHit, this, "ReflexParryPerformed" );
  1807.                        
  1808.                         //finishers are performed on current target
  1809.                         SetTarget( npc, true );
  1810.                        
  1811.                         PerformFinisher( 0.f, 0 );
  1812.                     }
  1813.                     else
  1814.                     {
  1815.                         //-----pitch check------
  1816.                         thisPos = this.GetWorldPosition();
  1817.                         attackerPos = parryInfo.attacker.GetWorldPosition();
  1818.                         playerToTargetRot = VecToRotation( thisPos - attackerPos );
  1819.                         zDifference = thisPos.Z - attackerPos.Z;
  1820.                        
  1821.                         if ( playerToTargetRot.Pitch < -5.f && zDifference > 0.35 )
  1822.                         {
  1823.                             repelType = PRT_Kick;
  1824.                             //Pass attacker to the timer so that he ragdolls after a delay
  1825.                             ragdollTarget = parryInfo.attacker;
  1826.                             AddTimer( 'ApplyCounterRagdollTimer', 0.3 );
  1827.                         }
  1828.                         else
  1829.                         {
  1830.                             useKnockdown = false;
  1831.                             if ( CanUseSkill(S_Sword_s11) )
  1832.                             {
  1833.                                 if( GetSkillLevel(S_Sword_s11) > 1 && RandRangeF(3,0) < GetWitcherPlayer().GetStat(BCS_Focus) )//CalculateAttributeValue(GetSkillAttributeValue(S_Sword_s11, 'chance', false, true)) )
  1834.                                 {
  1835.                                     duration = CalculateAttributeValue(GetSkillAttributeValue(S_Sword_s11, 'duration', false, true));
  1836.                                     useKnockdown = true;
  1837.                                 }
  1838.                             }
  1839.                             else if ( parryInfo.attacker.IsHuman() )
  1840.                             {
  1841.                                 //Apply knockdown if npc is countered on ledge
  1842.                                 tracePosStart = parryInfo.attacker.GetWorldPosition();
  1843.                                 tracePosStart.Z += 1.f;
  1844.                                 playerToAttackerVector = VecNormalize( parryInfo.attacker.GetWorldPosition() -  parryInfo.target.GetWorldPosition() );
  1845.                                 tracePosEnd = ( playerToAttackerVector * 0.75f ) + ( playerToAttackerVector * parryInfo.attacker.GetRadius() ) + parryInfo.attacker.GetWorldPosition();
  1846.                                 tracePosEnd.Z += 1.f;
  1847.  
  1848.                                 if ( !theGame.GetWorld().StaticTrace( tracePosStart, tracePosEnd, hitPos, hitNormal, counterCollisionGroupNames ) )
  1849.                                 {
  1850.                                     tracePosStart = tracePosEnd;
  1851.                                     tracePosEnd -= 3.f;
  1852.                                    
  1853.                                     if ( !theGame.GetWorld().StaticTrace( tracePosStart, tracePosEnd, hitPos, hitNormal, counterCollisionGroupNames ) )
  1854.                                         useKnockdown = true;
  1855.                                 }
  1856.                             }
  1857.                            
  1858.                             if(useKnockdown && (!parryInfo.attacker.IsImmuneToBuff(EET_HeavyKnockdown) || !parryInfo.attacker.IsImmuneToBuff(EET_Knockdown)))
  1859.                             {
  1860.                                 if(!parryInfo.attacker.IsImmuneToBuff(EET_HeavyKnockdown))
  1861.                                 {
  1862.                                     params.effectType = EET_HeavyKnockdown;
  1863.                                 }
  1864.                                 else
  1865.                                 {
  1866.                                     params.effectType = EET_Knockdown;
  1867.                                 }
  1868.                                
  1869.                                 repelType = PRT_Kick;
  1870.                                 params.creator = this;
  1871.                                 params.sourceName = "ReflexParryPerformed";
  1872.                                 params.duration = duration;
  1873.                                
  1874.                                 parryInfo.attacker.AddEffectCustom(params);
  1875.                             }
  1876.                             else
  1877.                             {
  1878.                                 parryInfo.attacker.AddEffectDefault(EET_CounterStrikeHit, this, "ReflexParryPerformed");
  1879.                             }
  1880.                         }
  1881.                     }
  1882.                    
  1883.                     parryInfo.attacker.GetInventory().PlayItemEffect(parryInfo.attackerWeaponId, 'counterattack');
  1884.                    
  1885.                     //by default repelType is PRT_Random
  1886.                     if ( repelType == PRT_Random )
  1887.                         if ( RandRange(100) > 50 )
  1888.                             repelType = PRT_Bash;
  1889.                         else
  1890.                             repelType = PRT_Kick;*/
  1891.                    
  1892.                     //W3EE - Begin
  1893.                     Combat().PerformCounter( this, counterCollisionGroupNames, parryInfo, weaponTags, hitNormal, repelType, ragdollTarget, isMutation8, npc );
  1894.                     //W3EE - End
  1895.                    
  1896.                     this.SetBehaviorVariable( 'repelType', (int)repelType );
  1897.                     parryInfo.attacker.SetBehaviorVariable( 'repelType', (int)repelType );
  1898.                 }
  1899.                 else
  1900.                 {
  1901.                     parryInfo.attacker.AddEffectDefault(EET_CounterStrikeHit, this, "ReflexParryPerformed");
  1902.                 }
  1903.                
  1904.                 //SetCustomOrientationTargetForCombatActions( OT_None );
  1905.                 SetParryTarget ( parryInfo.attacker );
  1906.                 SetSlideTarget( parryInfo.attacker );
  1907.                 if ( !IsActorLockedToTarget() )
  1908.                     SetMoveTarget( parryInfo.attacker );
  1909.                
  1910.                 if ( RaiseForceEvent( 'PerformCounter' ) )
  1911.                     OnCombatActionStart();
  1912.                
  1913.                 SetCustomRotation( 'Counter', VecHeading( parryInfo.attacker.GetWorldPosition() - this.GetWorldPosition() ), 0.0f, 0.2f, false );
  1914.                 AddTimer( 'UpdateCounterRotation', 0.4f, true );
  1915.                 AddTimer( 'SetCounterRotation', 0.2f );
  1916.                
  1917.                 IncreaseUninterruptedHitsCount();   //counters also count as uninterrupted hits
  1918.                
  1919.                 //drain stamina
  1920.                 if(IsHeavyAttack(parryInfo.attackActionName))
  1921.                     mult = theGame.params.HEAVY_STRIKE_COST_MULTIPLIER;
  1922.                    
  1923.                 DrainStamina(ESAT_Counterattack, 0, 0, '', 0, mult);
  1924.                
  1925.                 theGame.GetGamerProfile().IncStat(ES_CounterattackChain);
  1926.                
  1927.             }
  1928.             else
  1929.             {
  1930.                 ResetUninterruptedHitsCount();
  1931.             }
  1932.             return validCounter;
  1933.         }          
  1934.        
  1935.         return false;
  1936.     }
  1937.    
  1938.     timer function UpdateCounterRotation( dt : float, id : int )
  1939.     {
  1940.         UpdateCustomRotationHeading( 'Counter', VecHeading( parryTarget.GetWorldPosition() - this.GetWorldPosition() ) );
  1941.     }
  1942.    
  1943.     timer function SetCounterRotation( dt : float, id : int )
  1944.     {
  1945.         SetCustomRotation( 'Counter', VecHeading( parryTarget.GetWorldPosition() - this.GetWorldPosition() ), 360.f, 0.2f, false );
  1946.     }  
  1947.    
  1948.     private var parryTarget : CActor;
  1949.     private function SetParryTarget( t : CActor )
  1950.     {
  1951.         parryTarget = t;
  1952.     }
  1953.    
  1954.     // W3EE - Begin
  1955.     public function SetRagdollTarget( actor : CActor )
  1956.     {
  1957.         ragdollTarget = actor;
  1958.     }
  1959.    
  1960.     private var ragdollTarget : CActor;
  1961.     timer function ApplyCounterRagdollTimer( time : float , id : int)
  1962.     {
  1963.         var actor : CActor;
  1964.                
  1965.         actor = (CActor)ragdollTarget;
  1966.        
  1967.         if(actor)
  1968.         {
  1969.             actor.AddEffectDefault(EET_HeavyKnockdown, this, 'ReflexParryPerformed');
  1970.         }
  1971.     }
  1972.    
  1973.     ///////////////////////////////////////////////////////////////////////////
  1974.     // Player Mode
  1975.    
  1976.     public function EnableMode( mode : EPlayerMode, enable : bool )
  1977.     {
  1978.         playerMode.EnableMode( mode, enable ); 
  1979.     }
  1980.    
  1981.     public function GetPlayerMode() : W3PlayerMode
  1982.     {
  1983.         return playerMode;
  1984.     }
  1985.    
  1986.     private function GetClosestIncomingAttacker() : CActor
  1987.     {
  1988.         var i, size                     : int;
  1989.         var attackerToPlayerDistances   : array< float >;
  1990.         var closestAttackerIndex        : int;
  1991.         var incomingAttackers           : array<CActor>;
  1992.            
  1993.         //incomingAttackers = this.combatManager.SendTicketOwners( CTT_Attack );
  1994.         if(playerMode && playerMode.combatDataComponent)
  1995.         {
  1996.             if ( incomingAttackers.Size() <= 0 )
  1997.                 this.playerMode.combatDataComponent.GetTicketSourceOwners( incomingAttackers, 'TICKET_Charge' );
  1998.            
  1999.             if ( incomingAttackers.Size() <= 0 )
  2000.                 this.playerMode.combatDataComponent.GetTicketSourceOwners( incomingAttackers, 'TICKET_Melee' );
  2001.                
  2002.             if ( incomingAttackers.Size() <= 0 )
  2003.                 this.playerMode.combatDataComponent.GetTicketSourceOwners( incomingAttackers, 'TICKET_Range' );
  2004.         }
  2005.            
  2006.         size = incomingAttackers.Size();
  2007.         attackerToPlayerDistances.Resize( size );
  2008.  
  2009.         if ( size > 0 )
  2010.         {
  2011.             for ( i = incomingAttackers.Size()-1; i >= 0; i -= 1)
  2012.             {
  2013.                 if ( !IsEnemyVisible( incomingAttackers[i] ) )
  2014.                 {
  2015.                     incomingAttackers.EraseFast( i );
  2016.                 }
  2017.             }          
  2018.         }
  2019.    
  2020.         if ( size > 0 )
  2021.         {
  2022.             for ( i = 0; i < size; i += 1 )
  2023.             {
  2024.                 attackerToPlayerDistances[i] = VecDistance( incomingAttackers[i].GetWorldPosition(), this.GetWorldPosition() );
  2025.             }
  2026.             closestAttackerIndex = ArrayFindMinF( attackerToPlayerDistances );
  2027.             return incomingAttackers[ closestAttackerIndex ];
  2028.         }
  2029.         else
  2030.         {
  2031.             return NULL;
  2032.         }
  2033.     }
  2034.    
  2035.     // Combat Timer
  2036.     timer function CombatCheck( time : float , id : int)
  2037.     {
  2038.         var i : int;
  2039.         var strLevel, temp : string;
  2040.         var enemies : array<CActor>;
  2041.                
  2042.         UpdateFinishableEnemyList();
  2043.         FindMoveTarget();
  2044.         playerMode.UpdateCombatMode();
  2045.        
  2046.         if( GetPlayerCombatStance() == PCS_Guarded )
  2047.         {
  2048.             if( GetTarget().GetHealthPercents() > 0.25f )
  2049.             {
  2050.                 PlayBattleCry( 'BattleCryTaunt', 0.2f );
  2051.             }
  2052.             else
  2053.             {
  2054.                 if( GetTarget().IsHuman() )
  2055.                     PlayBattleCry( 'BattleCryHumansEnd', 0.3f );
  2056.                 else
  2057.                     PlayBattleCry( 'BattleCryMonstersEnd', 0.3f );
  2058.             }
  2059.         }
  2060.        
  2061.         if(IsThreatened() && ShouldProcessTutorial('TutorialMonsterThreatLevels') && FactsQuerySum("q001_nightmare_ended") > 0)
  2062.         {
  2063.             GetEnemiesInRange(enemies);
  2064.             for(i=0; i<enemies.Size(); i+=1)
  2065.             {
  2066.                 strLevel = ((CNewNPC)enemies[i]).GetExperienceDifferenceLevelName(temp);
  2067.                 if(strLevel == "deadlyLevel" || strLevel == "highLevel")
  2068.                 {
  2069.                     FactsAdd("tut_high_threat_monster");
  2070.                     break;
  2071.                 }
  2072.             }
  2073.         }      
  2074.     }
  2075.    
  2076.     public function ReceivedDamageInCombat() : bool
  2077.     {
  2078.         return receivedDamageInCombat;
  2079.     }
  2080.    
  2081.     //called when combat starts
  2082.     timer function PinEssentialGroupTimer( deltaTime : float, id : int )
  2083.     {
  2084.         ToggleEssentialModules( !IsHUDGroupEnabledForReason( GetFHUDConfig().essentialModules, "PinEssentialGroup" ), "PinEssentialGroup" );
  2085.     }
  2086.    
  2087.     timer function EssentialsOnTimer( deltaTime : float, id : int )
  2088.     {
  2089.         ToggleEssentialModules( true, "EssentialModulesHotkey" );
  2090.     }
  2091.    
  2092.     timer function MapOnTimer( deltaTime : float, id : int )
  2093.     {
  2094.         ToggleMinimapModules( true, "MinimapModulesHotkey" );
  2095.     }
  2096.    
  2097.     timer function QuestsOnTimer( deltaTime : float, id : int )
  2098.     {
  2099.         ToggleQuestsModules( true, "QuestsModulesHotkey" );
  2100.     }
  2101.    
  2102.     timer function CharOnTimer( deltaTime : float, id : int )
  2103.     {
  2104.         ToggleCharacterModules( true, "CharModulesHotkey" );
  2105.     }
  2106.    
  2107.     timer function DamageOffTimer( deltaTime : float, id : int ) //still needed as workaround
  2108.     {
  2109.         ToggleHUDModule( "WolfHeadModule", false, "OnDamage" );
  2110.     }
  2111.    
  2112.     timer function MeditationModulesOnTimer( deltaTime : float, id : int ) //needed for compatibility
  2113.     {
  2114.         if ( GetFHUDConfig().enableMeditationModules )
  2115.         {
  2116.             ToggleMeditModules( true, "RealTimeMeditation" );
  2117.         }
  2118.     }
  2119.  
  2120.     timer function MeditationModulesOffTimer( deltaTime : float, id : int ) //needed for compatibility
  2121.     {
  2122.         if ( GetFHUDConfig().enableMeditationModules )
  2123.         {
  2124.             ToggleMeditModules( false, "RealTimeMeditation" );
  2125.         }
  2126.     }
  2127.     //---=== modFriendlyHUD ===---
  2128.     event OnCombatStart()
  2129.     {
  2130.         var weaponType : EPlayerWeapon;
  2131.        
  2132.         //---=== modFriendlyHUD ===---
  2133.         if ( GetFHUDConfig().enableCombatModules )
  2134.         {
  2135.             ToggleCombatModules( true, "InCombat" );
  2136.         }
  2137.         //---=== modFriendlyHUD ===---
  2138.        
  2139.         theGame.CreateNoSaveLock( 'combat', noSaveLock );
  2140.        
  2141.         theGame.GameplayFactsAdd( "in_combat" );
  2142.        
  2143.         //cerberus achievement
  2144.         FactsRemove("statistics_cerberus_sign");
  2145.         FactsRemove("statistics_cerberus_petard");
  2146.         FactsRemove("statistics_cerberus_bolt");
  2147.         FactsRemove("statistics_cerberus_fists");
  2148.         FactsRemove("statistics_cerberus_melee");
  2149.         FactsRemove("statistics_cerberus_environment");
  2150.            
  2151.         BlockAction(EIAB_OpenMeditation, 'InCombat');
  2152.         BlockAction(EIAB_HighlightObjective, 'InCombat');
  2153.        
  2154.         if ( !this.IsUsingBoat() && GetTarget().GetAttitude(this) == AIA_Hostile )
  2155.         {
  2156.             weaponType = GetMostConvenientMeleeWeapon( GetTarget() );
  2157.            
  2158.             if ( weaponType == PW_Steel || weaponType == PW_Silver )
  2159.                 this.OnEquipMeleeWeapon( weaponType, false );
  2160.         }
  2161.     }
  2162.        
  2163.     //called when combat finishes
  2164.     event OnCombatFinished()
  2165.     {
  2166.         var cnt : int;
  2167.        
  2168.         //---=== modFriendlyHUD ===---
  2169.         if ( GetFHUDConfig().enableCombatModules )
  2170.         {
  2171.             ToggleCombatModules( false, "InCombat" );
  2172.         }
  2173.         //---=== modFriendlyHUD ===---
  2174.        
  2175.         reevaluateCurrentWeapon = false;
  2176.        
  2177.         thePlayer.HardLockToTarget( false );
  2178.    
  2179.         receivedDamageInCombat = false;
  2180.        
  2181.         theGame.GameplayFactsRemove( "in_combat" );
  2182.            
  2183.         //cerberus achievement
  2184.         cnt = 0;
  2185.         if(FactsQuerySum("statistics_cerberus_sign") > 0)
  2186.             cnt += 1;
  2187.         if(FactsQuerySum("statistics_cerberus_petard") > 0)
  2188.             cnt += 1;
  2189.         if(FactsQuerySum("statistics_cerberus_bolt") > 0)
  2190.             cnt += 1;
  2191.         if(FactsQuerySum("statistics_cerberus_fists") > 0)
  2192.             cnt += 1;
  2193.         if(FactsQuerySum("statistics_cerberus_melee") > 0)
  2194.             cnt += 1;
  2195.         if(FactsQuerySum("statistics_cerberus_environment") > 0)
  2196.             cnt += 1;
  2197.        
  2198.         //failsafe
  2199.         FactsRemove("statistics_cerberus_sign");
  2200.         FactsRemove("statistics_cerberus_petard");
  2201.         FactsRemove("statistics_cerberus_bolt");
  2202.         FactsRemove("statistics_cerberus_fists");
  2203.         FactsRemove("statistics_cerberus_melee");
  2204.         FactsRemove("statistics_cerberus_environment");
  2205.        
  2206.         if(cnt >= 3)
  2207.             theGame.GetGamerProfile().AddAchievement(EA_Cerberus);
  2208.         //end of cerberus
  2209.        
  2210.         if(theGame.GetTutorialSystem() && FactsQuerySum("TutorialShowSilver") > 0)
  2211.         {
  2212.             FactsAdd("tut_show_silver_sword", 1);
  2213.             FactsRemove("TutorialShowSilver");
  2214.         }
  2215.         this.SetBehaviorVariable('isInCombatForOverlay',0.f);
  2216.         GoToExplorationIfNeeded();
  2217.         theGame.ReleaseNoSaveLock( noSaveLock );
  2218.         LogChannel( 'OnCombatFinished', "OnCombatFinished: ReleaseNoSaveLock" );
  2219.        
  2220.         SetFailedFundamentalsFirstAchievementCondition(false);
  2221.        
  2222.         UnblockAction(EIAB_OpenMeditation, 'InCombat');
  2223.         UnblockAction(EIAB_HighlightObjective, 'InCombat');
  2224.     }
  2225.    
  2226.     event OnReactToBeingHit( damageAction : W3DamageAction )
  2227.     {
  2228.         var weaponType : EPlayerWeapon;
  2229.        
  2230.         super.OnReactToBeingHit(damageAction);
  2231.         IncHitCounter();
  2232.        
  2233.         if ( IsInCombat() && damageAction.attacker && damageAction.attacker == GetTarget() && !( this.IsUsingVehicle() && this.IsOnBoat() ) )
  2234.         {
  2235.             weaponType = GetMostConvenientMeleeWeapon( GetTarget() );
  2236.             if ( weaponType != PW_Fists && weaponType != PW_None && weaponType != this.GetCurrentMeleeWeaponType() )
  2237.                 OnEquipMeleeWeapon( weaponType, false );
  2238.         }
  2239.     }
  2240.    
  2241.     //called when player receives damage in combat(except for toxicity)
  2242.     public function ReceivedCombatDamage()
  2243.     {
  2244.         receivedDamageInCombat = true;
  2245.     }
  2246.    
  2247.     ///////////////////////////////////////////////////////////////////////////
  2248.     // @Uninterrupted hits
  2249.     ///////////////////////////////////////////////////////////////////////////
  2250.    
  2251.    
  2252.     timer function UninterruptedHitsResetOnIdle(dt : float, id : int)
  2253.     {
  2254.         ResetUninterruptedHitsCount();
  2255.     }
  2256.    
  2257.     public function ResetUninterruptedHitsCount()
  2258.     {
  2259.         uninterruptedHitsCount = 0;
  2260.         LogUnitAtt("Uninterrupted attacks reset!!!!");
  2261.     }
  2262.    
  2263.     public function IncreaseUninterruptedHitsCount()
  2264.     {
  2265.         uninterruptedHitsCount += 1;
  2266.         LogUnitAtt("Uninterrupted attacks count increased to " + uninterruptedHitsCount);
  2267.        
  2268.         if(uninterruptedHitsCount == 4)
  2269.             AddTimer('StartUninterruptedBlurr', 1, false);
  2270.        
  2271.         //idle turn off timer
  2272.         AddTimer('UninterruptedHitsResetOnIdle', 4.f, false);
  2273.     }
  2274.    
  2275.     timer function StartUninterruptedBlurr(dt : float, id : int)
  2276.     {
  2277.         var changed : bool;
  2278.         var movingAgent : CMovingPhysicalAgentComponent;
  2279.         var target : CActor;
  2280.        
  2281.         //check if the timer is to be turned off
  2282.         if(uninterruptedHitsCount < 4)
  2283.         {
  2284.             LogUnitAtt("Stopping camera effect");
  2285.             thePlayer.StopEffect(uninterruptedHitsCurrentCameraEffect);
  2286.             uninterruptedHitsCurrentCameraEffect = '';
  2287.             uninterruptedHitsCameraStarted = false;        
  2288.             RemoveTimer('StartUninterruptedBlurr');
  2289.         }
  2290.         else    //still valid
  2291.         {
  2292.             target = GetTarget();
  2293.            
  2294.             if( target )
  2295.             {
  2296.                 movingAgent = ( (CMovingPhysicalAgentComponent) (target.GetMovingAgentComponent()) );
  2297.             }
  2298.                
  2299.             if(!uninterruptedHitsCameraStarted)
  2300.             {
  2301.                 LogUnitAtt("Starting camera effect");
  2302.                 AddTimer('StartUninterruptedBlurr', 0.001, true);   //need to update per tick
  2303.                 if(movingAgent && movingAgent.GetCapsuleHeight() > 2)
  2304.                     uninterruptedHitsCurrentCameraEffect = theGame.params.UNINTERRUPTED_HITS_CAMERA_EFFECT_BIG_ENEMY;
  2305.                 else
  2306.                     uninterruptedHitsCurrentCameraEffect = theGame.params.UNINTERRUPTED_HITS_CAMERA_EFFECT_REGULAR_ENEMY;
  2307.                 thePlayer.PlayEffect(uninterruptedHitsCurrentCameraEffect);
  2308.                 uninterruptedHitsCameraStarted = true;
  2309.             }
  2310.             else
  2311.             {
  2312.                 changed = false;
  2313.                 if(movingAgent && movingAgent.GetCapsuleHeight() > 2 && uninterruptedHitsCurrentCameraEffect != theGame.params.UNINTERRUPTED_HITS_CAMERA_EFFECT_BIG_ENEMY)
  2314.                     changed = true;
  2315.                 else if(!movingAgent || ( movingAgent.GetCapsuleHeight() <= 2 && uninterruptedHitsCurrentCameraEffect != theGame.params.UNINTERRUPTED_HITS_CAMERA_EFFECT_REGULAR_ENEMY) )
  2316.                     changed = true;
  2317.                
  2318.                 //if the target's height has changed then swap the camera effect
  2319.                 if(changed)
  2320.                 {
  2321.                     //stop current effect
  2322.                     thePlayer.StopEffect(uninterruptedHitsCurrentCameraEffect);
  2323.                    
  2324.                     //change mode
  2325.                     if(uninterruptedHitsCurrentCameraEffect == theGame.params.UNINTERRUPTED_HITS_CAMERA_EFFECT_BIG_ENEMY)
  2326.                         uninterruptedHitsCurrentCameraEffect = theGame.params.UNINTERRUPTED_HITS_CAMERA_EFFECT_REGULAR_ENEMY;
  2327.                     else
  2328.                         uninterruptedHitsCurrentCameraEffect = theGame.params.UNINTERRUPTED_HITS_CAMERA_EFFECT_BIG_ENEMY;
  2329.                        
  2330.                     //turn new camera effect on
  2331.                     thePlayer.PlayEffect(uninterruptedHitsCurrentCameraEffect);
  2332.                 }
  2333.             }
  2334.         }
  2335.     }
  2336.    
  2337.     ///////////////////////////////////////////////////////////////////////////
  2338.     // Exploration Actions
  2339.     ///////////////////////////////////////////////////////////////////////////
  2340.    
  2341.     private var playerActionEventListeners          : array<CGameplayEntity>;
  2342.     private var playerActionEventBlockingListeners  : array<CGameplayEntity>;
  2343.    
  2344.     private function PlayerActionBlockGameplayActions( sourceName : name, lock : bool, isFromPlace : bool )
  2345.     {
  2346.         if ( lock )
  2347.         {
  2348.             thePlayer.BlockAction( EIAB_Signs, sourceName, false, false, isFromPlace );
  2349.             thePlayer.BlockAction( EIAB_DrawWeapon, sourceName, false, false, isFromPlace );
  2350.             thePlayer.BlockAction( EIAB_CallHorse, sourceName, false, false, isFromPlace );
  2351.             thePlayer.BlockAction( EIAB_FastTravel, sourceName, false, false, isFromPlace );
  2352.             thePlayer.BlockAction( EIAB_Fists, sourceName, false, false, isFromPlace );
  2353.             thePlayer.BlockAction( EIAB_InteractionAction, sourceName, false, false, isFromPlace );
  2354.             thePlayer.DisableCombatState();
  2355.         }
  2356.         else
  2357.         {
  2358.             thePlayer.UnblockAction( EIAB_Signs, sourceName );
  2359.             thePlayer.UnblockAction( EIAB_DrawWeapon, sourceName );
  2360.             thePlayer.UnblockAction( EIAB_CallHorse, sourceName );
  2361.             thePlayer.UnblockAction( EIAB_FastTravel, sourceName );
  2362.             thePlayer.UnblockAction( EIAB_Fists, sourceName );
  2363.             thePlayer.UnblockAction( EIAB_InteractionAction, sourceName );
  2364.         }
  2365.     }
  2366.    
  2367.     public function GetPlayerActionEventListeners() : array<CGameplayEntity>
  2368.     {
  2369.         return playerActionEventListeners;
  2370.     }
  2371.    
  2372.     //Registers for event + blocks GameplayActions
  2373.     public function RegisterForPlayerAction( listener : CGameplayEntity, isLockedByPlace : bool )
  2374.     {
  2375.         if ( !playerActionEventListeners.Contains( listener ) )
  2376.         {
  2377.             playerActionEventListeners.PushBack( listener );
  2378.         }
  2379.         if ( listener.ShouldBlockGameplayActionsOnInteraction() )
  2380.         {
  2381.             if ( !playerActionEventBlockingListeners.Contains( listener ) )
  2382.             {
  2383.                 playerActionEventBlockingListeners.PushBack( listener );
  2384.             }
  2385.             if ( playerActionEventBlockingListeners.Size() == 1 )
  2386.             {
  2387.                 PlayerActionBlockGameplayActions( 'PlayerAction', true, isLockedByPlace );
  2388.             }
  2389.         }
  2390.     }
  2391.    
  2392.     //Unregisters for event + unblocks GameplayActions
  2393.     public function UnregisterForPlayerAction( listener : CGameplayEntity, isLockedByPlace : bool )
  2394.     {
  2395.         playerActionEventListeners.Remove( listener );
  2396.         playerActionEventBlockingListeners.Remove( listener );
  2397.         if ( playerActionEventBlockingListeners.Size() == 0 )
  2398.         {
  2399.             PlayerActionBlockGameplayActions( 'PlayerAction', false, isLockedByPlace );
  2400.         }  
  2401.     }
  2402.    
  2403.     event OnPlayerActionStart()
  2404.     {
  2405.         //MS: Only used for ProudWalk
  2406.         thePlayer.SetBehaviorVariable( 'inJumpState', 1.f );
  2407.     }
  2408.    
  2409.     event OnPlayerActionEnd()
  2410.     {
  2411.         var i : int;       
  2412.         for ( i = playerActionEventListeners.Size() - 1; i >= 0; i-=1 )
  2413.         {
  2414.             playerActionEventListeners[i].OnPlayerActionEnd();
  2415.         }
  2416.         currentCustomAction = PEA_None;
  2417.        
  2418.         //MS: Only used for ProudWalk
  2419.         thePlayer.SetBehaviorVariable( 'inJumpState', 0.f );
  2420.     }
  2421.    
  2422.     event OnPlayerActionStartFinished()
  2423.     {
  2424.         var i : int;       
  2425.         for ( i = playerActionEventListeners.Size() - 1; i >= 0; i-=1 )
  2426.         {
  2427.             playerActionEventListeners[i].OnPlayerActionStartFinished();
  2428.         }
  2429.     }
  2430.    
  2431.     function PlayerStartAction( playerAction : EPlayerExplorationAction, optional animName : name ) : bool
  2432.     {
  2433.         if ( playerAction == PEA_SlotAnimation && !IsNameValid(animName) )
  2434.         {
  2435.             return false;
  2436.         }
  2437.            
  2438.         SetBehaviorVariable( 'playerStopAction', 0.0);
  2439.         SetBehaviorVariable( 'playerExplorationAction', (float)(int)playerAction);
  2440.        
  2441.         /*if ( playerAction == PEA_SlotAnimation )
  2442.         {
  2443.             if ( !this.ActionPlaySlotAnimationAsync('PLAYER_ACTION_SLOT',animName) )
  2444.                 return false;
  2445.         }*/
  2446.        
  2447.         if ( RaiseForceEvent('playerActionStart') )
  2448.         {
  2449.             currentCustomAction = playerAction;
  2450.             if ( playerAction == PEA_SlotAnimation )
  2451.             {
  2452.                 playerActionSlotAnimName = animName;
  2453.                 AddTimer('PlayActionAnimWorkaround',0,false);
  2454.             }
  2455.             return true;
  2456.         }
  2457.         return false;
  2458.     }
  2459.    
  2460.     private var playerActionSlotAnimName : name;
  2461.    
  2462.     timer function PlayActionAnimWorkaround( dt : float , id : int)
  2463.     {
  2464.         this.ActionPlaySlotAnimationAsync('PLAYER_ACTION_SLOT',playerActionSlotAnimName, 0.2, 0.2, true);
  2465.     }
  2466.    
  2467.     // W3EE - Begin
  2468.     function PlayerStartAnim( playerAction : EPlayerExplorationAction, animName : name, blendInValue, blendOutValue : float ) : bool
  2469.     {
  2470.         if( playerAction == PEA_SlotAnimation && !IsNameValid(animName) )
  2471.         {
  2472.             return false;
  2473.         }
  2474.            
  2475.         SetBehaviorVariable( 'playerStopAction', 0.0);
  2476.         SetBehaviorVariable( 'playerExplorationAction', (float)(int)playerAction);
  2477.        
  2478.        
  2479.        
  2480.         if( RaiseForceEvent('playerActionStart') )
  2481.         {
  2482.             currentCustomAction = playerAction;
  2483.             if( playerAction == PEA_SlotAnimation )
  2484.             {
  2485.                 blendIn = blendInValue;
  2486.                 blendOut = blendOutValue;
  2487.                 playerActionSlotAnimName = animName;
  2488.                 AddTimer('PlayActionAnimWorkaroundCustom', 0, false);
  2489.             }
  2490.             return true;
  2491.         }
  2492.         return false;
  2493.     }
  2494.    
  2495.     private var blendIn, blendOut : float;
  2496.     timer function PlayActionAnimWorkaroundCustom( dt : float , id : int)
  2497.     {
  2498.         this.ActionPlaySlotAnimationAsync('PLAYER_ACTION_SLOT',playerActionSlotAnimName, blendIn, blendOut, true);
  2499.     }
  2500.     // W3EE - End
  2501.    
  2502.     function PlayerStopAction( playerAction : EPlayerExplorationAction )
  2503.     {
  2504.         SetBehaviorVariable( 'playerExplorationAction', (float)(int)playerAction);
  2505.         SetBehaviorVariable( 'playerStopAction', 1.0);
  2506.         currentCustomAction = PEA_None;
  2507.     }
  2508.    
  2509.     function GetPlayerAction() : EPlayerExplorationAction
  2510.     {
  2511.         return currentCustomAction;
  2512.     }
  2513.    
  2514.     function MedallionPing()
  2515.     {
  2516.         var currTime        : float = theGame.GetEngineTimeAsSeconds();
  2517.        
  2518.         if ( lastMedallionEffect < currTime )
  2519.         {
  2520.             lastMedallionEffect = theGame.GetEngineTimeAsSeconds() + medallion.effectDuration;
  2521.             medallion.TriggerMedallionFX();
  2522.         }
  2523.     }
  2524.    
  2525.     ///////////////////////////////////////////////////////////////////////////
  2526.     // @INTERACTIONS
  2527.     ///////////////////////////////////////////////////////////////////////////
  2528.    
  2529.     public function CanPerformPlayerAction(optional alsoOutsideExplorationState : bool) : bool
  2530.     {
  2531.         //if in exploration or in any state and flag set
  2532.         if(!alsoOutsideExplorationState && GetCurrentStateName() != 'Exploration')
  2533.             return false;
  2534.        
  2535.         if( isInAir || (substateManager && !substateManager.CanInteract()) || IsInCombatAction() || GetCriticalBuffsCount() > 0)
  2536.             return false;
  2537.            
  2538.         return true;
  2539.     }
  2540.    
  2541.     //called when we receive an item
  2542.     event OnItemGiven(data : SItemChangedData)
  2543.     {
  2544.         var keyName : name;
  2545.         var i : int;
  2546.         var hud : CR4ScriptedHud;
  2547.         var message : string;
  2548.         var inve : CInventoryComponent;
  2549.  
  2550.         if(data.informGui)
  2551.         {          
  2552.             hud = (CR4ScriptedHud)theGame.GetHud();
  2553.             if(hud)
  2554.             {
  2555.                 message = GetLocStringByKeyExt("panel_common_item_received") + ": " + GetLocStringByKeyExt(inv.GetItemLocalizedNameByUniqueID(data.ids[0]));
  2556.                 if(data.quantity > 1)
  2557.                     message += " x" + data.quantity;
  2558.                 hud.HudConsoleMsg(message);
  2559.             }
  2560.         }
  2561.        
  2562.         inve = GetInventory();  //OnItemGiven can be called before we cache inventory component
  2563.        
  2564.         //key - check if we're next to a lock that uses this key and update interaction if needed
  2565.         if(inve.ItemHasTag(data.ids[0], 'key'))
  2566.         {
  2567.             keyName = inve.GetItemName(data.ids[0]);
  2568.             for(i=nearbyLockedContainersNoKey.Size()-1; i>=0; i-=1)
  2569.             {
  2570.                 if(nearbyLockedContainersNoKey[i].GetKeyName() == keyName && nearbyLockedContainersNoKey[i].IsEnabled())
  2571.                 {
  2572.                     nearbyLockedContainersNoKey[i].UpdateComponents("Unlock");
  2573.                     nearbyLockedContainersNoKey.Remove(nearbyLockedContainersNoKey[i]);
  2574.                 }
  2575.             }
  2576.         }
  2577.  
  2578.         //alchemy level 3 items
  2579.         if(inve.IsItemAlchemyItem(data.ids[0]))
  2580.         {
  2581.             UpgradeAlchemyItem(data.ids[0], CanUseSkill(S_Perk_08));           
  2582.         }
  2583.        
  2584.         if(inve.ItemHasTag(data.ids[0], theGame.params.TAG_OFIR_SET))
  2585.             CheckOfirSetAchievement();
  2586.     }
  2587.    
  2588.     private final function CheckOfirSetAchievement()
  2589.     {
  2590.         var hasArmor, hasBoots, hasGloves, hasPants, hasSword, hasSaddle, hasBag, hasBlinders : bool;
  2591.        
  2592.         //check player items
  2593.         CheckOfirItems(GetInventory(), hasArmor, hasBoots, hasGloves, hasPants, hasSword, hasSaddle, hasBag, hasBlinders);
  2594.  
  2595.         //check stash items
  2596.         CheckOfirItems(GetWitcherPlayer().GetHorseManager().GetInventoryComponent(), hasArmor, hasBoots, hasGloves, hasPants, hasSword, hasSaddle, hasBag, hasBlinders);
  2597.        
  2598.         if(hasArmor && hasBoots && hasGloves && hasPants && hasSword && hasSaddle && hasBag && hasBlinders)
  2599.             theGame.GetGamerProfile().AddAchievement(EA_LatestFashion);
  2600.     }
  2601.    
  2602.     private final function CheckOfirItems(inv : CInventoryComponent, out hasArmor : bool, out hasBoots : bool, out hasGloves : bool, out hasPants : bool, out hasSword : bool, out hasSaddle : bool, out hasBag : bool, out hasBlinders : bool)
  2603.     {
  2604.         var ofirs : array<SItemUniqueId>;
  2605.         var i : int;
  2606.        
  2607.         ofirs = inv.GetItemsByTag(theGame.params.TAG_OFIR_SET);
  2608.         for(i=0; i<ofirs.Size(); i+=1)
  2609.         {
  2610.             if(inv.IsItemChestArmor(ofirs[i]))
  2611.             {
  2612.                 hasArmor = true;
  2613.                 continue;
  2614.             }
  2615.             else if(inv.IsItemBoots(ofirs[i]))
  2616.             {
  2617.                 hasBoots = true;
  2618.                 continue;
  2619.             }
  2620.             else if(inv.IsItemGloves(ofirs[i]))
  2621.             {
  2622.                 hasGloves = true;
  2623.                 continue;
  2624.             }
  2625.             else if(inv.IsItemPants(ofirs[i]))
  2626.             {
  2627.                 hasPants = true;
  2628.                 continue;
  2629.             }
  2630.             else if(inv.IsItemSteelSwordUsableByPlayer(ofirs[i]))
  2631.             {
  2632.                 hasSword = true;
  2633.                 continue;
  2634.             }
  2635.             else if(inv.IsItemSilverSwordUsableByPlayer(ofirs[i]))
  2636.             {
  2637.                 hasSword = true;
  2638.                 continue;
  2639.             }
  2640.             else if(inv.IsItemSaddle(ofirs[i]))
  2641.             {
  2642.                 hasSaddle = true;
  2643.                 continue;
  2644.             }
  2645.             else if(inv.IsItemHorseBag(ofirs[i]))
  2646.             {
  2647.                 hasBag = true;
  2648.                 continue;
  2649.             }
  2650.             else if(inv.IsItemBlinders(ofirs[i]))
  2651.             {
  2652.                 hasBlinders = true;
  2653.                 continue;
  2654.             }
  2655.         }
  2656.     }
  2657.    
  2658.     //changes all alchemy items of level 3 abilities from level 2 to 3 (if upgrade) or from 3 to 2 (if not upgrading)
  2659.     public function ChangeAlchemyItemsAbilities(upgrade : bool)
  2660.     {
  2661.         var i : int;
  2662.         var dm : CDefinitionsManagerAccessor;
  2663.         var items : array<SItemUniqueId>;
  2664.    
  2665.         inv.GetAllItems(items);
  2666.         dm = theGame.GetDefinitionsManager();
  2667.        
  2668.         for(i=0; i<items.Size(); i+=1)
  2669.             if(inv.IsItemAlchemyItem(items[i]))
  2670.                 UpgradeAlchemyItem(items[i], upgrade);
  2671.     }
  2672.    
  2673.     //changes all alchemy items of level 3 abilities from level 2 to 3 (if upgrade) or from 3 to 2 (if not upgrading)
  2674.     public function UpgradeAlchemyItem(itemID : SItemUniqueId, upgrade : bool)
  2675.     {
  2676.         var j, currLevel, otherLevel : int;
  2677.         var dm : CDefinitionsManagerAccessor;
  2678.         var abs, currAbilities, otherAbilities : array<name>;
  2679.         var min, max : SAbilityAttributeValue;
  2680.    
  2681.         if(!inv.IsItemAlchemyItem(itemID))
  2682.             return;
  2683.            
  2684.         //get current level
  2685.         currLevel = (int)CalculateAttributeValue(inv.GetItemAttributeValue(itemID, 'level'));
  2686.        
  2687.         //if level ok then exit
  2688.         if(currLevel == 3 || currLevel == 2 || currLevel < 2 || currLevel > 3)
  2689.             return;
  2690.    
  2691.         //get current ability name
  2692.         currAbilities = inv.GetItemAbilitiesWithAttribute(itemID, 'level', currLevel);
  2693.                    
  2694.         //get other ability name
  2695.         inv.GetItemContainedAbilities(itemID, abs);
  2696.         dm = theGame.GetDefinitionsManager();
  2697.         for(j=0; j<abs.Size(); j+=1)
  2698.         {
  2699.             dm.GetAbilityAttributeValue(abs[j], 'level', min, max);
  2700.             otherLevel = (int)CalculateAttributeValue(GetAttributeRandomizedValue(min, max));
  2701.             if( (otherLevel == 2 || otherLevel == 3) && otherLevel != currLevel)
  2702.                 otherAbilities.PushBack(abs[j]);
  2703.         }
  2704.        
  2705.         //swap abilities
  2706.         if(otherAbilities.Size() == 0)
  2707.         {
  2708.             LogAssert(false, "CR4Player.UpgradeAlchemyItem: cannot find ability to swap to from <<" + currAbilities[0] + ">> on item <<" + inv.GetItemName(itemID) + ">> !!!");
  2709.         }
  2710.         else
  2711.         {
  2712.             for(j=0; j<currAbilities.Size(); j+=1)
  2713.                 inv.RemoveItemBaseAbility(itemID, currAbilities[j]);
  2714.                
  2715.             for(j=0; j<otherAbilities.Size(); j+=1)
  2716.                 inv.AddItemBaseAbility(itemID, otherAbilities[j]);
  2717.         }
  2718.     }
  2719.    
  2720.     ///////////////////////////////////////////////////////////////////////////
  2721.     // Movement adjustment helper functions
  2722.     ///////////////////////////////////////////////////////////////////////////
  2723.  
  2724.     public function MovAdjRotateToTarget( ticket : SMovementAdjustmentRequestTicket )
  2725.     {
  2726.         var movementAdjustor : CMovementAdjustor = GetMovingAgentComponent().GetMovementAdjustor();
  2727.         var localOrientationTarget : EOrientationTarget = GetOrientationTarget();
  2728.  
  2729.         if ( localOrientationTarget == OT_CustomHeading )
  2730.         {
  2731.             movementAdjustor.RotateTo( ticket, GetOrientationTargetCustomHeading() );                  
  2732.         }
  2733.         else if ( localOrientationTarget == OT_Actor )
  2734.         {
  2735.             /*if  ( parryTarget && IsGuarded() )
  2736.                 movementAdjustor.RotateTowards( ticket, parryTarget );
  2737.             else*/ if ( slideTarget )
  2738.                 movementAdjustor.RotateTowards( ticket, slideTarget );
  2739.             else if ( lAxisReleasedAfterCounter )
  2740.                 movementAdjustor.RotateTo( ticket, GetHeading() );
  2741.             else
  2742.                 movementAdjustor.RotateTo( ticket, GetCombatActionHeading() );//rawPlayerHeading );
  2743.         }
  2744.         else if ( localOrientationTarget == OT_Player )
  2745.         {
  2746.             if ( bLAxisReleased )
  2747.                 movementAdjustor.RotateTo( ticket, GetHeading() );
  2748.             else
  2749.                 movementAdjustor.RotateTo( ticket, rawPlayerHeading );//GetCombatActionHeading() );
  2750.         }
  2751.         else if ( localOrientationTarget == OT_CameraOffset )
  2752.         {
  2753.             //movementAdjustor.RotateTo( ticket, VecHeading( cachedCameraVector ) );//rawCameraHeading - oTCameraOffset );
  2754.             movementAdjustor.RotateTo( ticket, VecHeading( theCamera.GetCameraDirection() ) );//rawCameraHeading );
  2755.         }      
  2756.         else
  2757.         {
  2758.             // default to camera
  2759.             movementAdjustor.RotateTo( ticket, rawCameraHeading );
  2760.         }
  2761.         // never rotate to player
  2762.     }
  2763.  
  2764.     ////////////////////////////////////////////////////////////////////////////////////
  2765.     // Look at targets - moved here from movables
  2766.     ////////////////////////////////////////////////////////////////////////////////////
  2767.     //var cachedCameraVector : Vector;
  2768.     public function UpdateLookAtTarget()
  2769.     {
  2770.         var localOrientationTarget  : EOrientationTarget;
  2771.         var playerRot           : EulerAngles;
  2772.         var lookAtActive        : Float;
  2773.         var lookAtTarget        : Vector;
  2774.         var headBoneIdx         : int;
  2775.         var tempComponent       : CDrawableComponent;
  2776.         var entityHeight        : float;
  2777.         var useTorsoBone        : bool;
  2778.        
  2779.         var angles              : EulerAngles;
  2780.         var dir                 : Vector;
  2781.         var camZ                : float;
  2782.        
  2783.         var target              : CActor;
  2784.        
  2785.         lookAtActive = 0.0f;
  2786.    
  2787.         localOrientationTarget = GetOrientationTarget();
  2788.        
  2789.         if ( localOrientationTarget == OT_Player || localOrientationTarget == OT_CustomHeading )
  2790.         {
  2791.             /*headBoneIdx = GetTorsoBoneIndex();
  2792.             if ( headBoneIdx >= 0 )
  2793.             {
  2794.                 lookAtTarget = MatrixGetTranslation( GetBoneWorldMatrixByIndex( headBoneIdx ) );
  2795.             }*/    
  2796.            
  2797.             //lookAtTarget = GetHeadingVector() * 30.f + this.GetWorldPosition();// + lookAtTarget;
  2798.            
  2799.             if ( localOrientationTarget == OT_Player  )
  2800.                 angles = VecToRotation( GetHeadingVector() );
  2801.             else if ( customOrientationInfoStack.Size() > 0 )
  2802.                 angles = VecToRotation( VecFromHeading( customOrientationInfoStack[ customOrientationInfoStack.Size() - 1 ].customHeading ) );
  2803.             else
  2804.                 angles = VecToRotation( GetHeadingVector() );
  2805.            
  2806.             //angles.Pitch = oTCameraPitchOffset;  
  2807.             dir = RotForward( angles );
  2808.             lookAtTarget = dir * 30.f + this.GetWorldPosition();// + lookAtTarget;
  2809.             lookAtTarget.Z += 1.6f;
  2810.             lookAtActive = 1.0f;       
  2811.         }
  2812.         else if ( localOrientationTarget == OT_Camera )
  2813.         {
  2814.             headBoneIdx = GetHeadBoneIndex();
  2815.             if ( headBoneIdx >= 0 )
  2816.             {
  2817.                 lookAtTarget = MatrixGetTranslation( GetBoneWorldMatrixByIndex( headBoneIdx ) );
  2818.             }
  2819.             else
  2820.             {
  2821.                 lookAtTarget = GetWorldPosition();
  2822.                 lookAtTarget.Z += 1.6f; // fake head?
  2823.             }
  2824.             lookAtTarget += theCamera.GetCameraDirection() * 100.f;
  2825.             lookAtActive = 1.0f;
  2826.         }
  2827.         else if ( localOrientationTarget == OT_CameraOffset )
  2828.         {
  2829.             /*lookAtTarget = GetWorldPosition();
  2830.             lookAtTarget.Z += 1.6f; // fake head?          
  2831.             camDir = theCamera.GetCameraDirection();           
  2832.             camZ = camDir.Z;// + 0.1;
  2833.             camDir = VecFromHeading( VecHeading( theCamera.GetCameraDirection() ) - oTCameraOffset ) * VecLength2D( camDir );
  2834.             camDir.Z = camZ;*/
  2835.                    
  2836.             dir = theCamera.GetCameraDirection();
  2837.             angles = VecToRotation( dir );
  2838.             angles.Pitch = -angles.Pitch + oTCameraPitchOffset;
  2839.             angles.Yaw -= oTCameraOffset;
  2840.             dir = RotForward( angles );
  2841.    
  2842.             lookAtTarget = dir * 30.f + this.GetWorldPosition();// + lookAtTarget;
  2843.             lookAtTarget.Z += 1.6f;
  2844.             lookAtActive = 1.0f;
  2845.         }      
  2846.         else if ( localOrientationTarget == OT_Actor )
  2847.         {
  2848.             if ( IsInCombatAction() )
  2849.             {
  2850.                 if ( ( ( ( W3PlayerWitcher )this ).GetCurrentlyCastSign() != ST_None && GetBehaviorVariable( 'combatActionType' ) == (int)CAT_CastSign )
  2851.                     || GetBehaviorVariable( 'combatActionType' ) == (int)CAT_ItemThrow )
  2852.                     //|| GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Crossbow )
  2853.                 useTorsoBone = true;
  2854.             }
  2855.        
  2856.             if ( rangedWeapon && rangedWeapon.GetCurrentStateName() != 'State_WeaponWait' )
  2857.                 useTorsoBone = true;
  2858.        
  2859.             if ( tempLookAtTarget && (CActor)(tempLookAtTarget) )
  2860.             {
  2861.                 lookAtTarget = ProcessLookAtTargetPosition( tempLookAtTarget, useTorsoBone );
  2862.                 lookAtActive = 1.0f;
  2863.             }
  2864.            
  2865.             if ( GetDisplayTarget() && IsDisplayTargetTargetable() )
  2866.             {
  2867.                 lookAtTarget = ProcessLookAtTargetPosition( GetDisplayTarget(), useTorsoBone );
  2868.                 lookAtActive = 1.0f;
  2869.             }
  2870.             else
  2871.             {
  2872.                 //FAIL SAFE in case the displayTarget disappears for some reason
  2873.                
  2874.                 if ( slideTarget )
  2875.                 {
  2876.                     lookAtTarget = ProcessLookAtTargetPosition( slideTarget, useTorsoBone );
  2877.                 }
  2878.                 else
  2879.                 {
  2880.                     target = GetTarget();
  2881.                     if ( target )
  2882.                     {
  2883.                         lookAtTarget = ProcessLookAtTargetPosition( target, useTorsoBone );
  2884.                     }
  2885.                 }
  2886.                    
  2887.                 lookAtActive = 1.0f;   
  2888.             }
  2889.            
  2890.             if ( !slideTarget && !IsUsingVehicle() )
  2891.             {
  2892.                 // TODO maybe just get axis from head?
  2893.                 playerRot = GetWorldRotation();
  2894.                 lookAtTarget = GetWorldPosition() + VecFromHeading( playerRot.Yaw ) * 100.0f;
  2895.                 lookAtActive = 0.0f;
  2896.             }
  2897.            
  2898.             if ( useTorsoBone )
  2899.                 lookAtTarget.Z += 0.2f;
  2900.         }
  2901.        
  2902.        
  2903.         //lookAtTarget = player.GetHeadingVector() * 30.f + this.GetWorldPosition();// + lookAtTarget;
  2904.         //lookAtActive = 1.0f; 
  2905.         GetVisualDebug().AddSphere('lookAtTarget', 1.f, lookAtTarget, true, Color(255,0,0), 3.0f );
  2906.         SetLookAtPosition( lookAtTarget );
  2907.         UpdateLookAtVariables( lookAtActive, lookAtTarget );
  2908.     }
  2909.  
  2910.     private function ProcessLookAtTargetPosition( ent : CGameplayEntity, useTorsoBone : bool ) : Vector
  2911.     {
  2912.         var boneIdx         : int;
  2913.         var actor           : CActor;
  2914.         var lookAtTarget    : Vector;
  2915.         var tempComponent   : CDrawableComponent;
  2916.         var box             : Box;
  2917.         var entityHeight    : float;
  2918.         var entityPos       : Vector;
  2919.         var predictedPos    : Vector;
  2920.         var z               : float;
  2921.         var entMat          : Matrix;
  2922.    
  2923.         actor = (CActor)(ent);
  2924.         entityPos = ent.GetWorldPosition();
  2925.         lookAtTarget = entityPos;
  2926.        
  2927.         if ( actor )
  2928.         {
  2929.             if ( useTorsoBone )
  2930.                 boneIdx = actor.GetTorsoBoneIndex();
  2931.             else               
  2932.                 boneIdx = actor.GetHeadBoneIndex();
  2933.         }
  2934.         else
  2935.             boneIdx = -1;
  2936.    
  2937.         if ( !( ent.aimVector.X == 0 && ent.aimVector.Y == 0 && ent.aimVector.Z == 0 ) )
  2938.         {
  2939.             entMat = ent.GetLocalToWorld();
  2940.             lookAtTarget = VecTransform( entMat, ent.aimVector );
  2941.         }  
  2942.         else if ( boneIdx >= 0 )
  2943.         {
  2944.             lookAtTarget = MatrixGetTranslation( ent.GetBoneWorldMatrixByIndex( boneIdx ) );   
  2945.         }  
  2946.         else
  2947.         {
  2948.             if ( actor )
  2949.                 lookAtTarget.Z += ( ((CMovingPhysicalAgentComponent)actor.GetMovingAgentComponent()).GetCapsuleHeight() * 0.5 ); // fake head?
  2950.             else
  2951.             {
  2952.                 tempComponent = (CDrawableComponent)( ent.GetComponentByClassName('CDrawableComponent') );
  2953.                 if ( tempComponent.GetObjectBoundingVolume( box ) )
  2954.                 {
  2955.                     entityHeight = box.Max.Z - box.Min.Z;
  2956.                     lookAtTarget = lookAtTarget + Vector(0,0,entityHeight/2);
  2957.                 }      
  2958.             }
  2959.         }
  2960.         z = ((CMovingPhysicalAgentComponent)actor.GetMovingAgentComponent()).GetCapsuleHeight();
  2961.         if ( actor )
  2962.         {
  2963.             if ( PredictLookAtTargetPosition( actor, lookAtTarget.Z - entityPos.Z, predictedPos ) )
  2964.                 lookAtTarget = predictedPos;
  2965.         }
  2966.            
  2967.         return lookAtTarget;
  2968.     }
  2969.    
  2970.    
  2971.     private function PredictLookAtTargetPosition( targetActor : CActor, zOffSet : float, out predictedPos : Vector ) : bool
  2972.     {
  2973.         var virtualPos      : Vector;
  2974.         var i               : int;
  2975.         var dist            : float;
  2976.         var deltaTime       : float;
  2977.         var projSpeed       : float;
  2978.         var projSpeedInt    : Vector;
  2979.         var projAngle       : float;   
  2980.        
  2981.         var e3Hack              : bool;
  2982.         var currentTimeInCurve : float;
  2983.         e3Hack = false;    
  2984.        
  2985.         if ( rangedWeapon
  2986.             && rangedWeapon.GetDeployedEntity()
  2987.             && ( rangedWeapon.GetCurrentStateName() == 'State_WeaponAim' || rangedWeapon.GetCurrentStateName() == 'State_WeaponShoot' ) )
  2988.         {  
  2989.             projSpeed = rangedWeapon.GetDeployedEntity().projSpeed;
  2990.  
  2991.             virtualPos = targetActor.GetWorldPosition();
  2992.            
  2993.             if ( e3Hack && targetActor.HasTag( 'e3_griffin' ) )
  2994.             {
  2995.                 for ( i = 0; i < 10; i += 1 )
  2996.                 {
  2997.                     dist = VecDistance( rangedWeapon.GetDeployedEntity().GetWorldPosition(), virtualPos );
  2998.                     deltaTime = dist/projSpeed;
  2999.                     virtualPos = targetActor.PredictWorldPosition( deltaTime );
  3000.                 }
  3001.             }
  3002.             else
  3003.                 return false;
  3004.  
  3005.             virtualPos.Z += zOffSet;
  3006.             predictedPos = virtualPos;
  3007.             GetVisualDebug().AddSphere('CrossbowPredictedPos', 1.0f, virtualPos , true, Color(255,50,50), 5.0f );
  3008.             return true;
  3009.         }
  3010.         return false;
  3011.     }
  3012.    
  3013.     public function SetLookAtPosition( vec : Vector )
  3014.     {
  3015.         lookAtPosition = vec;
  3016.     }
  3017.  
  3018.     public function GetLookAtPosition() : Vector
  3019.     {
  3020.         return lookAtPosition;
  3021.     }
  3022.    
  3023.     ////////////////////////////////////////////////////////////////////////////////////
  3024.     // Scene
  3025.     ////////////////////////////////////////////////////////////////////////////////////
  3026.    
  3027.     event OnBlockingSceneEnded( optional output : CStorySceneOutput)
  3028.     {
  3029.         //hack for possible immortality from finishers
  3030.         SetImmortalityMode( AIM_None, AIC_SyncedAnim );
  3031.         super.OnBlockingSceneEnded(output);
  3032.     }
  3033.    
  3034.     ////////////////////////////////////////////////////////////////////////////////////
  3035.     // New combat / exploration and weapon drawing
  3036.     ////////////////////////////////////////////////////////////////////////////////////
  3037.    
  3038.     function GetCurrentMeleeWeaponName() : name
  3039.     {
  3040.         return weaponHolster.GetCurrentMeleeWeaponName();
  3041.     }
  3042.    
  3043.     public function GetCurrentMeleeWeaponType() : EPlayerWeapon
  3044.     {
  3045.         return weaponHolster.GetCurrentMeleeWeapon();
  3046.     }
  3047.    
  3048.     public function OnMeleeForceHolster(ignoreActionLock : bool)
  3049.     {
  3050.         weaponHolster.HolsterWeapon(ignoreActionLock, true);
  3051.     }
  3052.    
  3053.     event OnForcedHolsterWeapon()
  3054.     {
  3055.         weaponHolster.OnForcedHolsterWeapon();
  3056.     }
  3057.    
  3058.     event OnEquippedItem( category : name, slotName : name )
  3059.     {
  3060.         var weaponType : EPlayerWeapon;
  3061.        
  3062.         if ( slotName == 'r_weapon' )
  3063.         {
  3064.             switch ( category )
  3065.             {
  3066.                 case 'None' :
  3067.                     weaponType = PW_None;
  3068.                     break;
  3069.                 case 'fist' :
  3070.                     weaponType = PW_Fists;
  3071.                     break;
  3072.                 case 'steelsword' :
  3073.                     weaponType = PW_Steel;
  3074.                     break;
  3075.                 case 'silversword' :
  3076.                     weaponType = PW_Silver;
  3077.                     break;
  3078.                 default :
  3079.                     return true;
  3080.             }
  3081.            
  3082.             weaponHolster.OnEquippedMeleeWeapon( weaponType );
  3083.         }
  3084.     }
  3085.    
  3086.     private var isHoldingDeadlySword : bool;
  3087.     public function ProcessIsHoldingDeadlySword()
  3088.     {
  3089.         isHoldingDeadlySword = IsDeadlySwordHeld();
  3090.     }
  3091.    
  3092.     public function IsHoldingDeadlySword() : bool
  3093.     {
  3094.         return isHoldingDeadlySword;
  3095.     }
  3096.    
  3097.     event OnHolsteredItem( category :  name, slotName : name )
  3098.     {
  3099.         var weaponType : EPlayerWeapon;
  3100.        
  3101.         //hide HUD buff icon
  3102.         if ( slotName == 'r_weapon' && (category == 'steelsword' || category == 'silversword') )
  3103.         {
  3104.             if( category == 'steelsword' )
  3105.             {
  3106.                 ManageAerondightBuff( false );
  3107.             }
  3108.            
  3109.             GetBuff( EET_LynxSetBonus ).Pause( 'drawing weapon' );
  3110.            
  3111.             PauseOilBuffs( category == 'steelsword' );
  3112.         }
  3113.        
  3114.         if ( slotName == 'r_weapon' )
  3115.         {
  3116.             weaponType = weaponHolster.GetCurrentMeleeWeapon();
  3117.             switch ( category )
  3118.             {
  3119.                 case 'fist' :
  3120.                     if ( weaponType == PW_Fists )
  3121.                         weaponHolster.OnEquippedMeleeWeapon( PW_None );
  3122.                     return true;
  3123.                 case 'steelsword' :
  3124.                     if ( weaponType == PW_Steel )
  3125.                         weaponHolster.OnEquippedMeleeWeapon( PW_None );
  3126.                     return true;
  3127.                 case 'silversword' :
  3128.                     if ( weaponType == PW_Silver )
  3129.                         weaponHolster.OnEquippedMeleeWeapon( PW_None );
  3130.                     return true;
  3131.                 default :
  3132.                     return true;
  3133.             }
  3134.         }
  3135.     }
  3136.    
  3137.     event OnEquipMeleeWeapon( weaponType : EPlayerWeapon, ignoreActionLock : bool, optional sheatheIfAlreadyEquipped : bool )
  3138.     {  
  3139.         RemoveTimer( 'DelayedSheathSword' );
  3140.                
  3141.         weaponHolster.OnEquipMeleeWeapon( weaponType, ignoreActionLock, sheatheIfAlreadyEquipped );
  3142.        
  3143.         /*// Check if we want to go to combat or exploration
  3144.         if( weaponHolster.GetCurrentMeleeWeapon() == PW_None )
  3145.         {      
  3146.             GoToExplorationIfNeeded( );
  3147.         }
  3148.         else
  3149.         {
  3150.             GoToCombatIfNeeded( );
  3151.         }*/
  3152.        
  3153.         m_RefreshWeaponFXType = true;
  3154.     }
  3155.    
  3156.     event OnHolsterLeftHandItem()
  3157.     {
  3158.         weaponHolster.OnHolsterLeftHandItem();
  3159.     }
  3160.    
  3161.     timer function DelayedTryToReequipWeapon( dt: float, id : int )
  3162.     {
  3163.         var weaponType : EPlayerWeapon;
  3164.        
  3165.         if( IsInCombat() && GetTarget() )
  3166.         {
  3167.             weaponType = GetMostConvenientMeleeWeapon( GetTarget() );
  3168.            
  3169.             if ( weaponType == PW_Steel || weaponType == PW_Silver )
  3170.                 weaponHolster.OnEquipMeleeWeapon( weaponType, false );
  3171.         }  
  3172.     }
  3173.    
  3174.     timer function DelayedSheathSword( dt: float, id : int )
  3175.     {
  3176.         if ( !IsCombatMusicEnabled() )
  3177.         {
  3178.             if ( IsInCombatAction() || !IsActionAllowed( EIAB_DrawWeapon ) )
  3179.             {
  3180.                 LogChannel( 'OnCombatFinished', "DelayedSheathSword: Sheath pushed to buffer" );
  3181.                 PushCombatActionOnBuffer(EBAT_Sheathe_Sword,BS_Pressed);
  3182.             }
  3183.             else
  3184.             {
  3185.                 LogChannel( 'OnCombatFinished', "DelayedSheathSword: Sheath successful" );
  3186.                 OnEquipMeleeWeapon( PW_None, false );
  3187.             }
  3188.         }  
  3189.     }
  3190.    
  3191.     protected function ShouldAutoSheathSwordInstantly() : bool
  3192.     {
  3193.         var enemies : array<CActor>;
  3194.         var i : int;
  3195.        
  3196.         GetEnemiesInRange( enemies );
  3197.        
  3198.         for ( i = 0; i < enemies.Size(); i += 1 )
  3199.         {
  3200.             if ( IsThreat( enemies[i] ) &&
  3201.                 VecDistance( enemies[i].GetWorldPosition(), this.GetWorldPosition() ) <= findMoveTargetDist )
  3202.             {
  3203.                 return false;
  3204.             }
  3205.         }
  3206.        
  3207.         return true;
  3208.     }
  3209.    
  3210.     public function PrepareToAttack( optional target : CActor, optional action : EBufferActionType )
  3211.     {
  3212.         var  weaponType         : EPlayerWeapon;
  3213.        
  3214.         if( IsInAir() || !GetBIsCombatActionAllowed() )
  3215.         {
  3216.             return ;
  3217.         }
  3218.        
  3219.         if( !target )
  3220.         {
  3221.             target  = (CActor)displayTarget;
  3222.         }
  3223.         if( !target && IsCombatMusicEnabled() )
  3224.         {
  3225.             target  = moveTarget;
  3226.         }
  3227.         if( !target )
  3228.         {
  3229.             if ( this.GetCurrentStateName() == 'Exploration' )
  3230.             {
  3231.                 SetCombatActionHeading( ProcessCombatActionHeading( action ) );
  3232.                 thePlayer.CanAttackWhenNotInCombat( action, false, target );
  3233.             }
  3234.         }
  3235.        
  3236.         weaponHolster.TryToPrepareMeleeWeaponToAttack();
  3237.        
  3238.         //if ( this.GetCurrentStateName() == 'Exploration' ) //PF - commenting this because Geralt won't switch to proper state when you sheathe sword while mashing attack
  3239.         {
  3240.             weaponType = GetCurrentMeleeWeaponType();
  3241.            
  3242.             if ( weaponType == PW_None )
  3243.             {
  3244.                 // Get the weapon we have to use
  3245.                 weaponType = GetMostConvenientMeleeWeapon( target );
  3246.             }
  3247.            
  3248.             // Can't go to combat if we are in not a proper state
  3249.             if( !OnStateCanGoToCombat() )
  3250.             {
  3251.                 return;
  3252.             }
  3253.            
  3254.             GoToCombat( weaponType );
  3255.         }
  3256.     }
  3257.    
  3258.     public function DisplayCannotAttackMessage( actor : CActor ) : bool
  3259.     {
  3260.         if ( actor && ( actor.GetMovingAgentComponent().GetName() == "child_base" || ((CNewNPC)actor).GetNPCType() == ENGT_Quest ) )
  3261.         {
  3262.             DisplayHudMessage(GetLocStringByKeyExt("panel_hud_message_cant_attack_this_target"));
  3263.             return true;
  3264.         }  
  3265.        
  3266.         return false;
  3267.     }
  3268.    
  3269.     public function GetMostConvenientMeleeWeapon( targetToDrawAgainst : CActor, optional ignoreActionLock : bool ) : EPlayerWeapon
  3270.     {
  3271.         return weaponHolster.GetMostConvenientMeleeWeapon( targetToDrawAgainst, ignoreActionLock );
  3272.     }
  3273.    
  3274.     private var reevaluateCurrentWeapon : bool;
  3275.    
  3276.     event OnTargetWeaponDrawn()
  3277.     {
  3278.         var  weaponType : EPlayerWeapon = this.GetCurrentMeleeWeaponType();
  3279.         if ( weaponType == PW_Fists )
  3280.             reevaluateCurrentWeapon = true;
  3281.     }
  3282.    
  3283.     public function GoToCombatIfNeeded( optional enemy : CActor ) : bool
  3284.     {
  3285.         var  weaponType : EPlayerWeapon;
  3286.         var  target     : CActor;
  3287.        
  3288.         if( !enemy && IsInCombat() )
  3289.         {
  3290.             target = GetTarget();
  3291.            
  3292.             if ( target )
  3293.                 enemy = target;
  3294.             else
  3295.                 enemy = moveTarget;
  3296.         }
  3297.        
  3298.         // Should we fight
  3299.         if( !ShouldGoToCombat( enemy ) )
  3300.         {
  3301.             return false;
  3302.         }
  3303.        
  3304.         weaponType = this.GetCurrentMeleeWeaponType();
  3305.        
  3306.         if ( weaponType == PW_None || ( reevaluateCurrentWeapon && weaponType == PW_Fists ) || ( !IsInCombat() && weaponHolster.IsOnTheMiddleOfHolstering() ) )
  3307.         {
  3308.             // Get the weapon we have to use
  3309.             weaponType = weaponHolster.GetMostConvenientMeleeWeapon( enemy );
  3310.             reevaluateCurrentWeapon = false;
  3311.         }
  3312.        
  3313.         // Change the state+
  3314.         GoToCombat( weaponType );
  3315.        
  3316.        
  3317.         return true;
  3318.     }
  3319.    
  3320.     public function GoToCombatIfWanted( ) : bool
  3321.     {
  3322.         var weaponType  : EPlayerWeapon;
  3323.         var target      : CActor;
  3324.         var enemy       : CActor;
  3325.        
  3326.        
  3327.         if( !IsInCombat() )
  3328.         {
  3329.             return false;
  3330.         }
  3331.        
  3332.         target = GetTarget();
  3333.        
  3334.         if ( target )
  3335.             enemy = target;
  3336.         else
  3337.             enemy = moveTarget;
  3338.        
  3339.         weaponType = this.GetCurrentMeleeWeaponType();
  3340.        
  3341.         if ( weaponType == PW_None || ( !IsInCombat() && weaponHolster.IsOnTheMiddleOfHolstering() ) )
  3342.         {
  3343.             // Get the weapon we have to use
  3344.             weaponType = weaponHolster.GetMostConvenientMeleeWeapon( enemy );
  3345.         }
  3346.        
  3347.         // Change the state+
  3348.         GoToCombat( weaponType );
  3349.        
  3350.        
  3351.         return true;
  3352.     }
  3353.    
  3354.     public function GoToExplorationIfNeeded() : bool
  3355.     {
  3356.         /*
  3357.         if( GetCurrentStateName() == 'Exploration' )
  3358.         {
  3359.             return false;
  3360.         }
  3361.         */
  3362.        
  3363.         if( ! IsInCombatState() )
  3364.         {
  3365.             return false;
  3366.         }
  3367.        
  3368.         if( !ShouldGoToExploration() )
  3369.         {
  3370.             return false;
  3371.         }
  3372.        
  3373.         // Change fists weapon to none
  3374.         weaponHolster.EndedCombat();
  3375.        
  3376.         // Change the state
  3377.         GotoState( 'Exploration' );
  3378.         return true;
  3379.     }
  3380.    
  3381.     event OnStateCanGoToCombat()
  3382.     {
  3383.         return false;
  3384.     }
  3385.    
  3386.     event OnStateCanUpdateExplorationSubstates()
  3387.     {
  3388.         return false;
  3389.     }
  3390.    
  3391.     private function ShouldGoToCombat( optional enemy : CActor ) : bool
  3392.     {
  3393.         var currentStateName : name;
  3394.        
  3395.         // Can't go to combat if we are in not a proper state
  3396.         if( !OnStateCanGoToCombat() )
  3397.         {
  3398.             return false;
  3399.         }
  3400.        
  3401.         currentStateName = GetCurrentStateName();
  3402.        
  3403.         if( currentStateName == 'AimThrow' )
  3404.         {
  3405.             return false;
  3406.         }
  3407.        
  3408.         if( currentStateName == 'Swimming' )
  3409.         {
  3410.             return false;
  3411.         }
  3412.  
  3413.         if( currentStateName == 'TraverseExploration' )
  3414.         {
  3415.             return false;
  3416.         }
  3417.        
  3418.         // TODO: Reenable or find somethingbetter
  3419.         // Temporaryly disabled cause it does not work on some terrain
  3420.         /*
  3421.         if ( !theGame.GetWorld().NavigationLineTest( GetWorldPosition(), enemy.GetWorldPosition(), 0.4 ) )
  3422.         {
  3423.             return false;
  3424.         }
  3425.         */
  3426.        
  3427.         // if there is no enemy, check if combat is forced
  3428.         if ( !enemy )
  3429.         {
  3430.             return playerMode.combatMode;
  3431.         }
  3432.        
  3433.         // See if we should be fighting this enemy
  3434.         /*if ( !IsEnemyVisible( enemy ) )
  3435.         {
  3436.             return false;
  3437.         }*/
  3438.         /*if ( !WasVisibleInScaledFrame( enemy, 1.f, 1.f )  )
  3439.         {
  3440.             return false;
  3441.         }*/
  3442.        
  3443.         return true;
  3444.     }
  3445.    
  3446.     private function ShouldGoToExploration() : bool
  3447.     {
  3448.         if ( IsInCombat() )//moveTarget && IsThreat( moveTarget ) )
  3449.         {
  3450.             return false;
  3451.         }
  3452.         /*if( IsGuarded() )
  3453.         {
  3454.             return false;
  3455.         }*/
  3456.         if ( rangedWeapon && rangedWeapon.GetCurrentStateName() != 'State_WeaponWait' )
  3457.         {
  3458.             return false;
  3459.         }
  3460.         if( IsFistFightMinigameEnabled() )
  3461.         {
  3462.             return false;
  3463.         }
  3464.         if( IsKnockedUnconscious() )
  3465.         {
  3466.             return false;
  3467.         }
  3468.         if( IsInCombatAction() )
  3469.         {
  3470.             return false;
  3471.         }
  3472.         if( GetCriticalBuffsCount() > 0 )
  3473.         {
  3474.             return false;
  3475.         }
  3476.        
  3477.         return true;
  3478.     }
  3479.    
  3480.     // W3EE - Begin
  3481.     public function GoToCombat( weaponType : EPlayerWeapon, optional initialAction : EInitialAction )
  3482.     // W3EE - End
  3483.     {          
  3484.         // Set up and change state
  3485.         switch( weaponType )
  3486.         {
  3487.             case PW_Silver:
  3488.                 ((W3PlayerWitcherStateCombatSilver) GetState('CombatSilver')).SetupState( initialAction );
  3489.                 GoToStateIfNew( 'CombatSilver' );
  3490.                 break;
  3491.             case PW_Steel:
  3492.                 ((W3PlayerWitcherStateCombatSteel) GetState('CombatSteel')).SetupState( initialAction );
  3493.                 GoToStateIfNew( 'CombatSteel' );
  3494.                 break;
  3495.             case PW_Fists:
  3496.             case PW_None:
  3497.             default :
  3498.                 ((W3PlayerWitcherStateCombatFists) GetState('CombatFists')).SetupState( initialAction );
  3499.                 GoToStateIfNew( 'CombatFists' );
  3500.             break;
  3501.         }  
  3502.     }
  3503.    
  3504.     public function GoToStateIfNew( newState : name, optional keepStack : bool, optional forceEvents : bool  )
  3505.     {
  3506.         if( newState != GetCurrentStateName() )
  3507.         {
  3508.             GotoState( newState, keepStack, forceEvents );
  3509.         }
  3510.     }
  3511.    
  3512.     // So we can debug and control what is changing the state
  3513.     public function GotoState( newState : name, optional keepStack : bool, optional forceEvents : bool  )
  3514.     {
  3515.         /*if( newState == 'Exploration' )
  3516.         {
  3517.             newState = newState;
  3518.         }*/
  3519.        
  3520.         super.GotoState( newState, keepStack, forceEvents );
  3521.         //PushState( newState );
  3522.     }
  3523.     /*
  3524.     public function PushState( newState : name )
  3525.     {
  3526.         if( newState == 'Exploration' )
  3527.         {
  3528.             newState = newState;
  3529.         }
  3530.         super.PushState( newState );
  3531.     }
  3532.    
  3533.     public function PopState( optional popAll : bool )
  3534.     {
  3535.         super.PopState( popAll );
  3536.     }
  3537.     */
  3538.     public function IsThisACombatSuperState( stateName : name ) : bool
  3539.     {
  3540.         return stateName == 'Combat' || stateName == 'CombatSteel' || stateName == 'CombatSilver' || stateName == 'CombatFists';
  3541.     }
  3542.    
  3543.     public function GetWeaponHolster() : WeaponHolster
  3544.     {
  3545.         return weaponHolster;
  3546.     }
  3547.    
  3548.     public function AbortSign()
  3549.     {
  3550.         var playerWitcher : W3PlayerWitcher;
  3551.         var sign : W3SignEntity;
  3552.        
  3553.         playerWitcher = (W3PlayerWitcher)this;
  3554.        
  3555.         if(playerWitcher)
  3556.         {
  3557.             sign = (W3SignEntity)playerWitcher.GetCurrentSignEntity();
  3558.             if (sign)
  3559.             {
  3560.                 sign.OnSignAborted();
  3561.             }
  3562.         }
  3563.     }
  3564.  
  3565.     ///////////////////////////////////////////////////////////////////////////
  3566.     // Animation event handlers
  3567.     ///////////////////////////////////////////////////////////////////////////
  3568.     protected var disableActionBlend : bool;
  3569.    
  3570.         //KonradSuperDodgeHACK: To make dodge more responsive during NORMAL ATTACKS, dodge will fire immediately when hit animation can be played.
  3571.         //When hit anim is disabled, then the action will be cached and will be processed at the END of DisallowHitAnim event.
  3572.         //During all other actions, however, it will use the normal check of inputAllowed and combatActionAllowed. This is a super hack. And we will all go to hell for this.  
  3573.     event OnAnimEvent_DisallowHitAnim( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3574.     {
  3575.         if ( animEventType == AET_DurationEnd )
  3576.         {  
  3577.             if ( ( BufferCombatAction == EBAT_Dodge || BufferCombatAction == EBAT_Roll )
  3578.                     &&  IsInCombatAction()
  3579.                     && GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Attack )
  3580.             {
  3581.                 //LogChannel('combatActionAllowed',"BufferCombatAction != EBAT_EMPTY");
  3582.                 ( (CR4Player)this ).ProcessCombatActionBuffer();
  3583.                 disableActionBlend = true;
  3584.             }
  3585.         }
  3586.         else if ( IsInCombatAction() && GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Dodge && animEventType == AET_DurationStart )
  3587.         {
  3588.             disableActionBlend = false;
  3589.         }
  3590.        
  3591.         super.OnAnimEvent_DisallowHitAnim( animEventName, animEventType, animInfo );
  3592.     }
  3593.    
  3594.    
  3595.     event OnAnimEvent_FadeOut( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3596.     {
  3597.         theGame.FadeOutAsync( 0.2, Color( 0, 0, 0, 1 ) );
  3598.     }
  3599.    
  3600.     event OnAnimEvent_FadeIn( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3601.     {
  3602.         theGame.FadeInAsync( 0.4 );
  3603.     }
  3604.    
  3605.     event OnAnimEvent_BloodTrailForced( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3606.     {
  3607.         var bloodTrailParam     : CBloodTrailEffect;
  3608.         var weaponId            : SItemUniqueId;
  3609.        
  3610.         if ( isInFinisher )
  3611.         {
  3612.             bloodTrailParam = (CBloodTrailEffect)(GetFinisherVictim()).GetGameplayEntityParam( 'CBloodTrailEffect' );
  3613.             weaponId = this.inv.GetItemFromSlot('r_weapon');
  3614.             if ( bloodTrailParam )
  3615.                 thePlayer.inv.PlayItemEffect( weaponId, bloodTrailParam.GetEffectName() );
  3616.         }
  3617.     }
  3618.    
  3619.     event OnAnimEvent_SlowMo( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3620.     {
  3621.         if ( isInFinisher && DisableManualCameraControlStackHasSource( 'Finisher' ) )
  3622.         {
  3623.             if( animEventType != AET_DurationEnd  )
  3624.                 theGame.SetTimeScale( 0.1f, 'AnimEventSlomoMo', 1000, true );
  3625.             else
  3626.                 theGame.RemoveTimeScale( 'AnimEventSlomoMo' ); 
  3627.         }
  3628.     }
  3629.    
  3630.     event OnAnimEvent_PlayFinisherBlood( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3631.     {
  3632.         if ( isInFinisher )
  3633.         {
  3634.             SpawnFinisherBlood();
  3635.         }
  3636.     }
  3637.    
  3638.     event OnAnimEvent_OnWeaponDrawReady( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3639.     {
  3640.         weaponHolster.OnWeaponDrawReady();
  3641.     }
  3642.    
  3643.     event OnAnimEvent_OnWeaponHolsterReady( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3644.     {
  3645.         weaponHolster.OnWeaponHolsterReady();
  3646.     }
  3647.    
  3648.     event OnAnimEvent_ThrowHoldTest( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3649.     {
  3650.         var thrownEntity        : CThrowable;
  3651.        
  3652.         thrownEntity = (CThrowable)EntityHandleGet( thrownEntityHandle );
  3653.        
  3654.         if( IsThrowHold() )
  3655.         {
  3656.             SetBehaviorVariable( 'throwStage', (int)TS_Loop );
  3657.             PushState( 'AimThrow' );
  3658.             thrownEntity.StartAiming();
  3659.         }
  3660.         else
  3661.         {
  3662.             BombThrowRelease();
  3663.             SetCombatIdleStance( 1.f );
  3664.         }
  3665.     }
  3666.    
  3667.     event OnAnimEvent_AllowTempLookAt( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3668.     {
  3669.         if( animEventType == AET_DurationStart )
  3670.             SetTempLookAtTarget( slideTarget );
  3671.         else if( animEventType == AET_DurationEnd )
  3672.             SetTempLookAtTarget( NULL );
  3673.     }
  3674.    
  3675.     protected var slideNPC          : CNewNPC;
  3676.     protected var minSlideDistance  : float;
  3677.     protected var maxSlideDistance  : float;
  3678.     protected var slideTicket       : SMovementAdjustmentRequestTicket;
  3679.    
  3680.     event OnAnimEvent_SlideToTarget( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3681.     {
  3682.         var movementAdjustor    : CMovementAdjustor;
  3683.        
  3684.         if( animEventType == AET_DurationStart )
  3685.         {
  3686.             slideNPC = (CNewNPC)slideTarget;
  3687.         }
  3688.            
  3689.         if( !slideNPC )
  3690.         {
  3691.             return false;
  3692.         }
  3693.            
  3694.         if( animEventType == AET_DurationStart && slideNPC.GetGameplayVisibility() )
  3695.         {
  3696.             movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor();
  3697.             slideTicket = movementAdjustor.GetRequest( 'SlideToTarget' );
  3698.             movementAdjustor.CancelByName( 'SlideToTarget' );
  3699.             slideTicket = movementAdjustor.CreateNewRequest( 'SlideToTarget' );
  3700.             movementAdjustor.BindToEventAnimInfo( slideTicket, animInfo );
  3701.             //movementAdjustor.Continuous(slideTicket);
  3702.             movementAdjustor.MaxLocationAdjustmentSpeed( slideTicket, 1000000 );
  3703.             movementAdjustor.ScaleAnimation( slideTicket );
  3704.             minSlideDistance = ((CMovingPhysicalAgentComponent)this.GetMovingAgentComponent()).GetCapsuleRadius()+((CMovingPhysicalAgentComponent)slideNPC.GetMovingAgentComponent()).GetCapsuleRadius();
  3705.             if( IsInCombatFist() )
  3706.             {
  3707.                 maxSlideDistance = 1000.0f;
  3708.             }
  3709.             else
  3710.             {
  3711.                 maxSlideDistance = minSlideDistance;
  3712.             }
  3713.             movementAdjustor.SlideTowards( slideTicket, slideTarget, minSlideDistance, maxSlideDistance ); 
  3714.         }
  3715.         else if( !slideNPC.GetGameplayVisibility() )
  3716.         {
  3717.             movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor();
  3718.             movementAdjustor.CancelByName( 'SlideToTarget' );
  3719.             slideNPC = NULL;
  3720.         }
  3721.         else
  3722.         {
  3723.             movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor();
  3724.             movementAdjustor.SlideTowards( slideTicket, slideTarget, minSlideDistance, maxSlideDistance );             
  3725.         }
  3726.     }
  3727.    
  3728.     event OnAnimEvent_ActionBlend( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3729.     {
  3730.     }
  3731.     /*
  3732.     event OnAnimEvent_Throwable( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3733.     {
  3734.         var thrownEntity        : CThrowable;  
  3735.        
  3736.         thrownEntity = (CThrowable)EntityHandleGet( thrownEntityHandle );
  3737.            
  3738.         if ( inv.IsItemCrossbow( inv.GetItemFromSlot('l_weapon') ) &&  rangedWeapon.OnProcessThrowEvent( animEventName ) )
  3739.         {      
  3740.             return true;
  3741.         }
  3742.         else if( thrownEntity && IsThrowingItem() && thrownEntity.OnProcessThrowEvent( animEventName ) )
  3743.         {
  3744.             return true;
  3745.         }  
  3746.     }*/
  3747.    
  3748.     event OnAnimEvent_SubstateManager( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3749.     {
  3750.         // Notify the exploration manager
  3751.         substateManager.OnAnimEvent( animEventName, animEventType, animInfo );
  3752.     }
  3753.    
  3754.     event OnAnimEvent_AllowFall( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3755.     {
  3756.         if ( !substateManager.m_OwnerMAC.IsOnGround() )
  3757.         {
  3758.             substateManager.m_SharedDataO.SetFallFromCritical( true );
  3759.             substateManager.m_MoverO.SetVelocity( -6.0f * GetWorldForward() );
  3760.             substateManager.QueueStateExternal( 'Jump' );
  3761.             RemoveBuff( EET_Knockdown, true );
  3762.             RemoveBuff( EET_HeavyKnockdown, true );
  3763.             return true;
  3764.         }
  3765.         return false;
  3766.     }
  3767.    
  3768.     event OnAnimEvent_AllowFall2( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3769.     {
  3770.         if ( !substateManager.m_OwnerMAC.IsOnGround() )
  3771.         {
  3772.             //substateManager.m_SharedDataO.m_FromCriticalB = true;
  3773.             //substateManager.m_MoverO.SetVelocity( -6.0f * GetWorldForward() );
  3774.             substateManager.QueueStateExternal( 'Jump' );
  3775.             RemoveBuff( EET_Knockdown, true );
  3776.             RemoveBuff( EET_HeavyKnockdown, true );
  3777.         }
  3778.         if( substateManager.StateWantsAndCanEnter( 'Slide' ) )
  3779.         {
  3780.             substateManager.QueueStateExternal( 'Slide' );
  3781.         }
  3782.     }
  3783.    
  3784.     event OnAnimEvent_DettachGround( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3785.     {
  3786.         //substateManager.m_MoverO.SetManualMovement( true );
  3787.     }
  3788.    
  3789.     //pad vibration for finishers
  3790.     event OnAnimEvent_pad_vibration( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3791.     {
  3792.         var witcher : W3PlayerWitcher;
  3793.        
  3794.         theGame.VibrateControllerHard();
  3795.        
  3796.         //delayed FX for runeword 10 & 12
  3797.         witcher = GetWitcherPlayer();
  3798.         // W3EE - Begin
  3799.         /*
  3800.         if(isInFinisher && witcher)
  3801.         {
  3802.             if(HasAbility('Runeword 10 _Stats', true) && !witcher.runeword10TriggerredOnFinisher && ((bool)theGame.GetInGameConfigWrapper().GetVarValue('Gameplay', 'AutomaticFinishersEnabled')) == true)
  3803.             {              
  3804.                 witcher.Runeword10Triggerred();
  3805.                 witcher.runeword10TriggerredOnFinisher = true;
  3806.             }
  3807.             else if(HasAbility('Runeword 12 _Stats', true) && !witcher.runeword12TriggerredOnFinisher)
  3808.             {
  3809.                 witcher.Runeword12Triggerred();
  3810.                 witcher.runeword12TriggerredOnFinisher = true;
  3811.             }
  3812.         }
  3813.         */
  3814.         // W3EE - End
  3815.     }
  3816.    
  3817.     //pad vibration light
  3818.     event OnAnimEvent_pad_vibration_light( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3819.     {
  3820.         //theGame.VibrateControllerLight(); //draw & sheathe weapon
  3821.     }
  3822.    
  3823.     event OnAnimEvent_KillWithRagdoll( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3824.     {
  3825.         //thePlayer.SetKinematic( false );
  3826.         //thePlayer.Kill();
  3827.     }
  3828.    
  3829.     event OnAnimEvent_RemoveBurning( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3830.     {  
  3831.         thePlayer.AddBuffImmunity(EET_Burning, 'AnimEvent_RemoveBurning', true);
  3832.     }
  3833.    
  3834.     event OnAnimEvent_RemoveTangled( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3835.     {
  3836.         if ( this.HasBuff( EET_Tangled ) )
  3837.         {
  3838.             this.StopEffect('black_spider_web');
  3839.             this.PlayEffectSingle('black_spider_web_break');       
  3840.         }
  3841.     }
  3842.    
  3843.     // sound generation for creatures following noise instead of just finding combat target
  3844.     event OnAnimEvent_MoveNoise( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  3845.     {
  3846.         theGame.GetBehTreeReactionManager().CreateReactionEventIfPossible( this, 'MoveNoise', -1, 30.0f, -1.f, -1, true );
  3847.     }
  3848. ///////////////////////////////////////////////////////////////////////////
  3849.    
  3850.     event OnBehaviorGraphNotification( notificationName : name, stateName : name )
  3851.     {
  3852.         substateManager.OnBehaviorGraphNotification( notificationName, stateName );
  3853.        
  3854.         if( notificationName == 'PlayerRunActivate' )
  3855.         {
  3856.             isInRunAnimation = true;
  3857.         }
  3858.         else if( notificationName == 'PlayerRunDeactivate' )
  3859.         {
  3860.             isInRunAnimation = false;
  3861.         }
  3862.     }
  3863.  
  3864.     event OnEnumAnimEvent( animEventName : name, variant : SEnumVariant, animEventType : EAnimationEventType, animEventDuration : float, animInfo : SAnimationEventAnimInfo )
  3865.     {
  3866.         var movementAdjustor : CMovementAdjustor;
  3867.         var ticket : SMovementAdjustmentRequestTicket;
  3868.         var rotationRate : ERotationRate;
  3869.        
  3870.         if ( animEventName == 'RotateToTarget' )
  3871.         {
  3872.             /**
  3873.              *  Rotate player to target
  3874.              */
  3875.             rotationRate = GetRotationRateFromAnimEvent( variant.enumValue );
  3876.  
  3877.             movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor();
  3878.             if ( animEventType == AET_DurationStart || animEventType == AET_DurationStartInTheMiddle )
  3879.             {
  3880.                 // when it starts (also in the middle - it may mean that we switch between events)
  3881.                 // create request if there isn't any and always setup rotation rate
  3882.                 if (! movementAdjustor.IsRequestActive( movementAdjustor.GetRequest( 'RotateToTarget' ) ) )
  3883.                 {
  3884.                     // start rotation adjustment
  3885.                     ticket = movementAdjustor.CreateNewRequest( 'RotateToTarget' );
  3886.                    
  3887.                     // use adjustment duration only when RR_0 is selected, otherwise use continuous to match desired rotation as fast as possible
  3888.                     if ((int)rotationRate == 0)
  3889.                         movementAdjustor.AdjustmentDuration( ticket, animEventDuration );
  3890.                     else
  3891.                     {
  3892.                         movementAdjustor.Continuous( ticket );
  3893.                         movementAdjustor.BindToEvent( ticket, 'RotateToTarget' );
  3894.                     }  
  3895.                    
  3896.                     movementAdjustor.DontUseSourceAnimation( ticket ); // do not use source anim as it will use delta seconds from event
  3897.                     movementAdjustor.ReplaceRotation( ticket );
  3898.                 }
  3899.                 else
  3900.                 {
  3901.                     // get existing ticket to update rotation rate
  3902.                     ticket = movementAdjustor.GetRequest( 'RotateToTarget' );
  3903.                 }
  3904.                 MovAdjRotateToTarget( ticket );
  3905.                 // update rotationRate
  3906.                 if ((int)rotationRate > 0)
  3907.                 {
  3908.                     movementAdjustor.MaxRotationAdjustmentSpeed( ticket, (float)((int)rotationRate) );
  3909.                 }
  3910.             }
  3911.             else if ( animEventType == AET_DurationEnd )
  3912.             {
  3913.                 // it will end if there's no event, but sometimes one event could end and be followed by another
  3914.                 // and we want to have that continuity kept, that's why we won't end request manually
  3915.             }
  3916.             else
  3917.             {
  3918.                 // continuous update (makes more sense when there is no target and we want to rotate towards camera)
  3919.                 ticket = movementAdjustor.GetRequest( 'RotateToTarget' );
  3920.                 MovAdjRotateToTarget( ticket );
  3921.             }
  3922.         }
  3923.         super.OnEnumAnimEvent(animEventName, variant, animEventType, animEventDuration, animInfo);
  3924.     }
  3925.        
  3926.     event OnTeleported()
  3927.     {
  3928.         if( substateManager )
  3929.         {
  3930.             substateManager.OnTeleported();
  3931.         }
  3932.     }
  3933.    
  3934.     /*public function CaptureSafePosition()
  3935.     {
  3936.         lastSafePosition    = GetWorldPosition();
  3937.         lastSafeRotation    = GetWorldRotation();
  3938.         safePositionStored  = true;
  3939.     }*/
  3940.  
  3941.     ///////////////////////////////////////////////////////////////////////////
  3942.     // FISTFIGHT
  3943.     ///////////////////////////////////////////////////////////////////////////
  3944.     event OnStartFistfightMinigame()
  3945.     {
  3946.         super.OnStartFistfightMinigame();
  3947.        
  3948.         //Goto state CombatFist    
  3949.         SetFistFightMinigameEnabled( true );
  3950.         // W3EE - Begin
  3951.         //FistFightHealthChange( true );
  3952.         SetHealthPerc(100);
  3953.         // W3EE - End
  3954.         thePlayer.GetPlayerMode().ForceCombatMode( FCMR_QuestFunction );
  3955.         SetImmortalityMode(AIM_Unconscious, AIC_Fistfight);
  3956.         thePlayer.SetBehaviorVariable( 'playerWeaponLatent', (int)PW_Fists );
  3957.         GotoCombatStateWithAction( IA_None );
  3958.         ((CMovingAgentComponent)this.GetMovingAgentComponent()).SnapToNavigableSpace( true );
  3959.         EquipGeraltFistfightWeapon( true );
  3960.         BlockAction( EIAB_RadialMenu,   'FistfightMinigame' ,,true);
  3961.         BlockAction( EIAB_Signs,        'FistfightMinigame' ,,true);
  3962.         BlockAction( EIAB_ThrowBomb,    'FistfightMinigame' ,,true);
  3963.         BlockAction( EIAB_UsableItem,   'FistfightMinigame' ,,true);
  3964.         BlockAction( EIAB_Crossbow,     'FistfightMinigame' ,,true);
  3965.         BlockAction( EIAB_DrawWeapon,   'FistfightMinigame' ,,true);
  3966.         BlockAction( EIAB_RunAndSprint, 'FistfightMinigame' ,,true);
  3967.         BlockAction( EIAB_SwordAttack,  'FistfightMinigame' ,,true);
  3968.         BlockAction( EIAB_CallHorse,    'FistfightMinigame' ,,true);
  3969.         BlockAction( EIAB_Roll,         'FistfightMinigame' ,,true);
  3970.         BlockAction( EIAB_Interactions, 'FistfightMinigame' ,,true);
  3971.         BlockAction( EIAB_Explorations, 'FistfightMinigame' ,,true);
  3972.         BlockAction( EIAB_OpenInventory, 'FistfightMinigame' ,,true);
  3973.         BlockAction( EIAB_QuickSlots,    'FistfightMinigame' ,,true);
  3974.         BlockAction( EIAB_OpenCharacterPanel, 'FistfightMinigame' ,,true);
  3975.     }
  3976.    
  3977.     event OnEndFistfightMinigame()
  3978.     {
  3979.         ((CMovingAgentComponent)this.GetMovingAgentComponent()).SnapToNavigableSpace( false );
  3980.         // W3EE - Begin
  3981.         //FistFightHealthChange( false );
  3982.         SetHealthPerc(100);
  3983.         // W3EE - End
  3984.         thePlayer.GetPlayerMode().ReleaseForceCombatMode( FCMR_QuestFunction );
  3985.         EquipGeraltFistfightWeapon( false );
  3986.         SetFistFightMinigameEnabled( false );
  3987.         SetImmortalityMode(AIM_None, AIC_Fistfight);
  3988.         BlockAllActions('FistfightMinigame',false);
  3989.        
  3990.         super.OnEndFistfightMinigame();
  3991.     }
  3992.    
  3993.     public function GetFistFightFinisher( out masterAnimName, slaveAnimIndex : name )
  3994.     {
  3995.         var index : int;
  3996.    
  3997.         index = RandRange(1);
  3998.         switch ( index )
  3999.         {
  4000.             case 0 : masterAnimName = 'man_fistfight_finisher_1_win'; slaveAnimIndex = 'man_fistfight_finisher_1_looser';
  4001.         }
  4002.     }
  4003.    
  4004.     public function SetFistFightMinigameEnabled( flag : bool )
  4005.     {
  4006.         fistFightMinigameEnabled = flag;
  4007.     }
  4008.    
  4009.     public function SetFistFightParams( toDeath : bool, endsWithBS : bool )
  4010.     {
  4011.         isFFMinigameToTheDeath = toDeath;
  4012.         FFMinigameEndsithBS = endsWithBS;
  4013.     }
  4014.    
  4015.     public function IsFistFightMinigameEnabled() : bool
  4016.     {
  4017.         return fistFightMinigameEnabled;
  4018.     }
  4019.  
  4020.     public function IsFistFightMinigameToTheDeath() : bool
  4021.     {
  4022.         return isFFMinigameToTheDeath;
  4023.     }
  4024.  
  4025.     public function FistFightHealthChange( val : bool )
  4026.     {
  4027.         if( val == true )
  4028.         {
  4029.             GeraltMaxHealth = thePlayer.GetStatMax(BCS_Vitality);
  4030.             ClampGeraltMaxHealth( 2000 );
  4031.             SetHealthPerc( 100 );
  4032.         }
  4033.         else
  4034.         {
  4035.             ClampGeraltMaxHealth( GeraltMaxHealth );
  4036.             SetHealthPerc( 100 );
  4037.         }
  4038.        
  4039.     }
  4040.    
  4041.     function ClampGeraltMaxHealth( val : float )
  4042.     {
  4043.         thePlayer.abilityManager.SetStatPointMax( BCS_Vitality, val );
  4044.     }
  4045.    
  4046.     function EquipGeraltFistfightWeapon( val : bool )
  4047.     {
  4048.         if ( val )
  4049.         {
  4050.             fistsItems = thePlayer.GetInventory().AddAnItem( 'Geralt Fistfight Fists', 1, true, true );
  4051.             thePlayer.GetInventory().MountItem( fistsItems[0] , true );
  4052.         }
  4053.         else
  4054.         {
  4055.             thePlayer.GetInventory().DropItem( fistsItems[0], true );
  4056.         }
  4057.     }
  4058.  
  4059.     ///////////////////////////////////////////////////////////////////////////
  4060.     // GWINT
  4061.     ///////////////////////////////////////////////////////////////////////////
  4062.     public function GetGwintAiDifficulty() : EGwintDifficultyMode
  4063.     {
  4064.         return gwintAiDifficulty;
  4065.     }
  4066.  
  4067.     public function SetGwintAiDifficulty( difficulty : EGwintDifficultyMode )
  4068.     {
  4069.         gwintAiDifficulty = difficulty;
  4070.     }
  4071.  
  4072.     public function GetGwintAiAggression() : EGwintAggressionMode
  4073.     {
  4074.         return gwintAiAggression;
  4075.     }
  4076.  
  4077.     public function SetGwintAiAggression( aggression : EGwintAggressionMode )
  4078.     {
  4079.         gwintAiAggression = aggression;
  4080.     }
  4081.  
  4082.     public function GetGwintMinigameState() : EMinigameState   
  4083.     {
  4084.         return gwintMinigameState;
  4085.     }
  4086.    
  4087.     public function SetGwintMinigameState( minigameState : EMinigameState )
  4088.     {
  4089.         gwintMinigameState = minigameState;
  4090.     }
  4091.    
  4092.     public function OnGwintGameRequested( deckName : name, forceFaction : eGwintFaction )
  4093.     {
  4094.         var gwintManager:CR4GwintManager;
  4095.         gwintManager = theGame.GetGwintManager();
  4096.        
  4097.         gwintMinigameState = EMS_None;
  4098.        
  4099.         gwintManager.SetEnemyDeckByName(deckName);
  4100.         gwintManager.SetForcedFaction(forceFaction);
  4101.        
  4102.         if (gwintManager.GetHasDoneTutorial() || !theGame.GetTutorialSystem().AreMessagesEnabled())
  4103.         {
  4104.             gwintManager.gameRequested = true;
  4105.             theGame.RequestMenu( 'DeckBuilder' );
  4106.         }
  4107.         else
  4108.         {
  4109.             theGame.GetGuiManager().ShowUserDialog( UMID_SkipGwintTutorial, "gwint_tutorial_play_query_title", "gwint_tutorial_play_query", UDB_YesNo );
  4110.         }
  4111.     }
  4112.    
  4113.     public function StartGwint_TutorialOrSkip( skipTutorial : bool )
  4114.     {
  4115.         var gwintManager : CR4GwintManager;
  4116.        
  4117.         if( skipTutorial )
  4118.         {
  4119.             gwintManager = theGame.GetGwintManager();
  4120.             gwintManager.gameRequested = true;
  4121.             gwintManager.SetHasDoneTutorial(true);
  4122.             gwintManager.SetHasDoneDeckTutorial(true);
  4123.             theGame.RequestMenu( 'DeckBuilder' );
  4124.         }
  4125.         else
  4126.         {
  4127.             theGame.RequestMenu( 'GwintGame' );
  4128.         }
  4129.     }
  4130.    
  4131.     private var gwintCardNumbersArray : array<int>;
  4132.    
  4133.     public function InitGwintCardNumbersArray( arr : array<int> )
  4134.     {
  4135.         gwintCardNumbersArray.Clear();
  4136.         gwintCardNumbersArray = arr;
  4137.     }
  4138.    
  4139.     public function GetCardNumbersArray() : array<int>
  4140.     {
  4141.         return gwintCardNumbersArray;
  4142.     }
  4143.     ///////////////////////////////////////////////////////////////////////////
  4144.     // COMBAT CAMERA
  4145.     ///////////////////////////////////////////////////////////////////////////
  4146.    
  4147.     protected var customCameraStack : array<SCustomCameraParams>;
  4148.    
  4149.     public function AddCustomCamToStack( customCameraParams : SCustomCameraParams ) : int
  4150.     {
  4151.         if( customCameraParams.useCustomCamera )
  4152.         {
  4153.             if ( customCameraParams.cameraParams.enums[0].enumType != 'ECustomCameraType' )
  4154.             {
  4155.                 LogChannel( 'CustomCamera', "ERROR: Selected enum is not a custom camera!!!" );
  4156.                 return -1;
  4157.             }
  4158.             else
  4159.             {          
  4160.                 customCameraStack.PushBack( customCameraParams );
  4161.                 return ( customCameraStack.Size() - 1 );
  4162.             }
  4163.         }
  4164.        
  4165.         return 0;
  4166.     }
  4167.    
  4168.     public function DisableCustomCamInStack( customCameraStackIndex : int )
  4169.     {
  4170.         if ( customCameraStackIndex != -1 )
  4171.             customCameraStack[customCameraStackIndex].useCustomCamera = false;
  4172.         else
  4173.             LogChannel( 'CustomCamera', "ERROR: Custom camera to disable does not exist!!!" );
  4174.     }
  4175.    
  4176.     event OnInteriorStateChanged( inInterior : bool )
  4177.     {
  4178.         interiorCamera = inInterior;
  4179.     }
  4180.    
  4181.     event OnModifyPlayerSpeed( flag : bool )
  4182.     {
  4183.         modifyPlayerSpeed = flag;
  4184.         SetBehaviorVariable( 'modifyPlayerSpeed', (float)modifyPlayerSpeed );
  4185.     }
  4186.        
  4187.     event OnGameCameraTick( out moveData : SCameraMovementData, dt : float )
  4188.     {
  4189.         var targetRotation  : EulerAngles;
  4190.         var dist : float;
  4191.        
  4192.         if( thePlayer.IsInCombat() )
  4193.         {
  4194.             dist = VecDistance2D( thePlayer.GetWorldPosition(), thePlayer.GetTarget().GetWorldPosition() );
  4195.             thePlayer.GetVisualDebug().AddText( 'dbg', dist, thePlayer.GetWorldPosition() + Vector( 0.f,0.f,2.f ), true, , Color( 0, 255, 0 ) );
  4196.         }
  4197.        
  4198.         if ( isStartingFistFightMinigame )
  4199.         {
  4200.             moveData.pivotRotationValue = fistFightTeleportNode.GetWorldRotation();
  4201.             isStartingFistFightMinigame = false;
  4202.         }
  4203.        
  4204.         // Specific substate
  4205.         if( substateManager.UpdateCameraIfNeeded( moveData, dt ) )
  4206.         {
  4207.             return true;
  4208.         }
  4209.        
  4210.         // focusMode camera
  4211.         if ( theGame.IsFocusModeActive() )
  4212.         {
  4213.             theGame.GetGameCamera().ChangePivotRotationController( 'Exploration' );
  4214.             theGame.GetGameCamera().ChangePivotDistanceController( 'Default' );
  4215.             theGame.GetGameCamera().ChangePivotPositionController( 'Default' );
  4216.        
  4217.             // HACK
  4218.             moveData.pivotRotationController = theGame.GetGameCamera().GetActivePivotRotationController();
  4219.             moveData.pivotDistanceController = theGame.GetGameCamera().GetActivePivotDistanceController();
  4220.             moveData.pivotPositionController = theGame.GetGameCamera().GetActivePivotPositionController();
  4221.             // END HACK    
  4222.        
  4223.        
  4224.             moveData.pivotPositionController.SetDesiredPosition( thePlayer.GetWorldPosition() );
  4225.  
  4226.             moveData.pivotRotationController.SetDesiredPitch( -10.0f );
  4227.             moveData.pivotRotationController.maxPitch = 50.0;
  4228.  
  4229.             moveData.pivotDistanceController.SetDesiredDistance( 3.5f );
  4230.  
  4231.             if ( !interiorCamera )
  4232.             {
  4233.                 moveData.pivotPositionController.offsetZ = 1.5f;
  4234.                 DampVectorSpring( moveData.cameraLocalSpaceOffset, moveData.cameraLocalSpaceOffsetVel, Vector( 0.5f, 2.0f, 0.3f ), 0.20f, dt );
  4235.             }
  4236.             else
  4237.             {
  4238.                 moveData.pivotPositionController.offsetZ = 1.3f;
  4239.                 DampVectorSpring( moveData.cameraLocalSpaceOffset, moveData.cameraLocalSpaceOffsetVel, Vector( 0.5f, 2.3f, 0.5f ), 0.3f, dt );
  4240.             }
  4241.            
  4242.             return true;
  4243.         }
  4244.        
  4245.        
  4246.        
  4247.         // HACK: Target heading ( Made for ladder )
  4248.         if( substateManager.m_SharedDataO.IsForceHeading( targetRotation ) )
  4249.         {
  4250.             moveData.pivotRotationController.SetDesiredHeading( targetRotation.Yaw );
  4251.             moveData.pivotRotationController.SetDesiredPitch( targetRotation.Pitch );
  4252.             moveData.pivotRotationValue.Yaw     = LerpAngleF( 2.1f * dt, moveData.pivotRotationValue.Yaw, targetRotation.Yaw );
  4253.             moveData.pivotRotationValue.Pitch   = LerpAngleF( 1.0f * dt, moveData.pivotRotationValue.Pitch, targetRotation.Pitch );
  4254.             //return true;
  4255.         }
  4256.        
  4257.        
  4258.         if( customCameraStack.Size() > 0 )
  4259.         {
  4260.             // HANDLE CUSTOM CAMERAS HERE
  4261.             // IF HANDLED - RETURN TRUE
  4262.         }
  4263.        
  4264.         return false;
  4265.     }
  4266.    
  4267.     private var questCameraRequest : SQuestCameraRequest;
  4268.     private var cameraRequestTimeStamp : float;
  4269.    
  4270.     public function RequestQuestCamera( camera : SQuestCameraRequest )
  4271.     {
  4272.         questCameraRequest = camera;
  4273.         questCameraRequest.requestTimeStamp = theGame.GetEngineTimeAsSeconds();
  4274.     }
  4275.    
  4276.     public function ResetQuestCameraRequest()
  4277.     {
  4278.         var cameraRequest : SQuestCameraRequest;
  4279.        
  4280.         questCameraRequest = cameraRequest;
  4281.     }
  4282.    
  4283.     event OnGameCameraPostTick( out moveData : SCameraMovementData, dt : float )
  4284.     {
  4285.         var ent : CEntity;
  4286.         var playerPos : Vector;
  4287.         var angles : EulerAngles;
  4288.        
  4289.         var distance : float;
  4290.        
  4291.         /*if( thePlayer.IsInCombat() )
  4292.         {
  4293.             distance = VecDistance2D( thePlayer.GetWorldPosition(), thePlayer.GetTarget().GetWorldPosition() );
  4294.         }
  4295.        
  4296.         thePlayer.GetVisualDebug().AddText( 'Distance', "Distance form target: " + distance, thePlayer.GetWorldPosition() + Vector( 0.f,0.f,2.f ), true, , Color( 0, 255, 0 ) );
  4297.         */
  4298.        
  4299.         if ( questCameraRequest.requestTimeStamp > 0 )
  4300.         {
  4301.             if ( questCameraRequest.duration > 0 && questCameraRequest.requestTimeStamp + questCameraRequest.duration < theGame.GetEngineTimeAsSeconds() )
  4302.             {
  4303.                 ResetQuestCameraRequest();
  4304.                 return false;
  4305.             }
  4306.                
  4307.             if( questCameraRequest.lookAtTag )
  4308.             {
  4309.                 ent = theGame.GetEntityByTag( questCameraRequest.lookAtTag );
  4310.                 playerPos = GetWorldPosition();
  4311.                 playerPos.Z += 1.8f;
  4312.                
  4313.                 angles = VecToRotation( ent.GetWorldPosition() - playerPos );
  4314.                
  4315.                 moveData.pivotRotationController.SetDesiredHeading( angles.Yaw );
  4316.                 moveData.pivotRotationController.SetDesiredPitch( -angles.Pitch );
  4317.             }
  4318.             else
  4319.             {
  4320.                 if( questCameraRequest.requestYaw )
  4321.                 {
  4322.                     angles = GetWorldRotation();
  4323.                     moveData.pivotRotationController.SetDesiredHeading( angles.Yaw + questCameraRequest.yaw );
  4324.                 }
  4325.                
  4326.                 if( questCameraRequest.requestPitch )
  4327.                 {
  4328.                     moveData.pivotRotationController.SetDesiredPitch( questCameraRequest.pitch );
  4329.                 }
  4330.             }
  4331.         }
  4332.     }
  4333.    
  4334.     var wasRunning : bool;
  4335.     var vel : float;
  4336.     var smoothTime  : float;
  4337.    
  4338.     var constDamper : ConstDamper;
  4339.     var rotMultVel  : float;
  4340.    
  4341.     public function UpdateCameraInterior( out moveData : SCameraMovementData, timeDelta : float )
  4342.     {  
  4343.         var camDist     : float;
  4344.         var camOffset   : float;
  4345.         var rotMultDest : float;
  4346.         var rotMult : float;
  4347.         var angles      : EulerAngles;
  4348.            
  4349.         theGame.GetGameCamera().ChangePivotRotationController( 'ExplorationInterior' );
  4350.         theGame.GetGameCamera().ChangePivotDistanceController( 'Default' );
  4351.         theGame.GetGameCamera().ChangePivotPositionController( 'Default' );
  4352.    
  4353.         // HACK
  4354.         moveData.pivotRotationController = theGame.GetGameCamera().GetActivePivotRotationController();
  4355.         moveData.pivotDistanceController = theGame.GetGameCamera().GetActivePivotDistanceController();
  4356.         moveData.pivotPositionController = theGame.GetGameCamera().GetActivePivotPositionController();
  4357.         // END HACK
  4358.  
  4359.         moveData.pivotPositionController.SetDesiredPosition( GetWorldPosition(), 15.f );
  4360.  
  4361.         if ( !constDamper )
  4362.         {
  4363.             constDamper = new ConstDamper in this;
  4364.             constDamper.SetDamp( 0.35f );
  4365.         }      
  4366.        
  4367.         if ( rawPlayerSpeed <= 0 || AbsF( AngleDistance( rawPlayerHeading, GetHeading() ) ) > 135 )
  4368.             constDamper.Reset();
  4369.         else if ( theGame.IsUberMovementEnabled() )
  4370.             rotMult = 0.5f;
  4371.         else
  4372.             rotMult = 1.f;
  4373.  
  4374.         rotMult = constDamper.UpdateAndGet( timeDelta, rotMult );
  4375.        
  4376.         //DampFloatSpring( rotMult, rotMultVel, rotMultDest, 4.f, timeDelta );
  4377.        
  4378.         if ( AbsF( AngleDistance( GetHeading(), moveData.pivotRotationValue.Yaw ) ) < 135.f && rawPlayerSpeed > 0 )
  4379.             moveData.pivotRotationController.SetDesiredHeading( GetHeading(), rotMult );
  4380.         else
  4381.             moveData.pivotRotationController.SetDesiredHeading( moveData.pivotRotationValue.Yaw );
  4382.        
  4383.         moveData.pivotDistanceController.SetDesiredDistance( 1.5f );
  4384.        
  4385.         angles = VecToRotation( GetMovingAgentComponent().GetVelocity() );     
  4386.         if ( AbsF( angles.Pitch ) < 8.f || bLAxisReleased )
  4387.             moveData.pivotRotationController.SetDesiredPitch( -10.f );
  4388.         else
  4389.             moveData.pivotRotationController.SetDesiredPitch( -angles.Pitch - 18.f );  
  4390.        
  4391.         if ( IsGuarded() )
  4392.             moveData.pivotPositionController.offsetZ = 1.0f;
  4393.         else
  4394.             moveData.pivotPositionController.offsetZ = 1.3f;
  4395.        
  4396.         //if ( movementLockType == PMLT_NoSprint  )
  4397.         //{        
  4398.             if ( playerMoveType >= PMT_Run )
  4399.             {      
  4400.                 //camDist = 0.3f;
  4401.                 camDist = -0.5f;
  4402.                 camOffset = 0.25;
  4403.                
  4404.                 if ( !wasRunning )
  4405.                 {
  4406.                     smoothTime = 1.f;
  4407.                     wasRunning = true;
  4408.                 }              
  4409.                 DampFloatSpring( smoothTime, vel, 0.1, 0.5, timeDelta );
  4410.             }
  4411.             else
  4412.             {
  4413.                 //camDist = -0.6f;
  4414.                 camDist = 0.f;         
  4415.                 camOffset = 0.4f;
  4416.                 smoothTime = 0.2f;
  4417.                 wasRunning = false;
  4418.             }
  4419.            
  4420.             //camDist = theGame.GetGameplayConfigFloatValue( 'debugA' );
  4421.  
  4422.             DampVectorSpring( moveData.cameraLocalSpaceOffset, moveData.cameraLocalSpaceOffsetVel, Vector( 0.3f, camDist, 0.3f ), smoothTime, timeDelta ); 
  4423.             //DampVectorSpring( moveData.cameraLocalSpaceOffset, moveData.cameraLocalSpaceOffsetVel, Vector( 0.5, camDist, camOffset ), smoothTime, timeDelta );
  4424.         //}
  4425.         //else
  4426.         //  DampVectorSpring( moveData.cameraLocalSpaceOffset, moveData.cameraLocalSpaceOffsetVel, Vector( theGame.GetGameplayConfigFloatValue( 'debugA' ),theGame.GetGameplayConfigFloatValue( 'debugB' ),theGame.GetGameplayConfigFloatValue( 'debugC' ) ), 0.4f, timeDelta );
  4427.             //DampVectorSpring( moveData.cameraLocalSpaceOffset, moveData.cameraLocalSpaceOffsetVel, Vector( 0.7f, 0.f, 0.3 ), 0.4f, timeDelta );  
  4428.     }
  4429.    
  4430.    
  4431.     var wasBRAxisPushed                     : bool;
  4432.     protected function UpdateCameraChanneledSign( out moveData : SCameraMovementData, timeDelta : float ) : bool
  4433.     {  
  4434.         var screenSpaceOffset   : float;
  4435.         var screenSpaceOffsetFwd : float;
  4436.         var screenSpaceOffsetUp : float;
  4437.         var heading             : float;
  4438.         var pitch               : float;
  4439.         var playerToTargetRot   : EulerAngles;
  4440.         var rightOffset         : float = -20.f;
  4441.         var leftOffset          : float = 15.f;
  4442.         var angles              : EulerAngles;
  4443.        
  4444.         var vec                 : Vector;
  4445.        
  4446.         if( this.IsCurrentSignChanneled() && this.GetCurrentlyCastSign() != ST_Quen && this.GetCurrentlyCastSign() != ST_Yrden )
  4447.         {
  4448.             theGame.GetGameCamera().ChangePivotRotationController( 'SignChannel' );
  4449.             theGame.GetGameCamera().ChangePivotDistanceController( 'SignChannel' );
  4450.             // HACK
  4451.             moveData.pivotRotationController = theGame.GetGameCamera().GetActivePivotRotationController();
  4452.             moveData.pivotDistanceController = theGame.GetGameCamera().GetActivePivotDistanceController();
  4453.             // END HACK
  4454.  
  4455.             if ( GetCurrentlyCastSign() == ST_Axii )
  4456.                 leftOffset = 32.f;
  4457.  
  4458.             if ( oTCameraOffset != leftOffset && oTCameraOffset != rightOffset  )
  4459.             {
  4460.                 if( ( interiorCamera && !moveTarget )
  4461.                     || ( AngleDistance( GetHeading(), moveData.pivotRotationValue.Yaw ) < 0 ) )
  4462.                     oTCameraOffset = leftOffset;               
  4463.                 else
  4464.                     oTCameraOffset = rightOffset;
  4465.             }
  4466.            
  4467.             if ( oTCameraOffset == leftOffset )
  4468.             {
  4469.                 screenSpaceOffset = 0.65f;
  4470.                 oTCameraPitchOffset = 13.f;
  4471.                 //moveData.pivotDistanceController.SetDesiredDistance( 0.5f, 3.f );
  4472.             }
  4473.             else if ( oTCameraOffset == rightOffset )
  4474.             {
  4475.                 screenSpaceOffset = -0.65f;
  4476.                 oTCameraPitchOffset = 13.f;
  4477.                 //moveData.pivotDistanceController.SetDesiredDistance( 0.5f, 3.f );
  4478.             }
  4479.        
  4480.             moveData.pivotPositionController.offsetZ = 1.3f;
  4481.            
  4482.             if ( !delayCameraOrientationChange )
  4483.             {
  4484.                 if ( GetOrientationTarget() == OT_Camera || GetOrientationTarget() == OT_CameraOffset )
  4485.                 {
  4486.                     if ( bRAxisReleased )
  4487.                     {
  4488.                         heading = moveData.pivotRotationValue.Yaw;
  4489.                         pitch = moveData.pivotRotationValue.Pitch;
  4490.                     }
  4491.                     else
  4492.                     {
  4493.                         heading = moveData.pivotRotationValue.Yaw + oTCameraOffset;
  4494.                         pitch = moveData.pivotRotationValue.Pitch; //+ oTCameraPitchOffset;
  4495.                     }
  4496.                 }
  4497.                 else if ( GetOrientationTarget() == OT_Actor )
  4498.                 {
  4499.                     if ( GetDisplayTarget() )
  4500.                         vec = GetDisplayTarget().GetWorldPosition() - GetWorldPosition();
  4501.                     else if ( slideTarget )
  4502.                         vec = slideTarget.GetWorldPosition() - GetWorldPosition();
  4503.                     else if ( GetTarget() )
  4504.                         vec = GetTarget().GetWorldPosition() - GetWorldPosition();
  4505.                     else
  4506.                         vec = GetHeadingVector();
  4507.                        
  4508.                     angles = VecToRotation( vec );
  4509.                     heading = angles.Yaw + oTCameraOffset;
  4510.                     pitch = -angles.Pitch - oTCameraPitchOffset;//-angles.Pitch;               
  4511.                 }
  4512.                 else
  4513.                 {
  4514.                     angles = VecToRotation( GetHeadingVector() );
  4515.                     heading = angles.Yaw + oTCameraOffset;
  4516.                     pitch = -angles.Pitch - oTCameraPitchOffset;//-angles.Pitch;               
  4517.                 }
  4518.            
  4519.                 if ( !wasBRAxisPushed && ( !bRAxisReleased ) )//|| !lastAxisInputIsMovement ) )
  4520.                     wasBRAxisPushed = true;
  4521.  
  4522.                 moveData.pivotRotationController.SetDesiredHeading( heading , 2.f );
  4523.                 moveData.pivotRotationController.SetDesiredPitch( pitch );
  4524.             }
  4525.             else
  4526.             {
  4527.                 moveData.pivotRotationController.SetDesiredHeading( moveData.pivotRotationValue.Yaw, 1.f );
  4528.                 moveData.pivotRotationController.SetDesiredPitch( -oTCameraPitchOffset );
  4529.             }
  4530.            
  4531.             if ( moveData.pivotRotationValue.Pitch <= 5.f && moveData.pivotRotationValue.Pitch >= -15.f )
  4532.             {
  4533.                 screenSpaceOffsetFwd = 1.8;
  4534.                 screenSpaceOffsetUp = 0.4;
  4535.             }
  4536.             else if ( moveData.pivotRotationValue.Pitch > 0 )
  4537.             {
  4538.                 screenSpaceOffsetFwd = moveData.pivotRotationValue.Pitch*0.00727 + 1.275f;
  4539.                 screenSpaceOffsetFwd = ClampF( screenSpaceOffsetFwd, 1.5, 2.2 );
  4540.                
  4541.                 screenSpaceOffsetUp = -moveData.pivotRotationValue.Pitch*0.00727 + 0.4363f;
  4542.                 screenSpaceOffsetUp = ClampF( screenSpaceOffsetUp, 0, 0.3 );       
  4543.             }
  4544.             else   
  4545.             {
  4546.                 if ( GetCurrentlyCastSign() == ST_Axii )
  4547.                 {
  4548.                     screenSpaceOffsetFwd = -moveData.pivotRotationValue.Pitch*0.0425 + 0.8625f;    
  4549.                     screenSpaceOffsetFwd = ClampF( screenSpaceOffsetFwd, 1.5, 2.3 );
  4550.                 }
  4551.                 else
  4552.                 {
  4553.                     screenSpaceOffsetFwd = -moveData.pivotRotationValue.Pitch*0.035 + 0.75f;
  4554.                     screenSpaceOffsetFwd = ClampF( screenSpaceOffsetFwd, 1.5, 2.6 );
  4555.                 }
  4556.                 screenSpaceOffsetUp = -moveData.pivotRotationValue.Pitch*0.005 + 0.325f;
  4557.                 screenSpaceOffsetUp = ClampF( screenSpaceOffsetUp, 0.4, 0.5 );             
  4558.             }
  4559.                
  4560.             DampVectorSpring( moveData.cameraLocalSpaceOffset, moveData.cameraLocalSpaceOffsetVel, Vector( screenSpaceOffset, screenSpaceOffsetFwd, screenSpaceOffsetUp ), 0.25f, timeDelta );//1.5,0.4    
  4561.             moveData.pivotDistanceController.SetDesiredDistance( 2.8f, 5.f );  
  4562.             moveData.pivotPositionController.SetDesiredPosition( GetWorldPosition() );     
  4563.        
  4564.             return true;
  4565.         }
  4566.         else
  4567.         {
  4568.             this.wasBRAxisPushed = false;
  4569.            
  4570.             return false;
  4571.         }
  4572.     }  
  4573.  
  4574.     protected function UpdateCameraForSpecialAttack( out moveData : SCameraMovementData, timeDelta : float ) : bool
  4575.     {  
  4576.         var screenSpaceOffset   : float;
  4577.         var tempHeading         : float;
  4578.         var cameraOffsetLeft    : float;
  4579.         var cameraOffsetRight   : float;
  4580.        
  4581.         if ( !specialAttackCamera )
  4582.             return false;
  4583.                
  4584.         theGame.GetGameCamera().ForceManualControlHorTimeout();
  4585.         theGame.GetGameCamera().ForceManualControlVerTimeout();
  4586.         //if ( parent.delayCameraOrientationChange || parent.delayOrientationChange )
  4587.         //{
  4588.             cameraOffsetLeft = 30.f;
  4589.             cameraOffsetRight = -30.f;
  4590.         //}
  4591.         //else
  4592.         //{
  4593.         //  cameraOffsetLeft = 2.f;
  4594.         //  cameraOffsetRight = -2.f;
  4595.         //}
  4596.        
  4597.         theGame.GetGameCamera().ChangePivotRotationController( 'SignChannel' );
  4598.         theGame.GetGameCamera().ChangePivotDistanceController( 'SignChannel' );
  4599.         // HACK
  4600.         moveData.pivotRotationController = theGame.GetGameCamera().GetActivePivotRotationController();
  4601.         moveData.pivotDistanceController = theGame.GetGameCamera().GetActivePivotDistanceController();
  4602.  
  4603.         if ( slideTarget )
  4604.             tempHeading = VecHeading( slideTarget.GetWorldPosition() - GetWorldPosition() );
  4605.         else
  4606.             tempHeading = GetHeading();
  4607.            
  4608.         oTCameraPitchOffset = 0.f;     
  4609.            
  4610.         if( ( interiorCamera && !moveTarget )
  4611.             || ( AngleDistance( tempHeading, moveData.pivotRotationValue.Yaw ) < 0 ) )
  4612.             oTCameraOffset = cameraOffsetLeft;             
  4613.         else
  4614.             oTCameraOffset = cameraOffsetRight;
  4615.        
  4616.         if ( oTCameraOffset == cameraOffsetLeft )
  4617.         {
  4618.             if ( delayCameraOrientationChange || delayOrientationChange )
  4619.             {
  4620.                 screenSpaceOffset = 0.75f;
  4621.                 moveData.pivotDistanceController.SetDesiredDistance( 1.6f, 3.f );
  4622.                 moveData.pivotPositionController.offsetZ = 1.4f;
  4623.                 moveData.pivotRotationController.SetDesiredPitch( -15.f );
  4624.             }
  4625.             else
  4626.             {
  4627.                 screenSpaceOffset = 0.7f;
  4628.                 moveData.pivotDistanceController.SetDesiredDistance( 3.25f );
  4629.                 moveData.pivotPositionController.offsetZ = 1.2f;
  4630.                 moveData.pivotRotationController.SetDesiredPitch( -10.f );         
  4631.             }
  4632.         }
  4633.         else if ( oTCameraOffset == cameraOffsetRight )
  4634.         {
  4635.             if ( delayCameraOrientationChange || delayOrientationChange )
  4636.             {
  4637.                 screenSpaceOffset = -0.85f;
  4638.                 moveData.pivotDistanceController.SetDesiredDistance( 1.6f, 3.f );
  4639.                 moveData.pivotPositionController.offsetZ = 1.4f;
  4640.                 moveData.pivotRotationController.SetDesiredPitch( -15.f );
  4641.             }
  4642.             else
  4643.             {
  4644.                 screenSpaceOffset = -0.8f;
  4645.                 moveData.pivotDistanceController.SetDesiredDistance( 3.25f );
  4646.                 moveData.pivotPositionController.offsetZ = 1.2f;
  4647.                 moveData.pivotRotationController.SetDesiredPitch( -10.f );         
  4648.             }      
  4649.         }
  4650.         else
  4651.         {
  4652.             moveData.pivotDistanceController.SetDesiredDistance( 1.25f, 3.f );
  4653.             moveData.pivotPositionController.offsetZ = 1.3f;
  4654.             moveData.pivotRotationController.SetDesiredPitch( -5.5f );         
  4655.         }
  4656.        
  4657.         DampVectorSpring( moveData.cameraLocalSpaceOffset, moveData.cameraLocalSpaceOffsetVel, Vector( screenSpaceOffset, 0.f, 0.f ), 1.f, timeDelta );
  4658.        
  4659.         if ( !delayCameraOrientationChange )
  4660.         {
  4661.             if ( moveTarget )
  4662.                 moveData.pivotRotationController.SetDesiredHeading( GetHeading() + oTCameraOffset, 0.5f );
  4663.             else
  4664.                 moveData.pivotRotationController.SetDesiredHeading( GetHeading() + oTCameraOffset, 1.f );
  4665.         }
  4666.         else
  4667.             moveData.pivotRotationController.SetDesiredHeading( moveData.pivotRotationValue.Yaw, 1.f );
  4668.        
  4669.         moveData.pivotPositionController.SetDesiredPosition( GetWorldPosition() );
  4670.        
  4671.         return true;
  4672.     }
  4673.  
  4674.  
  4675.     private var fovVel : float;
  4676.     private var sprintOffset : Vector;
  4677.     private var previousOffset : bool;
  4678.     private var previousRotationVelocity : float;
  4679.     private var pivotRotationTimeStamp  : float;
  4680.     protected function UpdateCameraSprint( out moveData : SCameraMovementData, timeDelta : float )
  4681.     {
  4682.         var angleDiff : float;
  4683.         var camOffsetVector : Vector;
  4684.         var smoothSpeed : float;
  4685.         var camera : CCustomCamera;
  4686.         var camAngularSpeed : float;
  4687.        
  4688.         var playerToCamAngle : float;
  4689.         var useExplorationSprintCam : bool;
  4690.        
  4691.         camera = theGame.GetGameCamera();
  4692.         if( camera )
  4693.         {
  4694.             if ( sprintingCamera )
  4695.             {
  4696.                 //theGame.GetGameCamera().ForceManualControlHorTimeout();
  4697.                 if( thePlayer.GetAutoCameraCenter() )
  4698.                 {
  4699.                     theGame.GetGameCamera().ForceManualControlVerTimeout();
  4700.                 }
  4701.                
  4702.                 playerToCamAngle =  AbsF( AngleDistance( GetHeading(), moveData.pivotRotationValue.Yaw ) );
  4703.                
  4704.                 /*if ( theGame.GetGameplayConfigFloatValue( 'debugE' ) > 0.1f )
  4705.                     useExplorationSprintCam = !IsInCombat() || ( moveTarget && VecDistance( moveTarget.GetWorldPosition(), GetWorldPosition() ) > findMoveTargetDistMax );
  4706.                 else*/
  4707.                     useExplorationSprintCam = false;// !IsInCombat() || ( moveTarget && VecDistance( moveTarget.GetWorldPosition(), GetWorldPosition() ) > findMoveTargetDistMax );
  4708.                
  4709.                 if ( useExplorationSprintCam )
  4710.                 {
  4711.                     if ( playerToCamAngle <= 45  )
  4712.                     {
  4713.                         theGame.GetGameCamera().ChangePivotRotationController( 'Sprint' );
  4714.                         // HACK
  4715.                         moveData.pivotRotationController = theGame.GetGameCamera().GetActivePivotRotationController(); 
  4716.  
  4717.                         moveData.pivotRotationController.SetDesiredHeading( GetHeading(), 0.25f );
  4718.                         moveData.pivotRotationController.SetDesiredPitch( -3.5f, 0.5f );
  4719.                         thePlayer.EnableManualCameraControl( true, 'Sprint' );         
  4720.                     }
  4721.                     else
  4722.                     {          
  4723.                         thePlayer.EnableManualCameraControl( false, 'Sprint' );
  4724.                     }
  4725.                 }
  4726.                 else
  4727.                 {
  4728.                     if ( theGame.IsUberMovementEnabled() )
  4729.                         moveData.pivotRotationController.SetDesiredHeading( GetHeading(), 0.35f );
  4730.  
  4731.                     thePlayer.EnableManualCameraControl( true, 'Sprint' );     
  4732.                 }
  4733.                
  4734.                 if ( bRAxisReleased )
  4735.                 {
  4736.                     if ( AbsF( rawLeftJoyRot ) > 25 )
  4737.                         angleDiff = AngleDistance( GetHeading(), moveData.pivotRotationValue.Yaw );
  4738.                    
  4739.                     pivotRotationTimeStamp = theGame.GetEngineTimeAsSeconds();
  4740.                     previousRotationVelocity = 0.f;
  4741.                 }
  4742.                 else
  4743.                 {
  4744.                     if ( previousRotationVelocity <= 0 && AbsF( moveData.pivotRotationVelocity.Yaw ) > 250 )
  4745.                     {
  4746.                         pivotRotationTimeStamp = theGame.GetEngineTimeAsSeconds();
  4747.                         previousRotationVelocity = AbsF( moveData.pivotRotationVelocity.Yaw );
  4748.                     }
  4749.                 }
  4750.                
  4751.                 if ( pivotRotationTimeStamp + 0.4f <= theGame.GetEngineTimeAsSeconds() && AbsF( moveData.pivotRotationVelocity.Yaw ) > 250 )
  4752.                     angleDiff = VecHeading( rawRightJoyVec );
  4753.    
  4754.                 if ( useExplorationSprintCam )
  4755.                 {
  4756.                     if ( playerToCamAngle > 90 )
  4757.                     {
  4758.                         camOffsetVector.X = 0.f;
  4759.                         smoothSpeed = 1.f;                     
  4760.                     }
  4761.                     else if ( angleDiff > 15.f )
  4762.                     {
  4763.                         camOffsetVector.X = -0.8;
  4764.                         smoothSpeed = 1.f;
  4765.                         previousOffset = true;
  4766.                     }
  4767.                     else if ( angleDiff < -15.f )
  4768.                     {
  4769.                         camOffsetVector.X = 0.475f;
  4770.                         smoothSpeed = 1.5f;
  4771.                         previousOffset = false;
  4772.                     }
  4773.                     else
  4774.                     {
  4775.                         if ( previousOffset )
  4776.                         {
  4777.                             camOffsetVector.X = -0.8;
  4778.                             smoothSpeed = 1.5f;
  4779.                         }
  4780.                         else
  4781.                         {
  4782.                             camOffsetVector.X = 0.475f;
  4783.                             smoothSpeed = 1.5f;                    
  4784.                         }
  4785.                     }
  4786.                
  4787.                     camOffsetVector.Y = 1.4f;
  4788.                     camOffsetVector.Z = 0.275f;
  4789.                 }
  4790.                 else
  4791.                 {  
  4792.                     /*camOffsetVector.X = 0.f;
  4793.                     camOffsetVector.Y = 0.4f;
  4794.                     camOffsetVector.Z = 0.2f;*/
  4795.                     smoothSpeed = 0.75f;
  4796.                    
  4797.                     camOffsetVector.X = 0.f;
  4798.                     camOffsetVector.Y = 1.f;
  4799.                     camOffsetVector.Z = 0.2f;
  4800.                     moveData.pivotRotationController.SetDesiredPitch( -10.f, 0.5f );
  4801.                 }
  4802.                
  4803.                 DampVectorConst( sprintOffset, camOffsetVector, smoothSpeed, timeDelta );
  4804.                
  4805.                 moveData.cameraLocalSpaceOffset = sprintOffset;
  4806.                
  4807.                 DampFloatSpring( camera.fov, fovVel, 70.f, 1.0, timeDelta );
  4808.             }
  4809.             else
  4810.             {
  4811.                 sprintOffset = moveData.cameraLocalSpaceOffset;
  4812.                 DampFloatSpring( camera.fov, fovVel, 60.f, 1.0, timeDelta );
  4813.                 previousOffset = false;
  4814.             }
  4815.         }
  4816.     }
  4817.    
  4818.     function EnableSprintingCamera( flag : bool )
  4819.     {  
  4820.         if( !theGame.IsUberMovementEnabled() && !useSprintingCameraAnim )
  4821.         {
  4822.             return;
  4823.         }  
  4824.    
  4825.         super.EnableSprintingCamera( flag );
  4826.        
  4827.         if ( !flag )
  4828.         {
  4829.             thePlayer.EnableManualCameraControl( true, 'Sprint' );
  4830.         }
  4831.     }  
  4832.  
  4833.     protected function UpdateCameraCombatActionButNotInCombat( out moveData : SCameraMovementData, timeDelta : float )
  4834.     {  
  4835.         var vel         : Vector;
  4836.         var heading     : float;
  4837.         var pitch       : float;
  4838.         var headingMult : float;
  4839.         var pitchMult   : float;
  4840.         var camOffset   : Vector;
  4841.         var buff        : CBaseGameplayEffect;
  4842.         var runningAndAlertNear     : bool;
  4843.         var desiredDist             : float;
  4844.    
  4845.         if ( ( !IsCurrentSignChanneled() || GetCurrentlyCastSign() == ST_Quen || GetCurrentlyCastSign() == ST_Yrden ) && !specialAttackCamera && !IsInCombatActionFriendly() )
  4846.         {
  4847.             buff = GetCurrentlyAnimatedCS();
  4848.             runningAndAlertNear = GetPlayerCombatStance() == PCS_AlertNear && playerMoveType == PMT_Run && !GetDisplayTarget();
  4849.             if ( runningAndAlertNear ||
  4850.                 ( GetPlayerCombatStance() == PCS_AlertFar && !IsInCombatAction() && !buff ) )
  4851.             {
  4852.                 camOffset.X = 0.f;
  4853.                 camOffset.Y = 0.f;
  4854.                 camOffset.Z = -0.1f;
  4855.                
  4856.                 if ( runningAndAlertNear )
  4857.                 {
  4858.                     moveData.pivotDistanceController.SetDesiredDistance( 4.f );
  4859.                     moveData.pivotPositionController.offsetZ = 1.5f;
  4860.                 }
  4861.             }
  4862.             else
  4863.             {
  4864.                 camOffset.X = 0.f;
  4865.                 camOffset.Y = -1.5f;
  4866.                 camOffset.Z = -0.2f;
  4867.             }
  4868.                
  4869.             DampVectorSpring( moveData.cameraLocalSpaceOffset, moveData.cameraLocalSpaceOffsetVel, Vector( camOffset.X, camOffset.Y, camOffset.Z ), 0.4f, timeDelta );
  4870.             sprintOffset = moveData.cameraLocalSpaceOffset;
  4871.             heading = moveData.pivotRotationValue.Yaw;
  4872.            
  4873.             if ( GetOrientationTarget() == OT_Camera || GetOrientationTarget() == OT_CameraOffset )
  4874.                 pitch = moveData.pivotRotationValue.Pitch;
  4875.             else if ( lastAxisInputIsMovement
  4876.                     || GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Attack
  4877.                     || GetBehaviorVariable( 'combatActionType' ) == (int)CAT_SpecialAttack
  4878.                     || ( GetBehaviorVariable( 'combatActionType' ) == (int)CAT_CastSign && !IsCurrentSignChanneled() && GetCurrentlyCastSign() == ST_Quen ) )
  4879.             {
  4880.                 theGame.GetGameCamera().ForceManualControlVerTimeout();
  4881.                 pitch = -20.f;
  4882.             }
  4883.             else
  4884.                 pitch = moveData.pivotRotationValue.Pitch;
  4885.                
  4886.             headingMult = 1.f;
  4887.             pitchMult = 1.f;
  4888.        
  4889.             //if( GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Attack )
  4890.             if( GetBehaviorVariable( 'combatActionType' ) == (int)CAT_CastSign
  4891.                 && ( GetEquippedSign() == ST_Aard || GetEquippedSign() == ST_Yrden )
  4892.                 && GetBehaviorVariable( 'alternateSignCast' ) == 1 )
  4893.             {
  4894.                 //theGame.GetGameCamera().ForceManualControlHorTimeout();
  4895.                 theGame.GetGameCamera().ForceManualControlVerTimeout();        
  4896.                 pitch = -20.f;
  4897.                
  4898.                 //DampVectorSpring( moveData.cameraLocalSpaceOffset, moveData.cameraLocalSpaceOffsetVel, Vector( theGame.GetGameplayConfigFloatValue( 'debugA' ), theGame.GetGameplayConfigFloatValue( 'debugB' ), theGame.GetGameplayConfigFloatValue( 'debugC' ) ), 0.4f, timeDelta );
  4899.             }      
  4900.            
  4901.             //vel = GetMovingAgentComponent().GetVelocity();
  4902.             //if ( VecLength( vel ) > 0 && GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Dodge )
  4903.             //{
  4904.                 /*theGame.GetGameCamera().ForceManualControlHorTimeout();
  4905.                 heading = GetHeading();
  4906.                 headingMult = 0.5f;*/
  4907.             //}
  4908.            
  4909.             if ( IsCurrentSignChanneled() && GetCurrentlyCastSign() == ST_Quen )
  4910.             {
  4911.                 pitch = moveData.pivotRotationValue.Pitch;
  4912.             }
  4913.            
  4914.             moveData.pivotRotationController.SetDesiredHeading( heading, );
  4915.             moveData.pivotRotationController.SetDesiredPitch( pitch );
  4916.         }
  4917.     }
  4918.    
  4919.     /*public function UpdateCameraForSpecialAttack( out moveData : SCameraMovementData, timeDelta : float ) : bool
  4920.     {
  4921.         return false;
  4922.     }*/
  4923.     //------------------------------------------------------------------------------------------------------------------
  4924.     event OnGameCameraExplorationRotCtrlChange()
  4925.     {
  4926.         if( substateManager )
  4927.         {
  4928.             return substateManager.OnGameCameraExplorationRotCtrlChange( );
  4929.         }
  4930.        
  4931.         return false;
  4932.     }
  4933.    
  4934.     ///////////////////////////////////////////////////////////////////////////
  4935.     // COMBAT MOVEMENT ORIENTATION
  4936.     ///////////////////////////////////////////////////////////////////////////
  4937.  
  4938.     //Rotation
  4939.     function SetCustomRotation( customRotationName : name, rotHeading : float, rotSpeed : float, activeTime : float, rotateExistingDeltaLocation : bool )
  4940.     {
  4941.         var movementAdjustor    : CMovementAdjustor;
  4942.         var ticket              : SMovementAdjustmentRequestTicket;
  4943.    
  4944.         movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor();
  4945.         ticket = movementAdjustor.GetRequest( customRotationName );
  4946.         movementAdjustor.Cancel( ticket );
  4947.         ticket = movementAdjustor.CreateNewRequest( customRotationName );
  4948.         movementAdjustor.Continuous( ticket );
  4949.         movementAdjustor.ReplaceRotation( ticket );
  4950.         movementAdjustor.RotateTo( ticket, rotHeading );
  4951.         movementAdjustor.MaxRotationAdjustmentSpeed( ticket, rotSpeed );
  4952.         if (rotSpeed == 0.0f)
  4953.         {
  4954.             movementAdjustor.AdjustmentDuration( ticket, activeTime ); 
  4955.         }
  4956.         movementAdjustor.KeepActiveFor( ticket, activeTime );  
  4957.         movementAdjustor.RotateExistingDeltaLocation( ticket, rotateExistingDeltaLocation );
  4958.     }
  4959.    
  4960.     function UpdateCustomRotationHeading( customRotationName : name, rotHeading : float )
  4961.     {
  4962.         var movementAdjustor    : CMovementAdjustor;
  4963.         var ticket              : SMovementAdjustmentRequestTicket;
  4964.        
  4965.         movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor();
  4966.         ticket = movementAdjustor.GetRequest( customRotationName );
  4967.         movementAdjustor.RotateTo( ticket, rotHeading );
  4968.     }
  4969.    
  4970.     function SetCustomRotationTowards( customRotationName : name, target : CActor, rotSpeed : float, optional activeTime : float )
  4971.     {
  4972.         var movementAdjustor    : CMovementAdjustor;
  4973.         var ticket              : SMovementAdjustmentRequestTicket;
  4974.    
  4975.         movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor();
  4976.         ticket = movementAdjustor.GetRequest( customRotationName );
  4977.         movementAdjustor.Cancel( ticket );
  4978.         ticket = movementAdjustor.CreateNewRequest( customRotationName );
  4979.         movementAdjustor.Continuous( ticket );
  4980.         movementAdjustor.ReplaceRotation( ticket );
  4981.         movementAdjustor.RotateTowards( ticket, target );
  4982.         movementAdjustor.MaxRotationAdjustmentSpeed( ticket, rotSpeed );
  4983.         if (activeTime > 0.0f)
  4984.         {
  4985.             movementAdjustor.KeepActiveFor( ticket, activeTime );
  4986.         }
  4987.         else
  4988.         {
  4989.             movementAdjustor.DontEnd( ticket );
  4990.         }
  4991.     }
  4992.    
  4993.     //lock movement in dir
  4994.     function CustomLockMovement( customMovementName : name, heading : float )
  4995.     {
  4996.         var movementAdjustor    : CMovementAdjustor;
  4997.         var ticket              : SMovementAdjustmentRequestTicket;
  4998.    
  4999.         movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor();
  5000.         ticket = movementAdjustor.GetRequest( customMovementName );
  5001.         movementAdjustor.Cancel( ticket );
  5002.         ticket = movementAdjustor.CreateNewRequest( customMovementName );
  5003.         movementAdjustor.Continuous( ticket );
  5004.         movementAdjustor.DontEnd( ticket );
  5005.         movementAdjustor.LockMovementInDirection( ticket, heading );
  5006.     }
  5007.    
  5008.     function BindMovementAdjustmentToEvent( customRotationName : name, eventName : CName )
  5009.     {
  5010.         var movementAdjustor    : CMovementAdjustor;
  5011.         var ticket              : SMovementAdjustmentRequestTicket;
  5012.        
  5013.         movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor();
  5014.         ticket = movementAdjustor.GetRequest( customRotationName );
  5015.         movementAdjustor.BindToEvent( ticket, eventName );
  5016.     }
  5017.    
  5018.     function UpdateCustomLockMovementHeading( customMovementName : name, heading : float )
  5019.     {
  5020.         var movementAdjustor    : CMovementAdjustor;
  5021.         var ticket              : SMovementAdjustmentRequestTicket;
  5022.        
  5023.         movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor();
  5024.         ticket = movementAdjustor.GetRequest( customMovementName );
  5025.         movementAdjustor.LockMovementInDirection( ticket, heading );
  5026.     }  
  5027.    
  5028.     function CustomLockDistance( customMovementName : name, maintainDistanceTo : CNode, minDist, maxDist : float )
  5029.     {
  5030.         var movementAdjustor    : CMovementAdjustor;
  5031.         var ticket              : SMovementAdjustmentRequestTicket;
  5032.    
  5033.         movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor();
  5034.         ticket = movementAdjustor.GetRequest( customMovementName );
  5035.         movementAdjustor.Cancel( ticket );
  5036.         ticket = movementAdjustor.CreateNewRequest( customMovementName );
  5037.         movementAdjustor.Continuous( ticket ); 
  5038.         movementAdjustor.SlideTowards( ticket, maintainDistanceTo, minDist, maxDist ); 
  5039.     }
  5040.  
  5041.     function UpdateCustomLockDistance( customMovementName : name, maintainDistanceTo : CNode, minDist, maxDist : float  )
  5042.     {
  5043.         var movementAdjustor    : CMovementAdjustor;
  5044.         var ticket              : SMovementAdjustmentRequestTicket;
  5045.        
  5046.         movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor();
  5047.         ticket = movementAdjustor.GetRequest( customMovementName );
  5048.         movementAdjustor.SlideTowards( ticket, maintainDistanceTo, minDist, maxDist );
  5049.     }      
  5050.  
  5051.     private var disableManualCameraControlStack : array<name>;
  5052.     public function EnableManualCameraControl( enable : bool, sourceName : name )
  5053.     {
  5054.         if ( !enable )
  5055.         {
  5056.             if ( !disableManualCameraControlStack.Contains( sourceName ) )
  5057.             {
  5058.                 disableManualCameraControlStack.PushBack( sourceName );
  5059.             }
  5060.         }
  5061.         else
  5062.         {
  5063.             disableManualCameraControlStack.Remove( sourceName );
  5064.         }
  5065.        
  5066.         if ( disableManualCameraControlStack.Size() > 0 )
  5067.             theGame.GetGameCamera().EnableManualControl( false );
  5068.         else
  5069.             theGame.GetGameCamera().EnableManualControl( true );
  5070.     }
  5071.  
  5072.     public function IsCameraControlDisabled( optional disabledBySourceName : name ) : bool
  5073.     {
  5074.         if ( disabledBySourceName )
  5075.             return disableManualCameraControlStack.Contains( disabledBySourceName );
  5076.         else
  5077.             return disableManualCameraControlStack.Size() > 0; 
  5078.     }
  5079.  
  5080.     public function DisableManualCameraControlStackHasSource( sourceName : name ) : bool
  5081.     {
  5082.         return disableManualCameraControlStack.Contains( sourceName );
  5083.     }
  5084.  
  5085.     public function ClearDisableManualCameraControlStack()
  5086.     {
  5087.         disableManualCameraControlStack.Clear();
  5088.         theGame.GetGameCamera().EnableManualControl( true );
  5089.     }  
  5090.    
  5091.     //W3EE - Begin
  5092.     function SetOrientationTarget( target : EOrientationTarget )
  5093.     {
  5094.        
  5095.        
  5096.             if ( IsPCModeEnabled() && target == OT_Player )
  5097.             {
  5098.                 target = OT_Camera;
  5099.             }
  5100.            
  5101.             if ( !Options().LockOnMode() && !Options().LockOn() )
  5102.             {
  5103.                 orientationTarget = OT_CameraOffset;
  5104.             }
  5105.             else
  5106.             {
  5107.                 orientationTarget = target;
  5108.             }
  5109.     }
  5110.    
  5111.     function GetOrientationTarget() : EOrientationTarget
  5112.     {
  5113.        
  5114.        
  5115.             if ( !Options().LockOnMode() && !Options().LockOn() )
  5116.             {
  5117.                 return OT_CameraOffset;
  5118.             }
  5119.             else
  5120.             {
  5121.                 if( GetCombatAction() == EBAT_CastSign && theGame.GetInGameConfigWrapper().GetVarValue('EnhancedTargeting', 'ETSignsTowardsCamera') )
  5122.                     return OT_CameraOffset;
  5123.                 else
  5124.                     return orientationTarget;
  5125.             }
  5126.     }
  5127.     //W3EE - End
  5128.    
  5129.     var customOrientationInfoStack : array<SCustomOrientationInfo>;
  5130.     public function AddCustomOrientationTarget( orientationTarget : EOrientationTarget, sourceName : name )
  5131.     {
  5132.         var customOrientationInfo   : SCustomOrientationInfo;
  5133.         var i                       : int;
  5134.        
  5135.         if ( customOrientationInfoStack.Size() > 0 )
  5136.         {
  5137.             for( i = customOrientationInfoStack.Size()-1; i>=0; i-=1 )
  5138.             {
  5139.                 if ( customOrientationInfoStack[i].sourceName == sourceName )
  5140.                     customOrientationInfoStack.Erase(i);   
  5141.             }
  5142.         }
  5143.        
  5144.         customOrientationInfo.sourceName = sourceName;
  5145.         customOrientationInfo.orientationTarget = orientationTarget;
  5146.         customOrientationInfoStack.PushBack( customOrientationInfo );
  5147.         SetOrientationTarget( orientationTarget );
  5148.     }  
  5149.    
  5150.     public function RemoveCustomOrientationTarget( sourceName : name )
  5151.     {
  5152.         var customOrientationInfo   : SCustomOrientationInfo;
  5153.         var i                       : int;
  5154.        
  5155.         if ( customOrientationInfoStack.Size() > 0 )
  5156.         {
  5157.             for( i = customOrientationInfoStack.Size()-1; i>=0; i-=1 )
  5158.             {
  5159.                 if ( customOrientationInfoStack[i].sourceName == sourceName )
  5160.                     customOrientationInfoStack.Erase(i);   
  5161.             }
  5162.         }
  5163.         else
  5164.             LogChannel( 'CustomOrienatation', "ERROR: Custom orientation cannot be removed, stack is already empty!!!" );
  5165.     }
  5166.  
  5167.     // W3EE - Begin
  5168.     public function ClearCustomOrientationInfoStack()
  5169.     {
  5170.         customOrientationInfoStack.Clear();
  5171.     }
  5172.     // W3EE - End
  5173.    
  5174.     protected function GetCustomOrientationTarget( out infoStack : SCustomOrientationInfo ) : bool
  5175.     {
  5176.         var size : int;
  5177.        
  5178.         size = customOrientationInfoStack.Size();
  5179.        
  5180.         if ( size <= 0 )
  5181.             return false;
  5182.         else
  5183.         {
  5184.             infoStack = customOrientationInfoStack[ size - 1 ];
  5185.             return true;
  5186.         }
  5187.     }      
  5188.    
  5189.     //W3EE - Begin
  5190.     public function SetOrientationTargetCustomHeading( heading : float, sourceName : name  ) : bool
  5191.     {  
  5192.         var  i : int;
  5193.  
  5194.        
  5195.        
  5196.         if ( customOrientationInfoStack.Size() > 0 )
  5197.         {
  5198.             for( i = customOrientationInfoStack.Size()-1; i>=0; i-=1 )
  5199.             {
  5200.                 if ( customOrientationInfoStack[i].sourceName == sourceName )
  5201.                 {
  5202.                     if ( !Options().LockOnMode() && !Options().LockOn() )
  5203.                     {
  5204.                         customOrientationInfoStack[i].customHeading = VecHeading( theCamera.GetCameraDirection() ) - oTCameraOffset;
  5205.                     }
  5206.                     else
  5207.                     {
  5208.                         customOrientationInfoStack[i].customHeading = heading;
  5209.                     }
  5210.                     return true;
  5211.                 }
  5212.             }
  5213.         }
  5214.         LogChannel( 'SetOrientationTargetCustomHeading', "ERROR: Cannot set customHeading because stack is empty or sourceName is not found!!!" );
  5215.         return false;
  5216.     }
  5217.  
  5218.     // returns the topmost OT_CustomHeading in stack
  5219.     public function GetOrientationTargetCustomHeading() : float
  5220.     {
  5221.         var i : int;
  5222.  
  5223.        
  5224.        
  5225.         if ( customOrientationInfoStack.Size() > 0 )
  5226.         {
  5227.             for( i = customOrientationInfoStack.Size()-1; i>=0; i-=1 )
  5228.             {
  5229.                 if ( customOrientationInfoStack[i].orientationTarget == OT_CustomHeading )
  5230.                 {
  5231.                     if ( !Options().LockOnMode() && !Options().LockOn() )
  5232.                     {
  5233.                         return VecHeading( theCamera.GetCameraDirection() ) - oTCameraOffset;
  5234.                     }
  5235.                     else
  5236.                     {
  5237.                         return customOrientationInfoStack[i].customHeading;
  5238.                     }
  5239.                 }
  5240.             }
  5241.         }
  5242.         LogChannel( 'SetOrientationTargetCustomHeading', "ERROR: Cannot get customHeading because stack is empty or no OT_CustomHeading in stack!!!" );
  5243.         return -1.f;
  5244.     }  
  5245.  
  5246.     public function GetCombatActionOrientationTarget( combatActionType : ECombatActionType ) : EOrientationTarget
  5247.     {
  5248.         var newCustomOrientationTarget : EOrientationTarget;
  5249.         var targetEnt       : CGameplayEntity;
  5250.         var targetActor     : CActor;
  5251.  
  5252.        
  5253.        
  5254.         if ( GetCurrentStateName() == 'AimThrow' )
  5255.             newCustomOrientationTarget = OT_CameraOffset;
  5256.         else
  5257.         {
  5258.             targetEnt = GetDisplayTarget();
  5259.             targetActor = (CActor)targetEnt;       
  5260.        
  5261.             if ( targetEnt )
  5262.             {
  5263.                 if ( targetActor )
  5264.                 {
  5265.                     if ( moveTarget )
  5266.                         newCustomOrientationTarget = OT_Actor;
  5267.                     else
  5268.                     {  
  5269.                         if ( this.IsSwimming() )
  5270.                             newCustomOrientationTarget = OT_Camera;
  5271.                         else if ( lastAxisInputIsMovement )
  5272.                             newCustomOrientationTarget = OT_Player;
  5273.                         else
  5274.                             newCustomOrientationTarget = OT_Actor;
  5275.                     }
  5276.                 }
  5277.                 else
  5278.                 {
  5279.                     if ( combatActionType == CAT_Crossbow && targetEnt.HasTag( 'softLock_Bolt' ) )
  5280.                         newCustomOrientationTarget = OT_Actor;
  5281.                     else
  5282.                     {
  5283.                         if ( this.IsSwimming() )
  5284.                             newCustomOrientationTarget = OT_Camera;                
  5285.                         else if ( lastAxisInputIsMovement )
  5286.                             newCustomOrientationTarget = OT_Player;
  5287.                         else
  5288.                             newCustomOrientationTarget = OT_Camera;
  5289.                        
  5290.                     }
  5291.                 }
  5292.             }
  5293.             else
  5294.             {
  5295.                 if ( IsUsingVehicle() )// || this.IsSwimming() )
  5296.                     newCustomOrientationTarget = OT_Camera;
  5297.                 else if ( lastAxisInputIsMovement )
  5298.                 {
  5299.                     if ( this.IsSwimming() )
  5300.                     {
  5301.                         //if ( !bRAxisReleased
  5302.                         //  || ( GetOrientationTarget() == OT_Camera && ( this.rangedWeapon.GetCurrentStateName() == 'State_WeaponAim' || this.rangedWeapon.GetCurrentStateName() == 'State_WeaponShoot'  ) ) )
  5303.                             newCustomOrientationTarget = OT_Camera;
  5304.                         //else
  5305.                         //  newCustomOrientationTarget = OT_CustomHeading;
  5306.                     }
  5307.                     else
  5308.                         newCustomOrientationTarget = OT_Player;
  5309.                    
  5310.                 }
  5311.                 else
  5312.                     newCustomOrientationTarget = OT_Camera;
  5313.             }
  5314.         }
  5315.         if ( !Options().LockOnMode() && !Options().LockOn() )
  5316.         {
  5317.             return OT_CameraOffset;
  5318.         }
  5319.         else
  5320.         {
  5321.             return newCustomOrientationTarget;
  5322.         }
  5323.     }
  5324.    
  5325.     public function GetOrientationTargetHeading( orientationTarget : EOrientationTarget ) : float
  5326.     {  
  5327.         var heading : float;
  5328.  
  5329.        
  5330.        
  5331.         if( orientationTarget == OT_Camera )
  5332.             heading = VecHeading( theCamera.GetCameraDirection() );
  5333.         else if( orientationTarget == OT_CameraOffset )
  5334.             heading = VecHeading( theCamera.GetCameraDirection() ) - oTCameraOffset;   
  5335.         else if( orientationTarget == OT_CustomHeading )
  5336.             heading = GetOrientationTargetCustomHeading();
  5337.         else if ( GetDisplayTarget() && orientationTarget == OT_Actor )
  5338.         {
  5339.             if ( (CActor)( GetDisplayTarget() ) )
  5340.             {
  5341.                 //if ( GetPlayerCombatStance() == PCS_AlertNear )
  5342.                     heading = VecHeading( GetDisplayTarget().GetWorldPosition() - GetWorldPosition() );
  5343.                 //else
  5344.                 //  heading = GetHeading();
  5345.             }
  5346.             else
  5347.             {
  5348.                 if ( GetDisplayTarget().HasTag( 'softLock_Bolt' ) )
  5349.                     heading = VecHeading( GetDisplayTarget().GetWorldPosition() - GetWorldPosition() );
  5350.                 else
  5351.                     heading = GetHeading();
  5352.             }
  5353.         }
  5354.         else
  5355.             heading = GetHeading();
  5356.            
  5357.         if ( !Options().LockOnMode() && !Options().LockOn() )
  5358.         {
  5359.             return VecHeading( theCamera.GetCameraDirection() ) - oTCameraOffset;
  5360.         }
  5361.         else
  5362.         {
  5363.             return heading;
  5364.         }
  5365.         return 1;          
  5366.     }
  5367.     //W3EE - End
  5368.        
  5369.     event OnDelayOrientationChange()
  5370.     {
  5371.         var delayOrientation    : bool;
  5372.         var delayCameraRotation : bool;
  5373.         var moveData            : SCameraMovementData;
  5374.         var time                : float;
  5375.        
  5376.         time = 0.01f;
  5377.    
  5378.         // W3EE - Begin
  5379.         //if ( theInput.GetActionValue( 'CastSignHold' ) == 1.f )
  5380.         if( GetWitcherPlayer().GetIsAlternateCast() )
  5381.         // W3EE - End
  5382.         {
  5383.             actionType = 0;
  5384.             if ( moveTarget )
  5385.                 delayOrientation = true;
  5386.             else
  5387.             {
  5388.                 if ( !GetBIsCombatActionAllowed() )
  5389.                     delayOrientation = true;
  5390.             }
  5391.            
  5392.  
  5393.         }
  5394.         else if ( theInput.GetActionValue( 'ThrowItemHold' ) == 1.f )
  5395.         {
  5396.             actionType = 3;
  5397.             delayOrientation = true;       
  5398.         }
  5399.         else if ( theInput.GetActionValue( 'SpecialAttackHeavy' ) == 1.f )
  5400.         {
  5401.             actionType = 2;
  5402.             if ( !slideTarget )
  5403.                 delayOrientation = true;
  5404.             else
  5405.                 delayOrientation = true;
  5406.         }
  5407.         else if ( IsGuarded() && !moveTarget )
  5408.         {
  5409.             actionType = 1;
  5410.             delayOrientation = true;
  5411.         }
  5412.        
  5413.         if ( delayOrientation )
  5414.         {
  5415.             delayOrientationChange = true;
  5416.             theGame.GetGameCamera().ForceManualControlHorTimeout();
  5417.             theGame.GetGameCamera().ForceManualControlVerTimeout();
  5418.             AddTimer( 'DelayOrientationChangeTimer', time, true );
  5419.         }
  5420.        
  5421.         if ( delayCameraRotation )
  5422.         {
  5423.             delayCameraOrientationChange = true;
  5424.             theGame.GetGameCamera().ForceManualControlHorTimeout();
  5425.             theGame.GetGameCamera().ForceManualControlVerTimeout();
  5426.             AddTimer( 'DelayOrientationChangeTimer', time, true );         
  5427.         }
  5428.     }
  5429.  
  5430.     //This is also called from behgraph (e.g. SpecialHeavyAttack)
  5431.     event OnDelayOrientationChangeOff()
  5432.     {
  5433.         delayOrientationChange = false;
  5434.         delayCameraOrientationChange = false;
  5435.         RemoveTimer( 'DelayOrientationChangeTimer' );
  5436.  
  5437.         //if ( !IsCameraLockedToTarget() )
  5438.         //  theGame.GetGameCamera().EnableManualControl( true );
  5439.     }
  5440.    
  5441.     timer function DelayOrientationChangeTimer( time : float , id : int)
  5442.     {  
  5443.         // W3EE - Begin
  5444.         if ( ( actionType == 0 && /*theInput.GetActionValue( 'CastSignHold' ) == 0.f*/ !GetWitcherPlayer().GetIsAlternateCast() )
  5445.         // W3EE - End
  5446.             || ( actionType == 2 && theInput.GetActionValue( 'SpecialAttackHeavy' ) == 0.f )
  5447.             || ( actionType == 3 && theInput.GetActionValue( 'ThrowItemHold' ) == 0.f )
  5448.             || ( actionType == 1 && !IsGuarded() )
  5449.             || ( VecLength( rawRightJoyVec ) > 0.f ) )//&& !( slideTarget && IsInCombatAction() && GetBehaviorVariable( 'combatActionType') == (int)CAT_CastSign && GetCurrentlyCastSign() == ST_Axii ) ) )
  5450.         {
  5451.             OnDelayOrientationChangeOff();
  5452.         }
  5453.     }  
  5454.    
  5455.     //W3EE - Begin
  5456.     public function SetCombatActionHeading( heading : float )
  5457.     {
  5458.        
  5459.    
  5460.         if ( !Options().LockOnMode() && !Options().LockOn() )
  5461.         {
  5462.             combatActionHeading = VecHeading( theCamera.GetCameraDirection() ) - oTCameraOffset;
  5463.         }
  5464.         else
  5465.         {
  5466.             combatActionHeading = heading;
  5467.         }          
  5468.     }
  5469.    
  5470.     public function GetCombatActionHeading() : float
  5471.     {
  5472.        
  5473.    
  5474.         if ( !Options().LockOnMode() && !Options().LockOn() )
  5475.         {  
  5476.             return VecHeading( theCamera.GetCameraDirection() ) - oTCameraOffset;
  5477.         }
  5478.         else
  5479.         {
  5480.             return combatActionHeading;
  5481.         }
  5482.         return 1;      
  5483.     }
  5484.     //W3EE - End
  5485.    
  5486.     protected function EnableCloseCombatCharacterRadius( flag : bool )
  5487.     {
  5488.         var actor : CActor;
  5489.    
  5490.         actor = (CActor)slideTarget;
  5491.         if ( flag )
  5492.         {
  5493.             this.GetMovingAgentComponent().SetVirtualRadius( 'CloseCombatCharacterRadius' );
  5494.             if(actor)
  5495.                 actor.GetMovingAgentComponent().SetVirtualRadius( 'CloseCombatCharacterRadius' );
  5496.         }
  5497.         else
  5498.         {
  5499.             if  ( this.IsInCombat() )
  5500.             {
  5501.                 GetMovingAgentComponent().SetVirtualRadius( 'CombatCharacterRadius' );             
  5502.                 if(actor)
  5503.                     actor.GetMovingAgentComponent().SetVirtualRadius( 'CombatCharacterRadius' );
  5504.             }
  5505.             else
  5506.             {
  5507.                 this.GetMovingAgentComponent().ResetVirtualRadius();
  5508.                 if(actor)
  5509.                     actor.GetMovingAgentComponent().ResetVirtualRadius();          
  5510.             }
  5511.         }
  5512.     }      
  5513.    
  5514.     ///////////////////////////////////////////////////////////////////////////
  5515.     // Soft Lock Logic
  5516.    
  5517.  
  5518.    
  5519.     private var isSnappedToNavMesh : bool;
  5520.     private var snapToNavMeshCachedFlag : bool;
  5521.     public function SnapToNavMesh( flag : bool )   
  5522.     {
  5523.         var comp    : CMovingAgentComponent;
  5524.  
  5525.         comp = (CMovingAgentComponent)this.GetMovingAgentComponent();
  5526.    
  5527.         if ( comp )
  5528.         {
  5529.             comp.SnapToNavigableSpace( flag );
  5530.             isSnappedToNavMesh = flag;
  5531.         }
  5532.         else
  5533.         {
  5534.             snapToNavMeshCachedFlag = flag;
  5535.             AddTimer( 'DelayedSnapToNavMesh', 0.2f );
  5536.         }
  5537.     }
  5538.    
  5539.     public final function PlayRuneword4FX(optional weaponType : EPlayerWeapon)
  5540.     {
  5541.         var hasSwordDrawn : bool;
  5542.         var sword : SItemUniqueId;
  5543.        
  5544.         //we show fx only if overheal is greater than 1% - otherwise if we have a DoT and regen at the same time the health
  5545.         //jumps back and forth between 100% and 99.99% stating and stopping the fx over and over
  5546.         //needs to have sword drawn
  5547.         if(abilityManager.GetOverhealBonus() > (0.005 * GetStatMax(BCS_Vitality)))
  5548.         {
  5549.             hasSwordDrawn = HasAbility('Runeword 4 _Stats', true);
  5550.            
  5551.             if(!hasSwordDrawn && GetWitcherPlayer())           
  5552.             {
  5553.                 if(weaponType == PW_Steel)
  5554.                 {
  5555.                     if(GetWitcherPlayer().GetItemEquippedOnSlot(EES_SteelSword, sword))
  5556.                         hasSwordDrawn = inv.ItemHasAbility(sword, 'Runeword 4 _Stats');
  5557.                 }
  5558.                 else if(weaponType == PW_Silver)
  5559.                 {
  5560.                     if(GetWitcherPlayer().GetItemEquippedOnSlot(EES_SilverSword, sword))
  5561.                         hasSwordDrawn = inv.ItemHasAbility(sword, 'Runeword 4 _Stats');
  5562.                 }
  5563.             }
  5564.            
  5565.             if(hasSwordDrawn)
  5566.             {
  5567.                 if(!IsEffectActive('runeword_4', true))
  5568.                     PlayEffect('runeword_4');
  5569.             }
  5570.         }
  5571.     }
  5572.    
  5573.     timer function DelayedSnapToNavMesh( dt : float, id : int)
  5574.     {
  5575.         SnapToNavMesh( snapToNavMeshCachedFlag );
  5576.     }
  5577.    
  5578.     saved var navMeshSnapInfoStack : array<name>;
  5579.     public function EnableSnapToNavMesh( source : name, enable : bool )
  5580.     {
  5581.         if ( enable )
  5582.         {
  5583.             if ( !navMeshSnapInfoStack.Contains( source ) )
  5584.                 navMeshSnapInfoStack.PushBack( source );
  5585.         }
  5586.         else
  5587.         {
  5588.             if ( navMeshSnapInfoStack.Contains( source ) )
  5589.                 navMeshSnapInfoStack.Remove( source ); 
  5590.         }
  5591.        
  5592.         if ( navMeshSnapInfoStack.Size() > 0 )
  5593.             SnapToNavMesh( true );
  5594.         else
  5595.             SnapToNavMesh( false );
  5596.     }  
  5597.    
  5598.     public function ForceRemoveAllNavMeshSnaps()
  5599.     {
  5600.         navMeshSnapInfoStack.Clear();
  5601.         SnapToNavMesh( false );
  5602.     }
  5603.  
  5604.     public function CanSprint( speed : float ) : bool
  5605.     {
  5606.         if( speed <= 0.8f )
  5607.         {
  5608.             return false;
  5609.         }
  5610.        
  5611.         if ( thePlayer.GetIsSprintToggled() )
  5612.         {
  5613.         }
  5614.         else if ( !sprintActionPressed )
  5615.         {
  5616.             return false;
  5617.         }
  5618.         else if( !theInput.IsActionPressed('Sprint') || ( theInput.LastUsedGamepad() && IsInsideInteraction() && GetHowLongSprintButtonWasPressed() < 0.12 ) )
  5619.         {
  5620.             return false;
  5621.         }
  5622.        
  5623.         if ( thePlayer.HasBuff( EET_OverEncumbered ) )
  5624.         {
  5625.             return false;
  5626.         }
  5627.         if ( !IsSwimming() )
  5628.         {
  5629.             // W3EE - Begin
  5630.             if ( ShouldUseStaminaWhileSprinting() && !GetIsSprinting() && !IsInCombat() && GetStatPercents(BCS_Stamina) <= 0.1 )
  5631.             // W3EE - End
  5632.             {
  5633.                 return false;
  5634.             }
  5635.             if( ( !IsCombatMusicEnabled() || IsInFistFightMiniGame() ) && ( !IsActionAllowed(EIAB_RunAndSprint) || !IsActionAllowed(EIAB_Sprint) )  )
  5636.             {
  5637.                 return false;
  5638.             }
  5639.             if( IsTerrainTooSteepToRunUp() )
  5640.             {
  5641.                 return false;
  5642.             }
  5643.             if( IsInCombatAction() )
  5644.             {
  5645.                 return false;
  5646.             }
  5647.             if( IsInAir() )
  5648.             {
  5649.                 return false;
  5650.             }
  5651.         }
  5652.         if( theGame.IsFocusModeActive() )
  5653.         {
  5654.             // W3EE - Begin
  5655.             if ( !Options().SprintInWitcherSense() )
  5656.                 return false;
  5657.             // W3EE - End
  5658.         }
  5659.        
  5660.         return true;
  5661.     }
  5662.    
  5663.    
  5664.     public function SetTerrainPitch( pitch : float )
  5665.     {
  5666.         terrainPitch    = pitch;
  5667.     }
  5668.    
  5669.     public function IsTerrainTooSteepToRunUp() : bool
  5670.     {
  5671.         return terrainPitch <= disableSprintTerrainPitch;
  5672.     }
  5673.    
  5674.     public function SetTempLookAtTarget( actor : CGameplayEntity )
  5675.     {
  5676.         tempLookAtTarget = actor;
  5677.     }
  5678.    
  5679.     private var beingWarnedBy : array<CActor>;
  5680.    
  5681.     event OnBeingWarnedStart( sender : CActor )
  5682.     {
  5683.         if ( !beingWarnedBy.Contains(sender) )
  5684.             beingWarnedBy.PushBack(sender);
  5685.     }
  5686.     event OnBeingWarnedStop( sender : CActor )
  5687.     {
  5688.         beingWarnedBy.Remove(sender);
  5689.     }
  5690.    
  5691.     event OnCanFindPath( sender : CActor )
  5692.     {
  5693.         AddCanFindPathEnemyToList(sender,true);
  5694.     }
  5695.     event OnCannotFindPath( sender : CActor )
  5696.     {
  5697.         AddCanFindPathEnemyToList(sender,false);
  5698.     }
  5699.     event OnBecomeAwareAndCanAttack( sender : CActor )
  5700.     {
  5701.         AddEnemyToHostileEnemiesList( sender, true );
  5702.         OnApproachAttack( sender );    
  5703.     }
  5704.     event OnBecomeUnawareOrCannotAttack( sender : CActor )
  5705.     {
  5706.         AddEnemyToHostileEnemiesList( sender, false );
  5707.         OnApproachAttackEnd( sender );
  5708.         OnCannotFindPath(sender);
  5709.     }  
  5710.     event OnApproachAttack( sender : CActor )
  5711.     {
  5712.         AddEnemyToHostileEnemiesList( sender, true );
  5713.         super.OnApproachAttack( sender );
  5714.     }
  5715.     event OnApproachAttackEnd( sender : CActor )
  5716.     {
  5717.         AddEnemyToHostileEnemiesList( sender, false );
  5718.         super.OnApproachAttackEnd( sender );
  5719.     }
  5720.     event OnAttack( sender : CActor )
  5721.     {
  5722.         super.OnAttack( sender );
  5723.     }
  5724.     event OnAttackEnd( sender : CActor )
  5725.     {
  5726.         super.OnAttackEnd( sender );
  5727.     }
  5728.  
  5729.     event OnHitCeiling()
  5730.     {
  5731.         substateManager.ReactOnHitCeiling();
  5732.     }
  5733.    
  5734.     protected var hostileEnemies            : array<CActor>;        //all enemies that are actively engaged in combat with the player (may or may not be visible by Geralt)
  5735.     private var hostileMonsters         : array<CActor>;        // subgroup from hostileEnemies containing only monsters for sound system
  5736.     function AddEnemyToHostileEnemiesList( actor : CActor, add : bool )
  5737.     {
  5738.         if ( add )
  5739.         {
  5740.             RemoveTimer( 'RemoveEnemyFromHostileEnemiesListTimer' );
  5741.             if ( !hostileEnemies.Contains( actor ) )
  5742.             {
  5743.                 hostileEnemies.PushBack( actor );
  5744.                
  5745.                 if( !actor.IsHuman() )
  5746.                     hostileMonsters.PushBack( actor );
  5747.             }
  5748.         }
  5749.         else
  5750.         {
  5751.             if ( hostileEnemies.Size() == 1 )
  5752.             {
  5753.                 if ( !actor.IsAlive() || actor.IsKnockedUnconscious() )
  5754.                 {
  5755.                     hostileEnemies.Remove( actor );
  5756.                     if( !actor.IsHuman() )
  5757.                         hostileMonsters.Remove( actor );
  5758.                 }
  5759.                 else
  5760.                 {
  5761.                     // If we already waiting to remove an entity
  5762.                     if( hostileEnemyToRemove )
  5763.                     {
  5764.                         hostileEnemies.Remove( hostileEnemyToRemove );
  5765.                         if( !hostileEnemyToRemove.IsHuman() )
  5766.                             hostileMonsters.Remove( hostileEnemyToRemove );
  5767.                     }
  5768.                     hostileEnemyToRemove = actor;
  5769.                     AddTimer( 'RemoveEnemyFromHostileEnemiesListTimer', 3.f );
  5770.                 }
  5771.             }
  5772.             else
  5773.             {
  5774.                 hostileEnemies.Remove( actor );
  5775.                 if( !actor.IsHuman() )
  5776.                     hostileMonsters.Remove( actor );
  5777.             }
  5778.         }
  5779.     }
  5780.    
  5781.      
  5782.    
  5783.     public function ShouldEnableCombatMusic() : bool
  5784.     {
  5785.         var moveTargetNPC   : CNewNPC;
  5786.    
  5787.         if ( thePlayer.GetPlayerMode().GetForceCombatMode() )
  5788.             return true;   
  5789.         else if ( !IsCombatMusicEnabled() )
  5790.         {
  5791.             if ( IsInCombat() )
  5792.                 return true;
  5793.             else if ( IsThreatened() )
  5794.             {
  5795.                 moveTargetNPC = (CNewNPC)moveTarget;
  5796.                 if ( moveTargetNPC.IsRanged() && hostileEnemies.Contains( moveTargetNPC ) )
  5797.                     return true;
  5798.                 else
  5799.                     return false;
  5800.             }
  5801.             else
  5802.                 return false;
  5803.         }
  5804.         else if ( ( thePlayer.IsThreatened() && ( hostileEnemies.Size() > 0 || thePlayer.GetPlayerCombatStance() == PCS_AlertNear ) )
  5805.                 || IsInCombat()
  5806.                 || finishableEnemiesList.Size() > 0
  5807.                 || isInFinisher )
  5808.             return true;
  5809.         else
  5810.             return false;
  5811.        
  5812.     }
  5813.    
  5814.     public var canFindPathEnemiesList : array<CActor>;
  5815.     public var disablecanFindPathEnemiesListUpdate  : bool;
  5816.     private var lastCanFindPathEnemy    : CActor;
  5817.     private var cachedMoveTarget        : CActor;
  5818.     private var reachabilityTestId  : int;
  5819.     private var reachabilityTestId2 : int;
  5820.     function AddCanFindPathEnemyToList( actor : CActor, add : bool )
  5821.     {
  5822.         if ( disablecanFindPathEnemiesListUpdate )
  5823.             return;
  5824.            
  5825.         if ( add && !canFindPathEnemiesList.Contains( actor ) )
  5826.         {
  5827.             canFindPathEnemiesList.PushBack(actor);
  5828.         }
  5829.         else if ( !add )
  5830.         {
  5831.             canFindPathEnemiesList.Remove(actor);
  5832.            
  5833.             if ( canFindPathEnemiesList.Size() <= 0 )
  5834.                 playerMode.UpdateCombatMode();
  5835.         }
  5836.     }
  5837.    
  5838.     public function ClearCanFindPathEnemiesList( dt : float, id : int )
  5839.     {
  5840.         canFindPathEnemiesList.Clear();
  5841.     }  
  5842.    
  5843.     public var finishableEnemiesList : array<CActor>;
  5844.     function AddToFinishableEnemyList( actor : CActor, add : bool )
  5845.     {
  5846.         if ( add && !finishableEnemiesList.Contains( actor ) )
  5847.         {
  5848.             finishableEnemiesList.PushBack(actor);
  5849.         }
  5850.         else if ( !add )
  5851.         {
  5852.             finishableEnemiesList.Remove(actor);
  5853.         }
  5854.     }  
  5855.    
  5856.     private function UpdateFinishableEnemyList()
  5857.     {
  5858.         var i : int;
  5859.         i = 0;
  5860.         while ( i < finishableEnemiesList.Size() )
  5861.         {
  5862.             if ( !finishableEnemiesList[ i ] )
  5863.             {
  5864.                 finishableEnemiesList.EraseFast( i );
  5865.             }
  5866.             else
  5867.             {
  5868.                 i += 1;
  5869.             }
  5870.         }
  5871.     }
  5872.    
  5873.     private timer function ClearFinishableEnemyList( dt : float, id : int )
  5874.     {
  5875.         finishableEnemiesList.Clear();
  5876.     }  
  5877.  
  5878.     private var hostileEnemyToRemove : CActor;
  5879.     private timer function RemoveEnemyFromHostileEnemiesListTimer( time : float , id : int)
  5880.     {
  5881.         hostileEnemies.Remove( hostileEnemyToRemove );
  5882.        
  5883.         if( hostileEnemyToRemove.IsMonster() )
  5884.             hostileMonsters.Remove( hostileEnemyToRemove );
  5885.            
  5886.         hostileEnemyToRemove = NULL;
  5887.     }
  5888.    
  5889.     private function ClearHostileEnemiesList()
  5890.     {
  5891.         hostileEnemies.Clear();
  5892.         hostileMonsters.Clear();
  5893.         canFindPathEnemiesList.Clear();
  5894.     }
  5895.  
  5896.     private var moveTargets                     : array<CActor>;        //all hostileEnemies that Geralt is aware of.
  5897.     public function GetMoveTargets()            : array<CActor> { return moveTargets; }
  5898.     public function GetNumberOfMoveTargets()    : int   { return moveTargets.Size(); }
  5899.     public function GetHostileEnemies()         : array<CActor> { return hostileEnemies; }
  5900.     public function GetHostileEnemiesCount()    : int   { return hostileEnemies.Size(); }
  5901.  
  5902.     protected var enableStrafe      : bool;
  5903.    
  5904.    
  5905.     public function FindMoveTarget()
  5906.     {
  5907.         var moveTargetDists             : array<float>;
  5908.         var moveTargetCanPathFinds      : array<bool>;
  5909.         var aPotentialMoveTargetCanFindPath     : bool;
  5910.        
  5911.         var newMoveTarget               : CActor;
  5912.         var actors                      : array<CActor>;
  5913.         var currentHeading              : float;
  5914.         var size, i                     : int;
  5915.         var playerToNewMoveTargetDist   : float;
  5916.         var playerToMoveTargetDist      : float;
  5917.         var confirmEmptyMoveTarget      : bool;
  5918.         var newEmptyMoveTargetTimer     : float;
  5919.         var wasVisibleInFullFrame       : bool;
  5920.         var setIsThreatened             : bool;
  5921.        
  5922.         var enemysTarget                : CActor;
  5923.         var isEnemyInCombat             : bool;
  5924.         var potentialMoveTargets        : array<CActor>;
  5925.         var onlyThreatTargets           : bool;
  5926.        
  5927.         thePlayer.SetupEnemiesCollection( enemyCollectionDist, enemyCollectionDist, 10, 'None', FLAG_Attitude_Neutral + FLAG_Attitude_Hostile + FLAG_Attitude_Friendly + FLAG_OnlyAliveActors );
  5928.    
  5929.         //if ( moveTarget )
  5930.         //  cachedMoveTarget = moveTarget;
  5931.    
  5932.         if ( GetCurrentStateName() != 'PlayerDialogScene' && IsAlive() )//&& !IsInCombatAction() )//GetBIsCombatActionAllowed() )
  5933.         {
  5934.             GetVisibleEnemies( actors );
  5935.  
  5936.             //Include enemies that geralt cannot see, but is hostile to him
  5937.             if ( hostileEnemies.Size() > 0 )
  5938.             {
  5939.                 for( i=0; i < hostileEnemies.Size() ; i+=1 )
  5940.                 {
  5941.                     if ( !actors.Contains( hostileEnemies[i] ) )
  5942.                         actors.PushBack( hostileEnemies[i] );
  5943.                 }
  5944.             }
  5945.            
  5946.             //Include enemies that are technically dead, but can be finished off
  5947.             if ( finishableEnemiesList.Size() > 0 )
  5948.             {
  5949.                 for( i=0; i < finishableEnemiesList.Size() ; i+=1 )
  5950.                 {
  5951.                     if ( !actors.Contains( finishableEnemiesList[i] ) )
  5952.                         actors.PushBack( finishableEnemiesList[i] );
  5953.                 }
  5954.             }
  5955.            
  5956.             //Check the last moveTarget for situation where enemy targets an ally when you round a corner
  5957.             if ( moveTarget && !actors.Contains( moveTarget )  )
  5958.                 actors.PushBack( moveTarget );         
  5959.            
  5960.             FilterActors( actors, onlyThreatTargets, false );
  5961.            
  5962.             //Determine whether Player should be threatened
  5963.             if ( actors.Size() > 0 )
  5964.             {
  5965.                 setIsThreatened = false;
  5966.            
  5967.                 if ( onlyThreatTargets )
  5968.                 {
  5969.                     setIsThreatened = true;
  5970.                 }
  5971.                 else
  5972.                 {
  5973.                     for( i=0; i < actors.Size() ; i+=1 )
  5974.                     {
  5975.                         if ( IsThreat( actors[i] ) )
  5976.                         {
  5977.                             setIsThreatened = true;
  5978.                             break;
  5979.                         }
  5980.                         else
  5981.                         {
  5982.                             enemysTarget = actors[i].GetTarget();
  5983.                             isEnemyInCombat = actors[i].IsInCombat();
  5984.                             if ( isEnemyInCombat && enemysTarget && GetAttitudeBetween( enemysTarget, this ) == AIA_Friendly && enemysTarget.isPlayerFollower )
  5985.                             {
  5986.                                 setIsThreatened = true;
  5987.                                 break;
  5988.                             }                          
  5989.                         }
  5990.                     }
  5991.                 }
  5992.                
  5993.                 //After filtering you will only have either all hostile or all neutral npcs
  5994.                 for( i = actors.Size()-1; i>=0; i-=1 )
  5995.                 {          
  5996.                     if ( ( !actors[i].IsAlive() && !finishableEnemiesList.Contains( actors[i] ) )
  5997.                         || actors[i].IsKnockedUnconscious()
  5998.                         || this.GetUsedVehicle() == actors[i]
  5999.                         || !actors[i].CanBeTargeted() )
  6000.                     {
  6001.                         actors.EraseFast(i);
  6002.                     }
  6003.                     else if ( !IsThreatened() )
  6004.                     {
  6005.                         if ( !WasVisibleInScaledFrame( actors[i], 1.f, 1.f ) )
  6006.                             actors.EraseFast(i);
  6007.                     }
  6008.                 }
  6009.             }
  6010.             else if ( moveTarget && IsThreat( moveTarget ) )
  6011.                 setIsThreatened = true;
  6012.                 //SetIsThreatened( true );
  6013.             else
  6014.                 setIsThreatened = false;
  6015.                 //SetIsThreatened( false );
  6016.  
  6017.             if ( setIsThreatened )
  6018.             {              
  6019.                 enemyCollectionDist = 50.f;
  6020.                 SetIsThreatened( true );
  6021.             }
  6022.             else
  6023.             {
  6024.                 if ( IsThreatened() )
  6025.                     AddTimer( 'finishableEnemiesList', 1.f );
  6026.                
  6027.                 enemyCollectionDist = findMoveTargetDistMax;
  6028.                 SetIsThreatened( false );
  6029.             }
  6030.  
  6031.             moveTargets = actors;
  6032.             potentialMoveTargets = moveTargets;
  6033.            
  6034.             //MS: By default Geralt will not play PCS_AlertNear unless there is one guy among the hostile npcs that canBeStrafed
  6035.             if ( !moveTarget )
  6036.                 enableStrafe = false;
  6037.                
  6038.             if ( potentialMoveTargets.Size() > 0 )
  6039.             {
  6040.                 for ( i = 0; i < potentialMoveTargets.Size(); i += 1 )
  6041.                 {  
  6042.                     if ( potentialMoveTargets[i].CanBeStrafed() )
  6043.                         enableStrafe = true;
  6044.                    
  6045.                     if ( !potentialMoveTargets[i].GetGameplayVisibility() )
  6046.                         moveTargetDists.PushBack( 100.f ); //Put invisible enemies as the last choice for moveTarget
  6047.                     else
  6048.                         moveTargetDists.PushBack( VecDistance( potentialMoveTargets[i].GetNearestPointInPersonalSpace( GetWorldPosition() ), GetWorldPosition() ) );
  6049.  
  6050.                     if ( canFindPathEnemiesList.Contains( potentialMoveTargets[i] ) )
  6051.                     {
  6052.                         moveTargetCanPathFinds.PushBack( true );
  6053.                         aPotentialMoveTargetCanFindPath = true;
  6054.                     }
  6055.                     else
  6056.                     {
  6057.                         moveTargetCanPathFinds.PushBack( false );
  6058.                     }
  6059.                 }                  
  6060.  
  6061.                 if ( aPotentialMoveTargetCanFindPath )
  6062.                 {
  6063.                     for ( i = moveTargetCanPathFinds.Size()-1 ; i >= 0; i-=1 )
  6064.                     {
  6065.                         if ( !moveTargetCanPathFinds[i] )
  6066.                         {
  6067.                             moveTargetCanPathFinds.EraseFast(i);
  6068.                             potentialMoveTargets.EraseFast(i);
  6069.                             moveTargetDists.EraseFast(i);
  6070.                         }
  6071.                     }
  6072.                 }
  6073.  
  6074.                 if ( moveTargetDists.Size() > 0 )
  6075.                     newMoveTarget = potentialMoveTargets[ ArrayFindMinF( moveTargetDists ) ];
  6076.             }
  6077.  
  6078.             if ( newMoveTarget && newMoveTarget != moveTarget )
  6079.             {
  6080.                 if ( moveTarget )
  6081.                 {
  6082.                     playerToNewMoveTargetDist = VecDistance( newMoveTarget.GetNearestPointInPersonalSpace( GetWorldPosition() ), GetWorldPosition() );
  6083.                     playerToMoveTargetDist = VecDistance( moveTarget.GetNearestPointInPersonalSpace( GetWorldPosition() ), GetWorldPosition() );
  6084.                     wasVisibleInFullFrame = WasVisibleInScaledFrame( moveTarget, 1.f, 1.f ) ;
  6085.                    
  6086.                     if ( !IsThreat( moveTarget )
  6087.                         || !wasVisibleInFullFrame
  6088.                         || !IsEnemyVisible( moveTarget )
  6089.                         || ( !moveTarget.IsAlive() && !finishableEnemiesList.Contains( moveTarget ) )
  6090.                         || !moveTarget.GetGameplayVisibility()
  6091.                         || ( moveTarget.IsAlive() && moveTarget.IsKnockedUnconscious() )
  6092.                         || ( wasVisibleInFullFrame && IsEnemyVisible( moveTarget ) && playerToNewMoveTargetDist < playerToMoveTargetDist - 0.25f ) )
  6093.                     {
  6094.                         SetMoveTarget( newMoveTarget );
  6095.                     }
  6096.                 }
  6097.                 else
  6098.                     SetMoveTarget( newMoveTarget );
  6099.             }
  6100.  
  6101.  
  6102.             if ( !IsThreatened() )
  6103.             {
  6104.                 if ( moveTarget
  6105.                     && ( ( !moveTarget.IsAlive() && !finishableEnemiesList.Contains( moveTarget ) ) || !WasVisibleInScaledFrame( moveTarget, 0.8f, 1.f ) || VecDistance( moveTarget.GetWorldPosition(), this.GetWorldPosition() ) > theGame.params.MAX_THROW_RANGE  )   )
  6106.                 {
  6107.                     confirmEmptyMoveTarget =  true;
  6108.                     newEmptyMoveTargetTimer = 0.f;
  6109.                 }
  6110.             }
  6111.             /*else if ( moveTarget
  6112.                 && ( moveTarget.IsAlive() || finishableEnemiesList.Contains( moveTarget ) )
  6113.                 //&& moveTarget.GetGameplayVisibility()
  6114.                 && hostileEnemies.Contains( moveTarget ) )
  6115.             */ 
  6116.             else if ( moveTarget && ( IsThreat( moveTarget ) || finishableEnemiesList.Contains( moveTarget ) ) )               
  6117.             {
  6118.                 if ( !IsEnemyVisible( moveTarget ) )
  6119.                 {
  6120.                     confirmEmptyMoveTarget =  true;
  6121.                     newEmptyMoveTargetTimer = 5.f;
  6122.                 }
  6123.                 else
  6124.                     SetMoveTarget( moveTarget );
  6125.             }
  6126.             else if ( IsInCombat() )
  6127.             {
  6128.                 confirmEmptyMoveTarget =  true;
  6129.                 newEmptyMoveTargetTimer = 1.0f;
  6130.             }
  6131.            
  6132.             if ( confirmEmptyMoveTarget )
  6133.             {
  6134.                 if ( newEmptyMoveTargetTimer < emptyMoveTargetTimer )
  6135.                 {
  6136.                     bIsConfirmingEmptyTarget = false;
  6137.                     emptyMoveTargetTimer = newEmptyMoveTargetTimer;
  6138.                 }
  6139.                    
  6140.                 ConfirmEmptyMoveTarget( newEmptyMoveTargetTimer );
  6141.             }
  6142.         }
  6143.         else
  6144.             SetIsThreatened( false );
  6145.            
  6146.         //reactionsSystem
  6147.         if ( IsThreatened() && !IsInFistFightMiniGame() )
  6148.             theGame.GetBehTreeReactionManager().CreateReactionEventIfPossible( this, 'CombatNearbyAction', 5.0, 18.0f, -1.f, -1, true ); //reactionSystemSearch
  6149.         else
  6150.             theGame.GetBehTreeReactionManager().RemoveReactionEvent( this, 'CombatNearbyAction'); //reactionSystemSearch
  6151.            
  6152.         // sending nearby monsters count as parameter to sound system
  6153.         theSound.SoundParameter( "monster_count", hostileMonsters.Size() );
  6154.     }
  6155.    
  6156.     private function ConfirmEmptyMoveTarget( timeDelta : float )
  6157.     {
  6158.         if ( !bIsConfirmingEmptyTarget )
  6159.         {
  6160.             bIsConfirmingEmptyTarget = true;
  6161.             AddTimer( 'ConfirmEmptyTargetTimer', timeDelta );
  6162.         }
  6163.     }
  6164.  
  6165.     private timer function ConfirmEmptyTargetTimer( time : float , id : int)
  6166.     {      
  6167.         SetMoveTarget( NULL ); 
  6168.     }
  6169.    
  6170.  
  6171.     var isInCombatReason                : int;
  6172.     var canFindPathToEnemy              : bool;
  6173.     var combatModeEnt                   : CEntity; 
  6174.     var navDist                         : float;
  6175.     var directDist                      : float;   
  6176.     var reachableEnemyWasTooFar         : bool;
  6177.     var reachableEnemyWasTooFarTimeStamp    : float;
  6178.     var reachablilityFailed             : bool;
  6179.     var reachablilityFailedTimeStamp    : float;   
  6180.     public function ShouldEnableCombat( out unableToPathFind : bool, forceCombatMode : bool ) : bool
  6181.     {
  6182.         var shouldFindPathToNPCs    : bool;
  6183.         var playerToTargetDist      : float;
  6184.         var canFindPathToTarget     : bool;
  6185.         var moveTargetNPC           : CNewNPC;
  6186.         var currentTime             : float;
  6187.         var currentTime2            : float;
  6188.         var isReachableEnemyTooFar  : bool;
  6189.         var reachableEnemyWasTooFarTimeStampDelta   : float;
  6190.         var reachablilityFailedTimeStampDelta       : float;
  6191.         var currentTimeTemp         : float;
  6192.    
  6193.         /*if ( GetIsSprinting() )
  6194.         {
  6195.             unableToPathFind = true;
  6196.             isInCombatReason = 0;
  6197.             return false;      
  6198.         }*/
  6199.  
  6200.         if ( forceCombatMode && isSnappedToNavMesh )
  6201.             return true;
  6202.    
  6203.         if ( !IsThreatened() )
  6204.         {
  6205.             reachableEnemyWasTooFar = false;
  6206.             reachablilityFailed = false;       
  6207.             isInCombatReason = 0;
  6208.             return false;
  6209.         }
  6210.    
  6211.         if( thePlayer.substateManager.GetStateCur() != 'CombatExploration' && !thePlayer.substateManager.CanChangeToState( 'CombatExploration' )
  6212.         && thePlayer.substateManager.GetStateCur() != 'Ragdoll' ) //&& !thePlayer.substateManager.CanChangeToState( 'Ragdoll' ) ) )
  6213.         {
  6214.             reachableEnemyWasTooFar = false;
  6215.             reachablilityFailed = false;       
  6216.             isInCombatReason = 0;
  6217.             return false;
  6218.         }
  6219.  
  6220.         if ( moveTarget )
  6221.         {
  6222.             canFindPathToEnemy = CanFindPathToTarget( unableToPathFind );
  6223.             currentTimeTemp = EngineTimeToFloat( theGame.GetEngineTime() );
  6224.            
  6225.             if ( canFindPathToEnemy )
  6226.                 isReachableEnemyTooFar = IsReachableEnemyTooFar();                 
  6227.            
  6228.             if ( IsInCombat() )
  6229.             {
  6230.                 if ( canFindPathToEnemy )
  6231.                 {
  6232.                     if ( forceCombatMode )
  6233.                         return true;
  6234.                
  6235.                     reachablilityFailed = false;
  6236.                     reachablilityFailedTimeStamp = currentTimeTemp;                    
  6237.                
  6238.                     if ( reachableEnemyWasTooFar )
  6239.                     {                                              
  6240.                         if ( isReachableEnemyTooFar )
  6241.                         {
  6242.                             currentTime = currentTimeTemp;
  6243.                            
  6244.                             if ( GetIsSprinting() )
  6245.                                 reachableEnemyWasTooFarTimeStampDelta = 0.f;
  6246.                             else
  6247.                                 reachableEnemyWasTooFarTimeStampDelta = 3.f;
  6248.                                
  6249.                             if ( currentTime > reachableEnemyWasTooFarTimeStamp + reachableEnemyWasTooFarTimeStampDelta )
  6250.                             {                          
  6251.                                 isInCombatReason = 0;
  6252.                                 unableToPathFind = true;
  6253.                                 return false;
  6254.                             }
  6255.                         }
  6256.                         else
  6257.                             reachableEnemyWasTooFar = false;
  6258.                     }
  6259.                     else
  6260.                     {
  6261.                         if ( isReachableEnemyTooFar )
  6262.                         {
  6263.                             reachableEnemyWasTooFar = true;
  6264.                             reachableEnemyWasTooFarTimeStamp = currentTimeTemp;
  6265.                         }
  6266.                         else
  6267.                             reachableEnemyWasTooFar = false;
  6268.                     }  
  6269.            
  6270.                     return true;
  6271.                 }
  6272.                 else
  6273.                 {
  6274.                     reachableEnemyWasTooFar = false;
  6275.                     reachableEnemyWasTooFarTimeStamp = currentTimeTemp;
  6276.                
  6277.                     if ( reachablilityFailed )
  6278.                     {
  6279.                         if ( IsEnemyTooHighToReach() )
  6280.                             reachablilityFailedTimeStampDelta = 1.f;
  6281.                         else
  6282.                             reachablilityFailedTimeStampDelta = 5.f;
  6283.                    
  6284.                         currentTime2 = currentTimeTemp;
  6285.                         if ( currentTime2 > reachablilityFailedTimeStamp + reachablilityFailedTimeStampDelta )
  6286.                         {
  6287.                             unableToPathFind = true;
  6288.                             return false;
  6289.                         }
  6290.                     }
  6291.                     else
  6292.                     {
  6293.                         reachablilityFailed = true;
  6294.                         reachablilityFailedTimeStamp = currentTimeTemp;
  6295.                     }
  6296.                    
  6297.                     return true;
  6298.                 }
  6299.             }
  6300.             else if ( canFindPathToEnemy )
  6301.             {
  6302.                 if ( forceCombatMode )
  6303.                 {
  6304.                     reachableEnemyWasTooFar = false;
  6305.                     return true;
  6306.                 }
  6307.            
  6308.                 reachablilityFailed = false;
  6309.                 reachablilityFailedTimeStamp = currentTimeTemp;
  6310.                
  6311.                 moveTargetNPC = (CNewNPC)moveTarget;
  6312.                 playerToTargetDist = VecDistance( moveTarget.GetWorldPosition(), this.GetWorldPosition() );
  6313.  
  6314.                 /*if ( !theGame.GetWorld().NavigationLineTest( this.GetWorldPosition(), moveTarget.GetWorldPosition(), 0.4f ) )
  6315.                 {
  6316.                     isInCombatReason = 0;
  6317.                     return false;                  
  6318.                 }
  6319.                 else*/ if ( reachableEnemyWasTooFar
  6320.                     && ( isReachableEnemyTooFar || !theGame.GetWorld().NavigationLineTest( this.GetWorldPosition(), moveTarget.GetWorldPosition(), 0.4f ) ) )
  6321.                 {
  6322.                     isInCombatReason = 0;
  6323.                     return false;          
  6324.                 }
  6325.                 else if ( playerToTargetDist <= findMoveTargetDistMin )
  6326.                     isInCombatReason = 1;
  6327.                 else if ( ( moveTargetNPC.GetCurrentStance() == NS_Fly || moveTargetNPC.IsRanged() ) && hostileEnemies.Contains( moveTarget ) )
  6328.                     isInCombatReason = 2;
  6329.                 else
  6330.                 {            
  6331.                     isInCombatReason = 0;
  6332.                     return false;
  6333.                 }
  6334.                
  6335.                 reachableEnemyWasTooFar = false;
  6336.                 return true;
  6337.             }                      
  6338.         }
  6339.         else
  6340.         {
  6341.             reachableEnemyWasTooFar = false;
  6342.             reachablilityFailed = false;
  6343.         }
  6344.        
  6345.         isInCombatReason = 0;
  6346.         return false;
  6347.     }
  6348.    
  6349.     private function CanFindPathToTarget( out unableToPathFind : bool, optional forcedTarget : CNewNPC ) : bool
  6350.     {
  6351.         var moveTargetNPC : CNewNPC;
  6352.         var moveTargetsTemp : array<CActor>;
  6353.         var i : int;
  6354.         var safeSpotTolerance : float;
  6355.         var ent : CEntity;
  6356.  
  6357.         moveTargetsTemp = moveTargets;
  6358.    
  6359.         for ( i = 0; i < moveTargetsTemp.Size(); i += 1 )
  6360.         {
  6361.             moveTargetNPC = (CNewNPC)moveTargetsTemp[i];
  6362.        
  6363.             if ( moveTargetNPC && moveTargetNPC.GetCurrentStance() == NS_Fly )
  6364.             {
  6365.                 isInCombatReason = 2;
  6366.                 return true;
  6367.             }
  6368.         }
  6369.    
  6370.         switch ( navQuery.GetLastOutput( 0.4 ) )
  6371.         {
  6372.             case EAsyncTastResult_Failure:
  6373.             {
  6374.                 isInCombatReason = 0;
  6375.                 return false;
  6376.             }
  6377.             case EAsyncTastResult_Success:
  6378.             {
  6379.                 ent = navQuery.GetOutputClosestEntity();
  6380.                
  6381.                 if ( ent )
  6382.                     combatModeEnt = moveTarget;
  6383.                    
  6384.                 navDist = navQuery.GetOutputClosestDistance();
  6385.                
  6386.                 isInCombatReason = 1;
  6387.                 return true;
  6388.             }
  6389.             case EAsyncTastResult_Pending:
  6390.             {
  6391.                 return canFindPathToEnemy;
  6392.             }
  6393.             case EAsyncTastResult_Invalidated:
  6394.             {
  6395.                 if ( IsInCombat() )
  6396.                 {
  6397.                     if ( IsEnemyTooHighToReach() )
  6398.                         safeSpotTolerance = 0.f;
  6399.                     else
  6400.                         safeSpotTolerance = 3.f;
  6401.                 }
  6402.                 else
  6403.                     safeSpotTolerance = 0.f;
  6404.            
  6405.                 switch( navQuery.TestActorsList( ENavigationReachability_Any, this, moveTargetsTemp, safeSpotTolerance, 75.0 ) )
  6406.                 {
  6407.                     case EAsyncTastResult_Failure:
  6408.                     {
  6409.                         isInCombatReason = 0;
  6410.                         return false;
  6411.                     }
  6412.                     case EAsyncTastResult_Success:
  6413.                     {
  6414.                         ent = navQuery.GetOutputClosestEntity();
  6415.                        
  6416.                         if ( ent )
  6417.                             combatModeEnt = moveTarget;
  6418.                            
  6419.                         navDist = navQuery.GetOutputClosestDistance();                 
  6420.                    
  6421.                         isInCombatReason = 1;
  6422.                         return true;
  6423.                     }
  6424.                     case EAsyncTastResult_Pending:
  6425.                     {
  6426.                         return canFindPathToEnemy;
  6427.                     }  
  6428.                     case EAsyncTastResult_Invalidated:
  6429.                     {
  6430.                         if ( IsInCombat() )
  6431.                             return true;
  6432.                         else
  6433.                             return false;
  6434.                     }  
  6435.                 }
  6436.             }
  6437.         }  
  6438.     }
  6439.    
  6440.     private function IsReachableEnemyTooFar() : bool
  6441.     {
  6442.         //var navDistFailMax            : float = 100.f;
  6443.         var navDistLimit            : float = findMoveTargetDist; //25.f;
  6444.         var navDistDivisor          : float = 2.f;
  6445.         var playerToTargetVector    : Vector;  
  6446.    
  6447.         directDist = VecDistance( combatModeEnt.GetWorldPosition(), thePlayer.GetWorldPosition() );
  6448.         playerToTargetVector = this.GetWorldPosition() - combatModeEnt.GetWorldPosition();
  6449.        
  6450.         if ( playerMode.GetForceCombatMode() || isInCombatReason == 2 )
  6451.             return false;
  6452.        
  6453.         if ( ( playerToTargetVector.Z < 0.5 && navDist > navDistLimit && directDist < navDist/navDistDivisor ) )
  6454.             return true;
  6455.         else
  6456.             return false;
  6457.     }
  6458.    
  6459.     private function IsEnemyTooHighToReach() : bool
  6460.     {  
  6461.         var playerToTargetVector    : Vector;      
  6462.    
  6463.         playerToTargetVector = this.GetWorldPosition() - combatModeEnt.GetWorldPosition();
  6464.    
  6465.         if ( playerToTargetVector.Z < -0.5f && !theGame.GetWorld().NavigationLineTest( this.GetWorldPosition(), combatModeEnt.GetWorldPosition(), 0.4f ) )
  6466.             return true;
  6467.         else
  6468.             return false;
  6469.     }
  6470.    
  6471.     //Force Geralt to face an enemy for a moment before changing to another enemy
  6472.     public function LockToMoveTarget( lockTime : float )
  6473.     {
  6474.         /*if ( IsMoveTargetChangeAllowed() )
  6475.         {
  6476.             bMoveTargetChangeAllowed = false;
  6477.             AddTimer( 'DisableLockToMoveTargetTimer', lockTime );
  6478.         }*/
  6479.     }
  6480.    
  6481.     private timer function DisableLockToMoveTargetTimer( time : float , id : int)
  6482.     {
  6483.         if ( !this.IsActorLockedToTarget() )
  6484.         {
  6485.             SetMoveTargetChangeAllowed( true );
  6486.         }
  6487.     }
  6488.    
  6489.     public function SetMoveTargetChangeAllowed( flag : bool )
  6490.     {
  6491.         //bMoveTargetChangeAllowed = flag;
  6492.     }
  6493.    
  6494.     public function IsMoveTargetChangeAllowed() : bool
  6495.     {
  6496.         return bMoveTargetChangeAllowed;
  6497.     }
  6498.    
  6499.     public function SetMoveTarget( actor : CActor )
  6500.     {      
  6501.         if ( !actor && ForceCombatModeOverride() )
  6502.             return;
  6503.    
  6504.         if ( IsMoveTargetChangeAllowed()
  6505.             && moveTarget != actor )
  6506.         {
  6507.             moveTarget = actor;
  6508.             bIsConfirmingEmptyTarget = false;
  6509.             RemoveTimer( 'ConfirmEmptyTargetTimer' );
  6510.            
  6511.             if ( !moveTarget )
  6512.                 SetScriptMoveTarget( moveTarget );
  6513.         }
  6514.     }
  6515.    
  6516.     private var isThreatened    : bool;
  6517.     protected function SetIsThreatened( flag : bool )  
  6518.     {  
  6519.         var allowSetIsThreatened : bool;
  6520.        
  6521.         allowSetIsThreatened = true;
  6522.         if ( ForceCombatModeOverride() )
  6523.         {
  6524.             if ( flag || !moveTarget )
  6525.                 allowSetIsThreatened = true;
  6526.             else
  6527.                 allowSetIsThreatened = false;
  6528.         }
  6529.    
  6530.         if ( allowSetIsThreatened )
  6531.         {
  6532.             isThreatened = flag;
  6533.         }
  6534.     }
  6535.    
  6536.     public function ForceCombatModeOverride() : bool
  6537.     {
  6538.         if( this.GetPlayerMode().GetForceCombatMode()
  6539.             && canFindPathToEnemy
  6540.             && theGame.GetGlobalAttitude( GetBaseAttitudeGroup(), moveTarget.GetBaseAttitudeGroup() ) == AIA_Hostile )
  6541.             return true;
  6542.         else
  6543.             return false;
  6544.     }
  6545.    
  6546.     public function IsThreatened() : bool   { return isThreatened; }
  6547.        
  6548.     public function EnableFindTarget( flag : bool )
  6549.     {
  6550.         var target : CActor;
  6551.        
  6552.         if( IsActorLockedToTarget() )
  6553.         {
  6554.             target = GetTarget();
  6555.            
  6556.             if ( target && target.IsAlive() )
  6557.                 bCanFindTarget = flag;
  6558.             else
  6559.                 bCanFindTarget = true;
  6560.         }
  6561.         else
  6562.             bCanFindTarget = flag;
  6563.     }
  6564.    
  6565.     public function UpdateDisplayTarget( optional forceUpdate : bool, optional forceNullActor : bool )
  6566.     {
  6567.         var hud                     : CR4ScriptedHud;
  6568.         var tempTarget              : CGameplayEntity;
  6569.         var angleDist1              : float;
  6570.         var angleDist2              : float;
  6571.         var nonActorTargetMult      : float;
  6572.         var combatActionType        : int;
  6573.         var currTarget              : CActor;
  6574.         var interactionTarget       : CInteractionComponent;
  6575.        
  6576.         var heading                 : float;
  6577.  
  6578.         if(theGame.IsDialogOrCutscenePlaying())
  6579.         {
  6580.             currentSelectedDisplayTarget = NULL;
  6581.            
  6582.             if ( displayTarget )
  6583.                 ConfirmDisplayTarget( NULL );
  6584.            
  6585.             return;
  6586.         }
  6587.        
  6588.         if ( forceNullActor )
  6589.             currTarget = NULL;
  6590.         else
  6591.             currTarget = GetTarget();
  6592.            
  6593.         currentSelectedDisplayTarget = currTarget;
  6594.        
  6595.         if ( currTarget && !currTarget.IsTargetableByPlayer() )
  6596.         {
  6597.             currentSelectedDisplayTarget = NULL;
  6598.             ConfirmDisplayTarget( currentSelectedDisplayTarget );
  6599.             return;
  6600.         }
  6601.         //Setting multiplier that increases non actor target priority
  6602.         nonActorTargetMult = 1.25;
  6603.        
  6604.         //Update the interaction icon
  6605.         hud = (CR4ScriptedHud)theGame.GetHud();
  6606.        
  6607.         if ( !IsThreatened() )
  6608.         {
  6609.             if ( !bLAxisReleased || lastAxisInputIsMovement  )
  6610.             {
  6611.                 if ( currTarget )
  6612.                     angleDist1 = AbsF( AngleDistance( this.GetHeading(), VecHeading( currTarget.GetWorldPosition() - this.GetWorldPosition() ) ) );
  6613.                 else
  6614.                     angleDist1 = 360;
  6615.                
  6616.                 if ( nonActorTarget )
  6617.                     angleDist2 = AbsF( AngleDistance( this.GetHeading(), VecHeading( nonActorTarget.GetWorldPosition() - this.GetWorldPosition() ) ) );
  6618.                 else
  6619.                     angleDist2 = 360;          
  6620.             }
  6621.             else
  6622.             {
  6623.                 if ( currTarget )
  6624.                     angleDist1 = AbsF( AngleDistance( theCamera.GetCameraHeading(), VecHeading( currTarget.GetWorldPosition() - theCamera.GetCameraPosition() ) ) );
  6625.                 else
  6626.                     angleDist1 = 360;
  6627.                
  6628.                 if ( nonActorTarget )
  6629.                     angleDist2 = AbsF( AngleDistance( theCamera.GetCameraHeading(), VecHeading( nonActorTarget.GetWorldPosition() - theCamera.GetCameraPosition() ) ) );
  6630.                 else
  6631.                     angleDist2 = 360;
  6632.             }
  6633.         }
  6634.  
  6635.         else
  6636.         {      
  6637.             if ( !bLAxisReleased )
  6638.             {
  6639.                 if ( ShouldUsePCModeTargeting() )
  6640.                 {
  6641.                     if ( currTarget )
  6642.                         angleDist1 = AbsF( AngleDistance( theCamera.GetCameraHeading(), VecHeading( currTarget.GetWorldPosition() - theCamera.GetCameraPosition() ) ) );
  6643.                     else
  6644.                         angleDist1 = 360;
  6645.                    
  6646.                     if ( nonActorTarget && IsInCombatAction() )
  6647.                     {
  6648.                         angleDist2 = nonActorTargetMult * AbsF( AngleDistance( theCamera.GetCameraHeading(), VecHeading( nonActorTarget.GetWorldPosition() - theCamera.GetCameraPosition() ) ) );
  6649.                     }
  6650.                     else
  6651.                         angleDist2 = 360;              
  6652.                 }
  6653.                 else
  6654.                 {
  6655.                     if ( currTarget )
  6656.                         angleDist1 = AbsF( AngleDistance( rawPlayerHeading, VecHeading( currTarget.GetWorldPosition() - this.GetWorldPosition() ) ) );
  6657.                     else
  6658.                         angleDist1 = 360;
  6659.                    
  6660.                     if ( nonActorTarget && IsInCombatAction() )
  6661.                     {
  6662.                         angleDist2 = nonActorTargetMult * AbsF( AngleDistance( rawPlayerHeading, VecHeading( nonActorTarget.GetWorldPosition() - this.GetWorldPosition() ) ) );
  6663.                     }
  6664.                     else
  6665.                         angleDist2 = 360;
  6666.                 }
  6667.             }
  6668.             else
  6669.             {
  6670.                 angleDist1 = 0;
  6671.                 angleDist2 = 360;
  6672.             }
  6673.         }
  6674.        
  6675.        
  6676.         if ( angleDist1 < angleDist2 )
  6677.             tempTarget = currTarget;
  6678.         else
  6679.             tempTarget = nonActorTarget;
  6680.            
  6681.            
  6682.         if ( slideTarget && IsInCombatAction() )
  6683.         {
  6684.             combatActionType = (int)this.GetBehaviorVariable( 'combatActionType' );
  6685.             if (    combatActionType == (int)CAT_Attack        
  6686.                     || ( combatActionType == (int)CAT_SpecialAttack && this.GetBehaviorVariable( 'playerAttackType' ) == 1.f )
  6687.                     || ( combatActionType == (int)CAT_ItemThrow )
  6688.                     || ( combatActionType == (int)CAT_CastSign && !IsCurrentSignChanneled() )
  6689.                     || ( combatActionType == (int)CAT_CastSign && IsCurrentSignChanneled() && GetCurrentlyCastSign() == ST_Axii )
  6690.                     || ( combatActionType == (int)CAT_CastSign && IsCurrentSignChanneled() && GetCurrentlyCastSign() == ST_Igni )
  6691.                     || combatActionType == (int)CAT_Dodge
  6692.                     || combatActionType == (int)CAT_Roll )
  6693.             {
  6694.                 if ( combatActionType == (int)CAT_CastSign && GetCurrentlyCastSign() == ST_Igni && !IsCombatMusicEnabled() )
  6695.                     currentSelectedDisplayTarget = tempTarget; 
  6696.                 else
  6697.                     currentSelectedDisplayTarget = slideTarget;
  6698.             }
  6699.             else
  6700.                 currentSelectedDisplayTarget = tempTarget; 
  6701.         }
  6702.         else if ( slideTarget
  6703.             && this.rangedWeapon
  6704.             && this.rangedWeapon.GetCurrentStateName() != 'State_WeaponWait'
  6705.             && this.playerAiming.GetCurrentStateName() == 'Waiting' ) //( this.rangedWeapon.GetCurrentStateName() == 'State_WeaponShoot' || this.rangedWeapon.GetCurrentStateName() == 'State_WeaponAim' ) )
  6706.                 currentSelectedDisplayTarget = slideTarget;
  6707.         else
  6708.             currentSelectedDisplayTarget = tempTarget; 
  6709.        
  6710.         interactionTarget = theGame.GetInteractionsManager().GetActiveInteraction();
  6711.         if  ( interactionTarget && !IsThreatened() && !( this.IsCastingSign() && this.IsCurrentSignChanneled() ) )
  6712.         {
  6713.             tempTarget = (CGameplayEntity)interactionTarget.GetEntity();
  6714.             if ( tempTarget && tempTarget !=  this.GetUsedVehicle() )
  6715.             {
  6716.                 currentSelectedDisplayTarget = tempTarget;
  6717.                 SetDisplayTarget( currentSelectedDisplayTarget );
  6718.             }
  6719.         }
  6720.        
  6721.         // disabling display for invisible targets
  6722.         if ( (CActor)currentSelectedDisplayTarget && !((CActor)currentSelectedDisplayTarget).GetGameplayVisibility() )
  6723.         {
  6724.             currentSelectedDisplayTarget = NULL;
  6725.         }
  6726.        
  6727.         if ( displayTarget != currentSelectedDisplayTarget )
  6728.         {
  6729.             if ( forceUpdate )
  6730.                 SetDisplayTarget( currentSelectedDisplayTarget );
  6731.             else
  6732.                 ConfirmDisplayTarget( currentSelectedDisplayTarget );
  6733.         }
  6734.     }
  6735.    
  6736.     private var bConfirmDisplayTargetTimerEnabled   : bool;
  6737.     private var displayTargetToConfirm              : CGameplayEntity;
  6738.     private var currentSelectedDisplayTarget        : CGameplayEntity;
  6739.    
  6740.     private function ConfirmDisplayTarget( targetToConfirm : CGameplayEntity )
  6741.     {  
  6742.         if ( targetToConfirm != displayTarget )
  6743.         {
  6744.             displayTargetToConfirm = targetToConfirm;
  6745.             if( !bConfirmDisplayTargetTimerEnabled )
  6746.             {
  6747.                 bConfirmDisplayTargetTimerEnabled = true;
  6748.                
  6749.                 if ( targetToConfirm )
  6750.                     AddTimer( 'ConfirmDisplayTargetTimer', 0.1f );
  6751.                 else
  6752.                     AddTimer( 'ConfirmDisplayTargetTimer', 0.f );
  6753.             }
  6754.         }
  6755.     }
  6756.    
  6757.     private timer function ConfirmDisplayTargetTimer( time : float, optional id : int)
  6758.     {
  6759.         if ( displayTargetToConfirm == currentSelectedDisplayTarget )
  6760.             SetDisplayTarget( displayTargetToConfirm );
  6761.  
  6762.         bConfirmDisplayTargetTimerEnabled = false;
  6763.     }  
  6764.    
  6765.    
  6766.     protected function SetDisplayTarget( e : CGameplayEntity )
  6767.     {
  6768.         var displayTargetActor : CActor;
  6769.        
  6770.         if ( e != displayTarget )
  6771.         {
  6772.             displayTarget = e;
  6773.             displayTargetActor = (CActor)displayTarget;
  6774.             SetPlayerCombatTarget( displayTargetActor );
  6775.            
  6776.             if ( displayTargetActor && !displayTargetActor.IsTargetableByPlayer())
  6777.             {
  6778.                 isDisplayTargetTargetable = false;
  6779.             }
  6780.             else if ( !displayTargetActor && displayTarget != nonActorTarget )
  6781.             {
  6782.                 isDisplayTargetTargetable = false;
  6783.             }
  6784.             else
  6785.             {
  6786.                 isDisplayTargetTargetable = true;
  6787.             }
  6788.         }
  6789.     }
  6790.  
  6791.     public function GetDisplayTarget() : CGameplayEntity        { return displayTarget; }
  6792.    
  6793.     private var isDisplayTargetTargetable : bool;
  6794.     public function IsDisplayTargetTargetable() : bool
  6795.     {
  6796.         return isDisplayTargetTargetable;
  6797.     }
  6798.    
  6799.     public  var radialSlots                 : array<name>; 
  6800.     public function EnableRadialSlots( enable : bool, slotNames : array<name> )
  6801.     {
  6802.         var hud : CR4ScriptedHud;
  6803.         var module : CR4HudModuleRadialMenu;
  6804.         var i : int;
  6805.  
  6806.         hud = (CR4ScriptedHud)theGame.GetHud();
  6807.         module = (CR4HudModuleRadialMenu)hud.GetHudModule("RadialMenuModule");
  6808.  
  6809.         for(i=0; i<slotNames.Size(); i+=1)
  6810.         {
  6811.             module.SetDesaturated( !enable, slotNames[i] );
  6812.         }
  6813.     }
  6814.    
  6815.     public function IsEnemyInCone( source : CActor, coneHeading : Vector, coneDist, coneAngle : float, out newLockTarget : CActor ) : bool
  6816.     {
  6817.         var targets             : array<CActor>;
  6818.         var sourceToTargetDists : array<float>;
  6819.         var i                   : int;
  6820.         var targetingInfo       : STargetingInfo;
  6821.        
  6822.         //GetVisibleEnemies( targets );
  6823.         //targets = FilterActors( targets );
  6824.         targets = GetMoveTargets();
  6825.    
  6826.         if ( targets.Size() > 0 )
  6827.         {
  6828.             targetingInfo.source                = this;
  6829.             targetingInfo.canBeTargetedCheck    = true;
  6830.             targetingInfo.coneCheck             = true;
  6831.             targetingInfo.coneHalfAngleCos      = CosF( Deg2Rad( coneAngle * 0.5f ) );
  6832.             targetingInfo.coneDist              = coneDist;
  6833.             targetingInfo.coneHeadingVector     = coneHeading;
  6834.             targetingInfo.distCheck             = true;
  6835.             targetingInfo.invisibleCheck        = true;
  6836.             targetingInfo.navMeshCheck          = true;
  6837.             targetingInfo.inFrameCheck          = false;
  6838.             targetingInfo.frameScaleX           = 1.f;
  6839.             targetingInfo.frameScaleY           = 1.f;
  6840.             targetingInfo.knockDownCheck        = false;
  6841.             targetingInfo.knockDownCheckDist    = 1.5f;
  6842.             targetingInfo.rsHeadingCheck        = false;
  6843.             targetingInfo.rsHeadingLimitCos     = 1.0f;
  6844.            
  6845.             for( i = targets.Size() - 1; i >= 0; i -= 1 )
  6846.             {
  6847.                 targetingInfo.targetEntity      = targets[i];
  6848.                 if ( !IsEntityTargetable( targetingInfo ) )
  6849.                     targets.Erase( i );
  6850.             }
  6851.  
  6852.             for (  i = 0; i < targets.Size(); i += 1 )
  6853.                 sourceToTargetDists.PushBack( VecDistance( source.GetWorldPosition(), targets[i].GetWorldPosition() ) );
  6854.            
  6855.             if(sourceToTargetDists.Size() > 0)
  6856.                 newLockTarget = targets[ ArrayFindMinF( sourceToTargetDists ) ];
  6857.             else
  6858.                 newLockTarget = NULL;
  6859.         }
  6860.        
  6861.         return targets.Size() > 0;
  6862.     }  
  6863.    
  6864.     public function GetScreenSpaceLockTarget( sourceEnt : CGameplayEntity, coneAngle, coneDist, coneHeading : float, optional inFrameCheck : bool ) : CActor
  6865.     {
  6866.         var source                  : CActor;
  6867.         var sourcePos, targetPos    : Vector;
  6868.         var targets                 : array<CActor>;
  6869.         var sourceToTargetDists     : array<float>;
  6870.         var sourceCoord             : Vector;
  6871.         var targetCoord             : Vector;
  6872.         var i                       : int;
  6873.         var angleDiff               : float;
  6874.         var sourceToTargetHeading   : float;
  6875.         var sourceToTargetDist      : float;
  6876.         var size                    : float;
  6877.         var targetingDist           : float;
  6878.         var targetingInfo           : STargetingInfo;
  6879.        
  6880.         var temp : int;
  6881.        
  6882.         // MAREK TODO :  Need to use cached values of screenspace coords instead of calculating again
  6883.         //GetVisibleEnemies( targets );
  6884.         //targets = FilterActors( targets );
  6885.         source = (CActor)sourceEnt;
  6886.        
  6887.         targets = GetMoveTargets();
  6888.        
  6889.         if ( this.IsPCModeEnabled() )
  6890.         {
  6891.             if ( ( coneHeading > -45.f && coneHeading < 45.f )
  6892.                 || coneHeading > 135.f
  6893.                 || coneHeading < -135.f )
  6894.             {
  6895.                 if ( coneHeading > 0 )
  6896.                     coneHeading = 180 - coneHeading;
  6897.                 else
  6898.                     coneHeading = 180 + coneHeading;
  6899.             }
  6900.         }      
  6901.        
  6902.         /*if ( IsCombatMusicEnabled() || hostileEnemies.Size() > 0  )
  6903.         {
  6904.             if ( targets[0] && !IsThreat( targets[0] ) )
  6905.                 targets.Clear();
  6906.         }*/
  6907.        
  6908.         for( i = targets.Size() - 1; i >= 0; i -= 1 )
  6909.         {
  6910.             if ( ( !targets[i].GetGameplayVisibility() || !IsThreat( targets[i] ) || !IsEnemyVisible( targets[i] ) || !this.CanBeTargetedIfSwimming( targets[i] ) )
  6911.                 && ( !IsCastingSign() || GetCurrentlyCastSign() != ST_Axii ) )
  6912.                 targets.Erase(i);
  6913.         }
  6914.        
  6915.         if ( source )
  6916.         {
  6917.             temp = source.GetTorsoBoneIndex();
  6918.            
  6919.             if ( temp < 0 )
  6920.                 sourcePos = source.GetWorldPosition();
  6921.             else
  6922.                 sourcePos = MatrixGetTranslation( source.GetBoneWorldMatrixByIndex( source.GetTorsoBoneIndex() ) );    
  6923.         }
  6924.         else
  6925.             sourcePos = sourceEnt.GetWorldPosition();
  6926.            
  6927.         theCamera.WorldVectorToViewRatio( sourcePos, sourceCoord.X , sourceCoord.Y );
  6928.        
  6929.         /*if ( !IsUsingVehicle() )
  6930.             targetingDist = softLockDist;          
  6931.         else*/
  6932.             targetingDist = softLockDistVehicle;
  6933.        
  6934.         if ( targets.Size() > 0 )
  6935.         {
  6936.             targetingInfo.source                = this;
  6937.             targetingInfo.canBeTargetedCheck    = true;
  6938.             targetingInfo.coneCheck             = false;
  6939.             targetingInfo.coneHalfAngleCos      = 0.86602540378f; // = CosF( Deg2Rad( 60.0f * 0.5f ) )
  6940.             targetingInfo.coneDist              = targetingDist;
  6941.             targetingInfo.coneHeadingVector     = Vector( 0.0f, 1.0f, 0.0f );
  6942.             targetingInfo.distCheck             = true;
  6943.             targetingInfo.invisibleCheck        = true;
  6944.             targetingInfo.navMeshCheck          = false;
  6945.            
  6946.             if ( inFrameCheck )
  6947.                 targetingInfo.inFrameCheck      = true;
  6948.             else
  6949.                 targetingInfo.inFrameCheck      = false;
  6950.                
  6951.             targetingInfo.frameScaleX           = 1.f;
  6952.             targetingInfo.frameScaleY           = 1.f;
  6953.             targetingInfo.knockDownCheck        = false;
  6954.             targetingInfo.knockDownCheckDist    = softLockDist;
  6955.             if ( bRAxisReleased )
  6956.                 targetingInfo.rsHeadingCheck    = false;
  6957.             else
  6958.                 targetingInfo.rsHeadingCheck    = true;
  6959.             targetingInfo.rsHeadingLimitCos     = -0.5f; // = CosF( Deg2Rad( 120.0f ) );       
  6960.        
  6961.             for( i = targets.Size() - 1; i >= 0; i -= 1 )
  6962.             {
  6963.                 temp = targets[i].GetTorsoBoneIndex();
  6964.                
  6965.                 if ( temp < 0 )
  6966.                     targetPos = targets[i].GetWorldPosition();
  6967.                 else
  6968.                     targetPos = MatrixGetTranslation( targets[i].GetBoneWorldMatrixByIndex( targets[i].GetTorsoBoneIndex() ) );
  6969.                    
  6970.                 theCamera.WorldVectorToViewRatio( targetPos, targetCoord.X, targetCoord.Y );
  6971.                 sourceToTargetHeading = VecHeading( targetCoord - sourceCoord );
  6972.                 angleDiff = AbsF( AngleDistance( coneHeading, sourceToTargetHeading ) );
  6973.                
  6974.                 targetingInfo.targetEntity          = targets[i];
  6975.                 if ( !IsEntityTargetable( targetingInfo ) )
  6976.                     targets.Erase( i );
  6977.                 else if ( !bRAxisReleased && angleDiff > ( coneAngle * 0.5 ) )
  6978.                     targets.Erase( i );
  6979.                 else if ( targets[i] == sourceEnt )
  6980.                     targets.Erase( i );
  6981.            
  6982.                 /*if ( GetDisplayTarget() && IsInCombatAction() && GetBehaviorVariable( 'combatActionType') == (int)CAT_CastSign && GetCurrentlyCastSign() == ST_Igni )
  6983.                 {
  6984.  
  6985.                 }
  6986.                 else
  6987.                 {
  6988.                     targetingInfo.rsHeadingCheck        = false;
  6989.                     if ( !IsEntityTargetable( targetingInfo )
  6990.                         || angleDiff > ( coneAngle * 0.5 )
  6991.                         || targets[i] == sourceEnt )
  6992.                         targets.Erase( i );        
  6993.                 }*/
  6994.             }
  6995.         }
  6996.        
  6997.         size = targets.Size();
  6998.         if ( size > 0 )
  6999.         {
  7000.             for (  i = 0; i < targets.Size(); i += 1 )
  7001.             {
  7002.                 temp = targets[i].GetTorsoBoneIndex();
  7003.                
  7004.                 if ( temp < 0 )
  7005.                     targetPos = targets[i].GetWorldPosition();
  7006.                 else
  7007.                     targetPos = MatrixGetTranslation( targets[i].GetBoneWorldMatrixByIndex( targets[i].GetTorsoBoneIndex() ) );
  7008.    
  7009.                 theCamera.WorldVectorToViewRatio( targetPos, targetCoord.X, targetCoord.Y );
  7010.                 sourceToTargetHeading = AbsF( VecHeading( targetCoord - sourceCoord ) );
  7011.                 angleDiff = AngleDistance( 180, sourceToTargetHeading );
  7012.                 sourceToTargetDist = VecDistance2D( sourceCoord, targetCoord );
  7013.                
  7014.                 sourceToTargetDists.PushBack( SinF( Deg2Rad( angleDiff ) ) * sourceToTargetDist );
  7015.             }          
  7016.         }
  7017.        
  7018.         if ( targets.Size() > 0 )//GetDisplayTarget() )
  7019.             return targets[ ArrayFindMinF( sourceToTargetDists ) ];
  7020.         else
  7021.             return NULL;
  7022.     }
  7023.  
  7024.     public function IsEntityTargetable( out info : STargetingInfo, optional usePrecalcs : bool ) : bool
  7025.     {
  7026.         var playerHasBlockingBuffs  : bool;
  7027.         var sourceActor             : CActor;
  7028.         var targetEntity            : CEntity;
  7029.         var targetActor             : CActor;
  7030.         var targetNPC               : CNewNPC;
  7031.         var sourcePosition          : Vector;
  7032.         var targetPosition          : Vector;
  7033.         var direction               : Vector;
  7034.         var sourceToTargetDist      : float;
  7035.         var sourceCapsuleRadius     : float;
  7036.         var mpac                    : CMovingPhysicalAgentComponent;
  7037.        
  7038.         var coneDistSq              : float;
  7039.         var knockDownCheckDistSq    : float;
  7040.         var sourceToTargetAngleDist : float;
  7041.         var b                       : bool;
  7042.         var infoSourceWorldPos      : Vector;
  7043.         var infoTargetWorldPos      : Vector;
  7044.         var finishEnabled           : bool;
  7045.    
  7046.         if ( usePrecalcs )
  7047.         {
  7048.             playerHasBlockingBuffs = targetingIn.playerHasBlockingBuffs;
  7049.         }
  7050.         else
  7051.         {
  7052.             playerHasBlockingBuffs = thePlayer.HasBuff( EET_Confusion ) || thePlayer.HasBuff( EET_Hypnotized ) || thePlayer.HasBuff( EET_Blindness ) || thePlayer.HasBuff( EET_WraithBlindness );
  7053.         }      
  7054.         if ( playerHasBlockingBuffs )
  7055.         {
  7056.             return false;
  7057.         }
  7058.    
  7059.         sourceActor = info.source;
  7060.         targetEntity = info.targetEntity;
  7061.         if ( !sourceActor || !targetEntity )
  7062.         {
  7063.             return false;
  7064.         }
  7065.        
  7066.         targetActor = (CActor)targetEntity;
  7067.  
  7068.         // "can be targeted" check
  7069.         if ( info.canBeTargetedCheck && !targetActor.CanBeTargeted() )
  7070.         {
  7071.             return false;
  7072.         }
  7073.        
  7074.         // visibility check
  7075.         if ( info.invisibleCheck && !targetActor.GetGameplayVisibility() )
  7076.         {
  7077.             return false;
  7078.         }
  7079.    
  7080.         sourcePosition = sourceActor.GetWorldPosition();
  7081.         targetPosition = targetEntity.GetWorldPosition();
  7082.                
  7083.         if ( targetActor )
  7084.         {
  7085.             { // do not target mounted horses
  7086.                 targetNPC = (CNewNPC)targetActor;
  7087.                 if ( targetNPC )
  7088.                 {
  7089.                     if ( targetNPC.IsHorse() && !targetNPC.GetHorseComponent().IsDismounted() )
  7090.                     {
  7091.                         return false;
  7092.                     }
  7093.                 }
  7094.             }
  7095.         }
  7096.            
  7097.         if ( info.distCheck || info.knockDownCheck )
  7098.         {          
  7099.             if ( usePrecalcs )
  7100.             {
  7101.                 if ( targetActor )
  7102.                 {
  7103.                     // radius is taken form the first actor
  7104.                     sourceToTargetDist = Distance2DBetweenCapsuleAndPoint( targetActor, sourceActor ) - targetingPrecalcs.playerRadius;
  7105.                 }
  7106.                 else
  7107.                 {
  7108.                     sourceToTargetDist = VecDistance2D( sourcePosition, targetPosition ) - targetingPrecalcs.playerRadius;
  7109.                 }          
  7110.             }
  7111.             else
  7112.             {
  7113.                 if ( targetActor )
  7114.                 {
  7115.                     sourceToTargetDist = Distance2DBetweenCapsules( sourceActor, targetActor );
  7116.                 }
  7117.                 else
  7118.                 {
  7119.                     sourceToTargetDist = Distance2DBetweenCapsuleAndPoint( sourceActor, targetEntity );
  7120.                 }
  7121.             }
  7122.         }
  7123.  
  7124.         // distance check
  7125.         if ( info.distCheck )
  7126.         {
  7127.             if ( sourceToTargetDist >= info.coneDist )
  7128.             {
  7129.                 return false;
  7130.             }
  7131.         }
  7132.  
  7133.         // prepare source to target direction if needed
  7134.         if ( info.coneCheck || info.rsHeadingCheck )
  7135.         {
  7136.             direction = VecNormalize2D( targetPosition - sourcePosition );
  7137.         }
  7138.        
  7139.         // cone check
  7140.         if ( info.coneCheck )
  7141.         {
  7142.             if ( VecDot2D( direction, info.coneHeadingVector ) < info.coneHalfAngleCos )
  7143.             {
  7144.                 return false;
  7145.             }
  7146.         }
  7147.        
  7148.         // heading cone check
  7149.         if ( info.rsHeadingCheck )
  7150.         {
  7151.             if ( usePrecalcs )
  7152.             {
  7153.                 if ( VecDot2D( direction, targetingIn.lookAtDirection ) < info.rsHeadingLimitCos )
  7154.                 {
  7155.                     return false;
  7156.                 }
  7157.             }
  7158.             else
  7159.             {
  7160.                 if ( VecDot2D( direction, VecNormalize2D( GetLookAtPosition() - sourcePosition ) ) < info.rsHeadingLimitCos )
  7161.                 {
  7162.                     return false;
  7163.                 }
  7164.             }
  7165.         }
  7166.                
  7167.         // "in frame" check
  7168.         if ( info.inFrameCheck && !WasVisibleInScaledFrame( targetEntity, info.frameScaleX, info.frameScaleY ) )
  7169.         {
  7170.             return false;
  7171.         }
  7172.        
  7173.         // navmesh check
  7174.         if ( info.navMeshCheck && !IsSwimming() )
  7175.         {
  7176.             sourceCapsuleRadius = 0.1f;
  7177.             if ( usePrecalcs )
  7178.             {
  7179.                 sourceCapsuleRadius = targetingPrecalcs.playerRadius;
  7180.             }
  7181.             else
  7182.             {
  7183.                 mpac = (CMovingPhysicalAgentComponent)sourceActor.GetMovingAgentComponent();
  7184.                 if ( mpac )
  7185.                 {
  7186.                     sourceCapsuleRadius = mpac.GetCapsuleRadius();
  7187.                 }
  7188.             }
  7189.             if ( !theGame.GetWorld().NavigationLineTest( sourcePosition, targetPosition, sourceCapsuleRadius ) )
  7190.             {
  7191.                 return false;
  7192.             }
  7193.         }
  7194.        
  7195.         // knockdown check
  7196.         if ( info.knockDownCheck )
  7197.         {
  7198.             // if actor is not alive
  7199.             if ( targetActor && !targetActor.IsAlive() )
  7200.             {
  7201.                 // and contains enabled "Finish" interaction
  7202.                 finishEnabled = targetActor.GetComponent( 'Finish' ).IsEnabled();
  7203.                 if ( finishEnabled )
  7204.                 {
  7205.                     // and is contained in finishable enemies list
  7206.                     if ( finishableEnemiesList.Contains( targetActor ) )
  7207.                     {
  7208.                         // and is too far to "finish" -> we cannot target it
  7209.                         if ( sourceToTargetDist >= info.knockDownCheckDist )
  7210.                         {
  7211.                             return false;
  7212.                         }                      
  7213.                     }
  7214.                 }
  7215.             }              
  7216.         }
  7217.        
  7218.         return true;
  7219.     }
  7220.    
  7221.     public function CanBeTargetedIfSwimming( actor : CActor, optional usePrecalcs : bool ) : bool
  7222.     {
  7223.         var subDepth    : float;
  7224.         var isDiving    : bool;
  7225.    
  7226.         if ( !actor )
  7227.         {
  7228.             return false;
  7229.         }
  7230.        
  7231.         if ( usePrecalcs )
  7232.         {
  7233.             isDiving = targetingIn.isDiving;
  7234.         }
  7235.         else
  7236.         {
  7237.             isDiving = IsSwimming() && OnCheckDiving();
  7238.         }
  7239.    
  7240.         subDepth = ((CMovingPhysicalAgentComponent)actor.GetMovingAgentComponent()).GetSubmergeDepth();
  7241.                
  7242.         if ( isDiving )
  7243.         {
  7244.             return ( subDepth < -1.0f );
  7245.         }
  7246.         else
  7247.         {
  7248.             return ( subDepth >= -1.0f );
  7249.         }
  7250.     }
  7251.    
  7252.     /*
  7253.     public function IsEntityTargetable( source : CActor, targetEntity : CGameplayEntity, coneCheck : bool, coneAngle, coneDist, coneHeading : float, distCheck, invisibleCheck, navMeshCheck : bool, inFrameCheck : bool, frameScaleX : float, frameScaleY : float, knockDownCheck : bool, knockDownCheckDist : float, rsHeadingCheck : bool, rsHeading : float, rsHeadingLimit : float) : bool
  7254.     {
  7255.         var targetActor             : CActor;
  7256.         var targetNPC               : CNewNPC;
  7257.         var direction               : Vector;
  7258.         var sourceToTargetDist      : float;
  7259.         var coneDistSq              : float;
  7260.         var sourceCapsuleRadius     : float;
  7261.         var knockDownCheckDistSq    : float;
  7262.         var sourceToTargetAngleDist : float;
  7263.         var b                       : bool;
  7264.         var targetsHorse            : W3HorseComponent;
  7265.            
  7266.         direction = VecNormalize2D( targetEntity.GetWorldPosition() - source.GetWorldPosition() );
  7267.         targetActor = (CActor)targetEntity;
  7268.        
  7269.         if ( distCheck )
  7270.         {
  7271.             if ( targetActor )
  7272.                 sourceToTargetDist = VecDistanceSquared( source.GetWorldPosition(), targetActor.GetNearestPointInBothPersonalSpaces( source.GetWorldPosition() ) );
  7273.             else
  7274.                 sourceToTargetDist = VecDistanceSquared( source.GetWorldPosition(), targetEntity.GetWorldPosition() );
  7275.            
  7276.             coneDistSq = coneDist * coneDist;
  7277.         }
  7278.        
  7279.         if ( knockDownCheck && targetActor )
  7280.             knockDownCheckDistSq = knockDownCheckDist * knockDownCheckDist;
  7281.            
  7282.         if ( navMeshCheck && targetActor )
  7283.             sourceCapsuleRadius = ((CMovingPhysicalAgentComponent)source.GetMovingAgentComponent()).GetCapsuleRadius();
  7284.            
  7285.         if ( rsHeadingCheck )
  7286.             sourceToTargetAngleDist = AngleDistance( VecHeading( GetLookAtPosition() - source.GetWorldPosition() ), VecHeading( targetEntity.GetWorldPosition() - source.GetWorldPosition() ) );
  7287.        
  7288.         // do not target mounted horses
  7289.         if(targetActor)
  7290.         {
  7291.             targetNPC = (CNewNPC)targetActor;
  7292.             if(targetNPC)
  7293.             {
  7294.                 targetsHorse = (W3HorseComponent)targetNPC.GetHorseComponent();
  7295.                 if(targetsHorse && targetsHorse.IsNotBeingUsed() )
  7296.                     return false;
  7297.             }
  7298.         }  
  7299.        
  7300.         b = !coneCheck || AbsF( AngleDistance( coneHeading, VecHeading( direction ) ) ) < ( coneAngle * 0.5 );
  7301.         b = b && ( !distCheck || sourceToTargetDist < coneDistSq );
  7302.         b = b && ( !invisibleCheck || targetActor.GetGameplayVisibility() );
  7303.         b = b && ( !navMeshCheck || (!IsSwimming() && theGame.GetWorld().NavigationLineTest( source.GetWorldPosition(), targetActor.GetWorldPosition(), sourceCapsuleRadius ) ) );
  7304.         b = b && ( !inFrameCheck || WasVisibleInScaledFrame( targetEntity, frameScaleX, frameScaleY ) );
  7305.         b = b && ( !rsHeadingCheck || ( rsHeading >= 0 && sourceToTargetAngleDist < 0 && sourceToTargetAngleDist >= ( rsHeadingLimit * -1 ) ) || ( rsHeading < 0 && sourceToTargetAngleDist >= 0 && sourceToTargetAngleDist <= rsHeadingLimit ) );
  7306.         b = b && ( !knockDownCheck || !targetActor.GetComponent( 'Finish' ).IsEnabled() || ( targetActor.GetComponent( 'Finish' ).IsEnabled() && sourceToTargetDist < knockDownCheckDistSq ) );
  7307.  
  7308.         if ( b )
  7309.             return true;
  7310.         else
  7311.             return false;
  7312.     }
  7313.     */ 
  7314.     private function FilterActors( out targets : array<CActor>, out onlyThreatsReturned : bool, optional usePrecalcs : bool )
  7315.     {
  7316.         var i                               : int;
  7317.         var size                            : int;
  7318.         var foundThreat                     : bool;
  7319.         var foundNonThreat                  : bool;
  7320.         var threatsCount                    : int;
  7321.         var tmpActor                        : CActor;
  7322.        
  7323.         foundThreat = false;
  7324.         foundNonThreat = false;
  7325.        
  7326.         size = targets.Size();
  7327.         i = 0;
  7328.         threatsCount = 0;
  7329.        
  7330.         // after that loop first "threatsCount" targets will be "threat"
  7331.         for ( i = 0; i < size; i+=1 )
  7332.         {
  7333.             if( IsThreat( targets[ i ], usePrecalcs ) )
  7334.             {
  7335.                 foundThreat = true;
  7336.                 if ( i != threatsCount )
  7337.                 {
  7338.                     tmpActor = targets[ i ];
  7339.                     targets[ i ] = targets[ threatsCount ];
  7340.                     targets[ threatsCount ] = tmpActor;
  7341.                 }
  7342.                 threatsCount += 1;
  7343.             }
  7344.             else
  7345.             {
  7346.                 foundNonThreat = true;
  7347.             }
  7348.         }
  7349.        
  7350.         if ( foundThreat )
  7351.         {
  7352.             onlyThreatsReturned = true;
  7353.             if ( foundNonThreat )
  7354.             {
  7355.                 targets.Resize( threatsCount );
  7356.             }
  7357.         }
  7358.     }  
  7359.    
  7360.     private function InternalFindTargetsInCone( out targets : array< CActor >, out outHeadingVector : Vector, optional usePrecalcs : bool )
  7361.     {
  7362.         var size, i                         : int;
  7363.         var coneHalfAngleDot                : float;
  7364.         var coneHeading                     : float;
  7365.         var coneHeadingVector               : Vector;
  7366.         var position                        : Vector;
  7367.         var direction                       : Vector;
  7368.         var onlyThreatTargetsFound          : bool;
  7369.        
  7370.         targets.Clear();
  7371.         GetVisibleEnemies( targets );
  7372.        
  7373.         //Include enemies that are technically dead, but can be finished off
  7374.         for( i = 0; i < finishableEnemiesList.Size() ; i+=1 )
  7375.         {
  7376.             if ( !targets.Contains( finishableEnemiesList[i] ) )
  7377.             {
  7378.                 targets.PushBack( finishableEnemiesList[i] );
  7379.             }
  7380.         }      
  7381.  
  7382.         onlyThreatTargetsFound = false;
  7383.         FilterActors( targets, onlyThreatTargetsFound, true );
  7384.            
  7385.         if ( IsCombatMusicEnabled() && targets.Size() > 0 && !onlyThreatTargetsFound && !IsThreat( targets[0], usePrecalcs ) )
  7386.         {
  7387.             targets.Clear();
  7388.         }
  7389.        
  7390.         coneHeading = 0.0f;
  7391.         coneHalfAngleDot = 0.0f;
  7392.         if ( ( orientationTarget == OT_Camera ) || ( orientationTarget == OT_CameraOffset ) )
  7393.         {
  7394.             if ( usePrecalcs )
  7395.             {
  7396.                 coneHeading = targetingPrecalcs.cameraHeading;
  7397.             }
  7398.             else
  7399.             {
  7400.                 coneHeading = theGame.GetGameCamera().GetHeading();
  7401.             }
  7402.             coneHalfAngleDot = 0.5f; // = CosF( Deg2Rad( 120.f * 0.5f ) ); - Just use calculator... why not? this is constant.
  7403.         }
  7404.         else
  7405.         {
  7406.             if ( IsSwimming() )
  7407.             {
  7408.                 if ( usePrecalcs )
  7409.                 {
  7410.                     coneHeading = targetingPrecalcs.cameraHeading;
  7411.                 }
  7412.                 else
  7413.                 {
  7414.                     coneHeading = theGame.GetGameCamera().GetHeading();
  7415.                 }
  7416.                 coneHalfAngleDot = 0.17364817766f; // = CosF( Deg2Rad( 160.f * 0.5f ) );
  7417.             }
  7418.             else if ( bLAxisReleased )
  7419.             {
  7420.                 if( IsInCombatAction() )
  7421.                 {
  7422.                     coneHeading = GetCombatActionHeading();
  7423.                 }
  7424.                 else
  7425.                 {
  7426.                     if ( ShouldUsePCModeTargeting() )
  7427.                         coneHeading = theGame.GetGameCamera().GetHeading();
  7428.                     else
  7429.                         coneHeading = cachedRawPlayerHeading;
  7430.                 }
  7431.                    
  7432.                 if ( IsInCombat() )
  7433.                 {
  7434.                     if ( ShouldUsePCModeTargeting() )
  7435.                         coneHalfAngleDot = -1; // = CosF( Deg2Rad( 360.0f * 0.5f ) )
  7436.                     else
  7437.                         coneHalfAngleDot = 0.17364817766f; // = CosF( Deg2Rad( 160.f * 0.5f ) );
  7438.                 }
  7439.                 else
  7440.                 {
  7441.                     coneHalfAngleDot = -1.0f;
  7442.                 }
  7443.             }
  7444.             else
  7445.             {
  7446.                 if( IsInCombatAction() )
  7447.                 {
  7448.                     coneHeading = GetCombatActionHeading();
  7449.                 }
  7450.                 else
  7451.                 {
  7452.                     if ( ShouldUsePCModeTargeting() )
  7453.                         coneHeading = theGame.GetGameCamera().GetHeading();
  7454.                     else
  7455.                         coneHeading = cachedRawPlayerHeading;
  7456.                 }
  7457.                
  7458.                 if ( ShouldUsePCModeTargeting() )
  7459.                     coneHalfAngleDot = -1; // = CosF( Deg2Rad( 360.0f * 0.5f ) )
  7460.                 else               
  7461.                     coneHalfAngleDot = 0.17364817766f; // = CosF( Deg2Rad( 160.f * 0.5f ) );
  7462.             }
  7463.  
  7464.             coneHeadingVector = VecFromHeading( coneHeading );
  7465.             position = this.GetWorldPosition();
  7466.  
  7467.             for ( i = targets.Size() - 1; i >= 0; i -= 1 )
  7468.             {
  7469.                 if ( !targets[i] )
  7470.                 {
  7471.                     targets.EraseFast(i);
  7472.                     continue;
  7473.                 }
  7474.                    
  7475.                 direction = VecNormalize2D( targets[i].GetWorldPosition() - position );
  7476.                
  7477.                 if ( VecDot2D( coneHeadingVector, direction ) < coneHalfAngleDot )
  7478.                 {
  7479.                     targets.EraseFast( i );
  7480.                 }
  7481.             }
  7482.         }
  7483.        
  7484.         outHeadingVector = coneHeadingVector;
  7485.     }
  7486.    
  7487.     ///////////////////////////////////////////////////////////////////////////
  7488.     // (new) targeting
  7489.    
  7490.     function InitTargeting()
  7491.     {
  7492.         var consts : SR4PlayerTargetingConsts;
  7493.        
  7494.         if ( !targeting )
  7495.         {
  7496.             targeting = new CR4PlayerTargeting in this;
  7497.         }
  7498.         if ( targeting )
  7499.         {
  7500.             consts.softLockDistance = this.softLockDist;
  7501.             consts.softLockFrameSize = this.softLockFrameSize;
  7502.             targeting.SetConsts( consts );
  7503.         }      
  7504.     }
  7505.    
  7506.     function PrepareTargetingIn( actionCheck : bool, bufferActionType : EBufferActionType, actionInput : bool )
  7507.     {
  7508.         var coneDist : float;
  7509.        
  7510.         if ( actionCheck && bufferActionType == EBAT_ItemUse )
  7511.         {
  7512.             coneDist = findMoveTargetDist;
  7513.         }
  7514.         else if ( IsSwimming() )
  7515.         {
  7516.             coneDist = theGame.params.MAX_THROW_RANGE;
  7517.         }
  7518.         else if ( ( GetPlayerCombatStance() == PCS_AlertNear ) && ( ( playerMoveType == PMT_Walk ) || ( playerMoveType == PMT_Idle ) ) )
  7519.         {
  7520.             coneDist = softLockDist;
  7521.         }
  7522.         else
  7523.         {
  7524.             coneDist = findMoveTargetDist;
  7525.         }
  7526.    
  7527.         targetingIn.canFindTarget                   = this.bCanFindTarget;
  7528.         targetingIn.playerHasBlockingBuffs          = thePlayer.HasBuff( EET_Confusion ) || thePlayer.HasBuff( EET_Hypnotized ) || thePlayer.HasBuff( EET_Blindness ) || thePlayer.HasBuff( EET_WraithBlindness );
  7529.         targetingIn.isHardLockedToTarget            = this.IsHardLockEnabled();
  7530.         targetingIn.isActorLockedToTarget           = this.IsActorLockedToTarget();
  7531.         targetingIn.isCameraLockedToTarget          = this.IsCameraLockedToTarget();
  7532.         targetingIn.actionCheck                     = actionCheck;
  7533.         targetingIn.actionInput                     = actionInput;
  7534.         targetingIn.isInCombatAction                = this.IsInCombatAction();
  7535.         targetingIn.isLAxisReleased                 = this.bLAxisReleased;
  7536.         targetingIn.isLAxisReleasedAfterCounter     = this.lAxisReleasedAfterCounter;
  7537.         targetingIn.isLAxisReleasedAfterCounterNoCA = this.lAxisReleasedAfterCounterNoCA;
  7538.         targetingIn.lastAxisInputIsMovement         = this.lastAxisInputIsMovement;
  7539.         targetingIn.isAiming                        = this.playerAiming.GetCurrentStateName() == 'Aiming';
  7540.         targetingIn.isSwimming                      = this.IsSwimming();
  7541.         targetingIn.isDiving                        = this.IsSwimming() && OnCheckDiving();
  7542.         targetingIn.isThreatened                    = this.IsThreatened();
  7543.         targetingIn.isCombatMusicEnabled            = this.IsCombatMusicEnabled();
  7544.         targetingIn.isPcModeEnabled                 = this.IsPCModeEnabled();
  7545.         targetingIn.isInParryOrCounter              = this.isInParryOrCounter;
  7546.         targetingIn.shouldUsePcModeTargeting        = this.ShouldUsePCModeTargeting();
  7547.         targetingIn.bufferActionType                = bufferActionType;
  7548.         targetingIn.orientationTarget               = this.GetOrientationTarget();
  7549.         targetingIn.coneDist                        = coneDist; // computed few lines above
  7550.         targetingIn.findMoveTargetDist              = this.findMoveTargetDist;
  7551.         targetingIn.cachedRawPlayerHeading          = this.cachedRawPlayerHeading;
  7552.         targetingIn.combatActionHeading             = this.GetCombatActionHeading();
  7553.         targetingIn.rawPlayerHeadingVector          = VecFromHeading( this.rawPlayerHeading );
  7554.         targetingIn.lookAtDirection                 = VecNormalize2D( this.GetLookAtPosition() - GetWorldPosition() );
  7555.         targetingIn.moveTarget                      = this.moveTarget;
  7556.         targetingIn.aimingTarget                    = this.playerAiming.GetAimedTarget();  
  7557.         targetingIn.displayTarget                   = (CActor)this.displayTarget;
  7558.         targetingIn.finishableEnemies               = this.finishableEnemiesList;
  7559.         targetingIn.hostileEnemies                  = this.hostileEnemies;
  7560.         targetingIn.defaultSelectionWeights         = ProcessSelectionWeights();
  7561.     }
  7562.    
  7563.     function ResetTargetingOut()
  7564.     {
  7565.         targetingOut.target                     = NULL;
  7566.         targetingOut.result                     = false;
  7567.         targetingOut.confirmNewTarget           = false;
  7568.         targetingOut.forceDisableUpdatePosition = false;   
  7569.     }
  7570.    
  7571.     function MakeFindTargetPrecalcs()
  7572.     {
  7573.         var mpac : CMovingPhysicalAgentComponent;
  7574.    
  7575.         targetingPrecalcs.playerPosition        = thePlayer.GetWorldPosition();
  7576.         targetingPrecalcs.playerHeading         = thePlayer.GetHeading();
  7577.         targetingPrecalcs.playerHeadingVector   = thePlayer.GetHeadingVector();
  7578.         targetingPrecalcs.playerHeadingVector.Z = 0;
  7579.         targetingPrecalcs.playerHeadingVector   = VecNormalize2D( targetingPrecalcs.playerHeadingVector );
  7580.        
  7581.         targetingPrecalcs.playerRadius = 0.5f;
  7582.         mpac = (CMovingPhysicalAgentComponent)thePlayer.GetMovingAgentComponent();
  7583.         if ( mpac )
  7584.         {
  7585.             targetingPrecalcs.playerRadius = mpac.GetCapsuleRadius();
  7586.         }
  7587.        
  7588.         targetingPrecalcs.cameraPosition        = theCamera.GetCameraPosition();
  7589.         targetingPrecalcs.cameraDirection       = theCamera.GetCameraDirection();
  7590.         targetingPrecalcs.cameraHeadingVector   = targetingPrecalcs.cameraDirection;
  7591.         targetingPrecalcs.cameraHeadingVector.Z = 0;
  7592.         targetingPrecalcs.cameraHeadingVector   = VecNormalize2D( targetingPrecalcs.cameraHeadingVector );         
  7593.         targetingPrecalcs.cameraHeading         = VecHeading( targetingPrecalcs.cameraHeadingVector );             
  7594.     }
  7595.    
  7596.     public function GetForceDisableUpdatePosition() : bool
  7597.     {
  7598.         return targetingOut.forceDisableUpdatePosition;
  7599.     }
  7600.    
  7601.     public function SetUseNativeTargeting( use : bool )
  7602.     {
  7603.         useNativeTargeting = use;
  7604.     }
  7605.  
  7606.     // W3EE - Begin
  7607.     protected function FindTargetSimple()
  7608.     {
  7609.         var i                       : int;
  7610.         var currentTarget           : CActor;
  7611.         var targets                 : array< CActor >;
  7612.         var potentialFriendlyTargets: array< CActor >;
  7613.         var playerPosition          : Vector;
  7614.         var targetingInfo           : STargetingInfo;
  7615.         var bestRank                : float;
  7616.         var rank                    : float;
  7617.         var curTargetRank           : float;
  7618.         var newTarget               : CActor;
  7619.         var inverseDist             : float;
  7620.         var cameraAngleDiff         : float;
  7621.         var movementAngleDiff       : float;
  7622.         var facingAngleDiff         : float;
  7623.         var targetHeadingVector     : Vector;
  7624.         var cameraWeight            : float;
  7625.         var movementWeight          : float;
  7626.         var facingWeight            : float;
  7627.         var attackHysModifier       : float;
  7628.         var targetHysteresis        : float;
  7629.         var precull                 : int;
  7630.         var igconfig                : CInGameConfigWrapper;
  7631.        
  7632.         ResetTargetingOut();
  7633.        
  7634.         igconfig = theGame.GetInGameConfigWrapper();
  7635.        
  7636.         cameraWeight = StringToFloat(igconfig.GetVarValue('EnhancedTargeting', 'ETCameraWeight'));
  7637.         movementWeight = StringToFloat(igconfig.GetVarValue('EnhancedTargeting', 'ETMovementWeight'));
  7638.         facingWeight = StringToFloat(igconfig.GetVarValue('EnhancedTargeting', 'ETFacingWeight'));
  7639.         targetHysteresis = StringToFloat(igconfig.GetVarValue('EnhancedTargeting', 'ETHysteresis'));
  7640.        
  7641.         targetingInfo.inFrameCheck = igconfig.GetVarValue('EnhancedTargeting', 'ETInFrameCheck');
  7642.        
  7643.         attackHysModifier = 1.5f;
  7644.        
  7645.         currentTarget = GetTarget();
  7646.         playerPosition = this.GetWorldPosition();
  7647.        
  7648.         targetingInfo.source = this;
  7649.         targetingInfo.canBeTargetedCheck = true;
  7650.         targetingInfo.coneCheck = false;
  7651.         targetingInfo.coneHalfAngleCos = 0.0f;
  7652.         targetingInfo.coneHeadingVector = Vector( 0.0f, 1.0f, 0.0f );
  7653.         targetingInfo.distCheck = true;
  7654.         targetingInfo.invisibleCheck = true;
  7655.         targetingInfo.frameScaleX = softLockFrameSize;
  7656.         targetingInfo.frameScaleY = softLockFrameSize;
  7657.         targetingInfo.knockDownCheck = false;
  7658.         targetingInfo.knockDownCheckDist = 1.0f;
  7659.         targetingInfo.rsHeadingCheck = false;
  7660.         targetingInfo.rsHeadingLimitCos = 1.0f;
  7661.        
  7662.         if ( IsCombatMusicEnabled() )
  7663.             targetingInfo.coneDist = softLockDist;
  7664.         else if ( IsSwimming() )
  7665.             targetingInfo.coneDist = theGame.params.MAX_THROW_RANGE;
  7666.         else
  7667.             targetingInfo.coneDist = findMoveTargetDist;
  7668.        
  7669.         if ( currentTarget && IsHardLockEnabled() && currentTarget.IsAlive() && !currentTarget.IsKnockedUnconscious() )
  7670.         {
  7671.             if ( VecDistanceSquared( playerPosition, currentTarget.GetWorldPosition() ) > 50.f * 50.0f )
  7672.             {
  7673.                 HardLockToTarget( false );
  7674.             }
  7675.             else
  7676.             {
  7677.                 targetingOut.target = currentTarget;
  7678.                 targetingOut.result = true;
  7679.                 return;
  7680.             }
  7681.         }
  7682.        
  7683.         if ( (thePlayer.HasBuff( EET_Confusion ) || thePlayer.HasBuff( EET_Hypnotized ) || thePlayer.HasBuff( EET_Blindness ) || thePlayer.HasBuff( EET_WraithBlindness )) || !bCanFindTarget )
  7684.             return;
  7685.        
  7686.         if (this.playerAiming.GetCurrentStateName() == 'Aiming')
  7687.         {
  7688.             newTarget = this.playerAiming.GetAimedTarget();
  7689.            
  7690.             if (newTarget)
  7691.             {
  7692.                 targetingOut.target = newTarget;
  7693.                 targetingOut.result = true;
  7694.                 targetingOut.confirmNewTarget = true;
  7695.                 return;
  7696.             }
  7697.         }
  7698.        
  7699.         GetVisibleEnemies( targets );
  7700.        
  7701.         for( i = 0; i < finishableEnemiesList.Size(); i += 1 )
  7702.         {
  7703.             if ( !targets.Contains( finishableEnemiesList[i] ) )
  7704.             {
  7705.                 targets.PushBack( finishableEnemiesList[i] );
  7706.             }
  7707.         }
  7708.        
  7709.         precull = targets.Size();
  7710.        
  7711.         for( i = targets.Size() - 1; i >= 0; i -= 1 )
  7712.         {
  7713.             targetingInfo.targetEntity = targets[i];
  7714.            
  7715.             if ( IsSwimming() && !CanBeTargetedIfSwimming( targets[i], false ) )
  7716.                 targets.EraseFast( i );
  7717.            
  7718.             if ( !IsEntityTargetable( targetingInfo, false ) )
  7719.                 targets.EraseFast( i );
  7720.            
  7721.             if ( !IsThreat( targets[i], false ) && !targets[i].HasTag('animal') )
  7722.             {
  7723.                 potentialFriendlyTargets.PushBack(targets[i]);
  7724.                 targets.EraseFast( i );
  7725.             }
  7726.         }
  7727.        
  7728.         bestRank = 0.0f;
  7729.         curTargetRank = -100.0f;
  7730.         newTarget = NULL;
  7731.        
  7732.         if (targets.Size() > 0)
  7733.         {
  7734.             for( i = 0; i < targets.Size(); i += 1 )
  7735.             {
  7736.                 inverseDist = (((targetingInfo.coneDist + 2.0f) - Distance2DBetweenCapsules( this, targets[i] )) / (targetingInfo.coneDist/2.0f + 1.0f));
  7737.                
  7738.                 if (inverseDist < 0.1f)
  7739.                     inverseDist == 0.1f;
  7740.                
  7741.                 targetHeadingVector = VecNormalize(targets[i].GetWorldPosition() - playerPosition);
  7742.                
  7743.                 cameraAngleDiff = AbsF( Rad2Deg( AcosF( VecDot2D( VecFromHeading(theGame.GetGameCamera().GetHeading()), targetHeadingVector ) ) ) );
  7744.                 movementAngleDiff = AbsF( Rad2Deg( AcosF( VecDot2D( VecFromHeading(cachedRawPlayerHeading), targetHeadingVector ) ) ) );
  7745.                 facingAngleDiff = AbsF( Rad2Deg( AcosF( VecDot2D( GetHeadingVector(), targetHeadingVector ) ) ) );
  7746.                
  7747.                 rank = ((180.0f - cameraAngleDiff) / 180.0f) * inverseDist * cameraWeight;
  7748.                 rank += ((180.0f - facingAngleDiff) / 180.0f) * inverseDist * facingWeight;
  7749.                
  7750.                 if ( lastAxisInputIsMovement )
  7751.                     rank += ((180.0f - movementAngleDiff) / 180.0f) * inverseDist * movementWeight;
  7752.                
  7753.                 if (targets[i] == currentTarget)
  7754.                     curTargetRank = rank;
  7755.                
  7756.                 if ( rank > bestRank )
  7757.                 {
  7758.                     newTarget = targets[i];
  7759.                     bestRank = rank;
  7760.                 }
  7761.             }
  7762.            
  7763.             if ( IsInCombatAction_Attack() )
  7764.                 targetHysteresis *= attackHysModifier;
  7765.            
  7766.             if ( newTarget && ( (newTarget == currentTarget) || (curTargetRank < 0) || ((curTargetRank > 0) && (curTargetRank * targetHysteresis < bestRank)) ) )
  7767.             {
  7768.                 targetingOut.result = true;
  7769.                 targetingOut.target = newTarget;
  7770.                
  7771.                 if ( !currentTarget || (currentTarget && newTarget != currentTarget) )
  7772.                 {
  7773.                     targetingOut.confirmNewTarget = true;
  7774.                 }
  7775.             }
  7776.         }
  7777.         else
  7778.         {
  7779.             targetingOut.target = NULL;
  7780.            
  7781.             if (potentialFriendlyTargets.Size() > 0)
  7782.             {
  7783.                 for( i = potentialFriendlyTargets.Size() - 1; i >= 0; i -= 1 )
  7784.                 {
  7785.                     if ( potentialFriendlyTargets[i].HasTag(theGame.params.TAG_AXIIABLE_LOWER_CASE) || potentialFriendlyTargets[i].HasTag(theGame.params.TAG_AXIIABLE ) )
  7786.                         targetingOut.target = potentialFriendlyTargets[i];
  7787.                 }
  7788.             }
  7789.            
  7790.             targetingOut.result = true;
  7791.             targetingOut.confirmNewTarget = true;
  7792.         }
  7793.     }
  7794.     // W3EE - End
  7795.    
  7796.     protected function FindTarget( optional actionCheck : bool, optional action : EBufferActionType, optional actionInput : bool ) : CActor
  7797.     {
  7798.         if ( IsCombatMusicEnabled() && !IsInCombat() && reachableEnemyWasTooFar )
  7799.         {
  7800.             playerMode.UpdateCombatMode();
  7801.         }
  7802.        
  7803.         PrepareTargetingIn( actionCheck, action, actionInput );
  7804.        
  7805.         // W3EE - Begin
  7806.         if ( !Options().LockOnModeSF() && Options().LockOn() )
  7807.         {
  7808.             FindTargetSimple();
  7809.         }
  7810.         else
  7811.         if ( useNativeTargeting )
  7812.         {
  7813.             targeting.BeginFindTarget( targetingIn );
  7814.             targeting.FindTarget();
  7815.             targeting.EndFindTarget( targetingOut );
  7816.         }
  7817.         else
  7818.         {
  7819.             UpdateVisibleActors();
  7820.             MakeFindTargetPrecalcs();
  7821.             ResetTargetingOut();
  7822.             FindTarget_Scripted();
  7823.         }
  7824.         // W3EE - End
  7825.        
  7826.         if ( targetingOut.result )
  7827.         {
  7828.             if ( targetingOut.confirmNewTarget )
  7829.             {
  7830.                 ConfirmNewTarget( targetingOut.target );
  7831.             }
  7832.             return targetingOut.target;
  7833.         }
  7834.         return NULL;
  7835.     }
  7836.        
  7837.     protected function FindTarget_Scripted()
  7838.     {
  7839.         var currentTarget                   : CActor;
  7840.         var newTarget                       : CActor;
  7841.         var selectedTarget                  : CActor;
  7842.         var displayTargetActor              : CActor;
  7843.         var playerPosition                  : Vector;
  7844.         var playerHeadingVector             : Vector;
  7845.         var cameraPosition                  : Vector;
  7846.         var cameraHeadingVector             : Vector;
  7847.         var selectionHeadingVector          : Vector;
  7848.         var targetingInfo                   : STargetingInfo;
  7849.         var selectionWeights                : STargetSelectionWeights;
  7850.         var targets                         : array< CActor >;
  7851.         var isMoveTargetTargetable          : bool;    
  7852.         var targetChangeFromActionInput     : bool;
  7853.         var retainCurrentTarget             : bool;
  7854.        
  7855.         // caching data
  7856.        
  7857.         playerPosition = this.GetWorldPosition();
  7858.         playerHeadingVector = targetingPrecalcs.playerHeadingVector;           
  7859.         cameraPosition = theCamera.GetCameraPosition();
  7860.         cameraHeadingVector = targetingPrecalcs.cameraHeadingVector;
  7861.        
  7862.         currentTarget = GetTarget();       
  7863.         if ( currentTarget )
  7864.         {
  7865.             if ( IsHardLockEnabled() && currentTarget.IsAlive() && !currentTarget.IsKnockedUnconscious() )
  7866.             {
  7867.                 if ( VecDistanceSquared( playerPosition, currentTarget.GetWorldPosition() ) > 50.f * 50.0f )
  7868.                 {
  7869.                     HardLockToTarget( false );
  7870.                 }
  7871.                 else
  7872.                 {
  7873.                     targetingOut.target = currentTarget;
  7874.                     targetingOut.result = true;
  7875.                     return;
  7876.                 }
  7877.             }              
  7878.             GetVisualDebug().AddSphere('target', 1.0f, currentTarget.GetWorldPosition(), true, Color( 255, 255, 0 ), 1.0f );
  7879.         }
  7880.  
  7881.         if ( bCanFindTarget && !IsActorLockedToTarget() )
  7882.         {      
  7883.             if ( !targetingIn.playerHasBlockingBuffs )
  7884.             {
  7885.                 InternalFindTargetsInCone( targets, selectionHeadingVector, true );
  7886.             }
  7887.            
  7888.             targetingInfo.source                = this;
  7889.             targetingInfo.canBeTargetedCheck    = true;
  7890.             targetingInfo.coneCheck             = false;
  7891.             targetingInfo.coneHalfAngleCos      = 1.0f;
  7892.             targetingInfo.coneDist              = targetingIn.coneDist;
  7893.             targetingInfo.distCheck             = true;
  7894.             targetingInfo.invisibleCheck        = true;
  7895.             targetingInfo.navMeshCheck          = false; //true;
  7896.            
  7897.             if ( ShouldUsePCModeTargeting() )
  7898.                 targetingInfo.inFrameCheck          = false;
  7899.             else
  7900.                 targetingInfo.inFrameCheck          = true;
  7901.                
  7902.             targetingInfo.frameScaleX           = 1.0f;
  7903.             targetingInfo.frameScaleY           = 1.0f;
  7904.             targetingInfo.knockDownCheck        = false;
  7905.             targetingInfo.knockDownCheckDist    = 1.5f;
  7906.             targetingInfo.rsHeadingCheck        = false;
  7907.             targetingInfo.rsHeadingLimitCos     = 1.0f;
  7908.  
  7909.             if ( currentTarget )
  7910.             {
  7911.                 targetingInfo.targetEntity = currentTarget;
  7912.                 if ( !IsEntityTargetable( targetingInfo, true ) )
  7913.                 {
  7914.                     currentTarget = NULL;
  7915.                 }  
  7916.                 if ( currentTarget && !CanBeTargetedIfSwimming( currentTarget, true ) )
  7917.                 {
  7918.                     currentTarget = NULL;
  7919.                 }
  7920.             }
  7921.  
  7922.             isMoveTargetTargetable = false;
  7923.             if ( moveTarget )
  7924.             {
  7925.                 if ( CanBeTargetedIfSwimming( moveTarget, true ) )
  7926.                 {
  7927.                     targetingInfo.targetEntity = moveTarget;
  7928.                     targetingInfo.coneDist = findMoveTargetDist;
  7929.                     targetingInfo.inFrameCheck = false;
  7930.                     if ( IsEntityTargetable( targetingInfo, true ) )
  7931.                     {
  7932.                         isMoveTargetTargetable = true;
  7933.                     }
  7934.                 }
  7935.             }
  7936.  
  7937.             // checking "standard" cone dist again
  7938.             targetingInfo.coneDist = targetingIn.coneDist;
  7939.            
  7940.             if ( !targetingIn.playerHasBlockingBuffs )
  7941.             {
  7942.                 RemoveNonTargetable( targets, targetingInfo, selectionHeadingVector );
  7943.             }
  7944.            
  7945.             newTarget = NULL;
  7946.             if ( this.playerAiming.GetCurrentStateName() == 'Aiming' )
  7947.             {
  7948.                 newTarget = this.playerAiming.GetAimedTarget();            
  7949.                 if ( !newTarget )
  7950.                 {
  7951.                     selectionWeights.angleWeight = 1.f;
  7952.                     selectionWeights.distanceWeight = 0.f;
  7953.                     selectionWeights.distanceRingWeight = 0.f;
  7954.                    
  7955.                     selectedTarget = SelectTarget( targets, false, cameraPosition, cameraHeadingVector, selectionWeights, true );
  7956.                     newTarget = selectedTarget;            
  7957.                 }
  7958.             }
  7959.             else if ( IsSwimming() )
  7960.             {
  7961.                 selectionWeights.angleWeight = 0.9f;
  7962.                 selectionWeights.distanceWeight = 0.1f;
  7963.                 selectionWeights.distanceRingWeight = 0.f;
  7964.                
  7965.                 selectedTarget = SelectTarget( targets, true, cameraPosition, cameraHeadingVector, selectionWeights, true );       
  7966.                 newTarget = selectedTarget;
  7967.             }          
  7968.             else if ( IsThreatened() )
  7969.             {
  7970.                 // Change locked enemy when the current one becomes invisible
  7971.                 if ( IsCameraLockedToTarget() )
  7972.                 {
  7973.                     if ( currentTarget && !currentTarget.GetGameplayVisibility() )
  7974.                     {
  7975.                         ForceSelectLockTarget();
  7976.                     }
  7977.                 }          
  7978.            
  7979.                 displayTargetActor = (CActor)displayTarget;
  7980.                 selectedTarget = SelectTarget( targets, true, playerPosition, selectionHeadingVector, targetingIn.defaultSelectionWeights, true );
  7981.                    
  7982.                 if ( !selectedTarget )
  7983.                 {
  7984.                     targetingOut.forceDisableUpdatePosition = true;
  7985.                 }
  7986.                
  7987.                 targetChangeFromActionInput = targetingIn.actionInput && !lAxisReleasedAfterCounter;               
  7988.                 if ( selectedTarget &&
  7989.                      ( !IsThreat( currentTarget, true ) || ShouldUsePCModeTargeting() || ( !IsInCombatAction() && !lAxisReleasedAfterCounterNoCA ) || targetChangeFromActionInput ) )
  7990.                 {
  7991.                     newTarget = selectedTarget;
  7992.                 }
  7993.                 else if ( displayTargetActor &&
  7994.                           ( ( bLAxisReleased && !ShouldUsePCModeTargeting() )|| IsInCombatAction() ) &&
  7995.                           ( displayTargetActor.IsAlive() || finishableEnemiesList.Contains( displayTargetActor ) ) &&
  7996.                           displayTargetActor.GetGameplayVisibility() &&
  7997.                           ( IsEnemyVisible( displayTargetActor ) || finishableEnemiesList.Contains( displayTargetActor ) ) &&
  7998.                           this.CanBeTargetedIfSwimming( displayTargetActor, true ) &&
  7999.                           IsThreat( displayTargetActor, true ) &&
  8000.                           WasVisibleInScaledFrame( displayTargetActor, 1.f, 1.f ) )
  8001.                 {
  8002.                     newTarget = displayTargetActor;
  8003.                 }
  8004.                 // target closest enemy immediately when transitioning from running/sprint to walk/idle,
  8005.                 // but when you are already in walk/idle player should hit air after he kills his target, he should only target closest enemy when that enmy is within his field of vision
  8006.                 else if ( moveTarget &&
  8007.                           isMoveTargetTargetable &&
  8008.                          ( !IsInCombatAction() || isInParryOrCounter || GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Dodge || GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Roll ) )
  8009.                 {
  8010.                     newTarget = moveTarget;
  8011.                 }
  8012.                 else
  8013.                 {
  8014.                     newTarget = NULL;
  8015.                 }
  8016.             }
  8017.             else
  8018.             {
  8019.                 retainCurrentTarget = false;
  8020.                 if ( lAxisReleasedAfterCounterNoCA )
  8021.                 {
  8022.                     if ( lastAxisInputIsMovement && !this.IsSwimming())
  8023.                     {
  8024.                         selectionWeights.angleWeight = 0.375f;
  8025.                         selectionWeights.distanceWeight = 0.275f;
  8026.                         selectionWeights.distanceRingWeight = 0.35f;
  8027.                         selectedTarget = SelectTarget( targets, false, playerPosition, playerHeadingVector, selectionWeights, true );  
  8028.  
  8029.                         if ( currentTarget != selectedTarget )
  8030.                         {
  8031.                             targetingInfo.targetEntity = currentTarget;
  8032.                             if ( IsEntityTargetable( targetingInfo, true ) && currentTarget.IsAlive() )
  8033.                             {
  8034.                                 retainCurrentTarget = true;
  8035.                             }
  8036.                         }
  8037.                     }
  8038.                     else
  8039.                     {
  8040.                         selectionWeights.angleWeight = 0.75f;
  8041.                         selectionWeights.distanceWeight = 0.125f;
  8042.                         selectionWeights.distanceRingWeight = 0.125f;
  8043.                         selectedTarget = SelectTarget( targets, false, cameraPosition, cameraHeadingVector, selectionWeights, true );      
  8044.                     }          
  8045.                 }
  8046.                 else
  8047.                 {
  8048.                     selectionWeights.angleWeight = 0.6f;
  8049.                     selectionWeights.distanceWeight = 0.4f;
  8050.                     selectionWeights.distanceRingWeight = 0.f;
  8051.                     selectedTarget = SelectTarget( targets, true, playerPosition, targetingIn.rawPlayerHeadingVector, selectionWeights, true );
  8052.                 }
  8053.                
  8054.                 if ( retainCurrentTarget )
  8055.                 {
  8056.                     newTarget = currentTarget;
  8057.                 }
  8058.                 else if ( IsInCombatAction() && GetBehaviorVariable( 'isPerformingSpecialAttack' ) == 1.0f )
  8059.                 {
  8060.                     newTarget = moveTarget;
  8061.                 }
  8062.                 else if ( selectedTarget )
  8063.                 {
  8064.                     newTarget = selectedTarget;
  8065.                 }
  8066.                 else
  8067.                 {
  8068.                     newTarget = NULL;
  8069.                 }
  8070.             }  
  8071.        
  8072.             targetingOut.confirmNewTarget = true;
  8073.         }
  8074.         else
  8075.         {
  8076.             newTarget = NULL;
  8077.         }
  8078.        
  8079.         targetingOut.result = true;
  8080.         targetingOut.target = newTarget;           
  8081.     }
  8082.    
  8083.     function UpdateVisibleActors()
  8084.     {
  8085.         var i : int;
  8086.         var now : float;
  8087.        
  8088.         now = theGame.GetEngineTimeAsSeconds();
  8089.         for ( i = visibleActors.Size() - 1; i >= 0; i-=1 )
  8090.         {
  8091.             // wasn't visible for more than 1 second
  8092.             if ( ( now - visibleActorsTime[i] ) > 1.0f )
  8093.             {
  8094.                 visibleActors.EraseFast( i );
  8095.                 visibleActorsTime.EraseFast( i );
  8096.             }
  8097.         }
  8098.     }
  8099.    
  8100.     function RemoveNonTargetable( out targets : array< CActor >, out info : STargetingInfo, selectionHeadingVector : Vector )
  8101.     {
  8102.         var i                       : int;
  8103.         var cameraPosition          : Vector;
  8104.         var cameraDirection         : Vector;
  8105.         var nonCombatCheck          : bool;
  8106.         var playerToCamPlaneDist    : float;
  8107.         var targetToCamPlaneDist    : float;
  8108.        
  8109.         if ( targets.Size() == 0 )
  8110.         {
  8111.             return;
  8112.         }
  8113.        
  8114.         nonCombatCheck = bLAxisReleased && !IsInCombat();
  8115.        
  8116.         // first, let's prepare targeting info (so that we don't need to do it in each loop step)
  8117.         if ( nonCombatCheck )
  8118.         {
  8119.             info.coneHeadingVector  = targetingPrecalcs.playerHeadingVector;                   
  8120.             if ( lastAxisInputIsMovement )
  8121.             {
  8122.                 info.coneHeadingVector  = selectionHeadingVector;
  8123.                 info.invisibleCheck     = false;
  8124.                 info.coneCheck          = true;
  8125.                 info.coneHalfAngleCos   = 0.76604444311f; // = CosF( Deg2Rad( 80.0f * 0.5f ) )
  8126.             }
  8127.             else
  8128.             {
  8129.                 info.invisibleCheck = false;
  8130.                 info.frameScaleX    = 0.9f;
  8131.                 info.frameScaleY    = 0.9f;
  8132.             }
  8133.         }
  8134.         else
  8135.         {
  8136.             info.coneHeadingVector  = Vector( 0.0f, 0.0f, 0.0f );
  8137.                
  8138.             //MS: ConeCheck is false because it's already been filtered by InternalFindTargetsInCone
  8139.             if ( IsInCombat() )
  8140.             {
  8141.                 info.inFrameCheck = false;
  8142.             }
  8143.             else
  8144.             {
  8145.                 if ( !bLAxisReleased )
  8146.                 {
  8147.                     info.coneCheck          = true;
  8148.                    
  8149.                     if ( this.IsSwimming() )
  8150.                         info.coneHalfAngleCos   = -1; // = CosF( Deg2Rad( 360.0f * 0.5f ) )
  8151.                     else
  8152.                         info.coneHalfAngleCos   = 0.86602540378f; // = CosF( Deg2Rad( 60.0f * 0.5f ) )
  8153.                        
  8154.                     info.coneHeadingVector  = targetingIn.rawPlayerHeadingVector;
  8155.                 }
  8156.             }
  8157.         }
  8158.        
  8159.         cameraPosition = theCamera.GetCameraPosition();
  8160.         cameraDirection = targetingPrecalcs.cameraDirection;
  8161.         playerToCamPlaneDist = VecDot2D( cameraDirection, this.GetWorldPosition() - cameraPosition );
  8162.        
  8163.         // then, using prepared info let's filter out invalid targets
  8164.         for( i = targets.Size() - 1; i >= 0; i -= 1 )
  8165.         {  
  8166.             info.targetEntity = targets[i];
  8167.            
  8168.             if ( !CanBeTargetedIfSwimming( targets[i], true ) )
  8169.             {
  8170.                 targets.EraseFast( i );
  8171.             }
  8172.             else if ( !IsEntityTargetable( info, true ) )
  8173.             {
  8174.                 targets.EraseFast( i );
  8175.             }          
  8176.             else
  8177.             {
  8178.                 if ( nonCombatCheck && !lastAxisInputIsMovement )
  8179.                 {
  8180.                     // removing targets between camera and player
  8181.                     targetToCamPlaneDist = VecDot2D( cameraDirection, targets[i].GetWorldPosition() - cameraPosition );
  8182.                     if ( targetToCamPlaneDist < playerToCamPlaneDist )
  8183.                     {
  8184.                         targets.EraseFast( i );
  8185.                     }
  8186.                 }
  8187.             }
  8188.         }
  8189.     }
  8190.    
  8191.     var combatModeColor : Color;
  8192.     public function CombatModeDebug()
  8193.     {
  8194.         var visualDebug : CVisualDebug = GetVisualDebug();
  8195.        
  8196.         var naviQueryMsg    : string;
  8197.         var naviQueryMsg1   : string;
  8198.         var naviQueryMsg2   : string;
  8199.        
  8200.         var navSnapMsg      : string;
  8201.         var i               : int;
  8202.    
  8203.         if ( IsCombatMusicEnabled() )  
  8204.             visualDebug.AddText( 'CombatMusic', "CombatMusic : On", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.7f ), true, , Color( 255, 255, 255 ) );
  8205.         else
  8206.             visualDebug.AddText( 'CombatMusic', "CombatMusic : Off", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.7f ), true, , Color( 0, 0, 0 ) );    
  8207.  
  8208.         if ( GetPlayerMode().GetForceCombatMode() )
  8209.             visualDebug.AddText( 'ForcedCombatMode', "ForcedCombatMode : TRUE", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.6f ), true, , Color( 255, 255, 255 ) );
  8210.         else
  8211.             visualDebug.AddText( 'ForcedCombatMode', "ForcedCombatMode : FALSE", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.6f ), true, , Color( 0, 0, 0 ) );
  8212.  
  8213.    
  8214.         if ( IsThreatened() )
  8215.         {
  8216.             if ( IsInCombat() )
  8217.                 visualDebug.AddText( 'CombatMode', "CombatMode : AlertNear/Far", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.5f ), true, , Color( 255, 0, 0 ) );
  8218.             else
  8219.                 visualDebug.AddText( 'CombatMode', "CombatMode : CombatExploration", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.5f ), true, , Color( 255, 255, 0 ) );
  8220.         }
  8221.         else
  8222.             visualDebug.AddText( 'CombatMode', "CombatMode : NormalExploration", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.5f ), true, , Color( 0, 255, 0 ) );
  8223.    
  8224.         visualDebug.AddText( 'NaviQuery', naviQueryMsg, combatModeEnt.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor );
  8225.         visualDebug.AddText( 'NaviQuery1', naviQueryMsg1, thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor );
  8226.         visualDebug.AddText( 'NaviQuery2', naviQueryMsg2, thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.2f ), true, , combatModeColor );
  8227.        
  8228.         if ( isInCombatReason == 0 )
  8229.             visualDebug.AddText( 'CombatModeReason', "CombatModeReason : ", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.4f ), true, , Color( 125, 125, 125 ) );
  8230.         else if ( isInCombatReason == 1 )
  8231.             visualDebug.AddText( 'CombatModeReason', "CombatModeReason : Geralt CAN pathfind to NPC", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.4f ), true, , Color( 255, 0, 0 ) );
  8232.         else if ( isInCombatReason == 2 )
  8233.             visualDebug.AddText( 'CombatModeReason', "CombatModeReason : An NPC is flying or ranged", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.4f ), true, , Color( 255, 0, 0 ) );                 
  8234.         else if ( isInCombatReason == 2 )
  8235.             visualDebug.AddText( 'CombatModeReason', "CombatModeReason : Forced Combat Mode", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.4f ), true, , Color( 255, 0, 0 ) );
  8236.  
  8237.         if ( reachableEnemyWasTooFar )
  8238.         {
  8239.             combatModeColor.Red = 255;
  8240.             combatModeColor.Green = 255;
  8241.             combatModeColor.Blue = 0;              
  8242.         }
  8243.         else
  8244.         {
  8245.             combatModeColor.Red = 0;
  8246.             combatModeColor.Green = 255;
  8247.             combatModeColor.Blue = 0;              
  8248.         }
  8249.        
  8250.         if ( IsThreatened() )
  8251.         {
  8252.             switch ( navQuery.GetLastOutput( 2.0 ) )
  8253.             {
  8254.                 case EAsyncTastResult_Failure:
  8255.                 {  
  8256.                     if ( this.playerMode.GetForceCombatMode() )
  8257.                     {
  8258.                         if ( isSnappedToNavMesh )
  8259.                         {
  8260.                             visualDebug.AddText( 'NaviQuery', "", combatModeEnt.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor );
  8261.                             visualDebug.AddText( 'NaviQuery1', "Naviquery : Snapped So no need for query", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor );
  8262.                             visualDebug.AddText( 'NaviQuery2', "Naviquery : Snapped So no need for query", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.2f ), true, , combatModeColor );
  8263.                         }
  8264.                         else
  8265.                         {
  8266.                             visualDebug.AddText( 'NaviQuery', "", combatModeEnt.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor );
  8267.                             visualDebug.AddText( 'NaviQuery1', "Naviquery : Failed", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor );
  8268.                             visualDebug.AddText( 'NaviQuery2', "Naviquery : Failed", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.2f ), true, , combatModeColor );                     
  8269.                         }
  8270.                     }
  8271.                     else
  8272.                     {
  8273.                         visualDebug.AddText( 'NaviQuery', "", combatModeEnt.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor );
  8274.                         visualDebug.AddText( 'NaviQuery1', "Naviquery : Failed", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor );
  8275.                         visualDebug.AddText( 'NaviQuery2', "Naviquery : Failed", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.2f ), true, , combatModeColor );
  8276.                     }
  8277.                     break;
  8278.                 }
  8279.                 case EAsyncTastResult_Success:
  8280.                 {          
  8281.                     visualDebug.AddText( 'NaviQuery', combatModeEnt.GetName(), combatModeEnt.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor );
  8282.                     visualDebug.AddText( 'NaviQuery1', "Naviquery : Success (navDist: " + navDist + ")", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor );
  8283.                     visualDebug.AddText( 'NaviQuery2', "Naviquery : Success (directDist: " + directDist + ")", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.2f ), true, , combatModeColor );   
  8284.                     break;
  8285.                 }
  8286.                 case EAsyncTastResult_Pending:
  8287.                 {
  8288.                     visualDebug.AddText( 'NaviQuery', combatModeEnt.GetName(), combatModeEnt.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor );
  8289.                     visualDebug.AddText( 'NaviQuery1', "Naviquery : Pending (navDist: " + navDist + ")", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor );
  8290.                     visualDebug.AddText( 'NaviQuery2', "Naviquery : Pending (directDist: " + directDist + ")", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.2f ), true, , combatModeColor );   
  8291.                     break;
  8292.                 }
  8293.                 case EAsyncTastResult_Invalidated:
  8294.                 {
  8295.                     visualDebug.AddText( 'NaviQuery', "", combatModeEnt.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor );
  8296.                     visualDebug.AddText( 'NaviQuery1', "Naviquery : Invalidated", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor );
  8297.                     visualDebug.AddText( 'NaviQuery2', "Naviquery : Invalidated", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.2f ), true, , combatModeColor );        
  8298.                     break;
  8299.                 }          
  8300.             }
  8301.         }
  8302.         else
  8303.         {
  8304.             visualDebug.AddText( 'NaviQuery', "", combatModeEnt.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor );
  8305.             visualDebug.AddText( 'NaviQuery1', "", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor );
  8306.             visualDebug.AddText( 'NaviQuery2', "", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.2f ), true, , combatModeColor );               
  8307.         }
  8308.        
  8309.         if ( navMeshSnapInfoStack.Size() > 0 )
  8310.         {
  8311.             for ( i = navMeshSnapInfoStack.Size()-1; i >= 0; i -= 1 )
  8312.             {
  8313.                 navSnapMsg = navSnapMsg + navMeshSnapInfoStack[i] + " ";
  8314.             }
  8315.            
  8316.             visualDebug.AddText( 'NavMeshSnap', "NavMeshSnap: Enabled, Sources : " + navSnapMsg, thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.1f ), true, , Color( 255, 255, 255 ) );
  8317.         }
  8318.         else
  8319.             visualDebug.AddText( 'NavMeshSnap', "NavMeshSnap: Disabled" , thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.1f ), true, , Color( 0, 0, 0 ) );
  8320.        
  8321.     }
  8322.    
  8323.     function IsCombatMusicEnabled() : bool
  8324.     {
  8325.         if ( theSound.GetCurrentGameState() == ESGS_UnderwaterCombat
  8326.             || theSound.GetCurrentGameState() == ESGS_Combat
  8327.             || theSound.GetCurrentGameState() == ESGS_CombatMonsterHunt
  8328.             || theSound.GetCurrentGameState() == ESGS_FocusUnderwaterCombat )
  8329.             return true;
  8330.         else
  8331.             return false;
  8332.     }
  8333.    
  8334.     function IsSoundStateCombatMusic( gameState : ESoundGameState  ) : bool
  8335.     {
  8336.         if ( gameState == ESGS_UnderwaterCombat
  8337.             || gameState == ESGS_Combat
  8338.             || gameState == ESGS_CombatMonsterHunt
  8339.             || gameState == ESGS_FocusUnderwaterCombat )
  8340.             return true;
  8341.         else
  8342.             return false;
  8343.     }  
  8344.        
  8345.     private function ConfirmNewTarget( actorToConfirm : CActor )
  8346.     {
  8347.         var leftJoyRotLimit : float = 1.f;
  8348.        
  8349.         var target : CActor;
  8350.        
  8351.         target = GetTarget();
  8352.        
  8353.         //MS: When Player pushes stick in npcs direction, he needs to push the stick beyond leftJoyRotLimit in order to change targets
  8354.         if (    !target
  8355.                 || !moveTarget
  8356.                 || ( target && ( !IsThreat( target ) || !target.IsAlive() ) )
  8357.                 || VecLength( rawLeftJoyVec ) < 0.7f
  8358.                 || ( IsInCombatAction() && ( ( GetBehaviorVariable( 'combatActionType') == (int)CAT_Dodge ) || ( VecLength( rawLeftJoyVec ) >= 0.7f && ( prevRawLeftJoyRot >= ( rawLeftJoyRot + leftJoyRotLimit ) || prevRawLeftJoyRot <= ( rawLeftJoyRot - leftJoyRotLimit ) || AbsF( AngleDistance( cachedRawPlayerHeading, VecHeading( GetDisplayTarget().GetWorldPosition() - this.GetWorldPosition() ) ) ) > 60 ) ) ) )
  8359.                 || ( !IsInCombatAction() && ( !rangedWeapon || ( rangedWeapon.GetCurrentStateName() != 'State_WeaponHolster' ) ) ))//&& rangedWeapon.GetCurrentStateName() != 'State_WeaponShoot' ) && rangedWeapon.GetCurrentStateName() != 'State_WeaponAim' ) )
  8360.         {
  8361.             SetPrevRawLeftJoyRot();
  8362.            
  8363.             if ( actorToConfirm != target )
  8364.             {
  8365.                 SetTarget( actorToConfirm );
  8366.             }
  8367.         }
  8368.     }
  8369.    
  8370.     protected function SelectTarget( targets : array< CActor >, useVisibilityCheck : bool, sourcePosition : Vector, headingVector : Vector, selectionWeights : STargetSelectionWeights, optional usePrecalcs : bool ) : CActor
  8371.     {
  8372.         var i                   : int;
  8373.         var target              : CActor;  
  8374.         var selectedTarget      : CActor;  
  8375.         var currentTarget       : CActor;
  8376.         var playerPosition      : Vector;
  8377.         var distanceToPlayer    : float;
  8378.         var priority            : float;
  8379.         var maxPriority         : float;
  8380.         var now                 : float;
  8381.         var remove              : bool;
  8382.         var visibleActorIndex   : int;
  8383.                
  8384.         if ( useVisibilityCheck )
  8385.         {
  8386.             currentTarget = this.GetTarget();          
  8387.             playerPosition = this.GetWorldPosition();
  8388.             now = theGame.GetEngineTimeAsSeconds();
  8389.                
  8390.             for ( i = targets.Size() - 1; i >= 0; i-=1 )
  8391.             {  
  8392.                 target = targets[ i ];
  8393.                 if ( target != currentTarget && ( !IsPCModeEnabled() && !WasVisibleInScaledFrame( target, softLockFrameSize, softLockFrameSize ) ) )           
  8394.                 {
  8395.                     remove = true;
  8396.                     visibleActorIndex = visibleActors.FindFirst( target );
  8397.                     if ( visibleActorIndex != -1 )
  8398.                     {
  8399.                         if ( usePrecalcs )
  8400.                         {
  8401.                             distanceToPlayer = Distance2DBetweenCapsuleAndPoint( target, this ) - targetingPrecalcs.playerRadius;
  8402.                         }
  8403.                         else
  8404.                         {
  8405.                             distanceToPlayer = Distance2DBetweenCapsules( this, target );                      
  8406.                         }
  8407.                         // if within soft lock distance and soft lock visibility duration -> don't remove yet
  8408.                         if ( distanceToPlayer < this.softLockDist && ( now - visibleActorsTime[ i ] ) < 1.0f )
  8409.                         {
  8410.                             remove = false;
  8411.                         }
  8412.                     }
  8413.                     if ( remove )
  8414.                     {
  8415.                         targets.EraseFast( i );
  8416.                     }
  8417.                 }
  8418.                 else
  8419.                 {
  8420.                     visibleActorIndex = visibleActors.FindFirst( target );
  8421.                     if ( visibleActorIndex == -1 )
  8422.                     {
  8423.                         visibleActors.PushBack( target );
  8424.                         visibleActorsTime.PushBack( now );
  8425.                     }
  8426.                     else
  8427.                     {
  8428.                         visibleActorsTime[ visibleActorIndex ] = now;
  8429.                     }
  8430.                 }
  8431.             }
  8432.         }
  8433.  
  8434.         selectedTarget = NULL;
  8435.         maxPriority = -1.0f;
  8436.         for( i = targets.Size() - 1; i >= 0; i-=1 )
  8437.         {
  8438.             priority = CalcSelectionPriority( targets[ i ], selectionWeights, sourcePosition, headingVector );             
  8439.             if ( priority > maxPriority )
  8440.             {
  8441.                 maxPriority = priority;
  8442.                 selectedTarget = targets[ i ];
  8443.             }
  8444.         }          
  8445.    
  8446.         //LogChannel( 'selectedTarget', selectedTarget );
  8447.         return selectedTarget; 
  8448.     }
  8449.  
  8450.     function Distance2DBetweenCapsuleAndPoint( actor : CActor, entity : CEntity ) : float
  8451.     {
  8452.         var distance    : float;
  8453.         var mpac        : CMovingPhysicalAgentComponent;
  8454.        
  8455.         distance = VecDistance2D( actor.GetWorldPosition(), entity.GetWorldPosition() );
  8456.        
  8457.         mpac = (CMovingPhysicalAgentComponent)actor.GetMovingAgentComponent();
  8458.         if ( mpac )
  8459.         {
  8460.             distance -= mpac.GetCapsuleRadius();
  8461.         }
  8462.        
  8463.         return distance;       
  8464.     }
  8465.  
  8466.  
  8467.     function Distance2DBetweenCapsules( actor1 : CActor, actor2 : CActor ) : float
  8468.     {
  8469.         var distance    : float;
  8470.         var mpac        : CMovingPhysicalAgentComponent;
  8471.        
  8472.         distance = VecDistance2D( actor1.GetWorldPosition(), actor2.GetWorldPosition() );
  8473.        
  8474.         mpac = (CMovingPhysicalAgentComponent)actor1.GetMovingAgentComponent();
  8475.         if ( mpac )
  8476.         {
  8477.             distance -= mpac.GetCapsuleRadius();
  8478.         }
  8479.        
  8480.         mpac = (CMovingPhysicalAgentComponent)actor2.GetMovingAgentComponent();
  8481.         if ( mpac )
  8482.         {
  8483.             distance -= mpac.GetCapsuleRadius();
  8484.         }
  8485.        
  8486.         return distance;       
  8487.     }
  8488.  
  8489.     protected function ProcessSelectionWeights() : STargetSelectionWeights
  8490.     {
  8491.         var selectionWeights            : STargetSelectionWeights;
  8492.        
  8493.         if ( ShouldUsePCModeTargeting() )
  8494.         {
  8495.             selectionWeights.angleWeight = 0.75f;
  8496.             selectionWeights.distanceWeight = 0.25f;
  8497.             selectionWeights.distanceRingWeight = 0.f;     
  8498.             return selectionWeights;       
  8499.         }
  8500.        
  8501.         if ( IsInCombatAction() && ( GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Dodge || GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Roll ) )
  8502.         {
  8503.             selectionWeights.angleWeight = 0.575f;
  8504.             selectionWeights.distanceWeight = 0.175f;
  8505.             selectionWeights.distanceRingWeight = 0.25f;
  8506.         }      
  8507.         if ( !lAxisReleasedAfterCounter || IsInCombatAction() ) // !bLAxisReleased ||
  8508.         {
  8509.             if ( theInput.GetActionValue( 'ThrowItem' ) == 1.f || ( rangedWeapon && rangedWeapon.GetCurrentStateName() != 'State_WeaponWait' ) )
  8510.             {
  8511.                 selectionWeights.angleWeight = 1.f;
  8512.                 selectionWeights.distanceWeight = 0.f;
  8513.                 selectionWeights.distanceRingWeight = 0.f; 
  8514.             }
  8515.             else if ( !lAxisReleasedAfterCounter ) // !bLAxisReleased )
  8516.             {
  8517.                 selectionWeights.angleWeight = 0.55f;//0.75f;
  8518.                 selectionWeights.distanceWeight = 0.45f;//0.25f;
  8519.                 selectionWeights.distanceRingWeight = 0.f;//0.3f;
  8520.             }
  8521.             else
  8522.             {
  8523.                 selectionWeights.angleWeight = 0.75f;
  8524.                 selectionWeights.distanceWeight = 0.25f;
  8525.                 selectionWeights.distanceRingWeight = 0.f;//0.3f;          
  8526.             }
  8527.         }
  8528.         else if( !IsCurrentSignChanneled() )
  8529.         {
  8530.             selectionWeights.angleWeight = 0.35f;
  8531.             selectionWeights.distanceWeight = 0.65f;
  8532.             selectionWeights.distanceRingWeight = 0.f;     
  8533.         }
  8534.         else
  8535.         {
  8536.             selectionWeights.angleWeight = 0.275f;
  8537.             selectionWeights.distanceWeight = 0.375f;
  8538.             selectionWeights.distanceRingWeight = 0.35f;       
  8539.         }
  8540.        
  8541.         return selectionWeights;   
  8542.     }
  8543.    
  8544.     protected function CalcSelectionPriority( target : CEntity, selectionWeights : STargetSelectionWeights, sourcePosition : Vector, headingVector : Vector ) : float
  8545.     {
  8546.         var sourceToTarget              : Vector;
  8547.         var sourceToTargetDist          : float;
  8548.         var sourceToTargetAngleDiff     : float;
  8549.         var selectionPriority           : float;
  8550.        
  8551.         sourceToTarget = target.GetWorldPosition() - sourcePosition;
  8552.         sourceToTargetDist = VecLength2D( sourceToTarget );
  8553.         // normalize2D sourcetoTarget
  8554.         if ( sourceToTargetDist < 0.0001f )
  8555.         {
  8556.             sourceToTarget = Vector( 0.0f, 0.0f, 0.0f );
  8557.         }
  8558.         else
  8559.         {
  8560.             sourceToTarget *= ( 1.0f / sourceToTargetDist );
  8561.         }
  8562.         sourceToTargetAngleDiff = AbsF( Rad2Deg( AcosF( VecDot2D( sourceToTarget, headingVector ) ) ) );
  8563.        
  8564.         selectionPriority = ( selectionWeights.angleWeight * ( ( 180 - sourceToTargetAngleDiff ) / 180 ) );
  8565.         selectionPriority += selectionWeights.distanceWeight * ( ( softLockDist - sourceToTargetDist ) / softLockDist );   
  8566.        
  8567.         if ( sourceToTargetDist > 0.f  && sourceToTargetDist <= 6.f )
  8568.         {
  8569.             selectionPriority += selectionWeights.distanceRingWeight * 1.0f;   
  8570.         }
  8571.         else if ( sourceToTargetDist > 6.f  && sourceToTargetDist <= softLockDist )
  8572.         {
  8573.             selectionPriority += selectionWeights.distanceRingWeight * 0.4f;
  8574.         }  
  8575.        
  8576.         return selectionPriority;
  8577.     }
  8578.  
  8579.     // W3EE - Begin
  8580.     public function SetTarget( targetActor : CActor, optional forceSetTarget : bool )
  8581.     // W3EE - End
  8582.     {
  8583.         var playerToTargetDistance  : float;
  8584.         var target                  : CActor;
  8585.         var allow                   : bool;
  8586.        
  8587.         target = GetTarget();
  8588.  
  8589.         if ( !IsInNonGameplayCutscene() )
  8590.             allow = true;
  8591.        
  8592.         if ( allow )
  8593.         {
  8594.             if ( targetActor )
  8595.             {
  8596.                 if ( ( targetActor.IsAlive() && !targetActor.IsKnockedUnconscious() ) || finishableEnemiesList.Contains( targetActor ) )
  8597.                     allow = true;
  8598.                 else
  8599.                     allow = false;
  8600.             }
  8601.             else
  8602.                 allow = true;      
  8603.         }
  8604.        
  8605.         if ( forceSetTarget )
  8606.             allow = true;
  8607.            
  8608.         if ( allow && target != targetActor )
  8609.             allow = true;
  8610.         else
  8611.             allow = false;
  8612.        
  8613.         if ( allow )
  8614.         {  
  8615.             SetPlayerTarget( targetActor );
  8616.            
  8617.             //playerToTargetDistance = VecDistance( GetWorldPosition(), targetActor.GetNearestPointInBothPersonalSpaces( GetWorldPosition() ) );
  8618.             //LogChannel( 'Targeting', "selection " + playerToTargetDistance );        
  8619.         }
  8620.     }
  8621.  
  8622. /*
  8623.     protected function SetTarget( targetActor : CActor, optional forceSetTarget : bool )
  8624.     {
  8625.         var playerToTargetDistance  : float;
  8626.         var target                  : CActor;
  8627.         //var gec : CGameplayEffectsComponent;
  8628.        
  8629.    
  8630.         if ( !IsInNonGameplayCutscene()
  8631.             && ( ( ( !targetActor || ( ( targetActor.IsAlive() || finishableEnemiesList.Contains( targetActor ) ) && !targetActor.IsKnockedUnconscious() ) ) && !IsActorLockedToTarget() ) || forceSetTarget ) )
  8632.         {  
  8633.             target = GetTarget();
  8634.        
  8635.             if ( target != targetActor )
  8636.             {
  8637.                 if( target )
  8638.                 {
  8639.                     target.StopEffect( 'select_character' );   
  8640.                     //gec = GetGameplayEffectsComponent( target );
  8641.                     //if(gec)
  8642.                     //  gec.SetGameplayEffectFlag( EGEF_OutlineTarget, 0 );
  8643.                 }
  8644.                    
  8645.                 SetPlayerTarget( targetActor );
  8646.                 target = targetActor;
  8647.                
  8648.                 if(target)
  8649.                 {      
  8650.                     playerToTargetDistance = VecDistance( GetWorldPosition(), target.GetNearestPointInBothPersonalSpaces( GetWorldPosition() ) );
  8651.                 }
  8652.                
  8653.                 //LogChannel( 'Targeting', "selection " + playerToTargetDistance );            
  8654.             }
  8655.         }
  8656.     }
  8657. */ 
  8658.     public function SetSlideTarget( actor : CGameplayEntity )
  8659.     {
  8660.         //if ( slideTarget != actor && slideTarget )
  8661.         //  EnableCloseCombatCharacterRadius( false );
  8662.  
  8663.         slideTarget = actor;
  8664.        
  8665.         if ( slideTarget )
  8666.             SetPlayerCombatTarget((CActor)slideTarget);    
  8667.         else
  8668.             Log( "slideTarget = NULL" );
  8669.        
  8670.         if ( slideTarget == nonActorTarget )
  8671.             UpdateDisplayTarget( true, true );
  8672.         else
  8673.             UpdateDisplayTarget();
  8674.            
  8675.         ConfirmDisplayTargetTimer(0.f);
  8676.     }
  8677.    
  8678.     event OnForceSelectLockTarget()
  8679.     {
  8680.         ForceSelectLockTarget();
  8681.     }
  8682.  
  8683.     private function ForceSelectLockTarget()
  8684.     {
  8685.         var newMoveTarget   : CActor;
  8686.         var target          : CActor;
  8687.    
  8688.         newMoveTarget = GetScreenSpaceLockTarget( GetDisplayTarget(), 180.f, 1.f, 90 );
  8689.        
  8690.         if ( !newMoveTarget )
  8691.             newMoveTarget = GetScreenSpaceLockTarget( GetDisplayTarget(), 180.f, 1.f, -90 );
  8692.            
  8693.         if ( newMoveTarget )
  8694.         {
  8695.             thePlayer.ProcessLockTarget( newMoveTarget );
  8696.            
  8697.             target = GetTarget();
  8698.             if ( target )
  8699.             {
  8700.                 thePlayer.SetSlideTarget( target );
  8701.    
  8702.                 if ( IsHardLockEnabled() )
  8703.                     thePlayer.HardLockToTarget( true );
  8704.             }
  8705.         }
  8706.         else
  8707.         {
  8708.             thePlayer.HardLockToTarget( false );           
  8709.         }  
  8710.     }
  8711.    
  8712.     public function SetFinisherVictim( actor : CActor )
  8713.     {
  8714.         finisherVictim = actor;
  8715.     }
  8716.    
  8717.     public function GetFinisherVictim() : CActor
  8718.     {
  8719.         return finisherVictim;
  8720.     }  
  8721.    
  8722.     protected function SetNonActorTarget( actor : CGameplayEntity )    
  8723.     {
  8724.         if ( nonActorTarget != actor )
  8725.         nonActorTarget = actor;
  8726.     }
  8727.  
  8728.     timer function DisableTargetHighlightTimer( time : float , id : int)
  8729.     {
  8730.         var target : CActor;
  8731.         target = GetTarget();
  8732.        
  8733.         if( target )
  8734.         {
  8735.             target.StopEffect( 'select_character' );
  8736.         }
  8737.     }
  8738.  
  8739.     public function WasVisibleInScaledFrame( entity : CEntity, frameSizeX : float, frameSizeY : float ) : bool
  8740.     {
  8741.         var position                : Vector;
  8742.         var positionFound           : bool;
  8743.         var inFront                 : bool;
  8744.         var x, y                    : float;
  8745.         var boneIndex               : int;
  8746.         var actor                   : CActor;
  8747.         var gameplayEntity          : CGameplayEntity;
  8748.         var gameplayEntityMatrix    : Matrix;
  8749.         var drawableComp            : CDrawableComponent;  
  8750.         var box                     : Box;
  8751.         var ok                      : bool;
  8752.            
  8753.         if ( !entity )
  8754.         {
  8755.             return false;
  8756.         }
  8757.         if ( frameSizeX <= 0.0f && frameSizeY <= 0.0f )
  8758.         {
  8759.             LogChannel( 'WasVisibleInScaledFrame', "ERROR: WasVisibleInScaledFrame: frameSizeX && frameSizeY are both negative!!!" );
  8760.             return false;
  8761.         }
  8762.  
  8763.         if ( useNativeTargeting )
  8764.         {
  8765.             return targeting.WasVisibleInScaledFrame( entity, frameSizeX, frameSizeY );
  8766.         }
  8767.    
  8768.         position = entity.GetWorldPosition();
  8769.    
  8770.         actor = (CActor)entity;
  8771.         if ( actor )
  8772.         {
  8773.             boneIndex = entity.GetBoneIndex( 'pelvis' );
  8774.             if ( boneIndex == -1 )
  8775.             {
  8776.                 boneIndex = entity.GetBoneIndex( 'k_pelvis_g' ); // not hack at all. DONE !*100000000000000000000
  8777.             }
  8778.                
  8779.             if ( boneIndex != -1 )
  8780.             {
  8781.                 position = MatrixGetTranslation( entity.GetBoneWorldMatrixByIndex( boneIndex ) );
  8782.             }
  8783.             else
  8784.             {
  8785.                 position = entity.GetWorldPosition();
  8786.                 position.Z += ( (CMovingPhysicalAgentComponent)actor.GetMovingAgentComponent() ).GetCapsuleHeight() * 0.5;
  8787.             }
  8788.             positionFound = true;
  8789.         }
  8790.         else
  8791.         {
  8792.             gameplayEntity = (CGameplayEntity)entity;
  8793.             if ( gameplayEntity && !( gameplayEntity.aimVector.X == 0 && gameplayEntity.aimVector.Y == 0 && gameplayEntity.aimVector.Z == 0 ) )
  8794.             {
  8795.                 gameplayEntityMatrix = gameplayEntity.GetLocalToWorld();               
  8796.                 position = VecTransform( gameplayEntityMatrix, gameplayEntity.aimVector );
  8797.                 positionFound = true;
  8798.             }
  8799.         }
  8800.        
  8801.         // if still not found proper position for test
  8802.         if  ( !positionFound )
  8803.         {
  8804.             drawableComp = (CDrawableComponent)entity.GetComponentByClassName( 'CDrawableComponent' );
  8805.             if ( drawableComp && drawableComp.GetObjectBoundingVolume( box ) )
  8806.             {
  8807.                 position.Z += ( ( box.Max.Z - box.Min.Z ) * 0.66f );       
  8808.             }
  8809.         }
  8810.        
  8811.         inFront = theCamera.WorldVectorToViewRatio( position, x, y );
  8812.         if ( !inFront )
  8813.         {
  8814.             return false;
  8815.         }
  8816.         x = AbsF( x );
  8817.         y = AbsF( y );
  8818.    
  8819.         ok = true;
  8820.         ok = ok && ( frameSizeX <= 0.0f || x < frameSizeX );
  8821.         ok = ok && ( frameSizeY <= 0.0f || y < frameSizeY );
  8822.    
  8823.         return ok;
  8824.     }  
  8825.  
  8826.     public function HardLockToTarget( flag : bool )
  8827.     {
  8828.         if( flag && GetTarget().HasTag( 'NoHardLock' ) )
  8829.             return;
  8830.            
  8831.         EnableHardLock( flag );
  8832.         LockToTarget( flag );
  8833.     }
  8834.  
  8835.     public function LockToTarget( flag : bool )
  8836.     {
  8837.         if ( IsHardLockEnabled() && !flag )
  8838.             return;
  8839.            
  8840.         // W3EE - Begin
  8841.         if (theGame.GetInGameConfigWrapper().GetVarValue('EnhancedTargeting', 'ETDisableCameraLock'))
  8842.         {
  8843.             if (IsCameraLockedToTarget())
  8844.                 LockCameraToTarget( false );
  8845.         }
  8846.         else
  8847.         {
  8848.             LockCameraToTarget( flag );
  8849.         }
  8850.         // W3EE - End
  8851.        
  8852.         LockActorToTarget( flag );
  8853.     }
  8854.  
  8855.     public function LockCameraToTarget( flag : bool )
  8856.     {
  8857.         if ( flag && !IsCameraLockedToTarget() )
  8858.         {
  8859.             thePlayer.EnableManualCameraControl( false, 'LockCameraToTarget' );
  8860.             //((CCustomCamera)theCamera.GetTopmostCameraObject()).EnableManualControl( false );
  8861.             SetIsCameraLockedToTarget( flag );
  8862.         }
  8863.         else if ( !flag && IsCameraLockedToTarget() )
  8864.         {
  8865.             thePlayer.EnableManualCameraControl( true, 'LockCameraToTarget' );
  8866.             //((CCustomCamera)theCamera.GetTopmostCameraObject()).EnableManualControl( true );
  8867.             SetIsCameraLockedToTarget( flag );
  8868.         }
  8869.     }
  8870.    
  8871.     public function LockActorToTarget( flag : bool, optional withoutIcon : bool )
  8872.     {
  8873.         var displayTargetActor : CActor;
  8874.    
  8875.         if ( flag )
  8876.         {      
  8877.             if ( !IsActorLockedToTarget() )
  8878.             {
  8879.                 //SetSlideTarget( target );
  8880.                 SetIsActorLockedToTarget( flag );
  8881.                 SetMoveTargetChangeAllowed( true );
  8882.                 SetMoveTarget( GetTarget() );
  8883.                 SetMoveTargetChangeAllowed( false );
  8884.                 SetTarget( GetTarget() );
  8885.                 SetSlideTarget( GetTarget() );
  8886.                 AddTimer( 'CheckLockTargetIsAlive', 0.5, true );
  8887.             }
  8888.            
  8889.             if ( IsActorLockedToTarget() )
  8890.             {
  8891.                 displayTargetActor = (CActor)( GetDisplayTarget() );
  8892.                
  8893.                 if ( displayTargetActor && IsThreat( displayTargetActor ) && !withoutIcon )
  8894.                     EnableHardLockIcon( flag );
  8895.             }
  8896.         }
  8897.         else if ( !flag && IsActorLockedToTarget() )
  8898.         {
  8899.             SetIsActorLockedToTarget( flag );
  8900.             SetMoveTargetChangeAllowed( true );        
  8901.             RemoveTimer( 'CheckLockTargetIsAlive' );
  8902.             EnableHardLockIcon( flag );
  8903.         }  
  8904.     }
  8905.  
  8906.     private function EnableHardLockIcon( flag : bool )
  8907.     {
  8908.         var hud : CR4ScriptedHud;
  8909.         var module : CR4HudModuleEnemyFocus;
  8910.        
  8911.         if( GetTarget().HasTag( 'NoHardLockIcon' ) )
  8912.             return;
  8913.  
  8914.         hud = (CR4ScriptedHud)theGame.GetHud();
  8915.         module = (CR4HudModuleEnemyFocus)hud.GetHudModule("EnemyFocusModule");
  8916.         module.SetShowHardLock( flag );
  8917.     }
  8918.    
  8919.     private timer function CheckLockTargetIsAlive( time : float , id : int)
  8920.     {
  8921.         var vitality    : float;
  8922.         var essence     : float;
  8923.         var actor       : CActor;
  8924.         var target      : CActor;
  8925.        
  8926.         target = (CActor)GetDisplayTarget();
  8927.    
  8928.         if( !target
  8929.             || !target.IsAlive()
  8930.             || ( !target.GetGameplayVisibility() )
  8931.             || !CanBeTargetedIfSwimming( target )
  8932.             || (!target.UsesVitality() && !target.UsesEssence()))
  8933.         {
  8934.             if ( !ProcessLockTarget() )
  8935.                 HardLockToTarget( false );         
  8936.         }      
  8937.     }
  8938.    
  8939.     //////////////////////////////////////////////////////////////////////////////////////////
  8940.     //
  8941.     // @Damage
  8942.     //
  8943.     //////////////////////////////////////////////////////////////////////////////////////////
  8944.     protected function PlayHitAnimation(damageAction : W3DamageAction, animType : EHitReactionType)
  8945.     {
  8946.         var hitRotation     : float;
  8947.         var onHitCounter    : SAbilityAttributeValue;
  8948.         var counter         : int;
  8949.        
  8950.         if( damageAction.HasAnyCriticalEffect() )
  8951.             return;
  8952.        
  8953.         if( !substateManager.ReactOnBeingHit() && !IsUsingVehicle() )
  8954.         {
  8955.             return;
  8956.         }
  8957.        
  8958.         if ( damageAction.GetHitReactionType() == EHRT_Reflect )
  8959.             SetBehaviorVariable( 'isAttackReflected', 1.f );
  8960.         else
  8961.             SetBehaviorVariable( 'isAttackReflected', 0.f );
  8962.        
  8963.         SetBehaviorVariable( 'HitReactionType',(int)animType);
  8964.         SetBehaviorVariable( 'HitReactionWeapon', ProcessSwordOrFistHitReaction( this, (CActor)damageAction.attacker ) );
  8965.        
  8966.         if (damageAction.attacker)
  8967.         {
  8968.             super.PlayHitAnimation( damageAction, animType );
  8969.             if ( damageAction.attacker.HasAbility( 'IncreaseHitReactionSeverityWithHitCounter' ) )
  8970.             {
  8971.                 counter = GetHitCounter();
  8972.                 switch ( counter )
  8973.                 {
  8974.                     case 2 :                       
  8975.                         SetBehaviorVariable( 'HitReactionType', 2 );
  8976.                         break;
  8977.                    
  8978.                     case 3 :                       
  8979.                         AddEffectDefault( EET_Stagger, damageAction.attacker, damageAction.attacker.GetName() );
  8980.                         break;
  8981.                    
  8982.                     case 4 :                       
  8983.                         AddEffectDefault( EET_Knockdown, damageAction.attacker, damageAction.attacker.GetName() );
  8984.                         break;
  8985.                    
  8986.                     default :
  8987.                         break;
  8988.                 }
  8989.             }
  8990.             SetHitReactionDirection(damageAction.attacker);
  8991.             SetDetailedHitReaction(damageAction.GetSwingType(), damageAction.GetSwingDirection());
  8992.         }
  8993.        
  8994.         RaiseForceEvent( 'Hit' );
  8995.         theGame.GetBehTreeReactionManager().CreateReactionEventIfPossible( this, 'ActorInHitReaction', -1, 30.0f, -1.f, -1, true ); //reactionSystemSearch
  8996.        
  8997.         if ( IsUsingBoat() )
  8998.         {
  8999.             SoundEvent("cmb_play_hit_light");
  9000.             return;
  9001.         }
  9002.        
  9003.         if ( IsUsingVehicle() )
  9004.             return;
  9005.        
  9006.         if(damageAction.attacker)
  9007.         {
  9008.             hitRotation = VecHeading( damageAction.attacker.GetWorldPosition() - GetWorldPosition() );
  9009.             if ( this.GetBehaviorVariable( 'HitReactionDirection' ) == (float)( (int)EHRD_Back ) )
  9010.                 hitRotation += 180.f;
  9011.        
  9012.             //GetVisualDebug().AddArrow( 'temp', GetWorldPosition(), GetWorldPosition() + VecFromHeading( hitRotation )*2, 1.f, 0.2f, 0.2f, true, Color(0,255,255), true, 5.f );
  9013.             SetCustomRotation( 'Hit', hitRotation, 1080.f, 0.1f, false );
  9014.         }
  9015.        
  9016.         CriticalEffectAnimationInterrupted("PlayHitAnimation");
  9017.     }
  9018.    
  9019.     public function ReduceDamage( out damageData : W3DamageAction)
  9020.     {
  9021.         super.ReduceDamage(damageData);
  9022.        
  9023.         //halve damage if from your own bomb
  9024.         if(damageData.attacker == this && (damageData.GetBuffSourceName() == "petard" || (W3Petard)damageData.causer) )
  9025.         {
  9026.             if ( theGame.CanLog() )
  9027.             {
  9028.                 LogDMHits("CR4Player.ReduceDamage: hitting self with own bomb - damage reduced by 50%", damageData );
  9029.             }
  9030.             damageData.processedDmg.vitalityDamage = damageData.processedDmg.vitalityDamage / 2;
  9031.             damageData.processedDmg.essenceDamage = damageData.processedDmg.essenceDamage / 2;
  9032.         }
  9033.     }
  9034.    
  9035.     //crit hit chance 0-1
  9036.     public function GetCriticalHitChance( isLightAttack : bool, isHeavyAttack : bool, target : CActor, victimMonsterCategory : EMonsterCategory, isBolt : bool ) : float
  9037.     {
  9038.         var critChance : float;
  9039.         // var oilChanceAttribute : name;
  9040.         var weapons : array< SItemUniqueId >;
  9041.         var i : int;
  9042.         var holdsCrossbow : bool;
  9043.         var critVal : SAbilityAttributeValue;
  9044.        
  9045.         critChance = 0;
  9046.        
  9047.         //cheats
  9048.         if( FactsQuerySum( 'debug_fact_critical_boy' ) > 0 )
  9049.         {
  9050.             critChance += 1;
  9051.         }
  9052.        
  9053.         if( IsInState( 'HorseRiding' ) && ( ( CActor )GetUsedVehicle() ).GetMovingAgentComponent().GetRelativeMoveSpeed() >= 4.0 )
  9054.         {
  9055.             critChance += 1;
  9056.         }
  9057.        
  9058.         //normal case
  9059.         critChance += CalculateAttributeValue( GetAttributeValue( theGame.params.CRITICAL_HIT_CHANCE ) );
  9060.        
  9061.         //fix cases when we calculate change for crossbow but have sword bonus and vice-versa
  9062.         weapons = inv.GetHeldWeapons();
  9063.         for( i=0; i<weapons.Size(); i+=1 )
  9064.         {          
  9065.             holdsCrossbow = ( inv.IsItemCrossbow( weapons[i] ) || inv.IsItemBolt( weapons[i] ) );
  9066.             if( holdsCrossbow != isBolt )
  9067.             {
  9068.                 critVal = inv.GetItemAttributeValue( weapons[i], theGame.params.CRITICAL_HIT_CHANCE );
  9069.                 critChance -= CalculateAttributeValue( critVal );
  9070.             }          
  9071.         }
  9072.        
  9073.         // W3EE - Begin
  9074.         /*
  9075.         if( isHeavyAttack && CanUseSkill( S_Sword_s08 ) )
  9076.         {
  9077.             critChance += CalculateAttributeValue( GetSkillAttributeValue( S_Sword_s08, theGame.params.CRITICAL_HIT_CHANCE, false, true ) ) * GetSkillLevel( S_Sword_s08 );
  9078.         }
  9079.         else if( isLightAttack && CanUseSkill( S_Sword_s17 ) )
  9080.         {
  9081.             critChance += CalculateAttributeValue( GetSkillAttributeValue( S_Sword_s17, theGame.params.CRITICAL_HIT_CHANCE, false, true ) ) * GetSkillLevel( S_Sword_s17 );
  9082.         }
  9083.         */
  9084.    
  9085.         if( target && target.HasBuff( EET_Confusion ) )
  9086.         {
  9087.             critChance += ( ( W3ConfuseEffect )target.GetBuff( EET_Confusion ) ).GetCriticalHitChanceBonus();
  9088.         }
  9089.        
  9090.         //oils
  9091.         oilChanceAttribute = MonsterCategoryToCriticalChanceBonus( victimMonsterCategory );
  9092.         if( IsNameValid( oilChanceAttribute ) )
  9093.         {
  9094.             critChance += CalculateAttributeValue( GetAttributeValue( oilChanceAttribute ) );
  9095.         }
  9096.         */
  9097.        
  9098.         critVal = ((W3PlayerWitcher)this).GetOilCritChanceBonus(victimMonsterCategory);
  9099.         critChance += critVal.valueMultiplicative;
  9100.         // W3EE - End
  9101.        
  9102.         return critChance;
  9103.     }
  9104.    
  9105.     //gets damage bonus for critical hit
  9106.     public function GetCriticalHitDamageBonus(weaponId : SItemUniqueId, victimMonsterCategory : EMonsterCategory, isStrikeAtBack : bool) : SAbilityAttributeValue
  9107.     {
  9108.         var bonus/*, oilBonus*/ : SAbilityAttributeValue;
  9109.         // var vsAttributeName : name;
  9110.        
  9111.         bonus = super.GetCriticalHitDamageBonus(weaponId, victimMonsterCategory, isStrikeAtBack);
  9112.        
  9113.         //oil bonus    
  9114.         if( inv.ItemHasActiveOilApplied( weaponId, victimMonsterCategory ) )
  9115.         {
  9116.             vsAttributeName = MonsterCategoryToCriticalDamageBonus(victimMonsterCategory);
  9117.             oilBonus = inv.GetItemAttributeValue(weaponId, vsAttributeName);
  9118.             bonus += oilBonus;
  9119.         }
  9120.         */
  9121.        
  9122.         bonus += ((W3PlayerWitcher)this).GetOilCritDamageBonus(victimMonsterCategory);
  9123.        
  9124.         return bonus;
  9125.     }
  9126.    
  9127.     /**
  9128.         Called when we want to play hit animation
  9129.     */ 
  9130.     public function ReactToBeingHit(damageAction : W3DamageAction, optional buffNotApplied : bool) : bool
  9131.     {
  9132.         var strength    : float;
  9133.         var animType    : EHitReactionType;
  9134.         var sup         : bool;
  9135.         var boat : CBoatComponent;
  9136.         var combatActionType : int;
  9137.         var attackAction : W3Action_Attack;
  9138.         var npc : CNewNPC;
  9139.         var shakeCam : bool;
  9140.        
  9141.         attackAction = (W3Action_Attack)damageAction;
  9142.         //not parried, not countered, not dot, not dodged
  9143.         if(!damageAction.IsDoTDamage() && (!attackAction || (!attackAction.IsParried() && !attackAction.IsCountered() && !attackAction.WasDodged()) ) )
  9144.         {
  9145.             npc = (CNewNPC)attackAction.attacker;
  9146.             if(npc && npc.IsHeavyAttack(attackAction.GetAttackName()))
  9147.                 theGame.VibrateControllerVeryHard();//player got heavy hit
  9148.             else
  9149.                 theGame.VibrateControllerHard();//player got hit
  9150.         }
  9151.        
  9152.         if ( (CActor)GetUsedVehicle() && this.playerAiming.GetCurrentStateName() == 'Aiming' )
  9153.         {
  9154.             OnRangedForceHolster( true, true );
  9155.         }
  9156.        
  9157.         combatActionType = (int)GetBehaviorVariable( 'combatActionType' );
  9158.        
  9159.         if ( thePlayer.IsCurrentlyDodging() && ( combatActionType == (int)CAT_Roll || combatActionType == (int)CAT_CiriDodge ) )
  9160.             sup = false;
  9161.         else if ( this.GetCurrentStateName() == 'DismountHorse' )
  9162.             sup = false;
  9163.         else
  9164.             sup = super.ReactToBeingHit(damageAction, buffNotApplied);
  9165.         sup = false;
  9166.         //telemetry
  9167.         if(damageAction.attacker)
  9168.             theTelemetry.LogWithLabelAndValue( TE_FIGHT_HERO_GETS_HIT, damageAction.attacker.ToString(), (int)damageAction.processedDmg.vitalityDamage );
  9169.        
  9170.         //camera shake
  9171.         if(damageAction.DealsAnyDamage())
  9172.         {
  9173.             if( ((W3PlayerWitcher)this) && GetWitcherPlayer().IsAnyQuenActive() && damageAction.IsDoTDamage())
  9174.             {
  9175.                 shakeCam = false;
  9176.             }
  9177.             else
  9178.             {
  9179.                 shakeCam = true;
  9180.             }
  9181.            
  9182.             // W3EE - Begin
  9183.             /*
  9184.             if(shakeCam)
  9185.             {
  9186.                 animType = ModifyHitSeverityReaction(this, damageAction.GetHitReactionType());
  9187.            
  9188.                 if(animType == EHRT_Light || animType == EHRT_LightClose)
  9189.                     strength = 0.1;
  9190.                 else if(animType == EHRT_Heavy || animType == EHRT_Igni)
  9191.                     strength = 0.2;
  9192.                
  9193.                 GCameraShakeLight(strength, false, GetWorldPosition(), 10.0);
  9194.             }
  9195.             */
  9196.             // W3EE - End
  9197.            
  9198.             this.HitReactionEffect( 0.25 );
  9199.            
  9200.             //reset uninterrupted hits
  9201.             ResetUninterruptedHitsCount();
  9202.         }
  9203.                
  9204.         //pause health regen
  9205.         if(!damageAction.IsDoTDamage() && IsThreatened() && ShouldPauseHealthRegenOnHit() && damageAction.DealsAnyDamage() && !damageAction.WasDodged() && attackAction.CanBeParried() && !attackAction.IsParried())
  9206.         {
  9207.             PauseHPRegenEffects('being_hit', theGame.params.ON_HIT_HP_REGEN_DELAY);
  9208.         }
  9209.    
  9210.         //if player is on a boat and not moving then force dismount
  9211.         /*if(usedVehicle)
  9212.         {
  9213.             boat = (CBoatComponent) usedVehicle.GetComponentByClassName('CBoatComponent');
  9214.             if(boat && boat.GetLinearVelocityXY() < boat.IDLE_SPEED_THRESHOLD)
  9215.             {
  9216.                 boat.StopAndDismountBoat();
  9217.             }
  9218.         }*/
  9219.        
  9220.         //finesse achievement fail
  9221.         if(damageAction.processedDmg.vitalityDamage > 0 && !((W3Effect_Toxicity)damageAction.causer))
  9222.             ReceivedCombatDamage();
  9223.        
  9224.         //tutorial
  9225.         if(FactsQuerySum("tut_fight_use_slomo") > 0)
  9226.         {
  9227.             theGame.RemoveTimeScale( theGame.GetTimescaleSource(ETS_TutorialFight) );
  9228.             FactsRemove("tut_fight_slomo_ON");
  9229.         }
  9230.        
  9231.         // State
  9232.         if( !substateManager.ReactOnBeingHit( damageAction ) )
  9233.         {
  9234.             GoToCombatIfNeeded();
  9235.             //PushState( 'CombatFists' );
  9236.         }
  9237.        
  9238.         return sup;
  9239.     }
  9240.    
  9241.     protected function ShouldPauseHealthRegenOnHit() : bool
  9242.     {
  9243.         return true;
  9244.     }
  9245.    
  9246.     public function PlayHitEffect(damageAction : W3DamageAction)
  9247.     {
  9248.         super.PlayHitEffect(damageAction);
  9249.  
  9250.         //fullscreen hit fx
  9251.         if(damageAction.DealsAnyDamage() && !damageAction.IsDoTDamage())
  9252.             PlayEffect('hit_screen');
  9253.     }
  9254.    
  9255.     function HitReactionEffect( interval : float )
  9256.     {
  9257.         if ( hitReactionEffect )
  9258.         {
  9259.             PlayEffect( 'radial_blur' );
  9260.             hitReactionEffect = false;
  9261.         }
  9262.         else
  9263.         {
  9264.             AddTimer( 'HitReactionEffectCooldown', interval, false );
  9265.         }
  9266.     }
  9267.    
  9268.     timer function HitReactionEffectCooldown( td : float , id : int)
  9269.     {
  9270.         hitReactionEffect = true;
  9271.     }
  9272.     //////////////////////////////////////////////////////////////////////////////////////////
  9273.     //
  9274.     // @Parry
  9275.     //
  9276.     //////////////////////////////////////////////////////////////////////////////////////////
  9277.     // W3EE - Begin
  9278.     public function HasStaminaToParry( attackName : name ) : bool
  9279.     {
  9280.         return (IsHeavyAttack(attackName) && HasStaminaToUseAction(ESAT_Parry, , 1.2f)) || (IsLightAttack(attackName) && HasStaminaToUseAction(ESAT_Parry));
  9281.     }
  9282.    
  9283.     function PerformParryCheck( parryInfo : SParryInfo ) : bool
  9284.     {
  9285.         var mult                    : float;
  9286.         var parryType               : EParryType;
  9287.         var parryDir                : EPlayerParryDirection;
  9288.         var parryHeading            : float;
  9289.         var fistFightParry          : bool;
  9290.         var action                  : W3DamageAction;
  9291.         var xmlStaminaDamage        : float;
  9292.         var xmlStaminaDamageName    : name = 'stamina_damage' ;
  9293.         var counter