enum ActiveBaseContext
{
	None = 0,
	Locomotion = 1,
	Ladder = 2,
	Swimming = 3,
	BodyCarring = 4,
	MeleeWeapon = 5,
	RangedWeapon = 6,
	BodyCarringWithRangedWeapon = 7,
}

abstract class InputContextTransition extends DefaultTransition
{

	private const function GetVehicle( const scriptInterface : StateGameScriptInterface, out vehicle : weak< VehicleObject > ) : Bool
	{
		var player : weak< GameObject >;
		var vehicleID : EntityID;
		player = ( ( GameObject )( scriptInterface.owner ) );
		vehicleID = scriptInterface.localBlackboard.GetEntityID( GetAllBlackboardDefs().PlayerStateMachine.EntityIDVehicleRemoteControlled );
		if( VehicleComponent.GetVehicleFromID( player.GetGame(), vehicleID, vehicle ) )
		{
			return true;
		}
		if( VehicleComponent.GetVehicle( player.GetGame(), player.GetEntityID(), vehicle ) )
		{
			return true;
		}
		return false;
	}

	protected const function IsVehicleRemoteControlled( const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var vehicle : weak< VehicleObject >;
		if( GetVehicle( scriptInterface, vehicle ) )
		{
			return vehicle.IsVehicleRemoteControlled();
		}
		return false;
	}

	protected const function ToggleVehicleRemoteControlCamera( const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var vehicle : weak< VehicleObject >;
		if( GetVehicle( scriptInterface, vehicle ) && vehicle.IsVehicleRemoteControlled() )
		{
			vehicle.ToggleVehicleRemoteControlCamera();
			return true;
		}
		return false;
	}

	protected const function SetVehicleRemoteControlled( const scriptInterface : StateGameScriptInterface, enable : Bool ) : Bool
	{
		var vehicle : weak< VehicleObject >;
		if( GetVehicle( scriptInterface, vehicle ) && ( !( enable ) || vehicle.IsHackable() ) )
		{
			vehicle.SetVehicleRemoteControlled( enable, false, true );
			return true;
		}
		return false;
	}

	protected const function GetDriverCombatType( const stateContext : StateContext ) : gamedataDriverCombatType
	{
		var driverCombatType : StateResultInt;
		driverCombatType = stateContext.GetPermanentIntParameter( 'driverCombatType' );
		if( driverCombatType.valid )
		{
			return ( ( gamedataDriverCombatType )( driverCombatType.value ) );
		}
		return gamedataDriverCombatType.Invalid;
	}

	protected const function GetUIBlackboard( scriptInterface : StateGameScriptInterface ) : IBlackboard
	{
		var blackboardSystem : BlackboardSystem;
		var blackboard : IBlackboard;
		blackboardSystem = scriptInterface.GetBlackboardSystem();
		blackboard = blackboardSystem.Get( GetAllBlackboardDefs().UI_QuickSlotsData );
		return blackboard;
	}

}

abstract class InputContextTransitionDecisions extends InputContextTransition
{

	protected const virtual function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		return true;
	}

	protected const virtual function ToGameplayContext( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		return !( IsOnEnterConditionEnabled() ) || !( EnterCondition( stateContext, scriptInterface ) );
	}

	protected const virtual function ToBaseContext( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		return !( IsOnEnterConditionEnabled() ) || !( EnterCondition( stateContext, scriptInterface ) );
	}

	protected export const virtual function ExitCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		return !( IsOnEnterConditionEnabled() ) || !( EnterCondition( stateContext, scriptInterface ) );
	}

}

abstract class InputContextTransitionEvents extends InputContextTransition
{
	var m_gameplaySettings : weak< GameplaySettingsSystem >;
	var m_onInputSchemeUpdatedCallback : CallbackHandle;
	var m_OnInputHintManagerInitializedChangedCallback : CallbackHandle;
	var m_onInputSchemeChanged : Bool;
	protected var m_hasControllerChanged : Bool;
	protected var m_hasControllerSchemeChanged : Bool;
	var m_isGameplayInputHintManagerInitialized : Bool;
	var m_isGameplayInputHintRefreshRequired : Bool;

	protected export function OnAttach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		var inputSchemesBB : IBlackboard;
		inputSchemesBB = GameInstance.GetBlackboardSystem( scriptInterface.GetGame() ).Get( GetAllBlackboardDefs().InputSchemes );
		if( inputSchemesBB )
		{
			m_onInputSchemeUpdatedCallback = inputSchemesBB.RegisterListenerUint( GetAllBlackboardDefs().InputSchemes.Scheme, this, 'OnInputSchemeUpdated' );
			m_OnInputHintManagerInitializedChangedCallback = inputSchemesBB.RegisterListenerVariant( GetAllBlackboardDefs().InputSchemes.InitializedInputHintManagerList, this, 'OnInputHintManagerInitializedChanged' );
		}
		m_gameplaySettings = GameplaySettingsSystem.GetGameplaySettingsSystemInstance( scriptInterface.executionOwner );
	}

	protected export function OnDetach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		var inputSchemesBB : IBlackboard;
		inputSchemesBB = GameInstance.GetBlackboardSystem( scriptInterface.GetGame() ).Get( GetAllBlackboardDefs().InputSchemes );
		if( m_onInputSchemeUpdatedCallback )
		{
			inputSchemesBB.UnregisterListenerUint( GetAllBlackboardDefs().InputSchemes.Scheme, m_onInputSchemeUpdatedCallback );
		}
		if( m_OnInputHintManagerInitializedChangedCallback )
		{
			inputSchemesBB.UnregisterListenerVariant( GetAllBlackboardDefs().InputSchemes.InitializedInputHintManagerList, m_OnInputHintManagerInitializedChangedCallback );
		}
	}

	protected event OnInputSchemeUpdated( value : Uint32 )
	{
		m_onInputSchemeChanged = true;
	}

	protected function OnInputHintManagerInitializedChanged( value : Variant )
	{
		var currentInitializedInputHintManagerList : array< CName >;
		var isGameplayInputHintManagerInitialized : Bool;
		var i : Int32;
		currentInitializedInputHintManagerList = ( ( array< CName > )value );
		for( i = 0; i < currentInitializedInputHintManagerList.Size(); i += 1 )
		{
			if( currentInitializedInputHintManagerList[ i ] == 'GameplayInputHelper' )
			{
				isGameplayInputHintManagerInitialized = true;
				break;
			}
		}
		m_isGameplayInputHintRefreshRequired = m_isGameplayInputHintManagerInitialized != isGameplayInputHintManagerInitialized && !( m_isGameplayInputHintManagerInitialized );
		m_isGameplayInputHintManagerInitialized = isGameplayInputHintManagerInitialized;
	}

	protected const function ShouldForceRefreshInputHints( const stateContext : StateContext ) : Bool
	{
		var shouldForceRefreshInputHints : StateResultBool;
		shouldForceRefreshInputHints = stateContext.GetTemporaryBoolParameter( 'ForceRefreshInputHints' );
		return m_isGameplayInputHintRefreshRequired || ( shouldForceRefreshInputHints.valid && shouldForceRefreshInputHints.value );
	}

	protected const function ShowBodyCarryInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		var psmBodyCarrying : gamePSMBodyCarrying;
		psmBodyCarrying = ( ( gamePSMBodyCarrying )( scriptInterface.localBlackboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.BodyCarrying ) ) );
		if( scriptInterface.localBlackboard.GetBool( GetAllBlackboardDefs().PlayerStateMachine.CanThrowCarriedNPC ) )
		{
			ShowInputHint( scriptInterface, 'ThrowNPC', 'BodyCarry', "LocKey#17844", inkInputHintHoldIndicationType.Press );
			stateContext.SetPermanentBoolParameter( 'isThrowCarriedNPCInputHintDisplayed', true, true );
		}
		if( psmBodyCarrying == gamePSMBodyCarrying.Carry )
		{
			if( scriptInterface.executionOwner.PlayerLastUsedPad() )
			{
				if( scriptInterface.HasStatFlag( gamedataStatType.CanShootWhileCarryingBody ) )
				{
					ShowInputHint( scriptInterface, 'DropCarriedObject', 'BodyCarry', "LocKey#43673", inkInputHintHoldIndicationType.FromInputConfig, true );
				}
				else
				{
					ShowInputHint( scriptInterface, 'DropCarriedObject', 'BodyCarry', "LocKey#43673" );
				}
			}
			else
			{
				ShowInputHint( scriptInterface, 'DropCarriedObject', 'BodyCarry', "LocKey#43673", inkInputHintHoldIndicationType.Press );
			}
		}
		stateContext.SetPermanentBoolParameter( 'isBodyCarryInputHintDisplayed', true, true );
	}

	protected const function RemoveBodyCarryInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( m_isGameplayInputHintManagerInitialized )
		{
			RemoveInputHintsBySource( scriptInterface, 'BodyCarry' );
		}
		stateContext.RemovePermanentBoolParameter( 'isThrowCarriedNPCInputHintDisplayed' );
		stateContext.RemovePermanentBoolParameter( 'isBodyCarryInputHintDisplayed' );
	}

	protected const function ShowLadderInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		ShowInputHint( scriptInterface, 'ToggleSprint', 'Ladder', "LocKey#36200" );
		ShowInputHint( scriptInterface, 'Jump', 'Ladder', "LocKey#36201" );
		ShowInputHint( scriptInterface, 'ToggleCrouch', 'Ladder', "LocKey#36204" );
		stateContext.SetPermanentBoolParameter( 'isLadderInputHintDisplayed', true, true );
	}

	protected const function RemoveLadderInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( m_isGameplayInputHintManagerInitialized )
		{
			RemoveInputHintsBySource( scriptInterface, 'Ladder' );
		}
		stateContext.RemovePermanentBoolParameter( 'isLadderInputHintDisplayed' );
	}

	protected const function ShowTerminalInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		ShowInputHint( scriptInterface, 'Choice1', 'Terminal', "LocKey#49422" );
		stateContext.SetPermanentBoolParameter( 'isTerminalInputHintDisplayed', true, true );
	}

	protected const function RemoveTerminalInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( m_isGameplayInputHintManagerInitialized )
		{
			RemoveInputHintsBySource( scriptInterface, 'Terminal' );
		}
		stateContext.RemovePermanentBoolParameter( 'isTerminalInputHintDisplayed' );
	}

	protected const function ShowGenericExplorationInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( stateContext.GetStateMachineCurrentState( 'CombatGadget' ) == 'combatGadgetCharge' )
		{
			ShowInputHint( scriptInterface, 'CancelChargingCG', 'Locomotion', "LocKey#49906" );
		}
		else if( !( IsEmptyHandsForced( stateContext, scriptInterface ) ) )
		{
			ShowInputHint( scriptInterface, 'SwitchItem', 'Locomotion', "LocKey#45381" );
		}
		ShowCrouchInputHint( stateContext, scriptInterface, 'Locomotion' );
		stateContext.SetPermanentBoolParameter( 'isLocomotionInputHintDisplayed', true, true );
	}

	protected function RemoveGenericExplorationInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( m_isGameplayInputHintManagerInitialized )
		{
			RemoveInputHintsBySource( scriptInterface, 'Locomotion' );
		}
		stateContext.RemovePermanentBoolParameter( 'isCrouchInputHintDisplayed' );
		stateContext.RemovePermanentBoolParameter( 'isLocomotionInputHintDisplayed' );
	}

	protected const function ShowMeleeInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		var weapon : WeaponObject;
		var isThrowable : Bool;
		var isAiming : Bool;
		weapon = GameObject.GetActiveWeapon( GameInstance.GetPlayerSystem( scriptInterface.GetGame() ).GetLocalPlayerMainGameObject() );
		isThrowable = weapon.IsThrowable();
		isAiming = stateContext.IsStateActive( 'UpperBody', 'aimingState' );
		ShowInputHint( scriptInterface, 'MeleeAttack', 'Melee', ( ( isThrowable && isAiming ) ? ( "LocKey#17844" ) : ( "LocKey#40351" ) ), inkInputHintHoldIndicationType.Press, false, 1 );
		ShowInputHint( scriptInterface, 'MeleeBlock', 'Melee', ( ( isThrowable ) ? ( "LocKey#45379" ) : ( "LocKey#36191" ) ), inkInputHintHoldIndicationType.Press, true, 2 );
		ShowDodgeInputHint( stateContext, scriptInterface, 'Melee' );
		if( !( stateContext.GetBoolParameter( 'isCrouchInputHintDisplayed', true ) ) && ( ( gamePSMCombat )( scriptInterface.localBlackboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.Combat ) ) ) != gamePSMCombat.InCombat )
		{
			ShowCrouchInputHint( stateContext, scriptInterface, 'Melee' );
		}
		stateContext.SetPermanentBoolParameter( 'isMeleeInputHintDisplayed', true, true );
		stateContext.SetPermanentBoolParameter( 'isThrowInputHintDisplayed', isThrowable && isAiming, true );
	}

	protected function RemoveMeleeInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( m_isGameplayInputHintManagerInitialized )
		{
			RemoveInputHintsBySource( scriptInterface, 'Melee' );
		}
		stateContext.RemovePermanentBoolParameter( 'isMeleeInputHintDisplayed' );
		stateContext.RemovePermanentBoolParameter( 'isThrowInputHintDisplayed' );
		stateContext.RemovePermanentBoolParameter( 'isCrouchInputHintDisplayed' );
	}

	protected const function ShowRangedInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		var isChargeInputHintDisplayed : Bool;
		var isChargeRangedWeapon : Bool;
		isChargeInputHintDisplayed = stateContext.GetBoolParameter( 'isChargeInputHintDisplayed', true );
		isChargeRangedWeapon = IsChargeRangedWeapon( scriptInterface );
		if( !( isChargeInputHintDisplayed ) && isChargeRangedWeapon )
		{
			ShowInputHint( scriptInterface, 'RangedAttack', 'Ranged', "LocKey#47919", inkInputHintHoldIndicationType.FromInputConfig, true, 0 );
			stateContext.SetPermanentBoolParameter( 'isChargeInputHintDisplayed', true, true );
		}
		if( !( stateContext.GetBoolParameter( 'isQuickMeleeInputHintDisplayed', true ) ) && !( StatusEffectSystem.ObjectHasStatusEffectWithTag( scriptInterface.executionOwner, 'NoQuickMelee' ) ) )
		{
			ShowInputHint( scriptInterface, 'QuickMelee', 'Ranged', "LocKey#45380", inkInputHintHoldIndicationType.FromInputConfig, true, 1 );
			stateContext.SetPermanentBoolParameter( 'isQuickMeleeInputHintDisplayed', true, true );
		}
		if( !( stateContext.GetBoolParameter( 'isRangedInputHintDisplayed', true ) ) )
		{
			ShowInputHint( scriptInterface, 'Reload', 'Ranged', "LocKey#36198", inkInputHintHoldIndicationType.FromInputConfig, true, 2 );
			stateContext.SetPermanentBoolParameter( 'isRangedInputHintDisplayed', true, true );
		}
		if( ( ( !( stateContext.GetBoolParameter( 'isRangedDodgeInputHintDisplayed', true ) ) && scriptInterface.HasStatFlag( gamedataStatType.HasDodge ) ) && !( stateContext.IsStateActive( 'UpperBody', 'aimingState' ) ) ) || scriptInterface.HasStatFlag( gamedataStatType.CanAimWhileDodging ) )
		{
			ShowDodgeInputHint( stateContext, scriptInterface, 'Ranged' );
			stateContext.SetPermanentBoolParameter( 'isRangedDodgeInputHintDisplayed', true, true );
		}
		if( !( stateContext.GetBoolParameter( 'isCrouchInputHintDisplayed', true ) ) && ( ( gamePSMCombat )( scriptInterface.localBlackboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.Combat ) ) ) != gamePSMCombat.InCombat )
		{
			ShowCrouchInputHint( stateContext, scriptInterface, 'Ranged' );
		}
	}

	protected function RemoveRangedInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( m_isGameplayInputHintManagerInitialized )
		{
			RemoveInputHintsBySource( scriptInterface, 'Ranged' );
		}
		stateContext.RemovePermanentBoolParameter( 'isChargeInputHintDisplayed' );
		stateContext.RemovePermanentBoolParameter( 'isQuickMeleeInputHintDisplayed' );
		stateContext.RemovePermanentBoolParameter( 'isRangedInputHintDisplayed' );
		stateContext.RemovePermanentBoolParameter( 'isRangedDodgeInputHintDisplayed' );
		stateContext.RemovePermanentBoolParameter( 'isCrouchInputHintDisplayed' );
	}

	protected const function ShowDodgeInputHint( stateContext : StateContext, scriptInterface : StateGameScriptInterface, source : CName )
	{
		var gamepadInputSchemeBB : IBlackboard;
		var gamepadInputScheme : Uint32;
		gamepadInputSchemeBB = GameInstance.GetBlackboardSystem( scriptInterface.GetGame() ).Get( GetAllBlackboardDefs().InputSchemes );
		gamepadInputScheme = gamepadInputSchemeBB.GetUint( GetAllBlackboardDefs().InputSchemes.Scheme );
		if( scriptInterface.executionOwner.PlayerLastUsedKBM() )
		{
			ShowInputHint( scriptInterface, 'Dodge', source, "LocKey#87591", inkInputHintHoldIndicationType.FromInputConfig, true, 3 );
		}
		else
		{
			if( gamepadInputScheme == ( ( Uint32 )( InputScheme.LEGACY ) ) )
			{
				ShowInputHint( scriptInterface, 'UI_FakeDodge', source, "LocKey#36192", inkInputHintHoldIndicationType.Press, false, 3, inkInputHintKeyCombinationType.And );
			}
			else
			{
				ShowInputHint( scriptInterface, 'UI_FakeDodge', source, "LocKey#87591", inkInputHintHoldIndicationType.Press, false, 3, inkInputHintKeyCombinationType.And );
			}
		}
	}

	protected const function ShowCrouchInputHint( stateContext : StateContext, scriptInterface : StateGameScriptInterface, source : CName )
	{
		if( !( stateContext.GetBoolParameter( 'isCrouchInputHintDisplayed', true ) ) )
		{
			ShowInputHint( scriptInterface, 'ToggleCrouch', source, "LocKey#36202", inkInputHintHoldIndicationType.FromInputConfig, true, ( ( Int32 )( gameuiInputHintSortingPriority.Bottom ) ) );
			stateContext.SetPermanentBoolParameter( 'isCrouchInputHintDisplayed', true, true );
		}
	}

	protected const function ShowVehicleDriverInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		ShowVehicleDrawWeaponInputHint( stateContext, scriptInterface );
		ShowInputHint( scriptInterface, 'ToggleVehCamera', 'VehicleDriver', "LocKey#36194", inkInputHintHoldIndicationType.FromInputConfig, true, 2 );
		ShowVehicleExitInputHint( stateContext, scriptInterface, 'VehicleDriver' );
		stateContext.SetPermanentBoolParameter( 'isDriverInputHintDisplayed', true, true );
	}

	protected const function RemoveVehicleDriverInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( m_isGameplayInputHintManagerInitialized )
		{
			RemoveInputHint( scriptInterface, 'VehicleInsideWheel', 'UI_DPad' );
			RemoveInputHintsBySource( scriptInterface, 'VehicleDriver' );
		}
		stateContext.RemovePermanentBoolParameter( 'isDriverInputHintDisplayed' );
	}

	protected const function ShowVehicleRestrictedInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		ShowInputHint( scriptInterface, 'ToggleVehCamera', 'VehicleDriver', "LocKey#36194", inkInputHintHoldIndicationType.FromInputConfig, true );
		ShowVehicleExitInputHint( stateContext, scriptInterface, 'VehicleDriver' );
	}

	protected const function RemoveVehicleRestrictedInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( m_isGameplayInputHintManagerInitialized )
		{
			RemoveInputHintsBySource( scriptInterface, 'VehicleDriver' );
		}
	}

	protected const function ShowVehiclePassengerInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		ShowVehicleExitInputHint( stateContext, scriptInterface, 'VehiclePassenger' );
		stateContext.SetPermanentBoolParameter( 'isPassengerInputHintDisplayed', true, true );
	}

	protected const function RemoveVehiclePassengerInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( m_isGameplayInputHintManagerInitialized )
		{
			RemoveInputHint( scriptInterface, 'VehicleInsideWheel', 'UI_DPad' );
			RemoveInputHintsBySource( scriptInterface, 'VehiclePassenger' );
		}
		stateContext.RemovePermanentBoolParameter( 'isPassengerInputHintDisplayed' );
	}

	protected const function ShowVehicleRemoteControlDriverInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		ShowInputHint( scriptInterface, 'ToggleVehCamera', 'VehicleRemoteControlDrive', "LocKey#36194" );
		ShowInputHint( scriptInterface, 'Exit', 'VehicleRemoteControlDrive', "LocKey#36196", inkInputHintHoldIndicationType.FromInputConfig, true );
	}

	protected const function RemoveVehicleRemoteControlDriverInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( m_isGameplayInputHintManagerInitialized )
		{
			RemoveInputHintsBySource( scriptInterface, 'VehicleRemoteControlDrive' );
		}
	}

	protected const function ShowVehicleDriverCombatInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		ShowVehicleDriverCombatInputHintsInternal( 'VehicleDriverCombat', stateContext, scriptInterface );
	}

	protected const function RemoveVehicleDriverCombatInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( m_isGameplayInputHintManagerInitialized )
		{
			RemoveInputHintsBySource( scriptInterface, 'VehicleDriverCombat' );
		}
		stateContext.RemovePermanentBoolParameter( 'isDriverCombatScannerInputHintDisplayed' );
		stateContext.RemovePermanentBoolParameter( 'isDriverCombatInputHintDisplayed' );
	}

	protected const function ShowVehicleDriverCombatTPPInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		ShowVehicleDriverCombatInputHintsInternal( 'VehicleDriverCombatTPP', stateContext, scriptInterface );
	}

	protected const function RemoveVehicleDriverCombatTPPInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( m_isGameplayInputHintManagerInitialized )
		{
			RemoveInputHintsBySource( scriptInterface, 'VehicleDriverCombatTPP' );
		}
		stateContext.RemovePermanentBoolParameter( 'isDriverCombatScannerInputHintDisplayed' );
		stateContext.RemovePermanentBoolParameter( 'isDriverCombatInputHintDisplayed' );
	}

	private const function ShowVehicleDriverCombatInputHintsInternal( source : CName, stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		var vehicleRecord : Vehicle_Record;
		var vehicle : weak< VehicleObject >;
		var weapon : WeaponObject;
		var isThrowable, isAiming : Bool;
		VehicleComponent.GetVehicle( scriptInterface.executionOwner.GetGame(), scriptInterface.executionOwner, vehicle );
		vehicleRecord = vehicle.GetRecord();
		if( stateContext.GetBoolParameter( 'inMeleeDriverCombat', true ) )
		{
			RemoveInputHint( scriptInterface, 'UI_FakeRangedAttack', source );
			RemoveInputHint( scriptInterface, 'UI_FakeCameraAim', source );
			weapon = GameObject.GetActiveWeapon( GameInstance.GetPlayerSystem( scriptInterface.GetGame() ).GetLocalPlayerMainGameObject() );
			isThrowable = weapon.IsThrowable();
			isAiming = stateContext.IsStateActive( 'UpperBody', 'aimingState' );
			ShowInputHint( scriptInterface, 'MeleeAttack', source, ( ( isThrowable && isAiming ) ? ( "LocKey#17844" ) : ( "LocKey#40351" ) ), inkInputHintHoldIndicationType.Press, true, 1 );
			ShowInputHint( scriptInterface, 'MeleeBlock', source, ( ( isThrowable ) ? ( "LocKey#45379" ) : ( "LocKey#36191" ) ), inkInputHintHoldIndicationType.Press, true, 2 );
		}
		else
		{
			RemoveInputHint( scriptInterface, 'MeleeAttack', source );
			RemoveInputHint( scriptInterface, 'MeleeBlock', source );
			ShowInputHint( scriptInterface, 'UI_FakeRangedAttack', source, "LocKey#36197", inkInputHintHoldIndicationType.Press, false, 1 );
			ShowInputHint( scriptInterface, 'UI_FakeCameraAim', source, "LocKey#45379", inkInputHintHoldIndicationType.FromInputConfig, true, 2 );
		}
		if( vehicleRecord.VehDataPackageHandle().DriverCombat().Type() != gamedataDriverCombatType.MountedWeapons || vehicle.CanSwitchWeapons() )
		{
			ShowInputHint( scriptInterface, 'SwitchItem', source, "LocKey#77771", inkInputHintHoldIndicationType.FromInputConfig, false, 3 );
		}
		ShowInputHint( scriptInterface, 'ExitCombatMode', source, "LocKey#87490", inkInputHintHoldIndicationType.FromInputConfig, true, 5 );
		ShowInputHint( scriptInterface, 'ToggleVehCamera', source, "LocKey#36194", inkInputHintHoldIndicationType.FromInputConfig, true, 6 );
		stateContext.SetPermanentBoolParameter( 'isDriverCombatInputHintDisplayed', true, true );
		if( scriptInterface.executionOwner.PlayerLastUsedKBM() )
		{
			RemoveInputHint( scriptInterface, 'UI_FakeDriverCombatControllerVisionActivation', source );
			stateContext.RemovePermanentBoolParameter( 'isDriverCombatScannerInputHintDisplayed' );
		}
		else if( EquipmentSystem.IsCyberdeckEquipped( scriptInterface.executionOwner ) && !( QuickhackModule.IsQuickhackBlockedByScene( scriptInterface.executionOwner ) ) )
		{
			ShowInputHint( scriptInterface, 'UI_FakeDriverCombatControllerVisionActivation', source, "LocKey#52040", inkInputHintHoldIndicationType.FromInputConfig, false, 4, inkInputHintKeyCombinationType.And );
			stateContext.SetPermanentBoolParameter( 'isDriverCombatScannerInputHintDisplayed', true, true );
		}
	}

	protected const function ShowVehicleDrawWeaponInputHint( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		var isVehicleCombatModeBlocked : Bool;
		isVehicleCombatModeBlocked = IsVehicleBlockingCombat( scriptInterface ) || IsEmptyHandsForced( stateContext, scriptInterface );
		if( isVehicleCombatModeBlocked )
		{
			RemoveInputHint( scriptInterface, 'EnterCombatMode', 'VehicleDriver' );
			stateContext.SetPermanentBoolParameter( 'IsVehicleCombatModeBlocked', true, true );
			return;
		}
		ShowInputHint( scriptInterface, 'EnterCombatMode', 'VehicleDriver', "LocKey#45381", inkInputHintHoldIndicationType.FromInputConfig, true, 1 );
		stateContext.SetPermanentBoolParameter( 'IsVehicleCombatModeBlocked', false, true );
	}

	protected const function ShowVehicleExitInputHint( stateContext : StateContext, scriptInterface : StateGameScriptInterface, source : CName )
	{
		var vehicle : weak< GameObject >;
		if( IsExitVehicleBlocked( scriptInterface ) )
		{
			RemoveInputHint( scriptInterface, 'Exit', source );
			stateContext.SetPermanentBoolParameter( 'IsExitVehicleBlocked', true, true );
			return;
		}
		VehicleComponent.GetVehicle( scriptInterface.owner.GetGame(), scriptInterface.executionOwner, vehicle );
		if( vehicle = ( ( BikeObject )( vehicle ) ) )
		{
			ShowInputHint( scriptInterface, 'Exit', source, "LocKey#53066", inkInputHintHoldIndicationType.FromInputConfig, true, 127 );
		}
		else
		{
			ShowInputHint( scriptInterface, 'Exit', source, "LocKey#36196", inkInputHintHoldIndicationType.FromInputConfig, true, 127 );
		}
		stateContext.SetPermanentBoolParameter( 'IsExitVehicleBlocked', false, true );
	}

	protected const function ShowVehiclePassengerCombatInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		ShowInputHint( scriptInterface, 'RangedAttack', 'VehiclePassengerCombat', "LocKey#36197", inkInputHintHoldIndicationType.Press );
		ShowInputHint( scriptInterface, 'Reload', 'VehiclePassengerCombat', "LocKey#36198" );
		if( StatusEffectSystem.ObjectHasStatusEffectWithTag( scriptInterface.executionOwner, 'VehicleScene' ) )
		{
			ShowInputHint( scriptInterface, 'WeaponWheel', 'VehiclePassengerCombat', "LocKey#36199" );
		}
		stateContext.SetPermanentBoolParameter( 'isPassengerCombatInputHintDisplayed', true, true );
	}

	protected const function RemoveVehiclePassengerCombatInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( m_isGameplayInputHintManagerInitialized )
		{
			RemoveInputHintsBySource( scriptInterface, 'VehiclePassengerCombat' );
		}
		stateContext.RemovePermanentBoolParameter( 'isPassengerCombatInputHintDisplayed' );
	}

	protected const function ShowSwimmingInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		ShowInputHint( scriptInterface, 'ToggleSprint', 'Swimming', "LocKey#40155" );
		ShowInputHint( scriptInterface, 'Jump', 'Swimming', "LocKey#40158", inkInputHintHoldIndicationType.Press );
		ShowInputHint( scriptInterface, 'Dive', 'Swimming', "LocKey#40157" );
		stateContext.SetPermanentBoolParameter( 'isSwimmingInputHintDisplayed', true, true );
	}

	protected const function RemoveSwimmingInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( m_isGameplayInputHintManagerInitialized )
		{
			RemoveInputHintsBySource( scriptInterface, 'Swimming' );
		}
		stateContext.RemovePermanentBoolParameter( 'isSwimmingInputHintDisplayed' );
	}

	protected function RemoveAllInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		RemoveGenericExplorationInputHints( stateContext, scriptInterface );
		RemoveRangedInputHints( stateContext, scriptInterface );
		RemoveMeleeInputHints( stateContext, scriptInterface );
		RemoveBodyCarryInputHints( stateContext, scriptInterface );
		RemoveLadderInputHints( stateContext, scriptInterface );
		RemoveSwimmingInputHints( stateContext, scriptInterface );
		RemoveVehicleDriverInputHints( stateContext, scriptInterface );
		RemoveVehicleDriverCombatInputHints( stateContext, scriptInterface );
		RemoveVehicleDriverCombatTPPInputHints( stateContext, scriptInterface );
		RemoveVehicleRemoteControlDriverInputHints( stateContext, scriptInterface );
		RemoveVehiclePassengerCombatInputHints( stateContext, scriptInterface );
		RemoveVehiclePassengerInputHints( stateContext, scriptInterface );
		RemoveVehicleRemoteControlDriverInputHints( stateContext, scriptInterface );
		RemoveVehicleRestrictedInputHints( stateContext, scriptInterface );
	}

	protected function SetBaseContextInputHints( context : ActiveBaseContext, stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( context == ActiveBaseContext.None )
		{
			return;
		}
		RemoveAllInputHints( stateContext, scriptInterface );
		switch( context )
		{
			case ActiveBaseContext.Locomotion:
			{
				ShowGenericExplorationInputHints( stateContext, scriptInterface );
				break;
			}
			case ActiveBaseContext.Ladder:
			{
				ShowLadderInputHints( stateContext, scriptInterface );
				break;
			}
			case ActiveBaseContext.Swimming:
			{
				ShowSwimmingInputHints( stateContext, scriptInterface );
				break;
			}
			case ActiveBaseContext.BodyCarring:
			{
				ShowBodyCarryInputHints( stateContext, scriptInterface );
				break;
			}
			case ActiveBaseContext.MeleeWeapon:
			{
				ShowMeleeInputHints( stateContext, scriptInterface );
				break;
			}
			case ActiveBaseContext.RangedWeapon:
			{
				ShowRangedInputHints( stateContext, scriptInterface );
				break;
			}
			case ActiveBaseContext.BodyCarringWithRangedWeapon:
			{
				ShowBodyCarryInputHints( stateContext, scriptInterface );
				ShowRangedInputHints( stateContext, scriptInterface );
				break;
			}
			default:
			{
				break;
			}
		}
	}

	protected function UpdateWeaponInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface ) : ActiveBaseContext
	{
		var isExploring : Bool;
		var isExaminingDevice : Bool;
		var isDeviceControlled : Bool;
		var inEquipState : Bool;
		var rightHandWeapon : weak< WeaponObject >;
		var isRangedWeaponEquipped : Bool;
		var isMeleeWeaponEquipped : Bool;
		var canDisplayChargeInputHint : Bool;
		var canDisplayThrowInputHint : Bool;
		var canDisplayRangedDodgeInputHint : Bool;
		var canDisplayCrouchInputHint : Bool;
		var canDisplayThrowCarriedNPCInputHint : Bool;
		var isMeleeInputHintDisplayed : Bool;
		var isThrowInputHintDisplayed : Bool;
		var isRangedInputHintDisplayed : Bool;
		var isChargeInputHintDisplayed : Bool;
		var isRangedDodgeInputHintDisplayed : Bool;
		var isCrouchInputHintDisplayed : Bool;
		var isThrowCarriedNPCInputHintDisplayed : Bool;
		var context : ActiveBaseContext;
		isExploring = IsInHighLevelState( stateContext, 'exploration' );
		isExaminingDevice = IsExaminingDevice( scriptInterface ) || IsInteractingWithTerminal( scriptInterface );
		isDeviceControlled = scriptInterface.executionOwner.GetTakeOverControlSystem().IsDeviceControlled();
		inEquipState = ( IsRightHandInEquippedState( stateContext ) || IsRightHandInEquippingState( stateContext ) ) || IsInFirstEquip( stateContext );
		rightHandWeapon = GetActiveWeapon( scriptInterface );
		isRangedWeaponEquipped = inEquipState && rightHandWeapon.IsRanged();
		isMeleeWeaponEquipped = ( inEquipState && !( isRangedWeaponEquipped ) ) && rightHandWeapon.IsMelee();
		canDisplayChargeInputHint = isRangedWeaponEquipped && IsChargeRangedWeapon( scriptInterface );
		canDisplayThrowInputHint = ( isMeleeWeaponEquipped && rightHandWeapon.IsThrowable() ) && stateContext.IsStateActive( 'UpperBody', 'aimingState' );
		canDisplayRangedDodgeInputHint = ( !( isRangedWeaponEquipped ) || !( stateContext.IsStateActive( 'UpperBody', 'aimingState' ) ) ) || scriptInterface.HasStatFlag( gamedataStatType.CanAimWhileDodging );
		canDisplayCrouchInputHint = ( ( gamePSMCombat )( scriptInterface.localBlackboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.Combat ) ) ) != gamePSMCombat.InCombat;
		canDisplayThrowCarriedNPCInputHint = scriptInterface.localBlackboard.GetBool( GetAllBlackboardDefs().PlayerStateMachine.CanThrowCarriedNPC );
		isMeleeInputHintDisplayed = stateContext.GetBoolParameter( 'isMeleeInputHintDisplayed', true );
		isThrowInputHintDisplayed = stateContext.GetBoolParameter( 'isThrowInputHintDisplayed', true );
		isRangedInputHintDisplayed = stateContext.GetBoolParameter( 'isRangedInputHintDisplayed', true );
		isChargeInputHintDisplayed = stateContext.GetBoolParameter( 'isChargeInputHintDisplayed', true );
		isRangedDodgeInputHintDisplayed = stateContext.GetBoolParameter( 'isRangedDodgeInputHintDisplayed', true );
		isCrouchInputHintDisplayed = stateContext.GetBoolParameter( 'isCrouchInputHintDisplayed', true );
		isThrowCarriedNPCInputHintDisplayed = stateContext.GetBoolParameter( 'isThrowCarriedNPCInputHintDisplayed', true );
		if( ( ( isMeleeWeaponEquipped && isExploring ) && !( isExaminingDevice ) ) && !( isDeviceControlled ) )
		{
			if( isCrouchInputHintDisplayed && !( canDisplayCrouchInputHint ) )
			{
				RemoveInputHint( scriptInterface, 'ToggleCrouch', 'Melee' );
				stateContext.RemovePermanentBoolParameter( 'isCrouchInputHintDisplayed' );
			}
			if( ( ( ( !( isMeleeInputHintDisplayed ) || m_hasControllerChanged ) || m_hasControllerSchemeChanged ) || isThrowInputHintDisplayed != canDisplayThrowInputHint ) || ( !( isCrouchInputHintDisplayed ) && canDisplayCrouchInputHint ) )
			{
				return ActiveBaseContext.MeleeWeapon;
			}
		}
		else if( isMeleeInputHintDisplayed && ( ( ( !( isMeleeWeaponEquipped ) || !( isExploring ) ) || isExaminingDevice ) || isDeviceControlled ) )
		{
			RemoveMeleeInputHints( stateContext, scriptInterface );
		}
		if( ( ( ( isRangedWeaponEquipped && !( rightHandWeapon.IsHeavyWeapon() ) ) && isExploring ) && !( isExaminingDevice ) ) && !( isDeviceControlled ) )
		{
			if( isChargeInputHintDisplayed && !( canDisplayChargeInputHint ) )
			{
				RemoveInputHint( scriptInterface, 'RangedAttack', 'Ranged' );
				stateContext.RemovePermanentBoolParameter( 'isChargeInputHintDisplayed' );
			}
			if( isRangedDodgeInputHintDisplayed && !( canDisplayRangedDodgeInputHint ) )
			{
				RemoveInputHint( scriptInterface, 'Dodge', 'Ranged' );
				stateContext.RemovePermanentBoolParameter( 'isRangedInputHintDisplayed' );
			}
			if( isCrouchInputHintDisplayed && !( canDisplayCrouchInputHint ) )
			{
				RemoveInputHint( scriptInterface, 'ToggleCrouch', 'Ranged' );
				stateContext.RemovePermanentBoolParameter( 'isCrouchInputHintDisplayed' );
			}
			if( ( ( ( ( ( !( isRangedInputHintDisplayed ) || m_hasControllerChanged ) || m_hasControllerSchemeChanged ) || ( !( isChargeInputHintDisplayed ) && canDisplayChargeInputHint ) ) || ( !( isRangedDodgeInputHintDisplayed ) && canDisplayRangedDodgeInputHint ) ) || ( !( isCrouchInputHintDisplayed ) && canDisplayCrouchInputHint ) ) || ( !( isThrowCarriedNPCInputHintDisplayed ) && canDisplayThrowCarriedNPCInputHint ) )
			{
				if( stateContext.GetBoolParameter( 'isBodyCarryInputHintDisplayed', true ) )
				{
					return ActiveBaseContext.BodyCarringWithRangedWeapon;
				}
				else
				{
					return ActiveBaseContext.RangedWeapon;
				}
			}
		}
		else if( isRangedInputHintDisplayed && ( ( ( ( !( isRangedWeaponEquipped ) || rightHandWeapon.GetCurrentTriggerMode().Type() == gamedataTriggerMode.Charge != isChargeInputHintDisplayed ) || !( isExploring ) ) || isExaminingDevice ) || isDeviceControlled ) )
		{
			RemoveRangedInputHints( stateContext, scriptInterface );
		}
		return context;
	}

	protected function ConsumeControllerChange( stateContext : StateContext, scriptInterface : StateGameScriptInterface ) : Bool
	{
		var isKBMInputDevice : Bool;
		isKBMInputDevice = scriptInterface.executionOwner.PlayerLastUsedKBM();
		if( stateContext.GetBoolParameter( 'isKBMInputDevice', true ) && !( isKBMInputDevice ) )
		{
			stateContext.SetPermanentBoolParameter( 'isKBMInputDevice', false, true );
			return true;
		}
		if( !( stateContext.GetBoolParameter( 'isKBMInputDevice', true ) ) && isKBMInputDevice )
		{
			stateContext.SetPermanentBoolParameter( 'isKBMInputDevice', true, true );
			return true;
		}
		return false;
	}

	protected function ConsumeInputSchemeChange() : Bool
	{
		var oldValue : Bool;
		oldValue = m_onInputSchemeChanged;
		m_onInputSchemeChanged = false;
		return oldValue;
	}

}

class InitialStateDecisions extends InputContextTransitionDecisions
{

	protected export const function ToUiContext( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var player : weak< PlayerPuppet >;
		var expectedRecordID : TweakDBID;
		var recordID : TweakDBID;
		player = ( ( PlayerPuppet )( scriptInterface.executionOwner ) );
		if( player )
		{
			expectedRecordID = T"Character.Player_Puppet_Menu";
			recordID = player.GetRecordID();
			if( recordID == expectedRecordID )
			{
				return true;
			}
		}
		return false;
	}

}

class DeviceControlContextDecisions extends InputContextTransitionDecisions
{
	private var m_callbackID : CallbackHandle;

	protected export function OnAttach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		var allBlackboardDef : AllBlackboardDefinitions;
		if( scriptInterface.localBlackboard )
		{
			allBlackboardDef = GetAllBlackboardDefs();
			m_callbackID = scriptInterface.localBlackboard.RegisterListenerBool( allBlackboardDef.PlayerStateMachine.IsControllingDevice, this, 'OnControllingDeviceChange' );
			EnableOnEnterCondition( scriptInterface.localBlackboard.GetBool( allBlackboardDef.PlayerStateMachine.IsControllingDevice ) );
		}
	}

	protected export function OnDetach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		m_callbackID = NULL;
	}

	protected event OnControllingDeviceChange( value : Bool )
	{
		EnableOnEnterCondition( value );
	}

	protected export const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		return !( GetUIBlackboard( scriptInterface ).GetBool( GetAllBlackboardDefs().UI_QuickSlotsData.UIRadialContextRequest ) );
	}

}

class DeviceControlContextEvents extends InputContextTransitionEvents
{

	protected export virtual function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		RemoveAllInputHints( stateContext, scriptInterface );
	}

}

class BraindanceContextDecisions extends InputContextTransitionDecisions
{

	protected export const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		if( IsPlayerInBraindance( scriptInterface ) )
		{
			return true;
		}
		return false;
	}

}

class DeadContextDecisions extends InputContextTransitionDecisions
{
	private var m_callbackID : CallbackHandle;

	protected export function OnAttach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		var allBlackboardDef : AllBlackboardDefinitions;
		if( scriptInterface.localBlackboard )
		{
			allBlackboardDef = GetAllBlackboardDefs();
			m_callbackID = scriptInterface.localBlackboard.RegisterListenerInt( allBlackboardDef.PlayerStateMachine.Vitals, this, 'OnVitalsChanged' );
			OnVitalsChanged( scriptInterface.localBlackboard.GetInt( allBlackboardDef.PlayerStateMachine.Vitals ) );
		}
	}

	protected export function OnDetach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		m_callbackID = NULL;
	}

	protected event OnVitalsChanged( value : Int32 )
	{
		EnableOnEnterCondition( value == ( ( Int32 )( gamePSMVitals.Dead ) ) );
	}

	protected export const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		return true;
	}

}

class BaseContextDecisions extends InputContextTransitionDecisions
{

	protected export const function ToVehicleRemoteControlDriverContext( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var isVehicleRemoteControlled : Bool;
		isVehicleRemoteControlled = IsVehicleRemoteControlled( scriptInterface );
		if( isVehicleRemoteControlled )
		{
			return true;
		}
		return false;
	}

}

class BaseContextEvents extends InputContextTransitionEvents
{

	protected export function OnUpdate( timeDelta : Float, stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( m_gameplaySettings.GetIsInputHintEnabled() && m_isGameplayInputHintManagerInitialized )
		{
			UpdateHints( stateContext, scriptInterface );
		}
	}

	private function UpdateHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		var context : ActiveBaseContext;
		var contextTemp : ActiveBaseContext;
		if( ShouldForceRefreshInputHints( stateContext ) )
		{
			RemoveGenericExplorationInputHints( stateContext, scriptInterface );
			RemoveLadderInputHints( stateContext, scriptInterface );
			RemoveSwimmingInputHints( stateContext, scriptInterface );
			RemoveBodyCarryInputHints( stateContext, scriptInterface );
			RemoveMeleeInputHints( stateContext, scriptInterface );
			RemoveRangedInputHints( stateContext, scriptInterface );
			m_isGameplayInputHintRefreshRequired = false;
		}
		m_hasControllerChanged = ConsumeControllerChange( stateContext, scriptInterface );
		m_hasControllerSchemeChanged = ConsumeInputSchemeChange();
		context = UpdateLocomotionInputHints( stateContext, scriptInterface );
		if( context == ActiveBaseContext.None )
		{
			context = UpdateLadderInputHints( stateContext, scriptInterface );
		}
		if( context == ActiveBaseContext.None )
		{
			context = UpdateSwimmingInputHints( stateContext, scriptInterface );
		}
		if( context == ActiveBaseContext.None )
		{
			context = UpdateBodyCarryInputHints( stateContext, scriptInterface );
		}
		if( context == ActiveBaseContext.None || context == ActiveBaseContext.BodyCarring )
		{
			contextTemp = UpdateWeaponInputHints( stateContext, scriptInterface );
			context = ( ( contextTemp != ActiveBaseContext.None ) ? ( contextTemp ) : ( context ) );
		}
		SetBaseContextInputHints( context, stateContext, scriptInterface );
	}

	protected function UpdateLocomotionInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface ) : ActiveBaseContext
	{
		var isValidState : Bool;
		isValidState = IsStateValidForExploration( stateContext, scriptInterface );
		if( isValidState )
		{
			if( ( !( stateContext.GetBoolParameter( 'isLocomotionInputHintDisplayed', true ) ) || m_hasControllerChanged ) || m_hasControllerSchemeChanged )
			{
				return ActiveBaseContext.Locomotion;
			}
		}
		else if( !( isValidState ) && stateContext.GetBoolParameter( 'isLocomotionInputHintDisplayed', true ) )
		{
			RemoveGenericExplorationInputHints( stateContext, scriptInterface );
		}
		return ActiveBaseContext.None;
	}

	protected function UpdateBodyCarryInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface ) : ActiveBaseContext
	{
		var psmBodyCarrying : gamePSMBodyCarrying;
		var isCarryingBody : Bool;
		var isBodyCarryInputHintDisplayed : Bool;
		var isThrowCarriedNPCInputHintDisplayed : Bool;
		var canDisplayThrowCarriedNPCInputHint : Bool;
		psmBodyCarrying = ( ( gamePSMBodyCarrying )( scriptInterface.localBlackboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.BodyCarrying ) ) );
		isCarryingBody = psmBodyCarrying == gamePSMBodyCarrying.Carry || psmBodyCarrying == gamePSMBodyCarrying.Aim;
		isBodyCarryInputHintDisplayed = stateContext.GetBoolParameter( 'isBodyCarryInputHintDisplayed', true );
		isThrowCarriedNPCInputHintDisplayed = stateContext.GetBoolParameter( 'isThrowCarriedNPCInputHintDisplayed', true );
		canDisplayThrowCarriedNPCInputHint = scriptInterface.localBlackboard.GetBool( GetAllBlackboardDefs().PlayerStateMachine.CanThrowCarriedNPC );
		if( isCarryingBody && !( AreChoiceHubsActive( scriptInterface ) ) )
		{
			if( isThrowCarriedNPCInputHintDisplayed && !( canDisplayThrowCarriedNPCInputHint ) )
			{
				RemoveInputHint( scriptInterface, 'ThrowNPC', 'BodyCarry' );
				stateContext.RemovePermanentBoolParameter( 'isThrowCarriedNPCInputHintDisplayed' );
			}
			if( !( isBodyCarryInputHintDisplayed ) || ( !( isThrowCarriedNPCInputHintDisplayed ) && canDisplayThrowCarriedNPCInputHint ) )
			{
				return ActiveBaseContext.BodyCarring;
			}
		}
		else
		{
			if( isBodyCarryInputHintDisplayed )
			{
				RemoveBodyCarryInputHints( stateContext, scriptInterface );
			}
		}
		return ActiveBaseContext.None;
	}

	protected function UpdateLadderInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface ) : ActiveBaseContext
	{
		var locomotionStateName : CName;
		locomotionStateName = GetLocomotionState( stateContext );
		if( ( locomotionStateName == 'ladder' || locomotionStateName == 'ladderSprint' ) || locomotionStateName == 'ladderSlide' )
		{
			if( !( stateContext.GetBoolParameter( 'isLadderInputHintDisplayed', true ) ) )
			{
				return ActiveBaseContext.Ladder;
			}
		}
		else
		{
			if( stateContext.GetBoolParameter( 'isLadderInputHintDisplayed', true ) )
			{
				RemoveLadderInputHints( stateContext, scriptInterface );
			}
		}
		return ActiveBaseContext.None;
	}

	protected function UpdateSwimmingInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface ) : ActiveBaseContext
	{
		var isSwimming : Bool;
		isSwimming = stateContext.IsStateMachineActive( 'LocomotionSwimming' );
		if( isSwimming )
		{
			if( !( stateContext.GetBoolParameter( 'isSwimmingInputHintDisplayed', true ) ) )
			{
				return ActiveBaseContext.Swimming;
			}
		}
		else
		{
			if( stateContext.GetBoolParameter( 'isSwimmingInputHintDisplayed', true ) )
			{
				RemoveSwimmingInputHints( stateContext, scriptInterface );
			}
		}
		return ActiveBaseContext.None;
	}

	protected export virtual function OnExit( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		UpdateHints( stateContext, scriptInterface );
	}

	private function IsStateValidForExploration( stateContext : StateContext, scriptInterface : StateGameScriptInterface ) : Bool
	{
		var locomotionState : CName;
		if( stateContext.GetStateMachineCurrentState( 'HighLevel' ) != 'exploration' )
		{
			return false;
		}
		locomotionState = stateContext.GetStateMachineCurrentState( 'Locomotion' );
		if( ( locomotionState == 'ladder' || locomotionState == 'ladderSprint' ) || locomotionState == 'ladderSlide' )
		{
			return false;
		}
		if( locomotionState == 'climb' )
		{
			return false;
		}
		if( scriptInterface.IsPlayerInBraindance() )
		{
			return false;
		}
		if( stateContext.IsStateMachineActive( 'CarriedObject' ) )
		{
			return false;
		}
		if( scriptInterface.localBlackboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.Vehicle ) != ( ( Int32 )( gamePSMVehicle.Default ) ) )
		{
			return false;
		}
		if( HasRightWeaponEquipped( scriptInterface ) )
		{
			return false;
		}
		if( scriptInterface.GetWorkspotSystem().IsActorInWorkspot( scriptInterface.executionOwner ) )
		{
			return false;
		}
		if( ( ( ( locomotionState == 'veryHardLand' || scriptInterface.localBlackboard.GetBool( GetAllBlackboardDefs().PlayerStateMachine.IsPlayerInsideMovingElevator ) ) || StatusEffectSystem.ObjectHasStatusEffectWithTag( scriptInterface.executionOwner, 'NoMovement' ) ) || StatusEffectSystem.ObjectHasStatusEffectOfType( scriptInterface.executionOwner, gamedataStatusEffectType.Stunned ) ) || StatusEffectSystem.ObjectHasStatusEffectOfType( scriptInterface.executionOwner, gamedataStatusEffectType.Knockdown ) )
		{
			return false;
		}
		if( scriptInterface.executionOwner.GetTakeOverControlSystem().IsDeviceControlled() )
		{
			return false;
		}
		if( IsExaminingDevice( scriptInterface ) || IsInteractingWithTerminal( scriptInterface ) )
		{
			return false;
		}
		return true;
	}

}

class AimingContextDecisions extends InputContextTransitionDecisions
{
	private var m_leftHandChargeCallbackID : CallbackHandle;
	private var m_upperBodyCallbackID : CallbackHandle;
	private var m_meleeCallbackID : CallbackHandle;
	private var m_leftHandCharge : Bool;
	private var m_isAiming : Bool;
	private var m_meleeBlockActive : Bool;

	protected function UpdateNeedsToBeChecked()
	{
		EnableOnEnterCondition( ( m_leftHandCharge || m_isAiming ) || m_meleeBlockActive );
	}

	protected export function OnAttach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		var allBlackboardDef : AllBlackboardDefinitions;
		if( scriptInterface.localBlackboard )
		{
			allBlackboardDef = GetAllBlackboardDefs();
			m_leftHandChargeCallbackID = scriptInterface.localBlackboard.RegisterListenerInt( allBlackboardDef.PlayerStateMachine.LeftHandCyberware, this, 'OnLeftHandCyberwareChanged' );
			m_upperBodyCallbackID = scriptInterface.localBlackboard.RegisterListenerInt( allBlackboardDef.PlayerStateMachine.UpperBody, this, 'OnUpperBodyChanged' );
			m_meleeCallbackID = scriptInterface.localBlackboard.RegisterListenerInt( allBlackboardDef.PlayerStateMachine.Melee, this, 'OnMeleeChanged' );
			UpdateLeftHandCyberware( scriptInterface.localBlackboard.GetInt( allBlackboardDef.PlayerStateMachine.LeftHandCyberware ) );
			UpdateUpperBodyState( scriptInterface.localBlackboard.GetInt( allBlackboardDef.PlayerStateMachine.UpperBody ) );
			UpdateMeleeState( scriptInterface.localBlackboard.GetInt( allBlackboardDef.PlayerStateMachine.Melee ) );
			UpdateNeedsToBeChecked();
		}
	}

	protected export function OnDetach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		m_leftHandChargeCallbackID = NULL;
		m_upperBodyCallbackID = NULL;
		m_meleeCallbackID = NULL;
	}

	protected function UpdateLeftHandCyberware( value : Int32 )
	{
		m_leftHandCharge = value == ( ( Int32 )( gamePSMLeftHandCyberware.Charge ) );
	}

	protected event OnLeftHandCyberwareChanged( value : Int32 )
	{
		UpdateLeftHandCyberware( value );
		UpdateNeedsToBeChecked();
	}

	protected function UpdateUpperBodyState( value : Int32 )
	{
		m_isAiming = value == ( ( Int32 )( gamePSMUpperBodyStates.Aim ) );
	}

	protected event OnUpperBodyChanged( value : Int32 )
	{
		UpdateUpperBodyState( value );
		UpdateNeedsToBeChecked();
	}

	protected function UpdateMeleeState( value : Int32 )
	{
		m_meleeBlockActive = value == ( ( Int32 )( gamePSMMelee.Block ) );
	}

	protected event OnMeleeChanged( value : Int32 )
	{
		UpdateMeleeState( value );
		UpdateNeedsToBeChecked();
	}

	protected export const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		return true;
	}

}

class AimingContextEvents extends InputContextTransitionEvents
{

	protected export function OnUpdate( timeDelta : Float, stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		var context : ActiveBaseContext;
		m_hasControllerChanged = ConsumeControllerChange( stateContext, scriptInterface );
		m_hasControllerSchemeChanged = ConsumeInputSchemeChange();
		if( m_gameplaySettings.GetIsInputHintEnabled() && m_isGameplayInputHintManagerInitialized )
		{
			context = UpdateWeaponInputHints( stateContext, scriptInterface );
			SetBaseContextInputHints( context, stateContext, scriptInterface );
		}
	}

}

class VisionContextDecisions extends InputContextTransitionDecisions
{
	private var m_vehicleCallbackID : CallbackHandle;
	private var m_focusCallbackID : CallbackHandle;
	private var m_vehicleTransition : Bool;
	private var m_isFocusing : Bool;
	private var m_visionHoldPressed : Bool;

	protected function UpdateNeedsToBeChecked()
	{
		if( m_vehicleTransition )
		{
			EnableOnEnterCondition( false );
		}
		EnableOnEnterCondition( m_visionHoldPressed || m_isFocusing );
	}

	protected export function OnAttach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		var allBlackboardDef : AllBlackboardDefinitions;
		if( scriptInterface.localBlackboard )
		{
			allBlackboardDef = GetAllBlackboardDefs();
			m_vehicleCallbackID = scriptInterface.localBlackboard.RegisterListenerInt( allBlackboardDef.PlayerStateMachine.Vehicle, this, 'OnVehicleStateChanged' );
			m_focusCallbackID = scriptInterface.localBlackboard.RegisterListenerInt( allBlackboardDef.PlayerStateMachine.Vision, this, 'OnVisionChanged' );
			UpdateVehicleStateValue( scriptInterface.localBlackboard.GetInt( allBlackboardDef.PlayerStateMachine.Vehicle ) );
			UpdateVisionValue( scriptInterface.localBlackboard.GetInt( allBlackboardDef.PlayerStateMachine.Vision ) );
		}
		scriptInterface.executionOwner.RegisterInputListener( this, 'VisionHold' );
		UpdateVisionAction( scriptInterface.GetActionValue( 'VisionHold' ) );
		UpdateNeedsToBeChecked();
	}

	protected export function OnDetach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		m_vehicleCallbackID = NULL;
		m_focusCallbackID = NULL;
		scriptInterface.executionOwner.UnregisterInputListener( this );
	}

	protected function UpdateVisionAction( value : Float )
	{
		m_visionHoldPressed = value > 0.0;
	}

	protected event OnAction( action : ListenerAction, consumer : ListenerActionConsumer )
	{
		if( ListenerAction.GetName( action ) == 'VisionHold' )
		{
			UpdateVisionAction( ListenerAction.GetValue( action ) );
			UpdateNeedsToBeChecked();
		}
	}

	protected function UpdateVehicleStateValue( value : Int32 )
	{
		m_vehicleTransition = value == ( ( Int32 )( gamePSMVehicle.Transition ) );
	}

	protected event OnVehicleStateChanged( value : Int32 )
	{
		UpdateVehicleStateValue( value );
		UpdateNeedsToBeChecked();
	}

	protected function UpdateVisionValue( value : Int32 )
	{
		m_isFocusing = value == ( ( Int32 )( gamePSMVision.Focus ) );
	}

	protected event OnVisionChanged( value : Int32 )
	{
		UpdateVisionValue( value );
		UpdateNeedsToBeChecked();
	}

	protected export const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var vehicleID : EntityID;
		vehicleID = scriptInterface.localBlackboard.GetEntityID( GetAllBlackboardDefs().PlayerStateMachine.EntityIDVehicleRemoteControlled );
		if( EntityID.IsDefined( vehicleID ) )
		{
			return false;
		}
		if( m_isFocusing )
		{
			return true;
		}
		if( m_visionHoldPressed && !( stateContext.GetBoolParameter( 'lockHoldInput', true ) ) )
		{
			return true;
		}
		return false;
	}

}

class UiContextDecisions extends InputContextTransitionDecisions
{

	protected export const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var psmResult : StateResultBool;
		psmResult = stateContext.GetTemporaryBoolParameter( 'OnUIContextActive' );
		return psmResult.value;
	}

	protected const override function ExitCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var psmResult : StateResultBool;
		psmResult = stateContext.GetTemporaryBoolParameter( 'OnUIContextInactive' );
		return psmResult.value;
	}

}

class UiRadialContextDecisions extends InputContextTransitionDecisions
{

	protected export const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var psmResult : StateResultBool;
		psmResult = stateContext.GetTemporaryBoolParameter( 'OnUIRadialContextActive' );
		return psmResult.value;
	}

	protected const override function ExitCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var psmResult : StateResultBool;
		psmResult = stateContext.GetTemporaryBoolParameter( 'OnUIRadialContextInactive' );
		return psmResult.value;
	}

}

class UiRadialContextEvents extends InputContextTransitionEvents
{
	var m_mouse : Vector4;

	protected function OnUpdate( timeDelta : Float, stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		var leftStick : Vector4;
		leftStick.X = scriptInterface.GetActionValue( 'UI_LookX_Axis' );
		leftStick.Y = scriptInterface.GetActionValue( 'UI_LookY_Axis' );
		if( Vector4.Length( leftStick ) <= 0.40000001 )
		{
			leftStick = Vector4.EmptyVector();
			m_mouse.X += ( scriptInterface.GetActionValue( 'mouse_x' ) * MaxF( timeDelta, 0.005 ) );
			m_mouse.Y += ( scriptInterface.GetActionValue( 'mouse_y' ) * MaxF( timeDelta, 0.005 ) );
			m_mouse.X = ClampF( m_mouse.X, -1.0, 1.0 );
			m_mouse.Y = ClampF( m_mouse.Y, -1.0, 1.0 );
			if( Vector4.Length( m_mouse ) <= 0.40000001 )
			{
				leftStick = Vector4.EmptyVector();
			}
			else
			{
				leftStick = Vector4.Normalize( m_mouse );
			}
		}
		SetUIBlackboardVector4Variable( scriptInterface, GetAllBlackboardDefs().UI_QuickSlotsData.leftStick, leftStick );
	}

	protected function SetUIBlackboardVector4Variable( scriptInterface : StateGameScriptInterface, id : BlackboardID_Vector4, value : Vector4 )
	{
		var blackboardSystem : BlackboardSystem;
		var blackboard : IBlackboard;
		blackboardSystem = scriptInterface.GetBlackboardSystem();
		blackboard = blackboardSystem.Get( GetAllBlackboardDefs().UI_QuickSlotsData );
		blackboard.SetVector4( id, value );
	}

}

class UiQuickHackPanelContextDecisions extends InputContextTransitionDecisions
{

	protected export const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		if( IsQuickHackPanelOpened( scriptInterface ) && CheckRequiredStates( scriptInterface ) )
		{
			return true;
		}
		return false;
	}

	protected const virtual function CheckRequiredStates( scriptInterface : StateGameScriptInterface ) : Bool
	{
		var currentState : Int32;
		var vehicleID : EntityID;
		var isDeviceControlled : Bool;
		currentState = scriptInterface.localBlackboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.Vehicle );
		vehicleID = scriptInterface.localBlackboard.GetEntityID( GetAllBlackboardDefs().PlayerStateMachine.EntityIDVehicleRemoteControlled );
		isDeviceControlled = scriptInterface.executionOwner.GetTakeOverControlSystem().IsDeviceControlled();
		return !( EntityID.IsDefined( vehicleID ) ) && ( isDeviceControlled || ( ( currentState != ( ( Int32 )( gamePSMVehicle.Driving ) ) ) && ( currentState != ( ( Int32 )( gamePSMVehicle.DriverCombat ) ) ) ) );
	}

}

class UiQuickHackPanelContextEvents extends InputContextTransitionEvents
{

	protected export virtual function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		RemoveAllInputHints( stateContext, scriptInterface );
	}

	protected function SetChangeTargetTooltipVisibility( scriptInterface : StateGameScriptInterface, value : Bool )
	{
		var uiScannerBlackboard : weak< IBlackboard >;
		uiScannerBlackboard = GameInstance.GetBlackboardSystem( scriptInterface.owner.GetGame() ).Get( GetAllBlackboardDefs().UI_Scanner );
		uiScannerBlackboard.SetBool( GetAllBlackboardDefs().UI_Scanner.scannerChangeTargetTooltipVisibility, value );
	}

}

class UiQuickHackPanelContextDrivingDecisions extends UiQuickHackPanelContextDecisions
{

	protected const override function CheckRequiredStates( scriptInterface : StateGameScriptInterface ) : Bool
	{
		var currentState : Int32;
		var isDeviceControlled : Bool;
		currentState = scriptInterface.localBlackboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.Vehicle );
		isDeviceControlled = scriptInterface.executionOwner.GetTakeOverControlSystem().IsDeviceControlled();
		return !( isDeviceControlled ) && ( currentState == ( ( Int32 )( gamePSMVehicle.Driving ) ) );
	}

}

class UiQuickHackPanelContextDrivingEvents extends UiQuickHackPanelContextEvents
{

	protected override function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		super.OnEnter( stateContext, scriptInterface );
		SetChangeTargetTooltipVisibility( scriptInterface, false );
	}

	protected export virtual function OnExit( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		SetChangeTargetTooltipVisibility( scriptInterface, true );
	}

}

class UiQuickHackPanelContextDriverCombatDecisions extends UiQuickHackPanelContextDecisions
{

	protected const override function CheckRequiredStates( scriptInterface : StateGameScriptInterface ) : Bool
	{
		var currentState : Int32;
		var isDeviceControlled : Bool;
		currentState = scriptInterface.localBlackboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.Vehicle );
		isDeviceControlled = scriptInterface.executionOwner.GetTakeOverControlSystem().IsDeviceControlled();
		return !( isDeviceControlled ) && ( currentState == ( ( Int32 )( gamePSMVehicle.DriverCombat ) ) );
	}

}

class UiQuickHackPanelContextDriverCombatEvents extends UiQuickHackPanelContextEvents
{

	protected override function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		super.OnEnter( stateContext, scriptInterface );
		SetChangeTargetTooltipVisibility( scriptInterface, false );
	}

	protected export virtual function OnExit( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		SetChangeTargetTooltipVisibility( scriptInterface, true );
	}

}

class UiQuickHackPanelContextRemoteControlDecisions extends UiQuickHackPanelContextDecisions
{

	protected const override function CheckRequiredStates( scriptInterface : StateGameScriptInterface ) : Bool
	{
		var vehicleID : EntityID;
		vehicleID = scriptInterface.localBlackboard.GetEntityID( GetAllBlackboardDefs().PlayerStateMachine.EntityIDVehicleRemoteControlled );
		return EntityID.IsDefined( vehicleID );
	}

}

class UiQuickHackPanelContextRemoteControlEvents extends UiQuickHackPanelContextEvents
{

	protected override function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		super.OnEnter( stateContext, scriptInterface );
	}

}

class UiVendorContextDecisions extends InputContextTransitionDecisions
{

	protected export const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var psmResult : StateResultBool;
		psmResult = stateContext.GetTemporaryBoolParameter( 'OnUIVendorContextActive' );
		return psmResult.value;
	}

	protected const override function ExitCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var vendorInactive : StateResultBool;
		vendorInactive = stateContext.GetTemporaryBoolParameter( 'OnUIVendorContextInactive' );
		return vendorInactive.value;
	}

}

class UiPhoneContextDecisions extends InputContextTransitionDecisions
{

	protected export const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var psmContactListResult, psmSmsMessengerResult : StateResultBool;
		psmContactListResult = stateContext.GetTemporaryBoolParameter( 'OnUIContactListContextActive' );
		psmSmsMessengerResult = stateContext.GetTemporaryBoolParameter( 'OnUISmsMessengerContextActive' );
		return psmContactListResult.value || psmSmsMessengerResult.value;
	}

	protected const override function ExitCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var psmContactListResult, psmSmsMessengerResult : StateResultBool;
		psmContactListResult = stateContext.GetTemporaryBoolParameter( 'OnUIContactListContextInactive' );
		psmSmsMessengerResult = stateContext.GetTemporaryBoolParameter( 'OnUISmsMessengerContextInactive' );
		return psmContactListResult.value || psmSmsMessengerResult.value;
	}

}

class LadderEnterContextEvents extends InputContextTransitionEvents
{
}

class LadderEnterContextDecisions extends InputContextTransitionDecisions
{

	protected export const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var ladderEntryDuration : StateResultFloat;
		ladderEntryDuration = stateContext.GetPermanentFloatParameter( 'ladderEntryDuration' );
		if( !( ladderEntryDuration.valid ) )
		{
			return false;
		}
		return true;
	}

}

class VehicleBlockInputContextEvents extends InputContextTransitionEvents
{

	protected export virtual function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		RemoveAllInputHints( stateContext, scriptInterface );
	}

}

class VehicleBlockInputContextDecisions extends InputContextTransitionDecisions
{
	private var m_callbackID : CallbackHandle;

	protected export function OnAttach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		var allBlackboardDef : AllBlackboardDefinitions;
		if( scriptInterface.localBlackboard )
		{
			allBlackboardDef = GetAllBlackboardDefs();
			m_callbackID = scriptInterface.localBlackboard.RegisterListenerInt( allBlackboardDef.PlayerStateMachine.Vehicle, this, 'OnVehicleStateChanged' );
			OnVehicleStateChanged( scriptInterface.localBlackboard.GetInt( allBlackboardDef.PlayerStateMachine.Vehicle ) );
		}
	}

	protected export function OnDetach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		m_callbackID = NULL;
	}

	protected event OnVehicleStateChanged( value : Int32 )
	{
		EnableOnEnterCondition( value == ( ( Int32 )( gamePSMVehicle.Transition ) ) );
	}

	protected export const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		return true;
	}

}

class VehicleGameplayContextDecisions extends InputContextTransitionDecisions
{
	private var m_callbackID : CallbackHandle;

	protected export function OnAttach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		var allBlackboardDef : AllBlackboardDefinitions;
		if( scriptInterface.localBlackboard )
		{
			allBlackboardDef = GetAllBlackboardDefs();
			m_callbackID = scriptInterface.localBlackboard.RegisterListenerInt( allBlackboardDef.PlayerStateMachine.Vehicle, this, 'OnVehicleStateChanged' );
			OnVehicleStateChanged( scriptInterface.localBlackboard.GetInt( allBlackboardDef.PlayerStateMachine.Vehicle ) );
		}
	}

	protected export function OnDetach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		m_callbackID = NULL;
	}

	protected event OnVehicleStateChanged( value : Int32 )
	{
		EnableOnEnterCondition( value != ( ( Int32 )( gamePSMVehicle.Default ) ) );
	}

	protected export const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		return true;
	}

}

class VehiclePassengerContextEvents extends InputContextTransitionEvents
{

	protected export function OnUpdate( timeDelta : Float, stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( m_gameplaySettings.GetIsInputHintEnabled() && m_isGameplayInputHintManagerInitialized )
		{
			UpdatePassengerInputHints( stateContext, scriptInterface );
		}
	}

	protected function UpdatePassengerInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		var currentState : Int32;
		currentState = scriptInterface.localBlackboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.Vehicle );
		if( ShouldForceRefreshInputHints( stateContext ) )
		{
			RemoveVehiclePassengerInputHints( stateContext, scriptInterface );
			m_isGameplayInputHintRefreshRequired = false;
		}
		if( stateContext.GetBoolParameter( 'doNotDisplayPassengerInputHint', true ) || StatusEffectSystem.ObjectHasStatusEffect( scriptInterface.executionOwner, T"GameplayRestriction.VehicleCombatNoInterruptions" ) )
		{
			if( stateContext.GetBoolParameter( 'isPassengerInputHintDisplayed', true ) )
			{
				RemoveVehiclePassengerInputHints( stateContext, scriptInterface );
			}
			return;
		}
		if( ( ( currentState != ( ( Int32 )( gamePSMVehicle.Scene ) ) ) && !( stateContext.GetBoolParameter( 'isPassengerInputHintDisplayed', true ) ) ) && !( StatusEffectSystem.ObjectHasStatusEffect( scriptInterface.executionOwner, T"GameplayRestriction.VehicleCombatNoInterruptions" ) ) )
		{
			ShowVehiclePassengerInputHints( stateContext, scriptInterface );
		}
		else if( ( currentState == ( ( Int32 )( gamePSMVehicle.Scene ) ) ) && stateContext.GetBoolParameter( 'isPassengerInputHintDisplayed', true ) )
		{
			RemoveVehiclePassengerInputHints( stateContext, scriptInterface );
		}
	}

	protected export virtual function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		var vehicle : weak< GameObject >;
		VehicleComponent.GetVehicle( scriptInterface.owner.GetGame(), scriptInterface.executionOwner, vehicle );
		if( vehicle = ( ( AVObject )( vehicle ) ) )
		{
			stateContext.SetPermanentBoolParameter( 'doNotDisplayPassengerInputHint', true, true );
		}
		ShowVehiclePassengerInputHints( stateContext, scriptInterface );
	}

	protected export virtual function OnExit( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		RemoveVehiclePassengerInputHints( stateContext, scriptInterface );
		stateContext.RemovePermanentBoolParameter( 'doNotDisplayPassengerInputHint' );
	}

}

class VehiclePassengerContextDecisions extends VehicleGameplayContextDecisions
{

	protected export const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var isVehicleRemoteControlled : Bool;
		isVehicleRemoteControlled = IsVehicleRemoteControlled( scriptInterface );
		if( isVehicleRemoteControlled )
		{
			return false;
		}
		return true;
	}

	protected export const override function ExitCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var currentState : Int32;
		var isVehicleRemoteControlled : Bool;
		currentState = scriptInterface.localBlackboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.Vehicle );
		isVehicleRemoteControlled = IsVehicleRemoteControlled( scriptInterface );
		if( currentState == ( ( Int32 )( gamePSMVehicle.Default ) ) )
		{
			return true;
		}
		if( ( currentState != ( ( Int32 )( gamePSMVehicle.Scene ) ) ) && ( currentState != ( ( Int32 )( gamePSMVehicle.Passenger ) ) ) )
		{
			return true;
		}
		if( isVehicleRemoteControlled )
		{
			return true;
		}
		return false;
	}

}

class VehiclePassengerRemoteControlDriverContextEvents extends VehiclePassengerContextEvents
{
}

class VehiclePassengerRemoteControlDriverContextDecisions extends VehicleGameplayContextDecisions
{

	protected export const function ToVehiclePassengerContext( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var currentState : Int32;
		var isVehicleRemoteControlled : Bool;
		currentState = scriptInterface.localBlackboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.Vehicle );
		isVehicleRemoteControlled = IsVehicleRemoteControlled( scriptInterface );
		if( isVehicleRemoteControlled )
		{
			return false;
		}
		if( currentState == ( ( Int32 )( gamePSMVehicle.Passenger ) ) )
		{
			return true;
		}
		return false;
	}

	protected export const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var currentState : Int32;
		var isVehicleRemoteControlled : Bool;
		currentState = scriptInterface.localBlackboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.Vehicle );
		isVehicleRemoteControlled = IsVehicleRemoteControlled( scriptInterface );
		if( ( ( currentState == ( ( Int32 )( gamePSMVehicle.Scene ) ) ) || ( currentState == ( ( Int32 )( gamePSMVehicle.Passenger ) ) ) ) && isVehicleRemoteControlled )
		{
			return true;
		}
		return false;
	}

	protected export const override function ExitCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var currentState : Int32;
		var isVehicleRemoteControlled : Bool;
		currentState = scriptInterface.localBlackboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.Vehicle );
		isVehicleRemoteControlled = IsVehicleRemoteControlled( scriptInterface );
		if( currentState == ( ( Int32 )( gamePSMVehicle.Default ) ) )
		{
			return true;
		}
		if( ( currentState != ( ( Int32 )( gamePSMVehicle.Scene ) ) ) && ( currentState != ( ( Int32 )( gamePSMVehicle.Passenger ) ) ) )
		{
			return true;
		}
		if( !( isVehicleRemoteControlled ) )
		{
			return true;
		}
		return false;
	}

}

class VehicleRemoteControlDriverContextEvents extends InputContextTransitionEvents
{

	protected export function OnUpdate( timeDelta : Float, stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( scriptInterface.IsActionJustPressed( 'ToggleVehCamera' ) )
		{
			ToggleVehicleRemoteControlCamera( scriptInterface );
		}
		if( scriptInterface.IsActionJustPressed( 'Exit' ) )
		{
			SetVehicleRemoteControlled( scriptInterface, false );
		}
	}

	protected virtual function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		RemoveAllInputHints( stateContext, scriptInterface );
		ShowVehicleRemoteControlDriverInputHints( stateContext, scriptInterface );
		SaveLocksManager.RequestSaveLockAdd( scriptInterface.owner.GetGame(), 'RemoteControl' );
	}

	protected export function OnForcedExit( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		OnCommonExit( stateContext, scriptInterface );
	}

	protected export virtual function OnExit( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		OnCommonExit( stateContext, scriptInterface );
	}

	private function OnCommonExit( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		RemoveVehicleRemoteControlDriverInputHints( stateContext, scriptInterface );
		SaveLocksManager.RequestSaveLockRemove( scriptInterface.owner.GetGame(), 'RemoteControl' );
	}

}

class VehicleRemoteControlDriverContextDecisions extends VehicleGameplayContextDecisions
{

	protected export const override function ToBaseContext( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var isVehicleRemoteControlled : Bool;
		isVehicleRemoteControlled = IsVehicleRemoteControlled( scriptInterface );
		if( isVehicleRemoteControlled )
		{
			return false;
		}
		return true;
	}

}

class VehicleNoDriveContextEvents extends InputContextTransitionEvents
{

	protected virtual function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		RemoveVehicleDriverInputHints( stateContext, scriptInterface );
	}

	protected virtual function OnExit( stateContext : StateContext, scriptInterface : StateGameScriptInterface ) {}
}

class VehicleNoDriveContextDecisions extends InputContextTransitionDecisions
{
	private var m_callbackID : CallbackHandle;

	protected export function OnAttach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		var allBlackboardDef : AllBlackboardDefinitions;
		if( scriptInterface.localBlackboard )
		{
			allBlackboardDef = GetAllBlackboardDefs();
			m_callbackID = scriptInterface.localBlackboard.RegisterListenerInt( allBlackboardDef.PlayerStateMachine.Vehicle, this, 'OnVehicleStateChanged' );
			OnVehicleStateChanged( scriptInterface.localBlackboard.GetInt( allBlackboardDef.PlayerStateMachine.Vehicle ) );
		}
	}

	protected export function OnDetach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		m_callbackID = NULL;
	}

	protected event OnVehicleStateChanged( value : Int32 )
	{
		EnableOnEnterCondition( value == ( ( Int32 )( gamePSMVehicle.Driving ) ) );
	}

	protected export const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		if( StatusEffectSystem.ObjectHasStatusEffectWithTag( scriptInterface.executionOwner, 'NoDriving' ) )
		{
			return true;
		}
		return false;
	}

}

class VehicleQuestRestrictedContextDecisions extends InputContextTransitionDecisions
{

	protected export const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		if( StatusEffectSystem.ObjectHasStatusEffectWithTag( scriptInterface.executionOwner, 'VehicleOnlyForward' ) )
		{
			return true;
		}
		return false;
	}

}

class VehicleQuestRestrictedContextEvents extends VehicleNoDriveContextEvents
{

	protected override function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		ShowVehicleRestrictedInputHints( stateContext, scriptInterface );
		stateContext.SetPermanentBoolParameter( 'inVehicleRestrictState', true, true );
	}

	protected override function OnExit( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		RemoveVehicleRestrictedInputHints( stateContext, scriptInterface );
		stateContext.RemovePermanentBoolParameter( 'inVehicleRestrictState' );
	}

}

class VehicleTankDriverContextDecisions extends InputContextTransitionDecisions
{
	private var m_callbackID : CallbackHandle;

	protected export function OnAttach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		var allBlackboardDef : AllBlackboardDefinitions;
		if( scriptInterface.localBlackboard )
		{
			allBlackboardDef = GetAllBlackboardDefs();
			m_callbackID = scriptInterface.localBlackboard.RegisterListenerInt( allBlackboardDef.PlayerStateMachine.Vehicle, this, 'OnVehicleStateChanged' );
			OnVehicleStateChanged( scriptInterface.localBlackboard.GetInt( allBlackboardDef.PlayerStateMachine.Vehicle ) );
		}
	}

	protected export function OnDetach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		m_callbackID = NULL;
	}

	protected event OnVehicleStateChanged( value : Int32 )
	{
		EnableOnEnterCondition( value == ( ( Int32 )( gamePSMVehicle.Driving ) ) );
	}

	protected export const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var vehicle : weak< GameObject >;
		if( !( VehicleComponent.GetVehicle( scriptInterface.owner.GetGame(), scriptInterface.executionOwner, vehicle ) ) )
		{
			return false;
		}
		if( ( ( TankObject )( vehicle ) ) == NULL )
		{
			return false;
		}
		return true;
	}

}

class VehicleDriverContextEvents extends InputContextTransitionEvents
{

	protected export function OnUpdate( timeDelta : Float, stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( m_gameplaySettings.GetIsInputHintEnabled() && m_isGameplayInputHintManagerInitialized )
		{
			UpdateVehicleDriverInputHints( stateContext, scriptInterface );
		}
	}

	protected function UpdateVehicleDriverInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		var isVehicleCombatModeBlocked : Bool;
		var isExitVehicleBlocked : Bool;
		if( ShouldForceRefreshInputHints( stateContext ) )
		{
			RemoveVehicleDriverInputHints( stateContext, scriptInterface );
			m_isGameplayInputHintRefreshRequired = false;
		}
		if( stateContext.GetBoolParameter( 'isDriverInputHintDisplayed', true ) )
		{
			isVehicleCombatModeBlocked = IsVehicleBlockingCombat( scriptInterface ) || IsEmptyHandsForced( stateContext, scriptInterface );
			isExitVehicleBlocked = IsExitVehicleBlocked( scriptInterface );
			if( isVehicleCombatModeBlocked != stateContext.GetBoolParameter( 'IsVehicleCombatModeBlocked', true ) )
			{
				ShowVehicleDrawWeaponInputHint( stateContext, scriptInterface );
			}
			if( isExitVehicleBlocked != stateContext.GetBoolParameter( 'IsExitVehicleBlocked', true ) )
			{
				ShowVehicleExitInputHint( stateContext, scriptInterface, 'VehicleDriver' );
			}
		}
		else
		{
			ShowVehicleDriverInputHints( stateContext, scriptInterface );
		}
	}

	protected export virtual function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		ShowVehicleDriverInputHints( stateContext, scriptInterface );
	}

	protected export virtual function OnExit( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		RemoveVehicleDriverInputHints( stateContext, scriptInterface );
	}

}

class VehicleDriverContextDecisions extends InputContextTransitionDecisions
{
	private var m_callbackID : CallbackHandle;

	protected export function OnAttach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		var allBlackboardDef : AllBlackboardDefinitions;
		if( scriptInterface.localBlackboard )
		{
			allBlackboardDef = GetAllBlackboardDefs();
			m_callbackID = scriptInterface.localBlackboard.RegisterListenerInt( allBlackboardDef.PlayerStateMachine.Vehicle, this, 'OnVehicleStateChanged' );
			OnVehicleStateChanged( scriptInterface.localBlackboard.GetInt( allBlackboardDef.PlayerStateMachine.Vehicle ) );
		}
	}

	protected export function OnDetach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		m_callbackID = NULL;
	}

	protected event OnVehicleStateChanged( value : Int32 )
	{
		EnableOnEnterCondition( value == ( ( Int32 )( gamePSMVehicle.Driving ) ) );
	}

	protected const virtual function DriverCombatTypeEnterCondition( const stateContext : StateContext ) : Bool
	{
		var driverCombatType : gamedataDriverCombatType;
		driverCombatType = GetDriverCombatType( stateContext );
		return driverCombatType != gamedataDriverCombatType.MountedWeapons;
	}

	protected export const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		if( !( DriverCombatTypeEnterCondition( stateContext ) ) )
		{
			return false;
		}
		if( StatusEffectSystem.ObjectHasStatusEffectWithTag( scriptInterface.executionOwner, 'VehicleOnlyForward' ) )
		{
			return false;
		}
		if( StatusEffectSystem.ObjectHasStatusEffectWithTag( scriptInterface.executionOwner, 'NoDriving' ) )
		{
			return false;
		}
		return true;
	}

}

class VehicleDriverMountedWeaponsContextEvents extends VehicleDriverContextEvents
{
}

class VehicleDriverMountedWeaponsContextDecisions extends VehicleDriverContextDecisions
{

	protected const override function DriverCombatTypeEnterCondition( const stateContext : StateContext ) : Bool
	{
		var driverCombatType : gamedataDriverCombatType;
		driverCombatType = GetDriverCombatType( stateContext );
		return driverCombatType == gamedataDriverCombatType.MountedWeapons;
	}

}

class VehicleDriverCombatContextEvents extends InputContextTransitionEvents
{
	protected var m_weapon : weak< WeaponObject >;

	protected export function OnUpdate( timeDelta : Float, stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		m_hasControllerChanged = ConsumeControllerChange( stateContext, scriptInterface );
		if( m_gameplaySettings.GetIsInputHintEnabled() && m_isGameplayInputHintManagerInitialized )
		{
			UpdateVehicleDriverInputHints( stateContext, scriptInterface );
		}
	}

	protected function UpdateVehicleDriverInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		var weapon : weak< WeaponObject >;
		var isDriverCombatMeleeInputHintDirty : Bool;
		var canDisplayDriverCombatScannerInputHint : Bool;
		weapon = GetActiveWeapon( scriptInterface );
		isDriverCombatMeleeInputHintDirty = m_weapon.IsMelee() != weapon.IsMelee() || m_weapon.IsThrowable() != weapon.IsThrowable();
		m_weapon = weapon;
		if( m_hasControllerChanged || ShouldForceRefreshInputHints( stateContext ) )
		{
			RemoveVehicleDriverCombatInputHintsInternal( stateContext, scriptInterface );
			m_isGameplayInputHintRefreshRequired = false;
		}
		else
		{
			canDisplayDriverCombatScannerInputHint = ( scriptInterface.executionOwner.PlayerLastUsedPad() && EquipmentSystem.IsCyberdeckEquipped( scriptInterface.executionOwner ) ) && !( QuickhackModule.IsQuickhackBlockedByScene( scriptInterface.executionOwner ) );
			if( ( stateContext.GetBoolParameter( 'isDriverCombatInputHintDisplayed', true ) && !( isDriverCombatMeleeInputHintDirty ) ) && stateContext.GetBoolParameter( 'isDriverCombatScannerInputHintDisplayed', true ) == canDisplayDriverCombatScannerInputHint )
			{
				return;
			}
		}
		stateContext.SetPermanentBoolParameter( 'inMeleeDriverCombat', m_weapon.IsMelee(), true );
		UpdateVehicleDriverCombatInputHintsInternal( stateContext, scriptInterface );
	}

	protected virtual function UpdateVehicleDriverCombatInputHintsInternal( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		ShowVehicleDriverCombatInputHints( stateContext, scriptInterface );
	}

	protected virtual function RemoveVehicleDriverCombatInputHintsInternal( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		RemoveVehicleDriverCombatInputHints( stateContext, scriptInterface );
	}

	protected virtual function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		m_weapon = GetActiveWeapon( scriptInterface );
		stateContext.SetPermanentBoolParameter( 'inMeleeDriverCombat', m_weapon.IsMelee(), true );
		if( m_gameplaySettings.GetIsInputHintEnabled() && m_isGameplayInputHintManagerInitialized )
		{
			ShowVehicleDriverCombatInputHints( stateContext, scriptInterface );
		}
	}

	protected virtual function OnExit( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		RemoveVehicleDriverCombatInputHints( stateContext, scriptInterface );
		stateContext.RemovePermanentBoolParameter( 'inMeleeDriverCombat' );
	}

}

class VehicleDriverCombatContextDecisions extends InputContextTransitionDecisions
{
	private var m_callbackID : CallbackHandle;
	private var m_tppCallbackID : CallbackHandle;
	private var m_upperBodyCallbackID : CallbackHandle;
	protected var m_inTpp : Bool;
	protected var m_isAiming : Bool;

	protected export function OnAttach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		var allBlackboardDef : AllBlackboardDefinitions;
		allBlackboardDef = GetAllBlackboardDefs();
		if( scriptInterface.localBlackboard )
		{
			m_callbackID = scriptInterface.localBlackboard.RegisterListenerInt( allBlackboardDef.PlayerStateMachine.Vehicle, this, 'OnVehicleStateChanged', true );
			m_tppCallbackID = scriptInterface.localBlackboard.RegisterListenerBool( allBlackboardDef.PlayerStateMachine.IsDriverCombatInTPP, this, 'OnVehiclePerspectiveChanged', true );
			m_upperBodyCallbackID = scriptInterface.localBlackboard.RegisterListenerInt( allBlackboardDef.PlayerStateMachine.UpperBody, this, 'OnUpperBodyStateChanged', true );
		}
	}

	protected export function OnDetach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		var allBlackboardDef : AllBlackboardDefinitions;
		allBlackboardDef = GetAllBlackboardDefs();
		if( scriptInterface.localBlackboard )
		{
			scriptInterface.localBlackboard.UnregisterListenerInt( allBlackboardDef.PlayerStateMachine.Vehicle, m_callbackID );
			scriptInterface.localBlackboard.UnregisterListenerBool( allBlackboardDef.PlayerStateMachine.IsDriverCombatInTPP, m_tppCallbackID );
			scriptInterface.localBlackboard.UnregisterListenerInt( allBlackboardDef.PlayerStateMachine.UpperBody, m_upperBodyCallbackID );
		}
		m_callbackID = NULL;
		m_tppCallbackID = NULL;
		m_upperBodyCallbackID = NULL;
	}

	protected event OnVehicleStateChanged( value : Int32 )
	{
		EnableOnEnterCondition( value == ( ( Int32 )( gamePSMVehicle.DriverCombat ) ) );
	}

	protected event OnVehiclePerspectiveChanged( value : Bool )
	{
		m_inTpp = value;
	}

	protected event OnUpperBodyStateChanged( value : Int32 )
	{
		m_isAiming = value == ( ( Int32 )( gamePSMUpperBodyStates.Aim ) );
	}

	protected const virtual function CameraPerspectiveEnterCondition() : Bool
	{
		return !( m_inTpp );
	}

	protected const virtual function IsAimingEnterCondition() : Bool
	{
		return !( m_isAiming );
	}

	protected const virtual function DriverCombatTypeEnterCondition( const stateContext : StateContext ) : Bool
	{
		var driverCombatType : gamedataDriverCombatType;
		driverCombatType = GetDriverCombatType( stateContext );
		return driverCombatType == gamedataDriverCombatType.Standard || driverCombatType == gamedataDriverCombatType.Doors;
	}

	protected const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		if( ( !( CameraPerspectiveEnterCondition() ) || !( IsAimingEnterCondition() ) ) || !( DriverCombatTypeEnterCondition( stateContext ) ) )
		{
			return false;
		}
		if( StatusEffectSystem.ObjectHasStatusEffectWithTag( scriptInterface.executionOwner, 'VehicleOnlyForward' ) )
		{
			return false;
		}
		if( StatusEffectSystem.ObjectHasStatusEffectWithTag( scriptInterface.executionOwner, 'NoDriving' ) )
		{
			return false;
		}
		return true;
	}

}

class VehicleDriverCombatTPPContextEvents extends VehicleDriverCombatContextEvents
{

	protected override function UpdateVehicleDriverCombatInputHintsInternal( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		ShowVehicleDriverCombatTPPInputHints( stateContext, scriptInterface );
	}

	protected override function RemoveVehicleDriverCombatInputHintsInternal( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		RemoveVehicleDriverCombatTPPInputHints( stateContext, scriptInterface );
	}

	protected override function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		m_weapon = GetActiveWeapon( scriptInterface );
		stateContext.SetPermanentBoolParameter( 'inMeleeDriverCombat', m_weapon.IsMelee(), true );
		if( m_gameplaySettings.GetIsInputHintEnabled() && m_isGameplayInputHintManagerInitialized )
		{
			ShowVehicleDriverCombatTPPInputHints( stateContext, scriptInterface );
		}
	}

	protected override function OnExit( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		RemoveVehicleDriverCombatTPPInputHints( stateContext, scriptInterface );
		stateContext.RemovePermanentBoolParameter( 'inMeleeDriverCombat' );
	}

}

class VehicleDriverCombatTPPContextDecisions extends VehicleDriverCombatContextDecisions
{

	private const override function CameraPerspectiveEnterCondition() : Bool
	{
		return m_inTpp;
	}

}

class VehicleDriverCombatAimContextEvents extends VehicleDriverCombatContextEvents
{

	protected override function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		m_weapon = GetActiveWeapon( scriptInterface );
		stateContext.SetPermanentBoolParameter( 'inMeleeDriverCombat', m_weapon.IsMelee(), true );
		if( m_gameplaySettings.GetIsInputHintEnabled() && m_isGameplayInputHintManagerInitialized )
		{
			ShowVehicleDriverCombatTPPInputHints( stateContext, scriptInterface );
		}
	}

	protected override function OnExit( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		RemoveVehicleDriverCombatTPPInputHints( stateContext, scriptInterface );
		stateContext.RemovePermanentBoolParameter( 'inMeleeDriverCombat' );
	}

}

class VehicleDriverCombatAimContextDecisions extends VehicleDriverCombatContextDecisions
{

	protected const override function IsAimingEnterCondition() : Bool
	{
		return m_isAiming;
	}

	protected const override function CameraPerspectiveEnterCondition() : Bool
	{
		return true;
	}

}

class VehicleDriverCombatMountedWeaponsContextEvents extends VehicleDriverCombatContextEvents
{
}

class VehicleDriverCombatMountedWeaponsContextDecisions extends VehicleDriverCombatContextDecisions
{

	protected const override function CameraPerspectiveEnterCondition() : Bool
	{
		return true;
	}

	protected const override function IsAimingEnterCondition() : Bool
	{
		return true;
	}

	protected const override function DriverCombatTypeEnterCondition( const stateContext : StateContext ) : Bool
	{
		var driverCombatType : gamedataDriverCombatType;
		driverCombatType = GetDriverCombatType( stateContext );
		return driverCombatType == gamedataDriverCombatType.MountedWeapons;
	}

}

class VehicleNoDriveCombatContextDecisions extends InputContextTransitionDecisions
{
	private var m_callbackID : CallbackHandle;

	protected export function OnAttach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		var allBlackboardDef : AllBlackboardDefinitions;
		if( scriptInterface.localBlackboard )
		{
			allBlackboardDef = GetAllBlackboardDefs();
			m_callbackID = scriptInterface.localBlackboard.RegisterListenerInt( allBlackboardDef.PlayerStateMachine.Vehicle, this, 'OnVehicleStateChanged' );
			OnVehicleStateChanged( scriptInterface.localBlackboard.GetInt( allBlackboardDef.PlayerStateMachine.Vehicle ) );
		}
	}

	protected export function OnDetach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		m_callbackID = NULL;
	}

	protected event OnVehicleStateChanged( value : Int32 )
	{
		EnableOnEnterCondition( value == ( ( Int32 )( gamePSMVehicle.DriverCombat ) ) );
	}

	protected const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		if( StatusEffectSystem.ObjectHasStatusEffectWithTag( scriptInterface.executionOwner, 'NoDriving' ) )
		{
			return true;
		}
		return false;
	}

}

class VehicleCombatContextEvents extends InputContextTransitionEvents
{

	protected function OnUpdate( timeDelta : Float, stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( m_gameplaySettings.GetIsInputHintEnabled() && m_isGameplayInputHintManagerInitialized )
		{
			UpdateVehicleCombatInputHints( stateContext, scriptInterface );
		}
	}

	protected function UpdateVehicleCombatInputHints( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		if( ShouldForceRefreshInputHints( stateContext ) )
		{
			RemoveVehiclePassengerCombatInputHints( stateContext, scriptInterface );
			m_isGameplayInputHintRefreshRequired = false;
		}
		if( !( stateContext.GetBoolParameter( 'isPassengerCombatInputHintDisplayed', true ) ) )
		{
			ShowVehiclePassengerCombatInputHints( stateContext, scriptInterface );
		}
	}

	protected virtual function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		ShowVehiclePassengerCombatInputHints( stateContext, scriptInterface );
	}

	protected virtual function OnExit( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		RemoveVehiclePassengerCombatInputHints( stateContext, scriptInterface );
	}

}

class VehicleCombatContextDecisions extends InputContextTransitionDecisions
{
	private var m_callbackID : CallbackHandle;

	protected export function OnAttach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		var allBlackboardDef : AllBlackboardDefinitions;
		if( scriptInterface.localBlackboard )
		{
			allBlackboardDef = GetAllBlackboardDefs();
			m_callbackID = scriptInterface.localBlackboard.RegisterListenerInt( allBlackboardDef.PlayerStateMachine.Vehicle, this, 'OnVehicleStateChanged' );
			OnVehicleStateChanged( scriptInterface.localBlackboard.GetInt( allBlackboardDef.PlayerStateMachine.Vehicle ) );
		}
	}

	protected export function OnDetach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		m_callbackID = NULL;
	}

	protected event OnVehicleStateChanged( value : Int32 )
	{
		EnableOnEnterCondition( value == ( ( Int32 )( gamePSMVehicle.Combat ) ) );
	}

	protected const override function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		return true;
	}

}

