class ReactionManagerTask extends AIbehaviortaskScript
{
	protected var m_reactionData : AIReactionData;

	protected export override function Activate( context : ScriptExecutionContext )
	{
		m_reactionData = GetPuppet( context ).GetStimReactionComponent().GetDesiredReactionData();
		if( !( m_reactionData ) )
		{
			SendBehaviorStatus( ScriptExecutionContext.GetOwner( context ), AIbehaviorUpdateOutcome.FAILURE );
		}
		else
		{
			SendBehaviorStatus( ScriptExecutionContext.GetOwner( context ), AIbehaviorUpdateOutcome.IN_PROGRESS );
			UpdateArguments( context );
		}
		GetPuppet( context ).GetStimReactionComponent().GetPuppetReactionBlackboard().SetBool( GetAllBlackboardDefs().PuppetReaction.exitReactionFlag, false );
	}

	protected export override function Update( context : ScriptExecutionContext ) : AIbehaviorUpdateOutcome
	{
		if( !( m_reactionData ) )
		{
			return AIbehaviorUpdateOutcome.FAILURE;
		}
		if( ScriptExecutionContext.GetArgumentObject( context, 'StimTarget' ) != m_reactionData.stimTarget )
		{
			m_reactionData.stimTarget = ScriptExecutionContext.GetArgumentObject( context, 'StimTarget' );
			m_reactionData.stimSource = ScriptExecutionContext.GetArgumentVector( context, 'StimSource' );
			SendBehaviorStatus( ScriptExecutionContext.GetOwner( context ), AIbehaviorUpdateOutcome.IN_PROGRESS );
		}
		if( GetPuppet( context ).GetStimReactionComponent().GetPuppetReactionBlackboard().GetBool( GetAllBlackboardDefs().PuppetReaction.exitReactionFlag ) )
		{
			GetPuppet( context ).GetStimReactionComponent().GetPuppetReactionBlackboard().SetBool( GetAllBlackboardDefs().PuppetReaction.exitReactionFlag, false );
			return AIbehaviorUpdateOutcome.FAILURE;
		}
		return AIbehaviorUpdateOutcome.IN_PROGRESS;
	}

	protected export override function Deactivate( context : ScriptExecutionContext )
	{
		SendBehaviorStatus( ScriptExecutionContext.GetOwner( context ), AIbehaviorUpdateOutcome.SUCCESS );
		m_reactionData = NULL;
	}

	protected function UpdateArguments( context : ScriptExecutionContext )
	{
		ScriptExecutionContext.SetArgumentObject( context, 'StimTarget', m_reactionData.stimTarget );
		ScriptExecutionContext.SetArgumentVector( context, 'StimSource', m_reactionData.stimSource );
	}

	protected function SendBehaviorStatus( owner : GameObject, status : AIbehaviorUpdateOutcome )
	{
		var behaviorStatus : ReactionBehaviorStatus;
		behaviorStatus = new ReactionBehaviorStatus;
		behaviorStatus.status = status;
		behaviorStatus.reactionData = m_reactionData;
		owner.QueueEvent( behaviorStatus );
	}

}

class UpdateStimSource extends ReactionManagerTask
{

	protected override function Deactivate( context : ScriptExecutionContext )
	{
		m_reactionData = NULL;
	}

}

class SetDesiredReaction extends AIbehaviortaskScript
{
	editable var m_behaviorArgumentNameTag : CName;
	editable var m_behaviorArgumentFloatPriority : CName;
	editable var m_behaviorArgumentNameFlag : CName;
	protected var m_reactionData : AIReactionData;

	protected export override function Activate( context : ScriptExecutionContext )
	{
		m_reactionData = GetPuppet( context ).GetStimReactionComponent().GetDesiredReactionData();
		if( m_reactionData )
		{
			ScriptExecutionContext.SetArgumentName( context, m_behaviorArgumentNameTag, EnumValueToName( 'gamedataOutput', ( ( Int32 )( m_reactionData.reactionBehaviorName ) ) ) );
			ScriptExecutionContext.SetArgumentFloat( context, m_behaviorArgumentFloatPriority, m_reactionData.reactionBehaviorAIPriority );
			ScriptExecutionContext.SetArgumentName( context, m_behaviorArgumentNameFlag, 'AIGSF_InterruptsSamePriorityTask' );
		}
	}

}

class SetControllerStimSource extends AIbehaviortaskScript
{
	protected var m_investigateData : stimInvestigateData;

	protected override function Activate( context : ScriptExecutionContext )
	{
		m_investigateData = GetPuppet( context ).GetStimReactionComponent().GetActiveReactionData().stimInvestigateData;
		ScriptExecutionContext.SetArgumentObject( context, 'StimTarget', ( ( GameObject )( m_investigateData.controllerEntity ) ) );
		ScriptExecutionContext.SetArgumentVector( context, 'StimSource', m_investigateData.controllerEntity.GetWorldPosition() );
	}

}

class SetDeviceInvestigationData extends AIbehaviortaskScript
{
	var ownerPuppet : weak< ScriptedPuppet >;
	var listener : weak< GameObject >;

	protected override function Activate( context : ScriptExecutionContext )
	{
		var activeReactionData : AIReactionData;
		var investigateData : stimInvestigateData;
		var communicationEvent : CommunicationEvent;
		ownerPuppet = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) );
		communicationEvent = new CommunicationEvent;
		communicationEvent.name = 'ResetInvestigators';
		communicationEvent.sender = ScriptExecutionContext.GetOwner( context ).GetEntityID();
		activeReactionData = ownerPuppet.GetStimReactionComponent().GetActiveReactionData();
		if( !( activeReactionData ) )
		{
			activeReactionData = ownerPuppet.GetStimReactionComponent().GetDesiredReactionData();
		}
		investigateData = activeReactionData.stimInvestigateData;
		if( investigateData.mainDeviceEntity )
		{
			ScriptExecutionContext.SetArgumentObject( context, 'TargetDevice', ( ( GameObject )( investigateData.mainDeviceEntity ) ) );
			listener = ( ( GameObject )( investigateData.mainDeviceEntity ) );
			SetInvestigationStateOnListener( listener, true );
			listener.QueueEvent( communicationEvent );
		}
		listener = activeReactionData.stimTarget;
		SetInvestigationStateOnListener( listener, true );
		listener.QueueEvent( communicationEvent );
		if( activeReactionData.stimType != gamedataStimType.CarAlarm )
		{
			ForceVisionAppearance( ownerPuppet, GetDistractionHighlightData( ownerPuppet ) );
		}
		ScriptExecutionContext.SetArgumentVector( context, 'CustomWorldPosition', investigateData.distrationPoint );
	}

	protected override function Deactivate( context : ScriptExecutionContext )
	{
		var communicationEvent : CommunicationEvent;
		communicationEvent = new CommunicationEvent;
		communicationEvent.name = 'TaskDeactivated';
		communicationEvent.sender = ScriptExecutionContext.GetOwner( context ).GetEntityID();
		listener.QueueEvent( communicationEvent );
		ownerPuppet = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) );
		listener = ScriptExecutionContext.GetArgumentObject( context, 'TargetDevice' );
		if( listener )
		{
			SetInvestigationStateOnListener( listener, false );
		}
		listener = ScriptExecutionContext.GetArgumentObject( context, 'StimTarget' );
		SetInvestigationStateOnListener( listener, false );
		CancelForcedVisionAppearance( ownerPuppet, GetDistractionHighlightData( ownerPuppet ) );
	}

	private function SetInvestigationStateOnListener( listenerArg : weak< GameObject >, isInvestigated : Bool )
	{
		var device : Device;
		device = ( ( Device )( listenerArg ) );
		if( device != NULL )
		{
			device.GetBlackboard().SetBool( device.GetBlackboardDef().IsInvestigated, isInvestigated );
		}
	}

	private function GetDistractionHighlightData( owner : ScriptedPuppet ) : FocusForcedHighlightData
	{
		var highlight : FocusForcedHighlightData;
		highlight = new FocusForcedHighlightData;
		highlight.sourceID = owner.GetEntityID();
		highlight.sourceName = GetClassName();
		highlight.highlightType = EFocusForcedHighlightType.INVALID;
		highlight.outlineType = EFocusOutlineType.DISTRACTION;
		highlight.priority = EPriority.High;
		highlight.isRevealed = true;
		return highlight;
	}

	private function ForceVisionAppearance( owner : ScriptedPuppet, data : FocusForcedHighlightData )
	{
		var evt : ForceVisionApperanceEvent;
		if( !( owner ) )
		{
			return;
		}
		evt = new ForceVisionApperanceEvent;
		evt.forcedHighlight = data;
		evt.apply = true;
		GameInstance.GetPersistencySystem( owner.GetGame() ).QueueEntityEvent( owner.GetEntityID(), evt );
	}

	private function CancelForcedVisionAppearance( owner : ScriptedPuppet, data : FocusForcedHighlightData )
	{
		var evt : ForceVisionApperanceEvent;
		if( !( owner ) )
		{
			return;
		}
		evt = new ForceVisionApperanceEvent;
		evt.forcedHighlight = data;
		evt.apply = false;
		GameInstance.GetPersistencySystem( owner.GetGame() ).QueueEntityEvent( owner.GetEntityID(), evt );
	}

}

class SetDeviceControllerInvestigationData extends AIbehaviortaskScript
{
	var ownerPuppet : weak< ScriptedPuppet >;

	protected override function Activate( context : ScriptExecutionContext )
	{
		var activeReactionData : AIReactionData;
		var investigateData : stimInvestigateData;
		var investigationPositions : array< Vector4 >;
		var distance, closestDistance : Float;
		var position : Vector4;
		var path : NavigationPath;
		var controller : Device;
		var i : Int32;
		ownerPuppet = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) );
		activeReactionData = ownerPuppet.GetStimReactionComponent().GetActiveReactionData();
		investigateData = activeReactionData.stimInvestigateData;
		controller = ( ( Device )( investigateData.controllerEntity ) );
		investigationPositions = controller.GetNodePosition();
		for( i = 0; i < investigationPositions.Size(); i += 1 )
		{
			distance = Vector4.Distance( investigationPositions[ i ], ownerPuppet.GetWorldPosition() );
			path = GameInstance.GetAINavigationSystem( ownerPuppet.GetGame() ).CalculatePathForCharacter( ownerPuppet.GetWorldPosition(), investigationPositions[ i ], 0.0, ownerPuppet );
			if( !( path ) )
			{
				continue;
			}
			if( ( distance < closestDistance ) || ( closestDistance == 0.0 ) )
			{
				closestDistance = distance;
				position = investigationPositions[ i ];
			}
		}
		if( !( Vector4.IsZero( position ) ) )
		{
			ScriptExecutionContext.SetArgumentVector( context, 'StimSource', position );
		}
		else
		{
			ScriptExecutionContext.SetArgumentVector( context, 'StimSource', controller.GetWorldPosition() );
		}
		ScriptExecutionContext.SetArgumentObject( context, 'StimTarget', controller );
		ScriptExecutionContext.SetArgumentVector( context, 'CustomWorldPosition', controller.GetDistractionPointPosition( controller ) );
	}

}

class TriggerCombatAgainstStimTarget extends AIbehaviortaskScript
{

	protected export override function Activate( context : ScriptExecutionContext )
	{
		var puppet : ScriptedPuppet;
		var stimReactionComp : ReactionManagerComponent;
		var activeReactionData : AIReactionData;
		var investigateData : stimInvestigateData;
		var target : weak< GameObject >;
		var stimTarget : weak< GameObject >;
		var targetPuppet : weak< ScriptedPuppet >;
		var mountInfo : MountingInfo;
		puppet = GetPuppet( context );
		stimReactionComp = puppet.GetStimReactionComponent();
		activeReactionData = stimReactionComp.GetActiveOrDesiredReactionData();
		stimReactionComp.LogStart( EReactLogSource.BehaviorCombatTrigger, "TriggerCombatAgainstStimTarget attempt" );
		if( activeReactionData )
		{
			investigateData = activeReactionData.stimInvestigateData;
		}
		if( puppet.GetNPCType() == gamedataNPCType.Cerberus )
		{
			stimTarget = ScriptExecutionContext.GetArgumentObject( context, 'Player' );
		}
		else
		{
			stimTarget = ScriptExecutionContext.GetArgumentObject( context, 'StimTarget' );
		}
		if( investigateData.attackInstigator )
		{
			target = ( ( GameObject )( investigateData.attackInstigator ) );
			stimReactionComp.LogInfo( "target taken from attack instigator" );
		}
		else
		{
			target = stimTarget;
		}
		if( !( target ) )
		{
			stimReactionComp.LogFailure( "no target to start combat with" );
			return;
		}
		targetPuppet = ( ( ScriptedPuppet )( target ) );
		if( targetPuppet && ScriptedPuppet.IsPlayerCompanion( targetPuppet ) )
		{
			stimReactionComp.LogFailure( "can not start combat with player companion" );
			return;
		}
		if( GameObject.IsVehicle( target ) )
		{
			mountInfo = GameInstance.GetMountingFacility( puppet.GetGame() ).GetMountingInfoSingleWithObjects( , target );
			target = ( ( GameObject )( GameInstance.FindEntityByID( puppet.GetGame(), mountInfo.childId ) ) );
			targetPuppet = ( ( ScriptedPuppet )( target ) );
			stimReactionComp.LogInfo( "reevaluated target from vehicle driver" );
		}
		if( stimReactionComp.ShouldIgnoreCombatStim( activeReactionData.stimType, targetPuppet, targetPuppet, activeReactionData.stimSource, true ) )
		{
			stimReactionComp.LogFailure( "combat stim explicitely ignored" );
			return;
		}
		if( !( AIActionHelper.TryChangingAttitudeToHostile( puppet, target ) ) )
		{
			stimReactionComp.LogFailure( "failed changing attitude to hostile" );
			return;
		}
		TargetTrackingExtension.InjectThreat( puppet, target );
		stimReactionComp.LogSuccess( "injected threat" );
	}

}

class TriggerCombatReaction extends AIbehaviortaskScript
{

	protected export override function Deactivate( context : ScriptExecutionContext )
	{
		var ownerPuppet : ScriptedPuppet;
		var triggerAIEvent : AIEvent;
		ownerPuppet = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) );
		if( ownerPuppet.GetStimReactionComponent().GetInPendingBehavior() )
		{
			triggerAIEvent = new AIEvent;
			triggerAIEvent.name = 'TriggerCombatReaction';
			ownerPuppet.QueueEvent( triggerAIEvent );
		}
	}

}

class GenerateHeatAroundLastTriggeredStimuli extends AIbehaviortaskScript
{

	protected override function Activate( context : ScriptExecutionContext )
	{
		var stimSourcePos : Vector4;
		var stimuliCache : array< StimEventTaskData >;
		stimuliCache = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) ).GetStimReactionComponent().GetStimuliCache();
		stimSourcePos = stimuliCache[ stimuliCache.Size() - 1 ].cachedEvt.sourcePosition;
		GameInstance.GetInfluenceMapSystem( ScriptExecutionContext.GetOwner( context ).GetGame() ).SetSearchValueLerp( stimSourcePos, 2.0, 0.40000001, 0.60000002 );
	}

}

class SetTrafficLaneMovementParams extends AIbehaviortaskScript
{
	editable var m_movementType : String;
	editable var m_fearStage : gameFearStage;
	default m_fearStage = gameFearStage.Relaxed;

	protected export override function Activate( context : ScriptExecutionContext )
	{
		var crowdMemberComponent : CrowdMemberComponent;
		crowdMemberComponent = GetPuppet( context ).GetCrowdMemberComponent();
		ScriptExecutionContext.SetArgumentVector( context, 'CustomWorldPosition', ScriptExecutionContext.GetArgumentVector( context, 'PathDirection' ) );
		ScriptExecutionContext.SetArgumentVector( context, 'MovementDestination', ScriptExecutionContext.GetArgumentVector( context, 'ClosestPositionOnPath' ) );
		if( StrLen( m_movementType ) > 0 )
		{
			crowdMemberComponent.ChangeMoveType( StringToName( m_movementType ) );
		}
		switch( m_fearStage )
		{
			case gameFearStage.Stressed:
				crowdMemberComponent.ChangeFearStage( m_fearStage );
			break;
			case gameFearStage.Panic:
				crowdMemberComponent.ChangeFearStage( m_fearStage );
			break;
			case gameFearStage.Alarmed:
				crowdMemberComponent.ChangeFearStage( m_fearStage );
			break;
			case gameFearStage.Relaxed:
				crowdMemberComponent.ChangeFearStage( m_fearStage );
			break;
		}
	}

	protected export override function Deactivate( context : ScriptExecutionContext )
	{
		var crowdMemberComponent : CrowdMemberComponent;
		crowdMemberComponent = GetPuppet( context ).GetCrowdMemberComponent();
		crowdMemberComponent.TryStopTrafficMovement();
	}

}

class SetAvoidThreatDestination extends AIbehaviortaskScript
{

	protected override function Activate( context : ScriptExecutionContext )
	{
		var movePoliciesComponent : MovePoliciesComponent;
		movePoliciesComponent = GetPuppet( context ).GetMovePolicesComponent();
		if( movePoliciesComponent )
		{
			ScriptExecutionContext.SetArgumentVector( context, 'MovementDestination', movePoliciesComponent.GetDestination() );
		}
	}

}

class AddActiveStimuli extends AIbehaviortaskScript
{
	editable var stimType : gamedataStimType;
	editable var lifetime : Float;

	protected override function Activate( context : ScriptExecutionContext )
	{
		var owner : ScriptedPuppet;
		owner = GetPuppet( context );
		if( owner )
		{
			owner.GetStimBroadcasterComponent().AddActiveStimuli( owner, stimType, lifetime );
		}
	}

	protected override function Deactivate( context : ScriptExecutionContext )
	{
		var owner : ScriptedPuppet;
		owner = GetPuppet( context );
		if( owner && ( lifetime < 0.0 ) )
		{
			owner.GetStimBroadcasterComponent().RemoveActiveStimuliByName( owner, stimType );
		}
	}

}

class MarkDespawnCandidate extends AIbehaviortaskScript
{
	editable var m_onDeactivation : Bool;

	protected override function Activate( context : ScriptExecutionContext )
	{
		var reactionSystem : ReactionSystem;
		reactionSystem = GameInstance.GetReactionSystem( ScriptExecutionContext.GetOwner( context ).GetGame() );
		if( reactionSystem && !( m_onDeactivation ) )
		{
			reactionSystem.MarkDespawnCandidate( ScriptExecutionContext.GetOwner( context ).GetEntityID() );
		}
	}

}

class RegisterFearReaction extends AIbehaviortaskScript
{

	protected export override function Activate( context : ScriptExecutionContext )
	{
		var reactionSystem : ReactionSystem;
		var threat : GameObject;
		threat = GameInstance.GetPlayerSystem( ScriptExecutionContext.GetOwner( context ).GetGame() ).GetLocalPlayerMainGameObject();
		reactionSystem = GameInstance.GetReactionSystem( ScriptExecutionContext.GetOwner( context ).GetGame() );
		if( reactionSystem )
		{
			if( GetPuppet( context ).GetStimReactionComponent().IsInTrafficLane() )
			{
				reactionSystem.AddTrafficRunnersDirectly( ScriptExecutionContext.GetOwner( context ), threat );
			}
			else
			{
				reactionSystem.RegisterFearReaction( ScriptExecutionContext.GetOwner( context ), threat );
			}
		}
	}

	protected export override function Deactivate( context : ScriptExecutionContext )
	{
		var reactionSystem : ReactionSystem;
		reactionSystem = GameInstance.GetReactionSystem( ScriptExecutionContext.GetOwner( context ).GetGame() );
		if( reactionSystem )
		{
			reactionSystem.UnregisterFearReaction( ScriptExecutionContext.GetOwner( context ) );
		}
	}

}

class SetExplosionInstigatorPositionAsStimSource extends AIbehaviortaskScript
{

	protected override function Activate( context : ScriptExecutionContext )
	{
		var stimuliCache : array< StimEventTaskData >;
		var investigateData : stimInvestigateData;
		stimuliCache = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) ).GetStimReactionComponent().GetStimuliCache();
		if( stimuliCache.Size() != 0 )
		{
			investigateData = stimuliCache[ stimuliCache.Size() - 1 ].cachedEvt.stimInvestigateData;
			if( stimuliCache[ ( stimuliCache.Size() - 1 ) ].cachedEvt.GetStimType() == gamedataStimType.Explosion && investigateData.revealsInstigatorPosition )
			{
				ScriptExecutionContext.SetArgumentVector( context, 'StimSource', investigateData.attackInstigatorPosition );
			}
		}
	}

}

class UpdateWhistlePosition extends AIbehaviortaskScript
{
	protected virtual function SetTarget( context : ScriptExecutionContext, target : weak< GameObject > );
	protected virtual function SetPosition( context : ScriptExecutionContext, position : Vector4 );

	public static function TryGetDesiredWhistlePosition( owner : GameObject, playerPosition : Vector4, out position : Vector4, out proxy : GameObject ) : Bool
	{
		var whistleEffects : array< StatusEffect >;
		var navigationSystem : AINavigationSystem;
		var query : AINavigationSystemQuery;
		var queryId : Uint32;
		var worldPosition : WorldPosition;
		var navResult : AINavigationSystemResult;
		StatusEffectHelper.GetAppliedEffectsWithTag( owner, 'Whistle', whistleEffects );
		if( whistleEffects.Size() == 0 )
		{
			return false;
		}
		if( EntityID.IsDefined( whistleEffects[ 0 ].GetProxyEntityID() ) )
		{
			proxy = ( ( GameObject )( GameInstance.FindEntityByID( owner.GetGame(), whistleEffects[ 0 ].GetProxyEntityID() ) ) );
		}
		if( proxy && StatusEffectSystem.ObjectHasStatusEffectWithTag( owner, 'WhistleGoToCamera' ) )
		{
			position = proxy.GetWorldPosition();
		}
		else
		{
			proxy = NULL;
			position = playerPosition;
		}
		if( StatusEffectSystem.ObjectHasStatusEffectWithTag( owner, 'WhistleTurnAway' ) )
		{
			position = ( 2.0 * owner.GetWorldPosition() ) - position;
			return true;
		}
		navigationSystem = GameInstance.GetAINavigationSystem( owner.GetGame() );
		AIPositionSpec.SetEntity( query.source, owner );
		WorldPosition.SetVector4( worldPosition, position );
		AIPositionSpec.SetWorldPosition( query.target, worldPosition );
		queryId = navigationSystem.StartPathfinding( query );
		navigationSystem.GetResult( queryId, navResult );
		navigationSystem.StopPathfinding( queryId );
		if( navResult.hasClosestReachablePoint )
		{
			position = WorldPosition.ToVector4( navResult.closestReachablePoint );
		}
		return true;
	}

	protected override function Activate( context : ScriptExecutionContext )
	{
		var owner : ScriptedPuppet;
		var player : GameObject;
		var proxy : GameObject;
		var position : Vector4;
		owner = GetPuppet( context );
		player = GameInstance.GetPlayerSystem( owner.GetGame() ).GetLocalPlayerControlledGameObject();
		if( !( TryGetDesiredWhistlePosition( owner, player.GetWorldPosition(), position, proxy ) ) )
		{
			return;
		}
		SetTarget( context, ( ( proxy ) ? ( proxy ) : ( player ) ) );
		SetPosition( context, position );
	}

}

class UpdateWhistleStimSource extends UpdateWhistlePosition
{

	protected override function SetTarget( context : ScriptExecutionContext, target : weak< GameObject > )
	{
		ScriptExecutionContext.SetArgumentObject( context, 'StimTarget', target );
	}

	protected override function SetPosition( context : ScriptExecutionContext, position : Vector4 )
	{
		ScriptExecutionContext.SetArgumentVector( context, 'StimSource', position );
	}

}

class UpdateWhistleCustomWorldPosition extends UpdateWhistlePosition
{
	editable inlined var m_outPositionArgument : AIArgumentMapping;

	protected override function SetTarget( context : ScriptExecutionContext, target : weak< GameObject > ) {}

	protected override function SetPosition( context : ScriptExecutionContext, position : Vector4 )
	{
		ScriptExecutionContext.SetMappingValue( context, m_outPositionArgument, position );
	}

}

class InjectAttackInstigatorAsThreat extends AIbehaviortaskScript
{

	protected override function Activate( context : ScriptExecutionContext )
	{
		var stimuliCache : array< StimEventTaskData >;
		var investigateData : stimInvestigateData;
		var ownerPuppet : ScriptedPuppet;
		var attackInstigatorPuppet : ScriptedPuppet;
		ownerPuppet = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) );
		stimuliCache = ownerPuppet.GetStimReactionComponent().GetStimuliCache();
		if( stimuliCache.Size() != 0 )
		{
			investigateData = stimuliCache[ stimuliCache.Size() - 1 ].cachedEvt.stimInvestigateData;
			if( stimuliCache[ ( stimuliCache.Size() - 1 ) ].cachedEvt.GetStimType() == gamedataStimType.Explosion && investigateData.revealsInstigatorPosition )
			{
				attackInstigatorPuppet = ( ( ScriptedPuppet )( investigateData.attackInstigator ) );
				if( AIActionHelper.TryChangingAttitudeToHostile( ownerPuppet, attackInstigatorPuppet ) )
				{
					TargetTrackingExtension.InjectThreat( ownerPuppet, attackInstigatorPuppet );
				}
			}
		}
	}

}

class AdjustAnimWrappersForEscalatingFearPhase extends AIbehaviortaskScript
{

	protected override function Activate( context : ScriptExecutionContext )
	{
		AnimationControllerComponent.SetAnimWrapperWeightOnOwnerAndItems( ScriptExecutionContext.GetOwner( context ), 'panic', 0.0 );
		AnimationControllerComponent.SetAnimWrapperWeightOnOwnerAndItems( ScriptExecutionContext.GetOwner( context ), 'fear', 1.0 );
	}

	protected override function Deactivate( context : ScriptExecutionContext )
	{
		AnimationControllerComponent.SetAnimWrapperWeightOnOwnerAndItems( ScriptExecutionContext.GetOwner( context ), 'panic', 1.0 );
		AnimationControllerComponent.SetAnimWrapperWeightOnOwnerAndItems( ScriptExecutionContext.GetOwner( context ), 'fear', 0.0 );
	}

}

class AdjustAnimWrappersForDeescalatingFearPhase extends AIbehaviortaskScript
{

	protected override function Activate( context : ScriptExecutionContext )
	{
		var ownerPuppet : ScriptedPuppet;
		var reactionComponent : ReactionManagerComponent;
		ownerPuppet = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) );
		reactionComponent = ownerPuppet.GetStimReactionComponent();
		AnimationControllerComponent.SetAnimWrapperWeightOnOwnerAndItems( ScriptExecutionContext.GetOwner( context ), 'disturbed', 1.0 );
		AnimationControllerComponent.SetAnimWrapperWeightOnOwnerAndItems( ScriptExecutionContext.GetOwner( context ), 'panic', 0.0 );
		AnimationControllerComponent.SetAnimWrapperWeightOnOwnerAndItems( ScriptExecutionContext.GetOwner( context ), 'fear', 0.0 );
		if( !( reactionComponent.IsFearLocomotionWrapperSet() ) )
		{
			AnimationControllerComponent.SetAnimWrapperWeightOnOwnerAndItems( ScriptExecutionContext.GetOwner( context ), reactionComponent.GetRandomFearLocomotionAnimWrapper( 1 ), 1.0 );
		}
	}

}

class AdjustAnimWrappersForEscalatingPanicPhase extends AIbehaviortaskScript
{

	protected export override function Activate( context : ScriptExecutionContext )
	{
		AnimationControllerComponent.SetAnimWrapperWeightOnOwnerAndItems( ScriptExecutionContext.GetOwner( context ), 'disturbed', 0.0 );
		AnimationControllerComponent.SetAnimWrapperWeightOnOwnerAndItems( ScriptExecutionContext.GetOwner( context ), 'panic', 1.0 );
		AnimationControllerComponent.SetAnimWrapperWeightOnOwnerAndItems( ScriptExecutionContext.GetOwner( context ), 'fear', 0.0 );
	}

}

class SetStressOnTrafficLane extends AIbehaviortaskScript
{

	protected override function Activate( context : ScriptExecutionContext )
	{
		AnimationControllerComponent.SetAnimWrapperWeightOnOwnerAndItems( ScriptExecutionContext.GetOwner( context ), 'disturbed', 1.0 );
	}

}

class SetPanicOnTrafficLane extends AIbehaviortaskScript
{

	protected override function Activate( context : ScriptExecutionContext )
	{
		var stimTarget : GameObject;
		var vehicle : VehicleObject;
		stimTarget = ScriptExecutionContext.GetArgumentObject( context, 'StimTarget' );
		vehicle = ( ( VehicleObject )( stimTarget ) );
		if( VehicleComponent.IsMountedToVehicle( ScriptExecutionContext.GetOwner( context ).GetGame(), stimTarget ) || vehicle )
		{
			GameObject.PlayVoiceOver( ScriptExecutionContext.GetOwner( context ), 'pedestrian_hit', 'Script:SetPanicOnTrafficLane/pedestrian' );
		}
		else
		{
			GameObject.PlayVoiceOver( ScriptExecutionContext.GetOwner( context ), 'fear_run', 'Script:SetPanicOnTrafficLane' );
		}
	}

}

class TriggerFearRunningVO extends AIbehaviortaskScript
{

	protected export override function Activate( context : ScriptExecutionContext )
	{
		var stimTarget : GameObject;
		var vehicle : VehicleObject;
		var triggerVOEvent : SoundPlayVo;
		stimTarget = ScriptExecutionContext.GetArgumentObject( context, 'StimTarget' );
		vehicle = ( ( VehicleObject )( stimTarget ) );
		triggerVOEvent = new SoundPlayVo;
		if( VehicleComponent.IsMountedToVehicle( ScriptExecutionContext.GetOwner( context ).GetGame(), stimTarget ) || vehicle )
		{
			triggerVOEvent.voContext = 'pedestrian_hit';
			triggerVOEvent.debugInitialContext = 'Script:TriggerFearRunningVO/pedestrian';
			GameInstance.GetDelaySystem( ScriptExecutionContext.GetOwner( context ).GetGame() ).DelayEvent( ScriptExecutionContext.GetOwner( context ), triggerVOEvent, RandRangeF( 0.2, 0.69999999 ) );
		}
		else
		{
			triggerVOEvent.voContext = 'fear_run';
			triggerVOEvent.debugInitialContext = 'Script:TriggerFearRunningVO';
			GameInstance.GetDelaySystem( ScriptExecutionContext.GetOwner( context ).GetGame() ).DelayEvent( ScriptExecutionContext.GetOwner( context ), triggerVOEvent, RandRangeF( 0.2, 0.69999999 ) );
		}
	}

}

class ResetAllFearWrappers extends AIbehaviortaskScript
{

	protected override function Activate( context : ScriptExecutionContext )
	{
		AnimationControllerComponent.SetAnimWrapperWeightOnOwnerAndItems( ScriptExecutionContext.GetOwner( context ), 'disturbed', 0.0 );
		AnimationControllerComponent.SetAnimWrapperWeightOnOwnerAndItems( ScriptExecutionContext.GetOwner( context ), 'fear', 0.0 );
		AnimationControllerComponent.SetAnimWrapperWeightOnOwnerAndItems( ScriptExecutionContext.GetOwner( context ), 'panic', 0.0 );
		AnimationControllerComponent.SetAnimWrapperWeightOnOwnerAndItems( ScriptExecutionContext.GetOwner( context ), 'FearLocomotion1', 0.0 );
		AnimationControllerComponent.SetAnimWrapperWeightOnOwnerAndItems( ScriptExecutionContext.GetOwner( context ), 'FearLocomotion2', 0.0 );
		AnimationControllerComponent.SetAnimWrapperWeightOnOwnerAndItems( ScriptExecutionContext.GetOwner( context ), 'FearLocomotion3', 0.0 );
		AnimationControllerComponent.SetAnimWrapperWeightOnOwnerAndItems( ScriptExecutionContext.GetOwner( context ), 'FearLocomotion4', 0.0 );
	}

}

class ReprimandEscalation extends AIbehaviortaskScript
{

	protected export override function Activate( context : ScriptExecutionContext )
	{
		var statPoolsSystem : StatPoolsSystem;
		var reprimandEscalationEvent : ReprimandEscalationEvent;
		statPoolsSystem = GameInstance.GetStatPoolsSystem( ScriptExecutionContext.GetOwner( context ).GetGame() );
		reprimandEscalationEvent = new ReprimandEscalationEvent;
		if( !( statPoolsSystem.IsStatPoolAdded( ScriptExecutionContext.GetOwner( context ).GetEntityID(), gamedataStatPoolType.ReprimandEscalation ) ) )
		{
			reprimandEscalationEvent.startReprimand = true;
		}
		ScriptExecutionContext.GetOwner( context ).QueueEvent( reprimandEscalationEvent );
	}

}

class ReprimandDeescalation extends AIbehaviortaskScript
{

	protected export override function Activate( context : ScriptExecutionContext )
	{
		var reprimandEscalationEvent : ReprimandEscalationEvent;
		reprimandEscalationEvent = new ReprimandEscalationEvent;
		reprimandEscalationEvent.startDeescalate = true;
		ScriptExecutionContext.GetOwner( context ).QueueEvent( reprimandEscalationEvent );
	}

}

class ResetReprimandEscalation extends AIbehaviortaskScript
{

	protected export override function Deactivate( context : ScriptExecutionContext )
	{
		var statPoolsSystem : StatPoolsSystem;
		var m_AnimFeature_Reprimand : AnimFeature_Reprimand;
		statPoolsSystem = GameInstance.GetStatPoolsSystem( ScriptExecutionContext.GetOwner( context ).GetGame() );
		statPoolsSystem.RequestRemovingStatPool( ScriptExecutionContext.GetOwner( context ).GetEntityID(), gamedataStatPoolType.ReprimandEscalation );
		m_AnimFeature_Reprimand = new AnimFeature_Reprimand;
		m_AnimFeature_Reprimand.isActive = false;
		m_AnimFeature_Reprimand.state = 0;
		m_AnimFeature_Reprimand.isLocomotion = false;
		m_AnimFeature_Reprimand.weaponType = GetItemTypeFromContext( context );
		AnimationControllerComponent.ApplyFeature( ScriptExecutionContext.GetOwner( context ), 'ReprimandAnim', m_AnimFeature_Reprimand, 5.0 );
	}

}

function GetItemTypeFromContext( context : ScriptExecutionContext ) : Int32
{
	var itemsToEquip : array< NPCItemToEquip >;
	var BBoard : IBlackboard;
	var itemRecord : weak< Item_Record >;
	var itemObject : ItemObject;
	var itemEnumNumber : Int32;
	BBoard = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) ).GetAIControllerComponent().GetActionBlackboard();
	itemsToEquip = ( ( array< NPCItemToEquip > )( BBoard.GetVariant( GetAllBlackboardDefs().AIAction.ownerItemsToEquip ) ) );
	itemRecord = TweakDBInterface.GetItemRecord( ItemID.GetTDBID( itemsToEquip[ 0 ].itemID ) );
	if( !( itemRecord ) )
	{
		itemObject = GameInstance.GetTransactionSystem( ScriptExecutionContext.GetOwner( context ).GetGame() ).GetItemInSlot( ScriptExecutionContext.GetOwner( context ), T"AttachmentSlots.WeaponRight" );
		if( itemObject )
		{
			itemRecord = TweakDBInterface.GetItemRecord( ItemID.GetTDBID( itemObject.GetItemID() ) );
		}
	}
	itemEnumNumber = itemRecord.ItemType().AnimFeatureIndex();
	switch( itemRecord.ItemType().Type() )
	{
		case gamedataItemType.Wea_LightMachineGun:
			itemEnumNumber = 2;
		break;
		case gamedataItemType.Wea_HeavyMachineGun:
			itemEnumNumber = 2;
		break;
		case gamedataItemType.Wea_SubmachineGun:
			itemEnumNumber = 3;
		break;
		case gamedataItemType.Wea_Rifle:
			itemEnumNumber = 4;
		break;
		case gamedataItemType.Wea_PrecisionRifle:
			itemEnumNumber = 4;
		break;
		case gamedataItemType.Wea_SniperRifle:
			itemEnumNumber = 4;
		break;
		case gamedataItemType.Wea_AssaultRifle:
			itemEnumNumber = 4;
		break;
		case gamedataItemType.Wea_Shotgun:
			itemEnumNumber = 4;
		break;
		case gamedataItemType.Wea_ShotgunDual:
			itemEnumNumber = 4;
		break;
		case gamedataItemType.Wea_Handgun:
			itemEnumNumber = 6;
		break;
		case gamedataItemType.Wea_Revolver:
			itemEnumNumber = 6;
		break;
		case gamedataItemType.Wea_Katana:
			itemEnumNumber = 5;
		break;
		case gamedataItemType.Wea_Sword:
			itemEnumNumber = 5;
		break;
		case gamedataItemType.Wea_Knife:
			itemEnumNumber = 5;
		break;
		case gamedataItemType.Wea_LongBlade:
			itemEnumNumber = 5;
		break;
		case gamedataItemType.Wea_Melee:
			itemEnumNumber = 5;
		break;
		case gamedataItemType.Wea_OneHandedClub:
			itemEnumNumber = 5;
		break;
		case gamedataItemType.Wea_ShortBlade:
			itemEnumNumber = 5;
		break;
		case gamedataItemType.Wea_Hammer:
			itemEnumNumber = 5;
		break;
		case gamedataItemType.Wea_Fists:
			itemEnumNumber = 5;
		break;
		case gamedataItemType.Wea_TwoHandedClub:
			itemEnumNumber = 5;
		break;
		case gamedataItemType.Wea_Axe:
			itemEnumNumber = 5;
		break;
		case gamedataItemType.Wea_Chainsword:
			itemEnumNumber = 5;
		break;
		case gamedataItemType.Wea_Machete:
			itemEnumNumber = 5;
		break;
		case gamedataItemType.Cyb_MantisBlades:
			itemEnumNumber = 5;
		break;
		case gamedataItemType.Cyb_StrongArms:
			itemEnumNumber = 5;
		break;
		default:
			itemEnumNumber = 7;
		break;
	}
	return itemEnumNumber;
}

class ReprimandStartAnimFeature extends AIbehaviortaskScript
{

	protected export override function Activate( context : ScriptExecutionContext )
	{
		var m_AnimFeature_Reprimand : AnimFeature_Reprimand;
		m_AnimFeature_Reprimand = new AnimFeature_Reprimand;
		m_AnimFeature_Reprimand.isActive = true;
		m_AnimFeature_Reprimand.state = 2;
		m_AnimFeature_Reprimand.isLocomotion = false;
		m_AnimFeature_Reprimand.weaponType = GetItemTypeFromContext( context );
		AnimationControllerComponent.ApplyFeature( ScriptExecutionContext.GetOwner( context ), 'ReprimandAnim', m_AnimFeature_Reprimand );
	}

}

class ReprimandResetAnimFeature extends AIbehaviortaskScript
{

	protected export override function Activate( context : ScriptExecutionContext )
	{
		var m_AnimFeature_Reprimand : AnimFeature_Reprimand;
		m_AnimFeature_Reprimand = new AnimFeature_Reprimand;
		m_AnimFeature_Reprimand.isActive = false;
		m_AnimFeature_Reprimand.state = 0;
		m_AnimFeature_Reprimand.isLocomotion = false;
		m_AnimFeature_Reprimand.weaponType = GetItemTypeFromContext( context );
		AnimationControllerComponent.ApplyFeature( ScriptExecutionContext.GetOwner( context ), 'ReprimandAnim', m_AnimFeature_Reprimand, 5.0 );
	}

}

class ReprimandEscalateAnimFeature extends AIbehaviortaskScript
{

	protected export override function Activate( context : ScriptExecutionContext )
	{
		var m_AnimFeature_Reprimand : AnimFeature_Reprimand;
		m_AnimFeature_Reprimand = new AnimFeature_Reprimand;
		m_AnimFeature_Reprimand.isActive = true;
		m_AnimFeature_Reprimand.state = 3;
		m_AnimFeature_Reprimand.isLocomotion = false;
		m_AnimFeature_Reprimand.weaponType = GetItemTypeFromContext( context );
		AnimationControllerComponent.ApplyFeature( ScriptExecutionContext.GetOwner( context ), 'ReprimandAnim', m_AnimFeature_Reprimand );
	}

}

class ReprimandDeescalateAnimFeature extends AIbehaviortaskScript
{

	protected export override function Activate( context : ScriptExecutionContext )
	{
		var m_AnimFeature_Reprimand : AnimFeature_Reprimand;
		m_AnimFeature_Reprimand = new AnimFeature_Reprimand;
		m_AnimFeature_Reprimand.isActive = true;
		m_AnimFeature_Reprimand.state = 1;
		m_AnimFeature_Reprimand.isLocomotion = false;
		m_AnimFeature_Reprimand.weaponType = GetItemTypeFromContext( context );
		AnimationControllerComponent.ApplyFeature( ScriptExecutionContext.GetOwner( context ), 'ReprimandAnim', m_AnimFeature_Reprimand );
	}

}

class ReprimandToAlertedAnimFeature extends AIbehaviortaskScript
{

	protected override function Activate( context : ScriptExecutionContext )
	{
		var m_AnimFeature_Reprimand : AnimFeature_Reprimand;
		m_AnimFeature_Reprimand = new AnimFeature_Reprimand;
		m_AnimFeature_Reprimand.isActive = false;
		m_AnimFeature_Reprimand.state = 0;
		m_AnimFeature_Reprimand.isLocomotion = false;
		m_AnimFeature_Reprimand.weaponType = GetItemTypeFromContext( context );
		AnimationControllerComponent.ApplyFeature( ScriptExecutionContext.GetOwner( context ), 'ReprimandAnim', m_AnimFeature_Reprimand );
	}

}

class ReprimandToCombatAnimFeature extends AIbehaviortaskScript
{

	protected export override function Activate( context : ScriptExecutionContext )
	{
		var m_AnimFeature_Reprimand : AnimFeature_Reprimand;
		m_AnimFeature_Reprimand = new AnimFeature_Reprimand;
		m_AnimFeature_Reprimand.isActive = false;
		m_AnimFeature_Reprimand.state = 0;
		m_AnimFeature_Reprimand.isLocomotion = true;
		m_AnimFeature_Reprimand.weaponType = GetItemTypeFromContext( context );
		AnimationControllerComponent.ApplyFeature( ScriptExecutionContext.GetOwner( context ), 'ReprimandAnim', m_AnimFeature_Reprimand );
	}

}

class CallPolice extends AIbehaviortaskScript
{

	protected override function Activate( context : ScriptExecutionContext )
	{
		PreventionSystem.CrimeWitnessRequestToPreventionSystem( ScriptExecutionContext.GetOwner( context ).GetGame(), GameInstance.GetPlayerSystem( ScriptExecutionContext.GetOwner( context ).GetGame() ).GetLocalPlayerMainGameObject().GetWorldPosition() );
	}

}

class IncrimentStimThreshold extends AIbehaviortaskScript
{
	editable var m_thresholdTimeout : Float;

	protected export override function Activate( context : ScriptExecutionContext )
	{
		var thresholdEvent : StimThresholdEvent;
		thresholdEvent = new StimThresholdEvent;
		thresholdEvent.timeThreshold = m_thresholdTimeout;
		ScriptExecutionContext.GetOwner( context ).QueueEvent( thresholdEvent );
	}

}

class IncrimentStealthStimThreshold extends AIbehaviortaskScript
{
	editable var m_thresholdTimeout : Float;

	protected export override function Activate( context : ScriptExecutionContext )
	{
		var thresholdEvent : StealthStimThresholdEvent;
		thresholdEvent = new StealthStimThresholdEvent;
		thresholdEvent.timeThreshold = m_thresholdTimeout;
		ScriptExecutionContext.GetOwner( context ).QueueEvent( thresholdEvent );
	}

}

class SetTimestampToBehaviorAgrument extends AIbehaviortaskScript
{
	editable var m_timestampArgument : CName;

	protected export override function Activate( context : ScriptExecutionContext )
	{
		ScriptExecutionContext.SetArgumentFloat( context, m_timestampArgument, EngineTime.ToFloat( GameInstance.GetSimTime( ScriptExecutionContext.GetOwner( context ).GetGame() ) ) );
	}

}

class UnregisterReactionAction extends AIbehaviortaskScript
{
	editable var m_reactionName : CName;
	editable var m_onDeactivation : Bool;

	protected override function Activate( context : ScriptExecutionContext )
	{
		var reactionSystem : ReactionSystem;
		reactionSystem = GameInstance.GetReactionSystem( ScriptExecutionContext.GetOwner( context ).GetGame() );
		if( reactionSystem && !( m_onDeactivation ) )
		{
			reactionSystem.UnregisterReaction( m_reactionName );
		}
	}

	protected override function Deactivate( context : ScriptExecutionContext )
	{
		var reactionSystem : ReactionSystem;
		reactionSystem = GameInstance.GetReactionSystem( ScriptExecutionContext.GetOwner( context ).GetGame() );
		if( reactionSystem && m_onDeactivation )
		{
			reactionSystem.UnregisterReaction( m_reactionName );
		}
	}

}

class SetBackOffAnimFeature extends AIbehaviortaskScript
{

	protected override function Activate( context : ScriptExecutionContext )
	{
		var animFeature : AnimFeature_AIAction;
		animFeature = new AnimFeature_AIAction;
		animFeature.state = 1;
		AnimationControllerComponent.ApplyFeatureToReplicate( ScriptExecutionContext.GetOwner( context ), 'BackOffReaction', animFeature );
	}

	protected override function Deactivate( context : ScriptExecutionContext )
	{
		var animFeature : AnimFeature_AIAction;
		animFeature = new AnimFeature_AIAction;
		animFeature.state = 0;
		AnimationControllerComponent.ApplyFeatureToReplicate( ScriptExecutionContext.GetOwner( context ), 'BackOffReaction', animFeature );
	}

}

class SetBooleanArgumentWhenActive extends AIbehaviortaskScript
{
	editable var m_booleanArgument : CName;

	protected export override function Activate( context : ScriptExecutionContext )
	{
		ScriptExecutionContext.SetArgumentBool( context, m_booleanArgument, true );
	}

	protected export override function Deactivate( context : ScriptExecutionContext )
	{
		ScriptExecutionContext.SetArgumentBool( context, m_booleanArgument, false );
	}

}

class BodyInvestigated extends AIbehaviortaskScript
{

	protected override function Activate( context : ScriptExecutionContext )
	{
		ReactionManagerComponent.BodyInvestigated( GetPuppet( context ) );
	}

}

class TryStopMovingOnTrafficLane extends AIbehaviortaskScript
{

	protected export override function Activate( context : ScriptExecutionContext )
	{
		var ownerPuppet : ScriptedPuppet;
		ownerPuppet = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) );
		ownerPuppet.GetCrowdMemberComponent().TryStopTrafficMovement();
	}

}

class CrowdWalkAwayAfterCombat extends AIbehaviortaskScript
{

	protected override function Deactivate( context : ScriptExecutionContext )
	{
		var broadcaster : StimBroadcasterComponent;
		var ownerPuppet : ScriptedPuppet;
		ownerPuppet = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) );
		if( ownerPuppet && ownerPuppet.IsCrowd() )
		{
			broadcaster = GameInstance.GetPlayerSystem( ownerPuppet.GetGame() ).GetLocalPlayerControlledGameObject().GetStimBroadcasterComponent();
			broadcaster.SendDrirectStimuliToTarget( ScriptExecutionContext.GetOwner( context ), gamedataStimType.AreaEffect, ScriptExecutionContext.GetOwner( context ) );
		}
	}

}

