--- a/economy.c Sat Dec 30 23:14:39 2006 +0000
+++ b/economy.c Sat Dec 30 23:20:00 2006 +0000
@@ -420,7 +420,8 @@
p->bankrupt_timeout = 0x456;
break;
} else if (owner == _local_player) {
- _local_player = _network_playas = PLAYER_SPECTATOR;
+ _network_playas = PLAYER_SPECTATOR;
+ SetLocalPlayer(PLAYER_SPECTATOR);
}
#ifdef ENABLE_NETWORK
--- a/genworld.c Sat Dec 30 23:14:39 2006 +0000
+++ b/genworld.c Sat Dec 30 23:20:00 2006 +0000
@@ -133,7 +133,7 @@
}
ResetObjectToPlace();
- _local_player = _gw.lp;
+ SetLocalPlayer(_gw.lp);
SetGeneratingWorldProgress(GWP_GAME_START, 1);
/* Call any callback */
@@ -249,7 +249,7 @@
_gw.threaded = true;
/* This disables some commands and stuff */
- _local_player = PLAYER_SPECTATOR;
+ SetLocalPlayer(PLAYER_SPECTATOR);
/* Make sure everything is done via OWNER_NONE */
_current_player = OWNER_NONE;
--- a/misc_gui.c Sat Dec 30 23:14:39 2006 +0000
+++ b/misc_gui.c Sat Dec 30 23:20:00 2006 +0000
@@ -1647,7 +1647,8 @@
{
while (IsValidPlayer((PlayerID)p1)) {
if (_players[p1].is_active) {
- _local_player = (PlayerID)p1;
+ SetLocalPlayer((PlayerID)p1);
+
MarkWholeScreenDirty();
return _local_player;
}
--- a/network_client.c Sat Dec 30 23:14:39 2006 +0000
+++ b/network_client.c Sat Dec 30 23:20:00 2006 +0000
@@ -509,7 +509,7 @@
if (_network_playas == PLAYER_NEW_COMPANY || !IsValidPlayer(_network_playas) ||
!GetPlayer(_network_playas)->is_active) {
- _local_player = PLAYER_SPECTATOR;
+ SetLocalPlayer(PLAYER_SPECTATOR);
if (_network_playas == PLAYER_SPECTATOR) {
// The client wants to be a spectator..
@@ -521,10 +521,7 @@
}
} else {
// take control over an existing company
- _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;
+ SetLocalPlayer(_network_playas);
DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
}
}
--- a/network_server.c Sat Dec 30 23:14:39 2006 +0000
+++ b/network_server.c Sat Dec 30 23:20:00 2006 +0000
@@ -862,7 +862,7 @@
// Queue the command for the clients (are send at the end of the frame
// if they can handle it ;))
FOR_ALL_CLIENTS(new_cs) {
- if (new_cs->status > STATUS_AUTH) {
+ if (new_cs->status >= STATUS_MAP) {
// Callbacks are only send back to the client who sent them in the
// first place. This filters that out.
cp->callback = (new_cs != cs) ? 0 : callback;
--- a/openttd.c Sat Dec 30 23:14:39 2006 +0000
+++ b/openttd.c Sat Dec 30 23:20:00 2006 +0000
@@ -301,7 +301,7 @@
}
_pause = 0;
- _local_player = 0;
+ SetLocalPlayer(0);
/* Make sure you can't scroll in the menu */
_scrolling_viewport = 0;
_cursor.fix_at = false;
@@ -595,14 +595,14 @@
{
/* In a dedicated server, the server does not play */
if (_network_dedicated) {
- _local_player = PLAYER_SPECTATOR;
+ SetLocalPlayer(PLAYER_SPECTATOR);
return;
}
/* Create a single player */
DoStartupNewPlayer(false);
- _local_player = 0;
+ SetLocalPlayer(0);
_current_player = _local_player;
DoCommandP(0, (_patches.autorenew << 15 ) | (_patches.autorenew_months << 16) | 4, _patches.autorenew_money, NULL, CMD_SET_AUTOREPLACE);
@@ -623,7 +623,7 @@
static void MakeNewEditorWorldDone(void)
{
- _local_player = OWNER_NONE;
+ SetLocalPlayer(OWNER_NONE);
MarkWholeScreenDirty();
}
@@ -682,7 +682,7 @@
StartupEngines();
StartupDisasters();
- _local_player = 0;
+ SetLocalPlayer(0);
_current_player = _local_player;
DoCommandP(0, (_patches.autorenew << 15 ) | (_patches.autorenew_months << 16) | 4, _patches.autorenew_money, NULL, CMD_SET_AUTOREPLACE);
@@ -773,7 +773,7 @@
} else {
/* Update the local player for a loaded game. It is either always
* player #1 (eg 0) or in the case of a dedicated server a spectator */
- _local_player = _network_dedicated ? PLAYER_SPECTATOR : 0;
+ SetLocalPlayer(_network_dedicated ? PLAYER_SPECTATOR : 0);
DoCommandP(0, 0, 0, NULL, CMD_PAUSE); // decrease pause counter (was increased from opening load dialog)
#ifdef ENABLE_NETWORK
if (_network_server) {
@@ -794,7 +794,7 @@
break;
case SM_LOAD_HEIGHTMAP: /* Load heightmap from scenario editor */
- _local_player = OWNER_NONE;
+ SetLocalPlayer(OWNER_NONE);
GenerateWorld(GW_HEIGHTMAP, 1 << _patches.map_x, 1 << _patches.map_y);
MarkWholeScreenDirty();
@@ -806,7 +806,7 @@
_opt_ptr = &_opt;
- _local_player = OWNER_NONE;
+ SetLocalPlayer(OWNER_NONE);
_generating_world = true;
/* Delete all players */
FOR_ALL_PLAYERS(p) {
@@ -838,7 +838,7 @@
break;
case SM_GENRANDLAND: /* Generate random land within scenario editor */
- _local_player = OWNER_NONE;
+ SetLocalPlayer(OWNER_NONE);
GenerateWorld(GW_RANDOM, 1 << _patches.map_x, 1 << _patches.map_y);
// XXX: set date
MarkWholeScreenDirty();
@@ -1275,18 +1275,23 @@
* of course, we do need to initialize them for older savegames. */
if (CheckSavegameVersion(16)) {
FOR_ALL_PLAYERS(p) {
- p->engine_renew_list = NULL;
- p->engine_renew = false;
+ p->engine_renew_list = NULL;
+ p->engine_renew = false;
p->engine_renew_months = -6;
- p->engine_renew_money = 100000;
+ p->engine_renew_money = 100000;
}
- if (IsValidPlayer(_local_player)) {
- // Set the human controlled player to the patch settings
- // Scenario editor do not have any companies
- p = GetPlayer(_local_player);
- p->engine_renew = _patches.autorenew;
+
+ /* When loading a game, _local_player is not yet set to the correct value.
+ * However, in a dedicated server we are a spectator, so nothing needs to
+ * happen. In case we are not a dedicated server, the local player always
+ * becomes player 0, unless we are in the scenario editor where all the
+ * players are 'invalid'.
+ */
+ if (!_network_dedicated && IsValidPlayer(0)) {
+ p = GetPlayer(0);
+ p->engine_renew = _patches.autorenew;
p->engine_renew_months = _patches.autorenew_months;
- p->engine_renew_money = _patches.autorenew_money;
+ p->engine_renew_money = _patches.autorenew_money;
}
}
--- a/player.h Sat Dec 30 23:14:39 2006 +0000
+++ b/player.h Sat Dec 30 23:20:00 2006 +0000
@@ -206,6 +206,7 @@
int64 CalculateCompanyValue(const Player* p);
void InvalidatePlayerWindows(const Player* p);
void UpdatePlayerMoney32(Player *p);
+void SetLocalPlayer(PlayerID new_player);
#define FOR_ALL_PLAYERS(p) for (p = _players; p != endof(_players); p++)
VARDEF PlayerID _local_player;
--- a/players.c Sat Dec 30 23:14:39 2006 +0000
+++ b/players.c Sat Dec 30 23:20:00 2006 +0000
@@ -28,6 +28,29 @@
#include "date.h"
#include "window.h"
+/**
+ * Sets the local player and updates the patch settings that are set on a
+ * per-company (player) basis to reflect the core's state in the GUI.
+ * @param new_player the new player
+ * @pre IsValidPlayer(new_player) || new_player == PLAYER_SPECTATOR || new_player == OWNER_NONE
+ */
+void SetLocalPlayer(PlayerID new_player)
+{
+ /* Player could also be PLAYER_SPECTATOR or OWNER_NONE */
+ assert(IsValidPlayer(new_player) || new_player == PLAYER_SPECTATOR || new_player == OWNER_NONE);
+
+ _local_player = new_player;
+
+ /* Do not update the patches if we are in the intro GUI */
+ if (IsValidPlayer(new_player) && _game_mode != GM_MENU) {
+ const Player *p = GetPlayer(new_player);
+ _patches.autorenew = p->engine_renew;
+ _patches.autorenew_months = p->engine_renew_months;
+ _patches.autorenew_money = p->engine_renew_money;
+ InvalidateWindow(WC_GAME_OPTIONS, 0);
+ }
+}
+
uint16 GetDrawStringPlayerColor(PlayerID player)
{
@@ -820,9 +843,8 @@
/* This command is only executed in a multiplayer game */
if (!_networking) return CMD_ERROR;
- /* ClientID would be valid up to MAX_CLIENT_INFO, but as it has to be a
- * new player, its valid range is restricted to that of players */
- if (!(flags & DC_EXEC) || !IsValidPlayer((PlayerID)cid)) return 0;
+ /* Has the network client a correct ClientID? */
+ if (!(flags & DC_EXEC) || cid >= MAX_CLIENT_INFO) return 0;
/* Delete multiplayer progress bar */
DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);
@@ -839,7 +861,8 @@
} else
#endif /* ENABLE_NETWORK */
{
- _local_player = _network_playas = PLAYER_SPECTATOR;
+ _network_playas = PLAYER_SPECTATOR;
+ SetLocalPlayer(PLAYER_SPECTATOR);
}
break;
}
@@ -847,7 +870,7 @@
/* This is the joining client who wants a new company */
if (_local_player != _network_playas) {
assert(_local_player == PLAYER_SPECTATOR && _network_playas == p->index);
- _local_player = p->index;
+ SetLocalPlayer(p->index);
MarkWholeScreenDirty();
}