Merge 1.5.0-beta1
This commit is contained in:
304
src/openttd.cpp
304
src/openttd.cpp
@@ -34,7 +34,6 @@
|
||||
#include "console_func.h"
|
||||
#include "screenshot.h"
|
||||
#include "network/network.h"
|
||||
#include "network/network_server.h"
|
||||
#include "network/network_func.h"
|
||||
#include "ai/ai.hpp"
|
||||
#include "ai/ai_config.hpp"
|
||||
@@ -97,10 +96,9 @@ void MusicLoop();
|
||||
void CallWindowGameTickEvent();
|
||||
bool HandleBootstrap();
|
||||
|
||||
extern void AfterLoadCompanyStats();
|
||||
extern void CheckCaches();
|
||||
extern Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY);
|
||||
extern void OSOpenBrowser(const std::string &url);
|
||||
extern void RebuildTownCaches();
|
||||
extern void ShowOSErrorBox(const char *buf, bool system);
|
||||
extern std::string _config_file;
|
||||
|
||||
@@ -172,7 +170,6 @@ static void ShowHelp()
|
||||
" -G seed = Set random seed\n"
|
||||
" -n host[:port][#company]= Join network game\n"
|
||||
" -p password = Password to join server\n"
|
||||
" -P password = Password to join company\n"
|
||||
" -D [host][:port] = Start dedicated server\n"
|
||||
#if !defined(_WIN32)
|
||||
" -f = Fork into the background (dedicated only)\n"
|
||||
@@ -229,7 +226,7 @@ static void WriteSavegameInfo(const std::string &name)
|
||||
{
|
||||
extern SaveLoadVersion _sl_version;
|
||||
uint32_t last_ottd_rev = 0;
|
||||
byte ever_modified = 0;
|
||||
uint8_t ever_modified = 0;
|
||||
bool removed_newgrfs = false;
|
||||
|
||||
_gamelog.Info(&last_ottd_rev, &ever_modified, &removed_newgrfs);
|
||||
@@ -390,7 +387,6 @@ struct AfterNewGRFScan : NewGRFScanCallback {
|
||||
uint16_t dedicated_port = 0; ///< Port for the dedicated server.
|
||||
std::string connection_string; ///< Information about the server to connect to
|
||||
std::string join_server_password; ///< The password to join the server with.
|
||||
std::string join_company_password; ///< The password to join the company with.
|
||||
bool save_config = true; ///< The save config setting.
|
||||
|
||||
/**
|
||||
@@ -454,7 +450,7 @@ struct AfterNewGRFScan : NewGRFScanCallback {
|
||||
LoadIntroGame();
|
||||
_switch_mode = SM_NONE;
|
||||
|
||||
NetworkClientConnectGame(connection_string, COMPANY_NEW_COMPANY, join_server_password, join_company_password);
|
||||
NetworkClientConnectGame(connection_string, COMPANY_NEW_COMPANY, join_server_password);
|
||||
}
|
||||
|
||||
/* After the scan we're not used anymore. */
|
||||
@@ -482,44 +478,34 @@ void PostMainLoop()
|
||||
extern void DedicatedFork();
|
||||
#endif
|
||||
|
||||
/** Options of OpenTTD. */
|
||||
static const OptionData _options[] = {
|
||||
GETOPT_SHORT_VALUE('I'),
|
||||
GETOPT_SHORT_VALUE('S'),
|
||||
GETOPT_SHORT_VALUE('M'),
|
||||
GETOPT_SHORT_VALUE('m'),
|
||||
GETOPT_SHORT_VALUE('s'),
|
||||
GETOPT_SHORT_VALUE('v'),
|
||||
GETOPT_SHORT_VALUE('b'),
|
||||
GETOPT_SHORT_OPTVAL('D'),
|
||||
GETOPT_SHORT_VALUE('n'),
|
||||
GETOPT_SHORT_VALUE('p'),
|
||||
GETOPT_SHORT_VALUE('P'),
|
||||
/**
|
||||
* Create all the options that OpenTTD supports. Each option is
|
||||
* always a single character with no, an optional or a required value.
|
||||
* @return The available options.
|
||||
*/
|
||||
static std::vector<OptionData> CreateOptions()
|
||||
{
|
||||
std::vector<OptionData> options;
|
||||
/* Options that require a parameter. */
|
||||
for (char c : "GIMSbcmnpqrstv") options.push_back({ .type = ODF_HAS_VALUE, .id = c, .shortname = c });
|
||||
#if !defined(_WIN32)
|
||||
GETOPT_SHORT_NOVAL('f'),
|
||||
options.push_back({ .type = ODF_HAS_VALUE, .id = 'f', .shortname = 'f' });
|
||||
#endif
|
||||
GETOPT_SHORT_VALUE('r'),
|
||||
GETOPT_SHORT_VALUE('t'),
|
||||
GETOPT_SHORT_OPTVAL('d'),
|
||||
GETOPT_SHORT_NOVAL('e'),
|
||||
GETOPT_SHORT_OPTVAL('g'),
|
||||
GETOPT_SHORT_VALUE('G'),
|
||||
GETOPT_SHORT_VALUE('c'),
|
||||
GETOPT_SHORT_NOVAL('x'),
|
||||
GETOPT_SHORT_NOVAL('X'),
|
||||
GETOPT_SHORT_VALUE('q'),
|
||||
GETOPT_SHORT_NOVAL('h'),
|
||||
GETOPT_SHORT_NOVAL('Q'),
|
||||
GETOPT_END()
|
||||
};
|
||||
|
||||
/* Options with an optional parameter. */
|
||||
for (char c : "Ddg") options.push_back({ .type = ODF_OPTIONAL_VALUE, .id = c, .shortname = c });
|
||||
|
||||
/* Options without a parameter. */
|
||||
for (char c : "QXehx") options.push_back({ .type = ODF_NO_VALUE, .id = c, .shortname = c });
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main entry point for this lovely game.
|
||||
* @param argc The number of arguments passed to this game.
|
||||
* @param argv The values of the arguments.
|
||||
* @param arguments The command line arguments passed to the application.
|
||||
* @return 0 when there is no error.
|
||||
*/
|
||||
int openttd_main(int argc, char *argv[])
|
||||
int openttd_main(std::span<char * const> arguments)
|
||||
{
|
||||
_game_session_stats.start_time = std::chrono::steady_clock::now();
|
||||
_game_session_stats.savegame_size = std::nullopt;
|
||||
@@ -532,7 +518,7 @@ int openttd_main(int argc, char *argv[])
|
||||
std::string sounds_set;
|
||||
std::string music_set;
|
||||
Dimension resolution = {0, 0};
|
||||
std::unique_ptr<AfterNewGRFScan> scanner(new AfterNewGRFScan());
|
||||
std::unique_ptr<AfterNewGRFScan> scanner = std::make_unique<AfterNewGRFScan>();
|
||||
bool dedicated = false;
|
||||
bool only_local_path = false;
|
||||
|
||||
@@ -542,7 +528,8 @@ int openttd_main(int argc, char *argv[])
|
||||
_game_mode = GM_MENU;
|
||||
_switch_mode = SM_MENU;
|
||||
|
||||
GetOptData mgo(argc - 1, argv + 1, _options);
|
||||
auto options = CreateOptions();
|
||||
GetOptData mgo(arguments.subspan(1), options);
|
||||
int ret = 0;
|
||||
|
||||
int i;
|
||||
@@ -573,9 +560,6 @@ int openttd_main(int argc, char *argv[])
|
||||
case 'p':
|
||||
scanner->join_server_password = mgo.opt;
|
||||
break;
|
||||
case 'P':
|
||||
scanner->join_company_password = mgo.opt;
|
||||
break;
|
||||
case 'r': ParseResolution(&resolution, mgo.opt); break;
|
||||
case 't': scanner->startyear = atoi(mgo.opt); break;
|
||||
case 'd': {
|
||||
@@ -598,7 +582,7 @@ int openttd_main(int argc, char *argv[])
|
||||
if (mgo.opt != nullptr) {
|
||||
_file_to_saveload.name = mgo.opt;
|
||||
|
||||
std::string extension = std::filesystem::path(_file_to_saveload.name).extension().string();
|
||||
std::string extension = FS2OTTD(std::filesystem::path(OTTD2FS(_file_to_saveload.name)).extension());
|
||||
auto [ft, _] = FiosGetSavegameListCallback(SLO_LOAD, _file_to_saveload.name, extension);
|
||||
if (ft == FIOS_TYPE_INVALID) {
|
||||
std::tie(ft, _) = FiosGetScenarioListCallback(SLO_LOAD, _file_to_saveload.name, extension);
|
||||
@@ -626,13 +610,13 @@ int openttd_main(int argc, char *argv[])
|
||||
}
|
||||
break;
|
||||
case 'q': {
|
||||
DeterminePaths(argv[0], only_local_path);
|
||||
DeterminePaths(arguments[0], only_local_path);
|
||||
if (StrEmpty(mgo.opt)) {
|
||||
ret = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string extension = std::filesystem::path(_file_to_saveload.name).extension().string();
|
||||
std::string extension = FS2OTTD(std::filesystem::path(OTTD2FS(mgo.opt)).extension());
|
||||
auto [_, title] = FiosGetSavegameListCallback(SLO_LOAD, mgo.opt, extension);
|
||||
|
||||
_load_check_data.Clear();
|
||||
@@ -666,13 +650,13 @@ int openttd_main(int argc, char *argv[])
|
||||
if (i == -2) break;
|
||||
}
|
||||
|
||||
if (i == -2 || mgo.numleft > 0) {
|
||||
if (i == -2 || !mgo.arguments.empty()) {
|
||||
/* Either the user typed '-h', they made an error, or they added unrecognized command line arguments.
|
||||
* In all cases, print the help, and exit.
|
||||
*
|
||||
* The next two functions are needed to list the graphics sets. We can't do them earlier
|
||||
* because then we cannot show it on the debug console as that hasn't been configured yet. */
|
||||
DeterminePaths(argv[0], only_local_path);
|
||||
DeterminePaths(arguments[0], only_local_path);
|
||||
TarScanner::DoScan(TarScanner::BASESET);
|
||||
BaseGraphics::FindSets();
|
||||
BaseSounds::FindSets();
|
||||
@@ -681,7 +665,7 @@ int openttd_main(int argc, char *argv[])
|
||||
return ret;
|
||||
}
|
||||
|
||||
DeterminePaths(argv[0], only_local_path);
|
||||
DeterminePaths(arguments[0], only_local_path);
|
||||
TarScanner::DoScan(TarScanner::BASESET);
|
||||
|
||||
if (dedicated) Debug(net, 3, "Starting dedicated server, version {}", _openttd_revision);
|
||||
@@ -774,10 +758,10 @@ int openttd_main(int argc, char *argv[])
|
||||
InitializeSpriteSorter();
|
||||
|
||||
/* Initialize the zoom level of the screen to normal */
|
||||
_screen.zoom = ZOOM_LVL_NORMAL;
|
||||
_screen.zoom = ZOOM_LVL_MIN;
|
||||
|
||||
/* The video driver is now selected, now initialise GUI zoom */
|
||||
AdjustGUIZoom(false);
|
||||
UpdateGUIZoom();
|
||||
|
||||
SocialIntegration::Initialize();
|
||||
NetworkStartUp(); // initialize network-core
|
||||
@@ -825,8 +809,6 @@ int openttd_main(int argc, char *argv[])
|
||||
GenerateWorld(GWM_EMPTY, 64, 64); // Make the viewport initialization happy
|
||||
LoadIntroGame(false);
|
||||
|
||||
CheckForMissingGlyphs();
|
||||
|
||||
/* ScanNewGRFFiles now has control over the scanner. */
|
||||
RequestNewGRFScan(scanner.release());
|
||||
|
||||
@@ -873,8 +855,8 @@ static void OnStartGame(bool dedicated_server)
|
||||
* or in the case of a dedicated server, a spectator */
|
||||
SetLocalCompany(dedicated_server ? COMPANY_SPECTATOR : GetFirstPlayableCompanyID());
|
||||
|
||||
/* Update the static game info to set the values from the new game. */
|
||||
NetworkServerUpdateGameInfo();
|
||||
NetworkOnGameStart();
|
||||
|
||||
/* Execute the game-start script */
|
||||
IConsoleCmdExec("exec scripts/game_start.scr 0");
|
||||
}
|
||||
@@ -914,23 +896,11 @@ static void MakeNewGameDone()
|
||||
InitializeRailGUI();
|
||||
InitializeRoadGUI();
|
||||
|
||||
/* We are the server, we start a new company (not dedicated),
|
||||
* so set the default password *if* needed. */
|
||||
if (_network_server && !_settings_client.network.default_company_pass.empty()) {
|
||||
NetworkChangeCompanyPassword(_local_company, _settings_client.network.default_company_pass);
|
||||
}
|
||||
|
||||
if (_settings_client.gui.pause_on_newgame) Command<CMD_PAUSE>::Post(PM_PAUSED_NORMAL, true);
|
||||
|
||||
CheckEngines();
|
||||
CheckIndustries();
|
||||
MarkWholeScreenDirty();
|
||||
|
||||
if (_network_server) {
|
||||
ChangeNetworkRestartTime(true);
|
||||
|
||||
if (!_network_dedicated) ShowClientList();
|
||||
}
|
||||
}
|
||||
|
||||
static void MakeNewGame(bool from_heightmap, bool reset_settings)
|
||||
@@ -1138,8 +1108,7 @@ void SwitchToMode(SwitchMode new_mode)
|
||||
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_CRITICAL);
|
||||
ShowErrorMessage(GetSaveLoadErrorType(), GetSaveLoadErrorMessage(), WL_CRITICAL);
|
||||
} else {
|
||||
if (_file_to_saveload.abstract_ftype == FT_SCENARIO) {
|
||||
OnStartScenario();
|
||||
@@ -1181,8 +1150,7 @@ void SwitchToMode(SwitchMode new_mode)
|
||||
/* Cancel the saveload pausing */
|
||||
Command<CMD_PAUSE>::Post(PM_PAUSED_SAVELOAD, false);
|
||||
} else {
|
||||
SetDParamStr(0, GetSaveLoadErrorString());
|
||||
ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_CRITICAL);
|
||||
ShowErrorMessage(GetSaveLoadErrorType(), GetSaveLoadErrorMessage(), WL_CRITICAL);
|
||||
}
|
||||
|
||||
UpdateSocialIntegration(GM_EDITOR);
|
||||
@@ -1217,8 +1185,7 @@ void SwitchToMode(SwitchMode new_mode)
|
||||
case SM_SAVE_GAME: // Save game.
|
||||
/* Make network saved games on pause compatible to singleplayer mode */
|
||||
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);
|
||||
ShowErrorMessage(GetSaveLoadErrorType(), GetSaveLoadErrorMessage(), WL_ERROR);
|
||||
} else {
|
||||
CloseWindowById(WC_SAVELOAD, 0);
|
||||
}
|
||||
@@ -1241,195 +1208,6 @@ void SwitchToMode(SwitchMode new_mode)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check the validity of some of the caches.
|
||||
* Especially in the sense of desyncs between
|
||||
* the cached value and what the value would
|
||||
* be when calculated from the 'base' data.
|
||||
*/
|
||||
static void CheckCaches()
|
||||
{
|
||||
/* Return here so it is easy to add checks that are run
|
||||
* always to aid testing of caches. */
|
||||
if (_debug_desync_level <= 1) return;
|
||||
|
||||
/* Check the town caches. */
|
||||
std::vector<TownCache> old_town_caches;
|
||||
for (const Town *t : Town::Iterate()) {
|
||||
old_town_caches.push_back(t->cache);
|
||||
}
|
||||
|
||||
RebuildTownCaches();
|
||||
RebuildSubsidisedSourceAndDestinationCache();
|
||||
|
||||
uint i = 0;
|
||||
for (Town *t : Town::Iterate()) {
|
||||
if (MemCmpT(old_town_caches.data() + i, &t->cache) != 0) {
|
||||
Debug(desync, 2, "warning: town cache mismatch: town {}", t->index);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Check company infrastructure cache. */
|
||||
std::vector<CompanyInfrastructure> old_infrastructure;
|
||||
for (const Company *c : Company::Iterate()) old_infrastructure.push_back(c->infrastructure);
|
||||
|
||||
AfterLoadCompanyStats();
|
||||
|
||||
i = 0;
|
||||
for (const Company *c : Company::Iterate()) {
|
||||
if (MemCmpT(old_infrastructure.data() + i, &c->infrastructure) != 0) {
|
||||
Debug(desync, 2, "warning: infrastructure cache mismatch: company {}", c->index);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Strict checking of the road stop cache entries */
|
||||
for (const RoadStop *rs : RoadStop::Iterate()) {
|
||||
if (IsBayRoadStopTile(rs->xy)) continue;
|
||||
|
||||
assert(rs->GetEntry(DIAGDIR_NE) != rs->GetEntry(DIAGDIR_NW));
|
||||
rs->GetEntry(DIAGDIR_NE)->CheckIntegrity(rs);
|
||||
rs->GetEntry(DIAGDIR_NW)->CheckIntegrity(rs);
|
||||
}
|
||||
|
||||
for (Vehicle *v : Vehicle::Iterate()) {
|
||||
if (v != v->First() || v->vehstatus & VS_CRASHED || !v->IsPrimaryVehicle()) continue;
|
||||
|
||||
uint length = 0;
|
||||
for (const Vehicle *u = v; u != nullptr; u = u->Next()) length++;
|
||||
|
||||
NewGRFCache *grf_cache = CallocT<NewGRFCache>(length);
|
||||
VehicleCache *veh_cache = CallocT<VehicleCache>(length);
|
||||
GroundVehicleCache *gro_cache = CallocT<GroundVehicleCache>(length);
|
||||
TrainCache *tra_cache = CallocT<TrainCache>(length);
|
||||
|
||||
length = 0;
|
||||
for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
|
||||
FillNewGRFVehicleCache(u);
|
||||
grf_cache[length] = u->grf_cache;
|
||||
veh_cache[length] = u->vcache;
|
||||
switch (u->type) {
|
||||
case VEH_TRAIN:
|
||||
gro_cache[length] = Train::From(u)->gcache;
|
||||
tra_cache[length] = Train::From(u)->tcache;
|
||||
break;
|
||||
case VEH_ROAD:
|
||||
gro_cache[length] = RoadVehicle::From(u)->gcache;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
length++;
|
||||
}
|
||||
|
||||
switch (v->type) {
|
||||
case VEH_TRAIN: Train::From(v)->ConsistChanged(CCF_TRACK); break;
|
||||
case VEH_ROAD: RoadVehUpdateCache(RoadVehicle::From(v)); break;
|
||||
case VEH_AIRCRAFT: UpdateAircraftCache(Aircraft::From(v)); break;
|
||||
case VEH_SHIP: Ship::From(v)->UpdateCache(); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
length = 0;
|
||||
for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
|
||||
FillNewGRFVehicleCache(u);
|
||||
if (memcmp(&grf_cache[length], &u->grf_cache, sizeof(NewGRFCache)) != 0) {
|
||||
Debug(desync, 2, "warning: newgrf cache mismatch: type {}, vehicle {}, company {}, unit number {}, wagon {}", v->type, v->index, v->owner, v->unitnumber, length);
|
||||
}
|
||||
if (memcmp(&veh_cache[length], &u->vcache, sizeof(VehicleCache)) != 0) {
|
||||
Debug(desync, 2, "warning: vehicle cache mismatch: type {}, vehicle {}, company {}, unit number {}, wagon {}", v->type, v->index, v->owner, v->unitnumber, length);
|
||||
}
|
||||
switch (u->type) {
|
||||
case VEH_TRAIN:
|
||||
if (memcmp(&gro_cache[length], &Train::From(u)->gcache, sizeof(GroundVehicleCache)) != 0) {
|
||||
Debug(desync, 2, "warning: train ground vehicle cache mismatch: vehicle {}, company {}, unit number {}, wagon {}", v->index, v->owner, v->unitnumber, length);
|
||||
}
|
||||
if (memcmp(&tra_cache[length], &Train::From(u)->tcache, sizeof(TrainCache)) != 0) {
|
||||
Debug(desync, 2, "warning: train cache mismatch: vehicle {}, company {}, unit number {}, wagon {}", v->index, v->owner, v->unitnumber, length);
|
||||
}
|
||||
break;
|
||||
case VEH_ROAD:
|
||||
if (memcmp(&gro_cache[length], &RoadVehicle::From(u)->gcache, sizeof(GroundVehicleCache)) != 0) {
|
||||
Debug(desync, 2, "warning: road vehicle ground vehicle cache mismatch: vehicle {}, company {}, unit number {}, wagon {}", v->index, v->owner, v->unitnumber, length);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
length++;
|
||||
}
|
||||
|
||||
free(grf_cache);
|
||||
free(veh_cache);
|
||||
free(gro_cache);
|
||||
free(tra_cache);
|
||||
}
|
||||
|
||||
/* Check whether the caches are still valid */
|
||||
for (Vehicle *v : Vehicle::Iterate()) {
|
||||
byte buff[sizeof(VehicleCargoList)];
|
||||
memcpy(buff, &v->cargo, sizeof(VehicleCargoList));
|
||||
v->cargo.InvalidateCache();
|
||||
assert(memcmp(&v->cargo, buff, sizeof(VehicleCargoList)) == 0);
|
||||
}
|
||||
|
||||
/* Backup stations_near */
|
||||
std::vector<StationList> old_town_stations_near;
|
||||
for (Town *t : Town::Iterate()) old_town_stations_near.push_back(t->stations_near);
|
||||
|
||||
std::vector<StationList> old_industry_stations_near;
|
||||
for (Industry *ind : Industry::Iterate()) old_industry_stations_near.push_back(ind->stations_near);
|
||||
|
||||
for (Station *st : Station::Iterate()) {
|
||||
for (GoodsEntry &ge : st->goods) {
|
||||
byte buff[sizeof(StationCargoList)];
|
||||
memcpy(buff, &ge.cargo, sizeof(StationCargoList));
|
||||
ge.cargo.InvalidateCache();
|
||||
assert(memcmp(&ge.cargo, buff, sizeof(StationCargoList)) == 0);
|
||||
}
|
||||
|
||||
/* Check docking tiles */
|
||||
TileArea ta;
|
||||
std::map<TileIndex, bool> docking_tiles;
|
||||
for (TileIndex tile : st->docking_station) {
|
||||
ta.Add(tile);
|
||||
docking_tiles[tile] = IsDockingTile(tile);
|
||||
}
|
||||
UpdateStationDockingTiles(st);
|
||||
if (ta.tile != st->docking_station.tile || ta.w != st->docking_station.w || ta.h != st->docking_station.h) {
|
||||
Debug(desync, 2, "warning: station docking mismatch: station {}, company {}", st->index, st->owner);
|
||||
}
|
||||
for (TileIndex tile : ta) {
|
||||
if (docking_tiles[tile] != IsDockingTile(tile)) {
|
||||
Debug(desync, 2, "warning: docking tile mismatch: tile {}", tile);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check industries_near */
|
||||
IndustryList industries_near = st->industries_near;
|
||||
st->RecomputeCatchment();
|
||||
if (st->industries_near != industries_near) {
|
||||
Debug(desync, 2, "warning: station industries near mismatch: station {}", st->index);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check stations_near */
|
||||
i = 0;
|
||||
for (Town *t : Town::Iterate()) {
|
||||
if (t->stations_near != old_town_stations_near[i]) {
|
||||
Debug(desync, 2, "warning: town stations near mismatch: town {}", t->index);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
for (Industry *ind : Industry::Iterate()) {
|
||||
if (ind->stations_near != old_industry_stations_near[i]) {
|
||||
Debug(desync, 2, "warning: industry stations near mismatch: industry {}", ind->index);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* State controlling game loop.
|
||||
@@ -1485,7 +1263,7 @@ void StateGameLoop()
|
||||
|
||||
/* All these actions has to be done from OWNER_NONE
|
||||
* for multiplayer compatibility */
|
||||
Backup<CompanyID> cur_company(_current_company, OWNER_NONE, FILE_LINE);
|
||||
Backup<CompanyID> cur_company(_current_company, OWNER_NONE);
|
||||
|
||||
BasePersistentStorageArray::SwitchMode(PSM_ENTER_GAMELOOP);
|
||||
AnimateAnimatedTiles();
|
||||
|
||||
Reference in New Issue
Block a user