Advertisement
Guest User

witcher 3 error

a guest
Aug 11th, 2018
378
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 482.08 KB | None | 0 0
  1.  
  2. /** © 2015 CD PROJEKT S.A. All rights reserved.
  3. /** THE WITCHER® is a trademark of CD PROJEKT S. A.
  4. /** The Witcher game is based on the prose of Andrzej Sapkowski.
  5. /***********************************************************************/
  6. 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 : int;
  9294. var onHitCounter : SAbilityAttributeValue;
  9295.  
  9296. // if ( !parryInfo.canBeParried )
  9297. // return false;
  9298.  
  9299. if(CanParryAttack() && /*parryInfo.targetToAttackerAngleAbs < theGame.params.PARRY_HALF_ANGLE &&*/ FistFightCheck( parryInfo.target, parryInfo.attacker, fistFightParry ) )
  9300. if( shieldItem )
  9301. return shieldItem.ProcessShieldParry(this, parryInfo);
  9302.  
  9303. if( CanParryAttack() && FistFightCheck(parryInfo.target, parryInfo.attacker, fistFightParry) )
  9304. {
  9305. parryHeading = GetParryHeading( parryInfo, parryDir ) ;
  9306. //GetVisualDebug().AddArrow( 'CombatActionHeading', GetWorldPosition(), GetWorldPosition() + VecFromHeading( GetParryHeading( parryInfo, parryDir ) )*2, 1.f, 0.2f, 0.2f, true, Color(0,255,255), true, 5.f );
  9307. SetBehaviorVariable( 'parryDirection', (float)( (int)( parryDir ) ) );
  9308. SetBehaviorVariable( 'parryDirectionOverlay', (float)( (int)( parryDir ) ) );
  9309. SetBehaviorVariable( 'parryType', ChooseParryTypeIndex( parryInfo ) );
  9310.  
  9311. if ( IsInCombatActionFriendly() )
  9312. RaiseEvent('CombatActionFriendlyEnd');
  9313.  
  9314. if( GetSkillLevel(S_Sword_s10) < 3 && parryDir == PPD_Back )
  9315. return false;
  9316.  
  9317. this.SetBehaviorVariable( 'combatActionType', (int)CAT_Parry );
  9318.  
  9319. if ( parryInfo.targetToAttackerDist > 3.f && !bLAxisReleased && !thePlayer.IsCiri() )
  9320. {
  9321. if ( !RaiseForceEvent( 'PerformParryOverlay' ) )
  9322. return false;
  9323. else
  9324. {
  9325. if( !CanUseSkill(S_Sword_s10) )
  9326. Combat().StaminaLoss(ESAT_Parry);
  9327. ClearCustomOrientationInfoStack();
  9328. IncDefendCounter();
  9329. }
  9330. }
  9331. else
  9332. {
  9333. counter = GetDefendCounter();
  9334. onHitCounter = parryInfo.attacker.GetAttributeValue( 'break_through_parry_on_hit_counter' );
  9335. if ( onHitCounter.valueBase > 0 && counter == onHitCounter.valueBase )
  9336. {
  9337. AddEffectDefault( EET_Stagger, parryInfo.attacker, "Break through parry" );
  9338. }
  9339. else if ( RaiseForceEvent( 'PerformParry' ) )
  9340. {
  9341. if( parryInfo.targetToAttackerDist > 3.f )
  9342. {
  9343. if( !CanUseSkill(S_Sword_s10) )
  9344. Combat().StaminaLoss(ESAT_Parry);
  9345. }
  9346.  
  9347. OnCombatActionStart();
  9348. ClearCustomOrientationInfoStack();
  9349. SetSlideTarget( parryInfo.attacker );
  9350. SetCustomRotation( 'Parry', parryHeading, 1080.f, 0.1f, false );
  9351. IncDefendCounter();
  9352. }
  9353. else
  9354. return false;
  9355. }
  9356. //parryTarget := this
  9357. if ( parryInfo.attacker.IsWeaponHeld( 'fist' ) && !parryInfo.target.IsWeaponHeld( 'fist' ) )
  9358. {
  9359. parryInfo.attacker.ReactToReflectedAttack(parryInfo.target);
  9360. }
  9361. else
  9362. {
  9363. if(IsLightAttack(parryInfo.attackActionName))
  9364. parryInfo.target.PlayEffectOnHeldWeapon('light_block');
  9365. else
  9366. parryInfo.target.PlayEffectOnHeldWeapon('heavy_block');
  9367. }
  9368. return true;
  9369. }
  9370.  
  9371. return false;
  9372. }
  9373.  
  9374. public function GetParryHeading( parryInfo : SParryInfo, out parryDir : EPlayerParryDirection ) : float
  9375. // W3EE - End
  9376. {
  9377. var targetToAttackerHeading : float;
  9378. var currToTargetAttackerAngleDiff : float;
  9379.  
  9380. targetToAttackerHeading = VecHeading( parryInfo.attacker.GetWorldPosition() - parryInfo.target.GetWorldPosition() );
  9381. currToTargetAttackerAngleDiff = AngleDistance( VecHeading( parryInfo.target.GetHeadingVector() ), targetToAttackerHeading );
  9382.  
  9383. if ( !parryInfo.target.IsWeaponHeld( 'fist' ) )
  9384. {
  9385. if( currToTargetAttackerAngleDiff > -45 && currToTargetAttackerAngleDiff < 45 )
  9386. {
  9387. parryDir = PPD_Forward;
  9388. return targetToAttackerHeading;
  9389. }
  9390. else if( currToTargetAttackerAngleDiff >= 45 && currToTargetAttackerAngleDiff < 135 )
  9391. {
  9392. parryDir = PPD_Right;
  9393. //return targetToAttackerHeading;
  9394. return targetToAttackerHeading + 90;
  9395. }
  9396. else if( currToTargetAttackerAngleDiff <= -45 && currToTargetAttackerAngleDiff > -135 )
  9397. {
  9398. parryDir = PPD_Left;
  9399. //return targetToAttackerHeading;
  9400. return targetToAttackerHeading - 90;
  9401. }
  9402. else
  9403. {
  9404. parryDir = PPD_Back;
  9405. //return targetToAttackerHeading;
  9406. return targetToAttackerHeading + 180;
  9407. }
  9408. }
  9409. else
  9410. {
  9411. if( currToTargetAttackerAngleDiff > -45 && currToTargetAttackerAngleDiff < 45 )
  9412. {
  9413. parryDir = PPD_Forward;
  9414. return targetToAttackerHeading;
  9415. }
  9416. else if( currToTargetAttackerAngleDiff >= 45 && currToTargetAttackerAngleDiff < 180 )
  9417. {
  9418. parryDir = PPD_Right;
  9419. return targetToAttackerHeading + 90;
  9420. }
  9421. else if( currToTargetAttackerAngleDiff <= -45 && currToTargetAttackerAngleDiff >= -180 )
  9422. {
  9423. parryDir = PPD_Left;
  9424. return targetToAttackerHeading - 90;
  9425. }
  9426. else
  9427. {
  9428. parryDir = PPD_Back;
  9429. return targetToAttackerHeading + 180;
  9430. }
  9431. }
  9432. }
  9433.  
  9434. function ProcessLockTarget( optional newLockTarget : CActor, optional checkLeftStickHeading : bool ) : bool
  9435. {
  9436. var attackerNearestPoint : Vector;
  9437. var playerNearestPoint : Vector;
  9438. var incomingAttacker : CActor;
  9439. var tempLockTarget : CActor;
  9440. var target : CActor;
  9441. var useIncomingAttacker : bool;
  9442.  
  9443. if( newLockTarget.HasTag( 'NoHardLock' ) )
  9444. return false;
  9445.  
  9446. if ( newLockTarget )
  9447. tempLockTarget = newLockTarget;
  9448. else
  9449. {
  9450. incomingAttacker = GetClosestIncomingAttacker();
  9451. if ( incomingAttacker && incomingAttacker.IsAlive() && IsUsingVehicle() )
  9452. {
  9453. tempLockTarget = incomingAttacker;
  9454. useIncomingAttacker = false;
  9455. }
  9456.  
  9457. if ( !useIncomingAttacker )
  9458. {
  9459. target = GetTarget();
  9460. if( target.HasTag('ForceHardLock'))
  9461. {
  9462. return true;
  9463. }
  9464. else if ( target && target.IsAlive() && target.GetGameplayVisibility() && IsEnemyVisible( target ) && IsThreat( target ) && CanBeTargetedIfSwimming( target ) )
  9465. tempLockTarget = FindTarget();
  9466. else
  9467. {
  9468. tempLockTarget = GetScreenSpaceLockTarget( GetDisplayTarget(), 180.f, 1.f, 0.f );
  9469. }
  9470. }
  9471. }
  9472.  
  9473. if( tempLockTarget.HasTag( 'NoHardLock' ) )
  9474. return false;
  9475.  
  9476. if ( tempLockTarget )
  9477. {
  9478. if ( IsCombatMusicEnabled() || hostileEnemies.Size() > 0 )
  9479. {
  9480. if ( !IsThreat( tempLockTarget ) )
  9481. tempLockTarget = NULL;
  9482. }
  9483. }
  9484.  
  9485. SetTarget( tempLockTarget, true );
  9486. SetMoveTargetChangeAllowed( true );
  9487. SetMoveTarget( tempLockTarget );
  9488. SetMoveTargetChangeAllowed( false );
  9489. SetSlideTarget( tempLockTarget );
  9490.  
  9491. if ( tempLockTarget )
  9492. {
  9493. if ( this.IsActorLockedToTarget() )
  9494. EnableHardLockIcon( true );
  9495.  
  9496. return true;
  9497. }
  9498. else
  9499. return false;
  9500. }
  9501.  
  9502. //////////////////////////////////////////////////////////////////////////////////////////
  9503. //////////////////////// @COMBAT ///////////////////////////////////////////////////////
  9504. //////////////////////////////////////////////////////////////////////////////////////////
  9505.  
  9506. event OnTaskSyncAnim( npc : CNewNPC, animNameLeft : name ) {}
  9507.  
  9508. //checks if player is doing special attack light/heavy
  9509. public function IsDoingSpecialAttack(heavy : bool) : bool
  9510. {
  9511. var pat : EPlayerAttackType;
  9512.  
  9513. if(IsInCombatAction() && ( (int)GetBehaviorVariable('combatActionType')) == CAT_SpecialAttack)
  9514. {
  9515. pat = (int)GetBehaviorVariable('playerAttackType');
  9516.  
  9517. if(heavy && pat == PAT_Heavy)
  9518. {
  9519. return true;
  9520. }
  9521. else if(!heavy && pat == PAT_Light)
  9522. {
  9523. return true;
  9524. }
  9525. }
  9526.  
  9527. return false;
  9528. }
  9529.  
  9530. public function SetIsCurrentlyDodging(enable : bool, optional isRolling : bool)
  9531. {
  9532. super.SetIsCurrentlyDodging(enable, isRolling);
  9533.  
  9534. if ( isRolling )
  9535. {
  9536. SetCanPlayHitAnim( false );
  9537. this.AddBuffImmunity( EET_KnockdownTypeApplicator, 'Roll', false );
  9538. this.AddBuffImmunity( EET_Knockdown, 'Roll', false );
  9539. this.AddBuffImmunity( EET_HeavyKnockdown, 'Roll', false );
  9540. this.AddBuffImmunity( EET_Stagger, 'Roll', false );
  9541. }
  9542. else
  9543. {
  9544. SetCanPlayHitAnim( true );
  9545. this.RemoveBuffImmunity( EET_KnockdownTypeApplicator, 'Roll' );
  9546. this.RemoveBuffImmunity( EET_Knockdown, 'Roll' );
  9547. this.RemoveBuffImmunity( EET_HeavyKnockdown, 'Roll' );
  9548. this.RemoveBuffImmunity( EET_Stagger, 'Roll' );
  9549. }
  9550. }
  9551.  
  9552. public function EnableHardLock( flag : bool )
  9553. {
  9554. super.EnableHardLock(flag);
  9555.  
  9556. if(flag && ShouldProcessTutorial('TutorialTargettingWaiting'))
  9557. {
  9558. FactsAdd("tut_hardlocked");
  9559. }
  9560. }
  9561.  
  9562. protected function TestParryAndCounter(data : CPreAttackEventData, weaponId : SItemUniqueId, out parried : bool, out countered : bool) : array<CActor>
  9563. {
  9564. var ret : array<CActor>;
  9565.  
  9566. //cheat for QA tests - NPCs won't parry/counter
  9567. if(FactsQuerySum('player_is_the_boss') > 0)
  9568. {
  9569. //---------------- DEBUG
  9570. //draw debug AR
  9571. SetDebugAttackRange(data.rangeName);
  9572. RemoveTimer('PostAttackDebugRangeClear'); //disable AR clearing since we've just set a new one
  9573.  
  9574. return ret;
  9575. }
  9576.  
  9577. ret = super.TestParryAndCounter(data, weaponId, parried, countered);
  9578.  
  9579. //achievement
  9580. if(parried)
  9581. theGame.GetGamerProfile().ResetStat(ES_CounterattackChain);
  9582.  
  9583. return ret;
  9584. }
  9585.  
  9586. public function SetSpecialAttackTimeRatio(f : float)
  9587. {
  9588. LogSpecialHeavy(f);
  9589. specialAttackTimeRatio = f;
  9590. }
  9591.  
  9592. public function GetSpecialAttackTimeRatio() : float
  9593. {
  9594. return specialAttackTimeRatio;
  9595. }
  9596.  
  9597. //called when we processed special heavy attack action - either from hit or from CombatActionEnd()
  9598. public function OnSpecialAttackHeavyActionProcess()
  9599. {
  9600. //clear ration after attack performed
  9601. SetSpecialAttackTimeRatio(0.f);
  9602. }
  9603.  
  9604. protected function DoAttack(animData : CPreAttackEventData, weaponId : SItemUniqueId, parried : bool, countered : bool, parriedBy : array<CActor>, attackAnimationName : name, hitTime : float)
  9605. {
  9606. var shakeStr : float;
  9607. var weapon : EPlayerWeapon;
  9608. var targetActor : CActor;
  9609.  
  9610. //cam shake for player's heavy attacks
  9611. var attackDistance : EAttackDistance;
  9612. var attackNameString : string;
  9613.  
  9614. Combat().AttackCameraShake(animData.attackName);
  9615. Combat().ObliterationRunewordLvl1Flame();
  9616. Combat().SeveranceRunewordSignEffect(((W3PlayerWitcher)this).GetRunewordInfusionType());
  9617. Experience().AwardNonCombatXP(animData.attackName);
  9618. // W3EE - End
  9619.  
  9620. if ( animData.attackName == 'attack_heavy_special' )
  9621. {
  9622. if( specialAttackTimeRatio != 1 )
  9623. shakeStr = (specialAttackTimeRatio / 3.333) + 0.2;
  9624. else
  9625. shakeStr = 0.5;
  9626.  
  9627. GCameraShake( shakeStr, false, GetWorldPosition(), 10);
  9628. }
  9629. // W3EE - Begin
  9630. /*
  9631. else if ( IsHeavyAttack(attackActionName) )
  9632. {
  9633. if(parriedBy.Size() > 0)
  9634. shakeStr = 0.2;
  9635. else
  9636. shakeStr = 0.1;
  9637.  
  9638. GCameraShake(shakeStr, false, GetWorldPosition(), 10);
  9639. }
  9640. */
  9641. // W3EE - End
  9642.  
  9643. targetActor = (CActor)slideTarget;
  9644. if ( targetActor && hitTargets.Contains(targetActor) )
  9645. {
  9646. weapon = this.GetMostConvenientMeleeWeapon(targetActor,true);
  9647. if ( this.GetCurrentMeleeWeaponType() != PW_Fists && weapon != this.GetCurrentMeleeWeaponType() )
  9648. {
  9649. if ( weapon == PW_Steel )
  9650. {
  9651. thePlayer.OnEquipMeleeWeapon(PW_Steel,true);
  9652. }
  9653. else if ( weapon == PW_Silver )
  9654. {
  9655. thePlayer.OnEquipMeleeWeapon(PW_Silver,true);
  9656. }
  9657.  
  9658. }
  9659. }
  9660.  
  9661. super.DoAttack(animData, weaponId, parried, countered, parriedBy, attackAnimationName, hitTime);
  9662.  
  9663. // W3EE - Begin
  9664. if( IsLightAttack(animData.attackName) )
  9665. {
  9666. Combat().ActivateSwordDance();
  9667. ((W3Effect_SwordSignDancer)GetBuff(EET_SwordSignDancer)).CountActionType(ESA_FastAttack);
  9668. }
  9669. else
  9670. if( IsHeavyAttack(animData.attackName) )
  9671. ((W3Effect_SwordSignDancer)GetBuff(EET_SwordSignDancer)).CountActionType(ESA_StrongAttack);
  9672.  
  9673. SetPlayerAttacking(false);
  9674. if( IsInCombatAction_SpecialAttack() || IsSpecialAttack(animData.attackName) || IsCounterAttack(animData.attackName) )
  9675. return;
  9676.  
  9677. attackNameString = NameToString(attackAnimationName);
  9678. if( StrContains(attackNameString, "_far_") )
  9679. {
  9680. if( StrContains(attackNameString, "_mod") )
  9681. attackDistance = ADIST_Large;
  9682. else
  9683. attackDistance = ADIST_Medium;
  9684. }
  9685. else attackDistance = ADIST_Small;
  9686.  
  9687. switch(attackDistance)
  9688. {
  9689. case ADIST_Large:
  9690. if( IsHeavyAttack(animData.attackName) )
  9691. Combat().StaminaLoss(ESAT_HeavyAttack, 1.20f);
  9692. else
  9693. Combat().StaminaLoss(ESAT_LightAttack, 1.20f);
  9694. break;
  9695.  
  9696. case ADIST_Medium:
  9697. if( IsHeavyAttack(animData.attackName) )
  9698. Combat().StaminaLoss(ESAT_HeavyAttack, 1.10f);
  9699. else
  9700. Combat().StaminaLoss(ESAT_LightAttack, 1.10f);
  9701. break;
  9702.  
  9703. case ADIST_Small:
  9704. if( IsHeavyAttack(animData.attackName) )
  9705. Combat().StaminaLoss(ESAT_HeavyAttack);
  9706. else
  9707. Combat().StaminaLoss(ESAT_LightAttack);
  9708. break;
  9709.  
  9710. default:
  9711. Combat().StaminaLoss(ESAT_HeavyAttack);
  9712. break;
  9713. }
  9714.  
  9715. SetWasPlayerSpamming(false);
  9716. }
  9717.  
  9718. //var delayCombatStanceTimeStamp : float;
  9719.  
  9720. private var confirmCombatStanceTimeStamp : float;
  9721. private var isConfirmingCombatStance : bool;
  9722. final function SetPlayerCombatStance(stance : EPlayerCombatStance, optional force : bool )
  9723. {
  9724. var stanceInt : int;
  9725.  
  9726. if ( !CanChangeCombatStance( stance, force ) )
  9727. return;
  9728.  
  9729. combatStance = stance;
  9730. stanceInt = (int)stance;
  9731.  
  9732. SetBehaviorVariable( 'playerCombatStance' , (float)stanceInt);
  9733. SetBehaviorVariable( 'playerCombatStanceForOverlay' , (float)stanceInt);
  9734. if ( force )
  9735. SetBehaviorVariable( 'forceCombatStance' , 1.f);
  9736. else
  9737. SetBehaviorVariable( 'forceCombatStance' , 0.f);
  9738.  
  9739. if ( stance == PCS_AlertNear )
  9740. this.SetBehaviorVariable('isInCombatForOverlay',1.f);
  9741. else
  9742. this.SetBehaviorVariable('isInCombatForOverlay',0.f);
  9743. }
  9744.  
  9745. private function CanChangeCombatStance( stance : EPlayerCombatStance, optional force : bool ) : bool
  9746. {
  9747. var currTime : float;
  9748.  
  9749. if ( force )
  9750. return true;
  9751.  
  9752. if ( IsInFistFightMiniGame() )
  9753. return true;
  9754.  
  9755. if ( isInHolsterAnim )
  9756. return false;
  9757.  
  9758. if ( ( combatStance == PCS_Normal || combatStance == PCS_AlertFar ) && stance == PCS_AlertNear )
  9759. {
  9760. currTime = theGame.GetEngineTimeAsSeconds();
  9761. if ( !isConfirmingCombatStance )
  9762. {
  9763. isConfirmingCombatStance = true;
  9764. confirmCombatStanceTimeStamp = currTime;
  9765.  
  9766. return false;
  9767. }
  9768. else if ( currTime < confirmCombatStanceTimeStamp + 1.f )
  9769. {
  9770. if ( stance == PCS_AlertNear )
  9771. return false;
  9772. }
  9773. else
  9774. isConfirmingCombatStance = false;
  9775. }
  9776. else
  9777. isConfirmingCombatStance = false;
  9778.  
  9779. return true;
  9780. }
  9781.  
  9782. private var isInHolsterAnim : bool;
  9783. event OnHolsterWeaponStart()
  9784. {
  9785. isInHolsterAnim = true;
  9786. }
  9787.  
  9788. event OnHolsterWeaponEnd()
  9789. {
  9790. isInHolsterAnim = false;
  9791. }
  9792.  
  9793. final function GetPlayerCombatStance() : EPlayerCombatStance
  9794. {
  9795. return combatStance;
  9796. }
  9797.  
  9798. timer function DelayedDisableFindTarget( time : float , id : int)
  9799. {
  9800. if ( GetTarget().IsAlive() )
  9801. {
  9802. EnableFindTarget( false );
  9803. }
  9804. else
  9805. {
  9806. EnableFindTarget( true );
  9807. }
  9808. }
  9809.  
  9810. ///////////////////////////////////////////////////////////////////////////
  9811. // @BUFFER @COMBATACTIONBUFFER
  9812. ///////////////////////////////////////////////////////////////////////////
  9813.  
  9814. private var dodgeTimerRunning : bool;
  9815.  
  9816. function StartDodgeTimer()
  9817. {
  9818. dodgeTimerRunning = true;
  9819. thePlayer.AddTimer('DodgeTimer',0.2,false);
  9820. }
  9821.  
  9822. function StopDodgeTimer()
  9823. {
  9824. this.RemoveTimer('DodgeTimer');
  9825. dodgeTimerRunning = false;
  9826. }
  9827.  
  9828. function IsDodgeTimerRunning() : bool
  9829. {
  9830. return dodgeTimerRunning;
  9831. }
  9832.  
  9833. timer function DodgeTimer( dt : float, id : int )
  9834. {
  9835. dodgeTimerRunning = false;
  9836. }
  9837.  
  9838. public function EvadePressed( bufferAction : EBufferActionType )
  9839. {
  9840. }
  9841.  
  9842. public function PerformingCombatAction() : EBufferActionType
  9843. {
  9844. return BufferCombatAction;
  9845. }
  9846.  
  9847. public function PushCombatActionOnBuffer( action : EBufferActionType, stage : EButtonStage, optional allSteps : bool )
  9848. {
  9849. BufferButtonStage = stage;
  9850. BufferCombatAction = action;
  9851. BufferAllSteps = allSteps;
  9852. }
  9853.  
  9854. protected function ProcessCombatActionHeading( action : EBufferActionType ) : float
  9855. {
  9856. var processedActionHeading : float;
  9857.  
  9858. HandleMovement( 0.f );
  9859.  
  9860. if ( ShouldUsePCModeTargeting() )
  9861. return theGame.GetGameCamera().GetHeading();
  9862.  
  9863. if ( lAxisReleasedAfterCounter ) // && IsInCombatAction() )
  9864. ResetCachedRawPlayerHeading();
  9865.  
  9866. processedActionHeading = cachedRawPlayerHeading;
  9867.  
  9868. return processedActionHeading;
  9869. }
  9870. /*
  9871. private function ProcessCombatActionHeading( action : EBufferActionType ) : float
  9872. {
  9873. var processedActionHeading : float;
  9874. var unusedActor : CActor; //MS: placeholder variable to fix memory error
  9875.  
  9876. if ( IsUsingVehicle() )
  9877. {
  9878. processedActionHeading = theGame.GetGameCamera().GetHeading();
  9879. return processedActionHeading;
  9880. }
  9881.  
  9882. if ( !bLAxisReleased || lAxisPushedTimeStamp + 0.5f > theGame.GetEngineTimeAsSeconds() )
  9883. processedActionHeading = cachedRawPlayerHeading;
  9884. else
  9885. {
  9886. if ( GetDisplayTarget() )
  9887. {
  9888. if ( cachedCombatActionHeading == cachedRawPlayerHeading )
  9889. ResetCachedRawPlayerHeading();
  9890. else
  9891. {
  9892. cachedRawPlayerHeading = cachedCombatActionHeading;
  9893. canResetCachedCombatActionHeading = true;
  9894. }
  9895.  
  9896. processedActionHeading = cachedRawPlayerHeading;
  9897. }
  9898. else
  9899. {
  9900. if ( lAxisReleasedAfterCounterNoCA )
  9901. ResetRawPlayerHeading();
  9902.  
  9903. cachedRawPlayerHeading = rawPlayerHeading;
  9904.  
  9905. if ( lAxisReleasedAfterCounterNoCA )
  9906. processedActionHeading = GetHeading();
  9907. else
  9908. processedActionHeading = cachedRawPlayerHeading;
  9909. }
  9910. }
  9911.  
  9912. if ( this.IsCameraLockedToTarget() && this.IsActorLockedToTarget() && action != EBAT_Dodge && action != EBAT_Roll )
  9913. processedActionHeading = theGame.GetGameCamera().GetHeading();
  9914.  
  9915. if ( lAxisReleasedAfterCounterNoCA )
  9916. {
  9917. if ( action == EBAT_Dodge || action == EBAT_Roll )
  9918. {
  9919. if ( ( !IsEnemyInCone( this, GetHeadingVector(), softLockDist, 60.f, unusedActor ) || !IsEnemyInCone( this, GetHeadingVector() + 180, softLockDist, 60.f, unusedActor ) ) && moveTarget )
  9920. processedActionHeading = VecHeading( moveTarget.GetWorldPosition() - GetWorldPosition() ) + 180;
  9921. else
  9922. processedActionHeading = GetHeading() + 180;
  9923. }
  9924. }
  9925.  
  9926. //GetVisualDebug().AddArrow( 'cachedRawPlayerHeading', GetWorldPosition(), GetWorldPosition() + VecFromHeading( cachedRawPlayerHeading ), 1.f, 0.2f, 0.2f, true, Color(0,255,128), true, 5.f );
  9927. //GetVisualDebug().AddArrow( 'CombatActionHeading', GetWorldPosition(), GetWorldPosition() + VecFromHeading( GetCombatActionHeading() )*2, 1.f, 0.2f, 0.2f, true, Color(0,255,255), true, 5.f );
  9928.  
  9929. return processedActionHeading;
  9930. }*/
  9931.  
  9932. function ResetRawPlayerHeading()
  9933. {
  9934. if ( GetDisplayTarget() )
  9935. rawPlayerHeading = VecHeading( GetDisplayTarget().GetWorldPosition() - this.GetWorldPosition() );
  9936. else
  9937. rawPlayerHeading = GetHeading();
  9938.  
  9939. //LogChannel('ResetRawPlayerHeading',"ResetRawPlayerHeading" );
  9940. }
  9941.  
  9942. function ResetCachedRawPlayerHeading()
  9943. {
  9944. cachedRawPlayerHeading = rawPlayerHeading;
  9945. if ( GetDisplayTarget() && IsDisplayTargetTargetable() && AbsF( AngleDistance( VecHeading( GetDisplayTarget().GetWorldPosition() - this.GetWorldPosition() ), this.GetHeading() ) ) < 90.f )
  9946. cachedRawPlayerHeading = VecHeading( GetDisplayTarget().GetWorldPosition() - this.GetWorldPosition() );
  9947. else
  9948. cachedRawPlayerHeading = this.GetHeading();
  9949.  
  9950. if ( canResetCachedCombatActionHeading )
  9951. cachedCombatActionHeading = cachedRawPlayerHeading;
  9952. }
  9953.  
  9954. public function GetCombatActionTarget( action : EBufferActionType ) : CGameplayEntity
  9955. {
  9956. var selectedTargetableEntity : CGameplayEntity;
  9957.  
  9958. if ( !this.IsUsingVehicle() )
  9959. selectedTargetableEntity = FindNonActorTarget( true, action );
  9960.  
  9961. if ( selectedTargetableEntity )
  9962. {
  9963. return selectedTargetableEntity;
  9964. }
  9965. else
  9966. {
  9967. /*if ( !IsCombatMusicEnabled() && displayTarget )
  9968. {
  9969. if ( !( (CActor)displayTarget ) )
  9970. return NULL;
  9971. else
  9972. return displayTarget;
  9973. }*/
  9974.  
  9975. if ( !this.IsUsingVehicle() )
  9976. FindTarget( true, action, true );
  9977. else
  9978. ((CR4PlayerStateUseGenericVehicle)this.GetState( 'UseGenericVehicle' )).FindTarget();
  9979.  
  9980. return GetTarget();
  9981. }
  9982. }
  9983.  
  9984. //MS: FindNonActorTarget may or may not have an interaction component, which is why it is separate from ProcessInteraction
  9985. private function FindNonActorTarget( actionCheck : bool, optional action : EBufferActionType ) : CGameplayEntity
  9986. {
  9987. var targetableEntities : array<CGameplayEntity>;
  9988. var selectedTargetableEntity : CGameplayEntity;
  9989. var selectionPriority : array< float >;
  9990. var selectionWeights : STargetSelectionWeights;
  9991. var findEntityDist : float;
  9992. var i, size : int;
  9993. var playerHeading : float;
  9994. var playerInventory : CInventoryComponent;
  9995. var castSignType : ESignType;
  9996. var targetingInfo : STargetingInfo;
  9997. var playerPosition : Vector;
  9998. var cameraPosition : Vector;
  9999. var playerHeadingVector : Vector;
  10000. var rawPlayerHeadingVector : Vector;
  10001.  
  10002. playerPosition = this.GetWorldPosition();
  10003. cameraPosition = theCamera.GetCameraPosition();
  10004. rawPlayerHeadingVector = VecFromHeading( rawPlayerHeading );
  10005.  
  10006. if ( bCanFindTarget && !IsHardLockEnabled() )
  10007. {
  10008. if ( actionCheck && IsInCombat() && action == EBAT_CastSign )
  10009. {
  10010. findEntityDist = 6.f;
  10011. selectionWeights.angleWeight = 0.375f;
  10012. selectionWeights.distanceWeight = 0.275f;
  10013. selectionWeights.distanceRingWeight = 0.35f;
  10014. }
  10015. else if ( !IsInCombat() && lastAxisInputIsMovement )
  10016. {
  10017. findEntityDist = softLockDist;
  10018. selectionWeights.angleWeight = 0.375f;
  10019. selectionWeights.distanceWeight = 0.275f;
  10020. selectionWeights.distanceRingWeight = 0.35f;
  10021. }
  10022. else
  10023. {
  10024. findEntityDist = softLockDist;
  10025. selectionWeights.angleWeight = 0.75f;
  10026. selectionWeights.distanceWeight = 0.125f;
  10027. selectionWeights.distanceRingWeight = 0.125f;
  10028. }
  10029.  
  10030. //MSTODO : Ask programmers for filter for interactive entities
  10031. if ( !IsInCombat() || !bLAxisReleased )
  10032. {
  10033. FindGameplayEntitiesInRange( targetableEntities, this, findEntityDist, 10, theGame.params.TAG_SOFT_LOCK );
  10034. }
  10035.  
  10036. if ( targetableEntities.Size() > 0 )
  10037. {
  10038. playerInventory = this.GetInventory();
  10039. castSignType = this.GetEquippedSign();
  10040.  
  10041. if ( !bLAxisReleased )
  10042. {
  10043. targetingInfo.source = this;
  10044. targetingInfo.canBeTargetedCheck = false;
  10045. targetingInfo.coneCheck = true;
  10046. targetingInfo.coneHalfAngleCos = 0.5f; // = CosF( Deg2Rad( 120.0f * 0.5f ) )
  10047. targetingInfo.coneDist = softLockDist;
  10048. targetingInfo.coneHeadingVector = rawPlayerHeadingVector;
  10049. targetingInfo.distCheck = true;
  10050. targetingInfo.invisibleCheck = false;
  10051. targetingInfo.navMeshCheck = false;
  10052. targetingInfo.frameScaleX = 1.0f;
  10053. targetingInfo.frameScaleY = 1.0f;
  10054. targetingInfo.knockDownCheck = false;
  10055. targetingInfo.knockDownCheckDist = 0.0f;
  10056. targetingInfo.rsHeadingCheck = false;
  10057. targetingInfo.rsHeadingLimitCos = 1.0f;
  10058. }
  10059.  
  10060. for( i = targetableEntities.Size()-1; i>=0; i-=1 )
  10061. {
  10062. if ( bLAxisReleased )
  10063. {
  10064. if ( !lastAxisInputIsMovement )
  10065. {
  10066. if ( !WasVisibleInScaledFrame( targetableEntities[i], 0.9f, 0.9f ) )
  10067. {
  10068. targetableEntities.Erase(i);
  10069. continue;
  10070. }
  10071. }
  10072. else if ( !WasVisibleInScaledFrame( targetableEntities[i], 1.f, 1.f ) )
  10073. {
  10074. targetableEntities.Erase(i);
  10075. continue;
  10076. }
  10077. }
  10078. else
  10079. {
  10080. targetingInfo.targetEntity = targetableEntities[i];
  10081. if ( actionCheck && moveTarget )
  10082. {
  10083. targetingInfo.inFrameCheck = false;
  10084. if ( !IsEntityTargetable( targetingInfo ) )
  10085. {
  10086. targetableEntities.Erase(i);
  10087. continue;
  10088. }
  10089. }
  10090. else
  10091. {
  10092. targetingInfo.inFrameCheck = true;
  10093. if ( !IsEntityTargetable( targetingInfo ) )
  10094. {
  10095. targetableEntities.Erase(i);
  10096. continue;
  10097. }
  10098. }
  10099. }
  10100.  
  10101. if ( actionCheck )
  10102. {
  10103. if ( action == EBAT_ItemUse )
  10104. {
  10105. if ( ( playerInventory.IsItemBomb( this.GetSelectedItemId() ) && !targetableEntities[i].HasTag( 'softLock_Bomb' ) )
  10106. || ( playerInventory.IsItemCrossbow( this.GetSelectedItemId() ) && !targetableEntities[i].HasTag( 'softLock_Bolt' ) ) )
  10107. {
  10108. targetableEntities.Erase(i);
  10109. continue;
  10110. }
  10111. }
  10112. else if ( action == EBAT_CastSign )
  10113. {
  10114. if ( ( castSignType == ST_Aard && !targetableEntities[i].HasTag( 'softLock_Aard' ) )
  10115. || ( castSignType == ST_Igni && !targetableEntities[i].HasTag( 'softLock_Igni' ) )
  10116. || ( castSignType == ST_Axii && !targetableEntities[i].HasTag( 'softLock_Axii' ) )
  10117. || castSignType == ST_Yrden
  10118. || castSignType == ST_Quen )
  10119. {
  10120. targetableEntities.Erase(i);
  10121. continue;
  10122. }
  10123. }
  10124. else if ( action == EBAT_LightAttack || action == EBAT_HeavyAttack || action == EBAT_SpecialAttack_Heavy )
  10125. {
  10126. if ( ( IsWeaponHeld( 'fist' ) && !targetableEntities[i].HasTag( 'softLock_Fist' ) ) || ( !IsWeaponHeld( 'fist' ) && !targetableEntities[i].HasTag( 'softLock_Weapon' ) ) )
  10127. {
  10128. targetableEntities.Erase(i);
  10129. continue;
  10130. }
  10131. }
  10132. else
  10133. {
  10134. targetableEntities.Erase(i);
  10135. continue;
  10136. }
  10137. }
  10138. }
  10139. }
  10140.  
  10141. if ( targetableEntities.Size() > 0)
  10142. {
  10143. playerHeading = this.GetHeading();
  10144. playerHeadingVector = this.GetHeadingVector();
  10145. if ( IsInCombat() )
  10146. {
  10147. for( i = 0; i < targetableEntities.Size(); i += 1 )
  10148. {
  10149. if ( bLAxisReleased )
  10150. selectionPriority.PushBack( CalcSelectionPriority( targetableEntities[i], selectionWeights, cameraPosition, rawPlayerHeadingVector ) );
  10151. else
  10152. selectionPriority.PushBack( CalcSelectionPriority( targetableEntities[i], selectionWeights, playerPosition, rawPlayerHeadingVector ) );
  10153. }
  10154.  
  10155. if ( selectionPriority.Size() > 0 )
  10156. selectedTargetableEntity = targetableEntities[ ArrayFindMaxF( selectionPriority ) ];
  10157. }
  10158. else
  10159. {
  10160. if ( bLAxisReleased )
  10161. {
  10162. if ( !lastAxisInputIsMovement )
  10163. {
  10164. for( i = 0; i < targetableEntities.Size(); i += 1 )
  10165. selectionPriority.PushBack( CalcSelectionPriority( targetableEntities[i], selectionWeights, cameraPosition, rawPlayerHeadingVector ) );
  10166.  
  10167. if ( selectionPriority.Size() > 0 )
  10168. selectedTargetableEntity = targetableEntities[ ArrayFindMaxF( selectionPriority ) ];
  10169. }
  10170. else
  10171. {
  10172. if ( IsInCombatAction() )
  10173. selectedTargetableEntity = nonActorTarget;
  10174. else
  10175. {
  10176. for( i = 0; i < targetableEntities.Size(); i += 1 )
  10177. selectionPriority.PushBack( CalcSelectionPriority( targetableEntities[i], selectionWeights, playerPosition, playerHeadingVector ) );
  10178.  
  10179. if ( selectionPriority.Size() > 0 )
  10180. {
  10181. selectedTargetableEntity = targetableEntities[ ArrayFindMaxF( selectionPriority ) ];
  10182.  
  10183. targetingInfo.source = this;
  10184. targetingInfo.targetEntity = selectedTargetableEntity;
  10185. targetingInfo.canBeTargetedCheck = false;
  10186. targetingInfo.coneCheck = true;
  10187. targetingInfo.coneHalfAngleCos = 0.0f; // = CosF( Deg2Rad( 180.0f * 0.5f ) )
  10188. targetingInfo.coneDist = softLockDist;
  10189. targetingInfo.coneHeadingVector = this.GetHeadingVector();
  10190. targetingInfo.distCheck = true;
  10191. targetingInfo.invisibleCheck = false;
  10192. targetingInfo.navMeshCheck = false;
  10193. targetingInfo.inFrameCheck = false;
  10194. targetingInfo.frameScaleX = 1.0f;
  10195. targetingInfo.frameScaleY = 1.0f;
  10196. targetingInfo.knockDownCheck = false;
  10197. targetingInfo.knockDownCheckDist = 0.0f;
  10198. targetingInfo.rsHeadingCheck = false;
  10199. targetingInfo.rsHeadingLimitCos = 1.0f;
  10200.  
  10201. if ( !IsEntityTargetable( targetingInfo ) )
  10202. selectedTargetableEntity = NULL;
  10203. }
  10204. }
  10205. }
  10206. }
  10207. else
  10208. {
  10209. for( i = 0; i < targetableEntities.Size(); i += 1 )
  10210. selectionPriority.PushBack( CalcSelectionPriority( targetableEntities[i], selectionWeights, playerPosition, rawPlayerHeadingVector ) );
  10211.  
  10212. if ( selectionPriority.Size() > 0 )
  10213. selectedTargetableEntity = targetableEntities[ ArrayFindMaxF( selectionPriority ) ];
  10214. }
  10215. }
  10216. }
  10217. else
  10218. selectedTargetableEntity = NULL;
  10219. }
  10220.  
  10221. SetNonActorTarget( selectedTargetableEntity );
  10222. return selectedTargetableEntity;
  10223. }
  10224. /*
  10225. timer function IsItemUseInputHeld ( time : float , id : int)
  10226. {
  10227. if ( GetBIsInputAllowed()
  10228. && GetBIsCombatActionAllowed()
  10229. && IsActionAllowed( EIAB_Crossbow )
  10230. && inv.IsIdValid( GetSelectedItemId() )
  10231. && inv.IsItemCrossbow( GetSelectedItemId()En )
  10232. && rangedWeapon.GetCurrentStateName() == 'State_WeaponWait' )
  10233. {
  10234. SetIsAimingCrossbow( true );
  10235. PushCombatActionOnBuffer( EBAT_ItemUse, BS_Pressed );
  10236. ProcessCombatActionBuffer();
  10237. }
  10238.  
  10239. if ( theInput.GetActionValue( 'ThrowItem' ) == 0.f )
  10240. {
  10241. if ( GetBIsCombatActionAllowed() )
  10242. {
  10243. PushCombatActionOnBuffer( EBAT_ItemUse, BS_Pressed );
  10244. ProcessCombatActionBuffer();
  10245. }
  10246.  
  10247. SetIsAimingCrossbow( false );
  10248. RemoveTimer( 'IsItemUseInputHeld' );
  10249. }
  10250. }*/
  10251.  
  10252. public function SetupCombatAction( action : EBufferActionType, stage : EButtonStage )
  10253. {
  10254. var weaponType : EPlayerWeapon;
  10255. var canAttackTarget : CGameplayEntity;
  10256. var target : CActor;
  10257.  
  10258. /*if( thePlayer.substateManager.GetStateCur() == 'Slide' )
  10259. {
  10260. return;
  10261. }*/
  10262. if ( !IsCombatMusicEnabled() )
  10263. {
  10264. SetCombatActionHeading( ProcessCombatActionHeading( action ) );
  10265. FindTarget();
  10266. UpdateDisplayTarget( true );
  10267. }
  10268.  
  10269. if ( displayTarget && IsDisplayTargetTargetable() )
  10270. canAttackTarget = displayTarget;
  10271. else if ( GetTarget() )
  10272. canAttackTarget = GetTarget();
  10273. else if( !target && IsCombatMusicEnabled() )
  10274. canAttackTarget = moveTarget;
  10275.  
  10276. target = (CActor)canAttackTarget;
  10277.  
  10278. if ( !AllowAttack( target, action ) )
  10279. return;
  10280.  
  10281. if( ( action != EBAT_ItemUse ) && ( action != EBAT_CastSign ) )
  10282. {
  10283. weaponType = weaponHolster.GetCurrentMeleeWeapon();
  10284. PrepareToAttack( target, action );
  10285.  
  10286. //Do not automatically attack when drawing sword
  10287. if ( weaponType != weaponHolster.GetCurrentMeleeWeapon() )
  10288. {
  10289. //Check if switching from PW_None to PW_Fists. If so, allow the attack
  10290. if ( !( weaponType == PW_None && weaponHolster.GetCurrentMeleeWeapon() == PW_Fists ) )
  10291. return;
  10292. }
  10293. }
  10294.  
  10295. //geralt's special attack heavy
  10296. if(action == EBAT_SpecialAttack_Heavy && !((W3ReplacerCiri)this) )
  10297. thePlayer.SetAttackActionName(SkillEnumToName(S_Sword_s02));
  10298.  
  10299. CriticalEffectAnimationInterrupted("SetupCombatAction " + action);
  10300. PushCombatActionOnBuffer( action, stage );
  10301.  
  10302. if( GetBIsCombatActionAllowed() )
  10303. {
  10304. ProcessCombatActionBuffer();
  10305. }
  10306. }
  10307.  
  10308. public function AllowAttack( target : CActor, action : EBufferActionType ) : bool
  10309. {
  10310. var newTarget : CActor;
  10311. var canAttackWhenNotInCombat : bool;
  10312. var messageDisplayed : bool;
  10313.  
  10314. var itemId : SItemUniqueId;
  10315. var isShootingCrossbow : bool;
  10316.  
  10317. var isInCorrectState : bool;
  10318.  
  10319. if ( target )
  10320. {
  10321. if ( target.IsTargetableByPlayer())
  10322. {
  10323. if ( !target.IsAttackableByPlayer() )
  10324. {
  10325. DisplayHudMessage(GetLocStringByKeyExt("panel_hud_message_cant_attack_this_target"));
  10326. return false;
  10327. }
  10328. }
  10329. }
  10330.  
  10331. if ( this.GetCurrentStateName() == 'Exploration' )
  10332. isInCorrectState = true;
  10333.  
  10334. if ( action == EBAT_ItemUse )
  10335. {
  10336. itemId = thePlayer.GetSelectedItemId();
  10337. if ( inv.IsIdValid(itemId) && inv.IsItemCrossbow(itemId) )
  10338. isShootingCrossbow = true;
  10339.  
  10340. if ( !isInCorrectState )
  10341. {
  10342. if ( this.GetCurrentStateName() == 'AimThrow' && !isShootingCrossbow )
  10343. {
  10344. isInCorrectState = true;
  10345. }
  10346. }
  10347. }
  10348.  
  10349. if ( isInCorrectState )
  10350. canAttackWhenNotInCombat = thePlayer.CanAttackWhenNotInCombat( action, false, newTarget, target );
  10351.  
  10352. if( !target )
  10353. {
  10354. if ( isInCorrectState )
  10355. {
  10356. SetCombatActionHeading( ProcessCombatActionHeading( action ) );
  10357. target = newTarget;
  10358. }
  10359. }
  10360.  
  10361. if ( isInCorrectState )
  10362. {
  10363. if ( !canAttackWhenNotInCombat )
  10364. {
  10365. if ( DisplayCannotAttackMessage( target ) )
  10366. messageDisplayed = true;
  10367. else if ( ( action == EBAT_LightAttack || action == EBAT_HeavyAttack )
  10368. && !RaiseAttackFriendlyEvent( target ) )
  10369. messageDisplayed = true;
  10370. else
  10371. {
  10372. if ( !CanRaiseCombatActionFriendlyEvent( isShootingCrossbow ) )
  10373. messageDisplayed = true;
  10374. }
  10375. }
  10376.  
  10377. if ( messageDisplayed )
  10378. {
  10379. theInput.ForceDeactivateAction('ThrowItem');
  10380. theInput.ForceDeactivateAction('ThrowItemHold');
  10381. this.SignalGameplayEvent( 'FriendlyAttackAction' );
  10382. return false;
  10383. }
  10384. }
  10385.  
  10386. return true;
  10387. }
  10388.  
  10389.  
  10390. //returns true if processed
  10391. public function ProcessCombatActionBuffer() : bool
  10392. {
  10393. var actionResult : bool;
  10394. var action : EBufferActionType = this.BufferCombatAction;
  10395. var stage : EButtonStage = this.BufferButtonStage;
  10396. var s : SNotWorkingOutFunctionParametersHackStruct1;
  10397. var allSteps : bool = this.BufferAllSteps;
  10398.  
  10399. if ( IsInCombatActionFriendly() )
  10400. {
  10401. RaiseEvent('CombatActionFriendlyEnd');
  10402. }
  10403.  
  10404. //Disable any npcs that are set to unpushable when Player performs another combat action
  10405. if ( ( action != EBAT_SpecialAttack_Heavy && action != EBAT_ItemUse )
  10406. || ( action == EBAT_SpecialAttack_Heavy && stage == BS_Pressed )
  10407. || ( action == EBAT_ItemUse && stage != BS_Released ) )
  10408. {
  10409. GetMovingAgentComponent().GetMovementAdjustor().CancelAll();
  10410. SetUnpushableTarget( NULL );
  10411. }
  10412.  
  10413. //if ( !( action == EBAT_Dodge && stage == BS_Pressed && IsInCombatAction() && GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Dodge ) )
  10414. if ( !( action == EBAT_Dodge || action == EBAT_Roll ) )
  10415. {
  10416. SetIsCurrentlyDodging(false);
  10417. }
  10418. //-- init
  10419. SetCombatActionHeading( ProcessCombatActionHeading( action ) );
  10420.  
  10421. //theGame.GetSyncAnimManager().OnRemoveFinisherCameraAnimation();
  10422.  
  10423. if ( action == EBAT_ItemUse && GetInventory().IsItemCrossbow( selectedItemId ) )
  10424. {
  10425. //stage == BS_Pressed &&
  10426. if ( rangedWeapon
  10427. && ( ( rangedWeapon.GetCurrentStateName() != 'State_WeaponShoot' && rangedWeapon.GetCurrentStateName() != 'State_WeaponAim' ) || GetIsShootingFriendly() ) )
  10428. {
  10429. SetSlideTarget( GetCombatActionTarget( action ) );
  10430. }
  10431. }
  10432. else if ( !( ( action == EBAT_SpecialAttack_Heavy && stage == BS_Released ) || GetCurrentStateName() == 'AimThrow' ) )
  10433. {
  10434. SetSlideTarget( GetCombatActionTarget( action ) );
  10435. }
  10436.  
  10437. if( !slideTarget )
  10438. LogChannel( 'Targeting', "NO SLIDE TARGET" );
  10439.  
  10440. //-- process
  10441. actionResult = true;
  10442.  
  10443. switch ( action )
  10444. {
  10445. case EBAT_EMPTY :
  10446. {
  10447. this.BufferAllSteps = false;
  10448. return true;
  10449. } break;
  10450.  
  10451. case EBAT_LightAttack :
  10452. {
  10453. if ( IsCiri() )
  10454. return false;
  10455.  
  10456. switch ( stage )
  10457. {
  10458. case BS_Pressed ://BS_Released :
  10459. {
  10460. // early out, stamina drain etc
  10461. //if( HasStaminaToUseAction(ESAT_LightAttack) )
  10462. //{
  10463.  
  10464. // replacing stamina lock with stamina drain - change in design
  10465. /*
  10466. s = LockStamina(ESAT_LightAttack);
  10467. if(s.retValue)
  10468. {
  10469. AddCombatActionStaminaLock(s.outValue);
  10470. }
  10471. */
  10472. DrainStamina(ESAT_LightAttack);
  10473. //target.SignalGameplayEventParamInt('Time2Dodge', (int)EDT_Attack );
  10474.  
  10475. thePlayer.BreakPheromoneEffect();
  10476. actionResult = OnPerformAttack(theGame.params.ATTACK_NAME_LIGHT);
  10477. }
  10478. else actionResult = false;
  10479. // W3EE - End
  10480.  
  10481. } break;
  10482.  
  10483. default :
  10484. {
  10485. actionResult = false;
  10486. }break;
  10487. }
  10488. }break;
  10489.  
  10490. case EBAT_HeavyAttack :
  10491. {
  10492. if ( IsCiri() )
  10493. return false;
  10494.  
  10495. switch ( stage )
  10496. {
  10497. case BS_Released :
  10498. {
  10499. // early out, stamina drain etc
  10500. //if( HasStaminaToUseAction(ESAT_HeavyAttack) )
  10501. //{
  10502. // replacing stamina lock with stamina drain - change in design
  10503. /*
  10504. s = LockStamina(ESAT_HeavyAttack);
  10505. if(s.retValue)
  10506. {
  10507. AddCombatActionStaminaLock(s.outValue);
  10508. }
  10509. */
  10510. DrainStamina(ESAT_HeavyAttack);
  10511.  
  10512. //target.SignalGameplayEventParamInt('Time2Dodge', (int)EDT_Attack );
  10513.  
  10514. thePlayer.BreakPheromoneEffect();
  10515. actionResult = this.OnPerformAttack(theGame.params.ATTACK_NAME_HEAVY);
  10516. //}
  10517. else actionResult = false;
  10518. // W3EE - End
  10519.  
  10520. } break;
  10521.  
  10522. case BS_Pressed :
  10523. {
  10524. if ( this.GetCurrentStateName() == 'CombatFists' )
  10525. {
  10526.  
  10527.  
  10528. // W3EE - Begin
  10529. if( HasStaminaToUseAction(ESAT_HeavyAttack) )
  10530. {
  10531. // replacing stamina lock with stamina drain - change in design
  10532.  
  10533. s = LockStamina(ESAT_HeavyAttack);
  10534. if(s.retValue)
  10535. {
  10536. AddCombatActionStaminaLock(s.outValue);
  10537. }
  10538. */
  10539. DrainStamina(ESAT_HeavyAttack);
  10540.  
  10541. //target.SignalGameplayEventParamInt('Time2Dodge', (int)EDT_Attack );
  10542.  
  10543. thePlayer.BreakPheromoneEffect();
  10544. actionResult = this.OnPerformAttack(theGame.params.ATTACK_NAME_HEAVY);
  10545. }
  10546. else actionResult = false;
  10547. // W3EE - End
  10548. }
  10549. } break;
  10550.  
  10551. default :
  10552. {
  10553. actionResult = false;
  10554.  
  10555. } break;
  10556. }
  10557. } break;
  10558.  
  10559. case EBAT_ItemUse : //this gets called only for bombs. No usable items use this!
  10560. {
  10561. switch ( stage )
  10562. {
  10563. case BS_Pressed :
  10564. {
  10565. if ( !( (W3PlayerWitcher)this ) ||
  10566. ( !IsInCombatActionFriendly() && !( !GetBIsCombatActionAllowed() && ( GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Attack || GetBehaviorVariable( 'combatActionType' ) == (int)CAT_CastSign ) ) ) )
  10567. //( !IsCastingSign() && !IsInCombatActionFriendly() && !( !GetBIsCombatActionAllowed() && GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Attack ) ) )
  10568. {
  10569. if ( inv.IsItemCrossbow( selectedItemId ) )
  10570. {
  10571. rangedWeapon = ( Crossbow )( inv.GetItemEntityUnsafe( selectedItemId ) );
  10572. rangedWeapon.OnRangedWeaponPress();
  10573. GetTarget().SignalGameplayEvent( 'Approach' );
  10574. GetTarget().SignalGameplayEvent( 'ShootingCrossbow' );
  10575. }
  10576. else if(inv.IsItemBomb(selectedItemId) && this.inv.SingletonItemGetAmmo(selectedItemId) > 0 )
  10577. {
  10578. if( ((W3PlayerWitcher)this).GetBombDelay( ((W3PlayerWitcher)this).GetItemSlot( selectedItemId ) ) <= 0.0f )
  10579. {
  10580. BombThrowStart();
  10581. GetTarget().SignalGameplayEvent( 'Approach' );
  10582. }
  10583. }
  10584. else
  10585. {
  10586. DrainStamina(ESAT_UsableItem);
  10587. UsableItemStart();
  10588. }
  10589. }
  10590.  
  10591. } if (!allSteps) break;
  10592.  
  10593. case BS_Released:
  10594. {
  10595. if ( !( (W3PlayerWitcher)this ) ||
  10596. ( !IsInCombatActionFriendly() && ( GetBIsCombatActionAllowed() || !( !GetBIsCombatActionAllowed() && ( GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Attack || GetBehaviorVariable( 'combatActionType' ) == (int)CAT_CastSign ) ) ) ) )
  10597. //( !IsCastingSign() && !IsInCombatActionFriendly() && !( !GetBIsCombatActionAllowed() && GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Attack ) ) )
  10598. {
  10599. if ( inv.IsItemCrossbow( selectedItemId ) )
  10600. {
  10601. /*if ( rangedWeapon.GetCurrentStateName() == 'State_WeaponWait' )
  10602. {
  10603. rangedWeapon = ( Crossbow )( inv.GetItemEntityUnsafe( selectedItemId ) );
  10604. rangedWeapon.OnRangedWeaponPress();
  10605. }*/
  10606. rangedWeapon.OnRangedWeaponRelease();
  10607. }
  10608. else if(inv.IsItemBomb(selectedItemId))
  10609. {
  10610. BombThrowRelease();
  10611. }
  10612. else
  10613. {
  10614. UsableItemRelease();
  10615. }
  10616. }
  10617. } break;
  10618.  
  10619. default :
  10620. {
  10621. actionResult = false;
  10622. break;
  10623. }
  10624. }
  10625. } break;
  10626.  
  10627. case EBAT_Dodge :
  10628. {
  10629. switch ( stage )
  10630. {
  10631. case BS_Released :
  10632. {
  10633. //W3EE - Begin
  10634. if( HasStaminaToUseAction(ESAT_Dodge) )
  10635. {
  10636. Combat().EvadeSpeedModule();
  10637. Combat().StaminaLoss(ESAT_Dodge);
  10638. Experience().AwardDodgingXP(this);
  10639. theGame.GetBehTreeReactionManager().CreateReactionEvent( this, 'PlayerEvade', 1.0f, 10.0f, -1.0f, -1 );
  10640. thePlayer.BreakPheromoneEffect();
  10641. actionResult = this.OnPerformEvade( PET_Dodge );
  10642. }
  10643. else actionResult = false;
  10644. //W3EE - End
  10645. } break;
  10646.  
  10647. /*case BS_Pressed :
  10648. {
  10649. actionResult = this.OnPerformEvade( PET_Roll );
  10650. } break;*/
  10651.  
  10652. default :
  10653. {
  10654. actionResult = false;
  10655. } break;
  10656. }
  10657. } break;
  10658.  
  10659. case EBAT_Roll :
  10660. {
  10661. if ( IsCiri() )
  10662. return false;
  10663.  
  10664. switch ( stage )
  10665. {
  10666. case BS_Released :
  10667. {
  10668. //W3EE - Begin
  10669. if( HasStaminaToUseAction(ESAT_Roll, , 1.6f) )
  10670. {
  10671. Combat().EvadeSpeedModule();
  10672. Combat().StaminaLoss(ESAT_Roll, 1.6f);
  10673. Experience().AwardDodgingXP(this);
  10674. theGame.GetBehTreeReactionManager().CreateReactionEvent( this, 'PlayerEvade', 1.0f, 10.0f, -1.0f, -1 );
  10675. thePlayer.BreakPheromoneEffect();
  10676. actionResult = this.OnPerformEvade( PET_Roll );
  10677. }
  10678. else actionResult = false;
  10679. //W3EE - End
  10680. } break;
  10681.  
  10682. case BS_Pressed :
  10683. {
  10684. if ( this.GetBehaviorVariable( 'combatActionType' ) == 2.f )
  10685. {
  10686. if ( GetCurrentStateName() == 'CombatSteel' || GetCurrentStateName() == 'CombatSilver' )
  10687. actionResult = this.OnPerformEvade( PET_Pirouette );
  10688. else
  10689. actionResult = this.OnPerformEvade( PET_Roll );
  10690. }
  10691. else
  10692. {
  10693. if ( GetCurrentStateName() == 'CombatSteel' || GetCurrentStateName() == 'CombatSilver' )
  10694. {
  10695. actionResult = this.OnPerformEvade( PET_Dodge );
  10696. actionResult = this.OnPerformEvade( PET_Pirouette );
  10697. }
  10698. else
  10699. {
  10700. actionResult = this.OnPerformEvade( PET_Dodge );
  10701. actionResult = this.OnPerformEvade( PET_Roll );
  10702. }
  10703. }
  10704.  
  10705.  
  10706. } break;
  10707.  
  10708. default :
  10709. {
  10710. actionResult = false;
  10711. } break;
  10712. }
  10713. } break;
  10714.  
  10715. case EBAT_Draw_Steel :
  10716. {
  10717. switch ( stage )
  10718. {
  10719. case BS_Pressed :
  10720. {
  10721. if( !IsActionAllowed(EIAB_DrawWeapon) )
  10722. {
  10723. thePlayer.DisplayActionDisallowedHudMessage(EIAB_DrawWeapon);
  10724. actionResult = false;
  10725. break;
  10726. }
  10727. if( GetWitcherPlayer().IsItemEquippedByCategoryName( 'steelsword' ) )
  10728. {
  10729. OnEquipMeleeWeapon( PW_Steel, false, true );
  10730. }
  10731.  
  10732. actionResult = false;
  10733.  
  10734. } break;
  10735.  
  10736. default :
  10737. {
  10738. actionResult = false;
  10739. } break;
  10740. }
  10741. } break;
  10742.  
  10743. case EBAT_Draw_Silver :
  10744. {
  10745. switch ( stage )
  10746. {
  10747. case BS_Pressed :
  10748. {
  10749. if( !IsActionAllowed(EIAB_DrawWeapon) )
  10750. {
  10751. thePlayer.DisplayActionDisallowedHudMessage(EIAB_DrawWeapon);
  10752. actionResult = false;
  10753. break;
  10754. }
  10755. if( GetWitcherPlayer().IsItemEquippedByCategoryName( 'silversword' ) )
  10756. {
  10757. OnEquipMeleeWeapon( PW_Silver, false, true );
  10758. }
  10759.  
  10760. actionResult = false;
  10761.  
  10762. } break;
  10763.  
  10764. default :
  10765. {
  10766. actionResult = false;
  10767. } break;
  10768. }
  10769. } break;
  10770.  
  10771. case EBAT_Sheathe_Sword :
  10772. {
  10773. switch ( stage )
  10774. {
  10775. case BS_Pressed :
  10776. {
  10777. if( GetCurrentMeleeWeaponType() == PW_Silver )
  10778. {
  10779. if( GetWitcherPlayer().IsItemEquippedByCategoryName( 'silversword' ) )
  10780. {
  10781. OnEquipMeleeWeapon( PW_Silver, false, true );
  10782. }
  10783. }
  10784. else if( GetCurrentMeleeWeaponType() == PW_Steel )
  10785. {
  10786. if( GetWitcherPlayer().IsItemEquippedByCategoryName( 'steelsword' ) )
  10787. {
  10788. OnEquipMeleeWeapon( PW_Steel, false, true );
  10789. }
  10790. }
  10791.  
  10792. actionResult = false;
  10793.  
  10794. } break;
  10795.  
  10796. default :
  10797. {
  10798. actionResult = false;
  10799. } break;
  10800. }
  10801. } break;
  10802.  
  10803. default:
  10804. return false; //not processed
  10805. }
  10806.  
  10807. //if here then buffer was processed
  10808. CleanCombatActionBuffer();
  10809.  
  10810. if (actionResult)
  10811. {
  10812. SetCombatAction( action ) ;
  10813.  
  10814. // W3EE - Begin
  10815. /*
  10816. if(GetWitcherPlayer().IsInFrenzy())
  10817. GetWitcherPlayer().SkillFrenzyFinish(0);
  10818. */
  10819. // W3EE - End
  10820. }
  10821.  
  10822. return true;
  10823. }
  10824.  
  10825.  
  10826. public function CleanCombatActionBuffer()
  10827. {
  10828. BufferCombatAction = EBAT_EMPTY;
  10829. BufferAllSteps = false;
  10830. }
  10831.  
  10832. public function CancelHoldAttacks()
  10833. {
  10834. RemoveTimer( 'IsSpecialLightAttackInputHeld' );
  10835. RemoveTimer( 'IsSpecialHeavyAttackInputHeld' );
  10836. RemoveTimer( 'SpecialAttackLightSustainCost' );
  10837. RemoveTimer( 'SpecialAttackHeavySustainCost' );
  10838. RemoveTimer( 'UpdateSpecialAttackLightHeading' );
  10839. UnblockAction( EIAB_Crossbow, 'SpecialAttack' );
  10840.  
  10841. ResumeStaminaRegen('WhirlSkill');
  10842. ResumeStaminaRegen('RendSkill');
  10843.  
  10844. if ( GetBehaviorVariable( 'combatActionType' ) == (int)CAT_SpecialAttack && GetBehaviorVariable( 'isPerformingSpecialAttack' ) == 1.f )
  10845. {
  10846. if( GetBehaviorVariable( 'playerAttackType' ) == (int)PAT_Light )
  10847. {
  10848. SetAttackActionName(SkillEnumToName(S_Sword_s01));
  10849. PushCombatActionOnBuffer( EBAT_SpecialAttack_Light, BS_Released );
  10850. ProcessCombatActionBuffer();
  10851. //SetupCombatAction( EBAT_SpecialAttack_Light, BS_Released );
  10852. ((W3PlayerWitcherStateCombatFists) GetState('Combat')).ResetTimeToEndCombat();
  10853.  
  10854. }
  10855. else if( GetBehaviorVariable( 'playerAttackType' ) == (int)PAT_Heavy )
  10856. {
  10857. SetAttackActionName(SkillEnumToName(S_Sword_s02));
  10858. PushCombatActionOnBuffer( EBAT_SpecialAttack_Heavy, BS_Released );
  10859. ProcessCombatActionBuffer();
  10860. //SetupCombatAction( EBAT_SpecialAttack_Heavy, BS_Released );
  10861. }
  10862. }
  10863. }
  10864.  
  10865. public function RaiseAttackFriendlyEvent( actor : CActor ) : bool
  10866. {
  10867. var playerToTargetHeading : float;
  10868.  
  10869. if ( actor && RaiseCombatActionFriendlyEvent() )
  10870. {
  10871. SetBehaviorVariable( 'tauntTypeForOverlay', 0.f );
  10872. SetBehaviorVariable( 'combatActionTypeForOverlay', (int)CAT_Attack );
  10873.  
  10874. if ( actor )
  10875. actor.SignalGameplayEvent('PersonalTauntAction');
  10876. theGame.GetBehTreeReactionManager().CreateReactionEventIfPossible( this, 'TauntAction', -1.0, 4.5f, -1, 9999, true ); //reactionSystemSearch
  10877.  
  10878. OnCombatActionStart();
  10879.  
  10880. playerToTargetHeading = VecHeading( actor.GetWorldPosition() - GetWorldPosition() );
  10881.  
  10882. SetCustomRotation( 'Attack', playerToTargetHeading, 0.0f, 0.3f, false );
  10883.  
  10884. return true;
  10885. }
  10886.  
  10887. return false;
  10888. }
  10889.  
  10890. public function SendAttackReactionEvent()
  10891. {
  10892. var reactionName : name;
  10893.  
  10894. /*switch ( action )
  10895. {
  10896. case EBAT_LightAttack :
  10897. reactionName = 'AttackAction';
  10898. break;
  10899. case EBAT_HeavyAttack :
  10900. reactionName = 'AttackAction';
  10901. break;
  10902. case EBAT_SpecialAttack_Light :
  10903. reactionName = 'AttackAction';
  10904. break;
  10905. case EBAT_SpecialAttack_Heavy :
  10906. reactionName = 'AttackAction';
  10907. break;
  10908. case EBAT_Ciri_SpecialAttack :
  10909. reactionName = 'AttackAction';
  10910. break;
  10911. default:
  10912. return;
  10913. }*/
  10914.  
  10915. reactionName = 'AttackAction';
  10916.  
  10917. if ( IsNameValid(reactionName) )
  10918. {
  10919. theGame.GetBehTreeReactionManager().CreateReactionEventIfPossible( this, reactionName, -1.0, 8.0f, -1, 5, true ); //reactionSystemSearch
  10920. }
  10921.  
  10922. // event for horse - trigger running away
  10923. theGame.GetBehTreeReactionManager().CreateReactionEventIfPossible( this, 'outOfMyWay', -1.0, 2.0f, -1, 5, true ); //reactionSystemSearch
  10924. }
  10925.  
  10926. var forceCanAttackWhenNotInCombat : int; // 0 = NoForce, 1 = ForceWhenNoDisplayTarget 2 = ForceEvenWithDisplayTarget
  10927. public function SetForceCanAttackWhenNotInCombat( forceMode : int )
  10928. {
  10929. forceCanAttackWhenNotInCombat = forceMode;
  10930. }
  10931.  
  10932. public function CanAttackWhenNotInCombat( actionType : EBufferActionType, altCast : bool, out newTarget : CActor, optional target : CGameplayEntity ) : bool
  10933. {
  10934. var localTargets : array<CActor>;
  10935. var i, size : int;
  10936. var inputHeading : float;
  10937. var clearanceMin, clearanceMax : float;
  10938. var attackLength : float;
  10939. var attackAngle : float;
  10940. var npc : CNewNPC;
  10941. var canAttackTarget : CGameplayEntity;
  10942. var canAttackTargetActor : CActor;
  10943.  
  10944. if ( target )
  10945. canAttackTarget = target;
  10946. else if ( displayTarget && IsDisplayTargetTargetable() )
  10947. canAttackTarget = displayTarget;
  10948. else
  10949. canAttackTarget = slideTarget;
  10950.  
  10951. canAttackTargetActor = (CActor)canAttackTarget;
  10952.  
  10953. if ( forceCanAttackWhenNotInCombat == 2 )
  10954. return true;
  10955. else if ( forceCanAttackWhenNotInCombat == 1 && ( !canAttackTarget || !canAttackTargetActor.IsHuman() ) )
  10956. return true;
  10957.  
  10958. if ( actionType == EBAT_CastSign )
  10959. {
  10960. if ( thePlayer.GetEquippedSign() != ST_Quen && thePlayer.GetEquippedSign() != ST_Axii )
  10961. {
  10962. if ( CanUseSkill( S_Magic_s20 ) )
  10963. {
  10964. if ( thePlayer.GetEquippedSign() == ST_Aard )
  10965. attackLength = 6.f;
  10966. else if ( thePlayer.GetEquippedSign() == ST_Igni )
  10967. attackLength = 4.f;
  10968. else
  10969. attackLength = 6.f;
  10970. }
  10971. else
  10972. {
  10973. if ( thePlayer.GetEquippedSign() == ST_Aard )
  10974. attackLength = 9.f;
  10975. else if ( thePlayer.GetEquippedSign() == ST_Igni )
  10976. attackLength = 6.f;
  10977. else
  10978. attackLength = 6.f;
  10979. }
  10980.  
  10981. if ( altCast )
  10982. attackAngle = 180.f;
  10983. else
  10984. // sign cone angle / 2 with a bonus for safetey
  10985. attackAngle = 90.f;
  10986.  
  10987. if ( !lastAxisInputIsMovement )
  10988. inputHeading = VecHeading( theCamera.GetCameraDirection() );
  10989. else if ( lAxisReleasedAfterCounter )
  10990. inputHeading = GetHeading();
  10991. else
  10992. inputHeading = GetCombatActionHeading();
  10993.  
  10994. clearanceMin = 1.f;
  10995. clearanceMax = attackLength + 1.f;
  10996. }
  10997. else if ( thePlayer.GetEquippedSign() == ST_Axii )
  10998. {
  10999. npc = (CNewNPC)canAttackTarget;
  11000. if ( npc && npc.GetNPCType() == ENGT_Quest && !npc.HasTag(theGame.params.TAG_AXIIABLE_LOWER_CASE) && !npc.HasTag(theGame.params.TAG_AXIIABLE))
  11001. return false;
  11002. else if ( npc && npc.IsUsingHorse() )
  11003. return false;
  11004. else
  11005. return true;
  11006. }
  11007. else
  11008. return true;
  11009. }
  11010. else if ( actionType == EBAT_ItemUse )
  11011. {
  11012. attackLength = theGame.params.MAX_THROW_RANGE;
  11013. attackAngle = 90.f;
  11014.  
  11015. if ( thePlayer.lastAxisInputIsMovement )
  11016. inputHeading = GetCombatActionHeading();
  11017. else
  11018. inputHeading = VecHeading( theCamera.GetCameraDirection() );
  11019.  
  11020. clearanceMin = 0.8f;
  11021. clearanceMax = attackLength + 3.f;
  11022. }
  11023. else
  11024. {
  11025. if ( actionType == EBAT_SpecialAttack_Light || actionType == EBAT_SpecialAttack_Heavy )
  11026. {
  11027. attackLength = 1.9f;
  11028. attackAngle = 90.f;
  11029. }
  11030. else
  11031. {
  11032. if( thePlayer.GetCurrentMeleeWeaponType() == PW_Fists || thePlayer.GetCurrentMeleeWeaponType() == PW_None )
  11033. attackLength = 1.2f;
  11034. else
  11035. attackLength = 1.9f;
  11036.  
  11037. attackAngle = 90.f;
  11038. }
  11039.  
  11040. if ( lastAxisInputIsMovement )
  11041. inputHeading = GetCombatActionHeading();
  11042. else
  11043. inputHeading = VecHeading( theCamera.GetCameraDirection() );
  11044.  
  11045. clearanceMin = attackLength / 2.f;
  11046. clearanceMax = attackLength + 3.f;
  11047. }
  11048.  
  11049. //Use slideTarget first if it's NULL, then we try other npcs in the area
  11050.  
  11051. if ( canAttackTarget )
  11052. {
  11053. if ( ( canAttackTargetActor && canAttackTargetActor.IsHuman() ) || canAttackTargetActor.HasTag( 'softLock_Friendly' ) )
  11054. {
  11055. if ( ShouldPerformFriendlyAction( canAttackTargetActor, inputHeading, attackAngle, clearanceMin, clearanceMax ) )
  11056. {
  11057. SetSlideTarget( canAttackTargetActor );
  11058. newTarget = canAttackTargetActor;
  11059. return false;
  11060. }
  11061. }
  11062.  
  11063. //return true;
  11064. }
  11065.  
  11066. // W3EE - End
  11067.  
  11068. return true;
  11069.  
  11070. thePlayer.GetVisibleEnemies( localTargets );
  11071. size = localTargets.Size();
  11072.  
  11073. if ( size > 0 )
  11074. {
  11075. for ( i = size-1; i>=0; i-=1 )
  11076. {
  11077. /*
  11078. Andrzej: Geralt's friendly combat action - taunting actors with a sword or playing with Signs is set to work only for humans.
  11079. We don't want it to work against all non-humans, so I've added an exception that works similar to targeting non actor objects.
  11080. If you want Geralt to play friendly combat action when targeting monsters, add tag softLock_Friendly to monster's entity.
  11081. */
  11082. if ( !localTargets[i].IsHuman() && !localTargets[i].HasTag( 'softLock_Friendly' ) )
  11083. localTargets.Erase(i);
  11084. }
  11085. }
  11086.  
  11087. size = localTargets.Size();
  11088. if ( size > 0 )
  11089. {
  11090. for ( i = 0; i < localTargets.Size(); i += 1 )
  11091. {
  11092. if ( ShouldPerformFriendlyAction( localTargets[i], inputHeading, attackAngle, clearanceMin, clearanceMax ) )
  11093. {
  11094. SetSlideTarget( localTargets[i] );
  11095. newTarget = localTargets[i];
  11096. return false;
  11097. }
  11098. }
  11099. }
  11100.  
  11101. newTarget = NULL;
  11102.  
  11103. return true;
  11104. }
  11105.  
  11106. private function ShouldPerformFriendlyAction( actor : CActor, inputHeading, attackAngle, clearanceMin, clearanceMax : float ) : bool
  11107. {
  11108. var npc : CNewNPC;
  11109. var argh : float;
  11110. var playerToTargetDist : float;
  11111.  
  11112. npc = (CNewNPC)actor;
  11113.  
  11114. if ( npc &&
  11115. ( GetAttitudeBetween(thePlayer, npc) == AIA_Hostile || ( GetAttitudeBetween(thePlayer, npc) == AIA_Neutral && npc.GetNPCType() != ENGT_Guard ) ) )
  11116. {
  11117. }
  11118. else
  11119. {
  11120. playerToTargetDist = VecDistance( this.GetWorldPosition(), actor.PredictWorldPosition( 0.5f ) ); //actor.GetNearestPointInPersonalSpace( this.GetWorldPosition() ) );
  11121.  
  11122. argh = AbsF( AngleDistance( inputHeading, VecHeading( actor.GetWorldPosition() - thePlayer.GetWorldPosition() ) ) );
  11123.  
  11124. if ( AbsF( AngleDistance( inputHeading, VecHeading( actor.GetWorldPosition() - thePlayer.GetWorldPosition() ) ) ) < attackAngle )
  11125. {
  11126. if ( playerToTargetDist < clearanceMax )
  11127. {
  11128. return true;
  11129. }
  11130. }
  11131. else
  11132. {
  11133. if ( playerToTargetDist < clearanceMin )
  11134. {
  11135. return true;
  11136. }
  11137. }
  11138. }
  11139.  
  11140. return false;
  11141. }
  11142.  
  11143. ///////////////////////////////////////////////////////////////////////////
  11144. // HUD //#B
  11145. ///////////////////////////////////////////////////////////////////////////
  11146.  
  11147. public function GetHudMessagesSize() : int
  11148. {
  11149. return HudMessages.Size();
  11150. }
  11151.  
  11152. public function GetHudPendingMessage() : string
  11153. {
  11154. return HudMessages[0];
  11155. }
  11156.  
  11157. public function DisplayHudMessage( value : string ) : void
  11158. {
  11159. if (value == "")
  11160. {
  11161. return;
  11162. }
  11163.  
  11164. if( GetHudMessagesSize() > 0 )
  11165. {
  11166. if( HudMessages[HudMessages.Size()-1] == value )
  11167. {
  11168. return;
  11169. }
  11170. }
  11171. HudMessages.PushBack(value);
  11172. }
  11173.  
  11174. //hacks for review requests
  11175. private final function DisallowedActionDontShowHack(action : EInputActionBlock, isTimeLock : bool) : bool
  11176. {
  11177. var locks : array< SInputActionLock >;
  11178. var i : int;
  11179.  
  11180. //no info if we're trying to attack while staggered
  11181. if( GetWitcherPlayer() && GetWitcherPlayer().IsMeditating() )
  11182. return true;
  11183. // W3EE - End
  11184.  
  11185. if((action == EIAB_Fists || action == EIAB_SwordAttack || action == EIAB_Signs || action == EIAB_LightAttacks || action == EIAB_HeavyAttacks || action == EIAB_SpecialAttackLight || action == EIAB_SpecialAttackHeavy) && (HasBuff(EET_Stagger) || HasBuff(EET_LongStagger)) )
  11186. {
  11187. return true;
  11188. }
  11189.  
  11190. //display message if trying to throw bombs while hypnotized by bies or blinded by water hag
  11191. if( action == EIAB_ThrowBomb && ( HasBuff( EET_Hypnotized ) || HasBuff( EET_Confusion ) ) )
  11192. {
  11193. return false;
  11194. }
  11195.  
  11196. //show if locked temporarily
  11197. if(isTimeLock)
  11198. return false;
  11199.  
  11200. //always show meditation message
  11201. if(action == EIAB_OpenMeditation)
  11202. return false;
  11203.  
  11204. //if there's at least one lock from quest or from location fine
  11205. locks = GetActionLocks(action);
  11206. for(i=0; i<locks.Size(); i+=1)
  11207. {
  11208. if(locks[i].isFromQuest || locks[i].isFromPlace)
  11209. return false;
  11210. }
  11211.  
  11212. if ( this.IsCurrentlyUsingItemL() )
  11213. {
  11214. if ( action == EIAB_HeavyAttacks || action == EIAB_Parry )
  11215. return false;
  11216. }
  11217.  
  11218. //otherwise we don't display locks
  11219. return true;
  11220. }
  11221.  
  11222. public final function DisplayActionDisallowedHudMessage(action : EInputActionBlock, optional isCombatLock : bool, optional isPlaceLock : bool, optional isTimeLock : bool, optional isDangerous : bool)
  11223. {
  11224. var lockType : name;
  11225.  
  11226. if(action != EIAB_Undefined && DisallowedActionDontShowHack(action, isTimeLock))
  11227. return;
  11228.  
  11229. //combat lock is strongest - overrides all
  11230. if(IsInCombat() && !IsActionCombat(action))
  11231. isCombatLock = true;
  11232.  
  11233. //if no specific lock set, check based on action
  11234. if(!isCombatLock && !isPlaceLock && !isTimeLock && action != EIAB_Undefined)
  11235. {
  11236. lockType = inputHandler.GetActionBlockedHudLockType(action);
  11237.  
  11238. if(lockType == 'combat')
  11239. isCombatLock = true;
  11240. else if(lockType == 'place')
  11241. isPlaceLock = true;
  11242. else if(lockType == 'time')
  11243. isTimeLock = true;
  11244. }
  11245.  
  11246. if(isDangerous)
  11247. {
  11248. DisplayHudMessage(GetLocStringByKeyExt( "message_meditation_too_dangerous" ));
  11249. }
  11250. else if(isCombatLock)
  11251. {
  11252. DisplayHudMessage(GetLocStringByKeyExt( "panel_hud_message_actionnotallowed_combat" ));
  11253. }
  11254. else if(isPlaceLock)
  11255. {
  11256. DisplayHudMessage(GetLocStringByKeyExt( "menu_cannot_perform_action_here" ));
  11257. }
  11258. else if(isTimeLock)
  11259. {
  11260. DisplayHudMessage(GetLocStringByKeyExt( "menu_cannot_perform_action_now" ));
  11261. }
  11262. }
  11263.  
  11264. //removes first or all instances of given message
  11265. public function RemoveHudMessageByString(msg : string, optional allQueuedInstances : bool)
  11266. {
  11267. var i, j : int;
  11268.  
  11269. for(i=0; i<HudMessages.Size(); i+=1)
  11270. {
  11271. if(HudMessages[i] == msg)
  11272. {
  11273. HudMessages.EraseFast(i);
  11274.  
  11275. if(!allQueuedInstances)
  11276. return;
  11277.  
  11278. break;
  11279. }
  11280. }
  11281.  
  11282. //if here then we want all remaining instances as well
  11283. for(j=HudMessages.Size()-1; j >= i; j-=1)
  11284. {
  11285. if(HudMessages[i] == msg)
  11286. {
  11287. HudMessages.EraseFast(i);
  11288. }
  11289. }
  11290. }
  11291.  
  11292. public function RemoveHudMessageByIndex(idx : int)
  11293. {
  11294. if(idx >= 0 && idx < HudMessages.Size())
  11295. HudMessages.Erase(idx);
  11296. }
  11297.  
  11298. function SetSettlementBlockCanter( valueAdd : int ) // #B
  11299. {
  11300. m_SettlementBlockCanter += valueAdd;
  11301. }
  11302.  
  11303. var countDownToStart : int;
  11304. default countDownToStart = 0;
  11305.  
  11306. function DisplayRaceStart( countDownSecondsNumber : int ) // #B
  11307. {
  11308. var i : int;
  11309. countDownToStart = countDownSecondsNumber;
  11310. for( i = countDownSecondsNumber; i > 0; i -= 1 )
  11311. {
  11312. DisplayHudMessage(IntToString(i));
  11313. }
  11314. DisplayHudMessage(GetLocStringByKeyExt("panel_hud_message_race_start"));
  11315. AddTimer('RaceCountdown',1,true);
  11316. }
  11317.  
  11318. timer function RaceCountdown(dt : float, id : int) // #B
  11319. {
  11320. var hud : CR4ScriptedHud;
  11321. var messageModule : CR4HudModuleMessage;
  11322.  
  11323. countDownToStart -= 1;
  11324. hud = (CR4ScriptedHud)theGame.GetHud();
  11325.  
  11326. if( hud )
  11327. {
  11328. messageModule = (CR4HudModuleMessage)hud.GetHudModule("MessageModule");
  11329. if( messageModule )
  11330. {
  11331. messageModule.OnMessageHidden(); // to force show next messeage
  11332. }
  11333. }
  11334.  
  11335. if( countDownToStart <= 0 )
  11336. {
  11337. RemoveTimer('RaceCountdown');
  11338. }
  11339. }
  11340.  
  11341. public function GetCountDownToStart() : int // #B
  11342. {
  11343. return countDownToStart;
  11344. }
  11345.  
  11346. public function HAXE3GetContainer() : W3Container //#B temp for E3
  11347. {
  11348. return HAXE3Container;
  11349. }
  11350.  
  11351. public function HAXE3SetContainer( container : W3Container) : void //#B temp for E3
  11352. {
  11353. HAXE3Container = container;
  11354. }
  11355.  
  11356. public function HAXE3GetAutoLoot() : bool //#B temp for E3
  11357. {
  11358. return HAXE3bAutoLoot;
  11359. }
  11360.  
  11361. public function HAXE3SetAutoLoot( value : bool ) : void //#B temp for E3
  11362. {
  11363. HAXE3bAutoLoot = value;
  11364. }
  11365.  
  11366. public function GetShowHud() : bool
  11367. {
  11368. return bShowHud;
  11369. }
  11370.  
  11371. public function SetShowHud( value : bool ) : void
  11372. {
  11373. bShowHud = value;
  11374. }
  11375.  
  11376. public function DisplayItemRewardNotification( itemName : name, optional quantity : int ) : void
  11377. {
  11378. var hud : CR4ScriptedHud;
  11379. hud = (CR4ScriptedHud)theGame.GetHud();
  11380. hud.OnItemRecivedDuringScene(itemName, quantity); // #B because our default currency are Crowns !!!
  11381. }
  11382.  
  11383. function IsNewQuest( questGuid : CGUID ) : bool // #B
  11384. {
  11385. var i : int;
  11386. for(i = 0; i < displayedQuestsGUID.Size(); i += 1 )
  11387. {
  11388. if( displayedQuestsGUID[i] == questGuid )
  11389. {
  11390. return false;
  11391. }
  11392. }
  11393. displayedQuestsGUID.PushBack(questGuid);
  11394. return true;
  11395. }
  11396.  
  11397. function GetRewardMultiplierData( rewardName : name ) : SRewardMultiplier
  11398. {
  11399. var defaultReward : SRewardMultiplier;
  11400. var i : int;
  11401.  
  11402. for(i = 0; i < rewardsMultiplier.Size(); i += 1 )
  11403. {
  11404. if( rewardsMultiplier[i].rewardName == rewardName )
  11405. {
  11406. return rewardsMultiplier[i];
  11407. }
  11408. }
  11409.  
  11410. defaultReward.rewardName = rewardName;
  11411. defaultReward.rewardMultiplier = 1.0;
  11412. defaultReward.isItemMultiplier = false;
  11413.  
  11414. return defaultReward;
  11415. }
  11416.  
  11417. function GetRewardMultiplier( rewardName : name ) : float // #B
  11418. {
  11419. var i : int;
  11420. for(i = 0; i < rewardsMultiplier.Size(); i += 1 )
  11421. {
  11422. if( rewardsMultiplier[i].rewardName == rewardName )
  11423. {
  11424. return rewardsMultiplier[i].rewardMultiplier;
  11425. }
  11426. }
  11427. return 1.0;
  11428. }
  11429.  
  11430. function GetRewardMultiplierExists( rewardName : name ) : bool // #B
  11431. {
  11432. var i : int;
  11433. for(i = 0; i < rewardsMultiplier.Size(); i += 1 )
  11434. {
  11435. if( rewardsMultiplier[i].rewardName == rewardName )
  11436. {
  11437. return true;
  11438. }
  11439. }
  11440. return false;
  11441. }
  11442.  
  11443. function SetRewardMultiplier( rewardName : name, value : float, optional isItemMultiplier : bool ) : void // #B
  11444. {
  11445. var i : int;
  11446. var rewardMultiplier : SRewardMultiplier;
  11447.  
  11448. for(i = 0; i < rewardsMultiplier.Size(); i += 1 )
  11449. {
  11450. if( rewardsMultiplier[i].rewardName == rewardName )
  11451. {
  11452. rewardsMultiplier[i].rewardMultiplier = value;
  11453. rewardsMultiplier[i].isItemMultiplier = isItemMultiplier;
  11454. return;
  11455. }
  11456. }
  11457.  
  11458. rewardMultiplier.rewardName = rewardName;
  11459. rewardMultiplier.rewardMultiplier = value;
  11460. rewardMultiplier.isItemMultiplier = isItemMultiplier;
  11461.  
  11462. rewardsMultiplier.PushBack(rewardMultiplier);
  11463. }
  11464.  
  11465. function RemoveRewardMultiplier( rewardName : name ) : void // #B
  11466. {
  11467. var i : int;
  11468. for(i = 0; i < rewardsMultiplier.Size(); i += 1 )
  11469. {
  11470. if( rewardsMultiplier[i].rewardName == rewardName )
  11471. {
  11472. rewardsMultiplier.Erase(i);
  11473. return;
  11474. }
  11475. }
  11476. }
  11477.  
  11478. ////////////////////////////////////////////////////////////////////////////////
  11479. //
  11480. // @Items
  11481. //
  11482. ////////////////////////////////////////////////////////////////////////////////
  11483.  
  11484. public final function TissueExtractorDischarge() : bool
  11485. {
  11486. var ids : array<SItemUniqueId>;
  11487. var chargesLeft, uses, curr, max, red, blue, green : int;
  11488. var i : int;
  11489. var text : string;
  11490.  
  11491. ids = thePlayer.inv.GetItemsByName( 'q705_tissue_extractor' );
  11492. if( ids.Size() == 0 )
  11493. {
  11494. return false;
  11495. }
  11496.  
  11497. curr = GetTissueExtractorChargesCurr();
  11498. max = GetTissueExtractorChargesMax();
  11499.  
  11500. if( curr >= max )
  11501. {
  11502. //calculate how many times the effect will work
  11503. uses = FloorF( ( ( float ) curr ) / ( ( float ) max ) );
  11504. chargesLeft = Max( 0, curr - uses * max );
  11505.  
  11506. //update charges
  11507. inv.SetItemModifierInt( ids[0], 'charges', chargesLeft );
  11508.  
  11509. //add items
  11510. blue = 0;
  11511. green = 0;
  11512. red = 0;
  11513. for( i=0; i<uses; i+=1 )
  11514. {
  11515. switch( RandRange( 3 ) )
  11516. {
  11517. case 0:
  11518. blue += 1;
  11519. break;
  11520. case 1:
  11521. green += 1;
  11522. break;
  11523. case 2:
  11524. red += 1;
  11525. }
  11526. }
  11527.  
  11528. text = GetLocStringByKeyExt( "message_q705_extractor_extracted" );
  11529.  
  11530. if( blue > 0 )
  11531. {
  11532. inv.AddAnItem( 'Greater mutagen blue', blue, false, true );
  11533. text += "<br/>" + blue + "x " + GetLocStringByKey( inv.GetItemLocalizedNameByName( 'Greater mutagen blue' ) );
  11534. }
  11535. if( green > 0 )
  11536. {
  11537. inv.AddAnItem( 'Greater mutagen green', green, false, true );
  11538. text += "<br/>" + green + "x " + GetLocStringByKey( inv.GetItemLocalizedNameByName( 'Greater mutagen green' ) );
  11539. }
  11540. if( red > 0 )
  11541. {
  11542. inv.AddAnItem( 'Greater mutagen red', red, false, true );
  11543. text += "<br/>" + red + "x " + GetLocStringByKey( inv.GetItemLocalizedNameByName( 'Greater mutagen red' ) );
  11544. }
  11545.  
  11546. //popup to inform player
  11547. theGame.GetGuiManager().ShowNotification( text );
  11548.  
  11549. //clear flag for UI notification when item becomes charged
  11550. inv.SetItemModifierInt( ids[0], 'ui_notified', 0 );
  11551.  
  11552. return true;
  11553. }
  11554. else
  11555. {
  11556. //popup to inform player
  11557. theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt( "message_q705_extractor_too_few_charges" ) );
  11558. }
  11559.  
  11560. return false;
  11561. }
  11562.  
  11563. public final function TissueExtractorIncCharge()
  11564. {
  11565. var ids : array<SItemUniqueId>;
  11566. var uiData : SInventoryItemUIData;
  11567. var curr : int;
  11568.  
  11569. ids = thePlayer.inv.GetItemsByName( 'q705_tissue_extractor' );
  11570. if( ids.Size() == 0 )
  11571. {
  11572. return;
  11573. }
  11574.  
  11575. curr = GetTissueExtractorChargesCurr() + 1;
  11576. inv.SetItemModifierInt( ids[0], 'charges', curr );
  11577.  
  11578. //mark as new in inventory
  11579. if( curr >= GetTissueExtractorChargesMax() )
  11580. {
  11581. uiData = inv.GetInventoryItemUIData( ids[0] );
  11582. uiData.isNew = true;
  11583. inv.SetInventoryItemUIData( ids[0], uiData );
  11584.  
  11585. //show popup ingame
  11586. if( inv.GetItemModifierInt( ids[0], 'ui_notified', 0 ) == 0 )
  11587. {
  11588. inv.SetItemModifierInt( ids[0], 'ui_notified', 1 );
  11589. theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt( "message_q705_extractor_charged" ), , true );
  11590. }
  11591. }
  11592. }
  11593.  
  11594. public final function GetTissueExtractorChargesCurr() : int
  11595. {
  11596. var ids : array<SItemUniqueId>;
  11597.  
  11598. ids = thePlayer.inv.GetItemsByName( 'q705_tissue_extractor' );
  11599. if( ids.Size() == 0 )
  11600. {
  11601. return 0;
  11602. }
  11603.  
  11604. return inv.GetItemModifierInt( ids[0], 'charges', 0 );
  11605. }
  11606.  
  11607. public final function GetTissueExtractorChargesMax() : int
  11608. {
  11609. var ids : array<SItemUniqueId>;
  11610. var val : SAbilityAttributeValue;
  11611.  
  11612. ids = thePlayer.inv.GetItemsByName( 'q705_tissue_extractor' );
  11613. if( ids.Size() == 0 )
  11614. {
  11615. return 0;
  11616. }
  11617.  
  11618. val = inv.GetItemAttributeValue( ids[0], 'maxCharges' );
  11619.  
  11620. return FloorF( val.valueBase );
  11621. }
  11622.  
  11623. public function GetEquippedSword(steel : bool) : SItemUniqueId;
  11624.  
  11625. public final function HasRequiredLevelToEquipItem(item : SItemUniqueId) : bool
  11626. {
  11627. //W3EE - Begin
  11628.  
  11629. return Equipment().LevelRequirements(item, inv);
  11630.  
  11631. //W3EE - End
  11632. }
  11633.  
  11634. public function SkillReduceBombAmmoBonus()
  11635. {
  11636. // W3EE - Begin
  11637. /*
  11638. var i, ammo, maxAmmo : int;
  11639. var items : array<SItemUniqueId>;
  11640.  
  11641. items = inv.GetSingletonItems();
  11642.  
  11643. for(i=0; i<items.Size(); i+=1)
  11644. {
  11645. ammo = inv.GetItemModifierInt(items[i], 'ammo_current');
  11646.  
  11647. //if doesn't have infinite ammo
  11648. if(ammo > 0)
  11649. {
  11650. maxAmmo = inv.SingletonItemGetMaxAmmo(items[i]);
  11651.  
  11652. //if current ammo > max ammo, set current ammo to max ammo
  11653. if(ammo > maxAmmo)
  11654. {
  11655. inv.SetItemModifierInt(items[i], 'ammo_current', maxAmmo);
  11656. }
  11657. }
  11658. }
  11659. theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_OnAmmoChanged );
  11660. */
  11661. // W3EE - End
  11662. }
  11663.  
  11664. public function ConsumeItem( itemId : SItemUniqueId ) : bool
  11665. {
  11666. var params : SCustomEffectParams;
  11667. var buffs : array<SEffectInfo>;
  11668. var i : int;
  11669. var category : name;
  11670. var potionToxicity : float;
  11671.  
  11672. if(!inv.IsIdValid(itemId))
  11673. return false;
  11674.  
  11675. //apply buff
  11676. category = inv.GetItemCategory(itemId);
  11677. if(category == 'edibles' || inv.ItemHasTag(itemId, 'Drinks') || ( category == 'alchemy_ingredient' && inv.ItemHasTag(itemId, 'Alcohol')) )
  11678. {
  11679. // W3EE - Begin
  11680. if( inv.ItemHasTag(itemId, 'Drinks') )
  11681. inv.AddAnItem('Empty bottle', 1);
  11682. // W3EE - End
  11683.  
  11684. if(IsFistFightMinigameEnabled())
  11685. {
  11686. DisplayActionDisallowedHudMessage(EIAB_Undefined, false, false, true);
  11687. return false;
  11688. }
  11689.  
  11690. //edible buff
  11691. inv.GetItemBuffs(itemId, buffs);
  11692.  
  11693. for(i=0; i<buffs.Size(); i+=1)
  11694. {
  11695. params.effectType = buffs[i].effectType;
  11696. params.creator = this;
  11697. params.sourceName = "edible";
  11698. params.customAbilityName = buffs[i].effectAbilityName;
  11699. AddEffectCustom(params);
  11700. }
  11701.  
  11702. //custom hack
  11703. if ( inv.ItemHasTag(itemId, 'Alcohol') )
  11704. {
  11705. potionToxicity = CalculateAttributeValue(inv.GetItemAttributeValue(itemId, 'toxicity'));
  11706. abilityManager.GainStat(BCS_Toxicity, potionToxicity );
  11707. AddEffectDefault(EET_Drunkenness, NULL, inv.GetItemName(itemId));
  11708. }
  11709. PlayItemConsumeSound( itemId );
  11710. }
  11711.  
  11712. if(inv.IsItemFood(itemId))
  11713. FactsAdd("consumed_food_cnt");
  11714.  
  11715. //remove item
  11716. if(!inv.ItemHasTag(itemId, theGame.params.TAG_INFINITE_USE) && !inv.RemoveItem(itemId))
  11717. {
  11718. LogAssert(false,"Failed to remove consumable item from player inventory!" + inv.GetItemName( itemId ) );
  11719. return false;
  11720. }
  11721.  
  11722. return true;
  11723. }
  11724.  
  11725. public function MountVehicle( vehicleEntity : CEntity, mountType : EVehicleMountType, optional vehicleSlot : EVehicleSlot )
  11726. {
  11727. var vehicle : CVehicleComponent;
  11728. vehicle = (CVehicleComponent)(vehicleEntity.GetComponentByClassName('CVehicleComponent'));
  11729.  
  11730. if ( vehicle )
  11731. vehicle.Mount( this, mountType, vehicleSlot );
  11732. }
  11733.  
  11734. public function DismountVehicle( vehicleEntity : CEntity, dismountType : EDismountType )
  11735. {
  11736. var vehicle : CVehicleComponent;
  11737. vehicle = (CVehicleComponent)(vehicleEntity.GetComponentByClassName('CVehicleComponent'));
  11738.  
  11739. if ( vehicle )
  11740. vehicle.IssueCommandToDismount( dismountType );
  11741. }
  11742.  
  11743. ////////////////
  11744. // @stamina @stats
  11745. ////////////////
  11746.  
  11747. protected function ShouldDrainStaminaWhileSprinting() : bool
  11748. {
  11749. if( HasBuff( EET_PolishedGenitals ) && !IsInCombat() && !IsThreatened() )
  11750. {
  11751. return false;
  11752. }
  11753.  
  11754. return super.ShouldDrainStaminaWhileSprinting();
  11755. }
  11756.  
  11757. //Returns true if actor has enough stamina to perform given action type (refer to DrainStamina for more info).
  11758. //If there is not enough stamina and actor is a player character then a insufficient stamina indication is shown on HUD
  11759. public function HasStaminaToUseAction(action : EStaminaActionType, optional abilityName : name, optional dt :float, optional multiplier : float) : bool
  11760. {
  11761. var cost, temp : float;
  11762. var ret : bool;
  11763.  
  11764. if( dt == 0 )
  11765. dt = 1;
  11766. if( multiplier == 0 )
  11767. multiplier = 1;
  11768.  
  11769. cost = Combat().GetActionStaminaCost(action, temp, multiplier, dt, abilityName);
  11770. ret = GetStat(BCS_Stamina) >= cost; // super.HasStaminaToUseAction(action, abilityName, dt, multiplier);
  11771.  
  11772. if(!ret)
  11773. {
  11774. SetCombatActionHeading( GetHeading() );
  11775.  
  11776. if(multiplier == 0)
  11777. multiplier = 1;
  11778.  
  11779. //cost = multiplier * GetStaminaActionCost(action, abilityName, dt);
  11780. SetShowToLowStaminaIndication(cost);
  11781. }
  11782.  
  11783. return ret;
  11784. }
  11785. // W3EE - End
  11786. //since we cannot add timer on abilityManager...
  11787. timer function AbilityManager_FloorStaminaSegment(dt : float, id : int)
  11788. {
  11789. ((W3PlayerAbilityManager)abilityManager).FloorStaminaSegment();
  11790. }
  11791.  
  11792. public function DrainToxicity(amount : float )
  11793. {
  11794. if(abilityManager && abilityManager.IsInitialized() && IsAlive())
  11795. abilityManager.DrainToxicity(amount);
  11796. }
  11797.  
  11798. // W3EE - Begin
  11799. public function DrainFocus(amount : float, optional dt : float, optional isUndyingCall : bool )
  11800. {
  11801. if(abilityManager && abilityManager.IsInitialized() && IsAlive())
  11802. abilityManager.DrainFocus(amount, dt, isUndyingCall);
  11803. }
  11804. // W3EE - End
  11805.  
  11806. public function GetOffenseStat():int
  11807. {
  11808. if(abilityManager && abilityManager.IsInitialized())
  11809. return ((W3PlayerAbilityManager)abilityManager).GetOffenseStat();
  11810.  
  11811. return 0;
  11812. }
  11813.  
  11814. public function GetDefenseStat():int
  11815. {
  11816. if(abilityManager && abilityManager.IsInitialized())
  11817. return ((W3PlayerAbilityManager)abilityManager).GetDefenseStat();
  11818.  
  11819. return 0;
  11820. }
  11821.  
  11822. public function GetSignsStat():float
  11823. {
  11824. if(abilityManager && abilityManager.IsInitialized())
  11825. return ((W3PlayerAbilityManager)abilityManager).GetSignsStat();
  11826.  
  11827. return 0;
  11828. }
  11829.  
  11830. ////////////////
  11831. // water
  11832. ////////////////
  11833.  
  11834. private var inWaterTrigger : bool;
  11835.  
  11836. event OnOceanTriggerEnter()
  11837. {
  11838. inWaterTrigger = true;
  11839. }
  11840.  
  11841. event OnOceanTriggerLeave()
  11842. {
  11843. inWaterTrigger = false;
  11844. }
  11845.  
  11846. public function IsInWaterTrigger() : bool
  11847. {
  11848. return inWaterTrigger;
  11849. }
  11850.  
  11851. //////////////////////////////////////////////////////////////////////////////////////////
  11852. // @Skills @Perks
  11853. //////////////////////////////////////////////////////////////////////////////////////////
  11854.  
  11855. public function GetSkillColor(skill : ESkill) : ESkillColor
  11856. {
  11857. if(abilityManager && abilityManager.IsInitialized())
  11858. return ((W3PlayerAbilityManager)abilityManager).GetSkillColor(skill);
  11859.  
  11860. return SC_None;
  11861. }
  11862.  
  11863. public function GetSkillSlotIndexFromSkill(skill : ESkill) : int
  11864. {
  11865. if(abilityManager && abilityManager.IsInitialized())
  11866. return ((W3PlayerAbilityManager)abilityManager).GetSkillSlotIndexFromSkill(skill);
  11867.  
  11868. return -1;
  11869. }
  11870.  
  11871. public final function GetSkillSlotIndex(slotID : int, checkIfUnlocked : bool) : int
  11872. {
  11873. if(abilityManager && abilityManager.IsInitialized())
  11874. return ((W3PlayerAbilityManager)abilityManager).GetSkillSlotIndex(slotID, checkIfUnlocked);
  11875.  
  11876. return -1;
  11877. }
  11878.  
  11879. public final function GetSkillSlotIDFromIndex(skillSlotIndex : int) : int
  11880. {
  11881. if(abilityManager && abilityManager.IsInitialized())
  11882. return ((W3PlayerAbilityManager)abilityManager).GetSkillSlotIDFromIndex(skillSlotIndex);
  11883.  
  11884. return -1;
  11885. }
  11886.  
  11887. public function GetSkillSlotID(skill : ESkill) : int
  11888. {
  11889. if(abilityManager && abilityManager.IsInitialized())
  11890. return ((W3PlayerAbilityManager)abilityManager).GetSkillSlotID(skill);
  11891.  
  11892. return -1;
  11893. }
  11894.  
  11895. public function GetSkillGroupBonus(groupID : int) : name
  11896. {
  11897. if(abilityManager && abilityManager.IsInitialized())
  11898. return ((W3PlayerAbilityManager)abilityManager).GetGroupBonus(groupID);
  11899.  
  11900. return '';
  11901. }
  11902.  
  11903. public function GetGroupBonusCount(commonColor : ESkillColor,groupID : int) : int
  11904. {
  11905. if(abilityManager && abilityManager.IsInitialized())
  11906. return ((W3PlayerAbilityManager)abilityManager).GetSkillGroupColorCount(commonColor, groupID);
  11907.  
  11908. return 0;
  11909. }
  11910.  
  11911. public function GetMutagenSlotIDFromGroupID(groupID : int) : int
  11912. {
  11913. if(abilityManager && abilityManager.IsInitialized())
  11914. return ((W3PlayerAbilityManager)abilityManager).GetMutagenSlotIDFromGroupID(groupID);
  11915.  
  11916. return -1;
  11917. }
  11918.  
  11919. public function GetSkillLevel(skill : ESkill) : int
  11920. {
  11921. if(abilityManager && abilityManager.IsInitialized())
  11922. return ((W3PlayerAbilityManager)abilityManager).GetSkillLevel(skill);
  11923.  
  11924. return -1;
  11925. }
  11926.  
  11927. public function GetBoughtSkillLevel(skill : ESkill) : int
  11928. {
  11929. if(abilityManager && abilityManager.IsInitialized())
  11930. return ((W3PlayerAbilityManager)abilityManager).GetBoughtSkillLevel(skill);
  11931.  
  11932. return -1;
  11933. }
  11934.  
  11935. public function AddSkill(skill : ESkill, optional isTemporary : bool)
  11936. {
  11937. if(abilityManager && abilityManager.IsInitialized())
  11938. ((W3PlayerAbilityManager)abilityManager).AddSkill(skill, isTemporary);
  11939. }
  11940.  
  11941. public function AddMultipleSkills(skill : ESkill, optional number : int, optional isTemporary : bool)
  11942. {
  11943. var i : int;
  11944.  
  11945. if(number)
  11946. {
  11947. for( i=0; i<number; i+=1)
  11948. {
  11949. AddSkill(skill,isTemporary);
  11950. }
  11951. }
  11952. else
  11953. {
  11954. AddSkill(skill,isTemporary);
  11955. }
  11956. }
  11957.  
  11958. public function GetSkillAbilityName(skill : ESkill) : name
  11959. {
  11960. if(abilityManager && abilityManager.IsInitialized())
  11961. return ((W3PlayerAbilityManager)abilityManager).GetSkillAbilityName(skill);
  11962.  
  11963. return '';
  11964. }
  11965.  
  11966. public function HasStaminaToUseSkill(skill : ESkill, optional perSec : bool, optional signHack : bool) : bool
  11967. {
  11968. var ret : bool;
  11969. var cost : float;
  11970.  
  11971. cost = GetSkillStaminaUseCost(skill, perSec);
  11972.  
  11973. if( IsSkillSign(skill) )
  11974. {
  11975. if( ((W3PlayerWitcher)this).HasQuen() && skill == S_Magic_4 )
  11976. return true;
  11977. }
  11978.  
  11979. //perk, using adrenaline instead of stamina when out of stamina
  11980.  
  11981. if(!ret && IsSkillSign(skill) && CanUseSkill(S_Perk_09) && GetStat(BCS_Stamina) >= cost)
  11982. {
  11983. ret = true;
  11984. }
  11985.  
  11986. //Gryphon Armor Set Bonus 1 - next basic sign is being cast for free
  11987. if( !ret && IsSkillSign( skill ) && GetWitcherPlayer().HasBuff( EET_GryphonSetBonus ) )
  11988. {
  11989. ret = true;
  11990. }
  11991.  
  11992. if(!ret)
  11993. {
  11994. SetCombatActionHeading( GetHeading() );
  11995. IndicateTooLowAdrenaline();
  11996. //SetShowToLowStaminaIndication(cost);
  11997. }
  11998.  
  11999. return ret;
  12000. // W3EE - End
  12001. }
  12002.  
  12003. protected function GetSkillStaminaUseCost(skill : ESkill, optional perSec : bool) : float
  12004. {
  12005. if(abilityManager && abilityManager.IsInitialized())
  12006. return ((W3PlayerAbilityManager)abilityManager).GetSkillStaminaUseCost(skill, perSec);
  12007.  
  12008. return 0;
  12009. }
  12010.  
  12011. //works for perks and bookperks as well
  12012. public function GetSkillAttributeValue(skill : ESkill, attributeName : name, addBaseCharAttribute : bool, addSkillModsAttribute : bool) : SAbilityAttributeValue
  12013. {
  12014. var null : SAbilityAttributeValue;
  12015.  
  12016. if(abilityManager && abilityManager.IsInitialized())
  12017. return abilityManager.GetSkillAttributeValue(SkillEnumToName(skill), attributeName, addBaseCharAttribute, addSkillModsAttribute);
  12018.  
  12019. return null;
  12020. }
  12021.  
  12022. public function GetSkillLocalisationKeyName(skill : ESkill) : string // #B
  12023. {
  12024. if(abilityManager && abilityManager.IsInitialized())
  12025. return ((W3PlayerAbilityManager)abilityManager).GetSkillLocalisationKeyName(skill);
  12026.  
  12027. return "";
  12028. }
  12029.  
  12030. public function GetSkillLocalisationKeyDescription(skill : ESkill) : string // #B
  12031. {
  12032. if(abilityManager && abilityManager.IsInitialized())
  12033. return ((W3PlayerAbilityManager)abilityManager).GetSkillLocalisationKeyDescription(skill);
  12034.  
  12035. return "";
  12036. }
  12037.  
  12038. public function GetSkillIconPath(skill : ESkill) : string // #B
  12039. {
  12040. if(abilityManager && abilityManager.IsInitialized())
  12041. return ((W3PlayerAbilityManager)abilityManager).GetSkillIconPath(skill);
  12042.  
  12043. return "";
  12044. }
  12045.  
  12046. public function HasLearnedSkill(skill : ESkill) : bool
  12047. {
  12048. if(abilityManager && abilityManager.IsInitialized())
  12049. return ((W3PlayerAbilityManager)abilityManager).HasLearnedSkill(skill);
  12050.  
  12051. return false;
  12052. }
  12053.  
  12054. public function IsSkillEquipped(skill : ESkill) : bool
  12055. {
  12056. if(abilityManager && abilityManager.IsInitialized())
  12057. return ((W3PlayerAbilityManager)abilityManager).IsSkillEquipped(skill);
  12058.  
  12059. return false;
  12060. }
  12061.  
  12062. public function CanUseSkill(skill : ESkill) : bool
  12063. {
  12064. if(abilityManager && abilityManager.IsInitialized())
  12065. return ((W3PlayerAbilityManager)abilityManager).CanUseSkill(skill);
  12066. return false;
  12067. }
  12068.  
  12069. public function CanLearnSkill(skill : ESkill) : bool //#B
  12070. {
  12071. if(abilityManager && abilityManager.IsInitialized())
  12072. return ((W3PlayerAbilityManager)abilityManager).CanLearnSkill(skill);
  12073.  
  12074. return false;
  12075. }
  12076.  
  12077. public function HasSpentEnoughPoints(skill : ESkill) : bool //#J
  12078. {
  12079. if(abilityManager && abilityManager.IsInitialized())
  12080. return ((W3PlayerAbilityManager)abilityManager).HasSpentEnoughPoints(skill);
  12081.  
  12082. return false;
  12083. }
  12084.  
  12085. public function PathPointsForSkillsPath(skill : ESkill) : int //#J
  12086. {
  12087. if(abilityManager && abilityManager.IsInitialized())
  12088. return ((W3PlayerAbilityManager)abilityManager).PathPointsSpentInSkillPathOfSkill(skill);
  12089.  
  12090. return -1;
  12091. }
  12092.  
  12093. public function GetPlayerSkills() : array<SSkill> // #B
  12094. {
  12095. var null : array<SSkill>;
  12096.  
  12097. if(abilityManager && abilityManager.IsInitialized())
  12098. return ((W3PlayerAbilityManager)abilityManager).GetPlayerSkills();
  12099.  
  12100. return null;
  12101. }
  12102.  
  12103. public function GetPlayerSkill(s : ESkill) : SSkill // #B
  12104. {
  12105. var null : SSkill;
  12106.  
  12107. if(abilityManager && abilityManager.IsInitialized())
  12108. return ((W3PlayerAbilityManager)abilityManager).GetPlayerSkill(s);
  12109.  
  12110. return null;
  12111. }
  12112.  
  12113. public function GetSkillSubPathType(s : ESkill) : ESkillSubPath // #B
  12114. {
  12115. if(abilityManager && abilityManager.IsInitialized())
  12116. return ((W3PlayerAbilityManager)abilityManager).GetSkillSubPathType(s);
  12117.  
  12118. return ESSP_NotSet;
  12119. }
  12120.  
  12121. public function GetSkillSlotsCount() : int
  12122. {
  12123. if(abilityManager && abilityManager.IsInitialized())
  12124. return ((W3PlayerAbilityManager)abilityManager).GetSkillSlotsCount();
  12125.  
  12126. return 0;
  12127. }
  12128.  
  12129. public function GetSkillSlots() : array<SSkillSlot>
  12130. {
  12131. var null : array<SSkillSlot>;
  12132.  
  12133. if(abilityManager && abilityManager.IsInitialized())
  12134. return ((W3PlayerAbilityManager)abilityManager).GetSkillSlots();
  12135.  
  12136. return null;
  12137. }
  12138.  
  12139. public function GetPlayerSkillMutagens() : array<SMutagenSlot>
  12140. {
  12141. var null : array<SMutagenSlot>;
  12142.  
  12143. if(abilityManager && abilityManager.IsInitialized())
  12144. return ((W3PlayerAbilityManager)abilityManager).GetPlayerSkillMutagens();
  12145.  
  12146. return null;
  12147. }
  12148.  
  12149. // mutagens
  12150. //public function OnSkillMutagenEquipped()
  12151.  
  12152. public function BlockSkill(skill : ESkill, block : bool, optional cooldown : float) : bool
  12153. {
  12154. if(abilityManager && abilityManager.IsInitialized())
  12155. return ((W3PlayerAbilityManager)abilityManager).BlockSkill(skill, block, cooldown);
  12156.  
  12157. return false;
  12158. }
  12159.  
  12160. public function IsSkillBlocked(skill : ESkill) : bool
  12161. {
  12162. if(abilityManager && abilityManager.IsInitialized())
  12163. return ((W3PlayerAbilityManager)abilityManager).IsSkillBlocked(skill);
  12164.  
  12165. return false;
  12166. }
  12167.  
  12168. //returns true if succeeded
  12169. public function EquipSkill(skill : ESkill, slotID : int) : bool
  12170. {
  12171. var ret : bool;
  12172. var groupID : int;
  12173. var pam : W3PlayerAbilityManager;
  12174.  
  12175. if(abilityManager && abilityManager.IsInitialized())
  12176. {
  12177. pam = (W3PlayerAbilityManager)abilityManager;
  12178. ret = pam.EquipSkill(skill, slotID);
  12179. if(ret)
  12180. {
  12181. groupID = pam.GetSkillGroupIdFromSkillSlotId(slotID);
  12182. LogSkillColors("Equipped <<" + GetSkillColor(skill) + ">> skill <<" + skill + ">> to group <<" + groupID + ">>");
  12183. LogSkillColors("Group bonus color is now <<" + pam.GetSkillGroupColor(groupID) + ">>");
  12184. LogSkillColors("");
  12185. }
  12186.  
  12187. return ret;
  12188. }
  12189.  
  12190. return false;
  12191. }
  12192.  
  12193. //returns true if succeeded
  12194. public function UnequipSkill(slotID : int) : bool
  12195. {
  12196. var ret : bool;
  12197. var groupID : int;
  12198. var skill : ESkill;
  12199. var pam : W3PlayerAbilityManager;
  12200.  
  12201. if(abilityManager && abilityManager.IsInitialized())
  12202. {
  12203. pam = (W3PlayerAbilityManager)abilityManager;
  12204. GetSkillOnSlot(slotID, skill);
  12205. ret = pam.UnequipSkill(slotID);
  12206. if(ret)
  12207. {
  12208. groupID = pam.GetSkillGroupIdFromSkillSlotId(slotID);
  12209. LogSkillColors("Unequipped <<" + GetSkillColor(skill) + ">> skill <<" + skill + ">> from group <<" + groupID + ">>");
  12210. LogSkillColors("Group bonus color is now <<" + pam.GetSkillGroupColor(groupID) + ">>");
  12211. LogSkillColors("");
  12212. }
  12213. return ret;
  12214. }
  12215.  
  12216. return false;
  12217. }
  12218.  
  12219. //returns true if succeeded
  12220. public function GetSkillOnSlot(slotID : int, out skill : ESkill) : bool
  12221. {
  12222. if(abilityManager && abilityManager.IsInitialized())
  12223. return ((W3PlayerAbilityManager)abilityManager).GetSkillOnSlot(slotID, skill);
  12224.  
  12225. skill = S_SUndefined;
  12226. return false;
  12227. }
  12228.  
  12229. //returns random free skill slot (if any, otherwise -1)
  12230. public function GetFreeSkillSlot() : int
  12231. {
  12232. var i, size : int;
  12233. var skill : ESkill;
  12234.  
  12235. size = ((W3PlayerAbilityManager)abilityManager).GetSkillSlotsCount();
  12236. for(i=1; i<size; i+=1)
  12237. {
  12238. if(!GetSkillOnSlot(i, skill))
  12239. continue; //if slot locked
  12240.  
  12241. if(skill == S_SUndefined) //empty unlocked slot
  12242. return i;
  12243. }
  12244.  
  12245. return -1;
  12246. }
  12247.  
  12248. //////////////////
  12249. // @attacks
  12250. //////////////////
  12251.  
  12252. //performs an attack (mechanics wise) on given target and using given attack data
  12253. protected function Attack( hitTarget : CGameplayEntity, animData : CPreAttackEventData, weaponId : SItemUniqueId, parried : bool, countered : bool, parriedBy : array<CActor>, attackAnimationName : name, hitTime : float, weaponEntity : CItemEntity)
  12254. {
  12255. var attackAction : W3Action_Attack;
  12256.  
  12257. if(!PrepareAttackAction(hitTarget, animData, weaponId, parried, countered, parriedBy, attackAnimationName, hitTime, weaponEntity, attackAction))
  12258. return; //failed to create a valid attack action
  12259.  
  12260. if ( attackAction.IsParried() && ( ((CNewNPC)attackAction.victim).IsShielded(attackAction.attacker) || ((CNewNPC)attackAction.victim).SignalGameplayEventReturnInt('IsDefending',0) == 1 ) )
  12261. {
  12262. thePlayer.SetCanPlayHitAnim(true);
  12263. thePlayer.ReactToReflectedAttack(attackAction.victim);
  12264. }
  12265.  
  12266. theTelemetry.LogWithLabel( TE_FIGHT_PLAYER_ATTACKS, attackAction.GetAttackName() );
  12267.  
  12268. //process action
  12269. theGame.damageMgr.ProcessAction(attackAction);
  12270.  
  12271. delete attackAction;
  12272. }
  12273.  
  12274. public function IsHeavyAttack(attackName : name) : bool
  12275. {
  12276. var skill : ESkill;
  12277. var sup : bool;
  12278.  
  12279. sup = super.IsHeavyAttack(attackName);
  12280. if(sup)
  12281. return true;
  12282.  
  12283. // W3EE - Begin
  12284. if ( attackName == 'attack_heavy_special' || attackName == 'geralt_heavy_special1' || attackName == 'geralt_heavy_special2' )
  12285. return true;
  12286. // W3EE - End
  12287.  
  12288. skill = SkillNameToEnum(attackName);
  12289.  
  12290. return skill == S_Sword_2 || skill == S_Sword_s02;
  12291. }
  12292.  
  12293. public function IsLightAttack(attackName : name) : bool
  12294. {
  12295. var skill : ESkill;
  12296. var sup : bool;
  12297.  
  12298. sup = super.IsLightAttack(attackName);
  12299. if(sup)
  12300. return true;
  12301.  
  12302. // W3EE - Begin
  12303. if ( attackName == 'attack_light_special' || StrContains(NameToString(attackName), "counter") )
  12304. return true;
  12305. // W3EE - End
  12306.  
  12307. skill = SkillNameToEnum(attackName);
  12308.  
  12309. return skill == S_Sword_1 || skill == S_Sword_s01;
  12310. }
  12311.  
  12312. // W3EE - Begin
  12313. public function IsSpecialAttack( attackName : name ) : bool
  12314. {
  12315. return attackName == 'geralt_kick_special' || attackName == 'geralt_heavy_special1' || attackName == 'geralt_heavy_special2';
  12316. }
  12317.  
  12318. public function IsCounterAttack( attackName : name ) : bool
  12319. {
  12320. return StrContains(NameToString(attackName), "counter");
  12321. }
  12322. // W3EE - End
  12323.  
  12324. public final function ProcessWeaponCollision()
  12325. {
  12326. var l_stateName : name;
  12327.  
  12328. var l_weaponPosition : Vector;
  12329. var l_weaponTipPos : Vector;
  12330. var l_collidingPosition : Vector;
  12331. var l_offset : Vector;
  12332. var l_normal : Vector;
  12333.  
  12334. var l_slotMatrix : Matrix;
  12335.  
  12336. var l_distance : float;
  12337.  
  12338. var l_materialName : name;
  12339. var l_hitComponent : CComponent;
  12340. var l_destructibleCmp : CDestructionSystemComponent;
  12341. var barrel : COilBarrelEntity;
  12342.  
  12343. //return;
  12344.  
  12345. if( isCurrentlyDodging )
  12346. return;
  12347.  
  12348. l_stateName = GetCurrentStateName();
  12349.  
  12350. if( !attackEventInProgress && l_stateName == 'CombatFists' )
  12351. return;
  12352.  
  12353. CalcEntitySlotMatrix('r_weapon', l_slotMatrix);
  12354.  
  12355. l_weaponPosition = MatrixGetTranslation( l_slotMatrix );
  12356.  
  12357. // Finding weapon's tip
  12358. switch( l_stateName )
  12359. {
  12360. case 'CombatFists':
  12361. l_offset = MatrixGetAxisX( l_slotMatrix );
  12362. l_offset = VecNormalize( l_offset ) * 0.25f;
  12363. break;
  12364. // sword
  12365. default:
  12366. l_offset = MatrixGetAxisZ( l_slotMatrix );
  12367. l_offset = VecNormalize( l_offset ) * 1.f;
  12368. break;
  12369. }
  12370.  
  12371. l_weaponTipPos = l_weaponPosition + l_offset;
  12372.  
  12373.  
  12374.  
  12375. if( !attackEventInProgress )
  12376. {
  12377. // If the weapon is not moving fast enough, do not play collision fx
  12378. if( m_LastWeaponTipPos == Vector ( 0, 0, 0 ) )
  12379. l_distance = 0;
  12380. else
  12381. l_distance = VecDistance( l_weaponTipPos, m_LastWeaponTipPos ) ;
  12382.  
  12383. //GetVisualDebug().AddText( 'LastWeaponTipText', "Last - dist: " + l_distance, m_LastWeaponTipPos, true, , Color( 249, 98, 158 ) );
  12384. //GetVisualDebug().AddArrow( 'OldDirectArrow', l_weaponPosition, m_LastWeaponTipPos , 0.8f, 0.1f, 0.2f, true, Color( 249, 98, 158 ) );
  12385.  
  12386. m_LastWeaponTipPos = l_weaponTipPos;
  12387. if( l_distance < 0.35f )
  12388. return;
  12389.  
  12390. }
  12391.  
  12392. /*GetVisualDebug().AddSphere( 'WeaponPosition', 0.1f, l_weaponPosition, true, Color( 249, 98, 158 ) );
  12393. GetVisualDebug().AddText( 'WeaponTipText', "Weapon Tip", l_weaponTipPos, true, , Color( 249, 98, 158 ) );
  12394. GetVisualDebug().AddArrow( 'CollisionArrow', l_weaponPosition, l_weaponTipPos , 0.8f, 0.1f, 0.2f, true, Color( 249, 98, 158 ) );*/
  12395.  
  12396. m_LastWeaponTipPos = l_weaponTipPos;
  12397.  
  12398. if ( !theGame.GetWorld().StaticTraceWithAdditionalInfo( l_weaponPosition, l_weaponTipPos, l_collidingPosition, l_normal, l_materialName, l_hitComponent, m_WeaponFXCollisionGroupNames ) )
  12399. {
  12400. // Test left fist
  12401. if( l_stateName == 'CombatFists' )
  12402. {
  12403. CalcEntitySlotMatrix('l_weapon', l_slotMatrix);
  12404. l_weaponPosition = MatrixGetTranslation( l_slotMatrix );
  12405. l_offset = MatrixGetAxisX( l_slotMatrix );
  12406. l_offset = VecNormalize( l_offset ) * 0.25f;
  12407. l_weaponTipPos = l_weaponPosition + l_offset;
  12408. if( !theGame.GetWorld().StaticTrace( l_weaponPosition, l_weaponTipPos, l_collidingPosition, l_normal, m_WeaponFXCollisionGroupNames ) )
  12409. {
  12410. return;
  12411. }
  12412. }
  12413. else
  12414. {
  12415. return;
  12416. }
  12417. }
  12418.  
  12419. if( !m_CollisionEffect )
  12420. {
  12421. m_CollisionEffect = theGame.CreateEntity( m_CollisionFxTemplate, l_collidingPosition, EulerAngles(0,0,0) );
  12422. }
  12423.  
  12424. m_CollisionEffect.Teleport( l_collidingPosition );
  12425.  
  12426. // Play hit effect
  12427. switch( l_stateName )
  12428. {
  12429. case 'CombatFists':
  12430. m_CollisionEffect.PlayEffect('fist');
  12431. break;
  12432. default:
  12433. // Optimisation because IsSwordWooden() is heavy (around 0.13 ms)
  12434. if( m_RefreshWeaponFXType )
  12435. {
  12436. m_PlayWoodenFX = IsSwordWooden();
  12437. m_RefreshWeaponFXType = false;
  12438. }
  12439.  
  12440. if( m_PlayWoodenFX )
  12441. {
  12442. m_CollisionEffect.PlayEffect('wood');
  12443. }
  12444. else
  12445. {
  12446. switch( l_materialName )
  12447. {
  12448. case 'wood_hollow':
  12449. case 'wood_debris':
  12450. case 'wood_solid':
  12451. m_CollisionEffect.PlayEffect('wood');
  12452. break;
  12453. case 'dirt_hard':
  12454. case 'dirt_soil':
  12455. case 'hay':
  12456. m_CollisionEffect.PlayEffect('fist');
  12457. break;
  12458. case 'stone_debris':
  12459. case 'stone_solid':
  12460. case 'clay_tile':
  12461. case 'gravel_large':
  12462. case 'gravel_small':
  12463. case 'metal':
  12464. case 'custom_sword':
  12465. m_CollisionEffect.PlayEffect('sparks');
  12466. break;
  12467. case 'flesh':
  12468. m_CollisionEffect.PlayEffect('blood');
  12469. break;
  12470. default:
  12471. m_CollisionEffect.PlayEffect('wood');
  12472. break;
  12473. }
  12474.  
  12475. }
  12476. break;
  12477. }
  12478.  
  12479. //don't ask...
  12480. if(l_hitComponent)
  12481. {
  12482. barrel = (COilBarrelEntity)l_hitComponent.GetEntity();
  12483. if(barrel)
  12484. {
  12485. barrel.OnFireHit(NULL); //sets barrel on fire so that it explodes in a few sec
  12486. return;
  12487. }
  12488. }
  12489.  
  12490. // Destroy destructibles
  12491. l_destructibleCmp = (CDestructionSystemComponent) l_hitComponent;
  12492. if( l_destructibleCmp && l_stateName != 'CombatFists' )
  12493. {
  12494. l_destructibleCmp.ApplyFracture();
  12495. }
  12496.  
  12497.  
  12498. //GetVisualDebug().AddText( 'collisionText', "Collision Here", l_collidingPosition, true, , Color( 249, 98, 158 ) );
  12499. }
  12500.  
  12501. public function ReactToReflectedAttack( target : CGameplayEntity)
  12502. {
  12503.  
  12504. var hp, dmg : float;
  12505. var action : W3DamageAction;
  12506.  
  12507. super.ReactToReflectedAttack(target);
  12508.  
  12509. if ( !((CNewNPC)target).IsShielded(this) )
  12510. {
  12511. action = new W3DamageAction in this;
  12512. action.Initialize(target,this,NULL,'',EHRT_Reflect,CPS_AttackPower,true,false,false,false);
  12513. action.AddEffectInfo(EET_Stagger);
  12514. action.SetProcessBuffsIfNoDamage(true);
  12515.  
  12516. theGame.damageMgr.ProcessAction( action );
  12517. delete action;
  12518. }
  12519.  
  12520. theGame.VibrateControllerLight();//player attack was reflected
  12521. }
  12522.  
  12523. //////////////////
  12524. // falling damage
  12525. //////////////////
  12526.  
  12527. //return false when not falling
  12528. function GetFallDist( out fallDist : float ) : bool
  12529. {
  12530. var fallDiff, jumpTotalDiff : float;
  12531.  
  12532. // Get the falling height
  12533. substateManager.m_SharedDataO.CalculateFallingHeights( fallDiff, jumpTotalDiff );
  12534.  
  12535. if ( fallDiff <= 0 )
  12536. return false;
  12537.  
  12538. fallDist = fallDiff;
  12539. return true;
  12540. }
  12541.  
  12542. function ApplyFallingDamage(heightDiff : float, optional reducing : bool) : float
  12543. {
  12544. var hpPerc : float;
  12545. var tut : STutorialMessage;
  12546.  
  12547. if ( IsSwimming() || FactsQuerySum("block_falling_damage") >= 1 )
  12548. return 0.0f;
  12549.  
  12550. hpPerc = super.ApplyFallingDamage( heightDiff, reducing );
  12551.  
  12552. if(hpPerc > 0)
  12553. {
  12554. theGame.VibrateControllerHard();//player falling damage
  12555.  
  12556. if(IsAlive())
  12557. {
  12558. if(ShouldProcessTutorial('TutorialFallingDamage'))
  12559. {
  12560. FactsSet( "tutorial_falling_damage", 1 );
  12561. }
  12562.  
  12563. if(FactsQuerySum("tutorial_falling_damage") > 1 && ShouldProcessTutorial('TutorialFallingRoll'))
  12564. {
  12565. //fill tutorial object data
  12566. tut.type = ETMT_Hint;
  12567. tut.tutorialScriptTag = 'TutorialFallingRoll';
  12568. tut.hintPositionType = ETHPT_DefaultGlobal;
  12569. tut.hintDurationType = ETHDT_Long;
  12570. tut.canBeShownInMenus = false;
  12571. tut.glossaryLink = false;
  12572. tut.markAsSeenOnShow = true;
  12573.  
  12574. //show tutorial
  12575. theGame.GetTutorialSystem().DisplayTutorial(tut);
  12576. }
  12577. }
  12578. }
  12579.  
  12580. return hpPerc;
  12581. }
  12582.  
  12583. //--------------------------------- STAMINA INDICATOR #B --------------------------------------
  12584.  
  12585. public function SetShowToLowStaminaIndication( value : float ) : void
  12586. {
  12587. // W3EE - Begin
  12588. SoundEvent("gui_no_stamina");
  12589. // W3EE - End
  12590. fShowToLowStaminaIndication = value;
  12591. }
  12592.  
  12593. public function GetShowToLowStaminaIndication() : float
  12594. {
  12595. return fShowToLowStaminaIndication;
  12596. }
  12597.  
  12598. public final function IndicateTooLowAdrenaline()
  12599. {
  12600. SoundEvent("gui_no_adrenaline");
  12601. showTooLowAdrenaline = true;
  12602. }
  12603.  
  12604. /////////////////////////////////
  12605.  
  12606. protected function GotoCombatStateWithAction( initialAction : EInitialAction, optional initialBuff : CBaseGameplayEffect )
  12607. {
  12608. if ( this.GetCurrentActionType() == ActorAction_Exploration )
  12609. ActionCancelAll();
  12610.  
  12611. ((W3PlayerWitcherStateCombatFists)this.GetState('CombatFists')).SetupState( initialAction, initialBuff );
  12612. this.GotoState( 'CombatFists' );
  12613.  
  12614. }
  12615. ///////////////////////////////////////////////////////////////////////////////////////////
  12616. // COMBAT
  12617. public function IsThreat( actor : CActor, optional usePrecalcs : bool ) : bool
  12618. {
  12619. var npc : CNewNPC;
  12620. var dist : float;
  12621. var targetCapsuleHeight : float;
  12622. var isDistanceExpanded : bool;
  12623. var distanceToTarget : float;
  12624. var attitude : EAIAttitude;
  12625.  
  12626. if (!actor)
  12627. {
  12628. return false;
  12629. }
  12630.  
  12631. if ( finishableEnemiesList.Contains( actor ) )
  12632. {
  12633. return true;
  12634. }
  12635.  
  12636. if ( !actor.IsAlive() || actor.IsKnockedUnconscious() )
  12637. {
  12638. return false;
  12639. }
  12640.  
  12641. npc = (CNewNPC)actor;
  12642. if (npc && npc.IsHorse() )
  12643. {
  12644. return false;
  12645. }
  12646.  
  12647. if ( hostileEnemies.Contains( actor ) )
  12648. {
  12649. return true;
  12650. }
  12651.  
  12652. //MS: We add a tolerance to make geralt go to alertfar everytime he runs away from npc
  12653. if ( GetAttitudeBetween( this, actor ) == AIA_Hostile )
  12654. {
  12655. if ( usePrecalcs )
  12656. {
  12657. distanceToTarget = Distance2DBetweenCapsuleAndPoint( actor, this ) - targetingPrecalcs.playerRadius;
  12658. }
  12659. else
  12660. {
  12661. distanceToTarget = Distance2DBetweenCapsules( this, actor );
  12662. }
  12663.  
  12664. // shortDistance = findMoveTargetDist + 5.0f;
  12665. if ( distanceToTarget < findMoveTargetDist + 5.0f )
  12666. {
  12667. return true;
  12668. }
  12669.  
  12670. if ( actor.IsInCombat() || this.IsHardLockEnabled() )
  12671. {
  12672. targetCapsuleHeight = ( (CMovingPhysicalAgentComponent)actor.GetMovingAgentComponent() ).GetCapsuleHeight();
  12673. if ( targetCapsuleHeight >= 2.0f || npc.GetCurrentStance() == NS_Fly )
  12674. {
  12675. // expandedDistance = 40.f;
  12676. if ( distanceToTarget < 40.0f )
  12677. {
  12678. return true;
  12679. }
  12680. }
  12681. }
  12682. }
  12683.  
  12684. if ( actor.GetAttitudeGroup() == 'npc_charmed' )
  12685. {
  12686. if ( theGame.GetGlobalAttitude( GetBaseAttitudeGroup(), actor.GetBaseAttitudeGroup() ) == AIA_Hostile )
  12687. {
  12688. return true;
  12689. }
  12690. }
  12691.  
  12692. return false;
  12693. }
  12694.  
  12695. function SetBIsCombatActionAllowed ( flag : bool )
  12696. {
  12697. bIsCombatActionAllowed = flag;
  12698.  
  12699. if ( !flag )
  12700. {
  12701. SetBIsInCombatAction(true);
  12702. }
  12703. else
  12704. {
  12705. this.ProcessLAxisCaching();
  12706. //UnblockAction(EIAB_Interactions, 'InsideCombatAction' );
  12707. }
  12708.  
  12709. //LogChannel('combatActionAllowed', "Is SET TO: " + flag );
  12710. }
  12711.  
  12712. function GetBIsCombatActionAllowed() : bool
  12713. {
  12714. return bIsCombatActionAllowed;
  12715. }
  12716.  
  12717. function SetCombatAction( action : EBufferActionType )
  12718. {
  12719. currentCombatAction = action;
  12720. }
  12721.  
  12722. function GetCombatAction() : EBufferActionType
  12723. {
  12724. return currentCombatAction;
  12725. }
  12726.  
  12727. protected function WhenCombatActionIsFinished()
  12728. {
  12729. if(IsThrowingItem() || IsThrowingItemWithAim() )
  12730. {
  12731. if(inv.IsItemBomb(selectedItemId))
  12732. {
  12733. BombThrowAbort();
  12734. }
  12735. else
  12736. {
  12737. ThrowingAbort();
  12738. }
  12739. }
  12740.  
  12741. if ( this.GetCurrentStateName() != 'DismountHorse' )
  12742. OnRangedForceHolster( true );
  12743.  
  12744. //SetBehaviorVariable( 'combatActionType', (int)CAT_None2);
  12745. }
  12746.  
  12747. public function IsInCombatAction_Attack(): bool
  12748. {
  12749. if ( IsInCombatAction_NonSpecialAttack() || IsInCombatAction_SpecialAttack() )
  12750. return true;
  12751. else
  12752. return false;
  12753. }
  12754.  
  12755. public function IsInCombatAction_NonSpecialAttack(): bool
  12756. {
  12757. if ( IsInCombatAction() && ( GetCombatAction() == EBAT_LightAttack || GetCombatAction() == EBAT_HeavyAttack ) )
  12758. return true;
  12759. else
  12760. return false;
  12761. }
  12762.  
  12763. public function IsInSpecificCombatAction ( specificCombatAction : EBufferActionType ) : bool
  12764. {
  12765. if ( IsInCombatAction() && GetCombatAction() == specificCombatAction )
  12766. return true;
  12767. else
  12768. return false;
  12769. }
  12770.  
  12771. public function IsInRunAnimation() : bool
  12772. {
  12773. return isInRunAnimation;
  12774. }
  12775.  
  12776. //I need to call it after scene ends thats why it's public. PF
  12777. public function SetCombatIdleStance( stance : float )
  12778. {
  12779. SetBehaviorVariable( 'combatIdleStance', stance );
  12780. SetBehaviorVariable( 'CombatStanceForOverlay', stance );
  12781.  
  12782. if ( stance == 0.f )
  12783. LogChannel( 'ComboInput', "combatIdleStance = Left" );
  12784. else
  12785. LogChannel( 'ComboInput', "combatIdleStance = Right" );
  12786. }
  12787.  
  12788. public function GetCombatIdleStance() : float
  12789. {
  12790. // 0.f == Left
  12791. return GetBehaviorVariable( 'combatIdleStance' );
  12792. }
  12793.  
  12794. protected var isRotatingInPlace : bool;
  12795. event OnRotateInPlaceStart()
  12796. {
  12797. isRotatingInPlace = true;
  12798. }
  12799.  
  12800. event OnRotateInPlaceEnd()
  12801. {
  12802. isRotatingInPlace = false;
  12803. }
  12804.  
  12805. event OnFullyBlendedIdle()
  12806. {
  12807. if ( bLAxisReleased )
  12808. {
  12809. ResetRawPlayerHeading();
  12810. ResetCachedRawPlayerHeading();
  12811. defaultLocomotionController.ResetMoveDirection();
  12812. }
  12813. }
  12814.  
  12815. private var isInIdle : bool;
  12816.  
  12817. event OnPlayerIdleStart()
  12818. {
  12819. isInIdle = true;
  12820. }
  12821.  
  12822. event OnPlayerIdleEnd()
  12823. {
  12824. isInIdle = false;
  12825. }
  12826.  
  12827. public function IsInIdle() : bool
  12828. {
  12829. return isInIdle;
  12830. }
  12831.  
  12832. event OnRunLoopStart()
  12833. {
  12834. EnableRunCamera( true );
  12835. }
  12836.  
  12837. event OnRunLoopEnd()
  12838. {
  12839. EnableRunCamera( false );
  12840. }
  12841.  
  12842. event OnCombatActionStartBehgraph()
  12843. {
  12844. var action : EBufferActionType;
  12845. var cost, delay : float;
  12846.  
  12847. // Block saves
  12848. //theGame.CreateNoSaveLock( noSaveLockCombatActionName, noSaveLockCombatAction, true );
  12849.  
  12850. OnCombatActionStart();
  12851.  
  12852. action = PerformingCombatAction();
  12853. switch ( action )
  12854. {
  12855. case EBAT_LightAttack :
  12856. {
  12857. abilityManager.GetStaminaActionCost(ESAT_LightAttack, cost, delay);
  12858. } break;
  12859. case EBAT_HeavyAttack :
  12860. {
  12861. abilityManager.GetStaminaActionCost(ESAT_HeavyAttack, cost, delay);
  12862. } break;
  12863. case EBAT_ItemUse :
  12864. {
  12865. abilityManager.GetStaminaActionCost(ESAT_UsableItem, cost, delay);
  12866. } break;
  12867. case EBAT_Parry :
  12868. {
  12869. abilityManager.GetStaminaActionCost(ESAT_Parry, cost, delay);
  12870. } break;
  12871. case EBAT_Dodge :
  12872. {
  12873. abilityManager.GetStaminaActionCost(ESAT_Dodge, cost, delay);
  12874. } break;
  12875. case EBAT_Roll :
  12876. abilityManager.GetStaminaActionCost(ESAT_Roll, cost, delay);
  12877. break;
  12878. case EBAT_SpecialAttack_Light :
  12879. {
  12880. abilityManager.GetStaminaActionCost(ESAT_Ability, cost, delay, 0,0, GetSkillAbilityName(S_Sword_s01));
  12881. } break;
  12882. case EBAT_SpecialAttack_Heavy :
  12883. {
  12884. abilityManager.GetStaminaActionCost(ESAT_Ability, cost, delay, 0,0, GetSkillAbilityName(S_Sword_s02));
  12885. } break;
  12886. case EBAT_Roll :
  12887. {
  12888. abilityManager.GetStaminaActionCost(ESAT_Evade, cost, delay);
  12889. } break;
  12890. /*
  12891. case EBAT_Ciri_SpecialAttack :
  12892. {
  12893. cost = GetStaminaActionCost();
  12894. } break;
  12895. */
  12896. default :
  12897. ;
  12898. }
  12899.  
  12900. //Pause the stamina regen for as long as we're doing combat actions.
  12901. //Pause only once to avoid the pause counter from increasing with each lock
  12902. if( delay > 0 )
  12903. PauseStaminaRegen( 'InsideCombatAction' );
  12904. }
  12905.  
  12906. public function HolsterUsableItem() : bool
  12907. {
  12908. return holsterUsableItem;
  12909. }
  12910.  
  12911. private var isInGuardedState : bool;
  12912. public function IsInGuardedState() : bool
  12913. {
  12914. return isInGuardedState;
  12915. }
  12916.  
  12917. event OnGuardedStart()
  12918. {
  12919. isInParryOrCounter = true;
  12920. isInGuardedState = true;
  12921. }
  12922.  
  12923. event OnGuardedEnd()
  12924. {
  12925. isInParryOrCounter = false;
  12926. isInGuardedState = false;
  12927. }
  12928.  
  12929. private var restoreUsableItem : bool;
  12930. private var holsterUsableItem : bool;
  12931. event OnCombatActionStart()
  12932. {
  12933. //Block Actions
  12934. //BlockAction( EIAB_DrawWeapon, 'OnCombatActionStart' );
  12935.  
  12936. if( combatActionType == 0 )
  12937. SetPlayerAttacking(true);
  12938.  
  12939. if( (W3PlayerWitcher)this )
  12940. {
  12941. if( (combatActionType>= 0 && combatActionType <= 3) || combatActionType == 9 )
  12942. {
  12943. Combat().GetActionType();
  12944. Combat().CombatSpeedModule();
  12945. }
  12946. }
  12947. // W3EE - End
  12948. BlockAction( EIAB_UsableItem, 'OnCombatActionStart' );
  12949. BlockAction( EIAB_CallHorse, 'OnCombatActionStart' );
  12950.  
  12951. /*if ( !IsGuarded() )
  12952. SetParryTarget( NULL );*/
  12953.  
  12954. LogChannel('combatActionAllowed',"FALSE OnCombatActionStart");
  12955. SetBIsCombatActionAllowed( false );
  12956. SetBIsInputAllowed( false, 'OnCombatActionStart' );
  12957. //lastAxisInputIsMovement = true;
  12958.  
  12959. ClearFinishableEnemyList( 0.f, 0 );
  12960.  
  12961. bIsInHitAnim = false;
  12962.  
  12963. //Holster Crossbow if it's held
  12964. //if ( inv.IsItemCrossbow( inv.GetItemFromSlot( 'l_weapon' ) ) )//&& GetBehaviorVariable( 'combatActionType' ) != (int)CAT_Crossbow )
  12965. if ( rangedWeapon && rangedWeapon.GetCurrentStateName() != 'State_WeaponWait' )
  12966. {
  12967. CleanCombatActionBuffer();
  12968. SetIsAimingCrossbow( false );
  12969. OnRangedForceHolster( false, true );
  12970. }
  12971.  
  12972. //Holster UsableItem if it's held
  12973. holsterUsableItem = false;
  12974. if ( thePlayer.IsHoldingItemInLHand() ) // && !thePlayer.IsUsableItemLBlocked() )
  12975. {
  12976. if ( GetBehaviorVariable( 'combatActionType' ) == (int)CAT_CastSign )
  12977. holsterUsableItem = true;
  12978. else if ( GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Attack )
  12979. {
  12980. if ( this.GetCurrentStateName() == 'CombatFists' )
  12981. holsterUsableItem = true;
  12982. }
  12983. }
  12984.  
  12985. if ( holsterUsableItem )
  12986. {
  12987. thePlayer.SetPlayerActionToRestore ( PATR_None );
  12988. thePlayer.OnUseSelectedItem( true );
  12989.  
  12990. restoreUsableItem = true;
  12991. }
  12992.  
  12993. //Stop Geralt from automatically attacking while in AttackApproach when Player performs a non-attack combat action
  12994. if ( GetBehaviorVariable( 'combatActionType' ) != (int)CAT_Attack && GetBehaviorVariable( 'combatActionType' ) != (int)CAT_PreAttack )
  12995. {
  12996. RemoveTimer( 'ProcessAttackTimer' );
  12997. RemoveTimer( 'AttackTimerEnd' );
  12998. UnblockAction( EIAB_DrawWeapon, 'OnCombatActionStart_Attack' );
  12999. }
  13000. else
  13001. {
  13002. //MS: Do not remove this!! The attack to idle transition states will not work correctly if you change weapon mid-attack.
  13003. BlockAction( EIAB_DrawWeapon, 'OnCombatActionStart_Attack' );
  13004. }
  13005.  
  13006. //GetMovingAgentComponent().SnapToNavigableSpace(true);
  13007. }
  13008.  
  13009. var isInParryOrCounter : bool;
  13010. event OnParryOrCounterStart()
  13011. {
  13012. isInParryOrCounter = true;
  13013. OnCombatActionStartBehgraph();
  13014. }
  13015.  
  13016. event OnParryOrCounterEnd()
  13017. {
  13018. isInParryOrCounter = false;
  13019. OnCombatActionEnd();
  13020. SetBIsInCombatAction( false );
  13021. }
  13022.  
  13023. //called when a combat action is completed (e.g. single hit in a combo sequence)
  13024. event OnCombatActionEnd()
  13025. {
  13026. var item : SItemUniqueId;
  13027. var combatActionType : float;
  13028.  
  13029. super.OnCombatActionEnd();
  13030.  
  13031. // W3EE - Begin
  13032. //Unblock Actions
  13033. {
  13034. SetWasPlayerSpamming(true);
  13035. AddTimer('ResetPlayerSpamming', 3.5f, false, , , , true);
  13036. }
  13037. SetPlayerSpamming(false);
  13038. SetPlayerAttacking(false);
  13039. // W3EE - End
  13040.  
  13041. BlockAllActions( 'OnCombatActionStart', false );
  13042.  
  13043. UnblockAction( EIAB_DrawWeapon, 'OnCombatActionStart_Attack' );
  13044.  
  13045. // failsafe
  13046. UnblockAction( EIAB_Movement, 'CombatActionFriendly' );
  13047.  
  13048. //why? this way after EACH attack you reset it - what's the point then?
  13049. //ResetUninterruptedHitsCount();
  13050.  
  13051. oTCameraOffset = 0.f;
  13052. oTCameraPitchOffset = 0.f;
  13053.  
  13054. //LogChannel('combatActionAllowed',"TRUE OnCombatActionEnd");
  13055. SetBIsCombatActionAllowed( true );
  13056. //reapply critical buff if any
  13057. //ReapplyCriticalBuff();
  13058. SetBIsInputAllowed( true, 'OnCombatActionEnd' );
  13059. SetCanPlayHitAnim( true );
  13060. EnableFindTarget( true );
  13061.  
  13062. //AK: commented out because it sets dodging flag to false right after dodging starts when we chain multiple dodges
  13063. //IsCurrentlyDodging returned false in the middle of dodge anim
  13064. //SetIsCurrentlyDodging( false );
  13065. SetFinisherVictim( NULL );
  13066.  
  13067. OnBlockAllCombatTickets( false );
  13068.  
  13069. LogStamina("CombatActionEnd");
  13070.  
  13071. //GetMovingAgentComponent().SnapToNavigableSpace(false);
  13072.  
  13073. SetAttackActionName('');
  13074. combatActionType = GetBehaviorVariable('combatActionType');
  13075.  
  13076. //clean-up after special attack heavy finishes
  13077. if(GetBehaviorVariable('combatActionType') == (int)CAT_SpecialAttack)
  13078. {
  13079. theGame.GetGameCamera().StopAnimation( 'camera_shake_loop_lvl1_1' );
  13080. OnSpecialAttackHeavyActionProcess();
  13081. }
  13082. // Do we need to interrupt?
  13083. substateManager.ReactToChanceToFallAndSlide();
  13084. }
  13085.  
  13086. event OnCombatActionFriendlyStart()
  13087. {
  13088. SetBIsInCombatActionFriendly(true);
  13089. BlockAction( EIAB_Movement, 'CombatActionFriendly', false, false, false );
  13090. OnCombatActionStart();
  13091. }
  13092.  
  13093. event OnCombatActionFriendlyEnd()
  13094. {
  13095. SetBIsInCombatActionFriendly(false);
  13096. UnblockAction( EIAB_Movement, 'CombatActionFriendly' );
  13097. OnCombatActionEnd();
  13098. SetBIsInCombatAction(false);
  13099. //RaiseForceEvent( 'ForceIdle' );
  13100. }
  13101.  
  13102. // W3EE - Begin
  13103. private var StaggeredDuringAnim : bool; default StaggeredDuringAnim = false;
  13104. private var weapon : EPlayerWeapon;
  13105. private var IsCurrentlyStaggered : bool; default IsCurrentlyStaggered = false;
  13106. private var AnimatedState : bool; default AnimatedState = false;
  13107.  
  13108. public function GetStaggeredDuringAnim() : bool
  13109. {
  13110. return StaggeredDuringAnim;
  13111. }
  13112.  
  13113. public function SetStaggeredDuringAnim( hit : bool )
  13114. {
  13115. StaggeredDuringAnim = hit;
  13116. }
  13117.  
  13118. public function GetWep() : EPlayerWeapon
  13119. {
  13120. return weapon;
  13121. }
  13122.  
  13123. public function SetWep( weps : EPlayerWeapon )
  13124. {
  13125. weapon = weps;
  13126. }
  13127.  
  13128. public function GetIsStaggered() : bool
  13129. {
  13130. return IsCurrentlyStaggered;
  13131. }
  13132.  
  13133. public function SetIsStaggered( i : bool )
  13134. {
  13135. IsCurrentlyStaggered = i;
  13136. }
  13137.  
  13138. timer function SetNotStaggered( dt : float, id : int )
  13139. {
  13140. IsCurrentlyStaggered = false;
  13141. }
  13142.  
  13143. public function GetIsInAnimatedState() : bool
  13144. {
  13145. return AnimatedState;
  13146. }
  13147.  
  13148. public function SetAnimatedState( i : bool )
  13149. {
  13150. AnimatedState = i;
  13151.  
  13152. if( i == true )
  13153. {
  13154. BlockAction(EIAB_DrawWeapon, 'ConsumableAnims');
  13155. BlockAction(EIAB_CallHorse, 'ConsumableAnims');
  13156. BlockAction(EIAB_Signs, 'ConsumableAnims');
  13157. BlockAction(EIAB_Crossbow, 'ConsumableAnims');
  13158. BlockAction(EIAB_UsableItem, 'ConsumableAnims');
  13159. BlockAction(EIAB_ThrowBomb, 'ConsumableAnims');
  13160. BlockAction(EIAB_SwordAttack, 'ConsumableAnims');
  13161. BlockAction(EIAB_Jump, 'ConsumableAnims');
  13162. BlockAction(EIAB_Dodge, 'ConsumableAnims');
  13163. BlockAction(EIAB_Roll, 'ConsumableAnims');
  13164. BlockAction(EIAB_LightAttacks, 'ConsumableAnims');
  13165. BlockAction(EIAB_HeavyAttacks, 'ConsumableAnims');
  13166. BlockAction(EIAB_SpecialAttackLight, 'ConsumableAnims');
  13167. BlockAction(EIAB_SpecialAttackHeavy, 'ConsumableAnims');
  13168. }
  13169. else
  13170. {
  13171. UnblockAction(EIAB_DrawWeapon, 'ConsumableAnims');
  13172. UnblockAction(EIAB_CallHorse, 'ConsumableAnims');
  13173. UnblockAction(EIAB_Signs, 'ConsumableAnims');
  13174. UnblockAction(EIAB_Crossbow, 'ConsumableAnims');
  13175. UnblockAction(EIAB_UsableItem, 'ConsumableAnims');
  13176. UnblockAction(EIAB_ThrowBomb, 'ConsumableAnims');
  13177. UnblockAction(EIAB_SwordAttack, 'ConsumableAnims');
  13178. UnblockAction(EIAB_Jump, 'ConsumableAnims');
  13179. UnblockAction(EIAB_Dodge, 'ConsumableAnims');
  13180. UnblockAction(EIAB_Roll, 'ConsumableAnims');
  13181. UnblockAction(EIAB_LightAttacks, 'ConsumableAnims');
  13182. UnblockAction(EIAB_HeavyAttacks, 'ConsumableAnims');
  13183. UnblockAction(EIAB_SpecialAttackLight, 'ConsumableAnims');
  13184. UnblockAction(EIAB_SpecialAttackHeavy, 'ConsumableAnims');
  13185. }
  13186. }
  13187. // W3EE - End
  13188.  
  13189. event OnHitStart()
  13190. {
  13191. var timeLeft : float;
  13192. var currentEffects : array<CBaseGameplayEffect>;
  13193. var none : SAbilityAttributeValue;
  13194.  
  13195. CancelHoldAttacks();
  13196. WhenCombatActionIsFinished();
  13197. if ( isInFinisher )
  13198. {
  13199. if ( finisherTarget )
  13200. ( (CNewNPC)finisherTarget ).SignalGameplayEvent( 'FinisherInterrupt' );
  13201. isInFinisher = false;
  13202. finisherTarget = NULL;
  13203. SetBIsCombatActionAllowed( true );
  13204. }
  13205.  
  13206. bIsInHitAnim = true;
  13207.  
  13208. OnCombatActionStart(); //"because it's needed"
  13209.  
  13210. //OnCombatActionStart pauses the regen and we don't want that
  13211. ResumeStaminaRegen( 'InsideCombatAction' );
  13212.  
  13213. if( GetHealthPercents() < 0.3f )
  13214. {
  13215. PlayBattleCry('BattleCryBadSituation', 0.10f, true );
  13216. }
  13217. else
  13218. {
  13219. PlayBattleCry('BattleCryBadSituation', 0.05f, true );
  13220. }
  13221. }
  13222.  
  13223. event OnHitStartSwimming()
  13224. {
  13225. OnRangedForceHolster( true, true, false );
  13226. }
  13227.  
  13228. private var finisherSaveLock : int;
  13229. event OnFinisherStart()
  13230. {
  13231. var currentEffects : array<CBaseGameplayEffect>;
  13232.  
  13233. theGame.CreateNoSaveLock("Finisher",finisherSaveLock,true,false);
  13234.  
  13235. isInFinisher = true;
  13236.  
  13237. finisherTarget = slideTarget;
  13238. OnCombatActionStart();
  13239.  
  13240. CancelHoldAttacks();
  13241.  
  13242. //W3EE - Begin
  13243. // PlayFinisherCameraAnimation( theGame.GetSyncAnimManager().GetFinisherCameraAnimName() );
  13244. this.AddAnimEventCallback('SyncEvent','OnFinisherAnimEvent_SyncEvent');
  13245. Combat().ReaperFinisher();
  13246. //SetImmortalityMode( AIM_Invulnerable, AIC_SyncedAnim );
  13247. //W3EE - End
  13248. }
  13249.  
  13250. public function IsPerformingFinisher() : bool
  13251. {
  13252. return isInFinisher;
  13253. }
  13254.  
  13255. private function PlayFinisherCameraAnimation( cameraAnimName : name )
  13256. {
  13257. var camera : CCustomCamera = theGame.GetGameCamera();
  13258. var animation : SCameraAnimationDefinition;
  13259.  
  13260. if( IsLastEnemyKilled() && theGame.GetWorld().NavigationCircleTest( this.GetWorldPosition(), 3.f ) )
  13261. {
  13262. camera.StopAnimation('camera_shake_hit_lvl3_1' );
  13263.  
  13264. animation.animation = cameraAnimName;
  13265. animation.priority = CAP_Highest;
  13266. animation.blendIn = 0.15f;
  13267. animation.blendOut = 1.0f;
  13268. animation.weight = 1.f;
  13269. animation.speed = 1.0f;
  13270. animation.reset = true;
  13271.  
  13272. camera.PlayAnimation( animation );
  13273. //thePlayer.AddTimer( 'RemoveFinisherCameraAnimationCheck', 0.01, true );
  13274.  
  13275. thePlayer.EnableManualCameraControl( false, 'Finisher' );
  13276. }
  13277. }
  13278.  
  13279. public function IsLastEnemyKilled() : bool
  13280. {
  13281. var tempMoveTargets : array<CActor>;
  13282.  
  13283. FindMoveTarget();
  13284. tempMoveTargets = GetMoveTargets();
  13285. if ( tempMoveTargets.Size() <= 0 || !thePlayer.IsThreat( tempMoveTargets[0] ) )
  13286. return true;
  13287.  
  13288. return false;
  13289. }
  13290.  
  13291. event OnFinisherAnimEvent_SyncEvent( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  13292. {
  13293. if ( finisherTarget )
  13294. ( (CNewNPC)finisherTarget ).SignalGameplayEvent('FinisherKill');
  13295. finisherTarget = NULL;
  13296. }
  13297.  
  13298. event OnFinisherEnd()
  13299. {
  13300. isInFinisher = false;
  13301. finisherTarget = NULL;
  13302.  
  13303. theGame.ReleaseNoSaveLock(finisherSaveLock);
  13304.  
  13305. this.RemoveAnimEventCallback('SyncEvent');
  13306.  
  13307. //SetIsPerformingPhaseChangeAnimation( false ); // for eredin fight
  13308. SetImmortalityMode( AIM_None, AIC_SyncedAnim );
  13309. theGame.RemoveTimeScale( 'AnimEventSlomoMo' );
  13310. AddTimer( 'FinisherEndEnableCamera', 0.5f );
  13311. //OnBlockAllCombatTickets( false );
  13312. OnCombatActionEnd();
  13313. OnCombatActionEndComplete();
  13314. }
  13315.  
  13316. private timer function FinisherEndEnableCamera( dt : float, id : int )
  13317. {
  13318. thePlayer.EnableManualCameraControl( true, 'Finisher' );
  13319. }
  13320.  
  13321. public function SpawnFinisherBlood()
  13322. {
  13323. var weaponEntity : CEntity;
  13324. var weaponSlotMatrix : Matrix;
  13325. var bloodFxPos : Vector;
  13326. var bloodFxRot : EulerAngles;
  13327. var tempEntity : CEntity;
  13328.  
  13329. weaponEntity = this.GetInventory().GetItemEntityUnsafe( GetInventory().GetItemFromSlot('r_weapon') );
  13330. weaponEntity.CalcEntitySlotMatrix( 'blood_fx_point', weaponSlotMatrix );
  13331. bloodFxPos = MatrixGetTranslation( weaponSlotMatrix );
  13332. bloodFxRot = this.GetWorldRotation();//MatrixGetRotation( weaponSlotMatrix );
  13333. tempEntity = theGame.CreateEntity( (CEntityTemplate)LoadResource('finisher_blood'), bloodFxPos, bloodFxRot);
  13334. tempEntity.PlayEffect('crawl_blood');
  13335. }
  13336.  
  13337. //called when all combat actions have ended (e.g. whole combo)
  13338. event OnCombatActionEndComplete()
  13339. {
  13340. var buff : CBaseGameplayEffect;
  13341.  
  13342. buff = ChooseCurrentCriticalBuffForAnim();
  13343. SetCombatAction( EBAT_EMPTY );
  13344.  
  13345. //Unblock Actions what you wann
  13346. UnblockAction( EIAB_DrawWeapon, 'OnCombatActionStart' );
  13347. UnblockAction( EIAB_OpenInventory, 'OnCombatActionStart' );
  13348. UnblockAction( EIAB_UsableItem, 'OnCombatActionStart' );
  13349.  
  13350. UnblockAction( EIAB_DrawWeapon, 'OnCombatActionStart_Attack' );
  13351.  
  13352. SetUnpushableTarget( NULL );
  13353. SetBIsInCombatAction(false);
  13354. SetIsCurrentlyDodging(false);
  13355. SetMoveTargetChangeAllowed( true );
  13356. SetCanPlayHitAnim( true );
  13357.  
  13358. SetFinisherVictim( NULL );
  13359.  
  13360. this.RemoveBuffImmunity(EET_Burning, 'AnimEvent_RemoveBurning');
  13361.  
  13362. if ( rangedWeapon && rangedWeapon.GetCurrentStateName() == 'State_WeaponWait' && !buff )
  13363. {
  13364. ClearCustomOrientationInfoStack();
  13365. SetSlideTarget( NULL );
  13366. }
  13367.  
  13368. UnblockAction( EIAB_Crossbow, 'OnForceHolster' );
  13369.  
  13370. specialAttackCamera = false;
  13371.  
  13372. bIsRollAllowed = false;
  13373.  
  13374. if ( bLAxisReleased )
  13375. {
  13376. ResetRawPlayerHeading();
  13377. ResetCachedRawPlayerHeading();
  13378. }
  13379.  
  13380. //reapply critical buff if any
  13381. ReapplyCriticalBuff();
  13382. SetBIsInputAllowed( true, 'OnCombatActionEndComplete' );
  13383.  
  13384. //stamina regen is paused as long as we are doing some combat actions
  13385. ResumeStaminaRegen( 'InsideCombatAction' );
  13386.  
  13387. bIsInHitAnim = false;
  13388.  
  13389. SetBIsCombatActionAllowed( true );
  13390.  
  13391. m_LastWeaponTipPos = Vector(0, 0, 0, 0 );
  13392.  
  13393. //free tickets
  13394. this.AddTimer('FreeTickets',3.f,false);
  13395.  
  13396. // remove save lock
  13397. //theGame.ReleaseNoSaveLockByName( noSaveLockCombatActionName );
  13398. }
  13399.  
  13400. event OnMovementFullyBlended()
  13401. {
  13402. SetBehaviorVariable( 'isPerformingSpecialAttack', 0.f );
  13403.  
  13404. if ( restoreUsableItem )
  13405. {
  13406. restoreUsableItem = false;
  13407. SetPlayerActionToRestore ( PATR_Default );
  13408. OnUseSelectedItem();
  13409. }
  13410. }
  13411.  
  13412. event OnCombatMovementStart()
  13413. {
  13414. SetCombatIdleStance( 1.f );
  13415. OnCombatActionEndComplete();
  13416. }
  13417.  
  13418. timer function FreeTickets( dt : float, id : int )
  13419. {
  13420. FreeTicketAtCombatTarget();
  13421. }
  13422.  
  13423.  
  13424. /*
  13425. These declarations are needed here only to call event with the same name inside combat state (there's no other way to call it!).
  13426. */
  13427. event OnGuardedReleased(){}
  13428. event OnPerformAttack( playerAttackType : name ){}
  13429. event OnPerformEvade( playerEvadeType : EPlayerEvadeType ){}
  13430. event OnInterruptAttack(){}
  13431. event OnPerformGuard(){}
  13432. event OnSpawnHorse(){}
  13433. event OnDismountActionScriptCallback(){}
  13434.  
  13435. event OnHorseSummonStart()
  13436. {
  13437. thePlayer.BlockAction(EIAB_CallHorse, 'HorseSummon');
  13438. thePlayer.BlockAction(EIAB_Signs, 'HorseSummon');
  13439. thePlayer.BlockAction(EIAB_Crossbow, 'HorseSummon');
  13440. thePlayer.BlockAction(EIAB_UsableItem, 'HorseSummon');
  13441. thePlayer.BlockAction(EIAB_ThrowBomb, 'HorseSummon');
  13442. thePlayer.BlockAction(EIAB_SwordAttack, 'HorseSummon');
  13443. thePlayer.BlockAction(EIAB_Jump, 'HorseSummon');
  13444. thePlayer.BlockAction(EIAB_Dodge, 'HorseSummon');
  13445. thePlayer.BlockAction(EIAB_LightAttacks, 'HorseSummon');
  13446. thePlayer.BlockAction(EIAB_HeavyAttacks, 'HorseSummon');
  13447. thePlayer.BlockAction(EIAB_SpecialAttackLight, 'HorseSummon');
  13448. thePlayer.BlockAction(EIAB_SpecialAttackHeavy, 'HorseSummon');
  13449.  
  13450. horseSummonTimeStamp = theGame.GetEngineTimeAsSeconds();
  13451. }
  13452.  
  13453. event OnHorseSummonStop()
  13454. {
  13455. thePlayer.BlockAllActions('HorseSummon',false);
  13456. }
  13457.  
  13458. /*
  13459. CombatAction events when on vehicles
  13460. */
  13461. event OnCombatActionStartVehicle( action : EVehicleCombatAction )
  13462. {
  13463. this.SetBIsCombatActionAllowed( false );
  13464.  
  13465. if ( action != EHCA_ShootCrossbow )
  13466. {
  13467. SetIsAimingCrossbow( false );
  13468. OnRangedForceHolster();
  13469. }
  13470. }
  13471.  
  13472. event OnCombatActionEndVehicle()
  13473. {
  13474. this.SetBIsCombatActionAllowed( true );
  13475. }
  13476.  
  13477. ////////////////////////////////////////////////////////////////////////////////////////////
  13478. /////////////////////////// @CRITICAL STATES /////////////////////////////////////////////
  13479. ////////////////////////////////////////////////////////////////////////////////////////////
  13480.  
  13481. protected function CriticalBuffInformBehavior(buff : CBaseGameplayEffect)
  13482. {
  13483. /*if ( this.GetCurrentStateName() == 'Exploration' || this.GetCurrentStateName() == 'AimThrow' )
  13484. GotoCombatStateWithAction( IA_CriticalState, buff );
  13485. else
  13486. {*/
  13487. if( !CanAnimationReactToCriticalState( buff ) )
  13488. {
  13489. return;
  13490. }
  13491.  
  13492. // if ( IsInCombatAction() )
  13493. // RaiseEvent('ForceBlendOut');
  13494.  
  13495. SetBehaviorVariable( 'CriticalStateType', (int)GetBuffCriticalType(buff) );
  13496. SetBehaviorVariable( 'bCriticalState', 1);
  13497.  
  13498. if(CriticalBuffUsesFullBodyAnim(buff))
  13499. RaiseEvent('CriticalState');
  13500.  
  13501. SetBehaviorVariable( 'IsInAir', (int)IsInAir());
  13502.  
  13503. LogCritical("Sending player critical state event for <<" + buff.GetEffectType() + ">>");
  13504.  
  13505. //}
  13506. }
  13507.  
  13508. private function CanAnimationReactToCriticalState( buff : CBaseGameplayEffect ) : bool
  13509. {
  13510. var buffCritical : W3CriticalEffect;
  13511. var buffCriticalDOT : W3CriticalDOTEffect;
  13512. var isHeavyCritical : bool;
  13513.  
  13514. isHeavyCritical = false;
  13515.  
  13516. // Find out if it is a heavy critical state
  13517. buffCritical = ( W3CriticalEffect ) buff;
  13518. if( buffCritical )
  13519. {
  13520. isHeavyCritical = buffCritical.explorationStateHandling == ECH_HandleNow;
  13521. }
  13522. else
  13523. {
  13524. buffCriticalDOT = ( W3CriticalDOTEffect ) buff;
  13525. if( buffCriticalDOT )
  13526. {
  13527. isHeavyCritical = buffCriticalDOT.explorationStateHandling == ECH_HandleNow;
  13528. }
  13529. }
  13530.  
  13531. // If it is not, we may skip it
  13532. if( !isHeavyCritical )
  13533. {
  13534. if( !CanReactToCriticalState() )
  13535. {
  13536. return false;
  13537. }
  13538. }
  13539.  
  13540. return true;
  13541. }
  13542.  
  13543. public function CanReactToCriticalState() : bool
  13544. {
  13545. return substateManager.CanReactToHardCriticalState();
  13546. }
  13547.  
  13548. event OnCriticalStateAnimStart()
  13549. {
  13550. var heading : float;
  13551. var newCritical : ECriticalStateType;
  13552. var newReqCS : CBaseGameplayEffect;
  13553.  
  13554. OnCombatActionEndComplete();
  13555.  
  13556. //abort throwing if super was processed properly
  13557. newReqCS = newRequestedCS;
  13558. if(super.OnCriticalStateAnimStart())
  13559. {
  13560. //WhenCombatActionIsFinished();
  13561. RemoveTimer( 'IsItemUseInputHeld' );
  13562. keepRequestingCriticalAnimStart = false;
  13563. CancelHoldAttacks();
  13564.  
  13565. //knockdown direction
  13566. // No knockdown when using a vehicule: the vehicule will handle the knock down logic
  13567. //PFTODO
  13568. //we need this for NPCs also (knockdown dir)
  13569. if(!IsUsingVehicle())
  13570. {
  13571. newCritical = GetBuffCriticalType(newReqCS);
  13572. if(newCritical == ECST_HeavyKnockdown
  13573. || newCritical == ECST_Knockdown
  13574. || newCritical == ECST_Stagger
  13575. || newCritical == ECST_Ragdoll
  13576. || newCritical == ECST_LongStagger )
  13577. {
  13578. if(newReqCS.GetCreator())
  13579. heading = VecHeading(newReqCS.GetCreator().GetWorldPosition() - GetWorldPosition());
  13580. else
  13581. heading = GetHeading();
  13582.  
  13583. //this.GetMovingAgentComponent().GetMovementAdjustor().CancelAll();
  13584. SetCustomRotation( 'Knockdown', heading, 2160.f, 0.1f, true );
  13585.  
  13586. if ( newCritical != ECST_Stagger && newCritical != ECST_LongStagger )
  13587. substateManager.ReactOnCriticalState( true );
  13588. }
  13589. }
  13590.  
  13591. theGame.GetBehTreeReactionManager().CreateReactionEventIfPossible( this, 'CriticalEffectStart', -1, 30.0f, -1.f, -1, true ); //reactionSystemSearch
  13592. return true;
  13593. }
  13594.  
  13595. //SetBehaviorVariable( 'bCriticalStopped', 1);
  13596. return false;
  13597. }
  13598.  
  13599. /*
  13600. Called when new critical effect has started
  13601. This will interrupt current critical state
  13602.  
  13603. returns true if the effect got fired properly
  13604. */
  13605. public function StartCSAnim(buff : CBaseGameplayEffect) : bool
  13606. {
  13607. SetBehaviorVariable( 'bCriticalStopped', 0 );
  13608.  
  13609. if(super.StartCSAnim(buff))
  13610. {
  13611. if(!CriticalBuffUsesFullBodyAnim(buff))
  13612. {
  13613. OnCriticalStateAnimStart();
  13614. }
  13615.  
  13616. ResumeStaminaRegen( 'InsideCombatAction' );
  13617.  
  13618. keepRequestingCriticalAnimStart = true;
  13619. AddTimer('RequestCriticalAnimStart', 0, true);
  13620. //RequestCriticalAnimStart(0);
  13621.  
  13622. return true;
  13623. }
  13624.  
  13625. return false;
  13626. }
  13627.  
  13628. public function CriticalEffectAnimationInterrupted(reason : string) : bool
  13629. {
  13630. var ret : bool; //for debug
  13631.  
  13632. LogCriticalPlayer("R4Player.CriticalEffectAnimationInterrupted() - because: " + reason);
  13633.  
  13634. ret = super.CriticalEffectAnimationInterrupted(reason);
  13635.  
  13636. if(ret)
  13637. {
  13638. keepRequestingCriticalAnimStart = false;
  13639. }
  13640.  
  13641. substateManager.ReactOnCriticalState( false );
  13642.  
  13643. return ret;
  13644. }
  13645.  
  13646. public function CriticalStateAnimStopped(forceRemoveBuff : bool)
  13647. {
  13648. LogCriticalPlayer("R4Player.CriticalStateAnimStopped() - forced: " + forceRemoveBuff);
  13649.  
  13650. theGame.GetBehTreeReactionManager().CreateReactionEventIfPossible( this, 'RecoveredFromCriticalEffect', -1, 30.0f, -1.f, -1, true ); //reactionSystemSearch
  13651. super.CriticalStateAnimStopped(forceRemoveBuff);
  13652.  
  13653. substateManager.ReactOnCriticalState( false );
  13654. }
  13655.  
  13656. // keeps requesting (sending event) to enter critical states anim state in behavior
  13657. timer function RequestCriticalAnimStart(dt : float, id : int)
  13658. {
  13659. if(keepRequestingCriticalAnimStart)
  13660. {
  13661. if(newRequestedCS && newRequestedCS.GetDurationLeft() > 0)
  13662. {
  13663. CriticalBuffInformBehavior(newRequestedCS);
  13664. }
  13665. else
  13666. {
  13667. keepRequestingCriticalAnimStart = false;
  13668. RemoveTimer('RequestCriticalAnimStart');
  13669. }
  13670. }
  13671. else
  13672. {
  13673. RemoveTimer('RequestCriticalAnimStart');
  13674. }
  13675. }
  13676.  
  13677. event OnRagdollUpdate(progress : float)
  13678. {
  13679. //super.OnRagdollUpdate(progress);
  13680.  
  13681. SetIsInAir(progress == 0);
  13682. }
  13683.  
  13684. // getting from ragdoll after certain time has passed
  13685. event OnRagdollOnGround()
  13686. {
  13687. // try to getup immediately as currently when laying on ground we might be constantly switched between on ground and in air
  13688. TryToEndRagdollOnGround( 0.0f );
  13689. }
  13690.  
  13691. event OnRagdollInAir()
  13692. {
  13693. RemoveTimer('TryToEndRagdollOnGround');
  13694. }
  13695.  
  13696. event OnNoLongerInRagdoll()
  13697. {
  13698. RemoveTimer('TryToEndRagdollOnGround');
  13699. }
  13700.  
  13701. timer function TryToEndRagdollOnGround( td : float, optional id : int)
  13702. {
  13703. var critical : CBaseGameplayEffect;
  13704. var type : EEffectType;
  13705.  
  13706. critical = GetCurrentlyAnimatedCS();
  13707. if(critical)
  13708. {
  13709. type = critical.GetEffectType();
  13710. if(type == EET_Knockdown || type == EET_HeavyKnockdown || type == EET_Ragdoll)
  13711. {
  13712. // 2.5 seconds is not that long but this is not ragdoll simulator :)
  13713. if (critical.GetTimeActive() >= 2.5f)
  13714. {
  13715. SetIsInAir(false);
  13716. RequestCriticalAnimStop();
  13717. RemoveTimer('TryToEndRagdollOnGround');
  13718. }
  13719. else
  13720. {
  13721. AddTimer('TryToEndRagdollOnGround', 0.2f, true);
  13722. }
  13723. return;
  13724. }
  13725. }
  13726.  
  13727. // not in critical or type differs
  13728. RemoveTimer('TryToEndRagdollOnGround');
  13729. }
  13730.  
  13731. public function RequestCriticalAnimStop(optional dontSetCriticalToStopped : bool)
  13732. {
  13733. var buff : CBaseGameplayEffect;
  13734.  
  13735. buff = GetCurrentlyAnimatedCS();
  13736. if(buff && !CriticalBuffUsesFullBodyAnim(buff))
  13737. {
  13738. CriticalStateAnimStopped(false);
  13739. }
  13740.  
  13741. if(!buff || !CriticalBuffUsesFullBodyAnim(buff))
  13742. {
  13743. SetBehaviorVariable( 'bCriticalState', 0);
  13744. }
  13745.  
  13746. super.RequestCriticalAnimStop(dontSetCriticalToStopped);
  13747. }
  13748. ////////////////////////////////////////////////////////////////////////////////////////////
  13749. // @Buffs @Effects
  13750. ////////////////////////////////////////////////////////////////////////////////////////////
  13751.  
  13752. public function SimulateBuffTimePassing(simulatedTime : float)
  13753. {
  13754. effectManager.SimulateBuffTimePassing(simulatedTime);
  13755. }
  13756.  
  13757. public function AddEffectDefault(effectType : EEffectType, creat : CGameplayEntity, srcName : string, optional isSignEffect : bool) : EEffectInteract
  13758. {
  13759. var params : SCustomEffectParams;
  13760.  
  13761. /*
  13762. Welcome to the Ancient Pit. If you're here reading this then you're doomed...
  13763.  
  13764. You're probably asking why someone is overriding default effect durations with some custom arbitrary numbers...
  13765.  
  13766. The thuth is: noone remembers...
  13767.  
  13768. But we need this and you cannot remove it or shit will start falling apart.
  13769. */
  13770. if(effectType == EET_Stagger || effectType == EET_LongStagger || effectType == EET_Knockdown || effectType == EET_HeavyKnockdown)
  13771. {
  13772. params.effectType = effectType;
  13773. params.creator = creat;
  13774. params.sourceName = srcName;
  13775. params.isSignEffect = isSignEffect;
  13776.  
  13777. if ( effectType == EET_Stagger )
  13778. params.duration = 1.83;
  13779. else if ( effectType == EET_LongStagger )
  13780. params.duration = 4;
  13781. else if ( effectType == EET_Knockdown )
  13782. params.duration = 2.5;
  13783. else if ( effectType == EET_HeavyKnockdown )
  13784. params.duration = 4;
  13785.  
  13786. return super.AddEffectCustom(params);
  13787. }
  13788. else
  13789. {
  13790. return super.AddEffectDefault(effectType, creat, srcName, isSignEffect);
  13791. }
  13792. }
  13793.  
  13794.  
  13795. ////////////////////////////////////////////////////////////////////////////////////////////
  13796.  
  13797. //a cheat to ressurect player
  13798. public function CheatResurrect()
  13799. {
  13800. var items : array< SItemUniqueId >;
  13801. var i, size, itemLevel, maxPrice, itemPrice : int;
  13802. var itemToEquip : SItemUniqueId;
  13803.  
  13804. if(IsAlive())
  13805. return;
  13806.  
  13807.  
  13808. if ( !theGame.GetGuiManager().GetRootMenu() )
  13809. {
  13810. Log(" *** Call this function after DeathScreen appears *** ");
  13811. return;
  13812. }
  13813.  
  13814. SetAlive(true);
  13815.  
  13816. SetKinematic(true);
  13817.  
  13818. EnableFindTarget( true );
  13819. SetBehaviorVariable( 'Ragdoll_Weight', 0.f );
  13820. RaiseForceEvent( 'RecoverFromRagdoll' );
  13821. SetCanPlayHitAnim( true );
  13822. SetBehaviorVariable( 'CriticalStateType', (int)ECST_None );
  13823. GoToStateIfNew('Exploration');
  13824.  
  13825. ( (CDismembermentComponent)this.GetComponent( 'Dismemberment' ) ).ClearVisibleWound();
  13826.  
  13827. SetIsInAir(false); //might block getup from ragdol in knockdown
  13828.  
  13829. theInput.SetContext('Exploration');
  13830.  
  13831. ResetDeathType();
  13832.  
  13833. ForceUnlockAllInputActions(false);
  13834.  
  13835. theGame.CloseMenu('DeathScreenMenu');
  13836.  
  13837. //restore sounds
  13838. theSound.LeaveGameState(ESGS_Death);
  13839.  
  13840. //need to call stop/start functions, otherwise no auto HP regen, tox drain, etc. ever again
  13841. abilityManager.ForceSetStat(BCS_Vitality, GetStatMax(BCS_Vitality));
  13842. effectManager.StopVitalityRegen();
  13843. abilityManager.ForceSetStat( BCS_Air , 100.f );
  13844. effectManager.StopAirRegen();
  13845. abilityManager.ForceSetStat( BCS_Stamina , 100.f );
  13846. effectManager.StopStaminaRegen();
  13847. abilityManager.ForceSetStat( BCS_Toxicity , 0.f );
  13848. // W3EE - Begin
  13849. // abilityManager.ForceSetStat( BCS_Focus , 0.f );
  13850. // W3EE - End
  13851. GetWitcherPlayer().UpdateEncumbrance();
  13852.  
  13853. //equip highest level sword in inventory that can be equipped
  13854. if ( !inv.IsThereItemOnSlot( EES_SteelSword ) )
  13855. {
  13856. items = inv.GetItemsByCategory( 'steelsword' );
  13857. }
  13858. else if ( !inv.IsThereItemOnSlot( EES_SilverSword ) )
  13859. {
  13860. items = inv.GetItemsByCategory( 'silversword' );
  13861. }
  13862.  
  13863. size = items.Size();
  13864. maxPrice = -1;
  13865. for ( i = 0; i < size; i += 1 )
  13866. {
  13867. itemPrice = inv.GetItemPrice(items[i]);
  13868. itemLevel = inv.GetItemLevel(items[i]);
  13869. if ( itemLevel <= GetLevel() && itemPrice > maxPrice )
  13870. {
  13871. maxPrice = itemPrice;
  13872. itemToEquip = items[i];
  13873. }
  13874. }
  13875. if( inv.IsIdValid( itemToEquip ) )
  13876. {
  13877. EquipItem( itemToEquip , , true );
  13878. }
  13879.  
  13880. theGame.ReleaseNoSaveLock(deathNoSaveLock);
  13881. }
  13882.  
  13883. ////////////////////////////////////////////////////////////////////////////////////////////
  13884.  
  13885. public function SetIsInsideInteraction(b : bool) {isInsideInteraction = b;}
  13886. public function IsInsideInteraction() : bool {return isInsideInteraction;}
  13887.  
  13888. public function SetIsInsideHorseInteraction( b : bool, horse : CEntity )
  13889. {
  13890. isInsideHorseInteraction = b;
  13891. horseInteractionSource = horse;
  13892. }
  13893. public function IsInsideHorseInteraction() : bool {return isInsideHorseInteraction;}
  13894.  
  13895.  
  13896. event OnInteractionActivationTest( interactionComponentName : string, activator : CEntity )
  13897. {
  13898. if ( interactionComponentName == "ClimbLadder" )
  13899. {
  13900. if( PlayerHasLadderExplorationReady() )
  13901. {
  13902. return true;
  13903. }
  13904. }
  13905.  
  13906. return false;
  13907. }
  13908.  
  13909. private function PlayerHasLadderExplorationReady() : bool
  13910. {
  13911. if( !substateManager.CanInteract() )
  13912. {
  13913. return false;
  13914. }
  13915.  
  13916. if( !substateManager.m_SharedDataO.HasValidLadderExploration() )
  13917. {
  13918. return false;
  13919. }
  13920.  
  13921. return true;
  13922. }
  13923.  
  13924. ////////////////////////////////////////////////////////////////////////////////////////////
  13925. ////////////////////////////// @COMBAT /////////////////////////////////////////////////
  13926. ////////////////////////////////////////////////////////////////////////////////////////////
  13927.  
  13928. public function SetGuarded(flag : bool)
  13929. {
  13930. super.SetGuarded(flag);
  13931.  
  13932. if(flag && FactsQuerySum("tut_fight_use_slomo") > 0)
  13933. {
  13934. theGame.RemoveTimeScale( theGame.GetTimescaleSource(ETS_TutorialFight) );
  13935. FactsRemove("tut_fight_slomo_ON");
  13936. }
  13937. }
  13938.  
  13939.  
  13940. public function IsGuarded() : bool
  13941. {
  13942. return super.IsGuarded() && ( !rangedWeapon || rangedWeapon.GetCurrentStateName() == 'State_WeaponWait' );
  13943. }
  13944. ////////////////////////////////////////////////////////////////////////////////////////////
  13945. ///////////////////// @THROWABLE @BOMBS @PETARDS @Usable ///////////////////////////////////
  13946. ////////////////////////////////////////////////////////////////////////////////////////////
  13947.  
  13948. public function GetSelectedItemId() : SItemUniqueId {return selectedItemId;}
  13949. public function ClearSelectedItemId() {selectedItemId = GetInvalidUniqueId();}
  13950.  
  13951. public function IsHoldingItemInLHand() : bool
  13952. {
  13953. return currentlyEquipedItemL != GetInvalidUniqueId();
  13954. }
  13955.  
  13956. public function GetCurrentlyUsedItemL () : W3UsableItem
  13957. {
  13958. return currentlyUsedItemL;
  13959. }
  13960.  
  13961. public function SetPlayerActionToRestore ( actionToRestoreType : EPlayerActionToRestore )
  13962. {
  13963. playerActionToRestore = actionToRestoreType;
  13964. }
  13965.  
  13966. public function IsCurrentlyUsingItemL () : bool
  13967. {
  13968. return currentlyUsingItem;
  13969. }
  13970.  
  13971. function BlockSlotsOnLItemUse ()
  13972. {
  13973. var slotsToBlock : array<name>;
  13974.  
  13975. slotsToBlock.PushBack( 'Slot1' );
  13976. slotsToBlock.PushBack( 'Slot2' );
  13977. slotsToBlock.PushBack( 'Slot3' );
  13978. slotsToBlock.PushBack( 'Slot4' );
  13979. slotsToBlock.PushBack( 'Slot5' );
  13980. slotsToBlock.PushBack( 'Yrden' );
  13981. slotsToBlock.PushBack( 'Quen' );
  13982. slotsToBlock.PushBack( 'Igni' );
  13983. slotsToBlock.PushBack( 'Axii' );
  13984. slotsToBlock.PushBack( 'Aard' );
  13985.  
  13986.  
  13987. EnableRadialSlotsWithSource ( false, slotsToBlock, 'usableItemL' );
  13988. }
  13989.  
  13990. function UnblockSlotsOnLItemUse ()
  13991. {
  13992. var slotsToBlock : array<name>;
  13993.  
  13994. slotsToBlock.PushBack( 'Slot1' );
  13995. slotsToBlock.PushBack( 'Slot2' );
  13996. slotsToBlock.PushBack( 'Slot3' );
  13997. slotsToBlock.PushBack( 'Slot4' );
  13998. slotsToBlock.PushBack( 'Slot5' );
  13999. slotsToBlock.PushBack( 'Yrden' );
  14000. slotsToBlock.PushBack( 'Quen' );
  14001. slotsToBlock.PushBack( 'Igni' );
  14002. slotsToBlock.PushBack( 'Axii' );
  14003. slotsToBlock.PushBack( 'Aard' );
  14004.  
  14005.  
  14006. EnableRadialSlotsWithSource ( true, slotsToBlock, 'usableItemL' );
  14007. }
  14008.  
  14009. function IsUsableItemLBlocked () : bool
  14010. {
  14011. return isUsableItemBlocked;
  14012. }
  14013. function HideUsableItem( optional force : bool )
  14014. {
  14015. if( currentlyEquipedItemL != GetInvalidUniqueId() )
  14016. {
  14017. if( force )
  14018. {
  14019. if( !RaiseForceEvent( 'ItemEndL' ) )
  14020. {
  14021.  
  14022. OnUsingItemsReset();
  14023. }
  14024. return;
  14025.  
  14026. }
  14027. RaiseEvent( 'ItemUseL' );
  14028. }
  14029. }
  14030. function ProcessUsableItemsTransition ( actionToRestore : EPlayerActionToRestore )
  14031. {
  14032. var category : name;
  14033. var signSkill : ESkill;
  14034.  
  14035. category = inv.GetItemCategory ( selectedItemId );
  14036. signSkill = SignEnumToSkillEnum( GetEquippedSign());
  14037.  
  14038. switch ( actionToRestore )
  14039. {
  14040. case PATR_None:
  14041. if ( currentlyUsedItemL )
  14042. {
  14043. inv.UnmountItem( currentlyEquipedItemL, true );
  14044. }
  14045. currentlyEquipedItemL = GetInvalidUniqueId();
  14046. return;
  14047.  
  14048. case PATR_Default:
  14049. if ( IsSlotQuickslot( inv.GetSlotForItemId ( selectedItemId )) && category == 'usable' && currentlyEquipedItemL != selectedItemId )
  14050. {
  14051. if ( currentlyUsedItemL )
  14052. {
  14053. inv.UnmountItem( currentlyEquipedItemL, true );
  14054. }
  14055. currentlyEquipedItemL = GetInvalidUniqueId();
  14056. OnUseSelectedItem();
  14057. return;
  14058. }
  14059. break;
  14060. case PATR_Crossbow:
  14061. if ( inv.IsItemCrossbow ( selectedItemId ) )
  14062. {
  14063. if ( currentlyUsedItemL )
  14064. {
  14065. inv.UnmountItem( currentlyEquipedItemL, true );
  14066. }
  14067. currentlyEquipedItemL = GetInvalidUniqueId();
  14068. SetIsAimingCrossbow( true );
  14069.  
  14070. if ( theInput.IsActionPressed( 'ThrowItem' ) )
  14071. SetupCombatAction( EBAT_ItemUse, BS_Pressed );
  14072. else
  14073. {
  14074. SetupCombatAction( EBAT_ItemUse, BS_Pressed );
  14075. SetupCombatAction( EBAT_ItemUse, BS_Released );
  14076. }
  14077. return;
  14078. }
  14079. break;
  14080. case PATR_CastSign:
  14081. if( signSkill != S_SUndefined && playerActionToRestore == PATR_CastSign )
  14082. {
  14083. if ( currentlyUsedItemL )
  14084. {
  14085. inv.UnmountItem( currentlyEquipedItemL, true );
  14086. }
  14087. currentlyEquipedItemL = GetInvalidUniqueId();
  14088.  
  14089. if( HasStaminaToUseSkill( signSkill, false ) )
  14090. {
  14091. if( GetInvalidUniqueId() != inv.GetItemFromSlot( 'l_weapon' ) )
  14092. PushCombatActionOnBuffer( EBAT_CastSign, BS_Pressed );
  14093. else
  14094. SetupCombatAction( EBAT_CastSign, BS_Pressed );
  14095. }
  14096. else
  14097. {
  14098. // W3EE - Begin
  14099. thePlayer.SoundEvent("gui_no_adrenaline");
  14100. // W3EE - End
  14101. }
  14102. return;
  14103. }
  14104. break;
  14105. case PATR_ThrowBomb:
  14106. if ( inv.IsItemBomb ( selectedItemId ) )
  14107. {
  14108. if ( currentlyUsedItemL )
  14109. {
  14110. inv.UnmountItem( currentlyEquipedItemL, true );
  14111. }
  14112. currentlyEquipedItemL = GetInvalidUniqueId();
  14113. PrepareToAttack();
  14114. SetupCombatAction( EBAT_ItemUse, BS_Pressed );
  14115. return;
  14116. }
  14117. break;
  14118. case PATR_CallHorse:
  14119. theGame.OnSpawnPlayerHorse();
  14120. break;
  14121. default:
  14122. if ( currentlyUsedItemL )
  14123. {
  14124. inv.UnmountItem( currentlyEquipedItemL, true );
  14125. }
  14126. currentlyEquipedItemL = GetInvalidUniqueId();
  14127. return;
  14128. }
  14129. if ( currentlyUsedItemL )
  14130. {
  14131. inv.UnmountItem( currentlyEquipedItemL, true );
  14132. }
  14133. currentlyEquipedItemL = GetInvalidUniqueId();
  14134. }
  14135.  
  14136. function GetUsableItemLtransitionAllowed () : bool
  14137. {
  14138. return isUsableItemLtransitionAllowed;
  14139. }
  14140.  
  14141. function SetUsableItemLtransitionAllowed ( isAllowed : bool)
  14142. {
  14143. isUsableItemLtransitionAllowed = isAllowed;
  14144. }
  14145.  
  14146. event OnItemUseLUnBlocked ()
  14147. {
  14148. if ( isUsableItemBlocked )
  14149. {
  14150. isUsableItemBlocked = false;
  14151. UnblockSlotsOnLItemUse ();
  14152. }
  14153. }
  14154.  
  14155. event OnItemUseLBlocked ()
  14156. {
  14157. if ( !isUsableItemBlocked )
  14158. {
  14159. isUsableItemBlocked = true;
  14160. BlockSlotsOnLItemUse ();
  14161. }
  14162. }
  14163.  
  14164. event OnUsingItemsReset()
  14165. {
  14166. if ( currentlyUsingItem )
  14167. {
  14168. OnItemUseLUnBlocked ();
  14169. OnUsingItemsComplete();
  14170. }
  14171. }
  14172. event OnUsingItemsComplete ()
  14173. {
  14174. if ( isUsableItemBlocked )
  14175. {
  14176. OnItemUseLUnBlocked ();
  14177. }
  14178. currentlyUsingItem = false;
  14179. if ( GetUsableItemLtransitionAllowed () )
  14180. {
  14181. ProcessUsableItemsTransition( playerActionToRestore );
  14182. }
  14183. else
  14184. {
  14185. if ( currentlyUsedItemL )
  14186. {
  14187. inv.UnmountItem( currentlyEquipedItemL, true );
  14188. }
  14189. currentlyEquipedItemL = GetInvalidUniqueId();
  14190. }
  14191.  
  14192. SetPlayerActionToRestore ( PATR_Default );
  14193. }
  14194.  
  14195. event OnUseSelectedItem( optional force : bool )
  14196. {
  14197. var category : name;
  14198. var itemEntity : W3UsableItem;
  14199.  
  14200. if ( isUsableItemBlocked && !force )
  14201. {
  14202. return false;
  14203. }
  14204. if ( IsCastingSign() )
  14205. return false;
  14206.  
  14207. if ( currentlyEquipedItemL != GetInvalidUniqueId() )
  14208. {
  14209. SetBehaviorVariable( 'SelectedItemL', (int)GetUsableItemTypeById( currentlyEquipedItemL ), true );
  14210. if ( force )
  14211. {
  14212. if ( RaiseEvent( 'ItemEndL' ) )
  14213. {
  14214. SetUsableItemLtransitionAllowed ( true );
  14215. return true;
  14216. }
  14217. }
  14218. else
  14219. {
  14220. if ( RaiseEvent( 'ItemUseL' ) )
  14221. {
  14222. SetUsableItemLtransitionAllowed ( true );
  14223. return true;
  14224. }
  14225. }
  14226. }
  14227. else
  14228. {
  14229. category = inv.GetItemCategory( selectedItemId );
  14230. if( category != 'usable' )
  14231. {
  14232. return false;
  14233. }
  14234. SetBehaviorVariable( 'SelectedItemL', (int)GetUsableItemTypeById( selectedItemId ), true );
  14235. if( RaiseEvent( 'ItemUseL' ) )
  14236. {
  14237. currentlyEquipedItemL = selectedItemId;
  14238. SetUsableItemLtransitionAllowed ( false );
  14239. currentlyUsingItem = true;
  14240.  
  14241. return true;
  14242. }
  14243. inv.UnmountItem( selectedItemId, true );
  14244. }
  14245. }
  14246.  
  14247. protected saved var currentlyUsingItem : bool;
  14248.  
  14249. public function ProcessUseSelectedItem( itemEntity : W3UsableItem, optional shouldCallOnUsed : bool )
  14250. {
  14251. currentlyUsedItemL = itemEntity;
  14252. DrainStamina(ESAT_UsableItem);
  14253.  
  14254. if ( shouldCallOnUsed )
  14255. {
  14256. currentlyUsedItemL.OnUsed( thePlayer );
  14257. }
  14258. }
  14259.  
  14260. function GetUsableItemTypeById ( itemId : SItemUniqueId ) : EUsableItemType
  14261. {
  14262. var itemName : name;
  14263.  
  14264. itemName = inv.GetItemName ( itemId );
  14265.  
  14266. return theGame.GetDefinitionsManager().GetUsableItemType ( itemName );
  14267.  
  14268. }
  14269.  
  14270. // Starts the 'WaitForItemSpawnAndProccesTask' task
  14271. public function StartWaitForItemSpawnAndProccesTask()
  14272. {
  14273. AddTimer( 'WaitForItemSpawnAndProccesTask', 0.001f, true,,,,true );
  14274. }
  14275.  
  14276. // Kills the 'WaitForItemSpawnAndProccesTask' task
  14277. public function KillWaitForItemSpawnAndProccesTask()
  14278. {
  14279. RemoveTimer ( 'WaitForItemSpawnAndProccesTask' );
  14280. }
  14281.  
  14282. // Informs the 'WaitForItemSpawnAndProccesTask' task, that selected item should be used ASAP.
  14283. // Flag will be reset by the task itself
  14284. public function AllowUseSelectedItem()
  14285. {
  14286. m_useSelectedItemIfSpawned = true;
  14287. }
  14288.  
  14289. // Task waits for inventory to created selected item. Item will be used ASAP as the task is allowed to do so.
  14290. // Right after that - it kills itself.
  14291. timer function WaitForItemSpawnAndProccesTask( timeDelta : float , id : int )
  14292. {
  14293. var itemEntity : W3UsableItem;
  14294. var canTaskBeKilled : bool;
  14295. canTaskBeKilled = false;
  14296.  
  14297. if ( IsCastingSign() )
  14298. {
  14299. return;
  14300. }
  14301.  
  14302. // selectad item is wrong!
  14303. if ( selectedItemId == GetInvalidUniqueId() )
  14304. {
  14305. canTaskBeKilled = true;
  14306. }
  14307.  
  14308. itemEntity = (W3UsableItem)inv.GetItemEntityUnsafe( selectedItemId );
  14309. if ( itemEntity && m_useSelectedItemIfSpawned )
  14310. {
  14311. // we have selected item and we are allowed to use it, so to it and kill itself.
  14312. canTaskBeKilled = true;
  14313. m_useSelectedItemIfSpawned = false; // reset flag
  14314. ProcessUseSelectedItem( itemEntity, true );
  14315. }
  14316.  
  14317. if ( canTaskBeKilled )
  14318. {
  14319. KillWaitForItemSpawnAndProccesTask();
  14320. }
  14321. }
  14322.  
  14323. event OnBombProjectileReleased()
  14324. {
  14325. ResetRawPlayerHeading();
  14326. UnblockAction(EIAB_ThrowBomb, 'BombThrow');
  14327. UnblockAction(EIAB_Crossbow, 'BombThrow');
  14328.  
  14329. if(GetCurrentStateName() == 'AimThrow')
  14330. PopState();
  14331.  
  14332. FactsAdd("ach_bomb", 1, 4 );
  14333. theGame.GetGamerProfile().CheckLearningTheRopes();
  14334. }
  14335.  
  14336. public function SetIsThrowingItemWithAim(b : bool)
  14337. {
  14338. isThrowingItemWithAim = b;
  14339. }
  14340.  
  14341. public function SetIsThrowingItem( flag : bool ) {isThrowingItem = flag;}
  14342. public function IsThrowingItem() : bool {return isThrowingItem;}
  14343. public function IsThrowingItemWithAim() : bool {return isThrowingItemWithAim;}
  14344. public function SetThrowHold(b : bool) {isThrowHoldPressed = b;}
  14345. public function IsThrowHold() : bool {return isThrowHoldPressed;}
  14346. public function SetIsAimingCrossbow( flag : bool ) {isAimingCrossbow = flag;}
  14347. public function GetIsAimingCrossbow() : bool {return isAimingCrossbow;}
  14348.  
  14349. event OnThrowAnimLeave()
  14350. {
  14351. var throwStage : EThrowStage;
  14352. var thrownEntity : CThrowable;
  14353.  
  14354. thrownEntity = (CThrowable)EntityHandleGet( thrownEntityHandle );
  14355.  
  14356. if(thrownEntity && !thrownEntity.WasThrown())
  14357. {
  14358. throwStage = (int)GetBehaviorVariable( 'throwStage', (int)TS_Stop);
  14359. if(inv.IsItemBomb(selectedItemId))
  14360. {
  14361. BombThrowCleanUp();
  14362. }
  14363. else
  14364. {
  14365. ThrowingAbort();
  14366. }
  14367. }
  14368.  
  14369. thrownEntity = NULL;
  14370. SetIsThrowingItem( false );
  14371. SetIsThrowingItemWithAim( false );
  14372.  
  14373. this.EnableRadialSlotsWithSource( true, this.radialSlots, 'throwBomb' );
  14374. UnblockAction(EIAB_ThrowBomb, 'BombThrow');
  14375. UnblockAction(EIAB_Crossbow, 'BombThrow');
  14376. }
  14377.  
  14378. //Called when bomb throwing has started - it is ensured that we CAN throw it. At this point we don't know yet if it's a quick throw or aimed throw
  14379. protected function BombThrowStart()
  14380. {
  14381. var slideTargetActor : CActor;
  14382.  
  14383. BlockAction( EIAB_ThrowBomb, 'BombThrow' );
  14384. BlockAction(EIAB_Crossbow, 'BombThrow');
  14385.  
  14386. SetBehaviorVariable( 'throwStage', (int)TS_Start );
  14387. SetBehaviorVariable( 'combatActionType', (int)CAT_ItemThrow );
  14388.  
  14389. if ( slideTarget )
  14390. {
  14391. AddCustomOrientationTarget( OT_Actor, 'BombThrow' );
  14392.  
  14393. slideTargetActor = (CActor)( slideTarget );
  14394.  
  14395. //AK BOMB: moved rotation from anim event to scripts to prevent rotation to friendly and neutral npcs.
  14396. // removed the check after commenting out ProcessCanAttackWhenNotInCombatBomb
  14397. //if( !slideTargetActor || ( slideTargetActor && GetAttitudeBetween(this, slideTarget) == AIA_Hostile ) )
  14398. // SetCustomRotation( 'Throw', VecHeading( slideTarget.GetWorldPosition() - GetWorldPosition() ), 0.0f, 0.3f, false );
  14399. }
  14400. else
  14401. {
  14402. if ( lastAxisInputIsMovement )
  14403. AddCustomOrientationTarget( OT_Actor, 'BombThrow' );
  14404. else
  14405. AddCustomOrientationTarget( OT_Camera, 'BombThrow' );
  14406. }
  14407.  
  14408. UpdateLookAtTarget();
  14409. SetCustomRotation( 'Throw', VecHeading( this.GetLookAtPosition() - GetWorldPosition() ), 0.0f, 0.3f, false );
  14410.  
  14411. SetBehaviorVariable( 'itemType', (int)IT_Petard );
  14412.  
  14413. ProcessCanAttackWhenNotInCombatBomb();
  14414.  
  14415. if ( RaiseForceEvent('CombatAction') )
  14416. OnCombatActionStart();
  14417.  
  14418. //FIXME might be aborted afterwards and no bomb would be thrown actually
  14419. theTelemetry.LogWithLabel(TE_FIGHT_HERO_THROWS_BOMB, inv.GetItemName( selectedItemId ));
  14420. }
  14421.  
  14422. //from animation
  14423. event OnThrowAnimStart()
  14424. {
  14425. var itemId : SItemUniqueId;
  14426. var thrownEntity : CThrowable;
  14427. //Disable slots on radial menu
  14428. this.radialSlots.Clear();
  14429. GetWitcherPlayer().GetItemEquippedOnSlot(EES_Petard1, itemId );
  14430.  
  14431. if( GetSelectedItemId() == itemId )
  14432. {
  14433. this.radialSlots.PushBack( 'Slot2' );
  14434. }
  14435. else
  14436. {
  14437. this.radialSlots.PushBack( 'Slot1' );
  14438. }
  14439. this.radialSlots.PushBack( 'Slot3' );
  14440. this.radialSlots.PushBack( 'Slot4' );
  14441. this.radialSlots.PushBack( 'Slot5' );
  14442. this.EnableRadialSlotsWithSource( false, this.radialSlots, 'throwBomb' );
  14443.  
  14444. thrownEntity = (CThrowable)inv.GetDeploymentItemEntity( selectedItemId,,,true );
  14445. thrownEntity.Initialize( this, selectedItemId );
  14446. EntityHandleSet( thrownEntityHandle, thrownEntity );
  14447. SetIsThrowingItem( true );
  14448. }
  14449.  
  14450. public function BombThrowAbort()
  14451. {
  14452. BombThrowCleanUp();
  14453. UnblockAction( EIAB_ThrowBomb, 'BombThrow' );
  14454. UnblockAction(EIAB_Crossbow, 'BombThrow');
  14455. }
  14456.  
  14457. private function BombThrowCleanUp()
  14458. {
  14459. var throwStage : EThrowStage;
  14460. var thrownEntity : CThrowable;
  14461. var vehicle : CVehicleComponent;
  14462.  
  14463. thrownEntity = (CThrowable)EntityHandleGet( thrownEntityHandle );
  14464.  
  14465. this.EnableRadialSlotsWithSource( true, this.radialSlots, 'throwBomb' );
  14466. throwStage = (int)GetBehaviorVariable( 'throwStage', (int)TS_Stop);
  14467.  
  14468. SetBehaviorVariable( 'throwStage', (int)TS_Stop );
  14469.  
  14470. if( GetCurrentStateName() == 'AimThrow')
  14471. {
  14472. PopState();
  14473. thrownEntity.StopAiming( true );
  14474. }
  14475. else if ( this.IsUsingHorse() )
  14476. {
  14477. vehicle = (CVehicleComponent)(GetUsedVehicle().GetComponentByClassName('CVehicleComponent'));
  14478. vehicle.GetUserCombatManager().OnForceItemActionAbort();
  14479. }
  14480.  
  14481. //if bomb was not detached yet (is not flying)
  14482. if(thrownEntity && !thrownEntity.WasThrown())
  14483. {
  14484. thrownEntity.BreakAttachment();
  14485. thrownEntity.Destroy();
  14486. }
  14487.  
  14488. thrownEntity = NULL;
  14489. SetIsThrowingItem( false );
  14490. SetIsThrowingItemWithAim( false );
  14491. RemoveCustomOrientationTarget( 'BombThrow' );
  14492. }
  14493.  
  14494. public function ProcessCanAttackWhenNotInCombatBomb()
  14495. {
  14496. var targets : array< CGameplayEntity >;
  14497. var temp, throwVector, throwFrom, throwTo, throwVectorU : Vector;
  14498. var temp_n : name;
  14499. var throwVecLen : float;
  14500. var component : CComponent;
  14501. /* //AK BOMB: keeping it just in case we need to bring it back
  14502. var impactRange : float;
  14503. var entities : array<CGameplayEntity>;
  14504. var ent : CEntity;
  14505. var actor : CActor;
  14506. var petard : W3Petard;
  14507. var vehicle : CEntity;
  14508. var slotMatrix : Matrix;
  14509. var isShootingFriendly : bool;
  14510.  
  14511.  
  14512. if ( thrownEntity )
  14513. {
  14514. petard = (W3Petard)( thrownEntity );
  14515.  
  14516. if ( !IsThreatened() )
  14517. {
  14518. if ( this.playerAiming.GetCurrentStateName() == 'Aiming' )
  14519. ent = playerAiming.GetSweptFriendly();
  14520. else
  14521. actor = (CActor)GetDisplayTarget();
  14522.  
  14523. if( ent || ( actor && actor.IsHuman() && !IsThreat( actor ) ) )
  14524. SetIsShootingFriendly( true );
  14525. else
  14526. SetIsShootingFriendly( false );
  14527. }
  14528. else
  14529. SetIsShootingFriendly( false );
  14530. }
  14531. else
  14532. SetIsShootingFriendly( false );
  14533. */
  14534.  
  14535. //Quest can lock bomb throwing to allow bombs to throw only at specific targets
  14536. if( FactsQuerySum( "BombThrowSpecificTargets" ) > 0 )
  14537. {
  14538. //more optimal but less accurate version
  14539. //FindGameplayEntitiesCloseToPoint( targets, playerAiming.GetThrowPosition(), 2.f, 20, 'BombThrowSpecificTarget' );
  14540. //SetIsShootingFriendly( targets.Size() == 0 );
  14541.  
  14542. //fun fact - without breaking all calculations into separate variables this code doesn't work...
  14543. throwFrom = playerAiming.GetThrowStartPosition();
  14544. throwTo = playerAiming.GetThrowPosition();
  14545. throwVector = throwTo - throwFrom;
  14546. throwVecLen = VecDistance( throwFrom, throwTo );
  14547. throwVectorU = throwVector / throwVecLen;
  14548. if( theGame.GetWorld().StaticTraceWithAdditionalInfo( throwFrom, throwTo + throwVectorU, temp, temp, temp_n, component ) && component && component.GetEntity().HasTag( 'BombThrowSpecificTarget' ) )
  14549. {
  14550. SetIsShootingFriendly( false );
  14551. }
  14552. else
  14553. {
  14554. SetIsShootingFriendly( true );
  14555. }
  14556. }
  14557. else if( FactsQuerySum( "BombThrowDisallowSpecificTargets" ) > 0 )
  14558. {
  14559. //fun fact - without breaking all calculations into separate variables this code doesn't work...
  14560. throwFrom = playerAiming.GetThrowStartPosition();
  14561. throwTo = playerAiming.GetThrowPosition();
  14562. throwVector = throwTo - throwFrom;
  14563. throwVecLen = VecDistance( throwFrom, throwTo );
  14564. throwVectorU = throwVector / throwVecLen;
  14565. if( theGame.GetWorld().StaticTraceWithAdditionalInfo( throwFrom, throwTo + throwVectorU, temp, temp, temp_n, component ) && component && component.GetEntity().HasTag( 'BombThrowDisallowedTarget' ) )
  14566. {
  14567. SetIsShootingFriendly( true );
  14568. }
  14569. else
  14570. {
  14571. SetIsShootingFriendly( false );
  14572. }
  14573. }
  14574. else
  14575. {
  14576. SetIsShootingFriendly( false );
  14577. }
  14578.  
  14579. SetBehaviorVariable( 'isShootingFriendly', (float)( GetIsShootingFriendly() ) );
  14580. }
  14581.  
  14582. public function SetIsShootingFriendly( flag : bool )
  14583. {
  14584. isShootingFriendly = flag;
  14585. }
  14586.  
  14587. public function GetIsShootingFriendly() : bool
  14588. {
  14589. return isShootingFriendly;
  14590. }
  14591.  
  14592. //only for usable items
  14593. protected function UsableItemStart()
  14594. {
  14595. var thrownEntity : CThrowable;
  14596.  
  14597. //this seems like bullshit but it's because usable items use the same code as throwing bombs and shooting crossbow
  14598. thrownEntity = (CThrowable)inv.GetDeploymentItemEntity( selectedItemId,,,true );
  14599. thrownEntity.Initialize( this, selectedItemId );
  14600. EntityHandleSet( thrownEntityHandle, thrownEntity );
  14601. SetBehaviorVariable( 'throwStage', (int)TS_Start );
  14602. SetIsThrowingItem( true );
  14603. SetBehaviorVariable( 'combatActionType', (int)CAT_ItemThrow );
  14604.  
  14605. if ( slideTarget )
  14606. {
  14607. AddCustomOrientationTarget( OT_Actor, 'UsableItems' );
  14608. }
  14609. else
  14610. {
  14611. if ( lastAxisInputIsMovement )
  14612. AddCustomOrientationTarget( OT_Actor, 'UsableItems' );
  14613. else
  14614. AddCustomOrientationTarget( OT_Camera, 'UsableItems' );
  14615. }
  14616.  
  14617. SetBehaviorVariable( 'itemType', (int)(-1) );
  14618.  
  14619. if ( RaiseForceEvent('CombatAction') )
  14620. OnCombatActionStart();
  14621. }
  14622.  
  14623. protected function BombThrowRelease()
  14624. {
  14625. var stateName : name;
  14626.  
  14627. stateName = playerAiming.GetCurrentStateName();
  14628. OnDelayOrientationChangeOff();
  14629.  
  14630. if( GetIsShootingFriendly() || ( FactsQuerySum( "BombThrowSpecificTargets" ) > 0 && stateName != 'Aiming' ) )
  14631. {
  14632. BombThrowAbort();
  14633. }
  14634. else
  14635. {
  14636. SetBehaviorVariable( 'throwStage', (int)TS_End );
  14637.  
  14638. if ( stateName == 'Aiming' )
  14639. {
  14640. SetCustomRotation( 'Throw', VecHeading( this.GetLookAtPosition() - GetWorldPosition() ), 0.0f, 0.2f, false );
  14641. }
  14642. }
  14643. }
  14644.  
  14645. protected function UsableItemRelease()
  14646. {
  14647. OnDelayOrientationChangeOff();
  14648. SetBehaviorVariable( 'throwStage', (int)TS_End );
  14649. RemoveCustomOrientationTarget( 'UsableItems' );
  14650. }
  14651.  
  14652. // Called when usable item use or crossbow shot was aborted (bombs use different function)
  14653. public function ThrowingAbort()
  14654. {
  14655. var thrownEntity : CThrowable;
  14656.  
  14657. thrownEntity = (CThrowable)EntityHandleGet( thrownEntityHandle );
  14658.  
  14659. SetBehaviorVariable( 'throwStage', (int)TS_Stop );
  14660. RaiseEvent( 'actionStop' );
  14661.  
  14662. if( GetCurrentStateName() == 'AimThrow')
  14663. {
  14664. PopState();
  14665. thrownEntity.StopAiming( true );
  14666. }
  14667.  
  14668. //if bomb was not detached yet (is not flying)
  14669. if(thrownEntity && !thrownEntity.WasThrown())
  14670. {
  14671. thrownEntity.BreakAttachment();
  14672. thrownEntity.Destroy();
  14673. }
  14674. this.EnableRadialSlotsWithSource( true, this.radialSlots, 'throwBomb' );
  14675. }
  14676.  
  14677. public function CanSetupCombatAction_Throw() : bool
  14678. {
  14679. //if has item selected
  14680. if(!inv.IsIdValid( selectedItemId ))
  14681. return false;
  14682.  
  14683. //if not a throwable item
  14684. if(!inv.IsItemSingletonItem(selectedItemId))
  14685. return false;
  14686.  
  14687. //if input is not blocked
  14688. if(!GetBIsInputAllowed())
  14689. return false;
  14690.  
  14691. //if has ammo
  14692. if(inv.GetItemQuantity(GetSelectedItemId()) <= 0 && !inv.ItemHasTag(selectedItemId, theGame.params.TAG_INFINITE_AMMO))
  14693. return false;
  14694.  
  14695. //if action is not blocked or (HACK) we're in swimming
  14696. if(!inputHandler.IsActionAllowed(EIAB_ThrowBomb) && GetCurrentStateName() != 'Swimming')
  14697. return false;
  14698.  
  14699. return true;
  14700. }
  14701.  
  14702. public function GetThrownEntity() : CThrowable
  14703. {
  14704. return (CThrowable)EntityHandleGet( thrownEntityHandle );
  14705. }
  14706.  
  14707. // Crossbow events and functions
  14708. event OnWeaponWait() { rangedWeapon.OnWeaponWait(); }
  14709. event OnWeaponDrawStart() { rangedWeapon.OnWeaponDrawStart(); }
  14710. event OnWeaponReloadStart() { rangedWeapon.OnWeaponReloadStart(); }
  14711. event OnWeaponReloadEnd() { rangedWeapon.OnWeaponReloadEnd(); }
  14712. event OnWeaponAimStart() { rangedWeapon.OnWeaponAimStart(); }
  14713. event OnWeaponShootStart() { rangedWeapon.OnWeaponShootStart(); }
  14714. event OnWeaponShootEnd() { rangedWeapon.OnWeaponShootEnd(); }
  14715. event OnWeaponAimEnd() { rangedWeapon.OnWeaponAimEnd(); }
  14716. event OnWeaponHolsterStart() { rangedWeapon.OnWeaponHolsterStart(); }
  14717. event OnWeaponHolsterEnd() { rangedWeapon.OnWeaponHolsterEnd(); }
  14718. event OnWeaponToNormalTransStart() { rangedWeapon.OnWeaponToNormalTransStart(); }
  14719. event OnWeaponToNormalTransEnd() { rangedWeapon.OnWeaponToNormalTransEnd(); }
  14720.  
  14721. event OnEnableAimingMode( enable : bool )
  14722. {
  14723. if( !crossbowDontPopStateHack )
  14724. {
  14725. if ( enable )
  14726. PushState( 'AimThrow' );
  14727. else if ( GetCurrentStateName() == 'AimThrow' )
  14728. PopState();
  14729. }
  14730. }
  14731.  
  14732. event OnRangedForceHolster( optional forceUpperBodyAnim, instant, dropItem : bool )
  14733. {
  14734. if(rangedWeapon)
  14735. rangedWeapon.OnForceHolster( forceUpperBodyAnim, instant, dropItem );
  14736. }
  14737.  
  14738.  
  14739. public function IsCrossbowHeld() : bool
  14740. {
  14741. if (rangedWeapon)
  14742. return rangedWeapon.GetCurrentStateName() != 'State_WeaponWait';
  14743. return false;
  14744. }
  14745.  
  14746. // Tickets
  14747. event OnBlockAllCombatTickets( release : bool )
  14748. {
  14749. if (!release )
  14750. ((CR4PlayerStateCombat)GetState('Combat')).OnBlockAllCombatTickets(false);
  14751. }
  14752. event OnForceTicketUpdate() {}
  14753.  
  14754. ////////////////////////////////////////////////////////////////////////////////////////////
  14755. /////////////////////////// @ATTACKS /////////////////////////////////////////////
  14756. ////////////////////////////////////////////////////////////////////////////////////////////
  14757.  
  14758. /*script*/ event OnProcessActionPost(action : W3DamageAction)
  14759. {
  14760. var npc : CNewNPC;
  14761. var attackAction : W3Action_Attack;
  14762. var lifeLeech : float;
  14763.  
  14764. super.OnProcessActionPost(action);
  14765.  
  14766. attackAction = (W3Action_Attack)action;
  14767.  
  14768. if(attackAction)
  14769. {
  14770. npc = (CNewNPC)action.victim;
  14771.  
  14772. if(npc && npc.IsHuman() )
  14773. {
  14774. PlayBattleCry('BattleCryHumansHit', 0.05f );
  14775. }
  14776. else
  14777. {
  14778. PlayBattleCry('BattleCryMonstersHit', 0.05f );
  14779. }
  14780.  
  14781. if(attackAction.IsActionMelee())
  14782. {
  14783. //uninterrupted hits counting
  14784. IncreaseUninterruptedHitsCount();
  14785.  
  14786. //camera shake
  14787. if( IsLightAttack( attackAction.GetAttackName() ) )
  14788. {
  14789. GCameraShake(0.1, false, GetWorldPosition(), 10);
  14790. }
  14791.  
  14792. //Caretaker Shovel life steal
  14793. if(npc && inv.GetItemName(attackAction.GetWeaponId()) == 'PC Caretaker Shovel')
  14794. {
  14795. //inv.PlayItemEffect( items[i], 'stab_attack' );
  14796. lifeLeech = CalculateAttributeValue(inv.GetItemAttributeValue(attackAction.GetWeaponId() ,'lifesteal'));
  14797. if (npc.UsesVitality())
  14798. lifeLeech *= action.processedDmg.vitalityDamage;
  14799. else if (UsesEssence())
  14800. lifeLeech *= action.processedDmg.essenceDamage;
  14801. else
  14802. lifeLeech = 0;
  14803.  
  14804. if ( lifeLeech > 0 )
  14805. {
  14806. inv.PlayItemEffect( attackAction.GetWeaponId(), 'stab_attack' );
  14807. PlayEffect('drain_energy_caretaker_shovel');
  14808. GainStat(BCS_Vitality, lifeLeech);
  14809. }
  14810. }
  14811. }
  14812. }
  14813. }
  14814.  
  14815. public function SetHitReactTransScale(f : float) {hitReactTransScale = f;}
  14816. public function GetHitReactTransScale() : float
  14817. {
  14818. if ( ( (CNewNPC)slideTarget ).GetIsTranslationScaled() )
  14819. return hitReactTransScale;
  14820. else
  14821. return 1.f;
  14822. }
  14823.  
  14824. ////////////////////////////////////////////////////////////////////////////////////////////
  14825. /////////////////////////// @HORSE /////////////////////////////////////////////
  14826. ////////////////////////////////////////////////////////////////////////////////////////////
  14827.  
  14828. public function GetHorseWithInventory() : CNewNPC
  14829. {
  14830. return (CNewNPC)EntityHandleGet( horseWithInventory );
  14831. }
  14832. public function GetHorseCurrentlyMounted() : CNewNPC
  14833. {
  14834. return currentlyMountedHorse;
  14835. }
  14836. // Do not use outside of vehicle component
  14837. public function _SetHorseCurrentlyMounted( horse : CNewNPC )
  14838. {
  14839. currentlyMountedHorse = horse;
  14840. }
  14841.  
  14842. public function WasHorseRecentlySummoned() : bool
  14843. {
  14844. if ( horseSummonTimeStamp + 5.f > theGame.GetEngineTimeAsSeconds() )
  14845. return true;
  14846.  
  14847. return false;
  14848. }
  14849.  
  14850. private const var MOUNT_DISTANCE_CBT : float;
  14851. default MOUNT_DISTANCE_CBT = 3.0;
  14852.  
  14853. private const var MOUNT_ANGLE_CBT : float;
  14854. default MOUNT_ANGLE_CBT = 35.0;
  14855.  
  14856. private const var MOUNT_ANGLE_EXP : float;
  14857. default MOUNT_ANGLE_EXP = 45.0;
  14858.  
  14859. public function IsMountingHorseAllowed( optional alwaysAllowedInExploration : bool ) : bool
  14860. {
  14861. var angle : float;
  14862. var distance : float;
  14863.  
  14864. if( IsInsideHorseInteraction() )
  14865. {
  14866. angle = AngleDistance( thePlayer.rawPlayerHeading, VecHeading( thePlayer.horseInteractionSource.GetWorldPosition() - thePlayer.GetWorldPosition() ) );
  14867.  
  14868. if( thePlayer.IsInCombat() )
  14869. {
  14870. if( AbsF( angle ) < MOUNT_ANGLE_CBT )
  14871. {
  14872. distance = VecDistance( thePlayer.GetWorldPosition(), thePlayer.horseInteractionSource.GetWorldPosition() );
  14873.  
  14874. if( distance < MOUNT_DISTANCE_CBT )
  14875. {
  14876. return true;
  14877. }
  14878. else
  14879. {
  14880. return false;
  14881. }
  14882. }
  14883. else
  14884. {
  14885. return false;
  14886. }
  14887.  
  14888. }
  14889. else
  14890. {
  14891. if( alwaysAllowedInExploration )
  14892. {
  14893. return true;
  14894. }
  14895. else
  14896. {
  14897. if( AbsF( angle ) < MOUNT_ANGLE_EXP )
  14898. {
  14899. return true;
  14900. }
  14901. else
  14902. {
  14903. return false;
  14904. }
  14905. }
  14906. }
  14907. }
  14908. else
  14909. {
  14910. return false;
  14911. }
  14912. }
  14913.  
  14914. public function FollowActor( actor : CActor )
  14915. {
  14916. var l_aiTreeDecorator : CAIPlayerActionDecorator;
  14917. var l_aiTree_onFoot : CAIFollowSideBySideAction;
  14918. var l_aiTree_onHorse : CAIRiderFollowSideBySideAction;
  14919. var l_success : bool = false;
  14920.  
  14921. actor.AddTag( 'playerFollowing' );
  14922.  
  14923. if( thePlayer.IsUsingHorse() )
  14924. {
  14925. l_aiTree_onHorse = new CAIRiderFollowSideBySideAction in this;
  14926. l_aiTree_onHorse.OnCreated();
  14927.  
  14928. l_aiTree_onHorse.params.targetTag = 'playerFollowing';
  14929. }
  14930. else
  14931. {
  14932. l_aiTree_onFoot = new CAIFollowSideBySideAction in this;
  14933. l_aiTree_onFoot.OnCreated();
  14934.  
  14935. l_aiTree_onFoot.params.targetTag = 'playerFollowing';
  14936. }
  14937.  
  14938. l_aiTreeDecorator = new CAIPlayerActionDecorator in this;
  14939. l_aiTreeDecorator.OnCreated();
  14940. l_aiTreeDecorator.interruptOnInput = false;
  14941.  
  14942. if( thePlayer.IsUsingHorse() )
  14943. l_aiTreeDecorator.scriptedAction = l_aiTree_onHorse;
  14944. else
  14945. l_aiTreeDecorator.scriptedAction = l_aiTree_onFoot;
  14946.  
  14947. if( l_aiTreeDecorator )
  14948. l_success = ForceAIBehavior( l_aiTreeDecorator, BTAP_Emergency );
  14949. else if( thePlayer.IsUsingHorse() )
  14950. l_success = ForceAIBehavior( l_aiTree_onHorse, BTAP_Emergency );
  14951. else
  14952. l_success = ForceAIBehavior( l_aiTree_onFoot, BTAP_Emergency );
  14953.  
  14954. if ( l_success )
  14955. {
  14956. GetMovingAgentComponent().SetGameplayRelativeMoveSpeed( 0.0f );
  14957. }
  14958. }
  14959.  
  14960. public function SetCanFollowNpc( val : bool, actor : CActor ) { canFollowNpc = val; actorToFollow = actor; }
  14961. public function CanFollowNpc() : bool { return canFollowNpc; }
  14962. public function GetActorToFollow() : CActor { return actorToFollow; }
  14963.  
  14964. /*public function SetIsFollowing( val : bool )
  14965. {
  14966. isFollowing = val;
  14967.  
  14968. if( val )
  14969. followingStartTime = theGame.GetEngineTimeAsSeconds();
  14970. else
  14971. followingStartTime = 0.0;
  14972. }
  14973. public function GetFollowingStartTime() : float { return followingStartTime; }
  14974. public function IsFollowing() : bool { return isFollowing; }
  14975.  
  14976. timer function ResetIsFollowing( td : float, id : int )
  14977. {
  14978. isFollowing = false;
  14979. }*/
  14980.  
  14981. ////////////////////////////////////////////////////////////////////////////////////////////
  14982. ///////////////////// @SWIMMING ////////////////////////////////////////////////////////
  14983. ////////////////////////////////////////////////////////////////////////////////////////////
  14984.  
  14985. public function SetIsSwimming ( toggle : bool )
  14986. {
  14987. if( isSwimming != toggle )
  14988. {
  14989. thePlayer.substateManager.SetBehaviorParamBool( 'isSwimmingForOverlay', toggle );
  14990. isSwimming = toggle;
  14991. }
  14992. }
  14993. //public function IsSwimming () : bool { return isSwimming; }
  14994.  
  14995. ////////////////////////////////////////////////////////////////////////////////////////////
  14996. /////////////////////////// @DURABILITY //////////////////////////////////////////////////
  14997. ////////////////////////////////////////////////////////////////////////////////////////////
  14998.  
  14999. //returns true if repaired
  15000. public function RepairItemUsingConsumable(item, consumable : SItemUniqueId) : bool
  15001. {
  15002. var curr, max, repairValue, itemValue, repairBonus, newDurability : float;
  15003.  
  15004. //basic check
  15005. if(!inv.IsIdValid(item) || !inv.IsIdValid(consumable) || !inv.HasItemDurability(item))
  15006. return false;
  15007.  
  15008. curr = inv.GetItemDurability(item);
  15009. max = inv.GetItemMaxDurability(item);
  15010.  
  15011. //check durability level
  15012. if(curr > max)
  15013. return false;
  15014.  
  15015. //check consumable type
  15016. if( (inv.IsItemAnyArmor(item) && inv.ItemHasTag(consumable, theGame.params.TAG_REPAIR_CONSUMABLE_ARMOR)) ||
  15017. (inv.IsItemSilverSwordUsableByPlayer(item) && inv.ItemHasTag(consumable, theGame.params.TAG_REPAIR_CONSUMABLE_SILVER)) ||
  15018. (inv.IsItemSteelSwordUsableByPlayer(item) && inv.ItemHasTag(consumable, theGame.params.TAG_REPAIR_CONSUMABLE_STEEL)) )
  15019. {
  15020. //item stats
  15021. itemValue = CalculateAttributeValue(inv.GetItemAttributeValue(consumable, 'durabilityRepairValue'));
  15022. if(itemValue <= 0)
  15023. {
  15024. LogAssert(false, "CR4Player.RepairItemUsingConsumable: consumable <<" + inv.GetItemName(consumable) + ">> has <=0 durabilityRepairValue!!!");
  15025. return false;
  15026. }
  15027. repairBonus = CalculateAttributeValue(inv.GetItemAttributeValue(consumable, 'durabilityBonusValue'));
  15028.  
  15029. //calculate
  15030. repairValue = max * itemValue /100;
  15031.  
  15032. /* disabled repairing over 100%
  15033. if(HasBookPerk(S_Book_28))
  15034. max = max * (1 + (repairBonus + perkValue) /100);
  15035. */
  15036.  
  15037. newDurability = MinF(max, curr + repairValue);
  15038.  
  15039. inv.SetItemDurabilityScript(item, newDurability);
  15040.  
  15041. //consume
  15042. inv.RemoveItem(consumable);
  15043.  
  15044. return true;
  15045. }
  15046. return false;
  15047. }
  15048.  
  15049. ////////////////////////////////////////////////////////////////////////////////////////////
  15050. /////////////////////////// @PushingObject /////////////////////////////////////////////
  15051. ///////////////////////////////////////////////////////////////////////////////////////////
  15052. /*
  15053. event OnRigidBodyCollision( component : CComponent, actorIndex : int, shapeIndex : int )
  15054. {
  15055. pushableComponent = component;
  15056. if ( pushableComponent )
  15057. this.RaiseEvent('PushObject');
  15058.  
  15059. //component.ApplyForceAtPointToPhysicalObject
  15060. }
  15061.  
  15062. event OnRigidBodyExit( component : CComponent )
  15063. {
  15064. this.RaiseEvent('PushObjectEnd');
  15065. pushableComponent = NULL;
  15066. }
  15067.  
  15068. event OnPushObjectStart()
  15069. {
  15070. moveAdj = GetMovingAgentComponent().GetMovementAdjustor();
  15071. moveAdj.CancelAll();
  15072. pushRotTicket = moveAdj.CreateNewRequest( 'RotateToObject' );
  15073. moveAdj.MaxRotationAdjustmentSpeed(pushRotTicket,30);
  15074. moveAdj.Continuous(pushRotTicket);
  15075. moveAdj.DontEnd(pushRotTicket);
  15076. this.AddTimer('PushObjectUpdate',0.01,true, , , true);
  15077.  
  15078. }
  15079.  
  15080. event OnPushObjectStop()
  15081. {
  15082. this.RemoveTimer('PushObjectUpdate');
  15083. moveAdj.CancelByName('RotateToObject');
  15084. moveAdj = NULL;
  15085. }
  15086.  
  15087. timer function PushObjectUpdate( dt : float , id : int)
  15088. {
  15089. var impulse : Vector;
  15090. moveAdj.RotateTo( pushRotTicket, rawPlayerHeading );
  15091. impulse = this.GetHeadingVector()*10.0;
  15092. //impulse.Z += 0.5;
  15093. //pushableComponent.ApplyLocalImpulseToPhysicalObject(impulse);
  15094. }
  15095. */
  15096.  
  15097. //Shaedhen - Atmospheric Nights - Starts here
  15098. //Most of the functions of @DAY @NIGHT CYCLE CHECK have been heavily modified so I didn't specify each change because it would means pretty much everything
  15099. //I don't think there is a lot of other mods modifying this so it shouldn't cause much trouble.
  15100. //If it does, feel free to contact me either on Nexus or CDProjekt Forums and I'll assist with the merge. =)
  15101. public function InitAtmosphericNights()
  15102. {
  15103. var i : int;
  15104. inGameConfigWrapperDN = theGame.GetInGameConfigWrapper();
  15105. listOfStartTimesDK.PushBack(1080);
  15106. listOfStartTimesDK.PushBack(1140);
  15107. listOfStartTimesDK.PushBack(1200);
  15108. listOfStartTimesDK.PushBack(1260);
  15109. listOfStartTimesDK.PushBack(1320);
  15110. listOfStartDurationTimesDK.PushBack(60);
  15111. listOfStartDurationTimesDK.PushBack(120);
  15112. listOfStartDurationTimesDK.PushBack(180);
  15113. listOfStartDurationTimesDK.PushBack(240);
  15114. listOfEndTimesDK.PushBack(120);
  15115. listOfEndTimesDK.PushBack(180);
  15116. listOfEndTimesDK.PushBack(240);
  15117. listOfEndTimesDK.PushBack(300);
  15118. listOfEndTimesDK.PushBack(360);
  15119. listOfEndDurationTimesDK.PushBack(60);
  15120. listOfEndDurationTimesDK.PushBack(120);
  15121. listOfEndDurationTimesDK.PushBack(180);
  15122. listOfEndDurationTimesDK.PushBack(240);
  15123. for(i = 0; i < 12; i+=1)
  15124. intensityDN.PushBack(0.75f);
  15125. }
  15126.  
  15127.  
  15128.  
  15129. public function UpdateValuesDK()
  15130. {
  15131. var oldIntensity : array<float>;
  15132. var i : int;
  15133. var changeHours : bool;
  15134. var oldStart, oldStartTime, oldEndTime,oldEnd : int;
  15135. var change : bool;
  15136. change = false;
  15137. changeHours = false;
  15138. for(i = 0; i < 12; i+=1)
  15139. oldIntensity[i] = intensityDN[i];
  15140. oldStart = startDN;
  15141. oldStartTime = startTimeDN;
  15142. oldEnd = endDN;
  15143. oldEndTime = endTimeDN;
  15144. intensityDN[0] = 0.5f; //Default - shouldn't be used
  15145. intensityDN[1] = StringToFloat (inGameConfigWrapperDN.GetVarValue('DNMenu', 'darkIntensityNovi'))/100;
  15146. intensityDN[2] = StringToFloat (inGameConfigWrapperDN.GetVarValue('DNMenu', 'darkIntensitySkel'))/100;
  15147. intensityDN[3] = StringToFloat (inGameConfigWrapperDN.GetVarValue('DNMenu', 'darkIntensityKaer'))/100;
  15148. intensityDN[4] = StringToFloat (inGameConfigWrapperDN.GetVarValue('DNMenu', 'darkIntensityOrchard'))/100;
  15149. intensityDN[5] = StringToFloat (inGameConfigWrapperDN.GetVarValue('DNMenu', 'darkIntensityWyzima'))/100;
  15150. intensityDN[6] = StringToFloat (inGameConfigWrapperDN.GetVarValue('DNMenu', 'darkIntensityMyst'))/100;
  15151. intensityDN[7] = StringToFloat (inGameConfigWrapperDN.GetVarValue('DNMenu', 'darkIntensitySpiral'))/100;
  15152. intensityDN[8] = StringToFloat (inGameConfigWrapperDN.GetVarValue('DNMenu', 'darkIntensityWinter'))/100;
  15153. intensityDN[11] = StringToFloat (inGameConfigWrapperDN.GetVarValue('DNMenu', 'darkIntensityTous'))/100;
  15154. // intensityDN[9] = StringToFloat (inGameConfigWrapperDN.GetVarValue('DNMenu', 'darkIntensityInterior'))/100;
  15155. changeHours = inGameConfigWrapperDN.GetVarValue('DNMenu', 'customHours');
  15156. startDN = listOfStartTimesDK[StringToInt (inGameConfigWrapperDN.GetVarValue('DNMenu', 'darkStart'))];
  15157. startTimeDN = listOfStartDurationTimesDK[StringToInt (inGameConfigWrapperDN.GetVarValue('DNMenu', 'fullDark'))];
  15158. endDN = listOfEndTimesDK[StringToInt (inGameConfigWrapperDN.GetVarValue('DNMenu', 'darkEnd'))];
  15159. endTimeDN = listOfEndDurationTimesDK[StringToInt (inGameConfigWrapperDN.GetVarValue('DNMenu', 'noDark'))];
  15160. if(changeHours)
  15161. {
  15162. theGame.envMgr.SetDayStartAt(endDN/60);
  15163. theGame.envMgr.SetNightStart((startDN+startTimeDN)/60);
  15164. }else
  15165. {
  15166. theGame.envMgr.SetDayStartAt(3);
  15167. theGame.envMgr.SetNightStart(22);
  15168. startDN = 1200;
  15169. endTimeDN = 180;
  15170. }
  15171. for(i = 0; i < 12; i+=1)
  15172. if(oldIntensity[i] != intensityDN[i])
  15173. change = true;
  15174. if(oldStart != startDN)
  15175. change = true;
  15176. if(oldStartTime != startTimeDN)
  15177. change = true;
  15178. if(oldEnd != endDN)
  15179. change = true;
  15180. if(oldEndTime != endTimeDN)
  15181. change = true;
  15182.  
  15183. if(change && !justSpawnedDN)
  15184. CheckDayNightCycle();
  15185. }
  15186.  
  15187. ///////////////////////////////////////////////////////////////////////////////////////////
  15188. /////////////////////////// @DAY @NIGHT CYCLE CHECK /////////////////////////////////////
  15189. ///////////////////////////////////////////////////////////////////////////////////////////
  15190.  
  15191. public function CheckDayNightCycle()
  15192. {
  15193. var time : GameTime;
  15194. var nextCallTime : int;
  15195. var isNight : bool;
  15196. var isDay : bool;
  15197. var isAlmostNight : bool;
  15198. var isStartingDay : bool;
  15199.  
  15200. //if changed
  15201. isNight = theGame.envMgr.IsNight();
  15202. isDay = theGame.envMgr.IsDay(); //Might return true also if starting day or almost night but it's ok because it is not really used
  15203. isStartingDay = theGame.envMgr.IsStartingDay(endTimeDN); // 120 / 60 = 2 for 2hours
  15204. isAlmostNight = theGame.envMgr.IsAlmostNight(startTimeDN); // 180 / 60 = 3 for 3 hours
  15205.  
  15206. if(isNight)
  15207. {
  15208. OnNightStarted();
  15209. nextCallTime = endDN/60;
  15210. if(nextCallTime < 0 || nextCallTime > 24)
  15211. nextCallTime = 1;
  15212. time = theGame.envMgr.GetGameTimeTillNextHour(nextCallTime);
  15213. }else if(isAlmostNight)
  15214. {
  15215. OnNightAlmostStarted();
  15216. nextCallTime = (startDN+startTimeDN)/60;
  15217. if(nextCallTime < 0 || nextCallTime > 24)
  15218. nextCallTime = 1;
  15219. time = theGame.envMgr.GetGameTimeTillNextHour(nextCallTime);
  15220. }else if(isStartingDay)
  15221. {
  15222. OnDayJustStarted();
  15223. nextCallTime = (endDN+endTimeDN)/60;
  15224. if(nextCallTime < 0 || nextCallTime > 24)
  15225. nextCallTime = 1;
  15226. time = theGame.envMgr.GetGameTimeTillNextHour(nextCallTime);
  15227. }else if(isDay)
  15228. {
  15229.  
  15230. OnDayStarted();
  15231. nextCallTime = startDN/60;
  15232. if(nextCallTime < 0 || nextCallTime > 24)
  15233. nextCallTime = 1;
  15234. time = theGame.envMgr.GetGameTimeTillNextHour(nextCallTime);
  15235. }
  15236.  
  15237. AddGameTimeTimer('DayNightCycle', time);
  15238. }
  15239.  
  15240. timer function DayNightCycle(dt : GameTime, id : int)
  15241. {
  15242. CheckDayNightCycle();
  15243. }
  15244.  
  15245. /*script*/ event OnNightStarted()
  15246. {
  15247. var pam : W3PlayerAbilityManager;
  15248. var l_currentArea : EAreaName;
  15249. var intensity1 : float;
  15250. var intensity2 : float;
  15251. //EAreaName is an enum and intensityDN array follows the same value so value of l_currentArea will get the right area.
  15252. l_currentArea = theGame.GetCommonMapManager().GetCurrentArea();
  15253. intensity1 = intensityDN[l_currentArea];
  15254. if(intensity1 < 0 || intensity1 > 1)
  15255. intensity1 = 0.7f;
  15256. intensity2 = intensityDN[l_currentArea]*0.5;
  15257. if(intensity2 < 0 || intensity2 > 1)
  15258. intensity2 = 0.375f;
  15259. if(CanUseSkill(S_Perk_01))
  15260. {
  15261. pam = (W3PlayerAbilityManager)abilityManager;
  15262. pam.SetPerk01Abilities(false, true);
  15263. }
  15264. //Deactivating if already there
  15265. if(envIdDN > -1)
  15266. DeactivateEnvironment(envIdDN,0.0f);
  15267. if(envIdDN2 > -1)
  15268. DeactivateEnvironment(envIdDN2,0.0f);
  15269. if(envIdDNegated > -1)
  15270. DeactivateEnvironment(envIdDNegated, 0.0f);
  15271. envIdDN = -1;
  15272. envIdDN2 = -1;
  15273. envIdDNegated = -1;
  15274. //Loading it again with full darkness
  15275. // if(thePlayer.IsInInterior())
  15276. // {
  15277. // envIdDN = ActivateEnvironmentDefinition( environmentDN, 99999, intensityDN[9], 0.0f );
  15278. // envIdDN2 = ActivateEnvironmentDefinition( environmentDN2, 99999, intensityDN[9]*0.5, 0.0f );
  15279. // }else{
  15280. // }
  15281. //GetWitcherPlayer().DisplayHudMessage("Goes into is Night int is : " + intensity1);
  15282. if(environmentDN && environmentDN2)
  15283. {
  15284. envIdDN = ActivateEnvironmentDefinition( environmentDN, 99999, intensity1, 0.0f );
  15285. envIdDN2 = ActivateEnvironmentDefinition( environmentDN2, 99999, intensity2, 0.0f );
  15286. }
  15287. }
  15288.  
  15289. /*script*/ event OnNightAlmostStarted()
  15290. {
  15291. var hoursAndMins : int;
  15292. var timeToBlend : float;
  15293. var l_currentArea : EAreaName;
  15294.  
  15295. var intensity1 : float;
  15296. var intensity2 : float;
  15297. //EAreaName is an enum and intensityDN array follows the same value so value of l_currentArea will get the right area.
  15298. l_currentArea = theGame.GetCommonMapManager().GetCurrentArea();
  15299. intensity1 = intensityDN[l_currentArea];
  15300. if(intensity1 < 0 || intensity1 > 1)
  15301. intensity1 = 0.7f;
  15302. intensity2 = intensityDN[l_currentArea]*0.5;
  15303. if(intensity2 < 0 || intensity2 > 1)
  15304. intensity2 = 0.375f;
  15305.  
  15306. hoursAndMins = theGame.envMgr.GetTimeInMinutes();
  15307. timeToBlend = (( (float)(startDN+startTimeDN-hoursAndMins)) *(1.0/theGame.GetHoursPerMinute())) - 10.0f;
  15308. if(timeToBlend < 0)
  15309. timeToBlend = 1.0f;
  15310. if(envIdDN > -1)
  15311. DeactivateEnvironment( envIdDN,0);
  15312. if(envIdDN2 > -1)
  15313. DeactivateEnvironment( envIdDN2,0);
  15314. if(envIdDNegated > -1)
  15315. DeactivateEnvironment(envIdDNegated, 0.0f);
  15316. envIdDN = -1;
  15317. envIdDN2 = -1;
  15318. envIdDNegated = -1;
  15319.  
  15320. // if(thePlayer.IsInInterior())
  15321. // {
  15322. // if (envIdDN2 < 0 ){
  15323. // if((justSpawnedDN || theGame.GetHoursPerMinute() != realHoursPerMinutesDN)){
  15324. // envIdDN2 = ActivateEnvironmentDefinition( environmentDN2, 99999, intensityDN[9]*0.5, 0 );
  15325. // }else{
  15326. // envIdDN2 = ActivateEnvironmentDefinition( environmentDN2, 99999, intensityDN[9]*0.5, timeToBlend );
  15327. // }
  15328. // }
  15329. // envIdDN = ActivateEnvironmentDefinition( environmentDN, 99999, intensityDN[9], timeToBlend );
  15330. //}else{
  15331. //}
  15332. //GetWitcherPlayer().DisplayHudMessage("Goes into is AlmostNight int is : " + intensity1 + "ttb " + timeToBlend);
  15333. if (envIdDN2 < 0 && environmentDN2){
  15334. if((justSpawnedDN || theGame.GetHoursPerMinute() != realHoursPerMinutesDN)){
  15335. envIdDN2 = ActivateEnvironmentDefinition( environmentDN2, 99999, intensity2, 0.0f );
  15336. }else{
  15337. envIdDN2 = ActivateEnvironmentDefinition( environmentDN2, 99999, intensity2, timeToBlend );
  15338. }
  15339. }
  15340. if(environmentDN)
  15341. {
  15342. envIdDN = ActivateEnvironmentDefinition( environmentDN, 99999, intensity1, timeToBlend );
  15343. }
  15344. }
  15345.  
  15346. /*script*/ event OnDayStarted()
  15347. {
  15348. var pam : W3PlayerAbilityManager;
  15349. var hoursAndMins : int;
  15350.  
  15351. hoursAndMins = theGame.envMgr.GetTimeInMinutes();
  15352. if(CanUseSkill(S_Perk_01))
  15353. {
  15354. pam = (W3PlayerAbilityManager)abilityManager;
  15355. pam.SetPerk01Abilities(true, false);
  15356. }
  15357. //Deactivate it if time is appropriate
  15358. if((hoursAndMins >= (endDN+endTimeDN)))
  15359. {
  15360. if(envIdDN >= 0)
  15361. DeactivateEnvironment( envIdDN,0.0f);
  15362. if(envIdDN2 >= 0)
  15363. DeactivateEnvironment( envIdDN2,0.0f);
  15364. if(envIdDNegated >= 0)
  15365. DeactivateEnvironment(envIdDNegated, 0.0f);
  15366. envIdDN = -1;
  15367. envIdDN2 = -1;
  15368. envIdDNegated = -1;
  15369. }
  15370. }
  15371. /*script*/ event OnDayJustStarted()
  15372. {
  15373. var pam : W3PlayerAbilityManager;
  15374. var hoursAndMins : int;
  15375. var l_currentArea : EAreaName;
  15376. var timeToBlend : float;
  15377. var timeToDeBlend : float;
  15378. var adaptFactor : float;
  15379. var intensity1 : float;
  15380. hoursAndMins = theGame.envMgr.GetTimeInMinutes();
  15381. if(CanUseSkill(S_Perk_01))
  15382. {
  15383. pam = (W3PlayerAbilityManager)abilityManager;
  15384. pam.SetPerk01Abilities(true, false);
  15385. }
  15386. timeToBlend = (( (float)(endDN+endTimeDN-hoursAndMins)) *(1.0/theGame.GetHoursPerMinute()));
  15387. if(timeToBlend < 0)
  15388. timeToBlend = 1.0f;
  15389. if(envIdDN > -1)
  15390. DeactivateEnvironment( envIdDN,timeToBlend);
  15391. if(envIdDN2 > -1)
  15392. DeactivateEnvironment( envIdDN2,timeToBlend);
  15393. envIdDN2 = -1;
  15394.  
  15395. if((endDN+endTimeDN-hoursAndMins) <= 30 )
  15396. {
  15397. adaptFactor = 1.0f;
  15398. }else if((endDN+endTimeDN-hoursAndMins) <= 60 )
  15399. {
  15400. adaptFactor = 0.85f;
  15401. }else if((startDN+startTimeDN-hoursAndMins) <= 120 )
  15402. {
  15403. adaptFactor = 0.7f;
  15404. }else if((startDN+startTimeDN-hoursAndMins) <= 180 )
  15405. {
  15406. adaptFactor = 0.6f;
  15407. }else
  15408. {
  15409. adaptFactor = 0.4f;
  15410. }
  15411. l_currentArea = theGame.GetCommonMapManager().GetCurrentArea();
  15412. intensity1 = intensityDN[l_currentArea]*adaptFactor;
  15413. if(intensity1 < 0 || intensity1 > 1)
  15414. intensity1 = 0.4f;
  15415.  
  15416. timeToDeBlend = timeToBlend*8.0f; //TODO : Get this value right... Whatever is set doesn't seems to change much
  15417. if(timeToDeBlend < 0)
  15418. timeToDeBlend = 1.0f;
  15419.  
  15420.  
  15421. if(envIdDN < 0){
  15422. // if(thePlayer.IsInInterior())
  15423. // {
  15424. // envIdDN = ActivateEnvironmentDefinition( environmentDN, 99999, intensityDN[9]*adaptFactor, 0 );
  15425. // }else{
  15426. // }
  15427. if(environmentDN)
  15428. {
  15429. envIdDN = ActivateEnvironmentDefinition( environmentDN, 99999, intensity1, 0 );
  15430. }
  15431. }
  15432. if(environmentDNegated)
  15433. {
  15434. envIdDNegated = ActivateEnvironmentDefinition( environmentDNegated, 99999, -0.0001f, timeToDeBlend );
  15435. }
  15436. }
  15437.  
  15438. public function SetRealHoursPerMinutesDN(hpm : float)
  15439. {
  15440. realHoursPerMinutesDN = hpm;
  15441. }
  15442.  
  15443. public function OnMeditateStopDN(simulatedTime : float)
  15444. {
  15445. GetWitcherPlayer().MeditationRestoring(simulatedTime);
  15446. CheckDayNightCycle();
  15447. }
  15448.  
  15449. public function DeactivateDN()
  15450. {
  15451. if(envIdDN > -1)
  15452. DeactivateEnvironment( envIdDN,0.0f);
  15453. if(envIdDN2 > -1)
  15454. DeactivateEnvironment( envIdDN2,0.0f);
  15455. if(envIdDNegated > -1)
  15456. DeactivateEnvironment(envIdDNegated, 0.0f);
  15457. }
  15458. //Shaedhen - Atmospheric Nights - Ends here
  15459.  
  15460.  
  15461.  
  15462.  
  15463.  
  15464.  
  15465. ///////////////////////////////////////////////////////////////////////////////////////////
  15466. /////////////////////////// @INPUT //////////////////////////////////////////////////////
  15467. ///////////////////////////////////////////////////////////////////////////////////////////
  15468.  
  15469. public function ForceUnlockAllInputActions(alsoQuestLocks : bool)
  15470. {
  15471. if ( inputHandler )
  15472. inputHandler.ForceUnlockAllInputActions(alsoQuestLocks);
  15473. }
  15474.  
  15475. public function SetPrevRawLeftJoyRot()
  15476. {
  15477. prevRawLeftJoyRot = rawLeftJoyRot;
  15478. }
  15479.  
  15480. public function GetPrevRawLeftJoyRot() : float
  15481. {
  15482. return prevRawLeftJoyRot;
  15483. }
  15484.  
  15485. public function GetExplorationInputContext() : name
  15486. {
  15487. return explorationInputContext;
  15488. }
  15489.  
  15490. public function GetCombatInputContext() : name
  15491. {
  15492. return combatInputContext;
  15493. }
  15494.  
  15495. ///////////////////////////////////////////////////////////////////////////////////////////
  15496. /////////////////////////// @EXPLORATION ////////////////////////////////////////////////
  15497. ///////////////////////////////////////////////////////////////////////////////////////////
  15498.  
  15499. public function SetIsOnBoat(b : bool)
  15500. {
  15501. isOnBoat = b;
  15502. }
  15503.  
  15504. public function IsOnBoat() : bool
  15505. {
  15506. return isOnBoat;
  15507. }
  15508.  
  15509. public function IsInShallowWater() : bool
  15510. {
  15511. return isInShallowWater;
  15512. }
  15513.  
  15514. event OnEnterShallowWater()
  15515. {
  15516. if ( isInShallowWater )
  15517. return false;
  15518.  
  15519. isInShallowWater = true;
  15520. BlockAction( EIAB_Dodge,'ShallowWater', false, false, true );
  15521. BlockAction( EIAB_Sprint,'ShallowWater', false, false, true );
  15522. BlockAction( EIAB_Crossbow,'ShallowWater', false, false, true );
  15523. // W3EE - Begin
  15524. // BlockAction( EIAB_Jump,'ShallowWater', false, false, true );
  15525. // W3EE - End
  15526. SetBehaviorVariable( 'shallowWater',1.0);
  15527. }
  15528. event OnExitShallowWater()
  15529. {
  15530. if ( !isInShallowWater )
  15531. return false;
  15532.  
  15533. isInShallowWater = false;
  15534. BlockAllActions('ShallowWater',false);
  15535. SetBehaviorVariable( 'shallowWater',0.0);
  15536. }
  15537.  
  15538. public function TestIsInSettlement() : bool
  15539. {
  15540. return IsInSettlement();
  15541. }
  15542.  
  15543. ///////////////////////////////////////////////////////////////////////////////////////////
  15544. /////////////////////////// GLOSSARY ////////////////////////////////////////////////
  15545. ///////////////////////////////////////////////////////////////////////////////////////////
  15546.  
  15547. //Processes glossary image filename and exchanges it with override if provided
  15548. public function ProcessGlossaryImageOverride( defaultImage : string, uniqueTag : name ) : string
  15549. {
  15550. var size : int;
  15551. var i : int;
  15552.  
  15553. size = glossaryImageOverride.Size();
  15554.  
  15555. if( size == 0 )
  15556. return defaultImage;
  15557.  
  15558. for( i = 0; i < size; i += 1 )
  15559. {
  15560. if( glossaryImageOverride[i].uniqueTag == uniqueTag )
  15561. return glossaryImageOverride[i].imageFileName;
  15562.  
  15563. }
  15564.  
  15565. return defaultImage;
  15566. }
  15567.  
  15568. //Adds glossary image override filename to array
  15569. public function EnableGlossaryImageOverride( uniqueTag : name, imageFileName : string, enable : bool )
  15570. {
  15571. var imageData : SGlossaryImageOverride;
  15572. var size : int;
  15573. var i : int;
  15574.  
  15575. for( i = 0; i < glossaryImageOverride.Size(); i += 1 )
  15576. {
  15577. if( glossaryImageOverride[i].uniqueTag == uniqueTag )
  15578. {
  15579. glossaryImageOverride.Remove(glossaryImageOverride[i]);
  15580. }
  15581. }
  15582.  
  15583. if( enable )
  15584. {
  15585. if( IsNameValid(uniqueTag) && imageFileName != "" )
  15586. {
  15587. glossaryImageOverride.PushBack( SGlossaryImageOverride( uniqueTag, imageFileName ) );
  15588. }
  15589. }
  15590. }
  15591. ///////////////////////////////////////////////////////////////////////////////////////////
  15592. /////////////////////////// WEATHER DISPLAY /////////////////////////////
  15593. ///////////////////////////////////////////////////////////////////////////////////////////
  15594. public function SetWeatherDisplayDisabled( disable : bool )
  15595. {
  15596. disableWeatherDisplay = disable;
  15597. }
  15598.  
  15599. public function GetWeatherDisplayDisabled() : bool
  15600. {
  15601. return disableWeatherDisplay;
  15602. }
  15603.  
  15604. ///////////////////////////////////////////////////////////////////////////////////////////
  15605. /////////////////////////// MONSTER HUNT INVESTIGATION AREAS /////////////////////////////
  15606. ///////////////////////////////////////////////////////////////////////////////////////////
  15607.  
  15608. public function SetCurrentMonsterHuntInvestigationArea ( area : W3MonsterHuntInvestigationArea )
  15609. {
  15610. currentMonsterHuntInvestigationArea = area;
  15611. }
  15612.  
  15613.  
  15614. ///////////////////////////////////////////////////////////////////////////////////////////
  15615. /////////////////////////// BARBER SYSTEM CUSTOM HEAD /////////////////////////////
  15616. ///////////////////////////////////////////////////////////////////////////////////////////
  15617.  
  15618. public function RememberCustomHead( headName : name )
  15619. {
  15620. rememberedCustomHead = headName;
  15621. }
  15622.  
  15623. public function GetRememberedCustomHead() : name
  15624. {
  15625. return rememberedCustomHead;
  15626. }
  15627.  
  15628. public function ClearRememberedCustomHead()
  15629. {
  15630. rememberedCustomHead = '';
  15631. }
  15632.  
  15633. ///////////////////////////////////////////////////////////////////////////////////////////
  15634. /////////////////////////// @TUTORIAL ////////////////////////////////////////////////
  15635. ///////////////////////////////////////////////////////////////////////////////////////////
  15636.  
  15637. public function CreateTutorialInput()
  15638. {
  15639. var prevInputHandler : CPlayerInput;
  15640.  
  15641. prevInputHandler = inputHandler;
  15642. inputHandler = new W3PlayerTutorialInput in this;
  15643. inputHandler.Initialize(false, prevInputHandler);
  15644.  
  15645. if(prevInputHandler)
  15646. delete prevInputHandler;
  15647. }
  15648.  
  15649. public function CreateInput()
  15650. {
  15651. var oldInputHandler : CPlayerInput;
  15652.  
  15653. oldInputHandler = inputHandler;
  15654. inputHandler = new CPlayerInput in this;
  15655. inputHandler.Initialize(false, oldInputHandler);
  15656. }
  15657.  
  15658. timer function TutorialSilverCombat(dt : float, id : int)
  15659. {
  15660. var i : int;
  15661. var actors : array<CActor>;
  15662.  
  15663. if(IsInCombat())
  15664. {
  15665. actors = GetNPCsAndPlayersInRange(20, 1000000, ,FLAG_ExcludePlayer + FLAG_OnlyAliveActors);
  15666. for(i=0; i<actors.Size(); i+=1)
  15667. {
  15668. if(actors[i] && IsRequiredAttitudeBetween(this, actors[i], true) && actors[i].UsesEssence())
  15669. {
  15670. FactsAdd("TutorialShowSilver");
  15671.  
  15672. RemoveTimer('TutorialSilverCombat');
  15673. break;
  15674. }
  15675. }
  15676. }
  15677. }
  15678.  
  15679. private saved var m_bossTag : name;
  15680.  
  15681. public function GetBossTag() : name
  15682. {
  15683. return m_bossTag;
  15684. }
  15685.  
  15686. public function SetBossTag( bossTag : name )
  15687. {
  15688. m_bossTag = bossTag;
  15689. }
  15690.  
  15691. private saved var m_usingCoatOfArms : bool; default m_usingCoatOfArms = false;
  15692.  
  15693. public function IsUsingCoatOfArms() : bool
  15694. {
  15695. return m_usingCoatOfArms;
  15696. }
  15697.  
  15698. public function SetUsingCoatOfArms( using : bool)
  15699. {
  15700. m_usingCoatOfArms = using;
  15701. }
  15702.  
  15703. private saved var m_initialTimeOut : float;
  15704. private saved var m_currentTimeOut : float;
  15705.  
  15706. public function GetInitialTimeOut() : float
  15707. {
  15708. return m_initialTimeOut;
  15709. }
  15710.  
  15711. public function SetInitialTimeOut( timeOut : float )
  15712. {
  15713. m_initialTimeOut = timeOut;
  15714. }
  15715.  
  15716. public function GetCurrentTimeOut() : float
  15717. {
  15718. return m_currentTimeOut;
  15719. }
  15720.  
  15721. public function SetCurrentTimeOut( timeOut : float )
  15722. {
  15723. m_currentTimeOut = timeOut;
  15724. }
  15725.  
  15726.  
  15727. ///////////////////////////////////////////////////////////////////////////////////////////
  15728. /////////////////////////// @FINISHERS ////////////////////////////////////////////
  15729. ///////////////////////////////////////////////////////////////////////////////////////////
  15730.  
  15731. timer function DelayedFinisherInputTimer(dt : float, id : int)
  15732. {
  15733. //theGame.SetTimeScale( 0.1, theGame.GetTimescaleSource(ETS_FinisherInput), theGame.GetTimescalePriority(ETS_FinisherInput) );
  15734. //GetFinisherVictim().EnableFinishComponent( true );
  15735. }
  15736.  
  15737. timer function RemoveFinisherCameraAnimationCheck(dt : float, id : int)
  15738. {
  15739. if ( !isInFinisher && !bLAxisReleased )
  15740. {
  15741. theGame.GetSyncAnimManager().OnRemoveFinisherCameraAnimation();
  15742. RemoveTimer( 'RemoveFinisherCameraAnimationCheck' );
  15743. }
  15744. }
  15745.  
  15746. ///////////////////////////////////////////////////////////////////////////////////////////
  15747. /////////////////////////// @DEBUG @TIMERS ////////////////////////////////////////////
  15748. ///////////////////////////////////////////////////////////////////////////////////////////
  15749.  
  15750. timer function GameplayFactRemove(dt : float, timerId : int)
  15751. {
  15752. theGame.GameplayFactRemoveFromTimer(timerId);
  15753. }
  15754.  
  15755. //gives NORMAL starting inventory
  15756. timer function GiveStartingItems(dt : float, timerId : int)
  15757. {
  15758. var template : CEntityTemplate;
  15759. var invEntity : CInventoryComponent;
  15760. var entity : CEntity;
  15761. var items : array<SItemUniqueId>;
  15762. var id : SItemUniqueId;
  15763. var i : int;
  15764.  
  15765. //wait for inventory to init
  15766. if(inv)
  15767. {
  15768. inv.GetAllItems(items);
  15769. if(items.Size() <= 0)
  15770. {
  15771. return;
  15772. }
  15773. }
  15774. else
  15775. {
  15776. return;
  15777. }
  15778.  
  15779. //add items
  15780. template = (CEntityTemplate)LoadResource("geralt_inventory_release");
  15781. entity = theGame.CreateEntity(template, Vector(0,0,0));
  15782. invEntity = (CInventoryComponent)entity.GetComponentByClassName('CInventoryComponent');
  15783.  
  15784. invEntity.GetAllItems(items);
  15785. for(i=0; i<items.Size(); i+=1)
  15786. {
  15787. id = invEntity.GiveItemTo(inv, items[i], 0, false, true);
  15788. if ( inv.ItemHasTag(id,'Scabbard') )
  15789. {
  15790. inv.MountItem(id);
  15791. }
  15792. else if(!inv.IsItemFists(id) && inv.GetItemName(id) != 'Cat 1') //hack for cat potion - don't equip!
  15793. {
  15794. EquipItem(id);
  15795. }
  15796. else if(inv.IsItemSingletonItem(id))
  15797. {
  15798. inv.SingletonItemSetAmmo(id, inv.SingletonItemGetMaxAmmo(id));
  15799. }
  15800. }
  15801.  
  15802. entity.Destroy();
  15803.  
  15804. //remove timer
  15805. RemoveTimer('GiveStartingItems');
  15806. }
  15807.  
  15808. //Adds items used for testing. Won't be called in final release. Items are added from geralt_inventory entity.
  15809. //Works as a timer since we need to wait for inventory to init and there is no such event.
  15810. timer function Debug_GiveTestingItems(dt : float, optional id : int)
  15811. {
  15812. var template : CEntityTemplate;
  15813. var invTesting : CInventoryComponent;
  15814. var entity : CEntity;
  15815. var items : array<SItemUniqueId>;
  15816. var i : int;
  15817. var slot : EEquipmentSlots;
  15818.  
  15819. //wait for inventory to init
  15820. if(inv)
  15821. {
  15822. inv.GetAllItems(items);
  15823. if(items.Size() <= 0)
  15824. {
  15825. return;
  15826. }
  15827. }
  15828. else
  15829. {
  15830. return;
  15831. }
  15832.  
  15833. template = (CEntityTemplate)LoadResource("geralt_inventory_internal");
  15834. entity = theGame.CreateEntity(template, Vector(0,0,0));
  15835. invTesting = (CInventoryComponent)entity.GetComponentByClassName('CInventoryComponent');
  15836. invTesting.GiveAllItemsTo(inv, true);
  15837. entity.Destroy();
  15838.  
  15839. //once called remove the timer
  15840. RemoveTimer('Debug_GiveTestingItems');
  15841.  
  15842. //equip crossbow, bombs and bolts, select bolts
  15843. inv.GetAllItems(items);
  15844.  
  15845. for(i=0; i<items.Size(); i+=1)
  15846. {
  15847. if( inv.IsItemCrossbow(items[i]) || inv.IsItemBomb(items[i]) )
  15848. {
  15849. slot = inv.GetSlotForItemId(items[i]);
  15850. EquipItem(items[i], slot);
  15851.  
  15852. if( (W3PlayerWitcher)this && inv.IsItemCrossbow(items[i]) )
  15853. GetWitcherPlayer().SelectQuickslotItem(slot);
  15854. }
  15855. else if(inv.IsItemBolt(items[i]))
  15856. {
  15857. slot = inv.GetSlotForItemId(items[i]);
  15858. EquipItem(items[i], slot);
  15859. }
  15860.  
  15861. if(inv.IsItemSingletonItem(items[i]))
  15862. {
  15863. inv.SingletonItemSetAmmo(items[i], inv.SingletonItemGetMaxAmmo(items[i]));
  15864. }
  15865. }
  15866. }
  15867.  
  15868. //called in tutorial in not final version to remove testing items
  15869. timer function Debug_RemoveTestingItems(dt : float, id : int)
  15870. {
  15871. var template : CEntityTemplate;
  15872. var entity : CEntity;
  15873. var invTesting : CInventoryComponent;
  15874. var ids : array<SItemUniqueId>;
  15875. var i : int;
  15876.  
  15877. template = (CEntityTemplate)LoadResource("geralt_inventory_internal");
  15878. entity = theGame.CreateEntity(template, Vector(0,0,0));
  15879. invTesting = (CInventoryComponent)entity.GetComponentByClassName('CInventoryComponent');
  15880. invTesting.GetAllItems(ids);
  15881.  
  15882. for(i=0; i<ids.Size(); i+=1)
  15883. inv.RemoveItemByName(invTesting.GetItemName(ids[i]), invTesting.GetItemQuantity(ids[i]));
  15884.  
  15885. entity.Destroy();
  15886. RemoveTimer('Debug_RemoveTestingItems');
  15887. }
  15888.  
  15889. timer function Debug_DelayedConsoleCommand(dt : float, id : int)
  15890. {
  15891. //inv.AddAnItem('Recipe for Mutagen 23');
  15892. inv.AddAnItem('Boots 2 schematic');
  15893. }
  15894.  
  15895. function DBG_SkillSlots()
  15896. {
  15897. ((W3PlayerAbilityManager)abilityManager).DBG_SkillSlots();
  15898. }
  15899.  
  15900. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  15901. //////////////////////////////// @BACKLIGHT COLOR ////////////////////////////////////////////////////////////////////
  15902. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  15903.  
  15904. public final function SetPadBacklightColor(r, g, b : int)
  15905. {
  15906. var padBacklightColor : Vector;
  15907.  
  15908. padBacklightColor.X = r / 255;
  15909. padBacklightColor.Y = g / 255;
  15910. padBacklightColor.Z = b / 255;
  15911.  
  15912. SetBacklightColor(padBacklightColor);
  15913. }
  15914.  
  15915. public final function SetPadBacklightColorFromSign(signType : ESignType)
  15916. {
  15917. LogPS4Light("SetPadBacklightColorFromSign... " + signType);
  15918.  
  15919. switch(signType)
  15920. {
  15921. case ST_Yrden: SetPadBacklightColor( 200 , 81 , 255 ); break; // Violet
  15922. case ST_Quen: SetPadBacklightColor( 255 , 205 , 68 ); break; // Yellow
  15923. case ST_Igni: SetPadBacklightColor( 255 , 79 , 10 ); break; // Orange
  15924. case ST_Axii: SetPadBacklightColor( 255 , 255 , 255 ); break; // White
  15925. case ST_Aard: SetPadBacklightColor( 158 , 214 , 255 ); break; // Blue
  15926. }
  15927. }
  15928.  
  15929. timer function ResetPadBacklightColorTimer(dt : float, id : int)
  15930. {
  15931. ResetPadBacklightColor();
  15932. }
  15933.  
  15934. public final function ResetPadBacklightColor(optional skipHeldWeapon : bool)
  15935. {
  15936. var weapons : array<SItemUniqueId>;
  15937. var sword : CWitcherSword;
  15938. var healthPercentage : float;
  15939. var tmpBacklight : Vector;
  15940.  
  15941. if(!skipHeldWeapon)
  15942. {
  15943. weapons = inv.GetHeldWeapons();
  15944.  
  15945. //if holding a sword the default backlight color matches the one set in sword entity
  15946. if(weapons.Size() > 0)
  15947. {
  15948. sword = (CWitcherSword)inv.GetItemEntityUnsafe(weapons[0]);
  15949. if(sword)
  15950. {
  15951. tmpBacklight.X = sword.padBacklightColor.X / 255.0f;
  15952. tmpBacklight.Y = sword.padBacklightColor.Y / 255.0f;
  15953. tmpBacklight.Z = sword.padBacklightColor.Z / 255.0f;
  15954. tmpBacklight.W = 1.0f;
  15955. SetBacklightColor( tmpBacklight );
  15956. LogPS4Light("Setting light from sword template: " + NoTrailZeros(sword.padBacklightColor.X) + ", " + NoTrailZeros(sword.padBacklightColor.Y) + ", " + NoTrailZeros(sword.padBacklightColor.Z) );
  15957. return;
  15958. }
  15959. }
  15960. }
  15961.  
  15962. healthPercentage = GetStatPercents( BCS_Vitality );
  15963. SetBacklightFromHealth( healthPercentage );
  15964. LogPS4Light("Setting light from health, " + NoTrailZeros(RoundMath(healthPercentage*100)) + "%");
  15965. }
  15966.  
  15967. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  15968.  
  15969. event OnOpenningDoor()
  15970. {
  15971. if( !thePlayer.IsUsingHorse() )
  15972. RaiseEvent('OpenDoor');
  15973. }
  15974.  
  15975. public final function SetLoopingCameraShakeAnimName( n : name )
  15976. {
  15977. loopingCameraShakeAnimName = n;
  15978. }
  15979.  
  15980. public var loopingCameraShakeAnimName : name;
  15981. timer function RemoveQuestCameraShakeTimer( dt : float , id : int)
  15982. {
  15983. RemoveQuestCameraShake( loopingCameraShakeAnimName );
  15984. }
  15985.  
  15986. public function RemoveQuestCameraShake( animName : name )
  15987. {
  15988. var camera : CCustomCamera = theGame.GetGameCamera();
  15989. var animation : SCameraAnimationDefinition;
  15990.  
  15991. camera.StopAnimation( animName );
  15992. }
  15993.  
  15994. public function GetCameraPadding() : float
  15995. {
  15996. if( theGame.IsFocusModeActive() )
  15997. {
  15998. return 0.25; // Tweaked for [108933] Geralt is being clipped when using focus mode while running towards camera.
  15999. }
  16000. else
  16001. {
  16002. return 0.02f; // Tweaked for [114907] Player dissolving while aiming crossbow.
  16003. }
  16004. }
  16005.  
  16006. public function IsPerformingPhaseChangeAnimation() : bool { return isPerformingPhaseChangeAnimation; }
  16007. public function SetIsPerformingPhaseChangeAnimation( val : bool ) { isPerformingPhaseChangeAnimation = val; }
  16008.  
  16009. private function DealCounterDamageToOlgierd()
  16010. {
  16011. var damage : W3DamageAction;
  16012.  
  16013. damage = new W3DamageAction in this;
  16014.  
  16015. damage.Initialize( thePlayer.GetTarget(), thePlayer.GetTarget(), NULL, this, EHRT_None, CPS_Undefined, false, false, false, true );
  16016. damage.AddDamage( theGame.params.DAMAGE_NAME_DIRECT, thePlayer.GetTarget().GetStatMax( BCS_Vitality ) * 3 / 100 );
  16017. theGame.damageMgr.ProcessAction( damage );
  16018.  
  16019. delete damage;
  16020. }
  16021.  
  16022. timer function PlayDelayedCounterDamageEffect( dt : float, id : int )
  16023. {
  16024. thePlayer.GetTarget().PlayEffect( 'olgierd_energy_blast' );
  16025. }
  16026.  
  16027. // TEST
  16028. public function SetTestAdjustRequestedMovementDirection( val : bool )
  16029. {
  16030. testAdjustRequestedMovementDirection = val;
  16031. }
  16032.  
  16033. event OnVisualDebug( frame : CScriptedRenderFrame, flag : EShowFlags )
  16034. {
  16035. var boneFollow : int;
  16036. var bonePosition : Vector;
  16037. var yrdenEntity : W3YrdenEntity;
  16038.  
  16039. substateManager.OnVisualDebug( frame, flag );
  16040.  
  16041. boneFollow = thePlayer.GetBoneIndex( 'Reference' );
  16042. bonePosition = MatrixGetTranslation( thePlayer.GetBoneWorldMatrixByIndex( boneFollow ) );
  16043. frame.DrawText( "R", bonePosition, Color( 50, 200, 70 ) );
  16044. //frame.DrawText( "R", bonePositionCam, Color( 200, 50, 70 ) );
  16045.  
  16046. boneFollow = thePlayer.GetBoneIndex( 'Trajectory' );
  16047. bonePosition = MatrixGetTranslation( thePlayer.GetBoneWorldMatrixByIndex( boneFollow ) );
  16048. frame.DrawSphere( bonePosition, 0.1f, Color( 200, 50, 70 ) );
  16049. frame.DrawText( "T", bonePosition, Color( 200, 50, 70 ) );
  16050.  
  16051. //frame.DrawSphere( lastSafePosition, 1.0f, Color( 50, 200, 70 ) );
  16052. //frame.DrawText( "SavePos", lastSafePosition, Color( 50, 200, 70 ) );
  16053.  
  16054. yrdenEntity = (W3YrdenEntity)GetWitcherPlayer().GetSignEntity(ST_Yrden);
  16055. yrdenEntity.OnVisualDebug(frame, flag, false);
  16056.  
  16057. return true;
  16058. }
  16059.  
  16060. timer function PotDrinkTimer(dt : float, id : int)
  16061. {
  16062. inputHandler.PotDrinkTimer(false);
  16063. }
  16064.  
  16065. public function SetIsHorseRacing( val : bool )
  16066. {
  16067. isHorseRacing = val;
  16068. }
  16069.  
  16070. public function GetIsHorseRacing() : bool
  16071. {
  16072. return isHorseRacing;
  16073. }
  16074.  
  16075. public function SetHorseCombatSlowMo( val : bool )
  16076. {
  16077. horseCombatSlowMo = val;
  16078. }
  16079.  
  16080. public function GetHorseCombatSlowMo() : bool
  16081. {
  16082. return horseCombatSlowMo;
  16083. }
  16084.  
  16085. public function SetItemsPerLevelGiven( id : int )
  16086. {
  16087. itemsPerLevelGiven[id] = true;
  16088. }
  16089.  
  16090. private function AddItemPerLevelList()
  16091. {
  16092. var i : int;
  16093.  
  16094. itemsPerLevel.Clear();
  16095. itemsPerLevel.PushBack('O');
  16096. itemsPerLevel.PushBack('No Mans Land sword 2');
  16097. itemsPerLevel.PushBack('No Mans Land sword 3');
  16098. itemsPerLevel.PushBack('Silver sword 2');
  16099. itemsPerLevel.PushBack('Boots 01');
  16100. itemsPerLevel.PushBack('Novigraadan sword 2');
  16101. itemsPerLevel.PushBack('Light armor 01');
  16102. itemsPerLevel.PushBack('Heavy boots 01');
  16103. itemsPerLevel.PushBack('Nilfgaardian sword 3');
  16104. itemsPerLevel.PushBack('Silver sword 3');
  16105. itemsPerLevel.PushBack('Heavy gloves 01');
  16106. itemsPerLevel.PushBack('Skellige sword 2');
  16107. itemsPerLevel.PushBack('Heavy pants 01');
  16108. itemsPerLevel.PushBack('Silver sword 4');
  16109. itemsPerLevel.PushBack('No Mans Land sword 4');
  16110. itemsPerLevel.PushBack('Heavy armor 01');
  16111. itemsPerLevel.PushBack('Heavy boots 02');
  16112. itemsPerLevel.PushBack('Skellige sword 3');
  16113. itemsPerLevel.PushBack('Silver sword 5');
  16114. itemsPerLevel.PushBack('Heavy pants 02');
  16115. itemsPerLevel.PushBack('Heavy gloves 02');
  16116. itemsPerLevel.PushBack('Heavy gloves 02');
  16117. itemsPerLevel.PushBack('Heavy armor 02');
  16118. itemsPerLevel.PushBack('Scoiatael sword 1');
  16119.  
  16120. if ( itemsPerLevelGiven.Size() < 49 )
  16121. {
  16122. itemsPerLevelGiven.Clear();
  16123. for (i = 0; i < itemsPerLevel.Size(); i += 1) { itemsPerLevelGiven.PushBack( false ); }
  16124. }
  16125. }
  16126.  
  16127. // TEMP
  16128. public function DealDamageToBoat( dmg : float, index : int, optional globalHitPos : Vector )
  16129. {
  16130. var boat : CBoatDestructionComponent;
  16131.  
  16132. if(usedVehicle)
  16133. {
  16134. boat = (CBoatDestructionComponent) usedVehicle.GetComponentByClassName( 'CBoatDestructionComponent' );
  16135. if( boat )
  16136. {
  16137. boat.DealDamage( dmg, index, globalHitPos );
  16138. }
  16139. }
  16140. }
  16141.  
  16142. ////////////////////////////////////////////////////////////////////////////////
  16143. //
  16144. // PLAYABLE AREA
  16145. //
  16146. public function OnStartTeleportingPlayerToPlayableArea()
  16147. {
  16148. var FADEOUT_INTERVAL : float = 0.5;
  16149.  
  16150. // if we jumped on horse right before being teleported, we need to disable falling damage because height difference may kill us
  16151. if ( thePlayer.IsUsingHorse() )
  16152. {
  16153. if ( thePlayer.GetUsedHorseComponent().OnCheckHorseJump() )
  16154. {
  16155. thePlayer.GetUsedHorseComponent().SetCanTakeDamageFromFalling( false );
  16156. }
  16157. }
  16158.  
  16159. if ( thePlayer.IsActionAllowed( EIAB_FastTravel ) )
  16160. {
  16161. OnOpenMapToLetPlayerGoBackToPlayableArea();
  16162. }
  16163. else
  16164. {
  16165. theGame.FadeOutAsync( FADEOUT_INTERVAL );
  16166. thePlayer.AddTimer( 'BorderTeleportFadeOutTimer', FADEOUT_INTERVAL, false );
  16167. }
  16168. }
  16169.  
  16170. timer function BorderTeleportFadeOutTimer( dt : float, id : int )
  16171. {
  16172. OnTeleportPlayerToPlayableArea( false );
  16173. }
  16174.  
  16175. public function OnOpenMapToLetPlayerGoBackToPlayableArea()
  16176. {
  16177. var initData : W3MapInitData;
  16178.  
  16179. initData = new W3MapInitData in this;
  16180. initData.SetTriggeredExitEntity( true );
  16181. initData.ignoreSaveSystem = true;
  16182. initData.setDefaultState('FastTravel');
  16183. theGame.RequestMenuWithBackground( 'MapMenu', 'CommonMenu', initData );
  16184. }
  16185.  
  16186. public function OnTeleportPlayerToPlayableArea( afterClosingMap : bool )
  16187. {
  16188. var BLACKSCREEN_INTERVAL : float = 0.1;
  16189. var manager : CCommonMapManager = theGame.GetCommonMapManager();
  16190.  
  16191. thePlayer.TeleportWithRotation( manager.GetBorderTeleportPosition(), manager.GetBorderTeleportRotation() );
  16192. thePlayer.AddTimer( 'BorderTeleportFadeInTimer', BLACKSCREEN_INTERVAL, false );
  16193.  
  16194. theGame.FadeOutAsync( 0 );
  16195. theGame.SetFadeLock('PlayerTeleportation');
  16196. }
  16197.  
  16198. timer function BorderTeleportFadeInTimer( dt : float, id : int )
  16199. {
  16200. theGame.ResetFadeLock('PlayerTeleportation');
  16201. theGame.FadeOutAsync( 0 );
  16202. theGame.FadeInAsync( 2.0f );
  16203. }
  16204.  
  16205. public final function SetLastInstantKillTime(g : GameTime)
  16206. {
  16207. lastInstantKillTime = g;
  16208. }
  16209. //
  16210. //
  16211. //
  16212. ////////////////////////////////////////////////////////////////////////////////
  16213.  
  16214. timer function TestTimer(dt : float, id : int )
  16215. {
  16216. LogChannel('asdf', "asdf");
  16217. theGame.FadeOutAsync( 5 );
  16218. }
  16219.  
  16220. public final function Debug_ReleaseCriticalStateSaveLocks()
  16221. {
  16222. effectManager.Debug_ReleaseCriticalStateSaveLocks();
  16223. }
  16224.  
  16225. timer function Debug_SpamSpeed(dt : float, id : int)
  16226. {
  16227. if(currentlyMountedHorse)
  16228. {
  16229. LogSpeed("curr player's horse speed: " + NoTrailZeros(currentlyMountedHorse.GetMovingAgentComponent().GetSpeed())) ;
  16230. }
  16231. else
  16232. {
  16233. LogSpeed("curr player speed: " + NoTrailZeros(GetMovingAgentComponent().GetSpeed())) ;
  16234. }
  16235. }
  16236.  
  16237. timer function RemoveInstantKillSloMo(dt : float, id : int)
  16238. {
  16239. theGame.RemoveTimeScale( theGame.GetTimescaleSource(ETS_InstantKill) );
  16240. }
  16241.  
  16242. timer function RemoveForceFinisher(dt : float, id : int)
  16243. {
  16244. forceFinisher = false;
  16245. }
  16246.  
  16247. public final function Debug_ClearAllActionLocks(optional action : EInputActionBlock, optional all : bool)
  16248. {
  16249. inputHandler.Debug_ClearAllActionLocks(action, all);
  16250. }
  16251.  
  16252. function OnFocusedCameraBlendBegin() {}
  16253. function OnFocusedCameraBlendUpdate( progress : float ) {}
  16254. function OnFocusedCameraBlendEnd() {}
  16255.  
  16256. public function GetEtherealCount() : int { return etherealCount; }
  16257. public function IncrementEtherealCount()
  16258. {
  16259. etherealCount += 1;
  16260. if( etherealCount == 6 )
  16261. ResetEtherealCount();
  16262. }
  16263. public function ResetEtherealCount() { etherealCount = 0; }
  16264.  
  16265. public function SetInsideDiveAttackArea( val : bool ) { insideDiveAttackArea = val; }
  16266. public function IsInsideDiveAttackArea() : bool { return insideDiveAttackArea; }
  16267. public function SetDiveAreaNumber( val : int ) { diveAreaNumber = val; }
  16268. public function GetDiveAreaNumber() : int { return diveAreaNumber; }
  16269.  
  16270. // PHANTOM WEAPON
  16271. //------------------------------------------------------------------------------------------------------------------
  16272. timer function RemoveCameraEffect( dt : float, id : int )
  16273. {
  16274. theGame.GetGameCamera().StopEffect('frost');
  16275. }
  16276.  
  16277. public function InitPhantomWeaponMgr()
  16278. {
  16279. if( !phantomWeaponMgr )
  16280. {
  16281. phantomWeaponMgr = new CPhantomWeaponManager in this;
  16282. phantomWeaponMgr.Init( this.GetInventory() );
  16283. }
  16284. }
  16285.  
  16286. public function DestroyPhantomWeaponMgr()
  16287. {
  16288. if( phantomWeaponMgr )
  16289. {
  16290. delete phantomWeaponMgr;
  16291. }
  16292. }
  16293.  
  16294. timer function RemoveBloodEffects( dt : float, id : int )
  16295. {
  16296. StopEffect('covered_blood');
  16297. }
  16298. // W3EE - End
  16299.  
  16300. public function GetPhantomWeaponMgr() : CPhantomWeaponManager
  16301. {
  16302. if( phantomWeaponMgr )
  16303. {
  16304. return phantomWeaponMgr;
  16305. }
  16306. else
  16307. {
  16308. return NULL;
  16309. }
  16310. }
  16311.  
  16312. public timer function DischargeWeaponAfter( td : float, id : int )
  16313. {
  16314. GetPhantomWeaponMgr().DischargeWeapon();
  16315. }
  16316. //------------------------------------------------------------------------------------------------------------------
  16317. // FORCED FINISHER - mutation8
  16318. //------------------------------------------------------------------------------------------------------------------
  16319.  
  16320. private var forcedFinisherVictim : CActor;
  16321.  
  16322. timer function PerformFinisher( time : float , id : int )
  16323. {
  16324. var combatTarget : CActor;
  16325. var i : int;
  16326.  
  16327. combatTarget = thePlayer.GetTarget();
  16328.  
  16329. if( combatTarget )
  16330. {
  16331. combatTarget.Kill( 'AutoFinisher', false, thePlayer );
  16332. thePlayer.SetFinisherVictim( combatTarget );
  16333. forcedFinisherVictim = combatTarget;
  16334. thePlayer.CleanCombatActionBuffer();
  16335. thePlayer.OnBlockAllCombatTickets( true );
  16336. moveTargets = thePlayer.GetMoveTargets();
  16337.  
  16338. for( i = 0; i < moveTargets.Size(); i += 1 )
  16339. {
  16340. if( combatTarget != moveTargets[i] )
  16341. moveTargets[i].SignalGameplayEvent( 'InterruptChargeAttack' );
  16342. }
  16343.  
  16344. if( theGame.GetInGameConfigWrapper().GetVarValue( 'Gameplay', 'AutomaticFinishersEnabled' ) == "true" )
  16345. combatTarget.AddAbility( 'ForceFinisher', false );
  16346.  
  16347. if( combatTarget.HasTag( 'ForceFinisher' ) )
  16348. combatTarget.AddAbility( 'ForceFinisher', false );
  16349.  
  16350. combatTarget.SignalGameplayEvent( 'ForceFinisher' );
  16351.  
  16352. thePlayer.FindMoveTarget();
  16353.  
  16354. thePlayer.AddTimer( 'SignalFinisher', 0.2, false );
  16355. }
  16356. }
  16357.  
  16358. timer function SignalFinisher( time : float , id : int )
  16359. {
  16360. forcedFinisherVictim.SignalGameplayEvent( 'Finisher' );
  16361. forcedFinisherVictim = NULL;
  16362. }
  16363.  
  16364. // W3EE - Begin
  16365. private var isPlayerAttacking : bool; default isPlayerAttacking = false;
  16366. private var wasPlayerSpamming : bool; default wasPlayerSpamming = false;
  16367. private var isPlayerSpamming : bool; default isPlayerSpamming = false;
  16368. public function SetPlayerSpamming( flag : bool )
  16369. {
  16370. isPlayerSpamming = flag;
  16371. }
  16372.  
  16373. public function SetWasPlayerSpamming( flag : bool )
  16374. {
  16375. wasPlayerSpamming = flag;
  16376. }
  16377.  
  16378. public function SetPlayerAttacking( flag : bool )
  16379. {
  16380. isPlayerAttacking = flag;
  16381. }
  16382.  
  16383. public function IsPlayerAttacking() : bool
  16384. {
  16385. return isPlayerAttacking;
  16386. }
  16387.  
  16388. public function WasPlayerSpamming() : bool
  16389. {
  16390. return wasPlayerSpamming;
  16391. }
  16392.  
  16393. public function IsPlayerSpamming() : bool
  16394. {
  16395. return isPlayerSpamming;
  16396. }
  16397.  
  16398. timer function ResetPlayerSpamming( dt : float, id : int )
  16399. {
  16400. wasPlayerSpamming = false;
  16401. }
  16402. }
  16403.  
  16404. exec function ttt()
  16405. {
  16406. thePlayer.AddTimer( 'TestTimer', 5, false );
  16407. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement