diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 82212abda8..4cda3f91a7 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -44,6 +44,7 @@ void ClearEnginesHiddenFlagOfCompany(CompanyID cid); CompanyID _local_company; ///< Company controlled by the human player at this client. Can also be #COMPANY_SPECTATOR. CompanyID _current_company; ///< Company currently doing an action. +CompanyID _loaded_local_company; ///< Local company in loaded savegame Colours _company_colours[MAX_COMPANIES]; ///< NOSAVE: can be determined from company structs. CompanyManagerFace _company_manager_face; ///< for company manager face storage in openttd.cfg uint _next_competitor_start; ///< the number of ticks before the next AI is started @@ -1184,6 +1185,20 @@ int CompanyServiceInterval(const Company *c, VehicleType type) } } +/** + * Get the default local company after loading a new game + */ +CompanyID GetDefaultLocalCompany() +{ + if (_loaded_local_company >= COMPANY_FIRST && _loaded_local_company < MAX_COMPANIES && Company::IsValidID(_loaded_local_company)) { + return _loaded_local_company; + } + for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) { + if (Company::IsValidID(i)) return i; + } + return COMPANY_FIRST; +} + /** * Get total sum of all owned road bits. * @return Combined total road road bits. diff --git a/src/company_func.h b/src/company_func.h index 01f5859104..fd0de0c90b 100644 --- a/src/company_func.h +++ b/src/company_func.h @@ -32,6 +32,7 @@ CommandCost CheckTileOwnership(TileIndex tile); extern CompanyID _local_company; extern CompanyID _current_company; +extern CompanyID _loaded_local_company; extern Colours _company_colours[MAX_COMPANIES]; extern CompanyManagerFace _company_manager_face; @@ -57,4 +58,6 @@ static inline bool IsInteractiveCompany(CompanyID company) int CompanyServiceInterval(const Company *c, VehicleType type); +CompanyID GetDefaultLocalCompany(); + #endif /* COMPANY_FUNC_H */ diff --git a/src/misc.cpp b/src/misc.cpp index 1123f0d050..332b6edc64 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -81,6 +81,7 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin _cur_tileloop_tile = 1; _thd.redsq = INVALID_TILE; _road_layout_change_counter = 0; + _loaded_local_company = COMPANY_SPECTATOR; _game_events_since_load = (GameEventFlags) 0; _game_events_overall = (GameEventFlags) 0; _game_load_cur_date_ymd = { 0, 0, 0 }; diff --git a/src/network/network.cpp b/src/network/network.cpp index b517b7a11c..503a4c9de5 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -717,7 +717,7 @@ static void NetworkInitGameInfo() /* There should be always space for the server. */ assert(NetworkClientInfo::CanAllocateItem()); NetworkClientInfo *ci = new NetworkClientInfo(CLIENT_ID_SERVER); - ci->client_playas = _network_dedicated ? COMPANY_SPECTATOR : COMPANY_FIRST; + ci->client_playas = _network_dedicated ? COMPANY_SPECTATOR : GetDefaultLocalCompany(); strecpy(ci->client_name, _settings_client.network.client_name, lastof(ci->client_name)); } diff --git a/src/openttd.cpp b/src/openttd.cpp index ce902da30f..ab84690113 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -434,6 +434,7 @@ static void ShutdownGame() ClearCommandLog(); ClearDesyncMsgLog(); + _loaded_local_company = COMPANY_SPECTATOR; _game_events_since_load = (GameEventFlags) 0; _game_events_overall = (GameEventFlags) 0; _game_load_cur_date_ymd = { 0, 0, 0 }; @@ -1233,8 +1234,8 @@ void SwitchToMode(SwitchMode new_mode) 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); + * a company or in the case of a dedicated server a spectator */ + SetLocalCompany(_network_dedicated ? COMPANY_SPECTATOR : GetDefaultLocalCompany()); if (_ctrl_pressed && !_network_dedicated) { DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE); } diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 05f1585317..8e90270d43 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -970,9 +970,8 @@ bool AfterLoadGame() * a company does not exist yet. So create one here. * 1 exception: network-games. Those can have 0 companies * But this exception is not true for non-dedicated network servers! */ - if (!Company::IsValidID(COMPANY_FIRST) && (!_networking || (_networking && _network_server && !_network_dedicated))) { - DoStartupNewCompany(false); - Company *c = Company::Get(COMPANY_FIRST); + if (!Company::IsValidID(GetDefaultLocalCompany()) && (!_networking || (_networking && _network_server && !_network_dedicated))) { + Company *c = DoStartupNewCompany(false); c->settings = _settings_client.company; } diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index 2186f7fa69..be0117c06b 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -44,6 +44,7 @@ #include "../map_func.h" #include "../rev.h" #include "../strings_func.h" +#include "../company_func.h" #include "table/strings.h" #include @@ -62,6 +63,8 @@ static const uint32 _sl_xv_slxi_chunk_version = 0; ///< current version static void loadVL(const SlxiSubChunkInfo *info, uint32 length); static uint32 saveVL(const SlxiSubChunkInfo *info, bool dry_run); +static void loadLC(const SlxiSubChunkInfo *info, uint32 length); +static uint32 saveLC(const SlxiSubChunkInfo *info, bool dry_run); const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_VERSION_LABEL, XSCF_IGNORABLE_ALL, 1, 1, "version_label", saveVL, loadVL, nullptr }, @@ -129,6 +132,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_TOWN_MULTI_BUILDING, XSCF_NULL, 1, 1, "town_multi_building", nullptr, nullptr, nullptr }, { XSLFI_SHIP_LOST_COUNTER, XSCF_NULL, 1, 1, "ship_lost_counter", nullptr, nullptr, nullptr }, { XSLFI_BUILD_OBJECT_RATE_LIMIT,XSCF_NULL, 1, 1, "build_object_rate_limit", nullptr, nullptr, nullptr }, + { XSLFI_LOCAL_COMPANY, XSCF_IGNORABLE_ALL, 1, 1, "local_company", saveLC, loadLC, nullptr }, { XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker }; @@ -627,6 +631,22 @@ static uint32 saveVL(const SlxiSubChunkInfo *info, bool dry_run) return length; } +static void loadLC(const SlxiSubChunkInfo *info, uint32 length) +{ + if (length == 1) { + _loaded_local_company = (CompanyID) ReadBuffer::GetCurrent()->ReadByte(); + } else { + DEBUG(sl, 1, "SLXI chunk: feature: '%s', version: %d, has data of wrong length: %u", info->name, _sl_xv_feature_versions[info->index], length); + ReadBuffer::GetCurrent()->SkipBytes(length); + } +} + +static uint32 saveLC(const SlxiSubChunkInfo *info, bool dry_run) +{ + if (!dry_run) MemoryDumper::GetCurrent()->WriteByte(_local_company); + return 1; +} + extern const ChunkHandler _version_ext_chunk_handlers[] = { { 'SLXI', Save_SLXI, Load_SLXI, nullptr, Load_SLXI, CH_RIFF | CH_LAST}, }; diff --git a/src/saveload/extended_ver_sl.h b/src/saveload/extended_ver_sl.h index c3e6ad9cbe..03056bb73f 100644 --- a/src/saveload/extended_ver_sl.h +++ b/src/saveload/extended_ver_sl.h @@ -86,6 +86,7 @@ enum SlXvFeatureIndex { XSLFI_TOWN_MULTI_BUILDING, ///< Allow multiple stadium/church buildings in a single town XSLFI_SHIP_LOST_COUNTER, ///< Ship lost counter XSLFI_BUILD_OBJECT_RATE_LIMIT, ///< Build object rate limit + XSLFI_LOCAL_COMPANY, ///< Local company ID XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk