/*
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.

*/
// protocol.h -- communications protocols

#include "bothdefs.h"

#define PEXT_SETVIEW			0x00000001

#define PEXT_SCALE				0x00000002
#define PEXT_LIGHTSTYLECOL		0x00000004
#define PEXT_TRANS				0x00000008
#define PEXT_VIEW2_				0x00000010
//#define PEXT_BULLETENS			0x00000020 //obsolete
#define PEXT_ACCURATETIMINGS	0x00000040
#define PEXT_SOUNDDBL			0x00000080	//revised startsound protocol
#define PEXT_FATNESS			0x00000100	//GL only (or servers)
#define PEXT_HLBSP				0x00000200
#define PEXT_TE_BULLET			0x00000400
#define PEXT_HULLSIZE			0x00000800
#define PEXT_MODELDBL			0x00001000
#define PEXT_ENTITYDBL			0x00002000	//max of 1024 ents instead of 512
#define PEXT_ENTITYDBL2			0x00004000	//max of 1024 ents instead of 512
#define PEXT_FLOATCOORDS		0x00008000	//supports floating point origins.
//#define PEXT_VWEAP				0x00010000	//cause an extra qbyte to be sent, and an extra list of models for vweaps.
#define PEXT_Q2BSP_				0x00020000
#define PEXT_Q3BSP_				0x00040000

#define PEXT_COLOURMOD			0x00080000	//this replaces an older value which would rarly have caried any actual data.

#define PEXT_SPLITSCREEN		0x00100000
#define PEXT_HEXEN2				0x00200000	//more stats and working particle builtin.
#define PEXT_SPAWNSTATIC2		0x00400000	//Sends an entity delta instead of a baseline.
#define PEXT_CUSTOMTEMPEFFECTS	0x00800000	//supports custom temp ents.
#define PEXT_256PACKETENTITIES	0x01000000	//Client can recieve 256 packet entities.
//#define PEXT_NEVERUSED		0x02000000	//reserved for a future multicastmask
#define PEXT_SHOWPIC			0x04000000
#define PEXT_SETATTACHMENT		0x08000000	//md3 tags (needs networking, they need to lerp).
//#define PEXT_NEVERUSED		0x10000000	//reserved for a future multicastmask
#define PEXT_CHUNKEDDOWNLOADS	0x20000000	//alternate file download method. Hopefully it'll give quadroupled download speed, especially on higher pings.
#define PEXT_CSQC				0x40000000	//csqc additions
#define PEXT_DPFLAGS			0x80000000	//extra flags for viewmodel/externalmodel and possible other persistant style flags.
#define PEXT_SERVERADVERTISE	~0u
#define PEXT_CLIENTSUPPORT		(PEXT_SETVIEW|PEXT_SCALE|PEXT_LIGHTSTYLECOL|PEXT_TRANS|PEXT_VIEW2_|PEXT_ACCURATETIMINGS|PEXT_SOUNDDBL|PEXT_FATNESS|PEXT_HLBSP|PEXT_TE_BULLET|PEXT_HULLSIZE|PEXT_MODELDBL|PEXT_ENTITYDBL|PEXT_ENTITYDBL2|PEXT_FLOATCOORDS|PEXT_Q2BSP_|PEXT_Q3BSP_|PEXT_COLOURMOD|PEXT_SPLITSCREEN|PEXT_HEXEN2|PEXT_SPAWNSTATIC2|PEXT_CUSTOMTEMPEFFECTS|PEXT_256PACKETENTITIES|PEXT_SHOWPIC|PEXT_SETATTACHMENT|PEXT_CHUNKEDDOWNLOADS|PEXT_CSQC|PEXT_DPFLAGS)

#ifdef CSQC_DAT
	#define PEXT_BIGUSERINFOS	PEXT_CSQC	//FIXME: while useful for csqc, we should include something else that isn't so often stripped, or is available in ezquake, or something.
#else
	#define PEXT_BIGUSERINFOS	0xffffffff
#endif
#ifdef SIDEVIEWS
	#define PEXT_VIEW2			PEXT_VIEW2_
#endif
#ifdef Q2BSPS
	#define PEXT_Q2BSP			PEXT_Q2BSP_
#endif
#ifdef Q3BSPS
	#define PEXT_Q3BSP			PEXT_Q3BSP_
#endif
#define PEXT1_HIDEPROTOCOLS		(PEXT_Q3BSP_|PEXT_Q2BSP_|PEXT_HLBSP)	//These are hints for the server, and not useful to the client (they can figure stuff out themselves)

#define PEXT2_PRYDONCURSOR			0x00000001
#define PEXT2_VOICECHAT				0x00000002
#define PEXT2_SETANGLEDELTA			0x00000004
#define PEXT2_REPLACEMENTDELTAS		0x00000008	//weaponframe was part of the entity state. that flag is now the player's v_angle.
#define PEXT2_MAXPLAYERS			0x00000010	//Client is able to cope with more players than 32. abs max becomes 255, due to colormap issues.
#define PEXT2_PREDINFO				0x00000020	//movevar stats, NQ input sequences+acks.
#define PEXT2_NEWSIZEENCODING		0x00000040	//richer size encoding.
#define PEXT2_INFOBLOBS				0x00000080	//serverinfo+userinfo lengths can be MUCH higher (protocol is unbounded, but expect low sanity limits on userinfo), and contain nulls etc.
#define PEXT2_STUNAWARE				0x00000100	//changes the netchan to biased-bigendian (so lead two bits are 1 and not stun's 0, so we don't get confused)
#define PEXT2_VRINPUTS				0x00000200	//clc_move changes, more buttons etc. vr stuff!
#define PEXT2_LERPTIME				0x00000400	//fitz-bloat parity. redefines UF_16BIT as UF_LERPEND in favour of length coding.
#define PEXT2_SERVERADVERTISE		~0u
#define PEXT2_CLIENTSUPPORT			(PEXT2_PRYDONCURSOR|PEXT2_VOICECHAT|PEXT2_SETANGLEDELTA|PEXT2_REPLACEMENTDELTAS|PEXT2_MAXPLAYERS|PEXT2_PREDINFO|PEXT2_NEWSIZEENCODING|PEXT2_INFOBLOBS|PEXT2_STUNAWARE|PEXT2_VRINPUTS|PEXT2_LERPTIME) //warn if we see bits not listed here.

//EzQuake/Mvdsv extensions. (use ezquake name, to avoid confusion about .mvd format and its protocol differences)
#define EZPEXT1_FLOATENTCOORDS		0x00000001	//quirky - doesn't apply to broadcasts, just players+ents. this gives more precision, but will bug out if you try using it to increase map bounds in ways that may not be immediately apparent. iiuc this was added instead of fixing some inconsistent rounding...
#define EZPEXT1_SETANGLEREASON		0x00000002	//specifies the reason for an svc_setangles call. the mvdsv implementation will fuck over any mods that writebyte them. we'd need to modify our preparse stuff to work around the issue.
#define EZPEXT1_SERVERADVERTISE		EZPEXT1_FLOATENTCOORDS/* - implemented, but interactions with replacementdeltas is not defined*/ /*EZPEXT1_SETANGLEREASON - potentially causes compat issues with mods that stuffcmd it (common in nq)*/
#define EZPEXT1_CLIENTADVERTISE		EZPEXT1_FLOATENTCOORDS			//might as well ask for it, as a way around mvdsv's writecoord/PM_NudgePosition rounding difference bug.
#define EZPEXT1_CLIENTSUPPORT		(EZPEXT1_FLOATENTCOORDS|EZPEXT1_SETANGLEREASON)	//ones we can support in demos. warning if other bits.

//ZQuake transparent protocol extensions.
#define Z_EXT_PM_TYPE		(1<<0)	// basic PM_TYPE functionality (reliable jump_held)
#define Z_EXT_PM_TYPE_NEW	(1<<1)	// adds PM_FLY, PM_SPECTATOR
#define Z_EXT_VIEWHEIGHT	(1<<2)	// STAT_VIEWHEIGHT
#define Z_EXT_SERVERTIME	(1<<3)	// STAT_TIME
#define Z_EXT_PITCHLIMITS	(1<<4)	// serverinfo maxpitch & minpitch
#define Z_EXT_JOIN_OBSERVE	(1<<5)	// server: "join" and "observe" commands are supported
									// client: on-the-fly spectator <-> player switching supported

#define Z_EXT_PF_ONGROUND	(1<<6)	// server: PF_ONGROUND is valid for all svc_playerinfo
#define Z_EXT_VWEP			(1<<7)
#define Z_EXT_PF_SOLID		(1<<8)	//conflicts with many FTE extensions.

#ifdef QUAKESTATS
#define SERVER_SUPPORTED_Z_EXTENSIONS (Z_EXT_PM_TYPE|Z_EXT_PM_TYPE_NEW|Z_EXT_VIEWHEIGHT|Z_EXT_SERVERTIME|Z_EXT_PITCHLIMITS|Z_EXT_JOIN_OBSERVE|Z_EXT_PF_ONGROUND|Z_EXT_VWEP|Z_EXT_PF_SOLID)
#else
#define SERVER_SUPPORTED_Z_EXTENSIONS (Z_EXT_PM_TYPE|Z_EXT_PM_TYPE_NEW|Z_EXT_PITCHLIMITS|Z_EXT_JOIN_OBSERVE|Z_EXT_PF_ONGROUND|Z_EXT_VWEP|Z_EXT_PF_SOLID)
#endif
#define BUGGY_EZQUAKE_Z_EXTENSIONS    (Z_EXT_PF_ONGROUND|Z_EXT_PF_SOLID) //ezquake bugs out on these when ANY fteextension is present. hack the serverinfo to hide these.
#define CLIENT_SUPPORTED_Z_EXTENSIONS (SERVER_SUPPORTED_Z_EXTENSIONS|Z_EXT_PF_ONGROUND|Z_EXT_PF_SOLID)


#define PROTOCOL_VERSION_VARLENGTH		(('v'<<0) + ('l'<<8) + ('e'<<16) + ('n' << 24))	//variable length handshake

#define PROTOCOL_VERSION_FTE1			(('F'<<0) + ('T'<<8) + ('E'<<16) + ('X' << 24))	//fte extensions.
#define PROTOCOL_VERSION_FTE2			(('F'<<0) + ('T'<<8) + ('E'<<16) + ('2' << 24))	//fte extensions.
#define PROTOCOL_VERSION_EZQUAKE1		(('M'<<0) + ('V'<<8) + ('D'<<16) + ('1' << 24)) //ezquake/mvdsv extensions
#define PROTOCOL_VERSION_HUFFMAN		(('H'<<0) + ('U'<<8) + ('F'<<16) + ('F' << 24))	//packet compression
#define PROTOCOL_VERSION_FRAGMENT		(('F'<<0) + ('R'<<8) + ('A'<<16) + ('G' << 24))	//supports fragmentation/packets larger than 1450
#ifdef HAVE_DTLS
#define PROTOCOL_VERSION_DTLSUPGRADE	(('D'<<0) + ('T'<<8) + ('L'<<16) + ('S' << 24))	//server supports dtls. clients should dtlsconnect THEN continue connecting (also allows dtls rcon!).
#endif

#define PROTOCOL_INFO_GUID				(('G'<<0) + ('U'<<8) + ('I'<<16) + ('D' << 24))	//globally 'unique' client id info.

#define	PROTOCOL_VERSION_QW				28

#define	PROTOCOL_VERSION_Q2_DEMO_MIN	26	//we can parse this server
#define	PROTOCOL_VERSION_Q2_MIN			31	//we can join these outdated servers
#define	PROTOCOL_VERSION_Q2				34	//we host this
#define	PROTOCOL_VERSION_R1Q2			35
#define	PROTOCOL_VERSION_Q2PRO			36

#define	PROTOCOL_VERSION_Q2_DEMO_MAX	PROTOCOL_VERSION_Q2PRO

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

//#define	GAME_DEFAULTPORT	XXXXX	//rebranding allows selection of a different default port, which slightly reduces protocol conflicts.
#define	PORT_NQSERVER	26000
#define PORT_DPMASTER	PORT_Q3MASTER
#define	PORT_QWCLIENT	27001
#define	PORT_QWMASTER	27000
#define	PORT_QWSERVER	27500
#define PORT_H2SERVER	26900
#define PORT_Q2MASTER	27900
#define PORT_Q2CLIENT	27901
#define PORT_Q2SERVER	27910
#define PORT_Q3MASTER	27950
#define PORT_Q3SERVER	27960
#define PORT_ICEBROKER	PORT_DPMASTER

#ifdef GAME_DEFAULTPORT
	#define PORT_DEFAULTSERVER	GAME_DEFAULTPORT
#else
	#define PORT_DEFAULTSERVER	PORT_QWSERVER
#endif

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

// out of band message id bytes

// M = master, S = server, C = client, A = any
// the second character will always be \n if the message isn't a single
// qbyte long (?? not true anymore?)

#define	S2C_CHALLENGE		'c'
#define	S2C_CONNECTION		'j'
#define	A2A_PING			'k'	// respond with an A2A_ACK
#define	A2A_ACK				'l'	// general acknowledgement without info
#define	A2A_NACK			'm'	// [+ comment] general failure
#define A2A_ECHO			'e' // for echoing
#define	A2C_PRINT			'n'	// print a message on client

#define	S2M_HEARTBEAT		'a'	// + serverinfo + userlist + fraglist
#define	A2C_CLIENT_COMMAND	'B'	// + command line
#define	S2M_SHUTDOWN		'C'

#define C2M_MASTER_REQUEST  'c'
#define M2C_MASTER_REPLY	'd'	// + \n + qw server port list
//==================
// note that there are some defs.qc that mirror to these numbers
// also related to svc_strings[] in cl_parse
//==================

//
// server to client
//
#define	svc_bad						0
#define	svc_nop						1
#define	svc_disconnect				2
#define	svcqw_updatestatbyte		3	// [qbyte] [qbyte]
#define	svcnq_updatestatlong		3	// [qbyte] [long]
#define	svc_version					4	// [long] server version
#define	svc_setview					5	// [short] entity number
#define	svc_sound					6	// <see code>
#define	svc_time					7	// [float] server time
#define	svc_print					8	// [qbyte] id [string] null terminated string
#define	svc_stufftext				9	// [string] stuffed into client's console buffer
										// the string should be \n terminated
#define	svc_setangle				10	// [angle3] set the view angle to this absolute value

#define	svc_serverdata				11	// [long] protocol ...
#define	svc_lightstyle				12	// [qbyte] [string]
#define	svc_updatename				13	// [qbyte] [string]
#define	svc_updatefrags				14	// [qbyte] [short]
#define	svcnq_clientdata			15	// <shortbits + data>
#define	svc_stopsound				16	// <see code>
#define	svc_updatecolors			17	// [qbyte] [qbyte] [qbyte]
#define	svc_particle				18	// [vec3] <variable>
#define	svc_damage					19

#define	svc_spawnstatic				20
#define	svcfte_spawnstatic2			21
#define	svc_spawnbaseline			22

#define	svc_temp_entity				23	// variable
#define	svc_setpause				24	// [qbyte] on / off
#define	svcnq_signonnum				25	// [qbyte]  used for the signon sequence
#define	svcfte_splitscreenconfig	25	// [qbyte] seats, player[seat]. spectator flags passed via userinfo.

#define	svc_centerprint				26	// [string] to put in center of the screen

#define	svc_killedmonster			27
#define	svc_foundsecret				28

#define	svc_spawnstaticsound		29	// [coord3] [qbyte] samp [qbyte] vol [qbyte] aten

#define	svc_intermission			30		// [vec3_t] origin [vec3_t] angle
#define	svc_finale					31		// [string] text

#define	svc_cdtrack					32		// [qbyte] track
#define svc_sellscreen				33

#define svc_cutscene				34	//hmm... nq only... added after qw tree splitt?



//QW svcs
#define	svc_smallkick				34		// set client punchangle to 2
#define	svc_bigkick					35		// set client punchangle to 4

#define	svc_updateping				36		// [qbyte] [short]
#define	svc_updateentertime			37		// [qbyte] [float]

#define	svcqw_updatestatlong		38		// [qbyte] [long]

#define	svc_muzzleflash				39		// [short] entity

#define	svc_updateuserinfo			40		// [qbyte] slot [long] uid [string] userinfo

#define	svc_download				41		// [short] size [size bytes]
#define	svc_playerinfo				42		// variable
#define	svc_nails					43		// [qbyte] num [48 bits] xyzpy 12 12 12 4 8
#define	svc_chokecount				44		// [qbyte] packets choked
#define	svc_modellist				45		// [strings]
#define	svc_soundlist				46		// [strings]
#define	svc_packetentities			47		// [...]
#define	svc_deltapacketentities		48		// [...]
#define svc_maxspeed				49		// maxspeed change, for prediction
#define svc_entgravity				50		// gravity change, for prediction
#define svc_setinfo					51		// setinfo on a client
#define svc_serverinfo				52		// serverinfo
#define svc_updatepl				53		// [qbyte] [qbyte]

//mvdsv extended svcs (for mvd playback)
#define svc_nails2					54		//qwe - [qbyte] num [52 bits] nxyzpy 8 12 12 12 4 8

//FTE extended svcs
#ifdef PEXT_SOUNDDBL
#define svcfte_soundextended		55
#define svcfte_soundlistshort		56
#endif
#ifdef PEXT_LIGHTSTYLECOL
#define svcfte_lightstylecol		57
#endif

//#define svcfte_svcremoved			58

//#define	svcfte_svcremoved		59

#ifdef PEXT_MODELDBL
#define	svcfte_modellistshort		60		// [strings]
#endif

//#define svc_ftesetclientpersist	61	//ushort DATA

#define svc_setportalstate			62

#define	svcfte_particle2			63
#define	svcfte_particle3			64
#define	svcfte_particle4			65
#define svcfte_spawnbaseline2		66

#define	svcfte_customtempent		67

#define svcfte_choosesplitclient	68
#define svcfte_showpic				69
#define svcfte_hidepic				70
#define svcfte_movepic				71
#define svcfte_updatepic			72

//73

#define svcfte_effect				74		// [vector] org [byte] modelindex [byte] startframe [byte] framecount [byte] framerate
#define svcfte_effect2				75		// [vector] org [short] modelindex [short] startframe [byte] framecount [byte] framerate

#define svcfte_csqcentities			76	//entity lump for csqc

#define svcfte_precache				77

#define svcfte_updatestatstring		78
#define svcfte_updatestatfloat		79

#define svcfte_trailparticles		80		// [short] entnum [short] effectnum [vector] start [vector] end
#define svcfte_pointparticles		81		// [short] effectnum [vector] start [vector] velocity [short] count
#define svcfte_pointparticles1		82		// [short] effectnum [vector] start, same as svc_pointparticles except velocity is zero and count is 1

#define svcfte_cgamepacket			83
#define svcfte_voicechat			84
#define	svcfte_setangledelta		85	// [angle3] add this to the current viewangles
#define svcfte_updateentities		86
#define svcfte_brushedit			87	// networked brush editing, paired with clcfte_brushedit.
#define	svcfte_updateseats			88	// byte count, byte playernum[count]
#define svcfte_setinfoblob			89	// [8] 1-based index [string] key [32] isfinal<<31|offset [16] chunksize [chunksize] data
#define svcfte_cgamepacket_sized	90	//svcfte_cgamepacket with an extra short size right after the svc.
#define	svcfte_temp_entity_sized	91	//svc_temp_entity with an extra short size right after the svc (high bit means nq, unset means qw).
#define svcfte_csqcentities_sized	92	//entity lump for csqc (with size info)
#define svcfte_setanglebase			93	//updates the base angle (and optionally locks the view, otherwise nudging it without race conditions.)
#define svcfte_spawnstaticsound2	94	//*sigh*

//fitz svcs
#define svcfitz_skybox				37
#define svcfitz_bf					40
#define svcfitz_fog					41
#define svcfitz_spawnbaseline2		42
#define svcfitz_spawnstatic2		43
#define svcfitz_spawnstaticsound2	44

//nehahra svcs
#define svcneh_skyboxsize			50  // [coord] size (default is 4096)
#define svcneh_fog					51	// [byte] enable <optional past this point, only included if enable is true> [float] density [byte] red [byte] green [byte] blue

//QuakeEx(aka: rerelease) svcs.
//	these are not really documented anywhere. we're trying to stick with protocol 15 (because that's the only documented protocol it supports properly thanks to demos)
//	however we still need some special case svcs
//  (there's also some problematic c2s differences too)
#define svcqex_updateping			46	// [byte] slot, [signed_qe] ping
#define svcqex_updatesocial			47	// [byte] slot, 8 bytes of unknown
#define svcqex_updateplinfo			48	// [byte] slot, [leb128] health, [leb128] armour
#define svcqex_locprint				49	// uses qe's localised string formatting, otherwise treat as svc_print.
#define svcqex_servervars			50	// [leb128] changedvalues, [???] value...
#define svcqex_seq					51	// [leb128] input sequence ack
#define svcqex_achievement			52	// [string] codename
#define svcqex_chat					53
#define svcqex_levelcompleted		54
#define svcqex_backtolobby			55
#define svcqex_localsound			56
#define svcqex_prompt				57
#define svcqex_loccenterprint		58	// [string] codename

//DP extended svcs
#define svcdp_downloaddata			50
#define svcdp_updatestatbyte		51
#define svcnq_effect				52		// [vector] org [byte] modelindex [byte] startframe [byte] framecount [byte] framerate
#define svcnq_effect2				53		// [vector] org [short] modelindex [short] startframe [byte] framecount [byte] framerate
#define	svcdp_precache				54		// [short] precacheindex [string] filename, precacheindex is + 0 for modelindex and +32768 for soundindex
#define svcdp_spawnbaseline2		55
#define svcdp_spawnstatic2			56
#define svcdp_entities				57
#define svcdp_csqcentities			58
#define	svcdp_spawnstaticsound2		59	// [coord3] [short] samp [byte] vol [byte] aten
#define svcdp_trailparticles		60		// [short] entnum [short] effectnum [vector] start [vector] end
#define svcdp_pointparticles		61		// [short] effectnum [vector] start [vector] velocity [short] count
#define svcdp_pointparticles1		62		// [short] effectnum [vector] start, same as svc_pointparticles except velocity is zero and count is 1



#define svc_invalid			256


enum clustercmdops_e
{
	ccmd_bad = 0,			//abort!
	ccmd_stuffcmd,		//regular ol stuffcmd
			//string concommand
	ccmd_setcvar,		//master->server to order a cvar change.
	ccmd_print,
			//string message
	ccmd_acceptserver,
			//serverid
	ccmd_lostplayer,	//player dropped/timed out
			//long plid
	ccmd_foundplayer,	//server->master, saying that a player tried to connect directly (and we need their info)
			//string name
			//string clientaddress
			//string guid
	ccmd_takeplayer,	//master->server, saying to allocate a slot for a player.
			//long plid
			//long fromsvid (0=no reply needed)
			//byte statcount
			//float stats[statcount]
	ccmd_transferplayer,	//server->master, asking to move them to a new server.
			//long plid
			//string map
			//byte ipv4=0, ipv6=1
			//byte statcount
			//float stats[statcount]
	ccmd_transferedplayer,	//master->server, saying the transfer was completed. original server no longer owns the player.
			//long toserver,
			//long playerid
	ccmd_tookplayer,	//server->master->server, saying that a player was taken.
			//long svid (this is always the *other* server)
			//long plid
			//string addr (this is the client's address when sent to the master, and the server's address that took the message in the message to the source server)
	ccmd_transferabort,	//server->master->server, saying that a player was rejected.
			//long plid
			//long fromsvid
			//string server
	ccmd_saveplayer,	//server->master, saves a player's stats.
			//long plid
			//byte statcount
			//float stats[statcount]
	ccmd_serveraddress,	//server->master, contains a few net addresses
			//string addresses[]
			//byte 0
	ccmd_stringcmd,
			//string dest (black = broadcast to all)
			//string source (player name)
			//string cmd (type of event, handled by receiving server/forwarded to client)
			//string msg (extra info, like the typed text)
};


enum svcq2_ops_e
{
	svcq2_bad,	//0

	// these ops are known to the game dll
	svcq2_muzzleflash,	//1
	svcq2_muzzleflash2,	//2
	svcq2_temp_entity,	//3
	svcq2_layout,		//4
	svcq2_inventory,	//5

	// the rest are private to the client and server
	svcq2_nop,			//6
	svcq2_disconnect,	//7
	svcq2_reconnect,	//8
	svcq2_sound,		//9			// <see code>
	svcq2_print,		//10			// [qbyte] id [string] null terminated string
	svcq2_stufftext,	//11			// [string] stuffed into client's console buffer, should be \n terminated
	svcq2_serverdata,	//12			// [long] protocol ...
	svcq2_configstring,	//13		// [short] [string]
	svcq2_spawnbaseline,//14
	svcq2_centerprint,	//15		// [string] to put in center of the screen
	svcq2_download,		//16		// [short] size [size bytes]
	svcq2_playerinfo,	//17			// variable
	svcq2_packetentities,//18			// [...]
	svcq2_deltapacketentities,//19	// [...]
	svcq2_frame,			//20 (the bastard to implement.)


	svcr1q2_zpacket = 21,
	svcr1q2_zdownload = 22,
	svcr1q2_playerupdate = 23,
	svcr1q2_setting = 24,
	svcq2pro_gamestate = 23,
	svcq2pro_setting = 24,
};

enum clcq2_ops_e
{
	clcq2_bad = 0,
	clcq2_nop = 1,
	clcq2_move = 2,			// [[usercmd_t]
	clcq2_userinfo = 3,		// [[userinfo string]
	clcq2_stringcmd = 4,	// [string] message

	clcr1q2_setting = 5,	// [setting][value] R1Q2 settings support.
	clcr1q2_multimoves = 6,	// for crappy clients that can't lerp

	//fte-extended
	clcq2_stringcmd_seat = 30,
#ifdef VOICECHAT
	clcq2_voicechat = 31
#endif
};

enum {
	R1Q2_CLSET_NOGUN			= 0,
	R1Q2_CLSET_NOBLEND			= 1,
	R1Q2_CLSET_RECORDING		= 2,
	R1Q2_CLSET_PLAYERUPDATES	= 3,
	R1Q2_CLSET_FPS				= 4
};
enum {
	R1Q2_SVSET_PLAYERUPDATES	= 0,
	R1Q2_SVSET_FPS				= 1
};

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

//
// client to server
//
#define	clc_bad				0
#define	clc_nop 			1
#define	clc_disconnect		2	//nq only
#define	clc_move			3	// [[usercmd_t]
#define	clc_stringcmd		4	// [string] message
#define	clc_delta			5	// [qbyte] sequence number, requests delta compression of message
#define clc_tmove			6	// teleport request, spectator only
#define clc_upload			7	// 

#define clcdp_ackframe			50
#define clcdp_ackdownloaddata	51

#define clcfte_qcrequest		81
#define clcfte_prydoncursor		82
#define clcfte_voicechat		83
#define clcfte_brushedit		84
#define clcfte_move				85	//part of PEXT2_VRINPUTS. replaces clc_move+clcfte_prydoncursor+clcdp_ackframe
#define clcfte_stringcmd_seat	86

#define VRM_LOSS	(1u<<0)	//for server packetloss reports
#define VRM_DELAY	(1u<<1)	//for server to compute lag properly.
#define VRM_SEATS	(1u<<2) //for splitscreen to work properly
#define VRM_FRAMES	(1u<<3) //number of input frames in this packet.
#define VRM_ACKS	(1u<<4)	//number of sequence acks included in message.

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

#define DLERR_FILENOTFOUND	-1	//server cannot serve the file
#define DLERR_PERMISSIONS	-2	//server refuses to serve the file
#define DLERR_UNKNOWN		-3	//server bugged out while trying to serve the request
#define DLERR_REDIRECTFILE	-4	//client should download the specified file instead.
#define DLERR_REDIRECTPACK	-5	//client should download the specified package instead.
#define DLERR_PACKAGE		-6	//not networked. packages require special file access.

#define DLBLOCKSIZE			1024 //chunked downloads use fixed-size chunks (which I somewhat regret, but too late now I guess, really ought to use ranges.).

//these flags are sent as part of the svc_precache index, for any-time precaches. using the upper two bits means we still have 16k available models/sounds/etc
#define PC_TYPE			0xc000
#define PC_MODEL		0x0000
#define PC_SOUND		0x8000
#define PC_PARTICLE		0x4000
#define PC_UNUSED		0xc000

#define GAME_COOP		0
#define GAME_DEATHMATCH	1


// playerinfo flags from server
// playerinfo always sends: playernum, flags, origin[] and framenumber

#define	PF_MSEC			(1<<0)	//msecs says how long the player command was sitting on the server before it was sent back to the client
#define	PF_COMMAND		(1<<1)	//angles and movement values for other players (no msec or impulse)
#define	PF_VELOCITY1	(1<<2)
#define	PF_VELOCITY2	(1<<3)
#define	PF_VELOCITY3	(1<<4)
#define	PF_MODEL		(1<<5)
#define	PF_SKINNUM		(1<<6)
#define	PF_EFFECTS		(1<<7)
#define	PF_WEAPONFRAME	(1<<8)		// only sent for view player
#define	PF_DEAD			(1<<9)		// don't block movement any more
#define	PF_GIB			(1<<10)		// offset the view height differently

//ZQuake.
#define PF_PMC_SHIFT	11
#define	PF_PMC_MASK		((1<<11) | \
						 (1<<12) | \
						 (1<<13))
#ifdef PEXT_HULLSIZE
#define	PF_HULLSIZE_Z	(1<<14)
#endif
#define PF_EXTRA_PFS	(1<<15)

#ifdef PEXT_SCALE
#define	PF_SCALE		(1<<16)
#endif
#ifdef PEXT_TRANS
#define	PF_TRANS		(1<<17)
#endif
#ifdef PEXT_FATNESS
#define	PF_FATNESS		(1<<18)
#endif

#define	PF_COLOURMOD	(1<<19)
//#define	PF_UNUSED	(1<<20)	//remember to faff with zext
//#define	PF_UNUSED	(1<<21)	//remember to faff with zext
//note that if you add any more, you may need to change the check in the client so more can be parsed
#define PF_ONGROUND		(1<<22)	//or 14, depending on extensions... messy.
#define PF_SOLID		(1<<23) //or 15, depending on extensions... messy.


//not networked
#define PF_INWATER		(1u<<31) //for network smartjump.



// player move types
#define PMC_NORMAL			0		// normal ground movement
#define PMC_NORMAL_JUMP_HELD	1	// normal ground novement + jump_held
#define PMC_OLD_SPECTATOR	2		// fly through walls (QW compatibility mode)
#define PMC_SPECTATOR		3		// fly through walls
#define PMC_FLY				4		// fly, bump into walls
#define PMC_NONE			5		// can't move (client had better lerp the origin...)
#define PMC_FREEZE			6		// TODO: lerp movement and viewangles
#define PMC_WALLWALK		7		// future extension

//any more will require a different protocol message.

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

// if the high bit of the client to server qbyte is set, the low bits are
// client move cmd bits
// ms and angle2 are always sent, the others are optional
#define	CM_ANGLE1 	(1<<0)
#define	CM_ANGLE3 	(1<<1)
#define	CM_FORWARD	(1<<2)
#define	CM_SIDE		(1<<3)
#define	CM_UP		(1<<4)
#define	CM_BUTTONS	(1<<5)
#define	CM_IMPULSE	(1<<6)
#define	CM_ANGLE2 	(1<<7)

//sigh...
#define	Q2CM_ANGLE1 	(1<<0)
#define	Q2CM_ANGLE2 	(1<<1)
#define	Q2CM_ANGLE3 	(1<<2)
#define	Q2CM_FORWARD	(1<<3)
#define	Q2CM_SIDE		(1<<4)
#define	Q2CM_UP			(1<<5)
#define	Q2CM_BUTTONS	(1<<6)
#define	Q2CM_IMPULSE	(1<<7)

#define R1Q2_BUTTON_BYTE_FORWARD  4
#define R1Q2_BUTTON_BYTE_SIDE     8
#define R1Q2_BUTTON_BYTE_UP       16
#define R1Q2_BUTTON_BYTE_ANGLE1   32
#define R1Q2_BUTTON_BYTE_ANGLE2   64

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

// the first 16 bits of a packetentities update holds 9 bits
// of entity number and 7 bits of flags
#define	U_UNUSABLE	(1<<8)
#define	U_ORIGIN1	(1<<9)
#define	U_ORIGIN2	(1<<10)
#define	U_ORIGIN3	(1<<11)
#define	U_ANGLE2	(1<<12)
#define	U_FRAME		(1<<13)
#define	U_REMOVE	(1<<14)		// REMOVE this entity, don't add it
#define	U_MOREBITS	(1<<15)

// if MOREBITS is set, these additional flags are read in next
#define	U_ANGLE1	(1<<0)
#define	U_ANGLE3	(1<<1)
#define	U_MODEL		(1<<2)
#define	U_COLORMAP	(1<<3)
#define	U_SKIN		(1<<4)
#define	U_EFFECTS	(1<<5)
#define	U_SOLID		(1<<6)		// the entity should be solid for prediction
#ifdef PROTOCOLEXTENSIONS
#define U_EVENMORE	(1<<7)	//extension info follows

//fte extensions
//EVENMORE flags
#ifdef PEXT_SCALE
#define U_SCALE		(1<<0)	//scaler of alias models
#endif
#ifdef PEXT_TRANS
#define U_TRANS		(1<<1)	//transparency value
#endif
#ifdef PEXT_FATNESS
#define U_FATNESS	(1<<2)	//qbyte describing how fat an alias model should be. (moves verticies along normals). Useful for vacuum chambers...
#endif
#ifdef PEXT_MODELDBL
#define U_MODELDBL	(1<<3)	//extra bit for modelindexes
#endif
#define U_UNUSED1	(1<<4)
//FIXME: IMPLEMENT
#ifdef PEXT_ENTITYDBL
#define U_ENTITYDBL	(1<<5)	//use an extra qbyte for origin parts, cos one of them is off
#endif
#ifdef PEXT_ENTITYDBL2
#define U_ENTITYDBL2 (1<<6)	//use an extra qbyte for origin parts, cos one of them is off
#endif
#define U_YETMORE	(1<<7)	//even more extension info stuff.

#define U_DRAWFLAGS	(1<<8)	//use an extra qbyte for origin parts, cos one of them is off
#define U_ABSLIGHT	(1<<9)	//Force a lightlevel

#define U_COLOURMOD	(1<<10)	//rgb

#define U_DPFLAGS (1<<11)


#define U_TAGINFO (1<<12)
#define U_LIGHT (1<<13)
#define	U_EFFECTS16	(1<<14)

#define U_FARMORE (1<<15)

#endif

//FTE Replacement Deltas
//first byte contains the stuff that's most likely to change constantly
#define UF_FRAME		(1u<<0)
#define UF_ORIGINXY		(1u<<1)
#define UF_ORIGINZ		(1u<<2)
#define UF_ANGLESXZ		(1u<<3)
#define UF_ANGLESY		(1u<<4)
#define UF_EFFECTS		(1u<<5)
#define UF_PREDINFO		(1u<<6)	/*ent is predicted, probably a player*/
#define UF_EXTEND1		(1u<<7)

/*stuff which is common on ent spawning*/
#define UF_RESET		(1u<<8)	/*client will reset entire strict to its baseline*/
#define UF_16BIT_LERPTIME	(1u<<9)	/*either included frame/skin/model is 16bit (not part of the deltaing itself), or there's nextthink info*/
#define UF_MODEL		(1u<<10)
#define UF_SKIN			(1u<<11)
#define UF_COLORMAP		(1u<<12)
#define UF_SOLID		(1u<<13)
#define UF_FLAGS		(1u<<14)
#define UF_EXTEND2		(1u<<15)

/*the rest is optional extensions*/
#define UF_ALPHA		(1u<<16)
#define UF_SCALE		(1u<<17)
#define UF_BONEDATA		(1u<<18)
#define UF_DRAWFLAGS	(1u<<19)
#define UF_TAGINFO		(1u<<20)
#define UF_LIGHT		(1u<<21)
#define UF_TRAILEFFECT	(1u<<22)
#define UF_EXTEND3		(1u<<23)

#define UF_COLORMOD		(1u<<24)
#define UF_GLOW			(1u<<25)
#define UF_FATNESS		(1u<<26)
#define UF_MODELINDEX2  (1u<<27)
#define UF_GRAVITYDIR	(1u<<28)
#define UF_EFFECTS2_OLD	(1u<<29) /*specified >8bit effects, replaced with variable length*/
#define UF_UNUSED1		(1u<<30)
#define UF_EXTEND4		(1u<<31)

/*these flags are generally not deltaed as they're changing constantly*/
#define UFP_FORWARD		(1u<<0)
#define UFP_SIDE		(1u<<1)
#define UFP_UP			(1u<<2)
#define UFP_MOVETYPE	(1u<<3)	/*deltaed*/
#define UFP_VELOCITYXY	(1u<<4)
#define UFP_VELOCITYZ	(1u<<5)
#define UFP_MSEC		(1u<<6)
#define UFP_WEAPONFRAME_OLD	(1u<<7)	//no longer used. just a stat now that I rewrote stat deltas.
#define UFP_VIEWANGLE	(1u<<7)

#define UF_SV_REMOVE   UF_16BIT_LERPTIME	/*special flag  - lerptime isn't delta tracked serverside (reset sent as required with other fields)*/



#ifdef NQPROT
//NQ svc_clientdata stat updates.
#define	SU_VIEWHEIGHT	(1<<0)
#define	SU_IDEALPITCH	(1<<1)
#define	SU_PUNCH1		(1<<2)
#define	SU_PUNCH2		(1<<3)
#define	SU_PUNCH3		(1<<4)
#define	SU_VELOCITY1	(1<<5)
#define	SU_VELOCITY2	(1<<6)
#define	SU_VELOCITY3	(1<<7)
//define	SU_AIMENT		(1<<8)  AVAILABLE BIT
#define	SU_ITEMS		(1<<9)
#define	SU_ONGROUND		(1<<10)		// no data follows, the bit is it
#define	SU_INWATER		(1<<11)		// no data follows, the bit is it
#define	SU_WEAPONFRAME	(1<<12)
#define	SU_ARMOR		(1<<13)
#define	SU_WEAPONMODEL	(1<<14)
#define	SU_EXTEND1		(1<<15)

#define FITZSU_WEAPONMODEL2	(1<<16) // 1 byte, this is .weaponmodel & 0xFF00 (second byte)
#define FITZSU_ARMOR2		(1<<17) // 1 byte, this is .armorvalue & 0xFF00 (second byte)
#define FITZSU_AMMO2		(1<<18) // 1 byte, this is .currentammo & 0xFF00 (second byte)
#define FITZSU_SHELLS2		(1<<19) // 1 byte, this is .ammo_shells & 0xFF00 (second byte)
#define FITZSU_NAILS2		(1<<20) // 1 byte, this is .ammo_nails & 0xFF00 (second byte)
#define FITZSU_ROCKETS2		(1<<21) // 1 byte, this is .ammo_rockets & 0xFF00 (second byte)
#define FITZSU_CELLS2		(1<<22) // 1 byte, this is .ammo_cells & 0xFF00 (second byte)
#define SU_EXTEND2		(1<<23) // another byte to follow

#define FITZSU_WEAPONFRAME2	(1<<24) // 1 byte, this is .weaponframe & 0xFF00 (second byte)
#define FITZSU_WEAPONALPHA	(1<<25) // 1 byte, this is alpha for weaponmodel, uses ENTALPHA_ENCODE, not sent if ENTALPHA_DEFAULT
#define FITZSU_UNUSED26		(1<<26)
#define FITZSU_UNUSED27		(1<<27)
#define FITZSU_UNUSED28		(1<<28)
#define FITZSU_UNUSED29		(1<<29)
#define FITZSU_UNUSED30		(1<<30)
#define SU_EXTEND3		(1<<31) // another byte to follow, future expansion

//builds on top of fitz
#define	QEX_SU_FLOATCOORDS	(1<<8)
#define QEX_SU_ENTFLAGS		(1<<26)	// ULEB128 copy of the player's .flags field

// first extend byte
#define DPSU_PUNCHVEC1		(1<<16)
#define DPSU_PUNCHVEC2		(1<<17)
#define DPSU_PUNCHVEC3		(1<<18)
#define DPSU_VIEWZOOM		(1<<19) // byte factor (0 = 0.0 (not valid), 255 = 1.0)
#define DPSU_UNUSED20		(1<<20)
#define DPSU_UNUSED21		(1<<21)
#define DPSU_UNUSED22		(1<<22)
// second extend byte
#define DPSU_UNUSED24		(1<<24)
#define DPSU_UNUSED25		(1<<25)
#define DPSU_UNUSED26		(1<<26)
#define DPSU_UNUSED27		(1<<27)
#define DPSU_UNUSED28		(1<<28)
#define DPSU_UNUSED29		(1<<29)
#define DPSU_UNUSED30		(1<<30)



//NQ fast updates
#define	NQU_MOREBITS	(1<<0)
#define	NQU_ORIGIN1	(1<<1)
#define	NQU_ORIGIN2	(1<<2)
#define	NQU_ORIGIN3	(1<<3)
#define	NQU_ANGLE2	(1<<4)
#define	NQU_NOLERP	(1<<5)		// don't interpolate movement
#define	NQU_FRAME		(1<<6)
#define NQU_SIGNAL	(1<<7)		// just differentiates from other updates

// svc_update can pass all of the fast update bits, plus more
#define	NQU_ANGLE1	(1<<8)
#define	NQU_ANGLE3	(1<<9)
#define	NQU_MODEL		(1<<10)
#define	NQU_COLORMAP	(1<<11)
#define	NQU_SKIN		(1<<12)
#define	NQU_EFFECTS	(1<<13)
#define	NQU_LONGENTITY	(1<<14)


// LordHavoc's: protocol extension
#define DPU_EXTEND1		(1<<15)
// LordHavoc: first extend byte
#define DPU_DELTA			(1<<16) // no data, while this is set the entity is delta compressed (uses previous frame as a baseline, meaning only things that have changed from the previous frame are sent, except for the forced full update every half second)
#define DPU_ALPHA			(1<<17) // 1 byte, 0.0-1.0 maps to 0-255, not sent if exactly 1, and the entity is not sent if <=0 unless it has effects (model effects are checked as well)
#define DPU_SCALE			(1<<18) // 1 byte, scale / 16 positive, not sent if 1.0
#define DPU_EFFECTS2		(1<<19) // 1 byte, this is .effects & 0xFF00 (second byte)
#define DPU_GLOWSIZE		(1<<20) // 1 byte, encoding is float/4.0, unsigned, not sent if 0
#define DPU_GLOWCOLOR		(1<<21) // 1 byte, palette index, default is 254 (white), this IS used for darklight (allowing colored darklight), however the particles from a darklight are always black, not sent if default value (even if glowsize or glowtrail is set)
// LordHavoc: colormod feature has been removed, because no one used it
#define DPU_COLORMOD		(1<<22) // 1 byte, 3 bit red, 3 bit green, 2 bit blue, this lets you tint an object artifically, so you could make a red rocket, or a blue fiend...
#define DPU_EXTEND2		(1<<23) // another byte to follow
// LordHavoc: second extend byte
#define DPU_GLOWTRAIL		(1<<24) // leaves a trail of particles (of color .glowcolor, or black if it is a negative glowsize)
#define DPU_VIEWMODEL		(1<<25) // attachs the model to the view (origin and angles become relative to it), only shown to owner, a more powerful alternative to .weaponmodel and such
#define DPU_FRAME2		(1<<26) // 1 byte, this is .frame & 0xFF00 (second byte)
#define DPU_MODEL2		(1<<27) // 1 byte, this is .modelindex & 0xFF00 (second byte)
#define DPU_EXTERIORMODEL	(1<<28) // causes this model to not be drawn when using a first person view (third person will draw it, first person will not)
#define DPU_UNUSED29		(1<<29) // future expansion
#define DPU_UNUSED30		(1<<30) // future expansion
#define DPU_EXTEND3		(1<<31) // another byte to follow, future expansion

#define FITZU_ALPHA			(1<<16)
#define FITZU_FRAME2		(1<<17)
#define FITZU_MODEL2		(1<<18)
#define FITZU_LERPFINISH	(1<<19)
#define RMQU_SCALE			(1<<20)

#define QE_U_FLOATCOORDS	(1<<21)	//set on the local player entity, to boost precision for prediction.
#define QE_U_SOLIDTYPE		(1<<22)	//for prediction I suppose.
//#define QE_U_EXTEND		(1<<23)
#define QE_U_ENTFLAGS		(1<<24)	//not sure why this needs to be networked, oh well. redundant with clientdata
#define QE_U_HEALTH			(1<<25)	//not sure why this needs to be networked, oh well.
#define QE_U_UNKNOWN26		(1<<26)	//seems to be some sort of nodraw flag (presumably for solid bmodels that need a modelindex for collisions).
#define QE_U_UNUSED27		(1<<27)
#define QE_U_UNUSED28		(1<<28)
#define QE_U_UNUSED29		(1<<29)
#define QE_U_UNUSED30		(1<<30)
#define QE_U_UNUSED31		(1u<<31)

#endif



#define	Q2U_ORIGIN1	(1<<0)
#define	Q2U_ORIGIN2	(1<<1)
#define	Q2U_ANGLE2	(1<<2)
#define	Q2U_ANGLE3	(1<<3)
#define	Q2U_FRAME8	(1<<4)		// frame is a qbyte
#define	Q2U_EVENT		(1<<5)
#define	Q2U_REMOVE	(1<<6)		// REMOVE this entity, don't add it
#define	Q2U_MOREBITS1	(1<<7)		// read one additional qbyte

// second qbyte
#define	Q2U_NUMBER16	(1<<8)		// NUMBER8 is implicit if not set
#define	Q2U_ORIGIN3	(1<<9)
#define	Q2U_ANGLE1	(1<<10)
#define	Q2U_MODEL		(1<<11)
#define Q2U_RENDERFX8	(1<<12)		// fullbright, etc
#define Q2UX_ANGLE16	(1<<13)
#define	Q2U_EFFECTS8	(1<<14)		// autorotate, trails, etc
#define	Q2U_MOREBITS2	(1<<15)		// read one additional qbyte

// third qbyte
#define	Q2U_SKIN8		(1<<16)
#define	Q2U_FRAME16	(1<<17)		// frame is a short
#define	Q2U_RENDERFX16 (1<<18)	// 8 + 16 = 32
#define	Q2U_EFFECTS16	(1<<19)		// 8 + 16 = 32
#define	Q2U_MODEL2	(1<<20)		// weapons, flags, etc
#define	Q2U_MODEL3	(1<<21)
#define	Q2U_MODEL4	(1<<22)
#define	Q2U_MOREBITS3	(1<<23)		// read one additional qbyte

// fourth qbyte
#define	Q2U_OLDORIGIN	(1<<24)		// FIXME: get rid of this
#define	Q2U_SKIN16	(1<<25)
#define	Q2U_SOUND		(1<<26)
#define	Q2U_SOLID		(1<<27)
#define Q2UX_INDEX16	(1<<28)		//model or sound is 16bit
#define Q2UX_UNUSED3	(1<<29)
#define Q2UX_UNUSED2	(1<<30)
#define Q2UX_UNUSED1	(1<<31)

#define Q2UX_UNUSED		(Q2UX_UNUSED1|Q2UX_UNUSED2|Q2UX_UNUSED3|Q2UX_UNUSED4)

//QuakeEx-specific stuff
//gamevar info
#define QEX_GV_DEATHMATCH		(1<<0)
#define QEX_GV_IDEALPITCHSCALE	(1<<1)
#define QEX_GV_FRICTION			(1<<2)
#define QEX_GV_EDGEFRICTION		(1<<3)
#define QEX_GV_STOPSPEED		(1<<4)
#define QEX_GV_MAXVELOCITY		(1<<5)
#define QEX_GV_GRAVITY			(1<<6)
#define QEX_GV_NOSTEP			(1<<7)
#define QEX_GV_MAXSPEED			(1<<8)
#define QEX_GV_ACCELERATE		(1<<9)
#define QEX_GV_CONTROLLERONLY	(1<<10)
#define QEX_GV_TIMELIMIT		(1<<11)
#define QEX_GV_FRAGLIMIT		(1<<12)
#define QEX_GV_TEAMPLAY			(1<<13)
#define QEX_GV_ALL				((1<<14)-1)

//==============================================
//obsolete demo players info
#define DF_ORIGINX		(1u<<0)
#define DF_ORIGINY		(1u<<1)
#define DF_ORIGINZ		(1u<<2)
#define DF_ORIGINALL	(DF_ORIGINX|DF_ORIGINY|DF_ORIGINZ)
#define DF_ANGLEX		(1u<<3)
#define DF_ANGLEY		(1u<<4)
#define DF_ANGLEZ		(1u<<5)
#define DF_ANGLESALL	(DF_ANGLEX|DF_ANGLEY|DF_ANGLEZ)
#define DF_EFFECTS		(1u<<6)
#define DF_SKINNUM		(1u<<7)
#define DF_DEAD			(1u<<8)
#define DF_GIB			(1u<<9)
#define DF_WEAPONFRAME	(1u<<10)
#define DF_MODEL		(1u<<11)
#define DF_RESET (DF_ORIGINALL|DF_ANGLESALL|DF_EFFECTS|DF_SKINNUM|DF_WEAPONFRAME|DF_MODEL)

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

// a sound with no channel is a local only sound
// the sound field has bits 0-2: channel, 3-12: entity, 13: unused, 14-15: flags
#define	QWSND_VOLUME		(1<<15)		// a qbyte
#define	QWSND_ATTENUATION	(1<<14)		// a qbyte

#define	NQSND_VOLUME		(1<<0)		// a qbyte
#define	NQSND_ATTENUATION	(1<<1)		// a qbyte
//#define DPSND_LOOPING		(1<<2)		// a long, supposedly
#define FTESND_MOREFLAGS	(1<<2)		// actually, chan flags, mostly.
#define NQSND_LARGEENTITY	(1<<3)		//both dp+fitz
#define NQSND_LARGESOUND	(1<<4)		//both dp+fitz
#define	DPSND_SPEEDUSHORT4000	(1<<5)		// ushort speed*4000 (speed is usually 1.0, a value of 0.0 is the same as 1.0)
#define FTESND_TIMEOFS		(1<<6)		//signed short, in milliseconds.
#define FTESND_PITCHADJ		(1<<7)			//a byte (speed percent (0=100%))
//more flags are weird.
#define FTESND_VELOCITY		(CF_NET_SENTVELOCITY<<8)	//borrowed.
//FTESND_NOSPACIALISE		(CF_NOSPACIALISE<<8)
//FTESND_NOREVERB			(CF_NOREVERB<<8)
//FTESND_FORCELOOP			(CF_FORCELOOP<<8)
//FTESND_FOLLOW				(CF_FOLLOW<<8)
//FTESND_RESERVED			(CF_RESERVEDN<<8)

#define DEFAULT_SOUND_PACKET_VOLUME 255
#define DEFAULT_SOUND_PACKET_ATTENUATION 1.0

//baseline flags
#define FITZ_B_LARGEMODEL	(1<<0)
#define FITZ_B_LARGEFRAME	(1<<1)
#define FITZ_B_ALPHA		(1<<2)
#define RMQFITZ_B_SCALE		(1<<3)

#define QEX_B_SOLID			(1<<3)
#define QEX_B_UNKNOWN4		(1<<4)
#define QEX_B_UNKNOWN5		(1<<5)
#define QEX_B_UNKNOWN6		(1<<6)
#define QEX_B_UNKNOWN7		(1<<7)

#define	DEFAULT_VIEWHEIGHT	22


// svc_print messages have an id, so messages can be filtered
#define	PRINT_LOW			0
#define	PRINT_MEDIUM		1
#define	PRINT_HIGH			2
#define	PRINT_CHAT			3	// also go to chat buffer

//
// temp entity events
//
enum {
	TE_SPIKE				= 0,
	TE_SUPERSPIKE			= 1,
	TEQW_QWGUNSHOT			= 2,	//qw has count byte, nq does not
	TENQ_NQGUNSHOT			= 2,	//nq has no count byte
	TEQW_QWEXPLOSION		= 3,	//remapped to TEQW_EXPLOSIONNOSPRITE for nq.
	TENQ_NQEXPLOSION		= 3,	//remapped to TEQW_EXPLOSIONNOSPRITE for nq.
	TE_TAREXPLOSION			= 4,
	TE_LIGHTNING1			= 5,
	TE_LIGHTNING2			= 6,
	TE_WIZSPIKE				= 7,
	TE_KNIGHTSPIKE			= 8,
	TE_LIGHTNING3			= 9,
	TE_LAVASPLASH			= 10,
	TE_TELEPORT				= 11,

	TEQW_QWBLOOD			= 12,	//implemented as a particle() in nq
	TENQ_EXPLOSION2			= 12,	//remapped to TEQW_EXPLOSION2 for qw
	TEQW_LIGHTNINGBLOOD		= 13,	//implemented as a particle() in nq
	TENQ_BEAM				= 13,	//remapped to TEQW_BEAM for qw

#ifdef PEXT_TE_BULLET
	TE_BULLET				= 14,
	TEQW_SUPERBULLET		= 15,
#endif
	TENQ_RAILTRAIL			= 15,	//gah	[vector] origin [coord] red [coord] green [coord] blue
	TE_EXPLOSION3_NEH		= 16,	//gah	[vector] origin [coord] red [coord] green [coord] blue
	TEQW_RAILTRAIL			= 17,	//use the builtin, luke.
	TENQ_NEHLIGHTNING4		= 17,	//gah	[string] model [entity] entity [vector] start [vector] end
	TEQW_NEHLIGHTNING4		= 1000,	//give a real value if its ever properly implemented
	TEQW_BEAM				= 18,	//use the builtin, luke.
	TENQ_NEHSMOKE			= 18,	//gah	[vector] origin [byte] palette
	TEQW_EXPLOSION2			= 19,	//use the builtin, luke.
	TEQW_NQEXPLOSION		= 20,	//nq-style explosion over qw
	TENQ_QWEXPLOSION		= 20,	//qw-style explosion over nq
	TEQW_NQGUNSHOT			= 21,	//nq has count byte, qw does not
	TENQ_QWGUNSHOT			= 21,	//nq has count byte, qw does not

	// hexen 2
	TEH2_STREAM_LIGHTNING_SMALL	= 24,
	TEH2_STREAM_CHAIN			= 25,
	TEH2_STREAM_SUNSTAFF1		= 26,
	TEH2_STREAM_SUNSTAFF2		= 27,
	TEH2_STREAM_LIGHTNING		= 28,
	TEH2_STREAM_COLORBEAM		= 29,
	TEH2_STREAM_ICECHUNKS		= 30,
	TEH2_STREAM_GAZE			= 31,
	TEH2_STREAM_FAMINE		= 32,
	TEH2_PARTICLEEXPLOSION = 33,

	TEDP_BLOOD			= 50, // [coord*3] origin [byte*3] vel [byte] count
	TEDP_SPARK			= 51,
	TEDP_BLOODSHOWER	= 52,
	TEDP_EXPLOSIONRGB	= 53,
	TEDP_PARTICLECUBE	= 54,
	TEDP_PARTICLERAIN	= 55, // [vector] min [vector] max [vector] dir [short] count [byte] color
	TEDP_PARTICLESNOW	= 56, // [vector] min [vector] max [vector] dir [short] count [byte] color
	TEDP_GUNSHOTQUAD	= 57, // [vector] origin
	TEDP_SPIKEQUAD		= 58, // [vector] origin
	TEDP_SUPERSPIKEQUAD	= 59, // [vector] origin
	TEDP_EXPLOSIONQUAD	= 70, // [vector] origin
	TEDP_SMALLFLASH		= 72, // [vector] origin
	TEDP_CUSTOMFLASH	= 73,
	TEDP_FLAMEJET		= 74,
	TEDP_PLASMABURN		= 75,
	TEDP_TEI_G3			= 76,
	TEDP_SMOKE			= 77,
	TEDP_TEI_BIGEXPLOSION = 78,
	TEDP_TEI_PLASMAHIT	= 79,
};


#define CTE_CUSTOMCOUNT		1
#define CTE_CUSTOMDIRECTION	2
#define CTE_STAINS			4
#define CTE_GLOWS			8
#define CTE_CHANNELFADE		16
#define CTE_CUSTOMVELOCITY	32
#define CTE_PERSISTANT		64
#define CTE_ISBEAM			128
//CTE_ISBEAM && (CTE_CUSTOMVELOCITY||CTE_CUSTOMDIRECTION) = BOX particles.

//FTE's version of TEI_SHOWLMP2. tei's values and coding scheme which makes no sense to anyone but him.
#define SL_ORG_NW	0
#define SL_ORG_NE	1
#define SL_ORG_SW	2
#define SL_ORG_SE	3
#define SL_ORG_CC	4
#define SL_ORG_CN	5
#define SL_ORG_CS	6
#define SL_ORG_CW	7
#define SL_ORG_CE	8

//relative coding where offsets are predictable
#define SL_ORG_TL	20
#define SL_ORG_TR	21
#define SL_ORG_BL	22
#define SL_ORG_BR	23
#define SL_ORG_MM	24
#define SL_ORG_TM	25
#define SL_ORG_BM	26
#define SL_ORG_ML	27
#define SL_ORG_MR	28

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

  ELEMENTS COMMUNICATED ACROSS THE NET

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

#define	MAX_CLIENTS		255	/*max 255, min 32*/
#define	QWMAX_CLIENTS	32 /*QW's standard max. clients might have issues above this value*/
#define	NQMAX_CLIENTS	16 /*NQ's standard max. clients might have issues above this value*/

#define	UPDATE_BACKUP	64	// copies of entity_state_t to keep buffered
							// must be power of two
#define	UPDATE_MASK		(UPDATE_BACKUP-1)

#define	Q2UPDATE_BACKUP	16	// copies of entity_state_t to keep buffered
							// must be power of two
#define	Q2UPDATE_MASK		(Q2UPDATE_BACKUP-1)

#define	Q3UPDATE_BACKUP	32	// copies of entity_state_t to keep buffered
							// must be power of two
#define	Q3UPDATE_MASK		(Q3UPDATE_BACKUP-1)


// entity_state_t is the information conveyed from the server
// in an update message

typedef struct entity_state_s
{
	unsigned int		number;			// edict index
	unsigned int		sequence;

	unsigned short		modelindex;
	qbyte				inactiveflag;
	qbyte				bonecount;		//for networked bones
	unsigned int		boneoffset;		//offset into the frame (not a pointer, to avoid issues with reallocing extra storage)

//	unsigned int		eflags;			// nolerp, etc

	unsigned int		effects;

	vec3_t	origin;
	vec3_t	angles;
	union
	{
#if defined(Q2CLIENT) || defined(Q2SERVER)
		struct
		{
			int		renderfx;		//q2
			vec3_t	old_origin;		//q2/q3

			unsigned short		modelindex3;	//q2
			unsigned short		modelindex4;	//q2
			unsigned short		sound;			//q2
			qbyte				event;			//q2
		} q2;
#endif
		struct
		{
			/*info to predict other players, so I don't get yelled at if fte were to stop supporting it*/
			qbyte pmovetype;	//&128 means onground.
			qbyte msec;
			short vangle[3];

			short movement[3];
			short velocity[3]; // 1/8th

			unsigned short weaponframe;
			unsigned char gravitydir[2];	//pitch/yaw, no roll

			unsigned short traileffectnum;
			unsigned short emiteffectnum;

			vec3_t predorg;
		} q1;
	} u;

	unsigned short		modelindex2;	//q2/vweps
	unsigned short		frame;

	unsigned short		baseframe;
	qbyte				basebone;
	qbyte				pad;

	unsigned int		skinnum; /*for q2 this often contains rgba*/

	unsigned short		colormap;
	qbyte glowsize;
	qbyte glowcolour;

	qbyte	scale;	//4.4 precision
	char	fatness;
	qbyte	hexen2flags;
	qbyte	abslight;

	qbyte	dpflags;
	qbyte	colormod[3];//3.5 precision

	qbyte	glowmod[3];	//3.5 precision
	qbyte	trans;	//254==1, 255==1-or-wateralpha

	unsigned short light[4];

	float lerpend;	//fitz rubbish

	qbyte lightstyle;
	qbyte lightpflags;
	unsigned short tagindex;	//~0 == weird portal thing.

	unsigned int tagentity;

	unsigned int solidsize;
#define ES_SOLID_NOT 0
#define ES_SOLID_BSP 31
#define ES_SOLID_HULL1 0x80201810
#define ES_SOLID_HULL2 0x80401820
#define ES_SOLID_HAS_EXTRA_BITS(solid) ((solid&0x0707) || (((solid>>16)-32768+32) & 7))
} entity_state_t;
extern entity_state_t nullentitystate;


#define MAX_EXTENDED_PACKET_ENTITIES	256	//sanity limit.
#define	MAX_STANDARD_PACKET_ENTITIES	64	// doesn't count nails
#define	MAX_MVDPACKET_ENTITIES	196	// doesn't count nails
typedef struct
{
	float			servertime;
	int				num_entities;
	int				max_entities;
	entity_state_t	*entities;
	int				fixangles[MAX_SPLITS];	//these should not be in here
	vec3_t			fixedangles[MAX_SPLITS];
	vec3_t			punchangle[MAX_SPLITS];
	vec3_t			punchorigin[MAX_SPLITS];

	qbyte			*bonedata;
	size_t			bonedatacur;
	size_t			bonedatamax;
} packet_entities_t;

struct vrdevinfo_s
{
	unsigned int	status;
#define VRSTATUS_ORG	(1u<<0)
#define VRSTATUS_ANG	(1u<<1)
#define VRSTATUS_VEL	(1u<<2)
#define VRSTATUS_AVEL	(1u<<3)
	short			angles[3];
	short			avelocity[3];
	vec3_t			origin;
	vec3_t			velocity;
	unsigned int	weapon;
#define VRDEV_LEFT	0
#define VRDEV_RIGHT	1
#define VRDEV_HEAD	2
#define VRDEV_COUNT	3
};
typedef struct usercmd_s
{
	short	angles[3];
	signed int		forwardmove,sidemove,upmove;
	unsigned int	impulse;
	unsigned int	lightlevel;

	unsigned int	sequence;	// just for debugging prints
	float	msec;		//replace msec, but with more precision
	unsigned int buttons;	//replaces buttons, but with more bits.
	unsigned int weapon;//q3 has a separate weapon field to supplement impulse.
	unsigned int servertime;	//q3 networks the time in order to calculate msecs
	double	fservertime;//used as part of nq msec calcs
	double	fclienttime;//not used?

	//prydon cursor crap
	vec2_t	cursor_screen;
	vec3_t	cursor_start;
	vec3_t	cursor_impact;
	unsigned int	cursor_entitynumber;

	//vr things
	struct vrdevinfo_s vr[VRDEV_COUNT];	//left, right, head.
} usercmd_t;

typedef struct q2usercmd_s
{	//visible to gamecode so can't be changed (and the prediction code)
	qbyte	msec;
	qbyte	buttons;
	short	angles[3];
	short	forwardmove, sidemove, upmove;
	qbyte	impulse;
	qbyte	lightlevel;
} q2usercmd_t;

typedef struct q1usercmd_s
{	//as written to qwd demos so can't be changed.
	qbyte	msec;
	vec3_t	angles;
	short	forwardmove, sidemove, upmove;
	qbyte	buttons;
	qbyte	impulse;
} q1usercmd_t;
#define SHORT2ANGLE(x) (x) * (360.0/65536)
#define ANGLE2SHORT(x) (x) * (65536/360.0)




//
// per-level limits
//
#define	Q2MAX_CLIENTS			256		// absolute limit
#define	Q2MAX_EDICTS			1024	// must change protocol to increase more
#define	Q2MAX_LIGHTSTYLES		256
#define	Q2MAX_MODELS			256		// these are sent over the net as bytes
#define	Q2MAX_SOUNDS			256		// so they cannot be blindly increased
#define	Q2MAX_IMAGES			256
#define	Q2MAX_ITEMS				256
#define Q2MAX_GENERAL			(Q2MAX_CLIENTS*2)	// general config strings


#define	Q2CS_NAME				0
#define	Q2CS_CDTRACK			1
#define	Q2CS_SKY				2
#define	Q2CS_SKYAXIS			3		// %f %f %f format
#define	Q2CS_SKYROTATE			4
#define	Q2CS_STATUSBAR			5		// display program string

#define Q2CS_AIRACCEL			29		// air acceleration control
#define	Q2CS_MAXCLIENTS			30
#define	Q2CS_MAPCHECKSUM		31		// for catching cheater maps

#define	Q2CS_MODELS				32
#define	Q2CS_SOUNDS				(Q2CS_MODELS	+Q2MAX_MODELS)
#define	Q2CS_IMAGES				(Q2CS_SOUNDS	+Q2MAX_SOUNDS)
#define	Q2CS_LIGHTS				(Q2CS_IMAGES	+Q2MAX_IMAGES)
#define	Q2CS_ITEMS				(Q2CS_LIGHTS	+Q2MAX_LIGHTSTYLES)
#define	Q2CS_PLAYERSKINS		(Q2CS_ITEMS		+Q2MAX_ITEMS)
#define Q2CS_GENERAL			(Q2CS_PLAYERSKINS	+Q2MAX_CLIENTS)
#define	Q2MAX_CONFIGSTRINGS		(Q2CS_GENERAL	+Q2MAX_GENERAL)


// player_state->stats[] indexes
#define Q2STAT_HEALTH_ICON		0
#define	Q2STAT_HEALTH				1
#define	Q2STAT_AMMO_ICON			2
#define	Q2STAT_AMMO				3
#define	Q2STAT_ARMOR_ICON			4
#define	Q2STAT_ARMOR				5
#define	Q2STAT_SELECTED_ICON		6
#define	Q2STAT_PICKUP_ICON		7
#define	Q2STAT_PICKUP_STRING		8
#define	Q2STAT_TIMER_ICON			9
#define	Q2STAT_TIMER				10
#define	Q2STAT_HELPICON			11
#define	Q2STAT_SELECTED_ITEM		12
#define	Q2STAT_LAYOUTS			13
#define	Q2STAT_FRAGS				14
#define	Q2STAT_FLASHES			15		// cleared each frame, 1 = health, 2 = armor
#define Q2STAT_CHASE				16
#define Q2STAT_SPECTATOR			17

#define	Q2MAX_STATS				32


//for the local player
#define	Q2PS_M_TYPE				(1<<0)
#define	Q2PS_M_ORIGIN			(1<<1)
#define	Q2PS_M_VELOCITY			(1<<2)
#define	Q2PS_M_TIME				(1<<3)
#define	Q2PS_M_FLAGS			(1<<4)
#define	Q2PS_M_GRAVITY			(1<<5)
#define	Q2PS_M_DELTA_ANGLES		(1<<6)
#define	Q2PS_VIEWOFFSET			(1<<7)
#define	Q2PS_VIEWANGLES			(1<<8)
#define	Q2PS_KICKANGLES			(1<<9)
#define	Q2PS_BLEND				(1<<10)
#define	Q2PS_FOV				(1<<11)
#define	Q2PS_WEAPONINDEX		(1<<12)
#define	Q2PS_WEAPONFRAME		(1<<13)
#define	Q2PS_RDFLAGS			(1<<14)
#define	Q2PS_EXTRABITS			(1<<15)
#define Q2PS_INDEX16			(1<<16)
#define Q2PS_CLIENTNUM			(1<<17)
#define Q2PS_UNUSED6			(1<<18)
#define Q2PS_UNUSED5			(1<<19)
#define Q2PS_UNUSED4			(1<<20)
#define Q2PS_UNUSED3			(1<<21)
#define Q2PS_UNUSED2			(1<<22)
#define Q2PS_UNUSED1			(1<<23)

#define Q2PSX_GUNOFFSET			(1<<0)
#define Q2PSX_GUNANGLES			(1<<1)
#define Q2PSX_M_VELOCITY2		(1<<2)
#define Q2PSX_M_ORIGIN2			(1<<3)
#define Q2PSX_VIEWANGLE2		(1<<4)
#define Q2PSX_STATS				(1<<5)
#define Q2PSX_CLIENTNUM			(1<<6)
#define Q2PSX_OLD				(1<<8)	//not part of the protocol, just lazy handling.


// entity_state_t->renderfx flags
#define	Q2RF_MINLIGHT			(1u<<0)		//ni	always have some light (viewmodel)
#define	RF_EXTERNALMODEL		(1u<<1)		//i 	don't draw through eyes, only mirrors
#define	RF_WEAPONMODEL			(1u<<2)		//i 	only draw through eyes
#define	RF_FULLBRIGHT			(1u<<3)		//i 	always draw full intensity
#define	RF_DEPTHHACK			(1u<<4)		//i 	for view weapon Z crunching
#define	RF_TRANSLUCENT			(1u<<5)		//forces shader sort order and BEF_FORCETRANSPARENT
#define	Q2RF_FRAMELERP			(1u<<6)		//q2only
#define Q2RF_BEAM				(1u<<7)		//mostly q2only

#define	Q2RF_CUSTOMSKIN			(1u<<8)		//not even in q2		skin is an index in image_precache
#define	Q2RF_GLOW				(1u<<9)		//i		pulse lighting for bonus items
#define Q2RF_SHELL_RED			(1u<<10)	//q2only
#define	Q2RF_SHELL_GREEN		(1u<<11)	//q2only
#define Q2RF_SHELL_BLUE			(1u<<12)	//q2only

//ROGUE
#define Q2RF_IR_VISIBLE			(1u<<15)	// shows red with Q2RDF_IRGOGGLES
#define	Q2RF_SHELL_DOUBLE		(1u<<16)	//q2only
#define	Q2RF_SHELL_HALF_DAM		(1u<<17)	//q2only
#define Q2RF_USE_DISGUISE		(1u<<18)	//ni	entity is displayed with skin 'players/$MODEL/disguise.pcx' instead
//ROGUE

#define RF_ADDITIVE				(1u<<19)	//forces shader sort order and BEF_FORCEADDITIVE
#define RF_NOSHADOW				(1u<<20)	//disables shadow casting
#define RF_NODEPTHTEST			(1u<<21)	//forces shader sort order and BEF_FORCENODEPTH
#define RF_FORCECOLOURMOD		(1u<<22)	//forces BEF_FORCECOLOURMOD
#define RF_WEAPONMODELNOBOB		(1u<<23)
#define RF_FIRSTPERSON			(1u<<24)	//only draw through eyes
#define	RF_XFLIP				(1u<<25)	//flip horizontally (for q2's left-handed weapons)

// player_state_t->refdef flags
#define	RDF_UNDERWATER			(1u<<0)		// warp the screen as apropriate (fov trick)
#define RDF_NOWORLDMODEL		(1u<<1)		// used for player configuration screen
//ROGUE
#define	Q2RDF_IRGOGGLES			(1u<<2)		//ents with Q2RF_IR_VISIBLE show up pure red.
#define Q2RDF_UVGOGGLES			(1u<<3)		//usused / reserved
//ROGUE

#define RDF_BLOOM				(1u<<16)
#define RDF_FISHEYE				(1u<<17)
#define RDF_WATERWARP			(1u<<18)
#define RDF_CUSTOMPOSTPROC		(1u<<19)
#define RDF_ANTIALIAS			(1u<<20)	//fxaa, or possibly even just fsaa
#define RDF_RENDERSCALE			(1u<<21)
#define RDF_SCENEGAMMA			(1u<<22)
#define RDF_DISABLEPARTICLES	(1u<<23)	//mostly for skyrooms
#define RDF_SKIPSKY				(1u<<24)	//we drew a skyroom, skip drawing sky chains for this scene.
#define RDF_SKYROOMENABLED		(1u<<25)	//skyroom position is known, be prepared to draw the skyroom if its visible.

#define RDF_ALLPOSTPROC			(RDF_BLOOM|RDF_FISHEYE|RDF_WATERWARP|RDF_CUSTOMPOSTPROC|RDF_ANTIALIAS|RDF_SCENEGAMMA)	//these flags require rendering to an fbo for the various different post-processing shaders.





#define	Q2SND_VOLUME		(1u<<0)		// a qbyte
#define	Q2SND_ATTENUATION	(1u<<1)		// a qbyte
#define	Q2SND_POS			(1u<<2)		// three coordinates
#define	Q2SND_ENT			(1u<<3)		// a short 0-2: channel, 3-12: entity
#define	Q2SND_OFFSET		(1u<<4)		// a qbyte, msec offset from frame start
#define Q2SND_LARGEIDX		(1u<<5)		// idx is a short
#define Q2SND_LARGEPOS		(1u<<6)		// float coord
#define Q2SND_EXTRABITS		(1u<<7)		// unused for now, reserved.

#define Q2DEFAULT_SOUND_PACKET_VOLUME	1.0
#define Q2DEFAULT_SOUND_PACKET_ATTENUATION 1.0


#define ATTN_NONE	0
#define ATTN_NORM	1
#define CHAN_AUTO   0
#define CHAN_WEAPON 1
#define CHAN_VOICE  2
#define CHAN_ITEM   3
#define CHAN_BODY   4

#define	Q2MZ_BLASTER			0
#define Q2MZ_MACHINEGUN		1
#define	Q2MZ_SHOTGUN			2
#define	Q2MZ_CHAINGUN1		3
#define	Q2MZ_CHAINGUN2		4
#define	Q2MZ_CHAINGUN3		5
#define	Q2MZ_RAILGUN			6
#define	Q2MZ_ROCKET			7
#define	Q2MZ_GRENADE			8
#define	Q2MZ_LOGIN			9
#define	Q2MZ_LOGOUT			10
#define	Q2MZ_RESPAWN			11
#define	Q2MZ_BFG				12
#define	Q2MZ_SSHOTGUN			13
#define	Q2MZ_HYPERBLASTER		14
#define	Q2MZ_ITEMRESPAWN		15
// RAFAEL
#define Q2MZ_IONRIPPER		16
#define Q2MZ_BLUEHYPERBLASTER 17
#define Q2MZ_PHALANX			18
#define Q2MZ_SILENCED			128		// bit flag ORed with one of the above numbers

//ROGUE
#define Q2MZ_ETF_RIFLE		30
#define Q2MZ_UNUSED			31
#define Q2MZ_SHOTGUN2			32
#define Q2MZ_HEATBEAM			33
#define Q2MZ_BLASTER2			34
#define	Q2MZ_TRACKER			35
#define	Q2MZ_NUKE1			36
#define	Q2MZ_NUKE2			37
#define	Q2MZ_NUKE4			38
#define	Q2MZ_NUKE8			39
//ROGUE

//
// monster muzzle flashes
//
#define Q2MZ2_TANK_BLASTER_1				1
#define Q2MZ2_TANK_BLASTER_2				2
#define Q2MZ2_TANK_BLASTER_3				3
#define Q2MZ2_TANK_MACHINEGUN_1			4
#define Q2MZ2_TANK_MACHINEGUN_2			5
#define Q2MZ2_TANK_MACHINEGUN_3			6
#define Q2MZ2_TANK_MACHINEGUN_4			7
#define Q2MZ2_TANK_MACHINEGUN_5			8
#define Q2MZ2_TANK_MACHINEGUN_6			9
#define Q2MZ2_TANK_MACHINEGUN_7			10
#define Q2MZ2_TANK_MACHINEGUN_8			11
#define Q2MZ2_TANK_MACHINEGUN_9			12
#define Q2MZ2_TANK_MACHINEGUN_10			13
#define Q2MZ2_TANK_MACHINEGUN_11			14
#define Q2MZ2_TANK_MACHINEGUN_12			15
#define Q2MZ2_TANK_MACHINEGUN_13			16
#define Q2MZ2_TANK_MACHINEGUN_14			17
#define Q2MZ2_TANK_MACHINEGUN_15			18
#define Q2MZ2_TANK_MACHINEGUN_16			19
#define Q2MZ2_TANK_MACHINEGUN_17			20
#define Q2MZ2_TANK_MACHINEGUN_18			21
#define Q2MZ2_TANK_MACHINEGUN_19			22
#define Q2MZ2_TANK_ROCKET_1				23
#define Q2MZ2_TANK_ROCKET_2				24
#define Q2MZ2_TANK_ROCKET_3				25

#define Q2MZ2_INFANTRY_MACHINEGUN_1		26
#define Q2MZ2_INFANTRY_MACHINEGUN_2		27
#define Q2MZ2_INFANTRY_MACHINEGUN_3		28
#define Q2MZ2_INFANTRY_MACHINEGUN_4		29
#define Q2MZ2_INFANTRY_MACHINEGUN_5		30
#define Q2MZ2_INFANTRY_MACHINEGUN_6		31
#define Q2MZ2_INFANTRY_MACHINEGUN_7		32
#define Q2MZ2_INFANTRY_MACHINEGUN_8		33
#define Q2MZ2_INFANTRY_MACHINEGUN_9		34
#define Q2MZ2_INFANTRY_MACHINEGUN_10		35
#define Q2MZ2_INFANTRY_MACHINEGUN_11		36
#define Q2MZ2_INFANTRY_MACHINEGUN_12		37
#define Q2MZ2_INFANTRY_MACHINEGUN_13		38

#define Q2MZ2_SOLDIER_BLASTER_1			39
#define Q2MZ2_SOLDIER_BLASTER_2			40
#define Q2MZ2_SOLDIER_SHOTGUN_1			41
#define Q2MZ2_SOLDIER_SHOTGUN_2			42
#define Q2MZ2_SOLDIER_MACHINEGUN_1		43
#define Q2MZ2_SOLDIER_MACHINEGUN_2		44

#define Q2MZ2_GUNNER_MACHINEGUN_1			45
#define Q2MZ2_GUNNER_MACHINEGUN_2			46
#define Q2MZ2_GUNNER_MACHINEGUN_3			47
#define Q2MZ2_GUNNER_MACHINEGUN_4			48
#define Q2MZ2_GUNNER_MACHINEGUN_5			49
#define Q2MZ2_GUNNER_MACHINEGUN_6			50
#define Q2MZ2_GUNNER_MACHINEGUN_7			51
#define Q2MZ2_GUNNER_MACHINEGUN_8			52
#define Q2MZ2_GUNNER_GRENADE_1			53
#define Q2MZ2_GUNNER_GRENADE_2			54
#define Q2MZ2_GUNNER_GRENADE_3			55
#define Q2MZ2_GUNNER_GRENADE_4			56

#define Q2MZ2_CHICK_ROCKET_1				57

#define Q2MZ2_FLYER_BLASTER_1				58
#define Q2MZ2_FLYER_BLASTER_2				59

#define Q2MZ2_MEDIC_BLASTER_1				60

#define Q2MZ2_GLADIATOR_RAILGUN_1			61

#define Q2MZ2_HOVER_BLASTER_1				62

#define Q2MZ2_ACTOR_MACHINEGUN_1			63

#define Q2MZ2_SUPERTANK_MACHINEGUN_1		64
#define Q2MZ2_SUPERTANK_MACHINEGUN_2		65
#define Q2MZ2_SUPERTANK_MACHINEGUN_3		66
#define Q2MZ2_SUPERTANK_MACHINEGUN_4		67
#define Q2MZ2_SUPERTANK_MACHINEGUN_5		68
#define Q2MZ2_SUPERTANK_MACHINEGUN_6		69
#define Q2MZ2_SUPERTANK_ROCKET_1			70
#define Q2MZ2_SUPERTANK_ROCKET_2			71
#define Q2MZ2_SUPERTANK_ROCKET_3			72

#define Q2MZ2_BOSS2_MACHINEGUN_L1			73
#define Q2MZ2_BOSS2_MACHINEGUN_L2			74
#define Q2MZ2_BOSS2_MACHINEGUN_L3			75
#define Q2MZ2_BOSS2_MACHINEGUN_L4			76
#define Q2MZ2_BOSS2_MACHINEGUN_L5			77
#define Q2MZ2_BOSS2_ROCKET_1				78
#define Q2MZ2_BOSS2_ROCKET_2				79
#define Q2MZ2_BOSS2_ROCKET_3				80
#define Q2MZ2_BOSS2_ROCKET_4				81

#define Q2MZ2_FLOAT_BLASTER_1				82

#define Q2MZ2_SOLDIER_BLASTER_3			83
#define Q2MZ2_SOLDIER_SHOTGUN_3			84
#define Q2MZ2_SOLDIER_MACHINEGUN_3		85
#define Q2MZ2_SOLDIER_BLASTER_4			86
#define Q2MZ2_SOLDIER_SHOTGUN_4			87
#define Q2MZ2_SOLDIER_MACHINEGUN_4		88
#define Q2MZ2_SOLDIER_BLASTER_5			89
#define Q2MZ2_SOLDIER_SHOTGUN_5			90
#define Q2MZ2_SOLDIER_MACHINEGUN_5		91
#define Q2MZ2_SOLDIER_BLASTER_6			92
#define Q2MZ2_SOLDIER_SHOTGUN_6			93
#define Q2MZ2_SOLDIER_MACHINEGUN_6		94
#define Q2MZ2_SOLDIER_BLASTER_7			95
#define Q2MZ2_SOLDIER_SHOTGUN_7			96
#define Q2MZ2_SOLDIER_MACHINEGUN_7		97
#define Q2MZ2_SOLDIER_BLASTER_8			98
#define Q2MZ2_SOLDIER_SHOTGUN_8			99
#define Q2MZ2_SOLDIER_MACHINEGUN_8		100

// --- Xian shit below ---
#define	Q2MZ2_MAKRON_BFG					101
#define Q2MZ2_MAKRON_BLASTER_1			102
#define Q2MZ2_MAKRON_BLASTER_2			103
#define Q2MZ2_MAKRON_BLASTER_3			104
#define Q2MZ2_MAKRON_BLASTER_4			105
#define Q2MZ2_MAKRON_BLASTER_5			106
#define Q2MZ2_MAKRON_BLASTER_6			107
#define Q2MZ2_MAKRON_BLASTER_7			108
#define Q2MZ2_MAKRON_BLASTER_8			109
#define Q2MZ2_MAKRON_BLASTER_9			110
#define Q2MZ2_MAKRON_BLASTER_10			111
#define Q2MZ2_MAKRON_BLASTER_11			112
#define Q2MZ2_MAKRON_BLASTER_12			113
#define Q2MZ2_MAKRON_BLASTER_13			114
#define Q2MZ2_MAKRON_BLASTER_14			115
#define Q2MZ2_MAKRON_BLASTER_15			116
#define Q2MZ2_MAKRON_BLASTER_16			117
#define Q2MZ2_MAKRON_BLASTER_17			118
#define Q2MZ2_MAKRON_RAILGUN_1			119
#define	Q2MZ2_JORG_MACHINEGUN_L1			120
#define	Q2MZ2_JORG_MACHINEGUN_L2			121
#define	Q2MZ2_JORG_MACHINEGUN_L3			122
#define	Q2MZ2_JORG_MACHINEGUN_L4			123
#define	Q2MZ2_JORG_MACHINEGUN_L5			124
#define	Q2MZ2_JORG_MACHINEGUN_L6			125
#define	Q2MZ2_JORG_MACHINEGUN_R1			126
#define	Q2MZ2_JORG_MACHINEGUN_R2			127
#define	Q2MZ2_JORG_MACHINEGUN_R3			128
#define	Q2MZ2_JORG_MACHINEGUN_R4			129
#define Q2MZ2_JORG_MACHINEGUN_R5			130
#define	Q2MZ2_JORG_MACHINEGUN_R6			131
#define Q2MZ2_JORG_BFG_1					132
#define Q2MZ2_BOSS2_MACHINEGUN_R1			133
#define Q2MZ2_BOSS2_MACHINEGUN_R2			134
#define Q2MZ2_BOSS2_MACHINEGUN_R3			135
#define Q2MZ2_BOSS2_MACHINEGUN_R4			136
#define Q2MZ2_BOSS2_MACHINEGUN_R5			137

//ROGUE
#define	Q2MZ2_CARRIER_MACHINEGUN_L1		138
#define	Q2MZ2_CARRIER_MACHINEGUN_R1		139
#define	Q2MZ2_CARRIER_GRENADE				140
#define Q2MZ2_TURRET_MACHINEGUN			141
#define Q2MZ2_TURRET_ROCKET				142
#define Q2MZ2_TURRET_BLASTER				143
#define Q2MZ2_STALKER_BLASTER				144
#define Q2MZ2_DAEDALUS_BLASTER			145
#define Q2MZ2_MEDIC_BLASTER_2				146
#define	Q2MZ2_CARRIER_RAILGUN				147
#define	Q2MZ2_WIDOW_DISRUPTOR				148
#define	Q2MZ2_WIDOW_BLASTER				149
#define	Q2MZ2_WIDOW_RAIL					150
#define	Q2MZ2_WIDOW_PLASMABEAM			151		// PMM - not used
#define	Q2MZ2_CARRIER_MACHINEGUN_L2		152
#define	Q2MZ2_CARRIER_MACHINEGUN_R2		153
#define	Q2MZ2_WIDOW_RAIL_LEFT				154
#define	Q2MZ2_WIDOW_RAIL_RIGHT			155
#define	Q2MZ2_WIDOW_BLASTER_SWEEP1		156
#define	Q2MZ2_WIDOW_BLASTER_SWEEP2		157
#define	Q2MZ2_WIDOW_BLASTER_SWEEP3		158
#define	Q2MZ2_WIDOW_BLASTER_SWEEP4		159
#define	Q2MZ2_WIDOW_BLASTER_SWEEP5		160
#define	Q2MZ2_WIDOW_BLASTER_SWEEP6		161
#define	Q2MZ2_WIDOW_BLASTER_SWEEP7		162
#define	Q2MZ2_WIDOW_BLASTER_SWEEP8		163
#define	Q2MZ2_WIDOW_BLASTER_SWEEP9		164
#define	Q2MZ2_WIDOW_BLASTER_100			165
#define	Q2MZ2_WIDOW_BLASTER_90			166
#define	Q2MZ2_WIDOW_BLASTER_80			167
#define	Q2MZ2_WIDOW_BLASTER_70			168
#define	Q2MZ2_WIDOW_BLASTER_60			169
#define	Q2MZ2_WIDOW_BLASTER_50			170
#define	Q2MZ2_WIDOW_BLASTER_40			171
#define	Q2MZ2_WIDOW_BLASTER_30			172
#define	Q2MZ2_WIDOW_BLASTER_20			173
#define	Q2MZ2_WIDOW_BLASTER_10			174
#define	Q2MZ2_WIDOW_BLASTER_0				175
#define	Q2MZ2_WIDOW_BLASTER_10L			176
#define	Q2MZ2_WIDOW_BLASTER_20L			177
#define	Q2MZ2_WIDOW_BLASTER_30L			178
#define	Q2MZ2_WIDOW_BLASTER_40L			179
#define	Q2MZ2_WIDOW_BLASTER_50L			180
#define	Q2MZ2_WIDOW_BLASTER_60L			181
#define	Q2MZ2_WIDOW_BLASTER_70L			182
#define	Q2MZ2_WIDOW_RUN_1					183
#define	Q2MZ2_WIDOW_RUN_2					184
#define	Q2MZ2_WIDOW_RUN_3					185
#define	Q2MZ2_WIDOW_RUN_4					186
#define	Q2MZ2_WIDOW_RUN_5					187
#define	Q2MZ2_WIDOW_RUN_6					188
#define	Q2MZ2_WIDOW_RUN_7					189
#define	Q2MZ2_WIDOW_RUN_8					190
#define	Q2MZ2_CARRIER_ROCKET_1			191
#define	Q2MZ2_CARRIER_ROCKET_2			192
#define	Q2MZ2_CARRIER_ROCKET_3			193
#define	Q2MZ2_CARRIER_ROCKET_4			194
#define	Q2MZ2_WIDOW2_BEAMER_1				195
#define	Q2MZ2_WIDOW2_BEAMER_2				196
#define	Q2MZ2_WIDOW2_BEAMER_3				197
#define	Q2MZ2_WIDOW2_BEAMER_4				198
#define	Q2MZ2_WIDOW2_BEAMER_5				199
#define	Q2MZ2_WIDOW2_BEAM_SWEEP_1			200
#define	Q2MZ2_WIDOW2_BEAM_SWEEP_2			201
#define	Q2MZ2_WIDOW2_BEAM_SWEEP_3			202
#define	Q2MZ2_WIDOW2_BEAM_SWEEP_4			203
#define	Q2MZ2_WIDOW2_BEAM_SWEEP_5			204
#define	Q2MZ2_WIDOW2_BEAM_SWEEP_6			205
#define	Q2MZ2_WIDOW2_BEAM_SWEEP_7			206
#define	Q2MZ2_WIDOW2_BEAM_SWEEP_8			207
#define	Q2MZ2_WIDOW2_BEAM_SWEEP_9			208
#define	Q2MZ2_WIDOW2_BEAM_SWEEP_10		209
#define	Q2MZ2_WIDOW2_BEAM_SWEEP_11		210






#define MAX_MAP_AREA_BYTES		32

// edict->drawflags (hexen2 stuff)
#define MLS_MASK				7	// Model Light Style
#define MLS_NONE				0
#define MLS_FULLBRIGHT			1
#define MLS_POWERMODE			2
#define MLS_TORCH				3
#define MLS_TOTALDARK			4
#define MLS_UNUSED				4
#define MLS_ADDLIGHT			6
#define MLS_ABSLIGHT			(MLS_MASK)
#define SCALE_TYPE_MASK			(SCALE_TYPE_UNIFORM|SCALE_TYPE_XYONLY|SCALE_TYPE_ZONLY)
#define SCALE_TYPE_UNIFORM		0	// Scale X, Y, and Z
#define SCALE_TYPE_XYONLY		8	// Scale X and Y
#define SCALE_TYPE_ZONLY		16	// Scale Z
#define SCALE_TYPE_UNUSED		(SCALE_TYPE_XYONLY|SCALE_TYPE_ZONLY)
#define SCALE_ORIGIN_MASK		(SCALE_ORIGIN_TOP|SCALE_ORIGIN_BOTTOM|SCALE_ORIGIN_CENTER)
#define SCALE_ORIGIN_CENTER		0	// Scaling origin at object center
#define SCALE_ORIGIN_BOTTOM		32	// Scaling origin at object bottom
#define SCALE_ORIGIN_TOP		64	// Scaling origin at object top
#define SCALE_ORIGIN_ORIGIN		(SCALE_ORIGIN_TOP|SCALE_ORIGIN_BOTTOM)	// Scaling origin at object origin
#define DRF_TRANSLUCENT			128


//TENEBRAE_GFX_DLIGHTS
#define PFLAGS_NOSHADOW		1
#define PFLAGS_CORONA		2
#define PFLAGS_FULLDYNAMIC	128	//NOTE: this is a dp-ism. for tenebrae compat, this should be effects&16 and not pflags&128, as effects&16 already means something else

#define RENDER_STEP 1
#define RENDER_GLOWTRAIL 2
#define RENDER_VIEWMODEL 4
#define RENDER_EXTERIORMODEL 8
#define RENDER_LOWPRECISION 16 // send as low precision coordinates to save bandwidth
#define RENDER_COLORMAPPED 32
//#define RENDER_WORLDOBJECT 64
#define RENDER_COMPLEXANIMATION 128

//darkplaces protocols 5 to 7 use these
// reset all entity fields (typically used if status changed)
#define E5_FULLUPDATE (1<<0)
// E5_ORIGIN32=0: short[3] = s->origin[0] * 8, s->origin[1] * 8, s->origin[2] * 8
// E5_ORIGIN32=1: float[3] = s->origin[0], s->origin[1], s->origin[2]
#define E5_ORIGIN (1<<1)
// E5_ANGLES16=0: byte[3] = s->angle[0] * 256 / 360, s->angle[1] * 256 / 360, s->angle[2] * 256 / 360
// E5_ANGLES16=1: short[3] = s->angle[0] * 65536 / 360, s->angle[1] * 65536 / 360, s->angle[2] * 65536 / 360
#define E5_ANGLES (1<<2)
// E5_MODEL16=0: byte = s->modelindex
// E5_MODEL16=1: short = s->modelindex
#define E5_MODEL (1<<3)
// E5_FRAME16=0: byte = s->frame
// E5_FRAME16=1: short = s->frame
#define E5_FRAME (1<<4)
// byte = s->skin
#define E5_SKIN (1<<5)
// E5_EFFECTS16=0 && E5_EFFECTS32=0: byte = s->effects
// E5_EFFECTS16=1 && E5_EFFECTS32=0: short = s->effects
// E5_EFFECTS16=0 && E5_EFFECTS32=1: int = s->effects
// E5_EFFECTS16=1 && E5_EFFECTS32=1: int = s->effects
#define E5_EFFECTS (1<<6)
// bits >= (1<<8)
#define E5_EXTEND1 (1<<7)

// byte = s->renderflags
#define E5_FLAGS (1<<8)
// byte = bound(0, s->alpha * 255, 255)
#define E5_ALPHA (1<<9)
// byte = bound(0, s->scale * 16, 255)
#define E5_SCALE (1<<10)
// flag
#define E5_ORIGIN32 (1<<11)
// flag
#define E5_ANGLES16 (1<<12)
// flag
#define E5_MODEL16 (1<<13)
// byte = s->colormap
#define E5_COLORMAP (1<<14)
// bits >= (1<<16)
#define E5_EXTEND2 (1<<15)

// short = s->tagentity
// byte = s->tagindex
#define E5_ATTACHMENT (1<<16)
// short[4] = s->light[0], s->light[1], s->light[2], s->light[3]
// byte = s->lightstyle
// byte = s->lightpflags
#define E5_LIGHT (1<<17)
// byte = s->glowsize
// byte = s->glowcolor
#define E5_GLOW (1<<18)
// short = s->effects
#define E5_EFFECTS16 (1<<19)
// int = s->effects
#define E5_EFFECTS32 (1<<20)
// flag
#define E5_FRAME16 (1<<21)
// unused
#define E5_COLORMOD (1<<22)
// bits >= (1<<24)
#define E5_EXTEND3 (1<<23)

// unused
#define E5_GLOWMOD (1<<24)
// unused
#define E5_COMPLEXANIMATION (1<<25)
// unused
#define E5_TRAILEFFECTNUM (1<<26)
// unused
#define E5_UNUSED27 (1<<27)
// unused
#define E5_UNUSED28 (1<<28)
// unused
#define E5_UNUSED29 (1<<29)
// unused
#define E5_UNUSED30 (1<<30)
// bits2 > 0
#define E5_EXTEND4 (1u<<31)

#define E5_ALLUNUSED (E5_UNUSED27|E5_UNUSED28|E5_UNUSED29|E5_UNUSED30)
#define E5_SERVERPRIVATE (E5_EXTEND1|E5_EXTEND2|E5_EXTEND3|E5_EXTEND4)
#define E5_SERVERREMOVE E5_EXTEND1