(svn r6814) -Codechange: For network games ci->client_playas was always p->index + 1. To
authorDarkvater
Tue, 17 Oct 2006 22:16:46 +0000
changeset 4878 744717de172e
parent 4877 d4c365e0d2b6
child 4879 befa9bc9ccc5
(svn r6814) -Codechange: For network games ci->client_playas was always p->index + 1. To
correctly handle this ci->client_playas - 1 was used all over the code making
it pretty confusing at times. Use proper one-on-one values now. Special handling
is only needed for user-output to not to confuse users.
console_cmds.c
economy.c
network.c
network_client.c
network_gui.c
network_server.c
network_udp.c
openttd.c
player.h
players.c
--- a/console_cmds.c	Tue Oct 17 20:36:03 2006 +0000
+++ b/console_cmds.c	Tue Oct 17 22:16:46 2006 +0000
@@ -551,7 +551,9 @@
 
 		status = (cs->status < lengthof(stat_str) ? stat_str[cs->status] : "unknown");
 		IConsolePrintF(8, "Client #%1d  name: '%s'  status: '%s'  frame-lag: %3d  company: %1d  IP: %s  unique-id: '%s'",
-			cs->index, ci->client_name, status, lag, ci->client_playas, GetPlayerIP(ci), ci->unique_id);
+			cs->index, ci->client_name, status, lag,
+			ci->client_playas + (IsValidPlayer(ci->client_playas) ? 1 : 0),
+			GetPlayerIP(ci), ci->unique_id);
 	}
 
 	return true;
@@ -669,16 +671,15 @@
 
 	if (argc != 2) return false;
 
-	index = atoi(argv[1]);
+	index = atoi(argv[1]) - 1;
 
 	/* Check valid range */
-	if (index < 1 || index > MAX_PLAYERS) {
+	if (!IsValidPlayer(index)) {
 		IConsolePrintF(_icolour_err, "Company does not exist. Company-id must be between 1 and %d.", MAX_PLAYERS);
 		return true;
 	}
 
 	/* Check if company does exist */
-	index--;
 	p = GetPlayer(index);
 	if (!p->is_active) {
 		IConsoleError("Company does not exist.");
@@ -693,13 +694,13 @@
 	/* Check if the company has active players */
 	FOR_ALL_CLIENTS(cs) {
 		ci = DEREF_CLIENT_INFO(cs);
-		if (ci->client_playas - 1 == index) {
+		if (ci->client_playas == index) {
 			IConsoleError("Cannot remove company: a client is connected to that company.");
 			return true;
 		}
 	}
 	ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
-	if (ci->client_playas - 1 == index) {
+	if (ci->client_playas == index) {
 		IConsoleError("Cannot remove company: the server is connected to that company.");
 		return true;
 	}
@@ -723,7 +724,9 @@
 	for (ci = _network_client_info; ci != &_network_client_info[MAX_CLIENT_INFO]; ci++) {
 		if (ci->client_index != NETWORK_EMPTY_INDEX) {
 			IConsolePrintF(8, "Client #%1d  name: '%s'  company: %1d  IP: %s",
-				ci->client_index, ci->client_name, ci->client_playas, GetPlayerIP(ci));
+			               ci->client_index, ci->client_name,
+			               ci->client_playas + (IsValidPlayer(ci->client_playas) ? 1 : 0),
+			               GetPlayerIP(ci));
 		}
 	}
 
@@ -740,7 +743,7 @@
 	if (argc == 0) {
 		IConsoleHelp("Connect to a remote OTTD server and join the game. Usage: 'connect <ip>'");
 		IConsoleHelp("IP can contain port and player: 'IP[[#Player]:Port]', eg: 'server.ottd.org#2:443'");
-		IConsoleHelp("Player #0 is new company, #255 is spectator all others are a certain company");
+		IConsoleHelp("Player #255 is spectator all others are a certain company with Company 1 being #1");
 		return true;
 	}
 
@@ -763,11 +766,9 @@
 
 		/* From a user pov 0 is a new player, internally it's different and all
 		 * players are offset by one to ease up on users (eg players 1-8 not 0-7) */
-		if (_network_playas == 0) _network_playas = PLAYER_NEW_COMPANY;
-		if (!IsValidPlayer(_network_playas - 1) &&
-			  (_network_playas != PLAYER_SPECTATOR &&
-			   _network_playas != PLAYER_NEW_COMPANY)) {
-			return false;
+		if (_network_playas != PLAYER_SPECTATOR) {
+			_network_playas--;
+			if (!IsValidPlayer(_network_playas)) return false;
 		}
 	}
 	if (port != NULL) {
--- a/economy.c	Tue Oct 17 20:36:03 2006 +0000
+++ b/economy.c	Tue Oct 17 22:16:46 2006 +0000
@@ -428,7 +428,7 @@
 					/* Find all clients that were in control of this company */
 					FOR_ALL_CLIENTS(cs) {
 						ci = DEREF_CLIENT_INFO(cs);
-						if ((ci->client_playas-1) == owner) {
+						if (ci->client_playas == owner) {
 							ci->client_playas = PLAYER_SPECTATOR;
 							// Send the new info to all the clients
 							NetworkUpdateClientInfo(_network_own_client_index);
--- a/network.c	Tue Oct 17 20:36:03 2006 +0000
+++ b/network.c	Tue Oct 17 22:16:46 2006 +0000
@@ -294,7 +294,7 @@
 
 	FOR_ALL_CLIENTS(cs) {
 		NetworkClientInfo *ci = DEREF_CLIENT_INFO(cs);
-		if (ci->client_playas > 0 && ci->client_playas <= MAX_PLAYERS) count++;
+		if (IsValidPlayer(ci->client_playas)) count++;
 	}
 
 	return count;
@@ -575,6 +575,7 @@
 
 		cs->index = _network_client_index++;
 		ci->client_index = cs->index;
+		ci->client_playas = PLAYER_INACTIVE_CLIENT;
 		ci->join_date = _date;
 
 		InvalidateWindow(WC_CLIENT_LIST, 0);
@@ -1034,11 +1035,8 @@
 	memset(ci, 0, sizeof(*ci));
 
 	ci->client_index = NETWORK_SERVER_INDEX;
-	if (_network_dedicated) {
-		ci->client_playas = PLAYER_SPECTATOR;
-	} else {
-		ci->client_playas = _local_player + 1;
-	}
+	ci->client_playas = _network_dedicated ? PLAYER_SPECTATOR : _local_player;
+
 	ttd_strlcpy(ci->client_name, _network_player_name, sizeof(ci->client_name));
 	ttd_strlcpy(ci->unique_id, _network_unique_id, sizeof(ci->unique_id));
 }
@@ -1067,8 +1065,8 @@
 	_last_sync_frame = 0;
 	_network_own_client_index = NETWORK_SERVER_INDEX;
 
-	if (!_network_dedicated)
-		_network_playas = 1;
+	/* Non-dedicated server will always be player #1 */
+	if (!_network_dedicated) _network_playas = 0;
 
 	_network_clients_connected = 0;
 
--- a/network_client.c	Tue Oct 17 20:36:03 2006 +0000
+++ b/network_client.c	Tue Oct 17 22:16:46 2006 +0000
@@ -512,8 +512,8 @@
 		SEND_COMMAND(PACKET_CLIENT_MAP_OK)();
 
 		// new company/spectator (invalid player) or company we want to join is not active
-		if (_network_playas == PLAYER_NEW_COMPANY || !IsValidPlayer(_network_playas - 1) ||
-				!GetPlayer(_network_playas - 1)->is_active) {
+		if (_network_playas == PLAYER_NEW_COMPANY || !IsValidPlayer(_network_playas) ||
+				!GetPlayer(_network_playas)->is_active) {
 
 			if (_network_playas == PLAYER_SPECTATOR) {
 				// The client wants to be a spectator..
@@ -527,7 +527,7 @@
 			}
 		} else {
 			// take control over an existing company
-			_local_player = _network_playas - 1;
+			_local_player = _network_playas;
 			_patches.autorenew = GetPlayer(_local_player)->engine_renew;
 			_patches.autorenew_months = GetPlayer(_local_player)->engine_renew_months;
 			_patches.autorenew_money = GetPlayer(_local_player)->engine_renew_money;
@@ -631,10 +631,10 @@
 				break;
 			case NETWORK_ACTION_CHAT_PLAYER:
 			case NETWORK_ACTION_GIVE_MONEY:
-				/* For speak to player or give money, we need the player-name */
-				if (ci_to->client_playas > MAX_PLAYERS)
-					return NETWORK_RECV_STATUS_OKAY; // This should never happen
-				GetString(name, GetPlayer(ci_to->client_playas-1)->name_1);
+				/* For speaking to player or give money, we need the player-name */
+				if (!IsValidPlayer(ci_to->client_playas)) return NETWORK_RECV_STATUS_OKAY; // This should never happen
+
+				GetString(name, GetPlayer(ci_to->client_playas)->name_1);
 				ci = NetworkFindClientInfoFromIndex(_network_own_client_index);
 				break;
 			default:
@@ -649,7 +649,7 @@
 	}
 
 	if (ci != NULL)
-		NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas-1), self_send, name, "%s", msg);
+		NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas), self_send, name, "%s", msg);
 	return NETWORK_RECV_STATUS_OKAY;
 }
 
--- a/network_gui.c	Tue Oct 17 20:36:03 2006 +0000
+++ b/network_gui.c	Tue Oct 17 22:16:46 2006 +0000
@@ -924,7 +924,7 @@
 		}	break;
 		case 7: /* Join company */
 			if (nd->company != (byte)-1) {
-				_network_playas = nd->company + 1;
+				_network_playas = nd->company;
 				NetworkClientConnectGame(_network_last_host, _network_last_port);
 			}
 			break;
@@ -1084,7 +1084,7 @@
 static void ClientList_GiveMoney(byte client_no)
 {
 	if (NetworkFindClientInfo(client_no) != NULL)
-		ShowNetworkGiveMoneyWindow(NetworkFindClientInfo(client_no)->client_playas - 1);
+		ShowNetworkGiveMoneyWindow(NetworkFindClientInfo(client_no)->client_playas);
 }
 
 static void ClientList_SpeakToClient(byte client_no)
@@ -1187,7 +1187,7 @@
 		_clientlist_proc[i++] = &ClientList_SpeakToClient;
 	}
 
-	if (ci->client_playas >= 1 && ci->client_playas <= MAX_PLAYERS) {
+	if (IsValidPlayer(ci->client_playas)) {
 		GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_SPEAK_TO_COMPANY);
 		_clientlist_proc[i++] = &ClientList_SpeakToPlayer;
 	}
@@ -1195,12 +1195,10 @@
 	_clientlist_proc[i++] = &ClientList_SpeakToAll;
 
 	if (_network_own_client_index != ci->client_index) {
-		if (IsValidPlayer(_network_playas - 1)) {
-			// We are no spectator
-			if (ci->client_playas >= 1 && ci->client_playas <= MAX_PLAYERS) {
-				GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_GIVE_MONEY);
-				_clientlist_proc[i++] = &ClientList_GiveMoney;
-			}
+		/* We are no spectator and the player we want to give money to is no spectator */
+		if (IsValidPlayer(_network_playas) && IsValidPlayer(ci->client_playas)) {
+			GetString(_clientlist_action[i], STR_NETWORK_CLIENTLIST_GIVE_MONEY);
+			_clientlist_proc[i++] = &ClientList_GiveMoney;
 		}
 	}
 
@@ -1328,8 +1326,7 @@
 			}
 
 			// Filter out spectators
-			if (ci->client_playas > 0 && ci->client_playas <= MAX_PLAYERS)
-				DrawPlayerIcon(ci->client_playas - 1, 64, y + 1);
+			if (IsValidPlayer(ci->client_playas)) DrawPlayerIcon(ci->client_playas, 64, y + 1);
 
 			DoDrawString(ci->client_name, 81, y, colour);
 
--- a/network_server.c	Tue Oct 17 20:36:03 2006 +0000
+++ b/network_server.c	Tue Oct 17 22:16:46 2006 +0000
@@ -608,8 +608,8 @@
 				return;
 			}
 			break;
-		default: /* Join another company (companies 1-8) */
-			if (!IsValidPlayer(playas - 1)) {
+		default: /* Join another company (companies 1-8 (index 0-7)) */
+			if (!IsValidPlayer(playas)) {
 				SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_PLAYER_MISMATCH);
 				return;
 			}
@@ -637,17 +637,15 @@
 	if (_network_game_info.use_password) {
 		SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_GAME_PASSWORD);
 	} else {
-		if (ci->client_playas > 0 && ci->client_playas <= MAX_PLAYERS && _network_player_info[ci->client_playas - 1].password[0] != '\0') {
+		if (IsValidPlayer(ci->client_playas) && _network_player_info[ci->client_playas].password[0] != '\0') {
 			SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_COMPANY_PASSWORD);
 		} else {
 			SEND_COMMAND(PACKET_SERVER_WELCOME)(cs);
 		}
 	}
 
-	/* Make sure companies to who people try to join are not autocleaned */
-	if (playas >= 1 && playas <= MAX_PLAYERS) {
-		_network_player_info[playas-1].months_empty = 0;
-	}
+	/* Make sure companies to which people try to join are not autocleaned */
+	if (IsValidPlayer(playas)) _network_player_info[playas].months_empty = 0;
 }
 
 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_PASSWORD)
@@ -669,7 +667,7 @@
 
 		ci = DEREF_CLIENT_INFO(cs);
 
-		if (ci->client_playas <= MAX_PLAYERS && _network_player_info[ci->client_playas - 1].password[0] != '\0') {
+		if (IsValidPlayer(ci->client_playas) && _network_player_info[ci->client_playas].password[0] != '\0') {
 			SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_COMPANY_PASSWORD);
 			return;
 		}
@@ -680,7 +678,7 @@
 	} else if (cs->status == STATUS_INACTIVE && type == NETWORK_COMPANY_PASSWORD) {
 		ci = DEREF_CLIENT_INFO(cs);
 
-		if (strcmp(password, _network_player_info[ci->client_playas - 1].password) != 0) {
+		if (strcmp(password, _network_player_info[ci->client_playas].password) != 0) {
 			// Password is invalid
 			SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_PASSWORD);
 			return;
@@ -772,12 +770,12 @@
 	byte flags = GetCommandFlags(cp->cmd);
 
 	if (flags & CMD_SERVER && ci->client_index != NETWORK_SERVER_INDEX) {
-		IConsolePrintF(_icolour_err, "WARNING: server only command from player %d (IP: %s), kicking...", ci->client_playas, GetPlayerIP(ci));
+		IConsolePrintF(_icolour_err, "WARNING: server only command from client %d (IP: %s), kicking...", ci->client_index, GetPlayerIP(ci));
 		return false;
 	}
 
 	if (flags & CMD_OFFLINE) {
-		IConsolePrintF(_icolour_err, "WARNING: offline only command from player %d (IP: %s), kicking...", ci->client_playas, GetPlayerIP(ci));
+		IConsolePrintF(_icolour_err, "WARNING: offline only command from client %d (IP: %s), kicking...", ci->client_index, GetPlayerIP(ci));
 		return false;
 	}
 	return true;
@@ -817,7 +815,7 @@
 
 	/* Check if cp->cmd is valid */
 	if (!IsValidCommand(cp->cmd)) {
-		IConsolePrintF(_icolour_err, "WARNING: invalid command from player %d (IP: %s).", ci->client_playas, GetPlayerIP(ci));
+		IConsolePrintF(_icolour_err, "WARNING: invalid command from client %d (IP: %s).", ci->client_index, GetPlayerIP(ci));
 		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED);
 		return;
 	}
@@ -831,9 +829,9 @@
 	 * to match the player in the packet. If it doesn't, the client has done
 	 * something pretty naughty (or a bug), and will be kicked
 	 */
-	if (!(cp->cmd == CMD_PLAYER_CTRL && cp->p1 == 0) && ci->client_playas - 1 != cp->player) {
+	if (!(cp->cmd == CMD_PLAYER_CTRL && cp->p1 == 0) && ci->client_playas != cp->player) {
 		IConsolePrintF(_icolour_err, "WARNING: player %d (IP: %s) tried to execute a command as player %d, kicking...",
-									 ci->client_playas - 1, GetPlayerIP(ci), cp->player);
+		               ci->client_playas + 1, GetPlayerIP(ci), cp->player + 1);
 		SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_PLAYER_MISMATCH);
 		return;
 	}
@@ -987,7 +985,7 @@
 			ci = NetworkFindClientInfoFromIndex(from_index);
 			/* Display the text locally, and that is it */
 			if (ci != NULL)
-				NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas-1), false, ci->client_name, "%s", msg);
+				NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas), false, ci->client_name, "%s", msg);
 		} else {
 			/* Else find the client to send the message to */
 			FOR_ALL_CLIENTS(cs) {
@@ -1004,7 +1002,7 @@
 				ci = NetworkFindClientInfoFromIndex(from_index);
 				ci_to = NetworkFindClientInfoFromIndex(dest);
 				if (ci != NULL && ci_to != NULL)
-					NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas-1), true, ci_to->client_name, "%s", msg);
+					NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas), true, ci_to->client_name, "%s", msg);
 			} else {
 				FOR_ALL_CLIENTS(cs) {
 					if (cs->index == from_index) {
@@ -1034,7 +1032,7 @@
 		ci = NetworkFindClientInfoFromIndex(from_index);
 		ci_own = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
 		if (ci != NULL && ci_own != NULL && ci_own->client_playas == dest) {
-			NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas-1), false, ci->client_name, "%s", msg);
+			NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas), false, ci->client_name, "%s", msg);
 			if (from_index == NETWORK_SERVER_INDEX)
 				show_local = false;
 			ci_to = ci_own;
@@ -1047,8 +1045,8 @@
 		if (ci != NULL && show_local) {
 			if (from_index == NETWORK_SERVER_INDEX) {
 				char name[NETWORK_NAME_LENGTH];
-				GetString(name, GetPlayer(ci_to->client_playas-1)->name_1);
-				NetworkTextMessage(action, GetDrawStringPlayerColor(ci_own->client_playas-1), true, name, "%s", msg);
+				GetString(name, GetPlayer(ci_to->client_playas)->name_1);
+				NetworkTextMessage(action, GetDrawStringPlayerColor(ci_own->client_playas), true, name, "%s", msg);
 			} else {
 				FOR_ALL_CLIENTS(cs) {
 					if (cs->index == from_index) {
@@ -1068,7 +1066,7 @@
 		}
 		ci = NetworkFindClientInfoFromIndex(from_index);
 		if (ci != NULL)
-			NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas-1), false, ci->client_name, "%s", msg);
+			NetworkTextMessage(action, GetDrawStringPlayerColor(ci->client_playas), false, ci->client_name, "%s", msg);
 		break;
 	}
 }
@@ -1093,8 +1091,8 @@
 	NetworkRecv_string(cs, p, password, sizeof(password));
 	ci = DEREF_CLIENT_INFO(cs);
 
-	if (ci->client_playas <= MAX_PLAYERS) {
-		ttd_strlcpy(_network_player_info[ci->client_playas - 1].password, password, sizeof(_network_player_info[ci->client_playas - 1].password));
+	if (IsValidPlayer(ci->client_playas)) {
+		ttd_strlcpy(_network_player_info[ci->client_playas].password, password, sizeof(_network_player_info[0].password));
 	}
 }
 
@@ -1286,8 +1284,8 @@
 
 	ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
 	// Register local player (if not dedicated)
-	if (ci != NULL && ci->client_playas > 0  && ci->client_playas <= MAX_PLAYERS)
-		ttd_strlcpy(_network_player_info[ci->client_playas-1].players, ci->client_name, sizeof(_network_player_info[ci->client_playas-1].players));
+	if (ci != NULL && IsValidPlayer(ci->client_playas))
+		ttd_strlcpy(_network_player_info[ci->client_playas].players, ci->client_name, sizeof(_network_player_info[0].players));
 
 	FOR_ALL_CLIENTS(cs) {
 		char client_name[NETWORK_CLIENT_NAME_LENGTH];
@@ -1295,11 +1293,11 @@
 		NetworkGetClientName(client_name, sizeof(client_name), cs);
 
 		ci = DEREF_CLIENT_INFO(cs);
-		if (ci != NULL && ci->client_playas > 0 && ci->client_playas <= MAX_PLAYERS) {
-			if (strlen(_network_player_info[ci->client_playas-1].players) != 0)
-				ttd_strlcat(_network_player_info[ci->client_playas - 1].players, ", ", lengthof(_network_player_info[ci->client_playas - 1].players));
+		if (ci != NULL && IsValidPlayer(ci->client_playas)) {
+			if (strlen(_network_player_info[ci->client_playas].players) != 0)
+				ttd_strlcat(_network_player_info[ci->client_playas].players, ", ", lengthof(_network_player_info[0].players));
 
-			ttd_strlcat(_network_player_info[ci->client_playas - 1].players, client_name, lengthof(_network_player_info[ci->client_playas - 1].players));
+			ttd_strlcat(_network_player_info[ci->client_playas].players, client_name, lengthof(_network_player_info[0].players));
 		}
 	}
 }
@@ -1348,15 +1346,11 @@
 	/* Detect the active companies */
 	FOR_ALL_CLIENTS(cs) {
 		ci = DEREF_CLIENT_INFO(cs);
-		if (ci->client_playas >= 1 && ci->client_playas <= MAX_PLAYERS) {
-			clients_in_company[ci->client_playas-1] = true;
-		}
+		if (IsValidPlayer(ci->client_playas)) clients_in_company[ci->client_playas] = true;
 	}
 	if (!_network_dedicated) {
 		ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
-		if (ci->client_playas >= 1 && ci->client_playas <= MAX_PLAYERS) {
-			clients_in_company[ci->client_playas-1] = true;
-		}
+		if (IsValidPlayer(ci->client_playas)) clients_in_company[ci->client_playas] = true;
 	}
 
 	/* Go through all the comapnies */
--- a/network_udp.c	Tue Oct 17 20:36:03 2006 +0000
+++ b/network_udp.c	Tue Oct 17 22:16:46 2006 +0000
@@ -214,7 +214,7 @@
 		/* Find the clients that are connected to this player */
 		FOR_ALL_CLIENTS(cs) {
 			ci = DEREF_CLIENT_INFO(cs);
-			if (ci->client_playas - 1 == player->index) {
+			if (ci->client_playas == player->index) {
 				/* The uint8 == 1 indicates that a client is following */
 				NetworkSend_uint8(packet, 1);
 				NetworkSend_string(packet, ci->client_name);
@@ -224,7 +224,7 @@
 		}
 		/* Also check for the server itself */
 		ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
-		if (ci->client_playas - 1 == player->index) {
+		if (ci->client_playas == player->index) {
 			/* The uint8 == 1 indicates that a client is following */
 			NetworkSend_uint8(packet, 1);
 			NetworkSend_string(packet, ci->client_name);
@@ -239,7 +239,7 @@
 	/* And check if we have any spectators */
 	FOR_ALL_CLIENTS(cs) {
 		ci = DEREF_CLIENT_INFO(cs);
-		if (ci->client_playas - 1 > MAX_PLAYERS) {
+		if (!IsValidPlayer(ci->client_playas)) {
 			/* The uint8 == 1 indicates that a client is following */
 			NetworkSend_uint8(packet, 1);
 			NetworkSend_string(packet, ci->client_name);
@@ -249,7 +249,7 @@
 	}
 	/* Also check for the server itself */
 	ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
-	if (ci->client_playas - 1 > MAX_PLAYERS) {
+	if (!IsValidPlayer(ci->client_playas)) {
 		/* The uint8 == 1 indicates that a client is following */
 		NetworkSend_uint8(packet, 1);
 		NetworkSend_string(packet, ci->client_name);
--- a/openttd.c	Tue Oct 17 20:36:03 2006 +0000
+++ b/openttd.c	Tue Oct 17 22:16:46 2006 +0000
@@ -477,12 +477,17 @@
 			uint16 rport;
 
 			rport = NETWORK_DEFAULT_PORT;
+			_network_playas = PLAYER_NEW_COMPANY;
 
 			ParseConnectionString(&player, &port, network_conn);
 
 			if (player != NULL) {
 				_network_playas = atoi(player);
-				if (_network_playas == 0) _network_playas = PLAYER_NEW_COMPANY;
+
+		    if (_network_playas != PLAYER_SPECTATOR) {
+				  _network_playas--;
+					if (!IsValidPlayer(_network_playas)) return false;
+				}
 			}
 			if (port != NULL) rport = atoi(port);
 
--- a/player.h	Tue Oct 17 20:36:03 2006 +0000
+++ b/player.h	Tue Oct 17 22:16:46 2006 +0000
@@ -214,6 +214,7 @@
 /* Player identifiers All players below MAX_PLAYERS are playable
  * players, above, they are special, computer controlled players */
 enum Players {
+	PLAYER_INACTIVE_CLIENT = 253,
 	PLAYER_NEW_COMPANY = 254, ///< Command 'player' in Multiplayer to create a new company
 	PLAYER_SPECTATOR   = 255, ///< Spectator in Multiplayer or the player in the scenario editor
 	MAX_PLAYERS        = 8,
--- a/players.c	Tue Oct 17 20:36:03 2006 +0000
+++ b/players.c	Tue Oct 17 22:16:46 2006 +0000
@@ -854,10 +854,10 @@
 				 * server-side in network_server.c:838, function
 				 * DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND) */
 				NetworkClientInfo *ci = &_network_client_info[cid];
-				ci->client_playas = p->index + 1;
+				ci->client_playas = p->index;
 				NetworkUpdateClientInfo(ci->client_index);
 
-				if (ci->client_playas != 0 && ci->client_playas <= MAX_PLAYERS) {
+				if (IsValidPlayer(ci->client_playas)) {
 					PlayerID player_backup = _local_player;
 					_network_player_info[p->index].months_empty = 0;
 
@@ -873,7 +873,7 @@
 					 * with joining to let it send itself the command, and not the server?
 					 * For example in network_client.c:534? */
 					_cmd_text = ci->client_name;
-					_local_player = ci->client_playas - 1;
+					_local_player = ci->client_playas;
 					NetworkSend_Command(0, 0, 0, CMD_CHANGE_PRESIDENT_NAME, NULL);
 					_local_player = player_backup;
 				}