class ForceShootCommandTask extends AIbehaviortaskScript
{
	protected editable inlined var m_inCommand : AIArgumentMapping;
	protected var m_currentCommand : weak< AIForceShootCommand >;
	protected var m_threatPersistenceSource : AIThreatPersistenceSource_Record;
	protected var m_activationTimeStamp : Float;
	protected var m_commandDuration : Float;
	protected var m_target : weak< GameObject >;
	protected var m_targetID : EntityID;

	protected export override function Activate( context : ScriptExecutionContext )
	{
		SetUpdateInterval( context, RandomizeOffsetForUpdateInterval( 0.2 ) );
	}

	protected export override function Update( context : ScriptExecutionContext ) : AIbehaviorUpdateOutcome
	{
		var rawCommand : IScriptable;
		var typedCommand : AIForceShootCommand;
		var globalRef : GlobalNodeRef;
		var target : weak< GameObject >;
		rawCommand = ScriptExecutionContext.GetScriptableMappingValue( context, m_inCommand );
		typedCommand = ( ( AIForceShootCommand )( rawCommand ) );
		if( typedCommand == m_currentCommand )
		{
			if( m_currentCommand )
			{
				if( !( AIActionHelper.IsCommandCombatTargetValid( context, 'AIForceShootCommand' ) ) )
				{
					CancelCommand( context );
					if( typedCommand && typedCommand.state == AICommandState.Executing )
					{
						GetPuppet( context ).GetAIControllerComponent().StopExecutingCommand( typedCommand, true );
					}
				}
				else if( EntityID.IsDefined( m_targetID ) && !( m_target ) )
				{
					CancelCommand( context );
					ScriptExecutionContext.DebugLog( context, 'InjectCombatThreatCommand', "Canceling command, entity streamed out" );
					if( typedCommand && typedCommand.state == AICommandState.Executing )
					{
						GetPuppet( context ).GetAIControllerComponent().StopExecutingCommand( typedCommand, false );
					}
				}
				else if( ( m_commandDuration >= 0.0 ) && ( EngineTime.ToFloat( ScriptExecutionContext.GetAITime( context ) ) > ( m_activationTimeStamp + m_commandDuration ) ) )
				{
					CancelCommand( context );
					ScriptExecutionContext.DebugLog( context, 'AIForceShootCommand', "Canceling command, duration expired" );
					if( typedCommand && typedCommand.state == AICommandState.Executing )
					{
						GetPuppet( context ).GetAIControllerComponent().StopExecutingCommand( typedCommand, true );
					}
				}
			}
			return AIbehaviorUpdateOutcome.IN_PROGRESS;
		}
		m_currentCommand = typedCommand;
		m_commandDuration = typedCommand.duration;
		m_activationTimeStamp = EngineTime.ToFloat( ScriptExecutionContext.GetAITime( context ) );
		m_threatPersistenceSource = TweakDBInterface.GetAIThreatPersistenceSourceRecord( T"AIThreatPersistenceSource.CommandForceShoot" );
		if( !( GetGameObjectFromEntityReference( typedCommand.targetOverridePuppetRef, ScriptExecutionContext.GetOwner( context ).GetGame(), target ) ) )
		{
			globalRef = ResolveNodeRef( typedCommand.targetOverrideNodeRef, GlobalNodeID.GetRoot() );
			target = ( ( GameObject )( GameInstance.FindEntityByID( GetGame( context ), ( ( EntityID )( globalRef ) ) ) ) );
		}
		m_target = target;
		m_targetID = ( ( EntityID )( globalRef ) );
		if( EntityID.IsDefined( m_targetID ) && !( m_target ) )
		{
			CancelCommand( context );
			ScriptExecutionContext.DebugLog( context, 'AIForceShootCommand', "Canceling command, entity streamed out" );
			if( typedCommand && typedCommand.state == AICommandState.Executing )
			{
				GetPuppet( context ).GetAIControllerComponent().StopExecutingCommand( typedCommand, false );
			}
		}
		if( !( AIActionHelper.SetCommandCombatTarget( context, target, m_commandDuration != 0.0, ( ( Uint32 )( m_threatPersistenceSource.EnumValue() ) ) ) ) )
		{
			CancelCommand( context );
			ScriptExecutionContext.DebugLog( context, 'AIForceShootCommand', "Canceling command, unable to set CommandCombatTarget" );
			if( typedCommand && typedCommand.state == AICommandState.Executing )
			{
				GetPuppet( context ).GetAIControllerComponent().StopExecutingCommand( typedCommand, true );
			}
		}
		return AIbehaviorUpdateOutcome.IN_PROGRESS;
	}

	private export override final function Deactivate( context : ScriptExecutionContext )
	{
		var rawCommand : IScriptable;
		var typedCommand : AIForceShootCommand;
		if( !( m_currentCommand ) )
		{
			return;
		}
		rawCommand = ScriptExecutionContext.GetScriptableMappingValue( context, m_inCommand );
		typedCommand = ( ( AIForceShootCommand )( rawCommand ) );
		if( !( typedCommand ) )
		{
			CancelCommand( context );
		}
	}

	protected final function CancelCommand( context : ScriptExecutionContext )
	{
		AIActionHelper.ClearCommandCombatTarget( context, ( ( Uint32 )( m_threatPersistenceSource.EnumValue() ) ) );
		ScriptExecutionContext.SetMappingValue( context, m_inCommand, NULL );
		m_activationTimeStamp = 0.0;
		m_commandDuration = -1.0;
		m_currentCommand = NULL;
		m_target = NULL;
		m_targetID = m_target.GetEntityID();
	}

}

class ForceShootCommandCleanup extends AIbehaviortaskScript
{
	protected editable inlined var m_inCommand : AIArgumentMapping;

	private export override final function Deactivate( context : ScriptExecutionContext )
	{
		var threatPersistenceSource : AIThreatPersistenceSource_Record;
		threatPersistenceSource = TweakDBInterface.GetAIThreatPersistenceSourceRecord( T"AIThreatPersistenceSource.CommandForceShoot" );
		AIActionHelper.ClearCommandCombatTarget( context, ( ( Uint32 )( threatPersistenceSource.EnumValue() ) ) );
		ScriptExecutionContext.SetMappingValue( context, m_inCommand, NULL );
	}

}

class ForceShootCommandHandler extends AIbehaviortaskScript
{
	protected editable inlined var m_inCommand : AIArgumentMapping;
	protected var m_currentCommand : weak< AIForceShootCommand >;

	private override final function Activate( context : ScriptExecutionContext )
	{
		var rawCommand : IScriptable;
		var typedCommand : AIForceShootCommand;
		m_currentCommand = NULL;
		rawCommand = ScriptExecutionContext.GetScriptableMappingValue( context, m_inCommand );
		typedCommand = ( ( AIForceShootCommand )( rawCommand ) );
		if( typedCommand )
		{
			m_currentCommand = typedCommand;
		}
	}

	protected override function Update( context : ScriptExecutionContext ) : AIbehaviorUpdateOutcome
	{
		var rawCommand : IScriptable;
		var typedCommand : weak< AIForceShootCommand >;
		rawCommand = ScriptExecutionContext.GetScriptableMappingValue( context, m_inCommand );
		typedCommand = ( ( AIForceShootCommand )( rawCommand ) );
		if( !( typedCommand ) )
		{
			return AIbehaviorUpdateOutcome.IN_PROGRESS;
		}
		if( m_currentCommand )
		{
			if( typedCommand == m_currentCommand )
			{
				return AIbehaviorUpdateOutcome.IN_PROGRESS;
			}
			else
			{
				return AIbehaviorUpdateOutcome.SUCCESS;
			}
		}
		m_currentCommand = typedCommand;
		return AIbehaviorUpdateOutcome.SUCCESS;
	}

}

