680 lines
18 KiB
C++
680 lines
18 KiB
C++
// leave this line at the top for all g_xxxx.cpp files...
|
|
#include "g_headers.h"
|
|
|
|
#include "g_local.h"
|
|
#include "g_functions.h"
|
|
#include "g_vehicles.h"
|
|
|
|
extern float DotToSpot( vec3_t spot, vec3_t from, vec3_t fromAngles );
|
|
extern vmCvar_t cg_thirdPersonAlpha;
|
|
extern vec3_t playerMins;
|
|
extern vec3_t playerMaxs;
|
|
extern cvar_t *g_speederControlScheme;
|
|
|
|
|
|
// Update death sequence.
|
|
void CAnimalNPC::DeathUpdate()
|
|
{
|
|
if ( level.time >= m_iDieTime )
|
|
{
|
|
// If the vehicle is not empty.
|
|
if ( !(m_pParentEntity->client->ps.eFlags & EF_EMPTY_VEHICLE) )
|
|
{
|
|
EjectAll();
|
|
}
|
|
else
|
|
{
|
|
// Waste this sucker.
|
|
}
|
|
|
|
// Die now...
|
|
/* else
|
|
{
|
|
vec3_t mins, maxs, bottom;
|
|
trace_t trace;
|
|
|
|
if ( m_pVehicleInfo->explodeFX )
|
|
{
|
|
G_PlayEffect( m_pVehicleInfo->explodeFX, m_pParentEntity->currentOrigin );
|
|
//trace down and place mark
|
|
VectorCopy( m_pParentEntity->currentOrigin, bottom );
|
|
bottom[2] -= 80;
|
|
gi.trace( &trace, m_pParentEntity->currentOrigin, vec3_origin, vec3_origin, bottom, m_pParentEntity->s.number, CONTENTS_SOLID );
|
|
if ( trace.fraction < 1.0f )
|
|
{
|
|
VectorCopy( trace.endpos, bottom );
|
|
bottom[2] += 2;
|
|
G_PlayEffect( "ships/ship_explosion_mark", trace.endpos );
|
|
}
|
|
}
|
|
|
|
m_pParentEntity->takedamage = qfalse;//so we don't recursively damage ourselves
|
|
if ( m_pVehicleInfo->explosionRadius > 0 && m_pVehicleInfo->explosionDamage > 0 )
|
|
{
|
|
VectorCopy( m_pParentEntity->mins, mins );
|
|
mins[2] = -4;//to keep it off the ground a *little*
|
|
VectorCopy( m_pParentEntity->maxs, maxs );
|
|
VectorCopy( m_pParentEntity->currentOrigin, bottom );
|
|
bottom[2] += m_pParentEntity->mins[2] - 32;
|
|
gi.trace( &trace, m_pParentEntity->currentOrigin, mins, maxs, bottom, m_pParentEntity->s.number, CONTENTS_SOLID );
|
|
G_RadiusDamage( trace.endpos, NULL, m_pVehicleInfo->explosionDamage, m_pVehicleInfo->explosionRadius, NULL, MOD_EXPLOSIVE );//FIXME: extern damage and radius or base on fuel
|
|
}
|
|
|
|
m_pParentEntity->e_ThinkFunc = thinkF_G_FreeEntity;
|
|
m_pParentEntity->nextthink = level.time + FRAMETIME;
|
|
}*/
|
|
}
|
|
}
|
|
|
|
// Like a think or move command, this updates various vehicle properties.
|
|
bool CAnimalNPC::Update( const usercmd_t *pUmcd )
|
|
{
|
|
// Bucking so we can't do anything.
|
|
if ( m_ulFlags & VEH_BUCKING || m_ulFlags & VEH_FLYING || m_ulFlags & VEH_CRASHING )
|
|
{
|
|
m_pParentEntity->client->ps.speed = 0;
|
|
return false;
|
|
}
|
|
|
|
return CVehicleNPC::Update( pUmcd );
|
|
}
|
|
|
|
// ProcessMoveCommands the Vehicle.
|
|
void CAnimalNPC::ProcessMoveCommands()
|
|
{
|
|
/************************************************************************************/
|
|
/* BEGIN Here is where we move the vehicle (forward or back or whatever). BEGIN */
|
|
/************************************************************************************/
|
|
|
|
//Client sets ucmds and such for speed alterations
|
|
float speedInc, speedIdleDec, speedIdle, speedIdleAccel, speedMin, speedMax;
|
|
|
|
speedIdleDec = m_pVehicleInfo->decelIdle * m_fTimeModifier;
|
|
speedMax = m_pVehicleInfo->speedMax;
|
|
|
|
speedIdle = m_pVehicleInfo->speedIdle;
|
|
speedIdleAccel = m_pVehicleInfo->accelIdle * m_fTimeModifier;
|
|
speedMin = m_pVehicleInfo->speedMin;
|
|
|
|
if ( m_pParentEntity->client->ps.eFlags & EF_EMPTY_VEHICLE )
|
|
{//drifts to a stop
|
|
speedInc = speedIdle * m_fTimeModifier;
|
|
VectorClear( client->ps.moveDir );
|
|
//m_ucmd.forwardmove = 127;
|
|
m_pParentEntity->client->ps.speed = 0;
|
|
}
|
|
else
|
|
{
|
|
speedInc = m_pVehicleInfo->acceleration * m_fTimeModifier;
|
|
}
|
|
|
|
if ( m_pParentEntity->client->ps.speed || client->ps.groundEntityNum == ENTITYNUM_NONE ||
|
|
m_ucmd.forwardmove || m_ucmd.upmove > 0 )
|
|
{
|
|
if ( m_ucmd.forwardmove > 0 && speedInc )
|
|
{
|
|
m_pParentEntity->client->ps.speed += speedInc;
|
|
}
|
|
else if ( m_ucmd.forwardmove < 0 )
|
|
{
|
|
if ( m_pParentEntity->client->ps.speed > speedIdle )
|
|
{
|
|
m_pParentEntity->client->ps.speed -= speedInc;
|
|
}
|
|
else if ( client->ps.speed > speedMin )
|
|
{
|
|
m_pParentEntity->client->ps.speed -= speedIdleDec;
|
|
}
|
|
}
|
|
// No input, so coast to stop.
|
|
else if ( m_pParentEntity->client->ps.speed > 0.0f )
|
|
{
|
|
m_pParentEntity->client->ps.speed -= speedIdleDec;
|
|
if ( m_pParentEntity->client->ps.speed < 0.0f )
|
|
{
|
|
m_pParentEntity->client->ps.speed = 0.0f;
|
|
}
|
|
}
|
|
else if ( m_pParentEntity->client->ps.speed < 0.0f )
|
|
{
|
|
m_pParentEntity->client->ps.speed += speedIdleDec;
|
|
if ( m_pParentEntity->client->ps.speed > 0.0f )
|
|
{
|
|
m_pParentEntity->client->ps.speed = 0.0f;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( m_ucmd.forwardmove < 0 )
|
|
{
|
|
m_ucmd.forwardmove = 0;
|
|
}
|
|
if ( m_ucmd.upmove < 0 )
|
|
{
|
|
m_ucmd.upmove = 0;
|
|
}
|
|
|
|
m_ucmd.rightmove = 0;
|
|
|
|
/*if ( !m_pVehicleInfo->strafePerc
|
|
|| (!g_speederControlScheme->value && !m_pParentEntity->s.number) )
|
|
{//if in a strafe-capable vehicle, clear strafing unless using alternate control scheme
|
|
m_ucmd.rightmove = 0;
|
|
}*/
|
|
}
|
|
|
|
float fWalkSpeedMax = speedMax * 0.275f;
|
|
if ( m_ucmd.buttons & BUTTON_WALKING && m_pParentEntity->client->ps.speed > fWalkSpeedMax )
|
|
{
|
|
m_pParentEntity->client->ps.speed = fWalkSpeedMax;
|
|
}
|
|
else if ( m_pParentEntity->client->ps.speed > speedMax )
|
|
{
|
|
m_pParentEntity->client->ps.speed = speedMax;
|
|
}
|
|
else if ( m_pParentEntity->client->ps.speed < speedMin )
|
|
{
|
|
m_pParentEntity->client->ps.speed = speedMin;
|
|
}
|
|
|
|
/********************************************************************************/
|
|
/* END Here is where we move the vehicle (forward or back or whatever). END */
|
|
/********************************************************************************/
|
|
}
|
|
|
|
// ProcessOrientCommands the Vehicle.
|
|
void CAnimalNPC::ProcessOrientCommands()
|
|
{
|
|
/********************************************************************************/
|
|
/* BEGIN Here is where make sure the vehicle is properly oriented. BEGIN */
|
|
/********************************************************************************/
|
|
|
|
gentity_t *rider = m_pParentEntity->owner;
|
|
if ( !rider || !rider->client )
|
|
{
|
|
rider = m_pParentEntity;
|
|
}
|
|
|
|
float speed;
|
|
speed = VectorLength( m_pParentEntity->client->ps.velocity );
|
|
|
|
// If the player is the rider...
|
|
if ( !rider->s.number )
|
|
{//FIXME: use the vehicle's turning stat in this calc
|
|
m_vOrientation[YAW] = rider->client->ps.viewangles[YAW];
|
|
}
|
|
else
|
|
{
|
|
float turnSpeed = m_pVehicleInfo->turningSpeed;
|
|
if ( !m_pVehicleInfo->turnWhenStopped
|
|
&& !m_pParentEntity->client->ps.speed )//FIXME: or !m_ucmd.forwardmove?
|
|
{//can't turn when not moving
|
|
//FIXME: or ramp up to max turnSpeed?
|
|
turnSpeed = 0.0f;
|
|
}
|
|
if ( !rider || rider->NPC )
|
|
{//help NPCs out some
|
|
turnSpeed *= 2.0f;
|
|
if ( m_pParentEntity->client->ps.speed > 200.0f )
|
|
{
|
|
turnSpeed += turnSpeed * m_pParentEntity->client->ps.speed/200.0f*0.05f;
|
|
}
|
|
}
|
|
turnSpeed *= m_fTimeModifier;
|
|
|
|
//default control scheme: strafing turns, mouselook aims
|
|
if ( m_ucmd.rightmove < 0 )
|
|
{
|
|
m_vOrientation[YAW] += turnSpeed;
|
|
}
|
|
else if ( m_ucmd.rightmove > 0 )
|
|
{
|
|
m_vOrientation[YAW] -= turnSpeed;
|
|
}
|
|
|
|
if ( m_iArmor <= 25 )
|
|
{//damaged badly
|
|
}
|
|
}
|
|
|
|
/********************************************************************************/
|
|
/* END Here is where make sure the vehicle is properly oriented. END */
|
|
/********************************************************************************/
|
|
}
|
|
|
|
extern void PM_SetAnim(pmove_t *pm,int setAnimParts,int anim,int setAnimFlags, int blendTime);
|
|
extern int PM_AnimLength( int index, animNumber_t anim );
|
|
|
|
// This function makes sure that the vehicle is properly animated.
|
|
void CAnimalNPC::AnimateVehicle()
|
|
{
|
|
animNumber_t Anim = BOTH_VT_IDLE;
|
|
int iFlags = SETANIM_FLAG_NORMAL, iBlend = 300;
|
|
|
|
// We're dead (boarding is reused here so I don't have to make another variable :-).
|
|
if ( m_pParentEntity->health <= 0 )
|
|
{
|
|
if ( m_iBoarding != -999 ) // Animate the death just once!
|
|
{
|
|
m_iBoarding = -999;
|
|
iFlags = SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD;
|
|
|
|
// FIXME! Why do you keep repeating over and over!!?!?!? Bastard!
|
|
NPC_SetAnim( m_pParentEntity, SETANIM_LEGS, BOTH_VT_DEATH1, iFlags, iBlend );
|
|
}
|
|
return;
|
|
}
|
|
|
|
// If they're bucking, play the animation and leave...
|
|
if ( m_pParentEntity->client->ps.legsAnim == BOTH_VT_BUCK )
|
|
{
|
|
// Done with animation? Erase the flag.
|
|
if ( m_pParentEntity->client->ps.legsAnimTimer <= 0 )
|
|
{
|
|
m_ulFlags &= ~VEH_BUCKING;
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
else if ( m_ulFlags & VEH_BUCKING )
|
|
{
|
|
iFlags = SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD;
|
|
Anim = BOTH_VT_BUCK;
|
|
iBlend = 500;
|
|
NPC_SetAnim( m_pParentEntity, SETANIM_LEGS, BOTH_VT_BUCK, iFlags, iBlend );
|
|
return;
|
|
}
|
|
|
|
// Boarding animation.
|
|
if ( m_iBoarding != 0 )
|
|
{
|
|
// We've just started boarding, set the amount of time it will take to finish boarding.
|
|
if ( m_iBoarding < 0 )
|
|
{
|
|
// Boarding from left...
|
|
if ( m_iBoarding == -1 )
|
|
{
|
|
Anim = BOTH_VT_MOUNT_L;
|
|
}
|
|
else if ( m_iBoarding == -2 )
|
|
{
|
|
Anim = BOTH_VT_MOUNT_R;
|
|
}
|
|
else if ( m_iBoarding == -3 )
|
|
{
|
|
Anim = BOTH_VT_MOUNT_B;
|
|
}
|
|
|
|
// Set the delay time (which happens to be the time it takes for the animation to complete).
|
|
// NOTE: Here I made it so the delay is actually 70% (0.7f) of the animation time.
|
|
int iAnimLen = PM_AnimLength( m_pParentEntity->client->clientInfo.animFileIndex, Anim ) * 0.7f;
|
|
m_iBoarding = level.time + iAnimLen;
|
|
|
|
// Set the animation, which won't be interrupted until it's completed.
|
|
// TODO: But what if he's killed? Should the animation remain persistant???
|
|
iFlags = SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD;
|
|
|
|
NPC_SetAnim( m_pParentEntity, SETANIM_LEGS, Anim, iFlags, iBlend );
|
|
return;
|
|
}
|
|
// Otherwise we're done.
|
|
else if ( m_iBoarding <= level.time )
|
|
{
|
|
m_iBoarding = 0;
|
|
}
|
|
}
|
|
|
|
// Percentage of maximum speed relative to current speed.
|
|
//float fSpeed = VectorLength( client->ps.velocity );
|
|
float fSpeedPercToMax = m_pParentEntity->client->ps.speed / m_pVehicleInfo->speedMax;
|
|
|
|
// If we're moving...
|
|
if ( fSpeedPercToMax > 0.0f ) //fSpeedPercToMax >= 0.85f )
|
|
{
|
|
iBlend = 300;
|
|
iFlags = SETANIM_FLAG_OVERRIDE;
|
|
float fYawDelta = m_vPrevOrientation[YAW] - m_vOrientation[YAW];
|
|
|
|
// NOTE: Mikes suggestion for fixing the stuttering walk (left/right) is to maintain the
|
|
// current frame between animations. I have no clue how to do this and have to work on other
|
|
// stuff so good luck to him :-p AReis
|
|
|
|
// If we're walking (or our speed is less than .275%)...
|
|
if ( ( m_ucmd.buttons & BUTTON_WALKING ) || fSpeedPercToMax < 0.275f )
|
|
{
|
|
// Make them lean if we're turning.
|
|
/*if ( fYawDelta < -0.0001f )
|
|
{
|
|
Anim = BOTH_VT_WALK_FWD_L;
|
|
}
|
|
else if ( fYawDelta > 0.0001 )
|
|
{
|
|
Anim = BOTH_VT_WALK_FWD_R;
|
|
}
|
|
else*/
|
|
{
|
|
Anim = BOTH_VT_WALK_FWD;
|
|
}
|
|
}
|
|
// otherwise we're running.
|
|
else
|
|
{
|
|
// Make them lean if we're turning.
|
|
/*if ( fYawDelta < -0.0001f )
|
|
{
|
|
Anim = BOTH_VT_RUN_FWD_L;
|
|
}
|
|
else if ( fYawDelta > 0.0001 )
|
|
{
|
|
Anim = BOTH_VT_RUN_FWD_R;
|
|
}
|
|
else*/
|
|
{
|
|
Anim = BOTH_VT_RUN_FWD;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Going in reverse...
|
|
if ( fSpeedPercToMax < -0.018f )
|
|
{
|
|
iFlags = SETANIM_FLAG_OVERRIDE;
|
|
Anim = BOTH_VT_WALK_REV;
|
|
iBlend = 500;
|
|
}
|
|
else
|
|
{
|
|
int iChance = Q_irand( 0, 20000 );
|
|
|
|
// Every once in a while buck or do a different idle...
|
|
iFlags = SETANIM_FLAG_NORMAL | SETANIM_FLAG_RESTART | SETANIM_FLAG_HOLD;
|
|
iBlend = 600;
|
|
Anim = BOTH_VT_IDLE;
|
|
if ( iChance <= 15000 )
|
|
{
|
|
Anim = BOTH_VT_IDLE;
|
|
}
|
|
else if ( iChance > 15000 && iChance <= 19990 )
|
|
{
|
|
Anim = BOTH_VT_IDLE1;
|
|
}
|
|
else if ( iChance > 19990 && iChance <= 20000 )
|
|
{
|
|
//m_ulFlags |= VEH_BUCKING;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Crashing.
|
|
if ( m_ulFlags & VEH_CRASHING )
|
|
{
|
|
m_ulFlags &= ~VEH_CRASHING; // Remove the flag, we are doing the animation.
|
|
iBlend = 0;
|
|
Anim = BOTH_VT_LAND;
|
|
iFlags = SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD;
|
|
}
|
|
|
|
// In the Air.
|
|
if ( m_ulFlags & VEH_FLYING )
|
|
{
|
|
m_ulFlags &= ~VEH_FLYING;
|
|
iBlend = 10;
|
|
Anim = BOTH_VT_AIR;
|
|
iFlags = SETANIM_FLAG_OVERRIDE;
|
|
}
|
|
|
|
NPC_SetAnim( m_pParentEntity, SETANIM_LEGS, Anim, iFlags, iBlend );
|
|
}
|
|
|
|
// This function makes sure that the rider's in this vehicle are properly animated.
|
|
void CAnimalNPC::AnimateRiders()
|
|
{
|
|
animNumber_t Anim = BOTH_VT_IDLE;
|
|
int iFlags = SETANIM_FLAG_NORMAL, iBlend = 500;
|
|
|
|
// Boarding animation.
|
|
if ( m_iBoarding != 0 )
|
|
{
|
|
// We've just started moarding, set the amount of time it will take to finish moarding.
|
|
if ( m_iBoarding < 0 )
|
|
{
|
|
iBlend = 0;
|
|
// Boarding from left...
|
|
if ( m_iBoarding == -1 )
|
|
{
|
|
Anim = BOTH_VT_MOUNT_L;
|
|
}
|
|
else if ( m_iBoarding == -2 )
|
|
{
|
|
Anim = BOTH_VT_MOUNT_R;
|
|
}
|
|
else if ( m_iBoarding == -3 )
|
|
{
|
|
Anim = BOTH_VT_MOUNT_B;
|
|
}
|
|
|
|
// Set the animation, which won't be interrupted until it's completed.
|
|
// TODO: But what if he's killed? Should the animation remain persistant???
|
|
iFlags = SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD;
|
|
|
|
NPC_SetAnim( m_pPilot, SETANIM_BOTH, Anim, iFlags, iBlend );
|
|
return;
|
|
}
|
|
// Otherwise we're done.
|
|
else if ( m_iBoarding <= level.time )
|
|
{
|
|
m_iBoarding = 0;
|
|
}
|
|
}
|
|
|
|
// Percentage of maximum speed relative to current speed.
|
|
float fSpeedPercToMax = m_pParentEntity->client->ps.speed / m_pVehicleInfo->speedMax;
|
|
|
|
// Going in reverse...
|
|
if ( fSpeedPercToMax < -0.01f )
|
|
{
|
|
Anim = BOTH_VT_WALK_REV;
|
|
iBlend = 600;
|
|
}
|
|
else
|
|
{
|
|
// If they have a weapon...
|
|
if ( m_pPilot->client->ps.weapon != WP_NONE && m_pPilot->client->ps.weapon != WP_MELEE )
|
|
{
|
|
// If they're firing, play the right fire animation.
|
|
if ( m_ucmd.buttons & ( BUTTON_ATTACK | BUTTON_ALT_ATTACK ) )
|
|
{
|
|
iFlags = SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD;
|
|
iBlend = 0;
|
|
switch ( m_pPilot->client->ps.weapon )
|
|
{
|
|
case WP_SABER:
|
|
// If we're already in an attack animation, leave (let it continue).
|
|
if ( m_pPilot->client->ps.torsoAnimTimer > 0 && (m_pPilot->client->ps.torsoAnim == BOTH_VT_ATR_S ||
|
|
m_pPilot->client->ps.torsoAnim == BOTH_VT_ATL_S) )
|
|
{
|
|
//FIXME: no need to even call the PM_SetAnim at all in this case
|
|
Anim = (animNumber_t)m_pPilot->client->ps.torsoAnim;
|
|
iFlags = SETANIM_FLAG_NORMAL;
|
|
break;
|
|
}
|
|
|
|
// Start the attack.
|
|
if ( m_ucmd.rightmove > 0 ) //right side attack
|
|
{
|
|
Anim = BOTH_VT_ATR_S;
|
|
}
|
|
else if ( m_ucmd.rightmove < 0 ) //left-side attack
|
|
{
|
|
Anim = BOTH_VT_ATL_S;
|
|
}
|
|
else //random
|
|
{
|
|
//FIXME: alternate back and forth or auto-aim?
|
|
if ( !Q_irand( 0, 1 ) )
|
|
{
|
|
Anim = BOTH_VT_ATR_S;
|
|
}
|
|
else
|
|
{
|
|
Anim = BOTH_VT_ATL_S;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WP_BLASTER:
|
|
// Override the shoot anim.
|
|
if ( m_pPilot->client->ps.torsoAnim == BOTH_ATTACK3 )
|
|
{
|
|
if ( m_ucmd.rightmove > 0 ) //right side attack
|
|
{
|
|
Anim = BOTH_VT_ATR_G;
|
|
}
|
|
else if ( m_ucmd.rightmove < 0 ) //left side
|
|
{
|
|
Anim = BOTH_VT_ATL_G;
|
|
}
|
|
else //frontal
|
|
{
|
|
Anim = BOTH_VT_ATF_G;
|
|
}
|
|
}
|
|
else if ( m_pPilot->client->ps.torsoAnim == BOTH_VT_ATR_G ||
|
|
m_pPilot->client->ps.torsoAnim == BOTH_VT_ATL_G ||
|
|
m_pPilot->client->ps.torsoAnim == BOTH_VT_ATF_G )
|
|
{
|
|
Anim = (animNumber_t)m_pPilot->client->ps.torsoAnim;
|
|
iFlags = SETANIM_FLAG_RESTART;
|
|
}
|
|
else
|
|
{
|
|
Anim = (animNumber_t)m_pPilot->client->ps.torsoAnim;
|
|
iFlags = 0;
|
|
}
|
|
break;
|
|
|
|
case WP_THERMAL:
|
|
// Override throw animation.
|
|
if ( m_pPilot->client->ps.torsoAnim == BOTH_THERMAL_THROW
|
|
|| m_pPilot->client->ps.torsoAnim == BOTH_ATTACK10 )
|
|
{
|
|
if ( m_ucmd.rightmove > 0 ) //right side attack
|
|
{
|
|
Anim = BOTH_VT_ATR_T;
|
|
}
|
|
else if ( m_ucmd.rightmove < 0 ) //left side
|
|
{
|
|
Anim = BOTH_VT_ATL_T;
|
|
}
|
|
else //frontal
|
|
{
|
|
Anim = BOTH_VT_ATF_T;
|
|
}
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
Anim = (animNumber_t)m_pPilot->client->ps.torsoAnim;
|
|
iFlags = 0;
|
|
}
|
|
}
|
|
}
|
|
// They're not firing so play the Idle for the weapon.
|
|
else
|
|
{
|
|
iFlags = SETANIM_FLAG_NORMAL;
|
|
iBlend = 1500;
|
|
|
|
switch ( m_pPilot->client->ps.weapon )
|
|
{
|
|
case WP_SABER:
|
|
Anim = BOTH_VT_IDLE_S;
|
|
break;
|
|
|
|
case WP_BLASTER:
|
|
Anim = BOTH_VT_IDLE_G;
|
|
break;
|
|
|
|
case WP_THERMAL:
|
|
Anim = BOTH_VT_IDLE_T;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// Do normal Idle's and other things (crash, air move, etc...)
|
|
else
|
|
{
|
|
// In the Air.
|
|
if ( m_ulFlags & VEH_FLYING )
|
|
{
|
|
iBlend = 1500;
|
|
Anim = BOTH_VT_AIR;
|
|
iFlags = SETANIM_FLAG_OVERRIDE;
|
|
}
|
|
else
|
|
{
|
|
// If we're moving...
|
|
if ( fSpeedPercToMax > 0.0f ) //fSpeedPercToMax >= 0.85f )
|
|
{
|
|
// If we're walking (or our speed is less than 0.275f%)...
|
|
if ( ( m_ucmd.buttons & BUTTON_WALKING ) || fSpeedPercToMax < 0.275f )
|
|
{
|
|
iBlend = 800;
|
|
// Make them lean if we're turning.
|
|
if ( m_ucmd.rightmove < 0 )
|
|
{
|
|
Anim = BOTH_VT_WALK_FWD_L;
|
|
}
|
|
else if ( m_ucmd.rightmove > 0 )
|
|
{
|
|
Anim = BOTH_VT_WALK_FWD_R;
|
|
}
|
|
else
|
|
{
|
|
Anim = BOTH_VT_WALK_FWD;
|
|
}
|
|
}
|
|
// otherwise we're running.
|
|
else
|
|
{
|
|
iBlend = 1000;
|
|
// Make them lean if we're turning.
|
|
if ( m_ucmd.rightmove < 0 )
|
|
{
|
|
Anim = BOTH_VT_RUN_FWD_L;
|
|
}
|
|
else if ( m_ucmd.rightmove > 0 )
|
|
{
|
|
Anim = BOTH_VT_RUN_FWD_R;
|
|
}
|
|
else
|
|
{
|
|
Anim = BOTH_VT_RUN_FWD;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int iChance = Q_irand( 0, 20000 );
|
|
|
|
// Every once in a while buck or do a different idle...
|
|
iFlags = SETANIM_FLAG_NORMAL | SETANIM_FLAG_RESTART;
|
|
iBlend = 600;
|
|
Anim = BOTH_VT_IDLE;
|
|
if ( iChance > 19990 && iChance <= 20000 )
|
|
{
|
|
m_ulFlags |= VEH_BUCKING;
|
|
Anim = BOTH_VT_BUCK;
|
|
iFlags = SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
NPC_SetAnim( m_pPilot, SETANIM_BOTH, Anim, iFlags, iBlend );
|
|
} |