/*
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
	bool	changelevel_issued;	// cleared when at SV_SpawnServer
} server_static_t;

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

typedef enum {ss_loading, ss_active} server_state_t;


///////////////////////////////////////////////////////////////////////////
/// @brief	All server variables that all clients should have (?)
///////////////////////////////////////////////////////////////////////////
typedef struct
{
	bool	active;					///< false if only a net client
	
	bool	paused;					///< 
	bool	loadgame;				////< handle connections specially
	
	double		time;
	
	int			lastcheck;			///< used by PF_checkclient
	double		lastchecktime;
	
	char		name[64];			///< map name
#ifdef QUAKE2
	char		startspot[64];
#endif
	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];
} server_t;


#define	NUM_PING_TIMES		16
#define	NUM_SPAWN_PARMS		16

typedef struct client_s
{
	bool		active;					///< false = client is free
	bool		spawned;				///< false = don't send datagrams
	bool		dropasap;				///< has been told to go to another level
	bool		privileged;				///< can execute any host command
	bool		sendsignon;				///< only valid before spawned
	double		last_message;			///< reliable messages must be sent periodically
	qsocket_t	*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
	byte		msgbuf[MAX_MSGLEN];		///< copied and clear once per frame
	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]
	float		spawn_parms[NUM_SPAWN_PARMS];	//< spawn parms are carried from level to level
	int			old_frags;				//< client known data for deltas
} 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
#ifdef QUAKE2
#define MOVETYPE_BOUNCEMISSILE	11		/// bounce w/o gravity
#define MOVETYPE_FOLLOW			12		/// track movement of aiment
#endif

/// 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_GLIMPSE				4
#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
#ifdef QUAKE2
#define FL_FLASHLIGHT			8192
#define FL_ARCHIVE_OVERRIDE		1048576
#endif

// entity effects

#define	EF_BRIGHTFIELD				1
#define	EF_MUZZLEFLASH 				2
#define	EF_BRIGHTLIGHT 				4
#define	EF_DIMLIGHT 				8
#ifdef QUAKE2
#define EF_DARKLIGHT				16
#define EF_DARKFIELD				32
#define EF_LIGHT					64
#define EF_NODRAW					128
#endif

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

#ifdef QUAKE2
// server flags
#define	SFL_EPISODE_1		1
#define	SFL_EPISODE_2		2
#define	SFL_EPISODE_3		4
#define	SFL_EPISODE_4		8
#define	SFL_NEW_UNIT		16
#define	SFL_NEW_EPISODE		32
#define	SFL_CROSS_TRIGGERS	65280
#endif

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

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	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 (bool 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);
bool SV_CheckBottom (edict_t *ent);
bool SV_movestep (edict_t *ent, vec3_t move, bool 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 ();

#ifdef QUAKE2
void SV_SpawnServer (char *server, char *startspot);
#else
void SV_SpawnServer (char *server);
#endif
