diff --git a/regression/regression/result.txt b/regression/regression/result.txt index f77d8c190c..3dd8b60746 100644 --- a/regression/regression/result.txt +++ b/regression/regression/result.txt @@ -1388,7 +1388,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetReliability(): 75 GetMaxSpeed(): 64 GetPrice(): 8203 - GetMaxAge(): 5479 + GetMaxAge(): 5490 GetRunningCost(): 820 GetPower(): 300 GetWeight(): 47 @@ -1532,7 +1532,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetReliability(): 80 GetMaxSpeed(): 112 GetPrice(): 15234 - GetMaxAge(): 7671 + GetMaxAge(): 7686 GetRunningCost(): 1968 GetPower(): 1000 GetWeight(): 131 @@ -1550,7 +1550,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetReliability(): 84 GetMaxSpeed(): 128 GetPrice(): 22265 - GetMaxAge(): 7305 + GetMaxAge(): 7320 GetRunningCost(): 2296 GetPower(): 1200 GetWeight(): 162 @@ -3476,7 +3476,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetReliability(): 78 GetMaxSpeed(): 56 GetPrice(): 4921 - GetMaxAge(): 4383 + GetMaxAge(): 4392 GetRunningCost(): 426 GetPower(): 90 GetWeight(): 10 @@ -3602,7 +3602,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetReliability(): 77 GetMaxSpeed(): 48 GetPrice(): 4429 - GetMaxAge(): 5479 + GetMaxAge(): 5490 GetRunningCost(): 421 GetPower(): 120 GetWeight(): 9 @@ -3656,7 +3656,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetReliability(): 92 GetMaxSpeed(): 48 GetPrice(): 4716 - GetMaxAge(): 5479 + GetMaxAge(): 5490 GetRunningCost(): 421 GetPower(): 120 GetWeight(): 9 @@ -3764,7 +3764,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetReliability(): 98 GetMaxSpeed(): 48 GetPrice(): 4511 - GetMaxAge(): 5479 + GetMaxAge(): 5490 GetRunningCost(): 421 GetPower(): 120 GetWeight(): 9 @@ -3818,7 +3818,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetReliability(): 97 GetMaxSpeed(): 48 GetPrice(): 4306 - GetMaxAge(): 5479 + GetMaxAge(): 5490 GetRunningCost(): 421 GetPower(): 120 GetWeight(): 9 @@ -3872,7 +3872,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetReliability(): 87 GetMaxSpeed(): 48 GetPrice(): 4388 - GetMaxAge(): 5479 + GetMaxAge(): 5490 GetRunningCost(): 421 GetPower(): 120 GetWeight(): 9 @@ -3926,7 +3926,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetReliability(): 97 GetMaxSpeed(): 48 GetPrice(): 4675 - GetMaxAge(): 5479 + GetMaxAge(): 5490 GetRunningCost(): 421 GetPower(): 120 GetWeight(): 9 @@ -3980,7 +3980,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetReliability(): 98 GetMaxSpeed(): 48 GetPrice(): 4839 - GetMaxAge(): 5479 + GetMaxAge(): 5490 GetRunningCost(): 421 GetPower(): 120 GetWeight(): 9 @@ -4034,7 +4034,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetReliability(): 97 GetMaxSpeed(): 48 GetPrice(): 4962 - GetMaxAge(): 5479 + GetMaxAge(): 5490 GetRunningCost(): 421 GetPower(): 120 GetWeight(): 9 @@ -4088,7 +4088,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetReliability(): 82 GetMaxSpeed(): 48 GetPrice(): 4593 - GetMaxAge(): 5479 + GetMaxAge(): 5490 GetRunningCost(): 421 GetPower(): 120 GetWeight(): 9 @@ -4142,7 +4142,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetReliability(): 76 GetMaxSpeed(): 48 GetPrice(): 5947 - GetMaxAge(): 5479 + GetMaxAge(): 5490 GetRunningCost(): 421 GetPower(): 120 GetWeight(): 9 @@ -5060,7 +5060,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetReliability(): 99 GetMaxSpeed(): 24 GetPrice(): 30468 - GetMaxAge(): 10958 + GetMaxAge(): 10980 GetRunningCost(): 2296 GetPower(): -1 GetWeight(): -1 @@ -5096,7 +5096,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetReliability(): 88 GetMaxSpeed(): 32 GetPrice(): 18281 - GetMaxAge(): 10958 + GetMaxAge(): 10980 GetRunningCost(): 1476 GetPower(): -1 GetWeight(): -1 @@ -5186,7 +5186,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetReliability(): 81 GetMaxSpeed(): 24 GetPrice(): 24375 - GetMaxAge(): 10958 + GetMaxAge(): 10980 GetRunningCost(): 2460 GetPower(): -1 GetWeight(): -1 @@ -5258,7 +5258,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetReliability(): 58 GetMaxSpeed(): 236 GetPrice(): 28710 - GetMaxAge(): 7305 + GetMaxAge(): 7320 GetRunningCost(): 2390 GetPower(): -1 GetWeight(): -1 @@ -5276,7 +5276,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetReliability(): 95 GetMaxSpeed(): 236 GetPrice(): 30761 - GetMaxAge(): 8766 + GetMaxAge(): 8784 GetRunningCost(): 2812 GetPower(): -1 GetWeight(): -1 @@ -5330,7 +5330,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetReliability(): 77 GetMaxSpeed(): 236 GetPrice(): 30761 - GetMaxAge(): 10958 + GetMaxAge(): 10980 GetRunningCost(): 2756 GetPower(): -1 GetWeight(): -1 @@ -9321,8 +9321,8 @@ ERROR: IsEnd() is invalid as Begin() is never called GetEngineType(): 153 GetUnitNumber(): 1 GetAge(): 1 - GetMaxAge(): 5479 - GetAgeLeft(): 5478 + GetMaxAge(): 5490 + GetAgeLeft(): 5489 GetCurrentSpeed(): 7 GetRunningCost(): 421 GetProfitThisYear(): -1 @@ -9414,17 +9414,17 @@ ERROR: IsEnd() is invalid as Begin() is never called 17 => 0 16 => 0 MaxAge ListDump: - 16 => 10958 - 14 => 10958 - 17 => 7305 - 13 => 5479 - 12 => 5479 + 16 => 10980 + 14 => 10980 + 17 => 7320 + 13 => 5490 + 12 => 5490 AgeLeft ListDump: - 16 => 10958 - 14 => 10957 - 17 => 7305 - 13 => 5478 - 12 => 5478 + 16 => 10980 + 14 => 10979 + 17 => 7320 + 13 => 5489 + 12 => 5489 CurrentSpeed ListDump: 12 => 27 17 => 0 diff --git a/src/3rdparty/catch2/catch.hpp b/src/3rdparty/catch2/catch.hpp index 9b309bddc6..109698a5c2 100644 --- a/src/3rdparty/catch2/catch.hpp +++ b/src/3rdparty/catch2/catch.hpp @@ -5922,7 +5922,7 @@ namespace Catch { } void testCaseEnded(TestCaseStats const& testCaseStats) override { auto node = std::make_shared(testCaseStats); - assert(m_sectionStack.size() == 0); + assert(m_sectionStack.empty()); node->children.push_back(m_rootSection); m_testCases.push_back(node); m_rootSection.reset(); diff --git a/src/3rdparty/squirrel/squirrel/sqbaselib.cpp b/src/3rdparty/squirrel/squirrel/sqbaselib.cpp index c60bd3fe2e..051b03a514 100644 --- a/src/3rdparty/squirrel/squirrel/sqbaselib.cpp +++ b/src/3rdparty/squirrel/squirrel/sqbaselib.cpp @@ -762,7 +762,7 @@ static SQInteger closure_getinfos(HSQUIRRELVM v) { res->NewSlot(SQString::Create(_ss(v),"name",-1),nc->_name); res->NewSlot(SQString::Create(_ss(v),"paramscheck",-1),nc->_nparamscheck); SQObjectPtr typecheck; - if(nc->_typecheck.size() > 0) { + if(!nc->_typecheck.empty()) { typecheck = SQArray::Create(_ss(v), nc->_typecheck.size()); for(SQUnsignedInteger n = 0; n_typecheck.size(); n++) { diff --git a/src/3rdparty/squirrel/squirrel/sqfuncstate.cpp b/src/3rdparty/squirrel/squirrel/sqfuncstate.cpp index 2baca100e0..7111a79e90 100644 --- a/src/3rdparty/squirrel/squirrel/sqfuncstate.cpp +++ b/src/3rdparty/squirrel/squirrel/sqfuncstate.cpp @@ -563,7 +563,7 @@ void SQFuncState::PopChildState() SQFuncState::~SQFuncState() { - while(_childstates.size() > 0) + while(!_childstates.empty()) { PopChildState(); } diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp index 753f3df9f0..ce6f7a21c9 100644 --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.cpp @@ -98,7 +98,7 @@ struct AIConfigWindow : public Window { this->OnInvalidateData(0); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { CloseWindowByClass(WC_SCRIPT_LIST); CloseWindowByClass(WC_SCRIPT_SETTINGS); @@ -279,7 +279,7 @@ struct AIConfigWindow : public Window { this->SetWidgetDisabledState(WID_AIC_DECREASE_INTERVAL, GetGameSettings().difficulty.competitors_interval == MIN_COMPETITORS_INTERVAL); this->SetWidgetDisabledState(WID_AIC_INCREASE_INTERVAL, GetGameSettings().difficulty.competitors_interval == MAX_COMPETITORS_INTERVAL); this->SetWidgetDisabledState(WID_AIC_CHANGE, this->selected_slot == INVALID_COMPANY); - this->SetWidgetDisabledState(WID_AIC_CONFIGURE, this->selected_slot == INVALID_COMPANY || AIConfig::GetConfig(this->selected_slot)->GetConfigList()->size() == 0); + this->SetWidgetDisabledState(WID_AIC_CONFIGURE, this->selected_slot == INVALID_COMPANY || AIConfig::GetConfig(this->selected_slot)->GetConfigList()->empty()); this->SetWidgetDisabledState(WID_AIC_MOVE_UP, this->selected_slot == INVALID_COMPANY || !IsEditable((CompanyID)(this->selected_slot - 1))); this->SetWidgetDisabledState(WID_AIC_MOVE_DOWN, this->selected_slot == INVALID_COMPANY || !IsEditable((CompanyID)(this->selected_slot + 1))); diff --git a/src/ai/ai_scanner.cpp b/src/ai/ai_scanner.cpp index 2f6456f101..993137312e 100644 --- a/src/ai/ai_scanner.cpp +++ b/src/ai/ai_scanner.cpp @@ -95,7 +95,7 @@ AIInfo *AIScannerInfo::SelectRandomAI() const AIInfo *AIScannerInfo::FindInfo(const std::string &name, int version, bool force_exact_match) { - if (this->info_list.size() == 0) return nullptr; + if (this->info_list.empty()) return nullptr; if (name.empty()) return nullptr; if (version == -1) { diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index f64ae074ae..b926645b31 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -1474,9 +1474,9 @@ static void MaybeCrashAirplane(Aircraft *v) if (GB(Random(), 0, 22) > prob) return; /* Crash the airplane. Remove all goods stored at the station. */ - for (CargoID i = 0; i < NUM_CARGO; i++) { - st->goods[i].rating = 1; - if (st->goods[i].data != nullptr) st->goods[i].data->cargo.Truncate(); + for (GoodsEntry &ge : st->goods) { + ge.rating = 1; + if (ge.data != nullptr) ge.data->cargo.Truncate(); } CrashAirplane(v); diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index 8f0220790e..08066b3c1f 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -78,7 +78,7 @@ struct BuildAirToolbarWindow : Window { this->last_user_action = INVALID_WID_AT; } - void Close() override + void Close([[maybe_unused]] int data = 0) override { if (this->IsWidgetLowered(WID_AT_AIRPORT)) SetViewportCatchmentStation(nullptr, true); if (_settings_client.gui.link_terraform_toolbar) CloseWindowById(WC_SCEN_LAND_GEN, 0, false); @@ -233,7 +233,7 @@ class BuildAirportWindow : public PickerWindowBase { DropDownList list; for (uint i = 0; AirportClass::IsClassIDValid((AirportClassID)i); i++) { - list.emplace_back(new DropDownListStringItem(AirportClass::Get((AirportClassID)i)->name, i, false)); + list.push_back(std::make_unique(AirportClass::Get((AirportClassID)i)->name, i, false)); } return list; @@ -277,7 +277,7 @@ public: if (selectFirstAirport) this->SelectFirstAvailableAirport(true); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { CloseWindowById(WC_SELECT_STATION, 0); this->PickerWindowBase::Close(); diff --git a/src/articulated_vehicles.cpp b/src/articulated_vehicles.cpp index 53cc72fe9b..d0db9205c3 100644 --- a/src/articulated_vehicles.cpp +++ b/src/articulated_vehicles.cpp @@ -393,7 +393,7 @@ void CheckConsistencyOfArticulatedVehicle(const Vehicle *v) CargoTypes real_refit_union = 0; CargoTypes real_refit_intersection = ALL_CARGOTYPES; - CargoArray real_default_capacity{}; + CargoTypes real_default_cargoes = 0; do { CargoTypes refit_mask = GetAvailableVehicleCargoTypes(v->engine_type, true); @@ -401,17 +401,15 @@ void CheckConsistencyOfArticulatedVehicle(const Vehicle *v) if (refit_mask != 0) real_refit_intersection &= refit_mask; assert(v->cargo_type < NUM_CARGO || (v->type == VEH_TRAIN && Train::From(v)->IsVirtual())); - if (v->cargo_type < NUM_CARGO) { - real_default_capacity[v->cargo_type] += v->cargo_cap; - } + if (v->cargo_cap > 0) SetBit(real_default_cargoes, v->cargo_type); v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : nullptr; } while (v != nullptr); /* Check whether the vehicle carries more cargoes than expected */ bool carries_more = false; - for (CargoID cid = 0; cid < NUM_CARGO; cid++) { - if (real_default_capacity[cid] != 0 && purchase_default_capacity[cid] == 0) { + for (CargoID cid : SetCargoBitIterator(real_default_cargoes)) { + if (purchase_default_capacity[cid] == 0) { carries_more = true; break; } diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index a1618b283f..63230436dc 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -173,11 +173,15 @@ class ReplaceVehicleWindow : public Window { if (!CheckAutoreplaceValidity(this->sel_engine[0], eid, _local_company)) continue; } - EngineDisplayFlags flags = (side == 0) ? EngineDisplayFlags::None : e->display_flags; - if (side == 1 && eid == this->sel_engine[0]) flags |= EngineDisplayFlags::Shaded; - list.emplace_back(eid, e->info.variant_id, flags, 0); + list.emplace_back(eid, e->info.variant_id, (side == 0) ? EngineDisplayFlags::None : e->display_flags, 0); - if (side == 1 && e->info.variant_id != INVALID_ENGINE) variants.push_back(e->info.variant_id); + if (side == 1) { + EngineID parent = e->info.variant_id; + while (parent != INVALID_ENGINE) { + variants.push_back(parent); + parent = Engine::Get(parent)->info.variant_id; + } + } if (eid == this->sel_engine[side]) selected_engine = eid; // The selected engine is still in the list } @@ -216,7 +220,7 @@ class ReplaceVehicleWindow : public Window { /* We need to rebuild the left engines list */ this->GenerateReplaceVehList(true); this->vscroll[0]->SetCount(this->engines[0].size()); - if (this->reset_sel_engine && this->sel_engine[0] == INVALID_ENGINE && this->engines[0].size() != 0) { + if (this->reset_sel_engine && this->sel_engine[0] == INVALID_ENGINE && !this->engines[0].empty()) { this->sel_engine[0] = this->engines[0][0].engine_id; } } @@ -564,8 +568,8 @@ public: case WID_RV_TRAIN_ENGINEWAGON_DROPDOWN: { DropDownList list; - list.emplace_back(new DropDownListStringItem(STR_REPLACE_ENGINES, 1, false)); - list.emplace_back(new DropDownListStringItem(STR_REPLACE_WAGONS, 0, false)); + list.push_back(std::make_unique(STR_REPLACE_ENGINES, 1, false)); + list.push_back(std::make_unique(STR_REPLACE_WAGONS, 0, false)); ShowDropDownList(this, std::move(list), this->replace_engines ? 1 : 0, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN); break; } diff --git a/src/base_media_base.h b/src/base_media_base.h index 64abe82bb0..272aec82ea 100644 --- a/src/base_media_base.h +++ b/src/base_media_base.h @@ -95,7 +95,7 @@ struct BaseSet { return Tnum_files - this->valid_files; } - bool FillSetDetails(IniFile *ini, const std::string &path, const std::string &full_filename, bool allow_empty_filename = true); + bool FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename, bool allow_empty_filename = true); /** * Get the description for the given ISO code. @@ -244,7 +244,7 @@ struct GraphicsSet : BaseSet { PaletteType palette; ///< Palette of this graphics set BlitterType blitter; ///< Blitter of this graphics set - bool FillSetDetails(struct IniFile *ini, const std::string &path, const std::string &full_filename); + bool FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename); static MD5File::ChecksumResult CheckMD5(const MD5File *file, Subdirectory subdir); }; @@ -301,7 +301,7 @@ struct MusicSet : BaseSet { /** Number of valid songs in set. */ byte num_available; - bool FillSetDetails(struct IniFile *ini, const std::string &path, const std::string &full_filename); + bool FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename); }; /** All data/functions related with replacing the base music */ diff --git a/src/base_media_func.h b/src/base_media_func.h index e23ac3f06f..9586f0f9ac 100644 --- a/src/base_media_func.h +++ b/src/base_media_func.h @@ -38,10 +38,15 @@ extern void CheckExternalFiles(); * @return true if loading was successful. */ template -bool BaseSet::FillSetDetails(IniFile *ini, const std::string &path, const std::string &full_filename, bool allow_empty_filename) +bool BaseSet::FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename, bool allow_empty_filename) { - IniGroup *metadata = ini->GetGroup("metadata"); - IniItem *item; + const IniGroup *metadata = ini.GetGroup("metadata"); + if (metadata == nullptr) { + DEBUG(grf, 0, "Base " SET_TYPE "set detail loading: metadata missing."); + DEBUG(grf, 0, " Is %s readable for the user running OpenTTD?", full_filename.c_str()); + return false; + } + const IniItem *item; fetch_metadata("name"); this->name = *item->value; @@ -50,10 +55,10 @@ bool BaseSet::FillSetDetails(IniFile *ini, const this->description[std::string{}] = *item->value; /* Add the translations of the descriptions too. */ - for (item = metadata->item; item != nullptr; item = item->next) { - if (item->name.compare(0, 12, "description.") != 0) continue; + for (const IniItem &titem : metadata->items) { + if (titem.name.compare(0, 12, "description.") != 0) continue; - this->description[item->name.substr(12)] = item->value.value_or(""); + this->description[titem.name.substr(12)] = titem.value.value_or(""); } fetch_metadata("shortname"); @@ -68,13 +73,13 @@ bool BaseSet::FillSetDetails(IniFile *ini, const this->fallback = (item != nullptr && item->value && *item->value != "0" && *item->value != "false"); /* For each of the file types we want to find the file, MD5 checksums and warning messages. */ - IniGroup *files = ini->GetGroup("files"); - IniGroup *md5s = ini->GetGroup("md5s"); - IniGroup *origin = ini->GetGroup("origin"); + const IniGroup *files = ini.GetGroup("files"); + const IniGroup *md5s = ini.GetGroup("md5s"); + const IniGroup *origin = ini.GetGroup("origin"); for (uint i = 0; i < Tnum_files; i++) { MD5File *file = &this->files[i]; /* Find the filename first. */ - item = files->GetItem(BaseSet::file_names[i]); + item = files != nullptr ? files->GetItem(BaseSet::file_names[i]) : nullptr; if (item == nullptr || (!item->value.has_value() && !allow_empty_filename)) { DEBUG(grf, 0, "No " SET_TYPE " file for: %s (in %s)", BaseSet::file_names[i], full_filename.c_str()); return false; @@ -92,7 +97,7 @@ bool BaseSet::FillSetDetails(IniFile *ini, const file->filename = path + filename; /* Then find the MD5 checksum */ - item = md5s->GetItem(filename); + item = md5s != nullptr ? md5s->GetItem(filename) : nullptr; if (item == nullptr || !item->value.has_value()) { DEBUG(grf, 0, "No MD5 checksum specified for: %s (in %s)", filename.c_str(), full_filename.c_str()); return false; @@ -118,8 +123,8 @@ bool BaseSet::FillSetDetails(IniFile *ini, const } /* Then find the warning message when the file's missing */ - item = origin->GetItem(filename); - if (item == nullptr) item = origin->GetItem("default"); + item = origin != nullptr ? origin->GetItem(filename) : nullptr; + if (item == nullptr) item = origin != nullptr ? origin->GetItem("default") : nullptr; if (item == nullptr || !item->value.has_value()) { DEBUG(grf, 1, "No origin warning message specified for: %s", filename.c_str()); file->missing_warning.clear(); @@ -158,9 +163,9 @@ bool BaseMedia::AddFile(const std::string &filename, size_t basepath_ DEBUG(grf, 1, "Checking %s for base " SET_TYPE " set", filename.c_str()); Tbase_set *set = new Tbase_set(); - IniFile *ini = new IniFile(); + IniFile ini{}; std::string path{ filename, basepath_length }; - ini->LoadFromDisk(path, BASESET_DIR); + ini.LoadFromDisk(path, BASESET_DIR); auto psep = path.rfind(PATHSEPCHAR); if (psep != std::string::npos) { @@ -217,7 +222,6 @@ bool BaseMedia::AddFile(const std::string &filename, size_t basepath_ delete set; } - delete ini; return ret; } diff --git a/src/blitter/factory.hpp b/src/blitter/factory.hpp index 51799c79ad..e03d5f2934 100644 --- a/src/blitter/factory.hpp +++ b/src/blitter/factory.hpp @@ -121,7 +121,7 @@ public: #else const char *default_blitter = "8bpp-optimized"; #endif - if (GetBlitters().size() == 0) return nullptr; + if (GetBlitters().empty()) return nullptr; const char *bname = name.empty() ? default_blitter : name.c_str(); for (auto &it : GetBlitters()) { diff --git a/src/bootstrap_gui.cpp b/src/bootstrap_gui.cpp index 2d0c5e1254..c33db460b2 100644 --- a/src/bootstrap_gui.cpp +++ b/src/bootstrap_gui.cpp @@ -91,7 +91,7 @@ public: this->InitNested(1); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { _exit_game = true; this->Window::Close(); @@ -149,7 +149,7 @@ public: { } - void Close() override + void Close([[maybe_unused]] int data = 0) override { /* If we are not set to exit the game, it means the bootstrap failed. */ if (!_exit_game) { @@ -207,7 +207,7 @@ public: } /** Stop listening to the content client events. */ - void Close() override + void Close([[maybe_unused]] int data = 0) override { _network_content_client.RemoveCallback(this); this->Window::Close(); diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp index 2655bf5e07..020f3cacb1 100644 --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.cpp @@ -183,7 +183,7 @@ public: this->vscroll->SetCount(this->bridges.size()); } - void Close() override + void Close(int data = 0) override { this->last_sorting = this->bridges.GetListing(); this->Window::Close(); diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 565703aca4..661fb4fbff 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -780,11 +780,12 @@ static uint GetCargoWeight(const CargoArray &cap, VehicleType vtype) static int DrawCargoCapacityInfo(int left, int right, int y, TestedEngineDetails &te, bool refittable) { - for (CargoID c = 0; c < NUM_CARGO; c++) { - if (te.all_capacities[c] == 0) continue; + for (const CargoSpec *cs : _sorted_cargo_specs) { + CargoID cid = cs->Index(); + if (te.all_capacities[cid] == 0) continue; - SetDParam(0, c); - SetDParam(1, te.all_capacities[c]); + SetDParam(0, cid); + SetDParam(1, te.all_capacities[cid]); SetDParam(2, refittable ? STR_PURCHASE_INFO_REFITTABLE : STR_EMPTY); DrawString(left, right, y, STR_PURCHASE_INFO_CAPACITY); y += FONT_HEIGHT_NORMAL; @@ -1694,7 +1695,14 @@ struct BuildVehicleWindow : BuildVehicleWindowBase { list.emplace_back(eid, e->info.variant_id, e->display_flags, 0); if (rvi->railveh_type != RAILVEH_WAGON) num_engines++; - if (e->info.variant_id != eid && e->info.variant_id != INVALID_ENGINE) variants.push_back(e->info.variant_id); + + /* Add all parent variants of this engine to the variant list */ + EngineID parent = e->info.variant_id; + while (parent != INVALID_ENGINE) { + variants.push_back(parent); + parent = Engine::Get(parent)->info.variant_id; + } + if (eid == this->sel_engine) sel_id = eid; } @@ -1835,8 +1843,13 @@ struct BuildVehicleWindow : BuildVehicleWindowBase { /* ensure primary engine of variant group is in list after filtering */ std::vector variants; for (const auto &item : this->eng_list) { - if (item.engine_id != item.variant_id && item.variant_id != INVALID_ENGINE) variants.push_back(item.variant_id); + EngineID parent = item.variant_id; + while (parent != INVALID_ENGINE) { + variants.push_back(parent); + parent = Engine::Get(parent)->info.variant_id; + } } + for (const auto &variant : variants) { if (std::find(this->eng_list.begin(), this->eng_list.end(), variant) == this->eng_list.end()) { const Engine *e = Engine::Get(variant); @@ -1933,13 +1946,14 @@ struct BuildVehicleWindow : BuildVehicleWindowBase { if (cargo == CF_ANY || cargo == CF_ENGINES || cargo == CF_NONE) cargo = CT_INVALID; DoCommandP(this->window_number, sel_eng | (cargo << 24), 0, cmd, callback); - /* Update last used variant and refresh if necessary. */ + /* Update last used variant in hierarchy and refresh if necessary. */ bool refresh = false; - int recursion = 10; /* In case of infinite loop */ - for (Engine *e = Engine::Get(sel_eng); recursion > 0; e = Engine::Get(e->info.variant_id), --recursion) { + EngineID parent = sel_eng; + while (parent != INVALID_ENGINE) { + Engine *e = Engine::Get(parent); refresh |= (e->display_last_variant != sel_eng); e->display_last_variant = sel_eng; - if (e->info.variant_id == INVALID_ENGINE) break; + parent = e->info.variant_id; } if (refresh) { InvalidateWindowData(WC_REPLACE_VEHICLE, this->vehicle_type, 0); // Update the autoreplace window @@ -2629,7 +2643,14 @@ struct BuildVehicleWindowTrainAdvanced final : BuildVehicleWindowBase { if (!FilterByText(state, engine)) continue; list.emplace_back(eid, engine->info.variant_id, engine->display_flags, 0); - if (engine->info.variant_id != eid && engine->info.variant_id != INVALID_ENGINE) variants.push_back(engine->info.variant_id); + + /* Add all parent variants of this engine to the variant list */ + EngineID parent = engine->info.variant_id; + while (parent != INVALID_ENGINE) { + variants.push_back(parent); + parent = Engine::Get(parent)->info.variant_id; + } + if (eid == state.sel_engine) sel_id = eid; } @@ -2695,13 +2716,14 @@ struct BuildVehicleWindowTrainAdvanced final : BuildVehicleWindowBase { if (cargo == CF_ANY || cargo == CF_ENGINES) cargo = CF_NONE; DoCommandP(this->window_number, selected | (cargo << 24), 0, cmd, callback); - /* Update last used variant and refresh if necessary. */ + /* Update last used variant in hierarchy and refresh if necessary. */ bool refresh = false; - int recursion = 10; /* In case of infinite loop */ - for (Engine *e = Engine::Get(selected); recursion > 0; e = Engine::Get(e->info.variant_id), --recursion) { + EngineID parent = selected; + while (parent != INVALID_ENGINE) { + Engine *e = Engine::Get(parent); refresh |= (e->display_last_variant != selected); e->display_last_variant = selected; - if (e->info.variant_id == INVALID_ENGINE) break; + parent = e->info.variant_id; } if (refresh) { InvalidateWindowData(WC_REPLACE_VEHICLE, this->vehicle_type, 0); // Update the autoreplace window diff --git a/src/cargotype.h b/src/cargotype.h index f62bd07f0f..3f305536a4 100644 --- a/src/cargotype.h +++ b/src/cargotype.h @@ -217,4 +217,9 @@ static inline bool IsCargoInClass(CargoID c, CargoClass cc) using SetCargoBitIterator = SetBitIterator; +/** Comparator to sort CargoID by according to desired order. */ +struct CargoIDComparator { + bool operator() (const CargoID &lhs, const CargoID &rhs) const { return _sorted_cargo_types[lhs] < _sorted_cargo_types[rhs]; } +}; + #endif /* CARGOTYPE_H */ diff --git a/src/company_gui.cpp b/src/company_gui.cpp index c6eefd97b3..d446535fc1 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -719,10 +719,10 @@ private: if (default_livery != nullptr) { /* Add COLOUR_END to put the colour out of range, but also allow us to show what the default is */ default_col = (primary ? default_livery->colour1 : default_livery->colour2) + COLOUR_END; - list.emplace_back(new DropDownListColourItem(default_col, false)); + list.push_back(std::make_unique(default_col, false)); } for (uint i = 0; i < lengthof(_colour_dropdown); i++) { - list.emplace_back(new DropDownListColourItem(i, HasBit(used_colours, i))); + list.push_back(std::make_unique(i, HasBit(used_colours, i))); } byte sel = (default_livery == nullptr || HasBit(livery->in_use, primary ? 0 : 1)) ? (primary ? livery->colour1 : livery->colour2) : default_col; @@ -1032,7 +1032,7 @@ public: this->groups.ForceRebuild(); this->BuildGroupList((CompanyID)this->window_number); - if (this->groups.size() > 0) { + if (!this->groups.empty()) { this->sel = this->groups[0]->index; } } @@ -1119,7 +1119,7 @@ public: if (!Group::IsValidID(this->sel)) { this->sel = INVALID_GROUP; - if (this->groups.size() > 0) this->sel = this->groups[0]->index; + if (!this->groups.empty()) this->sel = this->groups[0]->index; } this->SetDirty(); @@ -2895,7 +2895,7 @@ struct BuyCompanyWindow : Window { this->company_value = hostile_takeover ? CalculateHostileTakeoverValue(c) : c->bankrupt_value; } - void Close() override + void Close(int data = 0) override { const Company *c = Company::GetIfValid((CompanyID)this->window_number); if (!this->hostile_takeover && c != nullptr && HasBit(c->bankrupt_asked, this->owner) && _current_company == this->owner) { diff --git a/src/console_gui.cpp b/src/console_gui.cpp index 9b6a1edf94..95c48c1abf 100644 --- a/src/console_gui.cpp +++ b/src/console_gui.cpp @@ -133,7 +133,7 @@ struct IConsoleWindow : Window this->line_offset = GetStringBoundingBox("] ").width + WidgetDimensions::scaled.frametext.left; } - void Close() override + void Close([[maybe_unused]] int data = 0) override { _iconsole_mode = ICONSOLE_CLOSED; VideoDriver::GetInstance()->EditBoxLostFocus(); diff --git a/src/core/kdtree.hpp b/src/core/kdtree.hpp index 431447a8f7..36dee3be8f 100644 --- a/src/core/kdtree.hpp +++ b/src/core/kdtree.hpp @@ -55,7 +55,7 @@ class Kdtree { /** Create one new node in the tree, return its index in the pool */ size_t AddNode(const T &element) { - if (this->free_list.size() == 0) { + if (this->free_list.empty()) { this->nodes.emplace_back(element); return this->nodes.size() - 1; } else { diff --git a/src/core/pool_func.cpp b/src/core/pool_func.cpp index 79ea4b21ce..e59a2de447 100644 --- a/src/core/pool_func.cpp +++ b/src/core/pool_func.cpp @@ -20,7 +20,7 @@ { PoolVector *pools = PoolBase::GetPools(); pools->erase(std::find(pools->begin(), pools->end(), this)); - if (pools->size() == 0) delete pools; + if (pools->empty()) delete pools; } /** diff --git a/src/core/span_type.hpp b/src/core/span_type.hpp index 3275d5d87e..a76fb7bc0f 100644 --- a/src/core/span_type.hpp +++ b/src/core/span_type.hpp @@ -85,7 +85,7 @@ public: constexpr pointer data() const noexcept { return first; } constexpr size_t size() const noexcept { return static_cast( last - first ); } constexpr std::ptrdiff_t ssize() const noexcept { return static_cast( last - first ); } - constexpr bool empty() const noexcept { return size() == 0; } + constexpr bool empty() const noexcept { return this->size() == 0; } constexpr iterator begin() const noexcept { return iterator(first); } constexpr iterator end() const noexcept { return iterator(last); } diff --git a/src/date_gui.cpp b/src/date_gui.cpp index 35806d393c..b84fc02996 100644 --- a/src/date_gui.cpp +++ b/src/date_gui.cpp @@ -81,14 +81,14 @@ struct SetDateWindow : Window { case WID_SD_DAY: for (uint i = 0; i < 31; i++) { - list.emplace_back(new DropDownListStringItem(STR_DAY_NUMBER_1ST + i, i + 1, false)); + list.push_back(std::make_unique(STR_DAY_NUMBER_1ST + i, i + 1, false)); } selected = this->date.day; break; case WID_SD_MONTH: for (uint i = 0; i < 12; i++) { - list.emplace_back(new DropDownListStringItem(STR_MONTH_JAN + i, i, false)); + list.push_back(std::make_unique(STR_MONTH_JAN + i, i, false)); } selected = this->date.month; break; @@ -96,7 +96,7 @@ struct SetDateWindow : Window { case WID_SD_YEAR: for (Year i = this->min_year; i <= this->max_year; i++) { SetDParam(0, i); - list.emplace_back(new DropDownListStringItem(STR_JUST_INT, i, false)); + list.push_back(std::make_unique(STR_JUST_INT, i, false)); } selected = this->date.year; break; diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 6e744c9978..00621c4b4f 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -296,7 +296,7 @@ struct DepotWindow : Window { OrderBackup::Reset(); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { CloseWindowById(WC_BUILD_VEHICLE, this->window_number); CloseWindowById(GetWindowClassForVehicleType(this->type), VehicleListIdentifier(VL_DEPOT_LIST, this->type, this->owner, this->GetDepotIndex()).Pack(), false); @@ -812,7 +812,7 @@ struct DepotWindow : Window { case WID_D_SELL_ALL: /* Only open the confirmation window if there are anything to sell */ - if (this->vehicle_list.size() != 0 || this->wagon_list.size() != 0) { + if (!this->vehicle_list.empty() || !this->wagon_list.empty()) { SetDParam(0, this->type); SetDParam(1, this->GetDepotIndex()); ShowQuery( @@ -877,7 +877,8 @@ struct DepotWindow : Window { /* Build tooltipstring */ std::string details; - for (CargoID cargo_type = 0; cargo_type < NUM_CARGO; cargo_type++) { + for (const CargoSpec *cs : _sorted_cargo_specs) { + CargoID cargo_type = cs->Index(); if (capacity[cargo_type] == 0) continue; SetDParam(0, cargo_type); // {CARGO} #1 diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index 49d83f9169..8caa10eb13 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -106,7 +106,7 @@ struct BuildDocksToolbarWindow : Window { if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { if (_game_mode == GM_NORMAL && this->IsWidgetLowered(WID_DT_STATION)) SetViewportCatchmentStation(nullptr, true); if (_settings_client.gui.link_terraform_toolbar) CloseWindowById(WC_SCEN_LAND_GEN, 0, false); @@ -425,7 +425,7 @@ public: this->LowerWidget(_settings_client.gui.station_show_coverage + BDSW_LT_OFF); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { CloseWindowById(WC_SELECT_STATION, 0); this->PickerWindowBase::Close(); diff --git a/src/driver.cpp b/src/driver.cpp index e3fef51dda..0635d4192d 100644 --- a/src/driver.cpp +++ b/src/driver.cpp @@ -110,7 +110,7 @@ void DriverFactoryBase::SelectDriver(const std::string &name, Driver::Type type) */ bool DriverFactoryBase::SelectDriverImpl(const std::string &name, Driver::Type type) { - if (GetDrivers().size() == 0) return false; + if (GetDrivers().empty()) return false; if (name.empty()) { /* Probe for this driver, but do not fall back to dedicated/null! */ diff --git a/src/engine.cpp b/src/engine.cpp index 64023ccd54..5e81ae93b0 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -486,7 +486,8 @@ uint Engine::GetDisplayMaxTractiveEffort() const */ Date Engine::GetLifeLengthInDays() const { - return DateAtStartOfYear(this->info.lifelength + _settings_game.vehicle.extend_vehicle_life); + /* Assume leap years; this gives the player a bit more than the given amount of years, but never less. */ + return static_cast(this->info.lifelength + _settings_game.vehicle.extend_vehicle_life) * DAYS_IN_LEAP_YEAR; } /** @@ -539,7 +540,7 @@ bool Engine::IsVariantHidden(CompanyID c) const * the last display variant rather than the actual parent variant. */ const Engine *re = this; const Engine *ve = re->GetDisplayVariant(); - while (!(ve->IsHidden(c)) && re->info.variant_id != INVALID_ENGINE && re->info.variant_id != re->index) { + while (!(ve->IsHidden(c)) && re->info.variant_id != INVALID_ENGINE) { re = Engine::Get(re->info.variant_id); ve = re->GetDisplayVariant(); } @@ -668,7 +669,7 @@ void CalcEngineReliability(Engine *e, bool new_month) { /* Get source engine for reliability age. This is normally our engine unless variant reliability syncing is requested. */ Engine *re = e; - while (re->info.variant_id != INVALID_ENGINE && re->info.variant_id != re->index && (re->info.extra_flags & ExtraEngineFlags::SyncReliability) != ExtraEngineFlags::None) { + while (re->info.variant_id != INVALID_ENGINE && (re->info.extra_flags & ExtraEngineFlags::SyncReliability) != ExtraEngineFlags::None) { re = Engine::Get(re->info.variant_id); } @@ -725,7 +726,7 @@ void SetYearEngineAgingStops() /* Base year ending date on half the model life */ YearMonthDay ymd; - ConvertDateToYMD(ei->base_intro + DateAtStartOfYear(ei->lifelength) / 2, &ymd); + ConvertDateToYMD(ei->base_intro + (static_cast(ei->lifelength) * DAYS_IN_LEAP_YEAR) / 2, &ymd); _year_engine_aging_stops = std::max(_year_engine_aging_stops, ymd.year); } @@ -768,7 +769,7 @@ void StartupOneEngine(Engine *e, Date aging_date, uint32 seed, Date no_introduce /* Get parent variant index for syncing reliability via random seed. */ const Engine *re = e; - while (re->info.variant_id != INVALID_ENGINE && re->info.variant_id != re->index && (re->info.extra_flags & ExtraEngineFlags::SyncReliability) != ExtraEngineFlags::None) { + while (re->info.variant_id != INVALID_ENGINE && (re->info.extra_flags & ExtraEngineFlags::SyncReliability) != ExtraEngineFlags::None) { re = Engine::Get(re->info.variant_id); } diff --git a/src/error_gui.cpp b/src/error_gui.cpp index 863cee63ef..8566a3193d 100644 --- a/src/error_gui.cpp +++ b/src/error_gui.cpp @@ -308,7 +308,7 @@ public: this->Close(); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { SetRedErrorSquare(INVALID_TILE); if (_window_system_initialized) ShowFirstError(); diff --git a/src/fileio.cpp b/src/fileio.cpp index c6a5f8911e..6e165e96ba 100644 --- a/src/fileio.cpp +++ b/src/fileio.cpp @@ -14,6 +14,7 @@ #include "fios.h" #include "string_func.h" #include "tar_type.h" +#include "3rdparty/cpp-btree/btree_set.h" #ifdef _WIN32 #include # define access _taccess @@ -84,6 +85,8 @@ static bool IsValidSearchPath(Searchpath sp) static void FillValidSearchPaths(bool only_local_path) { _valid_searchpaths.clear(); + + btree::btree_set seen{}; for (Searchpath sp = SP_FIRST_DIR; sp < NUM_SEARCHPATHS; sp++) { if (only_local_path) { switch (sp) { @@ -97,7 +100,11 @@ static void FillValidSearchPaths(bool only_local_path) } } - if (IsValidSearchPath(sp)) _valid_searchpaths.emplace_back(sp); + if (IsValidSearchPath(sp)) { + if (seen.count(_searchpaths[sp]) != 0) continue; + seen.insert(_searchpaths[sp]); + _valid_searchpaths.emplace_back(sp); + } } } diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index 4ce2dd7ffc..b8e05c9eca 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -409,7 +409,7 @@ public: } } - void Close() override + void Close([[maybe_unused]] int data = 0) override { /* pause is only used in single-player, non-editor mode, non menu mode */ if (!_networking && _game_mode != GM_EDITOR && _game_mode != GM_MENU) { diff --git a/src/game/game_gui.cpp b/src/game/game_gui.cpp index e5fadcdc29..6aa5514089 100644 --- a/src/game/game_gui.cpp +++ b/src/game/game_gui.cpp @@ -111,7 +111,7 @@ struct GSConfigWindow : public Window { this->RebuildVisibleSettings(); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { HideDropDownMenu(this); CloseWindowByClass(WC_SCRIPT_LIST); @@ -318,7 +318,7 @@ struct GSConfigWindow : public Window { DropDownList list; for (int i = config_item.min_value; i <= config_item.max_value; i++) { - list.emplace_back(new DropDownListStringItem(config_item.labels.find(i)->second, i, false)); + list.push_back(std::make_unique(config_item.labels.find(i)->second, i, false)); } ShowDropDownListAt(this, std::move(list), old_val, WID_GSC_SETTING_DROPDOWN, wi_rect, COLOUR_ORANGE); diff --git a/src/game/game_scanner.cpp b/src/game/game_scanner.cpp index 5b9b67f0db..0cc96abded 100644 --- a/src/game/game_scanner.cpp +++ b/src/game/game_scanner.cpp @@ -34,7 +34,7 @@ void GameScannerInfo::RegisterAPI(class Squirrel *engine) GameInfo *GameScannerInfo::FindInfo(const std::string &name, int version, bool force_exact_match) { - if (this->info_list.size() == 0) return nullptr; + if (this->info_list.empty()) return nullptr; if (name.empty()) return nullptr; if (version == -1) { diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index bbe648002e..cbd68e0fe0 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -328,8 +328,8 @@ static const NWidgetPart _nested_heightmap_load_widgets[] = { NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_UP), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD), SetFill(0, 1), EndContainer(), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWNNAME_DROPDOWN), SetDataTip(STR_JUST_STRING, STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP), SetFill(1, 0), - NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_INDUSTRY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWN_PULLDOWN), SetDataTip(STR_JUST_STRING1, STR_NULL), SetFill(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_INDUSTRY_PULLDOWN), SetDataTip(STR_JUST_STRING1, STR_NULL), SetFill(1, 0), EndContainer(), EndContainer(), EndContainer(), @@ -404,7 +404,7 @@ static DropDownList BuildMapsizeDropDown(int other_dimension) for (uint i = MIN_MAP_SIZE_BITS; i <= MAX_MAP_SIZE_BITS; i++) { SetDParam(0, 1LL << i); - list.emplace_back(new DropDownListStringItem((i + other_dimension > MAX_MAP_TILES_BITS) ? STR_RED_INT : STR_JUST_INT, i, false)); + list.push_back(std::make_unique((i + other_dimension > MAX_MAP_TILES_BITS) ? STR_RED_INT : STR_JUST_INT, i, false)); } return list; @@ -417,20 +417,20 @@ static DropDownList BuildTownNameDropDown() /* Add and sort newgrf townnames generators */ const auto &grf_names = GetGRFTownNameList(); for (uint i = 0; i < grf_names.size(); i++) { - list.emplace_back(new DropDownListStringItem(grf_names[i], BUILTIN_TOWNNAME_GENERATOR_COUNT + i, false)); + list.push_back(std::make_unique(grf_names[i], BUILTIN_TOWNNAME_GENERATOR_COUNT + i, false)); } std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc); size_t newgrf_size = list.size(); /* Insert newgrf_names at the top of the list */ if (newgrf_size > 0) { - list.emplace_back(new DropDownListItem(-1, false)); // separator line + list.push_back(std::make_unique(-1, false)); // separator line newgrf_size++; } /* Add and sort original townnames generators */ for (uint i = 0; i < BUILTIN_TOWNNAME_GENERATOR_COUNT; i++) { - list.emplace_back(new DropDownListStringItem(STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH + i, i, false)); + list.push_back(std::make_unique(STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH + i, i, false)); } std::sort(list.begin() + newgrf_size, list.end(), DropDownListStringItem::NatSortFunc); diff --git a/src/gfx.cpp b/src/gfx.cpp index 2dedc78d0b..2ac1738b41 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -696,7 +696,7 @@ int DrawString(int left, int right, int top, std::string_view str, TextColour co } Layouter layout(str, INT32_MAX, colour, fontsize); - if (layout.size() == 0) return 0; + if (layout.empty()) return 0; return DrawLayoutLine(*layout.front(), top, left, right, align, underline, true); } diff --git a/src/gfx_layout_fallback.cpp b/src/gfx_layout_fallback.cpp index c4c510bbc1..0e049eb8e8 100644 --- a/src/gfx_layout_fallback.cpp +++ b/src/gfx_layout_fallback.cpp @@ -39,22 +39,20 @@ class FallbackParagraphLayout : public ParagraphLayouter { public: /** Visual run contains data about the bit of text with the same font. */ class FallbackVisualRun : public ParagraphLayouter::VisualRun { + std::vector glyphs; ///< The glyphs we're drawing. + std::vector positions; ///< The positions of the glyphs. + std::vector glyph_to_char; ///< The char index of the glyphs. + Font *font; ///< The font used to layout these. - GlyphID *glyphs; ///< The glyphs we're drawing. - float *positions; ///< The positions of the glyphs. - int *glyph_to_char; ///< The char index of the glyphs. - int glyph_count; ///< The number of glyphs. public: - FallbackVisualRun(Font *font, const WChar *chars, int glyph_count, int char_offset, int x); - FallbackVisualRun(FallbackVisualRun &&other) noexcept; - ~FallbackVisualRun() override; - const Font *GetFont() const override; - int GetGlyphCount() const override; - const GlyphID *GetGlyphs() const override; - const float *GetPositions() const override; - int GetLeading() const override; - const int *GetGlyphToCharMap() const override; + FallbackVisualRun(Font *font, const char32_t *chars, int glyph_count, int char_offset, int x); + const Font *GetFont() const override { return this->font; } + int GetGlyphCount() const override { return static_cast(this->glyphs.size()); } + const GlyphID *GetGlyphs() const override { return this->glyphs.data(); } + const float *GetPositions() const override { return this->positions.data(); } + int GetLeading() const override { return this->GetFont()->fc->GetHeight(); } + const int *GetGlyphToCharMap() const override { return this->glyph_to_char.data(); } }; /** A single line worth of VisualRuns. */ @@ -111,20 +109,20 @@ public: * @param char_offset This run's offset from the start of the layout input string. * @param x The initial x position for this run. */ -FallbackParagraphLayout::FallbackVisualRun::FallbackVisualRun(Font *font, const WChar *chars, int char_count, int char_offset, int x) : - font(font), glyph_count(char_count) +FallbackParagraphLayout::FallbackVisualRun::FallbackVisualRun(Font *font, const char32_t *chars, int char_count, int char_offset, int x) : + font(font) { const bool isbuiltin = font->fc->IsBuiltInFont(); - this->glyphs = MallocT(this->glyph_count); - this->glyph_to_char = MallocT(this->glyph_count); + this->glyphs.reserve(char_count); + this->glyph_to_char.reserve(char_count); /* Positions contains the location of the begin of each of the glyphs, and the end of the last one. */ - this->positions = MallocT(this->glyph_count * 2 + 2); + this->positions.resize(char_count * 2 + 2); this->positions[0] = x; - for (int i = 0; i < this->glyph_count; i++) { - this->glyphs[i] = font->fc->MapCharToGlyph(chars[i]); + for (int i = 0; i < char_count; i++) { + const GlyphID &glyph_id = this->glyphs.emplace_back(font->fc->MapCharToGlyph(chars[i])); if (isbuiltin) { this->positions[2 * i + 1] = font->fc->GetAscender(); // Apply sprite font's ascender. } else if (chars[i] >= SCC_SPRITE_START && chars[i] <= SCC_SPRITE_END) { @@ -132,85 +130,11 @@ FallbackParagraphLayout::FallbackVisualRun::FallbackVisualRun(Font *font, const } else { this->positions[2 * i + 1] = 0; // No ascender adjustment. } - this->positions[2 * i + 2] = this->positions[2 * i] + font->fc->GetGlyphWidth(this->glyphs[i]); - this->glyph_to_char[i] = char_offset + i; + this->positions[2 * i + 2] = this->positions[2 * i] + font->fc->GetGlyphWidth(glyph_id); + this->glyph_to_char.push_back(char_offset + i); } } -/** Move constructor for visual runs.*/ -FallbackParagraphLayout::FallbackVisualRun::FallbackVisualRun(FallbackVisualRun &&other) noexcept : font(other.font), glyph_count(other.glyph_count) -{ - this->positions = other.positions; - this->glyph_to_char = other.glyph_to_char; - this->glyphs = other.glyphs; - - other.positions = nullptr; - other.glyph_to_char = nullptr; - other.glyphs = nullptr; -} - -/** Free all data. */ -FallbackParagraphLayout::FallbackVisualRun::~FallbackVisualRun() -{ - free(this->positions); - free(this->glyph_to_char); - free(this->glyphs); -} - -/** - * Get the font associated with this run. - * @return The font. - */ -const Font *FallbackParagraphLayout::FallbackVisualRun::GetFont() const -{ - return this->font; -} - -/** - * Get the number of glyphs in this run. - * @return The number of glyphs. - */ -int FallbackParagraphLayout::FallbackVisualRun::GetGlyphCount() const -{ - return this->glyph_count; -} - -/** - * Get the glyphs of this run. - * @return The glyphs. - */ -const GlyphID *FallbackParagraphLayout::FallbackVisualRun::GetGlyphs() const -{ - return this->glyphs; -} - -/** - * Get the positions of this run. - * @return The positions. - */ -const float *FallbackParagraphLayout::FallbackVisualRun::GetPositions() const -{ - return this->positions; -} - -/** - * Get the glyph-to-character map for this visual run. - * @return The glyph-to-character map. - */ -const int *FallbackParagraphLayout::FallbackVisualRun::GetGlyphToCharMap() const -{ - return this->glyph_to_char; -} - -/** - * Get the height of this font. - * @return The height of the font. - */ -int FallbackParagraphLayout::FallbackVisualRun::GetLeading() const -{ - return this->GetFont()->fc->GetHeight(); -} - /** * Get the height of the line. * @return The maximum height of the line. @@ -231,7 +155,7 @@ int FallbackParagraphLayout::FallbackLine::GetLeading() const */ int FallbackParagraphLayout::FallbackLine::GetWidth() const { - if (this->size() == 0) return 0; + if (this->empty()) return 0; /* * The last X position of a run contains is the end of that run. @@ -369,7 +293,7 @@ std::unique_ptr FallbackParagraphLayout::NextLine this->buffer++; } - if (l->size() == 0 || last_char - begin > 0) { + if (l->empty() || last_char - begin > 0) { int w = l->GetWidth(); l->emplace_back(iter->second, begin, last_char - begin, begin - this->buffer_begin, w); } diff --git a/src/gfx_layout_icu.cpp b/src/gfx_layout_icu.cpp index 8c3bf288bb..c2c8171d43 100644 --- a/src/gfx_layout_icu.cpp +++ b/src/gfx_layout_icu.cpp @@ -132,7 +132,7 @@ ICUParagraphLayout::ICUVisualRun::ICUVisualRun(const ICURun &run, int x) : glyphs(run.glyphs), glyph_to_char(run.glyph_to_char), total_advance(run.total_advance), font(run.font) { /* If there are no positions, the ICURun was not Shaped; that should never happen. */ - assert(run.positions.size() != 0); + assert(!run.positions.empty()); this->positions.reserve(run.positions.size()); /* "positions" is an array of x/y. So we need to alternate. */ @@ -380,7 +380,7 @@ std::vector ItemizeStyle(std::vector &runs_current, FontMap &fon runs = ItemizeScript(buff, length, runs); runs = ItemizeStyle(runs, font_mapping); - if (runs.size() == 0) return nullptr; + if (runs.empty()) return nullptr; for (auto &run : runs) { run.Shape(buff, length); diff --git a/src/gfxinit.cpp b/src/gfxinit.cpp index 7c10f6ca82..4c2aa531f1 100644 --- a/src/gfxinit.cpp +++ b/src/gfxinit.cpp @@ -546,12 +546,13 @@ void GfxLoadSprites() DEBUG(sprite, 2, "Completed loading sprite set %d", _settings_game.game_creation.landscape); } -bool GraphicsSet::FillSetDetails(IniFile *ini, const std::string &path, const std::string &full_filename) +bool GraphicsSet::FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename) { bool ret = this->BaseSet::FillSetDetails(ini, path, full_filename, false); if (ret) { - IniGroup *metadata = ini->GetGroup("metadata"); - IniItem *item; + const IniGroup *metadata = ini.GetGroup("metadata"); + assert(metadata != nullptr); /* ret can't be true if metadata isn't present. */ + const IniItem *item; fetch_metadata("palette"); this->palette = ((*item->value)[0] == 'D' || (*item->value)[0] == 'd') ? PAL_DOS : PAL_WINDOWS; diff --git a/src/group_gui.cpp b/src/group_gui.cpp index 1c2e726e56..0935bf60e9 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -447,7 +447,7 @@ public: this->SortVehicleList(); } - void Close() override + void Close(int data = 0) override { *this->sorting = this->vehgroups.GetListing(); this->Window::Close(); @@ -591,7 +591,7 @@ public: /* Disable all lists management button when the list is empty */ this->SetWidgetDisabledState(WID_GL_MANAGE_VEHICLES_DROPDOWN, !this->ShouldShowActionDropdownList() || _local_company != this->vli.company); - this->SetWidgetsDisabledState(this->vehicles.size() == 0 || _local_company != this->vli.company || (IsTopLevelGroupID(this->vli.index) && _settings_client.gui.disable_top_veh_list_mass_actions), + this->SetWidgetsDisabledState(this->vehicles.empty() || _local_company != this->vli.company || (IsTopLevelGroupID(this->vli.index) && _settings_client.gui.disable_top_veh_list_mass_actions), WID_GL_STOP_ALL, WID_GL_START_ALL); diff --git a/src/highscore_gui.cpp b/src/highscore_gui.cpp index a157a6f47a..cafecf0dcc 100644 --- a/src/highscore_gui.cpp +++ b/src/highscore_gui.cpp @@ -122,7 +122,7 @@ struct EndGameWindow : EndGameHighScoreBaseWindow { MarkWholeScreenDirty(); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { if (!_networking) DoCommandP(0, PM_PAUSED_NORMAL, 0, CMD_PAUSE); // unpause if (_game_mode != GM_MENU) ShowHighscoreTable(this->window_number, this->rank); @@ -170,7 +170,7 @@ struct HighScoreWindow : EndGameHighScoreBaseWindow { this->rank = ranking; } - void Close() override + void Close([[maybe_unused]] int data = 0) override { if (_game_mode != GM_MENU) ShowVitalWindows(); diff --git a/src/hotkeys.cpp b/src/hotkeys.cpp index 5a87eed1ab..ee9e672259 100644 --- a/src/hotkeys.cpp +++ b/src/hotkeys.cpp @@ -279,11 +279,12 @@ HotkeyList::~HotkeyList() * Load HotkeyList from IniFile. * @param ini IniFile to load from. */ -void HotkeyList::Load(IniFile *ini) +void HotkeyList::Load(const IniFile &ini) { - IniGroup *group = ini->GetGroup(this->ini_group); + const IniGroup *group = ini.GetGroup(this->ini_group); + if (group == nullptr) return; for (Hotkey *hotkey = this->items; hotkey->name != nullptr; ++hotkey) { - IniItem *item = group->GetItem(hotkey->name); + const IniItem *item = group->GetItem(hotkey->name); if (item != nullptr) { hotkey->keycodes.clear(); if (item->value.has_value()) ParseHotkeys(hotkey, item->value->c_str()); @@ -295,11 +296,11 @@ void HotkeyList::Load(IniFile *ini) * Save HotkeyList to IniFile. * @param ini IniFile to save to. */ -void HotkeyList::Save(IniFile *ini) const +void HotkeyList::Save(IniFile &ini) const { - IniGroup *group = ini->GetGroup(this->ini_group); + IniGroup &group = ini.GetOrCreateGroup(this->ini_group); for (const Hotkey *hotkey = this->items; hotkey->name != nullptr; ++hotkey) { - IniItem &item = group->GetOrCreateItem(hotkey->name); + IniItem &item = group.GetOrCreateItem(hotkey->name); item.SetValue(SaveKeycodes(hotkey)); } } @@ -325,8 +326,8 @@ int HotkeyList::CheckMatch(uint16 keycode, bool global_only) const static void SaveLoadHotkeys(bool save) { - IniFile *ini = new IniFile(); - ini->LoadFromDisk(_hotkeys_file, NO_DIRECTORY); + IniFile ini{}; + ini.LoadFromDisk(_hotkeys_file, NO_DIRECTORY); for (HotkeyList *list : *_hotkey_lists) { if (save) { @@ -336,8 +337,7 @@ static void SaveLoadHotkeys(bool save) } } - if (save) ini->SaveToDisk(_hotkeys_file); - delete ini; + if (save) ini.SaveToDisk(_hotkeys_file); } diff --git a/src/hotkeys.h b/src/hotkeys.h index b39bb486f0..6e0a604eb6 100644 --- a/src/hotkeys.h +++ b/src/hotkeys.h @@ -43,8 +43,8 @@ struct HotkeyList { HotkeyList(const char *ini_group, Hotkey *items, GlobalHotkeyHandlerFunc global_hotkey_handler = nullptr); ~HotkeyList(); - void Load(IniFile *ini); - void Save(IniFile *ini) const; + void Load(const IniFile &ini); + void Save(IniFile &ini) const; int CheckMatch(uint16 keycode, bool global_only = false) const; diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 2f85c50106..3408f473f4 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -2797,7 +2797,7 @@ static void CanCargoServiceIndustry(CargoID cargo, Industry *ind, bool *c_accept */ int WhoCanServiceIndustry(Industry *ind) { - if (ind->stations_near.size() == 0) return 0; // No stations found at all => nobody services + if (ind->stations_near.empty()) return 0; // No stations found at all => nobody services int result = 0; for (const Vehicle *v : Vehicle::Iterate()) { diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 596439c823..a6f02cf0e7 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -1639,7 +1639,7 @@ public: this->industry_editbox.cancel_button = QueryString::ACTION_CLEAR; } - void Close() override + void Close(int data = 0) override { this->last_sorting = this->industries.GetListing(); this->Window::Close(); @@ -1677,7 +1677,7 @@ public: case WID_ID_INDUSTRY_LIST: { int n = 0; Rect ir = r.Shrink(WidgetDimensions::scaled.framerect); - if (this->industries.size() == 0) { + if (this->industries.empty()) { DrawString(ir, STR_INDUSTRY_DIRECTORY_NONE); break; } @@ -1932,11 +1932,6 @@ enum CargoesFieldType { static const uint MAX_CARGOES = 16; ///< Maximum number of cargoes carried in a #CFT_CARGO field in #CargoesField. -static bool CargoIDSorter(const CargoID &a, const CargoID &b) -{ - return _sorted_cargo_types[a] < _sorted_cargo_types[b]; -} - /** Data about a single field in the #IndustryCargoesWindow panel. */ struct CargoesField { static int vert_inter_industry_space; @@ -2066,7 +2061,8 @@ struct CargoesField { } } this->u.cargo.num_cargoes = (count < 0) ? static_cast(insert - std::begin(this->u.cargo.vertical_cargoes)) : count; - std::sort(std::begin(this->u.cargo.vertical_cargoes), insert, &CargoIDSorter); + CargoIDComparator comparator; + std::sort(std::begin(this->u.cargo.vertical_cargoes), insert, comparator); std::fill(insert, std::end(this->u.cargo.vertical_cargoes), CT_INVALID); this->u.cargo.top_end = top_end; this->u.cargo.bottom_end = bottom_end; @@ -2582,8 +2578,7 @@ struct IndustryCargoesWindow : public Window { /* Compute max size of the cargo texts. */ this->cargo_textsize.width = 0; this->cargo_textsize.height = 0; - for (uint i = 0; i < NUM_CARGO; i++) { - const CargoSpec *csp = CargoSpec::Get(i); + for (const CargoSpec *csp : CargoSpec::Iterate()) { if (!csp->IsValid()) continue; this->cargo_textsize = maxdim(this->cargo_textsize, GetStringBoundingBox(csp->name)); } @@ -3107,7 +3102,7 @@ struct IndustryCargoesWindow : public Window { case WID_IC_CARGO_DROPDOWN: { DropDownList lst; for (const CargoSpec *cs : _sorted_standard_cargo_specs) { - lst.emplace_back(new DropDownListStringItem(cs->name, cs->Index(), false)); + lst.push_back(std::make_unique(cs->name, cs->Index(), false)); } if (!lst.empty()) { int selected = (this->ind_cargo >= NUM_INDUSTRYTYPES) ? (int)(this->ind_cargo - NUM_INDUSTRYTYPES) : -1; @@ -3121,7 +3116,7 @@ struct IndustryCargoesWindow : public Window { for (IndustryType ind : _sorted_industry_types) { const IndustrySpec *indsp = GetIndustrySpec(ind); if (!indsp->enabled) continue; - lst.emplace_back(new DropDownListStringItem(indsp->name, ind, false)); + lst.push_back(std::make_unique(indsp->name, ind, false)); } if (!lst.empty()) { int selected = (this->ind_cargo < NUM_INDUSTRYTYPES) ? (int)this->ind_cargo : -1; diff --git a/src/ini.cpp b/src/ini.cpp index 017f5f9030..ce3b34c59a 100644 --- a/src/ini.cpp +++ b/src/ini.cpp @@ -32,9 +32,9 @@ /** * Create a new ini file with given group names. - * @param list_group_names A \c nullptr terminated list with group names that should be loaded as lists instead of variables. @see IGT_LIST + * @param list_group_names A list with group names that should be loaded as lists instead of variables. @see IGT_LIST */ -IniFile::IniFile(const char * const *list_group_names) : IniLoadFile(list_group_names) +IniFile::IniFile(const IniGroupNameList &list_group_names) : IniLoadFile(list_group_names) { } @@ -56,20 +56,20 @@ bool IniFile::SaveToDisk(const std::string &filename) std::ofstream os(OTTD2FS(file_new).c_str()); if (os.fail()) return false; - for (const IniGroup *group = this->group; group != nullptr; group = group->next) { - os << group->comment << "[" << group->name << "]\n"; - for (const IniItem *item = group->item; item != nullptr; item = item->next) { - os << item->comment; + for (const IniGroup &group : this->groups) { + os << group.comment << "[" << group.name << "]\n"; + for (const IniItem &item : group.items) { + os << item.comment; /* protect item->name with quotes if needed */ - if (item->name.find(' ') != std::string::npos || - item->name[0] == '[') { - os << "\"" << item->name << "\""; + if (item.name.find(' ') != std::string::npos || + item.name[0] == '[') { + os << "\"" << item.name << "\""; } else { - os << item->name; + os << item.name; } - os << " = " << item->value.value_or("") << "\n"; + os << " = " << item.value.value_or("") << "\n"; } } os << this->comment; diff --git a/src/ini_load.cpp b/src/ini_load.cpp index e3a4687082..6afe5cb6b8 100644 --- a/src/ini_load.cpp +++ b/src/ini_load.cpp @@ -20,18 +20,9 @@ * @param parent the group we belong to * @param name the name of the item */ -IniItem::IniItem(IniGroup *parent, const std::string &name) : next(nullptr) +IniItem::IniItem(const std::string &name) { this->name = StrMakeValid(name); - - *parent->last_item = this; - parent->last_item = &this->next; -} - -/** Free everything we loaded. */ -IniItem::~IniItem() -{ - delete this->next; } /** @@ -48,37 +39,9 @@ void IniItem::SetValue(const std::string_view value) * @param parent the file we belong to * @param name the name of the group */ -IniGroup::IniGroup(IniLoadFile *parent, const std::string &name) : next(nullptr), type(IGT_VARIABLES), item(nullptr) +IniGroup::IniGroup(const std::string &name, IniGroupType type) : type(type) { this->name = StrMakeValid(name); - - this->last_item = &this->item; - *parent->last_group = this; - parent->last_group = &this->next; - - if (parent->list_group_names != nullptr) { - for (uint i = 0; parent->list_group_names[i] != nullptr; i++) { - if (this->name == parent->list_group_names[i]) { - this->type = IGT_LIST; - return; - } - } - } - if (parent->seq_group_names != nullptr) { - for (uint i = 0; parent->seq_group_names[i] != nullptr; i++) { - if (this->name == parent->seq_group_names[i]) { - this->type = IGT_SEQUENCE; - return; - } - } - } -} - -/** Free everything we loaded. */ -IniGroup::~IniGroup() -{ - delete this->item; - delete this->next; } /** @@ -86,10 +49,10 @@ IniGroup::~IniGroup() * @param name name of the item to find. * @return the requested item or nullptr if not found. */ -IniItem *IniGroup::GetItem(const std::string &name) const +const IniItem *IniGroup::GetItem(const std::string &name) const { - for (IniItem *item = this->item; item != nullptr; item = item->next) { - if (item->name == name) return item; + for (const IniItem &item : this->items) { + if (item.name == name) return &item; } return nullptr; @@ -102,12 +65,22 @@ IniItem *IniGroup::GetItem(const std::string &name) const */ IniItem &IniGroup::GetOrCreateItem(const std::string &name) { - for (IniItem *item = this->item; item != nullptr; item = item->next) { - if (item->name == name) return *item; + for (IniItem &item : this->items) { + if (item.name == name) return item; } /* Item doesn't exist, make a new one. */ - return *(new IniItem(this, name)); + return this->CreateItem(name); +} + +/** + * Create an item with the given name. This does not reuse an existing item of the same name. + * @param name name of the item to create. + * @return the created item. + */ +IniItem &IniGroup::CreateItem(const std::string &name) +{ + return this->items.emplace_back(name); } /** @@ -116,22 +89,7 @@ IniItem &IniGroup::GetOrCreateItem(const std::string &name) */ void IniGroup::RemoveItem(const std::string &name) { - IniItem **prev = &this->item; - - for (IniItem *item = this->item; item != nullptr; prev = &item->next, item = item->next) { - if (item->name != name) continue; - - *prev = item->next; - /* "last_item" is a pointer to the "real-last-item"->next. */ - if (this->last_item == &item->next) { - this->last_item = prev; - } - - item->next = nullptr; - delete item; - - return; - } + this->items.remove_if([&name](const IniItem &item) { return item.name == name; }); } /** @@ -139,81 +97,85 @@ void IniGroup::RemoveItem(const std::string &name) */ void IniGroup::Clear() { - delete this->item; - this->item = nullptr; - this->last_item = &this->item; + this->items.clear(); } /** * Construct a new in-memory Ini file representation. - * @param list_group_names A \c nullptr terminated list with group names that should be loaded as lists instead of variables. @see IGT_LIST - * @param seq_group_names A \c nullptr terminated list with group names that should be loaded as lists of names. @see IGT_SEQUENCE + * @param list_group_names A list with group names that should be loaded as lists instead of variables. @see IGT_LIST + * @param seq_group_names A list with group names that should be loaded as lists of names. @see IGT_SEQUENCE */ -IniLoadFile::IniLoadFile(const char * const *list_group_names, const char * const *seq_group_names) : - group(nullptr), +IniLoadFile::IniLoadFile(const IniGroupNameList &list_group_names, const IniGroupNameList &seq_group_names) : list_group_names(list_group_names), seq_group_names(seq_group_names) { - this->last_group = &this->group; } -/** Free everything we loaded. */ -IniLoadFile::~IniLoadFile() +/** + * Get the group with the given name. + * @param name name of the group to find. + * @return The requested group or \c nullptr if not found. + */ +const IniGroup *IniLoadFile::GetGroup(const std::string &name) const { - delete this->group; + for (const IniGroup &group : this->groups) { + if (group.name == name) return &group; + } + + return nullptr; } /** - * Get the group with the given name. If it doesn't exist - * and \a create_new is \c true create a new group. + * Get the group with the given name. * @param name name of the group to find. - * @param create_new Allow creation of group if it does not exist. - * @return The requested group if it exists or was created, else \c nullptr. + * @return The requested group or \c nullptr if not found. */ -IniGroup *IniLoadFile::GetGroup(const std::string &name, bool create_new) +IniGroup *IniLoadFile::GetGroup(const std::string &name) { - /* does it exist already? */ - for (IniGroup *group = this->group; group != nullptr; group = group->next) { - if (group->name == name) return group; + for (IniGroup &group : this->groups) { + if (group.name == name) return &group; } - if (!create_new) return nullptr; - - /* otherwise make a new one */ - IniGroup *group = new IniGroup(this, name); - group->comment = "\n"; - return group; + return nullptr; } /** - * Remove the group with the given name. - * @param name name of the group to remove. + * Get the group with the given name, and if it doesn't exist create a new group. + * @param name name of the group to find. + * @return the requested group. */ -void IniLoadFile::RemoveGroup(const char *name) +IniGroup &IniLoadFile::GetOrCreateGroup(const std::string &name) { - size_t len = strlen(name); - IniGroup *prev = nullptr; - IniGroup *group; - - /* does it exist already? */ - for (group = this->group; group != nullptr; prev = group, group = group->next) { - if (group->name.compare(0, len, name) == 0) { - break; - } + for (IniGroup &group : this->groups) { + if (group.name == name) return group; } - if (group == nullptr) return; + /* Group doesn't exist, make a new one. */ + return this->CreateGroup(name); +} - if (prev != nullptr) { - prev->next = prev->next->next; - if (this->last_group == &group->next) this->last_group = &prev->next; - } else { - this->group = this->group->next; - if (this->last_group == &group->next) this->last_group = &this->group; - } +/** + * Create an group with the given name. This does not reuse an existing group of the same name. + * @param name name of the group to create. + * @return the created group. + */ +IniGroup &IniLoadFile::CreateGroup(const std::string &name) +{ + IniGroupType type = IGT_VARIABLES; + if (std::find(this->list_group_names.begin(), this->list_group_names.end(), name) != this->list_group_names.end()) type = IGT_LIST; + if (std::find(this->seq_group_names.begin(), this->seq_group_names.end(), name) != this->seq_group_names.end()) type = IGT_SEQUENCE; + + return this->groups.emplace_back(name, type); +} - group->next = nullptr; - delete group; +/** + * Remove the group with the given name. + * @param name name of the group to remove. + */ +void IniLoadFile::RemoveGroup(const std::string &name) +{ + size_t len = name.length(); + this->groups.remove_if([&name, &len](const IniGroup &group) { return group.name.compare(0, len, name) == 0; }); } /** @@ -224,7 +186,7 @@ void IniLoadFile::RemoveGroup(const char *name) */ void IniLoadFile::LoadFromDisk(const std::string &filename, Subdirectory subdir, std::string *save) { - assert(this->last_group == &this->group); + assert(this->groups.empty()); char buffer[1024]; IniGroup *group = nullptr; @@ -281,7 +243,7 @@ void IniLoadFile::LoadFromDisk(const std::string &filename, Subdirectory subdir, e--; } s++; // skip [ - group = new IniGroup(this, std::string(s, e - s)); + group = &this->CreateGroup(std::string(s, e - s)); if (comment_size != 0) { group->comment.assign(comment, comment_size); comment_size = 0; @@ -289,9 +251,9 @@ void IniLoadFile::LoadFromDisk(const std::string &filename, Subdirectory subdir, } else if (group != nullptr) { if (group->type == IGT_SEQUENCE) { /* A sequence group, use the line as item name without further interpretation. */ - IniItem *item = new IniItem(group, std::string(buffer, e - buffer)); + IniItem &item = group->CreateItem(std::string(buffer, e - buffer)); if (comment_size) { - item->comment.assign(comment, comment_size); + item.comment.assign(comment, comment_size); comment_size = 0; } continue; @@ -307,9 +269,9 @@ void IniLoadFile::LoadFromDisk(const std::string &filename, Subdirectory subdir, } /* it's an item in an existing group */ - IniItem *item = new IniItem(group, std::string(s, t - s)); + IniItem &item = group->CreateItem(std::string(s, t - s)); if (comment_size != 0) { - item->comment.assign(comment, comment_size); + item.comment.assign(comment, comment_size); comment_size = 0; } @@ -326,9 +288,9 @@ void IniLoadFile::LoadFromDisk(const std::string &filename, Subdirectory subdir, /* If the value was not quoted and empty, it must be nullptr */ if (!quoted && e == t) { - item->value.reset(); + item.value.reset(); } else { - item->value = StrMakeValid(std::string(t)); + item.value = StrMakeValid(std::string(t)); } } else { /* it's an orphan item */ diff --git a/src/ini_type.h b/src/ini_type.h index fc25257970..a42cb339b1 100644 --- a/src/ini_type.h +++ b/src/ini_type.h @@ -11,6 +11,7 @@ #define INI_TYPE_H #include "fileio_type.h" +#include #include #include @@ -23,48 +24,48 @@ enum IniGroupType { /** A single "line" in an ini file. */ struct IniItem { - IniItem *next; ///< The next item in this group std::string name; ///< The name of this item std::optional value; ///< The value of this item std::string comment; ///< The comment associated with this item - IniItem(struct IniGroup *parent, const std::string &name); - ~IniItem(); + IniItem(const std::string &name); void SetValue(const std::string_view value); }; /** A group within an ini file. */ struct IniGroup { - IniGroup *next; ///< the next group within this file + std::list items; ///< all items in the group IniGroupType type; ///< type of group - IniItem *item; ///< the first item in the group - IniItem **last_item; ///< the last item in the group std::string name; ///< name of group std::string comment; ///< comment for group - IniGroup(struct IniLoadFile *parent, const std::string &name); - ~IniGroup(); + IniGroup(const std::string &name, IniGroupType type); - IniItem *GetItem(const std::string &name) const; + const IniItem *GetItem(const std::string &name) const; IniItem &GetOrCreateItem(const std::string &name); + IniItem &CreateItem(const std::string &name); void RemoveItem(const std::string &name); void Clear(); }; /** Ini file that only supports loading. */ struct IniLoadFile { - IniGroup *group; ///< the first group in the ini - IniGroup **last_group; ///< the last group in the ini + using IniGroupNameList = std::initializer_list; + + std::list groups; ///< all groups in the ini std::string comment; ///< last comment in file - const char * const *list_group_names; ///< nullptr terminated list with group names that are lists - const char * const *seq_group_names; ///< nullptr terminated list with group names that are sequences. + const IniGroupNameList list_group_names; ///< list of group names that are lists + const IniGroupNameList seq_group_names; ///< list of group names that are sequences. - IniLoadFile(const char * const *list_group_names = nullptr, const char * const *seq_group_names = nullptr); - virtual ~IniLoadFile(); + IniLoadFile(const IniGroupNameList &list_group_names = {}, const IniGroupNameList &seq_group_names = {}); + virtual ~IniLoadFile() { } - IniGroup *GetGroup(const std::string &name, bool create_new = true); - void RemoveGroup(const char *name); + const IniGroup *GetGroup(const std::string &name) const; + IniGroup *GetGroup(const std::string &name); + IniGroup &GetOrCreateGroup(const std::string &name); + IniGroup &CreateGroup(const std::string &name); + void RemoveGroup(const std::string &name); void LoadFromDisk(const std::string &filename, Subdirectory subdir, std::string *save = nullptr); @@ -88,7 +89,7 @@ struct IniLoadFile { /** Ini file that supports both loading and saving. */ struct IniFile : IniLoadFile { - IniFile(const char * const *list_group_names = nullptr); + IniFile(const IniGroupNameList &list_group_names = {}); bool SaveToDisk(const std::string &filename); diff --git a/src/lang/afrikaans.txt b/src/lang/afrikaans.txt index e8d65b9783..9b8b0df3a0 100644 --- a/src/lang/afrikaans.txt +++ b/src/lang/afrikaans.txt @@ -4422,7 +4422,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... te n STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... te naby aan 'n ander dorp STR_ERROR_TOO_MANY_TOWNS :{WHITE}... te veel dorpe STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... daar is nie meer spasie oor op die kaart nie -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE} Die dorp sal nie paaie bou nie. Jy kan dit verander deur die bou van paaie via Stellings-> Omgewings-> Dorpe te aktiveer STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Pad werke in verloop STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Kan nie die dorp verwyder nie...{}'n Stasie of depot verwys na die dorp of die blok wat deur die dorp besit word kan nie verwyder word nie. STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... daar is geen plek vir 'n standbeeld in die middel van die dorp diff --git a/src/lang/arabic_egypt.txt b/src/lang/arabic_egypt.txt index 7211ab1ece..74c2a1855b 100644 --- a/src/lang/arabic_egypt.txt +++ b/src/lang/arabic_egypt.txt @@ -4137,7 +4137,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... قر STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... قريبة جدا من مدينة أخرى STR_ERROR_TOO_MANY_TOWNS :{WHITE}... المدن كثيرة جدا STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... لا يوجد فراغ في الخريطة -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}لن تبني البلدية طرق جديدة. بإمكانك تمكين بناء الطرق الجديدة عن طريق الاعدادات --> البيئة--> المدن STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}اعمال الطرق قيد التنفيذ STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}لا يمكن ازالة هذه المدينة{}محطة او ورشة مرتبطة بالمدينة او هناك مربع مملوك للمدينة لا يمكن لزالته STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... لا يوجد مكان مناسب للمجسم بداخل هذة المدينة/البلدة diff --git a/src/lang/basque.txt b/src/lang/basque.txt index 9160311cc1..3ff33f8c38 100644 --- a/src/lang/basque.txt +++ b/src/lang/basque.txt @@ -4171,7 +4171,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... mapa STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... beste herritik hurbilegi STR_ERROR_TOO_MANY_TOWNS :{WHITE}... herri gehiegi STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... ez dago leku gehiagorik mapan -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Herriak ez du errepiderik eraikiko. Herriek errepideak eraiki ahal izateko Ezarpen Aurreratuak->Ekonomia->Herriak STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Errepide lanak egiten STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Geltoki edo gordailu bat herriari lotua dago edo ezin izan da herriaren jabegoa den lauki bat ezabatu STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... ez dago leku egokirik estatua batentzat hiri honen erdian diff --git a/src/lang/belarusian.txt b/src/lang/belarusian.txt index 18b270981f..72f79a995c 100644 --- a/src/lang/belarusian.txt +++ b/src/lang/belarusian.txt @@ -4778,7 +4778,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... за STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... занадта блізка да іншага горада STR_ERROR_TOO_MANY_TOWNS :{WHITE}... занадта шмат гарадоў STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... няма месца на мапе -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Гарады ня будуць будаваць дарогі самі. Вы можаце ўключыць будаўніцтва дарог у раздзеле «Наладкі -> Навак.{NBSP}асяроддзе -> Гарады». STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Ідуць дарожныя работы... STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Немагчыма зьнішчыць горад:{}да яго адносіцца станцыя або дэпо, альбо немагчыма ачысьціць адну з занятых ім клетак. STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... у цэнтры горада няма месца для статуі diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index 7ffca0d45e..4d9ee20d7f 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -4867,7 +4867,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... muit STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... muito perto de outra cidade STR_ERROR_TOO_MANY_TOWNS :{WHITE}... cidades demais STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... não há mais espaço no mapa -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}A cidade não irá construir estradas. Você pode ativar a construção através de Configurações->Ambiente->Cidades STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Recapeamento rodoviário em progresso STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Impossível remover cidade...{}Uma estação ou depósito referente à essa cidade não pode ser removido STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... não há local para uma estátua no centro dessa cidade diff --git a/src/lang/bulgarian.txt b/src/lang/bulgarian.txt index 3f2ac7744d..2e0c77af0b 100644 --- a/src/lang/bulgarian.txt +++ b/src/lang/bulgarian.txt @@ -4251,7 +4251,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... пр STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... прекалено близо до друг град STR_ERROR_TOO_MANY_TOWNS :{WHITE}... прекалено много градове STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... няма повече място на картата -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Градът няма да изгражда пътища. Можете да активирате строенето на пътища чрез Настройки за напреднали->Икономика->Градове. STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Пътни ремонти в процес STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Градът не може да бъде премахнат...{}Станция или депо има връзка с града, или плочка, собственост на града, не може да бъде отстранена STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... няма подходящо място за статуя в центъра на града diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index 2c0603ee2e..9f0dd98122 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -4867,7 +4867,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... mass STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... massa prop d'una altra població STR_ERROR_TOO_MANY_TOWNS :{WHITE}... massa poblacions STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}...no queda espai al mapa. -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}La població no construirà carrers. Pots activar la construcció de carrers via Configuració->Interacció amb l'entorn->Poblacions STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Obres en progrés STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}No es pot eliminar aquesta població...{}Hi ha una estació, un dipòsit o una cel·la pertanyent a la població que no pot ser eliminada STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... no hi ha un lloc adequat per situar l'estàtua al centre d'aquesta població diff --git a/src/lang/croatian.txt b/src/lang/croatian.txt index 32c881136a..12d46ffc16 100644 --- a/src/lang/croatian.txt +++ b/src/lang/croatian.txt @@ -4609,7 +4609,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... preb STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... preblizu drugome gradu STR_ERROR_TOO_MANY_TOWNS :{WHITE}... previše gradova STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... nema više mjesta na karti -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Grad neće graditi ceste. Možete uključiti gradnju cesta putem Postavki->Okolina->Gradovi STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Cestovni radovi u tijeku STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Nije moguće izbrisati ovaj grad...{}Postaja ili spremište se pozivaju na grad ili polja u vlasništvu grada nije moguće ukloniti STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... nema odgovarajućeg mjesta za kip u središtu ovog grada diff --git a/src/lang/czech.txt b/src/lang/czech.txt index 4531d06e13..afe43d495c 100644 --- a/src/lang/czech.txt +++ b/src/lang/czech.txt @@ -4878,7 +4878,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... moc STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... moc blízko k jinému městu STR_ERROR_TOO_MANY_TOWNS :{WHITE}... příliš mnoho měst STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... na mapě už není místo -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Město nebude stavět silnice. Můžete to změnit přes Pokročilé nastavení->Ekonomika->Města STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Silnice je v rekonstrukci STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Nelze vybourat město...{}Buď k němu patří stanice nebo depo, anebo se nedá odklidit políčko městem vlastněné STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... v tomto městě není žádné místo vhodné pro umístění sochy diff --git a/src/lang/danish.txt b/src/lang/danish.txt index 0f0951da53..591476210e 100644 --- a/src/lang/danish.txt +++ b/src/lang/danish.txt @@ -4866,7 +4866,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... for STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... for tæt på en anden by STR_ERROR_TOO_MANY_TOWNS :{WHITE}... for mange byer STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... der er ikke mere plads på kortet -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Byen vil ikke kunne bygge veje. Du kan tillade byer at bygge veje via Avancerede indstillinger->Økonomi->Byer. STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Vejarbejde i gang STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Kan ikke slette denne by...{}En station eller et depot refererer til byen, eller en brik der er ejet a byen kan ikke fjernes STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... Der er ingen egnede steder at placere en statue diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt index 7f370dd7d1..1fd74d2418 100644 --- a/src/lang/dutch.txt +++ b/src/lang/dutch.txt @@ -4866,7 +4866,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... te d STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... te dicht bij een andere plaats STR_ERROR_TOO_MANY_TOWNS :{WHITE}... te veel plaatsen STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... er is geen ruimte meer op de kaart -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}De stad bouwt geen wegen. Het bouwen van wegen kan aangezet worden via Instellingen->Omgeving->Steden STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Wegwerkzaamheden in uitvoering STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Kan deze stad niet verwijderen...{}Een station of depot verwijst naar deze plaats of een door de stad beheerde tegel kan niet worden verwijderd STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... er is geen geschikte plaats voor een standbeeld in het centrum van dit dorp diff --git a/src/lang/english.txt b/src/lang/english.txt index 8f2129a22e..7933975ccb 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -924,10 +924,8 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}New {STR STR_NEWS_SHOW_VEHICLE_GROUP_TOOLTIP :{BLACK}Open the group window focused on the vehicle's group -STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} no longer accepts {STRING} -STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} no longer accepts {STRING} or {STRING} -STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} now accepts {STRING} -STR_NEWS_STATION_NOW_ACCEPTS_CARGO_AND_CARGO :{WHITE}{STATION} now accepts {STRING} and {STRING} +STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_LIST :{WHITE}{STATION} no longer accepts: {CARGO_LIST} +STR_NEWS_STATION_NOW_ACCEPTS_CARGO_LIST :{WHITE}{STATION} now accepts: {CARGO_LIST} STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED :{BIG_FONT}{BLACK}Offer of subsidy expired:{}{}{STRING} from {STRING2} to {STRING2} will now not attract a subsidy STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE :{BIG_FONT}{BLACK}Subsidy withdrawn:{}{}{STRING} service from {STRING2} to {STRING2} is no longer subsidised @@ -4866,7 +4864,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... too STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... too close to another town STR_ERROR_TOO_MANY_TOWNS :{WHITE}... too many towns STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... there is no more space on the map -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}The town will not build roads. You can enable building of roads via Settings->Environment->Towns STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Road works in progress STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Can't delete this town...{}A station or depot is referring to the town or a town owned tile can't be removed STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... there is no suitable place for a statue in the centre of this town diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt index 9902b3158e..20523e2f27 100644 --- a/src/lang/english_AU.txt +++ b/src/lang/english_AU.txt @@ -4866,7 +4866,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... too STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... too close to another town STR_ERROR_TOO_MANY_TOWNS :{WHITE}... too many towns STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... there is no more space on the map -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}The town will not build roads. You can enable building of roads via Advanced Settings->Environment->Towns STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Road works in progress STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Can't delete this town...{}A station or depot is referring to the town or a town owned tile can't be removed STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... there is no suitable place for a statue in the centre of this town diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index b510cf53d6..30e7eefbd6 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -4866,7 +4866,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... too STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... too close to another town STR_ERROR_TOO_MANY_TOWNS :{WHITE}... too many towns STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... there is no more space on the map -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}The town will not build roads. You can enable building of roads via Settings->Environment->Towns STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Road work in progress STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Can't delete this town...{}A station or depot is referring to the town or a town owned tile can't be removed STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... there is no suitable place for a statue in the center of this town diff --git a/src/lang/esperanto.txt b/src/lang/esperanto.txt index aa1022099d..0e83240e87 100644 --- a/src/lang/esperanto.txt +++ b/src/lang/esperanto.txt @@ -4768,7 +4768,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... tro STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... tro proksime al alia urbo STR_ERROR_TOO_MANY_TOWNS :{WHITE}... tro da urboj STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... spaco mankas sur la mapo -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}La urbo ne konstruos stratojn. Vi povas ebligi stratkonstruadon per Avancitaj Agordoj->Ekonomio->Urboj STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Aktivas vojprilaborado STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Ne eblas forviŝi ĉi tiun urbon...{}Stacidomo aŭ garaĝo havas referencon al la urbo, aŭ ne eblas forviŝi kahelon posedatan de la urbo STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... ne jen estas konvenan lokon por statuo en la centro de ĉi tiu urbo diff --git a/src/lang/estonian.txt b/src/lang/estonian.txt index aa34843ced..167ba7bf9d 100644 --- a/src/lang/estonian.txt +++ b/src/lang/estonian.txt @@ -4820,7 +4820,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... liig STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... liiga lähedal teisele asulale STR_ERROR_TOO_MANY_TOWNS :{WHITE}... liiga palju asulaid STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... pole enam ruumi kaardil -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Asula ei ehita teid. Teedeehituse lubamiseks Põhjalik seadistus->Majandus->Asulad STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Teede ehitamine STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Seda asulat ei saa kõrvaldada...{}Jaam või depoo viitab asulale, või asulale kuuluvat ruutu ei saa kõrvaldada STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... asula keskuses ei leidu kujule sobivat kohta diff --git a/src/lang/faroese.txt b/src/lang/faroese.txt index 2bf38a6f3a..e1d125f5e4 100644 --- a/src/lang/faroese.txt +++ b/src/lang/faroese.txt @@ -3826,7 +3826,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... ov t STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... ov tætt við eina aðra bygd STR_ERROR_TOO_MANY_TOWNS :{WHITE}... ov nógvar bygdir STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... tað er einki pláss eftir á kortinum -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Bygdin byggir ikki vegir. Tú kanst tendra vega byggjing í Víðkaðir Innstillingar->Búðskapur->Bygdir STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Veg arbeiði í gongd STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Kann ikki strika hesa bygdina...{}Ein støð ella goymsla vísur til bygdina, ella ein puntur ið er ogn hjá bygdini kann ikki beinast burtur STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... einki hóskandi stað til eina standmynd í miðjuni av hesi bygdini diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index 548742eae0..558d9b7c29 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -4866,7 +4866,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... liia STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... liian lähellä toista kuntaa STR_ERROR_TOO_MANY_TOWNS :{WHITE}... liian monta kuntaa STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... kartalla ei ole enää tilaa -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Kunta ei rakenna teitä. Voit sallia teiden rakentamisen valikosta Asetukset->Ympäristö->Kunnat STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Tietyöt ovat käynnissä. STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Kuntaa ei voida poistaa...{}Asema tai varikko viittaa kuntaan tai kunnan omistamaa ruutua ei voida poistaa STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... tämän kunnan keskustassa ei ole sopivaa paikkaa patsaalle diff --git a/src/lang/french.txt b/src/lang/french.txt index 4a0ae2b3be..a7f79e1ef1 100644 --- a/src/lang/french.txt +++ b/src/lang/french.txt @@ -4867,7 +4867,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... trop STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... trop près d'une autre ville STR_ERROR_TOO_MANY_TOWNS :{WHITE}... trop de villes STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... il n'y a plus d'emplacement sur la carte -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}La ville ne construira pas de routes. Vous pouvez activer la construction des routes sous Paramètres->Environnement->Villes STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Route en travaux STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Impossible de supprimer cette ville...{}Une station ou un dépôt fait référence à cette ville ou une propriété municipale ne peut pas être supprimée. STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... aucun emplacement convenable disponible pour une statue dans ce centre-ville diff --git a/src/lang/gaelic.txt b/src/lang/gaelic.txt index 3a6088e5b2..860d1d4492 100644 --- a/src/lang/gaelic.txt +++ b/src/lang/gaelic.txt @@ -4565,7 +4565,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... ro f STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... ro fhaisg air baile eile STR_ERROR_TOO_MANY_TOWNS :{WHITE}... tha cus bhailtean ann STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... chan eil rum air fhàgail air a' mhapa -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Cha tog am baile rathad sam bith. ’S urrainn dhut togail rathaidean a chur an comas le Roghainnean->Àrainneachd->Bailtean STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Rathad ga ath-thogail STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Cha ghabh am baile seo sguabadh às...{}Tha stèisean no port no garaids no trèan-lann no cala no hangar a' toirt iomradh air a' bhaile no tha leac ann a tha leis a' bhaile is nach gabh toirt air falbh STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... chan eil ionad freagarrach airson ìomhaigh ann am meadhan a' bhaile seo diff --git a/src/lang/galician.txt b/src/lang/galician.txt index 0f1b0b9527..6fff3255e1 100644 --- a/src/lang/galician.txt +++ b/src/lang/galician.txt @@ -4812,7 +4812,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... dema STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... demasiado preto doutra cidade STR_ERROR_TOO_MANY_TOWNS :{WHITE}... hai demasiadas cidades STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... non queda máis espazo no mapa -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}O pobo non construirá estradas. Podes activar a función de construción de estradas en Opcións Avanzadas->Economía->Pobos STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Obras na estrada en curso STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Non se pode borrar esta vila...{}Unha estación ou depósito está relacionado coa vila ou un cadro propiedade da vila non pode ser eliminado STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... non hai ningún sitio adecuado para unha estatua no centro desta vila diff --git a/src/lang/german.txt b/src/lang/german.txt index 2fd4fccd53..62ac1ee6b8 100644 --- a/src/lang/german.txt +++ b/src/lang/german.txt @@ -4843,7 +4843,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... zu d STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... zu dicht an einer anderen Stadt STR_ERROR_TOO_MANY_TOWNS :{WHITE}... zu viele Städte STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... es ist kein Platz mehr auf dem Spielfeld -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Städte bauen im Moment keine Straßen. Städtischer Straßenbau kann mittels Einstellungen->Umgebung->Städte eingestellt werden STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Straßenarbeiten sind im Gange STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Stadt kann nicht gelöscht werden ...{}Eine Station oder ein Depot bezieht sich auf diese Stadt oder ein Feld im städtischen Besitz kann nicht entfernt werden. STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... es gibt keinen geeigneten Standort für die Statue im Zentrum dieser Stadt diff --git a/src/lang/greek.txt b/src/lang/greek.txt index 4ea24dfd03..6d618e91ba 100644 --- a/src/lang/greek.txt +++ b/src/lang/greek.txt @@ -4865,7 +4865,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... πο STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... πολύ κοντά σε άλλη πόλη STR_ERROR_TOO_MANY_TOWNS :{WHITE}... πάρα πολλές πόλεις STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... δεν υπάρχει άλλος χώρος στον χάρτη -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Η πόλη δεν θα οικοδομεί δρόμους. Μπορείτε να ενεργοποιήσετε την κατασκευή οδών μέσω τις Προχωρημένες Επιλογές->Οικονομία->Πόλεις STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Έργα οδοποιίας σε εξέλιξη STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Δεν γίνεται να διαγραφεί η πόλη...{}Ένας σταθμός ή ένα αμαξοστάσιο που αναφέρεται στην πόλη ή ένα τετραγωνίδιο της πόλης δεν μπορεί να αφαιρεθεί STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... δεν υπάρχει κατάλληλο μέρος για άγαλμα στο κέντρο αυτής της πόλης diff --git a/src/lang/hebrew.txt b/src/lang/hebrew.txt index d6a1a633c3..858c138eb5 100644 --- a/src/lang/hebrew.txt +++ b/src/lang/hebrew.txt @@ -4468,7 +4468,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... קר STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... קרוב מידי לעיר אחרת STR_ERROR_TOO_MANY_TOWNS :{WHITE}... יותר מידי ערים STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... אין יותר מקום על המפה -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}העיר לא תבנה כבישים. באפשרותך לאפשר בניית כבישים בעזרת תפריט הגדרות מתקמדות->כלכלה->ערים STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}עבודות כביש בפעולה STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}לא ניתן למחוק עיר זו...{}תחנה או מוסך מקושר לעיר או שמשבצת בבעלות העיר לא ניתנת להסרה STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... אין אף מיקום מתאים לפסל במרכז עיירה זו diff --git a/src/lang/hungarian.txt b/src/lang/hungarian.txt index 9cc9d42167..92df8d2847 100644 --- a/src/lang/hungarian.txt +++ b/src/lang/hungarian.txt @@ -254,6 +254,9 @@ STR_COLOUR_WHITE :Fehér STR_COLOUR_RANDOM :Véletlenszerű ###length 17 +STR_COLOUR_SECONDARY_ORANGE :Narancssárga +STR_COLOUR_SECONDARY_GREY :Szürke +STR_COLOUR_SECONDARY_SAME_AS_PRIMARY :Ugyanaz mint az elsődleges # Units used in OpenTTD @@ -569,6 +572,7 @@ STR_NEWS_MENU_DELETE_ALL_MESSAGES :Az összes üze # About menu ###length 11 STR_ABOUT_MENU_LAND_BLOCK_INFO :Terület-információ +STR_ABOUT_MENU_HELP :Súgó és útmutatók STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Átváltás konzolra STR_ABOUT_MENU_AI_DEBUG :MI / Játékszkript nyomkövetés @@ -1109,6 +1113,13 @@ STR_GAME_OPTIONS_GUI_SCALE_3X :3x STR_GAME_OPTIONS_GUI_SCALE_4X :4x STR_GAME_OPTIONS_GUI_SCALE_5X :5x +STR_GAME_OPTIONS_PARTICIPATE_SURVEY_FRAME :{BLACK}Automata felmérés +STR_GAME_OPTIONS_PARTICIPATE_SURVEY :{BLACK}Részvétel automata felmérésben +STR_GAME_OPTIONS_PARTICIPATE_SURVEY_TOOLTIP :{BLACK}Ha engedélyezve van, az OpenTTD továbbít egy felmérést a játékból kilépéskor +STR_GAME_OPTIONS_PARTICIPATE_SURVEY_LINK :{BLACK}Felmérésről és titoktartásról +STR_GAME_OPTIONS_PARTICIPATE_SURVEY_LINK_TOOLTIP :{BLACK}Ezzel megnyithatsz egy oldalt a böngészőben ahol további információt érhetsz el az automata felmérésről. +STR_GAME_OPTIONS_PARTICIPATE_SURVEY_PREVIEW :{BLACK}Felmérés eredményének előnézete +STR_GAME_OPTIONS_PARTICIPATE_SURVEY_PREVIEW_TOOLTIP :{BLACK}Mutasd a jelenleg futó játékhoz tartozó felmérés eredményeit. STR_GAME_OPTIONS_GRAPHICS :{BLACK}Grafika @@ -1293,6 +1304,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_LEFT :Balra STR_CONFIG_SETTING_HORIZONTAL_POS_CENTER :Középen STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Jobbra +STR_CONFIG_SETTING_SECONDS_VALUE :{COMMA}{NBSP}másodperc{P 0 "" ek} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Maximális kezdeti hitelkeret: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Maximálisan kölcsönözhető összeg (az inflációtól eltekintve) @@ -1464,6 +1476,8 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :nincs* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :csökkentett STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :normál +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR :Más vállalat tulajdonában lévő utak és sínek egyszintű kereszteződésének engedélyezése: {STRING} +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR_HELPTEXT :Engedélyezd más vállalat tulajdonában lévő utak és sínek egyszintű kereszteződésének építését STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Áthaladó megállóhelyek engedélyezése települési tulajdonú utakon: {STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Áthaladó megállóhelyek építésének engedélyezése települési tulajdonú utakon @@ -1477,6 +1491,8 @@ STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :Bekapcsolva az STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR :A vállalat kezdő színsémája: {STRING} STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :A vállalat színsémája a játék kezdetén +STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_SECONDARY :Kezdő vállalat másodlagos színe: {STRING} +STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_SECONDARY_HELPTEXT :Válassz egy másodlagos színt a vállalatnak, ha NewGRF-et használsz ami ezt lehetővé teszi. STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :Repülőterek nem avulnak el: {STRING} STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT :Bekapcsolva minden repülőtértípus örökké elérhető marad bevezetése után @@ -1679,6 +1695,9 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Kikapcsolva STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Ablakok bezárása jobb gombbal: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :A jobb gombbal való kattintás az ablak területén bezárja az ablakot. Ez a beállítás kikapcsolja a segédletek jobb gombbal való megjelenítését! ###length 3 +STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_NO :Nem +STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_YES :Igen +STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_YES_EXCEPT_STICKY :Igen, a zároltakat kivéve STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES :Játékmentés dátumformátuma: {STRING} STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_HELPTEXT :A játékmentésekben használt dátum formátuma @@ -2007,6 +2026,8 @@ STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Átlagos város STR_CONFIG_SETTING_LINKGRAPH_RECALC_INTERVAL :Kapcsolatgrafikon frissítése minden {STRING}{NBSP}másodpercben{P 0:2 "" s} STR_CONFIG_SETTING_LINKGRAPH_RECALC_INTERVAL_HELPTEXT :A kapcsolatgrafikon következő újrakalkulálása között eltelt idő. Minden újrakalkulálás során egy komponens tervei kerülnek kiszámításra. Ez azt jelenti, hogy az X érték beállítása nem jelenti azt, hogy az egész grafikon X másodpercenként frissül. Csak néhány komponens lesz frissítve. Minél rövidebbre van állítva, annál több CPU időre van szükség a kiszámításhoz. Ha hosszabbra van állítva, akkor hosszabb időbe telik, amíg az áruelosztás elkezdődik az új útvonalakon. +STR_CONFIG_SETTING_LINKGRAPH_RECALC_TIME :A kapcsolatgrafikon újrakalkulálására szánt idő, {STRING} +STR_CONFIG_SETTING_LINKGRAPH_RECALC_TIME_HELPTEXT :A kapcsolatgrafikon újrakalkulálására szánt idő. Egy újrakalkulálás megkezdésekor létrejön egy új szál ami ennyi másodpercig futhat. Minél rövidebbre állítod ezt a paramétert annál valószínűbb hogy a számítás nem készül el mire kellene. Ha ez megtörténik akkor a játék megáll amíg el nem készül a számítással ("laggol"). Minél hosszabbra állítod ezt az időt annál hosszabb idő telik el az útvonalak változása és az eloszlás frissítése között. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Utasok szétosztása: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :A "Szimmetrikus" azt jelenti, hogy megközelítóleg ugyanannyi utas megy majd A-ból B-be, mint B-ből A-ba. Az "Aszimmetrikus" beállítás esetén a különbözö irányokba tetszőleges mennyiségű utas mehet. "Kézi" esetben az utasok nem lesznek automatikusan szétosztva. @@ -2139,6 +2160,7 @@ STR_CONFIG_ERROR_SPRITECACHE_TOO_BIG :{WHITE}{BYTES} # Video initalization errors STR_VIDEO_DRIVER_ERROR :{WHITE}Hiba a videobeállításokban... STR_VIDEO_DRIVER_ERROR_NO_HARDWARE_ACCELERATION :{WHITE}... nem található kompatibilis GPU. Hardveres gyorsítás kikapcsolva. +STR_VIDEO_DRIVER_ERROR_HARDWARE_ACCELERATION_CRASH :{WHITE}... A videókártya illesztőprogram hibát okozott. Hardveres gyorsítás kikapcsolva # Intro window STR_INTRO_CAPTION :{WHITE}OpenTTD {REV} @@ -2152,6 +2174,7 @@ STR_INTRO_MULTIPLAYER :{BLACK}Hálóza STR_INTRO_GAME_OPTIONS :{BLACK}Alapbeállítások STR_INTRO_HIGHSCORE :{BLACK}Rekord tábla +STR_INTRO_HELP :{BLACK}Súgó és útmutatók STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Beállítások STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF beállítások STR_INTRO_ONLINE_CONTENT :{BLACK}Letölthető tartalmak @@ -2173,6 +2196,7 @@ STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE :{BLACK}Játékv STR_INTRO_TOOLTIP_GAME_OPTIONS :{BLACK}A játék alapvető beállításainak (pl. nyelv, grafikus alapcsomag, stb.) megjelenítése STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Rekord tábla megjelenítése +STR_INTRO_TOOLTIP_HELP :{BLACK}Férj hozzá a dokumentációhoz és az online tartalmakhoz STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}A beállítások megjelenítése STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}NewGRF beállítások megjelenítése STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Új és frissített tartalmak megtekintése és letöltése @@ -2195,6 +2219,14 @@ STR_ABANDON_GAME_QUERY :{YELLOW}Biztosa STR_ABANDON_SCENARIO_QUERY :{YELLOW}Biztosan abba akarod hagyni a pálya szerkesztését? # Help window +STR_HELP_WINDOW_CAPTION :{BLACK}Súgó és útmutatók +STR_HELP_WINDOW_WEBSITES :{BLACK}Weboldalak +STR_HELP_WINDOW_DOCUMENTS :{BLACK}Dokumentumok +STR_HELP_WINDOW_CHANGELOG :{BLACK}Változtatások listája +STR_HELP_WINDOW_KNOWN_BUGS :{BLACK}Ismert hibák +STR_HELP_WINDOW_MANUAL_WIKI :{BLACK}Útmutató / Wiki +STR_HELP_WINDOW_BUGTRACKER :{BLACK}Hiba jelentése +STR_HELP_WINDOW_COMMUNITY :{BLACK}Közösség # Cheat window STR_CHEATS :{WHITE}Csalások @@ -2471,6 +2503,12 @@ STR_NETWORK_ASK_RELAY_NO :{BLACK}Nem STR_NETWORK_ASK_RELAY_YES_ONCE :{BLACK}Igen, most az egyszer STR_NETWORK_ASK_RELAY_YES_ALWAYS :{BLACK}Igen, ne kérdezd újra +STR_NETWORK_ASK_SURVEY_CAPTION :Részvétel automata felmérésben? +STR_NETWORK_ASK_SURVEY_TEXT :Szeretnél részt venni az automata felmérésben?{}Az OpenTTD a játékból kilépéskor egy felmérést fog továbbítani.{}Ezt a beállítást bármikor megváltoztathatod a "Játék beállítások" menüpontban. +STR_NETWORK_ASK_SURVEY_PREVIEW :Felmérés eredményének előnézete +STR_NETWORK_ASK_SURVEY_LINK :Felmérésről és titoktartásról +STR_NETWORK_ASK_SURVEY_NO :Nem +STR_NETWORK_ASK_SURVEY_YES :Igen STR_NETWORK_SPECTATORS :Megfigyelők @@ -2677,6 +2715,7 @@ STR_TRANSPARENT_BUILDINGS_TOOLTIP :{BLACK}Építhe STR_TRANSPARENT_BRIDGES_TOOLTIP :{BLACK}Hidak átlátszóságának bekapcsolása. Ctrl+kattintással zárolható STR_TRANSPARENT_STRUCTURES_TOOLTIP :{BLACK}Tereptárgyak (adótornyok, világítótornyok stb.) átlátszóságának bekapcsolása. Ctrl+kattintással zárolható STR_TRANSPARENT_CATENARY_TOOLTIP :{BLACK}Felsővezetékek átlátszóságának bekapcsolása. Ctrl+kattintással zárolható +STR_TRANSPARENT_TEXT_TOOLTIP :BLACK}Töltő és ár/bevétel feliratok átlátszóságának bekapcsolása. Ctrl+kattintással zárolható STR_TRANSPARENT_INVISIBLE_TOOLTIP :{BLACK}Az objektum ne átlátszó legyen, hanem láthatatlan # Linkgraph legend window @@ -3407,6 +3446,7 @@ STR_NEWGRF_INSPECT_PARENT_TOOLTIP :{BLACK}Objektum STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT :{STRING} {HEX}-ban STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_OBJECT :Objektum STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_RAIL_TYPE :Pályatípus +STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_ROAD_TYPE :Út típus STR_NEWGRF_INSPECT_QUERY_CAPTION :{WHITE}NewGRF változó 60+x paraméter (hexadecimális) @@ -3813,6 +3853,8 @@ STR_COMPANY_VIEW_INFRASTRUCTURE_BUTTON :{BLACK}Részlet STR_COMPANY_VIEW_INFRASTRUCTURE_TOOLTIP :{BLACK}Részletes információk megtekintése az infrastruktúráról STR_COMPANY_VIEW_GIVE_MONEY_BUTTON :{BLACK}Adományozz pénzt STR_COMPANY_VIEW_GIVE_MONEY_TOOLTIP :{BLACK}Utalj pénzt ennek a vállalatnak +STR_COMPANY_VIEW_HOSTILE_TAKEOVER_BUTTON :{BLACK}Erőszakos átvétel +STR_COMPANY_VIEW_HOSTILE_TAKEOVER_TOOLTIP :{BLACK}Vedd át erőszakkal a vállalat vezetését STR_COMPANY_VIEW_NEW_FACE_BUTTON :{BLACK}Új arc STR_COMPANY_VIEW_NEW_FACE_TOOLTIP :{BLACK}Új arc választása az elnöknek @@ -3828,6 +3870,7 @@ STR_COMPANY_VIEW_PRESIDENT_S_NAME_QUERY_CAPTION :Elnök neve STR_COMPANY_VIEW_GIVE_MONEY_QUERY_CAPTION :Mennyi pénzt szeretnél adományozni? STR_BUY_COMPANY_MESSAGE :{WHITE}Vállalatunk vagyontárgyait eladásra kínáljuk: járművek, terület és hálózat tulajdonok, bankszámla{}{}Megveszed {COMPANY} vállalatot {CURRENCY_LONG}-ért? +STR_BUY_COMPANY_HOSTILE_TAKEOVER :{WHITE}A {COMPANY} erőszakos átvételével megvásárolod minden vagyonát, visszafizeted minden adósságát és kifizeted 2 évi nyereségét.{}{}Mindezek becsült értéke {CURRENCY_LONG}.{}{}Biztosan folytatni akarod ezt az átvételt? # Company infrastructure window STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}{COMPANY} infrastruktúrája @@ -3899,6 +3942,7 @@ STR_VEHICLE_LIST_MANAGE_LIST :{BLACK}Lista ke STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}A listán szereplő járműveknek utasítás küldése STR_VEHICLE_LIST_REPLACE_VEHICLES :Járművek lecserélése STR_VEHICLE_LIST_SEND_FOR_SERVICING :Javításra küld +STR_VEHICLE_LIST_CREATE_GROUP :Csoport létrehozása STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Idei nyereség: {CURRENCY_LONG} (Tavalyi: {CURRENCY_LONG}) STR_VEHICLE_LIST_CARGO :[{CARGO_LIST}] STR_VEHICLE_LIST_NAME_AND_CARGO :{STRING} {STRING} @@ -4716,6 +4760,10 @@ STR_AI_SETTINGS_SETTING :{STRING}: {ORAN # Textfile window +STR_TEXTFILE_JUMPLIST :{WHITE}Tartalomjegyzék +STR_TEXTFILE_JUMPLIST_TOOLTIP :{BLACK}Ugrás egy fejezetre a jelenlegi fileban ezzel a listával +STR_TEXTFILE_NAVBACK_TOOLTIP :{BLACK}Lépj vissza a navigáció történetben +STR_TEXTFILE_NAVFORWARD_TOOLTIP :{BLACK}Lépj előre a navigáció történetben STR_TEXTFILE_WRAP_TEXT :{WHITE}Szöveg törése STR_TEXTFILE_WRAP_TEXT_TOOLTIP :{BLACK}Szöveg törése az ablakban, hogy minden kiférjen és ne kelljen görgetni STR_TEXTFILE_VIEW_README :{BLACK}Readme megtekintése @@ -4725,6 +4773,8 @@ STR_TEXTFILE_VIEW_LICENCE :{BLACK}Licenc STR_TEXTFILE_README_CAPTION :{WHITE}{STRING} {STRING} readme-je STR_TEXTFILE_CHANGELOG_CAPTION :{WHITE}A(z) {STRING} {STRING} változásainak listája STR_TEXTFILE_LICENCE_CAPTION :{WHITE}A(z) {STRING} {STRING} licence +STR_TEXTFILE_SURVEY_RESULT_CAPTION :{WHITE}Felmérés eredményének előnézete +STR_TEXTFILE_GAME_MANUAL_CAPTION :{WHITE}OpenTTD dokumentum '{STRING}' # Vehicle loading indicators @@ -4859,7 +4909,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... túl STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... túl közel van egy másik településhez STR_ERROR_TOO_MANY_TOWNS :{WHITE}... túl sok a település STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... nincs több hely a térképen -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}A település nem fog utakat építeni. Az útépítést a Haladó beállítások->Környezet->Települések menüben engedélyezheted STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Útkarbantartás folyamatban STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Nem törölheted ezt a várost...{}Egy állomás vagy járműtelep hivatkozik a városra, vagy egy városi tulajdonú mező nem eltávolítható STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... nincs megfelelő hely egy szobornak a város központjában diff --git a/src/lang/icelandic.txt b/src/lang/icelandic.txt index 30c05c4a88..3a28a5ec1d 100644 --- a/src/lang/icelandic.txt +++ b/src/lang/icelandic.txt @@ -4059,7 +4059,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... of n STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... of nálægt öðrum bæ STR_ERROR_TOO_MANY_TOWNS :{WHITE}... of margir bæir STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... það er ekkert laust svæði á kortinu -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Bærinn getur ekki lagt vegi. Því er hægt að breyta í Ítarlegar stillingar->Efnahagur->Bæir. STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Vegaframkvæmdir standa yfir STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Ekki hægt að eyða bæ...{}Stöð eða skýli vísar í þennan bæ eða ekki hægt að fjarlægja reit í eigu bæjarins. STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... það er enginn ákjósanlegur staður fyrir styttu í miðju þessa bæjar diff --git a/src/lang/indonesian.txt b/src/lang/indonesian.txt index f17b3e3a3c..fdbd0b3e49 100644 --- a/src/lang/indonesian.txt +++ b/src/lang/indonesian.txt @@ -191,6 +191,9 @@ STR_COLOUR_WHITE :Putih STR_COLOUR_RANDOM :Acak ###length 17 +STR_COLOUR_SECONDARY_PALE_GREEN :Hijau Pucat +STR_COLOUR_SECONDARY_SECONDARY_PINK :Merah Muda +STR_COLOUR_SECONDARY_BROWN :Cokelat # Units used in OpenTTD @@ -506,6 +509,7 @@ STR_NEWS_MENU_DELETE_ALL_MESSAGES :Hapus semua pes # About menu ###length 11 STR_ABOUT_MENU_LAND_BLOCK_INFO :Informasi area daratan +STR_ABOUT_MENU_HELP :Bantuan & panduan STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Hidup/matikan Layar Konsol STR_ABOUT_MENU_AI_DEBUG :Debug skrip AI/Permainan @@ -2091,6 +2095,7 @@ STR_INTRO_MULTIPLAYER :{BLACK}Multi Pe STR_INTRO_GAME_OPTIONS :{BLACK}Pengaturan Permainan STR_INTRO_HIGHSCORE :{BLACK}Tabel Nilai Tertinggi +STR_INTRO_HELP :{BLACK}Bantuan & Panduan STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Pengaturan STR_INTRO_NEWGRF_SETTINGS :{BLACK}Pengaturan NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Cari Konten Daring @@ -2134,6 +2139,9 @@ STR_ABANDON_GAME_QUERY :{YELLOW}Apakah STR_ABANDON_SCENARIO_QUERY :{YELLOW}Apakah anda yakin untuk mengabaikan skenario ini ? # Help window +STR_HELP_WINDOW_WEBSITES :{BLACK}Situs web +STR_HELP_WINDOW_DOCUMENTS :{BLACK}Dokumen +STR_HELP_WINDOW_COMMUNITY :{BLACK}Komunitas # Cheat window STR_CHEATS :{WHITE}Kode Curang @@ -3769,6 +3777,7 @@ STR_COMPANY_VIEW_PRESIDENT_S_NAME_QUERY_CAPTION :Nama Manajer STR_COMPANY_VIEW_GIVE_MONEY_QUERY_CAPTION :Masukkan jumlah uang yang ingin anda berikan STR_BUY_COMPANY_MESSAGE :{WHITE}Kami mencari perusahaan transporasi untuk mengambil alih perusahaan kami.{}{}Anda ingin membeli {COMPANY} senilai {CURRENCY_LONG}? +STR_BUY_COMPANY_HOSTILE_TAKEOVER :{WHITE}Dengan mengambil alih {COMPANY} secara agresif, kamu akan membeli seluruh aset, membayarkan seluruh hutang, dan membayar profit selama dua tahun.{}{}Estimasi jumlahnya adalah {CURRENCY_LONG}.{}{}Apa kamu ingin melanjutkan pengambilalihan ini? # Company infrastructure window STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastruktur milik {COMPANY} @@ -4601,8 +4610,8 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Salah sa STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Jendela "Debug" skrip AI hanya tersedia untuk server # AI configuration window -STR_AI_CONFIG_CAPTION_AI :{WHITE}Konfigurasi AI -STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Konfigurasi Game Script +STR_AI_CONFIG_CAPTION_AI :{WHITE}Pengaturan AI +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Pengaturan Game Script STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Skrip Permainan yang akan di jalankan di permainan berikutnya STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}AI yg akan dijalankan pada permainan berikutnya STR_AI_CONFIG_HUMAN_PLAYER :Pemain Manusia @@ -4659,6 +4668,7 @@ STR_AI_SETTINGS_SETTING :{STRING}: {ORAN # Textfile window +STR_TEXTFILE_JUMPLIST_ITEM :{WHITE}{STRING} STR_TEXTFILE_WRAP_TEXT :{WHITE}Mengebatkan teks STR_TEXTFILE_WRAP_TEXT_TOOLTIP :{BLACK}Mengebatkan teks dari jendela sehingga akan muat tanpa menggulir STR_TEXTFILE_VIEW_README :{BLACK}Lihat readme @@ -4803,7 +4813,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... terl STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... terlalu dekat dengan kota lain STR_ERROR_TOO_MANY_TOWNS :{WHITE}... terlalu banyak kota STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... tidak ada lagi ruang tersisa dalam peta -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Kota tidak akan membangun jalan. Anda dapat mengaktifkan pembangunan jalan pada menu Pengaturan Lanjutan->Ekonomi->Kota STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Jalan sedang dikerjakan STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Tidak dapat menghancurkan kota ini...{}Suatu stasiun atau depo tergantung pada kota ini atau kotak milik kota tidak dapat dihapus STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... tidak ada tempat yang cocok untuk patung di tengah kota ini diff --git a/src/lang/irish.txt b/src/lang/irish.txt index 2f72d31361..80cdb83161 100644 --- a/src/lang/irish.txt +++ b/src/lang/irish.txt @@ -4670,7 +4670,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... rogh STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... roghearr do bhaile eile STR_ERROR_TOO_MANY_TOWNS :{WHITE}... an iomarca bailte STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... níl a thuilleadh spáis ar an léarscáil -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Ní thógfaidh an baile seo bóithre. Is féidir leat tógáil bóithre a chumasú in Ardsocruithe->Geilleagar->Bailte. STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Tá oibreacha bóthair ar bun STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Ní féidir an baile seo a scriosadh...{}Ní féidir stáisiún nó iosta atá ag tagairt don bhaile nó do thíle atá faoi úinéireacht an bhaile a bhaint STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... níl aon suíomh oiriúnach do dhealbh i lár an bhaile seo diff --git a/src/lang/italian.txt b/src/lang/italian.txt index a886316fa9..931c7f0568 100644 --- a/src/lang/italian.txt +++ b/src/lang/italian.txt @@ -4907,7 +4907,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... trop STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... troppo vicino ad un'altra città STR_ERROR_TOO_MANY_TOWNS :{WHITE}... troppe città STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... non c'è altro spazio sulla mappa -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Alla città non è permesso costruire strade. È possibile abilitare la costruzione di strade in Impostazioni -> Ambiente -> Città STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Lavori stradali in corso STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Impossibile eliminare la città...{}Una stazione o un deposito fa ancora riferimento alla città o una casella di proprietà della città non può essere rimossa STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... non ci sono spazi adeguati per una statua nel centro di questa città diff --git a/src/lang/japanese.txt b/src/lang/japanese.txt index 426b38f3a5..1bdf9b4135 100644 --- a/src/lang/japanese.txt +++ b/src/lang/japanese.txt @@ -4791,7 +4791,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}マッ STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}他の街に近すぎます STR_ERROR_TOO_MANY_TOWNS :{WHITE}街数の制限を超えています STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}マップに空きスペースがありません -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}この街は自動では道路を敷設しません。「設定→環境→街」から道路の敷設を許可できます STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}道路補修工事中です STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}街を削除できません{}この街名を参照する停留施設・車庫か、街が所有するタイルが除去できません STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}街の中心部に像を建てるのに適した場所がありません diff --git a/src/lang/korean.txt b/src/lang/korean.txt index 91626507a2..d4f19914d9 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -4867,7 +4867,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... 지 STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... 다른 도시와 너무 가깝습니다 STR_ERROR_TOO_MANY_TOWNS :{WHITE}... 도시가 너무 많습니다 STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... 지도에 더 이상 공간이 없습니다 -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}도시가 도로를 짓지 않을 것입니다. [설정→환경→도시]에서 도로를 지을 수 있도록 설정을 변경하실 수 있습니다. STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}도로 작업이 진행 중입니다 STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}이 도시를 삭제할 수 없습니다...{}도시나 도시 소유의 땅에 역, 정류장, 항구, 공항 또는 차량기지, 차고지, 정박소 등이 존재하면 도시를 삭제할 수 없습니다. STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... 이 도시의 중심에 동상을 세우기 적합한 장소가 없습니다 diff --git a/src/lang/latin.txt b/src/lang/latin.txt index 4ae0933d43..6720798682 100644 --- a/src/lang/latin.txt +++ b/src/lang/latin.txt @@ -4558,7 +4558,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... nimi STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... nimis prope aliud oppidum STR_ERROR_TOO_MANY_TOWNS :{WHITE}... nimis oppida adsunt STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... plus spatium tabulae deest -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Oppidum non vias struet. Potes hanc optionem mutare in Electionibus->Circumiecta->Oppida STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Constructio viaria agitur STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Non licet oppidum delere...{}Statio receptaculumve est oppido sive non licet tegulam oppidi removere STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... non est locus effigiei idoneus in medio oppidi diff --git a/src/lang/latvian.txt b/src/lang/latvian.txt index 3a639d05b1..92348e778a 100644 --- a/src/lang/latvian.txt +++ b/src/lang/latvian.txt @@ -4769,7 +4769,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... pār STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... pārāk tuvu citai pilsētai STR_ERROR_TOO_MANY_TOWNS :{WHITE}... pārāk daudz pilsētu STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... uz kartes nav vairāk vietas -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Pilsēta ceļus nebūvēs. Jūs varat ieslēgt ceļu būvi caur Papildu iestatījumi->Ekonomika->Pilsētas STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Notiek ceļa remonts STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Šo pilsētu nevar dzēst...{}Kāda stacija vai depo attiecas uz pilsētu. Vai pilsētai pieder nenoņemams lauciņš STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... šās pilsētas centrā statujai nav piemērotas vietas diff --git a/src/lang/lithuanian.txt b/src/lang/lithuanian.txt index d0e1e4fc51..dffc9da79f 100644 --- a/src/lang/lithuanian.txt +++ b/src/lang/lithuanian.txt @@ -4964,7 +4964,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... per STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... per arti kito miesto STR_ERROR_TOO_MANY_TOWNS :{WHITE}... per daug miestų STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... daugiau nera vietos zemelapyje -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Miestas nestatys kelių. Jūs galite įjungti kelių statybą per „Išplėstinės nuostatos>Aplinka>Miestai“. STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Vyksta kelio darbai STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Negalima panaikinti šio miesto...{}Mieste yra stotelė arba depas, arba miestui priklausantis vienas iš laukelių negali būti pašalintas STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... nėra tinkamos vietos statulai šio miesto centre diff --git a/src/lang/luxembourgish.txt b/src/lang/luxembourgish.txt index ddb4a6b377..96c8f2b3c7 100644 --- a/src/lang/luxembourgish.txt +++ b/src/lang/luxembourgish.txt @@ -4762,7 +4762,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... ze n STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... ze no un enger anerer Stad STR_ERROR_TOO_MANY_TOWNS :{WHITE}... ze vill Stied STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... et ass keng Plaz méi op der Kaart -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Stied bauen keng Stroossen. Du kanns de Bau iwwert Astellungen->Economie->Stied aschalten STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Stroossenarbeschten amgaangen STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Kann des Stad net läschen...{}Eng Statioun oder Schapp huet den Numm vun dëser Stad oder en Stéck dat der Stad gehéiert kann net ewechgeholl ginn STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... et gëtt keng gëeegent Plaz fir eng Statu am Stadzentrum diff --git a/src/lang/malay.txt b/src/lang/malay.txt index 2344b3c263..a90ae1f310 100644 --- a/src/lang/malay.txt +++ b/src/lang/malay.txt @@ -3965,7 +3965,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... terl STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... terlalu hampir ke bandar lain STR_ERROR_TOO_MANY_TOWNS :{WHITE}... bandar terlalu banyak STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... ruang tidak mencukupi di dalam peta -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Bandar ini tidak akan membina jalan. Anda boleh membenarkan pembinaan jalan melalui Tetapan Lanjutan->Ekonomi->Bandar STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Kerja-kerja jalanraya sedang berjalan STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Tidak boleh padam bandar ini...{}Tidak boleh dipadamkan kerana terdapat sebuah stesen atau depoh yang dipunyai bandar atau petak bandar STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... tiada lokasi sesuai untuk arca di tengah bandar diff --git a/src/lang/norwegian_bokmal.txt b/src/lang/norwegian_bokmal.txt index b0f7150849..2d4efd0bb4 100644 --- a/src/lang/norwegian_bokmal.txt +++ b/src/lang/norwegian_bokmal.txt @@ -4692,7 +4692,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}...{NBSP STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}...{NBSP}for nær en annen by STR_ERROR_TOO_MANY_TOWNS :{WHITE}...{NBSP}for mange byer STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... det er ikke mer plass på kartet -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Byen kommer ikke til å bygge veier. Du kan aktivere bygging av veier via Innstillinger->Miljø->Byer STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Veiarbeid i gang STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Kan ikke fjerne denne byen...{}En stasjon eller garasje/stall/hangar/dokk henviser til byen eller en by-eid rute som ikke kan fjernes STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... det er ingen passende steder for en statue i sentrum av denne byen diff --git a/src/lang/norwegian_nynorsk.txt b/src/lang/norwegian_nynorsk.txt index cfbbb11e18..a382891062 100644 --- a/src/lang/norwegian_nynorsk.txt +++ b/src/lang/norwegian_nynorsk.txt @@ -4194,7 +4194,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... for STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... for nær ein annan by STR_ERROR_TOO_MANY_TOWNS :{WHITE}... for mange byar STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... det er ikkje meir plass på kartet -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Byen byggjer ikkje vegar. Du kan tillete veg-bygging i Avanserte innstillingar -> Økonomi -> Byar STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Vegarbeid pågår STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Kan ikkje fjerne denne byen...{}Ein stasjon eller garasje/stall/hangar/dokk refererar til byen eller ei by-egd rute som ikkje kan fjernast STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... det er ingen passande plass til statue i sentrum av denne byen diff --git a/src/lang/polish.txt b/src/lang/polish.txt index 4dac9495ac..5dc4c4faaa 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -5252,7 +5252,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... zbyt STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... zbyt blisko innego miasta STR_ERROR_TOO_MANY_TOWNS :{WHITE}... zbyt wiele miast STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... nie ma więcej miejsca na mapie -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Miasto nie będzie budować dróg. Możesz zezwolić na budowę dróg poprzez Ustawienia->Środowisko->Miasta STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Trwają roboty drogowe STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Nie można usunąć tego miasta...{}Stacja lub zajezdnia przynależy do tego miasta lub obszar miasta nie może być usunięty STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... w centrum tego miasta nie ma odpowiedniego miejsca na pomnik diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index 9b83d2d549..8f3095400b 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -4867,7 +4867,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... muit STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... muito perto de outra localidade STR_ERROR_TOO_MANY_TOWNS :{WHITE}... demasiadas localidades STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... não existe mais espaço no mapa -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}A localidade não construirá estradas. Pode-se permitir a construção de estradas por Opções Avançadas->Economia->Localidades STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Trabalhos na estrada em curso STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Não é possível eliminar esta localidade...{}Uma estação ou depósito refere-se à localidade ou não é possível remover terreno pertencente à mesma STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... não há um sítio adequado para uma estátua no centro desta localidade diff --git a/src/lang/romanian.txt b/src/lang/romanian.txt index ee59ce7387..f3f5382ed8 100644 --- a/src/lang/romanian.txt +++ b/src/lang/romanian.txt @@ -3399,6 +3399,7 @@ STR_NEWGRF_INSPECT_PARENT_TOOLTIP :{BLACK}Analizea STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT :{STRING} la {HEX} STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_OBJECT :Obiect STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_RAIL_TYPE :Tip şină +STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_ROAD_TYPE :Tip de drum STR_NEWGRF_INSPECT_QUERY_CAPTION :{WHITE}Parametru variabilă 60+x NewGRF (hexadecimal) @@ -4717,6 +4718,8 @@ STR_AI_SETTINGS_SETTING :{STRING}: {ORAN STR_TEXTFILE_JUMPLIST :{WHITE}Cuprins STR_TEXTFILE_JUMPLIST_TOOLTIP :{BLACK}Săriți rapid la o secțiune din fișierul afișat prin această listă STR_TEXTFILE_JUMPLIST_ITEM :{WHITE}{STRING} +STR_TEXTFILE_NAVBACK_TOOLTIP :{BLACK}Reveniți în istoricul navigației +STR_TEXTFILE_NAVFORWARD_TOOLTIP :{BLACK}Reveniți înainte în istoricul navigației STR_TEXTFILE_WRAP_TEXT :{WHITE}Încadrează textul STR_TEXTFILE_WRAP_TEXT_TOOLTIP :{BLACK}Încadrează textul ferestrei ca să fie vizibil integral, fără derulare STR_TEXTFILE_VIEW_README :{BLACK}Vezi fișierul readme @@ -4862,7 +4865,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... prea STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... prea aproape de alt oraş STR_ERROR_TOO_MANY_TOWNS :{WHITE}... prea multe oraşe STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... nu mai este loc pe hartă -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Orașul nu va construi drumuri. Poți activa construirea drumurilor din Setări avansate -> Economie -> Orașe STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Lucrari la drum in curs de desfasurare STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Acest oraș nu poate fi șters...{}O stație sau un depou face referire la acest oraș, sau o parcelă deținută de oraș nu poate fi eliminată STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... nu există niciun loc potrivit pentru o statuie în centrul acestui oraș diff --git a/src/lang/russian.txt b/src/lang/russian.txt index e811e9e610..cae8f3268e 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -5053,7 +5053,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... сл STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... слишком близко к другому городу STR_ERROR_TOO_MANY_TOWNS :{WHITE}... слишком много городов STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... нет места на карте -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Города не будут строить дороги сами. Вы можете включить строительство дорог в разделе «Настройки -> Окр.{NBSP}среда -> Города». STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Идут дорожные работы... STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Невозможно уничтожить город:{}к нему относится станция или депо, либо невозможно очистить одну из занимаемых им клеток. STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... в центре города нет места для статуи diff --git a/src/lang/serbian.txt b/src/lang/serbian.txt index 13c5a0548c..1c386d7bde 100644 --- a/src/lang/serbian.txt +++ b/src/lang/serbian.txt @@ -4963,7 +4963,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... prev STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... drugo naselje je previše blizu STR_ERROR_TOO_MANY_TOWNS :{WHITE}... ima previše naselja STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... više ne postoji slobodnog prostora na terenu -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Naselje neće graditi kolovoze. Možete uključiti gradnju kolovoza preko Napredna Podešavanja->Okruženje->Naselja STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Putni radovi u toku STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Nije moguće obrisati naselje...{}Stanica ili depo na zemljištvu naselja se ne može ukloniti STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... ne postoji odgovarajuće mesto za spomenik u centru ovog naselja diff --git a/src/lang/simplified_chinese.txt b/src/lang/simplified_chinese.txt index b4b73809cb..cf5b22a0b3 100644 --- a/src/lang/simplified_chinese.txt +++ b/src/lang/simplified_chinese.txt @@ -175,7 +175,7 @@ STR_COLOUR_DEFAULT :默认 STR_COLOUR_DARK_BLUE :深蓝色 STR_COLOUR_PALE_GREEN :浅绿色 STR_COLOUR_PINK :粉红色 -STR_COLOUR_YELLOW :黄 色 +STR_COLOUR_YELLOW :黄 色 STR_COLOUR_RED :红 色 STR_COLOUR_LIGHT_BLUE :淡蓝色 STR_COLOUR_GREEN :绿 色 @@ -193,13 +193,13 @@ STR_COLOUR_RANDOM :随机 ###length 17 STR_COLOUR_SECONDARY_DARK_BLUE :深蓝色 STR_COLOUR_SECONDARY_PALE_GREEN :浅绿色 -STR_COLOUR_SECONDARY_SECONDARY_PINK :粉色 -STR_COLOUR_SECONDARY_YELLOW :黄 色 -STR_COLOUR_SECONDARY_RED :红 色 +STR_COLOUR_SECONDARY_SECONDARY_PINK :粉红色 +STR_COLOUR_SECONDARY_YELLOW :黄 色 +STR_COLOUR_SECONDARY_RED :红 色 STR_COLOUR_SECONDARY_LIGHT_BLUE :淡蓝色 STR_COLOUR_SECONDARY_GREEN :绿 色 STR_COLOUR_SECONDARY_DARK_GREEN :深绿色 -STR_COLOUR_SECONDARY_BLUE :蓝 色 +STR_COLOUR_SECONDARY_BLUE :蓝 色 STR_COLOUR_SECONDARY_CREAM :奶油色 STR_COLOUR_SECONDARY_MAUVE :深紫色 STR_COLOUR_SECONDARY_PURPLE :紫 色 @@ -954,7 +954,7 @@ STR_GAME_OPTIONS_CAPTION :{WHITE}游戏 STR_GAME_OPTIONS_TAB_GENERAL :通用 STR_GAME_OPTIONS_TAB_GENERAL_TT :{BLACK}选择通用设定 -STR_GAME_OPTIONS_TAB_GRAPHICS :图形包 +STR_GAME_OPTIONS_TAB_GRAPHICS :图像 STR_GAME_OPTIONS_TAB_GRAPHICS_TT :{BLACK}选择图形组设定 STR_GAME_OPTIONS_TAB_SOUND :音效 STR_GAME_OPTIONS_TAB_SOUND_TT :{BLACK}选择音乐和音效的设定 @@ -2216,7 +2216,7 @@ STR_LIVERY_DIESEL :内燃机车 STR_LIVERY_ELECTRIC :电力机车 STR_LIVERY_MONORAIL :单轨机车 STR_LIVERY_MAGLEV :磁悬浮机车 -STR_LIVERY_DMU :DMU 机车 +STR_LIVERY_DMU :内燃动车组 STR_LIVERY_EMU :电力动车组 STR_LIVERY_PASSENGER_WAGON_STEAM :客运机车(蒸汽) STR_LIVERY_PASSENGER_WAGON_DIESEL :客运机车(内燃机) @@ -4866,7 +4866,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}太靠 STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}太靠近另一个城镇了 STR_ERROR_TOO_MANY_TOWNS :{WHITE}城镇太多了 STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}地图上没有多余的地方了 -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}城镇不会修建道路{}您可以在“设置->环境->城镇”选项下开启建设道路的功能 STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}正在进行道路工程 STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}无法删除城镇...{}城镇范围内还有车站、车库或无法移除的区块 STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... 城市中心没有合适的地方放置公司塑像 diff --git a/src/lang/slovak.txt b/src/lang/slovak.txt index 1c5b8c2220..27561605d3 100644 --- a/src/lang/slovak.txt +++ b/src/lang/slovak.txt @@ -4880,7 +4880,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... prí STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... príliš blízko iného mesta STR_ERROR_TOO_MANY_TOWNS :{WHITE}... príliš veľa miest STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... nie je miesto na mape -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Mesto nebude stavať cesty. Môžete povoliť budovanie ciest cez Pokročilé nasvavenia->Ekonomika->Mestá. STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Prebiehajú cestné práce STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Toto mesto nie je možné odstrániť...{}Stanica alebo depo sa odvoláva na mesto, alebo parcela vo vlastníctve mesta nemôže byť odstránená STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... v centre mesta sa nenachádza žiadne vhodné miesto pre sochu diff --git a/src/lang/slovenian.txt b/src/lang/slovenian.txt index 789c065153..ba981b528c 100644 --- a/src/lang/slovenian.txt +++ b/src/lang/slovenian.txt @@ -4447,7 +4447,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... preb STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... preblizu drugemu mestu STR_ERROR_TOO_MANY_TOWNS :{WHITE}... preveliko število mest STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... ni več prostora na zemljevidu -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Mesta ne bodo gradila cest. Lahko omogočiš gradnjo cest v Napredne nastavitve->Ekonomija->Mesta STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Cestna dela napredujejo STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Ni mogoče zbrisati mesta...{}Postaja ali garaža se nanaša na to mesto ali pa področje v lastnini mesta ne more biti odstranjeno STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... ni primernega mesta za kip v centru tega mesta diff --git a/src/lang/spanish.txt b/src/lang/spanish.txt index 98dbed8d9e..d10bd46d85 100644 --- a/src/lang/spanish.txt +++ b/src/lang/spanish.txt @@ -4759,7 +4759,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... dema STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... demasiado cerca de otro municipio STR_ERROR_TOO_MANY_TOWNS :{WHITE}... demasiados municipios STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... no hay más espacio en el mapa -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}El municipio no construirá carreteras. Puedes activar la función de construcción de carreteras en Configuración->Ambiente->Municipios STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Obras de carretera en progreso STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}No se puede borrar este municipio...{}Quedan estaciones o depósitos relacionados con él, o una propiedad suya no puede ser retirada STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... no existe un lugar apropiado para una estatua en el centro de este municipio diff --git a/src/lang/spanish_MX.txt b/src/lang/spanish_MX.txt index 2c13ac1867..e5640938ef 100644 --- a/src/lang/spanish_MX.txt +++ b/src/lang/spanish_MX.txt @@ -4760,7 +4760,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... dema STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... demasiado cerca de otra localidad STR_ERROR_TOO_MANY_TOWNS :{WHITE}... demasiadas localidades STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... ya no hay espacio en el mapa -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}La localidad no construirá carreteras. Se puede activar esta función en Configuración->Entorno->Localidades STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Obras de carretera en progreso STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}No se puede eliminar esta localidad...{}Aún tiene una estación o depósito, o una de sus casillas no se puede quitar STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... no hay lugar apto para una estatua en el centro de esta localidad diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt index f33b6153a1..60c081cb1c 100644 --- a/src/lang/swedish.txt +++ b/src/lang/swedish.txt @@ -4845,7 +4845,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... för STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... för nära en annan stad STR_ERROR_TOO_MANY_TOWNS :{WHITE}... för många städer STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... det finns ingen plats kvar på kartan -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Staden kommer inte bygga vägar. Du kan tillåta att staden bygger vägar via Inställningar->Miljö->Städer STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Vägarbete pågår STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Kan inte ta bort den här staden...{}En station eller depå refererar till staden eller så kan inte en stadsägd ruta tas bort. STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... det finns ingen lämplig plats för en staty i stadens centrum diff --git a/src/lang/tamil.txt b/src/lang/tamil.txt index 51ea7cdc67..993933b841 100644 --- a/src/lang/tamil.txt +++ b/src/lang/tamil.txt @@ -4278,7 +4278,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... ப STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... மற்றொரு நகரத்திற்கு மிகவும் அருகாமையில் உள்ளது STR_ERROR_TOO_MANY_TOWNS :{WHITE}... மிகவும் அதிகமான நகரங்கள் STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... படத்தில் வேறு வெற்றுஇடம் இல்லை -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}நகராட்சி சாலைகளை அமைக்காது. இந்த அமைப்பினை மாற்ற செல்க சிறப்பு அமைப்புகள் -> பொருளாதாரம் -> நகரங்கள் STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}சாலைப் பணிகள் நடந்துக் கொண்டிருக்கின்றன STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}இந்த நகரத்தினை நீக்க இயலாது ...{} ஒரு நிலையமோ அல்லது பணிமனையோ நகரத்தின் பெயரில் உள்ளது மற்றும் நகரத்திற்குச் சொந்தமான கட்டங்களை நீக்க முடியாது. STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... நகரத்தின் நடுவில் சிலையினை அமைக்க தகுந்த இடமில்லை diff --git a/src/lang/thai.txt b/src/lang/thai.txt index e7330d49a0..edb70a7225 100644 --- a/src/lang/thai.txt +++ b/src/lang/thai.txt @@ -4411,7 +4411,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... ต STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... ใกล้กับเมืองอื่นมากเกินไป STR_ERROR_TOO_MANY_TOWNS :{WHITE}... มีเมืองมากเกินไป STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... มีพื้นที่บนแผนที่ไม่มากพอ -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}เมืองจะไม่สามารถสร้างถนนได้ในอนาคต. คุณสามารถเปิดใช้งานสร้างถนนของเมือง ใน Advanced Settings->Economy->Towns STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}กำลังอยู่ระหว่างการปรับปรุงถนน STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}ไม่สามารถทำลายเมืองได้{}สถานีหรือโรงเก็บนี้เป็นทรัพย์สินของเมืองไม่สามารถทำลายหรือเคลื่อนย้ายได้ STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... ที่นี่ไม่มีสถานที่เหมาะสมในการสร้างอนุเสาวรีย์ในใจกลางเมือง diff --git a/src/lang/traditional_chinese.txt b/src/lang/traditional_chinese.txt index 0222803ef6..d4a2b9313f 100644 --- a/src/lang/traditional_chinese.txt +++ b/src/lang/traditional_chinese.txt @@ -191,6 +191,23 @@ STR_COLOUR_WHITE :白 STR_COLOUR_RANDOM :隨機 ###length 17 +STR_COLOUR_SECONDARY_DARK_BLUE :暗藍 +STR_COLOUR_SECONDARY_PALE_GREEN :淡綠 +STR_COLOUR_SECONDARY_SECONDARY_PINK :粉紅 +STR_COLOUR_SECONDARY_YELLOW :黃 +STR_COLOUR_SECONDARY_RED :紅 +STR_COLOUR_SECONDARY_LIGHT_BLUE :淺藍 +STR_COLOUR_SECONDARY_GREEN :綠 +STR_COLOUR_SECONDARY_DARK_GREEN :暗綠 +STR_COLOUR_SECONDARY_BLUE :藍 +STR_COLOUR_SECONDARY_CREAM :奶黃 +STR_COLOUR_SECONDARY_MAUVE :淡紫 +STR_COLOUR_SECONDARY_PURPLE :紫 +STR_COLOUR_SECONDARY_ORANGE :橙 +STR_COLOUR_SECONDARY_BROWN :棕 +STR_COLOUR_SECONDARY_GREY :灰 +STR_COLOUR_SECONDARY_WHITE :白 +STR_COLOUR_SECONDARY_SAME_AS_PRIMARY :與主色調相同 # Units used in OpenTTD @@ -198,6 +215,7 @@ STR_UNITS_VELOCITY_IMPERIAL :{DECIMAL}{NBSP} STR_UNITS_VELOCITY_METRIC :{DECIMAL}{NBSP}公里/小時 STR_UNITS_VELOCITY_SI :{DECIMAL}{NBSP}米/秒 STR_UNITS_VELOCITY_GAMEUNITS :{DECIMAL}{NBSP}格/日 +STR_UNITS_VELOCITY_KNOTS :{DECIMAL}{NBSP}節 STR_UNITS_POWER_IMPERIAL :{DECIMAL}{NBSP}匹 STR_UNITS_POWER_METRIC :{DECIMAL}{NBSP}匹 @@ -505,6 +523,7 @@ STR_NEWS_MENU_DELETE_ALL_MESSAGES :刪除所有訊 # About menu ###length 11 STR_ABOUT_MENU_LAND_BLOCK_INFO :土地資訊 +STR_ABOUT_MENU_HELP :幫助和手冊 STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :切換主控台 STR_ABOUT_MENU_AI_DEBUG :AI/遊戲腳本除錯 @@ -933,12 +952,26 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}將主 # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}遊戲選項 +STR_GAME_OPTIONS_TAB_GENERAL :基本 +STR_GAME_OPTIONS_TAB_GENERAL_TT :{BLACK}選擇基本設定 +STR_GAME_OPTIONS_TAB_GRAPHICS :圖形集 +STR_GAME_OPTIONS_TAB_GRAPHICS_TT :{BLACK}選擇圖形設定 +STR_GAME_OPTIONS_TAB_SOUND :音效 +STR_GAME_OPTIONS_VOLUME :音量 +STR_GAME_OPTIONS_SFX_VOLUME :音效 +STR_GAME_OPTIONS_MUSIC_VOLUME :音樂 +STR_GAME_OPTIONS_VOLUME_0 :0% +STR_GAME_OPTIONS_VOLUME_25 :25% +STR_GAME_OPTIONS_VOLUME_50 :50% +STR_GAME_OPTIONS_VOLUME_75 :75% +STR_GAME_OPTIONS_VOLUME_100 :100% STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}幣值單位 STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}選擇幣值單位 +STR_GAME_OPTIONS_CURRENCY_CODE :{STRING} ({STRING}) ###length 42 STR_GAME_OPTIONS_CURRENCY_GBP :英鎊 @@ -990,6 +1023,10 @@ STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}選擇 # Autosave dropdown ###length 5 STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_OFF :關閉 +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_10_MINUTES :每10分鐘 +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_30_MINUTES :每30分鐘 +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_60_MINUTES :每60分鐘 +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_120_MINUTES :每120分鐘 STR_GAME_OPTIONS_LANGUAGE :{BLACK}語言 STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}選擇要用的介面語言 @@ -1026,6 +1063,9 @@ STR_GAME_OPTIONS_GUI_SCALE_3X :3倍 STR_GAME_OPTIONS_GUI_SCALE_4X :4倍 STR_GAME_OPTIONS_GUI_SCALE_5X :5倍 +STR_GAME_OPTIONS_PARTICIPATE_SURVEY_FRAME :{BLACK}自動問卷 +STR_GAME_OPTIONS_PARTICIPATE_SURVEY :{BLACK}參與自動問卷 +STR_GAME_OPTIONS_PARTICIPATE_SURVEY_LINK :{BLACK}關於問卷和隱私 STR_GAME_OPTIONS_GRAPHICS :{BLACK}圖形 @@ -1156,6 +1196,7 @@ STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}展開 STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}折疊所有選項 STR_CONFIG_SETTING_RESET_ALL :{BLACK}重設所有數值 STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT :(沒有適用的解釋) +STR_CONFIG_SETTING_VALUE :{PUSH_COLOUR}{ORANGE}{STRING}{POP_COLOUR} STR_CONFIG_SETTING_DEFAULT_VALUE :{LTBLUE}預設值:{ORANGE}{STRING} STR_CONFIG_SETTING_TYPE :{LTBLUE}設定種類:{ORANGE}{STRING} STR_CONFIG_SETTING_TYPE_CLIENT :用戶端設定 (存檔時不保存;影響所有遊戲) @@ -1209,6 +1250,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_LEFT :靠左 STR_CONFIG_SETTING_HORIZONTAL_POS_CENTER :置中 STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :靠右 +STR_CONFIG_SETTING_SECONDS_VALUE :{COMMA}{NBSP}秒 STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :最大貸款額:{STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :公司最多可借多少錢(此設定的值排除了通貨膨脹因素)。 @@ -1380,6 +1422,7 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NONE :無 STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :減少 STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :正常 +STR_CONFIG_SETTING_CROSSING_WITH_COMPETITOR :可在競爭對手所有的道路或鐵路上建造平交道:{STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :可在市鎮所屬道路上建設路邊車站:{STRING} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :容許在市鎮擁有的道路上建造直通型車站。 @@ -1393,6 +1436,7 @@ STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :如啟用此選 STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR :初始公司顏色:{STRING} STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :選擇公司的初始顏色。 +STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_SECONDARY :初始公司副色調:{STRING} STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :機場永不過期:{STRING} STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT :如啟用此選項,所有機場一經面世,就永遠可以選擇建設。 @@ -1595,6 +1639,8 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :無 STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :右鍵關閉視窗:{STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :在視窗內以右鍵點擊可關閉視窗。可用右鍵關閉工具提示。 ###length 3 +STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_NO :否 +STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_YES :是 STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES :使用 {STRING} 時間格式作為存檔檔名 STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_HELPTEXT :在存檔的檔名中使用的日期格式。 @@ -1921,6 +1967,7 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :無 STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :初始城市規模倍率:{STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :設定遊戲開始時城市的大小 (相對於一般市鎮而言)。 +STR_CONFIG_SETTING_LINKGRAPH_RECALC_INTERVAL :每{STRING}更新貨物分配圖 STR_CONFIG_SETTING_DISTRIBUTION_PAX :乘客分配方式:{STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :設使有交通路線連接甲、乙兩站。「對稱」指甲站往乙站的乘客數量與乙站往甲站的乘客數量大致相同。「不對稱」指任何一站往另一站的乘客數量皆由系統隨意決定。「手動」指系統不會自動分配乘客的目的地。 @@ -1947,12 +1994,14 @@ STR_CONFIG_SETTING_SHORT_PATH_SATURATION :如果最短路 STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT :貨物分配功能在派送貨物時,會優先使用最短路徑,至其飽和後改用第二短的路徑,如此類推。當所有路徑皆飽和但仍未滿足需求,系統會由容量較大的路徑開始繼續加載貨物。{}由於路徑飽和度難以準確估算,此設定容許您定義一值,使短路徑達至該飽和度後,系統便開始加載容量較大的路徑。{}如果此設定的值少於100%,即使系統高估路徑容量,也不會使過多的貨物滯留車站。 STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY :速度單位:{STRING} +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_NAUTICAL :速度單位(航海):{STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_HELPTEXT :在界面上以所選擇的單位表示速度。 ###length 5 STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_IMPERIAL :英制(英里/小時) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_METRIC :米制(公里/小時) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_SI :國際單位(米/秒) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_GAMEUNITS :遊戲單位 (格/日) +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_KNOTS :節 STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER :車輛功率單位:{STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_HELPTEXT :在界面上以所選擇的單位表示車輛的功率。 @@ -2064,6 +2113,7 @@ STR_INTRO_MULTIPLAYER :{BLACK}多人 STR_INTRO_GAME_OPTIONS :{BLACK}遊戲選項 STR_INTRO_HIGHSCORE :{BLACK}積分排行榜 +STR_INTRO_HELP :{BLACK}幫助和手冊 STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}設定 STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF 設定 STR_INTRO_ONLINE_CONTENT :{BLACK}檢查線上內容 @@ -2107,6 +2157,16 @@ STR_ABANDON_GAME_QUERY :{YELLOW}你要 STR_ABANDON_SCENARIO_QUERY :{YELLOW}你確定要離開這個場景嗎? # Help window +STR_HELP_WINDOW_CAPTION :{WHITE}幫助和手冊 +STR_HELP_WINDOW_WEBSITES :{BLACK}網站 +STR_HELP_WINDOW_DOCUMENTS :{BLACK}文檔 +STR_HELP_WINDOW_README :{BLACK}Readme +STR_HELP_WINDOW_CHANGELOG :{BLACK}修訂紀錄 +STR_HELP_WINDOW_LICENSE :{BLACK}許可協議 +STR_HELP_WINDOW_MAIN_WEBSITE :{BLACK}OpenTTD +STR_HELP_WINDOW_MANUAL_WIKI :{BLACK}手冊/維基 +STR_HELP_WINDOW_BUGTRACKER :{BLACK}回報漏洞 +STR_HELP_WINDOW_COMMUNITY :{BLACK}社區 # Cheat window STR_CHEATS :{WHITE}作弊 @@ -2383,6 +2443,10 @@ STR_NETWORK_ASK_RELAY_NO :{BLACK}否 STR_NETWORK_ASK_RELAY_YES_ONCE :{BLACK}是,僅此一次 STR_NETWORK_ASK_RELAY_YES_ALWAYS :{BLACK}是,且不再詢問 +STR_NETWORK_ASK_SURVEY_CAPTION :是否參與自動問卷? +STR_NETWORK_ASK_SURVEY_LINK :關於問卷和隱私 +STR_NETWORK_ASK_SURVEY_NO :否 +STR_NETWORK_ASK_SURVEY_YES :是 STR_NETWORK_SPECTATORS :旁觀者 @@ -2673,7 +2737,9 @@ STR_STATION_BUILD_STATION_CLASS_TOOLTIP :{BLACK}選擇 STR_STATION_BUILD_STATION_TYPE_TOOLTIP :{BLACK}選擇要興建的車站種類 STR_STATION_CLASS_DFLT :預設車站 +STR_STATION_CLASS_DFLT_STATION :預設車站 STR_STATION_CLASS_WAYP :號誌站 +STR_STATION_CLASS_WAYP_WAYPOINT :預設號誌站 # Signal window STR_BUILD_SIGNAL_CAPTION :{WHITE}號誌選擇 @@ -3316,6 +3382,7 @@ STR_NEWGRF_INSPECT_PARENT_TOOLTIP :{BLACK}檢查 STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT :{STRING} 於 {HEX} STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_OBJECT :物件 STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_RAIL_TYPE :鐵路種類 +STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_ROAD_TYPE :道路類型 STR_NEWGRF_INSPECT_QUERY_CAPTION :{WHITE}NewGRF variable 60+x 參數(16 進位) @@ -3722,6 +3789,7 @@ STR_COMPANY_VIEW_INFRASTRUCTURE_BUTTON :{BLACK}詳情 STR_COMPANY_VIEW_INFRASTRUCTURE_TOOLTIP :{BLACK}顯示基礎建設數目的詳細資料 STR_COMPANY_VIEW_GIVE_MONEY_BUTTON :{BLACK}給予資金 STR_COMPANY_VIEW_GIVE_MONEY_TOOLTIP :{BLACK}將資金給予此公司 +STR_COMPANY_VIEW_HOSTILE_TAKEOVER_BUTTON :{BLACK}敵意收購 STR_COMPANY_VIEW_NEW_FACE_BUTTON :{BLACK}新臉孔 STR_COMPANY_VIEW_NEW_FACE_TOOLTIP :{BLACK}選擇總經理的新臉孔 @@ -3808,6 +3876,7 @@ STR_VEHICLE_LIST_MANAGE_LIST :{BLACK}管理 STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}向清單所有車輛發出指示 STR_VEHICLE_LIST_REPLACE_VEHICLES :替換車輛 STR_VEHICLE_LIST_SEND_FOR_SERVICING :送去維護 +STR_VEHICLE_LIST_CREATE_GROUP :建立群組 STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}今年盈利:{CURRENCY_LONG} (去年盈利:{CURRENCY_LONG}) STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :送到機廠 @@ -4528,6 +4597,8 @@ STR_TIMETABLE_EXPECTED :{BLACK}實際 STR_TIMETABLE_SCHEDULED :{BLACK}表定時間 STR_TIMETABLE_EXPECTED_TOOLTIP :{BLACK}切換顯示 (根據實際情況的) 預期時間 或 表定時間 +STR_TIMETABLE_ARRIVAL :到: {COLOUR}{DATE_TINY} +STR_TIMETABLE_DEPARTURE :發: {COLOUR}{DATE_TINY} # Date window (for timetable) @@ -4571,6 +4642,7 @@ STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}下局 STR_AI_CONFIG_HUMAN_PLAYER :人類玩家 STR_AI_CONFIG_RANDOM_AI :隨機 AI STR_AI_CONFIG_NONE :(無) +STR_AI_CONFIG_NAME_VERSION :{STRING} {YELLOW}v{NUM} STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}競爭對手數目上限:{ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}向上移 @@ -4621,6 +4693,8 @@ STR_AI_SETTINGS_SETTING :{STRING}:{ORA # Textfile window +STR_TEXTFILE_JUMPLIST :{WHITE}目錄 +STR_TEXTFILE_JUMPLIST_ITEM :{WHITE}{STRING} STR_TEXTFILE_WRAP_TEXT :{WHITE}強迫文字換行 STR_TEXTFILE_WRAP_TEXT_TOOLTIP :{BLACK}強迫寬於視窗的文字自動換行 STR_TEXTFILE_VIEW_README :{BLACK}檢視Readme @@ -4630,6 +4704,7 @@ STR_TEXTFILE_VIEW_LICENCE :{BLACK}授權 STR_TEXTFILE_README_CAPTION :{WHITE}{STRING}{STRING}的 Readme STR_TEXTFILE_CHANGELOG_CAPTION :{WHITE}{STRING}{STRING}的修訂紀錄 STR_TEXTFILE_LICENCE_CAPTION :{WHITE}{STRING}{STRING}的授權條款 +STR_TEXTFILE_GAME_MANUAL_CAPTION :{WHITE}OpenTTD 文檔 '{STRING}' # Vehicle loading indicators @@ -4764,7 +4839,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... 太 STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... 太接近另一個市鎮 STR_ERROR_TOO_MANY_TOWNS :{WHITE}... 已有太多市鎮 STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... 地圖沒有足夠空間 -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}市鎮不會自動興建道路。你可以在 [設定] -> [環境] -> [市鎮] 啟用市鎮自行興建道路的功能。 STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}道路施工中 STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}無法刪除此市鎮...{}市鎮範圍內還有車站或機廠或無法移除的區塊 STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... 市中心沒有適合的空間建造雕像 @@ -5086,6 +5160,7 @@ STR_ERROR_NO_BUOY :{WHITE}沒有 STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}無法為車輛加入時刻表... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}車輛只能在車站停靠等候 STR_ERROR_TIMETABLE_NOT_STOPPING_HERE :{WHITE}此車輛不會停靠此站 +STR_ERROR_TIMETABLE_INCOMPLETE :{WHITE}... 時刻表並不完整 # Sign related errors STR_ERROR_TOO_MANY_SIGNS :{WHITE}... 已有太多標誌 @@ -5565,17 +5640,21 @@ STR_VEHICLE_NAME :{VEHICLE} STR_WAYPOINT_NAME :{WAYPOINT} STR_JUST_CARGO :{CARGO_LONG} +STR_JUST_RIGHT_ARROW :{RIGHT_ARROW} STR_JUST_CHECKMARK :{CHECKMARK} STR_JUST_COMMA :{COMMA} STR_JUST_CURRENCY_SHORT :{CURRENCY_SHORT} STR_JUST_CURRENCY_LONG :{CURRENCY_LONG} STR_JUST_CARGO_LIST :{CARGO_LIST} +STR_JUST_DECIMAL :{DECIMAL} STR_JUST_INT :{NUM} STR_JUST_DATE_TINY :{DATE_TINY} STR_JUST_DATE_SHORT :{DATE_SHORT} STR_JUST_DATE_LONG :{DATE_LONG} STR_JUST_DATE_ISO :{DATE_ISO} STR_JUST_STRING :{STRING} +STR_JUST_STRING1 :{STRING} +STR_JUST_STRING2 :{STRING} STR_JUST_STRING_STRING :{STRING}{STRING} STR_JUST_RAW_STRING :{STRING} STR_JUST_BIG_RAW_STRING :{BIG_FONT}{STRING} diff --git a/src/lang/turkish.txt b/src/lang/turkish.txt index 8ffee75036..2cab1d348a 100644 --- a/src/lang/turkish.txt +++ b/src/lang/turkish.txt @@ -4866,7 +4866,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... hari STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... başka bir şehire çok yakın STR_ERROR_TOO_MANY_TOWNS :{WHITE}... çok fazla şehir var STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... haritada boş yer yok -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Kasaba yol yapmayacak. Yol yapımını Gelişmiş Ayarlar->Ekonomi->Şehirler'den etkinleştirebilirsiniz STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Yol çalışmaları STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Bu kasaba silinemiyor...{}Bir istasyon veya garaj kasabaya atıfta bulunuyor ya da bir kasaba karesi kaldırılamıyor STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... bu şehrin merkezinde heykel için uygun bir yer yok diff --git a/src/lang/ukrainian.txt b/src/lang/ukrainian.txt index f7aad014e1..e87588d383 100644 --- a/src/lang/ukrainian.txt +++ b/src/lang/ukrainian.txt @@ -4924,7 +4924,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... на STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... надто близько до іншого міста STR_ERROR_TOO_MANY_TOWNS :{WHITE}... забагато міст STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... на карті немає вільного місця -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Місто не будуватиме дороги. Ви можете дозволити будівництво доріг через налаштування->Довкілля->Міста STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Дорога ремонтується STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Не можна видалити це місто...{}Станція або депо, що відносяться до міста або знаходяться на землі у власності міста, не можуть бути видалені STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... немає придатного місця для статуї в центрі цього міста diff --git a/src/lang/vietnamese.txt b/src/lang/vietnamese.txt index 28626fba82..a88373b672 100644 --- a/src/lang/vietnamese.txt +++ b/src/lang/vietnamese.txt @@ -4866,7 +4866,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... quá STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... quá gần đô thị khác STR_ERROR_TOO_MANY_TOWNS :{WHITE}... quá nhiều đô thị STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... không còn khoảng trống nào trên bản đồ -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Đô thị sẽ không xây dựng đường phố. Bạn có thể bật tính năng này ở menu Thiết lập mở rộng->Môi trường->Đô thị STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Xây dựng cầu đường đang tiến hành STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Không thể xoá đo thị này...{}Có một ga, bến hoặc xưởng thuộc đô thị hoặc là 1 ô đất của đô thị không thể xoá được. STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... không có nơi nào hợp lý để dựng tượng đài ở trung tâm đô thị này diff --git a/src/lang/welsh.txt b/src/lang/welsh.txt index bde76db59b..8617cf2355 100644 --- a/src/lang/welsh.txt +++ b/src/lang/welsh.txt @@ -4443,7 +4443,6 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... rhy STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... rhy agos i dref arall STR_ERROR_TOO_MANY_TOWNS :{WHITE}... gormod o drefi STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... nid oes mwy o le ar y map -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Ni fydd y dref yn adeiladu ffyrdd. Gallwch alluogi adeiladu ffyrdd yn Gosodiadau->Amgylchedd->Trefi STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Mae gwaith yn cael ei wneud ar y ffordd STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Methu dileu'r dref...{}Mae gorsaf neu depo sy'n cyfeirio i'r dref neu deil ym mherchnogaeth y dref na ellir ei ddileu STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... nid oes man addas i'r cerflun yn nghanol y ddinas yma diff --git a/src/misc/dbg_helpers.cpp b/src/misc/dbg_helpers.cpp index b197e9a8af..41d2aa65c0 100644 --- a/src/misc/dbg_helpers.cpp +++ b/src/misc/dbg_helpers.cpp @@ -139,7 +139,7 @@ void DumpTarget::BeginStruct(size_t type_id, const char *name, const void *ptr) { /* make composite name */ std::string cur_name = GetCurrentStructName(); - if (cur_name.size() > 0) { + if (!cur_name.empty()) { /* add name delimiter (we use structured names) */ cur_name += "."; } diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 3c1d1dae59..9ee02a65f9 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -341,19 +341,20 @@ public: line << GetString(STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED); bool found = false; - for (CargoID i = 0; i < NUM_CARGO; ++i) { - if (acceptance[i] > 0) { + for (const CargoSpec *cs : _sorted_cargo_specs) { + CargoID cid = cs->Index(); + if (acceptance[cid] > 0) { /* Add a comma between each item. */ if (found) line << ", "; found = true; /* If the accepted value is less than 8, show it in 1/8:ths */ - if (acceptance[i] < 8) { - SetDParam(0, acceptance[i]); - SetDParam(1, CargoSpec::Get(i)->name); + if (acceptance[cid] < 8) { + SetDParam(0, acceptance[cid]); + SetDParam(1, cs->name); line << GetString(STR_LAND_AREA_INFORMATION_CARGO_EIGHTS); } else { - line << GetString(CargoSpec::Get(i)->name); + line << GetString(cs->name); } } } @@ -1125,7 +1126,7 @@ struct QueryStringWindow : public Window } } - void Close() override + void Close([[maybe_unused]] int data = 0) override { if (!this->editbox.handled && this->parent != nullptr) { Window *parent = this->parent; @@ -1214,7 +1215,7 @@ struct QueryWindow : public Window { this->InitNested(WN_CONFIRM_POPUP_QUERY); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { if (this->proc != nullptr) this->proc(this->parent, false); this->Window::Close(); @@ -1416,7 +1417,7 @@ struct ModifierKeyToggleWindow : Window { this->UpdateButtons(); } - void Close() override + void Close(int data = 0) override { _invert_shift = false; _invert_ctrl = false; diff --git a/src/music.cpp b/src/music.cpp index 67edfcc02b..335d6496b8 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -116,14 +116,14 @@ template return BaseMedia::used_set != nullptr; } -bool MusicSet::FillSetDetails(IniFile *ini, const std::string &path, const std::string &full_filename) +bool MusicSet::FillSetDetails(const IniFile &ini, const std::string &path, const std::string &full_filename) { bool ret = this->BaseSet::FillSetDetails(ini, path, full_filename); if (ret) { this->num_available = 0; - IniGroup *names = ini->GetGroup("names"); - IniGroup *catindex = ini->GetGroup("catindex"); - IniGroup *timingtrim = ini->GetGroup("timingtrim"); + const IniGroup *names = ini.GetGroup("names"); + const IniGroup *catindex = ini.GetGroup("catindex"); + const IniGroup *timingtrim = ini.GetGroup("timingtrim"); uint tracknr = 1; for (uint i = 0; i < lengthof(this->songinfo); i++) { const std::string &filename = this->files[i].filename; @@ -133,7 +133,7 @@ bool MusicSet::FillSetDetails(IniFile *ini, const std::string &path, const std:: this->songinfo[i].filename = filename; // non-owned pointer - IniItem *item = catindex->GetItem(_music_file_names[i]); + const IniItem *item = catindex != nullptr ? catindex->GetItem(_music_file_names[i]) : nullptr; if (item != nullptr && item->value.has_value() && !item->value->empty()) { /* Song has a CAT file index, assume it's MPS MIDI format */ this->songinfo[i].filetype = MTT_MPSMIDI; @@ -158,7 +158,7 @@ bool MusicSet::FillSetDetails(IniFile *ini, const std::string &path, const std:: * the beginning, so we don't start reading e.g. root. */ while (*trimmed_filename == PATHSEPCHAR) trimmed_filename++; - item = names->GetItem(trimmed_filename); + item = names != nullptr ? names->GetItem(trimmed_filename) : nullptr; if (item != nullptr && item->value.has_value() && !item->value->empty()) break; } @@ -179,7 +179,7 @@ bool MusicSet::FillSetDetails(IniFile *ini, const std::string &path, const std:: this->songinfo[i].tracknr = tracknr++; } - item = trimmed_filename != nullptr ? timingtrim->GetItem(trimmed_filename) : nullptr; + item = trimmed_filename != nullptr && timingtrim != nullptr ? timingtrim->GetItem(trimmed_filename) : nullptr; if (item != nullptr && item->value.has_value() && !item->value->empty()) { auto endpos = item->value->find(':'); if (endpos != std::string::npos) { diff --git a/src/music/dmusic.cpp b/src/music/dmusic.cpp index 4cbe46f4ea..3dfa531d53 100644 --- a/src/music/dmusic.cpp +++ b/src/music/dmusic.cpp @@ -876,7 +876,7 @@ static const char *LoadDefaultDLSFile(const char *user_dls) } /* If we couldn't load the file from the registry, try again at the default install path of the GM DLS file. */ - if (dls_file.instruments.size() == 0) { + if (dls_file.instruments.empty()) { static const wchar_t *DLS_GM_FILE = L"%windir%\\System32\\drivers\\gm.dls"; wchar_t path[MAX_PATH]; ExpandEnvironmentStrings(DLS_GM_FILE, path, lengthof(path)); @@ -942,14 +942,14 @@ static const char *LoadDefaultDLSFile(const char *user_dls) /* Calculate download size for the instrument. */ size_t i_size = sizeof(DMUS_DOWNLOADINFO) + sizeof(DMUS_INSTRUMENT); - if (dls_file.instruments[i].articulators.size() > 0) { + if (!dls_file.instruments[i].articulators.empty()) { /* Articulations are stored as two chunks, one containing meta data and one with the actual articulation data. */ offsets += 2; i_size += sizeof(DMUS_ARTICULATION2) + sizeof(CONNECTIONLIST) + sizeof(CONNECTION) * dls_file.instruments[i].articulators.size(); } for (std::vector::iterator rgn = dls_file.instruments[i].regions.begin(); rgn != dls_file.instruments[i].regions.end(); rgn++) { - if (rgn->articulators.size() > 0) { + if (!rgn->articulators.empty()) { offsets += 2; i_size += sizeof(DMUS_ARTICULATION2) + sizeof(CONNECTIONLIST) + sizeof(CONNECTION) * rgn->articulators.size(); } @@ -1002,7 +1002,7 @@ static const char *LoadDefaultDLSFile(const char *user_dls) instrument = inst_data + 1; /* Write global articulations. */ - if (dls_file.instruments[i].articulators.size() > 0) { + if (!dls_file.instruments[i].articulators.empty()) { inst_data->ulGlobalArtIdx = last_offset; offset_table[last_offset++] = (char *)instrument - inst_base; offset_table[last_offset++] = (char *)instrument + sizeof(DMUS_ARTICULATION2) - inst_base; @@ -1031,18 +1031,18 @@ static const char *LoadDefaultDLSFile(const char *user_dls) /* The wave sample data will be taken from the region, if defined, otherwise from the wave itself. */ if (rgn.wave_sample.cbSize != 0) { inst_region->WSMP = rgn.wave_sample; - if (rgn.wave_loops.size() > 0) MemCpyT(inst_region->WLOOP, &rgn.wave_loops.front(), rgn.wave_loops.size()); + if (!rgn.wave_loops.empty()) MemCpyT(inst_region->WLOOP, &rgn.wave_loops.front(), rgn.wave_loops.size()); instrument = (char *)(inst_region + 1) - sizeof(DMUS_REGION::WLOOP) + sizeof(WLOOP) * rgn.wave_loops.size(); } else { inst_region->WSMP = rgn.wave_sample; - if (dls_file.waves[wave_id].wave_loops.size() > 0) MemCpyT(inst_region->WLOOP, &dls_file.waves[wave_id].wave_loops.front(), dls_file.waves[wave_id].wave_loops.size()); + if (!dls_file.waves[wave_id].wave_loops.empty()) MemCpyT(inst_region->WLOOP, &dls_file.waves[wave_id].wave_loops.front(), dls_file.waves[wave_id].wave_loops.size()); instrument = (char *)(inst_region + 1) - sizeof(DMUS_REGION::WLOOP) + sizeof(WLOOP) * dls_file.waves[wave_id].wave_loops.size(); } /* Write local articulator data. */ - if (rgn.articulators.size() > 0) { + if (!rgn.articulators.empty()) { inst_region->ulRegionArtIdx = last_offset; offset_table[last_offset++] = (char *)instrument - inst_base; offset_table[last_offset++] = (char *)instrument + sizeof(DMUS_ARTICULATION2) - inst_base; @@ -1171,7 +1171,7 @@ void MusicDriver_DMusic::Stop() } /* Unloaded any instruments we loaded. */ - if (_dls_downloads.size() > 0) { + if (!_dls_downloads.empty()) { IDirectMusicPortDownload *download_port = nullptr; _port->QueryInterface(IID_IDirectMusicPortDownload, (LPVOID *)&download_port); diff --git a/src/music/midifile.cpp b/src/music/midifile.cpp index 8aeecb0db3..c25557de10 100644 --- a/src/music/midifile.cpp +++ b/src/music/midifile.cpp @@ -87,7 +87,7 @@ public: */ bool IsValid() const { - return this->buf.size() > 0; + return !this->buf.empty(); } /** @@ -347,7 +347,7 @@ static bool FixupMidiData(MidiFile &target) std::sort(target.tempos.begin(), target.tempos.end(), TicktimeAscending); std::sort(target.blocks.begin(), target.blocks.end(), TicktimeAscending); - if (target.tempos.size() == 0) { + if (target.tempos.empty()) { /* No tempo information, assume 120 bpm (500,000 microseconds per beat */ target.tempos.push_back(MidiFile::TempoChange(0, 500000)); } @@ -359,9 +359,9 @@ static bool FixupMidiData(MidiFile &target) uint32 last_ticktime = 0; for (size_t i = 0; i < target.blocks.size(); i++) { MidiFile::DataBlock &block = target.blocks[i]; - if (block.data.size() == 0) { + if (block.data.empty()) { continue; - } else if (block.ticktime > last_ticktime || merged_blocks.size() == 0) { + } else if (block.ticktime > last_ticktime || merged_blocks.empty()) { merged_blocks.push_back(block); last_ticktime = block.ticktime; } else { diff --git a/src/network/core/tcp_connect.cpp b/src/network/core/tcp_connect.cpp index b6ec26de9e..4c44561ec9 100644 --- a/src/network/core/tcp_connect.cpp +++ b/src/network/core/tcp_connect.cpp @@ -204,7 +204,7 @@ void TCPConnecter::OnResolved(addrinfo *ai) } if (_debug_net_level >= 6) { - if (this->addresses.size() == 0) { + if (this->addresses.empty()) { DEBUG(net, 6, "%s did not resolve", this->connection_string.c_str()); } else { DEBUG(net, 6, "%s resolved in:", this->connection_string.c_str()); diff --git a/src/network/core/tcp_listen.h b/src/network/core/tcp_listen.h index e71cf7fa6d..65ed0f81b2 100644 --- a/src/network/core/tcp_listen.h +++ b/src/network/core/tcp_listen.h @@ -142,7 +142,7 @@ public: */ static bool Listen(uint16 port) { - assert(sockets.size() == 0); + assert(sockets.empty()); NetworkAddressList addresses; GetBindAddresses(&addresses, port); @@ -151,7 +151,7 @@ public: address.Listen(SOCK_STREAM, &sockets); } - if (sockets.size() == 0) { + if (sockets.empty()) { DEBUG(net, 0, "Could not start network: could not create listening socket"); ShowNetworkError(STR_NETWORK_ERROR_SERVER_START); return false; diff --git a/src/network/core/udp.cpp b/src/network/core/udp.cpp index 4764445b45..8061be57d9 100644 --- a/src/network/core/udp.cpp +++ b/src/network/core/udp.cpp @@ -52,7 +52,7 @@ bool NetworkUDPSocketHandler::Listen() addr.Listen(SOCK_DGRAM, &this->sockets); } - return this->sockets.size() != 0; + return !this->sockets.empty(); } /** @@ -75,7 +75,7 @@ void NetworkUDPSocketHandler::CloseSocket() */ void NetworkUDPSocketHandler::SendPacket(Packet *p, NetworkAddress *recv, bool all, bool broadcast, bool short_mtu) { - if (this->sockets.size() == 0) this->Listen(); + if (this->sockets.empty()) this->Listen(); const uint MTU = short_mtu ? UDP_MTU_SHORT : UDP_MTU; diff --git a/src/network/network.cpp b/src/network/network.cpp index 6ed9c2c11f..a4671e8012 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -777,7 +777,7 @@ void GetBindAddresses(NetworkAddressList *addresses, uint16 port) } /* No address, so bind to everything. */ - if (addresses->size() == 0) { + if (addresses->empty()) { addresses->emplace_back("", port); } } diff --git a/src/network/network_chat_gui.cpp b/src/network/network_chat_gui.cpp index 088919f1ae..5562c60643 100644 --- a/src/network/network_chat_gui.cpp +++ b/src/network/network_chat_gui.cpp @@ -74,7 +74,7 @@ static uint8 *_chatmessage_backup = nullptr; ///< Backup in case text is moved. */ static inline bool HaveChatMessages(bool show_all) { - if (show_all) return _chatmsg_list.size() != 0; + if (show_all) return !_chatmsg_list.empty(); auto now = std::chrono::steady_clock::now(); for (auto &cmsg : _chatmsg_list) { @@ -314,7 +314,7 @@ struct NetworkChatWindow : public Window { PositionNetworkChatWindow(this); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { InvalidateWindowData(WC_NEWS_WINDOW, 0, 0); this->Window::Close(); diff --git a/src/network/network_content_gui.cpp b/src/network/network_content_gui.cpp index 3a2db11a79..ccfdd1bfee 100644 --- a/src/network/network_content_gui.cpp +++ b/src/network/network_content_gui.cpp @@ -109,7 +109,7 @@ BaseNetworkContentDownloadStatusWindow::BaseNetworkContentDownloadStatusWindow(W this->InitNested(WN_NETWORK_STATUS_WINDOW_CONTENT_DOWNLOAD); } -void BaseNetworkContentDownloadStatusWindow::Close() +void BaseNetworkContentDownloadStatusWindow::Close([[maybe_unused]] int data) { _network_content_client.RemoveCallback(this); this->Window::Close(); @@ -201,7 +201,7 @@ public: this->parent = FindWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_CONTENT_LIST); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { TarScanner::Mode mode = TarScanner::NONE; for (auto ctype : this->receivedTypes) { @@ -574,7 +574,7 @@ public: this->InvalidateData(); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { _network_content_client.RemoveCallback(this); this->Window::Close(); @@ -828,7 +828,7 @@ public: case WID_NCL_NAME: if (this->content.SortType() == widget - WID_NCL_CHECKBOX) { this->content.ToggleSortOrder(); - if (this->content.size() > 0) this->list_pos = (int)this->content.size() - this->list_pos - 1; + if (!this->content.empty()) this->list_pos = (int)this->content.size() - this->list_pos - 1; } else { this->content.SetSortType(widget - WID_NCL_CHECKBOX); this->content.ForceResort(); @@ -903,7 +903,7 @@ public: } } - if (this->content.size() == 0) { + if (this->content.empty()) { if (this->UpdateFilterState()) { this->content.ForceRebuild(); this->InvalidateData(); diff --git a/src/network/network_content_gui.h b/src/network/network_content_gui.h index 4561255e6e..3973521661 100644 --- a/src/network/network_content_gui.h +++ b/src/network/network_content_gui.h @@ -32,7 +32,7 @@ public: */ BaseNetworkContentDownloadStatusWindow(WindowDesc *desc); - void Close() override; + void Close([[maybe_unused]] int data = 0) override; void UpdateWidgetSize(int widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override; void DrawWidget(const Rect &r, int widget) const override; void OnDownloadProgress(const ContentInfo *ci, int bytes) override; diff --git a/src/network/network_coordinator.cpp b/src/network/network_coordinator.cpp index 654eaeda60..4b4dee3d0d 100644 --- a/src/network/network_coordinator.cpp +++ b/src/network/network_coordinator.cpp @@ -648,7 +648,7 @@ void ClientNetworkCoordinatorSocketHandler::CloseStunHandler(const std::string & */ void ClientNetworkCoordinatorSocketHandler::CloseTurnHandler(const std::string &token) { - CloseWindowByClass(WC_NETWORK_ASK_RELAY); + CloseWindowByClass(WC_NETWORK_ASK_RELAY, NRWCD_HANDLED); auto turn_it = this->turn_handlers.find(token); if (turn_it == this->turn_handlers.end()) return; diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 4c3cda068d..2b80154792 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -76,9 +76,9 @@ static DropDownList BuildVisibilityDropDownList() { DropDownList list; - list.emplace_back(new DropDownListStringItem(STR_NETWORK_SERVER_VISIBILITY_LOCAL, SERVER_GAME_TYPE_LOCAL, false)); - list.emplace_back(new DropDownListStringItem(STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY, SERVER_GAME_TYPE_INVITE_ONLY, false)); - list.emplace_back(new DropDownListStringItem(STR_NETWORK_SERVER_VISIBILITY_PUBLIC, SERVER_GAME_TYPE_PUBLIC, false)); + list.push_back(std::make_unique(STR_NETWORK_SERVER_VISIBILITY_LOCAL, SERVER_GAME_TYPE_LOCAL, false)); + list.push_back(std::make_unique(STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY, SERVER_GAME_TYPE_INVITE_ONLY, false)); + list.push_back(std::make_unique(STR_NETWORK_SERVER_VISIBILITY_PUBLIC, SERVER_GAME_TYPE_PUBLIC, false)); return list; } @@ -154,7 +154,7 @@ public: NWidgetBase *child_wid = this->head->next; /* The first and last widget are always visible, determine which other should be visible */ for (uint i = 1; i < lengthof(this->visible) - 1; i++) { - if (given_width > MINIMUM_NAME_WIDTH_BEFORE_NEW_HEADER + child_wid->smallest_x && this->visible[i - 1]) { + if (given_width > ScaleGUITrad(MINIMUM_NAME_WIDTH_BEFORE_NEW_HEADER) + child_wid->smallest_x && this->visible[i - 1]) { this->visible[i] = true; given_width -= child_wid->smallest_x; } else { @@ -523,7 +523,7 @@ public: this->servers.ForceRebuild(); } - void Close() override + void Close(int data = 0) override { this->last_sorting = this->servers.GetListing(); this->Window::Close(); @@ -1567,8 +1567,8 @@ private: static void OnClickClientAdmin([[maybe_unused]] NetworkClientListWindow *w, [[maybe_unused]] Point pt, ClientID client_id) { DropDownList list; - list.emplace_back(new DropDownListStringItem(STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK, DD_CLIENT_ADMIN_KICK, false)); - list.emplace_back(new DropDownListStringItem(STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN, DD_CLIENT_ADMIN_BAN, false)); + list.push_back(std::make_unique(STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK, DD_CLIENT_ADMIN_KICK, false)); + list.push_back(std::make_unique(STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN, DD_CLIENT_ADMIN_BAN, false)); Rect wi_rect; wi_rect.left = pt.x; @@ -1589,8 +1589,8 @@ private: static void OnClickCompanyAdmin([[maybe_unused]] NetworkClientListWindow *w, [[maybe_unused]] Point pt, CompanyID company_id) { DropDownList list; - list.emplace_back(new DropDownListStringItem(STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET, DD_COMPANY_ADMIN_RESET, NetworkCompanyHasClients(company_id))); - list.emplace_back(new DropDownListStringItem(STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK, DD_COMPANY_ADMIN_UNLOCK, !NetworkCompanyIsPassworded(company_id))); + list.push_back(std::make_unique(STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET, DD_COMPANY_ADMIN_RESET, NetworkCompanyHasClients(company_id))); + list.push_back(std::make_unique(STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK, DD_COMPANY_ADMIN_UNLOCK, !NetworkCompanyIsPassworded(company_id))); Rect wi_rect; wi_rect.left = pt.x; @@ -1621,9 +1621,9 @@ private: { ButtonCommon *chat_button = new CompanyButton(SPR_CHAT, company_id == COMPANY_SPECTATOR ? STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP : STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP, COLOUR_ORANGE, company_id, &NetworkClientListWindow::OnClickCompanyChat); - if (_network_server) this->buttons[line_count].emplace_back(new CompanyButton(SPR_ADMIN, STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP, COLOUR_RED, company_id, &NetworkClientListWindow::OnClickCompanyAdmin, company_id == COMPANY_SPECTATOR)); + if (_network_server) this->buttons[line_count].push_back(std::make_unique(SPR_ADMIN, STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP, COLOUR_RED, company_id, &NetworkClientListWindow::OnClickCompanyAdmin, company_id == COMPANY_SPECTATOR)); this->buttons[line_count].emplace_back(chat_button); - if (client_playas != company_id) this->buttons[line_count].emplace_back(new CompanyButton(SPR_JOIN, STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP, COLOUR_ORANGE, company_id, &NetworkClientListWindow::OnClickCompanyJoin, company_id != COMPANY_SPECTATOR && Company::Get(company_id)->is_ai)); + if (client_playas != company_id) this->buttons[line_count].push_back(std::make_unique(SPR_JOIN, STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP, COLOUR_ORANGE, company_id, &NetworkClientListWindow::OnClickCompanyJoin, company_id != COMPANY_SPECTATOR && Company::Get(company_id)->is_ai)); this->line_count += 1; @@ -1632,8 +1632,8 @@ private: if (ci->client_playas != company_id) continue; has_players = true; - if (_network_server) this->buttons[line_count].emplace_back(new ClientButton(SPR_ADMIN, STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP, COLOUR_RED, ci->client_id, &NetworkClientListWindow::OnClickClientAdmin, _network_own_client_id == ci->client_id)); - if (_network_own_client_id != ci->client_id) this->buttons[line_count].emplace_back(new ClientButton(SPR_CHAT, STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP, COLOUR_ORANGE, ci->client_id, &NetworkClientListWindow::OnClickClientChat)); + if (_network_server) this->buttons[line_count].push_back(std::make_unique(SPR_ADMIN, STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP, COLOUR_RED, ci->client_id, &NetworkClientListWindow::OnClickClientAdmin, _network_own_client_id == ci->client_id)); + if (_network_own_client_id != ci->client_id) this->buttons[line_count].push_back(std::make_unique(SPR_CHAT, STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP, COLOUR_ORANGE, ci->client_id, &NetworkClientListWindow::OnClickClientChat)); if (ci->client_id == _network_own_client_id) { this->player_self_index = this->line_count; @@ -1663,7 +1663,7 @@ private: /* As spectator, show a line to create a new company. */ if (client_playas == COMPANY_SPECTATOR && !NetworkMaxCompaniesReached()) { - this->buttons[line_count].emplace_back(new CompanyButton(SPR_JOIN, STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP, COLOUR_ORANGE, COMPANY_SPECTATOR, &NetworkClientListWindow::OnClickCompanyNew)); + this->buttons[line_count].push_back(std::make_unique(SPR_JOIN, STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP, COLOUR_ORANGE, COMPANY_SPECTATOR, &NetworkClientListWindow::OnClickCompanyNew)); this->line_count += 1; } @@ -2436,6 +2436,12 @@ struct NetworkAskRelayWindow : public Window { this->InitNested(0); } + void Close(int data = 0) override + { + if (data == NRWCD_UNHANDLED) _network_coordinator_client.ConnectFailure(this->token, 0); + this->Window::Close(); + } + void UpdateWidgetSize(int widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override { if (widget == WID_NAR_TEXT) { @@ -2475,18 +2481,18 @@ struct NetworkAskRelayWindow : public Window { switch (widget) { case WID_NAR_NO: _network_coordinator_client.ConnectFailure(this->token, 0); - this->Close(); + this->Close(NRWCD_HANDLED); break; case WID_NAR_YES_ONCE: _network_coordinator_client.StartTurnConnection(this->token); - this->Close(); + this->Close(NRWCD_HANDLED); break; case WID_NAR_YES_ALWAYS: _settings_client.network.use_relay_service = URS_ALLOW; _network_coordinator_client.StartTurnConnection(this->token); - this->Close(); + this->Close(NRWCD_HANDLED); break; } } @@ -2522,7 +2528,7 @@ static WindowDesc _network_ask_relay_desc( */ void ShowNetworkAskRelay(const std::string &server_connection_string, const std::string &relay_connection_string, const std::string &token) { - CloseWindowByClass(WC_NETWORK_ASK_RELAY); + CloseWindowByClass(WC_NETWORK_ASK_RELAY, NRWCD_HANDLED); Window *parent = GetMainWindow(); new NetworkAskRelayWindow(&_network_ask_relay_desc, parent, server_connection_string, relay_connection_string, token); diff --git a/src/network/network_gui.h b/src/network/network_gui.h index 236719b2b3..45657c142f 100644 --- a/src/network/network_gui.h +++ b/src/network/network_gui.h @@ -40,5 +40,9 @@ struct NetworkCompanyInfo : NetworkCompanyStats { std::string clients; ///< The clients that control this company (Name1, name2, ..) }; +enum NetworkRelayWindowCloseData { + NRWCD_UNHANDLED = 0, ///< Relay request is unhandled. + NRWCD_HANDLED = 1, ///< Relay request is handled, either by user or by timeout. +}; #endif /* NETWORK_GUI_H */ diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 3aedc4ef44..1de71f4d13 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -1146,7 +1146,7 @@ static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop break; } - if (_cur.grffile->railtype_list.size() == 0) { + if (_cur.grffile->railtype_list.empty()) { /* Use traction type to select between normal and electrified * rail only when no translation list is in place. */ if (_gted[e->index].railtypelabel == RAILTYPE_RAIL_LABEL && engclass >= EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_ELECTRIC_LABEL; @@ -6040,9 +6040,9 @@ static void NewSpriteGroup(ByteReader *buf) group->default_group = PruneTargetSpriteGroup(group->default_group); } - group->error_group = ranges.size() > 0 ? ranges[0].group : group->default_group; + group->error_group = ranges.empty() ? group->default_group : ranges[0].group; /* nvar == 0 is a special case -- we turn our value into a callback result */ - group->calculated_result = ranges.size() == 0; + group->calculated_result = ranges.empty(); ProcessDeterministicSpriteGroupRanges(ranges, group->ranges, group->default_group); @@ -6306,7 +6306,7 @@ static CargoID TranslateCargo(uint8 feature, uint8 ctype) if ((feature == GSF_STATIONS || feature == GSF_ROADSTOPS) && ctype == 0xFE) return CT_DEFAULT_NA; if (ctype == 0xFF) return CT_PURCHASE; - if (_cur.grffile->cargo_list.size() == 0) { + if (_cur.grffile->cargo_list.empty()) { /* No cargo table, so use bitnum values */ if (ctype >= 32) { grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype); @@ -10492,19 +10492,18 @@ void ResetPersistentNewGRFData() */ static void BuildCargoTranslationMap() { - memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map)); + _cur.grffile->cargo_map.fill(UINT8_MAX); - for (CargoID c = 0; c < NUM_CARGO; c++) { - const CargoSpec *cs = CargoSpec::Get(c); + for (const CargoSpec *cs : CargoSpec::Iterate()) { if (!cs->IsValid()) continue; - if (_cur.grffile->cargo_list.size() == 0) { + if (_cur.grffile->cargo_list.empty()) { /* Default translation table, so just a straight mapping to bitnum */ - _cur.grffile->cargo_map[c] = cs->bitnum; + _cur.grffile->cargo_map[cs->Index()] = cs->bitnum; } else { /* Check the translation table for this cargo's label */ int idx = find_index(_cur.grffile->cargo_list, {cs->label}); - if (idx >= 0) _cur.grffile->cargo_map[c] = idx; + if (idx >= 0) _cur.grffile->cargo_map[cs->Index()] = idx; } } } @@ -10719,20 +10718,13 @@ static void CalculateRefitMasks() * cargo type. Finally disable the vehicle, if there is still no cargo. */ if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) { /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */ - const uint8 *cargo_map_for_first_refittable = nullptr; - { - const GRFFile *file = _gted[engine].defaultcargo_grf; - if (file == nullptr) file = e->GetGRF(); - if (file != nullptr && file->grf_version >= 8 && file->cargo_list.size() != 0) { - cargo_map_for_first_refittable = file->cargo_map; - } - } - - if (cargo_map_for_first_refittable != nullptr) { + const GRFFile *file = _gted[engine].defaultcargo_grf; + if (file == nullptr) file = e->GetGRF(); + if (file != nullptr && file->grf_version >= 8 && !file->cargo_list.empty()) { /* Use first refittable cargo from cargo translation table */ - byte best_local_slot = 0xFF; + byte best_local_slot = UINT8_MAX; for (CargoID cargo_type : SetCargoBitIterator(ei->refit_mask)) { - byte local_slot = cargo_map_for_first_refittable[cargo_type]; + byte local_slot = file->cargo_map[cargo_type]; if (local_slot < best_local_slot) { best_local_slot = local_slot; ei->cargo_type = cargo_type; @@ -10776,12 +10768,9 @@ static void FinaliseEngineArray() } } - /* Do final mapping on variant engine ID and set appropriate flags on variant engine */ + /* Do final mapping on variant engine ID. */ if (e->info.variant_id != INVALID_ENGINE) { e->info.variant_id = GetNewEngineID(e->grf_prop.grffile, e->type, e->info.variant_id); - if (e->info.variant_id != INVALID_ENGINE) { - Engine::Get(e->info.variant_id)->display_flags |= EngineDisplayFlags::HasVariants | EngineDisplayFlags::IsFolded; - } } if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue; @@ -10813,13 +10802,32 @@ static void FinaliseEngineArray() } } } + + /* Check engine variants don't point back on themselves (either directly or via a loop) then set appropriate flags + * on variant engine. This is performed separately as all variant engines need to have been resolved. */ + for (Engine *e : Engine::Iterate()) { + EngineID parent = e->info.variant_id; + while (parent != INVALID_ENGINE) { + parent = Engine::Get(parent)->info.variant_id; + if (parent != e->index) continue; + + /* Engine looped back on itself, so clear the variant. */ + e->info.variant_id = INVALID_ENGINE; + + grfmsg(1, "FinaliseEngineArray: Variant of engine %X in '%s' loops back on itself", _engine_mngr[e->index].internal_id, e->GetGRF()->filename.c_str()); + break; + } + + if (e->info.variant_id != INVALID_ENGINE) { + Engine::Get(e->info.variant_id)->display_flags |= EngineDisplayFlags::HasVariants | EngineDisplayFlags::IsFolded; + } + } } /** Check for invalid cargoes */ static void FinaliseCargoArray() { - for (CargoID c = 0; c < NUM_CARGO; c++) { - CargoSpec *cs = CargoSpec::Get(c); + for (CargoSpec *cs : CargoSpec::Iterate()) { if (!cs->IsValid()) { cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO; cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY; diff --git a/src/newgrf.h b/src/newgrf.h index 69c8185030..a7b8471c28 100644 --- a/src/newgrf.h +++ b/src/newgrf.h @@ -353,7 +353,7 @@ struct GRFFile : ZeroedMemoryAllocator { std::vector labels; ///< List of labels std::vector cargo_list; ///< Cargo translation table (local ID -> label) - uint8 cargo_map[NUM_CARGO]; ///< Inverse cargo translation table (CargoID -> local ID) + std::array cargo_map{}; ///< Inverse cargo translation table (CargoID -> local ID) std::vector railtype_list; ///< Railtype translation table RailType railtype_map[RAILTYPE_END]; diff --git a/src/newgrf_cargo.cpp b/src/newgrf_cargo.cpp index 70b1a18d94..7df6e011ed 100644 --- a/src/newgrf_cargo.cpp +++ b/src/newgrf_cargo.cpp @@ -86,7 +86,7 @@ CargoID GetCargoTranslation(uint8 cargo, const GRFFile *grffile, bool usebit) /* Other cases use (possibly translated) cargobits */ - if (grffile->cargo_list.size() > 0) { + if (!grffile->cargo_list.empty()) { /* ...and the cargo is in bounds, then get the cargo ID for * the label */ if (cargo < grffile->cargo_list.size()) return GetCargoIDByLabel(grffile->cargo_list[cargo]); diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index eef69c1141..5200d8f5b5 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -575,19 +575,11 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, return (v->grf_cache.consist_cargo_information & 0xFF000000); } if (!HasBit(v->grf_cache.cache_valid, NCVV_CONSIST_CARGO_INFORMATION)) { - const Vehicle *u; + std::array common_cargoes{}; byte cargo_classes = 0; - uint8 common_cargoes[NUM_CARGO]; - uint8 common_subtypes[256]; byte user_def_data = 0; - CargoID common_cargo_type = CT_INVALID; - uint8 common_subtype = 0xFF; // Return 0xFF if nothing is carried - /* Reset our arrays */ - memset(common_cargoes, 0, sizeof(common_cargoes)); - memset(common_subtypes, 0, sizeof(common_subtypes)); - - for (u = v; u != nullptr; u = u->Next()) { + for (const Vehicle *u = v; u != nullptr; u = u->Next()) { if (v->type == VEH_TRAIN) user_def_data |= Train::From(u)->tcache.user_def_data; /* Skip empty engines */ @@ -598,16 +590,13 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, } /* Pick the most common cargo type */ - uint common_cargo_best_amount = 0; - for (CargoID cargo = 0; cargo < NUM_CARGO; cargo++) { - if (common_cargoes[cargo] > common_cargo_best_amount) { - common_cargo_best_amount = common_cargoes[cargo]; - common_cargo_type = cargo; - } - } + auto cargo_it = std::max_element(std::begin(common_cargoes), std::end(common_cargoes)); + /* Return CT_INVALID if nothing is carried */ + CargoID common_cargo_type = (*cargo_it == 0) ? (CargoID)CT_INVALID : static_cast(std::distance(std::begin(common_cargoes), cargo_it)); /* Count subcargo types of common_cargo_type */ - for (u = v; u != nullptr; u = u->Next()) { + std::array common_subtypes{}; + for (const Vehicle *u = v; u != nullptr; u = u->Next()) { /* Skip empty engines and engines not carrying common_cargo_type */ if (u->cargo_type != common_cargo_type || !u->GetEngine()->CanCarryCargo()) continue; @@ -615,13 +604,9 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, } /* Pick the most common subcargo type*/ - uint common_subtype_best_amount = 0; - for (uint i = 0; i < lengthof(common_subtypes); i++) { - if (common_subtypes[i] > common_subtype_best_amount) { - common_subtype_best_amount = common_subtypes[i]; - common_subtype = i; - } - } + auto subtype_it = std::max_element(std::begin(common_subtypes), std::end(common_subtypes)); + /* Return UINT8_MAX if nothing is carried */ + uint8_t common_subtype = (*subtype_it == 0) ? UINT8_MAX : static_cast(std::distance(std::begin(common_subtypes), subtype_it)); /* Note: We have to store the untranslated cargotype in the cache as the cache can be read by different NewGRFs, * which will need different translations */ diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index cc538c5082..f6f068b5d6 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -168,7 +168,7 @@ struct NewGRFParametersWindow : public Window { clicked_row(UINT_MAX), editable(editable) { - this->action14present = (c->num_valid_params != c->param.size() || c->param_info.size() != 0); + this->action14present = (c->num_valid_params != c->param.size() || !c->param_info.empty()); this->CreateNestedTree(); this->vscroll = this->GetScrollbar(WID_NP_SCROLLBAR); @@ -181,7 +181,7 @@ struct NewGRFParametersWindow : public Window { this->InvalidateData(); } - void Close() override + void Close(int data = 0) override { HideDropDownMenu(this); this->Window::Close(); @@ -403,7 +403,7 @@ struct NewGRFParametersWindow : public Window { DropDownList list; for (uint32 i = par_info.min_value; i <= par_info.max_value; i++) { - list.emplace_back(new DropDownListStringItem(GetGRFStringFromGRFText(par_info.value_names.find(i)->second), i, false)); + list.push_back(std::make_unique(GetGRFStringFromGRFText(par_info.value_names.find(i)->second), i, false)); } ShowDropDownListAt(this, std::move(list), old_val, WID_NP_SETTING_DROPDOWN, wi_rect, COLOUR_ORANGE); @@ -686,7 +686,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { this->OnInvalidateData(GOID_NEWGRF_CURRENT_LOADED); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { CloseWindowByClass(WC_GRF_PARAMETERS); CloseWindowByClass(WC_TEXTFILE); @@ -967,10 +967,10 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { DropDownList list; /* Add 'None' option for clearing list */ - list.emplace_back(new DropDownListStringItem(STR_NONE, -1, false)); + list.push_back(std::make_unique(STR_NONE, -1, false)); for (uint i = 0; i < this->grf_presets.size(); i++) { - list.emplace_back(new DropDownListStringItem(this->grf_presets[i], i, false)); + list.push_back(std::make_unique(this->grf_presets[i], i, false)); } this->CloseChildWindows(WC_QUERY_STRING); // Remove the parameter query window @@ -1600,7 +1600,7 @@ void ShowMissingContentWindow(const GRFConfig *list) ci->md5sum = HasBit(c->flags, GCF_COMPATIBLE) ? c->original_md5sum : c->ident.md5sum; cv.push_back(ci); } - ShowNetworkContentListWindow(cv.size() == 0 ? nullptr : &cv, CONTENT_TYPE_NEWGRF); + ShowNetworkContentListWindow(cv.empty() ? nullptr : &cv, CONTENT_TYPE_NEWGRF); } Listing NewGRFWindow::last_sorting = {false, 0}; diff --git a/src/newgrf_railtype.cpp b/src/newgrf_railtype.cpp index 1ea3307db0..e31bc2b181 100644 --- a/src/newgrf_railtype.cpp +++ b/src/newgrf_railtype.cpp @@ -210,7 +210,7 @@ CustomSignalSpriteResult GetCustomSignalSprite(const RailTypeInfo *rti, TileInde */ RailType GetRailTypeTranslation(uint8 railtype, const GRFFile *grffile) { - if (grffile == nullptr || grffile->railtype_list.size() == 0) { + if (grffile == nullptr || grffile->railtype_list.empty()) { /* No railtype table present. Return railtype as-is (if valid), so it works for original railtypes. */ if (railtype >= RAILTYPE_END || GetRailTypeInfo(static_cast(railtype))->label == 0) return INVALID_RAILTYPE; @@ -233,7 +233,7 @@ RailType GetRailTypeTranslation(uint8 railtype, const GRFFile *grffile) uint8 GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile) { /* No rail type table present, return rail type as-is */ - if (grffile == nullptr || grffile->railtype_list.size() == 0) return railtype; + if (grffile == nullptr || grffile->railtype_list.empty()) return railtype; /* Look for a matching rail type label in the table */ RailTypeLabel label = GetRailTypeInfo(railtype)->label; diff --git a/src/newgrf_roadtype.cpp b/src/newgrf_roadtype.cpp index ac18246d0c..59e6abe647 100644 --- a/src/newgrf_roadtype.cpp +++ b/src/newgrf_roadtype.cpp @@ -156,7 +156,7 @@ uint8 GetReverseRoadTypeTranslation(RoadType roadtype, const GRFFile *grffile) if (grffile == nullptr) return roadtype; const std::vector *list = RoadTypeIsRoad(roadtype) ? &grffile->roadtype_list : &grffile->tramtype_list; - if (list->size() == 0) return roadtype; + if (list->empty()) return roadtype; /* Look for a matching road type label in the table */ RoadTypeLabel label = GetRoadTypeInfo(roadtype)->label; diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index a533585e6c..d06ae4658b 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -529,8 +529,8 @@ uint32 Waypoint::GetNewGRFVariable(const ResolverObject &object, uint16 variable break; case CT_DEFAULT: - for (CargoID cargo_type = 0; cargo_type < NUM_CARGO; cargo_type++) { - cargo += st->goods[cargo_type].CargoTotalCount(); + for (const GoodsEntry &ge : st->goods) { + cargo += ge.CargoTotalCount(); } break; diff --git a/src/order_gui.cpp b/src/order_gui.cpp index 9cf04e0d97..2ca06eca34 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -179,7 +179,7 @@ public: this->owner = v->owner; } - void Close() override + void Close(int data = 0) override { if (!FocusWindowById(WC_VEHICLE_ORDERS, this->window_number)) { MarkDirtyFocusedRoutePaths(this->vehicle); @@ -1896,7 +1896,7 @@ public: this->OnInvalidateData(VIWD_MODIFY_ORDERS); } - void Close() override + void Close(int data = 0) override { CloseWindowById(WC_VEHICLE_CARGO_TYPE_LOAD_ORDERS, this->window_number, false); CloseWindowById(WC_VEHICLE_CARGO_TYPE_UNLOAD_ORDERS, this->window_number, false); @@ -3013,7 +3013,7 @@ public: continue; } } - list.emplace_back(new DropDownListStringItem(OrderStringForVariable(this->vehicle, _order_conditional_variable[i]), _order_conditional_variable[i], false)); + list.push_back(std::make_unique(OrderStringForVariable(this->vehicle, _order_conditional_variable[i]), _order_conditional_variable[i], false)); } ShowDropDownList(this, std::move(list), ocv, WID_O_COND_VARIABLE); break; diff --git a/src/os/macosx/macos.mm b/src/os/macosx/macos.mm index 7405d06df0..a034220d12 100644 --- a/src/os/macosx/macos.mm +++ b/src/os/macosx/macos.mm @@ -95,21 +95,7 @@ void GetMacOSVersion(int *return_major, int *return_minor, int *return_bugfix) #endif } -#ifdef WITH_SDL - -/** - * Show the system dialogue message (SDL on MacOSX). - * - * @param title Window title. - * @param message Message text. - * @param buttonLabel Button text. - */ -void ShowMacDialog(const char *title, const char *message, const char *buttonLabel) -{ - NSRunAlertPanel([ NSString stringWithUTF8String:title ], [ NSString stringWithUTF8String:message ], [ NSString stringWithUTF8String:buttonLabel ], nil, nil); -} - -#elif defined WITH_COCOA +#ifdef WITH_COCOA extern void CocoaDialog(const char *title, const char *message, const char *buttonLabel); diff --git a/src/os/macosx/string_osx.cpp b/src/os/macosx/string_osx.cpp index 25e8fb71c7..4a719d74a4 100644 --- a/src/os/macosx/string_osx.cpp +++ b/src/os/macosx/string_osx.cpp @@ -278,7 +278,7 @@ int CoreTextParagraphLayout::CoreTextLine::GetLeading() const */ int CoreTextParagraphLayout::CoreTextLine::GetWidth() const { - if (this->size() == 0) return 0; + if (this->empty()) return 0; int total_width = 0; for (const auto &run : *this) { @@ -371,7 +371,7 @@ int MacOSStringCompare(std::string_view s1, std::string_view s2) /* Query CoreText for word and cluster break information. */ this->str_info.resize(utf16_to_utf8.size()); - if (utf16_str.size() > 0) { + if (!utf16_str.empty()) { CFAutoRelease str(CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, &utf16_str[0], utf16_str.size(), kCFAllocatorNull)); /* Get cluster breaks. */ diff --git a/src/os/windows/string_uniscribe.cpp b/src/os/windows/string_uniscribe.cpp index 595358e915..bd17e6677c 100644 --- a/src/os/windows/string_uniscribe.cpp +++ b/src/os/windows/string_uniscribe.cpp @@ -292,7 +292,7 @@ static std::vector UniscribeItemizeString(UniscribeParagraphLayoutF /* Itemize text. */ std::vector items = UniscribeItemizeString(buff, length); - if (items.size() == 0) return nullptr; + if (items.empty()) return nullptr; /* Build ranges from the items and the font map. A range is a run of text * that is part of a single item and formatted using a single font style. */ @@ -551,11 +551,11 @@ const int *UniscribeParagraphLayout::UniscribeVisualRun::GetGlyphToCharMap() con /* Query Uniscribe for word and cluster break information. */ this->str_info.resize(utf16_to_utf8.size()); - if (utf16_str.size() > 0) { + if (!utf16_str.empty()) { /* Itemize string into language runs. */ std::vector runs = UniscribeItemizeString(&utf16_str[0], (int32)utf16_str.size()); - for (std::vector::const_iterator run = runs.begin(); runs.size() > 0 && run != runs.end() - 1; run++) { + for (std::vector::const_iterator run = runs.begin(); !runs.empty() && run != runs.end() - 1; run++) { /* Get information on valid word and character break.s */ int len = (run + 1)->iCharPos - run->iCharPos; std::vector attr(len); diff --git a/src/plans_gui.cpp b/src/plans_gui.cpp index e30aa841a9..9e3237c051 100644 --- a/src/plans_gui.cpp +++ b/src/plans_gui.cpp @@ -98,7 +98,7 @@ struct PlansWindow : Window { RebuildList(); } - void Close() override + void Close(int data = 0) override { this->list.clear(); if (_current_plan) { diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index bcd98b47dd..198fbf9b7b 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -515,7 +515,7 @@ struct BuildRailToolbarWindow : Window { if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { if (this->IsWidgetLowered(WID_RAT_BUILD_STATION)) SetViewportCatchmentStation(nullptr, true); if (this->IsWidgetLowered(WID_RAT_BUILD_WAYPOINT)) SetViewportCatchmentWaypoint(nullptr, true); @@ -1250,7 +1250,7 @@ public: this->InvalidateData(); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { CloseWindowById(WC_SELECT_STATION, 0); this->PickerWindowBase::Close(); @@ -1983,7 +1983,7 @@ public: this->OnInvalidateData(); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { _convert_signal_button = false; _trace_restrict_button = false; @@ -2521,10 +2521,10 @@ struct BuildRailWaypointWindow : PickerWindowBase { } } - void Close() override + void Close(int data = 0) override { CloseWindowById(WC_SELECT_STATION, 0); - this->PickerWindowBase::Close(); + this->PickerWindowBase::Close(data); } void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override @@ -2816,7 +2816,7 @@ DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option) DropDownList list; if (all_option) { - list.emplace_back(new DropDownListStringItem(STR_REPLACE_ALL_RAILTYPE, INVALID_RAILTYPE, false)); + list.push_back(std::make_unique(STR_REPLACE_ALL_RAILTYPE, INVALID_RAILTYPE, false)); } Dimension d = { 0, 0 }; @@ -2838,18 +2838,18 @@ DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option) SetDParam(0, rti->strings.menu_text); SetDParam(1, rti->max_speed); if (for_replacement) { - list.emplace_back(new DropDownListStringItem(rti->strings.replace_text, rt, !HasBit(avail_railtypes, rt))); + list.push_back(std::make_unique(rti->strings.replace_text, rt, !HasBit(avail_railtypes, rt))); } else { StringID str = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING; - DropDownListIconItem *iconitem = new DropDownListIconItem(rti->gui_sprites.build_x_rail, PAL_NONE, str, rt, !HasBit(avail_railtypes, rt)); + auto iconitem = std::make_unique(rti->gui_sprites.build_x_rail, PAL_NONE, str, rt, !HasBit(avail_railtypes, rt)); iconitem->SetDimension(d); - list.emplace_back(iconitem); + list.push_back(std::move(iconitem)); } } - if (list.size() == 0) { + if (list.empty()) { /* Empty dropdowns are not allowed */ - list.emplace_back(new DropDownListStringItem(STR_NONE, INVALID_RAILTYPE, true)); + list.push_back(std::make_unique(STR_NONE, INVALID_RAILTYPE, true)); } return list; diff --git a/src/road_gui.cpp b/src/road_gui.cpp index dc97044758..49b26852bd 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -377,7 +377,7 @@ struct BuildRoadToolbarWindow : Window { if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { if (_game_mode == GM_NORMAL && (this->IsWidgetLowered(WID_ROT_BUS_STATION) || this->IsWidgetLowered(WID_ROT_TRUCK_STATION))) SetViewportCatchmentStation(nullptr, true); if (_game_mode == GM_NORMAL && this->IsWidgetLowered(WID_ROT_BUILD_WAYPOINT)) SetViewportCatchmentWaypoint(nullptr, true); @@ -1377,7 +1377,7 @@ public: } } - void Close() override + void Close([[maybe_unused]] int data = 0) override { CloseWindowById(WC_SELECT_STATION, 0); this->PickerWindowBase::Close(); @@ -2038,7 +2038,7 @@ struct BuildRoadWaypointWindow : PickerWindowBase { } } - void Close() override + void Close(int data = 0) override { CloseWindowById(WC_SELECT_STATION, 0); this->PickerWindowBase::Close(); @@ -2311,7 +2311,7 @@ DropDownList GetRoadTypeDropDownList(RoadTramTypes rtts, bool for_replacement, b DropDownList list; if (all_option) { - list.emplace_back(new DropDownListStringItem(STR_REPLACE_ALL_ROADTYPE, INVALID_ROADTYPE, false)); + list.push_back(std::make_unique(STR_REPLACE_ALL_ROADTYPE, INVALID_ROADTYPE, false)); } Dimension d = { 0, 0 }; @@ -2333,18 +2333,18 @@ DropDownList GetRoadTypeDropDownList(RoadTramTypes rtts, bool for_replacement, b SetDParam(0, rti->strings.menu_text); SetDParam(1, rti->max_speed / 2); if (for_replacement) { - list.emplace_back(new DropDownListStringItem(rti->strings.replace_text, rt, !HasBit(avail_roadtypes, rt))); + list.push_back(std::make_unique(rti->strings.replace_text, rt, !HasBit(avail_roadtypes, rt))); } else { StringID str = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING; - DropDownListIconItem *iconitem = new DropDownListIconItem(rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt)); + auto iconitem = std::make_unique(rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt)); iconitem->SetDimension(d); - list.emplace_back(iconitem); + list.push_back(std::move(iconitem)); } } - if (list.size() == 0) { + if (list.empty()) { /* Empty dropdowns are not allowed */ - list.emplace_back(new DropDownListStringItem(STR_NONE, INVALID_ROADTYPE, true)); + list.push_back(std::make_unique(STR_NONE, INVALID_ROADTYPE, true)); } return list; @@ -2377,14 +2377,14 @@ DropDownList GetScenRoadTypeDropDownList(RoadTramTypes rtts) SetDParam(0, rti->strings.menu_text); SetDParam(1, rti->max_speed / 2); StringID str = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING; - DropDownListIconItem *item = new DropDownListIconItem(rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt)); + auto item = std::make_unique(rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt)); item->SetDimension(d); - list.emplace_back(item); + list.push_back(std::move(item)); } - if (list.size() == 0) { + if (list.empty()) { /* Empty dropdowns are not allowed */ - list.emplace_back(new DropDownListStringItem(STR_NONE, -1, true)); + list.push_back(std::make_unique(STR_NONE, -1, true)); } return list; diff --git a/src/roadveh_gui.cpp b/src/roadveh_gui.cpp index 209b919e3a..24eaf8b15d 100644 --- a/src/roadveh_gui.cpp +++ b/src/roadveh_gui.cpp @@ -40,9 +40,7 @@ void DrawRoadVehDetails(const Vehicle *v, const Rect &r) if (v->HasArticulatedPart()) { CargoArray max_cargo{}; - StringID subtype_text[NUM_CARGO]; - - memset(subtype_text, 0, sizeof(subtype_text)); + std::array subtype_text{}; for (const Vehicle *u = v; u != nullptr; u = u->Next()) { max_cargo[u->cargo_type] += u->cargo_cap; @@ -55,16 +53,17 @@ void DrawRoadVehDetails(const Vehicle *v, const Rect &r) std::string capacity = GetString(STR_VEHICLE_DETAILS_TRAIN_ARTICULATED_RV_CAPACITY); bool first = true; - for (CargoID i = 0; i < NUM_CARGO; i++) { - if (max_cargo[i] > 0) { + for (const CargoSpec *cs : _sorted_cargo_specs) { + CargoID cid = cs->Index(); + if (max_cargo[cid] > 0) { if (!first) capacity += ", "; - SetDParam(0, i); - SetDParam(1, max_cargo[i]); + SetDParam(0, cid); + SetDParam(1, max_cargo[cid]); capacity += GetString(STR_JUST_CARGO); - if (subtype_text[i] != 0) { - capacity += GetString(subtype_text[i]); + if (subtype_text[cid] != STR_NULL) { + capacity += GetString(subtype_text[cid]); } first = false; diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 4a90a2e424..ce93899e51 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -2050,9 +2050,9 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_74)) { for (Station *st : Station::Iterate()) { - for (CargoID c = 0; c < NUM_CARGO; c++) { - st->goods[c].last_speed = 0; - if (st->goods[c].CargoAvailableCount() != 0) SetBit(st->goods[c].status, GoodsEntry::GES_RATING); + for (GoodsEntry &ge : st->goods) { + ge.last_speed = 0; + if (ge.CargoAvailableCount() != 0) SetBit(ge.status, GoodsEntry::GES_RATING); } } } diff --git a/src/saveload/game_sl.cpp b/src/saveload/game_sl.cpp index 5aa60d44a0..14ff8bfed4 100644 --- a/src/saveload/game_sl.cpp +++ b/src/saveload/game_sl.cpp @@ -174,7 +174,7 @@ struct GSTRChunkHandler : ChunkHandler { } /* If there were no strings in the savegame, set GameStrings to nullptr */ - if (_current_data->raw_strings.size() == 0) { + if (_current_data->raw_strings.empty()) { delete _current_data; _current_data = nullptr; return; diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index 9c8f643e91..366b165390 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -279,21 +279,21 @@ public: size_t num_cargo = this->GetNumCargo(); for (size_t i = 0; i < num_cargo; i++) { - GoodsEntry *ge = &st->goods[i]; - if (ge->data == nullptr) { + GoodsEntry &ge = st->goods[i]; + if (ge.data == nullptr) { if (spare_ged != nullptr) { - ge->data = std::move(spare_ged); + ge.data = std::move(spare_ged); } else { - ge->data.reset(new GoodsEntryData()); + ge.data.reset(new GoodsEntryData()); } } - SlObject(ge, this->GetLoadDescription()); - if (!IsSavegameVersionBefore(SLV_181)) ge->data->cargo.LoadSetReservedCount(_cargo_reserved_count); + SlObject(&ge, this->GetLoadDescription()); + if (!IsSavegameVersionBefore(SLV_181)) ge.data->cargo.LoadSetReservedCount(_cargo_reserved_count); if (IsSavegameVersionBefore(SLV_183)) { - SwapPackets(ge); + SwapPackets(&ge); } if (IsSavegameVersionBefore(SLV_68)) { - SB(ge->status, GoodsEntry::GES_ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15)); + SB(ge.status, GoodsEntry::GES_ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15)); if (GB(_waiting_acceptance, 0, 12) != 0) { /* In old versions, enroute_from used 0xFF as INVALID_STATION */ StationID source = (IsSavegameVersionBefore(SLV_7) && _cargo_source == 0xFF) ? INVALID_STATION : _cargo_source; @@ -306,12 +306,12 @@ public: /* Don't construct the packet with station here, because that'll fail with old savegames */ CargoPacket *cp = new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_periods, source, _cargo_source_xy, _cargo_feeder_share); - ge->data->cargo.Append(cp, INVALID_STATION); - SB(ge->status, GoodsEntry::GES_RATING, 1, 1); + ge.data->cargo.Append(cp, INVALID_STATION); + SB(ge.status, GoodsEntry::GES_RATING, 1, 1); } } - if (ge->data->MayBeRemoved()) { - spare_ged = std::move(ge->data); + if (ge.data->MayBeRemoved()) { + spare_ged = std::move(ge.data); } } } @@ -320,15 +320,16 @@ public: { Station *st = Station::From(bst); - uint num_cargo = IsSavegameVersionBefore(SLV_55) ? 12 : IsSavegameVersionBefore(SLV_EXTEND_CARGOTYPES) ? 32 : NUM_CARGO; - for (CargoID i = 0; i < num_cargo; i++) { - GoodsEntry *ge = &st->goods[i]; + size_t num_cargo = IsSavegameVersionBefore(SLV_55) ? 12 : IsSavegameVersionBefore(SLV_EXTEND_CARGOTYPES) ? 32 : NUM_CARGO; + auto end = std::next(std::begin(st->goods), std::min(num_cargo, std::size(st->goods))); + for (auto it = std::begin(st->goods); it != end; ++it) { + GoodsEntry &ge = *it; if (IsSavegameVersionBefore(SLV_183)) { - SwapPackets(ge); // We have to swap back again to be in the format pre-183 expects. - SlObject(ge, this->GetDescription()); - SwapPackets(ge); + SwapPackets(&ge); // We have to swap back again to be in the format pre-183 expects. + SlObject(&ge, this->GetDescription()); + SwapPackets(&ge); } else { - SlObject(ge, this->GetDescription()); + SlObject(&ge, this->GetDescription()); } } } diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index 228441fa27..4a8a973411 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.cpp @@ -50,9 +50,9 @@ public: void Save(Town *t) const override { - SlSetStructListLength(NUM_CARGO); - for (CargoID i = 0; i < NUM_CARGO; i++) { - SlObject(&t->supplied[i], this->GetDescription()); + SlSetStructListLength(std::size(t->supplied)); + for (auto &supplied : t->supplied) { + SlObject(&supplied, this->GetDescription()); } } @@ -77,9 +77,9 @@ public: void Save(Town *t) const override { - SlSetStructListLength(NUM_TE); - for (size_t i = TE_BEGIN; i < TE_END; i++) { - SlObject(&t->received[i], this->GetDescription()); + SlSetStructListLength(std::size(t->received)); + for (auto &received : t->received) { + SlObject(&received, this->GetDescription()); } } diff --git a/src/schdispatch_gui.cpp b/src/schdispatch_gui.cpp index e4a2fe3519..b83710c871 100644 --- a/src/schdispatch_gui.cpp +++ b/src/schdispatch_gui.cpp @@ -212,7 +212,7 @@ struct SchdispatchWindow : GeneralVehicleWindow { this->AutoSelectSchedule(); } - void Close() override + void Close(int data = 0) override { if (!FocusWindowById(WC_VEHICLE_VIEW, this->window_number)) { MarkDirtyFocusedRoutePaths(this->vehicle); diff --git a/src/script/api/script_industrytype.cpp b/src/script/api/script_industrytype.cpp index beaf512999..0543187205 100644 --- a/src/script/api/script_industrytype.cpp +++ b/src/script/api/script_industrytype.cpp @@ -70,8 +70,8 @@ const IndustrySpec *ins = ::GetIndustrySpec(industry_type); ScriptList *list = new ScriptList(); - for (size_t i = 0; i < lengthof(ins->produced_cargo); i++) { - if (ins->produced_cargo[i] != CT_INVALID) list->AddItem(ins->produced_cargo[i]); + for (const CargoID &c : ins->produced_cargo) { + if (::IsValidCargoID(c)) list->AddItem(c); } return list; @@ -84,8 +84,8 @@ const IndustrySpec *ins = ::GetIndustrySpec(industry_type); ScriptList *list = new ScriptList(); - for (size_t i = 0; i < lengthof(ins->accepts_cargo); i++) { - if (ins->accepts_cargo[i] != CT_INVALID) list->AddItem(ins->accepts_cargo[i]); + for (const CargoID &c : ins->accepts_cargo) { + if (::IsValidCargoID(c)) list->AddItem(c); } return list; diff --git a/src/script/script_gui.cpp b/src/script/script_gui.cpp index 5b823b8dd6..053a30fb9a 100644 --- a/src/script/script_gui.cpp +++ b/src/script/script_gui.cpp @@ -325,7 +325,7 @@ struct ScriptSettingsWindow : public Window { this->RebuildVisibleSettings(); } - void Close() override + void Close(int data = 0) override { HideDropDownMenu(this); this->Window::Close(); @@ -484,7 +484,7 @@ struct ScriptSettingsWindow : public Window { DropDownList list; for (int i = config_item.min_value; i <= config_item.max_value; i++) { - list.emplace_back(new DropDownListStringItem(config_item.labels.find(i)->second, i, false)); + list.push_back(std::make_unique(config_item.labels.find(i)->second, i, false)); } ShowDropDownListAt(this, std::move(list), old_val, WID_SCRS_SETTING_DROPDOWN, wi_rect, COLOUR_ORANGE); diff --git a/src/script/squirrel.cpp b/src/script/squirrel.cpp index e3008c4414..0469eee29f 100644 --- a/src/script/squirrel.cpp +++ b/src/script/squirrel.cpp @@ -177,7 +177,7 @@ struct ScriptAllocator { ~ScriptAllocator() { #ifdef SCRIPT_DEBUG_ALLOCATIONS - assert(this->allocations.size() == 0); + assert(this->allocations.empty()); #endif } }; diff --git a/src/settings.cpp b/src/settings.cpp index 5a540d359d..f5d0bc420b 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -192,12 +192,11 @@ static bool DecodeHexText(const char *pos, uint8 *dest, size_t dest_size); */ class ConfigIniFile : public IniFile { private: - inline static const char * const list_group_names[] = { + inline static const IniGroupNameList list_group_names = { "bans", "newgrf", "servers", "server_bind_addresses", - nullptr, }; public: @@ -685,16 +684,14 @@ static const char *GetSettingConfigName(const SettingDesc &sd) */ static void IniLoadSettings(IniFile &ini, const SettingTable &settings_table, const char *grpname, void *object, bool only_startup) { - IniGroup *group; - IniGroup *group_def = ini.GetGroup(grpname); + const IniGroup *group; + const IniGroup *group_def = ini.GetGroup(grpname); for (auto &sd : settings_table) { if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue; if (sd->startup != only_startup) continue; - IniItem *item; - if (sd->flags & SF_NO_NEWGAME) { - item = nullptr; - } else { + const IniItem *item = nullptr; + if (!(sd->flags & SF_NO_NEWGAME)) { /* For settings.xx.yy load the settings from [xx] yy = ? */ std::string s{ GetSettingConfigName(*sd) }; auto sc = s.find('.'); @@ -705,8 +702,8 @@ static void IniLoadSettings(IniFile &ini, const SettingTable &settings_table, co group = group_def; } - item = group->GetItem(s); - if (item == nullptr && group != group_def) { + if (group != nullptr) item = group->GetItem(s); + if (item == nullptr && group != group_def && group_def != nullptr) { /* For settings.xx.yy load the settings from [settings] yy = ? in case the previous * did not exist (e.g. loading old config files with a [settings] section */ item = group_def->GetItem(s); @@ -788,10 +785,10 @@ static void IniSaveSettings(IniFile &ini, const SettingTable &settings_table, co std::string s{ GetSettingConfigName(*sd) }; auto sc = s.find('.'); if (sc != std::string::npos) { - group = ini.GetGroup(s.substr(0, sc)); + group = &ini.GetOrCreateGroup(s.substr(0, sc)); s = s.substr(sc + 1); } else { - if (group_def == nullptr) group_def = ini.GetGroup(grpname); + if (group_def == nullptr) group_def = &ini.GetOrCreateGroup(grpname); group = group_def; } @@ -876,14 +873,14 @@ bool ListSettingDesc::IsSameValue(const IniItem *item, void *object) const */ static void IniLoadSettingList(IniFile &ini, const char *grpname, StringList &list) { - IniGroup *group = ini.GetGroup(grpname); + const IniGroup *group = ini.GetGroup(grpname); if (group == nullptr) return; list.clear(); - for (const IniItem *item = group->item; item != nullptr; item = item->next) { - if (!item->name.empty()) list.push_back(item->name); + for (const IniItem &item : group->items) { + if (!item.name.empty()) list.push_back(item.name); } } @@ -898,13 +895,11 @@ static void IniLoadSettingList(IniFile &ini, const char *grpname, StringList &li */ static void IniSaveSettingList(IniFile &ini, const char *grpname, StringList &list) { - IniGroup *group = ini.GetGroup(grpname); - - if (group == nullptr) return; - group->Clear(); + IniGroup &group = ini.GetOrCreateGroup(grpname); + group.Clear(); for (const auto &iter : list) { - group->GetOrCreateItem(iter.c_str()).SetValue(""); + group.GetOrCreateItem(iter).SetValue(""); } } @@ -2013,10 +2008,9 @@ static void HandleOldDiffCustom(bool savegame) } } -static void AILoadConfig(IniFile &ini, const char *grpname) +static void AILoadConfig(const IniFile &ini, const char *grpname) { - IniGroup *group = ini.GetGroup(grpname); - IniItem *item; + const IniGroup *group = ini.GetGroup(grpname); /* Clean any configured AI */ for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { @@ -2027,44 +2021,42 @@ static void AILoadConfig(IniFile &ini, const char *grpname) if (group == nullptr) return; CompanyID c = COMPANY_FIRST; - for (item = group->item; c < MAX_COMPANIES && item != nullptr; c++, item = item->next) { + for (const IniItem &item : group->items) { AIConfig *config = AIConfig::GetConfig(c, AIConfig::SSS_FORCE_NEWGAME); - config->Change(item->name); + config->Change(item.name); if (!config->HasScript()) { - if (item->name != "none") { - DEBUG(script, 0, "The AI by the name '%s' was no longer found, and removed from the list.", item->name.c_str()); + if (item.name != "none") { + DEBUG(script, 0, "The AI by the name '%s' was no longer found, and removed from the list.", item.name.c_str()); continue; } } - if (item->value.has_value()) config->StringToSettings(item->value->c_str()); + if (item.value.has_value()) config->StringToSettings(*item.value); } } -static void GameLoadConfig(IniFile &ini, const char *grpname) +static void GameLoadConfig(const IniFile &ini, const char *grpname) { - IniGroup *group = ini.GetGroup(grpname); - IniItem *item; + const IniGroup *group = ini.GetGroup(grpname); /* Clean any configured GameScript */ GameConfig::GetConfig(GameConfig::SSS_FORCE_NEWGAME)->Change(std::nullopt); /* If no group exists, return */ - if (group == nullptr) return; + if (group == nullptr || group->items.empty()) return; - item = group->item; - if (item == nullptr) return; + const IniItem &item = group->items.front(); GameConfig *config = GameConfig::GetConfig(AIConfig::SSS_FORCE_NEWGAME); - config->Change(item->name); + config->Change(item.name); if (!config->HasScript()) { - if (item->name != "none") { - DEBUG(script, 0, "The GameScript by the name '%s' was no longer found, and removed from the list.", item->name.c_str()); + if (item.name != "none") { + DEBUG(script, 0, "The GameScript by the name '%s' was no longer found, and removed from the list.", item.name.c_str()); return; } } - if (item->value.has_value()) config->StringToSettings(item->value->c_str()); + if (item.value.has_value()) config->StringToSettings(*item.value); } /** @@ -2107,22 +2099,21 @@ static bool DecodeHexText(const char *pos, uint8 *dest, size_t dest_size) * @param grpname Group name containing the configuration of the GRF. * @param is_static GRF is static. */ -static GRFConfig *GRFLoadConfig(IniFile &ini, const char *grpname, bool is_static) +static GRFConfig *GRFLoadConfig(const IniFile &ini, const char *grpname, bool is_static) { - IniGroup *group = ini.GetGroup(grpname); - IniItem *item; + const IniGroup *group = ini.GetGroup(grpname); GRFConfig *first = nullptr; GRFConfig **curr = &first; if (group == nullptr) return nullptr; uint num_grfs = 0; - for (item = group->item; item != nullptr; item = item->next) { + for (const IniItem &item : group->items) { GRFConfig *c = nullptr; uint8 grfid_buf[4]; MD5Hash md5sum; - const char *filename = item->name.c_str(); + const char *filename = item.name.c_str(); bool has_grfid = false; bool has_md5sum = false; @@ -2146,8 +2137,8 @@ static GRFConfig *GRFLoadConfig(IniFile &ini, const char *grpname, bool is_stati if (c == nullptr) c = new GRFConfig(filename); /* Parse parameters */ - if (item->value.has_value() && !item->value->empty()) { - int count = ParseIntList(item->value->c_str(), c->param.data(), c->param.size()); + if (item.value.has_value() && !item.value->empty()) { + int count = ParseIntList(item.value->c_str(), c->param.data(), c->param.size()); if (count < 0) { SetDParamStr(0, filename); ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_ARRAY, WL_CRITICAL); @@ -2170,7 +2161,7 @@ static GRFConfig *GRFLoadConfig(IniFile &ini, const char *grpname, bool is_stati SetDParam(1, STR_CONFIG_ERROR_INVALID_GRF_UNKNOWN); } - SetDParamStr(0, StrEmpty(filename) ? item->name.c_str() : filename); + SetDParamStr(0, StrEmpty(filename) ? item.name.c_str() : filename); ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_GRF, WL_CRITICAL); delete c; continue; @@ -2209,9 +2200,10 @@ static GRFConfig *GRFLoadConfig(IniFile &ini, const char *grpname, bool is_stati return first; } -static IniFileVersion LoadVersionFromConfig(IniFile &ini) +static IniFileVersion LoadVersionFromConfig(const IniFile &ini) { - IniGroup *group = ini.GetGroup("version"); + const IniGroup *group = ini.GetGroup("version"); + if (group == nullptr) return IFV_0; auto version_number = group->GetItem("ini_version"); /* Older ini-file versions don't have this key yet. */ @@ -2225,10 +2217,8 @@ static IniFileVersion LoadVersionFromConfig(IniFile &ini) static void AISaveConfig(IniFile &ini, const char *grpname) { - IniGroup *group = ini.GetGroup(grpname); - - if (group == nullptr) return; - group->Clear(); + IniGroup &group = ini.GetOrCreateGroup(grpname); + group.Clear(); for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { AIConfig *config = AIConfig::GetConfig(c, AIConfig::SSS_FORCE_NEWGAME); @@ -2241,17 +2231,14 @@ static void AISaveConfig(IniFile &ini, const char *grpname) name = "none"; } - IniItem *item = new IniItem(group, name); - item->SetValue(value); + group.CreateItem(name).SetValue(value); } } static void GameSaveConfig(IniFile &ini, const char *grpname) { - IniGroup *group = ini.GetGroup(grpname); - - if (group == nullptr) return; - group->Clear(); + IniGroup &group = ini.GetOrCreateGroup(grpname); + group.Clear(); GameConfig *config = GameConfig::GetConfig(AIConfig::SSS_FORCE_NEWGAME); std::string name; @@ -2263,8 +2250,7 @@ static void GameSaveConfig(IniFile &ini, const char *grpname) name = "none"; } - IniItem *item = new IniItem(group, name); - item->SetValue(value); + group.CreateItem(name).SetValue(value); } /** @@ -2273,17 +2259,17 @@ static void GameSaveConfig(IniFile &ini, const char *grpname) */ static void SaveVersionInConfig(IniFile &ini) { - IniGroup *group = ini.GetGroup("version"); - group->GetOrCreateItem("version_string").SetValue(_openttd_revision); - group->GetOrCreateItem("version_number").SetValue(stdstr_fmt("%08X", _openttd_newgrf_version)); - group->GetOrCreateItem("ini_version").SetValue(std::to_string(INIFILE_VERSION)); + IniGroup &group = ini.GetOrCreateGroup("version"); + group.GetOrCreateItem("version_string").SetValue(_openttd_revision); + group.GetOrCreateItem("version_number").SetValue(stdstr_fmt("%08X", _openttd_newgrf_version)); + group.GetOrCreateItem("ini_version").SetValue(std::to_string(INIFILE_VERSION)); } /* Save a GRF configuration to the given group name */ static void GRFSaveConfig(IniFile &ini, const char *grpname, const GRFConfig *list) { - ini.RemoveGroup(grpname); - IniGroup *group = ini.GetGroup(grpname); + IniGroup &group = ini.GetOrCreateGroup(grpname); + group.Clear(); const GRFConfig *c; for (c = list; c != nullptr; c = c->next) { @@ -2292,7 +2278,7 @@ static void GRFSaveConfig(IniFile &ini, const char *grpname, const GRFConfig *li char *pos = key + seprintf(key, lastof(key), "%08X|", BSWAP32(c->ident.grfid)); pos = md5sumToString(pos, lastof(key), c->ident.md5sum); seprintf(pos, lastof(key), "|%s", c->filename.c_str()); - group->GetOrCreateItem(key).SetValue(GRFBuildParamList(c)); + group.GetOrCreateItem(key).SetValue(GRFBuildParamList(c)); } } @@ -2353,6 +2339,7 @@ static void RemoveEntriesFromIni(IniFile &ini, const SettingTable &table) if (sc == std::string::npos) continue; IniGroup *group = ini.GetGroup(s.substr(0, sc)); + if (group == nullptr) continue; s = s.substr(sc + 1); group->RemoveItem(s); @@ -2382,16 +2369,16 @@ static void RemoveEntriesFromIni(IniFile &ini, const SettingTable &table) * @param[out] old_item The old item to base upgrading on. * @return Whether upgrading should happen; if false, old_item is a nullptr. */ -bool IsConversionNeeded(ConfigIniFile &ini, std::string group, std::string old_var, std::string new_var, IniItem **old_item) +bool IsConversionNeeded(const ConfigIniFile &ini, const std::string &group, const std::string &old_var, const std::string &new_var, const IniItem **old_item) { *old_item = nullptr; - IniGroup *igroup = ini.GetGroup(group, false); + const IniGroup *igroup = ini.GetGroup(group); /* If the group doesn't exist, there is nothing to convert. */ if (igroup == nullptr) return false; - IniItem *tmp_old_item = igroup->GetItem(old_var); - IniItem *new_item = igroup->GetItem(new_var); + const IniItem *tmp_old_item = igroup->GetItem(old_var); + const IniItem *new_item = igroup->GetItem(new_var); /* If the old item doesn't exist, there is nothing to convert. */ if (tmp_old_item == nullptr) return false; @@ -2442,9 +2429,9 @@ void LoadFromConfig(bool startup) /* Move no_http_content_downloads and use_relay_service from generic_ini to private_ini. */ if (generic_version < IFV_NETWORK_PRIVATE_SETTINGS) { - IniGroup *network = generic_ini.GetGroup("network", false); + const IniGroup *network = generic_ini.GetGroup("network"); if (network != nullptr) { - IniItem *no_http_content_downloads = network->GetItem("no_http_content_downloads"); + const IniItem *no_http_content_downloads = network->GetItem("no_http_content_downloads"); if (no_http_content_downloads != nullptr) { if (no_http_content_downloads->value == "true") { _settings_client.network.no_http_content_downloads = true; @@ -2453,7 +2440,7 @@ void LoadFromConfig(bool startup) } } - IniItem *use_relay_service = network->GetItem("use_relay_service"); + const IniItem *use_relay_service = network->GetItem("use_relay_service"); if (use_relay_service != nullptr) { if (use_relay_service->value == "never") { _settings_client.network.use_relay_service = UseRelayService::URS_NEVER; @@ -2466,7 +2453,7 @@ void LoadFromConfig(bool startup) } } - IniItem *old_item; + const IniItem *old_item; if (generic_version < IFV_GAME_TYPE && IsConversionNeeded(generic_ini, "network", "server_advertise", "server_game_type", &old_item)) { auto old_value = BoolSettingDesc::ParseSingleValue(old_item->value->c_str()); @@ -2484,14 +2471,14 @@ void LoadFromConfig(bool startup) case 3: _settings_client.gui.autosave_interval = 60; break; case 4: _settings_client.gui.autosave_interval = 120; break; case 5: { - IniItem *old_autosave_custom_days; + const IniItem *old_autosave_custom_days; if (IsConversionNeeded(generic_ini, "gui", "autosave_custom_days", "autosave_interval", &old_autosave_custom_days)) { _settings_client.gui.autosave_interval = (std::strtoul(old_autosave_custom_days->value->c_str(), nullptr, 10) + 2) / 3; } break; } case 6: { - IniItem *old_autosave_custom_minutes; + const IniItem *old_autosave_custom_minutes; if (IsConversionNeeded(generic_ini, "gui", "autosave_custom_minutes", "autosave_interval", &old_autosave_custom_minutes)) { _settings_client.gui.autosave_interval = std::strtoul(old_autosave_custom_minutes->value->c_str(), nullptr, 10); } @@ -2542,7 +2529,7 @@ void SaveToConfig(SaveToConfigFlags flags) * just so we can add a comment before it (that is how IniFile works). * This to explain what the file is about. After doing it once, never touch * it again, as otherwise we might be reverting user changes. */ - if (!private_ini.GetGroup("private", false)) private_ini.GetGroup("private")->comment = "; This file possibly contains private information which can identify you as person.\n"; + if (IniGroup *group = private_ini.GetGroup("private"); group != nullptr) group->comment = "; This file possibly contains private information which can identify you as person.\n"; HandlePrivateSettingDescs(private_ini, IniSaveSettings, IniSaveSettingList); SaveVersionInConfig(private_ini); @@ -2556,7 +2543,7 @@ void SaveToConfig(SaveToConfigFlags flags) * just so we can add a comment before it (that is how IniFile works). * This to explain what the file is about. After doing it once, never touch * it again, as otherwise we might be reverting user changes. */ - if (!secrets_ini.GetGroup("secrets", false)) secrets_ini.GetGroup("secrets")->comment = "; Do not share this file with others, not even if they claim to be technical support.\n; This file contains saved passwords and other secrets that should remain private to you!\n"; + if (IniGroup *group = secrets_ini.GetGroup("secrets"); group != nullptr) group->comment = "; Do not share this file with others, not even if they claim to be technical support.\n; This file contains saved passwords and other secrets that should remain private to you!\n"; HandleSecretsSettingDescs(secrets_ini, IniSaveSettings, IniSaveSettingList); SaveVersionInConfig(secrets_ini); @@ -2593,7 +2580,7 @@ void SaveToConfig(SaveToConfigFlags flags) /* These variables are migrated from generic ini to private ini now. */ if (generic_version < IFV_NETWORK_PRIVATE_SETTINGS) { - IniGroup *network = generic_ini.GetGroup("network", false); + IniGroup *network = generic_ini.GetGroup("network"); if (network != nullptr) { network->RemoveItem("no_http_content_downloads"); network->RemoveItem("use_relay_service"); @@ -2620,9 +2607,9 @@ StringList GetGRFPresetList() StringList list; ConfigIniFile ini(_config_file); - for (IniGroup *group = ini.group; group != nullptr; group = group->next) { - if (group->name.compare(0, 7, "preset-") == 0) { - list.push_back(group->name.substr(7)); + for (const IniGroup &group : ini.groups) { + if (group.name.compare(0, 7, "preset-") == 0) { + list.push_back(group.name.substr(7)); } } diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 63e6916518..82f712af23 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -201,7 +201,7 @@ struct GameOptionsWindow : Window { if constexpr (!NetworkSurveyHandler::IsSurveyPossible()) this->GetWidget(WID_GO_SURVEY_SEL)->SetDisplayedPlane(SZSP_NONE); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { CloseWindowById(WC_CUSTOM_CURRENCY, 0); CloseWindowByClass(WC_TEXTFILE); @@ -228,18 +228,18 @@ struct GameOptionsWindow : Window { int i = ¤cy - _currency_specs; if (i == CURRENCY_CUSTOM) continue; if (currency.code.empty()) { - list.emplace_back(new DropDownListStringItem(currency.name, i, HasBit(disabled, i))); + list.push_back(std::make_unique(currency.name, i, HasBit(disabled, i))); } else { SetDParam(0, currency.name); SetDParamStr(1, currency.code); - list.emplace_back(new DropDownListStringItem(STR_GAME_OPTIONS_CURRENCY_CODE, i, HasBit(disabled, i))); + list.push_back(std::make_unique(STR_GAME_OPTIONS_CURRENCY_CODE, i, HasBit(disabled, i))); } } std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc); /* Append custom currency at the end */ - list.emplace_back(new DropDownListItem(-1, false)); // separator line - list.emplace_back(new DropDownListStringItem(STR_GAME_OPTIONS_CURRENCY_CUSTOM, CURRENCY_CUSTOM, HasBit(disabled, CURRENCY_CUSTOM))); + list.push_back(std::make_unique(-1, false)); // separator line + list.push_back(std::make_unique(STR_GAME_OPTIONS_CURRENCY_CUSTOM, CURRENCY_CUSTOM, HasBit(disabled, CURRENCY_CUSTOM))); break; } @@ -256,7 +256,7 @@ struct GameOptionsWindow : Window { const StringID *items = _autosave_dropdown; for (uint i = 0; *items != INVALID_STRING_ID; items++, i++) { - list.emplace_back(new DropDownListStringItem(*items, i, false)); + list.push_back(std::make_unique(*items, i, false)); } break; } @@ -278,7 +278,7 @@ struct GameOptionsWindow : Window { SetDParamStr(0, _languages[i].name); } SetDParam(1, (LANGUAGE_TOTAL_STRINGS - _languages[i].missing) * 100 / LANGUAGE_TOTAL_STRINGS); - list.emplace_back(new DropDownListStringItem(hide_percentage ? STR_JUST_RAW_STRING : STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE, i, false)); + list.push_back(std::make_unique(hide_percentage ? STR_JUST_RAW_STRING : STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE, i, false)); } std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc); break; @@ -291,7 +291,7 @@ struct GameOptionsWindow : Window { for (uint i = 0; i < _resolutions.size(); i++) { SetDParam(0, _resolutions[i].width); SetDParam(1, _resolutions[i].height); - list.emplace_back(new DropDownListStringItem(STR_GAME_OPTIONS_RESOLUTION_ITEM, i, false)); + list.push_back(std::make_unique(STR_GAME_OPTIONS_RESOLUTION_ITEM, i, false)); } break; @@ -300,7 +300,7 @@ struct GameOptionsWindow : Window { auto i = std::distance(_refresh_rates.begin(), it); if (*it == _settings_client.gui.refresh_rate) *selected_index = i; SetDParam(0, *it); - list.emplace_back(new DropDownListStringItem(STR_GAME_OPTIONS_REFRESH_RATE_ITEM, i, false)); + list.push_back(std::make_unique(STR_GAME_OPTIONS_REFRESH_RATE_ITEM, i, false)); } break; @@ -2709,15 +2709,15 @@ struct GameSettingsWindow : Window { * we don't want to allow comparing with new game's settings. */ bool disabled = mode == RM_CHANGED_AGAINST_NEW && settings_ptr == &_settings_newgame; - list.emplace_back(new DropDownListStringItem(_game_settings_restrict_dropdown[mode], mode, disabled)); + list.push_back(std::make_unique(_game_settings_restrict_dropdown[mode], mode, disabled)); } break; case WID_GS_TYPE_DROPDOWN: - list.emplace_back(new DropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL, ST_ALL, false)); - list.emplace_back(new DropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME, ST_GAME, false)); - list.emplace_back(new DropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME, ST_COMPANY, false)); - list.emplace_back(new DropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT, ST_CLIENT, false)); + list.push_back(std::make_unique(STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL, ST_ALL, false)); + list.push_back(std::make_unique(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME, ST_GAME, false)); + list.push_back(std::make_unique(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME, ST_COMPANY, false)); + list.push_back(std::make_unique(STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT, ST_CLIENT, false)); break; } return list; @@ -2913,11 +2913,11 @@ struct GameSettingsWindow : Window { } } assert_msg(val >= sd->min && val <= (int)sd->max, "min: %d, max: %d, val: %d", sd->min, sd->max, val); - list.emplace_back(new DropDownListStringItem(sd->str_val + val - sd->min, val, false)); + list.push_back(std::make_unique(sd->str_val + val - sd->min, val, false)); } } else if ((sd->flags & SF_ENUM)) { for (const SettingDescEnumEntry *enumlist = sd->enumlist; enumlist != nullptr && enumlist->str != STR_NULL; enumlist++) { - list.emplace_back(new DropDownListStringItem(enumlist->str, enumlist->val, false)); + list.push_back(std::make_unique(enumlist->str, enumlist->val, false)); } } diff --git a/src/settings_gui.h b/src/settings_gui.h index 7a3f69e364..f4352f4fbd 100644 --- a/src/settings_gui.h +++ b/src/settings_gui.h @@ -29,7 +29,7 @@ DropDownList BuildSetDropDownList(int *selected_index) *selected_index = T::GetIndexOfUsedSet(); DropDownList list; for (int i = 0; i < n; i++) { - list.emplace_back(new DropDownListStringItem(T::GetSet(i)->name, i, false)); + list.push_back(std::make_unique(T::GetSet(i)->name, i, false)); } return list; } diff --git a/src/settingsgen/settingsgen.cpp b/src/settingsgen/settingsgen.cpp index c54224d73e..d9146da017 100644 --- a/src/settingsgen/settingsgen.cpp +++ b/src/settingsgen/settingsgen.cpp @@ -157,10 +157,10 @@ private: struct SettingsIniFile : IniLoadFile { /** * Construct a new ini loader. - * @param list_group_names A \c nullptr terminated list with group names that should be loaded as lists instead of variables. @see IGT_LIST - * @param seq_group_names A \c nullptr terminated list with group names that should be loaded as lists of names. @see IGT_SEQUENCE + * @param list_group_names A list with group names that should be loaded as lists instead of variables. @see IGT_LIST + * @param seq_group_names A list with group names that should be loaded as lists of names. @see IGT_SEQUENCE */ - SettingsIniFile(const char * const *list_group_names = nullptr, const char * const *seq_group_names = nullptr) : + SettingsIniFile(const IniGroupNameList &list_group_names = {}, const IniGroupNameList &seq_group_names = {}) : IniLoadFile(list_group_names, seq_group_names) { } @@ -194,32 +194,18 @@ static const char *TEMPLATES_GROUP_NAME = "templates"; ///< Name of the group co static const char *VALIDATION_GROUP_NAME = "validation"; ///< Name of the group containing the validation statements. static const char *DEFAULTS_GROUP_NAME = "defaults"; ///< Name of the group containing default values for the template variables. -/** - * Load the INI file. - * @param filename Name of the file to load. - * @return Loaded INI data. - */ -static IniLoadFile *LoadIniFile(const char *filename) -{ - static const char * const seq_groups[] = {PREAMBLE_GROUP_NAME, POSTAMBLE_GROUP_NAME, nullptr}; - - IniLoadFile *ini = new SettingsIniFile(nullptr, seq_groups); - ini->LoadFromDisk(filename, NO_DIRECTORY); - return ini; -} - /** * Dump a #IGT_SEQUENCE group into #_stored_output. * @param ifile Loaded INI data. * @param group_name Name of the group to copy. */ -static void DumpGroup(IniLoadFile *ifile, const char * const group_name) +static void DumpGroup(const IniLoadFile &ifile, const char * const group_name) { - IniGroup *grp = ifile->GetGroup(group_name, false); + const IniGroup *grp = ifile.GetGroup(group_name); if (grp != nullptr && grp->type == IGT_SEQUENCE) { - for (IniItem *item = grp->item; item != nullptr; item = item->next) { - if (!item->name.empty()) { - _stored_output.Add(item->name.c_str()); + for (const IniItem &item : grp->items) { + if (!item.name.empty()) { + _stored_output.Add(item.name.c_str()); _stored_output.Add("\n", 1); } } @@ -233,9 +219,9 @@ static void DumpGroup(IniLoadFile *ifile, const char * const group_name) * @param defaults Fallback group to search, \c nullptr skips the search. * @return Text of the item if found, else \c nullptr. */ -static const char *FindItemValue(const char *name, IniGroup *grp, IniGroup *defaults) +static const char *FindItemValue(const char *name, const IniGroup *grp, const IniGroup *defaults) { - IniItem *item = grp->GetItem(name); + const IniItem *item = grp->GetItem(name); if (item == nullptr && defaults != nullptr) item = defaults->GetItem(name); if (item == nullptr || !item->value.has_value()) return nullptr; return item->value->c_str(); @@ -248,18 +234,18 @@ static const char *FindItemValue(const char *name, IniGroup *grp, IniGroup *defa * @param default_grp Default values for items not set in @grp. * @param output Output to use for result. */ -static void DumpLine(IniItem *item, IniGroup *grp, IniGroup *default_grp, OutputStore &output) +static void DumpLine(const IniItem *item, const IniGroup *grp, const IniGroup *default_grp, OutputStore &output) { static const int MAX_VAR_LENGTH = 64; /* Prefix with #if/#ifdef/#ifndef */ - static const char * const pp_lines[] = {"if", "ifdef", "ifndef", nullptr}; + static const auto pp_lines = {"if", "ifdef", "ifndef"}; int count = 0; - for (const char * const *name = pp_lines; *name != nullptr; name++) { - const char *condition = FindItemValue(*name, grp, default_grp); + for (const auto &name : pp_lines) { + const char *condition = FindItemValue(name, grp, default_grp); if (condition != nullptr) { output.Add("#", 1); - output.Add(*name); + output.Add(name); output.Add(" ", 1); output.Add(condition); output.Add("\n", 1); @@ -312,31 +298,30 @@ static void DumpLine(IniItem *item, IniGroup *grp, IniGroup *default_grp, Output * Output all non-special sections through the template / template variable expansion system. * @param ifile Loaded INI data. */ -static void DumpSections(IniLoadFile *ifile) +static void DumpSections(const IniLoadFile &ifile) { - static const char * const special_group_names[] = {PREAMBLE_GROUP_NAME, POSTAMBLE_GROUP_NAME, DEFAULTS_GROUP_NAME, TEMPLATES_GROUP_NAME, VALIDATION_GROUP_NAME, nullptr}; + static const auto special_group_names = {PREAMBLE_GROUP_NAME, POSTAMBLE_GROUP_NAME, DEFAULTS_GROUP_NAME, TEMPLATES_GROUP_NAME, VALIDATION_GROUP_NAME}; - IniGroup *default_grp = ifile->GetGroup(DEFAULTS_GROUP_NAME, false); - IniGroup *templates_grp = ifile->GetGroup(TEMPLATES_GROUP_NAME, false); - IniGroup *validation_grp = ifile->GetGroup(VALIDATION_GROUP_NAME, false); + const IniGroup *default_grp = ifile.GetGroup(DEFAULTS_GROUP_NAME); + const IniGroup *templates_grp = ifile.GetGroup(TEMPLATES_GROUP_NAME); + const IniGroup *validation_grp = ifile.GetGroup(VALIDATION_GROUP_NAME); if (templates_grp == nullptr) return; /* Output every group, using its name as template name. */ - for (IniGroup *grp = ifile->group; grp != nullptr; grp = grp->next) { - const char * const *sgn; - for (sgn = special_group_names; *sgn != nullptr; sgn++) if (grp->name == *sgn) break; - if (*sgn != nullptr) continue; + for (const IniGroup &grp : ifile.groups) { + /* Exclude special group names. */ + if (std::find(std::begin(special_group_names), std::end(special_group_names), grp.name) != std::end(special_group_names)) continue; - IniItem *template_item = templates_grp->GetItem(grp->name); // Find template value. + const IniItem *template_item = templates_grp->GetItem(grp.name); // Find template value. if (template_item == nullptr || !template_item->value.has_value()) { - error("Cannot find template %s", grp->name.c_str()); + error("Cannot find template %s", grp.name.c_str()); } - DumpLine(template_item, grp, default_grp, _stored_output); + DumpLine(template_item, &grp, default_grp, _stored_output); if (validation_grp != nullptr) { - IniItem *validation_item = validation_grp->GetItem(grp->name); // Find template value. + const IniItem *validation_item = validation_grp->GetItem(grp.name); // Find template value. if (validation_item != nullptr && validation_item->value.has_value()) { - DumpLine(validation_item, grp, default_grp, _post_amble_output); + DumpLine(validation_item, &grp, default_grp, _post_amble_output); } } } @@ -436,11 +421,14 @@ static const OptionData _opts[] = { */ static void ProcessIniFile(const char *fname) { - IniLoadFile *ini_data = LoadIniFile(fname); - DumpGroup(ini_data, PREAMBLE_GROUP_NAME); - DumpSections(ini_data); - DumpGroup(ini_data, POSTAMBLE_GROUP_NAME); - delete ini_data; + static const IniLoadFile::IniGroupNameList seq_groups = {PREAMBLE_GROUP_NAME, POSTAMBLE_GROUP_NAME}; + + SettingsIniFile ini{{}, seq_groups}; + ini.LoadFromDisk(fname, NO_DIRECTORY); + + DumpGroup(ini, PREAMBLE_GROUP_NAME); + DumpSections(ini); + DumpGroup(ini, POSTAMBLE_GROUP_NAME); } /** diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index 5e8689e9bf..a4086af26f 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -1088,7 +1088,7 @@ SmallMapWindow::~SmallMapWindow() delete this->overlay; } -/* virtual */ void SmallMapWindow::Close() +/* virtual */ void SmallMapWindow::Close([[maybe_unused]] int data) { this->BreakIndustryChainLink(); this->Window::Close(); diff --git a/src/smallmap_gui.h b/src/smallmap_gui.h index 0351c6b016..5af983cb03 100644 --- a/src/smallmap_gui.h +++ b/src/smallmap_gui.h @@ -207,7 +207,7 @@ public: void SmallMapCenterOnCurrentPos(); Point GetStationMiddle(const Station *st) const; - void Close() override; + void Close([[maybe_unused]] int data = 0) override; void SetStringParameters(int widget) const override; void OnInit() override; void OnPaint() override; diff --git a/src/spritecache.cpp b/src/spritecache.cpp index bc37f94725..4e91f99867 100644 --- a/src/spritecache.cpp +++ b/src/spritecache.cpp @@ -259,7 +259,7 @@ SpriteFile &OpenCachedSpriteFile(const std::string &filename, Subdirectory subdi { SpriteFile *file = GetCachedSpriteFileByName(filename); if (file == nullptr) { - file = _sprite_files.emplace_back(new SpriteFile(filename, subdir, palette_remap)).get(); + file = _sprite_files.insert(std::end(_sprite_files), std::make_unique(filename, subdir, palette_remap))->get(); } else { file->SeekToBegin(); } diff --git a/src/station.cpp b/src/station.cpp index 4bde39cff8..e7d07cc9d5 100644 --- a/src/station.cpp +++ b/src/station.cpp @@ -94,8 +94,8 @@ Station::Station(TileIndex tile) : Station::~Station() { if (CleaningPool()) { - for (CargoID c = 0; c < NUM_CARGO; c++) { - if (this->goods[c].data != nullptr) this->goods[c].data->cargo.OnCleanPool(); + for (GoodsEntry &ge : this->goods) { + if (ge.data != nullptr) ge.data->cargo.OnCleanPool(); } return; } @@ -163,8 +163,8 @@ Station::~Station() /* Remove all news items */ DeleteStationNews(this->index); - for (CargoID c = 0; c < NUM_CARGO; c++) { - if (this->goods[c].data != nullptr) this->goods[c].data->cargo.Truncate(); + for (GoodsEntry &ge : this->goods) { + if (ge.data != nullptr) ge.data->cargo.Truncate(); } CargoPacket::InvalidateAllFrom(this->index); @@ -269,7 +269,7 @@ void Station::MarkTilesDirty(bool cargo_change) const /* Don't waste time updating if there are no custom station graphics * that might change. Even if there are custom graphics, they might * not change. Unfortunately we have no way of telling. */ - if (this->speclist.size() == 0) return; + if (this->speclist.empty()) return; } for (h = 0; h < train_station.h; h++) { diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 1332a1ce79..92e9cb2212 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -595,16 +595,16 @@ CargoTypes GetEmptyMask(const Station *st) } /** - * Items contains the two cargo names that are to be accepted or rejected. - * msg is the string id of the message to display. + * Add news item for when a station changes which cargoes it accepts. + * @param st Station of cargo change. + * @param cargoes Bit mask of cargo types to list. + * @param reject True iff the station rejects the cargo types. */ -static void ShowRejectOrAcceptNews(const Station *st, uint num_items, CargoID *cargo, StringID msg) +static void ShowRejectOrAcceptNews(const Station *st, CargoTypes cargoes, bool reject) { - for (uint i = 0; i < num_items; i++) { - SetDParam(i + 1, CargoSpec::Get(cargo[i])->name); - } - SetDParam(0, st->index); + SetDParam(1, cargoes); + StringID msg = reject ? STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_LIST : STR_NEWS_STATION_NOW_ACCEPTS_CARGO_LIST; AddNewsItem(msg, NT_ACCEPTANCE, NF_INCOLOUR | NF_SMALL, NR_STATION, st->index); } @@ -730,41 +730,13 @@ void UpdateStationAcceptance(Station *st, bool show_msg) /* show a message to report that the acceptance was changed? */ if (show_msg && st->owner == _local_company && st->IsInUse()) { - /* List of accept and reject strings for different number of - * cargo types */ - static const StringID accept_msg[] = { - STR_NEWS_STATION_NOW_ACCEPTS_CARGO, - STR_NEWS_STATION_NOW_ACCEPTS_CARGO_AND_CARGO, - }; - static const StringID reject_msg[] = { - STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO, - STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO, - }; - - /* Array of accepted and rejected cargo types */ - CargoID accepts[2] = { CT_INVALID, CT_INVALID }; - CargoID rejects[2] = { CT_INVALID, CT_INVALID }; - uint num_acc = 0; - uint num_rej = 0; - - /* Test each cargo type to see if its acceptance has changed */ - for (CargoID i = 0; i < NUM_CARGO; i++) { - if (HasBit(new_acc, i)) { - if (!HasBit(old_acc, i) && num_acc < lengthof(accepts)) { - /* New cargo is accepted */ - accepts[num_acc++] = i; - } - } else { - if (HasBit(old_acc, i) && num_rej < lengthof(rejects)) { - /* Old cargo is no longer accepted */ - rejects[num_rej++] = i; - } - } - } + /* Combine old and new masks to get changes */ + CargoTypes accepts = new_acc & ~old_acc; + CargoTypes rejects = ~new_acc & old_acc; /* Show news message if there are any changes */ - if (num_acc > 0) ShowRejectOrAcceptNews(st, num_acc, accepts, accept_msg[num_acc - 1]); - if (num_rej > 0) ShowRejectOrAcceptNews(st, num_rej, rejects, reject_msg[num_rej - 1]); + if (accepts != 0) ShowRejectOrAcceptNews(st, accepts, false); + if (rejects != 0) ShowRejectOrAcceptNews(st, rejects, true); } /* redraw the station view since acceptance changed */ @@ -783,10 +755,10 @@ static void UpdateStationSignCoord(BaseStation *st) if (!Station::IsExpected(st)) return; Station *full_station = Station::From(st); - for (CargoID c = 0; c < NUM_CARGO; ++c) { - LinkGraphID lg = full_station->goods[c].link_graph; + for (const GoodsEntry &ge : full_station->goods) { + LinkGraphID lg = ge.link_graph; if (!LinkGraph::IsValidID(lg)) continue; - (*LinkGraph::Get(lg))[full_station->goods[c].node].UpdateLocation(st->xy); + (*LinkGraph::Get(lg))[ge.node].UpdateLocation(st->xy); } } @@ -4110,8 +4082,8 @@ static bool StationHandleBigTick(BaseStation *st) if (Station::IsExpected(st)) { TriggerWatchedCargoCallbacks(Station::From(st)); - for (CargoID i = 0; i < NUM_CARGO; i++) { - ClrBit(Station::From(st)->goods[i].status, GoodsEntry::GES_ACCEPTED_BIGTICK); + for (GoodsEntry &ge : Station::From(st)->goods) { + ClrBit(ge.status, GoodsEntry::GES_ACCEPTED_BIGTICK); } } @@ -4683,10 +4655,9 @@ void StationDailyLoop() void StationMonthlyLoop() { for (Station *st : Station::Iterate()) { - for (CargoID i = 0; i < NUM_CARGO; i++) { - GoodsEntry *ge = &st->goods[i]; - SB(ge->status, GoodsEntry::GES_LAST_MONTH, 1, GB(ge->status, GoodsEntry::GES_CURRENT_MONTH, 1)); - ClrBit(ge->status, GoodsEntry::GES_CURRENT_MONTH); + for (GoodsEntry &ge : st->goods) { + SB(ge.status, GoodsEntry::GES_LAST_MONTH, 1, GB(ge.status, GoodsEntry::GES_CURRENT_MONTH, 1)); + ClrBit(ge.status, GoodsEntry::GES_CURRENT_MONTH); } } } @@ -4696,11 +4667,9 @@ void ModifyStationRatingAround(TileIndex tile, Owner owner, int amount, uint rad { ForAllStationsRadius(tile, radius, [&](Station *st) { if (st->owner == owner && DistanceManhattan(tile, st->xy) <= radius) { - for (CargoID i = 0; i < NUM_CARGO; i++) { - GoodsEntry *ge = &st->goods[i]; - - if (ge->status != 0) { - ge->rating = ClampTo(ge->rating + amount); + for (GoodsEntry &ge : st->goods) { + if (ge.status != 0) { + ge.rating = ClampTo(ge.rating + amount); } } } diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 4265006c19..a569ce5fcc 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -372,8 +372,7 @@ protected: byte minr1 = 255; byte minr2 = 255; - for (CargoID j = 0; j < NUM_CARGO; j++) { - if (!HasBit(cargo_filter, j)) continue; + for (CargoID j : SetCargoBitIterator(cargo_filter)) { if (a->goods[j].HasRating()) minr1 = std::min(minr1, a->goods[j].rating); if (b->goods[j].HasRating()) minr2 = std::min(minr2, b->goods[j].rating); } @@ -480,7 +479,7 @@ public: this->GetWidget(WID_STL_SORTDROPBTN)->widget_data = this->sorter_names[this->stations.SortType()]; } - void Close() override + void Close(int data = 0) override { this->last_sorting = this->stations.GetListing(); this->Window::Close(); @@ -1438,7 +1437,7 @@ struct StationViewWindow : public Window { ZoningStationWindowOpenClose(Station::Get(window_number)); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { ZoningStationWindowOpenClose(Station::Get(window_number)); CloseWindowById(WC_TRAINS_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_TRAIN, this->owner, this->window_number).Pack(), false); @@ -2548,7 +2547,7 @@ struct SelectStationWindow : Window { _thd.freeze = true; } - void Close() override + void Close([[maybe_unused]] int data = 0) override { SetViewportCatchmentStation(nullptr, true); diff --git a/src/story_gui.cpp b/src/story_gui.cpp index c7a18d8429..a6b39c3e7d 100644 --- a/src/story_gui.cpp +++ b/src/story_gui.cpp @@ -256,11 +256,11 @@ protected: for (const StoryPage *p : this->story_pages) { bool current_page = p->index == this->selected_page_id; if (!p->title.empty()) { - list.emplace_back(new DropDownListStringItem(p->title, p->index, current_page)); + list.push_back(std::make_unique(p->title, p->index, current_page)); } else { /* No custom title => use a generic page title with page number. */ SetDParam(0, page_num); - list.emplace_back(new DropDownListStringItem(STR_STORY_BOOK_GENERIC_PAGE_ITEM, p->index, current_page)); + list.push_back(std::make_unique(STR_STORY_BOOK_GENERIC_PAGE_ITEM, p->index, current_page)); } page_num++; } @@ -625,8 +625,8 @@ public: */ void UpdatePrevNextDisabledState() { - this->SetWidgetDisabledState(WID_SB_PREV_PAGE, story_pages.size() == 0 || this->IsFirstPageSelected()); - this->SetWidgetDisabledState(WID_SB_NEXT_PAGE, story_pages.size() == 0 || this->IsLastPageSelected()); + this->SetWidgetDisabledState(WID_SB_PREV_PAGE, story_pages.empty() || this->IsFirstPageSelected()); + this->SetWidgetDisabledState(WID_SB_NEXT_PAGE, story_pages.empty() || this->IsLastPageSelected()); this->SetWidgetDirty(WID_SB_PREV_PAGE); this->SetWidgetDirty(WID_SB_NEXT_PAGE); } @@ -872,7 +872,7 @@ public: this->BuildStoryPageList(); /* Was the last page removed? */ - if (this->story_pages.size() == 0) { + if (this->story_pages.empty()) { this->selected_generic_title.clear(); } @@ -880,14 +880,14 @@ public: if (!_story_page_pool.IsValidID(this->selected_page_id)) { this->selected_page_id = INVALID_STORY_PAGE; } - if (this->selected_page_id == INVALID_STORY_PAGE && this->story_pages.size() > 0) { + if (this->selected_page_id == INVALID_STORY_PAGE && !this->story_pages.empty()) { /* No page is selected, but there exist at least one available. * => Select first page. */ this->SetSelectedPage(this->story_pages[0]->index); } - this->SetWidgetDisabledState(WID_SB_SEL_PAGE, this->story_pages.size() == 0); + this->SetWidgetDisabledState(WID_SB_SEL_PAGE, this->story_pages.empty()); this->SetWidgetDirty(WID_SB_SEL_PAGE); this->UpdatePrevNextDisabledState(); } else if (data >= 0 && this->selected_page_id == data) { diff --git a/src/string.cpp b/src/string.cpp index 16c7bcecb3..ae4d8ba9fe 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -886,7 +886,7 @@ char *strcasestr(const char *haystack, const char *needle) */ static std::string_view SkipGarbage(std::string_view str) { - while (str.size() != 0 && (str[0] < '0' || IsInsideMM(str[0], ';', '@' + 1) || IsInsideMM(str[0], '[', '`' + 1) || IsInsideMM(str[0], '{', '~' + 1))) str.remove_prefix(1); + while (!str.empty() && (str[0] < '0' || IsInsideMM(str[0], ';', '@' + 1) || IsInsideMM(str[0], '[', '`' + 1) || IsInsideMM(str[0], '{', '~' + 1))) str.remove_prefix(1); return str; } diff --git a/src/stringfilter_type.h b/src/stringfilter_type.h index ef2b4d7efc..b4df174f2e 100644 --- a/src/stringfilter_type.h +++ b/src/stringfilter_type.h @@ -57,7 +57,7 @@ public: * Check whether any filter words were entered. * @return true if no words were entered. */ - bool IsEmpty() const { return this->word_index.size() == 0; } + bool IsEmpty() const { return this->word_index.empty(); } void ResetState(); void AddLine(const char *str); diff --git a/src/strings.cpp b/src/strings.cpp index a5bb541c7b..ce61900715 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -2431,7 +2431,7 @@ void InitializeLanguagePacks() std::string path = FioGetDirectory(sp, LANG_DIR); GetLanguageList(path.c_str()); } - if (_languages.size() == 0) usererror("No available language packs (invalid versions?)"); + if (_languages.empty()) usererror("No available language packs (invalid versions?)"); /* Acquire the locale of the current system */ const char *lang = GetCurrentLocale("LC_MESSAGES"); diff --git a/src/tbtr_template_gui_create.cpp b/src/tbtr_template_gui_create.cpp index b751189078..518618bea9 100644 --- a/src/tbtr_template_gui_create.cpp +++ b/src/tbtr_template_gui_create.cpp @@ -166,7 +166,7 @@ public: UpdateButtonState(); } - void Close() override + void Close(int data = 0) override { if (virtual_train != nullptr) { DoCommandP(0, virtual_train->index, 0, CMD_DELETE_VIRTUAL_TRAIN); diff --git a/src/tbtr_template_gui_main.cpp b/src/tbtr_template_gui_main.cpp index 7be5be0004..d155ade021 100644 --- a/src/tbtr_template_gui_main.cpp +++ b/src/tbtr_template_gui_main.cpp @@ -255,7 +255,7 @@ public: this->BuildTemplateGuiList(); } - void Close() override { + void Close(int data = 0) override { CloseWindowById(WC_CREATE_TEMPLATE, this->window_number); this->Window::Close(); } diff --git a/src/textfile_gui.cpp b/src/textfile_gui.cpp index 13c8ce856d..5e37d516d5 100644 --- a/src/textfile_gui.cpp +++ b/src/textfile_gui.cpp @@ -123,7 +123,7 @@ uint TextfileWindow::ReflowContent() uint TextfileWindow::GetContentHeight() { - if (this->lines.size() == 0) return 0; + if (this->lines.empty()) return 0; return this->lines.back().bottom; } @@ -529,8 +529,7 @@ void TextfileWindow::AfterLoadMarkdown() DropDownList list; for (size_t line : this->jumplist) { SetDParamStr(0, this->lines[line].text); - DropDownListStringItem *item = new DropDownListStringItem(STR_TEXTFILE_JUMPLIST_ITEM, (int)line, false); - list.emplace_back(item); + list.push_back(std::make_unique(STR_TEXTFILE_JUMPLIST_ITEM, (int)line, false)); } ShowDropDownList(this, std::move(list), -1, widget); break; diff --git a/src/timer/timer_game_tick.cpp b/src/timer/timer_game_tick.cpp index 5d9512cc7b..cc3bbaa68e 100644 --- a/src/timer/timer_game_tick.cpp +++ b/src/timer/timer_game_tick.cpp @@ -10,11 +10,11 @@ * This file implements the timer logic for the tick-based game-timer. */ -#include "stdafx.h" +#include "../stdafx.h" #include "timer.h" #include "timer_game_tick.h" -#include "safeguards.h" +#include "../safeguards.h" template<> void IntervalTimer::Elapsed(TimerGameTick::TElapsed delta) diff --git a/src/timer/timer_game_tick.h b/src/timer/timer_game_tick.h index 56f407a0ba..ffb3a52e26 100644 --- a/src/timer/timer_game_tick.h +++ b/src/timer/timer_game_tick.h @@ -10,7 +10,7 @@ #ifndef TIMER_GAME_TICK_H #define TIMER_GAME_TICK_H -#include "gfx_type.h" +#include "../gfx_type.h" #include diff --git a/src/timer/timer_manager.h b/src/timer/timer_manager.h index 1cda384a98..f31e90824d 100644 --- a/src/timer/timer_manager.h +++ b/src/timer/timer_manager.h @@ -11,7 +11,7 @@ #ifndef TIMER_MANAGER_H #define TIMER_MANAGER_H -#include "stdafx.h" +#include "../stdafx.h" #include template diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index 1b4a8d903d..f5721d8d83 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -370,7 +370,7 @@ struct TimetableWindow : GeneralVehicleWindow { this->owner = this->vehicle->owner; } - void Close() override + void Close(int data = 0) override { if (!FocusWindowById(WC_VEHICLE_VIEW, this->window_number)) { MarkDirtyFocusedRoutePaths(this->vehicle); diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 45003a4709..0b99627b3a 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -218,7 +218,7 @@ static void PopupMainToolbMenu(Window *w, int widget, StringID string, int count { DropDownList list; for (int i = 0; i < count; i++) { - list.emplace_back(new DropDownListStringItem(string + i, i, i < 32 && HasBit(disabled, i))); + list.push_back(std::make_unique(string + i, i, i < 32 && HasBit(disabled, i))); } PopupMainToolbMenu(w, widget, std::move(list), 0); } @@ -243,24 +243,24 @@ static void PopupMainCompanyToolbMenu(Window *w, int widget, int grey = 0) if (!_networking) break; /* Add the client list button for the companies menu */ - list.emplace_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_CLIENT_LIST, CTMN_CLIENT_LIST, false)); + list.push_back(std::make_unique(STR_NETWORK_COMPANY_LIST_CLIENT_LIST, CTMN_CLIENT_LIST, false)); if (_local_company != COMPANY_SPECTATOR) { - list.emplace_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_SPECTATE, CTMN_SPECTATE, false)); + list.push_back(std::make_unique(STR_NETWORK_COMPANY_LIST_SPECTATE, CTMN_SPECTATE, false)); } break; case WID_TN_STORY: - list.emplace_back(new DropDownListStringItem(STR_STORY_BOOK_SPECTATOR, CTMN_SPECTATOR, false)); + list.push_back(std::make_unique(STR_STORY_BOOK_SPECTATOR, CTMN_SPECTATOR, false)); break; case WID_TN_GOAL: - list.emplace_back(new DropDownListStringItem(STR_GOALS_SPECTATOR, CTMN_SPECTATOR, false)); + list.push_back(std::make_unique(STR_GOALS_SPECTATOR, CTMN_SPECTATOR, false)); break; } for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { if (!Company::IsValidID(c)) continue; - list.emplace_back(new DropDownListCompanyItem(c, false, HasBit(grey, c))); + list.push_back(std::make_unique(c, false, HasBit(grey, c))); } PopupMainToolbMenu(w, widget, std::move(list), _local_company == COMPANY_SPECTATOR ? (widget == WID_TN_COMPANIES ? CTMN_CLIENT_LIST : CTMN_SPECTATOR) : (int)_local_company); @@ -339,32 +339,32 @@ enum OptionMenuEntries { static CallBackFunction ToolbarOptionsClick(Window *w) { DropDownList list; - list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_GAME_OPTIONS, OME_GAMEOPTIONS, false)); - list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE, OME_SETTINGS, false)); + list.push_back(std::make_unique(STR_SETTINGS_MENU_GAME_OPTIONS, OME_GAMEOPTIONS, false)); + list.push_back(std::make_unique(STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE, OME_SETTINGS, false)); /* Changes to the per-AI settings don't get send from the server to the clients. Clients get * the settings once they join but never update it. As such don't show the window at all * to network clients. */ if (!_networking || _network_server) { - list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_AI_SETTINGS, OME_AI_SETTINGS, false)); - list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS, OME_GAMESCRIPT_SETTINGS, false)); - } - list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_NEWGRF_SETTINGS, OME_NEWGRFSETTINGS, false)); - list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_ZONING, OME_ZONING, false)); - list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS, OME_TRANSPARENCIES, false)); - list.emplace_back(new DropDownListItem(-1, false)); - list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED, OME_SHOW_TOWNNAMES, false, HasBit(_display_opt, DO_SHOW_TOWN_NAMES))); - list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED, OME_SHOW_STATIONNAMES, false, HasBit(_display_opt, DO_SHOW_STATION_NAMES))); - list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED, OME_SHOW_WAYPOINTNAMES, false, HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES))); - list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_SIGNS_DISPLAYED, OME_SHOW_SIGNS, false, HasBit(_display_opt, DO_SHOW_SIGNS))); - list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS, OME_SHOW_COMPETITOR_SIGNS, false, HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS))); + list.push_back(std::make_unique(STR_SETTINGS_MENU_AI_SETTINGS, OME_AI_SETTINGS, false)); + list.push_back(std::make_unique(STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS, OME_GAMESCRIPT_SETTINGS, false)); + } + list.push_back(std::make_unique(STR_SETTINGS_MENU_NEWGRF_SETTINGS, OME_NEWGRFSETTINGS, false)); + list.push_back(std::make_unique(STR_SETTINGS_MENU_ZONING, OME_ZONING, false)); + list.push_back(std::make_unique(STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS, OME_TRANSPARENCIES, false)); + list.push_back(std::make_unique(-1, false)); + list.push_back(std::make_unique(STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED, OME_SHOW_TOWNNAMES, false, HasBit(_display_opt, DO_SHOW_TOWN_NAMES))); + list.push_back(std::make_unique(STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED, OME_SHOW_STATIONNAMES, false, HasBit(_display_opt, DO_SHOW_STATION_NAMES))); + list.push_back(std::make_unique(STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED, OME_SHOW_WAYPOINTNAMES, false, HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES))); + list.push_back(std::make_unique(STR_SETTINGS_MENU_SIGNS_DISPLAYED, OME_SHOW_SIGNS, false, HasBit(_display_opt, DO_SHOW_SIGNS))); + list.push_back(std::make_unique(STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS, OME_SHOW_COMPETITOR_SIGNS, false, HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS))); if (_settings_client.gui.allow_hiding_waypoint_labels) { - list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_SHOW_HIDDEN_SIGNS, OME_SHOW_HIDDEN_SIGNS, false, HasBit(_extra_display_opt, XDO_SHOW_HIDDEN_SIGNS))); + list.push_back(std::make_unique(STR_SETTINGS_MENU_SHOW_HIDDEN_SIGNS, OME_SHOW_HIDDEN_SIGNS, false, HasBit(_extra_display_opt, XDO_SHOW_HIDDEN_SIGNS))); } - list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_FULL_ANIMATION, OME_FULL_ANIMATION, false, HasBit(_display_opt, DO_FULL_ANIMATION))); - list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_FULL_DETAIL, OME_FULL_DETAILS, false, HasBit(_display_opt, DO_FULL_DETAIL))); - list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS, OME_TRANSPARENTBUILDINGS, false, IsTransparencySet(TO_HOUSES))); - list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_SIGNS, OME_SHOW_STATIONSIGNS, false, IsTransparencySet(TO_SIGNS))); - list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_MONEY_TEXT_EFFECTS, OME_SHOW_MONEYTEXT, false, HasBit(_extra_display_opt, XDO_SHOW_MONEY_TEXT_EFFECTS))); + list.push_back(std::make_unique(STR_SETTINGS_MENU_FULL_ANIMATION, OME_FULL_ANIMATION, false, HasBit(_display_opt, DO_FULL_ANIMATION))); + list.push_back(std::make_unique(STR_SETTINGS_MENU_FULL_DETAIL, OME_FULL_DETAILS, false, HasBit(_display_opt, DO_FULL_DETAIL))); + list.push_back(std::make_unique(STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS, OME_TRANSPARENTBUILDINGS, false, IsTransparencySet(TO_HOUSES))); + list.push_back(std::make_unique(STR_SETTINGS_MENU_TRANSPARENT_SIGNS, OME_SHOW_STATIONSIGNS, false, IsTransparencySet(TO_SIGNS))); + list.push_back(std::make_unique(STR_SETTINGS_MENU_MONEY_TEXT_EFFECTS, OME_SHOW_MONEYTEXT, false, HasBit(_extra_display_opt, XDO_SHOW_MONEY_TEXT_EFFECTS))); ShowDropDownList(w, std::move(list), 0, WID_TN_SETTINGS, 140, true); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); @@ -498,11 +498,11 @@ enum MapMenuEntries { static CallBackFunction ToolbarMapClick(Window *w) { DropDownList list; - list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_MAP_OF_WORLD, MME_SHOW_SMALLMAP, false)); - list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_EXTRA_VIEWPORT, MME_SHOW_EXTRAVIEWPORTS, false)); - list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_LINGRAPH_LEGEND, MME_SHOW_LINKGRAPH, false)); - list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_SIGN_LIST, MME_SHOW_SIGNLISTS, false)); - list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_PLAN_LIST, MME_SHOW_PLANS, false)); + list.push_back(std::make_unique(STR_MAP_MENU_MAP_OF_WORLD, MME_SHOW_SMALLMAP, false)); + list.push_back(std::make_unique(STR_MAP_MENU_EXTRA_VIEWPORT, MME_SHOW_EXTRAVIEWPORTS, false)); + list.push_back(std::make_unique(STR_MAP_MENU_LINGRAPH_LEGEND, MME_SHOW_LINKGRAPH, false)); + list.push_back(std::make_unique(STR_MAP_MENU_SIGN_LIST, MME_SHOW_SIGNLISTS, false)); + list.push_back(std::make_unique(STR_MAP_MENU_PLAN_LIST, MME_SHOW_PLANS, false)); PopupMainToolbMenu(w, WID_TN_SMALL_MAP, std::move(list), 0); return CBF_NONE; } @@ -510,11 +510,11 @@ static CallBackFunction ToolbarMapClick(Window *w) static CallBackFunction ToolbarScenMapTownDir(Window *w) { DropDownList list; - list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_MAP_OF_WORLD, MME_SHOW_SMALLMAP, false)); - list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_EXTRA_VIEWPORT, MME_SHOW_EXTRAVIEWPORTS, false)); - list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_SIGN_LIST, MME_SHOW_SIGNLISTS, false)); - list.emplace_back(new DropDownListStringItem(STR_TOWN_MENU_TOWN_DIRECTORY, MME_SHOW_TOWNDIRECTORY, false)); - list.emplace_back(new DropDownListStringItem(STR_INDUSTRY_MENU_INDUSTRY_DIRECTORY, MME_SHOW_INDUSTRYDIRECTORY, false)); + list.push_back(std::make_unique(STR_MAP_MENU_MAP_OF_WORLD, MME_SHOW_SMALLMAP, false)); + list.push_back(std::make_unique(STR_MAP_MENU_EXTRA_VIEWPORT, MME_SHOW_EXTRAVIEWPORTS, false)); + list.push_back(std::make_unique(STR_MAP_MENU_SIGN_LIST, MME_SHOW_SIGNLISTS, false)); + list.push_back(std::make_unique(STR_TOWN_MENU_TOWN_DIRECTORY, MME_SHOW_TOWNDIRECTORY, false)); + list.push_back(std::make_unique(STR_INDUSTRY_MENU_INDUSTRY_DIRECTORY, MME_SHOW_INDUSTRYDIRECTORY, false)); PopupMainToolbMenu(w, WID_TE_SMALL_MAP, std::move(list), 0); return CBF_NONE; } @@ -718,13 +718,13 @@ static const int LTMN_HIGHSCORE = -9; ///< Show highscrore table static void AddDropDownLeagueTableOptions(DropDownList &list) { if (LeagueTable::GetNumItems() > 0) { for (LeagueTable *lt : LeagueTable::Iterate()) { - list.emplace_back(new DropDownListStringItem(lt->title, lt->index, false)); + list.push_back(std::make_unique(lt->title, lt->index, false)); } } else { - list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_COMPANY_LEAGUE_TABLE, LTMN_PERFORMANCE_LEAGUE, false)); - list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_DETAILED_PERFORMANCE_RATING, LTMN_PERFORMANCE_RATING, false)); + list.push_back(std::make_unique(STR_GRAPH_MENU_COMPANY_LEAGUE_TABLE, LTMN_PERFORMANCE_LEAGUE, false)); + list.push_back(std::make_unique(STR_GRAPH_MENU_DETAILED_PERFORMANCE_RATING, LTMN_PERFORMANCE_RATING, false)); if (!_networking) { - list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_HIGHSCORE, LTMN_HIGHSCORE, false)); + list.push_back(std::make_unique(STR_GRAPH_MENU_HIGHSCORE, LTMN_HIGHSCORE, false)); } } } @@ -733,12 +733,12 @@ static CallBackFunction ToolbarGraphsClick(Window *w) { DropDownList list; - list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_OPERATING_PROFIT_GRAPH, GRMN_OPERATING_PROFIT_GRAPH, false)); - list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_INCOME_GRAPH, GRMN_INCOME_GRAPH, false)); - list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_DELIVERED_CARGO_GRAPH, GRMN_DELIVERED_CARGO_GRAPH, false)); - list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_PERFORMANCE_HISTORY_GRAPH, GRMN_PERFORMANCE_HISTORY_GRAPH, false)); - list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_COMPANY_VALUE_GRAPH, GRMN_COMPANY_VALUE_GRAPH, false)); - list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_CARGO_PAYMENT_RATES, GRMN_CARGO_PAYMENT_RATES, false)); + list.push_back(std::make_unique(STR_GRAPH_MENU_OPERATING_PROFIT_GRAPH, GRMN_OPERATING_PROFIT_GRAPH, false)); + list.push_back(std::make_unique(STR_GRAPH_MENU_INCOME_GRAPH, GRMN_INCOME_GRAPH, false)); + list.push_back(std::make_unique(STR_GRAPH_MENU_DELIVERED_CARGO_GRAPH, GRMN_DELIVERED_CARGO_GRAPH, false)); + list.push_back(std::make_unique(STR_GRAPH_MENU_PERFORMANCE_HISTORY_GRAPH, GRMN_PERFORMANCE_HISTORY_GRAPH, false)); + list.push_back(std::make_unique(STR_GRAPH_MENU_COMPANY_VALUE_GRAPH, GRMN_COMPANY_VALUE_GRAPH, false)); + list.push_back(std::make_unique(STR_GRAPH_MENU_CARGO_PAYMENT_RATES, GRMN_CARGO_PAYMENT_RATES, false)); if (_toolbar_mode != TB_NORMAL) AddDropDownLeagueTableOptions(list); @@ -999,7 +999,7 @@ static CallBackFunction MenuClickBuildTram(int index) static CallBackFunction ToolbarBuildWaterClick(Window *w) { DropDownList list; - list.emplace_back(new DropDownListIconItem(SPR_IMG_BUILD_CANAL, PAL_NONE, STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION, 0, false)); + list.push_back(std::make_unique(SPR_IMG_BUILD_CANAL, PAL_NONE, STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION, 0, false)); ShowDropDownList(w, std::move(list), 0, WID_TN_WATER, 140, true); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); return CBF_NONE; @@ -1021,7 +1021,7 @@ static CallBackFunction MenuClickBuildWater(int) static CallBackFunction ToolbarBuildAirClick(Window *w) { DropDownList list; - list.emplace_back(new DropDownListIconItem(SPR_IMG_AIRPORT, PAL_NONE, STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION, 0, false)); + list.push_back(std::make_unique(SPR_IMG_AIRPORT, PAL_NONE, STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION, 0, false)); ShowDropDownList(w, std::move(list), 0, WID_TN_AIR, 140, true); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); return CBF_NONE; @@ -1043,9 +1043,9 @@ static CallBackFunction MenuClickBuildAir(int) static CallBackFunction ToolbarForestClick(Window *w) { DropDownList list; - list.emplace_back(new DropDownListIconItem(SPR_IMG_LANDSCAPING, PAL_NONE, STR_LANDSCAPING_MENU_LANDSCAPING, 0, false)); - list.emplace_back(new DropDownListIconItem(SPR_IMG_PLANTTREES, PAL_NONE, STR_LANDSCAPING_MENU_PLANT_TREES, 1, false)); - list.emplace_back(new DropDownListIconItem(SPR_IMG_SIGN, PAL_NONE, STR_LANDSCAPING_MENU_PLACE_SIGN, 2, false)); + list.push_back(std::make_unique(SPR_IMG_LANDSCAPING, PAL_NONE, STR_LANDSCAPING_MENU_LANDSCAPING, 0, false)); + list.push_back(std::make_unique(SPR_IMG_PLANTTREES, PAL_NONE, STR_LANDSCAPING_MENU_PLANT_TREES, 1, false)); + list.push_back(std::make_unique(SPR_IMG_SIGN, PAL_NONE, STR_LANDSCAPING_MENU_PLACE_SIGN, 2, false)); ShowDropDownList(w, std::move(list), 0, WID_TN_LANDSCAPE, 100, true); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); return CBF_NONE; diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 2944623742..4ec3104b57 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -1560,6 +1560,15 @@ static bool TownCanGrowRoad(TileIndex tile) return HasBit(GetRoadTypeInfo(rt)->flags, ROTF_TOWN_BUILD) || GetTownRoadType() == rt; } +/** + * Check if the town is allowed to build roads. + * @return true If the town is allowed to build roads. + */ +static inline bool TownAllowedToBuildRoads(const Town *t) +{ + return t->GetAllowBuildRoads() || _generating_world || _game_mode == GM_EDITOR; +} + /** * Grows the given town. * There are at the moment 3 possible way's for @@ -1589,7 +1598,7 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t * to say that this is the last iteration. */ _grow_town_result = GROWTH_SEARCH_STOPPED; - if (!t1->GetAllowBuildRoads() && !_generating_world) return; + if (!TownAllowedToBuildRoads(t1)) return; if (!t1->GetAllowBuildLevelCrossings() && IsTileType(tile, MP_RAILWAY)) return; if (!MayTownModifyRoad(tile)) return; @@ -1674,7 +1683,7 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t * the fitting RoadBits */ _grow_town_result = GROWTH_SEARCH_STOPPED; - if (!t1->GetAllowBuildRoads() && !_generating_world) return; + if (!TownAllowedToBuildRoads(t1)) return; switch (t1->layout) { default: NOT_REACHED(); @@ -1767,7 +1776,7 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t if (!IsValidTile(house_tile)) return; - if (target_dir != DIAGDIR_END && (t1->GetAllowBuildRoads() || _generating_world)) { + if (target_dir != DIAGDIR_END && TownAllowedToBuildRoads(t1)) { switch (t1->layout) { default: NOT_REACHED(); @@ -1846,7 +1855,7 @@ static bool CanFollowRoad(const Town *t, TileIndex tile, DiagDirection dir) if (HasTileWaterGround(target_tile)) return false; RoadBits target_rb = GetTownRoadBits(target_tile); - if (t->GetAllowBuildRoads() || _generating_world) { + if (TownAllowedToBuildRoads(t)) { /* Check whether a road connection exists or can be build. */ switch (GetTileType(target_tile)) { case MP_ROAD: @@ -2025,7 +2034,7 @@ static bool GrowTown(Town *t) /* No road available, try to build a random road block by * clearing some land and then building a road there. */ - if (t->GetAllowBuildRoads() || _generating_world) { + if (TownAllowedToBuildRoads(t)) { tile = t->xy; for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) { /* Only work with plain land that not already has a house */ @@ -2840,7 +2849,7 @@ static inline CommandCost IsAnotherHouseTypeAllowedInTown(Town *t, HouseID house static inline bool TownLayoutAllowsHouseHere(Town *t, const TileArea &ta) { /* Allow towns everywhere when we don't build roads */ - if (!t->GetAllowBuildRoads() && !_generating_world) return true; + if (!TownAllowedToBuildRoads(t)) return true; TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, ta.tile); @@ -3729,7 +3738,7 @@ static CommandCost TownActionBribe(Town *t, DoCommandFlag flags) /* set all close by station ratings to 0 */ for (Station *st : Station::Iterate()) { if (st->town == t && st->owner == _current_company) { - for (CargoID i = 0; i < NUM_CARGO; i++) st->goods[i].rating = 0; + for (GoodsEntry &ge : st->goods) ge.rating = 0; } } @@ -4139,8 +4148,8 @@ static void UpdateTownGrowth(Town *t) static void UpdateTownAmounts(Town *t) { - for (CargoID i = 0; i < NUM_CARGO; i++) t->supplied[i].NewMonth(); - for (int i = TE_BEGIN; i < TE_END; i++) t->received[i].NewMonth(); + for (auto &supplied : t->supplied) supplied.NewMonth(); + for (auto &received : t->received) received.NewMonth(); if (t->fund_buildings_months != 0) t->fund_buildings_months--; SetWindowDirty(WC_TOWN_VIEW, t->index); diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 0ad4ccd0c0..1cfac0f1a7 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -534,7 +534,7 @@ public: nvp->InitializeViewport(this, this->town->xy, ScaleZoomGUI(ZOOM_LVL_TOWN)); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { SetViewportCatchmentTown(Town::Get(this->window_number), false); this->Window::Close(); @@ -673,14 +673,6 @@ public: break; case WID_TV_EXPAND: { // expand town - only available on Scenario editor - /* Warn the user if towns are not allowed to build roads, but do this only once per OpenTTD run. */ - static bool _warn_town_no_roads = false; - - if (!Town::Get(this->window_number)->GetAllowBuildRoads() && !_warn_town_no_roads) { - ShowErrorMessage(STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS, INVALID_STRING_ID, WL_WARNING); - _warn_town_no_roads = true; - } - DoCommandP(0, this->window_number, 0, CMD_EXPAND_TOWN | CMD_MSG(STR_ERROR_CAN_T_EXPAND_TOWN)); break; } @@ -1013,7 +1005,7 @@ public: case WID_TD_LIST: { int n = 0; Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); - if (this->towns.size() == 0) { // No towns available. + if (this->towns.empty()) { // No towns available. DrawString(tr, STR_TOWN_DIRECTORY_NONE); break; } diff --git a/src/tracerestrict_gui.cpp b/src/tracerestrict_gui.cpp index d9f4bce3a3..4cad3ed866 100644 --- a/src/tracerestrict_gui.cpp +++ b/src/tracerestrict_gui.cpp @@ -1797,7 +1797,7 @@ public: this->ReloadProgramme(); } - void Close() override + void Close(int data = 0) override { extern const TraceRestrictProgram *_viewport_highlight_tracerestrict_program; if (_viewport_highlight_tracerestrict_program != nullptr) { @@ -3865,7 +3865,7 @@ public: this->owner = vli.company; } - void Close() override + void Close(int data = 0) override { *this->sorting = this->vehgroups.GetListing(); this->Window::Close(); diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 416abef8ed..6a72f993a2 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -1698,7 +1698,7 @@ static void MakeTrainBackup(TrainList &list, Train *t) static void RestoreTrainBackup(TrainList &list) { /* No train, nothing to do. */ - if (list.size() == 0) return; + if (list.empty()) return; Train *prev = nullptr; /* Iterate over the list and rebuild it. */ diff --git a/src/train_gui.cpp b/src/train_gui.cpp index 4647dcbae3..f73fe6d35d 100644 --- a/src/train_gui.cpp +++ b/src/train_gui.cpp @@ -549,14 +549,15 @@ void DrawTrainDetails(const Train *v, const Rect &r, int vscroll_pos, uint16 vsc /* Indent the total cargo capacity details */ Rect ir = r.Indent(WidgetDimensions::scaled.hsep_indent, rtl); - for (CargoID i = 0; i < NUM_CARGO; i++) { - if (max_cargo[i] > 0 && --vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) { - SetDParam(0, i); // {CARGO} #1 - SetDParam(1, act_cargo[i]); // {CARGO} #2 - SetDParam(2, i); // {SHORTCARGO} #1 - SetDParam(3, max_cargo[i]); // {SHORTCARGO} #2 + for (const CargoSpec *cs : _sorted_cargo_specs) { + CargoID cid = cs->Index(); + if (max_cargo[cid] > 0 && --vscroll_pos < 0 && vscroll_pos >= -vscroll_cap) { + SetDParam(0, cid); // {CARGO} #1 + SetDParam(1, act_cargo[cid]); // {CARGO} #2 + SetDParam(2, cid); // {SHORTCARGO} #1 + SetDParam(3, max_cargo[cid]); // {SHORTCARGO} #2 SetDParam(4, _settings_game.vehicle.freight_trains); - DrawString(ir.left, ir.right, y + text_y_offset, FreightWagonMult(i) > 1 ? STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT : STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY); + DrawString(ir.left, ir.right, y + text_y_offset, FreightWagonMult(cid) > 1 ? STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT : STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY); y += line_height; } } diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index ca13dbbb78..e95ba8e0a1 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -341,8 +341,8 @@ void BaseVehicleListWindow::SetCargoFilterArray() void BaseVehicleListWindow::FilterVehicleList() { this->vehgroups.Filter(this->cargo_filter[this->cargo_filter_criteria]); - if (0 == this->vehicles.size()) { - // no vehicle passed through the filter, invalidate the previously selected vehicle + if (this->vehicles.empty()) { + /* No vehicle passed through the filter, invalidate the previously selected vehicle */ this->vehicle_sel = INVALID_VEHICLE; } else if (this->vehicle_sel != INVALID_VEHICLE && std::find(this->vehicles.begin(), this->vehicles.end(), Vehicle::Get(this->vehicle_sel)) == this->vehicles.end()) { // previously selected engine didn't pass the filter, remove selection this->vehicle_sel = INVALID_VEHICLE; @@ -418,28 +418,28 @@ DropDownList BaseVehicleListWindow::BuildActionDropdownList(bool show_autoreplac bool disable = this->own_vehicles == 0; bool mass_action_disable = disable || (_settings_client.gui.disable_top_veh_list_mass_actions && consider_top_level); - if (show_autoreplace) list.emplace_back(new DropDownListStringItem(STR_VEHICLE_LIST_REPLACE_VEHICLES, ADI_REPLACE, disable)); + if (show_autoreplace) list.push_back(std::make_unique(STR_VEHICLE_LIST_REPLACE_VEHICLES, ADI_REPLACE, disable)); if (show_autoreplace && show_template_replace) { - list.emplace_back(new DropDownListStringItem(STR_TMPL_TEMPLATE_REPLACEMENT, ADI_TEMPLATE_REPLACE, disable)); + list.push_back(std::make_unique(STR_TMPL_TEMPLATE_REPLACEMENT, ADI_TEMPLATE_REPLACE, disable)); } - list.emplace_back(new DropDownListStringItem(STR_VEHICLE_LIST_SEND_FOR_SERVICING, ADI_SERVICE, mass_action_disable)); - list.emplace_back(new DropDownListStringItem(this->vehicle_depot_name[this->vli.vtype], ADI_DEPOT, mass_action_disable)); - if (_settings_client.gui.show_depot_sell_gui) list.emplace_back(new DropDownListStringItem(this->vehicle_depot_sell_name[this->vli.vtype], ADI_DEPOT_SELL, mass_action_disable)); - list.emplace_back(new DropDownListStringItem(STR_VEHICLE_LIST_CANCEL_DEPOT_SERVICE, ADI_CANCEL_DEPOT, mass_action_disable)); + list.push_back(std::make_unique(STR_VEHICLE_LIST_SEND_FOR_SERVICING, ADI_SERVICE, mass_action_disable)); + list.push_back(std::make_unique(this->vehicle_depot_name[this->vli.vtype], ADI_DEPOT, mass_action_disable)); + if (_settings_client.gui.show_depot_sell_gui) list.push_back(std::make_unique(this->vehicle_depot_sell_name[this->vli.vtype], ADI_DEPOT_SELL, mass_action_disable)); + list.push_back(std::make_unique(STR_VEHICLE_LIST_CANCEL_DEPOT_SERVICE, ADI_CANCEL_DEPOT, mass_action_disable)); if (show_group) { - list.emplace_back(new DropDownListStringItem(STR_GROUP_ADD_SHARED_VEHICLE, ADI_ADD_SHARED, disable)); - list.emplace_back(new DropDownListStringItem(STR_GROUP_REMOVE_ALL_VEHICLES, ADI_REMOVE_ALL, disable)); + list.push_back(std::make_unique(STR_GROUP_ADD_SHARED_VEHICLE, ADI_ADD_SHARED, disable)); + list.push_back(std::make_unique(STR_GROUP_REMOVE_ALL_VEHICLES, ADI_REMOVE_ALL, disable)); } if (_settings_client.gui.show_adv_tracerestrict_features) { - list.emplace_back(new DropDownListStringItem(STR_TRACE_RESTRICT_SLOT_MANAGE, ADI_TRACERESTRICT_SLOT_MGMT, false)); - list.emplace_back(new DropDownListStringItem(STR_TRACE_RESTRICT_COUNTER_MANAGE, ADI_TRACERESTRICT_COUNTER_MGMT, false)); + list.push_back(std::make_unique(STR_TRACE_RESTRICT_SLOT_MANAGE, ADI_TRACERESTRICT_SLOT_MGMT, false)); + list.push_back(std::make_unique(STR_TRACE_RESTRICT_COUNTER_MANAGE, ADI_TRACERESTRICT_COUNTER_MGMT, false)); } if (change_order_str != 0) { - list.emplace_back(new DropDownListStringItem(change_order_str, ADI_CHANGE_ORDER, disable)); + list.push_back(std::make_unique(change_order_str, ADI_CHANGE_ORDER, disable)); } if (show_create_group) { - list.emplace_back(new DropDownListStringItem(STR_VEHICLE_LIST_CREATE_GROUP, ADI_CREATE_GROUP, disable)); + list.push_back(std::make_unique(STR_VEHICLE_LIST_CREATE_GROUP, ADI_CREATE_GROUP, disable)); } return list; @@ -511,7 +511,7 @@ byte GetBestFittingSubType(const Vehicle *v_from, Vehicle *v_for, CargoID dest_c byte ret_refit_cyc = 0; bool success = false; - if (subtypes.size() > 0) { + if (!subtypes.empty()) { /* Check whether any articulated part is refittable to 'dest_cargo_type' with a subtype listed in 'subtypes' */ for (Vehicle *v = v_for; v != nullptr; v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : nullptr) { const Engine *e = v->GetEngine(); @@ -610,18 +610,18 @@ struct RefitOption { } }; -typedef std::vector SubtypeList; ///< List of refit subtypes associated to a cargo. +using RefitOptions = std::map, CargoIDComparator>; ///< Available refit options (subtype and string) associated with each cargo type. /** * Draw the list of available refit options for a consist and highlight the selected refit option (if any). - * @param list List of subtype options for each (sorted) cargo. - * @param sel Selected refit cargo-type in the window + * @param refits Available refit options for each (sorted) cargo. + * @param sel Selected refit option in the window * @param pos Position of the selected item in caller widow * @param rows Number of rows(capacity) in caller window * @param delta Step height in caller window * @param r Rectangle of the matrix widget. */ -static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int sel[2], uint pos, uint rows, uint delta, const Rect &r) +static void DrawVehicleRefitWindow(const RefitOptions &refits, const RefitOption *sel, uint pos, uint rows, uint delta, const Rect &r) { Rect ir = r.Shrink(WidgetDimensions::scaled.matrix); uint current = 0; @@ -638,12 +638,13 @@ static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int Rect tr = ir.Indent(iconwidth + WidgetDimensions::scaled.hsep_wide, rtl); /* Draw the list of subtypes for each cargo, and find the selected refit option (by its position). */ - for (uint i = 0; current < pos + rows && i < NUM_CARGO; i++) { - for (uint j = 0; current < pos + rows && j < list[i].size(); j++) { - const RefitOption &refit = list[i][j]; + for (const auto &pair : refits) { + bool has_subtypes = pair.second.size() > 1; + for (const RefitOption &refit : pair.second) { + if (current >= pos + rows) break; - /* Hide subtypes if sel[0] does not match */ - if (sel[0] != (int)i && refit.subtype != 0xFF) continue; + /* Hide subtypes if selected cargo type does not match */ + if ((sel == nullptr || sel->cargo != refit.cargo) && refit.subtype != UINT8_MAX) continue; /* Refit options with a position smaller than pos don't have to be drawn. */ if (current < pos) { @@ -651,19 +652,19 @@ static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int continue; } - if (list[i].size() > 1) { - if (refit.subtype != 0xFF) { + if (has_subtypes) { + if (refit.subtype != UINT8_MAX) { /* Draw tree lines */ int ycenter = tr.top + FONT_HEIGHT_NORMAL / 2; - GfxDrawLine(iconcenter, tr.top - WidgetDimensions::scaled.matrix.top, iconcenter, j == list[i].size() - 1 ? ycenter : tr.top - WidgetDimensions::scaled.matrix.top + delta - 1, linecolour); + GfxDrawLine(iconcenter, tr.top - WidgetDimensions::scaled.matrix.top, iconcenter, (&refit == &pair.second.back()) ? ycenter : tr.top - WidgetDimensions::scaled.matrix.top + delta - 1, linecolour); GfxDrawLine(iconcenter, ycenter, iconinner, ycenter, linecolour); } else { /* Draw expand/collapse icon */ - DrawSprite(sel[0] == (int)i ? SPR_CIRCLE_UNFOLDED : SPR_CIRCLE_FOLDED, PAL_NONE, iconleft, tr.top + (FONT_HEIGHT_NORMAL - iconheight) / 2); + DrawSprite((sel != nullptr && sel->cargo == refit.cargo) ? SPR_CIRCLE_UNFOLDED : SPR_CIRCLE_FOLDED, PAL_NONE, iconleft, tr.top + (FONT_HEIGHT_NORMAL - iconheight) / 2); } } - TextColour colour = (sel[0] == (int)i && (uint)sel[1] == j) ? TC_WHITE : TC_BLACK; + TextColour colour = (sel != nullptr && sel->cargo == refit.cargo && sel->subtype == refit.subtype) ? TC_WHITE : TC_BLACK; /* Get the cargo name. */ SetDParam(0, CargoSpec::Get(refit.cargo)->name); SetDParam(1, refit.string); @@ -677,9 +678,8 @@ static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int /** Refit cargo window. */ struct RefitWindow : public Window { - int sel[2]; ///< Index in refit options, sel[0] == -1 if nothing is selected. - RefitOption *cargo; ///< Refit option selected by #sel. - SubtypeList list[NUM_CARGO]; ///< List of refit subtypes available for each sorted cargo. + const RefitOption *selected_refit; ///< Selected refit option. + RefitOptions refit_list; ///< List of refit subtypes available for each sorted cargo. VehicleOrderID order; ///< If not #INVALID_VEH_ORDER_ID, selection is part of a refit order (rather than execute directly). uint information_width; ///< Width required for correctly displaying all cargoes in the information panel. Scrollbar *vscroll; ///< The main scrollbar. @@ -700,7 +700,12 @@ struct RefitWindow : public Window { */ void BuildRefitList() { - for (uint i = 0; i < NUM_CARGO; i++) this->list[i].clear(); + /* Store the currently selected RefitOption. */ + std::optional current_refit_option; + if (this->selected_refit != nullptr) current_refit_option = *(this->selected_refit); + this->selected_refit = nullptr; + + this->refit_list.clear(); Vehicle *v = Vehicle::Get(this->window_number); /* Check only the selected vehicles. */ @@ -720,19 +725,16 @@ struct RefitWindow : public Window { if (this->auto_refit && !HasBit(e->info.misc_flags, EF_AUTO_REFIT)) continue; /* Loop through all cargoes in the refit mask */ - int current_index = 0; for (const auto &cs : _sorted_cargo_specs) { CargoID cid = cs->Index(); /* Skip cargo type if it's not listed */ - if (!HasBit(cmask, cid)) { - current_index++; - continue; - } + if (!HasBit(cmask, cid)) continue; - bool first_vehicle = this->list[current_index].size() == 0; + auto &list = this->refit_list[cid]; + bool first_vehicle = list.empty(); if (first_vehicle) { /* Keeping the current subtype is always an option. It also serves as the option in case of no subtypes */ - this->list[current_index].push_back({cid, 0xFF, STR_EMPTY}); + list.push_back({cid, UINT8_MAX, STR_EMPTY}); } /* Check the vehicle's callback mask for cargo suffixes. @@ -764,16 +766,15 @@ struct RefitWindow : public Window { option.cargo = cid; option.subtype = refit_cyc; option.string = subtype; - include(this->list[current_index], option); + include(list, option); } else { /* Intersect the subtypes of earlier vehicles with the subtypes of this vehicle */ if (subtype == STR_EMPTY) { /* No more subtypes for this vehicle, delete all subtypes >= refit_cyc */ - SubtypeList &l = this->list[current_index]; - /* 0xFF item is in front, other subtypes are sorted. So just truncate the list in the right spot */ - for (uint i = 1; i < l.size(); i++) { - if (l[i].subtype >= refit_cyc) { - l.resize(i); + /* UINT8_MAX item is in front, other subtypes are sorted. So just truncate the list in the right spot */ + for (uint i = 1; i < list.size(); i++) { + if (list[i].subtype >= refit_cyc) { + list.resize(i); break; } } @@ -781,11 +782,10 @@ struct RefitWindow : public Window { } else { /* Check whether the subtype matches with the subtype of earlier vehicles. */ uint pos = 1; - SubtypeList &l = this->list[current_index]; - while (pos < l.size() && l[pos].subtype != refit_cyc) pos++; - if (pos < l.size() && l[pos].string != subtype) { + while (pos < list.size() && list[pos].subtype != refit_cyc) pos++; + if (pos < list.size() && list[pos].string != subtype) { /* String mismatch, remove item keeping the order */ - l.erase(l.begin() + pos); + list.erase(list.begin() + pos); } } } @@ -799,9 +799,23 @@ struct RefitWindow : public Window { v->First()->InvalidateNewGRFCache(); v->InvalidateNewGRFCache(); } - current_index++; } } while (v->IsArticulatedCallbackVehicleType() && (v = v->Next()) != nullptr); + + /* Restore the previously selected RefitOption. */ + if (current_refit_option.has_value()) { + for (const auto &pair : this->refit_list) { + for (const auto &refit : pair.second) { + if (refit.cargo == current_refit_option->cargo && refit.subtype == current_refit_option->subtype) { + this->selected_refit = &refit; + break; + } + } + if (this->selected_refit != nullptr) break; + } + } + + this->SetWidgetDisabledState(WID_VR_REFIT, this->selected_refit == nullptr); } /** @@ -809,25 +823,22 @@ struct RefitWindow : public Window { */ void RefreshScrollbar() { - uint scroll_row = 0; - uint row = 0; - uint old_row = this->vscroll->GetCount(); - - for (uint i = 0; i < NUM_CARGO; i++) { - for (uint j = 0; j < this->list[i].size(); j++) { - const RefitOption &refit = this->list[i][j]; - - /* Hide subtypes if sel[0] does not match */ - if (this->sel[0] != (int)i && refit.subtype != 0xFF) continue; - - if (this->sel[0] == (int)i && (uint)this->sel[1] == j) scroll_row = row; - - row++; + size_t scroll_row = 0; + size_t rows = 0; + CargoID cargo = this->selected_refit == nullptr ? (CargoID)CT_INVALID : this->selected_refit->cargo; + + for (const auto &pair : this->refit_list) { + if (pair.first == cargo) { + /* selected_refit points to an element in the vector so no need to search for it. */ + scroll_row = rows + (this->selected_refit - pair.second.data()); + rows += pair.second.size(); + } else { + rows++; /* Unselected cargo type is collapsed into one row. */ } } - this->vscroll->SetCount(row); - if (scroll_row < row && row != old_row) this->vscroll->ScrollTowards(scroll_row); + this->vscroll->SetCount(rows); + this->vscroll->ScrollTowards(static_cast(scroll_row)); } /** @@ -838,45 +849,24 @@ struct RefitWindow : public Window { { uint row = 0; - for (uint i = 0; i < NUM_CARGO; i++) { - for (uint j = 0; j < this->list[i].size(); j++) { - const RefitOption &refit = this->list[i][j]; - - /* Hide subtypes if sel[0] does not match */ - if (this->sel[0] != (int)i && refit.subtype != 0xFF) continue; - + for (const auto &pair : refit_list) { + for (const RefitOption &refit : pair.second) { if (row == click_row) { - this->sel[0] = i; - this->sel[1] = j; + this->selected_refit = &refit; return; } - row++; + /* If this cargo type is not already selected then its subtypes are not visible, so skip the rest. */ + if (this->selected_refit == nullptr || this->selected_refit->cargo != refit.cargo) break; } } - this->sel[0] = -1; - this->sel[1] = 0; - } - - /** - * Gets the #RefitOption placed in the selected index. - * @return Pointer to the #RefitOption currently in use. - */ - RefitOption *GetRefitOption() - { - if (this->sel[0] < 0) return nullptr; - - SubtypeList &l = this->list[this->sel[0]]; - if ((uint)this->sel[1] >= l.size()) return nullptr; - - return &l[this->sel[1]]; + /* No selection made */ + this->selected_refit = nullptr; } RefitWindow(WindowDesc *desc, const Vehicle *v, VehicleOrderID order, bool auto_refit, bool is_virtual) : Window(desc) { - this->sel[0] = -1; - this->sel[1] = 0; this->auto_refit = auto_refit; this->is_virtual_train = is_virtual; this->order = order; @@ -903,10 +893,10 @@ struct RefitWindow : public Window { this->FinishInitNested(v->index); this->owner = v->owner; - this->SetWidgetDisabledState(WID_VR_REFIT, this->sel[0] < 0); + this->SetWidgetDisabledState(WID_VR_REFIT, this->selected_refit == nullptr); } - void Close() override + void Close(int data = 0) override { if (this->window_number != INVALID_VEHICLE) { if (!FocusWindowById(WC_VEHICLE_VIEW, this->window_number)) { @@ -941,32 +931,8 @@ struct RefitWindow : public Window { void OnInit() override { - if (this->cargo != nullptr) { - /* Store the RefitOption currently in use. */ - RefitOption current_refit_option = *(this->cargo); - - /* Rebuild the refit list */ - this->BuildRefitList(); - this->sel[0] = -1; - this->sel[1] = 0; - this->cargo = nullptr; - for (uint i = 0; this->cargo == nullptr && i < NUM_CARGO; i++) { - for (uint j = 0; j < list[i].size(); j++) { - if (list[i][j] == current_refit_option) { - this->sel[0] = i; - this->sel[1] = j; - this->cargo = &list[i][j]; - break; - } - } - } - - this->SetWidgetDisabledState(WID_VR_REFIT, this->sel[0] < 0); - this->RefreshScrollbar(); - } else { - /* Rebuild the refit list */ - this->OnInvalidateData(VIWD_CONSIST_CHANGED); - } + /* (Re)build the refit list */ + this->OnInvalidateData(VIWD_CONSIST_CHANGED); } void OnPaint() override @@ -1055,16 +1021,16 @@ struct RefitWindow : public Window { * @return INVALID_STRING_ID if there is no capacity. StringID to use in any other case. * @post String parameters have been set. */ - StringID GetCapacityString(RefitOption *option) const + StringID GetCapacityString(const RefitOption &option) const { assert(_current_company == _local_company); Vehicle *v = Vehicle::Get(this->window_number); - CommandCost cost = DoCommand(v->tile, this->selected_vehicle, option->cargo | option->subtype << 8 | this->num_vehicles << 16 | + CommandCost cost = DoCommand(v->tile, this->selected_vehicle, option.cargo | option.subtype << 8 | this->num_vehicles << 16 | (int)this->auto_refit << 24, DC_QUERY_COST, GetCmdRefitVeh(v->type)); if (cost.Failed()) return INVALID_STRING_ID; - SetDParam(0, option->cargo); + SetDParam(0, option.cargo); SetDParam(1, _returned_refit_capacity); Money money = cost.GetCost(); @@ -1165,12 +1131,12 @@ struct RefitWindow : public Window { } case WID_VR_MATRIX: - DrawVehicleRefitWindow(this->list, this->sel, this->vscroll->GetPosition(), this->vscroll->GetCapacity(), this->resize.step_height, r); + DrawVehicleRefitWindow(this->refit_list, this->selected_refit, this->vscroll->GetPosition(), this->vscroll->GetCapacity(), this->resize.step_height, r); break; case WID_VR_INFO: - if (this->cargo != nullptr) { - StringID string = this->GetCapacityString(this->cargo); + if (this->selected_refit != nullptr) { + StringID string = this->GetCapacityString(*this->selected_refit); if (string != INVALID_STRING_ID) { DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.framerect), string); } @@ -1206,9 +1172,9 @@ struct RefitWindow : public Window { uint max_width = 0; /* Check the width of all cargo information strings. */ - for (uint i = 0; i < NUM_CARGO; i++) { - for (uint j = 0; j < this->list[i].size(); j++) { - StringID string = this->GetCapacityString(&list[i][j]); + for (const auto &list : this->refit_list) { + for (const RefitOption &refit : list.second) { + StringID string = this->GetCapacityString(refit); if (string != INVALID_STRING_ID) { Dimension dim = GetStringBoundingBox(string); max_width = std::max(dim.width, max_width); @@ -1225,7 +1191,6 @@ struct RefitWindow : public Window { case 1: // A new cargo has been selected. if (!gui_scope) break; - this->cargo = GetRefitOption(); this->RefreshScrollbar(); break; } @@ -1336,7 +1301,7 @@ struct RefitWindow : public Window { case WID_VR_MATRIX: { // listbox this->SetSelection(this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_VR_MATRIX)); - this->SetWidgetDisabledState(WID_VR_REFIT, this->sel[0] < 0); + this->SetWidgetDisabledState(WID_VR_REFIT, this->selected_refit == nullptr); this->InvalidateData(1); if (click_count == 1) break; @@ -1344,17 +1309,17 @@ struct RefitWindow : public Window { } case WID_VR_REFIT: // refit button - if (this->cargo != nullptr) { + if (this->selected_refit != nullptr) { const Vehicle *v = Vehicle::Get(this->window_number); if (this->order == INVALID_VEH_ORDER_ID) { bool delete_window = this->selected_vehicle == v->index && this->num_vehicles == UINT8_MAX; - if (DoCommandP(v->tile, this->selected_vehicle, this->cargo->cargo | this->cargo->subtype << 8 | this->num_vehicles << 16 | this->is_virtual_train << 31, + if (DoCommandP(v->tile, this->selected_vehicle, this->selected_refit->cargo | this->selected_refit->subtype << 8 | this->num_vehicles << 16 | this->is_virtual_train << 31, GetCmdRefitVeh(v)) && delete_window) { this->Close(); } } else { - if (DoCommandP(v->tile, v->index, this->cargo->cargo | this->cargo->subtype << 8 | this->order << 16, CMD_ORDER_REFIT)) this->Close(); + if (DoCommandP(v->tile, v->index, this->selected_refit->cargo | this->selected_refit->subtype << 8 | this->order << 16, CMD_ORDER_REFIT)) this->Close(); } } break; @@ -2263,7 +2228,7 @@ public: this->SortVehicleList(); } - void Close() override + void Close(int data = 0) override { *this->sorting = this->vehgroups.GetListing(); this->RefreshRouteOverlay(); @@ -2412,7 +2377,7 @@ public: if (show_buttons) { this->SetWidgetDisabledState(WID_VL_AVAILABLE_VEHICLES, this->owner != _local_company || this->vli.type != VL_STANDARD); this->SetWidgetDisabledState(WID_VL_MANAGE_VEHICLES_DROPDOWN, !this->ShouldShowActionDropdownList()); - this->SetWidgetsDisabledState(this->owner != _local_company || this->vehicles.size() == 0 || (this->vli.type == VL_STANDARD && _settings_client.gui.disable_top_veh_list_mass_actions), + this->SetWidgetsDisabledState(this->owner != _local_company || this->vehicles.empty() || (this->vli.type == VL_STANDARD && _settings_client.gui.disable_top_veh_list_mass_actions), WID_VL_STOP_ALL, WID_VL_START_ALL); } @@ -2882,7 +2847,7 @@ struct VehicleDetailsWindow : Window { if (v->type == VEH_TRAIN && _shift_pressed) this->tab = TDW_TAB_TOTALS; } - void Close() override + void Close(int data = 0) override { if (this->window_number != INVALID_VEHICLE) { if (!FocusWindowById(WC_VEHICLE_VIEW, this->window_number)) { @@ -3671,7 +3636,7 @@ public: this->UpdateButtonStatus(); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { if (this->window_number != INVALID_VEHICLE) { const Vehicle *v = Vehicle::Get(this->window_number); diff --git a/src/waypoint_gui.cpp b/src/waypoint_gui.cpp index db8b7aff73..d065a1eb14 100644 --- a/src/waypoint_gui.cpp +++ b/src/waypoint_gui.cpp @@ -106,7 +106,7 @@ public: this->OnInvalidateData(0); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { CloseWindowById(GetWindowClassForVehicleType(this->vt), VehicleListIdentifier(VL_STATION_LIST, this->vt, this->owner, this->window_number).Pack(), false); SetViewportCatchmentWaypoint(Waypoint::Get(this->window_number), false); diff --git a/src/widgets/dropdown.cpp b/src/widgets/dropdown.cpp index 78b84176f7..a9fe95e9d4 100644 --- a/src/widgets/dropdown.cpp +++ b/src/widgets/dropdown.cpp @@ -137,7 +137,7 @@ struct DropdownWindow : Window { DropdownWindow(Window *parent, DropDownList &&list, int selected, int button, bool instant_close, const Point &position, const Dimension &size, Colours wi_colour, bool scroll, DropDownSyncFocus sync_parent_focus) : Window(&_dropdown_desc), list(std::move(list)) { - assert(this->list.size() > 0); + assert(!this->list.empty()); this->position = position; this->parent_wnd_class = parent->window_class; @@ -179,7 +179,7 @@ struct DropdownWindow : Window { this->scrolling_timer = GUITimer(MILLISECONDS_PER_TICK); } - void Close() override + void Close([[maybe_unused]] int data = 0) override { /* Make the dropdown "invisible", so it doesn't affect new window placement. * Also mark it dirty in case the callback deals with the screen. (e.g. screenshots). */ @@ -493,7 +493,7 @@ void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int butt for (uint i = 0; strings[i] != INVALID_STRING_ID; i++) { if (i >= 32 || !HasBit(hidden_mask, i)) { - list.emplace_back(new DropDownListStringItem(strings[i], i, i < 32 && HasBit(disabled_mask, i))); + list.push_back(std::make_unique(strings[i], i, i < 32 && HasBit(disabled_mask, i))); } } diff --git a/src/widgets/slider.cpp b/src/widgets/slider.cpp index 59d0483668..f7678908d3 100644 --- a/src/widgets/slider.cpp +++ b/src/widgets/slider.cpp @@ -29,7 +29,7 @@ static const int SLIDER_WIDTH = 3; void DrawSliderWidget(Rect r, int min_value, int max_value, int value, const std::map &labels) { /* Allow space for labels. We assume they are in the small font. */ - if (labels.size() > 0) r.bottom -= FONT_HEIGHT_SMALL + WidgetDimensions::scaled.hsep_normal; + if (!labels.empty()) r.bottom -= FONT_HEIGHT_SMALL + WidgetDimensions::scaled.hsep_normal; max_value -= min_value; diff --git a/src/window.cpp b/src/window.cpp index 7bc8bac177..33a6304eb0 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1066,7 +1066,7 @@ void Window::CloseChildWindows(WindowClass wc) const /** * Hide the window and all its child windows, and mark them for a later deletion. */ -void Window::Close() +void Window::Close([[maybe_unused]] int data) { if (_thd.window_class == this->window_class && _thd.window_number == this->window_number) { @@ -1160,11 +1160,11 @@ Window *GetMainWindow() * @param number Number of the window within the window class * @param force force deletion; if false don't delete when stickied */ -void CloseWindowById(WindowClass cls, WindowNumber number, bool force) +void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data) { Window *w = FindWindowById(cls, number); if (w != nullptr && (force || (w->flags & WF_STICKY) == 0)) { - w->Close(); + w->Close(data); } } @@ -1174,14 +1174,14 @@ void CloseWindowById(WindowClass cls, WindowNumber number, bool force) * @param number Number of the window within the window class * @param force force deletion; if false don't delete when stickied */ -void CloseAllWindowsById(WindowClass cls, WindowNumber number, bool force) +void CloseAllWindowsById(WindowClass cls, WindowNumber number, bool force, int data) { if (cls < WC_END && !_present_window_types[cls]) return; /* Note: the container remains stable, even when deleting windows. */ for (Window *w : Window::Iterate()) { if (w->window_class == cls && w->window_number == number && (force || (w->flags & WF_STICKY) == 0)) { - w->Close(); + w->Close(data); } } } @@ -1190,14 +1190,14 @@ void CloseAllWindowsById(WindowClass cls, WindowNumber number, bool force) * Delete all windows of a given class * @param cls Window class of windows to delete */ -void CloseWindowByClass(WindowClass cls) +void CloseWindowByClass(WindowClass cls, int data) { if (cls < WC_END && !_present_window_types[cls]) return; /* Note: the container remains stable, even when deleting windows. */ for (Window *w : Window::Iterate()) { if (w->window_class == cls) { - w->Close(); + w->Close(data); } } } @@ -3752,7 +3752,7 @@ void RelocateAllWindows(int neww, int newh) * Hide the window and all its child windows, and mark them for a later deletion. * Always call ResetObjectToPlace() when closing a PickerWindow. */ -void PickerWindowBase::Close() +void PickerWindowBase::Close([[maybe_unused]] int data) { ResetObjectToPlace(); this->Window::Close(); diff --git a/src/window_func.h b/src/window_func.h index e209702cce..7374c27c88 100644 --- a/src/window_func.h +++ b/src/window_func.h @@ -57,9 +57,9 @@ void SetWindowWidgetDirty(WindowClass cls, WindowNumber number, byte widget_inde void SetWindowDirty(WindowClass cls, WindowNumber number); void SetWindowClassesDirty(WindowClass cls); -void CloseWindowById(WindowClass cls, WindowNumber number, bool force = true); -void CloseAllWindowsById(WindowClass cls, WindowNumber number, bool force = true); -void CloseWindowByClass(WindowClass cls); +void CloseWindowById(WindowClass cls, WindowNumber number, bool force = true, int data = 0); +void CloseAllWindowsById(WindowClass cls, WindowNumber number, bool force = true, int data = 0); +void CloseWindowByClass(WindowClass cls, int data = 0); bool FocusWindowById(WindowClass cls, WindowNumber number); diff --git a/src/window_gui.h b/src/window_gui.h index 23fb2f5fa1..a3e48f3791 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -269,7 +269,7 @@ protected: public: Window(WindowDesc *desc); - virtual void Close(); + virtual void Close(int data = 0); static void DeleteClosedWindows(); WindowDesc *window_desc; ///< Window description @@ -1003,7 +1003,7 @@ public: this->parent = parent; } - void Close() override; + void Close([[maybe_unused]] int data = 0) override; }; Window *BringWindowToFrontById(WindowClass cls, WindowNumber number);