shithub: qk3

Download patch

ref: bf5dc91f8d7bc2035effd18290c523050fa1b2cd
parent: f21a753a80c4034db22926835af88117e021eff0
author: qwx <>
date: Sat Jan 12 21:15:11 EST 2019

fix remaining linkage errors

--- a/code/botlib/be_aas_cluster.c
+++ b/code/botlib/be_aas_cluster.c
@@ -944,425 +944,6 @@
 	} //end for
 } //end of the function AAS_RemoveAllPortals
 
-#if 0
-//===========================================================================
-//
-// Parameter:				-
-// Returns:					-
-// Changes Globals:		-
-//===========================================================================
-void AAS_FloodCluster_r(int areanum, int clusternum)
-{
-	int i, otherareanum;
-	aas_face_t *face;
-	aas_area_t *area;
-
-	//set cluster mark
-	aasworld.areasettings[areanum].cluster = clusternum;
-	//if the area is a portal
-	//if (aasworld.areasettings[areanum].contents & AREACONTENTS_CLUSTERPORTAL) return;
-	//
-	area = &aasworld.areas[areanum];
-	//use area faces to flood into adjacent areas
-	for (i = 0; i < area->numfaces; i++)
-	{
-		face = &aasworld.faces[abs(aasworld.faceindex[area->firstface + i])];
-		//
-		if (face->frontarea != areanum) otherareanum = face->frontarea;
-		else otherareanum = face->backarea;
-		//if there's no area at the other side
-		if (!otherareanum) continue;
-		//if the area is a portal
-		if (aasworld.areasettings[otherareanum].contents & AREACONTENTS_CLUSTERPORTAL) continue;
-		//if the area is already marked
-		if (aasworld.areasettings[otherareanum].cluster) continue;
-		//
-		AAS_FloodCluster_r(otherareanum, clusternum);
-	} //end for
-	//use the reachabilities to flood into other areas
-	for (i = 0; i < aasworld.areasettings[areanum].numreachableareas; i++)
-	{
-		otherareanum = aasworld.reachability[
-					aasworld.areasettings[areanum].firstreachablearea + i].areanum;
-		if (!otherareanum)
-		{
-			continue;
-			AAS_Error("reachability %d has zero area\n", aasworld.areasettings[areanum].firstreachablearea + i);
-		} //end if
-		//if the area is a portal
-		if (aasworld.areasettings[otherareanum].contents & AREACONTENTS_CLUSTERPORTAL) continue;
-		//if the area is already marked
-		if (aasworld.areasettings[otherareanum].cluster) continue;
-		//
-		AAS_FloodCluster_r(otherareanum, clusternum);
-	} //end for
-} //end of the function AAS_FloodCluster_r
-//===========================================================================
-//
-// Parameter:				-
-// Returns:					-
-// Changes Globals:		-
-//===========================================================================
-void AAS_RemoveTeleporterPortals(void)
-{
-	int i, j, areanum;
-
-	for (i = 1; i < aasworld.numareas; i++)
-	{
-		for (j = 0; j < aasworld.areasettings[i].numreachableareas; j++)
-		{
-			areanum = aasworld.reachability[aasworld.areasettings[i].firstreachablearea + j].areanum;
-			if (aasworld.reachability[aasworld.areasettings[i].firstreachablearea + j].traveltype == TRAVEL_TELEPORT)
-			{
-				aasworld.areasettings[i].contents &= ~AREACONTENTS_CLUSTERPORTAL;
-				aasworld.areasettings[areanum].contents &= ~AREACONTENTS_CLUSTERPORTAL;
-				break;
-			} //end if
-		} //end for
-	} //end for
-} //end of the function AAS_RemoveTeleporterPortals
-//===========================================================================
-//
-// Parameter:				-
-// Returns:					-
-// Changes Globals:		-
-//===========================================================================
-void AAS_FloodClusterReachabilities(int clusternum)
-{
-	int i, j, areanum;
-
-	for (i = 1; i < aasworld.numareas; i++)
-	{
-		//if this area already has a cluster set
-		if (aasworld.areasettings[i].cluster) continue;
-		//if this area is a cluster portal
-		if (aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL) continue;
-		//loop over the reachable areas from this area
-		for (j = 0; j < aasworld.areasettings[i].numreachableareas; j++)
-		{
-			//the reachable area
-			areanum = aasworld.reachability[aasworld.areasettings[i].firstreachablearea + j].areanum;
-			//if this area is a cluster portal
-			if (aasworld.areasettings[areanum].contents & AREACONTENTS_CLUSTERPORTAL) continue;
-			//if this area has a cluster set
-			if (aasworld.areasettings[areanum].cluster == clusternum)
-			{
-				AAS_FloodCluster_r(i, clusternum);
-				i = 0;
-				break;
-			} //end if
-		} //end for
-	} //end for
-} //end of the function AAS_FloodClusterReachabilities
-
-//===========================================================================
-//
-// Parameter:				-
-// Returns:					-
-// Changes Globals:		-
-//===========================================================================
-void AAS_RemoveNotClusterClosingPortals(void)
-{
-	int i, j, k, facenum, otherareanum, nonclosingportals;
-	aas_area_t *area;
-	aas_face_t *face;
-
-	AAS_RemoveTeleporterPortals();
-	//
-	nonclosingportals = 0;
-	for (i = 1; i < aasworld.numareas; i++)
-	{
-		if (!(aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL)) continue;
-		//find a non-portal area adjacent to the portal area and flood
-		//the cluster from there
-		area = &aasworld.areas[i];
-		for (j = 0; j < area->numfaces; j++)
-		{
-			facenum = abs(aasworld.faceindex[area->firstface + j]);
-			face = &aasworld.faces[facenum];
-			//
-			if (face->frontarea != i) otherareanum = face->frontarea;
-			else otherareanum = face->backarea;
-			//
-			if (!otherareanum) continue;
-			//
-			if (aasworld.areasettings[otherareanum].contents & AREACONTENTS_CLUSTERPORTAL)
-			{
-				continue;
-			} //end if
-			//reset all cluster fields
-			AAS_RemoveClusterAreas();
-			//
-			AAS_FloodCluster_r(otherareanum, 1);
-			AAS_FloodClusterReachabilities(1);
-			//check if all adjacent non-portal areas have a cluster set
-			for (k = 0; k < area->numfaces; k++)
-			{
-				facenum = abs(aasworld.faceindex[area->firstface + k]);
-				face = &aasworld.faces[facenum];
-				//
-				if (face->frontarea != i) otherareanum = face->frontarea;
-				else otherareanum = face->backarea;
-				//
-				if (!otherareanum) continue;
-				//
-				if (aasworld.areasettings[otherareanum].contents & AREACONTENTS_CLUSTERPORTAL)
-				{
-					continue;
-				} //end if
-				//
-				if (!aasworld.areasettings[otherareanum].cluster) break;
-			} //end for
-			//if all adjacent non-portal areas have a cluster set then the portal
-			//didn't seal a cluster
-			if (k >= area->numfaces)
-			{
-				aasworld.areasettings[i].contents &= ~AREACONTENTS_CLUSTERPORTAL;
-				nonclosingportals++;
-				//recheck all the other portals again
-				i = 0;
-				break;
-			} //end if
-		} //end for
-	} //end for
-	botimport.Print(PRT_MESSAGE, "\r%6d non closing portals removed\n", nonclosingportals);
-} //end of the function AAS_RemoveNotClusterClosingPortals
-
-//===========================================================================
-//
-// Parameter:				-
-// Returns:					-
-// Changes Globals:		-
-//===========================================================================
-
-void AAS_RemoveNotClusterClosingPortals(void)
-{
-	int i, j, facenum, otherareanum, nonclosingportals, numseperatedclusters;
-	aas_area_t *area;
-	aas_face_t *face;
-
-	AAS_RemoveTeleporterPortals();
-	//
-	nonclosingportals = 0;
-	for (i = 1; i < aasworld.numareas; i++)
-	{
-		if (!(aasworld.areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL)) continue;
-		//
-		numseperatedclusters = 0;
-		//reset all cluster fields
-		AAS_RemoveClusterAreas();
-		//find a non-portal area adjacent to the portal area and flood
-		//the cluster from there
-		area = &aasworld.areas[i];
-		for (j = 0; j < area->numfaces; j++)
-		{
-			facenum = abs(aasworld.faceindex[area->firstface + j]);
-			face = &aasworld.faces[facenum];
-			//
-			if (face->frontarea != i) otherareanum = face->frontarea;
-			else otherareanum = face->backarea;
-			//if not solid at the other side of the face
-			if (!otherareanum) continue;
-			//don't flood into other portals
-			if (aasworld.areasettings[otherareanum].contents & AREACONTENTS_CLUSTERPORTAL) continue;
-			//if the area already has a cluster set
-			if (aasworld.areasettings[otherareanum].cluster) continue;
-			//another cluster is seperated by this portal
-			numseperatedclusters++;
-			//flood the cluster
-			AAS_FloodCluster_r(otherareanum, numseperatedclusters);
-			AAS_FloodClusterReachabilities(numseperatedclusters);
-		} //end for
-		//use the reachabilities to flood into other areas
-		for (j = 0; j < aasworld.areasettings[i].numreachableareas; j++)
-		{
-			otherareanum = aasworld.reachability[
-						aasworld.areasettings[i].firstreachablearea + j].areanum;
-			//this should never be qtrue but we check anyway
-			if (!otherareanum) continue;
-			//don't flood into other portals
-			if (aasworld.areasettings[otherareanum].contents & AREACONTENTS_CLUSTERPORTAL) continue;
-			//if the area already has a cluster set
-			if (aasworld.areasettings[otherareanum].cluster) continue;
-			//another cluster is seperated by this portal
-			numseperatedclusters++;
-			//flood the cluster
-			AAS_FloodCluster_r(otherareanum, numseperatedclusters);
-			AAS_FloodClusterReachabilities(numseperatedclusters);
-		} //end for
-		//a portal must seperate no more and no less than 2 clusters
-		if (numseperatedclusters != 2)
-		{
-			aasworld.areasettings[i].contents &= ~AREACONTENTS_CLUSTERPORTAL;
-			nonclosingportals++;
-			//recheck all the other portals again
-			i = 0;
-		} //end if
-	} //end for
-	botimport.Print(PRT_MESSAGE, "\r%6d non closing portals removed\n", nonclosingportals);
-} //end of the function AAS_RemoveNotClusterClosingPortals
-
-//===========================================================================
-//
-// Parameter:				-
-// Returns:					-
-// Changes Globals:		-
-//===========================================================================
-
-void AAS_AddTeleporterPortals(void)
-{
-	int j, area2num, facenum, otherareanum;
-	char *target, *targetname, *classname;
-	bsp_entity_t *entities, *ent, *dest;
-	vec3_t origin, destorigin, mins, maxs, end;
-	vec3_t bbmins, bbmaxs;
-	aas_area_t *area;
-	aas_face_t *face;
-	aas_trace_t trace;
-	aas_link_t *areas, *link;
-
-	entities = AAS_ParseBSPEntities();
-
-	for (ent = entities; ent; ent = ent->next)
-	{
-		classname = AAS_ValueForBSPEpairKey(ent, "classname");
-		if (classname && !strcmp(classname, "misc_teleporter"))
-		{
-			if (!AAS_VectorForBSPEpairKey(ent, "origin", origin))
-			{
-				botimport.Print(PRT_ERROR, "teleporter (%s) without origin\n", target);
-				continue;
-			} //end if
-			//
-			target = AAS_ValueForBSPEpairKey(ent, "target");
-			if (!target)
-			{
-				botimport.Print(PRT_ERROR, "teleporter (%s) without target\n", target);
-				continue;
-			} //end if
-			for (dest = entities; dest; dest = dest->next)
-			{
-				classname = AAS_ValueForBSPEpairKey(dest, "classname");
-				if (classname && !strcmp(classname, "misc_teleporter_dest"))
-				{
-					targetname = AAS_ValueForBSPEpairKey(dest, "targetname");
-					if (targetname && !strcmp(targetname, target))
-					{
-						break;
-					} //end if
-				} //end if
-			} //end for
-			if (!dest)
-			{
-				botimport.Print(PRT_ERROR, "teleporter without destination (%s)\n", target);
-				continue;
-			} //end if
-			if (!AAS_VectorForBSPEpairKey(dest, "origin", destorigin))
-			{
-				botimport.Print(PRT_ERROR, "teleporter destination (%s) without origin\n", target);
-				continue;
-			} //end if
-			destorigin[2] += 24; //just for q2e1m2, the dork has put the telepads in the ground
-			VectorCopy(destorigin, end);
-			end[2] -= 100;
-			trace = AAS_TraceClientBBox(destorigin, end, PRESENCE_CROUCH, -1);
-			if (trace.startsolid)
-			{
-				botimport.Print(PRT_ERROR, "teleporter destination (%s) in solid\n", target);
-				continue;
-			} //end if
-			VectorCopy(trace.endpos, destorigin);
-			area2num = AAS_PointAreaNum(destorigin);
-			//reset all cluster fields
-			for (j = 0; j < aasworld.numareas; j++)
-			{
-				aasworld.areasettings[j].cluster = 0;
-			} //end for
-			//
-			VectorSet(mins, -8, -8, 8);
-			VectorSet(maxs, 8, 8, 24);
-			//
-			AAS_PresenceTypeBoundingBox(PRESENCE_CROUCH, bbmins, bbmaxs);
-			//
-			VectorAdd(origin, mins, mins);
-			VectorAdd(origin, maxs, maxs);
-			//add bounding box size
-			VectorSubtract(mins, bbmaxs, mins);
-			VectorSubtract(maxs, bbmins, maxs);
-			//link an invalid (-1) entity
-			areas = AAS_AASLinkEntity(mins, maxs, -1);
-			//
-			for (link = areas; link; link = link->next_area)
-			{
-				if (!AAS_AreaGrounded(link->areanum)) continue;
-				//add the teleporter portal mark
-				aasworld.areasettings[link->areanum].contents |= AREACONTENTS_CLUSTERPORTAL |
-																			AREACONTENTS_TELEPORTAL;
-			} //end for
-			//
-			for (link = areas; link; link = link->next_area)
-			{
-				if (!AAS_AreaGrounded(link->areanum)) continue;
-				//find a non-portal area adjacent to the portal area and flood
-				//the cluster from there
-				area = &aasworld.areas[link->areanum];
-				for (j = 0; j < area->numfaces; j++)
-				{
-					facenum = abs(aasworld.faceindex[area->firstface + j]);
-					face = &aasworld.faces[facenum];
-					//
-					if (face->frontarea != link->areanum) otherareanum = face->frontarea;
-					else otherareanum = face->backarea;
-					//
-					if (!otherareanum) continue;
-					//
-					if (aasworld.areasettings[otherareanum].contents & AREACONTENTS_CLUSTERPORTAL)
-					{
-						continue;
-					} //end if
-					//
-					AAS_FloodCluster_r(otherareanum, 1);
-				} //end for
-			} //end for
-			//if the teleport destination IS in the same cluster
-			if (aasworld.areasettings[area2num].cluster)
-			{
-				for (link = areas; link; link = link->next_area)
-				{
-					if (!AAS_AreaGrounded(link->areanum)) continue;
-					//add the teleporter portal mark
-					aasworld.areasettings[link->areanum].contents &= ~(AREACONTENTS_CLUSTERPORTAL |
-																				AREACONTENTS_TELEPORTAL);
-				} //end for
-			} //end if
-		} //end if
-	} //end for
-	AAS_FreeBSPEntities(entities);
-} //end of the function AAS_AddTeleporterPortals
-
-//===========================================================================
-//
-// Parameter:				-
-// Returns:					-
-// Changes Globals:		-
-//===========================================================================
-void AAS_AddTeleporterPortals(void)
-{
-	int i, j, areanum;
-
-	for (i = 1; i < aasworld.numareas; i++)
-	{
-		for (j = 0; j < aasworld.areasettings[i].numreachableareas; j++)
-		{
-			if (aasworld.reachability[aasworld.areasettings[i].firstreachablearea + j].traveltype != TRAVEL_TELEPORT) continue;
-			areanum = aasworld.reachability[aasworld.areasettings[i].firstreachablearea + j].areanum;
-			aasworld.areasettings[areanum].contents |= AREACONTENTS_CLUSTERPORTAL;
-		} //end for
-	} //end for
-} //end of the function AAS_AddTeleporterPortals
-
-#endif
-
 //===========================================================================
 //
 // Parameter:				-
--- a/code/botlib/be_aas_def.h
+++ b/code/botlib/be_aas_def.h
@@ -32,14 +32,11 @@
 //debugging on
 #define AAS_DEBUG
 
-#define MAX_CLIENTS			64
-#define	MAX_MODELS			256		// these are sent over the net as 8 bits
-#define	MAX_SOUNDS			256		// so they cannot be blindly increased
-#define	MAX_CONFIGSTRINGS	1024
-
+#ifndef CS_MODELS
 #define	CS_SCORES			32
 #define	CS_MODELS			(CS_SCORES+MAX_CLIENTS)
 #define	CS_SOUNDS			(CS_MODELS+MAX_MODELS)
+#endif
 
 #define DF_AASENTNUMBER(x)		(x - aasworld.entities)
 #define DF_NUMBERAASENT(x)		(&aasworld.entities[x])
@@ -290,17 +287,17 @@
 
 #ifndef BSPCINCLUDE
 
-#include "be_aas_main.h"
-#include "be_aas_entity.h"
-#include "be_aas_sample.h"
-#include "be_aas_cluster.h"
-#include "be_aas_reach.h"
-#include "be_aas_route.h"
-#include "be_aas_routealt.h"
-#include "be_aas_debug.h"
-#include "be_aas_file.h"
-#include "be_aas_optimize.h"
-#include "be_aas_bsp.h"
-#include "be_aas_move.h"
+#include "../botlib/be_aas_main.h"
+#include "../botlib/be_aas_entity.h"
+#include "../botlib/be_aas_sample.h"
+#include "../botlib/be_aas_cluster.h"
+#include "../botlib/be_aas_reach.h"
+#include "../botlib/be_aas_route.h"
+#include "../botlib/be_aas_routealt.h"
+#include "../botlib/be_aas_debug.h"
+#include "../botlib/be_aas_file.h"
+#include "../botlib/be_aas_optimize.h"
+#include "../botlib/be_aas_bsp.h"
+#include "../botlib/be_aas_move.h"
 
 #endif //BSPCINCLUDE
--- a/code/botlib/be_aas_funcs.h
+++ b/code/botlib/be_aas_funcs.h
@@ -31,17 +31,16 @@
 
 #ifndef BSPCINCLUDE
 
-#include "be_aas_main.h"
-#include "be_aas_entity.h"
-#include "be_aas_sample.h"
-#include "be_aas_cluster.h"
-#include "be_aas_reach.h"
-#include "be_aas_route.h"
-#include "be_aas_routealt.h"
-#include "be_aas_debug.h"
-#include "be_aas_file.h"
-#include "be_aas_optimize.h"
-#include "be_aas_bsp.h"
-#include "be_aas_move.h"
+#include "../botlib/be_aas_main.h"
+#include "../botlib/be_aas_entity.h"
+#include "../botlib/be_aas_sample.h"
+#include "../botlib/be_aas_cluster.h"
+#include "../botlib/be_aas_reach.h"
+#include "../botlib/be_aas_route.h"
+#include "../botlib/be_aas_routealt.h"
+#include "../botlib/be_aas_debug.h"
+#include "../botlib/be_aas_file.h"
+#include "../botlib/be_aas_optimize.h"
+#include "../botlib/be_aas_move.h"
 
 #endif //BSPCINCLUDE
--- a/code/botlib/be_aas_reach.c
+++ b/code/botlib/be_aas_reach.c
@@ -415,14 +415,6 @@
 			//it can very well happen that the AAS_PointAreaNum function tells that
 			//a point is in an area and that starting a AAS_TraceClientBBox from that
 			//point will return trace.startsolid qtrue
-#if 0
-			if (AAS_PointAreaNum(start))
-			{
-				Log_Write("point %f %f %f in area %d but trace startsolid", start[0], start[1], start[2], areanum);
-				AAS_DrawPermanentCross(start, 4, LINECOLOR_RED);
-			} //end if
-			botimport.Print(PRT_MESSAGE, "AAS_BestReachableArea: start solid\n");
-#endif
 			VectorCopy(start, goalorigin);
 			return areanum;
 		} //end else
@@ -3386,15 +3378,6 @@
 		end_plane.dist = end_edgeverts[0][2];
 		VectorSet(end_plane.normal, 0, 0, 1);
 		//
-#ifndef BSPC
-#if 0
-		for (i = 0; i < 4; i++)
-		{
-			AAS_PermanentLine(start_edgeverts[i], start_edgeverts[(i+1)%4], 1);
-			AAS_PermanentLine(end_edgeverts[i], end_edgeverts[(i+1)%4], 1);
-		} //end for
-#endif
-#endif
 		VectorCopy(move_start, move_start_top);
 		move_start_top[2] += maxs[2] - mid[2] + 24; //+ bbox maxs z
 		VectorCopy(move_end, move_end_top);
--- a/code/botlib/be_aas_route.c
+++ b/code/botlib/be_aas_route.c
@@ -106,7 +106,7 @@
 // Returns:				-
 // Changes Globals:		-
 //===========================================================================
-__inline int AAS_ClusterAreaNum(int cluster, int areanum)
+int AAS_ClusterAreaNum(int cluster, int areanum)
 {
 	int side, areacluster;
 
@@ -166,7 +166,7 @@
 // Returns:				-
 // Changes Globals:		-
 //===========================================================================
-__inline int AAS_TravelFlagForType_inline(int traveltype)
+int AAS_TravelFlagForType_inline(int traveltype)
 {
 	int tfl;
 
@@ -339,7 +339,7 @@
 // Returns:				-
 // Changes Globals:		-
 //===========================================================================
-__inline float AAS_RoutingTime(void)
+float AAS_RoutingTime(void)
 {
 	return AAS_Time();
 } //end of the function AAS_RoutingTime
@@ -379,7 +379,7 @@
 // Returns:				-
 // Changes Globals:		-
 //===========================================================================
-__inline int AAS_AreaContentsTravelFlags_inline(int areanum)
+int AAS_AreaContentsTravelFlags_inline(int areanum)
 {
 	return aasworld.areacontentstravelflags[areanum];
 } //end of the function AAS_AreaContentsTravelFlags
@@ -2007,7 +2007,7 @@
 	//if the area has no reachabilities
 	if (!AAS_AreaReachability(areanum)) return qfalse;
 	//
-	n = aasworld.numareas * random();
+	n = aasworld.numareas * qrandom();
 	for (i = 0; i < aasworld.numareas; i++)
 	{
 		if (n <= 0) n = 1;
--- a/code/botlib/be_ai_chat.c
+++ b/code/botlib/be_ai_chat.c
@@ -788,7 +788,7 @@
 	{
 		if (!(syn->context & context)) continue;
 		//choose a weighted random replacement synonym
-		weight = random() * syn->totalweight;
+		weight = qrandom() * syn->totalweight;
 		if (!weight) continue;
 		curweight = 0;
 		for (replacement = syn->firstsynonym; replacement; replacement = replacement->next)
@@ -1055,7 +1055,7 @@
 	{
 		if (!strcmp(random->string, name))
 		{
-			i = random() * random->numstrings;
+			i = qrandom() * random->numstrings;
 			for (rs = random->firstrandomstring; rs; rs = rs->next)
 			{
 				if (--i < 0) break;
@@ -2440,7 +2440,7 @@
 			} //end if
 			else //choose a chat message randomly
 			{
-				n = random() * numchatmessages;
+				n = qrandom() * numchatmessages;
 				for (m = t->firstchatmessage; m; m = m->next)
 				{
 					if (m->time > AAS_Time()) continue;
@@ -2676,7 +2676,7 @@
 					if (m->time > AAS_Time()) continue;
 					numchatmessages++;
 				} //end if
-				num = random() * numchatmessages;
+				num = qrandom() * numchatmessages;
 				for (m = rchat->firstchatmessage; m; m = m->next)
 				{
 					if (--num < 0) break;
--- a/code/botlib/be_ai_gen.c
+++ b/code/botlib/be_ai_gen.c
@@ -64,7 +64,7 @@
 	{
 		//select a bot where the ones with the higest rankings have
 		//the highest chance of being selected
-		select = random() * sum;
+		select = qrandom() * sum;
 		for (i = 0; i < numranks; i++)
 		{
 			if (rankings[i] < 0) continue;
@@ -73,7 +73,7 @@
 		} //end for
 	} //end if
 	//select a bot randomly
-	index = random() * numranks;
+	index = qrandom() * numranks;
 	for (i = 0; i < numranks; i++)
 	{
 		if (rankings[index] >= 0) return index;
--- a/code/botlib/be_ai_goal.c
+++ b/code/botlib/be_ai_goal.c
@@ -45,6 +45,7 @@
 #include "be_ai_weight.h"
 #include "../game/be_ai_goal.h"
 #include "../game/be_ai_move.h"
+#include "be_aas_bsp.h"
 
 //#define DEBUG_AI_GOAL
 #ifdef RANDOMIZE
--- a/code/botlib/be_ai_move.c
+++ b/code/botlib/be_ai_move.c
@@ -41,6 +41,7 @@
 #include "../game/be_aas.h"
 #include "be_aas_funcs.h"
 #include "be_interface.h"
+#include "be_aas_bsp.h"
 
 #include "../game/be_ea.h"
 #include "../game/be_ai_goal.h"
--- a/code/botlib/be_ai_weight.c
+++ b/code/botlib/be_ai_weight.c
@@ -435,7 +435,6 @@
 	//
 	return config;
 } //end of the function ReadWeightConfig
-#if 0
 //===========================================================================
 //
 // Parameter:				-
@@ -442,118 +441,6 @@
 // Returns:					-
 // Changes Globals:		-
 //===========================================================================
-qboolean WriteFuzzyWeight(FILE *fp, fuzzyseperator_t *fs)
-{
-	if (fs->type == WT_BALANCE)
-	{
-		if (fprintf(fp, " return balance(") < 0) return qfalse;
-		if (!WriteFloat(fp, fs->weight)) return qfalse;
-		if (fprintf(fp, ",") < 0) return qfalse;
-		if (!WriteFloat(fp, fs->minweight)) return qfalse;
-		if (fprintf(fp, ",") < 0) return qfalse;
-		if (!WriteFloat(fp, fs->maxweight)) return qfalse;
-		if (fprintf(fp, ");\n") < 0) return qfalse;
-	} //end if
-	else
-	{
-		if (fprintf(fp, " return ") < 0) return qfalse;
-		if (!WriteFloat(fp, fs->weight)) return qfalse;
-		if (fprintf(fp, ";\n") < 0) return qfalse;
-	} //end else
-	return qtrue;
-} //end of the function WriteFuzzyWeight
-//===========================================================================
-//
-// Parameter:				-
-// Returns:					-
-// Changes Globals:		-
-//===========================================================================
-qboolean WriteFuzzySeperators_r(FILE *fp, fuzzyseperator_t *fs, int indent)
-{
-	if (!WriteIndent(fp, indent)) return qfalse;
-	if (fprintf(fp, "switch(%d)\n", fs->index) < 0) return qfalse;
-	if (!WriteIndent(fp, indent)) return qfalse;
-	if (fprintf(fp, "{\n") < 0) return qfalse;
-	indent++;
-	do
-	{
-		if (!WriteIndent(fp, indent)) return qfalse;
-		if (fs->next)
-		{
-			if (fprintf(fp, "case %d:", fs->value) < 0) return qfalse;
-		} //end if
-		else
-		{
-			if (fprintf(fp, "default:") < 0) return qfalse;
-		} //end else
-		if (fs->child)
-		{
-			if (fprintf(fp, "\n") < 0) return qfalse;
-			if (!WriteIndent(fp, indent)) return qfalse;
-			if (fprintf(fp, "{\n") < 0) return qfalse;
-			if (!WriteFuzzySeperators_r(fp, fs->child, indent + 1)) return qfalse;
-			if (!WriteIndent(fp, indent)) return qfalse;
-			if (fs->next)
-			{
-				if (fprintf(fp, "} //end case\n") < 0) return qfalse;
-			} //end if
-			else
-			{
-				if (fprintf(fp, "} //end default\n") < 0) return qfalse;
-			} //end else
-		} //end if
-		else
-		{
-			if (!WriteFuzzyWeight(fp, fs)) return qfalse;
-		} //end else
-		fs = fs->next;
-	} while(fs);
-	indent--;
-	if (!WriteIndent(fp, indent)) return qfalse;
-	if (fprintf(fp, "} //end switch\n") < 0) return qfalse;
-	return qtrue;
-} //end of the function WriteItemFuzzyWeights_r
-//===========================================================================
-//
-// Parameter:				-
-// Returns:					-
-// Changes Globals:		-
-//===========================================================================
-qboolean WriteWeightConfig(char *filename, weightconfig_t *config)
-{
-	int i;
-	FILE *fp;
-	weight_t *ifw;
-
-	fp = fopen(filename, "wb");
-	if (!fp) return qfalse;
-
-	for (i = 0; i < config->numweights; i++)
-	{
-		ifw = &config->weights[i];
-		if (fprintf(fp, "\nweight \"%s\"\n", ifw->name) < 0) return qfalse;
-		if (fprintf(fp, "{\n") < 0) return qfalse;
-		if (ifw->firstseperator->index > 0)
-		{
-			if (!WriteFuzzySeperators_r(fp, ifw->firstseperator, 1)) return qfalse;
-		} //end if
-		else
-		{
-			if (!WriteIndent(fp, 1)) return qfalse;
-			if (!WriteFuzzyWeight(fp, ifw->firstseperator)) return qfalse;
-		} //end else
-		if (fprintf(fp, "} //end weight\n") < 0) return qfalse;
-	} //end for
-	fclose(fp);
-	return qtrue;
-} //end of the function WriteWeightConfig
-#endif
-//===========================================================================
-//
-// Parameter:				-
-// Returns:					-
-// Changes Globals:		-
-//===========================================================================
 int FindFuzzyWeight(weightconfig_t *wc, char *name)
 {
 	int i;
@@ -614,7 +501,7 @@
 	if (inventory[fs->index] < fs->value)
 	{
 		if (fs->child) return FuzzyWeightUndecided_r(inventory, fs->child);
-		else return fs->minweight + random() * (fs->maxweight - fs->minweight);
+		else return fs->minweight + qrandom() * (fs->maxweight - fs->minweight);
 	} //end if
 	else if (fs->next)
 	{
@@ -622,10 +509,10 @@
 		{
 			//first weight
 			if (fs->child) w1 = FuzzyWeightUndecided_r(inventory, fs->child);
-			else w1 = fs->minweight + random() * (fs->maxweight - fs->minweight);
+			else w1 = fs->minweight + qrandom() * (fs->maxweight - fs->minweight);
 			//second weight
 			if (fs->next->child) w2 = FuzzyWeight_r(inventory, fs->next->child);
-			else w2 = fs->next->minweight + random() * (fs->next->maxweight - fs->next->minweight);
+			else w2 = fs->next->minweight + qrandom() * (fs->next->maxweight - fs->next->minweight);
 			//the scale factor
 			scale = (inventory[fs->index] - fs->value) / (fs->next->value - fs->value);
 			//scale between the two weights
@@ -686,12 +573,12 @@
 		if (inventory[s->index] < s->value)
 		{
 			if (s->child) s = s->child;
-			else return s->minweight + random() * (s->maxweight - s->minweight);
+			else return s->minweight + qrandom() * (s->maxweight - s->minweight);
 		} //end if
 		else
 		{
 			if (s->next) s = s->next;
-			else return s->minweight + random() * (s->maxweight - s->minweight);
+			else return s->minweight + qrandom() * (s->maxweight - s->minweight);
 		} //end else
 	} //end if
 	return 0;
@@ -712,7 +599,7 @@
 	else if (fs->type == WT_BALANCE)
 	{
 		//every once in a while an evolution leap occurs, mutation
-		if (random() < 0.01) fs->weight += crandom() * (fs->maxweight - fs->minweight);
+		if (qrandom() < 0.01) fs->weight += crandom() * (fs->maxweight - fs->minweight);
 		else fs->weight += crandom() * (fs->maxweight - fs->minweight) * 0.5;
 		//modify bounds if necesary because of mutation
 		if (fs->weight < fs->minweight) fs->minweight = fs->weight;
--- a/code/botlib/be_interface.c
+++ b/code/botlib/be_interface.c
@@ -30,6 +30,7 @@
  *****************************************************************************/
 
 #include "../game/q_shared.h"
+#include "../qcommon/qcommon.h"
 #include "l_memory.h"
 #include "l_log.h"
 #include "l_libvar.h"
@@ -76,7 +77,7 @@
 //===========================================================================
 int Sys_MilliSeconds(void)
 {
-	return clock() * 1000 / CLOCKS_PER_SEC;
+	return Sys_Milliseconds();
 } //end of the function Sys_MilliSeconds
 //===========================================================================
 //
--- a/code/botlib/l_crc.c
+++ b/code/botlib/l_crc.c
@@ -29,10 +29,6 @@
  *
  *****************************************************************************/
 
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
 #include "../game/q_shared.h"
 #include "../game/botlib.h"
 #include "be_interface.h"			//for botimport.Print
--- a/code/botlib/l_log.c
+++ b/code/botlib/l_log.c
@@ -29,10 +29,6 @@
  *
  *****************************************************************************/
 
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
 #include "../game/q_shared.h"
 #include "../game/botlib.h"
 #include "be_interface.h"			//for botimport.Print
--- a/code/botlib/l_precomp.c
+++ b/code/botlib/l_precomp.c
@@ -88,8 +88,10 @@
 
 #endif //BSPC
 
-#if defined(QUAKE) && !defined(BSPC)
+#ifdef QUAKE
+#ifndef BSPC
 #include "l_utils.h"
+#endif
 #endif //QUAKE
 
 //#define DEBUG_EVAL
@@ -96,7 +98,7 @@
 
 #define MAX_DEFINEPARMS			128
 
-#define DEFINEHASHING			1
+#define DEFINEHASHING
 
 //directive name with parse function
 typedef struct directive_s
@@ -517,7 +519,7 @@
 //	token_t *tokens;					//macro tokens (possibly containing parm tokens)
 //	struct define_s *next;			//next defined macro in a list
 } //end of the function PC_PrintDefine*/
-#if DEFINEHASHING
+#ifdef DEFINEHASHING
 //============================================================================
 //
 // Parameter:				-
@@ -687,7 +689,7 @@
 		define->flags |= DEFINE_FIXED;
 		define->builtin = builtin[i].builtin;
 		//add the define to the source
-#if DEFINEHASHING
+#ifdef DEFINEHASHING
 		PC_AddDefineToHash(define, source->definehash);
 #else
 		define->next = source->defines;
@@ -735,8 +737,7 @@
 		} //end case
 		case BUILTIN_DATE:
 		{
-			t = time(NULL);
-			curtime = ctime(&t);
+			curtime = ctime(time(nil));
 			strcpy(token->string, "\"");
 			strncat(token->string, curtime+4, 7);
 			strncat(token->string+7, curtime+20, 4);
@@ -750,8 +751,7 @@
 		} //end case
 		case BUILTIN_TIME:
 		{
-			t = time(NULL);
-			curtime = ctime(&t);
+			curtime = ctime(time(nil));
 			strcpy(token->string, "\"");
 			strncat(token->string, curtime+11, 8);
 			strcat(token->string, "\"");
@@ -1123,7 +1123,7 @@
 		SourceError(source, "expected name, found %s", token.string);
 		return qfalse;
 	} //end if
-#if DEFINEHASHING
+#ifdef DEFINEHASHING
 
 	hash = PC_NameHash(token.string);
 	for (lastdefine = NULL, define = source->definehash[hash]; define; define = define->hashnext)
@@ -1191,7 +1191,7 @@
 		return qfalse;
 	} //end if
 	//check if the define already exists
-#if DEFINEHASHING
+#ifdef DEFINEHASHING
 	define = PC_FindHashedDefine(source->definehash, token.string);
 #else
 	define = PC_FindDefine(source->defines, token.string);
@@ -1208,7 +1208,7 @@
 		PC_UnreadSourceToken(source, &token);
 		if (!PC_Directive_undef(source)) return qfalse;
 		//if the define was not removed (define->flags & DEFINE_FIXED)
-#if DEFINEHASHING
+#ifdef DEFINEHASHING
 		define = PC_FindHashedDefine(source->definehash, token.string);
 #else
 		define = PC_FindDefine(source->defines, token.string);
@@ -1220,7 +1220,7 @@
 	define->name = (char *) define + sizeof(define_t);
 	strcpy(define->name, token.string);
 	//add the define to the source
-#if DEFINEHASHING
+#ifdef DEFINEHASHING
 	PC_AddDefineToHash(define, source->definehash);
 #else //DEFINEHASHING
 	define->next = source->defines;
@@ -1330,7 +1330,7 @@
 	Com_Memset(&src, 0, sizeof(source_t));
 	strncpy(src.filename, "*extern", MAX_PATH);
 	src.scriptstack = script;
-#if DEFINEHASHING
+#ifdef DEFINEHASHING
 	src.definehash = GetClearedMemory(DEFINEHASHSIZE * sizeof(define_t *));
 #endif //DEFINEHASHING
 	//create a define from the source
@@ -1355,7 +1355,7 @@
 	def = src.defines;
 #endif //DEFINEHASHING
 	//
-#if DEFINEHASHING
+#ifdef DEFINEHASHING
 	FreeMemory(src.definehash);
 #endif //DEFINEHASHING
 	//
@@ -1379,7 +1379,7 @@
 
 	define = PC_DefineFromString(string);
 	if (!define) return qfalse;
-#if DEFINEHASHING
+#ifdef DEFINEHASHING
 	PC_AddDefineToHash(define, source->definehash);
 #else //DEFINEHASHING
 	define->next = source->defines;
@@ -1496,7 +1496,7 @@
 	for (define = globaldefines; define; define = define->next)
 	{
 		newdefine = PC_CopyDefine(source, define);
-#if DEFINEHASHING
+#ifdef DEFINEHASHING
 		PC_AddDefineToHash(newdefine, source->definehash);
 #else //DEFINEHASHING
 		newdefine->next = source->defines;
@@ -1527,7 +1527,7 @@
 		SourceError(source, "expected name after #ifdef, found %s", token.string);
 		return qfalse;
 	} //end if
-#if DEFINEHASHING
+#ifdef DEFINEHASHING
 	d = PC_FindHashedDefine(source->definehash, token.string);
 #else
 	d = PC_FindDefine(source->defines, token.string);
@@ -1739,7 +1739,7 @@
 				} //end if
 				//v = (value_t *) GetClearedMemory(sizeof(value_t));
 				AllocValue(v);
-#if DEFINEHASHING
+#ifdef DEFINEHASHING
 				if (PC_FindHashedDefine(source->definehash, t->string))
 #else			
 				if (PC_FindDefine(source->defines, t->string))
@@ -2180,7 +2180,7 @@
 			else
 			{
 				//then it must be a define
-#if DEFINEHASHING
+#ifdef DEFINEHASHING
 				define = PC_FindHashedDefine(source->definehash, token.string);
 #else
 				define = PC_FindDefine(source->defines, token.string);
@@ -2285,7 +2285,7 @@
 			else
 			{
 				//then it must be a define
-#if DEFINEHASHING
+#ifdef DEFINEHASHING
 				define = PC_FindHashedDefine(source->definehash, token.string);
 #else
 				define = PC_FindDefine(source->defines, token.string);
@@ -2759,7 +2759,7 @@
 		if (token->type == TT_NAME)
 		{
 			//check if the name is a define macro
-#if DEFINEHASHING
+#ifdef DEFINEHASHING
 			define = PC_FindHashedDefine(source->definehash, token->string);
 #else
 			define = PC_FindDefine(source->defines, token->string);
@@ -3001,7 +3001,7 @@
 	source->indentstack = NULL;
 	source->skip = 0;
 
-#if DEFINEHASHING
+#ifdef DEFINEHASHING
 	source->definehash = GetClearedMemory(DEFINEHASHSIZE * sizeof(define_t *));
 #endif //DEFINEHASHING
 	PC_AddGlobalDefinesToSource(source);
@@ -3034,7 +3034,7 @@
 	source->indentstack = NULL;
 	source->skip = 0;
 
-#if DEFINEHASHING
+#ifdef DEFINEHASHING
 	source->definehash = GetClearedMemory(DEFINEHASHSIZE * sizeof(define_t *));
 #endif //DEFINEHASHING
 	PC_AddGlobalDefinesToSource(source);
@@ -3069,7 +3069,7 @@
 		source->tokens = source->tokens->next;
 		PC_FreeToken(token);
 	} //end for
-#if DEFINEHASHING
+#ifdef DEFINEHASHING
 	for (i = 0; i < DEFINEHASHSIZE; i++)
 	{
 		while(source->definehash[i])
@@ -3095,7 +3095,7 @@
 		source->indentstack = source->indentstack->next;
 		FreeMemory(indent);
 	} //end for
-#if DEFINEHASHING
+#ifdef DEFINEHASHING
 	//
 	if (source->definehash) FreeMemory(source->definehash);
 #endif //DEFINEHASHING
--- a/code/botlib/l_precomp.h
+++ b/code/botlib/l_precomp.h
@@ -34,22 +34,16 @@
 #endif
 
 #ifndef PATH_SEPERATORSTR
-	#if defined(WIN32)|defined(_WIN32)|defined(__NT__)|defined(__WINDOWS__)|defined(__WINDOWS_386__)
-		#define PATHSEPERATOR_STR		"\\"
-	#else
-		#define PATHSEPERATOR_STR		"/"
-	#endif
+	#define PATHSEPERATOR_STR		"/"
 #endif
 #ifndef PATH_SEPERATORCHAR
-	#if defined(WIN32)|defined(_WIN32)|defined(__NT__)|defined(__WINDOWS__)|defined(__WINDOWS_386__)
-		#define PATHSEPERATOR_CHAR		'\\'
-	#else
-		#define PATHSEPERATOR_CHAR		'/'
-	#endif
+	#define PATHSEPERATOR_CHAR		'/'
 #endif
 
-#if defined(BSPC) && !defined(QDECL)
+#ifdef BSPC
+#ifndef QDECL
 #define QDECL
+#endif
 #endif
 
 
--- a/code/botlib/l_script.h
+++ b/code/botlib/l_script.h
@@ -39,9 +39,11 @@
 //maximum token length
 #define MAX_TOKEN					1024
 
-#if defined(BSPC) && !defined(QDECL)
+#ifdef BSPC
+#ifndef QDECL
 #define QDECL
 #endif
+#endif
 
 
 //script flags
@@ -52,13 +54,6 @@
 #define SCFL_PRIMITIVE				0x0010
 #define SCFL_NOBINARYNUMBERS		0x0020
 #define SCFL_NONUMBERVALUES		0x0040
-
-//token types
-#define TT_STRING						1			// string
-#define TT_LITERAL					2			// literal
-#define TT_NUMBER						3			// number
-#define TT_NAME						4			// name
-#define TT_PUNCTUATION				5			// punctuation
 
 //string sub type
 //---------------
--- a/code/botlib/l_utils.h
+++ b/code/botlib/l_utils.h
@@ -30,6 +30,5 @@
  *****************************************************************************/
 
 #define Vector2Angles(v,a)		vectoangles(v,a)
-#define MAX_PATH				MAX_QPATH
 #define Maximum(x,y)			(x > y ? x : y)
 #define Minimum(x,y)			(x < y ? x : y)
--- a/code/game/q_shared.h
+++ b/code/game/q_shared.h
@@ -553,8 +553,8 @@
 float	Q_random( int *seed );
 float	Q_crandom( int *seed );
 
-#define random()	((rand () & 0x7fff) / ((float)0x7fff))
-#define crandom()	(2.0 * (random() - 0.5))
+#define qrandom()	((rand () & 0x7fff) / ((float)0x7fff))
+#define crandom()	(2.0 * (qrandom() - 0.5))
 
 void vectoangles( const vec3_t value1, vec3_t angles);
 void AnglesToAxis( const vec3_t angles, vec3_t axis[3] );
--- a/code/mkfile
+++ b/code/mkfile
@@ -3,6 +3,34 @@
 TARG=q3ded
 
 OFILES=\
+	botlib/be_aas_bspq3.$O\
+	botlib/be_aas_cluster.$O\
+	botlib/be_aas_debug.$O\
+	botlib/be_aas_entity.$O\
+	botlib/be_aas_file.$O\
+	botlib/be_aas_main.$O\
+	botlib/be_aas_move.$O\
+	botlib/be_aas_optimize.$O\
+	botlib/be_aas_reach.$O\
+	botlib/be_aas_route.$O\
+	botlib/be_aas_routealt.$O\
+	botlib/be_aas_sample.$O\
+	botlib/be_ai_char.$O\
+	botlib/be_ai_chat.$O\
+	botlib/be_ai_gen.$O\
+	botlib/be_ai_goal.$O\
+	botlib/be_ai_move.$O\
+	botlib/be_ai_weap.$O\
+	botlib/be_ai_weight.$O\
+	botlib/be_ea.$O\
+	botlib/be_interface.$O\
+	botlib/l_crc.$O\
+	botlib/l_libvar.$O\
+	botlib/l_log.$O\
+	botlib/l_memory.$O\
+	botlib/l_precomp.$O\
+	botlib/l_script.$O\
+	botlib/l_struct.$O\
 	null/null_client.$O\
 	null/null_input.$O\
 	null/null_snddma.$O\
@@ -31,6 +59,7 @@
 	qcommon/unzip.$O\
 	qcommon/vm.$O\
 	qcommon/vm_interpreted.$O\
+	null/null_vm.$O\
 	game/q_math.$O\
 	game/q_shared.$O\
 	unix/qk3ded.$O\
@@ -39,6 +68,31 @@
 	unix/unix_shared.$O\
 
 HFILES=\
+	botlib/aasfile.h\
+	botlib/be_aas_bsp.h\
+	botlib/be_aas_cluster.h\
+	botlib/be_aas_debug.h\
+	botlib/be_aas_def.h\
+	botlib/be_aas_entity.h\
+	botlib/be_aas_file.h\
+	botlib/be_aas_funcs.h\
+	botlib/be_aas_main.h\
+	botlib/be_aas_move.h\
+	botlib/be_aas_optimize.h\
+	botlib/be_aas_reach.h\
+	botlib/be_aas_route.h\
+	botlib/be_aas_routealt.h\
+	botlib/be_aas_sample.h\
+	botlib/be_ai_weight.h\
+	botlib/be_interface.h\
+	botlib/l_crc.h\
+	botlib/l_libvar.h\
+	botlib/l_log.h\
+	botlib/l_memory.h\
+	botlib/l_precomp.h\
+	botlib/l_script.h\
+	botlib/l_struct.h\
+	botlib/l_utils.h\
 	game/ai_chat.h\
 	game/ai_cmd.h\
 	game/ai_dmnet.h\
@@ -82,7 +136,7 @@
 	unix/unix_glw.h\
 
 </sys/src/cmd/mkone
-CFLAGS=$CFLAGS -DDEDICATED -DC_ONLY
+CFLAGS=$CFLAGS -DDEDICATED -DC_ONLY -DBOTLIB
 
 %.$O:	%.c
 	$CC $CFLAGS -o $stem.$O $stem.c
--- /dev/null
+++ b/code/null/null_vm.c
@@ -1,0 +1,15 @@
+#include "../game/q_shared.h"
+#include "../qcommon/qcommon.h"
+
+void
+VM_Compile(vm_t *, vmHeader_t *)
+{
+	sysfatal("VM_Compile: no.");
+}
+
+int
+VM_CallCompiled(vm_t *, int *)
+{
+	sysfatal("VM_CallCompiled: no.");
+	return 0;
+}
--- a/code/qcommon/common.c
+++ b/code/qcommon/common.c
@@ -1841,7 +1841,7 @@
 
 	if (length > 0x7FFFF) {
 		//randomly trash data within buf
-		rnd = random() * (length - 0x7FFFF);
+		rnd = qrandom() * (length - 0x7FFFF);
 		value = 31;
 		for (i = 0; i < 0x7FFFF; i++) {
 			value *= 109;
--- a/code/qcommon/files.c
+++ b/code/qcommon/files.c
@@ -1205,7 +1205,7 @@
 				&& Q_stricmp( filename + l - 5, ".game" )	// menu files
 				&& Q_stricmp( filename + l - strlen(demoExt), demoExt )	// menu files
 				&& Q_stricmp( filename + l - 4, ".dat" ) ) {	// for journal files
-				fs_fakeChkSum = random();
+				fs_fakeChkSum = qrandom();
 			}
       
 			Q_strncpyz( fsh[*file].name, filename, sizeof( fsh[*file].name ) );
--- a/code/server/sv_bot.c
+++ b/code/server/sv_bot.c
@@ -22,7 +22,26 @@
 // sv_bot.c
 
 #include "server.h"
+#include "../botlib/l_memory.h"
+#include "../botlib/l_log.h"
+#include "../botlib/l_libvar.h"
+#include "../botlib/l_script.h"
+#include "../botlib/l_precomp.h"
+#include "../botlib/l_struct.h"
+#include "../botlib/aasfile.h"
 #include "../game/botlib.h"
+#include "../game/be_aas.h"
+#include "../botlib/be_aas_funcs.h"
+#include "../botlib/be_aas_def.h"
+#include "../botlib/be_interface.h"
+#include "../game/be_ea.h"
+#include "../botlib/be_ai_weight.h"
+#include "../game/be_ai_goal.h"
+#include "../game/be_ai_move.h"
+#include "../game/be_ai_weap.h"
+#include "../game/be_ai_chat.h"
+#include "../game/be_ai_char.h"
+#include "../game/be_ai_gen.h"
 
 typedef struct bot_debugpoly_s
 {
--- a/code/server/sv_game.c
+++ b/code/server/sv_game.c
@@ -22,8 +22,26 @@
 // sv_game.c -- interface to the game dll
 
 #include "server.h"
-
+#include "../botlib/l_memory.h"
+#include "../botlib/l_log.h"
+#include "../botlib/l_libvar.h"
+#include "../botlib/l_script.h"
+#include "../botlib/l_precomp.h"
+#include "../botlib/l_struct.h"
+#include "../botlib/aasfile.h"
 #include "../game/botlib.h"
+#include "../game/be_aas.h"
+#include "../botlib/be_aas_funcs.h"
+#include "../botlib/be_aas_def.h"
+#include "../botlib/be_interface.h"
+#include "../game/be_ea.h"
+#include "../botlib/be_ai_weight.h"
+#include "../game/be_ai_goal.h"
+#include "../game/be_ai_move.h"
+#include "../game/be_ai_weap.h"
+#include "../game/be_ai_chat.h"
+#include "../game/be_ai_char.h"
+#include "../game/be_ai_gen.h"
 
 botlib_export_t	*botlib_export;
 
--- a/code/unix/linux_local.h
+++ b/code/unix/linux_local.h
@@ -22,7 +22,7 @@
 // linux_local.h: Linux-specific Quake3 header file
 
 void Sys_QueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr );
-qboolean Sys_GetPacket ( netadr_t *net_from, msg_t *net_message );
+qboolean Sys_GetPacket ( msg_t *net_message );
 void Sys_SendKeyEvents (void);
 
 // Input subsystem
--- a/code/unix/qk3ded.c
+++ b/code/unix/qk3ded.c
@@ -2,8 +2,10 @@
 #include "../qcommon/qcommon.h"
 #include "../renderer/tr_public.h"
 #include "../client/client.h"
+#include "linux_local.h"
 
 #include <thread.h>
+#include <bio.h>
 
 mainstacksize = 256*1024;
 
@@ -11,6 +13,17 @@
 
 int svonly = 1;
 
+enum{
+	MAX_QUED_EVENTS = 256,
+	MASK_QUED_EVENTS = MAX_QUED_EVENTS - 1
+};
+
+static sysEvent_t  eventQue[MAX_QUED_EVENTS];
+static int eventHead, eventTail;
+static byte sys_packetReceived[MAX_MSGLEN];
+
+static Channel *inchan;
+
 void
 NET_Sleep(int n)
 {
@@ -25,12 +38,111 @@
 	}
 }
 
+void
+Sys_QueEvent(int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr)
+{
+	sysEvent_t	*ev;
+
+	ev = &eventQue[ eventHead & MASK_QUED_EVENTS ];
+	if(eventHead - eventTail >= MAX_QUED_EVENTS){
+		Com_Printf("Sys_QueEvent: overflow\n");
+		if(ev->evPtr)
+			Z_Free(ev->evPtr);
+		eventTail++;
+	}
+	eventHead++;
+	if(time == 0)
+		time = Sys_Milliseconds();
+	ev->evTime = time;
+	ev->evType = type;
+	ev->evValue = value;
+	ev->evValue2 = value2;
+	ev->evPtrLength = ptrLength;
+	ev->evPtr = ptr;
+}
+
+sysEvent_t
+Sys_GetEvent(void)
+{
+	sysEvent_t	ev;
+	char		*s;
+	msg_t netmsg;
+
+	// return if we have data
+	if ( eventHead > eventTail )
+		goto ret;
+
+	// pump the message loop
+	// in vga this calls KBD_Update, under X, it calls GetEvent
+	Sys_SendKeyEvents ();
+
+	// check for console commands
+	if((s = nbrecvp(inchan)) != nil){
+		char	*b;
+		int	 len;
+
+		len = strlen( s ) + 1;
+		b = Z_Malloc( len );
+		strcpy( b, s );
+		Sys_QueEvent( 0, SE_CONSOLE, 0, 0, len, b );
+		free(s);
+	}
+
+	// check for other input devices
+	IN_Frame();
+
+	// check for network packets
+	MSG_Init( &netmsg, sys_packetReceived, sizeof( sys_packetReceived ) );
+	if ( Sys_GetPacket ( &netmsg ) )
+	{
+		netadr_t		*buf;
+		int			 len;
+
+		// copy out to a seperate buffer for qeueing
+		len = sizeof( netadr_t ) + netmsg.cursize;
+		buf = Z_Malloc( len );
+		*buf = *net_from;
+		memcpy( buf+1, netmsg.data, netmsg.cursize );
+		Sys_QueEvent( 0, SE_PACKET, 0, 0, len, buf );
+	}
+
+	// return if we have data
+	if ( eventHead > eventTail )
+	{
+ret:
+		eventTail++;
+		return eventQue[ ( eventTail - 1 ) & MASK_QUED_EVENTS ];
+	}
+
+	// create an empty event to return
+
+	memset( &ev, 0, sizeof( ev ) );
+	ev.evTime = Sys_Milliseconds();
+
+	return ev;
+}
+
 static void
-Sys_ConsoleInputInit(void)
+cproc(void *)
 {
-	/* FIXME: on exit: Sys_Exit(0) */
+	char *s;
+	Biobuf *bf;
+
+	if((bf = Bfdopen(0, OREAD)) == nil)
+		sysfatal("Bfdopen: %r");
+	for(;;){
+		if((s = Brdstr(bf, '\n', 1)) == nil)
+			break;
+		if(sendp(inchan, s) < 0){
+			free(s);
+			break;
+		}
+		send(echan, nil);
+	}
+	Bterm(bf);
 }
 
+
 void
 threadmain(int argc, char **argv)
 {
@@ -49,7 +161,11 @@
 	}
 	Com_Init(args);
 	NET_Init();
-	Sys_ConsoleInputInit();
+	if((echan = chancreate(sizeof(int), 1)) == nil
+	|| (inchan = chancreate(sizeof(void *), 2)) == nil)
+		sysfatal("chancreate: %r");
+	if(proccreate(cproc, nil, 8192) < 0)
+		sysfatal("proccreate iproc: %r");
 	setfcr(getfcr() & ~(FPINVAL|FPZDIV));
 	for(;;)
 		Com_Frame();
--- a/code/unix/unix_main.c
+++ b/code/unix/unix_main.c
@@ -635,139 +635,7 @@
   return libHandle;
 }
 
-/*
-========================================================================
-
-EVENT LOOP
-
-========================================================================
-*/
-
-// bk000306: upped this from 64
-#define	MAX_QUED_EVENTS		256
-#define	MASK_QUED_EVENTS	( MAX_QUED_EVENTS - 1 )
-
-sysEvent_t  eventQue[MAX_QUED_EVENTS];
-// bk000306: initialize
-int   eventHead = 0;
-int             eventTail = 0;
-byte    sys_packetReceived[MAX_MSGLEN];
-
-/*
-================
-Sys_QueEvent
-
-A time of 0 will get the current time
-Ptr should either be null, or point to a block of data that can
-be freed by the game later.
-================
-*/
-void Sys_QueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr ) {
-  sysEvent_t  *ev;
-
-  ev = &eventQue[ eventHead & MASK_QUED_EVENTS ];
-
-  // bk000305 - was missing
-  if ( eventHead - eventTail >= MAX_QUED_EVENTS )
-  {
-    Com_Printf("Sys_QueEvent: overflow\n");
-    // we are discarding an event, but don't leak memory
-    if ( ev->evPtr )
-    {
-      Z_Free( ev->evPtr );
-    }
-    eventTail++;
-  }
-
-  eventHead++;
-
-  if ( time == 0 )
-  {
-    time = Sys_Milliseconds();
-  }
-
-  ev->evTime = time;
-  ev->evType = type;
-  ev->evValue = value;
-  ev->evValue2 = value2;
-  ev->evPtrLength = ptrLength;
-  ev->evPtr = ptr;
-}
-
-/*
-================
-Sys_GetEvent
-
-================
-*/
-sysEvent_t Sys_GetEvent( void ) {
-  sysEvent_t  ev;
-  char    *s;
-  msg_t   netmsg;
-  netadr_t  adr;
-
-  // return if we have data
-  if ( eventHead > eventTail )
-  {
-    eventTail++;
-    return eventQue[ ( eventTail - 1 ) & MASK_QUED_EVENTS ];
-  }
-
-  // pump the message loop
-  // in vga this calls KBD_Update, under X, it calls GetEvent
-  Sys_SendKeyEvents ();
-
-  // check for console commands
-  s = Sys_ConsoleInput();
-  if ( s )
-  {
-    char  *b;
-    int   len;
-
-    len = strlen( s ) + 1;
-    b = Z_Malloc( len );
-    strcpy( b, s );
-    Sys_QueEvent( 0, SE_CONSOLE, 0, 0, len, b );
-  }
-
-  // check for other input devices
-  IN_Frame();
-
-  // check for network packets
-  MSG_Init( &netmsg, sys_packetReceived, sizeof( sys_packetReceived ) );
-  if ( Sys_GetPacket ( &adr, &netmsg ) )
-  {
-    netadr_t    *buf;
-    int       len;
-
-    // copy out to a seperate buffer for qeueing
-    len = sizeof( netadr_t ) + netmsg.cursize;
-    buf = Z_Malloc( len );
-    *buf = adr;
-    memcpy( buf+1, netmsg.data, netmsg.cursize );
-    Sys_QueEvent( 0, SE_PACKET, 0, 0, len, buf );
-  }
-
-  // return if we have data
-  if ( eventHead > eventTail )
-  {
-    eventTail++;
-    return eventQue[ ( eventTail - 1 ) & MASK_QUED_EVENTS ];
-  }
-
-  // create an empty event to return
-
-  memset( &ev, 0, sizeof( ev ) );
-  ev.evTime = Sys_Milliseconds();
-
-  return ev;
-}
-
 /*****************************************************************************/
-
-qboolean Sys_CheckCD( void ) {
-  return qtrue;
-}
 
 void Sys_AppActivate (void)
 {