shithub: qk2

Download patch

ref: b8f176fc34741b72fc6bbb6ab45cad33c2c0d717
parent: 61e35a208c16f339e39e5b4d6244e12ddcc980f7
author: Konstantinn Bonnet <[email protected]>
date: Mon Jun 29 09:48:48 EDT 2015

make ctf work

also fix a small botch in game/game.h

--- a/README
+++ b/README
@@ -1,32 +1,115 @@
 qk2 - (9) quake 2
 =================
-	- installation
-		. mk install
-		. mkdir -p $home/lib/quake2/baseq2
-		. dircp /n/quake2cd/baseq2 $home/lib/quake2/baseq2
-	- game dir for gamemode "dicks" is stored in $home/lib/quake2/dicks/
-	- tested on 386 and amd64 only
+port of linux/x11 quake2 to plan9front. tested on amd64 and 386 only.
+currently lacks music and has a breaker bug with non 4:3 resolutions.
+performance-wise, it works fairly well on VESA with lower resolutions, e.g.
+800x600. on my machines.
 
-horrors
--------
-	- rendering glitches and fault reads on resolutions not originally
-	  supported (anything other than 4:3)
-	- edict_t definitions merged without much looking
-	- plan9/misc.c: stupid posixish glob stuff
-	- plan9/udp.c mostly horrid
-	- portme: cd_9
-	- garbled stdout (Sys_ConsoleOutput): \r instead of \n
-	- cinematic palette is fucked up if you resize during playback
-	- sound only (sortof) works thanks to shitty workarounds
-	- ctf is untouched, so are rogue, xatrix
 
+installation
+------------
+besides building and installation, qk2 needs the data from its retail cd. those
+are to be installed in $home/lib/quake2/baseq2. in a complete install, that
+directory will contain pak^(0 1 2)^.pak, as well as the players and video
+directories. neither players (for single play) nor video are mandatory. all
+filenames should be lowercased.
+
+% mk install
+% mkdir -p $home/lib/quake2/baseq2/^(players video)
+% cd /n/quake2cd/baseq2/
+% cp *.pak $home/lib/quake2/baseq2/
+% for(i in (players video)){ dircp $i $home/lib/quake2/baseq2/$i }
+
+
+quake2 mods
+-----------
+quake2 mods are C code built as shared libraries (called "game modules"). here,
+the code will have to be ported to plan9, adapted to qk2, then built and loaded
+against it. this repo contains the code for the official ctf mod; how to build
+and use it is explained below.
+for the rest of this file, let $mod the name of a mod. the data for the mod is
+to be stored in $home/lib/quake2/$mod/.
+
+
+installing a mod
+----------------
+in general, to build a mod, the only things that need to be altered are the
+contents of game/, mkfile, and adding a mk.$mod file. game/ contains $mod's
+source code for its game module (assuming the rest is implemented by qk2).
+mk.$mod contains TARG (for installation), and a list of object files to
+compile, and of headers (cf. mk.ctf for an example). mkfile includes the
+mk.$mod to build everything in one step. for example, to install ctf (and its
+data files from the cd):
+
+% bind -bc ctf game
+% ed mkfile	# output elided
+,s/<mk.baseq2/<mk.ctf/
+w
+q
+% mk install	# copies $OS.out to $home/lib/$objtype/q2ctf
+% mk clean
+% unmount game
+% mkdir $home/lib/quake2/ctf
+% dircp /n/quake2cd/ctf $home/lib/quake2/ctf
+
+ctf can then be started with e.g.:
+
+% q2ctf +set game ctf +set ctf 1
+
+
+porting a mod
+-------------
+in the case you wish to play a mod which has not been ported, and have nothing
+better to do, you will need to port it yourself. fwiw, ctf and crbot-1.0 took
+me about 4-5 hours each (not including debugging). note that all of this
+assumes the mod only alters code for the game module (game/). if that's not
+the case, no standard operational procedure exists.
+
+having obtained the $mod's source code, you can use game/*.[ch] as reference
+for your porting efforts. one thing specific to qk2 is how header files are
+handled: most common headers, including game/q_shared.h, were merged into dat.h
+and fns.h. game/[gp]*.h were merged into game/game.h. game/game.h is
+unfortunately included in dat.h, as some required structure definitions vary
+from mod to mod. as such, a mod is required to have $mod/game.h, which defines
+anything necessary for common code to work.
+
+you'll also need to write mk.$mod (cf. mod installation instructions above).
+
+
+todo/bugs
+---------
+- rendering glitches and fault reads on resolutions not originally supported
+  (anything other than 4:3)
+- edict_t definitions merged without much looking
+- sys.c: stupid posixish glob stuff
+- udp.c mostly horrid; need to rewrite networking stuff to use plan9 semantics
+- portme: cdaudio
+- garbled stdout (Sys_ConsoleOutput): \r instead of \n
+- cinematic palette is fucked up if you resize during playback
+- sound only (sortof) works thanks to shitty workarounds; in particular, sound
+  buffer seems to be overwritten as its being written to /dev/audio
+- multiplayer menu bugs: memory leaks and bugged map list
+- compliling with -DPARANOID reveals hidden truths
+- video menu doesn't make sense anymore; options menu includes deprecated crap
+- (bjnh) clean up code more, plan9 C style everywhere
+- (bjnh) better performance, use asm from original release
+- (bjnh) redesign everything to be super cool
+
+
 differences with linux/x11 quake2
 ---------------------------------
-	- mouse wheel up and down recognized and useable (but parsing is ugly)
-	- mouse buttons have (correct) plan9 names
-	- arbitrary resolutions up to 4096x4096 allowed (ref/r_local.h) and
-	  resize by dragging window edges
-	- no dynamic linking → "modules" are statically linked
+- mouse wheel up and down recognized and useable (but parsing is ugly)
+- mouse buttons have (correct) plan9 names
+- arbitrary resolutions up to 4096x4096 allowed (dat.h) and resize by dragging
+  window edges; no fullscreen
+- no dynamic linking → "modules" are statically linked
+- merged headers: dat.h,fns.h,game/game.h
+- m_windowed cvar and IN_Grabm() for mouse grabbing
+- ungrabs mouse when menu or console are opened
+- removed some useless sys cvars
+- mproc stuff for not letting mouse escape too often whenever the use swipes it
+  probably sucks
+
 
 legal
 -----
--- a/ctf/g_ai.c
+++ b/ctf/g_ai.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 
@@ -125,11 +126,11 @@
 		if (self->monsterinfo.idle_time)
 		{
 			self->monsterinfo.idle (self);
-			self->monsterinfo.idle_time = level.time + 15 + random() * 15;
+			self->monsterinfo.idle_time = level.time + 15 + qrandom() * 15;
 		}
 		else
 		{
-			self->monsterinfo.idle_time = level.time + random() * 15;
+			self->monsterinfo.idle_time = level.time + qrandom() * 15;
 		}
 	}
 }
@@ -155,11 +156,11 @@
 		if (self->monsterinfo.idle_time)
 		{
 			self->monsterinfo.search (self);
-			self->monsterinfo.idle_time = level.time + 15 + random() * 15;
+			self->monsterinfo.idle_time = level.time + 15 + qrandom() * 15;
 		}
 		else
 		{
-			self->monsterinfo.idle_time = level.time + random() * 15;
+			self->monsterinfo.idle_time = level.time + qrandom() * 15;
 		}
 	}
 }
@@ -656,16 +657,16 @@
 	else if (skill->value >= 2)
 		chance *= 2;
 
-	if (random () < chance)
+	if (qrandom () < chance)
 	{
 		self->monsterinfo.attack_state = AS_MISSILE;
-		self->monsterinfo.attack_finished = level.time + 2*random();
+		self->monsterinfo.attack_finished = level.time + 2*qrandom();
 		return true;
 	}
 
 	if (self->flags & FL_FLY)
 	{
-		if (random() < 0.3)
+		if (qrandom() < 0.3)
 			self->monsterinfo.attack_state = AS_SLIDING;
 		else
 			self->monsterinfo.attack_state = AS_STRAIGHT;
@@ -750,7 +751,7 @@
 used by ai_run and ai_stand
 =============
 */
-qboolean ai_checkattack (edict_t *self, float dist)
+qboolean ai_checkattack (edict_t *self, float)
 {
 	vec3_t		temp;
 	qboolean	hesDeadJim;
--- a/ctf/g_chase.c
+++ b/ctf/g_chase.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 
--- a/ctf/g_cmds.c
+++ b/ctf/g_cmds.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 #include "m_player.h"
@@ -720,7 +721,8 @@
 }
 
 
-int PlayerSort (void const *a, void const *b)
+int
+PlayerSort(void *a, void *b)
 {
 	int		anum, bnum;
 
--- a/ctf/g_combat.c
+++ b/ctf/g_combat.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 
@@ -113,10 +114,10 @@
 SpawnDamage
 ================
 */
-void SpawnDamage (int type, vec3_t origin, vec3_t normal, int damage)
+void SpawnDamage (int type, vec3_t origin, vec3_t normal, int /*damage*/)
 {
-	if (damage > 255)
-		damage = 255;
+	//if (damage > 255)
+	//	damage = 255;
 	gi.WriteByte (svc_temp_entity);
 	gi.WriteByte (type);
 //	gi.WriteByte (damage);
@@ -155,10 +156,10 @@
 	gclient_t	*client;
 	int			save;
 	int			power_armor_type;
-	int			index;
+	int			index = 0;
 	int			damagePerCell;
 	int			pa_te_type;
-	int			power;
+	int			power = 0;
 	int			power_used;
 
 	if (!damage)
--- a/ctf/g_ctf.c
+++ b/ctf/g_ctf.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 #include "m_player.h"
@@ -213,10 +214,10 @@
 	{
 		if (!from->inuse)
 			continue;
-#if 0
+/*
 		if (from->solid == SOLID_NOT)
 			continue;
-#endif
+*/
 		for (j=0 ; j<3 ; j++)
 			eorg[j] = org[j] - (from->s.origin[j] + (from->mins[j] + from->maxs[j])*0.5);
 		if (VectorLength(eorg) > rad)
@@ -500,13 +501,13 @@
 Note that bonuses are not cumaltive.  You get one, they are in importance
 order.
 */
-void CTFFragBonuses(edict_t *targ, edict_t *inflictor, edict_t *attacker)
+void CTFFragBonuses(edict_t *targ, edict_t *, edict_t *attacker)
 {
 	int i;
 	edict_t *ent;
 	gitem_t *flag_item, *enemy_flag_item;
 	int otherteam;
-	edict_t *flag, *carrier;
+	edict_t *flag, *carrier = nil;
 	char *c;
 	vec3_t v1, v2;
 
@@ -625,7 +626,7 @@
 		return;
 	}
 
-	if (carrier && carrier != attacker) {
+	if (carrier != nil && carrier != attacker) {
 		VectorSubtract(targ->s.origin, carrier->s.origin, v1);
 		VectorSubtract(attacker->s.origin, carrier->s.origin, v1);
 
@@ -856,13 +857,13 @@
 	}
 }
 
-qboolean CTFDrop_Flag(edict_t *ent, gitem_t *item)
+void
+CTFDrop_Flag(edict_t *ent, gitem_t *)
 {
 	if (rand() & 1) 
 		gi.cprintf(ent, PRINT_HIGH, "Only lusers drop flags.\n");
 	else
 		gi.cprintf(ent, PRINT_HIGH, "Winners don't drop flags.\n");
-	return false;
 }
 
 static void CTFFlagThink(edict_t *ent)
@@ -1141,7 +1142,7 @@
 /*QUAKED info_player_team1 (1 0 0) (-16 -16 -24) (16 16 32)
 potential team1 spawning position for ctf games
 */
-void SP_info_player_team1(edict_t *self)
+void SP_info_player_team1(edict_t *)
 {
 }
 
@@ -1148,7 +1149,7 @@
 /*QUAKED info_player_team2 (0 0 1) (-16 -16 -24) (16 16 32)
 potential team2 spawning position for ctf games
 */
-void SP_info_player_team2(edict_t *self)
+void SP_info_player_team2(edict_t *)
 {
 }
 
@@ -1250,7 +1251,7 @@
 	if (distance < 64)
 		return;
 
-#if 0
+/*
 	if (distance > 256)
 		return;
 
@@ -1268,7 +1269,7 @@
 		CTFResetGrapple(self);
 		return;
 	}
-#endif
+*/
 
 	// adjust start for beam origin being in middle of a segment
 //	VectorMA (start, 8, f, start);
@@ -1278,18 +1279,17 @@
 //	end[2] = self->absmin[2] + self->size[2] / 2;
 
 	gi.WriteByte (svc_temp_entity);
-#if 1 //def USE_GRAPPLE_CABLE
 	gi.WriteByte (TE_GRAPPLE_CABLE);
 	gi.WriteShort (self->owner - g_edicts);
 	gi.WritePosition (self->owner->s.origin);
 	gi.WritePosition (end);
 	gi.WritePosition (offset);
-#else
+/* ! USE_GRAPPLE_CABLE
 	gi.WriteByte (TE_MEDIC_CABLE_ATTACK);
 	gi.WriteShort (self - g_edicts);
 	gi.WritePosition (end);
 	gi.WritePosition (start);
-#endif
+*/
 	gi.multicast (self->s.origin, MULTICAST_PVS);
 }
 
@@ -1435,13 +1435,13 @@
 	gi.sound (ent, CHAN_RELIABLE+CHAN_WEAPON, gi.soundindex("weapons/grapple/grfire.wav"), volume, ATTN_NORM, 0);
 	CTFFireGrapple (ent, start, forward, damage, CTF_GRAPPLE_SPEED, effect);
 
-#if 0
+/*
 	// send muzzle flash
 	gi.WriteByte (svc_muzzleflash);
 	gi.WriteShort (ent-g_edicts);
 	gi.WriteByte (MZ_BLASTER);
 	gi.multicast (ent->s.origin, MULTICAST_PVS);
-#endif
+*/
 
 	PlayerNoise(ent, start, PNOISE_WEAPON);
 }
@@ -1569,7 +1569,7 @@
 CTFScoreboardMessage
 ==================
 */
-void CTFScoreboardMessage (edict_t *ent, edict_t *killer)
+void CTFScoreboardMessage (edict_t *, edict_t *)
 {
 	char	entry[1024];
 	char	string[1400];
@@ -1620,7 +1620,6 @@
 	// print level name and exit rules
 	// add the clients in sorted order
 	*string = 0;
-	len = 0;
 
 	// team one
 	sprintf(string, "if 24 xv 8 yv 8 pic 24 endif "
@@ -1638,7 +1637,7 @@
 		if (i >= total[0] && i >= total[1])
 			break; // we're done
 
-#if 0 //ndef NEW_SCORE
+/* //ndef NEW_SCORE
 		// set up y
 		sprintf(entry, "yv %d ", 42 + i * 8);
 		if (maxsize - len > strlen(entry)) {
@@ -1645,9 +1644,8 @@
 			strcat(string, entry);
 			len = strlen(string);
 		}
-#else
+*/
 		*entry = 0;
-#endif
 
 		// left side
 		if (i < total[0]) {
@@ -1654,7 +1652,7 @@
 			cl = &game.clients[sorted[0][i]];
 			cl_ent = g_edicts + 1 + sorted[0][i];
 
-#if 0 //ndef NEW_SCORE
+/* //ndef NEW_SCORE
 			sprintf(entry+strlen(entry),
 			"xv 0 %s \"%3d %3d %-12.12s\" ",
 			(cl_ent == ent) ? "string2" : "string",
@@ -1664,7 +1662,7 @@
 
 			if (cl_ent->client->pers.inventory[ITEM_INDEX(flag2_item)])
 				strcat(entry, "xv 56 picn sbfctf2 ");
-#else
+*/
 			sprintf(entry+strlen(entry),
 				"ctf 0 %d %d %d %d ",
 				42 + i * 8,
@@ -1675,7 +1673,6 @@
 			if (cl_ent->client->pers.inventory[ITEM_INDEX(flag2_item)])
 				sprintf(entry + strlen(entry), "xv 56 yv %d picn sbfctf2 ",
 					42 + i * 8);
-#endif
 
 			if (maxsize - len > strlen(entry)) {
 				strcat(string, entry);
@@ -1689,7 +1686,7 @@
 			cl = &game.clients[sorted[1][i]];
 			cl_ent = g_edicts + 1 + sorted[1][i];
 
-#if 0 //ndef NEW_SCORE
+/* //ndef NEW_SCORE
 			sprintf(entry+strlen(entry),
 			"xv 160 %s \"%3d %3d %-12.12s\" ",
 			(cl_ent == ent) ? "string2" : "string",
@@ -1699,9 +1696,7 @@
 
 			if (cl_ent->client->pers.inventory[ITEM_INDEX(flag1_item)])
 				strcat(entry, "xv 216 picn sbfctf1 ");
-
-#else
-
+*/
 			sprintf(entry+strlen(entry),
 				"ctf 160 %d %d %d %d ",
 				42 + i * 8,
@@ -1712,7 +1707,6 @@
 			if (cl_ent->client->pers.inventory[ITEM_INDEX(flag1_item)])
 				sprintf(entry + strlen(entry), "xv 216 yv %d picn sbfctf1 ",
 					42 + i * 8);
-#endif
 			if (maxsize - len > strlen(entry)) {
 				strcat(string, entry);
 				len = strlen(string);
@@ -2633,7 +2627,6 @@
 {
 	int i;
 	edict_t *ent;
-	int ghost = 0;
 
 	ctfgame.match = MATCH_GAME;
 	ctfgame.matchtime = level.time + matchtime->value * 60;
@@ -2946,12 +2939,12 @@
 	{ "Return to Main Menu",			PMENU_ALIGN_LEFT, CTFReturnToMain }
 };
 
-static const int jmenu_level = 2;
-static const int jmenu_match = 3;
-static const int jmenu_red = 5;
-static const int jmenu_blue = 7;
-static const int jmenu_chase = 9;
-static const int jmenu_reqmatch = 11;
+static int jmenu_level = 2;
+static int jmenu_match = 3;
+static int jmenu_red = 5;
+static int jmenu_blue = 7;
+static int jmenu_chase = 9;
+static int jmenu_reqmatch = 11;
 
 pmenu_t joinmenu[] = {
 	{ "*Quake II",			PMENU_ALIGN_CENTER, NULL },
@@ -2971,7 +2964,7 @@
 	{ "ENTER to select",	PMENU_ALIGN_LEFT, NULL },
 	{ "ESC to Exit Menu",	PMENU_ALIGN_LEFT, NULL },
 	{ "(TAB to Return)",	PMENU_ALIGN_LEFT, NULL },
-	{ "v" CTF_STRING_VERSION,	PMENU_ALIGN_RIGHT, NULL },
+	{ "v" CTF_VERSION,	PMENU_ALIGN_RIGHT, NULL },
 };
 
 pmenu_t nochasemenu[] = {
@@ -3021,17 +3014,17 @@
 	}
 }
 
-void CTFJoinTeam1(edict_t *ent, pmenuhnd_t *p)
+void CTFJoinTeam1(edict_t *ent, pmenuhnd_t *)
 {
 	CTFJoinTeam(ent, CTF_TEAM1);
 }
 
-void CTFJoinTeam2(edict_t *ent, pmenuhnd_t *p)
+void CTFJoinTeam2(edict_t *ent, pmenuhnd_t *)
 {
 	CTFJoinTeam(ent, CTF_TEAM2);
 }
 
-void CTFChaseCam(edict_t *ent, pmenuhnd_t *p)
+void CTFChaseCam(edict_t *ent, pmenuhnd_t *)
 {
 	int i;
 	edict_t *e;
@@ -3058,13 +3051,13 @@
 	PMenu_Open(ent, nochasemenu, -1, sizeof(nochasemenu) / sizeof(pmenu_t), NULL);
 }
 
-void CTFReturnToMain(edict_t *ent, pmenuhnd_t *p)
+void CTFReturnToMain(edict_t *ent, pmenuhnd_t *)
 {
 	PMenu_Close(ent);
 	CTFOpenJoinMenu(ent);
 }
 
-void CTFRequestMatch(edict_t *ent, pmenuhnd_t *p)
+void CTFRequestMatch(edict_t *ent, pmenuhnd_t *)
 {
 	char text[1024];
 
@@ -3077,7 +3070,7 @@
 
 void DeathmatchScoreboard (edict_t *ent);
 
-void CTFShowScores(edict_t *ent, pmenu_t *p)
+void CTFShowScores(edict_t *ent, pmenu_t *)
 {
 	PMenu_Close(ent);
 
@@ -3194,7 +3187,7 @@
 	PMenu_Open(ent, joinmenu, team, sizeof(joinmenu) / sizeof(pmenu_t), NULL);
 }
 
-void CTFCredits(edict_t *ent, pmenuhnd_t *p)
+void CTFCredits(edict_t *ent, pmenuhnd_t *)
 {
 	PMenu_Close(ent);
 	PMenu_Open(ent, creditsmenu, -1, sizeof(creditsmenu) / sizeof(pmenu_t), NULL);
@@ -3344,7 +3337,7 @@
  * just here to help old map conversions
  *--------------------------------------------------------------------------*/
 
-static void old_teleporter_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
+static void old_teleporter_touch (edict_t *self, edict_t *other, cplane_t *, csurface_t *)
 {
 	edict_t		*dest;
 	int			i;
@@ -3552,10 +3545,8 @@
 	CTFOpenAdminMenu(ent);
 }
 
-void CTFAdmin_SettingsCancel(edict_t *ent, pmenuhnd_t *p)
+void CTFAdmin_SettingsCancel(edict_t *ent, pmenuhnd_t *)
 {
-	admin_settings_t *settings = p->arg;
-
 	PMenu_Close(ent);
 	CTFOpenAdminMenu(ent);
 }
@@ -3669,7 +3660,6 @@
 
 	sprintf(text, "Match Lock:      %s", settings->matchlock ? "Yes" : "No");
 	PMenu_UpdateEntry(setmenu->entries + i, text, PMENU_ALIGN_LEFT, CTFAdmin_ChangeMatchLock);
-	i++;
 
 	PMenu_Update(ent);
 }
@@ -3690,7 +3680,7 @@
 	{ "Cancel",			PMENU_ALIGN_LEFT, CTFAdmin_SettingsCancel }
 };
 
-void CTFAdmin_Settings(edict_t *ent, pmenuhnd_t *p)
+void CTFAdmin_Settings(edict_t *ent, pmenuhnd_t *)
 {
 	admin_settings_t *settings;
 	pmenuhnd_t *menu;
@@ -3712,7 +3702,7 @@
 	CTFAdmin_UpdateSettings(ent, menu);
 }
 
-void CTFAdmin_MatchSet(edict_t *ent, pmenuhnd_t *p)
+void CTFAdmin_MatchSet(edict_t *ent, pmenuhnd_t *)
 {
 	PMenu_Close(ent);
 
@@ -3728,7 +3718,7 @@
 	}
 }
 
-void CTFAdmin_MatchMode(edict_t *ent, pmenuhnd_t *p)
+void CTFAdmin_MatchMode(edict_t *ent, pmenuhnd_t *)
 {
 	PMenu_Close(ent);
 
@@ -3740,7 +3730,7 @@
 	}
 }
 
-void CTFAdmin_Cancel(edict_t *ent, pmenuhnd_t *p)
+void CTFAdmin_Cancel(edict_t *ent, pmenuhnd_t *)
 {
 	PMenu_Close(ent);
 }
@@ -3918,7 +3908,7 @@
 {
 	char text[1024];
 	char *mlist, *token;
-	static const char *seps = " \t\n\r";
+	static char *seps = " \t\n\r";
 
 	if (gi.argc() < 2) {
 		gi.cprintf(ent, PRINT_HIGH, "Where do you want to warp to?\n");
--- a/ctf/g_ctf.h
+++ /dev/null
@@ -1,165 +1,0 @@
-#define CTF_VERSION			1.09b
-#define CTF_VSTRING2(x) #x
-#define CTF_VSTRING(x) CTF_VSTRING2(x)
-#define CTF_STRING_VERSION  CTF_VSTRING(CTF_VERSION)
-
-#define STAT_CTF_TEAM1_PIC			17
-#define STAT_CTF_TEAM1_CAPS			18
-#define STAT_CTF_TEAM2_PIC			19
-#define STAT_CTF_TEAM2_CAPS			20
-#define STAT_CTF_FLAG_PIC			21
-#define STAT_CTF_JOINED_TEAM1_PIC	22
-#define STAT_CTF_JOINED_TEAM2_PIC	23
-#define STAT_CTF_TEAM1_HEADER		24
-#define STAT_CTF_TEAM2_HEADER		25
-#define STAT_CTF_TECH				26
-#define STAT_CTF_ID_VIEW			27
-#define STAT_CTF_MATCH				28
-
-#define CONFIG_CTF_MATCH (CS_MAXCLIENTS-1)
-
-typedef enum {
-	CTF_NOTEAM,
-	CTF_TEAM1,
-	CTF_TEAM2
-} ctfteam_t;
-
-typedef enum {
-	CTF_GRAPPLE_STATE_FLY,
-	CTF_GRAPPLE_STATE_PULL,
-	CTF_GRAPPLE_STATE_HANG
-} ctfgrapplestate_t;
-
-typedef struct ghost_s {
-	char netname[16];
-	int number;
-
-	// stats
-	int deaths;
-	int kills;
-	int caps;
-	int basedef;
-	int carrierdef;
-
-	int code; // ghost code
-	int team; // team
-	int score; // frags at time of disconnect
-	edict_t *ent;
-} ghost_t;
-
-extern cvar_t *ctf;
-
-#define CTF_TEAM1_SKIN "ctf_r"
-#define CTF_TEAM2_SKIN "ctf_b"
-
-#define DF_CTF_FORCEJOIN	131072	
-#define DF_ARMOR_PROTECT	262144
-#define DF_CTF_NO_TECH      524288
-
-#define CTF_CAPTURE_BONUS		15	// what you get for capture
-#define CTF_TEAM_BONUS			10	// what your team gets for capture
-#define CTF_RECOVERY_BONUS		1	// what you get for recovery
-#define CTF_FLAG_BONUS			0	// what you get for picking up enemy flag
-#define CTF_FRAG_CARRIER_BONUS	2	// what you get for fragging enemy flag carrier
-#define CTF_FLAG_RETURN_TIME	40	// seconds until auto return
-
-#define CTF_CARRIER_DANGER_PROTECT_BONUS	2	// bonus for fraggin someone who has recently hurt your flag carrier
-#define CTF_CARRIER_PROTECT_BONUS			1	// bonus for fraggin someone while either you or your target are near your flag carrier
-#define CTF_FLAG_DEFENSE_BONUS				1	// bonus for fraggin someone while either you or your target are near your flag
-#define CTF_RETURN_FLAG_ASSIST_BONUS		1	// awarded for returning a flag that causes a capture to happen almost immediately
-#define CTF_FRAG_CARRIER_ASSIST_BONUS		2	// award for fragging a flag carrier if a capture happens almost immediately
-
-#define CTF_TARGET_PROTECT_RADIUS			400	// the radius around an object being defended where a target will be worth extra frags
-#define CTF_ATTACKER_PROTECT_RADIUS			400	// the radius around an object being defended where an attacker will get extra frags when making kills
-
-#define CTF_CARRIER_DANGER_PROTECT_TIMEOUT	8
-#define CTF_FRAG_CARRIER_ASSIST_TIMEOUT		10
-#define CTF_RETURN_FLAG_ASSIST_TIMEOUT		10
-
-#define CTF_AUTO_FLAG_RETURN_TIMEOUT		30	// number of seconds before dropped flag auto-returns
-
-#define CTF_TECH_TIMEOUT					60  // seconds before techs spawn again
-
-#define CTF_GRAPPLE_SPEED					650 // speed of grapple in flight
-#define CTF_GRAPPLE_PULL_SPEED				650	// speed player is pulled at
-
-void CTFInit(void);
-void CTFSpawn(void);
-
-void SP_info_player_team1(edict_t *self);
-void SP_info_player_team2(edict_t *self);
-
-char *CTFTeamName(int team);
-char *CTFOtherTeamName(int team);
-void CTFAssignSkin(edict_t *ent, char *s);
-void CTFAssignTeam(gclient_t *who);
-edict_t *SelectCTFSpawnPoint (edict_t *ent);
-qboolean CTFPickup_Flag(edict_t *ent, edict_t *other);
-qboolean CTFDrop_Flag(edict_t *ent, gitem_t *item);
-void CTFEffects(edict_t *player);
-void CTFCalcScores(void);
-void SetCTFStats(edict_t *ent);
-void CTFDeadDropFlag(edict_t *self);
-void CTFScoreboardMessage (edict_t *ent, edict_t *killer);
-void CTFTeam_f (edict_t *ent);
-void CTFID_f (edict_t *ent);
-void CTFSay_Team(edict_t *who, char *msg);
-void CTFFlagSetup (edict_t *ent);
-void CTFResetFlag(int ctf_team);
-void CTFFragBonuses(edict_t *targ, edict_t *inflictor, edict_t *attacker);
-void CTFCheckHurtCarrier(edict_t *targ, edict_t *attacker);
-
-// GRAPPLE
-void CTFWeapon_Grapple (edict_t *ent);
-void CTFPlayerResetGrapple(edict_t *ent);
-void CTFGrapplePull(edict_t *self);
-void CTFResetGrapple(edict_t *self);
-
-//TECH
-gitem_t *CTFWhat_Tech(edict_t *ent);
-qboolean CTFPickup_Tech (edict_t *ent, edict_t *other);
-void CTFDrop_Tech(edict_t *ent, gitem_t *item);
-void CTFDeadDropTech(edict_t *ent);
-void CTFSetupTechSpawn(void);
-int CTFApplyResistance(edict_t *ent, int dmg);
-int CTFApplyStrength(edict_t *ent, int dmg);
-qboolean CTFApplyStrengthSound(edict_t *ent);
-qboolean CTFApplyHaste(edict_t *ent);
-void CTFApplyHasteSound(edict_t *ent);
-void CTFApplyRegeneration(edict_t *ent);
-qboolean CTFHasRegeneration(edict_t *ent);
-void CTFRespawnTech(edict_t *ent);
-void CTFResetTech(void);
-
-void CTFOpenJoinMenu(edict_t *ent);
-qboolean CTFStartClient(edict_t *ent);
-void CTFVoteYes(edict_t *ent);
-void CTFVoteNo(edict_t *ent);
-void CTFReady(edict_t *ent);
-void CTFNotReady(edict_t *ent);
-qboolean CTFNextMap(void);
-qboolean CTFMatchSetup(void);
-qboolean CTFMatchOn(void);
-void CTFGhost(edict_t *ent);
-void CTFAdmin(edict_t *ent);
-qboolean CTFInMatch(void);
-void CTFStats(edict_t *ent);
-void CTFWarp(edict_t *ent);
-void CTFBoot(edict_t *ent);
-void CTFPlayerList(edict_t *ent);
-
-qboolean CTFCheckRules(void);
-
-void SP_misc_ctf_banner (edict_t *ent);
-void SP_misc_ctf_small_banner (edict_t *ent);
-
-extern char *ctf_statusbar;
-
-void UpdateChaseCam(edict_t *ent);
-void ChaseNext(edict_t *ent);
-void ChasePrev(edict_t *ent);
-
-void CTFObserver(edict_t *ent);
-
-void SP_trigger_teleport (edict_t *ent);
-void SP_info_teleport_destination (edict_t *ent);
--- a/ctf/g_func.c
+++ b/ctf/g_func.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 
@@ -409,7 +410,7 @@
 }
 
 
-void Use_Plat (edict_t *ent, edict_t *other, edict_t *activator)
+void Use_Plat (edict_t *ent, edict_t *, edict_t *)
 { 
 	if (ent->think)
 		return;		// already down
@@ -417,7 +418,7 @@
 }
 
 
-void Touch_Plat_Center (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
+void Touch_Plat_Center (edict_t *ent, edict_t *other, cplane_t *, csurface_t *)
 {
 	if (!other->client)
 		return;
@@ -581,13 +582,13 @@
 	T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
 }
 
-void rotating_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
+void rotating_touch (edict_t *self, edict_t *other, cplane_t *, csurface_t *)
 {
 	if (self->avelocity[0] || self->avelocity[1] || self->avelocity[2])
 		T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
 }
 
-void rotating_use (edict_t *self, edict_t *other, edict_t *activator)
+void rotating_use (edict_t *self, edict_t *, edict_t *)
 {
 	if (!VectorCompare (self->avelocity, vec3_origin))
 	{
@@ -718,13 +719,13 @@
 	Move_Calc (self, self->moveinfo.end_origin, button_wait);
 }
 
-void button_use (edict_t *self, edict_t *other, edict_t *activator)
+void button_use (edict_t *self, edict_t *, edict_t *activator)
 {
 	self->activator = activator;
 	button_fire (self);
 }
 
-void button_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
+void button_touch (edict_t *self, edict_t *other, cplane_t *, csurface_t *)
 {
 	if (!other->client)
 		return;
@@ -736,7 +737,7 @@
 	button_fire (self);
 }
 
-void button_killed (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
+void button_killed (edict_t *self, edict_t *, edict_t *attacker, int, vec3_t)
 {
 	self->activator = attacker;
 	self->health = self->max_health;
@@ -930,7 +931,7 @@
 	door_use_areaportals (self, true);
 }
 
-void door_use (edict_t *self, edict_t *other, edict_t *activator)
+void door_use (edict_t *self, edict_t *, edict_t *activator)
 {
 	edict_t	*ent;
 
@@ -961,7 +962,7 @@
 	}
 };
 
-void Touch_DoorTrigger (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
+void Touch_DoorTrigger (edict_t *self, edict_t *other, cplane_t *, csurface_t *)
 {
 	if (other->health <= 0)
 		return;
@@ -1094,7 +1095,7 @@
 	}
 }
 
-void door_killed (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
+void door_killed (edict_t *self, edict_t *, edict_t *attacker, int, vec3_t)
 {
 	edict_t	*ent;
 
@@ -1106,7 +1107,7 @@
 	door_use (self->teammaster, attacker, attacker);
 }
 
-void door_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
+void door_touch (edict_t *self, edict_t *other, cplane_t *, csurface_t *)
 {
 	if (!other->client)
 		return;
@@ -1613,7 +1614,7 @@
 	}
 }
 
-void train_use (edict_t *self, edict_t *other, edict_t *activator)
+void train_use (edict_t *self, edict_t *, edict_t *activator)
 {
 	self->activator = activator;
 
@@ -1679,7 +1680,7 @@
 
 /*QUAKED trigger_elevator (0.3 0.1 0.6) (-8 -8 -8) (8 8 8)
 */
-void trigger_elevator_use (edict_t *self, edict_t *other, edict_t *activator)
+void trigger_elevator_use (edict_t *self, edict_t *other, edict_t *)
 {
 	edict_t *target;
 
@@ -1757,7 +1758,7 @@
 	self->nextthink = level.time + self->wait + crandom() * self->random;
 }
 
-void func_timer_use (edict_t *self, edict_t *other, edict_t *activator)
+void func_timer_use (edict_t *self, edict_t *, edict_t *activator)
 {
 	self->activator = activator;
 
@@ -1805,7 +1806,7 @@
 speed	default 100
 */
 
-void func_conveyor_use (edict_t *self, edict_t *other, edict_t *activator)
+void func_conveyor_use (edict_t *self, edict_t *, edict_t *)
 {
 	if (self->spawnflags & 1)
 	{
@@ -1866,7 +1867,7 @@
 void door_secret_move6 (edict_t *self);
 void door_secret_done (edict_t *self);
 
-void door_secret_use (edict_t *self, edict_t *other, edict_t *activator)
+void door_secret_use (edict_t *self, edict_t *, edict_t *)
 {
 	// make sure we're not already moving
 	if (!VectorCompare(self->s.origin, vec3_origin))
@@ -1940,7 +1941,7 @@
 	T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, self->dmg, 1, 0, MOD_CRUSH);
 }
 
-void door_secret_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
+void door_secret_die (edict_t *self, edict_t *, edict_t *attacker, int, vec3_t)
 {
 	self->takedamage = DAMAGE_NO;
 	door_secret_use (self, attacker, attacker);
@@ -2017,7 +2018,7 @@
 /*QUAKED func_killbox (1 0 0) ?
 Kills everything inside when fired, irrespective of protection.
 */
-void use_killbox (edict_t *self, edict_t *other, edict_t *activator)
+void use_killbox (edict_t *self, edict_t *, edict_t *)
 {
 	KillBox (self);
 }
--- a/ctf/g_items.c
+++ b/ctf/g_items.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 
@@ -705,7 +706,7 @@
 	return POWER_ARMOR_NONE;
 }
 
-void Use_PowerArmor (edict_t *ent, gitem_t *item)
+void Use_PowerArmor (edict_t *ent, gitem_t *)
 {
 	int		index;
 
@@ -761,7 +762,7 @@
 Touch_Item
 ===============
 */
-void Touch_Item (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
+void Touch_Item (edict_t *ent, edict_t *other, cplane_t *, csurface_t *)
 {
 	qboolean	taken;
 
@@ -895,7 +896,7 @@
 	return dropped;
 }
 
-void Use_Item (edict_t *ent, edict_t *other, edict_t *activator)
+void Use_Item (edict_t *ent, edict_t *, edict_t *)
 {
 	ent->svflags &= ~SVF_NOCLIENT;
 	ent->use = NULL;
@@ -1589,10 +1590,9 @@
 /* precache */ "sprites/s_bfg1.sp2 sprites/s_bfg2.sp2 sprites/s_bfg3.sp2 weapons/bfg__f1y.wav weapons/bfg__l1a.wav weapons/bfg__x1b.wav weapons/bfg_hum.wav"
 	},
 
-#if 0
-//ZOID
 /*QUAKED weapon_laser (.3 .3 1) (-16 -16 -16) (16 16 16)
 */
+/*
 	{
 		"weapon_laser",
 		Pickup_Weapon,
@@ -1602,8 +1602,8 @@
 		"misc/w_pkup.wav",
 		"models/weapons/g_laser/tris.md2", EF_ROTATE,
 		"models/weapons/v_laser/tris.md2",
-/* icon */		"w_bfg",
-/* pickup */	"Flashlight Laser",
+			"w_bfg",
+		"Flashlight Laser",
 		0,
 		1,
 		"Cells",
@@ -1611,9 +1611,9 @@
 		0,
 		NULL,
 		0,
-/* precache */ ""
+		""
 	},
-#endif
+*/
 
 	//
 	// AMMO ITEMS
--- a/ctf/g_local.h
+++ /dev/null
@@ -1,1107 +1,0 @@
-// g_local.h -- local definitions for game module
-
-// define GAME_INCLUDE so that game.h does not define the
-// short, server-visible gclient_t and edict_t structures,
-// because we define the full size ones in this file
-#define	GAME_INCLUDE
-
-// the "gameversion" client command will print this plus compile date
-#define	GAMEVERSION	"baseq2"
-
-// protocol bytes that can be directly added to messages
-#define	svc_muzzleflash		1
-#define	svc_muzzleflash2	2
-#define	svc_temp_entity		3
-#define	svc_layout			4
-#define	svc_inventory		5
-
-//==================================================================
-
-// view pitching times
-#define DAMAGE_TIME		0.5
-#define	FALL_TIME		0.3
-
-
-// edict->spawnflags
-// these are set with checkboxes on each entity in the map editor
-#define	SPAWNFLAG_NOT_EASY			0x00000100
-#define	SPAWNFLAG_NOT_MEDIUM		0x00000200
-#define	SPAWNFLAG_NOT_HARD			0x00000400
-#define	SPAWNFLAG_NOT_DEATHMATCH	0x00000800
-#define	SPAWNFLAG_NOT_COOP			0x00001000
-
-// edict->flags
-#define	FL_FLY					0x00000001
-#define	FL_SWIM					0x00000002	// implied immunity to drowining
-#define FL_IMMUNE_LASER			0x00000004
-#define	FL_INWATER				0x00000008
-#define	FL_GODMODE				0x00000010
-#define	FL_NOTARGET				0x00000020
-#define FL_IMMUNE_SLIME			0x00000040
-#define FL_IMMUNE_LAVA			0x00000080
-#define	FL_PARTIALGROUND		0x00000100	// not all corners are valid
-#define	FL_WATERJUMP			0x00000200	// player jumping out of water
-#define	FL_TEAMSLAVE			0x00000400	// not the first on the team
-#define FL_NO_KNOCKBACK			0x00000800
-#define FL_POWER_ARMOR			0x00001000	// power armor (if any) is active
-#define FL_RESPAWN				0x80000000	// used for item respawning
-
-
-#define	FRAMETIME		0.1
-
-// memory tags to allow dynamic memory to be cleaned up
-#define	TAG_GAME	765		// clear when unloading the dll
-#define	TAG_LEVEL	766		// clear when loading a new level
-
-
-#define MELEE_DISTANCE	80
-
-#define BODY_QUEUE_SIZE		8
-
-typedef enum
-{
-	DAMAGE_NO,
-	DAMAGE_YES,			// will take damage if hit
-	DAMAGE_AIM			// auto targeting recognizes this
-} damage_t;
-
-typedef enum 
-{
-	WEAPON_READY, 
-	WEAPON_ACTIVATING,
-	WEAPON_DROPPING,
-	WEAPON_FIRING
-} weaponstate_t;
-
-typedef enum
-{
-	AMMO_BULLETS,
-	AMMO_SHELLS,
-	AMMO_ROCKETS,
-	AMMO_GRENADES,
-	AMMO_CELLS,
-	AMMO_SLUGS
-} ammo_t;
-
-
-//deadflag
-#define DEAD_NO					0
-#define DEAD_DYING				1
-#define DEAD_DEAD				2
-#define DEAD_RESPAWNABLE		3
-
-//range
-#define RANGE_MELEE				0
-#define RANGE_NEAR				1
-#define RANGE_MID				2
-#define RANGE_FAR				3
-
-//gib types
-#define GIB_ORGANIC				0
-#define GIB_METALLIC			1
-
-//monster ai flags
-#define AI_STAND_GROUND			0x00000001
-#define AI_TEMP_STAND_GROUND	0x00000002
-#define AI_SOUND_TARGET			0x00000004
-#define AI_LOST_SIGHT			0x00000008
-#define AI_PURSUIT_LAST_SEEN	0x00000010
-#define AI_PURSUE_NEXT			0x00000020
-#define AI_PURSUE_TEMP			0x00000040
-#define AI_HOLD_FRAME			0x00000080
-#define AI_GOOD_GUY				0x00000100
-#define AI_BRUTAL				0x00000200
-#define AI_NOSTEP				0x00000400
-#define AI_DUCKED				0x00000800
-#define AI_COMBAT_POINT			0x00001000
-#define AI_MEDIC				0x00002000
-#define AI_RESURRECTING			0x00004000
-
-//monster attack state
-#define AS_STRAIGHT				1
-#define AS_SLIDING				2
-#define	AS_MELEE				3
-#define	AS_MISSILE				4
-
-// armor types
-#define ARMOR_NONE				0
-#define ARMOR_JACKET			1
-#define ARMOR_COMBAT			2
-#define ARMOR_BODY				3
-#define ARMOR_SHARD				4
-
-// power armor types
-#define POWER_ARMOR_NONE		0
-#define POWER_ARMOR_SCREEN		1
-#define POWER_ARMOR_SHIELD		2
-
-// handedness values
-#define RIGHT_HANDED			0
-#define LEFT_HANDED				1
-#define CENTER_HANDED			2
-
-
-// game.serverflags values
-#define SFL_CROSS_TRIGGER_1		0x00000001
-#define SFL_CROSS_TRIGGER_2		0x00000002
-#define SFL_CROSS_TRIGGER_3		0x00000004
-#define SFL_CROSS_TRIGGER_4		0x00000008
-#define SFL_CROSS_TRIGGER_5		0x00000010
-#define SFL_CROSS_TRIGGER_6		0x00000020
-#define SFL_CROSS_TRIGGER_7		0x00000040
-#define SFL_CROSS_TRIGGER_8		0x00000080
-#define SFL_CROSS_TRIGGER_MASK	0x000000ff
-
-
-// noise types for PlayerNoise
-#define PNOISE_SELF				0
-#define PNOISE_WEAPON			1
-#define PNOISE_IMPACT			2
-
-
-// edict->movetype values
-typedef enum
-{
-MOVETYPE_NONE,			// never moves
-MOVETYPE_NOCLIP,		// origin and angles change with no interaction
-MOVETYPE_PUSH,			// no clip to world, push on box contact
-MOVETYPE_STOP,			// no clip to world, stops on box contact
-
-MOVETYPE_WALK,			// gravity
-MOVETYPE_STEP,			// gravity, special edge handling
-MOVETYPE_FLY,
-MOVETYPE_TOSS,			// gravity
-MOVETYPE_FLYMISSILE,	// extra size to monsters
-MOVETYPE_BOUNCE
-} movetype_t;
-
-
-
-typedef struct
-{
-	int		base_count;
-	int		max_count;
-	float	normal_protection;
-	float	energy_protection;
-	int		armor;
-} gitem_armor_t;
-
-
-// gitem_t->flags
-#define	IT_WEAPON		1		// use makes active weapon
-#define	IT_AMMO			2
-#define IT_ARMOR		4
-#define IT_STAY_COOP	8
-#define IT_KEY			16
-#define IT_POWERUP		32
-//ZOID
-#define IT_TECH			64
-//ZOID
-
-// gitem_t->weapmodel for weapons indicates model index
-#define WEAP_BLASTER			1 
-#define WEAP_SHOTGUN			2 
-#define WEAP_SUPERSHOTGUN		3 
-#define WEAP_MACHINEGUN			4 
-#define WEAP_CHAINGUN			5 
-#define WEAP_GRENADES			6 
-#define WEAP_GRENADELAUNCHER	7 
-#define WEAP_ROCKETLAUNCHER		8 
-#define WEAP_HYPERBLASTER		9 
-#define WEAP_RAILGUN			10
-#define WEAP_BFG				11
-#define WEAP_GRAPPLE			12
-
-typedef struct gitem_s
-{
-	char		*classname;	// spawning name
-	qboolean	(*pickup)(edict_t *ent, edict_t *other);
-	void		(*use)(edict_t *ent, struct gitem_s *item);
-	void		(*drop)(edict_t *ent, struct gitem_s *item);
-	void		(*weaponthink)(edict_t *ent);
-	char		*pickup_sound;
-	char		*world_model;
-	int			world_model_flags;
-	char		*view_model;
-
-	// client side info
-	char		*icon;
-	char		*pickup_name;	// for printing on pickup
-	int			count_width;		// number of digits to display by icon
-
-	int			quantity;		// for ammo how much, for weapons how much is used per shot
-	char		*ammo;			// for weapons
-	int			flags;			// IT_* flags
-
-	int			weapmodel;		// weapon model index (for weapons)
-
-	void		*info;
-	int			tag;
-
-	char		*precaches;		// string of all models, sounds, and images this item will use
-} gitem_t;
-
-
-
-//
-// this structure is left intact through an entire game
-// it should be initialized at dll load time, and read/written to
-// the server.ssv file for savegames
-//
-typedef struct
-{
-	char		helpmessage1[512];
-	char		helpmessage2[512];
-	int			helpchanged;	// flash F1 icon if non 0, play sound
-								// and increment only if 1, 2, or 3
-
-	gclient_t	*clients;		// [maxclients]
-
-	// can't store spawnpoint in level, because
-	// it would get overwritten by the savegame restore
-	char		spawnpoint[512];	// needed for coop respawns
-
-	// store latched cvars here that we want to get at often
-	int			maxclients;
-	int			maxentities;
-
-	// cross level triggers
-	int			serverflags;
-
-	// items
-	int			num_items;
-
-	qboolean	autosaved;
-} game_locals_t;
-
-
-//
-// this structure is cleared as each map is entered
-// it is read/written to the level.sav file for savegames
-//
-typedef struct
-{
-	int			framenum;
-	float		time;
-
-	char		level_name[MAX_QPATH];	// the descriptive name (Outer Base, etc)
-	char		mapname[MAX_QPATH];		// the server name (base1, etc)
-	char		nextmap[MAX_QPATH];		// go here when fraglimit is hit
-	char		forcemap[MAX_QPATH];	// go here
-
-	// intermission state
-	float		intermissiontime;		// time the intermission was started
-	char		*changemap;
-	int			exitintermission;
-	vec3_t		intermission_origin;
-	vec3_t		intermission_angle;
-
-	edict_t		*sight_client;	// changed once each frame for coop games
-
-	edict_t		*sight_entity;
-	int			sight_entity_framenum;
-	edict_t		*sound_entity;
-	int			sound_entity_framenum;
-	edict_t		*sound2_entity;
-	int			sound2_entity_framenum;
-
-	int			pic_health;
-
-	int			total_secrets;
-	int			found_secrets;
-
-	int			total_goals;
-	int			found_goals;
-
-	int			total_monsters;
-	int			killed_monsters;
-
-	edict_t		*current_entity;	// entity running from G_RunFrame
-	int			body_que;			// dead bodies
-
-	int			power_cubes;		// ugly necessity for coop
-} level_locals_t;
-
-
-// spawn_temp_t is only used to hold entity field values that
-// can be set from the editor, but aren't actualy present
-// in edict_t during gameplay
-typedef struct
-{
-	// world vars
-	char		*sky;
-	float		skyrotate;
-	vec3_t		skyaxis;
-	char		*nextmap;
-
-	int			lip;
-	int			distance;
-	int			height;
-	char		*noise;
-	float		pausetime;
-	char		*item;
-	char		*gravity;
-
-	float		minyaw;
-	float		maxyaw;
-	float		minpitch;
-	float		maxpitch;
-} spawn_temp_t;
-
-
-typedef struct
-{
-	// fixed data
-	vec3_t		start_origin;
-	vec3_t		start_angles;
-	vec3_t		end_origin;
-	vec3_t		end_angles;
-
-	int			sound_start;
-	int			sound_middle;
-	int			sound_end;
-
-	float		accel;
-	float		speed;
-	float		decel;
-	float		distance;
-
-	float		wait;
-
-	// state data
-	int			state;
-	vec3_t		dir;
-	float		current_speed;
-	float		move_speed;
-	float		next_speed;
-	float		remaining_distance;
-	float		decel_distance;
-	void		(*endfunc)(edict_t *);
-} moveinfo_t;
-
-
-typedef struct
-{
-	void	(*aifunc)(edict_t *self, float dist);
-	float	dist;
-	void	(*thinkfunc)(edict_t *self);
-} mframe_t;
-
-typedef struct
-{
-	int			firstframe;
-	int			lastframe;
-	mframe_t	*frame;
-	void		(*endfunc)(edict_t *self);
-} mmove_t;
-
-typedef struct
-{
-	mmove_t		*currentmove;
-	int			aiflags;
-	int			nextframe;
-	float		scale;
-
-	void		(*stand)(edict_t *self);
-	void		(*idle)(edict_t *self);
-	void		(*search)(edict_t *self);
-	void		(*walk)(edict_t *self);
-	void		(*run)(edict_t *self);
-	void		(*dodge)(edict_t *self, edict_t *other, float eta);
-	void		(*attack)(edict_t *self);
-	void		(*melee)(edict_t *self);
-	void		(*sight)(edict_t *self, edict_t *other);
-	qboolean	(*checkattack)(edict_t *self);
-
-	float		pausetime;
-	float		attack_finished;
-
-	vec3_t		saved_goal;
-	float		search_time;
-	float		trail_time;
-	vec3_t		last_sighting;
-	int			attack_state;
-	int			lefty;
-	float		idle_time;
-	int			linkcount;
-
-	int			power_armor_type;
-	int			power_armor_power;
-} monsterinfo_t;
-
-
-
-extern	game_locals_t	game;
-extern	level_locals_t	level;
-extern	game_import_t	gi;
-extern	game_export_t	globals;
-extern	spawn_temp_t	st;
-
-extern	int	sm_meat_index;
-extern	int	snd_fry;
-
-
-// means of death
-#define MOD_UNKNOWN			0
-#define MOD_BLASTER			1
-#define MOD_SHOTGUN			2
-#define MOD_SSHOTGUN		3
-#define MOD_MACHINEGUN		4
-#define MOD_CHAINGUN		5
-#define MOD_GRENADE			6
-#define MOD_G_SPLASH		7
-#define MOD_ROCKET			8
-#define MOD_R_SPLASH		9
-#define MOD_HYPERBLASTER	10
-#define MOD_RAILGUN			11
-#define MOD_BFG_LASER		12
-#define MOD_BFG_BLAST		13
-#define MOD_BFG_EFFECT		14
-#define MOD_HANDGRENADE		15
-#define MOD_HG_SPLASH		16
-#define MOD_WATER			17
-#define MOD_SLIME			18
-#define MOD_LAVA			19
-#define MOD_CRUSH			20
-#define MOD_TELEFRAG		21
-#define MOD_FALLING			22
-#define MOD_SUICIDE			23
-#define MOD_HELD_GRENADE	24
-#define MOD_EXPLOSIVE		25
-#define MOD_BARREL			26
-#define MOD_BOMB			27
-#define MOD_EXIT			28
-#define MOD_SPLASH			29
-#define MOD_TARGET_LASER	30
-#define MOD_TRIGGER_HURT	31
-#define MOD_HIT				32
-#define MOD_TARGET_BLASTER	33
-#define MOD_GRAPPLE			34
-#define MOD_FRIENDLY_FIRE	0x8000000
-
-extern	int	meansOfDeath;
-
-
-extern	edict_t			*g_edicts;
-
-#define	FOFS(x) (uintptr)&(((edict_t *)0)->x)
-#define	STOFS(x) (uintptr)&(((spawn_temp_t *)0)->x)
-#define	LLOFS(x) (uintptr)&(((level_locals_t *)0)->x)
-#define	CLOFS(x) (uintptr)&(((gclient_t *)0)->x)
-
-#define qrandom()	((rand () & 0x7fff) / ((float)0x7fff))
-#define crandom()	(2.0 * (qrandom() - 0.5))
-
-extern	cvar_t	*maxentities;
-extern	cvar_t	*deathmatch;
-extern	cvar_t	*coop;
-extern	cvar_t	*dmflags;
-extern	cvar_t	*skill;
-extern	cvar_t	*fraglimit;
-extern	cvar_t	*timelimit;
-//ZOID
-extern	cvar_t	*capturelimit;
-extern	cvar_t	*instantweap;
-//ZOID
-extern	cvar_t	*password;
-extern	cvar_t	*g_select_empty;
-extern	cvar_t	*dedicated;
-
-extern	cvar_t	*sv_gravity;
-extern	cvar_t	*sv_maxvelocity;
-
-extern	cvar_t	*gun_x, *gun_y, *gun_z;
-extern	cvar_t	*sv_rollspeed;
-extern	cvar_t	*sv_rollangle;
-
-extern	cvar_t	*run_pitch;
-extern	cvar_t	*run_roll;
-extern	cvar_t	*bob_up;
-extern	cvar_t	*bob_pitch;
-extern	cvar_t	*bob_roll;
-
-extern	cvar_t	*sv_cheats;
-extern	cvar_t	*maxclients;
-
-extern	cvar_t	*flood_msgs;
-extern	cvar_t	*flood_persecond;
-extern	cvar_t	*flood_waitdelay;
-
-extern	cvar_t	*sv_maplist;
-
-
-#define world	(&g_edicts[0])
-
-// item spawnflags
-#define ITEM_TRIGGER_SPAWN		0x00000001
-#define ITEM_NO_TOUCH			0x00000002
-// 6 bits reserved for editor flags
-// 8 bits used as power cube id bits for coop games
-#define DROPPED_ITEM			0x00010000
-#define	DROPPED_PLAYER_ITEM		0x00020000
-#define ITEM_TARGETS_USED		0x00040000
-
-//
-// fields are needed for spawning from the entity string
-// and saving / loading games
-//
-#define FFL_SPAWNTEMP		1
-
-typedef enum {
-	F_INT, 
-	F_FLOAT,
-	F_LSTRING,			// string on disk, pointer in memory, TAG_LEVEL
-	F_GSTRING,			// string on disk, pointer in memory, TAG_GAME
-	F_VECTOR,
-	F_ANGLEHACK,
-	F_EDICT,			// index on disk, pointer in memory
-	F_ITEM,				// index on disk, pointer in memory
-	F_CLIENT,			// index on disk, pointer in memory
-	F_IGNORE
-} fieldtype_t;
-
-typedef struct
-{
-	char	*name;
-	int		ofs;
-	fieldtype_t	type;
-	int		flags;
-} field_t;
-
-
-extern	field_t fields[];
-extern	gitem_t	itemlist[];
-
-
-//
-// g_cmds.c
-//
-qboolean CheckFlood(edict_t *ent);
-void Cmd_Help_f (edict_t *ent);
-void Cmd_Score_f (edict_t *ent);
-
-//
-// g_items.c
-//
-void PrecacheItem (gitem_t *it);
-void InitItems (void);
-void SetItemNames (void);
-gitem_t	*FindItem (char *pickup_name);
-gitem_t	*FindItemByClassname (char *classname);
-#define	ITEM_INDEX(x) ((x)-itemlist)
-edict_t *Drop_Item (edict_t *ent, gitem_t *item);
-void SetRespawn (edict_t *ent, float delay);
-void ChangeWeapon (edict_t *ent);
-void SpawnItem (edict_t *ent, gitem_t *item);
-void Think_Weapon (edict_t *ent);
-int ArmorIndex (edict_t *ent);
-int PowerArmorType (edict_t *ent);
-gitem_t	*GetItemByIndex (int index);
-qboolean Add_Ammo (edict_t *ent, gitem_t *item, int count);
-void Touch_Item (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf);
-
-//
-// g_utils.c
-//
-qboolean	KillBox (edict_t *ent);
-void	G_ProjectSource (vec3_t point, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result);
-edict_t *G_Find (edict_t *from, int fieldofs, char *match);
-edict_t *findradius (edict_t *from, vec3_t org, float rad);
-edict_t *G_PickTarget (char *targetname);
-void	G_UseTargets (edict_t *ent, edict_t *activator);
-void	G_SetMovedir (vec3_t angles, vec3_t movedir);
-
-void	G_InitEdict (edict_t *e);
-edict_t	*G_Spawn (void);
-void	G_FreeEdict (edict_t *e);
-
-void	G_TouchTriggers (edict_t *ent);
-void	G_TouchSolids (edict_t *ent);
-
-char	*G_CopyString (char *in);
-
-float	*tv (float x, float y, float z);
-char	*vtos (vec3_t v);
-
-float vectoyaw (vec3_t vec);
-void vectoangles (vec3_t vec, vec3_t angles);
-
-//
-// g_combat.c
-//
-qboolean OnSameTeam (edict_t *ent1, edict_t *ent2);
-qboolean CanDamage (edict_t *targ, edict_t *inflictor);
-qboolean CheckTeamDamage (edict_t *targ, edict_t *attacker);
-void T_Damage (edict_t *targ, edict_t *inflictor, edict_t *attacker, vec3_t dir, vec3_t point, vec3_t normal, int damage, int knockback, int dflags, int mod);
-void T_RadiusDamage (edict_t *inflictor, edict_t *attacker, float damage, edict_t *ignore, float radius, int mod);
-
-// damage flags
-#define DAMAGE_RADIUS			0x00000001	// damage was indirect
-#define DAMAGE_NO_ARMOR			0x00000002	// armour does not protect from this damage
-#define DAMAGE_ENERGY			0x00000004	// damage is from an energy based weapon
-#define DAMAGE_NO_KNOCKBACK		0x00000008	// do not affect velocity, just view angles
-#define DAMAGE_BULLET			0x00000010  // damage is from a bullet (used for ricochets)
-#define DAMAGE_NO_PROTECTION	0x00000020  // armor, shields, invulnerability, and godmode have no effect
-
-#define DEFAULT_BULLET_HSPREAD	300
-#define DEFAULT_BULLET_VSPREAD	500
-#define DEFAULT_SHOTGUN_HSPREAD	1000
-#define DEFAULT_SHOTGUN_VSPREAD	500
-#define DEFAULT_DEATHMATCH_SHOTGUN_COUNT	12
-#define DEFAULT_SHOTGUN_COUNT	12
-#define DEFAULT_SSHOTGUN_COUNT	20
-
-//
-// g_monster.c
-//
-void monster_fire_bullet (edict_t *self, vec3_t start, vec3_t dir, int damage, int kick, int hspread, int vspread, int flashtype);
-void monster_fire_shotgun (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int count, int flashtype);
-void monster_fire_blaster (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, int flashtype, int effect);
-void monster_fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, int flashtype);
-void monster_fire_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, int flashtype);
-void monster_fire_railgun (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int flashtype);
-void monster_fire_bfg (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, int kick, float damage_radius, int flashtype);
-void M_droptofloor (edict_t *ent);
-void monster_think (edict_t *self);
-void walkmonster_start (edict_t *self);
-void swimmonster_start (edict_t *self);
-void flymonster_start (edict_t *self);
-void AttackFinished (edict_t *self, float time);
-void monster_death_use (edict_t *self);
-void M_CatagorizePosition (edict_t *ent);
-qboolean M_CheckAttack (edict_t *self);
-void M_FlyCheck (edict_t *self);
-void M_CheckGround (edict_t *ent);
-
-//
-// g_misc.c
-//
-void ThrowHead (edict_t *self, char *gibname, int damage, int type);
-void ThrowClientHead (edict_t *self, int damage);
-void ThrowGib (edict_t *self, char *gibname, int damage, int type);
-void BecomeExplosion1(edict_t *self);
-
-//
-// g_ai.c
-//
-void AI_SetSightClient (void);
-
-void ai_stand (edict_t *self, float dist);
-void ai_move (edict_t *self, float dist);
-void ai_walk (edict_t *self, float dist);
-void ai_turn (edict_t *self, float dist);
-void ai_run (edict_t *self, float dist);
-void ai_charge (edict_t *self, float dist);
-int range (edict_t *self, edict_t *other);
-
-void FoundTarget (edict_t *self);
-qboolean infront (edict_t *self, edict_t *other);
-qboolean visible (edict_t *self, edict_t *other);
-qboolean FacingIdeal(edict_t *self);
-
-//
-// g_weapon.c
-//
-void ThrowDebris (edict_t *self, char *modelname, float speed, vec3_t origin);
-qboolean fire_hit (edict_t *self, vec3_t aim, int damage, int kick);
-void fire_bullet (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int mod);
-void fire_shotgun (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick, int hspread, int vspread, int count, int mod);
-void fire_blaster (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, int effect, qboolean hyper);
-void fire_grenade (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float timer, float damage_radius);
-void fire_grenade2 (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, float timer, float damage_radius, qboolean held);
-void fire_rocket (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius, int radius_damage);
-void fire_rail (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int kick);
-void fire_bfg (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, float damage_radius);
-
-//
-// g_ptrail.c
-//
-void PlayerTrail_Init (void);
-void PlayerTrail_Add (vec3_t spot);
-void PlayerTrail_New (vec3_t spot);
-edict_t *PlayerTrail_PickFirst (edict_t *self);
-edict_t *PlayerTrail_PickNext (edict_t *self);
-edict_t	*PlayerTrail_LastSpot (void);
-
-
-//
-// g_client.c
-//
-void respawn (edict_t *ent);
-void BeginIntermission (edict_t *targ);
-void PutClientInServer (edict_t *ent);
-void InitClientPersistant (gclient_t *client);
-void InitClientResp (gclient_t *client);
-void InitBodyQue (void);
-void ClientBeginServerFrame (edict_t *ent);
-
-//
-// g_player.c
-//
-void player_pain (edict_t *self, edict_t *other, float kick, int damage);
-void player_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point);
-
-//
-// g_svcmds.c
-//
-void	ServerCommand (void);
-
-//
-// p_view.c
-//
-void ClientEndServerFrame (edict_t *ent);
-
-//
-// p_hud.c
-//
-void MoveClientToIntermission (edict_t *client);
-void G_SetStats (edict_t *ent);
-void ValidateSelectedItem (edict_t *ent);
-void DeathmatchScoreboardMessage (edict_t *client, edict_t *killer);
-
-//
-// g_pweapon.c
-//
-void PlayerNoise(edict_t *who, vec3_t where, int type);
-void P_ProjectSource (gclient_t *client, vec3_t point, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result);
-void Weapon_Generic (edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, int FRAME_IDLE_LAST, int FRAME_DEACTIVATE_LAST, int *pause_frames, int *fire_frames, void (*fire)(edict_t *ent));
-
-//
-// m_move.c
-//
-qboolean M_CheckBottom (edict_t *ent);
-qboolean M_walkmove (edict_t *ent, float yaw, float dist);
-void M_MoveToGoal (edict_t *ent, float dist);
-void M_ChangeYaw (edict_t *ent);
-
-//
-// g_phys.c
-//
-void G_RunEntity (edict_t *ent);
-
-//
-// g_main.c
-//
-void SaveClientData (void);
-void FetchClientEntData (edict_t *ent);
-void EndDMLevel (void);
-
-
-//============================================================================
-
-// client_t->anim_priority
-#define	ANIM_BASIC		0		// stand / run
-#define	ANIM_WAVE		1
-#define	ANIM_JUMP		2
-#define	ANIM_PAIN		3
-#define	ANIM_ATTACK		4
-#define	ANIM_DEATH		5
-#define	ANIM_REVERSE	6
-
-
-// client data that stays across multiple level loads
-typedef struct
-{
-	char		userinfo[MAX_INFO_STRING];
-	char		netname[16];
-	int			hand;
-
-	qboolean	connected;			// a loadgame will leave valid entities that
-									// just don't have a connection yet
-
-	// values saved and restored from edicts when changing levels
-	int			health;
-	int			max_health;
-	qboolean	powerArmorActive;
-
-	int			selected_item;
-	int			inventory[MAX_ITEMS];
-
-	// ammo capacities
-	int			max_bullets;
-	int			max_shells;
-	int			max_rockets;
-	int			max_grenades;
-	int			max_cells;
-	int			max_slugs;
-
-	gitem_t		*weapon;
-	gitem_t		*lastweapon;
-
-	int			power_cubes;	// used for tracking the cubes in coop games
-	int			score;			// for calculating total unit score in coop games
-} client_persistant_t;
-
-// client data that stays across deathmatch respawns
-typedef struct
-{
-	client_persistant_t	coop_respawn;	// what to set client->pers to on a respawn
-	int			enterframe;			// level.framenum the client entered the game
-	int			score;				// frags, etc
-//ZOID
-	int			ctf_team;			// CTF team
-	int			ctf_state;
-	float		ctf_lasthurtcarrier;
-	float		ctf_lastreturnedflag;
-	float		ctf_flagsince;
-	float		ctf_lastfraggedcarrier;
-	qboolean	id_state;
-	qboolean	voted; // for elections
-	qboolean	ready;
-	qboolean	admin;
-	struct ghost_s *ghost; // for ghost codes
-//ZOID
-	vec3_t		cmd_angles;			// angles sent over in the last command
-	int			game_helpchanged;
-	int			helpchanged;
-} client_respawn_t;
-
-// this structure is cleared on each PutClientInServer(),
-// except for 'client->pers'
-struct gclient_s
-{
-	// known to server
-	player_state_t	ps;				// communicated by server to clients
-	int				ping;
-
-	// private to game
-	client_persistant_t	pers;
-	client_respawn_t	resp;
-	pmove_state_t		old_pmove;	// for detecting out-of-pmove changes
-
-	qboolean	showscores;			// set layout stat
-//ZOID
-	qboolean	inmenu;				// in menu
-	pmenuhnd_t	*menu;				// current menu
-//ZOID
-	qboolean	showinventory;		// set layout stat
-	qboolean	showhelp;
-	qboolean	showhelpicon;
-
-	int			ammo_index;
-
-	int			buttons;
-	int			oldbuttons;
-	int			latched_buttons;
-
-	qboolean	weapon_thunk;
-
-	gitem_t		*newweapon;
-
-	// sum up damage over an entire frame, so
-	// shotgun blasts give a single big kick
-	int			damage_armor;		// damage absorbed by armor
-	int			damage_parmor;		// damage absorbed by power armor
-	int			damage_blood;		// damage taken out of health
-	int			damage_knockback;	// impact damage
-	vec3_t		damage_from;		// origin for vector calculation
-
-	float		killer_yaw;			// when dead, look at killer
-
-	weaponstate_t	weaponstate;
-	vec3_t		kick_angles;	// weapon kicks
-	vec3_t		kick_origin;
-	float		v_dmg_roll, v_dmg_pitch, v_dmg_time;	// damage kicks
-	float		fall_time, fall_value;		// for view drop on fall
-	float		damage_alpha;
-	float		bonus_alpha;
-	vec3_t		damage_blend;
-	vec3_t		v_angle;			// aiming direction
-	float		bobtime;			// so off-ground doesn't change it
-	vec3_t		oldviewangles;
-	vec3_t		oldvelocity;
-
-	float		next_drown_time;
-	int			old_waterlevel;
-	int			breather_sound;
-
-	int			machinegun_shots;	// for weapon raising
-
-	// animation vars
-	int			anim_end;
-	int			anim_priority;
-	qboolean	anim_duck;
-	qboolean	anim_run;
-
-	// powerup timers
-	float		quad_framenum;
-	float		invincible_framenum;
-	float		breather_framenum;
-	float		enviro_framenum;
-
-	qboolean	grenade_blew_up;
-	float		grenade_time;
-	int			silencer_shots;
-	int			weapon_sound;
-
-	float		pickup_msg_time;
-
-	float		flood_locktill;		// locked from talking
-	float		flood_when[10];		// when messages were said
-	int			flood_whenhead;		// head pointer for when said
-
-	float		respawn_time;		// can respawn when time > this
-
-//ZOID
-	void		*ctf_grapple;		// entity of grapple
-	int			ctf_grapplestate;		// true if pulling
-	float		ctf_grapplereleasetime;	// time of grapple release
-	float		ctf_regentime;		// regen tech
-	float		ctf_techsndtime;
-	float		ctf_lasttechmsg;
-	edict_t		*chase_target;
-	qboolean	update_chase;
-	float		menutime;			// time to update menu
-	qboolean	menudirty;
-//ZOID
-};
-
-
-struct edict_t
-{
-	entity_state_t	s;
-	struct gclient_s	*client;	// NULL if not a player
-									// the server expects the first part
-									// of gclient_s to be a player_state_t
-									// but the rest of it is opaque
-
-	qboolean	inuse;
-	int			linkcount;
-
-	// FIXME: move these fields to a server private sv_entity_t
-	link_t		area;				// linked to a division node or leaf
-	
-	int			num_clusters;		// if -1, use headnode instead
-	int			clusternums[MAX_ENT_CLUSTERS];
-	int			headnode;			// unused if num_clusters != -1
-	int			areanum, areanum2;
-
-	//================================
-
-	int			svflags;
-	vec3_t		mins, maxs;
-	vec3_t		absmin, absmax, size;
-	solid_t		solid;
-	int			clipmask;
-	edict_t		*owner;
-
-
-	// DO NOT MODIFY ANYTHING ABOVE THIS, THE SERVER
-	// EXPECTS THE FIELDS IN THAT ORDER!
-
-	//================================
-	int			movetype;
-	int			flags;
-
-	char		*model;
-	float		freetime;			// sv.time when the object was freed
-	
-	//
-	// only used locally in game, not by server
-	//
-	char		*message;
-	char		*classname;
-	int			spawnflags;
-
-	float		timestamp;
-
-	float		angle;			// set in qe3, -1 = up, -2 = down
-	char		*target;
-	char		*targetname;
-	char		*killtarget;
-	char		*team;
-	char		*pathtarget;
-	char		*deathtarget;
-	char		*combattarget;
-	edict_t		*target_ent;
-
-	float		speed, accel, decel;
-	vec3_t		movedir;
-	vec3_t		pos1, pos2;
-
-	vec3_t		velocity;
-	vec3_t		avelocity;
-	int			mass;
-	float		air_finished;
-	float		gravity;		// per entity gravity multiplier (1.0 is normal)
-								// use for lowgrav artifact, flares
-
-	edict_t		*goalentity;
-	edict_t		*movetarget;
-	float		yaw_speed;
-	float		ideal_yaw;
-
-	float		nextthink;
-	void		(*prethink) (edict_t *ent);
-	void		(*think)(edict_t *self);
-	void		(*blocked)(edict_t *self, edict_t *other);	//move to moveinfo?
-	void		(*touch)(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf);
-	void		(*use)(edict_t *self, edict_t *other, edict_t *activator);
-	void		(*pain)(edict_t *self, edict_t *other, float kick, int damage);
-	void		(*die)(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point);
-
-	float		touch_debounce_time;		// are all these legit?  do we need more/less of them?
-	float		pain_debounce_time;
-	float		damage_debounce_time;
-	float		fly_sound_debounce_time;	//move to clientinfo
-	float		last_move_time;
-
-	int			health;
-	int			max_health;
-	int			gib_health;
-	int			deadflag;
-	qboolean	show_hostile;
-
-	float		powerarmor_time;
-
-	char		*map;			// target_changelevel
-
-	int			viewheight;		// height above origin where eyesight is determined
-	int			takedamage;
-	int			dmg;
-	int			radius_dmg;
-	float		dmg_radius;
-	int			sounds;			//make this a spawntemp var?
-	int			count;
-
-	edict_t		*chain;
-	edict_t		*enemy;
-	edict_t		*oldenemy;
-	edict_t		*activator;
-	edict_t		*groundentity;
-	int			groundentity_linkcount;
-	edict_t		*teamchain;
-	edict_t		*teammaster;
-
-	edict_t		*mynoise;		// can go in client only
-	edict_t		*mynoise2;
-
-	int			noise_index;
-	int			noise_index2;
-	float		volume;
-	float		attenuation;
-
-	// timing variables
-	float		wait;
-	float		delay;			// before firing targets
-	float		random;
-
-	float		teleport_time;
-
-	int			watertype;
-	int			waterlevel;
-
-	vec3_t		move_origin;
-	vec3_t		move_angles;
-
-	// move this to clientinfo?
-	int			light_level;
-
-	int			style;			// also used as areaportal number
-
-	gitem_t		*item;			// for bonus items
-
-	// common data blocks
-	moveinfo_t		moveinfo;
-	monsterinfo_t	monsterinfo;
-};
--- a/ctf/g_main.c
+++ b/ctf/g_main.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 
@@ -175,7 +176,7 @@
 {
 	edict_t		*ent;
 	char *s, *t, *f;
-	static const char *seps = " ,\n\r";
+	static char *seps = " ,\n\r";
 
 	// stay on same level flag
 	if ((int)dmflags->value & DF_SAME_LEVEL)
--- a/ctf/g_misc.c
+++ b/ctf/g_misc.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 
@@ -10,7 +11,7 @@
 
 //=====================================================
 
-void Use_Areaportal (edict_t *ent, edict_t *other, edict_t *activator)
+void Use_Areaportal (edict_t *ent, edict_t *, edict_t *)
 {
 	ent->count ^= 1;		// toggle state
 //	gi.dprintf ("portalstate: %i = %i\n", ent->style, ent->count);
@@ -41,7 +42,7 @@
 {
 	v[0] = 100.0 * crandom();
 	v[1] = 100.0 * crandom();
-	v[2] = 200.0 + 100.0 * random();
+	v[2] = 200.0 + 100.0 * qrandom();
 
 	if (damage < 50)
 		VectorScale (v, 0.7, v);
@@ -79,11 +80,11 @@
 	if (self->s.frame == 10)
 	{
 		self->think = G_FreeEdict;
-		self->nextthink = level.time + 8 + random()*10;
+		self->nextthink = level.time + 8 + qrandom()*10;
 	}
 }
 
-void gib_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
+void gib_touch (edict_t *self, edict_t *, cplane_t *plane, csurface_t *)
 {
 	vec3_t	normal_angles, right;
 
@@ -109,7 +110,7 @@
 	}
 }
 
-void gib_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
+void gib_die (edict_t *self, edict_t *, edict_t *, int, vec3_t)
 {
 	G_FreeEdict (self);
 }
@@ -152,12 +153,12 @@
 	VelocityForDamage (damage, vd);
 	VectorMA (self->velocity, vscale, vd, gib->velocity);
 	ClipGibVelocity (gib);
-	gib->avelocity[0] = random()*600;
-	gib->avelocity[1] = random()*600;
-	gib->avelocity[2] = random()*600;
+	gib->avelocity[0] = qrandom()*600;
+	gib->avelocity[1] = qrandom()*600;
+	gib->avelocity[2] = qrandom()*600;
 
 	gib->think = G_FreeEdict;
-	gib->nextthink = level.time + 10 + random()*10;
+	gib->nextthink = level.time + 10 + qrandom()*10;
 
 	gi.linkentity (gib);
 }
@@ -202,7 +203,7 @@
 	self->avelocity[YAW] = crandom()*600;
 
 	self->think = G_FreeEdict;
-	self->nextthink = level.time + 10 + random()*10;
+	self->nextthink = level.time + 10 + qrandom()*10;
 
 	gi.linkentity (self);
 }
@@ -255,7 +256,7 @@
 debris
 =================
 */
-void debris_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
+void debris_die (edict_t *self, edict_t *, edict_t *, int, vec3_t)
 {
 	G_FreeEdict (self);
 }
@@ -274,11 +275,11 @@
 	VectorMA (self->velocity, speed, v, chunk->velocity);
 	chunk->movetype = MOVETYPE_BOUNCE;
 	chunk->solid = SOLID_NOT;
-	chunk->avelocity[0] = random()*600;
-	chunk->avelocity[1] = random()*600;
-	chunk->avelocity[2] = random()*600;
+	chunk->avelocity[0] = qrandom()*600;
+	chunk->avelocity[1] = qrandom()*600;
+	chunk->avelocity[2] = qrandom()*600;
 	chunk->think = G_FreeEdict;
-	chunk->nextthink = level.time + 5 + random()*5;
+	chunk->nextthink = level.time + 5 + qrandom()*5;
 	chunk->s.frame = 0;
 	chunk->flags = 0;
 	chunk->classname = "debris";
@@ -337,7 +338,7 @@
 	this path_corner targeted touches it
 */
 
-void path_corner_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
+void path_corner_touch (edict_t *self, edict_t *other, cplane_t *, csurface_t *)
 {
 	vec3_t		v;
 	edict_t		*next;
@@ -416,7 +417,7 @@
 when first activated before going after the activator.  If
 hold is selected, it will stay here.
 */
-void point_combat_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
+void point_combat_touch (edict_t *self, edict_t *other, cplane_t *, csurface_t *)
 {
 	edict_t	*activator;
 
@@ -553,7 +554,7 @@
 
 #define START_OFF	1
 
-static void light_use (edict_t *self, edict_t *other, edict_t *activator)
+static void light_use (edict_t *self, edict_t *, edict_t *)
 {
 	if (self->spawnflags & START_OFF)
 	{
@@ -601,7 +602,7 @@
 				the wall will initially be present
 */
 
-void func_wall_use (edict_t *self, edict_t *other, edict_t *activator)
+void func_wall_use (edict_t *self, edict_t *, edict_t *)
 {
 	if (self->solid == SOLID_NOT)
 	{
@@ -673,7 +674,7 @@
 This is solid bmodel that will fall if it's support it removed.
 */
 
-void func_object_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
+void func_object_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *)
 {
 	// only squash thing we fall on top of
 	if (!plane)
@@ -691,7 +692,7 @@
 	self->touch = func_object_touch;
 }
 
-void func_object_use (edict_t *self, edict_t *other, edict_t *activator)
+void func_object_use (edict_t *self, edict_t *, edict_t *)
 {
 	self->solid = SOLID_BSP;
 	self->svflags &= ~SVF_NOCLIENT;
@@ -753,7 +754,7 @@
 it explodes.  You get one large chunk per 100 of mass (up to 8) and
 one small chunk per 25 of mass (up to 16).  So 800 gives the most.
 */
-void func_explosive_explode (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
+void func_explosive_explode (edict_t *self, edict_t *inflictor, edict_t *attacker, int, vec3_t)
 {
 	vec3_t	origin;
 	vec3_t	chunkorigin;
@@ -817,12 +818,12 @@
 		G_FreeEdict (self);
 }
 
-void func_explosive_use(edict_t *self, edict_t *other, edict_t *activator)
+void func_explosive_use(edict_t *self, edict_t *other, edict_t *)
 {
 	func_explosive_explode (self, self, other, self->health, vec3_origin);
 }
 
-void func_explosive_spawn (edict_t *self, edict_t *other, edict_t *activator)
+void func_explosive_spawn (edict_t *self, edict_t *, edict_t *)
 {
 	self->solid = SOLID_BSP;
 	self->svflags &= ~SVF_NOCLIENT;
@@ -881,7 +882,7 @@
 health (80), and dmg (150).
 */
 
-void barrel_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
+void barrel_touch (edict_t *self, edict_t *other, cplane_t *, csurface_t *)
 
 {
 	float	ratio;
@@ -974,7 +975,7 @@
 		BecomeExplosion1 (self);
 }
 
-void barrel_delay (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
+void barrel_delay (edict_t *self, edict_t *, edict_t *attacker, int, vec3_t)
 {
 	self->takedamage = DAMAGE_NO;
 	self->nextthink = level.time + 2 * FRAMETIME;
@@ -1029,7 +1030,7 @@
 /*QUAKED misc_blackhole (1 .5 0) (-8 -8 -8) (8 8 8)
 */
 
-void misc_blackhole_use (edict_t *ent, edict_t *other, edict_t *activator)
+void misc_blackhole_use (edict_t *ent, edict_t *, edict_t *)
 {
 	/*
 	gi.WriteByte (svc_temp_entity);
@@ -1165,7 +1166,7 @@
 		gi.sound (self, CHAN_BODY, gi.soundindex ("tank/thud.wav"), 1, ATTN_NORM, 0);
 }
 
-void commander_body_use (edict_t *self, edict_t *other, edict_t *activator)
+void commander_body_use (edict_t *self, edict_t *, edict_t *)
 {
 	self->think = commander_body_think;
 	self->nextthink = level.time + FRAMETIME;
@@ -1225,7 +1226,7 @@
 /*QUAKED misc_deadsoldier (1 .5 0) (-16 -16 0) (16 16 16) ON_BACK ON_STOMACH BACK_DECAP FETAL_POS SIT_DECAP IMPALED
 This is the dead player model. Comes in 6 exciting different poses!
 */
-void misc_deadsoldier_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
+void misc_deadsoldier_die (edict_t *self, edict_t *, edict_t *, int damage, vec3_t)
 {
 	int		n;
 
@@ -1338,7 +1339,7 @@
 /*QUAKED misc_viper_bomb (1 0 0) (-8 -8 -8) (8 8 8)
 "dmg"	how much boom should the bomb make?
 */
-void misc_viper_bomb_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
+void misc_viper_bomb_touch (edict_t *self, edict_t *, cplane_t *, csurface_t *)
 {
 	G_UseTargets (self, self->activator);
 
@@ -1366,7 +1367,7 @@
 	self->s.angles[2] = diff + 10;
 }
 
-void misc_viper_bomb_use (edict_t *self, edict_t *other, edict_t *activator)
+void misc_viper_bomb_use (edict_t *self, edict_t *, edict_t *activator)
 {
 	edict_t	*viper;
 
@@ -1460,7 +1461,7 @@
 		self->nextthink = level.time + FRAMETIME;
 }
 
-void misc_satellite_dish_use (edict_t *self, edict_t *other, edict_t *activator)
+void misc_satellite_dish_use (edict_t *self, edict_t *, edict_t *)
 {
 	self->s.frame = 0;
 	self->think = misc_satellite_dish_think;
@@ -1514,9 +1515,9 @@
 	ent->movetype = MOVETYPE_TOSS;
 	ent->svflags |= SVF_MONSTER;
 	ent->deadflag = DEAD_DEAD;
-	ent->avelocity[0] = random()*200;
-	ent->avelocity[1] = random()*200;
-	ent->avelocity[2] = random()*200;
+	ent->avelocity[0] = qrandom()*200;
+	ent->avelocity[1] = qrandom()*200;
+	ent->avelocity[2] = qrandom()*200;
 	ent->think = G_FreeEdict;
 	ent->nextthink = level.time + 30;
 	gi.linkentity (ent);
@@ -1535,9 +1536,9 @@
 	ent->movetype = MOVETYPE_TOSS;
 	ent->svflags |= SVF_MONSTER;
 	ent->deadflag = DEAD_DEAD;
-	ent->avelocity[0] = random()*200;
-	ent->avelocity[1] = random()*200;
-	ent->avelocity[2] = random()*200;
+	ent->avelocity[0] = qrandom()*200;
+	ent->avelocity[1] = qrandom()*200;
+	ent->avelocity[2] = qrandom()*200;
 	ent->think = G_FreeEdict;
 	ent->nextthink = level.time + 30;
 	gi.linkentity (ent);
@@ -1556,9 +1557,9 @@
 	ent->movetype = MOVETYPE_TOSS;
 	ent->svflags |= SVF_MONSTER;
 	ent->deadflag = DEAD_DEAD;
-	ent->avelocity[0] = random()*200;
-	ent->avelocity[1] = random()*200;
-	ent->avelocity[2] = random()*200;
+	ent->avelocity[0] = qrandom()*200;
+	ent->avelocity[1] = qrandom()*200;
+	ent->avelocity[2] = qrandom()*200;
 	ent->think = G_FreeEdict;
 	ent->nextthink = level.time + 30;
 	gi.linkentity (ent);
@@ -1585,7 +1586,7 @@
 /*QUAKED target_string (0 0 1) (-8 -8 -8) (8 8 8)
 */
 
-void target_string_use (edict_t *self, edict_t *other, edict_t *activator)
+void target_string_use (edict_t *self, edict_t *, edict_t *)
 {
 	edict_t *e;
 	int		n, l;
@@ -1685,6 +1686,8 @@
 
 void func_clock_think (edict_t *self)
 {
+	Tm *t;
+
 	if (!self->enemy)
 	{
 		self->enemy = G_Find (NULL, FOFS(targetname), self->target);
@@ -1704,12 +1707,8 @@
 	}
 	else
 	{
-		struct tm	*ltime;
-		time_t		gmtime;
-
-		time(&gmtime);
-		ltime = localtime(&gmtime);
-		Com_sprintf (self->message, CLOCK_MESSAGE_SIZE, "%2i:%2i:%2i", ltime->tm_hour, ltime->tm_min, ltime->tm_sec);
+		t = localtime(time(nil));
+		Com_sprintf (self->message, CLOCK_MESSAGE_SIZE, "%2d:%2d:%2d", t->hour, t->min, t->sec);
 		if (self->message[3] == ' ')
 			self->message[3] = '0';
 		if (self->message[6] == ' ')
@@ -1748,7 +1747,7 @@
 	self->nextthink = level.time + 1;
 }
 
-void func_clock_use (edict_t *self, edict_t *other, edict_t *activator)
+void func_clock_use (edict_t *self, edict_t *, edict_t *activator)
 {
 	if (!(self->spawnflags & 8))
 		self->use = NULL;
@@ -1775,7 +1774,7 @@
 	}
 
 	if ((self->spawnflags & 1) && (!self->count))
-		self->count = 60*60;;
+		self->count = 60*60;
 
 	func_clock_reset (self);
 
@@ -1791,7 +1790,7 @@
 
 //=================================================================================
 
-void teleporter_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
+void teleporter_touch (edict_t *self, edict_t *other, cplane_t *, csurface_t *)
 {
 	edict_t		*dest;
 	int			i;
--- a/ctf/g_monster.c
+++ b/ctf/g_monster.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 
@@ -72,7 +73,7 @@
 	gi.multicast (start, MULTICAST_PVS);
 }
 
-void monster_fire_bfg (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, int kick, float damage_radius, int flashtype)
+void monster_fire_bfg (edict_t *self, vec3_t start, vec3_t aimdir, int damage, int speed, int, float damage_radius, int flashtype)
 {
 	fire_bfg (self, start, aimdir, damage, speed, damage_radius);
 
@@ -109,11 +110,11 @@
 	if (self->waterlevel)
 		return;
 
-	if (random() > 0.5)
+	if (qrandom() > 0.5)
 		return;
 
 	self->think = M_FliesOn;
-	self->nextthink = level.time + 5 + 10 * random();
+	self->nextthink = level.time + 5 + 10 * qrandom();
 }
 
 void AttackFinished (edict_t *self, float time)
@@ -218,7 +219,7 @@
 					dmg = 2 + 2 * floor(level.time - ent->air_finished);
 					if (dmg > 15)
 						dmg = 15;
-					T_Damage (ent, world, world, vec3_origin, ent->s.origin, vec3_origin, dmg, 0, DAMAGE_NO_ARMOR, MOD_WATER);
+					T_Damage (ent, WORLD, WORLD, vec3_origin, ent->s.origin, vec3_origin, dmg, 0, DAMAGE_NO_ARMOR, MOD_WATER);
 					ent->pain_debounce_time = level.time + 1;
 				}
 			}
@@ -236,7 +237,7 @@
 					dmg = 2 + 2 * floor(level.time - ent->air_finished);
 					if (dmg > 15)
 						dmg = 15;
-					T_Damage (ent, world, world, vec3_origin, ent->s.origin, vec3_origin, dmg, 0, DAMAGE_NO_ARMOR, MOD_WATER);
+					T_Damage (ent, WORLD, WORLD, vec3_origin, ent->s.origin, vec3_origin, dmg, 0, DAMAGE_NO_ARMOR, MOD_WATER);
 					ent->pain_debounce_time = level.time + 1;
 				}
 			}
@@ -258,7 +259,7 @@
 		if (ent->damage_debounce_time < level.time)
 		{
 			ent->damage_debounce_time = level.time + 0.2;
-			T_Damage (ent, world, world, vec3_origin, ent->s.origin, vec3_origin, 10*ent->waterlevel, 0, 0, MOD_LAVA);
+			T_Damage (ent, WORLD, WORLD, vec3_origin, ent->s.origin, vec3_origin, 10*ent->waterlevel, 0, 0, MOD_LAVA);
 		}
 	}
 	if ((ent->watertype & CONTENTS_SLIME) && !(ent->flags & FL_IMMUNE_SLIME))
@@ -266,7 +267,7 @@
 		if (ent->damage_debounce_time < level.time)
 		{
 			ent->damage_debounce_time = level.time + 1;
-			T_Damage (ent, world, world, vec3_origin, ent->s.origin, vec3_origin, 4*ent->waterlevel, 0, 0, MOD_SLIME);
+			T_Damage (ent, WORLD, WORLD, vec3_origin, ent->s.origin, vec3_origin, 4*ent->waterlevel, 0, 0, MOD_SLIME);
 		}
 	}
 	
@@ -275,7 +276,7 @@
 		if (!(ent->svflags & SVF_DEADMONSTER))
 		{
 			if (ent->watertype & CONTENTS_LAVA)
-				if (random() <= 0.5)
+				if (qrandom() <= 0.5)
 					gi.sound (ent, CHAN_BODY, gi.soundindex("player/lava1.wav"), 1, ATTN_NORM, 0);
 				else
 					gi.sound (ent, CHAN_BODY, gi.soundindex("player/lava2.wav"), 1, ATTN_NORM, 0);
@@ -421,7 +422,7 @@
 Using a monster makes it angry at the current activator
 ================
 */
-void monster_use (edict_t *self, edict_t *other, edict_t *activator)
+void monster_use (edict_t *self, edict_t *, edict_t *activator)
 {
 	if (self->enemy)
 		return;
@@ -464,7 +465,7 @@
 	}
 }
 
-void monster_triggered_spawn_use (edict_t *self, edict_t *other, edict_t *activator)
+void monster_triggered_spawn_use (edict_t *self, edict_t *, edict_t *activator)
 {
 	// we have a one frame delay here so we don't telefrag the guy who activated us
 	self->think = monster_triggered_spawn;
--- a/ctf/g_phys.c
+++ b/ctf/g_phys.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 
@@ -584,11 +585,11 @@
 		// otherwise, just stay in place until the obstacle is gone
 		if (part->blocked)
 			part->blocked (part, obstacle);
-#if 0
+/*
 		// if the pushed entity went away and the pusher is still there
 		if (!obstacle->inuse && part->inuse)
 			goto retry;
-#endif
+*/
 	}
 	else
 	{
--- a/ctf/g_save.c
+++ b/ctf/g_save.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 
@@ -147,7 +148,7 @@
 	// latched vars
 	sv_cheats = gi.cvar ("cheats", "0", CVAR_SERVERINFO|CVAR_LATCH);
 	gi.cvar ("gamename", GAMEVERSION , CVAR_SERVERINFO | CVAR_LATCH);
-	gi.cvar ("gamedate", __DATE__ , CVAR_SERVERINFO | CVAR_LATCH);
+	gi.cvar ("gamedate", "Nov 30 1997" , CVAR_SERVERINFO | CVAR_LATCH);
 
 	maxclients = gi.cvar ("maxclients", "4", CVAR_SERVERINFO | CVAR_LATCH);
 	deathmatch = gi.cvar ("deathmatch", "0", CVAR_LATCH);
@@ -218,7 +219,7 @@
 
 //=========================================================
 
-void WriteField1 (FILE *f, field_t *field, byte *base)
+void WriteField1 (FILE *, field_t *field, byte *base)
 {
 	void		*p;
 	int			len;
@@ -431,7 +432,7 @@
 		gi.error ("Couldn't open %s", filename);
 
 	memset (str, 0, sizeof(str));
-	strcpy (str, __DATE__);
+	strcpy (str, "Nov 30 1997");
 	fwrite (str, sizeof(str), 1, f);
 
 	game.autosaved = autosave;
@@ -457,7 +458,7 @@
 		gi.error ("Couldn't open %s", filename);
 
 	fread (str, sizeof(str), 1, f);
-	if (strcmp (str, __DATE__))
+	if (strcmp (str, "Nov 30 1997"))
 	{
 		fclose (f);
 		gi.error ("Savegame from an older version.\n");
--- a/ctf/g_spawn.c
+++ b/ctf/g_spawn.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 
@@ -10,124 +11,6 @@
 } spawn_t;
 
 
-void SP_item_health (edict_t *self);
-void SP_item_health_small (edict_t *self);
-void SP_item_health_large (edict_t *self);
-void SP_item_health_mega (edict_t *self);
-
-void SP_info_player_start (edict_t *ent);
-void SP_info_player_deathmatch (edict_t *ent);
-void SP_info_player_coop (edict_t *ent);
-void SP_info_player_intermission (edict_t *ent);
-
-void SP_func_plat (edict_t *ent);
-void SP_func_rotating (edict_t *ent);
-void SP_func_button (edict_t *ent);
-void SP_func_door (edict_t *ent);
-void SP_func_door_secret (edict_t *ent);
-void SP_func_door_rotating (edict_t *ent);
-void SP_func_water (edict_t *ent);
-void SP_func_train (edict_t *ent);
-void SP_func_conveyor (edict_t *self);
-void SP_func_wall (edict_t *self);
-void SP_func_object (edict_t *self);
-void SP_func_explosive (edict_t *self);
-void SP_func_timer (edict_t *self);
-void SP_func_areaportal (edict_t *ent);
-void SP_func_clock (edict_t *ent);
-void SP_func_killbox (edict_t *ent);
-
-void SP_trigger_always (edict_t *ent);
-void SP_trigger_once (edict_t *ent);
-void SP_trigger_multiple (edict_t *ent);
-void SP_trigger_relay (edict_t *ent);
-void SP_trigger_push (edict_t *ent);
-void SP_trigger_hurt (edict_t *ent);
-void SP_trigger_key (edict_t *ent);
-void SP_trigger_counter (edict_t *ent);
-void SP_trigger_elevator (edict_t *ent);
-void SP_trigger_gravity (edict_t *ent);
-void SP_trigger_monsterjump (edict_t *ent);
-
-void SP_target_temp_entity (edict_t *ent);
-void SP_target_speaker (edict_t *ent);
-void SP_target_explosion (edict_t *ent);
-void SP_target_changelevel (edict_t *ent);
-void SP_target_secret (edict_t *ent);
-void SP_target_goal (edict_t *ent);
-void SP_target_splash (edict_t *ent);
-void SP_target_spawner (edict_t *ent);
-void SP_target_blaster (edict_t *ent);
-void SP_target_crosslevel_trigger (edict_t *ent);
-void SP_target_crosslevel_target (edict_t *ent);
-void SP_target_laser (edict_t *self);
-void SP_target_help (edict_t *ent);
-void SP_target_actor (edict_t *ent);
-void SP_target_lightramp (edict_t *self);
-void SP_target_earthquake (edict_t *ent);
-void SP_target_character (edict_t *ent);
-void SP_target_string (edict_t *ent);
-
-void SP_worldspawn (edict_t *ent);
-void SP_viewthing (edict_t *ent);
-
-void SP_light (edict_t *self);
-void SP_light_mine1 (edict_t *ent);
-void SP_light_mine2 (edict_t *ent);
-void SP_info_null (edict_t *self);
-void SP_info_notnull (edict_t *self);
-void SP_path_corner (edict_t *self);
-void SP_point_combat (edict_t *self);
-
-void SP_misc_explobox (edict_t *self);
-void SP_misc_banner (edict_t *self);
-void SP_misc_satellite_dish (edict_t *self);
-void SP_misc_actor (edict_t *self);
-void SP_misc_gib_arm (edict_t *self);
-void SP_misc_gib_leg (edict_t *self);
-void SP_misc_gib_head (edict_t *self);
-void SP_misc_insane (edict_t *self);
-void SP_misc_deadsoldier (edict_t *self);
-void SP_misc_viper (edict_t *self);
-void SP_misc_viper_bomb (edict_t *self);
-void SP_misc_bigviper (edict_t *self);
-void SP_misc_strogg_ship (edict_t *self);
-void SP_misc_teleporter (edict_t *self);
-void SP_misc_teleporter_dest (edict_t *self);
-void SP_misc_blackhole (edict_t *self);
-void SP_misc_eastertank (edict_t *self);
-void SP_misc_easterchick (edict_t *self);
-void SP_misc_easterchick2 (edict_t *self);
-
-void SP_monster_berserk (edict_t *self);
-void SP_monster_gladiator (edict_t *self);
-void SP_monster_gunner (edict_t *self);
-void SP_monster_infantry (edict_t *self);
-void SP_monster_soldier_light (edict_t *self);
-void SP_monster_soldier (edict_t *self);
-void SP_monster_soldier_ss (edict_t *self);
-void SP_monster_tank (edict_t *self);
-void SP_monster_medic (edict_t *self);
-void SP_monster_flipper (edict_t *self);
-void SP_monster_chick (edict_t *self);
-void SP_monster_parasite (edict_t *self);
-void SP_monster_flyer (edict_t *self);
-void SP_monster_brain (edict_t *self);
-void SP_monster_floater (edict_t *self);
-void SP_monster_hover (edict_t *self);
-void SP_monster_mutant (edict_t *self);
-void SP_monster_supertank (edict_t *self);
-void SP_monster_boss2 (edict_t *self);
-void SP_monster_jorg (edict_t *self);
-void SP_monster_boss3_stand (edict_t *self);
-
-void SP_monster_commander_body (edict_t *self);
-
-void SP_turret_breach (edict_t *self);
-void SP_turret_base (edict_t *self);
-void SP_turret_driver (edict_t *self);
-
-
 spawn_t	spawns[] = {
 	{"item_health", SP_item_health},
 	{"item_health_small", SP_item_health_small},
@@ -185,9 +68,9 @@
 	{"target_crosslevel_target", SP_target_crosslevel_target},
 	{"target_laser", SP_target_laser},
 	{"target_help", SP_target_help},
-#if 0 // remove monster code
+/* remove monster code
 	{"target_actor", SP_target_actor},
-#endif
+*/
 	{"target_lightramp", SP_target_lightramp},
 	{"target_earthquake", SP_target_earthquake},
 	{"target_character", SP_target_character},
@@ -212,15 +95,15 @@
 	{"misc_ctf_small_banner", SP_misc_ctf_small_banner},
 //ZOID
 	{"misc_satellite_dish", SP_misc_satellite_dish},
-#if 0 // remove monster code
+/* remove monster code
 	{"misc_actor", SP_misc_actor},
-#endif
+*/
 	{"misc_gib_arm", SP_misc_gib_arm},
 	{"misc_gib_leg", SP_misc_gib_leg},
 	{"misc_gib_head", SP_misc_gib_head},
-#if 0 // remove monster code
+/* remove monster code
 	{"misc_insane", SP_misc_insane},
-#endif
+*/
 	{"misc_deadsoldier", SP_misc_deadsoldier},
 	{"misc_viper", SP_misc_viper},
 	{"misc_viper_bomb", SP_misc_viper_bomb},
@@ -237,7 +120,7 @@
 	{"misc_easterchick", SP_misc_easterchick},
 	{"misc_easterchick2", SP_misc_easterchick2},
 
-#if 0 // remove monster code
+/* remove monster code
 	{"monster_berserk", SP_monster_berserk},
 	{"monster_gladiator", SP_monster_gladiator},
 	{"monster_gunner", SP_monster_gunner},
@@ -266,7 +149,7 @@
 	{"turret_breach", SP_turret_breach},
 	{"turret_base", SP_turret_base},
 	{"turret_driver", SP_turret_driver},
-#endif
+*/
 
 	{NULL, NULL}
 };
@@ -619,7 +502,7 @@
 
 //===================================================================
 
-#if 0
+/*
 	// cursor positioning
 	xl <value>
 	xr <value>
@@ -640,7 +523,7 @@
 	ifbit <stat> <value>
 	endif
 
-#endif
+*/
 
 char *single_statusbar = 
 "yb	-24 "
@@ -883,7 +766,7 @@
 	gi.soundindex ("*pain100_1.wav");
 	gi.soundindex ("*pain100_2.wav");
 
-#if 0 //DISABLED
+/* DISABLED
 	// sexed models
 	// THIS ORDER MUST MATCH THE DEFINES IN g_local.h
 	// you can add more, max 15
@@ -899,7 +782,7 @@
 	gi.modelindex ("#w_railgun.md2");
 	gi.modelindex ("#w_bfg.md2");
 	gi.modelindex ("#w_grapple.md2");
-#endif
+*/
 
 	//-------------------
 
--- a/ctf/g_svcmds.c
+++ b/ctf/g_svcmds.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 
--- a/ctf/g_target.c
+++ b/ctf/g_target.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 
@@ -7,7 +8,7 @@
 Fire an origin based temp entity event to the clients.
 "style"		type byte
 */
-void Use_Target_Tent (edict_t *ent, edict_t *other, edict_t *activator)
+void Use_Target_Tent (edict_t *ent, edict_t *, edict_t *)
 {
 	gi.WriteByte (svc_temp_entity);
 	gi.WriteByte (ent->style);
@@ -39,7 +40,7 @@
 Looped sounds are allways atten 3 / vol 1, and the use function toggles it on/off.
 Multiple identical looping sounds will just increase volume without any speed cost.
 */
-void Use_Target_Speaker (edict_t *ent, edict_t *other, edict_t *activator)
+void Use_Target_Speaker (edict_t *ent, edict_t *, edict_t *)
 {
 	int		chan;
 
@@ -99,7 +100,7 @@
 
 //==========================================================
 
-void Use_Target_Help (edict_t *ent, edict_t *other, edict_t *activator)
+void Use_Target_Help (edict_t *ent, edict_t *, edict_t *)
 {
 	if (ent->spawnflags & 1)
 		strncpy (game.helpmessage1, ent->message, sizeof(game.helpmessage2)-1);
@@ -135,7 +136,7 @@
 Counts a secret found.
 These are single use targets.
 */
-void use_target_secret (edict_t *ent, edict_t *other, edict_t *activator)
+void use_target_secret (edict_t *ent, edict_t *, edict_t *activator)
 {
 	gi.sound (ent, CHAN_VOICE, ent->noise_index, 1, ATTN_NORM, 0);
 
@@ -170,7 +171,7 @@
 Counts a goal completed.
 These are single use targets.
 */
-void use_target_goal (edict_t *ent, edict_t *other, edict_t *activator)
+void use_target_goal (edict_t *ent, edict_t *, edict_t *activator)
 {
 	gi.sound (ent, CHAN_VOICE, ent->noise_index, 1, ATTN_NORM, 0);
 
@@ -225,7 +226,7 @@
 	self->delay = save;
 }
 
-void use_target_explosion (edict_t *self, edict_t *other, edict_t *activator)
+void use_target_explosion (edict_t *self, edict_t *, edict_t *activator)
 {
 	self->activator = activator;
 
@@ -263,7 +264,7 @@
 	}
 
 	// if noexit, do a ton of damage to other
-	if (deathmatch->value && !( (int)dmflags->value & DF_ALLOW_EXIT) && other != world)
+	if (deathmatch->value && !( (int)dmflags->value & DF_ALLOW_EXIT) && other != WORLD)
 	{
 		T_Damage (other, self, self, vec3_origin, other->s.origin, vec3_origin, 10 * other->max_health, 1000, 0, MOD_EXIT);
 		return;
@@ -319,7 +320,7 @@
 		useful for lava/sparks
 */
 
-void use_target_splash (edict_t *self, edict_t *other, edict_t *activator)
+void use_target_splash (edict_t *self, edict_t *, edict_t *activator)
 {
 	gi.WriteByte (svc_temp_entity);
 	gi.WriteByte (TE_SPLASH);
@@ -361,7 +362,7 @@
 */
 void ED_CallSpawn (edict_t *ent);
 
-void use_target_spawner (edict_t *self, edict_t *other, edict_t *activator)
+void use_target_spawner (edict_t *self, edict_t *, edict_t *)
 {
 	edict_t	*ent;
 
@@ -397,8 +398,9 @@
 speed	default is 1000
 */
 
-void use_target_blaster (edict_t *self, edict_t *other, edict_t *activator)
+void use_target_blaster (edict_t *self, edict_t *, edict_t *)
 {
+/*
 	int effect;
 
 	if (self->spawnflags & 2)
@@ -407,7 +409,7 @@
 		effect = EF_HYPERBLASTER;
 	else
 		effect = EF_BLASTER;
-
+*/
 	fire_blaster (self, self->s.origin, self->movedir, self->dmg, self->speed, EF_BLASTER, MOD_TARGET_BLASTER);
 	gi.sound (self, CHAN_VOICE, self->noise_index, 1, ATTN_NORM, 0);
 }
@@ -432,7 +434,7 @@
 /*QUAKED target_crosslevel_trigger (.5 .5 .5) (-8 -8 -8) (8 8 8) trigger1 trigger2 trigger3 trigger4 trigger5 trigger6 trigger7 trigger8
 Once this trigger is touched/used, any trigger_crosslevel_target with the same trigger number is automatically used when a level is started within the same unit.  It is OK to check multiple triggers.  Message, delay, target, and killtarget also work.
 */
-void trigger_crosslevel_trigger_use (edict_t *self, edict_t *other, edict_t *activator)
+void trigger_crosslevel_trigger_use (edict_t *self, edict_t *, edict_t *)
 {
 	game.serverflags |= self->spawnflags;
 	G_FreeEdict (self);
@@ -557,7 +559,7 @@
 	self->nextthink = 0;
 }
 
-void target_laser_use (edict_t *self, edict_t *other, edict_t *activator)
+void target_laser_use (edict_t *self, edict_t *, edict_t *activator)
 {
 	self->activator = activator;
 	if (self->spawnflags & 1)
@@ -660,7 +662,7 @@
 	}
 }
 
-void target_lightramp_use (edict_t *self, edict_t *other, edict_t *activator)
+void target_lightramp_use (edict_t *self, edict_t *, edict_t *)
 {
 	if (!self->enemy)
 	{
@@ -766,7 +768,7 @@
 		self->nextthink = level.time + FRAMETIME;
 }
 
-void target_earthquake_use (edict_t *self, edict_t *other, edict_t *activator)
+void target_earthquake_use (edict_t *self, edict_t *, edict_t *activator)
 {
 	self->timestamp = level.time + self->count;
 	self->nextthink = level.time + FRAMETIME;
--- a/ctf/g_trigger.c
+++ b/ctf/g_trigger.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 
@@ -47,13 +48,13 @@
 	}
 }
 
-void Use_Multi (edict_t *ent, edict_t *other, edict_t *activator)
+void Use_Multi (edict_t *ent, edict_t *, edict_t *activator)
 {
 	ent->activator = activator;
 	multi_trigger (ent);
 }
 
-void Touch_Multi (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
+void Touch_Multi (edict_t *self, edict_t *other, cplane_t *, csurface_t *)
 {
 	if(other->client)
 	{
@@ -92,7 +93,7 @@
 4)
 set "message" to text string
 */
-void trigger_enable (edict_t *self, edict_t *other, edict_t *activator)
+void trigger_enable (edict_t *self, edict_t *, edict_t *)
 {
 	self->solid = SOLID_TRIGGER;
 	self->use = Use_Multi;
@@ -170,7 +171,7 @@
 /*QUAKED trigger_relay (.5 .5 .5) (-8 -8 -8) (8 8 8)
 This fixed size trigger cannot be touched, it can only be fired by other events.
 */
-void trigger_relay_use (edict_t *self, edict_t *other, edict_t *activator)
+void trigger_relay_use (edict_t *self, edict_t *, edict_t *activator)
 {
 	G_UseTargets (self, activator);
 }
@@ -193,7 +194,7 @@
 A relay trigger that only fires it's targets if player has the proper key.
 Use "item" to specify the required key, for example "key_data_cd"
 */
-void trigger_key_use (edict_t *self, edict_t *other, edict_t *activator)
+void trigger_key_use (edict_t *self, edict_t *, edict_t *activator)
 {
 	int			index;
 
@@ -307,7 +308,7 @@
 After the counter has been triggered "count" times (default 2), it will fire all of it's targets and remove itself.
 */
 
-void trigger_counter_use(edict_t *self, edict_t *other, edict_t *activator)
+void trigger_counter_use(edict_t *self, edict_t *, edict_t *activator)
 {
 	if (self->count == 0)
 		return;
@@ -375,7 +376,7 @@
 
 static int windsound;
 
-void trigger_push_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
+void trigger_push_touch (edict_t *self, edict_t *other, cplane_t *, csurface_t *)
 {
 	if (strcmp(other->classname, "grenade") == 0)
 	{
@@ -436,7 +437,7 @@
 "dmg"			default 5 (whole numbers only)
 
 */
-void hurt_use (edict_t *self, edict_t *other, edict_t *activator)
+void hurt_use (edict_t *self, edict_t *, edict_t *)
 {
 	if (self->solid == SOLID_NOT)
 		self->solid = SOLID_TRIGGER;
@@ -449,7 +450,7 @@
 }
 
 
-void hurt_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
+void hurt_touch (edict_t *self, edict_t *other, cplane_t *, csurface_t *)
 {
 	int		dflags;
 
@@ -513,7 +514,7 @@
 gravity for the level.
 */
 
-void trigger_gravity_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
+void trigger_gravity_touch (edict_t *self, edict_t *other, cplane_t *, csurface_t *)
 {
 	other->gravity = self->gravity;
 }
@@ -547,7 +548,7 @@
 "height" default to 200, the speed thrown upwards
 */
 
-void trigger_monsterjump_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
+void trigger_monsterjump_touch (edict_t *self, edict_t *other, cplane_t *, csurface_t *)
 {
 	if (other->flags & (FL_FLY | FL_SWIM) )
 		return;
--- a/ctf/g_utils.c
+++ b/ctf/g_utils.c
@@ -1,7 +1,6 @@
 #include <u.h>
 #include <libc.h>
-// g_utils.c -- misc utility functions for game module
-
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 
--- a/ctf/g_weapon.c
+++ b/ctf/g_weapon.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 
@@ -23,7 +24,7 @@
 	// easy mode only ducks one quarter the time
 	if (skill->value == 0)
 	{
-		if (random() > 0.25)
+		if (qrandom() > 0.25)
 			return;
 	}
 	VectorMA (start, 8192, dir, end);
@@ -431,7 +432,7 @@
 	G_FreeEdict (ent);
 }
 
-static void Grenade_Touch (edict_t *ent, edict_t *other, cplane_t *plane, csurface_t *surf)
+static void Grenade_Touch (edict_t *ent, edict_t *other, cplane_t *, csurface_t *surf)
 {
 	if (other == ent->owner)
 		return;
@@ -446,7 +447,7 @@
 	{
 		if (ent->spawnflags & 1)
 		{
-			if (random() > 0.5)
+			if (qrandom() > 0.5)
 				gi.sound (ent, CHAN_VOICE, gi.soundindex ("weapons/hgrenb1a.wav"), 1, ATTN_NORM, 0);
 			else
 				gi.sound (ent, CHAN_VOICE, gi.soundindex ("weapons/hgrenb2a.wav"), 1, ATTN_NORM, 0);
--- a/ctf/game.h
+++ b/ctf/game.h
@@ -1,222 +1,1284 @@
-// game.h -- game dll information visible to server
+typedef struct link_t link_t;
+typedef struct game_import_t game_import_t;
+typedef struct game_export_t game_export_t;
+typedef struct gitem_armor_t gitem_armor_t;
+typedef struct gitem_t gitem_t;
+typedef struct game_locals_t game_locals_t;
+typedef struct level_locals_t level_locals_t;
+typedef struct spawn_temp_t spawn_temp_t;
+typedef struct moveinfo_t moveinfo_t;
+typedef struct mframe_t mframe_t;
+typedef struct mmove_t mmove_t;
+typedef struct monsterinfo_t monsterinfo_t;
+typedef struct field_t field_t;
+typedef struct pmenuhnd_t pmenuhnd_t;
+typedef struct pmenu_t pmenu_t;
+typedef struct client_persistant_t client_persistant_t;
+typedef struct client_respawn_t client_respawn_t;
+typedef struct edict_t edict_t;
+typedef struct gclient_t gclient_t;
+typedef struct ghost_t ghost_t;
 
-#define	GAME_API_VERSION	3
+typedef void	(*SelectFunc_t)(edict_t *, pmenuhnd_t *);
 
-// edict->svflags
+enum{
+	GAME_API_VERSION = 3,
 
-#define	SVF_NOCLIENT			0x00000001	// don't send entity to clients, even if it has effects
-#define	SVF_DEADMONSTER			0x00000002	// treat as CONTENTS_DEADMONSTER for collision
-#define	SVF_MONSTER				0x00000004	// treat as CONTENTS_MONSTER for collision
-//ZOID
-#define SVF_PROJECTILE			0x00000008  // entity is simple projectile, used for network optimization
-// if an entity is projectile, the model index/x/y/z/pitch/yaw are sent, encoded into
-// seven (or eight) bytes.  This is to speed up projectiles.  Currently, only the
-// hyperblaster makes use of this.  use for items that are moving with a constant
-// velocity that don't change direction or model
-//ZOID
+	/* edict->svflags
+	 * if an entity is projectile, the model index/x/y/z/pitch/yaw are
+	 * sent, encoded into seven (or eight) bytes. this is to speed up
+	 * projectiles. Currently, only the hyperblaster makes use of this. use
+	 * for items that are moving with a constant velocity that don't change
+	 * direction or model */
+	SVF_NOCLIENT = 1<<0,	// don't send entity to clients, even if it has effects
+	SVF_DEADMONSTER = 1<<1,	// treat as CONTENTS_DEADMONSTER for collision
+	SVF_MONSTER = 1<<2,	// treat as CONTENTS_MONSTER for collision
+	SVF_PROJECTILE = 1<<3,	// entity is simple projectile, used for network optimization
 
-// edict->solid values
+	MAX_ENT_CLUSTERS = 16
+};
 
-typedef enum
-{
-SOLID_NOT,			// no interaction with other objects
-SOLID_TRIGGER,		// only touch when inside, after moving
-SOLID_BBOX,			// touch on edge
-SOLID_BSP			// bsp clip, touch on edge
-} solid_t;
+/* edict->solid values */
+typedef enum solid_t{
+	SOLID_NOT,	// no interaction with other objects
+	SOLID_TRIGGER,	// only touch when inside, after moving
+	SOLID_BBOX,	// touch on edge
+	SOLID_BSP	// bsp clip, touch on edge
+}solid_t;
+
+/* only used for entity area links now */
+struct link_t{
+	link_t *prev;
+	link_t *next;
+};
+
+struct game_import_t{
+	void	(*bprintf)(int, char *, ...);
+	void	(*dprintf)(char *, ...);
+	void	(*cprintf)(edict_t *, int, char *, ...);
+	void	(*centerprintf)(edict_t *, char *, ...);
+	void	(*sound)(edict_t *, int, int, float, float, float);
+	void	(*positioned_sound)(vec3_t, edict_t *, int, int, float, float, float);
+	/* config strings hold all the index strings, the lightstyles, and misc
+	 * data like the sky definition and cdtrack. all of the current
+	 * configstrings are sent to clients when they connect, and changes are
+	 * sent to all connected clients. */
+	void	(*configstring)(int, char *);
+	void	(*error)(char *, ...);
+	/* the *index functions create configstrings and some internal server
+	 * state */
+	int	(*modelindex)(char *);
+	int	(*soundindex)(char *);
+	int	(*imageindex)(char *);
+	void	(*setmodel)(edict_t *, char *);
+	/* collision detection */
+	trace_t	(*trace)(vec3_t, vec3_t, vec3_t, vec3_t, edict_t *, int);
+	int	(*pointcontents)(vec3_t);
+	qboolean	(*inPVS)(vec3_t, vec3_t);
+	qboolean	(*inPHS)(vec3_t, vec3_t);
+	void	(*SetAreaPortalState)(int, qboolean);
+	qboolean	(*AreasConnected)(int, int);
+	/* an entity will never be sent to a client or used for collision if it
+	 * is not passed to linkentity. if the size, position, or solidity
+	 * changes, it must be relinked. */
+	void	(*linkentity)(edict_t *);
+	void	(*unlinkentity)(edict_t *);	// call before removing an interactive edict
+	int	(*BoxEdicts)(vec3_t, vec3_t, edict_t **, int, int);
+	void	(*Pmove)(pmove_t *);	// player movement code common with client prediction
+	/* network messaging */
+	void	(*multicast)(vec3_t, multicast_t);
+	void	(*unicast) (edict_t *, qboolean);
+	void	(*WriteChar)(int);
+	void	(*WriteByte)(int);
+	void	(*WriteShort)(int);
+	void	(*WriteLong)(int);
+	void	(*WriteFloat)(float);
+	void	(*WriteString)(char *);
+	void	(*WritePosition)(vec3_t);	// some fractional bits
+	void	(*WriteDir)(vec3_t);	// single byte encoded, very coarse
+	void	(*WriteAngle)(float);
+	/* managed memory allocation */
+	void*	(*TagMalloc)(int, int);
+	void	(*TagFree)(void *);
+	void	(*FreeTags)(int);
+	/* console variable interaction */
+	cvar_t*	(*cvar)(char *, char *, int);
+	cvar_t*	(*cvar_set)(char *, char *);
+	cvar_t*	(*cvar_forceset)(char *, char *);
+	/* ClientCommand and ServerCommand parameter access */
+	int	(*argc)(void);
+	char*	(*argv)(int);
+	char*	(*args)(void);	// concatenation of all argv >= 1
+	/* add commands to the server console as if they were typed in for map
+	 * changing, etc */
+	void	(*AddCommandString)(char *);
+	void	(*DebugGraph)(float, int);
+};
+extern game_import_t gi;
+struct game_export_t{
+	int apiversion;
+	/* the init function will only be called when a game starts, not each
+	 * time a level is loaded. persistant data for clients and the server
+	 * can be allocated in init */
+	void	(*Init)(void);
+	void	(*Shutdown)(void);
+	/* each new level entered will cause a call to SpawnEntities */
+	void	(*SpawnEntities)(char *, char *, char *);
+	/* Read/Write Game is for storing persistant cross level information
+	 * about the world state and the clients. WriteGame is called every
+	 * time a level is exited. ReadGame is called on a loadgame. */
+	void	(*WriteGame)(char *, qboolean);
+	void	(*ReadGame)(char *);
+	/* ReadLevel is called after the default map information has been
+	 * loaded with SpawnEntities */
+	void	(*WriteLevel)(char *);
+	void	(*ReadLevel)(char *);
+	qboolean	(*ClientConnect)(edict_t *, char *);
+	void	(*ClientBegin)(edict_t *);
+	void	(*ClientUserinfoChanged)(edict_t *, char *);
+	void	(*ClientDisconnect)(edict_t *);
+	void	(*ClientCommand)(edict_t *);
+	void	(*ClientThink)(edict_t *, usercmd_t *);
+	void	(*RunFrame)(void);
+	/* ServerCommand will be called when an "sv <command>" command is
+	 * issued on the server console. The game can issue gi.argc() or
+	 * gi.argv() commands to get the rest of the parameters */
+	void	(*ServerCommand)(void);
+	/* global variables shared between game and server
+	 * The edict array is allocated in the game dll so it can vary in size
+	 * from one game to another. The size will be fixed when ge->Init() is
+	 * called */
+	edict_t *edicts;
+	int edict_size;
+	int num_edicts;	// current number, <= max_edicts
+	int max_edicts;
+};
+extern game_export_t globals;
 
-//===============================================================
+extern cvar_t *maxentities;
+extern cvar_t *deathmatch;
+extern cvar_t *coop;
+extern cvar_t *dmflags;
+extern cvar_t *skill;
+extern cvar_t *fraglimit;
+extern cvar_t *timelimit;
+extern cvar_t *capturelimit;
+extern cvar_t *instantweap;
+extern cvar_t *password;
+extern cvar_t *g_select_empty;
+extern cvar_t *dedicated;
+extern cvar_t *sv_gravity;
+extern cvar_t *sv_maxvelocity;
+extern cvar_t *gun_x;
+extern cvar_t *gun_y;
+extern cvar_t *gun_z;
+extern cvar_t *sv_rollspeed;
+extern cvar_t *sv_rollangle;
+extern cvar_t *run_pitch;
+extern cvar_t *run_roll;
+extern cvar_t *bob_up;
+extern cvar_t *bob_pitch;
+extern cvar_t *bob_roll;
+extern cvar_t *sv_cheats;
+extern cvar_t *maxclients;
+extern cvar_t *flood_msgs;
+extern cvar_t *flood_persecond;
+extern cvar_t *flood_waitdelay;
+extern cvar_t *sv_maplist;
+extern cvar_t *ctf;
 
-// link_t is only used for entity area links now
-typedef struct link_s
-{
-	struct link_s	*prev, *next;
-} link_t;
+#define	GAMEVERSION	"baseq2"
+#define DAMAGE_TIME	0.5
+#define	FALL_TIME	0.3
+#define	FRAMETIME	0.1
+enum{
+	/* view pitching times */
+	/* edict->spawnflags: these are set with checkboxes on each entity in
+	 * the map editor */
+	SPAWNFLAG_NOT_EASY = 1<<8,
+	SPAWNFLAG_NOT_MEDIUM = 1<<9,
+	SPAWNFLAG_NOT_HARD = 1<<10,
+	SPAWNFLAG_NOT_DEATHMATCH = 1<<11,
+	SPAWNFLAG_NOT_COOP = 1<<12,
 
-#define	MAX_ENT_CLUSTERS	16
+	/* edict->flags */
+	FL_FLY = 1<<0,
+	FL_SWIM = 1<<1,	// implied immunity to drowining
+	FL_IMMUNE_LASER = 1<<2,
+	FL_INWATER = 1<<3,
+	FL_GODMODE = 1<<4,
+	FL_NOTARGET = 1<<5,
+	FL_IMMUNE_SLIME = 1<<6,
+	FL_IMMUNE_LAVA = 1<<7,
+	FL_PARTIALGROUND = 1<<8,	// not all corners are valid
+	FL_WATERJUMP = 1<<9,	// player jumping out of water
+	FL_TEAMSLAVE = 1<<10,	// not the first on the team
+	FL_NO_KNOCKBACK = 1<<11,
+	FL_POWER_ARMOR = 1<<12,	// power armor (if any) is active
+	FL_RESPAWN = 1<<31,	// used for item respawning
 
+	/* memory tags to allow dynamic memory to be cleaned up */
+	TAG_GAME = 765,	// clear when unloading the dll
+	TAG_LEVEL = 766,	// clear when loading a new level
 
-typedef struct edict_t edict_t;
-typedef struct gclient_t gclient_t;
+	MELEE_DISTANCE = 80,
+	BODY_QUEUE_SIZE = 8,
 
+	/* deadflag */
+	DEAD_NO = 0,
+	DEAD_DYING = 1,
+	DEAD_DEAD = 2,
+	DEAD_RESPAWNABLE = 3,
 
-#ifndef GAME_INCLUDE
+	/* range */
+	RANGE_MELEE = 0,
+	RANGE_NEAR = 1,
+	RANGE_MID = 2,
+	RANGE_FAR = 3,
 
-struct gclient_t
-{
-	player_state_t	ps;		// communicated by server to clients
-	int				ping;
-	// the game dll can add anything it wants after
-	// this point in the structure
-};
+	/* gib types */
+	GIB_ORGANIC = 0,
+	GIB_METALLIC = 1,
 
+	/* monster ai flags */
+	AI_STAND_GROUND = 1<<0,
+	AI_TEMP_STAND_GROUND = 1<<1,
+	AI_SOUND_TARGET = 1<<2,
+	AI_LOST_SIGHT = 1<<3,
+	AI_PURSUIT_LAST_SEEN = 1<<4,
+	AI_PURSUE_NEXT = 1<<5,
+	AI_PURSUE_TEMP = 1<<6,
+	AI_HOLD_FRAME = 1<<7,
+	AI_GOOD_GUY = 1<<8,
+	AI_BRUTAL = 1<<9,
+	AI_NOSTEP = 1<<10,
+	AI_DUCKED = 1<<11,
+	AI_COMBAT_POINT = 1<<12,
+	AI_MEDIC = 1<<13,
+	AI_RESURRECTING = 1<<14,
 
-struct edict_t
-{
-	entity_state_t	s;
-	gclient_t	*client;
-	qboolean	inuse;
-	int			linkcount;
+	/* monster attack state */
+	AS_STRAIGHT = 1,
+	AS_SLIDING = 2,
+	AS_MELEE = 3,
+	AS_MISSILE = 4,
 
-	// FIXME: move these fields to a server private sv_entity_t
-	link_t		area;				// linked to a division node or leaf
-	
-	int			num_clusters;		// if -1, use headnode instead
-	int			clusternums[MAX_ENT_CLUSTERS];
-	int			headnode;			// unused if num_clusters != -1
-	int			areanum, areanum2;
+	/* armor types */
+	ARMOR_NONE = 0,
+	ARMOR_JACKET = 1,
+	ARMOR_COMBAT = 2,
+	ARMOR_BODY = 3,
+	ARMOR_SHARD = 4,
 
-	//================================
+	/* power armor types */
+	POWER_ARMOR_NONE = 0,
+	POWER_ARMOR_SCREEN = 1,
+	POWER_ARMOR_SHIELD = 2,
 
-	int			svflags;			// SVF_NOCLIENT, SVF_DEADMONSTER, SVF_MONSTER, etc
-	vec3_t		mins, maxs;
-	vec3_t		absmin, absmax, size;
-	solid_t		solid;
-	int			clipmask;
-	edict_t		*owner;
+	/* handedness values */
+	RIGHT_HANDED = 0,
+	LEFT_HANDED = 1,
+	CENTER_HANDED = 2,
 
-	// the game dll can add anything it wants after
-	// this point in the structure
-};
+	/* game.serverflags values */
+	SFL_CROSS_TRIGGER_1 = 1<<0,
+	SFL_CROSS_TRIGGER_2 = 1<<1,
+	SFL_CROSS_TRIGGER_3 = 1<<2,
+	SFL_CROSS_TRIGGER_4 = 1<<3,
+	SFL_CROSS_TRIGGER_5 = 1<<4,
+	SFL_CROSS_TRIGGER_6 = 1<<5,
+	SFL_CROSS_TRIGGER_7 = 1<<6,
+	SFL_CROSS_TRIGGER_8 = 1<<7,
+	SFL_CROSS_TRIGGER_MASK = 0xff,
 
-#endif		// GAME_INCLUDE
+	/* noise types for PlayerNoise */
+	PNOISE_SELF = 0,
+	PNOISE_WEAPON = 1,
+	PNOISE_IMPACT = 2,
 
-//===============================================================
+	/* gitem_t->flags */
+	IT_WEAPON = 1,	// use makes active weapon
+	IT_AMMO = 2,
+	IT_ARMOR = 4,
+	IT_STAY_COOP = 8,
+	IT_KEY = 16,
+	IT_POWERUP = 32,
+	IT_TECH = 64,
 
-//
-// functions provided by the main engine
-//
-typedef struct
-{
-	// special messages
-	void	(*bprintf) (int printlevel, char *fmt, ...);
-	void	(*dprintf) (char *fmt, ...);
-	void	(*cprintf) (edict_t *ent, int printlevel, char *fmt, ...);
-	void	(*centerprintf) (edict_t *ent, char *fmt, ...);
-	void	(*sound) (edict_t *ent, int channel, int soundindex, float volume, float attenuation, float timeofs);
-	void	(*positioned_sound) (vec3_t origin, edict_t *ent, int channel, int soundinedex, float volume, float attenuation, float timeofs);
+	/* gitem_t->weapmodel model index */
+	WEAP_BLASTER = 1, 
+	WEAP_SHOTGUN = 2, 
+	WEAP_SUPERSHOTGUN = 3, 
+	WEAP_MACHINEGUN = 4, 
+	WEAP_CHAINGUN = 5, 
+	WEAP_GRENADES = 6, 
+	WEAP_GRENADELAUNCHER = 7, 
+	WEAP_ROCKETLAUNCHER = 8, 
+	WEAP_HYPERBLASTER = 9, 
+	WEAP_RAILGUN = 10,
+	WEAP_BFG = 11,
+	WEAP_GRAPPLE = 12,
 
-	// config strings hold all the index strings, the lightstyles,
-	// and misc data like the sky definition and cdtrack.
-	// All of the current configstrings are sent to clients when
-	// they connect, and changes are sent to all connected clients.
-	void	(*configstring) (int num, char *string);
+	/* means of death */
+	MOD_UNKNOWN = 0,
+	MOD_BLASTER = 1,
+	MOD_SHOTGUN = 2,
+	MOD_SSHOTGUN = 3,
+	MOD_MACHINEGUN = 4,
+	MOD_CHAINGUN = 5,
+	MOD_GRENADE = 6,
+	MOD_G_SPLASH = 7,
+	MOD_ROCKET = 8,
+	MOD_R_SPLASH = 9,
+	MOD_HYPERBLASTER = 10,
+	MOD_RAILGUN = 11,
+	MOD_BFG_LASER = 12,
+	MOD_BFG_BLAST = 13,
+	MOD_BFG_EFFECT = 14,
+	MOD_HANDGRENADE = 15,
+	MOD_HG_SPLASH = 16,
+	MOD_WATER = 17,
+	MOD_SLIME = 18,
+	MOD_LAVA = 19,
+	MOD_CRUSH = 20,
+	MOD_TELEFRAG = 21,
+	MOD_FALLING = 22,
+	MOD_SUICIDE = 23,
+	MOD_HELD_GRENADE = 24,
+	MOD_EXPLOSIVE = 25,
+	MOD_BARREL = 26,
+	MOD_BOMB = 27,
+	MOD_EXIT = 28,
+	MOD_SPLASH = 29,
+	MOD_TARGET_LASER = 30,
+	MOD_TRIGGER_HURT = 31,
+	MOD_HIT = 32,
+	MOD_TARGET_BLASTER = 33,
+	MOD_GRAPPLE = 34,
+	MOD_FRIENDLY_FIRE = 1<<27,
 
-	void	(*error) (char *fmt, ...);
+	/* item spawnflags */
+	ITEM_TRIGGER_SPAWN = 1<<0,
+	ITEM_NO_TOUCH = 1<<1,
+	/* 6 bits reserved for editor flags */
+	/* 8 bits used as power cube id bits for coop games */
+	DROPPED_ITEM = 1<<16,
+	DROPPED_PLAYER_ITEM = 1<<17,
+	ITEM_TARGETS_USED = 1<<18,
 
-	// the *index functions create configstrings and some internal server state
-	int		(*modelindex) (char *name);
-	int		(*soundindex) (char *name);
-	int		(*imageindex) (char *name);
+	/* fields are needed for spawning from the entity string and saving or
+	 * loading games */
+	FFL_SPAWNTEMP = 1,
 
-	void	(*setmodel) (edict_t *ent, char *name);
+	/* damage flags */
+	DAMAGE_RADIUS = 1<<0,	// damage was indirect
+	DAMAGE_NO_ARMOR = 1<<1,	// armour does not protect from this damage
+	DAMAGE_ENERGY = 1<<2,	// damage is from an energy based weapon
+	DAMAGE_NO_KNOCKBACK = 1<<3,	// do not affect velocity, just view angles
+	DAMAGE_BULLET = 1<<4,	// damage is from a bullet (used for ricochets)
+	DAMAGE_NO_PROTECTION = 1<<5,	// armor, shields, invulnerability, and godmode have no effect
 
-	// collision detection
-	trace_t	(*trace) (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *passent, int contentmask);
-	int		(*pointcontents) (vec3_t point);
-	qboolean	(*inPVS) (vec3_t p1, vec3_t p2);
-	qboolean	(*inPHS) (vec3_t p1, vec3_t p2);
-	void		(*SetAreaPortalState) (int portalnum, qboolean open);
-	qboolean	(*AreasConnected) (int area1, int area2);
+	DEFAULT_BULLET_HSPREAD = 300,
+	DEFAULT_BULLET_VSPREAD = 500,
+	DEFAULT_SHOTGUN_HSPREAD = 1000,
+	DEFAULT_SHOTGUN_VSPREAD = 500,
+	DEFAULT_DEATHMATCH_SHOTGUN_COUNT = 12,
+	DEFAULT_SHOTGUN_COUNT = 12,
+	DEFAULT_SSHOTGUN_COUNT = 20,
 
-	// an entity will never be sent to a client or used for collision
-	// if it is not passed to linkentity.  If the size, position, or
-	// solidity changes, it must be relinked.
-	void	(*linkentity) (edict_t *ent);
-	void	(*unlinkentity) (edict_t *ent);		// call before removing an interactive edict
-	int		(*BoxEdicts) (vec3_t mins, vec3_t maxs, edict_t **list,	int maxcount, int areatype);
-	void	(*Pmove) (pmove_t *pmove);		// player movement code common with client prediction
+	PMENU_ALIGN_LEFT = 0,
+	PMENU_ALIGN_CENTER,
+	PMENU_ALIGN_RIGHT,
 
-	// network messaging
-	void	(*multicast) (vec3_t origin, multicast_t to);
-	void	(*unicast) (edict_t *ent, qboolean reliable);
-	void	(*WriteChar) (int c);
-	void	(*WriteByte) (int c);
-	void	(*WriteShort) (int c);
-	void	(*WriteLong) (int c);
-	void	(*WriteFloat) (float f);
-	void	(*WriteString) (char *s);
-	void	(*WritePosition) (vec3_t pos);	// some fractional bits
-	void	(*WriteDir) (vec3_t pos);		// single byte encoded, very coarse
-	void	(*WriteAngle) (float f);
+	/* client_t->anim_priority */
+	ANIM_BASIC = 0,	// stand / run
+	ANIM_WAVE = 1,
+	ANIM_JUMP = 2,
+	ANIM_PAIN = 3,
+	ANIM_ATTACK = 4,
+	ANIM_DEATH = 5,
+	ANIM_REVERSE = 6
+};
+extern int meansOfDeath;
+extern int sm_meat_index;
+extern int snd_fry;
 
-	// managed memory allocation
-	void	*(*TagMalloc) (int size, int tag);
-	void	(*TagFree) (void *block);
-	void	(*FreeTags) (int tag);
+typedef enum damage_t{
+	DAMAGE_NO,
+	DAMAGE_YES,	// will take damage if hit
+	DAMAGE_AIM	// auto targeting recognizes this
+}damage_t;
+typedef enum weaponstate_t{
+	WEAPON_READY, 
+	WEAPON_ACTIVATING,
+	WEAPON_DROPPING,
+	WEAPON_FIRING
+}weaponstate_t;
+typedef enum ammo_t{
+	AMMO_BULLETS,
+	AMMO_SHELLS,
+	AMMO_ROCKETS,
+	AMMO_GRENADES,
+	AMMO_CELLS,
+	AMMO_SLUGS
+}ammo_t;
+/* edict->movetype values */
+typedef enum movetype_t{
+	MOVETYPE_NONE,	// never moves
+	MOVETYPE_NOCLIP,	// origin and angles change with no interaction
+	MOVETYPE_PUSH,	// no clip to world, push on box contact
+	MOVETYPE_STOP,	// no clip to world, stops on box contact
+	MOVETYPE_WALK,	// gravity
+	MOVETYPE_STEP,	// gravity, special edge handling
+	MOVETYPE_FLY,
+	MOVETYPE_TOSS,	// gravity
+	MOVETYPE_FLYMISSILE,	// extra size to monsters
+	MOVETYPE_BOUNCE
+}movetype_t;
 
-	// console variable interaction
-	cvar_t	*(*cvar) (char *var_name, char *value, int flags);
-	cvar_t	*(*cvar_set) (char *var_name, char *value);
-	cvar_t	*(*cvar_forceset) (char *var_name, char *value);
+struct gitem_armor_t{
+	int base_count;
+	int max_count;
+	float normal_protection;
+	float energy_protection;
+	int armor;
+};
+struct gitem_t{
+	char *classname;	// spawning name
+	qboolean	(*pickup)(edict_t *, edict_t *);
+	void	(*use)(edict_t *, gitem_t *);
+	void	(*drop)(edict_t *, gitem_t *);
+	void	(*weaponthink)(edict_t *);
+	char *pickup_sound;
+	char *world_model;
+	int world_model_flags;
+	char *view_model;
+	/* client side info */
+	char *icon;
+	char *pickup_name;	// for printing on pickup
+	int count_width;	// number of digits to display by icon
+	int quantity;	// for ammo how much, for weapons how much is used per shot
+	char *ammo;	// for weapons
+	int flags;	// IT_* flags
+	int weapmodel;	// weapon model index (for weapons)
+	void *info;
+	int tag;
+	char *precaches;	// string of all models, sounds, and images this item will use
+};
+extern gitem_t itemlist[];
+/* this structure is left intact through an entire game. it should be
+ * initialized at dll load time, and read/written to the server.ssv file for
+ * savegames */
+struct game_locals_t{
+	char helpmessage1[512];
+	char helpmessage2[512];
+	/* flash F1 icon if non 0, play sound and increment only if 1, 2, or 3 */
+	int helpchanged;
+	gclient_t *clients;	// [maxclients]
+	/* can't store spawnpoint in level, because it would get overwritten by
+	 * the savegame restore */
+	char spawnpoint[512];	// needed for coop respawns
+	/* store latched cvars here that we want to get at often */
+	int maxclients;
+	int maxentities;
+	/* cross level triggers */
+	int serverflags;
+	int num_items;
+	qboolean autosaved;
+};
+extern game_locals_t game;
+/* this structure is cleared as each map is entered. it is read/written to the
+ * level.sav file for savegames */
+struct level_locals_t{
+	int framenum;
+	float time;
+	char level_name[MAX_QPATH];	// the descriptive name (Outer Base, etc)
+	char mapname[MAX_QPATH];	// the server name (base1, etc)
+	char nextmap[MAX_QPATH];	// go here when fraglimit is hit
+	char forcemap[MAX_QPATH];	// go here
+	/* intermission state */
+	float intermissiontime;	// time the intermission was started
+	char *changemap;
+	int exitintermission;
+	vec3_t intermission_origin;
+	vec3_t intermission_angle;
+	edict_t *sight_client;	// changed once each frame for coop games
+	edict_t *sight_entity;
+	int sight_entity_framenum;
+	edict_t *sound_entity;
+	int sound_entity_framenum;
+	edict_t *sound2_entity;
+	int sound2_entity_framenum;
+	int pic_health;
+	int total_secrets;
+	int found_secrets;
+	int total_goals;
+	int found_goals;
+	int total_monsters;
+	int killed_monsters;
+	edict_t *current_entity;	// entity running from G_RunFrame
+	int body_que;	// dead bodies
+	int power_cubes;	// ugly necessity for coop
+};
+extern level_locals_t level;
+/* spawn_temp_t is only used to hold entity field values that can be set from
+ * the editor, but aren't actualy present in edict_t during gameplay */
+struct spawn_temp_t{
+	/* world vars */
+	char *sky;
+	float skyrotate;
+	vec3_t skyaxis;
+	char *nextmap;
 
-	// ClientCommand and ServerCommand parameter access
-	int		(*argc) (void);
-	char	*(*argv) (int n);
-	char	*(*args) (void);	// concatenation of all argv >= 1
+	int lip;
+	int distance;
+	int height;
+	char *noise;
+	float pausetime;
+	char *item;
+	char *gravity;
+	float minyaw;
+	float maxyaw;
+	float minpitch;
+	float maxpitch;
+};
+extern spawn_temp_t st;
+struct moveinfo_t{
+	/* fixed data */
+	vec3_t start_origin;
+	vec3_t start_angles;
+	vec3_t end_origin;
+	vec3_t end_angles;
 
-	// add commands to the server console as if they were typed in
-	// for map changing, etc
-	void	(*AddCommandString) (char *text);
+	int sound_start;
+	int sound_middle;
+	int sound_end;
+	float accel;
+	float speed;
+	float decel;
+	float distance;
+	float wait;
+	/* state data */
+	int state;
+	vec3_t dir;
+	float current_speed;
+	float move_speed;
+	float next_speed;
+	float remaining_distance;
+	float decel_distance;
+	void	(*endfunc)(edict_t *);
+};
+struct mframe_t{
+	void	(*aifunc)(edict_t *, float);
+	float dist;
+	void	(*thinkfunc)(edict_t *);
+};
+struct mmove_t{
+	int firstframe;
+	int lastframe;
+	mframe_t *frame;
+	void	(*endfunc)(edict_t *);
+};
+struct monsterinfo_t{
+	mmove_t *currentmove;
+	int aiflags;
+	int nextframe;
+	float scale;
+	void	(*stand)(edict_t *);
+	void	(*idle)(edict_t *);
+	void	(*search)(edict_t *);
+	void	(*walk)(edict_t *);
+	void	(*run)(edict_t *);
+	void	(*dodge)(edict_t *, edict_t *, float);
+	void	(*attack)(edict_t *);
+	void	(*melee)(edict_t *);
+	void	(*sight)(edict_t *, edict_t *);
+	qboolean	(*checkattack)(edict_t *);
+	float pausetime;
+	float attack_finished;
+	vec3_t saved_goal;
+	float search_time;
+	float trail_time;
+	vec3_t last_sighting;
+	int attack_state;
+	int lefty;
+	float idle_time;
+	int linkcount;
+	int power_armor_type;
+	int power_armor_power;
+};
 
-	void	(*DebugGraph) (float value, int color);
-} game_import_t;
+typedef enum fieldtype_t{
+	F_INT,
+	F_FLOAT,
+	F_LSTRING,	// string on disk, pointer in memory, TAG_LEVEL
+	F_GSTRING,	// string on disk, pointer in memory, TAG_GAME
+	F_VECTOR,
+	F_ANGLEHACK,
+	F_EDICT,	// index on disk, pointer in memory
+	F_ITEM,	// index on disk, pointer in memory
+	F_CLIENT,	// index on disk, pointer in memory
+	F_IGNORE
+}fieldtype_t;
+struct field_t{
+	char *name;
+	int ofs;
+	fieldtype_t type;
+	int flags;
+};
+extern field_t fields[];
 
-//
-// functions exported by the game subsystem
-//
-typedef struct
-{
-	int			apiversion;
+struct pmenu_t{
+	char *text;
+	int align;
+	SelectFunc_t SelectFunc;
+};
+struct pmenuhnd_t{
+	pmenu_t *entries;
+	int cur;
+	int num;
+	void *arg;
+};
 
-	// the init function will only be called when a game starts,
-	// not each time a level is loaded.  Persistant data for clients
-	// and the server can be allocated in init
-	void		(*Init) (void);
-	void		(*Shutdown) (void);
+/* client data that stays across multiple level loads */
+struct client_persistant_t{
+	char userinfo[MAX_INFO_STRING];
+	char netname[16];
+	int hand;
+	/* a loadgame will leave valid entities that just don't have a
+	 * connection yet */
+	qboolean connected;
+	/* values saved and restored from edicts when changing levels */
+	int health;
+	int max_health;
+	qboolean powerArmorActive;
+	int selected_item;
+	int inventory[MAX_ITEMS];
+	/* ammo capacities */
+	int max_bullets;
+	int max_shells;
+	int max_rockets;
+	int max_grenades;
+	int max_cells;
+	int max_slugs;
+	gitem_t *weapon;
+	gitem_t *lastweapon;
+	int power_cubes;	// used for tracking the cubes in coop games
+	int score;	// for calculating total unit score in coop games
+};
+/* client data that stays across deathmatch respawns */
+struct client_respawn_t{
+	client_persistant_t coop_respawn;	// what to set client->pers to on a respawn
+	int enterframe;	// level.framenum the client entered the game
+	int score;	// frags, etc
+	int ctf_team;
+	int ctf_state;
+	float ctf_lasthurtcarrier;
+	float ctf_lastreturnedflag;
+	float ctf_flagsince;
+	float ctf_lastfraggedcarrier;
+	qboolean id_state;
+	qboolean voted;	// for elections
+	qboolean ready;
+	qboolean admin;
+	ghost_t *ghost;	// for ghost codes
+	vec3_t cmd_angles;	// angles sent over in the last command
+	int game_helpchanged;
+	int helpchanged;
+};
 
-	// each new level entered will cause a call to SpawnEntities
-	void		(*SpawnEntities) (char *mapname, char *entstring, char *spawnpoint);
+/* this structure is cleared on each PutClientInServer(), except for .pers */
+struct gclient_t{
+	/* known to server */
+	player_state_t ps;	// communicated by server to clients
+	int ping;
 
-	// Read/Write Game is for storing persistant cross level information
-	// about the world state and the clients.
-	// WriteGame is called every time a level is exited.
-	// ReadGame is called on a loadgame.
-	void		(*WriteGame) (char *filename, qboolean autosave);
-	void		(*ReadGame) (char *filename);
+	/* private to game */
+	client_persistant_t pers;
+	client_respawn_t resp;
+	pmove_state_t old_pmove;	// for detecting out-of-pmove changes
+
+	qboolean showscores;	// set layout stat
+	qboolean inmenu;	// in menu
+	pmenuhnd_t *menu;	// current menu
+	qboolean showinventory;	// set layout stat
+	qboolean showhelp;
+	qboolean showhelpicon;
+	int ammo_index;
+	int buttons;
+	int oldbuttons;
+	int latched_buttons;
+	qboolean weapon_thunk;
+	gitem_t *newweapon;
+	/* sum up damage over an entire frame, so shotgun blasts give a single
+	 * big kick */
+	int damage_armor;	// damage absorbed by armor
+	int damage_parmor;	// damage absorbed by power armor
+	int damage_blood;	// damage taken out of health
+	int damage_knockback;	// impact damage
+	vec3_t damage_from;	// origin for vector calculation
+	float killer_yaw;	// when dead, look at killer
+	weaponstate_t weaponstate;
+	vec3_t kick_angles;	// weapon kicks
+	vec3_t kick_origin;
+	float v_dmg_roll;	// damage kicks
+	float v_dmg_pitch;
+	float v_dmg_time;
+	float fall_time;	// for view drop on fall
+	float fall_value;
+	float damage_alpha;
+	float bonus_alpha;
+	vec3_t damage_blend;
+	vec3_t v_angle;	// aiming direction
+	float bobtime;	// so off-ground doesn't change it
+	vec3_t oldviewangles;
+	vec3_t oldvelocity;
+	float next_drown_time;
+	int old_waterlevel;
+	int breather_sound;
+	int machinegun_shots;	// for weapon raising
+	/* animation vars */
+	int anim_end;
+	int anim_priority;
+	qboolean anim_duck;
+	qboolean anim_run;
+	/* powerup timers */
+	float quad_framenum;
+	float invincible_framenum;
+	float breather_framenum;
+	float enviro_framenum;
+	qboolean grenade_blew_up;
+	float grenade_time;
+	int silencer_shots;
+	int weapon_sound;
+	float pickup_msg_time;
+	float flood_locktill;	// locked from talking
+	float flood_when[10];	// when messages were said
+	int flood_whenhead;	// head pointer for when said
+	float respawn_time;	// can respawn when time > this
+	void *ctf_grapple;	// entity of grapple
+	int ctf_grapplestate;	// true if pulling
+	float ctf_grapplereleasetime;	// time of grapple release
+	float ctf_regentime;	// regen tech
+	float ctf_techsndtime;
+	float ctf_lasttechmsg;
+	edict_t *chase_target;
+	qboolean update_chase;
+	float menutime;	// time to update menu
+	qboolean menudirty;
+};
+struct edict_t{
+	entity_state_t s;
+	gclient_t *client;	// nil if not a player
+
+	/* the server expects the first part of gclient_s to be a
+	 * player_state_t but the rest of it is opaque */
+	qboolean inuse;
+	int linkcount;
+	// FIXME: move these fields to a server private sv_entity_t
+	link_t area;	// linked to a division node or leaf
+	int num_clusters;	// if -1, use headnode instead
+	int clusternums[MAX_ENT_CLUSTERS];
+	int headnode;	// unused if num_clusters != -1
+	int areanum;
+	int areanum2;
+	int svflags;
+	vec3_t mins;
+	vec3_t maxs;
+	vec3_t absmin;
+	vec3_t absmax;
+	vec3_t size;
+	solid_t solid;
+	int clipmask;
+	edict_t *owner;
+
+	/* DO NOT MODIFY ANYTHING ABOVE THIS, THE SERVER EXPECTS THE FIELDS IN
+	 * THAT ORDER! */
+
+	int movetype;
+	int flags;
+	char *model;
+	float freetime;	// sv.time when the object was freed
+	/* only used locally in game, not by server */
+	char *message;
+	char *classname;
+	int spawnflags;
+	float timestamp;
+	float angle;	// set in qe3, -1 = up, -2 = down
+	char *target;
+	char *targetname;
+	char *killtarget;
+	char *team;
+	char *pathtarget;
+	char *deathtarget;
+	char *combattarget;
+	edict_t *target_ent;
+	float speed;
+	float accel;
+	float decel;
+	vec3_t movedir;
+	vec3_t pos1;
+	vec3_t pos2;
+	vec3_t velocity;
+	vec3_t avelocity;
+	int mass;
+	float air_finished;
+	/* per entity gravity multiplier (1.0 is normal); use for lowgrav
+	 * artifact, flares */
+	float gravity;
+	edict_t *goalentity;
+	edict_t *movetarget;
+	float yaw_speed;
+	float ideal_yaw;
+	float nextthink;
+	void	(*prethink)(edict_t *);
+	void	(*think)(edict_t *);
+	void	(*blocked)(edict_t *, edict_t *);	// move to moveinfo?
+	void	(*touch)(edict_t *, edict_t *, cplane_t *, csurface_t *);
+	void	(*use)(edict_t *, edict_t *, edict_t *);
+	void	(*pain)(edict_t *, edict_t *, float, int);
+	void	(*die)(edict_t *, edict_t *, edict_t *, int, vec3_t);
+	float touch_debounce_time;	// are all these legit? do we need more/less of them?
+	float pain_debounce_time;
+	float damage_debounce_time;
+	float fly_sound_debounce_time;	// move to clientinfo
+	float last_move_time;
+	int health;
+	int max_health;
+	int gib_health;
+	int deadflag;
+	qboolean show_hostile;
+	float powerarmor_time;
+	char *map;	// target_changelevel
+	int viewheight;	// height above origin where eyesight is determined
+	int takedamage;
+	int dmg;
+	int radius_dmg;
+	float dmg_radius;
+	int sounds;	// make this a spawntemp var?
+	int count;
+	edict_t *chain;
+	edict_t *enemy;
+	edict_t *oldenemy;
+	edict_t *activator;
+	edict_t *groundentity;
+	int groundentity_linkcount;
+	edict_t *teamchain;
+	edict_t *teammaster;
+	edict_t *mynoise;	// can go in client only
+	edict_t *mynoise2;
+	int noise_index;
+	int oise_index2;
+	float volume;
+	float attenuation;
+	/* timing variables */
+	float wait;
+	float delay;	// before firing targets
+	float random;
+	float teleport_time;
+	int watertype;
+	int waterlevel;
+	vec3_t move_origin;
+	vec3_t move_angles;
+	int light_level;	// move this to clientinfo?
+	int style;	// also used as areaportal number
+	gitem_t *item;	// for bonus items
+	/* common data blocks */
+	moveinfo_t moveinfo;
+	monsterinfo_t monsterinfo;
+};
+extern edict_t *g_edicts;
 
-	// ReadLevel is called after the default map information has been
-	// loaded with SpawnEntities
-	void		(*WriteLevel) (char *filename);
-	void		(*ReadLevel) (char *filename);
+#define CTF_VERSION	"1.09b"
+#define CTF_TEAM1_SKIN	"ctf_r"
+#define CTF_TEAM2_SKIN	"ctf_b"
+enum{
+	STAT_CTF_TEAM1_PIC = 17,
+	STAT_CTF_TEAM1_CAPS = 18,
+	STAT_CTF_TEAM2_PIC = 19,
+	STAT_CTF_TEAM2_CAPS = 20,
+	STAT_CTF_FLAG_PIC = 21,
+	STAT_CTF_JOINED_TEAM1_PIC = 22,
+	STAT_CTF_JOINED_TEAM2_PIC = 23,
+	STAT_CTF_TEAM1_HEADER = 24,
+	STAT_CTF_TEAM2_HEADER = 25,
+	STAT_CTF_TECH = 26,
+	STAT_CTF_ID_VIEW = 27,
+	STAT_CTF_MATCH = 28,
 
-	qboolean	(*ClientConnect) (edict_t *ent, char *userinfo);
-	void		(*ClientBegin) (edict_t *ent);
-	void		(*ClientUserinfoChanged) (edict_t *ent, char *userinfo);
-	void		(*ClientDisconnect) (edict_t *ent);
-	void		(*ClientCommand) (edict_t *ent);
-	void		(*ClientThink) (edict_t *ent, usercmd_t *cmd);
+	CONFIG_CTF_MATCH = CS_MAXCLIENTS-1,
 
-	void		(*RunFrame) (void);
+	DF_CTF_FORCEJOIN = 131072,	
+	DF_ARMOR_PROTECT = 262144,
+	DF_CTF_NO_TECH = 524288,
+	CTF_CAPTURE_BONUS = 15,	// what you get for capture
+	CTF_TEAM_BONUS = 10,	// what your team gets for capture
+	CTF_RECOVERY_BONUS = 1,	// what you get for recovery
+	CTF_FLAG_BONUS = 0,	// what you get for picking up enemy flag
+	CTF_FRAG_CARRIER_BONUS = 2,	// what you get for fragging enemy flag carrier
+	CTF_FLAG_RETURN_TIME = 40,	// seconds until auto return
+	/* bonus for fraggin someone who has recently hurt your flag carrier */
+	CTF_CARRIER_DANGER_PROTECT_BONUS = 2,
+	/* bonus for fraggin someone while either you or your target are near
+	 * your flag carrier */
+	CTF_CARRIER_PROTECT_BONUS = 1,
+	/* bonus for fraggin someone while either you or your target are near
+	 * your flag */
+	CTF_FLAG_DEFENSE_BONUS = 1,
+	/* awarded for returning a flag that causes a capture to happen almost
+	 * immediately */
+	CTF_RETURN_FLAG_ASSIST_BONUS = 1,
+	/* award for fragging a flag carrier if a capture happens almost
+	 * immediately */
+	CTF_FRAG_CARRIER_ASSIST_BONUS = 2,
+	/* the radius around an object being defended where a target will be
+	 * worth extra frags */
+	CTF_TARGET_PROTECT_RADIUS = 400,
+	/* the radius around an object being defended where an attacker will
+	 * get extra frags when making kills */
+	CTF_ATTACKER_PROTECT_RADIUS = 400,
+	CTF_CARRIER_DANGER_PROTECT_TIMEOUT = 8,
+	CTF_FRAG_CARRIER_ASSIST_TIMEOUT = 10,
+	CTF_RETURN_FLAG_ASSIST_TIMEOUT = 10,
+	/* number of seconds before dropped flag auto-returns */
+	CTF_AUTO_FLAG_RETURN_TIMEOUT = 30,
+	CTF_TECH_TIMEOUT = 60,	// seconds before techs spawn again
+	CTF_GRAPPLE_SPEED = 650,	// speed of grapple in flight
+	CTF_GRAPPLE_PULL_SPEED = 650	// speed player is pulled at
+};
 
-	// ServerCommand will be called when an "sv <command>" command is issued on the
-	// server console.
-	// The game can issue gi.argc() / gi.argv() commands to get the rest
-	// of the parameters
-	void		(*ServerCommand) (void);
+typedef enum ctfteam_t{
+	CTF_NOTEAM,
+	CTF_TEAM1,
+	CTF_TEAM2
+}ctfteam_t;
+typedef enum ctfgrapplestate_t{
+	CTF_GRAPPLE_STATE_FLY,
+	CTF_GRAPPLE_STATE_PULL,
+	CTF_GRAPPLE_STATE_HANG
+}ctfgrapplestate_t;
 
-	//
-	// global variables shared between game and server
-	//
+struct ghost_t{
+	char netname[16];
+	int number;
+	/* stats */
+	int deaths;
+	int kills;
+	int caps;
+	int basedef;
+	int carrierdef;
+	int code;	// ghost code
+	int team;	// team
+	int score;	// frags at time of disconnect
+	edict_t *ent;
+};
 
-	// The edict array is allocated in the game dll so it
-	// can vary in size from one game to another.
-	// 
-	// The size will be fixed when ge->Init() is called
-	edict_t	*edicts;
-	int			edict_size;
-	int			num_edicts;		// current number, <= max_edicts
-	int			max_edicts;
-} game_export_t;
+extern char *ctf_statusbar;
 
-game_export_t *GetGameApi (game_import_t *import);
+#define WORLD	(&g_edicts[0])
+
+#define qrandom()	((rand () & 0x7fff) / ((float)0x7fff))
+#define crandom()	(2.0 * (qrandom() - 0.5))
+#define	ITEM_INDEX(x)	((x)-itemlist)
+#define	FOFS(x)	(uintptr)&(((edict_t *)0)->x)
+#define	STOFS(x)	(uintptr)&(((spawn_temp_t *)0)->x)
+#define	LLOFS(x)	(uintptr)&(((level_locals_t *)0)->x)
+#define	CLOFS(x)	(uintptr)&(((gclient_t *)0)->x)
+
+game_export_t*	GetGameAPI(game_import_t *);
+qboolean	CheckFlood(edict_t *);
+void	Cmd_Help_f(edict_t *);
+void	Cmd_Score_f(edict_t *);
+void	PrecacheItem(gitem_t *);
+void	InitItems(void);
+void	SetItemNames(void);
+gitem_t*	FindItem(char *);
+gitem_t*	FindItemByClassname(char *);
+edict_t*	Drop_Item(edict_t *, gitem_t *);
+void	SetRespawn(edict_t *, float);
+void	ChangeWeapon(edict_t *);
+void	SpawnItem(edict_t *, gitem_t *);
+void	Think_Weapon(edict_t *);
+int	ArmorIndex(edict_t *);
+int	PowerArmorType(edict_t *);
+gitem_t*	GetItemByIndex(int);
+qboolean	Add_Ammo(edict_t *, gitem_t *, int);
+void	Touch_Item(edict_t *, edict_t *, cplane_t *, csurface_t *);
+qboolean	KillBox(edict_t *);
+void	G_ProjectSource(vec3_t, vec3_t, vec3_t, vec3_t, vec3_t);
+edict_t*	G_Find(edict_t *, int, char *);
+edict_t*	findradius(edict_t *, vec3_t, float);
+edict_t*	G_PickTarget(char *);
+void	G_UseTargets(edict_t *, edict_t *);
+void	G_SetMovedir(vec3_t, vec3_t);
+void	G_InitEdict(edict_t *);
+edict_t*	G_Spawn(void);
+void	G_FreeEdict(edict_t *);
+void	G_TouchTriggers(edict_t *);
+void	G_TouchSolids(edict_t *);
+char*	G_CopyString(char *);
+float*	tv(float, float, float);
+char*	vtos(vec3_t);
+float	vectoyaw(vec3_t);
+void	vectoangles(vec3_t, vec3_t);
+qboolean	OnSameTeam(edict_t *, edict_t *);
+qboolean	CanDamage(edict_t *, edict_t *);
+qboolean	CheckTeamDamage(edict_t *, edict_t *);
+void	T_Damage(edict_t *, edict_t *, edict_t *, vec3_t, vec3_t, vec3_t, int, int, int, int);
+void	T_RadiusDamage(edict_t *, edict_t *, float, edict_t *, float, int);
+void	monster_fire_bullet(edict_t *, vec3_t, vec3_t, int, int, int, int, int);
+void	monster_fire_shotgun(edict_t *, vec3_t, vec3_t, int, int, int, int, int, int);
+void	monster_fire_blaster(edict_t *, vec3_t, vec3_t, int, int, int, int);
+void	monster_fire_grenade(edict_t *, vec3_t, vec3_t, int, int, int);
+void	monster_fire_rocket(edict_t *, vec3_t, vec3_t, int, int, int);
+void	monster_fire_railgun(edict_t *, vec3_t, vec3_t, int, int, int);
+void	monster_fire_bfg(edict_t *, vec3_t, vec3_t, int, int, int, float, int);
+void	M_droptofloor(edict_t *);
+void	monster_think(edict_t *);
+void	walkmonster_start(edict_t *);
+void	swimmonster_start(edict_t *);
+void	flymonster_start(edict_t *);
+void	AttackFinished(edict_t *, float);
+void	monster_death_use(edict_t *);
+void	M_CatagorizePosition(edict_t *);
+qboolean	M_CheckAttack(edict_t *);
+void	M_FlyCheck(edict_t *);
+void	M_CheckGround(edict_t *);
+void	ThrowHead(edict_t *, char *, int, int);
+void	ThrowClientHead(edict_t *, int);
+void	ThrowGib(edict_t *, char *, int, int);
+void	BecomeExplosion1(edict_t *);
+void	AI_SetSightClient(void);
+void	ai_stand(edict_t *, float);
+void	ai_move(edict_t *, float);
+void	ai_walk(edict_t *, float);
+void	ai_turn(edict_t *, float);
+void	ai_run(edict_t *, float);
+void	ai_charge(edict_t *, float);
+int	range(edict_t *, edict_t *);
+void	FoundTarget(edict_t *);
+qboolean	infront(edict_t *, edict_t *);
+qboolean	visible(edict_t *, edict_t *);
+qboolean	FacingIdeal(edict_t *);
+void	ThrowDebris(edict_t *, char *, float, vec3_t);
+qboolean	fire_hit(edict_t *, vec3_t, int, int);
+void	fire_bullet(edict_t *, vec3_t, vec3_t, int, int, int, int, int);
+void	fire_shotgun(edict_t *, vec3_t, vec3_t, int, int, int, int, int, int);
+void	fire_blaster(edict_t *, vec3_t, vec3_t, int, int, int, qboolean);
+void	fire_grenade(edict_t *, vec3_t, vec3_t, int, int, float, float);
+void	fire_grenade2(edict_t *, vec3_t, vec3_t, int, int, float, float, qboolean);
+void	fire_rocket(edict_t *, vec3_t, vec3_t, int, int, float, int);
+void	fire_rail(edict_t *, vec3_t, vec3_t, int, int);
+void	fire_bfg(edict_t *, vec3_t, vec3_t, int, int, float);
+void	PlayerTrail_Init(void);
+void	PlayerTrail_Add(vec3_t);
+void	PlayerTrail_New(vec3_t);
+edict_t*	PlayerTrail_PickFirst(edict_t *);
+edict_t*	PlayerTrail_PickNext(edict_t *);
+edict_t*	PlayerTrail_LastSpot(void);
+void	respawn(edict_t *);
+void	BeginIntermission(edict_t *);
+void	PutClientInServer(edict_t *);
+void	InitClientPersistant(gclient_t *);
+void	InitClientResp(gclient_t *);
+void	InitBodyQue(void);
+void	ClientBeginServerFrame(edict_t *);
+void	player_pain(edict_t *, edict_t *, float, int);
+void	player_die(edict_t *, edict_t *, edict_t *, int, vec3_t);
+void	ServerCommand(void);
+void	ClientEndServerFrame(edict_t *);
+void	MoveClientToIntermission(edict_t *);
+void	G_SetStats(edict_t *);
+void	ValidateSelectedItem(edict_t *);
+void	DeathmatchScoreboardMessage(edict_t *, edict_t *);
+void	PlayerNoise(edict_t *, vec3_t, int);
+void	P_ProjectSource(gclient_t *, vec3_t, vec3_t, vec3_t, vec3_t, vec3_t);
+void	Weapon_Generic(edict_t *, int, int, int, int, int *, int *, void(*)(edict_t *));
+qboolean	M_CheckBottom(edict_t *);
+qboolean	M_walkmove(edict_t *, float, float);
+void	M_MoveToGoal(edict_t *, float);
+void	M_ChangeYaw(edict_t *);
+void	G_RunEntity(edict_t *);
+void	SaveClientData(void);
+void	FetchClientEntData(edict_t *);
+void	EndDMLevel(void);
+pmenuhnd_t*	PMenu_Open(edict_t *, pmenu_t *, int, int, void *);
+void	PMenu_Close(edict_t *);
+void	PMenu_UpdateEntry(pmenu_t *, char *, int, SelectFunc_t);
+void	PMenu_Do_Update(edict_t *);
+void	PMenu_Update(edict_t *);
+void	PMenu_Next(edict_t *);
+void	PMenu_Prev(edict_t *);
+void	PMenu_Select(edict_t *);
+void	CTFInit(void);
+void	CTFSpawn(void);
+void	SP_info_player_team1(edict_t *);
+void	SP_info_player_team2(edict_t *);
+char	*CTFTeamName(int);
+char	*CTFOtherTeamName(int);
+void	CTFAssignSkin(edict_t *, char *);
+void	CTFAssignTeam(gclient_t *);
+edict_t*	SelectCTFSpawnPoint(edict_t *);
+qboolean	CTFPickup_Flag(edict_t *, edict_t *);
+void	CTFDrop_Flag(edict_t *, gitem_t *);
+void	CTFEffects(edict_t *);
+void	CTFCalcScores(void);
+void	SetCTFStats(edict_t *);
+void	CTFDeadDropFlag(edict_t *);
+void	CTFScoreboardMessage(edict_t *, edict_t *);
+void	CTFTeam_f(edict_t *);
+void	CTFID_f(edict_t *);
+void	CTFSay_Team(edict_t *, char *);
+void	CTFFlagSetup(edict_t *);
+void	CTFResetFlag(int);
+void	CTFFragBonuses(edict_t *, edict_t *, edict_t *);
+void	CTFCheckHurtCarrier(edict_t *, edict_t *);
+void	CTFWeapon_Grapple(edict_t *);
+void	CTFPlayerResetGrapple(edict_t *);
+void	CTFGrapplePull(edict_t *);
+void	CTFResetGrapple(edict_t *);
+gitem_t*	CTFWhat_Tech(edict_t *);
+qboolean	CTFPickup_Tech(edict_t *, edict_t *);
+void	CTFDrop_Tech(edict_t *, gitem_t *);
+void	CTFDeadDropTech(edict_t *);
+void	CTFSetupTechSpawn(void);
+int	CTFApplyResistance(edict_t *, int);
+int	CTFApplyStrength(edict_t *, int);
+qboolean	CTFApplyStrengthSound(edict_t *);
+qboolean	CTFApplyHaste(edict_t *);
+void	CTFApplyHasteSound(edict_t *);
+void	CTFApplyRegeneration(edict_t *);
+qboolean	CTFHasRegeneration(edict_t *);
+void	CTFRespawnTech(edict_t *);
+void	CTFResetTech(void);
+void	CTFOpenJoinMenu(edict_t *);
+qboolean	CTFStartClient(edict_t *);
+void	CTFVoteYes(edict_t *);
+void	CTFVoteNo(edict_t *);
+void	CTFReady(edict_t *);
+void	CTFNotReady(edict_t *);
+qboolean	CTFNextMap(void);
+qboolean	CTFMatchSetup(void);
+qboolean	CTFMatchOn(void);
+void	CTFGhost(edict_t *);
+void	CTFAdmin(edict_t *);
+qboolean	CTFInMatch(void);
+void	CTFStats(edict_t *);
+void	CTFWarp(edict_t *);
+void	CTFBoot(edict_t *);
+void	CTFPlayerList(edict_t *);
+qboolean	CTFCheckRules(void);
+void	SP_misc_ctf_banner(edict_t *);
+void	SP_misc_ctf_small_banner(edict_t *);
+void	UpdateChaseCam(edict_t *);
+void	ChaseNext(edict_t *);
+void	ChasePrev(edict_t *);
+void	CTFObserver(edict_t *);
+void	SP_trigger_teleport(edict_t *);
+void	SP_info_teleport_destination(edict_t *);
+void	SP_item_health(edict_t *);
+void	SP_item_health_small(edict_t *);
+void	SP_item_health_large(edict_t *);
+void	SP_item_health_mega(edict_t *);
+void	SP_info_player_start(edict_t *);
+void	SP_info_player_deathmatch(edict_t *);
+void	SP_info_player_coop(edict_t *);
+void	SP_info_player_intermission(edict_t *);
+void	SP_func_plat(edict_t *);
+void	SP_func_rotating(edict_t *);
+void	SP_func_button(edict_t *);
+void	SP_func_door(edict_t *);
+void	SP_func_door_secret(edict_t *);
+void	SP_func_door_rotating(edict_t *);
+void	SP_func_water(edict_t *);
+void	SP_func_train(edict_t *);
+void	SP_func_conveyor(edict_t *);
+void	SP_func_wall(edict_t *);
+void	SP_func_object(edict_t *);
+void	SP_func_explosive(edict_t *);
+void	SP_func_timer(edict_t *);
+void	SP_func_areaportal(edict_t *);
+void	SP_func_clock(edict_t *);
+void	SP_func_killbox(edict_t *);
+void	SP_trigger_always(edict_t *);
+void	SP_trigger_once(edict_t *);
+void	SP_trigger_multiple(edict_t *);
+void	SP_trigger_relay(edict_t *);
+void	SP_trigger_push(edict_t *);
+void	SP_trigger_hurt(edict_t *);
+void	SP_trigger_key(edict_t *);
+void	SP_trigger_counter(edict_t *);
+void	SP_trigger_elevator(edict_t *);
+void	SP_trigger_gravity(edict_t *);
+void	SP_trigger_monsterjump(edict_t *);
+void	SP_target_temp_entity(edict_t *);
+void	SP_target_speaker(edict_t *);
+void	SP_target_explosion(edict_t *);
+void	SP_target_changelevel(edict_t *);
+void	SP_target_secret(edict_t *);
+void	SP_target_goal(edict_t *);
+void	SP_target_splash(edict_t *);
+void	SP_target_spawner(edict_t *);
+void	SP_target_blaster(edict_t *);
+void	SP_target_crosslevel_trigger(edict_t *);
+void	SP_target_crosslevel_target(edict_t *);
+void	SP_target_laser(edict_t *);
+void	SP_target_help(edict_t *);
+void	SP_target_actor(edict_t *);
+void	SP_target_lightramp(edict_t *);
+void	SP_target_earthquake(edict_t *);
+void	SP_target_character(edict_t *);
+void	SP_target_string(edict_t *);
+void	SP_worldspawn(edict_t *);
+void	SP_viewthing(edict_t *);
+void	SP_light(edict_t *);
+void	SP_light_mine1(edict_t *);
+void	SP_light_mine2(edict_t *);
+void	SP_info_null(edict_t *);
+void	SP_info_notnull(edict_t *);
+void	SP_path_corner(edict_t *);
+void	SP_point_combat(edict_t *);
+void	SP_misc_explobox(edict_t *);
+void	SP_misc_banner(edict_t *);
+void	SP_misc_satellite_dish(edict_t *);
+void	SP_misc_actor(edict_t *);
+void	SP_misc_gib_arm(edict_t *);
+void	SP_misc_gib_leg(edict_t *);
+void	SP_misc_gib_head(edict_t *);
+void	SP_misc_insane(edict_t *);
+void	SP_misc_deadsoldier(edict_t *);
+void	SP_misc_viper(edict_t *);
+void	SP_misc_viper_bomb(edict_t *);
+void	SP_misc_bigviper(edict_t *);
+void	SP_misc_strogg_ship(edict_t *);
+void	SP_misc_teleporter(edict_t *);
+void	SP_misc_teleporter_dest(edict_t *);
+void	SP_misc_blackhole(edict_t *);
+void	SP_misc_eastertank(edict_t *);
+void	SP_misc_easterchick(edict_t *);
+void	SP_misc_easterchick2(edict_t *);
+void	SP_monster_berserk(edict_t *);
+void	SP_monster_gladiator(edict_t *);
+void	SP_monster_gunner(edict_t *);
+void	SP_monster_infantry(edict_t *);
+void	SP_monster_soldier_light(edict_t *);
+void	SP_monster_soldier(edict_t *);
+void	SP_monster_soldier_ss(edict_t *);
+void	SP_monster_tank(edict_t *);
+void	SP_monster_medic(edict_t *);
+void	SP_monster_flipper(edict_t *);
+void	SP_monster_chick(edict_t *);
+void	SP_monster_parasite(edict_t *);
+void	SP_monster_flyer(edict_t *);
+void	SP_monster_brain(edict_t *);
+void	SP_monster_floater(edict_t *);
+void	SP_monster_hover(edict_t *);
+void	SP_monster_mutant(edict_t *);
+void	SP_monster_supertank(edict_t *);
+void	SP_monster_boss2(edict_t *);
+void	SP_monster_jorg(edict_t *);
+void	SP_monster_boss3_stand(edict_t *);
+void	SP_monster_commander_body(edict_t *);
+void	SP_turret_breach(edict_t *);
+void	SP_turret_base(edict_t *);
+void	SP_turret_driver(edict_t *);
--- /dev/null
+++ b/ctf/m_flash.c
@@ -1,0 +1,471 @@
+#include <u.h>
+#include <libc.h>
+#include <stdio.h>
+#include "../dat.h"
+#include "../fns.h"
+
+// this file is included in both the game dll and quake2,
+// the game needs it to source shot locations, the client
+// needs it to position muzzle flashes
+vec3_t monster_flash_offset [] =
+{
+// flash 0 is not used
+	0.0, 0.0, 0.0,
+
+// MZ2_TANK_BLASTER_1				1
+	20.7, -18.5, 28.7,
+// MZ2_TANK_BLASTER_2				2
+	16.6, -21.5, 30.1,
+// MZ2_TANK_BLASTER_3				3
+	11.8, -23.9, 32.1,
+// MZ2_TANK_MACHINEGUN_1			4
+	22.9, -0.7, 25.3,
+// MZ2_TANK_MACHINEGUN_2			5
+	22.2, 6.2, 22.3,
+// MZ2_TANK_MACHINEGUN_3			6
+	19.4, 13.1, 18.6,
+// MZ2_TANK_MACHINEGUN_4			7
+	19.4, 18.8, 18.6,
+// MZ2_TANK_MACHINEGUN_5			8
+	17.9, 25.0, 18.6,
+// MZ2_TANK_MACHINEGUN_6			9
+	14.1, 30.5, 20.6,
+// MZ2_TANK_MACHINEGUN_7			10
+	9.3, 35.3, 22.1,
+// MZ2_TANK_MACHINEGUN_8			11
+	4.7, 38.4, 22.1,
+// MZ2_TANK_MACHINEGUN_9			12
+	-1.1, 40.4, 24.1,
+// MZ2_TANK_MACHINEGUN_10			13
+	-6.5, 41.2, 24.1,
+// MZ2_TANK_MACHINEGUN_11			14
+	3.2, 40.1, 24.7,
+// MZ2_TANK_MACHINEGUN_12			15
+	11.7, 36.7, 26.0,
+// MZ2_TANK_MACHINEGUN_13			16
+	18.9, 31.3, 26.0,
+// MZ2_TANK_MACHINEGUN_14			17
+	24.4, 24.4, 26.4,
+// MZ2_TANK_MACHINEGUN_15			18
+	27.1, 17.1, 27.2,
+// MZ2_TANK_MACHINEGUN_16			19
+	28.5, 9.1, 28.0,
+// MZ2_TANK_MACHINEGUN_17			20
+	27.1, 2.2, 28.0,
+// MZ2_TANK_MACHINEGUN_18			21
+	24.9, -2.8, 28.0,
+// MZ2_TANK_MACHINEGUN_19			22
+	21.6, -7.0, 26.4,
+// MZ2_TANK_ROCKET_1				23
+	6.2, 29.1, 49.1,
+// MZ2_TANK_ROCKET_2				24
+	6.9, 23.8, 49.1,
+// MZ2_TANK_ROCKET_3				25
+	8.3, 17.8, 49.5,
+
+// MZ2_INFANTRY_MACHINEGUN_1		26
+	26.6, 7.1, 13.1,
+// MZ2_INFANTRY_MACHINEGUN_2		27
+	18.2, 7.5, 15.4,
+// MZ2_INFANTRY_MACHINEGUN_3		28
+	17.2, 10.3, 17.9,
+// MZ2_INFANTRY_MACHINEGUN_4		29
+	17.0, 12.8, 20.1,
+// MZ2_INFANTRY_MACHINEGUN_5		30
+	15.1, 14.1, 21.8,
+// MZ2_INFANTRY_MACHINEGUN_6		31
+	11.8, 17.2, 23.1,
+// MZ2_INFANTRY_MACHINEGUN_7		32
+	11.4, 20.2, 21.0,
+// MZ2_INFANTRY_MACHINEGUN_8		33
+	9.0, 23.0, 18.9,
+// MZ2_INFANTRY_MACHINEGUN_9		34
+	13.9, 18.6, 17.7,
+// MZ2_INFANTRY_MACHINEGUN_10		35
+	15.4, 15.6, 15.8,
+// MZ2_INFANTRY_MACHINEGUN_11		36
+	10.2, 15.2, 25.1,
+// MZ2_INFANTRY_MACHINEGUN_12		37
+	-1.9, 15.1, 28.2,
+// MZ2_INFANTRY_MACHINEGUN_13		38
+	-12.4, 13.0, 20.2,
+
+// MZ2_SOLDIER_BLASTER_1			39
+	10.6 * 1.2, 7.7 * 1.2, 7.8 * 1.2,
+// MZ2_SOLDIER_BLASTER_2			40
+	21.1 * 1.2, 3.6 * 1.2, 19.0 * 1.2,
+// MZ2_SOLDIER_SHOTGUN_1			41
+	10.6 * 1.2, 7.7 * 1.2, 7.8 * 1.2,
+// MZ2_SOLDIER_SHOTGUN_2			42
+	21.1 * 1.2, 3.6 * 1.2, 19.0 * 1.2,
+// MZ2_SOLDIER_MACHINEGUN_1			43
+	10.6 * 1.2, 7.7 * 1.2, 7.8 * 1.2,
+// MZ2_SOLDIER_MACHINEGUN_2			44
+	21.1 * 1.2, 3.6 * 1.2, 19.0 * 1.2,
+
+// MZ2_GUNNER_MACHINEGUN_1			45
+	30.1 * 1.15, 3.9 * 1.15, 19.6 * 1.15,
+// MZ2_GUNNER_MACHINEGUN_2			46
+	29.1 * 1.15, 2.5 * 1.15, 20.7 * 1.15,
+// MZ2_GUNNER_MACHINEGUN_3			47
+	28.2 * 1.15, 2.5 * 1.15, 22.2 * 1.15,
+// MZ2_GUNNER_MACHINEGUN_4			48
+	28.2 * 1.15, 3.6 * 1.15, 22.0 * 1.15,
+// MZ2_GUNNER_MACHINEGUN_5			49
+	26.9 * 1.15, 2.0 * 1.15, 23.4 * 1.15,
+// MZ2_GUNNER_MACHINEGUN_6			50
+	26.5 * 1.15, 0.6 * 1.15, 20.8 * 1.15,
+// MZ2_GUNNER_MACHINEGUN_7			51
+	26.9 * 1.15, 0.5 * 1.15, 21.5 * 1.15,
+// MZ2_GUNNER_MACHINEGUN_8			52
+	29.0 * 1.15, 2.4 * 1.15, 19.5 * 1.15,
+// MZ2_GUNNER_GRENADE_1				53
+	4.6 * 1.15, -16.8 * 1.15, 7.3 * 1.15,
+// MZ2_GUNNER_GRENADE_2				54
+	4.6 * 1.15, -16.8 * 1.15, 7.3 * 1.15,
+// MZ2_GUNNER_GRENADE_3				55
+	4.6 * 1.15, -16.8 * 1.15, 7.3 * 1.15,
+// MZ2_GUNNER_GRENADE_4				56
+	4.6 * 1.15, -16.8 * 1.15, 7.3 * 1.15,
+
+// MZ2_CHICK_ROCKET_1				57
+//	-24.8, -9.0, 39.0,
+	24.8, -9.0, 39.0,			// PGM - this was incorrect in Q2
+
+// MZ2_FLYER_BLASTER_1				58
+	12.1, 13.4, -14.5,
+// MZ2_FLYER_BLASTER_2				59
+	12.1, -7.4, -14.5,
+
+// MZ2_MEDIC_BLASTER_1				60
+	12.1, 5.4, 16.5,
+
+// MZ2_GLADIATOR_RAILGUN_1			61
+	30.0, 18.0, 28.0,
+
+// MZ2_HOVER_BLASTER_1				62
+	32.5, -0.8, 10.0,
+
+// MZ2_ACTOR_MACHINEGUN_1			63
+	18.4, 7.4, 9.6,
+
+// MZ2_SUPERTANK_MACHINEGUN_1		64
+	30.0, 30.0, 88.5,
+// MZ2_SUPERTANK_MACHINEGUN_2		65
+	30.0, 30.0, 88.5,
+// MZ2_SUPERTANK_MACHINEGUN_3		66
+	30.0, 30.0, 88.5,
+// MZ2_SUPERTANK_MACHINEGUN_4		67
+	30.0, 30.0, 88.5,
+// MZ2_SUPERTANK_MACHINEGUN_5		68
+	30.0, 30.0, 88.5,
+// MZ2_SUPERTANK_MACHINEGUN_6		69
+	30.0, 30.0, 88.5,
+// MZ2_SUPERTANK_ROCKET_1			70
+	16.0, -22.5, 91.2,
+// MZ2_SUPERTANK_ROCKET_2			71
+	16.0, -33.4, 86.7,
+// MZ2_SUPERTANK_ROCKET_3			72
+	16.0, -42.8, 83.3,
+
+// --- Start Xian Stuff ---
+// MZ2_BOSS2_MACHINEGUN_L1			73
+	32,	-40,	70,
+// MZ2_BOSS2_MACHINEGUN_L2			74
+	32,	-40,	70,
+// MZ2_BOSS2_MACHINEGUN_L3			75
+	32,	-40,	70,
+// MZ2_BOSS2_MACHINEGUN_L4			76
+	32,	-40,	70,
+// MZ2_BOSS2_MACHINEGUN_L5			77
+	32,	-40,	70,
+// --- End Xian Stuff
+
+// MZ2_BOSS2_ROCKET_1				78
+	22.0, 16.0, 10.0,
+// MZ2_BOSS2_ROCKET_2				79
+	22.0, 8.0, 10.0,
+// MZ2_BOSS2_ROCKET_3				80
+	22.0, -8.0, 10.0,
+// MZ2_BOSS2_ROCKET_4				81
+	22.0, -16.0, 10.0,
+
+// MZ2_FLOAT_BLASTER_1				82
+	32.5, -0.8, 10,
+
+// MZ2_SOLDIER_BLASTER_3			83
+	20.8 * 1.2, 10.1 * 1.2, -2.7 * 1.2,
+// MZ2_SOLDIER_SHOTGUN_3			84
+	20.8 * 1.2, 10.1 * 1.2, -2.7 * 1.2,
+// MZ2_SOLDIER_MACHINEGUN_3			85
+	20.8 * 1.2, 10.1 * 1.2, -2.7 * 1.2,
+// MZ2_SOLDIER_BLASTER_4			86
+	7.6 * 1.2, 9.3 * 1.2, 0.8 * 1.2,
+// MZ2_SOLDIER_SHOTGUN_4			87
+	7.6 * 1.2, 9.3 * 1.2, 0.8 * 1.2,
+// MZ2_SOLDIER_MACHINEGUN_4			88
+	7.6 * 1.2, 9.3 * 1.2, 0.8 * 1.2,
+// MZ2_SOLDIER_BLASTER_5			89
+	30.5 * 1.2, 9.9 * 1.2, -18.7 * 1.2,
+// MZ2_SOLDIER_SHOTGUN_5			90
+	30.5 * 1.2, 9.9 * 1.2, -18.7 * 1.2,
+// MZ2_SOLDIER_MACHINEGUN_5			91
+	30.5 * 1.2, 9.9 * 1.2, -18.7 * 1.2,
+// MZ2_SOLDIER_BLASTER_6			92
+	27.6 * 1.2, 3.4 * 1.2, -10.4 * 1.2,
+// MZ2_SOLDIER_SHOTGUN_6			93
+	27.6 * 1.2, 3.4 * 1.2, -10.4 * 1.2,
+// MZ2_SOLDIER_MACHINEGUN_6			94
+	27.6 * 1.2, 3.4 * 1.2, -10.4 * 1.2,
+// MZ2_SOLDIER_BLASTER_7			95
+	28.9 * 1.2, 4.6 * 1.2, -8.1 * 1.2,
+// MZ2_SOLDIER_SHOTGUN_7			96
+	28.9 * 1.2, 4.6 * 1.2, -8.1 * 1.2,
+// MZ2_SOLDIER_MACHINEGUN_7			97
+	28.9 * 1.2, 4.6 * 1.2, -8.1 * 1.2,
+// MZ2_SOLDIER_BLASTER_8			98
+//	34.5 * 1.2, 9.6 * 1.2, 6.1 * 1.2,
+	31.5 * 1.2, 9.6 * 1.2, 10.1 * 1.2,
+// MZ2_SOLDIER_SHOTGUN_8			99
+	34.5 * 1.2, 9.6 * 1.2, 6.1 * 1.2,
+// MZ2_SOLDIER_MACHINEGUN_8			100
+	34.5 * 1.2, 9.6 * 1.2, 6.1 * 1.2,
+
+// --- Xian shit below ---
+// MZ2_MAKRON_BFG					101
+	17,		-19.5,	62.9,
+// MZ2_MAKRON_BLASTER_1				102
+	-3.6,	-24.1,	59.5,
+// MZ2_MAKRON_BLASTER_2				103
+	-1.6,	-19.3,	59.5,
+// MZ2_MAKRON_BLASTER_3				104
+	-0.1,	-14.4,	59.5,		
+// MZ2_MAKRON_BLASTER_4				105
+	2.0,	-7.6,	59.5,	
+// MZ2_MAKRON_BLASTER_5				106
+	3.4,	1.3,	59.5,
+// MZ2_MAKRON_BLASTER_6				107
+	3.7,	11.1,	59.5,	
+// MZ2_MAKRON_BLASTER_7				108
+	-0.3,	22.3,	59.5,
+// MZ2_MAKRON_BLASTER_8				109
+	-6,		33,		59.5,
+// MZ2_MAKRON_BLASTER_9				110
+	-9.3,	36.4,	59.5,
+// MZ2_MAKRON_BLASTER_10			111
+	-7,		35,		59.5,
+// MZ2_MAKRON_BLASTER_11			112
+	-2.1,	29,		59.5,
+// MZ2_MAKRON_BLASTER_12			113
+	3.9,	17.3,	59.5,
+// MZ2_MAKRON_BLASTER_13			114
+	6.1,	5.8,	59.5,
+// MZ2_MAKRON_BLASTER_14			115
+	5.9,	-4.4,	59.5,
+// MZ2_MAKRON_BLASTER_15			116
+	4.2,	-14.1,	59.5,		
+// MZ2_MAKRON_BLASTER_16			117
+	2.4,	-18.8,	59.5,
+// MZ2_MAKRON_BLASTER_17			118
+	-1.8,	-25.5,	59.5,
+// MZ2_MAKRON_RAILGUN_1				119
+	-17.3,	7.8,	72.4,
+
+// MZ2_JORG_MACHINEGUN_L1			120
+	78.5,	-47.1,	96,			
+// MZ2_JORG_MACHINEGUN_L2			121
+	78.5,	-47.1,	96,			
+// MZ2_JORG_MACHINEGUN_L3			122
+	78.5,	-47.1,	96,			
+// MZ2_JORG_MACHINEGUN_L4			123
+	78.5,	-47.1,	96,			
+// MZ2_JORG_MACHINEGUN_L5			124
+	78.5,	-47.1,	96,			
+// MZ2_JORG_MACHINEGUN_L6			125
+	78.5,	-47.1,	96,			
+// MZ2_JORG_MACHINEGUN_R1			126
+	78.5,	46.7,  96,			
+// MZ2_JORG_MACHINEGUN_R2			127
+	78.5,	46.7,	96,			
+// MZ2_JORG_MACHINEGUN_R3			128
+	78.5,	46.7,	96,			
+// MZ2_JORG_MACHINEGUN_R4			129
+	78.5,	46.7,	96,			
+// MZ2_JORG_MACHINEGUN_R5			130
+	78.5,	46.7,	96,			
+// MZ2_JORG_MACHINEGUN_R6			131
+	78.5,	46.7,	96,			
+// MZ2_JORG_BFG_1					132
+	6.3,	-9,		111.2,
+
+// MZ2_BOSS2_MACHINEGUN_R1			73
+	32,	40,	70,
+// MZ2_BOSS2_MACHINEGUN_R2			74
+	32,	40,	70,
+// MZ2_BOSS2_MACHINEGUN_R3			75
+	32,	40,	70,
+// MZ2_BOSS2_MACHINEGUN_R4			76
+	32,	40,	70,
+// MZ2_BOSS2_MACHINEGUN_R5			77
+	32,	40,	70,
+
+// --- End Xian Shit ---
+
+// ROGUE
+// note that the above really ends at 137
+// carrier machineguns
+// MZ2_CARRIER_MACHINEGUN_L1
+	56,	-32, 32,
+// MZ2_CARRIER_MACHINEGUN_R1
+	56,	32, 32,
+// MZ2_CARRIER_GRENADE
+	42,	24, 50,
+// MZ2_TURRET_MACHINEGUN			141
+	16, 0, 0,
+// MZ2_TURRET_ROCKET				142
+	16, 0, 0,
+// MZ2_TURRET_BLASTER				143
+	16, 0, 0,
+// MZ2_STALKER_BLASTER				144
+	24, 0, 6,
+// MZ2_DAEDALUS_BLASTER				145
+	32.5, -0.8, 10.0,
+// MZ2_MEDIC_BLASTER_2				146
+	12.1, 5.4, 16.5,
+// MZ2_CARRIER_RAILGUN				147
+	32, 0, 6, 
+// MZ2_WIDOW_DISRUPTOR				148
+	57.72, 14.50, 88.81,
+// MZ2_WIDOW_BLASTER				149
+	56,	32, 32,
+// MZ2_WIDOW_RAIL					150
+	62, -20, 84, 
+// MZ2_WIDOW_PLASMABEAM				151		// PMM - not used!
+	32, 0, 6, 
+// MZ2_CARRIER_MACHINEGUN_L2		152
+	61,	-32, 12,
+// MZ2_CARRIER_MACHINEGUN_R2		153
+	61,	32, 12,
+// MZ2_WIDOW_RAIL_LEFT				154
+	17, -62, 91, 
+// MZ2_WIDOW_RAIL_RIGHT				155
+	68, 12, 86, 
+// MZ2_WIDOW_BLASTER_SWEEP1			156			pmm - the sweeps need to be in sequential order
+	47.5, 56, 89,
+// MZ2_WIDOW_BLASTER_SWEEP2			157
+	54, 52, 91,
+// MZ2_WIDOW_BLASTER_SWEEP3			158
+	58, 40, 91,
+// MZ2_WIDOW_BLASTER_SWEEP4			159
+	68, 30, 88,
+// MZ2_WIDOW_BLASTER_SWEEP5			160
+	74, 20, 88,
+// MZ2_WIDOW_BLASTER_SWEEP6			161
+	73, 11, 87,
+// MZ2_WIDOW_BLASTER_SWEEP7			162
+	73, 3, 87,
+// MZ2_WIDOW_BLASTER_SWEEP8			163
+	70, -12, 87,
+// MZ2_WIDOW_BLASTER_SWEEP9			164
+	67, -20, 90,
+// MZ2_WIDOW_BLASTER_100			165
+	-20, 76, 90,
+// MZ2_WIDOW_BLASTER_90				166
+	-8, 74, 90,
+// MZ2_WIDOW_BLASTER_80				167
+	0, 72, 90,
+// MZ2_WIDOW_BLASTER_70				168		d06
+	10, 71, 89,
+// MZ2_WIDOW_BLASTER_60				169		d07
+	23, 70, 87,
+// MZ2_WIDOW_BLASTER_50				170		d08
+	32, 64, 85,
+// MZ2_WIDOW_BLASTER_40				171
+	40, 58, 84,
+// MZ2_WIDOW_BLASTER_30				172		d10
+	48, 50, 83,
+// MZ2_WIDOW_BLASTER_20				173
+	54, 42, 82,
+// MZ2_WIDOW_BLASTER_10				174		d12
+	56, 34, 82,
+// MZ2_WIDOW_BLASTER_0				175
+	58, 26, 82,
+// MZ2_WIDOW_BLASTER_10L			176		d14
+	60, 16, 82,
+// MZ2_WIDOW_BLASTER_20L			177
+	59, 6, 81,
+// MZ2_WIDOW_BLASTER_30L			178		d16
+	58, -2, 80,
+// MZ2_WIDOW_BLASTER_40L			179
+	57, -10, 79,
+// MZ2_WIDOW_BLASTER_50L			180		d18
+	54, -18, 78,
+// MZ2_WIDOW_BLASTER_60L			181
+	42, -32, 80,
+// MZ2_WIDOW_BLASTER_70L			182		d20
+	36, -40, 78,
+// MZ2_WIDOW_RUN_1					183
+	68.4, 10.88, 82.08,
+// MZ2_WIDOW_RUN_2					184
+	68.51, 8.64, 85.14,
+// MZ2_WIDOW_RUN_3					185
+	68.66, 6.38, 88.78,
+// MZ2_WIDOW_RUN_4					186
+	68.73, 5.1, 84.47,
+// MZ2_WIDOW_RUN_5					187
+	68.82, 4.79, 80.52,
+// MZ2_WIDOW_RUN_6					188
+	68.77, 6.11, 85.37,
+// MZ2_WIDOW_RUN_7					189
+	68.67, 7.99, 90.24,
+// MZ2_WIDOW_RUN_8					190
+	68.55, 9.54, 87.36,
+// MZ2_CARRIER_ROCKET_1				191
+	0, 0, -5,
+// MZ2_CARRIER_ROCKET_2				192
+	0, 0, -5,
+// MZ2_CARRIER_ROCKET_3				193
+	0, 0, -5,
+// MZ2_CARRIER_ROCKET_4				194
+	0, 0, -5,
+// MZ2_WIDOW2_BEAMER_1				195
+//	72.13, -17.63, 93.77,
+	69.00, -17.63, 93.77,
+// MZ2_WIDOW2_BEAMER_2				196
+//	71.46, -17.08, 89.82,
+	69.00, -17.08, 89.82,
+// MZ2_WIDOW2_BEAMER_3				197
+//	71.47, -18.40, 90.70,
+	69.00, -18.40, 90.70,
+// MZ2_WIDOW2_BEAMER_4				198
+//	71.96, -18.34, 94.32,
+	69.00, -18.34, 94.32,
+// MZ2_WIDOW2_BEAMER_5				199
+//	72.25, -18.30, 97.98,
+	69.00, -18.30, 97.98,
+// MZ2_WIDOW2_BEAM_SWEEP_1			200
+	45.04, -59.02, 92.24,
+// MZ2_WIDOW2_BEAM_SWEEP_2			201
+	50.68, -54.70, 91.96,
+// MZ2_WIDOW2_BEAM_SWEEP_3			202
+	56.57, -47.72, 91.65,
+// MZ2_WIDOW2_BEAM_SWEEP_4			203
+	61.75, -38.75, 91.38,
+// MZ2_WIDOW2_BEAM_SWEEP_5			204
+	65.55, -28.76, 91.24,
+// MZ2_WIDOW2_BEAM_SWEEP_6			205
+	67.79, -18.90, 91.22,
+// MZ2_WIDOW2_BEAM_SWEEP_7			206
+	68.60, -9.52, 91.23,
+// MZ2_WIDOW2_BEAM_SWEEP_8			207
+	68.08, 0.18, 91.32,
+// MZ2_WIDOW2_BEAM_SWEEP_9			208
+	66.14, 9.79, 91.44,
+// MZ2_WIDOW2_BEAM_SWEEP_10			209
+	62.77, 18.91, 91.65,
+// MZ2_WIDOW2_BEAM_SWEEP_11			210
+	58.29, 27.11, 92.00,
+
+// end of table
+	0.0, 0.0, 0.0
+};
--- a/ctf/m_move.c
+++ b/ctf/m_move.c
@@ -1,7 +1,8 @@
-#include <u.h>
-#include <libc.h>
 // m_move.c -- monster movement
 
+#include <u.h>
+#include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 
--- a/ctf/p_client.c
+++ b/ctf/p_client.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 #include "m_player.h"
@@ -51,7 +52,7 @@
 // some maps don't have any coop spots at all, so we need to create them
 // where they should have been
 
-static void SP_CreateCoopSpots (edict_t *self)
+static void SP_CreateCoopSpots (edict_t *)
 {
 	edict_t	*spot;
 
@@ -152,7 +153,7 @@
 The deathmatch intermission point will be at one of these
 Use 'angles' instead of 'angle', so you can set pitch or roll as well as yaw.  'pitch yaw roll'
 */
-void SP_info_player_intermission(void)
+void SP_info_player_intermission(edict_t *)
 {
 }
 
@@ -160,7 +161,7 @@
 //=======================================================================
 
 
-void player_pain (edict_t *self, edict_t *other, float kick, int damage)
+void player_pain (edict_t *, edict_t *, float, int)
 {
 	// player pain is handled at the end of the frame in P_DamageFeedback
 }
@@ -180,7 +181,7 @@
 }
 
 
-void ClientObituary (edict_t *self, edict_t *inflictor, edict_t *attacker)
+void ClientObituary (edict_t *self, edict_t *, edict_t *attacker)
 {
 	int			mod;
 	char		*message;
@@ -438,11 +439,11 @@
 {
 	vec3_t		dir;
 
-	if (attacker && attacker != world && attacker != self)
+	if (attacker && attacker != WORLD && attacker != self)
 	{
 		VectorSubtract (attacker->s.origin, self->s.origin, dir);
 	}
-	else if (inflictor && inflictor != world && inflictor != self)
+	else if (inflictor && inflictor != WORLD && inflictor != self)
 	{
 		VectorSubtract (inflictor->s.origin, self->s.origin, dir);
 	}
@@ -470,7 +471,7 @@
 player_die
 ==================
 */
-void player_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
+void player_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t)
 {
 	int		n;
 
@@ -843,7 +844,7 @@
 edict_t *SelectCoopSpawnPoint (edict_t *ent)
 {
 	int		index;
-	edict_t	*spot = NULL;
+	edict_t	*spot = nil;
 	char	*target;
 
 	index = ent->client - game.clients;
@@ -850,10 +851,8 @@
 
 	// player 0 starts in normal player spawn point
 	if (!index)
-		return NULL;
+		return nil;
 
-	spot = NULL;
-
 	// assume there are four coop spots at each spawnpoint
 	while (1)
 	{
@@ -871,9 +870,6 @@
 				return spot;		// this is it
 		}
 	}
-
-
-	return spot;
 }
 
 
@@ -945,7 +941,7 @@
 	}
 }
 
-void body_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
+void body_die (edict_t *self, edict_t *, edict_t *, int damage, vec3_t)
 {
 	int	n;
 
@@ -1359,7 +1355,7 @@
 	char	*value;
 
 	// check to see if they are on the banned IP list
-	value = Info_ValueForKey (userinfo, "ip");
+	//value = Info_ValueForKey (userinfo, "ip");
 
 	// check for a password
 	value = Info_ValueForKey (userinfo, "password");
--- a/ctf/p_hud.c
+++ b/ctf/p_hud.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 
@@ -159,7 +160,6 @@
 	int		sorted[MAX_CLIENTS];
 	int		sortedscores[MAX_CLIENTS];
 	int		score, total;
-	int		picnum;
 	int		x, y;
 	gclient_t	*cl;
 	edict_t		*cl_ent;
@@ -209,7 +209,6 @@
 		cl = &game.clients[sorted[i]];
 		cl_ent = g_edicts + 1 + sorted[i];
 
-		picnum = gi.imageindex ("i_fixme");
 		x = (i>=6) ? 160 : 0;
 		y = 32 + 32 * (i%6);
 
@@ -379,7 +378,7 @@
 void G_SetStats (edict_t *ent)
 {
 	gitem_t		*item;
-	int			index, cells;
+	int			index, cells = 0;
 	int			power_armor_type;
 
 	//
--- a/ctf/p_menu.c
+++ b/ctf/p_menu.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 
@@ -76,7 +77,7 @@
 }
 
 // only use on pmenu's that have been called with PMenu_Open
-void PMenu_UpdateEntry(pmenu_t *entry, const char *text, int align, SelectFunc_t SelectFunc)
+void PMenu_UpdateEntry(pmenu_t *entry, char *text, int align, SelectFunc_t SelectFunc)
 {
 	if (entry->text)
 		free(entry->text);
--- a/ctf/p_menu.h
+++ /dev/null
@@ -1,29 +1,0 @@
-enum {
-	PMENU_ALIGN_LEFT,
-	PMENU_ALIGN_CENTER,
-	PMENU_ALIGN_RIGHT
-};
-
-typedef struct pmenuhnd_s {
-	struct pmenu_s *entries;
-	int cur;
-	int num;
-	void *arg;
-} pmenuhnd_t;
-
-typedef void (*SelectFunc_t)(edict_t *ent, pmenuhnd_t *hnd);
-
-typedef struct pmenu_s {
-	char *text;
-	int align;
-	SelectFunc_t SelectFunc;
-} pmenu_t;
-
-pmenuhnd_t *PMenu_Open(edict_t *ent, pmenu_t *entries, int cur, int num, void *arg);
-void PMenu_Close(edict_t *ent);
-void PMenu_UpdateEntry(pmenu_t *entry, const char *text, int align, SelectFunc_t SelectFunc);
-void PMenu_Do_Update(edict_t *ent);
-void PMenu_Update(edict_t *ent);
-void PMenu_Next(edict_t *ent);
-void PMenu_Prev(edict_t *ent);
-void PMenu_Select(edict_t *ent);
--- a/ctf/p_trail.c
+++ b/ctf/p_trail.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 
--- a/ctf/p_view.c
+++ b/ctf/p_view.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 #include "m_player.h"
@@ -22,7 +23,7 @@
 
 ===============
 */
-float SV_CalcRoll (vec3_t angles, vec3_t velocity)
+float SV_CalcRoll (vec3_t, vec3_t velocity)
 {
 	float	sign;
 	float	side;
@@ -551,7 +552,7 @@
 		VectorSet (dir, 0, 0, 1);
 
 		if (!deathmatch->value || !((int)dmflags->value & DF_NO_FALLING) )
-			T_Damage (ent, world, world, dir, ent->s.origin, vec3_origin, damage, 0, 0, MOD_FALLING);
+			T_Damage (ent, WORLD, WORLD, dir, ent->s.origin, vec3_origin, damage, 0, 0, MOD_FALLING);
 	}
 	else
 	{
@@ -683,7 +684,7 @@
 
 				current_player->pain_debounce_time = level.time;
 
-				T_Damage (current_player, world, world, vec3_origin, current_player->s.origin, vec3_origin, current_player->dmg, 0, DAMAGE_NO_ARMOR, MOD_WATER);
+				T_Damage (current_player, WORLD, WORLD, vec3_origin, current_player->s.origin, vec3_origin, current_player->dmg, 0, DAMAGE_NO_ARMOR, MOD_WATER);
 			}
 		}
 	}
@@ -712,9 +713,9 @@
 			}
 
 			if (envirosuit)	// take 1/3 damage with envirosuit
-				T_Damage (current_player, world, world, vec3_origin, current_player->s.origin, vec3_origin, 1*waterlevel, 0, 0, MOD_LAVA);
+				T_Damage (current_player, WORLD, WORLD, vec3_origin, current_player->s.origin, vec3_origin, 1*waterlevel, 0, 0, MOD_LAVA);
 			else
-				T_Damage (current_player, world, world, vec3_origin, current_player->s.origin, vec3_origin, 3*waterlevel, 0, 0, MOD_LAVA);
+				T_Damage (current_player, WORLD, WORLD, vec3_origin, current_player->s.origin, vec3_origin, 3*waterlevel, 0, 0, MOD_LAVA);
 		}
 
 		if (current_player->watertype & CONTENTS_SLIME)
@@ -721,7 +722,7 @@
 		{
 			if (!envirosuit)
 			{	// no damage from slime with envirosuit
-				T_Damage (current_player, world, world, vec3_origin, current_player->s.origin, vec3_origin, 1*waterlevel, 0, 0, MOD_SLIME);
+				T_Damage (current_player, WORLD, WORLD, vec3_origin, current_player->s.origin, vec3_origin, 1*waterlevel, 0, 0, MOD_SLIME);
 			}
 		}
 	}
--- a/ctf/p_weapon.c
+++ b/ctf/p_weapon.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 #include "m_player.h"
@@ -781,7 +782,7 @@
 	float	damage_radius;
 	int		radius_damage;
 
-	damage = 100 + (int)(random() * 20.0);
+	damage = 100 + (int)(qrandom() * 20.0);
 	radius_damage = 120;
 	damage_radius = 120;
 	if (is_quad)
@@ -1043,12 +1044,12 @@
 	ent->client->anim_priority = ANIM_ATTACK;
 	if (ent->client->ps.pmove.pm_flags & PMF_DUCKED)
 	{
-		ent->s.frame = FRAME_crattak1 - (int) (random()+0.25);
+		ent->s.frame = FRAME_crattak1 - (int) (qrandom()+0.25);
 		ent->client->anim_end = FRAME_crattak9;
 	}
 	else
 	{
-		ent->s.frame = FRAME_attack1 - (int) (random()+0.25);
+		ent->s.frame = FRAME_attack1 - (int) (qrandom()+0.25);
 		ent->client->anim_end = FRAME_attack8;
 	}
 }
--- a/ctf/q_shared.c
+++ b/ctf/q_shared.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <stdio.h>
 #include "../dat.h"
 #include "../fns.h"
 
@@ -9,7 +10,7 @@
 
 //============================================================================
 
-void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees )
+void RotatePointAroundVector( vec3_t dst, vec3_t dir, vec3_t point, float degrees )
 {
 	float	m[3][3];
 	float	im[3][3];
@@ -101,7 +102,7 @@
 }
 
 
-void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal )
+void ProjectPointOnPlane( vec3_t dst, vec3_t p, vec3_t normal )
 {
 	float d;
 	vec3_t n;
@@ -123,7 +124,7 @@
 /*
 ** assumes "src" is normalized
 */
-void PerpendicularVector( vec3_t dst, const vec3_t src )
+void PerpendicularVector( vec3_t dst, vec3_t src )
 {
 	int	pos;
 	int i;
@@ -236,12 +237,12 @@
 
 float	anglemod(float a)
 {
-#if 0
+/*
 	if (a >= 0)
 		a -= 360*(int)(a/360);
 	else
 		a += 360*( 1 + (int)(-a/360) );
-#endif
+*/
 	a = (360.0/65536) * ((int)(a*(65536/360.0)) & 65535);
 	return a;
 }
--- a/game/g_misc.c
+++ b/game/g_misc.c
@@ -1679,7 +1679,7 @@
 	else
 	{
 		t = localtime(time(nil));
-		Com_sprintf (self->message, CLOCK_MESSAGE_SIZE, "%2i:%2i:%2i", t->hour, t->min, t->sec);
+		Com_sprintf (self->message, CLOCK_MESSAGE_SIZE, "%2d:%2d:%2d", t->hour, t->min, t->sec);
 		if (self->message[3] == ' ')
 			self->message[3] = '0';
 		if (self->message[6] == ' ')
--- a/game/game.h
+++ b/game/game.h
@@ -548,7 +548,7 @@
 	MOD_TRIGGER_HURT = 31,
 	MOD_HIT = 32,
 	MOD_TARGET_BLASTER = 33,
-	MOD_FRIENDLY_FIRE = 1<<31
+	MOD_FRIENDLY_FIRE = 1<<27
 };
 extern int meansOfDeath;
 
--- a/mk.ctf
+++ b/mk.ctf
@@ -5,7 +5,7 @@
 	game/g_chase.$O\
 	game/g_cmds.$O\
 	game/g_combat.$O\
-	game/g_game.$O\
+	game/g_ctf.$O\
 	game/g_func.$O\
 	game/g_items.$O\
 	game/g_main.$O\
@@ -27,6 +27,7 @@
 	game/p_view.$O\
 	game/p_weapon.$O\
 	game/q_shared.$O\
+	game/m_flash.$O\
 
 GMHFILES=\
 	game/game.h\