Index: darkplaces/host.c
diff -u darkplaces/host.c:1.75 darkplaces/host.c:1.76
--- darkplaces/host.c:1.75	Mon Aug 18 20:25:06 2003
+++ darkplaces/host.c	Fri Aug 29 21:54:31 2003
@@ -96,8 +96,6 @@
 cvar_t timestamps = {CVAR_SAVE, "timestamps", "0"};
 cvar_t timeformat = {CVAR_SAVE, "timeformat", "[%b %e %X] "};
 
-cvar_t sv_maxplayers = {0, "maxplayers", "8"};
-
 /*
 ================
 Host_EndGame
@@ -182,6 +180,8 @@
 	longjmp (host_abortserver, 1);
 }
 
+mempool_t *sv_clients_mempool = NULL;
+
 void Host_ServerOptions (void)
 {
 	int i, numplayers;
@@ -241,7 +241,9 @@
 	if (numplayers > 1 && !deathmatch.integer)
 		Cvar_SetValueQuick(&deathmatch, 1);
 
-	Cvar_SetValueQuick(&sv_maxplayers, numplayers);
+	svs.maxclients = numplayers;
+	sv_clients_mempool = Mem_AllocPool("server clients");
+	svs.clients = Mem_Alloc(sv_clients_mempool, sizeof(client_t) * svs.maxclients);
 }
 
 /*
@@ -283,8 +285,6 @@
 	Cvar_RegisterVariable (&timestamps);
 	Cvar_RegisterVariable (&timeformat);
 
-	Cvar_RegisterVariable(&sv_maxplayers);
-
 	Host_ServerOptions ();
 }
 
@@ -358,9 +358,9 @@
 	vsnprintf(string, sizeof(string), fmt,argptr);
 	va_end(argptr);
 
-	for (i = 0;i < MAX_SCOREBOARD;i++)
+	for (i = 0, client = svs.clients;i < svs.maxclients;i++, client++)
 	{
-		if ((client = svs.connectedclients[i]) && client->spawned)
+		if (client->spawned)
 		{
 			MSG_WriteByte(&client->message, svc_print);
 			MSG_WriteString(&client->message, string);
@@ -436,9 +436,9 @@
 	}
 
 	// send notification to all clients
-	for (i = 0;i < MAX_SCOREBOARD;i++)
+	for (i = 0, client = svs.clients;i < svs.maxclients;i++, client++)
 	{
-		if (!(client = svs.connectedclients[i]))
+		if (!client->active)
 			continue;
 		MSG_WriteByte(&client->message, svc_updatename);
 		MSG_WriteByte(&client->message, host_client->number);
@@ -456,9 +456,8 @@
 	// free the client now
 	if (host_client->entitydatabase4)
 		EntityFrame4_FreeDatabase(host_client->entitydatabase4);
-	// remove the index reference
-	svs.connectedclients[host_client->number] = NULL;
-	Mem_Free(host_client);
+	// clear the client struct (this sets active to false)
+	memset(host_client, 0, sizeof(*host_client));
 }
 
 /*
@@ -473,7 +472,6 @@
 	int i, count;
 	sizebuf_t buf;
 	char message[4];
-	double start;
 
 	if (!sv.active)
 		return;
@@ -489,32 +487,6 @@
 	NetConn_Heartbeat(2);
 	NetConn_Heartbeat(2);
 
-// flush any pending messages - like the score!!!
-	start = Sys_DoubleTime();
-	do
-	{
-		count = 0;
-		NetConn_ClientFrame();
-		NetConn_ServerFrame();
-		for (i = 0;i < MAX_SCOREBOARD;i++)
-		{
-			host_client = svs.connectedclients[i];
-			if (host_client && host_client->message.cursize)
-			{
-				if (NetConn_CanSendMessage(host_client->netconnection))
-				{
-					NetConn_SendReliableMessage(host_client->netconnection, &host_client->message);
-					SZ_Clear(&host_client->message);
-				}
-				else
-					count++;
-			}
-		}
-		if ((Sys_DoubleTime() - start) > 3.0)
-			break;
-	}
-	while(count);
-
 // make sure all the clients know we're disconnecting
 	buf.data = message;
 	buf.maxsize = 4;
@@ -524,8 +496,8 @@
 	if (count)
 		Con_Printf("Host_ShutdownServer: NetConn_SendToAll failed for %u clients\n", count);
 
-	for (i = 0;i < MAX_SCOREBOARD;i++)
-		if ((host_client = svs.connectedclients[i]))
+	for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
+		if (host_client->active)
 			SV_DropClient(crash); // server shutdown
 
 	NetConn_CloseServerPorts();
@@ -534,6 +506,7 @@
 // clear structures
 //
 	memset(&sv, 0, sizeof(sv));
+	memset(svs.clients, 0, svs.maxclients*sizeof(client_t));
 }
 
 
@@ -835,9 +808,11 @@
 	timecount = 0;
 	timetotal = 0;
 	c = 0;
-	for (i = 0;i < MAX_SCOREBOARD;i++)
-		if (svs.connectedclients[i])
+	for (i=0 ; i<svs.maxclients ; i++)
+	{
+		if (svs.clients[i].active)
 			c++;
+	}
 
 	Con_Printf ("serverprofile: %2i clients %2i msec\n",  c,  m);
 }
Index: darkplaces/host_cmd.c
diff -u darkplaces/host_cmd.c:1.57 darkplaces/host_cmd.c:1.58
--- darkplaces/host_cmd.c:1.57	Thu Aug 28 04:08:07 2003
+++ darkplaces/host_cmd.c	Fri Aug 29 21:54:31 2003
@@ -69,16 +69,16 @@
 	else
 		print = SV_ClientPrintf;
 
-	for (players = 0, j = 0;j < MAX_SCOREBOARD;j++)
-		if (svs.connectedclients[j])
+	for (players = 0, j = 0;j < svs.maxclients;j++)
+		if (svs.clients[j].active)
 			players++;
 	print ("host:    %s\n", Cvar_VariableString ("hostname"));
 	print ("version: %s build %s\n", gamename, buildstring);
 	print ("map:     %s\n", sv.name);
-	print ("players: %i active (%i max)\n\n", players, min(sv_maxplayers.integer, MAX_SCOREBOARD));
-	for (j = 0;j < MAX_SCOREBOARD;j++)
+	print ("players: %i active (%i max)\n\n", players, svs.maxclients);
+	for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
 	{
-		if (!(client = svs.connectedclients[j]))
+		if (!client->active)
 			continue;
 		seconds = (int)(realtime - client->netconnection->connecttime);
 		minutes = seconds / 60;
@@ -241,9 +241,9 @@
 	}
 
 	SV_ClientPrintf ("Client ping times:\n");
-	for (i = 0;i < MAX_SCOREBOARD;i++)
+	for (i = 0, client = svs.clients;i < svs.maxclients;i++, client++)
 	{
-		if (!(client = svs.connectedclients[i]))
+		if (!client->active)
 			continue;
 		total = 0;
 		for (j=0 ; j<NUM_PING_TIMES ; j++)
@@ -411,7 +411,7 @@
 	if (cmd_source != src_command)
 		return;
 
-	if (!sv.active)
+	if (cls.state != ca_connected || !sv.active)
 	{
 		Con_Printf ("Not playing a local game.\n");
 		return;
@@ -423,16 +423,16 @@
 		return;
 	}
 
-	for (i = 0;i < MAX_SCOREBOARD;i++)
+	for (i = 0;i < svs.maxclients;i++)
 	{
-		if (svs.connectedclients[i])
+		if (svs.clients[i].active)
 		{
 			if (i > 0)
 			{
 				Con_Printf("Can't save multiplayer games.\n");
 				return;
 			}
-			if (svs.connectedclients[i]->edict->v->deadflag)
+			if (svs.clients[i].edict->v->deadflag)
 			{
 				Con_Printf("Can't savegame with a dead player\n");
 				return;
@@ -468,7 +468,7 @@
 	Host_SavegameComment (comment);
 	FS_Printf (f, "%s\n", comment);
 	for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
-		FS_Printf (f, "%f\n", svs.connectedclients[0]->spawn_parms[i]);
+		FS_Printf (f, "%f\n", svs.clients[0].spawn_parms[i]);
 	FS_Printf (f, "%d\n", current_skill);
 	FS_Printf (f, "%s\n", sv.name);
 	FS_Printf (f, "%f\n",sv.time);
@@ -649,7 +649,7 @@
 	FS_Close (f);
 
 	for (i = 0;i < NUM_SPAWN_PARMS;i++)
-		svs.connectedclients[0]->spawn_parms[i] = spawn_parms[i];
+		svs.clients[0].spawn_parms[i] = spawn_parms[i];
 
 	// make sure we're connected to loopback
 	if (cls.state == ca_disconnected || !(cls.state == ca_connected && cls.netcon != NULL && LHNETADDRESS_GetAddressType(&cls.netcon->peeraddress) == LHNETADDRESSTYPE_LOOP))
@@ -768,8 +768,8 @@
 	text[j++] = '\n';
 	text[j++] = 0;
 
-	for (j = 0;j < MAX_SCOREBOARD;j++)
-		if ((host_client = svs.connectedclients[j]) && host_client->spawned && (!teamplay.integer || host_client->edict->v->team == save->edict->v->team))
+	for (j = 0, host_client = svs.clients;j < svs.maxclients;j++, host_client++)
+		if (host_client->spawned && (!teamplay.integer || host_client->edict->v->team == save->edict->v->team))
 			SV_ClientPrintf("%s", text);
 	host_client = save;
 
@@ -845,8 +845,8 @@
 	text[j++] = 0;
 
 	save = host_client;
-	for (j = 0;j < MAX_SCOREBOARD;j++)
-		if ((host_client = svs.connectedclients[j]) && host_client->spawned && !strcasecmp(host_client->name, Cmd_Argv(1)))
+	for (j = 0, host_client = svs.clients;j < svs.maxclients;j++, host_client++)
+		if (host_client->spawned && !strcasecmp(host_client->name, Cmd_Argv(1)))
 			SV_ClientPrintf("%s", text);
 	host_client = save;
 }
@@ -1115,9 +1115,9 @@
 	MSG_WriteByte (&host_client->message, svc_time);
 	MSG_WriteFloat (&host_client->message, sv.time);
 
-	for (i = 0;i < MAX_SCOREBOARD;i++)
+	for (i = 0, client = svs.clients;i < svs.maxclients;i++, client++)
 	{
-		if (!(client = svs.connectedclients[i]))
+		if (!client->active)
 			continue;
 		MSG_WriteByte (&host_client->message, svc_updatename);
 		MSG_WriteByte (&host_client->message, i);
@@ -1214,22 +1214,22 @@
 	if (Cmd_Argc() > 2 && strcmp(Cmd_Argv(1), "#") == 0)
 	{
 		i = atof(Cmd_Argv(2)) - 1;
-		if (i < 0 || i >= MAX_SCOREBOARD || !(host_client = svs.connectedclients[i]))
+		if (i < 0 || i >= svs.maxclients || !(host_client = svs.clients + i)->active)
 			return;
 		byNumber = true;
 	}
 	else
 	{
-		for (i = 0;i < MAX_SCOREBOARD;i++)
+		for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
 		{
-			if (!(host_client = svs.connectedclients[i]))
+			if (!host_client->active)
 				continue;
 			if (strcasecmp(host_client->name, Cmd_Argv(1)) == 0)
 				break;
 		}
 	}
 
-	if (i < MAX_SCOREBOARD)
+	if (i < svs.maxclients)
 	{
 		if (cmd_source == src_command)
 		{
@@ -1659,6 +1659,36 @@
 		Cbuf_AddText ("connect local");
 }
 
+static void MaxPlayers_f(void)
+{
+	int n;
+
+	if (Cmd_Argc() != 2)
+	{
+		Con_Printf("\"maxplayers\" is \"%u\"\n", svs.maxclients);
+		return;
+	}
+
+	if (sv.active)
+	{
+		Con_Printf("maxplayers can not be changed while a server is running.\n");
+		return;
+	}
+
+	n = atoi(Cmd_Argv(1));
+	n = bound(1, n, MAX_SCOREBOARD);
+	Con_Printf ("\"maxplayers\" set to \"%u\"\n", n);
+
+	if (svs.clients)
+		Mem_Free(svs.clients);
+	svs.maxclients = n;
+	svs.clients = Mem_Alloc(sv_clients_mempool, sizeof(client_t) * svs.maxclients);
+	if (n == 1)
+		Cvar_Set ("deathmatch", "0");
+	else
+		Cvar_Set ("deathmatch", "1");
+}
+
 //=============================================================================
 
 /*
@@ -1723,6 +1753,7 @@
 	Cmd_AddCommand ("prespawn", Host_PreSpawn_f);
 	Cmd_AddCommand ("spawn", Host_Spawn_f);
 	Cmd_AddCommand ("begin", Host_Begin_f);
+	Cmd_AddCommand ("maxplayers", MaxPlayers_f);
 
 	Cvar_RegisterVariable(&sv_cheats);
 }
Index: darkplaces/menu.c
diff -u darkplaces/menu.c:1.84 darkplaces/menu.c:1.85
--- darkplaces/menu.c:1.84	Mon Aug 25 02:35:47 2003
+++ darkplaces/menu.c	Fri Aug 29 21:54:31 2003
@@ -2970,7 +2970,7 @@
 	m_state = m_gameoptions;
 	m_entersound = true;
 	if (maxplayers == 0)
-		maxplayers = sv_maxplayers.integer;
+		maxplayers = svs.maxclients;
 	if (maxplayers < 2)
 		maxplayers = min(8, MAX_SCOREBOARD);
 }
Index: darkplaces/netconn.c
diff -u darkplaces/netconn.c:1.14 darkplaces/netconn.c:1.15
--- darkplaces/netconn.c:1.14	Sat Aug 23 03:09:13 2003
+++ darkplaces/netconn.c	Fri Aug 29 21:54:31 2003
@@ -621,15 +621,8 @@
 
 int NetConn_IsLocalGame(void)
 {
-	int i;
-	if (cls.state == ca_connected && sv.active/* && LHNETADDRESS_GetAddressType(cl.netcon->peeraddress) == LHNETADDRESSTYPE_LOOP*/)
-	{
-		// make sure there are no other connected clients
-		for (i = 1;i < MAX_SCOREBOARD;i++)
-			if (svs.connectedclients[i])
-				return false;
+	if (cls.state == ca_connected && sv.active && cl.maxclients == 1)
 		return true;
-	}
 	return false;
 }
 
@@ -987,7 +980,7 @@
 extern void SV_ConnectClient(int clientnum, netconn_t *netconnection);
 int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, qbyte *data, int length, lhnetaddress_t *peeraddress)
 {
-	int i, n, ret, clientnum, responselength, best, clientcount;
+	int i, n, ret, clientnum, responselength, best;
 	double besttime;
 	client_t *client;
 	netconn_t *conn;
@@ -1057,10 +1050,10 @@
 						else
 						{
 							// see if this is a duplicate connection request
-							for (clientnum = 0;clientnum < MAX_SCOREBOARD;clientnum++)
-								if ((client = svs.connectedclients[clientnum]) && LHNETADDRESS_Compare(peeraddress, &client->netconnection->peeraddress) == 0)
+							for (clientnum = 0, client = svs.clients;clientnum < svs.maxclients;clientnum++, client++)
+								if (client->netconnection && LHNETADDRESS_Compare(peeraddress, &client->netconnection->peeraddress) == 0)
 									break;
-							if (clientnum < MAX_SCOREBOARD)
+							if (clientnum < svs.maxclients)
 							{
 								// duplicate connection request
 								if (realtime - client->netconnection->connecttime < 2.0)
@@ -1081,39 +1074,27 @@
 							else
 							{
 								// this is a new client, find a slot
-								for (clientcount = 0, clientnum = 0;clientnum < MAX_SCOREBOARD;clientnum++)
-									if (svs.connectedclients[clientnum])
-										clientcount++;
-								for (clientnum = 0;clientnum < MAX_SCOREBOARD;clientnum++)
-									if (!svs.connectedclients[clientnum])
+								for (clientnum = 0, client = svs.clients;clientnum < svs.maxclients;clientnum++, client++)
+									if (!client->active)
 										break;
-								if (clientcount < max(1, sv_maxplayers.integer) && clientnum < MAX_SCOREBOARD)
+								if (clientnum < svs.maxclients)
 								{
-									// allocate and prepare the client struct
-									if ((client = Mem_Alloc(sv_clients_mempool, sizeof(client_t))))
+									// prepare the client struct
+									if ((client->entitydatabase4 = EntityFrame4_AllocDatabase(sv_clients_mempool)))
 									{
-										if ((client->entitydatabase4 = EntityFrame4_AllocDatabase(sv_clients_mempool)))
+										if ((conn = NetConn_Open(mysocket, peeraddress)))
 										{
-											if ((conn = NetConn_Open(mysocket, peeraddress)))
-											{
-												// allocated connection
-												LHNETADDRESS_ToString(peeraddress, conn->address, sizeof(conn->address), true);
-												if (developer.integer)
-													Con_Printf("Datagram_ParseConnectionless: sending \"accept\" to %s.\n", conn->address);
-												NetConn_WriteString(mysocket, "\377\377\377\377accept", peeraddress);
-												// now set up the client struct
-												svs.connectedclients[clientnum] = client;
-												SV_ConnectClient(clientnum, conn);
-												NetConn_Heartbeat(1);
-											}
-											else
-											{
-												EntityFrame4_FreeDatabase(client->entitydatabase4);
-												Mem_Free(client);
-											}
+											// allocated connection
+											LHNETADDRESS_ToString(peeraddress, conn->address, sizeof(conn->address), true);
+											if (developer.integer)
+												Con_Printf("Datagram_ParseConnectionless: sending \"accept\" to %s.\n", conn->address);
+											NetConn_WriteString(mysocket, "\377\377\377\377accept", peeraddress);
+											// now set up the client
+											SV_ConnectClient(clientnum, conn);
+											NetConn_Heartbeat(1);
 										}
 										else
-											Mem_Free(client);
+											EntityFrame4_FreeDatabase(client->entitydatabase4);
 									}
 								}
 								else
@@ -1135,13 +1116,13 @@
 				// If there was a challenge in the getinfo message
 				if (length > 8 && string[7] == ' ')
 					challenge = string + 8;
-				for (i = 0, n = 0;i < MAX_SCOREBOARD;i++)
-					if (svs.connectedclients[i])
+				for (i = 0, n = 0;i < svs.maxclients;i++)
+					if (svs.clients[i].active)
 						n++;
 				responselength = snprintf(response, sizeof(response), "\377\377\377\377infoResponse\x0A"
 							"\\gamename\\%s\\modname\\%s\\sv_maxclients\\%d"
 							"\\clients\\%d\\mapname\\%s\\hostname\\%s\\protocol\\%d%s%s",
-							gamename, com_modname, min(sv_maxplayers.integer, MAX_SCOREBOARD), n,
+							gamename, com_modname, svs.maxclients, n,
 							sv.name, hostname.string, NET_PROTOCOL_VERSION, challenge ? "\\challenge\\" : "", challenge ? challenge : "");
 				// does it fit in the buffer?
 				if (responselength < (int)sizeof(response))
@@ -1201,10 +1182,10 @@
 						else
 						{
 							// see if this is a duplicate connection request
-							for (clientnum = 0;clientnum < MAX_SCOREBOARD;clientnum++)
-								if ((client = svs.connectedclients[clientnum]) && LHNETADDRESS_Compare(peeraddress, &client->netconnection->peeraddress) == 0)
+							for (clientnum = 0, client = svs.clients;clientnum < svs.maxclients;clientnum++, client++)
+								if (client->netconnection && LHNETADDRESS_Compare(peeraddress, &client->netconnection->peeraddress) == 0)
 									break;
-							if (clientnum < MAX_SCOREBOARD)
+							if (clientnum < svs.maxclients)
 							{
 								// duplicate connection request
 								if (realtime - client->netconnection->connecttime < 2.0)
@@ -1233,11 +1214,10 @@
 							else
 							{
 								// this is a new client, find a slot
-								for (clientnum = 0;clientnum < MAX_SCOREBOARD;clientnum++)
-									if (!(client = svs.connectedclients[clientnum]))
+								for (clientnum = 0, client = svs.clients;clientnum < svs.maxclients;clientnum++, client++)
+									if (!client->active)
 										break;
-								// WARNING: this is broken code
-								if (clientnum < MAX_SCOREBOARD && (client->netconnection = conn = NetConn_Open(mysocket, peeraddress)) != NULL)
+								if (clientnum < svs.maxclients && (client->netconnection = conn = NetConn_Open(mysocket, peeraddress)) != NULL)
 								{
 									// connect to the client
 									// everything is allocated, just fill in the details
@@ -1292,7 +1272,7 @@
 						MSG_WriteString(&net_message, hostname.string);
 						MSG_WriteString(&net_message, sv.name);
 						MSG_WriteByte(&net_message, net_activeconnections);
-						MSG_WriteByte(&net_message, min(sv_maxplayers.integer, MAX_SCOREBOARD));
+						MSG_WriteByte(&net_message, svs.maxclients);
 						MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
 						*((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
 						NetConn_Write(mysocket, net_message.data, net_message.cursize, peeraddress);
@@ -1367,25 +1347,14 @@
 			}
 		}
 #endif
-		for (i = 0;i < MAX_SCOREBOARD;i++)
+		for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
 		{
-			if ((host_client = svs.connectedclients[i]))
+			if (host_client->netconnection && host_client->netconnection->mysocket == mysocket && !LHNETADDRESS_Compare(&host_client->netconnection->peeraddress, peeraddress))
 			{
-				if (host_client->netconnection)
-				{
-					if (host_client->netconnection->mysocket == mysocket && !LHNETADDRESS_Compare(&host_client->netconnection->peeraddress, peeraddress))
-					{
-						sv_player = host_client->edict;
-						if ((ret = NetConn_ReceivedMessage(host_client->netconnection, data, length)) == 2)
-							SV_ReadClientMessage();
-						return ret;
-					}
-				}
-				else
-				{
-					Con_Printf("Removing client with no netconnection!\n");
-					SV_DropClient(true);
-				}
+				sv_player = host_client->edict;
+				if ((ret = NetConn_ReceivedMessage(host_client->netconnection, data, length)) == 2)
+					SV_ReadClientMessage();
+				return ret;
 			}
 		}
 	}
@@ -1401,9 +1370,9 @@
 	for (i = 0;i < sv_numsockets;i++)
 		while (sv_sockets[i] && (length = NetConn_Read(sv_sockets[i], readbuffer, sizeof(readbuffer), &peeraddress)) > 0)
 			NetConn_ServerParsePacket(sv_sockets[i], readbuffer, length, &peeraddress);
-	for (i = 0;i < MAX_SCOREBOARD;i++)
+	for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
 	{
-		if ((host_client = svs.connectedclients[i]) && realtime > host_client->netconnection->timeout)
+		if (host_client->netconnection && realtime > host_client->netconnection->timeout)
 		{
 			Con_Printf("Client \"%s\" connection timed out\n", host_client->name);
 			sv_player = host_client->edict;
@@ -1478,7 +1447,7 @@
 
 	// make advertising optional and don't advertise singleplayer games, and
 	// only send a heartbeat as often as the admin wants
-	if (sv.active && sv_public.integer && (!cl.islocalgame || sv_maxplayers.integer >= 2) && (priority > 1 || realtime > nextheartbeattime))
+	if (sv.active && sv_public.integer && svs.maxclients >= 2 && (priority > 1 || realtime > nextheartbeattime))
 	{
 		nextheartbeattime = realtime + sv_heartbeatperiod.value;
 		for (masternum = 0;sv_masters[masternum].name;masternum++)
@@ -1505,9 +1474,9 @@
 		count = 0;
 		NetConn_ClientFrame();
 		NetConn_ServerFrame();
-		for (i = 0;i < MAX_SCOREBOARD;i++)
+		for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
 		{
-			if ((host_client = svs.connectedclients[i]))
+			if (host_client->netconnection)
 			{
 				if (NetConn_CanSendMessage(host_client->netconnection))
 				{
Index: darkplaces/pr_cmds.c
diff -u darkplaces/pr_cmds.c:1.67 darkplaces/pr_cmds.c:1.68
--- darkplaces/pr_cmds.c:1.67	Sun Aug 24 00:00:52 2003
+++ darkplaces/pr_cmds.c	Fri Aug 29 21:54:31 2003
@@ -372,13 +372,15 @@
 	entnum = G_EDICTNUM(OFS_PARM0);
 	s = PF_VarString(1);
 
-	if (entnum < 1 || entnum > MAX_SCOREBOARD || !svs.connectedclients[entnum-1])
+	if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
 	{
 		Con_Printf ("tried to sprint to a non-client\n");
 		return;
 	}
 
-	client = svs.connectedclients[entnum-1];
+	client = svs.clients + entnum-1;
+	if (!client->netconnection)
+		return;
 	MSG_WriteChar(&client->message,svc_print);
 	MSG_WriteString(&client->message, s );
 }
@@ -402,13 +404,15 @@
 	entnum = G_EDICTNUM(OFS_PARM0);
 	s = PF_VarString(1);
 
-	if (entnum < 1 || entnum > MAX_SCOREBOARD || !svs.connectedclients[entnum-1])
+	if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
 	{
 		Con_Printf ("tried to sprint to a non-client\n");
 		return;
 	}
 
-	client = svs.connectedclients[entnum-1];
+	client = svs.clients + entnum-1;
+	if (!client->netconnection)
+		return;
 	MSG_WriteChar(&client->message,svc_centerprint);
 	MSG_WriteString(&client->message, s );
 }
@@ -829,8 +833,8 @@
 
 // cycle to the next one
 
-	check = bound(1, check, MAX_SCOREBOARD);
-	if (check == MAX_SCOREBOARD)
+	check = bound(1, check, svs.maxclients);
+	if (check == svs.maxclients)
 		i = 1;
 	else
 		i = check + 1;
@@ -840,7 +844,7 @@
 		// count the cost
 		pr_xfunction->builtinsprofile++;
 		// wrap around
-		if (i == MAX_SCOREBOARD+1)
+		if (i == svs.maxclients+1)
 			i = 1;
 		// look up the client's edict
 		ent = EDICT_NUM(i);
@@ -930,12 +934,15 @@
 	client_t	*old;
 
 	entnum = G_EDICTNUM(OFS_PARM0);
-	if (entnum < 1 || entnum > MAX_SCOREBOARD)
-		Host_Error ("Parm 0 not a client");
+	if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
+	{
+		Con_Printf("Can't stuffcmd to a non-client");
+		return;
+	}
 	str = G_STRING(OFS_PARM1);
 
 	old = host_client;
-	if ((host_client = svs.connectedclients[entnum-1]))
+	if ((host_client = svs.clients + entnum-1) && host_client->netconnection)
 		Host_ClientCommands ("%s", str);
 	host_client = old;
 }
@@ -951,10 +958,7 @@
 */
 void PF_localcmd (void)
 {
-	char	*str;
-
-	str = G_STRING(OFS_PARM0);
-	Cbuf_AddText (str);
+	Cbuf_AddText(G_STRING(OFS_PARM0));
 }
 
 /*
@@ -966,11 +970,7 @@
 */
 void PF_cvar (void)
 {
-	char	*str;
-
-	str = G_STRING(OFS_PARM0);
-
-	G_FLOAT(OFS_RETURN) = Cvar_VariableValue (str);
+	G_FLOAT(OFS_RETURN) = Cvar_VariableValue(G_STRING(OFS_PARM0));
 }
 
 /*
@@ -982,12 +982,7 @@
 */
 void PF_cvar_set (void)
 {
-	char	*var, *val;
-
-	var = G_STRING(OFS_PARM0);
-	val = G_STRING(OFS_PARM1);
-
-	Cvar_Set (var, val);
+	Cvar_Set(G_STRING(OFS_PARM0), G_STRING(OFS_PARM1));
 }
 
 /*
@@ -1116,7 +1111,7 @@
 	ed = G_EDICT(OFS_PARM0);
 	if (ed == sv.edicts)
 		Host_Error("remove: tried to remove world\n");
-	if (NUM_FOR_EDICT(ed) <= MAX_SCOREBOARD)
+	if (NUM_FOR_EDICT(ed) <= svs.maxclients)
 		Host_Error("remove: tried to remove a client\n");
 	ED_Free (ed);
 }
@@ -1440,9 +1435,9 @@
 	if (sv.state != ss_active)
 		return;
 
-	for (j = 0;j < MAX_SCOREBOARD;j++)
+	for (j = 0, host_client = svs.clients;j < svs.maxclients;j++, host_client++)
 	{
-		if ((client = svs.connectedclients[j]))
+		if (client->netconnection)
 		{
 			MSG_WriteChar (&client->message, svc_lightstyle);
 			MSG_WriteChar (&client->message,style);
@@ -1729,9 +1724,9 @@
 	case MSG_ONE:
 		ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
 		entnum = NUM_FOR_EDICT(ent);
-		if (entnum < 1 || entnum > MAX_SCOREBOARD || svs.connectedclients[entnum-1] == NULL)
-			Host_Error("WriteDest: not a client");
-		return &svs.connectedclients[entnum-1]->message;
+		if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
+			Con_Printf("WriteDest: tried to write to non-client\n");
+		return &svs.clients[entnum-1].message;
 
 	case MSG_ALL:
 		return &sv.reliable_datagram;
@@ -1841,11 +1836,14 @@
 
 	ent = G_EDICT(OFS_PARM0);
 	i = NUM_FOR_EDICT(ent);
-	if (i < 1 || i > MAX_SCOREBOARD || !svs.connectedclients[i-1])
-		Host_Error ("Entity is not a client");
+	if (i < 1 || i > svs.maxclients || !svs.clients[i-1].active)
+	{
+		Con_Printf("tried to setspawnparms on a non-client\n");
+		return;
+	}
 
 	// copy spawn parms out of the client_t
-	client = svs.connectedclients[i-1];
+	client = svs.clients + i-1;
 	for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
 		(&pr_global_struct->parm1)[i] = client->spawn_parms[i];
 }
@@ -2084,12 +2082,13 @@
 	entnum = G_EDICTNUM(OFS_PARM0);
 	i = G_FLOAT(OFS_PARM1);
 
-	if (entnum < 1 || entnum > MAX_SCOREBOARD || !(client = svs.connectedclients[entnum-1]))
+	if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
 	{
 		Con_Printf ("tried to setcolor a non-client\n");
 		return;
 	}
 
+	client = svs.clients + entnum-1;
 	if ((val = GETEDICTFIELDVALUE(client->edict, eval_clientcolors)))
 		val->_float = i;
 	client->colors = i;
@@ -2887,11 +2886,14 @@
 
 	//find client for this entity
 	i = (NUM_FOR_EDICT(G_EDICT(OFS_PARM0)) - 1);
-	if (i < 0 || i >= MAX_SCOREBOARD || !svs.connectedclients[i])
-		Host_Error("PF_clientcommand: entity is not a client");
+	if (i < 0 || i >= svs.maxclients || !svs.clients[i].active)
+	{
+		Con_Printf("PF_clientcommand: entity is not a client");
+		return;
+	}
 
 	temp_client = host_client;
-	host_client = svs.connectedclients[i];
+	host_client = svs.clients + i;
 	Cmd_ExecuteString (G_STRING(OFS_PARM1), src_client);
 	host_client = temp_client;
 }
Index: darkplaces/pr_edict.c
diff -u darkplaces/pr_edict.c:1.48 darkplaces/pr_edict.c:1.49
--- darkplaces/pr_edict.c:1.48	Sat Aug  9 12:56:06 2003
+++ darkplaces/pr_edict.c	Fri Aug 29 21:54:31 2003
@@ -199,11 +199,11 @@
 	e->e->free = false;
 	// LordHavoc: for consistency set these here
 	num = NUM_FOR_EDICT(e) - 1;
-	if (num >= 0 && num < MAX_SCOREBOARD && svs.connectedclients[num])
+	if (num >= 0 && num < svs.maxclients)
 	{
 		e->v->colormap = num + 1;
-		e->v->team = (svs.connectedclients[num]->colors & 15) + 1;
-		e->v->netname = PR_SetString(svs.connectedclients[num]->name);
+		e->v->team = (svs.clients[num].colors & 15) + 1;
+		e->v->netname = PR_SetString(svs.clients[num].name);
 	}
 }
 
@@ -223,7 +223,7 @@
 	int			i;
 	edict_t		*e;
 
-	for (i = MAX_SCOREBOARD + 1;i < sv.num_edicts;i++)
+	for (i = svs.maxclients + 1;i < sv.num_edicts;i++)
 	{
 		e = EDICT_NUM(i);
 		// the first couple seconds of server time can involve a lot of
Index: darkplaces/server.h
diff -u darkplaces/server.h:1.30 darkplaces/server.h:1.31
--- darkplaces/server.h:1.30	Wed Aug  6 12:33:26 2003
+++ darkplaces/server.h	Fri Aug 29 21:54:31 2003
@@ -24,8 +24,10 @@
 
 typedef struct
 {
-	// NULL pointers are non-existent clients
-	struct client_s *connectedclients[MAX_SCOREBOARD];
+	// number of svs.clients slots (updated by maxplayers command)
+	int maxclients;
+	// client slots
+	struct client_s *clients;
 	// episode completion information
 	int serverflags;
 	// cleared when at SV_SpawnServer
@@ -99,6 +101,8 @@
 
 typedef struct client_s
 {
+	// false = empty client slot
+	qboolean active;
 	// false = don't send datagrams
 	qboolean spawned;
 	// has been told to go to another level
@@ -107,7 +111,7 @@
 	qboolean sendsignon;
 	// remove this client immediately
 	qboolean deadsocket;
-	// index of this client in the svs.connectedclients pointer array
+	// index of this client in the svs.clients array
 	int number;
 
 	// reliable messages must be sent periodically
@@ -247,7 +251,6 @@
 extern cvar_t sv_aim;
 extern cvar_t sv_stepheight;
 extern cvar_t sv_jumpstep;
-extern cvar_t sv_maxplayers;
 
 extern mempool_t *sv_clients_mempool;
 extern mempool_t *sv_edicts_mempool;
Index: darkplaces/sv_main.c
diff -u darkplaces/sv_main.c:1.93 darkplaces/sv_main.c:1.94
--- darkplaces/sv_main.c:1.93	Wed Aug 27 08:22:00 2003
+++ darkplaces/sv_main.c	Fri Aug 29 21:54:31 2003
@@ -32,7 +32,6 @@
 static char localmodels[MAX_MODELS][5];			// inline model names for precache
 
 mempool_t *sv_edicts_mempool = NULL;
-mempool_t *sv_clients_mempool = NULL;
 
 //============================================================================
 
@@ -71,7 +70,6 @@
 		sprintf (localmodels[i], "*%i", i);
 
 	sv_edicts_mempool = Mem_AllocPool("server edicts");
-	sv_clients_mempool = Mem_AllocPool("server clients");
 }
 
 /*
@@ -261,7 +259,7 @@
 
 	MSG_WriteByte (&client->message, svc_serverinfo);
 	MSG_WriteLong (&client->message, DPPROTOCOL_VERSION4);
-	MSG_WriteByte (&client->message, MAX_SCOREBOARD);
+	MSG_WriteByte (&client->message, svs.maxclients);
 
 	if (!coop.integer && deathmatch.integer)
 		MSG_WriteByte (&client->message, GAME_DEATHMATCH);
@@ -308,12 +306,13 @@
 	int				i;
 	float			spawn_parms[NUM_SPAWN_PARMS];
 
-	client = svs.connectedclients[clientnum];
+	client = svs.clients + clientnum;
 
 // set up the client_t
 	if (sv.loadgame)
 		memcpy (spawn_parms, client->spawn_parms, sizeof(spawn_parms));
 	memset (client, 0, sizeof(*client));
+	client->active = true;
 	client->netconnection = netconnection;
 
 	Con_DPrintf("Client %s connected\n", client->netconnection->address);
@@ -822,7 +821,7 @@
 		// we can omit invisible entities with no effects that are not clients
 		// LordHavoc: this could kill tags attached to an invisible entity, I
 		// just hope we never have to support that case
-		if (cs.number > MAX_SCOREBOARD && ((cs.effects & EF_NODRAW) || (!cs.modelindex && !cs.specialvisibilityradius)))
+		if (cs.number > svs.maxclients && ((cs.effects & EF_NODRAW) || (!cs.modelindex && !cs.specialvisibilityradius)))
 			continue;
 		sendentitiesindex[e] = sendentities + numsendentities;
 		sendentities[numsendentities++] = cs;
@@ -1345,71 +1344,67 @@
 	char *s;
 
 // check for changes to be sent over the reliable streams
-	for (i = 0;i < MAX_SCOREBOARD;i++)
+	for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
 	{
-		// only update the client fields if they've spawned in
-		if ((host_client = svs.connectedclients[i]) && host_client->spawned)
-		{
-			// update the host_client fields we care about according to the entity fields
-			sv_player = host_client->edict;
-			s = PR_GetString(sv_player->v->netname);
-			if (s != host_client->name)
-			{
-				if (s == NULL)
-					s = "";
-				// point the string back at host_client->name to keep it safe
-				strncpy(host_client->name, s, sizeof(host_client->name) - 1);
-				sv_player->v->netname = PR_SetString(host_client->name);
-			}
-			if ((val = GETEDICTFIELDVALUE(sv_player, eval_clientcolors)) && host_client->colors != val->_float)
-				host_client->colors = val->_float;
-			host_client->frags = sv_player->v->frags;
-			if (gamemode == GAME_NEHAHRA)
-				if ((val = GETEDICTFIELDVALUE(sv_player, eval_pmodel)) && host_client->pmodel != val->_float)
-					host_client->pmodel = val->_float;
+		// update the host_client fields we care about according to the entity fields
+		sv_player = host_client->edict;
+		s = PR_GetString(sv_player->v->netname);
+		if (s != host_client->name)
+		{
+			if (s == NULL)
+				s = "";
+			// point the string back at host_client->name to keep it safe
+			strncpy(host_client->name, s, sizeof(host_client->name) - 1);
+			sv_player->v->netname = PR_SetString(host_client->name);
+		}
+		if ((val = GETEDICTFIELDVALUE(sv_player, eval_clientcolors)) && host_client->colors != val->_float)
+			host_client->colors = val->_float;
+		host_client->frags = sv_player->v->frags;
+		if (gamemode == GAME_NEHAHRA)
+			if ((val = GETEDICTFIELDVALUE(sv_player, eval_pmodel)) && host_client->pmodel != val->_float)
+				host_client->pmodel = val->_float;
 
-			// if the fields changed, send messages about the changes
-			if (strcmp(host_client->old_name, host_client->name))
+		// if the fields changed, send messages about the changes
+		if (strcmp(host_client->old_name, host_client->name))
+		{
+			strcpy(host_client->old_name, host_client->name);
+			for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
 			{
-				strcpy(host_client->old_name, host_client->name);
-				for (j = 0;j < MAX_SCOREBOARD;j++)
-				{
-					if (!(client = svs.connectedclients[j]) || !client->spawned)
-						continue;
-					MSG_WriteByte (&client->message, svc_updatename);
-					MSG_WriteByte (&client->message, i);
-					MSG_WriteString (&client->message, host_client->name);
-				}
+				if (!client->spawned || !client->netconnection)
+					continue;
+				MSG_WriteByte (&client->message, svc_updatename);
+				MSG_WriteByte (&client->message, i);
+				MSG_WriteString (&client->message, host_client->name);
 			}
-			if (host_client->old_colors != host_client->colors)
+		}
+		if (host_client->old_colors != host_client->colors)
+		{
+			host_client->old_colors = host_client->colors;
+			for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
 			{
-				host_client->old_colors = host_client->colors;
-				for (j = 0;j < MAX_SCOREBOARD;j++)
-				{
-					if (!(client = svs.connectedclients[j]) || !client->spawned)
-						continue;
-					MSG_WriteByte (&client->message, svc_updatecolors);
-					MSG_WriteByte (&client->message, i);
-					MSG_WriteByte (&client->message, host_client->colors);
-				}
+				if (!client->spawned || !client->netconnection)
+					continue;
+				MSG_WriteByte (&client->message, svc_updatecolors);
+				MSG_WriteByte (&client->message, i);
+				MSG_WriteByte (&client->message, host_client->colors);
 			}
-			if (host_client->old_frags != host_client->frags)
+		}
+		if (host_client->old_frags != host_client->frags)
+		{
+			host_client->old_frags = host_client->frags;
+			for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
 			{
-				host_client->old_frags = host_client->frags;
-				for (j = 0;j < MAX_SCOREBOARD;j++)
-				{
-					if (!(client = svs.connectedclients[j]) || !client->spawned)
-						continue;
-					MSG_WriteByte (&client->message, svc_updatefrags);
-					MSG_WriteByte (&client->message, i);
-					MSG_WriteShort (&client->message, host_client->frags);
-				}
+				if (!client->spawned || !client->netconnection)
+					continue;
+				MSG_WriteByte (&client->message, svc_updatefrags);
+				MSG_WriteByte (&client->message, i);
+				MSG_WriteShort (&client->message, host_client->frags);
 			}
 		}
 	}
 
-	for (j = 0;j < MAX_SCOREBOARD;j++)
-		if ((client = svs.connectedclients[j]))
+	for (j = 0, client = svs.clients;j < svs.maxclients;j++, client++)
+		if (client->netconnection)
 			SZ_Write (&client->message, sv.reliable_datagram.data, sv.reliable_datagram.cursize);
 
 	SZ_Clear (&sv.reliable_datagram);
@@ -1453,12 +1448,17 @@
 	SV_UpdateToReliableMessages();
 
 // build individual updates
-	for (i = 0;i < MAX_SCOREBOARD;i++)
+	for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
 	{
-		if (!(host_client = svs.connectedclients[i]))
+		if (!host_client->active)
 			continue;
+		if (!host_client->netconnection)
+		{
+			SZ_Clear(&host_client->message);
+			continue;
+		}
 
-		if (host_client->deadsocket || !host_client->netconnection || host_client->message.overflowed)
+		if (host_client->deadsocket || host_client->message.overflowed)
 		{
 			SV_DropClient (true);	// if the message couldn't send, kick off
 			continue;
@@ -1565,7 +1565,7 @@
 
 		if (svent->e->free)
 			continue;
-		if (entnum > MAX_SCOREBOARD && !svent->v->modelindex)
+		if (entnum > svs.maxclients && !svent->v->modelindex)
 			continue;
 
 		// create entity baseline
@@ -1573,7 +1573,7 @@
 		VectorCopy (svent->v->angles, svent->e->baseline.angles);
 		svent->e->baseline.frame = svent->v->frame;
 		svent->e->baseline.skin = svent->v->skin;
-		if (entnum > 0 && entnum <= MAX_SCOREBOARD)
+		if (entnum > 0 && entnum <= svs.maxclients)
 		{
 			svent->e->baseline.colormap = entnum;
 			svent->e->baseline.modelindex = SV_ModelIndex("progs/player.mdl");
@@ -1656,9 +1656,9 @@
 
 	svs.serverflags = pr_global_struct->serverflags;
 
-	for (i = 0;i < MAX_SCOREBOARD;i++)
+	for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
 	{
-		if (!(host_client = svs.connectedclients[i]))
+		if (!host_client->active)
 			continue;
 
 	// call the progs to get default spawn parms for the new client
@@ -1766,7 +1766,7 @@
 
 // allocate server memory
 	// start out with just enough room for clients and a reasonable estimate of entities
-	sv.max_edicts = max(MAX_SCOREBOARD + 1, 512);
+	sv.max_edicts = max(svs.maxclients + 1, 512);
 	sv.max_edicts = min(sv.max_edicts, MAX_EDICTS);
 
 	// clear the edict memory pool
@@ -1799,7 +1799,7 @@
 	sv.signon.data = sv.signon_buf;
 
 // leave slots at start for clients only
-	sv.num_edicts = MAX_SCOREBOARD+1;
+	sv.num_edicts = svs.maxclients+1;
 
 	sv.state = ss_loading;
 	sv.paused = false;
@@ -1892,8 +1892,8 @@
 #endif
 
 // send serverinfo to all connected clients
-	for (i = 0;i < MAX_SCOREBOARD;i++)
-		if ((host_client = svs.connectedclients[i]))
+	for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
+		if (host_client->netconnection)
 			SV_SendServerinfo(host_client);
 
 	Con_DPrintf ("Server spawned.\n");
Index: darkplaces/sv_phys.c
diff -u darkplaces/sv_phys.c:1.59 darkplaces/sv_phys.c:1.60
--- darkplaces/sv_phys.c:1.59	Wed Aug 27 08:22:00 2003
+++ darkplaces/sv_phys.c	Fri Aug 29 21:54:31 2003
@@ -1314,9 +1314,9 @@
 		if (pr_global_struct->force_retouch)
 			SV_LinkEdict (ent, true);	// force retouch even for stationary
 
-		if (i > 0 && i <= MAX_SCOREBOARD)
+		if (i > 0 && i <= svs.maxclients)
 		{
-			if (!svs.connectedclients[i-1] || !svs.connectedclients[i-1]->spawned)
+			if (!svs.clients[i-1].spawned)
 				continue;
 			// connected slot
 			// call standard client pre-think
@@ -1349,7 +1349,7 @@
 				VectorMA(ent->v->angles, sv.frametime, ent->v->avelocity, ent->v->angles);
 			}
 			// relink normal entities here, players always get relinked so don't relink twice
-			if (!(i > 0 && i <= MAX_SCOREBOARD))
+			if (!(i > 0 && i <= svs.maxclients))
 				SV_LinkEdict(ent, false);
 			break;
 		case MOVETYPE_STEP:
@@ -1372,7 +1372,7 @@
 			SV_Physics_Toss (ent);
 			break;
 		case MOVETYPE_FLY:
-			if (i > 0 && i <= MAX_SCOREBOARD)
+			if (i > 0 && i <= svs.maxclients)
 			{
 				if (SV_RunThink (ent))
 				{
@@ -1388,7 +1388,7 @@
 			break;
 		}
 
-		if (i > 0 && i <= MAX_SCOREBOARD && !ent->e->free)
+		if (i > 0 && i <= svs.maxclients && !ent->e->free)
 		{
 			SV_CheckVelocity (ent);
 
Index: darkplaces/sv_user.c
diff -u darkplaces/sv_user.c:1.38 darkplaces/sv_user.c:1.39
--- darkplaces/sv_user.c:1.38	Mon Aug 18 20:25:08 2003
+++ darkplaces/sv_user.c	Fri Aug 29 21:54:31 2003
@@ -665,14 +665,14 @@
 extern void SV_SendServerinfo(client_t *client);
 void SV_ReadClientMessage(void)
 {
-	int cmd, clientnum = host_client->number;
+	int cmd;
 	char *s;
 
 	//MSG_BeginReading ();
 
 	for(;;)
 	{
-		if (!(host_client = svs.connectedclients[clientnum]))
+		if (!host_client->active)
 		{
 			// a command caused an error
 			SV_DropClient (false);
@@ -761,13 +761,11 @@
 {
 	int i;
 
-	for (i = 0;i < MAX_SCOREBOARD;i++)
+	for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
 	{
-		if (!(host_client = svs.connectedclients[i]))
+		if (!host_client->active)
 			continue;
 
-		sv_player = host_client->edict;
-
 		if (!host_client->spawned)
 		{
 			// clear client movement until a new packet is received
@@ -777,6 +775,8 @@
 
 		if (sv.frametime)
 		{
+			sv_player = host_client->edict;
+
 			// LordHavoc: QuakeC replacement for SV_ClientThink (player movement)
 			if (SV_PlayerPhysicsQC)
 			{
Index: darkplaces/todo
diff -u darkplaces/todo:1.34 darkplaces/todo:1.35
--- darkplaces/todo:1.34	Thu Aug 28 23:49:00 2003
+++ darkplaces/todo	Fri Aug 29 21:54:31 2003
@@ -4,6 +4,7 @@
 -n darkplaces: make LHNET_Read print out the names of read errors (yummyluv)
 -n darkplaces: revert noclip movement to match nq for compatibility with mods that trap movement as input (MauveBib)
 -n dpmod: make grapple off-hand (joe hill)
+0 darkplaces: clean up the DrawQ_ blendfunc handling, instead of taking DRAWFLAG_ADDITIVE they should take blendfunc values (Black)
 0 darkplaces: ability to disable fopen builtin access to read /, read data/, write data/, or disable fopen builtin entirely
 0 darkplaces: add DP_GFX_QUAKE3MODELTAGS, DP_GFX_SKINFILES, and any other new extensions to the wiki
 0 darkplaces: add DP_LITSUPPORT extension