Esempio n. 1
0
static void MakeNewGameDone()
{
	SettingsDisableElrail(_settings_game.vehicle.disable_elrails);

	/* In a dedicated server, the server does not play */
	if (!VideoDriver::GetInstance()->HasGUI()) {
		SetLocalCompany(COMPANY_SPECTATOR);
		if (_settings_client.gui.pause_on_newgame) DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE);
		IConsoleCmdExec("exec scripts/game_start.scr 0");
		return;
	}

	/* Create a single company */
	DoStartupNewCompany(false);

	Company *c = Company::Get(COMPANY_FIRST);
	c->settings = _settings_client.company;

	IConsoleCmdExec("exec scripts/game_start.scr 0");

	SetLocalCompany(COMPANY_FIRST);

	InitializeRailGUI();

#ifdef ENABLE_NETWORK
	/* We are the server, we start a new company (not dedicated),
	 * so set the default password *if* needed. */
	if (_network_server && !StrEmpty(_settings_client.network.default_company_pass)) {
		NetworkChangeCompanyPassword(_local_company, _settings_client.network.default_company_pass);
	}
#endif /* ENABLE_NETWORK */

	if (_settings_client.gui.pause_on_newgame) DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE);

	CheckEngines();
	CheckIndustries();
	MarkWholeScreenDirty();
}
Esempio n. 2
0
static void MakeNewEditorWorldDone()
{
	SetLocalCompany(OWNER_NONE);
}
Esempio n. 3
0
void SwitchToMode(SwitchMode new_mode)
{
#ifdef ENABLE_NETWORK
	/* If we are saving something, the network stays in his current state */
	if (new_mode != SM_SAVE_GAME) {
		/* If the network is active, make it not-active */
		if (_networking) {
			if (_network_server && (new_mode == SM_LOAD_GAME || new_mode == SM_NEWGAME || new_mode == SM_RESTARTGAME)) {
				NetworkReboot();
			} else {
				NetworkDisconnect();
			}
		}

		/* If we are a server, we restart the server */
		if (_is_network_server) {
			/* But not if we are going to the menu */
			if (new_mode != SM_MENU) {
				/* check if we should reload the config */
				if (_settings_client.network.reload_cfg) {
					LoadFromConfig();
					MakeNewgameSettingsLive();
					ResetGRFConfig(false);
				}
				NetworkServerStart();
			} else {
				/* This client no longer wants to be a network-server */
				_is_network_server = false;
			}
		}
	}
#endif /* ENABLE_NETWORK */
	/* Make sure all AI controllers are gone at quitting game */
	if (new_mode != SM_SAVE_GAME) AI::KillAll();

	switch (new_mode) {
		case SM_EDITOR: // Switch to scenario editor
			MakeNewEditorWorld();
			break;

		case SM_RESTARTGAME: // Restart --> 'Random game' with current settings
		case SM_NEWGAME: // New Game --> 'Random game'
#ifdef ENABLE_NETWORK
			if (_network_server) {
				seprintf(_network_game_info.map_name, lastof(_network_game_info.map_name), "Random Map");
			}
#endif /* ENABLE_NETWORK */
			MakeNewGame(false, new_mode == SM_NEWGAME);
			break;

		case SM_LOAD_GAME: { // Load game, Play Scenario
			ResetGRFConfig(true);
			ResetWindowSystem();

			if (!SafeLoad(_file_to_saveload.name, _file_to_saveload.file_op, _file_to_saveload.detail_ftype, GM_NORMAL, NO_DIRECTORY)) {
				SetDParamStr(0, GetSaveLoadErrorString());
				ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR);
			} else {
				if (_file_to_saveload.abstract_ftype == FT_SCENARIO) {
					/* Reset engine pool to simplify changing engine NewGRFs in scenario editor. */
					EngineOverrideManager::ResetToCurrentNewGRFConfig();
				}
				/* Update the local company for a loaded game. It is either always
				 * company #1 (eg 0) or in the case of a dedicated server a spectator */
				SetLocalCompany(_network_dedicated ? COMPANY_SPECTATOR : COMPANY_FIRST);
				/* Execute the game-start script */
				IConsoleCmdExec("exec scripts/game_start.scr 0");
				/* Decrease pause counter (was increased from opening load dialog) */
				DoCommandP(0, PM_PAUSED_SAVELOAD, 0, CMD_PAUSE);
#ifdef ENABLE_NETWORK
				if (_network_server) {
					seprintf(_network_game_info.map_name, lastof(_network_game_info.map_name), "%s (Loaded game)", _file_to_saveload.title);
				}
#endif /* ENABLE_NETWORK */
			}
			break;
		}

		case SM_START_HEIGHTMAP: // Load a heightmap and start a new game from it
#ifdef ENABLE_NETWORK
			if (_network_server) {
				seprintf(_network_game_info.map_name, lastof(_network_game_info.map_name), "%s (Heightmap)", _file_to_saveload.title);
			}
#endif /* ENABLE_NETWORK */
			MakeNewGame(true, true);
			break;

		case SM_LOAD_HEIGHTMAP: // Load heightmap from scenario editor
			SetLocalCompany(OWNER_NONE);

			GenerateWorld(GWM_HEIGHTMAP, 1 << _settings_game.game_creation.map_x, 1 << _settings_game.game_creation.map_y);
			MarkWholeScreenDirty();
			break;

		case SM_LOAD_SCENARIO: { // Load scenario from scenario editor
			if (SafeLoad(_file_to_saveload.name, _file_to_saveload.file_op, _file_to_saveload.detail_ftype, GM_EDITOR, NO_DIRECTORY)) {
				SetLocalCompany(OWNER_NONE);
				_settings_newgame.game_creation.starting_year = _cur_year;
				/* Cancel the saveload pausing */
				DoCommandP(0, PM_PAUSED_SAVELOAD, 0, CMD_PAUSE);
			} else {
				SetDParamStr(0, GetSaveLoadErrorString());
				ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR);
			}
			break;
		}

		case SM_MENU: // Switch to game intro menu
			LoadIntroGame();
			if (BaseSounds::ini_set == NULL && BaseSounds::GetUsedSet()->fallback) {
				ShowErrorMessage(STR_WARNING_FALLBACK_SOUNDSET, INVALID_STRING_ID, WL_CRITICAL);
				BaseSounds::ini_set = stredup(BaseSounds::GetUsedSet()->name);
			}
			break;

		case SM_SAVE_GAME: // Save game.
			/* Make network saved games on pause compatible to singleplayer */
			if (SaveOrLoad(_file_to_saveload.name, SLO_SAVE, DFT_GAME_FILE, NO_DIRECTORY) != SL_OK) {
				SetDParamStr(0, GetSaveLoadErrorString());
				ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR);
			} else {
				DeleteWindowById(WC_SAVELOAD, 0);
			}
			break;

		case SM_SAVE_HEIGHTMAP: // Save heightmap.
			MakeHeightmapScreenshot(_file_to_saveload.name);
			DeleteWindowById(WC_SAVELOAD, 0);
			break;

		case SM_GENRANDLAND: // Generate random land within scenario editor
			SetLocalCompany(OWNER_NONE);
			GenerateWorld(GWM_RANDOM, 1 << _settings_game.game_creation.map_x, 1 << _settings_game.game_creation.map_y);
			/* XXX: set date */
			MarkWholeScreenDirty();
			break;

		default: NOT_REACHED();
	}
}
Esempio n. 4
0
/**
 * Control the companies: add, delete, etc.
 * @param tile unused
 * @param flags operation to perform
 * @param p1 various functionality
 * - bits 0..15:
 *        = 0 - create a new company
 *        = 1 - create a new AI company
 *        = 2 - delete a company
 * - bits 16..24: CompanyID
 * @param p2 ClientID
 * @param text unused
 * @return the cost of this operation or an error
 */
CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
	InvalidateWindowData(WC_COMPANY_LEAGUE, 0, 0);
	CompanyID company_id = (CompanyID)GB(p1, 16, 8);
#ifdef ENABLE_NETWORK
	ClientID client_id = (ClientID)p2;
#endif /* ENABLE_NETWORK */

	switch (GB(p1, 0, 16)) {
		case 0: { // Create a new company
			/* This command is only executed in a multiplayer game */
			if (!_networking) return CMD_ERROR;

#ifdef ENABLE_NETWORK
			/* Has the network client a correct ClientIndex? */
			if (!(flags & DC_EXEC)) return CommandCost();
			NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
#ifndef DEBUG_DUMP_COMMANDS
			/* When replaying the client ID is not a valid client; there
			 * are actually no clients at all. However, the company has to
			 * be created, otherwise we cannot rerun the game properly.
			 * So only allow a NULL client info in that case. */
			if (ci == NULL) return CommandCost();
#endif /* NOT DEBUG_DUMP_COMMANDS */

			/* Delete multiplayer progress bar */
			DeleteWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);

			Company *c = DoStartupNewCompany(false);

			/* A new company could not be created, revert to being a spectator */
			if (c == NULL) {
				if (_network_server) {
					ci->client_playas = COMPANY_SPECTATOR;
					NetworkUpdateClientInfo(ci->client_id);
				}
				break;
			}

			/* This is the client (or non-dedicated server) who wants a new company */
			if (client_id == _network_own_client_id) {
				assert(_local_company == COMPANY_SPECTATOR);
				SetLocalCompany(c->index);
				if (!StrEmpty(_settings_client.network.default_company_pass)) {
					NetworkChangeCompanyPassword(_local_company, _settings_client.network.default_company_pass);
				}

				/* Now that we have a new company, broadcast our company settings to
				 * all clients so everything is in sync */
				SyncCompanySettings();

				MarkWholeScreenDirty();
			}

			if (_network_server) {
				if (ci != NULL) {
					/* ci is only NULL when replaying.
					 * When replaying no client is actually in need of an update. */
					ci->client_playas = c->index;
					NetworkUpdateClientInfo(ci->client_id);
				}

				if (Company::IsValidID(c->index)) {
					_network_company_states[c->index].months_empty = 0;
					_network_company_states[c->index].password[0] = '\0';
					NetworkServerUpdateCompanyPassworded(c->index, false);

					/* XXX - When a client joins, we automatically set its name to the
					 * client's name (for some reason). As it stands now only the server
					 * knows the client's name, so it needs to send out a "broadcast" to
					 * do this. To achieve this we send a network command. However, it
					 * uses _local_company to execute the command as.  To prevent abuse
					 * (eg. only yourself can change your name/company), we 'cheat' by
					 * impersonation _local_company as the server. Not the best solution;
					 * but it works.
					 * TODO: Perhaps this could be improved by when the client is ready
					 * with joining to let it send itself the command, and not the server?
					 * For example in network_client.c:534? */
					if (ci != NULL) {
						/* ci is only NULL when replaying.
						 * When replaying, the command to rename the president will
						 * automatically be ran, so this is not even needed to get
						 * the exact same state. */
						NetworkSendCommand(0, 0, 0, CMD_RENAME_PRESIDENT, NULL, ci->client_name, c->index);
					}
				}

				/* Announce new company on network. */
				NetworkAdminCompanyInfo(c, true);

				if (ci != NULL) {
					/* ci is only NULL when replaying.
					 * When replaying, the message that someone started a new company
					 * is not interesting at all. */
					NetworkServerSendChat(NETWORK_ACTION_COMPANY_NEW, DESTTYPE_BROADCAST, 0, "", ci->client_id, c->index + 1);
				}
			}
#endif /* ENABLE_NETWORK */
			break;
		}

		case 1: // Make a new AI company
			if (!(flags & DC_EXEC)) return CommandCost();

			if (company_id != INVALID_COMPANY && (company_id >= MAX_COMPANIES || Company::IsValidID(company_id))) return CMD_ERROR;
			DoStartupNewCompany(true, company_id);
			break;

		case 2: { // Delete a company
			CompanyRemoveReason reason = (CompanyRemoveReason)GB(p2, 0, 2);
			if (reason >= CRR_END) return CMD_ERROR;

			Company *c = Company::GetIfValid(company_id);
			if (c == NULL) return CMD_ERROR;

			if (!(flags & DC_EXEC)) return CommandCost();

			/* Delete any open window of the company */
			DeleteCompanyWindows(c->index);
			CompanyNewsInformation *cni = MallocT<CompanyNewsInformation>(1);
			cni->FillData(c);

			/* Show the bankrupt news */
			SetDParam(0, STR_NEWS_COMPANY_BANKRUPT_TITLE);
			SetDParam(1, STR_NEWS_COMPANY_BANKRUPT_DESCRIPTION);
			SetDParamStr(2, cni->company_name);
			AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, cni);

			/* Remove the company */
			ChangeOwnershipOfCompanyItems(c->index, INVALID_OWNER);
			if (c->is_ai) AI::Stop(c->index);

			CompanyID c_index = c->index;
			delete c;
			AI::BroadcastNewEvent(new ScriptEventCompanyBankrupt(c_index));
			Game::NewEvent(new ScriptEventCompanyBankrupt(c_index));
			CompanyAdminRemove(c_index, (CompanyRemoveReason)reason);
			break;
		}

		default: return CMD_ERROR;
	}

	InvalidateWindowClassesData(WC_GAME_OPTIONS);
	InvalidateWindowClassesData(WC_AI_SETTINGS);
	InvalidateWindowClassesData(WC_AI_LIST);

	return CommandCost();
}
Esempio n. 5
0
/** Control the companies: add, delete, etc.
 * @param tile unused
 * @param flags operation to perform
 * @param p1 various functionality
 * - p1 = 0 - create a new company, Which company (network) it will be is in p2
 * - p1 = 1 - create a new AI company
 * - p1 = 2 - delete a company. Company is identified by p2
 * @param p2 various functionality, dictated by p1
 * - p1 = 0 - ClientID of the newly created client
 * - p1 = 1 - CompanyID to start AI (INVALID_COMPANY for first available)
 * - p1 = 2 - CompanyID of the that is getting deleted
 * @param text unused
 * @return the cost of this operation or an error
 *
 * @todo In the case of p1=0, create new company, the clientID of the new client is in parameter
 * p2. This parameter is passed in at function DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND)
 * on the server itself. First of all this is unbelievably ugly; second of all, well,
 * it IS ugly! <b>Someone fix this up :)</b> So where to fix?@n
 * @arg - network_server.c:838 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND)@n
 * @arg - network_client.c:536 DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_MAP) from where the map has been received
 */
CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
	InvalidateWindowData(WC_COMPANY_LEAGUE, 0, 0);

	switch (p1) {
		case 0: { // Create a new company
			/* This command is only executed in a multiplayer game */
			if (!_networking) return CMD_ERROR;

#ifdef ENABLE_NETWORK

			/* Joining Client:
			 * _local_company: COMPANY_SPECTATOR
			 * cid = clientid
			 *
			 * Other client(s)/server:
			 * _local_company: what they play as
			 * cid = requested company/company of joining client */
			ClientID cid = (ClientID)p2;

			/* Has the network client a correct ClientIndex? */
			if (!(flags & DC_EXEC)) return CommandCost();
			NetworkClientInfo *ci = NetworkFindClientInfoFromClientID(cid);
			if (ci == NULL) return CommandCost();

			/* Delete multiplayer progress bar */
			DeleteWindowById(WC_NETWORK_STATUS_WINDOW, 0);

			Company *c = DoStartupNewCompany(false);

			/* A new company could not be created, revert to being a spectator */
			if (c == NULL) {
				if (_network_server) {
					ci->client_playas = COMPANY_SPECTATOR;
					NetworkUpdateClientInfo(ci->client_id);
				}
				break;
			}

			/* This is the client (or non-dedicated server) who wants a new company */
			if (cid == _network_own_client_id) {
				assert(_local_company == COMPANY_SPECTATOR);
				SetLocalCompany(c->index);
				if (!StrEmpty(_settings_client.network.default_company_pass)) {
					NetworkChangeCompanyPassword(_settings_client.network.default_company_pass);
				}

				/* Now that we have a new company, broadcast our company settings to
				 * all clients so everything is in sync */
				SyncCompanySettings();

				MarkWholeScreenDirty();
			}

			if (_network_server) {
				/* XXX - UGLY! p2 (pid) is mis-used to fetch the client-id, done at
				 * server side in network_server.c:838, function
				 * DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND) */
				CompanyID old_playas = ci->client_playas;
				ci->client_playas = c->index;
				NetworkUpdateClientInfo(ci->client_id);

				if (Company::IsValidID(ci->client_playas)) {
					_network_company_states[c->index].months_empty = 0;
					_network_company_states[c->index].password[0] = '\0';
					NetworkServerUpdateCompanyPassworded(ci->client_playas, false);

					/* XXX - When a client joins, we automatically set its name to the
					 * client's name (for some reason). As it stands now only the server
					 * knows the client's name, so it needs to send out a "broadcast" to
					 * do this. To achieve this we send a network command. However, it
					 * uses _local_company to execute the command as.  To prevent abuse
					 * (eg. only yourself can change your name/company), we 'cheat' by
					 * impersonation _local_company as the server. Not the best solution;
					 * but it works.
					 * TODO: Perhaps this could be improved by when the client is ready
					 * with joining to let it send itself the command, and not the server?
					 * For example in network_client.c:534? */
					NetworkSend_Command(0, 0, 0, CMD_RENAME_PRESIDENT, NULL, ci->client_name, ci->client_playas);
				}

				/* Announce new company on network, if the client was a SPECTATOR before */
				if (old_playas == COMPANY_SPECTATOR) {
					NetworkServerSendChat(NETWORK_ACTION_COMPANY_NEW, DESTTYPE_BROADCAST, 0, "", ci->client_id, ci->client_playas + 1);
				}
			}
#endif /* ENABLE_NETWORK */
		} break;

		case 1: // Make a new AI company
			if (!(flags & DC_EXEC)) return CommandCost();

			if (p2 != INVALID_COMPANY && (p2 >= MAX_COMPANIES || Company::IsValidID(p2))) return CMD_ERROR;
			DoStartupNewCompany(true, (CompanyID)p2);
			break;

		case 2: { // Delete a company
			Company *c = Company::GetIfValid(p2);
			if (c == NULL) return CMD_ERROR;

			if (!(flags & DC_EXEC)) return CommandCost();

			/* Delete any open window of the company */
			DeleteCompanyWindows(c->index);
			CompanyNewsInformation *cni = MallocT<CompanyNewsInformation>(1);
			cni->FillData(c);

			/* Show the bankrupt news */
			SetDParam(0, STR_NEWS_COMPANY_BANKRUPT_TITLE);
			SetDParam(1, STR_NEWS_COMPANY_BANKRUPT_DESCRIPTION);
			SetDParamStr(2, cni->company_name);
			AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, NS_COMPANY_BANKRUPT, cni);

			/* Remove the company */
			ChangeOwnershipOfCompanyItems(c->index, INVALID_OWNER);
			if (c->is_ai) AI::Stop(c->index);

			CompanyID c_index = c->index;
			delete c;
			AI::BroadcastNewEvent(new AIEventCompanyBankrupt(c_index));
		} break;

		default: return CMD_ERROR;
	}

	return CommandCost();
}
Esempio n. 6
0
/**
 * Control the companies: add, delete, etc.
 * @param tile unused
 * @param flags operation to perform
 * @param p1 various functionality
 * - bits 0..15:
 *        = 0 - create a new company
 *        = 1 - create a new AI company
 *        = 2 - delete a company
 * - bits 16..24: CompanyID
 * @param p2 ClientID
 * @param text unused
 * @return the cost of this operation or an error
 */
CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
	InvalidateWindowData(WC_COMPANY_LEAGUE, 0, 0);
	CompanyID company_id = (CompanyID)GB(p1, 16, 8);
#ifdef ENABLE_NETWORK
	ClientID client_id = (ClientID)p2;
#endif /* ENABLE_NETWORK */

	switch (GB(p1, 0, 16)) {
		case 0: { // Create a new company
			/* This command is only executed in a multiplayer game */
			if (!_networking) return CMD_ERROR;

#ifdef ENABLE_NETWORK
			/* Has the network client a correct ClientIndex? */
			if (!(flags & DC_EXEC)) return CommandCost();
			NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
#ifndef DEBUG_DUMP_COMMANDS
			/* When replaying the client ID is not a valid client; there
			 * are actually no clients at all. However, the company has to
			 * be created, otherwise we cannot rerun the game properly.
			 * So only allow a NULL client info in that case. */
			if (ci == NULL) return CommandCost();
#endif /* NOT DEBUG_DUMP_COMMANDS */

			/* Delete multiplayer progress bar */
			DeleteWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);

			Company *c = DoStartupNewCompany(false);

			/* A new company could not be created, revert to being a spectator */
			if (c == NULL) {
				if (_network_server) {
					ci->client_playas = COMPANY_SPECTATOR;
					NetworkUpdateClientInfo(ci->client_id);
				}
				break;
			}

			/* This is the client (or non-dedicated server) who wants a new company */
			if (client_id == _network_own_client_id) {
				assert(_local_company == COMPANY_SPECTATOR);
				SetLocalCompany(c->index);
				if (!StrEmpty(_settings_client.network.default_company_pass)) {
					NetworkChangeCompanyPassword(_local_company, _settings_client.network.default_company_pass);
				}

				/* Now that we have a new company, broadcast our company settings to
				 * all clients so everything is in sync */
				SyncCompanySettings();

				MarkWholeScreenDirty();
			}

			NetworkServerNewCompany(c, ci);
#endif /* ENABLE_NETWORK */
			break;
		}

		case 1: { // Make a new AI company
			if (!(flags & DC_EXEC)) return CommandCost();

			if (company_id != INVALID_COMPANY && (company_id >= MAX_COMPANIES || Company::IsValidID(company_id))) return CMD_ERROR;
			Company *c = DoStartupNewCompany(true, company_id);
#ifdef ENABLE_NETWORK
			if (c != NULL) NetworkServerNewCompany(c, NULL);
#endif /* ENABLE_NETWORK */
			break;
		}

		case 2: { // Delete a company
			CompanyRemoveReason reason = (CompanyRemoveReason)GB(p2, 0, 2);
			if (reason >= CRR_END) return CMD_ERROR;

			Company *c = Company::GetIfValid(company_id);
			if (c == NULL) return CMD_ERROR;

			if (!(flags & DC_EXEC)) return CommandCost();

			/* Delete any open window of the company */
			DeleteCompanyWindows(c->index);
			CompanyNewsInformation *cni = MallocT<CompanyNewsInformation>(1);
			cni->FillData(c);

			/* Show the bankrupt news */
			SetDParam(0, STR_NEWS_COMPANY_BANKRUPT_TITLE);
			SetDParam(1, STR_NEWS_COMPANY_BANKRUPT_DESCRIPTION);
			SetDParamStr(2, cni->company_name);
			AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, cni);

			/* Remove the company */
			ChangeOwnershipOfCompanyItems(c->index, INVALID_OWNER);
			if (c->is_ai) AI::Stop(c->index);

			CompanyID c_index = c->index;
			delete c;
			AI::BroadcastNewEvent(new ScriptEventCompanyBankrupt(c_index));
			Game::NewEvent(new ScriptEventCompanyBankrupt(c_index));
			CompanyAdminRemove(c_index, (CompanyRemoveReason)reason);

			if (StoryPage::GetNumItems() == 0 || Goal::GetNumItems() == 0) InvalidateWindowData(WC_MAIN_TOOLBAR, 0);
			break;
		}

		default: return CMD_ERROR;
	}

	InvalidateWindowClassesData(WC_GAME_OPTIONS);
	InvalidateWindowClassesData(WC_AI_SETTINGS);
	InvalidateWindowClassesData(WC_AI_LIST);

	return CommandCost();
}