Setting the pose parameters correctly (so the turret looks like it's aiming
at what you want it to aim at) can be a bit tricky. I'd recommend trying to
set your turret up like VALVe's carriable floor turret guy as the code is
available for it.

Here's some code for a ceiling mounted turret we have that can spin 360
degrees. (Note: depending on if you've modified one of the lerp functions
you might see a bug when the turret reaches the 360/0 degree mark when
rotating from a certain direction - it'll sort of flip back the wrong way
then flip back to the correct way)

Just FYI - this turret is basically a copy/paste of one of VALVe's already
existing turrets. It has several think functions that run depending on its
state (if it sees an enemy and is popping out, if it loses and enemy and is
retiring, if it just saw an enemy but lost it, if its actively tracking an
enemy, etc).

Below are just some snippets; I could probably paste more if needed. This
entity is networked so that's why some of the functions say "(shared)" as
the code is accessible on both client & server.

//--------------------------------------------------------------------------
---
// Purpose:
//--------------------------------------------------------------------------
---
bool CFFMiniTurret::UpdateFacing( void )
{
        bool bMoved = false;

        // Get current orientation of the muzzle attachment
        Vector vecOrigin;
        QAngle vecAngles;
        MuzzlePosition( vecOrigin, vecAngles );

        // Update pitch
        float flDiff = -m_vecGoalAngles.x;
        SetPoseParameter( m_iPitchPoseParameter, flDiff );

        if( miniturret_debug.GetBool() )
                DevMsg( "[MiniTurret] Current Pitch: %f, Goal Pitch: %f,
pitch val: %f\n", vecAngles.x, m_vecGoalAngles.x, flDiff );

        // Get the current yaw value
        float flYaw = GetPoseParameter( m_iYawPoseParameter );

        if( miniturret_debug.GetBool() )
                Warning( "[MiniTurret] Current pose yaw: %f, vecAngles yaw:
%f, goal yaw: %f\n", flYaw, vecAngles.y, m_vecGoalAngles.y );

        // Update yaw
        flDiff = AngleNormalize( UTIL_ApproachAngle( AngleNormalize(
m_vecGoalAngles.y ), AngleNormalize( flYaw ), MaxYawSpeed() ) );
        SetPoseParameter( m_iYawPoseParameter, flDiff );

        InvalidateBoneCache();

        return bMoved;
}

//--------------------------------------------------------------------------
---
// Purpose: Get the muzzle position (shared)
//--------------------------------------------------------------------------
---
Vector CFFMiniTurret::MuzzlePosition( void )
{
        Vector vecOrigin;
        QAngle vecAngles;
        SetupAttachments();
        GetAttachment( m_iMuzzleAttachment, vecOrigin, vecAngles );

        return vecOrigin;
}
//--------------------------------------------------------------------------
---
// Purpose: Get the muzzle position (shared)
//--------------------------------------------------------------------------
---
void CFFMiniTurret::MuzzlePosition( Vector& vecOrigin, QAngle& vecAngles )
{
        SetupAttachments();
        GetAttachment( m_iMuzzleAttachment, vecOrigin, vecAngles );
}

//--------------------------------------------------------------------------
---
// Purpose: Setup attachments (shared)
//--------------------------------------------------------------------------
---
void CFFMiniTurret::SetupAttachments( void )
{
        if( m_iMuzzleAttachment == -1 )
                m_iMuzzleAttachment = LookupAttachment(
FF_MINITURRET_MUZZLE_ATTACHMENT );
        if( m_iEyeAttachment == -1 )
                m_iEyeAttachment = LookupAttachment(
FF_MINITURRET_EYE_ATTACHMENT );
        if( m_iLaserAttachment == -1 )
                m_iLaserAttachment = LookupAttachment(
FF_MINITURRET_EYE_ATTACHMENT );
}

The actual class definition:

//==========================================================================
===
//
//      class CFFMiniTurret
//
//==========================================================================
===

#define FF_MINITURRET_MODEL
"models/buildable/respawn_turret/respawn_turret.mdl"
//#define FF_MINITURRET_GLOW_SPRITE     "sprites/glow1.vmt"
#define FF_MINITURRET_BC_YAW            "aim_yaw"
#define FF_MINITURRET_BC_PITCH          "aim_pitch"

#define FF_MINITURRET_PING_TIME         5.0
#define FF_MINITURRET_MAX_WAIT          5.0
#define FF_MINITURRET_RANGE                     1024

#define FF_MINITURRET_MAX_PITCH         0.0f
#define FF_MINITURRET_MIN_PITCH         -90.0f

#define FF_MINITURRET_MUZZLE_ATTACHMENT "barrel01"
#define FF_MINITURRET_EYE_ATTACHMENT    "eyes"

//==========================================================================
===
//
//      class CFFMiniTurret
//
//==========================================================================
===
class CFFMiniTurret : public CBaseAnimating
{
public:
        DECLARE_CLASS( CFFMiniTurret, CBaseAnimating );
        DECLARE_NETWORKCLASS();

        // --> Shared code
        CFFMiniTurret( void );
        ~CFFMiniTurret( void );

        virtual void    Precache( void );
        virtual Class_T Classify( void ) { return CLASS_TURRET; }
        virtual Vector  EyePosition( void );
        Vector                  MuzzlePosition( void );
        void                    MuzzlePosition( Vector& vecOrigin, QAngle&
vecAngles );
        void                    LaserPosition( Vector& vecOrigin, QAngle&
vecAngles );
        void                    SetupAttachments( void );

        CNetworkVar( bool, m_bActive );         // Whether it's
deployed/active or not
        CNetworkVar( bool, m_bEnabled );        // Whether disabled or not

        virtual int             GetTeamNumber( void ) { return
TEAM_UNASSIGNED; }
        virtual bool    IsPlayer( void ) const { return false; }
        virtual bool    IsAlive( void ) { return true; }
        virtual bool    IsActive( void ) { return m_bActive; }
        virtual bool    IsEnabled( void ) { return m_bEnabled; }
        virtual bool    BlocksLOS( void ) { return false; }
        virtual int             BloodColor( void ) { return
BLOOD_COLOR_MECH; }
        virtual bool    ShouldSavePhysics( void ) { return false; }
        virtual bool    IsNPC( void ) { return true; }

protected:
        int             m_iEyeAttachment;
        int             m_iMuzzleAttachment;
        int             m_iLaserAttachment;
        // <-- Shared code

#ifdef CLIENT_DLL
        virtual void OnDataChanged( DataUpdateType_t updateType )
        {
                BaseClass::OnDataChanged( updateType );

                if( updateType == DATA_UPDATE_CREATED )
                {
                        SetNextClientThink( CLIENT_THINK_ALWAYS );
                }
        }

        // The model is all of a sudden drawing stupid ass shadows
eventhough
        // it's up in the ceiling???
        virtual ShadowType_t ShadowCastType( void ) { return SHADOWS_NONE; }
#else

public:
        DECLARE_DATADESC();

        virtual void    Spawn( void );
        virtual int             OnTakeDamage( const CTakeDamageInfo &info )
{ return 0; }
        virtual int             VPhysicsTakeDamage( const CTakeDamageInfo
&info ) { return 0; }

        const char              *GetTracerType( void ) { return "ACTracer";
} // TODO: Change

        // Think functions
        void                    OnObjectThink( void );  // Not a think
function
        void                    OnRetire( void );
        void                    OnDeploy( void );
        void                    OnActiveThink( void );
        void                    OnSearchThink( void );
        void                    OnAutoSearchThink( void );
        CBaseEntity *   HackFindEnemy( void );

        // Inputs
        /*
        void    InputToggle( inputdata_t &inputdata );
        void    InputEnable( inputdata_t &inputdata );
        void    InputDisable( inputdata_t &inputdata );
        */

        float                   MaxYawSpeed( void );


        // Activity stuff
        Activity                GetActivity( void ) { return m_Activity; }
        virtual void    SetActivity( Activity NewActivity );
        virtual bool    IsActivityFinished( void );
private:
        Activity                m_Activity;
        Activity                m_IdealActivity;
        int                             m_nIdealSequence;

protected:
        void                    Shoot( const Vector &vecSrc, const Vector
&vecDirToEnemy, bool bStrict = false );
        void                    DoMuzzleFlash( void );
        void                    Ping( void );
        //void                  Toggle( void );
        //void                  Enable( void );
        //void                  Disable( void );
        void                    SpinUp( void );
        void                    SpinDown( void );
        bool                    UpdateFacing( void );
        void                    EnableLaserDot( void );
        void                    DisableLaserDot( void );
        void                    EnableLaserBeam( void );
        void                    DisableLaserBeam( void );

        // Enemy handling
        void                    SetEnemy( CBaseEntity *pEntity );
        CBaseEntity             *GetEnemy( void );

protected:
        int             m_iAmmoType;
        float   m_flNextShell;

        float   m_flShotTime;
        float   m_flLastSight;
        float   m_flPingTime;
        //float m_flNextActivateSoundTime;

        int             m_iPitchPoseParameter;
        int             m_iYawPoseParameter;

        COutputEvent m_OnDeploy;
        COutputEvent m_OnRetire;

        // Aiming
        QAngle  m_vecGoalAngles;

        CHandle< CFFMiniTurretLaserDot >        m_hLaserDot;
        CHandle< CFFMiniTurretLaserBeam >       m_hLaserBeam;

        EHANDLE m_hEnemy;

#endif // CLIENT_DLL
};

If you look at VALVe's turrets you'll notice a lot of similarities...

VALVe's turrets are in dlls\hl2_dll btw (npc_turret*)

-----Original Message-----
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of Adam Maras
(memzero)
Sent: Monday, January 21, 2008 19:27
To: hlcoders
Subject: [hlcoders] Vector math is simply beyond me.

Hello, everybody. I'm having a headache with a model entity I'm writing,
and I need your help.

To start off, the entity is a turret. It has a model, the model has
pitch and yaw pose parameters I use to "point" the model at the player
it's shooting at. That being said, I can't get the math right for the
yaw to come out right at all. Here's what I have:

    * Vector vecAbsOrigin( GetAbsOrigin() ); // the absolute center of
      the model
    * QAngle angAbsAngles( GetAbsAngles() ); // the absolute angles of
      the model
    * Vector vecPosition; // the absolute position of what's being shot at

I've tried everything I know, but I cannot put these three values
together in any way that will give me a pitch and yaw for my
SetPoseParameter calls that will result in this turret pointing at its
target. I'm not versed in vector math, which doesn't help either. Can
someone help me out?

//   Adam Maras (memzero)

_______________________________________________
To unsubscribe, edit your list preferences, or view the list archives,
please visit:
http://list.valvesoftware.com/mailman/listinfo/hlcoders


_______________________________________________
To unsubscribe, edit your list preferences, or view the list archives, please 
visit:
http://list.valvesoftware.com/mailman/listinfo/hlcoders

Reply via email to