class GrappleInteractionCondition extends InteractionScriptedCondition { public export const function Test( const activatorObject : weak< GameObject >, const hotSpotObject : weak< GameObject > ) : Bool { return IsAreaBetweenPlayerAndVictim( activatorObject, hotSpotObject ); } protected const function IsAreaBetweenPlayerAndVictim( const activatorObject : weak< GameObject >, const hotSpotObject : weak< GameObject > ) : Bool { var maxGrabDistOverCover : Float; var toHotSpot : Vector4; var distanceFromHotspot : Float; var behindCoverHeightDifferenceLockout : Float; maxGrabDistOverCover = 1.29999995; toHotSpot = hotSpotObject.GetWorldPosition() - activatorObject.GetWorldPosition(); distanceFromHotspot = Vector4.Length2D( toHotSpot ); behindCoverHeightDifferenceLockout = -0.5; if( !( SpatialQueriesHelper.HasSpaceInFront( activatorObject, toHotSpot, 1.29999995, 0.5, distanceFromHotspot, 0.40000001 ) ) ) { return false; } if( ( toHotSpot.Z < behindCoverHeightDifferenceLockout ) && !( SpatialQueriesHelper.HasSpaceInFront( activatorObject, toHotSpot, 0.60000002, 0.5, distanceFromHotspot, 0.69999999 ) ) ) { return false; } if( distanceFromHotspot < maxGrabDistOverCover ) { return true; } return SpatialQueriesHelper.HasSpaceInFront( hotSpotObject, toHotSpot * -1.0, 0.60000002, 0.5, distanceFromHotspot - maxGrabDistOverCover, 1.10000002 ); } } class NewPerkFinisherCondition extends InteractionScriptedCondition { public export const function Test( const activatorObject : weak< GameObject >, const hotSpotObject : weak< GameObject > ) : Bool { var equippedWeapon : WeaponObject; var weaponRecord : Item_Record; var tags : array< CName >; var targetPuppet : weak< ScriptedPuppet >; var gameInstance : GameInstance; var interactonsBlackboard : IBlackboard; var interactionData : UIInteractionsDef; var choiceData : DialogChoiceHubs; var psmBlackBoard : IBlackboard; var eMeleeWeaponState : gamePSMMeleeWeapon; var result : Bool; var npcTarget : NPCPuppet; var statsSystem : StatsSystem; statsSystem = GameInstance.GetStatsSystem( activatorObject.GetGame() ); equippedWeapon = GameObject.GetActiveWeapon( activatorObject ); if( !( equippedWeapon.IsMelee() ) ) { return false; } weaponRecord = TDB.GetWeaponItemRecord( ItemID.GetTDBID( equippedWeapon.GetItemID() ) ); tags = weaponRecord.Tags(); if( !( tags.Contains( 'FinisherFront' ) ) && !( tags.Contains( 'FinisherBack' ) ) ) { return false; } targetPuppet = ( ( ScriptedPuppet )( hotSpotObject ) ); if( !( targetPuppet ) ) { return false; } if( targetPuppet.IsCrowd() || targetPuppet.IsCharacterCivilian() ) { return false; } if( !( ScriptedPuppet.IsActive( targetPuppet ) ) ) { return false; } if( StatusEffectSystem.ObjectHasStatusEffect( activatorObject, T"GameplayRestriction.FistFight" ) ) { return false; } gameInstance = activatorObject.GetGame(); if( GameInstance.GetGodModeSystem( gameInstance ).HasGodMode( targetPuppet.GetEntityID(), gameGodModeType.Immortal ) ) { return false; } if( GameInstance.GetGodModeSystem( gameInstance ).HasGodMode( targetPuppet.GetEntityID(), gameGodModeType.Invulnerable ) ) { return false; } if( GameInstance.GetMountingFacility( gameInstance ).IsMountedToAnything( activatorObject.GetEntityID() ) ) { return false; } if( GameInstance.GetMountingFacility( gameInstance ).IsMountedToAnything( targetPuppet.GetEntityID() ) ) { return false; } interactonsBlackboard = GameInstance.GetBlackboardSystem( gameInstance ).Get( GetAllBlackboardDefs().UIInteractions ); interactionData = GetAllBlackboardDefs().UIInteractions; choiceData = ( ( DialogChoiceHubs )( interactonsBlackboard.GetVariant( interactionData.DialogChoiceHubs ) ) ); if( choiceData.choiceHubs.Size() > 0 ) { return false; } psmBlackBoard = GameInstance.GetBlackboardSystem( gameInstance ).GetLocalInstanced( activatorObject.GetEntityID(), GetAllBlackboardDefs().PlayerStateMachine ); eMeleeWeaponState = ( ( gamePSMMeleeWeapon )( psmBlackBoard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.MeleeWeapon ) ) ); if( eMeleeWeaponState == gamePSMMeleeWeapon.NotReady ) { return false; } if( eMeleeWeaponState == gamePSMMeleeWeapon.StrongAttack ) { return false; } npcTarget = ( ( NPCPuppet )( hotSpotObject ) ); if( npcTarget && npcTarget.IsAboutToDieOrDefeated() ) { return false; } if( equippedWeapon.IsBlunt() && statsSystem.GetStatBoolValue( activatorObject.GetEntityID(), gamedataStatType.CanPerformBluntFinisher ) ) { result = IsFinisherAvailable( activatorObject, hotSpotObject ) && NewPerkFinisherBluntEnabled( activatorObject, hotSpotObject, equippedWeapon ); } else if( equippedWeapon.IsThrowable() && statsSystem.GetStatBoolValue( activatorObject.GetEntityID(), gamedataStatType.CanPerformCoolFinisher ) ) { result = IsFinisherAvailable( activatorObject, hotSpotObject ) && NewPerkFinisherThrowableEnabled( activatorObject, hotSpotObject, equippedWeapon ); } else if( equippedWeapon.IsBlade() && statsSystem.GetStatBoolValue( activatorObject.GetEntityID(), gamedataStatType.CanPerformReflexFinisher ) ) { result = IsFinisherAvailable( activatorObject, hotSpotObject ) && NewPerkFinisherBladeEnabled( activatorObject, hotSpotObject, equippedWeapon ); } else if( equippedWeapon.IsMonowire() && statsSystem.GetStatBoolValue( activatorObject.GetEntityID(), gamedataStatType.CanPerformMonowireFinisher ) ) { result = IsFinisherAvailable( activatorObject, hotSpotObject ) && NewPerkFinisherMonowireEnabled( activatorObject, hotSpotObject, equippedWeapon ); } else { return false; } if( !( result ) ) { return false; } else { if( !( targetPuppet.IsFinisherSoundPlayed() ) && !( hotSpotObject.GetIsInFastFinisher() ) ) { GameObject.PlaySound( activatorObject, 'w_melee_perk_finisher_ready' ); targetPuppet.SetFinisherSoundPlayed( true ); } } return IsAreaClear( activatorObject, hotSpotObject ); } private const function IsFinisherAvailable( const activatorObject : weak< GameObject >, const hotSpotObject : weak< GameObject > ) : Bool { var isInPoiseState : Bool; var isInThreshold : Bool; isInPoiseState = StatusEffectSystem.ObjectHasStatusEffect( hotSpotObject, T"BaseStatusEffect.FinisherActiveStatusEffect" ); isInThreshold = hotSpotObject.IsInFinisherHealthThreshold( activatorObject ); if( !( isInPoiseState ) && !( isInThreshold ) ) { return false; } return true; } protected const function NewPerkFinisherBladeEnabled( const activatorObject : weak< GameObject >, const hotSpotObject : weak< GameObject >, equippedWeapon : WeaponObject ) : Bool { var statsSystem : StatsSystem; var minDistance : Float; var distanceFromHotspot : Float; statsSystem = GameInstance.GetStatsSystem( activatorObject.GetGame() ); distanceFromHotspot = Vector4.Length2D( hotSpotObject.GetWorldPosition() - activatorObject.GetWorldPosition() ); minDistance = statsSystem.GetStatValue( activatorObject.GetEntityID(), gamedataStatType.NewPerkFinisherReflexes_TargetDistanceMax ); if( PlayerDevelopmentSystem.GetData( activatorObject ).IsNewPerkBoughtAnyLevel( gamedataNewPerkType.Reflexes_Right_Perk_3_4 ) ) { minDistance *= TweakDBInterface.GetFloat( T"NewPerks.Reflexes_Right_Perk_3_4.distanceMult", 2.0 ); } return distanceFromHotspot < minDistance; } protected const function NewPerkFinisherThrowableEnabled( const activatorObject : weak< GameObject >, const hotSpotObject : weak< GameObject >, equippedWeapon : WeaponObject ) : Bool { var statsSystem : StatsSystem; var minDistance : Float; var distanceFromHotspot : Float; statsSystem = GameInstance.GetStatsSystem( activatorObject.GetGame() ); distanceFromHotspot = Vector4.Length2D( hotSpotObject.GetWorldPosition() - activatorObject.GetWorldPosition() ); minDistance = statsSystem.GetStatValue( activatorObject.GetEntityID(), gamedataStatType.NewPerkFinisherCool_TargetDistanceMax ); minDistance += ( TweakDBInterface.GetFloat( T"NewPerks.Cool_Inbetween_Right_3.distanceBase", 5.0 ) * ClampF( GameInstance.GetStatsSystem( hotSpotObject.GetGame() ).GetStatValue( hotSpotObject.GetEntityID(), gamedataStatType.Cool_Inbetween_Right_3_Stacks ), 0.0, TweakDBInterface.GetFloat( T"NewPerks.Cool_Inbetween_Right_3.distanceMaxStacks", 3.0 ) ) ); if( distanceFromHotspot > minDistance ) { return false; } return true; } protected const function NewPerkFinisherMonowireEnabled( const activatorObject : weak< GameObject >, const hotSpotObject : weak< GameObject >, equippedWeapon : WeaponObject ) : Bool { var statsSystem : StatsSystem; var minDistance : Float; var distanceFromHotspot : Float; statsSystem = GameInstance.GetStatsSystem( activatorObject.GetGame() ); distanceFromHotspot = Vector4.Length2D( hotSpotObject.GetWorldPosition() - activatorObject.GetWorldPosition() ); minDistance = statsSystem.GetStatValue( activatorObject.GetEntityID(), gamedataStatType.NewPerkFinisherMonowire_TargetDistanceMax ); minDistance += ( TweakDBInterface.GetFloat( T"NewPerks.Reflexes_Right_Perk_3_4.distanceMult", 3.0 ) * ( ( Float )( ( ( ScriptedPuppet )( hotSpotObject ) ).GetDeviceActionQueueSize() ) ) ); if( distanceFromHotspot > minDistance ) { return false; } return true; } protected const function NewPerkFinisherBluntEnabled( const activatorObject : weak< GameObject >, const hotSpotObject : weak< GameObject >, const equippedWeapon : WeaponObject ) : Bool { var statsSystem : StatsSystem; var targetDistanceMax : Float; statsSystem = GameInstance.GetStatsSystem( activatorObject.GetGame() ); targetDistanceMax = statsSystem.GetStatValue( activatorObject.GetEntityID(), gamedataStatType.NewPerkFinisherBlunt_TargetDistanceMax ); if( Vector4.Length2D( hotSpotObject.GetWorldPosition() - activatorObject.GetWorldPosition() ) > targetDistanceMax ) { return false; } return true; } private const function IsAreaClear( const activatorObject : weak< GameObject >, const hotSpotObject : weak< GameObject > ) : Bool { var toHotSpot : Vector4; var leapAngle : EulerAngles; var distanceFromHotspot : Float; var isObstacleVaultable : Bool; toHotSpot = hotSpotObject.GetWorldPosition() - activatorObject.GetWorldPosition(); leapAngle = Vector4.ToRotation( toHotSpot ); if( -( leapAngle.Pitch ) > TDB.GetFloat( T"playerStateMachineFinisher.finisherLeapToTarget.leapMaxPitch" ) ) { return false; } distanceFromHotspot = Vector4.Length2D( toHotSpot ); distanceFromHotspot = MinF( distanceFromHotspot, 1.5 ); if( !( SpatialQueriesHelper.HasSpaceInFront( activatorObject, toHotSpot, 1.29999995, 0.5, distanceFromHotspot, 0.40000001 ) ) ) { return false; } if( !( GameInstance.GetTargetingSystem( activatorObject.GetGame() ).IsVisibleTarget( activatorObject, hotSpotObject ) ) ) { return false; } return SpatialQueriesHelper.IsTargetReachable( activatorObject, hotSpotObject, hotSpotObject.GetWorldPosition(), true, isObstacleVaultable ); } } class BlackwallForceInteractionCondition extends InteractionScriptedCondition { public export const function Test( const activatorObject : weak< GameObject >, const hotSpotObject : weak< GameObject > ) : Bool { return CanUseBlackwall( activatorObject, hotSpotObject ); } protected const function BlackwallForceEnabled( const activatorObject : weak< GameObject >, const hotSpotObject : weak< GameObject > ) : Bool { const var player : PlayerPuppet; player = ( ( PlayerPuppet )( activatorObject ) ); return player.IsBlackwallForceEquippedOnPlayer() && !( StatusEffectSystem.ObjectHasStatusEffectWithTag( player, 'BlackwallSQCooldown' ) ); } protected const function TargetMarkedByBlackwall( const activatorObject : weak< GameObject >, const hotSpotObject : weak< GameObject > ) : Bool { var target : GameObject; target = hotSpotObject; return StatusEffectSystem.ObjectHasStatusEffectWithTag( target, 'BlackwallMark' ); } protected const function CanUseBlackwall( const activatorObject : weak< GameObject >, const hotSpotObject : weak< GameObject > ) : Bool { return BlackwallForceEnabled( activatorObject, hotSpotObject ) && TargetMarkedByBlackwall( activatorObject, hotSpotObject ); } } class ContainerStateInteractionCondition extends InteractionScriptedCondition { public export const function Test( const activatorObject : weak< GameObject >, const hotSpotObject : weak< GameObject > ) : Bool { var container : gameLootContainerBase; container = ( ( gameLootContainerBase )( hotSpotObject ) ); if( container ) { return !( container.IsDisabled() ); } else { return false; } } } class DeviceDirectInteractionCondition extends InteractionScriptedCondition { public export const function Test( const activatorObject : weak< GameObject >, const hotSpotObject : weak< GameObject > ) : Bool { return ( ( Device )( hotSpotObject ) ).IsDirectInteractionCondition(); } } class IsPlayerNotInteractingWithDevice extends InteractionScriptedCondition { public const function Test( const activatorObject : weak< GameObject >, const hotSpotObject : weak< GameObject > ) : Bool { const var player : PlayerPuppet; var result : Bool; player = ( ( PlayerPuppet )( activatorObject ) ); result = !( player.GetPlayerStateMachineBlackboard().GetBool( GetAllBlackboardDefs().PlayerStateMachine.IsInteractingWithDevice ) ); return result; } } class DeviceRemoteInteractionCondition extends InteractionScriptedCondition { public const function Test( const activatorObject : weak< GameObject >, const hotSpotObject : weak< GameObject > ) : Bool { if( !( IsScannerTarget( hotSpotObject ) ) && !( IsLookaAtTarget( activatorObject, hotSpotObject ) ) ) { return false; } return ShouldEnableLayer( hotSpotObject ); } private const function IsScannerTarget( const hotSpotObject : weak< GameObject > ) : Bool { var blackBoard : IBlackboard; var entityID : EntityID; blackBoard = GameInstance.GetBlackboardSystem( hotSpotObject.GetGame() ).Get( GetAllBlackboardDefs().UI_Scanner ); entityID = blackBoard.GetEntityID( GetAllBlackboardDefs().UI_Scanner.ScannedObject ); return hotSpotObject.GetEntityID() == entityID; } private const function IsLookaAtTarget( const activatorObject : weak< GameObject >, const hotSpotObject : weak< GameObject > ) : Bool { return GameInstance.GetInteractionManager( activatorObject.GetGame() ).IsInteractionLookAtTarget( activatorObject, hotSpotObject ); } private const function ShouldEnableLayer( const hotSpotObject : weak< GameObject > ) : Bool { if( hotSpotObject ) { return hotSpotObject.ShouldEnableRemoteLayer(); } else { return false; } } } class PlayerIsSwimmingCondition extends InteractionScriptedCondition { public const function Test( const activatorObject : weak< GameObject >, const hotSpotObject : weak< GameObject > ) : Bool { const var player : PlayerPuppet; var result : Bool; player = ( ( PlayerPuppet )( activatorObject ) ); result = player.GetPlayerStateMachineBlackboard().GetInt( GetAllBlackboardDefs().PlayerStateMachine.HighLevel ) == ( ( Int32 )( gamePSMHighLevel.Swimming ) ); return result; } } class LootPickupScriptedCondition extends InteractionScriptedCondition { public export const function Test( const activatorObject : weak< GameObject >, const hotSpotObject : weak< GameObject > ) : Bool { var weaponRecord : WeaponItem_Record; var weaponObject : WeaponObject; var itemObject : ItemObject; var itemDropObject : gameItemDropObject; var itemType : gamedataItemType; var isGrenade, isHealingItem : Bool; var player : PlayerPuppet; var chargeItemCurrentCharge, chargeItemMaxCharge, chargeCost : Float; player = ( ( PlayerPuppet )( activatorObject ) ); itemDropObject = ( ( gameItemDropObject )( hotSpotObject ) ); itemObject = itemDropObject.GetItemObject(); weaponObject = ( ( WeaponObject )( itemObject ) ); if( weaponObject ) { weaponRecord = weaponObject.GetWeaponRecord(); if( weaponRecord.EquipArea().Type() == gamedataEquipmentArea.WeaponHeavy ) { if( player.GetPlayerStateMachineBlackboard().GetBool( GetAllBlackboardDefs().PlayerStateMachine.Carrying ) ) { return false; } } } itemType = itemObject.GetItemData().GetItemType(); isGrenade = itemType == gamedataItemType.Gad_Grenade; isHealingItem = itemType == gamedataItemType.Con_Inhaler || itemType == gamedataItemType.Con_Injector; if( ( isGrenade || isHealingItem ) && !( itemObject.GetItemData().HasTag( 'ForceRevealConsumable' ) ) ) { chargeItemCurrentCharge = GameInstance.GetStatPoolsSystem( player.GetGame() ).GetStatPoolValue( player.GetEntityID(), ( ( isGrenade ) ? ( gamedataStatPoolType.GrenadesCharges ) : ( gamedataStatPoolType.HealingItemsCharges ) ), false ); chargeItemMaxCharge = GameInstance.GetStatsSystem( player.GetGame() ).GetStatValue( player.GetEntityID(), ( ( isGrenade ) ? ( gamedataStatType.GrenadesMaxCharges ) : ( gamedataStatType.HealingItemMaxCharges ) ) ); chargeCost = ( ( Float )( ( ( isGrenade ) ? ( player.GetGrenadeThrowCostClean() ) : ( player.GetHealingItemUseCost() ) ) ) ); return ( chargeItemCurrentCharge / chargeCost ) < chargeItemMaxCharge; } return true; } }