1 /*
2 ===========================================================================
3 Copyright (C) 1999-2005 Id Software, Inc.
4 
5 This file is part of Quake III Arena source code.
6 
7 Quake III Arena source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
11 
12 Quake III Arena source code is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Quake III Arena source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 ===========================================================================
21 */
22 //
23 // g_local.h -- local definitions for game module
24 
25 #include "../qcommon/q_shared.h"
26 #include "bg_public.h"
27 #include "g_public.h"
28 
29 //==================================================================
30 
31 // the "gameversion" client command will print this plus compile date
32 #define	GAMEVERSION	BASEGAME
33 
34 #define BODY_QUEUE_SIZE		8
35 
36 #define INFINITE			1000000
37 
38 #define	FRAMETIME			100					// msec
39 #define	CARNAGE_REWARD_TIME	3000
40 #define REWARD_SPRITE_TIME	2000
41 
42 #define	INTERMISSION_DELAY_TIME	1000
43 #define	SP_INTERMISSION_DELAY_TIME	5000
44 
45 // gentity->flags
46 #define	FL_GODMODE				0x00000010
47 #define	FL_NOTARGET				0x00000020
48 #define	FL_TEAMSLAVE			0x00000400	// not the first on the team
49 #define FL_NO_KNOCKBACK			0x00000800
50 #define FL_DROPPED_ITEM			0x00001000
51 #define FL_NO_BOTS				0x00002000	// spawn point not for bot use
52 #define FL_NO_HUMANS			0x00004000	// spawn point just for bots
53 #define FL_FORCE_GESTURE		0x00008000	// force gesture on client
54 
55 // movers are things like doors, plats, buttons, etc
56 typedef enum {
57 	MOVER_POS1,
58 	MOVER_POS2,
59 	MOVER_1TO2,
60 	MOVER_2TO1
61 } moverState_t;
62 
63 #define SP_PODIUM_MODEL		"models/mapobjects/podium/podium4.md3"
64 
65 //============================================================================
66 
67 typedef struct gentity_s gentity_t;
68 typedef struct gclient_s gclient_t;
69 
70 struct gentity_s {
71 	entityState_t	s;				// communicated by server to clients
72 	entityShared_t	r;				// shared by both the server system and game
73 
74 	// DO NOT MODIFY ANYTHING ABOVE THIS, THE SERVER
75 	// EXPECTS THE FIELDS IN THAT ORDER!
76 	//================================
77 
78 	struct gclient_s	*client;			// NULL if not a client
79 
80 	qboolean	inuse;
81 
82 	char		*classname;			// set in QuakeEd
83 	int			spawnflags;			// set in QuakeEd
84 
85 	qboolean	neverFree;			// if true, FreeEntity will only unlink
86 									// bodyque uses this
87 
88 	int			flags;				// FL_* variables
89 
90 	char		*model;
91 	char		*model2;
92 	int			freetime;			// level.time when the object was freed
93 
94 	int			eventTime;			// events will be cleared EVENT_VALID_MSEC after set
95 	qboolean	freeAfterEvent;
96 	qboolean	unlinkAfterEvent;
97 
98 	qboolean	physicsObject;		// if true, it can be pushed by movers and fall off edges
99 									// all game items are physicsObjects,
100 	float		physicsBounce;		// 1.0 = continuous bounce, 0.0 = no bounce
101 	int			clipmask;			// brushes with this content value will be collided against
102 									// when moving.  items and corpses do not collide against
103 									// players, for instance
104 
105 	// movers
106 	moverState_t moverState;
107 	int			soundPos1;
108 	int			sound1to2;
109 	int			sound2to1;
110 	int			soundPos2;
111 	int			soundLoop;
112 	gentity_t	*parent;
113 	gentity_t	*nextTrain;
114 	gentity_t	*prevTrain;
115 	vec3_t		pos1, pos2;
116 
117 	char		*message;
118 
119 	int			timestamp;		// body queue sinking, etc
120 
121 	float		angle;			// set in editor, -1 = up, -2 = down
122 	char		*target;
123 	char		*targetname;
124 	char		*team;
125 	char		*targetShaderName;
126 	char		*targetShaderNewName;
127 	gentity_t	*target_ent;
128 
129 	float		speed;
130 	vec3_t		movedir;
131 
132 	int			nextthink;
133 	void		(*think)(gentity_t *self);
134 	void		(*reached)(gentity_t *self);	// movers call this when hitting endpoint
135 	void		(*blocked)(gentity_t *self, gentity_t *other);
136 	void		(*touch)(gentity_t *self, gentity_t *other, trace_t *trace);
137 	void		(*use)(gentity_t *self, gentity_t *other, gentity_t *activator);
138 	void		(*pain)(gentity_t *self, gentity_t *attacker, int damage);
139 	void		(*die)(gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod);
140 
141 	int			pain_debounce_time;
142 	int			fly_sound_debounce_time;	// wind tunnel
143 	int			last_move_time;
144 
145 	int			health;
146 
147 	qboolean	takedamage;
148 
149 	int			damage;
150 	int			splashDamage;	// quad will increase this without increasing radius
151 	int			splashRadius;
152 	int			methodOfDeath;
153 	int			splashMethodOfDeath;
154 
155 	int			count;
156 
157 	gentity_t	*chain;
158 	gentity_t	*enemy;
159 	gentity_t	*activator;
160 	gentity_t	*teamchain;		// next entity in team
161 	gentity_t	*teammaster;	// master of the team
162 
163 #ifdef MISSIONPACK
164 	int			kamikazeTime;
165 	int			kamikazeShockTime;
166 #endif
167 
168 	int			watertype;
169 	int			waterlevel;
170 
171 	int			noise_index;
172 
173 	// timing variables
174 	float		wait;
175 	float		random;
176 
177 	gitem_t		*item;			// for bonus items
178 };
179 
180 
181 typedef enum {
182 	CON_DISCONNECTED,
183 	CON_CONNECTING,
184 	CON_CONNECTED
185 } clientConnected_t;
186 
187 typedef enum {
188 	SPECTATOR_NOT,
189 	SPECTATOR_FREE,
190 	SPECTATOR_FOLLOW,
191 	SPECTATOR_SCOREBOARD
192 } spectatorState_t;
193 
194 typedef enum {
195 	TEAM_BEGIN,		// Beginning a team game, spawn at base
196 	TEAM_ACTIVE		// Now actively playing
197 } playerTeamStateState_t;
198 
199 typedef struct {
200 	playerTeamStateState_t	state;
201 
202 	int			location;
203 
204 	int			captures;
205 	int			basedefense;
206 	int			carrierdefense;
207 	int			flagrecovery;
208 	int			fragcarrier;
209 	int			assists;
210 
211 	float		lasthurtcarrier;
212 	float		lastreturnedflag;
213 	float		flagsince;
214 	float		lastfraggedcarrier;
215 } playerTeamState_t;
216 
217 // the auto following clients don't follow a specific client
218 // number, but instead follow the first two active players
219 #define	FOLLOW_ACTIVE1	-1
220 #define	FOLLOW_ACTIVE2	-2
221 
222 // client data that stays across multiple levels or tournament restarts
223 // this is achieved by writing all the data to cvar strings at game shutdown
224 // time and reading them back at connection time.  Anything added here
225 // MUST be dealt with in G_InitSessionData() / G_ReadSessionData() / G_WriteSessionData()
226 typedef struct {
227 	team_t		sessionTeam;
228 	int			spectatorTime;		// for determining next-in-line to play
229 	spectatorState_t	spectatorState;
230 	int			spectatorClient;	// for chasecam and follow mode
231 	int			wins, losses;		// tournament stats
232 	qboolean	teamLeader;			// true when this client is a team leader
233 } clientSession_t;
234 
235 //
236 #define MAX_NETNAME			36
237 #define	MAX_VOTE_COUNT		3
238 
239 // client data that stays across multiple respawns, but is cleared
240 // on each level change or team change at ClientBegin()
241 typedef struct {
242 	clientConnected_t	connected;
243 	usercmd_t	cmd;				// we would lose angles if not persistant
244 	qboolean	localClient;		// true if "ip" info key is "localhost"
245 	qboolean	initialSpawn;		// the first spawn should be at a cool location
246 	qboolean	predictItemPickup;	// based on cg_predictItems userinfo
247 	qboolean	pmoveFixed;			//
248 	char		netname[MAX_NETNAME];
249 	int			maxHealth;			// for handicapping
250 	int			enterTime;			// level.time the client entered the game
251 	playerTeamState_t teamState;	// status in teamplay games
252 	int			voteCount;			// to prevent people from constantly calling votes
253 	int			teamVoteCount;		// to prevent people from constantly calling votes
254 	qboolean	teamInfo;			// send team overlay updates?
255 } clientPersistant_t;
256 
257 
258 // this structure is cleared on each ClientSpawn(),
259 // except for 'client->pers' and 'client->sess'
260 struct gclient_s {
261 	// ps MUST be the first element, because the server expects it
262 	playerState_t	ps;				// communicated by server to clients
263 
264 	// the rest of the structure is private to game
265 	clientPersistant_t	pers;
266 	clientSession_t		sess;
267 
268 	qboolean	readyToExit;		// wishes to leave the intermission
269 
270 	qboolean	noclip;
271 
272 	int			lastCmdTime;		// level.time of last usercmd_t, for EF_CONNECTION
273 									// we can't just use pers.lastCommand.time, because
274 									// of the g_sycronousclients case
275 	int			buttons;
276 	int			oldbuttons;
277 	int			latched_buttons;
278 
279 	vec3_t		oldOrigin;
280 
281 	// sum up damage over an entire frame, so
282 	// shotgun blasts give a single big kick
283 	int			damage_armor;		// damage absorbed by armor
284 	int			damage_blood;		// damage taken out of health
285 	int			damage_knockback;	// impact damage
286 	vec3_t		damage_from;		// origin for vector calculation
287 	qboolean	damage_fromWorld;	// if true, don't use the damage_from vector
288 
289 	int			accurateCount;		// for "impressive" reward sound
290 
291 	int			accuracy_shots;		// total number of shots
292 	int			accuracy_hits;		// total number of hits
293 
294 	//
295 	int			lastkilled_client;	// last client that this client killed
296 	int			lasthurt_client;	// last client that damaged this client
297 	int			lasthurt_mod;		// type of damage the client did
298 
299 	// timers
300 	int			respawnTime;		// can respawn when time > this, force after g_forcerespwan
301 	int			inactivityTime;		// kick players when time > this
302 	qboolean	inactivityWarning;	// qtrue if the five seoond warning has been given
303 	int			rewardTime;			// clear the EF_AWARD_IMPRESSIVE, etc when time > this
304 
305 	int			airOutTime;
306 
307 	int			lastKillTime;		// for multiple kill rewards
308 
309 	qboolean	fireHeld;			// used for hook
310 	gentity_t	*hook;				// grapple hook if out
311 
312 	int			switchTeamTime;		// time the player switched teams
313 
314 	// timeResidual is used to handle events that happen every second
315 	// like health / armor countdowns and regeneration
316 	int			timeResidual;
317 
318 #ifdef MISSIONPACK
319 	gentity_t	*persistantPowerup;
320 	int			portalID;
321 	int			ammoTimes[WP_NUM_WEAPONS];
322 	int			invulnerabilityTime;
323 #endif
324 
325 	char		*areabits;
326 };
327 
328 
329 //
330 // this structure is cleared as each map is entered
331 //
332 #define	MAX_SPAWN_VARS			64
333 #define	MAX_SPAWN_VARS_CHARS	4096
334 
335 typedef struct {
336 	struct gclient_s	*clients;		// [maxclients]
337 
338 	struct gentity_s	*gentities;
339 	int			gentitySize;
340 	int			num_entities;		// current number, <= MAX_GENTITIES
341 
342 	int			warmupTime;			// restart match at this time
343 
344 	fileHandle_t	logFile;
345 
346 	// store latched cvars here that we want to get at often
347 	int			maxclients;
348 
349 	int			framenum;
350 	int			time;					// in msec
351 	int			previousTime;			// so movers can back up when blocked
352 
353 	int			startTime;				// level.time the map was started
354 
355 	int			teamScores[TEAM_NUM_TEAMS];
356 	int			lastTeamLocationTime;		// last time of client team location update
357 
358 	qboolean	newSession;				// don't use any old session data, because
359 										// we changed gametype
360 
361 	qboolean	restarted;				// waiting for a map_restart to fire
362 
363 	int			numConnectedClients;
364 	int			numNonSpectatorClients;	// includes connecting clients
365 	int			numPlayingClients;		// connected, non-spectators
366 	int			sortedClients[MAX_CLIENTS];		// sorted by score
367 	int			follow1, follow2;		// clientNums for auto-follow spectators
368 
369 	int			snd_fry;				// sound index for standing in lava
370 
371 	int			warmupModificationCount;	// for detecting if g_warmup is changed
372 
373 	// voting state
374 	char		voteString[MAX_STRING_CHARS];
375 	char		voteDisplayString[MAX_STRING_CHARS];
376 	int			voteTime;				// level.time vote was called
377 	int			voteExecuteTime;		// time the vote is executed
378 	int			voteYes;
379 	int			voteNo;
380 	int			numVotingClients;		// set by CalculateRanks
381 
382 	// team voting state
383 	char		teamVoteString[2][MAX_STRING_CHARS];
384 	int			teamVoteTime[2];		// level.time vote was called
385 	int			teamVoteYes[2];
386 	int			teamVoteNo[2];
387 	int			numteamVotingClients[2];// set by CalculateRanks
388 
389 	// spawn variables
390 	qboolean	spawning;				// the G_Spawn*() functions are valid
391 	int			numSpawnVars;
392 	char		*spawnVars[MAX_SPAWN_VARS][2];	// key / value pairs
393 	int			numSpawnVarChars;
394 	char		spawnVarChars[MAX_SPAWN_VARS_CHARS];
395 
396 	// intermission state
397 	int			intermissionQueued;		// intermission was qualified, but
398 										// wait INTERMISSION_DELAY_TIME before
399 										// actually going there so the last
400 										// frag can be watched.  Disable future
401 										// kills during this delay
402 	int			intermissiontime;		// time the intermission was started
403 	char		*changemap;
404 	qboolean	readyToExit;			// at least one client wants to exit
405 	int			exitTime;
406 	vec3_t		intermission_origin;	// also used for spectator spawns
407 	vec3_t		intermission_angle;
408 
409 	qboolean	locationLinked;			// target_locations get linked
410 	gentity_t	*locationHead;			// head of the location list
411 	int			bodyQueIndex;			// dead bodies
412 	gentity_t	*bodyQue[BODY_QUEUE_SIZE];
413 #ifdef MISSIONPACK
414 	int			portalSequence;
415 #endif
416 } level_locals_t;
417 
418 
419 //
420 // g_spawn.c
421 //
422 qboolean	G_SpawnString( const char *key, const char *defaultString, char **out );
423 // spawn string returns a temporary reference, you must CopyString() if you want to keep it
424 qboolean	G_SpawnFloat( const char *key, const char *defaultString, float *out );
425 qboolean	G_SpawnInt( const char *key, const char *defaultString, int *out );
426 qboolean	G_SpawnVector( const char *key, const char *defaultString, float *out );
427 void		G_SpawnEntitiesFromString( void );
428 char *G_NewString( const char *string );
429 
430 //
431 // g_cmds.c
432 //
433 void Cmd_Score_f (gentity_t *ent);
434 void StopFollowing( gentity_t *ent );
435 void BroadcastTeamChange( gclient_t *client, int oldTeam );
436 void SetTeam( gentity_t *ent, char *s );
437 void Cmd_FollowCycle_f( gentity_t *ent, int dir );
438 
439 //
440 // g_items.c
441 //
442 void G_CheckTeamItems( void );
443 void G_RunItem( gentity_t *ent );
444 void RespawnItem( gentity_t *ent );
445 
446 void UseHoldableItem( gentity_t *ent );
447 void PrecacheItem (gitem_t *it);
448 gentity_t *Drop_Item( gentity_t *ent, gitem_t *item, float angle );
449 gentity_t *LaunchItem( gitem_t *item, vec3_t origin, vec3_t velocity );
450 void SetRespawn (gentity_t *ent, float delay);
451 void G_SpawnItem (gentity_t *ent, gitem_t *item);
452 void FinishSpawningItem( gentity_t *ent );
453 void Think_Weapon (gentity_t *ent);
454 int ArmorIndex (gentity_t *ent);
455 void	Add_Ammo (gentity_t *ent, int weapon, int count);
456 void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace);
457 
458 void ClearRegisteredItems( void );
459 void RegisterItem( gitem_t *item );
460 void SaveRegisteredItems( void );
461 
462 //
463 // g_utils.c
464 //
465 int G_ModelIndex( char *name );
466 int		G_SoundIndex( char *name );
467 void	G_TeamCommand( team_t team, char *cmd );
468 void	G_KillBox (gentity_t *ent);
469 gentity_t *G_Find (gentity_t *from, int fieldofs, const char *match);
470 gentity_t *G_PickTarget (char *targetname);
471 void	G_UseTargets (gentity_t *ent, gentity_t *activator);
472 void	G_SetMovedir ( vec3_t angles, vec3_t movedir);
473 
474 void	G_InitGentity( gentity_t *e );
475 gentity_t	*G_Spawn (void);
476 gentity_t *G_TempEntity( vec3_t origin, int event );
477 void	G_Sound( gentity_t *ent, int channel, int soundIndex );
478 void	G_FreeEntity( gentity_t *e );
479 qboolean	G_EntitiesFree( void );
480 
481 void	G_TouchTriggers (gentity_t *ent);
482 void	G_TouchSolids (gentity_t *ent);
483 
484 float	*tv (float x, float y, float z);
485 char	*vtos( const vec3_t v );
486 
487 float vectoyaw( const vec3_t vec );
488 
489 void G_AddPredictableEvent( gentity_t *ent, int event, int eventParm );
490 void G_AddEvent( gentity_t *ent, int event, int eventParm );
491 void G_SetOrigin( gentity_t *ent, vec3_t origin );
492 void AddRemap(const char *oldShader, const char *newShader, float timeOffset);
493 const char *BuildShaderStateConfig( void );
494 
495 //
496 // g_combat.c
497 //
498 qboolean CanDamage (gentity_t *targ, vec3_t origin);
499 void G_Damage (gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, vec3_t dir, vec3_t point, int damage, int dflags, int mod);
500 qboolean G_RadiusDamage (vec3_t origin, gentity_t *attacker, float damage, float radius, gentity_t *ignore, int mod);
501 int G_InvulnerabilityEffect( gentity_t *targ, vec3_t dir, vec3_t point, vec3_t impactpoint, vec3_t bouncedir );
502 void body_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath );
503 void TossClientItems( gentity_t *self );
504 #ifdef MISSIONPACK
505 void TossClientPersistantPowerups( gentity_t *self );
506 #endif
507 void TossClientCubes( gentity_t *self );
508 
509 // damage flags
510 #define DAMAGE_RADIUS				0x00000001	// damage was indirect
511 #define DAMAGE_NO_ARMOR				0x00000002	// armour does not protect from this damage
512 #define DAMAGE_NO_KNOCKBACK			0x00000004	// do not affect velocity, just view angles
513 #define DAMAGE_NO_PROTECTION		0x00000008  // armor, shields, invulnerability, and godmode have no effect
514 #ifdef MISSIONPACK
515 #define DAMAGE_NO_TEAM_PROTECTION	0x00000010  // armor, shields, invulnerability, and godmode have no effect
516 #endif
517 
518 //
519 // g_missile.c
520 //
521 void G_RunMissile( gentity_t *ent );
522 
523 gentity_t *fire_blaster (gentity_t *self, vec3_t start, vec3_t aimdir);
524 gentity_t *fire_plasma (gentity_t *self, vec3_t start, vec3_t aimdir);
525 gentity_t *fire_grenade (gentity_t *self, vec3_t start, vec3_t aimdir);
526 gentity_t *fire_rocket (gentity_t *self, vec3_t start, vec3_t dir);
527 gentity_t *fire_bfg (gentity_t *self, vec3_t start, vec3_t dir);
528 gentity_t *fire_grapple (gentity_t *self, vec3_t start, vec3_t dir);
529 #ifdef MISSIONPACK
530 gentity_t *fire_nail( gentity_t *self, vec3_t start, vec3_t forward, vec3_t right, vec3_t up );
531 gentity_t *fire_prox( gentity_t *self, vec3_t start, vec3_t aimdir );
532 #endif
533 
534 
535 //
536 // g_mover.c
537 //
538 void G_RunMover( gentity_t *ent );
539 void Touch_DoorTrigger( gentity_t *ent, gentity_t *other, trace_t *trace );
540 
541 //
542 // g_trigger.c
543 //
544 void trigger_teleporter_touch (gentity_t *self, gentity_t *other, trace_t *trace );
545 
546 
547 //
548 // g_misc.c
549 //
550 void TeleportPlayer( gentity_t *player, vec3_t origin, vec3_t angles );
551 #ifdef MISSIONPACK
552 void DropPortalSource( gentity_t *ent );
553 void DropPortalDestination( gentity_t *ent );
554 #endif
555 
556 
557 //
558 // g_weapon.c
559 //
560 qboolean LogAccuracyHit( gentity_t *target, gentity_t *attacker );
561 void CalcMuzzlePoint ( gentity_t *ent, vec3_t forward, vec3_t right, vec3_t up, vec3_t muzzlePoint );
562 void SnapVectorTowards( vec3_t v, vec3_t to );
563 qboolean CheckGauntletAttack( gentity_t *ent );
564 void Weapon_HookFree (gentity_t *ent);
565 void Weapon_HookThink (gentity_t *ent);
566 
567 
568 //
569 // g_client.c
570 //
571 team_t TeamCount( int ignoreClientNum, int team );
572 int TeamLeader( int team );
573 team_t PickTeam( int ignoreClientNum );
574 void SetClientViewAngle( gentity_t *ent, vec3_t angle );
575 gentity_t *SelectSpawnPoint ( vec3_t avoidPoint, vec3_t origin, vec3_t angles );
576 void CopyToBodyQue( gentity_t *ent );
577 void respawn (gentity_t *ent);
578 void BeginIntermission (void);
579 void InitClientPersistant (gclient_t *client);
580 void InitClientResp (gclient_t *client);
581 void InitBodyQue (void);
582 void ClientSpawn( gentity_t *ent );
583 void player_die (gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod);
584 void AddScore( gentity_t *ent, vec3_t origin, int score );
585 void CalculateRanks( void );
586 qboolean SpotWouldTelefrag( gentity_t *spot );
587 
588 //
589 // g_svcmds.c
590 //
591 qboolean	ConsoleCommand( void );
592 void G_ProcessIPBans(void);
593 qboolean G_FilterPacket (char *from);
594 
595 //
596 // g_weapon.c
597 //
598 void FireWeapon( gentity_t *ent );
599 #ifdef MISSIONPACK
600 void G_StartKamikaze( gentity_t *ent );
601 #endif
602 
603 //
604 // p_hud.c
605 //
606 void MoveClientToIntermission (gentity_t *client);
607 void G_SetStats (gentity_t *ent);
608 void DeathmatchScoreboardMessage (gentity_t *client);
609 
610 //
611 // g_cmds.c
612 //
613 
614 //
615 // g_pweapon.c
616 //
617 
618 
619 //
620 // g_main.c
621 //
622 void FindIntermissionPoint( void );
623 void SetLeader(int team, int client);
624 void CheckTeamLeader( int team );
625 void G_RunThink (gentity_t *ent);
626 void QDECL G_LogPrintf( const char *fmt, ... );
627 void SendScoreboardMessageToAllClients( void );
628 void QDECL G_Printf( const char *fmt, ... );
629 void QDECL G_Error( const char *fmt, ... );
630 
631 //
632 // g_client.c
633 //
634 char *ClientConnect( int clientNum, qboolean firstTime, qboolean isBot );
635 void ClientUserinfoChanged( int clientNum );
636 void ClientDisconnect( int clientNum );
637 void ClientBegin( int clientNum );
638 void ClientCommand( int clientNum );
639 
640 //
641 // g_active.c
642 //
643 void ClientThink( int clientNum );
644 void ClientEndFrame( gentity_t *ent );
645 void G_RunClient( gentity_t *ent );
646 
647 //
648 // g_team.c
649 //
650 qboolean OnSameTeam( gentity_t *ent1, gentity_t *ent2 );
651 void Team_CheckDroppedItem( gentity_t *dropped );
652 qboolean CheckObeliskAttack( gentity_t *obelisk, gentity_t *attacker );
653 
654 //
655 // g_mem.c
656 //
657 void *G_Alloc( int size );
658 void G_InitMemory( void );
659 void Svcmd_GameMem_f( void );
660 
661 //
662 // g_session.c
663 //
664 void G_ReadSessionData( gclient_t *client );
665 void G_InitSessionData( gclient_t *client, char *userinfo );
666 
667 void G_InitWorldSession( void );
668 void G_WriteSessionData( void );
669 
670 //
671 // g_arenas.c
672 //
673 void UpdateTournamentInfo( void );
674 void SpawnModelsOnVictoryPads( void );
675 void Svcmd_AbortPodium_f( void );
676 
677 //
678 // g_bot.c
679 //
680 void G_InitBots( qboolean restart );
681 char *G_GetBotInfoByNumber( int num );
682 char *G_GetBotInfoByName( const char *name );
683 void G_CheckBotSpawn( void );
684 void G_RemoveQueuedBotBegin( int clientNum );
685 qboolean G_BotConnect( int clientNum, qboolean restart );
686 void Svcmd_AddBot_f( void );
687 void Svcmd_BotList_f( void );
688 void BotInterbreedEndMatch( void );
689 
690 // ai_main.c
691 #define MAX_FILEPATH			144
692 
693 //bot settings
694 typedef struct bot_settings_s
695 {
696 	char characterfile[MAX_FILEPATH];
697 	float skill;
698 	char team[MAX_FILEPATH];
699 } bot_settings_t;
700 
701 int BotAISetup( int restart );
702 int BotAIShutdown( int restart );
703 int BotAILoadMap( int restart );
704 int BotAISetupClient(int client, struct bot_settings_s *settings, qboolean restart);
705 int BotAIShutdownClient( int client, qboolean restart );
706 int BotAIStartFrame( int time );
707 void BotTestAAS(vec3_t origin);
708 
709 #include "g_team.h" // teamplay specific stuff
710 
711 
712 extern	level_locals_t	level;
713 extern	gentity_t		g_entities[MAX_GENTITIES];
714 
715 #define	FOFS(x) ((size_t)&(((gentity_t *)0)->x))
716 
717 extern	vmCvar_t	g_gametype;
718 extern	vmCvar_t	g_dedicated;
719 extern	vmCvar_t	g_cheats;
720 extern	vmCvar_t	g_maxclients;			// allow this many total, including spectators
721 extern	vmCvar_t	g_maxGameClients;		// allow this many active
722 extern	vmCvar_t	g_restarted;
723 
724 extern	vmCvar_t	g_dmflags;
725 extern	vmCvar_t	g_fraglimit;
726 extern	vmCvar_t	g_timelimit;
727 extern	vmCvar_t	g_capturelimit;
728 extern	vmCvar_t	g_friendlyFire;
729 extern	vmCvar_t	g_password;
730 extern	vmCvar_t	g_needpass;
731 extern	vmCvar_t	g_gravity;
732 extern	vmCvar_t	g_speed;
733 extern	vmCvar_t	g_knockback;
734 extern	vmCvar_t	g_quadfactor;
735 extern	vmCvar_t	g_forcerespawn;
736 extern	vmCvar_t	g_inactivity;
737 extern	vmCvar_t	g_debugMove;
738 extern	vmCvar_t	g_debugAlloc;
739 extern	vmCvar_t	g_debugDamage;
740 extern	vmCvar_t	g_weaponRespawn;
741 extern	vmCvar_t	g_weaponTeamRespawn;
742 extern	vmCvar_t	g_synchronousClients;
743 extern	vmCvar_t	g_motd;
744 extern	vmCvar_t	g_warmup;
745 extern	vmCvar_t	g_doWarmup;
746 extern	vmCvar_t	g_blood;
747 extern	vmCvar_t	g_allowVote;
748 extern	vmCvar_t	g_teamAutoJoin;
749 extern	vmCvar_t	g_teamForceBalance;
750 extern	vmCvar_t	g_banIPs;
751 extern	vmCvar_t	g_filterBan;
752 extern	vmCvar_t	g_obeliskHealth;
753 extern	vmCvar_t	g_obeliskRegenPeriod;
754 extern	vmCvar_t	g_obeliskRegenAmount;
755 extern	vmCvar_t	g_obeliskRespawnDelay;
756 extern	vmCvar_t	g_cubeTimeout;
757 extern	vmCvar_t	g_redteam;
758 extern	vmCvar_t	g_blueteam;
759 extern	vmCvar_t	g_smoothClients;
760 extern	vmCvar_t	pmove_fixed;
761 extern	vmCvar_t	pmove_msec;
762 extern	vmCvar_t	g_rankings;
763 extern	vmCvar_t	g_enableDust;
764 extern	vmCvar_t	g_enableBreath;
765 extern	vmCvar_t	g_singlePlayer;
766 extern	vmCvar_t	g_proxMineTimeout;
767 
768 void	trap_Printf( const char *fmt );
769 void	trap_Error( const char *fmt );
770 int		trap_Milliseconds( void );
771 int		trap_Argc( void );
772 void	trap_Argv( int n, char *buffer, int bufferLength );
773 void	trap_Args( char *buffer, int bufferLength );
774 int		trap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode );
775 void	trap_FS_Read( void *buffer, int len, fileHandle_t f );
776 void	trap_FS_Write( const void *buffer, int len, fileHandle_t f );
777 void	trap_FS_FCloseFile( fileHandle_t f );
778 int		trap_FS_GetFileList( const char *path, const char *extension, char *listbuf, int bufsize );
779 int		trap_FS_Seek( fileHandle_t f, long offset, int origin ); // fsOrigin_t
780 void	trap_SendConsoleCommand( int exec_when, const char *text );
781 void	trap_Cvar_Register( vmCvar_t *cvar, const char *var_name, const char *value, int flags );
782 void	trap_Cvar_Update( vmCvar_t *cvar );
783 void	trap_Cvar_Set( const char *var_name, const char *value );
784 int		trap_Cvar_VariableIntegerValue( const char *var_name );
785 float	trap_Cvar_VariableValue( const char *var_name );
786 void	trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize );
787 void	trap_LocateGameData( gentity_t *gEnts, int numGEntities, int sizeofGEntity_t, playerState_t *gameClients, int sizeofGameClient );
788 void	trap_DropClient( int clientNum, const char *reason );
789 void	trap_SendServerCommand( int clientNum, const char *text );
790 void	trap_SetConfigstring( int num, const char *string );
791 void	trap_GetConfigstring( int num, char *buffer, int bufferSize );
792 void	trap_GetUserinfo( int num, char *buffer, int bufferSize );
793 void	trap_SetUserinfo( int num, const char *buffer );
794 void	trap_GetServerinfo( char *buffer, int bufferSize );
795 void	trap_SetBrushModel( gentity_t *ent, const char *name );
796 void	trap_Trace( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentmask );
797 int		trap_PointContents( const vec3_t point, int passEntityNum );
798 qboolean trap_InPVS( const vec3_t p1, const vec3_t p2 );
799 qboolean trap_InPVSIgnorePortals( const vec3_t p1, const vec3_t p2 );
800 void	trap_AdjustAreaPortalState( gentity_t *ent, qboolean open );
801 qboolean trap_AreasConnected( int area1, int area2 );
802 void	trap_LinkEntity( gentity_t *ent );
803 void	trap_UnlinkEntity( gentity_t *ent );
804 int		trap_EntitiesInBox( const vec3_t mins, const vec3_t maxs, int *entityList, int maxcount );
805 qboolean trap_EntityContact( const vec3_t mins, const vec3_t maxs, const gentity_t *ent );
806 int		trap_BotAllocateClient( void );
807 void	trap_BotFreeClient( int clientNum );
808 void	trap_GetUsercmd( int clientNum, usercmd_t *cmd );
809 qboolean	trap_GetEntityToken( char *buffer, int bufferSize );
810 
811 int		trap_DebugPolygonCreate(int color, int numPoints, vec3_t *points);
812 void	trap_DebugPolygonDelete(int id);
813 
814 int		trap_BotLibSetup( void );
815 int		trap_BotLibShutdown( void );
816 int		trap_BotLibVarSet(char *var_name, char *value);
817 int		trap_BotLibVarGet(char *var_name, char *value, int size);
818 int		trap_BotLibDefine(char *string);
819 int		trap_BotLibStartFrame(float time);
820 int		trap_BotLibLoadMap(const char *mapname);
821 int		trap_BotLibUpdateEntity(int ent, void /* struct bot_updateentity_s */ *bue);
822 int		trap_BotLibTest(int parm0, char *parm1, vec3_t parm2, vec3_t parm3);
823 
824 int		trap_BotGetSnapshotEntity( int clientNum, int sequence );
825 int		trap_BotGetServerCommand(int clientNum, char *message, int size);
826 void	trap_BotUserCommand(int client, usercmd_t *ucmd);
827 
828 int		trap_AAS_BBoxAreas(vec3_t absmins, vec3_t absmaxs, int *areas, int maxareas);
829 int		trap_AAS_AreaInfo( int areanum, void /* struct aas_areainfo_s */ *info );
830 void	trap_AAS_EntityInfo(int entnum, void /* struct aas_entityinfo_s */ *info);
831 
832 int		trap_AAS_Initialized(void);
833 void	trap_AAS_PresenceTypeBoundingBox(int presencetype, vec3_t mins, vec3_t maxs);
834 float	trap_AAS_Time(void);
835 
836 int		trap_AAS_PointAreaNum(vec3_t point);
837 int		trap_AAS_PointReachabilityAreaIndex(vec3_t point);
838 int		trap_AAS_TraceAreas(vec3_t start, vec3_t end, int *areas, vec3_t *points, int maxareas);
839 
840 int		trap_AAS_PointContents(vec3_t point);
841 int		trap_AAS_NextBSPEntity(int ent);
842 int		trap_AAS_ValueForBSPEpairKey(int ent, char *key, char *value, int size);
843 int		trap_AAS_VectorForBSPEpairKey(int ent, char *key, vec3_t v);
844 int		trap_AAS_FloatForBSPEpairKey(int ent, char *key, float *value);
845 int		trap_AAS_IntForBSPEpairKey(int ent, char *key, int *value);
846 
847 int		trap_AAS_AreaReachability(int areanum);
848 
849 int		trap_AAS_AreaTravelTimeToGoalArea(int areanum, vec3_t origin, int goalareanum, int travelflags);
850 int		trap_AAS_EnableRoutingArea( int areanum, int enable );
851 int		trap_AAS_PredictRoute(void /*struct aas_predictroute_s*/ *route, int areanum, vec3_t origin,
852 							int goalareanum, int travelflags, int maxareas, int maxtime,
853 							int stopevent, int stopcontents, int stoptfl, int stopareanum);
854 
855 int		trap_AAS_AlternativeRouteGoals(vec3_t start, int startareanum, vec3_t goal, int goalareanum, int travelflags,
856 										void /*struct aas_altroutegoal_s*/ *altroutegoals, int maxaltroutegoals,
857 										int type);
858 int		trap_AAS_Swimming(vec3_t origin);
859 int		trap_AAS_PredictClientMovement(void /* aas_clientmove_s */ *move, int entnum, vec3_t origin, int presencetype, int onground, vec3_t velocity, vec3_t cmdmove, int cmdframes, int maxframes, float frametime, int stopevent, int stopareanum, int visualize);
860 
861 
862 void	trap_EA_Say(int client, char *str);
863 void	trap_EA_SayTeam(int client, char *str);
864 void	trap_EA_Command(int client, char *command);
865 
866 void	trap_EA_Action(int client, int action);
867 void	trap_EA_Gesture(int client);
868 void	trap_EA_Talk(int client);
869 void	trap_EA_Attack(int client);
870 void	trap_EA_Use(int client);
871 void	trap_EA_Respawn(int client);
872 void	trap_EA_Crouch(int client);
873 void	trap_EA_MoveUp(int client);
874 void	trap_EA_MoveDown(int client);
875 void	trap_EA_MoveForward(int client);
876 void	trap_EA_MoveBack(int client);
877 void	trap_EA_MoveLeft(int client);
878 void	trap_EA_MoveRight(int client);
879 void	trap_EA_SelectWeapon(int client, int weapon);
880 void	trap_EA_Jump(int client);
881 void	trap_EA_DelayedJump(int client);
882 void	trap_EA_Move(int client, vec3_t dir, float speed);
883 void	trap_EA_View(int client, vec3_t viewangles);
884 
885 void	trap_EA_EndRegular(int client, float thinktime);
886 void	trap_EA_GetInput(int client, float thinktime, void /* struct bot_input_s */ *input);
887 void	trap_EA_ResetInput(int client);
888 
889 
890 int		trap_BotLoadCharacter(char *charfile, float skill);
891 void	trap_BotFreeCharacter(int character);
892 float	trap_Characteristic_Float(int character, int index);
893 float	trap_Characteristic_BFloat(int character, int index, float min, float max);
894 int		trap_Characteristic_Integer(int character, int index);
895 int		trap_Characteristic_BInteger(int character, int index, int min, int max);
896 void	trap_Characteristic_String(int character, int index, char *buf, int size);
897 
898 int		trap_BotAllocChatState(void);
899 void	trap_BotFreeChatState(int handle);
900 void	trap_BotQueueConsoleMessage(int chatstate, int type, char *message);
901 void	trap_BotRemoveConsoleMessage(int chatstate, int handle);
902 int		trap_BotNextConsoleMessage(int chatstate, void /* struct bot_consolemessage_s */ *cm);
903 int		trap_BotNumConsoleMessages(int chatstate);
904 void	trap_BotInitialChat(int chatstate, char *type, int mcontext, char *var0, char *var1, char *var2, char *var3, char *var4, char *var5, char *var6, char *var7 );
905 int		trap_BotNumInitialChats(int chatstate, char *type);
906 int		trap_BotReplyChat(int chatstate, char *message, int mcontext, int vcontext, char *var0, char *var1, char *var2, char *var3, char *var4, char *var5, char *var6, char *var7 );
907 int		trap_BotChatLength(int chatstate);
908 void	trap_BotEnterChat(int chatstate, int client, int sendto);
909 void	trap_BotGetChatMessage(int chatstate, char *buf, int size);
910 int		trap_StringContains(char *str1, char *str2, int casesensitive);
911 int		trap_BotFindMatch(char *str, void /* struct bot_match_s */ *match, unsigned long int context);
912 void	trap_BotMatchVariable(void /* struct bot_match_s */ *match, int variable, char *buf, int size);
913 void	trap_UnifyWhiteSpaces(char *string);
914 void	trap_BotReplaceSynonyms(char *string, unsigned long int context);
915 int		trap_BotLoadChatFile(int chatstate, char *chatfile, char *chatname);
916 void	trap_BotSetChatGender(int chatstate, int gender);
917 void	trap_BotSetChatName(int chatstate, char *name, int client);
918 void	trap_BotResetGoalState(int goalstate);
919 void	trap_BotRemoveFromAvoidGoals(int goalstate, int number);
920 void	trap_BotResetAvoidGoals(int goalstate);
921 void	trap_BotPushGoal(int goalstate, void /* struct bot_goal_s */ *goal);
922 void	trap_BotPopGoal(int goalstate);
923 void	trap_BotEmptyGoalStack(int goalstate);
924 void	trap_BotDumpAvoidGoals(int goalstate);
925 void	trap_BotDumpGoalStack(int goalstate);
926 void	trap_BotGoalName(int number, char *name, int size);
927 int		trap_BotGetTopGoal(int goalstate, void /* struct bot_goal_s */ *goal);
928 int		trap_BotGetSecondGoal(int goalstate, void /* struct bot_goal_s */ *goal);
929 int		trap_BotChooseLTGItem(int goalstate, vec3_t origin, int *inventory, int travelflags);
930 int		trap_BotChooseNBGItem(int goalstate, vec3_t origin, int *inventory, int travelflags, void /* struct bot_goal_s */ *ltg, float maxtime);
931 int		trap_BotTouchingGoal(vec3_t origin, void /* struct bot_goal_s */ *goal);
932 int		trap_BotItemGoalInVisButNotVisible(int viewer, vec3_t eye, vec3_t viewangles, void /* struct bot_goal_s */ *goal);
933 int		trap_BotGetNextCampSpotGoal(int num, void /* struct bot_goal_s */ *goal);
934 int		trap_BotGetMapLocationGoal(char *name, void /* struct bot_goal_s */ *goal);
935 int		trap_BotGetLevelItemGoal(int index, char *classname, void /* struct bot_goal_s */ *goal);
936 float	trap_BotAvoidGoalTime(int goalstate, int number);
937 void	trap_BotSetAvoidGoalTime(int goalstate, int number, float avoidtime);
938 void	trap_BotInitLevelItems(void);
939 void	trap_BotUpdateEntityItems(void);
940 int		trap_BotLoadItemWeights(int goalstate, char *filename);
941 void	trap_BotFreeItemWeights(int goalstate);
942 void	trap_BotInterbreedGoalFuzzyLogic(int parent1, int parent2, int child);
943 void	trap_BotSaveGoalFuzzyLogic(int goalstate, char *filename);
944 void	trap_BotMutateGoalFuzzyLogic(int goalstate, float range);
945 int		trap_BotAllocGoalState(int state);
946 void	trap_BotFreeGoalState(int handle);
947 
948 void	trap_BotResetMoveState(int movestate);
949 void	trap_BotMoveToGoal(void /* struct bot_moveresult_s */ *result, int movestate, void /* struct bot_goal_s */ *goal, int travelflags);
950 int		trap_BotMoveInDirection(int movestate, vec3_t dir, float speed, int type);
951 void	trap_BotResetAvoidReach(int movestate);
952 void	trap_BotResetLastAvoidReach(int movestate);
953 int		trap_BotReachabilityArea(vec3_t origin, int testground);
954 int		trap_BotMovementViewTarget(int movestate, void /* struct bot_goal_s */ *goal, int travelflags, float lookahead, vec3_t target);
955 int		trap_BotPredictVisiblePosition(vec3_t origin, int areanum, void /* struct bot_goal_s */ *goal, int travelflags, vec3_t target);
956 int		trap_BotAllocMoveState(void);
957 void	trap_BotFreeMoveState(int handle);
958 void	trap_BotInitMoveState(int handle, void /* struct bot_initmove_s */ *initmove);
959 void	trap_BotAddAvoidSpot(int movestate, vec3_t origin, float radius, int type);
960 
961 int		trap_BotChooseBestFightWeapon(int weaponstate, int *inventory);
962 void	trap_BotGetWeaponInfo(int weaponstate, int weapon, void /* struct weaponinfo_s */ *weaponinfo);
963 int		trap_BotLoadWeaponWeights(int weaponstate, char *filename);
964 int		trap_BotAllocWeaponState(void);
965 void	trap_BotFreeWeaponState(int weaponstate);
966 void	trap_BotResetWeaponState(int weaponstate);
967 
968 int		trap_GeneticParentsAndChildSelection(int numranks, float *ranks, int *parent1, int *parent2, int *child);
969 
970 void	trap_SnapVector( float *v );
971 
972