/*
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[8192];

	// JoeQuake additions
	unsigned 	player_model_crc;
	unsigned 	eyes_model_crc;
} 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	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;

	// joe, from ProQuake: prevent clients from rapidly changing
	// their name/colour and doing a say or say_team
	double		change_time;

	// joe, from ProQuake: allow clients to connect if they don't have the map
	qboolean	nomap;
} 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

// 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_BLUE				64
#define	EF_RED				128

#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_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	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;

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

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);
