/*****************************************************************************
 * $Id: game_base_machine_pursue.cc,v 1.8 2005/09/19 16:28:43 devel Exp $
 * @file
 * @author	Jim E. Brooks  http://www.jimbrooks.org
 * @brief	Machine to guide a Craft in pursuit of target.
 *//*
 * LEGAL:	COPYRIGHT (C) JIM E. BROOKS 2005
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE (GPL).
 *****************************************************************************/

#define GAME_BASE_MACHINE_PURSUE_CC 1
#include "game_base_common.hh"
#include "game_base_pilot.hh"
#include "gfx_machine.hh"
#include "game_base_machine_pursue.hh"

static Machine::Opcode sSmprocPursueChecks[] =
{
DEF_PROC_BEGIN( "PursueChecks" ),

#if 0 // TODO
	DEF_CALL( gSmprocCheckAntiCrash ),	// avoid crashing
	DEF_CALL( gSmprocCheckEvade ),		// is pursuer being pursued?
#endif

DEF_PROC_END()
};

// A subroutine consisting of a set of usual steps to be done every frame.
static Machine::Opcode sSmprocPursueSub[] =
{
DEF_PROC_BEGIN( "PursueSub" ),

	DEF_CALL( sSmprocPursueChecks ),	// check if crash pending, if becoming pursued, etc
	DEF_FUNC( PursueAdjustSpeed ),		// adjust speed depending on distance from target
	DEF_FUNC( PursueFire ),				// fire guns when within range and aligned to target
	DEF_FUNC( PursueStep ),				// translate forward
	DEF_FUNC( PursueCheckTarget ),		// check if target was destroyed

DEF_PROC_END()
};

////////////////////////////////////////////////////////////////////////////////
// This is too simplistic...
// The goal to initially do a roll/pitch paired maneuver (wide angles)
// to point the pursuer at the target.  Eventually the pursuer will be trailing
// the target.  Paired yaw/pitch maneuvers (fine angles) should keep the pursuer
// tracking its target.
////////////////////////////////////////////////////////////////////////////////

static Machine::Opcode sSmprocRollPitch[] =
{
DEF_PROC_BEGIN( "PursueRollPitch" ),

	DEF_LABEL( "Roll" ),
		DEF_FUNC( PursueIfRoll ),
		DEF_JUMP_F( "SkipRoll" ),
		DEF_FUNC( PursueRoll ),
		DEF_CALL( sSmprocPursueSub ),
		OPC_SUSPEND,
		DEF_JUMP( "Roll" ),
	DEF_LABEL( "SkipRoll" ),

	DEF_LABEL( "Pitch" ),
		DEF_FUNC( PursueIfPitch ),
		DEF_JUMP_F( "SkipPitch" ),
		DEF_FUNC( PursuePitch ),
		DEF_CALL( sSmprocPursueSub ),
		OPC_SUSPEND,
		DEF_JUMP( "Pitch" ),
	DEF_LABEL( "SkipPitch" ),

DEF_PROC_END()
};

static Machine::Opcode sSmprocPitchYaw[] =
{
DEF_PROC_BEGIN( "PursuePitchYaw" ),

	DEF_LABEL( "Pitch" ),
		DEF_FUNC( PursueIfPitch ),
		DEF_JUMP_F( "SkipPitch" ),
		DEF_FUNC( PursuePitch ),
		DEF_CALL( sSmprocPursueSub ),
		OPC_SUSPEND,
		DEF_JUMP( "Pitch" ),
	DEF_LABEL( "SkipPitch" ),

	DEF_LABEL( "Yaw" ),
		DEF_FUNC( PursueIfYaw ),
		DEF_JUMP_F( "SkipYaw" ),
		DEF_FUNC( PursueYaw ),
		DEF_CALL( sSmprocPursueSub ),
		OPC_SUSPEND,
		DEF_JUMP( "Yaw" ),
	DEF_LABEL( "SkipYaw" ),

DEF_PROC_END()
};

Machine::Opcode gSmprocPursue[] =
{
DEF_PROC_BEGIN( "Pursue" ),

	// Flying inline with the target?
	DEF_FUNC( PursueIfInlineWithTarget ),
	DEF_JUMP_T( "Inline" ),

	// Roll/pitch.
	DEF_CALL( sSmprocRollPitch ),
	DEF_JUMP( "Again" ),

	// Pitch/yaw.
	DEF_LABEL( "Inline" ),
	DEF_CALL( sSmprocPitchYaw ),

	DEF_LABEL( "Again" ),
	DEF_CALL( sSmprocPursueSub ),
	OPC_SUSPEND,
	DEF_RERUN(),

DEF_PROC_END()
};
