/***********************************************************************/ /** © 2015 CD PROJEKT S.A. All rights reserved. /** THE WITCHER® is a trademark of CD PROJEKT S. A. /** The Witcher game is based on the prose of Andrzej Sapkowski. /***********************************************************************/ statemachine abstract import class CR4Player extends CPlayer { protected var pcGamePlayInitialized : bool; private var pcMode : bool; default pcMode = true; protected saved var weaponHolster : WeaponHolster; public var rangedWeapon : Crossbow; public var crossbowDontPopStateHack : bool; default crossbowDontPopStateHack = false; private var hitReactTransScale : float; private var bIsCombatActionAllowed : bool; private var currentCombatAction : EBufferActionType; private var uninterruptedHitsCount : int; private var uninterruptedHitsCameraStarted : bool; private var uninterruptedHitsCurrentCameraEffect : name; private var counterTimestamps : array; private var hitReactionEffect : bool; private var lookAtPosition : Vector; private var orientationTarget : EOrientationTarget; private var customOrientationTarget : EOrientationTarget; protected var customOrientationStack : array; public var delayOrientationChange : bool; protected var delayCameraOrientationChange : bool; private var actionType : int; private var customOrientationStackIndex : int; private var emptyMoveTargetTimer : float; private var onlyOneEnemyLeft : bool; public var isInFinisher : bool; private var finisherTarget : CGameplayEntity; private var combatStance : EPlayerCombatStance; public var approachAttack : int; default approachAttack = 1; protected var specialAttackCamera : bool; private var specialAttackTimeRatio : float; public saved var itemsPerLevel : array; public var itemsPerLevelGiven : array; private var playerTickTimerPhase : int; default playerTickTimerPhase = 0; protected var evadeHeading : float; public var vehicleCbtMgrAiming : bool; public var specialHeavyChargeDuration : float; public var specialHeavyStartEngineTime : EngineTime; public var playedSpecialAttackMissingResourceSound : bool; public function SetPlayedSpecialAttackMissingResourceSound(b : bool) {playedSpecialAttackMissingResourceSound = b;} public var counterCollisionGroupNames : array; public saved var lastInstantKillTime : GameTime; private var noSaveLockCombatActionName : string; default noSaveLockCombatActionName = 'combat_action'; private var noSaveLockCombatAction : int; private var deathNoSaveLock : int; private var noSaveLock : int; protected saved var newGamePlusInitialized : bool; default newGamePlusInitialized = false; protected var BufferAllSteps : bool; protected var BufferCombatAction : EBufferActionType; protected var BufferButtonStage : EButtonStage; default BufferAllSteps = false; default customOrientationTarget = OT_None; default hitReactionEffect = true; default uninterruptedHitsCount = 0; default uninterruptedHitsCameraStarted = false; default customOrientationStackIndex = -1; private var keepRequestingCriticalAnimStart : bool; default keepRequestingCriticalAnimStart = false; private var currentCustomAction : EPlayerExplorationAction; public var substateManager : CExplorationStateManager; protected var isOnBoat : bool; protected var isInShallowWater : bool; public var medallion : W3MedallionFX; protected var lastMedallionEffect : float; private var isInRunAnimation : bool; public var interiorTracker :CPlayerInteriorTracker; public var m_SettlementBlockCanter : int; private var fistFightMinigameEnabled : bool; private var isFFMinigameToTheDeath : bool; private var FFMinigameEndsithBS : bool; public var fistFightTeleportNode : CNode; public var isStartingFistFightMinigame : bool; public var GeraltMaxHealth : float; public var fistsItems : array< SItemUniqueId >; default FFMinigameEndsithBS = false; default fistFightMinigameEnabled = false; default isFFMinigameToTheDeath = false; private var gwintAiDifficulty : EGwintDifficultyMode; default gwintAiDifficulty = EGDM_Easy; private var gwintAiAggression : EGwintAggressionMode; default gwintAiAggression = EGAM_Defensive; private var gwintMinigameState : EMinigameState; default gwintMinigameState = EMS_None; import private var horseWithInventory : EntityHandle; private var currentlyMountedHorse : CNewNPC; private var horseSummonTimeStamp : float; private saved var isHorseRacing : bool; private var horseCombatSlowMo : bool; default isHorseRacing = false; default horseCombatSlowMo = true; private var HudMessages : array ; protected var fShowToLowStaminaIndication : float; public var showTooLowAdrenaline : bool; private var HAXE3Container : W3Container; private var HAXE3bAutoLoot: bool; private var bShowHud : bool; private var dodgeFeedbackTarget : CActor; default HAXE3bAutoLoot = false; default fShowToLowStaminaIndication = 0.0f; default bShowHud = true; saved var displayedQuestsGUID : array< CGUID >; saved var rewardsMultiplier : array< SRewardMultiplier >; saved var glossaryImageOverride : array< SGlossaryImageOverride >; private var prevRawLeftJoyRot : float; protected var explorationInputContext : name; protected var combatInputContext : name; protected var combatFistsInputContext : name; private var isInsideInteraction : bool; private var isInsideHorseInteraction : bool; public var horseInteractionSource : CEntity; public var nearbyLockedContainersNoKey : array; private var bMoveTargetChangeAllowed : bool; default bMoveTargetChangeAllowed = true; private var moveAdj : CMovementAdjustor; private var defaultLocomotionController : CR4LocomotionPlayerControllerScript; private var canFollowNpc : bool; private var actorToFollow : CActor; public var terrainPitch : float; public var steepSlopeNormalPitch : float; default steepSlopeNormalPitch = 65.f; public var disableSprintTerrainPitch : float; default disableSprintTerrainPitch = 54.f; private var submergeDepth : float; private var m_useSelectedItemIfSpawned : bool; default m_useSelectedItemIfSpawned = false; var navQuery : CNavigationReachabilityQueryInterface; public saved var rememberedCustomHead : name; public saved var disableWeatherDisplay : bool; public saved var proudWalk : bool; private var etherealCount : int; default etherealCount = 0; public saved var injuredWalk : bool; public saved var tiedWalk : bool; private var insideDiveAttackArea : bool; default insideDiveAttackArea = false; private var diveAreaNumber : int; default diveAreaNumber = -1; private var flyingBossCamera : bool; default flyingBossCamera = false; public function SetFlyingBossCamera( val : bool ) { flyingBossCamera = val; } public function GetFlyingBossCamera() : bool { return flyingBossCamera; } public saved var upscaledTooltipState : bool; default upscaledTooltipState = false; private var phantomWeaponMgr : CPhantomWeaponManager; function EnablePCMode( flag : bool ) { pcMode = flag; } public function IsPCModeEnabled() : bool { return pcMode && theInput.LastUsedPCInput(); } public function ShouldUsePCModeTargeting() : bool { return IsPCModeEnabled() && !lastAxisInputIsMovement; } public function SetDodgeFeedbackTarget( target : CActor ) { dodgeFeedbackTarget = target; } public function GetDodgeFeedbackTarget() : CActor { return dodgeFeedbackTarget; } public function SetSubmergeDepth( depth : float ) { submergeDepth = depth; } public function GetSubmergeDepth() : float { return submergeDepth; } editable var delayBetweenIllusionOneliners : float; hint delayBetweenIllusionOneliners = "delay in secs between oneliners about illusionary objects"; default delayBetweenIllusionOneliners = 5; private var battlecry_timeForNext : float; private var battlecry_delayMin : float; default battlecry_delayMin = 15; private var battlecry_delayMax : float; default battlecry_delayMax = 60; private var battlecry_lastTry : name; private var previousWeather : name; private var previousRainStrength : float; protected var receivedDamageInCombat : bool; protected var prevDayNightIsNight : bool; public var failedFundamentalsFirstAchievementCondition : bool; private var spawnedTime : float; public var currentMonsterHuntInvestigationArea : W3MonsterHuntInvestigationArea; private var isPerformingPhaseChangeAnimation : bool; default isPerformingPhaseChangeAnimation = false; default receivedDamageInCombat = false; public var playerMode : W3PlayerMode; protected saved var selectedItemId : SItemUniqueId; protected saved var blockedRadialSlots : array < SRadialSlotDef >; public var enemyCollectionDist : float; public var findMoveTargetDistMin : float; public var findMoveTargetDistMax : float; private var findMoveTargetScaledFrame : float; public var interactDist : float; protected var bCanFindTarget : bool; private var bIsConfirmingEmptyTarget : bool; private var displayTarget : CGameplayEntity; private var isShootingFriendly : bool; default findMoveTargetDistMax = 18.f; default findMoveTargetScaledFrame = 0.5f; default interactDist = 3.5f; private var currentSelectedTarget : CActor; private var selectedTargetToConfirm : CActor; private var bConfirmTargetTimerIsEnabled : bool; public saved var thrownEntityHandle : EntityHandle; private var isThrowingItemWithAim : bool; private saved var isThrowingItem : bool; private var isThrowHoldPressed : bool; private var isAimingCrossbow : bool; default isThrowingItemWithAim = false; public var playerAiming : PlayerAiming; public var forceDismember : bool; public var forceDismemberName : name; public var forceDismemberChance : int; public var forceDismemberExplosion : bool; private var finisherVictim : CActor; public var forceFinisher : bool; public var forceFinisherAnimName : name; public var forceFinisherChance : int; public var forcedStance : bool; private var m_WeaponFXCollisionGroupNames : array ; private var m_CollisionEffect : CEntity; private var m_LastWeaponTipPos : Vector; private var m_CollisionFxTemplate : CEntityTemplate; private var m_RefreshWeaponFXType : bool; private var m_PlayWoodenFX : bool; private var m_activePoster : W3Poster; public function SetActivePoster ( poster : W3Poster ) { m_activePoster = poster; } public function RemoveActivePoster () { m_activePoster = NULL; } public function GetActivePoster () : W3Poster { return m_activePoster; } public var horseOnNavMesh : bool; default horseOnNavMesh = true; public function SetHorseNav( val : bool ) { horseOnNavMesh = val; } public var testAdjustRequestedMovementDirection : bool; default testAdjustRequestedMovementDirection = false; default autoState = 'Exploration'; import final function GetEnemiesInRange( out enemies : array< CActor > ); import final function GetVisibleEnemies( out enemies : array< CActor > ); import final function IsEnemyVisible( enemy : CActor ) : bool; import final function SetupEnemiesCollection( range, heightTolerance : float, maxEnemies : int, optional tag : name, optional flags : int ); import final function IsInInterior() : bool; import final function IsInSettlement() : bool; import final function EnterSettlement( isEntering : bool ); import final function ActionDirectControl( controller : CR4LocomotionDirectController ) : bool; import final function SetPlayerTarget( target : CActor ); import final function SetPlayerCombatTarget( target : CActor ); import final function ObtainTicketFromCombatTarget( ticketName : CName, ticketsCount : int ); import final function FreeTicketAtCombatTarget(); import final function SetScriptMoveTarget( target : CActor ); import final function GetRiderData() : CAIStorageRiderData; import final function SetIsInCombat( inCombat : bool ); import final function SaveLastMountedHorse( mountedHorse : CActor ); import final function SetBacklightFromHealth( healthPercentage : float ); import private final function SetBacklightColor( color : Vector ); import final function GetCombatDataComponent() : CCombatDataComponent; import final function GetTemplatePathAndAppearance( out templatePath : string, out appearance : name ); import final function HACK_BoatDismountPositionCorrection( slotPos : Vector ); import final function HACK_ForceGetBonePosition( boneIndex : int ) : Vector; public function GetLevel() : int { return 0; } var targeting : CR4PlayerTargeting; var targetingPrecalcs : SR4PlayerTargetingPrecalcs; var targetingIn : SR4PlayerTargetingIn; var targetingOut : SR4PlayerTargetingOut; var useNativeTargeting : bool; default useNativeTargeting = true; var visibleActors : array< CActor >; var visibleActorsTime : array< float >; event OnSpawned( spawnData : SEntitySpawnData ) { var atts : array; var skill : ESkill; var i : int; var item : SItemUniqueId; AddAnimEventCallback('ThrowHoldTest', 'OnAnimEvent_ThrowHoldTest'); AddAnimEventCallback('OnWeaponDrawReady', 'OnAnimEvent_OnWeaponDrawReady'); AddAnimEventCallback('OnWeaponHolsterReady', 'OnAnimEvent_OnWeaponHolsterReady'); AddAnimEventCallback('AllowTempLookAt', 'OnAnimEvent_AllowTempLookAt'); AddAnimEventCallback('SlideToTarget', 'OnAnimEvent_SlideToTarget'); AddAnimEventCallback('PlayFinisherBlood', 'OnAnimEvent_PlayFinisherBlood'); AddAnimEventCallback('SlowMo', 'OnAnimEvent_SlowMo'); AddAnimEventCallback('BloodTrailForced', 'OnAnimEvent_BloodTrailForced'); AddAnimEventCallback('FadeOut', 'OnAnimEvent_FadeOut'); AddAnimEventCallback('FadeIn', 'OnAnimEvent_FadeIn'); AddAnimEventCallback('DisallowHitAnim', 'OnAnimEvent_DisallowHitAnim'); AddAnimEventCallback('AllowFall', 'OnAnimEvent_AllowFall'); AddAnimEventCallback('AllowFall2', 'OnAnimEvent_AllowFall2'); AddAnimEventCallback('DettachGround', 'OnAnimEvent_DettachGround'); AddAnimEventCallback('KillWithRagdoll', 'OnAnimEvent_KillWithRagdoll'); AddAnimEventCallback('pad_vibration', 'OnAnimEvent_pad_vibration'); AddAnimEventCallback('pad_vibration_light', 'OnAnimEvent_pad_vibration_light'); AddAnimEventCallback('RemoveBurning', 'OnAnimEvent_RemoveBurning'); AddAnimEventCallback('RemoveTangled', 'OnAnimEvent_RemoveTangled'); AddAnimEventCallback('MoveNoise', 'OnAnimEvent_MoveNoise'); AddItemPerLevelList(); enemyCollectionDist = findMoveTargetDistMax; theGame.RemoveTimeScale('horse_melee'); if(!spawnData.restored && !((W3ReplacerCiri)this) ) { AddTimer('GiveStartingItems', 0.00001, true, , , true); if(!theGame.IsFinalBuild()) { AddAbility('GeraltSkills_Testing'); AddTimer('Debug_GiveTestingItems',0.0001,true); } FactsAdd("tut_stash_fresh_playthrough"); } InitTargeting(); if( spawnData.restored ) { theGame.GameplayFactsRemove( "in_combat" ); } if ( !weaponHolster ) { weaponHolster = new WeaponHolster in this; } weaponHolster.Initialize( this, spawnData.restored ); if ( !interiorTracker ) { interiorTracker = new CPlayerInteriorTracker in this; } interiorTracker.Init( spawnData.restored ); super.OnSpawned( spawnData ); medallion = new W3MedallionFX in this; playerMode = new W3PlayerMode in this; playerMode.Initialize( this ); playerAiming = new PlayerAiming in this; playerAiming.Initialize( this ); navQuery = new CNavigationReachabilityQueryInterface in this; EnableFindTarget( true ); AddTimer( 'CombatCheck', 0.2f, true ); substateManager = ( CExplorationStateManager ) GetComponentByClassName( 'CExplorationStateManager' ); findMoveTargetDist = findMoveTargetDistMax; SetupEnemiesCollection( enemyCollectionDist, findMoveTargetDist, 10, 'None', FLAG_Attitude_Neutral + FLAG_Attitude_Hostile + FLAG_Attitude_Friendly + FLAG_OnlyAliveActors ); inputHandler.RemoveLocksOnSpawn(); ((CActor) this ).SetInteractionPriority( IP_Prio_0 ); prevDayNightIsNight = theGame.envMgr.IsNight(); CheckDayNightCycle(); EnableVisualDebug( SHOW_AI, true ); FactsRemove("blocked_illusion_oneliner"); SetFailedFundamentalsFirstAchievementCondition(false); m_CollisionFxTemplate = (CEntityTemplate) LoadResource( 'sword_colision_fx' ); if( m_WeaponFXCollisionGroupNames.Size() == 0 ) { m_WeaponFXCollisionGroupNames.PushBack('Static'); m_WeaponFXCollisionGroupNames.PushBack('Foliage'); m_WeaponFXCollisionGroupNames.PushBack('Fence'); m_WeaponFXCollisionGroupNames.PushBack('BoatSide'); m_WeaponFXCollisionGroupNames.PushBack('Door'); m_WeaponFXCollisionGroupNames.PushBack('RigidBody'); m_WeaponFXCollisionGroupNames.PushBack('Dynamic'); m_WeaponFXCollisionGroupNames.PushBack('Destructible'); } if ( counterCollisionGroupNames.Size() == 0 ) { counterCollisionGroupNames.PushBack('Static'); counterCollisionGroupNames.PushBack('Foliage'); counterCollisionGroupNames.PushBack('Fence'); counterCollisionGroupNames.PushBack('Terrain'); counterCollisionGroupNames.PushBack('Door'); counterCollisionGroupNames.PushBack('RigidBody'); counterCollisionGroupNames.PushBack('Dynamic'); counterCollisionGroupNames.PushBack('Destructible'); } ResetPadBacklightColor(); if( spawnData.restored ) { if (IsCurrentlyUsingItemL()) { if (inv.HasItemById( currentlyEquipedItemL )) { OnUseSelectedItem(); } else { HideUsableItem(true); } } if ( GetCurrentMeleeWeaponType() == PW_Steel || GetCurrentMeleeWeaponType() == PW_Silver ) { OnEquipMeleeWeapon(GetCurrentMeleeWeaponType(), true, true); } AddTimer( 'UnmountCrossbowTimer', 0.01, true ); ClearBlockedSlots(); } ((CR4PlayerStateSwimming)this.GetState('Swimming')).OnParentSpawned(); SetImmortalityMode( AIM_None, AIC_SyncedAnim ); theGame.GetDefinitionsManager().GetContainedAbilities('DwimeritiumBomb_3', atts); for(i=0; i 0) BlockAllActions('mq3036', false); spawnedTime = theGame.GetEngineTimeAsSeconds(); if ( theGame.GetInGameConfigWrapper().GetVarValue('Gameplay', 'EnableUberMovement' ) == "1" ) theGame.EnableUberMovement( true ); else theGame.EnableUberMovement( false ); if ( !FactsDoesExist("gwent_difficulty") ) FactsAdd("gwent_difficulty", 2); if(!newGamePlusInitialized && FactsQuerySum("NewGamePlus") > 0) { NewGamePlusInitialize(); } if( lastInstantKillTime > theGame.GetGameTime() ) { SetLastInstantKillTime( GameTimeCreate(0) ); } // modStatTrak BEGIN if (!this.GetInventory().HasItem('Achievement Stats')) { this.GetInventory().AddAnItem('Achievement Stats', 1, 0, 0); } //modStatTrak END } public function NewGamePlusInitialize() { SetLastInstantKillTime( GameTimeCreate(0) ); } public function GetTimeSinceSpawned() : float { return theGame.GetEngineTimeAsSeconds() - spawnedTime; } timer function UnmountCrossbowTimer( dt : float, id : int ) { var itemId : SItemUniqueId; itemId = this.inv.GetItemFromSlot( 'l_weapon' ); if ( inv.IsIdValid( itemId ) && inv.IsItemCrossbow( itemId ) ) { rangedWeapon = (Crossbow)( inv.GetItemEntityUnsafe( itemId ) ); if (rangedWeapon) { rangedWeapon.Initialize( (CActor)( rangedWeapon.GetParentEntity() ) ); OnRangedForceHolster( true, true ); RemoveTimer( 'UnmountCrossbowTimer' ); } } else RemoveTimer( 'UnmountCrossbowTimer' ); } event OnDestroyed() { playerAiming.RemoveAimingSloMo(); if(rangedWeapon) rangedWeapon.ClearDeployedEntity(true); ResetPadBacklightColor(); theGame.ReleaseNoSaveLock( noSaveLock ); } public function GetBlockedSlots () : array < SRadialSlotDef > { return blockedRadialSlots; } public function ClearBlockedSlots() { var i : int; for ( i = 0; i < blockedRadialSlots.Size(); i+=1 ) { if( !IsSwimming() ) { if ( EnableRadialSlot(blockedRadialSlots[i].slotName, 'swimming')) { i-=1; continue; } } if (!IsUsingVehicle()) { if ( EnableRadialSlot(blockedRadialSlots[i].slotName, 'useVehicle')) { i-=1; continue; } } if ( !IsCurrentlyUsingItemL() || !IsUsableItemLBlocked() ) { if ( EnableRadialSlot(blockedRadialSlots[i].slotName, 'usableItemL')) { i-=1; continue; } } if ( !IsThrowingItem() ) { if ( EnableRadialSlot(blockedRadialSlots[i].slotName, 'throwBomb')) { i-=1; continue; } } } } public function RestoreBlockedSlots () { var i : int; var slotsToBlock : array; for ( i = 0; i < blockedRadialSlots.Size(); i+=1 ) { slotsToBlock.PushBack ( blockedRadialSlots[i].slotName ); } if ( slotsToBlock.Size() > 0 ) { EnableRadialSlots ( false, slotsToBlock ); } } private function DisableRadialSlot ( slotName : name, sourceName : name ) : bool { var i : int; var k : int; var slotsToBlock : array; var blockedRadialSlotEntry : SRadialSlotDef; slotsToBlock.PushBack ( slotName ); for ( i = 0; i < blockedRadialSlots.Size(); i+=1 ) { if ( blockedRadialSlots[i].slotName == slotName ) { if ( sourceName != '' ) { for ( k = 0; k < blockedRadialSlots[i].disabledBySources.Size(); k += 1 ) { if ( blockedRadialSlots[i].disabledBySources[k] == sourceName ) { return false; } } blockedRadialSlots[i].disabledBySources.PushBack ( sourceName ); return false; } return false; } } blockedRadialSlotEntry = InitBlockedRadialSlotEntry ( slotName ); if ( sourceName != '' ) { blockedRadialSlotEntry.disabledBySources.PushBack ( sourceName ); } blockedRadialSlots.PushBack ( blockedRadialSlotEntry ); EnableRadialSlots ( false, slotsToBlock ); return true; } public function EnableRadialSlot ( slotName : name, sourceName : name ) : bool { var i : int; var k : int; var slotsToBlock : array; slotsToBlock.PushBack ( slotName ); for ( i = 0; i < blockedRadialSlots.Size(); i+=1 ) { if ( blockedRadialSlots[i].slotName == slotName ) { if ( sourceName != '' ) { for ( k = 0; k < blockedRadialSlots[i].disabledBySources.Size(); k += 1 ) { if ( blockedRadialSlots[i].disabledBySources[k] == sourceName ) { blockedRadialSlots[i].disabledBySources.Remove ( blockedRadialSlots[i].disabledBySources[k] ); } } } if ( blockedRadialSlots[i].disabledBySources.Size() <= 0 ) { blockedRadialSlots.Remove( blockedRadialSlots[i] ); EnableRadialSlots ( true, slotsToBlock ); return true; } return false; } } return false; } private function InitBlockedRadialSlotEntry ( slotName : name ) : SRadialSlotDef { var blockedRadialSlotEntry : SRadialSlotDef; blockedRadialSlotEntry.slotName = slotName; return blockedRadialSlotEntry; } public function EnableRadialSlotsWithSource ( enable : bool, slotsToBlock : array < name >, sourceName : name ) { var i : int; for ( i = 0; i < slotsToBlock.Size(); i+=1 ) { if ( enable ) { EnableRadialSlot ( slotsToBlock[i], sourceName ); } else { DisableRadialSlot ( slotsToBlock[i], sourceName ); } } if ( blockedRadialSlots.Size() <= 0 ) { blockedRadialSlots.Clear(); } } public function IsRadialSlotBlocked ( slotName : name ) : bool { var i : int; for ( i = 0; i < blockedRadialSlots.Size(); i+=1 ) { if ( blockedRadialSlots[i].slotName == slotName ) { return true; } } return false; } public function RepairItem ( rapairKitId : SItemUniqueId, usedOnItem : SItemUniqueId ); public function HasRepairAbleGearEquiped () : bool; public function HasRepairAbleWaponEquiped () : bool; public function IsItemRepairAble ( item : SItemUniqueId ) : bool; public final function ReduceAllOilsAmmo( id : SItemUniqueId ) { var i : int; var oils : array< W3Effect_Oil >; oils = inv.GetOilsAppliedOnItem( id ); for( i=0; i; var buff, recentOil : W3Effect_Oil; var i : int; item = GetEquippedSword( steel ); oils = GetBuffs( EET_Oil ); if( oils.Size() > 1 ) { recentOil = inv.GetNewestOilAppliedOnItem( item, false ); } for( i=0; i; var buff : W3Effect_Oil; var i : int; item = GetEquippedSword( isSteel ); oils = GetBuffs( EET_Oil ); for( i=0; i; var ammo, ammoBonus : float; var dm : CDefinitionsManagerAccessor; var buffParams : SCustomEffectParams; var oilParams : W3OilBuffParams; var oilName : name; var min, max : SAbilityAttributeValue; var i : int; var oils : array< W3Effect_Oil >; var existingOil : W3Effect_Oil; if( !CanApplyOilOnItem( oilId, usedOnItem ) ) { return false; } dm = theGame.GetDefinitionsManager(); inv.GetItemAbilitiesWithTag( oilId, theGame.params.OIL_ABILITY_TAG, oilAbilities ); oilName = inv.GetItemName( oilId ); oils = inv.GetOilsAppliedOnItem( usedOnItem ); for( i=0; i= CalculateAttributeValue( max ) ) { inv.RemoveOldestOilFromItem( usedOnItem ); } } } ammo = CalculateAttributeValue(inv.GetItemAttributeValue(oilId, 'ammo')); if(CanUseSkill(S_Alchemy_s06)) { ammoBonus = CalculateAttributeValue(GetSkillAttributeValue(S_Alchemy_s06, 'ammo_bonus', false, false)); ammo *= 1 + ammoBonus * GetSkillLevel(S_Alchemy_s06); } if( existingOil ) { existingOil.Reapply( RoundMath( ammo ) ); } else { buffParams.effectType = EET_Oil; buffParams.creator = this; oilParams = new W3OilBuffParams in this; oilParams.iconPath = dm.GetItemIconPath( oilName ); oilParams.localizedName = dm.GetItemLocalisationKeyName( oilName ); oilParams.localizedDescription = dm.GetItemLocalisationKeyName( oilName ); oilParams.sword = usedOnItem; oilParams.maxCount = RoundMath( ammo ); oilParams.currCount = RoundMath( ammo ); oilParams.oilAbilityName = oilAbilities[ 0 ]; oilParams.oilItemName = oilName; buffParams.buffSpecificParams = oilParams; AddEffectCustom( buffParams ); delete oilParams; } LogOils("Added oil <<" + oilName + ">> to <<" + inv.GetItemName( usedOnItem ) + ">>"); SetFailedFundamentalsFirstAchievementCondition( true ); theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_OnOilApplied ); if( !inv.IsItemHeld( usedOnItem ) ) { PauseOilBuffs( inv.IsItemSteelSwordUsableByPlayer( usedOnItem ) ); } return true; } public final function IsEquippedSwordUpgradedWithOil(steel : bool, optional oilName : name) : bool { var sword : SItemUniqueId; var i : int; var oils : array< W3Effect_Oil >; sword = GetEquippedSword( steel ); if( !inv.IsIdValid( sword ) ) { return false; } if( oilName == '' ) { return inv.ItemHasAnyActiveOilApplied( sword ); } oils = inv.GetOilsAppliedOnItem( sword ); for( i=0; i 0.1f; } function HandleMovement( deltaTime : float ) { if (WouldLikeToMove()) SetBehaviorVariable( 'playerWouldLikeToMove', 1.0f); else SetBehaviorVariable( 'playerWouldLikeToMove', 0.0f); super.HandleMovement( deltaTime ); } function BattleCryIsReady( ) : bool { var l_currentTime : float; l_currentTime = theGame.GetEngineTimeAsSeconds(); if( l_currentTime >= battlecry_timeForNext ) { return true; } return false; } function PlayBattleCry( _BattleCry : name , _Chance : float, optional _IgnoreDelay, ignoreRepeatCheck : bool ) { var l_randValue : float; var fact : int; fact = FactsQuerySum("force_stance_normal"); if( IsSwimming() || theGame.IsDialogOrCutscenePlaying() || IsInNonGameplayCutscene() || IsInGameplayScene() || theGame.IsCurrentlyPlayingNonGameplayScene() || theGame.IsFading() || theGame.IsBlackscreen() || FactsQuerySum("force_stance_normal") > 0 ) { return; } if ( !ignoreRepeatCheck ) { if( battlecry_lastTry == _BattleCry ) return; } battlecry_lastTry = _BattleCry; l_randValue = RandF(); if( l_randValue < _Chance && ( _IgnoreDelay || BattleCryIsReady() ) ) { thePlayer.PlayVoiceset( 90, _BattleCry ); battlecry_timeForNext = theGame.GetEngineTimeAsSeconds() + RandRangeF( battlecry_delayMax, battlecry_delayMin ); } } public final function OnWeatherChanged() { if( IsInInterior() || GetCurrentStateName() != 'Exploration' || theGame.IsDialogOrCutscenePlaying() || IsInNonGameplayCutscene() || IsInGameplayScene() || theGame.IsCurrentlyPlayingNonGameplayScene() || theGame.IsFading() || theGame.IsBlackscreen() || GetTimeSinceSpawned() < 60 ) { return; } AddTimer( 'CommentOnWeather', 1 ); } public final timer function CommentOnWeather( _Delta : float, _Id : int ) { var l_weather : name; var l_currentArea : EAreaName; var l_rand : float; l_weather = GetWeatherConditionName(); l_currentArea = theGame.GetCommonMapManager().GetCurrentArea(); switch ( l_weather ) { case 'WT_Clear': l_rand = RandF(); if( l_rand > 0.66f && !AreaIsCold() && theGame.envMgr.IsDay() ) { thePlayer.PlayVoiceset( 90, 'WeatherHot' ); } else if ( l_rand > 0.33f ) { thePlayer.PlayVoiceset( 90, 'WeatherClearingUp' ); } break; case 'WT_Rain_Storm': thePlayer.PlayVoiceset( 90, 'WeatherStormy' ); break; case 'WT_Light_Clouds': if( previousRainStrength < GetRainStrength() ) { thePlayer.PlayVoiceset( 90, 'WeatherLooksLikeRain' ); } else if( AreaIsCold() && previousWeather == 'WT_Clear' ) { thePlayer.PlayVoiceset( 90, 'WeatherCold' ); } break; case 'WT_Mid_Clouds': if( previousRainStrength < GetRainStrength() ) { thePlayer.PlayVoiceset( 90, 'WeatherRaining' ); } else if( AreaIsCold() && previousWeather == 'WT_Clear' ) { thePlayer.PlayVoiceset( 90, 'WeatherCold' ); } break; case 'WT_Mid_Clouds_Dark': if( previousWeather != 'WT_Heavy_Clouds' && previousWeather != 'WT_Heavy_Clouds_Dark' ) thePlayer.PlayVoiceset( 90, 'WeatherWindy' ); break; case 'WT_Heavy_Clouds': if( previousWeather != 'WT_Mid_Clouds_Dark' && previousWeather != 'WT_Heavy_Clouds_Dark' ) thePlayer.PlayVoiceset( 90, 'WeatherWindy' ); break; case 'WT_Heavy_Clouds_Dark': if( thePlayer.IsOnBoat() ) { thePlayer.PlayVoiceset( 90, 'WeatherSeaWillStorm' ); } else if( previousRainStrength < GetRainStrength() ) { thePlayer.PlayVoiceset( 90, 'WeatherLooksLikeRain' ); } else { thePlayer.PlayVoiceset( 90, 'WeatherWindy' ); } break; case 'WT_Snow': if( RandF() > 0.5f ) thePlayer.PlayVoiceset( 90, 'WeatherSnowy' ); else thePlayer.PlayVoiceset( 90, 'WeatherCold' ); break; } previousRainStrength = GetRainStrength(); previousWeather = l_weather; } function CanUpdateMovement() : bool { if ( rangedWeapon && GetBehaviorVariable( 'fullBodyAnimWeight' ) >= 1.f && rangedWeapon.GetCurrentStateName() != 'State_WeaponWait' ) return false; return true; } public function SetDefaultLocomotionController() { if( !defaultLocomotionController ) { defaultLocomotionController = new CR4LocomotionPlayerControllerScript in this; } ActionDirectControl( defaultLocomotionController ); } event OnPlayerTickTimer( deltaTime : float ) { var focusModeController : CFocusModeController; var cnt : int; super.OnPlayerTickTimer( deltaTime ); HandleMovement( deltaTime ); if ( playerAiming.GetCurrentStateName() == 'Aiming' ) { FindTarget(); FindNonActorTarget( false ); UpdateDisplayTarget(); UpdateLookAtTarget(); } else { if( playerTickTimerPhase == 0 ) { FindTarget(); } else if( playerTickTimerPhase == 1 ) { FindNonActorTarget( false ); } else if ( playerTickTimerPhase == 2 ) { UpdateDisplayTarget(); UpdateLookAtTarget(); } } playerTickTimerPhase = ( playerTickTimerPhase + 1 ) % 3; focusModeController = theGame.GetFocusModeController(); focusModeController.UpdateFocusInteractions( deltaTime ); cnt = (int)( effectManager.GetCriticalBuffsCount() > 0 ); SetBehaviorVariable('hasCriticalBuff', cnt); } event OnDeath( damageAction : W3DamageAction ) { super.OnDeath( damageAction ); RemoveTimer('RequestCriticalAnimStart'); EnableFindTarget( false ); BlockAllActions('Death', true); EnableHardLock( false ); theGame.CreateNoSaveLock( 'player_death', deathNoSaveLock, false, false ); theGame.SetDeathSaveLockId( deathNoSaveLock ); ClearHostileEnemiesList(); RemoveReactions(); SetPlayerCombatTarget(NULL); OnEnableAimingMode( false ); theGame.EnableFreeCamera( false ); } function OnRevived() { super.OnRevived(); BlockAllActions('Death', false); theGame.ReleaseNoSaveLock(deathNoSaveLock); this.RestartReactionsIfNeeded(); } public function CanStartTalk() : bool { if ( beingWarnedBy.Size() > 0 ) return false; return super.CanStartTalk(); } public function AddCounterTimeStamp(time : EngineTime) {counterTimestamps.PushBack(time);} public function CheckCounterSpamming(attacker : CActor) : bool { var counterWindowStartTime : EngineTime; var i, spamCounter : int; var reflexAction : bool; var testEngineTime : EngineTime; if(!attacker) return false; counterWindowStartTime = ((CNewNPC)attacker).GetCounterWindowStartTime(); spamCounter = 0; reflexAction = false; if ( counterWindowStartTime == testEngineTime ) { return false; } for(i = counterTimestamps.Size() - 1; i>=0; i-=1) { if(counterTimestamps[i] >= (counterWindowStartTime - EngineTimeFromFloat(0.4)) ) { spamCounter += 1; } else { counterTimestamps.Remove(counterTimestamps[i]); continue; } if(!reflexAction && (counterTimestamps[i] >= counterWindowStartTime)) reflexAction = true; } if(spamCounter == 1 && reflexAction) return true; return false; } protected function PerformCounterCheck(parryInfo: SParryInfo) : bool { var mult : float; var parryType : EParryType; var validCounter, useKnockdown : bool; var slideDistance, duration : float; var playerToTargetRot : EulerAngles; var zDifference, mutation8TriggerHP : float; var effectType : EEffectType; var repelType : EPlayerRepelType = PRT_Random; var params : SCustomEffectParams; var thisPos, attackerPos : Vector; var fistFightCheck, isMutation8 : bool; var fistFightCounter : bool; var attackerInventory : CInventoryComponent; var weaponId : SItemUniqueId; var weaponTags : array; var playerToAttackerVector : Vector; var tracePosStart : Vector; var tracePosEnd : Vector; var hitPos : Vector; var hitNormal : Vector; var min, max : SAbilityAttributeValue; var npc : CNewNPC; if(ShouldProcessTutorial('TutorialDodge') || ShouldProcessTutorial('TutorialCounter')) { theGame.RemoveTimeScale( theGame.GetTimescaleSource(ETS_TutorialFight) ); FactsRemove("tut_fight_slomo_ON"); } if ( !parryInfo.canBeParried || parryInfo.attacker.HasAbility( 'CannotBeCountered' ) ) return false; fistFightCheck = FistFightCheck( parryInfo.target, parryInfo.attacker, fistFightCounter ); if( ParryCounterCheck() && parryInfo.targetToAttackerAngleAbs < theGame.params.PARRY_HALF_ANGLE && fistFightCheck ) { validCounter = CheckCounterSpamming(parryInfo.attacker); if(validCounter) { if ( IsInCombatActionFriendly() ) RaiseEvent('CombatActionFriendlyEnd'); SetBehaviorVariable( 'parryType', ChooseParryTypeIndex( parryInfo ) ); SetBehaviorVariable( 'counter', (float)validCounter); SetBehaviorVariable( 'parryType', ChooseParryTypeIndex( parryInfo ) ); SetBehaviorVariable( 'counter', (float)validCounter); this.SetBehaviorVariable( 'combatActionType', (int)CAT_Parry ); if ( !fistFightCounter ) { attackerInventory = parryInfo.attacker.GetInventory(); weaponId = attackerInventory.GetItemFromSlot('r_weapon'); attackerInventory.GetItemTags( weaponId , weaponTags ); if( GetWitcherPlayer().IsMutationActive( EPMT_Mutation8 ) ) { isMutation8 = true; theGame.GetDefinitionsManager().GetAbilityAttributeValue( 'Mutation8', 'hp_perc_trigger', min, max ); mutation8TriggerHP = min.valueMultiplicative; } npc = (CNewNPC)parryInfo.attacker; if ( parryInfo.attacker.HasAbility('mon_gravehag') ) { repelType = PRT_Slash; parryInfo.attacker.AddEffectDefault(EET_CounterStrikeHit, this, 'ReflexParryPerformed'); } else if ( npc && !npc.IsHuman() && !npc.HasTag( 'dettlaff_vampire' ) ) { repelType = PRT_SideStepSlash; } else if ( weaponTags.Contains('spear2h') ) { repelType = PRT_SideStepSlash; parryInfo.attacker.AddEffectDefault(EET_CounterStrikeHit, this, "ReflexParryPerformed"); parryInfo.attacker.SignalGameplayEvent( 'SpearDestruction'); } else if( isMutation8 && npc && !npc.IsImmuneToMutation8Finisher() ) { repelType = PRT_RepelToFinisher; npc.AddEffectDefault( EET_CounterStrikeHit, this, "ReflexParryPerformed" ); SetTarget( npc, true ); PerformFinisher( 0.f, 0 ); } else { thisPos = this.GetWorldPosition(); attackerPos = parryInfo.attacker.GetWorldPosition(); playerToTargetRot = VecToRotation( thisPos - attackerPos ); zDifference = thisPos.Z - attackerPos.Z; if ( playerToTargetRot.Pitch < -5.f && zDifference > 0.35 ) { repelType = PRT_Kick; ragdollTarget = parryInfo.attacker; AddTimer( 'ApplyCounterRagdollTimer', 0.3 ); } else { useKnockdown = false; if ( CanUseSkill(S_Sword_s11) ) { if( GetSkillLevel(S_Sword_s11) > 1 && RandRangeF(3,0) < GetWitcherPlayer().GetStat(BCS_Focus) ) { duration = CalculateAttributeValue(GetSkillAttributeValue(S_Sword_s11, 'duration', false, true)); useKnockdown = true; } } else if ( parryInfo.attacker.IsHuman() ) { tracePosStart = parryInfo.attacker.GetWorldPosition(); tracePosStart.Z += 1.f; playerToAttackerVector = VecNormalize( parryInfo.attacker.GetWorldPosition() - parryInfo.target.GetWorldPosition() ); tracePosEnd = ( playerToAttackerVector * 0.75f ) + ( playerToAttackerVector * parryInfo.attacker.GetRadius() ) + parryInfo.attacker.GetWorldPosition(); tracePosEnd.Z += 1.f; if ( !theGame.GetWorld().StaticTrace( tracePosStart, tracePosEnd, hitPos, hitNormal, counterCollisionGroupNames ) ) { tracePosStart = tracePosEnd; tracePosEnd -= 3.f; if ( !theGame.GetWorld().StaticTrace( tracePosStart, tracePosEnd, hitPos, hitNormal, counterCollisionGroupNames ) ) useKnockdown = true; } } if(useKnockdown && (!parryInfo.attacker.IsImmuneToBuff(EET_HeavyKnockdown) || !parryInfo.attacker.IsImmuneToBuff(EET_Knockdown))) { if(!parryInfo.attacker.IsImmuneToBuff(EET_HeavyKnockdown)) { params.effectType = EET_HeavyKnockdown; } else { params.effectType = EET_Knockdown; } repelType = PRT_Kick; params.creator = this; params.sourceName = "ReflexParryPerformed"; params.duration = duration; parryInfo.attacker.AddEffectCustom(params); } else { parryInfo.attacker.AddEffectDefault(EET_CounterStrikeHit, this, "ReflexParryPerformed"); } } } parryInfo.attacker.GetInventory().PlayItemEffect(parryInfo.attackerWeaponId, 'counterattack'); if ( repelType == PRT_Random ) if ( RandRange(100) > 50 ) repelType = PRT_Bash; else repelType = PRT_Kick; this.SetBehaviorVariable( 'repelType', (int)repelType ); parryInfo.attacker.SetBehaviorVariable( 'repelType', (int)repelType ); } else { parryInfo.attacker.AddEffectDefault(EET_CounterStrikeHit, this, "ReflexParryPerformed"); } SetParryTarget ( parryInfo.attacker ); SetSlideTarget( parryInfo.attacker ); if ( !IsActorLockedToTarget() ) SetMoveTarget( parryInfo.attacker ); if ( RaiseForceEvent( 'PerformCounter' ) ) OnCombatActionStart(); SetCustomRotation( 'Counter', VecHeading( parryInfo.attacker.GetWorldPosition() - this.GetWorldPosition() ), 0.0f, 0.2f, false ); AddTimer( 'UpdateCounterRotation', 0.4f, true ); AddTimer( 'SetCounterRotation', 0.2f ); IncreaseUninterruptedHitsCount(); if(IsHeavyAttack(parryInfo.attackActionName)) mult = theGame.params.HEAVY_STRIKE_COST_MULTIPLIER; DrainStamina(ESAT_Counterattack, 0, 0, '', 0, mult); theGame.GetGamerProfile().IncStat(ES_CounterattackChain); } else { ResetUninterruptedHitsCount(); } return validCounter; } return false; } timer function UpdateCounterRotation( dt : float, id : int ) { UpdateCustomRotationHeading( 'Counter', VecHeading( parryTarget.GetWorldPosition() - this.GetWorldPosition() ) ); } timer function SetCounterRotation( dt : float, id : int ) { SetCustomRotation( 'Counter', VecHeading( parryTarget.GetWorldPosition() - this.GetWorldPosition() ), 360.f, 0.2f, false ); } private var parryTarget : CActor; private function SetParryTarget( t : CActor ) { parryTarget = t; } private var ragdollTarget : CActor; timer function ApplyCounterRagdollTimer( time : float , id : int) { var actor : CActor; actor = (CActor)ragdollTarget; if(actor) { actor.AddEffectDefault(EET_HeavyKnockdown, this, 'ReflexParryPerformed'); } } public function EnableMode( mode : EPlayerMode, enable : bool ) { playerMode.EnableMode( mode, enable ); } public function GetPlayerMode() : W3PlayerMode { return playerMode; } private function GetClosestIncomingAttacker() : CActor { var i, size : int; var attackerToPlayerDistances : array< float >; var closestAttackerIndex : int; var incomingAttackers : array; if(playerMode && playerMode.combatDataComponent) { if ( incomingAttackers.Size() <= 0 ) this.playerMode.combatDataComponent.GetTicketSourceOwners( incomingAttackers, 'TICKET_Charge' ); if ( incomingAttackers.Size() <= 0 ) this.playerMode.combatDataComponent.GetTicketSourceOwners( incomingAttackers, 'TICKET_Melee' ); if ( incomingAttackers.Size() <= 0 ) this.playerMode.combatDataComponent.GetTicketSourceOwners( incomingAttackers, 'TICKET_Range' ); } size = incomingAttackers.Size(); attackerToPlayerDistances.Resize( size ); if ( size > 0 ) { for ( i = incomingAttackers.Size()-1; i >= 0; i -= 1) { if ( !IsEnemyVisible( incomingAttackers[i] ) ) { incomingAttackers.EraseFast( i ); } } } if ( size > 0 ) { for ( i = 0; i < size; i += 1 ) { attackerToPlayerDistances[i] = VecDistance( incomingAttackers[i].GetWorldPosition(), this.GetWorldPosition() ); } closestAttackerIndex = ArrayFindMinF( attackerToPlayerDistances ); return incomingAttackers[ closestAttackerIndex ]; } else { return NULL; } } timer function CombatCheck( time : float , id : int) { var i : int; var strLevel, temp : string; var enemies : array; UpdateFinishableEnemyList(); FindMoveTarget(); playerMode.UpdateCombatMode(); if( GetPlayerCombatStance() == PCS_Guarded ) { if( GetTarget().GetHealthPercents() > 0.25f ) { PlayBattleCry( 'BattleCryTaunt', 0.2f ); } else { if( GetTarget().IsHuman() ) PlayBattleCry( 'BattleCryHumansEnd', 0.3f ); else PlayBattleCry( 'BattleCryMonstersEnd', 0.3f ); } } if(IsThreatened() && ShouldProcessTutorial('TutorialMonsterThreatLevels') && FactsQuerySum("q001_nightmare_ended") > 0) { GetEnemiesInRange(enemies); for(i=0; i 0) cnt += 1; if(FactsQuerySum("statistics_cerberus_petard") > 0) cnt += 1; if(FactsQuerySum("statistics_cerberus_bolt") > 0) cnt += 1; if(FactsQuerySum("statistics_cerberus_fists") > 0) cnt += 1; if(FactsQuerySum("statistics_cerberus_melee") > 0) cnt += 1; if(FactsQuerySum("statistics_cerberus_environment") > 0) cnt += 1; FactsRemove("statistics_cerberus_sign"); FactsRemove("statistics_cerberus_petard"); FactsRemove("statistics_cerberus_bolt"); FactsRemove("statistics_cerberus_fists"); FactsRemove("statistics_cerberus_melee"); FactsRemove("statistics_cerberus_environment"); if(cnt >= 3) theGame.GetGamerProfile().AddAchievement(EA_Cerberus); if(theGame.GetTutorialSystem() && FactsQuerySum("TutorialShowSilver") > 0) { FactsAdd("tut_show_silver_sword", 1); FactsRemove("TutorialShowSilver"); } this.SetBehaviorVariable('isInCombatForOverlay',0.f); GoToExplorationIfNeeded(); theGame.ReleaseNoSaveLock( noSaveLock ); LogChannel( 'OnCombatFinished', "OnCombatFinished: ReleaseNoSaveLock" ); SetFailedFundamentalsFirstAchievementCondition(false); UnblockAction(EIAB_OpenMeditation, 'InCombat'); UnblockAction(EIAB_HighlightObjective, 'InCombat'); } event OnReactToBeingHit( damageAction : W3DamageAction ) { var weaponType : EPlayerWeapon; super.OnReactToBeingHit(damageAction); IncHitCounter(); if ( IsInCombat() && damageAction.attacker && damageAction.attacker == GetTarget() && !( this.IsUsingVehicle() && this.IsOnBoat() ) ) { weaponType = GetMostConvenientMeleeWeapon( GetTarget() ); if ( weaponType != PW_Fists && weaponType != PW_None && weaponType != this.GetCurrentMeleeWeaponType() ) OnEquipMeleeWeapon( weaponType, false ); } } public function ReceivedCombatDamage() { receivedDamageInCombat = true; } timer function UninterruptedHitsResetOnIdle(dt : float, id : int) { ResetUninterruptedHitsCount(); } public function ResetUninterruptedHitsCount() { uninterruptedHitsCount = 0; LogUnitAtt("Uninterrupted attacks reset!!!!"); } public function IncreaseUninterruptedHitsCount() { uninterruptedHitsCount += 1; LogUnitAtt("Uninterrupted attacks count increased to " + uninterruptedHitsCount); if(uninterruptedHitsCount == 4) AddTimer('StartUninterruptedBlurr', 1, false); AddTimer('UninterruptedHitsResetOnIdle', 4.f, false); } timer function StartUninterruptedBlurr(dt : float, id : int) { var changed : bool; var movingAgent : CMovingPhysicalAgentComponent; var target : CActor; if(uninterruptedHitsCount < 4) { LogUnitAtt("Stopping camera effect"); thePlayer.StopEffect(uninterruptedHitsCurrentCameraEffect); uninterruptedHitsCurrentCameraEffect = ''; uninterruptedHitsCameraStarted = false; RemoveTimer('StartUninterruptedBlurr'); } else { target = GetTarget(); if( target ) { movingAgent = ( (CMovingPhysicalAgentComponent) (target.GetMovingAgentComponent()) ); } if(!uninterruptedHitsCameraStarted) { LogUnitAtt("Starting camera effect"); AddTimer('StartUninterruptedBlurr', 0.001, true); if(movingAgent && movingAgent.GetCapsuleHeight() > 2) uninterruptedHitsCurrentCameraEffect = theGame.params.UNINTERRUPTED_HITS_CAMERA_EFFECT_BIG_ENEMY; else uninterruptedHitsCurrentCameraEffect = theGame.params.UNINTERRUPTED_HITS_CAMERA_EFFECT_REGULAR_ENEMY; thePlayer.PlayEffect(uninterruptedHitsCurrentCameraEffect); uninterruptedHitsCameraStarted = true; } else { changed = false; if(movingAgent && movingAgent.GetCapsuleHeight() > 2 && uninterruptedHitsCurrentCameraEffect != theGame.params.UNINTERRUPTED_HITS_CAMERA_EFFECT_BIG_ENEMY) changed = true; else if(!movingAgent || ( movingAgent.GetCapsuleHeight() <= 2 && uninterruptedHitsCurrentCameraEffect != theGame.params.UNINTERRUPTED_HITS_CAMERA_EFFECT_REGULAR_ENEMY) ) changed = true; if(changed) { thePlayer.StopEffect(uninterruptedHitsCurrentCameraEffect); if(uninterruptedHitsCurrentCameraEffect == theGame.params.UNINTERRUPTED_HITS_CAMERA_EFFECT_BIG_ENEMY) uninterruptedHitsCurrentCameraEffect = theGame.params.UNINTERRUPTED_HITS_CAMERA_EFFECT_REGULAR_ENEMY; else uninterruptedHitsCurrentCameraEffect = theGame.params.UNINTERRUPTED_HITS_CAMERA_EFFECT_BIG_ENEMY; thePlayer.PlayEffect(uninterruptedHitsCurrentCameraEffect); } } } } private var playerActionEventListeners : array; private var playerActionEventBlockingListeners : array; private function PlayerActionBlockGameplayActions( sourceName : name, lock : bool, isFromPlace : bool ) { if ( lock ) { thePlayer.BlockAction( EIAB_Signs, sourceName, false, false, isFromPlace ); thePlayer.BlockAction( EIAB_DrawWeapon, sourceName, false, false, isFromPlace ); thePlayer.BlockAction( EIAB_CallHorse, sourceName, false, false, isFromPlace ); thePlayer.BlockAction( EIAB_FastTravel, sourceName, false, false, isFromPlace ); thePlayer.BlockAction( EIAB_Fists, sourceName, false, false, isFromPlace ); thePlayer.BlockAction( EIAB_InteractionAction, sourceName, false, false, isFromPlace ); thePlayer.DisableCombatState(); } else { thePlayer.UnblockAction( EIAB_Signs, sourceName ); thePlayer.UnblockAction( EIAB_DrawWeapon, sourceName ); thePlayer.UnblockAction( EIAB_CallHorse, sourceName ); thePlayer.UnblockAction( EIAB_FastTravel, sourceName ); thePlayer.UnblockAction( EIAB_Fists, sourceName ); thePlayer.UnblockAction( EIAB_InteractionAction, sourceName ); } } public function GetPlayerActionEventListeners() : array { return playerActionEventListeners; } public function RegisterForPlayerAction( listener : CGameplayEntity, isLockedByPlace : bool ) { if ( !playerActionEventListeners.Contains( listener ) ) { playerActionEventListeners.PushBack( listener ); } if ( listener.ShouldBlockGameplayActionsOnInteraction() ) { if ( !playerActionEventBlockingListeners.Contains( listener ) ) { playerActionEventBlockingListeners.PushBack( listener ); } if ( playerActionEventBlockingListeners.Size() == 1 ) { PlayerActionBlockGameplayActions( 'PlayerAction', true, isLockedByPlace ); } } } public function UnregisterForPlayerAction( listener : CGameplayEntity, isLockedByPlace : bool ) { playerActionEventListeners.Remove( listener ); playerActionEventBlockingListeners.Remove( listener ); if ( playerActionEventBlockingListeners.Size() == 0 ) { PlayerActionBlockGameplayActions( 'PlayerAction', false, isLockedByPlace ); } } event OnPlayerActionStart() { thePlayer.SetBehaviorVariable( 'inJumpState', 1.f ); } event OnPlayerActionEnd() { var i : int; for ( i = playerActionEventListeners.Size() - 1; i >= 0; i-=1 ) { playerActionEventListeners[i].OnPlayerActionEnd(); } currentCustomAction = PEA_None; thePlayer.SetBehaviorVariable( 'inJumpState', 0.f ); } event OnPlayerActionStartFinished() { var i : int; for ( i = playerActionEventListeners.Size() - 1; i >= 0; i-=1 ) { playerActionEventListeners[i].OnPlayerActionStartFinished(); } } function PlayerStartAction( playerAction : EPlayerExplorationAction, optional animName : name ) : bool { if ( playerAction == PEA_SlotAnimation && !IsNameValid(animName) ) { return false; } SetBehaviorVariable( 'playerStopAction', 0.0); SetBehaviorVariable( 'playerExplorationAction', (float)(int)playerAction); if ( RaiseForceEvent('playerActionStart') ) { currentCustomAction = playerAction; if ( playerAction == PEA_SlotAnimation ) { playerActionSlotAnimName = animName; AddTimer('PlayActionAnimWorkaround',0,false); } return true; } return false; } private var playerActionSlotAnimName : name; timer function PlayActionAnimWorkaround( dt : float , id : int) { this.ActionPlaySlotAnimationAsync('PLAYER_ACTION_SLOT',playerActionSlotAnimName, 0.2, 0.2, true); } function PlayerStopAction( playerAction : EPlayerExplorationAction ) { SetBehaviorVariable( 'playerExplorationAction', (float)(int)playerAction); SetBehaviorVariable( 'playerStopAction', 1.0); currentCustomAction = PEA_None; } function GetPlayerAction() : EPlayerExplorationAction { return currentCustomAction; } function MedallionPing() { var currTime : float = theGame.GetEngineTimeAsSeconds(); if ( lastMedallionEffect < currTime ) { lastMedallionEffect = theGame.GetEngineTimeAsSeconds() + medallion.effectDuration; medallion.TriggerMedallionFX(); } } public function CanPerformPlayerAction(optional alsoOutsideExplorationState : bool) : bool { if(!alsoOutsideExplorationState && GetCurrentStateName() != 'Exploration') return false; if( isInAir || (substateManager && !substateManager.CanInteract()) || IsInCombatAction() || GetCriticalBuffsCount() > 0) return false; return true; } event OnItemGiven(data : SItemChangedData) { var keyName : name; var i : int; var hud : CR4ScriptedHud; var message : string; var inve : CInventoryComponent; if(data.informGui) { hud = (CR4ScriptedHud)theGame.GetHud(); if(hud) { message = GetLocStringByKeyExt("panel_common_item_received") + ": " + GetLocStringByKeyExt(inv.GetItemLocalizedNameByUniqueID(data.ids[0])); if(data.quantity > 1) message += " x" + data.quantity; hud.HudConsoleMsg(message); } } inve = GetInventory(); if(inve.ItemHasTag(data.ids[0], 'key')) { keyName = inve.GetItemName(data.ids[0]); for(i=nearbyLockedContainersNoKey.Size()-1; i>=0; i-=1) { if(nearbyLockedContainersNoKey[i].GetKeyName() == keyName && nearbyLockedContainersNoKey[i].IsEnabled()) { nearbyLockedContainersNoKey[i].UpdateComponents("Unlock"); nearbyLockedContainersNoKey.Remove(nearbyLockedContainersNoKey[i]); } } } if(inve.IsItemAlchemyItem(data.ids[0])) { UpgradeAlchemyItem(data.ids[0], CanUseSkill(S_Perk_08)); } if(inve.ItemHasTag(data.ids[0], theGame.params.TAG_OFIR_SET)) CheckOfirSetAchievement(); } private final function CheckOfirSetAchievement() { var hasArmor, hasBoots, hasGloves, hasPants, hasSword, hasSaddle, hasBag, hasBlinders : bool; CheckOfirItems(GetInventory(), hasArmor, hasBoots, hasGloves, hasPants, hasSword, hasSaddle, hasBag, hasBlinders); CheckOfirItems(GetWitcherPlayer().GetHorseManager().GetInventoryComponent(), hasArmor, hasBoots, hasGloves, hasPants, hasSword, hasSaddle, hasBag, hasBlinders); if(hasArmor && hasBoots && hasGloves && hasPants && hasSword && hasSaddle && hasBag && hasBlinders) theGame.GetGamerProfile().AddAchievement(EA_LatestFashion); } private final function CheckOfirItems(inv : CInventoryComponent, out hasArmor : bool, out hasBoots : bool, out hasGloves : bool, out hasPants : bool, out hasSword : bool, out hasSaddle : bool, out hasBag : bool, out hasBlinders : bool) { var ofirs : array; var i : int; ofirs = inv.GetItemsByTag(theGame.params.TAG_OFIR_SET); for(i=0; i; inv.GetAllItems(items); dm = theGame.GetDefinitionsManager(); for(i=0; i; var min, max : SAbilityAttributeValue; if(!inv.IsItemAlchemyItem(itemID)) return; currLevel = (int)CalculateAttributeValue(inv.GetItemAttributeValue(itemID, 'level')); if(currLevel == 3 || currLevel == 2 || currLevel < 2 || currLevel > 3) return; currAbilities = inv.GetItemAbilitiesWithAttribute(itemID, 'level', currLevel); inv.GetItemContainedAbilities(itemID, abs); dm = theGame.GetDefinitionsManager(); for(j=0; j> on item <<" + inv.GetItemName(itemID) + ">> !!!"); } else { for(j=0; j 0 ) angles = VecToRotation( VecFromHeading( customOrientationInfoStack[ customOrientationInfoStack.Size() - 1 ].customHeading ) ); else angles = VecToRotation( GetHeadingVector() ); dir = RotForward( angles ); lookAtTarget = dir * 30.f + this.GetWorldPosition(); lookAtTarget.Z += 1.6f; lookAtActive = 1.0f; } else if ( localOrientationTarget == OT_Camera ) { headBoneIdx = GetHeadBoneIndex(); if ( headBoneIdx >= 0 ) { lookAtTarget = MatrixGetTranslation( GetBoneWorldMatrixByIndex( headBoneIdx ) ); } else { lookAtTarget = GetWorldPosition(); lookAtTarget.Z += 1.6f; } lookAtTarget += theCamera.GetCameraDirection() * 100.f; lookAtActive = 1.0f; } else if ( localOrientationTarget == OT_CameraOffset ) { dir = theCamera.GetCameraDirection(); angles = VecToRotation( dir ); angles.Pitch = -angles.Pitch + oTCameraPitchOffset; angles.Yaw -= oTCameraOffset; dir = RotForward( angles ); lookAtTarget = dir * 30.f + this.GetWorldPosition(); lookAtTarget.Z += 1.6f; lookAtActive = 1.0f; } else if ( localOrientationTarget == OT_Actor ) { if ( IsInCombatAction() ) { if ( ( ( ( W3PlayerWitcher )this ).GetCurrentlyCastSign() != ST_None && GetBehaviorVariable( 'combatActionType' ) == (int)CAT_CastSign ) || GetBehaviorVariable( 'combatActionType' ) == (int)CAT_ItemThrow ) useTorsoBone = true; } if ( rangedWeapon && rangedWeapon.GetCurrentStateName() != 'State_WeaponWait' ) useTorsoBone = true; if ( tempLookAtTarget && (CActor)(tempLookAtTarget) ) { lookAtTarget = ProcessLookAtTargetPosition( tempLookAtTarget, useTorsoBone ); lookAtActive = 1.0f; } if ( GetDisplayTarget() && IsDisplayTargetTargetable() ) { lookAtTarget = ProcessLookAtTargetPosition( GetDisplayTarget(), useTorsoBone ); lookAtActive = 1.0f; } else { if ( slideTarget ) { lookAtTarget = ProcessLookAtTargetPosition( slideTarget, useTorsoBone ); } else { target = GetTarget(); if ( target ) { lookAtTarget = ProcessLookAtTargetPosition( target, useTorsoBone ); } } lookAtActive = 1.0f; } if ( !slideTarget && !IsUsingVehicle() ) { playerRot = GetWorldRotation(); lookAtTarget = GetWorldPosition() + VecFromHeading( playerRot.Yaw ) * 100.0f; lookAtActive = 0.0f; } if ( useTorsoBone ) lookAtTarget.Z += 0.2f; } GetVisualDebug().AddSphere('lookAtTarget', 1.f, lookAtTarget, true, Color(255,0,0), 3.0f ); SetLookAtPosition( lookAtTarget ); UpdateLookAtVariables( lookAtActive, lookAtTarget ); } private function ProcessLookAtTargetPosition( ent : CGameplayEntity, useTorsoBone : bool ) : Vector { var boneIdx : int; var actor : CActor; var lookAtTarget : Vector; var tempComponent : CDrawableComponent; var box : Box; var entityHeight : float; var entityPos : Vector; var predictedPos : Vector; var z : float; var entMat : Matrix; actor = (CActor)(ent); entityPos = ent.GetWorldPosition(); lookAtTarget = entityPos; if ( actor ) { if ( useTorsoBone ) boneIdx = actor.GetTorsoBoneIndex(); else boneIdx = actor.GetHeadBoneIndex(); } else boneIdx = -1; if ( !( ent.aimVector.X == 0 && ent.aimVector.Y == 0 && ent.aimVector.Z == 0 ) ) { entMat = ent.GetLocalToWorld(); lookAtTarget = VecTransform( entMat, ent.aimVector ); } else if ( boneIdx >= 0 ) { lookAtTarget = MatrixGetTranslation( ent.GetBoneWorldMatrixByIndex( boneIdx ) ); } else { if ( actor ) lookAtTarget.Z += ( ((CMovingPhysicalAgentComponent)actor.GetMovingAgentComponent()).GetCapsuleHeight() * 0.5 ); else { tempComponent = (CDrawableComponent)( ent.GetComponentByClassName('CDrawableComponent') ); if ( tempComponent.GetObjectBoundingVolume( box ) ) { entityHeight = box.Max.Z - box.Min.Z; lookAtTarget = lookAtTarget + Vector(0,0,entityHeight/2); } } } z = ((CMovingPhysicalAgentComponent)actor.GetMovingAgentComponent()).GetCapsuleHeight(); if ( actor ) { if ( PredictLookAtTargetPosition( actor, lookAtTarget.Z - entityPos.Z, predictedPos ) ) lookAtTarget = predictedPos; } return lookAtTarget; } private function PredictLookAtTargetPosition( targetActor : CActor, zOffSet : float, out predictedPos : Vector ) : bool { var virtualPos : Vector; var i : int; var dist : float; var deltaTime : float; var projSpeed : float; var projSpeedInt : Vector; var projAngle : float; var e3Hack : bool; var currentTimeInCurve : float; e3Hack = false; if ( rangedWeapon && rangedWeapon.GetDeployedEntity() && ( rangedWeapon.GetCurrentStateName() == 'State_WeaponAim' || rangedWeapon.GetCurrentStateName() == 'State_WeaponShoot' ) ) { projSpeed = rangedWeapon.GetDeployedEntity().projSpeed; virtualPos = targetActor.GetWorldPosition(); if ( e3Hack && targetActor.HasTag( 'e3_griffin' ) ) { for ( i = 0; i < 10; i += 1 ) { dist = VecDistance( rangedWeapon.GetDeployedEntity().GetWorldPosition(), virtualPos ); deltaTime = dist/projSpeed; virtualPos = targetActor.PredictWorldPosition( deltaTime ); } } else return false; virtualPos.Z += zOffSet; predictedPos = virtualPos; GetVisualDebug().AddSphere('CrossbowPredictedPos', 1.0f, virtualPos , true, Color(255,50,50), 5.0f ); return true; } return false; } public function SetLookAtPosition( vec : Vector ) { lookAtPosition = vec; } public function GetLookAtPosition() : Vector { return lookAtPosition; } event OnBlockingSceneEnded( optional output : CStorySceneOutput) { SetImmortalityMode( AIM_None, AIC_SyncedAnim ); super.OnBlockingSceneEnded(output); } function GetCurrentMeleeWeaponName() : name { return weaponHolster.GetCurrentMeleeWeaponName(); } public function GetCurrentMeleeWeaponType() : EPlayerWeapon { return weaponHolster.GetCurrentMeleeWeapon(); } public function OnMeleeForceHolster(ignoreActionLock : bool) { weaponHolster.HolsterWeapon(ignoreActionLock, true); } event OnForcedHolsterWeapon() { weaponHolster.OnForcedHolsterWeapon(); } event OnEquippedItem( category : name, slotName : name ) { var weaponType : EPlayerWeapon; if ( slotName == 'r_weapon' ) { switch ( category ) { case 'None' : weaponType = PW_None; break; case 'fist' : weaponType = PW_Fists; break; case 'steelsword' : weaponType = PW_Steel; break; case 'silversword' : weaponType = PW_Silver; break; default : return true; } weaponHolster.OnEquippedMeleeWeapon( weaponType ); } } private var isHoldingDeadlySword : bool; public function ProcessIsHoldingDeadlySword() { isHoldingDeadlySword = IsDeadlySwordHeld(); } public function IsHoldingDeadlySword() : bool { return isHoldingDeadlySword; } event OnHolsteredItem( category : name, slotName : name ) { var weaponType : EPlayerWeapon; if ( slotName == 'r_weapon' && (category == 'steelsword' || category == 'silversword') ) { if( category == 'silversword' ) { ManageAerondightBuff( false ); } GetBuff( EET_LynxSetBonus ).Pause( 'drawing weapon' ); PauseOilBuffs( category == 'steelsword' ); } if ( slotName == 'r_weapon' ) { weaponType = weaponHolster.GetCurrentMeleeWeapon(); switch ( category ) { case 'fist' : if ( weaponType == PW_Fists ) weaponHolster.OnEquippedMeleeWeapon( PW_None ); return true; case 'steelsword' : if ( weaponType == PW_Steel ) weaponHolster.OnEquippedMeleeWeapon( PW_None ); return true; case 'silversword' : if ( weaponType == PW_Silver ) weaponHolster.OnEquippedMeleeWeapon( PW_None ); return true; default : return true; } } } event OnEquipMeleeWeapon( weaponType : EPlayerWeapon, ignoreActionLock : bool, optional sheatheIfAlreadyEquipped : bool ) { RemoveTimer( 'DelayedSheathSword' ); weaponHolster.OnEquipMeleeWeapon( weaponType, ignoreActionLock, sheatheIfAlreadyEquipped ); m_RefreshWeaponFXType = true; } event OnHolsterLeftHandItem() { weaponHolster.OnHolsterLeftHandItem(); } timer function DelayedTryToReequipWeapon( dt: float, id : int ) { var weaponType : EPlayerWeapon; if( IsInCombat() && GetTarget() ) { weaponType = GetMostConvenientMeleeWeapon( GetTarget() ); if ( weaponType == PW_Steel || weaponType == PW_Silver ) weaponHolster.OnEquipMeleeWeapon( weaponType, false ); } } timer function DelayedSheathSword( dt: float, id : int ) { if ( !IsCombatMusicEnabled() ) { if ( IsInCombatAction() || !IsActionAllowed( EIAB_DrawWeapon ) ) { LogChannel( 'OnCombatFinished', "DelayedSheathSword: Sheath pushed to buffer" ); PushCombatActionOnBuffer(EBAT_Sheathe_Sword,BS_Pressed); } else { LogChannel( 'OnCombatFinished', "DelayedSheathSword: Sheath successful" ); OnEquipMeleeWeapon( PW_None, false ); } } } protected function ShouldAutoSheathSwordInstantly() : bool { var enemies : array; var i : int; GetEnemiesInRange( enemies ); for ( i = 0; i < enemies.Size(); i += 1 ) { if ( IsThreat( enemies[i] ) && VecDistance( enemies[i].GetWorldPosition(), this.GetWorldPosition() ) <= findMoveTargetDist ) { return false; } } return true; } public function PrepareToAttack( optional target : CActor, optional action : EBufferActionType ) { var weaponType : EPlayerWeapon; if( IsInAir() || !GetBIsCombatActionAllowed() ) { return ; } if( !target ) { target = (CActor)displayTarget; } if( !target && IsCombatMusicEnabled() ) { target = moveTarget; } if( !target ) { if ( this.GetCurrentStateName() == 'Exploration' ) { SetCombatActionHeading( ProcessCombatActionHeading( action ) ); thePlayer.CanAttackWhenNotInCombat( action, false, target ); } } weaponHolster.TryToPrepareMeleeWeaponToAttack(); { weaponType = GetCurrentMeleeWeaponType(); if ( weaponType == PW_None ) { weaponType = GetMostConvenientMeleeWeapon( target ); } if( !OnStateCanGoToCombat() ) { return; } GoToCombat( weaponType ); } } public function DisplayCannotAttackMessage( actor : CActor ) : bool { if ( actor && ( actor.GetMovingAgentComponent().GetName() == "child_base" || ((CNewNPC)actor).GetNPCType() == ENGT_Quest ) ) { DisplayHudMessage(GetLocStringByKeyExt("panel_hud_message_cant_attack_this_target")); return true; } return false; } public function GetMostConvenientMeleeWeapon( targetToDrawAgainst : CActor, optional ignoreActionLock : bool ) : EPlayerWeapon { return weaponHolster.GetMostConvenientMeleeWeapon( targetToDrawAgainst, ignoreActionLock ); } private var reevaluateCurrentWeapon : bool; event OnTargetWeaponDrawn() { var weaponType : EPlayerWeapon = this.GetCurrentMeleeWeaponType(); if ( weaponType == PW_Fists ) reevaluateCurrentWeapon = true; } public function GoToCombatIfNeeded( optional enemy : CActor ) : bool { var weaponType : EPlayerWeapon; var target : CActor; if( !enemy && IsInCombat() ) { target = GetTarget(); if ( target ) enemy = target; else enemy = moveTarget; } if( !ShouldGoToCombat( enemy ) ) { return false; } weaponType = this.GetCurrentMeleeWeaponType(); if ( weaponType == PW_None || ( reevaluateCurrentWeapon && weaponType == PW_Fists ) || ( !IsInCombat() && weaponHolster.IsOnTheMiddleOfHolstering() ) ) { weaponType = weaponHolster.GetMostConvenientMeleeWeapon( enemy ); reevaluateCurrentWeapon = false; } GoToCombat( weaponType ); return true; } public function GoToCombatIfWanted( ) : bool { var weaponType : EPlayerWeapon; var target : CActor; var enemy : CActor; if( !IsInCombat() ) { return false; } target = GetTarget(); if ( target ) enemy = target; else enemy = moveTarget; weaponType = this.GetCurrentMeleeWeaponType(); if ( weaponType == PW_None || ( !IsInCombat() && weaponHolster.IsOnTheMiddleOfHolstering() ) ) { weaponType = weaponHolster.GetMostConvenientMeleeWeapon( enemy ); } GoToCombat( weaponType ); return true; } public function GoToExplorationIfNeeded() : bool { if( ! IsInCombatState() ) { return false; } if( !ShouldGoToExploration() ) { return false; } weaponHolster.EndedCombat(); GotoState( 'Exploration' ); return true; } event OnStateCanGoToCombat() { return false; } event OnStateCanUpdateExplorationSubstates() { return false; } private function ShouldGoToCombat( optional enemy : CActor ) : bool { var currentStateName : name; if( !OnStateCanGoToCombat() ) { return false; } currentStateName = GetCurrentStateName(); if( currentStateName == 'AimThrow' ) { return false; } if( currentStateName == 'Swimming' ) { return false; } if( currentStateName == 'TraverseExploration' ) { return false; } if ( !enemy ) { return playerMode.combatMode; } return true; } private function ShouldGoToExploration() : bool { if ( IsInCombat() ) { return false; } if ( rangedWeapon && rangedWeapon.GetCurrentStateName() != 'State_WeaponWait' ) { return false; } if( IsFistFightMinigameEnabled() ) { return false; } if( IsKnockedUnconscious() ) { return false; } if( IsInCombatAction() ) { return false; } if( GetCriticalBuffsCount() > 0 ) { return false; } return true; } private function GoToCombat( weaponType : EPlayerWeapon, optional initialAction : EInitialAction ) { switch( weaponType ) { case PW_Silver: ((W3PlayerWitcherStateCombatSilver) GetState('CombatSilver')).SetupState( initialAction ); GoToStateIfNew( 'CombatSilver' ); break; case PW_Steel: ((W3PlayerWitcherStateCombatSteel) GetState('CombatSteel')).SetupState( initialAction ); GoToStateIfNew( 'CombatSteel' ); break; case PW_Fists: case PW_None: default : ((W3PlayerWitcherStateCombatFists) GetState('CombatFists')).SetupState( initialAction ); GoToStateIfNew( 'CombatFists' ); break; } } public function GoToStateIfNew( newState : name, optional keepStack : bool, optional forceEvents : bool ) { if( newState != GetCurrentStateName() ) { GotoState( newState, keepStack, forceEvents ); } } public function GotoState( newState : name, optional keepStack : bool, optional forceEvents : bool ) { super.GotoState( newState, keepStack, forceEvents ); } public function IsThisACombatSuperState( stateName : name ) : bool { return stateName == 'Combat' || stateName == 'CombatSteel' || stateName == 'CombatSilver' || stateName == 'CombatFists'; } public function GetWeaponHolster() : WeaponHolster { return weaponHolster; } public function AbortSign() { var playerWitcher : W3PlayerWitcher; var sign : W3SignEntity; playerWitcher = (W3PlayerWitcher)this; if(playerWitcher) { sign = (W3SignEntity)playerWitcher.GetCurrentSignEntity(); if (sign) { sign.OnSignAborted(); } } } protected var disableActionBlend : bool; event OnAnimEvent_DisallowHitAnim( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { if ( animEventType == AET_DurationEnd ) { if ( ( BufferCombatAction == EBAT_Dodge || BufferCombatAction == EBAT_Roll ) && IsInCombatAction() && GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Attack ) { ( (CR4Player)this ).ProcessCombatActionBuffer(); disableActionBlend = true; } } else if ( IsInCombatAction() && GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Dodge && animEventType == AET_DurationStart ) { disableActionBlend = false; } super.OnAnimEvent_DisallowHitAnim( animEventName, animEventType, animInfo ); } event OnAnimEvent_FadeOut( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { theGame.FadeOutAsync( 0.2, Color( 0, 0, 0, 1 ) ); } event OnAnimEvent_FadeIn( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { theGame.FadeInAsync( 0.4 ); } event OnAnimEvent_BloodTrailForced( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { var bloodTrailParam : CBloodTrailEffect; var weaponId : SItemUniqueId; if ( isInFinisher ) { bloodTrailParam = (CBloodTrailEffect)(GetFinisherVictim()).GetGameplayEntityParam( 'CBloodTrailEffect' ); weaponId = this.inv.GetItemFromSlot('r_weapon'); if ( bloodTrailParam ) thePlayer.inv.PlayItemEffect( weaponId, bloodTrailParam.GetEffectName() ); } } event OnAnimEvent_SlowMo( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { if ( isInFinisher && DisableManualCameraControlStackHasSource( 'Finisher' ) ) { if( animEventType != AET_DurationEnd ) theGame.SetTimeScale( 0.1f, 'AnimEventSlomoMo', 1000, true ); else theGame.RemoveTimeScale( 'AnimEventSlomoMo' ); } } event OnAnimEvent_PlayFinisherBlood( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { if ( isInFinisher ) { SpawnFinisherBlood(); } } event OnAnimEvent_OnWeaponDrawReady( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { weaponHolster.OnWeaponDrawReady(); } event OnAnimEvent_OnWeaponHolsterReady( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { weaponHolster.OnWeaponHolsterReady(); } event OnAnimEvent_ThrowHoldTest( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { var thrownEntity : CThrowable; thrownEntity = (CThrowable)EntityHandleGet( thrownEntityHandle ); if( IsThrowHold() ) { SetBehaviorVariable( 'throwStage', (int)TS_Loop ); PushState( 'AimThrow' ); thrownEntity.StartAiming(); } else { BombThrowRelease(); SetCombatIdleStance( 1.f ); } } event OnAnimEvent_AllowTempLookAt( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { if( animEventType == AET_DurationStart ) SetTempLookAtTarget( slideTarget ); else if( animEventType == AET_DurationEnd ) SetTempLookAtTarget( NULL ); } protected var slideNPC : CNewNPC; protected var minSlideDistance : float; protected var maxSlideDistance : float; protected var slideTicket : SMovementAdjustmentRequestTicket; event OnAnimEvent_SlideToTarget( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { var movementAdjustor : CMovementAdjustor; if( animEventType == AET_DurationStart ) { slideNPC = (CNewNPC)slideTarget; } if( !slideNPC ) { return false; } if( animEventType == AET_DurationStart && slideNPC.GetGameplayVisibility() ) { movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor(); slideTicket = movementAdjustor.GetRequest( 'SlideToTarget' ); movementAdjustor.CancelByName( 'SlideToTarget' ); slideTicket = movementAdjustor.CreateNewRequest( 'SlideToTarget' ); movementAdjustor.BindToEventAnimInfo( slideTicket, animInfo ); movementAdjustor.MaxLocationAdjustmentSpeed( slideTicket, 1000000 ); movementAdjustor.ScaleAnimation( slideTicket ); minSlideDistance = ((CMovingPhysicalAgentComponent)this.GetMovingAgentComponent()).GetCapsuleRadius()+((CMovingPhysicalAgentComponent)slideNPC.GetMovingAgentComponent()).GetCapsuleRadius(); if( IsInCombatFist() ) { maxSlideDistance = 1000.0f; } else { maxSlideDistance = minSlideDistance; } movementAdjustor.SlideTowards( slideTicket, slideTarget, minSlideDistance, maxSlideDistance ); } else if( !slideNPC.GetGameplayVisibility() ) { movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor(); movementAdjustor.CancelByName( 'SlideToTarget' ); slideNPC = NULL; } else { movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor(); movementAdjustor.SlideTowards( slideTicket, slideTarget, minSlideDistance, maxSlideDistance ); } } event OnAnimEvent_ActionBlend( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { } event OnAnimEvent_SubstateManager( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { substateManager.OnAnimEvent( animEventName, animEventType, animInfo ); } event OnAnimEvent_AllowFall( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { if ( !substateManager.m_OwnerMAC.IsOnGround() ) { substateManager.m_SharedDataO.SetFallFromCritical( true ); substateManager.m_MoverO.SetVelocity( -6.0f * GetWorldForward() ); substateManager.QueueStateExternal( 'Jump' ); RemoveBuff( EET_Knockdown, true ); RemoveBuff( EET_HeavyKnockdown, true ); return true; } return false; } event OnAnimEvent_AllowFall2( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { if ( !substateManager.m_OwnerMAC.IsOnGround() ) { substateManager.QueueStateExternal( 'Jump' ); RemoveBuff( EET_Knockdown, true ); RemoveBuff( EET_HeavyKnockdown, true ); } if( substateManager.StateWantsAndCanEnter( 'Slide' ) ) { substateManager.QueueStateExternal( 'Slide' ); } } event OnAnimEvent_DettachGround( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { } event OnAnimEvent_pad_vibration( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { var witcher : W3PlayerWitcher; theGame.VibrateControllerHard(); witcher = GetWitcherPlayer(); if(isInFinisher && witcher) { if(HasAbility('Runeword 10 _Stats', true) && !witcher.runeword10TriggerredOnFinisher && ((bool)theGame.GetInGameConfigWrapper().GetVarValue('Gameplay', 'AutomaticFinishersEnabled')) == true) { witcher.Runeword10Triggerred(); witcher.runeword10TriggerredOnFinisher = true; } else if(HasAbility('Runeword 12 _Stats', true) && !witcher.runeword12TriggerredOnFinisher) { witcher.Runeword12Triggerred(); witcher.runeword12TriggerredOnFinisher = true; } } } event OnAnimEvent_pad_vibration_light( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { } event OnAnimEvent_KillWithRagdoll( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { } event OnAnimEvent_RemoveBurning( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { thePlayer.AddBuffImmunity(EET_Burning, 'AnimEvent_RemoveBurning', true); } event OnAnimEvent_RemoveTangled( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { if ( this.HasBuff( EET_Tangled ) ) { this.StopEffect('black_spider_web'); this.PlayEffectSingle('black_spider_web_break'); } } event OnAnimEvent_MoveNoise( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { theGame.GetBehTreeReactionManager().CreateReactionEventIfPossible( this, 'MoveNoise', -1, 30.0f, -1.f, -1, true ); } event OnBehaviorGraphNotification( notificationName : name, stateName : name ) { substateManager.OnBehaviorGraphNotification( notificationName, stateName ); if( notificationName == 'PlayerRunActivate' ) { isInRunAnimation = true; } else if( notificationName == 'PlayerRunDeactivate' ) { isInRunAnimation = false; } } event OnEnumAnimEvent( animEventName : name, variant : SEnumVariant, animEventType : EAnimationEventType, animEventDuration : float, animInfo : SAnimationEventAnimInfo ) { var movementAdjustor : CMovementAdjustor; var ticket : SMovementAdjustmentRequestTicket; var rotationRate : ERotationRate; if ( animEventName == 'RotateToTarget' ) { rotationRate = GetRotationRateFromAnimEvent( variant.enumValue ); movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor(); if ( animEventType == AET_DurationStart || animEventType == AET_DurationStartInTheMiddle ) { if (! movementAdjustor.IsRequestActive( movementAdjustor.GetRequest( 'RotateToTarget' ) ) ) { ticket = movementAdjustor.CreateNewRequest( 'RotateToTarget' ); if ((int)rotationRate == 0) movementAdjustor.AdjustmentDuration( ticket, animEventDuration ); else { movementAdjustor.Continuous( ticket ); movementAdjustor.BindToEvent( ticket, 'RotateToTarget' ); } movementAdjustor.DontUseSourceAnimation( ticket ); movementAdjustor.ReplaceRotation( ticket ); } else { ticket = movementAdjustor.GetRequest( 'RotateToTarget' ); } MovAdjRotateToTarget( ticket ); if ((int)rotationRate > 0) { movementAdjustor.MaxRotationAdjustmentSpeed( ticket, (float)((int)rotationRate) ); } } else if ( animEventType == AET_DurationEnd ) { } else { ticket = movementAdjustor.GetRequest( 'RotateToTarget' ); MovAdjRotateToTarget( ticket ); } } super.OnEnumAnimEvent(animEventName, variant, animEventType, animEventDuration, animInfo); } event OnTeleported() { if( substateManager ) { substateManager.OnTeleported(); } } event OnStartFistfightMinigame() { super.OnStartFistfightMinigame(); SetFistFightMinigameEnabled( true ); FistFightHealthChange( true ); thePlayer.GetPlayerMode().ForceCombatMode( FCMR_QuestFunction ); SetImmortalityMode(AIM_Unconscious, AIC_Fistfight); thePlayer.SetBehaviorVariable( 'playerWeaponLatent', (int)PW_Fists ); GotoCombatStateWithAction( IA_None ); ((CMovingAgentComponent)this.GetMovingAgentComponent()).SnapToNavigableSpace( true ); EquipGeraltFistfightWeapon( true ); BlockAction( EIAB_RadialMenu, 'FistfightMinigame' ,,true); BlockAction( EIAB_Signs, 'FistfightMinigame' ,,true); BlockAction( EIAB_ThrowBomb, 'FistfightMinigame' ,,true); BlockAction( EIAB_UsableItem, 'FistfightMinigame' ,,true); BlockAction( EIAB_Crossbow, 'FistfightMinigame' ,,true); BlockAction( EIAB_DrawWeapon, 'FistfightMinigame' ,,true); BlockAction( EIAB_RunAndSprint, 'FistfightMinigame' ,,true); BlockAction( EIAB_SwordAttack, 'FistfightMinigame' ,,true); BlockAction( EIAB_CallHorse, 'FistfightMinigame' ,,true); BlockAction( EIAB_Roll, 'FistfightMinigame' ,,true); BlockAction( EIAB_Interactions, 'FistfightMinigame' ,,true); BlockAction( EIAB_Explorations, 'FistfightMinigame' ,,true); BlockAction( EIAB_OpenInventory, 'FistfightMinigame' ,,true); BlockAction( EIAB_QuickSlots, 'FistfightMinigame' ,,true); BlockAction( EIAB_OpenCharacterPanel, 'FistfightMinigame' ,,true); } event OnEndFistfightMinigame() { ((CMovingAgentComponent)this.GetMovingAgentComponent()).SnapToNavigableSpace( false ); FistFightHealthChange( false ); thePlayer.GetPlayerMode().ReleaseForceCombatMode( FCMR_QuestFunction ); EquipGeraltFistfightWeapon( false ); SetFistFightMinigameEnabled( false ); SetImmortalityMode(AIM_None, AIC_Fistfight); BlockAllActions('FistfightMinigame',false); super.OnEndFistfightMinigame(); } public function GetFistFightFinisher( out masterAnimName, slaveAnimIndex : name ) { var index : int; index = RandRange(1); switch ( index ) { case 0 : masterAnimName = 'man_fistfight_finisher_1_win'; slaveAnimIndex = 'man_fistfight_finisher_1_looser'; } } public function SetFistFightMinigameEnabled( flag : bool ) { fistFightMinigameEnabled = flag; } public function SetFistFightParams( toDeath : bool, endsWithBS : bool ) { isFFMinigameToTheDeath = toDeath; FFMinigameEndsithBS = endsWithBS; } public function IsFistFightMinigameEnabled() : bool { return fistFightMinigameEnabled; } public function IsFistFightMinigameToTheDeath() : bool { return isFFMinigameToTheDeath; } public function FistFightHealthChange( val : bool ) { if( val == true ) { GeraltMaxHealth = thePlayer.GetStatMax(BCS_Vitality); ClampGeraltMaxHealth( 2000 ); SetHealthPerc( 100 ); } else { ClampGeraltMaxHealth( GeraltMaxHealth ); SetHealthPerc( 100 ); } } function ClampGeraltMaxHealth( val : float ) { thePlayer.abilityManager.SetStatPointMax( BCS_Vitality, val ); } function EquipGeraltFistfightWeapon( val : bool ) { if ( val ) { fistsItems = thePlayer.GetInventory().AddAnItem( 'Geralt Fistfight Fists', 1, true, true ); thePlayer.GetInventory().MountItem( fistsItems[0] , true ); } else { thePlayer.GetInventory().DropItem( fistsItems[0], true ); } } public function GetGwintAiDifficulty() : EGwintDifficultyMode { return gwintAiDifficulty; } public function SetGwintAiDifficulty( difficulty : EGwintDifficultyMode ) { gwintAiDifficulty = difficulty; } public function GetGwintAiAggression() : EGwintAggressionMode { return gwintAiAggression; } public function SetGwintAiAggression( aggression : EGwintAggressionMode ) { gwintAiAggression = aggression; } public function GetGwintMinigameState() : EMinigameState { return gwintMinigameState; } public function SetGwintMinigameState( minigameState : EMinigameState ) { gwintMinigameState = minigameState; } public function OnGwintGameRequested( deckName : name, forceFaction : eGwintFaction ) { var gwintManager:CR4GwintManager; gwintManager = theGame.GetGwintManager(); gwintMinigameState = EMS_None; gwintManager.SetEnemyDeckByName(deckName); gwintManager.SetForcedFaction(forceFaction); if (gwintManager.GetHasDoneTutorial() || !theGame.GetTutorialSystem().AreMessagesEnabled()) { gwintManager.gameRequested = true; theGame.RequestMenu( 'DeckBuilder' ); } else { theGame.GetGuiManager().ShowUserDialog( UMID_SkipGwintTutorial, "gwint_tutorial_play_query_title", "gwint_tutorial_play_query", UDB_YesNo ); } } public function StartGwint_TutorialOrSkip( skipTutorial : bool ) { var gwintManager : CR4GwintManager; if( skipTutorial ) { gwintManager = theGame.GetGwintManager(); gwintManager.gameRequested = true; gwintManager.SetHasDoneTutorial(true); gwintManager.SetHasDoneDeckTutorial(true); theGame.RequestMenu( 'DeckBuilder' ); } else { theGame.RequestMenu( 'GwintGame' ); } } private var gwintCardNumbersArray : array; public function InitGwintCardNumbersArray( arr : array ) { gwintCardNumbersArray.Clear(); gwintCardNumbersArray = arr; } public function GetCardNumbersArray() : array { return gwintCardNumbersArray; } protected var customCameraStack : array; public function AddCustomCamToStack( customCameraParams : SCustomCameraParams ) : int { if( customCameraParams.useCustomCamera ) { if ( customCameraParams.cameraParams.enums[0].enumType != 'ECustomCameraType' ) { LogChannel( 'CustomCamera', "ERROR: Selected enum is not a custom camera!!!" ); return -1; } else { customCameraStack.PushBack( customCameraParams ); return ( customCameraStack.Size() - 1 ); } } return 0; } public function DisableCustomCamInStack( customCameraStackIndex : int ) { if ( customCameraStackIndex != -1 ) customCameraStack[customCameraStackIndex].useCustomCamera = false; else LogChannel( 'CustomCamera', "ERROR: Custom camera to disable does not exist!!!" ); } event OnInteriorStateChanged( inInterior : bool ) { interiorCamera = inInterior; } event OnModifyPlayerSpeed( flag : bool ) { modifyPlayerSpeed = flag; SetBehaviorVariable( 'modifyPlayerSpeed', (float)modifyPlayerSpeed ); } event OnGameCameraTick( out moveData : SCameraMovementData, dt : float ) { var targetRotation : EulerAngles; var dist : float; if( thePlayer.IsInCombat() ) { dist = VecDistance2D( thePlayer.GetWorldPosition(), thePlayer.GetTarget().GetWorldPosition() ); thePlayer.GetVisualDebug().AddText( 'dbg', dist, thePlayer.GetWorldPosition() + Vector( 0.f,0.f,2.f ), true, , Color( 0, 255, 0 ) ); } if ( isStartingFistFightMinigame ) { moveData.pivotRotationValue = fistFightTeleportNode.GetWorldRotation(); isStartingFistFightMinigame = false; } if( substateManager.UpdateCameraIfNeeded( moveData, dt ) ) { return true; } if ( theGame.IsFocusModeActive() ) { theGame.GetGameCamera().ChangePivotRotationController( 'Exploration' ); theGame.GetGameCamera().ChangePivotDistanceController( 'Default' ); theGame.GetGameCamera().ChangePivotPositionController( 'Default' ); moveData.pivotRotationController = theGame.GetGameCamera().GetActivePivotRotationController(); moveData.pivotDistanceController = theGame.GetGameCamera().GetActivePivotDistanceController(); moveData.pivotPositionController = theGame.GetGameCamera().GetActivePivotPositionController(); moveData.pivotPositionController.SetDesiredPosition( thePlayer.GetWorldPosition() ); moveData.pivotRotationController.SetDesiredPitch( -10.0f ); moveData.pivotRotationController.maxPitch = 50.0; moveData.pivotDistanceController.SetDesiredDistance( 3.5f ); if ( !interiorCamera ) { moveData.pivotPositionController.offsetZ = 1.5f; DampVectorSpring( moveData.cameraLocalSpaceOffset, moveData.cameraLocalSpaceOffsetVel, Vector( 0.5f, 2.0f, 0.3f ), 0.20f, dt ); } else { moveData.pivotPositionController.offsetZ = 1.3f; DampVectorSpring( moveData.cameraLocalSpaceOffset, moveData.cameraLocalSpaceOffsetVel, Vector( 0.5f, 2.3f, 0.5f ), 0.3f, dt ); } return true; } if( substateManager.m_SharedDataO.IsForceHeading( targetRotation ) ) { moveData.pivotRotationController.SetDesiredHeading( targetRotation.Yaw ); moveData.pivotRotationController.SetDesiredPitch( targetRotation.Pitch ); moveData.pivotRotationValue.Yaw = LerpAngleF( 2.1f * dt, moveData.pivotRotationValue.Yaw, targetRotation.Yaw ); moveData.pivotRotationValue.Pitch = LerpAngleF( 1.0f * dt, moveData.pivotRotationValue.Pitch, targetRotation.Pitch ); } if( customCameraStack.Size() > 0 ) { } return false; } private var questCameraRequest : SQuestCameraRequest; private var cameraRequestTimeStamp : float; public function RequestQuestCamera( camera : SQuestCameraRequest ) { questCameraRequest = camera; questCameraRequest.requestTimeStamp = theGame.GetEngineTimeAsSeconds(); } public function ResetQuestCameraRequest() { var cameraRequest : SQuestCameraRequest; questCameraRequest = cameraRequest; } event OnGameCameraPostTick( out moveData : SCameraMovementData, dt : float ) { var ent : CEntity; var playerPos : Vector; var angles : EulerAngles; var distance : float; if ( questCameraRequest.requestTimeStamp > 0 ) { if ( questCameraRequest.duration > 0 && questCameraRequest.requestTimeStamp + questCameraRequest.duration < theGame.GetEngineTimeAsSeconds() ) { ResetQuestCameraRequest(); return false; } if( questCameraRequest.lookAtTag ) { ent = theGame.GetEntityByTag( questCameraRequest.lookAtTag ); playerPos = GetWorldPosition(); playerPos.Z += 1.8f; angles = VecToRotation( ent.GetWorldPosition() - playerPos ); moveData.pivotRotationController.SetDesiredHeading( angles.Yaw ); moveData.pivotRotationController.SetDesiredPitch( -angles.Pitch ); } else { if( questCameraRequest.requestYaw ) { angles = GetWorldRotation(); moveData.pivotRotationController.SetDesiredHeading( angles.Yaw + questCameraRequest.yaw ); } if( questCameraRequest.requestPitch ) { moveData.pivotRotationController.SetDesiredPitch( questCameraRequest.pitch ); } } } } var wasRunning : bool; var vel : float; var smoothTime : float; var constDamper : ConstDamper; var rotMultVel : float; public function UpdateCameraInterior( out moveData : SCameraMovementData, timeDelta : float ) { var camDist : float; var camOffset : float; var rotMultDest : float; var rotMult : float; var angles : EulerAngles; theGame.GetGameCamera().ChangePivotRotationController( 'ExplorationInterior' ); theGame.GetGameCamera().ChangePivotDistanceController( 'Default' ); theGame.GetGameCamera().ChangePivotPositionController( 'Default' ); moveData.pivotRotationController = theGame.GetGameCamera().GetActivePivotRotationController(); moveData.pivotDistanceController = theGame.GetGameCamera().GetActivePivotDistanceController(); moveData.pivotPositionController = theGame.GetGameCamera().GetActivePivotPositionController(); moveData.pivotPositionController.SetDesiredPosition( GetWorldPosition(), 15.f ); if ( !constDamper ) { constDamper = new ConstDamper in this; constDamper.SetDamp( 0.35f ); } if ( rawPlayerSpeed <= 0 || AbsF( AngleDistance( rawPlayerHeading, GetHeading() ) ) > 135 ) constDamper.Reset(); else if ( theGame.IsUberMovementEnabled() ) rotMult = 0.5f; else rotMult = 1.f; rotMult = constDamper.UpdateAndGet( timeDelta, rotMult ); if ( AbsF( AngleDistance( GetHeading(), moveData.pivotRotationValue.Yaw ) ) < 135.f && rawPlayerSpeed > 0 ) moveData.pivotRotationController.SetDesiredHeading( GetHeading(), rotMult ); else moveData.pivotRotationController.SetDesiredHeading( moveData.pivotRotationValue.Yaw ); moveData.pivotDistanceController.SetDesiredDistance( 1.5f ); angles = VecToRotation( GetMovingAgentComponent().GetVelocity() ); if ( AbsF( angles.Pitch ) < 8.f || bLAxisReleased ) moveData.pivotRotationController.SetDesiredPitch( -10.f ); else moveData.pivotRotationController.SetDesiredPitch( -angles.Pitch - 18.f ); if ( IsGuarded() ) moveData.pivotPositionController.offsetZ = 1.0f; else moveData.pivotPositionController.offsetZ = 1.3f; if ( playerMoveType >= PMT_Run ) { camDist = -0.5f; camOffset = 0.25; if ( !wasRunning ) { smoothTime = 1.f; wasRunning = true; } DampFloatSpring( smoothTime, vel, 0.1, 0.5, timeDelta ); } else { camDist = 0.f; camOffset = 0.4f; smoothTime = 0.2f; wasRunning = false; } DampVectorSpring( moveData.cameraLocalSpaceOffset, moveData.cameraLocalSpaceOffsetVel, Vector( 0.3f, camDist, 0.3f ), smoothTime, timeDelta ); } var wasBRAxisPushed : bool; protected function UpdateCameraChanneledSign( out moveData : SCameraMovementData, timeDelta : float ) : bool { var screenSpaceOffset : float; var screenSpaceOffsetFwd : float; var screenSpaceOffsetUp : float; var heading : float; var pitch : float; var playerToTargetRot : EulerAngles; var rightOffset : float = -20.f; var leftOffset : float = 15.f; var angles : EulerAngles; var vec : Vector; if( this.IsCurrentSignChanneled() && this.GetCurrentlyCastSign() != ST_Quen && this.GetCurrentlyCastSign() != ST_Yrden ) { theGame.GetGameCamera().ChangePivotRotationController( 'SignChannel' ); theGame.GetGameCamera().ChangePivotDistanceController( 'SignChannel' ); moveData.pivotRotationController = theGame.GetGameCamera().GetActivePivotRotationController(); moveData.pivotDistanceController = theGame.GetGameCamera().GetActivePivotDistanceController(); if ( GetCurrentlyCastSign() == ST_Axii ) leftOffset = 32.f; if ( oTCameraOffset != leftOffset && oTCameraOffset != rightOffset ) { if( ( interiorCamera && !moveTarget ) || ( AngleDistance( GetHeading(), moveData.pivotRotationValue.Yaw ) < 0 ) ) oTCameraOffset = leftOffset; else oTCameraOffset = rightOffset; } if ( oTCameraOffset == leftOffset ) { screenSpaceOffset = 0.65f; oTCameraPitchOffset = 13.f; } else if ( oTCameraOffset == rightOffset ) { screenSpaceOffset = -0.65f; oTCameraPitchOffset = 13.f; } moveData.pivotPositionController.offsetZ = 1.3f; if ( !delayCameraOrientationChange ) { if ( GetOrientationTarget() == OT_Camera || GetOrientationTarget() == OT_CameraOffset ) { if ( bRAxisReleased ) { heading = moveData.pivotRotationValue.Yaw; pitch = moveData.pivotRotationValue.Pitch; } else { heading = moveData.pivotRotationValue.Yaw + oTCameraOffset; pitch = moveData.pivotRotationValue.Pitch; } } else if ( GetOrientationTarget() == OT_Actor ) { if ( GetDisplayTarget() ) vec = GetDisplayTarget().GetWorldPosition() - GetWorldPosition(); else if ( slideTarget ) vec = slideTarget.GetWorldPosition() - GetWorldPosition(); else if ( GetTarget() ) vec = GetTarget().GetWorldPosition() - GetWorldPosition(); else vec = GetHeadingVector(); angles = VecToRotation( vec ); heading = angles.Yaw + oTCameraOffset; pitch = -angles.Pitch - oTCameraPitchOffset; } else { angles = VecToRotation( GetHeadingVector() ); heading = angles.Yaw + oTCameraOffset; pitch = -angles.Pitch - oTCameraPitchOffset; } if ( !wasBRAxisPushed && ( !bRAxisReleased ) ) wasBRAxisPushed = true; moveData.pivotRotationController.SetDesiredHeading( heading , 2.f ); moveData.pivotRotationController.SetDesiredPitch( pitch ); } else { moveData.pivotRotationController.SetDesiredHeading( moveData.pivotRotationValue.Yaw, 1.f ); moveData.pivotRotationController.SetDesiredPitch( -oTCameraPitchOffset ); } if ( moveData.pivotRotationValue.Pitch <= 5.f && moveData.pivotRotationValue.Pitch >= -15.f ) { screenSpaceOffsetFwd = 1.8; screenSpaceOffsetUp = 0.4; } else if ( moveData.pivotRotationValue.Pitch > 0 ) { screenSpaceOffsetFwd = moveData.pivotRotationValue.Pitch*0.00727 + 1.275f; screenSpaceOffsetFwd = ClampF( screenSpaceOffsetFwd, 1.5, 2.2 ); screenSpaceOffsetUp = -moveData.pivotRotationValue.Pitch*0.00727 + 0.4363f; screenSpaceOffsetUp = ClampF( screenSpaceOffsetUp, 0, 0.3 ); } else { if ( GetCurrentlyCastSign() == ST_Axii ) { screenSpaceOffsetFwd = -moveData.pivotRotationValue.Pitch*0.0425 + 0.8625f; screenSpaceOffsetFwd = ClampF( screenSpaceOffsetFwd, 1.5, 2.3 ); } else { screenSpaceOffsetFwd = -moveData.pivotRotationValue.Pitch*0.035 + 0.75f; screenSpaceOffsetFwd = ClampF( screenSpaceOffsetFwd, 1.5, 2.6 ); } screenSpaceOffsetUp = -moveData.pivotRotationValue.Pitch*0.005 + 0.325f; screenSpaceOffsetUp = ClampF( screenSpaceOffsetUp, 0.4, 0.5 ); } DampVectorSpring( moveData.cameraLocalSpaceOffset, moveData.cameraLocalSpaceOffsetVel, Vector( screenSpaceOffset, screenSpaceOffsetFwd, screenSpaceOffsetUp ), 0.25f, timeDelta ); moveData.pivotDistanceController.SetDesiredDistance( 2.8f, 5.f ); moveData.pivotPositionController.SetDesiredPosition( GetWorldPosition() ); return true; } else { this.wasBRAxisPushed = false; return false; } } protected function UpdateCameraForSpecialAttack( out moveData : SCameraMovementData, timeDelta : float ) : bool { var screenSpaceOffset : float; var tempHeading : float; var cameraOffsetLeft : float; var cameraOffsetRight : float; if ( !specialAttackCamera ) return false; theGame.GetGameCamera().ForceManualControlHorTimeout(); theGame.GetGameCamera().ForceManualControlVerTimeout(); cameraOffsetLeft = 30.f; cameraOffsetRight = -30.f; theGame.GetGameCamera().ChangePivotRotationController( 'SignChannel' ); theGame.GetGameCamera().ChangePivotDistanceController( 'SignChannel' ); moveData.pivotRotationController = theGame.GetGameCamera().GetActivePivotRotationController(); moveData.pivotDistanceController = theGame.GetGameCamera().GetActivePivotDistanceController(); if ( slideTarget ) tempHeading = VecHeading( slideTarget.GetWorldPosition() - GetWorldPosition() ); else tempHeading = GetHeading(); oTCameraPitchOffset = 0.f; if( ( interiorCamera && !moveTarget ) || ( AngleDistance( tempHeading, moveData.pivotRotationValue.Yaw ) < 0 ) ) oTCameraOffset = cameraOffsetLeft; else oTCameraOffset = cameraOffsetRight; if ( oTCameraOffset == cameraOffsetLeft ) { if ( delayCameraOrientationChange || delayOrientationChange ) { screenSpaceOffset = 0.75f; moveData.pivotDistanceController.SetDesiredDistance( 1.6f, 3.f ); moveData.pivotPositionController.offsetZ = 1.4f; moveData.pivotRotationController.SetDesiredPitch( -15.f ); } else { screenSpaceOffset = 0.7f; moveData.pivotDistanceController.SetDesiredDistance( 3.25f ); moveData.pivotPositionController.offsetZ = 1.2f; moveData.pivotRotationController.SetDesiredPitch( -10.f ); } } else if ( oTCameraOffset == cameraOffsetRight ) { if ( delayCameraOrientationChange || delayOrientationChange ) { screenSpaceOffset = -0.85f; moveData.pivotDistanceController.SetDesiredDistance( 1.6f, 3.f ); moveData.pivotPositionController.offsetZ = 1.4f; moveData.pivotRotationController.SetDesiredPitch( -15.f ); } else { screenSpaceOffset = -0.8f; moveData.pivotDistanceController.SetDesiredDistance( 3.25f ); moveData.pivotPositionController.offsetZ = 1.2f; moveData.pivotRotationController.SetDesiredPitch( -10.f ); } } else { moveData.pivotDistanceController.SetDesiredDistance( 1.25f, 3.f ); moveData.pivotPositionController.offsetZ = 1.3f; moveData.pivotRotationController.SetDesiredPitch( -5.5f ); } DampVectorSpring( moveData.cameraLocalSpaceOffset, moveData.cameraLocalSpaceOffsetVel, Vector( screenSpaceOffset, 0.f, 0.f ), 1.f, timeDelta ); if ( !delayCameraOrientationChange ) { if ( moveTarget ) moveData.pivotRotationController.SetDesiredHeading( GetHeading() + oTCameraOffset, 0.5f ); else moveData.pivotRotationController.SetDesiredHeading( GetHeading() + oTCameraOffset, 1.f ); } else moveData.pivotRotationController.SetDesiredHeading( moveData.pivotRotationValue.Yaw, 1.f ); moveData.pivotPositionController.SetDesiredPosition( GetWorldPosition() ); return true; } private var fovVel : float; private var sprintOffset : Vector; private var previousOffset : bool; private var previousRotationVelocity : float; private var pivotRotationTimeStamp : float; protected function UpdateCameraSprint( out moveData : SCameraMovementData, timeDelta : float ) { var angleDiff : float; var camOffsetVector : Vector; var smoothSpeed : float; var camera : CCustomCamera; var camAngularSpeed : float; var playerToCamAngle : float; var useExplorationSprintCam : bool; camera = theGame.GetGameCamera(); if( camera ) { if ( sprintingCamera ) { if( thePlayer.GetAutoCameraCenter() ) { theGame.GetGameCamera().ForceManualControlVerTimeout(); } playerToCamAngle = AbsF( AngleDistance( GetHeading(), moveData.pivotRotationValue.Yaw ) ); useExplorationSprintCam = false; if ( useExplorationSprintCam ) { if ( playerToCamAngle <= 45 ) { theGame.GetGameCamera().ChangePivotRotationController( 'Sprint' ); moveData.pivotRotationController = theGame.GetGameCamera().GetActivePivotRotationController(); moveData.pivotRotationController.SetDesiredHeading( GetHeading(), 0.25f ); moveData.pivotRotationController.SetDesiredPitch( -3.5f, 0.5f ); thePlayer.EnableManualCameraControl( true, 'Sprint' ); } else { thePlayer.EnableManualCameraControl( false, 'Sprint' ); } } else { if ( theGame.IsUberMovementEnabled() ) moveData.pivotRotationController.SetDesiredHeading( GetHeading(), 0.35f ); thePlayer.EnableManualCameraControl( true, 'Sprint' ); } if ( bRAxisReleased ) { if ( AbsF( rawLeftJoyRot ) > 25 ) angleDiff = AngleDistance( GetHeading(), moveData.pivotRotationValue.Yaw ); pivotRotationTimeStamp = theGame.GetEngineTimeAsSeconds(); previousRotationVelocity = 0.f; } else { if ( previousRotationVelocity <= 0 && AbsF( moveData.pivotRotationVelocity.Yaw ) > 250 ) { pivotRotationTimeStamp = theGame.GetEngineTimeAsSeconds(); previousRotationVelocity = AbsF( moveData.pivotRotationVelocity.Yaw ); } } if ( pivotRotationTimeStamp + 0.4f <= theGame.GetEngineTimeAsSeconds() && AbsF( moveData.pivotRotationVelocity.Yaw ) > 250 ) angleDiff = VecHeading( rawRightJoyVec ); if ( useExplorationSprintCam ) { if ( playerToCamAngle > 90 ) { camOffsetVector.X = 0.f; smoothSpeed = 1.f; } else if ( angleDiff > 15.f ) { camOffsetVector.X = -0.8; smoothSpeed = 1.f; previousOffset = true; } else if ( angleDiff < -15.f ) { camOffsetVector.X = 0.475f; smoothSpeed = 1.5f; previousOffset = false; } else { if ( previousOffset ) { camOffsetVector.X = -0.8; smoothSpeed = 1.5f; } else { camOffsetVector.X = 0.475f; smoothSpeed = 1.5f; } } camOffsetVector.Y = 1.4f; camOffsetVector.Z = 0.275f; } else { smoothSpeed = 0.75f; camOffsetVector.X = 0.f; camOffsetVector.Y = 1.f; camOffsetVector.Z = 0.2f; moveData.pivotRotationController.SetDesiredPitch( -10.f, 0.5f ); } DampVectorConst( sprintOffset, camOffsetVector, smoothSpeed, timeDelta ); moveData.cameraLocalSpaceOffset = sprintOffset; DampFloatSpring( camera.fov, fovVel, 70.f, 1.0, timeDelta ); } else { sprintOffset = moveData.cameraLocalSpaceOffset; DampFloatSpring( camera.fov, fovVel, 60.f, 1.0, timeDelta ); previousOffset = false; } } } function EnableSprintingCamera( flag : bool ) { if( !theGame.IsUberMovementEnabled() && !useSprintingCameraAnim ) { return; } super.EnableSprintingCamera( flag ); if ( !flag ) { thePlayer.EnableManualCameraControl( true, 'Sprint' ); } } protected function UpdateCameraCombatActionButNotInCombat( out moveData : SCameraMovementData, timeDelta : float ) { var vel : Vector; var heading : float; var pitch : float; var headingMult : float; var pitchMult : float; var camOffset : Vector; var buff : CBaseGameplayEffect; var runningAndAlertNear : bool; var desiredDist : float; if ( ( !IsCurrentSignChanneled() || GetCurrentlyCastSign() == ST_Quen || GetCurrentlyCastSign() == ST_Yrden ) && !specialAttackCamera && !IsInCombatActionFriendly() ) { buff = GetCurrentlyAnimatedCS(); runningAndAlertNear = GetPlayerCombatStance() == PCS_AlertNear && playerMoveType == PMT_Run && !GetDisplayTarget(); if ( runningAndAlertNear || ( GetPlayerCombatStance() == PCS_AlertFar && !IsInCombatAction() && !buff ) ) { camOffset.X = 0.f; camOffset.Y = 0.f; camOffset.Z = -0.1f; if ( runningAndAlertNear ) { moveData.pivotDistanceController.SetDesiredDistance( 4.f ); moveData.pivotPositionController.offsetZ = 1.5f; } } else { camOffset.X = 0.f; camOffset.Y = -1.5f; camOffset.Z = -0.2f; } DampVectorSpring( moveData.cameraLocalSpaceOffset, moveData.cameraLocalSpaceOffsetVel, Vector( camOffset.X, camOffset.Y, camOffset.Z ), 0.4f, timeDelta ); sprintOffset = moveData.cameraLocalSpaceOffset; heading = moveData.pivotRotationValue.Yaw; if ( GetOrientationTarget() == OT_Camera || GetOrientationTarget() == OT_CameraOffset ) pitch = moveData.pivotRotationValue.Pitch; else if ( lastAxisInputIsMovement || GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Attack || GetBehaviorVariable( 'combatActionType' ) == (int)CAT_SpecialAttack || ( GetBehaviorVariable( 'combatActionType' ) == (int)CAT_CastSign && !IsCurrentSignChanneled() && GetCurrentlyCastSign() == ST_Quen ) ) { theGame.GetGameCamera().ForceManualControlVerTimeout(); pitch = -20.f; } else pitch = moveData.pivotRotationValue.Pitch; headingMult = 1.f; pitchMult = 1.f; if( GetBehaviorVariable( 'combatActionType' ) == (int)CAT_CastSign && ( GetEquippedSign() == ST_Aard || GetEquippedSign() == ST_Yrden ) && GetBehaviorVariable( 'alternateSignCast' ) == 1 ) { theGame.GetGameCamera().ForceManualControlVerTimeout(); pitch = -20.f; } if ( IsCurrentSignChanneled() && GetCurrentlyCastSign() == ST_Quen ) { pitch = moveData.pivotRotationValue.Pitch; } moveData.pivotRotationController.SetDesiredHeading( heading, ); moveData.pivotRotationController.SetDesiredPitch( pitch ); } } event OnGameCameraExplorationRotCtrlChange() { if( substateManager ) { return substateManager.OnGameCameraExplorationRotCtrlChange( ); } return false; } function SetCustomRotation( customRotationName : name, rotHeading : float, rotSpeed : float, activeTime : float, rotateExistingDeltaLocation : bool ) { var movementAdjustor : CMovementAdjustor; var ticket : SMovementAdjustmentRequestTicket; movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor(); ticket = movementAdjustor.GetRequest( customRotationName ); movementAdjustor.Cancel( ticket ); ticket = movementAdjustor.CreateNewRequest( customRotationName ); movementAdjustor.Continuous( ticket ); movementAdjustor.ReplaceRotation( ticket ); movementAdjustor.RotateTo( ticket, rotHeading ); movementAdjustor.MaxRotationAdjustmentSpeed( ticket, rotSpeed ); if (rotSpeed == 0.0f) { movementAdjustor.AdjustmentDuration( ticket, activeTime ); } movementAdjustor.KeepActiveFor( ticket, activeTime ); movementAdjustor.RotateExistingDeltaLocation( ticket, rotateExistingDeltaLocation ); } function UpdateCustomRotationHeading( customRotationName : name, rotHeading : float ) { var movementAdjustor : CMovementAdjustor; var ticket : SMovementAdjustmentRequestTicket; movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor(); ticket = movementAdjustor.GetRequest( customRotationName ); movementAdjustor.RotateTo( ticket, rotHeading ); } function SetCustomRotationTowards( customRotationName : name, target : CActor, rotSpeed : float, optional activeTime : float ) { var movementAdjustor : CMovementAdjustor; var ticket : SMovementAdjustmentRequestTicket; movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor(); ticket = movementAdjustor.GetRequest( customRotationName ); movementAdjustor.Cancel( ticket ); ticket = movementAdjustor.CreateNewRequest( customRotationName ); movementAdjustor.Continuous( ticket ); movementAdjustor.ReplaceRotation( ticket ); movementAdjustor.RotateTowards( ticket, target ); movementAdjustor.MaxRotationAdjustmentSpeed( ticket, rotSpeed ); if (activeTime > 0.0f) { movementAdjustor.KeepActiveFor( ticket, activeTime ); } else { movementAdjustor.DontEnd( ticket ); } } function CustomLockMovement( customMovementName : name, heading : float ) { var movementAdjustor : CMovementAdjustor; var ticket : SMovementAdjustmentRequestTicket; movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor(); ticket = movementAdjustor.GetRequest( customMovementName ); movementAdjustor.Cancel( ticket ); ticket = movementAdjustor.CreateNewRequest( customMovementName ); movementAdjustor.Continuous( ticket ); movementAdjustor.DontEnd( ticket ); movementAdjustor.LockMovementInDirection( ticket, heading ); } function BindMovementAdjustmentToEvent( customRotationName : name, eventName : CName ) { var movementAdjustor : CMovementAdjustor; var ticket : SMovementAdjustmentRequestTicket; movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor(); ticket = movementAdjustor.GetRequest( customRotationName ); movementAdjustor.BindToEvent( ticket, eventName ); } function UpdateCustomLockMovementHeading( customMovementName : name, heading : float ) { var movementAdjustor : CMovementAdjustor; var ticket : SMovementAdjustmentRequestTicket; movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor(); ticket = movementAdjustor.GetRequest( customMovementName ); movementAdjustor.LockMovementInDirection( ticket, heading ); } function CustomLockDistance( customMovementName : name, maintainDistanceTo : CNode, minDist, maxDist : float ) { var movementAdjustor : CMovementAdjustor; var ticket : SMovementAdjustmentRequestTicket; movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor(); ticket = movementAdjustor.GetRequest( customMovementName ); movementAdjustor.Cancel( ticket ); ticket = movementAdjustor.CreateNewRequest( customMovementName ); movementAdjustor.Continuous( ticket ); movementAdjustor.SlideTowards( ticket, maintainDistanceTo, minDist, maxDist ); } function UpdateCustomLockDistance( customMovementName : name, maintainDistanceTo : CNode, minDist, maxDist : float ) { var movementAdjustor : CMovementAdjustor; var ticket : SMovementAdjustmentRequestTicket; movementAdjustor = GetMovingAgentComponent().GetMovementAdjustor(); ticket = movementAdjustor.GetRequest( customMovementName ); movementAdjustor.SlideTowards( ticket, maintainDistanceTo, minDist, maxDist ); } private var disableManualCameraControlStack : array; public function EnableManualCameraControl( enable : bool, sourceName : name ) { if ( !enable ) { if ( !disableManualCameraControlStack.Contains( sourceName ) ) { disableManualCameraControlStack.PushBack( sourceName ); } } else { disableManualCameraControlStack.Remove( sourceName ); } if ( disableManualCameraControlStack.Size() > 0 ) theGame.GetGameCamera().EnableManualControl( false ); else theGame.GetGameCamera().EnableManualControl( true ); } public function IsCameraControlDisabled( optional disabledBySourceName : name ) : bool { if ( disabledBySourceName ) return disableManualCameraControlStack.Contains( disabledBySourceName ); else return disableManualCameraControlStack.Size() > 0; } public function DisableManualCameraControlStackHasSource( sourceName : name ) : bool { return disableManualCameraControlStack.Contains( sourceName ); } public function ClearDisableManualCameraControlStack() { disableManualCameraControlStack.Clear(); theGame.GetGameCamera().EnableManualControl( true ); } function SetOrientationTarget( target : EOrientationTarget ) { if ( IsPCModeEnabled() && target == OT_Player ) { target = OT_Camera; } orientationTarget = target; } function GetOrientationTarget() : EOrientationTarget { return orientationTarget; } var customOrientationInfoStack : array; public function AddCustomOrientationTarget( orientationTarget : EOrientationTarget, sourceName : name ) { var customOrientationInfo : SCustomOrientationInfo; var i : int; if ( customOrientationInfoStack.Size() > 0 ) { for( i = customOrientationInfoStack.Size()-1; i>=0; i-=1 ) { if ( customOrientationInfoStack[i].sourceName == sourceName ) customOrientationInfoStack.Erase(i); } } customOrientationInfo.sourceName = sourceName; customOrientationInfo.orientationTarget = orientationTarget; customOrientationInfoStack.PushBack( customOrientationInfo ); SetOrientationTarget( orientationTarget ); } public function RemoveCustomOrientationTarget( sourceName : name ) { var customOrientationInfo : SCustomOrientationInfo; var i : int; if ( customOrientationInfoStack.Size() > 0 ) { for( i = customOrientationInfoStack.Size()-1; i>=0; i-=1 ) { if ( customOrientationInfoStack[i].sourceName == sourceName ) customOrientationInfoStack.Erase(i); } } else LogChannel( 'CustomOrienatation', "ERROR: Custom orientation cannot be removed, stack is already empty!!!" ); } protected function ClearCustomOrientationInfoStack() { customOrientationInfoStack.Clear(); } protected function GetCustomOrientationTarget( out infoStack : SCustomOrientationInfo ) : bool { var size : int; size = customOrientationInfoStack.Size(); if ( size <= 0 ) return false; else { infoStack = customOrientationInfoStack[ size - 1 ]; return true; } } public function SetOrientationTargetCustomHeading( heading : float, sourceName : name ) : bool { var i : int; if ( customOrientationInfoStack.Size() > 0 ) { for( i = customOrientationInfoStack.Size()-1; i>=0; i-=1 ) { if ( customOrientationInfoStack[i].sourceName == sourceName ) { customOrientationInfoStack[i].customHeading = heading; return true; } } } LogChannel( 'SetOrientationTargetCustomHeading', "ERROR: Cannot set customHeading because stack is empty or sourceName is not found!!!" ); return false; } public function GetOrientationTargetCustomHeading() : float { var i : int; if ( customOrientationInfoStack.Size() > 0 ) { for( i = customOrientationInfoStack.Size()-1; i>=0; i-=1 ) { if ( customOrientationInfoStack[i].orientationTarget == OT_CustomHeading ) { return customOrientationInfoStack[i].customHeading; } } } LogChannel( 'SetOrientationTargetCustomHeading', "ERROR: Cannot get customHeading because stack is empty or no OT_CustomHeading in stack!!!" ); return -1.f; } public function GetCombatActionOrientationTarget( combatActionType : ECombatActionType ) : EOrientationTarget { var newCustomOrientationTarget : EOrientationTarget; var targetEnt : CGameplayEntity; var targetActor : CActor; if ( GetCurrentStateName() == 'AimThrow' ) newCustomOrientationTarget = OT_CameraOffset; else { targetEnt = GetDisplayTarget(); targetActor = (CActor)targetEnt; if ( targetEnt ) { if ( targetActor ) { if ( moveTarget ) newCustomOrientationTarget = OT_Actor; else { if ( this.IsSwimming() ) newCustomOrientationTarget = OT_Camera; else if ( lastAxisInputIsMovement ) newCustomOrientationTarget = OT_Player; else newCustomOrientationTarget = OT_Actor; } } else { if ( combatActionType == CAT_Crossbow && targetEnt.HasTag( 'softLock_Bolt' ) ) newCustomOrientationTarget = OT_Actor; else { if ( this.IsSwimming() ) newCustomOrientationTarget = OT_Camera; else if ( lastAxisInputIsMovement ) newCustomOrientationTarget = OT_Player; else newCustomOrientationTarget = OT_Camera; } } } else { if ( IsUsingVehicle() ) newCustomOrientationTarget = OT_Camera; else if ( lastAxisInputIsMovement ) { if ( this.IsSwimming() ) { newCustomOrientationTarget = OT_Camera; } else newCustomOrientationTarget = OT_Player; } else newCustomOrientationTarget = OT_Camera; } } return newCustomOrientationTarget; } public function GetOrientationTargetHeading( orientationTarget : EOrientationTarget ) : float { var heading : float; if( orientationTarget == OT_Camera ) heading = VecHeading( theCamera.GetCameraDirection() ); else if( orientationTarget == OT_CameraOffset ) heading = VecHeading( theCamera.GetCameraDirection() ) - oTCameraOffset; else if( orientationTarget == OT_CustomHeading ) heading = GetOrientationTargetCustomHeading(); else if ( GetDisplayTarget() && orientationTarget == OT_Actor ) { if ( (CActor)( GetDisplayTarget() ) ) { heading = VecHeading( GetDisplayTarget().GetWorldPosition() - GetWorldPosition() ); } else { if ( GetDisplayTarget().HasTag( 'softLock_Bolt' ) ) heading = VecHeading( GetDisplayTarget().GetWorldPosition() - GetWorldPosition() ); else heading = GetHeading(); } } else heading = GetHeading(); return heading; } event OnDelayOrientationChange() { var delayOrientation : bool; var delayCameraRotation : bool; var moveData : SCameraMovementData; var time : float; time = 0.01f; if ( theInput.GetActionValue( 'CastSignHold' ) == 1.f ) { actionType = 0; if ( moveTarget ) delayOrientation = true; else { if ( !GetBIsCombatActionAllowed() ) delayOrientation = true; } } else if ( theInput.GetActionValue( 'ThrowItemHold' ) == 1.f ) { actionType = 3; delayOrientation = true; } else if ( theInput.GetActionValue( 'SpecialAttackHeavy' ) == 1.f ) { actionType = 2; if ( !slideTarget ) delayOrientation = true; else delayOrientation = true; } else if ( IsGuarded() && !moveTarget ) { actionType = 1; delayOrientation = true; } if ( delayOrientation ) { delayOrientationChange = true; theGame.GetGameCamera().ForceManualControlHorTimeout(); theGame.GetGameCamera().ForceManualControlVerTimeout(); AddTimer( 'DelayOrientationChangeTimer', time, true ); } if ( delayCameraRotation ) { delayCameraOrientationChange = true; theGame.GetGameCamera().ForceManualControlHorTimeout(); theGame.GetGameCamera().ForceManualControlVerTimeout(); AddTimer( 'DelayOrientationChangeTimer', time, true ); } } event OnDelayOrientationChangeOff() { delayOrientationChange = false; delayCameraOrientationChange = false; RemoveTimer( 'DelayOrientationChangeTimer' ); } timer function DelayOrientationChangeTimer( time : float , id : int) { if ( ( actionType == 0 && theInput.GetActionValue( 'CastSignHold' ) == 0.f ) || ( actionType == 2 && theInput.GetActionValue( 'SpecialAttackHeavy' ) == 0.f ) || ( actionType == 3 && theInput.GetActionValue( 'ThrowItemHold' ) == 0.f ) || ( actionType == 1 && !IsGuarded() ) || ( VecLength( rawRightJoyVec ) > 0.f ) ) { OnDelayOrientationChangeOff(); } } public function SetCombatActionHeading( heading : float ) { combatActionHeading = heading; } public function GetCombatActionHeading() : float { return combatActionHeading; } protected function EnableCloseCombatCharacterRadius( flag : bool ) { var actor : CActor; actor = (CActor)slideTarget; if ( flag ) { this.GetMovingAgentComponent().SetVirtualRadius( 'CloseCombatCharacterRadius' ); if(actor) actor.GetMovingAgentComponent().SetVirtualRadius( 'CloseCombatCharacterRadius' ); } else { if ( this.IsInCombat() ) { GetMovingAgentComponent().SetVirtualRadius( 'CombatCharacterRadius' ); if(actor) actor.GetMovingAgentComponent().SetVirtualRadius( 'CombatCharacterRadius' ); } else { this.GetMovingAgentComponent().ResetVirtualRadius(); if(actor) actor.GetMovingAgentComponent().ResetVirtualRadius(); } } } private var isSnappedToNavMesh : bool; private var snapToNavMeshCachedFlag : bool; public function SnapToNavMesh( flag : bool ) { var comp : CMovingAgentComponent; comp = (CMovingAgentComponent)this.GetMovingAgentComponent(); if ( comp ) { comp.SnapToNavigableSpace( flag ); isSnappedToNavMesh = flag; } else { snapToNavMeshCachedFlag = flag; AddTimer( 'DelayedSnapToNavMesh', 0.2f ); } } public final function PlayRuneword4FX(optional weaponType : EPlayerWeapon) { var hasSwordDrawn : bool; var sword : SItemUniqueId; if(abilityManager.GetOverhealBonus() > (0.005 * GetStatMax(BCS_Vitality))) { hasSwordDrawn = HasAbility('Runeword 4 _Stats', true); if(!hasSwordDrawn && GetWitcherPlayer()) { if(weaponType == PW_Steel) { if(GetWitcherPlayer().GetItemEquippedOnSlot(EES_SteelSword, sword)) hasSwordDrawn = inv.ItemHasAbility(sword, 'Runeword 4 _Stats'); } else if(weaponType == PW_Silver) { if(GetWitcherPlayer().GetItemEquippedOnSlot(EES_SilverSword, sword)) hasSwordDrawn = inv.ItemHasAbility(sword, 'Runeword 4 _Stats'); } } if(hasSwordDrawn) { if(!IsEffectActive('runeword_4', true)) PlayEffect('runeword_4'); } } } timer function DelayedSnapToNavMesh( dt : float, id : int) { SnapToNavMesh( snapToNavMeshCachedFlag ); } saved var navMeshSnapInfoStack : array; public function EnableSnapToNavMesh( source : name, enable : bool ) { if ( enable ) { if ( !navMeshSnapInfoStack.Contains( source ) ) navMeshSnapInfoStack.PushBack( source ); } else { if ( navMeshSnapInfoStack.Contains( source ) ) navMeshSnapInfoStack.Remove( source ); } if ( navMeshSnapInfoStack.Size() > 0 ) SnapToNavMesh( true ); else SnapToNavMesh( false ); } public function ForceRemoveAllNavMeshSnaps() { navMeshSnapInfoStack.Clear(); SnapToNavMesh( false ); } public function CanSprint( speed : float ) : bool { if( speed <= 0.8f ) { return false; } if ( thePlayer.GetIsSprintToggled() ) { } else if ( !sprintActionPressed ) { return false; } else if( !theInput.IsActionPressed('Sprint') || ( theInput.LastUsedGamepad() && IsInsideInteraction() && GetHowLongSprintButtonWasPressed() < 0.12 ) ) { return false; } if ( thePlayer.HasBuff( EET_OverEncumbered ) ) { return false; } if ( !IsSwimming() ) { if ( ShouldUseStaminaWhileSprinting() && !GetIsSprinting() && !IsInCombat() && GetStatPercents(BCS_Stamina) <= 0.9 ) { return false; } if( ( !IsCombatMusicEnabled() || IsInFistFightMiniGame() ) && ( !IsActionAllowed(EIAB_RunAndSprint) || !IsActionAllowed(EIAB_Sprint) ) ) { return false; } if( IsTerrainTooSteepToRunUp() ) { return false; } if( IsInCombatAction() ) { return false; } if( IsInAir() ) { return false; } } if( theGame.IsFocusModeActive() ) { return false; } return true; } public function SetTerrainPitch( pitch : float ) { terrainPitch = pitch; } public function IsTerrainTooSteepToRunUp() : bool { return terrainPitch <= disableSprintTerrainPitch; } public function SetTempLookAtTarget( actor : CGameplayEntity ) { tempLookAtTarget = actor; } private var beingWarnedBy : array; event OnBeingWarnedStart( sender : CActor ) { if ( !beingWarnedBy.Contains(sender) ) beingWarnedBy.PushBack(sender); } event OnBeingWarnedStop( sender : CActor ) { beingWarnedBy.Remove(sender); } event OnCanFindPath( sender : CActor ) { AddCanFindPathEnemyToList(sender,true); } event OnCannotFindPath( sender : CActor ) { AddCanFindPathEnemyToList(sender,false); } event OnBecomeAwareAndCanAttack( sender : CActor ) { AddEnemyToHostileEnemiesList( sender, true ); OnApproachAttack( sender ); } event OnBecomeUnawareOrCannotAttack( sender : CActor ) { AddEnemyToHostileEnemiesList( sender, false ); OnApproachAttackEnd( sender ); OnCannotFindPath(sender); } event OnApproachAttack( sender : CActor ) { AddEnemyToHostileEnemiesList( sender, true ); super.OnApproachAttack( sender ); } event OnApproachAttackEnd( sender : CActor ) { AddEnemyToHostileEnemiesList( sender, false ); super.OnApproachAttackEnd( sender ); } event OnAttack( sender : CActor ) { super.OnAttack( sender ); } event OnAttackEnd( sender : CActor ) { super.OnAttackEnd( sender ); } event OnHitCeiling() { substateManager.ReactOnHitCeiling(); } protected var hostileEnemies : array; private var hostileMonsters : array; function AddEnemyToHostileEnemiesList( actor : CActor, add : bool ) { if ( add ) { RemoveTimer( 'RemoveEnemyFromHostileEnemiesListTimer' ); if ( !hostileEnemies.Contains( actor ) ) { hostileEnemies.PushBack( actor ); if( !actor.IsHuman() ) hostileMonsters.PushBack( actor ); } } else { if ( hostileEnemies.Size() == 1 ) { if ( !actor.IsAlive() || actor.IsKnockedUnconscious() ) { hostileEnemies.Remove( actor ); if( !actor.IsHuman() ) hostileMonsters.Remove( actor ); } else { if( hostileEnemyToRemove ) { hostileEnemies.Remove( hostileEnemyToRemove ); if( !hostileEnemyToRemove.IsHuman() ) hostileMonsters.Remove( hostileEnemyToRemove ); } hostileEnemyToRemove = actor; AddTimer( 'RemoveEnemyFromHostileEnemiesListTimer', 3.f ); } } else { hostileEnemies.Remove( actor ); if( !actor.IsHuman() ) hostileMonsters.Remove( actor ); } } } public function ShouldEnableCombatMusic() : bool { var moveTargetNPC : CNewNPC; if ( thePlayer.GetPlayerMode().GetForceCombatMode() ) return true; else if ( !IsCombatMusicEnabled() ) { if ( IsInCombat() ) return true; else if ( IsThreatened() ) { moveTargetNPC = (CNewNPC)moveTarget; if ( moveTargetNPC.IsRanged() && hostileEnemies.Contains( moveTargetNPC ) ) return true; else return false; } else return false; } else if ( ( thePlayer.IsThreatened() && ( hostileEnemies.Size() > 0 || thePlayer.GetPlayerCombatStance() == PCS_AlertNear ) ) || IsInCombat() || finishableEnemiesList.Size() > 0 || isInFinisher ) return true; else return false; } public var canFindPathEnemiesList : array; public var disablecanFindPathEnemiesListUpdate : bool; private var lastCanFindPathEnemy : CActor; private var cachedMoveTarget : CActor; private var reachabilityTestId : int; private var reachabilityTestId2 : int; function AddCanFindPathEnemyToList( actor : CActor, add : bool ) { if ( disablecanFindPathEnemiesListUpdate ) return; if ( add && !canFindPathEnemiesList.Contains( actor ) ) { canFindPathEnemiesList.PushBack(actor); } else if ( !add ) { canFindPathEnemiesList.Remove(actor); if ( canFindPathEnemiesList.Size() <= 0 ) playerMode.UpdateCombatMode(); } } public function ClearCanFindPathEnemiesList( dt : float, id : int ) { canFindPathEnemiesList.Clear(); } public var finishableEnemiesList : array; function AddToFinishableEnemyList( actor : CActor, add : bool ) { if ( add && !finishableEnemiesList.Contains( actor ) ) { finishableEnemiesList.PushBack(actor); } else if ( !add ) { finishableEnemiesList.Remove(actor); } } private function UpdateFinishableEnemyList() { var i : int; i = 0; while ( i < finishableEnemiesList.Size() ) { if ( !finishableEnemiesList[ i ] ) { finishableEnemiesList.EraseFast( i ); } else { i += 1; } } } private timer function ClearFinishableEnemyList( dt : float, id : int ) { finishableEnemiesList.Clear(); } private var hostileEnemyToRemove : CActor; private timer function RemoveEnemyFromHostileEnemiesListTimer( time : float , id : int) { hostileEnemies.Remove( hostileEnemyToRemove ); if( hostileEnemyToRemove.IsMonster() ) hostileMonsters.Remove( hostileEnemyToRemove ); hostileEnemyToRemove = NULL; } private function ClearHostileEnemiesList() { hostileEnemies.Clear(); hostileMonsters.Clear(); canFindPathEnemiesList.Clear(); } private var moveTargets : array; public function GetMoveTargets() : array { return moveTargets; } public function GetNumberOfMoveTargets() : int { return moveTargets.Size(); } public function GetHostileEnemies() : array { return hostileEnemies; } public function GetHostileEnemiesCount() : int { return hostileEnemies.Size(); } protected var enableStrafe : bool; public function FindMoveTarget() { var moveTargetDists : array; var moveTargetCanPathFinds : array; var aPotentialMoveTargetCanFindPath : bool; var newMoveTarget : CActor; var actors : array; var currentHeading : float; var size, i : int; var playerToNewMoveTargetDist : float; var playerToMoveTargetDist : float; var confirmEmptyMoveTarget : bool; var newEmptyMoveTargetTimer : float; var wasVisibleInFullFrame : bool; var setIsThreatened : bool; var enemysTarget : CActor; var isEnemyInCombat : bool; var potentialMoveTargets : array; var onlyThreatTargets : bool; thePlayer.SetupEnemiesCollection( enemyCollectionDist, enemyCollectionDist, 10, 'None', FLAG_Attitude_Neutral + FLAG_Attitude_Hostile + FLAG_Attitude_Friendly + FLAG_OnlyAliveActors ); if ( GetCurrentStateName() != 'PlayerDialogScene' && IsAlive() ) { GetVisibleEnemies( actors ); if ( hostileEnemies.Size() > 0 ) { for( i=0; i < hostileEnemies.Size() ; i+=1 ) { if ( !actors.Contains( hostileEnemies[i] ) ) actors.PushBack( hostileEnemies[i] ); } } if ( finishableEnemiesList.Size() > 0 ) { for( i=0; i < finishableEnemiesList.Size() ; i+=1 ) { if ( !actors.Contains( finishableEnemiesList[i] ) ) actors.PushBack( finishableEnemiesList[i] ); } } if ( moveTarget && !actors.Contains( moveTarget ) ) actors.PushBack( moveTarget ); FilterActors( actors, onlyThreatTargets, false ); if ( actors.Size() > 0 ) { setIsThreatened = false; if ( onlyThreatTargets ) { setIsThreatened = true; } else { for( i=0; i < actors.Size() ; i+=1 ) { if ( IsThreat( actors[i] ) ) { setIsThreatened = true; break; } else { enemysTarget = actors[i].GetTarget(); isEnemyInCombat = actors[i].IsInCombat(); if ( isEnemyInCombat && enemysTarget && GetAttitudeBetween( enemysTarget, this ) == AIA_Friendly && enemysTarget.isPlayerFollower ) { setIsThreatened = true; break; } } } } for( i = actors.Size()-1; i>=0; i-=1 ) { if ( ( !actors[i].IsAlive() && !finishableEnemiesList.Contains( actors[i] ) ) || actors[i].IsKnockedUnconscious() || this.GetUsedVehicle() == actors[i] || !actors[i].CanBeTargeted() ) { actors.EraseFast(i); } else if ( !IsThreatened() ) { if ( !WasVisibleInScaledFrame( actors[i], 1.f, 1.f ) ) actors.EraseFast(i); } } } else if ( moveTarget && IsThreat( moveTarget ) ) setIsThreatened = true; else setIsThreatened = false; if ( setIsThreatened ) { enemyCollectionDist = 50.f; SetIsThreatened( true ); } else { if ( IsThreatened() ) AddTimer( 'finishableEnemiesList', 1.f ); enemyCollectionDist = findMoveTargetDistMax; SetIsThreatened( false ); } moveTargets = actors; potentialMoveTargets = moveTargets; if ( !moveTarget ) enableStrafe = false; if ( potentialMoveTargets.Size() > 0 ) { for ( i = 0; i < potentialMoveTargets.Size(); i += 1 ) { if ( potentialMoveTargets[i].CanBeStrafed() ) enableStrafe = true; if ( !potentialMoveTargets[i].GetGameplayVisibility() ) moveTargetDists.PushBack( 100.f ); else moveTargetDists.PushBack( VecDistance( potentialMoveTargets[i].GetNearestPointInPersonalSpace( GetWorldPosition() ), GetWorldPosition() ) ); if ( canFindPathEnemiesList.Contains( potentialMoveTargets[i] ) ) { moveTargetCanPathFinds.PushBack( true ); aPotentialMoveTargetCanFindPath = true; } else { moveTargetCanPathFinds.PushBack( false ); } } if ( aPotentialMoveTargetCanFindPath ) { for ( i = moveTargetCanPathFinds.Size()-1 ; i >= 0; i-=1 ) { if ( !moveTargetCanPathFinds[i] ) { moveTargetCanPathFinds.EraseFast(i); potentialMoveTargets.EraseFast(i); moveTargetDists.EraseFast(i); } } } if ( moveTargetDists.Size() > 0 ) newMoveTarget = potentialMoveTargets[ ArrayFindMinF( moveTargetDists ) ]; } if ( newMoveTarget && newMoveTarget != moveTarget ) { if ( moveTarget ) { playerToNewMoveTargetDist = VecDistance( newMoveTarget.GetNearestPointInPersonalSpace( GetWorldPosition() ), GetWorldPosition() ); playerToMoveTargetDist = VecDistance( moveTarget.GetNearestPointInPersonalSpace( GetWorldPosition() ), GetWorldPosition() ); wasVisibleInFullFrame = WasVisibleInScaledFrame( moveTarget, 1.f, 1.f ) ; if ( !IsThreat( moveTarget ) || !wasVisibleInFullFrame || !IsEnemyVisible( moveTarget ) || ( !moveTarget.IsAlive() && !finishableEnemiesList.Contains( moveTarget ) ) || !moveTarget.GetGameplayVisibility() || ( moveTarget.IsAlive() && moveTarget.IsKnockedUnconscious() ) || ( wasVisibleInFullFrame && IsEnemyVisible( moveTarget ) && playerToNewMoveTargetDist < playerToMoveTargetDist - 0.25f ) ) { SetMoveTarget( newMoveTarget ); } } else SetMoveTarget( newMoveTarget ); } if ( !IsThreatened() ) { if ( moveTarget && ( ( !moveTarget.IsAlive() && !finishableEnemiesList.Contains( moveTarget ) ) || !WasVisibleInScaledFrame( moveTarget, 0.8f, 1.f ) || VecDistance( moveTarget.GetWorldPosition(), this.GetWorldPosition() ) > theGame.params.MAX_THROW_RANGE ) ) { confirmEmptyMoveTarget = true; newEmptyMoveTargetTimer = 0.f; } } else if ( moveTarget && ( IsThreat( moveTarget ) || finishableEnemiesList.Contains( moveTarget ) ) ) { if ( !IsEnemyVisible( moveTarget ) ) { confirmEmptyMoveTarget = true; newEmptyMoveTargetTimer = 5.f; } else SetMoveTarget( moveTarget ); } else if ( IsInCombat() ) { confirmEmptyMoveTarget = true; newEmptyMoveTargetTimer = 1.0f; } if ( confirmEmptyMoveTarget ) { if ( newEmptyMoveTargetTimer < emptyMoveTargetTimer ) { bIsConfirmingEmptyTarget = false; emptyMoveTargetTimer = newEmptyMoveTargetTimer; } ConfirmEmptyMoveTarget( newEmptyMoveTargetTimer ); } } else SetIsThreatened( false ); if ( IsThreatened() && !IsInFistFightMiniGame() ) theGame.GetBehTreeReactionManager().CreateReactionEventIfPossible( this, 'CombatNearbyAction', 5.0, 18.0f, -1.f, -1, true ); else theGame.GetBehTreeReactionManager().RemoveReactionEvent( this, 'CombatNearbyAction'); theSound.SoundParameter( "monster_count", hostileMonsters.Size() ); } private function ConfirmEmptyMoveTarget( timeDelta : float ) { if ( !bIsConfirmingEmptyTarget ) { bIsConfirmingEmptyTarget = true; AddTimer( 'ConfirmEmptyTargetTimer', timeDelta ); } } private timer function ConfirmEmptyTargetTimer( time : float , id : int) { SetMoveTarget( NULL ); } var isInCombatReason : int; var canFindPathToEnemy : bool; var combatModeEnt : CEntity; var navDist : float; var directDist : float; var reachableEnemyWasTooFar : bool; var reachableEnemyWasTooFarTimeStamp : float; var reachablilityFailed : bool; var reachablilityFailedTimeStamp : float; public function ShouldEnableCombat( out unableToPathFind : bool, forceCombatMode : bool ) : bool { var shouldFindPathToNPCs : bool; var playerToTargetDist : float; var canFindPathToTarget : bool; var moveTargetNPC : CNewNPC; var currentTime : float; var currentTime2 : float; var isReachableEnemyTooFar : bool; var reachableEnemyWasTooFarTimeStampDelta : float; var reachablilityFailedTimeStampDelta : float; var currentTimeTemp : float; if ( forceCombatMode && isSnappedToNavMesh ) return true; if ( !IsThreatened() ) { reachableEnemyWasTooFar = false; reachablilityFailed = false; isInCombatReason = 0; return false; } if( thePlayer.substateManager.GetStateCur() != 'CombatExploration' && !thePlayer.substateManager.CanChangeToState( 'CombatExploration' ) && thePlayer.substateManager.GetStateCur() != 'Ragdoll' ) { reachableEnemyWasTooFar = false; reachablilityFailed = false; isInCombatReason = 0; return false; } if ( moveTarget ) { canFindPathToEnemy = CanFindPathToTarget( unableToPathFind ); currentTimeTemp = EngineTimeToFloat( theGame.GetEngineTime() ); if ( canFindPathToEnemy ) isReachableEnemyTooFar = IsReachableEnemyTooFar(); if ( IsInCombat() ) { if ( canFindPathToEnemy ) { if ( forceCombatMode ) return true; reachablilityFailed = false; reachablilityFailedTimeStamp = currentTimeTemp; if ( reachableEnemyWasTooFar ) { if ( isReachableEnemyTooFar ) { currentTime = currentTimeTemp; if ( GetIsSprinting() ) reachableEnemyWasTooFarTimeStampDelta = 0.f; else reachableEnemyWasTooFarTimeStampDelta = 3.f; if ( currentTime > reachableEnemyWasTooFarTimeStamp + reachableEnemyWasTooFarTimeStampDelta ) { isInCombatReason = 0; unableToPathFind = true; return false; } } else reachableEnemyWasTooFar = false; } else { if ( isReachableEnemyTooFar ) { reachableEnemyWasTooFar = true; reachableEnemyWasTooFarTimeStamp = currentTimeTemp; } else reachableEnemyWasTooFar = false; } return true; } else { reachableEnemyWasTooFar = false; reachableEnemyWasTooFarTimeStamp = currentTimeTemp; if ( reachablilityFailed ) { if ( IsEnemyTooHighToReach() ) reachablilityFailedTimeStampDelta = 1.f; else reachablilityFailedTimeStampDelta = 5.f; currentTime2 = currentTimeTemp; if ( currentTime2 > reachablilityFailedTimeStamp + reachablilityFailedTimeStampDelta ) { unableToPathFind = true; return false; } } else { reachablilityFailed = true; reachablilityFailedTimeStamp = currentTimeTemp; } return true; } } else if ( canFindPathToEnemy ) { if ( forceCombatMode ) { reachableEnemyWasTooFar = false; return true; } reachablilityFailed = false; reachablilityFailedTimeStamp = currentTimeTemp; moveTargetNPC = (CNewNPC)moveTarget; playerToTargetDist = VecDistance( moveTarget.GetWorldPosition(), this.GetWorldPosition() ); if ( reachableEnemyWasTooFar && ( isReachableEnemyTooFar || !theGame.GetWorld().NavigationLineTest( this.GetWorldPosition(), moveTarget.GetWorldPosition(), 0.4f ) ) ) { isInCombatReason = 0; return false; } else if ( playerToTargetDist <= findMoveTargetDistMin ) isInCombatReason = 1; else if ( ( moveTargetNPC.GetCurrentStance() == NS_Fly || moveTargetNPC.IsRanged() ) && hostileEnemies.Contains( moveTarget ) ) isInCombatReason = 2; else { isInCombatReason = 0; return false; } reachableEnemyWasTooFar = false; return true; } } else { reachableEnemyWasTooFar = false; reachablilityFailed = false; } isInCombatReason = 0; return false; } private function CanFindPathToTarget( out unableToPathFind : bool, optional forcedTarget : CNewNPC ) : bool { var moveTargetNPC : CNewNPC; var moveTargetsTemp : array; var i : int; var safeSpotTolerance : float; var ent : CEntity; moveTargetsTemp = moveTargets; for ( i = 0; i < moveTargetsTemp.Size(); i += 1 ) { moveTargetNPC = (CNewNPC)moveTargetsTemp[i]; if ( moveTargetNPC && moveTargetNPC.GetCurrentStance() == NS_Fly ) { isInCombatReason = 2; return true; } } switch ( navQuery.GetLastOutput( 0.4 ) ) { case EAsyncTastResult_Failure: { isInCombatReason = 0; return false; } case EAsyncTastResult_Success: { ent = navQuery.GetOutputClosestEntity(); if ( ent ) combatModeEnt = moveTarget; navDist = navQuery.GetOutputClosestDistance(); isInCombatReason = 1; return true; } case EAsyncTastResult_Pending: { return canFindPathToEnemy; } case EAsyncTastResult_Invalidated: { if ( IsInCombat() ) { if ( IsEnemyTooHighToReach() ) safeSpotTolerance = 0.f; else safeSpotTolerance = 3.f; } else safeSpotTolerance = 0.f; switch( navQuery.TestActorsList( ENavigationReachability_Any, this, moveTargetsTemp, safeSpotTolerance, 75.0 ) ) { case EAsyncTastResult_Failure: { isInCombatReason = 0; return false; } case EAsyncTastResult_Success: { ent = navQuery.GetOutputClosestEntity(); if ( ent ) combatModeEnt = moveTarget; navDist = navQuery.GetOutputClosestDistance(); isInCombatReason = 1; return true; } case EAsyncTastResult_Pending: { return canFindPathToEnemy; } case EAsyncTastResult_Invalidated: { if ( IsInCombat() ) return true; else return false; } } } } } private function IsReachableEnemyTooFar() : bool { var navDistLimit : float = findMoveTargetDist; var navDistDivisor : float = 2.f; var playerToTargetVector : Vector; directDist = VecDistance( combatModeEnt.GetWorldPosition(), thePlayer.GetWorldPosition() ); playerToTargetVector = this.GetWorldPosition() - combatModeEnt.GetWorldPosition(); if ( playerMode.GetForceCombatMode() || isInCombatReason == 2 ) return false; if ( ( playerToTargetVector.Z < 0.5 && navDist > navDistLimit && directDist < navDist/navDistDivisor ) ) return true; else return false; } private function IsEnemyTooHighToReach() : bool { var playerToTargetVector : Vector; playerToTargetVector = this.GetWorldPosition() - combatModeEnt.GetWorldPosition(); if ( playerToTargetVector.Z < -0.5f && !theGame.GetWorld().NavigationLineTest( this.GetWorldPosition(), combatModeEnt.GetWorldPosition(), 0.4f ) ) return true; else return false; } public function LockToMoveTarget( lockTime : float ) { } private timer function DisableLockToMoveTargetTimer( time : float , id : int) { if ( !this.IsActorLockedToTarget() ) { SetMoveTargetChangeAllowed( true ); } } public function SetMoveTargetChangeAllowed( flag : bool ) { } public function IsMoveTargetChangeAllowed() : bool { return bMoveTargetChangeAllowed; } public function SetMoveTarget( actor : CActor ) { if ( !actor && ForceCombatModeOverride() ) return; if ( IsMoveTargetChangeAllowed() && moveTarget != actor ) { moveTarget = actor; bIsConfirmingEmptyTarget = false; RemoveTimer( 'ConfirmEmptyTargetTimer' ); if ( !moveTarget ) SetScriptMoveTarget( moveTarget ); } } private var isThreatened : bool; protected function SetIsThreatened( flag : bool ) { var allowSetIsThreatened : bool; allowSetIsThreatened = true; if ( ForceCombatModeOverride() ) { if ( flag || !moveTarget ) allowSetIsThreatened = true; else allowSetIsThreatened = false; } if ( allowSetIsThreatened ) { isThreatened = flag; } } public function ForceCombatModeOverride() : bool { if( this.GetPlayerMode().GetForceCombatMode() && canFindPathToEnemy && theGame.GetGlobalAttitude( GetBaseAttitudeGroup(), moveTarget.GetBaseAttitudeGroup() ) == AIA_Hostile ) return true; else return false; } public function IsThreatened() : bool { return isThreatened; } public function EnableFindTarget( flag : bool ) { var target : CActor; if( IsActorLockedToTarget() ) { target = GetTarget(); if ( target && target.IsAlive() ) bCanFindTarget = flag; else bCanFindTarget = true; } else bCanFindTarget = flag; } public function UpdateDisplayTarget( optional forceUpdate : bool, optional forceNullActor : bool ) { var hud : CR4ScriptedHud; var tempTarget : CGameplayEntity; var angleDist1 : float; var angleDist2 : float; var nonActorTargetMult : float; var combatActionType : int; var currTarget : CActor; var interactionTarget : CInteractionComponent; var heading : float; if(theGame.IsDialogOrCutscenePlaying()) { currentSelectedDisplayTarget = NULL; if ( displayTarget ) ConfirmDisplayTarget( NULL ); return; } if ( forceNullActor ) currTarget = NULL; else currTarget = GetTarget(); currentSelectedDisplayTarget = currTarget; if ( currTarget && !currTarget.IsTargetableByPlayer() ) { currentSelectedDisplayTarget = NULL; ConfirmDisplayTarget( currentSelectedDisplayTarget ); return; } nonActorTargetMult = 1.25; hud = (CR4ScriptedHud)theGame.GetHud(); if ( !IsThreatened() ) { if ( !bLAxisReleased || lastAxisInputIsMovement ) { if ( currTarget ) angleDist1 = AbsF( AngleDistance( this.GetHeading(), VecHeading( currTarget.GetWorldPosition() - this.GetWorldPosition() ) ) ); else angleDist1 = 360; if ( nonActorTarget ) angleDist2 = AbsF( AngleDistance( this.GetHeading(), VecHeading( nonActorTarget.GetWorldPosition() - this.GetWorldPosition() ) ) ); else angleDist2 = 360; } else { if ( currTarget ) angleDist1 = AbsF( AngleDistance( theCamera.GetCameraHeading(), VecHeading( currTarget.GetWorldPosition() - theCamera.GetCameraPosition() ) ) ); else angleDist1 = 360; if ( nonActorTarget ) angleDist2 = AbsF( AngleDistance( theCamera.GetCameraHeading(), VecHeading( nonActorTarget.GetWorldPosition() - theCamera.GetCameraPosition() ) ) ); else angleDist2 = 360; } } else { if ( !bLAxisReleased ) { if ( ShouldUsePCModeTargeting() ) { if ( currTarget ) angleDist1 = AbsF( AngleDistance( theCamera.GetCameraHeading(), VecHeading( currTarget.GetWorldPosition() - theCamera.GetCameraPosition() ) ) ); else angleDist1 = 360; if ( nonActorTarget && IsInCombatAction() ) { angleDist2 = nonActorTargetMult * AbsF( AngleDistance( theCamera.GetCameraHeading(), VecHeading( nonActorTarget.GetWorldPosition() - theCamera.GetCameraPosition() ) ) ); } else angleDist2 = 360; } else { if ( currTarget ) angleDist1 = AbsF( AngleDistance( rawPlayerHeading, VecHeading( currTarget.GetWorldPosition() - this.GetWorldPosition() ) ) ); else angleDist1 = 360; if ( nonActorTarget && IsInCombatAction() ) { angleDist2 = nonActorTargetMult * AbsF( AngleDistance( rawPlayerHeading, VecHeading( nonActorTarget.GetWorldPosition() - this.GetWorldPosition() ) ) ); } else angleDist2 = 360; } } else { angleDist1 = 0; angleDist2 = 360; } } if ( angleDist1 < angleDist2 ) tempTarget = currTarget; else tempTarget = nonActorTarget; if ( slideTarget && IsInCombatAction() ) { combatActionType = (int)this.GetBehaviorVariable( 'combatActionType' ); if ( combatActionType == (int)CAT_Attack || ( combatActionType == (int)CAT_SpecialAttack && this.GetBehaviorVariable( 'playerAttackType' ) == 1.f ) || ( combatActionType == (int)CAT_ItemThrow ) || ( combatActionType == (int)CAT_CastSign && !IsCurrentSignChanneled() ) || ( combatActionType == (int)CAT_CastSign && IsCurrentSignChanneled() && GetCurrentlyCastSign() == ST_Axii ) || ( combatActionType == (int)CAT_CastSign && IsCurrentSignChanneled() && GetCurrentlyCastSign() == ST_Igni ) || combatActionType == (int)CAT_Dodge || combatActionType == (int)CAT_Roll ) { if ( combatActionType == (int)CAT_CastSign && GetCurrentlyCastSign() == ST_Igni && !IsCombatMusicEnabled() ) currentSelectedDisplayTarget = tempTarget; else currentSelectedDisplayTarget = slideTarget; } else currentSelectedDisplayTarget = tempTarget; } else if ( slideTarget && this.rangedWeapon && this.rangedWeapon.GetCurrentStateName() != 'State_WeaponWait' && this.playerAiming.GetCurrentStateName() == 'Waiting' ) currentSelectedDisplayTarget = slideTarget; else currentSelectedDisplayTarget = tempTarget; interactionTarget = theGame.GetInteractionsManager().GetActiveInteraction(); if ( interactionTarget && !IsThreatened() && !( this.IsCastingSign() && this.IsCurrentSignChanneled() ) ) { tempTarget = (CGameplayEntity)interactionTarget.GetEntity(); if ( tempTarget && tempTarget != this.GetUsedVehicle() ) { currentSelectedDisplayTarget = tempTarget; SetDisplayTarget( currentSelectedDisplayTarget ); } } if ( (CActor)currentSelectedDisplayTarget && !((CActor)currentSelectedDisplayTarget).GetGameplayVisibility() ) { currentSelectedDisplayTarget = NULL; } if ( displayTarget != currentSelectedDisplayTarget ) { if ( forceUpdate ) SetDisplayTarget( currentSelectedDisplayTarget ); else ConfirmDisplayTarget( currentSelectedDisplayTarget ); } } private var bConfirmDisplayTargetTimerEnabled : bool; private var displayTargetToConfirm : CGameplayEntity; private var currentSelectedDisplayTarget : CGameplayEntity; private function ConfirmDisplayTarget( targetToConfirm : CGameplayEntity ) { if ( targetToConfirm != displayTarget ) { displayTargetToConfirm = targetToConfirm; if( !bConfirmDisplayTargetTimerEnabled ) { bConfirmDisplayTargetTimerEnabled = true; if ( targetToConfirm ) AddTimer( 'ConfirmDisplayTargetTimer', 0.1f ); else AddTimer( 'ConfirmDisplayTargetTimer', 0.f ); } } } private timer function ConfirmDisplayTargetTimer( time : float, optional id : int) { if ( displayTargetToConfirm == currentSelectedDisplayTarget ) SetDisplayTarget( displayTargetToConfirm ); bConfirmDisplayTargetTimerEnabled = false; } protected function SetDisplayTarget( e : CGameplayEntity ) { var displayTargetActor : CActor; if ( e != displayTarget ) { displayTarget = e; displayTargetActor = (CActor)displayTarget; SetPlayerCombatTarget( displayTargetActor ); if ( displayTargetActor && !displayTargetActor.IsTargetableByPlayer()) { isDisplayTargetTargetable = false; } else if ( !displayTargetActor && displayTarget != nonActorTarget ) { isDisplayTargetTargetable = false; } else { isDisplayTargetTargetable = true; } } } public function GetDisplayTarget() : CGameplayEntity { return displayTarget; } private var isDisplayTargetTargetable : bool; public function IsDisplayTargetTargetable() : bool { return isDisplayTargetTargetable; } public var radialSlots : array; public function EnableRadialSlots( enable : bool, slotNames : array ) { var hud : CR4ScriptedHud; var module : CR4HudModuleRadialMenu; var i : int; hud = (CR4ScriptedHud)theGame.GetHud(); module = (CR4HudModuleRadialMenu)hud.GetHudModule("RadialMenuModule"); for(i=0; i; var sourceToTargetDists : array; var i : int; var targetingInfo : STargetingInfo; targets = GetMoveTargets(); if ( targets.Size() > 0 ) { targetingInfo.source = this; targetingInfo.canBeTargetedCheck = true; targetingInfo.coneCheck = true; targetingInfo.coneHalfAngleCos = CosF( Deg2Rad( coneAngle * 0.5f ) ); targetingInfo.coneDist = coneDist; targetingInfo.coneHeadingVector = coneHeading; targetingInfo.distCheck = true; targetingInfo.invisibleCheck = true; targetingInfo.navMeshCheck = true; targetingInfo.inFrameCheck = false; targetingInfo.frameScaleX = 1.f; targetingInfo.frameScaleY = 1.f; targetingInfo.knockDownCheck = false; targetingInfo.knockDownCheckDist = 1.5f; targetingInfo.rsHeadingCheck = false; targetingInfo.rsHeadingLimitCos = 1.0f; for( i = targets.Size() - 1; i >= 0; i -= 1 ) { targetingInfo.targetEntity = targets[i]; if ( !IsEntityTargetable( targetingInfo ) ) targets.Erase( i ); } for ( i = 0; i < targets.Size(); i += 1 ) sourceToTargetDists.PushBack( VecDistance( source.GetWorldPosition(), targets[i].GetWorldPosition() ) ); if(sourceToTargetDists.Size() > 0) newLockTarget = targets[ ArrayFindMinF( sourceToTargetDists ) ]; else newLockTarget = NULL; } return targets.Size() > 0; } public function GetScreenSpaceLockTarget( sourceEnt : CGameplayEntity, coneAngle, coneDist, coneHeading : float, optional inFrameCheck : bool ) : CActor { var source : CActor; var sourcePos, targetPos : Vector; var targets : array; var sourceToTargetDists : array; var sourceCoord : Vector; var targetCoord : Vector; var i : int; var angleDiff : float; var sourceToTargetHeading : float; var sourceToTargetDist : float; var size : float; var targetingDist : float; var targetingInfo : STargetingInfo; var temp : int; source = (CActor)sourceEnt; targets = GetMoveTargets(); if ( this.IsPCModeEnabled() ) { if ( ( coneHeading > -45.f && coneHeading < 45.f ) || coneHeading > 135.f || coneHeading < -135.f ) { if ( coneHeading > 0 ) coneHeading = 180 - coneHeading; else coneHeading = 180 + coneHeading; } } for( i = targets.Size() - 1; i >= 0; i -= 1 ) { if ( ( !targets[i].GetGameplayVisibility() || !IsThreat( targets[i] ) || !IsEnemyVisible( targets[i] ) || !this.CanBeTargetedIfSwimming( targets[i] ) ) && ( !IsCastingSign() || GetCurrentlyCastSign() != ST_Axii ) ) targets.Erase(i); } if ( source ) { temp = source.GetTorsoBoneIndex(); if ( temp < 0 ) sourcePos = source.GetWorldPosition(); else sourcePos = MatrixGetTranslation( source.GetBoneWorldMatrixByIndex( source.GetTorsoBoneIndex() ) ); } else sourcePos = sourceEnt.GetWorldPosition(); theCamera.WorldVectorToViewRatio( sourcePos, sourceCoord.X , sourceCoord.Y ); targetingDist = softLockDistVehicle; if ( targets.Size() > 0 ) { targetingInfo.source = this; targetingInfo.canBeTargetedCheck = true; targetingInfo.coneCheck = false; targetingInfo.coneHalfAngleCos = 0.86602540378f; targetingInfo.coneDist = targetingDist; targetingInfo.coneHeadingVector = Vector( 0.0f, 1.0f, 0.0f ); targetingInfo.distCheck = true; targetingInfo.invisibleCheck = true; targetingInfo.navMeshCheck = false; if ( inFrameCheck ) targetingInfo.inFrameCheck = true; else targetingInfo.inFrameCheck = false; targetingInfo.frameScaleX = 1.f; targetingInfo.frameScaleY = 1.f; targetingInfo.knockDownCheck = false; targetingInfo.knockDownCheckDist = softLockDist; if ( bRAxisReleased ) targetingInfo.rsHeadingCheck = false; else targetingInfo.rsHeadingCheck = true; targetingInfo.rsHeadingLimitCos = -0.5f; for( i = targets.Size() - 1; i >= 0; i -= 1 ) { temp = targets[i].GetTorsoBoneIndex(); if ( temp < 0 ) targetPos = targets[i].GetWorldPosition(); else targetPos = MatrixGetTranslation( targets[i].GetBoneWorldMatrixByIndex( targets[i].GetTorsoBoneIndex() ) ); theCamera.WorldVectorToViewRatio( targetPos, targetCoord.X, targetCoord.Y ); sourceToTargetHeading = VecHeading( targetCoord - sourceCoord ); angleDiff = AbsF( AngleDistance( coneHeading, sourceToTargetHeading ) ); targetingInfo.targetEntity = targets[i]; if ( !IsEntityTargetable( targetingInfo ) ) targets.Erase( i ); else if ( !bRAxisReleased && angleDiff > ( coneAngle * 0.5 ) ) targets.Erase( i ); else if ( targets[i] == sourceEnt ) targets.Erase( i ); } } size = targets.Size(); if ( size > 0 ) { for ( i = 0; i < targets.Size(); i += 1 ) { temp = targets[i].GetTorsoBoneIndex(); if ( temp < 0 ) targetPos = targets[i].GetWorldPosition(); else targetPos = MatrixGetTranslation( targets[i].GetBoneWorldMatrixByIndex( targets[i].GetTorsoBoneIndex() ) ); theCamera.WorldVectorToViewRatio( targetPos, targetCoord.X, targetCoord.Y ); sourceToTargetHeading = AbsF( VecHeading( targetCoord - sourceCoord ) ); angleDiff = AngleDistance( 180, sourceToTargetHeading ); sourceToTargetDist = VecDistance2D( sourceCoord, targetCoord ); sourceToTargetDists.PushBack( SinF( Deg2Rad( angleDiff ) ) * sourceToTargetDist ); } } if ( targets.Size() > 0 ) return targets[ ArrayFindMinF( sourceToTargetDists ) ]; else return NULL; } public function IsEntityTargetable( out info : STargetingInfo, optional usePrecalcs : bool ) : bool { var playerHasBlockingBuffs : bool; var sourceActor : CActor; var targetEntity : CEntity; var targetActor : CActor; var targetNPC : CNewNPC; var sourcePosition : Vector; var targetPosition : Vector; var direction : Vector; var sourceToTargetDist : float; var sourceCapsuleRadius : float; var mpac : CMovingPhysicalAgentComponent; var coneDistSq : float; var knockDownCheckDistSq : float; var sourceToTargetAngleDist : float; var b : bool; var infoSourceWorldPos : Vector; var infoTargetWorldPos : Vector; var finishEnabled : bool; if ( usePrecalcs ) { playerHasBlockingBuffs = targetingIn.playerHasBlockingBuffs; } else { playerHasBlockingBuffs = thePlayer.HasBuff( EET_Confusion ) || thePlayer.HasBuff( EET_Hypnotized ) || thePlayer.HasBuff( EET_Blindness ) || thePlayer.HasBuff( EET_WraithBlindness ); } if ( playerHasBlockingBuffs ) { return false; } sourceActor = info.source; targetEntity = info.targetEntity; if ( !sourceActor || !targetEntity ) { return false; } targetActor = (CActor)targetEntity; if ( info.canBeTargetedCheck && !targetActor.CanBeTargeted() ) { return false; } if ( info.invisibleCheck && !targetActor.GetGameplayVisibility() ) { return false; } sourcePosition = sourceActor.GetWorldPosition(); targetPosition = targetEntity.GetWorldPosition(); if ( targetActor ) { { targetNPC = (CNewNPC)targetActor; if ( targetNPC ) { if ( targetNPC.IsHorse() && !targetNPC.GetHorseComponent().IsDismounted() ) { return false; } } } } if ( info.distCheck || info.knockDownCheck ) { if ( usePrecalcs ) { if ( targetActor ) { sourceToTargetDist = Distance2DBetweenCapsuleAndPoint( targetActor, sourceActor ) - targetingPrecalcs.playerRadius; } else { sourceToTargetDist = VecDistance2D( sourcePosition, targetPosition ) - targetingPrecalcs.playerRadius; } } else { if ( targetActor ) { sourceToTargetDist = Distance2DBetweenCapsules( sourceActor, targetActor ); } else { sourceToTargetDist = Distance2DBetweenCapsuleAndPoint( sourceActor, targetEntity ); } } } if ( info.distCheck ) { if ( sourceToTargetDist >= info.coneDist ) { return false; } } if ( info.coneCheck || info.rsHeadingCheck ) { direction = VecNormalize2D( targetPosition - sourcePosition ); } if ( info.coneCheck ) { if ( VecDot2D( direction, info.coneHeadingVector ) < info.coneHalfAngleCos ) { return false; } } if ( info.rsHeadingCheck ) { if ( usePrecalcs ) { if ( VecDot2D( direction, targetingIn.lookAtDirection ) < info.rsHeadingLimitCos ) { return false; } } else { if ( VecDot2D( direction, VecNormalize2D( GetLookAtPosition() - sourcePosition ) ) < info.rsHeadingLimitCos ) { return false; } } } if ( info.inFrameCheck && !WasVisibleInScaledFrame( targetEntity, info.frameScaleX, info.frameScaleY ) ) { return false; } if ( info.navMeshCheck && !IsSwimming() ) { sourceCapsuleRadius = 0.1f; if ( usePrecalcs ) { sourceCapsuleRadius = targetingPrecalcs.playerRadius; } else { mpac = (CMovingPhysicalAgentComponent)sourceActor.GetMovingAgentComponent(); if ( mpac ) { sourceCapsuleRadius = mpac.GetCapsuleRadius(); } } if ( !theGame.GetWorld().NavigationLineTest( sourcePosition, targetPosition, sourceCapsuleRadius ) ) { return false; } } if ( info.knockDownCheck ) { if ( targetActor && !targetActor.IsAlive() ) { finishEnabled = targetActor.GetComponent( 'Finish' ).IsEnabled(); if ( finishEnabled ) { if ( finishableEnemiesList.Contains( targetActor ) ) { if ( sourceToTargetDist >= info.knockDownCheckDist ) { return false; } } } } } return true; } public function CanBeTargetedIfSwimming( actor : CActor, optional usePrecalcs : bool ) : bool { var subDepth : float; var isDiving : bool; if ( !actor ) { return false; } if ( usePrecalcs ) { isDiving = targetingIn.isDiving; } else { isDiving = IsSwimming() && OnCheckDiving(); } subDepth = ((CMovingPhysicalAgentComponent)actor.GetMovingAgentComponent()).GetSubmergeDepth(); if ( isDiving ) { return ( subDepth < -1.0f ); } else { return ( subDepth >= -1.0f ); } } private function FilterActors( out targets : array, out onlyThreatsReturned : bool, optional usePrecalcs : bool ) { var i : int; var size : int; var foundThreat : bool; var foundNonThreat : bool; var threatsCount : int; var tmpActor : CActor; foundThreat = false; foundNonThreat = false; size = targets.Size(); i = 0; threatsCount = 0; for ( i = 0; i < size; i+=1 ) { if( IsThreat( targets[ i ], usePrecalcs ) ) { foundThreat = true; if ( i != threatsCount ) { tmpActor = targets[ i ]; targets[ i ] = targets[ threatsCount ]; targets[ threatsCount ] = tmpActor; } threatsCount += 1; } else { foundNonThreat = true; } } if ( foundThreat ) { onlyThreatsReturned = true; if ( foundNonThreat ) { targets.Resize( threatsCount ); } } } private function InternalFindTargetsInCone( out targets : array< CActor >, out outHeadingVector : Vector, optional usePrecalcs : bool ) { var size, i : int; var coneHalfAngleDot : float; var coneHeading : float; var coneHeadingVector : Vector; var position : Vector; var direction : Vector; var onlyThreatTargetsFound : bool; targets.Clear(); GetVisibleEnemies( targets ); for( i = 0; i < finishableEnemiesList.Size() ; i+=1 ) { if ( !targets.Contains( finishableEnemiesList[i] ) ) { targets.PushBack( finishableEnemiesList[i] ); } } onlyThreatTargetsFound = false; FilterActors( targets, onlyThreatTargetsFound, true ); if ( IsCombatMusicEnabled() && targets.Size() > 0 && !onlyThreatTargetsFound && !IsThreat( targets[0], usePrecalcs ) ) { targets.Clear(); } coneHeading = 0.0f; coneHalfAngleDot = 0.0f; if ( ( orientationTarget == OT_Camera ) || ( orientationTarget == OT_CameraOffset ) ) { if ( usePrecalcs ) { coneHeading = targetingPrecalcs.cameraHeading; } else { coneHeading = theGame.GetGameCamera().GetHeading(); } coneHalfAngleDot = 0.5f; } else { if ( IsSwimming() ) { if ( usePrecalcs ) { coneHeading = targetingPrecalcs.cameraHeading; } else { coneHeading = theGame.GetGameCamera().GetHeading(); } coneHalfAngleDot = 0.17364817766f; } else if ( bLAxisReleased ) { if( IsInCombatAction() ) { coneHeading = GetCombatActionHeading(); } else { if ( ShouldUsePCModeTargeting() ) coneHeading = theGame.GetGameCamera().GetHeading(); else coneHeading = cachedRawPlayerHeading; } if ( IsInCombat() ) { if ( ShouldUsePCModeTargeting() ) coneHalfAngleDot = -1; else coneHalfAngleDot = 0.17364817766f; } else { coneHalfAngleDot = -1.0f; } } else { if( IsInCombatAction() ) { coneHeading = GetCombatActionHeading(); } else { if ( ShouldUsePCModeTargeting() ) coneHeading = theGame.GetGameCamera().GetHeading(); else coneHeading = cachedRawPlayerHeading; } if ( ShouldUsePCModeTargeting() ) coneHalfAngleDot = -1; else coneHalfAngleDot = 0.17364817766f; } coneHeadingVector = VecFromHeading( coneHeading ); position = this.GetWorldPosition(); for ( i = targets.Size() - 1; i >= 0; i -= 1 ) { if ( !targets[i] ) { targets.EraseFast(i); continue; } direction = VecNormalize2D( targets[i].GetWorldPosition() - position ); if ( VecDot2D( coneHeadingVector, direction ) < coneHalfAngleDot ) { targets.EraseFast( i ); } } } outHeadingVector = coneHeadingVector; } function InitTargeting() { var consts : SR4PlayerTargetingConsts; if ( !targeting ) { targeting = new CR4PlayerTargeting in this; } if ( targeting ) { consts.softLockDistance = this.softLockDist; consts.softLockFrameSize = this.softLockFrameSize; targeting.SetConsts( consts ); } } function PrepareTargetingIn( actionCheck : bool, bufferActionType : EBufferActionType, actionInput : bool ) { var coneDist : float; if ( actionCheck && bufferActionType == EBAT_ItemUse ) { coneDist = findMoveTargetDist; } else if ( IsSwimming() ) { coneDist = theGame.params.MAX_THROW_RANGE; } else if ( ( GetPlayerCombatStance() == PCS_AlertNear ) && ( ( playerMoveType == PMT_Walk ) || ( playerMoveType == PMT_Idle ) ) ) { coneDist = softLockDist; } else { coneDist = findMoveTargetDist; } targetingIn.canFindTarget = this.bCanFindTarget; targetingIn.playerHasBlockingBuffs = thePlayer.HasBuff( EET_Confusion ) || thePlayer.HasBuff( EET_Hypnotized ) || thePlayer.HasBuff( EET_Blindness ) || thePlayer.HasBuff( EET_WraithBlindness ); targetingIn.isHardLockedToTarget = this.IsHardLockEnabled(); targetingIn.isActorLockedToTarget = this.IsActorLockedToTarget(); targetingIn.isCameraLockedToTarget = this.IsCameraLockedToTarget(); targetingIn.actionCheck = actionCheck; targetingIn.actionInput = actionInput; targetingIn.isInCombatAction = this.IsInCombatAction(); targetingIn.isLAxisReleased = this.bLAxisReleased; targetingIn.isLAxisReleasedAfterCounter = this.lAxisReleasedAfterCounter; targetingIn.isLAxisReleasedAfterCounterNoCA = this.lAxisReleasedAfterCounterNoCA; targetingIn.lastAxisInputIsMovement = this.lastAxisInputIsMovement; targetingIn.isAiming = this.playerAiming.GetCurrentStateName() == 'Aiming'; targetingIn.isSwimming = this.IsSwimming(); targetingIn.isDiving = this.IsSwimming() && OnCheckDiving(); targetingIn.isThreatened = this.IsThreatened(); targetingIn.isCombatMusicEnabled = this.IsCombatMusicEnabled(); targetingIn.isPcModeEnabled = this.IsPCModeEnabled(); targetingIn.isInParryOrCounter = this.isInParryOrCounter; targetingIn.shouldUsePcModeTargeting = this.ShouldUsePCModeTargeting(); targetingIn.bufferActionType = bufferActionType; targetingIn.orientationTarget = this.GetOrientationTarget(); targetingIn.coneDist = coneDist; targetingIn.findMoveTargetDist = this.findMoveTargetDist; targetingIn.cachedRawPlayerHeading = this.cachedRawPlayerHeading; targetingIn.combatActionHeading = this.GetCombatActionHeading(); targetingIn.rawPlayerHeadingVector = VecFromHeading( this.rawPlayerHeading ); targetingIn.lookAtDirection = VecNormalize2D( this.GetLookAtPosition() - GetWorldPosition() ); targetingIn.moveTarget = this.moveTarget; targetingIn.aimingTarget = this.playerAiming.GetAimedTarget(); targetingIn.displayTarget = (CActor)this.displayTarget; targetingIn.finishableEnemies = this.finishableEnemiesList; targetingIn.hostileEnemies = this.hostileEnemies; targetingIn.defaultSelectionWeights = ProcessSelectionWeights(); } function ResetTargetingOut() { targetingOut.target = NULL; targetingOut.result = false; targetingOut.confirmNewTarget = false; targetingOut.forceDisableUpdatePosition = false; } function MakeFindTargetPrecalcs() { var mpac : CMovingPhysicalAgentComponent; targetingPrecalcs.playerPosition = thePlayer.GetWorldPosition(); targetingPrecalcs.playerHeading = thePlayer.GetHeading(); targetingPrecalcs.playerHeadingVector = thePlayer.GetHeadingVector(); targetingPrecalcs.playerHeadingVector.Z = 0; targetingPrecalcs.playerHeadingVector = VecNormalize2D( targetingPrecalcs.playerHeadingVector ); targetingPrecalcs.playerRadius = 0.5f; mpac = (CMovingPhysicalAgentComponent)thePlayer.GetMovingAgentComponent(); if ( mpac ) { targetingPrecalcs.playerRadius = mpac.GetCapsuleRadius(); } targetingPrecalcs.cameraPosition = theCamera.GetCameraPosition(); targetingPrecalcs.cameraDirection = theCamera.GetCameraDirection(); targetingPrecalcs.cameraHeadingVector = targetingPrecalcs.cameraDirection; targetingPrecalcs.cameraHeadingVector.Z = 0; targetingPrecalcs.cameraHeadingVector = VecNormalize2D( targetingPrecalcs.cameraHeadingVector ); targetingPrecalcs.cameraHeading = VecHeading( targetingPrecalcs.cameraHeadingVector ); } public function GetForceDisableUpdatePosition() : bool { return targetingOut.forceDisableUpdatePosition; } public function SetUseNativeTargeting( use : bool ) { useNativeTargeting = use; } protected function FindTarget( optional actionCheck : bool, optional action : EBufferActionType, optional actionInput : bool ) : CActor { if ( IsCombatMusicEnabled() && !IsInCombat() && reachableEnemyWasTooFar ) { playerMode.UpdateCombatMode(); } PrepareTargetingIn( actionCheck, action, actionInput ); if ( useNativeTargeting ) { targeting.BeginFindTarget( targetingIn ); targeting.FindTarget(); targeting.EndFindTarget( targetingOut ); } else { UpdateVisibleActors(); MakeFindTargetPrecalcs(); ResetTargetingOut(); FindTarget_Scripted(); } if ( targetingOut.result ) { if ( targetingOut.confirmNewTarget ) { ConfirmNewTarget( targetingOut.target ); } return targetingOut.target; } return NULL; } protected function FindTarget_Scripted() { var currentTarget : CActor; var newTarget : CActor; var selectedTarget : CActor; var displayTargetActor : CActor; var playerPosition : Vector; var playerHeadingVector : Vector; var cameraPosition : Vector; var cameraHeadingVector : Vector; var selectionHeadingVector : Vector; var targetingInfo : STargetingInfo; var selectionWeights : STargetSelectionWeights; var targets : array< CActor >; var isMoveTargetTargetable : bool; var targetChangeFromActionInput : bool; var retainCurrentTarget : bool; playerPosition = this.GetWorldPosition(); playerHeadingVector = targetingPrecalcs.playerHeadingVector; cameraPosition = theCamera.GetCameraPosition(); cameraHeadingVector = targetingPrecalcs.cameraHeadingVector; currentTarget = GetTarget(); if ( currentTarget ) { if ( IsHardLockEnabled() && currentTarget.IsAlive() && !currentTarget.IsKnockedUnconscious() ) { if ( VecDistanceSquared( playerPosition, currentTarget.GetWorldPosition() ) > 50.f * 50.0f ) { HardLockToTarget( false ); } else { targetingOut.target = currentTarget; targetingOut.result = true; return; } } GetVisualDebug().AddSphere('target', 1.0f, currentTarget.GetWorldPosition(), true, Color( 255, 255, 0 ), 1.0f ); } if ( bCanFindTarget && !IsActorLockedToTarget() ) { if ( !targetingIn.playerHasBlockingBuffs ) { InternalFindTargetsInCone( targets, selectionHeadingVector, true ); } targetingInfo.source = this; targetingInfo.canBeTargetedCheck = true; targetingInfo.coneCheck = false; targetingInfo.coneHalfAngleCos = 1.0f; targetingInfo.coneDist = targetingIn.coneDist; targetingInfo.distCheck = true; targetingInfo.invisibleCheck = true; targetingInfo.navMeshCheck = false; if ( ShouldUsePCModeTargeting() ) targetingInfo.inFrameCheck = false; else targetingInfo.inFrameCheck = true; targetingInfo.frameScaleX = 1.0f; targetingInfo.frameScaleY = 1.0f; targetingInfo.knockDownCheck = false; targetingInfo.knockDownCheckDist = 1.5f; targetingInfo.rsHeadingCheck = false; targetingInfo.rsHeadingLimitCos = 1.0f; if ( currentTarget ) { targetingInfo.targetEntity = currentTarget; if ( !IsEntityTargetable( targetingInfo, true ) ) { currentTarget = NULL; } if ( currentTarget && !CanBeTargetedIfSwimming( currentTarget, true ) ) { currentTarget = NULL; } } isMoveTargetTargetable = false; if ( moveTarget ) { if ( CanBeTargetedIfSwimming( moveTarget, true ) ) { targetingInfo.targetEntity = moveTarget; targetingInfo.coneDist = findMoveTargetDist; targetingInfo.inFrameCheck = false; if ( IsEntityTargetable( targetingInfo, true ) ) { isMoveTargetTargetable = true; } } } targetingInfo.coneDist = targetingIn.coneDist; if ( !targetingIn.playerHasBlockingBuffs ) { RemoveNonTargetable( targets, targetingInfo, selectionHeadingVector ); } newTarget = NULL; if ( this.playerAiming.GetCurrentStateName() == 'Aiming' ) { newTarget = this.playerAiming.GetAimedTarget(); if ( !newTarget ) { selectionWeights.angleWeight = 1.f; selectionWeights.distanceWeight = 0.f; selectionWeights.distanceRingWeight = 0.f; selectedTarget = SelectTarget( targets, false, cameraPosition, cameraHeadingVector, selectionWeights, true ); newTarget = selectedTarget; } } else if ( IsSwimming() ) { selectionWeights.angleWeight = 0.9f; selectionWeights.distanceWeight = 0.1f; selectionWeights.distanceRingWeight = 0.f; selectedTarget = SelectTarget( targets, true, cameraPosition, cameraHeadingVector, selectionWeights, true ); newTarget = selectedTarget; } else if ( IsThreatened() ) { if ( IsCameraLockedToTarget() ) { if ( currentTarget && !currentTarget.GetGameplayVisibility() ) { ForceSelectLockTarget(); } } displayTargetActor = (CActor)displayTarget; selectedTarget = SelectTarget( targets, true, playerPosition, selectionHeadingVector, targetingIn.defaultSelectionWeights, true ); if ( !selectedTarget ) { targetingOut.forceDisableUpdatePosition = true; } targetChangeFromActionInput = targetingIn.actionInput && !lAxisReleasedAfterCounter; if ( selectedTarget && ( !IsThreat( currentTarget, true ) || ShouldUsePCModeTargeting() || ( !IsInCombatAction() && !lAxisReleasedAfterCounterNoCA ) || targetChangeFromActionInput ) ) { newTarget = selectedTarget; } else if ( displayTargetActor && ( ( bLAxisReleased && !ShouldUsePCModeTargeting() )|| IsInCombatAction() ) && ( displayTargetActor.IsAlive() || finishableEnemiesList.Contains( displayTargetActor ) ) && displayTargetActor.GetGameplayVisibility() && ( IsEnemyVisible( displayTargetActor ) || finishableEnemiesList.Contains( displayTargetActor ) ) && this.CanBeTargetedIfSwimming( displayTargetActor, true ) && IsThreat( displayTargetActor, true ) && WasVisibleInScaledFrame( displayTargetActor, 1.f, 1.f ) ) { newTarget = displayTargetActor; } else if ( moveTarget && isMoveTargetTargetable && ( !IsInCombatAction() || isInParryOrCounter || GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Dodge || GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Roll ) ) { newTarget = moveTarget; } else { newTarget = NULL; } } else { retainCurrentTarget = false; if ( lAxisReleasedAfterCounterNoCA ) { if ( lastAxisInputIsMovement && !this.IsSwimming()) { selectionWeights.angleWeight = 0.375f; selectionWeights.distanceWeight = 0.275f; selectionWeights.distanceRingWeight = 0.35f; selectedTarget = SelectTarget( targets, false, playerPosition, playerHeadingVector, selectionWeights, true ); if ( currentTarget != selectedTarget ) { targetingInfo.targetEntity = currentTarget; if ( IsEntityTargetable( targetingInfo, true ) && currentTarget.IsAlive() ) { retainCurrentTarget = true; } } } else { selectionWeights.angleWeight = 0.75f; selectionWeights.distanceWeight = 0.125f; selectionWeights.distanceRingWeight = 0.125f; selectedTarget = SelectTarget( targets, false, cameraPosition, cameraHeadingVector, selectionWeights, true ); } } else { selectionWeights.angleWeight = 0.6f; selectionWeights.distanceWeight = 0.4f; selectionWeights.distanceRingWeight = 0.f; selectedTarget = SelectTarget( targets, true, playerPosition, targetingIn.rawPlayerHeadingVector, selectionWeights, true ); } if ( retainCurrentTarget ) { newTarget = currentTarget; } else if ( IsInCombatAction() && GetBehaviorVariable( 'isPerformingSpecialAttack' ) == 1.0f ) { newTarget = moveTarget; } else if ( selectedTarget ) { newTarget = selectedTarget; } else { newTarget = NULL; } } targetingOut.confirmNewTarget = true; } else { newTarget = NULL; } targetingOut.result = true; targetingOut.target = newTarget; } function UpdateVisibleActors() { var i : int; var now : float; now = theGame.GetEngineTimeAsSeconds(); for ( i = visibleActors.Size() - 1; i >= 0; i-=1 ) { if ( ( now - visibleActorsTime[i] ) > 1.0f ) { visibleActors.EraseFast( i ); visibleActorsTime.EraseFast( i ); } } } function RemoveNonTargetable( out targets : array< CActor >, out info : STargetingInfo, selectionHeadingVector : Vector ) { var i : int; var cameraPosition : Vector; var cameraDirection : Vector; var nonCombatCheck : bool; var playerToCamPlaneDist : float; var targetToCamPlaneDist : float; if ( targets.Size() == 0 ) { return; } nonCombatCheck = bLAxisReleased && !IsInCombat(); if ( nonCombatCheck ) { info.coneHeadingVector = targetingPrecalcs.playerHeadingVector; if ( lastAxisInputIsMovement ) { info.coneHeadingVector = selectionHeadingVector; info.invisibleCheck = false; info.coneCheck = true; info.coneHalfAngleCos = 0.76604444311f; } else { info.invisibleCheck = false; info.frameScaleX = 0.9f; info.frameScaleY = 0.9f; } } else { info.coneHeadingVector = Vector( 0.0f, 0.0f, 0.0f ); if ( IsInCombat() ) { info.inFrameCheck = false; } else { if ( !bLAxisReleased ) { info.coneCheck = true; if ( this.IsSwimming() ) info.coneHalfAngleCos = -1; else info.coneHalfAngleCos = 0.86602540378f; info.coneHeadingVector = targetingIn.rawPlayerHeadingVector; } } } cameraPosition = theCamera.GetCameraPosition(); cameraDirection = targetingPrecalcs.cameraDirection; playerToCamPlaneDist = VecDot2D( cameraDirection, this.GetWorldPosition() - cameraPosition ); for( i = targets.Size() - 1; i >= 0; i -= 1 ) { info.targetEntity = targets[i]; if ( !CanBeTargetedIfSwimming( targets[i], true ) ) { targets.EraseFast( i ); } else if ( !IsEntityTargetable( info, true ) ) { targets.EraseFast( i ); } else { if ( nonCombatCheck && !lastAxisInputIsMovement ) { targetToCamPlaneDist = VecDot2D( cameraDirection, targets[i].GetWorldPosition() - cameraPosition ); if ( targetToCamPlaneDist < playerToCamPlaneDist ) { targets.EraseFast( i ); } } } } } var combatModeColor : Color; public function CombatModeDebug() { var visualDebug : CVisualDebug = GetVisualDebug(); var naviQueryMsg : string; var naviQueryMsg1 : string; var naviQueryMsg2 : string; var navSnapMsg : string; var i : int; if ( IsCombatMusicEnabled() ) visualDebug.AddText( 'CombatMusic', "CombatMusic : On", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.7f ), true, , Color( 255, 255, 255 ) ); else visualDebug.AddText( 'CombatMusic', "CombatMusic : Off", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.7f ), true, , Color( 0, 0, 0 ) ); if ( GetPlayerMode().GetForceCombatMode() ) visualDebug.AddText( 'ForcedCombatMode', "ForcedCombatMode : TRUE", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.6f ), true, , Color( 255, 255, 255 ) ); else visualDebug.AddText( 'ForcedCombatMode', "ForcedCombatMode : FALSE", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.6f ), true, , Color( 0, 0, 0 ) ); if ( IsThreatened() ) { if ( IsInCombat() ) visualDebug.AddText( 'CombatMode', "CombatMode : AlertNear/Far", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.5f ), true, , Color( 255, 0, 0 ) ); else visualDebug.AddText( 'CombatMode', "CombatMode : CombatExploration", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.5f ), true, , Color( 255, 255, 0 ) ); } else visualDebug.AddText( 'CombatMode', "CombatMode : NormalExploration", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.5f ), true, , Color( 0, 255, 0 ) ); visualDebug.AddText( 'NaviQuery', naviQueryMsg, combatModeEnt.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor ); visualDebug.AddText( 'NaviQuery1', naviQueryMsg1, thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor ); visualDebug.AddText( 'NaviQuery2', naviQueryMsg2, thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.2f ), true, , combatModeColor ); if ( isInCombatReason == 0 ) visualDebug.AddText( 'CombatModeReason', "CombatModeReason : ", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.4f ), true, , Color( 125, 125, 125 ) ); else if ( isInCombatReason == 1 ) visualDebug.AddText( 'CombatModeReason', "CombatModeReason : Geralt CAN pathfind to NPC", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.4f ), true, , Color( 255, 0, 0 ) ); else if ( isInCombatReason == 2 ) visualDebug.AddText( 'CombatModeReason', "CombatModeReason : An NPC is flying or ranged", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.4f ), true, , Color( 255, 0, 0 ) ); else if ( isInCombatReason == 2 ) visualDebug.AddText( 'CombatModeReason', "CombatModeReason : Forced Combat Mode", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.4f ), true, , Color( 255, 0, 0 ) ); if ( reachableEnemyWasTooFar ) { combatModeColor.Red = 255; combatModeColor.Green = 255; combatModeColor.Blue = 0; } else { combatModeColor.Red = 0; combatModeColor.Green = 255; combatModeColor.Blue = 0; } if ( IsThreatened() ) { switch ( navQuery.GetLastOutput( 2.0 ) ) { case EAsyncTastResult_Failure: { if ( this.playerMode.GetForceCombatMode() ) { if ( isSnappedToNavMesh ) { visualDebug.AddText( 'NaviQuery', "", combatModeEnt.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor ); visualDebug.AddText( 'NaviQuery1', "Naviquery : Snapped So no need for query", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor ); visualDebug.AddText( 'NaviQuery2', "Naviquery : Snapped So no need for query", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.2f ), true, , combatModeColor ); } else { visualDebug.AddText( 'NaviQuery', "", combatModeEnt.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor ); visualDebug.AddText( 'NaviQuery1', "Naviquery : Failed", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor ); visualDebug.AddText( 'NaviQuery2', "Naviquery : Failed", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.2f ), true, , combatModeColor ); } } else { visualDebug.AddText( 'NaviQuery', "", combatModeEnt.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor ); visualDebug.AddText( 'NaviQuery1', "Naviquery : Failed", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor ); visualDebug.AddText( 'NaviQuery2', "Naviquery : Failed", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.2f ), true, , combatModeColor ); } break; } case EAsyncTastResult_Success: { visualDebug.AddText( 'NaviQuery', combatModeEnt.GetName(), combatModeEnt.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor ); visualDebug.AddText( 'NaviQuery1', "Naviquery : Success (navDist: " + navDist + ")", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor ); visualDebug.AddText( 'NaviQuery2', "Naviquery : Success (directDist: " + directDist + ")", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.2f ), true, , combatModeColor ); break; } case EAsyncTastResult_Pending: { visualDebug.AddText( 'NaviQuery', combatModeEnt.GetName(), combatModeEnt.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor ); visualDebug.AddText( 'NaviQuery1', "Naviquery : Pending (navDist: " + navDist + ")", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor ); visualDebug.AddText( 'NaviQuery2', "Naviquery : Pending (directDist: " + directDist + ")", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.2f ), true, , combatModeColor ); break; } case EAsyncTastResult_Invalidated: { visualDebug.AddText( 'NaviQuery', "", combatModeEnt.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor ); visualDebug.AddText( 'NaviQuery1', "Naviquery : Invalidated", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor ); visualDebug.AddText( 'NaviQuery2', "Naviquery : Invalidated", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.2f ), true, , combatModeColor ); break; } } } else { visualDebug.AddText( 'NaviQuery', "", combatModeEnt.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor ); visualDebug.AddText( 'NaviQuery1', "", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.3f ), true, , combatModeColor ); visualDebug.AddText( 'NaviQuery2', "", thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.2f ), true, , combatModeColor ); } if ( navMeshSnapInfoStack.Size() > 0 ) { for ( i = navMeshSnapInfoStack.Size()-1; i >= 0; i -= 1 ) { navSnapMsg = navSnapMsg + navMeshSnapInfoStack[i] + " "; } visualDebug.AddText( 'NavMeshSnap', "NavMeshSnap: Enabled, Sources : " + navSnapMsg, thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.1f ), true, , Color( 255, 255, 255 ) ); } else visualDebug.AddText( 'NavMeshSnap', "NavMeshSnap: Disabled" , thePlayer.GetWorldPosition() + Vector( 0.f,0.f,1.1f ), true, , Color( 0, 0, 0 ) ); } function IsCombatMusicEnabled() : bool { if ( theSound.GetCurrentGameState() == ESGS_UnderwaterCombat || theSound.GetCurrentGameState() == ESGS_Combat || theSound.GetCurrentGameState() == ESGS_CombatMonsterHunt || theSound.GetCurrentGameState() == ESGS_FocusUnderwaterCombat ) return true; else return false; } function IsSoundStateCombatMusic( gameState : ESoundGameState ) : bool { if ( gameState == ESGS_UnderwaterCombat || gameState == ESGS_Combat || gameState == ESGS_CombatMonsterHunt || gameState == ESGS_FocusUnderwaterCombat ) return true; else return false; } private function ConfirmNewTarget( actorToConfirm : CActor ) { var leftJoyRotLimit : float = 1.f; var target : CActor; target = GetTarget(); if ( !target || !moveTarget || ( target && ( !IsThreat( target ) || !target.IsAlive() ) ) || VecLength( rawLeftJoyVec ) < 0.7f || ( IsInCombatAction() && ( ( GetBehaviorVariable( 'combatActionType') == (int)CAT_Dodge ) || ( VecLength( rawLeftJoyVec ) >= 0.7f && ( prevRawLeftJoyRot >= ( rawLeftJoyRot + leftJoyRotLimit ) || prevRawLeftJoyRot <= ( rawLeftJoyRot - leftJoyRotLimit ) || AbsF( AngleDistance( cachedRawPlayerHeading, VecHeading( GetDisplayTarget().GetWorldPosition() - this.GetWorldPosition() ) ) ) > 60 ) ) ) ) || ( !IsInCombatAction() && ( !rangedWeapon || ( rangedWeapon.GetCurrentStateName() != 'State_WeaponHolster' ) ) )) { SetPrevRawLeftJoyRot(); if ( actorToConfirm != target ) { SetTarget( actorToConfirm ); } } } protected function SelectTarget( targets : array< CActor >, useVisibilityCheck : bool, sourcePosition : Vector, headingVector : Vector, selectionWeights : STargetSelectionWeights, optional usePrecalcs : bool ) : CActor { var i : int; var target : CActor; var selectedTarget : CActor; var currentTarget : CActor; var playerPosition : Vector; var distanceToPlayer : float; var priority : float; var maxPriority : float; var now : float; var remove : bool; var visibleActorIndex : int; if ( useVisibilityCheck ) { currentTarget = this.GetTarget(); playerPosition = this.GetWorldPosition(); now = theGame.GetEngineTimeAsSeconds(); for ( i = targets.Size() - 1; i >= 0; i-=1 ) { target = targets[ i ]; if ( target != currentTarget && ( !IsPCModeEnabled() && !WasVisibleInScaledFrame( target, softLockFrameSize, softLockFrameSize ) ) ) { remove = true; visibleActorIndex = visibleActors.FindFirst( target ); if ( visibleActorIndex != -1 ) { if ( usePrecalcs ) { distanceToPlayer = Distance2DBetweenCapsuleAndPoint( target, this ) - targetingPrecalcs.playerRadius; } else { distanceToPlayer = Distance2DBetweenCapsules( this, target ); } if ( distanceToPlayer < this.softLockDist && ( now - visibleActorsTime[ i ] ) < 1.0f ) { remove = false; } } if ( remove ) { targets.EraseFast( i ); } } else { visibleActorIndex = visibleActors.FindFirst( target ); if ( visibleActorIndex == -1 ) { visibleActors.PushBack( target ); visibleActorsTime.PushBack( now ); } else { visibleActorsTime[ visibleActorIndex ] = now; } } } } selectedTarget = NULL; maxPriority = -1.0f; for( i = targets.Size() - 1; i >= 0; i-=1 ) { priority = CalcSelectionPriority( targets[ i ], selectionWeights, sourcePosition, headingVector ); if ( priority > maxPriority ) { maxPriority = priority; selectedTarget = targets[ i ]; } } return selectedTarget; } function Distance2DBetweenCapsuleAndPoint( actor : CActor, entity : CEntity ) : float { var distance : float; var mpac : CMovingPhysicalAgentComponent; distance = VecDistance2D( actor.GetWorldPosition(), entity.GetWorldPosition() ); mpac = (CMovingPhysicalAgentComponent)actor.GetMovingAgentComponent(); if ( mpac ) { distance -= mpac.GetCapsuleRadius(); } return distance; } function Distance2DBetweenCapsules( actor1 : CActor, actor2 : CActor ) : float { var distance : float; var mpac : CMovingPhysicalAgentComponent; distance = VecDistance2D( actor1.GetWorldPosition(), actor2.GetWorldPosition() ); mpac = (CMovingPhysicalAgentComponent)actor1.GetMovingAgentComponent(); if ( mpac ) { distance -= mpac.GetCapsuleRadius(); } mpac = (CMovingPhysicalAgentComponent)actor2.GetMovingAgentComponent(); if ( mpac ) { distance -= mpac.GetCapsuleRadius(); } return distance; } protected function ProcessSelectionWeights() : STargetSelectionWeights { var selectionWeights : STargetSelectionWeights; if ( ShouldUsePCModeTargeting() ) { selectionWeights.angleWeight = 0.75f; selectionWeights.distanceWeight = 0.25f; selectionWeights.distanceRingWeight = 0.f; return selectionWeights; } if ( IsInCombatAction() && ( GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Dodge || GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Roll ) ) { selectionWeights.angleWeight = 0.575f; selectionWeights.distanceWeight = 0.175f; selectionWeights.distanceRingWeight = 0.25f; } if ( !lAxisReleasedAfterCounter || IsInCombatAction() ) { if ( theInput.GetActionValue( 'ThrowItem' ) == 1.f || ( rangedWeapon && rangedWeapon.GetCurrentStateName() != 'State_WeaponWait' ) ) { selectionWeights.angleWeight = 1.f; selectionWeights.distanceWeight = 0.f; selectionWeights.distanceRingWeight = 0.f; } else if ( !lAxisReleasedAfterCounter ) { selectionWeights.angleWeight = 0.55f; selectionWeights.distanceWeight = 0.45f; selectionWeights.distanceRingWeight = 0.f; } else { selectionWeights.angleWeight = 0.75f; selectionWeights.distanceWeight = 0.25f; selectionWeights.distanceRingWeight = 0.f; } } else if( !IsCurrentSignChanneled() ) { selectionWeights.angleWeight = 0.35f; selectionWeights.distanceWeight = 0.65f; selectionWeights.distanceRingWeight = 0.f; } else { selectionWeights.angleWeight = 0.275f; selectionWeights.distanceWeight = 0.375f; selectionWeights.distanceRingWeight = 0.35f; } return selectionWeights; } protected function CalcSelectionPriority( target : CEntity, selectionWeights : STargetSelectionWeights, sourcePosition : Vector, headingVector : Vector ) : float { var sourceToTarget : Vector; var sourceToTargetDist : float; var sourceToTargetAngleDiff : float; var selectionPriority : float; sourceToTarget = target.GetWorldPosition() - sourcePosition; sourceToTargetDist = VecLength2D( sourceToTarget ); if ( sourceToTargetDist < 0.0001f ) { sourceToTarget = Vector( 0.0f, 0.0f, 0.0f ); } else { sourceToTarget *= ( 1.0f / sourceToTargetDist ); } sourceToTargetAngleDiff = AbsF( Rad2Deg( AcosF( VecDot2D( sourceToTarget, headingVector ) ) ) ); selectionPriority = ( selectionWeights.angleWeight * ( ( 180 - sourceToTargetAngleDiff ) / 180 ) ); selectionPriority += selectionWeights.distanceWeight * ( ( softLockDist - sourceToTargetDist ) / softLockDist ); if ( sourceToTargetDist > 0.f && sourceToTargetDist <= 6.f ) { selectionPriority += selectionWeights.distanceRingWeight * 1.0f; } else if ( sourceToTargetDist > 6.f && sourceToTargetDist <= softLockDist ) { selectionPriority += selectionWeights.distanceRingWeight * 0.4f; } return selectionPriority; } protected function SetTarget( targetActor : CActor, optional forceSetTarget : bool ) { var playerToTargetDistance : float; var target : CActor; var allow : bool; target = GetTarget(); if ( !IsInNonGameplayCutscene() ) allow = true; if ( allow ) { if ( targetActor ) { if ( ( targetActor.IsAlive() && !targetActor.IsKnockedUnconscious() ) || finishableEnemiesList.Contains( targetActor ) ) allow = true; else allow = false; } else allow = true; } if ( forceSetTarget ) allow = true; if ( allow && target != targetActor ) allow = true; else allow = false; if ( allow ) { SetPlayerTarget( targetActor ); } } public function SetSlideTarget( actor : CGameplayEntity ) { slideTarget = actor; if ( slideTarget ) SetPlayerCombatTarget((CActor)slideTarget); else Log( "slideTarget = NULL" ); if ( slideTarget == nonActorTarget ) UpdateDisplayTarget( true, true ); else UpdateDisplayTarget(); ConfirmDisplayTargetTimer(0.f); } event OnForceSelectLockTarget() { ForceSelectLockTarget(); } private function ForceSelectLockTarget() { var newMoveTarget : CActor; var target : CActor; newMoveTarget = GetScreenSpaceLockTarget( GetDisplayTarget(), 180.f, 1.f, 90 ); if ( !newMoveTarget ) newMoveTarget = GetScreenSpaceLockTarget( GetDisplayTarget(), 180.f, 1.f, -90 ); if ( newMoveTarget ) { thePlayer.ProcessLockTarget( newMoveTarget ); target = GetTarget(); if ( target ) { thePlayer.SetSlideTarget( target ); if ( IsHardLockEnabled() ) thePlayer.HardLockToTarget( true ); } } else { thePlayer.HardLockToTarget( false ); } } public function SetFinisherVictim( actor : CActor ) { finisherVictim = actor; } public function GetFinisherVictim() : CActor { return finisherVictim; } protected function SetNonActorTarget( actor : CGameplayEntity ) { if ( nonActorTarget != actor ) nonActorTarget = actor; } timer function DisableTargetHighlightTimer( time : float , id : int) { var target : CActor; target = GetTarget(); if( target ) { target.StopEffect( 'select_character' ); } } public function WasVisibleInScaledFrame( entity : CEntity, frameSizeX : float, frameSizeY : float ) : bool { var position : Vector; var positionFound : bool; var inFront : bool; var x, y : float; var boneIndex : int; var actor : CActor; var gameplayEntity : CGameplayEntity; var gameplayEntityMatrix : Matrix; var drawableComp : CDrawableComponent; var box : Box; var ok : bool; if ( !entity ) { return false; } if ( frameSizeX <= 0.0f && frameSizeY <= 0.0f ) { LogChannel( 'WasVisibleInScaledFrame', "ERROR: WasVisibleInScaledFrame: frameSizeX && frameSizeY are both negative!!!" ); return false; } if ( useNativeTargeting ) { return targeting.WasVisibleInScaledFrame( entity, frameSizeX, frameSizeY ); } position = entity.GetWorldPosition(); actor = (CActor)entity; if ( actor ) { boneIndex = entity.GetBoneIndex( 'pelvis' ); if ( boneIndex == -1 ) { boneIndex = entity.GetBoneIndex( 'k_pelvis_g' ); } if ( boneIndex != -1 ) { position = MatrixGetTranslation( entity.GetBoneWorldMatrixByIndex( boneIndex ) ); } else { position = entity.GetWorldPosition(); position.Z += ( (CMovingPhysicalAgentComponent)actor.GetMovingAgentComponent() ).GetCapsuleHeight() * 0.5; } positionFound = true; } else { gameplayEntity = (CGameplayEntity)entity; if ( gameplayEntity && !( gameplayEntity.aimVector.X == 0 && gameplayEntity.aimVector.Y == 0 && gameplayEntity.aimVector.Z == 0 ) ) { gameplayEntityMatrix = gameplayEntity.GetLocalToWorld(); position = VecTransform( gameplayEntityMatrix, gameplayEntity.aimVector ); positionFound = true; } } if ( !positionFound ) { drawableComp = (CDrawableComponent)entity.GetComponentByClassName( 'CDrawableComponent' ); if ( drawableComp && drawableComp.GetObjectBoundingVolume( box ) ) { position.Z += ( ( box.Max.Z - box.Min.Z ) * 0.66f ); } } inFront = theCamera.WorldVectorToViewRatio( position, x, y ); if ( !inFront ) { return false; } x = AbsF( x ); y = AbsF( y ); ok = true; ok = ok && ( frameSizeX <= 0.0f || x < frameSizeX ); ok = ok && ( frameSizeY <= 0.0f || y < frameSizeY ); return ok; } public function HardLockToTarget( flag : bool ) { if( flag && GetTarget().HasTag( 'NoHardLock' ) ) return; EnableHardLock( flag ); LockToTarget( flag ); } public function LockToTarget( flag : bool ) { if ( IsHardLockEnabled() && !flag ) return; LockCameraToTarget( flag ); LockActorToTarget( flag ); } public function LockCameraToTarget( flag : bool ) { if ( flag && !IsCameraLockedToTarget() ) { thePlayer.EnableManualCameraControl( false, 'LockCameraToTarget' ); SetIsCameraLockedToTarget( flag ); } else if ( !flag && IsCameraLockedToTarget() ) { thePlayer.EnableManualCameraControl( true, 'LockCameraToTarget' ); SetIsCameraLockedToTarget( flag ); } } public function LockActorToTarget( flag : bool, optional withoutIcon : bool ) { var displayTargetActor : CActor; if ( flag ) { if ( !IsActorLockedToTarget() ) { SetIsActorLockedToTarget( flag ); SetMoveTargetChangeAllowed( true ); SetMoveTarget( GetTarget() ); SetMoveTargetChangeAllowed( false ); SetTarget( GetTarget() ); SetSlideTarget( GetTarget() ); AddTimer( 'CheckLockTargetIsAlive', 0.5, true ); } if ( IsActorLockedToTarget() ) { displayTargetActor = (CActor)( GetDisplayTarget() ); if ( displayTargetActor && IsThreat( displayTargetActor ) && !withoutIcon ) EnableHardLockIcon( flag ); } } else if ( !flag && IsActorLockedToTarget() ) { SetIsActorLockedToTarget( flag ); SetMoveTargetChangeAllowed( true ); RemoveTimer( 'CheckLockTargetIsAlive' ); EnableHardLockIcon( flag ); } } private function EnableHardLockIcon( flag : bool ) { var hud : CR4ScriptedHud; var module : CR4HudModuleEnemyFocus; if( GetTarget().HasTag( 'NoHardLockIcon' ) ) return; hud = (CR4ScriptedHud)theGame.GetHud(); module = (CR4HudModuleEnemyFocus)hud.GetHudModule("EnemyFocusModule"); module.SetShowHardLock( flag ); } private timer function CheckLockTargetIsAlive( time : float , id : int) { var vitality : float; var essence : float; var actor : CActor; var target : CActor; target = (CActor)GetDisplayTarget(); if( !target || !target.IsAlive() || ( !target.GetGameplayVisibility() ) || !CanBeTargetedIfSwimming( target ) || (!target.UsesVitality() && !target.UsesEssence())) { if ( !ProcessLockTarget() ) HardLockToTarget( false ); } } protected function PlayHitAnimation(damageAction : W3DamageAction, animType : EHitReactionType) { var hitRotation : float; var onHitCounter : SAbilityAttributeValue; var counter : int; if( damageAction.HasAnyCriticalEffect() ) return; if( !substateManager.ReactOnBeingHit() && !IsUsingVehicle() ) { return; } if ( damageAction.GetHitReactionType() == EHRT_Reflect ) SetBehaviorVariable( 'isAttackReflected', 1.f ); else SetBehaviorVariable( 'isAttackReflected', 0.f ); SetBehaviorVariable( 'HitReactionType',(int)animType); SetBehaviorVariable( 'HitReactionWeapon', ProcessSwordOrFistHitReaction( this, (CActor)damageAction.attacker ) ); if (damageAction.attacker) { super.PlayHitAnimation( damageAction, animType ); if ( damageAction.attacker.HasAbility( 'IncreaseHitReactionSeverityWithHitCounter' ) ) { counter = GetHitCounter(); switch ( counter ) { case 2 : SetBehaviorVariable( 'HitReactionType', 2 ); break; case 3 : AddEffectDefault( EET_Stagger, damageAction.attacker, damageAction.attacker.GetName() ); break; case 4 : AddEffectDefault( EET_Knockdown, damageAction.attacker, damageAction.attacker.GetName() ); break; default : break; } } SetHitReactionDirection(damageAction.attacker); SetDetailedHitReaction(damageAction.GetSwingType(), damageAction.GetSwingDirection()); } RaiseForceEvent( 'Hit' ); theGame.GetBehTreeReactionManager().CreateReactionEventIfPossible( this, 'ActorInHitReaction', -1, 30.0f, -1.f, -1, true ); if ( IsUsingBoat() ) { SoundEvent("cmb_play_hit_light"); return; } if ( IsUsingVehicle() ) return; if(damageAction.attacker) { hitRotation = VecHeading( damageAction.attacker.GetWorldPosition() - GetWorldPosition() ); if ( this.GetBehaviorVariable( 'HitReactionDirection' ) == (float)( (int)EHRD_Back ) ) hitRotation += 180.f; SetCustomRotation( 'Hit', hitRotation, 1080.f, 0.1f, false ); } CriticalEffectAnimationInterrupted("PlayHitAnimation"); } public function ReduceDamage( out damageData : W3DamageAction) { super.ReduceDamage(damageData); if(damageData.attacker == this && (damageData.GetBuffSourceName() == "petard" || (W3Petard)damageData.causer) ) { if ( theGame.CanLog() ) { LogDMHits("CR4Player.ReduceDamage: hitting self with own bomb - damage reduced by 50%", damageData ); } damageData.processedDmg.vitalityDamage = damageData.processedDmg.vitalityDamage / 2; damageData.processedDmg.essenceDamage = damageData.processedDmg.essenceDamage / 2; } } public function GetCriticalHitChance( isLightAttack : bool, isHeavyAttack : bool, target : CActor, victimMonsterCategory : EMonsterCategory, isBolt : bool ) : float { var critChance : float; var oilChanceAttribute : name; var weapons : array< SItemUniqueId >; var i : int; var holdsCrossbow : bool; var critVal : SAbilityAttributeValue; critChance = 0; if( FactsQuerySum( 'debug_fact_critical_boy' ) > 0 ) { critChance += 1; } if( IsInState( 'HorseRiding' ) && ( ( CActor )GetUsedVehicle() ).GetMovingAgentComponent().GetRelativeMoveSpeed() >= 4.0 ) { critChance += 1; } critChance += CalculateAttributeValue( GetAttributeValue( theGame.params.CRITICAL_HIT_CHANCE ) ); weapons = inv.GetHeldWeapons(); for( i=0; i 0 && !((W3Effect_Toxicity)damageAction.causer)) ReceivedCombatDamage(); if(FactsQuerySum("tut_fight_use_slomo") > 0) { theGame.RemoveTimeScale( theGame.GetTimescaleSource(ETS_TutorialFight) ); FactsRemove("tut_fight_slomo_ON"); } if( !substateManager.ReactOnBeingHit( damageAction ) ) { GoToCombatIfNeeded(); } return sup; } protected function ShouldPauseHealthRegenOnHit() : bool { return true; } public function PlayHitEffect(damageAction : W3DamageAction) { super.PlayHitEffect(damageAction); if(damageAction.DealsAnyDamage() && !damageAction.IsDoTDamage()) PlayEffect('hit_screen'); } function HitReactionEffect( interval : float ) { if ( hitReactionEffect ) { PlayEffect( 'radial_blur' ); hitReactionEffect = false; } else { AddTimer( 'HitReactionEffectCooldown', interval, false ); } } timer function HitReactionEffectCooldown( td : float , id : int) { hitReactionEffect = true; } function PerformParryCheck( parryInfo : SParryInfo) : bool { var mult : float; var parryType : EParryType; var parryDir : EPlayerParryDirection; var parryHeading : float; var fistFightParry : bool; var action : W3DamageAction; var xmlStaminaDamage : float; var xmlStaminaDamageName : name = 'stamina_damage' ; var counter : int; var onHitCounter : SAbilityAttributeValue; if(CanParryAttack() && FistFightCheck( parryInfo.target, parryInfo.attacker, fistFightParry ) ) { parryHeading = GetParryHeading( parryInfo, parryDir ) ; SetBehaviorVariable( 'parryDirection', (float)( (int)( parryDir ) ) ); SetBehaviorVariable( 'parryDirectionOverlay', (float)( (int)( parryDir ) ) ); SetBehaviorVariable( 'parryType', ChooseParryTypeIndex( parryInfo ) ); if ( IsInCombatActionFriendly() ) RaiseEvent('CombatActionFriendlyEnd'); if ( HasStaminaToParry(parryInfo.attackActionName) ) { this.SetBehaviorVariable( 'combatActionType', (int)CAT_Parry ); if ( parryInfo.targetToAttackerDist > 3.f && !bLAxisReleased && !thePlayer.IsCiri() ) { if ( !RaiseForceEvent( 'PerformParryOverlay' ) ) return false; else { ClearCustomOrientationInfoStack(); IncDefendCounter(); } } else { counter = GetDefendCounter(); onHitCounter = parryInfo.attacker.GetAttributeValue( 'break_through_parry_on_hit_counter' ); if ( onHitCounter.valueBase > 0 && counter == onHitCounter.valueBase ) { AddEffectDefault( EET_Stagger, parryInfo.attacker, "Break through parry" ); } else if ( RaiseForceEvent( 'PerformParry' ) ) { OnCombatActionStart(); ClearCustomOrientationInfoStack(); SetSlideTarget( parryInfo.attacker ); SetCustomRotation( 'Parry', parryHeading, 1080.f, 0.1f, false ); IncDefendCounter(); } else return false; } } else { AddEffectDefault(EET_Stagger, parryInfo.attacker, "Parry"); return true; } if ( parryInfo.attacker.IsWeaponHeld( 'fist' ) && !parryInfo.target.IsWeaponHeld( 'fist' ) ) { parryInfo.attacker.ReactToReflectedAttack(parryInfo.target); } else { if ( this.IsInFistFightMiniGame() && fistFightParry ) { if ( IsNameValid(xmlStaminaDamageName) ) { xmlStaminaDamage = CalculateAttributeValue(parryInfo.attacker.GetAttributeValue( xmlStaminaDamageName )); DrainStamina(ESAT_FixedValue, xmlStaminaDamage); } } else { DrainStamina(ESAT_Parry, 0, 0, '', 0, mult); } if(IsLightAttack(parryInfo.attackActionName)) parryInfo.target.PlayEffectOnHeldWeapon('light_block'); else parryInfo.target.PlayEffectOnHeldWeapon('heavy_block'); } return true; } return false; } protected function GetParryHeading( parryInfo : SParryInfo, out parryDir : EPlayerParryDirection ) : float { var targetToAttackerHeading : float; var currToTargetAttackerAngleDiff : float; targetToAttackerHeading = VecHeading( parryInfo.attacker.GetWorldPosition() - parryInfo.target.GetWorldPosition() ); currToTargetAttackerAngleDiff = AngleDistance( VecHeading( parryInfo.target.GetHeadingVector() ), targetToAttackerHeading ); if ( !parryInfo.target.IsWeaponHeld( 'fist' ) ) { if( currToTargetAttackerAngleDiff > -45 && currToTargetAttackerAngleDiff < 45 ) { parryDir = PPD_Forward; return targetToAttackerHeading; } else if( currToTargetAttackerAngleDiff >= 45 && currToTargetAttackerAngleDiff < 135 ) { parryDir = PPD_Right; return targetToAttackerHeading + 90; } else if( currToTargetAttackerAngleDiff <= -45 && currToTargetAttackerAngleDiff > -135 ) { parryDir = PPD_Left; return targetToAttackerHeading - 90; } else { parryDir = PPD_Back; return targetToAttackerHeading + 180; } } else { if( currToTargetAttackerAngleDiff > -45 && currToTargetAttackerAngleDiff < 45 ) { parryDir = PPD_Forward; return targetToAttackerHeading; } else if( currToTargetAttackerAngleDiff >= 45 && currToTargetAttackerAngleDiff < 180 ) { parryDir = PPD_Right; return targetToAttackerHeading + 90; } else if( currToTargetAttackerAngleDiff <= -45 && currToTargetAttackerAngleDiff >= -180 ) { parryDir = PPD_Left; return targetToAttackerHeading - 90; } else { parryDir = PPD_Back; return targetToAttackerHeading + 180; } } } function ProcessLockTarget( optional newLockTarget : CActor, optional checkLeftStickHeading : bool ) : bool { var attackerNearestPoint : Vector; var playerNearestPoint : Vector; var incomingAttacker : CActor; var tempLockTarget : CActor; var target : CActor; var useIncomingAttacker : bool; if( newLockTarget.HasTag( 'NoHardLock' ) ) return false; if ( newLockTarget ) tempLockTarget = newLockTarget; else { incomingAttacker = GetClosestIncomingAttacker(); if ( incomingAttacker && incomingAttacker.IsAlive() && IsUsingVehicle() ) { tempLockTarget = incomingAttacker; useIncomingAttacker = false; } if ( !useIncomingAttacker ) { target = GetTarget(); if( target.HasTag('ForceHardLock')) { return true; } else if ( target && target.IsAlive() && target.GetGameplayVisibility() && IsEnemyVisible( target ) && IsThreat( target ) && CanBeTargetedIfSwimming( target ) ) tempLockTarget = FindTarget(); else { tempLockTarget = GetScreenSpaceLockTarget( GetDisplayTarget(), 180.f, 1.f, 0.f ); } } } if( tempLockTarget.HasTag( 'NoHardLock' ) ) return false; if ( tempLockTarget ) { if ( IsCombatMusicEnabled() || hostileEnemies.Size() > 0 ) { if ( !IsThreat( tempLockTarget ) ) tempLockTarget = NULL; } } SetTarget( tempLockTarget, true ); SetMoveTargetChangeAllowed( true ); SetMoveTarget( tempLockTarget ); SetMoveTargetChangeAllowed( false ); SetSlideTarget( tempLockTarget ); if ( tempLockTarget ) { if ( this.IsActorLockedToTarget() ) EnableHardLockIcon( true ); return true; } else return false; } event OnTaskSyncAnim( npc : CNewNPC, animNameLeft : name ) {} public function IsDoingSpecialAttack(heavy : bool) : bool { var pat : EPlayerAttackType; if(IsInCombatAction() && ( (int)GetBehaviorVariable('combatActionType')) == CAT_SpecialAttack) { pat = (int)GetBehaviorVariable('playerAttackType'); if(heavy && pat == PAT_Heavy) { return true; } else if(!heavy && pat == PAT_Light) { return true; } } return false; } public function SetIsCurrentlyDodging(enable : bool, optional isRolling : bool) { super.SetIsCurrentlyDodging(enable, isRolling); if ( isRolling ) { SetCanPlayHitAnim( false ); this.AddBuffImmunity( EET_KnockdownTypeApplicator, 'Roll', false ); this.AddBuffImmunity( EET_Knockdown, 'Roll', false ); this.AddBuffImmunity( EET_HeavyKnockdown, 'Roll', false ); this.AddBuffImmunity( EET_Stagger, 'Roll', false ); } else { SetCanPlayHitAnim( true ); this.RemoveBuffImmunity( EET_KnockdownTypeApplicator, 'Roll' ); this.RemoveBuffImmunity( EET_Knockdown, 'Roll' ); this.RemoveBuffImmunity( EET_HeavyKnockdown, 'Roll' ); this.RemoveBuffImmunity( EET_Stagger, 'Roll' ); } } public function EnableHardLock( flag : bool ) { super.EnableHardLock(flag); if(flag && ShouldProcessTutorial('TutorialTargettingWaiting')) { FactsAdd("tut_hardlocked"); } } protected function TestParryAndCounter(data : CPreAttackEventData, weaponId : SItemUniqueId, out parried : bool, out countered : bool) : array { var ret : array; if(FactsQuerySum('player_is_the_boss') > 0) { SetDebugAttackRange(data.rangeName); RemoveTimer('PostAttackDebugRangeClear'); return ret; } ret = super.TestParryAndCounter(data, weaponId, parried, countered); if(parried) theGame.GetGamerProfile().ResetStat(ES_CounterattackChain); return ret; } public function SetSpecialAttackTimeRatio(f : float) { LogSpecialHeavy(f); specialAttackTimeRatio = f; } public function GetSpecialAttackTimeRatio() : float { return specialAttackTimeRatio; } public function OnSpecialAttackHeavyActionProcess() { SetSpecialAttackTimeRatio(0.f); } protected function DoAttack(animData : CPreAttackEventData, weaponId : SItemUniqueId, parried : bool, countered : bool, parriedBy : array, attackAnimationName : name, hitTime : float) { var shakeStr : float; var weapon : EPlayerWeapon; var targetActor : CActor; if ( animData.attackName == 'attack_heavy_special' ) { if( specialAttackTimeRatio != 1 ) shakeStr = (specialAttackTimeRatio / 3.333) + 0.2; else shakeStr = 0.5; GCameraShake( shakeStr, false, GetWorldPosition(), 10); } else if ( IsHeavyAttack(attackActionName) ) { if(parriedBy.Size() > 0) shakeStr = 0.2; else shakeStr = 0.1; GCameraShake(shakeStr, false, GetWorldPosition(), 10); } targetActor = (CActor)slideTarget; if ( targetActor && hitTargets.Contains(targetActor) ) { weapon = this.GetMostConvenientMeleeWeapon(targetActor,true); if ( this.GetCurrentMeleeWeaponType() != PW_Fists && weapon != this.GetCurrentMeleeWeaponType() ) { if ( weapon == PW_Steel ) { thePlayer.OnEquipMeleeWeapon(PW_Steel,true); } else if ( weapon == PW_Silver ) { thePlayer.OnEquipMeleeWeapon(PW_Silver,true); } } } super.DoAttack(animData, weaponId, parried, countered, parriedBy, attackAnimationName, hitTime); } private var confirmCombatStanceTimeStamp : float; private var isConfirmingCombatStance : bool; final function SetPlayerCombatStance(stance : EPlayerCombatStance, optional force : bool ) { var stanceInt : int; if ( !CanChangeCombatStance( stance, force ) ) return; combatStance = stance; stanceInt = (int)stance; SetBehaviorVariable( 'playerCombatStance' , (float)stanceInt); SetBehaviorVariable( 'playerCombatStanceForOverlay' , (float)stanceInt); if ( force ) SetBehaviorVariable( 'forceCombatStance' , 1.f); else SetBehaviorVariable( 'forceCombatStance' , 0.f); if ( stance == PCS_AlertNear ) this.SetBehaviorVariable('isInCombatForOverlay',1.f); else this.SetBehaviorVariable('isInCombatForOverlay',0.f); } private function CanChangeCombatStance( stance : EPlayerCombatStance, optional force : bool ) : bool { var currTime : float; if ( force ) return true; if ( IsInFistFightMiniGame() ) return true; if ( isInHolsterAnim ) return false; if ( ( combatStance == PCS_Normal || combatStance == PCS_AlertFar ) && stance == PCS_AlertNear ) { currTime = theGame.GetEngineTimeAsSeconds(); if ( !isConfirmingCombatStance ) { isConfirmingCombatStance = true; confirmCombatStanceTimeStamp = currTime; return false; } else if ( currTime < confirmCombatStanceTimeStamp + 1.f ) { if ( stance == PCS_AlertNear ) return false; } else isConfirmingCombatStance = false; } else isConfirmingCombatStance = false; return true; } private var isInHolsterAnim : bool; event OnHolsterWeaponStart() { isInHolsterAnim = true; } event OnHolsterWeaponEnd() { isInHolsterAnim = false; } final function GetPlayerCombatStance() : EPlayerCombatStance { return combatStance; } timer function DelayedDisableFindTarget( time : float , id : int) { if ( GetTarget().IsAlive() ) { EnableFindTarget( false ); } else { EnableFindTarget( true ); } } private var dodgeTimerRunning : bool; function StartDodgeTimer() { dodgeTimerRunning = true; thePlayer.AddTimer('DodgeTimer',0.2,false); } function StopDodgeTimer() { this.RemoveTimer('DodgeTimer'); dodgeTimerRunning = false; } function IsDodgeTimerRunning() : bool { return dodgeTimerRunning; } timer function DodgeTimer( dt : float, id : int ) { dodgeTimerRunning = false; } public function EvadePressed( bufferAction : EBufferActionType ) { } public function PerformingCombatAction() : EBufferActionType { return BufferCombatAction; } public function PushCombatActionOnBuffer( action : EBufferActionType, stage : EButtonStage, optional allSteps : bool ) { BufferButtonStage = stage; BufferCombatAction = action; BufferAllSteps = allSteps; } protected function ProcessCombatActionHeading( action : EBufferActionType ) : float { var processedActionHeading : float; HandleMovement( 0.f ); if ( ShouldUsePCModeTargeting() ) return theGame.GetGameCamera().GetHeading(); if ( lAxisReleasedAfterCounter ) ResetCachedRawPlayerHeading(); processedActionHeading = cachedRawPlayerHeading; return processedActionHeading; } function ResetRawPlayerHeading() { if ( GetDisplayTarget() ) rawPlayerHeading = VecHeading( GetDisplayTarget().GetWorldPosition() - this.GetWorldPosition() ); else rawPlayerHeading = GetHeading(); } function ResetCachedRawPlayerHeading() { cachedRawPlayerHeading = rawPlayerHeading; if ( GetDisplayTarget() && IsDisplayTargetTargetable() && AbsF( AngleDistance( VecHeading( GetDisplayTarget().GetWorldPosition() - this.GetWorldPosition() ), this.GetHeading() ) ) < 90.f ) cachedRawPlayerHeading = VecHeading( GetDisplayTarget().GetWorldPosition() - this.GetWorldPosition() ); else cachedRawPlayerHeading = this.GetHeading(); if ( canResetCachedCombatActionHeading ) cachedCombatActionHeading = cachedRawPlayerHeading; } public function GetCombatActionTarget( action : EBufferActionType ) : CGameplayEntity { var selectedTargetableEntity : CGameplayEntity; if ( !this.IsUsingVehicle() ) selectedTargetableEntity = FindNonActorTarget( true, action ); if ( selectedTargetableEntity ) { return selectedTargetableEntity; } else { if ( !this.IsUsingVehicle() ) FindTarget( true, action, true ); else ((CR4PlayerStateUseGenericVehicle)this.GetState( 'UseGenericVehicle' )).FindTarget(); return GetTarget(); } } private function FindNonActorTarget( actionCheck : bool, optional action : EBufferActionType ) : CGameplayEntity { var targetableEntities : array; var selectedTargetableEntity : CGameplayEntity; var selectionPriority : array< float >; var selectionWeights : STargetSelectionWeights; var findEntityDist : float; var i, size : int; var playerHeading : float; var playerInventory : CInventoryComponent; var castSignType : ESignType; var targetingInfo : STargetingInfo; var playerPosition : Vector; var cameraPosition : Vector; var playerHeadingVector : Vector; var rawPlayerHeadingVector : Vector; playerPosition = this.GetWorldPosition(); cameraPosition = theCamera.GetCameraPosition(); rawPlayerHeadingVector = VecFromHeading( rawPlayerHeading ); if ( bCanFindTarget && !IsHardLockEnabled() ) { if ( actionCheck && IsInCombat() && action == EBAT_CastSign ) { findEntityDist = 6.f; selectionWeights.angleWeight = 0.375f; selectionWeights.distanceWeight = 0.275f; selectionWeights.distanceRingWeight = 0.35f; } else if ( !IsInCombat() && lastAxisInputIsMovement ) { findEntityDist = softLockDist; selectionWeights.angleWeight = 0.375f; selectionWeights.distanceWeight = 0.275f; selectionWeights.distanceRingWeight = 0.35f; } else { findEntityDist = softLockDist; selectionWeights.angleWeight = 0.75f; selectionWeights.distanceWeight = 0.125f; selectionWeights.distanceRingWeight = 0.125f; } if ( !IsInCombat() || !bLAxisReleased ) { FindGameplayEntitiesInRange( targetableEntities, this, findEntityDist, 10, theGame.params.TAG_SOFT_LOCK ); } if ( targetableEntities.Size() > 0 ) { playerInventory = this.GetInventory(); castSignType = this.GetEquippedSign(); if ( !bLAxisReleased ) { targetingInfo.source = this; targetingInfo.canBeTargetedCheck = false; targetingInfo.coneCheck = true; targetingInfo.coneHalfAngleCos = 0.5f; targetingInfo.coneDist = softLockDist; targetingInfo.coneHeadingVector = rawPlayerHeadingVector; targetingInfo.distCheck = true; targetingInfo.invisibleCheck = false; targetingInfo.navMeshCheck = false; targetingInfo.frameScaleX = 1.0f; targetingInfo.frameScaleY = 1.0f; targetingInfo.knockDownCheck = false; targetingInfo.knockDownCheckDist = 0.0f; targetingInfo.rsHeadingCheck = false; targetingInfo.rsHeadingLimitCos = 1.0f; } for( i = targetableEntities.Size()-1; i>=0; i-=1 ) { if ( bLAxisReleased ) { if ( !lastAxisInputIsMovement ) { if ( !WasVisibleInScaledFrame( targetableEntities[i], 0.9f, 0.9f ) ) { targetableEntities.Erase(i); continue; } } else if ( !WasVisibleInScaledFrame( targetableEntities[i], 1.f, 1.f ) ) { targetableEntities.Erase(i); continue; } } else { targetingInfo.targetEntity = targetableEntities[i]; if ( actionCheck && moveTarget ) { targetingInfo.inFrameCheck = false; if ( !IsEntityTargetable( targetingInfo ) ) { targetableEntities.Erase(i); continue; } } else { targetingInfo.inFrameCheck = true; if ( !IsEntityTargetable( targetingInfo ) ) { targetableEntities.Erase(i); continue; } } } if ( actionCheck ) { if ( action == EBAT_ItemUse ) { if ( ( playerInventory.IsItemBomb( this.GetSelectedItemId() ) && !targetableEntities[i].HasTag( 'softLock_Bomb' ) ) || ( playerInventory.IsItemCrossbow( this.GetSelectedItemId() ) && !targetableEntities[i].HasTag( 'softLock_Bolt' ) ) ) { targetableEntities.Erase(i); continue; } } else if ( action == EBAT_CastSign ) { if ( ( castSignType == ST_Aard && !targetableEntities[i].HasTag( 'softLock_Aard' ) ) || ( castSignType == ST_Igni && !targetableEntities[i].HasTag( 'softLock_Igni' ) ) || ( castSignType == ST_Axii && !targetableEntities[i].HasTag( 'softLock_Axii' ) ) || castSignType == ST_Yrden || castSignType == ST_Quen ) { targetableEntities.Erase(i); continue; } } else if ( action == EBAT_LightAttack || action == EBAT_HeavyAttack || action == EBAT_SpecialAttack_Heavy ) { if ( ( IsWeaponHeld( 'fist' ) && !targetableEntities[i].HasTag( 'softLock_Fist' ) ) || ( !IsWeaponHeld( 'fist' ) && !targetableEntities[i].HasTag( 'softLock_Weapon' ) ) ) { targetableEntities.Erase(i); continue; } } else { targetableEntities.Erase(i); continue; } } } } if ( targetableEntities.Size() > 0) { playerHeading = this.GetHeading(); playerHeadingVector = this.GetHeadingVector(); if ( IsInCombat() ) { for( i = 0; i < targetableEntities.Size(); i += 1 ) { if ( bLAxisReleased ) selectionPriority.PushBack( CalcSelectionPriority( targetableEntities[i], selectionWeights, cameraPosition, rawPlayerHeadingVector ) ); else selectionPriority.PushBack( CalcSelectionPriority( targetableEntities[i], selectionWeights, playerPosition, rawPlayerHeadingVector ) ); } if ( selectionPriority.Size() > 0 ) selectedTargetableEntity = targetableEntities[ ArrayFindMaxF( selectionPriority ) ]; } else { if ( bLAxisReleased ) { if ( !lastAxisInputIsMovement ) { for( i = 0; i < targetableEntities.Size(); i += 1 ) selectionPriority.PushBack( CalcSelectionPriority( targetableEntities[i], selectionWeights, cameraPosition, rawPlayerHeadingVector ) ); if ( selectionPriority.Size() > 0 ) selectedTargetableEntity = targetableEntities[ ArrayFindMaxF( selectionPriority ) ]; } else { if ( IsInCombatAction() ) selectedTargetableEntity = nonActorTarget; else { for( i = 0; i < targetableEntities.Size(); i += 1 ) selectionPriority.PushBack( CalcSelectionPriority( targetableEntities[i], selectionWeights, playerPosition, playerHeadingVector ) ); if ( selectionPriority.Size() > 0 ) { selectedTargetableEntity = targetableEntities[ ArrayFindMaxF( selectionPriority ) ]; targetingInfo.source = this; targetingInfo.targetEntity = selectedTargetableEntity; targetingInfo.canBeTargetedCheck = false; targetingInfo.coneCheck = true; targetingInfo.coneHalfAngleCos = 0.0f; targetingInfo.coneDist = softLockDist; targetingInfo.coneHeadingVector = this.GetHeadingVector(); targetingInfo.distCheck = true; targetingInfo.invisibleCheck = false; targetingInfo.navMeshCheck = false; targetingInfo.inFrameCheck = false; targetingInfo.frameScaleX = 1.0f; targetingInfo.frameScaleY = 1.0f; targetingInfo.knockDownCheck = false; targetingInfo.knockDownCheckDist = 0.0f; targetingInfo.rsHeadingCheck = false; targetingInfo.rsHeadingLimitCos = 1.0f; if ( !IsEntityTargetable( targetingInfo ) ) selectedTargetableEntity = NULL; } } } } else { for( i = 0; i < targetableEntities.Size(); i += 1 ) selectionPriority.PushBack( CalcSelectionPriority( targetableEntities[i], selectionWeights, playerPosition, rawPlayerHeadingVector ) ); if ( selectionPriority.Size() > 0 ) selectedTargetableEntity = targetableEntities[ ArrayFindMaxF( selectionPriority ) ]; } } } else selectedTargetableEntity = NULL; } SetNonActorTarget( selectedTargetableEntity ); return selectedTargetableEntity; } public function SetupCombatAction( action : EBufferActionType, stage : EButtonStage ) { var weaponType : EPlayerWeapon; var canAttackTarget : CGameplayEntity; var target : CActor; if ( !IsCombatMusicEnabled() ) { SetCombatActionHeading( ProcessCombatActionHeading( action ) ); FindTarget(); UpdateDisplayTarget( true ); } if ( displayTarget && IsDisplayTargetTargetable() ) canAttackTarget = displayTarget; else if ( GetTarget() ) canAttackTarget = GetTarget(); else if( !target && IsCombatMusicEnabled() ) canAttackTarget = moveTarget; target = (CActor)canAttackTarget; if ( !AllowAttack( target, action ) ) return; if( ( action != EBAT_ItemUse ) && ( action != EBAT_CastSign ) ) { weaponType = weaponHolster.GetCurrentMeleeWeapon(); PrepareToAttack( target, action ); if ( weaponType != weaponHolster.GetCurrentMeleeWeapon() ) { if ( !( weaponType == PW_None && weaponHolster.GetCurrentMeleeWeapon() == PW_Fists ) ) return; } } if(action == EBAT_SpecialAttack_Heavy && !((W3ReplacerCiri)this) ) thePlayer.SetAttackActionName(SkillEnumToName(S_Sword_s02)); CriticalEffectAnimationInterrupted("SetupCombatAction " + action); PushCombatActionOnBuffer( action, stage ); if( GetBIsCombatActionAllowed() ) { ProcessCombatActionBuffer(); } } public function AllowAttack( target : CActor, action : EBufferActionType ) : bool { var newTarget : CActor; var canAttackWhenNotInCombat : bool; var messageDisplayed : bool; var itemId : SItemUniqueId; var isShootingCrossbow : bool; var isInCorrectState : bool; if ( target ) { if ( target.IsTargetableByPlayer()) { if ( !target.IsAttackableByPlayer() ) { DisplayHudMessage(GetLocStringByKeyExt("panel_hud_message_cant_attack_this_target")); return false; } } } if ( this.GetCurrentStateName() == 'Exploration' ) isInCorrectState = true; if ( action == EBAT_ItemUse ) { itemId = thePlayer.GetSelectedItemId(); if ( inv.IsIdValid(itemId) && inv.IsItemCrossbow(itemId) ) isShootingCrossbow = true; if ( !isInCorrectState ) { if ( this.GetCurrentStateName() == 'AimThrow' && !isShootingCrossbow ) { isInCorrectState = true; } } } if ( isInCorrectState ) canAttackWhenNotInCombat = thePlayer.CanAttackWhenNotInCombat( action, false, newTarget, target ); if( !target ) { if ( isInCorrectState ) { SetCombatActionHeading( ProcessCombatActionHeading( action ) ); target = newTarget; } } if ( isInCorrectState ) { if ( !canAttackWhenNotInCombat ) { if ( DisplayCannotAttackMessage( target ) ) messageDisplayed = true; else if ( ( action == EBAT_LightAttack || action == EBAT_HeavyAttack ) && !RaiseAttackFriendlyEvent( target ) ) messageDisplayed = true; else { if ( !CanRaiseCombatActionFriendlyEvent( isShootingCrossbow ) ) messageDisplayed = true; } } if ( messageDisplayed ) { theInput.ForceDeactivateAction('ThrowItem'); theInput.ForceDeactivateAction('ThrowItemHold'); this.SignalGameplayEvent( 'FriendlyAttackAction' ); return false; } } return true; } public function ProcessCombatActionBuffer() : bool { var actionResult : bool; var action : EBufferActionType = this.BufferCombatAction; var stage : EButtonStage = this.BufferButtonStage; var s : SNotWorkingOutFunctionParametersHackStruct1; var allSteps : bool = this.BufferAllSteps; if ( IsInCombatActionFriendly() ) { RaiseEvent('CombatActionFriendlyEnd'); } if ( ( action != EBAT_SpecialAttack_Heavy && action != EBAT_ItemUse ) || ( action == EBAT_SpecialAttack_Heavy && stage == BS_Pressed ) || ( action == EBAT_ItemUse && stage != BS_Released ) ) { GetMovingAgentComponent().GetMovementAdjustor().CancelAll(); SetUnpushableTarget( NULL ); } if ( !( action == EBAT_Dodge || action == EBAT_Roll ) ) { SetIsCurrentlyDodging(false); } SetCombatActionHeading( ProcessCombatActionHeading( action ) ); if ( action == EBAT_ItemUse && GetInventory().IsItemCrossbow( selectedItemId ) ) { if ( rangedWeapon && ( ( rangedWeapon.GetCurrentStateName() != 'State_WeaponShoot' && rangedWeapon.GetCurrentStateName() != 'State_WeaponAim' ) || GetIsShootingFriendly() ) ) { SetSlideTarget( GetCombatActionTarget( action ) ); } } else if ( !( ( action == EBAT_SpecialAttack_Heavy && stage == BS_Released ) || GetCurrentStateName() == 'AimThrow' ) ) { SetSlideTarget( GetCombatActionTarget( action ) ); } if( !slideTarget ) LogChannel( 'Targeting', "NO SLIDE TARGET" ); actionResult = true; switch ( action ) { case EBAT_EMPTY : { this.BufferAllSteps = false; return true; } break; case EBAT_LightAttack : { if ( IsCiri() ) return false; switch ( stage ) { case BS_Pressed : { DrainStamina(ESAT_LightAttack); thePlayer.BreakPheromoneEffect(); actionResult = OnPerformAttack(theGame.params.ATTACK_NAME_LIGHT); } break; default : { actionResult = false; }break; } }break; case EBAT_HeavyAttack : { if ( IsCiri() ) return false; switch ( stage ) { case BS_Released : { DrainStamina(ESAT_HeavyAttack); thePlayer.BreakPheromoneEffect(); actionResult = this.OnPerformAttack(theGame.params.ATTACK_NAME_HEAVY); } break; case BS_Pressed : { if ( this.GetCurrentStateName() == 'CombatFists' ) { DrainStamina(ESAT_HeavyAttack); thePlayer.BreakPheromoneEffect(); actionResult = this.OnPerformAttack(theGame.params.ATTACK_NAME_HEAVY); } } break; default : { actionResult = false; } break; } } break; case EBAT_ItemUse : { switch ( stage ) { case BS_Pressed : { if ( !( (W3PlayerWitcher)this ) || ( !IsInCombatActionFriendly() && !( !GetBIsCombatActionAllowed() && ( GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Attack || GetBehaviorVariable( 'combatActionType' ) == (int)CAT_CastSign ) ) ) ) { if ( inv.IsItemCrossbow( selectedItemId ) ) { rangedWeapon = ( Crossbow )( inv.GetItemEntityUnsafe( selectedItemId ) ); rangedWeapon.OnRangedWeaponPress(); GetTarget().SignalGameplayEvent( 'Approach' ); GetTarget().SignalGameplayEvent( 'ShootingCrossbow' ); } else if(inv.IsItemBomb(selectedItemId) && this.inv.SingletonItemGetAmmo(selectedItemId) > 0 ) { if( ((W3PlayerWitcher)this).GetBombDelay( ((W3PlayerWitcher)this).GetItemSlot( selectedItemId ) ) <= 0.0f ) { BombThrowStart(); GetTarget().SignalGameplayEvent( 'Approach' ); } } else { DrainStamina(ESAT_UsableItem); UsableItemStart(); } } } if (!allSteps) break; case BS_Released: { if ( !( (W3PlayerWitcher)this ) || ( !IsInCombatActionFriendly() && ( GetBIsCombatActionAllowed() || !( !GetBIsCombatActionAllowed() && ( GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Attack || GetBehaviorVariable( 'combatActionType' ) == (int)CAT_CastSign ) ) ) ) ) { if ( inv.IsItemCrossbow( selectedItemId ) ) { rangedWeapon.OnRangedWeaponRelease(); } else if(inv.IsItemBomb(selectedItemId)) { BombThrowRelease(); } else { UsableItemRelease(); } } } break; default : { actionResult = false; break; } } } break; case EBAT_Dodge : { switch ( stage ) { case BS_Released : { theGame.GetBehTreeReactionManager().CreateReactionEvent( this, 'PlayerEvade', 1.0f, 10.0f, -1.0f, -1 ); thePlayer.BreakPheromoneEffect(); actionResult = this.OnPerformEvade( PET_Dodge ); } break; default : { actionResult = false; } break; } } break; case EBAT_Roll : { if ( IsCiri() ) return false; switch ( stage ) { case BS_Released : { theGame.GetBehTreeReactionManager().CreateReactionEvent( this, 'PlayerEvade', 1.0f, 10.0f, -1.0f, -1 ); thePlayer.BreakPheromoneEffect(); actionResult = this.OnPerformEvade( PET_Roll ); } break; case BS_Pressed : { if ( this.GetBehaviorVariable( 'combatActionType' ) == 2.f ) { if ( GetCurrentStateName() == 'CombatSteel' || GetCurrentStateName() == 'CombatSilver' ) actionResult = this.OnPerformEvade( PET_Pirouette ); else actionResult = this.OnPerformEvade( PET_Roll ); } else { if ( GetCurrentStateName() == 'CombatSteel' || GetCurrentStateName() == 'CombatSilver' ) { actionResult = this.OnPerformEvade( PET_Dodge ); actionResult = this.OnPerformEvade( PET_Pirouette ); } else { actionResult = this.OnPerformEvade( PET_Dodge ); actionResult = this.OnPerformEvade( PET_Roll ); } } } break; default : { actionResult = false; } break; } } break; case EBAT_Draw_Steel : { switch ( stage ) { case BS_Pressed : { if( !IsActionAllowed(EIAB_DrawWeapon) ) { thePlayer.DisplayActionDisallowedHudMessage(EIAB_DrawWeapon); actionResult = false; break; } if( GetWitcherPlayer().IsItemEquippedByCategoryName( 'steelsword' ) ) { OnEquipMeleeWeapon( PW_Steel, false, true ); } actionResult = false; } break; default : { actionResult = false; } break; } } break; case EBAT_Draw_Silver : { switch ( stage ) { case BS_Pressed : { if( !IsActionAllowed(EIAB_DrawWeapon) ) { thePlayer.DisplayActionDisallowedHudMessage(EIAB_DrawWeapon); actionResult = false; break; } if( GetWitcherPlayer().IsItemEquippedByCategoryName( 'silversword' ) ) { OnEquipMeleeWeapon( PW_Silver, false, true ); } actionResult = false; } break; default : { actionResult = false; } break; } } break; case EBAT_Sheathe_Sword : { switch ( stage ) { case BS_Pressed : { if( GetCurrentMeleeWeaponType() == PW_Silver ) { if( GetWitcherPlayer().IsItemEquippedByCategoryName( 'silversword' ) ) { OnEquipMeleeWeapon( PW_Silver, false, true ); } } else if( GetCurrentMeleeWeaponType() == PW_Steel ) { if( GetWitcherPlayer().IsItemEquippedByCategoryName( 'steelsword' ) ) { OnEquipMeleeWeapon( PW_Steel, false, true ); } } actionResult = false; } break; default : { actionResult = false; } break; } } break; default: return false; } CleanCombatActionBuffer(); if (actionResult) { SetCombatAction( action ) ; if(GetWitcherPlayer().IsInFrenzy()) GetWitcherPlayer().SkillFrenzyFinish(0); } return true; } public function CleanCombatActionBuffer() { BufferCombatAction = EBAT_EMPTY; BufferAllSteps = false; } public function CancelHoldAttacks() { RemoveTimer( 'IsSpecialLightAttackInputHeld' ); RemoveTimer( 'IsSpecialHeavyAttackInputHeld' ); RemoveTimer( 'SpecialAttackLightSustainCost' ); RemoveTimer( 'SpecialAttackHeavySustainCost' ); RemoveTimer( 'UpdateSpecialAttackLightHeading' ); UnblockAction( EIAB_Crossbow, 'SpecialAttack' ); ResumeStaminaRegen('WhirlSkill'); if ( GetBehaviorVariable( 'combatActionType' ) == (int)CAT_SpecialAttack && GetBehaviorVariable( 'isPerformingSpecialAttack' ) == 1.f ) { if( GetBehaviorVariable( 'playerAttackType' ) == (int)PAT_Light ) { SetAttackActionName(SkillEnumToName(S_Sword_s01)); PushCombatActionOnBuffer( EBAT_SpecialAttack_Light, BS_Released ); ProcessCombatActionBuffer(); ((W3PlayerWitcherStateCombatFists) GetState('Combat')).ResetTimeToEndCombat(); } else if( GetBehaviorVariable( 'playerAttackType' ) == (int)PAT_Heavy ) { SetAttackActionName(SkillEnumToName(S_Sword_s02)); PushCombatActionOnBuffer( EBAT_SpecialAttack_Heavy, BS_Released ); ProcessCombatActionBuffer(); } } } public function RaiseAttackFriendlyEvent( actor : CActor ) : bool { var playerToTargetHeading : float; if ( actor && RaiseCombatActionFriendlyEvent() ) { SetBehaviorVariable( 'tauntTypeForOverlay', 0.f ); SetBehaviorVariable( 'combatActionTypeForOverlay', (int)CAT_Attack ); if ( actor ) actor.SignalGameplayEvent('PersonalTauntAction'); theGame.GetBehTreeReactionManager().CreateReactionEventIfPossible( this, 'TauntAction', -1.0, 4.5f, -1, 9999, true ); OnCombatActionStart(); playerToTargetHeading = VecHeading( actor.GetWorldPosition() - GetWorldPosition() ); SetCustomRotation( 'Attack', playerToTargetHeading, 0.0f, 0.3f, false ); return true; } return false; } public function SendAttackReactionEvent() { var reactionName : name; reactionName = 'AttackAction'; if ( IsNameValid(reactionName) ) { theGame.GetBehTreeReactionManager().CreateReactionEventIfPossible( this, reactionName, -1.0, 8.0f, -1, 5, true ); } theGame.GetBehTreeReactionManager().CreateReactionEventIfPossible( this, 'outOfMyWay', -1.0, 2.0f, -1, 5, true ); } var forceCanAttackWhenNotInCombat : int; public function SetForceCanAttackWhenNotInCombat( forceMode : int ) { forceCanAttackWhenNotInCombat = forceMode; } public function CanAttackWhenNotInCombat( actionType : EBufferActionType, altCast : bool, out newTarget : CActor, optional target : CGameplayEntity ) : bool { var localTargets : array; var i, size : int; var inputHeading : float; var clearanceMin, clearanceMax : float; var attackLength : float; var attackAngle : float; var npc : CNewNPC; var canAttackTarget : CGameplayEntity; var canAttackTargetActor : CActor; if ( target ) canAttackTarget = target; else if ( displayTarget && IsDisplayTargetTargetable() ) canAttackTarget = displayTarget; else canAttackTarget = slideTarget; canAttackTargetActor = (CActor)canAttackTarget; if ( forceCanAttackWhenNotInCombat == 2 ) return true; else if ( forceCanAttackWhenNotInCombat == 1 && ( !canAttackTarget || !canAttackTargetActor.IsHuman() ) ) return true; if ( actionType == EBAT_CastSign ) { if ( thePlayer.GetEquippedSign() != ST_Quen && thePlayer.GetEquippedSign() != ST_Axii ) { if ( CanUseSkill( S_Magic_s20 ) ) { if ( thePlayer.GetEquippedSign() == ST_Aard ) attackLength = 6.f; else if ( thePlayer.GetEquippedSign() == ST_Igni ) attackLength = 4.f; else attackLength = 6.f; } else { if ( thePlayer.GetEquippedSign() == ST_Aard ) attackLength = 9.f; else if ( thePlayer.GetEquippedSign() == ST_Igni ) attackLength = 6.f; else attackLength = 6.f; } if ( altCast ) attackAngle = 180.f; else attackAngle = 90.f; if ( !lastAxisInputIsMovement ) inputHeading = VecHeading( theCamera.GetCameraDirection() ); else if ( lAxisReleasedAfterCounter ) inputHeading = GetHeading(); else inputHeading = GetCombatActionHeading(); clearanceMin = 1.f; clearanceMax = attackLength + 1.f; } else if ( thePlayer.GetEquippedSign() == ST_Axii ) { npc = (CNewNPC)canAttackTarget; if ( npc && npc.GetNPCType() == ENGT_Quest && !npc.HasTag(theGame.params.TAG_AXIIABLE_LOWER_CASE) && !npc.HasTag(theGame.params.TAG_AXIIABLE)) return false; else if ( npc && npc.IsUsingHorse() ) return false; else return true; } else return true; } else if ( actionType == EBAT_ItemUse ) { attackLength = theGame.params.MAX_THROW_RANGE; attackAngle = 90.f; if ( thePlayer.lastAxisInputIsMovement ) inputHeading = GetCombatActionHeading(); else inputHeading = VecHeading( theCamera.GetCameraDirection() ); clearanceMin = 0.8f; clearanceMax = attackLength + 3.f; } else { if ( actionType == EBAT_SpecialAttack_Light || actionType == EBAT_SpecialAttack_Heavy ) { attackLength = 1.9f; attackAngle = 90.f; } else { if( thePlayer.GetCurrentMeleeWeaponType() == PW_Fists || thePlayer.GetCurrentMeleeWeaponType() == PW_None ) attackLength = 1.2f; else attackLength = 1.9f; attackAngle = 90.f; } if ( lastAxisInputIsMovement ) inputHeading = GetCombatActionHeading(); else inputHeading = VecHeading( theCamera.GetCameraDirection() ); clearanceMin = attackLength / 2.f; clearanceMax = attackLength + 3.f; } if ( canAttackTarget ) { if ( ( canAttackTargetActor && canAttackTargetActor.IsHuman() ) || canAttackTargetActor.HasTag( 'softLock_Friendly' ) ) { if ( ShouldPerformFriendlyAction( canAttackTargetActor, inputHeading, attackAngle, clearanceMin, clearanceMax ) ) { SetSlideTarget( canAttackTargetActor ); newTarget = canAttackTargetActor; return false; } } } return true; thePlayer.GetVisibleEnemies( localTargets ); size = localTargets.Size(); if ( size > 0 ) { for ( i = size-1; i>=0; i-=1 ) { if ( !localTargets[i].IsHuman() && !localTargets[i].HasTag( 'softLock_Friendly' ) ) localTargets.Erase(i); } } size = localTargets.Size(); if ( size > 0 ) { for ( i = 0; i < localTargets.Size(); i += 1 ) { if ( ShouldPerformFriendlyAction( localTargets[i], inputHeading, attackAngle, clearanceMin, clearanceMax ) ) { SetSlideTarget( localTargets[i] ); newTarget = localTargets[i]; return false; } } } newTarget = NULL; return true; } private function ShouldPerformFriendlyAction( actor : CActor, inputHeading, attackAngle, clearanceMin, clearanceMax : float ) : bool { var npc : CNewNPC; var argh : float; var playerToTargetDist : float; npc = (CNewNPC)actor; if ( npc && ( GetAttitudeBetween(thePlayer, npc) == AIA_Hostile || ( GetAttitudeBetween(thePlayer, npc) == AIA_Neutral && npc.GetNPCType() != ENGT_Guard ) ) ) { } else { playerToTargetDist = VecDistance( this.GetWorldPosition(), actor.PredictWorldPosition( 0.5f ) ); argh = AbsF( AngleDistance( inputHeading, VecHeading( actor.GetWorldPosition() - thePlayer.GetWorldPosition() ) ) ); if ( AbsF( AngleDistance( inputHeading, VecHeading( actor.GetWorldPosition() - thePlayer.GetWorldPosition() ) ) ) < attackAngle ) { if ( playerToTargetDist < clearanceMax ) { return true; } } else { if ( playerToTargetDist < clearanceMin ) { return true; } } } return false; } public function GetHudMessagesSize() : int { return HudMessages.Size(); } public function GetHudPendingMessage() : string { return HudMessages[0]; } public function DisplayHudMessage( value : string ) : void { if (value == "") { return; } if( GetHudMessagesSize() > 0 ) { if( HudMessages[HudMessages.Size()-1] == value ) { return; } } HudMessages.PushBack(value); } private final function DisallowedActionDontShowHack(action : EInputActionBlock, isTimeLock : bool) : bool { var locks : array< SInputActionLock >; var i : int; if((action == EIAB_Fists || action == EIAB_SwordAttack || action == EIAB_Signs || action == EIAB_LightAttacks || action == EIAB_HeavyAttacks || action == EIAB_SpecialAttackLight || action == EIAB_SpecialAttackHeavy) && (HasBuff(EET_Stagger) || HasBuff(EET_LongStagger)) ) { return true; } if( action == EIAB_ThrowBomb && ( HasBuff( EET_Hypnotized ) || HasBuff( EET_Confusion ) ) ) { return false; } if(isTimeLock) return false; if(action == EIAB_OpenMeditation) return false; locks = GetActionLocks(action); for(i=0; i= i; j-=1) { if(HudMessages[i] == msg) { HudMessages.EraseFast(i); } } } public function RemoveHudMessageByIndex(idx : int) { if(idx >= 0 && idx < HudMessages.Size()) HudMessages.Erase(idx); } function SetSettlementBlockCanter( valueAdd : int ) { m_SettlementBlockCanter += valueAdd; } var countDownToStart : int; default countDownToStart = 0; function DisplayRaceStart( countDownSecondsNumber : int ) { var i : int; countDownToStart = countDownSecondsNumber; for( i = countDownSecondsNumber; i > 0; i -= 1 ) { DisplayHudMessage(IntToString(i)); } DisplayHudMessage(GetLocStringByKeyExt("panel_hud_message_race_start")); AddTimer('RaceCountdown',1,true); } timer function RaceCountdown(dt : float, id : int) { var hud : CR4ScriptedHud; var messageModule : CR4HudModuleMessage; countDownToStart -= 1; hud = (CR4ScriptedHud)theGame.GetHud(); if( hud ) { messageModule = (CR4HudModuleMessage)hud.GetHudModule("MessageModule"); if( messageModule ) { messageModule.OnMessageHidden(); } } if( countDownToStart <= 0 ) { RemoveTimer('RaceCountdown'); } } public function GetCountDownToStart() : int { return countDownToStart; } public function HAXE3GetContainer() : W3Container { return HAXE3Container; } public function HAXE3SetContainer( container : W3Container) : void { HAXE3Container = container; } public function HAXE3GetAutoLoot() : bool { return HAXE3bAutoLoot; } public function HAXE3SetAutoLoot( value : bool ) : void { HAXE3bAutoLoot = value; } public function GetShowHud() : bool { return bShowHud; } public function SetShowHud( value : bool ) : void { bShowHud = value; } public function DisplayItemRewardNotification( itemName : name, optional quantity : int ) : void { var hud : CR4ScriptedHud; hud = (CR4ScriptedHud)theGame.GetHud(); hud.OnItemRecivedDuringScene(itemName, quantity); } function IsNewQuest( questGuid : CGUID ) : bool { var i : int; for(i = 0; i < displayedQuestsGUID.Size(); i += 1 ) { if( displayedQuestsGUID[i] == questGuid ) { return false; } } displayedQuestsGUID.PushBack(questGuid); return true; } function GetRewardMultiplierData( rewardName : name ) : SRewardMultiplier { var defaultReward : SRewardMultiplier; var i : int; for(i = 0; i < rewardsMultiplier.Size(); i += 1 ) { if( rewardsMultiplier[i].rewardName == rewardName ) { return rewardsMultiplier[i]; } } defaultReward.rewardName = rewardName; defaultReward.rewardMultiplier = 1.0; defaultReward.isItemMultiplier = false; return defaultReward; } function GetRewardMultiplier( rewardName : name ) : float { var i : int; for(i = 0; i < rewardsMultiplier.Size(); i += 1 ) { if( rewardsMultiplier[i].rewardName == rewardName ) { return rewardsMultiplier[i].rewardMultiplier; } } return 1.0; } function GetRewardMultiplierExists( rewardName : name ) : bool { var i : int; for(i = 0; i < rewardsMultiplier.Size(); i += 1 ) { if( rewardsMultiplier[i].rewardName == rewardName ) { return true; } } return false; } function SetRewardMultiplier( rewardName : name, value : float, optional isItemMultiplier : bool ) : void { var i : int; var rewardMultiplier : SRewardMultiplier; for(i = 0; i < rewardsMultiplier.Size(); i += 1 ) { if( rewardsMultiplier[i].rewardName == rewardName ) { rewardsMultiplier[i].rewardMultiplier = value; rewardsMultiplier[i].isItemMultiplier = isItemMultiplier; return; } } rewardMultiplier.rewardName = rewardName; rewardMultiplier.rewardMultiplier = value; rewardMultiplier.isItemMultiplier = isItemMultiplier; rewardsMultiplier.PushBack(rewardMultiplier); } function RemoveRewardMultiplier( rewardName : name ) : void { var i : int; for(i = 0; i < rewardsMultiplier.Size(); i += 1 ) { if( rewardsMultiplier[i].rewardName == rewardName ) { rewardsMultiplier.Erase(i); return; } } } public final function TissueExtractorDischarge() : bool { var ids : array; var chargesLeft, uses, curr, max, red, blue, green : int; var i : int; var text : string; ids = thePlayer.inv.GetItemsByName( 'q705_tissue_extractor' ); if( ids.Size() == 0 ) { return false; } curr = GetTissueExtractorChargesCurr(); max = GetTissueExtractorChargesMax(); if( curr >= max ) { uses = FloorF( ( ( float ) curr ) / ( ( float ) max ) ); chargesLeft = Max( 0, curr - uses * max ); inv.SetItemModifierInt( ids[0], 'charges', chargesLeft ); blue = 0; green = 0; red = 0; for( i=0; i 0 ) { inv.AddAnItem( 'Greater mutagen blue', blue, false, true ); text += "
" + blue + "x " + GetLocStringByKey( inv.GetItemLocalizedNameByName( 'Greater mutagen blue' ) ); } if( green > 0 ) { inv.AddAnItem( 'Greater mutagen green', green, false, true ); text += "
" + green + "x " + GetLocStringByKey( inv.GetItemLocalizedNameByName( 'Greater mutagen green' ) ); } if( red > 0 ) { inv.AddAnItem( 'Greater mutagen red', red, false, true ); text += "
" + red + "x " + GetLocStringByKey( inv.GetItemLocalizedNameByName( 'Greater mutagen red' ) ); } theGame.GetGuiManager().ShowNotification( text ); inv.SetItemModifierInt( ids[0], 'ui_notified', 0 ); return true; } else { theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt( "message_q705_extractor_too_few_charges" ) ); } return false; } public final function TissueExtractorIncCharge() { var ids : array; var uiData : SInventoryItemUIData; var curr : int; ids = thePlayer.inv.GetItemsByName( 'q705_tissue_extractor' ); if( ids.Size() == 0 ) { return; } curr = GetTissueExtractorChargesCurr() + 1; inv.SetItemModifierInt( ids[0], 'charges', curr ); if( curr >= GetTissueExtractorChargesMax() ) { uiData = inv.GetInventoryItemUIData( ids[0] ); uiData.isNew = true; inv.SetInventoryItemUIData( ids[0], uiData ); if( inv.GetItemModifierInt( ids[0], 'ui_notified', 0 ) == 0 ) { inv.SetItemModifierInt( ids[0], 'ui_notified', 1 ); theGame.GetGuiManager().ShowNotification( GetLocStringByKeyExt( "message_q705_extractor_charged" ), , true ); } } } public final function GetTissueExtractorChargesCurr() : int { var ids : array; ids = thePlayer.inv.GetItemsByName( 'q705_tissue_extractor' ); if( ids.Size() == 0 ) { return 0; } return inv.GetItemModifierInt( ids[0], 'charges', 0 ); } public final function GetTissueExtractorChargesMax() : int { var ids : array; var val : SAbilityAttributeValue; ids = thePlayer.inv.GetItemsByName( 'q705_tissue_extractor' ); if( ids.Size() == 0 ) { return 0; } val = inv.GetItemAttributeValue( ids[0], 'maxCharges' ); return FloorF( val.valueBase ); } public function GetEquippedSword(steel : bool) : SItemUniqueId; public final function HasRequiredLevelToEquipItem(item : SItemUniqueId) : bool { if(HasBuff(EET_WolfHour)) { if((inv.GetItemLevel(item) - 2) > GetLevel() ) return false; } else { if(inv.GetItemLevel(item) > GetLevel() ) return false; } return true; } public function SkillReduceBombAmmoBonus() { var i, ammo, maxAmmo : int; var items : array; items = inv.GetSingletonItems(); for(i=0; i 0) { maxAmmo = inv.SingletonItemGetMaxAmmo(items[i]); if(ammo > maxAmmo) { inv.SetItemModifierInt(items[i], 'ammo_current', maxAmmo); } } } theGame.GetGlobalEventsManager().OnScriptedEvent( SEC_OnAmmoChanged ); } public function ConsumeItem( itemId : SItemUniqueId ) : bool { var params : SCustomEffectParams; var buffs : array; var i : int; var category : name; var potionToxicity : float; if(!inv.IsIdValid(itemId)) return false; category = inv.GetItemCategory(itemId); if(category == 'edibles' || inv.ItemHasTag(itemId, 'Drinks') || ( category == 'alchemy_ingredient' && inv.ItemHasTag(itemId, 'Alcohol')) ) { if(IsFistFightMinigameEnabled()) { DisplayActionDisallowedHudMessage(EIAB_Undefined, false, false, true); return false; } inv.GetItemBuffs(itemId, buffs); for(i=0; i= cost) ); if(!ret && IsSkillSign(skill) && CanUseSkill(S_Perk_09) && GetStat(BCS_Focus) >= 1) { ret = true; } if( !ret && IsSkillSign( skill ) && GetWitcherPlayer().HasBuff( EET_GryphonSetBonus ) ) { ret = true; } if(!ret) { SetCombatActionHeading( GetHeading() ); SetShowToLowStaminaIndication(cost); } return ret; } protected function GetSkillStaminaUseCost(skill : ESkill, optional perSec : bool) : float { if(abilityManager && abilityManager.IsInitialized()) return ((W3PlayerAbilityManager)abilityManager).GetSkillStaminaUseCost(skill, perSec); return 0; } public function GetSkillAttributeValue(skill : ESkill, attributeName : name, addBaseCharAttribute : bool, addSkillModsAttribute : bool) : SAbilityAttributeValue { var null : SAbilityAttributeValue; if(abilityManager && abilityManager.IsInitialized()) return abilityManager.GetSkillAttributeValue(SkillEnumToName(skill), attributeName, addBaseCharAttribute, addSkillModsAttribute); return null; } public function GetSkillLocalisationKeyName(skill : ESkill) : string { if(abilityManager && abilityManager.IsInitialized()) return ((W3PlayerAbilityManager)abilityManager).GetSkillLocalisationKeyName(skill); return ""; } public function GetSkillLocalisationKeyDescription(skill : ESkill) : string { if(abilityManager && abilityManager.IsInitialized()) return ((W3PlayerAbilityManager)abilityManager).GetSkillLocalisationKeyDescription(skill); return ""; } public function GetSkillIconPath(skill : ESkill) : string { if(abilityManager && abilityManager.IsInitialized()) return ((W3PlayerAbilityManager)abilityManager).GetSkillIconPath(skill); return ""; } public function HasLearnedSkill(skill : ESkill) : bool { if(abilityManager && abilityManager.IsInitialized()) return ((W3PlayerAbilityManager)abilityManager).HasLearnedSkill(skill); return false; } public function IsSkillEquipped(skill : ESkill) : bool { if(abilityManager && abilityManager.IsInitialized()) return ((W3PlayerAbilityManager)abilityManager).IsSkillEquipped(skill); return false; } public function CanUseSkill(skill : ESkill) : bool { if(abilityManager && abilityManager.IsInitialized()) return ((W3PlayerAbilityManager)abilityManager).CanUseSkill(skill); return false; } public function CanLearnSkill(skill : ESkill) : bool { if(abilityManager && abilityManager.IsInitialized()) return ((W3PlayerAbilityManager)abilityManager).CanLearnSkill(skill); return false; } public function HasSpentEnoughPoints(skill : ESkill) : bool { if(abilityManager && abilityManager.IsInitialized()) return ((W3PlayerAbilityManager)abilityManager).HasSpentEnoughPoints(skill); return false; } public function PathPointsForSkillsPath(skill : ESkill) : int { if(abilityManager && abilityManager.IsInitialized()) return ((W3PlayerAbilityManager)abilityManager).PathPointsSpentInSkillPathOfSkill(skill); return -1; } public function GetPlayerSkills() : array { var null : array; if(abilityManager && abilityManager.IsInitialized()) return ((W3PlayerAbilityManager)abilityManager).GetPlayerSkills(); return null; } public function GetPlayerSkill(s : ESkill) : SSkill { var null : SSkill; if(abilityManager && abilityManager.IsInitialized()) return ((W3PlayerAbilityManager)abilityManager).GetPlayerSkill(s); return null; } public function GetSkillSubPathType(s : ESkill) : ESkillSubPath { if(abilityManager && abilityManager.IsInitialized()) return ((W3PlayerAbilityManager)abilityManager).GetSkillSubPathType(s); return ESSP_NotSet; } public function GetSkillSlotsCount() : int { if(abilityManager && abilityManager.IsInitialized()) return ((W3PlayerAbilityManager)abilityManager).GetSkillSlotsCount(); return 0; } public function GetSkillSlots() : array { var null : array; if(abilityManager && abilityManager.IsInitialized()) return ((W3PlayerAbilityManager)abilityManager).GetSkillSlots(); return null; } public function GetPlayerSkillMutagens() : array { var null : array; if(abilityManager && abilityManager.IsInitialized()) return ((W3PlayerAbilityManager)abilityManager).GetPlayerSkillMutagens(); return null; } public function BlockSkill(skill : ESkill, block : bool, optional cooldown : float) : bool { if(abilityManager && abilityManager.IsInitialized()) return ((W3PlayerAbilityManager)abilityManager).BlockSkill(skill, block, cooldown); return false; } public function IsSkillBlocked(skill : ESkill) : bool { if(abilityManager && abilityManager.IsInitialized()) return ((W3PlayerAbilityManager)abilityManager).IsSkillBlocked(skill); return false; } public function EquipSkill(skill : ESkill, slotID : int) : bool { var ret : bool; var groupID : int; var pam : W3PlayerAbilityManager; if(abilityManager && abilityManager.IsInitialized()) { pam = (W3PlayerAbilityManager)abilityManager; ret = pam.EquipSkill(skill, slotID); if(ret) { groupID = pam.GetSkillGroupIdFromSkillSlotId(slotID); LogSkillColors("Equipped <<" + GetSkillColor(skill) + ">> skill <<" + skill + ">> to group <<" + groupID + ">>"); LogSkillColors("Group bonus color is now <<" + pam.GetSkillGroupColor(groupID) + ">>"); LogSkillColors(""); } return ret; } return false; } public function UnequipSkill(slotID : int) : bool { var ret : bool; var groupID : int; var skill : ESkill; var pam : W3PlayerAbilityManager; if(abilityManager && abilityManager.IsInitialized()) { pam = (W3PlayerAbilityManager)abilityManager; GetSkillOnSlot(slotID, skill); ret = pam.UnequipSkill(slotID); if(ret) { groupID = pam.GetSkillGroupIdFromSkillSlotId(slotID); LogSkillColors("Unequipped <<" + GetSkillColor(skill) + ">> skill <<" + skill + ">> from group <<" + groupID + ">>"); LogSkillColors("Group bonus color is now <<" + pam.GetSkillGroupColor(groupID) + ">>"); LogSkillColors(""); } return ret; } return false; } public function GetSkillOnSlot(slotID : int, out skill : ESkill) : bool { if(abilityManager && abilityManager.IsInitialized()) return ((W3PlayerAbilityManager)abilityManager).GetSkillOnSlot(slotID, skill); skill = S_SUndefined; return false; } public function GetFreeSkillSlot() : int { var i, size : int; var skill : ESkill; size = ((W3PlayerAbilityManager)abilityManager).GetSkillSlotsCount(); for(i=1; i, attackAnimationName : name, hitTime : float, weaponEntity : CItemEntity) { var attackAction : W3Action_Attack; if(!PrepareAttackAction(hitTarget, animData, weaponId, parried, countered, parriedBy, attackAnimationName, hitTime, weaponEntity, attackAction)) return; if ( attackAction.IsParried() && ( ((CNewNPC)attackAction.victim).IsShielded(attackAction.attacker) || ((CNewNPC)attackAction.victim).SignalGameplayEventReturnInt('IsDefending',0) == 1 ) ) { thePlayer.SetCanPlayHitAnim(true); thePlayer.ReactToReflectedAttack(attackAction.victim); } theTelemetry.LogWithLabel( TE_FIGHT_PLAYER_ATTACKS, attackAction.GetAttackName() ); theGame.damageMgr.ProcessAction(attackAction); delete attackAction; } public function IsHeavyAttack(attackName : name) : bool { var skill : ESkill; var sup : bool; sup = super.IsHeavyAttack(attackName); if(sup) return true; if ( attackName == 'attack_heavy_special' ) return true; skill = SkillNameToEnum(attackName); return skill == S_Sword_2 || skill == S_Sword_s02; } public function IsLightAttack(attackName : name) : bool { var skill : ESkill; var sup : bool; sup = super.IsLightAttack(attackName); if(sup) return true; skill = SkillNameToEnum(attackName); return skill == S_Sword_1 || skill == S_Sword_s01; } public final function ProcessWeaponCollision() { var l_stateName : name; var l_weaponPosition : Vector; var l_weaponTipPos : Vector; var l_collidingPosition : Vector; var l_offset : Vector; var l_normal : Vector; var l_slotMatrix : Matrix; var l_distance : float; var l_materialName : name; var l_hitComponent : CComponent; var l_destructibleCmp : CDestructionSystemComponent; var barrel : COilBarrelEntity; if( isCurrentlyDodging ) return; l_stateName = GetCurrentStateName(); if( !attackEventInProgress && l_stateName == 'CombatFists' ) return; CalcEntitySlotMatrix('r_weapon', l_slotMatrix); l_weaponPosition = MatrixGetTranslation( l_slotMatrix ); switch( l_stateName ) { case 'CombatFists': l_offset = MatrixGetAxisX( l_slotMatrix ); l_offset = VecNormalize( l_offset ) * 0.25f; break; default: l_offset = MatrixGetAxisZ( l_slotMatrix ); l_offset = VecNormalize( l_offset ) * 1.f; break; } l_weaponTipPos = l_weaponPosition + l_offset; if( !attackEventInProgress ) { if( m_LastWeaponTipPos == Vector ( 0, 0, 0 ) ) l_distance = 0; else l_distance = VecDistance( l_weaponTipPos, m_LastWeaponTipPos ) ; m_LastWeaponTipPos = l_weaponTipPos; if( l_distance < 0.35f ) return; } m_LastWeaponTipPos = l_weaponTipPos; if ( !theGame.GetWorld().StaticTraceWithAdditionalInfo( l_weaponPosition, l_weaponTipPos, l_collidingPosition, l_normal, l_materialName, l_hitComponent, m_WeaponFXCollisionGroupNames ) ) { if( l_stateName == 'CombatFists' ) { CalcEntitySlotMatrix('l_weapon', l_slotMatrix); l_weaponPosition = MatrixGetTranslation( l_slotMatrix ); l_offset = MatrixGetAxisX( l_slotMatrix ); l_offset = VecNormalize( l_offset ) * 0.25f; l_weaponTipPos = l_weaponPosition + l_offset; if( !theGame.GetWorld().StaticTrace( l_weaponPosition, l_weaponTipPos, l_collidingPosition, l_normal, m_WeaponFXCollisionGroupNames ) ) { return; } } else { return; } } if( !m_CollisionEffect ) { m_CollisionEffect = theGame.CreateEntity( m_CollisionFxTemplate, l_collidingPosition, EulerAngles(0,0,0) ); } m_CollisionEffect.Teleport( l_collidingPosition ); switch( l_stateName ) { case 'CombatFists': m_CollisionEffect.PlayEffect('fist'); break; default: if( m_RefreshWeaponFXType ) { m_PlayWoodenFX = IsSwordWooden(); m_RefreshWeaponFXType = false; } if( m_PlayWoodenFX ) { m_CollisionEffect.PlayEffect('wood'); } else { switch( l_materialName ) { case 'wood_hollow': case 'wood_debris': case 'wood_solid': m_CollisionEffect.PlayEffect('wood'); break; case 'dirt_hard': case 'dirt_soil': case 'hay': m_CollisionEffect.PlayEffect('fist'); break; case 'stone_debris': case 'stone_solid': case 'clay_tile': case 'gravel_large': case 'gravel_small': case 'metal': case 'custom_sword': m_CollisionEffect.PlayEffect('sparks'); break; case 'flesh': m_CollisionEffect.PlayEffect('blood'); break; default: m_CollisionEffect.PlayEffect('wood'); break; } } break; } if(l_hitComponent) { barrel = (COilBarrelEntity)l_hitComponent.GetEntity(); if(barrel) { barrel.OnFireHit(NULL); return; } } l_destructibleCmp = (CDestructionSystemComponent) l_hitComponent; if( l_destructibleCmp && l_stateName != 'CombatFists' ) { l_destructibleCmp.ApplyFracture(); } } public function ReactToReflectedAttack( target : CGameplayEntity) { var hp, dmg : float; var action : W3DamageAction; super.ReactToReflectedAttack(target); theGame.VibrateControllerLight(); } function GetFallDist( out fallDist : float ) : bool { var fallDiff, jumpTotalDiff : float; substateManager.m_SharedDataO.CalculateFallingHeights( fallDiff, jumpTotalDiff ); if ( fallDiff <= 0 ) return false; fallDist = fallDiff; return true; } function ApplyFallingDamage(heightDiff : float, optional reducing : bool) : float { var hpPerc : float; var tut : STutorialMessage; if ( IsSwimming() || FactsQuerySum("block_falling_damage") >= 1 ) return 0.0f; hpPerc = super.ApplyFallingDamage( heightDiff, reducing ); if(hpPerc > 0) { theGame.VibrateControllerHard(); if(IsAlive()) { if(ShouldProcessTutorial('TutorialFallingDamage')) { FactsSet( "tutorial_falling_damage", 1 ); } if(FactsQuerySum("tutorial_falling_damage") > 1 && ShouldProcessTutorial('TutorialFallingRoll')) { tut.type = ETMT_Hint; tut.tutorialScriptTag = 'TutorialFallingRoll'; tut.hintPositionType = ETHPT_DefaultGlobal; tut.hintDurationType = ETHDT_Long; tut.canBeShownInMenus = false; tut.glossaryLink = false; tut.markAsSeenOnShow = true; theGame.GetTutorialSystem().DisplayTutorial(tut); } } } return hpPerc; } public function SetShowToLowStaminaIndication( value : float ) : void { fShowToLowStaminaIndication = value; } public function GetShowToLowStaminaIndication() : float { return fShowToLowStaminaIndication; } public final function IndicateTooLowAdrenaline() { SoundEvent("gui_no_adrenaline"); showTooLowAdrenaline = true; } protected function GotoCombatStateWithAction( initialAction : EInitialAction, optional initialBuff : CBaseGameplayEffect ) { if ( this.GetCurrentActionType() == ActorAction_Exploration ) ActionCancelAll(); ((W3PlayerWitcherStateCombatFists)this.GetState('CombatFists')).SetupState( initialAction, initialBuff ); this.GotoState( 'CombatFists' ); } public function IsThreat( actor : CActor, optional usePrecalcs : bool ) : bool { var npc : CNewNPC; var dist : float; var targetCapsuleHeight : float; var isDistanceExpanded : bool; var distanceToTarget : float; var attitude : EAIAttitude; if (!actor) { return false; } if ( finishableEnemiesList.Contains( actor ) ) { return true; } if ( !actor.IsAlive() || actor.IsKnockedUnconscious() ) { return false; } npc = (CNewNPC)actor; if (npc && npc.IsHorse() ) { return false; } if ( hostileEnemies.Contains( actor ) ) { return true; } if ( GetAttitudeBetween( this, actor ) == AIA_Hostile ) { if ( usePrecalcs ) { distanceToTarget = Distance2DBetweenCapsuleAndPoint( actor, this ) - targetingPrecalcs.playerRadius; } else { distanceToTarget = Distance2DBetweenCapsules( this, actor ); } if ( distanceToTarget < findMoveTargetDist + 5.0f ) { return true; } if ( actor.IsInCombat() || this.IsHardLockEnabled() ) { targetCapsuleHeight = ( (CMovingPhysicalAgentComponent)actor.GetMovingAgentComponent() ).GetCapsuleHeight(); if ( targetCapsuleHeight >= 2.0f || npc.GetCurrentStance() == NS_Fly ) { if ( distanceToTarget < 40.0f ) { return true; } } } } if ( actor.GetAttitudeGroup() == 'npc_charmed' ) { if ( theGame.GetGlobalAttitude( GetBaseAttitudeGroup(), actor.GetBaseAttitudeGroup() ) == AIA_Hostile ) { return true; } } return false; } function SetBIsCombatActionAllowed ( flag : bool ) { bIsCombatActionAllowed = flag; if ( !flag ) { SetBIsInCombatAction(true); } else { this.ProcessLAxisCaching(); } } function GetBIsCombatActionAllowed() : bool { return bIsCombatActionAllowed; } function SetCombatAction( action : EBufferActionType ) { currentCombatAction = action; } function GetCombatAction() : EBufferActionType { return currentCombatAction; } protected function WhenCombatActionIsFinished() { if(IsThrowingItem() || IsThrowingItemWithAim() ) { if(inv.IsItemBomb(selectedItemId)) { BombThrowAbort(); } else { ThrowingAbort(); } } if ( this.GetCurrentStateName() != 'DismountHorse' ) OnRangedForceHolster( true ); } public function IsInCombatAction_Attack(): bool { if ( IsInCombatAction_NonSpecialAttack() || IsInCombatAction_SpecialAttack() ) return true; else return false; } public function IsInCombatAction_NonSpecialAttack(): bool { if ( IsInCombatAction() && ( GetCombatAction() == EBAT_LightAttack || GetCombatAction() == EBAT_HeavyAttack ) ) return true; else return false; } public function IsInSpecificCombatAction ( specificCombatAction : EBufferActionType ) : bool { if ( IsInCombatAction() && GetCombatAction() == specificCombatAction ) return true; else return false; } public function IsInRunAnimation() : bool { return isInRunAnimation; } public function SetCombatIdleStance( stance : float ) { SetBehaviorVariable( 'combatIdleStance', stance ); SetBehaviorVariable( 'CombatStanceForOverlay', stance ); if ( stance == 0.f ) LogChannel( 'ComboInput', "combatIdleStance = Left" ); else LogChannel( 'ComboInput', "combatIdleStance = Right" ); } public function GetCombatIdleStance() : float { return GetBehaviorVariable( 'combatIdleStance' ); } protected var isRotatingInPlace : bool; event OnRotateInPlaceStart() { isRotatingInPlace = true; } event OnRotateInPlaceEnd() { isRotatingInPlace = false; } event OnFullyBlendedIdle() { if ( bLAxisReleased ) { ResetRawPlayerHeading(); ResetCachedRawPlayerHeading(); defaultLocomotionController.ResetMoveDirection(); } } private var isInIdle : bool; event OnPlayerIdleStart() { isInIdle = true; } event OnPlayerIdleEnd() { isInIdle = false; } public function IsInIdle() : bool { return isInIdle; } event OnRunLoopStart() { EnableRunCamera( true ); } event OnRunLoopEnd() { EnableRunCamera( false ); } event OnCombatActionStartBehgraph() { var action : EBufferActionType; var cost, delay : float; OnCombatActionStart(); action = PerformingCombatAction(); switch ( action ) { case EBAT_LightAttack : { abilityManager.GetStaminaActionCost(ESAT_LightAttack, cost, delay); } break; case EBAT_HeavyAttack : { abilityManager.GetStaminaActionCost(ESAT_HeavyAttack, cost, delay); } break; case EBAT_ItemUse : { abilityManager.GetStaminaActionCost(ESAT_UsableItem, cost, delay); } break; case EBAT_Parry : { abilityManager.GetStaminaActionCost(ESAT_Parry, cost, delay); } break; case EBAT_Dodge : { abilityManager.GetStaminaActionCost(ESAT_Dodge, cost, delay); } break; case EBAT_Roll : abilityManager.GetStaminaActionCost(ESAT_Roll, cost, delay); break; case EBAT_SpecialAttack_Light : { abilityManager.GetStaminaActionCost(ESAT_Ability, cost, delay, 0,0, GetSkillAbilityName(S_Sword_s01)); } break; case EBAT_SpecialAttack_Heavy : { abilityManager.GetStaminaActionCost(ESAT_Ability, cost, delay, 0,0, GetSkillAbilityName(S_Sword_s02)); } break; case EBAT_Roll : { abilityManager.GetStaminaActionCost(ESAT_Evade, cost, delay); } break; default : ; } if( delay > 0 ) PauseStaminaRegen( 'InsideCombatAction' ); } public function HolsterUsableItem() : bool { return holsterUsableItem; } private var isInGuardedState : bool; public function IsInGuardedState() : bool { return isInGuardedState; } event OnGuardedStart() { isInParryOrCounter = true; isInGuardedState = true; } event OnGuardedEnd() { isInParryOrCounter = false; isInGuardedState = false; } private var restoreUsableItem : bool; private var holsterUsableItem : bool; event OnCombatActionStart() { BlockAction( EIAB_UsableItem, 'OnCombatActionStart' ); BlockAction( EIAB_CallHorse, 'OnCombatActionStart' ); LogChannel('combatActionAllowed',"FALSE OnCombatActionStart"); SetBIsCombatActionAllowed( false ); SetBIsInputAllowed( false, 'OnCombatActionStart' ); ClearFinishableEnemyList( 0.f, 0 ); bIsInHitAnim = false; if ( rangedWeapon && rangedWeapon.GetCurrentStateName() != 'State_WeaponWait' ) { CleanCombatActionBuffer(); SetIsAimingCrossbow( false ); OnRangedForceHolster( false, true ); } holsterUsableItem = false; if ( thePlayer.IsHoldingItemInLHand() ) { if ( GetBehaviorVariable( 'combatActionType' ) == (int)CAT_CastSign ) holsterUsableItem = true; else if ( GetBehaviorVariable( 'combatActionType' ) == (int)CAT_Attack ) { if ( this.GetCurrentStateName() == 'CombatFists' ) holsterUsableItem = true; } } if ( holsterUsableItem ) { thePlayer.SetPlayerActionToRestore ( PATR_None ); thePlayer.OnUseSelectedItem( true ); restoreUsableItem = true; } if ( GetBehaviorVariable( 'combatActionType' ) != (int)CAT_Attack && GetBehaviorVariable( 'combatActionType' ) != (int)CAT_PreAttack ) { RemoveTimer( 'ProcessAttackTimer' ); RemoveTimer( 'AttackTimerEnd' ); UnblockAction( EIAB_DrawWeapon, 'OnCombatActionStart_Attack' ); } else { BlockAction( EIAB_DrawWeapon, 'OnCombatActionStart_Attack' ); } } var isInParryOrCounter : bool; event OnParryOrCounterStart() { isInParryOrCounter = true; OnCombatActionStartBehgraph(); } event OnParryOrCounterEnd() { isInParryOrCounter = false; OnCombatActionEnd(); SetBIsInCombatAction( false ); } event OnCombatActionEnd() { var item : SItemUniqueId; var combatActionType : float; super.OnCombatActionEnd(); BlockAllActions( 'OnCombatActionStart', false ); UnblockAction( EIAB_DrawWeapon, 'OnCombatActionStart_Attack' ); UnblockAction( EIAB_Movement, 'CombatActionFriendly' ); oTCameraOffset = 0.f; oTCameraPitchOffset = 0.f; SetBIsCombatActionAllowed( true ); SetBIsInputAllowed( true, 'OnCombatActionEnd' ); SetCanPlayHitAnim( true ); EnableFindTarget( true ); SetFinisherVictim( NULL ); OnBlockAllCombatTickets( false ); LogStamina("CombatActionEnd"); SetAttackActionName(''); combatActionType = GetBehaviorVariable('combatActionType'); if(GetBehaviorVariable('combatActionType') == (int)CAT_SpecialAttack) { theGame.GetGameCamera().StopAnimation( 'camera_shake_loop_lvl1_1' ); OnSpecialAttackHeavyActionProcess(); } substateManager.ReactToChanceToFallAndSlide(); } event OnCombatActionFriendlyStart() { SetBIsInCombatActionFriendly(true); BlockAction( EIAB_Movement, 'CombatActionFriendly', false, false, false ); OnCombatActionStart(); } event OnCombatActionFriendlyEnd() { SetBIsInCombatActionFriendly(false); UnblockAction( EIAB_Movement, 'CombatActionFriendly' ); OnCombatActionEnd(); SetBIsInCombatAction(false); } event OnHitStart() { var timeLeft : float; var currentEffects : array; var none : SAbilityAttributeValue; CancelHoldAttacks(); WhenCombatActionIsFinished(); if ( isInFinisher ) { if ( finisherTarget ) ( (CNewNPC)finisherTarget ).SignalGameplayEvent( 'FinisherInterrupt' ); isInFinisher = false; finisherTarget = NULL; SetBIsCombatActionAllowed( true ); } bIsInHitAnim = true; OnCombatActionStart(); ResumeStaminaRegen( 'InsideCombatAction' ); if( GetHealthPercents() < 0.3f ) { PlayBattleCry('BattleCryBadSituation', 0.10f, true ); } else { PlayBattleCry('BattleCryBadSituation', 0.05f, true ); } } event OnHitStartSwimming() { OnRangedForceHolster( true, true, false ); } private var finisherSaveLock : int; event OnFinisherStart() { var currentEffects : array; theGame.CreateNoSaveLock("Finisher",finisherSaveLock,true,false); isInFinisher = true; finisherTarget = slideTarget; OnCombatActionStart(); CancelHoldAttacks(); PlayFinisherCameraAnimation( theGame.GetSyncAnimManager().GetFinisherCameraAnimName() ); this.AddAnimEventCallback('SyncEvent','OnFinisherAnimEvent_SyncEvent'); SetImmortalityMode( AIM_Invulnerable, AIC_SyncedAnim ); } public function IsPerformingFinisher() : bool { return isInFinisher; } private function PlayFinisherCameraAnimation( cameraAnimName : name ) { var camera : CCustomCamera = theGame.GetGameCamera(); var animation : SCameraAnimationDefinition; if( IsLastEnemyKilled() && theGame.GetWorld().NavigationCircleTest( this.GetWorldPosition(), 3.f ) ) { camera.StopAnimation('camera_shake_hit_lvl3_1' ); animation.animation = cameraAnimName; animation.priority = CAP_Highest; animation.blendIn = 0.15f; animation.blendOut = 1.0f; animation.weight = 1.f; animation.speed = 1.0f; animation.reset = true; camera.PlayAnimation( animation ); thePlayer.EnableManualCameraControl( false, 'Finisher' ); } } public function IsLastEnemyKilled() : bool { var tempMoveTargets : array; FindMoveTarget(); tempMoveTargets = GetMoveTargets(); if ( tempMoveTargets.Size() <= 0 || !thePlayer.IsThreat( tempMoveTargets[0] ) ) return true; return false; } event OnFinisherAnimEvent_SyncEvent( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) { if ( finisherTarget ) ( (CNewNPC)finisherTarget ).SignalGameplayEvent('FinisherKill'); finisherTarget = NULL; } event OnFinisherEnd() { isInFinisher = false; finisherTarget = NULL; theGame.ReleaseNoSaveLock(finisherSaveLock); this.RemoveAnimEventCallback('SyncEvent'); SetImmortalityMode( AIM_None, AIC_SyncedAnim ); theGame.RemoveTimeScale( 'AnimEventSlomoMo' ); AddTimer( 'FinisherEndEnableCamera', 0.5f ); OnCombatActionEnd(); OnCombatActionEndComplete(); } private timer function FinisherEndEnableCamera( dt : float, id : int ) { thePlayer.EnableManualCameraControl( true, 'Finisher' ); } public function SpawnFinisherBlood() { var weaponEntity : CEntity; var weaponSlotMatrix : Matrix; var bloodFxPos : Vector; var bloodFxRot : EulerAngles; var tempEntity : CEntity; weaponEntity = this.GetInventory().GetItemEntityUnsafe( GetInventory().GetItemFromSlot('r_weapon') ); weaponEntity.CalcEntitySlotMatrix( 'blood_fx_point', weaponSlotMatrix ); bloodFxPos = MatrixGetTranslation( weaponSlotMatrix ); bloodFxRot = this.GetWorldRotation(); tempEntity = theGame.CreateEntity( (CEntityTemplate)LoadResource('finisher_blood'), bloodFxPos, bloodFxRot); tempEntity.PlayEffect('crawl_blood'); } event OnCombatActionEndComplete() { var buff : CBaseGameplayEffect; buff = ChooseCurrentCriticalBuffForAnim(); SetCombatAction( EBAT_EMPTY ); UnblockAction( EIAB_DrawWeapon, 'OnCombatActionStart' ); UnblockAction( EIAB_OpenInventory, 'OnCombatActionStart' ); UnblockAction( EIAB_UsableItem, 'OnCombatActionStart' ); UnblockAction( EIAB_DrawWeapon, 'OnCombatActionStart_Attack' ); SetUnpushableTarget( NULL ); SetBIsInCombatAction(false); SetIsCurrentlyDodging(false); SetMoveTargetChangeAllowed( true ); SetCanPlayHitAnim( true ); SetFinisherVictim( NULL ); this.RemoveBuffImmunity(EET_Burning, 'AnimEvent_RemoveBurning'); if ( rangedWeapon && rangedWeapon.GetCurrentStateName() == 'State_WeaponWait' && !buff ) { ClearCustomOrientationInfoStack(); SetSlideTarget( NULL ); } UnblockAction( EIAB_Crossbow, 'OnForceHolster' ); specialAttackCamera = false; bIsRollAllowed = false; if ( bLAxisReleased ) { ResetRawPlayerHeading(); ResetCachedRawPlayerHeading(); } ReapplyCriticalBuff(); SetBIsInputAllowed( true, 'OnCombatActionEndComplete' ); ResumeStaminaRegen( 'InsideCombatAction' ); bIsInHitAnim = false; SetBIsCombatActionAllowed( true ); m_LastWeaponTipPos = Vector(0, 0, 0, 0 ); this.AddTimer('FreeTickets',3.f,false); } event OnMovementFullyBlended() { SetBehaviorVariable( 'isPerformingSpecialAttack', 0.f ); if ( restoreUsableItem ) { restoreUsableItem = false; SetPlayerActionToRestore ( PATR_Default ); OnUseSelectedItem(); } } event OnCombatMovementStart() { SetCombatIdleStance( 1.f ); OnCombatActionEndComplete(); } timer function FreeTickets( dt : float, id : int ) { FreeTicketAtCombatTarget(); } event OnGuardedReleased(){} event OnPerformAttack( playerAttackType : name ){} event OnPerformEvade( playerEvadeType : EPlayerEvadeType ){} event OnInterruptAttack(){} event OnPerformGuard(){} event OnSpawnHorse(){} event OnDismountActionScriptCallback(){} event OnHorseSummonStart() { thePlayer.BlockAction(EIAB_CallHorse, 'HorseSummon'); thePlayer.BlockAction(EIAB_Signs, 'HorseSummon'); thePlayer.BlockAction(EIAB_Crossbow, 'HorseSummon'); thePlayer.BlockAction(EIAB_UsableItem, 'HorseSummon'); thePlayer.BlockAction(EIAB_ThrowBomb, 'HorseSummon'); thePlayer.BlockAction(EIAB_SwordAttack, 'HorseSummon'); thePlayer.BlockAction(EIAB_Jump, 'HorseSummon'); thePlayer.BlockAction(EIAB_Dodge, 'HorseSummon'); thePlayer.BlockAction(EIAB_LightAttacks, 'HorseSummon'); thePlayer.BlockAction(EIAB_HeavyAttacks, 'HorseSummon'); thePlayer.BlockAction(EIAB_SpecialAttackLight, 'HorseSummon'); thePlayer.BlockAction(EIAB_SpecialAttackHeavy, 'HorseSummon'); horseSummonTimeStamp = theGame.GetEngineTimeAsSeconds(); } event OnHorseSummonStop() { thePlayer.BlockAllActions('HorseSummon',false); } event OnCombatActionStartVehicle( action : EVehicleCombatAction ) { this.SetBIsCombatActionAllowed( false ); if ( action != EHCA_ShootCrossbow ) { SetIsAimingCrossbow( false ); OnRangedForceHolster(); } } event OnCombatActionEndVehicle() { this.SetBIsCombatActionAllowed( true ); } protected function CriticalBuffInformBehavior(buff : CBaseGameplayEffect) { if( !CanAnimationReactToCriticalState( buff ) ) { return; } SetBehaviorVariable( 'CriticalStateType', (int)GetBuffCriticalType(buff) ); SetBehaviorVariable( 'bCriticalState', 1); if(CriticalBuffUsesFullBodyAnim(buff)) RaiseEvent('CriticalState'); SetBehaviorVariable( 'IsInAir', (int)IsInAir()); LogCritical("Sending player critical state event for <<" + buff.GetEffectType() + ">>"); } private function CanAnimationReactToCriticalState( buff : CBaseGameplayEffect ) : bool { var buffCritical : W3CriticalEffect; var buffCriticalDOT : W3CriticalDOTEffect; var isHeavyCritical : bool; isHeavyCritical = false; buffCritical = ( W3CriticalEffect ) buff; if( buffCritical ) { isHeavyCritical = buffCritical.explorationStateHandling == ECH_HandleNow; } else { buffCriticalDOT = ( W3CriticalDOTEffect ) buff; if( buffCriticalDOT ) { isHeavyCritical = buffCriticalDOT.explorationStateHandling == ECH_HandleNow; } } if( !isHeavyCritical ) { if( !CanReactToCriticalState() ) { return false; } } return true; } public function CanReactToCriticalState() : bool { return substateManager.CanReactToHardCriticalState(); } event OnCriticalStateAnimStart() { var heading : float; var newCritical : ECriticalStateType; var newReqCS : CBaseGameplayEffect; OnCombatActionEndComplete(); newReqCS = newRequestedCS; if(super.OnCriticalStateAnimStart()) { RemoveTimer( 'IsItemUseInputHeld' ); keepRequestingCriticalAnimStart = false; CancelHoldAttacks(); if(!IsUsingVehicle()) { newCritical = GetBuffCriticalType(newReqCS); if(newCritical == ECST_HeavyKnockdown || newCritical == ECST_Knockdown || newCritical == ECST_Stagger || newCritical == ECST_Ragdoll || newCritical == ECST_LongStagger ) { if(newReqCS.GetCreator()) heading = VecHeading(newReqCS.GetCreator().GetWorldPosition() - GetWorldPosition()); else heading = GetHeading(); SetCustomRotation( 'Knockdown', heading, 2160.f, 0.1f, true ); if ( newCritical != ECST_Stagger && newCritical != ECST_LongStagger ) substateManager.ReactOnCriticalState( true ); } } theGame.GetBehTreeReactionManager().CreateReactionEventIfPossible( this, 'CriticalEffectStart', -1, 30.0f, -1.f, -1, true ); return true; } return false; } public function StartCSAnim(buff : CBaseGameplayEffect) : bool { SetBehaviorVariable( 'bCriticalStopped', 0 ); if(super.StartCSAnim(buff)) { if(!CriticalBuffUsesFullBodyAnim(buff)) { OnCriticalStateAnimStart(); } ResumeStaminaRegen( 'InsideCombatAction' ); keepRequestingCriticalAnimStart = true; AddTimer('RequestCriticalAnimStart', 0, true); return true; } return false; } public function CriticalEffectAnimationInterrupted(reason : string) : bool { var ret : bool; LogCriticalPlayer("R4Player.CriticalEffectAnimationInterrupted() - because: " + reason); ret = super.CriticalEffectAnimationInterrupted(reason); if(ret) { keepRequestingCriticalAnimStart = false; } substateManager.ReactOnCriticalState( false ); return ret; } public function CriticalStateAnimStopped(forceRemoveBuff : bool) { LogCriticalPlayer("R4Player.CriticalStateAnimStopped() - forced: " + forceRemoveBuff); theGame.GetBehTreeReactionManager().CreateReactionEventIfPossible( this, 'RecoveredFromCriticalEffect', -1, 30.0f, -1.f, -1, true ); super.CriticalStateAnimStopped(forceRemoveBuff); substateManager.ReactOnCriticalState( false ); } timer function RequestCriticalAnimStart(dt : float, id : int) { if(keepRequestingCriticalAnimStart) { if(newRequestedCS && newRequestedCS.GetDurationLeft() > 0) { CriticalBuffInformBehavior(newRequestedCS); } else { keepRequestingCriticalAnimStart = false; RemoveTimer('RequestCriticalAnimStart'); } } else { RemoveTimer('RequestCriticalAnimStart'); } } event OnRagdollUpdate(progress : float) { SetIsInAir(progress == 0); } event OnRagdollOnGround() { TryToEndRagdollOnGround( 0.0f ); } event OnRagdollInAir() { RemoveTimer('TryToEndRagdollOnGround'); } event OnNoLongerInRagdoll() { RemoveTimer('TryToEndRagdollOnGround'); } timer function TryToEndRagdollOnGround( td : float, optional id : int) { var critical : CBaseGameplayEffect; var type : EEffectType; critical = GetCurrentlyAnimatedCS(); if(critical) { type = critical.GetEffectType(); if(type == EET_Knockdown || type == EET_HeavyKnockdown || type == EET_Ragdoll) { if (critical.GetTimeActive() >= 2.5f) { SetIsInAir(false); RequestCriticalAnimStop(); RemoveTimer('TryToEndRagdollOnGround'); } else { AddTimer('TryToEndRagdollOnGround', 0.2f, true); } return; } } RemoveTimer('TryToEndRagdollOnGround'); } public function RequestCriticalAnimStop(optional dontSetCriticalToStopped : bool) { var buff : CBaseGameplayEffect; buff = GetCurrentlyAnimatedCS(); if(buff && !CriticalBuffUsesFullBodyAnim(buff)) { CriticalStateAnimStopped(false); } if(!buff || !CriticalBuffUsesFullBodyAnim(buff)) { SetBehaviorVariable( 'bCriticalState', 0); } super.RequestCriticalAnimStop(dontSetCriticalToStopped); } public function SimulateBuffTimePassing(simulatedTime : float) { effectManager.SimulateBuffTimePassing(simulatedTime); } public function AddEffectDefault(effectType : EEffectType, creat : CGameplayEntity, srcName : string, optional isSignEffect : bool) : EEffectInteract { var params : SCustomEffectParams; if(effectType == EET_Stagger || effectType == EET_LongStagger || effectType == EET_Knockdown || effectType == EET_HeavyKnockdown) { params.effectType = effectType; params.creator = creat; params.sourceName = srcName; params.isSignEffect = isSignEffect; if ( effectType == EET_Stagger ) params.duration = 1.83; else if ( effectType == EET_LongStagger ) params.duration = 4; else if ( effectType == EET_Knockdown ) params.duration = 2.5; else if ( effectType == EET_HeavyKnockdown ) params.duration = 4; return super.AddEffectCustom(params); } else { return super.AddEffectDefault(effectType, creat, srcName, isSignEffect); } } public function CheatResurrect() { var items : array< SItemUniqueId >; var i, size, itemLevel, maxPrice, itemPrice : int; var itemToEquip : SItemUniqueId; if(IsAlive()) return; if ( !theGame.GetGuiManager().GetRootMenu() ) { Log(" *** Call this function after DeathScreen appears *** "); return; } SetAlive(true); SetKinematic(true); EnableFindTarget( true ); SetBehaviorVariable( 'Ragdoll_Weight', 0.f ); RaiseForceEvent( 'RecoverFromRagdoll' ); SetCanPlayHitAnim( true ); SetBehaviorVariable( 'CriticalStateType', (int)ECST_None ); GoToStateIfNew('Exploration'); ( (CDismembermentComponent)this.GetComponent( 'Dismemberment' ) ).ClearVisibleWound(); SetIsInAir(false); theInput.SetContext('Exploration'); ResetDeathType(); ForceUnlockAllInputActions(false); theGame.CloseMenu('DeathScreenMenu'); theSound.LeaveGameState(ESGS_Death); abilityManager.ForceSetStat(BCS_Vitality, GetStatMax(BCS_Vitality)); effectManager.StopVitalityRegen(); abilityManager.ForceSetStat( BCS_Air , 100.f ); effectManager.StopAirRegen(); abilityManager.ForceSetStat( BCS_Stamina , 100.f ); effectManager.StopStaminaRegen(); abilityManager.ForceSetStat( BCS_Toxicity , 0.f ); abilityManager.ForceSetStat( BCS_Focus , 0.f ); GetWitcherPlayer().UpdateEncumbrance(); if ( !inv.IsThereItemOnSlot( EES_SteelSword ) ) { items = inv.GetItemsByCategory( 'steelsword' ); } else if ( !inv.IsThereItemOnSlot( EES_SilverSword ) ) { items = inv.GetItemsByCategory( 'silversword' ); } size = items.Size(); maxPrice = -1; for ( i = 0; i < size; i += 1 ) { itemPrice = inv.GetItemPrice(items[i]); itemLevel = inv.GetItemLevel(items[i]); if ( itemLevel <= GetLevel() && itemPrice > maxPrice ) { maxPrice = itemPrice; itemToEquip = items[i]; } } if( inv.IsIdValid( itemToEquip ) ) { EquipItem( itemToEquip , , true ); } theGame.ReleaseNoSaveLock(deathNoSaveLock); } public function SetIsInsideInteraction(b : bool) {isInsideInteraction = b;} public function IsInsideInteraction() : bool {return isInsideInteraction;} public function SetIsInsideHorseInteraction( b : bool, horse : CEntity ) { isInsideHorseInteraction = b; horseInteractionSource = horse; } public function IsInsideHorseInteraction() : bool {return isInsideHorseInteraction;} event OnInteractionActivationTest( interactionComponentName : string, activator : CEntity ) { if ( interactionComponentName == "ClimbLadder" ) { if( PlayerHasLadderExplorationReady() ) { return true; } } return false; } private function PlayerHasLadderExplorationReady() : bool { if( !substateManager.CanInteract() ) { return false; } if( !substateManager.m_SharedDataO.HasValidLadderExploration() ) { return false; } return true; } public function SetGuarded(flag : bool) { super.SetGuarded(flag); if(flag && FactsQuerySum("tut_fight_use_slomo") > 0) { theGame.RemoveTimeScale( theGame.GetTimescaleSource(ETS_TutorialFight) ); FactsRemove("tut_fight_slomo_ON"); } } public function IsGuarded() : bool { return super.IsGuarded() && ( !rangedWeapon || rangedWeapon.GetCurrentStateName() == 'State_WeaponWait' ); } public function GetSelectedItemId() : SItemUniqueId {return selectedItemId;} public function ClearSelectedItemId() {selectedItemId = GetInvalidUniqueId();} public function IsHoldingItemInLHand() : bool { return currentlyEquipedItemL != GetInvalidUniqueId(); } public function GetCurrentlyUsedItemL () : W3UsableItem { return currentlyUsedItemL; } public function SetPlayerActionToRestore ( actionToRestoreType : EPlayerActionToRestore ) { playerActionToRestore = actionToRestoreType; } public function IsCurrentlyUsingItemL () : bool { return currentlyUsingItem; } function BlockSlotsOnLItemUse () { var slotsToBlock : array; slotsToBlock.PushBack( 'Slot1' ); slotsToBlock.PushBack( 'Slot2' ); slotsToBlock.PushBack( 'Slot3' ); slotsToBlock.PushBack( 'Slot4' ); slotsToBlock.PushBack( 'Slot5' ); slotsToBlock.PushBack( 'Yrden' ); slotsToBlock.PushBack( 'Quen' ); slotsToBlock.PushBack( 'Igni' ); slotsToBlock.PushBack( 'Axii' ); slotsToBlock.PushBack( 'Aard' ); EnableRadialSlotsWithSource ( false, slotsToBlock, 'usableItemL' ); } function UnblockSlotsOnLItemUse () { var slotsToBlock : array; slotsToBlock.PushBack( 'Slot1' ); slotsToBlock.PushBack( 'Slot2' ); slotsToBlock.PushBack( 'Slot3' ); slotsToBlock.PushBack( 'Slot4' ); slotsToBlock.PushBack( 'Slot5' ); slotsToBlock.PushBack( 'Yrden' ); slotsToBlock.PushBack( 'Quen' ); slotsToBlock.PushBack( 'Igni' ); slotsToBlock.PushBack( 'Axii' ); slotsToBlock.PushBack( 'Aard' ); EnableRadialSlotsWithSource ( true, slotsToBlock, 'usableItemL' ); } function IsUsableItemLBlocked () : bool { return isUsableItemBlocked; } function HideUsableItem( optional force : bool ) { if( currentlyEquipedItemL != GetInvalidUniqueId() ) { if( force ) { if( !RaiseForceEvent( 'ItemEndL' ) ) { OnUsingItemsReset(); } return; } RaiseEvent( 'ItemUseL' ); } } function ProcessUsableItemsTransition ( actionToRestore : EPlayerActionToRestore ) { var category : name; var signSkill : ESkill; category = inv.GetItemCategory ( selectedItemId ); signSkill = SignEnumToSkillEnum( GetEquippedSign()); switch ( actionToRestore ) { case PATR_None: if ( currentlyUsedItemL ) { inv.UnmountItem( currentlyEquipedItemL, true ); } currentlyEquipedItemL = GetInvalidUniqueId(); return; case PATR_Default: if ( IsSlotQuickslot( inv.GetSlotForItemId ( selectedItemId )) && category == 'usable' && currentlyEquipedItemL != selectedItemId ) { if ( currentlyUsedItemL ) { inv.UnmountItem( currentlyEquipedItemL, true ); } currentlyEquipedItemL = GetInvalidUniqueId(); OnUseSelectedItem(); return; } break; case PATR_Crossbow: if ( inv.IsItemCrossbow ( selectedItemId ) ) { if ( currentlyUsedItemL ) { inv.UnmountItem( currentlyEquipedItemL, true ); } currentlyEquipedItemL = GetInvalidUniqueId(); SetIsAimingCrossbow( true ); if ( theInput.IsActionPressed( 'ThrowItem' ) ) SetupCombatAction( EBAT_ItemUse, BS_Pressed ); else { SetupCombatAction( EBAT_ItemUse, BS_Pressed ); SetupCombatAction( EBAT_ItemUse, BS_Released ); } return; } break; case PATR_CastSign: if( signSkill != S_SUndefined && playerActionToRestore == PATR_CastSign ) { if ( currentlyUsedItemL ) { inv.UnmountItem( currentlyEquipedItemL, true ); } currentlyEquipedItemL = GetInvalidUniqueId(); if( HasStaminaToUseSkill( signSkill, false ) ) { if( GetInvalidUniqueId() != inv.GetItemFromSlot( 'l_weapon' ) ) PushCombatActionOnBuffer( EBAT_CastSign, BS_Pressed ); else SetupCombatAction( EBAT_CastSign, BS_Pressed ); } else { thePlayer.SoundEvent("gui_no_stamina"); } return; } break; case PATR_ThrowBomb: if ( inv.IsItemBomb ( selectedItemId ) ) { if ( currentlyUsedItemL ) { inv.UnmountItem( currentlyEquipedItemL, true ); } currentlyEquipedItemL = GetInvalidUniqueId(); PrepareToAttack(); SetupCombatAction( EBAT_ItemUse, BS_Pressed ); return; } break; case PATR_CallHorse: theGame.OnSpawnPlayerHorse(); break; default: if ( currentlyUsedItemL ) { inv.UnmountItem( currentlyEquipedItemL, true ); } currentlyEquipedItemL = GetInvalidUniqueId(); return; } if ( currentlyUsedItemL ) { inv.UnmountItem( currentlyEquipedItemL, true ); } currentlyEquipedItemL = GetInvalidUniqueId(); } function GetUsableItemLtransitionAllowed () : bool { return isUsableItemLtransitionAllowed; } function SetUsableItemLtransitionAllowed ( isAllowed : bool) { isUsableItemLtransitionAllowed = isAllowed; } event OnItemUseLUnBlocked () { if ( isUsableItemBlocked ) { isUsableItemBlocked = false; UnblockSlotsOnLItemUse (); } } event OnItemUseLBlocked () { if ( !isUsableItemBlocked ) { isUsableItemBlocked = true; BlockSlotsOnLItemUse (); } } event OnUsingItemsReset() { if ( currentlyUsingItem ) { OnItemUseLUnBlocked (); OnUsingItemsComplete(); } } event OnUsingItemsComplete () { if ( isUsableItemBlocked ) { OnItemUseLUnBlocked (); } currentlyUsingItem = false; if ( GetUsableItemLtransitionAllowed () ) { ProcessUsableItemsTransition( playerActionToRestore ); } else { if ( currentlyUsedItemL ) { inv.UnmountItem( currentlyEquipedItemL, true ); } currentlyEquipedItemL = GetInvalidUniqueId(); } SetPlayerActionToRestore ( PATR_Default ); } event OnUseSelectedItem( optional force : bool ) { var category : name; var itemEntity : W3UsableItem; if ( isUsableItemBlocked && !force ) { return false; } if ( IsCastingSign() ) return false; if ( currentlyEquipedItemL != GetInvalidUniqueId() ) { SetBehaviorVariable( 'SelectedItemL', (int)GetUsableItemTypeById( currentlyEquipedItemL ), true ); if ( force ) { if ( RaiseEvent( 'ItemEndL' ) ) { SetUsableItemLtransitionAllowed ( true ); return true; } } else { if ( RaiseEvent( 'ItemUseL' ) ) { SetUsableItemLtransitionAllowed ( true ); return true; } } } else { category = inv.GetItemCategory( selectedItemId ); if( category != 'usable' ) { return false; } SetBehaviorVariable( 'SelectedItemL', (int)GetUsableItemTypeById( selectedItemId ), true ); if( RaiseEvent( 'ItemUseL' ) ) { currentlyEquipedItemL = selectedItemId; SetUsableItemLtransitionAllowed ( false ); currentlyUsingItem = true; return true; } inv.UnmountItem( selectedItemId, true ); } } protected saved var currentlyUsingItem : bool; public function ProcessUseSelectedItem( itemEntity : W3UsableItem, optional shouldCallOnUsed : bool ) { currentlyUsedItemL = itemEntity; DrainStamina(ESAT_UsableItem); if ( shouldCallOnUsed ) { currentlyUsedItemL.OnUsed( thePlayer ); } } function GetUsableItemTypeById ( itemId : SItemUniqueId ) : EUsableItemType { var itemName : name; itemName = inv.GetItemName ( itemId ); return theGame.GetDefinitionsManager().GetUsableItemType ( itemName ); } public function StartWaitForItemSpawnAndProccesTask() { AddTimer( 'WaitForItemSpawnAndProccesTask', 0.001f, true,,,,true ); } public function KillWaitForItemSpawnAndProccesTask() { RemoveTimer ( 'WaitForItemSpawnAndProccesTask' ); } public function AllowUseSelectedItem() { m_useSelectedItemIfSpawned = true; } timer function WaitForItemSpawnAndProccesTask( timeDelta : float , id : int ) { var itemEntity : W3UsableItem; var canTaskBeKilled : bool; canTaskBeKilled = false; if ( IsCastingSign() ) { return; } if ( selectedItemId == GetInvalidUniqueId() ) { canTaskBeKilled = true; } itemEntity = (W3UsableItem)inv.GetItemEntityUnsafe( selectedItemId ); if ( itemEntity && m_useSelectedItemIfSpawned ) { canTaskBeKilled = true; m_useSelectedItemIfSpawned = false; ProcessUseSelectedItem( itemEntity, true ); } if ( canTaskBeKilled ) { KillWaitForItemSpawnAndProccesTask(); } } event OnBombProjectileReleased() { ResetRawPlayerHeading(); UnblockAction(EIAB_ThrowBomb, 'BombThrow'); UnblockAction(EIAB_Crossbow, 'BombThrow'); if(GetCurrentStateName() == 'AimThrow') PopState(); FactsAdd("ach_bomb", 1, 4 ); theGame.GetGamerProfile().CheckLearningTheRopes(); } public function SetIsThrowingItemWithAim(b : bool) { isThrowingItemWithAim = b; } public function SetIsThrowingItem( flag : bool ) {isThrowingItem = flag;} public function IsThrowingItem() : bool {return isThrowingItem;} public function IsThrowingItemWithAim() : bool {return isThrowingItemWithAim;} public function SetThrowHold(b : bool) {isThrowHoldPressed = b;} public function IsThrowHold() : bool {return isThrowHoldPressed;} public function SetIsAimingCrossbow( flag : bool ) {isAimingCrossbow = flag;} public function GetIsAimingCrossbow() : bool {return isAimingCrossbow;} event OnThrowAnimLeave() { var throwStage : EThrowStage; var thrownEntity : CThrowable; thrownEntity = (CThrowable)EntityHandleGet( thrownEntityHandle ); if(thrownEntity && !thrownEntity.WasThrown()) { throwStage = (int)GetBehaviorVariable( 'throwStage', (int)TS_Stop); if(inv.IsItemBomb(selectedItemId)) { BombThrowCleanUp(); } else { ThrowingAbort(); } } thrownEntity = NULL; SetIsThrowingItem( false ); SetIsThrowingItemWithAim( false ); this.EnableRadialSlotsWithSource( true, this.radialSlots, 'throwBomb' ); UnblockAction(EIAB_ThrowBomb, 'BombThrow'); UnblockAction(EIAB_Crossbow, 'BombThrow'); } protected function BombThrowStart() { var slideTargetActor : CActor; BlockAction( EIAB_ThrowBomb, 'BombThrow' ); BlockAction(EIAB_Crossbow, 'BombThrow'); SetBehaviorVariable( 'throwStage', (int)TS_Start ); SetBehaviorVariable( 'combatActionType', (int)CAT_ItemThrow ); if ( slideTarget ) { AddCustomOrientationTarget( OT_Actor, 'BombThrow' ); slideTargetActor = (CActor)( slideTarget ); } else { if ( lastAxisInputIsMovement ) AddCustomOrientationTarget( OT_Actor, 'BombThrow' ); else AddCustomOrientationTarget( OT_Camera, 'BombThrow' ); } UpdateLookAtTarget(); SetCustomRotation( 'Throw', VecHeading( this.GetLookAtPosition() - GetWorldPosition() ), 0.0f, 0.3f, false ); SetBehaviorVariable( 'itemType', (int)IT_Petard ); ProcessCanAttackWhenNotInCombatBomb(); if ( RaiseForceEvent('CombatAction') ) OnCombatActionStart(); theTelemetry.LogWithLabel(TE_FIGHT_HERO_THROWS_BOMB, inv.GetItemName( selectedItemId )); } event OnThrowAnimStart() { var itemId : SItemUniqueId; var thrownEntity : CThrowable; this.radialSlots.Clear(); GetWitcherPlayer().GetItemEquippedOnSlot(EES_Petard1, itemId ); if( GetSelectedItemId() == itemId ) { this.radialSlots.PushBack( 'Slot2' ); } else { this.radialSlots.PushBack( 'Slot1' ); } this.radialSlots.PushBack( 'Slot3' ); this.radialSlots.PushBack( 'Slot4' ); this.radialSlots.PushBack( 'Slot5' ); this.EnableRadialSlotsWithSource( false, this.radialSlots, 'throwBomb' ); thrownEntity = (CThrowable)inv.GetDeploymentItemEntity( selectedItemId,,,true ); thrownEntity.Initialize( this, selectedItemId ); EntityHandleSet( thrownEntityHandle, thrownEntity ); SetIsThrowingItem( true ); } public function BombThrowAbort() { BombThrowCleanUp(); UnblockAction( EIAB_ThrowBomb, 'BombThrow' ); UnblockAction(EIAB_Crossbow, 'BombThrow'); } private function BombThrowCleanUp() { var throwStage : EThrowStage; var thrownEntity : CThrowable; var vehicle : CVehicleComponent; thrownEntity = (CThrowable)EntityHandleGet( thrownEntityHandle ); this.EnableRadialSlotsWithSource( true, this.radialSlots, 'throwBomb' ); throwStage = (int)GetBehaviorVariable( 'throwStage', (int)TS_Stop); SetBehaviorVariable( 'throwStage', (int)TS_Stop ); if( GetCurrentStateName() == 'AimThrow') { PopState(); thrownEntity.StopAiming( true ); } else if ( this.IsUsingHorse() ) { vehicle = (CVehicleComponent)(GetUsedVehicle().GetComponentByClassName('CVehicleComponent')); vehicle.GetUserCombatManager().OnForceItemActionAbort(); } if(thrownEntity && !thrownEntity.WasThrown()) { thrownEntity.BreakAttachment(); thrownEntity.Destroy(); } thrownEntity = NULL; SetIsThrowingItem( false ); SetIsThrowingItemWithAim( false ); RemoveCustomOrientationTarget( 'BombThrow' ); } public function ProcessCanAttackWhenNotInCombatBomb() { var targets : array< CGameplayEntity >; var temp, throwVector, throwFrom, throwTo, throwVectorU : Vector; var temp_n : name; var throwVecLen : float; var component : CComponent; if( FactsQuerySum( "BombThrowSpecificTargets" ) > 0 ) { throwFrom = playerAiming.GetThrowStartPosition(); throwTo = playerAiming.GetThrowPosition(); throwVector = throwTo - throwFrom; throwVecLen = VecDistance( throwFrom, throwTo ); throwVectorU = throwVector / throwVecLen; if( theGame.GetWorld().StaticTraceWithAdditionalInfo( throwFrom, throwTo + throwVectorU, temp, temp, temp_n, component ) && component && component.GetEntity().HasTag( 'BombThrowSpecificTarget' ) ) { SetIsShootingFriendly( false ); } else { SetIsShootingFriendly( true ); } } else if( FactsQuerySum( "BombThrowDisallowSpecificTargets" ) > 0 ) { throwFrom = playerAiming.GetThrowStartPosition(); throwTo = playerAiming.GetThrowPosition(); throwVector = throwTo - throwFrom; throwVecLen = VecDistance( throwFrom, throwTo ); throwVectorU = throwVector / throwVecLen; if( theGame.GetWorld().StaticTraceWithAdditionalInfo( throwFrom, throwTo + throwVectorU, temp, temp, temp_n, component ) && component && component.GetEntity().HasTag( 'BombThrowDisallowedTarget' ) ) { SetIsShootingFriendly( true ); } else { SetIsShootingFriendly( false ); } } else { SetIsShootingFriendly( false ); } SetBehaviorVariable( 'isShootingFriendly', (float)( GetIsShootingFriendly() ) ); } public function SetIsShootingFriendly( flag : bool ) { isShootingFriendly = flag; } public function GetIsShootingFriendly() : bool { return isShootingFriendly; } protected function UsableItemStart() { var thrownEntity : CThrowable; thrownEntity = (CThrowable)inv.GetDeploymentItemEntity( selectedItemId,,,true ); thrownEntity.Initialize( this, selectedItemId ); EntityHandleSet( thrownEntityHandle, thrownEntity ); SetBehaviorVariable( 'throwStage', (int)TS_Start ); SetIsThrowingItem( true ); SetBehaviorVariable( 'combatActionType', (int)CAT_ItemThrow ); if ( slideTarget ) { AddCustomOrientationTarget( OT_Actor, 'UsableItems' ); } else { if ( lastAxisInputIsMovement ) AddCustomOrientationTarget( OT_Actor, 'UsableItems' ); else AddCustomOrientationTarget( OT_Camera, 'UsableItems' ); } SetBehaviorVariable( 'itemType', (int)(-1) ); if ( RaiseForceEvent('CombatAction') ) OnCombatActionStart(); } protected function BombThrowRelease() { var stateName : name; stateName = playerAiming.GetCurrentStateName(); OnDelayOrientationChangeOff(); if( GetIsShootingFriendly() || ( FactsQuerySum( "BombThrowSpecificTargets" ) > 0 && stateName != 'Aiming' ) ) { BombThrowAbort(); } else { SetBehaviorVariable( 'throwStage', (int)TS_End ); if ( stateName == 'Aiming' ) { SetCustomRotation( 'Throw', VecHeading( this.GetLookAtPosition() - GetWorldPosition() ), 0.0f, 0.2f, false ); } } } protected function UsableItemRelease() { OnDelayOrientationChangeOff(); SetBehaviorVariable( 'throwStage', (int)TS_End ); RemoveCustomOrientationTarget( 'UsableItems' ); } public function ThrowingAbort() { var thrownEntity : CThrowable; thrownEntity = (CThrowable)EntityHandleGet( thrownEntityHandle ); SetBehaviorVariable( 'throwStage', (int)TS_Stop ); RaiseEvent( 'actionStop' ); if( GetCurrentStateName() == 'AimThrow') { PopState(); thrownEntity.StopAiming( true ); } if(thrownEntity && !thrownEntity.WasThrown()) { thrownEntity.BreakAttachment(); thrownEntity.Destroy(); } this.EnableRadialSlotsWithSource( true, this.radialSlots, 'throwBomb' ); } public function CanSetupCombatAction_Throw() : bool { if(!inv.IsIdValid( selectedItemId )) return false; if(!inv.IsItemSingletonItem(selectedItemId)) return false; if(!GetBIsInputAllowed()) return false; if(inv.GetItemQuantity(GetSelectedItemId()) <= 0 && !inv.ItemHasTag(selectedItemId, theGame.params.TAG_INFINITE_AMMO)) return false; if(!inputHandler.IsActionAllowed(EIAB_ThrowBomb) && GetCurrentStateName() != 'Swimming') return false; return true; } public function GetThrownEntity() : CThrowable { return (CThrowable)EntityHandleGet( thrownEntityHandle ); } event OnWeaponWait() { rangedWeapon.OnWeaponWait(); } event OnWeaponDrawStart() { rangedWeapon.OnWeaponDrawStart(); } event OnWeaponReloadStart() { rangedWeapon.OnWeaponReloadStart(); } event OnWeaponReloadEnd() { rangedWeapon.OnWeaponReloadEnd(); } event OnWeaponAimStart() { rangedWeapon.OnWeaponAimStart(); } event OnWeaponShootStart() { rangedWeapon.OnWeaponShootStart(); } event OnWeaponShootEnd() { rangedWeapon.OnWeaponShootEnd(); } event OnWeaponAimEnd() { rangedWeapon.OnWeaponAimEnd(); } event OnWeaponHolsterStart() { rangedWeapon.OnWeaponHolsterStart(); } event OnWeaponHolsterEnd() { rangedWeapon.OnWeaponHolsterEnd(); } event OnWeaponToNormalTransStart() { rangedWeapon.OnWeaponToNormalTransStart(); } event OnWeaponToNormalTransEnd() { rangedWeapon.OnWeaponToNormalTransEnd(); } event OnEnableAimingMode( enable : bool ) { if( !crossbowDontPopStateHack ) { if ( enable ) PushState( 'AimThrow' ); else if ( GetCurrentStateName() == 'AimThrow' ) PopState(); } } event OnRangedForceHolster( optional forceUpperBodyAnim, instant, dropItem : bool ) { if(rangedWeapon) rangedWeapon.OnForceHolster( forceUpperBodyAnim, instant, dropItem ); } public function IsCrossbowHeld() : bool { if (rangedWeapon) return rangedWeapon.GetCurrentStateName() != 'State_WeaponWait'; return false; } event OnBlockAllCombatTickets( release : bool ) { if (!release ) ((CR4PlayerStateCombat)GetState('Combat')).OnBlockAllCombatTickets(false); } event OnForceTicketUpdate() {} event OnProcessActionPost(action : W3DamageAction) { var npc : CNewNPC; var attackAction : W3Action_Attack; var lifeLeech : float; super.OnProcessActionPost(action); attackAction = (W3Action_Attack)action; if(attackAction) { npc = (CNewNPC)action.victim; if(npc && npc.IsHuman() ) { PlayBattleCry('BattleCryHumansHit', 0.05f ); } else { PlayBattleCry('BattleCryMonstersHit', 0.05f ); } if(attackAction.IsActionMelee()) { IncreaseUninterruptedHitsCount(); if( IsLightAttack( attackAction.GetAttackName() ) ) { GCameraShake(0.1, false, GetWorldPosition(), 10); } if(npc && inv.GetItemName(attackAction.GetWeaponId()) == 'PC Caretaker Shovel') { lifeLeech = CalculateAttributeValue(inv.GetItemAttributeValue(attackAction.GetWeaponId() ,'lifesteal')); if (npc.UsesVitality()) lifeLeech *= action.processedDmg.vitalityDamage; else if (UsesEssence()) lifeLeech *= action.processedDmg.essenceDamage; else lifeLeech = 0; if ( lifeLeech > 0 ) { inv.PlayItemEffect( attackAction.GetWeaponId(), 'stab_attack' ); PlayEffect('drain_energy_caretaker_shovel'); GainStat(BCS_Vitality, lifeLeech); } } } } } public function SetHitReactTransScale(f : float) {hitReactTransScale = f;} public function GetHitReactTransScale() : float { if ( ( (CNewNPC)slideTarget ).GetIsTranslationScaled() ) return hitReactTransScale; else return 1.f; } public function GetHorseWithInventory() : CNewNPC { return (CNewNPC)EntityHandleGet( horseWithInventory ); } public function GetHorseCurrentlyMounted() : CNewNPC { return currentlyMountedHorse; } public function _SetHorseCurrentlyMounted( horse : CNewNPC ) { currentlyMountedHorse = horse; } public function WasHorseRecentlySummoned() : bool { if ( horseSummonTimeStamp + 5.f > theGame.GetEngineTimeAsSeconds() ) return true; return false; } private const var MOUNT_DISTANCE_CBT : float; default MOUNT_DISTANCE_CBT = 3.0; private const var MOUNT_ANGLE_CBT : float; default MOUNT_ANGLE_CBT = 35.0; private const var MOUNT_ANGLE_EXP : float; default MOUNT_ANGLE_EXP = 45.0; public function IsMountingHorseAllowed( optional alwaysAllowedInExploration : bool ) : bool { var angle : float; var distance : float; if( IsInsideHorseInteraction() ) { angle = AngleDistance( thePlayer.rawPlayerHeading, VecHeading( thePlayer.horseInteractionSource.GetWorldPosition() - thePlayer.GetWorldPosition() ) ); if( thePlayer.IsInCombat() ) { if( AbsF( angle ) < MOUNT_ANGLE_CBT ) { distance = VecDistance( thePlayer.GetWorldPosition(), thePlayer.horseInteractionSource.GetWorldPosition() ); if( distance < MOUNT_DISTANCE_CBT ) { return true; } else { return false; } } else { return false; } } else { if( alwaysAllowedInExploration ) { return true; } else { if( AbsF( angle ) < MOUNT_ANGLE_EXP ) { return true; } else { return false; } } } } else { return false; } } public function FollowActor( actor : CActor ) { var l_aiTreeDecorator : CAIPlayerActionDecorator; var l_aiTree_onFoot : CAIFollowSideBySideAction; var l_aiTree_onHorse : CAIRiderFollowSideBySideAction; var l_success : bool = false; actor.AddTag( 'playerFollowing' ); if( thePlayer.IsUsingHorse() ) { l_aiTree_onHorse = new CAIRiderFollowSideBySideAction in this; l_aiTree_onHorse.OnCreated(); l_aiTree_onHorse.params.targetTag = 'playerFollowing'; } else { l_aiTree_onFoot = new CAIFollowSideBySideAction in this; l_aiTree_onFoot.OnCreated(); l_aiTree_onFoot.params.targetTag = 'playerFollowing'; } l_aiTreeDecorator = new CAIPlayerActionDecorator in this; l_aiTreeDecorator.OnCreated(); l_aiTreeDecorator.interruptOnInput = false; if( thePlayer.IsUsingHorse() ) l_aiTreeDecorator.scriptedAction = l_aiTree_onHorse; else l_aiTreeDecorator.scriptedAction = l_aiTree_onFoot; if( l_aiTreeDecorator ) l_success = ForceAIBehavior( l_aiTreeDecorator, BTAP_Emergency ); else if( thePlayer.IsUsingHorse() ) l_success = ForceAIBehavior( l_aiTree_onHorse, BTAP_Emergency ); else l_success = ForceAIBehavior( l_aiTree_onFoot, BTAP_Emergency ); if ( l_success ) { GetMovingAgentComponent().SetGameplayRelativeMoveSpeed( 0.0f ); } } public function SetCanFollowNpc( val : bool, actor : CActor ) { canFollowNpc = val; actorToFollow = actor; } public function CanFollowNpc() : bool { return canFollowNpc; } public function GetActorToFollow() : CActor { return actorToFollow; } public function SetIsSwimming ( toggle : bool ) { if( isSwimming != toggle ) { thePlayer.substateManager.SetBehaviorParamBool( 'isSwimmingForOverlay', toggle ); isSwimming = toggle; } } public function RepairItemUsingConsumable(item, consumable : SItemUniqueId) : bool { var curr, max, repairValue, itemValue, repairBonus, newDurability : float; if(!inv.IsIdValid(item) || !inv.IsIdValid(consumable) || !inv.HasItemDurability(item)) return false; curr = inv.GetItemDurability(item); max = inv.GetItemMaxDurability(item); if(curr > max) return false; if( (inv.IsItemAnyArmor(item) && inv.ItemHasTag(consumable, theGame.params.TAG_REPAIR_CONSUMABLE_ARMOR)) || (inv.IsItemSilverSwordUsableByPlayer(item) && inv.ItemHasTag(consumable, theGame.params.TAG_REPAIR_CONSUMABLE_SILVER)) || (inv.IsItemSteelSwordUsableByPlayer(item) && inv.ItemHasTag(consumable, theGame.params.TAG_REPAIR_CONSUMABLE_STEEL)) ) { itemValue = CalculateAttributeValue(inv.GetItemAttributeValue(consumable, 'durabilityRepairValue')); if(itemValue <= 0) { LogAssert(false, "CR4Player.RepairItemUsingConsumable: consumable <<" + inv.GetItemName(consumable) + ">> has <=0 durabilityRepairValue!!!"); return false; } repairBonus = CalculateAttributeValue(inv.GetItemAttributeValue(consumable, 'durabilityBonusValue')); repairValue = max * itemValue /100; newDurability = MinF(max, curr + repairValue); inv.SetItemDurabilityScript(item, newDurability); inv.RemoveItem(consumable); return true; } return false; } private function CheckDayNightCycle() { var time : GameTime; var isNight : bool; isNight = theGame.envMgr.IsNight(); if(prevDayNightIsNight != isNight) { if(isNight) OnNightStarted(); else OnDayStarted(); prevDayNightIsNight = isNight; } if(isNight) time = theGame.envMgr.GetGameTimeTillNextDay(); else time = theGame.envMgr.GetGameTimeTillNextNight(); AddGameTimeTimer('DayNightCycle', time); } timer function DayNightCycle(dt : GameTime, id : int) { CheckDayNightCycle(); } event OnNightStarted() { var pam : W3PlayerAbilityManager; if(CanUseSkill(S_Perk_01)) { pam = (W3PlayerAbilityManager)abilityManager; pam.SetPerk01Abilities(false, true); } } event OnDayStarted() { var pam : W3PlayerAbilityManager; if(CanUseSkill(S_Perk_01)) { pam = (W3PlayerAbilityManager)abilityManager; pam.SetPerk01Abilities(true, false); } } public function ForceUnlockAllInputActions(alsoQuestLocks : bool) { if ( inputHandler ) inputHandler.ForceUnlockAllInputActions(alsoQuestLocks); } public function SetPrevRawLeftJoyRot() { prevRawLeftJoyRot = rawLeftJoyRot; } public function GetPrevRawLeftJoyRot() : float { return prevRawLeftJoyRot; } public function GetExplorationInputContext() : name { return explorationInputContext; } public function GetCombatInputContext() : name { return combatInputContext; } public function SetIsOnBoat(b : bool) { isOnBoat = b; } public function IsOnBoat() : bool { return isOnBoat; } public function IsInShallowWater() : bool { return isInShallowWater; } event OnEnterShallowWater() { if ( isInShallowWater ) return false; isInShallowWater = true; BlockAction( EIAB_Dodge,'ShallowWater', false, false, true ); BlockAction( EIAB_Sprint,'ShallowWater', false, false, true ); BlockAction( EIAB_Crossbow,'ShallowWater', false, false, true ); BlockAction( EIAB_Jump,'ShallowWater', false, false, true ); SetBehaviorVariable( 'shallowWater',1.0); } event OnExitShallowWater() { if ( !isInShallowWater ) return false; isInShallowWater = false; BlockAllActions('ShallowWater',false); SetBehaviorVariable( 'shallowWater',0.0); } public function TestIsInSettlement() : bool { return IsInSettlement(); } public function ProcessGlossaryImageOverride( defaultImage : string, uniqueTag : name ) : string { var size : int; var i : int; size = glossaryImageOverride.Size(); if( size == 0 ) return defaultImage; for( i = 0; i < size; i += 1 ) { if( glossaryImageOverride[i].uniqueTag == uniqueTag ) return glossaryImageOverride[i].imageFileName; } return defaultImage; } public function EnableGlossaryImageOverride( uniqueTag : name, imageFileName : string, enable : bool ) { var imageData : SGlossaryImageOverride; var size : int; var i : int; for( i = 0; i < glossaryImageOverride.Size(); i += 1 ) { if( glossaryImageOverride[i].uniqueTag == uniqueTag ) { glossaryImageOverride.Remove(glossaryImageOverride[i]); } } if( enable ) { if( IsNameValid(uniqueTag) && imageFileName != "" ) { glossaryImageOverride.PushBack( SGlossaryImageOverride( uniqueTag, imageFileName ) ); } } } public function SetWeatherDisplayDisabled( disable : bool ) { disableWeatherDisplay = disable; } public function GetWeatherDisplayDisabled() : bool { return disableWeatherDisplay; } public function SetCurrentMonsterHuntInvestigationArea ( area : W3MonsterHuntInvestigationArea ) { currentMonsterHuntInvestigationArea = area; } public function RememberCustomHead( headName : name ) { rememberedCustomHead = headName; } public function GetRememberedCustomHead() : name { return rememberedCustomHead; } public function ClearRememberedCustomHead() { rememberedCustomHead = ''; } public function CreateTutorialInput() { var prevInputHandler : CPlayerInput; prevInputHandler = inputHandler; inputHandler = new W3PlayerTutorialInput in this; inputHandler.Initialize(false, prevInputHandler); if(prevInputHandler) delete prevInputHandler; } public function CreateInput() { var oldInputHandler : CPlayerInput; oldInputHandler = inputHandler; inputHandler = new CPlayerInput in this; inputHandler.Initialize(false, oldInputHandler); } timer function TutorialSilverCombat(dt : float, id : int) { var i : int; var actors : array; if(IsInCombat()) { actors = GetNPCsAndPlayersInRange(20, 1000000, ,FLAG_ExcludePlayer + FLAG_OnlyAliveActors); for(i=0; i; var id : SItemUniqueId; var i : int; if(inv) { inv.GetAllItems(items); if(items.Size() <= 0) { return; } } else { return; } template = (CEntityTemplate)LoadResource("geralt_inventory_release"); entity = theGame.CreateEntity(template, Vector(0,0,0)); invEntity = (CInventoryComponent)entity.GetComponentByClassName('CInventoryComponent'); invEntity.GetAllItems(items); for(i=0; i; var i : int; var slot : EEquipmentSlots; if(inv) { inv.GetAllItems(items); if(items.Size() <= 0) { return; } } else { return; } template = (CEntityTemplate)LoadResource("geralt_inventory_internal"); entity = theGame.CreateEntity(template, Vector(0,0,0)); invTesting = (CInventoryComponent)entity.GetComponentByClassName('CInventoryComponent'); invTesting.GiveAllItemsTo(inv, true); entity.Destroy(); RemoveTimer('Debug_GiveTestingItems'); inv.GetAllItems(items); for(i=0; i; var i : int; template = (CEntityTemplate)LoadResource("geralt_inventory_internal"); entity = theGame.CreateEntity(template, Vector(0,0,0)); invTesting = (CInventoryComponent)entity.GetComponentByClassName('CInventoryComponent'); invTesting.GetAllItems(ids); for(i=0; i; var sword : CWitcherSword; var healthPercentage : float; var tmpBacklight : Vector; if(!skipHeldWeapon) { weapons = inv.GetHeldWeapons(); if(weapons.Size() > 0) { sword = (CWitcherSword)inv.GetItemEntityUnsafe(weapons[0]); if(sword) { tmpBacklight.X = sword.padBacklightColor.X / 255.0f; tmpBacklight.Y = sword.padBacklightColor.Y / 255.0f; tmpBacklight.Z = sword.padBacklightColor.Z / 255.0f; tmpBacklight.W = 1.0f; SetBacklightColor( tmpBacklight ); LogPS4Light("Setting light from sword template: " + NoTrailZeros(sword.padBacklightColor.X) + ", " + NoTrailZeros(sword.padBacklightColor.Y) + ", " + NoTrailZeros(sword.padBacklightColor.Z) ); return; } } } healthPercentage = GetStatPercents( BCS_Vitality ); SetBacklightFromHealth( healthPercentage ); LogPS4Light("Setting light from health, " + NoTrailZeros(RoundMath(healthPercentage*100)) + "%"); } event OnOpenningDoor() { if( !thePlayer.IsUsingHorse() ) RaiseEvent('OpenDoor'); } public final function SetLoopingCameraShakeAnimName( n : name ) { loopingCameraShakeAnimName = n; } public var loopingCameraShakeAnimName : name; timer function RemoveQuestCameraShakeTimer( dt : float , id : int) { RemoveQuestCameraShake( loopingCameraShakeAnimName ); } public function RemoveQuestCameraShake( animName : name ) { var camera : CCustomCamera = theGame.GetGameCamera(); var animation : SCameraAnimationDefinition; camera.StopAnimation( animName ); } public function GetCameraPadding() : float { if( theGame.IsFocusModeActive() ) { return 0.25; } else { return 0.02f; } } public function IsPerformingPhaseChangeAnimation() : bool { return isPerformingPhaseChangeAnimation; } public function SetIsPerformingPhaseChangeAnimation( val : bool ) { isPerformingPhaseChangeAnimation = val; } private function DealCounterDamageToOlgierd() { var damage : W3DamageAction; damage = new W3DamageAction in this; damage.Initialize( thePlayer.GetTarget(), thePlayer.GetTarget(), NULL, this, EHRT_None, CPS_Undefined, false, false, false, true ); damage.AddDamage( theGame.params.DAMAGE_NAME_DIRECT, thePlayer.GetTarget().GetStatMax( BCS_Vitality ) * 3 / 100 ); theGame.damageMgr.ProcessAction( damage ); delete damage; } timer function PlayDelayedCounterDamageEffect( dt : float, id : int ) { thePlayer.GetTarget().PlayEffect( 'olgierd_energy_blast' ); } public function SetTestAdjustRequestedMovementDirection( val : bool ) { testAdjustRequestedMovementDirection = val; } event OnVisualDebug( frame : CScriptedRenderFrame, flag : EShowFlags ) { var boneFollow : int; var bonePosition : Vector; var yrdenEntity : W3YrdenEntity; substateManager.OnVisualDebug( frame, flag ); boneFollow = thePlayer.GetBoneIndex( 'Reference' ); bonePosition = MatrixGetTranslation( thePlayer.GetBoneWorldMatrixByIndex( boneFollow ) ); frame.DrawText( "R", bonePosition, Color( 50, 200, 70 ) ); boneFollow = thePlayer.GetBoneIndex( 'Trajectory' ); bonePosition = MatrixGetTranslation( thePlayer.GetBoneWorldMatrixByIndex( boneFollow ) ); frame.DrawSphere( bonePosition, 0.1f, Color( 200, 50, 70 ) ); frame.DrawText( "T", bonePosition, Color( 200, 50, 70 ) ); yrdenEntity = (W3YrdenEntity)GetWitcherPlayer().GetSignEntity(ST_Yrden); yrdenEntity.OnVisualDebug(frame, flag, false); return true; } timer function PotDrinkTimer(dt : float, id : int) { inputHandler.PotDrinkTimer(false); } public function SetIsHorseRacing( val : bool ) { isHorseRacing = val; } public function GetIsHorseRacing() : bool { return isHorseRacing; } public function SetHorseCombatSlowMo( val : bool ) { horseCombatSlowMo = val; } public function GetHorseCombatSlowMo() : bool { return horseCombatSlowMo; } public function SetItemsPerLevelGiven( id : int ) { itemsPerLevelGiven[id] = true; } private function AddItemPerLevelList() { var i : int; itemsPerLevel.Clear(); itemsPerLevel.PushBack('O'); itemsPerLevel.PushBack('No Mans Land sword 2'); itemsPerLevel.PushBack('No Mans Land sword 3'); itemsPerLevel.PushBack('Silver sword 2'); itemsPerLevel.PushBack('Boots 01'); itemsPerLevel.PushBack('Novigraadan sword 2'); itemsPerLevel.PushBack('Light armor 01'); itemsPerLevel.PushBack('Heavy boots 01'); itemsPerLevel.PushBack('Nilfgaardian sword 3'); itemsPerLevel.PushBack('Silver sword 3'); itemsPerLevel.PushBack('Heavy gloves 01'); itemsPerLevel.PushBack('Skellige sword 2'); itemsPerLevel.PushBack('Heavy pants 01'); itemsPerLevel.PushBack('Silver sword 4'); itemsPerLevel.PushBack('No Mans Land sword 4'); itemsPerLevel.PushBack('Heavy armor 01'); itemsPerLevel.PushBack('Heavy boots 02'); itemsPerLevel.PushBack('Skellige sword 3'); itemsPerLevel.PushBack('Silver sword 5'); itemsPerLevel.PushBack('Heavy pants 02'); itemsPerLevel.PushBack('Heavy gloves 02'); itemsPerLevel.PushBack('Heavy gloves 02'); itemsPerLevel.PushBack('Heavy armor 02'); itemsPerLevel.PushBack('Scoiatael sword 1'); if ( itemsPerLevelGiven.Size() < 49 ) { itemsPerLevelGiven.Clear(); for (i = 0; i < itemsPerLevel.Size(); i += 1) { itemsPerLevelGiven.PushBack( false ); } } } public function DealDamageToBoat( dmg : float, index : int, optional globalHitPos : Vector ) { var boat : CBoatDestructionComponent; if(usedVehicle) { boat = (CBoatDestructionComponent) usedVehicle.GetComponentByClassName( 'CBoatDestructionComponent' ); if( boat ) { boat.DealDamage( dmg, index, globalHitPos ); } } } public function OnStartTeleportingPlayerToPlayableArea() { var FADEOUT_INTERVAL : float = 0.5; if ( thePlayer.IsUsingHorse() ) { if ( thePlayer.GetUsedHorseComponent().OnCheckHorseJump() ) { thePlayer.GetUsedHorseComponent().SetCanTakeDamageFromFalling( false ); } } if ( thePlayer.IsActionAllowed( EIAB_FastTravel ) ) { OnOpenMapToLetPlayerGoBackToPlayableArea(); } else { theGame.FadeOutAsync( FADEOUT_INTERVAL ); thePlayer.AddTimer( 'BorderTeleportFadeOutTimer', FADEOUT_INTERVAL, false ); } } timer function BorderTeleportFadeOutTimer( dt : float, id : int ) { OnTeleportPlayerToPlayableArea( false ); } public function OnOpenMapToLetPlayerGoBackToPlayableArea() { var initData : W3MapInitData; initData = new W3MapInitData in this; initData.SetTriggeredExitEntity( true ); initData.ignoreSaveSystem = true; initData.setDefaultState('FastTravel'); theGame.RequestMenuWithBackground( 'MapMenu', 'CommonMenu', initData ); } public function OnTeleportPlayerToPlayableArea( afterClosingMap : bool ) { var BLACKSCREEN_INTERVAL : float = 0.1; var manager : CCommonMapManager = theGame.GetCommonMapManager(); thePlayer.TeleportWithRotation( manager.GetBorderTeleportPosition(), manager.GetBorderTeleportRotation() ); thePlayer.AddTimer( 'BorderTeleportFadeInTimer', BLACKSCREEN_INTERVAL, false ); theGame.FadeOutAsync( 0 ); theGame.SetFadeLock('PlayerTeleportation'); } timer function BorderTeleportFadeInTimer( dt : float, id : int ) { theGame.ResetFadeLock('PlayerTeleportation'); theGame.FadeOutAsync( 0 ); theGame.FadeInAsync( 2.0f ); } public final function SetLastInstantKillTime(g : GameTime) { lastInstantKillTime = g; } timer function TestTimer(dt : float, id : int ) { LogChannel('asdf', "asdf"); theGame.FadeOutAsync( 5 ); } public final function Debug_ReleaseCriticalStateSaveLocks() { effectManager.Debug_ReleaseCriticalStateSaveLocks(); } timer function Debug_SpamSpeed(dt : float, id : int) { if(currentlyMountedHorse) { LogSpeed("curr player's horse speed: " + NoTrailZeros(currentlyMountedHorse.GetMovingAgentComponent().GetSpeed())) ; } else { LogSpeed("curr player speed: " + NoTrailZeros(GetMovingAgentComponent().GetSpeed())) ; } } timer function RemoveInstantKillSloMo(dt : float, id : int) { theGame.RemoveTimeScale( theGame.GetTimescaleSource(ETS_InstantKill) ); } timer function RemoveForceFinisher(dt : float, id : int) { forceFinisher = false; } public final function Debug_ClearAllActionLocks(optional action : EInputActionBlock, optional all : bool) { inputHandler.Debug_ClearAllActionLocks(action, all); } function OnFocusedCameraBlendBegin() {} function OnFocusedCameraBlendUpdate( progress : float ) {} function OnFocusedCameraBlendEnd() {} public function GetEtherealCount() : int { return etherealCount; } public function IncrementEtherealCount() { etherealCount += 1; if( etherealCount == 6 ) ResetEtherealCount(); } public function ResetEtherealCount() { etherealCount = 0; } public function SetInsideDiveAttackArea( val : bool ) { insideDiveAttackArea = val; } public function IsInsideDiveAttackArea() : bool { return insideDiveAttackArea; } public function SetDiveAreaNumber( val : int ) { diveAreaNumber = val; } public function GetDiveAreaNumber() : int { return diveAreaNumber; } public function InitPhantomWeaponMgr() { if( !phantomWeaponMgr ) { phantomWeaponMgr = new CPhantomWeaponManager in this; phantomWeaponMgr.Init( this.GetInventory() ); } } public function DestroyPhantomWeaponMgr() { if( phantomWeaponMgr ) { delete phantomWeaponMgr; } } public function GetPhantomWeaponMgr() : CPhantomWeaponManager { if( phantomWeaponMgr ) { return phantomWeaponMgr; } else { return NULL; } } public timer function DischargeWeaponAfter( td : float, id : int ) { GetPhantomWeaponMgr().DischargeWeapon(); } private var forcedFinisherVictim : CActor; timer function PerformFinisher( time : float , id : int ) { var combatTarget : CActor; var i : int; combatTarget = thePlayer.GetTarget(); if( combatTarget ) { combatTarget.Kill( 'AutoFinisher', false, thePlayer ); thePlayer.SetFinisherVictim( combatTarget ); forcedFinisherVictim = combatTarget; thePlayer.CleanCombatActionBuffer(); thePlayer.OnBlockAllCombatTickets( true ); moveTargets = thePlayer.GetMoveTargets(); for( i = 0; i < moveTargets.Size(); i += 1 ) { if( combatTarget != moveTargets[i] ) moveTargets[i].SignalGameplayEvent( 'InterruptChargeAttack' ); } if( theGame.GetInGameConfigWrapper().GetVarValue( 'Gameplay', 'AutomaticFinishersEnabled' ) == "true" ) combatTarget.AddAbility( 'ForceFinisher', false ); if( combatTarget.HasTag( 'ForceFinisher' ) ) combatTarget.AddAbility( 'ForceFinisher', false ); combatTarget.SignalGameplayEvent( 'ForceFinisher' ); thePlayer.FindMoveTarget(); thePlayer.AddTimer( 'SignalFinisher', 0.2, false ); } } timer function SignalFinisher( time : float , id : int ) { forcedFinisherVictim.SignalGameplayEvent( 'Finisher' ); forcedFinisherVictim = NULL; } } exec function ttt() { thePlayer.AddTimer( 'TestTimer', 5, false ); }