import enum AICommandState
{
	NotExecuting,
	Enqueued,
	Executing,
	Cancelled,
	Interrupted,
	Success,
	Failure,
}

import class AICommand extends IScriptable
{
	import const var id : Uint32;
	import const var state : AICommandState;

	public import function Copy() : AICommand;
	public import function GetCategory() : CName;
	public import function SetCategory( value : CName );
}

importonly abstract class AICommandFactory extends IScriptable
{
}

importonly abstract class AICommandParams extends AICommandFactory
{
}

importonly abstract class MiscAICommandNodeParams extends AICommandParams
{
}

import class ScriptedAICommandParams extends MiscAICommandNodeParams
{

	public export virtual function CreateCommand() : AICommand
	{
		return NULL;
	}

}

import struct worldTrafficLaneRef
{
	import var nodeRef : NodeRef;
	import var laneNumber : Uint16;
	import var isReversed : Bool;
}

import struct AIPositionSpec
{
	import var entity : weak< Entity >;
	import var worldPosition : WorldPosition;

	public import static function IsEmpty( position : AIPositionSpec ) : Bool;
	public import static function IsEntity( position : AIPositionSpec ) : Bool;
	public import static function IsWorldPosition( position : AIPositionSpec ) : Bool;
	public import static function GetEntity( position : AIPositionSpec ) : Entity;
	public import static function GetWorldPosition( position : AIPositionSpec ) : Vector4;
	public import static function SetEntity( aiPositionSpec : AIPositionSpec, entity : weak< Entity > );
	public import static function SetWorldPosition( aiPositionSpec : ref< AIPositionSpec >, position : WorldPosition );
}

import struct AIMovementTypeSpec
{
	import var useNPCMovementParams : Bool;
	import var movementType : moveMovementType;

	public import static function Resolve( spec : AIMovementTypeSpec, puppet : gamePuppet ) : moveMovementType;
}

import class AIMoveCommand extends AICommand
{
	import var removeAfterCombat : Bool;
	import var ignoreInCombat : Bool;
	import var alwaysUseStealth : Bool;
}

import class AIMoveToCommand extends AIMoveCommand
{
	import var movementTarget : AIPositionSpec;
	import var rotateEntityTowardsFacingTarget : Bool;
	import var facingTarget : AIPositionSpec;
	import var movementType : moveMovementType;
	import var ignoreNavigation : Bool;
	import var useStart : Bool;
	import var useStop : Bool;
	import var desiredDistanceFromTarget : Float;
	import var finishWhenDestinationReached : Bool;
}

class AICommsCallMoveToCommand extends AIMoveToCommand
{
}

enum ECompanionDistancePreset
{
	Medium = 0,
	Close = 1,
	Far = 2,
	VeryFar = 3,
}

enum ECompanionPositionPreset
{
	Behind = 0,
	InFront = 1,
}

import class AIMoveOnSplineCommand extends AIMoveCommand
{
	import var spline : NodeRef;
	import var movementType : AIMovementTypeSpec;
	import var rotateEntityTowardsFacingTarget : Bool;
	import var facingTarget : weak< GameObject >;
	import var shootingTarget : weak< GameObject >;
	import var companion : weak< GameObject >;
	import var desiredDistance : Float;
	import var deadZoneRadius : Float;
	import var catchUpWithCompanion : Bool;
	import var teleportToCompanion : Bool;
	import var useMatchForSpeedForPlayer : Bool;
	import var startFromClosestPoint : Bool;
	import var splineRecalculation : Bool;
	import var disableFootIK : Bool;
	import var ignoreNavigation : Bool;
	import var snapToTerrain : Bool;
	import var ignoreLineOfSightCheck : Bool;
	import var useAlertedState : Bool;
	import var useStart : Bool;
	import var useStop : Bool;
	import var reverse : Bool;
	import var useOMLReservation : Bool;
	import var useCombatState : Bool;
	import var allowCrowdOnPath : Bool;
	import var lookAtTarget : weak< GameObject >;
	import var minSearchAngle : Float;
	import var maxSearchAngle : Float;
	import var noWaitToEndDistance : Float;
	import var noWaitToEndCompanionDistance : Float;
	import var maxCompanionDistanceOnSpline : Float;
}

import class AIAnimMoveOnSplineCommand extends AIMoveCommand
{
	import var spline : NodeRef;
	import var useStart : Bool;
	import var useStop : Bool;
	import var controllerSetupName : CName;
	import var blendTime : Float;
	import var globalInBlendTime : Float;
	import var globalOutBlendTime : Float;
	import var turnCharacterToMatchVelocity : Bool;
	import var customStartAnimationName : CName;
	import var customMainAnimationName : CName;
	import var customStopAnimationName : CName;
	import var startSnapToTerrain : Bool;
	import var mainSnapToTerrain : Bool;
	import var stopSnapToTerrain : Bool;
	import var startSnapToTerrainBlendTime : Float;
	import var stopSnapToTerrainBlendTime : Float;
}

import class AIRotateToCommand extends AIMoveCommand
{
	import var target : AIPositionSpec;
	import var angleTolerance : Float;
	import var angleOffset : Float;
	import var speed : Float;
}

import class AIPatrolCommand extends AIMoveCommand
{
	import var pathParams : AIPatrolPathParameters;
	import var alertedPathParams : AIPatrolPathParameters;
	import var alertedRadius : Float;
	import var alertedSpots : array< NodeRef >;
	editable var patrolWithWeapon : Bool;
	[ customEditor = "TweakDBGroupInheritance;PatrolActions.AIPatrolActionComposite" ]
	editable var patrolAction : TweakDBID;
}

import class AIFollowTargetCommand extends AIMoveCommand
{
	import var target : weak< GameObject >;
	import var desiredDistance : Float;
	import var tolerance : Float;
	import var stopWhenDestinationReached : Bool;
	import var movementType : moveMovementType;
	import var lookAtTarget : weak< GameObject >;
	import var matchSpeed : Bool;
	import var teleport : Bool;
}

import class AIJoinCrowdCommand extends AIMoveCommand
{
}

import class AIRootMotionCommand extends AIMoveCommand
{
	import var params : SceneAnimationMotionActionParams;
}

import class AIAssignRestrictMovementAreaCommand extends AICommand
{
	import var restrictMovementAreaRef : NodeRef;
}

import class vehiclePortalsList extends IScriptable
{
	import var listPoints : array< NodeRef >;
}

importonly abstract class AIVehicleCommand extends AICommand
{
	import var useKinematic : Bool;
	import var needDriver : Bool;
}

import class vehicleAudioCurvesParam extends IScriptable
{
}

import class AIVehicleOnSplineCommand extends AIVehicleCommand
{
	import var splineRef : NodeRef;
	import var secureTimeOut : Float;
	import var driveBackwards : Bool;
	import var reverseSpline : Bool;
	import var startFromClosest : Bool;
	import var forcedStartSpeed : Float;
	import var stopAtPathEnd : Bool;
	import var keepDistanceBool : Bool;
	import var keepDistanceCompanion : weak< GameObject >;
	import var keepDistanceDistance : Float;
	import var rubberBandingBool : Bool;
	import var rubberBandingTargetRef : weak< GameObject >;
	import var rubberBandingTargetForwardOffset : Float;
	import var rubberBandingMinDistance : Float;
	import var rubberBandingMaxDistance : Float;
	import var rubberBandingStopAndWait : Bool;
	import var rubberBandingTeleportToCatchUp : Bool;
	import var rubberBandingStayInFront : Bool;
	import var audioCurvesParam : weak< vehicleAudioCurvesParam >;
}

import class AIVehicleFollowCommand extends AIVehicleCommand
{
	import var target : weak< GameObject >;
	import var secureTimeOut : Float;
	import var distanceMin : Float;
	import var distanceMax : Float;
	import var stopWhenTargetReached : Bool;
	import var useTraffic : Bool;
	import var trafficTryNeighborsForStart : Bool;
	import var trafficTryNeighborsForEnd : Bool;
}

import class AIVehicleChaseCommand extends AIVehicleCommand
{
	import var target : weak< GameObject >;
	import var distanceMin : Float;
	import var distanceMax : Float;
	import var forcedStartSpeed : Float;
	import var aggressiveRamming : Bool;
	import var ignoreChaseVehiclesLimit : Bool;
	import var boostDrivingStats : Bool;
}

import class AIVehiclePanicCommand extends AIVehicleCommand
{
	import var allowSimplifiedMovement : Bool;
	import var ignoreTickets : Bool;
	import var disableStuckDetection : Bool;
	import var useSpeedBasedLookupRange : Bool;
	import var tryDriveAwayFromPlayer : Bool;
}

import class AIVehicleDriveToPointAutonomousCommand extends AIVehicleCommand
{
	import var targetPosition : Vector3;
	import var maxSpeed : Float;
	import var minSpeed : Float;
	import var clearTrafficOnPath : Bool;
	import var minimumDistanceToTarget : Float;
	import var forcedStartSpeed : Float;
	import var driveDownTheRoadIndefinitely : Bool;
}

import class AIVehicleDrivePatrolCommand extends AIVehicleCommand
{
	import var maxSpeed : Float;
	import var minSpeed : Float;
	import var clearTrafficOnPath : Bool;
	import var emergencyPatrol : Bool;
	import var numPatrolLoops : Uint32;
	import var forcedStartSpeed : Float;
}

import class AIVehicleToNodeCommand extends AIVehicleCommand
{
	import var nodeRef : NodeRef;
	import var stopAtPathEnd : Bool;
	import var secureTimeOut : Float;
	import var isPlayer : Bool;
	import var useTraffic : Bool;
	import var speedInTraffic : Float;
	import var forceGreenLights : Bool;
	import var portals : vehiclePortalsList;
	import var trafficTryNeighborsForStart : Bool;
	import var trafficTryNeighborsForEnd : Bool;
	import var ignoreNoAIDrivingLanes : Bool;
}

import class AIVehicleRacingCommand extends AIVehicleCommand
{
	import var splineRef : NodeRef;
	import var secureTimeOut : Float;
	import var reverseSpline : Bool;
	import var driveBackwards : Bool;
	import var startFromClosest : Bool;
	import var rubberBandingBool : Bool;
	import var rubberBandingTargetRef : weak< GameObject >;
	import var rubberBandingTargetForwardOffset : Float;
	import var rubberBandingMinDistance : Float;
	import var rubberBandingMaxDistance : Float;
	import var rubberBandingStopAndWait : Bool;
	import var rubberBandingTeleportToCatchUp : Bool;
	import var rubberBandingStayInFront : Bool;
}

import class AIVehicleJoinTrafficCommand extends AIVehicleCommand
{
}

import enum gameSceneAnimationMotionActionParamsPlacementMode
{
	Blend,
	TeleportToStart,
	PlayAtActorPosition,
}

import class SceneAnimationMotionActionParams extends IScriptable
{
	import var animationName : CName;
	import var placementMode : gameSceneAnimationMotionActionParamsPlacementMode;
	import var placementTransform : WorldTransform;
	import var startTime : Float;
	import var endTime : Float;
	import var poseBlendInTime : Float;
}

import class AITeleportCommand extends AICommand
{
	import var position : Vector4;
	import var rotation : Float;
	import var doNavTest : Bool;
}

import abstract class AIBaseUseWorkspotCommand extends AICommand
{
	import var moveToWorkspot : Bool;
	import var forceEntryAnimName : CName;
	import var continueInCombat : Bool;
	editable var movementType : moveMovementType;
}

import class AIUseWorkspotCommand extends AIBaseUseWorkspotCommand
{
	import var workspotNode : NodeRef;
	import var jumpToEntry : Bool;
	import var entryId : WorkEntryId;
}

import class AIEquipCommand extends AICommand
{
	import var slotId : TweakDBID;
	import var itemId : TweakDBID;
	import var failIfItemNotFound : Bool;
	import var durationOverride : Float;
}

import class AIUnequipCommand extends AICommand
{
	import var slotId : TweakDBID;
	import var durationOverride : Float;
}

class AIAssignRoleCommand extends AICommand
{
	editable inlined var role : AIRole;
}

class AIAssignRoleCommandParams extends ScriptedAICommandParams
{
	editable inlined var role : AIRole;

	public constexpr export function GetCommandName() : String
	{
		return "Assign AI Role";
	}

	public export override function CreateCommand() : AICommand
	{
		var command : AIAssignRoleCommand;
		command = new AIAssignRoleCommand;
		command.role = role;
		return command;
	}

}

class AIClearRoleCommandParams extends ScriptedAICommandParams
{

	public constexpr export function GetCommandName() : String
	{
		return "Clear AI Role";
	}

	public override function CreateCommand() : AICommand
	{
		var command : AIAssignRoleCommand;
		command = new AIAssignRoleCommand;
		command.role = new AINoRole;
		return command;
	}

}

import class AICombatRelatedCommand extends AICommand
{
	import editable inlined var immediately : Bool;
}

import class AIUseCoverCommand extends AICombatRelatedCommand
{
	import editable inlined var coverNodeRef : NodeRef;
	import editable inlined var oneTimeSelection : Bool;
	import editable inlined var forcedEntryAnimation : CName;
	editable inlined var limitToTheseExposureMethods : CoverCommandParams;
}

class AISetCombatPresetCommand extends AICombatRelatedCommand
{
	editable inlined var combatPreset : EAICombatPreset;
}

class AISetCombatPresetCommandParams extends ScriptedAICommandParams
{
	editable inlined var combatPreset : EAICombatPreset;

	public constexpr export function GetCommandName() : String
	{
		return "Set Combat Preset";
	}

	public export override function CreateCommand() : AICommand
	{
		var command : AISetCombatPresetCommand;
		command = new AISetCombatPresetCommand;
		command.combatPreset = combatPreset;
		return command;
	}

}

class AIInjectCombatThreatCommand extends AICombatRelatedCommand
{
	editable inlined var targetNodeRef : NodeRef;
	editable inlined var targetPuppetRef : EntityReference;
	editable inlined var dontForceHostileAttitude : Bool;
	editable inlined var duration : Float;
	editable inlined var isPersistent : Bool;
}

class AIInjectCombatThreatCommandParams extends ScriptedAICommandParams
{
	editable inlined var targetNodeRef : NodeRef;
	[ customEditor = "scnbPerformerPuppetRefSelector" ]
	editable var targetPuppetRef : EntityReference;
	editable inlined var dontForceHostileAttitude : Bool;
	editable inlined var duration : Float;
	editable inlined var isPersistent : Bool;

	public constexpr export function GetCommandName() : String
	{
		return "Set Threat";
	}

	public override function CreateCommand() : AICommand
	{
		var command : AIInjectCombatThreatCommand;
		command = new AIInjectCombatThreatCommand;
		command.targetNodeRef = targetNodeRef;
		command.targetPuppetRef = targetPuppetRef;
		command.dontForceHostileAttitude = dontForceHostileAttitude;
		command.duration = duration;
		command.isPersistent = isPersistent;
		return command;
	}

}

class AIMeleeAttackCommand extends AICombatRelatedCommand
{
	editable inlined var targetOverrideNodeRef : NodeRef;
	editable inlined var targetOverridePuppetRef : EntityReference;
	editable inlined var duration : Float;
}

class AIMeleeAttackCommandParams extends ScriptedAICommandParams
{
	editable inlined var targetOverrideNodeRef : NodeRef;
	[ customEditor = "scnbPerformerPuppetRefSelector" ]
	editable inlined var targetOverridePuppetRef : EntityReference;
	editable inlined var duration : Float;
	default duration = -1.f;

	public constexpr function GetCommandName() : String
	{
		return "Melee Attack";
	}

	public override function CreateCommand() : AICommand
	{
		var command : AIMeleeAttackCommand;
		command = new AIMeleeAttackCommand;
		command.targetOverrideNodeRef = targetOverrideNodeRef;
		command.targetOverridePuppetRef = targetOverridePuppetRef;
		command.duration = duration;
		return command;
	}

}

import class AIInjectCombatTargetCommand extends AICombatRelatedCommand
{
	import editable inlined var targetNodeRef : NodeRef;
	import editable inlined var targetPuppetRef : EntityReference;
	import editable inlined var duration : Float;
}

import class AIInjectLookatTargetCommand extends AICombatRelatedCommand
{
	import editable inlined var targetNodeRef : NodeRef;
	import editable inlined var targetPuppetRef : EntityReference;
	import editable inlined var duration : Float;
}

import class AIThrowGrenadeCommand extends AICombatRelatedCommand
{
	import editable inlined var targetOverrideNodeRef : NodeRef;
	import editable inlined var targetOverridePuppetRef : EntityReference;
	import editable inlined var duration : Float;
	import editable inlined var once : Bool;
}

import class AIThrowGrenadeForcedCommand extends AIThrowGrenadeCommand
{
}

import class AIShootCommand extends AICombatRelatedCommand
{
	import editable inlined var targetOverrideNodeRef : NodeRef;
	import editable inlined var targetOverridePuppetRef : EntityReference;
	import editable inlined var duration : Float;
	import editable inlined var once : Bool;
}

class AIForceShootCommand extends AICombatRelatedCommand
{
	editable inlined var targetOverrideNodeRef : NodeRef;
	editable inlined var targetOverridePuppetRef : EntityReference;
	editable inlined var duration : Float;
}

class AIForceShootCommandParams extends ScriptedAICommandParams
{
	editable inlined var targetOverrideNodeRef : NodeRef;
	[ customEditor = "scnbPerformerPuppetRefSelector" ]
	editable inlined var targetOverridePuppetRef : EntityReference;
	editable inlined var duration : Float;
	default duration = -1.f;

	public constexpr export function GetCommandName() : String
	{
		return "Force Shoot";
	}

	public export override function CreateCommand() : AICommand
	{
		var command : AIForceShootCommand;
		command = new AIForceShootCommand;
		command.targetOverrideNodeRef = targetOverrideNodeRef;
		command.targetOverridePuppetRef = targetOverridePuppetRef;
		command.duration = duration;
		return command;
	}

}

class AIAimAtTargetCommand extends AICombatRelatedCommand
{
	editable inlined var targetOverrideNodeRef : NodeRef;
	editable inlined var targetOverridePuppetRef : EntityReference;
	editable inlined var duration : Float;
}

class AIAimAtTargetCommandParams extends ScriptedAICommandParams
{
	editable inlined var targetOverrideNodeRef : NodeRef;
	[ customEditor = "scnbPerformerPuppetRefSelector" ]
	editable inlined var targetOverridePuppetRef : EntityReference;
	editable inlined var duration : Float;
	default duration = -1.f;

	public constexpr function GetCommandName() : String
	{
		return "Aim at Target";
	}

	public override function CreateCommand() : AICommand
	{
		var command : AIAimAtTargetCommand;
		command = new AIAimAtTargetCommand;
		command.targetOverrideNodeRef = targetOverrideNodeRef;
		command.targetOverridePuppetRef = targetOverridePuppetRef;
		command.duration = duration;
		return command;
	}

}

import class AISwitchToPrimaryWeaponCommand extends AICommand
{
	import editable var unEquip : Bool;
}

import class AISwitchToSecondaryWeaponCommand extends AICommand
{
	import editable var unEquip : Bool;
}

class AIHoldPositionCommand extends AIMoveCommand
{
	editable var duration : Float;
}

class AIHoldPositionCommandParams extends ScriptedAICommandParams
{
	editable inlined var duration : Float;
	default duration = -1.f;

	public constexpr export function GetCommandName() : String
	{
		return "Hold Position";
	}

	public override function CreateCommand() : AICommand
	{
		var command : AIHoldPositionCommand;
		command = new AIHoldPositionCommand;
		command.duration = duration;
		return command;
	}

}

import class AIMoveToCoverCommand extends AIMoveCommand
{
	editable inlined var coverNodeRef : NodeRef;
	editable inlined var specialAction : ECoverSpecialAction;
}

class AIMoveToCoverCommandParams extends ScriptedAICommandParams
{
	editable inlined var coverNodeRef : NodeRef;
	editable inlined var alwaysUseStealth : Bool;
	editable inlined var specialAction : ECoverSpecialAction;

	public constexpr export function GetCommandName() : String
	{
		return "Move To Cover";
	}

	public export override function CreateCommand() : AICommand
	{
		var command : AIMoveToCoverCommand;
		command = new AIMoveToCoverCommand;
		command.coverNodeRef = coverNodeRef;
		command.alwaysUseStealth = alwaysUseStealth;
		command.specialAction = specialAction;
		return command;
	}

}

class AIStopCoverCommand extends AICommand
{
}

class AIStopCoverCommandParams extends ScriptedAICommandParams
{

	public constexpr export function GetCommandName() : String
	{
		return "Stop Cover";
	}

	public export override function CreateCommand() : AICommand
	{
		var command : AIStopCoverCommand;
		command = new AIStopCoverCommand;
		return command;
	}

}

class AIJoinTargetsSquad extends AICommand
{
	editable inlined var targetPuppetRef : EntityReference;
}

class AIJoinTargetsSquadCommandParams extends ScriptedAICommandParams
{
	editable inlined var targetPuppetRef : EntityReference;

	public constexpr export function GetCommandName() : String
	{
		return "Join Target's Squad";
	}

	public override function CreateCommand() : AICommand
	{
		var command : AIJoinTargetsSquad;
		command = new AIJoinTargetsSquad;
		command.targetPuppetRef = targetPuppetRef;
		return command;
	}

}

class AIFollowerCommand extends AICommand
{
	var combatCommand : Bool;

	public final function IsCombatCommand() : Bool
	{
		return combatCommand;
	}

}

class AIFollowerCombatCommand extends AIFollowerCommand
{
	default combatCommand = true;
}

class AIFollowerTakedownCommand extends AIFollowerCommand
{
	editable inlined var targetRef : EntityReference;
	editable inlined var approachBeforeTakedown : Bool;
	editable inlined var doNotTeleportIfTargetIsVisible : Bool;
	var target : weak< GameObject >;
}

class AIFollowerTakedownCommandParams extends ScriptedAICommandParams
{
	[ customEditor = "scnbPerformerPuppetRefSelector" ]
	editable inlined var targetRef : EntityReference;
	editable inlined var approachBeforeTakedown : Bool;
	editable inlined var doNotTeleportIfTargetIsVisible : Bool;

	public constexpr export function GetCommandName() : String
	{
		return "Takedown";
	}

	public export override function CreateCommand() : AICommand
	{
		var command : AIFollowerTakedownCommand;
		command = new AIFollowerTakedownCommand;
		command.targetRef = targetRef;
		command.approachBeforeTakedown = approachBeforeTakedown;
		command.doNotTeleportIfTargetIsVisible = doNotTeleportIfTargetIsVisible;
		return command;
	}

}

class AIFollowerDeviceCommand extends AIFollowerCommand
{
	var target : weak< GameObject >;
	var overrideMovementTarget : weak< GameObject >;
}

class AIFlatheadSetSoloModeCommand extends AIFollowerCommand
{
	editable inlined var soloModeState : Bool;
}

class AIFlatheadSetSoloModeCommandParams extends ScriptedAICommandParams
{
	editable inlined var soloMode : Bool;

	public constexpr function GetCommandName() : String
	{
		return "Flathead Set Solo Mode";
	}

	public override function CreateCommand() : AICommand
	{
		var command : AIFlatheadSetSoloModeCommand;
		command = new AIFlatheadSetSoloModeCommand;
		command.soloModeState = soloMode;
		return command;
	}

}

class CommandSignal extends TaggedSignalUserData
{
	var track : Bool;
	var commandClassNames : array< CName >;
}

class AIScanTargetCommand extends AICommand
{
	editable inlined var targetPuppetRef : EntityReference;
}

class AIScanTargetCommandParams extends ScriptedAICommandParams
{
	editable inlined var targetPuppetRef : EntityReference;

	public constexpr function GetCommandName() : String
	{
		return "Scan Target";
	}

	public override function CreateCommand() : AICommand
	{
		var command : AIScanTargetCommand;
		command = new AIScanTargetCommand;
		command.targetPuppetRef = targetPuppetRef;
		return command;
	}

}

class AIRoadBlockadeMemberCommand extends AICombatRelatedCommand
{
	editable inlined var duration : Float;
}

class AIRoadBlockadeMemberCommandParams extends ScriptedAICommandParams
{
	editable inlined var duration : Float;

	public constexpr export function GetCommandName() : String
	{
		return "Road blockade member";
	}

	public override function CreateCommand() : AICommand
	{
		var command : AIRoadBlockadeMemberCommand;
		command = new AIRoadBlockadeMemberCommand;
		command.duration = duration;
		return command;
	}

}

