/*
Copyright (C) 1996-1997 Id Software, Inc.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/
// server.h

typedef struct
{
	int			maxclients;
	int			maxclientslimit;
	struct		client_s	*clients;		// [maxclients]
	int			serverflags;				// episode completion information
	qboolean	changelevel_issued;			// cleared when at SV_SpawnServer
} server_static_t;

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

typedef enum {ss_loading, ss_active} server_state_t;

typedef struct
{
	qboolean		active;							// false if only a net client

	qboolean		paused;
	qboolean		loadgame;						// handle connections specially

	double			time;
	
	int				lastcheck;						// used by PF_checkclient
	double			lastchecktime;
	
	char			name[64];						// map name
	char			modelname[64];					// maps/<name>.bsp, for model_precache[0]
	struct model_s 	*worldmodel;
	char			*model_precache[MAX_MODELS];	// NULL terminated
	struct model_s	*models[MAX_MODELS];
	char			*sound_precache[MAX_SOUNDS];	// NULL terminated
	char			*lightstyles[MAX_LIGHTSTYLES];
	int				num_edicts;
	int				max_edicts;
	edict_t			*edicts;						// can NOT be array indexed, because
													// edict_t is variable sized, but can
													// be used to reference the world ent
	server_state_t	state;							// some actions are only valid during load

	sizebuf_t		datagram;
	byte			datagram_buf[MAX_DATAGRAM];

	sizebuf_t		reliable_datagram;				// copied to all clients at end of frame
	byte			reliable_datagram_buf[MAX_DATAGRAM];

	sizebuf_t		signon;

	byte		signon_buf[MAX_MSGLEN-2]; //johnfitz -- was 8192, now uses MAX_MSGLEN

	unsigned		protocol;			//johnfitz
} server_t;


#define	NUM_PING_TIMES		16
#define	NUM_SPAWN_PARMS		16

typedef struct client_s
{
	qboolean	active;			// false = client is free
	qboolean	spawned;		// false = don't send datagrams
	qboolean	dropasap;		// has been told to go to another level
	qboolean	privileged;		// can execute any host command
	qboolean	sendsignon;		// only valid before spawned

	double		last_message;	// reliable messages must be sent periodically

	struct qsocket_s *netconnection;// communications handle

	usercmd_t	cmd;			// movement
	vec3_t		wishdir;		// intended motion calced from cmd

	sizebuf_t	message;		// can be added to at any time,
								// copied and clear once per frame
	byte		msgbuf[MAX_MSGLEN];
	edict_t		*edict;			// EDICT_NUM(clientnum+1)
	char		name[32];		// for printing to other people
	int			colors;
		
	float		ping_times[NUM_PING_TIMES];
	int			num_pings;		// ping_times[num_pings%NUM_PING_TIMES]

// spawn parms are carried from level to level
	float		spawn_parms[NUM_SPAWN_PARMS];

// client known data for deltas	
	int			old_frags;
		// JPG - added spam_time to prevent spamming.  If time < spam_time then
	// the client is spamming and is silenced.
	double		spam_time;

	// JPG 3.00 - prevent clients from rapidly changing their name/colour
	//            and doing a say or say_team
	double		change_time;

	//R00k	added to shut up a player
	qboolean	mute;	
} client_t;


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

// edict->movetype values
#define	MOVETYPE_NONE			0	// never moves
#define	MOVETYPE_ANGLENOCLIP	1
#define	MOVETYPE_ANGLECLIP		2
#define	MOVETYPE_WALK			3	// gravity
#define	MOVETYPE_STEP			4	// gravity, special edge handling
#define	MOVETYPE_FLY			5
#define	MOVETYPE_TOSS			6	// gravity
#define	MOVETYPE_PUSH			7	// no clip to world, push and crush
#define	MOVETYPE_NOCLIP			8
#define	MOVETYPE_FLYMISSILE		9	// extra size to monsters
#define	MOVETYPE_BOUNCE			10
#define MOVETYPE_BOUNCEMISSILE	11		// bounce w/o gravity
#define MOVETYPE_FOLLOW			12		// track movement of aiment

// edict->solid values
#define	SOLID_NOT			0	// no interaction with other objects
#define	SOLID_TRIGGER		1	// touch on edge, but not blocking
#define	SOLID_BBOX			2	// touch on edge, block
#define	SOLID_SLIDEBOX		3	// touch on edge, but not an onground
#define	SOLID_BSP			4	// bsp clip, touch on edge, block

// edict->deadflag values
#define	DEAD_NO				0
#define	DEAD_DYING			1
#define	DEAD_DEAD			2

#define	DAMAGE_NO			0
#define	DAMAGE_YES			1
#define	DAMAGE_AIM			2

// edict->flags
#define	FL_FLY				1
#define	FL_SWIM				2
#define	FL_CONVEYOR			4
#define	FL_CLIENT			8
#define	FL_INWATER			16
#define	FL_MONSTER			32
#define	FL_GODMODE			64
#define	FL_NOTARGET			128
#define	FL_ITEM				256
#define	FL_ONGROUND			512
#define	FL_PARTIALGROUND	1024	// not all corners are valid
#define	FL_WATERJUMP		2048	// player jumping out of water
#define	FL_JUMPRELEASED		4096	// for jump debouncing

// entity effects
#define	EF_BRIGHTFIELD		1
#define	EF_MUZZLEFLASH 		2
#define	EF_BRIGHTLIGHT 		4
#define	EF_DIMLIGHT 		8
#define	EF_NODRAW			16
#define	EF_FROZEN			32	//White powerupshell
#define EF_BLUE				64
#define EF_RED				128

//#define EF_NOGUNBOB		256			// LordHavoc: when used with .viewmodelforclient this makes the entity attach to the view without gun bobbing and such effects, it also works on the player entity to disable gun bobbing of the engine-managed .viewmodel (without affecting any .viewmodelforclient entities attached to the player)
//#define EF_FULLBRIGHT		512			// LordHavoc: fullbright

#define EF_FLAME			1024			// LordHavoc: on fire
/*
#define EF_STARDUST				2048		// LordHavoc: showering sparks
#define EF_NOSHADOW				4096		// LordHavoc: does not cast a shadow
#define EF_NODEPTHTEST			8192		// LordHavoc: shows through walls
#define EF_SELECTABLE			16384		// LordHavoc: highlights when PRYDON_CLIENTCURSOR mouse is over it
#define EF_DOUBLESIDED			32768		//[515]: disable cull face for this entity
#define EF_NOSELFSHADOW			65536		// LordHavoc: does not cast a shadow on itself (or any other EF_NOSELFSHADOW entities)
#define EF_UNUSED17				131072
#define EF_UNUSED18				262144
#define EF_UNUSED19				524288
#define EF_RESTARTANIM_BIT		1048576     // div0: restart animation bit (like teleport bit, but lerps between end and start of the anim, and doesn't stop player lerping)
#define EF_TELEPORT_BIT			2097152		// div0: teleport bit (toggled when teleporting, prevents lerping when the bit has changed)
#define EF_LOWPRECISION			4194304		// LordHavoc: entity is low precision (integer coordinates) to save network bandwidth  (serverside only)
#define EF_NOMODELFLAGS			8388608		// indicates the model's .effects should be ignored (allows overriding them)
#define EF_ROCKET				16777216	// leave a trail
#define EF_GRENADE				33554432	// leave a trail
#define EF_GIB					67108864	// leave a trail
#define EF_ROTATE				134217728	// rotate (bonus items)
#define EF_TRACER				268435456	// green split trail
#define EF_ZOMGIB				536870912	// small blood trail
#define EF_TRACER2				1073741824	// orange split trail + rotate
#define EF_TRACER3				0x80000000	// purple trail
*/

//R00k add vweapon effects here for protocol support

#define	SPAWNFLAG_NOT_EASY			256
#define	SPAWNFLAG_NOT_MEDIUM		512
#define	SPAWNFLAG_NOT_HARD			1024
#define	SPAWNFLAG_NOT_DEATHMATCH	2048

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

extern	cvar_t	teamplay;
extern	cvar_t	skill;
extern	cvar_t	deathmatch;
extern	cvar_t	coop;
extern	cvar_t	fraglimit;
extern	cvar_t	timelimit;

extern	cvar_t	sv_maxvelocity;
extern	cvar_t	sv_gravity;
extern	cvar_t	sv_nostep;
extern	cvar_t	sv_sound_land;
extern	cvar_t	sv_freezenonclients;
extern	cvar_t	sv_disable_noclip_touch_triggers;
extern	cvar_t	sv_friction;
extern	cvar_t	sv_edgefriction;
extern	cvar_t	sv_stopspeed;
extern	cvar_t	sv_maxspeed;
extern	cvar_t	sv_accelerate;
extern	cvar_t	sv_idealpitchscale;
extern	cvar_t	sv_aim;

extern	cvar_t	pq_fullpitch;	// JPG 2.01
extern	cvar_t	cl_fullpitch;	// JPG 2.01

extern	server_static_t	svs;			// persistant server info
extern	server_t	sv;			// local server

extern	client_t	*host_client;

extern	jmp_buf 	host_abortserver;

extern	double		host_time;

extern	edict_t		*sv_player;

extern	qboolean	sv_cheatfree;

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

void SV_Init (void);

void SV_StartParticle (vec3_t org, vec3_t dir, int color, int count);
void SV_StartSound (edict_t *entity, int channel, char *sample, int volume, float attenuation);

void SV_DropClient (qboolean crash);

void SV_SendClientMessages (void);
void SV_ClearDatagram (void);

int SV_ModelIndex (char *name);

void SV_SetIdealPitch (void);

void SV_AddUpdates (void);

void SV_ClientThink (void);
void SV_AddClientToServer (struct qsocket_s *ret);

void SV_ClientPrintf (char *fmt, ...);
void SV_BroadcastPrintf (char *fmt, ...);

void SV_Physics (void);

qboolean SV_CheckBottom (edict_t *ent);
qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink);

void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg);


void SV_MoveToGoal (void);

void SV_CheckForNewClients (void);
void SV_RunClients (void);
void SV_SaveSpawnparms ();
void SV_SpawnServer (char *server);
