codemp/game/g_vehicles.c File Reference

#include "g_headers.h"
#include "q_shared.h"
#include "g_local.h"
#include "g_functions.h"
#include "g_vehicles.h"
#include "../CGame/cg_Local.h"

Go to the source code of this file.

Defines

#define GAME_INLINE   inline
#define bgEntity_t   gentity_t

Functions

gentity_tNPC_Spawn_Do (gentity_t *pEnt, qboolean fullSpawnNow)
qboolean G_ClearLineOfSight (const vec3_t point1, const vec3_t point2, int ignore, int clipmask)
qboolean G_SetG2PlayerModelInfo (gentity_t *pEnt, const char *modelName, const char *customSkin, const char *surfOff, const char *surfOn)
void G_RemovePlayerModel (gentity_t *pEnt)
void G_ChangePlayerModel (gentity_t *pEnt, const char *newModel)
void G_RemoveWeaponModels (gentity_t *pEnt)
void CG_ChangeWeapon (int num)
float DotToSpot (vec3_t spot, vec3_t from, vec3_t fromAngles)
qboolean Q3_TaskIDPending (gentity_t *ent, taskID_t taskType)
void SetClientViewAngle (gentity_t *ent, vec3_t angle)
void PM_SetAnim (pmove_t *pm, int setAnimParts, int anim, int setAnimFlags, int blendTime)
int PM_AnimLength (int index, animNumber_t anim)
void NPC_SetAnim (gentity_t *ent, int setAnimParts, int anim, int setAnimFlags, int iBlend)
void G_Knockdown (gentity_t *self, gentity_t *attacker, const vec3_t pushDir, float strength, qboolean breakSaberLock)
void PM_SetTorsoAnimTimer (gentity_t *ent, int *torsoAnimTimer, int time)
void PM_SetLegsAnimTimer (gentity_t *ent, int *legsAnimTimer, int time)
qboolean BG_UnrestrainedPitchRoll (playerState_t *ps, Vehicle_t *pVeh)
void Vehicle_SetAnim (gentity_t *ent, int setAnimParts, int anim, int setAnimFlags, int iBlend)
void G_VehicleTrace (trace_t *results, const vec3_t start, const vec3_t tMins, const vec3_t tMaxs, const vec3_t end, int passEntityNum, int contentmask)
Vehicle_tG_IsRidingVehicle (gentity_t *pEnt)
float G_CanJumpToEnemyVeh (Vehicle_t *pVeh, const usercmd_t *pUcmd)
void G_VehicleSpawn (gentity_t *self)
void G_AttachToVehicle (gentity_t *pEnt, usercmd_t **ucmd)
void G_KnockOffVehicle (gentity_t *pRider, gentity_t *self, qboolean bPull)
void G_DrivableATSTDie (gentity_t *self)
void G_DriveATST (gentity_t *pEnt, gentity_t *atst)
void Animate (Vehicle_t *pVeh)
bool ValidateBoard (Vehicle_t *pVeh, bgEntity_t *pEnt)
bool Board (Vehicle_t *pVeh, bgEntity_t *pEnt)
bool VEH_TryEject (Vehicle_t *pVeh, gentity_t *parent, gentity_t *ent, int ejectDir, vec3_t vExitPos)
void G_EjectDroidUnit (Vehicle_t *pVeh, qboolean kill)
bool Eject (Vehicle_t *pVeh, bgEntity_t *pEnt, qboolean forceEject)
bool EjectAll (Vehicle_t *pVeh)
void RegisterAssets (Vehicle_t *pVeh)
void ChangeWeapon (gentity_t *ent, int newWeapon)
bool Initialize (Vehicle_t *pVeh)
GAME_INLINE void SetParent (Vehicle_t *pVeh, bgEntity_t *pParentEntity)
GAME_INLINE void SetPilot (Vehicle_t *pVeh, bgEntity_t *pPilot)
GAME_INLINE bool AddPassenger (Vehicle_t *pVeh)
GAME_INLINE bool Inhabited (Vehicle_t *pVeh)
void G_SetSharedVehicleFunctions (vehicleInfo_t *pVehInfo)

Variables

vmCvar_t cg_thirdPersonAlpha
vec3_t playerMins
vec3_t playerMaxs
cvar_tg_speederControlScheme
cvar_tin_joystick


Define Documentation

#define bgEntity_t   gentity_t
 

Definition at line 41 of file g_vehicles.c.

#define GAME_INLINE   inline
 

Definition at line 40 of file g_vehicles.c.


Function Documentation

GAME_INLINE bool AddPassenger Vehicle_t pVeh  ) 
 

Definition at line 3291 of file g_vehicles.c.

References GAME_INLINE, and Vehicle_t.

Referenced by G_SetSharedVehicleFunctions().

03291 { return false; }

void Animate Vehicle_t pVeh  ) 
 

Definition at line 478 of file g_vehicles.c.

References vehicleInfo_t::AnimateRiders, vehicleInfo_t::AnimateVehicle, Vehicle_s::m_pPilot, Vehicle_s::m_pVehicleInfo, and Vehicle_t.

Referenced by G_SetSharedVehicleFunctions().

00479 {
00480         // Validate a pilot rider.
00481         if ( pVeh->m_pPilot )
00482         {
00483                 if (pVeh->m_pVehicleInfo->AnimateRiders)
00484                 {
00485                         pVeh->m_pVehicleInfo->AnimateRiders( pVeh );
00486                 }
00487         }
00488 
00489         pVeh->m_pVehicleInfo->AnimateVehicle( pVeh );
00490 }

qboolean BG_UnrestrainedPitchRoll playerState_t ps,
Vehicle_t pVeh
 

Definition at line 7785 of file bg_pmove.c.

References bg_fighterAltControl, playerState_s::clientNum, vmCvar_t::integer, playerState_s::m_iVehicleNum, Vehicle_s::m_pVehicleInfo, MAX_CLIENTS, playerState_t, qboolean, qfalse, qtrue, vehicleInfo_t::type, Vehicle_t, and VH_FIGHTER.

Referenced by PM_UpdateViewAngles(), and PM_VehicleViewAngles().

07786 {
07787         if ( bg_fighterAltControl.integer
07788                 && ps->clientNum < MAX_CLIENTS //real client
07789                 && ps->m_iVehicleNum//in a vehicle
07790                 && pVeh //valid vehicle data pointer
07791                 && pVeh->m_pVehicleInfo//valid vehicle info
07792                 && pVeh->m_pVehicleInfo->type == VH_FIGHTER )//fighter
07793                 //FIXME: specify per vehicle instead of assuming true for all fighters
07794                 //FIXME: map/server setting?
07795         {//can roll and pitch without limitation!
07796                 return qtrue;
07797         }
07798         return qfalse;
07799 }

bool Board Vehicle_t pVeh,
bgEntity_t pEnt
 

Definition at line 627 of file g_vehicles.c.

References bgEntity_t, Board(), CG_CenterPrint(), CG_ChangeWeapon(), CHAN_AUTO, gentity_s::client, gentity_s::fly_sound_debounce_time, G_RemoveWeaponModels(), G_Sound(), G_SoundIndex(), playerState_s::generic1, gentity_t, vehicleInfo_t::Ghost, gentity_s::health, vehicleInfo_t::hideRider, level, entityState_s::loopSound, playerState_s::loopSound, Vehicle_s::m_iBoarding, Vehicle_s::m_iDropTime, Vehicle_s::m_iNumPassengers, entityState_s::m_iVehicleNum, playerState_s::m_iVehicleNum, Vehicle_s::m_pOldPilot, Vehicle_s::m_pParentEntity, Vehicle_s::m_pPilot, Vehicle_s::m_ppPassengers, Vehicle_s::m_pVehicleInfo, Vehicle_s::m_ucmd, Vehicle_s::m_ulFlags, Vehicle_s::m_vOrientation, MAX_CLIENTS, vehicleInfo_t::maxPassengers, memset(), NULL, entityState_s::number, vehicleInfo_t::numHands, entityState_s::owner, entityShared_t::ownerNum, gclient_s::ps, gentity_s::r, ROLL, gentity_s::s, SCREEN_HEIGHT, SetClientViewAngle(), vehicleInfo_t::SetPilot, vehicleInfo_t::soundLoop, vehicleInfo_t::soundOn, gentity_s::spawnflags, playerState_s::speed, level_locals_t::time, vehicleInfo_t::type, usercmd_t, vehicleInfo_t::ValidateBoard, vec3_t, VectorCopy, VEH_BUCKING, Vehicle_t, VH_FIGHTER, playerState_s::weapon, and WP_NONE.

Referenced by Board(), G_SetSharedVehicleFunctions(), and G_SetWalkerVehicleFunctions().

00628 {
00629         vec3_t vPlayerDir;
00630         gentity_t *ent = (gentity_t *)pEnt;
00631         gentity_t *parent = (gentity_t *)pVeh->m_pParentEntity;
00632 
00633         // If it's not a valid entity, OR if the vehicle is blowing up (it's dead), OR it's not
00634         // empty, OR we're already being boarded, OR the person trying to get on us is already
00635         // in a vehicle (that was a fun bug :-), leave!
00636         if ( !ent || parent->health <= 0 /*|| !( parent->client->ps.eFlags & EF_EMPTY_VEHICLE )*/ || (pVeh->m_iBoarding > 0) ||
00637 #ifdef _JK2MP
00638                  ( ent->client->ps.m_iVehicleNum ) )
00639 #else
00640                  ( ent->s.m_iVehicleNum != 0 ) )
00641 #endif
00642                 return false;
00643 
00644         // Bucking so we can't do anything (NOTE: Should probably be a better name since fighters don't buck...).
00645         if ( pVeh->m_ulFlags & VEH_BUCKING )
00646                 return false;
00647 
00648         // Validate the entity's ability to board this vehicle.
00649         if ( !pVeh->m_pVehicleInfo->ValidateBoard( pVeh, pEnt ) )
00650                 return false;
00651 
00652         // FIXME FIXME!!! Ask Mike monday where ent->client->ps.eFlags might be getting changed!!! It is always 0 (when it should
00653         // be 1024) so a person riding a vehicle is able to ride another vehicle!!!!!!!!
00654 
00655         // Tell everybody their status.
00656         // ALWAYS let the player be the pilot.
00657         if ( ent->s.number < MAX_CLIENTS )
00658         {
00659                 pVeh->m_pOldPilot = pVeh->m_pPilot;
00660 
00661 
00662 #ifdef _JK2MP
00663                 if ( !pVeh->m_pPilot )
00664                 { //become the pilot, if there isn't one now
00665                         pVeh->m_pVehicleInfo->SetPilot( pVeh, (bgEntity_t *)ent );
00666                 }
00667                 // If we're not yet full...
00668                 else if ( pVeh->m_iNumPassengers < pVeh->m_pVehicleInfo->maxPassengers )
00669                 {
00670                         int i;
00671                         // Find an empty slot and put that passenger here.
00672                         for ( i = 0; i < pVeh->m_pVehicleInfo->maxPassengers; i++ )
00673                         {
00674                                 if ( pVeh->m_ppPassengers[i] == NULL )
00675                                 {
00676                                         pVeh->m_ppPassengers[i] = (bgEntity_t *)ent;
00677 #ifdef QAGAME
00678                                         //Server just needs to tell client which passengernum he is
00679                                         if ( ent->client )
00680                                         {
00681                                                 ent->client->ps.generic1 = i+1;
00682                                         }
00683 #endif
00684                                         break;
00685                                 }
00686                         }
00687                         pVeh->m_iNumPassengers++;
00688                 }
00689                 // We're full, sorry...
00690                 else
00691                 {
00692                         return false;
00693                 }
00694                 ent->s.m_iVehicleNum = parent->s.number;
00695                 if (ent->client)
00696                 {
00697                         ent->client->ps.m_iVehicleNum = ent->s.m_iVehicleNum;
00698                 }
00699                 if ( pVeh->m_pPilot == (bgEntity_t *)ent )
00700                 {
00701                         parent->r.ownerNum = ent->s.number;
00702                         parent->s.owner = parent->r.ownerNum; //for prediction
00703                 }
00704 #else
00705                 pVeh->m_pVehicleInfo->SetPilot( pVeh, ent );
00706                 ent->s.m_iVehicleNum = parent->s.number;
00707                 parent->owner = ent;
00708 #endif
00709 
00710 #ifdef QAGAME           
00711                 {
00712                         gentity_t *gParent = (gentity_t *)parent;
00713                         if ( (gParent->spawnflags&2) )
00714                         {//was being suspended
00715                                 gParent->spawnflags &= ~2;//SUSPENDED - clear this spawnflag, no longer docked, okay to free-fall if not in space
00716                                 //gParent->client->ps.eFlags &= ~EF_RADAROBJECT;
00717                                 G_Sound( gParent, CHAN_AUTO, G_SoundIndex( "sound/vehicles/common/release.wav" ) );
00718                                 if ( gParent->fly_sound_debounce_time )
00719                                 {//we should drop like a rock for a few seconds
00720                                         pVeh->m_iDropTime = level.time + gParent->fly_sound_debounce_time;
00721                                 }
00722                         }
00723                 }
00724 #endif
00725 
00726 #ifndef _JK2MP
00727                 gi.cvar_set( "cg_thirdperson", "1" );                                                           //go to third person
00728                 CG_CenterPrint( "@SP_INGAME_EXIT_VIEW", SCREEN_HEIGHT * 0.95 );         //tell them how to get out!
00729 #endif
00730 
00731                 //FIXME: rider needs to look in vehicle's direction when he gets in
00732                 // Clear these since they're used to turn the vehicle now.
00733                 /*SetClientViewAngle( ent, pVeh->m_vOrientation );
00734                 memset( &parent->client->usercmd, 0, sizeof( usercmd_t ) );
00735                 memset( &pVeh->m_ucmd, 0, sizeof( usercmd_t ) );
00736                 VectorClear( parent->client->ps.viewangles );
00737                 VectorClear( parent->client->ps.delta_angles );*/
00738 
00739                 // Set the looping sound only when there is a pilot (when the vehicle is "on").
00740                 if ( pVeh->m_pVehicleInfo->soundLoop )
00741                 {
00742 #ifdef _JK2MP
00743                         parent->client->ps.loopSound = parent->s.loopSound = pVeh->m_pVehicleInfo->soundLoop;
00744 #else
00745                         parent->s.loopSound = pVeh->m_pVehicleInfo->soundLoop;
00746 #endif
00747                 }
00748         }
00749         else
00750         {
00751                 // If there's no pilot, try to drive this vehicle.
00752                 if ( pVeh->m_pPilot == NULL )
00753                 {
00754 #ifdef _JK2MP
00755                         pVeh->m_pVehicleInfo->SetPilot( pVeh, (bgEntity_t *)ent );
00756                         // TODO: Set pilot should do all this stuff....
00757                         parent->r.ownerNum = ent->s.number;
00758                         parent->s.owner = parent->r.ownerNum; //for prediction
00759 #else
00760                         pVeh->m_pVehicleInfo->SetPilot( pVeh, ent );
00761                         // TODO: Set pilot should do all this stuff....
00762                         parent->owner = ent;
00763 #endif
00764                         // Set the looping sound only when there is a pilot (when the vehicle is "on").
00765                         if ( pVeh->m_pVehicleInfo->soundLoop )
00766                         {
00767 #ifdef _JK2MP
00768                                 parent->client->ps.loopSound = parent->s.loopSound = pVeh->m_pVehicleInfo->soundLoop;
00769 #else
00770                                 parent->s.loopSound = pVeh->m_pVehicleInfo->soundLoop;
00771 #endif
00772                         }
00773 
00774                         parent->client->ps.speed = 0;
00775                         memset( &pVeh->m_ucmd, 0, sizeof( usercmd_t ) );
00776                 }
00777                 // If we're not yet full...
00778                 else if ( pVeh->m_iNumPassengers < pVeh->m_pVehicleInfo->maxPassengers )
00779                 {
00780                         int i;
00781                         // Find an empty slot and put that passenger here.
00782                         for ( i = 0; i < pVeh->m_pVehicleInfo->maxPassengers; i++ )
00783                         {
00784                                 if ( pVeh->m_ppPassengers[i] == NULL )
00785                                 {
00786 #ifdef _JK2MP
00787                                         pVeh->m_ppPassengers[i] = (bgEntity_t *)ent;
00788 #ifdef QAGAME
00789                                         //Server just needs to tell client which passengernum he is
00790                                         if ( ent->client )
00791                                         {
00792                                                 ent->client->ps.generic1 = i+1;
00793                                         }
00794 #endif
00795 #else
00796                                         pVeh->m_ppPassengers[i] = ent;
00797 #endif
00798                                         break;
00799                                 }
00800                         }
00801                         pVeh->m_iNumPassengers++;
00802                 }
00803                 // We're full, sorry...
00804                 else
00805                 {
00806                         return false;
00807                 }
00808         }
00809         
00810         // Make sure the entity knows it's in a vehicle.
00811 #ifdef _JK2MP
00812         ent->client->ps.m_iVehicleNum = parent->s.number;
00813         ent->r.ownerNum = parent->s.number;
00814         ent->s.owner = ent->r.ownerNum; //for prediction
00815         if (pVeh->m_pPilot == (bgEntity_t *)ent)
00816         {
00817                 parent->client->ps.m_iVehicleNum = ent->s.number+1; //always gonna be under MAX_CLIENTS so no worries about 1 byte overflow
00818         }
00819 #else
00820         ent->s.m_iVehicleNum = parent->s.number;
00821         ent->owner = parent;
00822         parent->s.m_iVehicleNum = ent->s.number+1;
00823 #endif
00824 
00825         //memset( &ent->client->usercmd, 0, sizeof( usercmd_t ) );
00826 
00827         //FIXME: no saber or weapons if numHands = 2, should switch to speeder weapon, no attack anim on player
00828         if ( pVeh->m_pVehicleInfo->numHands == 2 )
00829         {//switch to vehicle weapon
00830 #ifndef _JK2MP //rwwFIXMEFIXMEFIXME
00831                 if (ent->s.number<MAX_CLIENTS)
00832                 {
00833                         CG_ChangeWeapon(WP_NONE);
00834                 }
00835 
00836                 ent->client->ps.weapon = WP_NONE;
00837                 G_RemoveWeaponModels( ent );
00838 #endif
00839         }
00840 
00841         if ( pVeh->m_pVehicleInfo->hideRider )
00842         {//hide the rider
00843                 pVeh->m_pVehicleInfo->Ghost( pVeh, (bgEntity_t *)ent );
00844         }
00845 
00846         // Play the start sounds
00847         if ( pVeh->m_pVehicleInfo->soundOn )
00848         {
00849 #ifdef _JK2MP
00850                 G_Sound( parent, CHAN_AUTO, pVeh->m_pVehicleInfo->soundOn );
00851 #else
00852                 // NOTE: Use this type so it's spatialized and updates play origin as bike moves - MCG
00853                 G_SoundIndexOnEnt( parent, CHAN_AUTO, pVeh->m_pVehicleInfo->soundOn );
00854 #endif
00855         }
00856 
00857 #ifdef VEH_CONTROL_SCHEME_4
00858         if ( pVeh->m_pVehicleInfo->type == VH_FIGHTER )
00859         {//clear their angles
00860                 FighterStorePilotViewAngles( pVeh, (bgEntity_t *)parent );
00861         }
00862 #endif //VEH_CONTROL_SCHEME_4
00863 
00864         VectorCopy( pVeh->m_vOrientation, vPlayerDir );
00865         vPlayerDir[ROLL] = 0;
00866         SetClientViewAngle( ent, vPlayerDir );
00867 
00868         return true;
00869 }

void CG_ChangeWeapon int  num  ) 
 

void ChangeWeapon gentity_t ent,
int  newWeapon
 

float DotToSpot vec3_t  spot,
vec3_t  from,
vec3_t  fromAngles
 

bool Eject Vehicle_t pVeh,
bgEntity_t pEnt,
qboolean  forceEject
 

Definition at line 1016 of file g_vehicles.c.

References BG_SetLegsAnimTimer(), BG_SetTorsoAnimTimer(), bgEntity_t, cg, CG_ChangeWeapon(), gentity_s::client, clientPersistant_t::cmd, CON_CONNECTED, clientPersistant_t::connected, entityShared_t::contents, CONTENTS_BODY, ENTITYNUM_NONE, G_EjectDroidUnit(), G_RemoveWeaponModels(), G_SetOrigin(), gentity_t, gentity_s::health, vehicleInfo_t::hideRider, gentity_s::inuse, level, entityState_s::loopSound, playerState_s::loopSound, Vehicle_s::m_bWasBoarding, Vehicle_s::m_EjectDir, Vehicle_s::m_iBoarding, Vehicle_s::m_iNumPassengers, entityState_s::m_iVehicleNum, playerState_s::m_iVehicleNum, Vehicle_s::m_pDroidUnit, Vehicle_s::m_pOldPilot, Vehicle_s::m_pParentEntity, Vehicle_s::m_pPilot, Vehicle_s::m_ppPassengers, Vehicle_s::m_pVehicleInfo, Vehicle_s::m_ucmd, Vehicle_s::m_vOrientation, MAX_CLIENTS, vehicleInfo_t::maxPassengers, memset(), NULL, entityState_s::number, playerState_s::origin, entityState_s::owner, entityShared_t::ownerNum, gclient_s::pers, PITCH, PM_SetLegsAnimTimer(), PM_SetTorsoAnimTimer(), gclient_s::ps, qboolean, qfalse, qtrue, gentity_s::r, ROLL, bgEntity_s::s, gentity_s::s, SetClientViewAngle(), vehicleInfo_t::SetPilot, gclient_s::solidHack, level_locals_t::time, trap_LinkEntity(), vehicleInfo_t::UnGhost, usercmd_t, vec3_t, VectorCopy, VEH_EJECT_BOTTOM, VEH_EJECT_LEFT, VEH_TryEject(), Vehicle_t, playerState_s::viewangles, playerState_s::weapon, WP_NONE, and YAW.

Referenced by G_SetSharedVehicleFunctions().

01017 {
01018         gentity_t       *parent;
01019         vec3_t          vExitPos;
01020 #ifndef _JK2MP
01021         vec3_t          vPlayerDir;
01022 #endif
01023         gentity_t       *ent = (gentity_t *)pEnt;
01024         int                     firstEjectDir;
01025 
01026 #ifdef _JK2MP
01027         qboolean        taintedRider = qfalse;
01028         qboolean        deadRider = qfalse;
01029 
01030         if ( pEnt == pVeh->m_pDroidUnit )
01031         {
01032                 G_EjectDroidUnit( pVeh, qfalse );
01033                 return true;
01034         }
01035 
01036         if (ent)
01037         {
01038                 if (!ent->inuse || !ent->client || ent->client->pers.connected != CON_CONNECTED)
01039                 {
01040                         taintedRider = qtrue;
01041                         parent = (gentity_t *)pVeh->m_pParentEntity;
01042                         goto getItOutOfMe;
01043                 }
01044                 else if (ent->health < 1)
01045                 {
01046                         deadRider = qtrue;
01047                 }
01048         }
01049 #endif
01050 
01051         // Validate.
01052         if ( !ent )
01053         {
01054                 return false;
01055         }
01056         if ( !forceEject )
01057         {
01058                 if ( !( pVeh->m_iBoarding == 0 || pVeh->m_iBoarding == -999 || ( pVeh->m_iBoarding < -3 && pVeh->m_iBoarding >= -9 ) ) )
01059                 {
01060 #ifdef _JK2MP //I don't care, if he's dead get him off even if he died while boarding
01061                         deadRider = qtrue;
01062                         pVeh->m_iBoarding = 0;
01063                         pVeh->m_bWasBoarding = false;
01064 #else
01065                         return false;
01066 #endif
01067                 }
01068         }
01069 
01070 #ifndef _JK2MP //rwwFIXMEFIXMEFIXME
01071         if (ent->s.number<MAX_CLIENTS)
01072         {
01073                 CG_ChangeWeapon(WP_NONE);
01074         }
01075         ent->client->ps.weapon = WP_NONE;
01076         G_RemoveWeaponModels( ent );
01077 #endif
01078 
01079         parent = (gentity_t *)pVeh->m_pParentEntity;
01080 
01081         //Try ejecting in every direction
01082         if ( pVeh->m_EjectDir < VEH_EJECT_LEFT )
01083         {
01084                 pVeh->m_EjectDir = VEH_EJECT_LEFT;
01085         }
01086         else if ( pVeh->m_EjectDir > VEH_EJECT_BOTTOM )
01087         {
01088                 pVeh->m_EjectDir = VEH_EJECT_BOTTOM;
01089         }
01090         firstEjectDir = pVeh->m_EjectDir;
01091         while ( !VEH_TryEject( pVeh, parent, ent, pVeh->m_EjectDir, vExitPos ) )
01092         {
01093                 pVeh->m_EjectDir++;
01094                 if ( pVeh->m_EjectDir > VEH_EJECT_BOTTOM )
01095                 {
01096                         pVeh->m_EjectDir = VEH_EJECT_LEFT;
01097                 }
01098                 if ( pVeh->m_EjectDir == firstEjectDir )
01099                 {//they all failed
01100 #ifdef _JK2MP
01101                         if (!deadRider)
01102                         { //if he's dead.. just shove him in solid, who cares.
01103                                 return false;
01104                         }
01105 #endif
01106                         if ( forceEject )
01107                         {//we want to always get out, just eject him here
01108                                 VectorCopy( ent->currentOrigin, vExitPos );
01109                                 break;
01110                         }
01111                         else
01112                         {//can't eject
01113                                 return false;
01114                         }
01115                 }
01116         }
01117 
01118         // Move them to the exit position.
01119         G_SetOrigin( ent, vExitPos );
01120 #ifdef _JK2MP
01121         VectorCopy(ent->currentOrigin, ent->client->ps.origin);
01122         trap_LinkEntity( ent );
01123 #else
01124         gi.linkentity( ent );
01125 #endif
01126 
01127         // If it's the player, stop overrides.
01128         if ( ent->s.number < MAX_CLIENTS )
01129         {
01130 #ifndef _JK2MP
01131                 cg.overrides.active = 0;
01132 #else
01133 
01134 #endif
01135         }
01136 
01137 #ifdef _JK2MP //in MP if someone disconnects on us, we still have to clear our owner
01138 getItOutOfMe:
01139 #endif
01140 
01141         // If he's the pilot...
01142         if ( (gentity_t *)pVeh->m_pPilot == ent )
01143         {
01144 #ifdef _JK2MP
01145                 int j = 0;
01146 #endif
01147 
01148                 pVeh->m_pPilot = NULL;
01149 #ifdef _JK2MP
01150                 parent->r.ownerNum = ENTITYNUM_NONE;
01151                 parent->s.owner = parent->r.ownerNum; //for prediction
01152 
01153                 //keep these current angles
01154                 //SetClientViewAngle( parent, pVeh->m_vOrientation );
01155                 memset( &parent->client->pers.cmd, 0, sizeof( usercmd_t ) );
01156 #else
01157                 parent->owner = NULL;
01158 
01159                 //keep these current angles
01160                 //SetClientViewAngle( parent, pVeh->m_vOrientation );
01161                 memset( &parent->client->usercmd, 0, sizeof( usercmd_t ) );
01162 #endif
01163                 memset( &pVeh->m_ucmd, 0, sizeof( usercmd_t ) );
01164 
01165 #ifdef _JK2MP //if there are some passengers, promote the first passenger to pilot
01166                 while (j < pVeh->m_iNumPassengers)
01167                 {
01168                         if (pVeh->m_ppPassengers[j])
01169                         {
01170                                 int k = 1;
01171                                 pVeh->m_pVehicleInfo->SetPilot( pVeh, pVeh->m_ppPassengers[j] );
01172                                 parent->r.ownerNum = pVeh->m_ppPassengers[j]->s.number;
01173                                 parent->s.owner = parent->r.ownerNum; //for prediction
01174                                 parent->client->ps.m_iVehicleNum = pVeh->m_ppPassengers[j]->s.number+1;
01175 
01176                                 //rearrange the passenger slots now..
01177 #ifdef QAGAME
01178                                 //Server just needs to tell client he's not a passenger anymore
01179                                 if ( ((gentity_t *)pVeh->m_ppPassengers[j])->client )
01180                                 {
01181                                         ((gentity_t *)pVeh->m_ppPassengers[j])->client->ps.generic1 = 0;
01182                                 }
01183 #endif
01184                                 pVeh->m_ppPassengers[j] = NULL;
01185                                 while (k < pVeh->m_iNumPassengers)
01186                                 {
01187                                         if (!pVeh->m_ppPassengers[k-1])
01188                                         { //move down
01189                                                 pVeh->m_ppPassengers[k-1] = pVeh->m_ppPassengers[k];
01190                                                 pVeh->m_ppPassengers[k] = NULL;
01191 #ifdef QAGAME
01192                                                 //Server just needs to tell client which passenger he is
01193                                                 if ( ((gentity_t *)pVeh->m_ppPassengers[k-1])->client )
01194                                                 {
01195                                                         ((gentity_t *)pVeh->m_ppPassengers[k-1])->client->ps.generic1 = k;
01196                                                 }
01197 #endif
01198                                         }
01199                                         k++;
01200                                 }
01201                                 pVeh->m_iNumPassengers--;
01202 
01203                                 break;
01204                         }
01205                         j++;
01206                 }
01207 #endif
01208         }
01209         else if (ent==(gentity_t *)pVeh->m_pOldPilot)
01210         {
01211                 pVeh->m_pOldPilot = 0;
01212         }
01213         else
01214         {
01215                 int i;
01216                 // Look for this guy in the passenger list.
01217                 for ( i = 0; i < pVeh->m_pVehicleInfo->maxPassengers; i++ )
01218                 {
01219                         // If we found him...
01220                         if ( (gentity_t *)pVeh->m_ppPassengers[i] == ent )
01221                         {
01222 #ifdef QAGAME
01223                                 //Server just needs to tell client he's not a passenger anymore
01224                                 if ( ((gentity_t *)pVeh->m_ppPassengers[i])->client )
01225                                 {
01226                                         ((gentity_t *)pVeh->m_ppPassengers[i])->client->ps.generic1 = 0;
01227                                 }
01228 #endif
01229                                 pVeh->m_ppPassengers[i] = NULL;
01230                                 pVeh->m_iNumPassengers--;
01231                                 break;
01232                         }
01233                 }
01234 
01235                 // Didn't find him, can't eject because they aren't in the vehicle (hopefully)!
01236                 if ( i == pVeh->m_pVehicleInfo->maxPassengers )
01237                 {
01238                         return false;
01239                 }
01240         }
01241 
01242 #ifdef _JK2MP //I hate adding these!
01243         if (!taintedRider)
01244         {
01245 #endif
01246                 if ( pVeh->m_pVehicleInfo->hideRider )
01247                 {
01248                         pVeh->m_pVehicleInfo->UnGhost( pVeh, (bgEntity_t *)ent );
01249                 }
01250 #ifdef _JK2MP
01251         }
01252 #endif
01253 
01254         // If the vehicle now has no pilot...
01255         if ( pVeh->m_pPilot == NULL  )
01256         {
01257 #ifdef _JK2MP
01258                 parent->client->ps.loopSound = parent->s.loopSound = 0;
01259 #else
01260                 parent->s.loopSound = 0;
01261 #endif
01262                 // Completely empty vehicle...?
01263                 if ( pVeh->m_iNumPassengers == 0 )
01264                 {
01265 #ifdef _JK2MP
01266                         parent->client->ps.m_iVehicleNum = 0;
01267 #else
01268                         parent->s.m_iVehicleNum = 0;
01269 #endif
01270                 }
01271         }
01272 
01273 #ifdef _JK2MP
01274         if (taintedRider)
01275         { //you can go now
01276                 pVeh->m_iBoarding = level.time + 1000;
01277                 return true;
01278         }
01279 #endif
01280 
01281         // Client not in a vehicle.
01282 #ifdef _JK2MP
01283         ent->client->ps.m_iVehicleNum = 0;
01284         ent->r.ownerNum = ENTITYNUM_NONE;
01285         ent->s.owner = ent->r.ownerNum; //for prediction
01286 
01287         ent->client->ps.viewangles[PITCH] = 0.0f;
01288         ent->client->ps.viewangles[ROLL] = 0.0f;
01289         ent->client->ps.viewangles[YAW] = pVeh->m_vOrientation[YAW];
01290         SetClientViewAngle(ent, ent->client->ps.viewangles);
01291 
01292         if (ent->client->solidHack)
01293         {
01294                 ent->client->solidHack = 0;
01295                 ent->r.contents = CONTENTS_BODY;
01296         }
01297 #else
01298         ent->owner = NULL;      
01299 #endif
01300         ent->s.m_iVehicleNum = 0;
01301 
01302         // Jump out.
01303 /*      if ( ent->client->ps.velocity[2] < JUMP_VELOCITY )
01304         {
01305                 ent->client->ps.velocity[2] = JUMP_VELOCITY;
01306         }
01307         else
01308         {
01309                 ent->client->ps.velocity[2] += JUMP_VELOCITY;
01310         }*/
01311 
01312         // Make sure entity is facing the direction it got off at.
01313 #ifndef _JK2MP
01314         VectorCopy( pVeh->m_vOrientation, vPlayerDir );
01315         vPlayerDir[ROLL] = 0;
01316         SetClientViewAngle( ent, vPlayerDir );
01317 #endif
01318 
01319         //if was using vehicle weapon, remove it and switch to normal weapon when hop out...
01320         if ( ent->client->ps.weapon == WP_NONE )
01321         {//FIXME: check against this vehicle's gun from the g_vehicleInfo table
01322                 //remove the vehicle's weapon from me
01323                 //ent->client->ps.stats[STAT_WEAPONS] &= ~( 1 << WP_EMPLACED_GUN );
01324                 //ent->client->ps.ammo[weaponData[WP_EMPLACED_GUN].ammoIndex] = 0;//maybe store this ammo on the vehicle before clearing it?
01325                 //switch back to a normal weapon we're carrying
01326                 
01327                 //FIXME: store the weapon we were using when we got on and restore that when hop off
01328 /*              if ( (ent->client->ps.stats[STAT_WEAPONS]&(1<<WP_SABER)) )
01329                 {
01330                         CG_ChangeWeapon( WP_SABER );
01331                 }
01332                 else
01333                 {//go through all weapons and switch to highest held
01334                         for ( int checkWp = WP_NUM_WEAPONS-1; checkWp > WP_NONE; checkWp-- )
01335                         {
01336                                 if ( (ent->client->ps.stats[STAT_WEAPONS]&(1<<checkWp)) )
01337                                 {
01338                                         CG_ChangeWeapon( checkWp );
01339                                 }
01340                         }
01341                         if ( checkWp == WP_NONE )
01342                         {
01343                                 CG_ChangeWeapon( WP_NONE );
01344                         }
01345                 }*/
01346         }
01347         else
01348         {//FIXME: if they have their saber out:
01349                 //if dualSabers, add the second saber into the left hand
01350                 //saber[0] has more than one blade, turn them all on
01351                 //NOTE: this is because you're only allowed to use your first saber's first blade on a vehicle
01352         }
01353 
01354 /*      if ( !ent->s.number && ent->client->ps.weapon != WP_SABER 
01355                 && cg_gunAutoFirst.value )
01356         {
01357                 gi.cvar_set( "cg_thirdperson", "0" );
01358         }*/
01359 #ifdef _JK2MP
01360         BG_SetLegsAnimTimer( &ent->client->ps, 0 );
01361         BG_SetTorsoAnimTimer( &ent->client->ps, 0 );
01362 #else
01363         PM_SetLegsAnimTimer( ent, &ent->client->ps.legsAnimTimer, 0 );
01364         PM_SetTorsoAnimTimer( ent, &ent->client->ps.torsoAnimTimer, 0 );
01365 #endif
01366 
01367         // Set how long until this vehicle can be boarded again.
01368         pVeh->m_iBoarding = level.time + 1000;
01369 
01370         return true;
01371 }

bool EjectAll Vehicle_t pVeh  ) 
 

Definition at line 1374 of file g_vehicles.c.

References CHAN_VOICE, vehicleInfo_t::Eject, G_Damage(), G_EjectDroidUnit(), G_MuteSound(), gentity_t, vehicleInfo_t::killRiderOnDeath, Vehicle_s::m_bWasBoarding, Vehicle_s::m_EjectDir, Vehicle_s::m_iBoarding, Vehicle_s::m_iNumPassengers, Vehicle_s::m_pDroidUnit, Vehicle_s::m_pOldPilot, Vehicle_s::m_pPilot, Vehicle_s::m_ppPassengers, Vehicle_s::m_pVehicleInfo, vehicleInfo_t::maxPassengers, MOD_SUICIDE, NULL, entityState_s::number, entityState_s::origin, qtrue, gentity_s::s, VEH_EJECT_TOP, and Vehicle_t.

Referenced by G_SetSharedVehicleFunctions().

01375 {
01376         // TODO: Setup a default escape for ever vehicle type.
01377 
01378         pVeh->m_EjectDir = VEH_EJECT_TOP;
01379         // Make sure no other boarding calls exist. We MUST exit.
01380         pVeh->m_iBoarding = 0;
01381         pVeh->m_bWasBoarding = false;
01382 
01383         // Throw them off.
01384         if ( pVeh->m_pPilot )
01385         {
01386 #ifdef QAGAME
01387                 gentity_t *pilot = (gentity_t*)pVeh->m_pPilot;
01388 #endif
01389                 pVeh->m_pVehicleInfo->Eject( pVeh, pVeh->m_pPilot, qtrue );
01390 #ifdef QAGAME
01391                 if ( pVeh->m_pVehicleInfo->killRiderOnDeath && pilot )
01392                 {//Kill them, too
01393                         //FIXME: proper origin, MOD and attacker (for credit/death message)?  Get from vehicle?
01394                         G_MuteSound(pilot->s.number, CHAN_VOICE);
01395                         G_Damage( pilot, NULL, NULL, NULL, pilot->s.origin, 10000, 0, MOD_SUICIDE );
01396                 }
01397 #endif
01398         }
01399         if ( pVeh->m_pOldPilot )
01400         {
01401 #ifdef QAGAME
01402                 gentity_t *pilot = (gentity_t*)pVeh->m_pOldPilot;
01403 #endif
01404                 pVeh->m_pVehicleInfo->Eject( pVeh, pVeh->m_pOldPilot, qtrue );
01405 #ifdef QAGAME
01406                 if ( pVeh->m_pVehicleInfo->killRiderOnDeath && pilot )
01407                 {//Kill them, too
01408                         //FIXME: proper origin, MOD and attacker (for credit/death message)?  Get from vehicle?
01409                         G_MuteSound(pilot->s.number, CHAN_VOICE);
01410                         G_Damage( pilot, NULL, NULL, NULL, pilot->s.origin, 10000, 0, MOD_SUICIDE );
01411                 }
01412 #endif
01413         }
01414         if ( pVeh->m_iNumPassengers )
01415         {
01416                 int i;
01417 
01418                 for ( i = 0; i < pVeh->m_pVehicleInfo->maxPassengers; i++ )
01419                 {
01420                         if ( pVeh->m_ppPassengers[i] )
01421                         {
01422 #ifdef QAGAME
01423                                 gentity_t *rider = (gentity_t*)pVeh->m_ppPassengers[i];
01424 #endif
01425                                 pVeh->m_pVehicleInfo->Eject( pVeh, pVeh->m_ppPassengers[i], qtrue );
01426 #ifdef QAGAME
01427                                 if ( pVeh->m_pVehicleInfo->killRiderOnDeath && rider )
01428                                 {//Kill them, too
01429                                         //FIXME: proper origin, MOD and attacker (for credit/death message)?  Get from vehicle?
01430                                         G_MuteSound(rider->s.number, CHAN_VOICE);
01431                                         G_Damage( rider, NULL, NULL, NULL, rider->s.origin, 10000, 0, MOD_SUICIDE );//FIXME: proper MOD?  Get from vehicle?
01432                                 }
01433 #endif
01434                         }
01435                 }
01436                 pVeh->m_iNumPassengers = 0;
01437         }
01438         
01439         if ( pVeh->m_pDroidUnit )
01440         {
01441                 G_EjectDroidUnit( pVeh, pVeh->m_pVehicleInfo->killRiderOnDeath );
01442         }
01443 
01444         return true;
01445 }

void G_AttachToVehicle gentity_t pEnt,
usercmd_t **  ucmd
 

Definition at line 244 of file g_vehicles.c.

References cg, gentity_s::client, g_entities, G_SetOrigin(), gentity_t, gentity_s::ghoul2, level, gentity_s::m_pVehicle, Vehicle_s::m_vOrientation, gentity_s::modelScale, NULL, playerState_s::origin, ORIGIN, entityShared_t::ownerNum, gclient_s::ps, gentity_s::r, gentity_s::s, cg_t::time, level_locals_t::time, trap_G2API_AddBolt(), trap_G2API_GetBoltMatrix(), trap_LinkEntity(), ucmd, usercmd_t, and gentity_s::waypoint.

00245 {
00246         gentity_t               *vehEnt;
00247         mdxaBone_t              boltMatrix;
00248         gentity_t               *ent;
00249 #ifdef _JK2MP
00250         int                             crotchBolt;
00251 #endif
00252 
00253         if ( !pEnt || !ucmd )
00254                 return;
00255 
00256         ent = (gentity_t *)pEnt;
00257 
00258 #ifdef _JK2MP
00259         vehEnt = &g_entities[ent->r.ownerNum];
00260 #else
00261         vehEnt = ent->owner;
00262 #endif
00263         ent->waypoint = vehEnt->waypoint; // take the veh's waypoint as your own
00264 
00265         if ( !vehEnt->m_pVehicle )
00266                 return;
00267 
00268 #ifdef _JK2MP
00269         crotchBolt = trap_G2API_AddBolt(vehEnt->ghoul2, 0, "*driver");
00270 
00271         // Get the driver tag.
00272         trap_G2API_GetBoltMatrix( vehEnt->ghoul2, 0, crotchBolt, &boltMatrix,
00273                                                         vehEnt->m_pVehicle->m_vOrientation, vehEnt->currentOrigin,
00274                                                         level.time, NULL, vehEnt->modelScale );
00275         BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, ent->client->ps.origin );
00276         G_SetOrigin(ent, ent->client->ps.origin);
00277         trap_LinkEntity( ent );
00278 #else
00279         // Get the driver tag.
00280         gi.G2API_GetBoltMatrix( vehEnt->ghoul2, vehEnt->playerModel, vehEnt->crotchBolt, &boltMatrix,
00281                                                         vehEnt->m_pVehicle->m_vOrientation, vehEnt->currentOrigin,
00282                                                         (cg.time?cg.time:level.time), NULL, vehEnt->s.modelScale );
00283         gi.G2API_GiveMeVectorFromMatrix( boltMatrix, ORIGIN, ent->client->ps.origin );
00284         gi.linkentity( ent );
00285 #endif
00286 }

float G_CanJumpToEnemyVeh Vehicle_t pVeh,
const usercmd_t pUcmd
 

Definition at line 121 of file g_vehicles.c.

References AngleVectors(), DotProduct, gentity_s::enemy, G_IsRidingVehicle(), gentity_t, level, Vehicle_s::m_pParentEntity, Vehicle_s::m_pPilot, Q_irand(), usercmd_s::rightmove, level_locals_t::time, usercmd_t, vec3_t, VectorNormalize(), VectorSubtract, and Vehicle_t.

00122 {
00123 #ifndef _JK2MP
00124         gentity_t*      rider = pVeh->m_pPilot;
00125 
00126         // If There Is An Enemy And We Are At The Same Z Height
00127         //------------------------------------------------------
00128         if (rider && 
00129                 rider->enemy && 
00130                 pUcmd->rightmove && 
00131                 fabsf(rider->enemy->currentOrigin[2] - rider->currentOrigin[2])<50.0f)
00132         {
00133                 if (level.time<pVeh->m_safeJumpMountTime)
00134                 {
00135                         return pVeh->m_safeJumpMountRightDot;
00136                 }
00137 
00138 
00139                 // If The Enemy Is Riding Another Vehicle
00140                 //----------------------------------------
00141                 Vehicle_t*      enemyVeh = G_IsRidingVehicle(rider->enemy);
00142                 if (enemyVeh)
00143                 {
00144                         vec3_t  enemyFwd;
00145                         vec3_t  toEnemy;
00146                         float   toEnemyDistance;
00147                         vec3_t  riderFwd;
00148                         vec3_t  riderRight;
00149                         float   riderRightDot;
00150 
00151                         // If He Is Close Enough And Going The Same Speed
00152                         //------------------------------------------------
00153                         VectorSubtract(rider->enemy->currentOrigin, rider->currentOrigin, toEnemy);
00154                         toEnemyDistance = VectorNormalize(toEnemy);
00155                         if (toEnemyDistance<70.0f && 
00156                                 pVeh->m_pParentEntity->resultspeed>100.0f &&
00157                                 fabsf(pVeh->m_pParentEntity->resultspeed - enemyVeh->m_pParentEntity->resultspeed)<100.0f)
00158                         {
00159                                 // If He Is Either To The Left Or Right Of Me
00160                                 //--------------------------------------------
00161                                 AngleVectors(rider->currentAngles, riderFwd, riderRight, 0);
00162                                 riderRightDot = DotProduct(riderRight, toEnemy);
00163                                 if ((pUcmd->rightmove>0 && riderRightDot>0.2) || (pUcmd->rightmove<0 &&riderRightDot<-0.2))
00164                                 {
00165                                         // If We Are Both Going About The Same Direction
00166                                         //-----------------------------------------------
00167                                         AngleVectors(rider->enemy->currentAngles, enemyFwd, 0, 0);
00168                                         if (DotProduct(enemyFwd, riderFwd)>0.2f)
00169                                         {
00170                                                 pVeh->m_safeJumpMountTime = level.time + Q_irand(3000, 4000);   // Ok, now you get a 3 sec window
00171                                                 pVeh->m_safeJumpMountRightDot = riderRightDot;
00172                                                 return riderRightDot;
00173                                         }// Same Direction?
00174                                 }// To Left Or Right?
00175                         }// Close Enough & Same Speed?
00176                 }// Enemy Riding A Vehicle?
00177         }// Has Enemy And On Same Z-Height
00178 #endif
00179         return 0.0f;
00180 }

void G_ChangePlayerModel gentity_t pEnt,
const char *  newModel
 

Referenced by G_DriveATST().

qboolean G_ClearLineOfSight const vec3_t  point1,
const vec3_t  point2,
int  ignore,
int  clipmask
 

Definition at line 11 of file NPC_senses.c.

References trace_t::endpos, EntIsGlass(), trace_t::entityNum, trace_t::fraction, g_entities, gentity_t, NULL, entityState_s::number, qboolean, qfalse, qtrue, gentity_s::s, trap_Trace(), vec3_t, and VectorCopy.

Referenced by G_FindLocalInterestPoint().

00012 {
00013         trace_t         tr;
00014         gentity_t       *hit;
00015 
00016         trap_Trace ( &tr, point1, NULL, NULL, point2, ignore, clipmask );
00017         if ( tr.fraction == 1.0 ) 
00018         {
00019                 return qtrue;
00020         }
00021 
00022         hit = &g_entities[ tr.entityNum ];
00023         if(EntIsGlass(hit))
00024         {
00025                 vec3_t  newpoint1;
00026                 VectorCopy(tr.endpos, newpoint1);
00027                 trap_Trace (&tr, newpoint1, NULL, NULL, point2, hit->s.number, clipmask );
00028 
00029                 if ( tr.fraction == 1.0 ) 
00030                 {
00031                         return qtrue;
00032                 }
00033         }
00034 
00035         return qfalse;
00036 }

void G_DrivableATSTDie gentity_t self  ) 
 

Definition at line 368 of file g_vehicles.c.

References gentity_t.

00369 {
00370 }

void G_DriveATST gentity_t pEnt,
gentity_t atst
 

Definition at line 372 of file g_vehicles.c.

References playerState_s::ammo, ammoData, weaponData_s::ammoIndex, bg_itemlist, BOTH_STAND1, cg, CG_ChangeWeapon(), CG_RegisterItemVisuals(), cg_thirdPersonAlpha, CLASS_ATST, gentity_s::client, CROUCH_MAXS_2, DEFAULT_MAXS_2, playerState_s::eFlags, FL_SHIELDED, gentity_s::flags, G_ChangePlayerModel(), G_RemovePlayerModel(), G_RemoveWeaponModels(), G_SetG2PlayerModelInfo(), G_Sound(), G_SoundIndex(), gentity_t, gentity_s::ghoul2, gitem_t, gclient_s::NPC_class, NPC_SetAnim(), gentity_s::NPC_type, NULL, playerMaxs, playerMins, gclient_s::ps, gentity_s::s, SETANIM_BOTH, SETANIM_FLAG_OVERRIDE, STANDARD_VIEWHEIGHT_OFFSET, STAT_WEAPONS, playerState_s::stats, vmCvar_t::value, VectorCopy, VectorSet, playerState_s::viewheight, weaponData, WP_BLASTER, WP_BOWCASTER, WP_EMPLACED_GUN, and WP_ROCKET_LAUNCHER.

00373 {
00374         if ( pEnt->NPC_type && pEnt->client && (pEnt->client->NPC_class == CLASS_ATST) )
00375         {//already an atst, switch back
00376                 //open hatch
00377                 G_RemovePlayerModel( pEnt );
00378                 pEnt->NPC_type = "player";
00379                 pEnt->client->NPC_class = CLASS_PLAYER;
00380                 pEnt->flags &= ~FL_SHIELDED;
00381                 pEnt->client->ps.eFlags &= ~EF_IN_ATST;
00382                 //size
00383                 VectorCopy( playerMins, pEnt->mins );
00384                 VectorCopy( playerMaxs, pEnt->maxs );
00385                 pEnt->client->crouchheight = CROUCH_MAXS_2;
00386                 pEnt->client->standheight = DEFAULT_MAXS_2;
00387                 G_ChangePlayerModel( pEnt, pEnt->NPC_type );
00388                 //G_SetG2PlayerModel( pEnt, pEnt->NPC_type, NULL, NULL, NULL );
00389 
00390                 //FIXME: reset/4 their weapon
00391                 pEnt->client->ps.stats[STAT_WEAPONS] &= ~(( 1 << WP_ATST_MAIN )|( 1 << WP_ATST_SIDE ));
00392                 pEnt->client->ps.ammo[weaponData[WP_ATST_MAIN].ammoIndex] = 0;
00393                 pEnt->client->ps.ammo[weaponData[WP_ATST_SIDE].ammoIndex] = 0;
00394                 CG_ChangeWeapon( WP_BLASTER );
00395                 //camera
00396                 //if ( pEnt->client->ps.weapon != WP_SABER )
00397                 {
00398                         gi.cvar_set( "cg_thirdperson", "0" );
00399                 }
00400                 cg.overrides.active &= ~(CG_OVERRIDE_3RD_PERSON_RNG|CG_OVERRIDE_3RD_PERSON_VOF|CG_OVERRIDE_3RD_PERSON_POF|CG_OVERRIDE_3RD_PERSON_APH);
00401                 cg.overrides.thirdPersonRange = cg.overrides.thirdPersonVertOffset = cg.overrides.thirdPersonPitchOffset = 0;
00402                 cg.overrides.thirdPersonAlpha = cg_thirdPersonAlpha.value;
00403                 pEnt->client->ps.viewheight = pEnt->maxs[2] + STANDARD_VIEWHEIGHT_OFFSET;
00404                 //pEnt->mass = 10;
00405         }
00406         else
00407         {//become an atst
00408                 pEnt->NPC_type = "atst";
00409                 pEnt->client->NPC_class = CLASS_ATST;
00410                 pEnt->client->ps.eFlags |= EF_IN_ATST;
00411                 pEnt->flags |= FL_SHIELDED;
00412                 //size
00413                 VectorSet( pEnt->mins, ATST_MINS0, ATST_MINS1, ATST_MINS2 );
00414                 VectorSet( pEnt->maxs, ATST_MAXS0, ATST_MAXS1, ATST_MAXS2 );
00415                 pEnt->client->crouchheight = ATST_MAXS2;
00416                 pEnt->client->standheight = ATST_MAXS2;
00417                 if ( !atst )
00418                 {//no pEnt to copy from
00419                         G_ChangePlayerModel( pEnt, "atst" );
00420                         //G_SetG2PlayerModel( pEnt, "atst", NULL, NULL, NULL );
00421                         NPC_SetAnim( pEnt, SETANIM_BOTH, BOTH_STAND1, SETANIM_FLAG_OVERRIDE, 200 );
00422                 }
00423                 else
00424                 {
00425                         G_RemovePlayerModel( pEnt );
00426                         G_RemoveWeaponModels( pEnt );
00427                         gi.G2API_CopyGhoul2Instance( atst->ghoul2, pEnt->ghoul2 );
00428                         pEnt->playerModel = 0;
00429                         G_SetG2PlayerModelInfo( pEnt, "atst", NULL, NULL, NULL );
00430                         //turn off hatch underside
00431                         gi.G2API_SetSurfaceOnOff( &pEnt->ghoul2[pEnt->playerModel], "head_hatchcover", 0x00000002/*G2SURFACEFLAG_OFF*/ );
00432                         G_Sound( pEnt, G_SoundIndex( "sound/chars/atst/atst_hatch_close" ));
00433                 }
00434                 pEnt->s.radius = 320;
00435                 //weapon
00436                 gitem_t *item = FindItemForWeapon( WP_ATST_MAIN );      //precache the weapon
00437                 CG_RegisterItemSounds( (item-bg_itemlist) );
00438                 CG_RegisterItemVisuals( (item-bg_itemlist) );
00439                 item = FindItemForWeapon( WP_ATST_SIDE );       //precache the weapon
00440                 CG_RegisterItemSounds( (item-bg_itemlist) );
00441                 CG_RegisterItemVisuals( (item-bg_itemlist) );
00442                 pEnt->client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_ATST_MAIN )|( 1 << WP_ATST_SIDE );
00443                 pEnt->client->ps.ammo[weaponData[WP_ATST_MAIN].ammoIndex] = ammoData[weaponData[WP_ATST_MAIN].ammoIndex].max;
00444                 pEnt->client->ps.ammo[weaponData[WP_ATST_SIDE].ammoIndex] = ammoData[weaponData[WP_ATST_SIDE].ammoIndex].max;
00445                 CG_ChangeWeapon( WP_ATST_MAIN );
00446                 //HACKHACKHACKTEMP
00447                 item = FindItemForWeapon( WP_EMPLACED_GUN );
00448                 CG_RegisterItemSounds( (item-bg_itemlist) );
00449                 CG_RegisterItemVisuals( (item-bg_itemlist) );
00450                 item = FindItemForWeapon( WP_ROCKET_LAUNCHER );
00451                 CG_RegisterItemSounds( (item-bg_itemlist) );
00452                 CG_RegisterItemVisuals( (item-bg_itemlist) );
00453                 item = FindItemForWeapon( WP_BOWCASTER );
00454                 CG_RegisterItemSounds( (item-bg_itemlist) );
00455                 CG_RegisterItemVisuals( (item-bg_itemlist) );
00456                 //HACKHACKHACKTEMP
00457                 //FIXME: these get lost in load/save!  Must use variables that are set every frame or saved/loaded
00458                 //camera
00459                 gi.cvar_set( "cg_thirdperson", "1" );
00460                 cg.overrides.active |= CG_OVERRIDE_3RD_PERSON_RNG;
00461                 cg.overrides.thirdPersonRange = 240;
00462                 //cg.overrides.thirdPersonVertOffset = 100;
00463                 //cg.overrides.thirdPersonPitchOffset = -30;
00464                 //FIXME: this gets stomped in pmove?
00465                 pEnt->client->ps.viewheight = 120;
00466                 //FIXME: setting these broke things very badly...?
00467                 //pEnt->client->standheight = 200;
00468                 //pEnt->client->crouchheight = 200;
00469                 //pEnt->mass = 300;
00470                 //movement
00471                 //pEnt->client->ps.speed = 0;//FIXME: override speed?
00472                 //FIXME: slow turn turning/can't turn if not moving?
00473         }
00474 }

void G_EjectDroidUnit Vehicle_t pVeh,
qboolean  kill
 

Definition at line 986 of file g_vehicles.c.

References CHAN_VOICE, gentity_s::client, ENTITYNUM_NONE, FL_UNDYING, gentity_s::flags, G_Damage(), G_MuteSound(), gentity_t, playerState_s::m_iVehicleNum, entityState_s::m_iVehicleNum, Vehicle_s::m_pDroidUnit, MOD_SUICIDE, NULL, entityState_s::number, entityState_s::origin, entityState_s::owner, entityShared_t::ownerNum, gclient_s::ps, gentity_s::r, gentity_s::s, bgEntity_s::s, and Vehicle_t.

Referenced by Eject(), and EjectAll().

00987 {
00988         pVeh->m_pDroidUnit->s.m_iVehicleNum = ENTITYNUM_NONE;
00989 #ifdef _JK2MP
00990         pVeh->m_pDroidUnit->s.owner = ENTITYNUM_NONE;
00991 #else
00992         pVeh->m_pDroidUnit->owner = NULL;
00993 #endif
00994 //      pVeh->m_pDroidUnit->s.otherEntityNum2 = ENTITYNUM_NONE;
00995 #ifdef QAGAME
00996         {
00997                 gentity_t *droidEnt = (gentity_t *)pVeh->m_pDroidUnit;
00998                 droidEnt->flags &= ~FL_UNDYING;
00999                 droidEnt->r.ownerNum = ENTITYNUM_NONE;
01000                 if ( droidEnt->client )
01001                 {
01002                         droidEnt->client->ps.m_iVehicleNum = ENTITYNUM_NONE;
01003                 }
01004                 if ( kill )
01005                 {//Kill them, too
01006                         //FIXME: proper origin, MOD and attacker (for credit/death message)?  Get from vehicle?
01007                         G_MuteSound(droidEnt->s.number, CHAN_VOICE);
01008                         G_Damage( droidEnt, NULL, NULL, NULL, droidEnt->s.origin, 10000, 0, MOD_SUICIDE );//FIXME: proper MOD?  Get from vehicle?
01009                 }
01010         }
01011 #endif
01012         pVeh->m_pDroidUnit = NULL;
01013 }

Vehicle_t* G_IsRidingVehicle gentity_t pEnt  ) 
 

Definition at line 108 of file g_vehicles.c.

References CLASS_VEHICLE, gentity_s::client, g_entities, gentity_t, entityState_s::m_iVehicleNum, gclient_s::NPC_class, NULL, gentity_s::s, and Vehicle_t.

Referenced by G_CanJumpToEnemyVeh(), and G_KnockOffVehicle().

00109 {
00110         gentity_t *ent = (gentity_t *)pEnt;
00111 
00112         if ( ent && ent->client && ent->client->NPC_class != CLASS_VEHICLE && ent->s.m_iVehicleNum != 0 ) //ent->client && ( ent->client->ps.eFlags & EF_IN_VEHICLE ) && ent->owner )
00113         {
00114                 return g_entities[ent->s.m_iVehicleNum].m_pVehicle;
00115         }
00116         return NULL;
00117 }

void G_Knockdown gentity_t self,
gentity_t attacker,
const vec3_t  pushDir,
float  strength,
qboolean  breakSaberLock
 

void G_KnockOffVehicle gentity_t pRider,
gentity_t self,
qboolean  bPull
 

Definition at line 289 of file g_vehicles.c.

References AngleVectors(), gentity_s::client, DotProduct, vehicleInfo_t::Eject, G_IsRidingVehicle(), gentity_t, Vehicle_s::m_EjectDir, Vehicle_s::m_pVehicleInfo, NULL, qtrue, vec3_t, VectorCopy, VectorNormalize(), VectorSubtract, VEH_EJECT_FRONT, VEH_EJECT_LEFT, VEH_EJECT_REAR, VEH_EJECT_RIGHT, and Vehicle_t.

00290 {
00291         Vehicle_t *pVeh = NULL;
00292         vec3_t riderAngles, fDir, rDir, dir2Me;
00293         float   fDot, rDot;
00294 
00295         if ( !pRider || !pRider->client )
00296         {
00297                 return;
00298         }
00299         
00300         pVeh = G_IsRidingVehicle( pRider );
00301 
00302         if ( !pVeh || !pVeh->m_pVehicleInfo )
00303         {
00304                 return;
00305         }
00306 
00307         VectorCopy( pRider->currentAngles, riderAngles );
00308         riderAngles[0] = 0;
00309         AngleVectors( riderAngles, fDir, rDir, NULL );
00310         VectorSubtract( self->currentOrigin, pRider->currentOrigin, dir2Me );
00311         dir2Me[2] = 0;
00312         VectorNormalize( dir2Me );
00313         fDot = DotProduct( fDir, dir2Me );
00314         if ( fDot >= 0.5f )
00315         {//I'm in front of them
00316                 if ( bPull )
00317                 {//pull them foward
00318                         pVeh->m_EjectDir = VEH_EJECT_FRONT;
00319                 }
00320                 else
00321                 {//push them back
00322                         pVeh->m_EjectDir = VEH_EJECT_REAR;
00323                 }
00324         }
00325         else if ( fDot <= -0.5f )
00326         {//I'm behind them
00327                 if ( bPull )
00328                 {//pull them back
00329                         pVeh->m_EjectDir = VEH_EJECT_REAR;
00330                 }
00331                 else
00332                 {//push them forward
00333                         pVeh->m_EjectDir = VEH_EJECT_FRONT;
00334                 }
00335         }
00336         else
00337         {//to the side of them
00338                 rDot = DotProduct( fDir, dir2Me );
00339                 if ( rDot >= 0.0f )
00340                 {//to the right
00341                         if ( bPull )
00342                         {//pull them right
00343                                 pVeh->m_EjectDir = VEH_EJECT_RIGHT;
00344                         }
00345                         else
00346                         {//push them left
00347                                 pVeh->m_EjectDir = VEH_EJECT_LEFT;
00348                         }
00349                 }
00350                 else
00351                 {//to the left
00352                         if ( bPull )
00353                         {//pull them left
00354                                 pVeh->m_EjectDir = VEH_EJECT_LEFT;
00355                         }
00356                         else
00357                         {//push them right
00358                                 pVeh->m_EjectDir = VEH_EJECT_RIGHT;
00359                         }
00360                 }
00361         }
00362         //now forcibly eject them
00363         pVeh->m_pVehicleInfo->Eject( pVeh, pRider, qtrue );
00364 }

void G_RemovePlayerModel gentity_t pEnt  ) 
 

Referenced by G_DriveATST().

void G_RemoveWeaponModels gentity_t pEnt  ) 
 

Referenced by AnimateRiders(), Board(), Eject(), and G_DriveATST().

qboolean G_SetG2PlayerModelInfo gentity_t pEnt,
const char *  modelName,
const char *  customSkin,
const char *  surfOff,
const char *  surfOn
 

Referenced by G_DriveATST().

void G_SetSharedVehicleFunctions vehicleInfo_t pVehInfo  ) 
 

Definition at line 3298 of file g_vehicles.c.

References AddPassenger(), vehicleInfo_t::AddPassenger, Animate(), vehicleInfo_t::Animate, vehicleInfo_t::AttachRiders, Board(), vehicleInfo_t::Board, vehicleInfo_t::DeathUpdate, Eject(), vehicleInfo_t::Eject, EjectAll(), vehicleInfo_t::EjectAll, vehicleInfo_t::Ghost, Inhabited(), vehicleInfo_t::Inhabited, Initialize(), vehicleInfo_t::Initialize, RegisterAssets(), vehicleInfo_t::RegisterAssets, SetParent(), vehicleInfo_t::SetParent, SetPilot(), vehicleInfo_t::SetPilot, vehicleInfo_t::StartDeathDelay, vehicleInfo_t::UnGhost, vehicleInfo_t::Update, vehicleInfo_t::UpdateRider, ValidateBoard(), and vehicleInfo_t::ValidateBoard.

Referenced by BG_SetSharedVehicleFunctions().

03299 {
03300 //      pVehInfo->AnimateVehicle                                =               AnimateVehicle;
03301 //      pVehInfo->AnimateRiders                                 =               AnimateRiders;
03302         pVehInfo->ValidateBoard                                 =               ValidateBoard;
03303         pVehInfo->SetParent                                             =               SetParent;
03304         pVehInfo->SetPilot                                              =               SetPilot;
03305         pVehInfo->AddPassenger                                  =               AddPassenger;
03306         pVehInfo->Animate                                               =               Animate;
03307         pVehInfo->Board                                                 =               Board;
03308         pVehInfo->Eject                                                 =               Eject;
03309         pVehInfo->EjectAll                                              =               EjectAll;
03310         pVehInfo->StartDeathDelay                               =               StartDeathDelay;
03311         pVehInfo->DeathUpdate                                   =               DeathUpdate;
03312         pVehInfo->RegisterAssets                                =               RegisterAssets;
03313         pVehInfo->Initialize                                    =               Initialize;
03314         pVehInfo->Update                                                =               Update;
03315         pVehInfo->UpdateRider                                   =               UpdateRider;
03316 //      pVehInfo->ProcessMoveCommands                   =               ProcessMoveCommands;
03317 //      pVehInfo->ProcessOrientCommands                 =               ProcessOrientCommands;
03318         pVehInfo->AttachRiders                                  =               AttachRiders;
03319         pVehInfo->Ghost                                                 =               Ghost;
03320         pVehInfo->UnGhost                                               =               UnGhost;
03321         pVehInfo->Inhabited                                             =               Inhabited;
03322 }

void G_VehicleSpawn gentity_t self  ) 
 

Definition at line 183 of file g_vehicles.c.

References entityState_s::angles, gNPC_t::behaviorState, BS_CINEMATIC, gentity_s::count, gentity_s::damage, gentity_t, level, Vehicle_s::m_iPilotTime, gentity_s::m_pVehicle, Vehicle_s::m_pVehicleInfo, gentity_s::NPC, NPC_Spawn_Do(), entityState_s::origin, qtrue, gentity_s::s, gentity_s::spawnflags, gentity_s::speed, level_locals_t::time, trap_LinkEntity(), vehicleInfo_t::type, VectorCopy, VH_ANIMAL, and YAW.

Referenced by NPC_VehicleSpawnUse(), and SP_NPC_Vehicle().

00184 {
00185         float yaw;
00186         gentity_t *vehEnt;
00187 
00188         VectorCopy( self->currentOrigin, self->s.origin );
00189 
00190 #ifdef _JK2MP
00191         trap_LinkEntity( self );
00192 #else
00193         gi.linkentity( self );
00194 #endif
00195 
00196         if ( !self->count )
00197         {
00198                 self->count = 1;
00199         }
00200 
00201         //save this because self gets removed in next func
00202         yaw = self->s.angles[YAW];
00203         
00204 #ifdef _JK2MP
00205         vehEnt = NPC_Spawn_Do( self );
00206 #else
00207         vehEnt = NPC_Spawn_Do( self, qtrue );
00208 #endif
00209         
00210         if ( !vehEnt )
00211         {
00212                 return;//return NULL;
00213         }
00214         
00215         vehEnt->s.angles[YAW] = yaw;
00216         if ( vehEnt->m_pVehicle->m_pVehicleInfo->type != VH_ANIMAL )
00217         {
00218                 vehEnt->NPC->behaviorState = BS_CINEMATIC;
00219         }
00220 
00221 #ifdef _JK2MP //special check in case someone disconnects/dies while boarding
00222         if (vehEnt->spawnflags & 1)
00223         { //die without pilot
00224                 if (!vehEnt->damage)
00225                 { //default 10 sec
00226                         vehEnt->damage = 10000;
00227                 }
00228                 if (!vehEnt->speed)
00229                 { //default 512 units
00230                         vehEnt->speed = 512.0f;
00231                 }
00232                 vehEnt->m_pVehicle->m_iPilotTime = level.time + vehEnt->damage;
00233         }
00234 #else
00235         if (vehEnt->spawnflags & 1)
00236         { //die without pilot
00237                 vehEnt->m_pVehicle->m_iPilotTime = level.time + vehEnt->endFrame;
00238         }
00239 #endif
00240         //return vehEnt;
00241 }

void G_VehicleTrace trace_t results,
const vec3_t  start,
const vec3_t  tMins,
const vec3_t  tMaxs,
const vec3_t  end,
int  passEntityNum,
int  contentmask
 

Definition at line 99 of file g_vehicles.c.

References trap_Trace(), and vec3_t.

Referenced by VEH_TryEject().

00100 {
00101 #ifdef _JK2MP
00102         trap_Trace(results, start, tMins, tMaxs, end, passEntityNum, contentmask);
00103 #else
00104         gi.trace( results, start, tMins, tMaxs, end, passEntityNum, contentmask );
00105 #endif
00106 }

GAME_INLINE bool Inhabited Vehicle_t pVeh  ) 
 

Definition at line 3294 of file g_vehicles.c.

References GAME_INLINE, Vehicle_s::m_iNumPassengers, Vehicle_s::m_pPilot, and Vehicle_t.

Referenced by G_SetSharedVehicleFunctions().

03294 { return ( pVeh->m_pPilot || pVeh->m_iNumPassengers ) ? true : false; }

bool Initialize Vehicle_t pVeh  ) 
 

Definition at line 1623 of file g_vehicles.c.

References gNPC_t::aiFlags, vehTurretStatus_t::ammo, vehWeaponStatus_t::ammo, playerState_s::ammo, vehWeaponStats_t::ammoMax, entityState_s::angles, vehicleInfo_t::armor, turretStats_t::bAI, BG_SetAnim(), bgAllAnims, BOTH_VS_IDLE, gentity_s::client, vehTurretStatus_t::enemyEntNum, ENTITYNUM_NONE, G_Alloc(), g_gravity, G_VehUpdateShields(), gentity_t, playerState_s::gravity, vehicleInfo_t::gravity, gentity_s::health, gNPCstats_e::health, turretStats_t::iAmmoMax, turretStats_t::iMuzzle, bgEntity_s::localAnimIndex, Vehicle_s::m_bWasBoarding, Vehicle_s::m_EjectDir, Vehicle_s::m_fTimeModifier, Vehicle_s::m_iArmor, Vehicle_s::m_iBoarding, Vehicle_s::m_iDieTime, Vehicle_s::m_iDroidUnitTag, Vehicle_s::m_iExhaustTag, Vehicle_s::m_iMuzzleTag, Vehicle_s::m_iNumPassengers, Vehicle_s::m_iShields, entityState_s::m_iVehicleNum, playerState_s::m_iVehicleNum, Vehicle_s::m_pOldPilot, Vehicle_s::m_pParentEntity, Vehicle_s::m_pPilot, Vehicle_s::m_ppPassengers, Vehicle_s::m_pVehicleInfo, Vehicle_s::m_ucmd, Vehicle_s::m_ulFlags, Vehicle_s::m_vBoardingVelocity, Vehicle_s::m_vOrientation, vehicleInfo_t::mass, gentity_s::mass, MAX_VEHICLE_EXHAUSTS, MAX_VEHICLE_MUZZLES, MAX_VEHICLE_TURRETS, MAX_VEHICLE_WEAPONS, clientPersistant_t::maxHealth, vehicleInfo_t::maxPassengers, memset(), vehTurretStatus_t::nextMuzzle, gentity_s::NPC, NPC_SetAnim(), NPCAI_CUSTOM_GRAVITY, NULL, gclient_s::pers, bgEntity_s::playerState, gclient_s::ps, gentity_s::s, SETANIM_BOTH, SETANIM_FLAG_NORMAL, vehicleInfo_t::shields, playerState_s::speed, STAT_ARMOR, STAT_HEALTH, STAT_MAX_HEALTH, STAT_WEAPONS, gNPC_t::stats, playerState_s::stats, vehicleInfo_t::turret, Vehicle_s::turretStatus, usercmd_t, vmCvar_t::value, VectorClear, VEH_EJECT_LEFT, VEH_GEARSOPEN, Vehicle_t, playerState_s::weapon, vehicleInfo_t::weapon, WEAPON_READY, playerState_s::weaponstate, Vehicle_s::weaponStatus, WP_BLASTER, and YAW.

Referenced by G_SetSharedVehicleFunctions().

01624 {
01625         gentity_t *parent = (gentity_t *)pVeh->m_pParentEntity;
01626         int i = 0;
01627 
01628         if ( !parent || !parent->client )
01629                 return false;
01630 
01631 #ifdef _JK2MP
01632         parent->client->ps.m_iVehicleNum = 0;
01633 #endif
01634         parent->s.m_iVehicleNum = 0;
01635         {
01636         pVeh->m_iArmor = pVeh->m_pVehicleInfo->armor;
01637         parent->client->pers.maxHealth = parent->client->ps.stats[STAT_MAX_HEALTH] = parent->NPC->stats.health = parent->health = parent->client->ps.stats[STAT_HEALTH] = pVeh->m_iArmor;
01638         pVeh->m_iShields = pVeh->m_pVehicleInfo->shields;
01639 #ifdef _JK2MP
01640         G_VehUpdateShields( parent );
01641 #endif
01642         parent->client->ps.stats[STAT_ARMOR] = pVeh->m_iShields;
01643         }
01644         parent->mass = pVeh->m_pVehicleInfo->mass;
01645         //initialize the ammo to max
01646         for ( i = 0; i < MAX_VEHICLE_WEAPONS; i++ )
01647         {
01648                 parent->client->ps.ammo[i] = pVeh->weaponStatus[i].ammo = pVeh->m_pVehicleInfo->weapon[i].ammoMax;
01649         }
01650         for ( i = 0; i < MAX_VEHICLE_TURRETS; i++ )
01651         {
01652                 pVeh->turretStatus[i].nextMuzzle = (pVeh->m_pVehicleInfo->turret[i].iMuzzle[i]-1);
01653                 parent->client->ps.ammo[MAX_VEHICLE_WEAPONS+i] = pVeh->turretStatus[i].ammo = pVeh->m_pVehicleInfo->turret[i].iAmmoMax;
01654                 if ( pVeh->m_pVehicleInfo->turret[i].bAI )
01655                 {//they're going to be finding enemies, init this to NONE
01656                         pVeh->turretStatus[i].enemyEntNum = ENTITYNUM_NONE;
01657                 }
01658         }
01659         //begin stopped...?
01660         parent->client->ps.speed = 0; 
01661         
01662         VectorClear( pVeh->m_vOrientation );
01663         pVeh->m_vOrientation[YAW] = parent->s.angles[YAW];
01664 
01665 #ifdef _JK2MP
01666         if ( pVeh->m_pVehicleInfo->gravity &&
01667                 pVeh->m_pVehicleInfo->gravity != g_gravity.value )
01668         {//not normal gravity
01669                 if ( parent->NPC )
01670                 {
01671                         parent->NPC->aiFlags |= NPCAI_CUSTOM_GRAVITY;
01672                 }
01673                 parent->client->ps.gravity = pVeh->m_pVehicleInfo->gravity;
01674         }
01675 #else
01676         if ( pVeh->m_pVehicleInfo->gravity &&
01677                 pVeh->m_pVehicleInfo->gravity != g_gravity->value )
01678         {//not normal gravity
01679                 parent->svFlags |= SVF_CUSTOM_GRAVITY;
01680                 parent->client->ps.gravity = pVeh->m_pVehicleInfo->gravity;
01681         }
01682 #endif
01683 
01684         if ( pVeh->m_pVehicleInfo->maxPassengers > 0 )
01685         {
01686                 int i;
01687 
01688                 // Allocate an array of entity pointers.
01689 #ifndef _JK2MP //this is kind of silly if you ask me, I'm just using a static pointer array
01690                 pVeh->m_ppPassengers = (gentity_t**)G_Alloc ( sizeof(gentity_t*) * pVeh->m_pVehicleInfo->maxPassengers );
01691 #endif
01692                 for ( i = 0; i < pVeh->m_pVehicleInfo->maxPassengers; i++ )
01693                 {
01694                         pVeh->m_ppPassengers[i] = NULL;
01695                 }
01696         }
01697 
01698         pVeh->m_iNumPassengers = 0; 
01699         /*
01700         if ( pVeh->m_iVehicleTypeID == VH_FIGHTER )
01701         {
01702                 pVeh->m_ulFlags = VEH_GEARSOPEN;
01703         }
01704         else
01705         */
01706         //why?! -rww
01707         {
01708                 pVeh->m_ulFlags = 0;
01709         }
01710         pVeh->m_fTimeModifier = 1.0f;
01711         pVeh->m_iBoarding = 0;
01712         pVeh->m_bWasBoarding = false;
01713         pVeh->m_pOldPilot = NULL;
01714         VectorClear(pVeh->m_vBoardingVelocity);
01715         pVeh->m_pPilot = NULL;
01716         memset( &pVeh->m_ucmd, 0, sizeof( usercmd_t ) );
01717         pVeh->m_iDieTime = 0;
01718         pVeh->m_EjectDir = VEH_EJECT_LEFT;
01719 
01720         //pVeh->m_iDriverTag = -1;
01721         //pVeh->m_iLeftExhaustTag = -1;
01722         //pVeh->m_iRightExhaustTag = -1;
01723         //pVeh->m_iGun1Tag = -1;
01724         //pVeh->m_iGun1Bone = -1;
01725         //pVeh->m_iLeftWingBone = -1;
01726         //pVeh->m_iRightWingBone = -1;
01727         memset( pVeh->m_iExhaustTag, -1, sizeof( int ) * MAX_VEHICLE_EXHAUSTS );
01728         memset( pVeh->m_iMuzzleTag, -1, sizeof( int ) * MAX_VEHICLE_MUZZLES );
01729         // FIXME! Use external values read from the vehicle data file!
01730 #ifndef _JK2MP //blargh, fixme
01731         memset( pVeh->m_Muzzles, 0, sizeof( Muzzle ) * MAX_VEHICLE_MUZZLES );
01732 #endif
01733         pVeh->m_iDroidUnitTag = -1;
01734 
01735         //initialize to blaster, just since it's a basic weapon and there's no lightsaber crap...?
01736         parent->client->ps.weapon = WP_BLASTER;
01737         parent->client->ps.weaponstate = WEAPON_READY;
01738         parent->client->ps.stats[STAT_WEAPONS] |= (1<<WP_BLASTER);
01739 
01740         //Initialize to landed (wings closed, gears down) animation
01741         {
01742                 int iFlags = SETANIM_FLAG_NORMAL, iBlend = 300;
01743 #ifdef _JK2MP
01744                 pVeh->m_ulFlags |= VEH_GEARSOPEN;
01745                 BG_SetAnim(pVeh->m_pParentEntity->playerState, 
01746                         bgAllAnims[pVeh->m_pParentEntity->localAnimIndex].anims,
01747                         SETANIM_BOTH, BOTH_VS_IDLE, iFlags, iBlend);
01748 #else
01749                 NPC_SetAnim( pVeh->m_pParentEntity, SETANIM_BOTH, BOTH_VS_IDLE, iFlags, iBlend );
01750 #endif
01751         }
01752 
01753         return true;
01754 }

void NPC_SetAnim gentity_t ent,
int  setAnimParts,
int  anim,
int  setAnimFlags,
int  iBlend
 

gentity_t* NPC_Spawn_Do gentity_t pEnt,
qboolean  fullSpawnNow
 

int PM_AnimLength int  index,
animNumber_t  anim
 

Definition at line 1584 of file bg_panimate.c.

01585 {
01586         if (anim >= MAX_ANIMATIONS || !pm->animations)
01587         {
01588                 return -1;
01589         }
01590         if ( anim < 0 )
01591         {
01592                 Com_Error(ERR_DROP,"ERROR: anim %d < 0\n", anim );
01593         }
01594         return pm->animations[anim].numFrames * fabs((float)(pm->animations[anim].frameLerp));
01595 }

void PM_SetAnim pmove_t pm,
int  setAnimParts,
int  anim,
int  setAnimFlags,
int  blendTime
 

void PM_SetLegsAnimTimer gentity_t ent,
int *  legsAnimTimer,
int  time
 

void PM_SetTorsoAnimTimer gentity_t ent,
int *  torsoAnimTimer,
int  time
 

qboolean Q3_TaskIDPending gentity_t ent,
taskID_t  taskType
 

void RegisterAssets Vehicle_t pVeh  ) 
 

Definition at line 1616 of file g_vehicles.c.

References RegisterAssets(), and Vehicle_t.

Referenced by G_SetSharedVehicleFunctions(), G_SetWalkerVehicleFunctions(), and RegisterAssets().

01617 {
01618 }

void SetClientViewAngle gentity_t ent,
vec3_t  angle
 

Definition at line 1116 of file g_client.c.

References ANGLE2SHORT, entityState_s::angles, usercmd_s::angles, gentity_s::client, clientPersistant_t::cmd, playerState_s::delta_angles, gentity_t, gclient_s::pers, gclient_s::ps, gentity_s::s, vec3_t, VectorCopy, and playerState_s::viewangles.

Referenced by Board(), ClientCommand(), ClientSpawn(), ClientThink_real(), Eject(), G_HeldByMonster(), misc_weapon_shooter_aim(), NPC_Begin(), NPC_Spawn_Do(), Rancor_DropVictim(), TeleportPlayer(), and WP_SaberPositionUpdate().

01116                                                         {
01117         int                     i;
01118 
01119         // set the delta angle
01120         for (i=0 ; i<3 ; i++) {
01121                 int             cmdAngle;
01122 
01123                 cmdAngle = ANGLE2SHORT(angle[i]);
01124                 ent->client->ps.delta_angles[i] = cmdAngle - ent->client->pers.cmd.angles[i];
01125         }
01126         VectorCopy( angle, ent->s.angles );
01127         VectorCopy (ent->s.angles, ent->client->ps.viewangles);
01128 }

GAME_INLINE void SetParent Vehicle_t pVeh,
bgEntity_t pParentEntity
 

Definition at line 3285 of file g_vehicles.c.

References bgEntity_t, GAME_INLINE, Vehicle_s::m_pParentEntity, and Vehicle_t.

Referenced by G_SetSharedVehicleFunctions().

03285 { pVeh->m_pParentEntity = pParentEntity; }

GAME_INLINE void SetPilot Vehicle_t pVeh,
bgEntity_t pPilot
 

Definition at line 3288 of file g_vehicles.c.

References bgEntity_t, GAME_INLINE, Vehicle_s::m_pPilot, and Vehicle_t.

Referenced by G_SetSharedVehicleFunctions().

03288 { pVeh->m_pPilot = pPilot; }

bool ValidateBoard Vehicle_t pVeh,
bgEntity_t pEnt
 

Definition at line 493 of file g_vehicles.c.

References AngleVectors(), bgEntity_t, gentity_s::client, DotProduct, gentity_t, playerState_s::groundEntityNum, Vehicle_s::m_iBoarding, Vehicle_s::m_iDieTime, Vehicle_s::m_iNumPassengers, Vehicle_s::m_pParentEntity, Vehicle_s::m_pPilot, Vehicle_s::m_pVehicleInfo, vehicleInfo_t::maxPassengers, NULL, entityState_s::number, gclient_s::ps, gentity_s::s, vehicleInfo_t::type, vec3_t, VectorNormalize(), VectorSet, VectorSubtract, VEH_MOUNT_THROW_LEFT, VEH_MOUNT_THROW_RIGHT, Vehicle_t, VH_FIGHTER, VH_SPEEDER, VH_WALKER, and YAW.

Referenced by G_SetSharedVehicleFunctions().

00494 {
00495         // Determine where the entity is entering the vehicle from (left, right, or back).
00496         vec3_t vVehToEnt;
00497         vec3_t vVehDir;
00498         const gentity_t *parent = (gentity_t *)pVeh->m_pParentEntity;
00499         const gentity_t *ent = (gentity_t *)pEnt;
00500         vec3_t vVehAngles;
00501         float fDot;
00502 
00503         if ( pVeh->m_iDieTime>0)
00504         {
00505                 return false;
00506         }
00507 
00508         if ( pVeh->m_pPilot != NULL )
00509         {//already have a driver!
00510                 if ( pVeh->m_pVehicleInfo->type == VH_FIGHTER )
00511                 {//I know, I know, this should by in the fighters's validateboard()
00512                         //can never steal a fighter from it's pilot
00513                         if ( pVeh->m_iNumPassengers < pVeh->m_pVehicleInfo->maxPassengers )
00514                         {
00515                                 return true;
00516                         }
00517                         else
00518                         {
00519                                 return false;
00520                         }
00521                 }
00522                 else if ( pVeh->m_pVehicleInfo->type == VH_WALKER )
00523                 {//I know, I know, this should by in the walker's validateboard()
00524                         if ( !ent->client || ent->client->ps.groundEntityNum != parent->s.number )
00525                         {//can only steal an occupied AT-ST if you're on top (by the hatch)
00526                                 return false;
00527                         }
00528                 }
00529                 else if (pVeh->m_pVehicleInfo->type == VH_SPEEDER)
00530                 {//you can only steal the bike from the driver if you landed on the driver or bike
00531                         return (pVeh->m_iBoarding==VEH_MOUNT_THROW_LEFT || pVeh->m_iBoarding==VEH_MOUNT_THROW_RIGHT);
00532                 }
00533         }
00534         // Yes, you shouldn't have put this here (you 'should' have made an 'overriden' ValidateBoard func), but in this
00535         // instance it's more than adequate (which is why I do it too :-). Making a whole other function for this is silly.
00536         else if ( pVeh->m_pVehicleInfo->type == VH_FIGHTER )
00537         {
00538                 // If you're a fighter, you allow everyone to enter you from all directions.
00539                 return true;
00540         }
00541 
00542         // Clear out all orientation axis except for the yaw.
00543         VectorSet(vVehAngles, 0, parent->currentAngles[YAW], 0);
00544 
00545         // Vector from Entity to Vehicle.
00546         VectorSubtract( ent->currentOrigin, parent->currentOrigin, vVehToEnt );
00547         vVehToEnt[2] = 0;
00548         VectorNormalize( vVehToEnt );
00549 
00550         // Get the right vector.
00551         AngleVectors( vVehAngles, NULL, vVehDir, NULL ); 
00552         VectorNormalize( vVehDir );
00553 
00554         // Find the angle between the vehicle right vector and the vehicle to entity vector.
00555         fDot = DotProduct( vVehToEnt, vVehDir );
00556 
00557         // If the entity is within a certain angle to the left of the vehicle...
00558         if ( fDot >= 0.5f )
00559         {
00560                 // Right board.
00561                 pVeh->m_iBoarding = -2;
00562         }
00563         else if ( fDot <= -0.5f )
00564         {
00565                 // Left board.
00566                 pVeh->m_iBoarding = -1;
00567         }
00568         // Maybe they're trying to board from the back...
00569         else
00570         {
00571                 // The forward vector of the vehicle.
00572         //      AngleVectors( vVehAngles, vVehDir, NULL, NULL ); 
00573         //      VectorNormalize( vVehDir );
00574 
00575                 // Find the angle between the vehicle forward and the vehicle to entity vector.
00576         //      fDot = DotProduct( vVehToEnt, vVehDir );
00577 
00578                 // If the entity is within a certain angle behind the vehicle...
00579                 //if ( fDot <= -0.85f )
00580                 {
00581                         // Jump board.
00582                         pVeh->m_iBoarding = -3;
00583                 }
00584         }
00585 
00586         // If for some reason we couldn't board, leave...
00587         if ( pVeh->m_iBoarding > -1 )
00588                 return false;
00589 
00590         return true;
00591 }

bool VEH_TryEject Vehicle_t pVeh,
gentity_t parent,
gentity_t ent,
int  ejectDir,
vec3_t  vExitPos
 

Definition at line 871 of file g_vehicles.c.

References trace_t::allsolid, AngleVectors(), gentity_s::clipmask, DEFAULT_MAXS_2, DEFAULT_MINS_2, trace_t::endpos, ENTITYNUM_NONE, trace_t::fraction, G_VehicleTrace(), gentity_t, Vehicle_s::m_pVehicleInfo, MAX_CLIENTS, NULL, entityState_s::number, entityShared_t::ownerNum, gentity_s::r, gentity_s::s, trace_t::startsolid, vehicleInfo_t::type, vec3_t, VectorAdd, VectorCopy, VectorNormalize(), VectorSet, VEH_EJECT_BOTTOM, VEH_EJECT_FRONT, VEH_EJECT_LEFT, VEH_EJECT_REAR, VEH_EJECT_RIGHT, VEH_EJECT_TOP, Vehicle_t, VH_WALKER, and YAW.

Referenced by Eject().

00876 {
00877         float           fBias;
00878         float           fVehDiag;
00879         float           fEntDiag;
00880         int                     oldOwner;
00881         vec3_t          vEntMins, vEntMaxs, vVehLeaveDir, vVehAngles;
00882         trace_t         m_ExitTrace;
00883 
00884         // Make sure that the entity is not 'stuck' inside the vehicle (since their bboxes will now intersect).
00885         // This makes the entity leave the vehicle from the right side.
00886         VectorSet(vVehAngles, 0, parent->currentAngles[YAW], 0);
00887         switch ( ejectDir )
00888         {
00889                 // Left.
00890                 case VEH_EJECT_LEFT:
00891                         AngleVectors( vVehAngles, NULL, vVehLeaveDir, NULL ); 
00892                         vVehLeaveDir[0] = -vVehLeaveDir[0];
00893                         vVehLeaveDir[1] = -vVehLeaveDir[1];
00894                         vVehLeaveDir[2] = -vVehLeaveDir[2];
00895                         break;
00896                 // Right.
00897                 case VEH_EJECT_RIGHT:
00898                         AngleVectors( vVehAngles, NULL, vVehLeaveDir, NULL ); 
00899                         break;
00900                 // Front.
00901                 case VEH_EJECT_FRONT:
00902                         AngleVectors( vVehAngles, vVehLeaveDir, NULL, NULL ); 
00903                         break;
00904                 // Rear.
00905                 case VEH_EJECT_REAR:
00906                         AngleVectors( vVehAngles, vVehLeaveDir, NULL, NULL ); 
00907                         vVehLeaveDir[0] = -vVehLeaveDir[0];
00908                         vVehLeaveDir[1] = -vVehLeaveDir[1];
00909                         vVehLeaveDir[2] = -vVehLeaveDir[2];
00910                         break;
00911                 // Top.
00912                 case VEH_EJECT_TOP:
00913                         AngleVectors( vVehAngles, NULL, NULL, vVehLeaveDir ); 
00914                         break;
00915                 // Bottom?.
00916                 case VEH_EJECT_BOTTOM:
00917                         break;
00918         }
00919         VectorNormalize( vVehLeaveDir );
00920         //NOTE: not sure why following line was needed - MCG
00921         //pVeh->m_EjectDir = VEH_EJECT_LEFT;
00922 
00923         // Since (as of this time) the collidable geometry of the entity is just an axis 
00924         // aligned box, we need to get the diagonal length of it in case we come out on that side.
00925         // Diagonal Length == squareroot( squared( Sidex / 2 ) + squared( Sidey / 2 ) );
00926 
00927         // TODO: DO diagonal for entity.
00928 
00929         fBias = 1.0f;
00930         if (pVeh->m_pVehicleInfo->type == VH_WALKER)
00931         { //hacktastic!
00932                 fBias += 0.2f;
00933         }
00934         VectorCopy( ent->currentOrigin, vExitPos );
00935         fVehDiag = sqrtf( ( parent->maxs[0] * parent->maxs[0] ) + ( parent->maxs[1] * parent->maxs[1] ) );
00936         VectorCopy( ent->maxs, vEntMaxs );
00937 #ifdef _JK2MP
00938         if ( ent->s.number < MAX_CLIENTS )
00939         {//for some reason, in MP, player client mins and maxs are never stored permanently, just set to these hardcoded numbers in PMove
00940                 vEntMaxs[0] = 15;
00941                 vEntMaxs[1] = 15;
00942         }
00943 #endif
00944         fEntDiag = sqrtf( ( vEntMaxs[0] * vEntMaxs[0] ) + ( vEntMaxs[1] * vEntMaxs[1] ) );
00945         vVehLeaveDir[0] *= ( fVehDiag + fEntDiag ) * fBias;     // x
00946         vVehLeaveDir[1] *= ( fVehDiag + fEntDiag ) * fBias;     // y
00947         vVehLeaveDir[2] *= ( fVehDiag + fEntDiag ) * fBias;
00948         VectorAdd( vExitPos, vVehLeaveDir, vExitPos );
00949 
00950         //we actually could end up *not* getting off if the trace fails...
00951         // Check to see if this new position is a valid place for our entity to go.
00952 #ifdef _JK2MP
00953         VectorSet(vEntMins, -15.0f, -15.0f, DEFAULT_MINS_2);
00954         VectorSet(vEntMaxs, 15.0f, 15.0f, DEFAULT_MAXS_2);
00955 #else
00956         VectorCopy(ent->mins, vEntMins);
00957         VectorCopy(ent->maxs, vEntMaxs);
00958 #endif
00959         oldOwner = ent->r.ownerNum;
00960         ent->r.ownerNum = ENTITYNUM_NONE;
00961         G_VehicleTrace( &m_ExitTrace, ent->currentOrigin, vEntMins, vEntMaxs, vExitPos, ent->s.number, ent->clipmask );
00962         ent->r.ownerNum = oldOwner;
00963 
00964         if ( m_ExitTrace.allsolid//in solid
00965                 || m_ExitTrace.startsolid)
00966         {
00967                 return false;
00968         }
00969         // If the trace hit something, we can't go there!
00970         if ( m_ExitTrace.fraction < 1.0f )
00971         {//not totally clear
00972 #ifdef _JK2MP
00973 //              if ( (parent->clipmask&ent->r.contents) )//vehicle could actually get stuck on body
00974 #else
00975                 if ( (parent->clipmask&ent->contents) )//vehicle could actually get stuck on body
00976 #endif
00977                 {//the trace hit the vehicle, don't let them get out, just in case
00978                         return false;
00979                 }
00980                 //otherwise, use the trace.endpos
00981                 VectorCopy( m_ExitTrace.endpos, vExitPos );
00982         }
00983         return true;
00984 }

void Vehicle_SetAnim gentity_t ent,
int  setAnimParts,
int  anim,
int  setAnimFlags,
int  iBlend
 

Definition at line 88 of file g_vehicles.c.

References BG_SetAnim(), bgAllAnims, gentity_s::client, gentity_t, entityState_s::legsAnim, playerState_s::legsAnim, gentity_s::localAnimIndex, NPC_SetAnim(), gclient_s::ps, and gentity_s::s.

00089 {
00090 #ifdef _JK2MP
00091         assert(ent->client);
00092         BG_SetAnim(&ent->client->ps, bgAllAnims[ent->localAnimIndex].anims, setAnimParts, anim, setAnimFlags, iBlend);
00093         ent->s.legsAnim = ent->client->ps.legsAnim;
00094 #else
00095         NPC_SetAnim(ent, setAnimParts, anim, setAnimFlags, iBlend);
00096 #endif
00097 }


Variable Documentation

vmCvar_t cg_thirdPersonAlpha
 

Definition at line 60 of file g_vehicles.c.

cvar_t* g_speederControlScheme
 

Definition at line 63 of file g_vehicles.c.

cvar_t* in_joystick
 

Definition at line 64 of file g_vehicles.c.

vec3_t playerMaxs
 

Definition at line 62 of file g_vehicles.c.

vec3_t playerMins
 

Definition at line 61 of file g_vehicles.c.