Abode915

Untitled

Jul 29th, 2021
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 217.13 KB | None | 0 0
  1. /***********************************************************************/
  2. /** © 2015 CD PROJEKT S.A. All rights reserved.
  3. /** THE WITCHER® is a trademark of CD PROJEKT S. A.
  4. /** The Witcher game is based on the prose of Andrzej Sapkowski.
  5. /***********************************************************************/
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17. import abstract class CActor extends CGameplayEntity
  18. {
  19.  
  20. import var isAttackableByPlayer : bool;
  21. editable saved var isTargatebleByPlayer : bool; default isTargatebleByPlayer = true;
  22. editable saved var isUsingTooltip : bool; default isUsingTooltip = true;
  23. //MODEnableMimics
  24. import var useHiResShadows : bool; default useHiResShadows = true;
  25. //MODEnableMimics END
  26. public var slideTarget : CGameplayEntity;
  27. public var parryTypeTable : array< array< EParryType > >;
  28. public var lastAttacker : CActor;
  29. public var counterAttackAnimTable : array< name >;
  30. private var bIsGuarded : bool;
  31. private var bParryEnabled : bool;
  32. protected var bCanPerformCounter : bool;
  33. private var lastParryType : EParryType;
  34. private var useAdditiveHits : bool;
  35. private var oneTimeAdditiveHit : bool;
  36. private var useAdditiveCriticalStateAnim: bool;
  37. private var criticalCancelAdditiveHit : bool;
  38. private var lastAttackRangeName : name;
  39. protected var attackActionName : name;
  40. protected var hitTargets : array<CGameplayEntity>;
  41. private var droppedItems : array<SDroppedItem>;
  42. private var wasDefeatedFromFistFight : bool;
  43. protected var isCurrentlyDodging : bool;
  44. private var combatStartTime : float;
  45. private var combatPartStartTime : float;
  46. private var collisionDamageTimestamp : float;
  47. private var lastWasAttackedTime : float;
  48. private var lastWasHitTime : float;
  49. private var lowerGuardTime : float;
  50. private var knockedUncounscious : bool;
  51. private var isGameplayVisible : bool;
  52. private var lastBreathTime : float;
  53. protected var isRecoveringFromKnockdown : bool;
  54.  
  55. private var hitCounter : int; default hitCounter = 0;
  56. private var totalHitCounter : int; default totalHitCounter = 0;
  57. public var customHits : bool; default customHits = false;
  58.  
  59. private var defendCounter : int; default defendCounter = 0;
  60. private var totalDefendCounter : int; default totalDefendCounter = 0;
  61.  
  62. default bIsGuarded = false;
  63. default bParryEnabled = false;
  64. default collisionDamageTimestamp = 0.0;
  65.  
  66.  
  67. private var bIsPlayerCurrentTarget : bool;
  68.  
  69.  
  70. protected saved var buffImmunities : array<SBuffImmunity>;
  71. protected saved var buffRemovedImmunities : array<SBuffImmunity>;
  72. protected saved var newRequestedCS : CBaseGameplayEffect;
  73.  
  74. private var criticalStateCounter : int;
  75. private var totalCriticalStateCounter : int;
  76.  
  77.  
  78. public saved var isDead : bool;
  79.  
  80.  
  81. protected var canPlayHitAnim : bool; default canPlayHitAnim = true;
  82.  
  83.  
  84. private editable var damageDistanceNotReducing : float; default damageDistanceNotReducing = 5.0f;
  85. private editable var deathDistNotReducing : float; default deathDistNotReducing = 7.0f;
  86. private editable var damageDistanceReducing : float; default damageDistanceReducing = 9.0f;
  87. private editable var deathDistanceReducing : float; default deathDistanceReducing = 9.0f;
  88. private editable var fallDamageMinHealthPerc : float; default fallDamageMinHealthPerc = 0.05f;
  89.  
  90.  
  91. public var isPlayerFollower : bool;
  92.  
  93. private var MAC : CMovingPhysicalAgentComponent;
  94.  
  95. saved var immortalityFlags : int;
  96. default immortalityFlags = 0;
  97.  
  98. saved var abilityManager : W3AbilityManager;
  99.  
  100. private var effectsUpdateTicking : bool; default effectsUpdateTicking = false;
  101.  
  102. public function GetIgnoreImmortalDodge() : bool
  103. {
  104.  
  105. return false;
  106. }
  107.  
  108.  
  109.  
  110.  
  111. public function SetTatgetableByPlayer(isTargetAble : bool)
  112. {
  113. isTargatebleByPlayer = isTargetAble;
  114. }
  115.  
  116. public function IsTargetableByPlayer() : bool
  117. {
  118. if ( thePlayer.playerMode.GetForceCombatMode() )
  119. {
  120. if ( this.GetAttitude( thePlayer ) == AIA_Friendly )
  121. return false;
  122. }
  123. return isTargatebleByPlayer;
  124. }
  125.  
  126. public function IsUsingTooltip() : bool
  127. {
  128. return isUsingTooltip;
  129. }
  130.  
  131. public function SetIsUsingTooltip (hasTooltip : bool)
  132. {
  133. isUsingTooltip = hasTooltip;
  134. }
  135.  
  136.  
  137.  
  138. public function GetTotalWeaponDamage(weaponId : SItemUniqueId, damageTypeName : name, crossbowId : SItemUniqueId, optional bolt : W3BoltProjectile) : float
  139. {
  140. var weaponDamage, innateDamage : SAbilityAttributeValue;
  141. var ret : float;
  142.  
  143. innateDamage = GetAttributeValue(damageTypeName);
  144. if( bolt )
  145. weaponDamage.valueAdditive = bolt.GetBoltDamage(damageTypeName);
  146. else
  147. weaponDamage = GetInventory().GetItemAttributeValue(weaponId, damageTypeName);
  148. weaponDamage.valueAdditive += innateDamage.valueAdditive; weaponDamage.valueMultiplicative += innateDamage.valueMultiplicative;
  149. ret = CalculateAttributeValue(weaponDamage);
  150.  
  151. return ret;
  152. }
  153.  
  154. public function GetAttributeValue(attributeName : name, optional tags : array<name>, optional ignoreDeath : bool) : SAbilityAttributeValue
  155. {
  156. var null : SAbilityAttributeValue;
  157.  
  158. if(abilityManager && abilityManager.IsInitialized() && (ignoreDeath || IsAlive()) )
  159. return abilityManager.GetAttributeValue(attributeName,tags);
  160.  
  161. null.valueBase = -1;
  162. null.valueAdditive = -1;
  163. null.valueMultiplicative = 0;
  164. return null;
  165. }
  166.  
  167.  
  168. public function GetAbilityAttributeValue(abilityName : name, attributeName : name) : SAbilityAttributeValue
  169. {
  170. var null : SAbilityAttributeValue;
  171.  
  172. if(abilityManager && abilityManager.IsInitialized())
  173. return abilityManager.GetAbilityAttributeValue(abilityName, attributeName);
  174.  
  175. null.valueBase = -1;
  176. null.valueAdditive = -1;
  177. null.valueMultiplicative = 0;
  178. return null;
  179. }
  180.  
  181.  
  182. function CanAddAttribute( attributeName : name, abilityName : name ) : bool
  183. {
  184. if ( attributeName == 'vitality' && UsesEssence())
  185. {
  186. return false;
  187. }
  188. else if ( attributeName == 'essence' && UsesVitality())
  189. {
  190. return false;
  191. }
  192.  
  193. return true;
  194. }
  195.  
  196. event OnAbilityAdded( abilityName : name)
  197. {
  198. if(abilityManager && abilityManager.IsInitialized())
  199. abilityManager.OnAbilityAdded(abilityName);
  200. }
  201.  
  202. event OnAbilityRemoved( abilityName : name)
  203. {
  204. if(abilityManager && abilityManager.IsInitialized())
  205. abilityManager.OnAbilityRemoved(abilityName);
  206. }
  207.  
  208. public final function IsAbilityBlocked(abilityName : name) : bool {return abilityManager.IsAbilityBlocked(abilityName);}
  209. public final function BlockAbility(abilityName : name, block : bool, optional cooldown : float) : bool {return abilityManager.BlockAbility(abilityName, block, cooldown);}
  210.  
  211. import public function MuteHeadAudio( mute: bool );
  212. import public function CanPush( canPush: bool );
  213.  
  214.  
  215.  
  216. import public function ApplyItemAbilities( itemId : SItemUniqueId ) : bool;
  217. //MODEnableMimics
  218. import function IsPlayingChatScene() : bool;
  219. //MODEnableMimics END
  220.  
  221.  
  222. import public function RemoveItemAbilities( itemId : SItemUniqueId ) : bool;
  223.  
  224.  
  225. import public function GetCharacterStatsParam(abilities : array<name>);
  226.  
  227.  
  228. import public function ReportDeathToSpawnSystems();
  229.  
  230.  
  231. import public function ForceSoundAppearanceUpdate();
  232.  
  233. saved var immortalityFlagsCopy : int;
  234. default immortalityFlagsCopy = 0;
  235.  
  236.  
  237. private function GetPureImmortalityFlags() : int
  238. {
  239. var mask : int;
  240.  
  241.  
  242. mask = 16777215;
  243.  
  244. return ( immortalityFlags & mask );
  245. }
  246. public function WillBeUnconscious() : bool
  247. {
  248. var pureImmortalityFlags : int;
  249. pureImmortalityFlags = GetPureImmortalityFlags();
  250.  
  251. return pureImmortalityFlags > 0 && pureImmortalityFlags < 256;
  252. }
  253.  
  254. public function IsImmortal() : bool
  255. {
  256. var pureImmortalityFlags : int;
  257. pureImmortalityFlags = GetPureImmortalityFlags();
  258.  
  259. return pureImmortalityFlags >= 256 && pureImmortalityFlags < 65536;
  260. }
  261.  
  262. public function IsInvulnerable() : bool
  263. {
  264. var pureImmortalityFlags : int;
  265. pureImmortalityFlags = GetPureImmortalityFlags();
  266.  
  267. return pureImmortalityFlags >= 65536;
  268. }
  269.  
  270. public function IsVulnerable() : bool
  271. {
  272. var pureImmortalityFlags : int;
  273. pureImmortalityFlags = GetPureImmortalityFlags();
  274.  
  275. return pureImmortalityFlags == 0;
  276. }
  277. public function GetImmortalityMode() : EActorImmortalityMode
  278. {
  279. if ( WillBeUnconscious() ) { return AIM_Unconscious; }
  280. else if( IsInvulnerable() ) { return AIM_Invulnerable; }
  281. else if( IsImmortal() ) { return AIM_Immortal; }
  282.  
  283. return AIM_None;
  284. }
  285.  
  286. public function LogAllAbilities()
  287. {
  288. var attributes : array< name >;
  289. var i : int;
  290. var res : string;
  291.  
  292. GetWitcherPlayer().GetCharacterStats().GetAllAttributesNames( attributes );
  293. for ( i = 1; i< attributes.Size(); i+=1 )
  294. {
  295. res = NameToString( attributes[i] ) + " ("+ GetLocStringByKeyExt( NameToString( attributes[i] ) ) + ") : " + FloatToString( CalculateAttributeValue( GetAttributeValue( attributes[i] ) ) );
  296. LogStats( res );
  297. }
  298. }
  299.  
  300. public function ForceVulnerable()
  301. {
  302. var oldMode : EActorImmortalityMode;
  303. if( immortalityFlags > 0 )
  304. {
  305. oldMode = GetImmortalityMode();
  306. LogChannel('Stats', "Actor <<" + this + ">> forces to vulnerable from <<" + oldMode + ">>");
  307. }
  308. immortalityFlags = 0;
  309. }
  310.  
  311. public function ForceVulnerableImmortalityMode()
  312. {
  313. immortalityFlagsCopy = immortalityFlags;
  314. immortalityFlags = 0;
  315. }
  316.  
  317. public function RestoreImmortalityMode()
  318. {
  319. immortalityFlags = immortalityFlagsCopy;
  320. }
  321.  
  322. public function GetImmortalityModeChannels( mode : EActorImmortalityMode) : array< EActorImmortalityChanel >
  323. {
  324. var numImmortalityChannels : int;
  325. var result : array< EActorImmortalityChanel >;
  326. var i : int;
  327. var modeOffset : int;
  328. var mask : int;
  329. var channel : int;
  330. var _shift8, _shift16 : int;
  331.  
  332. _shift8 = 256;
  333. _shift16 = 65536;
  334.  
  335. modeOffset = 1;
  336. if ( mode == AIM_Immortal )
  337. {
  338. modeOffset = _shift8;
  339. }
  340. else if ( mode == AIM_Invulnerable)
  341. {
  342. modeOffset = _shift16;
  343. }
  344.  
  345. numImmortalityChannels = 8;
  346. if( mode != AIM_None )
  347. {
  348. for( i = 0; i < numImmortalityChannels; i += 1 )
  349. {
  350. channel = (int) PowF( 2, i );
  351. mask = modeOffset * channel;
  352. if( ( immortalityFlags & mask ) > 0 )
  353. {
  354. result.PushBack( channel );
  355. }
  356. }
  357. }
  358. else
  359. {
  360. for( i = 0; i < numImmortalityChannels; i += 1 )
  361. {
  362. channel = (int) PowF( 2, i );
  363. if( ( channel & immortalityFlags ) == 0 &&
  364. ( ( channel * _shift8 ) & immortalityFlags ) == 0 &&
  365. ( ( channel * _shift16 ) & immortalityFlags ) == 0 )
  366. {
  367. result.PushBack( channel );
  368. }
  369. }
  370. }
  371.  
  372. return result;
  373. }
  374.  
  375. public function SetImmortalityMode( mode : EActorImmortalityMode, channel : EActorImmortalityChanel, optional lockMode : bool )
  376. {
  377. var oldMode : EActorImmortalityMode;
  378. var channelInt : int;
  379. var _shift8, _shift16, _shift24 : int;
  380.  
  381. channelInt = channel;
  382.  
  383.  
  384. _shift8 = 256;
  385.  
  386. _shift16 = 65536;
  387.  
  388. _shift24 = 16777216;
  389.  
  390. if ( !lockMode && ( ( immortalityFlags & ( channelInt * _shift24 ) ) != 0 ) )
  391. return;
  392.  
  393. oldMode = GetImmortalityMode();
  394.  
  395. if ( mode == AIM_Unconscious )
  396. {
  397. immortalityFlags = immortalityFlags | ( channelInt );
  398. immortalityFlags = immortalityFlags & ( ~( channelInt * _shift8 ) );
  399. immortalityFlags = immortalityFlags & ( ~( channelInt * _shift16 ) );
  400. }
  401. else if ( mode == AIM_Immortal )
  402. {
  403. immortalityFlags = immortalityFlags | ( channelInt * _shift8 );
  404. immortalityFlags = immortalityFlags & ( ~channelInt );
  405. immortalityFlags = immortalityFlags & ( ~( channelInt * _shift16 ) );
  406. }
  407. else if ( mode == AIM_Invulnerable)
  408. {
  409. immortalityFlags = immortalityFlags | ( channelInt * _shift16 );
  410. immortalityFlags = immortalityFlags & ( ~channelInt );
  411. immortalityFlags = immortalityFlags & ( ~( channelInt * _shift8 ) );
  412. }
  413. else if ( mode == AIM_None )
  414. {
  415. immortalityFlags = immortalityFlags & ( ~channelInt );
  416. immortalityFlags = immortalityFlags & ( ~( channelInt * _shift8 ) );
  417. immortalityFlags = immortalityFlags & ( ~( channelInt * _shift16 ) );
  418. }
  419. if ( lockMode )
  420. {
  421. immortalityFlags = immortalityFlags | ( channelInt * _shift24 );
  422. }
  423.  
  424. if ( oldMode == mode )
  425. return;
  426.  
  427. LogChannel('Stats', "Actor <<" + this + ">> changes immortality mode from <<" + oldMode + ">> to <<" + mode + ">>");
  428. }
  429.  
  430.  
  431.  
  432. protected var isSwimming : bool;
  433.  
  434.  
  435. protected saved var usedVehicleHandle : EntityHandle ;
  436. protected var usedVehicle : CGameplayEntity;
  437.  
  438.  
  439. protected saved var effectManager : W3EffectManager;
  440.  
  441. private var traverser : CScriptedExplorationTraverser;
  442. function GetTraverser() : CScriptedExplorationTraverser
  443. {
  444. return traverser;
  445. }
  446. timer function UpdateTraverser( time : float , id : int)
  447. {
  448. if( traverser )
  449. {
  450. traverser.Update( time );
  451. }
  452. }
  453.  
  454.  
  455. event OnStartTraversingExploration( t : CScriptedExplorationTraverser )
  456. {
  457. SetInteractionPriority(IP_Max_Unpushable);
  458. traverser = t;
  459. return true;
  460. }
  461.  
  462. event OnFinishTraversingExploration()
  463. {
  464. RestoreOriginalInteractionPriority();
  465. traverser = NULL;
  466. return true;
  467. }
  468.  
  469.  
  470. private saved var nextFreeAnimMultCauserId : int;
  471. default nextFreeAnimMultCauserId = 0;
  472.  
  473. private var animationMultiplierCausers : array< SAnimMultiplyCauser >;
  474.  
  475. import final function GetAutoEffects( out effects : array< name > );
  476.  
  477. import final function SignalGameplayEvent( eventName : CName );
  478.  
  479. import final function SignalGameplayEventParamCName( eventName : CName, param : CName );
  480. import final function SignalGameplayEventParamInt( eventName : CName, param : int );
  481. import final function SignalGameplayEventParamFloat( eventName : CName, param : float );
  482. import final function SignalGameplayEventParamObject( eventName : CName, param : IScriptable );
  483.  
  484. import final function SignalGameplayEventReturnCName( eventName : CName, defaultVal : CName ) : CName;
  485. import final function SignalGameplayEventReturnInt( eventName : CName, defaultVal : int ) : int;
  486. import final function SignalGameplayEventReturnFloat( eventName : CName, defaultVal : float ) : float;
  487.  
  488. import final function SignalGameplayDamageEvent( eventName : CName, data : CDamageData );
  489.  
  490. import final function GetScriptStorageObject( storageItemName : CName ) : IScriptable;
  491.  
  492. import final function ForceAIUpdate();
  493.  
  494.  
  495. import final function GetTarget() : CActor;
  496.  
  497.  
  498.  
  499.  
  500. import final function IsDangerous( actor : CActor ) : bool;
  501.  
  502.  
  503. import final function GetAttitude( actor : CActor ) : EAIAttitude;
  504. import final function SetAttitude( actor : CActor , attitude : EAIAttitude );
  505. import final function ResetAttitude( actor : CActor );
  506. import final function HasAttitudeTowards( actor : CActor ) : bool;
  507. import final function ClearAttitudes( hostile, neutral, friendly : bool );
  508.  
  509.  
  510. import final function GetAttitudeGroup() : CName;
  511. import final function GetBaseAttitudeGroup() : CName;
  512. import final function SetBaseAttitudeGroup( groupName : CName );
  513. import final function ResetBaseAttitudeGroup();
  514. import final function SetTemporaryAttitudeGroup( groupName : CName, priority : EAttitudeGroupPriority );
  515. import final function ResetTemporaryAttitudeGroup( priority : EAttitudeGroupPriority );
  516.  
  517.  
  518.  
  519. import final function IsInCombat() : bool;
  520.  
  521.  
  522. public function SetCombatStartTime()
  523. {
  524. combatStartTime = theGame.GetEngineTimeAsSeconds();
  525. }
  526.  
  527. public function GetCombatStartTime() : float
  528. {
  529. return combatStartTime;
  530. }
  531.  
  532. public function ResetCombatStartTime()
  533. {
  534. combatStartTime = 0;
  535. }
  536.  
  537. public function SetCombatPartStartTime()
  538. {
  539. combatPartStartTime = theGame.GetEngineTimeAsSeconds();
  540. }
  541.  
  542. public function ResetCombatPartStartTime()
  543. {
  544. combatPartStartTime = 0;
  545. }
  546.  
  547. public function GetCombatTime() : float
  548. {
  549. var time : float;
  550.  
  551. if( combatStartTime )
  552. {
  553. time = theGame.GetEngineTimeAsSeconds() - combatStartTime;
  554. return time;
  555. }
  556. else
  557. {
  558. return 0;
  559. }
  560. }
  561.  
  562. public function GetCombatPartTime() : float
  563. {
  564. var time : float;
  565.  
  566. if( combatPartStartTime )
  567. {
  568. time = theGame.GetEngineTimeAsSeconds() - combatPartStartTime;
  569. return time;
  570. }
  571. else
  572. {
  573. return 0;
  574. }
  575. }
  576.  
  577.  
  578. protected function OnCombatModeSet( toggle : bool )
  579. {
  580. var movingAgent : CMovingAgentComponent = GetMovingAgentComponent();
  581.  
  582. if ( movingAgent )
  583. {
  584. movingAgent.EnableCombatMode( toggle );
  585. movingAgent.SetVirtualRadius( 'testRadius' );
  586.  
  587. if ( toggle )
  588. {
  589. movingAgent.SetVirtualRadius( 'CombatCharacterRadius' );
  590. }
  591. else
  592. {
  593. movingAgent.ResetVirtualRadius();
  594. }
  595. }
  596. }
  597.  
  598. public function HasHitTarget() : bool
  599. {
  600. return hitTargets.Size() != 0;
  601. }
  602.  
  603.  
  604.  
  605. public function WasDefeatedFromFistFight() : bool
  606. {
  607. return this.wasDefeatedFromFistFight;
  608. }
  609.  
  610. import private var isInFFMiniGame : bool;
  611.  
  612. event OnStartFistfightMinigame()
  613. {
  614. // W3EE - Begin
  615. //PauseHPRegenEffects('FistFightMinigame', -1);
  616. // W3EE - End
  617. isInFFMiniGame = true;
  618. }
  619.  
  620. event OnEndFistfightMinigame()
  621. {
  622. ResumeHPRegenEffects('FistFightMinigame');
  623. isInFFMiniGame = false;
  624. }
  625.  
  626. public function IsInFistFightMiniGame() : bool
  627. {
  628. return isInFFMiniGame;
  629. }
  630.  
  631. import final function SetDebugAttackRange(rangeName : name);
  632. import final function EnableDebugARTraceDraw( enable : bool );
  633.  
  634.  
  635. import final function IsReadyForNewAction() : bool;
  636.  
  637.  
  638. import final function ActionCancelAll();
  639.  
  640. import final function IsCurrentActionInProgress() : bool;
  641. import final function IsCurrentActionSucceded() : bool;
  642. import final function IsCurrentActionFailed() : bool;
  643.  
  644. import final function IsInNonGameplayCutscene() : bool;
  645. import final function IsInGameplayScene() : bool;
  646.  
  647. import final function PlayScene( input : string ) : bool;
  648. import final function StopAllScenes();
  649.  
  650. import final function GetCurrentActionPriority() : int;
  651.  
  652. import final function GetCurrentActionType() : EActorActionType;
  653.  
  654. import final function IsDoingSomethingMoreImportant( priority : int ) : bool;
  655.  
  656. import final function CanPlayQuestScene() : bool;
  657. import final function HasInteractionScene() : bool;
  658. import final function CanTalk( optional ignoreCurrentSpeech : bool ) : bool;
  659.  
  660. import final function GetActorAnimState() : int;
  661.  
  662.  
  663. import final function IsInView() : bool;
  664.  
  665.  
  666. import final function IsUsingExploration() : bool;
  667.  
  668. import final function GetAnimCombatSlots( animSlotName : name, out outSlots : array< Matrix >,
  669. slotsNum : int, mainEnemyMatrix : Matrix ) : bool;
  670.  
  671. import final function GetHeadBoneIndex() : int;
  672. import final function GetTorsoBoneIndex() : int;
  673.  
  674. var isInAir : bool; default isInAir = false;
  675. public function IsInAir() : bool {return isInAir;}
  676.  
  677. public function SetIsInAir(b : bool)
  678. {
  679. var critical : CBaseGameplayEffect;
  680.  
  681. if ( b != isInAir )
  682. {
  683. isInAir = b;
  684. SetBehaviorVariable( 'IsInAir', (int)isInAir);
  685.  
  686. critical = GetCurrentlyAnimatedCS();
  687. if(critical)
  688. {
  689. if ( isInAir )
  690. this.SignalGameplayEvent('DisableFinisher');
  691. else
  692. this.SignalGameplayEvent('EnableFinisher');
  693. }
  694. }
  695. }
  696.  
  697. public var ragdollPullingStartPosition : Vector;
  698.  
  699. public function GetRagdollPullingStartPosition() : Vector
  700. {
  701. return ragdollPullingStartPosition;
  702. }
  703.  
  704. event OnRagdollPullingStarts( ragdollPos, entityPos : Vector )
  705. {
  706. ragdollPullingStartPosition = ragdollPos;
  707. SignalGameplayEvent( 'OnRagdollPullingStart' );
  708. }
  709.  
  710.  
  711.  
  712.  
  713. import final latent function ActionMoveToNode( target : CNode, optional moveType : EMoveType, optional absSpeed : float, optional radius : float, optional failureAction : EMoveFailureAction ) : bool;
  714.  
  715. import final function ActionMoveToNodeAsync( target : CNode, optional moveType : EMoveType, optional absSpeed : float, optional radius : float, optional failureAction : EMoveFailureAction ) : bool;
  716.  
  717.  
  718. import final latent function ActionMoveToNodeWithHeading( target : CNode, optional moveType : EMoveType, optional absSpeed : float, optional radius : float, optional failureAction : EMoveFailureAction ) : bool;
  719.  
  720. import final function ActionMoveToNodeWithHeadingAsync( target : CNode, optional moveType : EMoveType, optional absSpeed : float, optional radius : float, optional failureAction : EMoveFailureAction ) : bool;
  721.  
  722.  
  723. import final latent function ActionMoveTo( target : Vector, optional moveType : EMoveType, optional absSpeed : float, optional radius : float, optional failureAction : EMoveFailureAction ) : bool;
  724.  
  725. import final function ActionMoveToAsync( target : Vector, optional moveType : EMoveType, optional absSpeed : float, optional radius : float, optional failureAction : EMoveFailureAction ) : bool;
  726.  
  727.  
  728. import final latent function ActionMoveToWithHeading( target : Vector, heading : float, optional moveType : EMoveType, optional absSpeed : float, optional radius : float, optional failureAction : EMoveFailureAction ) : bool;
  729.  
  730. import final function ActionMoveToWithHeadingAsync( target : Vector, heading : float, optional moveType : EMoveType, optional absSpeed : float, optional radius : float, optional failureAction : EMoveFailureAction ) : bool;
  731.  
  732.  
  733. import final latent function ActionMoveToDynamicNode( target : CNode, moveType : EMoveType, absSpeed : float, range : float, optional keepDistance : bool, optional failureAction : EMoveFailureAction ) : bool;
  734.  
  735. import final function ActionMoveToDynamicNodeAsync( target : CNode, moveType : EMoveType, absSpeed : float, range : float, optional keepDistance : bool, optional failureAction : EMoveFailureAction ) : bool;
  736.  
  737.  
  738. import final latent function ActionMoveCustom( targeter : CMoveTRGScript ) : bool;
  739.  
  740. import final function ActionMoveCustomAsync( targeter : CMoveTRGScript ) : bool;
  741.  
  742.  
  743. import final latent function ActionSlideThrough( explorationAreaToUse : CActionAreaComponent ) : bool;
  744.  
  745. import final function ActionSlideThroughAsync( explorationAreaToUse : CActionAreaComponent ) : bool;
  746.  
  747.  
  748. import final latent function ActionSlideTo( target : Vector, duration : float ) : bool;
  749.  
  750. import final function ActionSlideToAsync( target : Vector, duration : float ) : bool;
  751.  
  752.  
  753. import final latent function ActionMoveOnCurveTo( target : Vector, duration : float, rightShift : bool ) : bool;
  754.  
  755. import final function ActionMoveOnCurveToAsync( target : Vector, duration : float, rightShift : bool ) : bool;
  756.  
  757.  
  758. import final latent function ActionSlideToWithHeading( target : Vector, heading : float, duration : float, optional rotation : ESlideRotation ) : bool;
  759.  
  760. import final function ActionSlideToWithHeadingAsync( target : Vector, heading : float, duration : float, optional rotation : ESlideRotation ) : bool;
  761.  
  762.  
  763. import final latent function ActionMoveAwayFromNode( position : CNode, distance : float, optional moveType : EMoveType, optional absSpeed : float, optional radius : float, optional failureAction : EMoveFailureAction ) : bool;
  764.  
  765. import final function ActionMoveAwayFromNodeAsync( position : CNode, distance : float, optional moveType : EMoveType, optional absSpeed : float, optional radius : float, optional failureAction : EMoveFailureAction ) : bool;
  766.  
  767.  
  768.  
  769. import final latent function ActionMoveAwayFromLine( positionA : Vector, positionB : Vector, distance : float, makeMinimalMovement : bool, optional moveType : EMoveType, optional absSpeed : float, optional radius : float, optional failureAction : EMoveFailureAction ) : bool;
  770.  
  771.  
  772. import final function ActionMoveAwayFromLineAsync( positionA : Vector, positionB : Vector, distance : float, makeMinimalMovement : bool, optional moveType : EMoveType, optional absSpeed : float, optional radius : float, optional failureAction : EMoveFailureAction ) : bool;
  773.  
  774.  
  775. import final latent function ActionRotateTo( target : Vector ) : bool;
  776.  
  777. import final function ActionRotateToAsync( target : Vector ) : bool;
  778.  
  779.  
  780. import final latent function ActionSetOrientation( orientation : float ) : bool;
  781.  
  782.  
  783. import final latent function ActionPlaySlotAnimation( slotName : name, animationName : name, optional blendIn : float, optional blendOut : float, optional continuePlaying : bool ) : bool;
  784. import final function ActionPlaySlotAnimationAsync( slotName : name, animationName : name, optional blendIn : float, optional blendOut : float, optional continuePlaying : bool ) : bool;
  785.  
  786.  
  787. import final latent function ActionExitWork( optional fast : bool ) : bool;
  788.  
  789. import final function ActionExitWorkAsync( optional fast : bool ) : bool;
  790.  
  791.  
  792.  
  793.  
  794.  
  795.  
  796.  
  797.  
  798. import final latent function ActionExploration( exploration : SExplorationQueryToken, optional listener : IScriptable, optional steeringGraphTargetNode : CNode ) : bool;
  799.  
  800. import final latent function ActionAnimatedSlideToStatic( settings : SAnimatedSlideSettings, target : Vector, heading : float, translation : bool, rotation : bool ) : bool;
  801. import final latent function ActionAnimatedSlideTo( settings : SAnimatedSlideSettings, target : CNode, translation : bool, rotation : bool ) : bool;
  802.  
  803. import final function ActionAnimatedSlideToStaticAsync( settings : SAnimatedSlideSettings, target : Vector, heading : float, translation : bool, rotation : bool ) : bool;
  804. import final function ActionAnimatedSlideToAsync( settings : SAnimatedSlideSettings, target : CNode, translation : bool, rotation : bool ) : bool;
  805. import final function ActionAnimatedSlideToStaticAsync_P( settings : SAnimatedSlideSettings, target : Vector, heading : float, translation : bool, rotation : bool, out animProxy : CActionMoveAnimationProxy ) : bool;
  806. import final function ActionAnimatedSlideToAsync_P( settings : SAnimatedSlideSettings, target : CNode, translation : bool, rotation : bool, out animProxy : CActionMoveAnimationProxy ) : bool;
  807.  
  808. import final latent function ActionMatchTo( settings : SAnimatedSlideSettings, target : SActionMatchToTarget ) : bool;
  809. import final function ActionMatchToAsync( settings : SActionMatchToSettings, target : SActionMatchToTarget ) : bool;
  810. import final function ActionMatchToAsync_P( settings : SActionMatchToSettings, target : SActionMatchToTarget, out animProxy : CActionMoveAnimationProxy ) : bool;
  811.  
  812.  
  813.  
  814. import final function GetSkeletonType() : ESkeletonType;
  815.  
  816. import final function GetFallTauntEvent() : string;
  817.  
  818.  
  819. latent function RotateTo( target : Vector, optional duration : float ) : bool
  820. {
  821. var vec, pos : Vector;
  822. var heading : float;
  823. var res : bool;
  824.  
  825. if( duration <= 0.0 )
  826. duration = 0.2;
  827.  
  828. pos = GetWorldPosition();
  829. vec = target - GetWorldPosition();
  830. heading = VecHeading( vec );
  831. res = ActionSlideToWithHeading( pos, heading, duration );
  832. return res;
  833. }
  834.  
  835.  
  836. latent function RotateToNode( node : CNode, optional duration : float ) : bool
  837. {
  838. var res : bool;
  839. res = RotateTo( node.GetWorldPosition(), duration );
  840. return res;
  841. }
  842.  
  843.  
  844.  
  845. import final function SetErrorState( description : string );
  846.  
  847.  
  848. import final function GetRadius() : float;
  849.  
  850.  
  851. import final function GetVisualDebug() : CVisualDebug;
  852.  
  853.  
  854. event OnBehTreeEnded(){}
  855.  
  856.  
  857. import final function PlayVoiceset( priority : int, voiceset : string, optional breakCurrentSpeach : bool ) : bool;
  858.  
  859.  
  860. import final function StopAllVoicesets( optional cleanupQueue : bool );
  861.  
  862. import final function HasVoiceset( voiceset : string ) : EAsyncCheckResult;
  863.  
  864.  
  865. import final function IsRotatedTowards( node : CNode, optional maxAngle : float ) : bool;
  866.  
  867.  
  868. import final function IsRotatedTowardsPoint( point : Vector, optional maxAngle : float ) : bool;
  869.  
  870.  
  871.  
  872. import protected final function GetAliveFlag() : bool;
  873.  
  874. public final function IsAlive() : bool
  875. {
  876.  
  877. return GetAliveFlag();
  878. }
  879.  
  880.  
  881. public function Heal(amount : float)
  882. {
  883. if(amount <= 0)
  884. return;
  885.  
  886. if(UsesVitality())
  887. GainStat(BCS_Vitality, amount);
  888. else if (UsesEssence())
  889. GainStat(BCS_Essence, amount);
  890. }
  891.  
  892. public function SetHealthPerc( amount : float )
  893. {
  894. var stat : EBaseCharacterStats;
  895. var maxHealth : float;
  896. if(amount < 0)
  897. return;
  898.  
  899. if(UsesVitality())
  900. stat = BCS_Vitality;
  901. else if (UsesEssence())
  902. stat = BCS_Essence;
  903.  
  904. maxHealth = GetMaxHealth();
  905.  
  906. ForceSetStat( stat, amount * maxHealth );
  907. }
  908.  
  909. public function SetHealth( amount : float )
  910. {
  911. var stat : EBaseCharacterStats;
  912.  
  913. if(amount < 0)
  914. return;
  915.  
  916. if(UsesVitality())
  917. stat = BCS_Vitality;
  918. else if (UsesEssence())
  919. stat = BCS_Essence;
  920.  
  921. ForceSetStat( stat, amount );
  922. }
  923.  
  924.  
  925. import final function SetAlive( flag : bool );
  926.  
  927.  
  928. import final function IsExternalyControlled() : bool;
  929.  
  930.  
  931. import final function IsMoving() : bool;
  932.  
  933.  
  934. import final function GetMoveDestination() : Vector;
  935.  
  936.  
  937. import final function GetPositionOrMoveDestination() : Vector;
  938.  
  939. import final function GetVoicetag() : name;
  940.  
  941.  
  942. import final function EnableCollisions( val : bool );
  943.  
  944.  
  945.  
  946.  
  947.  
  948. import final function PredictWorldPosition( inTime : float ) : Vector;
  949.  
  950.  
  951. import final function GetHeadAngleHorizontal() : float;
  952.  
  953.  
  954. import final function GetHeadAngleVertical() : float;
  955.  
  956. import final function GetMovingAgentComponent() : CMovingAgentComponent;
  957.  
  958. import final function GetMorphedMeshManagerComponent() : CMorphedMeshManagerComponent;
  959.  
  960. import final function EnablePathEngineAgent( flag : bool );
  961.  
  962. import final function EnableCollisionInfoReportingForItem( itemId : SItemUniqueId, enable : bool );
  963.  
  964. import final function EnablePhysicalMovement( enable : bool ) : bool;
  965.  
  966. import final function EnableStaticCollisions( enable : bool ) : bool;
  967.  
  968. import final function EnableDynamicCollisions( enable : bool ) : bool;
  969.  
  970. import final function EnableCharacterCollisions( enable : bool ) : bool;
  971.  
  972. import final function PushInDirection( pusherPos : Vector, direction : Vector, optional speed : float, optional playAnimation : bool, optional applyRotation : bool );
  973.  
  974. import final function PushAway( pusher : CMovingAgentComponent, optional strength : float, optional speed : float );
  975.  
  976.  
  977. import final function IsRagdollObstacle() : bool;
  978.  
  979. import final function ForceAIBehavior( tree : IAITree, forceLevel : EArbitratorPriorities, optional forceEventName : name ) : int;
  980. import final function CancelAIBehavior( forceActionId : int ) : bool;
  981.  
  982. function IsFrozen() : bool
  983. {
  984. return HasBuff( EET_Frozen );
  985. }
  986.  
  987.  
  988.  
  989.  
  990.  
  991.  
  992.  
  993. import final function ClearRotationTarget();
  994.  
  995.  
  996. import final function SetRotationTarget( node : CNode, optional clamping : bool );
  997.  
  998.  
  999. import final function SetRotationTargetPos( position : Vector, optional clamping : bool );
  1000.  
  1001. final function SetRotationTargetWithTimeout( node : CNode, clamping : bool, optional timeout : float )
  1002. {
  1003. if( timeout == 0.0 )
  1004. {
  1005. timeout = 10.0;
  1006. }
  1007.  
  1008. SetRotationTarget( node, clamping );
  1009. AddTimer('ClearRotationTargetTimer', timeout, false );
  1010. }
  1011.  
  1012. final function ClearRotationTargetWithTimeout()
  1013. {
  1014. ClearRotationTarget();
  1015. RemoveTimer('ClearRotationTargetTimer');
  1016. }
  1017.  
  1018. timer function ClearRotationTargetTimer( td : float , id : int)
  1019. {
  1020. ClearRotationTarget();
  1021. }
  1022.  
  1023.  
  1024.  
  1025.  
  1026. import final function InAttackRange( target : CGameplayEntity, optional rangeName : name ) : bool;
  1027.  
  1028.  
  1029. import final function GetNearestPointInPersonalSpace( position : Vector ) : Vector;
  1030.  
  1031.  
  1032. import final function GetNearestPointInPersonalSpaceAt( myPosition : Vector, otherPosition : Vector ) : Vector;
  1033.  
  1034.  
  1035. import final function GatherEntitiesInAttackRange( out entities : array< CGameplayEntity >, optional rangeName : name );
  1036.  
  1037.  
  1038. function GetNearestPoint( position : Vector, distance : float ) : Vector
  1039. {
  1040. var vec : Vector;
  1041. vec = GetWorldPosition() - position;
  1042. return position + ( VecNormalize2D( vec ) ) * distance;
  1043. }
  1044.  
  1045.  
  1046. function GetNearestPointInBothPersonalSpaces( position : Vector ) : Vector
  1047. {
  1048. return GetNearestPointInBothPersonalSpacesAt( this.GetWorldPosition(), position );
  1049. }
  1050.  
  1051.  
  1052. function GetNearestPointInBothPersonalSpacesAt( myPosition : Vector, otherPosition : Vector ) : Vector
  1053. {
  1054. var pos : Vector;
  1055. var playerRadius : float;
  1056.  
  1057. playerRadius = ((CMovingPhysicalAgentComponent)thePlayer.GetMovingAgentComponent()).GetCapsuleRadius();
  1058. pos = playerRadius * VecNormalize2D( otherPosition - myPosition ) + this.GetNearestPointInPersonalSpaceAt( myPosition, otherPosition );
  1059.  
  1060. return pos;
  1061. }
  1062.  
  1063. function GetVectorBetweenTwoNearestPoints( actorA, actorB : CActor ) : Vector
  1064. {
  1065. var actorANearestPoint : Vector;
  1066. var actorBNearestPoint : Vector;
  1067.  
  1068. actorANearestPoint = actorA.GetNearestPointInPersonalSpace( actorB.GetWorldPosition() );
  1069. actorBNearestPoint = actorB.GetNearestPointInPersonalSpace( actorA.GetWorldPosition() );
  1070. return actorBNearestPoint - actorANearestPoint;
  1071. }
  1072.  
  1073. public function IsOnGround() : bool
  1074. {
  1075. var distFromGround : float;
  1076.  
  1077. distFromGround = GetDistanceFromGround(1.5);
  1078.  
  1079. if( distFromGround < 0.15f )
  1080. {
  1081. return true;
  1082. }
  1083. else if ( distFromGround < 1.5 )
  1084. {
  1085. if ( !MAC )
  1086. {
  1087. MAC = (CMovingPhysicalAgentComponent)GetMovingAgentComponent();
  1088. }
  1089.  
  1090. if ( MAC )
  1091. {
  1092. return MAC.IsOnGround();
  1093. }
  1094. }
  1095.  
  1096. return false;
  1097. }
  1098.  
  1099. public function IsFalling() : bool
  1100. {
  1101. if ( !MAC )
  1102. {
  1103. MAC = (CMovingPhysicalAgentComponent)GetMovingAgentComponent();
  1104. }
  1105.  
  1106. if ( MAC )
  1107. {
  1108. return MAC.IsFalling();
  1109. }
  1110. else
  1111. {
  1112. return false;
  1113. }
  1114. }
  1115.  
  1116. public function GetDistanceFromGround( _MaxTestDistance : float, optional _CollisionGroupNames : array<name> ) : float
  1117. {
  1118. var l_pos, l_ground, l_normal : Vector;
  1119. var l_groundZ : float;
  1120. var l_distance : float;
  1121.  
  1122. l_pos = GetWorldPosition();
  1123.  
  1124.  
  1125. if ( theGame.GetWorld().NavigationComputeZ( l_pos, l_pos.Z - _MaxTestDistance, l_pos.Z + _MaxTestDistance, l_groundZ ) )
  1126. {
  1127. l_distance = l_pos.Z - l_groundZ;
  1128. return l_distance;
  1129. }
  1130.  
  1131. return _MaxTestDistance;
  1132. }
  1133.  
  1134.  
  1135.  
  1136.  
  1137. import final function IsAttackableByPlayer() : bool;
  1138.  
  1139.  
  1140. import final function SetAttackableByPlayerPersistent( flag : bool );
  1141.  
  1142.  
  1143. import final function SetAttackableByPlayerRuntime( flag : bool, optional timeout : float );
  1144.  
  1145.  
  1146.  
  1147.  
  1148. import final function SetVisibility( isVisible : bool );
  1149. import final function GetVisibility() : bool;
  1150.  
  1151. public function SetGameplayVisibility( b : bool ) { isGameplayVisible = b; }
  1152. public function GetGameplayVisibility(): bool
  1153. {
  1154. if ( this.HasAbility( 'PersistentCameraLock' ) && thePlayer.GetTarget() == this && thePlayer.IsHardLockEnabled() )
  1155. return true;
  1156. else
  1157. return isGameplayVisible;
  1158. }
  1159.  
  1160.  
  1161. import final function SetAppearance( appearanceName : CName );
  1162.  
  1163.  
  1164. import final function GetAppearance() : name;
  1165.  
  1166.  
  1167. import final function GetAnimationTimeMultiplier() : float;
  1168.  
  1169. import final function CanStealOtherActor( actor : CActor) : bool;
  1170. import final function ResetClothAndDangleSimulation();
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176. import final function SetAnimationTimeMultiplier( mult : float );
  1177.  
  1178.  
  1179. //W3EE - Begin
  1180. public function IsWeaponDamaged() : bool
  1181. {
  1182. var heldWeapons : array<SItemUniqueId>;
  1183. var i : int;
  1184. var IsWeaponDamaged : bool;
  1185. var inv : CInventoryComponent;
  1186.  
  1187. inv = GetInventory();
  1188. heldWeapons = inv.GetHeldWeapons();
  1189.  
  1190. for ( i = 0; i < heldWeapons.Size(); i += 1 )
  1191. {
  1192. IsWeaponDamaged = inv.ItemHasTag( heldWeapons[i], 'DamagedWeapon' );
  1193.  
  1194. if ( IsWeaponDamaged )
  1195. break;
  1196. }
  1197.  
  1198. return IsWeaponDamaged;
  1199. }
  1200.  
  1201. public function SetAnimationSpeedMultiplier( mul : float, optional overrideExistingId : int, optional forceValue : bool ) : int
  1202. {
  1203. var causer : SAnimMultiplyCauser;
  1204. var finalMul : float;
  1205. var i,size : int;
  1206.  
  1207. size = animationMultiplierCausers.Size();
  1208.  
  1209. if( overrideExistingId != -1 )
  1210. {
  1211. for( i = 0; i < size; i += 1 )
  1212. {
  1213. if( animationMultiplierCausers[i].id == overrideExistingId )
  1214. {
  1215. animationMultiplierCausers[i].mul = mul;
  1216. SetAnimationTimeMultiplier( CalculateFinalAnimationSpeedMultiplier(forceValue) );
  1217. return animationMultiplierCausers[i].id;
  1218. }
  1219. }
  1220. }
  1221.  
  1222. nextFreeAnimMultCauserId = RandRange(1000, 1);
  1223. for( i = 0; i < size; i += 1 )
  1224. {
  1225. if( animationMultiplierCausers[i].id == nextFreeAnimMultCauserId )
  1226. {
  1227. nextFreeAnimMultCauserId = RandRange(1000, 1);
  1228. i = 0;
  1229. }
  1230. }
  1231.  
  1232. causer.mul = mul;
  1233. causer.id = nextFreeAnimMultCauserId;
  1234.  
  1235. nextFreeAnimMultCauserId += 1;
  1236.  
  1237. animationMultiplierCausers.PushBack( causer );
  1238.  
  1239.  
  1240. SetAnimationTimeMultiplier( CalculateFinalAnimationSpeedMultiplier(forceValue) );
  1241.  
  1242. return causer.id;
  1243. }
  1244.  
  1245. private function CalculateFinalAnimationSpeedMultiplier( optional forceValue : bool ) : float
  1246. {
  1247. var i,size : int;
  1248. var FinalMult : float = 1.f;
  1249. size = animationMultiplierCausers.Size();
  1250.  
  1251. if(size > 0)
  1252. {
  1253. for( i = 0; i < size; i += 1 )
  1254. {
  1255. FinalMult *= animationMultiplierCausers[i].mul;
  1256. }
  1257.  
  1258. return FinalMult;
  1259. }
  1260. return 1;
  1261. }
  1262.  
  1263.  
  1264. public function ResetAnimationSpeedMultiplier(id : int)
  1265. {
  1266. var i,size : int;
  1267.  
  1268. size = animationMultiplierCausers.Size();
  1269. if(size == 0)
  1270. return;
  1271.  
  1272. for(i=0; i<size; i+=1)
  1273. {
  1274. if(animationMultiplierCausers[i].id == id)
  1275. animationMultiplierCausers.Remove(animationMultiplierCausers[i]);
  1276. }
  1277.  
  1278. if(animationMultiplierCausers.Size()+1 != size)
  1279. {
  1280. LogAssert(false, "CAnimatedComponent.ResetAnimationMultiplier: invalid causer ID passed, nothing removed!");
  1281. return;
  1282. }
  1283.  
  1284. SetAnimationTimeMultiplier(CalculateFinalAnimationSpeedMultiplier());
  1285. }
  1286.  
  1287. public function ClearAnimationSpeedMultipliers()
  1288. {
  1289. animationMultiplierCausers.Clear();
  1290. SetAnimationTimeMultiplier( 1.0f );
  1291. }
  1292. //W3EE - End
  1293.  
  1294. import final function CalculateHeight() : float;
  1295.  
  1296.  
  1297. import final function SetBehaviorMimicVariable( varName : name, varValue : float ) : bool;
  1298.  
  1299.  
  1300.  
  1301.  
  1302.  
  1303.  
  1304. import final function DrawItems ( instant : bool, itemId : SItemUniqueId, optional itemId2 : SItemUniqueId, optional itemId3 : SItemUniqueId ) : bool;
  1305. import final function HolsterItems( instant : bool, itemId : SItemUniqueId, optional itemId2 : SItemUniqueId, optional itemId3 : SItemUniqueId ) : bool;
  1306.  
  1307. import final latent function DrawItemsLatent ( itemId : SItemUniqueId, optional itemId2 : SItemUniqueId, optional itemId3 : SItemUniqueId ) : bool;
  1308. import final latent function HolsterItemsLatent( itemId : SItemUniqueId, optional itemId2 : SItemUniqueId, optional itemId3 : SItemUniqueId ) : bool;
  1309.  
  1310. import final latent function DrawWeaponAndAttackLatent( itemId : SItemUniqueId ) : bool;
  1311.  
  1312. import latent function WaitForFinishedAllLatentItemActions() : bool;
  1313.  
  1314.  
  1315. import final function IssueRequiredItems( leftItem : name, rightItem : name );
  1316. import final function SetRequiredItems( leftItem : name, rightItem : name );
  1317.  
  1318. import final function IssueRequiredItemsGeneric( items : array<name>, slots : array<name> );
  1319. import final function SetRequiredItemsGeneric( items : array<name>, slots : array<name> );
  1320.  
  1321. import final latent function ProcessRequiredItems( optional instant : bool );
  1322.  
  1323. import final latent function ActivateAndSyncBehaviorWithItemsParallel( names : name, optional timeout : float ) : bool;
  1324. import final latent function ActivateAndSyncBehaviorWithItemsSequence( names : name, optional timeout : float ) : bool;
  1325.  
  1326.  
  1327. import final function UseItem( itemId : SItemUniqueId ) : bool;
  1328.  
  1329.  
  1330. import final function EmptyHands();
  1331.  
  1332.  
  1333.  
  1334. import final function PlayLine( stringId : int, subtitle : bool );
  1335.  
  1336. import final function PlayLineByStringKey( stringKey : string, subtitle : bool );
  1337.  
  1338. import final function EndLine();
  1339.  
  1340. import final function IsSpeaking( optional stringId : int ) : bool;
  1341.  
  1342. import final function PlayMimicAnimationAsync( animation : name ) : bool;
  1343.  
  1344. final latent function WaitForEndOfSpeach()
  1345. {
  1346. SleepOneFrame();
  1347.  
  1348. while( IsSpeaking() )
  1349. {
  1350. Sleep(0.1f);
  1351. }
  1352. }
  1353.  
  1354.  
  1355. import final function PlayPushAnimation( pushDirection : EPushingDirection );
  1356.  
  1357.  
  1358. import final function SetInteractionPriority( priority : EInteractionPriority );
  1359.  
  1360.  
  1361. import final function GetInteractionPriority() : EInteractionPriority;
  1362.  
  1363.  
  1364. import final function SetUnpushableTarget( target : CActor ) : CActor;
  1365.  
  1366.  
  1367. import final function SetOriginalInteractionPriority( priority : EInteractionPriority );
  1368.  
  1369.  
  1370. import final function RestoreOriginalInteractionPriority();
  1371.  
  1372.  
  1373. import final function GetOriginalInteractionPriority() : EInteractionPriority;
  1374.  
  1375.  
  1376. import final function SetGroupShadows( flag : bool );
  1377.  
  1378.  
  1379.  
  1380.  
  1381.  
  1382.  
  1383. public function GetAttackableNPCsAndPlayersInRange(range : float, optional maxResults : int, optional tag : name) : array <CActor>
  1384. {
  1385. if(maxResults <= 0)
  1386. maxResults = 1000000;
  1387.  
  1388. return GetNPCsAndPlayersInRange(range, maxResults, tag, FLAG_Attitude_Neutral + FLAG_Attitude_Hostile + FLAG_OnlyAliveActors + FLAG_ExcludeTarget);
  1389. }
  1390.  
  1391. public function GetNPCsAndPlayersInRange(range : float, optional maxResults : int, optional tag : name, optional queryFlags : int) : array <CActor>
  1392. {
  1393. var i : int;
  1394. var actors : array<CActor>;
  1395. var entities : array<CGameplayEntity>;
  1396. var actorEnt : CActor;
  1397.  
  1398.  
  1399. if((queryFlags & FLAG_Attitude_Neutral) == 0 && (queryFlags & FLAG_Attitude_Hostile) == 0 && (queryFlags & FLAG_Attitude_Friendly) == 0)
  1400. queryFlags = queryFlags | FLAG_Attitude_Neutral | FLAG_Attitude_Hostile | FLAG_Attitude_Friendly;
  1401.  
  1402.  
  1403. if(maxResults <= 0)
  1404. maxResults = 1000000;
  1405.  
  1406.  
  1407. FindGameplayEntitiesInSphere(entities, GetWorldPosition(), range, maxResults, tag, queryFlags, this);
  1408.  
  1409.  
  1410. for(i=0; i<entities.Size(); i+=1)
  1411. {
  1412. actorEnt = (CActor)entities[i];
  1413. if(actorEnt)
  1414. actors.PushBack(actorEnt);
  1415. }
  1416.  
  1417. return actors;
  1418. }
  1419.  
  1420. public function GetAttackableNPCsAndPlayersInCone(range : float, coneDir : float, coneAngle : float, optional maxResults : int, optional tag : name) : array <CActor>
  1421. {
  1422. if(maxResults <= 0)
  1423. maxResults = 1000000;
  1424.  
  1425. return GetNPCsAndPlayersInCone(range, coneDir, coneAngle, maxResults, tag, FLAG_Attitude_Neutral + FLAG_Attitude_Hostile + FLAG_OnlyAliveActors + FLAG_ExcludeTarget);
  1426. }
  1427.  
  1428. public function GetNPCsAndPlayersInCone(range : float, coneDir : float, coneAngle : float, optional maxResults : int, optional tag : name, optional queryFlags : int) : array <CActor>
  1429. {
  1430. var i : int;
  1431. var actors : array<CActor>;
  1432. var entities : array<CGameplayEntity>;
  1433. var actor : CActor;
  1434.  
  1435.  
  1436. if((queryFlags & FLAG_Attitude_Neutral) == 0 && (queryFlags & FLAG_Attitude_Hostile) == 0 && (queryFlags & FLAG_Attitude_Friendly) == 0)
  1437. queryFlags = queryFlags | FLAG_Attitude_Neutral | FLAG_Attitude_Hostile | FLAG_Attitude_Friendly;
  1438.  
  1439.  
  1440. if(maxResults <= 0)
  1441. maxResults = 1000000;
  1442.  
  1443.  
  1444. FindGameplayEntitiesInCone(entities, GetWorldPosition(), coneDir, coneAngle, range, maxResults, tag, queryFlags, this);
  1445.  
  1446. for(i=0; i<entities.Size(); i+=1)
  1447. {
  1448. actor = (CActor)entities[i];
  1449. if(actor)
  1450. actors.PushBack(actor);
  1451. }
  1452.  
  1453. return actors;
  1454. }
  1455.  
  1456.  
  1457.  
  1458. // W3EE - Begin
  1459. private var injurySystem : W3EEInjurySystem;
  1460. public function GetInjuryManager() : W3EEInjurySystem
  1461. {
  1462. return injurySystem;
  1463. }
  1464.  
  1465. public function InitInjuryManager()
  1466. {
  1467. injurySystem = new W3EEInjurySystem in this;
  1468. injurySystem.Init(this);
  1469. }
  1470.  
  1471. timer function StopHeadHitEffect( dt : float, id : int )
  1472. {
  1473. StopEffect('stunned_ghost');
  1474. }
  1475.  
  1476. public timer function PlayActorHitAnimation( dt : float, id : int )
  1477. {
  1478. var damageAction : W3DamageAction;
  1479. var hitReaction : EHitReactionType;
  1480.  
  1481. if( ((CNewNPC)this).IsFlying() || HasBuff(EET_Stagger) || HasBuff(EET_LongStagger) || HasBuff(EET_Knockdown) || HasBuff(EET_HeavyKnockdown) || HasBuff(EET_Immobilized) || HasBuff(EET_CounterStrikeHit) )
  1482. return;
  1483.  
  1484. damageAction = new W3DamageAction in theGame.damageMgr;
  1485. damageAction.Initialize(GetWitcherPlayer(), this, GetWitcherPlayer(), "ParriedCounter", EHRT_Light, CPS_Undefined, true, false, false, false);
  1486. damageAction.SetHitAnimationPlayType(EAHA_ForceYes);
  1487. damageAction.SetCannotReturnDamage(true);
  1488. damageAction.SetSuppressHitSounds(true);
  1489. damageAction.SetCanPlayHitParticle(false);
  1490. theGame.damageMgr.ProcessAction(damageAction);
  1491. delete damageAction;
  1492. }
  1493.  
  1494. public timer function RollAttackStumble( dt : float, id : int )
  1495. {
  1496. var damageAction : W3DamageAction;
  1497. var hitReaction : EHitReactionType;
  1498.  
  1499. if( ((CNewNPC)this).IsFlying() || HasBuff(EET_Stagger) || HasBuff(EET_LongStagger) || HasBuff(EET_Knockdown) || HasBuff(EET_HeavyKnockdown) || HasBuff(EET_Immobilized) || HasBuff(EET_CounterStrikeHit) )
  1500. return;
  1501.  
  1502. if( RandRange(100,0) <= 35 )
  1503. {
  1504. damageAction = new W3DamageAction in theGame.damageMgr;
  1505. if( RandRange(100,0) <= 35 )
  1506. hitReaction = EHRT_Heavy;
  1507. else
  1508. hitReaction = EHRT_Light;
  1509. damageAction.Initialize(NULL, this, NULL, "CombatInjury", hitReaction, CPS_Undefined, false, false, false, true);
  1510. damageAction.SetHitAnimationPlayType(EAHA_ForceYes);
  1511. damageAction.SetCannotReturnDamage(true);
  1512. damageAction.SetSuppressHitSounds(true);
  1513. damageAction.SetCanPlayHitParticle(false);
  1514. theGame.damageMgr.ProcessAction(damageAction);
  1515. delete damageAction;
  1516. }
  1517. }
  1518.  
  1519. public timer function RollRunningAttackStumble( dt : float, id : int )
  1520. {
  1521. var damageAction : W3DamageAction;
  1522. var hitReaction : EHitReactionType;
  1523.  
  1524. if( ((CNewNPC)this).IsFlying() || HasBuff(EET_Stagger) || HasBuff(EET_LongStagger) || HasBuff(EET_Knockdown) || HasBuff(EET_HeavyKnockdown) || HasBuff(EET_Immobilized) || HasBuff(EET_CounterStrikeHit) )
  1525. return;
  1526.  
  1527. if( RandRange(100,0) <= 45 )
  1528. {
  1529. damageAction = new W3DamageAction in theGame.damageMgr;
  1530. if( RandRange(100,0) <= 45 )
  1531. hitReaction = EHRT_Heavy;
  1532. else
  1533. hitReaction = EHRT_Light;
  1534. damageAction.Initialize(NULL, this, NULL, "CombatInjury", hitReaction, CPS_Undefined, false, false, false, true);
  1535. SetOverrideDirection(true);
  1536. damageAction.SetHitAnimationPlayType(EAHA_ForceYes);
  1537. damageAction.SetCannotReturnDamage(true);
  1538. damageAction.SetSuppressHitSounds(true);
  1539. damageAction.SetCanPlayHitParticle(false);
  1540. theGame.damageMgr.ProcessAction(damageAction);
  1541. SetOverrideDirection(false);
  1542. delete damageAction;
  1543. }
  1544. }
  1545. // W3EE - End
  1546.  
  1547. event OnSpawned( spawnData : SEntitySpawnData )
  1548. {
  1549. super.OnSpawned(spawnData);
  1550.  
  1551. AddAnimEventCallback( 'RotateEvent', 'OnAnimEvent_RotateEvent' );
  1552. AddAnimEventCallback( 'RotateAwayEvent', 'OnAnimEvent_RotateAwayEvent' );
  1553.  
  1554. AddAnimEventCallback( 'Shake0', 'OnAnimEvent_Shake0' );
  1555. AddAnimEventCallback( 'Shake1', 'OnAnimEvent_Shake1' );
  1556. AddAnimEventCallback( 'Shake2', 'OnAnimEvent_Shake2' );
  1557. AddAnimEventCallback( 'Shake3', 'OnAnimEvent_Shake3' );
  1558. AddAnimEventCallback( 'Shake4', 'OnAnimEvent_Shake4' );
  1559. AddAnimEventCallback( 'Shake5', 'OnAnimEvent_Shake5' );
  1560. AddAnimEventCallback( 'DropItem', 'OnAnimEvent_DropItem' );
  1561. AddAnimEventCallback( 'OnGround', 'OnAnimEvent_OnGround' );
  1562. AddAnimEventCallback( 'Death', 'OnAnimEvent_Death' );
  1563. AddAnimEventCallback( 'MountHorseType', 'OnAnimEvent_MountHorseType' );
  1564. AddAnimEventCallback( 'HorseRidingOn', 'OnAnimEvent_HorseRidingOn' );
  1565. AddAnimEventCallback( 'item_track_hack_reading_book', 'OnAnimEvent_item_track_hack_reading_book' );
  1566. AddAnimEventCallback( 'item_track_hack_reading_book_unmount', 'OnAnimEvent_item_track_hack_reading_book_unmount' );
  1567.  
  1568. effectsUpdateTicking = false;
  1569. SetBehaviorVariable( 'CriticalStateType', (int)ECST_None );
  1570.  
  1571. if(!spawnData.restored)
  1572. {
  1573. SetAbilityManager();
  1574. if(abilityManager)
  1575. abilityManager.Init(this, GetCharacterStats(), false, theGame.GetSpawnDifficultyMode());
  1576.  
  1577. SetEffectManager();
  1578. }
  1579. else
  1580. {
  1581. if(abilityManager)
  1582. abilityManager.Init(this, GetCharacterStats(), true, theGame.GetSpawnDifficultyMode());
  1583.  
  1584. if(effectManager)
  1585. effectManager.OnLoad(this);
  1586. else
  1587. SetEffectManager();
  1588. }
  1589.  
  1590. if(abilityManager)
  1591. abilityManager.PostInit();
  1592.  
  1593. //MODEnableMimics
  1594. activateMimicsAndHiResShadows(this);
  1595. //MODEnableMimics END
  1596. ClearAnimationSpeedMultipliers();
  1597. SetGameplayVisibility( true );
  1598.  
  1599. MountHorseIfNeeded();
  1600.  
  1601.  
  1602. if(effectManager)
  1603. ResumeStaminaRegen( 'SignCast' );
  1604.  
  1605. // W3EE - Begom
  1606. InitInjuryManager();
  1607. AddTimer('SetIsQuest', 1.5f, false);
  1608. // W3EE - End
  1609. }
  1610.  
  1611. protected function SetEffectManager()
  1612. {
  1613. effectManager = new W3EffectManager in this;
  1614. effectManager.Initialize( this );
  1615. }
  1616.  
  1617. public function MountHorseIfNeeded()
  1618. {
  1619. var vehicle : CVehicleComponent;
  1620. if ( usedVehicle )
  1621. {
  1622. return;
  1623. }
  1624.  
  1625. usedVehicle = (CGameplayEntity)EntityHandleGet(usedVehicleHandle);
  1626.  
  1627. if( usedVehicle )
  1628. {
  1629.  
  1630. if ( VecDistance2D( usedVehicle.GetWorldPosition(), this.GetWorldPosition() ) > 100 )
  1631. {
  1632. usedVehicle = NULL;
  1633. EntityHandleSet( usedVehicleHandle, NULL );
  1634. }
  1635. else
  1636. {
  1637. vehicle = (CVehicleComponent)usedVehicle.GetComponentByClassName('CVehicleComponent');
  1638. vehicle.Mount( this, VMT_ImmediateUse, EVS_driver_slot );
  1639. }
  1640. }
  1641. }
  1642.  
  1643. public function UpdateSoundInfo()
  1644. {
  1645. var cr4HumanoidCombatComponent : CR4HumanoidCombatComponent;
  1646. var defMapping : SSoundInfoMapping;
  1647.  
  1648. if(IsHuman())
  1649. {
  1650. cr4HumanoidCombatComponent = (CR4HumanoidCombatComponent)GetComponentByClassName( 'CR4HumanoidCombatComponent' );
  1651. if( cr4HumanoidCombatComponent )
  1652. {
  1653. cr4HumanoidCombatComponent.UpdateSoundInfo();
  1654. defMapping = cr4HumanoidCombatComponent.GetDefaultSoundInfoMapping();
  1655. if( defMapping.isDefault )
  1656. {
  1657. if( defMapping.soundTypeIdentification != 'default' && defMapping.soundTypeIdentification != '' )
  1658. {
  1659. SoundSwitch( "armour_type_movement", defMapping.soundTypeIdentification );
  1660. }
  1661. }
  1662. }
  1663. }
  1664. }
  1665.  
  1666. timer function DelaySoundInfoUpdate(dt : float , id : int)
  1667. {
  1668. UpdateSoundInfo();
  1669. }
  1670.  
  1671. event OnForceUpdateSoundInfo()
  1672. {
  1673. UpdateSoundInfo();
  1674. }
  1675.  
  1676. event OnAppearanceChanged()
  1677. {
  1678. AddTimer('DelaySoundInfoUpdate', 1);
  1679. }
  1680.  
  1681. public timer function RestoreOriginalInteractionPriorityTimer( optional deltaTime : float , id : int)
  1682. {
  1683. RestoreOriginalInteractionPriority();
  1684. }
  1685.  
  1686.  
  1687. public function CanBeTeleporting() : bool
  1688. {
  1689. var temp : EMonsterCategory;
  1690. var temp2 : name;
  1691. var temp3, temp4, teleports : bool;
  1692.  
  1693. theGame.GetMonsterParamsForActor(this, temp, temp2, teleports, temp3, temp4);
  1694. return teleports;
  1695. }
  1696.  
  1697. public function CanBeStrafed() : bool
  1698. {
  1699. var temp : CMonsterParam;
  1700.  
  1701. theGame.GetMonsterParamForActor( this, temp );
  1702. return temp.canBeStrafed;
  1703. }
  1704.  
  1705. public function CanBeTargeted() : bool
  1706. {
  1707. var temp : EMonsterCategory;
  1708. var temp2 : name;
  1709. var temp3, temp4, canBeTargeted : bool;
  1710.  
  1711. if ( !IsTargetableByPlayer() )
  1712. return false;
  1713.  
  1714. theGame.GetMonsterParamsForActor(this, temp, temp2, temp3, canBeTargeted, temp4);
  1715. return canBeTargeted;
  1716. }
  1717.  
  1718. private var cachedIsHuman : int; default cachedIsHuman = -1;
  1719. public function IsHuman() : bool
  1720. {
  1721. var monsterCategory : EMonsterCategory;
  1722. var temp2 : name;
  1723. var temp3, temp4, canBeTargeted : bool;
  1724.  
  1725. if ( cachedIsHuman != -1 )
  1726. return cachedIsHuman > 0;
  1727.  
  1728. theGame.GetMonsterParamsForActor(this, monsterCategory, temp2, temp3, canBeTargeted, temp4);
  1729.  
  1730. if ( monsterCategory == MC_Human )
  1731. cachedIsHuman = 1;
  1732. else
  1733. cachedIsHuman = 0;
  1734.  
  1735. return cachedIsHuman;
  1736. }
  1737.  
  1738. private var cachedIsWoman : int; default cachedIsWoman = -1;
  1739. public function IsWoman() : bool
  1740. {
  1741. if ( cachedIsWoman != -1 )
  1742. return cachedIsWoman > 0;
  1743.  
  1744. if ( GetMovingAgentComponent().GetName() == "woman_base" || GetMovingAgentComponent().GetName() == "noble_woman_base" )
  1745. cachedIsWoman = 1;
  1746. else
  1747. cachedIsWoman = 0;
  1748.  
  1749. return cachedIsWoman;
  1750. }
  1751.  
  1752. private var cachedIsMan : int; default cachedIsMan = -1;
  1753. public function IsMan() : bool
  1754. {
  1755. if ( cachedIsMan != -1 )
  1756. return cachedIsMan > 0;
  1757.  
  1758. if ( GetMovingAgentComponent().GetName() == "man_base" )
  1759. cachedIsMan = 1;
  1760. else
  1761. cachedIsMan = 0;
  1762.  
  1763. return cachedIsMan;
  1764. }
  1765.  
  1766. private var cachedIsMonster : int; default cachedIsMonster = -1;
  1767. public function IsMonster() : bool
  1768. {
  1769. var monsterCategory : EMonsterCategory;
  1770. var temp2 : name;
  1771. var temp3, temp4, canBeTargeted : bool;
  1772.  
  1773. if ( cachedIsMonster != -1 )
  1774. return cachedIsMonster > 0;
  1775.  
  1776. theGame.GetMonsterParamsForActor(this, monsterCategory, temp2, temp3, canBeTargeted, temp4);
  1777.  
  1778. if ( MonsterCategoryIsMonster( monsterCategory ) )
  1779. cachedIsMonster = 1;
  1780. else
  1781. cachedIsMonster = 0;
  1782.  
  1783. return cachedIsMonster;
  1784. }
  1785.  
  1786. private var cachedIsAnimal : int; default cachedIsAnimal = -1;
  1787. public function IsAnimal() : bool
  1788. {
  1789. var monsterCategory : EMonsterCategory;
  1790. var tmpName : name;
  1791. var tmpBool : bool;
  1792.  
  1793. if ( cachedIsAnimal != -1 )
  1794. return cachedIsAnimal > 0;
  1795.  
  1796. theGame.GetMonsterParamsForActor(this, monsterCategory, tmpName, tmpBool, tmpBool, tmpBool);
  1797.  
  1798. if ( monsterCategory == MC_Animal )
  1799. cachedIsAnimal = 1;
  1800. else
  1801. cachedIsAnimal = 0;
  1802.  
  1803. return cachedIsAnimal;
  1804. }
  1805.  
  1806. private var cachedIsVampire : int; default cachedIsVampire = -1;
  1807. public function IsVampire() : bool
  1808. {
  1809. var monsterCategory : EMonsterCategory;
  1810. var tmpName : name;
  1811. var tmpBool : bool;
  1812.  
  1813. if ( cachedIsVampire != -1 )
  1814. return cachedIsVampire > 0;
  1815.  
  1816. theGame.GetMonsterParamsForActor(this, monsterCategory, tmpName, tmpBool, tmpBool, tmpBool);
  1817.  
  1818. if ( monsterCategory == MC_Vampire )
  1819. cachedIsVampire = 1;
  1820. else
  1821. cachedIsVampire = 0;
  1822.  
  1823. return cachedIsVampire;
  1824. }
  1825.  
  1826. protected function SetAbilityManager();
  1827.  
  1828. timer function CheckBlockedAbilities(dt : float, id : int)
  1829. {
  1830. var nextCallTime : float;
  1831.  
  1832. nextCallTime = abilityManager.CheckBlockedAbilities(dt);
  1833.  
  1834. if(nextCallTime != -1)
  1835. AddTimer('CheckBlockedAbilities', nextCallTime, , , , true);
  1836. }
  1837.  
  1838. protected function GetKillAction( source : name, optional ignoreImmortalityMode : bool, optional attacker : CGameplayEntity, optional playHitSound : bool ) : W3DamageAction
  1839. {
  1840. var vit, ess : float;
  1841. var action : W3DamageAction;
  1842. var dmg : CDamageData;
  1843.  
  1844. vit = abilityManager.GetStatMax(BCS_Vitality);
  1845. ess = abilityManager.GetStatMax(BCS_Essence);
  1846.  
  1847. if ( !IsNameValid(source) )
  1848. source = 'Kill';
  1849.  
  1850. action = new W3DamageAction in theGame.damageMgr;
  1851. action.Initialize(attacker, this, theGame, source, EHRT_None, CPS_Undefined, false, false, false, true);
  1852. action.AddDamage(theGame.params.DAMAGE_NAME_DIRECT, MaxF(vit,ess));
  1853. action.SetIgnoreImmortalityMode(ignoreImmortalityMode);
  1854. action.SetCanPlayHitParticle(false);
  1855. action.SetCannotReturnDamage(true);
  1856. action.SetSuppressHitSounds(!playHitSound);
  1857. return action;
  1858. }
  1859.  
  1860. function Kill(source : name, optional ignoreImmortalityMode : bool, optional attacker : CGameplayEntity, optional playHitSound : bool)
  1861. {
  1862. var action : W3DamageAction;
  1863.  
  1864. if ( theGame.CanLog() )
  1865. {
  1866. LogDMHits( "CActor.Kill: called for actor <<" + this + ">> with source <<" + source + ">>" );
  1867. }
  1868.  
  1869. action = GetKillAction( source, ignoreImmortalityMode, attacker, playHitSound );
  1870.  
  1871. theGame.damageMgr.ProcessAction(action);
  1872.  
  1873. delete action;
  1874. }
  1875.  
  1876.  
  1877. private function InterfaceKill( force : bool, attacker : CActor )
  1878. {
  1879. Kill( 'From Code', force);
  1880. }
  1881.  
  1882.  
  1883.  
  1884.  
  1885.  
  1886.  
  1887. import function EnableStaticLookAt( point : Vector, duration : float );
  1888.  
  1889.  
  1890. import function EnableDynamicLookAt( node : CNode, duration : float );
  1891.  
  1892.  
  1893. import function DisableLookAt();
  1894.  
  1895.  
  1896. import function SetLookAtMode( mode : ELookAtMode );
  1897.  
  1898.  
  1899. import function ResetLookAtMode( mode : ELookAtMode );
  1900.  
  1901.  
  1902.  
  1903. public function HasStaminaToParry( attActionName : name ) : bool
  1904. {
  1905. var multiplier : float;
  1906.  
  1907. if( IsHeavyAttack( attActionName ) )
  1908. multiplier = theGame.params.HEAVY_STRIKE_COST_MULTIPLIER;
  1909.  
  1910. return HasStaminaToUseAction( ESAT_Parry, '', 0, multiplier );
  1911. }
  1912.  
  1913. public function CanParryAttack() : bool
  1914. {
  1915. return bParryEnabled && IsGuarded();
  1916. }
  1917.  
  1918. public function a() : bool
  1919. {
  1920. return bParryEnabled;
  1921. }
  1922. public function b() : bool
  1923. {
  1924. return IsGuarded();
  1925. }
  1926.  
  1927. public function CanCounterParryAttack(attActionName : name ) : bool
  1928. {
  1929. return CanParryAttack() && CanPerformCounter() && HasStaminaToParry(attActionName);
  1930. }
  1931.  
  1932. public function FistFightCheck( target, attacker : CActor, out bothUsingFists : bool ) : bool
  1933. {
  1934. var i, j, size, size2 : int;
  1935. var targetFists, attackerFists : array<SItemUniqueId>;
  1936. var targetInv, attackerInv : CInventoryComponent;
  1937.  
  1938. targetInv = target.GetInventory();
  1939. targetFists = targetInv.GetItemsByCategory( 'fist' );
  1940. size = targetFists.Size();
  1941.  
  1942. if ( size <= 0 )
  1943. return true;
  1944.  
  1945. attackerInv = attacker.GetInventory();
  1946. attackerFists = attackerInv.GetItemsByCategory( 'fist' );
  1947. size2 = attackerFists.Size();
  1948.  
  1949. if ( size2 > 0 )
  1950. {
  1951. for ( i = 0; i < size ; i += 1 )
  1952. {
  1953. if ( targetInv.IsItemHeld( targetFists[i] ) )
  1954. {
  1955. for ( j = 0; j < size2 ; j += 1 )
  1956. {
  1957. if ( attackerInv.IsItemHeld( attackerFists[j] ) )
  1958. {
  1959. bothUsingFists = true;
  1960. return true;
  1961. }
  1962. }
  1963. return false;
  1964. }
  1965. }
  1966. return true;
  1967. }
  1968. else
  1969. {
  1970. for ( i = 0; i < size ; i += 1 )
  1971. {
  1972. if ( targetInv.IsItemHeld( targetFists[i] ) )
  1973. return false;
  1974. }
  1975. return true;
  1976. }
  1977. }
  1978.  
  1979.  
  1980. public function ProcessSwordOrFistHitReaction( target, attacker : CActor ) : float
  1981. {
  1982. var i, j, size : int;
  1983. var targetFists, attackerFists : array<SItemUniqueId>;
  1984.  
  1985. targetFists = target.GetInventory().GetItemsByCategory( 'fist' );
  1986. size = targetFists.Size();
  1987.  
  1988. if ( size > 0 )
  1989. {
  1990. attackerFists = attacker.GetInventory().GetItemsByCategory( 'fist' );
  1991.  
  1992. for ( i = 0; i < size ; i += 1 )
  1993. {
  1994. if ( target.GetInventory().IsItemHeld( targetFists[i] ) )
  1995. {
  1996. for ( j = 0; j < attackerFists.Size() ; j += 1 )
  1997. {
  1998. if ( attacker.GetInventory().IsItemHeld( attackerFists[j] ) )
  1999. return 1.f;
  2000. }
  2001.  
  2002. return 0;
  2003. }
  2004. }
  2005. }
  2006.  
  2007. return 0.f;
  2008. }
  2009.  
  2010.  
  2011. public function IsWeaponHeld( itemCategory : name ) : bool
  2012. {
  2013. var items : array <SItemUniqueId>;
  2014. var i : int;
  2015. var inv : CInventoryComponent;
  2016.  
  2017. inv = GetInventory();
  2018. items = inv.GetItemsByCategory( itemCategory );
  2019.  
  2020. for( i = 0 ; i < items.Size(); i += 1 )
  2021. {
  2022. if( inv.IsItemHeld(items[i]) )
  2023. {
  2024. return true;
  2025. }
  2026. }
  2027. return false;
  2028. }
  2029.  
  2030.  
  2031. public function IsAnyWeaponHeld() : bool
  2032. {
  2033. return IsWeaponHeld('silversword') || IsWeaponHeld('steelsword') || IsWeaponHeld('fist');
  2034. }
  2035.  
  2036. public function IsSecondaryWeaponHeld() : bool
  2037. {
  2038. var heldWeapons : array <SItemUniqueId>;
  2039. var isSecondaryWeaponHeld : bool;
  2040. var i : int;
  2041. var inv : CInventoryComponent;
  2042.  
  2043. inv = GetInventory();
  2044. heldWeapons = inv.GetHeldWeapons();
  2045. for ( i = 0; i < heldWeapons.Size(); i += 1 )
  2046. {
  2047. isSecondaryWeaponHeld = inv.ItemHasTag( heldWeapons[i], 'SecondaryWeapon' );
  2048.  
  2049. if ( isSecondaryWeaponHeld )
  2050. break;
  2051. }
  2052.  
  2053. return isSecondaryWeaponHeld;
  2054. }
  2055.  
  2056. public function IsSwordWooden() : bool
  2057. {
  2058. var heldWeapons : array<SItemUniqueId>;
  2059. var i : int;
  2060. var isSwordWooden : bool;
  2061. var inv : CInventoryComponent;
  2062.  
  2063. inv = GetInventory();
  2064. heldWeapons = inv.GetHeldWeapons();
  2065.  
  2066. for ( i = 0; i < heldWeapons.Size(); i += 1 )
  2067. {
  2068. isSwordWooden = inv.ItemHasTag( heldWeapons[i], 'Wooden' );
  2069.  
  2070. if ( isSwordWooden )
  2071. break;
  2072. }
  2073.  
  2074. return isSwordWooden;
  2075. }
  2076.  
  2077. public function IsDeadlySwordHeld() : bool
  2078. {
  2079. if ( IsSwordWooden() )
  2080. return false;
  2081.  
  2082. if ( IsSecondaryWeaponHeld() )
  2083. return false;
  2084.  
  2085. if ( IsWeaponHeld( 'fist' ) )
  2086. return false;
  2087.  
  2088. return true;
  2089. }
  2090.  
  2091. public function SetIsCurrentlyDodging(b : bool, optional isRolling : bool)
  2092. {
  2093. isCurrentlyDodging = b;
  2094.  
  2095.  
  2096. theGame.GetBehTreeReactionManager().CreateReactionEventIfPossible( this, 'MoveNoise', -1, 30.0f, -1.f, -1, true );
  2097. }
  2098.  
  2099. public final function IsCurrentlyDodging() : bool {return isCurrentlyDodging;}
  2100.  
  2101. public final function SetParryEnabled( flag : bool )
  2102. {
  2103. bParryEnabled = flag;
  2104. }
  2105.  
  2106. public final function GetLastAttackRangeName() : name
  2107. {
  2108. return lastAttackRangeName;
  2109. }
  2110.  
  2111. public function CanPerformCounter() : bool
  2112. {
  2113. return bCanPerformCounter;
  2114. }
  2115.  
  2116.  
  2117. public function IsGuarded() : bool
  2118. {
  2119. return bIsGuarded;
  2120. }
  2121.  
  2122. function SetGuarded( flag : bool )
  2123. {
  2124. if( bIsGuarded == true && flag == false )
  2125. {
  2126. lowerGuardTime = theGame.GetEngineTimeAsSeconds();
  2127. }
  2128. bIsGuarded = flag;
  2129. SetBehaviorVariable( 'bIsGuarded', (int)bIsGuarded);
  2130. }
  2131.  
  2132. public final function CanGuard() : bool
  2133. {
  2134. // W3EE - Begin
  2135. var l_delayToWait : float = 0.f; //CalculateAttributeValue( GetAttributeValue('delay_between_raise_guard') );
  2136. // W3EE - End
  2137. var l_currentDelay : float;
  2138.  
  2139. if( l_delayToWait <= 0 ) return true;
  2140.  
  2141. l_currentDelay = theGame.GetEngineTimeAsSeconds() - lowerGuardTime;
  2142. if( l_currentDelay >= l_delayToWait )
  2143. {
  2144. return true;
  2145. }
  2146.  
  2147. return false;
  2148. }
  2149.  
  2150. final function DisableHitAnimFor( time : float )
  2151. {
  2152. this.SetCanPlayHitAnim(false);
  2153. AddTimer('EnableHitAnim', time, false, , ,true, true);
  2154. }
  2155.  
  2156. public final function UseAdditiveHit( ) : bool
  2157. {
  2158. return useAdditiveHits;
  2159. }
  2160. public final function SetUseAdditiveHit( _Flag : bool, optional _CriticalCancelAdditiveHit : bool, optional _OneTimeActivation : bool )
  2161. {
  2162. if ( _OneTimeActivation )
  2163. oneTimeAdditiveHit = _OneTimeActivation;
  2164. else
  2165. useAdditiveHits = _Flag;
  2166. criticalCancelAdditiveHit = _CriticalCancelAdditiveHit;
  2167. }
  2168. public final function UseAdditiveCriticalState() : bool
  2169. {
  2170. return useAdditiveCriticalStateAnim;
  2171. }
  2172. public final function SetUseAdditiveCriticalStateAnim( flag : bool )
  2173. {
  2174. useAdditiveCriticalStateAnim = flag;
  2175. }
  2176. function SetCanPlayHitAnim( flag : bool )
  2177. {
  2178. RemoveTimer('EnableHitAnim');
  2179. canPlayHitAnim = flag;
  2180. }
  2181. final function CanPlayHitAnim() : bool
  2182. {
  2183. return canPlayHitAnim;
  2184. }
  2185. final function StopRotateEventAdjustments()
  2186. {
  2187. var movementAdjustor : CMovementAdjustor = GetMovingAgentComponent().GetMovementAdjustor();
  2188. movementAdjustor.Cancel( movementAdjustor.GetRequest( 'RotateEvent' ) );
  2189. }
  2190. public function GetCriticalCancelAdditiveHit() : bool
  2191. {
  2192. return criticalCancelAdditiveHit;
  2193. }
  2194.  
  2195.  
  2196.  
  2197.  
  2198. public final function GetAbilityManager() : W3AbilityManager
  2199. {
  2200. return abilityManager;
  2201. }
  2202.  
  2203.  
  2204.  
  2205.  
  2206.  
  2207.  
  2208. public function DrainStamina(action : EStaminaActionType, optional fixedCost : float, optional fixedDelay : float, optional abilityName : name, optional dt : float, optional costMult : float)
  2209. {
  2210. if(abilityManager && abilityManager.IsInitialized() && IsAlive())
  2211. abilityManager.DrainStamina(action, fixedCost, fixedDelay, abilityName, dt, costMult);
  2212. }
  2213.  
  2214. public function DrainAir( cost : float, optional regenDelay : float )
  2215. {
  2216. if(abilityManager && abilityManager.IsInitialized() && IsAlive())
  2217. abilityManager.DrainAir(cost, regenDelay);
  2218. }
  2219.  
  2220. public function DrainSwimmingStamina( cost : float, optional regenDelay : float )
  2221. {
  2222. if(abilityManager && abilityManager.IsInitialized() && IsAlive())
  2223. abilityManager.DrainSwimmingStamina(cost, regenDelay);
  2224. }
  2225.  
  2226. public function DrainMorale(amount : float)
  2227. {
  2228. if(abilityManager && abilityManager.IsInitialized() && IsAlive())
  2229. abilityManager.DrainMorale(amount);
  2230. }
  2231.  
  2232. public function DrainVitality(amount : float)
  2233. {
  2234. if(abilityManager && abilityManager.IsInitialized() && IsAlive())
  2235. abilityManager.DrainVitality(amount);
  2236. }
  2237.  
  2238. public function DrainEssence(amount : float)
  2239. {
  2240. if(abilityManager && abilityManager.IsInitialized() && IsAlive())
  2241. abilityManager.DrainEssence(amount);
  2242. }
  2243.  
  2244. public function AddPanic( amount : float )
  2245. {
  2246. if(abilityManager && abilityManager.IsInitialized() && IsAlive())
  2247. abilityManager.AddPanic( amount );
  2248. }
  2249.  
  2250. public function GainStat( stat : EBaseCharacterStats, amount : float )
  2251. {
  2252. if(abilityManager && abilityManager.IsInitialized() && IsAlive())
  2253. abilityManager.GainStat(stat, amount);
  2254. }
  2255.  
  2256. public function UpdateStatMax(stat : EBaseCharacterStats)
  2257. {
  2258. if(abilityManager && abilityManager.IsInitialized() && IsAlive())
  2259. abilityManager.UpdateStatMax(stat);
  2260. }
  2261.  
  2262. public function ForceSetStat(stat : EBaseCharacterStats, val : float)
  2263. {
  2264. if(abilityManager && abilityManager.IsInitialized() && IsAlive())
  2265. abilityManager.ForceSetStat(stat, val);
  2266. }
  2267.  
  2268.  
  2269. public function GetPowerStatValue(stat : ECharacterPowerStats, optional abilityName : name, optional ignoreDeath : bool) : SAbilityAttributeValue
  2270. {
  2271. var null : SAbilityAttributeValue;
  2272.  
  2273. if(abilityManager && abilityManager.IsInitialized() && (ignoreDeath || IsAlive()) )
  2274. return abilityManager.GetPowerStatValue(stat, abilityName);
  2275.  
  2276. return null;
  2277. }
  2278.  
  2279.  
  2280. public function GetResistValue(stat : ECharacterDefenseStats, out points : float, out percents : float)
  2281. {
  2282. points = 0;
  2283. percents = 0;
  2284.  
  2285. if(abilityManager && abilityManager.IsInitialized() && IsAlive())
  2286. abilityManager.GetResistValue(stat, points, percents);
  2287. }
  2288.  
  2289. public function ResumeEffects(type : EEffectType, sourceName : name)
  2290. {
  2291. if(effectManager && effectManager.IsReady())
  2292. effectManager.ResumeEffects(type, sourceName);
  2293. }
  2294.  
  2295.  
  2296.  
  2297.  
  2298. public function PauseEffects(type : EEffectType, sourceName : name, optional singleLock : bool, optional duration : float, optional useMaxDuration : bool)
  2299. {
  2300. if(effectManager)
  2301. effectManager.PauseEffects(type, sourceName, singleLock, duration, useMaxDuration);
  2302. }
  2303.  
  2304. public function HasDefaultAbilitySet() : bool
  2305. {
  2306. return GetCharacterStats().HasAbilityWithTag( theGame.params.BASE_ABILITY_TAG, true );
  2307. }
  2308.  
  2309. public function IgnoresDifficultySettings() : bool
  2310. {
  2311. if(abilityManager && abilityManager.IsInitialized())
  2312. return abilityManager.IgnoresDifficultySettings();
  2313.  
  2314. return true;
  2315. }
  2316.  
  2317.  
  2318.  
  2319. public function HasStaminaToUseAction( action : EStaminaActionType, optional abilityName : name, optional dt :float, optional multiplier : float ) : bool
  2320. {
  2321. var ret : bool;
  2322. var cost : float;
  2323.  
  2324. ret = false;
  2325.  
  2326. if( abilityManager && abilityManager.IsInitialized() && IsAlive() )
  2327. {
  2328. if( multiplier == 0 )
  2329. multiplier = 1;
  2330.  
  2331. cost = multiplier * GetStaminaActionCost( action, abilityName, dt );
  2332. ret = (GetStat(BCS_Stamina) >= cost);
  2333. }
  2334.  
  2335. return ret;
  2336. }
  2337.  
  2338.  
  2339. public function GetStaminaActionCost( action : EStaminaActionType, optional abilityName : name, optional dt : float, optional mult : float ) : float
  2340. {
  2341. var cost, delay : float;
  2342.  
  2343. if(abilityManager && abilityManager.IsInitialized() && IsAlive())
  2344. {
  2345. abilityManager.GetStaminaActionCost(action, cost, delay, 0, 0, abilityName, dt, mult);
  2346. return cost;
  2347. }
  2348.  
  2349. return -1;
  2350. }
  2351.  
  2352.  
  2353. public function GetStaminaActionDelay(action : EStaminaActionType, optional abilityName : name, optional dt :float) : float
  2354. {
  2355. var cost, delay : float;
  2356.  
  2357. if(abilityManager && abilityManager.IsInitialized() && IsAlive())
  2358. {
  2359. abilityManager.GetStaminaActionCost(action, cost, delay, 0, 0, abilityName, dt);
  2360. return delay;
  2361. }
  2362.  
  2363. return 0;
  2364. }
  2365.  
  2366.  
  2367. public function GetHealthPercents() : float
  2368. {
  2369. if( !abilityManager || !abilityManager.IsInitialized())
  2370. return -1;
  2371.  
  2372. if(UsesVitality())
  2373. return abilityManager.GetStatPercents(BCS_Vitality);
  2374. else if(UsesEssence())
  2375. return abilityManager.GetStatPercents(BCS_Essence);
  2376. else
  2377. return -1;
  2378. }
  2379.  
  2380. public final function GetHealth() : float
  2381. {
  2382. if( !abilityManager || !abilityManager.IsInitialized())
  2383. return -1;
  2384.  
  2385. if(UsesVitality())
  2386. return abilityManager.GetStat(BCS_Vitality);
  2387. else if(UsesEssence())
  2388. return abilityManager.GetStat(BCS_Essence);
  2389. else
  2390. return -1;
  2391. }
  2392.  
  2393.  
  2394. public function GetStaminaPercents() : float
  2395. {
  2396. if( !abilityManager || !abilityManager.IsInitialized())
  2397. return -1;
  2398.  
  2399. return abilityManager.GetStatPercents( BCS_Stamina );
  2400. }
  2401.  
  2402.  
  2403. public function GetMaxHealth() : float
  2404. {
  2405. var vit, ess : bool;
  2406.  
  2407. vit = UsesVitality();
  2408. ess = UsesEssence();
  2409.  
  2410. if(vit && !ess)
  2411. return GetStatMax(BCS_Vitality);
  2412. else if(!vit && ess)
  2413. return GetStatMax(BCS_Essence);
  2414. else
  2415. return -1;
  2416. }
  2417.  
  2418. public function GetCurrentHealth() : float
  2419. {
  2420. var vit, ess : bool;
  2421.  
  2422. vit = UsesVitality();
  2423. ess = UsesEssence();
  2424.  
  2425. if(vit && !ess)
  2426. return GetStat(BCS_Vitality);
  2427. else if(!vit && ess)
  2428. return GetStat(BCS_Essence);
  2429. else
  2430. return -1;
  2431. }
  2432.  
  2433.  
  2434. public final function UsesVitality() : bool
  2435. {
  2436. if(abilityManager )
  2437. return abilityManager.UsedHPType() == BCS_Vitality;
  2438.  
  2439. return false;
  2440. }
  2441.  
  2442.  
  2443. public function UsesEssence() : bool
  2444. {
  2445. if(abilityManager )
  2446. return abilityManager.UsedHPType() == BCS_Essence;
  2447.  
  2448. return false;
  2449. }
  2450.  
  2451. public function GetUsedHealthType() : EBaseCharacterStats
  2452. {
  2453. if(abilityManager && abilityManager.IsInitialized())
  2454. return abilityManager.UsedHPType();
  2455.  
  2456. return BCS_Undefined;
  2457. }
  2458.  
  2459. public function GetStat(stat : EBaseCharacterStats, optional ignoreLock : bool) : float
  2460. {
  2461. if(abilityManager && abilityManager.IsInitialized())
  2462. return abilityManager.GetStat(stat, ignoreLock);
  2463.  
  2464. return -1;
  2465. }
  2466.  
  2467. public function GetStatMax(stat : EBaseCharacterStats) : float
  2468. {
  2469. if(abilityManager && abilityManager.IsInitialized())
  2470. return abilityManager.GetStatMax(stat);
  2471.  
  2472. return -1;
  2473. }
  2474.  
  2475. public function GetStats(stat : EBaseCharacterStats, out curr : float, out max : float )
  2476. {
  2477. curr = -1;
  2478. max = -1;
  2479. if ( abilityManager && abilityManager.IsInitialized() )
  2480. abilityManager.GetStats( stat, curr, max );
  2481. }
  2482.  
  2483.  
  2484. public function GetStatPercents(stat : EBaseCharacterStats) : float
  2485. {
  2486. if(abilityManager && abilityManager.IsInitialized())
  2487. return abilityManager.GetStatPercents(stat);
  2488.  
  2489. return -1;
  2490. }
  2491.  
  2492. function GetThreatLevel() : int
  2493. {
  2494. return 0;
  2495. }
  2496.  
  2497. // W3EE - Begin
  2498. private var slowdownFactor : float; default slowdownFactor = 0;
  2499. private var isCrippled : bool; default isCrippled = false;
  2500.  
  2501. timer function RemoveCripplingInjury( dt : float, id : int )
  2502. {
  2503. var npcStats : SOpponentStats;
  2504.  
  2505. npcStats = ((CNewNPC)this).GetNPCStats();
  2506. ResetAnimationSpeedMultiplier(npcStats.spdMultID2);
  2507. SetCrippled(false);
  2508. }
  2509.  
  2510. public function SetCrippled( i : bool )
  2511. {
  2512. isCrippled = i;
  2513. }
  2514.  
  2515. public function GetCrippled() : bool
  2516. {
  2517. return isCrippled;
  2518. }
  2519.  
  2520. public function SetSlowdownFactor( i : float )
  2521. {
  2522. slowdownFactor = i;
  2523. }
  2524.  
  2525. public function GetSlowdownFactor() : float
  2526. {
  2527. return slowdownFactor;
  2528. }
  2529. // W3EE - End
  2530.  
  2531. event OnTakeDamage( action : W3DamageAction )
  2532. {
  2533. var playerAttacker : CPlayer;
  2534. var attackName : name;
  2535. var animatedComponent : CAnimatedComponent;
  2536. var buff : W3Effect_Frozen;
  2537. var buffs : array<CBaseGameplayEffect>;
  2538. // W3EE - Begin
  2539. var i, size : int;
  2540. var damageTypes : array< name >;
  2541. var damageType : name;
  2542. // W3EE - End
  2543. var min, max : SAbilityAttributeValue;
  2544. var lifeLeech, health, stamina : float;
  2545. var wasAlive : bool;
  2546. var hudModuleDamageType : EFloatingValueType;
  2547. var npcVictim : CNewNPC;
  2548.  
  2549. // W3EE - Begin
  2550. var witcher : W3PlayerWitcher;
  2551. var attackAction : W3Action_Attack;
  2552. var adrGain : SAbilityAttributeValue;
  2553. var value : SAbilityAttributeValue;
  2554. var items : array<SItemUniqueId>;
  2555. var signType : ESignType;
  2556. var weaponEnt : CEntity;
  2557. var npc : CNewNPC;
  2558. // W3EE - End
  2559.  
  2560. playerAttacker = (CPlayer)action.attacker;
  2561. wasAlive = IsAlive();
  2562. npcVictim = (CNewNPC)action.victim;
  2563.  
  2564. buffs = GetBuffs(EET_Frozen);
  2565. for(i=0; i<buffs.Size(); i+=1)
  2566. {
  2567. buff = (W3Effect_Frozen)buffs[i];
  2568. if(buff.KillOnHit())
  2569. {
  2570. action.processedDmg.vitalityDamage = GetStatMax(BCS_Vitality);
  2571. action.processedDmg.essenceDamage = GetStatMax(BCS_Essence);
  2572. if ( action.attacker == thePlayer )
  2573. {
  2574. ShowFloatingValue(EFVT_InstantDeath, 0, false);
  2575. }
  2576. break;
  2577. }
  2578. }
  2579.  
  2580. npc = (CNewNPC)action.victim;
  2581. // W3EE - Begin
  2582. /*
  2583. if(playerAttacker && npc)
  2584. {
  2585. ((CAIStorageReactionData)npc.GetScriptStorageObject('ReactionData')).ResetAttitudes(npc);
  2586.  
  2587. if ( npc.HasAttitudeTowards( thePlayer ) && npc.GetAttitude( thePlayer ) == AIA_Hostile )
  2588. {
  2589. npc.ResetAttitude( thePlayer );
  2590. }
  2591.  
  2592. npc.SetTemporaryAttitudeGroup('npc_charmed', AGP_Axii);
  2593. npc.SignalGameplayEvent('NoticedObjectReevaluation');
  2594. }*/
  2595.  
  2596. if( ((W3Effect_YrdenHealthDrain)action.causer) || ((W3YrdenEntityStateYrdenShock)action.causer) )
  2597. OnYrdenHit(action.attacker);
  2598.  
  2599. witcher = GetWitcherPlayer();
  2600. attackAction = (W3Action_Attack)action;
  2601. /*
  2602. if( attackAction && attackAction.IsActionMelee() && (!attackAction.WasDodged() || (Options().EnemyDodgeNegateDamage() && Combat().DamagePercentageTaken() > 0) || !Options().EnemyDodgeNegateDamage()) )
  2603. {
  2604. if( witcher.HasAbility('Runeword 11 _Stats', true) && (playerAttacker || attackAction.IsParried()) )
  2605. {
  2606. SoundEvent('sign_igni_charge_begin');
  2607. }
  2608. else
  2609.  
  2610. if( playerAttacker && witcher.HasAbility('Runeword 6 _Stats', true) && !attackAction.IsParried() )
  2611. {
  2612. witcher.Heal(witcher.GetStatMax(BCS_Vitality) * 0.03f);
  2613. witcher.PlayEffectSingle('drain_energy_caretaker_shovel');
  2614. }
  2615. else
  2616.  
  2617. }
  2618. */
  2619.  
  2620. Combat().CrippleEnemy( playerAttacker, (CNewNPC)action.victim, action );
  2621. // W3EE - End
  2622.  
  2623.  
  2624. if(action.processedDmg.vitalityDamage > 0 && UsesVitality())
  2625. {
  2626. DrainVitality(action.processedDmg.vitalityDamage);
  2627. action.SetDealtDamage();
  2628. }
  2629. if(action.processedDmg.essenceDamage > 0 && UsesEssence())
  2630. {
  2631. DrainEssence(action.processedDmg.essenceDamage);
  2632. action.SetDealtDamage();
  2633. }
  2634. if(action.processedDmg.moraleDamage > 0)
  2635. DrainMorale(action.processedDmg.moraleDamage);
  2636. if(action.processedDmg.staminaDamage > 0)
  2637. DrainStamina(ESAT_FixedValue, action.processedDmg.staminaDamage, 0);
  2638.  
  2639.  
  2640. ShouldAttachArrowToPlayer( action );
  2641.  
  2642.  
  2643. if( ((action.attacker && action.attacker == thePlayer) || (CBaseGameplayEffect)action.causer) && !action.GetUnderwaterDisplayDamageHack() )
  2644. {
  2645. if(action.GetInstantKillFloater())
  2646. {
  2647. hudModuleDamageType = EFVT_InstantDeath;
  2648. }
  2649. else if(action.IsCriticalHit())
  2650. {
  2651. hudModuleDamageType = EFVT_Critical;
  2652. }
  2653. else if(action.IsDoTDamage())
  2654. {
  2655. hudModuleDamageType = EFVT_DoT;
  2656. }
  2657. else
  2658. {
  2659. hudModuleDamageType = EFVT_None;
  2660. }
  2661.  
  2662. // W3EE - Begin
  2663. size = action.GetDTsNames( damageTypes );
  2664. for(i=0; i<size; i+=1)
  2665. {
  2666. damageType = damageTypes[i];
  2667. }
  2668. ShowFloatingValue(hudModuleDamageType, action.GetDamageDealt(), (hudModuleDamageType == EFVT_DoT), , damageType);
  2669. // W3EE - End
  2670. }
  2671.  
  2672.  
  2673. if(action.attacker && !action.IsDoTDamage() && wasAlive && action.GetDTCount() > 0 && !action.GetUnderwaterDisplayDamageHack())
  2674. {
  2675. theGame.witcherLog.CacheCombatDamageMessage(action.attacker, this, action.GetDamageDealt());
  2676. theGame.witcherLog.AddCombatDamageMessage(action.DealtDamage());
  2677. }
  2678.  
  2679. if( !IsAlive() )
  2680. {
  2681. OnDeath( action );
  2682.  
  2683.  
  2684. if(playerAttacker)
  2685. {
  2686. if (thePlayer.HasBuff(EET_Mutagen07))
  2687. {
  2688. mutagen = thePlayer.GetBuff(EET_Mutagen07);
  2689. theGame.GetDefinitionsManager().GetAbilityAttributeValue(mutagen.GetAbilityName(), 'lifeLeech', min, max);
  2690. lifeLeech = CalculateAttributeValue(GetAttributeRandomizedValue(min, max));
  2691. if (UsesVitality())
  2692. lifeLeech = lifeLeech * action.processedDmg.vitalityDamage;
  2693. else if (UsesEssence())
  2694. lifeLeech = lifeLeech * action.processedDmg.essenceDamage;
  2695. else
  2696. lifeLeech = 0;
  2697.  
  2698. thePlayer.GainStat(BCS_Vitality, lifeLeech);
  2699. }
  2700. }
  2701.  
  2702. SignalGameplayEvent('DamageTaken');
  2703. }
  2704.  
  2705. public function Revive()
  2706. {
  2707. var maxVitality, maxEssence : float;
  2708.  
  2709. if (thePlayer.HasBuff(EET_Mutagen33) && action.DealsAnyDamage() && (npcVictim.HasBuff(EET_Bleeding) || npcVictim.HasBuff(EET_BleedingTracking)))
  2710. {
  2711. mutagen = thePlayer.GetBuff(EET_Mutagen33);
  2712. theGame.GetDefinitionsManager().GetAbilityAttributeValue(mutagen.GetAbilityName(), 'lifeLeech', min, max);
  2713. lifeLeech = CalculateAttributeValue(GetAttributeRandomizedValue(min, max));
  2714. if (UsesVitality())
  2715. lifeLeech = lifeLeech * action.processedDmg.vitalityDamage;
  2716. else if (UsesEssence())
  2717. lifeLeech = lifeLeech * action.processedDmg.essenceDamage;
  2718. else
  2719. lifeLeech = 0;
  2720.  
  2721. thePlayer.GainStat(BCS_Vitality, lifeLeech);
  2722. }
  2723. {
  2724. OnRevived();
  2725.  
  2726. if(effectManager)
  2727. effectManager.OnOwnerRevived();
  2728.  
  2729. abilityManager.OnOwnerRevived();
  2730. }
  2731. }
  2732.  
  2733.  
  2734. public function ApplyActionEffects( action : W3DamageAction ) : bool
  2735. {
  2736. if(effectManager)
  2737. return effectManager.AddEffectsFromAction( action );
  2738.  
  2739. if ( thePlayer.HasBuff(EET_Mutagen04) && action.DealsAnyDamage() && thePlayer.IsHeavyAttack(attackName) && thePlayer.GetStat(BCS_Stamina) > 0)
  2740. {
  2741. mutagen = thePlayer.GetBuff(EET_Mutagen04);
  2742. theGame.GetDefinitionsManager().GetAbilityAttributeValue(mutagen.GetAbilityName(), 'staminaCostPerc', min, max);
  2743. stamina = CalculateAttributeValue(GetAttributeRandomizedValue(min, max));
  2744. stamina *= thePlayer.GetStat(BCS_Stamina);
  2745. theGame.GetDefinitionsManager().GetAbilityAttributeValue(mutagen.GetAbilityName(), 'healthReductionPerc', min, max);
  2746. health = CalculateAttributeValue(GetAttributeRandomizedValue(min, max));
  2747. if (UsesVitality())
  2748. {
  2749. health *= GetStat(BCS_Vitality);
  2750. DrainVitality(health);
  2751. thePlayer.DrainStamina(ESAT_FixedValue, stamina, 0.5f);
  2752. }
  2753. else if (UsesEssence())
  2754. {
  2755. health *= GetStat(BCS_Essence);
  2756. DrainEssence(health);
  2757. thePlayer.DrainStamina(ESAT_FixedValue, stamina, 0.5f);
  2758. }
  2759.  
  2760. if(health > 0)
  2761. action.SetDealtDamage();
  2762. }
  2763. }
  2764.  
  2765.  
  2766. if( !IsAlive() )
  2767. {
  2768.  
  2769. return false;
  2770. }
  2771.  
  2772. // W3EE - Begin
  2773. private var burnCounter : float; default burnCounter = 0.f;
  2774. public function GetBurnCounter() : float
  2775. {
  2776. return burnCounter;
  2777. }
  2778.  
  2779. public function IncBurnCounter(optional by : float)
  2780. {
  2781. if ( by )
  2782. burnCounter += by;
  2783. else
  2784. burnCounter += 1;
  2785. ClampF(burnCounter, 0, 3);
  2786. }
  2787.  
  2788. /*public function DecBurnCounter(optional by : float)
  2789. {
  2790. if( by )
  2791. burnCounter -= by;
  2792. else
  2793. burnCounter -= 1;
  2794. }*/
  2795.  
  2796. private var damageTakenMultiplier : float; default damageTakenMultiplier = 1.f;
  2797. public function GetDamageTakenMultiplier() : float
  2798. {
  2799. return damageTakenMultiplier;
  2800. }
  2801.  
  2802. public function SetDamageTakenMultiplier( to : float )
  2803. {
  2804. damageTakenMultiplier = to;
  2805. }
  2806.  
  2807. private var isFrozenEffectPlaying : bool; default isFrozenEffectPlaying = false;
  2808.  
  2809. public function GetIsFrozenEffectPlaying() : bool
  2810. {
  2811. return isFrozenEffectPlaying;
  2812. }
  2813.  
  2814. public function SetIsFrozenEffectPlaying( to : bool )
  2815. {
  2816. isFrozenEffectPlaying = to;
  2817. }
  2818.  
  2819. public timer function RemoveFreezeEffects( dt : float, id : int )
  2820. {
  2821. StopEffect('critical_frozen');
  2822. isFrozenEffectPlaying = false;
  2823. }
  2824.  
  2825. private var isRevoveringFromParalysis : bool; default isRevoveringFromParalysis = false;
  2826.  
  2827. public function GetIsRecoveringFromParalysis() : bool
  2828. {
  2829. return isRevoveringFromParalysis;
  2830. var maxVitality, maxEssence : float;
  2831.  
  2832. if ( !IsAlive() || IsKnockedUnconscious() )
  2833. {
  2834. OnRevived();
  2835.  
  2836. if(effectManager)
  2837. effectManager.OnOwnerRevived();
  2838.  
  2839. abilityManager.OnOwnerRevived();
  2840. }
  2841. }
  2842.  
  2843. public function SetIsRecoveringFromParalysis( to : bool )
  2844. {
  2845. isRevoveringFromParalysis = to;
  2846. }
  2847.  
  2848. public timer function ParalysisRecovery( dt : float, id : int )
  2849. {
  2850. var npcStats : SOpponentStats;
  2851.  
  2852. isRevoveringFromParalysis = false;
  2853.  
  2854. npcStats = ((CNewNPC)this).GetNPCStats();
  2855. ResetAnimationSpeedMultiplier(npcStats.spdMultID2);
  2856. }
  2857. // W3EE - End
  2858. if(effectManager)
  2859. return effectManager.AddEffectsFromAction( action );
  2860.  
  2861. return false;
  2862. }
  2863.  
  2864.  
  2865. public function GetHitCounter(optional total : bool) : int
  2866. {
  2867. if ( total )
  2868. return totalHitCounter;
  2869. return hitCounter;
  2870. }
  2871.  
  2872. public function IncHitCounter()
  2873. {
  2874. hitCounter += 1;
  2875. totalHitCounter += 1;
  2876. // W3EE - Begin
  2877. AddTimer('ResetHitCounter',2.0,false,,,,true);
  2878. // W3EE - End
  2879. }
  2880.  
  2881. public timer function ResetHitCounter( deta : float , id : int)
  2882. {
  2883. hitCounter = 0;
  2884. }
  2885.  
  2886.  
  2887. public function GetDefendCounter(optional total : bool) : int
  2888. {
  2889. if ( total )
  2890. return totalDefendCounter;
  2891. return defendCounter;
  2892. }
  2893.  
  2894. public function IncDefendCounter()
  2895. {
  2896. defendCounter += 1;
  2897. totalDefendCounter += 1;
  2898. // W3EE - Begin
  2899. AddTimer('ResetDefendCounter',2.0,false,,,,true);
  2900. // W3EE - End
  2901. }
  2902.  
  2903. public timer function ResetDefendCounter( deta : float , id : int)
  2904. {
  2905. defendCounter = 0;
  2906. }
  2907.  
  2908.  
  2909. public function ReactToReflectedAttack( target : CGameplayEntity)
  2910. {
  2911. var hp, dmg : float;
  2912. var action : W3DamageAction;
  2913.  
  2914. action = new W3DamageAction in this;
  2915. action.Initialize(target,this,NULL,'',EHRT_Reflect,CPS_AttackPower,true,false,false,false);
  2916. action.SetHitAnimationPlayType(EAHA_ForceYes);
  2917. action.SetCannotReturnDamage( true );
  2918.  
  2919.  
  2920.  
  2921. if( ((CActor) target).HasTag( 'scolopendromorph' ) )
  2922. {
  2923. ((CActor) target).PlayEffect('heavy_hit_back');
  2924. }
  2925. else
  2926. {
  2927. // W3EE - Begin
  2928. //((CActor) target).PlayEffectOnHeldWeapon('light_block');
  2929. // W3EE - End
  2930. }
  2931.  
  2932. theGame.damageMgr.ProcessAction( action );
  2933. delete action;
  2934. }
  2935.  
  2936.  
  2937. public function ReactToBeingHit(damageAction : W3DamageAction, optional buffNotApplied : bool) : bool
  2938. {
  2939. var animType : EHitReactionType;
  2940. var receivedAnyDamage : bool;
  2941. var isParriedOrCountered, playHitAnim, criticalAllowsHit, immortalDebugHack : bool;
  2942. var hitAnimationPlayType : EActionHitAnim;
  2943. var animPlayed : bool;
  2944. var attackAction : W3Action_Attack;
  2945. var hud : CR4ScriptedHud;
  2946.  
  2947.  
  2948. OnReactToBeingHit( damageAction );
  2949.  
  2950.  
  2951. hitAnimationPlayType = damageAction.GetHitAnimationPlayType();
  2952. // W3EE - Begin
  2953. receivedAnyDamage = true; // damageAction.DealtDamage();
  2954. // W3EE - End
  2955. attackAction = (W3Action_Attack)damageAction;
  2956. animPlayed = false;
  2957.  
  2958. if ( hitAnimationPlayType != EAHA_ForceNo)
  2959. {
  2960. playHitAnim = false;
  2961.  
  2962.  
  2963. if(GetImmortalityMode() == AIM_Invulnerable && this == thePlayer)
  2964. {
  2965. playHitAnim = false;
  2966. }
  2967. else if( HasTag( 'ethereal' ) && !HasAbility( 'EtherealActive' ) )
  2968. {
  2969. playHitAnim = false;
  2970. ActivateEthereal( true );
  2971. }
  2972. else if(hitAnimationPlayType == EAHA_ForceYes)
  2973. {
  2974. playHitAnim = true;
  2975. }
  2976. else if(hitAnimationPlayType == EAHA_ForceYes)
  2977. {
  2978. playHitAnim = true;
  2979. }
  2980. else
  2981. {
  2982. if(effectManager)
  2983. criticalAllowsHit = CriticalBuffIsHitAllowed(effectManager.GetCurrentlyAnimatedCS(), damageAction.GetHitReactionType());
  2984.  
  2985. isParriedOrCountered = attackAction && ( attackAction.IsParried() || attackAction.IsCountered() || attackAction.WasDodged() );
  2986. immortalDebugHack = (GetImmortalityMode() == AIM_Immortal && !isParriedOrCountered);
  2987.  
  2988. if( HasAbility('IgnoreHitAnimFromSigns') )
  2989. {
  2990. playHitAnim = false;
  2991. }
  2992.  
  2993.  
  2994.  
  2995. else if ( damageAction.attacker == thePlayer && thePlayer.GetAttitude( this ) == AIA_Friendly && !HasBuff(EET_AxiiGuardMe) )
  2996. {
  2997. playHitAnim = false;
  2998. }
  2999. else if((receivedAnyDamage || immortalDebugHack) && CanPlayHitAnim() && criticalAllowsHit)
  3000. {
  3001. playHitAnim = true;
  3002. }
  3003. else
  3004. {
  3005. if(buffNotApplied && damageAction.IsActionWitcherSign())
  3006. {
  3007. playHitAnim = true;
  3008. }
  3009. else if(CanPlayHitAnim())
  3010. {
  3011. if(receivedAnyDamage && ( useAdditiveHits || oneTimeAdditiveHit ) )
  3012. {
  3013. playHitAnim = true;
  3014. }
  3015. else if(!receivedAnyDamage && !isParriedOrCountered && criticalAllowsHit)
  3016. {
  3017.  
  3018. playHitAnim = true;
  3019. }
  3020. }
  3021. }
  3022.  
  3023. // W3EE - Begin
  3024. if( damageAction.IsDoTDamage() )
  3025. playHitAnim = false;
  3026. // W3EE - End
  3027. }
  3028.  
  3029.  
  3030. if(playHitAnim)
  3031. {
  3032.  
  3033.  
  3034. if( ( useAdditiveHits || oneTimeAdditiveHit ) && !( criticalCancelAdditiveHit && damageAction.IsCriticalHit() ))
  3035. {
  3036. // W3EE - Begin
  3037. animType = ModifyHitSeverityReaction(this, damageAction.GetHitReactionType());
  3038. if( animType != EHRT_None )
  3039. {
  3040. SetDetailedHitReaction(damageAction.GetSwingType(), damageAction.GetSwingDirection());
  3041. damageAction.additiveHitReactionAnimRequested = true;
  3042. oneTimeAdditiveHit = false;
  3043. }
  3044. // W3EE - End
  3045. }
  3046. }
  3047. damageAction.additiveHitReactionAnimRequested = true;
  3048. oneTimeAdditiveHit = false;
  3049. }
  3050. else if ( hitAnimationPlayType == EAHA_ForceYes || (CanPlayHitAnim() && hitAnimationPlayType == EAHA_Default))
  3051. {
  3052. // W3EE - Begin
  3053. animType = ModifyHitSeverityReaction(this, damageAction.GetHitReactionType());
  3054. if( animType != EHRT_None )
  3055. {
  3056. PlayHitAnimation(damageAction, animType);
  3057. animPlayed = true;
  3058. }
  3059. // W3EE - End
  3060. }
  3061. }
  3062. }
  3063.  
  3064.  
  3065.  
  3066. lastWasHitTime = theGame.GetEngineTimeAsSeconds();
  3067. lastWasAttackedTime = lastWasHitTime ;
  3068.  
  3069.  
  3070. return animPlayed;
  3071.  
  3072. // W3EE - Frozen & Chilled Effects
  3073. event OnFireHit(source : CGameplayEntity)
  3074. {
  3075. RemoveAllBuffsOfType(EET_Frozen);
  3076. RemoveAllBuffsOfType(EET_SlowdownFrost);
  3077. super.OnFireHit(source);
  3078. }
  3079. // W3EE - End
  3080.  
  3081. public final function ProcessHitSound(damageAction : W3DamageAction, hitAnimPlayed : bool)
  3082. {
  3083. var noHitSound : bool;
  3084. var playHitReactionSfx : bool;
  3085. var playHitReactionSfxOverrides : bool;
  3086. var npcVictim : CNewNPC;
  3087.  
  3088. noHitSound = damageAction.SuppressHitSounds();
  3089. if( !IsAlive() && ( damageAction.IsDoTDamage() || theGame.IsDialogOrCutscenePlaying() ) )
  3090. {
  3091. noHitSound = true;
  3092. }
  3093.  
  3094. if( noHitSound )
  3095. {
  3096. SoundSwitch( "opponent_weapon_type", 'empty');
  3097. SoundSwitch("opponent_weapon_size", '');
  3098. return;
  3099. }
  3100.  
  3101.  
  3102. SetHitSoundData(damageAction);
  3103.  
  3104. npcVictim = (CNewNPC) damageAction.victim;
  3105.  
  3106.  
  3107.  
  3108. if( !hitAnimPlayed || (npcVictim && !npcVictim.CanPlayHitAnim() ))
  3109. {
  3110. playHitReactionSfx = damageAction.DealtDamage() && !damageAction.IsDoTDamage() && damageAction.GetBuffSourceName() != "FallingDamage";
  3111. playHitReactionSfxOverrides = ((W3Petard)damageAction.causer);
  3112. if( playHitReactionSfx || playHitReactionSfxOverrides )
  3113. {
  3114. if (damageAction.GetHitReactionType() == EHRT_Heavy)
  3115. SoundEvent("cmb_play_hit_heavy");
  3116. else
  3117. SoundEvent("cmb_play_hit_light");
  3118. }
  3119. }
  3120. }
  3121.  
  3122.  
  3123. public function SetHitSoundData(action : W3DamageAction)
  3124. {
  3125. var weaponMeshSoundTypeIdentification, soundMonsterName, weaponMeshSoundSizeIdentification, armourMeshSoundSizeIdentification : name;
  3126. var victimWeaponMeshSoundTypeIdentification, victimWeaponMeshSoundSizeIdentification : name;
  3127. var i, boneIndex : int;
  3128. var weaponComponents : array<CComponent>;
  3129. var victimWeaponComponents : array<CComponent>;
  3130. var monsterCategory : EMonsterCategory;
  3131. var isTeleporting : bool;
  3132. var canBeTargeted : bool;
  3133. var canBeHitByFists : bool;
  3134. var category : name;
  3135. var weaponEntity : CItemEntity;
  3136. var victimWeapon : CItemEntity;
  3137. var attackAction : W3Action_Attack;
  3138. var weaponId : SItemUniqueId;
  3139. var victimeWeaponId : SItemUniqueId;
  3140. var nodeCauser : CNode;
  3141. var isByArrow : bool;
  3142. var cr4HumanoidCombatComponent : CR4HumanoidCombatComponent;
  3143. var victimInv : CInventoryComponent;
  3144. var heldWeapons : array<SItemUniqueId>;
  3145.  
  3146.  
  3147. attackAction = (W3Action_Attack)action;
  3148. isByArrow = (W3ArrowProjectile)action.causer;
  3149. nodeCauser = (CNode)action.causer;
  3150.  
  3151. if(attackAction && (attackAction.IsActionMelee() || isByArrow) )
  3152. {
  3153. weaponId = attackAction.GetWeaponId();
  3154. weaponEntity = action.attacker.GetInventory().GetItemEntityUnsafe(weaponId);
  3155.  
  3156. victimInv = action.victim.GetInventory();
  3157. heldWeapons = victimInv.GetHeldWeapons();
  3158. if( heldWeapons.Size() > 0 )
  3159. {
  3160. victimeWeaponId = heldWeapons[0];
  3161. victimWeapon = victimInv.GetItemEntityUnsafe(victimeWeaponId);
  3162. }
  3163.  
  3164. category = action.attacker.GetInventory().GetItemCategory(weaponId);
  3165.  
  3166. if(category == 'monster_weapon')
  3167. {
  3168. theGame.GetMonsterParamsForActor( (CActor)action.attacker, monsterCategory, soundMonsterName, isTeleporting, canBeTargeted, canBeHitByFists);
  3169.  
  3170.  
  3171. SoundSwitch( "opponent_weapon_type", 'monster' );
  3172. SoundSwitch( "opponent_weapon_size", soundMonsterName );
  3173. }
  3174. else if(category == 'fist')
  3175. {
  3176. SoundSwitch( "opponent_weapon_type", 'fist' );
  3177. SoundSwitch( "opponent_weapon_size", '' );
  3178. }
  3179. else
  3180. {
  3181.  
  3182. if(isByArrow)
  3183. {
  3184. SoundSwitch( "opponent_weapon_type", "arrow" );
  3185. }
  3186. else
  3187. {
  3188. weaponComponents = weaponEntity.GetComponentsByClassName('CMeshComponent');
  3189. if( (weaponComponents.Size() > 0 ) && weaponComponents[ 0 ] )
  3190. {
  3191. weaponMeshSoundTypeIdentification = GetMeshSoundTypeIdentification( weaponComponents[0] );
  3192. weaponMeshSoundSizeIdentification = GetMeshSoundSizeIdentification( weaponComponents[0] );
  3193. }
  3194.  
  3195. victimWeaponComponents = victimWeapon.GetComponentsByClassName('CMeshComponent');
  3196. if( (victimWeaponComponents.Size() > 0 ) && victimWeaponComponents[ 0 ] )
  3197. {
  3198. victimWeaponMeshSoundTypeIdentification = GetMeshSoundTypeIdentification( victimWeaponComponents[0] );
  3199. victimWeaponMeshSoundSizeIdentification = GetMeshSoundSizeIdentification( victimWeaponComponents[0] );
  3200.  
  3201. }
  3202.  
  3203. if(IsNameValid(weaponMeshSoundTypeIdentification))
  3204. {
  3205. SoundSwitch( "opponent_weapon_type", weaponMeshSoundTypeIdentification );
  3206. SoundSwitch( "opponent_weapon_size", weaponMeshSoundSizeIdentification );
  3207. action.attacker.SoundSwitch( "weapon_type", weaponMeshSoundTypeIdentification );
  3208. action.attacker.SoundSwitch( "weapon_size", weaponMeshSoundSizeIdentification );
  3209. }
  3210.  
  3211. if(IsNameValid(victimWeaponMeshSoundTypeIdentification))
  3212. {
  3213. action.attacker.SoundSwitch( "opponent_weapon_type", victimWeaponMeshSoundTypeIdentification );
  3214. action.attacker.SoundSwitch( "opponent_weapon_size", victimWeaponMeshSoundSizeIdentification );
  3215. SoundSwitch( "weapon_type", victimWeaponMeshSoundTypeIdentification );
  3216. SoundSwitch( "weapon_size", victimWeaponMeshSoundSizeIdentification );
  3217. }
  3218. }
  3219. }
  3220.  
  3221. boneIndex = attackAction.GetHitBoneIndex();
  3222.  
  3223.  
  3224. if(boneIndex == GetHeadBoneIndex())
  3225. SoundSwitch( "hit_location", "head" );
  3226. else
  3227. SoundSwitch( "hit_location", "body" );
  3228.  
  3229.  
  3230.  
  3231. if(StrContains(action.attacker.GetName(), "kikimore") && soundMonsterName == 'Endriaga' && attackAction.GetSoundAttackType() == 'monster_medium_hit_heavy')
  3232. {
  3233. SoundSwitch( "opponent_attack_type", 'monster_medium_hit_light' );
  3234. }
  3235. else
  3236. {
  3237. SoundSwitch( "opponent_attack_type", attackAction.GetSoundAttackType() );
  3238. }
  3239.  
  3240.  
  3241. cr4HumanoidCombatComponent = (CR4HumanoidCombatComponent)GetComponentByClassName( 'CR4HumanoidCombatComponent' );
  3242. if( cr4HumanoidCombatComponent )
  3243. {
  3244. armourMeshSoundSizeIdentification = cr4HumanoidCombatComponent.GetSoundTypeIdentificationForBone( boneIndex );
  3245. if( armourMeshSoundSizeIdentification != 'default' && armourMeshSoundSizeIdentification != 'None' )
  3246. {
  3247. SoundSwitch( "armour_type", armourMeshSoundSizeIdentification );
  3248. }
  3249. }
  3250. }
  3251.  
  3252. else if(action.IsActionWitcherSign())
  3253. {
  3254. SetDamageActionMagicHitSound((CEntity)action.causer);
  3255. }
  3256.  
  3257. else if( (W3CiriPhantom)action.attacker )
  3258. {
  3259. SoundSwitch( "opponent_weapon_type", 'ciri_spec_ability' );
  3260. }
  3261. else if( (W3SnowballProjectile)action.causer || (nodeCauser && nodeCauser.HasTag('Snowball')) )
  3262. {
  3263. SoundSwitch( "opponent_weapon_type", 'snowball' );
  3264. }
  3265. else if( (W3Petard)action.causer )
  3266. {
  3267. SoundSwitch( "opponent_attack_type", ((W3Petard)action.causer).GetAudioImpactName() );
  3268.  
  3269. weaponComponents = ((W3Petard)action.causer).GetComponentsByClassName('CMeshComponent');
  3270. if( (weaponComponents.Size() > 0 ) && weaponComponents[ 0 ] )
  3271. {
  3272. weaponMeshSoundTypeIdentification = GetMeshSoundTypeIdentification( weaponComponents[0] );
  3273. weaponMeshSoundSizeIdentification = GetMeshSoundSizeIdentification( weaponComponents[0] );
  3274. SoundSwitch( "opponent_weapon_type", weaponMeshSoundTypeIdentification );
  3275. SoundSwitch( "opponent_weapon_size", weaponMeshSoundSizeIdentification );
  3276. }
  3277. }
  3278. else if( isByArrow )
  3279. {
  3280. SoundSwitch( "opponent_weapon_type", 'arrow' );
  3281. SoundSwitch( "opponent_attack_type", 'wpn_arrow' );
  3282. }
  3283. }
  3284.  
  3285. protected function SetDamageActionMagicHitSound(causer : CEntity)
  3286. {
  3287. SoundSwitch( "opponent_weapon_type", 'magic' );
  3288.  
  3289. if((W3IgniProjectile)causer)
  3290. SoundSwitch( "opponent_weapon_size", 'magic_igni' );
  3291. if((W3AardProjectile)causer)
  3292. SoundSwitch( "opponent_weapon_size", 'magic_aard' );
  3293. if((W3YrdenEntity)causer)
  3294. SoundSwitch( "opponent_weapon_size", 'magic_yrden' );
  3295. if((W3QuenEntity)causer)
  3296. SoundSwitch( "opponent_weapon_size", 'magic_quen' );
  3297. }
  3298.  
  3299.  
  3300. public function PlayHitEffect(damageAction : W3DamageAction)
  3301. {
  3302. var effectName : name;
  3303. var attackAction : W3Action_Attack;
  3304. var actorAttacker : CActor;
  3305. var fxEntity : CEntity;
  3306.  
  3307. if(HasTag('NoHitFx'))
  3308. return;
  3309.  
  3310.  
  3311. attackAction = (W3Action_Attack)damageAction;
  3312. actorAttacker = (CActor)damageAction.attacker;
  3313. if(attackAction && actorAttacker && actorAttacker.GetInventory().ItemHasTag(attackAction.GetWeaponId(), 'Wooden'))
  3314. {
  3315.  
  3316. if(actorAttacker.IsHeavyAttack(attackAction.GetAttackName()))
  3317. {
  3318. effectName = 'wood_heavy_hit';
  3319. }
  3320. else
  3321. {
  3322. effectName = 'wood_light_hit';
  3323. }
  3324. }
  3325. else if ( attackAction && actorAttacker && damageAction.DealsAnyDamage()
  3326. && !actorAttacker.GetInventory().ItemHasTag(attackAction.GetWeaponId(), 'MagicWeaponFX') && actorAttacker.IsWeaponHeld('fist') )
  3327. {
  3328. effectName = 'fistfight_heavy_hit';
  3329. }
  3330. else
  3331. {
  3332.  
  3333. effectName = damageAction.GetHitEffect(IsAttackerAtBack(damageAction.attacker), !damageAction.DealsAnyDamage());
  3334. }
  3335.  
  3336. if(IsNameValid(effectName))
  3337. PlayEffect(effectName);
  3338.  
  3339.  
  3340. if( damageAction.IsCriticalHit() && damageAction.IsActionWitcherSign() && actorAttacker && IsAlive() && actorAttacker == thePlayer && GetWitcherPlayer().IsMutationActive( EPMT_Mutation2 ) )
  3341. {
  3342. fxEntity = CreateFXEntityAtPelvis( 'mutation2_critical', true );
  3343. if( fxEntity )
  3344. {
  3345. switch( damageAction.GetSignSkill() )
  3346. {
  3347. case S_Magic_1 :
  3348. fxEntity.PlayEffect( 'critical_aard' );
  3349. break;
  3350. case S_Magic_2 :
  3351. fxEntity.PlayEffect( 'critical_igni' );
  3352. break;
  3353. case S_Magic_3 :
  3354. case S_Magic_s03 :
  3355. fxEntity.PlayEffect( 'critical_yrden' );
  3356. break;
  3357. case S_Magic_4 :
  3358. case S_Magic_s04 :
  3359. case S_Magic_s13 :
  3360. fxEntity.PlayEffect( 'critical_quen' );
  3361. break;
  3362. }
  3363. }
  3364. }
  3365.  
  3366.  
  3367. if( actorAttacker == thePlayer && damageAction.IsActionWitcherSign() && IsAlive() && GetWitcherPlayer().IsMutationActive( EPMT_Mutation1 ) )
  3368. {
  3369. fxEntity = CreateFXEntityAtPelvis( 'mutation1_hit', true );
  3370. if( fxEntity )
  3371. {
  3372. switch( damageAction.GetSignType() )
  3373. {
  3374. case ST_Aard:
  3375. effectName = 'mutation_1_hit_aard' ;
  3376. break;
  3377. case ST_Igni:
  3378. effectName = 'mutation_1_hit_igni' ;
  3379. break;
  3380. case ST_Yrden:
  3381. effectName = 'mutation_1_hit_yrden' ;
  3382. break;
  3383. case ST_Quen:
  3384. effectName = 'mutation_1_hit_quen' ;
  3385. break;
  3386. }
  3387.  
  3388. fxEntity.PlayEffect( effectName );
  3389. }
  3390. }
  3391. }
  3392.  
  3393. event OnReactToBeingHit( damageAction : W3DamageAction );
  3394.  
  3395. function InterruptCombatFocusMode();
  3396.  
  3397. protected function PlayHitAnimation( damageAction : W3DamageAction, animType : EHitReactionType )
  3398. {
  3399. if ( IsNameValid( ( (CNewNPC)damageAction.attacker ).GetAbilityBuffStackedOnEnemyHitName() ) )
  3400. {
  3401. damageAction.attacker.AddAbility( ( (CNewNPC)damageAction.attacker ).GetAbilityBuffStackedOnEnemyHitName(), true );
  3402. }
  3403. }
  3404.  
  3405. // W3EE - Begin
  3406. var overrideDirection : bool;
  3407. public function SetOverrideDirection( b : bool ) {overrideDirection = b;}
  3408. // W3EE - End;
  3409.  
  3410. public function SetHitReactionDirection( attacker : CNode )
  3411. {
  3412. var victimToAttackerAngle : float = NodeToNodeAngleDistance(attacker, this);
  3413.  
  3414. // W3EE - Begin
  3415. if( overrideDirection )
  3416. {
  3417. this.SetBehaviorVariable('HitReactionDirection', (int)EHRD_Back);
  3418. return;
  3419. }
  3420. // W3EE - End
  3421.  
  3422. if( AbsF(victimToAttackerAngle) <= 90 )
  3423. {
  3424.  
  3425. this.SetBehaviorVariable( 'HitReactionDirection',(int)EHRD_Forward);
  3426. }
  3427. else if( AbsF(victimToAttackerAngle) > 90 )
  3428. {
  3429.  
  3430. this.SetBehaviorVariable( 'HitReactionDirection',(int)EHRD_Back);
  3431. }
  3432.  
  3433.  
  3434. if( victimToAttackerAngle > 45 && victimToAttackerAngle < 135 )
  3435. {
  3436.  
  3437. this.SetBehaviorVariable( 'HitReactionSide',(int)EHRS_Right);
  3438. }
  3439. else if( victimToAttackerAngle < -45 && victimToAttackerAngle > -135 )
  3440. {
  3441.  
  3442. this.SetBehaviorVariable( 'HitReactionSide',(int)EHRS_Left);
  3443. }
  3444. else
  3445. {
  3446. this.SetBehaviorVariable( 'HitReactionSide',(int)EHRS_None);
  3447. }
  3448. }
  3449.  
  3450. function SetDetailedHitReaction(type : EAttackSwingType, dir : EAttackSwingDirection)
  3451. {
  3452. this.SetBehaviorVariable( 'HitSwingDirection',(int)dir);
  3453. this.SetBehaviorVariable( 'HitSwingType',(int)type);
  3454. }
  3455.  
  3456.  
  3457. event OnPreSceneInvulnerability( val : bool )
  3458. {
  3459. if( val )
  3460. {
  3461. SetImmortalityMode( AIM_Invulnerable, AIC_Scene );
  3462. }
  3463. else
  3464. {
  3465. SetImmortalityMode( AIM_None, AIC_Scene );
  3466. }
  3467. }
  3468.  
  3469. event OnBlockingSceneStarted( scene: CStoryScene )
  3470. {
  3471. this.SetKinematic(true);
  3472. SetImmortalityMode( AIM_Invulnerable, AIC_Scene );
  3473. SetTemporaryAttitudeGroup( 'geralt_friendly', AGP_Scenes);
  3474. }
  3475.  
  3476. event OnBlockingSceneEnded( optional output : CStorySceneOutput)
  3477. {
  3478. SetImmortalityMode( AIM_None, AIC_Scene );
  3479. ResetTemporaryAttitudeGroup( AGP_Scenes );
  3480. }
  3481.  
  3482.  
  3483. event OnDeath( damageAction : W3DamageAction )
  3484. {
  3485.  
  3486. OnFocusModeSound( false, false );
  3487. SetFocusModeSoundEffectType( FMSET_None );
  3488.  
  3489.  
  3490. StopAllVoicesets();
  3491.  
  3492.  
  3493. if(effectManager)
  3494. {
  3495. if ( this.WillBeUnconscious() )
  3496. effectManager.OwnerHasEnteredUnconscious();
  3497. else
  3498. effectManager.OwnerHasDied();
  3499. }
  3500.  
  3501. // W3EE - Begin
  3502. if( GetCrippled() )
  3503. AddTimer('RemoveCripplingInjury', 0.1, false);
  3504. // W3EE - End
  3505.  
  3506. SetFocusModeVisibility( FMV_None );
  3507.  
  3508.  
  3509. this.GetMovingAgentComponent().SetEnabledFeetIK(false,0.5);
  3510.  
  3511.  
  3512. if( HasTag( 'etherealTest' ) )
  3513. {
  3514. HACK_ManageEtherealSkills();
  3515. }
  3516.  
  3517. if( HasTag( 'ethereal' ) )
  3518. {
  3519. StopEffect( 'olgierd_energy_blast' );
  3520. PlayEffect( 'ethereal_debuff' );
  3521. ManageEtherealSkillsAndFXes();
  3522. }
  3523. }
  3524.  
  3525.  
  3526. function OnRevived()
  3527. {
  3528. wasDefeatedFromFistFight = false;
  3529. SignalGameplayEvent( 'OnRevive' );
  3530. SetAlive(true);
  3531. this.GetMovingAgentComponent().SetEnabledFeetIK(true,0.5);
  3532. }
  3533.  
  3534. event OnCombatActionEnd()
  3535. {
  3536. StopRotateEventAdjustments();
  3537. }
  3538.  
  3539. event OnCanFindPath( sender : CActor )
  3540. {
  3541. }
  3542. event OnCannotFindPath( sender : CActor )
  3543. {
  3544. }
  3545. event OnBecomeAwareAndCanAttack( sender : CActor )
  3546. {
  3547. }
  3548. event OnBecomeUnawareOrCannotAttack( sender : CActor )
  3549. {
  3550. }
  3551. event OnApproachAttack( sender : CActor )
  3552. {
  3553. }
  3554. event OnApproachAttackEnd( sender : CActor )
  3555. {
  3556. }
  3557. event OnAttack( sender : CActor )
  3558. {
  3559. }
  3560. event OnAttackEnd( sender : CActor )
  3561. {
  3562. }
  3563.  
  3564. event OnAxiied( attacker : CActor)
  3565. {
  3566. var i : int;
  3567. var victimTags, attackerTags : array<name>;
  3568.  
  3569. victimTags = GetTags();
  3570. attackerTags = attacker.GetTags();
  3571.  
  3572. AddHitFacts( victimTags, attackerTags, "_axii_hit" );
  3573. }
  3574.  
  3575.  
  3576. public function SetEffectsUpdateTicking( on : bool, optional dontCheckEffectsManager : bool )
  3577. {
  3578. if( on )
  3579. {
  3580. if( !effectsUpdateTicking )
  3581. {
  3582. if( abilityManager && abilityManager.IsInitialized() && ( dontCheckEffectsManager || ( effectManager && effectManager.IsReady() ) ) )
  3583. {
  3584. effectsUpdateTicking = true;
  3585. AddTimer( 'EffectsUpdate', 0.001, true );
  3586. }
  3587. }
  3588. }
  3589. else if( effectsUpdateTicking && effectManager && effectManager.CanBeRemoved() )
  3590. {
  3591. effectsUpdateTicking = false;
  3592. RemoveTimer( 'EffectsUpdate' );
  3593. }
  3594. }
  3595.  
  3596. public function IsEffectsUpdateTicking() : bool
  3597. {
  3598. return effectsUpdateTicking;
  3599. }
  3600.  
  3601. public function StartVitalityRegen() : bool
  3602. {
  3603. if( effectManager )
  3604. {
  3605. return effectManager.StartVitalityRegen();
  3606. }
  3607.  
  3608. return false;
  3609. }
  3610.  
  3611. public function StopVitalityRegen()
  3612. {
  3613. if( effectManager )
  3614. {
  3615. effectManager.StopVitalityRegen();
  3616. }
  3617. }
  3618.  
  3619. public function StartEssenceRegen() : bool
  3620. {
  3621. if( effectManager )
  3622. {
  3623. return effectManager.StartEssenceRegen();
  3624. }
  3625.  
  3626. return false;
  3627. }
  3628.  
  3629. public function StopEssenceRegen()
  3630. {
  3631. if( effectManager )
  3632. {
  3633. effectManager.StopEssenceRegen();
  3634. }
  3635. }
  3636.  
  3637. public function StartStaminaRegen() : bool
  3638. {
  3639. if( effectManager )
  3640. {
  3641. return effectManager.StartStaminaRegen();
  3642. }
  3643.  
  3644. return false;
  3645. }
  3646.  
  3647. public function StopStaminaRegen()
  3648. {
  3649. if( effectManager )
  3650. {
  3651. effectManager.StopStaminaRegen();
  3652. }
  3653. }
  3654.  
  3655. public function StartMoraleRegen() : bool
  3656. {
  3657. if( effectManager )
  3658. {
  3659. return effectManager.StartMoraleRegen();
  3660. }
  3661.  
  3662. return false;
  3663. }
  3664.  
  3665. public function StopMoraleRegen()
  3666. {
  3667. if( effectManager )
  3668. {
  3669. effectManager.StopMoraleRegen();
  3670. }
  3671. }
  3672.  
  3673. public function StartPanicRegen() : bool
  3674. {
  3675. if( effectManager )
  3676. {
  3677. return effectManager.StartPanicRegen();
  3678. }
  3679.  
  3680. return false;
  3681. }
  3682.  
  3683. public function StopPanicRegen()
  3684. {
  3685. if( effectManager )
  3686. {
  3687. effectManager.StopPanicRegen();
  3688. }
  3689. }
  3690.  
  3691. public function StartAirRegen() : bool
  3692. {
  3693. if( effectManager )
  3694. {
  3695. return effectManager.StartAirRegen();
  3696. }
  3697.  
  3698. return false;
  3699. }
  3700.  
  3701. public function StopAirRegen()
  3702. {
  3703. if( effectManager )
  3704. {
  3705. effectManager.StopAirRegen();
  3706. }
  3707. }
  3708.  
  3709. public function StartSwimmingStaminaRegen() : bool
  3710. {
  3711. if( effectManager )
  3712. {
  3713. return effectManager.StartSwimmingStaminaRegen();
  3714. }
  3715.  
  3716. return false;
  3717. }
  3718.  
  3719. public function StopSwimmingStaminaRegen()
  3720. {
  3721. if( effectManager )
  3722. {
  3723. effectManager.StopSwimmingStaminaRegen();
  3724. }
  3725. }
  3726.  
  3727. timer function EffectsUpdate( deltaTime : float , id : int)
  3728. {
  3729. if(effectManager)
  3730. effectManager.PerformUpdate( deltaTime );
  3731. }
  3732.  
  3733.  
  3734.  
  3735.  
  3736.  
  3737. public function UpdateRequestedDirectionVariables( headingYawWS : float, orientationYawWS : float )
  3738. {
  3739.  
  3740. SetBehaviorVariable( 'requestedMovementDirection', AngleNormalize( headingYawWS ) );
  3741. SetBehaviorVariable( 'requestedFacingDirection', AngleNormalize( orientationYawWS ) );
  3742. SetBehaviorVariable( 'requestedMovementDirectionForOverlay', AngleNormalize( headingYawWS ) );
  3743. SetBehaviorVariable( 'requestedFacingDirectionForOverlay', AngleNormalize( orientationYawWS ) );
  3744. }
  3745.  
  3746.  
  3747.  
  3748.  
  3749. public function UpdateLookAtVariables( lookAtTargetActive : float, lookAtTarget : Vector )
  3750. {
  3751. var sourceToTargetVector : Vector;
  3752. var pitch : float;
  3753. var sourcePos : Vector;
  3754. var headBoneIdx : int;
  3755. var angleDiff : float;
  3756.  
  3757. lookAtTarget.W = 1.0f;
  3758.  
  3759. angleDiff = AngleDistance( VecHeading( lookAtTarget - GetWorldPosition() ), GetHeading() ) / 180.f;
  3760. SetBehaviorVariable( 'lookatOn', lookAtTargetActive );
  3761. SetBehaviorVectorVariable( 'lookAtTarget', lookAtTarget );
  3762. SetBehaviorVectorVariable( 'lookAtTarget2', lookAtTarget );
  3763. SetBehaviorVariable( 'lookatToHeadingDiffYaw', angleDiff );
  3764. SetBehaviorVariable( 'lookatToHeadingDiffYawForOverlay', angleDiff );
  3765. headBoneIdx = this.GetHeadBoneIndex();
  3766.  
  3767. if ( headBoneIdx >= 0 )
  3768. sourcePos = MatrixGetTranslation( this.GetBoneWorldMatrixByIndex( headBoneIdx ) );
  3769. else
  3770. sourcePos = GetWorldPosition();
  3771.  
  3772. sourceToTargetVector = VecNormalize( lookAtTarget - sourcePos );
  3773. pitch = Rad2Deg( AsinF( ClampF( sourceToTargetVector.Z, -1.0f, 1.0f ) ) );
  3774.  
  3775. if ( lookAtTarget.X == sourcePos.X && lookAtTarget.Y == sourcePos.Y )
  3776. {
  3777. pitch = lookAtTarget.Z < sourcePos.Z? -90 : 90;
  3778. }
  3779.  
  3780. SetBehaviorVariable( 'lookatToHeadingDiffPitch', pitch/90 );
  3781. }
  3782.  
  3783.  
  3784.  
  3785.  
  3786.  
  3787.  
  3788. protected function CriticalBuffInformBehavior(buff : CBaseGameplayEffect);
  3789.  
  3790. public function GetNewRequestedCS() : CBaseGameplayEffect {return newRequestedCS;}
  3791. public function SetNewRequestedCS(buff : CBaseGameplayEffect) {newRequestedCS = buff;}
  3792.  
  3793.  
  3794. public function StartCSAnim(buff : CBaseGameplayEffect) : bool
  3795. {
  3796. LogCritical("Received request to start CS anim for <<" + GetBuffCriticalType(buff) + ">>");
  3797.  
  3798. if(effectManager && effectManager.GetCurrentlyAnimatedCS() == buff)
  3799. {
  3800. LogCritical("ASSERT: Trying to start anims for currently played critical state - aborting!");
  3801. return false;
  3802. }
  3803.  
  3804. if(newRequestedCS == buff)
  3805. return false;
  3806.  
  3807.  
  3808.  
  3809. if( this == thePlayer && IsUsingVehicle())
  3810. return false;
  3811.  
  3812. if(GetCurrentStateName() == 'TraverseExploration')
  3813. ActionCancelAll();
  3814.  
  3815. newRequestedCS = buff;
  3816. SetBehaviorVariable( 'CriticalStateType', (int)GetBuffCriticalType(buff) );
  3817. SetBehaviorVariable( 'bCriticalState', 1);
  3818.  
  3819. return true;
  3820. }
  3821.  
  3822.  
  3823. event OnCriticalStateAnimStart()
  3824. {
  3825.  
  3826. if(!newRequestedCS)
  3827. {
  3828. LogCritical("Aborting start of new CS - it got deleted in the meantime");
  3829. return false;
  3830. }
  3831.  
  3832. LogCritical("Started anim of CS <<" + GetBuffCriticalType(newRequestedCS) + ">>");
  3833.  
  3834. if(effectManager)
  3835. effectManager.SetCurrentlyAnimatedCS(newRequestedCS);
  3836.  
  3837. newRequestedCS = NULL;
  3838.  
  3839. return true;
  3840. }
  3841.  
  3842.  
  3843. public function CriticalEffectAnimationInterrupted(reason : string) : bool
  3844. {
  3845. var buff : CBaseGameplayEffect;
  3846.  
  3847. if(effectManager)
  3848. {
  3849. buff = effectManager.GetCurrentlyAnimatedCS();
  3850. if(buff)
  3851. {
  3852.  
  3853. if(CriticalBuffIsDestroyedOnInterrupt(buff))
  3854. effectManager.RemoveEffect(effectManager.GetCurrentlyAnimatedCS(), true);
  3855.  
  3856. effectManager.SetCurrentlyAnimatedCS(NULL);
  3857. SetBehaviorVariable( 'bCriticalState', 0);
  3858. SetBehaviorVariable( 'CriticalStateType', (int)ECST_None );
  3859.  
  3860. LogCritical("Critical effect animation gets interrupted, reason: " + reason);
  3861. return true;
  3862. }
  3863. }
  3864.  
  3865. return false;
  3866. }
  3867.  
  3868. public function RequestCriticalAnimStop(optional dontSetCriticalToStopped : bool)
  3869. {
  3870. var currentlyAnimatedCritical : CBaseGameplayEffect;
  3871. var critType : ECriticalStateType;
  3872.  
  3873. if(effectManager)
  3874. currentlyAnimatedCritical = effectManager.GetCurrentlyAnimatedCS();
  3875.  
  3876. critType = GetBuffCriticalType(currentlyAnimatedCritical);
  3877.  
  3878. if(currentlyAnimatedCritical)
  3879. LogCritical("Requesting CS anim stop for <<" + critType + ">>, time remaining = " + NoTrailZeros(currentlyAnimatedCritical.GetDurationLeft()) );
  3880. else
  3881. LogCritical("Requesting CS anim stop but there is no critical playing animation right now");
  3882.  
  3883.  
  3884. if(!dontSetCriticalToStopped && IsAlive() )
  3885. SetBehaviorVariable( 'bCriticalStopped', 1 );
  3886.  
  3887. this.SignalGameplayEvent('DisableFinisher');
  3888.  
  3889. this.SignalGameplayEventParamInt('StoppingEffect', (int)critType);
  3890. }
  3891.  
  3892.  
  3893. public function CriticalStateAnimStopped(forceRemoveBuff : bool)
  3894. {
  3895. var buffToStop : CBaseGameplayEffect;
  3896. var findNewBuff, buggedCS : bool;
  3897. var buff : CBaseGameplayEffect;
  3898. var csType : ECriticalStateType;
  3899.  
  3900. if( !ChooseNextCriticalBuffForAnim() )
  3901. {
  3902. SetBehaviorVariable( 'CriticalStateType', (int)ECST_None );
  3903. }
  3904.  
  3905. if(effectManager)
  3906. buff = effectManager.GetCurrentlyAnimatedCS();
  3907.  
  3908. if(buff)
  3909. {
  3910. csType = GetBuffCriticalType(buff);
  3911.  
  3912. LogCritical("Stopping CS animation for <<" + csType + ">>");
  3913.  
  3914. if(thePlayer.HasBuff( EET_Mutagen36) && thePlayer.CanUseSkill(S_Magic_s09) && buff.GetEffectType() == EET_Burning)
  3915. forceRemoveBuff = false;
  3916.  
  3917. if(forceRemoveBuff || buff.GetDurationLeft() < 0 || !buff.IsActive() || CriticalBuffIsDestroyedOnInterrupt(buff))
  3918. {
  3919. {
  3920. LogCritical("Buff <<" + csType + ">> gets removed (CriticalStateAnimStopped)");
  3921. effectManager.RemoveEffect(effectManager.GetCurrentlyAnimatedCS(), true);
  3922. }
  3923. }
  3924. else
  3925. {
  3926. LogCritical("Buff <<" + csType + ">> gets moved to background and won't be played now but isn't removed yet. Duration left = " + NoTrailZeros(buff.GetDurationLeft()) );
  3927. effectManager.SetCurrentlyAnimatedCS(NULL);
  3928. }
  3929. }
  3930. else
  3931. {
  3932.  
  3933. }
  3934.  
  3935.  
  3936.  
  3937. }
  3938.  
  3939.  
  3940.  
  3941.  
  3942. public function ChooseNextCriticalBuffForAnim() : CBaseGameplayEffect
  3943. {
  3944. var max, val, i : int;
  3945. var eff : array<CBaseGameplayEffect>;
  3946. var buff : CBaseGameplayEffect;
  3947.  
  3948. if(!effectManager)
  3949. return NULL;
  3950.  
  3951. eff = effectManager.GetCriticalBuffs();
  3952. eff.Remove(GetCurrentlyAnimatedCS());
  3953. buff = NULL;
  3954.  
  3955. for(i=0; i<eff.Size(); i+=1)
  3956. {
  3957.  
  3958. if(!eff[i].IsActive())
  3959. continue;
  3960.  
  3961.  
  3962. if(!CriticalEffectCanPlayAnimation(eff[i]))
  3963. continue;
  3964.  
  3965. val = CalculateCriticalStateTypePriority( GetBuffCriticalType(eff[i]) );
  3966. if( val >= max )
  3967. {
  3968. max = val;
  3969. buff = eff[i];
  3970. }
  3971. }
  3972.  
  3973. return buff;
  3974. }
  3975.  
  3976. public function ChooseCurrentCriticalBuffForAnim() : CBaseGameplayEffect
  3977. {
  3978. var tempType : ECriticalStateType;
  3979. var max, val, i, size : int;
  3980. var maxSet : bool;
  3981. var eff : array<CBaseGameplayEffect>;
  3982. var buff : CBaseGameplayEffect;
  3983.  
  3984. if(!effectManager)
  3985. return NULL;
  3986.  
  3987. eff = effectManager.GetCurrentEffects();
  3988. size = eff.Size();
  3989. maxSet = false;
  3990. buff = NULL;
  3991.  
  3992. for(i=0; i<size; i+=1)
  3993. {
  3994. tempType = GetBuffCriticalType(eff[i]);
  3995.  
  3996. if(tempType == ECST_None)
  3997. continue;
  3998.  
  3999. if(eff[i].GetDurationLeft() <= 0 || !eff[i].IsActive())
  4000. {
  4001.  
  4002. effectManager.RemoveEffect(eff[i]);
  4003. continue;
  4004. }
  4005.  
  4006. if(tempType != ECST_None)
  4007. {
  4008.  
  4009. if(!CriticalEffectCanPlayAnimation(eff[i]))
  4010. continue;
  4011.  
  4012. val = CalculateCriticalStateTypePriority(tempType);
  4013. if(val > max || !maxSet)
  4014. {
  4015. max = val;
  4016. maxSet = true;
  4017. buff = eff[i];
  4018. }
  4019. }
  4020. }
  4021.  
  4022. return buff;
  4023. }
  4024.  
  4025. public function GetCriticalBuffs() : array<CBaseGameplayEffect>
  4026. {
  4027. var null : array<CBaseGameplayEffect>;
  4028.  
  4029. if(effectManager)
  4030. return effectManager.GetCriticalBuffs();
  4031.  
  4032. return null;
  4033. }
  4034.  
  4035. public function IsHelpless() : bool
  4036. {
  4037. if( HasBuff(EET_Immobilized) ||
  4038. HasBuff(EET_Burning) ||
  4039. HasBuff(EET_Knockdown) ||
  4040. HasBuff(EET_HeavyKnockdown) ||
  4041. HasBuff(EET_Blindness) ||
  4042. HasBuff(EET_Confusion) ||
  4043. HasBuff(EET_Paralyzed) ||
  4044. HasBuff(EET_Hypnotized) ||
  4045. HasBuff(EET_Stagger) ||
  4046. HasBuff(EET_LongStagger) ||
  4047. HasBuff(EET_Tangled) ||
  4048. HasBuff(EET_Ragdoll) ||
  4049. HasBuff(EET_Frozen) ||
  4050. HasBuff(EET_Trap) ||
  4051. HasBuff(EET_KnockdownTypeApplicator) ||
  4052. HasBuff(EET_CounterStrikeHit)
  4053. )
  4054. return true;
  4055.  
  4056. return false;
  4057. }
  4058.  
  4059. public final function IsCriticalTypeHigherThanAllCurrent(crit : ECriticalStateType) : bool
  4060. {
  4061. var i, askedPriority : int;
  4062. var buffs : array<CBaseGameplayEffect>;
  4063.  
  4064. askedPriority = CalculateCriticalStateTypePriority(crit);
  4065. buffs = GetCriticalBuffs();
  4066. for(i=0; i<buffs.Size(); i+=1)
  4067. {
  4068. if(buffs[i].IsActive() && CalculateCriticalStateTypePriority( GetBuffCriticalType(buffs[i]) ) >= askedPriority)
  4069. return false;
  4070. }
  4071.  
  4072. return true;
  4073. }
  4074.  
  4075.  
  4076.  
  4077.  
  4078.  
  4079. public function RecalcEffectDurations()
  4080. {
  4081. if(effectManager)
  4082. effectManager.RecalcEffectDurations();
  4083. }
  4084.  
  4085. public function AddEffectCustom(params : SCustomEffectParams) : EEffectInteract
  4086. {
  4087. if( effectManager && effectManager.IsReady())
  4088. return effectManager.AddEffectCustom(params);
  4089.  
  4090. LogAssert(false, "Actor.AddEffectCustom: <<" + this + ">> effect manager does not exist! Cannot add <<" + params.effectType + ">>");
  4091. return EI_Undefined;
  4092. }
  4093.  
  4094. public function AddEffectDefault(effectType : EEffectType, creat : CGameplayEntity, optional srcName : string, optional signEffect : bool) : EEffectInteract
  4095. {
  4096. if( effectManager && effectManager.IsReady() )
  4097. return effectManager.AddEffectDefault(effectType,creat,srcName,signEffect);
  4098.  
  4099. LogAssert(false, "Actor.AddEffectDefault: <<" + this + ">> effect manager does not exist! Cannot add <<" + effectType + ">>");
  4100. return EI_Undefined;
  4101. }
  4102.  
  4103. public function ProcessOnHitEffects(victim : CActor, silverSword : bool, steelSword : bool, sign : bool)
  4104. {
  4105. if(effectManager)
  4106. effectManager.ProcessOnHitEffects(victim, silverSword, steelSword, sign);
  4107. }
  4108.  
  4109. public function RemoveBuff(effectType : EEffectType, optional csForcedRemove : bool, optional sourceName : string)
  4110. {
  4111. if( effectManager && effectManager.IsReady() )
  4112. effectManager.RemoveEffect(effectManager.GetEffect(effectType, sourceName) , csForcedRemove );
  4113. }
  4114.  
  4115. public function RemoveEffect(effect : CBaseGameplayEffect, optional csForcedRemove : bool)
  4116. {
  4117. if( effectManager && effectManager.IsReady() )
  4118. effectManager.RemoveEffect(effect, csForcedRemove );
  4119. }
  4120.  
  4121. public function RemoveAllNonAutoBuffs( optional removeOils : bool, optional skipPerk14 : bool )
  4122. {
  4123. if( effectManager && effectManager.IsReady() )
  4124. // W3EE - Begin
  4125. effectManager.RemoveAllNonAutoEffects( removeOils, skipPerk14 );
  4126. //effectManager.RemoveAllNonAutoEffects( removeOils );
  4127. // W3EE - End
  4128. }
  4129.  
  4130. public function RemoveAllBuffsOfType(effectType : EEffectType)
  4131. {
  4132. if( effectManager && effectManager.IsReady() )
  4133. effectManager.RemoveAllEffectsOfType(effectType);
  4134. }
  4135.  
  4136. public function RemoveAllBuffsWithSource( source : string )
  4137. {
  4138. if( effectManager && effectManager.IsReady() )
  4139. effectManager.RemoveAllBuffsWithSource( source );
  4140. }
  4141.  
  4142. // W3EE - Begin
  4143. public function CountEffectsOfType( type : EEffectType ) : int
  4144. {
  4145. if( effectManager && effectManager.IsReady() )
  4146. return effectManager.CountEffectsOfType(type);
  4147.  
  4148. return 0;
  4149. }
  4150.  
  4151. public function HasDecoctionEffect() : bool
  4152. {
  4153. if( effectManager && effectManager.IsReady() )
  4154. return effectManager.HasDecoctionEffect();
  4155.  
  4156. return 0;
  4157. }
  4158.  
  4159. public function RemoveFirstBuffWithSource( source : string )
  4160. {
  4161. if( effectManager && effectManager.IsReady() )
  4162. effectManager.RemoveFirstBuffWithSource( source );
  4163. }
  4164. // W3EE - End
  4165.  
  4166. public function HasBuff(effectType : EEffectType) : bool
  4167. {
  4168. if( effectManager && effectManager.IsReady() )
  4169. return effectManager.HasEffect(effectType);
  4170.  
  4171. return false;
  4172. }
  4173.  
  4174. public function GetBuffTimePercentageByType( effectType : EEffectType) : int
  4175. {
  4176. if ( effectManager && effectManager.IsReady() )
  4177. {
  4178. return effectManager.GetEffectTimePercentageByType( effectType );
  4179. }
  4180. return 0;
  4181. }
  4182.  
  4183. public function GetBuffTimePercentage( effect : CBaseGameplayEffect) : int
  4184. {
  4185. if ( effectManager && effectManager.IsReady() )
  4186. {
  4187. return effectManager.GetEffectTimePercentage( effect );
  4188. }
  4189. return 0;
  4190. }
  4191.  
  4192. public function GetCriticalBuffsCount() : int
  4193. {
  4194. if(effectManager)
  4195. return effectManager.GetCriticalBuffsCount();
  4196.  
  4197. return 0;
  4198. }
  4199.  
  4200. public function GetCurrentlyAnimatedCS() : CBaseGameplayEffect
  4201. {
  4202. if(effectManager)
  4203. return effectManager.GetCurrentlyAnimatedCS();
  4204.  
  4205. return NULL;
  4206. }
  4207.  
  4208. public function GetBuff(effectType : EEffectType, optional sourceName : string) : CBaseGameplayEffect
  4209. {
  4210. if(effectManager)
  4211. return effectManager.GetEffect(effectType, sourceName);
  4212.  
  4213. return NULL;
  4214. }
  4215.  
  4216. public function GetBuffs(optional type : EEffectType, optional sourceName : string, optional partialSourceNameSearch : bool) : array<CBaseGameplayEffect>
  4217. {
  4218. var null : array<CBaseGameplayEffect>;
  4219.  
  4220. if(effectManager)
  4221. return effectManager.GetCurrentEffects(type, sourceName, partialSourceNameSearch);
  4222.  
  4223. return null;
  4224. }
  4225.  
  4226. public final function HasPotionBuff() : bool
  4227. {
  4228. if(effectManager)
  4229. return effectManager.HasPotionBuff();
  4230.  
  4231. return false;
  4232. }
  4233.  
  4234. public final function IsImmuneToInstantKill() : bool
  4235. {
  4236. if( HasAbility( 'InstantKillImmune' ) || IsImmortal() || IsInvulnerable() || WillBeUnconscious() )
  4237. {
  4238. return true;
  4239. }
  4240.  
  4241. return false;
  4242. }
  4243.  
  4244. public function IsImmuneToBuff(effect : EEffectType) : bool
  4245. {
  4246. var immunes : CBuffImmunity;
  4247. var i : int;
  4248. var potion, positive, neutral, negative, immobilize, confuse, damage : bool;
  4249. var criticalStatesToResist, resistCriticalStateChance, resistCriticalStateMultiplier : float;
  4250. var mac : CMovingAgentComponent;
  4251.  
  4252. mac = GetMovingAgentComponent();
  4253.  
  4254. if ( mac && mac.IsEntityRepresentationForced() == 512 && !IsUsingVehicle() )
  4255. {
  4256. if( effect != EET_Snowstorm && effect != EET_SnowstormQ403 )
  4257. return false;
  4258. }
  4259.  
  4260. if ( IsCriticalEffectType( effect ) && HasAbility( 'ResistCriticalStates' ) )
  4261. {
  4262. criticalStatesToResist = CalculateAttributeValue( GetAttributeValue( 'critical_states_to_raise_guard' ) );
  4263. resistCriticalStateChance = CalculateAttributeValue( GetAttributeValue( 'resist_critical_state_chance' ) );
  4264. resistCriticalStateMultiplier = CalculateAttributeValue( GetAttributeValue( 'resist_critical_state_chance_mult_per_hit' ) );
  4265.  
  4266. criticalStateCounter = GetCriticalStateCounter();
  4267. resistCriticalStateChance += criticalStateCounter * resistCriticalStateMultiplier;
  4268.  
  4269. if ( criticalStateCounter >= criticalStatesToResist )
  4270. {
  4271. if( resistCriticalStateChance > RandRangeF( 1, 0 ) )
  4272. {
  4273. return true;
  4274. }
  4275. }
  4276. }
  4277.  
  4278. for(i=0; i<buffImmunities.Size(); i+=1)
  4279. {
  4280. if(buffImmunities[i].buffType == effect)
  4281. return true;
  4282. }
  4283.  
  4284. for(i=0; i<buffRemovedImmunities.Size(); i+=1)
  4285. {
  4286. if(buffRemovedImmunities[i].buffType == effect)
  4287. return false;
  4288. }
  4289.  
  4290. immunes = theGame.GetBuffImmunitiesForActor(this);
  4291. if(immunes.immunityTo.Contains(effect))
  4292. return true;
  4293.  
  4294. theGame.effectMgr.GetEffectTypeFlags(effect, potion, positive, neutral, negative, immobilize, confuse, damage);
  4295. if( (potion && immunes.potion) || (positive && immunes.positive) || (neutral && immunes.neutral) || (negative && ( isImmuneToNegativeBuffs || immunes.negative ) ) || (immobilize && immunes.immobilize) || (confuse && immunes.confuse) || (damage && immunes.damage) )
  4296. return true;
  4297.  
  4298. return false;
  4299. }
  4300.  
  4301. public function AddBuffImmunity_AllCritical(source : name, removeIfPresent : bool)
  4302. {
  4303. var i, size : int;
  4304.  
  4305. size = (int)EET_EffectTypesSize;
  4306.  
  4307. for( i=0; i<size; i+=1 )
  4308. {
  4309. if( IsCriticalEffectType(i) )
  4310. AddBuffImmunity(i, source, removeIfPresent);
  4311. }
  4312. }
  4313.  
  4314. protected saved var isImmuneToNegativeBuffs : bool;
  4315. public function AddBuffImmunity_AllNegative(source : name, removeIfPresent : bool)
  4316. {
  4317. isImmuneToNegativeBuffs = true;
  4318. }
  4319.  
  4320. public function AddBuffImmunity(effect : EEffectType, source : name, removeBuffIfPresent : bool)
  4321. {
  4322. var i : int;
  4323. var removed, immuneExists : bool;
  4324. var immunity : SBuffImmunity;
  4325.  
  4326.  
  4327. removed = false;
  4328. for(i=0; i<buffRemovedImmunities.Size(); i+=1)
  4329. {
  4330. if(buffRemovedImmunities[i].buffType == effect && buffRemovedImmunities[i].sources.Contains(source))
  4331. {
  4332. buffRemovedImmunities[i].sources.Remove(source);
  4333. if(buffRemovedImmunities[i].sources.Size() == 0)
  4334. buffRemovedImmunities.Erase(i);
  4335.  
  4336. removed = true;
  4337. break;
  4338. }
  4339. }
  4340.  
  4341. if(!removed)
  4342. {
  4343.  
  4344. immuneExists = false;
  4345. for(i=0; i<buffImmunities.Size(); i+=1)
  4346. {
  4347. if(buffImmunities[i].buffType == effect)
  4348. {
  4349. if(!buffImmunities[i].sources.Contains(source))
  4350. {
  4351. buffImmunities[i].sources.PushBack(source);
  4352. }
  4353. immuneExists = true;
  4354. break;
  4355. }
  4356. }
  4357.  
  4358. if(!immuneExists)
  4359. {
  4360. immunity.buffType = effect;
  4361. immunity.sources.PushBack(source);
  4362. buffImmunities.PushBack(immunity);
  4363. }
  4364. }
  4365.  
  4366.  
  4367. if(removeBuffIfPresent && effectManager)
  4368. effectManager.RemoveAllEffectsOfType(effect);
  4369. }
  4370.  
  4371. public function RemoveBuffImmunity_AllCritical(optional source : name)
  4372. {
  4373. var i, size : int;
  4374.  
  4375.  
  4376. size = (int)EET_EffectTypesSize;
  4377. for(i=0; i<size; i+=1)
  4378. {
  4379. if(IsCriticalEffectType(i))
  4380. RemoveBuffImmunity(i, source);
  4381. }
  4382. }
  4383.  
  4384. public function RemoveBuffImmunity_AllNegative(optional source : name)
  4385. {
  4386. isImmuneToNegativeBuffs = false;
  4387. }
  4388.  
  4389. public function RemoveBuffImmunity(effect : EEffectType, optional source : name)
  4390. {
  4391. var immunes : CBuffImmunity;
  4392. var i : int;
  4393. var immunity : SBuffImmunity;
  4394.  
  4395.  
  4396. for(i=0; i<buffImmunities.Size(); i+=1)
  4397. {
  4398. if(buffImmunities[i].buffType == effect && buffImmunities[i].sources.Contains(source))
  4399. {
  4400. buffImmunities[i].sources.Remove(source);
  4401. if(buffImmunities[i].sources.Size() == 0)
  4402. buffImmunities.Erase(i);
  4403. break;
  4404. }
  4405. }
  4406.  
  4407.  
  4408. if(!IsNameValid(source))
  4409. {
  4410. immunes = theGame.GetBuffImmunitiesForActor(this);
  4411.  
  4412. if(immunes.immunityTo.Contains(effect))
  4413. {
  4414. for(i=0; i<buffRemovedImmunities.Size(); i+=1)
  4415. {
  4416. if(buffRemovedImmunities[i].buffType == effect)
  4417. {
  4418. if(!buffRemovedImmunities[i].sources.Contains(source))
  4419. {
  4420. buffRemovedImmunities[i].sources.PushBack(source);
  4421. }
  4422. return;
  4423. }
  4424. }
  4425.  
  4426.  
  4427. immunity.buffType = effect;
  4428. immunity.sources.PushBack(source);
  4429. buffRemovedImmunities.PushBack(immunity);
  4430. }
  4431. }
  4432. }
  4433.  
  4434. public final function SetIsRecoveringFromKnockdown()
  4435. {
  4436. isRecoveringFromKnockdown = true;
  4437. }
  4438.  
  4439. public final function GetIsRecoveringFromKnockdown() : bool
  4440. {
  4441. return isRecoveringFromKnockdown;
  4442. }
  4443.  
  4444. public function PauseHPRegenEffects(sourceName : name, optional duration : float)
  4445. {
  4446. if(effectManager && effectManager.IsReady())
  4447. effectManager.PauseHPRegenEffects(sourceName, duration);
  4448. }
  4449.  
  4450. public function ResumeHPRegenEffects( sourceName : name, optional forceAll : bool )
  4451. {
  4452. if(effectManager && effectManager.IsReady())
  4453. effectManager.ResumeHPRegenEffects( sourceName, forceAll );
  4454. }
  4455.  
  4456. public function PauseStaminaRegen(sourceName : name, optional duration : float)
  4457. {
  4458. if(effectManager && effectManager.IsReady())
  4459. effectManager.PauseStaminaRegen(sourceName, duration);
  4460. }
  4461.  
  4462. public function ResumeStaminaRegen(sourceName : name)
  4463. {
  4464. if(effectManager && effectManager.IsReady())
  4465. effectManager.ResumeStaminaRegen(sourceName);
  4466. }
  4467.  
  4468.  
  4469. public function GetCriticalStateCounter(optional total : bool) : int
  4470. {
  4471. if ( total )
  4472. return totalCriticalStateCounter;
  4473. return criticalStateCounter;
  4474. }
  4475.  
  4476. public function IncCriticalStateCounter()
  4477. {
  4478. criticalStateCounter += 1;
  4479. totalCriticalStateCounter += 1;
  4480. AddTimer('ResetCriticalStateCounter',5.0,false);
  4481. }
  4482.  
  4483. private timer function ResetCriticalStateCounter( deta : float , id : int)
  4484. {
  4485. criticalStateCounter = 0;
  4486. }
  4487.  
  4488.  
  4489.  
  4490.  
  4491. public function GetTotalSignSpellPower(signSkill : ESkill) : SAbilityAttributeValue;
  4492.  
  4493.  
  4494.  
  4495. public timer function EnableHighlightTimer( time : float , id : int)
  4496. {
  4497. if ( bIsPlayerCurrentTarget && thePlayer.GetCurrentStateName() != 'Exploration' )
  4498. {
  4499. PlayEffect( 'select_character' );
  4500. }
  4501. }
  4502.  
  4503. public function SetBIsPlayerCurrentTarget ( flag : bool )
  4504. {
  4505. bIsPlayerCurrentTarget = flag;
  4506. }
  4507.  
  4508.  
  4509.  
  4510. event OnSlideToTargetAnimEvent( animEventName : name, properties : SSlideToTargetEventProps, animEventType : EAnimationEventType, animEventDuration : float, animInfo : SAnimationEventAnimInfo )
  4511. {
  4512.  
  4513. ProcessSlideToTarget( animEventDuration, properties );
  4514. }
  4515.  
  4516. event OnSlideToTargetDistance( animEventName : name, properties : SMultiValue, animEventType : EAnimationEventType, animEventDuration : float, animInfo : SAnimationEventAnimInfo )
  4517. {
  4518. if ( animEventType == AET_DurationStart )
  4519. {
  4520. ProcessSlideToTargetDistance( animEventDuration, properties.floats[0] );
  4521. }
  4522. }
  4523.  
  4524.  
  4525. public function SetRotationAdjustmentRotateTo( turnTowards : CNode, optional offsetHeading : float )
  4526. {
  4527. var movementAdjustor : CMovementAdjustor = GetMovingAgentComponent().GetMovementAdjustor();
  4528. var ticket : SMovementAdjustmentRequestTicket = movementAdjustor.GetRequest( 'RotateEvent' );
  4529.  
  4530. movementAdjustor.RotateTowards( ticket, turnTowards, offsetHeading );
  4531. }
  4532.  
  4533.  
  4534. public function SetRotationAdjustmentRotateToHeading( heading : float )
  4535. {
  4536. var movementAdjustor : CMovementAdjustor = GetMovingAgentComponent().GetMovementAdjustor();
  4537. var ticket : SMovementAdjustmentRequestTicket = movementAdjustor.GetRequest( 'RotateEvent' );
  4538.  
  4539. movementAdjustor.RotateTo(ticket,heading);
  4540. }
  4541.  
  4542. public function SuspendRotationAdjustment()
  4543. {
  4544. var movementAdjustor : CMovementAdjustor = GetMovingAgentComponent().GetMovementAdjustor();
  4545. var ticket : SMovementAdjustmentRequestTicket = movementAdjustor.GetRequest( 'RotateEvent' );
  4546.  
  4547. movementAdjustor.KeepRotationAdjustmentActive( ticket );
  4548. }
  4549.  
  4550. public function GetRotationRateFromAnimEvent( enumValue : int ) : ERotationRate
  4551. {
  4552. var hax : array<ERotationRate>;
  4553. if ( enumValue < 0 )
  4554. {
  4555. return -1;
  4556. }
  4557. else if ( enumValue < 20 )
  4558. {
  4559.  
  4560. hax.PushBack(RR_0);
  4561. hax.PushBack(RR_30);
  4562. hax.PushBack(RR_60);
  4563. hax.PushBack(RR_90);
  4564. hax.PushBack(RR_180);
  4565. hax.PushBack(RR_360);
  4566. hax.PushBack(RR_1080);
  4567. hax.PushBack(RR_2160);
  4568. return hax[enumValue];
  4569.  
  4570. }
  4571. else
  4572. {
  4573. return enumValue;
  4574. }
  4575. }
  4576.  
  4577. private function GetWoundNameFromDLCForAnim( animInfo : SAnimationEventAnimInfo ) : name
  4578. {
  4579. var i, size : int;
  4580.  
  4581. var dlcFinishersLeftSide : array< CR4FinisherDLC >;
  4582. var dlcFinishersRightSide : array< CR4FinisherDLC >;
  4583.  
  4584. dlcFinishersLeftSide = theGame.GetSyncAnimManager().dlcFinishersLeftSide;
  4585. size = dlcFinishersLeftSide.Size();
  4586.  
  4587. for( i = 0; i < size; i += 1 )
  4588. {
  4589. if( dlcFinishersLeftSide[i].IsFinisherForAnim( animInfo ) )
  4590. {
  4591. return dlcFinishersLeftSide[i].woundName;
  4592. }
  4593. }
  4594.  
  4595. dlcFinishersRightSide = theGame.GetSyncAnimManager().dlcFinishersRightSide;
  4596. size = dlcFinishersRightSide.Size();
  4597.  
  4598. for( i = 0; i < size; i += 1 )
  4599. {
  4600. if( dlcFinishersRightSide[i].IsFinisherForAnim( animInfo ) )
  4601. {
  4602. return dlcFinishersRightSide[i].woundName;
  4603. }
  4604. }
  4605.  
  4606. return 'none';
  4607. }
  4608.  
  4609. event OnEnumAnimEvent( animEventName : name, variant : SEnumVariant, animEventType : EAnimationEventType, animEventDuration : float, animInfo : SAnimationEventAnimInfo )
  4610. {
  4611. var movementAdjustor : CMovementAdjustor;
  4612. var ticket : SMovementAdjustmentRequestTicket;
  4613. var rotationRate : ERotationRate;
  4614. var loopShake : bool;
  4615. var shakeStrength : float;
  4616. var animName : name;
  4617. var player : CR4Player;
  4618. var woundName : name;
  4619.  
  4620. switch( animEventName )
  4621. {
  4622. case 'RotateEvent':
  4623. case 'RotateAwayEvent':
  4624.  
  4625. rotationRate = GetRotationRateFromAnimEvent( variant.enumValue );
  4626. movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor();
  4627.  
  4628. if ( animEventType == AET_DurationStart || animEventType == AET_DurationStartInTheMiddle )
  4629. {
  4630. movementAdjustor.Cancel( movementAdjustor.GetRequest( 'RotateEvent' ) );
  4631.  
  4632. ticket = movementAdjustor.CreateNewRequest( 'RotateEvent' );
  4633.  
  4634. movementAdjustor.Continuous( ticket );
  4635. movementAdjustor.KeepActiveFor( ticket, animEventDuration );
  4636. if ((int)rotationRate >= 0)
  4637. {
  4638. movementAdjustor.MaxRotationAdjustmentSpeed( ticket, (float)((int)rotationRate) );
  4639. }
  4640. movementAdjustor.MatchMoveRotation( ticket );
  4641. movementAdjustor.UpdateSourceAnimation( ticket, animInfo );
  4642. movementAdjustor.CancelIfSourceAnimationUpdateIsNotUpdated( ticket );
  4643. movementAdjustor.SteeringMayOverrideMaxRotationAdjustmentSpeed( ticket );
  4644. if ( (CNewNPC)this )
  4645. {
  4646. if ( animEventName == 'RotateAwayEvent' )
  4647. SignalGameplayEvent( 'RotateAwayEventStart');
  4648. else
  4649. SignalGameplayEvent( 'RotateEventStart');
  4650. }
  4651. }
  4652. else if ( animEventType == AET_DurationEnd )
  4653. {
  4654.  
  4655. SignalGameplayEvent( 'RotateEventEnd');
  4656. }
  4657. else
  4658. {
  4659. ticket = movementAdjustor.GetRequest( 'RotateEvent' );
  4660. movementAdjustor.UpdateSourceAnimation( ticket, animInfo );
  4661. SignalGameplayEvent( 'RotateEventSync');
  4662. }
  4663. break;
  4664.  
  4665. case 'InteractionPriority':
  4666. if ( animEventType == AET_DurationStart )
  4667. {
  4668. SetInteractionPriority( (EInteractionPriority) variant.enumValue );
  4669.  
  4670. RemoveTimer( 'RestoreOriginalInteractionPriorityTimer' );
  4671. AddTimer( 'RestoreOriginalInteractionPriorityTimer', animEventDuration, false, , , true ) ;
  4672. }
  4673. break;
  4674.  
  4675. case 'Dismemberment':
  4676. if ( animEventType == AET_DurationEnd )
  4677. {
  4678. if( variant.enumValue == DWT_DLC_Defined )
  4679. {
  4680. woundName = GetWoundNameFromDLCForAnim( animInfo );
  4681. }
  4682. else
  4683. {
  4684. woundName = GetWoundNameFromWoundType( variant.enumValue );
  4685. }
  4686. SetDismembermentInfo( woundName, this.GetWorldPosition() - thePlayer.GetWorldPosition(), false );
  4687. Dismember();
  4688. DropItemFromSlot( 'r_weapon', true );
  4689. DropItemFromSlot( 'l_weapon', true );
  4690. }
  4691. break;
  4692.  
  4693. case 'Shake':
  4694. if( animEventType == AET_Duration || animEventType == AET_DurationEnd )
  4695. {
  4696. return false;
  4697. }
  4698. loopShake = ( animEventType == AET_DurationStart );
  4699.  
  4700. animName = '';
  4701. if( loopShake )
  4702. {
  4703. animName = 'camera_shake_loop_lvl1_1';
  4704. player = thePlayer;
  4705. player.loopingCameraShakeAnimName = animName;
  4706. thePlayer.AddTimer( 'RemoveQuestCameraShakeTimer', animEventDuration );
  4707. }
  4708.  
  4709. shakeStrength = (int) variant.enumValue;
  4710. shakeStrength = ( shakeStrength / 10 ) * 1.9f + 0.1f ;
  4711. GCameraShake( shakeStrength, true, this.GetWorldPosition(), 30.0f, loopShake, animName);
  4712.  
  4713. break;
  4714.  
  4715. default:
  4716. break;
  4717. }
  4718. }
  4719.  
  4720. function GetWoundNameFromWoundType( woundType : int ) : name
  4721. {
  4722. switch ( woundType )
  4723. {
  4724. case DWT_Head: return 'cut_head';
  4725. case DWT_Torso: return 'cut_torso';
  4726. case DWT_TorsoLeft: return 'none';
  4727. case DWT_TorsoRight: return 'none';
  4728. case DWT_ArmLeft: return 'none';
  4729. case DWT_ArmRight: return 'cut_arm';
  4730. case DWT_LegLeft: return 'none';
  4731. case DWT_LegRight: return 'none';
  4732.  
  4733. case DWT_Morph_Head: return 'morph_cut_head';
  4734. case DWT_Morph_Torso: return 'morph_cut_torso';
  4735. case DWT_Morph_TorsoLeft: return 'none';
  4736. case DWT_Morph_TorsoRight: return 'none';
  4737. case DWT_Morph_ArmLeft: return 'none';
  4738. case DWT_Morph_ArmRight: return 'morph_cut_arm';
  4739. case DWT_Morph_LegLeft: return 'none';
  4740. case DWT_Morph_LegRight: return 'none';
  4741.  
  4742. case DWT_DLC_Defined: return 'none';
  4743. }
  4744. }
  4745.  
  4746. event OnAnimEvent_RotateEvent( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  4747. {
  4748. var variant : SEnumVariant;
  4749. variant.enumValue = -1;
  4750.  
  4751. OnEnumAnimEvent( animEventName, variant, animEventType, 10.0f, animInfo );
  4752. }
  4753.  
  4754. event OnAnimEvent_RotateAwayEvent( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  4755. {
  4756. var variant : SEnumVariant;
  4757. variant.enumValue = -1;
  4758.  
  4759. OnEnumAnimEvent( animEventName, variant, animEventType, 10.0f, animInfo );
  4760. }
  4761.  
  4762. event OnAnimEvent_DeathHitGround( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  4763. {
  4764. var effectName : name;
  4765.  
  4766.  
  4767. if(effectManager)
  4768. {
  4769. if(effectManager.HasEffect(EET_Burning))
  4770. {
  4771. effectName = 'igni_death_hit';
  4772. effectManager.RemoveAllEffectsOfType(EET_Burning, true);
  4773. }
  4774. else
  4775. {
  4776. effectName = '';
  4777. }
  4778.  
  4779. if(IsNameValid(effectName))
  4780. PlayEffect(effectName);
  4781. }
  4782. }
  4783.  
  4784.  
  4785. event OnAnimEvent_Shake0( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  4786. {
  4787. var loopShake : bool = ( animEventType == AET_DurationStart );
  4788. GCameraShake(0.1, true, this.GetWorldPosition(), 30.0f, loopShake);
  4789. }
  4790. event OnAnimEvent_Shake1( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  4791. {
  4792. var loopShake : bool = ( animEventType == AET_DurationStart );
  4793. GCameraShake(0.2, true, this.GetWorldPosition(), 30.0f, loopShake);
  4794. }
  4795. event OnAnimEvent_Shake2( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  4796. {
  4797. var loopShake : bool = ( animEventType == AET_DurationStart );
  4798. GCameraShake(0.4, true, this.GetWorldPosition(), 30.0f, loopShake);
  4799. }
  4800. event OnAnimEvent_Shake3( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  4801. {
  4802. var loopShake : bool = ( animEventType == AET_DurationStart );
  4803. GCameraShake(0.6, true, this.GetWorldPosition(), 30.0f, loopShake);
  4804. }
  4805. event OnAnimEvent_Shake4( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  4806. {
  4807. var loopShake : bool = ( animEventType == AET_DurationStart );
  4808. GCameraShake(0.8, true, this.GetWorldPosition(), 30.0f, loopShake);
  4809. }
  4810. event OnAnimEvent_Shake5( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  4811. {
  4812. var loopShake : bool = ( animEventType == AET_DurationStart );
  4813. GCameraShake(1.0, true, this.GetWorldPosition(), 40.0f, loopShake);
  4814. }
  4815.  
  4816. event OnAnimEvent_DropItem( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  4817. {
  4818.  
  4819.  
  4820. DropItemFromSlot( 'r_weapon' );
  4821. DropItemFromSlot( 'l_weapon' );
  4822. this.BreakAttachment();
  4823. }
  4824.  
  4825. event OnAnimEvent_OnGround( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  4826. {
  4827.  
  4828. if(animEventType != AET_DurationEnd )
  4829. SetBehaviorVariable( 'ExplorationMode', 1 );
  4830. else
  4831. SetBehaviorVariable( 'ExplorationMode', 2 );
  4832. }
  4833.  
  4834. event OnAnimEvent_Death( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  4835. {
  4836. if(animEventType == AET_DurationEnd && effectManager)
  4837. effectManager.OwnerHasFinishedDeathAnim();
  4838. }
  4839.  
  4840. event OnAnimEvent_MountHorseType( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  4841. {
  4842. SignalGameplayEventParamCName('MountHorseType',GetAnimNameFromEventAnimInfo(animInfo));
  4843. }
  4844.  
  4845. event OnAnimEvent_HorseRidingOn( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  4846. {
  4847. SignalGameplayEvent( 'HorseRidingOn' );
  4848. }
  4849.  
  4850.  
  4851. event OnAnimEvent_item_track_hack_reading_book( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  4852. {
  4853. var ids : array<SItemUniqueId>;
  4854.  
  4855. ids = GetInventory().AddAnItem( 'bookshelf_book', 1, true, true, false );
  4856. if( GetInventory().IsIdValid( ids[0] ) )
  4857. {
  4858. GetInventory().MountItem( ids[0], true, true );
  4859. }
  4860. }
  4861.  
  4862.  
  4863. event OnAnimEvent_item_track_hack_reading_book_unmount( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  4864. {
  4865. var ids : array<SItemUniqueId>;
  4866.  
  4867. if( animEventType == AET_DurationEnd )
  4868. {
  4869. ids = GetInventory().GetItemsByName( 'bookshelf_book' );
  4870. if( GetInventory().IsIdValid( ids[0] ) )
  4871. {
  4872. GetInventory().UnmountItem( ids[0], true );
  4873. GetInventory().RemoveItemByName( 'bookshelf_book', -1 );
  4874. }
  4875. }
  4876. }
  4877.  
  4878.  
  4879. event OnDeathAnimFinished()
  4880. {
  4881. if(effectManager)
  4882. effectManager.OwnerHasFinishedDeathAnim();
  4883.  
  4884. if(CanBleed())
  4885. {
  4886. CreateBloodSpill();
  4887. CreateBloodSpill();
  4888. CreateBloodSpill();
  4889. }
  4890. //MODEnableMimics
  4891. if(IsHuman() && this != thePlayer)//{
  4892. SetAnimationSpeedMultiplier(0.0);
  4893. // theGame.GetGuiManager().ShowNotification( "actor" );}
  4894. //MODEnableMimics END
  4895. }
  4896.  
  4897. public function EnableFinishComponent( flag : bool )
  4898. {
  4899. var comp : CComponent;
  4900.  
  4901. comp = GetComponent( "Finish" );
  4902.  
  4903. if ( comp )
  4904. {
  4905. if ( flag && !theGame.GetWorld().NavigationLineTest( thePlayer.GetWorldPosition(), this.GetWorldPosition(), 0.4f ) )
  4906. flag = false;
  4907.  
  4908. comp.SetEnabled( flag );
  4909.  
  4910. if ( flag )
  4911. {
  4912. thePlayer.ProcessIsHoldingDeadlySword();
  4913. thePlayer.UpdateDisplayTarget( true );
  4914. }
  4915. }
  4916. }
  4917.  
  4918. public final function CanBleed() : bool
  4919. {
  4920. var pts, perc : float;
  4921.  
  4922. // W3EE - Begin
  4923. if( ((CNewNPC)this) )
  4924. perc = ((CNewNPC)this).GetNPCCustomStat(theGame.params.DAMAGE_NAME_BLEEDING);
  4925. else
  4926. GetResistValue(CDS_BleedingRes, pts, perc);
  4927. // W3EE - End
  4928.  
  4929. return perc < 1;
  4930. }
  4931.  
  4932. public final function CreateBloodSpill()
  4933. {
  4934. var bloodTemplate : CEntityTemplate;
  4935.  
  4936. bloodTemplate = (CEntityTemplate)LoadResource("blood_0" + RandRange(4));
  4937. theGame.CreateEntity(bloodTemplate, GetWorldPosition() + VecRingRand(0, 0.5) , EulerAngles(0, RandF() * 360, 0));
  4938. }
  4939.  
  4940.  
  4941.  
  4942.  
  4943. public function DropItemFromSlot( slotName : name, optional removeFromInv : bool )
  4944. {
  4945. var itemToDrop : SItemUniqueId;
  4946. var inv : CInventoryComponent;
  4947. var droppedWeapon : SDroppedItem;
  4948. var itemEntity : CItemEntity;
  4949.  
  4950. inv = GetInventory();
  4951. itemToDrop = inv.GetItemFromSlot(slotName);
  4952. if ( inv.IsIdValid( itemToDrop ) )
  4953. {
  4954. itemEntity = inv.GetItemEntityUnsafe( itemToDrop );
  4955. AddDroppedItem( inv.GetItemName( itemToDrop ), itemEntity );
  4956.  
  4957.  
  4958.  
  4959.  
  4960. inv.DropItem( itemToDrop, removeFromInv );
  4961. }
  4962. }
  4963.  
  4964. public function AddDroppedItem( itemName : name, entity : CEntity )
  4965. {
  4966. var droppedItem : SDroppedItem;
  4967.  
  4968. droppedItem.itemName = itemName;
  4969. droppedItem.entity = entity;
  4970. droppedItems.PushBack( droppedItem );
  4971. }
  4972.  
  4973. public function RemoveDroppedItem( itemName : name, destroy : bool )
  4974. {
  4975. var i : int;
  4976.  
  4977. i = 0;
  4978. while ( i < droppedItems.Size() )
  4979. {
  4980. if ( droppedItems[i].itemName == itemName )
  4981. {
  4982.  
  4983. if ( destroy && droppedItems[i].entity )
  4984. {
  4985. droppedItems[i].entity.Destroy();
  4986. }
  4987. droppedItems.Erase(i);
  4988. }
  4989. else
  4990. {
  4991. i += 1;
  4992. }
  4993. }
  4994. }
  4995.  
  4996. public function DropEquipment( tag : name, optional direction : Vector )
  4997. {
  4998. var dropPhysics : CDropPhysicsComponent;
  4999.  
  5000. if ( tag == '' )
  5001. {
  5002. LogAssert( false, "CActor.DropEquipment: empty tag!" );
  5003. return;
  5004. }
  5005.  
  5006. dropPhysics = (CDropPhysicsComponent)GetComponentByClassName( 'CDropPhysicsComponent' );
  5007. if ( dropPhysics )
  5008. {
  5009. dropPhysics.DropMeshByTag( tag, direction );
  5010. }
  5011. }
  5012.  
  5013. public function SetWound( woundName : name, optional spawnEntity : bool, optional createParticles : bool,
  5014. optional dropEquipment : bool, optional playSound : bool,
  5015. optional direction : Vector, optional playedEffectsMask : int )
  5016. {
  5017. var dc : CDismembermentComponent;
  5018. dc = (CDismembermentComponent)GetComponentByClassName( 'CDismembermentComponent' );
  5019. if ( dc )
  5020. {
  5021.  
  5022.  
  5023. if ( dc.IsExplosionWound( woundName ) )
  5024. {
  5025. createParticles = false;
  5026. }
  5027. dc.SetVisibleWound( woundName, spawnEntity, createParticles, dropEquipment, playSound, direction, playedEffectsMask );
  5028. }
  5029. }
  5030.  
  5031. public function IsCurrentWound( woundName : name ) : bool
  5032. {
  5033. var dc : CDismembermentComponent;
  5034. dc = (CDismembermentComponent)GetComponentByClassName( 'CDismembermentComponent' );
  5035. if ( dc )
  5036. {
  5037. return ( dc.GetVisibleWoundName() == woundName );
  5038. }
  5039. return false;
  5040. }
  5041.  
  5042. public function IsWoundDefined( woundName : name ) : bool
  5043. {
  5044. var dc : CDismembermentComponent;
  5045. dc = (CDismembermentComponent)GetComponentByClassName( 'CDismembermentComponent' );
  5046. if ( dc )
  5047. {
  5048. return dc.IsWoundDefined( woundName );
  5049. }
  5050. return false;
  5051. }
  5052.  
  5053. public function GetNearestWoundForBone( boneIndex : int, directionWS : Vector, woundTypeFlags : EWoundTypeFlags ) : name
  5054. {
  5055. var dc : CDismembermentComponent;
  5056. dc = (CDismembermentComponent)GetComponentByClassName( 'CDismembermentComponent' );
  5057. if ( dc )
  5058. {
  5059. return dc.GetNearestWoundNameForBone( boneIndex, directionWS, woundTypeFlags );
  5060. }
  5061. return '';
  5062. }
  5063.  
  5064. private var woundToDismember : name;
  5065. private var forwardVector : Vector;
  5066. private var dismemberForceRagdoll : bool;
  5067. private var dismemberEffectsMask : int;
  5068. public function SetDismembermentInfo( woundName : name, vec : Vector, forceRagoll : bool, optional playedEffectsMask : int )
  5069. {
  5070. woundToDismember = woundName;
  5071. forwardVector = vec;
  5072. dismemberForceRagdoll = forceRagoll;
  5073. dismemberEffectsMask = playedEffectsMask;
  5074. }
  5075.  
  5076. public timer function DelayedDismemberTimer( time : float , id : int)
  5077. {
  5078. Dismember();
  5079. }
  5080.  
  5081. private function Dismember()
  5082. {
  5083. SetWound( woundToDismember, true, true, true, true, forwardVector, dismemberEffectsMask );
  5084.  
  5085. if(dismemberForceRagdoll && ((CMovingPhysicalAgentComponent)GetMovingAgentComponent()).HasRagdoll() )
  5086. {
  5087. TurnOnRagdoll();
  5088. }
  5089. }
  5090.  
  5091. public function TurnOnRagdoll()
  5092. {
  5093. SetBehaviorVariable( 'Ragdoll_Weight', 1.f );
  5094. RaiseEvent( 'Ragdoll' );
  5095. //MODEnableMimics
  5096. if(IsHuman() && this != thePlayer)//{
  5097. SetAnimationSpeedMultiplier(0.0);
  5098. // theGame.GetGuiManager().ShowNotification( "actor" );}
  5099. if(this == thePlayer)
  5100. AddTimer( 'Reztart', 6, false, , , true );
  5101. }
  5102.  
  5103. timer function Reztart( deltaTime : float , id : int)
  5104. {
  5105. var actors : array<CActor>;
  5106. var actor : CActor;
  5107. var i : int;
  5108.  
  5109. actors = GetActorsInRange( thePlayer, 1000, 999 );
  5110.  
  5111. for( i = 0; i < actors.Size(); i += 1 )
  5112. {
  5113. actor = (CActor) actors[i];
  5114. if ( actor.GetVoicetag() == 'GERALT' )
  5115. continue;
  5116. if (actor.IsHuman())//{
  5117. activateMimicsAndHiResShadows(actor);
  5118. // Log("Reztart");
  5119. // Log(actor);}
  5120. }
  5121.  
  5122. AddTimer( 'Reztart', 15, false, , , true );
  5123. // theGame.GetGuiManager().ShowNotification( "geralt" );
  5124. if(FactsDoesExist("reztart")){
  5125. FactsRemove("reztart");
  5126. RemoveTimer( 'Reztart' );
  5127. return;}
  5128. FactsAdd("reztart");
  5129. //MODEnableMimics END
  5130. }
  5131.  
  5132.  
  5133.  
  5134. private function FindAttackTargets(preAttackData : CPreAttackEventData) : array<CGameplayEntity>
  5135. {
  5136. var targets : array<CGameplayEntity>;
  5137. var i : int;
  5138. var attitude : bool;
  5139. var canLog : bool;
  5140.  
  5141. canLog = theGame.CanLog();
  5142.  
  5143. if(preAttackData.rangeName == '')
  5144. {
  5145. if ( canLog )
  5146. {
  5147. LogAssert(false, "CActor.FindAttackTargets: attack <<" + preAttackData.attackName + ">> of <<" + this + ">> has no range defined!!! Skipping hit!!!");
  5148. LogDMHits("CActor.FindAttackTargets: attack <<" + preAttackData.attackName + ">> of <<" + this + ">> has no range defined!!! Skipping hit!!!");
  5149. }
  5150. return targets;
  5151. }
  5152. else
  5153. {
  5154. GatherEntitiesInAttackRange(targets, preAttackData.rangeName);
  5155. }
  5156.  
  5157.  
  5158. for(i=targets.Size()-1; i>=0; i-=1)
  5159. {
  5160. if(!targets[i] || targets[i] == this)
  5161. {
  5162.  
  5163. targets.EraseFast(i);
  5164. }
  5165. else if( (W3SignEntity)targets[i] || (CProjectileTrajectory)targets[i] || (CDamageAreaEntity)targets[i] || (W3ToxicCloud)targets[i])
  5166. {
  5167.  
  5168. targets.EraseFast(i);
  5169. }
  5170. else if(!targets[i].IsAlive())
  5171. {
  5172.  
  5173. targets.EraseFast(i);
  5174. }
  5175. else if( targets[i].HasTag( 'isHiddenUnderground' ) )
  5176. {
  5177.  
  5178. targets.EraseFast(i);
  5179. }
  5180. else
  5181. {
  5182.  
  5183. attitude = IsRequiredAttitudeBetween(this, targets[i], preAttackData.Damage_Hostile, preAttackData.Damage_Neutral, preAttackData.Damage_Friendly || ((CActor)targets[i]).HasBuff(EET_AxiiGuardMe) );
  5184. if(!attitude)
  5185. {
  5186. if ( canLog )
  5187. {
  5188. LogDMHits("Attacker <<" + this + ">> is skipping target << " + targets[i] + ">> due to failed attitude check");
  5189. }
  5190. targets.EraseFast(i);
  5191. }
  5192. }
  5193. }
  5194.  
  5195.  
  5196.  
  5197.  
  5198. return targets;
  5199. }
  5200.  
  5201. public function IsSuperHeavyAttack(attackName : name) : bool
  5202. {
  5203. return theGame.GetDefinitionsManager().AbilityHasTag(attackName, theGame.params.ATTACK_NAME_SUPERHEAVY);
  5204. }
  5205.  
  5206. public function IsHeavyAttack(attackName : name) : bool
  5207. {
  5208. return theGame.GetDefinitionsManager().AbilityHasTag(attackName, theGame.params.ATTACK_NAME_HEAVY);
  5209. }
  5210.  
  5211. public function IsLightAttack(attackName : name) : bool
  5212. {
  5213. return theGame.GetDefinitionsManager().AbilityHasTag(attackName, theGame.params.ATTACK_NAME_LIGHT);
  5214. }
  5215.  
  5216.  
  5217. function BlinkWeapon(optional weaponId : SItemUniqueId) : bool
  5218. {
  5219. if ( GetInventory().IsIdValid(weaponId) )
  5220. GetInventory().PlayItemEffect(weaponId,'flash_fx');
  5221. else
  5222. {
  5223. return PlayEffectOnHeldWeapon('flash_fx');
  5224. }
  5225.  
  5226. return true;
  5227. }
  5228.  
  5229. function PlayEffectOnHeldWeapon( effectName : name, optional disable : bool ) : bool
  5230. {
  5231. var itemId : SItemUniqueId;
  5232. var inv : CInventoryComponent;
  5233.  
  5234. inv = GetInventory();
  5235. itemId = inv.GetItemFromSlot('r_weapon');
  5236.  
  5237. if ( !inv.IsIdValid(itemId) )
  5238. {
  5239. itemId = inv.GetItemFromSlot('l_weapon');
  5240.  
  5241. if ( !inv.IsIdValid(itemId) )
  5242. return false;
  5243. }
  5244. if ( disable )
  5245. inv.StopItemEffect(itemId,effectName);
  5246. else
  5247. inv.PlayItemEffect(itemId,effectName);
  5248.  
  5249. return true;
  5250. }
  5251.  
  5252.  
  5253. protected function PerformCounterCheck(parryInfo: SParryInfo) : bool;
  5254.  
  5255.  
  5256. function PerformPerfectParryCheck(parryInfo: SParryInfo) : bool;
  5257. function PerformParryCheck(parryInfo: SParryInfo) : bool;
  5258.  
  5259.  
  5260. event OnPreAttackEvent(animEventName : name, animEventType : EAnimationEventType, data : CPreAttackEventData, animInfo : SAnimationEventAnimInfo )
  5261. {
  5262. var parriedBy : array<CActor>;
  5263. var weaponId : SItemUniqueId;
  5264. var player : CR4Player = thePlayer;
  5265. var parried, countered : bool;
  5266.  
  5267.  
  5268.  
  5269.  
  5270. if(animEventType == AET_DurationStart)
  5271. {
  5272. ignoreAttack = false;
  5273. SetAttackData(data);
  5274. weaponId = GetInventory().GetItemFromSlot(data.weaponSlot);
  5275. if ( this != thePlayer )
  5276. BlinkWeapon(weaponId);
  5277.  
  5278. SetCurrentAttackData(data, animInfo );
  5279. if ( data.rangeName == 'useCollisionFromItem' )
  5280. {
  5281. lastAttackRangeName = data.rangeName;
  5282. }
  5283. }
  5284.  
  5285. else if(animEventType == AET_DurationEnd)
  5286. {
  5287. attackEventInProgress = false;
  5288.  
  5289.  
  5290. if ( ignoreAttack )
  5291. {
  5292. ignoreAttack = false;
  5293. return true;
  5294. }
  5295.  
  5296.  
  5297. if ( this == thePlayer && ( GetEventEndsAtTimeFromEventAnimInfo(animInfo) - GetLocalAnimTimeFromEventAnimInfo(animInfo) > 0.06 ))
  5298. return true;
  5299.  
  5300. weaponId = GetInventory().GetItemFromSlot(data.weaponSlot);
  5301.  
  5302. if(!GetInventory().IsIdValid(weaponId) || data.attackName == '')
  5303. {
  5304. LogAttackEvents("No valid attack data set - skipping hit!");
  5305. LogAssert(false, "No valid attack data set - skipping hit!");
  5306. return false;
  5307. }
  5308.  
  5309. hitTargets = FindAttackTargets(data);
  5310. parriedBy = TestParryAndCounter(data, weaponId, parried, countered);
  5311.  
  5312. if( data.attackName == 'attack_speed_based' && this == thePlayer )
  5313. return false;
  5314.  
  5315. lastAttackRangeName = data.rangeName;
  5316. DoAttack(data, weaponId, parried, countered, parriedBy, GetAnimNameFromEventAnimInfo( animInfo ), GetLocalAnimTimeFromEventAnimInfo( animInfo ));
  5317. }
  5318. }
  5319.  
  5320. private function PreAttackParry()
  5321. {
  5322. var data : CPreAttackEventData;
  5323. var animInfo : SAnimationEventAnimInfo;
  5324. var parriedBy : array<CActor>;
  5325. var weaponId : SItemUniqueId;
  5326. var parried, countered : bool;
  5327.  
  5328. if ( !attackEventInProgress )
  5329. return;
  5330.  
  5331. GetCurrentAttackDataAndAnimInfo( data, animInfo);
  5332.  
  5333. weaponId = GetInventory().GetItemFromSlot(data.weaponSlot);
  5334.  
  5335. if(!GetInventory().IsIdValid(weaponId) || data.attackName == '')
  5336. {
  5337. LogAttackEvents("No valid attack data set - skipping hit!");
  5338. LogAssert(false, "No valid attack data set - skipping hit!");
  5339. return;
  5340. }
  5341.  
  5342. parriedBy = TestParryAndCounter(data, weaponId, parried, countered);
  5343. if ( parried || countered )
  5344. {
  5345. DoAttack(data, weaponId, parried, countered, parriedBy, GetAnimNameFromEventAnimInfo( animInfo ), GetLocalAnimTimeFromEventAnimInfo( animInfo ));
  5346. ignoreAttack = false;
  5347. }
  5348. }
  5349.  
  5350.  
  5351.  
  5352. protected var attackEventInProgress : bool;
  5353. private var ignoreAttack : bool;
  5354. private var currentAttackData : CPreAttackEventData;
  5355. private var currentAttackAnimInfo : SAnimationEventAnimInfo;
  5356. private var ignoreTargetsForCurrentAttack : array<CGameplayEntity>;
  5357.  
  5358. private function SetCurrentAttackData(data : CPreAttackEventData , animInfo : SAnimationEventAnimInfo)
  5359. {
  5360. currentAttackData = data;
  5361. currentAttackAnimInfo = animInfo;
  5362. ignoreTargetsForCurrentAttack.Clear();
  5363. attackEventInProgress = true;
  5364. SignalGameplayEvent('NewCurrentAttackData');
  5365. }
  5366.  
  5367. private function GetCurrentAttackDataAndAnimInfo(out data : CPreAttackEventData , out animInfo : SAnimationEventAnimInfo) : bool
  5368. {
  5369. if ( !attackEventInProgress )
  5370. return false;
  5371.  
  5372. data = currentAttackData;
  5373. animInfo = currentAttackAnimInfo;
  5374.  
  5375. return true;
  5376. }
  5377.  
  5378. public function GetCurrentAttackData( out data : CPreAttackEventData ) : bool
  5379. {
  5380. if ( !attackEventInProgress )
  5381. return false;
  5382.  
  5383. data = currentAttackData;
  5384.  
  5385. return true;
  5386. }
  5387.  
  5388.  
  5389.  
  5390. event OnCollisionFromItem( collidedEntity : CGameplayEntity, optional itemEntity : CItemEntity )
  5391. {
  5392. var data : CPreAttackEventData;
  5393. var animInfo : SAnimationEventAnimInfo;
  5394. var parriedBy : array<CActor>;
  5395. var weaponId : SItemUniqueId;
  5396. var parried, countered : bool;
  5397. var hasProperAttitude : bool;
  5398. var npc : CNewNPC;
  5399.  
  5400. if ( !attackEventInProgress )
  5401. {
  5402. LogItemCollision("Item " + itemEntity + " collided with " + collidedEntity + " but Attack is not in progress");
  5403. return false;
  5404. }
  5405.  
  5406. npc = (CNewNPC) this;
  5407. if ( npc && !npc.IsAttacking() )
  5408. {
  5409. attackEventInProgress = false;
  5410. if ( ignoreAttack )
  5411. {
  5412. ignoreAttack = false;
  5413. }
  5414.  
  5415. LogItemCollision("Item " + itemEntity + " collided with " + collidedEntity + " but npc is not attacking");
  5416. return false;
  5417. }
  5418.  
  5419. if ( !collidedEntity )
  5420. {
  5421. LogItemCollision("Item " + itemEntity + " collided with NOT actor");
  5422. return false;
  5423. }
  5424.  
  5425. if ( ignoreTargetsForCurrentAttack.Contains(collidedEntity) )
  5426. return false;
  5427.  
  5428. GetCurrentAttackDataAndAnimInfo( data, animInfo);
  5429.  
  5430. if ( data.rangeName != 'useCollisionFromItem' )
  5431. return false;
  5432.  
  5433. hasProperAttitude = IsRequiredAttitudeBetween(this, collidedEntity, data.Damage_Hostile, data.Damage_Neutral, data.Damage_Friendly);
  5434. if ( !hasProperAttitude )
  5435. {
  5436. return false;
  5437. }
  5438.  
  5439. weaponId = GetInventory().GetItemFromSlot(data.weaponSlot);
  5440.  
  5441. GetInventory().GetItemEntityUnsafe(weaponId) == itemEntity;
  5442.  
  5443. if(!GetInventory().IsIdValid(weaponId) || data.attackName == '' )
  5444. {
  5445. LogAttackEvents("No valid attack data set - skipping hit!");
  5446. LogAssert(false, "No valid attack data set - skipping hit!");
  5447. return false;
  5448. }
  5449. else if ( itemEntity && GetInventory().GetItemEntityUnsafe(weaponId) != itemEntity )
  5450. {
  5451. LogItemCollision("Item " + itemEntity + " collided with " + collidedEntity + " but Attack is for different item");
  5452. return false;
  5453. }
  5454.  
  5455.  
  5456.  
  5457. if ( this.HasAbility( 'WildHunt_Imlerith' ) )
  5458. data.canBeDodged = false;
  5459.  
  5460. hitTargets.PushBack(collidedEntity);
  5461. parriedBy = TestParryAndCounter(data, weaponId, parried, countered);
  5462.  
  5463. DoAttack(data, weaponId, parried, countered, parriedBy, GetAnimNameFromEventAnimInfo( animInfo ), GetLocalAnimTimeFromEventAnimInfo( animInfo ));
  5464.  
  5465. LogItemCollision("Item " + itemEntity + " collided with " + collidedEntity + " and Attack should deal dmg");
  5466.  
  5467. ignoreTargetsForCurrentAttack.PushBack(collidedEntity);
  5468. ignoreAttack = true;
  5469. return true;
  5470. }
  5471.  
  5472.  
  5473.  
  5474. event OnCollisionFromGiantWeapon( collidedActor : CActor, optional itemEntity : CItemEntity )
  5475. {
  5476. var data : CPreAttackEventData;
  5477. var animInfo : SAnimationEventAnimInfo;
  5478. var parriedBy : array<CActor>;
  5479. var weaponId : SItemUniqueId;
  5480. var parried, countered : bool;
  5481. var hasProperAttitude : bool;
  5482. var npc : CNewNPC;
  5483.  
  5484. if ( !attackEventInProgress )
  5485. {
  5486. LogItemCollision("Item " + itemEntity + " collided with " + collidedActor + " but Attack is not in progress");
  5487. return false;
  5488. }
  5489.  
  5490. npc = (CNewNPC) this;
  5491. if ( npc && !npc.IsAttacking() )
  5492. {
  5493. attackEventInProgress = false;
  5494. if ( ignoreAttack )
  5495. {
  5496. ignoreAttack = false;
  5497. }
  5498.  
  5499. LogItemCollision("Item " + itemEntity + " collided with " + collidedActor + " but npc is not attacking");
  5500. return false;
  5501. }
  5502.  
  5503. if ( !collidedActor )
  5504. {
  5505. LogItemCollision("Item " + itemEntity + " collided with NOT actor");
  5506. return false;
  5507. }
  5508.  
  5509. if ( ignoreTargetsForCurrentAttack.Contains(collidedActor) )
  5510. return false;
  5511.  
  5512. GetCurrentAttackDataAndAnimInfo( data, animInfo);
  5513.  
  5514. if ( data.rangeName != 'useCollisionFromItem' )
  5515. return false;
  5516.  
  5517. hasProperAttitude = IsRequiredAttitudeBetween(this, collidedActor, data.Damage_Hostile, data.Damage_Neutral, data.Damage_Friendly);
  5518. if ( !hasProperAttitude )
  5519. {
  5520.  
  5521. }
  5522.  
  5523. weaponId = GetInventory().GetItemFromSlot(data.weaponSlot);
  5524.  
  5525. GetInventory().GetItemEntityUnsafe(weaponId) == itemEntity;
  5526.  
  5527. if(!GetInventory().IsIdValid(weaponId) || data.attackName == '' )
  5528. {
  5529. LogAttackEvents("No valid attack data set - skipping hit!");
  5530. LogAssert(false, "No valid attack data set - skipping hit!");
  5531. return false;
  5532. }
  5533. else if ( itemEntity && GetInventory().GetItemEntityUnsafe(weaponId) != itemEntity )
  5534. {
  5535. LogItemCollision("Item " + itemEntity + " collided with " + collidedActor + " but Attack is for different item");
  5536. return false;
  5537. }
  5538.  
  5539.  
  5540. if ( collidedActor.HasAbility( 'CustomReactionToGiantWeapon' ) || collidedActor.HasTag( 'CustomReactionToGiantWeapon' ) )
  5541. {
  5542. this.SignalGameplayEventParamObject( 'ReactionToGiantWeaponActor', collidedActor );
  5543. this.SignalGameplayEventParamObject( 'ReactionToGiantWeaponItem', itemEntity );
  5544. }
  5545. else
  5546. {
  5547. return false;
  5548. }
  5549.  
  5550. return true;
  5551. }
  5552.  
  5553.  
  5554.  
  5555.  
  5556. public function SetAttackData(data : CPreAttackEventData)
  5557. {
  5558. var i : int;
  5559. var targets : array<CGameplayEntity>;
  5560. var npc : CNewNPC;
  5561. var actor : CActor;
  5562.  
  5563.  
  5564. if(!GetInventory().IsIdValid(GetInventory().GetItemFromSlot(data.weaponSlot)) )
  5565. {
  5566. if ( theGame.CanLog() )
  5567. {
  5568. LogAssert(false, "Attacker <<" + this + ">> has invalid weapon ID, no attack data set!!!");
  5569. LogDMHits("Attacker <<" + this + ">> has invalid weapon ID, no attack data set!!!");
  5570. }
  5571. return;
  5572. }
  5573.  
  5574.  
  5575. SetDebugAttackRange(data.rangeName);
  5576.  
  5577.  
  5578. if(!IsNameValid(attackActionName))
  5579. attackActionName = data.attackName;
  5580.  
  5581.  
  5582. npc = (CNewNPC)this;
  5583. if(npc)
  5584. {
  5585. npc.SetCounterWindowStartTime(theGame.GetEngineTime());
  5586. npc.SignalGameplayEventParamInt( 'swingType', data.swingType );
  5587. npc.SignalGameplayEventParamInt( 'swingDir', data.swingDir );
  5588.  
  5589. if((ShouldProcessTutorial('TutorialCounter') || ShouldProcessTutorial('TutorialDodge')) && GetTarget() == thePlayer && FactsQuerySum("tut_fight_use_slomo") > 0 && !thePlayer.IsCurrentlyDodging())
  5590. {
  5591.  
  5592. if(theGame.GetTutorialSystem().AreMessagesEnabled())
  5593. theGame.SetTimeScale(0.001, theGame.GetTimescaleSource(ETS_TutorialFight), theGame.GetTimescalePriority(ETS_TutorialFight) );
  5594.  
  5595.  
  5596. FactsAdd("tut_fight_slomo_ON");
  5597. }
  5598. }
  5599.  
  5600.  
  5601. targets = FindAttackTargets(data);
  5602.  
  5603. if ( targets.Size() == 0 && this == thePlayer && this.slideTarget)
  5604. targets.PushBack(this.slideTarget);
  5605.  
  5606. for(i=0; i<targets.Size(); i+=1)
  5607. {
  5608.  
  5609. npc = (CNewNPC)targets[i];
  5610. if( npc )
  5611. {
  5612. if ( !this.IsUsingHorse() )
  5613. {
  5614.  
  5615. if(data.hitReactionType == EHRT_Light)
  5616. npc.SignalGameplayEventParamInt('Time2Dodge', (int)EDT_Attack_Light );
  5617. else if(data.hitReactionType == EHRT_Heavy)
  5618. npc.SignalGameplayEventParamInt('Time2Dodge', (int)EDT_Attack_Heavy );
  5619.  
  5620. npc.SignalGameplayEventParamInt( 'swingType', data.swingType );
  5621. npc.SignalGameplayEventParamInt( 'swingDir', data.swingDir );
  5622. }
  5623.  
  5624. if( ( npc.IsShielded(this) || npc.IsGuarded() ) && data.Can_Parry_Attack)
  5625. {
  5626.  
  5627. if(IsHeavyAttack(attackActionName))
  5628. {
  5629. npc.SignalGameplayEventParamInt('ParryStart',1);
  5630.  
  5631. }
  5632. else
  5633. {
  5634. npc.SignalGameplayEventParamInt('ParryStart',0);
  5635.  
  5636. }
  5637. }
  5638. }
  5639.  
  5640. actor = (CActor) targets[i];
  5641. if ( actor )
  5642. {
  5643.  
  5644. actor.IsAttacked();
  5645. }
  5646. }
  5647. }
  5648.  
  5649. var perfectParried : bool;
  5650. protected function TestParryAndCounter(data : CPreAttackEventData, weaponId : SItemUniqueId, out parried : bool, out countered : bool) : array<CActor>
  5651. {
  5652. var actor : CActor;
  5653. var i : int;
  5654. var parryInfo : SParryInfo;
  5655. var parriedBy : array<CActor>;
  5656. var npc : CNewNPC;
  5657. var playerTarget : CR4Player;
  5658. var levelDiff : int;
  5659. var chanceToFailParry : float;
  5660.  
  5661.  
  5662.  
  5663.  
  5664. SetDebugAttackRange(data.rangeName);
  5665. RemoveTimer('PostAttackDebugRangeClear');
  5666.  
  5667.  
  5668. for(i=hitTargets.Size()-1; i>=0; i-=1)
  5669. {
  5670. actor = (CActor)hitTargets[i];
  5671. if(!actor)
  5672. continue;
  5673.  
  5674. parryInfo = ProcessParryInfo(this, actor, data.swingType, data.swingDir, attackActionName, weaponId, data.Can_Parry_Attack );
  5675. playerTarget = (CR4Player)hitTargets[i];
  5676. parried = false;
  5677. perfectParried = false;
  5678. countered = false;
  5679.  
  5680. // W3EE - Begin
  5681. /*if( FactsQuerySum( "tut_fight_start" ) > 0 || actor.HasAbility( 'IgnoreLevelDiffForParryTest' ) )
  5682. levelDiff = 0;
  5683. else
  5684. levelDiff = GetLevel() - actor.GetLevel();*/
  5685.  
  5686. if( thePlayer.IsInFistFightMiniGame() || /*levelDiff < theGame.params.LEVEL_DIFF_DEADLY &&*/ (!playerTarget || playerTarget.IsActionAllowed(EIAB_Counter)) )
  5687. countered = actor.PerformCounterCheck(parryInfo);
  5688. // W3EE - End
  5689.  
  5690. if(!countered)
  5691. {
  5692. // W3EE - Begin
  5693. if( thePlayer.IsInFistFightMiniGame() || /*levelDiff < theGame.params.LEVEL_DIFF_DEADLY &&*/ (!playerTarget || playerTarget.IsActionAllowed(EIAB_Parry)) )
  5694. {
  5695. /*if ( !thePlayer.IsInFistFightMiniGame() && levelDiff >= theGame.params.LEVEL_DIFF_HIGH )
  5696. {
  5697. chanceToFailParry = CalculateAttributeValue(actor.GetAttributeValue('chance_to_fail_parry_per_level_diff'));
  5698. if ( chanceToFailParry > 0 )
  5699. {
  5700. chanceToFailParry *= (levelDiff - theGame.params.LEVEL_DIFF_HIGH + 1);
  5701. if( RandRange(100) < chanceToFailParry )
  5702. parryInfo.canBeParried = false;
  5703. }
  5704. }*/
  5705. // W3EE - End
  5706. parried = actor.PerformPerfectParryCheck(parryInfo);
  5707. perfectParried = parried;
  5708. if( !parried )
  5709. parried = actor.PerformParryCheck(parryInfo);
  5710. }
  5711. }
  5712. else if(playerTarget && data.Can_Parry_Attack)
  5713. {
  5714. FactsAdd("ach_counter", 1, 4 );
  5715. theGame.GetGamerProfile().CheckLearningTheRopes();
  5716. }
  5717.  
  5718.  
  5719.  
  5720.  
  5721.  
  5722.  
  5723. if(countered || parried)
  5724. {
  5725.  
  5726. actor.SetDetailedHitReaction(data.swingType, data.swingDir);
  5727.  
  5728. if ( theGame.CanLog() )
  5729. {
  5730.  
  5731. LogAttackRangesDebug("");
  5732. if(countered)
  5733. {
  5734. LogDMHits("Attack countered by <<" + actor + ">>");
  5735. LogAttackRangesDebug("Attack countered by <<" + actor + ">>");
  5736. }
  5737. else if(parried)
  5738. {
  5739. LogDMHits("Attack parried by <<" + actor + ">>");
  5740. LogAttackRangesDebug("Attack parried by <<" + actor + ">>");
  5741. }
  5742. }
  5743.  
  5744. parriedBy.PushBack(actor);
  5745. }
  5746. }
  5747.  
  5748. return parriedBy;
  5749. }
  5750.  
  5751.  
  5752. protected function DoAttack(animData : CPreAttackEventData, weaponId : SItemUniqueId, parried : bool, countered : bool, parriedBy : array<CActor>, attackAnimationName : name, hitTime : float)
  5753. {
  5754. var i : int;
  5755. var weaponEntity : CItemEntity;
  5756.  
  5757. phantomStrike = false;
  5758. weaponEntity = GetInventory().GetItemEntityUnsafe(weaponId);
  5759.  
  5760.  
  5761. for(i=0; i<hitTargets.Size(); i+=1)
  5762. {
  5763. Attack(hitTargets[i], animData, weaponId, parried, countered, parriedBy, attackAnimationName, hitTime, weaponEntity);
  5764. }
  5765.  
  5766. // W3EE - Begin
  5767. if( ((W3PlayerWitcher)this).HasBuff(EET_WinterBlade) && IsLightAttack(attackActionName) && hitTargets.Size() && !countered )
  5768. ((W3Effect_WinterBlade)((W3PlayerWitcher)this).GetBuff(EET_WinterBlade)).IncreaseCounter();
  5769.  
  5770. GetInjuryManager().AttackStumbles();
  5771. // W3EE - End
  5772.  
  5773. if( GetInventory().ItemHasTag( weaponId, 'PhantomWeapon' ) )
  5774. {
  5775. // W3EE - Begin
  5776. if( this == thePlayer && IsLightAttack( attackActionName ) && hitTargets.Size() && !countered )
  5777. // W3EE - End
  5778. {
  5779. thePlayer.GetPhantomWeaponMgr().IncrementHitCounter();
  5780. attackActionName = '';
  5781. }
  5782. else if( IsHeavyAttack( attackActionName ) )
  5783. {
  5784. AddTimer('PhantomWeapon', 0.0);
  5785. phantomWeaponHitTime = hitTime + 0.0;
  5786. phantomWeaponAnimData = animData;
  5787. phantomWeaponWeaponId = weaponId;
  5788. phantomWeaponParried = parried;
  5789. phantomWeaponCountered = countered;
  5790. phantomWeaponParriedBy = parriedBy;
  5791. phantomWeaponAttackAnimationName = attackAnimationName;
  5792. phantomWeaponHitTargets = hitTargets;
  5793. }
  5794. else
  5795. {
  5796. attackActionName = '';
  5797. }
  5798. }
  5799. else
  5800. {
  5801. attackActionName = '';
  5802. }
  5803.  
  5804.  
  5805. hitTargets.Clear();
  5806. AddTimer('PostAttackDebugRangeClear', 1);
  5807. }
  5808.  
  5809.  
  5810. var phantomWeaponAnimData : CPreAttackEventData;
  5811. var phantomWeaponWeaponId : SItemUniqueId;
  5812. var phantomWeaponParried : bool;
  5813. var phantomWeaponCountered : bool;
  5814. var phantomWeaponParriedBy : array<CActor>;
  5815. var phantomWeaponAttackAnimationName : name;
  5816. var phantomWeaponHitTime : float;
  5817. var phantomWeaponHitTargets : array<CGameplayEntity>;
  5818. var phantomStrike : bool;
  5819.  
  5820. timer function PhantomWeapon(dt : float, id : int)
  5821. {
  5822. var i : int;
  5823. var weaponEntity : CItemEntity;
  5824.  
  5825. weaponEntity = GetInventory().GetItemEntityUnsafe(phantomWeaponWeaponId);
  5826.  
  5827. // W3EE - Begin
  5828. if( this == thePlayer )
  5829. {
  5830. if( thePlayer.GetPhantomWeaponMgr().IsWeaponCharged() )
  5831. phantomStrike = true;
  5832. }
  5833. else
  5834. {
  5835. phantomStrike = true;
  5836. }
  5837.  
  5838. if( phantomStrike )
  5839. {
  5840. for(i=0; i<phantomWeaponHitTargets.Size(); i+=1)
  5841. {
  5842. phantomWeaponHitTargets[i].AddAbility( 'DisableFinishers', true );
  5843. phantomWeaponHitTargets[i].AddAbility( 'DisableDismemberment', true );
  5844.  
  5845. Attack(phantomWeaponHitTargets[i], phantomWeaponAnimData, phantomWeaponWeaponId, phantomWeaponParried, phantomWeaponCountered, phantomWeaponParriedBy, phantomWeaponAttackAnimationName, phantomWeaponHitTime, weaponEntity);
  5846.  
  5847. phantomWeaponHitTargets[i].RemoveAbility( 'DisableFinishers' );
  5848. phantomWeaponHitTargets[i].RemoveAbility( 'DisableDismemberment' );
  5849. }
  5850. }
  5851. // W3EE - End
  5852.  
  5853. for(i=0; i<phantomWeaponHitTargets.Size(); i+=1)
  5854. {
  5855.  
  5856. phantomWeaponHitTargets[i].AddAbility( 'DisableFinishers', true );
  5857. phantomWeaponHitTargets[i].AddAbility( 'DisableDismemberment', true );
  5858.  
  5859. Attack(phantomWeaponHitTargets[i], phantomWeaponAnimData, phantomWeaponWeaponId, phantomWeaponParried, phantomWeaponCountered, phantomWeaponParriedBy, phantomWeaponAttackAnimationName, phantomWeaponHitTime, weaponEntity);
  5860.  
  5861. phantomWeaponHitTargets[i].RemoveAbility( 'DisableFinishers' );
  5862. phantomWeaponHitTargets[i].RemoveAbility( 'DisableDismemberment' );
  5863. }
  5864.  
  5865. if( !phantomWeaponCountered && phantomWeaponHitTargets.Size() && phantomWeaponParried )
  5866. PlayEffectOnHeldWeapon( 'special_attack_block' );
  5867.  
  5868. AddTimer('PostAttackDebugRangeClear', 1);
  5869. attackActionName = '';
  5870. }
  5871.  
  5872. timer function PostAttackDebugRangeClear(dt : float, id : int)
  5873. {
  5874. SetDebugAttackRange('');
  5875. }
  5876.  
  5877. protected function Attack( hitTarget : CGameplayEntity, animData : CPreAttackEventData, weaponId : SItemUniqueId, parried : bool, countered : bool, parriedBy : array<CActor>, attackAnimationName : name, hitTime : float, weaponEntity : CItemEntity)
  5878. {
  5879. var action : W3Action_Attack;
  5880.  
  5881. if(PrepareAttackAction(hitTarget, animData, weaponId, parried, countered, parriedBy, attackAnimationName, hitTime, weaponEntity, action))
  5882. {
  5883. theGame.damageMgr.ProcessAction(action);
  5884. delete action;
  5885. }
  5886. }
  5887.  
  5888. public function SetAttackActionName(nam : name)
  5889. {
  5890. attackActionName = nam;
  5891. }
  5892.  
  5893. protected function PrepareAttackAction( hitTarget : CGameplayEntity, animData : CPreAttackEventData, weaponId : SItemUniqueId, parried : bool, countered : bool, parriedBy : array<CActor>, attackAnimationName : name, hitTime : float, weaponEntity : CItemEntity, out attackAction : W3Action_Attack) : bool
  5894. {
  5895. var actor : CActor;
  5896. // W3EE - Begin
  5897. var phantomDmgInfo : SAbilityAttributeValue;
  5898. var phantomDmg, winterDmg : W3DamageAction;
  5899. var npc : CNewNPC;
  5900. var ent, fx : CEntity;
  5901. var entityTemplate : CEntityTemplate;
  5902. var rot : EulerAngles;
  5903. var i : int;
  5904. var pos, basePos : Vector;
  5905. var angle, radius : float;
  5906. var surface : CGameplayFXSurfacePost;
  5907. // W3EE - End
  5908.  
  5909. if(!hitTarget)
  5910. return false;
  5911.  
  5912. attackAction = new W3Action_Attack in theGame.damageMgr;
  5913.  
  5914. if ( animData.hitFX == 'basedOnWeapon' )
  5915. ChangeHitFxBasedOnWeapon(animData, weaponId);
  5916.  
  5917. attackAction.Init( this, hitTarget, NULL, weaponId, animData.attackName, GetName(), animData.hitReactionType, animData.Can_Parry_Attack, animData.canBeDodged, attackActionName, animData.swingType, animData.swingDir, true, false, false, false, animData.hitFX, animData.hitBackFX, animData.hitParriedFX, animData.hitBackParriedFX);
  5918.  
  5919.  
  5920.  
  5921. attackAction.SetAttackAnimName(attackAnimationName);
  5922. attackAction.SetHitTime(hitTime);
  5923. attackAction.SetWeaponEntity(weaponEntity);
  5924. attackAction.SetWeaponSlot(animData.weaponSlot);
  5925. attackAction.SetSoundAttackType(animData.soundAttackType);
  5926.  
  5927. actor = (CActor)hitTarget;
  5928.  
  5929. if(actor && parriedBy.Contains(actor))
  5930. {
  5931. if(perfectParried)
  5932. {
  5933. attackAction.SetIsPerfectParried(true);
  5934. SignalGameplayEvent('AttackParried');
  5935. }
  5936. else
  5937. if(parried)
  5938. {
  5939. attackAction.SetIsParried(true);
  5940. SignalGameplayEvent('AttackParried');
  5941. }
  5942. else if(countered)
  5943. {
  5944. attackAction.SetIsCountered(true);
  5945. SignalGameplayEvent('AttackCountered');
  5946. }
  5947. }
  5948.  
  5949.  
  5950. if ( attackAction.IsParried() && attackAction.attacker.HasAbility('ReflectOnBeingParried') )
  5951. {
  5952. ((CActor)attackAction.attacker).SetCanPlayHitAnim( true );
  5953. ReactToReflectedAttack(attackAction.victim);
  5954. }
  5955.  
  5956. // W3EE - Begin
  5957. ((W3Effect_WinterBlade)((W3PlayerWitcher)this).GetBuff(EET_WinterBlade)).DealDischargeDamage(attackAction);
  5958. // W3EE - End
  5959.  
  5960. if(phantomStrike)
  5961. {
  5962. attackAction.SetIsParried(false);
  5963. attackAction.SetHitAnimationPlayType(EAHA_ForceNo);
  5964.  
  5965. if( attackAction.attacker == thePlayer )
  5966. {
  5967. // W3EE - Begin
  5968. npc = (CNewNPC)attackAction.victim;
  5969. phantomDmg = new W3DamageAction in theGame.damageMgr;
  5970. phantomDmg.Initialize(attackAction.attacker, attackAction.victim, attackAction.causer, attackAction.GetBuffSourceName(), EHRT_None, CPS_Undefined, attackAction.IsActionMelee(), attackAction.IsActionRanged(), attackAction.IsActionWitcherSign(), attackAction.IsActionEnvironment());
  5971. if( npc && npc.IsShielded( thePlayer ) )
  5972. {
  5973. npc.ProcessShieldDestruction();
  5974. phantomDmg.AddEffectInfo(EET_LongStagger);
  5975. }
  5976. else actor.AddEffectDefault(EET_HeavyKnockdown, attackAction.attacker);
  5977. phantomDmgInfo = GetWitcherPlayer().GetInventory().GetItemAttributeValue(GetWitcherPlayer().GetHeldSword(), 'SlashingDamage');
  5978. phantomDmg.SetForceExplosionDismemberment();
  5979. phantomDmg.SetCannotReturnDamage(true);
  5980. phantomDmg.SetCanPlayHitParticle(false);
  5981. phantomDmg.AddDamage(theGame.params.DAMAGE_NAME_FIRE, (phantomDmgInfo.valueBase * (1.f + phantomDmgInfo.valueMultiplicative) + phantomDmgInfo.valueAdditive));
  5982. phantomDmg.SetHitAnimationPlayType(EAHA_ForceNo);
  5983.  
  5984. theGame.damageMgr.ProcessAction(phantomDmg);
  5985. delete phantomDmg;
  5986. thePlayer.GetPhantomWeaponMgr().DischargeWeapon(true);
  5987. thePlayer.GetPhantomWeaponMgr().DischargeWeapon( true );
  5988. attackAction.AddEffectInfo( EET_HeavyKnockdown );
  5989.  
  5990. SoundEvent('sign_igni_charge_begin');
  5991. SoundEvent('sign_igni_charge_begin');
  5992.  
  5993. npc.AddTimer('Runeword1DisableFireFX', 6);
  5994. npc.PlayEffect('critical_burning');
  5995. npc.PlayEffect('critical_burning_csx');
  5996.  
  5997. surface = theGame.GetSurfacePostFX();
  5998. surface.AddSurfacePostFXGroup(npc.GetWorldPosition(), 1.f, 30, 3, 9, 1);
  5999.  
  6000. fx = npc.CreateFXEntityAtPelvis('mutation2_critical', true);
  6001. fx.PlayEffect('critical_igni');
  6002. fx.PlayEffect('critical_igni');
  6003. fx = npc.CreateFXEntityAtPelvis('mutation1_hit', true);
  6004. fx.PlayEffect('mutation_1_hit_igni');
  6005. fx.PlayEffect('mutation_1_hit_igni');
  6006.  
  6007. GCameraShake(0.6f, false, thePlayer.GetWorldPosition(),,,, 0.85f);
  6008. // W3EE - End
  6009. }
  6010. else
  6011. {
  6012. if( parried )
  6013. {
  6014. attackAction.AddEffectInfo( EET_Stagger );
  6015. attackAction.ClearDamage();
  6016. }
  6017. else if( !parried && !countered )
  6018. {
  6019. attackAction.AddEffectInfo( EET_Knockdown );
  6020. }
  6021. }
  6022. }
  6023.  
  6024. return true;
  6025. }
  6026.  
  6027. protected function ChangeHitFxBasedOnWeapon( out animData : CPreAttackEventData , weaponId : SItemUniqueId)
  6028. {
  6029. var weaponName : name;
  6030.  
  6031. weaponName = GetInventory().GetItemName(weaponId);
  6032.  
  6033. if ( weaponName == 'fists' )
  6034. {
  6035. animData.hitFX = 'fistfight_hit';
  6036. animData.hitBackFX = 'fistfight_hit_back';
  6037. }
  6038. else if ( weaponName == 'fists_lightning' )
  6039. {
  6040. animData.hitFX = 'hit_electric';
  6041. animData.hitParriedFX = 'hit_electric';
  6042. animData.hitBackFX = 'hit_electric';
  6043. animData.hitBackParriedFX = 'hit_electric';
  6044. }
  6045. else if ( weaponName == 'fists_fire' )
  6046. {
  6047. animData.hitFX = 'fire_hit';
  6048. animData.hitParriedFX = 'fire_hit';
  6049. animData.hitBackFX = 'fire_hit';
  6050. animData.hitBackParriedFX = 'fire_hit';
  6051. }
  6052. else if ( weaponName == 'fists_lightning_lynx' )
  6053. {
  6054. animData.hitFX = 'hit_electric_quen';
  6055. animData.hitParriedFX = 'hit_electric_quen';
  6056. animData.hitBackFX = 'hit_electric_quen';
  6057. animData.hitBackParriedFX = 'hit_electric_quen';
  6058. }
  6059. }
  6060.  
  6061. // W3EE - Begin
  6062. private var CBActive : bool;
  6063. private var CBCharge : int;
  6064.  
  6065. public function IsColdBloodActive() : bool
  6066. {
  6067. return CBActive;
  6068. }
  6069.  
  6070. public function ColdBloodCharge() : int
  6071. {
  6072. return CBCharge;
  6073. }
  6074.  
  6075. public function SetColdBloodActive( i : bool )
  6076. {
  6077. CBActive = i;
  6078. }
  6079.  
  6080. public function IncColdBloodCharge()
  6081. {
  6082. CBCharge += 1;
  6083. }
  6084.  
  6085. timer function ResetCB( dt : float, id : int )
  6086. {
  6087. SetColdBloodActive(false);
  6088. CBCharge = 0;
  6089. }
  6090. // W3EE - End
  6091.  
  6092. public function ReduceDamage( out damageData : W3DamageAction )
  6093. {
  6094. var actorAttacker : CActor;
  6095. var id : SItemUniqueId;
  6096. var attackAction : W3Action_Attack;
  6097. var arrStr : array<string>;
  6098. var l_percAboutToBeRemoved : float;
  6099. var l_healthPerc : float;
  6100. var l_threshold : float;
  6101. var l_maxPercLossAllowed : float;
  6102. var l_maxDamageAllowed : float;
  6103. var l_maxHealth, mult : float;
  6104. var l_actorTarget : CActor;
  6105. var canLog : bool;
  6106. var hitsToKill : SAbilityAttributeValue;
  6107. // var thisNPC : CNewNPC;
  6108. var minDamage : float;
  6109. var i : int;
  6110. var dmgTypes : array< SRawDamage >;
  6111. var hasPoisonDamage : bool;
  6112.  
  6113. // W3EE - Begin
  6114. var crushThroughBlocks : SAbilityAttributeValue;
  6115. // W3EE - End
  6116.  
  6117. canLog = theGame.CanLog();
  6118.  
  6119.  
  6120.  
  6121. // W3EE - Begin
  6122. /*
  6123. if( damageData.victim == thePlayer && !damageData.IsDoTDamage() )
  6124. {
  6125. damageData.GetDTs( dmgTypes );
  6126.  
  6127.  
  6128. for( i=0; i<dmgTypes.Size(); i+=1 )
  6129. {
  6130. if( dmgTypes[i].dmgType == theGame.params.DAMAGE_NAME_DIRECT )
  6131. {
  6132. dmgTypes.EraseFast( i );
  6133. break;
  6134. }
  6135. }
  6136.  
  6137. if( dmgTypes.Size() > 0 )
  6138. {
  6139. hasPoisonDamage = false;
  6140. for( i=0; i<dmgTypes.Size(); i+=1 )
  6141. {
  6142. if( dmgTypes[ i ].dmgType == theGame.params.DAMAGE_NAME_POISON )
  6143. {
  6144. hasPoisonDamage = true;
  6145. break;
  6146. }
  6147. }
  6148.  
  6149. if( !( hasPoisonDamage && this == GetWitcherPlayer() && HasBuff( EET_GoldenOriole ) && GetWitcherPlayer().GetPotionBuffLevel( EET_GoldenOriole ) == 3) )
  6150. {
  6151. minDamage = 0;
  6152. for( i=0; i<dmgTypes.Size(); i+=1 )
  6153. {
  6154. if( DamageHitsVitality( dmgTypes[ i ].dmgType ) )
  6155. {
  6156. minDamage += dmgTypes[ i ].dmgVal;
  6157. }
  6158. }
  6159. minDamage *= 0.05;
  6160. if(minDamage < 1)
  6161. {
  6162. minDamage = 1;
  6163. }
  6164. if( damageData.processedDmg.vitalityDamage < minDamage )
  6165. {
  6166. damageData.processedDmg.vitalityDamage = minDamage;
  6167. }
  6168. }
  6169. }
  6170. }
  6171. */
  6172.  
  6173. if(damageData.IsActionRanged() && damageData.attacker == thePlayer && (W3BoltProjectile)(damageData.causer) )
  6174. {
  6175. if(UsesEssence() && damageData.processedDmg.essenceDamage < 1)
  6176. {
  6177. damageData.processedDmg.essenceDamage = 1;
  6178.  
  6179. if ( canLog )
  6180. {
  6181. LogDMHits("CActor.ReduceDamage: victim would take no damage but it's a bolt so we deal 1 pt of damage", damageData );
  6182. }
  6183. }
  6184. else if(UsesVitality() && damageData.processedDmg.vitalityDamage < 1)
  6185. {
  6186. damageData.processedDmg.vitalityDamage = 1;
  6187.  
  6188. if ( canLog )
  6189. {
  6190. LogDMHits("CActor.ReduceDamage: victim would take no damage but it's a bolt so we deal 1 pt of damage", damageData );
  6191. }
  6192. }
  6193. }
  6194.  
  6195.  
  6196. // W3EE - Begin
  6197. /*
  6198. thisNPC = (CNewNPC)this;
  6199. if( thisNPC && damageData.attacker == thePlayer && !HasBuff(EET_AxiiGuardMe) &&
  6200. ( GetAttitudeBetween( this, thePlayer ) == AIA_Friendly ||
  6201. ( GetAttitudeBetween( this, thePlayer ) == AIA_Neutral && thisNPC.GetNPCType() == ENGT_Guard ) ) )
  6202. {
  6203. if ( canLog )
  6204. {
  6205. LogDMHits("Player attacked friendly or neutral community npc - no damage dealt", damageData);
  6206. }
  6207. damageData.SetAllProcessedDamageAs(0);
  6208. damageData.ClearEffects();
  6209. return;
  6210. }
  6211. */
  6212. // W3EE - End
  6213.  
  6214. if(damageData.IsActionMelee() && HasAbility( 'ReflectMeleeAttacks' ) )
  6215. {
  6216. if ( canLog )
  6217. {
  6218. LogDMHits("CActor.ReduceDamage: victim is heavily armored and attacker bounces of his armor", damageData );
  6219. }
  6220. damageData.SetAllProcessedDamageAs(0);
  6221. ((CActor)damageData.attacker).ReactToReflectedAttack( this );
  6222. damageData.ClearEffects();
  6223. return;
  6224. }
  6225.  
  6226.  
  6227. if(!damageData.DealsAnyDamage() && damageData.GetBuffSourceName() != "Mutation4")
  6228. return;
  6229.  
  6230.  
  6231. if(damageData.IsActionMelee() && HasAbility( 'CannotBeAttackedFromAllSides' ) )
  6232. {
  6233. if ( canLog )
  6234. {
  6235. LogDMHits("CActor.ReduceDamage: victim attacked from behind and immune to this type of strike - no damage will be done", damageData );
  6236. }
  6237. damageData.SetAllProcessedDamageAs(0);
  6238. ((CActor)damageData.attacker).ReactToReflectedAttack( this );
  6239. damageData.ClearEffects();
  6240. return;
  6241. }
  6242.  
  6243.  
  6244. if(damageData.IsActionMelee() && HasAbility( 'CannotBeAttackedFromBehind' ) && IsAttackerAtBack(damageData.attacker) )
  6245. {
  6246. if ( canLog )
  6247. {
  6248. LogDMHits("CActor.ReduceDamage: victim attacked from behind and immune to this type of strike - no damage will be done", damageData );
  6249. }
  6250. damageData.SetAllProcessedDamageAs(0);
  6251. ((CActor)damageData.attacker).ReactToReflectedAttack( this );
  6252. damageData.ClearEffects();
  6253. return;
  6254. }
  6255.  
  6256.  
  6257. if(damageData.IsActionMelee() && HasAbility( 'VulnerableFromFront' ) && !IsAttackerAtBack(damageData.attacker) )
  6258. {
  6259. if ( canLog )
  6260. {
  6261. LogDMHits("CActor.ReduceDamage: victim attacked from front and vulnerable to this type of strike - attack will ignor armor", damageData );
  6262. }
  6263. damageData.SetIgnoreArmor( true );
  6264. damageData.SetPointResistIgnored( true );
  6265. return;
  6266. }
  6267.  
  6268.  
  6269.  
  6270. if( this.HasAbility( 'EredinInvulnerable' ) && damageData.IsActionWitcherSign() )
  6271. {
  6272. if ( canLog )
  6273. {
  6274. LogDMHits("CActor.ReduceDamage: victim has EredinInvulnerable ability - no damage will be done", damageData );
  6275. }
  6276. damageData.SetAllProcessedDamageAs(0);
  6277. return;
  6278. }
  6279.  
  6280.  
  6281. //W3EE - Begin
  6282. //dodge
  6283. /*
  6284. if(this != thePlayer && IsCurrentlyDodging() && damageData.CanBeDodged() && VecDistanceSquared(this.GetWorldPosition(),damageData.attacker.GetWorldPosition()) > 1.7 ) //~1.3^2
  6285. {
  6286. if ( canLog )
  6287. {
  6288. LogDMHits("Non-player character dodge - no damage dealt", damageData);
  6289. }
  6290. damageData.SetWasDodged();
  6291. damageData.SetAllProcessedDamageAs(0);
  6292. damageData.ClearEffects();
  6293. damageData.SetHitAnimationPlayType(EAHA_ForceNo);
  6294. return;
  6295. }
  6296. */
  6297.  
  6298. Combat().EnemyDodge(damageData, this);
  6299. //W3EE - End
  6300.  
  6301.  
  6302. if(this != thePlayer && FactsDoesExist("debug_fact_weak"))
  6303. {
  6304. if ( canLog )
  6305. {
  6306. LogDMHits("CActor.ReduceDamage: using 'weak' cheat - all damage set to 0.001", damageData );
  6307. }
  6308. damageData.processedDmg.essenceDamage = MinF(0.001, damageData.processedDmg.essenceDamage);
  6309. damageData.processedDmg.vitalityDamage = MinF(0.001, damageData.processedDmg.vitalityDamage);
  6310. damageData.processedDmg.staminaDamage = MinF(0.001, damageData.processedDmg.staminaDamage);
  6311. damageData.processedDmg.moraleDamage = MinF(0.001, damageData.processedDmg.moraleDamage);
  6312. }
  6313.  
  6314.  
  6315.  
  6316.  
  6317. if(damageData.IsParryStagger())
  6318. {
  6319. actorAttacker = (CActor)damageData.attacker;
  6320.  
  6321. if ( ((CMovingPhysicalAgentComponent)( actorAttacker ).GetMovingAgentComponent()).GetCapsuleHeight() > 2.f )
  6322. mult = theGame.params.PARRY_STAGGER_REDUCE_DAMAGE_LARGE;
  6323. else if ( actorAttacker.GetRadius() > 0.6 )
  6324. mult = theGame.params.PARRY_STAGGER_REDUCE_DAMAGE_LARGE;
  6325. else if ( this == thePlayer && thePlayer.GetBossTag() != '' )
  6326. mult = theGame.params.PARRY_STAGGER_REDUCE_DAMAGE_LARGE;
  6327. else if ( actorAttacker.HasAbility( 'mon_troll_base' ) )
  6328. mult = theGame.params.PARRY_STAGGER_REDUCE_DAMAGE_LARGE;
  6329. else
  6330. mult = theGame.params.PARRY_STAGGER_REDUCE_DAMAGE_SMALL;
  6331.  
  6332. damageData.MultiplyAllDamageBy(mult);
  6333.  
  6334. if ( canLog )
  6335. {
  6336. LogDMHits("Stagger-Parry, reducing damage by " + NoTrailZeros((1-mult)*100) + "%");
  6337. }
  6338. }
  6339. else
  6340. {
  6341.  
  6342. attackAction = (W3Action_Attack)damageData;
  6343. //W3EE - Begin
  6344. actorAttacker = (CActor)damageData.attacker;
  6345. if( attackAction && damageData.IsActionMelee() && attackAction.CanBeParried() && (attackAction.IsParried() || attackAction.IsCountered()) )
  6346. {
  6347. crushThroughBlocks = actorAttacker.GetAttributeValue('damage_through_blocks');
  6348. if( ((W3PlayerWitcher)actorAttacker).IsSetBonusActive(EISB_Bear_2) && ((W3PlayerWitcher)actorAttacker).IsHeavyAttack(attackAction.GetAttackName()) && Combat().GetWolvenEffect().GetStacks() >= 5 )
  6349. crushThroughBlocks.valueMultiplicative += 1.f;
  6350.  
  6351. if( !((W3PlayerWitcher)this) && crushThroughBlocks.valueMultiplicative <= 0.f )
  6352. {
  6353. arrStr.PushBack(GetDisplayName());
  6354. if(attackAction.IsParried())
  6355. {
  6356. if ( canLog )
  6357. {
  6358. LogDMHits("Attack parried - no damage", damageData);
  6359. }
  6360. theGame.witcherLog.AddCombatMessage(GetLocStringByKeyExtWithParams("hud_combat_log_parries", , , arrStr), attackAction.attacker, this);
  6361. }
  6362. else
  6363. {
  6364. if ( canLog )
  6365. {
  6366. LogDMHits("Attack countered - no damage", damageData);
  6367. }
  6368. theGame.witcherLog.AddCombatMessage(GetLocStringByKeyExtWithParams("hud_combat_log_counters", , , arrStr), attackAction.attacker, this);
  6369. }
  6370.  
  6371. damageData.SetAllProcessedDamageAs(0);
  6372. }
  6373. return;
  6374. }
  6375. //W3EE - End
  6376. }
  6377.  
  6378. actorAttacker = (CActor)damageData.attacker;
  6379.  
  6380.  
  6381. if((CPlayer)actorAttacker && !((CPlayer)damageData.victim) && FactsQuerySum('player_is_the_boss') > 0)
  6382. {
  6383. if ( canLog )
  6384. {
  6385. LogDMHits("Using 'like a boss' cheat - damage set to 40% of targets MAX health", damageData);
  6386. }
  6387. damageData.processedDmg.vitalityDamage = GetStatMax(BCS_Vitality) / 2.5;
  6388. damageData.processedDmg.essenceDamage = GetStatMax(BCS_Essence) / 2.5;
  6389. }
  6390.  
  6391. // W3EE - Begin
  6392. /*
  6393. if(attackAction && actorAttacker == thePlayer && thePlayer.inv.IsItemBolt(attackAction.GetWeaponId()) )
  6394. {
  6395. if(thePlayer.IsOnBoat())
  6396. {
  6397. hitsToKill = GetAttributeValue('extraDamageWhenPlayerOnBoat');
  6398. if(hitsToKill.valueAdditive > 0)
  6399. {
  6400. damageData.processedDmg.vitalityDamage = CeilF(GetStatMax(BCS_Vitality) / hitsToKill.valueAdditive);
  6401. damageData.processedDmg.essenceDamage = CeilF(GetStatMax(BCS_Essence) / hitsToKill.valueAdditive);
  6402.  
  6403. if(theGame.CanLog())
  6404. {
  6405. LogDMHits("Target is getting killed by " + NoTrailZeros(hitsToKill.valueAdditive) + " hits when being shot from boat by default bolts", damageData);
  6406. LogDMHits("Final hacked damage is now, vit: " + NoTrailZeros(damageData.processedDmg.vitalityDamage) + ", ess: " + NoTrailZeros(damageData.processedDmg.essenceDamage), damageData);
  6407. }
  6408. }
  6409. }
  6410. }
  6411. */
  6412.  
  6413. if( HasAbility('HealthBuff') && HasAbility('mh207_wraith_boss') )
  6414. {
  6415. damageData.SetAllProcessedDamageAs(0);
  6416. damageData.SetCanPlayHitParticle(false);
  6417. damageData.SetHitAnimationPlayType(EAHA_ForceNo);
  6418. }
  6419.  
  6420. if( HasAbility( 'ShadowFormActive' ) )
  6421. {
  6422. if ( canLog )
  6423. {
  6424. LogDMHits("CActor.ReduceDamage: victim has ShadowFormActive ability - damage reduced to 10% of base", damageData );
  6425. }
  6426. if( !((CR4Player)actorAttacker).HasBuff(EET_Decoction6) )
  6427. {
  6428. damageData.processedDmg.vitalityDamage *= 0.1f;
  6429. damageData.processedDmg.essenceDamage *= 0.1f;
  6430. damageData.SetCanPlayHitParticle( false );
  6431. theGame.witcherLog.CombatMessageAddGlobalDamageMult(0.1f);
  6432. }
  6433. }
  6434. // W3EE - End
  6435.  
  6436.  
  6437.  
  6438. if( actorAttacker && HasAbility( 'IceArmor' ) && !actorAttacker.HasAbility( 'Ciri_Rage' ) )
  6439. {
  6440. if ( theGame.GetDifficultyMode() == EDM_Easy )
  6441. {
  6442. if ( canLog )
  6443. {
  6444. LogDMHits("CActor.ReduceDamage: victim has IceArmor ability - damage reduced by 5%", damageData );
  6445. }
  6446. damageData.processedDmg.vitalityDamage *= 0.95f;
  6447. damageData.processedDmg.essenceDamage *= 0.95f;
  6448. theGame.witcherLog.CombatMessageAddGlobalDamageMult(0.95f);
  6449. }
  6450. else
  6451. {
  6452. if ( canLog )
  6453. {
  6454. LogDMHits("CActor.ReduceDamage: victim has IceArmor ability - damage reduced by 50%", damageData );
  6455. }
  6456. damageData.processedDmg.vitalityDamage *= 0.5f;
  6457. damageData.processedDmg.essenceDamage *= 0.5f;
  6458. theGame.witcherLog.CombatMessageAddGlobalDamageMult(0.5f);
  6459. }
  6460. }
  6461.  
  6462.  
  6463.  
  6464.  
  6465. if( HasAbility( 'LastBreath' ) )
  6466. {
  6467. l_threshold = CalculateAttributeValue( GetAttributeValue('lastbreath_threshold') );
  6468. if( l_threshold == 0 ) l_threshold = 0.25f;
  6469. l_healthPerc = GetHealthPercents();
  6470.  
  6471.  
  6472. if( theGame.GetEngineTimeAsSeconds() - lastBreathTime < 1 )
  6473. {
  6474. if( damageData.processedDmg.vitalityDamage > 0 ) damageData.processedDmg.vitalityDamage = 0;
  6475. if( damageData.processedDmg.essenceDamage > 0 ) damageData.processedDmg.essenceDamage = 0;
  6476.  
  6477. if ( canLog )
  6478. {
  6479. LogDMHits("CActor.ReduceDamage: victim just activated LastBreath ability - reducing damage" );
  6480. }
  6481. }
  6482. else if( l_healthPerc > l_threshold )
  6483. {
  6484. l_maxHealth = GetMaxHealth();
  6485. l_percAboutToBeRemoved = MaxF( damageData.processedDmg.vitalityDamage, damageData.processedDmg.essenceDamage ) / l_maxHealth;
  6486.  
  6487. l_maxPercLossAllowed = l_healthPerc - l_threshold;
  6488.  
  6489. if( l_percAboutToBeRemoved > l_maxPercLossAllowed )
  6490. {
  6491.  
  6492. l_maxDamageAllowed = l_maxPercLossAllowed * l_maxHealth;
  6493. if( damageData.processedDmg.vitalityDamage > 0 ) damageData.processedDmg.vitalityDamage = l_maxDamageAllowed;
  6494. if( damageData.processedDmg.essenceDamage > 0 ) damageData.processedDmg.essenceDamage = l_maxDamageAllowed;
  6495. if ( canLog )
  6496. {
  6497. LogDMHits("CActor.ReduceDamage: victim has LastBreath ability - reducing damage", damageData );
  6498. }
  6499.  
  6500. SignalGameplayEvent('LastBreath');
  6501. lastBreathTime = theGame.GetEngineTimeAsSeconds();
  6502. DisableHitAnimFor( 1 );
  6503. }
  6504. }
  6505. }
  6506.  
  6507. if(damageData.victim != thePlayer)
  6508. {
  6509.  
  6510. if(!damageData.GetIgnoreImmortalityMode())
  6511. {
  6512. if(!((W3PlayerWitcher)this))
  6513. Log("");
  6514.  
  6515.  
  6516. if( IsInvulnerable() && !HasAbility('mon_gargoyle') )
  6517. {
  6518. if ( canLog )
  6519. {
  6520. LogDMHits("CActor.ReduceDamage: victim Invulnerable - no damage will be dealt", damageData );
  6521. }
  6522. damageData.SetAllProcessedDamageAs(0);
  6523. return;
  6524. }
  6525.  
  6526. //if(actorAttacker && damageData.DealsAnyDamage() )
  6527. actorAttacker.SignalGameplayEventParamObject( 'DamageInstigated', damageData );
  6528.  
  6529.  
  6530. if( IsImmortal() )
  6531. {
  6532. if ( canLog )
  6533. {
  6534. LogDMHits("CActor.ReduceDamage: victim is Immortal, clamping damage", damageData );
  6535. }
  6536. // W3EE - Begin
  6537. damageData.processedDmg.vitalityDamage = ClampF(damageData.processedDmg.vitalityDamage, 0, GetStat(BCS_Vitality)-1 );
  6538. damageData.processedDmg.essenceDamage = ClampF(damageData.processedDmg.essenceDamage, 0, GetStat(BCS_Essence)-1 );
  6539.  
  6540. if(actorAttacker && damageData.DealsAnyDamage() )
  6541. actorAttacker.SignalGameplayEventParamObject( 'DamageInstigated', damageData );
  6542. // W3EE - End
  6543. return;
  6544. }
  6545. }
  6546. else
  6547. {
  6548.  
  6549. if(actorAttacker && damageData.DealsAnyDamage() )
  6550. actorAttacker.SignalGameplayEventParamObject( 'DamageInstigated', damageData );
  6551. }
  6552. }
  6553. }
  6554.  
  6555.  
  6556. public function GetDelaySinceLastAttacked() : float
  6557. {
  6558. return theGame.GetEngineTimeAsSeconds() - lastWasAttackedTime;
  6559. }
  6560.  
  6561. public function GetDelaySinceLastHit() : float
  6562. {
  6563. return theGame.GetEngineTimeAsSeconds() - lastWasHitTime;
  6564. }
  6565.  
  6566. public function IsAttacked( optional byPlayer : bool ) : void
  6567. {
  6568. if( byPlayer )
  6569. SignalGameplayEvent( 'AttackedByPlayer' );
  6570.  
  6571. lastWasAttackedTime = theGame.GetEngineTimeAsSeconds();
  6572. }
  6573.  
  6574. function IsAttackerAtBack(attacker : CNode) : bool
  6575. {
  6576. var targetToSourceAngle : float;
  6577.  
  6578. if(!attacker)
  6579. return false;
  6580.  
  6581. targetToSourceAngle = AbsF( NodeToNodeAngleDistance(attacker, this) );
  6582. if( targetToSourceAngle > 90 )
  6583. return true;
  6584.  
  6585. return false;
  6586. }
  6587.  
  6588.  
  6589. function ProcessSlideToTarget( duration : float, slideProperties : SSlideToTargetEventProps )
  6590. {
  6591. var attackerWorldPos, targetWorldPos, slideToWorldPos, targetNearestPointWorldPos : Vector;
  6592. var attackerToTargetDist : float;
  6593. var minSlideDistance : float;
  6594. var maxSlideDistance : float;
  6595. var slideDuration : float;
  6596.  
  6597. if(!slideTarget)
  6598. return;
  6599.  
  6600. slideDuration = duration;
  6601. minSlideDistance = slideProperties.minSlideDist;
  6602. maxSlideDistance = slideProperties.maxSlideDist;
  6603.  
  6604. attackerWorldPos = GetWorldPosition();
  6605. targetWorldPos = slideTarget.GetWorldPosition();
  6606.  
  6607. if ( (CActor)slideTarget )
  6608. targetNearestPointWorldPos = ( (CActor)slideTarget ).GetNearestPointInPersonalSpace( attackerWorldPos );
  6609. else
  6610. targetNearestPointWorldPos = slideTarget.GetWorldPosition();
  6611.  
  6612. attackerToTargetDist = VecDistance( attackerWorldPos, targetWorldPos );
  6613.  
  6614. if ( attackerToTargetDist > minSlideDistance && attackerToTargetDist < maxSlideDistance )
  6615. {
  6616. GetVisualDebug().AddSphere('NearestEnemyLoc', 0.2f, targetNearestPointWorldPos, true, Color(0,255,255), 0.1f );
  6617. ActionSlideToAsync( targetNearestPointWorldPos, slideDuration );
  6618. }
  6619. }
  6620.  
  6621. function ProcessSlideToTargetDistance ( duration : float, targetDist : float )
  6622. {
  6623. var targetPos : Vector;
  6624. var targetToPlayerVector : Vector;
  6625. var slidePosition : Vector;
  6626.  
  6627. targetPos = GetTarget().GetWorldPosition();
  6628. targetToPlayerVector = VecNormalize( GetWorldPosition() - targetPos );
  6629. slidePosition = targetPos + ( targetToPlayerVector * targetDist );
  6630. GetVisualDebug().AddSphere('SyncLocation', 0.25f, slidePosition, true, Color(0,210,210), 60.0f );
  6631. ActionSlideToAsync( slidePosition, duration );
  6632. }
  6633.  
  6634.  
  6635. function SetDetailedHitType ( hitType : EDetailedHitType )
  6636. {
  6637. SetBehaviorVariable( 'detailedHitType',(int)hitType);
  6638. }
  6639.  
  6640. function ChooseDetailedHitType( parryInfo : SParryInfo ) : EDetailedHitType
  6641. {
  6642. switch ( parryInfo.attackSwingType )
  6643. {
  6644. case AST_Jab:
  6645. return EDHT_Straight;
  6646. case AST_Vertical:
  6647. return EDHT_Straight;
  6648. default:
  6649. if ( parryInfo.attackSwingDir == ASD_RightLeft )
  6650. return EDHT_RightLeft;
  6651. else if ( parryInfo.attackSwingDir == ASD_LeftRight )
  6652. return EDHT_LeftRight;
  6653. else
  6654. return EDHT_None;
  6655. }
  6656. }
  6657.  
  6658. function ChooseParryTypeIndex( parryInfo : SParryInfo ) : float
  6659. {
  6660. var parryType : EParryType;
  6661. var parryTypeIndex : float;
  6662.  
  6663. parryType = thePlayer.parryTypeTable[parryInfo.attackSwingType][parryInfo.attackSwingDir];
  6664.  
  6665. lastParryType = parryType;
  6666.  
  6667. parryTypeIndex = (float)((int)parryType);
  6668. return parryTypeIndex;
  6669. }
  6670.  
  6671. function ProcessParryInfo( attacker : CActor, target : CActor, attackSwingType : EAttackSwingType, attackSwingDir : EAttackSwingDirection, attActionName : name, attackerWeaponId : SItemUniqueId, canBeParried : bool ) : SParryInfo
  6672. {
  6673. var parryInfo : SParryInfo;
  6674.  
  6675. parryInfo.attacker = attacker;
  6676. parryInfo.target = target;
  6677. parryInfo.attackActionName = attActionName;
  6678. parryInfo.attackerWeaponId = attackerWeaponId;
  6679. parryInfo.targetToAttackerAngleAbs = AbsF( NodeToNodeAngleDistance(attacker,target) );
  6680. parryInfo.targetToAttackerDist = VecDistance( attacker.GetWorldPosition(), target.GetWorldPosition() );
  6681. parryInfo.attackSwingType = attackSwingType;
  6682. parryInfo.attackSwingDir = attackSwingDir;
  6683. parryInfo.canBeParried = canBeParried;
  6684.  
  6685. if( attacker.HasAbility( 'UnblockableAttacks' ) )
  6686. {
  6687. parryInfo.canBeParried = false;
  6688. }
  6689.  
  6690. target.SetDetailedHitType(ChooseDetailedHitType(parryInfo));
  6691.  
  6692. return parryInfo;
  6693. }
  6694.  
  6695.  
  6696. timer function DelayDodgeProjectileEventTimer( dt : float , id : int)
  6697. {
  6698. SignalGameplayEvent( 'Time2DodgeProjectileDelayed' );
  6699. }
  6700.  
  6701. timer function DelayDodgeBombEventTimer( dt : float , id : int)
  6702. {
  6703. SignalGameplayEvent( 'Time2DodgeBombDelayed' );
  6704. }
  6705.  
  6706. timer function DelayRepulseProjectileEventTimer( dt : float , id : int)
  6707. {
  6708. SignalGameplayEvent( 'Time2RepulseProjectileDelayed' );
  6709. }
  6710.  
  6711. timer function DelayRepulseBombEventTimer( dt : float , id : int)
  6712. {
  6713. SignalGameplayEvent( 'Time2RepulseBombDelayed' );
  6714. }
  6715.  
  6716.  
  6717.  
  6718.  
  6719.  
  6720.  
  6721. public function GetTotalArmor() : SAbilityAttributeValue
  6722. {
  6723. return GetAttributeValue(theGame.params.ARMOR_VALUE_NAME, , true);
  6724. }
  6725.  
  6726.  
  6727. public function HasWeaponDrawn(treatFistsAsWeapon : bool) : bool
  6728. {
  6729. var ids : array<SItemUniqueId>;
  6730. var i : int;
  6731. var fistsIds : array<SItemUniqueId>;
  6732. var inv : CInventoryComponent;
  6733.  
  6734. inv = GetInventory();
  6735. ids = inv.GetAllWeapons();
  6736.  
  6737. if ( treatFistsAsWeapon )
  6738. {
  6739.  
  6740. for(i=0; i<ids.Size(); i+=1)
  6741. if(inv.IsItemHeld(ids[i]))
  6742. return true;
  6743. }
  6744. else
  6745. {
  6746.  
  6747. fistsIds = inv.GetItemsByCategory('fist');
  6748. for(i=0; i<ids.Size(); i+=1)
  6749. if( !fistsIds.Contains(ids[i]) && inv.IsItemHeld(ids[i]) )
  6750. return true;
  6751. }
  6752.  
  6753. return false;
  6754. }
  6755.  
  6756. public function UnequipItem(item : SItemUniqueId) : bool
  6757. {
  6758. return GetInventory().UnmountItem(item, true);
  6759. }
  6760.  
  6761. public function EquipItem(item : SItemUniqueId, optional slot : EEquipmentSlots, optional toHand : bool) : bool
  6762. {
  6763. return GetInventory().MountItem(item, toHand);
  6764. }
  6765.  
  6766. function IsInAgony() : bool;
  6767. function Agony();
  6768.  
  6769. function IsKnockedUnconscious() : bool
  6770. {
  6771. return knockedUncounscious;
  6772. }
  6773.  
  6774. function EnterKnockedUnconscious()
  6775. {
  6776. knockedUncounscious = true;
  6777. }
  6778.  
  6779. function EndKnockedUnconscious()
  6780. {
  6781. knockedUncounscious = false;
  6782. }
  6783.  
  6784. private timer function EnableHitAnim( time : float , id : int)
  6785. {
  6786. SetCanPlayHitAnim(true);
  6787. }
  6788.  
  6789. public function SetUsedVehicle(ent : CGameplayEntity)
  6790. {
  6791. usedVehicle = ent;
  6792.  
  6793. if( usedVehicle )
  6794. {
  6795. EntityHandleSet(usedVehicleHandle,usedVehicle);
  6796. GetRootAnimatedComponent().UpdateByOtherAnimatedComponent( usedVehicle.GetRootAnimatedComponent() );
  6797. GetMovingAgentComponent().SetUseEntityForPelvisOffset( usedVehicle );
  6798. }
  6799. else
  6800. {
  6801. EntityHandleSet(usedVehicleHandle, NULL);
  6802. GetRootAnimatedComponent().DontUpdateByOtherAnimatedComponent();
  6803. GetMovingAgentComponent().SetUseEntityForPelvisOffset();
  6804. }
  6805. }
  6806.  
  6807. public final function GetUsedVehicle() : CGameplayEntity
  6808. {
  6809. var vehicleFromHandle : CGameplayEntity;
  6810.  
  6811.  
  6812. vehicleFromHandle = (CGameplayEntity)EntityHandleGet( usedVehicleHandle );
  6813. if ( vehicleFromHandle )
  6814. {
  6815. return vehicleFromHandle;
  6816. }
  6817. return usedVehicle;
  6818. }
  6819.  
  6820. public function IsUsingVehicle() : bool
  6821. {
  6822.  
  6823. if ( EntityHandleGet( usedVehicleHandle ) )
  6824. {
  6825. return true;
  6826. }
  6827. return usedVehicle;
  6828. }
  6829.  
  6830.  
  6831. public final function IsUsingHorse( optional ignoreMountInProgress : bool ) : bool
  6832.  
  6833. {
  6834.  
  6835. var horseComp : W3HorseComponent;
  6836. var mountStatus : EVehicleMountStatus;
  6837.  
  6838. horseComp = GetUsedHorseComponent();
  6839. if(horseComp)
  6840. {
  6841. mountStatus = horseComp.riderSharedParams.mountStatus;
  6842.  
  6843. if( ignoreMountInProgress )
  6844. {
  6845. return mountStatus == VMS_mounted;
  6846. }
  6847. else
  6848. {
  6849. return mountStatus == VMS_mounted || mountStatus == VMS_mountInProgress;
  6850. }
  6851. }
  6852. return false;
  6853. }
  6854.  
  6855. public function IsUsingBoat() : bool
  6856. {
  6857. if( (W3Boat)GetUsedVehicle() )
  6858. {
  6859. return true;
  6860. }
  6861. return false;
  6862. }
  6863.  
  6864. public function GetUsedHorseComponent() : W3HorseComponent
  6865. {
  6866. var npc : CNewNPC;
  6867.  
  6868. npc = (CNewNPC)GetUsedVehicle();
  6869.  
  6870. if(npc)
  6871. return npc.GetHorseComponent();
  6872.  
  6873. return NULL;
  6874. }
  6875.  
  6876. public final function FindAndMountVehicle( optional mountType : EVehicleMountType, optional maxDistance : float ) : bool
  6877. {
  6878. var vehicle : CVehicleComponent;
  6879.  
  6880.  
  6881.  
  6882. LogChannel( 'Vehicles', "Doing mounting" );
  6883.  
  6884. vehicle = FindTheNearestVehicle( maxDistance, true );
  6885. LogChannel( 'Vehicles', "vehicle " + vehicle );
  6886. if ( vehicle )
  6887. {
  6888. vehicle.StopTheVehicle();
  6889.  
  6890.  
  6891. vehicle.Mount( this, mountType, EVS_driver_slot );
  6892. return true;
  6893. }
  6894. return false;
  6895. }
  6896.  
  6897. public final function FindTheNearestVehicle( maxDistance : float, requireToBeMountable : bool ) : CVehicleComponent
  6898. {
  6899.  
  6900. var vehicle : CVehicleComponent;
  6901. var nodes : array< CNode >;
  6902. var vehicleEntity : CEntity;
  6903.  
  6904.  
  6905. theGame.GetNodesByTag('vehicle', nodes);
  6906. if ( nodes.Size() == 0 )
  6907. {
  6908. return NULL;
  6909. }
  6910.  
  6911. vehicleEntity = SelectTheNearestVehicles( nodes, maxDistance );
  6912. if ( !vehicleEntity )
  6913. {
  6914. return NULL;
  6915. }
  6916.  
  6917. vehicle = (CVehicleComponent)vehicleEntity.GetComponentByClassName('CVehicleComponent');
  6918. if ( requireToBeMountable && vehicle && !vehicle.CanBeUsedBy( this ) )
  6919. {
  6920. return NULL;
  6921. }
  6922.  
  6923. return vehicle;
  6924. }
  6925.  
  6926. private final function SelectTheNearestVehicles( nodes : array< CNode >, maxDistance : float ) : CEntity
  6927. {
  6928. var i, size : int;
  6929. var bestEnt : CEntity;
  6930. var curr, best : float;
  6931. var posA, posB : Vector;
  6932.  
  6933. bestEnt = NULL;
  6934. size = nodes.Size();
  6935. best = maxDistance * maxDistance;
  6936.  
  6937. posB = this.GetWorldPosition();
  6938.  
  6939. for ( i=0; i<size; i+=1 )
  6940. {
  6941. posA = nodes[ i ].GetWorldPosition();
  6942.  
  6943. curr = VecDistanceSquared2D( posA, posB );
  6944. if ( curr < best )
  6945. {
  6946. best = curr;
  6947. bestEnt = (CEntity)nodes[i];
  6948. }
  6949. }
  6950.  
  6951. return bestEnt;
  6952. }
  6953.  
  6954. public function GetCurrentEffects() : array< CBaseGameplayEffect >
  6955. {
  6956. var null : array< CBaseGameplayEffect >;
  6957.  
  6958. if(effectManager)
  6959. return effectManager.GetCurrentEffects();
  6960.  
  6961. return null;
  6962. }
  6963.  
  6964.  
  6965. public function GetNeedsToReduceFallingDamage( heightDiff : float ) : bool
  6966. {
  6967. return heightDiff >= damageDistanceNotReducing;
  6968. }
  6969.  
  6970.  
  6971. public function CanReduceFallDamage( heightDiff : float ) : bool
  6972. {
  6973. return heightDiff <= damageDistanceReducing;
  6974. }
  6975.  
  6976.  
  6977. function ApplyFallingDamage( heightDiff : float, optional reducing : bool ) : float
  6978. {
  6979. var forcedDeath : bool;
  6980. var action : W3DamageAction;
  6981. var dmgPerc : float;
  6982. var damageValue : float;
  6983. var deathDistance : float;
  6984. var damageDistance : float;
  6985.  
  6986. var totalDamage : float;
  6987.  
  6988.  
  6989. //--===modEnhancedQuen Begin===--
  6990. var witcher : W3PlayerWitcher;
  6991. var quenEnhanced : ModEnhancedQuenConfig;
  6992. var disabled : bool;
  6993. var quen : bool;
  6994. var quenDeath : float;
  6995. var quenBreak : float;
  6996.  
  6997. witcher = GetWitcherPlayer();
  6998. quenEnhanced = new ModEnhancedQuenConfig in this;
  6999. disabled = quenEnhanced.quenBlocksFallsDisabled;
  7000. quen = false;
  7001.  
  7002. if( !disabled )
  7003. {
  7004. if( reducing )
  7005. quenBreak = quenEnhanced.quenBreakDistanceReducing;
  7006. else
  7007. quenBreak = quenEnhanced.quenBreakDistNotReducing;
  7008.  
  7009. if( witcher && witcher.IsAnyQuenActive())
  7010. {
  7011. quenDeath = quenEnhanced.quenDeathDistance;
  7012. quen = true;
  7013. }
  7014. }
  7015. //--===modEnhancedQuen End===--
  7016.  
  7017. forcedDeath = !thePlayer.IsAlive();
  7018.  
  7019.  
  7020. if( reducing )
  7021. {
  7022. deathDistance = deathDistanceReducing;
  7023. damageDistance = damageDistanceReducing;
  7024. }
  7025. else
  7026. {
  7027. deathDistance = deathDistNotReducing;
  7028. damageDistance = damageDistanceNotReducing;
  7029. }
  7030.  
  7031.  
  7032. //--===modEnhancedQuen Begin===--
  7033. if( ((!quen || disabled) && heightDiff > deathDistance) || forcedDeath )
  7034. //--===modEnhancedQuen End===--
  7035. {
  7036. dmgPerc = 1.0f;
  7037. PlayEffect( 'heavy_hit' );
  7038. PlayEffect( 'hit_screen' );
  7039.  
  7040.  
  7041. totalDamage = GetMaxHealth();
  7042. }
  7043.  
  7044.  
  7045. else if( heightDiff < damageDistance )
  7046. {
  7047. return 0.0f;
  7048. }
  7049.  
  7050. //--===modEnhancedQuen Begin===--
  7051. else if( !disabled && quen )
  7052. {
  7053. if( heightDiff <= quenDeath )
  7054. {
  7055. if( !quenEnhanced.quenNeverBreaks && heightDiff > quenBreak )
  7056. {
  7057. PlayEffect('hit_electric_quen');
  7058. witcher.FinishQuen(true);
  7059. }
  7060. return 0.0f;
  7061. }
  7062.  
  7063. if( heightDiff > quenDeath )
  7064. {
  7065. PlayEffect('hit_electric_quen');
  7066. witcher.FinishQuen(true);
  7067.  
  7068. dmgPerc = 1.0f;
  7069. PlayEffect( 'heavy_hit' );
  7070. PlayEffect( 'hit_screen' );
  7071.  
  7072.  
  7073. totalDamage = GetMaxHealth();
  7074. }
  7075. }
  7076. //--===modEnhancedQuen End===--
  7077.  
  7078.  
  7079. else
  7080. {
  7081. dmgPerc = MapF( heightDiff, damageDistance, deathDistance, 0.0f, 1.0f );
  7082.  
  7083.  
  7084. if( dmgPerc < 1.0f && dmgPerc >= GetHealthPercents() - fallDamageMinHealthPerc )
  7085. {
  7086. totalDamage = MaxF( 0.0f, GetHealthPercents() - fallDamageMinHealthPerc ) * GetMaxHealth();
  7087. }
  7088. else
  7089. {
  7090. totalDamage = dmgPerc * GetMaxHealth();
  7091. }
  7092. }
  7093.  
  7094.  
  7095. action = new W3DamageAction in this;
  7096. action.Initialize(NULL, this, NULL, "FallingDamage", EHRT_None, CPS_Undefined, false, false, false, true);
  7097. action.SetCanPlayHitParticle(false);
  7098. damageValue = totalDamage;
  7099. action.AddDamage(theGame.params.DAMAGE_NAME_DIRECT, damageValue );
  7100.  
  7101. theGame.damageMgr.ProcessAction( action );
  7102.  
  7103. delete action;
  7104. //--===modEnhancedQuen Begin===--
  7105. delete quenEnhanced;
  7106. //--===modEnhancedQuen End===--
  7107.  
  7108. return dmgPerc;
  7109. }
  7110.  
  7111.  
  7112.  
  7113.  
  7114.  
  7115.  
  7116. event OnContactEvent( position : Vector, force : Vector, otherBody : CComponent, actorIndex : int, shapeIndex : int )
  7117. {
  7118. var mass, velocity, momentum : float;
  7119. var damage : W3DamageAction;
  7120. var damageVal : float;
  7121. var hitReaction : EHitReactionType;
  7122.  
  7123. if( this.collisionDamageTimestamp + 1.0 > theGame.GetEngineTimeAsSeconds())
  7124. return false;
  7125.  
  7126. if( otherBody.HasCollisionType('Ragdoll', actorIndex, shapeIndex) || otherBody.HasCollisionType('Weapon', actorIndex, shapeIndex) || otherBody.HasCollisionType('Corpse', actorIndex, shapeIndex) )
  7127. {
  7128.  
  7129. return false;
  7130. }
  7131.  
  7132. mass = otherBody.GetPhysicalObjectMass( actorIndex );
  7133. velocity = VecLength( otherBody.GetPhysicalObjectLinearVelocity( actorIndex ) );
  7134. momentum = mass * velocity;
  7135.  
  7136.  
  7137.  
  7138.  
  7139.  
  7140. if( momentum < 50.0 || velocity < 3.5 )
  7141. return false;
  7142.  
  7143. damageVal = 0.25 * momentum;
  7144. hitReaction = EHRT_Light;
  7145.  
  7146.  
  7147.  
  7148. if( damageVal > 100.0 )
  7149. damageVal = 100.0;
  7150.  
  7151. damage = new W3DamageAction in this;
  7152. damage.Initialize( (CGameplayEntity)( otherBody.GetEntity() ), this, theGame, "physical_object_damage", hitReaction, CPS_Undefined, false, false, false, true );
  7153. damage.AddDamage( theGame.params.DAMAGE_NAME_PHYSICAL, damageVal );
  7154. theGame.damageMgr.ProcessAction( damage );
  7155.  
  7156. this.collisionDamageTimestamp = theGame.GetEngineTimeAsSeconds();
  7157.  
  7158. delete damage;
  7159. }
  7160.  
  7161.  
  7162. var customCameraStackIndex : int;
  7163. event OnCustomCamera( eventName : name, properties : SMultiValue, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo )
  7164. {
  7165. var customCameraParams : SCustomCameraParams;
  7166. var player : CR4Player = thePlayer;
  7167.  
  7168. if ( properties.enums[0].enumType != 'ECustomCameraType' )
  7169. LogChannel( 'CustomCamera', "ERROR: Selected enum is not a custom camera!!!" );
  7170. else
  7171. {
  7172. if ( properties.enums[0].enumValue == CCT_None )
  7173. {
  7174. player.DisableCustomCamInStack( customCameraStackIndex );
  7175. }
  7176. else
  7177. {
  7178. customCameraParams.source = this;
  7179. customCameraParams.cameraParams = properties;
  7180. customCameraParams.useCustomCamera = true;
  7181. player.DisableCustomCamInStack( customCameraStackIndex );
  7182. this.customCameraStackIndex = player.AddCustomCamToStack( customCameraParams );
  7183. SignalGameplayEventParamInt('CameraIndex',customCameraStackIndex);
  7184. }
  7185. }
  7186. }
  7187.  
  7188. // W3EE - Frozen & Chilled Effects
  7189. event OnFrostHit(source : CGameplayEntity)
  7190. {
  7191. super.OnFrostHit(source);
  7192. RemoveAllBuffsOfType(EET_Burning);
  7193. }
  7194. // W3EE - End
  7195.  
  7196.  
  7197.  
  7198.  
  7199.  
  7200. public function SetIsSwimming ( toggle : bool ) { isSwimming = toggle; }
  7201. public function IsSwimming () : bool { return isSwimming; }
  7202.  
  7203. public final function IsDiving() : bool
  7204. {
  7205. if ( !MAC )
  7206. MAC = (CMovingPhysicalAgentComponent)GetMovingAgentComponent();
  7207.  
  7208. if(MAC)
  7209. return MAC.IsDiving();
  7210.  
  7211. return false;
  7212. }
  7213.  
  7214.  
  7215. final function GetSwordTipMovementFromAnimation( animation : name, time : float, deltaTime : float, hitWeapon : CItemEntity ) : Vector
  7216. {
  7217. var handBone : name;
  7218. var handBoneIdx : int;
  7219. var boneAtTimeMS : Matrix;
  7220. var boneWithDeltaTimeMS : Matrix;
  7221. var swordTipAtTime : Vector;
  7222. var swordTipWithDeltaTime : Vector;
  7223. var localToWorld : Matrix;
  7224. var weaponSlotMatrixWS : Matrix;
  7225. var handMatrixWS : Matrix;
  7226.  
  7227. handBone = 'r_weapon';
  7228. handBoneIdx = GetBoneIndex( handBone );
  7229.  
  7230.  
  7231. hitWeapon.CalcEntitySlotMatrix( 'blood_fx_point', weaponSlotMatrixWS );
  7232. handMatrixWS = GetBoneWorldMatrixByIndex( handBoneIdx );
  7233.  
  7234.  
  7235. swordTipAtTime = MatrixGetTranslation( weaponSlotMatrixWS );
  7236. swordTipAtTime = VecTransform( MatrixGetInverted( handMatrixWS ), swordTipAtTime );
  7237. swordTipWithDeltaTime = swordTipAtTime;
  7238.  
  7239. GetRootAnimatedComponent().GetBoneMatrixMovementModelSpaceInAnimation( handBoneIdx, animation, time, deltaTime, boneAtTimeMS, boneWithDeltaTimeMS );
  7240.  
  7241. swordTipAtTime = VecTransform( boneAtTimeMS, swordTipAtTime );
  7242. swordTipWithDeltaTime = VecTransform( boneWithDeltaTimeMS, swordTipWithDeltaTime );
  7243.  
  7244. localToWorld = GetLocalToWorld();
  7245. swordTipAtTime = VecTransform( localToWorld, swordTipAtTime );
  7246. swordTipWithDeltaTime = VecTransform( localToWorld, swordTipWithDeltaTime );
  7247.  
  7248.  
  7249. return swordTipWithDeltaTime - swordTipAtTime;
  7250. }
  7251.  
  7252.  
  7253. public function GetLyingDownFacingDirection() : float
  7254. {
  7255. var boneAngles : EulerAngles;
  7256. var pitch : float;
  7257. boneAngles = MatrixGetRotation( GetBoneWorldMatrixByIndex( this.GetBoneIndex( 'torso3' ) ) );
  7258. pitch = boneAngles.Pitch;
  7259.  
  7260. return pitch;
  7261. }
  7262.  
  7263.  
  7264. function RegisterCollisionEventsListener()
  7265. {
  7266. var physicalComponent : CMovingPhysicalAgentComponent;
  7267. physicalComponent = ((CMovingPhysicalAgentComponent)GetComponentByClassName('CMovingPhysicalAgentComponent'));
  7268. if( physicalComponent )
  7269. {
  7270. physicalComponent.RegisterEventListener( this );
  7271. }
  7272. }
  7273.  
  7274. public final function FreezeCloth( frozen : bool )
  7275. {
  7276. var comps : array< CComponent >;
  7277. var cloth : CClothComponent;
  7278. var i : int;
  7279.  
  7280. comps = GetComponentsByClassName( 'CClothComponent' );
  7281. for( i=0; i<comps.Size(); i+=1 )
  7282. {
  7283. cloth = ( CClothComponent ) comps[ i ];
  7284. if( cloth )
  7285. {
  7286. cloth.SetFrozen( frozen );
  7287. }
  7288. }
  7289. }
  7290.  
  7291. public final function SetClothSimulation( b : bool )
  7292. {
  7293. var comps : array< CComponent >;
  7294. var cloth : CClothComponent;
  7295. var i : int;
  7296.  
  7297. comps = GetComponentsByClassName( 'CClothComponent' );
  7298. for( i=0; i<comps.Size(); i+=1 )
  7299. {
  7300. cloth = ( CClothComponent ) comps[ i ];
  7301. if( cloth )
  7302. {
  7303. cloth.SetSimulated( b );
  7304. }
  7305. }
  7306. }
  7307.  
  7308.  
  7309.  
  7310.  
  7311.  
  7312. event OnRagdollOnGround();
  7313.  
  7314.  
  7315. event OnRagdollInAir();
  7316.  
  7317.  
  7318. event OnNoLongerInRagdoll();
  7319.  
  7320.  
  7321.  
  7322.  
  7323.  
  7324. event OnProcessActionPost(action : W3DamageAction)
  7325. {
  7326. var actorVictim : CActor;
  7327. var bloodTrailParam : CBloodTrailEffect;
  7328. var attackAction : W3Action_Attack;
  7329.  
  7330. actorVictim = (CActor)action.victim;
  7331. attackAction = (W3Action_Attack)action;
  7332.  
  7333.  
  7334. if( attackAction && action.DealsAnyDamage() && actorVictim)
  7335. {
  7336. bloodTrailParam = (CBloodTrailEffect)actorVictim.GetGameplayEntityParam( 'CBloodTrailEffect' );
  7337. if ( bloodTrailParam )
  7338. {
  7339. GetInventory().PlayItemEffect( attackAction.GetWeaponId(), bloodTrailParam.GetEffectName() );
  7340. }
  7341. }
  7342. }
  7343.  
  7344. event OnHitActionReaction( attacker : CActor, weaponName : name )
  7345. {
  7346.  
  7347. if ( attacker.HasAbility( 'mon_cloud_giant' ) && weaponName == 'mon_q704_cloud_giant_ep2_weapon' )
  7348. {
  7349. SoundEvent( "monster_cloud_giant_cmb_weapon_hit_add", 'head' );
  7350. }
  7351. else if ( attacker.HasAbility( 'mon_knight_giant' ) && weaponName == 'mon_q701_giant_ep2_weapon' )
  7352. {
  7353. SoundEvent( "monster_knight_giant_cmb_weapon_hit_add", 'head' );
  7354. }
  7355. }
  7356.  
  7357.  
  7358. public function GetCriticalHitDamageBonus(weaponId : SItemUniqueId, victimMonsterCategory : EMonsterCategory, isStrikeAtBack : bool) : SAbilityAttributeValue
  7359. {
  7360. return GetAttributeValue(theGame.params.CRITICAL_HIT_DAMAGE_BONUS);
  7361. }
  7362.  
  7363.  
  7364. public function HasAlternateQuen() : bool
  7365. {
  7366. return false;
  7367. }
  7368.  
  7369. public function FinishQuen( skipVisuals : bool, optional forceNoBearSetBonus : bool );
  7370.  
  7371. public function UpdateStatsForDifficultyLevel(d : EDifficultyMode)
  7372. {
  7373. if(abilityManager && abilityManager.IsInitialized() && IsAlive())
  7374. abilityManager.UpdateStatsForDifficultyLevel(d);
  7375. }
  7376.  
  7377. public function GetLevel() : int
  7378. {
  7379. return -1;
  7380. }
  7381.  
  7382. public function TestIsInSettlement() : bool
  7383. {
  7384. var ents : array<CEntity>;
  7385. var trigger : CTriggerAreaComponent;
  7386. var i : int;
  7387.  
  7388. theGame.GetEntitiesByTag('settlement', ents);
  7389.  
  7390. for(i=0; i<ents.Size(); i+=1)
  7391. {
  7392. trigger = (CTriggerAreaComponent)(ents[i].GetComponentByClassName('CTriggerAreaComponent'));
  7393. if(trigger.TestEntityOverlap(this))
  7394. return true;
  7395. }
  7396.  
  7397. return false;
  7398. }
  7399.  
  7400. event OnSpawnedEditor( spawnData : SEntitySpawnData )
  7401. {
  7402. var resource : CEntityTemplate;
  7403. var resourceKey, itemName : name;
  7404. var ent : CEntity;
  7405. var i : int;
  7406. var items, ids : array<SItemUniqueId>;
  7407. var inv, geraltInv : CInventoryComponent;
  7408. var definition : EPlayerPreviewInventory;
  7409.  
  7410.  
  7411.  
  7412. buffImmunities.Clear();
  7413.  
  7414.  
  7415. if ( this.GetVoicetag() != 'GERALT' )
  7416. {
  7417. return true;
  7418. }
  7419.  
  7420. definition = theGame.GetGameplayConfigEnumValue('playerPreviewInventory');
  7421.  
  7422.  
  7423. switch(definition)
  7424. {
  7425. case PPI_Bear_1 :
  7426. resourceKey = 'preview_inventory_bear_1';
  7427. break;
  7428. case PPI_Bear_4 :
  7429. resourceKey = 'preview_inventory_bear_4';
  7430. break;
  7431. case PPI_Lynx_1 :
  7432. resourceKey = 'preview_inventory_lynx_1';
  7433. break;
  7434. case PPI_Lynx_4 :
  7435. resourceKey = 'preview_inventory_lynx_4';
  7436. break;
  7437. case PPI_Gryphon_1 :
  7438. resourceKey = 'preview_inventory_gryphon_1';
  7439. break;
  7440. case PPI_Gryphon_4 :
  7441. resourceKey = 'preview_inventory_gryphon_4';
  7442. break;
  7443. case PPI_Common_1 :
  7444. resourceKey = 'preview_inventory_common_1';
  7445. break;
  7446. case PPI_Naked :
  7447. resourceKey = 'preview_inventory_naked';
  7448. break;
  7449. case PPI_Viper :
  7450. resourceKey = 'preview_inventory_viper';
  7451. break;
  7452. case PPI_Red_Wolf_1 :
  7453. resourceKey = 'preview_inventory_red_wolf_1';
  7454. break;
  7455.  
  7456. case PPI_default :
  7457. default :
  7458. resourceKey = 'preview_inventory_default';
  7459. break;
  7460. }
  7461.  
  7462. resource = (CEntityTemplate)LoadResource(resourceKey);
  7463. geraltInv = GetInventory();
  7464. geraltInv.InitInvFromTemplate( resource );
  7465. }
  7466.  
  7467. event OnCutsceneDeath()
  7468. {
  7469. Kill( 'Quest', true );
  7470. }
  7471.  
  7472.  
  7473.  
  7474.  
  7475.  
  7476. public function ActivateEthereal( optional fromHit : bool )
  7477. {
  7478. AddAbility( 'EtherealActivating' );
  7479.  
  7480. if( fromHit )
  7481. {
  7482.  
  7483. AddTimer( 'ActivateEtherealDelayed', 0.0 );
  7484. }
  7485. else
  7486. {
  7487.  
  7488. SetBehaviorVariable( 'wakeUpType', 1.0 );
  7489. AddTimer( 'ActivateEtherealDelayed', 2.15 );
  7490.  
  7491.  
  7492. }
  7493. }
  7494.  
  7495. timer function ActivateEtherealDelayed( td : float, id : int )
  7496. {
  7497. AddAbility( 'EtherealActive' );
  7498. RemoveBuffImmunity( EET_Stagger );
  7499. RemoveBuffImmunity( EET_LongStagger );
  7500. }
  7501.  
  7502. private function ManageEtherealSkillsAndFXes()
  7503. {
  7504. var skills : array<name>;
  7505. var actors : array<CGameplayEntity>;
  7506. var i, j : int;
  7507.  
  7508. skills.PushBack( 'EtherealSkill_1' );
  7509. skills.PushBack( 'EtherealSkill_2' );
  7510. skills.PushBack( 'EtherealSkill_3' );
  7511. skills.PushBack( 'EtherealSkill_4' );
  7512. skills.PushBack( 'EtherealSkill_5' );
  7513.  
  7514. actors.Clear();
  7515. FindGameplayEntitiesInRange( actors, this, 100, 10, 'ethereal', FLAG_OnlyAliveActors );
  7516. thePlayer.IncrementEtherealCount();
  7517.  
  7518. for( i = 0; i < actors.Size(); i += 1 )
  7519. {
  7520. actors[i].PlayEffect( 'ethereal_buff' );
  7521.  
  7522. if( !actors[i].HasAbility( 'EtherealActive' ) )
  7523. {
  7524. actors[i].AddAbility( 'EtherealBuff' );
  7525. }
  7526.  
  7527. for( j = 0; j < thePlayer.GetEtherealCount(); j += 1 )
  7528. {
  7529. actors[i].AddAbility( skills[j] );
  7530.  
  7531. if( j == 3 )
  7532. {
  7533. ((CNewNPC)actors[i]).RaiseGuard();
  7534. actors[i].AddAbility( 'EtherealMashingFix' );
  7535. }
  7536. else if( j == 4 )
  7537. {
  7538. actors[i].SetBehaviorVariable( 'hasSkill_5', 1.0 );
  7539. }
  7540. }
  7541. }
  7542. }
  7543.  
  7544. public function ShouldAttachArrowToPlayer( action : W3DamageAction )
  7545. {
  7546. var arrow : W3ArrowProjectile;
  7547.  
  7548. if( action.victim == thePlayer )
  7549. {
  7550. if( (W3ArrowProjectile)action.causer )
  7551. {
  7552. if( action.processedDmg.vitalityDamage == 0 )
  7553. {
  7554. arrow = (W3ArrowProjectile)action.causer;
  7555. arrow.SetShouldBeAttachedToVictim( false );
  7556. }
  7557. }
  7558. }
  7559. }
  7560.  
  7561.  
  7562.  
  7563.  
  7564.  
  7565.  
  7566. private final function CacheHudModuleHealFloater(heal : float)
  7567. {
  7568. cachedHeal += heal;
  7569.  
  7570. if(!hudModuleHealScheduledUpdate)
  7571. {
  7572. hudModuleHealScheduledUpdate = true;
  7573. AddTimer('HudModuleHealUpdate', 1.0f);
  7574. }
  7575. }
  7576. var cachedHeal : float;
  7577. var hudModuleHealScheduledUpdate : bool;
  7578.  
  7579. timer function HudModuleHealUpdate(dt : float, id : int)
  7580. {
  7581. if(cachedHeal >= 1.0f)
  7582. {
  7583. ShowFloatingValue(EFVT_Heal, cachedHeal, false);
  7584. cachedHeal = 0.f;
  7585. }
  7586.  
  7587. hudModuleHealScheduledUpdate = false;
  7588. }
  7589.  
  7590.  
  7591. // W3EE - Begin
  7592. private final function CacheHudModuleDoTDamageFloater(dmg : float, optional damageType : name)
  7593. {
  7594. cachedDoTDamage += dmg;
  7595. cachedDamageType = damageType;
  7596.  
  7597. if(!hudModuleDoTScheduledUpdate)
  7598. {
  7599. hudModuleDoTScheduledUpdate = true;
  7600. AddTimer('HudModuleDoTUpdate', 1.0f);
  7601. }
  7602. }
  7603. var cachedDoTDamage : float;
  7604. var hudModuleDoTScheduledUpdate : bool;
  7605. var cachedDamageType : name;
  7606.  
  7607. timer function HudModuleDoTUpdate(dt : float, id : int)
  7608. {
  7609. if(cachedDoTDamage >= 1.0f)
  7610. {
  7611. ShowFloatingValue(EFVT_DoT, cachedDoTDamage, false, , cachedDamageType);
  7612. cachedDoTDamage = 0.f;
  7613. }
  7614.  
  7615. hudModuleDoTScheduledUpdate = false;
  7616. }
  7617.  
  7618. public function ShowFloatingValue(type : EFloatingValueType, value : float, cache : bool, optional stringParam : string, optional damageType : name, optional statusType : EEffectType)
  7619. {
  7620. var hud : CR4ScriptedHud;
  7621. var module : CR4HudModuleEnemyFocus;
  7622.  
  7623. if(type == EFVT_Heal && cache)
  7624. {
  7625. CacheHudModuleHealFloater(value);
  7626. }
  7627. else if(type == EFVT_DoT && cache)
  7628. {
  7629. CacheHudModuleDoTDamageFloater(value, damageType);
  7630. }
  7631. else if(thePlayer.GetTarget() == this)
  7632. {
  7633. hud = (CR4ScriptedHud)theGame.GetHud();
  7634. if(hud)
  7635. {
  7636. module = (CR4HudModuleEnemyFocus)hud.GetHudModule("EnemyFocusModule");
  7637. if(module)
  7638. {
  7639. module.ShowDamageType(type, value, stringParam, , damageType, statusType);
  7640. }
  7641. }
  7642. }
  7643. }
  7644.  
  7645. public function IsHuge() : bool
  7646. {
  7647. if( (CNewNPC)this )
  7648. return ((CNewNPC)this).IsHuge();
  7649. else
  7650. return HasAbility( 'mon_type_huge' );
  7651. }
  7652.  
  7653. public function ApplyBleeding( numberStacks : int, causer : CGameplayEntity, sourceName : string, optional forceEffect : bool )
  7654. {
  7655. var bleedingEffect : W3Effect_Bleeding;
  7656. var bleedingParams : SCustomEffectParams;
  7657. var effectValue : SAbilityAttributeValue;
  7658. var resistPts, resistPerc : float;
  7659.  
  7660. bleedingEffect = (W3Effect_Bleeding)GetBuff(EET_Bleeding);
  7661.  
  7662. effectValue.valueMultiplicative = Max(1, numberStacks);
  7663.  
  7664. bleedingParams.effectType = EET_Bleeding;
  7665. bleedingParams.creator = causer;
  7666. bleedingParams.sourceName = sourceName;
  7667. bleedingParams.duration = -1;
  7668. bleedingParams.effectValue = effectValue;
  7669. bleedingParams.customAbilityName = '';
  7670. bleedingParams.customFXName = '';
  7671. bleedingParams.isSignEffect = false;
  7672.  
  7673. if( (CR4Player)this )
  7674. {
  7675. GetResistValue(CDS_BleedingRes, resistPts, resistPerc);
  7676. if( forceEffect || RandRangeF(1.f) > resistPerc )
  7677. {
  7678. if( !bleedingEffect )
  7679. AddEffectCustom(bleedingParams);
  7680. else
  7681. bleedingEffect.IncreaseStacks((int)effectValue.valueMultiplicative);
  7682. }
  7683. }
  7684. else
  7685. {
  7686. if( forceEffect || RandRangeF(1.f) > ((CNewNPC)this).GetNPCCustomStat(theGame.params.DAMAGE_NAME_BLEEDING) )
  7687. {
  7688. if( !bleedingEffect )
  7689. AddEffectCustom(bleedingParams);
  7690. else
  7691. {
  7692. bleedingEffect.IncreaseStacks((int)effectValue.valueMultiplicative);
  7693. ShowFloatingValue(EFVT_Buff, 0, false,, theGame.params.DAMAGE_NAME_DIRECT, EET_Bleeding);
  7694. }
  7695. }
  7696. }
  7697. }
  7698.  
  7699. public function ApplyPoisoning( numberStacks : int, causer : CGameplayEntity, sourceName : string, optional forceEffect : bool )
  7700. {
  7701. var poisonEffect : W3Effect_Poison;
  7702. var poisonParams : SCustomEffectParams;
  7703. var effectValue : SAbilityAttributeValue;
  7704. var resistPts, resistPerc : float;
  7705.  
  7706. poisonEffect = (W3Effect_Poison)GetBuff(EET_Poison);
  7707.  
  7708. effectValue.valueMultiplicative = Max(1, numberStacks);
  7709.  
  7710. poisonParams.effectType = EET_Poison;
  7711. poisonParams.creator = causer;
  7712. poisonParams.sourceName = sourceName;
  7713. poisonParams.duration = -1;
  7714. poisonParams.effectValue = effectValue;
  7715. poisonParams.customAbilityName = '';
  7716. poisonParams.customFXName = '';
  7717. poisonParams.isSignEffect = false;
  7718.  
  7719. if( (CR4Player)this )
  7720. {
  7721. GetResistValue(CDS_PoisonRes, resistPts, resistPerc);
  7722. if( forceEffect || RandRangeF(1.f) > resistPerc )
  7723. {
  7724. if( !poisonEffect )
  7725. AddEffectCustom(poisonParams);
  7726. else
  7727. poisonEffect.IncreaseStacks((int)effectValue.valueMultiplicative);
  7728. }
  7729. }
  7730. else
  7731. {
  7732. if( forceEffect || RandRangeF(1.f) > ((CNewNPC)this).GetNPCCustomStat(theGame.params.DAMAGE_NAME_POISON) )
  7733. {
  7734. if( !poisonEffect )
  7735. AddEffectCustom(poisonParams);
  7736. else
  7737. {
  7738. poisonEffect.IncreaseStacks((int)effectValue.valueMultiplicative);
  7739. ShowFloatingValue(EFVT_Buff, 0, false,, theGame.params.DAMAGE_NAME_POISON, EET_Poison);
  7740. }
  7741. }
  7742. }
  7743. }
  7744.  
  7745. private var isImmobilized : bool; default isImmobilized = false;
  7746. public function SetIsImmobilized( b : bool )
  7747. {
  7748. isImmobilized = b;
  7749. }
  7750.  
  7751. public function IsImmobilized() : bool
  7752. {
  7753. return isImmobilized;
  7754. }
  7755.  
  7756. private var isQuest : bool; default isQuest = false;
  7757. timer function SetIsQuest( dt : float, id : int )
  7758. {
  7759. isQuest = (HasTag('mq3031_nidas') || HasAbility('_canBeFollower') || HasAbility('_combatFollowerHardcoreV') || HasAbility('_combatFollowerHardcoreE') || HasAbility('_combatFollowerHardV') || HasAbility('_combatFollowerHardE') || ((CNewNPC)this).GetNPCType() == ENGT_Quest) && (CNewNPC)this;
  7760. }
  7761.  
  7762. public function IsQuestActor() : bool
  7763. {
  7764. return isQuest && !HasAbility('mon_q703_arena_knights') && !HasAbility('SkillBoss') && !HasAbility('SkillShieldHard');
  7765. }
  7766.  
  7767. private var yrdenImmobilizeCooldown : float; default yrdenImmobilizeCooldown = 0.f;
  7768. public function SetYrdenCooldown( cooldown : float )
  7769. {
  7770. yrdenImmobilizeCooldown = cooldown;
  7771. }
  7772.  
  7773. public function GetYrdenCooldown() : float
  7774. {
  7775. return yrdenImmobilizeCooldown;
  7776. }
  7777. // W3EE - End
  7778.  
  7779. public function CreateFXEntityAtPelvis( resourceName : name, attach : bool ) : CEntity
  7780. {
  7781. var boneName : name;
  7782. var boneIndex : int;
  7783.  
  7784. boneName = 'pelvis';
  7785. boneIndex = GetBoneIndex( boneName );
  7786. if( boneIndex == -1 )
  7787. {
  7788. boneName = 'k_pelvis_g';
  7789. }
  7790.  
  7791. return CreateFXEntityAtBone( resourceName, boneName, attach );
  7792. }
  7793.  
  7794. public function CreateFXEntityAtBone( resourceName : name, boneName : name, attach : bool ) : CEntity
  7795. {
  7796. var template : CEntityTemplate;
  7797. var boneRotation : EulerAngles;
  7798. var bonePosition : Vector;
  7799. var boneIndex : int;
  7800. var fxEnt : CEntity;
  7801.  
  7802.  
  7803. boneIndex = GetBoneIndex( boneName );
  7804. if( boneIndex == -1 )
  7805. {
  7806. return fxEnt;
  7807. }
  7808.  
  7809.  
  7810. template = (CEntityTemplate)LoadResource( resourceName );
  7811. if( !template )
  7812. {
  7813. return fxEnt;
  7814. }
  7815.  
  7816. GetBoneWorldPositionAndRotationByIndex( boneIndex, bonePosition, boneRotation );
  7817. fxEnt = theGame.CreateEntity( template, bonePosition, boneRotation );
  7818.  
  7819. if( attach )
  7820. {
  7821. fxEnt.CreateAttachmentAtBoneWS( this, boneName, bonePosition, boneRotation );
  7822. }
  7823.  
  7824. return fxEnt;
  7825. }
  7826.  
  7827.  
  7828.  
  7829.  
  7830.  
  7831.  
  7832.  
  7833. public function OnSignCastPerformed(signType : ESignType, isAlternate : bool)
  7834. {
  7835.  
  7836. }
  7837.  
  7838. timer function Runeword1DisableFireFX(dt : float, id : int)
  7839. {
  7840.  
  7841. if(IsEffectActive('critical_burning') && !HasBuff(EET_Burning))
  7842. {
  7843. StopEffect('critical_burning');
  7844. StopEffect('critical_burning_csx');
  7845. }
  7846. }
  7847.  
  7848. // W3EE - Begin
  7849. timer function DisablePoisonFX( dt : float, id : int )
  7850. {
  7851. if( IsEffectActive('critical_poison') && !HasBuff(EET_Poison) )
  7852. {
  7853. StopEffect('critical_poison');
  7854. }
  7855. }
  7856.  
  7857. private var wasPoiseBroken : bool;
  7858. public function SetWasPoiseBroken( b : bool )
  7859. {
  7860. wasPoiseBroken = b;
  7861. }
  7862.  
  7863. public function GetWasPoiseBroken() : bool
  7864. {
  7865. return wasPoiseBroken;
  7866. }
  7867.  
  7868. timer function NotifyStaggerEndTimed( dt : float, id : int )
  7869. {
  7870. NotifyStaggerEnd();
  7871. }
  7872.  
  7873. public function NotifyStaggerEnd()
  7874. {
  7875. var playerPoise : W3Effect_Poise;
  7876. var npcPoise : W3Effect_NPCPoise;
  7877.  
  7878. wasPoiseBroken = false;
  7879. playerPoise = (W3Effect_Poise)GetBuff(EET_Poise);
  7880. npcPoise = (W3Effect_NPCPoise)GetBuff(EET_NPCPoise);
  7881. if( playerPoise.IsPoiseBroken() )
  7882. playerPoise.SetPoiseBreakTimer(0);
  7883.  
  7884. if( npcPoise.IsPoiseBroken() )
  7885. npcPoise.SetPoiseBreakTimer(0);
  7886. }
  7887. // W3EE - End
  7888.  
  7889.  
  7890.  
  7891. public function Debug_GetUsedDifficultyMode() : EDifficultyMode
  7892. {
  7893. if(abilityManager && abilityManager.IsInitialized())
  7894. return abilityManager.Debug_GetUsedDifficultyMode();
  7895.  
  7896. return EDM_NotSet;
  7897. }
  7898.  
  7899. private function HACK_ManageEtherealSkills()
  7900. {
  7901. var ents : array<CGameplayEntity>;
  7902. var i : int;
  7903. var abilityName : name;
  7904.  
  7905. ents.Clear();
  7906. FindGameplayEntitiesInRange(ents, thePlayer, 50, 10, 'etherealTest', FLAG_Attitude_Hostile + FLAG_OnlyAliveActors );
  7907.  
  7908. ((CActor)ents[0]).ActivateEthereal();
  7909. }
  7910.  
  7911. import function CPPForceActorLOD( enable : bool, optional LODIndex : int );
  7912. exec function ForceActorLOD( enable : bool, optional LODIndex : int )
  7913. CPPForceActorLOD( enable, LODIndex );
  7914.  
  7915.  
Add Comment
Please, Sign In to add comment