/***********************************************************************/
/** Witcher Script file
/***********************************************************************/
/** IAIActions
/** Copyright © 2013
/***********************************************************************/

////////////////////////////////////////////////////////////
abstract class IAIBaseAction extends IAIActionTree 
{
	editable var enterExplorationOnStart : bool;
	
	default enterExplorationOnStart = true;
};

////////////////////////////////////////////////////////////
class CAIFollowAction extends IAIBaseAction
{
	editable inlined var params : CAIFollowParams;
	
	default aiTreeName = "resdef:ai\scripted_actions/follow";

	function Init()
	{
		params = new CAIFollowParams in this;
		params.OnCreated();
	}
};

class CAIFollowParams extends IAIActionParameters
{
	// !!! Warning !!!
	// If you consider making changes to CAIFollowParams
	// please consider updating CAIRiderFollowActionParams  
	editable var targetTag 				: CName;
	editable var moveType 				: EMoveType;
	editable var keepDistance 			: bool;
	editable var followDistance 		: float;
	editable var moveSpeed 				: float;
	editable var followTargetSelection 	: bool;
	editable var teleportToCatchup		: bool;
	editable var cachupDistance			: float;
	editable var rotateToWhenAtTarget	: bool;	
	

	default targetTag 				= "PLAYER";
	default moveType 				= MT_Walk;
	default moveSpeed 				= 1.0;
	default followDistance 			= 2.0;
	default keepDistance 			= true;
	default followTargetSelection 	= true;
	default teleportToCatchup		= false;
	default cachupDistance			= 75.0;
	default rotateToWhenAtTarget	= true;
	
	hint rotateToWhenAtTarget = "After reaching the follow distance, NPC will rotate towards the target";
	
	function Init()
	{
		super.Init();
	}
};

////////////////////////////////////////////////////////////
// CAIFollowSideBySideAction
class CAIFollowSideBySideAction extends CAIFollowAction
{
	function Init()
	{
		super.Init();		
		customSteeringGraph 	= LoadSteeringGraph( "gameplay/behaviors/npc/steering/action/follow_side_by_side.w2steer" );
		params.followDistance 	= 0.25;
		params.moveType 		= MT_Sprint;
	}
	
	editable var useCustomSteering		: bool;
	editable var customSteeringGraph	: CMoveSteeringBehavior;
	
	default useCustomSteering 	= true;
};

////////////////////////////////////////////////////////////
// CAIRiderFollowAction
class CAIRiderFollowAction extends IRiderActionTree
{
	editable inlined var params 		: CAIRiderFollowActionParams;
	
	default aiTreeName = "resdef:ai\scripted_actions/rider_follow";

	function Init()
	{
		params = new CAIRiderFollowActionParams in this;
		params.OnCreated();
	}
};
////////////////////////////////////////////////////////////
// CAIRiderFollowActionParams
class CAIRiderFollowActionParams extends IRiderActionParameters
{
	editable var targetTag 				: CName;
	editable var moveType 				: EMoveType;
	editable var keepDistance 			: bool;
	editable var followDistance 		: float;
	editable var moveSpeed 				: float;
	editable var followTargetSelection 	: bool;
	editable var matchRiderMountStatus	: bool;
	
	default targetTag 				= "PLAYER";
	default moveType 				= MT_Walk;
	default moveSpeed 				= 1.0;
	default followDistance 			= 2.0;
	default keepDistance 			= true;
	default followTargetSelection 	= true;
	default matchRiderMountStatus	= true;
	
	//editable var horseActionTree		: IAIActionTree;
	function Init()
	{
		super.Init();
		followTargetSelection 	= false;		
	}
	
	// Using copy to because:
	// It is not possible to put all params in a common class because it 
	// would reset all existing move to in the world
	function CopyTo( followParams : CAIFollowParams )
	{
		followParams.targetTag 				= targetTag;
		followParams.moveType 				= moveType;
		followParams.keepDistance 			= keepDistance;
		followParams.followDistance 		= followDistance;
		followParams.moveSpeed 				= moveSpeed;
		// not followTargetSelection because it is different for horse
	}
};


////////////////////////////////////////////////////////////
// CAIRiderFollowSideBySideAction
class CAIRiderFollowSideBySideAction extends IRiderActionTree
{

	
	editable inlined var params 		: CAIRiderFollowSideBySideActionParams;
	
	default aiTreeName = "resdef:ai\scripted_actions/rider_follow_side_by_side";

	function Init()
	{
		params = new CAIRiderFollowSideBySideActionParams in this;
		params.OnCreated();
	}
};

////////////////////////////////////////////////////////////
// CAIRiderFollowSideBySideActionParams
class CAIRiderFollowSideBySideActionParams extends CAIRiderFollowActionParams
{		
	editable var useCustomSteering			: bool;
	editable var customSteeringGraph		: CMoveSteeringBehavior;
	editable var horseCustomSteeringGraph	: CMoveSteeringBehavior;
	
	default useCustomSteering 			= true;
	
	function Init()
	{
		customSteeringGraph 		= LoadSteeringGraph( "gameplay/behaviors/npc/steering/action/follow_side_by_side.w2steer" );
		horseCustomSteeringGraph 	= LoadSteeringGraph( "gameplay/behaviors/npc/steering/action/horse_follow_side_by_side.w2steer" );
		followDistance 				= 0.0;
		moveType 					= MT_Sprint;
		
		super.Init();	
	}
	
	// Using copy to because:
	// It is not possible to put all params in a common class because it 
	// would reset all existing move to in the world
	function CopyTo_SideBySide( followSideBySideAction : CAIFollowSideBySideAction )
	{
		super.CopyTo( followSideBySideAction.params );
		// Disable target selection and set the target manually
		followSideBySideAction.useCustomSteering 		= true;
		followSideBySideAction.customSteeringGraph 		= horseCustomSteeringGraph;
	}
};


////////////////////////////////////////////////////////////
class CAIHorseDoNothingAction extends IAIActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/horse_do_nothing";
};

////////////////////////////////////////////////////////////
class CAIDoNothingAction extends IAIActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/horse_do_nothing";
};

////////////////////////////////////////////////////////////
// CAIMoveAlongPathAction
class CAIMoveAlongPathAction extends IAIBaseAction
{	
	editable inlined var params : CAIMoveAlongPathParams;
	
	default aiTreeName = "resdef:ai\scripted_actions/move_along_path";
	
	function Init()
	{
		params = new CAIMoveAlongPathParams in this;
		params.OnCreated();
	}
	function OnPostLoad() : bool
	{
		if ( params && !params.steeringGraph )
		{
			params.steeringGraph = LoadSteeringGraph( "gameplay/behaviors/npc/steering/action/manual_pathfollow/manual_pathfollow.w2steer" );
			return true;
		}
		return false;
	}
};
////////////////////////////////////////////////////////////
// CAIMoveAlongPathParams
class CAIMoveAlongPathParams extends IAIActionParameters
{
	// !!! Warning !!!
	// If you consider making changes to CAIMoveAlongPathParams
	// please consider updating CAIRiderMoveAlongPathActionParams  
	editable var pathTag 				: CName;
	editable var upThePath 				: bool;
	editable var fromBeginning 			: bool;
	editable var pathMargin				: float;
	editable var moveTypeBeforePath		: EMoveType;
	editable var moveType 				: EMoveType;
	editable var moveSpeed				: float;
	editable var steeringGraph			: CMoveSteeringBehavior;
	editable var arrivalDistance		: Float;
	editable var rotateAfterReachStart 	: bool;
	editable var useExplorations 		: bool;
	editable var dontCareAboutNavigable	: bool;
	editable var tolerance				: float;
	
	default upThePath 				= true;
	default fromBeginning 			= true;
	default pathMargin 				= 1.25;
	default moveTypeBeforePath		= MT_Run;
	default moveType 				= MT_Run;
	default moveSpeed 				= 1.0;
	default arrivalDistance			= 0.5;
	default rotateAfterReachStart 	= true;
	default useExplorations 		= false;
	default dontCareAboutNavigable	= false;
	default tolerance				= 0.5;
	
	function Init()
	{
		super.Init();
		
		steeringGraph = LoadSteeringGraph( "gameplay/behaviors/npc/steering/action/manual_pathfollow/manual_pathfollow.w2steer" );
	}
};

////////////////////////////////////////////////////////////
class CAIMoveAlongPathWithCompanionAction extends CAIMoveAlongPathAction
{
	default aiTreeName = "resdef:ai\scripted_actions/move_along_path_companion";

	function Init()
	{
		params = new CAIMoveAlongPathWithCompanionParams in this;
		params.OnCreated();
	}
};

class CAIMoveAlongPathWithCompanionParams extends CAIMoveAlongPathParams
{
	editable var companionTag 						: CName;
	editable var maxDistance						: float;
	editable var minDistance						: float;
	editable var companionOffset					: float;
	editable var progressWhenCompanionIsAhead		: bool;
	editable var progressOnlyWhenCompanionIsAhead	: bool;
	editable var matchCompanionSpeed				: bool;
	
	default matchCompanionSpeed				= true;
	default companionTag 					= 'PLAYER';
	default maxDistance 					= 10.0f;
	default minDistance 					= 4.0f;
	default companionOffset					= -3.0f;
	default progressWhenCompanionIsAhead 	= false;
	default progressOnlyWhenCompanionIsAhead = false;
};

////////////////////////////////////////////////////////////
class CAIMoveAlongPathAwareOfTailAction extends CAIMoveAlongPathAction
{
	default aiTreeName = "resdef:ai\scripted_actions/move_along_path_tail";

	function Init()
	{
		params = new CAIMoveAlongPathAwareOfTailParams in this;
		params.OnCreated();
	}
};

class CAIMoveAlongPathAwareOfTailParams extends CAIMoveAlongPathParams
{
	editable var tailTag					: CName;
	editable var startMovementDistance		: float;
	editable var stopDistance				: float;
	
	default tailTag 				= 'PLAYER';
	default startMovementDistance 	= 15.0f;
	default stopDistance 			= 10.0f;
};

////////////////////////////////////////////////////////////
// CAIRaceAlongPathAction
class CAIRaceAlongPathAction extends CAIMoveAlongPathAction
{	
	default aiTreeName = "resdef:ai\scripted_actions/race_along_path";
	
	function Init()
	{
		params = new CAIRaceAlongPathParams in this;
		params.OnCreated();
	}
};
////////////////////////////////////////////////////////////
// CAIRaceAlongPathParams
class CAIRaceAlongPathParams extends CAIMoveAlongPathParams
{
	function Init()
	{
		super.Init();
		
		steeringGraph = LoadSteeringGraph( "gameplay/behaviors/npc/steering/action/manual_pathfollow/manual_pathfollow_racing.w2steer" );
	}
};

////////////////////////////////////////////////////////////
// CAIRiderMoveAlongPathAction
class CAIRiderMoveAlongPathAction extends IRiderActionTree
{	
	default aiTreeName = "resdef:ai\scripted_actions/rider_move_along_path";
	
	editable inlined var params : CAIRiderMoveAlongPathActionParams;
	
	function Init()
	{
		params = new CAIRiderMoveAlongPathActionParams in this;
		params.OnCreated();
	}
};
////////////////////////////////////////////////////////////
// CAIRiderMoveAlongPathActionParams
class CAIRiderMoveAlongPathActionParams extends IRiderActionParameters
{
	editable var pathTag 				: CName;
	editable var upThePath 				: bool;
	editable var fromBeginning 			: bool;
	editable var pathMargin				: float;
	editable var moveTypeBeforePath		: EMoveType;
	editable var moveType 				: EMoveType;
	editable var moveSpeed				: float;
	editable var steeringGraph			: CMoveSteeringBehavior;
	editable var arrivalDistance		: Float;
	editable var rotateAfterReachStart 	: bool;
	editable var useExplorations 		: bool;	
	editable var dontCareAboutNavigable	: bool;
	editable var tolerance				: float;
	
	
	default upThePath 				= true;
	default fromBeginning 			= true;
	default pathMargin 				= 1.25;
	default moveTypeBeforePath		= MT_Run;
	default moveType 				= MT_Run;
	default moveSpeed 				= 1.0;
	default arrivalDistance			= 0.5;
	default rotateAfterReachStart 	= false;
	default useExplorations 		= false;
	default dontCareAboutNavigable 	= false;
	default tolerance				= 0.5;
	
	
	function Init()
	{		
		steeringGraph = LoadSteeringGraph( "gameplay/behaviors/npc/steering/action/manual_pathfollow/manual_pathfollow.w2steer" );
	}
	// Using copy to because:
	// It is not possible to put all params in a common class because it 
	// would reset all existing move to in the world
	function CopyTo( moveAlongPathParams : CAIMoveAlongPathParams )
	{
		moveAlongPathParams.pathTag 				= pathTag;
		moveAlongPathParams.upThePath 				= upThePath;
		moveAlongPathParams.fromBeginning 			= fromBeginning;
		moveAlongPathParams.pathMargin 				= pathMargin;
		moveAlongPathParams.moveTypeBeforePath		= moveTypeBeforePath;
		moveAlongPathParams.moveType 				= moveType;
		moveAlongPathParams.moveSpeed 				= moveSpeed;
		moveAlongPathParams.steeringGraph 			= steeringGraph;
		moveAlongPathParams.arrivalDistance			= arrivalDistance;
		moveAlongPathParams.rotateAfterReachStart	= rotateAfterReachStart;
		moveAlongPathParams.useExplorations			= useExplorations;
		moveAlongPathParams.dontCareAboutNavigable	= dontCareAboutNavigable;
		moveAlongPathParams.tolerance				= tolerance;
	}
};

////////////////////////////////////////////////////////////
class CAIRiderMoveAlongPathWithCompanionAction extends CAIRiderMoveAlongPathAction
{
	default aiTreeName = "resdef:ai\scripted_actions/rider_move_along_path_companion";

	function Init()
	{
		params = new CAIRiderMoveAlongPathWithCompanionActionParams in this;
		params.OnCreated();
	}
};

class CAIRiderMoveAlongPathWithCompanionActionParams extends CAIRiderMoveAlongPathActionParams
{
	editable var companionTag 						: CName;
	editable var maxDistance						: float;
	editable var minDistance						: float;
	editable var companionOffset					: float;
	editable var progressWhenCompanionIsAhead		: bool;
	editable var progressOnlyWhenCompanionIsAhead	: bool;
	editable var matchCompanionSpeed				: bool;
	
	default matchCompanionSpeed				= true;	
	default companionTag 					= 'PLAYER';
	default maxDistance 					= 15.0f;
	default minDistance 					= 8.0f;
	default companionOffset					= -9.0f;
	default progressWhenCompanionIsAhead 	= false;
	default progressOnlyWhenCompanionIsAhead = false;
	
	// Using copy to because:
	// It is not possible to put all params in a common class because it 
	// would reset all existing move to in the world
	function CopyTo_2( moveAlongPathParams : CAIMoveAlongPathWithCompanionParams )
	{
		super.CopyTo( moveAlongPathParams );
		moveAlongPathParams.matchCompanionSpeed					= matchCompanionSpeed;
		moveAlongPathParams.companionTag 						= companionTag;
		moveAlongPathParams.maxDistance 						= maxDistance;
		moveAlongPathParams.minDistance 						= minDistance;
		moveAlongPathParams.companionOffset 					= companionOffset;
		moveAlongPathParams.progressWhenCompanionIsAhead 		= progressWhenCompanionIsAhead;
		moveAlongPathParams.progressOnlyWhenCompanionIsAhead 	= progressOnlyWhenCompanionIsAhead;
	}
};

////////////////////////////////////////////////////////////
// CAIRiderRaceAlongPathAction
class CAIRiderRaceAlongPathAction extends IRiderActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/rider_race_along_path";

	editable inlined var params : CAIRiderRaceAlongPathActionParams;
	function Init()
	{
		params = new CAIRiderRaceAlongPathActionParams in this;
		params.OnCreated();
	}
};

////////////////////////////////////////////////////////////
// CAIRiderRaceAlongPathActionParams
class CAIRiderRaceAlongPathActionParams extends IRiderActionParameters
{	
	editable var pathTag 				: CName;
	editable var upThePath 				: bool;
	editable var fromBeginning 			: bool;
	editable var pathMargin				: float;
	editable var tolerance				: float;
	editable var moveTypeBeforePath		: EMoveType;
	editable var moveType 				: EMoveType; // move type is controlled by path
	editable var moveSpeed				: float;
	editable var steeringGraph			: CMoveSteeringBehavior;
	editable var arrivalDistance		: Float;
	editable var rotateAfterReachStart	: Bool;	
	editable var dontCareAboutNavigable	: bool;
	
	default upThePath 				= true;
	default fromBeginning 			= true;
	default pathMargin 				= 1.25;
	default tolerance				= 0.5;
	default moveTypeBeforePath		= MT_Run;
	default moveType 				= MT_Run;
	default moveSpeed 				= 1.0;
	default arrivalDistance			= 0.5;
	default rotateAfterReachStart	= false;
	default dontCareAboutNavigable	= false;
	
	function Init()
	{
		super.Init();
		steeringGraph = LoadSteeringGraph( "gameplay/behaviors/npc/steering/action/manual_pathfollow/manual_pathfollow_racing.w2steer" );
	}
	// Using copy to because:
	// It is not possible to put all params in a common class because it 
	// would reset all existing move to in the world
	function CopyTo( raceAlongPathParams : CAIRaceAlongPathParams )
	{
		raceAlongPathParams.pathTag 				= pathTag;
		raceAlongPathParams.upThePath 				= upThePath;
		raceAlongPathParams.fromBeginning 			= fromBeginning;
		raceAlongPathParams.pathMargin 				= pathMargin;
		raceAlongPathParams.tolerance 				= tolerance;
		raceAlongPathParams.moveTypeBeforePath		= moveTypeBeforePath;
		raceAlongPathParams.moveType 				= moveType;
		raceAlongPathParams.moveSpeed 				= moveSpeed;
		raceAlongPathParams.steeringGraph 			= steeringGraph;
		raceAlongPathParams.arrivalDistance			= arrivalDistance;
		raceAlongPathParams.steeringGraph 			= steeringGraph;
		raceAlongPathParams.rotateAfterReachStart	= rotateAfterReachStart;
		raceAlongPathParams.dontCareAboutNavigable	= dontCareAboutNavigable;
	}
};


////////////////////////////////////////////////////////////
// CAIRiderRideHorseAction
class CAIRiderRideHorseAction extends IRiderActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/rider_ride_horse";

	function Init()
	{
	}
	
	function CopyTo( horseDoNothingAction : CAIHorseDoNothingAction )
	{
		// no params
	}
};
abstract class ISailorActionTree extends IAIActionTree
{
};
abstract class ISailorActionParameters extends IAIActionParameters
{
};

////////////////////////////////////////////////////////////
// CAISailorMountBoatAction
class CAISailorMountBoatAction extends ISailorActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/sailor_mount_boat";

	editable inlined var params : CAISailorMountBoatActionParams;
	
	function Init()
	{
		params = new CAISailorMountBoatActionParams in this;
		params.OnCreated();
	}
};

////////////////////////////////////////////////////////////
// CAISailorMountBoatActionParams
class CAISailorMountBoatActionParams extends ISailorActionParameters
{
	editable var boatTag 			: CName;
	function Init()
	{
		super.Init();
	}
};

////////////////////////////////////////////////////////////
// CAISailorDismountBoatAction
class CAISailorDismountBoatAction extends ISailorActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/sailor_dismount_boat";

	editable var teleportHere		: CName;
};

////////////////////////////////////////////////////////////
// CAISailorMoveToAction
class CAISailorMoveToAction extends ISailorActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/sailor_move_to";

	editable inlined var params : CAISailorMoveToActionParams;
	
	function Init()
	{
		params = new CAISailorMoveToActionParams in this;
		params.OnCreated();
	}
};

////////////////////////////////////////////////////////////
// CAISailorMoveToActionParams
class CAISailorMoveToActionParams extends ISailorActionParameters
{
	editable var boatTag 			: CName;
	editable var entityTag 			: CName;
	
	function Init()
	{
		super.Init();
	}
};
////////////////////////////////////////////////////////////
// CAISailorMoveAlongPathAction
class CAISailorMoveAlongPathAction extends ISailorActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/sailor_move_along_path";

	editable inlined var params : CAISailorMoveAlongPathActionParams;
	
	function Init()
	{
		params = new CAISailorMoveAlongPathActionParams in this;
		params.OnCreated();
	}
};

////////////////////////////////////////////////////////////
// CAISailorMoveAlongPathActionParams
class CAISailorMoveAlongPathActionParams extends ISailorActionParameters
{
	editable var boatTag 			: CName;
	editable var pathTag 			: CName;
	editable var upThePath 			: bool;
	editable var startFromBeginning : bool;
	
	default upThePath 			=  true;
	default startFromBeginning 	= true;
	function Init()
	{
		super.Init();
	}
};
////////////////////////////////////////////////////////////
// CAISailorRaceAlongPathAction
class CAISailorRaceAlongPathAction extends ISailorActionTree
{	
	default aiTreeName = "resdef:ai\scripted_actions/sailor_race_along_path";

	editable inlined var params : CAISailorRaceAlongPathActionParams;
	
	function Init()
	{
		params = new CAISailorRaceAlongPathActionParams in this;
		params.OnCreated();
	}
};

////////////////////////////////////////////////////////////
// CAISailorRaceAlongPathActionParams
class CAISailorRaceAlongPathActionParams extends ISailorActionParameters
{
	editable var boatTag 			: CName;
	editable var pathTag 			: CName;
	editable var upThePath 			: bool;
	editable var startFromBeginning : bool;
	
	default upThePath 			=  true;
	default startFromBeginning 	= true;
	function Init()
	{
		super.Init();
	}
};

////////////////////////////////////////////////////////////
// CAIMoveToAction
class CAIMoveToPoint extends IAIBaseAction
{
	default aiTreeName = "resdef:ai\scripted_actions/move_to_point";

	editable inlined var params : CAIMoveToPointParams;
	
	function Init()
	{
		params = new CAIMoveToPointParams in this;
		params.OnCreated();
	}
};
////////////////////////////////////////////////////////////
// CAIMoveToParams
class CAIMoveToPointParams extends IAIActionParameters
{
	editable var maxDistance 			: float;
	editable var moveSpeed 				: float;
	editable var moveType 				: EMoveType;
	editable var destinationPosition	: Vector;
	editable var destinationHeading		: float;
	editable var maxIterationsNumber	: int;
	editable var useTimeout				: bool;
	editable var timeoutValue			: float;
	
	default maxDistance 		= 1.0;
	default moveSpeed 			= 1.0;
	default moveType 			= MT_Walk;
	default maxIterationsNumber = 1;
};

////////////////////////////////////////////////////////////
// CAIMoveToAction
class CAIMoveToAction extends IAIBaseAction
{
	default aiTreeName = "resdef:ai\scripted_actions/move_to";

	editable inlined var params : CAIMoveToParams;
	
	function Init()
	{
		params = new CAIMoveToParams in this;
		params.OnCreated();
	}
};
////////////////////////////////////////////////////////////
// CAIMoveToParams
class CAIMoveToParams extends IAIActionParameters
{
	// !!! Warning !!!
	// If you consider making changes to CAIMoveToParams
	// please consider updating CAIRiderMoveToActionParams  
	editable var maxDistance 		: float;
	editable var moveSpeed 			: float;
	editable var moveType 			: EMoveType;
	editable var targetTag 			: CName;
	editable var rotateAfterwards 	: bool;
	editable var tolerance			: float;
	
	default maxDistance 		= 1.0;
	default moveSpeed 			= 1.0;
	default moveType 			= MT_Walk;
	default rotateAfterwards 	= true;
	default tolerance			= 0.0;
};

class CAIMoveToActionAwareOfTail extends IAIBaseAction
{
	default aiTreeName = "resdef:ai\scripted_actions\move_to_tail";
	
	editable inlined var params : CAIMoveToActionAwareOfTailParams;

	function Init()
	{
		params = new CAIMoveToActionAwareOfTailParams in this;
		params.OnCreated();
	}
};

class CAIMoveToActionAwareOfTailParams extends CAIMoveToParams
{
	editable var tailTag					: CName;
	editable var startMovementDistance		: float;
	editable var stopDistance				: float;
	
	default tailTag 				= 'PLAYER';
	default startMovementDistance 	= 15.0f;
	default stopDistance 			= 10.0f;
};

////////////////////////////////////////////////////////////
// CAIRiderMoveToAction
class CAIRiderMoveToAction extends IRiderActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/rider_move_to";

	editable inlined var params : CAIRiderMoveToActionParams;
	
	function Init()
	{
		params = new CAIRiderMoveToActionParams in this;
		params.OnCreated();
	}
};
////////////////////////////////////////////////////////////
// CAIRiderMoveToActionParams
class CAIRiderMoveToActionParams extends IRiderActionParameters
{
	editable var maxDistance 		: float;
	editable var moveSpeed 			: float;
	editable var moveType 			: EMoveType;
	editable var targetTag 			: CName;
	editable var rotateAfterwards 	: bool;
	
	default maxDistance 		= 1.0;
	default moveSpeed 			= 1.0;
	default moveType 			= MT_Walk;
	default rotateAfterwards 	= true;
	
	// Using copy to because:
	// It is not possible to put all params in a common class because it 
	// would reset all existing move to in the world
	function CopyTo( moveToParams : CAIMoveToParams )
	{
		moveToParams.maxDistance 		= maxDistance;
		moveToParams.moveSpeed 			= moveSpeed;
		moveToParams.moveType 			= moveType;
		moveToParams.targetTag 			= targetTag;
		moveToParams.rotateAfterwards 	= rotateAfterwards;
	}
};

////////////////////////////////////////////////////////////
class CAIPlayAnimationStateAction extends IAIActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/play_animation";
	
	editable var eventStateName	: CName;	
};

class CAIPlayAnimationStateParams extends IAIActionParameters
{
	editable var eventStateName: CName;
};

////////////////////////////////////////////////////////////
class CAIPlayAnimationSlotAction extends IAIActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/play_animation_slot";

	editable var animName: CName;
	editable var slotName: CName;
	editable var blendInTime: float;
	editable var blendOutTime: float;
	
	
	default blendInTime = 1.0f;
	default blendOutTime = 1.0f;	
	default slotName = 'NPC_ANIM_SLOT';
};



/////////////////////////////////////////////////////////
// Formations
abstract class IAIFormationActionTree extends IAIBaseAction
{
	editable var formation : CFormation;
};

class CAIFormationFollowActionTree extends IAIFormationActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/follow_leader_by_tag";

	editable var leaderTag : name;
};

class CAIFormationLeadActionTree extends IAIFormationActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/lead_formation";
	
	editable var leaderSteering : CMoveSteeringBehavior;
	editable var reshapeOnMoveAction : Bool;
	editable inlined var leadSubtree : IAIActionTree;
	
	function Init()
	{
		leaderSteering = LoadSteeringGraph( "gameplay/behaviors/npc/formation/steering_leader/leader_default.w2steer" );
		reshapeOnMoveAction = true;
	}
};

////////////////////////////////////////////////////////////
class CAIFinishAnimationsAction extends IAIActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/finish_slot_animations";
};

////////////////////////////////////////////////////////////
class CAIBreakAnimationsAction extends IAIActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/break_slot_animations";
};

////////////////////////////////////////////////////////////
class CAIPlayVoiceSetAction extends IAIActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/play_voice_set";
	
	editable var voiceSet : string;
	editable var priority : int;
};

class CAIPlayVoiceSetParams extends IAIActionParameters
{
	editable var voiceSet : string;
	editable var priority : int;
};

////////////////////////////////////////////////////////////
class CAIRotateToAction extends IAIActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/rotate_towards";
	
	editable var targetTag : CName;
	editable var keepRotating : bool;
};

////////////////////////////////////////////////////////////
class CAIWalkToTargetWaitAction extends IAIActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/walk_to_target";

	editable inlined var params : CAIWalkToTargetWaitParams;
	
	function Init()
	{
		params = new CAIWalkToTargetWaitParams in this;
		params.OnCreated();
	}
};

class CAIWalkToTargetWaitParams extends IAIActionParameters
{
	editable var tag : CName;
	
	editable var maxDistance : float;
	editable var moveSpeed : float;
	editable var moveType : EMoveType;
		
	editable var waitForTag : CName;	
	editable var timeout : float;
	editable var testDistance : float;
	
	default maxDistance = 3.0;
	default moveSpeed = 1.0;
	default moveType = MT_Walk;
		
	default testDistance = 10.0;
};

////////////////////////////////////////////////////////////
import class CAIActionSequence extends IAIActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/action_sequence";
};

class CAIActionSequenceParams extends IAIActionParameters
{
	editable inlined var actions : array<IAIActionTree>;
};

////////////////////////////////////////////////////////////
class CAIActionLoop extends IAIActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/loop";
	
	editable var loopCount : int;
	editable inlined var loopedAction : IAIActionTree;
	
	default loopCount = 0;
};



////////////////////////////////////////////////////////////
// CAIActionPoke
class CAIActionPoke extends IAIActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/action_poke";

	editable var pokeEvent 						: name;
	editable inlined var pokableScriptedAction 	: IAIActionTree;
};
////////////////////////////////////////////////////////////
// CAIRiderActionSequence
class CAIRiderActionSequence extends IRiderActionTree
{	
	default aiTreeName = "resdef:ai\scripted_actions/action_sequence";
	editable inlined var actions : array<IRiderActionTree>;
};
////////////////////////////////////////////////////////////
// CAIRiderActionPoke
class CAIRiderActionPoke extends IRiderActionTree
{	
	default aiTreeName = "resdef:ai\scripted_actions/action_poke";
	editable var pokeEvent 						: name;
	editable inlined var pokableScriptedAction 	: IRiderActionTree;
};

////////////////////////////////////////////////////////////
// CAIWalkToTargetWaitingForActorAction
class CAIWalkToTargetWaitingForActorAction extends IAIActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/walk_to_target_wait";

	editable var tag : CName;
	
	editable var maxDistance : float;
	editable var moveSpeed : float;
	editable var moveType : EMoveType;
		
	editable var waitForTag : CName;	
	editable var timeout : float;
	editable var testDistance : float;
	
	default maxDistance = 3.0;
	default moveSpeed = 1.0;
	default moveType = MT_Walk;
	default testDistance = 10.0;
};

////////////////////////////////////////////////////////////
// CAIPlayEffectAction
class CAIPlayEffectAction extends IAIActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/play_effect";

	editable var effectName : CName;
};
////////////////////////////////////////////////////////////
// CAIPlayEffectParams
class CAIPlayEffectParams extends IAIActionParameters
{
	editable var effectName : CName;
};

////////////////////////////////////////////////////////////
// CAIExecuteAttackAction
class CAIExecuteAttackAction extends IAIActionTree
{
	editable var attackParameter : EAttackType;
	
	default aiTreeName = "resdef:ai\scripted_actions/action_attack";
};

////////////////////////////////////////////////////////////
// CAIExecuteRangeAttackAction
class CAIExecuteRangeAttackAction extends IAIActionTree
{
	editable var attackParameter 	: EAttackType;
	editable var targetTag			: name;
	editable var projectileName		: name;
	
	hint attackParameter = "Attack type being considered a 'range' attack";
	
	default aiTreeName = "resdef:ai\scripted_actions/action_range_attack";
};



////////////////////////////////////////////////////////////
// CAIDrawTorchAction
class CAIDrawTorchAction extends IAIActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/draw_torch";
};

////////////////////////////////////////////////////////////
// CAIHideTorchAction
class CAIHideTorchAction extends IAIActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/hide_torch";
};


////////////////////////////////////////////////////////////
// CAIAttachToCurve
class CAIAttachToCurve extends IAIActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/attach_to_curve";
	
	editable var animationName		: name;
	editable var curveTag			: name;
	editable var curveDummyName		: string;
	editable var blendInTime		: float;
	editable var slotAnimation		: name;
	
	default animationName			= 'Move';
	default blendInTime				= 2.0; 
};

////////////////////////////////////////////////////////////
// CAIWaitForChangingWeaponEndAction
class CAIWaitForChangingWeaponEndAction extends IAIActionTree
{
	default aiTreeName = "resdef:ai\scripted_actions/wait_for_changing_weapon_end";
};

abstract class IActionDecorator extends IAIActionTree
{
	editable inlined var scriptedAction 		: IAIActionTree;
};

////////////////////////////////////////////////////////////
// CAIGoToExplorationActionDecorator
class CAIGoToExplorationActionDecorator extends IActionDecorator
{
	default aiTreeName = "resdef:ai\scripted_actions\go_to_exploration_action_decorator";
	
	editable var sheathWeaponsOnStart : bool;
	
	default sheathWeaponsOnStart = true;
};

////////////////////////////////////////////////////////////
// CAIPlayAnimationUpperBodySlotAction
class CAIPlayAnimationUpperBodySlotAction extends IActionDecorator
{
	default aiTreeName = "resdef:ai\scripted_actions\play_animation_upper_body_slot";

	editable var animName: CName;
	editable var interruptScriptedActionOnSlotAnimEnd : bool;
	
};

////////////////////////////////////////////////////////////
// CAIHandsBehindBackOverlayActionTree
class CAIHandsBehindBackOverlayActionTree extends IActionDecorator
{
	default aiTreeName = "resdef:ai\scripted_actions\hands_behind_back_overlay";
	
	editable var duration : float;	default duration = -1.f;
	editable var interruptScriptedActionOnDurationEnd : bool;
};

////////////////////////////////////////////////////////////
// CAICombatModeActionDecorator
class CAICombatModeActionDecorator extends IActionDecorator
{
	default aiTreeName = "resdef:ai\scripted_actions\combat_mode_action_decorator";
	
	editable var drawWeaponOnStart 				: bool;
	editable var LeftItemType 					: name;
	editable var RightItemType 					: name;
	
	editable var changeBehaviorGraphOnStart 	: bool;
	editable var behGraph 						: EBehaviorGraph;
	
	editable var changeBahviorGraphToExplorationOnDeacitvate : bool;
	
	editable var forceCombatModeOnPLAYER 		: bool;
	
	hint LeftItemType 				= "only available when <drawWeaponOnStart> is TRUE";
	hint RightItemType 				= "only available when <drawWeaponOnStart> is TRUE";
	hint chooseSilverIfPossible 	= "only available when <drawWeaponOnStart> is TRUE";
	hint behGraph 					= "only available when <changeBehaviorGraphOnStart> is TRUE";
};

////////////////////////////////////////////////////////////
// CAIInterruptableByHitAction
class CAIInterruptableByHitAction extends IActionDecorator
{
	default aiTreeName = "resdef:ai\scripted_actions/hit_interruptable_action";
	
	editable var shouldForceHitReaction 		: bool;
	editable var hitReactionType				: EHitReactionType;
	editable var hitReactionSide				: EHitReactionSide;
	editable var hitReactionDirection			: EHitReactionDirection;
	editable var hitSwingType					: EAttackSwingType;
	editable var hitSwingDirection				: EAttackSwingDirection;
	
	hint shouldForceHitReaction = "if the actor gets hit, play a specific hit reaction instead of the usual one";
	
}

////////////////////////////////////////////////////////////
// CAIInterruptOnHitOrOnCriticalEffect
class CAIInterruptOnHitOrOnCriticalEffect extends IActionDecorator
{
	default aiTreeName = "resdef:ai\scripted_actions\decorator_interrupt_on_hit_or_on_critical_effect";
	
	editable var completeOnHit 					: bool;
	editable var completeOnCriticalEffect		: bool;
	
	default completeOnHit = true;
	default completeOnCriticalEffect = true;
}

////////////////////////////////////////////////////////////
// CAIkLookAtActionDecorator
class CAIkLookAtActionDecorator extends IActionDecorator
{
	default aiTreeName = "resdef:ai\scripted_actions\lookat_action_decorator";
	
	editable var lookAtNodeTag : name;
};

////////////////////////////////////////////////////////////
// CAIChangeBehaviorGraphDecorator
class CAIChangeBehaviorGraphDecorator extends IActionDecorator
{
	default aiTreeName = "resdef:ai\scripted_actions\change_behavior_graph";
	
	editable var graphWhenActivate 		: name;
	editable var graphWhenDeactivate 	: name;
}

////////////////////////////////////////////////////////////
// CAIScaredActionDecorator
class CAIScaredActionDecorator extends IActionDecorator
{
	default aiTreeName = "resdef:ai\scripted_actions\scared_action_decorator.w2behtree";
}

////////////////////////////////////////////////////////////
// PLAYER ACTION DECORATORS
////////////////////////////////////////////////////////////

abstract class IPlayerActionDecorator extends IAIActionTree
{
	editable inlined var scriptedAction : CAITree;
};

abstract class IPlayerRiderActionDecorator extends IAIActionTree
{
	editable inlined var scriptedAction : IRiderActionTree;
};

class CAIPlayerActionDecorator extends IPlayerActionDecorator
{
	default aiTreeName = "resdef:ai\scripted_actions\player_action_decorator";
	
	editable var interruptOnInput : bool;
	
	default interruptOnInput = true;
};

class CAIPlayerRiderActionDecorator extends IPlayerRiderActionDecorator
{
	default aiTreeName = "resdef:ai\scripted_actions\player_action_decorator";
	
	editable var interruptOnInput : bool;
	
	default interruptOnInput = true;
};
