A start to explaining Quake 3


Probably not quite right, but it's a start. I'm forced to make some guesses about the structure, due to me not actually having the game, and not being able to test my suppositions.

(g) means a file is in the game folder, (c) means the client folder, (u) means the ui folder

The main data structure for entities in q3 is shown below. this is stored in q_shared.h in the game directory (it's linked to directly by most of the other code (the *_local.h files link to it)

I'm pulling together definitions for each of the fields in it. each field that is a link, links to the definitions I've been able to find. Comments I've added are in blue.


struct gentity_s {
entityState_t s; // communicated by server to clients
entityShared_t r; // shared by both the server system and game

// DO NOT MODIFY ANYTHING ABOVE THIS, THE SERVER
// EXPECTS THE FIELDS IN THAT ORDER!
//================================

struct gclient_s *client; // NULL if not a client

qboolean inuse; //If a structure is being used this should be true.

char *classname; // set in QuakeEd Map entity stuff I think
int spawnflags; // set in QuakeEd

qboolean neverFree; // if true, FreeEntity will only unlink
// bodyque uses this

int flags; // FL_* variables

char *model;
char *model2;
int freetime; // level.time when the object was freed
int eventTime; // events will be cleared EVENT_VALID_MSEC after set
qboolean freeAfterEvent;
qboolean unlinkAfterEvent;

qboolean physicsObject; // if true, it can be pushed by movers and fall off edges
// all game items are physicsObjects,
float physicsBounce; // 1.0 = continuous bounce, 0.0 = no bounce
int clipmask; // brushes with this content value will be collided against
// when moving. items and corpses do not collide against
// players, for instance

// movers
moverState_t moverState;
int soundPos1;
int sound1to2;
int sound2to1;
int soundPos2;
int soundLoop;
gentity_t *parent;
gentity_t *nextTrain;
gentity_t *prevTrain;
vec3_t pos1, pos2;

char *message;

int timestamp; // body queue sinking, etc

float angle; // set in editor, -1 = up, -2 = down
char *target;
char *targetname;
char *team;
gentity_t *target_ent;

float speed;
vec3_t movedir;

int nextthink; // when the entity will think next.
void (*think)(gentity_t *self);// what it does when it thinks
void (*reached)(gentity_t *self); // movers call this when hitting endpoint
void (*blocked)(gentity_t *self, gentity_t *other); // what a mover does when it cant move
void (*touch)(gentity_t *self, gentity_t *other, trace_t *trace);// what happens if it is touched
void (*use)(gentity_t *self, gentity_t *other, gentity_t *activator); // what happens when the entity is used
void (*pain)(gentity_t *self, gentity_t *attacker, int damage);// What happens when an entity is damaged
void (*die)(gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod); // What happens when it's taken more damage than it has health

int pain_debounce_time;// used so the pain function isn't activated too often
int fly_sound_debounce_time; // wind tunnel
int last_move_time;

int health; // How much damage an entity can take

qboolean takedamage;

int damage; // Storage for how much it can do (checked in things like explode functions) ditto for the ones below
int splashDamage; // quad will increase this without increasing radius
int splashRadius;
int methodOfDeath;
int splashMethodOfDeath;

int count;

gentity_t *chain; // for trains I would guess
gentity_t *enemy;
gentity_t *activator;
gentity_t *teamchain; // next entity in team
gentity_t *teammaster; // master of the team

int watertype;// From the content types. water, slime lava, etc
int waterlevel;// appears to be 0: out of water 3: underwater with 1 and 2 being part in (feet , waist?)

int noise_index;

// timing variables
float wait;
float random;

gitem_t *item; // for bonus items

qboolean botDelayBegin;

};

The entity state structure (sent from server to client)
typedef struct entityState_s {

int number; // entity index
int eType; // entityType_t
int eFlags; // This would appear to be refering to this list of flags

trajectory_t pos; // for calculating position
trajectory_t apos; // for calculating angles

int time; // not sure what these two are for
int time2;

vec3_t origin; // a 3 dimensional array of floats (Note)
vec3_t origin2; // these 2 are probably used for the actual location of the entity, and where it was a frame ago

vec3_t angles; //These 2 will probably be for current angles, and angles a frame ago
vec3_t angles2;

int otherEntityNum; // shotgun sources, etc
int otherEntityNum2; // not a clue here yet

int groundEntityNum; // -1 = in air
int constantLight; // r + (g<<8) + (b<<16) + (intensity<<24)
int loopSound; // constantly loop this sound

int modelindex;
int modelindex2;
int clientNum; // 0 to (MAX_CLIENTS - 1), for players and corpses
int frame;

int solid; // for client side prediction, trap_linkentity sets this properly

int event; // impulse events -- muzzle flashes, footsteps, etc
int eventParm;

// for players
int powerups; // bit flags
int weapon; // determines weapon and flash model, etc
int legsAnim; // mask off ANIM_TOGGLEBIT
int torsoAnim; // mask off ANIM_TOGGLEBIT
} entityState_t;


Entity Types

This is the list of types that an entity can be. when I find out the effects these have on the game, I'll update it (in bg_public.h (in game))

typedef enum {
	ET_GENERAL,
	ET_PLAYER,
	ET_ITEM,
	ET_MISSILE,
	ET_MOVER,
	ET_BEAM,
	ET_PORTAL,
	ET_SPEAKER,
	ET_PUSH_TRIGGER,
	ET_TELEPORT_TRIGGER,
	ET_INVISIBLE,
	ET_GRAPPLE,				// grapple hooked on wall

	ET_EVENTS				// any of the EV_* events can be added freestanding
							// by setting eType to ET_EVENTS + eventNum
							// this avoids having to set eFlags and eventNum
} entityType_t;

Entity Flags

Also in bg_public.h (g) All I can find for the moment

// entityState_t->eFlags
#define	EF_DEAD				0x00000001		// don't draw a foe marker over players with EF_DEAD
#define	EF_TELEPORT_BIT		0x00000004		// toggled every time the origin abruptly changes
#define	EF_AWARD_EXCELLENT	0x00000008		// draw an excellent sprite
#define	EF_BOUNCE			0x00000010		// for missiles
#define	EF_BOUNCE_HALF		0x00000020		// for missiles
#define	EF_AWARD_GAUNTLET	0x00000040		// draw a gauntlet sprite
#define	EF_NODRAW			0x00000080		// may have an event, but no model (unspawned items)
#define	EF_FIRING			0x00000100		// for lightning gun
#define	EF_MOVER_STOP		0x00000400		// will push otherwise
#define	EF_TALK				0x00001000		// draw a talk balloon
#define	EF_CONNECTION		0x00002000		// draw a connection trouble sprite
#define	EF_VOTED			0x00004000		// already cast a vote
#define	EF_AWARD_IMPRESSIVE	0x00008000		// draw an impressive sprite

trajectory_t Definition

From q_shared.h(g).

typedef struct {
	trType_t	trType;
	int		trTime;
	int		trDuration;			// if non 0, trTime + trDuration = stop time
	vec3_t	trBase;
	vec3_t	trDelta;			// velocity, etc
} trajectory_t;

vec3_t Note

I checked to see if this has changed. it has, kinda. heres it's defintion, along with some others

typedef float vec_t;
typedef vec_t vec2_t[2];
typedef vec_t vec3_t[3];
typedef vec_t vec4_t[4];
typedef vec_t vec5_t[5];

I don't know why they've done it this way yet, but I'm planning to find out


The client structure (I'm working on the defintions)

struct gclient_s {
	// ps MUST be the first element, because the server expects it
	playerState_t	ps;				// communicated by server to clients

	// the rest of the structure is private to game
	clientPersistant_t	pers;
	clientSession_t		sess;

	qboolean	readyToExit;		// wishes to leave the intermission

	qboolean	noclip;

	int			lastCmdTime;		// level.time of last usercmd_t, for EF_CONNECTION
									// we can't just use pers.lastCommand.time, because
									// of the g_sycronousclients case
	int			buttons;
	int			oldbuttons;
	int			latched_buttons;

	// sum up damage over an entire frame, so
	// shotgun blasts give a single big kick
	int			damage_armor;		// damage absorbed by armor
	int			damage_blood;		// damage taken out of health
	int			damage_knockback;	// impact damage
	vec3_t		damage_from;		// origin for vector calculation
	qboolean	damage_fromWorld;	// if true, don't use the damage_from vector

	int			accurateCount;		// for "impressive" reward sound

	//
	int			lasthurt_client;	// last client that damaged this client
	int			lasthurt_mod;		// type of damage the client did

	// timers
	int			respawnTime;		// can respawn when time > this, force after g_forcerespwan
	int			inactivityTime;		// kick players when time > this
	qboolean	inactivityWarning;	// qtrue if the five seoond warning has been given
	int			rewardTime;			// clear the EF_AWARD_IMPRESSIVE, etc when time > this

	int			airOutTime;

	int			lastKillTime;		// for multiple kill rewards

	qboolean	fireHeld;			// used for hook
	gentity_t	*hook;				// grapple hook if out

	// timeResidual is used to handle events that happen every second
	// like health / armor countdowns and regeneration
	int			timeResidual;
};

Entity Flags

// gentity->flags
#define	FL_GODMODE				0x00000010
#define	FL_NOTARGET				0x00000020
#define	FL_TEAMSLAVE			0x00000400	// not the first on the team
#define FL_NO_KNOCKBACK			0x00000800
#define FL_DROPPED_ITEM			0x00001000
#define FL_NO_BOTS				0x00002000	// spawn point not for bot use
#define FL_NO_HUMANS			0x00004000	// spawn point just for bots