class AISquadHelper
{

	public static function GetSquadName( obj : weak< GameObject > ) : CName
	{
		var squadInterface : SquadScriptInterface;
		var squadName : CName;
		if( GetSquadMemberInterface( obj, squadInterface ) )
		{
			squadName = squadInterface.GetName();
		}
		return squadName;
	}

	public static function GetSquadmates( obj : weak< GameObject >, membersList : ref< array< weak< Entity > > >, optional dontRemoveSelf : Bool ) : Bool
	{
		var squadInterface : SquadScriptInterface;
		if( GetSquadMemberInterface( obj, squadInterface ) )
		{
			membersList = squadInterface.ListMembersWeak();
			if( !( dontRemoveSelf ) )
			{
				membersList.Remove( obj );
			}
		}
		return membersList.Size() > 0;
	}

	public static function GetSquadmatesID( obj : weak< GameObject >, out membersListID : array< EntityID >, optional dontRemoveSelf : Bool ) : Bool
	{
		var membersList : array< weak< Entity > >;
		var squadInterface : SquadScriptInterface;
		var i : Int32;
		if( GetSquadMemberInterface( obj, squadInterface ) )
		{
			membersList = squadInterface.ListMembersWeak();
			if( !( dontRemoveSelf ) )
			{
				membersList.Remove( obj );
			}
		}
		for( i = 0; i < membersList.Size(); i += 1 )
		{
			membersListID.PushBack( membersList[ i ].GetEntityID() );
		}
		return membersListID.Size() > 0;
	}

	public static function HasSquadMemberComponent( obj : weak< GameObject > ) : Bool
	{
		if( !( obj ) )
		{
			return false;
		}
		return obj.GetSquadMemberComponent();
	}

	public static function GetSquadMemberInterface( obj : weak< GameObject >, out squadInterface : SquadScriptInterface ) : Bool
	{
		if( obj && obj.GetSquadMemberComponent() )
		{
			squadInterface = obj.GetSquadMemberComponent().MySquad( AISquadType.Combat );
		}
		return squadInterface != NULL;
	}

	public static function GetCombatSquadInterface( obj : weak< GameObject >, out squadInterface : CombatSquadScriptInterface ) : Bool
	{
		if( obj && obj.GetSquadMemberComponent() )
		{
			squadInterface = ( ( CombatSquadScriptInterface )( obj.GetSquadMemberComponent().MySquad( AISquadType.Combat ) ) );
		}
		return squadInterface != NULL;
	}

	public static function GetSquadBaseInterface( obj : weak< GameObject >, out squadBaseInterface : PuppetSquadInterface ) : Bool
	{
		if( obj && obj.GetSquadMemberComponent() )
		{
			squadBaseInterface = ( ( PuppetSquadInterface )( obj.GetSquadMemberComponent().MySquad( AISquadType.Combat ) ) );
		}
		return squadBaseInterface != NULL;
	}

	public static function GetPlayerSquadInterface( obj : weak< GameObject >, out playerSquadInterface : PlayerSquadInterface ) : Bool
	{
		if( obj && obj.GetSquadMemberComponent() )
		{
			playerSquadInterface = ( ( PlayerSquadInterface )( obj.GetSquadMemberComponent().MySquad( AISquadType.Combat ) ) );
		}
		return playerSquadInterface != NULL;
	}

	public static function GetAllSquadMemberInterfaces( obj : weak< GameObject > ) : array< SquadScriptInterface >
	{
		return obj.GetSquadMemberComponent().MySquads();
	}

	public static function LeaveSquad( obj : weak< GameObject >, squadType : AISquadType ) : Bool
	{
		if( obj && obj.GetSquadMemberComponent() )
		{
			obj.GetSquadMemberComponent().MySquad( squadType ).Leave( obj );
			return true;
		}
		return false;
	}

	public static function LeaveAllSquads( obj : weak< GameObject > ) : Bool
	{
		var squads : array< SquadScriptInterface >;
		var i : Int32;
		if( obj && obj.GetSquadMemberComponent() )
		{
			squads = obj.GetSquadMemberComponent().MySquads();
			for( i = 0; i < squads.Size(); i += 1 )
			{
				squads[ i ].Leave( obj );
			}
			return true;
		}
		return false;
	}

	public static function PlayerSquadOrderStringToEnum( const playerSquadOrderName : ref< String > ) : EAIPlayerSquadOrder
	{
		switch( playerSquadOrderName )
		{
			case "OrderTakedown":
				return EAIPlayerSquadOrder.Takedown;
			default:
				return EAIPlayerSquadOrder.Invalid;
		}
	}

	public static function SendStimFromSquadTargetToMember( member : Entity, actionName : CName )
	{
		var puppet : ScriptedPuppet;
		var squadMembers : array< weak< Entity > >;
		var squadMember : ScriptedPuppet;
		var target : GameObject;
		var smi : SquadScriptInterface;
		var broadcaster : StimBroadcasterComponent;
		var i : Int32;
		puppet = ( ( ScriptedPuppet )( member ) );
		if( !( GetSquadmates( puppet, squadMembers ) ) )
		{
			return;
		}
		for( i = 0; i < squadMembers.Size(); i += 1 )
		{
			squadMember = ( ( ScriptedPuppet )( squadMembers[ i ] ) );
			target = squadMember.GetStimReactionComponent().GetActiveReactionData().stimTarget;
			if( target )
			{
				GetSquadMemberInterface( squadMember, smi );
				broadcaster = squadMember.GetStimBroadcasterComponent();
				if( smi.HasOrderBySquadAction( actionName, EntityGameInterface.GetEntity( squadMember.GetEntity() ) ) && broadcaster )
				{
					broadcaster.SendDrirectStimuliToTarget( puppet, gamedataStimType.Combat, target );
				}
			}
		}
	}

	public static function GetCurrentSquadRing( puppet : weak< ScriptedPuppet > ) : gamedataAIRingType
	{
		var ring : gamedataAIRingType;
		var blackboard : IBlackboard;
		if( !( puppet ) )
		{
			return gamedataAIRingType.Invalid;
		}
		blackboard = AICoverHelper.GetCoverBlackboard( puppet );
		ring = ( ( gamedataAIRingType )( blackboard.GetVariant( GetAllBlackboardDefs().AICover.currentRing ) ) );
		if( ring != gamedataAIRingType.Invalid )
		{
			return ring;
		}
		ring = ( ( gamedataAIRingType )( blackboard.GetVariant( GetAllBlackboardDefs().AICover.lastCoverRing ) ) );
		return ring;
	}

	public static function SquadRingTypeToTicketName( type : gamedataAIRingType ) : CName
	{
		switch( type )
		{
			case gamedataAIRingType.Melee:
				return 'MeleeRing';
			case gamedataAIRingType.Close:
				return 'CloseRing';
			case gamedataAIRingType.Medium:
				return 'MediumRing';
			case gamedataAIRingType.Far:
				return 'FarRing';
			case gamedataAIRingType.Extreme:
				return 'ExtremeRing';
			case gamedataAIRingType.Default:
				return 'DefaultRing';
			default:
				return 'DefaultRing';
		}
	}

	public static function SquadRingTypeToTicketString( type : gamedataAIRingType ) : String
	{
		switch( type )
		{
			case gamedataAIRingType.Melee:
				return "MeleeRing";
			case gamedataAIRingType.Close:
				return "CloseRing";
			case gamedataAIRingType.Medium:
				return "MediumRing";
			case gamedataAIRingType.Far:
				return "FarRing";
			case gamedataAIRingType.Extreme:
				return "ExtremeRing";
			case gamedataAIRingType.Default:
				return "DefaultRing";
			default:
				return "DefaultRing";
		}
	}

	public static function NotifySquadOnIncapacitated( puppet : weak< ScriptedPuppet > )
	{
		var squadmates : array< weak< Entity > >;
		var squadmate : weak< ScriptedPuppet >;
		var i : Int32;
		if( GetSquadmates( puppet, squadmates, true ) )
		{
			for( i = 0; i < squadmates.Size(); i += 1 )
			{
				squadmate = ( ( weak< weak< ScriptedPuppet > > )( squadmates[ i ] ) );
				if( squadmate )
				{
					ScriptedPuppet.SendActionSignal( squadmate, 'RecentIncapacitationInSquad', 15.0 );
				}
			}
		}
	}

	public static function RemoveThreatFromSquad( puppet : weak< ScriptedPuppet >, const threat : ref< TrackedLocation > )
	{
		var squadmates : array< weak< Entity > >;
		var squadmate : weak< ScriptedPuppet >;
		var i : Int32;
		if( !( puppet ) )
		{
			return;
		}
		if( GetSquadmates( puppet, squadmates, true ) )
		{
			for( i = 0; i < squadmates.Size(); i += 1 )
			{
				squadmate = ( ( weak< weak< ScriptedPuppet > > )( squadmates[ i ] ) );
				if( squadmate )
				{
					RemoveThreatOnSquadmate( puppet.GetGame(), squadmate, threat );
				}
			}
		}
	}

	public static function RemoveThreatOnSquadmate( game : GameInstance, squadmate : weak< ScriptedPuppet >, const threat : ref< TrackedLocation > )
	{
		var tte : TargetTrackingExtension;
		if( !( squadmate ) || !( GameInstance.IsValid( game ) ) )
		{
			return;
		}
		tte = ( ( TargetTrackingExtension )( squadmate.GetTargetTrackerComponent() ) );
		if( tte )
		{
			tte.RemoveThreat( tte.MapThreat( threat.entity ) );
			tte.SetRecentlyDroppedThreat( threat.entity, threat.sharedLocation.position );
		}
	}

	public static function GetThreatLocationFromSquad( puppet : weak< ScriptedPuppet >, threat : weak< Entity >, threatLocation : ref< TrackedLocation > ) : Bool
	{
		var squadmates : array< weak< Entity > >;
		var squadmate : weak< ScriptedPuppet >;
		var i : Int32;
		if( !( puppet ) || !( threat ) )
		{
			return false;
		}
		if( GetSquadmates( puppet, squadmates ) )
		{
			for( i = 0; i < squadmates.Size(); i += 1 )
			{
				squadmate = ( ( weak< weak< ScriptedPuppet > > )( squadmates[ i ] ) );
				if( squadmate )
				{
					if( GeThreatLocationFromSquadmate( squadmate, threat, threatLocation ) )
					{
						return true;
					}
				}
			}
		}
		return false;
	}

	public static function GeThreatLocationFromSquadmate( squadmate : weak< ScriptedPuppet >, threat : weak< Entity >, threatLocation : ref< TrackedLocation > ) : Bool
	{
		var tte : TargetTrackingExtension;
		var allThreats : array< TrackedLocation >;
		var i : Int32;
		if( !( squadmate ) || !( threat ) )
		{
			return false;
		}
		tte = ( ( TargetTrackingExtension )( squadmate.GetTargetTrackerComponent() ) );
		if( tte )
		{
			allThreats = tte.GetThreats( false );
			for( i = 0; i < allThreats.Size(); i += 1 )
			{
				if( allThreats[ i ].entity == threat )
				{
					threatLocation = allThreats[ i ];
					return true;
				}
			}
		}
		return false;
	}

	public static function PullSquadSync( puppet : weak< ScriptedPuppet >, squadType : AISquadType )
	{
		var squadmates : array< weak< Entity > >;
		var squadmate : weak< ScriptedPuppet >;
		var i : Int32;
		var currentTopThreat : TrackedLocation;
		var targetTrackerComponent : TargetTrackerComponent;
		var isPuppetPolice : Bool;
		isPuppetPolice = NPCManager.HasTag( puppet.GetRecordID(), 'InActivePoliceChase' );
		if( !( puppet ) )
		{
			return;
		}
		targetTrackerComponent = puppet.GetTargetTrackerComponent();
		if( targetTrackerComponent )
		{
			targetTrackerComponent.GetTopHostileThreat( false, currentTopThreat );
		}
		if( GetSquadmates( puppet, squadmates, true ) )
		{
			for( i = 0; i < squadmates.Size(); i += 1 )
			{
				squadmate = ( ( weak< weak< ScriptedPuppet > > )( squadmates[ i ] ) );
				if( squadmate )
				{
					if( isPuppetPolice )
					{
						if( Vector4.Distance( puppet.GetWorldPosition(), squadmate.GetWorldPosition() ) < 60.0 )
						{
							PullSquadSyncOnSquadmate( puppet.GetGame(), squadmate, squadType, currentTopThreat.entity );
						}
					}
					else
					{
						PullSquadSyncOnSquadmate( puppet.GetGame(), squadmate, squadType, currentTopThreat.entity );
					}
				}
			}
		}
	}

	public static function PullSquadSyncOnSquadmate( game : GameInstance, squadmate : weak< ScriptedPuppet >, squadType : AISquadType, currentTopThreat : weak< Entity > )
	{
		var tte : TargetTrackingExtension;
		var threatData : DroppedThreatData;
		if( !( squadmate ) || !( GameInstance.IsValid( game ) ) )
		{
			return;
		}
		tte = ( ( TargetTrackingExtension )( squadmate.GetTargetTrackerComponent() ) );
		if( !( tte ) )
		{
			return;
		}
		threatData = tte.GetRecentlyDroppedThreat();
		if( threatData.threat && ( threatData.threat == currentTopThreat ) )
		{
			return;
		}
		tte.PullSquadSync( squadType );
	}

	public static function IsSignalActive( owner : weak< ScriptedPuppet >, signalName : CName ) : Bool
	{
		var signalTable : gameBoolSignalTable;
		var signalId : Uint16;
		if( !( IsNameValid( signalName ) ) )
		{
			return false;
		}
		signalTable = owner.GetSignalTable();
		if( !( signalTable ) )
		{
			return false;
		}
		signalId = signalTable.GetOrCreateSignal( signalName );
		if( !( signalTable.GetCurrentValue( signalId ) ) )
		{
			return false;
		}
		return true;
	}

	public static function EnterAlerted( owner : weak< ScriptedPuppet > )
	{
		var membersList : array< weak< Entity > >;
		var puppet : weak< ScriptedPuppet >;
		var i : Int32;
		if( owner.IsCharacterCivilian() || owner.IsCrowd() )
		{
			return;
		}
		if( !( AISquadHelper.GetSquadmates( owner, membersList ) ) )
		{
			return;
		}
		for( i = 0; i < membersList.Size(); i += 1 )
		{
			puppet = ( ( ScriptedPuppet )( membersList[ i ] ) );
			if( !( puppet ) )
			{
				continue;
			}
			if( puppet.IsCharacterCivilian() || puppet.IsCrowd() )
			{
				return;
			}
			if( puppet.GetHighLevelStateFromBlackboard() == gamedataNPCHighLevelState.Relaxed )
			{
				NPCPuppet.ChangeHighLevelState( puppet, gamedataNPCHighLevelState.Alerted );
			}
		}
	}

}

abstract class AIScriptSquad extends IScriptable
{

	public static function GetBaseSquadRecord( out squadRecord : weak< AISquadParams_Record > ) : Bool
	{
		var tweakID : TweakDBID;
		if( !( squadRecord ) )
		{
			tweakID = TDBID.Create( TDB.GetString( T"AIGeneralSettings.baseSquadParamsID" ) );
			squadRecord = TweakDBInterface.GetAISquadParamsRecord( tweakID );
		}
		return squadRecord != NULL;
	}

	public static function GetSquadRecord( entity : weak< Entity >, out squadRecord : weak< AISquadParams_Record > ) : Bool
	{
		var puppet : weak< ScriptedPuppet >;
		var chr : weak< Character_Record >;
		puppet = ( ( ScriptedPuppet )( entity ) );
		if( puppet )
		{
			chr = TweakDBInterface.GetCharacterRecord( puppet.GetRecordID() );
			if( chr )
			{
				squadRecord = chr.SquadParamsID();
			}
		}
		return squadRecord != NULL;
	}

	public static function GetTicketRecord( ticketName : CName, squadRecord : weak< AISquadParams_Record >, out ticketRecord : weak< AITicket_Record > ) : Bool
	{
		var i : Int32;
		var count : Int32;
		var ticket : AITicket_Record;
		count = squadRecord.GetOverridenTicketsCount();
		for( i = 0; i < count; i += 1 )
		{
			ticket = squadRecord.GetOverridenTicketsItem( i );
			if( ticketName == ticket.TicketType().EnumName() )
			{
				ticketRecord = ticket;
				return true;
			}
		}
		count = squadRecord.GetAllTicketsCount();
		for( i = 0; i < count; i += 1 )
		{
			ticket = squadRecord.GetAllTicketsItem( i );
			if( ticketName == ticket.TicketType().EnumName() )
			{
				ticketRecord = ticket;
				return true;
			}
		}
		return false;
	}

	public static function TicketDebugHelper( const ticketNameCheck : ref< String >, entity : weak< Entity >, ticketRecord : weak< AITicket_Record > ) : Bool
	{
		var ticketName : String;
		if( IsFinal() )
		{
			return false;
		}
		if( entity || IsStringValid( ticketNameCheck ) )
		{
			if( IsStringValid( ticketNameCheck ) )
			{
				ticketName = NameToString( ticketRecord.TicketType().EnumName() );
				if( StrContains( ticketName, ticketNameCheck ) )
				{
					if( ( ( GameObject )( entity ) ) )
					{
						if( ( ( GameObject )( entity ) ).IsSelectedForDebugging() )
						{
							return true;
						}
						return false;
					}
					return true;
				}
				return false;
			}
			if( ( ( GameObject )( entity ) ) )
			{
				if( ( ( GameObject )( entity ) ).IsSelectedForDebugging() )
				{
					return true;
				}
				return false;
			}
		}
		return false;
	}

	public static function CanPerformTicket( const context : ScriptExecutionContext, actionType : weak< AITicketType_Record > ) : Bool
	{
		if( HasOrder( context, actionType.EnumName() ) )
		{
			return true;
		}
		return false;
	}

	public static function OpenTicket( const context : ScriptExecutionContext, actionType : weak< AITicketType_Record > )
	{
		SignalSquad( context, actionType.EnumName(), EAISquadVerb.OpenSquadAction );
	}

	public static function CommitToTicket( const context : ScriptExecutionContext, actionType : weak< AITicketType_Record > )
	{
		SignalSquad( context, actionType.EnumName(), EAISquadVerb.CommitToSquadAction );
	}

	public static function CompleteTicket( const context : ScriptExecutionContext, actionType : weak< AITicketType_Record > )
	{
		SignalSquad( context, actionType.EnumName(), EAISquadVerb.ReportDoneOnSquadAction );
	}

	public static function FailTicket( const context : ScriptExecutionContext, actionType : weak< AITicketType_Record > )
	{
		SignalSquad( context, actionType.EnumName(), EAISquadVerb.ReportFailureOnSquadAction );
	}

	public static function CloseTicket( const context : ScriptExecutionContext, actionType : weak< AITicketType_Record > )
	{
		SignalSquad( context, actionType.EnumName(), EAISquadVerb.RevokeSquadAction );
	}

	public static function RevokeTicket( const context : ScriptExecutionContext, actionType : weak< AITicketType_Record > )
	{
		SignalSquad( context, actionType.EnumName(), EAISquadVerb.RevokeOrder );
	}

	public static function EvaluateTicketActivation( const context : ScriptExecutionContext, actionType : weak< AITicketType_Record > )
	{
		SignalSquad( context, actionType.EnumName(), EAISquadVerb.EvaluateTicketActivation );
	}

	public static function EvaluateTicketDeactivation( const context : ScriptExecutionContext, actionType : weak< AITicketType_Record > )
	{
		SignalSquad( context, actionType.EnumName(), EAISquadVerb.EvaluateTicketDeactivation );
	}

	[ profile = "" ]
	public static function HasOrder( const context : ScriptExecutionContext, ticketName : CName ) : Bool
	{
		var smi : SquadScriptInterface;
		var puppet : ScriptedPuppet;
		puppet = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) );
		if( !( AISquadHelper.GetSquadMemberInterface( puppet, smi ) ) )
		{
			return true;
		}
		if( smi.HasOrderBySquadAction( ticketName, puppet ) )
		{
			return true;
		}
		return false;
	}

	public static function HasOrder( puppet : weak< ScriptedPuppet >, ticketName : CName ) : Bool
	{
		var smi : SquadScriptInterface;
		if( !( AISquadHelper.GetSquadMemberInterface( puppet, smi ) ) )
		{
			return true;
		}
		if( smi.HasOrderBySquadAction( ticketName, puppet ) )
		{
			return true;
		}
		return false;
	}

	public static function SignalSquad( const context : ScriptExecutionContext, actionName : CName, verb : EAISquadVerb )
	{
		var puppet : ScriptedPuppet;
		puppet = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) );
		if( puppet )
		{
			puppet.HandleSquadAction( actionName, verb );
		}
	}

	[ profile = "" ]
	public static function CheckTickets( const context : ScriptExecutionContext, actionRecord : weak< AIAction_Record > ) : Bool
	{
		var i : Int32;
		var count : Int32;
		var smi : SquadScriptInterface;
		var scriptedOwner : ScriptedPuppet;
		scriptedOwner = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) );
		if( !( AISquadHelper.GetSquadMemberInterface( scriptedOwner, smi ) ) )
		{
			return true;
		}
		count = actionRecord.GetTicketsCount();
		for( i = 0; i < count; i += 1 )
		{
			if( !( smi.HasOrderBySquadAction( actionRecord.GetTicketsItem( i ).EnumName(), scriptedOwner ) ) )
			{
				return false;
			}
		}
		return true;
	}

	public static function CloseTickets( const context : ScriptExecutionContext, actionRecord : weak< AIAction_Record > )
	{
		var i : Int32;
		var count : Int32;
		var puppet : ScriptedPuppet;
		var squadMemberComp : SquadMemberBaseComponent;
		puppet = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) );
		if( !( puppet ) )
		{
			return;
		}
		squadMemberComp = puppet.GetSquadMemberComponent();
		count = actionRecord.GetTicketsCount();
		for( i = 0; i < count; i += 1 )
		{
			squadMemberComp.PerformSquadVerb( actionRecord.GetTicketsItem( i ).EnumName(), EAISquadVerb.RevokeSquadAction );
		}
	}

	public static function RevokeTickets( const context : ScriptExecutionContext, actionRecord : weak< AIAction_Record > )
	{
		var i : Int32;
		var count : Int32;
		var puppet : ScriptedPuppet;
		var squadMemberComp : SquadMemberBaseComponent;
		puppet = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) );
		if( !( puppet ) )
		{
			return;
		}
		squadMemberComp = puppet.GetSquadMemberComponent();
		count = actionRecord.GetTicketsCount();
		for( i = 0; i < count; i += 1 )
		{
			squadMemberComp.PerformSquadVerb( actionRecord.GetTicketsItem( i ).EnumName(), EAISquadVerb.RevokeOrder );
		}
	}

	public static function RequestTickets( const context : ScriptExecutionContext, actionRecord : weak< AIAction_Record > )
	{
		var i : Int32;
		var count : Int32;
		var ticketName : CName;
		var puppet : ScriptedPuppet;
		var squadMemberComp : SquadMemberBaseComponent;
		puppet = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) );
		if( !( puppet ) )
		{
			return;
		}
		squadMemberComp = puppet.GetSquadMemberComponent();
		count = actionRecord.GetTicketsCount();
		for( i = 0; i < count; i += 1 )
		{
			ticketName = actionRecord.GetTicketsItem( i ).EnumName();
			squadMemberComp.PerformSquadVerb( ticketName, EAISquadVerb.OpenSquadAction );
			squadMemberComp.PerformSquadVerb( ticketName, EAISquadVerb.EvaluateTicketActivation );
		}
	}

	public static function EvaluateTicketsActivation( const context : ScriptExecutionContext, actionRecord : weak< AIAction_Record > )
	{
		var i : Int32;
		var count : Int32;
		var puppet : ScriptedPuppet;
		var squadMemberComp : SquadMemberBaseComponent;
		puppet = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) );
		if( !( puppet ) )
		{
			return;
		}
		squadMemberComp = puppet.GetSquadMemberComponent();
		count = actionRecord.GetTicketsCount();
		for( i = 0; i < count; i += 1 )
		{
			squadMemberComp.PerformSquadVerb( actionRecord.GetTicketsItem( i ).EnumName(), EAISquadVerb.EvaluateTicketActivation );
		}
	}

	[ profile = "" ]
	public static function EvaluateTicketsDeactivation( const context : ScriptExecutionContext, actionRecord : weak< AIAction_Record > )
	{
		var i : Int32;
		var count : Int32;
		var puppet : ScriptedPuppet;
		var squadMemberComp : SquadMemberBaseComponent;
		puppet = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) );
		if( !( puppet ) )
		{
			return;
		}
		squadMemberComp = puppet.GetSquadMemberComponent();
		count = actionRecord.GetTicketsCount();
		for( i = 0; i < count; i += 1 )
		{
			squadMemberComp.PerformSquadVerb( actionRecord.GetTicketsItem( i ).EnumName(), EAISquadVerb.EvaluateTicketDeactivation );
		}
	}

	public static function CommitToTickets( const context : ScriptExecutionContext, actionRecord : weak< AIAction_Record > )
	{
		var i : Int32;
		var count : Int32;
		var puppet : ScriptedPuppet;
		var squadMemberComp : SquadMemberBaseComponent;
		puppet = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) );
		if( !( puppet ) )
		{
			return;
		}
		squadMemberComp = puppet.GetSquadMemberComponent();
		count = actionRecord.GetTicketsCount();
		for( i = 0; i < count; i += 1 )
		{
			squadMemberComp.PerformSquadVerb( actionRecord.GetTicketsItem( i ).EnumName(), EAISquadVerb.CommitToSquadAction );
		}
	}

	public static function CompleteTickets( const context : ScriptExecutionContext, actionRecord : weak< AIAction_Record >, succeed : Bool )
	{
		var i : Int32;
		var count : Int32;
		var puppet : ScriptedPuppet;
		var squadMemberComp : SquadMemberBaseComponent;
		puppet = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) );
		if( !( puppet ) )
		{
			return;
		}
		squadMemberComp = puppet.GetSquadMemberComponent();
		count = actionRecord.GetTicketsCount();
		for( i = 0; i < count; i += 1 )
		{
			if( succeed )
			{
				squadMemberComp.PerformSquadVerb( actionRecord.GetTicketsItem( i ).EnumName(), EAISquadVerb.ReportDoneOnSquadAction );
			}
			else
			{
				squadMemberComp.PerformSquadVerb( actionRecord.GetTicketsItem( i ).EnumName(), EAISquadVerb.ReportFailureOnSquadAction );
			}
		}
	}

	public static function WaitForTicketsAcknowledgement( const context : ScriptExecutionContext, actionRecord : weak< AIAction_Record > ) : Bool
	{
		var i : Int32;
		var count : Int32;
		var smi : SquadScriptInterface;
		var puppet : ScriptedPuppet;
		var ticketName : CName;
		count = actionRecord.GetTicketsCount();
		if( count > 0 )
		{
			puppet = ( ( ScriptedPuppet )( ScriptExecutionContext.GetOwner( context ) ) );
			if( !( AISquadHelper.GetSquadMemberInterface( puppet, smi ) ) )
			{
				return true;
			}
			for( i = 0; i < count; i += 1 )
			{
				ticketName = actionRecord.GetTicketsItem( i ).EnumName();
				if( !( smi.HasOrderBySquadAction( ticketName, puppet ) ) )
				{
					continue;
				}
				if( !( smi.HasAcknowledgedOrderBySquadAction( ticketName, puppet ) ) )
				{
					return true;
				}
			}
		}
		return false;
	}

}

