Advertisement
Guest User

Untitled

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