/*****************************************************************************
 * $LastChangedDate: 2011-04-09 21:58:06 -0400 (Sat, 09 Apr 2011) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   Missiles.
 *//*
 * LEGAL:   COPYRIGHT (C) 2008 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
 *****************************************************************************/

#ifndef GAME_MISSILE_HH
#define GAME_MISSILE_HH 1

#include "game/projectile.hh"

namespace game {

////////////////////////////////////////////////////////////////////////////////
/// @brief Missiles.
///
/// Lua:
/// ----
/// (See also projectile.hh).
/// Lua determines which Actor is the target.
/// Lua interfaces with this C++ class in terms of the Dyna class.
///
/// C++:
/// ----
/// (See also projectile.hh).
/// Every tick, Guide() rotates the Dyna's matrix
/// to guide the missile towards the target.
/// If the target is hit, movement stops.
/// If the target is destroyed by another action,
/// missile will fly straight until it flies past max distance.
///
class Missile : public Projectile
{
PREVENT_COPYING(Missile)
public:
                        Missile( shptr<Object> target,
                                 Object&       launcher,
                                 const Speed   launcherSpeed,
                                 const Meter   particleRadiusGeo,
                                 const bool    malfunction );
    virtual              ~Missile();
    virtual const string GetName( void ) { return string("Missile"); }

private:
    shptr<Graph>        MakeGraph( void );
    CLASS_METHOD Speed  ComputeInitialSpeed( const Speed launcherSpeed );
    virtual WorldVertex Guide( const fp step1 );
    virtual void        Explode( void );
    void                Maneuver( Matrix&           matrix,  /*IN/OUT*/
                                  const uint        rotationAxis,
                                  const uint        nextRotationAxis,
                                  Radian            maneuverAngle, 
                                  const WorldVertex targetPos );

private:
    shptr<Object>   mTarget;                        ///< what missile is guided towards
    uint            mRotationAxis;                  ///< AXIS_ROLL or AXIS_PITCH
    Radian          mManeuverAngleRoll;
    Radian          mManeuverAnglePitch;
    fp              mPredictedManeuverAngleSign;    ///< try rotating in same direction as previously
    const fp        mHitDistance;                   ///< scalar in world space
    const bool      mMalfunction;                   ///< missiles don't always work
public:
    DECLARE_TYPESIG(TYPESIG_MISSILE)
};

} // namespace game

#endif // GAME_MISSILE_HH
