// Copyright (C) 1999-2000 Id Software, Inc.
//
// q_shared.c -- stateless support routines that are included in each code dll

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <stdarg.h>
#include <string.h>

#include "sqlite3.h"

#define ID_INLINE

#ifdef WIN32
#	pragma warning(disable:4018)
#endif

#ifdef WIN32
#	undef ID_INLINE
#	define ID_INLINE __inline
#endif

#define LittleLong

typedef enum {qfalse, qtrue}	qboolean;
typedef unsigned char			byte;
typedef float					vec3_t[3];

#ifndef NULL
#define NULL ((void *)0)
#endif

#define DEBUG	0

#define MAXPRINTMSG			4096

// the game guarantees that no string from the network will ever
// exceed MAX_STRING_CHARS
#define	MAX_STRING_CHARS	1024	// max length of a string passed to Cmd_TokenizeString
#define	MAX_STRING_TOKENS	256		// max tokens resulting from Cmd_TokenizeString
#define	MAX_TOKEN_CHARS		1024	// max length of an individual token

#define	MAX_INFO_STRING		1024
#define	MAX_INFO_KEY		1024
#define	MAX_INFO_VALUE		1024

#define	BIG_INFO_STRING		8192  // used for system info key only
#define	BIG_INFO_KEY		8192
#define	BIG_INFO_VALUE		8192


#define	MAX_QPATH			64		// max length of a quake game pathname
#ifdef PATH_MAX
#define MAX_OSPATH			PATH_MAX
#else
#define	MAX_OSPATH			256		// max length of a filesystem pathname
#endif

#define	MAX_MAP_AREA_BYTES		32		// bit vector of area visibility

typedef int fileHandle_t;

#ifdef ERR_FATAL
#undef ERR_FATAL			// this is be defined in malloc.h
#endif

// parameters to the main Error routine
typedef enum {
	ERR_FATAL,					// exit the entire game with a popup window
	ERR_DROP,					// print to console and disconnect from game
	ERR_SERVERDISCONNECT,		// don't kill server
	ERR_DISCONNECT,				// client disconnected from the server
	ERR_NEED_CD					// pop up the need-cd dialog
} errorParm_t;

void Com_Error( errorParm_t level, const char *error, ... );
void Com_Printf( const char *text, ... );

void	Com_sprintf (char *dest, int size, const char *fmt, ...);
char	*va(char *format, ...);

// buffer size safe library replacements
void	Q_strncpyz( char *dest, const char *src, int destsize );
void	Q_strcat( char *dest, int size, const char *src );

int		Q_stricmpn (const char *s1, const char *s2, int n);
int		Q_strncmp (const char *s1, const char *s2, int n);
int		Q_stricmp (const char *s1, const char *s2);
void	Q_strcat( char *dest, int size, const char *src );

//
// key / value info strings
//
char *Info_ValueForKey( const char *s, const char *key );
void Info_RemoveKey( char *s, const char *key );
void Info_RemoveKey_big( char *s, const char *key );
void Info_SetValueForKey( char *s, const char *key, const char *value );
void Info_SetValueForKey_Big( char *s, const char *key, const char *value );
qboolean Info_Validate( const char *s );
void Info_NextPair( const char **s, char *key, char *value );


/*
========================================================================

  ELEMENTS COMMUNICATED ACROSS THE NET

========================================================================
*/

#define	ANGLE2SHORT(x)	((int)((x)*65536/360) & 65535)
#define	SHORT2ANGLE(x)	((x)*(360.0/65536))

#define	SNAPFLAG_RATE_DELAYED	1
#define	SNAPFLAG_NOT_ACTIVE		2	// snapshot used during connection and for zombies
#define SNAPFLAG_SERVERCOUNT	4	// toggled every map_restart so transitions can be detected

//
// per-level limits
//
#define	MAX_CLIENTS			64		// absolute limit
#define MAX_LOCATIONS		64

#define	GENTITYNUM_BITS		10		// don't need to send any more
#define	MAX_GENTITIES		(1<<GENTITYNUM_BITS)

// entitynums are communicated with GENTITY_BITS, so any reserved
// values that are going to be communcated over the net need to
// also be in this range
#define	ENTITYNUM_NONE		(MAX_GENTITIES-1)
#define	ENTITYNUM_WORLD		(MAX_GENTITIES-2)
#define	ENTITYNUM_MAX_NORMAL	(MAX_GENTITIES-2)


#define	MAX_MODELS			256		// these are sent over the net as 8 bits
#define	MAX_SOUNDS			256		// so they cannot be blindly increased

#define	MAX_CONFIGSTRINGS	2048

// these are the only configstrings that the system reserves, all the
// other ones are strictly for servergame to clientgame communication
#define	CS_SERVERINFO		0		// an info string with all the serverinfo cvars
#define	CS_SYSTEMINFO		1		// an info string for server system to client system configuration (timescale, etc)

#define	RESERVED_CONFIGSTRINGS	2	// game can't modify below this, only the system can

#define	MAX_GAMESTATE_CHARS	16000
typedef struct {
	int			stringOffsets[MAX_CONFIGSTRINGS];
	char		stringData[MAX_GAMESTATE_CHARS];
	int			dataCount;
} gameState_t;

typedef enum {
	GS_INITIALIZE = -1,
	GS_PLAYING,
	GS_WARMUP_COUNTDOWN,
	GS_WARMUP,
	GS_INTERMISSION,
	GS_WAITING_FOR_PLAYERS,
	GS_RESET
} gamestate_t;

//=========================================================

// bit field limits
#define	MAX_STATS				16
#define	MAX_PERSISTANT			16
#define	MAX_POWERUPS			16
#define	MAX_WEAPONS				64		

#define	MAX_PS_EVENTS			2

#define PS_PMOVEFRAMECOUNTBITS	6

#define MAX_EVENTS 4

typedef enum {
	TEAM_FREE,
	TEAM_RED,
	TEAM_BLUE,
	TEAM_SPECTATOR,

	TEAM_NUM_TEAMS
} team_t;

typedef enum {
	PERS_SCORE,                     // !!! MUST NOT CHANGE, SERVER AND GAME BOTH REFERENCE !!!
	PERS_HITS,                      // total points damage inflicted so damage beeps can sound on change
	PERS_RANK,
	PERS_TEAM,
	PERS_SPAWN_COUNT,               // incremented every respawn
	PERS_REWARD_COUNT,              // incremented for each reward sound
	PERS_REWARD,                    // a reward_t
	PERS_ATTACKER,                  // clientnum of last damage inflicter
	PERS_KILLED,                    // count of the number of times you died
	// these were added for single player awards tracking
	PERS_RESPAWNS_LEFT,             // DHM - Nerve :: number of remaining respawns

	PERS_ACCURACY_SHOTS,
	PERS_ACCURACY_HITS,

	// Rafael - mg42		// (SA) I don't understand these here.  can someone explain?
	PERS_HWEAPON_USE,
	// Rafael wolfkick
	PERS_WOLFKICK
} persEnum_t;

typedef struct cplane_s {
	vec3_t normal;
	float dist;
	byte type;              // for fast side tests: 0,1,2 = axial, 3 = nonaxial
	byte signbits;          // signx + (signy<<1) + (signz<<2), used as lookup during collision
	byte pad[2];
} cplane_t;

typedef struct {
	qboolean allsolid;      // if true, plane is not valid
	qboolean startsolid;    // if true, the initial point was in a solid area
	float fraction;         // time completed, 1.0 = didn't hit anything
	vec3_t endpos;          // final position
	cplane_t plane;         // surface normal at impact, transformed to world space
	int surfaceFlags;           // surface hit
	int contents;           // contents on other side of surface hit
	int entityNum;          // entity the contacted sirface is a part of
} trace_t;

typedef enum
{
	AISTATE_NULL = -1,
	AISTATE_RELAXED,
	AISTATE_QUERY,
	AISTATE_ALERT,
	AISTATE_COMBAT,
	MAX_AISTATES
} aistateEnum_t;

// playerState_t is the information needed by both the client and server
// to predict player motion and actions
// nothing outside of pmove should modify these, or some degree of prediction error
// will occur

// you can't add anything to this without modifying the code in msg.c

// playerState_t is a full superset of entityState_t as it is used by players,
// so if a playerState_t is transmitted, the entityState_t can be fully derived
// from it.
typedef struct playerState_s {
	int commandTime;            // cmd->serverTime of last executed command
	int pm_type;
	int bobCycle;               // for view bobbing and footstep generation
	int pm_flags;               // ducked, jump_held, etc
	int pm_time;

	vec3_t origin;
	vec3_t velocity;
	int weaponTime;
	int weaponDelay;            // for weapons that don't fire immediately when 'fire' is hit (grenades, venom, ...)
	int grenadeTimeLeft;            // for delayed grenade throwing.  this is set to a #define for grenade
									// lifetime when the attack button goes down, then when attack is released
									// this is the amount of time left before the grenade goes off (or if it
									// gets to 0 while in players hand, it explodes)


	int gravity;
	float leanf;                // amount of 'lean' when player is looking around corner //----(SA)	added

	int speed;
	int delta_angles[3];            // add to command angles to get view direction
									// changed by spawns, rotating objects, and teleporters

	int groundEntityNum;        // ENTITYNUM_NONE = in air

	int legsTimer;              // don't change low priority animations until this runs out
	int legsAnim;               // mask off ANIM_TOGGLEBIT

	int torsoTimer;             // don't change low priority animations until this runs out
	int torsoAnim;              // mask off ANIM_TOGGLEBIT

	int movementDir;            // a number 0 to 7 that represents the reletive angle
								// of movement to the view angle (axial and diagonals)
								// when at rest, the value will remain unchanged
								// used to twist the legs during strafing



	int eFlags;                 // copied to entityState_t->eFlags

	int eventSequence;          // pmove generated events
	int events[MAX_EVENTS];
	int eventParms[MAX_EVENTS];
	int oldEventSequence;           // so we can see which events have been added since we last converted to entityState_t

	int externalEvent;          // events set on player from another source
	int externalEventParm;
	int externalEventTime;

	int clientNum;              // ranges from 0 to MAX_CLIENTS-1

	// weapon info
	int weapon;                 // copied to entityState_t->weapon
	int weaponstate;

	// item info
	int item;

	vec3_t viewangles;          // for fixed views
	int viewheight;

	// damage feedback
	int damageEvent;            // when it changes, latch the other parms
	int damageYaw;
	int damagePitch;
	int damageCount;

	int stats[MAX_STATS];
	int persistant[MAX_PERSISTANT];         // stats that aren't cleared on death
	int powerups[MAX_POWERUPS];         // level.time that the powerup runs out
	int ammo[MAX_WEAPONS];              // total amount of ammo
	int ammoclip[MAX_WEAPONS];          // ammo in clip
	int holdable[16];
	int holding;                        // the current item in holdable[] that is selected (held)
	
	int weapons[MAX_WEAPONS / ( sizeof( int ) * 8 )];   // 64 bits for weapons held
	//int weapons[2];

	// Ridah, allow for individual bounding boxes

	vec3_t mins, maxs;

	float crouchMaxZ;
	float crouchViewHeight, standViewHeight, deadViewHeight;
	// variable movement speed
	float runSpeedScale, sprintSpeedScale, crouchSpeedScale;
	// done.

	// Ridah, view locking for mg42
	int viewlocked;
	int viewlocked_entNum;

	// Ridah, need this to fix friction problems with slow zombie's whereby
	// the friction prevents them from accelerating to their full potential
	float friction;

	// Ridah, AI character id is used for weapon association
	int aiChar;
	int teamNum;

	// Rafael
	int gunfx;

	// RF, burning effect is required for view blending effect
	int onFireStart;

	int serverCursorHint;               // what type of cursor hint the server is dictating
	int serverCursorHintVal;            // a value (0-255) associated with the above

	trace_t serverCursorHintTrace;      // not communicated over net, but used to store the current server-side cursorhint trace

	// ----------------------------------------------------------------------
	// not communicated over the net at all
	// FIXME: this doesn't get saved between predicted frames on the clients-side (cg.predictedPlayerState)
	// So to use persistent variables here, which don't need to come from the server,
	// we could use a marker variable, and use that to store everything after it
	// before we read in the new values for the predictedPlayerState, then restore them
	// after copying the structure recieved from the server.

	// (SA) yeah.  this is causing me a little bit of trouble too.  can we go ahead with the above suggestion or find an alternative?

	int ping;                   // server to game info for scoreboard
	int pmove_framecount;           // FIXME: don't transmit over the network
	int entityEventSequence;

	int sprintTime;
	int sprintExertTime;

	// JPW NERVE -- value for all multiplayer classes with regenerating "class weapons" -- ie LT artillery, medic medpack, engineer build points, etc
	int classWeaponTime;
	int jumpTime;         // used in MP to prevent jump accel
	// jpw

	int weapAnimTimer;              // don't change low priority animations until this runs out		//----(SA)	added
	int weapAnim;               // mask off ANIM_TOGGLEBIT										//----(SA)	added

	qboolean releasedFire;

	float aimSpreadScaleFloat;          // (SA) the server-side aimspreadscale that lets it track finer changes but still only
										// transmit the 8bit int to the client
	int aimSpreadScale;         // 0 - 255 increases with angular movement
	int lastFireTime;           // used by server to hold last firing frame briefly when randomly releasing trigger (AI)

	int quickGrenTime;

	int leanStopDebounceTime;

//----(SA)	added

	// seems like heat and aimspread could be tied together somehow, however, they (appear to) change at different rates and
	// I can't currently see how to optimize this to one server->client transmission "weapstatus" value.
	int weapHeat[MAX_WEAPONS];          // some weapons can overheat.  this tracks (server-side) how hot each weapon currently is.
	int curWeapHeat;                    // value for the currently selected weapon (for transmission to client)

	int venomTime;          //----(SA)	added
//----(SA)	end

	aistateEnum_t aiState;

	int identifyClient;                 // NERVE - SMF

} playerState_t;

//===================================================================

// if entityState->solid == SOLID_BMODEL, modelindex is an inline model number
#define	SOLID_BMODEL	0xffffff

typedef enum {
	TR_STATIONARY,
	TR_INTERPOLATE,
	TR_LINEAR,
	TR_LINEAR_STOP,
	TR_LINEAR_STOP_BACK,
	TR_SINE,
	TR_GRAVITY,
	TR_GRAVITY_LOW,
	TR_GRAVITY_FLOAT,
	TR_GRAVITY_PAUSED,
	TR_ACCELERATE,
	TR_DECCELERATE
} trType_t;

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;

// entityState_t is the information conveyed from the server
// in an update message about entities that the client will
// need to render in some way
// Different eTypes may use the information in different ways
// The messages are delta compressed, so it doesn't really matter if
// the structure size is fairly large

typedef struct entityState_s {
	int number;             // entity index
	int eType;              // entityType_t
	int eFlags;

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

	int time;
	int time2;

	vec3_t origin;
	vec3_t origin2;

	vec3_t angles;
	vec3_t angles2;

	int otherEntityNum;     // shotgun sources, etc
	int otherEntityNum2;

	int groundEntityNum;        // -1 = in air

	int constantLight;      // r + (g<<8) + (b<<16) + (intensity<<24)
	int dl_intensity;       // used for coronas
	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

	// old style events, in for compatibility only
	int event;
	int eventParm;

	int eventSequence;      // pmove generated events
	int events[MAX_EVENTS];
	int eventParms[MAX_EVENTS];

	// 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
//	int		weapAnim;		// mask off ANIM_TOGGLEBIT	//----(SA)	removed (weap anims will be client-side only)

	int density;            // for particle effects

	int dmgFlags;           // to pass along additional information for damage effects for players/ Also used for cursorhints for non-player entities

	// Ridah
	int onFireStart, onFireEnd;

	int aiChar, teamNum;

	int effect1Time, effect2Time, effect3Time;

	aistateEnum_t aiState;

	int animMovetype;       // clients can't derive movetype of other clients for anim scripting system


} entityState_t;

typedef struct {
	int	warmup;
	int time;
} cg_t;

typedef enum {
	GT_FFA,
	GT_TOURNAMENT,
	GT_SINGLE_PLAYER,
	GT_TEAM,
	GT_CTF,
	GT_WOLF,
	GT_WOLF_STOPWATCH,
	GT_WOLF_CP,
	GT_WOLF_CPH,
	GT_MAX_GAME_TYPE
} gametype_t;

typedef struct {
	qboolean		infoValid;
	int				clientNum;
	team_t			team;
	char			name[MAX_QPATH];
} clientInfo_t;

typedef struct {
	gametype_t	gametype;
	float		timelimit;
	int			currentRound;
	float		nextTimeLimit;
	int			teamNum;
	int levelStartTime;
	clientInfo_t	clientinfo[MAX_CLIENTS];
	gamestate_t	gamestate;
} cgs_t;

typedef enum {
	PM_NORMAL,      // can accelerate and turn
	PM_NOCLIP,      // noclip movement
	PM_SPECTATOR,   // still run into walls
	PM_DEAD,        // no acceleration or turning, but free falling
	PM_FREEZE,      // stuck in place with no control
	PM_INTERMISSION // no movement or status bar
} pmtype_t;

// ========================================================================================

//
// config strings are a general means of communicating variable length strings
// from the server to all connected clients.
//

// CS_SERVERINFO and CS_SYSTEMINFO are defined in q_shared.h
//#define	CS_MUSIC				2
//#define	CS_MESSAGE				3		// from the map worldspawn's message field
//#define	CS_MOTD					4		// g_motd string for server message of the day
//#define	CS_WARMUP				5		// server time when the match will be restarted
//#define	CS_SCORES1				6
//#define	CS_SCORES2				7
//#define CS_VOTE_TIME			8
//#define CS_VOTE_STRING			9
//#define	CS_VOTE_YES				10
//#define	CS_VOTE_NO				11
//
//#define CS_TEAMVOTE_TIME		12
//#define CS_TEAMVOTE_STRING		14
//#define	CS_TEAMVOTE_YES			16
//#define	CS_TEAMVOTE_NO			18
//
//#define	CS_GAME_VERSION			20
//#define	CS_LEVEL_START_TIME		21		// so the timer only shows the current level
//#define	CS_INTERMISSION			22		// when 1, fraglimit/timelimit has been hit and intermission will start in a second or two
//#define CS_FLAGSTATUS			23		// string indicating flag status in CTF
//#define CS_SHADERSTATE			24
//#define CS_BOTINFO				25
//
//#define	CS_ITEMS				27		// string of 0's and 1's that tell which items are present
//
//#define	CS_MODELS				32
//#define	CS_SOUNDS				(CS_MODELS+MAX_MODELS)
//#define	CS_PLAYERS				(CS_SOUNDS+MAX_SOUNDS)
//#define CS_LOCATIONS			(CS_PLAYERS+MAX_CLIENTS)
//#define CS_PARTICLES			(CS_LOCATIONS+MAX_LOCATIONS) 
//
//#define CS_MAX					(CS_PARTICLES+MAX_LOCATIONS)
//
//#if (CS_MAX) > MAX_CONFIGSTRINGS
//#error overflow: (CS_MAX) > MAX_CONFIGSTRINGS
//#endif

//#define	CS_MUSIC				2
//#define	CS_MESSAGE				3		// from the map worldspawn's message field
//#define	CS_MOTD					4		// g_motd string for server message of the day
//#define	CS_WARMUP				5		// server time when the match will be restarted
//#define	CS_SCORES1				6
//#define	CS_SCORES2				7
//#define CS_VOTE_TIME			8
//#define CS_VOTE_STRING			9
//#define	CS_VOTE_YES				10
//#define	CS_VOTE_NO				11
//
//#define CS_TEAMVOTE_TIME		12
//#define CS_TEAMVOTE_STRING		14
//#define	CS_TEAMVOTE_YES			16
//#define	CS_TEAMVOTE_NO			18
//
//#define	CS_GAME_VERSION			20
//#define	CS_LEVEL_START_TIME		21		// so the timer only shows the current level
//#define	CS_INTERMISSION			22		// when 1, fraglimit/timelimit has been hit and intermission will start in a second or two
//#define CS_FLAGSTATUS			23		// string indicating flag status in CTF
//#define CS_SHADERSTATE			24
//#define CS_BOTINFO				25
//
//#define	CS_ITEMS				27		// string of 0's and 1's that tell which items are present
//
//#define	CS_MODELS				64
//#define	CS_SOUNDS				(CS_MODELS+MAX_MODELS)
//#define	CS_PLAYERS				(CS_SOUNDS+MAX_SOUNDS)
//#define CS_LOCATIONS			(CS_PLAYERS+MAX_CLIENTS)
//#define CS_PARTICLES			(CS_LOCATIONS+MAX_LOCATIONS) 
//
//#define CS_MAX					(CS_PARTICLES+MAX_LOCATIONS)
//
//#if (CS_MAX) > MAX_CONFIGSTRINGS
//#error overflow: (CS_MAX) > MAX_CONFIGSTRINGS
//#endif

#define CS_MUSIC                2
#define CS_MESSAGE              3       // from the map worldspawn's message field
#define CS_MOTD                 4       // g_motd string for server message of the day
#define CS_WARMUP               5       // server time when the match will be restarted
#define CS_SCORES1              6
#define CS_SCORES2              7
#define CS_VOTE_TIME            8
#define CS_VOTE_STRING          9
#define CS_VOTE_YES             10
#define CS_VOTE_NO              11
#define CS_GAME_VERSION         12
#define CS_LEVEL_START_TIME     13      // so the timer only shows the current level
#define CS_INTERMISSION         14      // when 1, intermission will start in a second or two
// DHM - Nerve :: Wolf Multiplayer information
#define CS_MULTI_INFO           15
#define CS_MULTI_MAPWINNER      16
#define CS_MULTI_MAPDESC        17
#define CS_MULTI_OBJECTIVE1     18
#define CS_MULTI_OBJECTIVE2     19
#define CS_MULTI_OBJECTIVE3     20
#define CS_MULTI_OBJECTIVE4     21
#define CS_MULTI_OBJECTIVE5     22
#define CS_MULTI_OBJECTIVE6     23

#define CS_MULTI_OBJ1_STATUS    24
#define CS_MULTI_OBJ2_STATUS    25
#define CS_MULTI_OBJ3_STATUS    26
#define CS_MULTI_OBJ4_STATUS    27
#define CS_MULTI_OBJ5_STATUS    28
#define CS_MULTI_OBJ6_STATUS    29

// dhm
#define CS_SHADERSTATE          30
#define CS_ITEMS                31      // string of 0's and 1's that tell which items are present

#define CS_SCREENFADE           32      // Ridah, used to tell clients to fade their screen to black/normal
#define CS_FOGVARS              33      //----(SA) used for saving the current state/settings of the fog
#define CS_SKYBOXORG            34      // this is where we should view the skybox from
#define CS_TARGETEFFECT         35      //----(SA)

#define CS_WOLFINFO             36      // NERVE - SMF

#define CS_MODELS               64
#define CS_SOUNDS               ( CS_MODELS + MAX_MODELS )
#define CS_PLAYERS              ( CS_SOUNDS + MAX_SOUNDS )
#define CS_LOCATIONS            ( CS_PLAYERS + MAX_CLIENTS )
#define CS_PARTICLES            ( CS_LOCATIONS + MAX_LOCATIONS )
// JPW NERVE -- for spawnpoint selection
#define CS_MULTI_SPAWNTARGETS   ( CS_PARTICLES + MAX_PARTICLES_AREAS )
#define CS_OID_TRIGGERS         ( CS_MULTI_SPAWNTARGETS + MAX_MULTI_SPAWNTARGETS )
// jpw
#define CS_DLIGHTS              ( CS_OID_TRIGGERS + MAX_OID_TRIGGERS )
#define CS_CLIPBOARDS           ( CS_DLIGHTS + MAX_DLIGHT_CONFIGSTRINGS )
#define CS_SPLINES              ( CS_CLIPBOARDS + MAX_CLIPBOARD_CONFIGSTRINGS )
#define CS_TAGCONNECTS          ( CS_SPLINES + MAX_SPLINE_CONFIGSTRINGS )

#define CS_MAX                  ( CS_TAGCONNECTS + MAX_TAGCONNECTS )

#if ( CS_MAX ) > MAX_CONFIGSTRINGS
#error overflow: (CS_MAX) > MAX_CONFIGSTRINGS
#endif


typedef enum { GENDER_MALE, GENDER_FEMALE, GENDER_NEUTER } gender_t;

// entityState_t->event values
// entity events are for effects that take place reletive
// to an existing entities origin.  Very network efficient.

// two bits at the top of the entityState->event field
// will be incremented with each change in the event so
// that an identical event started twice in a row can
// be distinguished.  And off the value with ~EV_EVENT_BITS
// to retrieve the actual event number
#define EV_EVENT_BIT1       0x00000100
#define EV_EVENT_BIT2       0x00000200
#define EV_EVENT_BITS       ( EV_EVENT_BIT1 | EV_EVENT_BIT2 )

#define	EVENT_VALID_MSEC	300

typedef enum {
	EV_NONE,
	EV_FOOTSTEP,
	EV_FOOTSTEP_METAL,
	EV_FOOTSTEP_WOOD,
	EV_FOOTSTEP_GRASS,
	EV_FOOTSTEP_GRAVEL,
	EV_FOOTSTEP_ROOF,
	EV_FOOTSTEP_SNOW,
	EV_FOOTSTEP_CARPET,
	EV_FOOTSPLASH,
	EV_FOOTWADE,
	EV_SWIM,
	EV_STEP_4,
	EV_STEP_8,
	EV_STEP_12,
	EV_STEP_16,
	EV_FALL_SHORT,
	EV_FALL_MEDIUM,
	EV_FALL_FAR,
	EV_FALL_NDIE,
	EV_FALL_DMG_10,
	EV_FALL_DMG_15,
	EV_FALL_DMG_25,
	EV_FALL_DMG_50,
	EV_JUMP_PAD,        
	EV_JUMP,
	EV_WATER_TOUCH, 
	EV_WATER_LEAVE,
	EV_WATER_UNDER, 
	EV_WATER_CLEAR, 
	EV_ITEM_PICKUP,         
	EV_ITEM_PICKUP_QUIET,   
	EV_GLOBAL_ITEM_PICKUP,  
	EV_NOITEM,
	EV_NOAMMO,
	EV_EMPTYCLIP,
	EV_FILL_CLIP,
	EV_MG42_FIXED, 
	EV_WEAP_OVERHEAT,
	EV_CHANGE_WEAPON,
	EV_FIRE_WEAPON,
	EV_FIRE_WEAPONB,
	EV_FIRE_WEAPON_LASTSHOT,
	EV_FIRE_QUICKGREN,  
	EV_NOFIRE_UNDERWATER,
	EV_FIRE_WEAPON_MG42,
	EV_USE_ITEM0,
	EV_USE_ITEM1,
	EV_USE_ITEM2,
	EV_USE_ITEM3,
	EV_USE_ITEM4,
	EV_USE_ITEM5,
	EV_USE_ITEM6,
	EV_USE_ITEM7,
	EV_USE_ITEM8,
	EV_USE_ITEM9,
	EV_USE_ITEM10,
	EV_USE_ITEM11,
	EV_USE_ITEM12,
	EV_USE_ITEM13,
	EV_USE_ITEM14,
	EV_USE_ITEM15,
	EV_ITEM_RESPAWN,
	EV_ITEM_POP,
	EV_PLAYER_TELEPORT_IN,
	EV_PLAYER_TELEPORT_OUT,
	EV_GRENADE_BOUNCE,     
	EV_GENERAL_SOUND,
	EV_GLOBAL_SOUND,      
	EV_GLOBAL_CLIENT_SOUND, 
	EV_BULLET_HIT_FLESH,
	EV_BULLET_HIT_WALL,
	EV_MISSILE_HIT,
	EV_MISSILE_MISS,
	EV_RAILTRAIL,
	EV_VENOM,
	EV_VENOMFULL,
	EV_BULLET,            
	EV_LOSE_HAT,           
	EV_GIB_HEAD, 
	EV_PAIN,
	EV_CROUCH_PAIN,
	EV_DEATH1,
	EV_DEATH2,
	EV_DEATH3,
	EV_OBITUARY,
	EV_STOPSTREAMINGSOUND,
	EV_POWERUP_QUAD,
	EV_POWERUP_BATTLESUIT,
	EV_POWERUP_REGEN,
	EV_GIB_PLAYER,
	EV_DEBUG_LINE,
	EV_STOPLOOPINGSOUND,
	EV_TAUNT,
	EV_SMOKE,
	EV_SPARKS,
	EV_SPARKS_ELECTRIC,
	EV_BATS,
	EV_BATS_UPDATEPOSITION,
	EV_BATS_DEATH,
	EV_EXPLODE,
	EV_EFFECT,
	EV_MORTAREFX,
	EV_SPINUP,
	EV_TESTID1,
	EV_TESTID2,
	EV_ENDTEST,
	EV_SNOW_ON,
	EV_SNOW_OFF,
	EV_MISSILE_MISS_SMALL,
	EV_MISSILE_MISS_LARGE,
	EV_WOLFKICK_HIT_FLESH,
	EV_WOLFKICK_HIT_WALL,
	EV_WOLFKICK_MISS,
	EV_SPIT_HIT,
	EV_SPIT_MISS,
	EV_SHARD,
	EV_JUNK,
	EV_EMITTER,
	EV_OILPARTICLES,
	EV_OILSLICK,
	EV_OILSLICKREMOVE,
	EV_MG42EFX,
	EV_FLAMEBARREL_BOUNCE,
	EV_FLAKGUN1,
	EV_FLAKGUN2,
	EV_FLAKGUN3,
	EV_FLAKGUN4,
	EV_EXERT1,
	EV_EXERT2,
	EV_EXERT3,
	EV_SNOWFLURRY,
	EV_CONCUSSIVE,
	EV_DUST,
	EV_RUMBLE_EFX,
	EV_GUNSPARKS,
	EV_FLAMETHROWER_EFFECT,
	EV_SNIPER_SOUND,
	EV_POPUP,
	EV_POPUPBOOK,
	EV_GIVEPAGE,
	EV_MG42BULLET_HIT_FLESH,
	EV_MG42BULLET_HIT_WALL,
	EV_MAX_EVENTS

} entity_event_t;

// means of death
typedef enum {
	MOD_UNKNOWN,
	MOD_SHOTGUN,
	MOD_GAUNTLET,
	MOD_MACHINEGUN,
	MOD_GRENADE,
	MOD_GRENADE_SPLASH,
	MOD_ROCKET,
	MOD_ROCKET_SPLASH,
	MOD_RAILGUN,
	MOD_LIGHTNING,
	MOD_BFG,
	MOD_BFG_SPLASH,

	MOD_KNIFE,
	MOD_KNIFE2,
	MOD_KNIFE_STEALTH,
	MOD_LUGER,
	MOD_COLT,
	MOD_MP40,
	MOD_THOMPSON,
	MOD_STEN,
	MOD_MAUSER,
	MOD_SNIPERRIFLE,
	MOD_GARAND,
	MOD_SNOOPERSCOPE,
	MOD_SILENCER,  
	MOD_AKIMBO,     
	MOD_BAR,    
	MOD_FG42,
	MOD_FG42SCOPE,
	MOD_PANZERFAUST,
	MOD_ROCKET_LAUNCHER,
	MOD_GRENADE_LAUNCHER,
	MOD_VENOM,
	MOD_VENOM_FULL,
	MOD_FLAMETHROWER,
	MOD_TESLA,
	MOD_SPEARGUN,
	MOD_SPEARGUN_CO2,
	MOD_GRENADE_PINEAPPLE,
	MOD_CROSS,

	MOD_MORTAR,
	MOD_MORTAR_SPLASH,

	MOD_KICKED,
	MOD_GRABBER,

	MOD_DYNAMITE,
	MOD_DYNAMITE_SPLASH,
	MOD_AIRSTRIKE, 
	MOD_SYRINGE,   
	MOD_AMMO,   
	MOD_ARTY,   

	MOD_WATER,
	MOD_SLIME,
	MOD_LAVA,
	MOD_CRUSH,
	MOD_TELEFRAG,
	MOD_FALLING,
	MOD_SUICIDE,
	MOD_TARGET_LASER,
	MOD_TRIGGER_HURT,
	MOD_GRAPPLE,
	MOD_EXPLOSIVE,
	MOD_POISONGAS,

	MOD_ZOMBIESPIT,
	MOD_ZOMBIESPIT_SPLASH,
	MOD_ZOMBIESPIRIT,
	MOD_ZOMBIESPIRIT_SPLASH,

	MOD_LOPER_LEAP,
	MOD_LOPER_GROUND,
	MOD_LOPER_HIT,

	MOD_LT_AMMO,
	MOD_LT_AIRSTRIKE,
	MOD_ENGINEER,
	MOD_MEDIC,

	MOD_BAT

} meansOfDeath_t;

//
// entityState_t->eType
//
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,             
	ET_CONCUSSIVE_TRIGGER,  
	ET_OID_TRIGGER,        
	ET_EXPLOSIVE_INDICATOR, 
	ET_EXPLOSIVE,       
	ET_EF_TESLA,
	ET_EF_SPOTLIGHT,
	ET_EFFECT3,
	ET_ALARMBOX,
	ET_CORONA,
	ET_TRAP,
	ET_GAMEMODEL,         
	ET_FOOTLOCKER,
	ET_FLAMEBARREL,
	ET_FP_PARTS,
	ET_FIRE_COLUMN,
	ET_FIRE_COLUMN_SMOKE,
	ET_RAMJET,
	ET_FLAMETHROWER_CHUNK,   
	ET_EXPLO_PART,
	ET_PROP,
	ET_BAT,
	ET_AI_EFFECT,
	ET_CAMERA,
	ET_MOVERSCALED,
	ET_CORPSE,         
	ET_SMOKER,  
	ET_TEMPHEAD,
	ET_MG42_BARREL,
	ET_EVENTS  

} entityType_t;

char *	COM_Parse( char **data_p );

char *	CopyString( const char *in );

int		Cmd_Argc( void );
char *	Cmd_Argv( int arg );
char *	Cmd_Args( void );
void	Cmd_TokenizeString( char *text );

void	Info_Print( const char *s );

