1 /*
2 ===========================================================================
3 Copyright (C) 2000 - 2013, Raven Software, Inc.
4 Copyright (C) 2001 - 2013, Activision, Inc.
5 Copyright (C) 2013 - 2015, OpenJK contributors
6 
7 This file is part of the OpenJK source code.
8 
9 OpenJK is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License version 2 as
11 published by the Free Software Foundation.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, see <http://www.gnu.org/licenses/>.
20 ===========================================================================
21 */
22 
23 #ifndef __G_VEHICLES_H
24 #define __G_VEHICLES_H
25 
26 #include "../qcommon/q_shared.h"
27 #include "g_public.h"
28 
29 typedef enum
30 {
31 	VH_NONE = 0,
32 	VH_WALKER,		//something you ride inside of, it walks like you, like an AT-ST
33 	VH_FIGHTER,		//something you fly inside of, like an X-Wing or TIE fighter
34 	VH_SPEEDER,		//something you ride on that hovers, like a speeder or swoop
35 	VH_ANIMAL,		//animal you ride on top of that walks, like a tauntaun
36 	VH_FLIER,		//animal you ride on top of that flies, like a giant mynoc?
37 	VH_NUM_VEHICLES
38 } vehicleType_t;
39 
40 enum	EWeaponPose
41 {
42 	WPOSE_NONE	= 0,
43 	WPOSE_BLASTER,
44 	WPOSE_SABERLEFT,
45 	WPOSE_SABERRIGHT,
46 };
47 
48 extern stringID_table_t VehicleTable[VH_NUM_VEHICLES+1];
49 
50 #define NO_PILOT_DIE_TIME 10000
51 
52 //===========================================================================================================
53 //START VEHICLE WEAPONS
54 //===========================================================================================================
55 typedef struct
56 {
57 //*** IMPORTANT!!! *** vWeapFields table correponds to this structure!
58 	char	*name;
59 	qboolean	bIsProjectile;	//traceline or entity?
60 	qboolean	bHasGravity;	//if a projectile, drops
61 	qboolean	bIonWeapon;//disables ship shields and sends them out of control
62 	qboolean	bSaberBlockable;//lightsabers can deflect this projectile
63 	int		iMuzzleFX;	//index of Muzzle Effect
64 	int		iModel;		//handle to the model used by this projectile
65 	int		iShotFX;	//index of Shot Effect
66 	int		iImpactFX;	//index of Impact Effect
67 	int		iG2MarkShaderHandle;	//index of shader to use for G2 marks made on other models when hit by this projectile
68 	float	fG2MarkSize;//size (diameter) of the ghoul2 mark
69 	int		iLoopSound;	//index of loopSound
70 	float	fSpeed;		//speed of projectile/range of traceline
71 	float	fHoming;		//0.0 = not homing, 0.5 = half vel to targ, half cur vel, 1.0 = all vel to targ
72 	float	fHomingFOV;
73 	int		iLockOnTime;	//0 = no lock time needed, else # of ms needed to lock on
74 	int		iDamage;		//damage done when traceline or projectile directly hits target
75 	int		iSplashDamage;//damage done to ents in splashRadius of end of traceline or projectile origin on impact
76 	float	fSplashRadius;//radius that ent must be in to take splashDamage (linear fall-off)
77 	int		iAmmoPerShot;	//how much "ammo" each shot takes
78 	int		iHealth;		//if non-zero, projectile can be shot, takes this much damage before being destroyed
79 	float	fWidth;		//width of traceline or bounding box of projecile (non-rotating!)
80 	float	fHeight;		//height of traceline or bounding box of projecile (non-rotating!)
81 	int		iLifeTime;	//removes itself after this amount of time
82 	qboolean	bExplodeOnExpire;	//when iLifeTime is up, explodes rather than simply removing itself
83 } vehWeaponInfo_t;
84 
85 #define	VWFOFS(x) offsetof(vehWeaponInfo_t, x)
86 
87 #define MAX_VEH_WEAPONS	16	//sigh... no more than 16 different vehicle weapons
88 #define VEH_WEAPON_BASE	0
89 #define VEH_WEAPON_NONE	-1
90 
91 extern vehWeaponInfo_t g_vehWeaponInfo[MAX_VEH_WEAPONS];
92 extern int	numVehicleWeapons;
93 
94 //===========================================================================================================
95 //END VEHICLE WEAPONS
96 //===========================================================================================================
97 
98 // The maximum number of muzzles a vehicle may have.
99 #define		MAX_VEHICLE_MUZZLES			10
100 
101 // The maximum number of exhausts a vehicle may have.
102 #define		MAX_VEHICLE_EXHAUSTS		4
103 
104 // The maxiumum number of different weapons a vehicle may have
105 #define		MAX_VEHICLE_WEAPONS			2
106 #define		MAX_VEHICLE_TURRETS			2
107 #define		MAX_VEHICLE_TURRET_MUZZLES	2
108 
109 typedef struct
110 {
111 	int			iWeapon;	//what vehWeaponInfo index to use
112 	int			iDelay;		//delay between turret muzzle shots
113 	int			iAmmoMax;	//how much ammo it has
114 	int			iAmmoRechargeMS;	//how many MS between every point of recharged ammo
115 	char		*yawBone;	//bone on ship that this turret uses to yaw
116 	char		*pitchBone;	//bone on ship that this turret uses to pitch
117 	int			yawAxis;	//axis on yawBone to which we should to apply the yaw angles
118 	int			pitchAxis;	//axis on pitchBone to which we should to apply the pitch angles
119 	float		yawClampLeft;	//how far the turret is allowed to turn left
120 	float		yawClampRight;	//how far the turret is allowed to turn right
121 	float		pitchClampUp;	//how far the turret is allowed to title up
122 	float		pitchClampDown; //how far the turret is allowed to tilt down
123 	int			iMuzzle[MAX_VEHICLE_TURRET_MUZZLES];//iMuzzle-1 = index of ship's muzzle to fire this turret's 1st and 2nd shots from
124 	char		*gunnerViewTag;//Where to put the view origin of the gunner (name)
125 	float		fTurnSpeed;	//how quickly the turret can turn
126 	qboolean	bAI;	//whether or not the turret auto-targets enemies when it's not manned
127 	qboolean	bAILead;//whether
128 	float		fAIRange;	//how far away the AI will look for enemies
129 	int			passengerNum;//which passenger, if any, has control of this turret (overrides AI)
130 } turretStats_t;
131 
132 typedef struct
133 {
134 //*** IMPORTANT!!! *** See note at top of next structure!!! ***
135 	// Weapon stuff.
136 	int			ID;//index into the weapon data
137 	// The delay between shots for each weapon.
138 	int			delay;
139 	// Whether or not all the muzzles for each weapon can be linked together (linked delay = weapon delay * number of muzzles linked!)
140 	int			linkable;
141 	// Whether or not to auto-aim the projectiles/tracelines at the thing under the crosshair when we fire
142 	qboolean	aimCorrect;
143 	//maximum ammo
144 	int			ammoMax;
145 	//ammo recharge rate - milliseconds per unit (minimum of 100, which is 10 ammo per second)
146 	int			ammoRechargeMS;
147 	//sound to play when out of ammo (plays default "no ammo" sound if none specified)
148 	int			soundNoAmmo;
149 } vehWeaponStats_t;
150 
151 // Compiler pre-define.
152 struct Vehicle_t;
153 
154 typedef struct
155 {
156 //*** IMPORTANT!!! *** vehFields table correponds to this structure!
157 	char		*name;	//unique name of the vehicle
158 
159 	//general data
160 	vehicleType_t	type;	//what kind of vehicle
161 	int			numHands;	//if 2 hands, no weapons, if 1 hand, can use 1-handed weapons, if 0 hands, can use 2-handed weapons
162 	float		lookPitch;	//How far you can look up and down off the forward of the vehicle
163 	float		lookYaw;	//How far you can look left and right off the forward of the vehicle
164 	float		length;		//how long it is - used for body length traces when turning/moving?
165 	float		width;		//how wide it is - used for body length traces when turning/moving?
166 	float		height;		//how tall it is - used for body length traces when turning/moving?
167 	vec3_t		centerOfGravity;//offset from origin: {forward, right, up} as a modifier on that dimension (-1.0f is all the way back, 1.0f is all the way forward)
168 
169 	//speed stats
170 	float		speedMax;		//top speed
171 	float		turboSpeed;		//turbo speed
172 	float		speedMin;		//if < 0, can go in reverse
173 	float		speedIdle;		//what speed it drifts to when no accel/decel input is given
174 	float		accelIdle;		//if speedIdle > 0, how quickly it goes up to that speed
175 	float		acceleration;	//when pressing on accelerator
176 	float		decelIdle;		//when giving no input, how quickly it drops to speedIdle
177 	float		throttleSticks;	//if true, speed stays at whatever you accel/decel to, unless you turbo or brake
178 	float		strafePerc;		//multiplier on current speed for strafing.  If 1.0f, you can strafe at the same speed as you're going forward, 0.5 is half, 0 is no strafing
179 
180 	//handling stats
181 	float		bankingSpeed;	//how quickly it pitches and rolls (not under player control)
182 	float		rollLimit;		//how far it can roll to either side
183 	float		pitchLimit;		//how far it can roll forward or backward
184 	float		braking;		//when pressing on decelerator
185 	float		mouseYaw;		// The mouse yaw override.
186 	float		mousePitch;		// The mouse pitch override.
187 	float		turningSpeed;	//how quickly you can turn
188 	qboolean	turnWhenStopped;//whether or not you can turn when not moving
189 	float		traction;		//how much your command input affects velocity
190 	float		friction;		//how much velocity is cut on its own
191 	float		maxSlope;		//the max slope that it can go up with control
192 	qboolean	speedDependantTurning;//vehicle turns faster the faster it's going
193 
194 	//durability stats
195 	int			mass;			//for momentum and impact force (player mass is 10)
196 	int			armor;			//total points of damage it can take
197 	int			shields;		//energy shield damage points
198 	int			shieldRechargeMS;//energy shield milliseconds per point recharged
199 	float		toughness;		//modifies incoming damage, 1.0 is normal, 0.5 is half, etc.  Simulates being made of tougher materials/construction
200 	int			malfunctionArmorLevel;//when armor drops to or below this point, start malfunctioning
201 	int			surfDestruction; //can parts of this thing be torn off on impact? -rww
202 
203 	//individual "area" health -rww
204 	int			health_front;
205 	int			health_back;
206 	int			health_right;
207 	int			health_left;
208 
209 	//visuals & sounds
210 	char		*model;			//what model to use - if make it an NPC's primary model, don't need this?
211 	char		*skin;			//what skin to use - if make it an NPC's primary model, don't need this?
212 	int			g2radius;		//render radius for the ghoul2 model
213 	int			riderAnim;		//what animation the rider uses
214 	int			radarIconHandle;//what icon to show on radar in MP
215 	char		*droidNPC;		//NPC to attach to *droidunit tag (if it exists in the model)
216 
217 	int			soundOn;		//sound to play when get on it
218 	int			soundOff;		//sound to play when get off
219 	int			soundLoop;		//sound to loop while riding it
220 	int			soundTakeOff;	//sound to play when ship takes off
221 	int			soundEngineStart;//sound to play when ship's thrusters first activate
222 	int			soundSpin;		//sound to loop while spiraling out of control
223 	int			soundTurbo;		//sound to play when turbo/afterburner kicks in
224 	int			soundHyper;		//sound to play when ship lands
225 	int			soundLand;		//sound to play when ship lands
226 	int			soundFlyBy;		//sound to play when they buzz you
227 	int			soundFlyBy2;	//alternate sound to play when they buzz you
228 	int			soundShift1;	//sound to play when accelerating
229 	int			soundShift2;	//sound to play when accelerating
230 	int			soundShift3;	//sound to play when decelerating
231 	int			soundShift4;	//sound to play when decelerating
232 
233 	int			iExhaustFX;		//exhaust effect, played from "*exhaust" bolt(s)
234 	int			iTurboFX;		//turbo exhaust effect, played from "*exhaust" bolt(s) when ship is in "turbo" mode
235 	int			iTurboStartFX;	//turbo begin effect, played from "*exhaust" bolts when "turbo" mode begins
236 	int			iTrailFX;		//trail effect, played from "*trail" bolt(s)
237 	int			iImpactFX;		//impact effect, for when it bumps into something
238 	int			iExplodeFX;		//explosion effect, for when it blows up (should have the sound built into explosion effect)
239 	int			iWakeFX;		//effect it makes when going across water
240 	int			iDmgFX;			//effect to play on damage from a weapon or something
241 	int			iArmorLowFX;	//played when armor is less than 30% of full
242 	int			iArmorGoneFX;	//played when on armor is completely gone
243 
244 	//Weapon stats
245 	vehWeaponStats_t	weapon[MAX_VEHICLE_WEAPONS];
246 
247 	// Which weapon a muzzle fires (has to match one of the weapons this vehicle has). So 1 would be weapon 1,
248 	// 2 would be weapon 2 and so on.
249 	int			weapMuzzle[MAX_VEHICLE_MUZZLES];
250 
251 	//turrets (if any) on the vehicle
252 	turretStats_t	turret[MAX_VEHICLE_TURRETS];
253 
254 	// The max height before this ship (?) starts (auto)landing.
255 	float landingHeight;
256 
257 	//other misc stats
258 	int			gravity;		//normal is 800
259 	float		hoverHeight;	//if 0, it's a ground vehicle
260 	float		hoverStrength;	//how hard it pushes off ground when less than hover height... causes "bounce", like shocks
261 	qboolean	waterProof;		//can drive underwater if it has to
262 	float		bouyancy;		//when in water, how high it floats (1 is neutral bouyancy)
263 	int			fuelMax;		//how much fuel it can hold (capacity)
264 	int			fuelRate;		//how quickly is uses up fuel
265 	int			turboDuration;	//how long turbo lasts
266 	int			turboRecharge;	//how long turbo takes to recharge
267 	int			visibility;		//for sight alerts
268 	int			loudness;		//for sound alerts
269 	float		explosionRadius;//range of explosion
270 	int			explosionDamage;//damage of explosion
271 
272 	int			maxPassengers;	// The max number of passengers this vehicle may have (Default = 0).
273 	qboolean	hideRider;		// rider (and passengers?) should not be drawn
274 	qboolean	killRiderOnDeath;//if rider is on vehicle when it dies, they should die
275 	qboolean	flammable;		//whether or not the vehicle should catch on fire before it explodes
276 	int			explosionDelay;	//how long the vehicle should be on fire/dying before it explodes
277 	//camera stuff
278 	qboolean	cameraOverride;	//whether or not to use all of the following 3rd person camera override values
279 	float		cameraRange;	//how far back the camera should be - normal is 80
280 	float		cameraVertOffset;//how high over the vehicle origin the camera should be - normal is 16
281 	float		cameraHorzOffset;//how far to left/right (negative/positive) of of the vehicle origin the camera should be - normal is 0
282 	float		cameraPitchOffset;//a modifier on the camera's pitch (up/down angle) to the vehicle - normal is 0
283 	float		cameraFOV;		//third person camera FOV, default is 80
284 	float		cameraAlpha;	//fade out the vehicle to this alpha (0.1-1.0f) if it's in the way of the crosshair
285 	qboolean	cameraPitchDependantVertOffset;//use the hacky AT-ST pitch dependant vertical offset
286 
287 	//NOTE: some info on what vehicle weapon to use?  Like ATST or TIE bomber or TIE fighter or X-Wing...?
288 
289 //===VEH_PARM_MAX========================================================================
290 //*** IMPORTANT!!! *** vehFields table correponds to this structure!
291 
292 //THE FOLLOWING FIELDS are not in the vehFields table because they are internal variables, not read in from the .veh file
293 	int			modelIndex;		//set internally, not until this vehicle is spawned into the level
294 
295 	// NOTE: Please note that most of this stuff has been converted from C++ classes to generic C.
296 	// This part of the structure is used to simulate inheritance for vehicles. The basic idea is that all vehicle use
297 	// this vehicle interface since they declare their own functions and assign the function pointer to the
298 	// corresponding function. Meanwhile, the base logic can still call the appropriate functions. In C++ talk all
299 	// of these functions (pointers) are pure virtuals and this is an abstract base class (although it cannot be
300 	// inherited from, only contained and reimplemented (through an object and a setup function respectively)). -AReis
301 
302 	// Makes sure that the vehicle is properly animated.
303 	void (*AnimateVehicle)( Vehicle_t *pVeh );
304 
305 	// Makes sure that the rider's in this vehicle are properly animated.
306 	void (*AnimateRiders)( Vehicle_t *pVeh );
307 
308 	// Determine whether this entity is able to board this vehicle or not.
309 	bool (*ValidateBoard)( Vehicle_t *pVeh, gentity_t *pEnt );
310 
311 	// Set the parent entity of this Vehicle NPC.
312 	void (*SetParent)( Vehicle_t *pVeh, gentity_t *pParentEntity );
313 
314 	// Add a pilot to the vehicle.
315 	void (*SetPilot)( Vehicle_t *pVeh, gentity_t *pPilot );
316 
317 	// Add a passenger to the vehicle (false if we're full).
318 	bool (*AddPassenger)( Vehicle_t *pVeh );
319 
320 	// Animate the vehicle and it's riders.
321 	void (*Animate)( Vehicle_t *pVeh );
322 
323 	// Board this Vehicle (get on). The first entity to board an empty vehicle becomes the Pilot.
324 	bool (*Board)( Vehicle_t *pVeh, gentity_t *pEnt );
325 
326 	// Eject an entity from the vehicle.
327 	bool (*Eject)( Vehicle_t *pVeh, gentity_t *pEnt, qboolean forceEject );
328 
329 	// Eject all the inhabitants of this vehicle.
330 	bool (*EjectAll)( Vehicle_t *pVeh );
331 
332 	// Start a delay until the vehicle dies.
333 	void (*StartDeathDelay)( Vehicle_t *pVeh, int iDelayTime );
334 
335 	// Update death sequence.
336 	void (*DeathUpdate)( Vehicle_t *pVeh );
337 
338 	// Register all the assets used by this vehicle.
339 	void (*RegisterAssets)( Vehicle_t *pVeh );
340 
341 	// Initialize the vehicle (should be called by Spawn?).
342 	bool (*Initialize)( Vehicle_t *pVeh );
343 
344 	// Like a think or move command, this updates various vehicle properties.
345 	bool (*Update)( Vehicle_t *pVeh, const usercmd_t *pUcmd );
346 
347 	// Update the properties of a Rider (that may reflect what happens to the vehicle).
348 	//
349 	//	[return]		bool			True if still in vehicle, false if otherwise.
350 	bool (*UpdateRider)( Vehicle_t *pVeh, gentity_t *pRider, usercmd_t *pUcmd );
351 
352 	// ProcessMoveCommands the Vehicle.
353 	void (*ProcessMoveCommands)( Vehicle_t *pVeh );
354 
355 	// ProcessOrientCommands the Vehicle.
356 	void (*ProcessOrientCommands)( Vehicle_t *pVeh );
357 
358 	// Attachs all the riders of this vehicle to their appropriate position/tag (*driver, *pass1, *pass2, whatever...).
359 	void (*AttachRiders)( Vehicle_t *pVeh );
360 
361 	// Make someone invisible and un-collidable.
362 	void (*Ghost)( Vehicle_t *pVeh, gentity_t *pEnt );
363 
364 	// Make someone visible and collidable.
365 	void (*UnGhost)( Vehicle_t *pVeh, gentity_t *pEnt );
366 
367 	// Get the pilot of this vehicle.
368 	const gentity_t *(*GetPilot)( Vehicle_t *pVeh );
369 
370 	// Whether this vehicle is currently inhabited (by anyone) or not.
371 	bool (*Inhabited)( Vehicle_t *pVeh );
372 } vehicleInfo_t;
373 
374 #define	VFOFS(x) offsetof(vehicleInfo_t, x)
375 
376 #define MAX_VEHICLES	16	//sigh... no more than 64 individual vehicles
377 extern vehicleInfo_t g_vehicleInfo[MAX_VEHICLES];
378 extern int	numVehicles;
379 
380 // Load the function pointers for a vehicle into this shared vehicle info structure.
381 extern void G_SetSpeederVehicleFunctions( vehicleInfo_t *pVehInfo );
382 extern void G_SetAnimalVehicleFunctions( vehicleInfo_t *pVehInfo );
383 extern void G_SetFighterVehicleFunctions( vehicleInfo_t *pVehInfo );
384 extern void G_SetWalkerVehicleFunctions( vehicleInfo_t *pVehInfo );
385 
386 // Setup the shared functions (one's that all vehicles would generally use).
387 extern void G_SetSharedVehicleFunctions( vehicleInfo_t *pVehInfo );
388 
389 // Create/Allocate a new Animal Vehicle (initializing it as well).
390 extern void G_CreateSpeederNPC( Vehicle_t **pVeh, const char *strType );
391 extern void G_CreateAnimalNPC( Vehicle_t **pVeh, const char *strType );
392 extern void G_CreateFighterNPC( Vehicle_t **pVeh, const char *strType );
393 extern void G_CreateWalkerNPC( Vehicle_t **pVeh, const char *strType );
394 
395 #define VEH_DEFAULT_SPEED_MAX		800.0f
396 #define VEH_DEFAULT_ACCEL			10.0f
397 #define VEH_DEFAULT_DECEL			10.0f
398 #define VEH_DEFAULT_STRAFE_PERC		0.5f
399 #define VEH_DEFAULT_BANKING_SPEED	0.5f
400 #define VEH_DEFAULT_ROLL_LIMIT		60.0f
401 #define VEH_DEFAULT_PITCH_LIMIT		90.0f
402 #define VEH_DEFAULT_BRAKING			10.0f
403 #define VEH_DEFAULT_TURNING_SPEED	1.0f
404 #define VEH_DEFAULT_TRACTION		8.0f
405 #define VEH_DEFAULT_FRICTION		1.0f
406 #define VEH_DEFAULT_MAX_SLOPE		0.85f
407 #define VEH_DEFAULT_MASS			200
408 #define VEH_DEFAULT_MAX_ARMOR		200
409 #define VEH_DEFAULT_TOUGHNESS		2.5f
410 #define VEH_DEFAULT_GRAVITY			800
411 #define VEH_DEFAULT_HOVER_HEIGHT	64.0f
412 #define VEH_DEFAULT_HOVER_STRENGTH	10.0f
413 #define VEH_DEFAULT_VISIBILITY		0
414 #define VEH_DEFAULT_LOUDNESS		0
415 #define VEH_DEFAULT_EXP_RAD			400.0f
416 #define VEH_DEFAULT_EXP_DMG			1000
417 #define VEH_MAX_PASSENGERS			10
418 
419 #define VEH_MOUNT_THROW_LEFT		-5
420 #define	VEH_MOUNT_THROW_RIGHT		-6
421 
422 #define MAX_STRAFE_TIME				2000.0f//FIXME: extern?
423 #define	MIN_LANDING_SPEED			200//equal to or less than this and close to ground = auto-slow-down to land
424 #define	MIN_LANDING_SLOPE			0.8f//must be pretty flat to land on the surf
425 
426 #define VEHICLE_BASE				0
427 #define VEHICLE_NONE				-1
428 
429 enum
430 {
431 	VEH_EJECT_LEFT,
432 	VEH_EJECT_RIGHT,
433 	VEH_EJECT_FRONT,
434 	VEH_EJECT_REAR,
435 	VEH_EJECT_TOP,
436 	VEH_EJECT_BOTTOM
437 };
438 
439 // Vehicle flags.
440 enum
441 {
442 	VEH_NONE = 0, VEH_FLYING = 0x00000001, VEH_CRASHING = 0x00000002,
443 	VEH_LANDING = 0x00000004, VEH_BUCKING = 0x00000010, VEH_WINGSOPEN = 0x00000020,
444 	VEH_GEARSOPEN = 0x00000040, VEH_SLIDEBREAKING = 0x00000080, VEH_SPINNING = 0x00000100,
445 	VEH_OUTOFCONTROL = 0x00000200,
446 	VEH_SABERINLEFTHAND = 0x00000400,
447 	VEH_STRAFERAM = 0x00000800,
448 	VEH_ACCELERATORON = 0x00001000,
449 	VEH_ARMORLOW = 0x00002000,
450 	VEH_ARMORGONE = 0x00004000
451 };
452 //externed functions
453 extern void G_VehicleSpawn( gentity_t *self );
454 
455 // A vehicle weapon muzzle.
456 struct Muzzle
457 {
458 	// These are updated every frame and represent the current position and direction for the specific muzzle.
459 	vec3_t m_vMuzzlePos;
460 	vec3_t m_vMuzzleDir;
461 
462 	// This is how long to wait before being able to fire a specific muzzle again. This is based on the firing rate
463 	// so that a firing rate of 10 rounds/sec would make this value initially 100 miliseconds.
464 	int m_iMuzzleWait;
465 
466 	// whether this Muzzle was just fired or not (reset at muzzle flash code).
467 	bool m_bFired;
468 
469 
sg_exportMuzzle470 	void sg_export(
471 		ojk::SavedGameHelper& saved_game) const
472 	{
473 		saved_game.write<float>(m_vMuzzlePos);
474 		saved_game.write<float>(m_vMuzzleDir);
475 		saved_game.write<int32_t>(m_iMuzzleWait);
476 		saved_game.write<int8_t>(m_bFired);
477 		saved_game.skip(3);
478 	}
479 
sg_importMuzzle480 	void sg_import(
481 		ojk::SavedGameHelper& saved_game)
482 	{
483 		saved_game.read<float>(m_vMuzzlePos);
484 		saved_game.read<float>(m_vMuzzleDir);
485 		saved_game.read<int32_t>(m_iMuzzleWait);
486 		saved_game.read<int8_t>(m_bFired);
487 		saved_game.skip(3);
488 	}
489 };
490 
491 //defines for impact damage surface stuff
492 #define	SHIPSURF_FRONT		1
493 #define	SHIPSURF_BACK		2
494 #define	SHIPSURF_RIGHT		3
495 #define	SHIPSURF_LEFT		4
496 
497 #define	SHIPSURF_DAMAGE_FRONT_LIGHT		1
498 #define	SHIPSURF_DAMAGE_BACK_LIGHT		2
499 #define	SHIPSURF_DAMAGE_RIGHT_LIGHT		3
500 #define	SHIPSURF_DAMAGE_LEFT_LIGHT		4
501 #define	SHIPSURF_DAMAGE_FRONT_HEAVY		5
502 #define	SHIPSURF_DAMAGE_BACK_HEAVY		6
503 #define	SHIPSURF_DAMAGE_RIGHT_HEAVY		7
504 #define	SHIPSURF_DAMAGE_LEFT_HEAVY		8
505 
506 //generic part bits
507 #define SHIPSURF_BROKEN_A	(1<<0) //gear 1
508 #define SHIPSURF_BROKEN_B	(1<<1) //gear 1
509 #define SHIPSURF_BROKEN_C	(1<<2) //wing 1
510 #define SHIPSURF_BROKEN_D	(1<<3) //wing 2
511 #define SHIPSURF_BROKEN_E	(1<<4) //wing 3
512 #define SHIPSURF_BROKEN_F	(1<<5) //wing 4
513 
514 typedef struct
515 {
516 	//linked firing mode
517 	qboolean	linked;//weapon 1's muzzles are in linked firing mode
518 	//current weapon ammo
519 	int			ammo;
520 	//debouncer for ammo recharge
521 	int			lastAmmoInc;
522 	//which muzzle will fire next
523 	int			nextMuzzle;
524 
525 
sg_export__anon47a2c1010808526 	void sg_export(
527 		ojk::SavedGameHelper& saved_game) const
528 	{
529 		saved_game.write<int32_t>(linked);
530 		saved_game.write<int32_t>(ammo);
531 		saved_game.write<int32_t>(lastAmmoInc);
532 		saved_game.write<int32_t>(nextMuzzle);
533 	}
534 
sg_import__anon47a2c1010808535 	void sg_import(
536 		ojk::SavedGameHelper& saved_game)
537 	{
538 		saved_game.read<int32_t>(linked);
539 		saved_game.read<int32_t>(ammo);
540 		saved_game.read<int32_t>(lastAmmoInc);
541 		saved_game.read<int32_t>(nextMuzzle);
542 	}
543 } vehWeaponStatus_t;
544 
545 typedef struct
546 {
547 	//current weapon ammo
548 	int			ammo;
549 	//debouncer for ammo recharge
550 	int			lastAmmoInc;
551 	//which muzzle will fire next
552 	int			nextMuzzle;
553 	//which entity they're after
554 	int			enemyEntNum;
555 	//how long to hold on to our current enemy
556 	int			enemyHoldTime;
557 
558 
sg_export__anon47a2c1010908559 	void sg_export(
560 		ojk::SavedGameHelper& saved_game) const
561 	{
562 		saved_game.write<int32_t>(ammo);
563 		saved_game.write<int32_t>(lastAmmoInc);
564 		saved_game.write<int32_t>(nextMuzzle);
565 		saved_game.write<int32_t>(enemyEntNum);
566 		saved_game.write<int32_t>(enemyHoldTime);
567 	}
568 
sg_import__anon47a2c1010908569 	void sg_import(
570 		ojk::SavedGameHelper& saved_game)
571 	{
572 		saved_game.read<int32_t>(ammo);
573 		saved_game.read<int32_t>(lastAmmoInc);
574 		saved_game.read<int32_t>(nextMuzzle);
575 		saved_game.read<int32_t>(enemyEntNum);
576 		saved_game.read<int32_t>(enemyHoldTime);
577 	}
578 } vehTurretStatus_t;
579 
580 // This is the implementation of the vehicle interface and any of the other variables needed. This
581 // is what actually represents a vehicle. -AReis.
582 // !!!!!!!!!!!!!!!!!! loadsave affecting structure !!!!!!!!!!!!!!!!!!!!!!!
583 struct Vehicle_t
584 {
585 	// The entity who pilots/drives this vehicle.
586 	// NOTE: This is redundant (since m_pParentEntity->owner _should_ be the pilot). This makes things clearer though.
587 	gentity_t *m_pPilot;
588 
589 	int m_iPilotTime; //if spawnflag to die without pilot and this < level.time then die.
590 	qboolean m_bHasHadPilot; //qtrue once the vehicle gets its first pilot
591 
592 	//the droid unit NPC for this vehicle, if any
593 	gentity_t *m_pDroidUnit;
594 
595 	// The entity from which this NPC comes from.
596 	gentity_t *m_pParentEntity;
597 
598 	// If not zero, how long to wait before we can do anything with the vehicle (we're getting on still).
599 	// -1 = board from left, -2 = board from right, -3 = jump/quick board.  -4 & -5 = throw off existing pilot
600 	int		m_iBoarding;
601 
602 	// Used to check if we've just started the boarding process
603 	bool	m_bWasBoarding;
604 
605 	// The speed the vehicle maintains while boarding occurs (often zero)
606 	vec3_t	m_vBoardingVelocity;
607 
608 	// Time modifier (must only be used in ProcessMoveCommands() and ProcessOrientCommands() and is updated in Update()).
609 	float m_fTimeModifier;
610 
611 	// Ghoul2 Animation info.
612 	// NOTE: Since each vehicle has their own model instance, these bolts must be local to each vehicle as well.
613 	int m_iLeftWingBone;
614 	int m_iRightWingBone;
615 	//int m_iDriverTag;
616 	int m_iExhaustTag[MAX_VEHICLE_EXHAUSTS];
617 	int m_iMuzzleTag[MAX_VEHICLE_MUZZLES];
618 	int m_iDroidUnitTag;
619 	int	m_iGunnerViewTag[MAX_VEHICLE_TURRETS];//Where to put the view origin of the gunner (index)
620 
621 	// This vehicles weapon muzzles.
622 	Muzzle m_Muzzles[MAX_VEHICLE_MUZZLES];
623 
624 	// The user commands structure.
625 	usercmd_t m_ucmd;
626 
627 	// The direction an entity will eject from the vehicle towards.
628 	int m_EjectDir;
629 
630 	// Flags that describe the vehicles behavior.
631 	unsigned long m_ulFlags;
632 
633 	// NOTE: Vehicle Type ID, Orientation, and Armor MUST be transmitted over the net.
634 
635 	// Current angles of this vehicle.
636 	vec3_t		m_vOrientation;
637 
638 	// How long you have strafed left or right (increments every frame that you strafe to right, decrements every frame you strafe left)
639 	int			m_fStrafeTime;
640 
641 	// Previous angles of this vehicle.
642 	vec3_t		m_vPrevOrientation;
643 
644 	// When control is lost on a speeder, current angular velocity is stored here and applied until landing
645 	float		m_vAngularVelocity;
646 
647 	vec3_t		m_vFullAngleVelocity;
648 
649 	// Current armor and shields of your vehicle (explodes if armor to 0).
650 	int			m_iArmor;	//hull strength - STAT_HEALTH on NPC
651 	int			m_iShields;	//energy shielding - STAT_ARMOR on NPC
652 
653 	// Timer for all cgame-FX...? ex: exhaust?
654 	int			m_iLastFXTime;
655 
656 	// When to die.
657 	int			m_iDieTime;
658 
659 	// This pointer is to a valid VehicleInfo (which could be an animal, speeder, fighter, whatever). This
660 	// contains the functions actually used to do things to this specific kind of vehicle as well as shared
661 	// information (max speed, type, etc...).
662 	vehicleInfo_t *m_pVehicleInfo;
663 
664 	// This trace tells us if we're within landing height.
665 	trace_t m_LandTrace;
666 
667 	//bitflag of surfaces that have broken off
668 	int			m_iRemovedSurfaces;
669 
670 	// the last time this vehicle fired a turbo burst
671 	int			m_iTurboTime;
672 
673 	//how long it should drop like a rock for after freed from SUSPEND
674 	int			m_iDropTime;
675 
676 	int			m_iSoundDebounceTimer;
677 
678 	//last time we incremented the shields
679 	int			lastShieldInc;
680 
681 	//so we don't hold it down and toggle it back and forth
682 	qboolean	linkWeaponToggleHeld;
683 
684 	//info about our weapons (linked, ammo, etc.)
685 	vehWeaponStatus_t	weaponStatus[MAX_VEHICLE_WEAPONS];
686 	vehTurretStatus_t	turretStatus[MAX_VEHICLE_TURRETS];
687 
688 	//the guy who was previously the pilot
689 	gentity_t*	m_pOldPilot;
690 
691 	// don't need these in mp
692 	int			m_safeJumpMountTime;
693 	float		m_safeJumpMountRightDot;
694 
695 
sg_exportVehicle_t696 	void sg_export(
697 		ojk::SavedGameHelper& saved_game) const
698 	{
699 		saved_game.write<int32_t>(m_pPilot);
700 		saved_game.write<int32_t>(m_iPilotTime);
701 		saved_game.write<int32_t>(m_bHasHadPilot);
702 		saved_game.write<int32_t>(m_pDroidUnit);
703 		saved_game.write<int32_t>(m_pParentEntity);
704 		saved_game.write<int32_t>(m_iBoarding);
705 		saved_game.write<int8_t>(m_bWasBoarding);
706 		saved_game.skip(3);
707 		saved_game.write<float>(m_vBoardingVelocity);
708 		saved_game.write<float>(m_fTimeModifier);
709 		saved_game.write<int32_t>(m_iLeftWingBone);
710 		saved_game.write<int32_t>(m_iRightWingBone);
711 		saved_game.write<int32_t>(m_iExhaustTag);
712 		saved_game.write<int32_t>(m_iMuzzleTag);
713 		saved_game.write<int32_t>(m_iDroidUnitTag);
714 		saved_game.write<int32_t>(m_iGunnerViewTag);
715 		saved_game.write<>(m_Muzzles);
716 		saved_game.write<>(m_ucmd);
717 		saved_game.write<int32_t>(m_EjectDir);
718 		saved_game.write<uint32_t>(m_ulFlags);
719 		saved_game.write<float>(m_vOrientation);
720 		saved_game.write<int32_t>(m_fStrafeTime);
721 		saved_game.write<float>(m_vPrevOrientation);
722 		saved_game.write<float>(m_vAngularVelocity);
723 		saved_game.write<float>(m_vFullAngleVelocity);
724 		saved_game.write<int32_t>(m_iArmor);
725 		saved_game.write<int32_t>(m_iShields);
726 		saved_game.write<int32_t>(m_iLastFXTime);
727 		saved_game.write<int32_t>(m_iDieTime);
728 		saved_game.write<int32_t>(m_pVehicleInfo);
729 		saved_game.write<>(m_LandTrace);
730 		saved_game.write<int32_t>(m_iRemovedSurfaces);
731 		saved_game.write<int32_t>(m_iTurboTime);
732 		saved_game.write<int32_t>(m_iDropTime);
733 		saved_game.write<int32_t>(m_iSoundDebounceTimer);
734 		saved_game.write<int32_t>(lastShieldInc);
735 		saved_game.write<int32_t>(linkWeaponToggleHeld);
736 		saved_game.write<>(weaponStatus);
737 		saved_game.write<>(turretStatus);
738 		saved_game.write<int32_t>(m_pOldPilot);
739 		saved_game.write<int32_t>(m_safeJumpMountTime);
740 		saved_game.write<float>(m_safeJumpMountRightDot);
741 	}
742 
sg_importVehicle_t743 	void sg_import(
744 		ojk::SavedGameHelper& saved_game)
745 	{
746 		saved_game.read<int32_t>(m_pPilot);
747 		saved_game.read<int32_t>(m_iPilotTime);
748 		saved_game.read<int32_t>(m_bHasHadPilot);
749 		saved_game.read<int32_t>(m_pDroidUnit);
750 		saved_game.read<int32_t>(m_pParentEntity);
751 		saved_game.read<int32_t>(m_iBoarding);
752 		saved_game.read<int8_t>(m_bWasBoarding);
753 		saved_game.skip(3);
754 		saved_game.read<float>(m_vBoardingVelocity);
755 		saved_game.read<float>(m_fTimeModifier);
756 		saved_game.read<int32_t>(m_iLeftWingBone);
757 		saved_game.read<int32_t>(m_iRightWingBone);
758 		saved_game.read<int32_t>(m_iExhaustTag);
759 		saved_game.read<int32_t>(m_iMuzzleTag);
760 		saved_game.read<int32_t>(m_iDroidUnitTag);
761 		saved_game.read<int32_t>(m_iGunnerViewTag);
762 		saved_game.read<>(m_Muzzles);
763 		saved_game.read<>(m_ucmd);
764 		saved_game.read<int32_t>(m_EjectDir);
765 		saved_game.read<uint32_t>(m_ulFlags);
766 		saved_game.read<float>(m_vOrientation);
767 		saved_game.read<int32_t>(m_fStrafeTime);
768 		saved_game.read<float>(m_vPrevOrientation);
769 		saved_game.read<float>(m_vAngularVelocity);
770 		saved_game.read<float>(m_vFullAngleVelocity);
771 		saved_game.read<int32_t>(m_iArmor);
772 		saved_game.read<int32_t>(m_iShields);
773 		saved_game.read<int32_t>(m_iLastFXTime);
774 		saved_game.read<int32_t>(m_iDieTime);
775 		saved_game.read<int32_t>(m_pVehicleInfo);
776 		saved_game.read<>(m_LandTrace);
777 		saved_game.read<int32_t>(m_iRemovedSurfaces);
778 		saved_game.read<int32_t>(m_iTurboTime);
779 		saved_game.read<int32_t>(m_iDropTime);
780 		saved_game.read<int32_t>(m_iSoundDebounceTimer);
781 		saved_game.read<int32_t>(lastShieldInc);
782 		saved_game.read<int32_t>(linkWeaponToggleHeld);
783 		saved_game.read<>(weaponStatus);
784 		saved_game.read<>(turretStatus);
785 		saved_game.read<int32_t>(m_pOldPilot);
786 		saved_game.read<int32_t>(m_safeJumpMountTime);
787 		saved_game.read<float>(m_safeJumpMountRightDot);
788 	}
789 };
790 
791 extern int BG_VehicleGetIndex( const char *vehicleName );
792 
793 #endif	// __G_VEHICLES_H
794