Re-reading the email I can see some things I put in the code that were never
used... and also, setting up the model & its .qc is probably the more
important aspect of getting the thing working as expected (but I had no part
in doing that - someone else on the team did the modelling).
------
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