From 2ab3b5516f5641d726e936a31a999d61b34a4c00 Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Mon, 21 Jul 2025 06:46:16 -0400 Subject: [PATCH 001/137] Codechange: Early continue for cargos not moved by this station --- src/station_cmd.cpp | 244 ++++++++++++++++++++++---------------------- 1 file changed, 123 insertions(+), 121 deletions(-) diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 333460b53bbf7..0d89063424f4b 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -3955,144 +3955,146 @@ static void UpdateStationRating(Station *st) for (const CargoSpec *cs : CargoSpec::Iterate()) { GoodsEntry *ge = &st->goods[cs->Index()]; - /* Slowly increase the rating back to its original level in the case we - * didn't deliver cargo yet to this station. This happens when a bribe - * failed while you didn't moved that cargo yet to a station. */ - if (!ge->HasRating() && ge->rating < INITIAL_STATION_RATING) { - ge->rating++; - } - - /* Only change the rating if we are moving this cargo */ - if (ge->HasRating()) { - byte_inc_sat(&ge->time_since_pickup); - if (ge->time_since_pickup == 255 && _settings_game.order.selectgoods) { - ge->status.Reset(GoodsEntry::State::Rating); - ge->last_speed = 0; - TruncateCargo(cs, ge); - waiting_changed = true; - continue; - } - bool skip = false; - int rating = 0; - uint waiting = ge->HasData() ? ge->GetData().cargo.AvailableCount() : 0; - - /* num_dests is at least 1 if there is any cargo as - * StationID::Invalid() is also a destination. - */ - uint num_dests = ge->HasData() ? static_cast(ge->GetData().cargo.Packets()->MapSize()) : 0; - - /* Average amount of cargo per next hop, but prefer solitary stations - * with only one or two next hops. They are allowed to have more - * cargo waiting per next hop. - * With manual cargo distribution waiting_avg = waiting / 2 as then - * StationID::Invalid() is the only destination. - */ - uint waiting_avg = waiting / (num_dests + 1); - - if (_cheats.station_rating.value) { - ge->rating = rating = MAX_STATION_RATING; + /* The station might not currently be moving this cargo. */ + if (!ge->HasRating()) { + /* Slowly increase the rating back to its original level in the case we + * didn't deliver cargo yet to this station. This happens when a bribe + * failed while you didn't moved that cargo yet to a station. */ + if (ge->rating < INITIAL_STATION_RATING) ge->rating++; + + /* Nothing else to do with this cargo. */ + continue; + } + + byte_inc_sat(&ge->time_since_pickup); + if (ge->time_since_pickup == 255 && _settings_game.order.selectgoods) { + ge->status.Reset(GoodsEntry::State::Rating); + ge->last_speed = 0; + TruncateCargo(cs, ge); + waiting_changed = true; + continue; + } + + bool skip = false; + int rating = 0; + uint waiting = ge->HasData() ? ge->GetData().cargo.AvailableCount() : 0; + + /* num_dests is at least 1 if there is any cargo as + * StationID::Invalid() is also a destination. + */ + uint num_dests = ge->HasData() ? static_cast(ge->GetData().cargo.Packets()->MapSize()) : 0; + + /* Average amount of cargo per next hop, but prefer solitary stations + * with only one or two next hops. They are allowed to have more + * cargo waiting per next hop. + * With manual cargo distribution waiting_avg = waiting / 2 as then + * StationID::Invalid() is the only destination. + */ + uint waiting_avg = waiting / (num_dests + 1); + + if (_cheats.station_rating.value) { + ge->rating = rating = MAX_STATION_RATING; + skip = true; + } else if (cs->callback_mask.Test(CargoCallbackMask::StationRatingCalc)) { + /* Perform custom station rating. If it succeeds the speed, days in transit and + * waiting cargo ratings must not be executed. */ + + /* NewGRFs expect last speed to be 0xFF when no vehicle has arrived yet. */ + uint last_speed = ge->HasVehicleEverTriedLoading() ? ge->last_speed : 0xFF; + + uint32_t var18 = ClampTo(ge->time_since_pickup) + | (ClampTo(ge->max_waiting_cargo) << 8) + | (ClampTo(last_speed) << 24); + /* Convert to the 'old' vehicle types */ + uint32_t var10 = (st->last_vehicle_type == VEH_INVALID) ? 0x0 : (st->last_vehicle_type + 0x10); + uint16_t callback = GetCargoCallback(CBID_CARGO_STATION_RATING_CALC, var10, var18, cs); + if (callback != CALLBACK_FAILED) { skip = true; - } else if (cs->callback_mask.Test(CargoCallbackMask::StationRatingCalc)) { - /* Perform custom station rating. If it succeeds the speed, days in transit and - * waiting cargo ratings must not be executed. */ - - /* NewGRFs expect last speed to be 0xFF when no vehicle has arrived yet. */ - uint last_speed = ge->HasVehicleEverTriedLoading() ? ge->last_speed : 0xFF; - - uint32_t var18 = ClampTo(ge->time_since_pickup) - | (ClampTo(ge->max_waiting_cargo) << 8) - | (ClampTo(last_speed) << 24); - /* Convert to the 'old' vehicle types */ - uint32_t var10 = (st->last_vehicle_type == VEH_INVALID) ? 0x0 : (st->last_vehicle_type + 0x10); - uint16_t callback = GetCargoCallback(CBID_CARGO_STATION_RATING_CALC, var10, var18, cs); - if (callback != CALLBACK_FAILED) { - skip = true; - rating = GB(callback, 0, 14); - - /* Simulate a 15 bit signed value */ - if (HasBit(callback, 14)) rating -= 0x4000; - } - } + rating = GB(callback, 0, 14); - if (!skip) { - int b = ge->last_speed - 85; - if (b >= 0) rating += b >> 2; - - uint8_t waittime = ge->time_since_pickup; - if (st->last_vehicle_type == VEH_SHIP) waittime >>= 2; - if (waittime <= 21) rating += 25; - if (waittime <= 12) rating += 25; - if (waittime <= 6) rating += 45; - if (waittime <= 3) rating += 35; - - rating -= 90; - if (ge->max_waiting_cargo <= 1500) rating += 55; - if (ge->max_waiting_cargo <= 1000) rating += 35; - if (ge->max_waiting_cargo <= 600) rating += 10; - if (ge->max_waiting_cargo <= 300) rating += 20; - if (ge->max_waiting_cargo <= 100) rating += 10; + /* Simulate a 15 bit signed value */ + if (HasBit(callback, 14)) rating -= 0x4000; } + } - if (Company::IsValidID(st->owner) && st->town->statues.Test(st->owner)) rating += 26; + if (!skip) { + int b = ge->last_speed - 85; + if (b >= 0) rating += b >> 2; - uint8_t age = ge->last_age; - if (age < 3) rating += 10; - if (age < 2) rating += 10; - if (age < 1) rating += 13; + uint8_t waittime = ge->time_since_pickup; + if (st->last_vehicle_type == VEH_SHIP) waittime >>= 2; + if (waittime <= 21) rating += 25; + if (waittime <= 12) rating += 25; + if (waittime <= 6) rating += 45; + if (waittime <= 3) rating += 35; - { - int or_ = ge->rating; // old rating + rating -= 90; + if (ge->max_waiting_cargo <= 1500) rating += 55; + if (ge->max_waiting_cargo <= 1000) rating += 35; + if (ge->max_waiting_cargo <= 600) rating += 10; + if (ge->max_waiting_cargo <= 300) rating += 20; + if (ge->max_waiting_cargo <= 100) rating += 10; + } - /* only modify rating in steps of -2, -1, 0, 1 or 2 */ - ge->rating = rating = ClampTo(or_ + Clamp(rating - or_, -2, 2)); + if (Company::IsValidID(st->owner) && st->town->statues.Test(st->owner)) rating += 26; - /* if rating is <= 64 and more than 100 items waiting on average per destination, - * remove some random amount of goods from the station */ - if (rating <= 64 && waiting_avg >= 100) { - int dec = Random() & 0x1F; - if (waiting_avg < 200) dec &= 7; - waiting -= (dec + 1) * num_dests; - waiting_changed = true; - } + uint8_t age = ge->last_age; + if (age < 3) rating += 10; + if (age < 2) rating += 10; + if (age < 1) rating += 13; - /* if rating is <= 127 and there are any items waiting, maybe remove some goods. */ - if (rating <= 127 && waiting != 0) { - uint32_t r = Random(); - if (rating <= (int)GB(r, 0, 7)) { - /* Need to have int, otherwise it will just overflow etc. */ - waiting = std::max((int)waiting - (int)((GB(r, 8, 2) - 1) * num_dests), 0); - waiting_changed = true; - } - } + { + int or_ = ge->rating; // old rating - /* At some point we really must cap the cargo. Previously this - * was a strict 4095, but now we'll have a less strict, but - * increasingly aggressive truncation of the amount of cargo. */ - static const uint WAITING_CARGO_THRESHOLD = 1 << 12; - static const uint WAITING_CARGO_CUT_FACTOR = 1 << 6; - static const uint MAX_WAITING_CARGO = 1 << 15; + /* only modify rating in steps of -2, -1, 0, 1 or 2 */ + ge->rating = rating = ClampTo(or_ + Clamp(rating - or_, -2, 2)); - if (waiting > WAITING_CARGO_THRESHOLD) { - uint difference = waiting - WAITING_CARGO_THRESHOLD; - waiting -= (difference / WAITING_CARGO_CUT_FACTOR); + /* if rating is <= 64 and more than 100 items waiting on average per destination, + * remove some random amount of goods from the station */ + if (rating <= 64 && waiting_avg >= 100) { + int dec = Random() & 0x1F; + if (waiting_avg < 200) dec &= 7; + waiting -= (dec + 1) * num_dests; + waiting_changed = true; + } - waiting = std::min(waiting, MAX_WAITING_CARGO); + /* if rating is <= 127 and there are any items waiting, maybe remove some goods. */ + if (rating <= 127 && waiting != 0) { + uint32_t r = Random(); + if (rating <= (int)GB(r, 0, 7)) { + /* Need to have int, otherwise it will just overflow etc. */ + waiting = std::max((int)waiting - (int)((GB(r, 8, 2) - 1) * num_dests), 0); waiting_changed = true; } + } - /* We can't truncate cargo that's already reserved for loading. - * Thus StoredCount() here. */ - if (waiting_changed && waiting < (ge->HasData() ? ge->GetData().cargo.AvailableCount() : 0)) { - /* Feed back the exact own waiting cargo at this station for the - * next rating calculation. */ - ge->max_waiting_cargo = 0; + /* At some point we really must cap the cargo. Previously this + * was a strict 4095, but now we'll have a less strict, but + * increasingly aggressive truncation of the amount of cargo. */ + static const uint WAITING_CARGO_THRESHOLD = 1 << 12; + static const uint WAITING_CARGO_CUT_FACTOR = 1 << 6; + static const uint MAX_WAITING_CARGO = 1 << 15; - TruncateCargo(cs, ge, ge->GetData().cargo.AvailableCount() - waiting); - } else { - /* If the average number per next hop is low, be more forgiving. */ - ge->max_waiting_cargo = waiting_avg; - } + if (waiting > WAITING_CARGO_THRESHOLD) { + uint difference = waiting - WAITING_CARGO_THRESHOLD; + waiting -= (difference / WAITING_CARGO_CUT_FACTOR); + + waiting = std::min(waiting, MAX_WAITING_CARGO); + waiting_changed = true; + } + + /* We can't truncate cargo that's already reserved for loading. + * Thus StoredCount() here. */ + if (waiting_changed && waiting < (ge->HasData() ? ge->GetData().cargo.AvailableCount() : 0)) { + /* Feed back the exact own waiting cargo at this station for the + * next rating calculation. */ + ge->max_waiting_cargo = 0; + + TruncateCargo(cs, ge, ge->GetData().cargo.AvailableCount() - waiting); + } else { + /* If the average number per next hop is low, be more forgiving. */ + ge->max_waiting_cargo = waiting_avg; } } } From 20067d2db5e5adadd237915558fa26b99ae42a6f Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Mon, 21 Jul 2025 06:49:35 -0400 Subject: [PATCH 002/137] Doc: Update station rating comments and doxygen. --- src/station_cmd.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 0d89063424f4b..2b5aadb8fe2ce 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -3946,6 +3946,10 @@ static void TruncateCargo(const CargoSpec *cs, GoodsEntry *ge, uint amount = UIN } } +/** + * Periodic update of a station's rating. + * @param st The station to update. + */ static void UpdateStationRating(Station *st) { bool waiting_changed = false; @@ -3968,6 +3972,8 @@ static void UpdateStationRating(Station *st) } byte_inc_sat(&ge->time_since_pickup); + + /* If this cargo hasn't been picked up in a long time, get rid of it. */ if (ge->time_since_pickup == 255 && _settings_game.order.selectgoods) { ge->status.Reset(GoodsEntry::State::Rating); ge->last_speed = 0; @@ -4351,6 +4357,14 @@ static const IntervalTimer _economy_stations_monthly({TimerGam } }); +/** + * Forcibly modify station ratings near a given tile. + * Used when a crash hurts a company's station ratings nearby, or when local authority actions affect nearby ratings. + * @param tile The center of the ratings change area. + * @param owner The station owner whose stations are affected. + * @param amount The amount to change the rating. + * @param radius The radius to search for stations, from the origin tile. + */ void ModifyStationRatingAround(TileIndex tile, Owner owner, int amount, uint radius) { ForAllStationsRadius(tile, radius, [&](Station *st) { From d07ff71c67001de45624c9fa3b82cb4f85225358 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 21 Sep 2025 02:25:31 +0100 Subject: [PATCH 003/137] Fix ed67aedabf: Wrong button type for town menu in scenario editor toolbar. (#14641) The button was changed from an action to a menu, which should be WWT_IMGBTN instead of WWT_PUSHIMGBTN. --- src/toolbar_gui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 8f71d93f1c3c4..c447b182b6bb3 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -2555,7 +2555,7 @@ static constexpr NWidgetPart _nested_toolb_scen_inner_widgets[] = { NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_ZOOM_OUT), SetSpriteTip(SPR_IMG_ZOOMOUT, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT), NWidget(NWID_SPACER), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_LAND_GENERATE), SetSpriteTip(SPR_IMG_LANDSCAPING, STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION_TOOLTIP), - NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_TOWN_GENERATE), SetSpriteTip(SPR_IMG_TOWN, STR_SCENEDIT_TOOLBAR_TOWN_GENERATION_TOOLTIP), + NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_TOWN_GENERATE), SetSpriteTip(SPR_IMG_TOWN, STR_SCENEDIT_TOOLBAR_TOWN_GENERATION_TOOLTIP), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_INDUSTRY), SetSpriteTip(SPR_IMG_INDUSTRY, STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION_TOOLTIP), NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_ROADS), SetSpriteTip(SPR_IMG_BUILDROAD, STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION_TOOLTIP), NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_TRAMS), SetSpriteTip(SPR_IMG_BUILDTRAMS, STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION_TOOLTIP), From 030bbc6399f9f9f4b11a4f97e92fc515025736a5 Mon Sep 17 00:00:00 2001 From: translators Date: Sun, 21 Sep 2025 04:37:37 +0000 Subject: [PATCH 004/137] Update: Translations from eints vietnamese: 4 changes by KhoiCanDev --- src/lang/vietnamese.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lang/vietnamese.txt b/src/lang/vietnamese.txt index ec663d1330e8b..cac92cff53711 100644 --- a/src/lang/vietnamese.txt +++ b/src/lang/vietnamese.txt @@ -3348,6 +3348,8 @@ STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: STR_SAVELOAD_FILTER_TITLE :{BLACK}Lọc: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Ghi đè file STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Bạn có chắc chắn ghi đè lên file đang tồn tại? +STR_SAVELOAD_DELETE_TITLE :{WHITE}Xóa File +STR_SAVELOAD_DELETE_WARNING :{WHITE}Bạn có chắc chắn muốn xóa file này? STR_SAVELOAD_DIRECTORY :{STRING} (Thư mục) STR_SAVELOAD_PARENT_DIRECTORY :{STRING} (Thư mục cha) @@ -4183,6 +4185,7 @@ STR_PURCHASE_INFO_ALL_BUT :Tất cả tr STR_PURCHASE_INFO_MAX_TE :{BLACK}Lực kéo tối đa: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Tầm xa: {GOLD}{COMMA} ô STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Kiểu máy bay: {GOLD}{STRING} +STR_PURCHASE_INFO_RAILTYPES :{BLACK}Kiểu đường ray: {GOLD}{STRING} ###length 3 STR_CARGO_TYPE_FILTER_ALL :Tất cả hàng hóa @@ -4366,6 +4369,7 @@ STR_ENGINE_PREVIEW_RUNCOST_YEAR :Chi phí hoạt STR_ENGINE_PREVIEW_RUNCOST_PERIOD :Chi phí hoạt động: {CURRENCY_LONG}/kỳ STR_ENGINE_PREVIEW_CAPACITY :Tải trọng: {CARGO_LONG} STR_ENGINE_PREVIEW_CAPACITY_2 :Tải trọng: {CARGO_LONG}, {CARGO_LONG} +STR_ENGINE_PREVIEW_RAILTYPES :Kiểu đường ray: {STRING} # Autoreplace window STR_REPLACE_VEHICLES_WHITE :{WHITE}Thay thế {STRING} - {STRING} From 70d418285060efb28c964f299bb898baf59b3ac9 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 21 Sep 2025 09:32:25 +0100 Subject: [PATCH 005/137] Fix #14631, Fix 1cb0cbcb6c: Waypoint customs spec not allocated properly on initial construction. (#14633) Split AllocateSpecToStation/RoadStop into Allocate and Assign functions, allowing command tests to occur separately. --- src/newgrf_roadstop.cpp | 37 +++++++++++++++++++++++------------ src/newgrf_roadstop.h | 3 ++- src/newgrf_station.cpp | 38 +++++++++++++++++++++++------------- src/newgrf_station.h | 3 ++- src/saveload/waypoint_sl.cpp | 3 ++- src/station_cmd.cpp | 6 ++++-- src/waypoint_cmd.cpp | 9 ++++++--- 7 files changed, 64 insertions(+), 35 deletions(-) diff --git a/src/newgrf_roadstop.cpp b/src/newgrf_roadstop.cpp index da022d14f336b..f093c0b2b495c 100644 --- a/src/newgrf_roadstop.cpp +++ b/src/newgrf_roadstop.cpp @@ -561,20 +561,22 @@ const RoadStopSpec *GetRoadStopSpec(TileIndex t) /** * Allocate a RoadStopSpec to a Station. This is called once per build operation. - * @param statspec RoadStopSpec to allocate. + * @param spec RoadStopSpec to allocate. * @param st Station to allocate it to. - * @param exec Whether to actually allocate the spec. * @return Index within the Station's road stop spec list, or std::nullopt if the allocation failed. */ -std::optional AllocateSpecToRoadStop(const RoadStopSpec *statspec, BaseStation *st, bool exec) +std::optional AllocateSpecToRoadStop(const RoadStopSpec *spec, BaseStation *st) { uint i; - if (statspec == nullptr || st == nullptr) return 0; + if (spec == nullptr) return 0; + + /* If station doesn't exist yet then the first slot is available. */ + if (st == nullptr) return 1; /* Try to find the same spec and return that one */ for (i = 1; i < st->roadstop_speclist.size() && i < NUM_ROADSTOPSPECS_PER_STATION; i++) { - if (st->roadstop_speclist[i].spec == statspec) return i; + if (st->roadstop_speclist[i].spec == spec) return i; } /* Try to find an unused spec slot */ @@ -587,16 +589,25 @@ std::optional AllocateSpecToRoadStop(const RoadStopSpec *statspec, Base return std::nullopt; } - if (exec) { - if (i >= st->roadstop_speclist.size()) st->roadstop_speclist.resize(i + 1); - st->roadstop_speclist[i].spec = statspec; - st->roadstop_speclist[i].grfid = statspec->grf_prop.grfid; - st->roadstop_speclist[i].localidx = statspec->grf_prop.local_id; + return i; +} - RoadStopUpdateCachedTriggers(st); - } +/** + * Assign a previously allocated RoadStopSpec specindex to a Station. + * @param spec RoadStopSpec to assign.. + * @param st Station to allocate it to. + * @param specindex Spec index of allocation. + */ +void AssignSpecToRoadStop(const RoadStopSpec *spec, BaseStation *st, uint8_t specindex) +{ + if (specindex == 0) return; + if (specindex >= st->roadstop_speclist.size()) st->roadstop_speclist.resize(specindex + 1); - return i; + st->roadstop_speclist[specindex].spec = spec; + st->roadstop_speclist[specindex].grfid = spec->grf_prop.grfid; + st->roadstop_speclist[specindex].localidx = spec->grf_prop.local_id; + + RoadStopUpdateCachedTriggers(st); } /** diff --git a/src/newgrf_roadstop.h b/src/newgrf_roadstop.h index 3f826aac43867..73fa2e9db673c 100644 --- a/src/newgrf_roadstop.h +++ b/src/newgrf_roadstop.h @@ -177,7 +177,8 @@ bool GetIfClassHasNewStopsByType(const RoadStopClass *roadstopclass, RoadStopTyp bool GetIfStopIsForType(const RoadStopSpec *roadstopspec, RoadStopType rs, RoadType roadtype); const RoadStopSpec *GetRoadStopSpec(TileIndex t); -std::optional AllocateSpecToRoadStop(const RoadStopSpec *statspec, BaseStation *st, bool exec); +std::optional AllocateSpecToRoadStop(const RoadStopSpec *spec, BaseStation *st); +void AssignSpecToRoadStop(const RoadStopSpec *spec, BaseStation *st, uint8_t specindex); void DeallocateSpecFromRoadStop(BaseStation *st, uint8_t specindex); void RoadStopUpdateCachedTriggers(BaseStation *st); diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index d307e6dd9da5d..358f6505d54ac 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -692,16 +692,18 @@ CommandCost PerformStationTileSlopeCheck(TileIndex north_tile, TileIndex cur_til /** * Allocate a StationSpec to a Station. This is called once per build operation. - * @param statspec StationSpec to allocate. + * @param spec StationSpec to allocate. * @param st Station to allocate it to. - * @param exec Whether to actually allocate the spec. * @return Index within the Station's station spec list, or std::nullopt if the allocation failed. */ -std::optional AllocateSpecToStation(const StationSpec *statspec, BaseStation *st, bool exec) +std::optional AllocateSpecToStation(const StationSpec *spec, BaseStation *st) { uint i; - if (statspec == nullptr || st == nullptr) return 0; + if (spec == nullptr) return 0; + + /* If station doesn't exist yet then the first slot is available. */ + if (st == nullptr) return 1; for (i = 1; i < st->speclist.size() && i < NUM_STATIONSSPECS_PER_STATION; i++) { if (st->speclist[i].spec == nullptr && st->speclist[i].grfid == 0) break; @@ -714,24 +716,32 @@ std::optional AllocateSpecToStation(const StationSpec *statspec, BaseSt * but it's fairly unlikely that one reaches the limit anyways. */ for (i = 1; i < st->speclist.size() && i < NUM_STATIONSSPECS_PER_STATION; i++) { - if (st->speclist[i].spec == statspec) return i; + if (st->speclist[i].spec == spec) return i; } return std::nullopt; } - if (exec) { - if (i >= st->speclist.size()) st->speclist.resize(i + 1); - st->speclist[i].spec = statspec; - st->speclist[i].grfid = statspec->grf_prop.grfid; - st->speclist[i].localidx = statspec->grf_prop.local_id; - - StationUpdateCachedTriggers(st); - } - return i; } +/** + * Assign a previously allocated StationSpec specindex to a Station. + * @param spec StationSpec to assign.. + * @param st Station to allocate it to. + * @param specindex Spec index of allocation. + */ +void AssignSpecToStation(const StationSpec *spec, BaseStation *st, uint8_t specindex) +{ + if (specindex == 0) return; + if (specindex >= st->speclist.size()) st->speclist.resize(specindex + 1); + + st->speclist[specindex].spec = spec; + st->speclist[specindex].grfid = spec->grf_prop.grfid; + st->speclist[specindex].localidx = spec->grf_prop.local_id; + + StationUpdateCachedTriggers(st); +} /** * Deallocate a StationSpec from a Station. Called when removing a single station tile. diff --git a/src/newgrf_station.h b/src/newgrf_station.h index 2537209fd8744..990f0bc4a94f8 100644 --- a/src/newgrf_station.h +++ b/src/newgrf_station.h @@ -215,7 +215,8 @@ SpriteID GetCustomStationFoundationRelocation(const StationSpec *statspec, BaseS uint16_t GetStationCallback(CallbackID callback, uint32_t param1, uint32_t param2, const StationSpec *statspec, BaseStation *st, TileIndex tile, std::span regs100 = {}); CommandCost PerformStationTileSlopeCheck(TileIndex north_tile, TileIndex cur_tile, const StationSpec *statspec, Axis axis, uint8_t plat_len, uint8_t numtracks); -std::optional AllocateSpecToStation(const StationSpec *statspec, BaseStation *st, bool exec); +std::optional AllocateSpecToStation(const StationSpec *spec, BaseStation *st); +void AssignSpecToStation(const StationSpec *spec, BaseStation *st, uint8_t specindex); void DeallocateSpecFromStation(BaseStation *st, uint8_t specindex); bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID sclass, uint station); diff --git a/src/saveload/waypoint_sl.cpp b/src/saveload/waypoint_sl.cpp index 58d014a15dd83..57edac03239da 100644 --- a/src/saveload/waypoint_sl.cpp +++ b/src/saveload/waypoint_sl.cpp @@ -136,7 +136,8 @@ void MoveWaypointsToBaseStations() SetRailStationReservation(tile, reserved); if (wp.spec != nullptr) { - auto specindex = AllocateSpecToStation(wp.spec, new_wp, true); + auto specindex = AllocateSpecToStation(wp.spec, new_wp); + if (specindex.has_value()) AssignSpecToStation(wp.spec, new_wp, *specindex); SetCustomStationSpecIndex(tile, specindex.value_or(0)); } new_wp->rect.BeforeAddTile(tile, StationRect::ADD_FORCE); diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 2b5aadb8fe2ce..ce85d755e2cd7 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -1491,7 +1491,7 @@ CommandCost CmdBuildRailStation(DoCommandFlags flags, TileIndex tile_org, RailTy } /* Check if we can allocate a custom stationspec to this station */ - auto specindex = AllocateSpecToStation(statspec, st, flags.Test(DoCommandFlag::Execute)); + auto specindex = AllocateSpecToStation(statspec, st); if (!specindex.has_value()) return CommandCost(STR_ERROR_TOO_MANY_STATION_SPECS); if (statspec != nullptr) { @@ -1514,6 +1514,7 @@ CommandCost CmdBuildRailStation(DoCommandFlags flags, TileIndex tile_org, RailTy st->rect.BeforeAddRect(tile_org, w_org, h_org, StationRect::ADD_TRY); + if (specindex.has_value()) AssignSpecToStation(statspec, st, *specindex); if (statspec != nullptr) { /* Include this station spec's animation trigger bitmask * in the station's cached copy. */ @@ -2113,7 +2114,7 @@ CommandCost CmdBuildRoadStop(DoCommandFlags flags, TileIndex tile, uint8_t width if (ret.Failed()) return ret; /* Check if we can allocate a custom stationspec to this station */ - auto specindex = AllocateSpecToRoadStop(roadstopspec, st, flags.Test(DoCommandFlag::Execute)); + auto specindex = AllocateSpecToRoadStop(roadstopspec, st); if (!specindex.has_value()) return CommandCost(STR_ERROR_TOO_MANY_STATION_SPECS); if (roadstopspec != nullptr) { @@ -2127,6 +2128,7 @@ CommandCost CmdBuildRoadStop(DoCommandFlags flags, TileIndex tile, uint8_t width } if (flags.Test(DoCommandFlag::Execute)) { + if (specindex.has_value()) AssignSpecToRoadStop(roadstopspec, st, *specindex); /* Check every tile in the area. */ for (TileIndex cur_tile : roadstop_area) { /* Get existing road types and owners before any tile clearing */ diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index 18a0540595c9f..1a0dba435dea5 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -271,7 +271,8 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlags flags, TileIndex start_tile, Axi if (!Waypoint::CanAllocateItem()) return CommandCost(STR_ERROR_TOO_MANY_STATIONS_LOADING); } - auto specindex = AllocateSpecToStation(spec, wp, flags.Test(DoCommandFlag::Execute)); + /* Check if we can allocate a custom spec to this waypoint. */ + auto specindex = AllocateSpecToStation(spec, wp); if (!specindex.has_value()) return CommandCost(STR_ERROR_TOO_MANY_STATION_SPECS); if (flags.Test(DoCommandFlag::Execute)) { @@ -284,6 +285,7 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlags flags, TileIndex start_tile, Axi wp->owner = GetTileOwner(start_tile); wp->rect.BeforeAddRect(start_tile, width, height, StationRect::ADD_TRY); + if (specindex.has_value()) AssignSpecToStation(spec, wp, *specindex); wp->delete_ctr = 0; wp->facilities.Set(StationFacility::Train); @@ -391,8 +393,8 @@ CommandCost CmdBuildRoadWaypoint(DoCommandFlags flags, TileIndex start_tile, Axi if (!Waypoint::CanAllocateItem()) return CommandCost(STR_ERROR_TOO_MANY_STATIONS_LOADING); } - /* Check if we can allocate a custom roadstopspec to this station */ - auto specindex = AllocateSpecToRoadStop(roadstopspec, wp, flags.Test(DoCommandFlag::Execute)); + /* Check if we can allocate a custom spec to this waypoint. */ + auto specindex = AllocateSpecToRoadStop(roadstopspec, wp); if (!specindex.has_value()) return CommandCost(STR_ERROR_TOO_MANY_STATION_SPECS); if (flags.Test(DoCommandFlag::Execute)) { @@ -406,6 +408,7 @@ CommandCost CmdBuildRoadWaypoint(DoCommandFlags flags, TileIndex start_tile, Axi wp->owner = _current_company; wp->rect.BeforeAddRect(start_tile, width, height, StationRect::ADD_TRY); + if (specindex.has_value()) AssignSpecToRoadStop(roadstopspec, wp, *specindex); if (roadstopspec != nullptr) { /* Include this road stop spec's animation trigger bitmask From ce166bbbc314e463a607a131f32c997faded2203 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 21 Sep 2025 01:29:54 +0100 Subject: [PATCH 006/137] Codechange: Demagicify main toolbar button type. Use WWT_PUSHIMGBTN for non-menu buttons so they automatically raise, replacing the custom OnTimeout function. --- src/toolbar_gui.cpp | 79 ++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 44 deletions(-) diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index c447b182b6bb3..dec57a4400699 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -2109,15 +2109,6 @@ struct MainToolbarWindow : Window { } }}; - void OnTimeout() override - { - /* We do not want to automatically raise the pause, fast forward and - * switchbar buttons; they have to stay down when pressed etc. */ - for (WidgetID i = WID_TN_SETTINGS; i < WID_TN_SWITCH_BAR; i++) { - this->RaiseWidgetWhenLowered(i); - } - } - /** * Some data on this window has become invalid. * @param data Information about the changed data. @@ -2176,43 +2167,43 @@ struct MainToolbarWindow : Window { static std::unique_ptr MakeMainToolbar() { /** Sprites to use for the different toolbar buttons */ - static const SpriteID toolbar_button_sprites[] = { - SPR_IMG_PAUSE, // WID_TN_PAUSE - SPR_IMG_FASTFORWARD, // WID_TN_FAST_FORWARD - SPR_IMG_SETTINGS, // WID_TN_SETTINGS - SPR_IMG_SAVE, // WID_TN_SAVE - SPR_IMG_SMALLMAP, // WID_TN_SMALL_MAP - SPR_IMG_TOWN, // WID_TN_TOWNS - SPR_IMG_SUBSIDIES, // WID_TN_SUBSIDIES - SPR_IMG_COMPANY_LIST, // WID_TN_STATIONS - SPR_IMG_COMPANY_FINANCE, // WID_TN_FINANCES - SPR_IMG_COMPANY_GENERAL, // WID_TN_COMPANIES - SPR_IMG_STORY_BOOK, // WID_TN_STORY - SPR_IMG_GOAL, // WID_TN_GOAL - SPR_IMG_GRAPHS, // WID_TN_GRAPHS - SPR_IMG_COMPANY_LEAGUE, // WID_TN_LEAGUE - SPR_IMG_INDUSTRY, // WID_TN_INDUSTRIES - SPR_IMG_TRAINLIST, // WID_TN_TRAINS - SPR_IMG_TRUCKLIST, // WID_TN_ROADVEHS - SPR_IMG_SHIPLIST, // WID_TN_SHIPS - SPR_IMG_AIRPLANESLIST, // WID_TN_AIRCRAFT - SPR_IMG_ZOOMIN, // WID_TN_ZOOMIN - SPR_IMG_ZOOMOUT, // WID_TN_ZOOMOUT - SPR_IMG_BUILDRAIL, // WID_TN_RAILS - SPR_IMG_BUILDROAD, // WID_TN_ROADS - SPR_IMG_BUILDTRAMS, // WID_TN_TRAMS - SPR_IMG_BUILDWATER, // WID_TN_WATER - SPR_IMG_BUILDAIR, // WID_TN_AIR - SPR_IMG_LANDSCAPING, // WID_TN_LANDSCAPE - SPR_IMG_MUSIC, // WID_TN_MUSIC_SOUND - SPR_IMG_MESSAGES, // WID_TN_MESSAGES - SPR_IMG_QUERY, // WID_TN_HELP - SPR_IMG_SWITCH_TOOLBAR, // WID_TN_SWITCH_BAR + static const std::tuple toolbar_button_sprites[] = { + {WID_TN_PAUSE, WWT_IMGBTN, SPR_IMG_PAUSE}, + {WID_TN_FAST_FORWARD, WWT_IMGBTN, SPR_IMG_FASTFORWARD}, + {WID_TN_SETTINGS, WWT_IMGBTN, SPR_IMG_SETTINGS}, + {WID_TN_SAVE, WWT_IMGBTN_2, SPR_IMG_SAVE}, + {WID_TN_SMALL_MAP, WWT_IMGBTN, SPR_IMG_SMALLMAP}, + {WID_TN_TOWNS, WWT_IMGBTN, SPR_IMG_TOWN}, + {WID_TN_SUBSIDIES, WWT_IMGBTN, SPR_IMG_SUBSIDIES}, + {WID_TN_STATIONS, WWT_IMGBTN, SPR_IMG_COMPANY_LIST}, + {WID_TN_FINANCES, WWT_IMGBTN, SPR_IMG_COMPANY_FINANCE}, + {WID_TN_COMPANIES, WWT_IMGBTN, SPR_IMG_COMPANY_GENERAL}, + {WID_TN_STORY, WWT_IMGBTN, SPR_IMG_STORY_BOOK}, + {WID_TN_GOAL, WWT_IMGBTN, SPR_IMG_GOAL}, + {WID_TN_GRAPHS, WWT_IMGBTN, SPR_IMG_GRAPHS}, + {WID_TN_LEAGUE, WWT_IMGBTN, SPR_IMG_COMPANY_LEAGUE}, + {WID_TN_INDUSTRIES, WWT_IMGBTN, SPR_IMG_INDUSTRY}, + {WID_TN_TRAINS, WWT_IMGBTN, SPR_IMG_TRAINLIST}, + {WID_TN_ROADVEHS, WWT_IMGBTN, SPR_IMG_TRUCKLIST}, + {WID_TN_SHIPS, WWT_IMGBTN, SPR_IMG_SHIPLIST}, + {WID_TN_AIRCRAFT, WWT_IMGBTN, SPR_IMG_AIRPLANESLIST}, + {WID_TN_ZOOM_IN, WWT_PUSHIMGBTN, SPR_IMG_ZOOMIN}, + {WID_TN_ZOOM_OUT, WWT_PUSHIMGBTN, SPR_IMG_ZOOMOUT}, + {WID_TN_RAILS, WWT_IMGBTN, SPR_IMG_BUILDRAIL}, + {WID_TN_ROADS, WWT_IMGBTN, SPR_IMG_BUILDROAD}, + {WID_TN_TRAMS, WWT_IMGBTN, SPR_IMG_BUILDTRAMS}, + {WID_TN_WATER, WWT_IMGBTN, SPR_IMG_BUILDWATER}, + {WID_TN_AIR, WWT_IMGBTN, SPR_IMG_BUILDAIR}, + {WID_TN_LANDSCAPE, WWT_IMGBTN, SPR_IMG_LANDSCAPING}, + {WID_TN_MUSIC_SOUND, WWT_IMGBTN, SPR_IMG_MUSIC}, + {WID_TN_MESSAGES, WWT_IMGBTN, SPR_IMG_MESSAGES}, + {WID_TN_HELP, WWT_IMGBTN, SPR_IMG_QUERY}, + {WID_TN_SWITCH_BAR, WWT_IMGBTN, SPR_IMG_SWITCH_TOOLBAR}, }; auto hor = std::make_unique(); - for (WidgetID i = 0; i < WID_TN_END; i++) { - switch (i) { + for (const auto &[widget, tp, sprite] : toolbar_button_sprites) { + switch (widget) { case WID_TN_SMALL_MAP: case WID_TN_FINANCES: case WID_TN_VEHICLE_START: @@ -2222,7 +2213,7 @@ static std::unique_ptr MakeMainToolbar() hor->Add(std::make_unique(0, 0)); break; } - auto leaf = std::make_unique(i == WID_TN_SAVE ? WWT_IMGBTN_2 : WWT_IMGBTN, COLOUR_GREY, i, WidgetData{.sprite = toolbar_button_sprites[i]}, STR_TOOLBAR_TOOLTIP_PAUSE_GAME + i); + auto leaf = std::make_unique(tp, COLOUR_GREY, widget, WidgetData{.sprite = sprite}, STR_TOOLBAR_TOOLTIP_PAUSE_GAME + widget); leaf->SetMinimalSize(20, 20); hor->Add(std::move(leaf)); } From 69697a62d340c316ea0ee8c8aabbdcba8695e4c2 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 21 Sep 2025 01:00:20 +0100 Subject: [PATCH 007/137] Fix 8c58fb1efdc: Doubled beep sounds when clicking toolbar buttons. * ShowDropDownList() now issues a beep, so individual toolbar buttons no longer need to do it. * HandleButtonClick() may be called twice for some buttons, as it is called by automatically for PUSH buttons. This caused some beeps to sound louder than others. --- src/toolbar_gui.cpp | 14 -------------- src/window.cpp | 3 +++ 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index dec57a4400699..eba265fc7ba42 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -117,7 +117,6 @@ class DropDownListCompanyItem : public DropDownIconresult; ShowDropDownList(w, std::move(list), selected, WID_TN_LEAGUE, 140, _settings_client.gui.toolbar_dropdown_autoselect); - SndClickBeep(); - return CBF_NONE; } @@ -876,7 +870,6 @@ static CallBackFunction ToolbarZoomOutClick(Window *w) static CallBackFunction ToolbarBuildRailClick(Window *w) { ShowDropDownList(w, GetRailTypeDropDownList(), _last_built_railtype, WID_TN_RAILS, 140, _settings_client.gui.toolbar_dropdown_autoselect); - SndClickBeep(); return CBF_NONE; } @@ -898,7 +891,6 @@ static CallBackFunction MenuClickBuildRail(int index) static CallBackFunction ToolbarBuildRoadClick(Window *w) { ShowDropDownList(w, GetRoadTypeDropDownList(RTTB_ROAD), _last_built_roadtype, WID_TN_ROADS, 140, _settings_client.gui.toolbar_dropdown_autoselect); - SndClickBeep(); return CBF_NONE; } @@ -920,7 +912,6 @@ static CallBackFunction MenuClickBuildRoad(int index) static CallBackFunction ToolbarBuildTramClick(Window *w) { ShowDropDownList(w, GetRoadTypeDropDownList(RTTB_TRAM), _last_built_tramtype, WID_TN_TRAMS, 140, _settings_client.gui.toolbar_dropdown_autoselect); - SndClickBeep(); return CBF_NONE; } @@ -944,7 +935,6 @@ static CallBackFunction ToolbarBuildWaterClick(Window *w) DropDownList list; list.push_back(MakeDropDownListIconItem(SPR_IMG_BUILD_CANAL, PAL_NONE, STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION, 0)); ShowDropDownList(w, std::move(list), 0, WID_TN_WATER, 140, _settings_client.gui.toolbar_dropdown_autoselect); - SndClickBeep(); return CBF_NONE; } @@ -966,7 +956,6 @@ static CallBackFunction ToolbarBuildAirClick(Window *w) DropDownList list; list.push_back(MakeDropDownListIconItem(SPR_IMG_AIRPORT, PAL_NONE, STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION, 0)); ShowDropDownList(w, std::move(list), 0, WID_TN_AIR, 140, _settings_client.gui.toolbar_dropdown_autoselect); - SndClickBeep(); return CBF_NONE; } @@ -990,7 +979,6 @@ static CallBackFunction ToolbarForestClick(Window *w) list.push_back(MakeDropDownListIconItem(SPR_IMG_PLANTTREES, PAL_NONE, STR_LANDSCAPING_MENU_PLANT_TREES, 1)); list.push_back(MakeDropDownListIconItem(SPR_IMG_SIGN, PAL_NONE, STR_LANDSCAPING_MENU_PLACE_SIGN, 2)); ShowDropDownList(w, std::move(list), 0, WID_TN_LANDSCAPE, 100, _settings_client.gui.toolbar_dropdown_autoselect); - SndClickBeep(); return CBF_NONE; } @@ -1260,7 +1248,6 @@ static CallBackFunction ToolbarScenGenIndustry(Window *w) static CallBackFunction ToolbarScenBuildRoadClick(Window *w) { ShowDropDownList(w, GetScenRoadTypeDropDownList(RTTB_ROAD), _last_built_roadtype, WID_TE_ROADS, 140, _settings_client.gui.toolbar_dropdown_autoselect); - SndClickBeep(); return CBF_NONE; } @@ -1280,7 +1267,6 @@ static CallBackFunction ToolbarScenBuildRoad(int index) static CallBackFunction ToolbarScenBuildTramClick(Window *w) { ShowDropDownList(w, GetScenRoadTypeDropDownList(RTTB_TRAM), _last_built_tramtype, WID_TE_TRAMS, 140, _settings_client.gui.toolbar_dropdown_autoselect); - SndClickBeep(); return CBF_NONE; } diff --git a/src/window.cpp b/src/window.cpp index 50422b89de84a..e40641f24ed78 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -594,6 +594,9 @@ EventState Window::OnHotkey(int hotkey) */ void Window::HandleButtonClick(WidgetID widget) { + /* Button click for this widget may already have been handled. */ + if (this->IsWidgetLowered(widget) && this->timeout_timer == TIMEOUT_DURATION) return; + this->LowerWidget(widget); this->SetTimeout(); this->SetWidgetDirty(widget); From 13ab9c1adc8189bf4a74801efe57311b2a591caa Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 21 Sep 2025 13:41:23 +0100 Subject: [PATCH 008/137] Fix 6e90b828c6: Off-by-one in Rect::CentreTo. (#14643) * Rect right/bottom are inclusive so -1 must be taken from width/height. * Misnamed variable, `new_right` is actually `new_top`. --- src/core/geometry_type.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/geometry_type.hpp b/src/core/geometry_type.hpp index b3400c2cc3eff..f5bb66f554228 100644 --- a/src/core/geometry_type.hpp +++ b/src/core/geometry_type.hpp @@ -261,8 +261,8 @@ struct Rect { [[nodiscard]] inline Rect CentreTo(int width, int height) const { int new_left = CentreBounds(this->left, this->right, width); - int new_right = CentreBounds(this->top, this->bottom, height); - return {new_left, new_right, new_left + width, new_right + height}; + int new_top = CentreBounds(this->top, this->bottom, height); + return {new_left, new_top, new_left + width - 1, new_top + height - 1}; } }; From 29012c3fce476334b883a6a4bac55d154df1099a Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 21 Sep 2025 13:41:47 +0100 Subject: [PATCH 009/137] Codechange: Move settings entry size global variables. (#14644) _setting_circle_size and (the incorrectly named) SETTING_HEIGHT variables are now static members of BaseSettingEntry. Neither of these are constants, so they no longer use constant naming style. --- src/settingentry_gui.cpp | 18 +++++++++--------- src/settingentry_gui.h | 6 +++--- src/settings_gui.cpp | 14 ++++++-------- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/settingentry_gui.cpp b/src/settingentry_gui.cpp index 1d86a49369df4..087cff205d00b 100644 --- a/src/settingentry_gui.cpp +++ b/src/settingentry_gui.cpp @@ -94,22 +94,22 @@ uint BaseSettingEntry::Draw(GameSettings *settings_ptr, int left, int right, int if (cur_row >= max_row) return cur_row; bool rtl = _current_text_dir == TD_RTL; - int offset = (rtl ? -(int)_setting_circle_size.width : (int)_setting_circle_size.width) / 2; + int offset = (rtl ? -static_cast(BaseSettingEntry::circle_size.width) : static_cast(BaseSettingEntry::circle_size.width)) / 2; int level_width = rtl ? -WidgetDimensions::scaled.hsep_indent : WidgetDimensions::scaled.hsep_indent; int x = rtl ? right : left; if (cur_row >= first_row) { PixelColour colour = GetColourGradient(COLOUR_ORANGE, SHADE_NORMAL); - y += (cur_row - first_row) * SETTING_HEIGHT; // Compute correct y start position + y += (cur_row - first_row) * BaseSettingEntry::line_height; // Compute correct y start position /* Draw vertical for parent nesting levels */ for (uint lvl = 0; lvl < this->level; lvl++) { - if (!HasBit(parent_last, lvl)) GfxDrawLine(x + offset, y, x + offset, y + SETTING_HEIGHT - 1, colour); + if (!HasBit(parent_last, lvl)) GfxDrawLine(x + offset, y, x + offset, y + BaseSettingEntry::line_height - 1, colour); x += level_width; } /* draw own |- prefix */ - int halfway_y = y + SETTING_HEIGHT / 2; - int bottom_y = flags.Test(SettingEntryFlag::LastField) ? halfway_y : y + SETTING_HEIGHT - 1; + int halfway_y = y + BaseSettingEntry::line_height / 2; + int bottom_y = flags.Test(SettingEntryFlag::LastField) ? halfway_y : y + BaseSettingEntry::line_height - 1; GfxDrawLine(x + offset, y, x + offset, bottom_y, colour); /* Small horizontal line from the last vertical line */ GfxDrawLine(x + offset, halfway_y, x + level_width - (rtl ? -WidgetDimensions::scaled.hsep_normal : WidgetDimensions::scaled.hsep_normal), halfway_y, colour); @@ -274,7 +274,7 @@ void SettingEntry::DrawSetting(GameSettings *settings_ptr, int left, int right, uint buttons_left = rtl ? right + 1 - SETTING_BUTTON_WIDTH : left; uint text_left = left + (rtl ? 0 : SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_wide); uint text_right = right - (rtl ? SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_wide : 0); - uint button_y = y + (SETTING_HEIGHT - SETTING_BUTTON_HEIGHT) / 2; + uint button_y = y + (BaseSettingEntry::line_height - SETTING_BUTTON_HEIGHT) / 2; /* We do not allow changes of some items when we are a client in a networkgame */ bool editable = sd->IsEditable(); @@ -293,7 +293,7 @@ void SettingEntry::DrawSetting(GameSettings *settings_ptr, int left, int right, editable && value != (sd->flags.Test(SettingFlag::GuiZeroIsSpecial) ? 0 : min_val), editable && static_cast(value) != max_val); } auto [param1, param2] = sd->GetValueParams(value); - DrawString(text_left, text_right, y + (SETTING_HEIGHT - GetCharacterHeight(FS_NORMAL)) / 2, GetString(sd->GetTitle(), STR_CONFIG_SETTING_VALUE, param1, param2), highlight ? TC_WHITE : TC_LIGHT_BLUE); + DrawString(text_left, text_right, y + (BaseSettingEntry::line_height - GetCharacterHeight(FS_NORMAL)) / 2, GetString(sd->GetTitle(), STR_CONFIG_SETTING_VALUE, param1, param2), highlight ? TC_WHITE : TC_LIGHT_BLUE); } /* == SettingsContainer methods == */ @@ -611,8 +611,8 @@ uint SettingsPage::Draw(GameSettings *settings_ptr, int left, int right, int y, void SettingsPage::DrawSetting(GameSettings *, int left, int right, int y, bool) const { bool rtl = _current_text_dir == TD_RTL; - DrawSprite((this->folded ? SPR_CIRCLE_FOLDED : SPR_CIRCLE_UNFOLDED), PAL_NONE, rtl ? right - _setting_circle_size.width : left, y + (SETTING_HEIGHT - _setting_circle_size.height) / 2); - DrawString(rtl ? left : left + _setting_circle_size.width + WidgetDimensions::scaled.hsep_normal, rtl ? right - _setting_circle_size.width - WidgetDimensions::scaled.hsep_normal : right, y + (SETTING_HEIGHT - GetCharacterHeight(FS_NORMAL)) / 2, this->title, TC_ORANGE); + DrawSprite((this->folded ? SPR_CIRCLE_FOLDED : SPR_CIRCLE_UNFOLDED), PAL_NONE, rtl ? right - BaseSettingEntry::circle_size.width : left, y + (BaseSettingEntry::line_height - BaseSettingEntry::circle_size.height) / 2); + DrawString(rtl ? left : left + BaseSettingEntry::circle_size.width + WidgetDimensions::scaled.hsep_normal, rtl ? right - BaseSettingEntry::circle_size.width - WidgetDimensions::scaled.hsep_normal : right, y + (BaseSettingEntry::line_height - GetCharacterHeight(FS_NORMAL)) / 2, this->title, TC_ORANGE); } /** Construct settings tree */ diff --git a/src/settingentry_gui.h b/src/settingentry_gui.h index 66c017b99f147..e23d54e8bf657 100644 --- a/src/settingentry_gui.h +++ b/src/settingentry_gui.h @@ -14,9 +14,6 @@ #include "settings_internal.h" #include "stringfilter_type.h" -extern Dimension _setting_circle_size; -extern int SETTING_HEIGHT; - /** * Flags for #SettingEntry * @note The #SEF_BUTTONS_MASK matches expectations of the formal parameter 'state' of #DrawArrowButtons @@ -86,6 +83,9 @@ struct BaseSettingEntry { virtual uint Draw(GameSettings *settings_ptr, int left, int right, int y, uint first_row, uint max_row, BaseSettingEntry *selected, uint cur_row = 0, uint parent_last = 0) const; + static inline Dimension circle_size; ///< Dimension of the circle +/- icon. + static inline int line_height; ///< Height of a single setting. + protected: virtual void DrawSetting(GameSettings *settings_ptr, int left, int right, int y, bool highlight) const = 0; }; diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 034a5da24b965..af466bf40bdf5 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -84,8 +84,6 @@ static const uint32_t _autosave_dropdown_to_minutes[] = { 120, }; -Dimension _setting_circle_size; ///< Dimension of the circle +/- icon. This is here as not all users are within the class of the settings window. - /** * Get index of the current screen resolution. * @return Index of the current screen resolution if it is a known resolution, _resolutions.size() otherwise. @@ -363,8 +361,6 @@ std::unique_ptr MakeNWidgetSocialPlugins() return std::make_unique(); } -int SETTING_HEIGHT = 11; ///< Height of a single setting in the tree view in pixels - static const StringID _game_settings_restrict_dropdown[] = { STR_CONFIG_SETTING_RESTRICT_BASIC, // RM_BASIC STR_CONFIG_SETTING_RESTRICT_ADVANCED, // RM_ADVANCED @@ -453,7 +449,9 @@ struct GameOptionsWindow : Window { void OnInit() override { - _setting_circle_size = maxdim(GetSpriteSize(SPR_CIRCLE_FOLDED), GetSpriteSize(SPR_CIRCLE_UNFOLDED)); + BaseSettingEntry::circle_size = maxdim(GetSpriteSize(SPR_CIRCLE_FOLDED), GetSpriteSize(SPR_CIRCLE_UNFOLDED)); + BaseSettingEntry::line_height = std::max({static_cast(BaseSettingEntry::circle_size.height), SETTING_BUTTON_HEIGHT, GetCharacterHeight(FS_NORMAL)}) + WidgetDimensions::scaled.vsep_normal; + this->gui_scale = _gui_scale; } @@ -709,7 +707,7 @@ struct GameOptionsWindow : Window { case WID_GO_OPTIONSPANEL: { Rect tr = r.Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect); - tr.top += this->warn_lines * SETTING_HEIGHT; + tr.top += this->warn_lines * BaseSettingEntry::line_height; uint last_row = this->vscroll->GetPosition() + this->vscroll->GetCapacity() - this->warn_lines; int next_row = GetSettingsTree().Draw(settings_ptr, tr.left, tr.right, tr.top, this->vscroll->GetPosition(), last_row, this->last_clicked); @@ -858,7 +856,7 @@ struct GameOptionsWindow : Window { } case WID_GO_OPTIONSPANEL: - fill.height = resize.height = SETTING_HEIGHT = std::max({(int)_setting_circle_size.height, SETTING_BUTTON_HEIGHT, GetCharacterHeight(FS_NORMAL)}) + WidgetDimensions::scaled.vsep_normal; + fill.height = resize.height = BaseSettingEntry::line_height; resize.width = 1; size.height = 8 * resize.height + WidgetDimensions::scaled.framerect.Vertical(); @@ -1271,7 +1269,7 @@ struct GameOptionsWindow : Window { Rect wi_rect; wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x); wi_rect.right = wi_rect.left + SETTING_BUTTON_WIDTH - 1; - wi_rect.top = pt.y - rel_y + (SETTING_HEIGHT - SETTING_BUTTON_HEIGHT) / 2; + wi_rect.top = pt.y - rel_y + (BaseSettingEntry::line_height - SETTING_BUTTON_HEIGHT) / 2; wi_rect.bottom = wi_rect.top + SETTING_BUTTON_HEIGHT - 1; /* For dropdowns we also have to check the y position thoroughly, the mouse may not above the just opening dropdown */ From a7b06fc9f5111078dd326390cb5111f09ade7b53 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 21 Sep 2025 14:57:53 +0100 Subject: [PATCH 010/137] Codechange: Don't use Point for non-2D coordinate. (#14645) `HandleScrollbarHittest` returns min and max coordinates, not x and y. Also avoid referring to the min and max coordinates as top and bottom, as these functions are used for both vertical and horizontal scrollbars. --- src/widget.cpp | 75 ++++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 42 deletions(-) diff --git a/src/widget.cpp b/src/widget.cpp index 138ce18264c80..0c5977d174327 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -139,57 +139,48 @@ static inline Point GetAlignedPosition(const Rect &r, const Dimension &d, String /** * Compute the vertical position of the draggable part of scrollbar - * @param sb Scrollbar list data - * @param top Top position of the scrollbar (top position of the up-button) - * @param bottom Bottom position of the scrollbar (bottom position of the down-button) + * @param sb Scrollbar list data + * @param mi Minimum coordinate of the scroll bar. + * @param ma Maximum coordinate of the scroll bar. * @param horizontal Whether the scrollbar is horizontal or not - * @return A Point, with x containing the top coordinate of the draggable part, and - * y containing the bottom coordinate of the draggable part + * @return A pair, with first containing the minimum coordinate of the draggable part, and + * second containing the maximum coordinate of the draggable part */ -static Point HandleScrollbarHittest(const Scrollbar *sb, int top, int bottom, bool horizontal) +static std::pair HandleScrollbarHittest(const Scrollbar *sb, int mi, int ma, bool horizontal) { /* Base for reversion */ - int rev_base = top + bottom; - int button_size; - if (horizontal) { - button_size = NWidgetScrollbar::GetHorizontalDimension().width; - } else { - button_size = NWidgetScrollbar::GetVerticalDimension().height; - } - top += button_size; // top points to just below the up-button - bottom -= button_size; // bottom points to just before the down-button + int rev_base = mi + ma; + int button_size = horizontal ? NWidgetScrollbar::GetHorizontalDimension().width : NWidgetScrollbar::GetVerticalDimension().height; + + mi += button_size; // now points to just after the up/left-button + ma -= button_size; // now points to just before the down/right-button int count = sb->GetCount(); int cap = sb->GetCapacity(); if (count > cap) { - int height = bottom + 1 - top; + int height = ma + 1 - mi; int slider_height = std::max(button_size, cap * height / count); height -= slider_height; - top += height * sb->GetPosition() / (count - cap); - bottom = top + slider_height - 1; + mi += height * sb->GetPosition() / (count - cap); + ma = mi + slider_height - 1; } - Point pt; - if (horizontal && _current_text_dir == TD_RTL) { - pt.x = rev_base - bottom; - pt.y = rev_base - top; - } else { - pt.x = top; - pt.y = bottom; - } - return pt; + /* Reverse coordinates for RTL. */ + if (horizontal && _current_text_dir == TD_RTL) return {rev_base - ma, rev_base - mi}; + + return {mi, ma}; } /** * Compute new position of the scrollbar after a click and updates the window flags. - * @param w Window on which a scroll was performed. - * @param sb Scrollbar - * @param mi Minimum coordinate of the scroll bar. - * @param ma Maximum coordinate of the scroll bar. - * @param x The X coordinate of the mouse click. - * @param y The Y coordinate of the mouse click. + * @param w Window on which a scroll was performed. + * @param sb Scrollbar + * @param x The X coordinate of the mouse click. + * @param y The Y coordinate of the mouse click. + * @param mi Minimum coordinate of the scroll bar. + * @param ma Maximum coordinate of the scroll bar. */ static void ScrollbarClickPositioning(Window *w, NWidgetScrollbar *sb, int x, int y, int mi, int ma) { @@ -224,15 +215,15 @@ static void ScrollbarClickPositioning(Window *w, NWidgetScrollbar *sb, int x, in } w->mouse_capture_widget = sb->GetIndex(); } else { - Point pt = HandleScrollbarHittest(sb, mi, ma, sb->type == NWID_HSCROLLBAR); + auto [start, end] = HandleScrollbarHittest(sb, mi, ma, sb->type == NWID_HSCROLLBAR); - if (pos < pt.x) { + if (pos < start) { changed = sb->UpdatePosition(rtl ? 1 : -1, Scrollbar::SS_BIG); - } else if (pos > pt.y) { + } else if (pos > end) { changed = sb->UpdatePosition(rtl ? -1 : 1, Scrollbar::SS_BIG); } else { - _scrollbar_start_pos = pt.x - mi - button_size; - _scrollbar_size = ma - mi - button_size * 2 - (pt.y - pt.x); + _scrollbar_start_pos = start - mi - button_size; + _scrollbar_size = ma - mi - button_size * 2 - (end - start); w->mouse_capture_widget = sb->GetIndex(); _cursorpos_drag_start = _cursor.pos; } @@ -534,8 +525,8 @@ static inline void DrawVerticalScrollbar(const Rect &r, Colours colour, bool up_ GfxFillRect(right - bl, r.top + height, right - 1, r.bottom - height, c1); GfxFillRect(right, r.top + height, right + br - 1, r.bottom - height, c2); - Point pt = HandleScrollbarHittest(scrollbar, r.top, r.bottom, false); - DrawFrameRect(r.left, pt.x, r.right, pt.y, colour, bar_dragged ? FrameFlag::Lowered : FrameFlags{}); + auto [top, bottom] = HandleScrollbarHittest(scrollbar, r.top, r.bottom, false); + DrawFrameRect(r.left, top, r.right, bottom, colour, bar_dragged ? FrameFlag::Lowered : FrameFlags{}); } /** @@ -574,8 +565,8 @@ static inline void DrawHorizontalScrollbar(const Rect &r, Colours colour, bool l GfxFillRect(r.left + width, bottom, r.right - width, bottom + bb - 1, c2); /* draw actual scrollbar */ - Point pt = HandleScrollbarHittest(scrollbar, r.left, r.right, true); - DrawFrameRect(pt.x, r.top, pt.y, r.bottom, colour, bar_dragged ? FrameFlag::Lowered : FrameFlags{}); + auto [left, right] = HandleScrollbarHittest(scrollbar, r.left, r.right, true); + DrawFrameRect(left, r.top, right, r.bottom, colour, bar_dragged ? FrameFlag::Lowered : FrameFlags{}); } /** From 71eba489bc891d0cb277f09ddc9542ebd865cb14 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 21 Sep 2025 20:26:06 +0100 Subject: [PATCH 011/137] Codechange: Deduplicate DrawButtonDropdown. (#14646) Use Rect methods to position components. --- src/widget.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/widget.cpp b/src/widget.cpp index 0c5977d174327..f917901802fea 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -745,21 +745,17 @@ void DrawCaption(const Rect &r, Colours colour, Owner owner, TextColour text_col */ static inline void DrawButtonDropdown(const Rect &r, Colours colour, bool clicked_button, bool clicked_dropdown, std::string_view str, StringAlignment align) { - int dd_width = NWidgetLeaf::dropdown_dimension.width; + bool rtl = _current_text_dir == TD_RTL; - if (_current_text_dir == TD_LTR) { - DrawFrameRect(r.left, r.top, r.right - dd_width, r.bottom, colour, clicked_button ? FrameFlag::Lowered : FrameFlags{}); - DrawImageButtons(r.WithWidth(dd_width, true), WWT_DROPDOWN, colour, clicked_dropdown, SPR_ARROW_DOWN, SA_CENTER); - if (!str.empty()) { - DrawString(r.left + WidgetDimensions::scaled.dropdowntext.left, r.right - dd_width - WidgetDimensions::scaled.dropdowntext.right, CentreBounds(r.top, r.bottom, GetCharacterHeight(FS_NORMAL)), str, TC_BLACK, align); - } - } else { - DrawFrameRect(r.left + dd_width, r.top, r.right, r.bottom, colour, clicked_button ? FrameFlag::Lowered : FrameFlags{}); - DrawImageButtons(r.WithWidth(dd_width, false), WWT_DROPDOWN, colour, clicked_dropdown, SPR_ARROW_DOWN, SA_CENTER); - if (!str.empty()) { - DrawString(r.left + dd_width + WidgetDimensions::scaled.dropdowntext.left, r.right - WidgetDimensions::scaled.dropdowntext.right, CentreBounds(r.top, r.bottom, GetCharacterHeight(FS_NORMAL)), str, TC_BLACK, align); - } + Rect text = r.Indent(NWidgetLeaf::dropdown_dimension.width, !rtl); + DrawFrameRect(text, colour, clicked_button ? FrameFlag::Lowered : FrameFlags{}); + if (!str.empty()) { + text = text.CentreTo(text.Width(), GetCharacterHeight(FS_NORMAL)).Shrink(WidgetDimensions::scaled.dropdowntext, RectPadding::zero); + DrawString(text, str, TC_BLACK, align); } + + Rect button = r.WithWidth(NWidgetLeaf::dropdown_dimension.width, !rtl); + DrawImageButtons(button, WWT_DROPDOWN, colour, clicked_dropdown, SPR_ARROW_DOWN, SA_CENTER); } /** From 1278f62e2e4a65929fb340b7cfae7141efe37b2d Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 21 Sep 2025 20:30:59 +0100 Subject: [PATCH 012/137] Codechange: Call shorter variant of DrawFrameRect and GfxFillRect. (#14647) Pass rect instead of breaking it up when possible. --- src/bootstrap_gui.cpp | 4 ++-- src/widget.cpp | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/bootstrap_gui.cpp b/src/bootstrap_gui.cpp index 80620f303b4ae..ae04d45b7bd67 100644 --- a/src/bootstrap_gui.cpp +++ b/src/bootstrap_gui.cpp @@ -60,8 +60,8 @@ class BootstrapBackground : public Window { void DrawWidget(const Rect &r, WidgetID) const override { - GfxFillRect(r.left, r.top, r.right, r.bottom, PixelColour{4}, FILLRECT_OPAQUE); - GfxFillRect(r.left, r.top, r.right, r.bottom, PixelColour{0}, FILLRECT_CHECKER); + GfxFillRect(r, PixelColour{4}, FILLRECT_OPAQUE); + GfxFillRect(r, PixelColour{0}, FILLRECT_CHECKER); } }; diff --git a/src/widget.cpp b/src/widget.cpp index f917901802fea..317727e57d235 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -344,7 +344,7 @@ void DrawSpriteIgnorePadding(SpriteID img, PaletteID pal, const Rect &r, StringA static inline void DrawImageButtons(const Rect &r, WidgetType type, Colours colour, bool clicked, SpriteID img, StringAlignment align) { assert(img != 0); - DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, (clicked) ? FrameFlag::Lowered : FrameFlags{}); + DrawFrameRect(r, colour, clicked ? FrameFlag::Lowered : FrameFlags{}); if ((type & WWT_MASK) == WWT_IMGBTN_2 && clicked) img++; // Show different image when clicked for #WWT_IMGBTN_2. DrawSpriteIgnorePadding(img, PAL_NONE, r, align); @@ -363,7 +363,7 @@ static inline void DrawImageButtons(const Rect &r, WidgetType type, Colours colo */ static inline void DrawImageTextButtons(const Rect &r, Colours colour, bool clicked, SpriteID img, TextColour text_colour, const std::string &text, StringAlignment align, FontSize fs) { - DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, (clicked) ? FrameFlag::Lowered : FrameFlags{}); + DrawFrameRect(r, colour, clicked ? FrameFlag::Lowered : FrameFlags{}); bool rtl = _current_text_dir == TD_RTL; int image_width = img != 0 ? GetScaledSpriteSize(img).width : 0; @@ -426,7 +426,7 @@ static inline void DrawText(const Rect &r, TextColour colour, std::string_view s */ static inline void DrawInset(const Rect &r, Colours colour, TextColour text_colour, std::string_view str, StringAlignment align, FontSize fs) { - DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, {FrameFlag::Lowered, FrameFlag::Darkened}); + DrawFrameRect(r, colour, {FrameFlag::Lowered, FrameFlag::Darkened}); if (!str.empty()) DrawString(r.Shrink(WidgetDimensions::scaled.inset), str, text_colour, align, false, fs); } @@ -442,7 +442,7 @@ static inline void DrawInset(const Rect &r, Colours colour, TextColour text_colo */ static inline void DrawMatrix(const Rect &r, Colours colour, bool clicked, uint32_t num_columns, uint32_t num_rows, uint resize_x, uint resize_y) { - DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, (clicked) ? FrameFlag::Lowered : FrameFlags{}); + DrawFrameRect(r, colour, clicked ? FrameFlag::Lowered : FrameFlags{}); int column_width; // Width of a single column in the matrix. if (num_columns == 0) { @@ -680,7 +680,7 @@ static inline void DrawDebugBox(const Rect &r, Colours colour, bool clicked) static inline void DrawResizeBox(const Rect &r, Colours colour, bool at_left, bool clicked, bool bevel) { if (bevel) { - DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, (clicked) ? FrameFlag::Lowered : FrameFlags{}); + DrawFrameRect(r, colour, clicked ? FrameFlag::Lowered : FrameFlags{}); } else if (clicked) { GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), GetColourGradient(colour, SHADE_LIGHTER)); } @@ -694,7 +694,7 @@ static inline void DrawResizeBox(const Rect &r, Colours colour, bool at_left, bo */ static inline void DrawCloseBox(const Rect &r, Colours colour) { - if (colour != COLOUR_WHITE) DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, {}); + if (colour != COLOUR_WHITE) DrawFrameRect(r, colour, {}); Point offset; Dimension d = GetSpriteSize(SPR_CLOSEBOX, &offset); d.width -= offset.x; @@ -2307,7 +2307,7 @@ void NWidgetBackground::Draw(const Window *w) switch (this->type) { case WWT_PANEL: - DrawFrameRect(r.left, r.top, r.right, r.bottom, this->colour, this->IsLowered() ? FrameFlag::Lowered : FrameFlags{}); + DrawFrameRect(r, this->colour, this->IsLowered() ? FrameFlag::Lowered : FrameFlags{}); break; case WWT_FRAME: @@ -2986,7 +2986,7 @@ void NWidgetLeaf::Draw(const Window *w) break; case WWT_PUSHBTN: - DrawFrameRect(r.left, r.top, r.right, r.bottom, this->colour, (clicked) ? FrameFlag::Lowered : FrameFlags{}); + DrawFrameRect(r, this->colour, clicked ? FrameFlag::Lowered : FrameFlags{}); break; case WWT_BOOLBTN: { @@ -3006,7 +3006,7 @@ void NWidgetLeaf::Draw(const Window *w) case WWT_TEXTBTN: case WWT_PUSHTXTBTN: case WWT_TEXTBTN_2: - DrawFrameRect(r.left, r.top, r.right, r.bottom, this->colour, (clicked) ? FrameFlag::Lowered : FrameFlags{}); + DrawFrameRect(r, this->colour, clicked ? FrameFlag::Lowered : FrameFlags{}); DrawLabel(r, this->text_colour, GetStringForWidget(w, this, (type & WWT_MASK) == WWT_TEXTBTN_2 && clicked), this->align, this->text_size); break; From 1229a498b716d35095d02376e97457c851367a8b Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 21 Sep 2025 22:47:04 +0100 Subject: [PATCH 013/137] Codechange: Add constant for INVALID_WIDGET. (#14649) Replaces direct use of -1, making it easier to find. --- src/airport_gui.cpp | 2 +- src/depot_gui.cpp | 8 ++++---- src/dock_gui.cpp | 4 ++-- src/rail_gui.cpp | 2 +- src/road_gui.cpp | 2 +- src/terraform_gui.cpp | 4 ++-- src/widget.cpp | 8 ++++---- src/widget_type.h | 20 ++++++++++---------- src/widgets/airport_widget.h | 2 -- src/widgets/dock_widget.h | 2 -- src/widgets/game_widget.h | 2 +- src/widgets/rail_widget.h | 2 -- src/widgets/road_widget.h | 2 -- src/widgets/script_widget.h | 2 +- src/widgets/settings_widget.h | 2 +- src/widgets/terraform_widget.h | 4 ---- src/window.cpp | 6 +++--- src/window_gui.h | 2 +- src/window_type.h | 3 +++ 19 files changed, 35 insertions(+), 44 deletions(-) diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index 48b34bbd00692..51ba9ffd66d44 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -84,7 +84,7 @@ static void PlaceAirport(TileIndex tile) /** Airport build toolbar window handler. */ struct BuildAirToolbarWindow : Window { - int last_user_action = INVALID_WID_AT; // Last started user action. + WidgetID last_user_action = INVALID_WIDGET; // Last started user action. BuildAirToolbarWindow(WindowDesc &desc, WindowNumber window_number) : Window(desc) { diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index d4ad2baa9ce43..8306ec8b30bf9 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -260,7 +260,7 @@ struct DepotWindow : Window { VehicleType type = VEH_INVALID; bool generate_list = true; bool check_unitnumber_digits = true; - WidgetID hovered_widget = -1; ///< Index of the widget being hovered during drag/drop. -1 if no drag is in progress. + WidgetID hovered_widget = INVALID_WIDGET; ///< Index of the widget being hovered during drag/drop. \c INVALID_WIDGET if no drag is in progress. VehicleList vehicle_list{}; VehicleList wagon_list{}; uint unitnumber_digits = 2; @@ -1001,10 +1001,10 @@ struct DepotWindow : Window { this->vehicle_over = VehicleID::Invalid(); this->SetWidgetDirty(WID_D_MATRIX); - if (this->hovered_widget != -1) { + if (this->hovered_widget != INVALID_WIDGET) { this->SetWidgetLoweredState(this->hovered_widget, false); this->SetWidgetDirty(this->hovered_widget); - this->hovered_widget = -1; + this->hovered_widget = INVALID_WIDGET; } } @@ -1116,7 +1116,7 @@ struct DepotWindow : Window { this->SetDirty(); break; } - this->hovered_widget = -1; + this->hovered_widget = INVALID_WIDGET; _cursor.vehchain = false; } diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index 4e44efc3d992a..e79a501c681e8 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -98,7 +98,7 @@ static TileIndex GetOtherAqueductEnd(TileIndex tile_from, TileIndex *tile_to = n /** Toolbar window for constructing water infrastructure. */ struct BuildDocksToolbarWindow : Window { - DockToolbarWidgets last_clicked_widget = WID_DT_INVALID; ///< Contains the last widget that has been clicked on this toolbar. + WidgetID last_clicked_widget = INVALID_WIDGET; ///< Contains the last widget that has been clicked on this toolbar. BuildDocksToolbarWindow(WindowDesc &desc, WindowNumber window_number) : Window(desc) { @@ -189,7 +189,7 @@ struct BuildDocksToolbarWindow : Window { default: return; } - this->last_clicked_widget = (DockToolbarWidgets)widget; + this->last_clicked_widget = widget; } void OnPlaceObject([[maybe_unused]] Point pt, TileIndex tile) override diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index feaccc2a7d129..7b9a503577e06 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -438,7 +438,7 @@ static void HandleAutoSignalPlacement() /** Rail toolbar management class. */ struct BuildRailToolbarWindow : Window { RailType railtype = INVALID_RAILTYPE; ///< Rail type to build. - int last_user_action = INVALID_WID_RAT; ///< Last started user action. + WidgetID last_user_action = INVALID_WIDGET; ///< Last started user action. BuildRailToolbarWindow(WindowDesc &desc, RailType railtype) : Window(desc), railtype(railtype) { diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 46c59c82c914d..e3d29dbd3850a 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -344,7 +344,7 @@ static bool RoadToolbar_CtrlChanged(Window *w) /** Road toolbar window handler. */ struct BuildRoadToolbarWindow : Window { RoadType roadtype = INVALID_ROADTYPE; ///< Road type to build. - int last_started_action = INVALID_WID_ROT; ///< Last started user action. + WidgetID last_started_action = INVALID_WIDGET; ///< Last started user action. BuildRoadToolbarWindow(WindowDesc &desc, WindowNumber window_number) : Window(desc), roadtype(_cur_roadtype) { diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index ab81c7004f8e0..7c0f388a603ba 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -155,7 +155,7 @@ void PlaceProc_DemolishArea(TileIndex tile) /** Terra form toolbar managing class. */ struct TerraformToolbarWindow : Window { - int last_user_action = INVALID_WID_TT; ///< Last started user action. + WidgetID last_user_action = INVALID_WIDGET; ///< Last started user action. TerraformToolbarWindow(WindowDesc &desc, WindowNumber window_number) : Window(desc) { @@ -529,7 +529,7 @@ static void ResetLandscapeConfirmationCallback(Window *, bool confirmed) /** Landscape generation window handler in the scenario editor. */ struct ScenarioEditorLandscapeGenerationWindow : Window { - int last_user_action = INVALID_WID_ETT; ///< Last started user action. + WidgetID last_user_action = INVALID_WIDGET; ///< Last started user action. ScenarioEditorLandscapeGenerationWindow(WindowDesc &desc, WindowNumber window_number) : Window(desc) { diff --git a/src/widget.cpp b/src/widget.cpp index 317727e57d235..1248d0fb16ca0 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -269,12 +269,12 @@ void ScrollbarClickHandler(Window *w, NWidgetCore *nw, int x, int y) * @param *w Window to look inside * @param x The Window client X coordinate * @param y The Window client y coordinate - * @return A widget index, or -1 if no widget was found. + * @return A widget index, or \c INVALID_WIDGET if no widget was found. */ WidgetID GetWidgetFromPos(const Window *w, int x, int y) { NWidgetCore *nw = w->nested_root->GetWidgetFromPos(x, y); - return (nw != nullptr) ? nw->GetIndex() : -1; + return (nw != nullptr) ? nw->GetIndex() : INVALID_WIDGET; } /** @@ -1885,7 +1885,7 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, int x, int y, uint g * @param width Horizontal size of the spacer widget. * @param height Vertical size of the spacer widget. */ -NWidgetSpacer::NWidgetSpacer(int width, int height) : NWidgetResizeBase(NWID_SPACER, -1, 0, 0) +NWidgetSpacer::NWidgetSpacer(int width, int height) : NWidgetResizeBase(NWID_SPACER, INVALID_WIDGET, 0, 0) { this->SetMinimalSize(width, height); this->SetResize(0, 0); @@ -3408,7 +3408,7 @@ std::unique_ptr MakeWindowNWidgetTree(std::span if (hor_cont != nullptr && hor_cont->GetWidgetOfType(WWT_CAPTION) != nullptr && hor_cont->GetWidgetOfType(WWT_SHADEBOX) != nullptr) { /* If the first widget has a title bar and a shade box, silently add a shade selection widget in the tree. */ - auto shade_stack = std::make_unique(-1); + auto shade_stack = std::make_unique(INVALID_WIDGET); *shade_select = shade_stack.get(); /* Load the remaining parts into the shade stack. */ shade_stack->Add(MakeNWidgets({nwid_begin, nwid_end}, std::make_unique())); diff --git a/src/widget_type.h b/src/widget_type.h index 063c6b4d6dfac..072d56365e85c 100644 --- a/src/widget_type.h +++ b/src/widget_type.h @@ -136,7 +136,7 @@ using WidgetLookup = std::map; */ class NWidgetBase { public: - NWidgetBase(WidgetType tp, WidgetID index = -1) : type(tp), index(index) {} + NWidgetBase(WidgetType tp, WidgetID index = INVALID_WIDGET) : type(tp), index(index) {} virtual ~NWidgetBase() = default; void ApplyAspectRatio(); @@ -249,7 +249,7 @@ class NWidgetBase { NWidgetBase *parent = nullptr; ///< Parent widget of this widget, automatically filled in when added to container. protected: - const WidgetID index = -1; ///< Index of the nested widget (\c -1 means 'not used'). + const WidgetID index = INVALID_WIDGET; ///< Index of the nested widget (\c INVALID_WIDGET means 'not used'). inline void StoreSizePosition(SizingType sizing, int x, int y, uint given_width, uint given_height); }; @@ -402,7 +402,7 @@ class NWidgetCore : public NWidgetResizeBase { protected: WidgetData widget_data{}; ///< Data of the widget. @see Widget::data StringID tool_tip{}; ///< Tooltip of the widget. @see Widget::tool_tips - WidgetID scrollbar_index = -1; ///< Index of an attached scrollbar. + WidgetID scrollbar_index = INVALID_WIDGET; ///< Index of an attached scrollbar. TextColour highlight_colour{}; ///< Colour of highlight. TextColour text_colour{}; ///< Colour of text within widget. FontSize text_size = FS_NORMAL; ///< Size of text within widget. @@ -471,7 +471,7 @@ inline bool NWidgetCore::IsDisabled() const */ class NWidgetContainer : public NWidgetBase { public: - NWidgetContainer(WidgetType tp, WidgetID index = -1) : NWidgetBase(tp, index) {} + NWidgetContainer(WidgetType tp, WidgetID index = INVALID_WIDGET) : NWidgetBase(tp, index) {} void AdjustPaddingForZoom() override; void Add(std::unique_ptr &&wid); @@ -537,7 +537,7 @@ using NWidContainerFlags = EnumBitSet; /** Container with pre/inter/post child space. */ class NWidgetPIPContainer : public NWidgetContainer { public: - NWidgetPIPContainer(WidgetType tp, NWidContainerFlags flags = {}, WidgetID index = -1) : NWidgetContainer(tp, index), flags(flags) {} + NWidgetPIPContainer(WidgetType tp, NWidContainerFlags flags = {}, WidgetID index = INVALID_WIDGET) : NWidgetContainer(tp, index), flags(flags) {} void AdjustPaddingForZoom() override; void SetPIP(uint8_t pip_pre, uint8_t pip_inter, uint8_t pip_post); @@ -565,7 +565,7 @@ class NWidgetPIPContainer : public NWidgetContainer { */ class NWidgetHorizontal : public NWidgetPIPContainer { public: - NWidgetHorizontal(NWidContainerFlags flags = {}, WidgetID index = -1, WidgetType type = NWID_HORIZONTAL) : NWidgetPIPContainer(type, flags, index) {} + NWidgetHorizontal(NWidContainerFlags flags = {}, WidgetID index = INVALID_WIDGET, WidgetType type = NWID_HORIZONTAL) : NWidgetPIPContainer(type, flags, index) {} void SetupSmallestSize(Window *w) override; void AssignSizePosition(SizingType sizing, int x, int y, uint given_width, uint given_height, bool rtl) override; @@ -577,7 +577,7 @@ class NWidgetHorizontal : public NWidgetPIPContainer { */ class NWidgetHorizontalLTR : public NWidgetHorizontal { public: - NWidgetHorizontalLTR(NWidContainerFlags flags = {}, WidgetID index = -1) : NWidgetHorizontal(flags, index, NWID_HORIZONTAL_LTR) {} + NWidgetHorizontalLTR(NWidContainerFlags flags = {}, WidgetID index = INVALID_WIDGET) : NWidgetHorizontal(flags, index, NWID_HORIZONTAL_LTR) {} void AssignSizePosition(SizingType sizing, int x, int y, uint given_width, uint given_height, bool rtl) override; }; @@ -588,7 +588,7 @@ class NWidgetHorizontalLTR : public NWidgetHorizontal { */ class NWidgetVertical : public NWidgetPIPContainer { public: - NWidgetVertical(NWidContainerFlags flags = {}, WidgetID index = -1) : NWidgetPIPContainer(NWID_VERTICAL, flags, index) {} + NWidgetVertical(NWidContainerFlags flags = {}, WidgetID index = INVALID_WIDGET) : NWidgetPIPContainer(NWID_VERTICAL, flags, index) {} void SetupSmallestSize(Window *w) override; void AssignSizePosition(SizingType sizing, int x, int y, uint given_width, uint given_height, bool rtl) override; @@ -1412,7 +1412,7 @@ constexpr NWidgetPart SetAspect(float ratio, AspectFlags flags = AspectFlag::Res * Child widgets must have a index bigger than the parent index. * @ingroup NestedWidgetParts */ -constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx = -1) +constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx = INVALID_WIDGET) { return NWidgetPart{tp, NWidgetPartWidget{col, idx}}; } @@ -1423,7 +1423,7 @@ constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx = -1) * @param cont_flags Flags for the containers (#NWID_HORIZONTAL and #NWID_VERTICAL). * @ingroup NestedWidgetParts */ -constexpr NWidgetPart NWidget(WidgetType tp, NWidContainerFlags cont_flags = {}, WidgetID idx = -1) +constexpr NWidgetPart NWidget(WidgetType tp, NWidContainerFlags cont_flags = {}, WidgetID idx = INVALID_WIDGET) { return NWidgetPart{tp, NWidgetPartContainer{cont_flags, idx}}; } diff --git a/src/widgets/airport_widget.h b/src/widgets/airport_widget.h index 4e16f4596ea9d..af2261b149eb9 100644 --- a/src/widgets/airport_widget.h +++ b/src/widgets/airport_widget.h @@ -14,8 +14,6 @@ enum AirportToolbarWidgets : WidgetID { WID_AT_AIRPORT, ///< Build airport button. WID_AT_DEMOLISH, ///< Demolish button. - - INVALID_WID_AT = -1, }; /** Widgets of the #BuildAirportWindow class. */ diff --git a/src/widgets/dock_widget.h b/src/widgets/dock_widget.h index 0a1f480eb6187..85cabe94d688c 100644 --- a/src/widgets/dock_widget.h +++ b/src/widgets/dock_widget.h @@ -27,8 +27,6 @@ enum DockToolbarWidgets : WidgetID { WID_DT_BUOY, ///< Build buoy button. WID_DT_RIVER, ///< Build river button (in scenario editor). WID_DT_BUILD_AQUEDUCT, ///< Build aqueduct button. - - WID_DT_INVALID, ///< Used to initialize a variable. }; #endif /* WIDGETS_DOCK_WIDGET_H */ diff --git a/src/widgets/game_widget.h b/src/widgets/game_widget.h index 5b105d9934c37..4ad5973fa6db2 100644 --- a/src/widgets/game_widget.h +++ b/src/widgets/game_widget.h @@ -24,7 +24,7 @@ enum GSConfigWidgets : WidgetID { WID_GSC_CONTENT_DOWNLOAD = WID_GSC_TEXTFILE + TFT_CONTENT_END, ///< Download content button. WID_GSC_RESET, ///< Reset button. - WID_GSC_SETTING_DROPDOWN = -1, ///< Dynamically created dropdown for changing setting value. + WID_GSC_SETTING_DROPDOWN = INVALID_WIDGET, ///< Dynamically created dropdown for changing setting value. }; #endif /* WIDGETS_GS_WIDGET_H */ diff --git a/src/widgets/rail_widget.h b/src/widgets/rail_widget.h index f290d801622e3..02da916e7265e 100644 --- a/src/widgets/rail_widget.h +++ b/src/widgets/rail_widget.h @@ -28,8 +28,6 @@ enum RailToolbarWidgets : WidgetID { WID_RAT_BUILD_TUNNEL, ///< Build a tunnel. WID_RAT_REMOVE, ///< Bulldozer to remove rail. WID_RAT_CONVERT_RAIL, ///< Convert other rail to this type. - - INVALID_WID_RAT = -1, }; /** Widgets of the #BuildRailStationWindow class. */ diff --git a/src/widgets/road_widget.h b/src/widgets/road_widget.h index 679545728a2e8..23de63ed533d4 100644 --- a/src/widgets/road_widget.h +++ b/src/widgets/road_widget.h @@ -27,8 +27,6 @@ enum RoadToolbarWidgets : WidgetID { WID_ROT_BUILD_TUNNEL, ///< Build tunnel. WID_ROT_REMOVE, ///< Remove road. WID_ROT_CONVERT_ROAD, ///< Convert road. - - INVALID_WID_ROT = -1, }; /** Widgets of the #BuildRoadDepotWindow class. */ diff --git a/src/widgets/script_widget.h b/src/widgets/script_widget.h index 7b9905dcc98fe..71fecc5badb98 100644 --- a/src/widgets/script_widget.h +++ b/src/widgets/script_widget.h @@ -28,7 +28,7 @@ enum ScriptSettingsWidgets : WidgetID { WID_SCRS_SCROLLBAR, ///< Scrollbar to scroll through all settings. WID_SCRS_RESET, ///< Reset button. - WID_SCRS_SETTING_DROPDOWN = -1, ///< Dynamically created dropdown for changing setting value. + WID_SCRS_SETTING_DROPDOWN = INVALID_WIDGET, ///< Dynamically created dropdown for changing setting value. }; /** Widgets of the #ScriptDebugWindow class. */ diff --git a/src/widgets/settings_widget.h b/src/widgets/settings_widget.h index 858f17f104c34..d7a3c069d87ee 100644 --- a/src/widgets/settings_widget.h +++ b/src/widgets/settings_widget.h @@ -85,7 +85,7 @@ enum GameOptionsWidgets : WidgetID { WID_GO_RESTRICT_DROPDOWN, ///< The drop down box to restrict the list of settings WID_GO_TYPE_DROPDOWN, ///< The drop down box to choose client/game/company/all settings - WID_GO_SETTING_DROPDOWN = -1, ///< Dynamically created dropdown for changing setting value. + WID_GO_SETTING_DROPDOWN = INVALID_WIDGET, ///< Dynamically created dropdown for changing setting value. }; /** Widgets of the #CustomCurrencyWindow class. */ diff --git a/src/widgets/terraform_widget.h b/src/widgets/terraform_widget.h index 6b5796f9b5490..d4ce57eabd292 100644 --- a/src/widgets/terraform_widget.h +++ b/src/widgets/terraform_widget.h @@ -22,8 +22,6 @@ enum TerraformToolbarWidgets : WidgetID { WID_TT_PLANT_TREES, ///< Plant trees button (note: opens separate window, no place-push-button). WID_TT_PLACE_SIGN, ///< Place sign button. WID_TT_PLACE_OBJECT, ///< Place object button. - - INVALID_WID_TT = -1, }; /** Widgets of the #ScenarioEditorLandscapeGenerationWindow class. */ @@ -44,8 +42,6 @@ enum EditorTerraformToolbarWidgets : WidgetID { WID_ETT_DECREASE_SIZE, ///< Downwards arrow button to decrease terraforming size. WID_ETT_NEW_SCENARIO, ///< Button for generating a new scenario. WID_ETT_RESET_LANDSCAPE, ///< Button for removing all company-owned property. - - INVALID_WID_ETT = -1, }; #endif /* WIDGETS_TERRAFORM_WIDGET_H */ diff --git a/src/window.cpp b/src/window.cpp index e40641f24ed78..419612e0bf9e8 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1809,7 +1809,7 @@ void Window::InitNested(WindowNumber window_number) * Empty constructor, initialization has been moved to #InitNested() called from the constructor of the derived class. * @param desc The description of the window. */ -Window::Window(WindowDesc &desc) : window_desc(desc), scale(_gui_scale), mouse_capture_widget(-1) +Window::Window(WindowDesc &desc) : window_desc(desc), scale(_gui_scale), mouse_capture_widget(INVALID_WIDGET) { this->z_position = _z_windows.insert(_z_windows.end(), this); } @@ -1891,7 +1891,7 @@ static void DecreaseWindowCounters() NWidgetScrollbar *sb = static_cast(nwid); if (sb->disp_flags.Any({NWidgetDisplayFlag::ScrollbarUp, NWidgetDisplayFlag::ScrollbarDown})) { sb->disp_flags.Reset({NWidgetDisplayFlag::ScrollbarUp, NWidgetDisplayFlag::ScrollbarDown}); - w->mouse_capture_widget = -1; + w->mouse_capture_widget = INVALID_WIDGET; sb->SetDirty(w); } } @@ -2390,7 +2390,7 @@ static EventState HandleActiveWidget() /* Abort if no button is clicked any more. */ if (!_left_button_down) { w->SetWidgetDirty(w->mouse_capture_widget); - w->mouse_capture_widget = -1; + w->mouse_capture_widget = INVALID_WIDGET; return ES_HANDLED; } diff --git a/src/window_gui.h b/src/window_gui.h index edfbf94da8f37..c6f1909ef29e9 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -323,7 +323,7 @@ struct Window { NWidgetStacked *shade_select = nullptr; ///< Selection widget (#NWID_SELECTION) to use for shading the window. If \c nullptr, window cannot shade. Dimension unshaded_size{}; ///< Last known unshaded size (only valid while shaded). - WidgetID mouse_capture_widget = -1; ///< ID of current mouse capture widget (e.g. dragged scrollbar). -1 if no widget has mouse capture. + WidgetID mouse_capture_widget = INVALID_WIDGET; ///< ID of current mouse capture widget (e.g. dragged scrollbar). \c INVALID_WIDGET if no widget has mouse capture. Window *parent = nullptr; ///< Parent window. WindowList::iterator z_position{}; diff --git a/src/window_type.h b/src/window_type.h index 585ad7a83f676..880738be1dc51 100644 --- a/src/window_type.h +++ b/src/window_type.h @@ -19,6 +19,9 @@ */ using WidgetID = int; +/** An invalid widget index. */ +static constexpr WidgetID INVALID_WIDGET = -1; + /** %Window numbers. */ enum WindowNumberEnum : uint8_t { WN_GAME_OPTIONS_AI = 0, ///< AI settings. From 853dc245a03cc289a3b899d585ac47d75a9ee67f Mon Sep 17 00:00:00 2001 From: translators Date: Mon, 22 Sep 2025 04:38:24 +0000 Subject: [PATCH 014/137] Update: Translations from eints chinese (simplified): 4 changes by WenSimEHRP catalan: 5 changes by J0anJosep --- src/lang/catalan.txt | 6 +++++- src/lang/simplified_chinese.txt | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index c715650802757..11352fd53f0ca 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -3349,6 +3349,8 @@ STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtre: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Sobreescriu fitxer STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Esteu segur que voleu sobreescriure el fitxer? +STR_SAVELOAD_DELETE_TITLE :{WHITE}Esborra el fitxer +STR_SAVELOAD_DELETE_WARNING :{YELLOW}Esteu segur que voleu esborrar aquest fitxer? STR_SAVELOAD_DIRECTORY :{STRING} (carpeta) STR_SAVELOAD_PARENT_DIRECTORY :{STRING} (carpeta superior) @@ -4126,7 +4128,7 @@ STR_GROUP_LIVERY_TOOLTIP :{BLACK}Canvia l STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Clica per protegir aquest grup de l'autosubstitució global. Ctrl + clic també protegeix els subgrups. STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}Esborrar grup -STR_GROUP_DELETE_QUERY_TEXT :{WHITE}Estàs segur que vols esborrar aquest grup i tots els seus subgrups? +STR_GROUP_DELETE_QUERY_TEXT :{WHITE}Esteu segur que voleu esborrar aquest grup i tots els seus subgrups? STR_GROUP_ADD_SHARED_VEHICLE :Afegeix vehicles compartits STR_GROUP_REMOVE_ALL_VEHICLES :Treu tots els vehicles @@ -4184,6 +4186,7 @@ STR_PURCHASE_INFO_ALL_BUT :Qualsevol excep STR_PURCHASE_INFO_MAX_TE :{BLACK}Esforç de tracció màxim: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Abast: {GOLD}{COMMA} cel·les STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Tipus d'aeronau: {GOLD}{STRING} +STR_PURCHASE_INFO_RAILTYPES :{BLACK}Tipus de rail: {GOLD}{STRING} ###length 3 STR_CARGO_TYPE_FILTER_ALL :Tots els tipus de càrrega @@ -4367,6 +4370,7 @@ STR_ENGINE_PREVIEW_RUNCOST_YEAR :Cost d'utilitza STR_ENGINE_PREVIEW_RUNCOST_PERIOD :Cost d'utilització: {CURRENCY_LONG}/període STR_ENGINE_PREVIEW_CAPACITY :Capacitat: {CARGO_LONG} STR_ENGINE_PREVIEW_CAPACITY_2 :Capacitat: {CARGO_LONG}, {CARGO_LONG} +STR_ENGINE_PREVIEW_RAILTYPES :Tipus de rail: {STRING} # Autoreplace window STR_REPLACE_VEHICLES_WHITE :{WHITE}Substitueix {STRING} - {STRING} diff --git a/src/lang/simplified_chinese.txt b/src/lang/simplified_chinese.txt index 58a02c6686935..136c41ea47e03 100644 --- a/src/lang/simplified_chinese.txt +++ b/src/lang/simplified_chinese.txt @@ -3348,6 +3348,8 @@ STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF STR_SAVELOAD_FILTER_TITLE :{BLACK}搜索: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}覆盖文件 STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}确定覆盖已有文件吗? +STR_SAVELOAD_DELETE_TITLE :{WHITE}删除文件 +STR_SAVELOAD_DELETE_WARNING :{YELLOW}确定删除文件吗? STR_SAVELOAD_DIRECTORY :{STRING}(目录) STR_SAVELOAD_PARENT_DIRECTORY :{STRING}(上级目录) @@ -4183,6 +4185,7 @@ STR_PURCHASE_INFO_ALL_BUT :所有货物( STR_PURCHASE_INFO_MAX_TE :{BLACK}最大牵引力:{GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}航行距离:{GOLD}{COMMA} 格 STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}飞机类型:{GOLD}{STRING} +STR_PURCHASE_INFO_RAILTYPES :{BLACK}轨道类型:{GOLD}{STRING} ###length 3 STR_CARGO_TYPE_FILTER_ALL :所有货物类型 @@ -4366,6 +4369,7 @@ STR_ENGINE_PREVIEW_RUNCOST_YEAR :运行费用: STR_ENGINE_PREVIEW_RUNCOST_PERIOD :运行费用:{CURRENCY_LONG}/周期 STR_ENGINE_PREVIEW_CAPACITY :容量:{CARGO_LONG} STR_ENGINE_PREVIEW_CAPACITY_2 :容量:{CARGO_LONG}、{CARGO_LONG} +STR_ENGINE_PREVIEW_RAILTYPES :轨道类型:{STRING} # Autoreplace window STR_REPLACE_VEHICLES_WHITE :{WHITE}更新 {STRING} - {STRING} From 43e65d04e4060343cd081f3384158883ff39b8c5 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Mon, 22 Sep 2025 07:18:08 +0100 Subject: [PATCH 015/137] Codefix: Incorrect naming and location of widget names for build docks window. (#14650) --- src/dock_gui.cpp | 33 ++++++++++++--------------------- src/widgets/dock_widget.h | 9 +++++++++ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index e79a501c681e8..e247c01396f9f 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -412,21 +412,12 @@ Window *ShowBuildDocksScenToolbar() return AllocateWindowDescFront(_build_docks_scen_toolbar_desc, TRANSPORT_WATER); } -/** Widget numbers of the build-dock GUI. */ -enum BuildDockStationWidgets { - BDSW_BACKGROUND, ///< Background panel. - BDSW_LT_OFF, ///< 'Off' button of coverage high light. - BDSW_LT_ON, ///< 'On' button of coverage high light. - BDSW_INFO, ///< 'Coverage highlight' label. - BDSW_ACCEPTANCE, ///< Acceptance info. -}; - struct BuildDocksStationWindow : public PickerWindowBase { public: BuildDocksStationWindow(WindowDesc &desc, Window *parent) : PickerWindowBase(desc, parent) { this->InitNested(TRANSPORT_WATER); - this->LowerWidget(_settings_client.gui.station_show_coverage + BDSW_LT_OFF); + this->LowerWidget(_settings_client.gui.station_show_coverage + WID_BDSW_LT_OFF); } void Close([[maybe_unused]] int data = 0) override @@ -448,7 +439,7 @@ struct BuildDocksStationWindow : public PickerWindowBase { } /* strings such as 'Size' and 'Coverage Area' */ - Rect r = this->GetWidget(BDSW_ACCEPTANCE)->GetCurrentRect(); + Rect r = this->GetWidget(WID_BDSW_ACCEPTANCE)->GetCurrentRect(); const int bottom = r.bottom; r.bottom = INT_MAX; // Allow overflow as we want to know the required height. r.top = DrawStationCoverageAreaText(r, SCT_ALL, rad, false) + WidgetDimensions::scaled.vsep_normal; @@ -464,11 +455,11 @@ struct BuildDocksStationWindow : public PickerWindowBase { void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override { switch (widget) { - case BDSW_LT_OFF: - case BDSW_LT_ON: - this->RaiseWidget(_settings_client.gui.station_show_coverage + BDSW_LT_OFF); - _settings_client.gui.station_show_coverage = (widget != BDSW_LT_OFF); - this->LowerWidget(_settings_client.gui.station_show_coverage + BDSW_LT_OFF); + case WID_BDSW_LT_OFF: + case WID_BDSW_LT_ON: + this->RaiseWidget(_settings_client.gui.station_show_coverage + WID_BDSW_LT_OFF); + _settings_client.gui.station_show_coverage = (widget != WID_BDSW_LT_OFF); + this->LowerWidget(_settings_client.gui.station_show_coverage + WID_BDSW_LT_OFF); SndClickBeep(); this->SetDirty(); SetViewportCatchmentStation(nullptr, true); @@ -492,16 +483,16 @@ static constexpr NWidgetPart _nested_build_dock_station_widgets[] = { NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_STATION_BUILD_DOCK_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), EndContainer(), - NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BDSW_BACKGROUND), + NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BDSW_BACKGROUND), NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0), SetPadding(WidgetDimensions::unscaled.picker), NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_picker, 0), - NWidget(WWT_LABEL, INVALID_COLOUR, BDSW_INFO), SetStringTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE), SetFill(1, 0), + NWidget(WWT_LABEL, INVALID_COLOUR, WID_BDSW_INFO), SetStringTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE), SetFill(1, 0), NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), SetPIP(14, 0, 14), - NWidget(WWT_TEXTBTN, COLOUR_GREY, BDSW_LT_OFF), SetMinimalSize(60, 12), SetFill(1, 0), SetStringTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP), - NWidget(WWT_TEXTBTN, COLOUR_GREY, BDSW_LT_ON), SetMinimalSize(60, 12), SetFill(1, 0), SetStringTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BDSW_LT_OFF), SetMinimalSize(60, 12), SetFill(1, 0), SetStringTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BDSW_LT_ON), SetMinimalSize(60, 12), SetFill(1, 0), SetStringTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP), EndContainer(), EndContainer(), - NWidget(WWT_EMPTY, INVALID_COLOUR, BDSW_ACCEPTANCE), SetResize(0, 1), SetMinimalTextLines(2, WidgetDimensions::unscaled.vsep_normal), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BDSW_ACCEPTANCE), SetResize(0, 1), SetMinimalTextLines(2, WidgetDimensions::unscaled.vsep_normal), EndContainer(), EndContainer(), }; diff --git a/src/widgets/dock_widget.h b/src/widgets/dock_widget.h index 85cabe94d688c..2877b1ac02a19 100644 --- a/src/widgets/dock_widget.h +++ b/src/widgets/dock_widget.h @@ -17,6 +17,15 @@ enum BuildDockDepotWidgets : WidgetID { WID_BDD_Y, ///< Y-direction button. }; +/** Widgets of the #BuildDocksStationWindow window. */ +enum BuildDocksStationWidgets : WidgetID { + WID_BDSW_BACKGROUND, ///< Background panel. + WID_BDSW_LT_OFF, ///< 'Off' button of coverage high light. + WID_BDSW_LT_ON, ///< 'On' button of coverage high light. + WID_BDSW_INFO, ///< 'Coverage highlight' label. + WID_BDSW_ACCEPTANCE, ///< Acceptance info. +}; + /** Widgets of the #BuildDocksToolbarWindow class. */ enum DockToolbarWidgets : WidgetID { WID_DT_CANAL, ///< Build canal button. From 2b164111a9d376614db3dff39608c7a74814505e Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Mon, 22 Sep 2025 20:04:55 +0100 Subject: [PATCH 016/137] Codechange: Use EnumBitSet for TownFlags. (#14651) --- src/newgrf_town.cpp | 2 +- src/saveload/afterload.cpp | 2 +- src/town.h | 26 +++++++++++--------------- src/town_cmd.cpp | 34 +++++++++++++++++----------------- src/town_gui.cpp | 2 +- 5 files changed, 31 insertions(+), 35 deletions(-) diff --git a/src/newgrf_town.cpp b/src/newgrf_town.cpp index eb581d93280fa..370769cde668f 100644 --- a/src/newgrf_town.cpp +++ b/src/newgrf_town.cpp @@ -63,7 +63,7 @@ static uint16_t TownHistoryHelper(const Town *t, CargoLabel label, uint period, case 0x82: return ClampTo(this->t->cache.population); case 0x83: return GB(ClampTo(this->t->cache.population), 8, 8); case 0x8A: return this->t->grow_counter / Ticks::TOWN_GROWTH_TICKS; - case 0x92: return this->t->flags; // In original game, 0x92 and 0x93 are really one word. Since flags is a byte, this is to adjust + case 0x92: return this->t->flags.base(); // In original game, 0x92 and 0x93 are one word. case 0x93: return 0; case 0x94: return ClampTo(this->t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)]); case 0x95: return GB(ClampTo(this->t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)]), 8, 8); diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 908249e53319b..4a901a3b39346 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -3120,7 +3120,7 @@ bool AfterLoadGame() /* Convert towns growth_rate and grow_counter to ticks */ for (Town *t : Town::Iterate()) { /* 0x8000 = TOWN_GROWTH_RATE_CUSTOM previously */ - if (t->growth_rate & 0x8000) SetBit(t->flags, TOWN_CUSTOM_GROWTH); + if (t->growth_rate & 0x8000) t->flags.Set(TownFlag::CustomGrowth); if (t->growth_rate != TOWN_GROWTH_RATE_NONE) { t->growth_rate = TownTicksToGameTicks(t->growth_rate & ~0x8000); } diff --git a/src/town.h b/src/town.h index a8786767c9319..38ba6c1798f3f 100644 --- a/src/town.h +++ b/src/town.h @@ -37,6 +37,16 @@ static const uint16_t MAX_TOWN_GROWTH_TICKS = 930; ///< Max amount of original t typedef Pool TownPool; extern TownPool _town_pool; +/** Flags controlling various town behaviours. */ +enum class TownFlag : uint8_t { + IsGrowing = 0, ///< Conditions for town growth are met. Grow according to Town::growth_rate. + HasChurch = 1, ///< There can be only one church by town. + HasStadium = 2, ///< There can be only one stadium by town. + CustomGrowth = 3, ///< Growth rate is controlled by GS. +}; + +using TownFlags = EnumBitSet; + /** Data structure with cached data of towns. */ struct TownCache { uint32_t num_houses = 0; ///< Amount of houses @@ -62,7 +72,7 @@ struct Town : TownPool::PoolItem<&_town_pool> { std::string name{}; ///< Custom town name. If empty, the town was not renamed and uses the generated name. mutable std::string cached_name{}; ///< NOSAVE: Cache of the resolved name of the town, if not using a custom town name - uint8_t flags = 0; ///< See #TownFlags. + TownFlags flags{}; ///< See #TownFlags. uint16_t noise_reached = 0; ///< level of noise that all the airports are generating @@ -224,20 +234,6 @@ enum TownDirectoryInvalidateWindowData { TDIWD_FORCE_RESORT, }; -/** - * This enum is used in conjunction with town->flags. - * IT simply states what bit is used for. - * It is pretty unrealistic (IMHO) to only have one church/stadium - * per town, NO MATTER the population of it. - * And there are 5 more bits available on flags... - */ -enum TownFlags { - TOWN_IS_GROWING = 0, ///< Conditions for town growth are met. Grow according to Town::growth_rate. - TOWN_HAS_CHURCH = 1, ///< There can be only one church by town. - TOWN_HAS_STADIUM = 2, ///< There can be only one stadium by town. - TOWN_CUSTOM_GROWTH = 3, ///< Growth rate is controlled by GS. -}; - CommandCost CheckforTownRating(DoCommandFlags flags, Town *t, TownRatingCheckType type); diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index bcb03da78e8bb..abf59d90bc01b 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -666,7 +666,7 @@ static void TileLoop_Town(TileIndex tile) Backup cur_company(_current_company, OWNER_TOWN); if (hs->building_flags.Any(BUILDING_HAS_1_TILE) && - HasBit(t->flags, TOWN_IS_GROWING) && + t->flags.Test(TownFlag::IsGrowing) && CanDeleteHouse(tile) && GetHouseAge(tile) >= hs->minimum_life && --t->time_until_rebuild == 0) { @@ -917,7 +917,7 @@ static bool GrowTown(Town *t, TownExpandModes modes); */ static void TownTickHandler(Town *t) { - if (HasBit(t->flags, TOWN_IS_GROWING)) { + if (t->flags.Test(TownFlag::IsGrowing)) { TownExpandModes modes{TownExpandMode::Buildings}; if (_settings_game.economy.allow_town_roads) modes.Set(TownExpandMode::Roads); int i = (int)t->grow_counter - 1; @@ -2046,7 +2046,7 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSi t->cache.num_houses = 0; t->time_until_rebuild = 10; UpdateTownRadius(t); - t->flags = 0; + t->flags.Reset(); t->cache.population = 0; InitializeBuildingCounts(t); /* Spread growth across ticks so even if there are many @@ -2867,15 +2867,15 @@ static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes) if (TimerGameCalendar::year < hs->min_year || TimerGameCalendar::year > hs->max_year) continue; /* Special houses that there can be only one of. */ - uint oneof = 0; + TownFlags oneof{}; if (hs->building_flags.Test(BuildingFlag::IsChurch)) { - SetBit(oneof, TOWN_HAS_CHURCH); + oneof.Set(TownFlag::HasChurch); } else if (hs->building_flags.Test(BuildingFlag::IsStadium)) { - SetBit(oneof, TOWN_HAS_STADIUM); + oneof.Set(TownFlag::HasStadium); } - if (t->flags & oneof) continue; + if (t->flags.Any(oneof)) continue; /* Make sure there is no slope? */ bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped); @@ -2899,7 +2899,7 @@ static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes) } /* Special houses that there can be only one of. */ - t->flags |= oneof; + t->flags.Set(oneof); BuildTownHouse(t, tile, hs, house, random_bits, false, hs->extra_flags.Test(HouseExtraFlag::BuildingIsProtected)); @@ -3034,9 +3034,9 @@ void ClearTownHouse(Town *t, TileIndex tile) /* Clear flags for houses that only may exist once/town. */ if (hs->building_flags.Test(BuildingFlag::IsChurch)) { - ClrBit(t->flags, TOWN_HAS_CHURCH); + t->flags.Reset(TownFlag::HasChurch); } else if (hs->building_flags.Test(BuildingFlag::IsStadium)) { - ClrBit(t->flags, TOWN_HAS_STADIUM); + t->flags.Reset(TownFlag::HasStadium); } /* Do the actual clearing of tiles */ @@ -3168,7 +3168,7 @@ CommandCost CmdTownGrowthRate(DoCommandFlags flags, TownID town_id, uint16_t gro if (flags.Test(DoCommandFlag::Execute)) { if (growth_rate == 0) { /* Just clear the flag, UpdateTownGrowth will determine a proper growth rate */ - ClrBit(t->flags, TOWN_CUSTOM_GROWTH); + t->flags.Reset(TownFlag::CustomGrowth); } else { uint old_rate = t->growth_rate; if (t->grow_counter >= old_rate) { @@ -3179,7 +3179,7 @@ CommandCost CmdTownGrowthRate(DoCommandFlags flags, TownID town_id, uint16_t gro t->grow_counter = t->grow_counter * growth_rate / old_rate; } t->growth_rate = growth_rate; - SetBit(t->flags, TOWN_CUSTOM_GROWTH); + t->flags.Set(TownFlag::CustomGrowth); } UpdateTownGrowth(t); InvalidateWindowData(WC_TOWN_VIEW, town_id); @@ -3829,7 +3829,7 @@ static uint GetNormalGrowthRate(Town *t) */ static void UpdateTownGrowthRate(Town *t) { - if (HasBit(t->flags, TOWN_CUSTOM_GROWTH)) return; + if (t->flags.Test(TownFlag::CustomGrowth)) return; uint old_rate = t->growth_rate; t->growth_rate = GetNormalGrowthRate(t); UpdateTownGrowCounter(t, old_rate); @@ -3844,7 +3844,7 @@ static void UpdateTownGrowth(Town *t) { UpdateTownGrowthRate(t); - ClrBit(t->flags, TOWN_IS_GROWING); + t->flags.Reset(TownFlag::IsGrowing); SetWindowDirty(WC_TOWN_VIEW, t->index); if (_settings_game.economy.town_growth_rate == 0 && t->fund_buildings_months == 0) return; @@ -3866,15 +3866,15 @@ static void UpdateTownGrowth(Town *t) } } - if (HasBit(t->flags, TOWN_CUSTOM_GROWTH)) { - if (t->growth_rate != TOWN_GROWTH_RATE_NONE) SetBit(t->flags, TOWN_IS_GROWING); + if (t->flags.Test(TownFlag::CustomGrowth)) { + if (t->growth_rate != TOWN_GROWTH_RATE_NONE) t->flags.Set(TownFlag::IsGrowing); SetWindowDirty(WC_TOWN_VIEW, t->index); return; } if (t->fund_buildings_months == 0 && CountActiveStations(t) == 0 && !Chance16(1, 12)) return; - SetBit(t->flags, TOWN_IS_GROWING); + t->flags.Set(TownFlag::IsGrowing); SetWindowDirty(WC_TOWN_VIEW, t->index); } diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 845617634467f..2659adc38a3e1 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -453,7 +453,7 @@ struct TownViewWindow : Window { tr.top += GetCharacterHeight(FS_NORMAL); } - if (HasBit(this->town->flags, TOWN_IS_GROWING)) { + if (this->town->flags.Test(TownFlag::IsGrowing)) { DrawString(tr, GetString(this->town->fund_buildings_months == 0 ? STR_TOWN_VIEW_TOWN_GROWS_EVERY : STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED, RoundDivSU(this->town->growth_rate + 1, Ticks::DAY_TICKS))); tr.top += GetCharacterHeight(FS_NORMAL); } else { From 484ed1008af9f1a8907ed8e34957eee298c113f7 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 23 Sep 2025 22:00:34 +0100 Subject: [PATCH 017/137] Codechange: Make TownRatingCheckType an enum class. (#14652) --- src/road_cmd.cpp | 4 ++-- src/town.h | 8 ++++---- src/town_cmd.cpp | 6 +++--- src/tunnelbridge_cmd.cpp | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index f1aff80870837..eea76ef76a99f 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -282,7 +282,7 @@ CommandCost CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, R /* check if you're allowed to remove the street owned by a town * removal allowance depends on difficulty setting */ - CommandCost ret = CheckforTownRating(flags, t, ROAD_REMOVE); + CommandCost ret = CheckforTownRating(flags, t, TownRatingCheckType::RoadRemove); if (ret.Failed()) return ret; /* Get a bitmask of which neighbouring roads has a tile */ @@ -2492,7 +2492,7 @@ CommandCost CmdConvertRoad(DoCommandFlags flags, TileIndex tile, TileIndex area_ * acceptance of destructive actions. */ if (owner == OWNER_TOWN) { Town *t = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority); - CommandCost ret = CheckforTownRating({}, t, tt == MP_TUNNELBRIDGE ? TUNNELBRIDGE_REMOVE : ROAD_REMOVE); + CommandCost ret = CheckforTownRating({}, t, tt == MP_TUNNELBRIDGE ? TownRatingCheckType::TunnelBridgeRemove : TownRatingCheckType::RoadRemove); if (ret.Failed()) { error = std::move(ret); continue; diff --git a/src/town.h b/src/town.h index 38ba6c1798f3f..5151e3c87cfe6 100644 --- a/src/town.h +++ b/src/town.h @@ -221,10 +221,10 @@ enum TownCouncilAttitudes { * Action types that a company must ask permission for to a town authority. * @see CheckforTownRating */ -enum TownRatingCheckType { - ROAD_REMOVE = 0, ///< Removal of a road owned by the town. - TUNNELBRIDGE_REMOVE = 1, ///< Removal of a tunnel or bridge owned by the town. - TOWN_RATING_CHECK_TYPE_COUNT, ///< Number of town checking action types. +enum class TownRatingCheckType : uint8_t { + RoadRemove, ///< Removal of a road owned by the town. + TunnelBridgeRemove, ///< Removal of a tunnel or bridge owned by the town. + End, }; /** Special values for town list window for the data parameter of #InvalidateWindowData. */ diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index abf59d90bc01b..dea412c6982d2 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -4050,8 +4050,8 @@ CommandCost CheckforTownRating(DoCommandFlags flags, Town *t, TownRatingCheckTyp } /* minimum rating needed to be allowed to remove stuff */ - static const int needed_rating[][TOWN_RATING_CHECK_TYPE_COUNT] = { - /* ROAD_REMOVE, TUNNELBRIDGE_REMOVE */ + static const int needed_rating[][to_underlying(TownRatingCheckType::End)] = { + /* RoadRemove, TunnelBridgeRemove */ { RATING_ROAD_NEEDED_LENIENT, RATING_TUNNEL_BRIDGE_NEEDED_LENIENT}, // Lenient { RATING_ROAD_NEEDED_NEUTRAL, RATING_TUNNEL_BRIDGE_NEEDED_NEUTRAL}, // Neutral { RATING_ROAD_NEEDED_HOSTILE, RATING_TUNNEL_BRIDGE_NEEDED_HOSTILE}, // Hostile @@ -4062,7 +4062,7 @@ CommandCost CheckforTownRating(DoCommandFlags flags, Town *t, TownRatingCheckTyp * owned by a town no removal if rating is lower than ... depends now on * difficulty setting. Minimum town rating selected by difficulty level */ - int needed = needed_rating[_settings_game.difficulty.town_council_tolerance][type]; + int needed = needed_rating[_settings_game.difficulty.town_council_tolerance][to_underlying(type)]; if (GetRating(t) < needed) { return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index); diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 2d03900ea16b1..6180c1ffb596e 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -866,7 +866,7 @@ static CommandCost DoClearTunnel(TileIndex tile, DoCommandFlags flags) /* Check if you are allowed to remove the tunnel owned by a town * Removal depends on difficulty settings */ - ret = CheckforTownRating(flags, t, TUNNELBRIDGE_REMOVE); + ret = CheckforTownRating(flags, t, TownRatingCheckType::TunnelBridgeRemove); if (ret.Failed()) return ret; } @@ -947,7 +947,7 @@ static CommandCost DoClearBridge(TileIndex tile, DoCommandFlags flags) /* Check if you are allowed to remove the bridge owned by a town * Removal depends on difficulty settings */ - ret = CheckforTownRating(flags, t, TUNNELBRIDGE_REMOVE); + ret = CheckforTownRating(flags, t, TownRatingCheckType::TunnelBridgeRemove); if (ret.Failed()) return ret; } From 6ad7c1c40adf3e0c6a6efb55dabc7030958e4b2f Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 23 Sep 2025 23:15:21 +0100 Subject: [PATCH 018/137] Fix d85f4b3ebf: Incorrect row height in network server list. (#14653) --- src/network/network_gui.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 0aefc12bd9636..61975b476ab12 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -476,12 +476,12 @@ class NetworkGameWindow : public Window { { switch (widget) { case WID_NG_MATRIX: - fill.height = resize.height = std::max(GetSpriteSize(SPR_BLOT).height, (uint)GetCharacterHeight(FS_NORMAL)) + padding.height; + fill.height = resize.height = std::max(this->blot.height, GetCharacterHeight(FS_NORMAL)) + padding.height; size.height = 12 * resize.height; break; case WID_NG_LASTJOINED: - size.height = std::max(GetSpriteSize(SPR_BLOT).height, (uint)GetCharacterHeight(FS_NORMAL)) + WidgetDimensions::scaled.matrix.Vertical(); + size.height = std::max(this->blot.height, GetCharacterHeight(FS_NORMAL)) + WidgetDimensions::scaled.matrix.Vertical(); break; case WID_NG_LASTJOINED_SPACER: From bec4e71d53fe6bd638aeecfd97f0732dc6287270 Mon Sep 17 00:00:00 2001 From: translators Date: Wed, 24 Sep 2025 04:37:55 +0000 Subject: [PATCH 019/137] Update: Translations from eints hungarian: 5 changes by vargaviktor --- src/lang/hungarian.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lang/hungarian.txt b/src/lang/hungarian.txt index 69da51259765a..5d137f1e27246 100644 --- a/src/lang/hungarian.txt +++ b/src/lang/hungarian.txt @@ -3412,6 +3412,8 @@ STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: STR_SAVELOAD_FILTER_TITLE :{BLACK}Szűrő: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Fájl felülírása STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Biztos vagy benne, hogy felülírod a létező fájlt? +STR_SAVELOAD_DELETE_TITLE :{WHITE}Fájl törlése +STR_SAVELOAD_DELETE_WARNING :{YELLOW}Biztosan törölni akarod ezt a fájlt? STR_SAVELOAD_DIRECTORY :{STRING} (Könyvtár) STR_SAVELOAD_PARENT_DIRECTORY :{STRING} (Szülőkönyvtár) @@ -4247,6 +4249,7 @@ STR_PURCHASE_INFO_ALL_BUT :Mindenre, kivé STR_PURCHASE_INFO_MAX_TE :{BLACK}Maximális vonóerő: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Hatótávolság: {GOLD}{COMMA} mező STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Típus: {GOLD}{STRING} +STR_PURCHASE_INFO_RAILTYPES :{BLACK}Sín típusok: {GOLD}{STRING} ###length 3 STR_CARGO_TYPE_FILTER_ALL :Minden rakománytípus @@ -4430,6 +4433,7 @@ STR_ENGINE_PREVIEW_RUNCOST_YEAR :Üzemeletetés: STR_ENGINE_PREVIEW_RUNCOST_PERIOD :Üzemeltetés: {CURRENCY_LONG}/időszak STR_ENGINE_PREVIEW_CAPACITY :Kapacitás: {CARGO_LONG} STR_ENGINE_PREVIEW_CAPACITY_2 :Kapacitás: {CARGO_LONG}, {CARGO_LONG} +STR_ENGINE_PREVIEW_RAILTYPES :Sín típusok: {STRING} # Autoreplace window STR_REPLACE_VEHICLES_WHITE :{WHITE}{STRING} lecserélése - {STRING} @@ -5332,6 +5336,7 @@ STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}A híd t STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}A híd túl alacsony a bójához STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}A híd túl alacsony a vasúti ellenőrzőponthoz STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}BA híd túl alacsony az útponthoz +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}A híd túl alacsony a zároláshoz # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Nem áshatsz ide alagutat... From ecb761fc6934c6dc5c521ef8b5461dde40b62674 Mon Sep 17 00:00:00 2001 From: Kuhnovic <68320206+Kuhnovic@users.noreply.github.com> Date: Wed, 24 Sep 2025 21:34:01 +0200 Subject: [PATCH 020/137] Codechange: Simplified structure of yapf_ship_regions. (#14640) --- src/pathfinder/yapf/yapf_ship_regions.cpp | 207 ++++++++-------------- 1 file changed, 75 insertions(+), 132 deletions(-) diff --git a/src/pathfinder/yapf/yapf_ship_regions.cpp b/src/pathfinder/yapf/yapf_ship_regions.cpp index 202936a7bdbd7..089fde6073d84 100644 --- a/src/pathfinder/yapf/yapf_ship_regions.cpp +++ b/src/pathfinder/yapf/yapf_ship_regions.cpp @@ -16,12 +16,15 @@ #include "../../safeguards.h" -constexpr int DIRECT_NEIGHBOUR_COST = 100; -constexpr int NODES_PER_REGION = 4; -constexpr int MAX_NUMBER_OF_NODES = 65536; +static constexpr int DIRECT_NEIGHBOUR_COST = 100; +static constexpr int NODES_PER_REGION = 4; +static constexpr int MAX_NUMBER_OF_NODES = 65536; + +static constexpr int NODE_LIST_HASH_BITS_OPEN = 12; +static constexpr int NODE_LIST_HASH_BITS_CLOSED = 12; /** Yapf Node Key that represents a single patch of interconnected water within a water region. */ -struct CYapfRegionPatchNodeKey { +struct WaterRegionPatchKey { WaterRegionPatchDesc water_region_patch; inline void Set(const WaterRegionPatchDesc &water_region_patch) @@ -30,19 +33,18 @@ struct CYapfRegionPatchNodeKey { } inline int CalcHash() const { return CalculateWaterRegionPatchHash(this->water_region_patch); } - inline bool operator==(const CYapfRegionPatchNodeKey &other) const { return this->CalcHash() == other.CalcHash(); } + inline bool operator==(const WaterRegionPatchKey &other) const { return this->CalcHash() == other.CalcHash(); } }; -inline uint ManhattanDistance(const CYapfRegionPatchNodeKey &a, const CYapfRegionPatchNodeKey &b) +inline uint ManhattanDistance(const WaterRegionPatchKey &a, const WaterRegionPatchKey &b) { return (std::abs(a.water_region_patch.x - b.water_region_patch.x) + std::abs(a.water_region_patch.y - b.water_region_patch.y)) * DIRECT_NEIGHBOUR_COST; } /** Yapf Node for water regions. */ -template -struct CYapfRegionNodeT : CYapfNodeT> { - typedef Tkey_ Key; - typedef CYapfRegionNodeT Node; +struct WaterRegionNode : CYapfNodeT { + using Key = WaterRegionPatchKey; + using Node = WaterRegionNode; inline void Set(Node *parent, const WaterRegionPatchDesc &water_region_patch) { @@ -71,21 +73,43 @@ struct CYapfRegionNodeT : CYapfNodeT> { } }; -/** YAPF origin for water regions. */ -template -class CYapfOriginRegionT { -public: - typedef typename Types::Tpf Tpf; ///< The pathfinder class (derived from THIS class). - typedef typename Types::NodeList::Item Node; ///< This will be our node type. - typedef typename Node::Key Key; ///< Key to hash tables. +using WaterRegionNodeList = NodeList; + +/* We don't need a follower but YAPF requires one. */ +struct DummyFollower : public CFollowTrackWater {}; + +class YapfShipRegions; -protected: - inline Tpf &Yapf() { return *static_cast(this); } +/* Types struct required for YAPF internals. */ +struct WaterRegionTypes { + using Tpf = YapfShipRegions; + using TrackFollower = DummyFollower; + using NodeList = WaterRegionNodeList; + using VehicleType = Ship; +}; +/** Water region based YAPF implementation for ships. */ +class YapfShipRegions + : public CYapfBaseT + , public CYapfSegmentCostCacheNoneT +{ private: - std::vector origin_keys; + using Node = typename WaterRegionTypes::NodeList::Item; + + std::vector origin_keys; + WaterRegionPatchKey dest; + + inline YapfShipRegions &Yapf() + { + return *static_cast(this); + } public: + explicit YapfShipRegions(int max_nodes) + { + this->max_search_nodes = max_nodes; + } + void AddOrigin(const WaterRegionPatchDesc &water_region_patch) { if (water_region_patch.label == INVALID_WATER_REGION_PATCH) return; @@ -94,45 +118,52 @@ class CYapfOriginRegionT { bool HasOrigin(const WaterRegionPatchDesc &water_region_patch) { - return std::ranges::find(this->origin_keys, CYapfRegionPatchNodeKey{ water_region_patch }) != this->origin_keys.end(); + return std::ranges::find(this->origin_keys, WaterRegionPatchKey{ water_region_patch }) != this->origin_keys.end(); + } + + void SetDestination(const WaterRegionPatchDesc &water_region_patch) + { + this->dest.Set(water_region_patch); } void PfSetStartupNodes() { - for (const CYapfRegionPatchNodeKey &origin_key : this->origin_keys) { + for (const WaterRegionPatchKey &origin_key : this->origin_keys) { Node &node = Yapf().CreateNewNode(); node.Set(nullptr, origin_key); Yapf().AddStartupNode(node); } } -}; - -/** YAPF destination provider for water regions. */ -template -class CYapfDestinationRegionT { -public: - typedef typename Types::Tpf Tpf; ///< The pathfinder class (derived from THIS class). - typedef typename Types::NodeList::Item Node; ///< This will be our node type. - typedef typename Node::Key Key; ///< Key to hash tables. -protected: - Key dest; - -public: - void SetDestination(const WaterRegionPatchDesc &water_region_patch) + inline void PfFollowNode(Node &old_node) { - this->dest.Set(water_region_patch); + VisitWaterRegionPatchCallback visit_func = [&](const WaterRegionPatchDesc &water_region_patch) { + Node &node = Yapf().CreateNewNode(); + node.Set(&old_node, water_region_patch); + Yapf().AddNewNode(node, TrackFollower{}); + }; + VisitWaterRegionPatchNeighbours(old_node.key.water_region_patch, visit_func); } -protected: - Tpf &Yapf() { return *static_cast(this); } - -public: inline bool PfDetectDestination(Node &n) const { return n.key == this->dest; } + inline bool PfCalcCost(Node &n, const TrackFollower *) + { + n.cost = n.parent->cost + ManhattanDistance(n.key, n.parent->key); + + /* Incentivise zigzagging by adding a slight penalty when the search continues in the same direction. */ + Node *grandparent = n.parent->parent; + if (grandparent != nullptr) { + const DiagDirDiff dir_diff = DiagDirDifference(n.parent->GetDiagDirFromParent(), n.GetDiagDirFromParent()); + if (dir_diff != DIAGDIRDIFF_90LEFT && dir_diff != DIAGDIRDIFF_90RIGHT) n.cost += 1; + } + + return true; + } + inline bool PfCalcEstimate(Node &n) { if (this->PfDetectDestination(n)) { @@ -144,31 +175,6 @@ class CYapfDestinationRegionT { return true; } -}; - -/** YAPF node following for water region pathfinding. */ -template -class CYapfFollowRegionT { -public: - typedef typename Types::Tpf Tpf; ///< The pathfinder class (derived from THIS class). - typedef typename Types::TrackFollower TrackFollower; - typedef typename Types::NodeList::Item Node; ///< This will be our node type. - typedef typename Node::Key Key; ///< Key to hash tables. - -protected: - inline Tpf &Yapf() { return *static_cast(this); } - -public: - inline void PfFollowNode(Node &old_node) - { - VisitWaterRegionPatchCallback visit_func = [&](const WaterRegionPatchDesc &water_region_patch) - { - Node &node = Yapf().CreateNewNode(); - node.Set(&old_node, water_region_patch); - Yapf().AddNewNode(node, TrackFollower{}); - }; - VisitWaterRegionPatchNeighbours(old_node.key.water_region_patch, visit_func); - } inline char TransportTypeChar() const { return '^'; } @@ -178,7 +184,8 @@ class CYapfFollowRegionT { /* We reserve 4 nodes (patches) per water region. The vast majority of water regions have 1 or 2 regions so this should be a pretty * safe limit. We cap the limit at 65536 which is at a region size of 16x16 is equivalent to one node per region for a 4096x4096 map. */ - Tpf pf(std::min(static_cast(Map::Size() * NODES_PER_REGION) / WATER_REGION_NUMBER_OF_TILES, MAX_NUMBER_OF_NODES)); + const int node_limit = std::min(static_cast(Map::Size() * NODES_PER_REGION) / WATER_REGION_NUMBER_OF_TILES, MAX_NUMBER_OF_NODES); + YapfShipRegions pf(node_limit); pf.SetDestination(start_water_region_patch); if (v->current_order.IsType(OT_GOTO_STATION)) { @@ -215,70 +222,6 @@ class CYapfFollowRegionT { } }; -/** Cost Provider of YAPF for water regions. */ -template -class CYapfCostRegionT { -public: - typedef typename Types::Tpf Tpf; ///< The pathfinder class (derived from THIS class). - typedef typename Types::TrackFollower TrackFollower; - typedef typename Types::NodeList::Item Node; ///< This will be our node type. - typedef typename Node::Key Key; ///< Key to hash tables. - -protected: - /** To access inherited path finder. */ - Tpf &Yapf() { return *static_cast(this); } - -public: - /** - * Called by YAPF to calculate the cost from the origin to the given node. - * Calculates only the cost of given node, adds it to the parent node cost - * and stores the result into Node::cost member. - */ - inline bool PfCalcCost(Node &n, const TrackFollower *) - { - n.cost = n.parent->cost + ManhattanDistance(n.key, n.parent->key); - - /* Incentivise zigzagging by adding a slight penalty when the search continues in the same direction. */ - Node *grandparent = n.parent->parent; - if (grandparent != nullptr) { - const DiagDirDiff dir_diff = DiagDirDifference(n.parent->GetDiagDirFromParent(), n.GetDiagDirFromParent()); - if (dir_diff != DIAGDIRDIFF_90LEFT && dir_diff != DIAGDIRDIFF_90RIGHT) n.cost += 1; - } - - return true; - } -}; - -/* We don't need a follower but YAPF requires one. */ -struct DummyFollower : public CFollowTrackWater {}; - -/** - * Config struct of YAPF for route planning. - * Defines all 6 base YAPF modules as classes providing services for CYapfBaseT. - */ -template -struct CYapfRegion_TypesT { - typedef CYapfRegion_TypesT Types; ///< Shortcut for this struct type. - typedef Tpf_ Tpf; ///< Pathfinder type. - typedef DummyFollower TrackFollower; ///< Track follower helper class - typedef Tnode_list NodeList; - typedef Ship VehicleType; - - /** Pathfinder components (modules). */ - typedef CYapfBaseT PfBase; ///< Base pathfinder class. - typedef CYapfFollowRegionT PfFollow; ///< Node follower. - typedef CYapfOriginRegionT PfOrigin; ///< Origin provider. - typedef CYapfDestinationRegionT PfDestination; ///< Destination/distance provider. - typedef CYapfSegmentCostCacheNoneT PfCache; ///< Segment cost cache provider. - typedef CYapfCostRegionT PfCost; ///< Cost provider. -}; - -typedef NodeList, 12, 12> CRegionNodeListWater; - -struct CYapfRegionWater : CYapfT> { - explicit CYapfRegionWater(int max_nodes) { this->max_search_nodes = max_nodes; } -}; - /** * Finds a path at the water region level. Note that the starting region is always included if the path was found. * @param v The ship to find a path for. @@ -288,5 +231,5 @@ struct CYapfRegionWater : CYapfT YapfShipFindWaterRegionPath(const Ship *v, TileIndex start_tile, int max_returned_path_length) { - return CYapfRegionWater::FindWaterRegionPath(v, start_tile, max_returned_path_length); + return YapfShipRegions::FindWaterRegionPath(v, start_tile, max_returned_path_length); } From 42c9f84d74d198529fccb98d65270b12be7d0253 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Wed, 24 Sep 2025 22:44:41 +0100 Subject: [PATCH 021/137] Fix 3ac1a2f1e4: Game crash due to invalid vehicle type information. (#14628) Use std::variant instead of union for vehicle info. RailVehicleInfo is now non-POD so using in a union causes undefined behaviour. --- src/aircraft_cmd.cpp | 6 +- src/articulated_vehicles.cpp | 8 +- src/autoreplace_cmd.cpp | 8 +- src/autoreplace_gui.cpp | 2 +- src/build_vehicle_gui.cpp | 18 ++-- src/depot_gui.cpp | 2 +- src/elrail.cpp | 2 +- src/engine.cpp | 135 ++++++++++++++-------------- src/engine_base.h | 35 +++++--- src/engine_gui.cpp | 12 +-- src/engine_type.h | 34 +++++-- src/newgrf.cpp | 32 +++---- src/newgrf/newgrf_act0_aircraft.cpp | 2 +- src/newgrf/newgrf_act0_roadvehs.cpp | 2 +- src/newgrf/newgrf_act0_ships.cpp | 2 +- src/newgrf/newgrf_act0_trains.cpp | 2 +- src/newgrf_engine.cpp | 2 +- src/rail.cpp | 4 +- src/road.cpp | 4 +- src/roadveh_cmd.cpp | 14 +-- src/saveload/vehicle_sl.cpp | 2 +- src/ship_cmd.cpp | 6 +- src/train_cmd.cpp | 18 ++-- src/vehicle.cpp | 26 +++--- src/vehicle_base.h | 20 ----- src/vehicle_cmd.cpp | 8 +- 26 files changed, 208 insertions(+), 198 deletions(-) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 7a1b8b7a8cbb5..91f0f7968f10a 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -200,7 +200,7 @@ void GetRotorImage(const Aircraft *v, EngineImageType image_type, VehicleSpriteS static void GetAircraftIcon(EngineID engine, EngineImageType image_type, VehicleSpriteSeq *result) { const Engine *e = Engine::Get(engine); - uint8_t spritenum = e->u.air.image_index; + uint8_t spritenum = e->VehInfo().image_index; if (IsCustomVehicleSpriteNum(spritenum)) { GetCustomVehicleIcon(engine, DIR_W, image_type, result); @@ -267,7 +267,7 @@ void GetAircraftSpriteSize(EngineID engine, uint &width, uint &height, int &xoff */ CommandCost CmdBuildAircraft(DoCommandFlags flags, TileIndex tile, const Engine *e, Vehicle **ret) { - const AircraftVehicleInfo *avi = &e->u.air; + const AircraftVehicleInfo *avi = &e->VehInfo(); const Station *st = Station::GetByTile(tile); /* Prevent building aircraft types at places which can't handle them */ @@ -438,7 +438,7 @@ static void CheckIfAircraftNeedsService(Aircraft *v) Money Aircraft::GetRunningCost() const { const Engine *e = this->GetEngine(); - uint cost_factor = GetVehicleProperty(this, PROP_AIRCRAFT_RUNNING_COST_FACTOR, e->u.air.running_cost); + uint cost_factor = GetVehicleProperty(this, PROP_AIRCRAFT_RUNNING_COST_FACTOR, e->VehInfo().running_cost); return GetPrice(PR_RUNNING_AIRCRAFT, cost_factor, e->GetGRF()); } diff --git a/src/articulated_vehicles.cpp b/src/articulated_vehicles.cpp index 9ffc0a6e8f943..08c3c4416c370 100644 --- a/src/articulated_vehicles.cpp +++ b/src/articulated_vehicles.cpp @@ -365,10 +365,10 @@ void AddArticulatedParts(Vehicle *first) t->track = front->track; t->railtypes = front->railtypes; - t->spritenum = e_artic->u.rail.image_index; + t->spritenum = e_artic->VehInfo().image_index; if (e_artic->CanCarryCargo()) { t->cargo_type = e_artic->GetDefaultCargoType(); - t->cargo_cap = e_artic->u.rail.capacity; // Callback 36 is called when the consist is finished + t->cargo_cap = e_artic->VehInfo().capacity; // Callback 36 is called when the consist is finished } else { t->cargo_type = front->cargo_type; // Needed for livery selection t->cargo_cap = 0; @@ -392,11 +392,11 @@ void AddArticulatedParts(Vehicle *first) rv->roadtype = front->roadtype; rv->compatible_roadtypes = front->compatible_roadtypes; - rv->spritenum = e_artic->u.road.image_index; + rv->spritenum = e_artic->VehInfo().image_index; if (e_artic->CanCarryCargo()) { rv->cargo_type = e_artic->GetDefaultCargoType(); assert(IsValidCargoType(rv->cargo_type)); - rv->cargo_cap = e_artic->u.road.capacity; // Callback 36 is called when the consist is finished + rv->cargo_cap = e_artic->VehInfo().capacity; // Callback 36 is called when the consist is finished } else { rv->cargo_type = front->cargo_type; // Needed for livery selection rv->cargo_cap = 0; diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index 0798c679b3f3c..454450c6420d0 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -71,16 +71,16 @@ bool CheckAutoreplaceValidity(EngineID from, EngineID to, CompanyID company) switch (type) { case VEH_TRAIN: { /* make sure the railtypes are compatible */ - if (!GetAllCompatibleRailTypes(e_from->u.rail.railtypes).Any(GetAllCompatibleRailTypes(e_to->u.rail.railtypes))) return false; + if (!GetAllCompatibleRailTypes(e_from->VehInfo().railtypes).Any(GetAllCompatibleRailTypes(e_to->VehInfo().railtypes))) return false; /* make sure we do not replace wagons with engines or vice versa */ - if ((e_from->u.rail.railveh_type == RAILVEH_WAGON) != (e_to->u.rail.railveh_type == RAILVEH_WAGON)) return false; + if ((e_from->VehInfo().railveh_type == RAILVEH_WAGON) != (e_to->VehInfo().railveh_type == RAILVEH_WAGON)) return false; break; } case VEH_ROAD: /* make sure the roadtypes are compatible */ - if (!GetRoadTypeInfo(e_from->u.road.roadtype)->powered_roadtypes.Any(GetRoadTypeInfo(e_to->u.road.roadtype)->powered_roadtypes)) return false; + if (!GetRoadTypeInfo(e_from->VehInfo().roadtype)->powered_roadtypes.Any(GetRoadTypeInfo(e_to->VehInfo().roadtype)->powered_roadtypes)) return false; /* make sure that we do not replace a tram with a normal road vehicles or vice versa */ if (e_from->info.misc_flags.Test(EngineMiscFlag::RoadIsTram) != e_to->info.misc_flags.Test(EngineMiscFlag::RoadIsTram)) return false; @@ -88,7 +88,7 @@ bool CheckAutoreplaceValidity(EngineID from, EngineID to, CompanyID company) case VEH_AIRCRAFT: /* make sure that we do not replace a plane with a helicopter or vice versa */ - if ((e_from->u.air.subtype & AIR_CTOL) != (e_to->u.air.subtype & AIR_CTOL)) return false; + if ((e_from->VehInfo().subtype & AIR_CTOL) != (e_to->VehInfo().subtype & AIR_CTOL)) return false; break; default: break; diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index 081a8a8acee39..67f970776928b 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -140,7 +140,7 @@ class ReplaceVehicleWindow : public Window { case VEH_ROAD: if (draw_left && this->sel_roadtype != INVALID_ROADTYPE) { /* Ensure that the roadtype is specific to the selected one */ - if (e->u.road.roadtype != this->sel_roadtype) continue; + if (e->VehInfo().roadtype != this->sel_roadtype) continue; } break; diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index a40ad4ef359e0..0702fdeee53a7 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -726,8 +726,8 @@ static int DrawShipPurchaseInfo(int left, int right, int y, EngineID engine_numb /* Purchase cost - Max speed */ uint raw_speed = e->GetDisplayMaxSpeed(); - uint ocean_speed = e->u.ship.ApplyWaterClassSpeedFrac(raw_speed, true); - uint canal_speed = e->u.ship.ApplyWaterClassSpeedFrac(raw_speed, false); + uint ocean_speed = e->VehInfo().ApplyWaterClassSpeedFrac(raw_speed, true); + uint canal_speed = e->VehInfo().ApplyWaterClassSpeedFrac(raw_speed, false); if (ocean_speed == canal_speed) { if (te.cost != 0) { @@ -885,10 +885,10 @@ int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number, switch (e->type) { default: NOT_REACHED(); case VEH_TRAIN: - if (e->u.rail.railveh_type == RAILVEH_WAGON) { - y = DrawRailWagonPurchaseInfo(left, right, y, engine_number, &e->u.rail, te); + if (e->VehInfo().railveh_type == RAILVEH_WAGON) { + y = DrawRailWagonPurchaseInfo(left, right, y, engine_number, &e->VehInfo(), te); } else { - y = DrawRailEnginePurchaseInfo(left, right, y, engine_number, &e->u.rail, te); + y = DrawRailEnginePurchaseInfo(left, right, y, engine_number, &e->VehInfo(), te); } articulated_cargo = true; break; @@ -920,7 +920,7 @@ int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number, } /* Draw details that apply to all types except rail wagons. */ - if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) { + if (e->type != VEH_TRAIN || e->VehInfo().railveh_type != RAILVEH_WAGON) { /* Design date - Life length */ DrawString(left, right, y, GetString(STR_PURCHASE_INFO_DESIGNED_LIFE, ymd.year, TimerGameCalendar::DateToYear(e->GetLifeLengthInDays()))); y += GetCharacterHeight(FS_NORMAL); @@ -1395,7 +1395,7 @@ struct BuildVehicleWindow : Window { for (const Engine *e : Engine::IterateType(VEH_TRAIN)) { if (!this->show_hidden_engines && e->IsVariantHidden(_local_company)) continue; EngineID eid = e->index; - const RailVehicleInfo *rvi = &e->u.rail; + const RailVehicleInfo *rvi = &e->VehInfo(); if (this->filter.railtype != INVALID_RAILTYPE && !HasPowerOnRail(rvi->railtypes, this->filter.railtype)) continue; if (!IsEngineBuildable(eid, VEH_TRAIN, _local_company)) continue; @@ -1426,7 +1426,7 @@ struct BuildVehicleWindow : Window { if (std::ranges::find(list, variant, &GUIEngineListItem::engine_id) == list.end()) { const Engine *e = Engine::Get(variant); list.emplace_back(variant, e->info.variant_id, e->display_flags | EngineDisplayFlag::Shaded, 0); - if (e->u.rail.railveh_type != RAILVEH_WAGON) num_engines++; + if (e->VehInfo().railveh_type != RAILVEH_WAGON) num_engines++; } } @@ -1461,7 +1461,7 @@ struct BuildVehicleWindow : Window { if (!this->show_hidden_engines && e->IsVariantHidden(_local_company)) continue; EngineID eid = e->index; if (!IsEngineBuildable(eid, VEH_ROAD, _local_company)) continue; - if (this->filter.roadtype != INVALID_ROADTYPE && !HasPowerOnRoad(e->u.road.roadtype, this->filter.roadtype)) continue; + if (this->filter.roadtype != INVALID_ROADTYPE && !HasPowerOnRoad(e->VehInfo().roadtype, this->filter.roadtype)) continue; if (!bdf.Filter(e->badges)) continue; /* Filter by name or NewGRF extra text */ diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 8306ec8b30bf9..18856c2a951a3 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -229,7 +229,7 @@ void InitDepotWindowBlockSizes() if (!e->IsEnabled()) continue; uint w = TRAININFO_DEFAULT_VEHICLE_WIDTH; - if (e->GetGRF() != nullptr && IsCustomVehicleSpriteNum(e->u.rail.image_index)) { + if (e->GetGRF() != nullptr && IsCustomVehicleSpriteNum(e->VehInfo().image_index)) { w = e->GetGRF()->traininfo_vehicle_width; if (w != VEHICLEINFO_FULL_VEHICLE_WIDTH) { /* Hopeless. diff --git a/src/elrail.cpp b/src/elrail.cpp index 720da0f26ba0b..14b145713c8b0 100644 --- a/src/elrail.cpp +++ b/src/elrail.cpp @@ -582,7 +582,7 @@ void UpdateDisableElrailSettingState(bool disable, bool update_vehicles) { /* walk through all train engines */ for (Engine *e : Engine::IterateType(VEH_TRAIN)) { - RailVehicleInfo *rv_info = &e->u.rail; + RailVehicleInfo *rv_info = &e->VehInfo(); /* update railtype of engines intended to use elrail */ if (rv_info->intended_railtypes.Test(RAILTYPE_ELECTRIC)) { rv_info->railtypes.Set(RAILTYPE_ELECTRIC, !disable); diff --git a/src/engine.cpp b/src/engine.cpp index 68b9e1b0d1a9d..15f0cfa5e9ea8 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -78,24 +78,19 @@ Engine::Engine(VehicleType type, uint16_t local_id) /* Check if this base engine is within the original engine data range */ if (local_id >= _engine_counts[type]) { - /* 'power' defaults to zero, so we also have to default to 'wagon' */ - if (type == VEH_TRAIN) this->u.rail.railveh_type = RAILVEH_WAGON; + /* Initialise default type-specific information. */ + switch (type) { + case VEH_TRAIN: this->vehicle_info.emplace(); break; + case VEH_ROAD: this->vehicle_info.emplace(); break; + case VEH_SHIP: this->vehicle_info.emplace(); break; + case VEH_AIRCRAFT: this->vehicle_info.emplace(); break; + default: break; + } /* Set model life to maximum to make wagons available */ this->info.base_life = TimerGameCalendar::Year{0xFF}; - /* Set road vehicle tractive effort to the default value */ - if (type == VEH_ROAD) this->u.road.tractive_effort = 0x4C; /* Aircraft must have CT_INVALID as default, as there is no property */ this->info.cargo_type = INVALID_CARGO; this->info.cargo_label = (type == VEH_AIRCRAFT) ? CT_INVALID : CT_PASSENGERS; - /* Ships must have a non-zero acceleration. */ - if (type == VEH_SHIP) this->u.ship.acceleration = 1; - /* Set visual effect to the default value */ - switch (type) { - case VEH_TRAIN: this->u.rail.visual_effect = VE_DEFAULT; break; - case VEH_ROAD: this->u.road.visual_effect = VE_DEFAULT; break; - case VEH_SHIP: this->u.ship.visual_effect = VE_DEFAULT; break; - default: break; // The aircraft, disasters and especially visual effects have no NewGRF configured visual effects - } /* Set cargo aging period to the default value. */ this->info.cargo_age_period = Ticks::CARGO_AGING_TICKS; /* Not a variant */ @@ -110,33 +105,37 @@ Engine::Engine(VehicleType type, uint16_t local_id) switch (type) { default: NOT_REACHED(); - case VEH_TRAIN: - this->u.rail = _orig_rail_vehicle_info[local_id]; - this->original_image_index = this->u.rail.image_index; + case VEH_TRAIN: { + RailVehicleInfo &rvi = this->vehicle_info.emplace(_orig_rail_vehicle_info[local_id]); + this->original_image_index = rvi.image_index; this->info.string_id = STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_KIRBY_PAUL_TANK_STEAM + local_id; /* Set the default model life of original wagons to "infinite" */ - if (this->u.rail.railveh_type == RAILVEH_WAGON) this->info.base_life = TimerGameCalendar::Year{0xFF}; + if (rvi.railveh_type == RAILVEH_WAGON) this->info.base_life = TimerGameCalendar::Year{0xFF}; break; + } - case VEH_ROAD: - this->u.road = _orig_road_vehicle_info[local_id]; - this->original_image_index = this->u.road.image_index; + case VEH_ROAD: { + RoadVehicleInfo &rvi = this->vehicle_info.emplace(_orig_road_vehicle_info[local_id]); + this->original_image_index = rvi.image_index; this->info.string_id = STR_VEHICLE_NAME_ROAD_VEHICLE_MPS_REGAL_BUS + local_id; break; + } - case VEH_SHIP: - this->u.ship = _orig_ship_vehicle_info[local_id]; - this->original_image_index = this->u.ship.image_index; + case VEH_SHIP: { + ShipVehicleInfo &svi = this->vehicle_info.emplace(_orig_ship_vehicle_info[local_id]); + this->original_image_index = svi.image_index; this->info.string_id = STR_VEHICLE_NAME_SHIP_MPS_OIL_TANKER + local_id; break; + } - case VEH_AIRCRAFT: - this->u.air = _orig_aircraft_vehicle_info[local_id]; - this->original_image_index = this->u.air.image_index; + case VEH_AIRCRAFT: { + AircraftVehicleInfo &avi = this->vehicle_info.emplace(_orig_aircraft_vehicle_info[local_id]); + this->original_image_index = avi.image_index; this->info.string_id = STR_VEHICLE_NAME_AIRCRAFT_SAMPSON_U52 + local_id; break; + } } } @@ -174,11 +173,11 @@ bool Engine::CanCarryCargo() const */ switch (this->type) { case VEH_TRAIN: - if (this->u.rail.capacity == 0) return false; + if (this->VehInfo().capacity == 0) return false; break; case VEH_ROAD: - if (this->u.road.capacity == 0) return false; + if (this->VehInfo().capacity == 0) return false; break; case VEH_SHIP: @@ -210,7 +209,7 @@ uint Engine::DetermineCapacity(const Vehicle *v, uint16_t *mail_capacity) const CargoType cargo_type = (v != nullptr) ? v->cargo_type : default_cargo; if (mail_capacity != nullptr && this->type == VEH_AIRCRAFT && IsCargoInClass(cargo_type, CargoClass::Passengers)) { - *mail_capacity = GetEngineProperty(this->index, PROP_AIRCRAFT_MAIL_CAPACITY, this->u.air.mail_capacity, v); + *mail_capacity = GetEngineProperty(this->index, PROP_AIRCRAFT_MAIL_CAPACITY, this->VehInfo().mail_capacity, v); } /* Check the refit capacity callback if we are not in the default configuration, or if we are using the new multiplier algorithm. */ @@ -225,24 +224,24 @@ uint Engine::DetermineCapacity(const Vehicle *v, uint16_t *mail_capacity) const uint extra_mail_cap = 0; switch (this->type) { case VEH_TRAIN: - capacity = GetEngineProperty(this->index, PROP_TRAIN_CARGO_CAPACITY, this->u.rail.capacity, v); + capacity = GetEngineProperty(this->index, PROP_TRAIN_CARGO_CAPACITY, this->VehInfo().capacity, v); /* In purchase list add the capacity of the second head. Always use the plain property for this. */ - if (v == nullptr && this->u.rail.railveh_type == RAILVEH_MULTIHEAD) capacity += this->u.rail.capacity; + if (v == nullptr && this->VehInfo().railveh_type == RAILVEH_MULTIHEAD) capacity += this->VehInfo().capacity; break; case VEH_ROAD: - capacity = GetEngineProperty(this->index, PROP_ROADVEH_CARGO_CAPACITY, this->u.road.capacity, v); + capacity = GetEngineProperty(this->index, PROP_ROADVEH_CARGO_CAPACITY, this->VehInfo().capacity, v); break; case VEH_SHIP: - capacity = GetEngineProperty(this->index, PROP_SHIP_CARGO_CAPACITY, this->u.ship.capacity, v); + capacity = GetEngineProperty(this->index, PROP_SHIP_CARGO_CAPACITY, this->VehInfo().capacity, v); break; case VEH_AIRCRAFT: - capacity = GetEngineProperty(this->index, PROP_AIRCRAFT_PASSENGER_CAPACITY, this->u.air.passenger_capacity, v); + capacity = GetEngineProperty(this->index, PROP_AIRCRAFT_PASSENGER_CAPACITY, this->VehInfo().passenger_capacity, v); if (!IsCargoInClass(cargo_type, CargoClass::Passengers)) { - extra_mail_cap = GetEngineProperty(this->index, PROP_AIRCRAFT_MAIL_CAPACITY, this->u.air.mail_capacity, v); + extra_mail_cap = GetEngineProperty(this->index, PROP_AIRCRAFT_MAIL_CAPACITY, this->VehInfo().mail_capacity, v); } if (IsValidCargoType(GetCargoTypeByLabel(CT_MAIL))) { if (!new_multipliers && cargo_type == GetCargoTypeByLabel(CT_MAIL)) return capacity + extra_mail_cap; @@ -284,25 +283,25 @@ Money Engine::GetRunningCost() const uint cost_factor; switch (this->type) { case VEH_ROAD: - base_price = this->u.road.running_cost_class; + base_price = this->VehInfo().running_cost_class; if (base_price == INVALID_PRICE) return 0; - cost_factor = GetEngineProperty(this->index, PROP_ROADVEH_RUNNING_COST_FACTOR, this->u.road.running_cost); + cost_factor = GetEngineProperty(this->index, PROP_ROADVEH_RUNNING_COST_FACTOR, this->VehInfo().running_cost); break; case VEH_TRAIN: - base_price = this->u.rail.running_cost_class; + base_price = this->VehInfo().running_cost_class; if (base_price == INVALID_PRICE) return 0; - cost_factor = GetEngineProperty(this->index, PROP_TRAIN_RUNNING_COST_FACTOR, this->u.rail.running_cost); + cost_factor = GetEngineProperty(this->index, PROP_TRAIN_RUNNING_COST_FACTOR, this->VehInfo().running_cost); break; case VEH_SHIP: base_price = PR_RUNNING_SHIP; - cost_factor = GetEngineProperty(this->index, PROP_SHIP_RUNNING_COST_FACTOR, this->u.ship.running_cost); + cost_factor = GetEngineProperty(this->index, PROP_SHIP_RUNNING_COST_FACTOR, this->VehInfo().running_cost); break; case VEH_AIRCRAFT: base_price = PR_RUNNING_AIRCRAFT; - cost_factor = GetEngineProperty(this->index, PROP_AIRCRAFT_RUNNING_COST_FACTOR, this->u.air.running_cost); + cost_factor = GetEngineProperty(this->index, PROP_AIRCRAFT_RUNNING_COST_FACTOR, this->VehInfo().running_cost); break; default: NOT_REACHED(); @@ -322,27 +321,27 @@ Money Engine::GetCost() const switch (this->type) { case VEH_ROAD: base_price = PR_BUILD_VEHICLE_ROAD; - cost_factor = GetEngineProperty(this->index, PROP_ROADVEH_COST_FACTOR, this->u.road.cost_factor); + cost_factor = GetEngineProperty(this->index, PROP_ROADVEH_COST_FACTOR, this->VehInfo().cost_factor); break; case VEH_TRAIN: - if (this->u.rail.railveh_type == RAILVEH_WAGON) { + if (this->VehInfo().railveh_type == RAILVEH_WAGON) { base_price = PR_BUILD_VEHICLE_WAGON; - cost_factor = GetEngineProperty(this->index, PROP_TRAIN_COST_FACTOR, this->u.rail.cost_factor); + cost_factor = GetEngineProperty(this->index, PROP_TRAIN_COST_FACTOR, this->VehInfo().cost_factor); } else { base_price = PR_BUILD_VEHICLE_TRAIN; - cost_factor = GetEngineProperty(this->index, PROP_TRAIN_COST_FACTOR, this->u.rail.cost_factor); + cost_factor = GetEngineProperty(this->index, PROP_TRAIN_COST_FACTOR, this->VehInfo().cost_factor); } break; case VEH_SHIP: base_price = PR_BUILD_VEHICLE_SHIP; - cost_factor = GetEngineProperty(this->index, PROP_SHIP_COST_FACTOR, this->u.ship.cost_factor); + cost_factor = GetEngineProperty(this->index, PROP_SHIP_COST_FACTOR, this->VehInfo().cost_factor); break; case VEH_AIRCRAFT: base_price = PR_BUILD_VEHICLE_AIRCRAFT; - cost_factor = GetEngineProperty(this->index, PROP_AIRCRAFT_COST_FACTOR, this->u.air.cost_factor); + cost_factor = GetEngineProperty(this->index, PROP_AIRCRAFT_COST_FACTOR, this->VehInfo().cost_factor); break; default: NOT_REACHED(); @@ -359,22 +358,22 @@ uint Engine::GetDisplayMaxSpeed() const { switch (this->type) { case VEH_TRAIN: - return GetEngineProperty(this->index, PROP_TRAIN_SPEED, this->u.rail.max_speed); + return GetEngineProperty(this->index, PROP_TRAIN_SPEED, this->VehInfo().max_speed); case VEH_ROAD: { uint max_speed = GetEngineProperty(this->index, PROP_ROADVEH_SPEED, 0); - return (max_speed != 0) ? max_speed * 2 : this->u.road.max_speed / 2; + return (max_speed != 0) ? max_speed * 2 : this->VehInfo().max_speed / 2; } case VEH_SHIP: - return GetEngineProperty(this->index, PROP_SHIP_SPEED, this->u.ship.max_speed) / 2; + return GetEngineProperty(this->index, PROP_SHIP_SPEED, this->VehInfo().max_speed) / 2; case VEH_AIRCRAFT: { uint max_speed = GetEngineProperty(this->index, PROP_AIRCRAFT_SPEED, 0); if (max_speed != 0) { return (max_speed * 128) / 10; } - return this->u.air.max_speed; + return this->VehInfo().max_speed; } default: NOT_REACHED(); @@ -392,9 +391,9 @@ uint Engine::GetPower() const /* Only trains and road vehicles have 'power'. */ switch (this->type) { case VEH_TRAIN: - return GetEngineProperty(this->index, PROP_TRAIN_POWER, this->u.rail.power); + return GetEngineProperty(this->index, PROP_TRAIN_POWER, this->VehInfo().power); case VEH_ROAD: - return GetEngineProperty(this->index, PROP_ROADVEH_POWER, this->u.road.power) * 10; + return GetEngineProperty(this->index, PROP_ROADVEH_POWER, this->VehInfo().power) * 10; default: NOT_REACHED(); } @@ -410,9 +409,9 @@ uint Engine::GetDisplayWeight() const /* Only trains and road vehicles have 'weight'. */ switch (this->type) { case VEH_TRAIN: - return GetEngineProperty(this->index, PROP_TRAIN_WEIGHT, this->u.rail.weight) << (this->u.rail.railveh_type == RAILVEH_MULTIHEAD ? 1 : 0); + return GetEngineProperty(this->index, PROP_TRAIN_WEIGHT, this->VehInfo().weight) << (this->VehInfo().railveh_type == RAILVEH_MULTIHEAD ? 1 : 0); case VEH_ROAD: - return GetEngineProperty(this->index, PROP_ROADVEH_WEIGHT, this->u.road.weight) / 4; + return GetEngineProperty(this->index, PROP_ROADVEH_WEIGHT, this->VehInfo().weight) / 4; default: NOT_REACHED(); } @@ -428,9 +427,9 @@ uint Engine::GetDisplayMaxTractiveEffort() const /* Only trains and road vehicles have 'tractive effort'. */ switch (this->type) { case VEH_TRAIN: - return (GROUND_ACCELERATION * this->GetDisplayWeight() * GetEngineProperty(this->index, PROP_TRAIN_TRACTIVE_EFFORT, this->u.rail.tractive_effort)) / 256; + return (GROUND_ACCELERATION * this->GetDisplayWeight() * GetEngineProperty(this->index, PROP_TRAIN_TRACTIVE_EFFORT, this->VehInfo().tractive_effort)) / 256; case VEH_ROAD: - return (GROUND_ACCELERATION * this->GetDisplayWeight() * GetEngineProperty(this->index, PROP_ROADVEH_TRACTIVE_EFFORT, this->u.road.tractive_effort)) / 256; + return (GROUND_ACCELERATION * this->GetDisplayWeight() * GetEngineProperty(this->index, PROP_ROADVEH_TRACTIVE_EFFORT, this->VehInfo().tractive_effort)) / 256; default: NOT_REACHED(); } @@ -454,7 +453,7 @@ uint16_t Engine::GetRange() const { switch (this->type) { case VEH_AIRCRAFT: - return GetEngineProperty(this->index, PROP_AIRCRAFT_RANGE, this->u.air.max_range); + return GetEngineProperty(this->index, PROP_AIRCRAFT_RANGE, this->VehInfo().max_range); default: NOT_REACHED(); } @@ -468,7 +467,7 @@ StringID Engine::GetAircraftTypeText() const { switch (this->type) { case VEH_AIRCRAFT: - switch (this->u.air.subtype) { + switch (this->VehInfo().subtype) { case AIR_HELI: return STR_LIVERY_HELICOPTER; case AIR_CTOL: return STR_LIVERY_SMALL_PLANE; case AIR_CTOL | AIR_FAST: return STR_LIVERY_LARGE_PLANE; @@ -625,7 +624,7 @@ void ShowEnginePreviewWindow(EngineID engine); static bool IsWagon(EngineID index) { const Engine *e = Engine::Get(index); - return e->type == VEH_TRAIN && e->u.rail.railveh_type == RAILVEH_WAGON; + return e->type == VEH_TRAIN && e->VehInfo().railveh_type == RAILVEH_WAGON; } /** @@ -700,7 +699,7 @@ void SetYearEngineAgingStops() /* Exclude certain engines */ if (!ei->climates.Test(_settings_game.game_creation.landscape)) continue; - if (e->type == VEH_TRAIN && e->u.rail.railveh_type == RAILVEH_WAGON) continue; + if (e->type == VEH_TRAIN && e->VehInfo().railveh_type == RAILVEH_WAGON) continue; /* Base year ending date on half the model life */ TimerGameCalendar::YearMonthDay ymd = TimerGameCalendar::ConvertDateToYMD(ei->base_intro + (ei->lifelength.base() * CalendarTime::DAYS_IN_LEAP_YEAR) / 2); @@ -1107,13 +1106,13 @@ static void NewVehicleAvailable(Engine *e) if (e->type == VEH_TRAIN) { /* maybe make another rail type available */ - assert(e->u.rail.railtypes != RailTypes{}); - RailTypes introduced = GetAllIntroducesRailTypes(e->u.rail.railtypes); + assert(e->VehInfo().railtypes != RailTypes{}); + RailTypes introduced = GetAllIntroducesRailTypes(e->VehInfo().railtypes); for (Company *c : Company::Iterate()) c->avail_railtypes = AddDateIntroducedRailTypes(c->avail_railtypes | introduced, TimerGameCalendar::date); } else if (e->type == VEH_ROAD) { /* maybe make another road type available */ - assert(e->u.road.roadtype < ROADTYPE_END); - for (Company *c : Company::Iterate()) c->avail_roadtypes = AddDateIntroducedRoadTypes(c->avail_roadtypes | GetRoadTypeInfo(e->u.road.roadtype)->introduces_roadtypes, TimerGameCalendar::date); + assert(e->VehInfo().roadtype < ROADTYPE_END); + for (Company *c : Company::Iterate()) c->avail_roadtypes = AddDateIntroducedRoadTypes(c->avail_roadtypes | GetRoadTypeInfo(e->VehInfo().roadtype)->introduces_roadtypes, TimerGameCalendar::date); } /* Only broadcast event if AIs are able to build this vehicle type. */ @@ -1268,12 +1267,12 @@ bool IsEngineBuildable(EngineID engine, VehicleType type, CompanyID company) if (type == VEH_TRAIN && company != OWNER_DEITY) { /* Check if the rail type is available to this company */ const Company *c = Company::Get(company); - if (!GetAllCompatibleRailTypes(e->u.rail.railtypes).Any(c->avail_railtypes)) return false; + if (!GetAllCompatibleRailTypes(e->VehInfo().railtypes).Any(c->avail_railtypes)) return false; } if (type == VEH_ROAD && company != OWNER_DEITY) { /* Check if the road type is available to this company */ const Company *c = Company::Get(company); - if (!GetRoadTypeInfo(e->u.road.roadtype)->powered_roadtypes.Any(c->avail_roadtypes)) return false; + if (!GetRoadTypeInfo(e->VehInfo().roadtype)->powered_roadtypes.Any(c->avail_roadtypes)) return false; } return true; @@ -1319,7 +1318,7 @@ void CheckEngines() if (!e->IsEnabled()) continue; /* Don't consider train wagons, we need a powered engine available. */ - if (e->type == VEH_TRAIN && e->u.rail.railveh_type == RAILVEH_WAGON) continue; + if (e->type == VEH_TRAIN && e->VehInfo().railveh_type == RAILVEH_WAGON) continue; /* We have an available engine... yay! */ if (e->flags.Test(EngineFlag::Available) && e->company_avail.Any()) return; diff --git a/src/engine_base.h b/src/engine_base.h index 82ea41cd8ffec..d8e6052524b11 100644 --- a/src/engine_base.h +++ b/src/engine_base.h @@ -35,7 +35,8 @@ using EngineDisplayFlags = EnumBitSet; typedef Pool EnginePool; extern EnginePool _engine_pool; -struct Engine : EnginePool::PoolItem<&_engine_pool> { +class Engine : public EnginePool::PoolItem<&_engine_pool> { +public: CompanyMask company_avail{}; ///< Bit for each company whether the engine is available for that company. CompanyMask company_hidden{}; ///< Bit for each company whether the engine is normally hidden in the build gui for that company. CompanyMask preview_asked{}; ///< Bit for each company which has already been offered a preview. @@ -64,13 +65,6 @@ struct Engine : EnginePool::PoolItem<&_engine_pool> { EngineID display_last_variant = EngineID::Invalid(); ///< NOSAVE client-side-only last variant selected. EngineInfo info{}; - union { - RailVehicleInfo rail; - RoadVehicleInfo road; - ShipVehicleInfo ship; - AircraftVehicleInfo air; - } u{}; - uint16_t list_position = 0; /* NewGRF related data */ @@ -78,6 +72,11 @@ struct Engine : EnginePool::PoolItem<&_engine_pool> { std::vector overrides{}; std::vector badges{}; +private: + /* Vehicle-type specific information. */ + std::variant vehicle_info{}; + +public: Engine() {} Engine(VehicleType type, uint16_t local_id); bool IsEnabled() const; @@ -177,6 +176,18 @@ struct Engine : EnginePool::PoolItem<&_engine_pool> { bool operator() (size_t index) { return Engine::Get(index)->type == this->vt; } }; + template + inline T &VehInfo() + { + return std::get(this->vehicle_info); + } + + template + inline const T &VehInfo() const + { + return std::get(this->vehicle_info); + } + /** * Returns an iterable ensemble of all valid engines of the given type * @param vt the VehicleType for engines to be valid @@ -234,22 +245,22 @@ inline const EngineInfo *EngInfo(EngineID e) inline const RailVehicleInfo *RailVehInfo(EngineID e) { - return &Engine::Get(e)->u.rail; + return &Engine::Get(e)->VehInfo(); } inline const RoadVehicleInfo *RoadVehInfo(EngineID e) { - return &Engine::Get(e)->u.road; + return &Engine::Get(e)->VehInfo(); } inline const ShipVehicleInfo *ShipVehInfo(EngineID e) { - return &Engine::Get(e)->u.ship; + return &Engine::Get(e)->VehInfo(); } inline const AircraftVehicleInfo *AircraftVehInfo(EngineID e) { - return &Engine::Get(e)->u.air; + return &Engine::Get(e)->VehInfo(); } #endif /* ENGINE_BASE_H */ diff --git a/src/engine_gui.cpp b/src/engine_gui.cpp index 210cf3bdf190a..19a4eff047ead 100644 --- a/src/engine_gui.cpp +++ b/src/engine_gui.cpp @@ -43,12 +43,12 @@ StringID GetEngineCategoryName(EngineID engine) switch (e->type) { default: NOT_REACHED(); case VEH_ROAD: - return GetRoadTypeInfo(e->u.road.roadtype)->strings.new_engine; + return GetRoadTypeInfo(e->VehInfo().roadtype)->strings.new_engine; case VEH_AIRCRAFT: return STR_ENGINE_PREVIEW_AIRCRAFT; case VEH_SHIP: return STR_ENGINE_PREVIEW_SHIP; case VEH_TRAIN: - assert(e->u.rail.railtypes.Any()); - return GetRailTypeInfo(e->u.rail.railtypes.GetNthSetBit(0).value())->strings.new_loco; + assert(e->VehInfo().railtypes.Any()); + return GetRailTypeInfo(e->VehInfo().railtypes.GetNthSetBit(0).value())->strings.new_loco; } } @@ -182,12 +182,12 @@ static std::string GetTrainEngineInfoString(const Engine &e) res << GetString(STR_ENGINE_PREVIEW_COST_WEIGHT, e.GetCost(), e.GetDisplayWeight()); res << '\n'; - if (e.u.rail.railtypes.Count() > 1) { + if (e.VehInfo().railtypes.Count() > 1) { std::string railtypes{}; std::string_view list_separator = GetListSeparator(); for (const auto &rt : _sorted_railtypes) { - if (!e.u.rail.railtypes.Test(rt)) continue; + if (!e.VehInfo().railtypes.Test(rt)) continue; if (!railtypes.empty()) railtypes += list_separator; AppendStringInPlace(railtypes, GetRailTypeInfo(rt)->strings.name); @@ -197,7 +197,7 @@ static std::string GetTrainEngineInfoString(const Engine &e) } bool is_maglev = true; - for (RailType rt : e.u.rail.railtypes) { + for (RailType rt : e.VehInfo().railtypes) { is_maglev &= GetRailTypeInfo(rt)->acceleration_type == VehicleAccelerationModel::Maglev; } diff --git a/src/engine_type.h b/src/engine_type.h index 1fefbe1ba1fa0..640a99b73f1b6 100644 --- a/src/engine_type.h +++ b/src/engine_type.h @@ -25,7 +25,7 @@ /** Unique identification number of an engine. */ using EngineID = PoolID; -struct Engine; +class Engine; /** Available types of rail vehicles. */ enum RailVehicleTypes : uint8_t { @@ -50,10 +50,30 @@ enum class VehicleAccelerationModel : uint8_t { Maglev, ///< Maglev acceleration model. }; +/** Meaning of the various bits of the visual effect. */ +enum VisualEffect : uint8_t { + VE_OFFSET_START = 0, ///< First bit that contains the offset (0 = front, 8 = centre, 15 = rear) + VE_OFFSET_COUNT = 4, ///< Number of bits used for the offset + VE_OFFSET_CENTRE = 8, ///< Value of offset corresponding to a position above the centre of the vehicle + + VE_TYPE_START = 4, ///< First bit used for the type of effect + VE_TYPE_COUNT = 2, ///< Number of bits used for the effect type + VE_TYPE_DEFAULT = 0, ///< Use default from engine class + VE_TYPE_STEAM = 1, ///< Steam plumes + VE_TYPE_DIESEL = 2, ///< Diesel fumes + VE_TYPE_ELECTRIC = 3, ///< Electric sparks + + VE_DISABLE_EFFECT = 6, ///< Flag to disable visual effect + VE_ADVANCED_EFFECT = VE_DISABLE_EFFECT, ///< Flag for advanced effects + VE_DISABLE_WAGON_POWER = 7, ///< Flag to disable wagon power + + VE_DEFAULT = 0xFF, ///< Default value to indicate that visual effect should be based on engine class +}; + /** Information about a rail vehicle. */ struct RailVehicleInfo { uint8_t image_index = 0; - RailVehicleTypes railveh_type{}; + RailVehicleTypes railveh_type = RAILVEH_WAGON; uint8_t cost_factor = 0; ///< Purchase cost factor; For multiheaded engines the sum of both engine prices. RailTypes railtypes{}; ///< Railtypes, mangled if elrail is disabled. RailTypes intended_railtypes{}; ///< Intended railtypes, regardless of elrail being enabled or disabled. @@ -67,7 +87,7 @@ struct RailVehicleInfo { uint8_t capacity = 0; ///< Cargo capacity of vehicle; For multiheaded engines the capacity of each single engine. uint16_t pow_wag_power = 0; ///< Extra power applied to consist if wagon should be powered uint8_t pow_wag_weight = 0; ///< Extra weight applied to consist if wagon should be powered - uint8_t visual_effect = 0; ///< Bitstuffed NewGRF visual effect data + uint8_t visual_effect = VE_DEFAULT; ///< Bitstuffed NewGRF visual effect data uint8_t shorten_factor = 0; ///< length on main map for this type is 8 - shorten_factor uint8_t tractive_effort = 0; ///< Tractive effort coefficient uint8_t air_drag = 0; ///< Coefficient of air drag @@ -80,12 +100,12 @@ struct ShipVehicleInfo { uint8_t image_index = 0; uint8_t cost_factor = 0; uint8_t running_cost = 0; - uint8_t acceleration = 0; ///< Acceleration (1 unit = 1/3.2 mph per tick = 0.5 km-ish/h per tick) + uint8_t acceleration = 1; ///< Acceleration (1 unit = 1/3.2 mph per tick = 0.5 km-ish/h per tick) uint16_t max_speed = 0; ///< Maximum speed (1 unit = 1/3.2 mph = 0.5 km-ish/h) uint16_t capacity = 0; SoundID sfx{}; bool old_refittable = 0; ///< Is ship refittable; only used during initialisation. Later use EngineInfo::refit_mask. - uint8_t visual_effect = 0; ///< Bitstuffed NewGRF visual effect data + uint8_t visual_effect = VE_DEFAULT; ///< Bitstuffed NewGRF visual effect data uint8_t ocean_speed_frac = 0; ///< Fraction of maximum speed for ocean tiles. uint8_t canal_speed_frac = 0; ///< Fraction of maximum speed for canal/river tiles. @@ -133,9 +153,9 @@ struct RoadVehicleInfo { uint8_t capacity = 0; uint8_t weight = 0; ///< Weight in 1/4t units uint8_t power = 0; ///< Power in 10hp units - uint8_t tractive_effort = 0; ///< Coefficient of tractive effort + uint8_t tractive_effort = 0x4C; ///< Coefficient of tractive effort uint8_t air_drag = 0; ///< Coefficient of air drag - uint8_t visual_effect = 0; ///< Bitstuffed NewGRF visual effect data + uint8_t visual_effect = VE_DEFAULT; ///< Bitstuffed NewGRF visual effect data uint8_t shorten_factor = 0; ///< length on main map for this type is 8 - shorten_factor RoadType roadtype{}; ///< Road type }; diff --git a/src/newgrf.cpp b/src/newgrf.cpp index b6444a8e06ba1..26a6a66fea97e 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -272,7 +272,7 @@ Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16_t internal_id } if (type == VEH_TRAIN) { _gted[e->index].railtypelabels.clear(); - for (RailType rt : e->u.rail.railtypes) _gted[e->index].railtypelabels.push_back(GetRailTypeInfo(rt)->label); + for (RailType rt : e->VehInfo().railtypes) _gted[e->index].railtypelabels.push_back(GetRailTypeInfo(rt)->label); } GrfMsg(5, "Created new engine at index {} for GRFID {:x}, type {}, index {}", e->index, std::byteswap(file->grfid), type, internal_id); @@ -427,7 +427,7 @@ void ResetNewGRFData() /* Fill rail type label temporary data for default trains */ for (const Engine *e : Engine::IterateType(VEH_TRAIN)) { _gted[e->index].railtypelabels.clear(); - for (RailType rt : e->u.rail.railtypes) _gted[e->index].railtypelabels.push_back(GetRailTypeInfo(rt)->label); + for (RailType rt : e->VehInfo().railtypes) _gted[e->index].railtypelabels.push_back(GetRailTypeInfo(rt)->label); } /* Reset GRM reservations */ @@ -661,7 +661,7 @@ static void CalculateRefitMasks() /* If the NewGRF did not set any cargo properties, we apply default values. */ if (_gted[engine].defaultcargo_grf == nullptr) { /* If the vehicle has any capacity, apply the default refit masks */ - if (e->type != VEH_TRAIN || e->u.rail.capacity != 0) { + if (e->type != VEH_TRAIN || e->VehInfo().capacity != 0) { static constexpr LandscapeType T = LandscapeType::Temperate; static constexpr LandscapeType A = LandscapeType::Arctic; static constexpr LandscapeType S = LandscapeType::Tropic; @@ -716,8 +716,8 @@ static void CalculateRefitMasks() } break; } - e->u.ship.old_refittable = true; - } else if (e->type == VEH_TRAIN && e->u.rail.railveh_type != RAILVEH_WAGON) { + e->VehInfo().old_refittable = true; + } else if (e->type == VEH_TRAIN && e->VehInfo().railveh_type != RAILVEH_WAGON) { /* Train engines default to all cargoes, so you can build single-cargo consists with fast engines. * Trains loading multiple cargoes may start stations accepting unwanted cargoes. */ _gted[engine].cargo_allowed = {CargoClass::Passengers, CargoClass::Mail, CargoClass::Armoured, CargoClass::Express, CargoClass::Bulk, CargoClass::PieceGoods, CargoClass::Liquid}; @@ -792,7 +792,7 @@ static void CalculateRefitMasks() /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes. * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */ - if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && IsValidCargoType(ei->cargo_type) && !HasBit(ei->refit_mask, ei->cargo_type)) { + if (!only_defaultcargo && (e->type != VEH_SHIP || e->VehInfo().old_refittable) && IsValidCargoType(ei->cargo_type) && !HasBit(ei->refit_mask, ei->cargo_type)) { ei->cargo_type = INVALID_CARGO; } @@ -819,7 +819,7 @@ static void CalculateRefitMasks() ei->cargo_type = (CargoType)FindFirstBit(ei->refit_mask); } } - if (!IsValidCargoType(ei->cargo_type) && e->type == VEH_TRAIN && e->u.rail.railveh_type != RAILVEH_WAGON && e->u.rail.capacity == 0) { + if (!IsValidCargoType(ei->cargo_type) && e->type == VEH_TRAIN && e->VehInfo().railveh_type != RAILVEH_WAGON && e->VehInfo().capacity == 0) { /* For train engines which do not carry cargo it does not matter if their cargo type is invalid. * Fallback to the first available instead, if the cargo type has not been changed (as indicated by * cargo_label not being CT_INVALID). */ @@ -830,7 +830,7 @@ static void CalculateRefitMasks() if (!IsValidCargoType(ei->cargo_type)) ei->climates = {}; /* Clear refit_mask for not refittable ships */ - if (e->type == VEH_SHIP && !e->u.ship.old_refittable) { + if (e->type == VEH_SHIP && !e->VehInfo().old_refittable) { ei->refit_mask = 0; } } @@ -867,16 +867,16 @@ static void FinaliseEngineArray() switch (e->type) { case VEH_TRAIN: - for (RailType rt : e->u.rail.railtypes) { + for (RailType rt : e->VehInfo().railtypes) { AppendCopyableBadgeList(e->badges, GetRailTypeInfo(rt)->badges, GSF_TRAINS); } break; - case VEH_ROAD: AppendCopyableBadgeList(e->badges, GetRoadTypeInfo(e->u.road.roadtype)->badges, GSF_ROADVEHICLES); break; + case VEH_ROAD: AppendCopyableBadgeList(e->badges, GetRoadTypeInfo(e->VehInfo().roadtype)->badges, GSF_ROADVEHICLES); break; default: break; } /* Skip wagons, there livery is defined via the engine */ - if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) { + if (e->type != VEH_TRAIN || e->VehInfo().railveh_type != RAILVEH_WAGON) { LiveryScheme ls = GetEngineLiveryScheme(e->index, EngineID::Invalid(), nullptr); SetBit(_loaded_newgrf_features.used_liveries, ls); /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */ @@ -1693,14 +1693,14 @@ static void AfterLoadGRFs() for (Engine *e : Engine::IterateType(VEH_ROAD)) { if (_gted[e->index].rv_max_speed != 0) { /* Set RV maximum speed from the mph/0.8 unit value */ - e->u.road.max_speed = _gted[e->index].rv_max_speed * 4; + e->VehInfo().max_speed = _gted[e->index].rv_max_speed * 4; } RoadTramType rtt = e->info.misc_flags.Test(EngineMiscFlag::RoadIsTram) ? RTT_TRAM : RTT_ROAD; const GRFFile *file = e->GetGRF(); if (file == nullptr || _gted[e->index].roadtramtype == 0) { - e->u.road.roadtype = (rtt == RTT_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD; + e->VehInfo().roadtype = (rtt == RTT_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD; continue; } @@ -1713,7 +1713,7 @@ static void AfterLoadGRFs() RoadTypeLabel rtl = (*list)[_gted[e->index].roadtramtype]; RoadType rt = GetRoadTypeByLabel(rtl); if (rt != INVALID_ROADTYPE && GetRoadTramType(rt) == rtt) { - e->u.road.roadtype = rt; + e->VehInfo().roadtype = rt; continue; } } @@ -1730,8 +1730,8 @@ static void AfterLoadGRFs() } if (railtypes.Any()) { - e->u.rail.railtypes = railtypes; - e->u.rail.intended_railtypes = railtypes; + e->VehInfo().railtypes = railtypes; + e->VehInfo().intended_railtypes = railtypes; } else { /* Rail type is not available, so disable this engine */ e->info.climates = {}; diff --git a/src/newgrf/newgrf_act0_aircraft.cpp b/src/newgrf/newgrf_act0_aircraft.cpp index d246544784a08..d4e7df1298baa 100644 --- a/src/newgrf/newgrf_act0_aircraft.cpp +++ b/src/newgrf/newgrf_act0_aircraft.cpp @@ -35,7 +35,7 @@ static ChangeInfoResult AircraftVehicleChangeInfo(uint first, uint last, int pro if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles EngineInfo *ei = &e->info; - AircraftVehicleInfo *avi = &e->u.air; + AircraftVehicleInfo *avi = &e->VehInfo(); switch (prop) { case 0x08: { // Sprite ID diff --git a/src/newgrf/newgrf_act0_roadvehs.cpp b/src/newgrf/newgrf_act0_roadvehs.cpp index e8cf67f6bb1e2..34fd862c98141 100644 --- a/src/newgrf/newgrf_act0_roadvehs.cpp +++ b/src/newgrf/newgrf_act0_roadvehs.cpp @@ -36,7 +36,7 @@ static ChangeInfoResult RoadVehicleChangeInfo(uint first, uint last, int prop, B if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles EngineInfo *ei = &e->info; - RoadVehicleInfo *rvi = &e->u.road; + RoadVehicleInfo *rvi = &e->VehInfo(); switch (prop) { case 0x05: // Road/tram type diff --git a/src/newgrf/newgrf_act0_ships.cpp b/src/newgrf/newgrf_act0_ships.cpp index 0e1bfe0b178cd..3b9c32b15cfa6 100644 --- a/src/newgrf/newgrf_act0_ships.cpp +++ b/src/newgrf/newgrf_act0_ships.cpp @@ -37,7 +37,7 @@ static ChangeInfoResult ShipVehicleChangeInfo(uint first, uint last, int prop, B if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles EngineInfo *ei = &e->info; - ShipVehicleInfo *svi = &e->u.ship; + ShipVehicleInfo *svi = &e->VehInfo(); switch (prop) { case 0x08: { // Sprite ID diff --git a/src/newgrf/newgrf_act0_trains.cpp b/src/newgrf/newgrf_act0_trains.cpp index 8f8a4c4121bfa..0e44e3a1b5b0a 100644 --- a/src/newgrf/newgrf_act0_trains.cpp +++ b/src/newgrf/newgrf_act0_trains.cpp @@ -35,7 +35,7 @@ ChangeInfoResult RailVehicleChangeInfo(uint first, uint last, int prop, ByteRead if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles EngineInfo *ei = &e->info; - RailVehicleInfo *rvi = &e->u.rail; + RailVehicleInfo *rvi = &e->VehInfo(); switch (prop) { case 0x05: { // Track type diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index 5d1f7ba7fe8e6..c1f355fe1cea5 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -1138,7 +1138,7 @@ static void GetRotorOverrideSprite(EngineID engine, const struct Aircraft *v, En /* Only valid for helicopters */ assert(e->type == VEH_AIRCRAFT); - assert(!(e->u.air.subtype & AIR_CTOL)); + assert(!(e->VehInfo().subtype & AIR_CTOL)); /* We differ from TTDPatch by resolving the sprite using the primary vehicle 'v', and not using the rotor vehicle 'v->Next()->Next()'. * TTDPatch copies some variables between the vehicles each time, to somehow synchronize the rotor vehicle with the primary vehicle. diff --git a/src/rail.cpp b/src/rail.cpp index 852a4dce6f2fb..d9e41087e389d 100644 --- a/src/rail.cpp +++ b/src/rail.cpp @@ -129,7 +129,7 @@ RailTypes GetCompanyRailTypes(CompanyID company, bool introduces) if (ei->climates.Test(_settings_game.game_creation.landscape) && (e->company_avail.Test(company) || TimerGameCalendar::date >= e->intro_date + CalendarTime::DAYS_IN_YEAR)) { - const RailVehicleInfo *rvi = &e->u.rail; + const RailVehicleInfo *rvi = &e->VehInfo(); if (rvi->railveh_type != RAILVEH_WAGON) { assert(rvi->railtypes.Any()); @@ -159,7 +159,7 @@ RailTypes GetRailTypes(bool introduces) const EngineInfo *ei = &e->info; if (!ei->climates.Test(_settings_game.game_creation.landscape)) continue; - const RailVehicleInfo *rvi = &e->u.rail; + const RailVehicleInfo *rvi = &e->VehInfo(); if (rvi->railveh_type != RAILVEH_WAGON) { assert(rvi->railtypes.Any()); if (introduces) { diff --git a/src/road.cpp b/src/road.cpp index 27a6a9bb780d8..5b796f12eaedd 100644 --- a/src/road.cpp +++ b/src/road.cpp @@ -204,7 +204,7 @@ RoadTypes GetCompanyRoadTypes(CompanyID company, bool introduces) if (ei->climates.Test(_settings_game.game_creation.landscape) && (e->company_avail.Test(company) || TimerGameCalendar::date >= e->intro_date + CalendarTime::DAYS_IN_YEAR)) { - const RoadVehicleInfo *rvi = &e->u.road; + const RoadVehicleInfo *rvi = &e->VehInfo(); assert(rvi->roadtype < ROADTYPE_END); if (introduces) { rts.Set(GetRoadTypeInfo(rvi->roadtype)->introduces_roadtypes); @@ -231,7 +231,7 @@ RoadTypes GetRoadTypes(bool introduces) const EngineInfo *ei = &e->info; if (!ei->climates.Test(_settings_game.game_creation.landscape)) continue; - const RoadVehicleInfo *rvi = &e->u.road; + const RoadVehicleInfo *rvi = &e->VehInfo(); assert(rvi->roadtype < ROADTYPE_END); if (introduces) { rts.Set(GetRoadTypeInfo(rvi->roadtype)->introduces_roadtypes); diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 2117b85159294..70717f15b8901 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -105,7 +105,7 @@ int RoadVehicle::GetDisplayImageWidth(Point *offset) const static void GetRoadVehIcon(EngineID engine, EngineImageType image_type, VehicleSpriteSeq *result) { const Engine *e = Engine::Get(engine); - uint8_t spritenum = e->u.road.image_index; + uint8_t spritenum = e->VehInfo().image_index; if (IsCustomVehicleSpriteNum(spritenum)) { GetCustomVehicleIcon(engine, DIR_W, image_type, result); @@ -203,7 +203,7 @@ static uint GetRoadVehLength(const RoadVehicle *v) /* Use callback 11 */ veh_len = GetVehicleCallback(CBID_VEHICLE_LENGTH, 0, 0, v->engine_type, v); } - if (veh_len == CALLBACK_FAILED) veh_len = e->u.road.shorten_factor; + if (veh_len == CALLBACK_FAILED) veh_len = e->VehInfo().shorten_factor; if (veh_len != 0) { length -= Clamp(veh_len, 0, VEHICLE_LENGTH - 1); } @@ -263,12 +263,12 @@ void RoadVehUpdateCache(RoadVehicle *v, bool same_length) CommandCost CmdBuildRoadVehicle(DoCommandFlags flags, TileIndex tile, const Engine *e, Vehicle **ret) { /* Check that the vehicle can drive on the road in question */ - RoadType rt = e->u.road.roadtype; + RoadType rt = e->VehInfo().roadtype; const RoadTypeInfo *rti = GetRoadTypeInfo(rt); if (!HasTileAnyRoadType(tile, rti->powered_roadtypes)) return CommandCost(STR_ERROR_DEPOT_WRONG_DEPOT_TYPE); if (flags.Test(DoCommandFlag::Execute)) { - const RoadVehicleInfo *rvi = &e->u.road; + const RoadVehicleInfo *rvi = &e->VehInfo(); RoadVehicle *v = new RoadVehicle(); *ret = v; @@ -1645,12 +1645,12 @@ static bool RoadVehController(RoadVehicle *v) Money RoadVehicle::GetRunningCost() const { const Engine *e = this->GetEngine(); - if (e->u.road.running_cost_class == INVALID_PRICE) return 0; + if (e->VehInfo().running_cost_class == INVALID_PRICE) return 0; - uint cost_factor = GetVehicleProperty(this, PROP_ROADVEH_RUNNING_COST_FACTOR, e->u.road.running_cost); + uint cost_factor = GetVehicleProperty(this, PROP_ROADVEH_RUNNING_COST_FACTOR, e->VehInfo().running_cost); if (cost_factor == 0) return 0; - return GetPrice(e->u.road.running_cost_class, cost_factor, e->GetGRF()); + return GetPrice(e->VehInfo().running_cost_class, cost_factor, e->GetGRF()); } bool RoadVehicle::Tick() diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 51ef51069d763..3532c6ce8706e 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -439,7 +439,7 @@ void AfterLoadVehiclesPhase2(bool part_of_load) if (rv->IsFrontEngine()) { rv->gcache.last_speed = rv->cur_speed; // update displayed road vehicle speed - rv->roadtype = Engine::Get(rv->engine_type)->u.road.roadtype; + rv->roadtype = Engine::Get(rv->engine_type)->VehInfo().roadtype; rv->compatible_roadtypes = GetRoadTypeInfo(rv->roadtype)->powered_roadtypes; RoadTramType rtt = GetRoadTramType(rv->roadtype); for (RoadVehicle *u = rv; u != nullptr; u = u->Next()) { diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 434f85276317b..2591099c95382 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -81,7 +81,7 @@ static inline TrackBits GetTileShipTrackStatus(TileIndex tile) static void GetShipIcon(EngineID engine, EngineImageType image_type, VehicleSpriteSeq *result) { const Engine *e = Engine::Get(engine); - uint8_t spritenum = e->u.ship.image_index; + uint8_t spritenum = e->VehInfo().image_index; if (IsCustomVehicleSpriteNum(spritenum)) { GetCustomVehicleIcon(engine, DIR_W, image_type, result); @@ -247,7 +247,7 @@ void Ship::UpdateCache() Money Ship::GetRunningCost() const { const Engine *e = this->GetEngine(); - uint cost_factor = GetVehicleProperty(this, PROP_SHIP_RUNNING_COST_FACTOR, e->u.ship.running_cost); + uint cost_factor = GetVehicleProperty(this, PROP_SHIP_RUNNING_COST_FACTOR, e->VehInfo().running_cost); return GetPrice(PR_RUNNING_SHIP, cost_factor, e->GetGRF()); } @@ -886,7 +886,7 @@ CommandCost CmdBuildShip(DoCommandFlags flags, TileIndex tile, const Engine *e, int x; int y; - const ShipVehicleInfo *svi = &e->u.ship; + const ShipVehicleInfo *svi = &e->VehInfo(); Ship *v = new Ship(); *ret = v; diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 93a5483cfc40c..136f321c717fd 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -146,7 +146,7 @@ void Train::ConsistChanged(ConsistChangeFlags allowed_changes) for (Train *u = this; u != nullptr; u = u->Next()) { const Engine *e_u = u->GetEngine(); - const RailVehicleInfo *rvi_u = &e_u->u.rail; + const RailVehicleInfo *rvi_u = &e_u->VehInfo(); if (!e_u->info.misc_flags.Test(EngineMiscFlag::RailTilts)) train_can_tilt = false; min_curve_speed_mod = std::min(min_curve_speed_mod, u->GetCurveSpeedModifier()); @@ -441,7 +441,7 @@ int Train::GetCursorImageOffset() const int reference_width = TRAININFO_DEFAULT_VEHICLE_WIDTH; const Engine *e = this->GetEngine(); - if (e->GetGRF() != nullptr && IsCustomVehicleSpriteNum(e->u.rail.image_index)) { + if (e->GetGRF() != nullptr && IsCustomVehicleSpriteNum(e->VehInfo().image_index)) { reference_width = e->GetGRF()->traininfo_vehicle_width; } @@ -461,7 +461,7 @@ int Train::GetDisplayImageWidth(Point *offset) const int vehicle_pitch = 0; const Engine *e = this->GetEngine(); - if (e->GetGRF() != nullptr && IsCustomVehicleSpriteNum(e->u.rail.image_index)) { + if (e->GetGRF() != nullptr && IsCustomVehicleSpriteNum(e->VehInfo().image_index)) { reference_width = e->GetGRF()->traininfo_vehicle_width; vehicle_pitch = e->GetGRF()->traininfo_vehicle_pitch; } @@ -515,7 +515,7 @@ static void GetRailIcon(EngineID engine, bool rear_head, int &y, EngineImageType { const Engine *e = Engine::Get(engine); Direction dir = rear_head ? DIR_E : DIR_W; - uint8_t spritenum = e->u.rail.image_index; + uint8_t spritenum = e->VehInfo().image_index; if (IsCustomVehicleSpriteNum(spritenum)) { GetCustomVehicleIcon(engine, dir, image_type, result); @@ -636,7 +636,7 @@ static std::vector GetFreeWagonsInDepot(TileIndex tile) */ static CommandCost CmdBuildRailWagon(DoCommandFlags flags, TileIndex tile, const Engine *e, Vehicle **ret) { - const RailVehicleInfo *rvi = &e->u.rail; + const RailVehicleInfo *rvi = &e->VehInfo(); /* Check that the wagon can drive on the track in question */ if (!IsCompatibleRail(rvi->railtypes, GetRailType(tile))) return CMD_ERROR; @@ -770,7 +770,7 @@ static void AddRearEngineToMultiheadedTrain(Train *v) */ CommandCost CmdBuildRailVehicle(DoCommandFlags flags, TileIndex tile, const Engine *e, Vehicle **ret) { - const RailVehicleInfo *rvi = &e->u.rail; + const RailVehicleInfo *rvi = &e->VehInfo(); if (rvi->railveh_type == RAILVEH_WAGON) return CmdBuildRailWagon(flags, tile, e, ret); @@ -4074,15 +4074,15 @@ Money Train::GetRunningCost() const do { const Engine *e = v->GetEngine(); - if (e->u.rail.running_cost_class == INVALID_PRICE) continue; + if (e->VehInfo().running_cost_class == INVALID_PRICE) continue; - uint cost_factor = GetVehicleProperty(v, PROP_TRAIN_RUNNING_COST_FACTOR, e->u.rail.running_cost); + uint cost_factor = GetVehicleProperty(v, PROP_TRAIN_RUNNING_COST_FACTOR, e->VehInfo().running_cost); if (cost_factor == 0) continue; /* Halve running cost for multiheaded parts */ if (v->IsMultiheaded()) cost_factor /= 2; - cost += GetPrice(e->u.rail.running_cost_class, cost_factor, e->GetGRF()); + cost += GetPrice(e->VehInfo().running_cost_class, cost_factor, e->GetGRF()); } while ((v = v->GetNextVehicle()) != nullptr); return cost; diff --git a/src/vehicle.cpp b/src/vehicle.cpp index e6573b372682c..bb1973e56edd2 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -1925,7 +1925,7 @@ bool CanBuildVehicleInfrastructure(VehicleType type, uint8_t subtype) if (max > 0) { /* Can we actually build the vehicle type? */ for (const Engine *e : Engine::IterateType(type)) { - if (type == VEH_ROAD && GetRoadTramType(e->u.road.roadtype) != (RoadTramType)subtype) continue; + if (type == VEH_ROAD && GetRoadTramType(e->VehInfo().roadtype) != (RoadTramType)subtype) continue; if (e->company_avail.Test(_local_company)) return true; } return false; @@ -1955,7 +1955,7 @@ LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_ switch (e->type) { default: NOT_REACHED(); case VEH_TRAIN: - if (v != nullptr && parent_engine_type != EngineID::Invalid() && (UsesWagonOverride(v) || (v->IsArticulatedPart() && e->u.rail.railveh_type != RAILVEH_WAGON))) { + if (v != nullptr && parent_engine_type != EngineID::Invalid() && (UsesWagonOverride(v) || (v->IsArticulatedPart() && e->VehInfo().railveh_type != RAILVEH_WAGON))) { /* Wagonoverrides use the colour scheme of the front engine. * Articulated parts use the colour scheme of the first part. (Not supported for articulated wagons) */ engine_type = parent_engine_type; @@ -1966,7 +1966,7 @@ LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_ if (!IsValidCargoType(cargo_type)) cargo_type = e->GetDefaultCargoType(); if (!IsValidCargoType(cargo_type)) cargo_type = GetCargoTypeByLabel(CT_GOODS); // The vehicle does not carry anything, let's pick some freight cargo assert(IsValidCargoType(cargo_type)); - if (e->u.rail.railveh_type == RAILVEH_WAGON) { + if (e->VehInfo().railveh_type == RAILVEH_WAGON) { if (!CargoSpec::Get(cargo_type)->is_freight) { if (parent_engine_type == EngineID::Invalid()) { return LS_PASSENGER_WAGON_STEAM; @@ -1987,7 +1987,7 @@ LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_ } else { bool is_mu = e->info.misc_flags.Test(EngineMiscFlag::RailIsMU); - switch (e->u.rail.engclass) { + switch (e->VehInfo().engclass) { default: NOT_REACHED(); case EC_STEAM: return LS_STEAM; case EC_DIESEL: return is_mu ? LS_DMU : LS_DIESEL; @@ -2024,7 +2024,7 @@ LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_ return IsCargoInClass(cargo_type, CargoClass::Passengers) ? LS_PASSENGER_SHIP : LS_FREIGHT_SHIP; case VEH_AIRCRAFT: - switch (e->u.air.subtype) { + switch (e->VehInfo().subtype) { case AIR_HELI: return LS_HELICOPTER; case AIR_CTOL: return LS_SMALL_PLANE; case AIR_CTOL | AIR_FAST: return LS_LARGE_PLANE; @@ -2641,9 +2641,9 @@ void Vehicle::UpdateVisualEffect(bool allow_power_change) /* Evaluate properties */ uint8_t visual_effect; switch (e->type) { - case VEH_TRAIN: visual_effect = e->u.rail.visual_effect; break; - case VEH_ROAD: visual_effect = e->u.road.visual_effect; break; - case VEH_SHIP: visual_effect = e->u.ship.visual_effect; break; + case VEH_TRAIN: visual_effect = e->VehInfo().visual_effect; break; + case VEH_ROAD: visual_effect = e->VehInfo().visual_effect; break; + case VEH_SHIP: visual_effect = e->VehInfo().visual_effect; break; default: visual_effect = 1 << VE_DISABLE_EFFECT; break; } @@ -2670,7 +2670,7 @@ void Vehicle::UpdateVisualEffect(bool allow_power_change) (!HasBit(visual_effect, VE_DISABLE_EFFECT) && GB(visual_effect, VE_TYPE_START, VE_TYPE_COUNT) == VE_TYPE_DEFAULT)) { /* Only train engines have default effects. * Note: This is independent of whether the engine is a front engine or articulated part or whatever. */ - if (e->type != VEH_TRAIN || e->u.rail.railveh_type == RAILVEH_WAGON || !IsInsideMM(e->u.rail.engclass, EC_STEAM, EC_MONORAIL)) { + if (e->type != VEH_TRAIN || e->VehInfo().railveh_type == RAILVEH_WAGON || !IsInsideMM(e->VehInfo().engclass, EC_STEAM, EC_MONORAIL)) { if (visual_effect == VE_DEFAULT) { visual_effect = 1 << VE_DISABLE_EFFECT; } else { @@ -2679,9 +2679,9 @@ void Vehicle::UpdateVisualEffect(bool allow_power_change) } else { if (visual_effect == VE_DEFAULT) { /* Also set the offset */ - visual_effect = (VE_OFFSET_CENTRE - (e->u.rail.engclass == EC_STEAM ? 4 : 0)) << VE_OFFSET_START; + visual_effect = (VE_OFFSET_CENTRE - (e->VehInfo().engclass == EC_STEAM ? 4 : 0)) << VE_OFFSET_START; } - SB(visual_effect, VE_TYPE_START, VE_TYPE_COUNT, e->u.rail.engclass - EC_STEAM + VE_TYPE_STEAM); + SB(visual_effect, VE_TYPE_START, VE_TYPE_COUNT, e->VehInfo().engclass - EC_STEAM + VE_TYPE_STEAM); } } @@ -3063,7 +3063,7 @@ bool CanVehicleUseStation(EngineID engine_type, const Station *st) case VEH_AIRCRAFT: return st->facilities.Test(StationFacility::Airport) && - st->airport.GetFTA()->flags.Test(e->u.air.subtype & AIR_CTOL ? AirportFTAClass::Flag::Airplanes : AirportFTAClass::Flag::Helicopters); + st->airport.GetFTA()->flags.Test(e->VehInfo().subtype & AIR_CTOL ? AirportFTAClass::Flag::Airplanes : AirportFTAClass::Flag::Helicopters); default: return false; @@ -3124,7 +3124,7 @@ StringID GetVehicleCannotUseStationReason(const Vehicle *v, const Station *st) case VEH_AIRCRAFT: if (!st->facilities.Test(StationFacility::Airport)) return STR_ERROR_NO_AIRPORT; - if (v->GetEngine()->u.air.subtype & AIR_CTOL) { + if (v->GetEngine()->VehInfo().subtype & AIR_CTOL) { return STR_ERROR_AIRPORT_NO_PLANES; } else { return STR_ERROR_AIRPORT_NO_HELICOPTERS; diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 8fe5ec0f6d906..aef3b4f246ac7 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -64,26 +64,6 @@ struct NewGRFCache { auto operator<=>(const NewGRFCache &) const = default; }; -/** Meaning of the various bits of the visual effect. */ -enum VisualEffect : uint8_t { - VE_OFFSET_START = 0, ///< First bit that contains the offset (0 = front, 8 = centre, 15 = rear) - VE_OFFSET_COUNT = 4, ///< Number of bits used for the offset - VE_OFFSET_CENTRE = 8, ///< Value of offset corresponding to a position above the centre of the vehicle - - VE_TYPE_START = 4, ///< First bit used for the type of effect - VE_TYPE_COUNT = 2, ///< Number of bits used for the effect type - VE_TYPE_DEFAULT = 0, ///< Use default from engine class - VE_TYPE_STEAM = 1, ///< Steam plumes - VE_TYPE_DIESEL = 2, ///< Diesel fumes - VE_TYPE_ELECTRIC = 3, ///< Electric sparks - - VE_DISABLE_EFFECT = 6, ///< Flag to disable visual effect - VE_ADVANCED_EFFECT = VE_DISABLE_EFFECT, ///< Flag for advanced effects - VE_DISABLE_WAGON_POWER = 7, ///< Flag to disable wagon power - - VE_DEFAULT = 0xFF, ///< Default value to indicate that visual effect should be based on engine class -}; - /** Models for spawning visual effects. */ enum VisualEffectSpawnModel : uint8_t { VESM_NONE = 0, ///< No visual effect diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index c27fb92ded52a..c5a93b0f37250 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -122,10 +122,10 @@ std::tuple CmdBuildVehicle(D /* Check whether the number of vehicles we need to build can be built according to pool space. */ uint num_vehicles; switch (type) { - case VEH_TRAIN: num_vehicles = (e->u.rail.railveh_type == RAILVEH_MULTIHEAD ? 2 : 1) + CountArticulatedParts(eid, false); break; + case VEH_TRAIN: num_vehicles = (e->VehInfo().railveh_type == RAILVEH_MULTIHEAD ? 2 : 1) + CountArticulatedParts(eid, false); break; case VEH_ROAD: num_vehicles = 1 + CountArticulatedParts(eid, false); break; case VEH_SHIP: num_vehicles = 1; break; - case VEH_AIRCRAFT: num_vehicles = e->u.air.subtype & AIR_CTOL ? 2 : 3; break; + case VEH_AIRCRAFT: num_vehicles = e->VehInfo().subtype & AIR_CTOL ? 2 : 3; break; default: NOT_REACHED(); // Safe due to IsDepotTile() } if (!Vehicle::CanAllocateItem(num_vehicles)) return { CommandCost(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME), VehicleID::Invalid(), 0, 0, {} }; @@ -133,7 +133,7 @@ std::tuple CmdBuildVehicle(D /* Check whether we can allocate a unit number. Autoreplace does not allocate * an unit number as it will (always) reuse the one of the replaced vehicle * and (train) wagons don't have an unit number in any scenario. */ - UnitID unit_num = (flags.Test(DoCommandFlag::QueryCost) || flags.Test(DoCommandFlag::AutoReplace) || (type == VEH_TRAIN && e->u.rail.railveh_type == RAILVEH_WAGON)) ? 0 : GetFreeUnitNumber(type); + UnitID unit_num = (flags.Test(DoCommandFlag::QueryCost) || flags.Test(DoCommandFlag::AutoReplace) || (type == VEH_TRAIN && e->VehInfo().railveh_type == RAILVEH_WAGON)) ? 0 : GetFreeUnitNumber(type); if (unit_num == UINT16_MAX) return { CommandCost(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME), VehicleID::Invalid(), 0, 0, {} }; /* If we are refitting we need to temporarily purchase the vehicle to be able to @@ -325,7 +325,7 @@ static CommandCost GetRefitCost(const Vehicle *v, EngineID engine_type, CargoTyp break; case VEH_TRAIN: - base_price = (e->u.rail.railveh_type == RAILVEH_WAGON) ? PR_BUILD_VEHICLE_WAGON : PR_BUILD_VEHICLE_TRAIN; + base_price = (e->VehInfo().railveh_type == RAILVEH_WAGON) ? PR_BUILD_VEHICLE_WAGON : PR_BUILD_VEHICLE_TRAIN; cost_factor <<= 1; expense_type = EXPENSES_TRAIN_RUN; break; From 80e58e751aafdd033abae43b72b7dbd827deafe3 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Wed, 24 Sep 2025 22:45:18 +0100 Subject: [PATCH 022/137] Fix #14607: Bridge-over-station discrepancy depending on build order. (#14608) When building a custom station, the callback-derived tile layout is ignored during the bridge height test. This caused a discrepancy between building a station under a bridge vs building a bridge over the same station. Test the station tile layout callback during the bridge height test. --- src/station_cmd.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index ce85d755e2cd7..c9a3924f87353 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -1480,14 +1480,23 @@ CommandCost CmdBuildRailStation(DoCommandFlags flags, TileIndex tile_org, RailTy RailStationTileLayout stl{statspec, numtracks, plat_len}; auto it = stl.begin(); TileIndex tile_track = tile_org; - for (uint i = 0; i != numtracks; ++i) { + for (uint i = 0; i != numtracks; ++i, tile_track += track_delta) { TileIndex tile = tile_track; - for (uint j = 0; j != plat_len; ++j) { - ret = IsRailStationBridgeAboveOk(tile, statspec, StationType::Rail, *it++ + axis); + for (uint j = 0; j != plat_len; ++j, tile += tile_delta, ++it) { + /* Don't check the layout if there's no bridge above anyway. */ + if (!IsBridgeAbove(tile)) continue; + + StationGfx gfx = *it + axis; + if (statspec != nullptr) { + uint32_t platinfo = GetPlatformInfo(AXIS_X, gfx, plat_len, numtracks, j, i, false); + /* As the station is not yet completely finished, the station does not yet exist. */ + uint16_t callback = GetStationCallback(CBID_STATION_BUILD_TILE_LAYOUT, platinfo, 0, statspec, nullptr, tile); + if (callback != CALLBACK_FAILED && callback <= UINT8_MAX) gfx = (callback & ~1) + axis; + } + + ret = IsRailStationBridgeAboveOk(tile, statspec, StationType::Rail, gfx); if (ret.Failed()) return ret; - tile += tile_delta; } - tile_track += track_delta; } /* Check if we can allocate a custom stationspec to this station */ From 6401855842d3daafcfd9c45c5c346ba87d396d36 Mon Sep 17 00:00:00 2001 From: Kuhnovic <68320206+Kuhnovic@users.noreply.github.com> Date: Fri, 26 Sep 2025 10:04:50 +0200 Subject: [PATCH 023/137] Fix bff8501: Gcc 15 warns about duplicate type. (#14660) --- src/pathfinder/yapf/yapf_river_builder.cpp | 8 ++++---- src/pathfinder/yapf/yapf_ship_regions.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pathfinder/yapf/yapf_river_builder.cpp b/src/pathfinder/yapf/yapf_river_builder.cpp index 697ddd2e8fadd..d61e1aaa376dc 100644 --- a/src/pathfinder/yapf/yapf_river_builder.cpp +++ b/src/pathfinder/yapf/yapf_river_builder.cpp @@ -22,7 +22,7 @@ struct YapfRiverBuilderNode : CYapfNodeT; /* We don't need a follower but YAPF requires one. */ -struct DummyFollower {}; +struct RiverBuilderFollower {}; /* We don't need a vehicle but YAPF requires one. */ struct DummyVehicle : Vehicle {}; @@ -32,7 +32,7 @@ class YapfRiverBuilder; /* Types struct required for YAPF components. */ struct RiverBuilderTypes { using Tpf = YapfRiverBuilder; - using TrackFollower = DummyFollower; + using TrackFollower = RiverBuilderFollower; using NodeList = RiverBuilderNodeList; using VehicleType = DummyVehicle; }; @@ -74,7 +74,7 @@ class YapfRiverBuilder return n.GetTile() == this->end_tile; } - inline bool PfCalcCost(Node &n, const DummyFollower *) + inline bool PfCalcCost(Node &n, const RiverBuilderFollower *) { n.cost = n.parent->cost + 1 + RandomRange(_settings_game.game_creation.river_route_random); return true; @@ -94,7 +94,7 @@ class YapfRiverBuilder if (IsValidTile(t) && RiverFlowsDown(old_node.GetTile(), t)) { Node &node = Yapf().CreateNewNode(); node.Set(&old_node, t, INVALID_TRACKDIR, true); - Yapf().AddNewNode(node, DummyFollower{}); + Yapf().AddNewNode(node, RiverBuilderFollower{}); } } } diff --git a/src/pathfinder/yapf/yapf_ship_regions.cpp b/src/pathfinder/yapf/yapf_ship_regions.cpp index 089fde6073d84..ac0a52aac4a38 100644 --- a/src/pathfinder/yapf/yapf_ship_regions.cpp +++ b/src/pathfinder/yapf/yapf_ship_regions.cpp @@ -76,14 +76,14 @@ struct WaterRegionNode : CYapfNodeT { using WaterRegionNodeList = NodeList; /* We don't need a follower but YAPF requires one. */ -struct DummyFollower : public CFollowTrackWater {}; +struct WaterRegionFollower : public CFollowTrackWater {}; class YapfShipRegions; /* Types struct required for YAPF internals. */ struct WaterRegionTypes { using Tpf = YapfShipRegions; - using TrackFollower = DummyFollower; + using TrackFollower = WaterRegionFollower; using NodeList = WaterRegionNodeList; using VehicleType = Ship; }; From f4f1beba64cdb13c66a08118055933c266bd8a83 Mon Sep 17 00:00:00 2001 From: Kuhnovic <68320206+Kuhnovic@users.noreply.github.com> Date: Fri, 26 Sep 2025 11:37:50 +0200 Subject: [PATCH 024/137] Codechange: Moved PruneIntermediateNodeBranch to rail pathfinder. (#14662) --- src/pathfinder/yapf/yapf_base.hpp | 18 ---------------- src/pathfinder/yapf/yapf_rail.cpp | 35 +++++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/pathfinder/yapf/yapf_base.hpp b/src/pathfinder/yapf/yapf_base.hpp index f8888e1364ce1..2c8a728953fdc 100644 --- a/src/pathfinder/yapf/yapf_base.hpp +++ b/src/pathfinder/yapf/yapf_base.hpp @@ -185,24 +185,6 @@ class CYapfBaseT { } } - /** - * In some cases an intermediate node branch should be pruned. - * The most prominent case is when a red EOL signal is encountered, but - * there was a segment change (e.g. a rail type change) before that. If - * the branch would not be pruned, the rail type change location would - * remain the best intermediate node, and thus the vehicle would still - * go towards the red EOL signal. - */ - void PruneIntermediateNodeBranch(Node *n) - { - bool intermediate_on_branch = false; - while (n != nullptr && !n->segment->end_segment_reason.Test(EndSegmentReason::ChoiceFollows)) { - if (n == Yapf().best_intermediate_node) intermediate_on_branch = true; - n = n->parent; - } - if (intermediate_on_branch) Yapf().best_intermediate_node = n; - } - /** * AddNewNode() - called by Tderived::PfFollowNode() for each child node. * Nodes are evaluated here and added into open list diff --git a/src/pathfinder/yapf/yapf_rail.cpp b/src/pathfinder/yapf/yapf_rail.cpp index 208b65b737188..4d22118be579b 100644 --- a/src/pathfinder/yapf/yapf_rail.cpp +++ b/src/pathfinder/yapf/yapf_rail.cpp @@ -544,14 +544,37 @@ struct CYapfRail_TypesT { typedef CYapfCostRailT PfCost; }; -struct CYapfRail : CYapfT> {}; -struct CYapfRailNo90 : CYapfT> {}; +template +struct CYapfRailBase : CYapfT { + typedef typename Types::NodeList::Item Node; -struct CYapfAnyDepotRail : CYapfT> {}; -struct CYapfAnyDepotRailNo90 : CYapfT> {}; + /** + * In some cases an intermediate node branch should be pruned. + * The most prominent case is when a red EOL signal is encountered, but + * there was a segment change (e.g. a rail type change) before that. If + * the branch would not be pruned, the rail type change location would + * remain the best intermediate node, and thus the vehicle would still + * go towards the red EOL signal. + */ + void PruneIntermediateNodeBranch(Node *n) + { + bool intermediate_on_branch = false; + while (n != nullptr && !n->segment->end_segment_reason.Test(EndSegmentReason::ChoiceFollows)) { + if (n == this->best_intermediate_node) intermediate_on_branch = true; + n = n->parent; + } + if (intermediate_on_branch) this->best_intermediate_node = n; + } +}; + +struct CYapfRail : CYapfRailBase> {}; +struct CYapfRailNo90 : CYapfRailBase> {}; + +struct CYapfAnyDepotRail : CYapfRailBase> {}; +struct CYapfAnyDepotRailNo90 : CYapfRailBase> {}; -struct CYapfAnySafeTileRail : CYapfT> {}; -struct CYapfAnySafeTileRailNo90 : CYapfT> {}; +struct CYapfAnySafeTileRail : CYapfRailBase> {}; +struct CYapfAnySafeTileRailNo90 : CYapfRailBase> {}; Track YapfTrainChooseTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool reserve_track, PBSTileInfo *target, TileIndex *dest) From aa6fb0e9e519200715903dc29a26075ce2eb4d2b Mon Sep 17 00:00:00 2001 From: Kuhnovic <68320206+Kuhnovic@users.noreply.github.com> Date: Fri, 26 Sep 2025 13:35:11 +0200 Subject: [PATCH 025/137] Codechange: Simplified logic of ship leaving a depot. (#14661) --- src/ship_cmd.cpp | 40 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 2591099c95382..f741c93f8a986 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -359,7 +359,12 @@ static bool CheckReverseShip(const Ship *v, Trackdir *trackdir = nullptr) return YapfShipCheckReverse(v, trackdir); } -static bool CheckShipLeaveDepot(Ship *v) +/** + * Checks whether a ship should stay in the depot. + * @param v Ship to check. + * @return True if the ship should stay in the depot, false if it has to leave. + */ +static bool CheckShipStayInDepot(Ship *v) { if (!v->IsChainInDepot()) return false; @@ -382,34 +387,13 @@ static bool CheckShipLeaveDepot(Ship *v) return u->type == VEH_SHIP && u->cur_speed != 0; })) return true; - TileIndex tile = v->tile; - Axis axis = GetShipDepotAxis(tile); - - DiagDirection north_dir = ReverseDiagDir(AxisToDiagDir(axis)); - TileIndex north_neighbour = TileAdd(tile, TileOffsByDiagDir(north_dir)); - DiagDirection south_dir = AxisToDiagDir(axis); - TileIndex south_neighbour = TileAdd(tile, 2 * TileOffsByDiagDir(south_dir)); - - TrackBits north_tracks = DiagdirReachesTracks(north_dir) & GetTileShipTrackStatus(north_neighbour); - TrackBits south_tracks = DiagdirReachesTracks(south_dir) & GetTileShipTrackStatus(south_neighbour); - if (north_tracks && south_tracks) { - if (CheckReverseShip(v)) north_tracks = TRACK_BIT_NONE; - } + assert(v->GetVehicleTrackdir() == TRACKDIR_X_NE || v->GetVehicleTrackdir() == TRACKDIR_Y_NW); + v->direction = DiagDirToDir(TrackdirToExitdir(v->GetVehicleTrackdir())); + if (CheckReverseShip(v)) v->direction = ReverseDir(v->direction); - if (north_tracks) { - /* Leave towards north */ - v->rotation = v->direction = DiagDirToDir(north_dir); - } else if (south_tracks) { - /* Leave towards south */ - v->rotation = v->direction = DiagDirToDir(south_dir); - } else { - /* Both ways blocked */ - return false; - } - - v->state = AxisToTrackBits(axis); + v->state = AxisToTrackBits(GetShipDepotAxis(v->tile)); + v->rotation = v->direction; v->vehstatus.Reset(VehState::Hidden); - v->cur_speed = 0; v->UpdateViewport(true, true); SetWindowDirty(WC_VEHICLE_DEPOT, v->tile); @@ -698,7 +682,7 @@ static void ShipController(Ship *v) if (v->current_order.IsType(OT_LOADING)) return; - if (CheckShipLeaveDepot(v)) return; + if (CheckShipStayInDepot(v)) return; v->ShowVisualEffect(); From 5822c8cc6555f1635d236777cd3e9db33be2aacb Mon Sep 17 00:00:00 2001 From: Kuhnovic <68320206+Kuhnovic@users.noreply.github.com> Date: Fri, 26 Sep 2025 16:33:20 +0200 Subject: [PATCH 026/137] Codechange: Set YAPF startup nodes directly. (#14663) --- src/pathfinder/yapf/yapf_base.hpp | 12 ++--- src/pathfinder/yapf/yapf_common.hpp | 57 ++++++---------------- src/pathfinder/yapf/yapf_river_builder.cpp | 7 +-- src/pathfinder/yapf/yapf_ship_regions.cpp | 16 +++--- 4 files changed, 28 insertions(+), 64 deletions(-) diff --git a/src/pathfinder/yapf/yapf_base.hpp b/src/pathfinder/yapf/yapf_base.hpp index 2c8a728953fdc..9bb84488d52b3 100644 --- a/src/pathfinder/yapf/yapf_base.hpp +++ b/src/pathfinder/yapf/yapf_base.hpp @@ -35,7 +35,6 @@ * Requirements to your pathfinder class derived from CYapfBaseT: * -------------------------------------------------------------- * Your pathfinder derived class needs to implement following methods: - * inline void PfSetStartupNodes() * inline void PfFollowNode(Node &org) * inline bool PfCalcCost(Node &n) * inline bool PfCalcEstimate(Node &n) @@ -104,8 +103,6 @@ class CYapfBaseT { { this->vehicle = v; - Yapf().PfSetStartupNodes(); - for (;;) { this->num_steps++; Node *best_open_node = this->nodes.GetBestOpenNode(); @@ -162,14 +159,13 @@ class CYapfBaseT { /** Add new node (created by CreateNewNode and filled with data) into open list */ inline void AddStartupNode(Node &n) { + assert(n.parent == nullptr); + assert(this->num_steps == 0); + Yapf().PfNodeCacheFetch(n); /* insert the new node only if it is not there */ if (this->nodes.FindOpenNode(n.key) == nullptr) { this->nodes.InsertOpenNode(n); - } else { - /* if we are here, it means that node is already there - how it is possible? - * probably the train is in the position that both its ends point to the same tile/exit-dir - * very unlikely, but it happened */ } } @@ -191,6 +187,8 @@ class CYapfBaseT { */ void AddNewNode(Node &n, const TrackFollower &tf) { + assert(n.parent != nullptr); + /* evaluate the node */ bool cached = Yapf().PfNodeCacheFetch(n); if (!cached) { diff --git a/src/pathfinder/yapf/yapf_common.hpp b/src/pathfinder/yapf/yapf_common.hpp index 7f358dcd33ad6..538f3bd3bfb75 100644 --- a/src/pathfinder/yapf/yapf_common.hpp +++ b/src/pathfinder/yapf/yapf_common.hpp @@ -23,9 +23,6 @@ class CYapfOriginTileT { typedef typename Node::Key Key; ///< key to hash tables protected: - TileIndex origin_tile; ///< origin tile - TrackdirBits origin_trackdirs; ///< origin trackdir mask - /** to access inherited path finder */ inline Tpf &Yapf() { @@ -36,19 +33,12 @@ class CYapfOriginTileT { /** Set origin tile / trackdir mask */ void SetOrigin(TileIndex tile, TrackdirBits trackdirs) { - this->origin_tile = tile; - this->origin_trackdirs = trackdirs; - } - - /** Called when YAPF needs to place origin nodes into open list */ - void PfSetStartupNodes() - { - bool is_choice = (KillFirstBit(this->origin_trackdirs) != TRACKDIR_BIT_NONE); - for (TrackdirBits tdb = this->origin_trackdirs; tdb != TRACKDIR_BIT_NONE; tdb = KillFirstBit(tdb)) { + bool is_choice = (KillFirstBit(trackdirs) != TRACKDIR_BIT_NONE); + for (TrackdirBits tdb = trackdirs; tdb != TRACKDIR_BIT_NONE; tdb = KillFirstBit(tdb)) { Trackdir td = (Trackdir)FindFirstBit(tdb); - Node &n1 = Yapf().CreateNewNode(); - n1.Set(nullptr, this->origin_tile, td, is_choice); - Yapf().AddStartupNode(n1); + Node &node = Yapf().CreateNewNode(); + node.Set(nullptr, tile, td, is_choice); + Yapf().AddStartupNode(node); } } }; @@ -62,12 +52,6 @@ class CYapfOriginTileTwoWayT { typedef typename Node::Key Key; ///< key to hash tables protected: - TileIndex origin_tile; ///< first origin tile - Trackdir origin_td; ///< first origin trackdir - TileIndex reverse_tile; ///< second (reverse) origin tile - Trackdir reverse_td; ///< second (reverse) origin trackdir - int reverse_penalty; ///< penalty to be added for using the reverse origin - /** to access inherited path finder */ inline Tpf &Yapf() { @@ -76,28 +60,19 @@ class CYapfOriginTileTwoWayT { public: /** set origin (tiles, trackdirs, etc.) */ - void SetOrigin(TileIndex tile, Trackdir td, TileIndex tiler = INVALID_TILE, Trackdir tdr = INVALID_TRACKDIR, int reverse_penalty = 0) - { - this->origin_tile = tile; - this->origin_td = td; - this->reverse_tile = tiler; - this->reverse_td = tdr; - this->reverse_penalty = reverse_penalty; - } - - /** Called when YAPF needs to place origin nodes into open list */ - void PfSetStartupNodes() + void SetOrigin(TileIndex forward_tile, Trackdir forward_td, TileIndex reverse_tile = INVALID_TILE, + Trackdir reverse_td = INVALID_TRACKDIR, int reverse_penalty = 0) { - if (this->origin_tile != INVALID_TILE && this->origin_td != INVALID_TRACKDIR) { - Node &n1 = Yapf().CreateNewNode(); - n1.Set(nullptr, this->origin_tile, this->origin_td, false); - Yapf().AddStartupNode(n1); + if (forward_tile != INVALID_TILE && forward_td != INVALID_TRACKDIR) { + Node &node = Yapf().CreateNewNode(); + node.Set(nullptr, forward_tile, forward_td, false); + Yapf().AddStartupNode(node); } - if (this->reverse_tile != INVALID_TILE && this->reverse_td != INVALID_TRACKDIR) { - Node &n2 = Yapf().CreateNewNode(); - n2.Set(nullptr, this->reverse_tile, this->reverse_td, false); - n2.cost = this->reverse_penalty; - Yapf().AddStartupNode(n2); + if (reverse_tile != INVALID_TILE && reverse_td != INVALID_TRACKDIR) { + Node &node = Yapf().CreateNewNode(); + node.Set(nullptr, reverse_tile, reverse_td, false); + node.cost = reverse_penalty; + Yapf().AddStartupNode(node); } } }; diff --git a/src/pathfinder/yapf/yapf_river_builder.cpp b/src/pathfinder/yapf/yapf_river_builder.cpp index d61e1aaa376dc..c084f841c94d7 100644 --- a/src/pathfinder/yapf/yapf_river_builder.cpp +++ b/src/pathfinder/yapf/yapf_river_builder.cpp @@ -47,7 +47,6 @@ class YapfRiverBuilder using Key = Node::Key; protected: - TileIndex start_tile; ///< Start tile of the river TileIndex end_tile; ///< End tile of the river inline YapfRiverBuilder &Yapf() @@ -58,14 +57,10 @@ class YapfRiverBuilder public: YapfRiverBuilder(TileIndex start_tile, TileIndex end_tile) { - this->start_tile = start_tile; this->end_tile = end_tile; - } - void PfSetStartupNodes() - { Node &node = Yapf().CreateNewNode(); - node.Set(nullptr, this->start_tile, INVALID_TRACKDIR, false); + node.Set(nullptr, start_tile, INVALID_TRACKDIR, false); Yapf().AddStartupNode(node); } diff --git a/src/pathfinder/yapf/yapf_ship_regions.cpp b/src/pathfinder/yapf/yapf_ship_regions.cpp index ac0a52aac4a38..caa243fc10998 100644 --- a/src/pathfinder/yapf/yapf_ship_regions.cpp +++ b/src/pathfinder/yapf/yapf_ship_regions.cpp @@ -113,7 +113,12 @@ class YapfShipRegions void AddOrigin(const WaterRegionPatchDesc &water_region_patch) { if (water_region_patch.label == INVALID_WATER_REGION_PATCH) return; - if (!HasOrigin(water_region_patch)) this->origin_keys.emplace_back(water_region_patch); + if (!HasOrigin(water_region_patch)) { + this->origin_keys.emplace_back(water_region_patch); + Node &node = Yapf().CreateNewNode(); + node.Set(nullptr, water_region_patch); + Yapf().AddStartupNode(node); + } } bool HasOrigin(const WaterRegionPatchDesc &water_region_patch) @@ -126,15 +131,6 @@ class YapfShipRegions this->dest.Set(water_region_patch); } - void PfSetStartupNodes() - { - for (const WaterRegionPatchKey &origin_key : this->origin_keys) { - Node &node = Yapf().CreateNewNode(); - node.Set(nullptr, origin_key); - Yapf().AddStartupNode(node); - } - } - inline void PfFollowNode(Node &old_node) { VisitWaterRegionPatchCallback visit_func = [&](const WaterRegionPatchDesc &water_region_patch) { From 0b99a0b66a9f3d9bff5b325258146dc713f1bc5c Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Fri, 26 Sep 2025 10:37:27 -0400 Subject: [PATCH 027/137] Feature: Draw infinite water when all borders are water (#13289) --- src/genworld_gui.cpp | 49 ++++++++++++++++----------- src/heightmap.cpp | 5 +++ src/landscape.cpp | 30 ++++++++++++++++ src/landscape.h | 2 ++ src/lang/english.txt | 7 ++-- src/object_cmd.cpp | 5 +++ src/settings_type.h | 8 +++++ src/table/settings/world_settings.ini | 7 ++++ src/void_cmd.cpp | 7 +++- src/water_cmd.cpp | 7 ++++ src/widgets/genworld_widget.h | 2 +- 11 files changed, 105 insertions(+), 24 deletions(-) diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index b91a51945e323..f910f75cf351b 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -115,7 +115,7 @@ static constexpr NWidgetPart _nested_generate_landscape_widgets[] = { NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_VARIETY_PULLDOWN), SetToolTip(STR_CONFIG_SETTING_VARIETY_HELPTEXT), SetFill(1, 1), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_SMOOTHNESS_PULLDOWN), SetToolTip(STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_HELPTEXT), SetFill(1, 1), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_RIVER_PULLDOWN), SetToolTip(STR_CONFIG_SETTING_RIVER_AMOUNT_HELPTEXT), SetFill(1, 1), - NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_BORDERS_RANDOM), SetToolTip(STR_MAPGEN_BORDER_TYPE_TOOLTIP), SetFill(1, 1), + NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_BORDERS_PULLDOWN), SetToolTip(STR_MAPGEN_BORDER_TYPE_TOOLTIP), SetFill(1, 1), EndContainer(), EndContainer(), @@ -379,6 +379,7 @@ static DropDownList BuildTownNameDropDown() static const StringID _elevations[] = {STR_TERRAIN_TYPE_VERY_FLAT, STR_TERRAIN_TYPE_FLAT, STR_TERRAIN_TYPE_HILLY, STR_TERRAIN_TYPE_MOUNTAINOUS, STR_TERRAIN_TYPE_ALPINIST, STR_TERRAIN_TYPE_CUSTOM}; static const StringID _sea_lakes[] = {STR_SEA_LEVEL_VERY_LOW, STR_SEA_LEVEL_LOW, STR_SEA_LEVEL_MEDIUM, STR_SEA_LEVEL_HIGH, STR_SEA_LEVEL_CUSTOM}; static const StringID _rivers[] = {STR_RIVERS_NONE, STR_RIVERS_FEW, STR_RIVERS_MODERATE, STR_RIVERS_LOT}; +static const StringID _borders[] = {STR_MAPGEN_BORDER_RANDOMIZE, STR_MAPGEN_BORDER_MANUAL, STR_MAPGEN_BORDER_INFINITE_WATER}; static const StringID _smoothness[] = {STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH, STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_SMOOTH, STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_ROUGH, STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_VERY_ROUGH}; static const StringID _rotation[] = {STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE, STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_CLOCKWISE}; static const StringID _num_towns[] = {STR_NUM_VERY_LOW, STR_NUM_LOW, STR_NUM_NORMAL, STR_NUM_HIGH, STR_NUM_CUSTOM}; @@ -471,7 +472,7 @@ struct GenerateLandscapeWindow : public Window { case WID_GL_RIVER_PULLDOWN: return GetString(_rivers[_settings_newgame.game_creation.amount_of_rivers]); case WID_GL_SMOOTHNESS_PULLDOWN: return GetString(_smoothness[_settings_newgame.game_creation.tgen_smoothness]); case WID_GL_VARIETY_PULLDOWN: return GetString(_variety[_settings_newgame.game_creation.variety]); - case WID_GL_BORDERS_RANDOM: return GetString((_settings_newgame.game_creation.water_borders == BorderFlag::Random) ? STR_MAPGEN_BORDER_RANDOMIZE : STR_MAPGEN_BORDER_MANUAL); + case WID_GL_BORDERS_PULLDOWN: return GetString(_borders[_settings_newgame.game_creation.water_border_presets]); case WID_GL_WATER_NE: return GetString((_settings_newgame.game_creation.water_borders == BorderFlag::Random) ? STR_MAPGEN_BORDER_RANDOM : _settings_newgame.game_creation.water_borders.Test(BorderFlag::NorthEast) ? STR_MAPGEN_BORDER_WATER : STR_MAPGEN_BORDER_FREEFORM); case WID_GL_WATER_NW: return GetString((_settings_newgame.game_creation.water_borders == BorderFlag::Random) ? STR_MAPGEN_BORDER_RANDOM : _settings_newgame.game_creation.water_borders.Test(BorderFlag::NorthWest) ? STR_MAPGEN_BORDER_WATER : STR_MAPGEN_BORDER_FREEFORM); case WID_GL_WATER_SE: return GetString((_settings_newgame.game_creation.water_borders == BorderFlag::Random) ? STR_MAPGEN_BORDER_RANDOM : _settings_newgame.game_creation.water_borders.Test(BorderFlag::SouthEast) ? STR_MAPGEN_BORDER_WATER : STR_MAPGEN_BORDER_FREEFORM); @@ -507,12 +508,10 @@ struct GenerateLandscapeWindow : public Window { if (mode == GLWM_GENERATE) { this->SetWidgetDisabledState(WID_GL_SMOOTHNESS_PULLDOWN, _settings_newgame.game_creation.land_generator == LG_ORIGINAL); this->SetWidgetDisabledState(WID_GL_VARIETY_PULLDOWN, _settings_newgame.game_creation.land_generator == LG_ORIGINAL); - this->SetWidgetDisabledState(WID_GL_BORDERS_RANDOM, _settings_newgame.game_creation.land_generator == LG_ORIGINAL || !_settings_newgame.construction.freeform_edges); + this->SetWidgetDisabledState(WID_GL_BORDERS_PULLDOWN, _settings_newgame.game_creation.land_generator == LG_ORIGINAL); this->SetWidgetsDisabledState(_settings_newgame.game_creation.land_generator == LG_ORIGINAL || !_settings_newgame.construction.freeform_edges || _settings_newgame.game_creation.water_borders == BorderFlag::Random, WID_GL_WATER_NW, WID_GL_WATER_NE, WID_GL_WATER_SE, WID_GL_WATER_SW); - this->SetWidgetLoweredState(WID_GL_BORDERS_RANDOM, _settings_newgame.game_creation.water_borders == BorderFlag::Random); - this->SetWidgetLoweredState(WID_GL_WATER_NW, _settings_newgame.game_creation.water_borders.Test(BorderFlag::NorthWest)); this->SetWidgetLoweredState(WID_GL_WATER_NE, _settings_newgame.game_creation.water_borders.Test(BorderFlag::NorthEast)); this->SetWidgetLoweredState(WID_GL_WATER_SE, _settings_newgame.game_creation.water_borders.Test(BorderFlag::SouthEast)); @@ -622,10 +621,7 @@ struct GenerateLandscapeWindow : public Window { case WID_GL_SMOOTHNESS_PULLDOWN: strs = _smoothness; break; case WID_GL_VARIETY_PULLDOWN: strs = _variety; break; case WID_GL_HEIGHTMAP_ROTATION_PULLDOWN: strs = _rotation; break; - case WID_GL_BORDERS_RANDOM: - d = maxdim(GetStringBoundingBox(STR_MAPGEN_BORDER_RANDOMIZE), GetStringBoundingBox(STR_MAPGEN_BORDER_MANUAL)); - break; - + case WID_GL_BORDERS_PULLDOWN: strs = _borders; break; case WID_GL_WATER_NE: case WID_GL_WATER_NW: case WID_GL_WATER_SE: @@ -807,7 +803,11 @@ struct GenerateLandscapeWindow : public Window { ShowDropDownMenu(this, _variety, _settings_newgame.game_creation.variety, WID_GL_VARIETY_PULLDOWN, 0, 0); break; - /* Freetype map borders */ + /* Map borders */ + case WID_GL_BORDERS_PULLDOWN: + ShowDropDownMenu(this, _borders, _settings_newgame.game_creation.water_border_presets, WID_GL_BORDERS_PULLDOWN, 0, 0); + break; + case WID_GL_WATER_NW: _settings_newgame.game_creation.water_borders.Flip(BorderFlag::NorthWest); SndClickBeep(); @@ -832,16 +832,6 @@ struct GenerateLandscapeWindow : public Window { this->InvalidateData(); break; - case WID_GL_BORDERS_RANDOM: - if (_settings_newgame.game_creation.water_borders == BorderFlag::Random) { - _settings_newgame.game_creation.water_borders.Reset(); - } else { - _settings_newgame.game_creation.water_borders = BorderFlag::Random; - } - SndClickBeep(); - this->InvalidateData(); - break; - case WID_GL_AI_BUTTON: ///< AI Settings ShowAIConfigWindow(); break; @@ -908,6 +898,25 @@ struct GenerateLandscapeWindow : public Window { break; } + case WID_GL_BORDERS_PULLDOWN: { + switch (index) { + case BFP_RANDOM: + _settings_newgame.game_creation.water_borders = BorderFlag::Random; + _settings_newgame.construction.freeform_edges = true; + break; + case BFP_MANUAL: + _settings_newgame.game_creation.water_borders = {}; + _settings_newgame.construction.freeform_edges = true; + break; + case BFP_INFINITE_WATER: + _settings_newgame.game_creation.water_borders = BORDERFLAGS_ALL; + _settings_newgame.construction.freeform_edges = false; + break; + } + _settings_newgame.game_creation.water_border_presets = static_cast(index); + break; + } + case WID_GL_WATER_PULLDOWN: { if ((uint)index == CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY) { this->widget_id = widget; diff --git a/src/heightmap.cpp b/src/heightmap.cpp index 543ef179525a3..9d7a09bf7e4c2 100644 --- a/src/heightmap.cpp +++ b/src/heightmap.cpp @@ -9,6 +9,7 @@ #include "stdafx.h" #include "heightmap.h" +#include "landscape.h" #include "clear_map.h" #include "strings_func.h" #include "void_map.h" @@ -523,6 +524,10 @@ bool LoadHeightmap(DetailedFileType dft, std::string_view filename) GreyscaleToMapHeights(x, y, map); FixSlopes(); + + /* If all map borders are water, we will draw infinite water. */ + _settings_game.construction.freeform_edges = !IsMapSurroundedByWater(); + MarkWholeScreenDirty(); return true; diff --git a/src/landscape.cpp b/src/landscape.cpp index 61aa649874693..621de24c0154b 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -637,6 +637,36 @@ void ClearSnowLine() _snow_line = nullptr; } +/** + * Check if all tiles on the map edge should be considered water borders. + * @return true If the edge of the map is flat and height 0, allowing for infinite water borders. + */ +bool IsMapSurroundedByWater() +{ + auto check_tile = [](uint x, uint y) -> bool { + auto [slope, h] = GetTilePixelSlopeOutsideMap(x, y); + return ((slope == SLOPE_FLAT) && (h == 0)); + }; + + /* Check the map corners. */ + if (!check_tile(0, 0)) return false; + if (!check_tile(0, Map::SizeY())) return false; + if (!check_tile(Map::SizeX(), 0)) return false; + if (!check_tile(Map::SizeX(), Map::SizeY())) return false; + + /* Check the map edges.*/ + for (uint x = 0; x <= Map::SizeX(); x++) { + if (!check_tile(x, 0)) return false; + if (!check_tile(x, Map::SizeY())) return false; + } + for (uint y = 1; y < Map::SizeY(); y++) { + if (!check_tile(0, y)) return false; + if (!check_tile(Map::SizeX(), y)) return false; + } + + return true; +} + /** * Clear a piece of landscape * @param flags of operation to conduct diff --git a/src/landscape.h b/src/landscape.h index db2a9781e47b1..3f33789694010 100644 --- a/src/landscape.h +++ b/src/landscape.h @@ -33,6 +33,8 @@ uint8_t HighestSnowLine(); uint8_t LowestSnowLine(); void ClearSnowLine(); +bool IsMapSurroundedByWater(); + int GetSlopeZInCorner(Slope tileh, Corner corner); std::tuple GetFoundationSlope(TileIndex tile); diff --git a/src/lang/english.txt b/src/lang/english.txt index f33f4848fc120..9aab6f47bbcc6 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -3428,8 +3428,11 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Southwes STR_MAPGEN_BORDER_FREEFORM :{BLACK}Freeform STR_MAPGEN_BORDER_WATER :{BLACK}Water STR_MAPGEN_BORDER_RANDOM :{BLACK}Random -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Random -STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual + +###length 3 +STR_MAPGEN_BORDER_RANDOMIZE :Random +STR_MAPGEN_BORDER_MANUAL :Manual +STR_MAPGEN_BORDER_INFINITE_WATER :Infinite Water STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Heightmap rotation: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Heightmap name: diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index b17b30c9c3060..4cf1c579e826c 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -253,6 +253,11 @@ CommandCost CmdBuildObject(DoCommandFlags flags, TileIndex tile, ObjectType type Owner o = GetTileOwner(t); if (o != OWNER_NONE && o != OWNER_WATER) cost.AddCost(CheckOwnership(o, t)); + /* If freeform edges are disabled, don't allow building on edge tiles. */ + if (!_settings_game.construction.freeform_edges && (!IsInsideMM(TileX(t), 1, Map::MaxX() - 1) || !IsInsideMM(TileY(t), 1, Map::MaxY() - 1))) { + return CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP); + } + /* However, the tile has to be clear of vehicles. */ cost.AddCost(EnsureNoVehicleOnGround(t)); } diff --git a/src/settings_type.h b/src/settings_type.h index 86350e405494e..ebbe874da0e77 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -64,6 +64,13 @@ enum IndustryDensity : uint8_t { ID_END, ///< Number of industry density settings. }; +/** Possible options for the Borders pulldown in the Genworld GUI. */ +enum BorderFlagPresets : uint8_t { + BFP_RANDOM = 0, + BFP_MANUAL, + BFP_INFINITE_WATER, +}; + /** Possible values for the "timekeeping_units" setting. */ enum TimekeepingUnits : uint8_t { TKU_CALENDAR = 0, @@ -375,6 +382,7 @@ struct GameCreationSettings { uint8_t town_name; ///< the town name generator used for town names LandscapeType landscape; ///< the landscape we're currently in BorderFlags water_borders; ///< bitset of the borders that are water + BorderFlagPresets water_border_presets; ///< presets for map border options uint16_t custom_town_number; ///< manually entered number of towns uint16_t custom_industry_number; ///< manually entered number of industries uint8_t variety; ///< variety level applied to TGP diff --git a/src/table/settings/world_settings.ini b/src/table/settings/world_settings.ini index a4c97cf8546a1..f17bf4d7293f8 100644 --- a/src/table/settings/world_settings.ini +++ b/src/table/settings/world_settings.ini @@ -268,6 +268,13 @@ def = 15 min = 0 max = 16 +[SDT_VAR] +var = game_creation.water_border_presets +type = SLE_UINT8 +def = BFP_RANDOM +min = BFP_RANDOM +max = BFP_INFINITE_WATER + [SDT_VAR] var = game_creation.custom_town_number type = SLE_UINT16 diff --git a/src/void_cmd.cpp b/src/void_cmd.cpp index 2665f4d2bfe44..a49483e91cf40 100644 --- a/src/void_cmd.cpp +++ b/src/void_cmd.cpp @@ -21,7 +21,12 @@ static void DrawTile_Void(TileInfo *ti) { - DrawGroundSprite(SPR_FLAT_BARE_LAND + SlopeToSpriteOffset(ti->tileh), PALETTE_ALL_BLACK); + /* If freeform edges are off, draw infinite water off the edges of the map. */ + if (!_settings_game.construction.freeform_edges) { + DrawGroundSprite(SPR_FLAT_WATER_TILE + SlopeToSpriteOffset(ti->tileh), PAL_NONE); + } else { + DrawGroundSprite(SPR_FLAT_BARE_LAND + SlopeToSpriteOffset(ti->tileh), PALETTE_ALL_BLACK); + } } diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 39a06374e1da5..6533d34f226a8 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -454,6 +454,13 @@ CommandCost CmdBuildLock(DoCommandFlags flags, TileIndex tile) DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile)); if (dir == INVALID_DIAGDIR) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION); + TileIndex lower_tile = TileAddByDiagDir(tile, ReverseDiagDir(dir)); + + /* If freeform edges are disabled, don't allow building on edge tiles. */ + if (!_settings_game.construction.freeform_edges && (!IsInsideMM(TileX(lower_tile), 1, Map::MaxX() - 1) || !IsInsideMM(TileY(lower_tile), 1, Map::MaxY() - 1))) { + return CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP); + } + return DoBuildLock(tile, dir, flags); } diff --git a/src/widgets/genworld_widget.h b/src/widgets/genworld_widget.h index 8d852a117be6c..e57e4efd085ab 100644 --- a/src/widgets/genworld_widget.h +++ b/src/widgets/genworld_widget.h @@ -54,7 +54,7 @@ enum GenerateLandscapeWidgets : WidgetID { WID_GL_SMOOTHNESS_PULLDOWN, ///< Dropdown 'Smoothness'. WID_GL_VARIETY_PULLDOWN, ///< Dropdown 'Variety distribution'. - WID_GL_BORDERS_RANDOM, ///< 'Random'/'Manual' borders. + WID_GL_BORDERS_PULLDOWN, ///< Dropdown 'Map edges'. WID_GL_WATER_NW, ///< NW 'Water'/'Freeform'. WID_GL_WATER_NE, ///< NE 'Water'/'Freeform'. WID_GL_WATER_SE, ///< SE 'Water'/'Freeform'. From 41837d093bcf9a163a2ef919a3caac3c5c25d430 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 26 Sep 2025 19:00:45 +0100 Subject: [PATCH 028/137] Change: Record and show multiple errors for each NewGRF. (#14658) --- src/newgrf.cpp | 13 ++++++++----- src/newgrf/newgrf_actb.cpp | 27 +++++++++++++-------------- src/newgrf_config.cpp | 13 ++----------- src/newgrf_config.h | 6 ++++-- src/newgrf_gui.cpp | 31 +++++++++++++++++-------------- 5 files changed, 44 insertions(+), 46 deletions(-) diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 26a6a66fea97e..15a06a53f40b5 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -148,9 +148,12 @@ GRFError *DisableGrf(StringID message, GRFConfig *config) if (message == STR_NULL) return nullptr; - config->error = {STR_NEWGRF_ERROR_MSG_FATAL, message}; - if (config == _cur_gps.grfconfig) config->error->param_value[0] = _cur_gps.nfo_line; - return &config->error.value(); + auto it = std::ranges::find(config->errors, _cur_gps.nfo_line, &GRFError::nfo_line); + if (it == std::end(config->errors)) { + it = config->errors.emplace(it, STR_NEWGRF_ERROR_MSG_FATAL, _cur_gps.nfo_line, message); + } + if (config == _cur_gps.grfconfig) it->param_value[0] = _cur_gps.nfo_line; + return &*it; } /** @@ -392,7 +395,7 @@ static void ResetNewGRF() static void ResetNewGRFErrors() { for (const auto &c : _grfconfig) { - c->error.reset(); + c->errors.clear(); } } @@ -1841,7 +1844,7 @@ void LoadNewGRF(SpriteID load_index, uint num_baseset) if (num_non_static == NETWORK_MAX_GRF_COUNT) { Debug(grf, 0, "'{}' is not loaded as the maximum number of non-static GRFs has been reached", c->filename); c->status = GCS_DISABLED; - c->error = {STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED}; + c->errors.emplace_back(STR_NEWGRF_ERROR_MSG_FATAL, 0, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED); continue; } num_non_static++; diff --git a/src/newgrf/newgrf_actb.cpp b/src/newgrf/newgrf_actb.cpp index 53aed45267ec9..11a3f7e322ba0 100644 --- a/src/newgrf/newgrf_actb.cpp +++ b/src/newgrf/newgrf_actb.cpp @@ -73,9 +73,6 @@ static void GRFLoadError(ByteReader &buf) /* This is a fatal error, so make sure the GRF is deactivated and no * more of it gets loaded. */ DisableGrf(); - - /* Make sure we show fatal errors, instead of silly infos from before */ - _cur_gps.grfconfig->error.reset(); } if (message_id >= lengthof(msgstr) && message_id != 0xFF) { @@ -88,39 +85,41 @@ static void GRFLoadError(ByteReader &buf) return; } - /* For now we can only show one message per newgrf file. */ - if (_cur_gps.grfconfig->error.has_value()) return; + /* An error may be emitted multiple times in different loading stages. Re-use if so. */ + auto it = std::ranges::find(_cur_gps.grfconfig->errors, _cur_gps.nfo_line, &GRFError::nfo_line); + if (it == std::end(_cur_gps.grfconfig->errors)) { + it = _cur_gps.grfconfig->errors.emplace(it, sevstr[severity], _cur_gps.nfo_line); + } - _cur_gps.grfconfig->error = {sevstr[severity]}; - GRFError *error = &_cur_gps.grfconfig->error.value(); + GRFError &error = *it; if (message_id == 0xFF) { /* This is a custom error message. */ if (buf.HasData()) { std::string_view message = buf.ReadString(); - error->custom_message = TranslateTTDPatchCodes(_cur_gps.grffile->grfid, lang, true, message, SCC_RAW_STRING_POINTER); + error.custom_message = TranslateTTDPatchCodes(_cur_gps.grffile->grfid, lang, true, message, SCC_RAW_STRING_POINTER); } else { GrfMsg(7, "GRFLoadError: No custom message supplied."); - error->custom_message.clear(); + error.custom_message.clear(); } } else { - error->message = msgstr[message_id]; + error.message = msgstr[message_id]; } if (buf.HasData()) { std::string_view data = buf.ReadString(); - error->data = TranslateTTDPatchCodes(_cur_gps.grffile->grfid, lang, true, data); + error.data = TranslateTTDPatchCodes(_cur_gps.grffile->grfid, lang, true, data); } else { GrfMsg(7, "GRFLoadError: No message data supplied."); - error->data.clear(); + error.data.clear(); } /* Only two parameter numbers can be used in the string. */ - for (uint i = 0; i < error->param_value.size() && buf.HasData(); i++) { + for (uint i = 0; i < error.param_value.size() && buf.HasData(); i++) { uint param_number = buf.ReadByte(); - error->param_value[i] = _cur_gps.grffile->GetParam(param_number); + error.param_value[i] = _cur_gps.grffile->GetParam(param_number); } } diff --git a/src/newgrf_config.cpp b/src/newgrf_config.cpp index eb4862c7a0028..422fd57f4c667 100644 --- a/src/newgrf_config.cpp +++ b/src/newgrf_config.cpp @@ -40,7 +40,7 @@ GRFConfig::GRFConfig(const GRFConfig &config) : name(config.name), info(config.info), url(config.url), - error(config.error), + errors(config.errors), version(config.version), min_loadable_version(config.min_loadable_version), flags(config.flags), @@ -156,15 +156,6 @@ GRFConfigList _grfconfig_newgame; GRFConfigList _grfconfig_static; uint _missing_extra_graphics = 0; -/** - * Construct a new GRFError. - * @param severity The severity of this error. - * @param message The actual error-string. - */ -GRFError::GRFError(StringID severity, StringID message) : message(message), severity(severity) -{ -} - /** * Get the value of the given user-changeable parameter. * @param info The grf parameter info to get the value for. @@ -472,7 +463,7 @@ GRFListCompatibility IsGoodGRFConfigList(GRFConfigList &grfconfig) c->ident.md5sum = f->ident.md5sum; c->name = f->name; c->info = f->name; - c->error.reset(); + c->errors.clear(); c->version = f->version; c->min_loadable_version = f->min_loadable_version; c->num_valid_params = f->num_valid_params; diff --git a/src/newgrf_config.h b/src/newgrf_config.h index 337058f6b619d..8b03088f96f63 100644 --- a/src/newgrf_config.h +++ b/src/newgrf_config.h @@ -107,12 +107,14 @@ struct GRFIdentifier { /** Information about why GRF had problems during initialisation */ struct GRFError { - GRFError(StringID severity, StringID message = {}); + GRFError(StringID severity, uint32_t nfo_line, StringID message = {}) + : message(message), severity(severity), nfo_line(nfo_line) {} std::string custom_message{}; ///< Custom message (if present) std::string data{}; ///< Additional data for message and custom_message StringID message{}; ///< Default message StringID severity{}; ///< Info / Warning / Error / Fatal + uint32_t nfo_line; ///< Line within NewGRF of error. std::array param_value{}; ///< Values of GRF parameters to show for message and custom_message }; @@ -169,7 +171,7 @@ struct GRFConfig { GRFTextWrapper name{}; ///< NOSAVE: GRF name (Action 0x08) GRFTextWrapper info{}; ///< NOSAVE: GRF info (author, copyright, ...) (Action 0x08) GRFTextWrapper url{}; ///< NOSAVE: URL belonging to this GRF. - std::optional error = std::nullopt; ///< NOSAVE: Error/Warning during GRF loading (Action 0x0B) + std::vector errors; ///< NOSAVE: Error/Warning during GRF loading (Action 0x0B) uint32_t version = 0; ///< NOSAVE: Version a NewGRF can set so only the newest NewGRF is shown uint32_t min_loadable_version = 0; ///< NOSAVE: Minimum compatible version a NewGRF can define diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index f33c298519340..86a8b38e03c41 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -51,17 +51,20 @@ void ShowNewGRFError() for (const auto &c : _grfconfig) { /* Only show Fatal and Error level messages */ - if (!c->error.has_value() || (c->error->severity != STR_NEWGRF_ERROR_MSG_FATAL && c->error->severity != STR_NEWGRF_ERROR_MSG_ERROR)) continue; + if (c->errors.empty()) continue; + + const GRFError &error = c->errors.back(); + if (error.severity != STR_NEWGRF_ERROR_MSG_FATAL && error.severity != STR_NEWGRF_ERROR_MSG_ERROR) continue; std::vector params; params.emplace_back(c->GetName()); - params.emplace_back(c->error->message != STR_NULL ? c->error->message : STR_JUST_RAW_STRING); - params.emplace_back(c->error->custom_message); + params.emplace_back(error.message != STR_NULL ? error.message : STR_JUST_RAW_STRING); + params.emplace_back(error.custom_message); params.emplace_back(c->filename); - params.emplace_back(c->error->data); - for (const uint32_t &value : c->error->param_value) params.emplace_back(value); + params.emplace_back(error.data); + for (const uint32_t &value : error.param_value) params.emplace_back(value); - if (c->error->severity == STR_NEWGRF_ERROR_MSG_FATAL) { + if (error.severity == STR_NEWGRF_ERROR_MSG_FATAL) { ShowErrorMessage(GetEncodedStringWithArgs(STR_NEWGRF_ERROR_FATAL_POPUP, params), {}, WL_CRITICAL); } else { ShowErrorMessage(GetEncodedStringWithArgs(STR_NEWGRF_ERROR_POPUP, params), {}, WL_ERROR); @@ -81,15 +84,15 @@ static StringID GetGRFPaletteString(uint8_t palette) static void ShowNewGRFInfo(const GRFConfig &c, const Rect &r, bool show_params) { Rect tr = r.Shrink(WidgetDimensions::scaled.frametext); - if (c.error.has_value()) { - std::arrayparam_value)>> params{}; + for (const GRFError &error : c.errors) { + std::array> params{}; auto it = params.begin(); - *it++ = c.error->custom_message; // is skipped by built-in messages + *it++ = error.custom_message; // is skipped by built-in messages *it++ = c.filename; - *it++ = c.error->data; - for (const uint32_t &value : c.error->param_value) *it++ = value; + *it++ = error.data; + for (const uint32_t &value : error.param_value) *it++ = value; - tr.top = DrawStringMultiLine(tr, GetString(c.error->severity, GetStringWithArgs(c.error->message != STR_NULL ? c.error->message : STR_JUST_RAW_STRING, {params.begin(), it}))); + tr.top = DrawStringMultiLine(tr, GetString(error.severity, GetStringWithArgs(error.message != STR_NULL ? error.message : STR_JUST_RAW_STRING, {params.begin(), it}))); } /* Draw filename or not if it is not known (GRF sent over internet) */ @@ -868,8 +871,8 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { } } DrawSprite(SPR_SQUARE, pal, square_left, tr.top + square_offset_y); - if (c->error.has_value()) DrawSprite(SPR_WARNING_SIGN, 0, warning_left, tr.top + warning_offset_y); - uint txtoffset = !c->error.has_value() ? 0 : warning.width; + if (!c->errors.empty()) DrawSprite(SPR_WARNING_SIGN, 0, warning_left, tr.top + warning_offset_y); + uint txtoffset = c->errors.empty() ? 0 : warning.width; DrawString(text_left + (rtl ? 0 : txtoffset), text_right - (rtl ? txtoffset : 0), tr.top + offset_y, std::move(text), h ? TC_WHITE : TC_ORANGE); tr.top += step_height; } From 18e28077cc9c5fdec7455e5ff9cc2a89d27982df Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 27 Sep 2025 01:50:33 +0100 Subject: [PATCH 029/137] Fix: League Table layout broken with RTL languages. (#14667) --- src/league_gui.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/league_gui.cpp b/src/league_gui.cpp index 52452e88efb29..0624f2f17c738 100644 --- a/src/league_gui.cpp +++ b/src/league_gui.cpp @@ -111,14 +111,14 @@ class PerformanceLeagueWindow : public Window { bool rtl = _current_text_dir == TD_RTL; Rect ordinal = ir.WithWidth(this->ordinal_width, rtl); - uint icon_left = ir.Indent(rtl ? this->text_width : this->ordinal_width, rtl).left; - Rect text = ir.WithWidth(this->text_width, !rtl); + Rect icon = ir.Indent(this->ordinal_width + WidgetDimensions::scaled.hsep_wide, rtl).WithWidth(this->icon.width, rtl); + Rect text = ir.Indent(this->ordinal_width + this->icon.width + WidgetDimensions::scaled.hsep_wide * 2, rtl); for (uint i = 0; i != this->companies.size(); i++) { const Company *c = this->companies[i]; DrawString(ordinal.left, ordinal.right, ir.top + text_y_offset, GetString(STR_COMPANY_LEAGUE_COMPANY_RANK, i + 1)); - DrawCompanyIcon(c->index, icon_left, ir.top + icon_y_offset); + DrawCompanyIcon(c->index, icon.left, ir.top + icon_y_offset); DrawString(text.left, text.right, ir.top + text_y_offset, GetString(STR_COMPANY_LEAGUE_COMPANY_NAME, c->index, c->index, GetPerformanceTitleFromValue(c->old_economy[0].performance_history))); ir.top += this->line_height; @@ -133,7 +133,6 @@ class PerformanceLeagueWindow : public Window { for (uint i = 0; i < MAX_COMPANIES; i++) { this->ordinal_width = std::max(this->ordinal_width, GetStringBoundingBox(GetString(STR_COMPANY_LEAGUE_COMPANY_RANK, i + 1)).width); } - this->ordinal_width += WidgetDimensions::scaled.hsep_wide; // Keep some extra spacing uint widest_width = 0; StringID widest_title = STR_NULL; @@ -154,7 +153,7 @@ class PerformanceLeagueWindow : public Window { this->text_width = widest_width + WidgetDimensions::scaled.hsep_indent * 3; // Keep some extra spacing - size.width = WidgetDimensions::scaled.framerect.Horizontal() + this->ordinal_width + this->icon.width + this->text_width + WidgetDimensions::scaled.hsep_wide; + size.width = WidgetDimensions::scaled.framerect.Horizontal() + this->ordinal_width + WidgetDimensions::scaled.hsep_wide + this->icon.width + WidgetDimensions::scaled.hsep_wide + this->text_width; size.height = this->line_height * MAX_COMPANIES + WidgetDimensions::scaled.framerect.Vertical(); } From 910eeef17f66070ec32a9b868637691c80ec8841 Mon Sep 17 00:00:00 2001 From: translators Date: Sat, 27 Sep 2025 04:38:00 +0000 Subject: [PATCH 030/137] Update: Translations from eints --- src/lang/afrikaans.txt | 2 ++ src/lang/arabic_egypt.txt | 2 ++ src/lang/basque.txt | 2 ++ src/lang/belarusian.txt | 2 ++ src/lang/brazilian_portuguese.txt | 2 ++ src/lang/bulgarian.txt | 2 ++ src/lang/catalan.txt | 2 ++ src/lang/chuvash.txt | 2 ++ src/lang/croatian.txt | 2 ++ src/lang/czech.txt | 2 ++ src/lang/danish.txt | 2 ++ src/lang/dutch.txt | 2 ++ src/lang/english_AU.txt | 2 ++ src/lang/english_US.txt | 2 ++ src/lang/esperanto.txt | 2 ++ src/lang/estonian.txt | 2 ++ src/lang/faroese.txt | 2 ++ src/lang/finnish.txt | 2 ++ src/lang/french.txt | 2 ++ src/lang/frisian.txt | 2 ++ src/lang/gaelic.txt | 2 ++ src/lang/galician.txt | 2 ++ src/lang/german.txt | 2 ++ src/lang/greek.txt | 2 ++ src/lang/hebrew.txt | 2 ++ src/lang/hindi.txt | 2 ++ src/lang/hungarian.txt | 2 ++ src/lang/icelandic.txt | 2 ++ src/lang/ido.txt | 2 ++ src/lang/indonesian.txt | 2 ++ src/lang/irish.txt | 2 ++ src/lang/italian.txt | 2 ++ src/lang/japanese.txt | 2 ++ src/lang/korean.txt | 2 ++ src/lang/latin.txt | 2 ++ src/lang/latvian.txt | 2 ++ src/lang/lithuanian.txt | 2 ++ src/lang/luxembourgish.txt | 2 ++ src/lang/macedonian.txt | 2 ++ src/lang/malay.txt | 2 ++ src/lang/maltese.txt | 2 ++ src/lang/maori.txt | 2 ++ src/lang/marathi.txt | 2 ++ src/lang/norwegian_bokmal.txt | 2 ++ src/lang/norwegian_nynorsk.txt | 2 ++ src/lang/persian.txt | 2 ++ src/lang/polish.txt | 2 ++ src/lang/portuguese.txt | 2 ++ src/lang/romanian.txt | 2 ++ src/lang/russian.txt | 2 ++ src/lang/serbian.txt | 2 ++ src/lang/simplified_chinese.txt | 2 ++ src/lang/slovak.txt | 2 ++ src/lang/slovenian.txt | 2 ++ src/lang/spanish.txt | 2 ++ src/lang/spanish_MX.txt | 2 ++ src/lang/swedish.txt | 2 ++ src/lang/tamil.txt | 2 ++ src/lang/thai.txt | 2 ++ src/lang/traditional_chinese.txt | 2 ++ src/lang/turkish.txt | 2 ++ src/lang/ukrainian.txt | 2 ++ src/lang/urdu.txt | 2 ++ src/lang/vietnamese.txt | 2 ++ src/lang/welsh.txt | 2 ++ 65 files changed, 130 insertions(+) diff --git a/src/lang/afrikaans.txt b/src/lang/afrikaans.txt index 0071396cda7c8..9b1b1f2d00cfd 100644 --- a/src/lang/afrikaans.txt +++ b/src/lang/afrikaans.txt @@ -2846,6 +2846,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Suidwes STR_MAPGEN_BORDER_FREEFORM :{BLACK}Vryeform STR_MAPGEN_BORDER_WATER :{BLACK}Water STR_MAPGEN_BORDER_RANDOM :{BLACK}Lukraak + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Lukraak STR_MAPGEN_BORDER_MANUAL :{BLACK}Handmatig diff --git a/src/lang/arabic_egypt.txt b/src/lang/arabic_egypt.txt index 446c7df5490fd..45f5a44a807f8 100644 --- a/src/lang/arabic_egypt.txt +++ b/src/lang/arabic_egypt.txt @@ -2769,6 +2769,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK} الج STR_MAPGEN_BORDER_FREEFORM :{BLACK} حر STR_MAPGEN_BORDER_WATER :{BLACK} ماء STR_MAPGEN_BORDER_RANDOM :{BLACK} عشوائي + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK} عشوائيا STR_MAPGEN_BORDER_MANUAL :{BLACK} يدوي diff --git a/src/lang/basque.txt b/src/lang/basque.txt index 9ab90acd5461d..7c6f5ec08d682 100644 --- a/src/lang/basque.txt +++ b/src/lang/basque.txt @@ -2687,6 +2687,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Hegomend STR_MAPGEN_BORDER_FREEFORM :{BLACK}Modu askea STR_MAPGEN_BORDER_WATER :{BLACK}Ura STR_MAPGEN_BORDER_RANDOM :{BLACK}Ausazkoa + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Ausazkoa STR_MAPGEN_BORDER_MANUAL :{BLACK}Eskuz egin diff --git a/src/lang/belarusian.txt b/src/lang/belarusian.txt index 924bfd9c6faa5..088433e101ba5 100644 --- a/src/lang/belarusian.txt +++ b/src/lang/belarusian.txt @@ -3631,6 +3631,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Паўд STR_MAPGEN_BORDER_FREEFORM :{BLACK}Зямля STR_MAPGEN_BORDER_WATER :{BLACK}Вада STR_MAPGEN_BORDER_RANDOM :{BLACK}Выпадковы + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Выпадковыя STR_MAPGEN_BORDER_MANUAL :{BLACK}Уручную diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index bb169f5799a4d..fefdaba10e48d 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -3429,6 +3429,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Sudoeste STR_MAPGEN_BORDER_FREEFORM :{BLACK}Forma livre STR_MAPGEN_BORDER_WATER :{BLACK}Água STR_MAPGEN_BORDER_RANDOM :{BLACK}Aleatório + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Aleatório STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual diff --git a/src/lang/bulgarian.txt b/src/lang/bulgarian.txt index 4fe06333387fa..8358254842c0b 100644 --- a/src/lang/bulgarian.txt +++ b/src/lang/bulgarian.txt @@ -3358,6 +3358,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Югоз STR_MAPGEN_BORDER_FREEFORM :{BLACK}Произволни STR_MAPGEN_BORDER_WATER :{BLACK}Вода STR_MAPGEN_BORDER_RANDOM :{BLACK}Случаен + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Случаен STR_MAPGEN_BORDER_MANUAL :{BLACK}Ръчно нагалсени diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index 11352fd53f0ca..8125287d6dcab 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -3429,6 +3429,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Sud-oest STR_MAPGEN_BORDER_FREEFORM :{BLACK}Forma lliure STR_MAPGEN_BORDER_WATER :{BLACK}Aigua STR_MAPGEN_BORDER_RANDOM :{BLACK}Aleatori + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Aleatori STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual diff --git a/src/lang/chuvash.txt b/src/lang/chuvash.txt index 5bad0832c439e..4ba7521f992bf 100644 --- a/src/lang/chuvash.txt +++ b/src/lang/chuvash.txt @@ -1222,6 +1222,8 @@ STR_MAPGEN_TOWN_NAME_CATALAN :Катталу # Strings for map borders at game generation +###length 3 + # SE Map generation diff --git a/src/lang/croatian.txt b/src/lang/croatian.txt index 1f60e8431619e..3b47a5321bc4d 100644 --- a/src/lang/croatian.txt +++ b/src/lang/croatian.txt @@ -3012,6 +3012,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Jugozapa STR_MAPGEN_BORDER_FREEFORM :{BLACK}Slobodni oblik STR_MAPGEN_BORDER_WATER :{BLACK}Voda STR_MAPGEN_BORDER_RANDOM :{BLACK}Nasumično + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Nasumično STR_MAPGEN_BORDER_MANUAL :{BLACK}Ručno diff --git a/src/lang/czech.txt b/src/lang/czech.txt index 51022ea0298f7..52af5153df177 100644 --- a/src/lang/czech.txt +++ b/src/lang/czech.txt @@ -3466,6 +3466,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Jihozáp STR_MAPGEN_BORDER_FREEFORM :{BLACK}terén STR_MAPGEN_BORDER_WATER :{BLACK}voda STR_MAPGEN_BORDER_RANDOM :{BLACK}náhodně + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}náhodně STR_MAPGEN_BORDER_MANUAL :{BLACK}vlastní diff --git a/src/lang/danish.txt b/src/lang/danish.txt index d498678ef3afb..2cf618905656b 100644 --- a/src/lang/danish.txt +++ b/src/lang/danish.txt @@ -3428,6 +3428,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Sydvest STR_MAPGEN_BORDER_FREEFORM :{BLACK}Fri udformning STR_MAPGEN_BORDER_WATER :{BLACK}Vand STR_MAPGEN_BORDER_RANDOM :{BLACK}Tilfældige + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Tilfældige STR_MAPGEN_BORDER_MANUAL :{BLACK}Manuel diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt index ecd71919e2692..0bd5d514a0114 100644 --- a/src/lang/dutch.txt +++ b/src/lang/dutch.txt @@ -3428,6 +3428,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Zuidwest STR_MAPGEN_BORDER_FREEFORM :{BLACK}Vrije vorm STR_MAPGEN_BORDER_WATER :{BLACK}Water STR_MAPGEN_BORDER_RANDOM :{BLACK}Willekeurig + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Willekeurig STR_MAPGEN_BORDER_MANUAL :{BLACK}Handmatig diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt index 804b09d79c063..9b55f7cbb1895 100644 --- a/src/lang/english_AU.txt +++ b/src/lang/english_AU.txt @@ -3428,6 +3428,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Southwes STR_MAPGEN_BORDER_FREEFORM :{BLACK}Freeform STR_MAPGEN_BORDER_WATER :{BLACK}Water STR_MAPGEN_BORDER_RANDOM :{BLACK}Random + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Random STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index c04f5ce88f638..5983f412d0d7b 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -3428,6 +3428,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Southwes STR_MAPGEN_BORDER_FREEFORM :{BLACK}Freeform STR_MAPGEN_BORDER_WATER :{BLACK}Water STR_MAPGEN_BORDER_RANDOM :{BLACK}Random + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Random STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual diff --git a/src/lang/esperanto.txt b/src/lang/esperanto.txt index 1b9aa8ce116a0..afe5f84a31c9e 100644 --- a/src/lang/esperanto.txt +++ b/src/lang/esperanto.txt @@ -3256,6 +3256,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Sudokcid STR_MAPGEN_BORDER_FREEFORM :{BLACK}Libermana STR_MAPGEN_BORDER_WATER :{BLACK}Akvo STR_MAPGEN_BORDER_RANDOM :{BLACK}Hazarde + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Hazarde STR_MAPGEN_BORDER_MANUAL :{BLACK}Permane diff --git a/src/lang/estonian.txt b/src/lang/estonian.txt index 49dab0b1c72d5..1e9fa32ff4492 100644 --- a/src/lang/estonian.txt +++ b/src/lang/estonian.txt @@ -3376,6 +3376,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Edel STR_MAPGEN_BORDER_FREEFORM :{BLACK}Vaba STR_MAPGEN_BORDER_WATER :{BLACK}Vesi STR_MAPGEN_BORDER_RANDOM :{BLACK}Suvaline + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Suvaline STR_MAPGEN_BORDER_MANUAL :{BLACK}Määratud diff --git a/src/lang/faroese.txt b/src/lang/faroese.txt index 15dba5c7727fb..439b1d04ddaef 100644 --- a/src/lang/faroese.txt +++ b/src/lang/faroese.txt @@ -2524,6 +2524,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Útsynni STR_MAPGEN_BORDER_FREEFORM :{BLACK}Freeform STR_MAPGEN_BORDER_WATER :{BLACK}Vatn STR_MAPGEN_BORDER_RANDOM :{BLACK}Tilvildarligt + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Tilvildarligt STR_MAPGEN_BORDER_MANUAL :{BLACK}Manuelt diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index 2271da1991262..8a8cbac8b1d6f 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -3428,6 +3428,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Lounas STR_MAPGEN_BORDER_FREEFORM :{BLACK}Vapaa STR_MAPGEN_BORDER_WATER :{BLACK}Vesi STR_MAPGEN_BORDER_RANDOM :{BLACK}Sattumanvarainen + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Sattumanvarainen STR_MAPGEN_BORDER_MANUAL :{BLACK}Manuaalinen diff --git a/src/lang/french.txt b/src/lang/french.txt index d1b844e658630..0e4e6fc263a3b 100644 --- a/src/lang/french.txt +++ b/src/lang/french.txt @@ -3429,6 +3429,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Sud-Oues STR_MAPGEN_BORDER_FREEFORM :{BLACK}Forme libre STR_MAPGEN_BORDER_WATER :{BLACK}Eau STR_MAPGEN_BORDER_RANDOM :{BLACK}Aléatoire + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Aléatoire STR_MAPGEN_BORDER_MANUAL :{BLACK}Manuel diff --git a/src/lang/frisian.txt b/src/lang/frisian.txt index 81441e30a46b7..75a2cb27ac217 100644 --- a/src/lang/frisian.txt +++ b/src/lang/frisian.txt @@ -2660,6 +2660,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Súdwest STR_MAPGEN_BORDER_FREEFORM :{BLACK}Frij foarmje STR_MAPGEN_BORDER_WATER :{BLACK}Wetter STR_MAPGEN_BORDER_RANDOM :{BLACK}Samar wat + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Samar wat STR_MAPGEN_BORDER_MANUAL :{BLACK}Hânmjittich diff --git a/src/lang/gaelic.txt b/src/lang/gaelic.txt index 4b246f9ae3212..9f6df83f83a30 100644 --- a/src/lang/gaelic.txt +++ b/src/lang/gaelic.txt @@ -3032,6 +3032,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Iar-dhea STR_MAPGEN_BORDER_FREEFORM :{BLACK}Cruth saor STR_MAPGEN_BORDER_WATER :{BLACK}Uisge STR_MAPGEN_BORDER_RANDOM :{BLACK}Air thuaiream + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Air thuaiream STR_MAPGEN_BORDER_MANUAL :{BLACK}A làimh diff --git a/src/lang/galician.txt b/src/lang/galician.txt index 4859d6aff2f10..b9a979c8a8bcd 100644 --- a/src/lang/galician.txt +++ b/src/lang/galician.txt @@ -3427,6 +3427,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Suroeste STR_MAPGEN_BORDER_FREEFORM :{BLACK}Forma libre STR_MAPGEN_BORDER_WATER :{BLACK}Auga STR_MAPGEN_BORDER_RANDOM :{BLACK}Aleatorio + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Aleatorio STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual diff --git a/src/lang/german.txt b/src/lang/german.txt index f02568c7c07e4..ec1cc449665eb 100644 --- a/src/lang/german.txt +++ b/src/lang/german.txt @@ -3425,6 +3425,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Südwest STR_MAPGEN_BORDER_FREEFORM :{BLACK}Beliebig STR_MAPGEN_BORDER_WATER :{BLACK}Wasser STR_MAPGEN_BORDER_RANDOM :{BLACK}Zufällig + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Zufällig STR_MAPGEN_BORDER_MANUAL :{BLACK}Manuell diff --git a/src/lang/greek.txt b/src/lang/greek.txt index 4ad2d4028b837..2c366e6440b71 100644 --- a/src/lang/greek.txt +++ b/src/lang/greek.txt @@ -3521,6 +3521,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Νοτι STR_MAPGEN_BORDER_FREEFORM :{BLACK}Ελεύθερη μορφή STR_MAPGEN_BORDER_WATER :{BLACK}Νερό STR_MAPGEN_BORDER_RANDOM :{BLACK}Τυχαία + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Τυχαία STR_MAPGEN_BORDER_MANUAL :{BLACK}Χειροκίνητος diff --git a/src/lang/hebrew.txt b/src/lang/hebrew.txt index 403a05aa87261..662b4e10863b1 100644 --- a/src/lang/hebrew.txt +++ b/src/lang/hebrew.txt @@ -3045,6 +3045,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}דרום STR_MAPGEN_BORDER_FREEFORM :{BLACK}יד חופשית STR_MAPGEN_BORDER_WATER :{BLACK}מים STR_MAPGEN_BORDER_RANDOM :{BLACK}אקראי + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}אקראי STR_MAPGEN_BORDER_MANUAL :{BLACK}ידני diff --git a/src/lang/hindi.txt b/src/lang/hindi.txt index 658351a121015..7d1a61c12fcff 100644 --- a/src/lang/hindi.txt +++ b/src/lang/hindi.txt @@ -1004,6 +1004,8 @@ STR_MAPGEN_TOWN_NAME_ITALIAN :इटैलि STR_MAPGEN_BORDER_WATER :{BLACK}जल STR_MAPGEN_BORDER_RANDOM :{BLACK}यादृच्छिक +###length 3 + # SE Map generation diff --git a/src/lang/hungarian.txt b/src/lang/hungarian.txt index 5d137f1e27246..b9b9067247f4f 100644 --- a/src/lang/hungarian.txt +++ b/src/lang/hungarian.txt @@ -3492,6 +3492,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Délnyug STR_MAPGEN_BORDER_FREEFORM :{BLACK}Szárazföld STR_MAPGEN_BORDER_WATER :{BLACK}Víz STR_MAPGEN_BORDER_RANDOM :{BLACK}Véletlen + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Véletlen STR_MAPGEN_BORDER_MANUAL :{BLACK}Kézi diff --git a/src/lang/icelandic.txt b/src/lang/icelandic.txt index 8bcd7bb027cc6..eeb4f28dd7654 100644 --- a/src/lang/icelandic.txt +++ b/src/lang/icelandic.txt @@ -2630,6 +2630,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Suðvest STR_MAPGEN_BORDER_FREEFORM :{BLACK}Frjálsar STR_MAPGEN_BORDER_WATER :{BLACK}Vatn STR_MAPGEN_BORDER_RANDOM :{BLACK}Slembin + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Slembnar STR_MAPGEN_BORDER_MANUAL :{BLACK}Forvaldar diff --git a/src/lang/ido.txt b/src/lang/ido.txt index b66649307a809..9ce3042cabbcd 100644 --- a/src/lang/ido.txt +++ b/src/lang/ido.txt @@ -1071,6 +1071,8 @@ STR_MAPGEN_BY :{BLACK}* # Strings for map borders at game generation +###length 3 + # SE Map generation diff --git a/src/lang/indonesian.txt b/src/lang/indonesian.txt index 606976eaaed89..bce95528efa3f 100644 --- a/src/lang/indonesian.txt +++ b/src/lang/indonesian.txt @@ -3240,6 +3240,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Barat Da STR_MAPGEN_BORDER_FREEFORM :{BLACK}Bebas STR_MAPGEN_BORDER_WATER :{BLACK}Perairan STR_MAPGEN_BORDER_RANDOM :{BLACK}Acak + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Acak STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual diff --git a/src/lang/irish.txt b/src/lang/irish.txt index 5bb301b9ee614..32eae7e2b373a 100644 --- a/src/lang/irish.txt +++ b/src/lang/irish.txt @@ -3043,6 +3043,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Iardheis STR_MAPGEN_BORDER_FREEFORM :{BLACK}Saorfhoirme STR_MAPGEN_BORDER_WATER :{BLACK}Uisce STR_MAPGEN_BORDER_RANDOM :{BLACK}Randamach + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Randamach STR_MAPGEN_BORDER_MANUAL :{BLACK}De láimh diff --git a/src/lang/italian.txt b/src/lang/italian.txt index e3f80fa5c2c6a..9e93da9af0053 100644 --- a/src/lang/italian.txt +++ b/src/lang/italian.txt @@ -3428,6 +3428,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Sud-oves STR_MAPGEN_BORDER_FREEFORM :{BLACK}Variabile STR_MAPGEN_BORDER_WATER :{BLACK}Acqua STR_MAPGEN_BORDER_RANDOM :{BLACK}Casuale + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Casuale STR_MAPGEN_BORDER_MANUAL :{BLACK}Manuale diff --git a/src/lang/japanese.txt b/src/lang/japanese.txt index f5170ca57f059..b1419a6484b5c 100644 --- a/src/lang/japanese.txt +++ b/src/lang/japanese.txt @@ -3176,6 +3176,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}南西 STR_MAPGEN_BORDER_FREEFORM :{BLACK}自由形成 STR_MAPGEN_BORDER_WATER :{BLACK}水域 STR_MAPGEN_BORDER_RANDOM :{BLACK}ランダム + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}ランダム設定 STR_MAPGEN_BORDER_MANUAL :{BLACK}手動設定 diff --git a/src/lang/korean.txt b/src/lang/korean.txt index 9ad3186e14b12..45c9642f8e5b3 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -3429,6 +3429,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}남서 STR_MAPGEN_BORDER_FREEFORM :{BLACK}변경 가능 STR_MAPGEN_BORDER_WATER :{BLACK}물 STR_MAPGEN_BORDER_RANDOM :{BLACK}임의 + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}임의 STR_MAPGEN_BORDER_MANUAL :{BLACK}사용자 정의 diff --git a/src/lang/latin.txt b/src/lang/latin.txt index 76eaa9afea59c..1091802ffc644 100644 --- a/src/lang/latin.txt +++ b/src/lang/latin.txt @@ -3000,6 +3000,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Africus STR_MAPGEN_BORDER_FREEFORM :{BLACK}Quilibet STR_MAPGEN_BORDER_WATER :{BLACK}Aqua STR_MAPGEN_BORDER_RANDOM :{BLACK}Fortuiti + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Fortuiti STR_MAPGEN_BORDER_MANUAL :{BLACK}Manu diff --git a/src/lang/latvian.txt b/src/lang/latvian.txt index a342fe2b9b565..62221c230cc1e 100644 --- a/src/lang/latvian.txt +++ b/src/lang/latvian.txt @@ -3431,6 +3431,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Dienvidr STR_MAPGEN_BORDER_FREEFORM :{BLACK}Brīvā forma STR_MAPGEN_BORDER_WATER :{BLACK}Ūdens STR_MAPGEN_BORDER_RANDOM :{BLACK}Nejauša + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Nejaušas STR_MAPGEN_BORDER_MANUAL :{BLACK}Manuāli diff --git a/src/lang/lithuanian.txt b/src/lang/lithuanian.txt index 865935973c262..bd4e4ad2aaad0 100644 --- a/src/lang/lithuanian.txt +++ b/src/lang/lithuanian.txt @@ -3463,6 +3463,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Pietvaka STR_MAPGEN_BORDER_FREEFORM :{BLACK}Laisva forma STR_MAPGEN_BORDER_WATER :{BLACK}Vanduo STR_MAPGEN_BORDER_RANDOM :{BLACK}Atsitiktinis + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Atsitiktiniai STR_MAPGEN_BORDER_MANUAL :{BLACK}Pasirinktiniai diff --git a/src/lang/luxembourgish.txt b/src/lang/luxembourgish.txt index a1d3b19840213..1e3b62ef5a4d4 100644 --- a/src/lang/luxembourgish.txt +++ b/src/lang/luxembourgish.txt @@ -3385,6 +3385,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Südwest STR_MAPGEN_BORDER_FREEFORM :{BLACK}Fräiform STR_MAPGEN_BORDER_WATER :{BLACK}Waasser STR_MAPGEN_BORDER_RANDOM :{BLACK}Zoufälleg + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Zoufall STR_MAPGEN_BORDER_MANUAL :{BLACK}Manuell diff --git a/src/lang/macedonian.txt b/src/lang/macedonian.txt index 552c372116dcc..18b63a7eae95a 100644 --- a/src/lang/macedonian.txt +++ b/src/lang/macedonian.txt @@ -1460,6 +1460,8 @@ STR_MAPGEN_BY :{BLACK}* # Strings for map borders at game generation +###length 3 + # SE Map generation diff --git a/src/lang/malay.txt b/src/lang/malay.txt index b484731b797f8..27ca9a08525e8 100644 --- a/src/lang/malay.txt +++ b/src/lang/malay.txt @@ -2527,6 +2527,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Barat da STR_MAPGEN_BORDER_FREEFORM :{BLACK}Bebas STR_MAPGEN_BORDER_WATER :{BLACK}Air STR_MAPGEN_BORDER_RANDOM :{BLACK}Rambang + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Rambang STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual diff --git a/src/lang/maltese.txt b/src/lang/maltese.txt index 2b95200f6fed2..597ed222da70d 100644 --- a/src/lang/maltese.txt +++ b/src/lang/maltese.txt @@ -974,6 +974,8 @@ STR_MAPGEN_BY :{BLACK}* # Strings for map borders at game generation +###length 3 + # SE Map generation diff --git a/src/lang/maori.txt b/src/lang/maori.txt index 0e1f95a9fcd58..6507cfa6a720e 100644 --- a/src/lang/maori.txt +++ b/src/lang/maori.txt @@ -3426,6 +3426,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Tongamā STR_MAPGEN_BORDER_FREEFORM :{BLACK}Hanga noa STR_MAPGEN_BORDER_WATER :{BLACK}Wai STR_MAPGEN_BORDER_RANDOM :{BLACK}Matapōkere + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Matapōkere STR_MAPGEN_BORDER_MANUAL :{BLACK}Ā-ringa diff --git a/src/lang/marathi.txt b/src/lang/marathi.txt index 7df164e113c3f..3e98b72c5400e 100644 --- a/src/lang/marathi.txt +++ b/src/lang/marathi.txt @@ -1324,6 +1324,8 @@ STR_MAPGEN_TOWN_NAME_ITALIAN :ईटेलि # Strings for map borders at game generation STR_MAPGEN_BORDER_WATER :{BLACK}पाणी +###length 3 + STR_MAPGEN_HEIGHTMAP_SIZE :{ORANGE}{NUM} x {NUM} diff --git a/src/lang/norwegian_bokmal.txt b/src/lang/norwegian_bokmal.txt index da763e6bdb617..c0e7ebd892cfd 100644 --- a/src/lang/norwegian_bokmal.txt +++ b/src/lang/norwegian_bokmal.txt @@ -3430,6 +3430,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Sørvest STR_MAPGEN_BORDER_FREEFORM :{BLACK}Frihånds STR_MAPGEN_BORDER_WATER :{BLACK}Sjø STR_MAPGEN_BORDER_RANDOM :{BLACK}Tilfeldig + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Tilfeldige STR_MAPGEN_BORDER_MANUAL :{BLACK}Manuelle diff --git a/src/lang/norwegian_nynorsk.txt b/src/lang/norwegian_nynorsk.txt index 1c71fe8533e76..bcf128286aae5 100644 --- a/src/lang/norwegian_nynorsk.txt +++ b/src/lang/norwegian_nynorsk.txt @@ -2710,6 +2710,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Sørvest STR_MAPGEN_BORDER_FREEFORM :{BLACK}Frihands STR_MAPGEN_BORDER_WATER :{BLACK}Vatn STR_MAPGEN_BORDER_RANDOM :{BLACK}Tilfeldig + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Tilfeldig STR_MAPGEN_BORDER_MANUAL :{BLACK}Manuell diff --git a/src/lang/persian.txt b/src/lang/persian.txt index 86037e1e7796a..7504651f8e7c4 100644 --- a/src/lang/persian.txt +++ b/src/lang/persian.txt @@ -2785,6 +2785,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}جنوب STR_MAPGEN_BORDER_FREEFORM :{BLACK}قالب آزاد STR_MAPGEN_BORDER_WATER :{BLACK}دریا STR_MAPGEN_BORDER_RANDOM :{BLACK}تصادفی + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}تصادفی STR_MAPGEN_BORDER_MANUAL :{BLACK}دستی diff --git a/src/lang/polish.txt b/src/lang/polish.txt index e620986c82d13..21f40b3f0885a 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -3808,6 +3808,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Płd.-za STR_MAPGEN_BORDER_FREEFORM :{BLACK}Ląd STR_MAPGEN_BORDER_WATER :{BLACK}Woda STR_MAPGEN_BORDER_RANDOM :{BLACK}Losowe + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Losowo STR_MAPGEN_BORDER_MANUAL :{BLACK}Użytkownika diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index 6c1aa845e9c74..c5aa9fc218672 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -3429,6 +3429,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Sudoeste STR_MAPGEN_BORDER_FREEFORM :{BLACK}Modo livre STR_MAPGEN_BORDER_WATER :{BLACK}Água STR_MAPGEN_BORDER_RANDOM :{BLACK}Aleatório + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Aleatório STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual diff --git a/src/lang/romanian.txt b/src/lang/romanian.txt index eb1c78c72124e..4094e24a36487 100644 --- a/src/lang/romanian.txt +++ b/src/lang/romanian.txt @@ -3376,6 +3376,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Sud-vest STR_MAPGEN_BORDER_FREEFORM :{BLACK}Pământ STR_MAPGEN_BORDER_WATER :{BLACK}Apă STR_MAPGEN_BORDER_RANDOM :{BLACK}Aleator + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Aleator STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual diff --git a/src/lang/russian.txt b/src/lang/russian.txt index 277fbec78ed83..834471c13d774 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -3603,6 +3603,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Юго- STR_MAPGEN_BORDER_FREEFORM :{BLACK}Свободный STR_MAPGEN_BORDER_WATER :{BLACK}Водный STR_MAPGEN_BORDER_RANDOM :{BLACK}Случайно + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Случайно STR_MAPGEN_BORDER_MANUAL :{BLACK}Вручную diff --git a/src/lang/serbian.txt b/src/lang/serbian.txt index f14ffc78a18af..de1746c3c683c 100644 --- a/src/lang/serbian.txt +++ b/src/lang/serbian.txt @@ -3431,6 +3431,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Jugozapa STR_MAPGEN_BORDER_FREEFORM :{BLACK}Kopno STR_MAPGEN_BORDER_WATER :{BLACK}More STR_MAPGEN_BORDER_RANDOM :{BLACK}Proizvoljno + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Proizvoljno STR_MAPGEN_BORDER_MANUAL :{BLACK}Podešeno diff --git a/src/lang/simplified_chinese.txt b/src/lang/simplified_chinese.txt index 136c41ea47e03..7fdcf877b72a7 100644 --- a/src/lang/simplified_chinese.txt +++ b/src/lang/simplified_chinese.txt @@ -3428,6 +3428,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}西南 STR_MAPGEN_BORDER_FREEFORM :{BLACK}自由形式 STR_MAPGEN_BORDER_WATER :{BLACK}水面 STR_MAPGEN_BORDER_RANDOM :{BLACK}随机 + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}随机 STR_MAPGEN_BORDER_MANUAL :{BLACK}手动 diff --git a/src/lang/slovak.txt b/src/lang/slovak.txt index daeb7280a01f0..4701412c183f4 100644 --- a/src/lang/slovak.txt +++ b/src/lang/slovak.txt @@ -3378,6 +3378,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Juho-zá STR_MAPGEN_BORDER_FREEFORM :{BLACK}Náhodne STR_MAPGEN_BORDER_WATER :{BLACK}Voda STR_MAPGEN_BORDER_RANDOM :{BLACK}Náhodne + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Náhodne STR_MAPGEN_BORDER_MANUAL :{BLACK}Manuálne diff --git a/src/lang/slovenian.txt b/src/lang/slovenian.txt index a58b036798178..971b8b97526f9 100644 --- a/src/lang/slovenian.txt +++ b/src/lang/slovenian.txt @@ -2930,6 +2930,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Jugozaho STR_MAPGEN_BORDER_FREEFORM :{BLACK}Poljubno STR_MAPGEN_BORDER_WATER :{BLACK}Voda STR_MAPGEN_BORDER_RANDOM :{BLACK}Naključno + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Naključno STR_MAPGEN_BORDER_MANUAL :{BLACK}Ročno diff --git a/src/lang/spanish.txt b/src/lang/spanish.txt index 5341c2ca88b1f..70640bd735607 100644 --- a/src/lang/spanish.txt +++ b/src/lang/spanish.txt @@ -3398,6 +3398,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Suroeste STR_MAPGEN_BORDER_FREEFORM :{BLACK}Forma libre STR_MAPGEN_BORDER_WATER :{BLACK}Agua STR_MAPGEN_BORDER_RANDOM :{BLACK}Aleatorio + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Aleatorio STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual diff --git a/src/lang/spanish_MX.txt b/src/lang/spanish_MX.txt index 351e2d84ea366..f21104fa5e27a 100644 --- a/src/lang/spanish_MX.txt +++ b/src/lang/spanish_MX.txt @@ -3422,6 +3422,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Suroeste STR_MAPGEN_BORDER_FREEFORM :{BLACK}Forma libre STR_MAPGEN_BORDER_WATER :{BLACK}Agua STR_MAPGEN_BORDER_RANDOM :{BLACK}Aleatorio + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Aleatorio STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt index 298b9d86b2e75..66d739073967a 100644 --- a/src/lang/swedish.txt +++ b/src/lang/swedish.txt @@ -3428,6 +3428,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Sydväst STR_MAPGEN_BORDER_FREEFORM :{BLACK}Fri form STR_MAPGEN_BORDER_WATER :{BLACK}Vatten STR_MAPGEN_BORDER_RANDOM :{BLACK}På måfå + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}På måfå STR_MAPGEN_BORDER_MANUAL :{BLACK}Manuella diff --git a/src/lang/tamil.txt b/src/lang/tamil.txt index fea48d823a807..b9ece84d8eeef 100644 --- a/src/lang/tamil.txt +++ b/src/lang/tamil.txt @@ -3023,6 +3023,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}தெ STR_MAPGEN_BORDER_FREEFORM :{BLACK}இலவசமாக STR_MAPGEN_BORDER_WATER :{BLACK}தண்ணீர் STR_MAPGEN_BORDER_RANDOM :{BLACK}ஏதொவொன்று + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}ஏதோவொன்று STR_MAPGEN_BORDER_MANUAL :{BLACK}எனது diff --git a/src/lang/thai.txt b/src/lang/thai.txt index 8c4ffb9ab7151..9e7b2c7115395 100644 --- a/src/lang/thai.txt +++ b/src/lang/thai.txt @@ -2861,6 +2861,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}ตะ STR_MAPGEN_BORDER_FREEFORM :{BLACK}ไม่ยึดติดรูปแบบ STR_MAPGEN_BORDER_WATER :{BLACK}น้ำ STR_MAPGEN_BORDER_RANDOM :{BLACK}สุ่ม + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}สุ่ม STR_MAPGEN_BORDER_MANUAL :{BLACK}ปรับแต่งเอง diff --git a/src/lang/traditional_chinese.txt b/src/lang/traditional_chinese.txt index 8acba78a68703..b9f596ba69e88 100644 --- a/src/lang/traditional_chinese.txt +++ b/src/lang/traditional_chinese.txt @@ -3428,6 +3428,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}西南 STR_MAPGEN_BORDER_FREEFORM :{BLACK}自由地形 STR_MAPGEN_BORDER_WATER :{BLACK}水域 STR_MAPGEN_BORDER_RANDOM :{BLACK}隨機 + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}隨機 STR_MAPGEN_BORDER_MANUAL :{BLACK}手動 diff --git a/src/lang/turkish.txt b/src/lang/turkish.txt index bbb8b60d96516..1734004986f35 100644 --- a/src/lang/turkish.txt +++ b/src/lang/turkish.txt @@ -3338,6 +3338,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Güneyba STR_MAPGEN_BORDER_FREEFORM :{BLACK}Serbest STR_MAPGEN_BORDER_WATER :{BLACK}Su STR_MAPGEN_BORDER_RANDOM :{BLACK}Rastgele + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Rastgele STR_MAPGEN_BORDER_MANUAL :{BLACK}El ile diff --git a/src/lang/ukrainian.txt b/src/lang/ukrainian.txt index 72b8665bfd99a..5ef10b2455272 100644 --- a/src/lang/ukrainian.txt +++ b/src/lang/ukrainian.txt @@ -3537,6 +3537,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}півд STR_MAPGEN_BORDER_FREEFORM :{BLACK}вільний формат STR_MAPGEN_BORDER_WATER :{BLACK}вода STR_MAPGEN_BORDER_RANDOM :{BLACK}довільно + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}довільно STR_MAPGEN_BORDER_MANUAL :{BLACK}вручну diff --git a/src/lang/urdu.txt b/src/lang/urdu.txt index 63aade5047214..4fa01ee68cbb0 100644 --- a/src/lang/urdu.txt +++ b/src/lang/urdu.txt @@ -2222,6 +2222,8 @@ STR_MAPGEN_BORDER_TYPE_TOOLTIP :{BLACK}کھیل STR_MAPGEN_BORDER_FREEFORM :{BLACK}فری فارم STR_MAPGEN_BORDER_WATER :{BLACK}پانی STR_MAPGEN_BORDER_RANDOM :{BLACK}بے ترتیب + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}بے ترتیب STR_MAPGEN_BORDER_MANUAL :{BLACK}دستی diff --git a/src/lang/vietnamese.txt b/src/lang/vietnamese.txt index cac92cff53711..8c211ff30f5fe 100644 --- a/src/lang/vietnamese.txt +++ b/src/lang/vietnamese.txt @@ -3428,6 +3428,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}Tây Nam STR_MAPGEN_BORDER_FREEFORM :{BLACK}Dạng Tự Do STR_MAPGEN_BORDER_WATER :{BLACK}Nước STR_MAPGEN_BORDER_RANDOM :{BLACK}Ngẫu Nhiên + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Ngẫu Nhiên STR_MAPGEN_BORDER_MANUAL :{BLACK}Điều Chỉnh diff --git a/src/lang/welsh.txt b/src/lang/welsh.txt index 066674e3c2188..85133232b28c0 100644 --- a/src/lang/welsh.txt +++ b/src/lang/welsh.txt @@ -3414,6 +3414,8 @@ STR_MAPGEN_SOUTHWEST :{BLACK}De Orlle STR_MAPGEN_BORDER_FREEFORM :{BLACK}Ffurfrydd STR_MAPGEN_BORDER_WATER :{BLACK}Dŵr STR_MAPGEN_BORDER_RANDOM :{BLACK}Ar hap + +###length 3 STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Ar hap STR_MAPGEN_BORDER_MANUAL :{BLACK}Â Llaw From 5e7cb08411dedea5c12214d0cd18b9ccd086be70 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Wed, 24 Sep 2025 21:13:43 +0200 Subject: [PATCH 031/137] Fix #14549: changing interface scale could underflow map zoom --- src/zoom_type.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/zoom_type.h b/src/zoom_type.h index 06fb780aab962..272d2fab9541d 100644 --- a/src/zoom_type.h +++ b/src/zoom_type.h @@ -12,8 +12,12 @@ #include "core/enum_type.hpp" -/** All zoom levels we know. */ -enum class ZoomLevel : uint8_t { +/** + * All zoom levels we know. + * + * The underlying type is signed so subtract-and-Clamp works without need for casting. + */ +enum class ZoomLevel : int8_t { /* Our possible zoom-levels */ Begin = 0, ///< Begin for iteration. Min = Begin, ///< Minimum zoom level. From 69ea970d6eebf9b1ef3b9302ed20062ee43d2fa3 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 27 Sep 2025 13:08:06 +0100 Subject: [PATCH 032/137] Codefix 18e28077cc: Local variable icon shadowed member variable icon. (#14668) Rename rects used in league table to avoid name shadowing. Now uses the same naming as in ScriptLeagueWindow. --- src/league_gui.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/league_gui.cpp b/src/league_gui.cpp index 0624f2f17c738..4278ad0ba0c54 100644 --- a/src/league_gui.cpp +++ b/src/league_gui.cpp @@ -57,7 +57,7 @@ static inline StringID GetPerformanceTitleFromValue(uint value) class PerformanceLeagueWindow : public Window { private: GUIList companies{}; - uint ordinal_width = 0; ///< The width of the ordinal number + uint rank_width = 0; ///< The width of the rank uint text_width = 0; ///< The width of the actual text int line_height = 0; ///< Height of the text lines Dimension icon{}; ///< Dimension of the company icon. @@ -110,17 +110,17 @@ class PerformanceLeagueWindow : public Window { int text_y_offset = (this->line_height - GetCharacterHeight(FS_NORMAL)) / 2; bool rtl = _current_text_dir == TD_RTL; - Rect ordinal = ir.WithWidth(this->ordinal_width, rtl); - Rect icon = ir.Indent(this->ordinal_width + WidgetDimensions::scaled.hsep_wide, rtl).WithWidth(this->icon.width, rtl); - Rect text = ir.Indent(this->ordinal_width + this->icon.width + WidgetDimensions::scaled.hsep_wide * 2, rtl); + Rect rank_rect = ir.WithWidth(this->rank_width, rtl); + Rect icon_rect = ir.Indent(this->rank_width + WidgetDimensions::scaled.hsep_wide, rtl).WithWidth(this->icon.width, rtl); + Rect text_rect = ir.Indent(this->rank_width + this->icon.width + WidgetDimensions::scaled.hsep_wide * 2, rtl); for (uint i = 0; i != this->companies.size(); i++) { const Company *c = this->companies[i]; - DrawString(ordinal.left, ordinal.right, ir.top + text_y_offset, GetString(STR_COMPANY_LEAGUE_COMPANY_RANK, i + 1)); + DrawString(rank_rect.left, rank_rect.right, ir.top + text_y_offset, GetString(STR_COMPANY_LEAGUE_COMPANY_RANK, i + 1)); - DrawCompanyIcon(c->index, icon.left, ir.top + icon_y_offset); + DrawCompanyIcon(c->index, icon_rect.left, ir.top + icon_y_offset); - DrawString(text.left, text.right, ir.top + text_y_offset, GetString(STR_COMPANY_LEAGUE_COMPANY_NAME, c->index, c->index, GetPerformanceTitleFromValue(c->old_economy[0].performance_history))); + DrawString(text_rect.left, text_rect.right, ir.top + text_y_offset, GetString(STR_COMPANY_LEAGUE_COMPANY_NAME, c->index, c->index, GetPerformanceTitleFromValue(c->old_economy[0].performance_history))); ir.top += this->line_height; } } @@ -129,9 +129,9 @@ class PerformanceLeagueWindow : public Window { { if (widget != WID_PLT_BACKGROUND) return; - this->ordinal_width = 0; + this->rank_width = 0; for (uint i = 0; i < MAX_COMPANIES; i++) { - this->ordinal_width = std::max(this->ordinal_width, GetStringBoundingBox(GetString(STR_COMPANY_LEAGUE_COMPANY_RANK, i + 1)).width); + this->rank_width = std::max(this->rank_width, GetStringBoundingBox(GetString(STR_COMPANY_LEAGUE_COMPANY_RANK, i + 1)).width); } uint widest_width = 0; @@ -153,7 +153,7 @@ class PerformanceLeagueWindow : public Window { this->text_width = widest_width + WidgetDimensions::scaled.hsep_indent * 3; // Keep some extra spacing - size.width = WidgetDimensions::scaled.framerect.Horizontal() + this->ordinal_width + WidgetDimensions::scaled.hsep_wide + this->icon.width + WidgetDimensions::scaled.hsep_wide + this->text_width; + size.width = WidgetDimensions::scaled.framerect.Horizontal() + this->rank_width + WidgetDimensions::scaled.hsep_wide + this->icon.width + WidgetDimensions::scaled.hsep_wide + this->text_width; size.height = this->line_height * MAX_COMPANIES + WidgetDimensions::scaled.framerect.Vertical(); } From 0aaeb6f7e765d21c43bbcf54dca74edac8a82c94 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 27 Sep 2025 18:10:22 +0100 Subject: [PATCH 033/137] Codechange: Rename TrackFollowers to follower. (#14664) Replaces use of codestyle breaking `F` in places. --- src/pathfinder/yapf/yapf_base.hpp | 4 +-- src/pathfinder/yapf/yapf_costrail.hpp | 36 +++++++++++++------------- src/pathfinder/yapf/yapf_node_rail.hpp | 10 +++---- src/pathfinder/yapf/yapf_rail.cpp | 18 ++++++------- src/pathfinder/yapf/yapf_ship.cpp | 16 ++++++------ 5 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/pathfinder/yapf/yapf_base.hpp b/src/pathfinder/yapf/yapf_base.hpp index 9bb84488d52b3..6555b6539e169 100644 --- a/src/pathfinder/yapf/yapf_base.hpp +++ b/src/pathfinder/yapf/yapf_base.hpp @@ -185,7 +185,7 @@ class CYapfBaseT { * AddNewNode() - called by Tderived::PfFollowNode() for each child node. * Nodes are evaluated here and added into open list */ - void AddNewNode(Node &n, const TrackFollower &tf) + void AddNewNode(Node &n, const TrackFollower &follower) { assert(n.parent != nullptr); @@ -197,7 +197,7 @@ class CYapfBaseT { this->stats_cache_hits++; } - bool valid = Yapf().PfCalcCost(n, &tf); + bool valid = Yapf().PfCalcCost(n, &follower); if (valid) valid = Yapf().PfCalcEstimate(n); diff --git a/src/pathfinder/yapf/yapf_costrail.hpp b/src/pathfinder/yapf/yapf_costrail.hpp index 1c2b1e61fb83d..2cda842dd3796 100644 --- a/src/pathfinder/yapf/yapf_costrail.hpp +++ b/src/pathfinder/yapf/yapf_costrail.hpp @@ -271,11 +271,11 @@ class CYapfCostRailT : public CYapfCostBase { * Calculates only the cost of given node, adds it to the parent node cost * and stores the result into Node::cost member */ - inline bool PfCalcCost(Node &n, const TrackFollower *tf) + inline bool PfCalcCost(Node &n, const TrackFollower *follower) { assert(!n.flags_u.flags_s.target_seen); - assert(tf->new_tile == n.key.tile); - assert((HasTrackdir(tf->new_td_bits, n.key.td))); + assert(follower->new_tile == n.key.tile); + assert((HasTrackdir(follower->new_td_bits, n.key.td))); /* Does the node have some parent node? */ bool has_parent = (n.parent != nullptr); @@ -326,7 +326,7 @@ class CYapfCostRailT : public CYapfCostBase { EndSegmentReasons end_segment_reason{}; - TrackFollower tf_local(v, Yapf().GetCompatibleRailTypes()); + TrackFollower follower_local{v, Yapf().GetCompatibleRailTypes()}; if (!has_parent) { /* We will jump to the middle of the cost calculator assuming that segment cache is not used. */ @@ -378,7 +378,7 @@ class CYapfCostRailT : public CYapfCostBase { segment_cost += Yapf().OneTileCost(cur.tile, cur.td); /* If we skipped some tunnel/bridge/station tiles, add their base cost */ - segment_cost += YAPF_TILE_LENGTH * tf->tiles_skipped; + segment_cost += YAPF_TILE_LENGTH * follower->tiles_skipped; /* Slope cost. */ segment_cost += Yapf().SlopeCost(cur.tile, cur.td); @@ -387,7 +387,7 @@ class CYapfCostRailT : public CYapfCostBase { segment_cost += Yapf().SignalCost(n, cur.tile, cur.td); /* Reserved tiles. */ - segment_cost += Yapf().ReservationCost(n, cur.tile, cur.td, tf->tiles_skipped); + segment_cost += Yapf().ReservationCost(n, cur.tile, cur.td, follower->tiles_skipped); end_segment_reason = segment.end_segment_reason; @@ -445,9 +445,9 @@ class CYapfCostRailT : public CYapfCostBase { /* Waypoint is also a good reason to finish. */ end_segment_reason.Set(EndSegmentReason::Waypoint); - } else if (tf->is_station) { + } else if (follower->is_station) { /* Station penalties. */ - uint platform_length = tf->tiles_skipped + 1; + uint platform_length = follower->tiles_skipped + 1; /* We don't know yet if the station is our target or not. Act like * if it is pass-through station (not our destination). */ segment_cost += Yapf().PfGetSettings().rail_station_penalty * platform_length; @@ -466,10 +466,10 @@ class CYapfCostRailT : public CYapfCostBase { if (n.num_signals_passed < this->sig_look_ahead_costs.size()) { int min_speed = 0; - int max_speed = tf->GetSpeedLimit(&min_speed); + int max_speed = follower->GetSpeedLimit(&min_speed); int max_veh_speed = std::min(v->GetDisplayMaxSpeed(), v->current_order.GetMaxSpeed()); if (max_speed < max_veh_speed) { - extra_cost += YAPF_TILE_LENGTH * (max_veh_speed - max_speed) * (4 + tf->tiles_skipped) / max_veh_speed; + extra_cost += YAPF_TILE_LENGTH * (max_veh_speed - max_speed) * (4 + follower->tiles_skipped) / max_veh_speed; } if (min_speed > max_veh_speed) { extra_cost += YAPF_TILE_LENGTH * (min_speed - max_veh_speed); @@ -483,13 +483,13 @@ class CYapfCostRailT : public CYapfCostBase { } /* Move to the next tile/trackdir. */ - tf = &tf_local; - tf_local.Init(v, Yapf().GetCompatibleRailTypes()); + follower = &follower_local; + follower_local.Init(v, Yapf().GetCompatibleRailTypes()); - if (!tf_local.Follow(cur.tile, cur.td)) { - assert(tf_local.err != TrackFollower::EC_NONE); + if (!follower_local.Follow(cur.tile, cur.td)) { + assert(follower_local.err != TrackFollower::EC_NONE); /* Can't move to the next tile (EOL?). */ - if (tf_local.err == TrackFollower::EC_RAIL_ROAD_TYPE) { + if (follower_local.err == TrackFollower::EC_RAIL_ROAD_TYPE) { end_segment_reason.Set(EndSegmentReason::RailType); } else { end_segment_reason.Set(EndSegmentReason::DeadEnd); @@ -502,14 +502,14 @@ class CYapfCostRailT : public CYapfCostBase { } /* Check if the next tile is not a choice. */ - if (KillFirstBit(tf_local.new_td_bits) != TRACKDIR_BIT_NONE) { + if (KillFirstBit(follower_local.new_td_bits) != TRACKDIR_BIT_NONE) { /* More than one segment will follow. Close this one. */ end_segment_reason.Set(EndSegmentReason::ChoiceFollows); break; } /* Gather the next tile/trackdir/tile_type/rail_type. */ - TILE next(tf_local.new_tile, (Trackdir)FindFirstBit(tf_local.new_td_bits)); + TILE next(follower_local.new_tile, (Trackdir)FindFirstBit(follower_local.new_td_bits)); if (TrackFollower::DoTrackMasking() && IsTileType(next.tile, MP_RAILWAY)) { if (HasSignalOnTrackdir(next.tile, next.td) && IsPbsSignal(GetSignalType(next.tile, TrackdirToTrack(next.td)))) { @@ -538,7 +538,7 @@ class CYapfCostRailT : public CYapfCostBase { if (segment_cost > MAX_SEGMENT_COST) { /* Potentially in the infinite loop (or only very long segment?). We should * not force it to finish prematurely unless we are on a regular tile. */ - if (IsTileType(tf->new_tile, MP_RAILWAY)) { + if (IsTileType(follower->new_tile, MP_RAILWAY)) { end_segment_reason.Set(EndSegmentReason::SegmentTooLong); break; } diff --git a/src/pathfinder/yapf/yapf_node_rail.hpp b/src/pathfinder/yapf/yapf_node_rail.hpp index 53483d30e34e3..cf493e1b95548 100644 --- a/src/pathfinder/yapf/yapf_node_rail.hpp +++ b/src/pathfinder/yapf/yapf_node_rail.hpp @@ -177,17 +177,17 @@ struct CYapfRailNode : CYapfNodeT { template bool IterateTiles(const Train *v, Tpf &yapf, Tbase &obj, bool (Tfunc::*func)(TileIndex, Trackdir)) const { - typename Tbase::TrackFollower ft(v, yapf.GetCompatibleRailTypes()); + typename Tbase::TrackFollower follower{v, yapf.GetCompatibleRailTypes()}; TileIndex cur = this->base::GetTile(); Trackdir cur_td = this->base::GetTrackdir(); while (cur != this->GetLastTile() || cur_td != this->GetLastTrackdir()) { if (!((obj.*func)(cur, cur_td))) return false; - if (!ft.Follow(cur, cur_td)) break; - cur = ft.new_tile; - assert(KillFirstBit(ft.new_td_bits) == TRACKDIR_BIT_NONE); - cur_td = FindFirstTrackdir(ft.new_td_bits); + if (!follower.Follow(cur, cur_td)) break; + cur = follower.new_tile; + assert(KillFirstBit(follower.new_td_bits) == TRACKDIR_BIT_NONE); + cur_td = FindFirstTrackdir(follower.new_td_bits); } return (obj.*func)(cur, cur_td); diff --git a/src/pathfinder/yapf/yapf_rail.cpp b/src/pathfinder/yapf/yapf_rail.cpp index 4d22118be579b..57ca8098f4d40 100644 --- a/src/pathfinder/yapf/yapf_rail.cpp +++ b/src/pathfinder/yapf/yapf_rail.cpp @@ -229,9 +229,9 @@ class CYapfFollowAnyDepotRailT { */ inline void PfFollowNode(Node &old_node) { - TrackFollower F(Yapf().GetVehicle()); - if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir())) { - Yapf().AddMultipleNodes(&old_node, F); + TrackFollower follower{Yapf().GetVehicle()}; + if (follower.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir())) { + Yapf().AddMultipleNodes(&old_node, follower); } } @@ -320,9 +320,9 @@ class CYapfFollowAnySafeTileRailT : public CYapfReserveTrack { */ inline void PfFollowNode(Node &old_node) { - TrackFollower F(Yapf().GetVehicle(), Yapf().GetCompatibleRailTypes()); - if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir()) && F.MaskReservedTracks()) { - Yapf().AddMultipleNodes(&old_node, F); + TrackFollower follower{Yapf().GetVehicle(), Yapf().GetCompatibleRailTypes()}; + if (follower.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir()) && follower.MaskReservedTracks()) { + Yapf().AddMultipleNodes(&old_node, follower); } } @@ -402,9 +402,9 @@ class CYapfFollowRailT : public CYapfReserveTrack { */ inline void PfFollowNode(Node &old_node) { - TrackFollower F(Yapf().GetVehicle()); - if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir())) { - Yapf().AddMultipleNodes(&old_node, F); + TrackFollower follower{Yapf().GetVehicle()}; + if (follower.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir())) { + Yapf().AddMultipleNodes(&old_node, follower); } } diff --git a/src/pathfinder/yapf/yapf_ship.cpp b/src/pathfinder/yapf/yapf_ship.cpp index fcb2e3759c491..bec4068a57a37 100644 --- a/src/pathfinder/yapf/yapf_ship.cpp +++ b/src/pathfinder/yapf/yapf_ship.cpp @@ -133,11 +133,11 @@ class CYapfFollowShipT { */ inline void PfFollowNode(Node &old_node) { - TrackFollower F(Yapf().GetVehicle()); - if (F.Follow(old_node.key.tile, old_node.key.td)) { + TrackFollower follower{Yapf().GetVehicle()}; + if (follower.Follow(old_node.key.tile, old_node.key.td)) { if (this->water_region_corridor.empty() - || std::ranges::find(this->water_region_corridor, GetWaterRegionInfo(F.new_tile)) != this->water_region_corridor.end()) { - Yapf().AddMultipleNodes(&old_node, F); + || std::ranges::find(this->water_region_corridor, GetWaterRegionInfo(follower.new_tile)) != this->water_region_corridor.end()) { + Yapf().AddMultipleNodes(&old_node, follower); } } } @@ -166,7 +166,7 @@ class CYapfFollowShipT { /** Returns a random tile/trackdir that can be reached from the current tile/trackdir, or tile/INVALID_TRACK if none is available. */ static std::pair GetRandomFollowUpTileTrackdir(const Ship *v, TileIndex tile, Trackdir dir) { - TrackFollower follower(v); + TrackFollower follower{v}; if (follower.Follow(tile, dir)) { TrackdirBits dirs = follower.new_td_bits; const TrackdirBits dirs_without_90_degree = dirs & ~TrackdirCrossesTrackdirs(dir); @@ -361,7 +361,7 @@ class CYapfCostShipT { * Calculates only the cost of given node, adds it to the parent node cost * and stores the result into Node::cost member. */ - inline bool PfCalcCost(Node &n, const TrackFollower *tf) + inline bool PfCalcCost(Node &n, const TrackFollower *follower) { /* Base tile cost depending on distance. */ int c = IsDiagonalTrackdir(n.GetTrackdir()) ? YAPF_TILE_LENGTH : YAPF_TILE_CORNER_LENGTH; @@ -381,12 +381,12 @@ class CYapfCostShipT { if (!IsPreferredShipDirection(n.GetTile(), n.GetTrackdir())) c += YAPF_TILE_LENGTH; /* Skipped tile cost for aqueducts. */ - c += YAPF_TILE_LENGTH * tf->tiles_skipped; + c += YAPF_TILE_LENGTH * follower->tiles_skipped; /* Ocean/canal speed penalty. */ const ShipVehicleInfo *svi = ShipVehInfo(Yapf().GetVehicle()->engine_type); uint8_t speed_frac = (GetEffectiveWaterClass(n.GetTile()) == WATER_CLASS_SEA) ? svi->ocean_speed_frac : svi->canal_speed_frac; - if (speed_frac > 0) c += YAPF_TILE_LENGTH * (1 + tf->tiles_skipped) * speed_frac / (256 - speed_frac); + if (speed_frac > 0) c += YAPF_TILE_LENGTH * (1 + follower->tiles_skipped) * speed_frac / (256 - speed_frac); /* Lock penalty. */ if (IsTileType(n.GetTile(), MP_WATER) && IsLock(n.GetTile()) && GetLockPart(n.GetTile()) == LOCK_PART_MIDDLE) { From bfe5fb73391a135fbca466e81acb06607fbbb17c Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 27 Sep 2025 18:10:39 +0100 Subject: [PATCH 034/137] Codechange: FlatSet's contains() should be const. (#14665) This function does not modify contents, so should be marked const. --- src/core/flatset_type.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/flatset_type.hpp b/src/core/flatset_type.hpp index 2dc42d0b48107..b69f1daebf12b 100644 --- a/src/core/flatset_type.hpp +++ b/src/core/flatset_type.hpp @@ -54,7 +54,7 @@ class FlatSet { * @param key Key to test. * @return true iff the key exists in the set. */ - bool contains(const Tkey &key) + bool contains(const Tkey &key) const { return std::ranges::binary_search(this->data, key, Tcompare{}); } From 9307e1929e23685910e2031941aa625b91d67568 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sat, 27 Sep 2025 18:11:42 +0100 Subject: [PATCH 035/137] Fix #14604: Clearing tiles to build objects did not update town ratings (#14616) --- src/object_cmd.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index 4cf1c579e826c..6cfed66e4746b 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -303,10 +303,10 @@ CommandCost CmdBuildObject(DoCommandFlags flags, TileIndex tile, ObjectType type for (TileIndex t : ta) { if (HasTileWaterGround(t)) { if (!IsWaterTile(t)) { - Command::Do(DoCommandFlags{flags}.Reset(DoCommandFlag::NoWater).Set(DoCommandFlag::NoModifyTownRating), t); + Command::Do(DoCommandFlags{flags}.Reset(DoCommandFlag::NoWater), t); } } else { - Command::Do(flags | DoCommandFlag::NoModifyTownRating, t); + Command::Do(flags, t); } } } From f64e1cdae0323314189286bed78c95ff58eba795 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sat, 27 Sep 2025 18:12:49 +0100 Subject: [PATCH 036/137] Fix: Industry accept/produce when not contiguous range from 0 (#14555) --- src/industry_cmd.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index d1e273ab4bfae..08dbdc4efcabd 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -1761,17 +1761,25 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, auto &industries = Industry::industries[type]; industries.insert(i->index); + size_t produced_count = 0; for (size_t index = 0; index < std::size(indspec->produced_cargo); ++index) { - if (!IsValidCargoType(indspec->produced_cargo[index])) break; - + if (IsValidCargoType(indspec->produced_cargo[index])) { + produced_count = index + 1; + } + } + for (size_t index = 0; index < produced_count; ++index) { Industry::ProducedCargo &p = i->produced.emplace_back(); p.cargo = indspec->produced_cargo[index]; p.rate = indspec->production_rate[index]; } + size_t accepted_count = 0; for (size_t index = 0; index < std::size(indspec->accepts_cargo); ++index) { - if (!IsValidCargoType(indspec->accepts_cargo[index])) break; - + if (IsValidCargoType(indspec->accepts_cargo[index])) { + accepted_count = index + 1; + } + } + for (size_t index = 0; index < accepted_count; ++index) { Industry::AcceptedCargo &a = i->accepted.emplace_back(); a.cargo = indspec->accepts_cargo[index]; } From e58fdb8840a9d0f23351031763d7da38cfd2be8a Mon Sep 17 00:00:00 2001 From: Rubidium Date: Sat, 27 Sep 2025 21:42:49 +0200 Subject: [PATCH 037/137] Codefix: shadowing of variables --- src/station_cmd.cpp | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index c9a3924f87353..8a90e30f0ee0d 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -1478,11 +1478,8 @@ CommandCost CmdBuildRailStation(DoCommandFlags flags, TileIndex tile_org, RailTy TileIndexDiff track_delta = TileOffsByAxis(OtherAxis(axis)); // offset to go to the next track RailStationTileLayout stl{statspec, numtracks, plat_len}; - auto it = stl.begin(); - TileIndex tile_track = tile_org; - for (uint i = 0; i != numtracks; ++i, tile_track += track_delta) { - TileIndex tile = tile_track; - for (uint j = 0; j != plat_len; ++j, tile += tile_delta, ++it) { + for (auto [i, it, tile_track] = std::make_tuple(0, stl.begin(), tile_org); i != numtracks; ++i, tile_track += track_delta) { + for (auto [j, tile] = std::make_tuple(0, tile_track); j != plat_len; ++j, tile += tile_delta, ++it) { /* Don't check the layout if there's no bridge above anyway. */ if (!IsBridgeAbove(tile)) continue; @@ -1531,14 +1528,9 @@ CommandCost CmdBuildRailStation(DoCommandFlags flags, TileIndex tile_org, RailTy } Track track = AxisToTrack(axis); - - auto it = stl.begin(); - Company *c = Company::Get(st->owner); - TileIndex tile_track = tile_org; - for (uint i = 0; i != numtracks; ++i) { - TileIndex tile = tile_track; - for (uint j = 0; j != plat_len; ++j) { + for (auto [i, it, tile_track] = std::make_tuple(0, stl.begin(), tile_org); i != numtracks; ++i, tile_track += track_delta) { + for (auto [j, tile] = std::make_tuple(0, tile_track); j != plat_len; ++j, tile += tile_delta, ++it) { if (IsRailStationTile(tile) && HasStationReservation(tile)) { /* Check for trains having a reservation for this tile. */ Train *v = GetTrainForReservation(tile, AxisToTrack(GetRailStationAxis(tile))); @@ -1558,7 +1550,7 @@ CommandCost CmdBuildRailStation(DoCommandFlags flags, TileIndex tile_org, RailTy DeleteAnimatedTile(tile); uint8_t old_specindex = HasStationTileRail(tile) ? GetCustomStationSpecIndex(tile) : 0; - MakeRailStation(tile, st->owner, st->index, axis, *it++, rt); + MakeRailStation(tile, st->owner, st->index, axis, *it, rt); /* Free the spec if we overbuild something */ DeallocateSpecFromStation(st, old_specindex); @@ -1588,12 +1580,9 @@ CommandCost CmdBuildRailStation(DoCommandFlags flags, TileIndex tile_org, RailTy if (!IsStationTileBlocked(tile)) c->infrastructure.rail[rt]++; c->infrastructure.station++; - - tile += tile_delta; } AddTrackToSignalBuffer(tile_track, track, _current_company); YapfNotifyTrackLayoutChange(tile_track, track); - tile_track += track_delta; } for (uint i = 0; i < affected_vehicles.size(); ++i) { From 380f9e8b48978376754e10f52cbc1c40c607b226 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 28 Sep 2025 00:30:47 +0100 Subject: [PATCH 038/137] Change: Prefer normal/medium weight font in FontConfig fallback detection. (#14672) This way it behaves similar to Windows. --- src/os/unix/font_unix.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/os/unix/font_unix.cpp b/src/os/unix/font_unix.cpp index dd8f2f1d2a3ef..978695a853141 100644 --- a/src/os/unix/font_unix.cpp +++ b/src/os/unix/font_unix.cpp @@ -123,6 +123,22 @@ FT_Error GetFontByFaceName(std::string_view font_name, FT_Face *face) return err; } +/** + * Get distance between font weight and preferred font weights. + * @param weight Font weight from FontConfig. + * @return Distance from preferred weight, where lower values are preferred. + */ +static int GetPreferredWeightDistance(int weight) +{ + /* Prefer a font between normal and medium weight. */ + static constexpr int PREFERRED_WEIGHT_MIN = FC_WEIGHT_NORMAL; + static constexpr int PREFERRED_WEIGHT_MAX = FC_WEIGHT_MEDIUM; + + if (weight < PREFERRED_WEIGHT_MIN) return std::abs(weight - PREFERRED_WEIGHT_MIN); + if (weight > PREFERRED_WEIGHT_MAX) return weight - PREFERRED_WEIGHT_MAX; + return 0; +} + bool FontConfigFindFallbackFont(FontCacheSettings *settings, const std::string &language_isocode, MissingGlyphSearcher *callback) { bool ret = false; @@ -164,9 +180,10 @@ bool FontConfigFindFallbackFont(FontCacheSettings *settings, const std::string & FcPatternGetInteger(font, FC_SLANT, 0, &value); if (value != 0) continue; - /* We want the fatter font as they look better at small sizes. */ + /* We want a font near to medium weight. */ FcPatternGetInteger(font, FC_WEIGHT, 0, &value); - if (value <= best_weight) continue; + int weight = GetPreferredWeightDistance(value); + if (best_weight != -1 && weight > best_weight) continue; /* Possible match based on attributes, get index. */ int32_t index; @@ -179,7 +196,7 @@ bool FontConfigFindFallbackFont(FontCacheSettings *settings, const std::string & Debug(fontcache, 1, "Font \"{}\" misses{} glyphs", FromFcString(file), missing ? "" : " no"); if (!missing) { - best_weight = value; + best_weight = weight; best_font = FromFcString(file); best_index = index; } From 6d3f39609f59bf57dbb6c27102a23d39c0fae330 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 21 Sep 2025 14:32:27 +0100 Subject: [PATCH 039/137] Codechange: Add WithX/WithY methods to Rect. This simplifies creating a new Rect with specific horizontal or vertical coordinates. --- src/core/geometry_type.hpp | 44 ++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/src/core/geometry_type.hpp b/src/core/geometry_type.hpp index f5bb66f554228..9e7cf625830f9 100644 --- a/src/core/geometry_type.hpp +++ b/src/core/geometry_type.hpp @@ -211,8 +211,8 @@ struct Rect { [[nodiscard]] inline Rect WithWidth(int width, bool end) const { return end - ? Rect {this->right - width + 1, this->top, this->right, this->bottom} - : Rect {this->left, this->top, this->left + width - 1, this->bottom}; + ? this->WithX(this->right - width + 1, this->right) + : this->WithX(this->left, this->left + width - 1); } /** @@ -224,21 +224,21 @@ struct Rect { [[nodiscard]] inline Rect Indent(int indent, bool end) const { return end - ? Rect {this->left, this->top, this->right - indent, this->bottom} - : Rect {this->left + indent, this->top, this->right, this->bottom}; + ? this->WithX(this->left, this->right - indent) + : this->WithX(this->left + indent, this->right); } /** * Copy Rect and set its height. - * @param width height in pixels for new Rect. + * @param height height in pixels for new Rect. * @param end if set, set height at end of Rect, i.e. at bottom. * @return the new resized Rect. */ [[nodiscard]] inline Rect WithHeight(int height, bool end = false) const { return end - ? Rect {this->left, this->bottom - height + 1, this->right, this->bottom} - : Rect {this->left, this->top, this->right, this->top + height - 1}; + ? this->WithY(this->bottom - height + 1, this->bottom) + : this->WithY(this->top, this->top + height - 1); } /** @@ -264,6 +264,36 @@ struct Rect { int new_top = CentreBounds(this->top, this->bottom, height); return {new_left, new_top, new_left + width - 1, new_top + height - 1}; } + + /** + * Create a new Rect, replacing the left and right coordiates. + * @param new_left New left coordinate. + * @param new_right New right coordinate. + * @return The new Rect. + */ + [[nodiscard]] inline Rect WithX(int new_left, int new_right) const { return {new_left, this->top, new_right, this->bottom}; } + + /** + * Create a new Rect, replacing the top and bottom coordiates. + * @param new_top New top coordinate. + * @param new_bottom New bottom coordinate. + * @return The new Rect. + */ + [[nodiscard]] inline Rect WithY(int new_top, int new_bottom) const { return {this->left, new_top, this->right, new_bottom}; } + + /** + * Create a new Rect, replacing the left and right coordiates. + * @param other Rect containing the new left and right coordinates. + * @return The new Rect. + */ + [[nodiscard]] inline Rect WithX(const Rect &other) const { return this->WithX(other.left, other.right); } + + /** + * Create a new Rect, replacing the top and bottom coordiates. + * @param other Rect containing the new top and bottom coordinates. + * @return The new Rect. + */ + [[nodiscard]] inline Rect WithY(const Rect &other) const { return this->WithY(other.top, other.bottom); } }; /** From 31eec7106b5353550cf3f4825a68d9e8724e2b1c Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 21 Sep 2025 20:35:58 +0100 Subject: [PATCH 040/137] Codechange: Use Rect WithX/WithY in some places. --- src/build_vehicle_gui.cpp | 2 +- src/dropdown.cpp | 4 ++-- src/dropdown_common_type.h | 4 ++-- src/error_gui.cpp | 2 +- src/fios_gui.cpp | 4 ++-- src/misc_gui.cpp | 2 +- src/network/network_content_gui.cpp | 2 +- src/train_gui.cpp | 2 +- src/transparency_gui.cpp | 2 +- src/vehicle_gui.cpp | 6 +++--- src/widget.cpp | 26 ++++++++++++++------------ 11 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 0702fdeee53a7..f21a424f1ed90 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1030,7 +1030,7 @@ void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_li if (has_variants) { Rect fr = tr.WithWidth(circle_width, rtl); - DrawSpriteIgnorePadding(is_folded ? SPR_CIRCLE_FOLDED : SPR_CIRCLE_UNFOLDED, PAL_NONE, {fr.left, textr.top, fr.right, textr.bottom}, SA_CENTER); + DrawSpriteIgnorePadding(is_folded ? SPR_CIRCLE_FOLDED : SPR_CIRCLE_UNFOLDED, PAL_NONE, fr.WithY(textr), SA_CENTER); } tr = tr.Indent(circle_width + WidgetDimensions::scaled.hsep_normal, rtl); diff --git a/src/dropdown.cpp b/src/dropdown.cpp index 2b2570f3db8ad..d3df9a731aee0 100644 --- a/src/dropdown.cpp +++ b/src/dropdown.cpp @@ -248,7 +248,7 @@ struct DropdownWindow : Window { if (y < item_height) { if (item->masked || !item->Selectable()) return false; result = item->result; - click_result = item->OnClick({r.left, 0, r.right, item_height - 1}, {_cursor.pos.x - this->left, y}); + click_result = item->OnClick(r.WithY(0, item_height - 1), {_cursor.pos.x - this->left, y}); return true; } @@ -274,7 +274,7 @@ struct DropdownWindow : Window { if (--pos >= 0) continue; if (y + item_height - 1 <= ir.bottom) { - Rect full{ir.left, y, ir.right, y + item_height - 1}; + Rect full = ir.WithY(y, y + item_height - 1); bool selected = (this->selected_result == item->result) && item->Selectable(); if (selected) GfxFillRect(full, PC_BLACK); diff --git a/src/dropdown_common_type.h b/src/dropdown_common_type.h index 80362f6712f17..e29aa16163121 100644 --- a/src/dropdown_common_type.h +++ b/src/dropdown_common_type.h @@ -41,8 +41,8 @@ class DropDownDivider : public TBase { PixelColour c2 = GetColourGradient(bg_colour, SHADE_LIGHTEST); int mid = CentreBounds(full.top, full.bottom, 0); - GfxFillRect(full.left, mid - WidgetDimensions::scaled.bevel.bottom, full.right, mid - 1, c1); - GfxFillRect(full.left, mid, full.right, mid + WidgetDimensions::scaled.bevel.top - 1, c2); + GfxFillRect(full.WithY(mid - WidgetDimensions::scaled.bevel.bottom, mid - 1), c1); + GfxFillRect(full.WithY(mid, mid + WidgetDimensions::scaled.bevel.top - 1), c2); } }; diff --git a/src/error_gui.cpp b/src/error_gui.cpp index 182ac7229fa5a..ed5d0b2ab1813 100644 --- a/src/error_gui.cpp +++ b/src/error_gui.cpp @@ -209,7 +209,7 @@ struct ErrmsgWindow : public Window, ErrorMessageData { /* Note: NewGRF supplied error message often do not start with a colour code, so default to white. */ Rect top_section = r.WithHeight(this->height_summary + extra, false); Rect bottom_section = r.WithHeight(this->height_extra + extra, true); - Rect middle_section = { top_section.left, top_section.bottom, top_section.right, bottom_section.top }; + Rect middle_section = top_section.WithY(top_section.bottom, bottom_section.top); DrawStringMultiLineWithClipping(top_section, this->summary_msg.GetDecodedString(), TC_WHITE, SA_CENTER); DrawStringMultiLineWithClipping(middle_section, this->detailed_msg.GetDecodedString(), TC_WHITE, SA_CENTER); DrawStringMultiLineWithClipping(bottom_section, this->extra_msg.GetDecodedString(), TC_WHITE, SA_CENTER); diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index 10e05908eb788..6c2dfb8b90be5 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -527,9 +527,9 @@ struct SaveLoadWindow : public Window { const FiosItem *item = *it; if (item == this->selected) { - GfxFillRect(br.left, tr.top, br.right, tr.bottom, PC_DARK_BLUE); + GfxFillRect(br.WithY(tr), PC_DARK_BLUE); } else if (item == this->highlighted) { - GfxFillRect(br.left, tr.top, br.right, tr.bottom, PC_VERY_DARK_BLUE); + GfxFillRect(br.WithY(tr), PC_VERY_DARK_BLUE); } DrawString(tr, item->title.GetDecodedString(), _fios_colours[item->type.detailed]); tr = tr.Translate(0, this->resize.step_height); diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 719f5a5dfabbc..55b2b8b867909 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -833,7 +833,7 @@ Rect QueryString::GetBoundingRect(const Window *w, WidgetID wid, size_t from, si const auto p1 = GetCharPosInString(tb->GetText(), from, FS_NORMAL); const auto p2 = from != to ? GetCharPosInString(tb->GetText(), to, FS_NORMAL) : p1; - return { Clamp(r.left + p1.left, r.left, r.right), r.top, Clamp(r.left + p2.right, r.left, r.right), r.bottom }; + return r.WithX(Clamp(r.left + p1.left, r.left, r.right), Clamp(r.left + p2.right, r.left, r.right)); } /** diff --git a/src/network/network_content_gui.cpp b/src/network/network_content_gui.cpp index 13600aedbaa56..a184511f98b75 100644 --- a/src/network/network_content_gui.cpp +++ b/src/network/network_content_gui.cpp @@ -673,7 +673,7 @@ class NetworkContentListWindow : public Window, ContentCallback { case ContentInfo::State::DoesNotExist: sprite = SPR_BLOT; pal = PALETTE_TO_RED; break; default: NOT_REACHED(); } - DrawSpriteIgnorePadding(sprite, pal, {checkbox.left, mr.top, checkbox.right, mr.bottom}, SA_CENTER); + DrawSpriteIgnorePadding(sprite, pal, checkbox.WithY(mr), SA_CENTER); StringID str = STR_CONTENT_TYPE_BASE_GRAPHICS + ci->type - CONTENT_TYPE_BASE_GRAPHICS; DrawString(type.left, type.right, mr.top + text_y_offset, str, TC_BLACK, SA_HOR_CENTER); diff --git a/src/train_gui.cpp b/src/train_gui.cpp index fc4262c89faa9..cfa018c0ecc9c 100644 --- a/src/train_gui.cpp +++ b/src/train_gui.cpp @@ -401,7 +401,7 @@ void DrawTrainDetails(const Train *v, const Rect &r, int vscroll_pos, uint16_t v if (vscroll_pos <= 0 && vscroll_pos > -vscroll_cap) { int py = r.top - line_height * vscroll_pos + text_y_offset; if (i > 0 || separate_sprite_row) { - if (vscroll_pos != 0) GfxFillRect(r.left, py - WidgetDimensions::scaled.matrix.top - 1, r.right, py - WidgetDimensions::scaled.matrix.top, GetColourGradient(COLOUR_GREY, SHADE_LIGHT)); + if (vscroll_pos != 0) GfxFillRect(r.WithY(py - WidgetDimensions::scaled.matrix.top - 1, py - WidgetDimensions::scaled.matrix.top), GetColourGradient(COLOUR_GREY, SHADE_LIGHT)); } switch (det_tab) { case TDW_TAB_CARGO: diff --git a/src/transparency_gui.cpp b/src/transparency_gui.cpp index 0c768f59ff87e..8574075b1e3ef 100644 --- a/src/transparency_gui.cpp +++ b/src/transparency_gui.cpp @@ -62,7 +62,7 @@ class TransparenciesWindow : public Window if (i == WID_TT_TEXT) continue; // Loading and cost/income text has no invisibility button. const Rect wr = this->GetWidget(i)->GetCurrentRect().Shrink(WidgetDimensions::scaled.fullbevel); - DrawFrameRect(wr.left, fr.top, wr.right, fr.bottom, COLOUR_PALE_GREEN, + DrawFrameRect(wr.WithY(fr), COLOUR_PALE_GREEN, HasBit(_invisibility_opt, i - WID_TT_BEGIN) ? FrameFlag::Lowered : FrameFlags{}); } break; diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index fbd7a69b54a27..0ea6f71e445c5 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -1042,7 +1042,7 @@ struct RefitWindow : public Window { switch (widget) { case WID_VR_VEHICLE_PANEL_DISPLAY: { Vehicle *v = Vehicle::Get(this->window_number); - DrawVehicleImage(v, {this->sprite_left, r.top, this->sprite_right, r.bottom}, + DrawVehicleImage(v, r.WithX(this->sprite_left, this->sprite_right), VehicleID::Invalid(), EIT_IN_DETAILS, this->hscroll != nullptr ? this->hscroll->GetPosition() : 0); /* Highlight selected vehicles. */ @@ -1791,7 +1791,7 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int DrawSprite(SPR_WARNING_SIGN, PAL_NONE, vehicle_button_x, ir.top + GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal + profit.height); } - DrawVehicleImage(v, {image_left, ir.top, image_right, ir.bottom}, selected_vehicle, EIT_IN_LIST, 0); + DrawVehicleImage(v, ir.WithX(image_left, image_right), selected_vehicle, EIT_IN_LIST, 0); if (_settings_client.gui.show_cargo_in_vehicle_lists) { /* Get the cargoes the vehicle can carry */ @@ -1843,7 +1843,7 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int for (int i = 0; i < static_cast(vehgroup.NumVehicles()); ++i) { if (image_left + WidgetDimensions::scaled.hsep_wide * i >= image_right) break; // Break if there is no more space to draw any more vehicles anyway. - DrawVehicleImage(vehgroup.vehicles_begin[i], {image_left + WidgetDimensions::scaled.hsep_wide * i, ir.top, image_right, ir.bottom}, selected_vehicle, EIT_IN_LIST, 0); + DrawVehicleImage(vehgroup.vehicles_begin[i], ir.WithX(image_left + WidgetDimensions::scaled.hsep_wide * i, image_right), selected_vehicle, EIT_IN_LIST, 0); } if (show_orderlist) DrawSmallOrderList(vehgroup.vehicles_begin[0]->orders, olr.left, olr.right, ir.top + GetCharacterHeight(FS_SMALL), this->order_arrow_width); diff --git a/src/widget.cpp b/src/widget.cpp index 1248d0fb16ca0..cf89f126d7ded 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -510,8 +510,9 @@ static inline void DrawVerticalScrollbar(const Rect &r, Colours colour, bool up_ PixelColour c2 = GetColourGradient(colour, SHADE_LIGHTEST); /* draw "shaded" background */ - GfxFillRect(r.left, r.top + height, r.right, r.bottom - height, c2); - GfxFillRect(r.left, r.top + height, r.right, r.bottom - height, c1, FILLRECT_CHECKER); + Rect bg = r.Shrink(0, height); + GfxFillRect(bg, c2); + GfxFillRect(bg, c1, FILLRECT_CHECKER); /* track positions. These fractions are based on original 1x dimensions, but scale better. */ int left = r.left + r.Width() * 3 / 11; /* left track is positioned 3/11ths from the left */ @@ -520,10 +521,10 @@ static inline void DrawVerticalScrollbar(const Rect &r, Colours colour, bool up_ const uint8_t br = WidgetDimensions::scaled.bevel.right; /* draw shaded lines */ - GfxFillRect(left - bl, r.top + height, left - 1, r.bottom - height, c1); - GfxFillRect(left, r.top + height, left + br - 1, r.bottom - height, c2); - GfxFillRect(right - bl, r.top + height, right - 1, r.bottom - height, c1); - GfxFillRect(right, r.top + height, right + br - 1, r.bottom - height, c2); + GfxFillRect(bg.WithX(left - bl, left - 1), c1); + GfxFillRect(bg.WithX(left, left + br - 1), c2); + GfxFillRect(bg.WithX(right - bl, right - 1), c1); + GfxFillRect(bg.WithX(right, right + br - 1), c2); auto [top, bottom] = HandleScrollbarHittest(scrollbar, r.top, r.bottom, false); DrawFrameRect(r.left, top, r.right, bottom, colour, bar_dragged ? FrameFlag::Lowered : FrameFlags{}); @@ -549,8 +550,9 @@ static inline void DrawHorizontalScrollbar(const Rect &r, Colours colour, bool l PixelColour c2 = GetColourGradient(colour, SHADE_LIGHTEST); /* draw "shaded" background */ - GfxFillRect(r.left + width, r.top, r.right - width, r.bottom, c2); - GfxFillRect(r.left + width, r.top, r.right - width, r.bottom, c1, FILLRECT_CHECKER); + Rect bg = r.Shrink(width, 0); + GfxFillRect(bg, c2); + GfxFillRect(bg, c1, FILLRECT_CHECKER); /* track positions. These fractions are based on original 1x dimensions, but scale better. */ int top = r.top + r.Height() * 3 / 11; /* top track is positioned 3/11ths from the top */ @@ -559,10 +561,10 @@ static inline void DrawHorizontalScrollbar(const Rect &r, Colours colour, bool l const uint8_t bb = WidgetDimensions::scaled.bevel.bottom; /* draw shaded lines */ - GfxFillRect(r.left + width, top - bt, r.right - width, top - 1, c1); - GfxFillRect(r.left + width, top, r.right - width, top + bb - 1, c2); - GfxFillRect(r.left + width, bottom - bt, r.right - width, bottom - 1, c1); - GfxFillRect(r.left + width, bottom, r.right - width, bottom + bb - 1, c2); + GfxFillRect(bg.WithY(top - bt, top - 1), c1); + GfxFillRect(bg.WithY(top, top + bb - 1), c2); + GfxFillRect(bg.WithY(bottom - bt, bottom - 1), c1); + GfxFillRect(bg.WithY(bottom, bottom + bb - 1), c2); /* draw actual scrollbar */ auto [left, right] = HandleScrollbarHittest(scrollbar, r.left, r.right, true); From 37f737417cda13011d3a4db5226f83637d22448f Mon Sep 17 00:00:00 2001 From: translators Date: Sun, 28 Sep 2025 04:37:53 +0000 Subject: [PATCH 041/137] Update: Translations from eints english (au): 3 changes by krysclarke swedish: 3 changes by robert-i korean: 3 changes by telk5093 greek: 3 changes by gh658804 russian: 3 changes by Ln-Wolf finnish: 3 changes by hpiirai catalan: 3 changes by J0anJosep portuguese: 3 changes by jcteotonio portuguese (brazilian): 3 changes by pasantoro polish: 3 changes by pAter-exe --- src/lang/brazilian_portuguese.txt | 5 +++-- src/lang/catalan.txt | 5 +++-- src/lang/english_AU.txt | 5 +++-- src/lang/finnish.txt | 5 +++-- src/lang/greek.txt | 5 +++-- src/lang/korean.txt | 5 +++-- src/lang/polish.txt | 5 +++-- src/lang/portuguese.txt | 5 +++-- src/lang/russian.txt | 5 +++-- src/lang/swedish.txt | 5 +++-- 10 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index fefdaba10e48d..dd916cca9a35b 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -3431,8 +3431,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Água STR_MAPGEN_BORDER_RANDOM :{BLACK}Aleatório ###length 3 -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Aleatório -STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual +STR_MAPGEN_BORDER_RANDOMIZE :Aleatório +STR_MAPGEN_BORDER_MANUAL :Manual +STR_MAPGEN_BORDER_INFINITE_WATER :Água Infinita STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Rotação do mapa de altitudes: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Nome do mapa de altitudes: diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index 8125287d6dcab..118391db10aef 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -3431,8 +3431,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Aigua STR_MAPGEN_BORDER_RANDOM :{BLACK}Aleatori ###length 3 -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Aleatori -STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual +STR_MAPGEN_BORDER_RANDOMIZE :Aleatori +STR_MAPGEN_BORDER_MANUAL :Manual +STR_MAPGEN_BORDER_INFINITE_WATER :Aigua infinita STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Rotació del mapa d'alçades: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Nom del mapa d'alçades: diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt index 9b55f7cbb1895..734f92210b850 100644 --- a/src/lang/english_AU.txt +++ b/src/lang/english_AU.txt @@ -3430,8 +3430,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Water STR_MAPGEN_BORDER_RANDOM :{BLACK}Random ###length 3 -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Random -STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual +STR_MAPGEN_BORDER_RANDOMIZE :Random +STR_MAPGEN_BORDER_MANUAL :Manual +STR_MAPGEN_BORDER_INFINITE_WATER :Infinite Water STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Heightmap rotation: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Heightmap name: diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index 8a8cbac8b1d6f..b58fc0438a297 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -3430,8 +3430,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Vesi STR_MAPGEN_BORDER_RANDOM :{BLACK}Sattumanvarainen ###length 3 -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Sattumanvarainen -STR_MAPGEN_BORDER_MANUAL :{BLACK}Manuaalinen +STR_MAPGEN_BORDER_RANDOMIZE :Satunnaiset +STR_MAPGEN_BORDER_MANUAL :Aseta käsin +STR_MAPGEN_BORDER_INFINITE_WATER :Ääretön vesi STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Korkeuskartan kierto: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Korkeuskartan nimi: diff --git a/src/lang/greek.txt b/src/lang/greek.txt index 2c366e6440b71..9d6df28701210 100644 --- a/src/lang/greek.txt +++ b/src/lang/greek.txt @@ -3523,8 +3523,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Νερό STR_MAPGEN_BORDER_RANDOM :{BLACK}Τυχαία ###length 3 -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Τυχαία -STR_MAPGEN_BORDER_MANUAL :{BLACK}Χειροκίνητος +STR_MAPGEN_BORDER_RANDOMIZE :Τυχαία +STR_MAPGEN_BORDER_MANUAL :Χειροκίνητος +STR_MAPGEN_BORDER_INFINITE_WATER :Απεριόριστo Νερό STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Περιστροφή χάρτη υψομετρίας: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Όνομα χάρτη υψομετρίας: diff --git a/src/lang/korean.txt b/src/lang/korean.txt index 45c9642f8e5b3..4b47e9b0bd1f8 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -3431,8 +3431,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}물 STR_MAPGEN_BORDER_RANDOM :{BLACK}임의 ###length 3 -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}임의 -STR_MAPGEN_BORDER_MANUAL :{BLACK}사용자 정의 +STR_MAPGEN_BORDER_RANDOMIZE :임의 +STR_MAPGEN_BORDER_MANUAL :사용자 정의 +STR_MAPGEN_BORDER_INFINITE_WATER :물 (지도 밖까지 모두) STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}높이맵 방향: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}높이맵 이름: diff --git a/src/lang/polish.txt b/src/lang/polish.txt index 21f40b3f0885a..ac8b8b1424ba3 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -3810,8 +3810,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Woda STR_MAPGEN_BORDER_RANDOM :{BLACK}Losowe ###length 3 -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Losowo -STR_MAPGEN_BORDER_MANUAL :{BLACK}Użytkownika +STR_MAPGEN_BORDER_RANDOMIZE :Losowe +STR_MAPGEN_BORDER_MANUAL :Ustalone +STR_MAPGEN_BORDER_INFINITE_WATER :Bezkres Wód STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Obrót mapy wysokości: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Nazwa mapy wysokosci: diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index c5aa9fc218672..61532a91146e2 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -3431,8 +3431,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Água STR_MAPGEN_BORDER_RANDOM :{BLACK}Aleatório ###length 3 -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Aleatório -STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual +STR_MAPGEN_BORDER_RANDOMIZE :Aleatório +STR_MAPGEN_BORDER_MANUAL :Manual +STR_MAPGEN_BORDER_INFINITE_WATER :Água Infinita STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Rotação mapa de alt.: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Nome mapa de alt.: diff --git a/src/lang/russian.txt b/src/lang/russian.txt index 834471c13d774..6631323b3a57b 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -3605,8 +3605,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Водн STR_MAPGEN_BORDER_RANDOM :{BLACK}Случайно ###length 3 -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Случайно -STR_MAPGEN_BORDER_MANUAL :{BLACK}Вручную +STR_MAPGEN_BORDER_RANDOMIZE :Случайно +STR_MAPGEN_BORDER_MANUAL :Вручную +STR_MAPGEN_BORDER_INFINITE_WATER :Бескрайний океан STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Поворот карты: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Название карты: diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt index 66d739073967a..31af4a5536e3b 100644 --- a/src/lang/swedish.txt +++ b/src/lang/swedish.txt @@ -3430,8 +3430,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Vatten STR_MAPGEN_BORDER_RANDOM :{BLACK}På måfå ###length 3 -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}På måfå -STR_MAPGEN_BORDER_MANUAL :{BLACK}Manuella +STR_MAPGEN_BORDER_RANDOMIZE :Slumpmässig +STR_MAPGEN_BORDER_MANUAL :Manuellt +STR_MAPGEN_BORDER_INFINITE_WATER :Obegränsat vatten STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Höjdkartans rotation: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Namn på höjdkarta: From cb1c2409e6b0482705214f3d7afc938627097a75 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Thu, 25 Sep 2025 08:45:24 +0100 Subject: [PATCH 042/137] Codechange: Rework network client list buttons. Instead of calculating and storing which buttons to display for each line and then further calculating what each line should be when displaying it, store everything on one pass. This simplifies/deduplicates logic. --- src/network/network_gui.cpp | 409 ++++++++++++++++-------------------- 1 file changed, 183 insertions(+), 226 deletions(-) diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 61975b476ab12..c1d1dfbf10ba7 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -1381,6 +1381,159 @@ class Button : public ButtonCommon { using CompanyButton = Button; using ClientButton = Button; +/** + * Base interface for a network client list line. + */ +class ButtonLine { +public: + std::vector> buttons{}; ///< Buttons for this line. + + virtual ~ButtonLine() = default; + + /** + * Draw the button line. + * @param r Rect to draw within. + */ + virtual void Draw(Rect r) const = 0; + + template + T &AddButton(TArgs &&... args) + { + auto &button = this->buttons.emplace_back(std::make_unique(std::forward(args)...)); + return static_cast(*button); + } + + /** + * Get the button at a given point on the line. + * @param r Rect of line. + * @param pt Point of interest. + * @return Button at point, or \c nullptr if button isn't pressed. + */ + ButtonCommon *GetButton(Rect r, const Point &pt) const + { + bool rtl = _current_text_dir == TD_RTL; + for (auto &button : this->buttons) { + if (r.WithWidth(button->width, !rtl).Contains(pt)) return button.get(); + r = r.Indent(button->width + WidgetDimensions::scaled.hsep_normal, !rtl); + } + return nullptr; + } + + /** + * Get tooptip for a given point on the line. + * @param r Rect of line. + * @param pt Point of interest. + * @return EncodedString of tooltip, or \c std::nullopt if none. + */ + virtual std::optional GetTooltip(Rect r, const Point &pt) const + { + ButtonCommon *button = this->GetButton(r, pt); + if (button == nullptr) return {}; + return GetEncodedString(button->tooltip); + } + +protected: + /** + * Draw the buttons for this line. + * @param r Rect to draw within. + * @return Rect of remaining space. + */ + Rect DrawButtons(Rect r) const + { + bool rtl = _current_text_dir == TD_RTL; + for (auto &button : buttons) { + Rect br = r.CentreTo(r.Width(), button->height).WithWidth(button->width, !rtl); + DrawFrameRect(br, button->colour, {}); + DrawSpriteIgnorePadding(button->sprite, PAL_NONE, br, SA_CENTER); + if (button->disabled) { + GfxFillRect(br.Shrink(WidgetDimensions::scaled.bevel), GetColourGradient(button->colour, SHADE_DARKER), FILLRECT_CHECKER); + } + r = r.Indent(button->width + WidgetDimensions::scaled.hsep_normal, !rtl); + } + return r; + } +}; + +class CompanyButtonLine : public ButtonLine { +public: + CompanyButtonLine(CompanyID company_id) : company_id(company_id) {} + + void Draw(Rect r) const override + { + bool rtl = _current_text_dir == TD_RTL; + r = this->DrawButtons(r); + + Dimension d = GetSpriteSize(SPR_COMPANY_ICON); + PaletteID pal = Company::IsValidID(this->company_id) ? GetCompanyPalette(this->company_id) : PALETTE_TO_GREY; + DrawSpriteIgnorePadding(SPR_COMPANY_ICON, pal, r.WithWidth(d.width, rtl), SA_CENTER); + + Rect tr = r.CentreTo(r.Width(), GetCharacterHeight(FS_NORMAL)).Indent(d.width + WidgetDimensions::scaled.hsep_normal, rtl); + if (this->company_id == COMPANY_SPECTATOR) { + DrawString(tr, STR_NETWORK_CLIENT_LIST_SPECTATORS, TC_SILVER); + } else if (this->company_id == COMPANY_NEW_COMPANY) { + DrawString(tr, STR_NETWORK_CLIENT_LIST_NEW_COMPANY, TC_WHITE); + } else { + DrawString(tr, GetString(STR_COMPANY_NAME, this->company_id, this->company_id), TC_SILVER); + } + }; + +private: + CompanyID company_id; +}; + +class ClientButtonLine : public ButtonLine { +public: + ClientButtonLine(ClientPoolID client_pool_id) : client_pool_id(client_pool_id) {} + + void Draw(Rect r) const override + { + const NetworkClientInfo *ci = NetworkClientInfo::GetIfValid(this->client_pool_id); + if (ci == nullptr) return; + + bool rtl = _current_text_dir == TD_RTL; + r = this->DrawButtons(r); + + Rect tr = r.CentreTo(r.Width(), GetCharacterHeight(FS_NORMAL)); + + SpriteID player_icon = 0; + if (ci->client_id == _network_own_client_id) { + player_icon = SPR_PLAYER_SELF; + } else if (ci->client_id == CLIENT_ID_SERVER) { + player_icon = SPR_PLAYER_HOST; + } + + if (player_icon != 0) { + Dimension d = GetSpriteSize(player_icon); + DrawSpriteIgnorePadding(player_icon, PALETTE_TO_GREY, r.WithWidth(d.width, rtl), SA_CENTER); + tr = tr.Indent(d.width + WidgetDimensions::scaled.hsep_normal, rtl); + } + + DrawString(tr, GetString(STR_JUST_RAW_STRING, ci->client_name), TC_BLACK); + } + + std::optional GetTooltip(Rect r, const Point &pt) const override + { + bool rtl = _current_text_dir == TD_RTL; + Dimension d = GetSpriteSize(SPR_PLAYER_SELF); + + if (r.WithWidth(d.width, rtl).Contains(pt)) { + const NetworkClientInfo *ci = NetworkClientInfo::GetIfValid(this->client_pool_id); + if (ci != nullptr) { + if (ci->client_id == _network_own_client_id) { + return GetEncodedString(STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP); + } else if (ci->client_id == CLIENT_ID_SERVER) { + return GetEncodedString(STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP); + } + } + } + + return this->ButtonLine::GetTooltip(r, pt); + } + +private: + ClientPoolID client_pool_id; +}; + /** * Main handle for clientlist */ @@ -1393,12 +1546,9 @@ struct NetworkClientListWindow : Window { Scrollbar *vscroll = nullptr; ///< Vertical scrollbar of this window. uint line_height = 0; ///< Current lineheight of each entry in the matrix. - uint line_count = 0; ///< Amount of lines in the matrix. int hover_index = -1; ///< Index of the current line we are hovering over, or -1 if none. - int player_self_index = -1; ///< The line the current player is on. - int player_host_index = -1; ///< The line the host is on. - std::map>> buttons{}; ///< Per line which buttons are available. + std::vector> buttons{}; ///< Per line which buttons are available. /** * Chat button on a Company is clicked. @@ -1504,34 +1654,24 @@ struct NetworkClientListWindow : Window { */ void RebuildListCompany(CompanyID company_id, CompanyID client_playas, bool can_join_company) { - 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].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 (can_join_company) 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; + ButtonLine &company_line = *this->buttons.emplace_back(std::make_unique(company_id)); + if (_network_server) company_line.AddButton(SPR_ADMIN, STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP, COLOUR_RED, company_id, &NetworkClientListWindow::OnClickCompanyAdmin, company_id == COMPANY_SPECTATOR); + ButtonCommon &chat_button = company_line.AddButton(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 (can_join_company) company_line.AddButton(SPR_JOIN, STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP, COLOUR_ORANGE, company_id, &NetworkClientListWindow::OnClickCompanyJoin, company_id != COMPANY_SPECTATOR && Company::Get(company_id)->is_ai); bool has_players = false; for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { if (ci->client_playas != company_id) continue; has_players = true; - 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 (_network_own_client_id != ci->client_id && client_playas != COMPANY_SPECTATOR && !ci->CanJoinCompany(client_playas)) this->buttons[line_count].push_back(std::make_unique(SPR_JOIN, STR_NETWORK_CLIENT_LIST_COMPANY_AUTHORIZE_TOOLTIP, COLOUR_GREEN, ci->client_id, &NetworkClientListWindow::OnClickClientAuthorize)); - - if (ci->client_id == _network_own_client_id) { - this->player_self_index = this->line_count; - } else if (ci->client_id == CLIENT_ID_SERVER) { - this->player_host_index = this->line_count; - } - - this->line_count += 1; + ButtonLine &line = *this->buttons.emplace_back(std::make_unique(ci->index)); + if (_network_server) line.AddButton(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) line.AddButton(SPR_CHAT, STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP, COLOUR_ORANGE, ci->client_id, &NetworkClientListWindow::OnClickClientChat); + if (_network_own_client_id != ci->client_id && client_playas != COMPANY_SPECTATOR && !ci->CanJoinCompany(client_playas)) line.AddButton(SPR_JOIN, STR_NETWORK_CLIENT_LIST_COMPANY_AUTHORIZE_TOOLTIP, COLOUR_GREEN, ci->client_id, &NetworkClientListWindow::OnClickClientAuthorize); } /* Disable the chat button when there are players in this company. */ - chat_button->disabled = !has_players; + chat_button.disabled = !has_players; } /** @@ -1543,14 +1683,11 @@ struct NetworkClientListWindow : Window { CompanyID client_playas = own_ci == nullptr ? COMPANY_SPECTATOR : own_ci->client_playas; this->buttons.clear(); - this->line_count = 0; - this->player_host_index = -1; - this->player_self_index = -1; /* As spectator, show a line to create a new company. */ if (client_playas == COMPANY_SPECTATOR && !NetworkMaxCompaniesReached()) { - 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; + ButtonLine &line = *this->buttons.emplace_back(std::make_unique(COMPANY_NEW_COMPANY)); + line.AddButton(SPR_JOIN, STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP, COLOUR_ORANGE, COMPANY_SPECTATOR, &NetworkClientListWindow::OnClickCompanyNew); } if (client_playas != COMPANY_SPECTATOR) { @@ -1567,40 +1704,7 @@ struct NetworkClientListWindow : Window { /* Spectators */ this->RebuildListCompany(COMPANY_SPECTATOR, client_playas, client_playas != COMPANY_SPECTATOR); - this->vscroll->SetCount(this->line_count); - } - - /** - * Get the button at a specific point on the WID_CL_MATRIX. - * @param pt The point to look for a button. - * @return The button or a nullptr if there was none. - */ - ButtonCommon *GetButtonAtPoint(Point pt) - { - uint index = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_CL_MATRIX); - Rect matrix = this->GetWidget(WID_CL_MATRIX)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect); - - bool rtl = _current_text_dir == TD_RTL; - uint x = rtl ? matrix.left : matrix.right; - - /* Find the buttons for this row. */ - auto button_find = this->buttons.find(index); - if (button_find == this->buttons.end()) return nullptr; - - /* Check if we want to display a tooltip for any of the buttons. */ - for (auto &button : button_find->second) { - uint left = rtl ? x : x - button->width; - uint right = rtl ? x + button->width : x; - - if (IsInsideMM(pt.x, left, right)) { - return button.get(); - } - - int width = button->width + WidgetDimensions::scaled.framerect.Horizontal(); - x += rtl ? width : -width; - } - - return nullptr; + this->vscroll->SetCount(this->buttons.size()); } public: @@ -1614,7 +1718,7 @@ struct NetworkClientListWindow : Window { void OnInit() override { - RebuildList(); + this->RebuildList(); } void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override @@ -1718,7 +1822,11 @@ struct NetworkClientListWindow : Window { break; case WID_CL_MATRIX: { - ButtonCommon *button = this->GetButtonAtPoint(pt); + auto it = this->vscroll->GetScrolledItemFromWidget(this->buttons, pt.y, this, WID_CL_MATRIX); + if (it == std::end(this->buttons)) break; + + Rect r = this->GetWidget(WID_CL_MATRIX)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect); + ButtonCommon *button = (*it)->GetButton(r, pt); if (button == nullptr) break; button->OnClick(this, pt); @@ -1731,34 +1839,14 @@ struct NetworkClientListWindow : Window { { switch (widget) { case WID_CL_MATRIX: { - int index = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_CL_MATRIX); - - bool rtl = _current_text_dir == TD_RTL; - Rect matrix = this->GetWidget(WID_CL_MATRIX)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect); - - Dimension d = GetSpriteSize(SPR_COMPANY_ICON); - uint text_left = matrix.left + (rtl ? 0 : d.width + WidgetDimensions::scaled.hsep_wide); - uint text_right = matrix.right - (rtl ? d.width + WidgetDimensions::scaled.hsep_wide : 0); - - Dimension d2 = GetSpriteSize(SPR_PLAYER_SELF); - uint offset_x = WidgetDimensions::scaled.hsep_indent - d2.width - ScaleGUITrad(3); + auto it = this->vscroll->GetScrolledItemFromWidget(this->buttons, pt.y, this, WID_CL_MATRIX); + if (it == std::end(this->buttons)) break; - uint player_icon_x = rtl ? text_right - offset_x - d2.width : text_left + offset_x; + Rect r = this->GetWidget(WID_CL_MATRIX)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect); + auto tooltip = (*it)->GetTooltip(r, pt); + if (!tooltip.has_value()) break; - if (IsInsideMM(pt.x, player_icon_x, player_icon_x + d2.width)) { - if (index == this->player_self_index) { - GuiShowTooltips(this, GetEncodedString(STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP), close_cond); - return true; - } else if (index == this->player_host_index) { - GuiShowTooltips(this, GetEncodedString(STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP), close_cond); - return true; - } - } - - ButtonCommon *button = this->GetButtonAtPoint(pt); - if (button == nullptr) return false; - - GuiShowTooltips(this, GetEncodedString(button->tooltip), close_cond); + GuiShowTooltips(this, std::move(*tooltip), close_cond); return true; }; } @@ -1852,154 +1940,23 @@ struct NetworkClientListWindow : Window { } } - /** - * Draw the buttons for a single line in the matrix. - * - * The x-position in RTL is the most left or otherwise the most right pixel - * we can draw the buttons from. - * - * @param x The x-position to start with the buttons. Updated during this function. - * @param y The y-position to start with the buttons. - * @param buttons The buttons to draw. - */ - void DrawButtons(int &x, uint y, const std::vector> &buttons) const - { - Rect r; - - for (auto &button : buttons) { - bool rtl = _current_text_dir == TD_RTL; - - int offset = (this->line_height - button->height) / 2; - r.left = rtl ? x : x - button->width + 1; - r.right = rtl ? x + button->width - 1 : x; - r.top = y + offset; - r.bottom = r.top + button->height - 1; - - DrawFrameRect(r, button->colour, {}); - DrawSprite(button->sprite, PAL_NONE, r.left + WidgetDimensions::scaled.framerect.left, r.top + WidgetDimensions::scaled.framerect.top); - if (button->disabled) { - GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), GetColourGradient(button->colour, SHADE_DARKER), FILLRECT_CHECKER); - } - - int width = button->width + WidgetDimensions::scaled.hsep_normal; - x += rtl ? width : -width; - } - } - - /** - * Draw a company and its clients on the matrix. - * @param company_id The company to draw. - * @param r The rect to draw within. - * @param line The Nth line we are drawing. Updated during this function. - */ - void DrawCompany(CompanyID company_id, const Rect &r, uint &line) const - { - bool rtl = _current_text_dir == TD_RTL; - int text_y_offset = CentreBounds(0, this->line_height, GetCharacterHeight(FS_NORMAL)); - - Dimension d = GetSpriteSize(SPR_COMPANY_ICON); - int offset = CentreBounds(0, this->line_height, d.height); - - uint line_start = this->vscroll->GetPosition(); - uint line_end = line_start + this->vscroll->GetCapacity(); - - uint y = r.top + (this->line_height * (line - line_start)); - - /* Draw the company line (if in range of scrollbar). */ - if (IsInsideMM(line, line_start, line_end)) { - int icon_left = r.WithWidth(d.width, rtl).left; - Rect tr = r.Indent(d.width + WidgetDimensions::scaled.hsep_normal, rtl); - int &x = rtl ? tr.left : tr.right; - - /* If there are buttons for this company, draw them. */ - auto button_find = this->buttons.find(line); - if (button_find != this->buttons.end()) { - this->DrawButtons(x, y, button_find->second); - } - - if (company_id == COMPANY_SPECTATOR) { - DrawSprite(SPR_COMPANY_ICON, PALETTE_TO_GREY, icon_left, y + offset); - DrawString(tr.left, tr.right, y + text_y_offset, STR_NETWORK_CLIENT_LIST_SPECTATORS, TC_SILVER); - } else if (company_id == COMPANY_NEW_COMPANY) { - DrawSprite(SPR_COMPANY_ICON, PALETTE_TO_GREY, icon_left, y + offset); - DrawString(tr.left, tr.right, y + text_y_offset, STR_NETWORK_CLIENT_LIST_NEW_COMPANY, TC_WHITE); - } else { - DrawCompanyIcon(company_id, icon_left, y + offset); - - DrawString(tr.left, tr.right, y + text_y_offset, GetString(STR_COMPANY_NAME, company_id, company_id), TC_SILVER); - } - } - - y += this->line_height; - line++; - - for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { - if (ci->client_playas != company_id) continue; - - /* Draw the player line (if in range of scrollbar). */ - if (IsInsideMM(line, line_start, line_end)) { - Rect tr = r.Indent(WidgetDimensions::scaled.hsep_indent, rtl); - - /* If there are buttons for this client, draw them. */ - auto button_find = this->buttons.find(line); - if (button_find != this->buttons.end()) { - int &x = rtl ? tr.left : tr.right; - this->DrawButtons(x, y, button_find->second); - } - - SpriteID player_icon = 0; - if (ci->client_id == _network_own_client_id) { - player_icon = SPR_PLAYER_SELF; - } else if (ci->client_id == CLIENT_ID_SERVER) { - player_icon = SPR_PLAYER_HOST; - } - - if (player_icon != 0) { - Dimension d2 = GetSpriteSize(player_icon); - int offset_y = CentreBounds(0, this->line_height, d2.height); - DrawSprite(player_icon, PALETTE_TO_GREY, rtl ? tr.right - d2.width : tr.left, y + offset_y); - tr = tr.Indent(d2.width + WidgetDimensions::scaled.hsep_normal, rtl); - } - - DrawString(tr.left, tr.right, y + text_y_offset, GetString(STR_JUST_RAW_STRING, ci->client_name), TC_BLACK); - } - - y += this->line_height; - line++; - } - } - void DrawWidget(const Rect &r, WidgetID widget) const override { switch (widget) { case WID_CL_MATRIX: { - Rect ir = r.Shrink(WidgetDimensions::scaled.framerect, RectPadding::zero); - uint line = 0; + Rect ir = r.WithHeight(this->line_height).Shrink(WidgetDimensions::scaled.framerect, RectPadding::zero); if (this->hover_index >= 0) { Rect br = r.WithHeight(this->line_height).Translate(0, this->hover_index * this->line_height); GfxFillRect(br.Shrink(WidgetDimensions::scaled.bevel), GREY_SCALE(9)); } - NetworkClientInfo *own_ci = NetworkClientInfo::GetByClientID(_network_own_client_id); - CompanyID client_playas = own_ci == nullptr ? COMPANY_SPECTATOR : own_ci->client_playas; - - if (client_playas == COMPANY_SPECTATOR && !NetworkMaxCompaniesReached()) { - this->DrawCompany(COMPANY_NEW_COMPANY, ir, line); - } - - if (client_playas != COMPANY_SPECTATOR) { - this->DrawCompany(client_playas, ir, line); - } - - for (const Company *c : Company::Iterate()) { - if (client_playas == c->index) continue; - this->DrawCompany(c->index, ir, line); + auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->buttons); + for (auto it = first; it != last; ++it) { + (*it)->Draw(ir); + ir = ir.Translate(0, this->line_height); } - /* Spectators */ - this->DrawCompany(COMPANY_SPECTATOR, ir, line); - break; } } From 81530e2574134bf21471aaf1d2aaa4aaa763eaf2 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Thu, 25 Sep 2025 08:45:25 +0100 Subject: [PATCH 043/137] Change: Support interface scaling in network client list buttons. --- src/network/network_gui.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index c1d1dfbf10ba7..a8d2fc4859172 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -1339,7 +1339,7 @@ class ButtonCommon { colour(colour), disabled(disabled) { - Dimension d = GetSpriteSize(sprite); + Dimension d = GetScaledSpriteSize(sprite); this->height = d.height + WidgetDimensions::scaled.framerect.Vertical(); this->width = d.width + WidgetDimensions::scaled.framerect.Horizontal(); } @@ -1463,7 +1463,7 @@ class CompanyButtonLine : public ButtonLine { bool rtl = _current_text_dir == TD_RTL; r = this->DrawButtons(r); - Dimension d = GetSpriteSize(SPR_COMPANY_ICON); + Dimension d = GetScaledSpriteSize(SPR_COMPANY_ICON); PaletteID pal = Company::IsValidID(this->company_id) ? GetCompanyPalette(this->company_id) : PALETTE_TO_GREY; DrawSpriteIgnorePadding(SPR_COMPANY_ICON, pal, r.WithWidth(d.width, rtl), SA_CENTER); @@ -1503,7 +1503,7 @@ class ClientButtonLine : public ButtonLine { } if (player_icon != 0) { - Dimension d = GetSpriteSize(player_icon); + Dimension d = GetScaledSpriteSize(player_icon); DrawSpriteIgnorePadding(player_icon, PALETTE_TO_GREY, r.WithWidth(d.width, rtl), SA_CENTER); tr = tr.Indent(d.width + WidgetDimensions::scaled.hsep_normal, rtl); } @@ -1514,7 +1514,7 @@ class ClientButtonLine : public ButtonLine { std::optional GetTooltip(Rect r, const Point &pt) const override { bool rtl = _current_text_dir == TD_RTL; - Dimension d = GetSpriteSize(SPR_PLAYER_SELF); + Dimension d = GetScaledSpriteSize(SPR_PLAYER_SELF); if (r.WithWidth(d.width, rtl).Contains(pt)) { const NetworkClientInfo *ci = NetworkClientInfo::GetIfValid(this->client_pool_id); @@ -1754,7 +1754,7 @@ struct NetworkClientListWindow : Window { break; case WID_CL_MATRIX: { - uint height = std::max({GetSpriteSize(SPR_COMPANY_ICON).height, GetSpriteSize(SPR_JOIN).height, GetSpriteSize(SPR_ADMIN).height, GetSpriteSize(SPR_CHAT).height}); + uint height = std::max({GetScaledSpriteSize(SPR_COMPANY_ICON).height, GetScaledSpriteSize(SPR_JOIN).height, GetScaledSpriteSize(SPR_ADMIN).height, GetScaledSpriteSize(SPR_CHAT).height}); height += WidgetDimensions::scaled.framerect.Vertical(); this->line_height = std::max(height, (uint)GetCharacterHeight(FS_NORMAL)) + padding.height; From ff674829f5b335e4ae59d34eaf722944247ab19f Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 28 Sep 2025 14:09:36 +0100 Subject: [PATCH 044/137] Codechange: Replace Rect CentreTo with CentreToHeight. (#14675) So far all callers only need to centre vertically, so not having to provide the existing width simplifies calls. --- src/company_gui.cpp | 8 ++++---- src/core/geometry_type.hpp | 8 +++----- src/dropdown_common_type.h | 4 ++-- src/genworld_gui.cpp | 3 +-- src/network/network_gui.cpp | 6 +++--- src/newgrf_badge_gui.cpp | 4 ++-- src/widget.cpp | 2 +- 7 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 9debd59c5bbed..66dc383cbb207 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -1333,8 +1333,8 @@ class SelectCompanyManagerFaceWindow : public Window Rect ir = r.Shrink(WidgetDimensions::scaled.frametext, RectPadding::zero).WithHeight(this->line_height); bool rtl = _current_text_dir == TD_RTL; - Rect br = ir.CentreTo(ir.Width(), SETTING_BUTTON_HEIGHT).WithWidth(SETTING_BUTTON_WIDTH, rtl); - Rect tr = ir.Shrink(RectPadding::zero, WidgetDimensions::scaled.matrix).CentreTo(ir.Width(), GetCharacterHeight(FS_NORMAL)).Indent(SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_wide, rtl); + Rect br = ir.CentreToHeight(SETTING_BUTTON_HEIGHT).WithWidth(SETTING_BUTTON_WIDTH, rtl); + Rect tr = ir.Shrink(RectPadding::zero, WidgetDimensions::scaled.matrix).CentreToHeight(GetCharacterHeight(FS_NORMAL)).Indent(SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_wide, rtl); DrawArrowButtons(br.left, br.top, COLOUR_YELLOW, this->selected_var == UINT_MAX - 1 ? this->click_state : 0, true, true); DrawString(tr, GetString(STR_FACE_SETTING_NUMERIC, STR_FACE_STYLE, this->face.style + 1, GetNumCompanyManagerFaceStyles()), TC_WHITE); @@ -1352,8 +1352,8 @@ class SelectCompanyManagerFaceWindow : public Window const uint8_t var = static_cast(*it - vars.data()); const FaceVar &facevar = **it; - Rect br = ir.CentreTo(ir.Width(), SETTING_BUTTON_HEIGHT).WithWidth(SETTING_BUTTON_WIDTH, rtl); - Rect tr = ir.Shrink(RectPadding::zero, WidgetDimensions::scaled.matrix).CentreTo(ir.Width(), GetCharacterHeight(FS_NORMAL)).Indent(SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_wide, rtl); + Rect br = ir.CentreToHeight(SETTING_BUTTON_HEIGHT).WithWidth(SETTING_BUTTON_WIDTH, rtl); + Rect tr = ir.Shrink(RectPadding::zero, WidgetDimensions::scaled.matrix).CentreToHeight(GetCharacterHeight(FS_NORMAL)).Indent(SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_wide, rtl); uint val = vars[var].GetBits(this->face); if (facevar.type == FaceVarType::Toggle) { diff --git a/src/core/geometry_type.hpp b/src/core/geometry_type.hpp index 9e7cf625830f9..ccc610fa90d03 100644 --- a/src/core/geometry_type.hpp +++ b/src/core/geometry_type.hpp @@ -253,16 +253,14 @@ struct Rect { } /** - * Centre a dimension within this Rect. - * @param width The horizontal dimension. + * Centre a vertical dimension within this Rect. * @param height The vertical dimension. * @return the new resized Rect. */ - [[nodiscard]] inline Rect CentreTo(int width, int height) const + [[nodiscard]] inline Rect CentreToHeight(int height) const { - int new_left = CentreBounds(this->left, this->right, width); int new_top = CentreBounds(this->top, this->bottom, height); - return {new_left, new_top, new_left + width - 1, new_top + height - 1}; + return {this->left, new_top, this->right, new_top + height - 1}; } /** diff --git a/src/dropdown_common_type.h b/src/dropdown_common_type.h index e29aa16163121..81e2b36be9dfd 100644 --- a/src/dropdown_common_type.h +++ b/src/dropdown_common_type.h @@ -216,7 +216,7 @@ class DropDownToggle : public TBase { bool rtl = TEnd ^ (_current_text_dir == TD_RTL); int w = SETTING_BUTTON_WIDTH; - if (r.WithWidth(w, rtl).CentreTo(w, SETTING_BUTTON_HEIGHT).Contains(pt)) return this->click; + if (r.WithWidth(w, rtl).CentreToHeight(SETTING_BUTTON_HEIGHT).Contains(pt)) return this->click; return this->TBase::OnClick(r.Indent(w + WidgetDimensions::scaled.hsep_wide, rtl), pt); } @@ -226,7 +226,7 @@ class DropDownToggle : public TBase { bool rtl = TEnd ^ (_current_text_dir == TD_RTL); int w = SETTING_BUTTON_WIDTH; - Rect br = r.WithWidth(w, rtl).CentreTo(w, SETTING_BUTTON_HEIGHT); + Rect br = r.WithWidth(w, rtl).CentreToHeight(SETTING_BUTTON_HEIGHT); DrawBoolButton(br.left, br.top, this->button_colour, this->background_colour, this->on, true); this->TBase::Draw(full, r.Indent(w + WidgetDimensions::scaled.hsep_wide, rtl), sel, click_result, bg_colour); diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index f910f75cf351b..8bef4e4c818b8 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -1419,8 +1419,7 @@ struct GenerateProgressWindow : public Window { DrawFrameRect(r, COLOUR_GREY, {FrameFlag::BorderOnly, FrameFlag::Lowered}); Rect br = r.Shrink(WidgetDimensions::scaled.bevel); DrawFrameRect(br.WithWidth(br.Width() * GenWorldStatus::percent / 100, _current_text_dir == TD_RTL), COLOUR_MAUVE, {}); - DrawString(br.left, br.right, CentreBounds(br.top, br.bottom, GetCharacterHeight(FS_NORMAL)), - GetString(STR_GENERATION_PROGRESS, GenWorldStatus::percent), TC_FROMSTRING, SA_HOR_CENTER); + DrawString(br.CentreToHeight(GetCharacterHeight(FS_NORMAL)), GetString(STR_GENERATION_PROGRESS, GenWorldStatus::percent), TC_FROMSTRING, SA_HOR_CENTER); break; } diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index a8d2fc4859172..a437f776f7c45 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -1442,7 +1442,7 @@ class ButtonLine { { bool rtl = _current_text_dir == TD_RTL; for (auto &button : buttons) { - Rect br = r.CentreTo(r.Width(), button->height).WithWidth(button->width, !rtl); + Rect br = r.CentreToHeight(button->height).WithWidth(button->width, !rtl); DrawFrameRect(br, button->colour, {}); DrawSpriteIgnorePadding(button->sprite, PAL_NONE, br, SA_CENTER); if (button->disabled) { @@ -1467,7 +1467,7 @@ class CompanyButtonLine : public ButtonLine { PaletteID pal = Company::IsValidID(this->company_id) ? GetCompanyPalette(this->company_id) : PALETTE_TO_GREY; DrawSpriteIgnorePadding(SPR_COMPANY_ICON, pal, r.WithWidth(d.width, rtl), SA_CENTER); - Rect tr = r.CentreTo(r.Width(), GetCharacterHeight(FS_NORMAL)).Indent(d.width + WidgetDimensions::scaled.hsep_normal, rtl); + Rect tr = r.CentreToHeight(GetCharacterHeight(FS_NORMAL)).Indent(d.width + WidgetDimensions::scaled.hsep_normal, rtl); if (this->company_id == COMPANY_SPECTATOR) { DrawString(tr, STR_NETWORK_CLIENT_LIST_SPECTATORS, TC_SILVER); } else if (this->company_id == COMPANY_NEW_COMPANY) { @@ -1493,7 +1493,7 @@ class ClientButtonLine : public ButtonLine { bool rtl = _current_text_dir == TD_RTL; r = this->DrawButtons(r); - Rect tr = r.CentreTo(r.Width(), GetCharacterHeight(FS_NORMAL)); + Rect tr = r.CentreToHeight(GetCharacterHeight(FS_NORMAL)); SpriteID player_icon = 0; if (ci->client_id == _network_own_client_id) { diff --git a/src/newgrf_badge_gui.cpp b/src/newgrf_badge_gui.cpp index 0c6b1f82de162..8c10484df4ead 100644 --- a/src/newgrf_badge_gui.cpp +++ b/src/newgrf_badge_gui.cpp @@ -280,7 +280,7 @@ class DropDownMover : public TBase { bool rtl = (_current_text_dir == TD_RTL); int w = SETTING_BUTTON_WIDTH; - Rect br = r.WithWidth(w, TEnd ^ rtl).CentreTo(w, SETTING_BUTTON_HEIGHT); + Rect br = r.WithWidth(w, TEnd ^ rtl).CentreToHeight(SETTING_BUTTON_HEIGHT); if (br.WithWidth(w / 2, rtl).Contains(pt)) return this->click_up; if (br.WithWidth(w / 2, !rtl).Contains(pt)) return this->click_down; @@ -298,7 +298,7 @@ class DropDownMover : public TBase { if (click_result == this->click_down) state = 2; } - Rect br = r.WithWidth(w, TEnd ^ rtl).CentreTo(w, SETTING_BUTTON_HEIGHT); + Rect br = r.WithWidth(w, TEnd ^ rtl).CentreToHeight(SETTING_BUTTON_HEIGHT); DrawUpDownButtons(br.left, br.top, this->button_colour, state, this->click_up != 0, this->click_down != 0); this->TBase::Draw(full, r.Indent(w + WidgetDimensions::scaled.hsep_wide, TEnd ^ rtl), sel, click_result, bg_colour); diff --git a/src/widget.cpp b/src/widget.cpp index cf89f126d7ded..b99da3d4bfd5a 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -752,7 +752,7 @@ static inline void DrawButtonDropdown(const Rect &r, Colours colour, bool clicke Rect text = r.Indent(NWidgetLeaf::dropdown_dimension.width, !rtl); DrawFrameRect(text, colour, clicked_button ? FrameFlag::Lowered : FrameFlags{}); if (!str.empty()) { - text = text.CentreTo(text.Width(), GetCharacterHeight(FS_NORMAL)).Shrink(WidgetDimensions::scaled.dropdowntext, RectPadding::zero); + text = text.CentreToHeight(GetCharacterHeight(FS_NORMAL)).Shrink(WidgetDimensions::scaled.dropdowntext, RectPadding::zero); DrawString(text, str, TC_BLACK, align); } From 5ed8f1203bbb9696176f091fec78404d6ce72f9e Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 28 Sep 2025 18:09:57 +0100 Subject: [PATCH 045/137] Codechange: Cleanup unnecessary includes of spritecache.h (#14678) --- src/aircraft_cmd.cpp | 1 - src/aircraft_gui.cpp | 1 - src/depot_gui.cpp | 2 +- src/fontcache.h | 4 ++-- src/fontcache/spritefontcache.cpp | 1 + src/newgrf/newgrf_act12.cpp | 1 + src/newgrf_canal.cpp | 1 - src/rail_gui.cpp | 1 - src/roadveh_cmd.cpp | 1 - src/ship_cmd.cpp | 1 - src/ship_gui.cpp | 1 - src/spritecache_internal.h | 2 +- src/train_cmd.cpp | 1 - src/vehicle_gui.cpp | 1 - 14 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 91f0f7968f10a..f3cd7f09b735b 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -16,7 +16,6 @@ #include "news_func.h" #include "newgrf_engine.h" #include "newgrf_sound.h" -#include "spritecache.h" #include "error_func.h" #include "strings_func.h" #include "command_func.h" diff --git a/src/aircraft_gui.cpp b/src/aircraft_gui.cpp index 5b7d67582b92b..3709dfb7211ac 100644 --- a/src/aircraft_gui.cpp +++ b/src/aircraft_gui.cpp @@ -14,7 +14,6 @@ #include "strings_func.h" #include "vehicle_func.h" #include "window_gui.h" -#include "spritecache.h" #include "zoom_func.h" #include "table/strings.h" diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 18856c2a951a3..3644a31694225 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -17,7 +17,7 @@ #include "viewport_func.h" #include "command_func.h" #include "depot_base.h" -#include "spritecache.h" +#include "spritecache_type.h" #include "strings_func.h" #include "sound_func.h" #include "vehicle_func.h" diff --git a/src/fontcache.h b/src/fontcache.h index 099f9b17e631a..a74e0a57b6b34 100644 --- a/src/fontcache.h +++ b/src/fontcache.h @@ -10,9 +10,9 @@ #ifndef FONTCACHE_H #define FONTCACHE_H +#include "gfx_type.h" #include "provider_manager.h" -#include "string_type.h" -#include "spritecache.h" +#include "spritecache_type.h" /** Glyphs are characters from a font. */ typedef uint32_t GlyphID; diff --git a/src/fontcache/spritefontcache.cpp b/src/fontcache/spritefontcache.cpp index 96f9fd8cc3d67..a1c2f297707a0 100644 --- a/src/fontcache/spritefontcache.cpp +++ b/src/fontcache/spritefontcache.cpp @@ -10,6 +10,7 @@ #include "../stdafx.h" #include "../fontcache.h" #include "../gfx_layout.h" +#include "../spritecache.h" #include "../string_func.h" #include "../zoom_func.h" #include "spritefontcache.h" diff --git a/src/newgrf/newgrf_act12.cpp b/src/newgrf/newgrf_act12.cpp index 2e0250775b834..124d2f1afe9ab 100644 --- a/src/newgrf/newgrf_act12.cpp +++ b/src/newgrf/newgrf_act12.cpp @@ -10,6 +10,7 @@ #include "../stdafx.h" #include "../debug.h" #include "../fontcache.h" +#include "../spritecache.h" #include "newgrf_bytereader.h" #include "newgrf_internal.h" diff --git a/src/newgrf_canal.cpp b/src/newgrf_canal.cpp index 4cb05922dd1c3..0e593ba74922a 100644 --- a/src/newgrf_canal.cpp +++ b/src/newgrf_canal.cpp @@ -13,7 +13,6 @@ #include "newgrf_canal.h" #include "water.h" #include "water_map.h" -#include "spritecache.h" #include "safeguards.h" diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 7b9a503577e06..3ff53b06482ab 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -29,7 +29,6 @@ #include "dropdown_func.h" #include "tunnelbridge.h" #include "tilehighlight_func.h" -#include "spritecache.h" #include "core/geometry_func.hpp" #include "hotkeys.h" #include "engine_base.h" diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 70717f15b8901..060ec3694b32d 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -28,7 +28,6 @@ #include "depot_map.h" #include "effectvehicle_func.h" #include "roadstop_base.h" -#include "spritecache.h" #include "core/random_func.hpp" #include "company_base.h" #include "core/backup_type.hpp" diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index f741c93f8a986..c976cabc0a296 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -19,7 +19,6 @@ #include "pathfinder/yapf/yapf.h" #include "pathfinder/yapf/yapf_ship_regions.h" #include "newgrf_sound.h" -#include "spritecache.h" #include "strings_func.h" #include "window_func.h" #include "timer/timer_game_calendar.h" diff --git a/src/ship_gui.cpp b/src/ship_gui.cpp index 7bdedb82dc796..eb5eb4d42fbd0 100644 --- a/src/ship_gui.cpp +++ b/src/ship_gui.cpp @@ -14,7 +14,6 @@ #include "vehicle_gui.h" #include "strings_func.h" #include "vehicle_func.h" -#include "spritecache.h" #include "zoom_func.h" #include "table/strings.h" diff --git a/src/spritecache_internal.h b/src/spritecache_internal.h index 5d7b02e615eba..367db3601e76e 100644 --- a/src/spritecache_internal.h +++ b/src/spritecache_internal.h @@ -13,7 +13,7 @@ #include "core/math_func.hpp" #include "gfx_type.h" #include "spritecache_type.h" -#include "spriteloader/spriteloader.hpp" +#include "spriteloader/sprite_file_type.hpp" #include "table/sprites.h" diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 136f321c717fd..5723eb11cff84 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -26,7 +26,6 @@ #include "newgrf_station.h" #include "effectvehicle_func.h" #include "network/network.h" -#include "spritecache.h" #include "core/random_func.hpp" #include "company_base.h" #include "newgrf.h" diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 0ea6f71e445c5..251b905aa113b 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -30,7 +30,6 @@ #include "dropdown_func.h" #include "timetable.h" #include "articulated_vehicles.h" -#include "spritecache.h" #include "core/geometry_func.hpp" #include "core/container_func.hpp" #include "company_base.h" From 126669e10d9de26ae4c6d44958a4e7f9e8abeed5 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 9 Sep 2025 18:00:54 +0100 Subject: [PATCH 046/137] Codechange: Make GetRail/RoadTypeInfoIndex() a member method. This follows a similar pattern used for cargoes, houses and objects. Also fixes incorrect documentation of GetRoadTypeInfoIndex(). --- src/newgrf_railtype.cpp | 2 +- src/newgrf_roadtype.cpp | 2 +- src/rail.cpp | 12 ++++++++++++ src/rail.h | 15 ++------------- src/road.cpp | 12 ++++++++++++ src/road.h | 15 ++------------- 6 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/newgrf_railtype.cpp b/src/newgrf_railtype.cpp index 0d215971b85f1..67754addb2de6 100644 --- a/src/newgrf_railtype.cpp +++ b/src/newgrf_railtype.cpp @@ -35,7 +35,7 @@ case 0x43: return TimerGameCalendar::date.base(); case 0x44: return to_underlying(HouseZone::TownEdge); case 0x45: { - auto rt = GetRailTypeInfoIndex(this->rti); + RailType rt = this->rti->Index(); uint8_t local = GetReverseRailTypeTranslation(rt, this->ro.grffile); if (local == 0xFF) local = 0xFE; return 0xFFFF | local << 16; diff --git a/src/newgrf_roadtype.cpp b/src/newgrf_roadtype.cpp index e48a67b11a177..6b40a1e0d83b0 100644 --- a/src/newgrf_roadtype.cpp +++ b/src/newgrf_roadtype.cpp @@ -69,7 +69,7 @@ uint32_t GetTrackTypes(TileIndex tile, const GRFFile *grffile) case 0x43: return TimerGameCalendar::date.base(); case 0x44: return to_underlying(HouseZone::TownEdge); case 0x45: { - auto rt = GetRoadTypeInfoIndex(this->rti); + RoadType rt = this->rti->Index(); uint8_t local = GetReverseRoadTypeTranslation(rt, this->ro.grffile); if (local == 0xFF) local = 0xFE; if (RoadTypeIsRoad(rt)) { diff --git a/src/rail.cpp b/src/rail.cpp index d9e41087e389d..590676aa87681 100644 --- a/src/rail.cpp +++ b/src/rail.cpp @@ -19,6 +19,18 @@ #include "safeguards.h" +/** + * Get the RailType for this RailTypeInfo. + * @return RailType in static RailTypeInfo definitions. + */ +RailType RailTypeInfo::Index() const +{ + extern RailTypeInfo _railtypes[RAILTYPE_END]; + size_t index = this - _railtypes; + assert(index < RAILTYPE_END); + return static_cast(index); +} + /** * Return the rail type of tile, or INVALID_RAILTYPE if this is no rail tile. */ diff --git a/src/rail.h b/src/rail.h index 4a294e213dbe5..631a7989d09d8 100644 --- a/src/rail.h +++ b/src/rail.h @@ -286,6 +286,8 @@ class RailTypeInfo { { return 82 * this->fallback_railtype; } + + RailType Index() const; }; @@ -301,19 +303,6 @@ inline const RailTypeInfo *GetRailTypeInfo(RailType railtype) return &_railtypes[railtype]; } -/** - * Returns the railtype for a Railtype information. - * @param rti Pointer to static RailTypeInfo - * @return Railtype in static railtype definitions - */ -inline RailType GetRailTypeInfoIndex(const RailTypeInfo *rti) -{ - extern RailTypeInfo _railtypes[RAILTYPE_END]; - size_t index = rti - _railtypes; - assert(index < RAILTYPE_END && rti == _railtypes + index); - return static_cast(index); -} - /** * Returns all compatible railtypes for a set of railtypes. * @param railtypes Set of railtypes to get the compatible railtypes from. diff --git a/src/road.cpp b/src/road.cpp index 5b796f12eaedd..51bdf1900d39d 100644 --- a/src/road.cpp +++ b/src/road.cpp @@ -23,6 +23,18 @@ #include "safeguards.h" +/** + * Get the RoadType for this RoadTypeInfo. + * @return RoadType in static RoadTypeInfo definitions. + */ +RoadType RoadTypeInfo::Index() const +{ + extern RoadTypeInfo _roadtypes[ROADTYPE_END]; + size_t index = this - _roadtypes; + assert(index < ROADTYPE_END); + return static_cast(index); +} + /** * Return if the tile is a valid tile for a crossing. * diff --git a/src/road.h b/src/road.h index 76355d216e807..a3c689419fba5 100644 --- a/src/road.h +++ b/src/road.h @@ -185,6 +185,8 @@ class RoadTypeInfo { { return this->group[ROTSG_GROUND] != nullptr; } + + RoadType Index() const; }; /** @@ -231,19 +233,6 @@ inline const RoadTypeInfo *GetRoadTypeInfo(RoadType roadtype) return &_roadtypes[roadtype]; } -/** - * Returns the railtype for a Railtype information. - * @param rti Pointer to static RailTypeInfo - * @return Railtype in static railtype definitions - */ -inline RoadType GetRoadTypeInfoIndex(const RoadTypeInfo *rti) -{ - extern RoadTypeInfo _roadtypes[ROADTYPE_END]; - size_t index = rti - _roadtypes; - assert(index < ROADTYPE_END && rti == _roadtypes + index); - return static_cast(index); -} - /** * Checks if an engine of the given RoadType got power on a tile with a given * RoadType. This would normally just be an equality check, but for electrified From ca8fb69ffd1baa6bb3e8d2afd4ac6b3a089a0f78 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 9 Sep 2025 21:07:01 +0100 Subject: [PATCH 047/137] Codechange: Use std algorithm when allocating rail/road type. Use `std::ranges::find()` instead of a `for`-loop to allocate rail and road types. --- src/rail_cmd.cpp | 45 +++++++++++++++---------------- src/road_cmd.cpp | 69 ++++++++++++++++++++++-------------------------- 2 files changed, 54 insertions(+), 60 deletions(-) diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index fa702799559ba..e7c9c627cf71d 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -148,34 +148,33 @@ void InitRailTypes() */ RailType AllocateRailType(RailTypeLabel label) { - for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { - RailTypeInfo *rti = &_railtypes[rt]; + auto it = std::ranges::find(_railtypes, 0, &RailTypeInfo::label); + if (it == std::end(_railtypes)) return INVALID_RAILTYPE; - if (rti->label == 0) { - /* Set up new rail type */ - *rti = _original_railtypes[RAILTYPE_RAIL]; - rti->label = label; - rti->alternate_labels.clear(); + RailTypeInfo &rti = *it; + RailType rt = rti.Index(); - /* Make us compatible with ourself. */ - rti->powered_railtypes = rt; - rti->compatible_railtypes = rt; + /* Set up new rail type based on default rail. */ + rti = _original_railtypes[RAILTYPE_RAIL]; + rti.label = label; + rti.alternate_labels.clear(); - /* We also introduce ourself. */ - rti->introduces_railtypes = rt; + /* Make us compatible with ourself. */ + rti.powered_railtypes = rt; + rti.compatible_railtypes = rt; - /* Default sort order; order of allocation, but with some - * offsets so it's easier for NewGRF to pick a spot without - * changing the order of other (original) rail types. - * The << is so you can place other railtypes in between the - * other railtypes, the 7 is to be able to place something - * before the first (default) rail type. */ - rti->sorting_order = rt << 4 | 7; - return rt; - } - } + /* We also introduce ourself. */ + rti.introduces_railtypes = rt; + + /* Default sort order; order of allocation, but with some + * offsets so it's easier for NewGRF to pick a spot without + * changing the order of other (original) rail types. + * The << is so you can place other railtypes in between the + * other railtypes, the 7 is to be able to place something + * before the first (default) rail type. */ + rti.sorting_order = rt << 4 | 7; - return INVALID_RAILTYPE; + return rt; } static const uint8_t _track_sloped_sprites[14] = { diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index eea76ef76a99f..f2609fc617dbc 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -129,43 +129,38 @@ void InitRoadTypes() */ RoadType AllocateRoadType(RoadTypeLabel label, RoadTramType rtt) { - for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { - RoadTypeInfo *rti = &_roadtypes[rt]; - - if (rti->label == 0) { - /* Set up new road type */ - *rti = _original_roadtypes[(rtt == RTT_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD]; - rti->label = label; - rti->alternate_labels.clear(); - rti->flags = {}; - rti->introduction_date = CalendarTime::INVALID_DATE; - - /* Make us compatible with ourself. */ - rti->powered_roadtypes = rt; - - /* We also introduce ourself. */ - rti->introduces_roadtypes = rt; - - /* Default sort order; order of allocation, but with some - * offsets so it's easier for NewGRF to pick a spot without - * changing the order of other (original) road types. - * The << is so you can place other roadtypes in between the - * other roadtypes, the 7 is to be able to place something - * before the first (default) road type. */ - rti->sorting_order = rt << 2 | 7; - - /* Set bitmap of road/tram types */ - if (rtt == RTT_TRAM) { - _roadtypes_tram.Set(rt); - } else { - _roadtypes_road.Set(rt); - } - - return rt; - } - } - - return INVALID_ROADTYPE; + auto it = std::ranges::find(_roadtypes, 0, &RoadTypeInfo::label); + if (it == std::end(_roadtypes)) return INVALID_ROADTYPE; + + RoadTypeInfo &rti = *it; + RoadType rt = rti.Index(); + + /* Set up new road type based on default tram or road. */ + rti = _original_roadtypes[(rtt == RTT_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD]; + rti.label = label; + rti.alternate_labels.clear(); + rti.flags = {}; + rti.introduction_date = CalendarTime::INVALID_DATE; + + /* Make us compatible with ourself. */ + rti.powered_roadtypes = rt; + + /* We also introduce ourself. */ + rti.introduces_roadtypes = rt; + + /* Default sort order; order of allocation, but with some + * offsets so it's easier for NewGRF to pick a spot without + * changing the order of other (original) road types. + * The << is so you can place other roadtypes in between the + * other roadtypes, the 7 is to be able to place something + * before the first (default) road type. */ + rti.sorting_order = rt << 2 | 7; + + /* Set bitmap of road/tram types */ + _roadtypes_road.Set(rt, rtt == RTT_ROAD); + _roadtypes_tram.Set(rt, rtt == RTT_TRAM); + + return rt; } /** From 29136350cfee87b2b3869aa8034852e57b3aec8c Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 9 Sep 2025 21:14:17 +0100 Subject: [PATCH 048/137] Codechange: Initialise rail/road types with range-for. Replace double loop with single loop that performs both parts together. --- src/rail_cmd.cpp | 15 +++++++-------- src/road_cmd.cpp | 15 +++++++-------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index e7c9c627cf71d..e2ee0b781be15 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -129,15 +129,14 @@ static bool CompareRailTypes(const RailType &first, const RailType &second) */ void InitRailTypes() { - for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { - RailTypeInfo *rti = &_railtypes[rt]; - ResolveRailTypeGUISprites(rti); - if (rti->flags.Test(RailTypeFlag::Hidden)) _railtypes_hidden_mask.Set(rt); - } - _sorted_railtypes.clear(); - for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { - if (_railtypes[rt].label == 0) continue; + for (RailTypeInfo &rti : _railtypes) { + RailType rt = rti.Index(); + + ResolveRailTypeGUISprites(&rti); + _railtypes_hidden_mask.Set(rt, rti.flags.Test(RailTypeFlag::Hidden)); + + if (rti.label == 0) continue; _sorted_railtypes.push_back(rt); } std::sort(_sorted_railtypes.begin(), _sorted_railtypes.end(), CompareRailTypes); diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index f2609fc617dbc..4b5d93682dd92 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -110,15 +110,14 @@ static bool CompareRoadTypes(const RoadType &first, const RoadType &second) */ void InitRoadTypes() { - for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { - RoadTypeInfo *rti = &_roadtypes[rt]; - ResolveRoadTypeGUISprites(rti); - if (rti->flags.Test(RoadTypeFlag::Hidden)) _roadtypes_hidden_mask.Set(rt); - } - _sorted_roadtypes.clear(); - for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { - if (_roadtypes[rt].label == 0) continue; + for (RoadTypeInfo &rti : _roadtypes) { + RoadType rt = rti.Index(); + + ResolveRoadTypeGUISprites(&rti); + _roadtypes_hidden_mask.Set(rt, rti.flags.Test(RoadTypeFlag::Hidden)); + + if (rti.label == 0) continue; _sorted_roadtypes.push_back(rt); } std::sort(_sorted_roadtypes.begin(), _sorted_roadtypes.end(), CompareRoadTypes); From c8220494de28c993141b657a9d082becf61f0bee Mon Sep 17 00:00:00 2001 From: Su Date: Sun, 28 Sep 2025 20:18:23 +0100 Subject: [PATCH 049/137] Change: replace the "(City)" identifier in the town directory with the city icon (#14634) --- src/lang/english.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 9aab6f47bbcc6..240fc2ac059a4 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -3691,7 +3691,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Enter a STR_TOWN_DIRECTORY_CAPTION :{WHITE}Towns ({COMMA} of {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- None - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (City){BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA}) {YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Town names - click on name to centre main view on town. Ctrl+Click to open a new viewport on town location STR_TOWN_POPULATION :{BLACK}World population: {COMMA} From 8eaf511f0c7929454eb8b083e3a1e777004db77c Mon Sep 17 00:00:00 2001 From: translators Date: Mon, 29 Sep 2025 04:39:03 +0000 Subject: [PATCH 050/137] Update: Translations from eints english (us): 3 changes by 2TallTyler galician: 9 changes by pvillaverde --- src/lang/afrikaans.txt | 1 - src/lang/arabic_egypt.txt | 1 - src/lang/belarusian.txt | 1 - src/lang/brazilian_portuguese.txt | 1 - src/lang/bulgarian.txt | 1 - src/lang/catalan.txt | 1 - src/lang/croatian.txt | 1 - src/lang/czech.txt | 1 - src/lang/danish.txt | 1 - src/lang/dutch.txt | 1 - src/lang/english_AU.txt | 1 - src/lang/english_US.txt | 6 +++--- src/lang/esperanto.txt | 1 - src/lang/estonian.txt | 1 - src/lang/finnish.txt | 1 - src/lang/french.txt | 1 - src/lang/galician.txt | 12 +++++++++--- src/lang/german.txt | 1 - src/lang/greek.txt | 1 - src/lang/hebrew.txt | 1 - src/lang/hungarian.txt | 1 - src/lang/indonesian.txt | 1 - src/lang/irish.txt | 1 - src/lang/italian.txt | 1 - src/lang/japanese.txt | 1 - src/lang/korean.txt | 1 - src/lang/latin.txt | 1 - src/lang/latvian.txt | 1 - src/lang/lithuanian.txt | 1 - src/lang/luxembourgish.txt | 1 - src/lang/maori.txt | 1 - src/lang/norwegian_bokmal.txt | 1 - src/lang/persian.txt | 1 - src/lang/polish.txt | 1 - src/lang/portuguese.txt | 1 - src/lang/romanian.txt | 1 - src/lang/russian.txt | 1 - src/lang/serbian.txt | 1 - src/lang/simplified_chinese.txt | 1 - src/lang/slovak.txt | 1 - src/lang/slovenian.txt | 1 - src/lang/spanish.txt | 1 - src/lang/spanish_MX.txt | 1 - src/lang/swedish.txt | 1 - src/lang/tamil.txt | 1 - src/lang/thai.txt | 1 - src/lang/traditional_chinese.txt | 1 - src/lang/turkish.txt | 1 - src/lang/ukrainian.txt | 1 - src/lang/vietnamese.txt | 1 - src/lang/welsh.txt | 1 - 51 files changed, 12 insertions(+), 55 deletions(-) diff --git a/src/lang/afrikaans.txt b/src/lang/afrikaans.txt index 9b1b1f2d00cfd..9c98637e2381c 100644 --- a/src/lang/afrikaans.txt +++ b/src/lang/afrikaans.txt @@ -3075,7 +3075,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Tik 'n n # Town directory window STR_TOWN_DIRECTORY_NONE :{ORANGE}- Geen - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Stad){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Dorpname - klik op 'n naam om skerm daarna te skuif. Ctrl+klik om 'n nuwe venster vir die dorp oop te maak STR_TOWN_POPULATION :{BLACK}Wêreldbevolking: {COMMA} diff --git a/src/lang/arabic_egypt.txt b/src/lang/arabic_egypt.txt index 45f5a44a807f8..0a1b38a540477 100644 --- a/src/lang/arabic_egypt.txt +++ b/src/lang/arabic_egypt.txt @@ -2992,7 +2992,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}ادخل # Town directory window STR_TOWN_DIRECTORY_NONE :{ORANGE}-بدون- STR_TOWN_DIRECTORY_TOWN :{ORANGE}{RLE}{TOWN}{BLACK} {RLM}({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{RLE}{TOWN}{YELLOW} (مدينة){BLACK} {RLM}({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}اسم المدينة - اضغط على الاسم لتوسيط الشاشة عليها. اضغط + كنترول لفتح شاشة عرض جديدة للضاحية. STR_TOWN_POPULATION :{BLACK}سكان العالم: {COMMA} diff --git a/src/lang/belarusian.txt b/src/lang/belarusian.txt index 088433e101ba5..814bd6c5752c5 100644 --- a/src/lang/belarusian.txt +++ b/src/lang/belarusian.txt @@ -3880,7 +3880,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Увяд # Town directory window STR_TOWN_DIRECTORY_NONE :{ORANGE}- Няма - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Мегаполіс){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Сьпіс гарадоў: пстрычка па назьве паказвае горад у асноўным вакне. Ctrl+пстрычка — у дадатковым вакне. STR_TOWN_POPULATION :{BLACK}Насельніцтва: {COMMA} diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index dd916cca9a35b..762bcab37326c 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -3692,7 +3692,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Introduz STR_TOWN_DIRECTORY_CAPTION :{WHITE}Localidades ({COMMA} of {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Nenhum - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Cidade){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Nomes das localidades - clique em um nome para centralizar a visualização principal na cidade. Ctrl+Clique para abrir uma nova visualização na localização da localidade STR_TOWN_POPULATION :{BLACK}População mundial: {COMMA} diff --git a/src/lang/bulgarian.txt b/src/lang/bulgarian.txt index 8358254842c0b..a45f727b20a26 100644 --- a/src/lang/bulgarian.txt +++ b/src/lang/bulgarian.txt @@ -3620,7 +3620,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Въве STR_TOWN_DIRECTORY_CAPTION :{WHITE}Градове ({COMMA} от {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Отсъства - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (метрополис){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Имена на градовете - натиснете на името, за да центрирате камерата върху този град. Ctrl+Click отваря прозорец с нов изглед към града STR_TOWN_POPULATION :{BLACK}Обща популация на картата: {COMMA} diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index 118391db10aef..9f29851a9c266 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -3692,7 +3692,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Posa un STR_TOWN_DIRECTORY_CAPTION :{WHITE}Poblacions ({COMMA} de {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Cap - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA} -{YELLOW} ciutat{BLACK}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Noms de les poblacions - feu clic al nom d'una població per a centrar-hi la vista principal. Amb Ctrl+clic, s'obre una vista nova centrada on hi ha la població. STR_TOWN_POPULATION :{BLACK}Població mundial: {COMMA} diff --git a/src/lang/croatian.txt b/src/lang/croatian.txt index 3b47a5321bc4d..2fcb9bb0b3400 100644 --- a/src/lang/croatian.txt +++ b/src/lang/croatian.txt @@ -3249,7 +3249,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Unesi im # Town directory window STR_TOWN_DIRECTORY_NONE :{ORANGE}- Ništa - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Grad){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Imena gradova - klikni na ime kako bi centrirao pogled na grad. Ctrl+klik otvara novi prozor sa lokacijom grada STR_TOWN_POPULATION :{BLACK}Svjetsko stanovništvo: {COMMA} diff --git a/src/lang/czech.txt b/src/lang/czech.txt index 52af5153df177..06d4ae0371061 100644 --- a/src/lang/czech.txt +++ b/src/lang/czech.txt @@ -3723,7 +3723,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Zadej n STR_TOWN_DIRECTORY_CAPTION :{WHITE}Města ({COMMA} z {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Nic - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (velkoměsto){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Jména měst - pohled na město zaměříš kliknutím na jeho jméno. Při stisknutém Ctrl otevřeš nový pohled STR_TOWN_POPULATION :{BLACK}Populace světa: {COMMA} diff --git a/src/lang/danish.txt b/src/lang/danish.txt index 2cf618905656b..dd755db6fa731 100644 --- a/src/lang/danish.txt +++ b/src/lang/danish.txt @@ -3690,7 +3690,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Indtast STR_TOWN_DIRECTORY_CAPTION :{WHITE}Byer ({COMMA} of {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Ingen - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (storby){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Bynavne - klik på et navn for at centrere skærmen over byen. Ctrl+Klik åbner et nyt vindue ved byens lokalitet. STR_TOWN_POPULATION :{BLACK}Verdens befolkning: {COMMA} diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt index 0bd5d514a0114..884055d6d71dd 100644 --- a/src/lang/dutch.txt +++ b/src/lang/dutch.txt @@ -3690,7 +3690,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Geef een STR_TOWN_DIRECTORY_CAPTION :{WHITE}Steden ({COMMA} van {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE} Geen STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (groeistad){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Plaatsnamen - klik op naam om het scherm te centreren op de stad. Ctrl+klik opent een nieuw kijkvenster op de locatie van de stad STR_TOWN_POPULATION :{BLACK}Wereldbevolking: {COMMA} diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt index 734f92210b850..0b1ba3134d95a 100644 --- a/src/lang/english_AU.txt +++ b/src/lang/english_AU.txt @@ -3691,7 +3691,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Enter a STR_TOWN_DIRECTORY_CAPTION :{WHITE}Towns ({COMMA} of {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- None - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (City){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Town names - click on name to centre main view on town. Ctrl+Click to open a new viewport on town location STR_TOWN_POPULATION :{BLACK}World population: {COMMA} diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index 5983f412d0d7b..10ad2ad02ab55 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -3430,8 +3430,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Water STR_MAPGEN_BORDER_RANDOM :{BLACK}Random ###length 3 -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Random -STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual +STR_MAPGEN_BORDER_RANDOMIZE :Random +STR_MAPGEN_BORDER_MANUAL :Manual +STR_MAPGEN_BORDER_INFINITE_WATER :Infinite Water STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Heightmap rotation: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Heightmap name: @@ -3690,7 +3691,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Enter a STR_TOWN_DIRECTORY_CAPTION :{WHITE}Towns ({COMMA} of {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- None - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (City){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Town names - click on name to center main view on town. Ctrl+Click to open a new viewport on town location STR_TOWN_POPULATION :{BLACK}World population: {COMMA} diff --git a/src/lang/esperanto.txt b/src/lang/esperanto.txt index afe5f84a31c9e..f8ee39b52d70a 100644 --- a/src/lang/esperanto.txt +++ b/src/lang/esperanto.txt @@ -3479,7 +3479,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Enigu no # Town directory window STR_TOWN_DIRECTORY_NONE :{ORANGE}-Neniu - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Urbego){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Urbonomoj - klaku nomon por centri vidpukto ĉe la urbo. Ctrl+Klak por malfermi novan vidujon ĉe la urba loko STR_TOWN_POPULATION :{BLACK}Monda enloĝantaro: {COMMA} diff --git a/src/lang/estonian.txt b/src/lang/estonian.txt index 1e9fa32ff4492..7c4f76532189c 100644 --- a/src/lang/estonian.txt +++ b/src/lang/estonian.txt @@ -3628,7 +3628,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Sisesta # Town directory window STR_TOWN_DIRECTORY_NONE :{ORANGE}- Puudub - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Linn){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Astuste nimed - vajuta nimele, et viia vaade asustusele. Ctrl+klõps avab uue vaate linna asukohas STR_TOWN_POPULATION :{BLACK}Maailma rahvaarv: {COMMA} diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index b58fc0438a297..a377d6509c1c4 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -3691,7 +3691,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Syötä STR_TOWN_DIRECTORY_CAPTION :{WHITE}Kunnat ({COMMA}/{COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Ei mitään - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (kaupunki){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Kuntien nimet – keskitä päänäkymä kuntaan napsauttamalla nimeä. Ctrl+napsautus avaa uuden näkymäikkunan kunnan sijaintiin STR_TOWN_POPULATION :{BLACK}Maailman asukasluku: {COMMA} diff --git a/src/lang/french.txt b/src/lang/french.txt index 0e4e6fc263a3b..a142fa87647b6 100644 --- a/src/lang/french.txt +++ b/src/lang/french.txt @@ -3691,7 +3691,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Entrer u STR_TOWN_DIRECTORY_CAPTION :{WHITE}Villes ({COMMA} de {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}− Aucune − STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Métropole){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Noms des villes - Cliquer sur un nom pour centrer la vue principale sur la ville. Ctrl-clic pour ouvrir une nouvelle vue sur la ville. STR_TOWN_POPULATION :{BLACK}Population mondiale{NBSP}: {COMMA} diff --git a/src/lang/galician.txt b/src/lang/galician.txt index b9a979c8a8bcd..c4ec239fcd84f 100644 --- a/src/lang/galician.txt +++ b/src/lang/galician.txt @@ -3349,6 +3349,8 @@ STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtro: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Sobrescribir arquivo STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Estás seguro de que queres rescribir este arquivo? +STR_SAVELOAD_DELETE_TITLE :{WHITE}Borrar ficheiro +STR_SAVELOAD_DELETE_WARNING :{YELLOW}Estás seguro de que queres borrar este ficheiro? STR_SAVELOAD_DIRECTORY :{STRING} (Directorio) STR_SAVELOAD_PARENT_DIRECTORY :{STRING} (Directorio pai) @@ -3429,8 +3431,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Auga STR_MAPGEN_BORDER_RANDOM :{BLACK}Aleatorio ###length 3 -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Aleatorio -STR_MAPGEN_BORDER_MANUAL :{BLACK}Manual +STR_MAPGEN_BORDER_RANDOMIZE :Aleatorio +STR_MAPGEN_BORDER_MANUAL :Manual +STR_MAPGEN_BORDER_INFINITE_WATER :Auga infinita STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Rotación do mapa de alturas: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Nome do mapa de alturas: @@ -3689,7 +3692,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Escribe STR_TOWN_DIRECTORY_CAPTION :{WHITE}Vilas ({COMMA} de {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Ningunha - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Vila){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Nomes de vilas - pincha no nome para centrar a vista na vila. Ctrl+Clic abre unha nova fiestra na localización da vila STR_TOWN_POPULATION :{BLACK}Poboación mundial: {COMMA} @@ -4186,6 +4188,7 @@ STR_PURCHASE_INFO_ALL_BUT :Todos excepto { STR_PURCHASE_INFO_MAX_TE :{BLACK}Esforzo máximo de tracción: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Autonomía: {GOLD}{COMMA} cadros STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Tipo de aeronave: {GOLD}{STRING} +STR_PURCHASE_INFO_RAILTYPES :{BLACK}Tipos de ferrocarril: {GOLD}{STRING} ###length 3 STR_CARGO_TYPE_FILTER_ALL :Todos os tipos de carga @@ -4369,6 +4372,7 @@ STR_ENGINE_PREVIEW_RUNCOST_YEAR :Custo de mantem STR_ENGINE_PREVIEW_RUNCOST_PERIOD :Custo de mantemento: {CURRENCY_LONG}/período STR_ENGINE_PREVIEW_CAPACITY :Capacidade: {CARGO_LONG} STR_ENGINE_PREVIEW_CAPACITY_2 :Capacidade: {CARGO_LONG}, {CARGO_LONG} +STR_ENGINE_PREVIEW_RAILTYPES :Tipos de ferrocarril: {STRING} # Autoreplace window STR_REPLACE_VEHICLES_WHITE :{WHITE}Substituír {STRING} - {STRING} @@ -5267,9 +5271,11 @@ STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... pont STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}A ponte remataría fóra do mapa STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}A ponte é demasiado baixa para a estación STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}A ponte é demasiado baixa para unha estación de estrada +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}A ponte é moi baixa para o porto STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}A ponte é demasiado baixa para a boia STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}A ponte é demasiado baixa para un punto de ruta de ferrocarril STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}A ponte é demasiado baixa para un punto de ruta de estrada +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}A ponte é moi baixa para a exclusa # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Non se pode construír un túnel aí... diff --git a/src/lang/german.txt b/src/lang/german.txt index ec1cc449665eb..53da600dc2188 100644 --- a/src/lang/german.txt +++ b/src/lang/german.txt @@ -3687,7 +3687,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Text fü STR_TOWN_DIRECTORY_CAPTION :{WHITE}Städte ({COMMA} von {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Keine - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Großstadt){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Städtenamen – Klick auf den Namen zentriert Hauptansicht auf die Stadt. Mit Strg+Klick wird eine neue Zusatzansicht auf die Stadt geöffnet STR_TOWN_POPULATION :{BLACK}Weltbevölkerung: {COMMA} diff --git a/src/lang/greek.txt b/src/lang/greek.txt index 9d6df28701210..2c97b15f418cf 100644 --- a/src/lang/greek.txt +++ b/src/lang/greek.txt @@ -3784,7 +3784,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Δώστ STR_TOWN_DIRECTORY_CAPTION :{WHITE}Πόλεις ({COMMA} από {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Τίποτα - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Πόλη){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Ονόματα πόλεων - πατήστε στο όνομα για κεντράρισμα της κύριας προβολής στην πόλη. Ctrl+Κλικ για άνοιγμα νέου παραθύρου προβολής στην τοποθεσία της πόλης STR_TOWN_POPULATION :{BLACK}Παγκόσμιος πληθυσμός: {COMMA} diff --git a/src/lang/hebrew.txt b/src/lang/hebrew.txt index 662b4e10863b1..2347dcba42201 100644 --- a/src/lang/hebrew.txt +++ b/src/lang/hebrew.txt @@ -3280,7 +3280,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}הכנס # Town directory window STR_TOWN_DIRECTORY_NONE :{ORANGE}- אין - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (City){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}שמות ערים - לחץ על שם כדי למקד את התצוגה על העיר. Ctrl+לחיצה פותח חלונית תצוגה חדשה על מיקום העיר STR_TOWN_POPULATION :{BLACK}אוכלוסיית העולם: {COMMA} diff --git a/src/lang/hungarian.txt b/src/lang/hungarian.txt index b9b9067247f4f..3bb4c6f731d2d 100644 --- a/src/lang/hungarian.txt +++ b/src/lang/hungarian.txt @@ -3754,7 +3754,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Felirat STR_TOWN_DIRECTORY_CAPTION :{WHITE}Városok ({COMMA}, {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Nincs - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Város){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Városnevek - kattints egy névre a város megnézéséhez. Ctrl+kattintással új nézet nyílik a városnál STR_TOWN_POPULATION :{BLACK}Világnépesség: {COMMA} diff --git a/src/lang/indonesian.txt b/src/lang/indonesian.txt index bce95528efa3f..f0f0168d50cea 100644 --- a/src/lang/indonesian.txt +++ b/src/lang/indonesian.txt @@ -3487,7 +3487,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Masukkan # Town directory window STR_TOWN_DIRECTORY_NONE :{ORANGE}- Tidak Ada - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Kota){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Nama-nama kota - Klik pada nama untuk mengarahkan pandangan utama pada kota. Ctrl+Click akan membuka viewport baru pada lokasi kota STR_TOWN_POPULATION :{BLACK}Populasi Dunia: {COMMA} diff --git a/src/lang/irish.txt b/src/lang/irish.txt index 32eae7e2b373a..69038bddc3bd7 100644 --- a/src/lang/irish.txt +++ b/src/lang/irish.txt @@ -3281,7 +3281,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Iontrái # Town directory window STR_TOWN_DIRECTORY_NONE :{ORANGE}- Ceann ar bith - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Cathair){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Ainmneacha bailte - cliceáil ar ainm le go mbeidh an baile i lár an scáileán. Osclaítear amharc nua ar shuíomh an bhaile le Ctrl+Cliceáil STR_TOWN_POPULATION :{BLACK}Daonra domhanda: {COMMA} diff --git a/src/lang/italian.txt b/src/lang/italian.txt index 9e93da9af0053..caca85805185a 100644 --- a/src/lang/italian.txt +++ b/src/lang/italian.txt @@ -3682,7 +3682,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Inserire # Town directory window STR_TOWN_DIRECTORY_NONE :{ORANGE}- Nessuna - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Metropoli){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Nomi delle città - fare clic su un nome per centrare la visuale principale sulla città. Ctrl+Clic per aprire una nuova finestra di visualizzazione sulla posizione della città STR_TOWN_POPULATION :{BLACK}Popolazione mondiale: {COMMA} diff --git a/src/lang/japanese.txt b/src/lang/japanese.txt index b1419a6484b5c..a3dc9d420735e 100644 --- a/src/lang/japanese.txt +++ b/src/lang/japanese.txt @@ -3424,7 +3424,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}標識 STR_TOWN_DIRECTORY_CAPTION :{WHITE}街一覧 ({COMMA} の {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- なし- STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (都市){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}街の名前 - メイン画面を街の場所に移動するには名前をクリックします。Ctrl+クリックで新しいビューポートに表示します STR_TOWN_POPULATION :{BLACK}地域人口: {COMMA}人 diff --git a/src/lang/korean.txt b/src/lang/korean.txt index 4b47e9b0bd1f8..a2edd95224643 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -3692,7 +3692,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}팻말 STR_TOWN_DIRECTORY_CAPTION :{WHITE}도시 목록 ({1:COMMA}개 중 {0:COMMA}개) STR_TOWN_DIRECTORY_NONE :{ORANGE}(없음) STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (대도시){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}도시 이름 - 이 도시로 시점을 변경하려면 클릭하세요. CTRL+클릭하면 이 도시 위치를 기준으로 새로운 외부 화면을 엽니다 STR_TOWN_POPULATION :{BLACK}총 인구 수: {COMMA} diff --git a/src/lang/latin.txt b/src/lang/latin.txt index 1091802ffc644..e9c79abb82ec1 100644 --- a/src/lang/latin.txt +++ b/src/lang/latin.txt @@ -3234,7 +3234,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Inscribe # Town directory window STR_TOWN_DIRECTORY_NONE :{ORANGE}- Nulla - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Urbs){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Nomina oppidorum - preme in nomen ut conspectus supra oppidum locetur. Ctrl+Preme ut novam fenestram conspectus supra oppidum aperiatur STR_TOWN_POPULATION :{BLACK}Incolae mundi: {COMMA} diff --git a/src/lang/latvian.txt b/src/lang/latvian.txt index 62221c230cc1e..2c84ecb6ea22c 100644 --- a/src/lang/latvian.txt +++ b/src/lang/latvian.txt @@ -3696,7 +3696,6 @@ STR_TOWN_DIRECTORY_CAPTION :{WHITE}Pilsēta STR_TOWN_DIRECTORY_NONE :{G=m}{ORANGE}- Neviens - STR_TOWN_DIRECTORY_NONE.kas :{ORANGE}- Neviena - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Pilsēta){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Pilsētu nosaukumi - klikšķināt uz nosaukuma, lai centrētu skatu uz to.Ctrl+klikšķis atvērs skatu uz pilsētu jaunā skatlaukā STR_TOWN_POPULATION :{BLACK}Pasaules iedzīvotāju skaits: {COMMA} diff --git a/src/lang/lithuanian.txt b/src/lang/lithuanian.txt index bd4e4ad2aaad0..70b83009e7efc 100644 --- a/src/lang/lithuanian.txt +++ b/src/lang/lithuanian.txt @@ -3716,7 +3716,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Įrašyk STR_TOWN_DIRECTORY_CAPTION :{WHITE}Miestai ({COMMA} of {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}Nėra STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Miestas){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Spragtelėjus ant pavadinimo, miestas bus parodytas ekrano centre. Spragtelėkite laikant nuspaudus „Ctrl“ klavišą, kad atverti papildomą peržiūros langą į pasirinktą miestą STR_TOWN_POPULATION :{BLACK}Pasaulio populiacija: {COMMA} diff --git a/src/lang/luxembourgish.txt b/src/lang/luxembourgish.txt index 1e3b62ef5a4d4..3b7b5fafa1d14 100644 --- a/src/lang/luxembourgish.txt +++ b/src/lang/luxembourgish.txt @@ -3647,7 +3647,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Gëff en STR_TOWN_DIRECTORY_CAPTION :{WHITE}Stied ({COMMA} vu {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Keng - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Stad){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Stiednimm - klick op den Numm fir d'Usiicht drop ze zentréieren. Ctrl+Klick erstellt eng nei Usiicht vun der Stad STR_TOWN_POPULATION :{BLACK}Weltbevölkerung: {COMMA} diff --git a/src/lang/maori.txt b/src/lang/maori.txt index 6507cfa6a720e..69e81d94e7f47 100644 --- a/src/lang/maori.txt +++ b/src/lang/maori.txt @@ -3688,7 +3688,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Tāurua STR_TOWN_DIRECTORY_CAPTION :{WHITE}Tāone ({COMMA} o te {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Kore - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Tāone nui){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Ingoa o ngā tāone - pāwhiria he ingoa kia neke i te tirohanga matua ki te tāone. Pātaki+Pāwhiri kia huaki i tētahi atu tirohanga i te tauwāhi o te tāone STR_TOWN_POPULATION :{BLACK}Taupori o te ao: {COMMA} diff --git a/src/lang/norwegian_bokmal.txt b/src/lang/norwegian_bokmal.txt index c0e7ebd892cfd..3a7c14dafcc86 100644 --- a/src/lang/norwegian_bokmal.txt +++ b/src/lang/norwegian_bokmal.txt @@ -3692,7 +3692,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Skriv in STR_TOWN_DIRECTORY_CAPTION :{WHITE}Byer ({COMMA} av {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Ingen - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (By){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Bynavn - klikk på navnet for å gå til byen. Ctrl+klikk for å åpne et nytt tilleggsvindu over byen STR_TOWN_POPULATION :{BLACK}Verdensbefolkning: {COMMA} diff --git a/src/lang/persian.txt b/src/lang/persian.txt index 7504651f8e7c4..09b8b4d19800c 100644 --- a/src/lang/persian.txt +++ b/src/lang/persian.txt @@ -3003,7 +3003,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}برای STR_TOWN_DIRECTORY_CAPTION :{WHITE}شهرها ({COMMA} از {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- هیچکدام - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (City){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}نام شهرها - برای مرکز قرار دادن نمای اصلی روی شهر، روی نام کلیک کنید. Ctrl+Click برای باز کردن یک نمای جدید در موقعیت شهر. STR_TOWN_POPULATION :{BLACK}جمعیت جهان: {COMMA} diff --git a/src/lang/polish.txt b/src/lang/polish.txt index ac8b8b1424ba3..9c35d70698459 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -4071,7 +4071,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Wpisz na STR_TOWN_DIRECTORY_CAPTION :{WHITE}Miasta ({COMMA} z {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Żaden - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Metropolia){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Nazwy miast - kliknij na nazwę miasta, aby wyśrodkować na nim widok główny. Użyj Ctrl, aby otworzyć nowy podgląd na lokalizację miasta STR_TOWN_POPULATION :{BLACK}Populacja świata: {COMMA} diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index 61532a91146e2..560ef2bf4fc98 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -3692,7 +3692,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Introduz STR_TOWN_DIRECTORY_CAPTION :{WHITE}Localidades ({COMMA} de {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Nenhuma - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Cidade){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Nomes das localidades - clique no nome para centrar a visualização na cidade. Ctrl+Clique para abrir um novo visualizador na localização da localidade STR_TOWN_POPULATION :{BLACK}População Mundial: {COMMA} diff --git a/src/lang/romanian.txt b/src/lang/romanian.txt index 4094e24a36487..b08d2f80eacbf 100644 --- a/src/lang/romanian.txt +++ b/src/lang/romanian.txt @@ -3631,7 +3631,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Introdu STR_TOWN_DIRECTORY_CAPTION :{WHITE}Orașe ({COMMA} din {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Nimic - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (oraș){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Numele orașelor - clic pe un nume pentru a centra imaginea pe orașul respectiv. Ctrl+Click pentru a deshide o fereastra cu locația orașului STR_TOWN_POPULATION :{BLACK}Populația totală: {COMMA} diff --git a/src/lang/russian.txt b/src/lang/russian.txt index 6631323b3a57b..de883b9d6bc21 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -3866,7 +3866,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Введ STR_TOWN_DIRECTORY_CAPTION :{WHITE}Города ({COMMA} / {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Нет - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Мегаполис){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Список городов. Щелчок по названию показывает город в основном окне. Ctrl+щелчок показывает в дополнительном окне. STR_TOWN_POPULATION :{BLACK}Население: {COMMA} diff --git a/src/lang/serbian.txt b/src/lang/serbian.txt index de1746c3c683c..e0f8b059c577f 100644 --- a/src/lang/serbian.txt +++ b/src/lang/serbian.txt @@ -3676,7 +3676,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Unos naz # Town directory window STR_TOWN_DIRECTORY_NONE :{ORANGE}- Prazno - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (City){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Imena naselja - klikom na naziv glavni pogled se premešta na to naselje. Ctrl+klik otvara novi pogled na lokaciju naselja STR_TOWN_POPULATION :{BLACK}Svetska populacija: {COMMA} diff --git a/src/lang/simplified_chinese.txt b/src/lang/simplified_chinese.txt index 7fdcf877b72a7..89e700d3b58e7 100644 --- a/src/lang/simplified_chinese.txt +++ b/src/lang/simplified_chinese.txt @@ -3690,7 +3690,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}为标 STR_TOWN_DIRECTORY_CAPTION :{WHITE}城镇({COMMA} 座,共 {COMMA}座) STR_TOWN_DIRECTORY_NONE :{ORANGE}- 无 - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK}({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW}(都市){BLACK}({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK} 城镇名称 - 点击名称可以将屏幕中心{}移动到城镇所在的位置。按住 点选将会在新视点中显示城镇位置 STR_TOWN_POPULATION :{BLACK}地图人口总数:{COMMA} diff --git a/src/lang/slovak.txt b/src/lang/slovak.txt index 4701412c183f4..cbb3c6743aaf2 100644 --- a/src/lang/slovak.txt +++ b/src/lang/slovak.txt @@ -3630,7 +3630,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Zadajte # Town directory window STR_TOWN_DIRECTORY_NONE :{ORANGE}- Žiadne - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Veľkomesto){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Názvy miest - kliknite na názov pre pohľad na mesto. Ctrl+Klik otvorí nové okno s pohľadom na mesto STR_TOWN_POPULATION :{BLACK}Svetová populácia: {COMMA} diff --git a/src/lang/slovenian.txt b/src/lang/slovenian.txt index 971b8b97526f9..4f08febbaacf0 100644 --- a/src/lang/slovenian.txt +++ b/src/lang/slovenian.txt @@ -3157,7 +3157,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Vpiši i # Town directory window STR_TOWN_DIRECTORY_NONE :{ORANGE}- Brez - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Mesto){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Imena mest - klikni na ime za pogled na mesto. Ctrl+Klik odpre nov pogled na lokaciji mesta STR_TOWN_POPULATION :{BLACK}Svetovno prebivalstvo: {COMMA} diff --git a/src/lang/spanish.txt b/src/lang/spanish.txt index 70640bd735607..3c578f94a5c09 100644 --- a/src/lang/spanish.txt +++ b/src/lang/spanish.txt @@ -3660,7 +3660,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Introduc STR_TOWN_DIRECTORY_CAPTION :{WHITE}Municipios ({COMMA} of {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Ninguna - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Ciudad){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Nombres de los municipios - Clica sobre un nombre para centrar la vista principal en el municipio. Ctrl+clic abre una ventana de visualización en dicha posición STR_TOWN_POPULATION :{BLACK}Población mundial: {COMMA} diff --git a/src/lang/spanish_MX.txt b/src/lang/spanish_MX.txt index f21104fa5e27a..f005e3ab34cb0 100644 --- a/src/lang/spanish_MX.txt +++ b/src/lang/spanish_MX.txt @@ -3684,7 +3684,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Indicar STR_TOWN_DIRECTORY_CAPTION :{WHITE}Pueblos ({COMMA} de {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Ninguno - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (ciudad){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Nombres de pueblos. Clic en un nombre centra la vista principal en el pueblo. Ctrl+Clic abre una vista aparte en su ubicación STR_TOWN_POPULATION :{BLACK}Población mundial: {COMMA} diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt index 31af4a5536e3b..6544a8248bb1b 100644 --- a/src/lang/swedish.txt +++ b/src/lang/swedish.txt @@ -3691,7 +3691,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Mata in STR_TOWN_DIRECTORY_CAPTION :{WHITE}Städer ({COMMA} av {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Inga - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Stad){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Stadsnamn - klicka på ett namn för att centrera huvudvyn på staden. Ctrl+Klick för att öppna en ny fönstervy över stadens läge STR_TOWN_POPULATION :{BLACK}Global folkmängd: {COMMA} diff --git a/src/lang/tamil.txt b/src/lang/tamil.txt index b9ece84d8eeef..10ccf21cd3f65 100644 --- a/src/lang/tamil.txt +++ b/src/lang/tamil.txt @@ -3243,7 +3243,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}கு STR_TOWN_DIRECTORY_CAPTION :{WHITE}நகரங்கள் ({1:COMMA}இல் {0:COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- ஒன்றுமில்லை - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (மாநகரம்){BLACK} ({COMMA}) STR_TOWN_POPULATION :{BLACK}உலக மக்கள்தொகை: {COMMA} # Town view window diff --git a/src/lang/thai.txt b/src/lang/thai.txt index 9e7b2c7115395..98eec60d46d0b 100644 --- a/src/lang/thai.txt +++ b/src/lang/thai.txt @@ -3085,7 +3085,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}กร # Town directory window STR_TOWN_DIRECTORY_NONE :{ORANGE}- ไม่มี - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (เมือง){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}ชื่อเมือง - คลิ๊กเมาส์ที่ชื่อเมือง STR_TOWN_POPULATION :{BLACK}ประชากรโดยรวมทั้งแผนที่: {COMMA} diff --git a/src/lang/traditional_chinese.txt b/src/lang/traditional_chinese.txt index b9f596ba69e88..56033a4f941a5 100644 --- a/src/lang/traditional_chinese.txt +++ b/src/lang/traditional_chinese.txt @@ -3690,7 +3690,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}輸入 STR_TOWN_DIRECTORY_CAPTION :{WHITE}市鎮({COMMA} 座,總共 {COMMA} 座) STR_TOWN_DIRECTORY_NONE :{ORANGE}- 無 - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (城市){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}市鎮名稱 - 點選名稱可將市鎮置於畫面正中央。按住 點選可於市鎮位置開啟新檢視視窗 STR_TOWN_POPULATION :{BLACK}世界人口:{COMMA} diff --git a/src/lang/turkish.txt b/src/lang/turkish.txt index 1734004986f35..63f61b4003ca3 100644 --- a/src/lang/turkish.txt +++ b/src/lang/turkish.txt @@ -3594,7 +3594,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Tabela i # Town directory window STR_TOWN_DIRECTORY_NONE :{ORANGE}- Hiçbiri - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Şehir){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Şehir isimleri - şehre bakmak için ismine tıkla. Ctrl + Sol Tıklama şehrin olduğu yere ait bir görünüm penceresi açar. STR_TOWN_POPULATION :{BLACK}Dünya nüfusu: {COMMA} diff --git a/src/lang/ukrainian.txt b/src/lang/ukrainian.txt index 5ef10b2455272..c525d5020f367 100644 --- a/src/lang/ukrainian.txt +++ b/src/lang/ukrainian.txt @@ -3799,7 +3799,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Введ STR_TOWN_DIRECTORY_CAPTION :{WHITE}Міста ({COMMA} of {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- немає - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Мегаполіс){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Назви міст - натисніть на назву, щоб показати місто у центрі екрану. Ctrl+клац мишею відкриває нове вікно з видом на місто STR_TOWN_POPULATION :{BLACK}Населення світу: {COMMA} diff --git a/src/lang/vietnamese.txt b/src/lang/vietnamese.txt index 8c211ff30f5fe..45cadcf237516 100644 --- a/src/lang/vietnamese.txt +++ b/src/lang/vietnamese.txt @@ -3690,7 +3690,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Nhập t STR_TOWN_DIRECTORY_CAPTION :{WHITE}Đô Thị ({COMMA} đến {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Không Có - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (đô thị){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Tên các đô thị - nháy vào tên để xem trung tâm đô thị. Ctrl+Click mở cửa sổ mới của đô thị STR_TOWN_POPULATION :{BLACK}Dân số thế giới: {COMMA} diff --git a/src/lang/welsh.txt b/src/lang/welsh.txt index 85133232b28c0..761db4c555bec 100644 --- a/src/lang/welsh.txt +++ b/src/lang/welsh.txt @@ -3676,7 +3676,6 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Rhowch e STR_TOWN_DIRECTORY_CAPTION :{WHITE}Trefi ({COMMA} o {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Dim - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Dinas){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Enwau trefi - cliciwch ar enw tref i ganoli'r brif olygfa ar y dref. Ctrl+Clic i agor ffenest golwg newydd ar leoliad y dref STR_TOWN_POPULATION :{BLACK}Poblogaeth y Byd: {COMMA} From f8aa2e64e42e3cb6c4ac9de35ff8f903641b66c2 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Mon, 29 Sep 2025 19:23:02 +0100 Subject: [PATCH 051/137] Add: Include build cost in rail/road dropdowns. (#14599) --- src/dropdown_common_type.h | 26 ++++++++++++++++++++++++++ src/newgrf_badge_gui.cpp | 12 ++++++------ src/newgrf_badge_gui.h | 4 ++-- src/rail_gui.cpp | 4 ++-- src/road_gui.cpp | 6 +++--- 5 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/dropdown_common_type.h b/src/dropdown_common_type.h index 81e2b36be9dfd..dac1500d46139 100644 --- a/src/dropdown_common_type.h +++ b/src/dropdown_common_type.h @@ -260,6 +260,32 @@ class DropDownIndent : public TBase { } }; +/** + * Drop down spacer component. + * @tparam TBase Base component. + * @tparam TEnd Position space at end if true, or start if false. + */ +template +class DropDownSpacer : public TBase { +public: + template + explicit DropDownSpacer(Args&&... args) : TBase(std::forward(args)...) {} + + uint Width() const override { return WidgetDimensions::scaled.hsep_wide + this->TBase::Width(); } + + int OnClick(const Rect &r, const Point &pt) const override + { + bool rtl = TEnd ^ (_current_text_dir == TD_RTL); + return this->TBase::OnClick(r.Indent(WidgetDimensions::scaled.hsep_wide, rtl), pt); + } + + void Draw(const Rect &full, const Rect &r, bool sel, int click_result, Colours bg_colour) const override + { + bool rtl = TEnd ^ (_current_text_dir == TD_RTL); + this->TBase::Draw(full, r.Indent(WidgetDimensions::scaled.hsep_wide, rtl), sel, click_result, bg_colour); + } +}; + /** * Drop down component that makes the item unselectable. * @tparam TBase Base component. diff --git a/src/newgrf_badge_gui.cpp b/src/newgrf_badge_gui.cpp index 8c10484df4ead..491986c82bfe8 100644 --- a/src/newgrf_badge_gui.cpp +++ b/src/newgrf_badge_gui.cpp @@ -240,17 +240,17 @@ class DropDownBadges : public TBase { Dimension dim{}; }; -using DropDownListBadgeItem = DropDownBadges; -using DropDownListBadgeIconItem = DropDownBadges; +using DropDownListBadgeItem = DropDownBadges, FS_SMALL, true>>; +using DropDownListBadgeIconItem = DropDownBadges, FS_SMALL, true>>; -std::unique_ptr MakeDropDownListBadgeItem(const std::shared_ptr &gui_classes, std::span badges, GrfSpecFeature feature, std::optional introduction_date, std::string &&str, int value, bool masked, bool shaded) +std::unique_ptr MakeDropDownListBadgeItem(const std::shared_ptr &gui_classes, std::span badges, GrfSpecFeature feature, std::optional introduction_date, Money cost, std::string &&str, int value, bool masked, bool shaded) { - return std::make_unique(gui_classes, badges, feature, introduction_date, std::move(str), value, masked, shaded); + return std::make_unique(gui_classes, badges, feature, introduction_date, GetString(STR_JUST_CURRENCY_SHORT, cost), std::move(str), value, masked, shaded); } -std::unique_ptr MakeDropDownListBadgeIconItem(const std::shared_ptr &gui_classes, std::span badges, GrfSpecFeature feature, std::optional introduction_date, const Dimension &dim, SpriteID sprite, PaletteID palette, std::string &&str, int value, bool masked, bool shaded) +std::unique_ptr MakeDropDownListBadgeIconItem(const std::shared_ptr &gui_classes, std::span badges, GrfSpecFeature feature, std::optional introduction_date, Money cost, const Dimension &dim, SpriteID sprite, PaletteID palette, std::string &&str, int value, bool masked, bool shaded) { - return std::make_unique(gui_classes, badges, feature, introduction_date, dim, sprite, palette, std::move(str), value, masked, shaded); + return std::make_unique(gui_classes, badges, feature, introduction_date, GetString(STR_JUST_CURRENCY_SHORT, cost), dim, sprite, palette, std::move(str), value, masked, shaded); } /** diff --git a/src/newgrf_badge_gui.h b/src/newgrf_badge_gui.h index e73186d951d76..b908cf7f5533f 100644 --- a/src/newgrf_badge_gui.h +++ b/src/newgrf_badge_gui.h @@ -50,8 +50,8 @@ class GUIBadgeClasses : public UsedBadgeClasses { int DrawBadgeNameList(Rect r, std::span badges, GrfSpecFeature feature); void DrawBadgeColumn(Rect r, int column_group, const GUIBadgeClasses &gui_classes, std::span badges, GrfSpecFeature feature, std::optional introduction_date, PaletteID remap); -std::unique_ptr MakeDropDownListBadgeItem(const std::shared_ptr &gui_classes, std::span badges, GrfSpecFeature feature, std::optional introduction_date, std::string &&str, int value, bool masked = false, bool shaded = false); -std::unique_ptr MakeDropDownListBadgeIconItem(const std::shared_ptr &gui_classes, std::span badges, GrfSpecFeature feature, std::optional introduction_date, const Dimension &dim, SpriteID sprite, PaletteID palette, std::string &&str, int value, bool masked = false, bool shaded = false); +std::unique_ptr MakeDropDownListBadgeItem(const std::shared_ptr &gui_classes, std::span badges, GrfSpecFeature feature, std::optional introduction_date, Money cost, std::string &&str, int value, bool masked = false, bool shaded = false); +std::unique_ptr MakeDropDownListBadgeIconItem(const std::shared_ptr &gui_classes, std::span badges, GrfSpecFeature feature, std::optional introduction_date, Money cost, const Dimension &dim, SpriteID sprite, PaletteID palette, std::string &&str, int value, bool masked = false, bool shaded = false); DropDownList BuildBadgeClassConfigurationList(const class GUIBadgeClasses &badge_class, uint columns, std::span column_separators); bool HandleBadgeConfigurationDropDownClick(GrfSpecFeature feature, uint columns, int result, int click_result, BadgeFilterChoices &choices); diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 3ff53b06482ab..a0d8688096136 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -2065,12 +2065,12 @@ DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option) const RailTypeInfo *rti = GetRailTypeInfo(rt); if (for_replacement) { - list.push_back(MakeDropDownListBadgeItem(badge_class_list, rti->badges, GSF_RAILTYPES, rti->introduction_date, GetString(rti->strings.replace_text), rt, !avail_railtypes.Test(rt))); + list.push_back(MakeDropDownListBadgeItem(badge_class_list, rti->badges, GSF_RAILTYPES, rti->introduction_date, RailBuildCost(rt), GetString(rti->strings.replace_text), rt, !avail_railtypes.Test(rt))); } else { std::string str = rti->max_speed > 0 ? GetString(STR_TOOLBAR_RAILTYPE_VELOCITY, rti->strings.menu_text, rti->max_speed) : GetString(rti->strings.menu_text); - list.push_back(MakeDropDownListBadgeIconItem(badge_class_list, rti->badges, GSF_RAILTYPES, rti->introduction_date, d, rti->gui_sprites.build_x_rail, PAL_NONE, std::move(str), rt, !avail_railtypes.Test(rt))); + list.push_back(MakeDropDownListBadgeIconItem(badge_class_list, rti->badges, GSF_RAILTYPES, rti->introduction_date, RailBuildCost(rt), d, rti->gui_sprites.build_x_rail, PAL_NONE, std::move(str), rt, !avail_railtypes.Test(rt))); } } diff --git a/src/road_gui.cpp b/src/road_gui.cpp index e3d29dbd3850a..3e37167a7658e 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -1805,12 +1805,12 @@ DropDownList GetRoadTypeDropDownList(RoadTramTypes rtts, bool for_replacement, b const RoadTypeInfo *rti = GetRoadTypeInfo(rt); if (for_replacement) { - list.push_back(MakeDropDownListBadgeItem(badge_class_list, rti->badges, GSF_ROADTYPES, rti->introduction_date, GetString(rti->strings.replace_text), rt, !avail_roadtypes.Test(rt))); + list.push_back(MakeDropDownListBadgeItem(badge_class_list, rti->badges, GSF_ROADTYPES, rti->introduction_date, RoadBuildCost(rt), GetString(rti->strings.replace_text), rt, !avail_roadtypes.Test(rt))); } else { std::string str = rti->max_speed > 0 ? GetString(STR_TOOLBAR_RAILTYPE_VELOCITY, rti->strings.menu_text, rti->max_speed / 2) : GetString(rti->strings.menu_text); - list.push_back(MakeDropDownListBadgeIconItem(badge_class_list, rti->badges, GSF_ROADTYPES, rti->introduction_date, d, rti->gui_sprites.build_x_road, PAL_NONE, std::move(str), rt, !avail_roadtypes.Test(rt))); + list.push_back(MakeDropDownListBadgeIconItem(badge_class_list, rti->badges, GSF_ROADTYPES, rti->introduction_date, RoadBuildCost(rt), d, rti->gui_sprites.build_x_road, PAL_NONE, std::move(str), rt, !avail_roadtypes.Test(rt))); } } @@ -1854,7 +1854,7 @@ DropDownList GetScenRoadTypeDropDownList(RoadTramTypes rtts) std::string str = rti->max_speed > 0 ? GetString(STR_TOOLBAR_RAILTYPE_VELOCITY, rti->strings.menu_text, rti->max_speed / 2) : GetString(rti->strings.menu_text); - list.push_back(MakeDropDownListBadgeIconItem(badge_class_list, rti->badges, GSF_ROADTYPES, rti->introduction_date, d, rti->gui_sprites.build_x_road, PAL_NONE, std::move(str), rt, !avail_roadtypes.Test(rt))); + list.push_back(MakeDropDownListBadgeIconItem(badge_class_list, rti->badges, GSF_ROADTYPES, rti->introduction_date, RoadBuildCost(rt), d, rti->gui_sprites.build_x_road, PAL_NONE, std::move(str), rt, !avail_roadtypes.Test(rt))); } if (list.empty()) { From dcc3a6775203130610ad96d601d32e767b194687 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Mon, 29 Sep 2025 21:02:08 +0100 Subject: [PATCH 052/137] Fix 9cdf740097: Don't make copy of format providers when making a screenshot. (#14681) While here, use projection instead of lambda to select provider. --- src/screenshot.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/screenshot.cpp b/src/screenshot.cpp index 224241ec52a03..c12693c5a4a13 100644 --- a/src/screenshot.cpp +++ b/src/screenshot.cpp @@ -48,10 +48,10 @@ uint _heightmap_highest_peak; ///< When saving a heightmap, this contain */ static ScreenshotProvider *GetScreenshotProvider() { - auto providers = ProviderManager::GetProviders(); + const auto &providers = ProviderManager::GetProviders(); if (providers.empty()) return nullptr; - auto it = std::ranges::find_if(providers, [](const auto &p) { return p->GetName() == _screenshot_format_name; }); + auto it = std::ranges::find(providers, _screenshot_format_name, &ScreenshotProvider::GetName); if (it != std::end(providers)) return *it; return providers.front(); From aa7eb089c6260ab96fcc2d2523f68e6242b14781 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Mon, 29 Sep 2025 21:16:42 +0200 Subject: [PATCH 053/137] Codechange: make all Providers fully const (Font/Screenshot/Sound) --- src/fontcache.h | 4 ++-- src/fontcache/freetypefontcache.cpp | 4 ++-- src/fontcache/spritefontcache.cpp | 4 ++-- src/os/macosx/font_osx.cpp | 4 ++-- src/os/windows/font_win32.cpp | 4 ++-- src/provider_manager.h | 8 ++++---- src/screenshot.cpp | 2 +- src/screenshot_bmp.cpp | 2 +- src/screenshot_pcx.cpp | 2 +- src/screenshot_png.cpp | 2 +- src/screenshot_type.h | 2 +- src/soundloader_opus.cpp | 2 +- src/soundloader_raw.cpp | 2 +- src/soundloader_type.h | 2 +- src/soundloader_wav.cpp | 2 +- 15 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/fontcache.h b/src/fontcache.h index a74e0a57b6b34..b03f84514d25e 100644 --- a/src/fontcache.h +++ b/src/fontcache.h @@ -229,8 +229,8 @@ class FontCacheFactory : public BaseProvider { ProviderManager::Unregister(*this); } - virtual std::unique_ptr LoadFont(FontSize fs, FontType fonttype) = 0; - virtual bool FindFallbackFont(struct FontCacheSettings *settings, const std::string &language_isocode, class MissingGlyphSearcher *callback) = 0; + virtual std::unique_ptr LoadFont(FontSize fs, FontType fonttype) const = 0; + virtual bool FindFallbackFont(struct FontCacheSettings *settings, const std::string &language_isocode, class MissingGlyphSearcher *callback) const = 0; }; class FontProviderManager : ProviderManager { diff --git a/src/fontcache/freetypefontcache.cpp b/src/fontcache/freetypefontcache.cpp index 9d52ab8f77c32..0e3de26877e56 100644 --- a/src/fontcache/freetypefontcache.cpp +++ b/src/fontcache/freetypefontcache.cpp @@ -225,7 +225,7 @@ class FreeTypeFontCacheFactory : public FontCacheFactory { * format is 'font family name' or 'font family name, font style'. * @param fs The font size to load. */ - std::unique_ptr LoadFont(FontSize fs, FontType fonttype) override + std::unique_ptr LoadFont(FontSize fs, FontType fonttype) const override { if (fonttype != FontType::TrueType) return nullptr; @@ -271,7 +271,7 @@ class FreeTypeFontCacheFactory : public FontCacheFactory { return LoadFont(fs, face, font, GetFontCacheFontSize(fs)); } - bool FindFallbackFont(struct FontCacheSettings *settings, const std::string &language_isocode, class MissingGlyphSearcher *callback) override + bool FindFallbackFont(struct FontCacheSettings *settings, const std::string &language_isocode, class MissingGlyphSearcher *callback) const override { #ifdef WITH_FONTCONFIG if (FontConfigFindFallbackFont(settings, language_isocode, callback)) return true; diff --git a/src/fontcache/spritefontcache.cpp b/src/fontcache/spritefontcache.cpp index a1c2f297707a0..0ed1cff34e14d 100644 --- a/src/fontcache/spritefontcache.cpp +++ b/src/fontcache/spritefontcache.cpp @@ -157,14 +157,14 @@ class SpriteFontCacheFactory : public FontCacheFactory { public: SpriteFontCacheFactory() : FontCacheFactory("sprite", "Sprite font provider") {} - std::unique_ptr LoadFont(FontSize fs, FontType fonttype) override + std::unique_ptr LoadFont(FontSize fs, FontType fonttype) const override { if (fonttype != FontType::Sprite) return nullptr; return std::make_unique(fs); } - bool FindFallbackFont(struct FontCacheSettings *, const std::string &, class MissingGlyphSearcher *) override + bool FindFallbackFont(struct FontCacheSettings *, const std::string &, class MissingGlyphSearcher *) const override { return false; } diff --git a/src/os/macosx/font_osx.cpp b/src/os/macosx/font_osx.cpp index 20c24f078afce..e406a790b2082 100644 --- a/src/os/macosx/font_osx.cpp +++ b/src/os/macosx/font_osx.cpp @@ -211,7 +211,7 @@ class CoreTextFontCacheFactory : public FontCacheFactory { * fallback search, use it. Otherwise, try to resolve it by font name. * @param fs The font size to load. */ - std::unique_ptr LoadFont(FontSize fs, FontType fonttype) override + std::unique_ptr LoadFont(FontSize fs, FontType fonttype) const override { if (fonttype != FontType::TrueType) return nullptr; @@ -259,7 +259,7 @@ class CoreTextFontCacheFactory : public FontCacheFactory { return std::make_unique(fs, std::move(font_ref), GetFontCacheFontSize(fs)); } - bool FindFallbackFont(FontCacheSettings *settings, const std::string &language_isocode, MissingGlyphSearcher *callback) override + bool FindFallbackFont(FontCacheSettings *settings, const std::string &language_isocode, MissingGlyphSearcher *callback) const override { /* Determine fallback font using CoreText. This uses the language isocode * to find a suitable font. CoreText is available from 10.5 onwards. */ diff --git a/src/os/windows/font_win32.cpp b/src/os/windows/font_win32.cpp index 7413eb70cbe24..da305072608b8 100644 --- a/src/os/windows/font_win32.cpp +++ b/src/os/windows/font_win32.cpp @@ -276,7 +276,7 @@ class Win32FontCacheFactory : FontCacheFactory { * fallback search, use it. Otherwise, try to resolve it by font name. * @param fs The font size to load. */ - std::unique_ptr LoadFont(FontSize fs, FontType fonttype) override + std::unique_ptr LoadFont(FontSize fs, FontType fonttype) const override { if (fonttype != FontType::TrueType) return nullptr; @@ -308,7 +308,7 @@ class Win32FontCacheFactory : FontCacheFactory { return LoadWin32Font(fs, logfont, GetFontCacheFontSize(fs), font); } - bool FindFallbackFont(FontCacheSettings *settings, const std::string &language_isocode, MissingGlyphSearcher *callback) override + bool FindFallbackFont(FontCacheSettings *settings, const std::string &language_isocode, MissingGlyphSearcher *callback) const override { Debug(fontcache, 1, "Trying fallback fonts"); EFCParam langInfo; diff --git a/src/provider_manager.h b/src/provider_manager.h index 5ab398de34dd4..377a17af28c11 100644 --- a/src/provider_manager.h +++ b/src/provider_manager.h @@ -25,7 +25,7 @@ class ProviderManager { ProviderManager &operator=(ProviderManager const &) = delete; - static void Register(TProviderType &instance) + static void Register(const TProviderType &instance) { /* Insert according to comparator. */ auto &providers = GetProviders(); @@ -33,7 +33,7 @@ class ProviderManager { providers.insert(it, &instance); } - static void Unregister(TProviderType &instance) + static void Unregister(const TProviderType &instance) { auto &providers = GetProviders(); providers.erase(std::find(std::begin(providers), std::end(providers), &instance)); @@ -43,9 +43,9 @@ class ProviderManager { * Get the currently known providers. * @return The known providers. */ - static std::vector &GetProviders() + static std::vector &GetProviders() { - static std::vector providers{}; + static std::vector providers{}; return providers; } }; diff --git a/src/screenshot.cpp b/src/screenshot.cpp index c12693c5a4a13..d06db8b15447a 100644 --- a/src/screenshot.cpp +++ b/src/screenshot.cpp @@ -46,7 +46,7 @@ uint _heightmap_highest_peak; ///< When saving a heightmap, this contain * If the selected provider is not found, then the first provider will be used instead. * @returns ScreenshotProvider, or null if none exist. */ -static ScreenshotProvider *GetScreenshotProvider() +static const ScreenshotProvider *GetScreenshotProvider() { const auto &providers = ProviderManager::GetProviders(); if (providers.empty()) return nullptr; diff --git a/src/screenshot_bmp.cpp b/src/screenshot_bmp.cpp index 6ad3c8dd9807f..260eefc6fa9f2 100644 --- a/src/screenshot_bmp.cpp +++ b/src/screenshot_bmp.cpp @@ -43,7 +43,7 @@ class ScreenshotProvider_Bmp : public ScreenshotProvider { public: ScreenshotProvider_Bmp() : ScreenshotProvider("bmp", "BMP", 10) {} - bool MakeImage(std::string_view name, const ScreenshotCallback &callb, uint w, uint h, int pixelformat, const Colour *palette) override + bool MakeImage(std::string_view name, const ScreenshotCallback &callb, uint w, uint h, int pixelformat, const Colour *palette) const override { uint bpp; // bytes per pixel switch (pixelformat) { diff --git a/src/screenshot_pcx.cpp b/src/screenshot_pcx.cpp index e3c4c70441f29..024609a21222f 100644 --- a/src/screenshot_pcx.cpp +++ b/src/screenshot_pcx.cpp @@ -41,7 +41,7 @@ class ScreenshotProvider_Pcx : public ScreenshotProvider { public: ScreenshotProvider_Pcx() : ScreenshotProvider("pcx", "PCX", 20) {} - bool MakeImage(std::string_view name, const ScreenshotCallback &callb, uint w, uint h, int pixelformat, const Colour *palette) override + bool MakeImage(std::string_view name, const ScreenshotCallback &callb, uint w, uint h, int pixelformat, const Colour *palette) const override { uint maxlines; uint y; diff --git a/src/screenshot_png.cpp b/src/screenshot_png.cpp index c0c868bbe0f52..b636861b649fb 100644 --- a/src/screenshot_png.cpp +++ b/src/screenshot_png.cpp @@ -31,7 +31,7 @@ class ScreenshotProvider_Png : public ScreenshotProvider { public: ScreenshotProvider_Png() : ScreenshotProvider("png", "PNG", 0) {} - bool MakeImage(std::string_view name, const ScreenshotCallback &callb, uint w, uint h, int pixelformat, const Colour *palette) override + bool MakeImage(std::string_view name, const ScreenshotCallback &callb, uint w, uint h, int pixelformat, const Colour *palette) const override { png_color rq[256]; uint i, y, n; diff --git a/src/screenshot_type.h b/src/screenshot_type.h index d93f7c20bb787..4859952899c76 100644 --- a/src/screenshot_type.h +++ b/src/screenshot_type.h @@ -36,7 +36,7 @@ class ScreenshotProvider : public PriorityBaseProvider { ProviderManager::Unregister(*this); } - virtual bool MakeImage(std::string_view name, const ScreenshotCallback &callb, uint w, uint h, int pixelformat, const Colour *palette) = 0; + virtual bool MakeImage(std::string_view name, const ScreenshotCallback &callb, uint w, uint h, int pixelformat, const Colour *palette) const = 0; }; #endif /* SCREENSHOT_TYPE_H */ diff --git a/src/soundloader_opus.cpp b/src/soundloader_opus.cpp index 7bb924e9bcd78..79252641cf94f 100644 --- a/src/soundloader_opus.cpp +++ b/src/soundloader_opus.cpp @@ -34,7 +34,7 @@ class SoundLoader_Opus : public SoundLoader { static constexpr size_t DECODE_BUFFER_SAMPLES = 5760 * 2; static constexpr size_t DECODE_BUFFER_BYTES = DECODE_BUFFER_SAMPLES * sizeof(opus_int16); - bool Load(SoundEntry &sound, bool new_format, std::vector &data) override + bool Load(SoundEntry &sound, bool new_format, std::vector &data) const override { if (!new_format) return false; diff --git a/src/soundloader_raw.cpp b/src/soundloader_raw.cpp index 7caaf52905249..2ac0efc1fbf24 100644 --- a/src/soundloader_raw.cpp +++ b/src/soundloader_raw.cpp @@ -22,7 +22,7 @@ class SoundLoader_Raw : public SoundLoader { static constexpr uint16_t RAW_SAMPLE_RATE = 11025; ///< Sample rate of raw pcm samples. static constexpr uint8_t RAW_SAMPLE_BITS = 8; ///< Bit depths of raw pcm samples. - bool Load(SoundEntry &sound, bool new_format, std::vector &data) override + bool Load(SoundEntry &sound, bool new_format, std::vector &data) const override { /* Raw sounds are apecial case for the jackhammer sound (name in Windows sample.cat is "Corrupt sound") * It's not a RIFF file, but raw PCM data. diff --git a/src/soundloader_type.h b/src/soundloader_type.h index 2f00cc8284399..8c91052fd166e 100644 --- a/src/soundloader_type.h +++ b/src/soundloader_type.h @@ -26,7 +26,7 @@ class SoundLoader : public PriorityBaseProvider { ProviderManager::Unregister(*this); } - virtual bool Load(SoundEntry &sound, bool new_format, std::vector &data) = 0; + virtual bool Load(SoundEntry &sound, bool new_format, std::vector &data) const = 0; }; #endif /* SOUNDLOADER_TYPE_H */ diff --git a/src/soundloader_wav.cpp b/src/soundloader_wav.cpp index 36897aab7345d..72dbf0a056ae2 100644 --- a/src/soundloader_wav.cpp +++ b/src/soundloader_wav.cpp @@ -23,7 +23,7 @@ class SoundLoader_Wav : public SoundLoader { static constexpr uint16_t DEFAULT_SAMPLE_RATE = 11025; - bool Load(SoundEntry &sound, bool new_format, std::vector &data) override + bool Load(SoundEntry &sound, bool new_format, std::vector &data) const override { RandomAccessFile &file = *sound.file; From 8a8ebabb9d106e0f5ad96b19d7830154d810b052 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Mon, 29 Sep 2025 22:08:16 +0100 Subject: [PATCH 054/137] Change: Provide road and rail overlay sprites for bridge decks. (#14557) This allows bridges designed primarily with NewGRF railtypes and roadtypes to be at least somewhat compatible with built-in rail and road. --- media/baseset/openttd.grf | Bin 631667 -> 641653 bytes media/baseset/openttd.grf.hash | 2 +- media/baseset/openttd/CMakeLists.txt | 2 + media/baseset/openttd/bridge_decks.nfo | 36 +++++++++++++++++ media/baseset/openttd/bridge_decks.png | Bin 0 -> 7771 bytes media/baseset/openttd/openttd.nfo | 1 + src/newgrf/newgrf_act5.cpp | 1 + src/rail.h | 1 + src/table/railtypes.h | 8 ++-- src/table/sprites.h | 10 ++++- src/tunnelbridge_cmd.cpp | 54 ++++++++++++++++--------- 11 files changed, 91 insertions(+), 24 deletions(-) create mode 100644 media/baseset/openttd/bridge_decks.nfo create mode 100644 media/baseset/openttd/bridge_decks.png diff --git a/media/baseset/openttd.grf b/media/baseset/openttd.grf index 620cc8ab981eb34ffd83886fd9e17befd31631eb..4464c415f3a7cfa8e124513b97ec6b079eda21fa 100644 GIT binary patch delta 10126 zcmcI~3v^r6mG(X7K6E8r%d#!M9Y6H2osbaoxFSGaCIJ!>5*|qiU{gwXr2q9NHpNhRTI@t|@JgGIV;b`?u`tDP8>2DGlua|5m_j z%Jl!+&RR2COUp;HbfvSuy}$kK@94L0RR6BKCSMS)z3H0PELVwZkwFAO5(MGX)jRXQ zkx!Oxj%H;ZX;(EHci(qU<=yveifk1#&&Z`knb&&n&K)SzJ4_STVC$IkUKKX0d8! zv3h24JuWi0Yz)L!{ClYIO|rG^oy`RA6z?M5CA`acSMct@yZX&{Ham}85zWMc;`=nA zLRczTp9;de_~@#|_~0sGxp0lJLbzVoAZ!vI7WN27g)w1LumwVj$wg!(`7(Kw93;x$XU`NvzfY;KOE7E8L(I}2`&&m$7tM|(?$HzeyM!{{xJHzw;y;b=@G&H88^ z&2LV;0N)+GljM!OOty~PNpj-fPIi#&kzY~0d9;IM#otdRiThLmi6lP23v_9FO8EQq zfX7-mQcd@HPq?GBEjRV=beGR=In|v>hyS5i6ksfTgy?O#vcoB3Job4p43Zhmazze! zWJ8bW#7O0cq)SV>MyjP=x1pyl5hKmbqw{EQ7Tgf8gH4j&n{6aFk;rf(?ahhTC2`}4 zI@~Henz)nXpHqGbfSQ^)l9hQuG#hzr@Av0@%8h0QFA^o&V9Ot3c^imgd2pLgmst^ z8-+WB`!L;h3BAG#!np8L;n$cKg=8+NC%2F$vXdMlFOqT0h<_mh&8KtdLb{4>pm)$s z^d5R2HE4vk2+>TURJI7aYcWyewi+WMsSa7%TaCeSND@XY(jGKe7F_H$Fi6tDfT2qc z@G2NWLJaPvU4EEPRR!{h0dpab&!gRy$pu7*%P@X=cLiTe)Wl*lOuNeYL%beCR4?jX zv)GeF*3wVC*FYUhEjKmJ7-76*JOD3wJ+>v z`xp0fxlk{xMSj|j`xzJB6Erf9tRRgfLbj4e$k%XFkAJ?MtevyH7ZM;U{U#XI?vgHRgJzlf3hVl6sV4 ztN4?ex>fj+uo;!5x32R-v}ad?R>JF+=c)>N&3ksd4v2D`9H)#%jiXPIbBEZ z#9DfgeuZwOkI=8-=VVGMw6nn2o!JU9jv~8Mndp1H$T37wTnf?KJqi-90arwc%(Js1 z2Q|gzQjGIRLZ0Hn&2+h8Bg~TxV&LoYiGwev-5ON#3$V175IwnA?9QUBDp5~W7oST# zy6NXv5uIPfAERAfemztnG4Y*5WG%Eiht*S;%v<>de7~f3=SEUhsd{(@>Z8QR+u`eG zJ=-7}-TAyV_1#n@oWvrlXJ1R!6DMyaMag;^iLiR2LOoU_E}X2DAL2it-6d=(R8B~2 zC&d!}h-E&~zA4p;`DC^tyVjfM#P0G)>YRNwAuON&My$|vvkG>>7JEK#rByV_!o1$P z&Aw1F^e#VtjaTC3MeEzLaWK%Vo0Ybd?hqaALAc3UZNI=5)4kRFQL7GnSX&J|Xl5o;U(c6;ha!TmPg6`q=URn-X)Y) z(`)Em^fB5_hv?tY)AVJUpl4_c)Rnggt<|~_3+jd*_6PR*4P6fh{DDv~)LyAaz(<1M zR)c|HFwj{Z;bk-!;@Pf1FyQyA?%uKpTR{9!MM4ndK1IWf?=Rs+<_cI%1JOXLNRh(f zz)%ri!8Wmti84wkTPYta&?6-upYj3Q4C^1~zB@O>h7GYCLX zju^*tb@oG;9gm6OK!CsI2>X#2k9*D6X($M@;cUEvf1BI|)siP-7|3w8=qGwdv{&@| z1AMDw9M=qU^&YR;NB!YcHE}^TX@WQRloQF`1wpV}Mw1aau42{(Cu%$Tk~Q#i@tCT^ ze!j}OcWkpYH3p%*6WlXw7ST@c zShpC6`gOYpPSf_>i53#Fp2Lmo^#!L3?NhQ5F=7SNvcu4g)*@Yhds{~Lndj^GZ^!qq z!5husi~X;)$k1a20e=`F-s=lxunS}{NZ1T2y&heX z9lQt|-xcOu)rjGZz0czZH@?rOb-)&0}aR!8o~Sv zncEyC5&by68>)G;96(6j9Wg$RF#k|K?utYV{u(rj0l(hYfjJal;Lwk2k;q+sew5p! zWTY3fE0BC!Jnk{z5b@g;wr`}52PRPAAc$VGI^K7%T*U;5AcVTzkow)8T10&_uO_}I z3{pK{KZuvuv*$t*fN_WaPVDr@3P4uFkqjY){d?-{I)0AoL-v&Yv-Hr>3+-Y|Dr|rK zCH5c3Ywd52ze7Uy6|}c3Rc5_Jb^q8)w6h#ur{VBnuhd>?MC_IP6B4v~MXVjG#ZD-} zU@U0pT#HIrS%_^$$}hxf)r1+jvkpgw`)B0NEhu(23y%mfpQyAh(x&+0|b~->`p=tVC>JrPv3&ktNtHo8~8u144CNV?JEyB(k{mIZ4468pL zG@^!q6&(!h3oxhKAH)jwAE+`SIxB=M1+ziztb}X~P6dW0fU?Ksa)f&-xDNs}7%+X* zA@fV=;aTQQd<6-oim-P1CMhsbrkkbwBCI5SjU-bPOv~Y3$v;>cVf&~*m{=eq$WA}p z0nryEW3YHj>V?sbyaz5){m3nYMMlJIfFEi{sR&bc42 zGu+P}fFs0bg-F1x8aZN)$^OAS-QZ)aYNVe8tYSDrb98pZ#1u>(;b|3X8Acm~Kq}^W^(e>#S(LeN2q>xzexDp#S?`$D#3;f|oWM@&}M?z*296ZkvGxAHrtlBUm zzZT$7wGMm0Ug7VBvx18(jG|KRB?+9IrpZUx0~D%K*ZCfPo)e5XUOF=z=thSxLkd{k zSRGroASp$9b0L=ogHRwL(ffHRHs-Rdh%xXPO9b!+m+&$YhN~&I@XK>_J@SkvObO~9 zx7&qK^D2l2p5-Ez*aU|i z4jktYzrKt3T-b>pT*v!qWD5*QqpBXp=KmHx=i-lvVVx%LV;AvnV0g{D;3egxikWY~ z>i}#TenX-<8zgcvocad~C73>BE<-UfAY%O|en7(MA}J6U&V`NaRvIQK zLk>ePA*1bLpuYgy`IX@3JFMEVLX-sddUlB2m!@)9eySqE*V(t*9yuIt3mAMKCR=N@ zp--~Rpnd>xivEXA&H%OQ{|nS#!U?Y!$6D2!u#!U^WliBG-N01L%B>DnSBHYVMF^qc z47v=Ca>5$B$!V{iM$|6NY;c!v0uJ?O2ZS>c0*xtmKzz1S+ zcP^YY8N3fKIEspkQRw^lub`Vm1Kca>Z3TQCTqk9k;3Ug9C-r|u#Si?CP;pT-^5ppn z3&(w-P^P|geP3<{95c%mKHzm}DneSF^16@*0%3xjdh!={X z>L9E_`a0}_o8@32KnW{h*T6k+wcb?hUxBVd$|b^h@IGvh9a>$B&po$kbG>7Vt6crRj?W)Kj63c;dmn0+Ox>U!ZS!^Lx!6lLdE0z~S zk*FLgjlylo)qD<7*(_C2@@1boRLmOSmQ(|;-h%&GO0tLlg(&eBXhA!yg$IXQi2KCK z#K%NQ4P)Xs_cV-MC-7lOl8(4eZMOSH@jsX;hqOIS$q&(}IJ|lC0(!t3Z=m~fM^@7| z-^9i8t^(}FuN7n*&BiYT_x3}l*2ra_$8#ZRKto}Gd<&?UWOZaN_h)a$7Dc}BNGW`3RU|(p4*S~iN9dthecMkxO1mn? z^%IZK16A<|rtL@rS{)NBUx*N0gPYi;MLZfi6&@Ai}x`n?J zl4!cUj|M>rsUz25@@^%2$S@9*(YMGiFyh%bQ7**%{SrED593_<1l>VfXzS;3cV*mJ zmx7*~21>@;*;@@BrzBxcJJhE_ToW-vAsf8(V1Ng?mdcYIO1EEw3t<8C@Y#SvaCenr z)`||*2`gZ}6CDK7Q{i%xC|d$~P#`)Th>nAFm%9{&@a0HKd9YGc6b+Vy&0y!Cc!6cvz|E}otts?tIh*CBLlnf(Vw_*pSf0d3sGTMND2Qc zl#<2g9iA41a6f5BPoVR2*Q#=7fiLD$94^W2+n=joohp(equ_j9-V9U@o`+8<3gkn; zec0nrR3+*_3za}VFNHcx?>g~m&B5p6L~uD(9mz%JLiIV9Kj2m+U#f})*~--2I3k#j zx<)ivmQ=UP>4P<}J9QJgB()XV(Sv_Rem+~0WxgY^fzMB^PtH|vMsy#|gW1XT{8^%o zJPAL54{3i9UrpS7N24}jHtjBh&CtcV69u%rlCMWr`4M&ctZbz%B*~Ht2{ibm@jEhS z9~J*Sp(@=u+ZU_$WknUusqXjtvND=ULP|v@p2Z8W&#Ee9yO5mG`ExlB7qb9zZU91A zs)Ba2(~0cjd^$f_XU<2^ebnVNtN0?(`JC7Ml6fcGm?$M`s#f($uB?C`rD_{d%$4j> zUXfbKS9nyX&#h(Q)s^V;uB-U&% z@h^`YAXyw}w>MG7oJi=B-E%q8X^%Ix%*^8>@GVj6&P~L4zxf@!b{j^T^_r#eMdb=%)ZieHN~IoWC5lRhXp zqEdU%K49HtUu(UGh9O&Pe=ND&Z8eiSMECAm>!s6kGskuie!+5JbN^iv=3YVobiz!I#F}9 z79Aw>oc;UB_(VAxNaL-{PVYeSvVWQG;U8mX-0PppGvA}JAS;v6IFh8dw`I;}|KUF& ziKhNvc76YvE0}>2`!jw5eii~*BcX96F;$@mCz7cKZYPx_83E`lXWs1d7$SEgqKeX6 z7Bv?@o=XxXZ0iW81B!5m=3FAed|0f?4mE?P14{A#Lq(%^!)Ki4VG&e$3INjI{zpuliTy-E>!#1zmUz*aKkO22_F;4$Kun9a*2 zQH=I$N6U{^ND`X8}cBB0c`n}^1+mB2=m+pR$QWQd|^N8>?C;Br}{;y#>+omjmHpLC##l|!Ku_lSim zcUC5Iuv{I8MFBoW8}KR|*L;%f)SOVri$(eHti%PpNQ!DsS;>?t+#<>YW&9C#HD1gK zm-3bHAVd+)!BVr;oGW5!^ZPK7_#nI>lEGqjn%}~rXzDG5`}mu5um~rRB)<~Ji`zlR z7ZidG|B9MIGEcHbKFQDuWc~blA|+nt-(U?Q9rW?VtTAeP;S3D$*E5qOn#5Py3-Org z61R~9n9gaP|40s-k2DGGsK%}G|SDiY%#kGMYnY+Uu>RD-^cq?XGqrgI@W0Z z)5JRaLOQ68Hrn5`@jOOW#=`h@+-Um!$UJMG9DkTNr>d=D>(yy>qBkAA%q}GA)Z*zS zQbH7CCNtG-7m+U#X(tIfK20RZF z{04rDD2`}6%;#HmY%@Ue&1mW^_yd0H;au|;){cj2?eGS1BsYpue?j6p)?ohH%EvVB zE=kK)uXQ)S2fOD}73Pcf^A`RdBfwt)Ke8(oCt2nvE}PD?>z{`Cn!n=GMgQM+YPBfF z{j!KPhSBUOb1Gb8S*VmTHoZk=j+qPjPK;58LkD~?+bo1yLgffU3#HikF9jrqa@eBPxue;O1pFMM+Kt2 zA7S2r)c2In>`L8B+X|qRKZwqoEKRb^?}!3_Mtu+dSE%ni^F{xbQ;;J1WPyY!kEMkW z;5QP{U^uTyzyn3j1Kv!6D-MO@2_V#BaRNS*iMk>ueOR=31~OYl2;2@{h>~V5MdwX} zRrm@uih_le@Vof~;(#jgFJnaShqZ7Sbt~{yw#z~BPylm)SKyWN;Q=wDad+|_wwn&R zAoFq8-BPn5h_UVa^`=<)6A}eg4CZ*QH>CVZ6X2W!N`X*F@=&+?(L*k6}zou>$#lG_7 zqN%ybv8gZ7o{GdRuPvW)qP;d%Ielz;UM?vv?+iu;1{MYehW|#5qFY579Wpq990q=%Xz_H#LPqiF n9~Lu8wAW`c0x=U1GXpUT5VHa?8xXStF~|1$OwLDEAY&K+C*~Wc diff --git a/media/baseset/openttd.grf.hash b/media/baseset/openttd.grf.hash index 5b07da7ff6484..f940ca5d62c7d 100644 --- a/media/baseset/openttd.grf.hash +++ b/media/baseset/openttd.grf.hash @@ -1 +1 @@ -eb8390a0569e66ec417c64ad254f9d05 +b779126d7cd1567eb09a0a7871f70a71 diff --git a/media/baseset/openttd/CMakeLists.txt b/media/baseset/openttd/CMakeLists.txt index f2df774d1b4eb..a7d768326e666 100644 --- a/media/baseset/openttd/CMakeLists.txt +++ b/media/baseset/openttd/CMakeLists.txt @@ -10,6 +10,7 @@ if(GRFCODEC_FOUND) ${CMAKE_CURRENT_SOURCE_DIR}/airport_preview.nfo ${CMAKE_CURRENT_SOURCE_DIR}/aqueduct.nfo ${CMAKE_CURRENT_SOURCE_DIR}/autorail.nfo + ${CMAKE_CURRENT_SOURCE_DIR}/bridge_decks.nfo ${CMAKE_CURRENT_SOURCE_DIR}/canals.nfo ${CMAKE_CURRENT_SOURCE_DIR}/chars.nfo ${CMAKE_CURRENT_SOURCE_DIR}/elrails.nfo @@ -31,6 +32,7 @@ if(GRFCODEC_FOUND) ${CMAKE_CURRENT_SOURCE_DIR}/airport_preview.png ${CMAKE_CURRENT_SOURCE_DIR}/aqueduct.png ${CMAKE_CURRENT_SOURCE_DIR}/autorail.png + ${CMAKE_CURRENT_SOURCE_DIR}/bridge_decks.png ${CMAKE_CURRENT_SOURCE_DIR}/canals.png ${CMAKE_CURRENT_SOURCE_DIR}/canal_locks.png ${CMAKE_CURRENT_SOURCE_DIR}/chars.png diff --git a/media/baseset/openttd/bridge_decks.nfo b/media/baseset/openttd/bridge_decks.nfo new file mode 100644 index 0000000000000..beced3f59fee1 --- /dev/null +++ b/media/baseset/openttd/bridge_decks.nfo @@ -0,0 +1,36 @@ +// This file is part of OpenTTD. +// OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. +// OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . +// + -1 * 0 0C "Bridge decks" + -1 * 3 05 1B 18 + + -1 sprites/bridge_decks.png 8bpp 96 16 64 31 -31 0 normal + -1 sprites/bridge_decks.png 8bpp 16 16 64 31 -31 0 normal + -1 sprites/bridge_decks.png 8bpp 176 16 64 39 -31 -8 normal + -1 sprites/bridge_decks.png 8bpp 256 16 64 23 -31 0 normal + -1 sprites/bridge_decks.png 8bpp 336 16 64 23 -31 0 normal + -1 sprites/bridge_decks.png 8bpp 416 16 64 39 -31 -8 normal + + -1 sprites/bridge_decks.png 8bpp 96 71 64 31 -31 0 normal + -1 sprites/bridge_decks.png 8bpp 16 71 64 31 -31 0 normal + -1 sprites/bridge_decks.png 8bpp 176 71 64 39 -31 -8 normal + -1 sprites/bridge_decks.png 8bpp 256 71 64 23 -31 0 normal + -1 sprites/bridge_decks.png 8bpp 336 71 64 23 -31 0 normal + -1 sprites/bridge_decks.png 8bpp 416 71 64 39 -31 -8 normal + + -1 sprites/bridge_decks.png 8bpp 96 126 64 31 -31 0 normal + -1 sprites/bridge_decks.png 8bpp 16 126 64 31 -31 0 normal + -1 sprites/bridge_decks.png 8bpp 176 126 64 39 -31 -8 normal + -1 sprites/bridge_decks.png 8bpp 256 126 64 23 -31 0 normal + -1 sprites/bridge_decks.png 8bpp 336 126 64 23 -31 0 normal + -1 sprites/bridge_decks.png 8bpp 416 126 64 39 -31 -8 normal + +// X and Y axis are swapped for road surface. + -1 sprites/bridge_decks.png 8bpp 16 181 64 31 -31 0 normal + -1 sprites/bridge_decks.png 8bpp 96 181 64 31 -31 0 normal + -1 sprites/bridge_decks.png 8bpp 176 181 64 39 -31 -8 normal + -1 sprites/bridge_decks.png 8bpp 256 181 64 23 -31 0 normal + -1 sprites/bridge_decks.png 8bpp 336 181 64 23 -31 0 normal + -1 sprites/bridge_decks.png 8bpp 416 181 64 39 -31 -8 normal diff --git a/media/baseset/openttd/bridge_decks.png b/media/baseset/openttd/bridge_decks.png new file mode 100644 index 0000000000000000000000000000000000000000..a602e0ed73a5e7eaec0de77fd56928e5c7bf4f18 GIT binary patch literal 7771 zcma)>c{tSH`~P2dvM+@&RLUAE*=3Y9LcNh1`@S0tgBgtSjYb)R$JkLUf?#7LL*($z}<0I=%oX*~k~ zs;vu~#7J{7VmN7006+tn7@BGWz&Qs8hlq%XoSYmO3^p+_addQq!C;Y*ktr!DB_$* zDUMZDk$rt7deXEOYCNtc(nwdmj7ZC-f}l}M%HC`h7@)PF<$!XCM2pB5C>df*J^Ngd zvyq9UoKF-?J7ox<5Y#9Xl%Y6atHubk5R8T? zGw4%vMte!qY>x;Zpd<+BiPKuhv$%r!kfzeHp5OwMg`qfytvnx0OFY_C>60zE32M@Z zvK>u<;!98@Op1vht)n1$8x-7j=X0T7};Z(h_}S= zQF=&+b+e>M%%nv|`5v&h59}WR2V{VJ2pk>(N5{bN32;IID5t>b8E|$EoE!2ndP?&p z>d9Amnhw7YyEr1n6ri{Q6eK`N0Vw4Fr4s;OcryUV$pK(6U}6HCp93OVP*FXYxM7gA z2~y4!rRSLF7+Es8N3lhH(z1;`KR?GlHz))yUWdJbt`-nYC!}{VVS?(t@CN|4j{oUY z-99Cb7mExq{U_QCs|*4>cQ4J|epw6vR~PiPG);r1*K=pyXE%*^-{$yZ3zsZiEq(l# zYbKaxTdn0_>@#6@FYNrdEr5eBA54uYi%VBY*1x&_?~w6%K;mfCk%pV>n8ICJYRfDj z{Z@Ms6V&a$nJ5FqQ+#&j6H=%z;%))8CA}#Mi@F5m9|}Go2_p6#BBY$o8E6Vd-ygJF z-W|(}Pp#j-vDsK{esk3np${Z7wI|C*NtJX{M=^^AXGuF(dc)Fgg}iH3y5r`~hz{*M zy-ULM)Vh&9-d{Jsyk($yUOya*2^QRXyKHST1hwuW>!A5r$qgGCCG(Ha^8x@VrA9T6R*K9;SonuPmO zI4p?iq%T{Fod7y*`A8bCd=%44`X0w88n1ZeW~q$`yZ`D?x<~5FGHS*nz{aT51Ye=r z$QNs|Iz9tpR%JZaJJ+$B;8hW-VGzF~7%UbbRq}eHM3qmed6zGF*SHv_ zIyJ{ikS^yyG^VPX665wOot-*ZAEH5GA3KY0R~(pntEPqz@)`fk}H>~1+Cx!22Wl|uaFJF)V8(t@h*v$0OFBV;{&(`g$JvVoh>O`1%C$L zojNR;K>$~+Ez5|X-BR0L+}}!u_+0fPW^V7heiv#h^qXgk`ZD7WT%94X_{;mPI46=r z*h~{4gA$N#X|{9+5Dmp}nGgGV?HQxO+1h~sN

qSFQ`q2GXp3s={SyoOm*Id{;Lo zM3Q|S8jWtHFMwEj$f@cUDPB8hqbTo0On;XU5FM3i8DpoOD@FFQ>_2au|3TkHDoM|c zy6vfUXG;MxK^j+vg!4e(ubHMVh1*}u#D{fA^RV*Yb5P1wSTYR_JtACVs@v$ z@-+D&90qb-I;M`?BmQZ~tM^t{;Js>-`r~M6TCCaM1dYRpZuJ*CIZZT$3T0lm@?n{; zQmx$Fh-;l!3(7y5C6~-2B zh%Tz3-+RJeAxuyhF=Y7V@k@IA7|QqoaIKxL3E;(3TcVhuR5I(#Mk4&wR5DLc2Hf~z z+9vt`X0{i#if^r)QUzC&OT@rE|M|Vfs4CZQsCuS{t-a6ns0zyA;qDMc1Kg(Wz8$gm;Y65l`1u3S=V?_?_3QBmjE84X z@l}l`9fx#!wp(R8Kpi_Y?(}*)6FeC3U*6$pyE*OOW1dBr_p1D>#6 zrMq-F$k=myE({lGd=5P6=zT!FHqRo!(>B=9VuJW7Gb2ps(3_QEom~_Cc@4b(owpRJ z%sXL1(joh*$!*}qursgJb?8zK_UM{ou2(!HnI-k^*tguS;Sys#`w_gm{Zt~P+{J;$ z<~NlQr#%f!C-t(5pO*HH&SZ;M-oNV5aGRo^-s#&&66y6&>@o*7Yntsb4pUl5>N&6;4{d^INjHWMxUpEV`us^U5=>vtaBfr9?l;sUJ)ZGeOQ1R!}ve6sl z%2|J%FeU%RxBiP3+JJ0MERU2g|xq zIDW9Q`qI_Nq@}>9M*>lKs}0|3uQ;%}G-&f}Epfsqm;CmMkH{DF>}{It40HsoR0|8# zbXnI6`}KNDITm}Kb4@r}^S<|0%P|~d*@w5gzGZD>DpT$&*XOX~d~ju-<*%COY;6qh zGrnYD6cS27<3oUIlXu(X{e@+;0{li}SV79Aors?b##MQ<|A5QC68%b8&deqjUpQL{ zTjD}NEs#05_0-C5jq>oJsghdHIQR09tnQ}A>?Ujey(XANn~^zk=rY`uYK7<5y}zt5 z&sH92U>9p!&S%L=qF>*i?g)q@SlM}Mp=&bE$CNVRWXs5BG6Q{TP^RV8pcCIz*KZ2O zZraGg^9ugfyY>#gZF)FI_G{#45Rr3gw_ESt>4;E7W6Wy^5Z_mO4vKrb8uhthz=xv| znXmOb4NXrXrn0S;%u;MNJ7aFlU7v5JuE4x_KdAJ_QR4kSR`IK;kK)}v_(Uz#cE_Mk z~mr`|^|(!92x2xRRU)mPHE1|u3eA&#vuthb`UPG%I}HHXSCwP>{_87~J# z!>fcjU7VpXKwznOk?Q1A7TKVj)#9ALA$SzJ-n@3jzz;@*MgN6nRt!Fe)prlR&NQ#v#$i;81m|?1*`*;B=ng7WP(pTzQ zEx9j}ga03-F~biY(d^j!>`*cCn^4KnNVYqHpR-Y9_fM;Z&c2=D`XdqtvE$POp8T}av*?r1aKwz4e=fg6jl{u@8qJ@15S^OA0`rE(jV1RZ zDw9Z6gZe^)+cbhuntF+Yt$Px8Cji=#1by|AaB-4Xo)Z9BtZiD58U=;jdOdLTPK_fd z>+*~0C-PqelZa1K8K{p7+9r_@Ls_M;kuu#Zh*%hsDxfMGp#Km1p(6&UPzw@3NB?^ZjfPTTi><&Uax%s`gs) zl8*x;{LN#HpF5ja;5_Udu7nhuD6k9P$?K|tCFRohPW^9@bZCR^j`q$)wB zRcNgHxSKQkkwW5{xC`4+i_9Fw+M$T!?jk)i|3I#f0d?iKbGglyZ%=WZ*$&DS1wm{p z)l(9^zf9l=9WXTC0^eOks0%gO1sA`_`=FKlfv^jzOBYp{xpIVfT-dIkOHe&$dp5y4 z6h)%)?D%oZ>4t-tr(gfkNg&xAWoC@H^d?VGi!IkN$t4C2D++T&&2q5JTWl~9bVzT` zS?~j4;`ebyypU8Vq01)N9ca8n$T#9*na&+`8?G9Lthu$}jwca_nd>}Ufn}c5xJ!t} zpW!Tg8gxCiNCR{641xUyh`ifKRuXrtOj_}yfM#Bi=kQ`H(r5jjP4#(6b(gye?#t!g z5O)aFp(C>wG(OY)mbZ^lD_~ffyEDOO?oa&2yz{rBs?s)rZ0s~&!y-12Rs&SjRL|b7 zlfIEUAG6FIp-6ThCzQGI&|(xcVJKY=A${)72AGLJK;p+cOr%;LGl}dhhvtb5#nj=(=D;MH^dD{wJKlYf_vBGk&H?tHY21*>9GmY1U^=1gZ<823~2M4UlVMf%Y53pC}L0)EgSpwCRD4VG8*=XD? zArm-I;H5bgtkcHJ-2mA@jyuQZjc6=}@(UwK;}X6%mhioSJ~5k7$-T)~G(|FPz8+rf zJoj^BsSSO~P*?EFp^5|R`~Bx^8rl7zLvxAnJ3^VqjbHf?H{7nj{FxW~kN+2Js0#8+ z%aiFC+~01zeZ}+hz*dsr%2VHT@=G=_uq|{On^&{%6GQVYdb#+1;3j&{z8@(b$iM>N z)hlx6u>;TPDQb`vr^f6UIsXKu`fAMcbcV5_Q#3*@@Pr*4Apo(IV0T>cpb2YeFxt;- zYi7K6ZaAYY%|17{AB&r#!Po4LOdpL$Mn=nq$0MT;AwFKGMh$J9*Sf5w^G(x3etH`t zv=_z){3&$G=i@BdR-6|MfuBb*YBp7Pd2D>XK|}3LT8@@f4tmC8JIrK8YtpD zO}@?1L0`L@O1B0V<5iYxU?oR$W@T<$zx{YUXW!u;rNm5Ab5Tk(B?PRiZ z#h^hkIDTce@q57GE-N@}*AeSM1sAhJT5q<#p%RaUr#4P2Ubk&{;I`{{n`XLB78JFtL z`3Mfy^QvD764aJ_2f7b9s#!z93?W1p_6Neck5_ePeYm=xmM^|wKOPxsCHS@%A~>&w z_W-Ux;vA|bX`fw+c+$XogUiuq=m~oC^e?>~_d0Fv^AX?rvh2DK!H*8J0>9BeVEXv47Kmy# z@sw7D=>{P}jfG?3)(F#sisdd2TAGBHQB<{iZ{F!_D*kkS)<64{sC5d0<)2Y`I1 zna`_N5O2r{ioyw{v%(x@0$Dl|pZTq$Ky!Ci?wdzLu5F5nx&FGja}7b@+?pzoClf04 z_IjBaa6j{yOW7x}(f5P5*%}HJ^OyMB(4rrUQ)yeBV<_x~X}9~k`I2NAa_D0)?1k;R z1j6=SKktx)*+|gkEOTY+_3ODz)N{WCf;V?){{?S!bb|_u%DDNjpnX*)2EHk;6`y=_ zk$rnT(8_g0Dfy5-)qHyBS(t3h9qUt?uDy`{*e=PNYKv27MQH4F1_UqAPI#(+7`_&& zmeF>UcKO|@_Ya?_AKS~5DMJ{QYwWC?j%GwbTBBd(pCv-RAU3By4*fteBK@wxR^~3p zoXYo-N!x-EPf4?fnROC@93D9-wzv+^YQkI(Jy*Blbna z+IX>{fVSn1$mS;@^VjUo3QMouM#TV)K}JE*=T;?8@kzU^looG>No^Q>h1QCk{^X6? zr)!fNPyewR^)_37#`3jVXLDlAZ~94|psRvSDg7MIC>XYlEL0x_cH7n+%E=_!N z*&tTJ2fsA%_A)v1iJiuRFomSe35gD#vn9i%V8t+W=={mDv9gn@+lbVQ3{ym7b$)9y zFw&4x@Zuh6{PlYUQrsQy&&7gR|G=9n?|iyU56D2xJ6%^^cfZaI&DLx)BB{C(?Zua@|DITS&%JUbFavJHX*XHHkmlqC z`Z&XL&&wfLa6W$d#(`zZ&0x6ihyF1o6Qjq}*Mhs+3fd&pC*sMOs_Ygoy;6(v9LY)PCudaMaB+%S0n0N$j(lt472H}yUb-*PG3%i(HQ!g9%9U-tjE%Co)$JYn z4rj{1-}`P$r8+N#R>vxZFzgTdmuT3bAr`HaqgzM$k#ehbD9^wJGZJV%Kd-`nndKzl z5qsH+V{Yru3(e5Z?J`2I`t?YoOq$sGv(e06278Wwd<#oraBqEOWHy$+MCcdzZKxIQ zsRc}#!ESCc1+=~fd4!$>&s$4*$$Y%!GziHGjCkY!J?H)YX!E|(OGYK@o2xa7O(wip z38&T)?56Xn7n{&WSsyRa&)Bi|zp}-m$C|BSf~9|9tm)k!UijQ1X(s$#_vV*uMFwVc zlk9STl_}x*@4PU!Dv9=SA#ykBy4htVB{Tfh(*aRQ$B^8DhB`dT$|JLpMzEhl)$KX3gAfGwYW9sbX^nxWvoH zdc|W!Uq6T`-E&5ccH}~p$Gz5rzGZIdM>Ov9uNT<{rv>&5;*P1iQ>mv&x89d?}a$hr0*zV2@dEc<2{X5v78 zd7z>(TVi!Gvwh{OfrRQH&aTB(T-8QmD^69x<({ /* 0x18 */ { A5BLOCK_ALLOW_OFFSET, SPR_PALETTE_BASE, 1, PALETTE_SPRITE_COUNT, "Palette" }, /* 0x19 */ { A5BLOCK_ALLOW_OFFSET, SPR_ROAD_WAYPOINTS_BASE, 1, ROAD_WAYPOINTS_SPRITE_COUNT, "Road waypoints" }, /* 0x1A */ { A5BLOCK_ALLOW_OFFSET, SPR_OVERLAY_ROCKS_BASE, 1, OVERLAY_ROCKS_SPRITE_COUNT, "Overlay rocks" }, + /* 0x1B */ { A5BLOCK_ALLOW_OFFSET, SPR_BRIDGE_DECKS_BASE, 1, BRIDGE_DECKS_SPRITE_COUNT, "Bridge decks" }, }); /** diff --git a/src/rail.h b/src/rail.h index 631a7989d09d8..b65f2351c86d5 100644 --- a/src/rail.h +++ b/src/rail.h @@ -131,6 +131,7 @@ class RailTypeInfo { SpriteID single_sloped;///< single piece of rail for slopes SpriteID crossing; ///< level crossing, rail in X direction SpriteID tunnel; ///< tunnel sprites base + SpriteID bridge_deck; ///< bridge deck sprites base } base_sprites; /** diff --git a/src/table/railtypes.h b/src/table/railtypes.h index 0b0112322ebc1..2788212a96be6 100644 --- a/src/table/railtypes.h +++ b/src/table/railtypes.h @@ -25,7 +25,7 @@ static const RailTypeInfo _original_railtypes[] = { SPR_RAIL_SINGLE_NORTH, SPR_RAIL_SINGLE_SOUTH, SPR_RAIL_SINGLE_EAST, SPR_RAIL_SINGLE_WEST, SPR_TRACKS_FOR_SLOPES_RAIL_BASE, SPR_CROSSING_OFF_X_RAIL, - SPR_TUNNEL_ENTRY_REAR_RAIL + SPR_TUNNEL_ENTRY_REAR_RAIL, SPR_BRIDGE_DECKS_RAIL, }, /* GUI sprites */ @@ -123,7 +123,7 @@ static const RailTypeInfo _original_railtypes[] = { SPR_RAIL_SINGLE_NORTH, SPR_RAIL_SINGLE_SOUTH, SPR_RAIL_SINGLE_EAST, SPR_RAIL_SINGLE_WEST, SPR_TRACKS_FOR_SLOPES_RAIL_BASE, SPR_CROSSING_OFF_X_RAIL, - SPR_TUNNEL_ENTRY_REAR_RAIL + SPR_TUNNEL_ENTRY_REAR_RAIL, SPR_BRIDGE_DECKS_RAIL, }, /* GUI sprites */ @@ -225,7 +225,7 @@ static const RailTypeInfo _original_railtypes[] = { SPR_MONO_SINGLE_NORTH, SPR_MONO_SINGLE_SOUTH, SPR_MONO_SINGLE_EAST, SPR_MONO_SINGLE_WEST, SPR_TRACKS_FOR_SLOPES_MONO_BASE, SPR_CROSSING_OFF_X_MONO, - SPR_TUNNEL_ENTRY_REAR_MONO + SPR_TUNNEL_ENTRY_REAR_MONO, SPR_BRIDGE_DECKS_MONO, }, /* GUI sprites */ @@ -323,7 +323,7 @@ static const RailTypeInfo _original_railtypes[] = { SPR_MGLV_SINGLE_NORTH, SPR_MGLV_SINGLE_SOUTH, SPR_MGLV_SINGLE_EAST, SPR_MGLV_SINGLE_WEST, SPR_TRACKS_FOR_SLOPES_MAGLEV_BASE, SPR_CROSSING_OFF_X_MAGLEV, - SPR_TUNNEL_ENTRY_REAR_MAGLEV + SPR_TUNNEL_ENTRY_REAR_MAGLEV, SPR_BRIDGE_DECKS_MGLV, }, /* GUI sprites */ diff --git a/src/table/sprites.h b/src/table/sprites.h index 573bead42fdef..caef133af7e97 100644 --- a/src/table/sprites.h +++ b/src/table/sprites.h @@ -321,8 +321,16 @@ static const uint16_t ROAD_WAYPOINTS_SPRITE_COUNT = 4; static constexpr SpriteID SPR_OVERLAY_ROCKS_BASE = SPR_ROAD_WAYPOINTS_BASE + ROAD_WAYPOINTS_SPRITE_COUNT; static constexpr uint16_t OVERLAY_ROCKS_SPRITE_COUNT = 19 * 5; /* Rock overlays: plain, snow 1, snow 2, snow 3 and full snow. */ +/** Bridge deck sprites. */ +static constexpr SpriteID SPR_BRIDGE_DECKS_BASE = SPR_OVERLAY_ROCKS_BASE + OVERLAY_ROCKS_SPRITE_COUNT; +static constexpr uint16_t BRIDGE_DECKS_SPRITE_COUNT = 6 * 4; /* Bridge deck sprites: 6 directions * (3 track types + 1 road type). */ +static const SpriteID SPR_BRIDGE_DECKS_RAIL = SPR_BRIDGE_DECKS_BASE + 0; +static const SpriteID SPR_BRIDGE_DECKS_MONO = SPR_BRIDGE_DECKS_BASE + 6; +static const SpriteID SPR_BRIDGE_DECKS_MGLV = SPR_BRIDGE_DECKS_BASE + 12; +static const SpriteID SPR_BRIDGE_DECKS_ROAD = SPR_BRIDGE_DECKS_BASE + 18; + /* From where can we start putting NewGRFs? */ -static const SpriteID SPR_NEWGRFS_BASE = SPR_OVERLAY_ROCKS_BASE + OVERLAY_ROCKS_SPRITE_COUNT; +static const SpriteID SPR_NEWGRFS_BASE = SPR_BRIDGE_DECKS_BASE + BRIDGE_DECKS_SPRITE_COUNT; /* Manager face sprites */ static const SpriteID SPR_GRADIENT = 874; // background gradient behind manager face diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 6180c1ffb596e..7ffe3332497af 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -135,6 +135,19 @@ bool HasBridgeFlatRamp(Slope tileh, Axis axis) return (tileh != SLOPE_FLAT); } +/** + * Test if bridge piece uses a custom sprite table. + * @param bridge_type Bridge type. + * @param piece Bridge piece. + * @return True iff a custom sprite table is used for the bridge piece. + */ +static bool BridgeHasCustomSpriteTable(BridgeType bridge_type, BridgePieces piece) +{ + assert(piece < NUM_BRIDGE_PIECES); + const BridgeSpec *bridge = GetBridgeSpec(bridge_type); + return piece < bridge->sprite_table.size() && !bridge->sprite_table[piece].empty(); +} + /** * Get the sprite table for a rail/road bridge piece. * @param bridge_type Bridge type. @@ -1158,8 +1171,9 @@ static void GetBridgeRoadCatenary(const RoadTypeInfo *rti, TileIndex head_tile, * @param z the z of the bridge * @param offset sprite offset identifying flat to sloped bridge tiles * @param head are we drawing bridge head? + * @param is_custom_layout Set if the bridge uses a custom sprite layout. */ -static void DrawBridgeRoadBits(TileIndex head_tile, int x, int y, int z, int offset, bool head) +static void DrawBridgeRoadBits(TileIndex head_tile, int x, int y, int z, int offset, bool head, bool is_custom_layout) { RoadType road_rt = GetRoadTypeRoad(head_tile); RoadType tram_rt = GetRoadTypeTram(head_tile); @@ -1178,6 +1192,9 @@ static void DrawBridgeRoadBits(TileIndex head_tile, int x, int y, int z, int off if (road_rti != nullptr) { if (road_rti->UsesOverlay()) { seq_back[0] = GetCustomRoadSprite(road_rti, head_tile, ROTSG_BRIDGE, head ? TCX_NORMAL : TCX_ON_BRIDGE) + offset; + } else if (is_custom_layout) { + /* For custom layouts draw a custom bridge deck. */ + seq_back[0] = SPR_BRIDGE_DECKS_ROAD + offset; } } else if (tram_rti != nullptr) { if (tram_rti->UsesOverlay()) { @@ -1428,13 +1445,16 @@ static void DrawTile_TunnelBridge(TileInfo *ti) DrawBridgeMiddle(ti, BridgePillarFlag::EdgeNE + tunnelbridge_direction); } else { // IsBridge(ti->tile) DrawFoundation(ti, GetBridgeFoundation(ti->tileh, DiagDirToAxis(tunnelbridge_direction))); + bool is_custom_layout; // Set if rail/road bridge uses a custom layout. uint base_offset = GetBridgeRampDirectionBaseOffset(tunnelbridge_direction); std::span psid; if (transport_type != TRANSPORT_WATER) { + BridgeType bridge_type = GetBridgeType(ti->tile); if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head base_offset += GetBridgeSpriteTableBaseOffset(transport_type, ti->tile); - psid = GetBridgeSpriteTable(GetBridgeType(ti->tile), BRIDGE_PIECE_HEAD); + psid = GetBridgeSpriteTable(bridge_type, BRIDGE_PIECE_HEAD); + is_custom_layout = BridgeHasCustomSpriteTable(bridge_type, BRIDGE_PIECE_HEAD); } else { psid = _aqueduct_sprite_table_heads; } @@ -1473,23 +1493,18 @@ static void DrawTile_TunnelBridge(TileInfo *ti) } /* DrawBridgeRoadBits() calls EndSpriteCombine() and StartSpriteCombine() */ - DrawBridgeRoadBits(ti->tile, ti->x, ti->y, z, offset, true); + DrawBridgeRoadBits(ti->tile, ti->x, ti->y, z, offset, true, is_custom_layout); EndSpriteCombine(); } else if (transport_type == TRANSPORT_RAIL) { const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); - if (rti->UsesOverlay()) { - SpriteID surface = GetCustomRailSprite(rti, ti->tile, RTSG_BRIDGE); - if (surface != 0) { - if (HasBridgeFlatRamp(ti->tileh, DiagDirToAxis(tunnelbridge_direction))) { - AddSortableSpriteToDraw(surface + ((DiagDirToAxis(tunnelbridge_direction) == AXIS_X) ? RTBO_X : RTBO_Y), PAL_NONE, *ti, {{0, 0, TILE_HEIGHT}, {TILE_SIZE, TILE_SIZE, 0}, {}}); - } else { - AddSortableSpriteToDraw(surface + RTBO_SLOPE + tunnelbridge_direction, PAL_NONE, *ti, {{}, {TILE_SIZE, TILE_SIZE, TILE_HEIGHT}, {}}); - } + SpriteID surface = rti->UsesOverlay() ? GetCustomRailSprite(rti, ti->tile, RTSG_BRIDGE) : rti->base_sprites.bridge_deck; + if (surface != 0) { + if (HasBridgeFlatRamp(ti->tileh, DiagDirToAxis(tunnelbridge_direction))) { + AddSortableSpriteToDraw(surface + ((DiagDirToAxis(tunnelbridge_direction) == AXIS_X) ? RTBO_X : RTBO_Y), PAL_NONE, *ti, {{0, 0, TILE_HEIGHT}, {TILE_SIZE, TILE_SIZE, 0}, {}}); + } else { + AddSortableSpriteToDraw(surface + RTBO_SLOPE + tunnelbridge_direction, PAL_NONE, *ti, {{}, {TILE_SIZE, TILE_SIZE, TILE_HEIGHT}, {}}); } - /* Don't fallback to non-overlay sprite -- the spec states that - * if an overlay is present then the bridge surface must be - * present. */ } /* PBS debugging, draw reserved tracks darker */ @@ -1614,16 +1629,19 @@ void DrawBridgeMiddle(const TileInfo *ti, BridgePillarFlags blocked_pillars) TransportType transport_type = GetTunnelBridgeTransportType(rampsouth); Axis axis = GetBridgeAxis(ti->tile); BridgePillarFlags pillars; + bool is_custom_layout; // Set if rail/road bridge uses a custom layout. uint base_offset = GetBridgeMiddleAxisBaseOffset(axis); std::span psid; bool drawfarpillar; if (transport_type != TRANSPORT_WATER) { BridgeType bridge_type = GetBridgeType(rampsouth); + BridgePieces bridge_piece = CalcBridgePiece(GetTunnelBridgeLength(ti->tile, rampnorth) + 1, GetTunnelBridgeLength(ti->tile, rampsouth) + 1); drawfarpillar = !HasBit(GetBridgeSpec(bridge_type)->flags, 0); base_offset += GetBridgeSpriteTableBaseOffset(transport_type, rampsouth); - psid = GetBridgeSpriteTable(bridge_type, CalcBridgePiece(GetTunnelBridgeLength(ti->tile, rampnorth) + 1, GetTunnelBridgeLength(ti->tile, rampsouth) + 1)); + psid = GetBridgeSpriteTable(bridge_type, bridge_piece); pillars = GetBridgeTilePillarFlags(ti->tile, rampnorth, rampsouth, bridge_type, transport_type); + is_custom_layout = BridgeHasCustomSpriteTable(bridge_type, bridge_piece); } else { drawfarpillar = true; psid = _aqueduct_sprite_table_middle; @@ -1653,11 +1671,11 @@ void DrawBridgeMiddle(const TileInfo *ti, BridgePillarFlags blocked_pillars) if (transport_type == TRANSPORT_ROAD) { /* DrawBridgeRoadBits() calls EndSpriteCombine() and StartSpriteCombine() */ - DrawBridgeRoadBits(rampsouth, x, y, bridge_z, axis ^ 1, false); + DrawBridgeRoadBits(rampsouth, x, y, bridge_z, axis ^ 1, false, is_custom_layout); } else if (transport_type == TRANSPORT_RAIL) { const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(rampsouth)); - if (rti->UsesOverlay() && !IsInvisibilitySet(TO_BRIDGES)) { - SpriteID surface = GetCustomRailSprite(rti, rampsouth, RTSG_BRIDGE, TCX_ON_BRIDGE); + if (!IsInvisibilitySet(TO_BRIDGES)) { + SpriteID surface = rti->UsesOverlay() ? GetCustomRailSprite(rti, rampsouth, RTSG_BRIDGE, TCX_ON_BRIDGE) : rti->base_sprites.bridge_deck; if (surface != 0) { AddSortableSpriteToDraw(surface + axis, PAL_NONE, x, y, bridge_z, {{}, {TILE_SIZE, TILE_SIZE, 0}, {}}, IsTransparencySet(TO_BRIDGES)); } From 3087194d80f479355a139e2190011adc6f649806 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 28 Sep 2025 19:10:16 +0100 Subject: [PATCH 055/137] Codechange: Use Rects for group window drawing. Simplifies handling of LTR/RTL coordinates. --- src/group_gui.cpp | 75 +++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 35 deletions(-) diff --git a/src/group_gui.cpp b/src/group_gui.cpp index df081be946329..e697fb4a3844d 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -281,19 +281,17 @@ class VehicleGroupWindow : public BaseVehicleListWindow { /** * Draw a row in the group list. - * @param y Top of the row. - * @param left Left of the row. - * @param right Right of the row. + * @param r Rect to draw row in. * @param g_id Group to list. * @param indent Indentation level. * @param protection Whether autoreplace protection is set. * @param has_children Whether the group has children and should have a fold / unfold button. */ - void DrawGroupInfo(int y, int left, int right, GroupID g_id, uint16_t level_mask = 0, uint8_t indent = 0, bool protection = false, bool has_children = false) const + void DrawGroupInfo(Rect r, GroupID g_id, uint16_t level_mask = 0, uint8_t indent = 0, bool protection = false, bool has_children = false) const { /* Highlight the group if a vehicle is dragged over it */ if (g_id == this->group_over) { - GfxFillRect(left + WidgetDimensions::scaled.bevel.left, y + WidgetDimensions::scaled.framerect.top, right - WidgetDimensions::scaled.bevel.right, y + this->tiny_step_height - 1 - WidgetDimensions::scaled.framerect.bottom, GetColourGradient(COLOUR_GREY, SHADE_LIGHTEST)); + GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), GetColourGradient(COLOUR_GREY, SHADE_LIGHTEST)); } if (g_id == NEW_GROUP) return; @@ -307,25 +305,29 @@ class VehicleGroupWindow : public BaseVehicleListWindow { const int level_width = rtl ? -WidgetDimensions::scaled.hsep_indent : WidgetDimensions::scaled.hsep_indent; const PixelColour linecolour = GetColourGradient(COLOUR_ORANGE, SHADE_NORMAL); + r = r.Shrink(WidgetDimensions::scaled.framerect, RectPadding::zero); if (indent > 0) { /* Draw tree continuation lines. */ - int tx = (rtl ? right - WidgetDimensions::scaled.framerect.right : left + WidgetDimensions::scaled.framerect.left) + offset; + int tx = (rtl ? r.right : r.left) + offset; for (uint lvl = 1; lvl <= indent; ++lvl) { - if (HasBit(level_mask, lvl)) GfxDrawLine(tx, y, tx, y + this->tiny_step_height - 1, linecolour, WidgetDimensions::scaled.fullbevel.top); + if (HasBit(level_mask, lvl)) GfxDrawLine(tx, r.top, tx, r.bottom, linecolour, WidgetDimensions::scaled.fullbevel.top); if (lvl < indent) tx += level_width; } /* Draw our node in the tree. */ - int ycentre = y + this->tiny_step_height / 2 - 1; - if (!HasBit(level_mask, indent)) GfxDrawLine(tx, y, tx, ycentre, linecolour, WidgetDimensions::scaled.fullbevel.top); + int ycentre = CentreBounds(r.top, r.bottom, WidgetDimensions::scaled.fullbevel.top); + if (!HasBit(level_mask, indent)) GfxDrawLine(tx, r.top, tx, ycentre, linecolour, WidgetDimensions::scaled.fullbevel.top); GfxDrawLine(tx, ycentre, tx + offset - (rtl ? -1 : 1), ycentre, linecolour, WidgetDimensions::scaled.fullbevel.top); } /* draw fold / unfold button */ - int x = rtl ? right - WidgetDimensions::scaled.framerect.right - this->column_size[VGC_FOLD].width + 1 : left + WidgetDimensions::scaled.framerect.left; + r = r.Indent(indent * WidgetDimensions::scaled.hsep_indent, rtl); if (has_children) { - DrawSprite(Group::Get(g_id)->folded ? SPR_CIRCLE_FOLDED : SPR_CIRCLE_UNFOLDED, PAL_NONE, x + indent * level_width, y + (this->tiny_step_height - this->column_size[VGC_FOLD].height) / 2); + DrawSpriteIgnorePadding(Group::Get(g_id)->folded ? SPR_CIRCLE_FOLDED : SPR_CIRCLE_UNFOLDED, PAL_NONE, r.WithWidth(this->column_size[VGC_FOLD].width, rtl), SA_CENTER); } + /* Group name text column shrinks to fit available space. */ + int text_width = this->column_size[VGC_NAME].width - indent * WidgetDimensions::scaled.hsep_indent; + /* draw group name */ std::string str; if (IsAllGroupID(g_id)) { @@ -335,19 +337,22 @@ class VehicleGroupWindow : public BaseVehicleListWindow { } else { str = GetString(STR_GROUP_NAME, g_id); } - x = rtl ? x - WidgetDimensions::scaled.hsep_normal - this->column_size[VGC_NAME].width : x + WidgetDimensions::scaled.hsep_normal + this->column_size[VGC_FOLD].width; - DrawString(x + (rtl ? 0 : indent * WidgetDimensions::scaled.hsep_indent), x + this->column_size[VGC_NAME].width - 1 - (rtl ? indent * WidgetDimensions::scaled.hsep_indent : 0), y + (this->tiny_step_height - this->column_size[VGC_NAME].height) / 2, std::move(str), colour); + r = r.Indent(this->column_size[VGC_FOLD].width + WidgetDimensions::scaled.hsep_normal, rtl); + DrawString(r.WithWidth(text_width, rtl).CentreToHeight(this->column_size[VGC_NAME].height), std::move(str), colour); /* draw autoreplace protection */ - x = rtl ? x - WidgetDimensions::scaled.hsep_wide - this->column_size[VGC_PROTECT].width : x + WidgetDimensions::scaled.hsep_wide + this->column_size[VGC_NAME].width; - if (protection) DrawSprite(SPR_GROUP_REPLACE_PROTECT, PAL_NONE, x, y + (this->tiny_step_height - this->column_size[VGC_PROTECT].height) / 2); + r = r.Indent(text_width + WidgetDimensions::scaled.hsep_wide, rtl); + if (protection) { + DrawSpriteIgnorePadding(SPR_GROUP_REPLACE_PROTECT, PAL_NONE, r.WithWidth(this->column_size[VGC_PROTECT].width, rtl), SA_CENTER); + } /* draw autoreplace status */ - x = rtl ? x - WidgetDimensions::scaled.hsep_normal - this->column_size[VGC_AUTOREPLACE].width : x + WidgetDimensions::scaled.hsep_normal + this->column_size[VGC_PROTECT].width; - if (stats.autoreplace_defined) DrawSprite(SPR_GROUP_REPLACE_ACTIVE, stats.autoreplace_finished ? PALETTE_CRASH : PAL_NONE, x, y + (this->tiny_step_height - this->column_size[VGC_AUTOREPLACE].height) / 2); + r = r.Indent(this->column_size[VGC_PROTECT].width + WidgetDimensions::scaled.hsep_normal, rtl); + if (stats.autoreplace_defined) { + DrawSpriteIgnorePadding(SPR_GROUP_REPLACE_ACTIVE, stats.autoreplace_finished ? PALETTE_CRASH : PAL_NONE, r.WithWidth(this->column_size[VGC_AUTOREPLACE].width, rtl), SA_CENTER); + } /* draw the profit icon */ - x = rtl ? x - WidgetDimensions::scaled.hsep_normal - this->column_size[VGC_PROFIT].width : x + WidgetDimensions::scaled.hsep_normal + this->column_size[VGC_AUTOREPLACE].width; SpriteID spr; uint num_vehicle_min_age = GetGroupNumVehicleMinAge(this->vli.company, g_id, this->vli.vtype); Money profit_last_year_min_age = GetGroupProfitLastYearMinAge(this->vli.company, g_id, this->vli.vtype); @@ -360,16 +365,18 @@ class VehicleGroupWindow : public BaseVehicleListWindow { } else { spr = SPR_PROFIT_LOT; } - DrawSprite(spr, PAL_NONE, x, y + (this->tiny_step_height - this->column_size[VGC_PROFIT].height) / 2); + + r = r.Indent(this->column_size[VGC_AUTOREPLACE].width + WidgetDimensions::scaled.hsep_normal, rtl); + DrawSpriteIgnorePadding(spr, PAL_NONE, r.WithWidth(this->column_size[VGC_PROFIT].width, rtl), SA_CENTER); /* draw the number of vehicles of the group */ - x = rtl ? x - WidgetDimensions::scaled.hsep_normal - this->column_size[VGC_NUMBER].width : x + WidgetDimensions::scaled.hsep_normal + this->column_size[VGC_PROFIT].width; + r = r.Indent(this->column_size[VGC_PROFIT].width + WidgetDimensions::scaled.hsep_normal, rtl); int num_vehicle_with_subgroups = GetGroupNumVehicle(this->vli.company, g_id, this->vli.vtype); int num_vehicle = GroupStatistics::Get(this->vli.company, g_id, this->vli.vtype).num_vehicle; if (IsAllGroupID(g_id) || IsDefaultGroupID(g_id) || num_vehicle_with_subgroups == num_vehicle) { - DrawString(x, x + this->column_size[VGC_NUMBER].width - 1, y + (this->tiny_step_height - this->column_size[VGC_NUMBER].height) / 2, GetString(STR_JUST_COMMA, num_vehicle), colour, SA_RIGHT | SA_FORCE, false, FS_SMALL); + DrawString(r.CentreToHeight(this->column_size[VGC_NUMBER].height), GetString(STR_JUST_COMMA, num_vehicle), colour, SA_RIGHT | SA_FORCE, false, FS_SMALL); } else { - DrawString(x, x + this->column_size[VGC_NUMBER].width - 1, y + (this->tiny_step_height - this->column_size[VGC_NUMBER].height) / 2, GetString(STR_GROUP_COUNT_WITH_SUBGROUP, num_vehicle, num_vehicle_with_subgroups - num_vehicle), colour, SA_RIGHT | SA_FORCE); + DrawString(r.CentreToHeight(this->column_size[VGC_NUMBER].height), GetString(STR_GROUP_COUNT_WITH_SUBGROUP, num_vehicle, num_vehicle_with_subgroups - num_vehicle), colour, SA_RIGHT | SA_FORCE); } } @@ -594,11 +601,11 @@ class VehicleGroupWindow : public BaseVehicleListWindow { { switch (widget) { case WID_GL_ALL_VEHICLES: - DrawGroupInfo(r.top, r.left, r.right, ALL_GROUP); + DrawGroupInfo(r, ALL_GROUP); break; case WID_GL_DEFAULT_VEHICLES: - DrawGroupInfo(r.top, r.left, r.right, DEFAULT_GROUP); + DrawGroupInfo(r, DEFAULT_GROUP); break; case WID_GL_INFO: { @@ -634,19 +641,18 @@ class VehicleGroupWindow : public BaseVehicleListWindow { } case WID_GL_LIST_GROUP: { - int y1 = r.top; + Rect row = r.WithHeight(this->tiny_step_height); + auto [first, last] = this->group_sb->GetVisibleRangeIterators(this->groups); for (auto it = first; it != last; ++it) { const Group *g = it->group; - assert(g->owner == this->owner); - DrawGroupInfo(y1, r.left, r.right, g->index, it->level_mask, it->indent, g->flags.Test(GroupFlag::ReplaceProtection), g->folded || (std::next(it) != std::end(this->groups) && std::next(it)->indent > it->indent)); - - y1 += this->tiny_step_height; + DrawGroupInfo(row, g->index, it->level_mask, it->indent, g->flags.Test(GroupFlag::ReplaceProtection), g->folded || (std::next(it) != std::end(this->groups) && std::next(it)->indent > it->indent)); + row = row.Translate(0, this->tiny_step_height); } if ((uint)this->group_sb->GetPosition() + this->group_sb->GetCapacity() > this->groups.size()) { - DrawGroupInfo(y1, r.left, r.right, NEW_GROUP); + DrawGroupInfo(row, NEW_GROUP); } break; } @@ -733,11 +739,10 @@ class VehicleGroupWindow : public BaseVehicleListWindow { if (it->group->folded || (std::next(it) != std::end(this->groups) && std::next(it)->indent > it->indent)) { /* The group has children, check if the user clicked the fold / unfold button. */ - NWidgetCore *group_display = this->GetWidget(widget); - int x = _current_text_dir == TD_RTL ? - group_display->pos_x + group_display->current_x - WidgetDimensions::scaled.framerect.right - it->indent * WidgetDimensions::scaled.hsep_indent - this->column_size[VGC_FOLD].width : - group_display->pos_x + WidgetDimensions::scaled.framerect.left + it->indent * WidgetDimensions::scaled.hsep_indent; - if (click_count > 1 || (pt.x >= x && pt.x < (int)(x + this->column_size[VGC_FOLD].width))) { + bool rtl = _current_text_dir == TD_RTL; + Rect r = this->GetWidget(widget)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect, RectPadding::zero); + r = r.Indent(it->indent * WidgetDimensions::scaled.hsep_indent, rtl).WithWidth(this->column_size[VGC_FOLD].width, rtl); + if (click_count > 1 || r.Contains(pt)) { GroupID g = this->vli.ToGroupID(); if (!IsAllGroupID(g) && !IsDefaultGroupID(g)) { From 42084ca5168eb4f640c14528da79dc9b2c4f004e Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 28 Sep 2025 19:23:57 +0100 Subject: [PATCH 056/137] Change: Make groups window group list aware of interface scaling. --- src/group_gui.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/group_gui.cpp b/src/group_gui.cpp index e697fb4a3844d..aa761e7c72677 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -240,24 +240,24 @@ class VehicleGroupWindow : public BaseVehicleListWindow { */ uint ComputeGroupInfoSize() { - this->column_size[VGC_FOLD] = maxdim(GetSpriteSize(SPR_CIRCLE_FOLDED), GetSpriteSize(SPR_CIRCLE_UNFOLDED)); + this->column_size[VGC_FOLD] = maxdim(GetScaledSpriteSize(SPR_CIRCLE_FOLDED), GetScaledSpriteSize(SPR_CIRCLE_UNFOLDED)); this->tiny_step_height = this->column_size[VGC_FOLD].height; this->column_size[VGC_NAME] = maxdim(GetStringBoundingBox(STR_GROUP_DEFAULT_TRAINS + this->vli.vtype), GetStringBoundingBox(STR_GROUP_ALL_TRAINS + this->vli.vtype)); this->column_size[VGC_NAME].width = std::max(170u, this->column_size[VGC_NAME].width) + WidgetDimensions::scaled.hsep_indent; this->tiny_step_height = std::max(this->tiny_step_height, this->column_size[VGC_NAME].height); - this->column_size[VGC_PROTECT] = GetSpriteSize(SPR_GROUP_REPLACE_PROTECT); + this->column_size[VGC_PROTECT] = GetScaledSpriteSize(SPR_GROUP_REPLACE_PROTECT); this->tiny_step_height = std::max(this->tiny_step_height, this->column_size[VGC_PROTECT].height); - this->column_size[VGC_AUTOREPLACE] = GetSpriteSize(SPR_GROUP_REPLACE_ACTIVE); + this->column_size[VGC_AUTOREPLACE] = GetScaledSpriteSize(SPR_GROUP_REPLACE_ACTIVE); this->tiny_step_height = std::max(this->tiny_step_height, this->column_size[VGC_AUTOREPLACE].height); this->column_size[VGC_PROFIT].width = 0; this->column_size[VGC_PROFIT].height = 0; static const SpriteID profit_sprites[] = {SPR_PROFIT_NA, SPR_PROFIT_NEGATIVE, SPR_PROFIT_SOME, SPR_PROFIT_LOT}; for (const auto &profit_sprite : profit_sprites) { - Dimension d = GetSpriteSize(profit_sprite); + Dimension d = GetScaledSpriteSize(profit_sprite); this->column_size[VGC_PROFIT] = maxdim(this->column_size[VGC_PROFIT], d); } this->tiny_step_height = std::max(this->tiny_step_height, this->column_size[VGC_PROFIT].height); From 9eacb889f810eb1668f1e783f0c4296aaf62af0d Mon Sep 17 00:00:00 2001 From: translators Date: Tue, 30 Sep 2025 04:38:08 +0000 Subject: [PATCH 057/137] Update: Translations from eints english (au): 1 change by krysclarke greek: 1 change by gh658804 hungarian: 4 changes by vargaviktor russian: 1 change by Ln-Wolf finnish: 1 change by hpiirai portuguese: 1 change by jcteotonio portuguese (brazilian): 1 change by pasantoro --- src/lang/brazilian_portuguese.txt | 1 + src/lang/english_AU.txt | 1 + src/lang/finnish.txt | 1 + src/lang/greek.txt | 1 + src/lang/hungarian.txt | 6 ++++-- src/lang/portuguese.txt | 1 + src/lang/russian.txt | 1 + 7 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index 762bcab37326c..d3b6f76991d72 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -3692,6 +3692,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Introduz STR_TOWN_DIRECTORY_CAPTION :{WHITE}Localidades ({COMMA} of {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Nenhum - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA}) {YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Nomes das localidades - clique em um nome para centralizar a visualização principal na cidade. Ctrl+Clique para abrir uma nova visualização na localização da localidade STR_TOWN_POPULATION :{BLACK}População mundial: {COMMA} diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt index 0b1ba3134d95a..10cc0ac016a00 100644 --- a/src/lang/english_AU.txt +++ b/src/lang/english_AU.txt @@ -3691,6 +3691,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Enter a STR_TOWN_DIRECTORY_CAPTION :{WHITE}Towns ({COMMA} of {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- None - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA}) {YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Town names - click on name to centre main view on town. Ctrl+Click to open a new viewport on town location STR_TOWN_POPULATION :{BLACK}World population: {COMMA} diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index a377d6509c1c4..6427a51c2af81 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -3691,6 +3691,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Syötä STR_TOWN_DIRECTORY_CAPTION :{WHITE}Kunnat ({COMMA}/{COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Ei mitään - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA}) {YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Kuntien nimet – keskitä päänäkymä kuntaan napsauttamalla nimeä. Ctrl+napsautus avaa uuden näkymäikkunan kunnan sijaintiin STR_TOWN_POPULATION :{BLACK}Maailman asukasluku: {COMMA} diff --git a/src/lang/greek.txt b/src/lang/greek.txt index 2c97b15f418cf..5ec9e6777016f 100644 --- a/src/lang/greek.txt +++ b/src/lang/greek.txt @@ -3784,6 +3784,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Δώστ STR_TOWN_DIRECTORY_CAPTION :{WHITE}Πόλεις ({COMMA} από {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Τίποτα - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA}) {YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Ονόματα πόλεων - πατήστε στο όνομα για κεντράρισμα της κύριας προβολής στην πόλη. Ctrl+Κλικ για άνοιγμα νέου παραθύρου προβολής στην τοποθεσία της πόλης STR_TOWN_POPULATION :{BLACK}Παγκόσμιος πληθυσμός: {COMMA} diff --git a/src/lang/hungarian.txt b/src/lang/hungarian.txt index 3bb4c6f731d2d..167ffc89fb604 100644 --- a/src/lang/hungarian.txt +++ b/src/lang/hungarian.txt @@ -3494,8 +3494,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Víz STR_MAPGEN_BORDER_RANDOM :{BLACK}Véletlen ###length 3 -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Véletlen -STR_MAPGEN_BORDER_MANUAL :{BLACK}Kézi +STR_MAPGEN_BORDER_RANDOMIZE :Véletlen +STR_MAPGEN_BORDER_MANUAL :Kézi +STR_MAPGEN_BORDER_INFINITE_WATER :Végtelen víz STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Magasságtérkép elforgatása: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Magasságtérkép neve: @@ -3754,6 +3755,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Felirat STR_TOWN_DIRECTORY_CAPTION :{WHITE}Városok ({COMMA}, {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Nincs - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA}) {YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Városnevek - kattints egy névre a város megnézéséhez. Ctrl+kattintással új nézet nyílik a városnál STR_TOWN_POPULATION :{BLACK}Világnépesség: {COMMA} diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index 560ef2bf4fc98..bc417f32d4a69 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -3692,6 +3692,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Introduz STR_TOWN_DIRECTORY_CAPTION :{WHITE}Localidades ({COMMA} de {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Nenhuma - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA}) {YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Nomes das localidades - clique no nome para centrar a visualização na cidade. Ctrl+Clique para abrir um novo visualizador na localização da localidade STR_TOWN_POPULATION :{BLACK}População Mundial: {COMMA} diff --git a/src/lang/russian.txt b/src/lang/russian.txt index de883b9d6bc21..e1aefd33195c6 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -3866,6 +3866,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Введ STR_TOWN_DIRECTORY_CAPTION :{WHITE}Города ({COMMA} / {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Нет - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA}) {YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Список городов. Щелчок по названию показывает город в основном окне. Ctrl+щелчок показывает в дополнительном окне. STR_TOWN_POPULATION :{BLACK}Население: {COMMA} From 5d5d27841b328176640ce934779e76886aebe14e Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 30 Sep 2025 22:16:50 +0100 Subject: [PATCH 058/137] Fix: Bootstrap ignored default OpenTTD truetype fonts. (#14684) Bootstrapping assumed that glyphs must be missing if there is no baseset, ignoring whether there actually are glyphs missing. --- src/bootstrap_gui.cpp | 2 +- src/fontcache/spritefontcache.cpp | 1 + src/strings.cpp | 7 +++---- src/strings_func.h | 2 +- src/textfile_gui.cpp | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/bootstrap_gui.cpp b/src/bootstrap_gui.cpp index ae04d45b7bd67..1cfd582c0d8d7 100644 --- a/src/bootstrap_gui.cpp +++ b/src/bootstrap_gui.cpp @@ -380,7 +380,7 @@ bool HandleBootstrap() /* Initialise the font cache. */ InitializeUnicodeGlyphMap(); /* Next "force" finding a suitable non-sprite font as the local font is missing. */ - CheckForMissingGlyphs(false); + CheckForMissingGlyphs(); /* Initialise the palette. The biggest step is 'faking' some recolour sprites. * This way the mauve and gray colours work and we can show the user interface. */ diff --git a/src/fontcache/spritefontcache.cpp b/src/fontcache/spritefontcache.cpp index 0ed1cff34e14d..8d6723726696c 100644 --- a/src/fontcache/spritefontcache.cpp +++ b/src/fontcache/spritefontcache.cpp @@ -94,6 +94,7 @@ void InitializeUnicodeGlyphMap(FontSize fs) SetUnicodeGlyph(fs, unicode_map.code, 0); } else { SpriteID sprite = base + key - ASCII_LETTERSTART; + if (!SpriteExists(sprite)) continue; SetUnicodeGlyph(fs, unicode_map.code, sprite); } } diff --git a/src/strings.cpp b/src/strings.cpp index f4ff461bc7c33..b4050dca0c83d 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -2356,15 +2356,14 @@ class LanguagePackGlyphSearcher : public MissingGlyphSearcher { * mean it might use characters that are not in the * font, which is the whole reason this check has * been added. - * @param base_font Whether to look at the base font as well. * @param searcher The methods to use to search for strings to check. * If nullptr the loaded language pack searcher is used. */ -void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher) +void CheckForMissingGlyphs(MissingGlyphSearcher *searcher) { static LanguagePackGlyphSearcher pack_searcher; if (searcher == nullptr) searcher = &pack_searcher; - bool bad_font = !base_font || searcher->FindMissingGlyphs(); + bool bad_font = searcher->FindMissingGlyphs(); #if defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA) if (bad_font) { /* We found an unprintable character... lets try whether we can find @@ -2390,7 +2389,7 @@ void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher) ShowErrorMessage(GetEncodedString(STR_JUST_RAW_STRING, std::move(err_str)), {}, WL_WARNING); } - if (bad_font && base_font) { + if (bad_font) { /* Our fallback font does miss characters too, so keep the * user chosen font as that is more likely to be any good than * the wild guess we made */ diff --git a/src/strings_func.h b/src/strings_func.h index 7bb9ae99ffd07..e883504b41c71 100644 --- a/src/strings_func.h +++ b/src/strings_func.h @@ -195,6 +195,6 @@ class MissingGlyphSearcher { bool FindMissingGlyphs(); }; -void CheckForMissingGlyphs(bool base_font = true, MissingGlyphSearcher *search = nullptr); +void CheckForMissingGlyphs(MissingGlyphSearcher *search = nullptr); #endif /* STRINGS_FUNC_H */ diff --git a/src/textfile_gui.cpp b/src/textfile_gui.cpp index 75650c52ef021..4c3f31d49b461 100644 --- a/src/textfile_gui.cpp +++ b/src/textfile_gui.cpp @@ -923,7 +923,7 @@ void TextfileWindow::LoadText(std::string_view buf) this->AfterLoadText(); this->ReflowContent(); - CheckForMissingGlyphs(true, this); + CheckForMissingGlyphs(this); /* The font may have changed when searching for glyphs, so ensure widget sizes are updated just in case. */ this->ReInit(); From 632ab6a4e51bb3cdab12f77798dadf0d741f697f Mon Sep 17 00:00:00 2001 From: translators Date: Wed, 1 Oct 2025 04:38:32 +0000 Subject: [PATCH 059/137] Update: Translations from eints chinese (traditional): 4 changes by KogentaSan english (us): 1 change by 2TallTyler korean: 1 change by telk5093 polish: 1 change by pAter-exe --- src/lang/english_US.txt | 1 + src/lang/korean.txt | 1 + src/lang/polish.txt | 1 + src/lang/traditional_chinese.txt | 6 ++++-- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index 10ad2ad02ab55..3640eda96ce69 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -3691,6 +3691,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Enter a STR_TOWN_DIRECTORY_CAPTION :{WHITE}Towns ({COMMA} of {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- None - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA}) {YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Town names - click on name to center main view on town. Ctrl+Click to open a new viewport on town location STR_TOWN_POPULATION :{BLACK}World population: {COMMA} diff --git a/src/lang/korean.txt b/src/lang/korean.txt index a2edd95224643..e0bb797da5d53 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -3692,6 +3692,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}팻말 STR_TOWN_DIRECTORY_CAPTION :{WHITE}도시 목록 ({1:COMMA}개 중 {0:COMMA}개) STR_TOWN_DIRECTORY_NONE :{ORANGE}(없음) STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA}) {YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}도시 이름 - 이 도시로 시점을 변경하려면 클릭하세요. CTRL+클릭하면 이 도시 위치를 기준으로 새로운 외부 화면을 엽니다 STR_TOWN_POPULATION :{BLACK}총 인구 수: {COMMA} diff --git a/src/lang/polish.txt b/src/lang/polish.txt index 9c35d70698459..6785c742b8eb4 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -4071,6 +4071,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Wpisz na STR_TOWN_DIRECTORY_CAPTION :{WHITE}Miasta ({COMMA} z {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Żaden - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA}) {YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Nazwy miast - kliknij na nazwę miasta, aby wyśrodkować na nim widok główny. Użyj Ctrl, aby otworzyć nowy podgląd na lokalizację miasta STR_TOWN_POPULATION :{BLACK}Populacja świata: {COMMA} diff --git a/src/lang/traditional_chinese.txt b/src/lang/traditional_chinese.txt index 56033a4f941a5..73cb73984e7f3 100644 --- a/src/lang/traditional_chinese.txt +++ b/src/lang/traditional_chinese.txt @@ -3430,8 +3430,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}水域 STR_MAPGEN_BORDER_RANDOM :{BLACK}隨機 ###length 3 -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}隨機 -STR_MAPGEN_BORDER_MANUAL :{BLACK}手動 +STR_MAPGEN_BORDER_RANDOMIZE :隨機 +STR_MAPGEN_BORDER_MANUAL :手動 +STR_MAPGEN_BORDER_INFINITE_WATER :無盡水域 STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}高度圖旋轉: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}高度圖名稱: @@ -3690,6 +3691,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}輸入 STR_TOWN_DIRECTORY_CAPTION :{WHITE}市鎮({COMMA} 座,總共 {COMMA} 座) STR_TOWN_DIRECTORY_NONE :{ORANGE}- 無 - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK}({COMMA}){YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}市鎮名稱 - 點選名稱可將市鎮置於畫面正中央。按住 點選可於市鎮位置開啟新檢視視窗 STR_TOWN_POPULATION :{BLACK}世界人口:{COMMA} From 97674ac2a21b2a15a11a90d61ba610cfcf3bec3e Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 3 Oct 2025 22:28:28 +0100 Subject: [PATCH 060/137] Fix f6c5da4cad: dump_info should not reverse non-ASCII label. (#14697) Cargo/rail/road types labels are already in appropriate endian-ness. --- src/console_cmds.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 338c9a209ab0d..d3b086f60659c 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -2699,7 +2699,7 @@ static std::string FormatLabel(uint32_t label) return fmt::format("{:c}{:c}{:c}{:c}", GB(label, 24, 8), GB(label, 16, 8), GB(label, 8, 8), GB(label, 0, 8)); } - return fmt::format("{:08X}", std::byteswap(label)); + return fmt::format("{:08X}", label); } static void ConDumpRoadTypes() From 4d4096630378477528e2d045b3805b0df8ecf830 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 7 Sep 2025 14:13:57 +0100 Subject: [PATCH 061/137] Codechange: Use FlatSet to store and test alternate rail/road types. --- src/newgrf/newgrf_act0_railtypes.cpp | 2 +- src/newgrf/newgrf_act0_roadtypes.cpp | 2 +- src/rail.cpp | 3 +-- src/rail.h | 3 ++- src/road.cpp | 3 +-- src/road.h | 3 ++- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/newgrf/newgrf_act0_railtypes.cpp b/src/newgrf/newgrf_act0_railtypes.cpp index 27394f8bf414c..d37a3684eca7d 100644 --- a/src/newgrf/newgrf_act0_railtypes.cpp +++ b/src/newgrf/newgrf_act0_railtypes.cpp @@ -204,7 +204,7 @@ static ChangeInfoResult RailTypeReserveInfo(uint first, uint last, int prop, Byt if (type_map[id] != INVALID_RAILTYPE) { int n = buf.ReadByte(); for (int j = 0; j != n; j++) { - _railtypes[type_map[id]].alternate_labels.push_back(std::byteswap(buf.ReadDWord())); + _railtypes[type_map[id]].alternate_labels.insert(std::byteswap(buf.ReadDWord())); } break; } diff --git a/src/newgrf/newgrf_act0_roadtypes.cpp b/src/newgrf/newgrf_act0_roadtypes.cpp index 2eff6b05fde0d..4fa5746ce9bde 100644 --- a/src/newgrf/newgrf_act0_roadtypes.cpp +++ b/src/newgrf/newgrf_act0_roadtypes.cpp @@ -192,7 +192,7 @@ static ChangeInfoResult RoadTypeReserveInfo(uint first, uint last, int prop, Byt if (type_map[id] != INVALID_ROADTYPE) { int n = buf.ReadByte(); for (int j = 0; j != n; j++) { - _roadtypes[type_map[id]].alternate_labels.push_back(std::byteswap(buf.ReadDWord())); + _roadtypes[type_map[id]].alternate_labels.insert(std::byteswap(buf.ReadDWord())); } break; } diff --git a/src/rail.cpp b/src/rail.cpp index 590676aa87681..7e7174fef2de2 100644 --- a/src/rail.cpp +++ b/src/rail.cpp @@ -205,8 +205,7 @@ RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels) if (allow_alternate_labels) { /* Test if any rail type defines the label as an alternate. */ for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) { - const RailTypeInfo *rti = GetRailTypeInfo(r); - if (std::ranges::find(rti->alternate_labels, label) != rti->alternate_labels.end()) return r; + if (GetRailTypeInfo(r)->alternate_labels.contains(label)) return r; } } diff --git a/src/rail.h b/src/rail.h index b65f2351c86d5..9865f810038a1 100644 --- a/src/rail.h +++ b/src/rail.h @@ -15,6 +15,7 @@ #include "gfx_type.h" #include "core/bitmath_func.hpp" #include "core/enum_type.hpp" +#include "core/flatset_type.hpp" #include "economy_func.h" #include "slope_type.h" #include "strings_type.h" @@ -227,7 +228,7 @@ class RailTypeInfo { /** * Rail type labels this type provides in addition to the main label. */ - std::vector alternate_labels; + FlatSet alternate_labels; /** * Colour on mini-map diff --git a/src/road.cpp b/src/road.cpp index 51bdf1900d39d..590abfa07c2c2 100644 --- a/src/road.cpp +++ b/src/road.cpp @@ -275,8 +275,7 @@ RoadType GetRoadTypeByLabel(RoadTypeLabel label, bool allow_alternate_labels) if (allow_alternate_labels) { /* Test if any road type defines the label as an alternate. */ for (RoadType r = ROADTYPE_BEGIN; r != ROADTYPE_END; r++) { - const RoadTypeInfo *rti = GetRoadTypeInfo(r); - if (std::ranges::find(rti->alternate_labels, label) != rti->alternate_labels.end()) return r; + if (GetRoadTypeInfo(r)->alternate_labels.contains(label)) return r; } } diff --git a/src/road.h b/src/road.h index a3c689419fba5..b67df0e70aa55 100644 --- a/src/road.h +++ b/src/road.h @@ -13,6 +13,7 @@ #include "road_type.h" #include "gfx_type.h" #include "core/bitmath_func.hpp" +#include "core/flatset_type.hpp" #include "strings_type.h" #include "timer/timer_game_calendar.h" #include "core/enum_type.hpp" @@ -137,7 +138,7 @@ class RoadTypeInfo { /** * Road type labels this type provides in addition to the main label. */ - std::vector alternate_labels; + FlatSet alternate_labels; /** * Colour on mini-map From 6fdacb0759144b13099867b590a548db7df7ae01 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Wed, 1 Oct 2025 21:54:40 +0100 Subject: [PATCH 062/137] Codechange: Use find/find_if to search for rail/road types by label. Replaces manual loops. --- src/rail.cpp | 16 ++++++---------- src/road.cpp | 16 ++++++---------- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/src/rail.cpp b/src/rail.cpp index 7e7174fef2de2..b977c1c9631d1 100644 --- a/src/rail.cpp +++ b/src/rail.cpp @@ -194,21 +194,17 @@ RailTypes GetRailTypes(bool introduces) */ RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels) { + extern RailTypeInfo _railtypes[RAILTYPE_END]; if (label == 0) return INVALID_RAILTYPE; - /* Loop through each rail type until the label is found */ - for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) { - const RailTypeInfo *rti = GetRailTypeInfo(r); - if (rti->label == label) return r; - } - - if (allow_alternate_labels) { + auto it = std::ranges::find(_railtypes, label, &RailTypeInfo::label); + if (it == std::end(_railtypes) && allow_alternate_labels) { /* Test if any rail type defines the label as an alternate. */ - for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) { - if (GetRailTypeInfo(r)->alternate_labels.contains(label)) return r; - } + it = std::ranges::find_if(_railtypes, [label](const RailTypeInfo &rti) { return rti.alternate_labels.contains(label); }); } + if (it != std::end(_railtypes)) return it->Index(); + /* No matching label was found, so it is invalid */ return INVALID_RAILTYPE; } diff --git a/src/road.cpp b/src/road.cpp index 590abfa07c2c2..18478e9598a26 100644 --- a/src/road.cpp +++ b/src/road.cpp @@ -264,21 +264,17 @@ RoadTypes GetRoadTypes(bool introduces) */ RoadType GetRoadTypeByLabel(RoadTypeLabel label, bool allow_alternate_labels) { + extern RoadTypeInfo _roadtypes[ROADTYPE_END]; if (label == 0) return INVALID_ROADTYPE; - /* Loop through each road type until the label is found */ - for (RoadType r = ROADTYPE_BEGIN; r != ROADTYPE_END; r++) { - const RoadTypeInfo *rti = GetRoadTypeInfo(r); - if (rti->label == label) return r; - } - - if (allow_alternate_labels) { + auto it = std::ranges::find(_roadtypes, label, &RoadTypeInfo::label); + if (it == std::end(_roadtypes) && allow_alternate_labels) { /* Test if any road type defines the label as an alternate. */ - for (RoadType r = ROADTYPE_BEGIN; r != ROADTYPE_END; r++) { - if (GetRoadTypeInfo(r)->alternate_labels.contains(label)) return r; - } + it = std::ranges::find_if(_roadtypes, [label](const RoadTypeInfo &rti) { return rti.alternate_labels.contains(label); }); } + if (it != std::end(_roadtypes)) return it->Index(); + /* No matching label was found, so it is invalid */ return INVALID_ROADTYPE; } From c9fbc41636ff7c39629e6426e5f6ca98dc7bc43c Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 5 Oct 2025 07:57:09 +0100 Subject: [PATCH 063/137] Codechange: Script list iterator tidying. (#14698) * Use `iter->` instead of `(*iter).` * Use prefix instead of postfix operators * Use `auto` instead of explicit iterator type. * Use `std::next()` instead of assignment then increment. * Use range-for where possible. --- src/script/api/script_list.cpp | 118 ++++++++++++++++----------------- 1 file changed, 57 insertions(+), 61 deletions(-) diff --git a/src/script/api/script_list.cpp b/src/script/api/script_list.cpp index 134b80287b108..90bc74d0b7910 100644 --- a/src/script/api/script_list.cpp +++ b/src/script/api/script_list.cpp @@ -95,7 +95,7 @@ class ScriptListSorterValueAscending : public ScriptListSorter { this->has_no_more_items = false; this->bucket_iter = this->list->buckets.begin(); - this->bucket_list = &(*this->bucket_iter).second; + this->bucket_list = &this->bucket_iter->second; this->bucket_list_iter = this->bucket_list->begin(); this->item_next = *this->bucket_list_iter; @@ -121,14 +121,14 @@ class ScriptListSorterValueAscending : public ScriptListSorter { return; } - this->bucket_list_iter++; + ++this->bucket_list_iter; if (this->bucket_list_iter == this->bucket_list->end()) { - this->bucket_iter++; + ++this->bucket_iter; if (this->bucket_iter == this->list->buckets.end()) { this->bucket_list = nullptr; return; } - this->bucket_list = &(*this->bucket_iter).second; + this->bucket_list = &this->bucket_iter->second; this->bucket_list_iter = this->bucket_list->begin(); } this->item_next = *this->bucket_list_iter; @@ -186,7 +186,7 @@ class ScriptListSorterValueDescending : public ScriptListSorter { /* Go to the end of the bucket-list */ this->bucket_iter = this->list->buckets.end(); --this->bucket_iter; - this->bucket_list = &(*this->bucket_iter).second; + this->bucket_list = &this->bucket_iter->second; /* Go to the end of the items in the bucket */ this->bucket_list_iter = this->bucket_list->end(); @@ -220,14 +220,12 @@ class ScriptListSorterValueDescending : public ScriptListSorter { this->bucket_list = nullptr; return; } - this->bucket_iter--; - this->bucket_list = &(*this->bucket_iter).second; + --this->bucket_iter; + this->bucket_list = &this->bucket_iter->second; /* Go to the end of the items in the bucket */ this->bucket_list_iter = this->bucket_list->end(); - --this->bucket_list_iter; - } else { - this->bucket_list_iter--; } + --this->bucket_list_iter; this->item_next = *this->bucket_list_iter; } @@ -276,7 +274,7 @@ class ScriptListSorterItemAscending : public ScriptListSorter { this->has_no_more_items = false; this->item_iter = this->list->items.begin(); - this->item_next = (*this->item_iter).first; + this->item_next = this->item_iter->first; SQInteger item_current = this->item_next; FindNext(); @@ -297,8 +295,8 @@ class ScriptListSorterItemAscending : public ScriptListSorter { this->has_no_more_items = true; return; } - this->item_iter++; - if (this->item_iter != this->list->items.end()) item_next = (*this->item_iter).first; + ++this->item_iter; + if (this->item_iter != this->list->items.end()) item_next = this->item_iter->first; } SQInteger Next() override @@ -350,7 +348,7 @@ class ScriptListSorterItemDescending : public ScriptListSorter { this->item_iter = this->list->items.end(); --this->item_iter; - this->item_next = (*this->item_iter).first; + this->item_next = this->item_iter->first; SQInteger item_current = this->item_next; FindNext(); @@ -375,9 +373,9 @@ class ScriptListSorterItemDescending : public ScriptListSorter { /* Use 'end' as marker for 'beyond begin' */ this->item_iter = this->list->items.end(); } else { - this->item_iter--; + --this->item_iter; } - if (this->item_iter != this->list->items.end()) item_next = (*this->item_iter).first; + if (this->item_iter != this->list->items.end()) item_next = this->item_iter->first; } SQInteger Next() override @@ -412,9 +410,9 @@ bool ScriptList::SaveObject(HSQUIRRELVM vm) sq_pushbool(vm, this->sort_ascending ? SQTrue : SQFalse); sq_arrayappend(vm, -2); sq_newtable(vm); - for (ScriptListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) { - sq_pushinteger(vm, iter->first); - sq_pushinteger(vm, iter->second); + for (const auto &item : this->items) { + sq_pushinteger(vm, item.first); + sq_pushinteger(vm, item.second); sq_rawset(vm, -3); } sq_arrayappend(vm, -2); @@ -509,13 +507,13 @@ void ScriptList::RemoveItem(SQInteger item) { this->modifications++; - ScriptListMap::iterator item_iter = this->items.find(item); + auto item_iter = this->items.find(item); if (item_iter == this->items.end()) return; SQInteger value = item_iter->second; this->sorter->Remove(item); - ScriptListBucket::iterator bucket_iter = this->buckets.find(value); + auto bucket_iter = this->buckets.find(value); assert(bucket_iter != this->buckets.end()); bucket_iter->second.erase(item); if (bucket_iter->second.empty()) this->buckets.erase(bucket_iter); @@ -558,7 +556,7 @@ SQInteger ScriptList::Count() SQInteger ScriptList::GetValue(SQInteger item) { - ScriptListMap::const_iterator item_iter = this->items.find(item); + auto item_iter = this->items.find(item); return item_iter == this->items.end() ? 0 : item_iter->second; } @@ -566,14 +564,14 @@ bool ScriptList::SetValue(SQInteger item, SQInteger value) { this->modifications++; - ScriptListMap::iterator item_iter = this->items.find(item); + auto item_iter = this->items.find(item); if (item_iter == this->items.end()) return false; SQInteger value_old = item_iter->second; if (value_old == value) return true; this->sorter->Remove(item); - ScriptListBucket::iterator bucket_iter = this->buckets.find(value_old); + auto bucket_iter = this->buckets.find(value_old); assert(bucket_iter != this->buckets.end()); bucket_iter->second.erase(item); if (bucket_iter->second.empty()) this->buckets.erase(bucket_iter); @@ -624,10 +622,9 @@ void ScriptList::AddList(ScriptList *list) this->buckets = list->buckets; this->modifications++; } else { - ScriptListMap *list_items = &list->items; - for (auto &it : *list_items) { - this->AddItem(it.first); - this->SetValue(it.first, it.second); + for (const auto &item : list->items) { + this->AddItem(item.first); + this->SetValue(item.first, item.second); } } } @@ -652,8 +649,8 @@ void ScriptList::RemoveAboveValue(SQInteger value) this->modifications++; for (ScriptListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).second > value) this->RemoveItem((*iter).first); + next_iter = std::next(iter); + if (iter->second > value) this->RemoveItem(iter->first); } } @@ -662,8 +659,8 @@ void ScriptList::RemoveBelowValue(SQInteger value) this->modifications++; for (ScriptListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).second < value) this->RemoveItem((*iter).first); + next_iter = std::next(iter); + if (iter->second < value) this->RemoveItem(iter->first); } } @@ -672,8 +669,8 @@ void ScriptList::RemoveBetweenValue(SQInteger start, SQInteger end) this->modifications++; for (ScriptListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).second > start && (*iter).second < end) this->RemoveItem((*iter).first); + next_iter = std::next(iter); + if (iter->second > start && iter->second < end) this->RemoveItem(iter->first); } } @@ -682,8 +679,8 @@ void ScriptList::RemoveValue(SQInteger value) this->modifications++; for (ScriptListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).second == value) this->RemoveItem((*iter).first); + next_iter = std::next(iter); + if (iter->second == value) this->RemoveItem(iter->first); } } @@ -701,10 +698,10 @@ void ScriptList::RemoveTop(SQInteger count) switch (this->sorter_type) { default: NOT_REACHED(); case SORT_BY_VALUE: - for (ScriptListBucket::iterator iter = this->buckets.begin(); iter != this->buckets.end(); iter = this->buckets.begin()) { - ScriptItemList *items = &(*iter).second; + for (auto iter = this->buckets.begin(); iter != this->buckets.end(); iter = this->buckets.begin()) { + ScriptItemList *items = &iter->second; size_t size = items->size(); - for (ScriptItemList::iterator iter = items->begin(); iter != items->end(); iter = items->begin()) { + for (auto iter = items->begin(); iter != items->end(); iter = items->begin()) { if (--count < 0) return; this->RemoveItem(*iter); /* When the last item is removed from the bucket, the bucket itself is removed. @@ -716,9 +713,9 @@ void ScriptList::RemoveTop(SQInteger count) break; case SORT_BY_ITEM: - for (ScriptListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter = this->items.begin()) { + for (auto iter = this->items.begin(); iter != this->items.end(); iter = this->items.begin()) { if (--count < 0) return; - this->RemoveItem((*iter).first); + this->RemoveItem(iter->first); } break; } @@ -738,10 +735,10 @@ void ScriptList::RemoveBottom(SQInteger count) switch (this->sorter_type) { default: NOT_REACHED(); case SORT_BY_VALUE: - for (ScriptListBucket::reverse_iterator iter = this->buckets.rbegin(); iter != this->buckets.rend(); iter = this->buckets.rbegin()) { - ScriptItemList *items = &(*iter).second; + for (auto iter = this->buckets.rbegin(); iter != this->buckets.rend(); iter = this->buckets.rbegin()) { + ScriptItemList *items = &iter->second; size_t size = items->size(); - for (ScriptItemList::reverse_iterator iter = items->rbegin(); iter != items->rend(); iter = items->rbegin()) { + for (auto iter = items->rbegin(); iter != items->rend(); iter = items->rbegin()) { if (--count < 0) return; this->RemoveItem(*iter); /* When the last item is removed from the bucket, the bucket itself is removed. @@ -753,9 +750,9 @@ void ScriptList::RemoveBottom(SQInteger count) break; case SORT_BY_ITEM: - for (ScriptListMap::reverse_iterator iter = this->items.rbegin(); iter != this->items.rend(); iter = this->items.rbegin()) { + for (auto iter = this->items.rbegin(); iter != this->items.rend(); iter = this->items.rbegin()) { if (--count < 0) return; - this->RemoveItem((*iter).first); + this->RemoveItem(iter->first); } break; } @@ -768,9 +765,8 @@ void ScriptList::RemoveList(ScriptList *list) if (list == this) { Clear(); } else { - ScriptListMap *list_items = &list->items; - for (ScriptListMap::iterator iter = list_items->begin(); iter != list_items->end(); iter++) { - this->RemoveItem((*iter).first); + for (const auto &item : list->items) { + this->RemoveItem(item.first); } } } @@ -780,8 +776,8 @@ void ScriptList::KeepAboveValue(SQInteger value) this->modifications++; for (ScriptListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).second <= value) this->RemoveItem((*iter).first); + next_iter = std::next(iter); + if (iter->second <= value) this->RemoveItem(iter->first); } } @@ -790,8 +786,8 @@ void ScriptList::KeepBelowValue(SQInteger value) this->modifications++; for (ScriptListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).second >= value) this->RemoveItem((*iter).first); + next_iter = std::next(iter); + if (iter->second >= value) this->RemoveItem(iter->first); } } @@ -800,8 +796,8 @@ void ScriptList::KeepBetweenValue(SQInteger start, SQInteger end) this->modifications++; for (ScriptListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).second <= start || (*iter).second >= end) this->RemoveItem((*iter).first); + next_iter = std::next(iter); + if (iter->second <= start || iter->second >= end) this->RemoveItem(iter->first); } } @@ -810,8 +806,8 @@ void ScriptList::KeepValue(SQInteger value) this->modifications++; for (ScriptListMap::iterator next_iter, iter = this->items.begin(); iter != this->items.end(); iter = next_iter) { - next_iter = iter; next_iter++; - if ((*iter).second != value) this->RemoveItem((*iter).first); + next_iter = std::next(iter); + if (iter->second != value) this->RemoveItem(iter->first); } } @@ -848,7 +844,7 @@ SQInteger ScriptList::_get(HSQUIRRELVM vm) SQInteger idx; sq_getinteger(vm, 2, &idx); - ScriptListMap::const_iterator item_iter = this->items.find(idx); + auto item_iter = this->items.find(idx); if (item_iter == this->items.end()) return SQ_ERROR; sq_pushinteger(vm, item_iter->second); @@ -932,14 +928,14 @@ SQInteger ScriptList::Valuate(HSQUIRRELVM vm) /* Push the function to call */ sq_push(vm, 2); - for (ScriptListMap::iterator iter = this->items.begin(); iter != this->items.end(); iter++) { + for (const auto &item : this->items) { /* Check for changing of items. */ int previous_modification_count = this->modifications; /* Push the root table as instance object, this is what squirrel does for meta-functions. */ sq_pushroottable(vm); /* Push all arguments for the valuator function. */ - sq_pushinteger(vm, (*iter).first); + sq_pushinteger(vm, item.first); for (int i = 0; i < nparam - 1; i++) { sq_push(vm, i + 3); } @@ -980,7 +976,7 @@ SQInteger ScriptList::Valuate(HSQUIRRELVM vm) return sq_throwerror(vm, "modifying valuated list outside of valuator function"); } - this->SetValue((*iter).first, value); + this->SetValue(item.first, value); /* Pop the return value. */ sq_poptop(vm); From a617d009cca418255a9682fd83c9cebc6423303e Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 5 Oct 2025 15:47:33 +0100 Subject: [PATCH 064/137] Codechange: Dereference with `x->` instead of `(*x).` (#14700) --- src/ai/ai_scanner.cpp | 2 +- src/bitmap_type.h | 4 ++-- src/blitter/32bpp_sse2.cpp | 4 ++-- src/core/geometry_type.hpp | 6 +++--- src/fileio.cpp | 2 +- src/misc/dbg_helpers.cpp | 2 +- src/script/api/script_controller.cpp | 2 +- src/script/api/script_error.cpp | 2 +- src/script/script_config.cpp | 2 +- src/station_base.h | 4 ++-- src/viewport.cpp | 4 ++-- src/viewport_sprite_sorter_sse4.cpp | 4 ++-- 12 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/ai/ai_scanner.cpp b/src/ai/ai_scanner.cpp index 70e5b55148133..f4b055268499c 100644 --- a/src/ai/ai_scanner.cpp +++ b/src/ai/ai_scanner.cpp @@ -137,5 +137,5 @@ AILibrary *AIScannerLibrary::FindLibrary(const std::string &library, int version ScriptInfoList::iterator it = this->info_list.find(library_name); if (it == this->info_list.end()) return nullptr; - return static_cast((*it).second); + return static_cast(it->second); } diff --git a/src/bitmap_type.h b/src/bitmap_type.h index 4dd356e48a6bb..acf3b3d22b56f 100644 --- a/src/bitmap_type.h +++ b/src/bitmap_type.h @@ -118,9 +118,9 @@ class BitmapTileIterator : public OrthogonalTileIterator { inline TileIterator& operator ++() override { - (*this).OrthogonalTileIterator::operator++(); + this->OrthogonalTileIterator::operator++(); while (this->tile != INVALID_TILE && !this->bitmap->HasTile(TileIndex(this->tile))) { - (*this).OrthogonalTileIterator::operator++(); + this->OrthogonalTileIterator::operator++(); } return *this; } diff --git a/src/blitter/32bpp_sse2.cpp b/src/blitter/32bpp_sse2.cpp index 6fc08ca6cd4c0..791952a09522f 100644 --- a/src/blitter/32bpp_sse2.cpp +++ b/src/blitter/32bpp_sse2.cpp @@ -113,7 +113,7 @@ Sprite *Blitter_32bppSSE_Base::Encode(SpriteType sprite_type, const SpriteLoader else break; dst_rgba++; } - (*dst_rgba_line).data = nb_pix_transp; + dst_rgba_line->data = nb_pix_transp; Colour *nb_right = dst_rgba_line + 1; dst_rgba_line = reinterpret_cast(reinterpret_cast(dst_rgba_line) + info.sprite_line_size); @@ -126,7 +126,7 @@ Sprite *Blitter_32bppSSE_Base::Encode(SpriteType sprite_type, const SpriteLoader else break; dst_rgba--; } - (*nb_right).data = nb_pix_transp; + nb_right->data = nb_pix_transp; } } diff --git a/src/core/geometry_type.hpp b/src/core/geometry_type.hpp index ccc610fa90d03..e46315899ebb0 100644 --- a/src/core/geometry_type.hpp +++ b/src/core/geometry_type.hpp @@ -62,14 +62,14 @@ struct Dimension { bool operator< (const Dimension &other) const { - int x = (*this).width - other.width; + int x = this->width - other.width; if (x != 0) return x < 0; - return (*this).height < other.height; + return this->height < other.height; } bool operator== (const Dimension &other) const { - return (*this).width == other.width && (*this).height == other.height; + return this->width == other.width && this->height == other.height; } }; diff --git a/src/fileio.cpp b/src/fileio.cpp index 981d37c8cde90..da9ae826abfd5 100644 --- a/src/fileio.cpp +++ b/src/fileio.cpp @@ -593,7 +593,7 @@ bool ExtractTar(const std::string &tar_filename, Subdirectory subdir) /* We don't know the file. */ if (it == _tar_list[subdir].end()) return false; - const auto &dirname = (*it).second; + const auto &dirname = it->second; /* The file doesn't have a sub directory! */ if (dirname.empty()) { diff --git a/src/misc/dbg_helpers.cpp b/src/misc/dbg_helpers.cpp index 7e2d4314c400e..bc51801fa9dca 100644 --- a/src/misc/dbg_helpers.cpp +++ b/src/misc/dbg_helpers.cpp @@ -91,7 +91,7 @@ bool DumpTarget::FindKnownName(size_t type_id, const void *ptr, std::string &nam KNOWN_NAMES::const_iterator it = m_known_names.find(KnownStructKey(type_id, ptr)); if (it != m_known_names.end()) { /* we have found it */ - name = (*it).second; + name = it->second; return true; } return false; diff --git a/src/script/api/script_controller.cpp b/src/script/api/script_controller.cpp index 774b089ef5d4f..65c5970bda602 100644 --- a/src/script/api/script_controller.cpp +++ b/src/script/api/script_controller.cpp @@ -116,7 +116,7 @@ ScriptController::ScriptController(::CompanyID company) : LoadedLibraryList::iterator it = controller.loaded_library.find(library_name); if (it != controller.loaded_library.end()) { - fake_class = (*it).second; + fake_class = it->second; } else { int next_number = ++controller.loaded_library_count; diff --git a/src/script/api/script_error.cpp b/src/script/api/script_error.cpp index 953e9d8d383a4..34c1dfb9d56ff 100644 --- a/src/script/api/script_error.cpp +++ b/src/script/api/script_error.cpp @@ -54,7 +54,7 @@ ScriptError::ScriptErrorMapString ScriptError::error_map_string = ScriptError::S ScriptErrorMap::iterator it = error_map.find(internal_string_id); if (it == error_map.end()) return ERR_UNKNOWN; - return (*it).second; + return it->second; } /* static */ void ScriptError::RegisterErrorMap(StringID internal_string_id, ScriptErrorType ai_error_msg) diff --git a/src/script/script_config.cpp b/src/script/script_config.cpp index a599a7e30a746..7243af22af08b 100644 --- a/src/script/script_config.cpp +++ b/src/script/script_config.cpp @@ -85,7 +85,7 @@ int ScriptConfig::GetSetting(const std::string &name) const { const auto it = this->settings.find(name); if (it == this->settings.end()) return this->info->GetSettingDefaultValue(name); - return (*it).second; + return it->second; } void ScriptConfig::SetSetting(std::string_view name, int value) diff --git a/src/station_base.h b/src/station_base.h index b1d26cc72151c..d8e62d23393fa 100644 --- a/src/station_base.h +++ b/src/station_base.h @@ -599,9 +599,9 @@ class AirportTileIterator : public OrthogonalTileIterator { inline TileIterator& operator ++() override { - (*this).OrthogonalTileIterator::operator++(); + this->OrthogonalTileIterator::operator++(); while (this->tile != INVALID_TILE && !st->TileBelongsToAirport(this->tile)) { - (*this).OrthogonalTileIterator::operator++(); + this->OrthogonalTileIterator::operator++(); } return *this; } diff --git a/src/viewport.cpp b/src/viewport.cpp index 734a34bb7a68a..83d08f5c56610 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -1637,8 +1637,8 @@ static void ViewportSortParentSprites(ParentSpriteToSortVector *psdv) auto ssum = std::max(s->xmax, s->xmin) + std::max(s->ymax, s->ymin); auto prev = sprite_list.before_begin(); auto x = sprite_list.begin(); - while (x != sprite_list.end() && ((*x).first <= ssum)) { - auto p = (*x).second; + while (x != sprite_list.end() && x->first <= ssum) { + auto p = x->second; if (p == s) { /* We found the current sprite, remove it and move on. */ x = sprite_list.erase_after(prev); diff --git a/src/viewport_sprite_sorter_sse4.cpp b/src/viewport_sprite_sorter_sse4.cpp index a5ce747dc1891..448502ef0c777 100644 --- a/src/viewport_sprite_sorter_sse4.cpp +++ b/src/viewport_sprite_sorter_sse4.cpp @@ -87,8 +87,8 @@ void ViewportSortParentSpritesSSE41(ParentSpriteToSortVector *psdv) auto ssum = std::max(s->xmax, s->xmin) + std::max(s->ymax, s->ymin); auto prev = sprite_list.before_begin(); auto x = sprite_list.begin(); - while (x != sprite_list.end() && ((*x).first <= ssum)) { - auto p = (*x).second; + while (x != sprite_list.end() && x->first <= ssum) { + auto p = x->second; if (p == s) { /* We found the current sprite, remove it and move on. */ x = sprite_list.erase_after(prev); From f935e34d90b36543fc4331b4312b50d856ef8f8d Mon Sep 17 00:00:00 2001 From: Rito12 Date: Wed, 8 Oct 2025 17:10:47 +0200 Subject: [PATCH 065/137] Codefix: Remove double SetDirty() calls. --- src/build_vehicle_gui.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index f21a424f1ed90..812e9e32807ac 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1931,7 +1931,6 @@ struct BuildVehicleWindow : Window { /* We need to refresh if a filter is removed. */ this->eng_list.ForceRebuild(); - this->SetDirty(); break; } @@ -1943,7 +1942,6 @@ struct BuildVehicleWindow : Window { SetBadgeFilter(this->badge_filter_choices, BadgeID(index)); } this->eng_list.ForceRebuild(); - this->SetDirty(); } break; } From 8e055156e390ca255bcfe286726b21936321fd81 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 11 Oct 2025 10:22:50 +0100 Subject: [PATCH 066/137] Codefix: Make sure safeguards.h is the last included non-table header. (#14687) --- src/console_cmds.cpp | 5 ++++- src/fontcache/freetypefontcache.cpp | 7 ++++--- src/heightmap.cpp | 6 ++++-- src/openttd.cpp | 4 ++-- src/os/unix/unix.cpp | 9 ++++----- src/saveload/saveload.cpp | 15 ++++++++++++--- src/string.cpp | 8 +++----- src/video/allegro_v.cpp | 4 ++-- src/video/win32_v.cpp | 12 +++++++----- 9 files changed, 42 insertions(+), 28 deletions(-) diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index d3b086f60659c..ffc6b1366536e 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -46,6 +46,10 @@ #include "company_cmd.h" #include "misc_cmd.h" +#if defined(WITH_ZLIB) +#include "network/network_content.h" +#endif /* WITH_ZLIB */ + #include "table/strings.h" #include "safeguards.h" @@ -2176,7 +2180,6 @@ static bool ConNetworkAuthorizedKey(std::span argv) /* Content downloading only is available with ZLIB */ #if defined(WITH_ZLIB) -#include "network/network_content.h" /** Resolve a string to a content type. */ static ContentType StringToContentType(std::string_view str) diff --git a/src/fontcache/freetypefontcache.cpp b/src/fontcache/freetypefontcache.cpp index 0e3de26877e56..254b7224158c6 100644 --- a/src/fontcache/freetypefontcache.cpp +++ b/src/fontcache/freetypefontcache.cpp @@ -7,6 +7,8 @@ /** @file freetypefontcache.cpp FreeType font cache implementation. */ +#ifdef WITH_FREETYPE + #include "../stdafx.h" #include "../debug.h" @@ -20,14 +22,13 @@ #include "../table/control_codes.h" -#include "../safeguards.h" - -#ifdef WITH_FREETYPE #include #include FT_FREETYPE_H #include FT_GLYPH_H #include FT_TRUETYPE_TABLES_H +#include "../safeguards.h" + /** Font cache for fonts that are based on a freetype font. */ class FreeTypeFontCache : public TrueTypeFontCache { private: diff --git a/src/heightmap.cpp b/src/heightmap.cpp index 9d7a09bf7e4c2..0bbc79cb3d57a 100644 --- a/src/heightmap.cpp +++ b/src/heightmap.cpp @@ -22,6 +22,10 @@ #include "table/strings.h" +#ifdef WITH_PNG +#include +#endif /* WITH_PNG */ + #include "safeguards.h" /** @@ -72,8 +76,6 @@ static inline uint8_t RGBToGreyscale(uint8_t red, uint8_t green, uint8_t blue) #ifdef WITH_PNG -#include - /** * The PNG Heightmap loader. */ diff --git a/src/openttd.cpp b/src/openttd.cpp index a26aa68a978d1..4317b99e648ae 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -88,13 +88,13 @@ #include "table/strings.h" -#include "safeguards.h" - #ifdef __EMSCRIPTEN__ # include # include #endif +#include "safeguards.h" + void CallLandscapeTick(); void DoPaletteAnimations(); void MusicLoop(); diff --git a/src/os/unix/unix.cpp b/src/os/unix/unix.cpp index 36ee069637b2f..5bc89cceac227 100644 --- a/src/os/unix/unix.cpp +++ b/src/os/unix/unix.cpp @@ -14,7 +14,6 @@ #include "../../fios.h" #include "../../thread.h" - #include #include #include @@ -26,6 +25,10 @@ #include #endif +#ifdef WITH_ICONV +#include +#endif /* WITH_ICONV */ + #ifdef __EMSCRIPTEN__ # include #endif @@ -85,10 +88,6 @@ bool FiosIsHiddenFile(const std::filesystem::path &path) #ifdef WITH_ICONV -#include -#include "../../debug.h" -#include "../../string_func.h" - std::optional GetCurrentLocale(const char *param); #define INTERNALCODE "UTF-8" diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index f602bd1524355..9f759cc7b041a 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -56,6 +56,18 @@ # include #endif +#ifdef WITH_LZO +#include +#endif + +#if defined(WITH_ZLIB) +#include +#endif /* WITH_ZLIB */ + +#if defined(WITH_LIBLZMA) +#include +#endif /* WITH_LIBLZMA */ + #include "table/strings.h" #include "../safeguards.h" @@ -2417,7 +2429,6 @@ struct FileWriter : SaveFilter { *******************************************/ #ifdef WITH_LZO -#include /** Buffer size for the LZO compressor */ static const uint LZO_BUFFER_SIZE = 8192; @@ -2546,7 +2557,6 @@ struct NoCompSaveFilter : SaveFilter { ********************************************/ #if defined(WITH_ZLIB) -#include /** Filter using Zlib compression. */ struct ZlibLoadFilter : LoadFilter { @@ -2665,7 +2675,6 @@ struct ZlibSaveFilter : SaveFilter { ********************************************/ #if defined(WITH_LIBLZMA) -#include /** * Have a copy of an initialised LZMA stream. We need this as it's diff --git a/src/string.cpp b/src/string.cpp index 18827e59042db..09b3f7250d58c 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -28,7 +28,10 @@ #ifdef WITH_ICU_I18N /* Required by StrNaturalCompare. */ +# include +# include # include +# include # include "language.h" # include "gfx_func.h" #endif /* WITH_ICU_I18N */ @@ -453,8 +456,6 @@ int StrNaturalCompare(std::string_view s1, std::string_view s2, bool ignore_garb #ifdef WITH_ICU_I18N -#include - /** * Search if a string is contained in another string using the current locale. * @@ -601,9 +602,6 @@ bool ConvertHexToBytes(std::string_view hex, std::span bytes) #elif defined(WITH_ICU_I18N) -#include -#include - /** String iterator using ICU as a backend. */ class IcuStringIterator : public StringIterator { diff --git a/src/video/allegro_v.cpp b/src/video/allegro_v.cpp index 424fafa2a973d..11f0d63e9b4e5 100644 --- a/src/video/allegro_v.cpp +++ b/src/video/allegro_v.cpp @@ -28,14 +28,14 @@ #include "allegro_v.h" #include -#include "../safeguards.h" - #ifdef _DEBUG /* Allegro replaces SEGV/ABRT signals meaning that the debugger will never * be triggered, so rereplace the signals and make the debugger useful. */ #include #endif +#include "../safeguards.h" + static FVideoDriver_Allegro iFVideoDriver_Allegro; static BITMAP *_allegro_screen; diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp index 728b2be9f922a..d8600faa655f2 100644 --- a/src/video/win32_v.cpp +++ b/src/video/win32_v.cpp @@ -32,6 +32,13 @@ #include #endif +#ifdef WITH_OPENGL +#include +#include "../3rdparty/opengl/glext.h" +#include "../3rdparty/opengl/wglext.h" +#include "opengl.h" +#endif /* WITH_OPENGL */ + #include "../safeguards.h" /* Missing define in MinGW headers. */ @@ -1285,11 +1292,6 @@ void VideoDriver_Win32GDI::Paint() #ifdef WITH_OPENGL -#include -#include "../3rdparty/opengl/glext.h" -#include "../3rdparty/opengl/wglext.h" -#include "opengl.h" - #ifndef PFD_SUPPORT_COMPOSITION # define PFD_SUPPORT_COMPOSITION 0x00008000 #endif From a949197264cb2b40ed65c47dc845f2dc4235b7e4 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Wed, 15 Oct 2025 23:16:00 +0100 Subject: [PATCH 067/137] Fix ef71ce0a9d: Crash when user enters a blank line in the console. (#14711) Crash caused by reading outside the bounds of string_view (though not the underlying buffer) --- src/console_gui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/console_gui.cpp b/src/console_gui.cpp index db8831f25923e..06db00510fc1c 100644 --- a/src/console_gui.cpp +++ b/src/console_gui.cpp @@ -453,7 +453,7 @@ void IConsoleClose() static std::optional IConsoleHistoryAdd(std::string_view cmd) { /* Strip all spaces at the begin */ - while (IsWhitespace(cmd[0])) cmd.remove_prefix(1); + while (!cmd.empty() && IsWhitespace(cmd[0])) cmd.remove_prefix(1); /* Do not put empty command in history */ if (cmd.empty()) return std::nullopt; From c627c64cc574f6afb9c08210e7c88282891079a4 Mon Sep 17 00:00:00 2001 From: translators Date: Thu, 16 Oct 2025 04:38:47 +0000 Subject: [PATCH 068/137] Update: Translations from eints swedish: 1 change by robert-i norwegian (bokmal): 4 changes by eriksorngard chinese (simplified): 4 changes by WenSimEHRP catalan: 1 change by J0anJosep danish: 4 changes by bscargo latvian: 8 changes by lexuslatvia dutch: 4 changes by Afoklala french: 5 changes by ottdfevr --- src/lang/catalan.txt | 1 + src/lang/danish.txt | 6 ++++-- src/lang/dutch.txt | 6 ++++-- src/lang/french.txt | 7 +++++-- src/lang/latvian.txt | 10 ++++++++-- src/lang/norwegian_bokmal.txt | 6 ++++-- src/lang/simplified_chinese.txt | 6 ++++-- src/lang/swedish.txt | 1 + 8 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index 9f29851a9c266..24174ac869fd5 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -3692,6 +3692,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Posa un STR_TOWN_DIRECTORY_CAPTION :{WHITE}Poblacions ({COMMA} de {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Cap - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA}) {YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Noms de les poblacions - feu clic al nom d'una població per a centrar-hi la vista principal. Amb Ctrl+clic, s'obre una vista nova centrada on hi ha la població. STR_TOWN_POPULATION :{BLACK}Població mundial: {COMMA} diff --git a/src/lang/danish.txt b/src/lang/danish.txt index dd755db6fa731..066774cc60d0d 100644 --- a/src/lang/danish.txt +++ b/src/lang/danish.txt @@ -3430,8 +3430,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Vand STR_MAPGEN_BORDER_RANDOM :{BLACK}Tilfældige ###length 3 -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Tilfældige -STR_MAPGEN_BORDER_MANUAL :{BLACK}Manuel +STR_MAPGEN_BORDER_RANDOMIZE :Tilfældig +STR_MAPGEN_BORDER_MANUAL :Manuel +STR_MAPGEN_BORDER_INFINITE_WATER :Uendeligt vand STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Højdekortets rotation: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Højdekortets navn: @@ -3690,6 +3691,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Indtast STR_TOWN_DIRECTORY_CAPTION :{WHITE}Byer ({COMMA} of {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Ingen - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA}) {YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Bynavne - klik på et navn for at centrere skærmen over byen. Ctrl+Klik åbner et nyt vindue ved byens lokalitet. STR_TOWN_POPULATION :{BLACK}Verdens befolkning: {COMMA} diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt index 884055d6d71dd..db922cb60287d 100644 --- a/src/lang/dutch.txt +++ b/src/lang/dutch.txt @@ -3430,8 +3430,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Water STR_MAPGEN_BORDER_RANDOM :{BLACK}Willekeurig ###length 3 -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Willekeurig -STR_MAPGEN_BORDER_MANUAL :{BLACK}Handmatig +STR_MAPGEN_BORDER_RANDOMIZE :Willekeurig +STR_MAPGEN_BORDER_MANUAL :Handmatig +STR_MAPGEN_BORDER_INFINITE_WATER :Onbeperkt water STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Rotatie van hoogtekaart: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Naam van hoogtekaart: @@ -3690,6 +3691,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Geef een STR_TOWN_DIRECTORY_CAPTION :{WHITE}Steden ({COMMA} van {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE} Geen STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA}) {YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Plaatsnamen - klik op naam om het scherm te centreren op de stad. Ctrl+klik opent een nieuw kijkvenster op de locatie van de stad STR_TOWN_POPULATION :{BLACK}Wereldbevolking: {COMMA} diff --git a/src/lang/french.txt b/src/lang/french.txt index a142fa87647b6..d9b622afd8aeb 100644 --- a/src/lang/french.txt +++ b/src/lang/french.txt @@ -3431,8 +3431,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Eau STR_MAPGEN_BORDER_RANDOM :{BLACK}Aléatoire ###length 3 -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Aléatoire -STR_MAPGEN_BORDER_MANUAL :{BLACK}Manuel +STR_MAPGEN_BORDER_RANDOMIZE :Aléatoire +STR_MAPGEN_BORDER_MANUAL :Manuel +STR_MAPGEN_BORDER_INFINITE_WATER :Eau à l'infini STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Rotation de la carte d'altitude{NBSP}: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Nom de la carte d'altitude{NBSP}: @@ -3691,6 +3692,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Entrer u STR_TOWN_DIRECTORY_CAPTION :{WHITE}Villes ({COMMA} de {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}− Aucune − STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA}) {YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Noms des villes - Cliquer sur un nom pour centrer la vue principale sur la ville. Ctrl-clic pour ouvrir une nouvelle vue sur la ville. STR_TOWN_POPULATION :{BLACK}Population mondiale{NBSP}: {COMMA} @@ -5270,6 +5272,7 @@ STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... pont STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Le pont finirait en dehors de la carte STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Le pont est trop bas pour les gares STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Le pont est trop bas pour les arrêts de bus +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Le pont est trop bas pour le port STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Le pont est trop bas pour les bouées STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Le pont est trop bas pour les points de contrôle STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Le pont est trop bas pour les points de contrôle de route diff --git a/src/lang/latvian.txt b/src/lang/latvian.txt index 2c84ecb6ea22c..95111c22df265 100644 --- a/src/lang/latvian.txt +++ b/src/lang/latvian.txt @@ -3353,6 +3353,8 @@ STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtrs: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Pārrakstīt datni STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Vai tiešām vēlaties pārrakstīt esošās datnes? +STR_SAVELOAD_DELETE_TITLE :{WHITE}Dzēst Failu +STR_SAVELOAD_DELETE_WARNING :{YELLOW}Vai tiešām vēlaties dzēst failu? STR_SAVELOAD_DIRECTORY :{STRING} (Vietne) STR_SAVELOAD_PARENT_DIRECTORY :{STRING} (Īpašnieka katalogs) @@ -3433,8 +3435,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Ūdens STR_MAPGEN_BORDER_RANDOM :{BLACK}Nejauša ###length 3 -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Nejaušas -STR_MAPGEN_BORDER_MANUAL :{BLACK}Manuāli +STR_MAPGEN_BORDER_RANDOMIZE :Nejaušas +STR_MAPGEN_BORDER_MANUAL :Manuāli +STR_MAPGEN_BORDER_INFINITE_WATER :Bezgalīgs Ūdens STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Augstumu kartes pagriešana: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Augstumu kartes nosaukums: @@ -3696,6 +3699,7 @@ STR_TOWN_DIRECTORY_CAPTION :{WHITE}Pilsēta STR_TOWN_DIRECTORY_NONE :{G=m}{ORANGE}- Neviens - STR_TOWN_DIRECTORY_NONE.kas :{ORANGE}- Neviena - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA}) {YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Pilsētu nosaukumi - klikšķināt uz nosaukuma, lai centrētu skatu uz to.Ctrl+klikšķis atvērs skatu uz pilsētu jaunā skatlaukā STR_TOWN_POPULATION :{BLACK}Pasaules iedzīvotāju skaits: {COMMA} @@ -4195,6 +4199,7 @@ STR_PURCHASE_INFO_ALL_BUT :visu, izņemot STR_PURCHASE_INFO_MAX_TE :{BLACK}Maksimālais vilces spēks: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Apgabas: {GOLD}{COMMA} lauciņi STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Lidaparāta veids: {GOLD}{STRING} +STR_PURCHASE_INFO_RAILTYPES :{BLACK}Sliežu veidi: {GOLD}{STRING} ###length 3 STR_CARGO_TYPE_FILTER_ALL :Visi kravu veidi @@ -4378,6 +4383,7 @@ STR_ENGINE_PREVIEW_RUNCOST_YEAR :Darbības izmak STR_ENGINE_PREVIEW_RUNCOST_PERIOD :Darbības izmaksas: {CURRENCY_LONG}/periodā STR_ENGINE_PREVIEW_CAPACITY :Ietilpība: {CARGO_LONG} STR_ENGINE_PREVIEW_CAPACITY_2 :Ietilpība: {CARGO_LONG}, {CARGO_LONG} +STR_ENGINE_PREVIEW_RAILTYPES :Sliežu veidi: {STRING} # Autoreplace window STR_REPLACE_VEHICLES_WHITE :{WHITE}Nomainīt {STRING} - {STRING} diff --git a/src/lang/norwegian_bokmal.txt b/src/lang/norwegian_bokmal.txt index 3a7c14dafcc86..a674b766cb607 100644 --- a/src/lang/norwegian_bokmal.txt +++ b/src/lang/norwegian_bokmal.txt @@ -3432,8 +3432,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Sjø STR_MAPGEN_BORDER_RANDOM :{BLACK}Tilfeldig ###length 3 -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Tilfeldige -STR_MAPGEN_BORDER_MANUAL :{BLACK}Manuelle +STR_MAPGEN_BORDER_RANDOMIZE :Tilfeldige +STR_MAPGEN_BORDER_MANUAL :Manuelle +STR_MAPGEN_BORDER_INFINITE_WATER :Uendelig vann STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Høydekartrotering: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Høydekartnavn: @@ -3692,6 +3693,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Skriv in STR_TOWN_DIRECTORY_CAPTION :{WHITE}Byer ({COMMA} av {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Ingen - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA}) {YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Bynavn - klikk på navnet for å gå til byen. Ctrl+klikk for å åpne et nytt tilleggsvindu over byen STR_TOWN_POPULATION :{BLACK}Verdensbefolkning: {COMMA} diff --git a/src/lang/simplified_chinese.txt b/src/lang/simplified_chinese.txt index 89e700d3b58e7..067950f22aa20 100644 --- a/src/lang/simplified_chinese.txt +++ b/src/lang/simplified_chinese.txt @@ -3430,8 +3430,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}水面 STR_MAPGEN_BORDER_RANDOM :{BLACK}随机 ###length 3 -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}随机 -STR_MAPGEN_BORDER_MANUAL :{BLACK}手动 +STR_MAPGEN_BORDER_RANDOMIZE :随机 +STR_MAPGEN_BORDER_MANUAL :手动 +STR_MAPGEN_BORDER_INFINITE_WATER :无尽水域 STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}高度图旋转: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}高度图名称: @@ -3690,6 +3691,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}为标 STR_TOWN_DIRECTORY_CAPTION :{WHITE}城镇({COMMA} 座,共 {COMMA}座) STR_TOWN_DIRECTORY_NONE :{ORANGE}- 无 - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK}({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK}({COMMA}){YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK} 城镇名称 - 点击名称可以将屏幕中心{}移动到城镇所在的位置。按住 点选将会在新视点中显示城镇位置 STR_TOWN_POPULATION :{BLACK}地图人口总数:{COMMA} diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt index 6544a8248bb1b..a0f29b1edfb94 100644 --- a/src/lang/swedish.txt +++ b/src/lang/swedish.txt @@ -3691,6 +3691,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Mata in STR_TOWN_DIRECTORY_CAPTION :{WHITE}Städer ({COMMA} av {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Inga - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA}) {YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Stadsnamn - klicka på ett namn för att centrera huvudvyn på staden. Ctrl+Klick för att öppna en ny fönstervy över stadens läge STR_TOWN_POPULATION :{BLACK}Global folkmängd: {COMMA} From bf3a07c5d211cea3eb32967e40be65307274b46d Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 19 Oct 2025 11:45:13 +0100 Subject: [PATCH 069/137] Codechange: Silence uninitialized variable warning from GCC. (#14715) `is_custom_layout` is not used uninitialized but GCC does not know that and produces a warning. --- src/tunnelbridge_cmd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 7ffe3332497af..00138c1957675 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -1445,7 +1445,7 @@ static void DrawTile_TunnelBridge(TileInfo *ti) DrawBridgeMiddle(ti, BridgePillarFlag::EdgeNE + tunnelbridge_direction); } else { // IsBridge(ti->tile) DrawFoundation(ti, GetBridgeFoundation(ti->tileh, DiagDirToAxis(tunnelbridge_direction))); - bool is_custom_layout; // Set if rail/road bridge uses a custom layout. + bool is_custom_layout = false; // Set if rail/road bridge uses a custom layout. uint base_offset = GetBridgeRampDirectionBaseOffset(tunnelbridge_direction); std::span psid; From 75ca1e3cda8c6cc38f85558e1cae7cbc351d0fd5 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 3 Oct 2025 17:35:47 +0100 Subject: [PATCH 070/137] Fix a46a3a97f3: Incorrect parameter order for CmdSetCompanyManagerFace. Style and bits were mixed up. Switch everything to style first, as the most significant parameter. --- src/company_cmd.cpp | 6 +++--- src/company_gui.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index e9fc5f94ff882..ef62b91538c29 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -925,7 +925,7 @@ CommandCost CmdCompanyCtrl(DoCommandFlags flags, CompanyCtrlAction cca, CompanyI if (!_company_manager_face.empty()) { auto cmf = ParseCompanyManagerFaceCode(_company_manager_face); if (cmf.has_value()) { - Command::SendNet(STR_NULL, c->index, cmf->bits, cmf->style); + Command::SendNet(STR_NULL, c->index, cmf->style, cmf->bits); } } @@ -1050,11 +1050,11 @@ CommandCost CmdCompanyAllowListCtrl(DoCommandFlags flags, CompanyAllowListCtrlAc /** * Change the company manager's face. * @param flags operation to perform - * @param bits The bits of company manager face. * @param style The style of the company manager face. + * @param bits The bits of company manager face. * @return the cost of this operation or an error */ -CommandCost CmdSetCompanyManagerFace(DoCommandFlags flags, uint32_t bits, uint style) +CommandCost CmdSetCompanyManagerFace(DoCommandFlags flags, uint style, uint32_t bits) { CompanyManagerFace tmp_face{style, bits, {}}; if (!IsValidCompanyManagerFace(tmp_face)) return CMD_ERROR; diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 66dc383cbb207..bf336ed35a369 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -1384,7 +1384,7 @@ class SelectCompanyManagerFaceWindow : public Window /* OK button */ case WID_SCMF_ACCEPT: - Command::Post(this->face.bits, this->face.style); + Command::Post(this->face.style, this->face.bits); [[fallthrough]]; /* Cancel button */ From 9f7f314f8152e4a67202ad0a8d02d5a5ea8b2908 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 3 Oct 2025 17:36:57 +0100 Subject: [PATCH 071/137] Codechange: [Script] Add regression test for company president gender. --- regression/regression/main.nut | 16 ++++++++++++++++ regression/regression/result.txt | 11 ++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/regression/regression/main.nut b/regression/regression/main.nut index b9df4ebb4a51b..d029cea9968d0 100644 --- a/regression/regression/main.nut +++ b/regression/regression/main.nut @@ -461,6 +461,21 @@ function Regression::Company() } } +function Regression::CompanyGender() +{ + print(""); + print("--Company Gender--"); + /* Check gender switching behaviour matches API. */ + print(" GetPresidentGender(): " + AICompany.GetPresidentGender(AICompany.COMPANY_SELF)); + print(" SetPresidentGender(): " + AICompany.SetPresidentGender(AICompany.GENDER_MALE)); + print(" GetPresidentGender(): " + AICompany.GetPresidentGender(AICompany.COMPANY_SELF)); + print(" SetPresidentGender(): " + AICompany.SetPresidentGender(AICompany.GENDER_FEMALE)); + print(" GetPresidentGender(): " + AICompany.GetPresidentGender(AICompany.COMPANY_SELF)); + /* Setting to existing gender should fail. */ + print(" SetPresidentGender(): " + AICompany.SetPresidentGender(AICompany.GENDER_FEMALE)); + print(" GetPresidentGender(): " + AICompany.GetPresidentGender(AICompany.COMPANY_SELF)); +} + function Regression::Engine() { local j = 0; @@ -2096,6 +2111,7 @@ function Regression::Start() this.Vehicle(); /* Order has to be after Vehicle */ this.Order(); + this.CompanyGender(); print(""); print(" First Subsidy Test"); PrintSubsidy(0); diff --git a/regression/regression/result.txt b/regression/regression/result.txt index 6a88a5297da70..ec60ce3651709 100644 --- a/regression/regression/result.txt +++ b/regression/regression/result.txt @@ -10006,6 +10006,15 @@ ERROR: IsEnd() is invalid as Begin() is never called foreach(): 20 => 23596 +--Company Gender-- + GetPresidentGender(): 1 + SetPresidentGender(): true + GetPresidentGender(): 0 + SetPresidentGender(): true + GetPresidentGender(): 1 + SetPresidentGender(): false + GetPresidentGender(): 1 + First Subsidy Test --Subsidy (0) -- IsValidSubsidy(): true @@ -10107,7 +10116,7 @@ ERROR: IsEnd() is invalid as Begin() is never called constructor failed with: excessive CPU usage in list filter function Your script made an error: excessive CPU usage in valuator function -*FUNCTION [Start()] regression/main.nut line [2168] +*FUNCTION [Start()] regression/main.nut line [2184] [Infinite] CLOSURE [list] INSTANCE From 2396353c160e39ad1903eea8ecd073f563a889b3 Mon Sep 17 00:00:00 2001 From: SamuXarick <43006711+SamuXarick@users.noreply.github.com> Date: Wed, 22 Oct 2025 13:42:17 +0100 Subject: [PATCH 072/137] Codechange: Optimize FlowRiver (#13264) --- src/core/strong_typedef_type.hpp | 27 ++++++++++++++++++ src/landscape.cpp | 47 ++++++++++++++++---------------- 2 files changed, 50 insertions(+), 24 deletions(-) diff --git a/src/core/strong_typedef_type.hpp b/src/core/strong_typedef_type.hpp index a89ec0460f08d..e818228d5057c 100644 --- a/src/core/strong_typedef_type.hpp +++ b/src/core/strong_typedef_type.hpp @@ -158,4 +158,31 @@ namespace StrongType { }; } +/** + * Implementation of std::hash for StrongType::Typedef. + * + * This specialization of std::hash allows hashing of StrongType::Typedef instances + * by leveraging the hash of the base type. + * + * Example Usage: + * using MyType = StrongType::Typedef; + * std::unordered_map my_map; + * + * @tparam TBaseType The underlying type of the StrongType::Typedef. + * @tparam TProperties Additional properties for the StrongType::Typedef. + */ +template +struct std::hash> { + /** + * Computes the hash value for a StrongType::Typedef instance. + * + * @param t The StrongType::Typedef instance to hash. + * @return The hash value of the base type of t. + */ + std::size_t operator()(const StrongType::Typedef &t) const noexcept + { + return std::hash()(t.base()); + } +}; + #endif /* STRONG_TYPEDEF_TYPE_HPP */ diff --git a/src/landscape.cpp b/src/landscape.cpp index 621de24c0154b..983c3e4f561d3 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -27,7 +27,6 @@ #include "effectvehicle_func.h" #include "landscape_type.h" #include "animated_tile_func.h" -#include "core/flatset_type.hpp" #include "core/random_func.hpp" #include "object_base.h" #include "company_func.h" @@ -43,6 +42,8 @@ #include "table/strings.h" #include "table/sprites.h" +#include + #include "safeguards.h" extern const TileTypeProcs @@ -1240,28 +1241,29 @@ bool RiverFlowsDown(TileIndex begin, TileIndex end) */ static std::tuple FlowRiver(TileIndex spring, TileIndex begin, uint min_river_length) { - uint height_begin = TileHeight(begin); - if (IsWaterTile(begin)) { return { DistanceManhattan(spring, begin) > min_river_length, GetTileZ(begin) == 0 }; } - FlatSet marks; + int height_begin = TileHeight(begin); + + std::unordered_set marks; marks.insert(begin); - /* Breadth first search for the closest tile we can flow down to. */ - std::list queue; + std::vector queue; queue.push_back(begin); + /* Breadth first search for the closest tile we can flow down to. + * We keep the queue to find the Nth tile for lake guessing. The tiles + * in the queue are neatly ordered by insertion. + */ bool found = false; - uint count = 0; // Number of tiles considered; to be used for lake location guessing. TileIndex end; - do { - end = queue.front(); - queue.pop_front(); + for (size_t i = 0; i != queue.size(); i++) { + end = queue[i]; - uint height_end = TileHeight(end); - if (IsTileFlat(end) && (height_end < height_begin || (height_end == height_begin && IsWaterTile(end)))) { + int height_end; + if (IsTileFlat(end, &height_end) && (height_end < height_begin || (height_end == height_begin && IsWaterTile(end)))) { found = true; break; } @@ -1270,31 +1272,29 @@ static std::tuple FlowRiver(TileIndex spring, TileIndex begin, uint TileIndex t = end + TileOffsByDiagDir(d); if (IsValidTile(t) && !marks.contains(t) && RiverFlowsDown(end, t)) { marks.insert(t); - count++; queue.push_back(t); } } - } while (!queue.empty()); + } bool main_river = false; if (found) { /* Flow further down hill. */ std::tie(found, main_river) = FlowRiver(spring, end, min_river_length); - } else if (count > 32) { + } else if (queue.size() > 32) { /* Maybe we can make a lake. Find the Nth of the considered tiles. */ - auto cit = marks.cbegin(); - std::advance(cit, RandomRange(count - 1)); - TileIndex lake_centre = *cit; + TileIndex lake_centre = queue[RandomRange(static_cast(queue.size()))]; + int height_lake; if (IsValidTile(lake_centre) && - /* A river, or lake, can only be built on flat slopes. */ - IsTileFlat(lake_centre) && - /* We want the lake to be built at the height of the river. */ - TileHeight(begin) == TileHeight(lake_centre) && /* We don't want the lake at the entry of the valley. */ lake_centre != begin && /* We don't want lakes in the desert. */ (_settings_game.game_creation.landscape != LandscapeType::Tropic || GetTropicZone(lake_centre) != TROPICZONE_DESERT) && + /* A river, or lake, can only be built on flat slopes. */ + IsTileFlat(lake_centre, &height_lake) && + /* We want the lake to be built at the height of the river. */ + height_lake == height_begin && /* We only want a lake if the river is long enough. */ DistanceManhattan(spring, lake_centre) > min_river_length) { end = lake_centre; @@ -1304,7 +1304,7 @@ static std::tuple FlowRiver(TileIndex spring, TileIndex begin, uint /* Run the loop twice, so artefacts from going circular in one direction get (mostly) hidden. */ for (uint loops = 0; loops < 2; ++loops) { for (auto tile : SpiralTileSequence(lake_centre, diameter)) { - MakeLake(tile, height_begin); + MakeLake(tile, height_lake); } } @@ -1312,7 +1312,6 @@ static std::tuple FlowRiver(TileIndex spring, TileIndex begin, uint } } - marks.clear(); if (found) YapfBuildRiver(begin, end, spring, main_river); return { found, main_river }; } From 8e8eebd7858c320b10c8aef9f5e335e19c5344d3 Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Thu, 23 Oct 2025 08:24:58 -0400 Subject: [PATCH 073/137] Doc: Define policy on AI usage in OpenTTD development (#14537) --- CONTRIBUTING.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 668d73d70091f..fe1687dacac98 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -196,6 +196,29 @@ These include: You may also want the guide to [compiling OpenTTD](./COMPILING.md). +## Use of AI + +OpenTTD is a labour of love, created by people. + +Please refrain from submitting issues or pull requests that have been generated by an LLM or other fully-automated tools. +Any submission that is in violation of this policy will be closed, and the submitter may be blocked from this repository without warning. + +If you submit an issue, you need to understand what your issue description is saying. +You need to be able to answer questions about your bug report or feature request. +Using an AI tool to _proofread_ your issue/comment text is acceptable. Using an AI tool to _write_ your issue/comment text is not. + +If you submit a pull request, you need to understand what every line of code you've changed does. +If you can't explain why your PR is doing something, then do not submit it. +Using an AI tool to generate entire lines of code is unacceptable. + +The rationale behind this policy is that automated contributions are a waste of the maintainers' time. +Humans spend their time and brainpower reviewing every submission. +Issues or pull requests generated by automation tools create an imbalance of effort between the submitter and the reviewer. +Nobody learns anything when a maintainer reviews code written by an LLM. + +Additionally, AI-generated code conflicts with this project's license (GPL v2), since you cannot truly release code for use if you didn't author it yourself. + + ## Project goals ### What are the goals of the official branch? From 5c89dff677d9fa180626136a12caa8a354a18a94 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Thu, 23 Oct 2025 20:59:58 +0100 Subject: [PATCH 074/137] Codechange: Iterate road/tram masks instead of checking each type. (#14716) --- src/company_base.h | 6 ++++-- src/company_cmd.cpp | 20 ++++---------------- src/road.h | 14 -------------- src/road_type.h | 16 ++++++++++++++++ src/town_cmd.cpp | 12 +++--------- 5 files changed, 27 insertions(+), 41 deletions(-) diff --git a/src/company_base.h b/src/company_base.h index cdaca96dc4a4c..a1409c84edd81 100644 --- a/src/company_base.h +++ b/src/company_base.h @@ -45,8 +45,10 @@ struct CompanyInfrastructure { return std::accumulate(std::begin(this->rail), std::end(this->rail), 0U); } - uint32_t GetRoadTotal() const; - uint32_t GetTramTotal() const; + uint32_t GetRoadTramTotal(RoadTramType rtt) const; + + inline uint32_t GetRoadTotal() const { return GetRoadTramTotal(RTT_ROAD); } + inline uint32_t GetTramTotal() const { return GetRoadTramTotal(RTT_TRAM); } }; class FreeUnitIDGenerator { diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index ef62b91538c29..577f54b4b481f 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -1291,26 +1291,14 @@ int CompanyServiceInterval(const Company *c, VehicleType type) /** * Get total sum of all owned road bits. + * @param rtt RoadTramType to get total for. * @return Combined total road road bits. */ -uint32_t CompanyInfrastructure::GetRoadTotal() const +uint32_t CompanyInfrastructure::GetRoadTramTotal(RoadTramType rtt) const { uint32_t total = 0; - for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { - if (RoadTypeIsRoad(rt)) total += this->road[rt]; - } - return total; -} - -/** - * Get total sum of all owned tram bits. - * @return Combined total of tram road bits. - */ -uint32_t CompanyInfrastructure::GetTramTotal() const -{ - uint32_t total = 0; - for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { - if (RoadTypeIsTram(rt)) total += this->road[rt]; + for (RoadType rt : GetMaskForRoadTramType(rtt)) { + total += this->road[rt]; } return total; } diff --git a/src/road.h b/src/road.h index b67df0e70aa55..4918d7cc80c07 100644 --- a/src/road.h +++ b/src/road.h @@ -21,20 +21,6 @@ #include "newgrf_badge_type.h" #include "economy_func.h" - -enum RoadTramType : bool { - RTT_ROAD, - RTT_TRAM, -}; - -enum RoadTramTypes : uint8_t { - RTTB_ROAD = 1 << RTT_ROAD, - RTTB_TRAM = 1 << RTT_TRAM, -}; -DECLARE_ENUM_AS_BIT_SET(RoadTramTypes) - -static const RoadTramType _roadtramtypes[] = { RTT_ROAD, RTT_TRAM }; - /** Roadtype flag bit numbers. */ enum class RoadTypeFlag : uint8_t { Catenary = 0, ///< Bit number for adding catenary diff --git a/src/road_type.h b/src/road_type.h index 07a6deb69ec78..99b5f8a40bdbd 100644 --- a/src/road_type.h +++ b/src/road_type.h @@ -31,6 +31,22 @@ DECLARE_INCREMENT_DECREMENT_OPERATORS(RoadType) using RoadTypes = EnumBitSet; +/** + * The different types of road type. + */ +enum RoadTramType : bool { + RTT_ROAD, ///< Road road type. + RTT_TRAM, ///< Tram road type. +}; + +enum RoadTramTypes : uint8_t { + RTTB_ROAD = 1 << RTT_ROAD, ///< Road road type bit. + RTTB_TRAM = 1 << RTT_TRAM, ///< Tram road type bit. +}; +DECLARE_ENUM_AS_BIT_SET(RoadTramTypes) + +static const RoadTramType _roadtramtypes[] = { RTT_ROAD, RTT_TRAM }; + /** * Enumeration for the road parts on a tile. * diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index dea412c6982d2..b3c95ba053047 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -965,14 +965,9 @@ RoadType GetTownRoadType() const RoadTypeInfo *best = nullptr; const uint16_t assume_max_speed = 50; - for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { - if (RoadTypeIsTram(rt)) continue; - + for (RoadType rt : GetMaskForRoadTramType(RTT_ROAD)) { const RoadTypeInfo *rti = GetRoadTypeInfo(rt); - /* Unused road type. */ - if (rti->label == 0) continue; - /* Can town build this road. */ if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue; @@ -997,10 +992,9 @@ RoadType GetTownRoadType() static TimerGameCalendar::Date GetTownRoadTypeFirstIntroductionDate() { const RoadTypeInfo *best = nullptr; - for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { - if (RoadTypeIsTram(rt)) continue; + for (RoadType rt : GetMaskForRoadTramType(RTT_ROAD)) { const RoadTypeInfo *rti = GetRoadTypeInfo(rt); - if (rti->label == 0) continue; // Unused road type. + if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue; // Town can't build this road type. if (best != nullptr && rti->introduction_date >= best->introduction_date) continue; From fd32d1447e2e10b44c4fdfc695e943d2e0dd8aab Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 11 Oct 2025 17:00:40 +0100 Subject: [PATCH 075/137] Codechange: Remove StationIDStack and SmallStack. Use a std::vector or std::span instead. --- src/aircraft_cmd.cpp | 3 +- src/cargopacket.cpp | 26 ++-- src/cargopacket.h | 16 +- src/core/CMakeLists.txt | 1 - src/core/smallstack_type.hpp | 266 --------------------------------- src/economy.cpp | 20 +-- src/linkgraph/linkgraphjob.cpp | 4 +- src/order_base.h | 2 +- src/order_cmd.cpp | 14 +- src/station_base.h | 2 +- src/station_cmd.cpp | 6 +- src/station_type.h | 3 - src/vehicle_base.h | 4 +- 13 files changed, 49 insertions(+), 318 deletions(-) delete mode 100644 src/core/smallstack_type.hpp diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index f3cd7f09b735b..dce6e04f57ccb 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -135,7 +135,8 @@ static StationID FindNearestHangar(const Aircraft *v) next_dest = Station::GetIfValid(v->current_order.GetDestination().ToStationID()); } else { last_dest = GetTargetAirportIfValid(v); - next_dest = Station::GetIfValid(v->GetNextStoppingStation().value); + std::vector next_station = v->GetNextStoppingStation(); + if (!next_station.empty()) next_dest = Station::GetIfValid(next_station.back()); } } diff --git a/src/cargopacket.cpp b/src/cargopacket.cpp index 38d94894900ea..f8c736c3a8fc1 100644 --- a/src/cargopacket.cpp +++ b/src/cargopacket.cpp @@ -404,13 +404,13 @@ void VehicleCargoList::AgeCargo() * @return MoveToAction to be performed. */ /* static */ VehicleCargoList::MoveToAction VehicleCargoList::ChooseAction(const CargoPacket *cp, StationID cargo_next, - StationID current_station, bool accepted, StationIDStack next_station) + StationID current_station, bool accepted, std::span next_station) { if (cargo_next == StationID::Invalid()) { return (accepted && cp->first_station != current_station) ? MTA_DELIVER : MTA_KEEP; } else if (cargo_next == current_station) { return MTA_DELIVER; - } else if (next_station.Contains(cargo_next)) { + } else if (std::ranges::find(next_station, cargo_next) != std::end(next_station)) { return MTA_KEEP; } else { return MTA_TRANSFER; @@ -432,7 +432,7 @@ void VehicleCargoList::AgeCargo() * @param current_tile Current tile the cargo handling is happening on. * return If any cargo will be unloaded. */ -bool VehicleCargoList::Stage(bool accepted, StationID current_station, StationIDStack next_station, uint8_t order_flags, const GoodsEntry *ge, CargoType cargo, CargoPayment *payment, TileIndex current_tile) +bool VehicleCargoList::Stage(bool accepted, StationID current_station, std::span next_station, uint8_t order_flags, const GoodsEntry *ge, CargoType cargo, CargoPayment *payment, TileIndex current_tile) { this->AssertCountConsistency(); assert(this->action_counts[MTA_LOAD] == 0); @@ -468,9 +468,9 @@ bool VehicleCargoList::Stage(bool accepted, StationID current_station, StationID } else { FlowStat new_shares = flow_it->second; new_shares.ChangeShare(current_station, INT_MIN); - StationIDStack excluded = next_station; - while (!excluded.IsEmpty() && !new_shares.GetShares()->empty()) { - new_shares.ChangeShare(excluded.Pop(), INT_MIN); + for (auto station_it = next_station.rbegin(); station_it != next_station.rend(); ++station_it) { + if (!new_shares.GetShares()->empty()) break; + new_shares.ChangeShare(*station_it, INT_MIN); } if (new_shares.GetShares()->empty()) { cargo_next = StationID::Invalid(); @@ -739,11 +739,11 @@ bool StationCargoList::ShiftCargo(Taction &action, StationID next) * @return Amount of cargo actually moved. */ template -uint StationCargoList::ShiftCargo(Taction action, StationIDStack next, bool include_invalid) +uint StationCargoList::ShiftCargo(Taction action, std::span next, bool include_invalid) { uint max_move = action.MaxMove(); - while (!next.IsEmpty()) { - this->ShiftCargo(action, next.Pop()); + for (auto it = next.rbegin(); it != next.rend(); ++it) { + this->ShiftCargo(action, *it); if (action.MaxMove() == 0) break; } if (include_invalid && action.MaxMove() > 0) { @@ -814,7 +814,7 @@ uint StationCargoList::Truncate(uint max_move, StationCargoAmountMap *cargo_per_ * @param current_tile Current tile the cargo handling is happening on. * @return Amount of cargo actually reserved. */ -uint StationCargoList::Reserve(uint max_move, VehicleCargoList *dest, StationIDStack next_station, TileIndex current_tile) +uint StationCargoList::Reserve(uint max_move, VehicleCargoList *dest, std::span next_station, TileIndex current_tile) { return this->ShiftCargo(CargoReservation(this, dest, max_move, current_tile), next_station, true); } @@ -831,7 +831,7 @@ uint StationCargoList::Reserve(uint max_move, VehicleCargoList *dest, StationIDS * modes of loading are exclusive, though. If cargo is reserved we don't * need to load unreserved cargo. */ -uint StationCargoList::Load(uint max_move, VehicleCargoList *dest, StationIDStack next_station, TileIndex current_tile) +uint StationCargoList::Load(uint max_move, VehicleCargoList *dest, std::span next_station, TileIndex current_tile) { uint move = std::min(dest->ActionCount(VehicleCargoList::MTA_LOAD), max_move); if (move > 0) { @@ -839,7 +839,7 @@ uint StationCargoList::Load(uint max_move, VehicleCargoList *dest, StationIDStac dest->Reassign(move); return move; } else { - return this->ShiftCargo(CargoLoad(this, dest, max_move, current_tile), next_station, true); + return this->ShiftCargo(CargoLoad{this, dest, max_move, current_tile}, next_station, true); } } @@ -853,7 +853,7 @@ uint StationCargoList::Load(uint max_move, VehicleCargoList *dest, StationIDStac */ uint StationCargoList::Reroute(uint max_move, StationCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge) { - return this->ShiftCargo(StationCargoReroute(this, dest, max_move, avoid, avoid2, ge), avoid, false); + return this->ShiftCargo(StationCargoReroute(this, dest, max_move, avoid, avoid2, ge), {&avoid, 1}, false); } /* diff --git a/src/cargopacket.h b/src/cargopacket.h index 8b4c7b6d40148..35cfd2cce466c 100644 --- a/src/cargopacket.h +++ b/src/cargopacket.h @@ -371,7 +371,7 @@ class VehicleCargoList : public CargoList { void RemoveFromMeta(const CargoPacket *cp, MoveToAction action, uint count); static MoveToAction ChooseAction(const CargoPacket *cp, StationID cargo_next, - StationID current_station, bool accepted, StationIDStack next_station); + StationID current_station, bool accepted, std::span next_station); public: /** The station cargo list needs to control the unloading. */ @@ -469,7 +469,7 @@ class VehicleCargoList : public CargoList { void InvalidateCache(); - bool Stage(bool accepted, StationID current_station, StationIDStack next_station, uint8_t order_flags, const GoodsEntry *ge, CargoType cargo, CargoPayment *payment, TileIndex current_tile); + bool Stage(bool accepted, StationID current_station, std::span next_station, uint8_t order_flags, const GoodsEntry *ge, CargoType cargo, CargoPayment *payment, TileIndex current_tile); /** * Marks all cargo in the vehicle as to be kept. This is mostly useful for @@ -543,7 +543,7 @@ class StationCargoList : public CargoList - uint ShiftCargo(Taction action, StationIDStack next, bool include_invalid); + uint ShiftCargo(Taction action, std::span next, bool include_invalid); void Append(CargoPacket *cp, StationID next); @@ -552,10 +552,10 @@ class StationCargoList : public CargoList next) const { - while (!next.IsEmpty()) { - if (this->packets.find(next.Pop()) != this->packets.end()) return true; + for (const StationID &station : next) { + if (this->packets.find(station) != this->packets.end()) return true; } /* Packets for StationID::Invalid() can go anywhere. */ return this->packets.find(StationID::Invalid()) != this->packets.end(); @@ -603,8 +603,8 @@ class StationCargoList : public CargoList next, TileIndex current_tile); + uint Load(uint max_move, VehicleCargoList *dest, std::span next, TileIndex current_tile); uint Truncate(uint max_move = UINT_MAX, StationCargoAmountMap *cargo_per_source = nullptr); uint Reroute(uint max_move, StationCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge); diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 224cfba0eba13..fa76393137a7d 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -22,7 +22,6 @@ add_files( pool_type.hpp random_func.cpp random_func.hpp - smallstack_type.hpp string_builder.cpp string_builder.hpp string_consumer.cpp diff --git a/src/core/smallstack_type.hpp b/src/core/smallstack_type.hpp deleted file mode 100644 index 3b26951453bbf..0000000000000 --- a/src/core/smallstack_type.hpp +++ /dev/null @@ -1,266 +0,0 @@ -/* - * This file is part of OpenTTD. - * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. - * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . - */ - -/** @file smallstack_type.hpp Minimal stack that uses a pool to avoid pointers and doesn't allocate any heap memory if there is only one valid item. */ - -#ifndef SMALLSTACK_TYPE_HPP -#define SMALLSTACK_TYPE_HPP - -/** - * A simplified pool which stores values instead of pointers and doesn't - * redefine operator new/delete. It also never zeroes memory and always reuses - * it. - */ -template -class SimplePool { -public: - inline SimplePool() : first_unused(0), first_free(0) {} - - /** - * Get the item at position index. - * @return Item at index. - */ - inline Titem &Get(Tindex index) { return this->data[index]; } - - /** - * Create a new item and return its index. - * @return Index of new item. - */ - inline Tindex Create() - { - Tindex index = this->FindFirstFree(); - if (index < Tmax_size) { - this->data[index].valid = true; - this->first_free = index + 1; - this->first_unused = std::max(this->first_unused, this->first_free); - } - return index; - } - - /** - * Destroy (or rather invalidate) the item at the given index. - * @param index Index of item to be destroyed. - */ - inline void Destroy(Tindex index) - { - this->data[index].valid = false; - this->first_free = std::min(this->first_free, index); - } - -private: - - inline Tindex FindFirstFree() - { - Tindex index = this->first_free; - for (; index < this->first_unused; index++) { - if (!this->data[index].valid) return index; - } - - if (index >= this->data.size() && index < Tmax_size) { - this->data.resize(index + 1); - } - return index; - } - - struct SimplePoolPoolItem : public Titem { - bool valid; - }; - - Tindex first_unused; - Tindex first_free; - - std::vector data; -}; - -/** - * Base class for SmallStack. We cannot add this into SmallStack itself as - * certain compilers don't like it. - */ -template -struct SmallStackItem { - Tindex next; ///< Pool index of next item. - Titem value; ///< Value of current item. - - /** - * Create a new item. - * @param value Value of the item. - * @param next Next item in the stack. - */ - inline SmallStackItem(const Titem &value, Tindex next) : - next(next), value(value) {} - SmallStackItem() = default; -}; - -/** - * Minimal stack that uses a pool to avoid pointers. It has some peculiar - * properties that make it useful for passing around lists of IDs but not much - * else: - * 1. It always includes an invalid item as bottom. - * 2. It doesn't have a deep copy operation but uses smart pointers instead. - * Every copy is thus implicitly shared. - * 3. Its items are immutable. - * 4. Due to 2. and 3. memory management can be done by "branch counting". - * Whenever you copy a smallstack, the first item on the heap increases its - * branch_count, signifying that there are multiple items "in front" of it. - * When deleting a stack items are deleted up to the point where - * branch_count > 0. - * 5. You can choose your own index type, so that you can align it with your - * value type. E.G. value types of 16 bits length like to be combined with - * index types of the same length. - * @tparam Titem Value type to be used. - * @tparam Tindex Index type to use for the pool. - * @tparam Tinvalid_value Value to construct invalid item to keep at the bottom of each stack. - * @tparam Tgrowth_step Growth step for pool. - * @tparam Tmax_size Maximum size for pool. - */ -template -class SmallStack : public SmallStackItem { -public: - static constexpr Titem Tinvalid{Tinvalid_value}; - - typedef SmallStackItem Item; - - /** - * SmallStack item that can be kept in a pool. - */ - struct PooledSmallStack : public Item { - Tindex branch_count; ///< Number of branches in the tree structure this item is parent of - }; - - typedef SimplePool SmallStackPool; - - /** - * Constructor for a stack with one or two items in it. - * @param value Initial item. If not missing or Tinvalid there will be Tinvalid below it. - */ - inline SmallStack(const Titem &value = Tinvalid) : Item(value, Tmax_size) {} - - /** - * Remove the head of stack and all other items members that are unique to it. - */ - inline ~SmallStack() - { - while (this->next != Tmax_size) this->Pop(); - } - - /** - * Shallow copy the stack, marking the first item as branched. - * @param other Stack to copy from - */ - inline SmallStack(const SmallStack &other) : Item(other) { this->Branch(); } - - /** - * Shallow copy the stack, marking the first item as branched. - * @param other Stack to copy from - * @return This smallstack. - */ - inline SmallStack &operator=(const SmallStack &other) - { - if (this == &other) return *this; - while (this->next != Tmax_size) this->Pop(); - this->next = other.next; - this->value = other.value; - /* Deleting and branching are independent operations, so it's fine to - * acquire separate locks for them. */ - this->Branch(); - return *this; - } - - /** - * Pushes a new item onto the stack if there is still space in the - * underlying pool. Otherwise the topmost item's value gets overwritten. - * @param item Item to be pushed. - */ - inline void Push(const Titem &item) - { - if (this->value != Tinvalid) { - Tindex new_item = SmallStack::GetPool().Create(); - if (new_item != Tmax_size) { - PooledSmallStack &pushed = SmallStack::GetPool().Get(new_item); - pushed.value = this->value; - pushed.next = this->next; - pushed.branch_count = 0; - this->next = new_item; - } - } - this->value = item; - } - - /** - * Pop an item from the stack. - * @return Current top of stack. - */ - inline Titem Pop() - { - Titem ret = this->value; - if (this->next == Tmax_size) { - this->value = Tinvalid; - } else { - PooledSmallStack &popped = SmallStack::GetPool().Get(this->next); - this->value = popped.value; - if (popped.branch_count == 0) { - SmallStack::GetPool().Destroy(this->next); - } else { - --popped.branch_count; - if (popped.next != Tmax_size) { - ++(SmallStack::GetPool().Get(popped.next).branch_count); - } - } - /* Accessing popped here is no problem as the pool will only set - * the validity flag, not actually delete the item, on Destroy(). */ - this->next = popped.next; - } - return ret; - } - - /** - * Check if the stack is empty. - * @return If the stack is empty. - */ - inline bool IsEmpty() const - { - return this->value == Tinvalid && this->next == Tmax_size; - } - - /** - * Check if the given item is contained in the stack. - * @param item Item to look for. - * @return If the item is in the stack. - */ - inline bool Contains(const Titem &item) const - { - if (item == Tinvalid || item == this->value) return true; - if (this->next != Tmax_size) { - const SmallStack *in_list = this; - do { - in_list = static_cast( - static_cast(&SmallStack::GetPool().Get(in_list->next))); - if (in_list->value == item) return true; - } while (in_list->next != Tmax_size); - } - return false; - } - -protected: - static SmallStackPool &GetPool() - { - static SmallStackPool pool; - return pool; - } - - /** - * Create a branch in the pool if necessary. - */ - inline void Branch() - { - if (this->next != Tmax_size) { - ++(SmallStack::GetPool().Get(this->next).branch_count); - } - } -}; - -#endif diff --git a/src/economy.cpp b/src/economy.cpp index 824066e898e2b..8001d3afd843d 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -1270,7 +1270,7 @@ void PrepareUnload(Vehicle *front_v) assert(CargoPayment::CanAllocateItem()); front_v->cargo_payment = new CargoPayment(front_v); - StationIDStack next_station = front_v->GetNextStoppingStation(); + std::vector next_station = front_v->GetNextStoppingStation(); if (front_v->orders == nullptr || (front_v->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0) { Station *st = Station::Get(front_v->last_station_visited); for (Vehicle *v = front_v; v != nullptr; v = v->Next()) { @@ -1433,7 +1433,7 @@ struct FinalizeRefitAction { CargoArray &consist_capleft; ///< Capacities left in the consist. Station *st; ///< Station to reserve cargo from. - StationIDStack &next_station; ///< Next hops to reserve cargo for. + std::span next_station; ///< Next hops to reserve cargo for. bool do_reserve; ///< If the vehicle should reserve. /** @@ -1443,7 +1443,7 @@ struct FinalizeRefitAction * @param next_station Next hops to reserve cargo for. * @param do_reserve If we should reserve cargo or just add up the capacities. */ - FinalizeRefitAction(CargoArray &consist_capleft, Station *st, StationIDStack &next_station, bool do_reserve) : + FinalizeRefitAction(CargoArray &consist_capleft, Station *st, std::span next_station, bool do_reserve) : consist_capleft(consist_capleft), st(st), next_station(next_station), do_reserve(do_reserve) {} /** @@ -1471,7 +1471,7 @@ struct FinalizeRefitAction * @param next_station Possible next stations the vehicle can travel to. * @param new_cargo_type Target cargo for refit. */ -static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station *st, StationIDStack next_station, CargoType new_cargo_type) +static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station *st, std::span next_station, CargoType new_cargo_type) { Vehicle *v_start = v->GetFirstEnginePart(); if (!IterateVehicleParts(v_start, IsEmptyAction())) return; @@ -1538,16 +1538,16 @@ static bool MayLoadUnderExclusiveRights(const Station *st, const Vehicle *v) struct ReserveCargoAction { Station *st; - StationIDStack *next_station; + std::span next_station; - ReserveCargoAction(Station *st, StationIDStack *next_station) : + ReserveCargoAction(Station *st, std::span next_station) : st(st), next_station(next_station) {} bool operator()(Vehicle *v) { if (v->cargo_cap > v->cargo.RemainingCount() && MayLoadUnderExclusiveRights(st, v)) { st->goods[v->cargo_type].GetOrCreateData().cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(), - &v->cargo, *next_station, v->GetCargoTile()); + &v->cargo, next_station, v->GetCargoTile()); } return true; @@ -1563,7 +1563,7 @@ struct ReserveCargoAction { * @param consist_capleft If given, save free capacities after reserving there. * @param next_station Station(s) the vehicle will stop at next. */ -static void ReserveConsist(Station *st, Vehicle *u, CargoArray *consist_capleft, StationIDStack *next_station) +static void ReserveConsist(Station *st, Vehicle *u, CargoArray *consist_capleft, std::span next_station) { /* If there is a cargo payment not all vehicles of the consist have tried to do the refit. * In that case, only reserve if it's a fixed refit and the equivalent of "articulated chain" @@ -1618,14 +1618,14 @@ static void LoadUnloadVehicle(Vehicle *front) StationID last_visited = front->last_station_visited; Station *st = Station::Get(last_visited); - StationIDStack next_station = front->GetNextStoppingStation(); + std::vector next_station = front->GetNextStoppingStation(); bool use_autorefit = front->current_order.IsRefit() && front->current_order.GetRefitCargo() == CARGO_AUTO_REFIT; CargoArray consist_capleft{}; if (_settings_game.order.improved_load && use_autorefit ? front->cargo_payment == nullptr : (front->current_order.GetLoadType() & OLFB_FULL_LOAD) != 0) { ReserveConsist(st, front, (use_autorefit && front->load_unload_ticks != 0) ? &consist_capleft : nullptr, - &next_station); + next_station); } /* We have not waited enough time till the next round of loading/unloading */ diff --git a/src/linkgraph/linkgraphjob.cpp b/src/linkgraph/linkgraphjob.cpp index 5287fb633bb68..f83e3341a961d 100644 --- a/src/linkgraph/linkgraphjob.cpp +++ b/src/linkgraph/linkgraphjob.cpp @@ -132,11 +132,11 @@ LinkGraphJob::~LinkGraphJob() !(*lg)[node_id].HasEdgeTo(dest_id) || (*lg)[node_id][dest_id].LastUpdate() == EconomyTime::INVALID_DATE) { /* Edge has been removed. Delete flows. */ - StationIDStack erased = flows.DeleteFlows(to); + std::vector erased = flows.DeleteFlows(to); /* Delete old flows for source stations which have been deleted * from the new flows. This avoids flow cycles between old and * new flows. */ - while (!erased.IsEmpty()) geflows.erase(erased.Pop()); + for (const StationID &station : erased) geflows.erase(station); } else if ((*lg)[node_id][dest_id].last_unrestricted_update == EconomyTime::INVALID_DATE) { /* Edge is fully restricted. */ flows.RestrictFlows(to); diff --git a/src/order_base.h b/src/order_base.h index 1b0f6b175255c..5a2511bae0909 100644 --- a/src/order_base.h +++ b/src/order_base.h @@ -367,7 +367,7 @@ struct OrderList : OrderListPool::PoolItem<&_orderlist_pool> { */ inline VehicleOrderID GetNumManualOrders() const { return this->num_manual_orders; } - StationIDStack GetNextStoppingStation(const Vehicle *v, VehicleOrderID first = INVALID_VEH_ORDER_ID, uint hops = 0) const; + std::vector GetNextStoppingStation(const Vehicle *v, VehicleOrderID first = INVALID_VEH_ORDER_ID, uint hops = 0) const; VehicleOrderID GetNextDecisionNode(VehicleOrderID next, uint hops) const; void InsertOrderAt(Order &&order, VehicleOrderID index); diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 9f968a461f54b..32df9ffd30956 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -361,14 +361,14 @@ VehicleOrderID OrderList::GetNextDecisionNode(VehicleOrderID next, uint hops) co * @pre The vehicle is currently loading and v->last_station_visited is meaningful. * @note This function may draw a random number. Don't use it from the GUI. */ -StationIDStack OrderList::GetNextStoppingStation(const Vehicle *v, VehicleOrderID first, uint hops) const +std::vector OrderList::GetNextStoppingStation(const Vehicle *v, VehicleOrderID first, uint hops) const { VehicleOrderID next = first; if (first == INVALID_VEH_ORDER_ID) { next = v->cur_implicit_order_index; if (next >= this->GetNumOrders()) { next = this->GetFirstOrder(); - if (next == INVALID_VEH_ORDER_ID) return StationID::Invalid(); + if (next == INVALID_VEH_ORDER_ID) return {}; } else { /* GetNext never returns INVALID_VEH_ORDER_ID if there is a valid station in the list. * As the given "next" is already valid and a station in the list, we @@ -392,9 +392,9 @@ StationIDStack OrderList::GetNextStoppingStation(const Vehicle *v, VehicleOrderI } else if (skip_to == INVALID_VEH_ORDER_ID || skip_to == first) { next = (advance == first) ? INVALID_VEH_ORDER_ID : advance; } else { - StationIDStack st1 = this->GetNextStoppingStation(v, skip_to, hops); - StationIDStack st2 = this->GetNextStoppingStation(v, advance, hops); - while (!st2.IsEmpty()) st1.Push(st2.Pop()); + std::vector st1 = this->GetNextStoppingStation(v, skip_to, hops); + std::vector st2 = this->GetNextStoppingStation(v, advance, hops); + std::copy(st2.rbegin(), st2.rend(), std::back_inserter(st1)); return st1; } ++hops; @@ -404,11 +404,11 @@ StationIDStack OrderList::GetNextStoppingStation(const Vehicle *v, VehicleOrderI if (next == INVALID_VEH_ORDER_ID || ((orders[next].IsType(OT_GOTO_STATION) || orders[next].IsType(OT_IMPLICIT)) && orders[next].GetDestination() == v->last_station_visited && (orders[next].GetUnloadType() & (OUFB_TRANSFER | OUFB_UNLOAD)) != 0)) { - return StationID::Invalid(); + return {}; } } while (orders[next].IsType(OT_GOTO_DEPOT) || orders[next].GetDestination() == v->last_station_visited); - return orders[next].GetDestination().ToStationID(); + return {orders[next].GetDestination().ToStationID()}; } /** diff --git a/src/station_base.h b/src/station_base.h index d8e62d23393fa..4832a0f60cbce 100644 --- a/src/station_base.h +++ b/src/station_base.h @@ -155,7 +155,7 @@ class FlowStatMap : public std::map { void AddFlow(StationID origin, StationID via, uint amount); void PassOnFlow(StationID origin, StationID via, uint amount); - StationIDStack DeleteFlows(StationID via); + std::vector DeleteFlows(StationID via); void RestrictFlows(StationID via); void ReleaseFlows(StationID via); void FinalizeLocalConsumption(StationID self); diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 8a90e30f0ee0d..bffab91a52a4b 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -5200,14 +5200,14 @@ void FlowStatMap::FinalizeLocalConsumption(StationID self) * @return IDs of source stations for which the complete FlowStat, not only a * share, has been erased. */ -StationIDStack FlowStatMap::DeleteFlows(StationID via) +std::vector FlowStatMap::DeleteFlows(StationID via) { - StationIDStack ret; + std::vector ret; for (FlowStatMap::iterator f_it = this->begin(); f_it != this->end();) { FlowStat &s_flows = f_it->second; s_flows.ChangeShare(via, INT_MIN); if (s_flows.GetShares()->empty()) { - ret.Push(f_it->first); + ret.push_back(f_it->first); this->erase(f_it++); } else { ++f_it; diff --git a/src/station_type.h b/src/station_type.h index 07615dd7a1685..1c4da959dd8bf 100644 --- a/src/station_type.h +++ b/src/station_type.h @@ -11,7 +11,6 @@ #define STATION_TYPE_H #include "core/pool_type.hpp" -#include "core/smallstack_type.hpp" #include "tilearea_type.h" using StationID = PoolID; @@ -26,8 +25,6 @@ struct RoadStop; struct StationSpec; struct Waypoint; -using StationIDStack = SmallStack; - /** Station types */ enum class StationType : uint8_t { Rail, diff --git a/src/vehicle_base.h b/src/vehicle_base.h index aef3b4f246ac7..642669ae8e21d 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -714,9 +714,9 @@ struct Vehicle : VehiclePool::PoolItem<&_vehicle_pool>, BaseVehicle, BaseConsist * Get the next station the vehicle will stop at. * @return ID of the next station the vehicle will stop at or StationID::Invalid(). */ - inline StationIDStack GetNextStoppingStation() const + inline std::vector GetNextStoppingStation() const { - return (this->orders == nullptr) ? StationID::Invalid() : this->orders->GetNextStoppingStation(this); + return (this->orders == nullptr) ? std::vector{} : this->orders->GetNextStoppingStation(this); } void ResetRefitCaps(); From d6eff806f0a84a0f80656a4f58d9391b9833b79b Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Thu, 16 Oct 2025 21:54:43 +0100 Subject: [PATCH 076/137] Codechange: Use single vector for next station order. Pass vector to insert into to avoid handling multiple vectors. This may change the order of returned stations. --- src/aircraft_cmd.cpp | 3 ++- src/economy.cpp | 6 ++++-- src/order_base.h | 2 +- src/order_cmd.cpp | 15 +++++++-------- src/vehicle_base.h | 5 +++-- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index dce6e04f57ccb..94d976e112e2f 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -135,7 +135,8 @@ static StationID FindNearestHangar(const Aircraft *v) next_dest = Station::GetIfValid(v->current_order.GetDestination().ToStationID()); } else { last_dest = GetTargetAirportIfValid(v); - std::vector next_station = v->GetNextStoppingStation(); + std::vector next_station; + v->GetNextStoppingStation(next_station); if (!next_station.empty()) next_dest = Station::GetIfValid(next_station.back()); } } diff --git a/src/economy.cpp b/src/economy.cpp index 8001d3afd843d..d61372de7eabb 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -1270,7 +1270,8 @@ void PrepareUnload(Vehicle *front_v) assert(CargoPayment::CanAllocateItem()); front_v->cargo_payment = new CargoPayment(front_v); - std::vector next_station = front_v->GetNextStoppingStation(); + std::vector next_station; + front_v->GetNextStoppingStation(next_station); if (front_v->orders == nullptr || (front_v->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0) { Station *st = Station::Get(front_v->last_station_visited); for (Vehicle *v = front_v; v != nullptr; v = v->Next()) { @@ -1618,7 +1619,8 @@ static void LoadUnloadVehicle(Vehicle *front) StationID last_visited = front->last_station_visited; Station *st = Station::Get(last_visited); - std::vector next_station = front->GetNextStoppingStation(); + std::vector next_station; + front->GetNextStoppingStation(next_station); bool use_autorefit = front->current_order.IsRefit() && front->current_order.GetRefitCargo() == CARGO_AUTO_REFIT; CargoArray consist_capleft{}; if (_settings_game.order.improved_load && use_autorefit ? diff --git a/src/order_base.h b/src/order_base.h index 5a2511bae0909..5dac764838126 100644 --- a/src/order_base.h +++ b/src/order_base.h @@ -367,7 +367,7 @@ struct OrderList : OrderListPool::PoolItem<&_orderlist_pool> { */ inline VehicleOrderID GetNumManualOrders() const { return this->num_manual_orders; } - std::vector GetNextStoppingStation(const Vehicle *v, VehicleOrderID first = INVALID_VEH_ORDER_ID, uint hops = 0) const; + void GetNextStoppingStation(std::vector &next_station, const Vehicle *v, VehicleOrderID first = INVALID_VEH_ORDER_ID, uint hops = 0) const; VehicleOrderID GetNextDecisionNode(VehicleOrderID next, uint hops) const; void InsertOrderAt(Order &&order, VehicleOrderID index); diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 32df9ffd30956..8754c96874b5b 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -361,14 +361,14 @@ VehicleOrderID OrderList::GetNextDecisionNode(VehicleOrderID next, uint hops) co * @pre The vehicle is currently loading and v->last_station_visited is meaningful. * @note This function may draw a random number. Don't use it from the GUI. */ -std::vector OrderList::GetNextStoppingStation(const Vehicle *v, VehicleOrderID first, uint hops) const +void OrderList::GetNextStoppingStation(std::vector &next_station, const Vehicle *v, VehicleOrderID first, uint hops) const { VehicleOrderID next = first; if (first == INVALID_VEH_ORDER_ID) { next = v->cur_implicit_order_index; if (next >= this->GetNumOrders()) { next = this->GetFirstOrder(); - if (next == INVALID_VEH_ORDER_ID) return {}; + if (next == INVALID_VEH_ORDER_ID) return; } else { /* GetNext never returns INVALID_VEH_ORDER_ID if there is a valid station in the list. * As the given "next" is already valid and a station in the list, we @@ -392,10 +392,9 @@ std::vector OrderList::GetNextStoppingStation(const Vehicle *v, Vehic } else if (skip_to == INVALID_VEH_ORDER_ID || skip_to == first) { next = (advance == first) ? INVALID_VEH_ORDER_ID : advance; } else { - std::vector st1 = this->GetNextStoppingStation(v, skip_to, hops); - std::vector st2 = this->GetNextStoppingStation(v, advance, hops); - std::copy(st2.rbegin(), st2.rend(), std::back_inserter(st1)); - return st1; + this->GetNextStoppingStation(next_station, v, skip_to, hops); + this->GetNextStoppingStation(next_station, v, advance, hops); + return; } ++hops; } @@ -404,11 +403,11 @@ std::vector OrderList::GetNextStoppingStation(const Vehicle *v, Vehic if (next == INVALID_VEH_ORDER_ID || ((orders[next].IsType(OT_GOTO_STATION) || orders[next].IsType(OT_IMPLICIT)) && orders[next].GetDestination() == v->last_station_visited && (orders[next].GetUnloadType() & (OUFB_TRANSFER | OUFB_UNLOAD)) != 0)) { - return {}; + return; } } while (orders[next].IsType(OT_GOTO_DEPOT) || orders[next].GetDestination() == v->last_station_visited); - return {orders[next].GetDestination().ToStationID()}; + next_station.push_back(orders[next].GetDestination().ToStationID()); } /** diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 642669ae8e21d..6e9cc5e20f2cf 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -714,9 +714,10 @@ struct Vehicle : VehiclePool::PoolItem<&_vehicle_pool>, BaseVehicle, BaseConsist * Get the next station the vehicle will stop at. * @return ID of the next station the vehicle will stop at or StationID::Invalid(). */ - inline std::vector GetNextStoppingStation() const + inline void GetNextStoppingStation(std::vector &next_station) const { - return (this->orders == nullptr) ? std::vector{} : this->orders->GetNextStoppingStation(this); + if (this->orders == nullptr) return; + this->orders->GetNextStoppingStation(next_station, this); } void ResetRefitCaps(); From e4b0e84a7cd22769b48f4ab09da6b1300fb1a7ee Mon Sep 17 00:00:00 2001 From: SamuXarick <43006711+SamuXarick@users.noreply.github.com> Date: Fri, 24 Oct 2025 20:19:47 +0100 Subject: [PATCH 077/137] Doc 80666a0: Fix typo in game script changelog (#14714) --- src/script/api/game_changelog.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/script/api/game_changelog.hpp b/src/script/api/game_changelog.hpp index 4a3a3111abea9..50c91de6bd620 100644 --- a/src/script/api/game_changelog.hpp +++ b/src/script/api/game_changelog.hpp @@ -29,7 +29,7 @@ * \li GSCargo::CC_NON_POTABLE * \li GSVehicleList_Waypoint * \li GSBaseStation::GetOwner - * \li GSError:ERR_BRIDGE_TOO_LOW + * \li GSError::ERR_BRIDGE_TOO_LOW * \li GSRail::GetAllRailTypes * * Other changes: From a19f6c02e541a61e33905a5ef96f3e199dc578bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Guilloux?= Date: Fri, 24 Oct 2025 21:20:41 +0200 Subject: [PATCH 078/137] Codechange: Add prefix to dependabot commits (#14691) --- .github/dependabot.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d97e315781b96..050a4cc0bc2df 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -8,3 +8,5 @@ updates: actions: patterns: - "*" + commit-message: + prefix: "Upgrade: " From 06b830dc0730c878bfffbca09b2888a46e31faf0 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 24 Oct 2025 20:30:03 +0100 Subject: [PATCH 079/137] Codechange: Prefer string equality instead of comparison. (#14727) --- src/base_media_func.h | 2 +- src/fios.cpp | 2 +- src/game/game_text.cpp | 10 +++++----- src/ini_load.cpp | 3 +-- src/language.h | 12 ++++-------- src/network/network.cpp | 4 ++-- src/network/network_admin.cpp | 3 +-- src/network/network_client.cpp | 24 ++++++++++++------------ src/network/network_server.cpp | 4 ++-- src/os/windows/font_win32.cpp | 5 ++--- src/saveload/ai_sl.cpp | 4 ++-- src/saveload/game_sl.cpp | 2 +- src/saveload/saveload.cpp | 2 +- src/settings.cpp | 2 +- src/settings_table.cpp | 2 +- 15 files changed, 37 insertions(+), 44 deletions(-) diff --git a/src/base_media_func.h b/src/base_media_func.h index 8f1fac4c26d25..d5a96bcc93566 100644 --- a/src/base_media_func.h +++ b/src/base_media_func.h @@ -79,7 +79,7 @@ bool BaseSet::FillSetDetails(const IniFile &ini, const std::string &path, con /* Add the translations of the descriptions too. */ for (const IniItem &titem : metadata->items) { - if (titem.name.compare(0, 12, "description.") != 0) continue; + if (!titem.name.starts_with("description.")) continue; this->description[titem.name.substr(12)] = titem.value.value_or(""); } diff --git a/src/fios.cpp b/src/fios.cpp index fc02d43da789c..67eec48b44594 100644 --- a/src/fios.cpp +++ b/src/fios.cpp @@ -507,7 +507,7 @@ std::tuple FiosGetHeightmapListCallback(SaveLoadOperation for (Searchpath sp : _valid_searchpaths) { std::string buf = FioGetDirectory(sp, HEIGHTMAP_DIR); - if (buf.compare(0, buf.size(), it->second.tar_filename, 0, buf.size()) == 0) { + if (it->second.tar_filename.starts_with(buf)) { match = true; break; } diff --git a/src/game/game_text.cpp b/src/game/game_text.cpp index 27e4314f5ac8c..021d5fec57a64 100644 --- a/src/game/game_text.cpp +++ b/src/game/game_text.cpp @@ -225,15 +225,15 @@ static std::shared_ptr LoadTranslations() if (!tar_filename.empty() && (iter = _tar_list[GAME_DIR].find(tar_filename)) != _tar_list[GAME_DIR].end()) { /* The main script is in a tar file, so find all files that * are in the same tar and add them to the langfile scanner. */ - for (const auto &tar : _tar_filelist[GAME_DIR]) { + for (const auto &[name, entry] : _tar_filelist[GAME_DIR]) { /* Not in the same tar. */ - if (tar.second.tar_filename != iter->first) continue; + if (entry.tar_filename != iter->first) continue; /* Check the path and extension. */ - if (tar.first.size() <= ldir.size() || tar.first.compare(0, ldir.size(), ldir) != 0) continue; - if (tar.first.compare(tar.first.size() - 4, 4, ".txt") != 0) continue; + if (!name.starts_with(ldir)) continue; + if (!name.ends_with(".txt")) continue; - scanner.AddFile(tar.first, 0, tar_filename); + scanner.AddFile(name, 0, tar_filename); } } else { /* Scan filesystem */ diff --git a/src/ini_load.cpp b/src/ini_load.cpp index 7702eed8ce684..f134f6502e3a6 100644 --- a/src/ini_load.cpp +++ b/src/ini_load.cpp @@ -173,8 +173,7 @@ IniGroup &IniLoadFile::CreateGroup(std::string_view name) */ void IniLoadFile::RemoveGroup(std::string_view name) { - size_t len = name.length(); - this->groups.remove_if([&name, &len](const IniGroup &group) { return group.name.compare(0, len, name) == 0; }); + this->groups.remove_if([&name](const IniGroup &group) { return group.name.starts_with(name); }); } /** diff --git a/src/language.h b/src/language.h index 4f1a50a29d95e..3158154ed2709 100644 --- a/src/language.h +++ b/src/language.h @@ -67,10 +67,8 @@ struct LanguagePackHeader { */ uint8_t GetGenderIndex(std::string_view gender_str) const { - for (uint8_t i = 0; i < MAX_NUM_GENDERS; i++) { - if (gender_str.compare(this->genders[i]) == 0) return i; - } - return MAX_NUM_GENDERS; + auto it = std::ranges::find(this->genders, gender_str); + return static_cast(std::distance(std::begin(this->genders), it)); } /** @@ -80,10 +78,8 @@ struct LanguagePackHeader { */ uint8_t GetCaseIndex(std::string_view case_str) const { - for (uint8_t i = 0; i < MAX_NUM_CASES; i++) { - if (case_str.compare(this->cases[i]) == 0) return i; - } - return MAX_NUM_CASES; + auto it = std::ranges::find(this->cases, case_str); + return static_cast(std::distance(std::begin(this->cases), it)); } }; /** Make sure the size is right. */ diff --git a/src/network/network.cpp b/src/network/network.cpp index 6a02b82f5acc4..29cbcf7acff4c 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -875,14 +875,14 @@ static void CheckClientAndServerName() { static const std::string fallback_client_name = "Unnamed Client"; StrTrimInPlace(_settings_client.network.client_name); - if (_settings_client.network.client_name.empty() || _settings_client.network.client_name.compare(fallback_client_name) == 0) { + if (_settings_client.network.client_name.empty() || _settings_client.network.client_name == fallback_client_name) { Debug(net, 1, "No \"client_name\" has been set, using \"{}\" instead. Please set this now using the \"name \" command", fallback_client_name); _settings_client.network.client_name = fallback_client_name; } static const std::string fallback_server_name = "Unnamed Server"; StrTrimInPlace(_settings_client.network.server_name); - if (_settings_client.network.server_name.empty() || _settings_client.network.server_name.compare(fallback_server_name) == 0) { + if (_settings_client.network.server_name.empty() || _settings_client.network.server_name == fallback_server_name) { Debug(net, 1, "No \"server_name\" has been set, using \"{}\" instead. Please set this now using the \"server_name \" command", fallback_server_name); _settings_client.network.server_name = fallback_server_name; } diff --git a/src/network/network_admin.cpp b/src/network/network_admin.cpp index 5ede07f12b324..95694636d2583 100644 --- a/src/network/network_admin.cpp +++ b/src/network/network_admin.cpp @@ -633,8 +633,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_JOIN(Packet &p) std::string password = p.Recv_string(NETWORK_PASSWORD_LENGTH); - if (_settings_client.network.admin_password.empty() || - _settings_client.network.admin_password.compare(password) != 0) { + if (_settings_client.network.admin_password.empty() || _settings_client.network.admin_password != password) { /* Password is invalid */ return this->SendError(NETWORK_ERROR_WRONG_PASSWORD); } diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index 6dccf9e5fe9d2..4313a9de0ae05 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -537,7 +537,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Pac ci = NetworkClientInfo::GetByClientID(client_id); if (ci != nullptr) { - if (playas == ci->client_playas && name.compare(ci->client_name) != 0) { + if (playas == ci->client_playas && name != ci->client_name) { /* Client name changed, display the change */ NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, name); } else if (playas != ci->client_playas) { @@ -1296,17 +1296,17 @@ void NetworkUpdateClientName(const std::string &client_name) if (ci == nullptr) return; /* Don't change the name if it is the same as the old name */ - if (client_name.compare(ci->client_name) != 0) { - if (!_network_server) { - MyClient::SendSetName(client_name); - } else { - /* Copy to a temporary buffer so no #n gets added after our name in the settings when there are duplicate names. */ - std::string temporary_name = client_name; - if (NetworkMakeClientNameUnique(temporary_name)) { - NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, temporary_name); - ci->client_name = std::move(temporary_name); - NetworkUpdateClientInfo(CLIENT_ID_SERVER); - } + if (client_name == ci->client_name) return; + + if (!_network_server) { + MyClient::SendSetName(client_name); + } else { + /* Copy to a temporary buffer so no #n gets added after our name in the settings when there are duplicate names. */ + std::string temporary_name = client_name; + if (NetworkMakeClientNameUnique(temporary_name)) { + NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, temporary_name); + ci->client_name = std::move(temporary_name); + NetworkUpdateClientInfo(CLIENT_ID_SERVER); } } } diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 3087db360efa8..ff39b2b854a17 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -1451,7 +1451,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_RCON(Packet &p) /* We are allowed, nothing more to validate. */ } else if (_settings_client.network.rcon_password.empty()) { return NETWORK_RECV_STATUS_OKAY; - } else if (_settings_client.network.rcon_password.compare(password) != 0) { + } else if (_settings_client.network.rcon_password != password) { Debug(net, 1, "[rcon] Wrong password from client-id {}", this->client_id); return NETWORK_RECV_STATUS_OKAY; } @@ -1648,7 +1648,7 @@ bool NetworkServerChangeClientName(ClientID client_id, const std::string &new_na { /* Check if the name's already in use */ for (NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { - if (ci->client_name.compare(new_name) == 0) return false; + if (ci->client_name == new_name) return false; } NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id); diff --git a/src/os/windows/font_win32.cpp b/src/os/windows/font_win32.cpp index da305072608b8..24100a1704b75 100644 --- a/src/os/windows/font_win32.cpp +++ b/src/os/windows/font_win32.cpp @@ -38,9 +38,8 @@ struct EFCParam { bool Add(const std::wstring_view &font) { - for (const auto &entry : this->fonts) { - if (font.compare(entry) == 0) return false; - } + auto it = std::ranges::find(this->fonts, font); + if (it != std::end(this->fonts)) return false; this->fonts.emplace_back(font); diff --git a/src/saveload/ai_sl.cpp b/src/saveload/ai_sl.cpp index 29f759361c899..e6e52f8217d00 100644 --- a/src/saveload/ai_sl.cpp +++ b/src/saveload/ai_sl.cpp @@ -111,7 +111,7 @@ struct AIPLChunkHandler : ChunkHandler { * latest version of the AI instead. */ config->Change(_ai_saveload_name, -1, false); if (!config->HasScript()) { - if (_ai_saveload_name.compare("%_dummy") != 0) { + if (_ai_saveload_name != "%_dummy") { Debug(script, 0, "The savegame has an AI by the name '{}', version {} which is no longer available.", _ai_saveload_name, _ai_saveload_version); Debug(script, 0, "Configuration switched to Random AI."); } @@ -136,7 +136,7 @@ struct AIPLChunkHandler : ChunkHandler { * latest version of the AI instead. */ config->Change(_ai_saveload_name, -1, false); if (!config->HasScript()) { - if (_ai_saveload_name.compare("%_dummy") != 0) { + if (_ai_saveload_name != "%_dummy") { Debug(script, 0, "The savegame has an AI by the name '{}', version {} which is no longer available.", _ai_saveload_name, _ai_saveload_version); Debug(script, 0, "A random other AI will be loaded in its place."); } else { diff --git a/src/saveload/game_sl.cpp b/src/saveload/game_sl.cpp index d6a35ffa20424..82b2c783edcc3 100644 --- a/src/saveload/game_sl.cpp +++ b/src/saveload/game_sl.cpp @@ -80,7 +80,7 @@ struct GSDTChunkHandler : ChunkHandler { * latest version of the GameScript instead. */ config->Change(_game_saveload_name, -1, false); if (!config->HasScript()) { - if (_game_saveload_name.compare("%_dummy") != 0) { + if (_game_saveload_name != "%_dummy") { Debug(script, 0, "The savegame has an GameScript by the name '{}', version {} which is no longer available.", _game_saveload_name, _game_saveload_version); Debug(script, 0, "This game will continue to run without GameScript."); } else { diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 9f759cc7b041a..a6dd26e3cfbac 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -2861,7 +2861,7 @@ static std::pair GetSavegameFormat(std::string_ std::string_view name = has_comp_level ? full_name.substr(0, separator) : full_name; for (const auto &slf : _saveload_formats) { - if (slf.init_write != nullptr && name.compare(slf.name) == 0) { + if (slf.init_write != nullptr && name == slf.name) { if (has_comp_level) { auto complevel = full_name.substr(separator + 1); diff --git a/src/settings.cpp b/src/settings.cpp index 9efb21a0572c8..1b90eb6140359 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1547,7 +1547,7 @@ StringList GetGRFPresetList() ConfigIniFile ini(_config_file); for (const IniGroup &group : ini.groups) { - if (group.name.compare(0, 7, "preset-") == 0) { + if (group.name.starts_with("preset-")) { list.push_back(group.name.substr(7)); } } diff --git a/src/settings_table.cpp b/src/settings_table.cpp index b75bd3afb6f39..1881cfd79e479 100644 --- a/src/settings_table.cpp +++ b/src/settings_table.cpp @@ -572,7 +572,7 @@ static void MaxVehiclesChanged(int32_t) */ static bool ReplaceAsteriskWithEmptyPassword(std::string &newval) { - if (newval.compare("*") == 0) newval.clear(); + if (newval == "*") newval.clear(); return true; } From 813cde37353c3219e3f682da04398331081bb463 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 24 Oct 2025 20:30:50 +0100 Subject: [PATCH 080/137] Fix: Don't set set town index for depot tiles. (#14729) --- src/saveload/afterload.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 4a901a3b39346..6f2ba03bcb68f 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -1007,6 +1007,7 @@ bool AfterLoadGame() case MP_ROAD: t.m4() |= (t.m2() << 4); + if (GB(t.m5(), 4, 2) == ROAD_TILE_DEPOT) break; if ((GB(t.m5(), 4, 2) == ROAD_TILE_CROSSING ? (Owner)t.m3() : GetTileOwner(t)) == OWNER_TOWN) { SetTownIndex(t, CalcClosestTownFromTile(t)->index); } else { From 6fc4bef0e38ef4e2b3fe015283e4705e1600afaa Mon Sep 17 00:00:00 2001 From: Oliver Bechstein-Rumble <58312347+OllieBechstein@users.noreply.github.com> Date: Fri, 24 Oct 2025 20:33:55 +0100 Subject: [PATCH 081/137] Fix #14240: Remember previous GUI scale when toggling auto-detect (#14380) --- src/settings_gui.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index af466bf40bdf5..7b0c9e1a15143 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -415,6 +415,7 @@ struct GameOptionsWindow : Window { bool reload = false; bool gui_scale_changed = false; int gui_scale = 0; + static inline int previous_gui_scale = 0; ///< Previous GUI scale. static inline WidgetID active_tab = WID_GO_TAB_GENERAL; GameOptionsWindow(WindowDesc &desc) : Window(desc), filter_editbox(50) @@ -1076,9 +1077,12 @@ struct GameOptionsWindow : Window { case WID_GO_GUI_SCALE_AUTO: { if (_gui_scale_cfg == -1) { - _gui_scale_cfg = _gui_scale; + _gui_scale_cfg = this->previous_gui_scale; // Load the previous GUI scale this->SetWidgetLoweredState(WID_GO_GUI_SCALE_AUTO, false); + if (AdjustGUIZoom(false)) ReInitAllWindows(true); + this->gui_scale = _gui_scale; } else { + this->previous_gui_scale = _gui_scale; // Set the previous GUI scale value as the current one _gui_scale_cfg = -1; this->SetWidgetLoweredState(WID_GO_GUI_SCALE_AUTO, true); if (AdjustGUIZoom(false)) ReInitAllWindows(true); From 2212169a8c69392d491365e997d961efb782a68c Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Fri, 24 Oct 2025 20:34:35 +0100 Subject: [PATCH 082/137] Fix: Do not pre-fill industry production history for unused production slots (#14730) --- src/industry_cmd.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 08dbdc4efcabd..565d86c374cab 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -1835,13 +1835,13 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, if (indspec->callback_mask.Test(IndustryCallbackMask::Production256Ticks)) { IndustryProductionCallback(i, 1); for (auto &p : i->produced) { - p.history[LAST_MONTH].production = ScaleByCargoScale(p.waiting * 8, false); + if (IsValidCargoType(p.cargo)) p.history[LAST_MONTH].production = ScaleByCargoScale(p.waiting * 8, false); p.waiting = 0; } } for (auto &p : i->produced) { - p.history[LAST_MONTH].production += ScaleByCargoScale(p.rate * 8, false); + if (IsValidCargoType(p.cargo)) p.history[LAST_MONTH].production += ScaleByCargoScale(p.rate * 8, false); } UpdateValidHistory(i->valid_history, HISTORY_YEAR, TimerGameEconomy::month); From 6ebe64703fef2d7fbe91401ae5715ac2bddf2b1a Mon Sep 17 00:00:00 2001 From: Rito12 <111280526+Rito13@users.noreply.github.com> Date: Fri, 24 Oct 2025 22:25:16 +0200 Subject: [PATCH 083/137] Add: Game units for height. (#14615) --- src/lang/english.txt | 4 +++- src/strings.cpp | 1 + src/table/settings/locale_settings.ini | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 240fc2ac059a4..1733c8d0c2798 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -254,6 +254,7 @@ STR_UNITS_FORCE_SI :{DECIMAL}{NBSP} STR_UNITS_HEIGHT_IMPERIAL :{DECIMAL}{NBSP}ft STR_UNITS_HEIGHT_METRIC :{DECIMAL}{NBSP}m STR_UNITS_HEIGHT_SI :{DECIMAL}{NBSP}m +STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}{NBSP}level{P "" s} # Time units used in string control characters STR_UNITS_DAYS :{COMMA}{NBSP}day{P "" s} @@ -2158,10 +2159,11 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Heights units: {STRING2} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Whenever a height is shown in the user interface, show it in the selected units -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metric (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :Game units (levels) STR_CONFIG_SETTING_LOCALISATION :Localisation STR_CONFIG_SETTING_GRAPHICS :Graphics diff --git a/src/strings.cpp b/src/strings.cpp index b4050dca0c83d..141027f0b791f 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -916,6 +916,7 @@ static const Units _units_height[] = { { { 3.0 }, STR_UNITS_HEIGHT_IMPERIAL, 0 }, // "Wrong" conversion factor for more nicer GUI values { { 1.0 }, STR_UNITS_HEIGHT_METRIC, 0 }, { { 1.0 }, STR_UNITS_HEIGHT_SI, 0 }, + { { .02 }, STR_UNITS_HEIGHT_GAMEUNITS,0 }, }; /** Unit conversions for time in calendar days or wallclock seconds */ diff --git a/src/table/settings/locale_settings.ini b/src/table/settings/locale_settings.ini index c5c0a520bf10f..1296f15332190 100644 --- a/src/table/settings/locale_settings.ini +++ b/src/table/settings/locale_settings.ini @@ -163,7 +163,7 @@ type = SLE_UINT8 from = SLV_184 flags = SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown def = 1 -max = 2 +max = 3 full = _locale_units post_cb = [](auto) { MarkWholeScreenDirty(); } cat = SC_BASIC From 70bf84175f85817261df50d019945f6e14738bec Mon Sep 17 00:00:00 2001 From: Rito12 <111280526+Rito13@users.noreply.github.com> Date: Fri, 24 Oct 2025 22:27:11 +0200 Subject: [PATCH 084/137] Add: Show height difference in bridge is too low error message. (#14614) --- src/lang/english.txt | 14 +++++++------- src/station_cmd.cpp | 5 ++++- src/water_cmd.cpp | 6 ++++-- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 1733c8d0c2798..9385e9f4cb95e 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -5271,13 +5271,13 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Start an STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... ends of bridge must both be on land STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... bridge too long STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Bridge would end out of the map -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Bridge is too low for station -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Bridge is too low for road stop -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Bridge is too low for dock -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Bridge is too low for buoy -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Bridge is too low for rail waypoint -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Bridge is too low for road waypoint -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Bridge is too low for lock +STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Bridge is {HEIGHT} too low for station +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Bridge is {HEIGHT} too low for road stop +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Bridge is {HEIGHT} too low for dock +STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Bridge is {HEIGHT} too low for buoy +STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Bridge is {HEIGHT} too low for rail waypoint +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Bridge is {HEIGHT} too low for road waypoint +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Bridge is {HEIGHT} too low for lock # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Can't build tunnel here... diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index bffab91a52a4b..0b8703e53dbb2 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -891,7 +891,10 @@ static CommandCost IsStationBridgeAboveOk(TileIndex tile, std::span::Do(DoCommandFlag::Auto, tile); } - if (GetTileMaxZ(tile) + height > bridge_height) return CommandCost{GetBridgeTooLowMessageForStationType(type)}; + if (GetTileMaxZ(tile) + height > bridge_height) { + int height_diff = (GetTileMaxZ(tile) + height - bridge_height) * TILE_HEIGHT_STEP; + return CommandCostWithParam(GetBridgeTooLowMessageForStationType(type), height_diff); + } return CommandCost{}; } diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 6533d34f226a8..f0a1252a75227 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -365,7 +365,8 @@ static CommandCost DoBuildLock(TileIndex tile, DiagDirection dir, DoCommandFlags for (LockPart lock_part = LOCK_PART_MIDDLE; TileIndex t : {tile, tile - delta, tile + delta}) { if (IsBridgeAbove(t) && GetBridgeHeight(GetSouthernBridgeEnd(t)) < GetTileMaxZ(t) + GetLockPartMinimalBridgeHeight(lock_part)) { - return CommandCost(STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK); + int height_diff = (GetTileMaxZ(tile) + GetLockPartMinimalBridgeHeight(lock_part) - GetBridgeHeight(GetSouthernBridgeEnd(t))) * TILE_HEIGHT_STEP; + return CommandCostWithParam(STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK, height_diff); } ++lock_part; } @@ -1445,7 +1446,8 @@ static CommandCost CheckBuildAbove_Water(TileIndex tile, DoCommandFlags flags, A if (IsWater(tile) || IsCoast(tile)) return CommandCost(); if (IsLock(tile)) { if (GetTileMaxZ(tile) + GetLockPartMinimalBridgeHeight(GetLockPart(tile)) <= height) return CommandCost(); - return CommandCost(STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK); + int height_diff = (GetTileMaxZ(tile) + GetLockPartMinimalBridgeHeight(GetLockPart(tile)) - height) * TILE_HEIGHT_STEP; + return CommandCostWithParam(STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK, height_diff); } return Command::Do(flags, tile); } From a1920fc225083a49769da70abac7df7a3f5a70e0 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 24 Oct 2025 21:32:09 +0100 Subject: [PATCH 085/137] Change: Scale towns/industries by amount of land tiles. (#10063) --- src/genworld.cpp | 2 + src/genworld.h | 3 +- src/genworld_gui.cpp | 5 +- src/industry_cmd.cpp | 109 +++++++++++++++++++++++++++++-------------- src/lang/english.txt | 3 +- src/map.cpp | 16 +++++++ src/map_func.h | 13 ++++++ src/town_cmd.cpp | 5 +- 8 files changed, 114 insertions(+), 42 deletions(-) diff --git a/src/genworld.cpp b/src/genworld.cpp index effa9e16e72ec..1e52fd9a24efa 100644 --- a/src/genworld.cpp +++ b/src/genworld.cpp @@ -139,11 +139,13 @@ static void _GenerateWorld() if (_game_mode != GM_MENU) FlatEmptyWorld(_settings_game.game_creation.se_flat_world_height); ConvertGroundTilesIntoWaterTiles(); + Map::CountLandTiles(); IncreaseGeneratingWorldProgress(GWP_OBJECT); _settings_game.game_creation.snow_line_height = DEF_SNOWLINE_HEIGHT; } else { GenerateClearTile(); + Map::CountLandTiles(); /* Only generate towns, tree and industries in newgame mode. */ if (_game_mode != GM_EDITOR) { diff --git a/src/genworld.h b/src/genworld.h index 0bfd8455ec2ea..f571971260aaf 100644 --- a/src/genworld.h +++ b/src/genworld.h @@ -64,7 +64,8 @@ enum GenWorldProgress : uint8_t { GWP_RIVER, ///< Create the rivers GWP_ROUGH_ROCKY, ///< Make rough and rocky areas GWP_TOWN, ///< Generate towns - GWP_INDUSTRY, ///< Generate industries + GWP_LAND_INDUSTRY, ///< Generate industries + GWP_WATER_INDUSTRY, ///< Generate industries GWP_OBJECT, ///< Generate objects (radio tower, light houses) GWP_TREE, ///< Generate trees GWP_GAME_INIT, ///< Initialize the game diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index 8bef4e4c818b8..12d78035bea49 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -1349,7 +1349,8 @@ static const StringID _generation_class_table[] = { STR_GENERATION_RIVER_GENERATION, STR_GENERATION_CLEARING_TILES, STR_GENERATION_TOWN_GENERATION, - STR_GENERATION_INDUSTRY_GENERATION, + STR_GENERATION_LAND_INDUSTRY_GENERATION, + STR_GENERATION_WATER_INDUSTRY_GENERATION, STR_GENERATION_OBJECT_GENERATION, STR_GENERATION_TREE_GENERATION, STR_GENERATION_SETTINGUP_GAME, @@ -1456,7 +1457,7 @@ void ShowGenerateWorldProgress() static void _SetGeneratingWorldProgress(GenWorldProgress cls, uint progress, uint total) { - static const int percent_table[] = {0, 5, 14, 17, 20, 40, 60, 65, 80, 85, 95, 99, 100 }; + static const int percent_table[] = {0, 5, 14, 17, 20, 40, 55, 60, 65, 80, 85, 95, 99, 100 }; static_assert(lengthof(percent_table) == GWP_CLASS_COUNT + 1); assert(cls < GWP_CLASS_COUNT); diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 565d86c374cab..292f379f8e917 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -45,6 +45,7 @@ #include "industry_cmd.h" #include "landscape_cmd.h" #include "terraform_cmd.h" +#include "map_func.h" #include "timer/timer.h" #include "timer/timer_game_calendar.h" #include "timer/timer_game_economy.h" @@ -2290,12 +2291,15 @@ static Industry *CreateNewIndustry(TileIndex tile, IndustryType type, IndustryAv /** * Compute the appearance probability for an industry during map creation. * @param it Industry type to compute. + * @param water Whether to get probability of land-based, water-based, (or both, if std::nullopt), industry types. * @param[out] force_at_least_one Returns whether at least one instance should be forced on map creation. * @return Relative probability for the industry to appear. */ -static uint32_t GetScaledIndustryGenerationProbability(IndustryType it, bool *force_at_least_one) +static uint32_t GetScaledIndustryGenerationProbability(IndustryType it, std::optional water, bool *force_at_least_one) { const IndustrySpec *ind_spc = GetIndustrySpec(it); + if (water.has_value() && ind_spc->behaviour.Test(IndustryBehaviour::BuiltOnWater) != *water) return 0; + uint32_t chance = ind_spc->appear_creation[to_underlying(_settings_game.game_creation.landscape)]; if (!ind_spc->enabled || ind_spc->layouts.empty() || (_game_mode != GM_EDITOR && _settings_game.difficulty.industry_density == ID_FUND_ONLY) || @@ -2387,11 +2391,11 @@ static Industry *PlaceIndustry(IndustryType type, IndustryAvailabilityCallType c * @param type IndustryType of the desired industry * @param try_hard Try very hard to find a place. (Used to place at least one industry per type) */ -static void PlaceInitialIndustry(IndustryType type, bool try_hard) +static void PlaceInitialIndustry(IndustryType type, bool water, bool try_hard) { Backup cur_company(_current_company, OWNER_NONE); - IncreaseGeneratingWorldProgress(GWP_INDUSTRY); + IncreaseGeneratingWorldProgress(water ? GWP_WATER_INDUSTRY : GWP_LAND_INDUSTRY); PlaceIndustry(type, IACT_MAPGENERATION, try_hard); cur_company.Restore(); @@ -2445,6 +2449,31 @@ void IndustryBuildData::EconomyMonthlyLoop() } } +struct IndustryGenerationProbabilities { + std::array probs{}; + std::array force_one{}; + uint64_t total = 0; + uint num_forced = 0; +}; + +/** + * Get scaled industry generation probabilities. + * @param water Whether to get land or water industry probabilities. + * @returns Probability information. + */ +static IndustryGenerationProbabilities GetScaledProbabilities(bool water) +{ + IndustryGenerationProbabilities p{}; + + for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) { + p.probs[it] = GetScaledIndustryGenerationProbability(it, water, &p.force_one[it]); + p.total += p.probs[it];; + if (p.force_one[it]) p.num_forced++; + } + + return p; +} + /** * This function will create random industries during game creation. * It will scale the amount of industries by mapsize and difficulty level. @@ -2453,46 +2482,54 @@ void GenerateIndustries() { if (_game_mode != GM_EDITOR && _settings_game.difficulty.industry_density == ID_FUND_ONLY) return; // No industries in the game. - uint32_t industry_probs[NUM_INDUSTRYTYPES]; - bool force_at_least_one[NUM_INDUSTRYTYPES]; - uint32_t total_prob = 0; - uint num_forced = 0; + /* Get the probabilities for all industries. This is done first as we need the total of + * both land and water for scaling later. */ + IndustryGenerationProbabilities lprob = GetScaledProbabilities(false); + IndustryGenerationProbabilities wprob = GetScaledProbabilities(true); - for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) { - industry_probs[it] = GetScaledIndustryGenerationProbability(it, force_at_least_one + it); - total_prob += industry_probs[it]; - if (force_at_least_one[it]) num_forced++; - } + /* Run generation twice, for land and water industries in turn. */ + for (bool water = false;; water = true) { + auto &p = water ? wprob : lprob; - uint total_amount = GetNumberOfIndustries(); - if (total_prob == 0 || total_amount < num_forced) { - /* Only place the forced ones */ - total_amount = num_forced; - } + /* Total number of industries scaled by land/water proportion. */ + uint total_amount = p.total * GetNumberOfIndustries() / (lprob.total + wprob.total); - SetGeneratingWorldProgress(GWP_INDUSTRY, total_amount); + /* Scale land-based industries to the land proportion. */ + if (!water) total_amount = Map::ScaleByLandProportion(total_amount); - /* Try to build one industry per type independent of any probabilities */ - for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) { - if (force_at_least_one[it]) { - assert(total_amount > 0); - total_amount--; - PlaceInitialIndustry(it, true); + /* Ensure that forced industries are generated even if the scaled amounts are too low. */ + if (p.total == 0 || total_amount < p.num_forced) { + /* Only place the forced ones */ + total_amount = p.num_forced; } - } - /* Add the remaining industries according to their probabilities */ - for (uint i = 0; i < total_amount; i++) { - uint32_t r = RandomRange(total_prob); - IndustryType it = 0; - while (r >= industry_probs[it]) { - r -= industry_probs[it]; - it++; - assert(it < NUM_INDUSTRYTYPES); + SetGeneratingWorldProgress(water ? GWP_WATER_INDUSTRY : GWP_LAND_INDUSTRY, total_amount); + + /* Try to build one industry per type independent of any probabilities */ + for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) { + if (p.force_one[it]) { + assert(total_amount > 0); + total_amount--; + PlaceInitialIndustry(it, water, true); + } } - assert(industry_probs[it] > 0); - PlaceInitialIndustry(it, false); + + /* Add the remaining industries according to their probabilities */ + for (uint i = 0; i < total_amount; i++) { + uint32_t r = RandomRange(p.total); + IndustryType it = 0; + while (r >= p.probs[it]) { + r -= p.probs[it]; + it++; + assert(it < NUM_INDUSTRYTYPES); + } + assert(p.probs[it] > 0); + PlaceInitialIndustry(it, water, false); + } + + if (water) break; } + _industry_builder.Reset(); } @@ -3119,7 +3156,7 @@ void CheckIndustries() if (Industry::GetIndustryTypeCount(it) > 0) continue; // Types of existing industries can be skipped. bool force_at_least_one; - uint32_t chance = GetScaledIndustryGenerationProbability(it, &force_at_least_one); + uint32_t chance = GetScaledIndustryGenerationProbability(it, std::nullopt, &force_at_least_one); if (chance == 0 || !force_at_least_one) continue; // Types that are not available can be skipped. const IndustrySpec *is = GetIndustrySpec(it); diff --git a/src/lang/english.txt b/src/lang/english.txt index 9385e9f4cb95e..566fc9ad012e0 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -3473,7 +3473,8 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Landscap STR_GENERATION_RIVER_GENERATION :{BLACK}River generation STR_GENERATION_CLEARING_TILES :{BLACK}Rough and rocky area generation STR_GENERATION_TOWN_GENERATION :{BLACK}Town generation -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Industry generation +STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}Land industry generation +STR_GENERATION_WATER_INDUSTRY_GENERATION :{BLACK}Water industry generation STR_GENERATION_OBJECT_GENERATION :{BLACK}Object generation STR_GENERATION_TREE_GENERATION :{BLACK}Tree generation STR_GENERATION_SETTINGUP_GAME :{BLACK}Setting up game diff --git a/src/map.cpp b/src/map.cpp index efb5168cbfe77..a6dc2af46be48 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -23,6 +23,8 @@ /* static */ uint Map::size; ///< The number of tiles on the map /* static */ uint Map::tile_mask; ///< _map_size - 1 (to mask the mapsize) +/* static */ uint Map::initial_land_count; ///< Initial number of land tiles on the map. + /* static */ std::unique_ptr Tile::base_tiles; ///< Base tiles of the map /* static */ std::unique_ptr Tile::extended_tiles; ///< Extended tiles of the map @@ -58,6 +60,20 @@ AllocateWaterRegions(); } +/* static */ void Map::CountLandTiles() +{ + /* Count number of tiles that are land. */ + Map::initial_land_count = 0; + for (const auto tile : Map::Iterate()) { + Map::initial_land_count += IsWaterTile(tile) ? 0 : 1; + } + + /* Compensate for default values being set for (or users are most familiar with) at least + * very low sea level. Dividing by 12 adds roughly 8%. */ + Map::initial_land_count += Map::initial_land_count / 12; + Map::initial_land_count = std::min(Map::initial_land_count, Map::size); +} + #ifdef _DEBUG TileIndex TileAdd(TileIndex tile, TileIndexDiff offset) diff --git a/src/map_func.h b/src/map_func.h index e1929c2f91c8e..1854de91b30fa 100644 --- a/src/map_func.h +++ b/src/map_func.h @@ -239,8 +239,11 @@ struct Map { static uint size; ///< The number of tiles on the map static uint tile_mask; ///< _map_size - 1 (to mask the mapsize) + static uint initial_land_count; ///< Initial number of land tiles on the map. + public: static void Allocate(uint size_x, uint size_y); + static void CountLandTiles(); /** * Logarithm of the map size along the X side. @@ -307,6 +310,16 @@ struct Map { return Map::SizeY() - 1; } + /** + * Scales the given value by the number of water tiles. + * @param n the value to scale + * @return the scaled size + */ + static inline uint ScaleByLandProportion(uint n) + { + /* Use 64-bit arithmetic to avoid overflow. */ + return static_cast(static_cast(n) * Map::initial_land_count / Map::size); + } /** * 'Wraps' the given "tile" so it is within the map. diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index b3c95ba053047..4ba9143c84d09 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -55,6 +55,7 @@ #include "road_cmd.h" #include "terraform_cmd.h" #include "tunnelbridge_cmd.h" +#include "map_func.h" #include "timer/timer.h" #include "timer/timer_game_calendar.h" #include "timer/timer_game_economy.h" @@ -2420,9 +2421,9 @@ bool GenerateTowns(TownLayout layout, std::optional number) if (number.has_value()) { total = number.value(); } else if (_settings_game.difficulty.number_towns == static_cast(CUSTOM_TOWN_NUMBER_DIFFICULTY)) { - total = GetDefaultTownsForMapSize(); + total = Map::ScaleByLandProportion(GetDefaultTownsForMapSize()); } else { - total = GetDefaultTownsForMapSize() + (Random() & 7); + total = Map::ScaleByLandProportion(GetDefaultTownsForMapSize() + (Random() & 7)); } total = std::min(TownPool::MAX_SIZE, total); From 7b703f688aa3771da0906cacead9f40bc1dfdce2 Mon Sep 17 00:00:00 2001 From: translators Date: Sat, 25 Oct 2025 04:38:31 +0000 Subject: [PATCH 086/137] Update: Translations from eints galician: 1 change by pvillaverde --- src/lang/afrikaans.txt | 2 +- src/lang/arabic_egypt.txt | 2 +- src/lang/basque.txt | 2 +- src/lang/belarusian.txt | 2 +- src/lang/brazilian_portuguese.txt | 10 +--------- src/lang/bulgarian.txt | 3 +-- src/lang/catalan.txt | 10 +--------- src/lang/chuvash.txt | 2 +- src/lang/croatian.txt | 2 +- src/lang/czech.txt | 3 +-- src/lang/danish.txt | 10 +--------- src/lang/dutch.txt | 10 +--------- src/lang/english_AU.txt | 10 +--------- src/lang/english_US.txt | 10 +--------- src/lang/esperanto.txt | 2 +- src/lang/estonian.txt | 3 +-- src/lang/faroese.txt | 2 +- src/lang/finnish.txt | 10 +--------- src/lang/french.txt | 10 +--------- src/lang/frisian.txt | 2 +- src/lang/gaelic.txt | 2 +- src/lang/galician.txt | 11 ++--------- src/lang/german.txt | 3 +-- src/lang/greek.txt | 10 +--------- src/lang/hebrew.txt | 3 +-- src/lang/hindi.txt | 2 +- src/lang/hungarian.txt | 10 +--------- src/lang/icelandic.txt | 2 +- src/lang/ido.txt | 2 +- src/lang/indonesian.txt | 2 +- src/lang/irish.txt | 2 +- src/lang/italian.txt | 4 +--- src/lang/japanese.txt | 2 +- src/lang/korean.txt | 10 +--------- src/lang/latin.txt | 2 +- src/lang/latvian.txt | 10 +--------- src/lang/lithuanian.txt | 3 +-- src/lang/luxembourgish.txt | 3 +-- src/lang/macedonian.txt | 2 +- src/lang/malay.txt | 2 +- src/lang/maltese.txt | 2 +- src/lang/maori.txt | 8 +------- src/lang/marathi.txt | 2 +- src/lang/norwegian_bokmal.txt | 10 +--------- src/lang/norwegian_nynorsk.txt | 2 +- src/lang/persian.txt | 2 +- src/lang/polish.txt | 10 +--------- src/lang/portuguese.txt | 10 +--------- src/lang/romanian.txt | 3 +-- src/lang/russian.txt | 10 +--------- src/lang/serbian.txt | 2 +- src/lang/simplified_chinese.txt | 10 +--------- src/lang/slovak.txt | 3 +-- src/lang/slovenian.txt | 2 +- src/lang/spanish.txt | 3 +-- src/lang/spanish_MX.txt | 3 +-- src/lang/swedish.txt | 10 +--------- src/lang/tamil.txt | 2 +- src/lang/thai.txt | 2 +- src/lang/traditional_chinese.txt | 10 +--------- src/lang/turkish.txt | 3 +-- src/lang/ukrainian.txt | 3 +-- src/lang/urdu.txt | 2 +- src/lang/vietnamese.txt | 10 +--------- src/lang/welsh.txt | 3 +-- 65 files changed, 66 insertions(+), 255 deletions(-) diff --git a/src/lang/afrikaans.txt b/src/lang/afrikaans.txt index 9c98637e2381c..fe8ec701556e3 100644 --- a/src/lang/afrikaans.txt +++ b/src/lang/afrikaans.txt @@ -1839,7 +1839,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Hoogte eenheid: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Wanneer 'n hoogte word in die gebruikerskoppelvlak, wys dit in die geselekteerde eenhede -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Empiries (vt) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metries (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) diff --git a/src/lang/arabic_egypt.txt b/src/lang/arabic_egypt.txt index 0a1b38a540477..6323e068fc7f1 100644 --- a/src/lang/arabic_egypt.txt +++ b/src/lang/arabic_egypt.txt @@ -1716,7 +1716,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE ::وحدات ج STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_IMPERIAL :إمبراطوري (lbf) STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_METRIC :متري (كغ - قوة) -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :إمبراطوري (قدم) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :متري (م) diff --git a/src/lang/basque.txt b/src/lang/basque.txt index 7c6f5ec08d682..4267f20101f41 100644 --- a/src/lang/basque.txt +++ b/src/lang/basque.txt @@ -1731,7 +1731,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_METRIC :Metrikoa (kgf) STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Garaiera unitateak: {STRING} -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Inperiala (oin) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrikoa (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) diff --git a/src/lang/belarusian.txt b/src/lang/belarusian.txt index 814bd6c5752c5..22cd4a442dd28 100644 --- a/src/lang/belarusian.txt +++ b/src/lang/belarusian.txt @@ -2414,7 +2414,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :СІ (кН) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Сыстэма адзінак для вышыні: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Паказваць значэньні вышыні ў абранай сыстэме адзінак -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :ангельская (фут) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :мэтрычная (м) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :СІ (м) diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index d3b6f76991d72..ffe13e3f947b7 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -2159,7 +2159,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Unidades de altura: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Sempre que uma altura for exibida na interface do usuário, mostrar nessas unidades -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Métrico (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3472,7 +3472,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Geraçã STR_GENERATION_RIVER_GENERATION :{BLACK}Geração de rios STR_GENERATION_CLEARING_TILES :{BLACK}Geração de áreas irregulares e rochosas STR_GENERATION_TOWN_GENERATION :{BLACK}Geração de localidades -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Geração de indústrias STR_GENERATION_OBJECT_GENERATION :{BLACK}Geração de objetos STR_GENERATION_TREE_GENERATION :{BLACK}Geração de árvores STR_GENERATION_SETTINGUP_GAME :{BLACK}Configurando o jogo @@ -5270,13 +5269,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Início STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... os extremos da ponte devem estar sobre a terra STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... ponte muito longa STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}A ponte terminaria fora do mapa -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Ponte é muito baixa para uma estação -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Ponte é muito baixa para uma parada rodoviária -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}A ponte é muito baixa para a doca -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Ponte é muito baixa para uma boia -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Ponte é muito baixa para um ponto de controle ferroviário -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Ponte é muito baixa para um ponto de controle rodoviário -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}A ponte é muito baixa para eclusa # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Não é possível construir túnel aqui... diff --git a/src/lang/bulgarian.txt b/src/lang/bulgarian.txt index a45f727b20a26..1975b3a0faa7a 100644 --- a/src/lang/bulgarian.txt +++ b/src/lang/bulgarian.txt @@ -2125,7 +2125,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Мерни единици за височина: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Показваните височини ще бъдат изписвани в избраните мерни единици -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Имперски (фут) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Метрични (м) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (м) @@ -3400,7 +3400,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Гене STR_GENERATION_RIVER_GENERATION :{BLACK}Генериране на реки STR_GENERATION_CLEARING_TILES :{BLACK}Генериране на твърда и скална повърност STR_GENERATION_TOWN_GENERATION :{BLACK}Генерация на град -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Генерация на индустрията STR_GENERATION_OBJECT_GENERATION :{BLACK}Генериране на обекти STR_GENERATION_TREE_GENERATION :{BLACK}Генериране на дървета STR_GENERATION_SETTINGUP_GAME :{BLACK}Настройване на играта diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index 24174ac869fd5..2835c09afd905 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -2159,7 +2159,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Unitats de longitud: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Quan es mostren longituds a la interfície d'usuari, presenta-les en les unitats seleccionades -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (peu) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Mètric (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3472,7 +3472,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Generaci STR_GENERATION_RIVER_GENERATION :{BLACK}Generació de rius STR_GENERATION_CLEARING_TILES :{BLACK}Generació d'una àrea escarpada i rocosa STR_GENERATION_TOWN_GENERATION :{BLACK}Generació de poblacions -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Generació d'indústries STR_GENERATION_OBJECT_GENERATION :{BLACK}Generació inamovible STR_GENERATION_TREE_GENERATION :{BLACK}Generació d'arbres STR_GENERATION_SETTINGUP_GAME :{BLACK}Configurant la partida @@ -5270,13 +5269,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Inici i STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... els extrems del pont han d'estar tots dos a terra STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... el pont és massa llarg STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}El pont acabaria fora del mapa -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}El pont està massa baix per a l'estació. -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}El pont està massa baix per a la parada. -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}El pont és massa baix per al port. -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}El pont està massa baix per a la boia. -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}El pont està massa baix per al punt de pas. -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}El pont està massa baix per al punt de pas de carretera. -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}El pont és massa baix per a la resclosa. # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Aquí no es pot construir el túnel... diff --git a/src/lang/chuvash.txt b/src/lang/chuvash.txt index 4ba7521f992bf..49bc9aeb81183 100644 --- a/src/lang/chuvash.txt +++ b/src/lang/chuvash.txt @@ -853,7 +853,7 @@ STR_CONFIG_SETTING_TOWN_GROWTH_VERY_FAST :Питӗ хӑв ###length 3 -###length 3 +###length 4 STR_CONFIG_SETTING_INTERFACE :Интерфейс STR_CONFIG_SETTING_INTERFACE_CONSTRUCTION :Лартӑм diff --git a/src/lang/croatian.txt b/src/lang/croatian.txt index 2fcb9bb0b3400..7bc156fb652e2 100644 --- a/src/lang/croatian.txt +++ b/src/lang/croatian.txt @@ -1958,7 +1958,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Jedinice visine: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Uvijek kada je visina prikazana u korisničkom sučelju, prikaži je u odabranim jedinicama -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperijalni (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrički (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) diff --git a/src/lang/czech.txt b/src/lang/czech.txt index 06d4ae0371061..fd987da743e1d 100644 --- a/src/lang/czech.txt +++ b/src/lang/czech.txt @@ -2211,7 +2211,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Výškové jednotky: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Kdykoliv se v uživatelském rozhraní zobrazí výška, bude ve zvolených jednotkách -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperiální (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrické (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3508,7 +3508,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Generov STR_GENERATION_RIVER_GENERATION :{BLACK}Generování řek STR_GENERATION_CLEARING_TILES :{BLACK}Tvorba členitého a kamenitého území STR_GENERATION_TOWN_GENERATION :{BLACK}Generování měst -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Generování průmyslu STR_GENERATION_OBJECT_GENERATION :{BLACK}Výstavba nepřesunutelných objektů STR_GENERATION_TREE_GENERATION :{BLACK}Výsadba stromů STR_GENERATION_SETTINGUP_GAME :{BLACK}Nastavování hry diff --git a/src/lang/danish.txt b/src/lang/danish.txt index 066774cc60d0d..c870b469880de 100644 --- a/src/lang/danish.txt +++ b/src/lang/danish.txt @@ -2158,7 +2158,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Højdeenheder: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Når højde er vist i brugergrænsefladen, så vis dem i de valgte enheder -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperisk (fod) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrisk (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3471,7 +3471,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Landskab STR_GENERATION_RIVER_GENERATION :{BLACK}Flod-generering STR_GENERATION_CLEARING_TILES :{BLACK}Generer råt og stenet område STR_GENERATION_TOWN_GENERATION :{BLACK}By generation -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Industri generation STR_GENERATION_OBJECT_GENERATION :{BLACK}Ikke-flytbar generering STR_GENERATION_TREE_GENERATION :{BLACK}Trægenerering STR_GENERATION_SETTINGUP_GAME :{BLACK}Klargør spil @@ -5269,13 +5268,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Start- o STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... begge ender af en bro skal være på land STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... broen er for lang STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Broen ville slutte udenfor kortet -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Broen er for lav til en station -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Broen er for lav til et vej stoppested -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Broen er for lav til havnen -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Broen er for lav til en bøje -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Broen er for lav til et rutepunkt -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Broen er for lav til et rutepunkt -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Bro er for lav til at låse # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Kan ikke bygge en tunnel her... diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt index db922cb60287d..2fe998bbebd4d 100644 --- a/src/lang/dutch.txt +++ b/src/lang/dutch.txt @@ -2158,7 +2158,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Hoogte-eenheden: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Wanneer hoogtes worden weergegeven in het gebruikersscherm, gebruik dan de geselecteerde eenheden -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperiaal (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrisch (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3471,7 +3471,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Landscha STR_GENERATION_RIVER_GENERATION :{BLACK}Rivierplaatsing STR_GENERATION_CLEARING_TILES :{BLACK}Ontwikkeling van ruig en rotsachtig gebied STR_GENERATION_TOWN_GENERATION :{BLACK}Steden genereren -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Industrieën genereren STR_GENERATION_OBJECT_GENERATION :{BLACK}Ontwikkeling van onverplaatsbare objecten STR_GENERATION_TREE_GENERATION :{BLACK}Bosplaatsing STR_GENERATION_SETTINGUP_GAME :{BLACK}Spel wordt geconfigureerd @@ -5269,13 +5268,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Begin en STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... uiteinden van brug moeten beiden op land zijn STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... brug te lang STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Brug zou eindigen buiten de kaart -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Brug te laag voor station -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Brug te laag voor halte -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}De brug is te laag voor haven -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Brug te laag voor boei -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Brug te laag voor spoorroutepunt -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Brug te laag voor wegroutepunt -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Brug te laag voor sluis # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Kan hier geen tunnel bouwen... diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt index 10cc0ac016a00..087a675509b10 100644 --- a/src/lang/english_AU.txt +++ b/src/lang/english_AU.txt @@ -2158,7 +2158,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Heights units: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Whenever heights are shown in the user interface, show it in the selected units -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metric (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3471,7 +3471,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Landscap STR_GENERATION_RIVER_GENERATION :{BLACK}River generation STR_GENERATION_CLEARING_TILES :{BLACK}Rough and rocky area generation STR_GENERATION_TOWN_GENERATION :{BLACK}Town generation -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Industry generation STR_GENERATION_OBJECT_GENERATION :{BLACK}Object generation STR_GENERATION_TREE_GENERATION :{BLACK}Tree generation STR_GENERATION_SETTINGUP_GAME :{BLACK}Setting up game @@ -5269,13 +5268,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Start an STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... ends of bridge must both be on land STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... bridge too long STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Bridge would end out of the map -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Bridge is too low for station -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Bridge is too low for road stop -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Bridge is too low for dock -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Bridge is too low for buoy -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Bridge is too low for rail waypoint -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Bridge is too low for road waypoint -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Bridge is too low for lock # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Can't build tunnel here... diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index 3640eda96ce69..3528b41f3f060 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -2158,7 +2158,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Heights units: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Whenever a height is shown in the user interface, show it in the selected units -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metric (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3471,7 +3471,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Landscap STR_GENERATION_RIVER_GENERATION :{BLACK}River generation STR_GENERATION_CLEARING_TILES :{BLACK}Rough and rocky area generation STR_GENERATION_TOWN_GENERATION :{BLACK}Town generation -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Industry generation STR_GENERATION_OBJECT_GENERATION :{BLACK}Object generation STR_GENERATION_TREE_GENERATION :{BLACK}Tree generation STR_GENERATION_SETTINGUP_GAME :{BLACK}Setting up game @@ -5269,13 +5268,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Start an STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... ends of bridge must both be on land STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... bridge too long STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Bridge would end out of the map -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Bridge is too low for station -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Bridge is too low for road stop -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Bridge is too low for dock -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Bridge is too low for buoy -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Bridge is too low for rail waypoint -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Bridge is too low for road waypoint -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Bridge is too low for lock # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Can't build tunnel here... diff --git a/src/lang/esperanto.txt b/src/lang/esperanto.txt index f8ee39b52d70a..8898cf08644d5 100644 --- a/src/lang/esperanto.txt +++ b/src/lang/esperanto.txt @@ -2099,7 +2099,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI-unuoj (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Altecunuoj: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Kiam ajn montriĝas alteco en la uzantinterfaco, montru ĝin en la indikitaj unuoj -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Angla-usona sistemo (futoj) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metra (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI-unuoj (m) diff --git a/src/lang/estonian.txt b/src/lang/estonian.txt index 7c4f76532189c..24edd3e26da02 100644 --- a/src/lang/estonian.txt +++ b/src/lang/estonian.txt @@ -2163,7 +2163,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI-süsteem (kN STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Kõrgusühikud: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Liideses näidatakse kõrgust valitud mõõdustikus -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Inglise mõõdustik (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Meetermõõdustik (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI-süsteem (m) @@ -3418,7 +3418,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Maastiku STR_GENERATION_RIVER_GENERATION :{BLACK}Jõgede tekitamine STR_GENERATION_CLEARING_TILES :{BLACK}Mägise ja kivise maa-ala tekitamine STR_GENERATION_TOWN_GENERATION :{BLACK}Asulate tekitamine -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Tööstuse tekitamine STR_GENERATION_OBJECT_GENERATION :{BLACK}Objekti tekitamine STR_GENERATION_TREE_GENERATION :{BLACK}Puude tekitamine STR_GENERATION_SETTINGUP_GAME :{BLACK}Mängu seadistamine diff --git a/src/lang/faroese.txt b/src/lang/faroese.txt index 439b1d04ddaef..b2b65047adb36 100644 --- a/src/lang/faroese.txt +++ b/src/lang/faroese.txt @@ -1675,7 +1675,7 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Eingin ###length 3 -###length 3 +###length 4 STR_CONFIG_SETTING_SOUND :Ljóð effektir STR_CONFIG_SETTING_INTERFACE :Takførisflati diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index 6427a51c2af81..f0de21e757223 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -2158,7 +2158,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Korkeuden yksikkö: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Kun käyttöliittymässä näytetään korkeus, näytä se valittua yksikköä käyttäen -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Brittiläinen (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrinen (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3471,7 +3471,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Maaston STR_GENERATION_RIVER_GENERATION :{BLACK}Jokien luominen STR_GENERATION_CLEARING_TILES :{BLACK}Karun ja kivisen alueen luominen STR_GENERATION_TOWN_GENERATION :{BLACK}Kuntien luominen -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Tuotantolaitosten luominen STR_GENERATION_OBJECT_GENERATION :{BLACK}Siirtämättömän luominen STR_GENERATION_TREE_GENERATION :{BLACK}Puiden luominen STR_GENERATION_SETTINGUP_GAME :{BLACK}Valmistellaan peliä @@ -5269,13 +5268,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Alku- ja STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... sillan molempien päiden pitää sijaita maalla. STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... silta liian pitkä STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Silta päättyisi kartan ulkopuolelle -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Silta on liian matala aseman ylle -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Silta on liian matala pysäkin ylle -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Silta on liian matala sataman ylle -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Silta on liian matala poijun ylle -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Silta on liian matala rautatien reittipisteen ylle -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Silta on liian matala tien reittipisteen ylle -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Silta on liian matala sulun ylle # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Tunnelia ei voi rakentaa... diff --git a/src/lang/french.txt b/src/lang/french.txt index d9b622afd8aeb..235e21f98ed3f 100644 --- a/src/lang/french.txt +++ b/src/lang/french.txt @@ -2159,7 +2159,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Unité de hauteur{NBSP}: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Quand une hauteur est affichée dans l'interface utilisateur, utiliser l'unité sélectionnée -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Impérial (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Métrique (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3472,7 +3472,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Généra STR_GENERATION_RIVER_GENERATION :{BLACK}Création des rivières STR_GENERATION_CLEARING_TILES :{BLACK}Création des zones rugueuses et rocheuses STR_GENERATION_TOWN_GENERATION :{BLACK}Génération des villes -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Génération des industries STR_GENERATION_OBJECT_GENERATION :{BLACK}Création des objets inamovibles STR_GENERATION_TREE_GENERATION :{BLACK}Création des arbres STR_GENERATION_SETTINGUP_GAME :{BLACK}Configuration du jeu @@ -5270,13 +5269,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Le débu STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... les deux extrémités du pont doivent être sur la terre ferme STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... pont trop long STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Le pont finirait en dehors de la carte -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Le pont est trop bas pour les gares -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Le pont est trop bas pour les arrêts de bus -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Le pont est trop bas pour le port -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Le pont est trop bas pour les bouées -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Le pont est trop bas pour les points de contrôle -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Le pont est trop bas pour les points de contrôle de route -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Ce pont est trop bas pour le verrouillage # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Impossible de construire un tunnel ici... diff --git a/src/lang/frisian.txt b/src/lang/frisian.txt index 75a2cb27ac217..6b3fc822a5b80 100644 --- a/src/lang/frisian.txt +++ b/src/lang/frisian.txt @@ -1785,7 +1785,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Hichte-ienheid: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Wannear't der hichten sichtber binne yn de interface de selektearre ienheiden brûke -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Ymperiaal (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrysk (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) diff --git a/src/lang/gaelic.txt b/src/lang/gaelic.txt index 9f6df83f83a30..c747f8bc6a186 100644 --- a/src/lang/gaelic.txt +++ b/src/lang/gaelic.txt @@ -2011,7 +2011,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Aonadan àirde: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Nuair a thèid àirde a shealltainn san eadar-aghaidh, seall i leis na h-aonadan a thagh thu -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Impireil (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Meatrach (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) diff --git a/src/lang/galician.txt b/src/lang/galician.txt index c4ec239fcd84f..79258e6b87dd9 100644 --- a/src/lang/galician.txt +++ b/src/lang/galician.txt @@ -2159,7 +2159,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Unidades para a altura (cota): {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Cando as cotas se amosen na interfaz de usuario, facelo coas unidades seleccionadas -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Métrico (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3472,7 +3472,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Xeració STR_GENERATION_RIVER_GENERATION :{BLACK}Xeración de ríos STR_GENERATION_CLEARING_TILES :{BLACK}Xeración de áreas rochosas e escarpadas STR_GENERATION_TOWN_GENERATION :{BLACK}Xeración de vilas -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Xeración da industria STR_GENERATION_OBJECT_GENERATION :{BLACK}Xeración de obxectos STR_GENERATION_TREE_GENERATION :{BLACK}Xeración de árbores STR_GENERATION_SETTINGUP_GAME :{BLACK}Configurando partida @@ -3692,6 +3691,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Escribe STR_TOWN_DIRECTORY_CAPTION :{WHITE}Vilas ({COMMA} de {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Ningunha - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA}) {YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Nomes de vilas - pincha no nome para centrar a vista na vila. Ctrl+Clic abre unha nova fiestra na localización da vila STR_TOWN_POPULATION :{BLACK}Poboación mundial: {COMMA} @@ -5269,13 +5269,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}O inicio STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... ambos extremos da ponte deben estar en terra STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... ponte demasiado longa STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}A ponte remataría fóra do mapa -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}A ponte é demasiado baixa para a estación -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}A ponte é demasiado baixa para unha estación de estrada -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}A ponte é moi baixa para o porto -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}A ponte é demasiado baixa para a boia -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}A ponte é demasiado baixa para un punto de ruta de ferrocarril -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}A ponte é demasiado baixa para un punto de ruta de estrada -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}A ponte é moi baixa para a exclusa # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Non se pode construír un túnel aí... diff --git a/src/lang/german.txt b/src/lang/german.txt index 53da600dc2188..ff17c31330294 100644 --- a/src/lang/german.txt +++ b/src/lang/german.txt @@ -2157,7 +2157,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Höheneinheiten: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Immer wenn Höhen angezeigt werden, sie in den gewählten Einheiten anzeigen -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrisch (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3467,7 +3467,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Landscha STR_GENERATION_RIVER_GENERATION :{BLACK}Flussgenerierung STR_GENERATION_CLEARING_TILES :{BLACK}Raue, felsige Landschaft wird erzeugt STR_GENERATION_TOWN_GENERATION :{BLACK}Stadterzeugung -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Industrieerzeugung STR_GENERATION_OBJECT_GENERATION :{BLACK}Unbewegliche Objekte werden erzeugt STR_GENERATION_TREE_GENERATION :{BLACK}Bäume werden erzeugt STR_GENERATION_SETTINGUP_GAME :{BLACK}Spiel wird vorbereitet diff --git a/src/lang/greek.txt b/src/lang/greek.txt index 5ec9e6777016f..6d4ebdff5335a 100644 --- a/src/lang/greek.txt +++ b/src/lang/greek.txt @@ -2251,7 +2251,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Μονάδες μέτρησης ύψους: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Όποτε εμφανίζεται ένα ύψος στη διεπαφή χρήστη, να εμφανίζεται στην επιλεγμένη μονάδα -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Αυτοκρατορικό (πόδια) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Μετρικό (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3564,7 +3564,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Δημι STR_GENERATION_RIVER_GENERATION :{BLACK}Δημιουργία ποταμού STR_GENERATION_CLEARING_TILES :{BLACK}Δημιουργία άγριας και πετρώδης περιοχής STR_GENERATION_TOWN_GENERATION :{BLACK}Δημιουργία πόλης -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Δημιουργία βιομηχανίας STR_GENERATION_OBJECT_GENERATION :{BLACK}Δημιουργία μη μετακινούμενων STR_GENERATION_TREE_GENERATION :{BLACK}Δημιουργία δέντρων STR_GENERATION_SETTINGUP_GAME :{BLACK}Ρύθμιση παιχνιδιού @@ -5370,13 +5369,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Η αρ STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... και τα δύο άκρα της γέφυρας πρέπει να είναι σε έδαφος STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... η γέφυρα είναι πολλή μακριά STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Η γέφυρα θα καταλήξει εκτός χάρτη -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Η γέφυρα είναι πολύ χαμηλή για σταθμό -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Η γέφυρα είναι πολύ χαμηλή για οδική στάση -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Η γέφυρα είναι πολύ χαμηλή για αποβάθρα -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Η γέφυρα είναι πολύ χαμηλή για σημαδούρα -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Η γέφυρα είναι πολύ χαμηλή για σιδηροδρομικό σημείο αναφοράς -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Η γέφυρα είναι πολύ χαμηλή για οδικό σημείο αναφοράς -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Η γέφυρα είναι πολύ χαμηλή για κλείδωμα # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Δεν μπορεί να κατασκευαστεί σήραγγα εδώ... diff --git a/src/lang/hebrew.txt b/src/lang/hebrew.txt index 2347dcba42201..fe2efa775ce2e 100644 --- a/src/lang/hebrew.txt +++ b/src/lang/hebrew.txt @@ -1939,7 +1939,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :בינלאומ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :יחידות גובה: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :כאשר מוצגים גבהים השתמש ביחידות שנבחרו -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :בריטית (רגל) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :מטרי (מטר) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (מטר) @@ -3082,7 +3082,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}יציר STR_GENERATION_RIVER_GENERATION :{BLACK}יצירת נהרות STR_GENERATION_CLEARING_TILES :{BLACK}יצירת איזורים סלעיים STR_GENERATION_TOWN_GENERATION :{BLACK}יצירת עיירה -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}יצירת תעשייה STR_GENERATION_OBJECT_GENERATION :{BLACK}יצירת מבנים בלתי ניידים STR_GENERATION_TREE_GENERATION :{BLACK}יצירת עצים STR_GENERATION_SETTINGUP_GAME :{BLACK}קביעת הגדרות המשחק diff --git a/src/lang/hindi.txt b/src/lang/hindi.txt index 7d1a61c12fcff..c103ddcb04793 100644 --- a/src/lang/hindi.txt +++ b/src/lang/hindi.txt @@ -719,7 +719,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_SI :अंतर् ###length 3 -###length 3 +###length 4 STR_CONFIG_SETTING_INTERFACE_GENERAL :सामान्य STR_CONFIG_SETTING_COMPANY :कंपनी diff --git a/src/lang/hungarian.txt b/src/lang/hungarian.txt index 167ffc89fb604..a7269ea7e51e8 100644 --- a/src/lang/hungarian.txt +++ b/src/lang/hungarian.txt @@ -2222,7 +2222,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Hosszúság mértékegysége: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :A magassági értékek a kiválasztott mértékegységben fognak megjelenni a felhasználói felületen -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Angolszász (láb) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrikus (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3535,7 +3535,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Tájkép STR_GENERATION_RIVER_GENERATION :{BLACK}Folyó generálás STR_GENERATION_CLEARING_TILES :{BLACK}Durva és köves területek generálása STR_GENERATION_TOWN_GENERATION :{BLACK}Város generálás -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Ipar generálás STR_GENERATION_OBJECT_GENERATION :{BLACK}Mozgathatatlan létesítmények létrehozása STR_GENERATION_TREE_GENERATION :{BLACK}Fák generálása STR_GENERATION_SETTINGUP_GAME :{BLACK}Játék beállítása @@ -5333,13 +5332,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}A kezdet STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... a híd mindkét végének szárazföldön kell lennie STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... a híd túl hosszú STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}A híd a térképen túl végződne -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}A híd túl alacsony az állomáshoz -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}A híd túl alacsony a megállóhoz -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}A híd túl alacsony a kikötőhöz -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}A híd túl alacsony a bójához -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}A híd túl alacsony a vasúti ellenőrzőponthoz -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}BA híd túl alacsony az útponthoz -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}A híd túl alacsony a zároláshoz # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Nem áshatsz ide alagutat... diff --git a/src/lang/icelandic.txt b/src/lang/icelandic.txt index eeb4f28dd7654..d76cab670b860 100644 --- a/src/lang/icelandic.txt +++ b/src/lang/icelandic.txt @@ -1700,7 +1700,7 @@ STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Meðalstærð b ###length 3 -###length 3 +###length 4 STR_CONFIG_SETTING_SOUND :Hljóð STR_CONFIG_SETTING_INTERFACE :Viðmót diff --git a/src/lang/ido.txt b/src/lang/ido.txt index 9ce3042cabbcd..6a2107860f1eb 100644 --- a/src/lang/ido.txt +++ b/src/lang/ido.txt @@ -822,7 +822,7 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violkolora ###length 3 -###length 3 +###length 4 diff --git a/src/lang/indonesian.txt b/src/lang/indonesian.txt index f0f0168d50cea..4f6fb8ee18951 100644 --- a/src/lang/indonesian.txt +++ b/src/lang/indonesian.txt @@ -2056,7 +2056,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Satuan ketinggian: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Apabila ketinggian ditampilkan di antarmuka, nyatakan di satuan yang dipilih -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrik (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) diff --git a/src/lang/irish.txt b/src/lang/irish.txt index 69038bddc3bd7..c11a13d9b35a0 100644 --- a/src/lang/irish.txt +++ b/src/lang/irish.txt @@ -1913,7 +1913,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Aonaid airde: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Aon áit a thaispeántar airde sa chomhéadan úsáideora, taispeain sna haonaid roghnaithe í -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Impiriúil (tr) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Méadrach (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) diff --git a/src/lang/italian.txt b/src/lang/italian.txt index caca85805185a..7ed8445e02947 100644 --- a/src/lang/italian.txt +++ b/src/lang/italian.txt @@ -2172,7 +2172,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Unità di altezza: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Seleziona le unità di misura da utilizzare per mostrare le altezze nell'interfaccia utente -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperiali (piedi) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metriche (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3469,7 +3469,6 @@ STR_GENERATION_WORLD_GENERATION :{BLACK}Generazi STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Generazione paesaggio STR_GENERATION_RIVER_GENERATION :{BLACK}Generazione fiumi STR_GENERATION_CLEARING_TILES :{BLACK}Generazione aree brulle e rocciose -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Generazione industrie STR_GENERATION_OBJECT_GENERATION :{BLACK}Generazione oggetti inamovibili STR_GENERATION_TREE_GENERATION :{BLACK}Generazione alberi STR_GENERATION_SETTINGUP_GAME :{BLACK}Impostazione partita @@ -5247,7 +5246,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Inizio e STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... gli estremi del ponte devono trovarsi entrambi sul terreno STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... ponte troppo lungo STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Il ponte terminerebbe fuori dalla mappa -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Ponte troppo basso per una fermata # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Impossibile costruire il tunnel qui... diff --git a/src/lang/japanese.txt b/src/lang/japanese.txt index a3dc9d420735e..61999a9fbe93e 100644 --- a/src/lang/japanese.txt +++ b/src/lang/japanese.txt @@ -2011,7 +2011,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :国際単位系 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :距離単位: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :ゲーム中の高度をいずれの単位系で表すか決定します -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :ヤード・ポンド法 (フィート(ft)) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :メートル法 (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :国際単位系 (m) diff --git a/src/lang/korean.txt b/src/lang/korean.txt index e0bb797da5d53..6faf58f355974 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -2159,7 +2159,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :국제표준규 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :높이 단위: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :높이를 표시할 때 선택한 단위를 사용하여 나타냅니다 -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :야드파운드법 (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :미터법 (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :국제표준규격 (m) @@ -3472,7 +3472,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}지형 STR_GENERATION_RIVER_GENERATION :{BLACK}강 제작 STR_GENERATION_CLEARING_TILES :{BLACK}거친 암석지대 만드는 중 STR_GENERATION_TOWN_GENERATION :{BLACK}도시 생성 -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}산업시설 생성 STR_GENERATION_OBJECT_GENERATION :{BLACK}움직일수 없는 객체 만드는 중 STR_GENERATION_TREE_GENERATION :{BLACK}나무 심는 중 STR_GENERATION_SETTINGUP_GAME :{BLACK}게임 설정 중 @@ -5270,13 +5269,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}시작 STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... 다리의 양 끝은 모두 땅이어야 합니다 STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... 다리가 너무 깁니다! STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}다리 끝이 지도 밖을 넘어갑니다 -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}다리 밑에 역을 두기에는 다리 높이가 너무 낮습니다 -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}다리 밑에 도로 정류장을 두기에는 다리 높이가 너무 낮습니다 -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}다리 밑에 항구를 두기에는 다리 높이가 너무 낮습니다 -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}다리 밑에 부표를 두기에는 다리 높이가 너무 낮습니다 -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}다리 밑에 철도 경유지를 두기에는 다리 높이가 너무 낮습니다 -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}다리 밑에 도로 경유지를 두기에는 다리 높이가 너무 낮습니다 -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}다리 밑에 항구를 두기에는 다리 높이가 너무 낮습니다 # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}여기에 터널을 지을 수 없습니다... diff --git a/src/lang/latin.txt b/src/lang/latin.txt index e9c79abb82ec1..43c99cba6036b 100644 --- a/src/lang/latin.txt +++ b/src/lang/latin.txt @@ -2013,7 +2013,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Unitates altitudinis: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Quandocumque altitudo monstratur, monstrabitur his unitatibus electis -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Anglicae (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metricae (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) diff --git a/src/lang/latvian.txt b/src/lang/latvian.txt index 95111c22df265..8422f4c211919 100644 --- a/src/lang/latvian.txt +++ b/src/lang/latvian.txt @@ -2162,7 +2162,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI, starptautis STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Augstuma mērvienības: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Kad lietotāja saskarnē rāda augstumu, uzrādīt to norādītajās mērvienībās -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :impērijas, britu (pēda) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :metriskās (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI, starptautiskās (m) @@ -3476,7 +3476,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Ainavu v STR_GENERATION_RIVER_GENERATION :{BLACK}Upes radīšana STR_GENERATION_CLEARING_TILES :{BLACK}Nelīdzena un akmeņaina apvidus radīšana STR_GENERATION_TOWN_GENERATION :{BLACK}Pilsētas veidošana -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Nozares veidošana STR_GENERATION_OBJECT_GENERATION :{BLACK}Objekta radīšana STR_GENERATION_TREE_GENERATION :{BLACK}Koka radīšana STR_GENERATION_SETTINGUP_GAME :{BLACK}Iestatīt spēli @@ -5280,13 +5279,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Sākumam STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... abiem tilta galiem jābūt uz zemes STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... tilts ir pārāk garš STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Tilts beigtos ārpus kartes -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Tilts ir pārāk zems stacijai -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Tilts ir pārāk zems, ceļa pieturai -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Tilts ir pārāk zems piestātnei -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Tilts ir pārāk zems bojai -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Tilts ir pārāk zems dzelzceļa pieturas punktam -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Tilts ir pārāk zems ceļa punktam -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Tilts ir pārāk zems slūžām # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Šeit nevar būvēt tuneli... diff --git a/src/lang/lithuanian.txt b/src/lang/lithuanian.txt index 70b83009e7efc..c4c4d96a55301 100644 --- a/src/lang/lithuanian.txt +++ b/src/lang/lithuanian.txt @@ -2274,7 +2274,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Aukščio vienetai: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Vienetai, kuriais matuojamas aukštis -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :imperiniai (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :metriniai (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3503,7 +3503,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Peizažo STR_GENERATION_RIVER_GENERATION :{BLACK}Upių generavimas STR_GENERATION_CLEARING_TILES :{BLACK}Daubų ir uolų generacija STR_GENERATION_TOWN_GENERATION :{BLACK}Miestų generavimas -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Pramonės generavimas STR_GENERATION_OBJECT_GENERATION :{BLACK}Nejudinama generacija STR_GENERATION_TREE_GENERATION :{BLACK}Medžių generacija STR_GENERATION_SETTINGUP_GAME :{BLACK}Sukurti zaidima diff --git a/src/lang/luxembourgish.txt b/src/lang/luxembourgish.txt index 3b7b5fafa1d14..db4bb0e90d2bc 100644 --- a/src/lang/luxembourgish.txt +++ b/src/lang/luxembourgish.txt @@ -2131,7 +2131,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Héichteneenheeten: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Emmer wann Héichten am Userinterface ugewisen ginn, weis se an den ausgewielten Eenheeten un -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Britesch (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metresch (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3427,7 +3427,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Landscha STR_GENERATION_RIVER_GENERATION :{BLACK}Generéiren vu Flëss STR_GENERATION_CLEARING_TILES :{BLACK}Generatioun vu knubbelegem a stengege Land STR_GENERATION_TOWN_GENERATION :{BLACK}Stiedgeneratioun -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Industriegeneratioun STR_GENERATION_OBJECT_GENERATION :{BLACK}Objets-Generatioun STR_GENERATION_TREE_GENERATION :{BLACK}Baam Generatioun STR_GENERATION_SETTINGUP_GAME :{BLACK}Spill gëtt opgestallt diff --git a/src/lang/macedonian.txt b/src/lang/macedonian.txt index 18b63a7eae95a..24b1becdcb7db 100644 --- a/src/lang/macedonian.txt +++ b/src/lang/macedonian.txt @@ -1136,7 +1136,7 @@ STR_CONFIG_SETTING_ZOOM_LVL_OUT_8X :8x ###length 3 -###length 3 +###length 4 diff --git a/src/lang/malay.txt b/src/lang/malay.txt index 27ca9a08525e8..5da82b66f22d4 100644 --- a/src/lang/malay.txt +++ b/src/lang/malay.txt @@ -1593,7 +1593,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_VOLUME_SI :Unit SI (m³) ###length 3 -###length 3 +###length 4 STR_CONFIG_SETTING_SOUND :Bunyi STR_CONFIG_SETTING_INTERFACE :Antaramuka (Interface) diff --git a/src/lang/maltese.txt b/src/lang/maltese.txt index 597ed222da70d..7d41aa8c9c014 100644 --- a/src/lang/maltese.txt +++ b/src/lang/maltese.txt @@ -754,7 +754,7 @@ STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS_HELPTEXT :Ippermetti l-uz ###length 3 -###length 3 +###length 4 diff --git a/src/lang/maori.txt b/src/lang/maori.txt index 69e81d94e7f47..c48be32287fe2 100644 --- a/src/lang/maori.txt +++ b/src/lang/maori.txt @@ -2158,7 +2158,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Waeine teitei: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Ina whakaaria he teitei i te tāhono kaiwhakamahi, whakaaria i te waeine kua tīpakona -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Ingarangi (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Ngahuru (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3468,7 +3468,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Hanga wh STR_GENERATION_RIVER_GENERATION :{BLACK}Hanga awa STR_GENERATION_CLEARING_TILES :{BLACK}Hanga rohe tuarangaranga, tokatoka hoki STR_GENERATION_TOWN_GENERATION :{BLACK}Hanga tāone -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Hanga ahumahi STR_GENERATION_OBJECT_GENERATION :{BLACK}Hanga mea STR_GENERATION_TREE_GENERATION :{BLACK}Hanga rākau STR_GENERATION_SETTINGUP_GAME :{BLACK}Whakatatū i te kēmu @@ -5263,11 +5262,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Me tōti STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... me tū ki te whenua ngā pito e rua o te arawhiti STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... he roa rawa te arawhiti STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Ka mutu te arawhiti i waho i te mahere -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}He hakahaka rawa te arawhiti mō te teihana -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}He hakahaka rawa te arawhiti mō te tūnga rori -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}He hakahaka rawa te arawhiti mō te kārewa -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}He hakahaka rawa te arawhiti mō te aratohu rerewhenua -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}He hakahaka rawa te arawhiti mō te aratohu rori # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Tē taea te hanga te anaroa i konei... diff --git a/src/lang/marathi.txt b/src/lang/marathi.txt index 3e98b72c5400e..cb308dabb23c6 100644 --- a/src/lang/marathi.txt +++ b/src/lang/marathi.txt @@ -1042,7 +1042,7 @@ STR_CONFIG_SETTING_STATUSBAR_POS :स्टेट ###length 3 -###length 3 +###length 4 diff --git a/src/lang/norwegian_bokmal.txt b/src/lang/norwegian_bokmal.txt index a674b766cb607..6c48f2cccab86 100644 --- a/src/lang/norwegian_bokmal.txt +++ b/src/lang/norwegian_bokmal.txt @@ -2160,7 +2160,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Høydeenheter: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Når en høyde vises i brukergrensesnittet, vis den i de valgte enhetene -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperisk (fot) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrisk (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3473,7 +3473,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Landskap STR_GENERATION_RIVER_GENERATION :{BLACK}Skap elver STR_GENERATION_CLEARING_TILES :{BLACK}Generering av ulendt og steinete område STR_GENERATION_TOWN_GENERATION :{BLACK}Bygenerering -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Industrigenerering STR_GENERATION_OBJECT_GENERATION :{BLACK}Objektgenerering STR_GENERATION_TREE_GENERATION :{BLACK}Tregenerering STR_GENERATION_SETTINGUP_GAME :{BLACK}Klargjør spillet @@ -5271,13 +5270,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Start og STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...{NBSP}broens ender må være på land STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... broen er for lang STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Bro vil ende utenfor kartet -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Broen er for lav for en stasjon -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Broen er for lav for en holdeplass -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Broen er for lav for en havn -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Broen er for lav for en bøye -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Broen er for lav for et veipunkt -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Broen er for lav for et veipunkt -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Broen er for lav for en sluse # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Kan ikke bygge tunnel her... diff --git a/src/lang/norwegian_nynorsk.txt b/src/lang/norwegian_nynorsk.txt index bcf128286aae5..290c4c01b1a13 100644 --- a/src/lang/norwegian_nynorsk.txt +++ b/src/lang/norwegian_nynorsk.txt @@ -1747,7 +1747,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Eining for høgde: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Bruk vald eining for å vise høgde -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Britisk eining (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrisk (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) diff --git a/src/lang/persian.txt b/src/lang/persian.txt index 09b8b4d19800c..b91113615007c 100644 --- a/src/lang/persian.txt +++ b/src/lang/persian.txt @@ -1728,7 +1728,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_METRIC :متریک (kgf STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :واحدهای ارتفاع: {STRING} -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :امپریال (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :متریک (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :متر (m) diff --git a/src/lang/polish.txt b/src/lang/polish.txt index 6785c742b8eb4..fa73f92c9fb24 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -2538,7 +2538,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Jednostki wysokości: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Jeśli kiedykolwiek wysokości są pokazywane w interfejsie użytkownika, pokaż je w wybranych jednostkach -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperialne (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metryczne (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3851,7 +3851,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Tworzeni STR_GENERATION_RIVER_GENERATION :{BLACK}Tworzenie rzek STR_GENERATION_CLEARING_TILES :{BLACK}Tworzenie terenów skalistych i nierówności STR_GENERATION_TOWN_GENERATION :{BLACK}Tworzenie miast -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Rozmieszczanie przedsiębiorstw STR_GENERATION_OBJECT_GENERATION :{BLACK}Rozmieszczanie obiektów STR_GENERATION_TREE_GENERATION :{BLACK}Rozmieszczanie drzew STR_GENERATION_SETTINGUP_GAME :{BLACK}Konfigurowanie rozgrywki @@ -5655,13 +5654,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Począte STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... końce mostu muszą znajdować się na lądzie STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... za długi most STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Koniec mostu poza mapą -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Most jest zbyt niski dla stacji -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Most jest zbyt niski dla przystanku -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Most jest zbyt niski dla portu -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Most jest zbyt niski dla boi -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Most jest zbyt niski dla posterunku kolejowego -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Most jest zbyt niski dla posterunku drogowego -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Most jest zbyt niski dla śluzy # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Nie można tutaj zbudować tunelu... diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index bc417f32d4a69..710514ee7e373 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -2159,7 +2159,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Unidades de altura: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Quando as alturas são mostradas no interface de utilizador, mostrar na unidade selecionada -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (ft/pé) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Métrico (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3472,7 +3472,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}A gerar STR_GENERATION_RIVER_GENERATION :{BLACK}A gerar rios STR_GENERATION_CLEARING_TILES :{BLACK}A gerar zonas rochosas e montanhosas STR_GENERATION_TOWN_GENERATION :{BLACK}A gerar localidades -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}A gerar indústrias STR_GENERATION_OBJECT_GENERATION :{BLACK}A gerar objetos STR_GENERATION_TREE_GENERATION :{BLACK}A gerar árvores STR_GENERATION_SETTINGUP_GAME :{BLACK}A configurar jogo @@ -5270,13 +5269,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Início STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... ambos os extremos da ponte devem estar em terra STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... ponte demasiado longa STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}A ponte terminaria fora do mapa -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}A ponte é demasiado baixa para a estação -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}A ponte é demasiado baixa para a paragem rodoviária -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}A ponte é demasiado baixa para a doca -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}A ponte é demasiado baixa para a boia -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}A ponte é demasiado baixa para o ponto de controlo ferroviário -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}A ponte é demasiado baixa para o ponto de controlo rodoviário -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}A ponte é demasiado baixa para a eclusa # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Não é possível construir túnel aqui... diff --git a/src/lang/romanian.txt b/src/lang/romanian.txt index b08d2f80eacbf..2b6f5bcea7065 100644 --- a/src/lang/romanian.txt +++ b/src/lang/romanian.txt @@ -2127,7 +2127,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Unitate înălțime: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Afișează înălțimile în interfață folosind unitățile selectate -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metric (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3418,7 +3418,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Generare STR_GENERATION_RIVER_GENERATION :{BLACK}Generarea râurilor STR_GENERATION_CLEARING_TILES :{BLACK}Generare zonă dură și pietroasă STR_GENERATION_TOWN_GENERATION :{BLACK}Generare oraș -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Generare industrie STR_GENERATION_OBJECT_GENERATION :{BLACK}Generare fixă STR_GENERATION_TREE_GENERATION :{BLACK}Generare arbori STR_GENERATION_SETTINGUP_GAME :{BLACK}Se configurează jocul diff --git a/src/lang/russian.txt b/src/lang/russian.txt index e1aefd33195c6..bdbcf8b5585ac 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -2309,7 +2309,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :СИ (кН) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Система единиц для высоты: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Показывать значения высоты в выбранной системе единиц -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :английская (фут) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :метрическая (м) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :СИ (м) @@ -3646,7 +3646,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Созд STR_GENERATION_RIVER_GENERATION :{BLACK}Создание рек STR_GENERATION_CLEARING_TILES :{BLACK}Расстановка декораций и камней STR_GENERATION_TOWN_GENERATION :{BLACK}Создание городов -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Создание предприятий STR_GENERATION_OBJECT_GENERATION :{BLACK}Создание объектов STR_GENERATION_TREE_GENERATION :{BLACK}Высадка лесов STR_GENERATION_SETTINGUP_GAME :{BLACK}Настройка @@ -5456,13 +5455,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Нача STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... оба конца моста должны опираться на землю STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... мост слишком длинный STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Мост выходит за пределы карты -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Высота моста недостаточна для строительства станции -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Высота моста недостаточна для строительства остановки -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Высота моста недостаточна для строительства пристани -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Высота моста недостаточна для установки буя -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Высота моста недостаточна для строительства маршрутной точки -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Высота моста недостаточна для строительства маршрутной точки -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Высота моста недостаточна для строительства шлюза # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Здесь невозможно построить туннель... diff --git a/src/lang/serbian.txt b/src/lang/serbian.txt index e0f8b059c577f..efdb5971ca568 100644 --- a/src/lang/serbian.txt +++ b/src/lang/serbian.txt @@ -2250,7 +2250,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Mere visine: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Kad visine budu pokazane u interfejsu, pokazi u željenoj meri -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperijalne mere (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metričke mere (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) diff --git a/src/lang/simplified_chinese.txt b/src/lang/simplified_chinese.txt index 067950f22aa20..d89c02dac6386 100644 --- a/src/lang/simplified_chinese.txt +++ b/src/lang/simplified_chinese.txt @@ -2158,7 +2158,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :国际单位制 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :高度单位:{STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :在界面上以所选择的单位表示高度 -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :英制(呎) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :公制(米) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :国际单位制(米) @@ -3471,7 +3471,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}景观 STR_GENERATION_RIVER_GENERATION :{BLACK}生成河流 STR_GENERATION_CLEARING_TILES :{BLACK}生成岩石地貌 STR_GENERATION_TOWN_GENERATION :{BLACK}城镇生成 -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}工业生成 STR_GENERATION_OBJECT_GENERATION :{BLACK}生成固定设施 STR_GENERATION_TREE_GENERATION :{BLACK}生成树木 STR_GENERATION_SETTINGUP_GAME :{BLACK}设置游戏 @@ -5269,13 +5268,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}起止 STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}……桥梁两端必须都位于地面上 STR_ERROR_BRIDGE_TOO_LONG :{WHITE}……桥梁太长 STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}桥梁终点将越出地图 -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}桥梁过低,无法建设车站 -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}桥梁过低,无法建设车站 -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}桥梁过低,无法建设码头 -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}桥梁过低,无法放置浮标 -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}桥梁过低,无法建设路点 -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}桥梁过低,无法建设路点 -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}桥梁过低,无法建设船闸 # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}不能在这里开凿隧道…… diff --git a/src/lang/slovak.txt b/src/lang/slovak.txt index cbb3c6743aaf2..fdd76be32ab99 100644 --- a/src/lang/slovak.txt +++ b/src/lang/slovak.txt @@ -2172,7 +2172,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Jednotky výšky: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Vždy, keď sa zobrazí výška v užívateľskom rozhraní, zobrazí sa vo vybraných jednotkách -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperialne (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrické (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3420,7 +3420,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :Generujem kraji STR_GENERATION_RIVER_GENERATION :{BLACK}Generovanie riek STR_GENERATION_CLEARING_TILES :{BLACK}Generovanie nerovností a skál STR_GENERATION_TOWN_GENERATION :Vytváranie mesta -STR_GENERATION_INDUSTRY_GENERATION :Vytváranie priemyslu STR_GENERATION_OBJECT_GENERATION :{BLACK}Generovanie objektov STR_GENERATION_TREE_GENERATION :{BLACK}Generovanie stromov STR_GENERATION_SETTINGUP_GAME :{BLACK}Nastavovanie hry diff --git a/src/lang/slovenian.txt b/src/lang/slovenian.txt index 4f08febbaacf0..e6e9b9742f2db 100644 --- a/src/lang/slovenian.txt +++ b/src/lang/slovenian.txt @@ -1962,7 +1962,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Višinske enote: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Ko je omogočen prikaz višin na vmesniku, bodo prikazane v izbranih enotah. -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperične (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrične (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) diff --git a/src/lang/spanish.txt b/src/lang/spanish.txt index 3c578f94a5c09..7627577713790 100644 --- a/src/lang/spanish.txt +++ b/src/lang/spanish.txt @@ -2137,7 +2137,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Unidad de altura: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Cada vez que se muestre una altura en la interfaz de usuario, se empleará la unidad seleccionada -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (pies) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Métrico (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3440,7 +3440,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Generaci STR_GENERATION_RIVER_GENERATION :{BLACK}Generación de ríos STR_GENERATION_CLEARING_TILES :{BLACK}Generación de áreas ásperas o rocosas STR_GENERATION_TOWN_GENERATION :{BLACK}Generación de municipios -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Generación de industrias STR_GENERATION_OBJECT_GENERATION :{BLACK}Generación de inamovibles STR_GENERATION_TREE_GENERATION :{BLACK}Generación de árboles STR_GENERATION_SETTINGUP_GAME :{BLACK}Configurar juego diff --git a/src/lang/spanish_MX.txt b/src/lang/spanish_MX.txt index f005e3ab34cb0..4d128a76f1164 100644 --- a/src/lang/spanish_MX.txt +++ b/src/lang/spanish_MX.txt @@ -2154,7 +2154,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Unidades de altura: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Cada vez que se muestre una altura en la interfaz de usuario, se emplearán las unidades elegidas -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (pies) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Métrico (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3464,7 +3464,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Generaci STR_GENERATION_RIVER_GENERATION :{BLACK}Generación de ríos STR_GENERATION_CLEARING_TILES :{BLACK}Generación de áreas rugosas y rocosas STR_GENERATION_TOWN_GENERATION :{BLACK}Generación de pueblos -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Generación de industrias STR_GENERATION_OBJECT_GENERATION :{BLACK}Generación de objetos STR_GENERATION_TREE_GENERATION :{BLACK}Generación de árboles STR_GENERATION_SETTINGUP_GAME :{BLACK}Configurando partida diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt index a0f29b1edfb94..dff44044918ec 100644 --- a/src/lang/swedish.txt +++ b/src/lang/swedish.txt @@ -2158,7 +2158,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Höjdenhet: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Närhelst en höjd visas i användargränssnittet, visa den i de valda enheterna -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Brittisk (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrisk (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3471,7 +3471,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Landskap STR_GENERATION_RIVER_GENERATION :{BLACK}Generera Flod STR_GENERATION_CLEARING_TILES :{BLACK}Svår och stenig markgenerering STR_GENERATION_TOWN_GENERATION :{BLACK}Stadsgenerering -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Industrigenerering STR_GENERATION_OBJECT_GENERATION :{BLACK}Generera objekt STR_GENERATION_TREE_GENERATION :{BLACK}Generera Träd STR_GENERATION_SETTINGUP_GAME :{BLACK}Ställer in spel @@ -5269,13 +5268,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Start- o STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... brons båda ändar måste vara på land STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... för lång bro STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Bron slutar utanför kartans gränser -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Bro för låg för station -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Bro för låg för depå -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Bron är för låg för en kaj -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Bro för låg för boj -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Bro för låg för järnvägsriktmärke -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Bro för låg för vägriktmärke -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Bro för låg för sluss # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Kan inte bygga tunnel här... diff --git a/src/lang/tamil.txt b/src/lang/tamil.txt index 10ccf21cd3f65..516cfb1db30f1 100644 --- a/src/lang/tamil.txt +++ b/src/lang/tamil.txt @@ -1916,7 +1916,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :உயரங்கள் அலகுகள்: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :பயனர் இடைமுகத்தில் ஒரு உயரம் காட்டப்படும் போதெல்லாம், தேர்ந்தெடுக்கப்பட்ட அலகுகளில் அதைக் காட்டுங்கள் -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :இம்பீரியல் (அடி) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :மெட்ரிக் (மீ) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :அனைத்துலக முறை அலகு (மீ) diff --git a/src/lang/thai.txt b/src/lang/thai.txt index 98eec60d46d0b..c3c517a6fe84b 100644 --- a/src/lang/thai.txt +++ b/src/lang/thai.txt @@ -1829,7 +1829,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :มาตรฐ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :หน่วยวัดความสูง: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :การแสดงหน่วยวัดความสูงเมื่อกดดูรายละเอียดของวัตถุต่างๆ -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :อิมพีเรียล (ฟุต) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :เมตริก (เมตร) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :มาตรฐานสากล (เมตร) diff --git a/src/lang/traditional_chinese.txt b/src/lang/traditional_chinese.txt index 73cb73984e7f3..dc2f58726dc9d 100644 --- a/src/lang/traditional_chinese.txt +++ b/src/lang/traditional_chinese.txt @@ -2158,7 +2158,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :國際單位( STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :高度單位:{STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :在界面上以所選擇的單位表示高度。 -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :英制(英呎) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :米制(米) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :國際單位(米) @@ -3471,7 +3471,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}景觀 STR_GENERATION_RIVER_GENERATION :{BLACK}產生河流 STR_GENERATION_CLEARING_TILES :{BLACK}產生荒地與岩石地貌 STR_GENERATION_TOWN_GENERATION :{BLACK}市鎮生成 -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}工業生成 STR_GENERATION_OBJECT_GENERATION :{BLACK}無法移動 STR_GENERATION_TREE_GENERATION :{BLACK}產生樹木 STR_GENERATION_SETTINGUP_GAME :{BLACK}設定遊戲 @@ -5269,13 +5268,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}開始 STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... 橋樑的兩端應在陸地上 STR_ERROR_BRIDGE_TOO_LONG :{WHITE}……橋樑過長 STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}橋的終點將會在地圖外 -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}橋樑過低,無法興建車站 -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}橋樑過低,無法興建車站 -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}橋樑過低,無法興建碼頭 -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}橋樑過低,無法放置浮標 -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}橋樑過低,無法興建中途站 -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}橋樑過低,無法興建中途站 -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}橋樑過低,無法興建水閘 # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}無法在此挖掘隧道... diff --git a/src/lang/turkish.txt b/src/lang/turkish.txt index 63f61b4003ca3..35d04b5311f50 100644 --- a/src/lang/turkish.txt +++ b/src/lang/turkish.txt @@ -2106,7 +2106,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (Uluslararas STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Yükseklik ölçü birimi: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Kullanıcı arayüzünde yükseklikler görüntülendiğinde, bunları seçili ölçü biriminde göster -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (Ingiliz ölçü birimleri) (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrik (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (Uluslararası Ölçüm Sistemi) (m) @@ -3380,7 +3380,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Peyzaj o STR_GENERATION_RIVER_GENERATION :{BLACK}Nehir oluşturma STR_GENERATION_CLEARING_TILES :{BLACK}Engebeli ve kayalık alan oluştur STR_GENERATION_TOWN_GENERATION :{BLACK}Kasaba Oluşumu -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Endüstri Oluşumu STR_GENERATION_OBJECT_GENERATION :{BLACK}Nesne oluşturma STR_GENERATION_TREE_GENERATION :{BLACK}Ağaç üretimi STR_GENERATION_SETTINGUP_GAME :{BLACK}Oyun ayarlanıyor diff --git a/src/lang/ukrainian.txt b/src/lang/ukrainian.txt index c525d5020f367..c96a193178632 100644 --- a/src/lang/ukrainian.txt +++ b/src/lang/ukrainian.txt @@ -2273,7 +2273,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :СІ (кН) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Одиниці висоти: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Якщо висоти відображаються на інтерфейсі: показувати в обраній одиниці виміру -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Імперські (фути) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Метричні (м) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :СІ (м) @@ -3579,7 +3579,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Гене STR_GENERATION_RIVER_GENERATION :{BLACK}Генерація річок STR_GENERATION_CLEARING_TILES :{BLACK}Розкидати каміння STR_GENERATION_TOWN_GENERATION :{BLACK}Генерація міст -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Генерація промисловості STR_GENERATION_OBJECT_GENERATION :{BLACK}Генерація нерухомості STR_GENERATION_TREE_GENERATION :{BLACK}Насадження дерев STR_GENERATION_SETTINGUP_GAME :{BLACK}Налаштування гри diff --git a/src/lang/urdu.txt b/src/lang/urdu.txt index 4fa01ee68cbb0..40e9f035a728d 100644 --- a/src/lang/urdu.txt +++ b/src/lang/urdu.txt @@ -1482,7 +1482,7 @@ STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :شہر کا ش ###length 3 -###length 3 +###length 4 STR_CONFIG_SETTING_INTERFACE :انٹرفیس STR_CONFIG_SETTING_INTERFACE_CONSTRUCTION :تعمیرات diff --git a/src/lang/vietnamese.txt b/src/lang/vietnamese.txt index 45cadcf237516..4cbf272ae3258 100644 --- a/src/lang/vietnamese.txt +++ b/src/lang/vietnamese.txt @@ -2158,7 +2158,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Đơn vị độ cao: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Khi độ cao thể hiện trên giao diện, thì hiển thị nó trên đơn vị đã chọn -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Hoàng Gia (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metric (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3470,7 +3470,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Khởi t STR_GENERATION_RIVER_GENERATION :{BLACK}Khởi tạo sông suối STR_GENERATION_CLEARING_TILES :{BLACK}Sinh đá và sự gồ ghề STR_GENERATION_TOWN_GENERATION :{BLACK}Khởi tạo thị trấn -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Khởi tạo nhà máy STR_GENERATION_OBJECT_GENERATION :{BLACK}Sinh đối tượng cứng STR_GENERATION_TREE_GENERATION :{BLACK}Trồng cây STR_GENERATION_SETTINGUP_GAME :{BLACK}Thiết lập ván chơi @@ -5267,13 +5266,6 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Điểu STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... hai đầu cầu phải được gá vào đất STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... cầu quá dài STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Cầu có thể vượt quá phạm vi bản đồ -STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Cầu quá thấp cho ga -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Cầu quá thấp cho điểm dừng chân -STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Cầu quá thấp để xây dựng cảng -STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Cầu quá thấp cho phao -STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Cầu quá thấp cho điểm mốc đường ray -STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Cầu quá thấp cho điểm mốc đường -STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :Cầu thấp, tàu không qua được khóa # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Không thể đào hầm ở đây... diff --git a/src/lang/welsh.txt b/src/lang/welsh.txt index 761db4c555bec..271efe20fba21 100644 --- a/src/lang/welsh.txt +++ b/src/lang/welsh.txt @@ -2146,7 +2146,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Unedau uchder: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Pan y dangosir uchder yn y rhyngwyneb defnyddiwr, ei ddangos yn yr unedau a ddewiswyd -###length 3 +###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrig (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) @@ -3456,7 +3456,6 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Creu tir STR_GENERATION_RIVER_GENERATION :{BLACK}Cynhyrchu afonydd STR_GENERATION_CLEARING_TILES :{BLACK}Cynhyrchu ardaloedd creigiog a chnapiog STR_GENERATION_TOWN_GENERATION :{BLACK}Creu trefi -STR_GENERATION_INDUSTRY_GENERATION :{BLACK}Creu diwydiant STR_GENERATION_OBJECT_GENERATION :{BLACK}Cynhyrchu gwrthrych STR_GENERATION_TREE_GENERATION :{BLACK}Cynhyrchu coed STR_GENERATION_SETTINGUP_GAME :{BLACK}Gosod gêm yn ei le From 1522c9f661547cf52a5436f2cf09a44e471fd0ba Mon Sep 17 00:00:00 2001 From: translators Date: Sun, 26 Oct 2025 04:38:02 +0000 Subject: [PATCH 087/137] Update: Translations from eints english (au): 11 changes by krysclarke swedish: 11 changes by robert-i chinese (traditional): 11 changes by KogentaSan greek: 11 changes by gh658804 russian: 13 changes by Ln-Wolf finnish: 15 changes by hpiirai portuguese: 44 changes by jcteotonio portuguese (brazilian): 11 changes by pasantoro, 1 change by jcteotonio polish: 10 changes by Rito13, 1 change by pAter-exe --- src/lang/brazilian_portuguese.txt | 13 +++++- src/lang/english_AU.txt | 11 +++++ src/lang/finnish.txt | 19 ++++++-- src/lang/greek.txt | 11 +++++ src/lang/polish.txt | 11 +++++ src/lang/portuguese.txt | 77 ++++++++++++++++++------------- src/lang/russian.txt | 15 +++++- src/lang/swedish.txt | 11 +++++ src/lang/traditional_chinese.txt | 11 +++++ 9 files changed, 139 insertions(+), 40 deletions(-) diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index ffe13e3f947b7..42ecbac923035 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -255,6 +255,7 @@ STR_UNITS_FORCE_SI :{DECIMAL}{NBSP} STR_UNITS_HEIGHT_IMPERIAL :{DECIMAL}{NBSP}ft STR_UNITS_HEIGHT_METRIC :{DECIMAL}{NBSP}m STR_UNITS_HEIGHT_SI :{DECIMAL}{NBSP}m +STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}{NBSP}níve{P l is} # Time units used in string control characters STR_UNITS_DAYS :{COMMA}{NBSP}dia{P "" s} @@ -2163,6 +2164,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Sempre que uma STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Métrico (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :Unidades do jogo (níveis) STR_CONFIG_SETTING_LOCALISATION :Localização STR_CONFIG_SETTING_GRAPHICS :Gráficos @@ -3472,6 +3474,8 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Geraçã STR_GENERATION_RIVER_GENERATION :{BLACK}Geração de rios STR_GENERATION_CLEARING_TILES :{BLACK}Geração de áreas irregulares e rochosas STR_GENERATION_TOWN_GENERATION :{BLACK}Geração de localidades +STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}Geração de indústrias terrestres +STR_GENERATION_WATER_INDUSTRY_GENERATION :{BLACK}Geração de indústrias fluviais STR_GENERATION_OBJECT_GENERATION :{BLACK}Geração de objetos STR_GENERATION_TREE_GENERATION :{BLACK}Geração de árvores STR_GENERATION_SETTINGUP_GAME :{BLACK}Configurando o jogo @@ -5269,6 +5273,13 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Início STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... os extremos da ponte devem estar sobre a terra STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... ponte muito longa STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}A ponte terminaria fora do mapa +STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}A ponte está {HEIGHT} abaixo do necessário para a estação +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}A ponte está {HEIGHT} abaixo do necessário para a parada rodoviária +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}A ponte está {HEIGHT} abaixo do necessário para a doca +STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}A ponte está {HEIGHT} abaixo do necessário para a boia +STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}A ponte está {HEIGHT} abaixo do necessário para o ponto de controle ferroviário +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}A ponte está {HEIGHT} abaixo do necessário para o ponto de controle rodoviário +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}A ponte está {HEIGHT} abaixo do necessário para a eclusa # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Não é possível construir túnel aqui... @@ -5906,7 +5917,7 @@ STR_WAYPOINT_NAME :{WAYPOINT} STR_CURRENCY_SHORT_KILO :{NBSP}k STR_CURRENCY_SHORT_MEGA :{NBSP}M -STR_CURRENCY_SHORT_GIGA :{NBSP}G +STR_CURRENCY_SHORT_GIGA :{NBSP}B STR_CURRENCY_SHORT_TERA :{NBSP}T STR_JUST_CARGO :{CARGO_LONG} diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt index 087a675509b10..92dc23506aa14 100644 --- a/src/lang/english_AU.txt +++ b/src/lang/english_AU.txt @@ -254,6 +254,7 @@ STR_UNITS_FORCE_SI :{DECIMAL}{NBSP} STR_UNITS_HEIGHT_IMPERIAL :{DECIMAL}{NBSP}ft STR_UNITS_HEIGHT_METRIC :{DECIMAL}{NBSP}m STR_UNITS_HEIGHT_SI :{DECIMAL}{NBSP}m +STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}{NBSP}level{P "" s} # Time units used in string control characters STR_UNITS_DAYS :{COMMA}{NBSP}day{P "" s} @@ -2162,6 +2163,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Whenever height STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metric (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :Game units (levels) STR_CONFIG_SETTING_LOCALISATION :Localisation STR_CONFIG_SETTING_GRAPHICS :Graphics @@ -3471,6 +3473,8 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Landscap STR_GENERATION_RIVER_GENERATION :{BLACK}River generation STR_GENERATION_CLEARING_TILES :{BLACK}Rough and rocky area generation STR_GENERATION_TOWN_GENERATION :{BLACK}Town generation +STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}Land industry generation +STR_GENERATION_WATER_INDUSTRY_GENERATION :{BLACK}Water industry generation STR_GENERATION_OBJECT_GENERATION :{BLACK}Object generation STR_GENERATION_TREE_GENERATION :{BLACK}Tree generation STR_GENERATION_SETTINGUP_GAME :{BLACK}Setting up game @@ -5268,6 +5272,13 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Start an STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... ends of bridge must both be on land STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... bridge too long STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Bridge would end out of the map +STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Bridge is {HEIGHT} too low for station +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Bridge is {HEIGHT} too low for road stop +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Bridge is {HEIGHT} too low for dock +STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Bridge is {HEIGHT} too low for buoy +STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Bridge is {HEIGHT} too low for rail waypoint +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Bridge is {HEIGHT} too low for road waypoint +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Bridge is {HEIGHT} too low for lock # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Can't build tunnel here... diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index f0de21e757223..f7b6d68b0d0c7 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -254,6 +254,7 @@ STR_UNITS_FORCE_SI :{DECIMAL}{NBSP} STR_UNITS_HEIGHT_IMPERIAL :{DECIMAL}{NBSP}ft STR_UNITS_HEIGHT_METRIC :{DECIMAL}{NBSP}m STR_UNITS_HEIGHT_SI :{DECIMAL}{NBSP}m +STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}{NBSP}taso{P "" a} # Time units used in string control characters STR_UNITS_DAYS :{COMMA}{NBSP}vrk @@ -2124,8 +2125,8 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_HELPTEXT :Kun käyttölii STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_IMPERIAL :Brittiläinen (mph) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_METRIC :Metrinen (km/h) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_SI :SI (m/s) -STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_GAMEUNITS_DAYS :Pelin yksiköt (ruutua/vrk) -STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_GAMEUNITS_SECS :Pelin yksiköt (ruutua/s) +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_GAMEUNITS_DAYS :Pelin yksiköt (ruutuja/vrk) +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_GAMEUNITS_SECS :Pelin yksiköt (ruutuja/s) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_KNOTS :Solmut STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER :Kulkuneuvon tehon yksikkö: {STRING} @@ -2162,6 +2163,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Kun käyttölii STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Brittiläinen (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrinen (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :Pelin yksiköt (tasoja) STR_CONFIG_SETTING_LOCALISATION :Mittayksiköt ja päivämäärät STR_CONFIG_SETTING_GRAPHICS :Grafiikka @@ -2962,8 +2964,8 @@ STR_STATION_BUILD_BUS_ORIENTATION :{WHITE}Linja-au STR_STATION_BUILD_BUS_ORIENTATION_TOOLTIP :{BLACK}Valitse linja-autoaseman suunta STR_STATION_BUILD_TRUCK_ORIENTATION :{WHITE}Lastauslaiturin suunta STR_STATION_BUILD_TRUCK_ORIENTATION_TOOLTIP :{BLACK}Valitse lastauslaiturin suunta -STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION :{WHITE}Aseman suunta -STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION_TOOLTIP :{BLACK}Valitse aseman suunta +STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION :{WHITE}Raitiotien matkustaja-aseman suunta +STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION_TOOLTIP :{BLACK}Valitse raitiotien matkustaja-aseman suunta STR_STATION_BUILD_CARGO_TRAM_ORIENTATION :{WHITE}Rahtiaseman suunta STR_STATION_BUILD_CARGO_TRAM_ORIENTATION_TOOLTIP :{BLACK}Valitse rahtiaseman suunta @@ -3471,6 +3473,8 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Maaston STR_GENERATION_RIVER_GENERATION :{BLACK}Jokien luominen STR_GENERATION_CLEARING_TILES :{BLACK}Karun ja kivisen alueen luominen STR_GENERATION_TOWN_GENERATION :{BLACK}Kuntien luominen +STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}Teollisuuden luominen maalla +STR_GENERATION_WATER_INDUSTRY_GENERATION :{BLACK}Teollisuuden luominen vedessä STR_GENERATION_OBJECT_GENERATION :{BLACK}Siirtämättömän luominen STR_GENERATION_TREE_GENERATION :{BLACK}Puiden luominen STR_GENERATION_SETTINGUP_GAME :{BLACK}Valmistellaan peliä @@ -5268,6 +5272,13 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Alku- ja STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... sillan molempien päiden pitää sijaita maalla. STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... silta liian pitkä STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Silta päättyisi kartan ulkopuolelle +STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Silta on {HEIGHT} liian matala aseman ylle +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Silta on {HEIGHT} liian matala pysäkin ylle +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Silta on {HEIGHT} liian matala sataman ylle +STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Silta on {HEIGHT} liian matala poijun ylle +STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Silta on {HEIGHT} liian matala rautatien reittipisteen ylle +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Silta on {HEIGHT} liian matala tien reittipisteen ylle +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Silta on {HEIGHT} liian matala sulun ylle # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Tunnelia ei voi rakentaa... diff --git a/src/lang/greek.txt b/src/lang/greek.txt index 6d4ebdff5335a..051a97e806e9b 100644 --- a/src/lang/greek.txt +++ b/src/lang/greek.txt @@ -316,6 +316,7 @@ STR_UNITS_FORCE_SI :{DECIMAL}{NBSP} STR_UNITS_HEIGHT_IMPERIAL :{DECIMAL}{NBSP}πόδ{P "ι" "ια"} STR_UNITS_HEIGHT_METRIC :{DECIMAL}{NBSP}μ STR_UNITS_HEIGHT_SI :{DECIMAL}{NBSP}m +STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}{NBSP}επίπεδ{P "ο" "α"} # Time units used in string control characters STR_UNITS_DAYS :{COMMA}{NBSP}ημέρ{P 0 α ες} @@ -2255,6 +2256,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Όποτε εμ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Αυτοκρατορικό (πόδια) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Μετρικό (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :Μονάδες παιχνιδιού (επίπεδα) STR_CONFIG_SETTING_LOCALISATION :Τοπικοποίηση STR_CONFIG_SETTING_GRAPHICS :Γραφικά @@ -3564,6 +3566,8 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Δημι STR_GENERATION_RIVER_GENERATION :{BLACK}Δημιουργία ποταμού STR_GENERATION_CLEARING_TILES :{BLACK}Δημιουργία άγριας και πετρώδης περιοχής STR_GENERATION_TOWN_GENERATION :{BLACK}Δημιουργία πόλης +STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}Δημιουργία βιομηχανίας γης +STR_GENERATION_WATER_INDUSTRY_GENERATION :{BLACK}Δημιουργία βιομηχανίας νερού STR_GENERATION_OBJECT_GENERATION :{BLACK}Δημιουργία μη μετακινούμενων STR_GENERATION_TREE_GENERATION :{BLACK}Δημιουργία δέντρων STR_GENERATION_SETTINGUP_GAME :{BLACK}Ρύθμιση παιχνιδιού @@ -5369,6 +5373,13 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Η αρ STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... και τα δύο άκρα της γέφυρας πρέπει να είναι σε έδαφος STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... η γέφυρα είναι πολλή μακριά STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Η γέφυρα θα καταλήξει εκτός χάρτη +STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Η γέφυρα είναι {HEIGHT} πολύ χαμηλή για σταθμό +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Η γέφυρα είναι {HEIGHT} πολύ χαμηλή για οδική στάση +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Η γέφυρα είναι {HEIGHT} πολύ χαμηλή για αποβάθρα +STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Η γέφυρα είναι {HEIGHT} πολύ χαμηλή για σημαδούρα +STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Η γέφυρα είναι {HEIGHT} πολύ χαμηλή για σιδηροδρομικό σημείο αναφοράς +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Η γέφυρα είναι {HEIGHT} πολύ χαμηλή για οδικό σημείο αναφοράς +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Η γέφυρα είναι {HEIGHT} πολύ χαμηλή για κλείδωμα # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Δεν μπορεί να κατασκευαστεί σήραγγα εδώ... diff --git a/src/lang/polish.txt b/src/lang/polish.txt index fa73f92c9fb24..f26c53b4a4d60 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -633,6 +633,7 @@ STR_UNITS_FORCE_SI :{DECIMAL}{NBSP} STR_UNITS_HEIGHT_IMPERIAL :{DECIMAL}{NBSP}st{P opa opy óp} STR_UNITS_HEIGHT_METRIC :{DECIMAL}{NBSP}m STR_UNITS_HEIGHT_SI :{DECIMAL}{NBSP}m +STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}{NBSP}skok{P "" i ów} poziomu # Time units used in string control characters STR_UNITS_DAYS :{COMMA}{NBSP}d{P zień ni ni} @@ -2542,6 +2543,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Jeśli kiedykol STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperialne (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metryczne (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :Jednostki gry (skoki poziomu) STR_CONFIG_SETTING_LOCALISATION :Lokalizacja STR_CONFIG_SETTING_GRAPHICS :Grafika @@ -3851,6 +3853,8 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Tworzeni STR_GENERATION_RIVER_GENERATION :{BLACK}Tworzenie rzek STR_GENERATION_CLEARING_TILES :{BLACK}Tworzenie terenów skalistych i nierówności STR_GENERATION_TOWN_GENERATION :{BLACK}Tworzenie miast +STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}Tworzenie fabryk na lądzie +STR_GENERATION_WATER_INDUSTRY_GENERATION :{BLACK}Tworzenie przemysłu na wodzie STR_GENERATION_OBJECT_GENERATION :{BLACK}Rozmieszczanie obiektów STR_GENERATION_TREE_GENERATION :{BLACK}Rozmieszczanie drzew STR_GENERATION_SETTINGUP_GAME :{BLACK}Konfigurowanie rozgrywki @@ -5654,6 +5658,13 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Począte STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... końce mostu muszą znajdować się na lądzie STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... za długi most STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Koniec mostu poza mapą +STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Most jest o {HEIGHT} za niski dla stacji +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Most jest o {HEIGHT} za niski dla przystanku +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Most jest o {HEIGHT} za niski dla portu +STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Most jest o {HEIGHT} za niski dla boi +STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Most jest o {HEIGHT} za niski dla posterunku kolejowego +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Most jest o {HEIGHT} za niski dla posterunku drogowego +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Most jest o {HEIGHT} za niski dla śluzy # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Nie można tutaj zbudować tunelu... diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index 710514ee7e373..e800b2a356680 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -138,7 +138,7 @@ STR_ABBREV_GOODS :BN STR_ABBREV_GRAIN :CR STR_ABBREV_WOOD :MD STR_ABBREV_IRON_ORE :FR -STR_ABBREV_STEEL :AC +STR_ABBREV_STEEL :AÇ STR_ABBREV_VALUABLES :VL STR_ABBREV_COPPER_ORE :CO STR_ABBREV_MAIZE :ML @@ -150,14 +150,14 @@ STR_ABBREV_GOLD :OU STR_ABBREV_WATER :AG STR_ABBREV_WHEAT :TR STR_ABBREV_RUBBER :BR -STR_ABBREV_SUGAR :AÇ +STR_ABBREV_SUGAR :AÚ STR_ABBREV_TOYS :BQ STR_ABBREV_SWEETS :DC STR_ABBREV_COLA :CL STR_ABBREV_CANDYFLOSS :AD STR_ABBREV_BUBBLES :BO STR_ABBREV_TOFFEE :CM -STR_ABBREV_BATTERIES :BA +STR_ABBREV_BATTERIES :PI STR_ABBREV_PLASTIC :PL STR_ABBREV_FIZZY_DRINKS :RF STR_ABBREV_ALL :TODOS @@ -255,6 +255,7 @@ STR_UNITS_FORCE_SI :{DECIMAL}{NBSP} STR_UNITS_HEIGHT_IMPERIAL :{DECIMAL}{NBSP}pé{P "" s} STR_UNITS_HEIGHT_METRIC :{DECIMAL}{NBSP}m STR_UNITS_HEIGHT_SI :{DECIMAL}{NBSP}m +STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}{NBSP}níve{P l is} # Time units used in string control characters STR_UNITS_DAYS :{COMMA}{NBSP}dia{P "" s} @@ -760,7 +761,7 @@ STR_HIGHSCORE_PERFORMANCE_TITLE_ENTREPRENEUR :Empreendedor STR_HIGHSCORE_PERFORMANCE_TITLE_INDUSTRIALIST :Industrialista STR_HIGHSCORE_PERFORMANCE_TITLE_CAPITALIST :Capitalista STR_HIGHSCORE_PERFORMANCE_TITLE_MAGNATE :Magnata -STR_HIGHSCORE_PERFORMANCE_TITLE_MOGUL :Grande Magnata +STR_HIGHSCORE_PERFORMANCE_TITLE_MOGUL :Barão STR_HIGHSCORE_PERFORMANCE_TITLE_TYCOON_OF_THE_CENTURY :Magnata do Século STR_HIGHSCORE_NAME :{PRESIDENT_NAME}, {COMPANY} STR_HIGHSCORE_STATS :{BIG_FONT}"{STRING}" ({COMMA}) @@ -1057,7 +1058,7 @@ STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_60_MINUTES :A cada 60 minut STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_120_MINUTES :A cada 120 minutos STR_GAME_OPTIONS_LANGUAGE :Língua -STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :Selecionar a Língua da interface do jogo +STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :Selecionar a língua da interface do jogo STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE :{STRING} ({NUM}% concluído) STR_GAME_OPTIONS_FULLSCREEN :Ecrã Inteiro @@ -1096,9 +1097,9 @@ STR_GAME_OPTIONS_GUI_SCALE_MARK :{DECIMAL}x STR_GAME_OPTIONS_PARTICIPATE_SURVEY_FRAME :Sondagem automatizada STR_GAME_OPTIONS_PARTICIPATE_SURVEY :Participar numa sondagem automatizada -STR_GAME_OPTIONS_PARTICIPATE_SURVEY_TOOLTIP :Quando ativo, o OpenTTD transmitirá uma sondagem ao deixar um jogo +STR_GAME_OPTIONS_PARTICIPATE_SURVEY_TOOLTIP :Quando ativo, o OpenTTD enviará dados para sondagem ao sair de um jogo STR_GAME_OPTIONS_PARTICIPATE_SURVEY_LINK :Sobre sondagem e privacidade -STR_GAME_OPTIONS_PARTICIPATE_SURVEY_LINK_TOOLTIP :Isto abre um navegador com mais informações sobre a sondagem automatizada +STR_GAME_OPTIONS_PARTICIPATE_SURVEY_LINK_TOOLTIP :Isto abre o navegador com mais informações sobre a sondagem automatizada STR_GAME_OPTIONS_PARTICIPATE_SURVEY_PREVIEW :Pré-visualizar resultado da sondagem STR_GAME_OPTIONS_PARTICIPATE_SURVEY_PREVIEW_TOOLTIP :Mostrar o resultado da sondagem do jogo atual a decorrer @@ -1159,11 +1160,11 @@ STR_CURRENCY_SET_CUSTOM_CURRENCY_PREFIX_TOOLTIP :{BLACK}Definir STR_CURRENCY_SUFFIX :{LTBLUE}Sufixo: {ORANGE}{STRING} STR_CURRENCY_SET_CUSTOM_CURRENCY_SUFFIX_TOOLTIP :{BLACK}Definir o sufixo para a sua moeda -STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Mudar para o Euro: {ORANGE}{NUM} -STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Mudar para o Euro: {ORANGE}Nunca +STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Mudar para o Euro em: {ORANGE}{NUM} +STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Mudar para o Euro em: {ORANGE}Nunca STR_CURRENCY_SET_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Definir o ano para mudar para o Euro -STR_CURRENCY_DECREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Mudar para Euro mais cedo -STR_CURRENCY_INCREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Mudar para Euro mais tarde +STR_CURRENCY_DECREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Mudar para o Euro mais cedo +STR_CURRENCY_INCREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Mudar para o Euro mais tarde STR_CURRENCY_PREVIEW :{LTBLUE}Pré-visualizar: {ORANGE}{CURRENCY_LONG} STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Libras (£) na sua moeda @@ -1502,7 +1503,7 @@ STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Permitir estaç STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Permite a construção de estações de passagem nas ruas pertencentes a localidades. STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Permitir estações de passagem nas estradas detidas pelos competidores: {STRING} STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD_HELPTEXT :Permite a construção de estações de passagem nas estradas que são de outras empresas -STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}Não é possível mudar quando já existem veículos. +STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}Não é possível alterar esta configuração quando já existem veículos STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :Manutenção de infraestruturas: {STRING} STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :Quando ativo, as infraestruturas têm custos de manutenção. O custo cresce mais do que o proporcional com o tamanho da rede e assim afeta mais as empresas maiores do que as mais pequenas @@ -2139,14 +2140,14 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_SI :SI (kW) STR_CONFIG_SETTING_LOCALISATION_UNITS_WEIGHT :Unidades de peso: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_WEIGHT_HELPTEXT :Quando um peso é mostrado na interface de utilizador, mostrar na unidade selecionada ###length 3 -STR_CONFIG_SETTING_LOCALISATION_UNITS_WEIGHT_IMPERIAL :Imperial (short ton) +STR_CONFIG_SETTING_LOCALISATION_UNITS_WEIGHT_IMPERIAL :Imperial (short t/ton) STR_CONFIG_SETTING_LOCALISATION_UNITS_WEIGHT_METRIC :Métrico (t/tonelada) STR_CONFIG_SETTING_LOCALISATION_UNITS_WEIGHT_SI :SI (kg) STR_CONFIG_SETTING_LOCALISATION_UNITS_VOLUME :Unidades de volume: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_VOLUME_HELPTEXT :Quando uma quantidade de volume é mostrada na interface de utilizador, mostrar na unidade selecionada ###length 3 -STR_CONFIG_SETTING_LOCALISATION_UNITS_VOLUME_IMPERIAL :Imperial (gal) +STR_CONFIG_SETTING_LOCALISATION_UNITS_VOLUME_IMPERIAL :Imperial (galões) STR_CONFIG_SETTING_LOCALISATION_UNITS_VOLUME_METRIC :Métrico (l) STR_CONFIG_SETTING_LOCALISATION_UNITS_VOLUME_SI :SI (m³) @@ -2160,9 +2161,10 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_SI :SI (kN) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT :Unidades de altura: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Quando as alturas são mostradas no interface de utilizador, mostrar na unidade selecionada ###length 4 -STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (ft/pé) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (pés) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Métrico (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :Unidades do jogo (níveis) STR_CONFIG_SETTING_LOCALISATION :Localização STR_CONFIG_SETTING_GRAPHICS :Gráficos @@ -2256,7 +2258,7 @@ STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Verifica STR_INTRO_TOOLTIP_QUIT :{BLACK}Sair de 'OpenTTD' STR_INTRO_BASESET :{BLACK}O conjunto de gráficos base selecionado tem {NUM} elemento{P "" s} visua{P l is} em falta. Por favor, verifique se existem atualizações para este conjunto. -STR_INTRO_TRANSLATION :{BLACK}Falta{P 0 "" m} traduzir {NUM} linha{P "" s} neste idioma. Por favor, ajude o OpenTTD em inscrever-se como tradutor. Leia readme.txt para mais detalhes. +STR_INTRO_TRANSLATION :{BLACK}Falta{P 0 "" m} traduzir {NUM} linha{P "" s} nesta língua. Por favor, ajude o OpenTTD em inscrever-se como tradutor. Leia readme.txt para mais detalhes. # Quit window STR_QUIT_CAPTION :{WHITE}Sair @@ -3023,7 +3025,7 @@ STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Comprar # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Seleção de Objeto -STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Pré-visualização do objecto +STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Pré-visualização do objeto STR_OBJECT_BUILD_SIZE :{BLACK}Tamanho: {GOLD}{NUM} x {NUM} mosaicos STR_OBJECT_CLASS_LTHS :Faróis @@ -3140,9 +3142,9 @@ STR_LAND_AREA_INFORMATION_COST_TO_CLEAR :{BLACK}Custo de STR_LAND_AREA_INFORMATION_REVENUE_WHEN_CLEARED :{BLACK}Receitas apuradas: {LTBLUE}{CURRENCY_LONG} STR_LAND_AREA_INFORMATION_OWNER_N_A :N/D STR_LAND_AREA_INFORMATION_OWNER :{BLACK}Proprietário: {LTBLUE}{STRING} -STR_LAND_AREA_INFORMATION_ROAD_OWNER :{BLACK}Dono da estrada: {LTBLUE}{STRING} -STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Dono da linha de elétrico: {LTBLUE}{STRING} -STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Dono da linha férrea: {LTBLUE}{STRING} +STR_LAND_AREA_INFORMATION_ROAD_OWNER :{BLACK}Proprietário da estrada: {LTBLUE}{STRING} +STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Proprietário da linha de elétrico: {LTBLUE}{STRING} +STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Proprietário da linha de comboio: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Autoridade local: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Nenhuma STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordenadas: {LTBLUE}{NUM} x {NUM} x {NUM} @@ -3472,6 +3474,8 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}A gerar STR_GENERATION_RIVER_GENERATION :{BLACK}A gerar rios STR_GENERATION_CLEARING_TILES :{BLACK}A gerar zonas rochosas e montanhosas STR_GENERATION_TOWN_GENERATION :{BLACK}A gerar localidades +STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}A gerar indústrias terrestres +STR_GENERATION_WATER_INDUSTRY_GENERATION :{BLACK}A gerar indústrias fluviais STR_GENERATION_OBJECT_GENERATION :{BLACK}A gerar objetos STR_GENERATION_TREE_GENERATION :{BLACK}A gerar árvores STR_GENERATION_SETTINGUP_GAME :{BLACK}A configurar jogo @@ -3559,10 +3563,10 @@ STR_NEWGRF_PARAMETERS_NUM_PARAM :{LTBLUE}Número # NewGRF inspect window STR_NEWGRF_INSPECT_CAPTION :{WHITE}Inspeccionar - {STRING} STR_NEWGRF_INSPECT_PARENT_BUTTON :{BLACK}Pai -STR_NEWGRF_INSPECT_PARENT_TOOLTIP :{BLACK}Inspecciona o objecto do escopo pai +STR_NEWGRF_INSPECT_PARENT_TOOLTIP :{BLACK}Inspeciona o objeto do escopo pai STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT :{STRING} em {HEX} -STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_OBJECT :Objecto +STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_OBJECT :Objeto STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_RAIL_TYPE :Tipo de ferrovia STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_ROAD_TYPE :Tipo de estrada @@ -3765,7 +3769,7 @@ STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{Y # Goal window STR_GOALS_CAPTION :{WHITE}Objetivos de {COMPANY} STR_GOALS_SPECTATOR_CAPTION :{WHITE}Objetivos globais -STR_GOALS_SPECTATOR :Objectivos Globais +STR_GOALS_SPECTATOR :Objetivos Globais STR_GOALS_GLOBAL_BUTTON :{BLACK}Global STR_GOALS_GLOBAL_BUTTON_HELPTEXT :{BLACK}Mostrar objetivos globais STR_GOALS_COMPANY_BUTTON :{BLACK}Empresa @@ -4984,7 +4988,7 @@ STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Jogo gravado nu STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE :Ficheiro não é legível STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE :Não é possível escrever ficheiro STR_GAME_SAVELOAD_ERROR_DATA_INTEGRITY_CHECK_FAILED :Falha ao verificar integridade de dados -STR_GAME_SAVELOAD_ERROR_PATCHPACK :Salvar o jogo é feito com uma versão modificada +STR_GAME_SAVELOAD_ERROR_PATCHPACK :Jogo foi gravado com uma versão modificada STR_GAME_SAVELOAD_NOT_AVAILABLE : STR_WARNING_LOADGAME_REMOVED_TRAMS :{WHITE}O jogo foi guardado numa versão sem suporte para elétricos. Todos os elétricos foram removidos. @@ -5027,7 +5031,7 @@ STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY :{WHITE}Dinheiro STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}É necessário terreno plano STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Terreno inclinado na direção incorreta STR_ERROR_CAN_T_DO_THIS :{WHITE}Não é possível fazer isto... -STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}O edifício deve ser demolido primeiro +STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}O edifício tem que ser demolido primeiro STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... o edifício está protegido STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Não é possível limpar esta área... STR_ERROR_SITE_UNSUITABLE :{WHITE}... sítio inadequado @@ -5055,7 +5059,7 @@ STR_ERROR_EXCAVATION_WOULD_DAMAGE :{WHITE}A escava STR_ERROR_ALREADY_AT_SEA_LEVEL :{WHITE}... já está ao nível do mar STR_ERROR_TOO_HIGH :{WHITE}... demasiado alto STR_ERROR_ALREADY_LEVELLED :{WHITE}... já está nivelado -STR_ERROR_BRIDGE_TOO_HIGH_AFTER_LOWER_LAND :{WHITE}Ponte acima seria demasiado alta. +STR_ERROR_BRIDGE_TOO_HIGH_AFTER_LOWER_LAND :{WHITE}A ponte acima ficaria demasiado alta. # Company related errors STR_ERROR_CAN_T_CHANGE_COMPANY_NAME :{WHITE}Não é possível alterar o nome da empresa... @@ -5269,6 +5273,13 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Início STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... ambos os extremos da ponte devem estar em terra STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... ponte demasiado longa STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}A ponte terminaria fora do mapa +STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}A ponte está {HEIGHT} abaixo do necessário para a estação +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}A ponte está {HEIGHT} abaixo do necessário para a paragem rodoviária +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}A ponte está {HEIGHT} abaixo do necessário para a doca +STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}A ponte está {HEIGHT} abaixo do necessário para a boia +STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}A ponte está {HEIGHT} abaixo do necessário para o ponto de controlo ferroviário +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}A ponte está {HEIGHT} abaixo do necessário para o ponto de controlo rodoviário +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}A ponte está {HEIGHT} abaixo do necessário para a eclusa # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Não é possível construir túnel aqui... @@ -5281,12 +5292,12 @@ STR_ERROR_TUNNEL_TOO_LONG :{WHITE}... tún # Object related errors STR_ERROR_TOO_MANY_OBJECTS :{WHITE}... demasiados objetos -STR_ERROR_CAN_T_BUILD_OBJECT :{WHITE}Não é possível construir objecto... -STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Objecto no caminho +STR_ERROR_CAN_T_BUILD_OBJECT :{WHITE}Não é possível construir objeto... +STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Objeto no caminho STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... sede de empresa no caminho STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Não é possível comprar esta área de terreno... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... já lhe pertence! -STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... atingido o limite de construção de objeto +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... foi atingido o limite de construção de objetos # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Não é possível criar grupo... @@ -5904,10 +5915,10 @@ STR_TOWN_NAME :{TOWN} STR_VEHICLE_NAME :{VEHICLE} STR_WAYPOINT_NAME :{WAYPOINT} -STR_CURRENCY_SHORT_KILO :{NBSP}k -STR_CURRENCY_SHORT_MEGA :{NBSP}M -STR_CURRENCY_SHORT_GIGA :{NBSP}G -STR_CURRENCY_SHORT_TERA :{NBSP}T +STR_CURRENCY_SHORT_KILO :{NBSP}mil +STR_CURRENCY_SHORT_MEGA :{NBSP}milh. +STR_CURRENCY_SHORT_GIGA :{NBSP}mil milh. +STR_CURRENCY_SHORT_TERA :{NBSP}bilh. STR_JUST_CARGO :{CARGO_LONG} STR_JUST_LEFT_ARROW :{LEFT_ARROW} diff --git a/src/lang/russian.txt b/src/lang/russian.txt index bdbcf8b5585ac..f9ca11109c0ea 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -380,6 +380,7 @@ STR_UNITS_FORCE_SI :{DECIMAL}{NBSP} STR_UNITS_HEIGHT_IMPERIAL :{DECIMAL}{NBSP}фут{P "" а ов} STR_UNITS_HEIGHT_METRIC :{DECIMAL}{NBSP}м STR_UNITS_HEIGHT_SI :{DECIMAL}{NBSP}м +STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}{NBSP}уров{P ень ня ней} # Time units used in string control characters STR_UNITS_DAYS :{COMMA}{NBSP}д{P ень ня ней} @@ -2275,8 +2276,8 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_HELPTEXT :Показыв 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_DAYS :Внутренние единицы (клеток/день) -STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_GAMEUNITS_SECS :Внутренние единицы (клеток/сек.) +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_GAMEUNITS_DAYS :Игровые единицы (клеток/день) +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_GAMEUNITS_SECS :Игровые единицы (клеток/сек.) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_KNOTS :узлы STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER :Система единиц для мощности: {STRING} @@ -2313,6 +2314,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Показыв STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :английская (фут) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :метрическая (м) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :СИ (м) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :Игровые единицы (уровни) STR_CONFIG_SETTING_LOCALISATION :Локализация STR_CONFIG_SETTING_GRAPHICS :Графика @@ -3646,6 +3648,8 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Созд STR_GENERATION_RIVER_GENERATION :{BLACK}Создание рек STR_GENERATION_CLEARING_TILES :{BLACK}Расстановка декораций и камней STR_GENERATION_TOWN_GENERATION :{BLACK}Создание городов +STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}Создание наземных предприятий +STR_GENERATION_WATER_INDUSTRY_GENERATION :{BLACK}Создание водных предприятий STR_GENERATION_OBJECT_GENERATION :{BLACK}Создание объектов STR_GENERATION_TREE_GENERATION :{BLACK}Высадка лесов STR_GENERATION_SETTINGUP_GAME :{BLACK}Настройка @@ -5455,6 +5459,13 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Нача STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... оба конца моста должны опираться на землю STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... мост слишком длинный STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Мост выходит за пределы карты +STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Высота моста {HEIGHT} недостаточна для строительства станции +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Высота моста {HEIGHT} недостаточна для строительства остановки +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Высота моста {HEIGHT} недостаточна для строительства пристани +STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Высота моста {HEIGHT} недостаточна для установки буя +STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Высота моста {HEIGHT} недостаточна для строительства маршрутной точки +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Высота моста {HEIGHT} недостаточна для строительства маршрутной точки +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Высота моста {HEIGHT} недостаточна для строительства шлюза # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Здесь невозможно построить туннель... diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt index dff44044918ec..488b609c9f271 100644 --- a/src/lang/swedish.txt +++ b/src/lang/swedish.txt @@ -254,6 +254,7 @@ STR_UNITS_FORCE_SI :{DECIMAL}{NBSP} STR_UNITS_HEIGHT_IMPERIAL :{DECIMAL}{NBSP}fot STR_UNITS_HEIGHT_METRIC :{DECIMAL}{NBSP}m STR_UNITS_HEIGHT_SI :{DECIMAL}{NBSP}m +STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}{NBSP}nivå{P "" s} # Time units used in string control characters STR_UNITS_DAYS :{COMMA}{NBSP}dag{P "" ar} @@ -2162,6 +2163,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Närhelst en h STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Brittisk (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrisk (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :Spelenheter (nivåer) STR_CONFIG_SETTING_LOCALISATION :Lokalisering STR_CONFIG_SETTING_GRAPHICS :Grafik @@ -3471,6 +3473,8 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Landskap STR_GENERATION_RIVER_GENERATION :{BLACK}Generera Flod STR_GENERATION_CLEARING_TILES :{BLACK}Svår och stenig markgenerering STR_GENERATION_TOWN_GENERATION :{BLACK}Stadsgenerering +STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}Generering av markindustri +STR_GENERATION_WATER_INDUSTRY_GENERATION :{BLACK}Generering av vattenindustri STR_GENERATION_OBJECT_GENERATION :{BLACK}Generera objekt STR_GENERATION_TREE_GENERATION :{BLACK}Generera Träd STR_GENERATION_SETTINGUP_GAME :{BLACK}Ställer in spel @@ -5268,6 +5272,13 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Start- o STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... brons båda ändar måste vara på land STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... för lång bro STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Bron slutar utanför kartans gränser +STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Bron är {HEIGHT} för låg för station +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Bron är {HEIGHT} för låg för depå +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Bron är {HEIGHT} för låg för en kaj +STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Bron är {HEIGHT} för låg för boj +STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Bron är {HEIGHT} för låg för järnvägsriktmärke +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Bron är {HEIGHT} för låg för vägriktmärke +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Bron är {HEIGHT} för låg för sluss # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Kan inte bygga tunnel här... diff --git a/src/lang/traditional_chinese.txt b/src/lang/traditional_chinese.txt index dc2f58726dc9d..89d7aabf11294 100644 --- a/src/lang/traditional_chinese.txt +++ b/src/lang/traditional_chinese.txt @@ -254,6 +254,7 @@ STR_UNITS_FORCE_SI :{DECIMAL}{NBSP} STR_UNITS_HEIGHT_IMPERIAL :{DECIMAL}{NBSP}英呎 STR_UNITS_HEIGHT_METRIC :{DECIMAL}{NBSP}米 STR_UNITS_HEIGHT_SI :{DECIMAL}{NBSP}公尺 +STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}{NBSP}層 # Time units used in string control characters STR_UNITS_DAYS :{COMMA}{NBSP}日 @@ -2162,6 +2163,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :在界面上以 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :英制(英呎) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :米制(米) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :國際單位(米) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :遊戲單位(層次) STR_CONFIG_SETTING_LOCALISATION :本地化 STR_CONFIG_SETTING_GRAPHICS :圖形 @@ -3471,6 +3473,8 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}景觀 STR_GENERATION_RIVER_GENERATION :{BLACK}產生河流 STR_GENERATION_CLEARING_TILES :{BLACK}產生荒地與岩石地貌 STR_GENERATION_TOWN_GENERATION :{BLACK}市鎮生成 +STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}產生陸上工業 +STR_GENERATION_WATER_INDUSTRY_GENERATION :{BLACK}產生水上工業 STR_GENERATION_OBJECT_GENERATION :{BLACK}無法移動 STR_GENERATION_TREE_GENERATION :{BLACK}產生樹木 STR_GENERATION_SETTINGUP_GAME :{BLACK}設定遊戲 @@ -5268,6 +5272,13 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}開始 STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... 橋樑的兩端應在陸地上 STR_ERROR_BRIDGE_TOO_LONG :{WHITE}……橋樑過長 STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}橋的終點將會在地圖外 +STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}橋高 {HEIGHT},不足以興建車站 +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}橋高 {HEIGHT},不足以興建車站 +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}橋高 {HEIGHT},不足以興建碼頭 +STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}橋高 {HEIGHT},不足以放置浮標 +STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}橋高 {HEIGHT},不足以興建中途站 +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}橋高 {HEIGHT},不足以興建中途站 +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}橋高 {HEIGHT},不足以興建水閘 # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}無法在此挖掘隧道... From b43cdcba01c74b3a9b4f03b8c8b4a3b49dadfffe Mon Sep 17 00:00:00 2001 From: translators Date: Mon, 27 Oct 2025 04:41:32 +0000 Subject: [PATCH 088/137] Update: Translations from eints norwegian (bokmal): 12 changes by eriksorngard portuguese: 1 change by jcteotonio polish: 2 changes by pAter-exe, 2 changes by Rito13 --- src/lang/norwegian_bokmal.txt | 13 ++++++++++++- src/lang/polish.txt | 8 ++++---- src/lang/portuguese.txt | 2 +- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/lang/norwegian_bokmal.txt b/src/lang/norwegian_bokmal.txt index 6c48f2cccab86..0121c8b0fa1c3 100644 --- a/src/lang/norwegian_bokmal.txt +++ b/src/lang/norwegian_bokmal.txt @@ -256,6 +256,7 @@ STR_UNITS_FORCE_SI :{DECIMAL}{NBSP} STR_UNITS_HEIGHT_IMPERIAL :{DECIMAL}{NBSP}fot STR_UNITS_HEIGHT_METRIC :{DECIMAL}{NBSP}m STR_UNITS_HEIGHT_SI :{DECIMAL}{NBSP}m +STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}{NBSP}nivå{P "" er} # Time units used in string control characters STR_UNITS_DAYS :{COMMA}{NBSP}dag{P "" er} @@ -2164,6 +2165,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Når en høyde STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperisk (fot) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrisk (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :Spillenheter (nivåer) STR_CONFIG_SETTING_LOCALISATION :Lokalisering STR_CONFIG_SETTING_GRAPHICS :Grafikk @@ -3470,9 +3472,11 @@ STR_GENERATION_PROGRESS :{WHITE}{NUM}{NB STR_GENERATION_PROGRESS_NUM :{BLACK}{NUM} / {NUM} STR_GENERATION_WORLD_GENERATION :{BLACK}Generer en verden STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Landskapsgenerering -STR_GENERATION_RIVER_GENERATION :{BLACK}Skap elver +STR_GENERATION_RIVER_GENERATION :{BLACK}Elvegenerering STR_GENERATION_CLEARING_TILES :{BLACK}Generering av ulendt og steinete område STR_GENERATION_TOWN_GENERATION :{BLACK}Bygenerering +STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}Landindustrigenerering +STR_GENERATION_WATER_INDUSTRY_GENERATION :{BLACK}Vannindustrigenerering STR_GENERATION_OBJECT_GENERATION :{BLACK}Objektgenerering STR_GENERATION_TREE_GENERATION :{BLACK}Tregenerering STR_GENERATION_SETTINGUP_GAME :{BLACK}Klargjør spillet @@ -5270,6 +5274,13 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Start og STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}...{NBSP}broens ender må være på land STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... broen er for lang STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Bro vil ende utenfor kartet +STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Broen er {HEIGHT} for lav for en stasjon +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Broen er {HEIGHT} for lav for en holdeplass +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Broen er {HEIGHT} for lav for en havn +STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Broen er {HEIGHT} for lav for en bøye +STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Broen er {HEIGHT} for lav for et veipunkt +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Broen er {HEIGHT} for lav for et veipunkt +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Broen er {HEIGHT} for lav for en sluse # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Kan ikke bygge tunnel her... diff --git a/src/lang/polish.txt b/src/lang/polish.txt index f26c53b4a4d60..5e983a32f1a35 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -633,7 +633,7 @@ STR_UNITS_FORCE_SI :{DECIMAL}{NBSP} STR_UNITS_HEIGHT_IMPERIAL :{DECIMAL}{NBSP}st{P opa opy óp} STR_UNITS_HEIGHT_METRIC :{DECIMAL}{NBSP}m STR_UNITS_HEIGHT_SI :{DECIMAL}{NBSP}m -STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}{NBSP}skok{P "" i ów} poziomu +STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}{NBSP}poziom{P "" y ów} # Time units used in string control characters STR_UNITS_DAYS :{COMMA}{NBSP}d{P zień ni ni} @@ -2543,7 +2543,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Jeśli kiedykol STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperialne (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metryczne (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) -STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :Jednostki gry (skoki poziomu) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :Jednostki gry (poziomy) STR_CONFIG_SETTING_LOCALISATION :Lokalizacja STR_CONFIG_SETTING_GRAPHICS :Grafika @@ -2928,7 +2928,7 @@ STR_NETWORK_ASK_RELAY_NO :{BLACK}Nie STR_NETWORK_ASK_RELAY_YES_ONCE :{BLACK}Tak, ten jeden raz STR_NETWORK_ASK_RELAY_YES_ALWAYS :{BLACK}Tak, nie pytaj ponownie -STR_NETWORK_ASK_SURVEY_CAPTION :Uczestniczyć w automatycznej ankiecie? +STR_NETWORK_ASK_SURVEY_CAPTION :Uczestnictwo w automatycznej ankiecie? STR_NETWORK_ASK_SURVEY_TEXT :Czy chcesz wziąć udział w automatycznej ankiecie?{}OpenTTD prześle ankietę przy opuszczaniu gry.{}Możesz to zmienić w dowolnym momencie w „Opcjach gry”. STR_NETWORK_ASK_SURVEY_PREVIEW :Podejrzyj wynik ankiety STR_NETWORK_ASK_SURVEY_LINK :O ankiecie i prywatności @@ -3853,7 +3853,7 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Tworzeni STR_GENERATION_RIVER_GENERATION :{BLACK}Tworzenie rzek STR_GENERATION_CLEARING_TILES :{BLACK}Tworzenie terenów skalistych i nierówności STR_GENERATION_TOWN_GENERATION :{BLACK}Tworzenie miast -STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}Tworzenie fabryk na lądzie +STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}Tworzenie przemysłu na lądzie STR_GENERATION_WATER_INDUSTRY_GENERATION :{BLACK}Tworzenie przemysłu na wodzie STR_GENERATION_OBJECT_GENERATION :{BLACK}Rozmieszczanie obiektów STR_GENERATION_TREE_GENERATION :{BLACK}Rozmieszczanie drzew diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index e800b2a356680..d5b20f7f15eeb 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -5918,7 +5918,7 @@ STR_WAYPOINT_NAME :{WAYPOINT} STR_CURRENCY_SHORT_KILO :{NBSP}mil STR_CURRENCY_SHORT_MEGA :{NBSP}milh. STR_CURRENCY_SHORT_GIGA :{NBSP}mil milh. -STR_CURRENCY_SHORT_TERA :{NBSP}bilh. +STR_CURRENCY_SHORT_TERA :{NBSP}bil. STR_JUST_CARGO :{CARGO_LONG} STR_JUST_LEFT_ARROW :{LEFT_ARROW} From d1376d0b6701a673542636e2405ba47d34aa9c1c Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Mon, 27 Oct 2025 14:18:31 -0400 Subject: [PATCH 089/137] Fix #14737: Don't scale custom town and industry counts by land area (#14738) --- src/industry_cmd.cpp | 4 ++-- src/town_cmd.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 292f379f8e917..3cc143aa6b081 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -2494,8 +2494,8 @@ void GenerateIndustries() /* Total number of industries scaled by land/water proportion. */ uint total_amount = p.total * GetNumberOfIndustries() / (lprob.total + wprob.total); - /* Scale land-based industries to the land proportion. */ - if (!water) total_amount = Map::ScaleByLandProportion(total_amount); + /* Scale land-based industries to the land proportion, unless the player has set a custom industry count. */ + if (!water && _settings_game.difficulty.industry_density != ID_CUSTOM) total_amount = Map::ScaleByLandProportion(total_amount); /* Ensure that forced industries are generated even if the scaled amounts are too low. */ if (p.total == 0 || total_amount < p.num_forced) { diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 4ba9143c84d09..60cde52c29f35 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -2421,7 +2421,7 @@ bool GenerateTowns(TownLayout layout, std::optional number) if (number.has_value()) { total = number.value(); } else if (_settings_game.difficulty.number_towns == static_cast(CUSTOM_TOWN_NUMBER_DIFFICULTY)) { - total = Map::ScaleByLandProportion(GetDefaultTownsForMapSize()); + total = GetDefaultTownsForMapSize(); } else { total = Map::ScaleByLandProportion(GetDefaultTownsForMapSize() + (Random() & 7)); } From 6295310f2584f1ac23fcde399d8faae4b02d16a2 Mon Sep 17 00:00:00 2001 From: translators Date: Tue, 28 Oct 2025 04:38:50 +0000 Subject: [PATCH 090/137] Update: Translations from eints chinese (traditional): 4 changes by KogentaSan chinese (simplified): 11 changes by WenSimEHRP catalan: 11 changes by J0anJosep --- src/lang/catalan.txt | 11 +++++++++++ src/lang/simplified_chinese.txt | 11 +++++++++++ src/lang/traditional_chinese.txt | 8 ++++---- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index 2835c09afd905..bfcbcc843e72b 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -255,6 +255,7 @@ STR_UNITS_FORCE_SI :{G=Masculin}{DE STR_UNITS_HEIGHT_IMPERIAL :{DECIMAL}{NBSP}ft STR_UNITS_HEIGHT_METRIC :{DECIMAL}{NBSP}m STR_UNITS_HEIGHT_SI :{G=Masculin}{DECIMAL}{NBSP}m +STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}{NBSP}nivell{P "" s} # Time units used in string control characters STR_UNITS_DAYS :{COMMA}{NBSP}di{P a es} @@ -2163,6 +2164,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Quan es mostren STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (peu) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Mètric (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :Unitats de la partida (nivells) STR_CONFIG_SETTING_LOCALISATION :Localització STR_CONFIG_SETTING_GRAPHICS :Gràfics @@ -3472,6 +3474,8 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Generaci STR_GENERATION_RIVER_GENERATION :{BLACK}Generació de rius STR_GENERATION_CLEARING_TILES :{BLACK}Generació d'una àrea escarpada i rocosa STR_GENERATION_TOWN_GENERATION :{BLACK}Generació de poblacions +STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}Generació d'indústries terrestres +STR_GENERATION_WATER_INDUSTRY_GENERATION :{BLACK}Generació d'indústries a l'aigua STR_GENERATION_OBJECT_GENERATION :{BLACK}Generació inamovible STR_GENERATION_TREE_GENERATION :{BLACK}Generació d'arbres STR_GENERATION_SETTINGUP_GAME :{BLACK}Configurant la partida @@ -5269,6 +5273,13 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Inici i STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... els extrems del pont han d'estar tots dos a terra STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... el pont és massa llarg STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}El pont acabaria fora del mapa +STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}El pont és {HEIGHT} massa baix per a l'estació. +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}El pont és {HEIGHT} massa baix per a la parada de carretera. +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}El pont és {HEIGHT} massa baix per al moll. +STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}El pont és {HEIGHT} massa baix per a la boia. +STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}El pont és {HEIGHT} massa baix per al punt de pas. +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}El pont és {HEIGHT} massa baix per al punt de pas de carretera. +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}El pont és {HEIGHT} massa baix per a la resclosa. # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Aquí no es pot construir el túnel... diff --git a/src/lang/simplified_chinese.txt b/src/lang/simplified_chinese.txt index d89c02dac6386..17e04752d0214 100644 --- a/src/lang/simplified_chinese.txt +++ b/src/lang/simplified_chinese.txt @@ -254,6 +254,7 @@ STR_UNITS_FORCE_SI :{DECIMAL}{NBSP} STR_UNITS_HEIGHT_IMPERIAL :{DECIMAL}{NBSP}英尺 STR_UNITS_HEIGHT_METRIC :{DECIMAL}{NBSP}米 STR_UNITS_HEIGHT_SI :{DECIMAL}{NBSP}米 +STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}{NBSP}层 # Time units used in string control characters STR_UNITS_DAYS :{COMMA}{NBSP}日 @@ -2162,6 +2163,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :在界面上以 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :英制(呎) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :公制(米) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :国际单位制(米) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :游戏单位(层) STR_CONFIG_SETTING_LOCALISATION :本地化 STR_CONFIG_SETTING_GRAPHICS :图形 @@ -3471,6 +3473,8 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}景观 STR_GENERATION_RIVER_GENERATION :{BLACK}生成河流 STR_GENERATION_CLEARING_TILES :{BLACK}生成岩石地貌 STR_GENERATION_TOWN_GENERATION :{BLACK}城镇生成 +STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}生成陆上工业 +STR_GENERATION_WATER_INDUSTRY_GENERATION :{BLACK}生成水上工业 STR_GENERATION_OBJECT_GENERATION :{BLACK}生成固定设施 STR_GENERATION_TREE_GENERATION :{BLACK}生成树木 STR_GENERATION_SETTINGUP_GAME :{BLACK}设置游戏 @@ -5268,6 +5272,13 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}起止 STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}……桥梁两端必须都位于地面上 STR_ERROR_BRIDGE_TOO_LONG :{WHITE}……桥梁太长 STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}桥梁终点将越出地图 +STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}桥梁过低,尚需 {HEIGHT}净空以建设车站 +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}桥梁过低,尚需 {HEIGHT}净空以建设车站 +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}桥梁过低,尚需 {HEIGHT}净空以建设码头 +STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}桥梁过低,尚需 {HEIGHT}净空以放置浮标 +STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}桥梁过低,尚需 {HEIGHT}净空以建设路点 +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}桥梁过低,尚需 {HEIGHT}净空以建设路点 +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}桥梁过低,尚需 {HEIGHT}净空以建设船闸 # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}不能在这里开凿隧道…… diff --git a/src/lang/traditional_chinese.txt b/src/lang/traditional_chinese.txt index 89d7aabf11294..23c0ccb9e5bf6 100644 --- a/src/lang/traditional_chinese.txt +++ b/src/lang/traditional_chinese.txt @@ -241,11 +241,11 @@ STR_UNITS_WEIGHT_LONG_SI :{DECIMAL}{NBSP} STR_UNITS_VOLUME_SHORT_IMPERIAL :{DECIMAL}{NBSP}加侖 STR_UNITS_VOLUME_SHORT_METRIC :{DECIMAL}{NBSP}升 -STR_UNITS_VOLUME_SHORT_SI :{DECIMAL}{NBSP}米³ +STR_UNITS_VOLUME_SHORT_SI :{DECIMAL}{NBSP}立方公尺 STR_UNITS_VOLUME_LONG_IMPERIAL :{DECIMAL}{NBSP}加侖 STR_UNITS_VOLUME_LONG_METRIC :{DECIMAL}{NBSP}公升 -STR_UNITS_VOLUME_LONG_SI :{DECIMAL}{NBSP}立方米 +STR_UNITS_VOLUME_LONG_SI :{DECIMAL}{NBSP}立方公尺 STR_UNITS_FORCE_IMPERIAL :{DECIMAL}{NBSP}磅力 STR_UNITS_FORCE_METRIC :{DECIMAL}{NBSP}公斤力 @@ -2162,8 +2162,8 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :在界面上以 ###length 4 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :英制(英呎) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :米制(米) -STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :國際單位(米) -STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :遊戲單位(層次) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :國際單位(公尺) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :遊戲單位(層) STR_CONFIG_SETTING_LOCALISATION :本地化 STR_CONFIG_SETTING_GRAPHICS :圖形 From 534918ccb022babae0b9e48b40d21d2795ef5611 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 28 Oct 2025 22:05:23 +0000 Subject: [PATCH 091/137] Codechange: Simplify YAPF debug helpers a little. (#14741) Remove template magic to get C-array size. --- src/misc/dbg_helpers.cpp | 8 ++++---- src/misc/dbg_helpers.h | 33 ++++++++++--------------------- src/pathfinder/yapf/yapf_type.hpp | 2 +- 3 files changed, 15 insertions(+), 28 deletions(-) diff --git a/src/misc/dbg_helpers.cpp b/src/misc/dbg_helpers.cpp index bc51801fa9dca..65076410f66e6 100644 --- a/src/misc/dbg_helpers.cpp +++ b/src/misc/dbg_helpers.cpp @@ -23,13 +23,13 @@ static const std::string_view trackdir_names[] = { /** Return name of given Trackdir. */ std::string ValueStr(Trackdir td) { - return fmt::format("{} ({})", to_underlying(td), ItemAtT(td, trackdir_names, "UNK", INVALID_TRACKDIR, "INV")); + return fmt::format("{} ({})", to_underlying(td), ItemAt(td, trackdir_names, "UNK", INVALID_TRACKDIR, "INV")); } /** Return composed name of given TrackdirBits. */ std::string ValueStr(TrackdirBits td_bits) { - return fmt::format("{} ({})", to_underlying(td_bits), ComposeNameT(td_bits, trackdir_names, "UNK", INVALID_TRACKDIR_BIT, "INV")); + return fmt::format("{} ({})", to_underlying(td_bits), ComposeName(td_bits, trackdir_names, "UNK", INVALID_TRACKDIR_BIT, "INV")); } @@ -41,7 +41,7 @@ static const std::string_view diagdir_names[] = { /** Return name of given DiagDirection. */ std::string ValueStr(DiagDirection dd) { - return fmt::format("{} ({})", to_underlying(dd), ItemAtT(dd, diagdir_names, "UNK", INVALID_DIAGDIR, "INV")); + return fmt::format("{} ({})", to_underlying(dd), ItemAt(dd, diagdir_names, "UNK", INVALID_DIAGDIR, "INV")); } @@ -53,7 +53,7 @@ static const std::string_view signal_type_names[] = { /** Return name of given SignalType. */ std::string ValueStr(SignalType t) { - return fmt::format("{} ({})", to_underlying(t), ItemAtT(t, signal_type_names, "UNK")); + return fmt::format("{} ({})", to_underlying(t), ItemAt(t, signal_type_names, "UNK")); } diff --git a/src/misc/dbg_helpers.h b/src/misc/dbg_helpers.h index 69e598fb74b3f..6cf520e861e26 100644 --- a/src/misc/dbg_helpers.h +++ b/src/misc/dbg_helpers.h @@ -18,24 +18,14 @@ #include "../track_type.h" #include "../core/format.hpp" -/** Helper template class that provides C array length and item type */ -template struct ArrayT; - -/** Helper template class that provides C array length and item type */ -template struct ArrayT { - static const size_t length = N; - using Item = T; -}; - - /** * Helper template function that returns item of array at given index * or t_unk when index is out of bounds. */ -template -inline typename ArrayT::Item ItemAtT(E idx, const T &t, typename ArrayT::Item t_unk) +template +inline std::string_view ItemAt(E idx, std::span t, std::string_view t_unk) { - if (static_cast(idx) >= ArrayT::length) { + if (static_cast(idx) >= std::size(t)) { return t_unk; } return t[idx]; @@ -46,16 +36,13 @@ inline typename ArrayT::Item ItemAtT(E idx, const T &t, typename ArrayT::I * or t_inv when index == idx_inv * or t_unk when index is out of bounds. */ -template -inline typename ArrayT::Item ItemAtT(E idx, const T &t, typename ArrayT::Item t_unk, E idx_inv, typename ArrayT::Item t_inv) +template +inline std::string_view ItemAt(E idx, std::span t, std::string_view t_unk, E idx_inv, std::string_view t_inv) { - if (static_cast(idx) < ArrayT::length) { - return t[idx]; - } if (idx == idx_inv) { return t_inv; } - return t_unk; + return ItemAt(idx, t, t_unk); } /** @@ -64,8 +51,8 @@ inline typename ArrayT::Item ItemAtT(E idx, const T &t, typename ArrayT::I * or t_inv when index == idx_inv * or t_unk when index is out of bounds. */ -template -inline std::string ComposeNameT(E value, T &t, std::string_view t_unk, E val_inv, std::string_view name_inv) +template +inline std::string ComposeName(E value, std::span t, std::string_view t_unk, E val_inv, std::string_view name_inv) { std::string out; if (value == val_inv) { @@ -73,7 +60,7 @@ inline std::string ComposeNameT(E value, T &t, std::string_view t_unk, E val_inv } else if (value == 0) { out = ""; } else { - for (size_t i = 0; i < ArrayT::length; i++) { + for (size_t i = 0; i < std::size(t); i++) { if ((value & (1 << i)) == 0) continue; out += (!out.empty() ? "+" : ""); out += t[i]; @@ -93,7 +80,7 @@ inline std::string ComposeNameT(E value, T &t, std::string_view t_unk, E val_inv * or unknown_name when index is out of bounds. */ template -inline std::string ComposeNameT(E value, std::span names, std::string_view unknown_name) +inline std::string ComposeName(E value, std::span names, std::string_view unknown_name) { std::string out; if (value.base() == 0) { diff --git a/src/pathfinder/yapf/yapf_type.hpp b/src/pathfinder/yapf/yapf_type.hpp index 2a045e0785107..7aeb0f80af658 100644 --- a/src/pathfinder/yapf/yapf_type.hpp +++ b/src/pathfinder/yapf/yapf_type.hpp @@ -72,7 +72,7 @@ inline std::string ValueStr(EndSegmentReasons flags) "PATH_TOO_LONG", "FIRST_TWO_WAY_RED", "LOOK_AHEAD_END", "TARGET_REACHED" }; - return fmt::format("0x{:04X} ({})", flags.base(), ComposeNameT(flags, end_segment_reason_names, "UNK")); + return fmt::format("0x{:04X} ({})", flags.base(), ComposeName(flags, end_segment_reason_names, "UNK")); } #endif /* YAPF_TYPE_HPP */ From 3b0276130237da27138b0d34b7584783d7911d73 Mon Sep 17 00:00:00 2001 From: translators Date: Wed, 29 Oct 2025 04:41:13 +0000 Subject: [PATCH 092/137] Update: Translations from eints english (us): 11 changes by 2TallTyler --- src/lang/english_US.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index 3528b41f3f060..1a529a17b0048 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -254,6 +254,7 @@ STR_UNITS_FORCE_SI :{DECIMAL}{NBSP} STR_UNITS_HEIGHT_IMPERIAL :{DECIMAL}{NBSP}ft STR_UNITS_HEIGHT_METRIC :{DECIMAL}{NBSP}m STR_UNITS_HEIGHT_SI :{DECIMAL}{NBSP}m +STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}{NBSP}level{P "" s} # Time units used in string control characters STR_UNITS_DAYS :{COMMA}{NBSP}day{P "" s} @@ -2162,6 +2163,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Whenever a heig STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metric (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :Game units (levels) STR_CONFIG_SETTING_LOCALISATION :Localization STR_CONFIG_SETTING_GRAPHICS :Graphics @@ -3471,6 +3473,8 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Landscap STR_GENERATION_RIVER_GENERATION :{BLACK}River generation STR_GENERATION_CLEARING_TILES :{BLACK}Rough and rocky area generation STR_GENERATION_TOWN_GENERATION :{BLACK}Town generation +STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}Land industry generation +STR_GENERATION_WATER_INDUSTRY_GENERATION :{BLACK}Water industry generation STR_GENERATION_OBJECT_GENERATION :{BLACK}Object generation STR_GENERATION_TREE_GENERATION :{BLACK}Tree generation STR_GENERATION_SETTINGUP_GAME :{BLACK}Setting up game @@ -5268,6 +5272,13 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Start an STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... ends of bridge must both be on land STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... bridge too long STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Bridge would end out of the map +STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Bridge is {HEIGHT} too low for station +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Bridge is {HEIGHT} too low for road stop +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Bridge is {HEIGHT} too low for dock +STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Bridge is {HEIGHT} too low for buoy +STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Bridge is {HEIGHT} too low for rail waypoint +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Bridge is {HEIGHT} too low for road waypoint +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Bridge is {HEIGHT} too low for lock # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Can't build tunnel here... From 3ebedecb4a206006fabda84970ed8c79b810eb62 Mon Sep 17 00:00:00 2001 From: SamuXarick <43006711+SamuXarick@users.noreply.github.com> Date: Wed, 29 Oct 2025 20:18:00 +0000 Subject: [PATCH 093/137] Add: [Script] Auto-convert ObjectType bool to integer when setting values for items in lists via [] (#14308) --- src/script/api/script_list.cpp | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/script/api/script_list.cpp b/src/script/api/script_list.cpp index 90bc74d0b7910..086a6b603d43b 100644 --- a/src/script/api/script_list.cpp +++ b/src/script/api/script_list.cpp @@ -854,18 +854,32 @@ SQInteger ScriptList::_get(HSQUIRRELVM vm) SQInteger ScriptList::_set(HSQUIRRELVM vm) { if (sq_gettype(vm, 2) != OT_INTEGER) return SQ_ERROR; - if (sq_gettype(vm, 3) != OT_INTEGER && sq_gettype(vm, 3) != OT_NULL) { - return sq_throwerror(vm, "you can only assign integers to this list"); - } - SQInteger idx, val; + SQInteger idx; sq_getinteger(vm, 2, &idx); - if (sq_gettype(vm, 3) == OT_NULL) { - this->RemoveItem(idx); - return 0; + + /* Retrieve the return value */ + SQInteger val; + switch (sq_gettype(vm, 3)) { + case OT_NULL: + this->RemoveItem(idx); + return 0; + + case OT_BOOL: { + SQBool v; + sq_getbool(vm, 3, &v); + val = v ? 1 : 0; + break; + } + + case OT_INTEGER: + sq_getinteger(vm, 3, &val); + break; + + default: + return sq_throwerror(vm, "you can only assign integers to this list"); } - sq_getinteger(vm, 3, &val); if (!this->HasItem(idx)) { this->AddItem(idx, val); return 0; From 3f19240bbef1db737887130cf23f612bd9e31983 Mon Sep 17 00:00:00 2001 From: SamuXarick <43006711+SamuXarick@users.noreply.github.com> Date: Thu, 30 Oct 2025 17:36:43 +0000 Subject: [PATCH 094/137] Doc 313c6c4: [Script] GetAllRailTypes and GetRailType are from ScriptEngine (#14745) --- src/script/api/ai_changelog.hpp | 4 ++-- src/script/api/game_changelog.hpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/script/api/ai_changelog.hpp b/src/script/api/ai_changelog.hpp index 9d976962a1405..dbb10f1df7460 100644 --- a/src/script/api/ai_changelog.hpp +++ b/src/script/api/ai_changelog.hpp @@ -29,7 +29,7 @@ * \li AICargo::CC_NON_POTABLE * \li AIVehicleList_Waypoint * \li AIError::ERR_BRIDGE_TOO_LOW - * \li AIRail::GetAllRailTypes + * \li AIEngine::GetAllRailTypes * * Other changes: * \li AIBridge::GetBridgeID renamed to AIBridge::GetBridgeType @@ -37,7 +37,7 @@ * \li AIList instances can now be saved * \li AIVehicleList_Station accepts an optional AIVehicle::VehicleType parameter * \li AIList instances can now be cloned - * \li AIRail::GetRailType will only return the first RailType of an engine, use AIRail::GetAllRailTypes instead + * \li AIEngine::GetRailType will only return the first RailType of an engine, use AIEngine::GetAllRailTypes instead * * \b 14.0 * diff --git a/src/script/api/game_changelog.hpp b/src/script/api/game_changelog.hpp index 50c91de6bd620..4dbb379896ca0 100644 --- a/src/script/api/game_changelog.hpp +++ b/src/script/api/game_changelog.hpp @@ -30,7 +30,7 @@ * \li GSVehicleList_Waypoint * \li GSBaseStation::GetOwner * \li GSError::ERR_BRIDGE_TOO_LOW - * \li GSRail::GetAllRailTypes + * \li GSEngine::GetAllRailTypes * * Other changes: * \li GSBridge::GetBridgeID renamed to GSBridge::GetBridgeType @@ -38,7 +38,7 @@ * \li GSList instances can now be saved * \li GSVehicleList_Station accepts an optional GSVehicle::VehicleType parameter * \li GSList instances can now be cloned - * \li GSRail::GetRailType will only return the first RailType of an engine, use GSRail::GetAllRailTypes instead + * \li GSEngine::GetRailType will only return the first RailType of an engine, use GSEngine::GetAllRailTypes instead * * \b 14.0 * From 038c4d2b8783919de29e4bbb6d2e56410102c5fc Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Thu, 30 Oct 2025 20:22:30 +0000 Subject: [PATCH 095/137] Codechange: Make driver probe behave the same as loading by name. (#14736) Inconsistent initialisation order when setting active driver and starting the driver. --- src/driver.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/driver.cpp b/src/driver.cpp index 70e2071524379..10b0f890b4dc1 100644 --- a/src/driver.cpp +++ b/src/driver.cpp @@ -145,11 +145,12 @@ bool DriverFactoryBase::SelectDriverImpl(const std::string &name, Driver::Type t /* Keep old driver in case we need to switch back, or may still need to process an OS callback. */ auto oldd = std::move(GetActiveDriver(type)); - GetActiveDriver(type) = d->CreateInstance(); + auto newd = d->CreateInstance(); - auto err = GetActiveDriver(type)->Start({}); + auto err = newd->Start({}); if (!err) { Debug(driver, 1, "Successfully probed {} driver '{}'", GetDriverTypeName(type), d->name); + GetActiveDriver(type) = std::move(newd); return true; } From 20fd2b5014bdbafe554345f256b4688caf5b8dbc Mon Sep 17 00:00:00 2001 From: SamuXarick <43006711+SamuXarick@users.noreply.github.com> Date: Fri, 31 Oct 2025 11:38:49 +0000 Subject: [PATCH 096/137] Codefix: Add missing 'this->' in ScriptList (#14747) --- src/script/api/script_list.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/script/api/script_list.cpp b/src/script/api/script_list.cpp index 086a6b603d43b..fc629d39fe820 100644 --- a/src/script/api/script_list.cpp +++ b/src/script/api/script_list.cpp @@ -100,7 +100,7 @@ class ScriptListSorterValueAscending : public ScriptListSorter { this->item_next = *this->bucket_list_iter; SQInteger item_current = this->item_next; - FindNext(); + this->FindNext(); return item_current; } @@ -139,7 +139,7 @@ class ScriptListSorterValueAscending : public ScriptListSorter { if (this->IsEnd()) return 0; SQInteger item_current = this->item_next; - FindNext(); + this->FindNext(); return item_current; } @@ -149,7 +149,7 @@ class ScriptListSorterValueAscending : public ScriptListSorter { /* If we remove the 'next' item, skip to the next */ if (item == this->item_next) { - FindNext(); + this->FindNext(); return; } } @@ -194,7 +194,7 @@ class ScriptListSorterValueDescending : public ScriptListSorter { this->item_next = *this->bucket_list_iter; SQInteger item_current = this->item_next; - FindNext(); + this->FindNext(); return item_current; } @@ -234,7 +234,7 @@ class ScriptListSorterValueDescending : public ScriptListSorter { if (this->IsEnd()) return 0; SQInteger item_current = this->item_next; - FindNext(); + this->FindNext(); return item_current; } @@ -244,7 +244,7 @@ class ScriptListSorterValueDescending : public ScriptListSorter { /* If we remove the 'next' item, skip to the next */ if (item == this->item_next) { - FindNext(); + this->FindNext(); return; } } @@ -277,7 +277,7 @@ class ScriptListSorterItemAscending : public ScriptListSorter { this->item_next = this->item_iter->first; SQInteger item_current = this->item_next; - FindNext(); + this->FindNext(); return item_current; } @@ -296,7 +296,7 @@ class ScriptListSorterItemAscending : public ScriptListSorter { return; } ++this->item_iter; - if (this->item_iter != this->list->items.end()) item_next = this->item_iter->first; + if (this->item_iter != this->list->items.end()) this->item_next = this->item_iter->first; } SQInteger Next() override @@ -304,7 +304,7 @@ class ScriptListSorterItemAscending : public ScriptListSorter { if (this->IsEnd()) return 0; SQInteger item_current = this->item_next; - FindNext(); + this->FindNext(); return item_current; } @@ -314,7 +314,7 @@ class ScriptListSorterItemAscending : public ScriptListSorter { /* If we remove the 'next' item, skip to the next */ if (item == this->item_next) { - FindNext(); + this->FindNext(); return; } } @@ -351,7 +351,7 @@ class ScriptListSorterItemDescending : public ScriptListSorter { this->item_next = this->item_iter->first; SQInteger item_current = this->item_next; - FindNext(); + this->FindNext(); return item_current; } @@ -375,7 +375,7 @@ class ScriptListSorterItemDescending : public ScriptListSorter { } else { --this->item_iter; } - if (this->item_iter != this->list->items.end()) item_next = this->item_iter->first; + if (this->item_iter != this->list->items.end()) this->item_next = this->item_iter->first; } SQInteger Next() override @@ -383,7 +383,7 @@ class ScriptListSorterItemDescending : public ScriptListSorter { if (this->IsEnd()) return 0; SQInteger item_current = this->item_next; - FindNext(); + this->FindNext(); return item_current; } @@ -393,7 +393,7 @@ class ScriptListSorterItemDescending : public ScriptListSorter { /* If we remove the 'next' item, skip to the next */ if (item == this->item_next) { - FindNext(); + this->FindNext(); return; } } @@ -763,7 +763,7 @@ void ScriptList::RemoveList(ScriptList *list) this->modifications++; if (list == this) { - Clear(); + this->Clear(); } else { for (const auto &item : list->items) { this->RemoveItem(item.first); From 8ea347a811659b6105de91802fd5354a38322f1c Mon Sep 17 00:00:00 2001 From: Rito12 <111280526+Rito13@users.noreply.github.com> Date: Fri, 31 Oct 2025 15:26:47 +0100 Subject: [PATCH 097/137] Remove: Rail type cost from replace vehicle window. (#14748) --- src/newgrf_badge_gui.cpp | 5 +++++ src/newgrf_badge_gui.h | 1 + src/rail_gui.cpp | 2 +- src/road_gui.cpp | 2 +- 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/newgrf_badge_gui.cpp b/src/newgrf_badge_gui.cpp index 491986c82bfe8..0a1290fedb2ee 100644 --- a/src/newgrf_badge_gui.cpp +++ b/src/newgrf_badge_gui.cpp @@ -243,6 +243,11 @@ class DropDownBadges : public TBase { using DropDownListBadgeItem = DropDownBadges, FS_SMALL, true>>; using DropDownListBadgeIconItem = DropDownBadges, FS_SMALL, true>>; +std::unique_ptr MakeDropDownListBadgeItem(const std::shared_ptr &gui_classes, std::span badges, GrfSpecFeature feature, std::optional introduction_date, std::string &&str, int value, bool masked, bool shaded) +{ + return std::make_unique(gui_classes, badges, feature, introduction_date, "", std::move(str), value, masked, shaded); +} + std::unique_ptr MakeDropDownListBadgeItem(const std::shared_ptr &gui_classes, std::span badges, GrfSpecFeature feature, std::optional introduction_date, Money cost, std::string &&str, int value, bool masked, bool shaded) { return std::make_unique(gui_classes, badges, feature, introduction_date, GetString(STR_JUST_CURRENCY_SHORT, cost), std::move(str), value, masked, shaded); diff --git a/src/newgrf_badge_gui.h b/src/newgrf_badge_gui.h index b908cf7f5533f..bd47f05aaf145 100644 --- a/src/newgrf_badge_gui.h +++ b/src/newgrf_badge_gui.h @@ -50,6 +50,7 @@ class GUIBadgeClasses : public UsedBadgeClasses { int DrawBadgeNameList(Rect r, std::span badges, GrfSpecFeature feature); void DrawBadgeColumn(Rect r, int column_group, const GUIBadgeClasses &gui_classes, std::span badges, GrfSpecFeature feature, std::optional introduction_date, PaletteID remap); +std::unique_ptr MakeDropDownListBadgeItem(const std::shared_ptr &gui_classes, std::span badges, GrfSpecFeature feature, std::optional introduction_date, std::string &&str, int value, bool masked = false, bool shaded = false); std::unique_ptr MakeDropDownListBadgeItem(const std::shared_ptr &gui_classes, std::span badges, GrfSpecFeature feature, std::optional introduction_date, Money cost, std::string &&str, int value, bool masked = false, bool shaded = false); std::unique_ptr MakeDropDownListBadgeIconItem(const std::shared_ptr &gui_classes, std::span badges, GrfSpecFeature feature, std::optional introduction_date, Money cost, const Dimension &dim, SpriteID sprite, PaletteID palette, std::string &&str, int value, bool masked = false, bool shaded = false); diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index a0d8688096136..f577582df0d29 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -2065,7 +2065,7 @@ DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option) const RailTypeInfo *rti = GetRailTypeInfo(rt); if (for_replacement) { - list.push_back(MakeDropDownListBadgeItem(badge_class_list, rti->badges, GSF_RAILTYPES, rti->introduction_date, RailBuildCost(rt), GetString(rti->strings.replace_text), rt, !avail_railtypes.Test(rt))); + list.push_back(MakeDropDownListBadgeItem(badge_class_list, rti->badges, GSF_RAILTYPES, rti->introduction_date, GetString(rti->strings.replace_text), rt, !avail_railtypes.Test(rt))); } else { std::string str = rti->max_speed > 0 ? GetString(STR_TOOLBAR_RAILTYPE_VELOCITY, rti->strings.menu_text, rti->max_speed) diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 3e37167a7658e..7928f9c5a53ee 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -1805,7 +1805,7 @@ DropDownList GetRoadTypeDropDownList(RoadTramTypes rtts, bool for_replacement, b const RoadTypeInfo *rti = GetRoadTypeInfo(rt); if (for_replacement) { - list.push_back(MakeDropDownListBadgeItem(badge_class_list, rti->badges, GSF_ROADTYPES, rti->introduction_date, RoadBuildCost(rt), GetString(rti->strings.replace_text), rt, !avail_roadtypes.Test(rt))); + list.push_back(MakeDropDownListBadgeItem(badge_class_list, rti->badges, GSF_ROADTYPES, rti->introduction_date, GetString(rti->strings.replace_text), rt, !avail_roadtypes.Test(rt))); } else { std::string str = rti->max_speed > 0 ? GetString(STR_TOOLBAR_RAILTYPE_VELOCITY, rti->strings.menu_text, rti->max_speed / 2) From 7c855c69fa40a03530201cca3cb4784e3c326997 Mon Sep 17 00:00:00 2001 From: translators Date: Sat, 1 Nov 2025 04:37:15 +0000 Subject: [PATCH 098/137] Update: Translations from eints dutch: 11 changes by Afoklala --- src/lang/dutch.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt index 2fe998bbebd4d..ce787417e8521 100644 --- a/src/lang/dutch.txt +++ b/src/lang/dutch.txt @@ -254,6 +254,7 @@ STR_UNITS_FORCE_SI :{DECIMAL}{NBSP} STR_UNITS_HEIGHT_IMPERIAL :{DECIMAL}{NBSP}ft STR_UNITS_HEIGHT_METRIC :{DECIMAL}{NBSP}m STR_UNITS_HEIGHT_SI :{DECIMAL}{NBSP}m +STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}{NBSP}niveau{P "" s} # Time units used in string control characters STR_UNITS_DAYS :{COMMA}{NBSP}dag{P "" en} @@ -2162,6 +2163,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Wanneer hoogtes STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperiaal (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrisch (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :Speleenheden (niveaus) STR_CONFIG_SETTING_LOCALISATION :Lokalisatie STR_CONFIG_SETTING_GRAPHICS :Grafische elementen @@ -3471,6 +3473,8 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Landscha STR_GENERATION_RIVER_GENERATION :{BLACK}Rivierplaatsing STR_GENERATION_CLEARING_TILES :{BLACK}Ontwikkeling van ruig en rotsachtig gebied STR_GENERATION_TOWN_GENERATION :{BLACK}Steden genereren +STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}Landindustrieontwikkeling +STR_GENERATION_WATER_INDUSTRY_GENERATION :{BLACK}Waterindustrieontwikkeling STR_GENERATION_OBJECT_GENERATION :{BLACK}Ontwikkeling van onverplaatsbare objecten STR_GENERATION_TREE_GENERATION :{BLACK}Bosplaatsing STR_GENERATION_SETTINGUP_GAME :{BLACK}Spel wordt geconfigureerd @@ -5268,6 +5272,13 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Begin en STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... uiteinden van brug moeten beiden op land zijn STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... brug te lang STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Brug zou eindigen buiten de kaart +STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Brug is {HEIGHT} te laag voor station +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Brug is {HEIGHT} te laag voor halte +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Brug is {HEIGHT} te laag voor dok +STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Brug {HEIGHT} te laag voor boei +STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Brug {HEIGHT} te laag voor spoorroutepunt +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Brug is {HEIGHT} te laag voor wegroutepunt +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Brug is {HEIGHT} te laag voor sluis # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Kan hier geen tunnel bouwen... From 34bbae05dbb8997e65271afdef65e5526968d260 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 1 Nov 2025 14:25:24 +0000 Subject: [PATCH 099/137] Codechange: Use enum/EnumBitSet for livery in use flags. (#14746) Replaces magic numbers. --- src/company_cmd.cpp | 22 +++++++++++----------- src/company_gui.cpp | 10 +++++----- src/group_cmd.cpp | 18 +++++++++--------- src/livery.h | 9 ++++++++- src/saveload/company_sl.cpp | 4 ++-- src/script/api/script_group.cpp | 4 ++-- src/vehicle.cpp | 6 +++--- 7 files changed, 40 insertions(+), 33 deletions(-) diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 577f54b4b481f..c336e4bf21cb7 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -574,14 +574,14 @@ restart:; void ResetCompanyLivery(Company *c) { for (LiveryScheme scheme = LS_BEGIN; scheme < LS_END; scheme++) { - c->livery[scheme].in_use = 0; + c->livery[scheme].in_use.Reset(); c->livery[scheme].colour1 = c->colour; c->livery[scheme].colour2 = c->colour; } for (Group *g : Group::Iterate()) { if (g->owner == c->index) { - g->livery.in_use = 0; + g->livery.in_use.Reset(); g->livery.colour1 = c->colour; g->livery.colour2 = c->colour; } @@ -1077,8 +1077,8 @@ CommandCost CmdSetCompanyManagerFace(DoCommandFlags flags, uint style, uint32_t void UpdateCompanyLiveries(Company *c) { for (int i = 1; i < LS_END; i++) { - if (!HasBit(c->livery[i].in_use, 0)) c->livery[i].colour1 = c->livery[LS_DEFAULT].colour1; - if (!HasBit(c->livery[i].in_use, 1)) c->livery[i].colour2 = c->livery[LS_DEFAULT].colour2; + if (!c->livery[i].in_use.Test(Livery::Flag::Primary)) c->livery[i].colour1 = c->livery[LS_DEFAULT].colour1; + if (!c->livery[i].in_use.Test(Livery::Flag::Secondary)) c->livery[i].colour2 = c->livery[LS_DEFAULT].colour2; } UpdateCompanyGroupLiveries(c); } @@ -1109,7 +1109,7 @@ CommandCost CmdSetCompanyColour(DoCommandFlags flags, LiveryScheme scheme, bool if (flags.Test(DoCommandFlag::Execute)) { if (primary) { - if (scheme != LS_DEFAULT) AssignBit(c->livery[scheme].in_use, 0, colour != INVALID_COLOUR); + if (scheme != LS_DEFAULT) c->livery[scheme].in_use.Set(Livery::Flag::Primary, colour != INVALID_COLOUR); if (colour == INVALID_COLOUR) colour = c->livery[LS_DEFAULT].colour1; c->livery[scheme].colour1 = colour; @@ -1122,7 +1122,7 @@ CommandCost CmdSetCompanyColour(DoCommandFlags flags, LiveryScheme scheme, bool CompanyAdminUpdate(c); } } else { - if (scheme != LS_DEFAULT) AssignBit(c->livery[scheme].in_use, 1, colour != INVALID_COLOUR); + if (scheme != LS_DEFAULT) c->livery[scheme].in_use.Set(Livery::Flag::Secondary, colour != INVALID_COLOUR); if (colour == INVALID_COLOUR) colour = c->livery[LS_DEFAULT].colour2; c->livery[scheme].colour2 = colour; @@ -1131,16 +1131,16 @@ CommandCost CmdSetCompanyColour(DoCommandFlags flags, LiveryScheme scheme, bool } } - if (c->livery[scheme].in_use != 0) { + if (c->livery[scheme].in_use.Any({Livery::Flag::Primary, Livery::Flag::Secondary})) { /* If enabling a scheme, set the default scheme to be in use too */ - c->livery[LS_DEFAULT].in_use = 1; + c->livery[LS_DEFAULT].in_use.Set(Livery::Flag::Primary); } else { /* Else loop through all schemes to see if any are left enabled. * If not, disable the default scheme too. */ - c->livery[LS_DEFAULT].in_use = 0; + c->livery[LS_DEFAULT].in_use.Reset({Livery::Flag::Primary, Livery::Flag::Secondary}); for (scheme = LS_DEFAULT; scheme < LS_END; scheme++) { - if (c->livery[scheme].in_use != 0) { - c->livery[LS_DEFAULT].in_use = 1; + if (c->livery[scheme].in_use.Any({Livery::Flag::Primary, Livery::Flag::Secondary})) { + c->livery[LS_DEFAULT].in_use.Set(Livery::Flag::Primary); break; } } diff --git a/src/company_gui.cpp b/src/company_gui.cpp index bf336ed35a369..b302f5874e67b 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -655,7 +655,7 @@ struct SelectCompanyLiveryWindow : public Window { } uint8_t sel; - if (default_livery == nullptr || HasBit(livery->in_use, primary ? 0 : 1)) { + if (default_livery == nullptr || livery->in_use.Test(primary ? Livery::Flag::Primary : Livery::Flag::Secondary)) { sel = primary ? livery->colour1 : livery->colour2; } else { sel = default_col; @@ -819,7 +819,7 @@ struct SelectCompanyLiveryWindow : public Window { } if (scheme == LS_END) scheme = LS_DEFAULT; const Livery *livery = &c->livery[scheme]; - if (scheme == LS_DEFAULT || HasBit(livery->in_use, primary ? 0 : 1)) { + if (scheme == LS_DEFAULT || livery->in_use.Test(primary ? Livery::Flag::Primary : Livery::Flag::Secondary)) { colour = STR_COLOUR_DARK_BLUE + (primary ? livery->colour1 : livery->colour2); } } @@ -827,7 +827,7 @@ struct SelectCompanyLiveryWindow : public Window { if (this->sel != GroupID::Invalid()) { const Group *g = Group::Get(this->sel); const Livery *livery = &g->livery; - if (HasBit(livery->in_use, primary ? 0 : 1)) { + if (livery->in_use.Test(primary ? Livery::Flag::Primary : Livery::Flag::Secondary)) { colour = STR_COLOUR_DARK_BLUE + (primary ? livery->colour1 : livery->colour2); } } @@ -875,12 +875,12 @@ struct SelectCompanyLiveryWindow : public Window { /* Text below the first dropdown. */ DrawSprite(SPR_SQUARE, GetColourPalette(livery.colour1), pri_squ.left, y + square_offs); - DrawString(pri.left, pri.right, y + text_offs, (is_default_scheme || HasBit(livery.in_use, 0)) ? STR_COLOUR_DARK_BLUE + livery.colour1 : STR_COLOUR_DEFAULT, is_selected ? TC_WHITE : TC_GOLD); + DrawString(pri.left, pri.right, y + text_offs, (is_default_scheme || livery.in_use.Test(Livery::Flag::Primary)) ? STR_COLOUR_DARK_BLUE + livery.colour1 : STR_COLOUR_DEFAULT, is_selected ? TC_WHITE : TC_GOLD); /* Text below the second dropdown. */ if (sec.right > sec.left) { // Second dropdown has non-zero size. DrawSprite(SPR_SQUARE, GetColourPalette(livery.colour2), sec_squ.left, y + square_offs); - DrawString(sec.left, sec.right, y + text_offs, (is_default_scheme || HasBit(livery.in_use, 1)) ? STR_COLOUR_DARK_BLUE + livery.colour2 : STR_COLOUR_DEFAULT, is_selected ? TC_WHITE : TC_GOLD); + DrawString(sec.left, sec.right, y + text_offs, (is_default_scheme || livery.in_use.Test(Livery::Flag::Secondary)) ? STR_COLOUR_DARK_BLUE + livery.colour2 : STR_COLOUR_DEFAULT, is_selected ? TC_WHITE : TC_GOLD); } y += this->line_height; diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp index b0e4ce4ee57ab..2ba83c4dd892b 100644 --- a/src/group_cmd.cpp +++ b/src/group_cmd.cpp @@ -306,8 +306,8 @@ static void PropagateChildLivery(const Group *g, bool reset_cache) for (const GroupID &childgroup : g->children) { Group *cg = Group::Get(childgroup); - if (!HasBit(cg->livery.in_use, 0)) cg->livery.colour1 = g->livery.colour1; - if (!HasBit(cg->livery.in_use, 1)) cg->livery.colour2 = g->livery.colour2; + if (!cg->livery.in_use.Test(Livery::Flag::Primary)) cg->livery.colour1 = g->livery.colour1; + if (!cg->livery.in_use.Test(Livery::Flag::Secondary)) cg->livery.colour2 = g->livery.colour2; PropagateChildLivery(cg, reset_cache); } } @@ -321,8 +321,8 @@ void UpdateCompanyGroupLiveries(const Company *c) { for (Group *g : Group::Iterate()) { if (g->owner == c->index && g->parent == GroupID::Invalid()) { - if (!HasBit(g->livery.in_use, 0)) g->livery.colour1 = c->livery[LS_DEFAULT].colour1; - if (!HasBit(g->livery.in_use, 1)) g->livery.colour2 = c->livery[LS_DEFAULT].colour2; + if (!g->livery.in_use.Test(Livery::Flag::Primary)) g->livery.colour1 = c->livery[LS_DEFAULT].colour1; + if (!g->livery.in_use.Test(Livery::Flag::Secondary)) g->livery.colour2 = c->livery[LS_DEFAULT].colour2; PropagateChildLivery(g, false); } } @@ -480,11 +480,11 @@ CommandCost CmdAlterGroup(DoCommandFlags flags, AlterGroupMode mode, GroupID gro GroupStatistics::UpdateAutoreplace(g->owner); - if (!HasBit(g->livery.in_use, 0) || !HasBit(g->livery.in_use, 1)) { + if (!g->livery.in_use.All({Livery::Flag::Primary, Livery::Flag::Secondary})) { /* Update livery with new parent's colours if either colour is default. */ const Livery *livery = GetParentLivery(g); - if (!HasBit(g->livery.in_use, 0)) g->livery.colour1 = livery->colour1; - if (!HasBit(g->livery.in_use, 1)) g->livery.colour2 = livery->colour2; + if (!g->livery.in_use.Test(Livery::Flag::Primary)) g->livery.colour1 = livery->colour1; + if (!g->livery.in_use.Test(Livery::Flag::Secondary)) g->livery.colour2 = livery->colour2; PropagateChildLivery(g, true); MarkWholeScreenDirty(); @@ -684,11 +684,11 @@ CommandCost CmdSetGroupLivery(DoCommandFlags flags, GroupID group_id, bool prima if (flags.Test(DoCommandFlag::Execute)) { if (primary) { - AssignBit(g->livery.in_use, 0, colour != INVALID_COLOUR); + g->livery.in_use.Set(Livery::Flag::Primary, colour != INVALID_COLOUR); if (colour == INVALID_COLOUR) colour = GetParentLivery(g)->colour1; g->livery.colour1 = colour; } else { - AssignBit(g->livery.in_use, 1, colour != INVALID_COLOUR); + g->livery.in_use.Set(Livery::Flag::Secondary, colour != INVALID_COLOUR); if (colour == INVALID_COLOUR) colour = GetParentLivery(g)->colour2; g->livery.colour2 = colour; } diff --git a/src/livery.h b/src/livery.h index 2de27555d9782..31c39f78403ff 100644 --- a/src/livery.h +++ b/src/livery.h @@ -10,6 +10,7 @@ #ifndef LIVERY_H #define LIVERY_H +#include "core/enum_type.hpp" #include "company_type.h" #include "gfx_type.h" @@ -76,7 +77,13 @@ DECLARE_ENUM_AS_ADDABLE(LiveryClass) /** Information about a particular livery. */ struct Livery { - uint8_t in_use = 0; ///< Bit 0 set if this livery should override the default livery first colour, Bit 1 for the second colour. + enum class Flag : uint8_t { + Primary = 0, ///< Primary colour is set. + Secondary = 1, ///< Secondary colour is set. + }; + using Flags = EnumBitSet; + + Flags in_use{}; ///< Livery flags. Colours colour1 = COLOUR_BEGIN; ///< First colour, for all vehicles. Colours colour2 = COLOUR_BEGIN; ///< Second colour, for vehicles with 2CC support. }; diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index 679b42bded653..5ed2a63111519 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -445,11 +445,11 @@ class SlCompanyLiveries : public DefaultSaveLoadHandlerlivery[i], this->GetLoadDescription()); if (update_in_use && i != LS_DEFAULT) { - if (c->livery[i].in_use == 0) { + if (!c->livery[i].in_use.Any({Livery::Flag::Primary, Livery::Flag::Secondary})) { c->livery[i].colour1 = c->livery[LS_DEFAULT].colour1; c->livery[i].colour2 = c->livery[LS_DEFAULT].colour2; } else { - c->livery[i].in_use = 3; + c->livery[i].in_use = {Livery::Flag::Primary, Livery::Flag::Secondary}; } } } diff --git a/src/script/api/script_group.cpp b/src/script/api/script_group.cpp index 486032cd70090..5713fddc35ba5 100644 --- a/src/script/api/script_group.cpp +++ b/src/script/api/script_group.cpp @@ -241,7 +241,7 @@ EnforcePrecondition(ScriptCompany::Colours::COLOUR_INVALID, IsValidGroup(group_id)); const Group *g = ::Group::Get(group_id); - if (!HasBit(g->livery.in_use, 0)) return ScriptCompany::Colours::COLOUR_INVALID; + if (!g->livery.in_use.Test(Livery::Flag::Primary)) return ScriptCompany::Colours::COLOUR_INVALID; return (ScriptCompany::Colours)g->livery.colour1; } @@ -250,6 +250,6 @@ EnforcePrecondition(ScriptCompany::Colours::COLOUR_INVALID, IsValidGroup(group_id)); const Group *g = ::Group::Get(group_id); - if (!HasBit(g->livery.in_use, 1)) return ScriptCompany::Colours::COLOUR_INVALID; + if (!g->livery.in_use.Test(Livery::Flag::Secondary)) return ScriptCompany::Colours::COLOUR_INVALID; return (ScriptCompany::Colours)g->livery.colour2; } diff --git a/src/vehicle.cpp b/src/vehicle.cpp index bb1973e56edd2..95764752d252e 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -2052,16 +2052,16 @@ const Livery *GetEngineLivery(EngineID engine_type, CompanyID company, EngineID const Group *g = Group::GetIfValid(v->First()->group_id); if (g != nullptr) { /* Traverse parents until we find a livery or reach the top */ - while (g->livery.in_use == 0 && g->parent != GroupID::Invalid()) { + while (!g->livery.in_use.Any({Livery::Flag::Primary, Livery::Flag::Secondary}) && g->parent != GroupID::Invalid()) { g = Group::Get(g->parent); } - if (g->livery.in_use != 0) return &g->livery; + if (g->livery.in_use.Any({Livery::Flag::Primary, Livery::Flag::Secondary})) return &g->livery; } } /* The default livery is always available for use, but its in_use flag determines * whether any _other_ liveries are in use. */ - if (c->livery[LS_DEFAULT].in_use != 0) { + if (c->livery[LS_DEFAULT].in_use.Any({Livery::Flag::Primary, Livery::Flag::Secondary})) { /* Determine the livery scheme to use */ scheme = GetEngineLiveryScheme(engine_type, parent_engine_type, v); } From 66b6d71e3264a8fd8d9a7b1025d7e537af6c97ec Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 1 Nov 2025 22:33:00 +0000 Subject: [PATCH 100/137] Codechange: Use std::initializer_list for NWidgetPart data. (#14749) Avoids using C/C++ arrays. --- src/ai/ai_gui.cpp | 2 +- src/airport_gui.cpp | 4 ++-- src/autoreplace_gui.cpp | 6 +++--- src/bootstrap_gui.cpp | 8 ++++---- src/bridge_gui.cpp | 2 +- src/build_vehicle_gui.cpp | 2 +- src/cheat_gui.cpp | 2 +- src/company_gui.cpp | 12 ++++++------ src/console_gui.cpp | 2 +- src/date_gui.cpp | 2 +- src/depot_gui.cpp | 2 +- src/dock_gui.cpp | 8 ++++---- src/dropdown.cpp | 2 +- src/engine_gui.cpp | 2 +- src/error_gui.cpp | 4 ++-- src/fios_gui.cpp | 8 ++++---- src/framerate_gui.cpp | 4 ++-- src/game/game_gui.cpp | 2 +- src/genworld_gui.cpp | 8 ++++---- src/goal_gui.cpp | 2 +- src/graph_gui.cpp | 20 ++++++++++---------- src/group_gui.cpp | 2 +- src/help_gui.cpp | 2 +- src/highscore_gui.cpp | 2 +- src/industry_gui.cpp | 8 ++++---- src/intro_gui.cpp | 2 +- src/league_gui.cpp | 4 ++-- src/linkgraph/linkgraph_gui.cpp | 2 +- src/main_gui.cpp | 2 +- src/misc_gui.cpp | 10 +++++----- src/music_gui.cpp | 4 ++-- src/network/network_chat_gui.cpp | 2 +- src/network/network_content_gui.cpp | 4 ++-- src/network/network_gui.cpp | 12 ++++++------ src/newgrf_debug_gui.cpp | 6 +++--- src/newgrf_gui.cpp | 14 +++++++------- src/news_gui.cpp | 12 ++++++------ src/object_gui.cpp | 2 +- src/order_gui.cpp | 6 +++--- src/osk_gui.cpp | 2 +- src/picker_gui.cpp | 4 ++-- src/rail_gui.cpp | 10 +++++----- src/road_gui.cpp | 16 ++++++++-------- src/screenshot_gui.cpp | 2 +- src/script/script_gui.cpp | 6 +++--- src/settings_gui.cpp | 8 ++++---- src/signs_gui.cpp | 4 ++-- src/smallmap_gui.cpp | 6 +++--- src/station_gui.cpp | 6 +++--- src/statusbar_gui.cpp | 2 +- src/story_gui.cpp | 2 +- src/subsidy_gui.cpp | 2 +- src/terraform_gui.cpp | 4 ++-- src/textfile_gui.cpp | 2 +- src/timetable_gui.cpp | 2 +- src/toolbar_gui.cpp | 6 +++--- src/town_gui.cpp | 12 ++++++------ src/transparency_gui.cpp | 2 +- src/tree_gui.cpp | 2 +- src/vehicle_gui.cpp | 10 +++++----- src/viewport_gui.cpp | 2 +- src/waypoint_gui.cpp | 2 +- 62 files changed, 157 insertions(+), 157 deletions(-) diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp index c13e313130f94..4dd4a8c671a57 100644 --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.cpp @@ -28,7 +28,7 @@ /** Widgets for the configure AI window. */ -static constexpr NWidgetPart _nested_ai_config_widgets[] = { +static constexpr std::initializer_list _nested_ai_config_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_MAUVE), NWidget(WWT_CAPTION, COLOUR_MAUVE), SetStringTip(STR_AI_CONFIG_CAPTION_AI, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index 51ba9ffd66d44..35208579155b3 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -197,7 +197,7 @@ struct BuildAirToolbarWindow : Window { }, AirportToolbarGlobalHotkeys}; }; -static constexpr NWidgetPart _nested_air_toolbar_widgets[] = { +static constexpr std::initializer_list _nested_air_toolbar_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_TOOLBAR_AIRCRAFT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -580,7 +580,7 @@ class BuildAirportWindow : public PickerWindowBase { }}; }; -static constexpr NWidgetPart _nested_build_airport_widgets[] = { +static constexpr std::initializer_list _nested_build_airport_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_STATION_BUILD_AIRPORT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index 67f970776928b..d38708ce6b1b0 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -698,7 +698,7 @@ class ReplaceVehicleWindow : public Window { } }; -static constexpr NWidgetPart _nested_replace_rail_vehicle_widgets[] = { +static constexpr std::initializer_list _nested_replace_rail_vehicle_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_RV_CAPTION), @@ -762,7 +762,7 @@ static WindowDesc _replace_rail_vehicle_desc( _nested_replace_rail_vehicle_widgets ); -static constexpr NWidgetPart _nested_replace_road_vehicle_widgets[] = { +static constexpr std::initializer_list _nested_replace_road_vehicle_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_RV_CAPTION), @@ -820,7 +820,7 @@ static WindowDesc _replace_road_vehicle_desc( _nested_replace_road_vehicle_widgets ); -static constexpr NWidgetPart _nested_replace_vehicle_widgets[] = { +static constexpr std::initializer_list _nested_replace_vehicle_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_RV_CAPTION), SetMinimalSize(433, 14), diff --git a/src/bootstrap_gui.cpp b/src/bootstrap_gui.cpp index 1cfd582c0d8d7..3dcdeae43aab5 100644 --- a/src/bootstrap_gui.cpp +++ b/src/bootstrap_gui.cpp @@ -33,7 +33,7 @@ #include "safeguards.h" /** Widgets for the background window to prevent smearing. */ -static constexpr NWidgetPart _background_widgets[] = { +static constexpr std::initializer_list _background_widgets = { NWidget(WWT_PANEL, COLOUR_DARK_BLUE, WID_BB_BACKGROUND), SetResize(1, 1), EndContainer(), }; @@ -66,7 +66,7 @@ class BootstrapBackground : public Window { }; /** Nested widgets for the error window. */ -static constexpr NWidgetPart _nested_bootstrap_errmsg_widgets[] = { +static constexpr std::initializer_list _nested_bootstrap_errmsg_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CAPTION, COLOUR_GREY, WID_BEM_CAPTION), SetStringTip(STR_MISSING_GRAPHICS_ERROR_TITLE), EndContainer(), @@ -123,7 +123,7 @@ class BootstrapErrorWindow : public Window { }; /** Nested widgets for the download window. */ -static constexpr NWidgetPart _nested_bootstrap_download_status_window_widgets[] = { +static constexpr std::initializer_list _nested_bootstrap_download_status_window_widgets = { NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_CONTENT_DOWNLOAD_TITLE, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), NWidget(WWT_PANEL, COLOUR_GREY), NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), SetPadding(WidgetDimensions::unscaled.modalpopup), @@ -174,7 +174,7 @@ struct BootstrapContentDownloadStatusWindow : public BaseNetworkContentDownloadS }; /** The widgets for the query. It has no close box as that sprite does not exist yet. */ -static constexpr NWidgetPart _bootstrap_query_widgets[] = { +static constexpr std::initializer_list _bootstrap_query_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_MISSING_GRAPHICS_SET_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), EndContainer(), diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp index c29d8bb86db5a..ca4cc5161ce40 100644 --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.cpp @@ -309,7 +309,7 @@ const std::initializer_list BuildBridgeWind }; /** Widgets of the bridge gui. */ -static constexpr NWidgetPart _nested_build_bridge_widgets[] = { +static constexpr std::initializer_list _nested_build_bridge_widgets = { /* Header */ NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 812e9e32807ac..ea6efdcfc4219 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -58,7 +58,7 @@ uint GetEngineListHeight(VehicleType type) return std::max(GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.matrix.Vertical(), GetVehicleImageCellSize(type, EIT_PURCHASE).height); } -static constexpr NWidgetPart _nested_build_vehicle_widgets[] = { +static constexpr std::initializer_list _nested_build_vehicle_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_BV_CAPTION), SetTextStyle(TC_WHITE), diff --git a/src/cheat_gui.cpp b/src/cheat_gui.cpp index 5cbdb1f78f4bc..af45b55ac727a 100644 --- a/src/cheat_gui.cpp +++ b/src/cheat_gui.cpp @@ -219,7 +219,7 @@ static const CheatEntry _cheats_ui[] = { static_assert(CHT_NUM_CHEATS == lengthof(_cheats_ui)); /** Widget definitions of the cheat GUI. */ -static constexpr NWidgetPart _nested_cheat_widgets[] = { +static constexpr std::initializer_list _nested_cheat_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_CHEATS, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/company_gui.cpp b/src/company_gui.cpp index b302f5874e67b..29efaf7c3d566 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -286,7 +286,7 @@ static void DrawYearColumn(const Rect &r, TimerGameEconomy::Year year, const Exp DrawPrice(sum, r.left, r.right, y, TC_WHITE); } -static constexpr NWidgetPart _nested_company_finances_widgets[] = { +static constexpr std::initializer_list _nested_company_finances_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_CF_CAPTION), @@ -1062,7 +1062,7 @@ struct SelectCompanyLiveryWindow : public Window { } }; -static constexpr NWidgetPart _nested_select_company_livery_widgets[] = { +static constexpr std::initializer_list _nested_select_company_livery_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_SCL_CAPTION), @@ -1161,7 +1161,7 @@ void DrawCompanyManagerFace(const CompanyManagerFace &cmf, Colours colour, const } /** Nested widget description for the company manager face selection dialog */ -static constexpr NWidgetPart _nested_select_company_manager_face_widgets[] = { +static constexpr std::initializer_list _nested_select_company_manager_face_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_SCMF_CAPTION), SetStringTip(STR_FACE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -1536,7 +1536,7 @@ static void DoSelectCompanyManagerFace(Window *parent) new SelectCompanyManagerFaceWindow(_select_company_manager_face_desc, parent); } -static constexpr NWidgetPart _nested_company_infrastructure_widgets[] = { +static constexpr std::initializer_list _nested_company_infrastructure_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_CI_CAPTION), @@ -1840,7 +1840,7 @@ static void ShowCompanyInfrastructure(CompanyID company) AllocateWindowDescFront(_company_infrastructure_desc, company); } -static constexpr NWidgetPart _nested_company_widgets[] = { +static constexpr std::initializer_list _nested_company_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_C_CAPTION), @@ -2405,7 +2405,7 @@ struct BuyCompanyWindow : Window { Money company_value{}; ///< The value of the company for which the user can buy it. }; -static constexpr NWidgetPart _nested_buy_company_widgets[] = { +static constexpr std::initializer_list _nested_buy_company_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_LIGHT_BLUE), NWidget(WWT_CAPTION, COLOUR_LIGHT_BLUE, WID_BC_CAPTION), diff --git a/src/console_gui.cpp b/src/console_gui.cpp index 06db00510fc1c..1dba122e92c2d 100644 --- a/src/console_gui.cpp +++ b/src/console_gui.cpp @@ -133,7 +133,7 @@ static inline void IConsoleResetHistoryPos() static std::optional IConsoleHistoryAdd(std::string_view cmd); static void IConsoleHistoryNavigate(int direction); -static constexpr NWidgetPart _nested_console_window_widgets[] = { +static constexpr std::initializer_list _nested_console_window_widgets = { NWidget(WWT_EMPTY, INVALID_COLOUR, WID_C_BACKGROUND), SetResize(1, 1), }; diff --git a/src/date_gui.cpp b/src/date_gui.cpp index 02ab436d6335d..81dbbd5ffcfdf 100644 --- a/src/date_gui.cpp +++ b/src/date_gui.cpp @@ -173,7 +173,7 @@ struct SetDateWindow : Window { }; /** Widgets for the date setting window. */ -static constexpr NWidgetPart _nested_set_date_widgets[] = { +static constexpr std::initializer_list _nested_set_date_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN), SetStringTip(STR_DATE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 3644a31694225..bfec17d9aafa5 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -47,7 +47,7 @@ */ /** Nested widget definition for train depots. */ -static constexpr NWidgetPart _nested_train_depot_widgets[] = { +static constexpr std::initializer_list _nested_train_depot_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_D_SHOW_RENAME), SetAspect(WidgetDimensions::ASPECT_RENAME), // rename button diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index e247c01396f9f..caad21a280417 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -333,7 +333,7 @@ struct BuildDocksToolbarWindow : Window { * Nested widget parts of docks toolbar, game version. * Position of #WID_DT_RIVER widget has changed. */ -static constexpr NWidgetPart _nested_build_docks_toolbar_widgets[] = { +static constexpr std::initializer_list _nested_build_docks_toolbar_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_WATERWAYS_TOOLBAR_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -378,7 +378,7 @@ Window *ShowBuildDocksToolbar() * Nested widget parts of docks toolbar, scenario editor version. * Positions of #WID_DT_DEPOT, #WID_DT_STATION, and #WID_DT_BUOY widgets have changed. */ -static constexpr NWidgetPart _nested_build_docks_scen_toolbar_widgets[] = { +static constexpr std::initializer_list _nested_build_docks_scen_toolbar_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_WATERWAYS_TOOLBAR_CAPTION_SE, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -478,7 +478,7 @@ struct BuildDocksStationWindow : public PickerWindowBase { }; /** Nested widget parts of a build dock station window. */ -static constexpr NWidgetPart _nested_build_dock_station_widgets[] = { +static constexpr std::initializer_list _nested_build_dock_station_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_STATION_BUILD_DOCK_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -579,7 +579,7 @@ struct BuildDocksDepotWindow : public PickerWindowBase { } }; -static constexpr NWidgetPart _nested_build_docks_depot_widgets[] = { +static constexpr std::initializer_list _nested_build_docks_depot_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_DEPOT_BUILD_SHIP_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/dropdown.cpp b/src/dropdown.cpp index d3df9a731aee0..30e56c3fb2b30 100644 --- a/src/dropdown.cpp +++ b/src/dropdown.cpp @@ -56,7 +56,7 @@ std::unique_ptr MakeDropDownListCheckedItem(bool checked, Stri return std::make_unique(indent, checked, GetString(str), value, masked, shaded); } -static constexpr NWidgetPart _nested_dropdown_menu_widgets[] = { +static constexpr std::initializer_list _nested_dropdown_menu_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_PANEL, COLOUR_END, WID_DM_ITEMS), SetScrollbar(WID_DM_SCROLL), EndContainer(), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_DM_SHOW_SCROLL), diff --git a/src/engine_gui.cpp b/src/engine_gui.cpp index 19a4eff047ead..43389f974755b 100644 --- a/src/engine_gui.cpp +++ b/src/engine_gui.cpp @@ -52,7 +52,7 @@ StringID GetEngineCategoryName(EngineID engine) } } -static constexpr NWidgetPart _nested_engine_preview_widgets[] = { +static constexpr std::initializer_list _nested_engine_preview_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_LIGHT_BLUE), NWidget(WWT_CAPTION, COLOUR_LIGHT_BLUE), SetStringTip(STR_ENGINE_PREVIEW_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/error_gui.cpp b/src/error_gui.cpp index ed5d0b2ab1813..7fe4cc6f12b23 100644 --- a/src/error_gui.cpp +++ b/src/error_gui.cpp @@ -33,7 +33,7 @@ #include "safeguards.h" -static constexpr NWidgetPart _nested_errmsg_widgets[] = { +static constexpr std::initializer_list _nested_errmsg_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_RED), NWidget(WWT_CAPTION, COLOUR_RED, WID_EM_CAPTION), SetStringTip(STR_ERROR_MESSAGE_CAPTION), @@ -50,7 +50,7 @@ static WindowDesc _errmsg_desc( _nested_errmsg_widgets ); -static constexpr NWidgetPart _nested_errmsg_face_widgets[] = { +static constexpr std::initializer_list _nested_errmsg_face_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_RED), NWidget(WWT_CAPTION, COLOUR_RED, WID_EM_CAPTION), diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index 6c2dfb8b90be5..a4d593dbcfbce 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -65,7 +65,7 @@ void LoadCheckData::Clear() } /** Load game/scenario with optional content download */ -static constexpr NWidgetPart _nested_load_dialog_widgets[] = { +static constexpr std::initializer_list _nested_load_dialog_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_SL_CAPTION), @@ -128,7 +128,7 @@ static constexpr NWidgetPart _nested_load_dialog_widgets[] = { }; /** Load heightmap with content download */ -static constexpr NWidgetPart _nested_load_heightmap_dialog_widgets[] = { +static constexpr std::initializer_list _nested_load_heightmap_dialog_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_SL_CAPTION), @@ -175,7 +175,7 @@ static constexpr NWidgetPart _nested_load_heightmap_dialog_widgets[] = { }; /** Load town data */ -static constexpr NWidgetPart _nested_load_town_data_dialog_widgets[] = { +static constexpr std::initializer_list _nested_load_town_data_dialog_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_SL_CAPTION), @@ -217,7 +217,7 @@ static constexpr NWidgetPart _nested_load_town_data_dialog_widgets[] = { }; /** Save game/scenario */ -static constexpr NWidgetPart _nested_save_dialog_widgets[] = { +static constexpr std::initializer_list _nested_save_dialog_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_SL_CAPTION), diff --git a/src/framerate_gui.cpp b/src/framerate_gui.cpp index 72c0aa2f970b7..df390d28223b6 100644 --- a/src/framerate_gui.cpp +++ b/src/framerate_gui.cpp @@ -377,7 +377,7 @@ static std::string_view GetAIName(int ai_index) } /** @hideinitializer */ -static constexpr NWidgetPart _framerate_window_widgets[] = { +static constexpr std::initializer_list _framerate_window_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_FRW_CAPTION), @@ -695,7 +695,7 @@ static WindowDesc _framerate_display_desc( /** @hideinitializer */ -static constexpr NWidgetPart _frametime_graph_window_widgets[] = { +static constexpr std::initializer_list _frametime_graph_window_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_FGW_CAPTION), SetTextStyle(TC_WHITE), diff --git a/src/game/game_gui.cpp b/src/game/game_gui.cpp index ec47cd6eb5b19..34e2e30342d41 100644 --- a/src/game/game_gui.cpp +++ b/src/game/game_gui.cpp @@ -33,7 +33,7 @@ /** Widgets for the configure GS window. */ -static constexpr NWidgetPart _nested_gs_config_widgets[] = { +static constexpr std::initializer_list _nested_gs_config_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_MAUVE), NWidget(WWT_CAPTION, COLOUR_MAUVE), SetStringTip(STR_AI_CONFIG_CAPTION_GAMESCRIPT, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index 12d78035bea49..b98c34c6089a2 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -74,7 +74,7 @@ void SetNewLandscapeType(LandscapeType landscape) } /** Widgets of GenerateLandscapeWindow when generating world */ -static constexpr NWidgetPart _nested_generate_landscape_widgets[] = { +static constexpr std::initializer_list _nested_generate_landscape_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN), SetStringTip(STR_MAPGEN_WORLD_GENERATION_CAPTION), @@ -198,7 +198,7 @@ static constexpr NWidgetPart _nested_generate_landscape_widgets[] = { }; /** Widgets of GenerateLandscapeWindow when loading heightmap */ -static constexpr NWidgetPart _nested_heightmap_load_widgets[] = { +static constexpr std::initializer_list _nested_heightmap_load_widgets = { /* Window header. */ NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), @@ -1244,7 +1244,7 @@ struct CreateScenarioWindow : public Window } }; -static constexpr NWidgetPart _nested_create_scenario_widgets[] = { +static constexpr std::initializer_list _nested_create_scenario_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN), SetStringTip(STR_SE_MAPGEN_CAPTION), @@ -1317,7 +1317,7 @@ void ShowCreateScenario() new CreateScenarioWindow(_create_scenario_desc, GLWM_SCENARIO); } -static constexpr NWidgetPart _nested_generate_progress_widgets[] = { +static constexpr std::initializer_list _nested_generate_progress_widgets = { NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_GENERATION_WORLD, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), NWidget(WWT_PANEL, COLOUR_GREY), NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), SetPadding(WidgetDimensions::unscaled.modalpopup), diff --git a/src/goal_gui.cpp b/src/goal_gui.cpp index ccf9d98b1efe3..e44e66644ccaa 100644 --- a/src/goal_gui.cpp +++ b/src/goal_gui.cpp @@ -275,7 +275,7 @@ struct GoalListWindow : public Window { }; /** Widgets of the #GoalListWindow. */ -static constexpr NWidgetPart _nested_goals_list_widgets[] = { +static constexpr std::initializer_list _nested_goals_list_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN, WID_GOAL_CAPTION), diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index 962b201405f51..74b916c168caf 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -133,7 +133,7 @@ static std::unique_ptr MakeNWidgetCompanyLines() return vert; } -static constexpr NWidgetPart _nested_graph_legend_widgets[] = { +static constexpr std::initializer_list _nested_graph_legend_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN), SetStringTip(STR_GRAPH_KEY_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -935,7 +935,7 @@ struct OperatingProfitGraphWindow : BaseCompanyGraphWindow { } }; -static constexpr NWidgetPart _nested_operating_profit_widgets[] = { +static constexpr std::initializer_list _nested_operating_profit_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN), SetStringTip(STR_GRAPH_OPERATING_PROFIT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -988,7 +988,7 @@ struct IncomeGraphWindow : BaseCompanyGraphWindow { } }; -static constexpr NWidgetPart _nested_income_graph_widgets[] = { +static constexpr std::initializer_list _nested_income_graph_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN), SetStringTip(STR_GRAPH_INCOME_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -1039,7 +1039,7 @@ struct DeliveredCargoGraphWindow : BaseCompanyGraphWindow { } }; -static constexpr NWidgetPart _nested_delivered_cargo_graph_widgets[] = { +static constexpr std::initializer_list _nested_delivered_cargo_graph_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN), SetStringTip(STR_GRAPH_CARGO_DELIVERED_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -1096,7 +1096,7 @@ struct PerformanceHistoryGraphWindow : BaseCompanyGraphWindow { } }; -static constexpr NWidgetPart _nested_performance_history_widgets[] = { +static constexpr std::initializer_list _nested_performance_history_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN), SetStringTip(STR_GRAPH_COMPANY_PERFORMANCE_RATINGS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -1148,7 +1148,7 @@ struct CompanyValueGraphWindow : BaseCompanyGraphWindow { } }; -static constexpr NWidgetPart _nested_company_value_graph_widgets[] = { +static constexpr std::initializer_list _nested_company_value_graph_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN), SetStringTip(STR_GRAPH_COMPANY_VALUES_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -1412,7 +1412,7 @@ struct PaymentRatesGraphWindow : BaseCargoGraphWindow { } }; -static constexpr NWidgetPart _nested_cargo_payment_rates_widgets[] = { +static constexpr std::initializer_list _nested_cargo_payment_rates_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN), SetStringTip(STR_GRAPH_CARGO_PAYMENT_RATES_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -1813,7 +1813,7 @@ struct IndustryProductionGraphWindow : BaseCargoGraphWindow { } }; -static constexpr NWidgetPart _nested_industry_production_widgets[] = { +static constexpr std::initializer_list _nested_industry_production_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN, WID_GRAPH_CAPTION), @@ -1957,7 +1957,7 @@ struct TownCargoGraphWindow : BaseCargoGraphWindow { } }; -static constexpr NWidgetPart _nested_town_cargo_graph_widgets[] = { +static constexpr std::initializer_list _nested_town_cargo_graph_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN, WID_GRAPH_CAPTION), @@ -2042,7 +2042,7 @@ std::unique_ptr MakeCompanyButtonRowsGraphGUI() return MakeCompanyButtonRows(WID_PRD_COMPANY_FIRST, WID_PRD_COMPANY_LAST, COLOUR_BROWN, 8, STR_PERFORMANCE_DETAIL_SELECT_COMPANY_TOOLTIP); } -static constexpr NWidgetPart _nested_performance_rating_detail_widgets[] = { +static constexpr std::initializer_list _nested_performance_rating_detail_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN), SetStringTip(STR_PERFORMANCE_DETAIL, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/group_gui.cpp b/src/group_gui.cpp index aa761e7c72677..af4d073c1a3d2 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -38,7 +38,7 @@ #include "safeguards.h" -static constexpr NWidgetPart _nested_group_widgets[] = { +static constexpr std::initializer_list _nested_group_widgets = { NWidget(NWID_HORIZONTAL), // Window header NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_GL_CAPTION), diff --git a/src/help_gui.cpp b/src/help_gui.cpp index 14c18652a8848..b9fa907227cde 100644 --- a/src/help_gui.cpp +++ b/src/help_gui.cpp @@ -175,7 +175,7 @@ struct HelpWindow : public Window { } }; -static constexpr NWidgetPart _nested_helpwin_widgets[] = { +static constexpr std::initializer_list _nested_helpwin_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_HELP_WINDOW_CAPTION), diff --git a/src/highscore_gui.cpp b/src/highscore_gui.cpp index fde61eb60bde8..e5e0a3da4fafe 100644 --- a/src/highscore_gui.cpp +++ b/src/highscore_gui.cpp @@ -217,7 +217,7 @@ struct HighScoreWindow : EndGameHighScoreBaseWindow { } }; -static constexpr NWidgetPart _nested_highscore_widgets[] = { +static constexpr std::initializer_list _nested_highscore_widgets = { NWidget(WWT_PANEL, COLOUR_BROWN, WID_H_BACKGROUND), SetResize(1, 1), EndContainer(), }; diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index a4f94228e232e..25ac005796492 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -257,7 +257,7 @@ void SortIndustryTypes() std::sort(_sorted_industry_types.begin(), _sorted_industry_types.end(), IndustryTypeNameSorter); } -static constexpr NWidgetPart _nested_build_industry_widgets[] = { +static constexpr std::initializer_list _nested_build_industry_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_FUND_INDUSTRY_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -1204,7 +1204,7 @@ static void UpdateIndustryProduction(Industry *i) } /** Widget definition of the view industry gui */ -static constexpr NWidgetPart _nested_industry_view_widgets[] = { +static constexpr std::initializer_list _nested_industry_view_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_CREAM), NWidget(WWT_CAPTION, COLOUR_CREAM, WID_IV_CAPTION), @@ -1242,7 +1242,7 @@ void ShowIndustryViewWindow(IndustryID industry) } /** Widget definition of the industry directory gui */ -static constexpr NWidgetPart _nested_industry_directory_widgets[] = { +static constexpr std::initializer_list _nested_industry_directory_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN, WID_ID_CAPTION), @@ -1931,7 +1931,7 @@ void ShowIndustryDirectory() } /** Widgets of the industry cargoes window. */ -static constexpr NWidgetPart _nested_industry_cargoes_widgets[] = { +static constexpr std::initializer_list _nested_industry_cargoes_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN, WID_IC_CAPTION), diff --git a/src/intro_gui.cpp b/src/intro_gui.cpp index 642b6f979280d..2d84c1ec6c5a6 100644 --- a/src/intro_gui.cpp +++ b/src/intro_gui.cpp @@ -343,7 +343,7 @@ struct SelectGameWindow : public Window { } }; -static constexpr NWidgetPart _nested_select_game_widgets[] = { +static constexpr std::initializer_list _nested_select_game_widgets = { NWidget(WWT_CAPTION, COLOUR_BROWN), SetStringTip(STR_INTRO_CAPTION), NWidget(WWT_PANEL, COLOUR_BROWN), NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), SetPadding(WidgetDimensions::unscaled.sparse), diff --git a/src/league_gui.cpp b/src/league_gui.cpp index 4278ad0ba0c54..9c1a6a40e4512 100644 --- a/src/league_gui.cpp +++ b/src/league_gui.cpp @@ -180,7 +180,7 @@ class PerformanceLeagueWindow : public Window { } }; -static constexpr NWidgetPart _nested_performance_league_widgets[] = { +static constexpr std::initializer_list _nested_performance_league_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN), SetStringTip(STR_COMPANY_LEAGUE_TABLE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -416,7 +416,7 @@ class ScriptLeagueWindow : public Window { } }; -static constexpr NWidgetPart _nested_script_league_widgets[] = { +static constexpr std::initializer_list _nested_script_league_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN, WID_SLT_CAPTION), diff --git a/src/linkgraph/linkgraph_gui.cpp b/src/linkgraph/linkgraph_gui.cpp index 5cb9320b418a3..e31dd166aaa4c 100644 --- a/src/linkgraph/linkgraph_gui.cpp +++ b/src/linkgraph/linkgraph_gui.cpp @@ -496,7 +496,7 @@ std::unique_ptr MakeCargoesLegendLinkGraphGUI() } -static constexpr NWidgetPart _nested_linkgraph_legend_widgets[] = { +static constexpr std::initializer_list _nested_linkgraph_legend_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_LGL_CAPTION), SetStringTip(STR_LINKGRAPH_LEGEND_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/main_gui.cpp b/src/main_gui.cpp index 2b7a9b9d8f2d3..9cf5411ec071f 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -177,7 +177,7 @@ void FixTitleGameZoom(int zoom_adjust) vp.virtual_height = ScaleByZoom(vp.height, vp.zoom); } -static constexpr NWidgetPart _nested_main_window_widgets[] = { +static constexpr std::initializer_list _nested_main_window_widgets = { NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_M_VIEWPORT), SetResize(1, 1), }; diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 55b2b8b867909..5b9d683a554af 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -47,7 +47,7 @@ enum OskActivation : uint8_t { }; -static constexpr NWidgetPart _nested_land_info_widgets[] = { +static constexpr std::initializer_list _nested_land_info_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_LAND_AREA_INFORMATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -319,7 +319,7 @@ void ShowLandInfo(TileIndex tile) new LandInfoWindow(tile); } -static constexpr NWidgetPart _nested_about_widgets[] = { +static constexpr std::initializer_list _nested_about_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_ABOUT_OPENTTD, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -586,7 +586,7 @@ void HideFillingPercent(TextEffectID *te_id) *te_id = INVALID_TE_ID; } -static constexpr NWidgetPart _nested_tooltips_widgets[] = { +static constexpr std::initializer_list _nested_tooltips_widgets = { NWidget(WWT_EMPTY, INVALID_COLOUR, WID_TT_BACKGROUND), }; @@ -975,7 +975,7 @@ struct QueryStringWindow : public Window } }; -static constexpr NWidgetPart _nested_query_string_widgets[] = { +static constexpr std::initializer_list _nested_query_string_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_QS_CAPTION), SetTextStyle(TC_WHITE), @@ -1113,7 +1113,7 @@ struct QueryWindow : public Window { } }; -static constexpr NWidgetPart _nested_query_widgets[] = { +static constexpr std::initializer_list _nested_query_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_RED), NWidget(WWT_CAPTION, COLOUR_RED, WID_Q_CAPTION), diff --git a/src/music_gui.cpp b/src/music_gui.cpp index cbd30c6c40d7f..7bdbf2dead7db 100644 --- a/src/music_gui.cpp +++ b/src/music_gui.cpp @@ -621,7 +621,7 @@ struct MusicTrackSelectionWindow : public Window { } }; -static constexpr NWidgetPart _nested_music_track_selection_widgets[] = { +static constexpr std::initializer_list _nested_music_track_selection_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_MTS_CAPTION), @@ -857,7 +857,7 @@ struct MusicWindow : public Window { } }; -static constexpr NWidgetPart _nested_music_window_widgets[] = { +static constexpr std::initializer_list _nested_music_window_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_MUSIC_JAZZ_JUKEBOX_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/network/network_chat_gui.cpp b/src/network/network_chat_gui.cpp index 30bf187c10647..865036b424f58 100644 --- a/src/network/network_chat_gui.cpp +++ b/src/network/network_chat_gui.cpp @@ -411,7 +411,7 @@ struct NetworkChatWindow : public Window { }; /** The widgets of the chat window. */ -static constexpr NWidgetPart _nested_chat_window_widgets[] = { +static constexpr std::initializer_list _nested_chat_window_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY, WID_NC_CLOSE), NWidget(WWT_PANEL, COLOUR_GREY, WID_NC_BACKGROUND), diff --git a/src/network/network_content_gui.cpp b/src/network/network_content_gui.cpp index a184511f98b75..76acaa217fac2 100644 --- a/src/network/network_content_gui.cpp +++ b/src/network/network_content_gui.cpp @@ -84,7 +84,7 @@ static void ShowContentTextfileWindow(Window *parent, TextfileType file_type, co } /** Nested widgets for the download window. */ -static constexpr NWidgetPart _nested_network_content_download_status_window_widgets[] = { +static constexpr std::initializer_list _nested_network_content_download_status_window_widgets = { NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_CONTENT_DOWNLOAD_TITLE, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), NWidget(WWT_PANEL, COLOUR_GREY), NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), SetPadding(WidgetDimensions::unscaled.modalpopup), @@ -1025,7 +1025,7 @@ void BuildContentTypeStringList() } /** The widgets for the content list. */ -static constexpr NWidgetPart _nested_network_content_list_widgets[] = { +static constexpr std::initializer_list _nested_network_content_list_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_LIGHT_BLUE), NWidget(WWT_CAPTION, COLOUR_LIGHT_BLUE), SetStringTip(STR_CONTENT_TITLE), diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index a437f776f7c45..9aa146e95f6d5 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -854,7 +854,7 @@ static std::unique_ptr MakeResizableHeader() return std::make_unique(); } -static constexpr NWidgetPart _nested_network_game_widgets[] = { +static constexpr std::initializer_list _nested_network_game_widgets = { /* TOP */ NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_LIGHT_BLUE), @@ -1129,7 +1129,7 @@ struct NetworkStartServerWindow : public Window { } }; -static constexpr NWidgetPart _nested_network_start_server_window_widgets[] = { +static constexpr std::initializer_list _nested_network_start_server_window_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_LIGHT_BLUE), NWidget(WWT_CAPTION, COLOUR_LIGHT_BLUE), SetStringTip(STR_NETWORK_START_SERVER_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -1217,7 +1217,7 @@ static void ShowNetworkStartServerWindow() extern void DrawCompanyIcon(CompanyID cid, int x, int y); -static constexpr NWidgetPart _nested_client_list_widgets[] = { +static constexpr std::initializer_list _nested_client_list_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_NETWORK_CLIENT_LIST_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -2097,7 +2097,7 @@ struct NetworkJoinStatusWindow : Window { } }; -static constexpr NWidgetPart _nested_network_join_status_window_widgets[] = { +static constexpr std::initializer_list _nested_network_join_status_window_widgets = { NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_NETWORK_CONNECTING_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), NWidget(WWT_PANEL, COLOUR_GREY), NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), SetPadding(WidgetDimensions::unscaled.modalpopup), @@ -2198,7 +2198,7 @@ struct NetworkAskRelayWindow : public Window { } }; -static constexpr NWidgetPart _nested_network_ask_relay_widgets[] = { +static constexpr std::initializer_list _nested_network_ask_relay_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_RED), NWidget(WWT_CAPTION, COLOUR_RED, WID_NAR_CAPTION), SetStringTip(STR_NETWORK_ASK_RELAY_CAPTION), @@ -2293,7 +2293,7 @@ struct NetworkAskSurveyWindow : public Window { } }; -static constexpr NWidgetPart _nested_network_ask_survey_widgets[] = { +static constexpr std::initializer_list _nested_network_ask_survey_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_NAS_CAPTION), SetStringTip(STR_NETWORK_ASK_SURVEY_CAPTION), diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp index f3780370bf05a..e9ba84f5c910d 100644 --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -624,7 +624,7 @@ struct NewGRFInspectWindow : Window { /* static */ uint32_t NewGRFInspectWindow::var60params[GSF_FAKE_END][0x20] = { {0} }; // Use spec to have 0s in whole array -static constexpr NWidgetPart _nested_newgrf_inspect_chain_widgets[] = { +static constexpr std::initializer_list _nested_newgrf_inspect_chain_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_NGRFI_CAPTION), SetStringTip(STR_NEWGRF_INSPECT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -648,7 +648,7 @@ static constexpr NWidgetPart _nested_newgrf_inspect_chain_widgets[] = { EndContainer(), }; -static constexpr NWidgetPart _nested_newgrf_inspect_widgets[] = { +static constexpr std::initializer_list _nested_newgrf_inspect_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_NGRFI_CAPTION), SetStringTip(STR_NEWGRF_INSPECT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -1119,7 +1119,7 @@ struct SpriteAlignerWindow : Window { bool SpriteAlignerWindow::centre = true; bool SpriteAlignerWindow::crosshair = true; -static constexpr NWidgetPart _nested_sprite_aligner_widgets[] = { +static constexpr std::initializer_list _nested_sprite_aligner_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_SA_CAPTION), diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index 86a8b38e03c41..60d7b70f08161 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -500,7 +500,7 @@ struct NewGRFParametersWindow : public Window { GRFParameterInfo NewGRFParametersWindow::dummy_parameter_info(0); -static constexpr NWidgetPart _nested_newgrf_parameter_widgets[] = { +static constexpr std::initializer_list _nested_newgrf_parameter_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_MAUVE), NWidget(WWT_CAPTION, COLOUR_MAUVE, WID_NP_CAPTION), @@ -1743,7 +1743,7 @@ class NWidgetNewGRFDisplay : public NWidgetBase { const uint NWidgetNewGRFDisplay::MAX_EXTRA_INFO_WIDTH = 150; const uint NWidgetNewGRFDisplay::MIN_EXTRA_FOR_3_COLUMNS = 50; -static constexpr NWidgetPart _nested_newgrf_actives_widgets[] = { +static constexpr std::initializer_list _nested_newgrf_actives_widgets = { NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), /* Left side, presets. */ NWidget(NWID_VERTICAL), @@ -1798,7 +1798,7 @@ static constexpr NWidgetPart _nested_newgrf_actives_widgets[] = { EndContainer(), }; -static constexpr NWidgetPart _nested_newgrf_availables_widgets[] = { +static constexpr std::initializer_list _nested_newgrf_availables_widgets = { NWidget(WWT_FRAME, COLOUR_MAUVE), SetStringTip(STR_NEWGRF_SETTINGS_INACTIVE_LIST), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), /* Left side, available grfs, filter edit box. */ NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), @@ -1831,7 +1831,7 @@ static constexpr NWidgetPart _nested_newgrf_availables_widgets[] = { EndContainer(), }; -static constexpr NWidgetPart _nested_newgrf_infopanel_widgets[] = { +static constexpr std::initializer_list _nested_newgrf_infopanel_widgets = { NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), /* Right side, info panel. */ NWidget(WWT_PANEL, COLOUR_MAUVE), @@ -1886,7 +1886,7 @@ std::unique_ptr NewGRFDisplay() } /* Widget definition of the manage newgrfs window */ -static constexpr NWidgetPart _nested_newgrf_widgets[] = { +static constexpr std::initializer_list _nested_newgrf_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_MAUVE), NWidget(WWT_CAPTION, COLOUR_MAUVE), SetStringTip(STR_NEWGRF_SETTINGS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -1970,7 +1970,7 @@ void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFC } /** Widget parts of the save preset window. */ -static constexpr NWidgetPart _nested_save_preset_widgets[] = { +static constexpr std::initializer_list _nested_save_preset_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_SAVE_PRESET_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -2123,7 +2123,7 @@ static void ShowSavePresetWindow(std::string_view initial_text) } /** Widgets for the progress window. */ -static constexpr NWidgetPart _nested_scan_progress_widgets[] = { +static constexpr std::initializer_list _nested_scan_progress_widgets = { NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_NEWGRF_SCAN_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), NWidget(WWT_PANEL, COLOUR_GREY), NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), SetPadding(WidgetDimensions::unscaled.modalpopup), diff --git a/src/news_gui.cpp b/src/news_gui.cpp index 351f5595619da..1e45fbd2b4371 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -102,7 +102,7 @@ static TileIndex GetReferenceTile(const NewsReference &reference) } /* Normal news items. */ -static constexpr NWidgetPart _nested_normal_news_widgets[] = { +static constexpr std::initializer_list _nested_normal_news_widgets = { NWidget(WWT_PANEL, COLOUR_WHITE, WID_N_PANEL), NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.fullbevel), NWidget(NWID_LAYER, INVALID_COLOUR), @@ -134,7 +134,7 @@ static WindowDesc _normal_news_desc( ); /* New vehicles news items. */ -static constexpr NWidgetPart _nested_vehicle_news_widgets[] = { +static constexpr std::initializer_list _nested_vehicle_news_widgets = { NWidget(WWT_PANEL, COLOUR_WHITE, WID_N_PANEL), NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.fullbevel), NWidget(NWID_LAYER, INVALID_COLOUR), @@ -182,7 +182,7 @@ static WindowDesc _vehicle_news_desc( ); /* Company news items. */ -static constexpr NWidgetPart _nested_company_news_widgets[] = { +static constexpr std::initializer_list _nested_company_news_widgets = { NWidget(WWT_PANEL, COLOUR_WHITE, WID_N_PANEL), NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.fullbevel), NWidget(NWID_LAYER, INVALID_COLOUR), @@ -227,7 +227,7 @@ static WindowDesc _company_news_desc( ); /* Thin news items. */ -static constexpr NWidgetPart _nested_thin_news_widgets[] = { +static constexpr std::initializer_list _nested_thin_news_widgets = { NWidget(WWT_PANEL, COLOUR_WHITE, WID_N_PANEL), NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.fullbevel), NWidget(NWID_LAYER, INVALID_COLOUR), @@ -261,7 +261,7 @@ static WindowDesc _thin_news_desc( ); /* Small news items. */ -static constexpr NWidgetPart _nested_small_news_widgets[] = { +static constexpr std::initializer_list _nested_small_news_widgets = { /* Caption + close box. The caption is not WWT_CAPTION as the window shall not be moveable and so on. */ NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_LIGHT_BLUE, WID_N_CLOSEBOX), @@ -1275,7 +1275,7 @@ struct MessageHistoryWindow : Window { } }; -static constexpr NWidgetPart _nested_message_history[] = { +static constexpr std::initializer_list _nested_message_history = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN), SetStringTip(STR_MESSAGE_HISTORY, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/object_gui.cpp b/src/object_gui.cpp index 6f1207e585154..76ba2f1199395 100644 --- a/src/object_gui.cpp +++ b/src/object_gui.cpp @@ -385,7 +385,7 @@ class BuildObjectWindow : public PickerWindow { }, BuildObjectGlobalHotkeys}; }; -static constexpr NWidgetPart _nested_build_object_widgets[] = { +static constexpr std::initializer_list _nested_build_object_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_OBJECT_BUILD_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/order_gui.cpp b/src/order_gui.cpp index 8193b6b411e3d..d131681252774 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -1586,7 +1586,7 @@ struct OrdersWindow : public Window { }; /** Nested widget definition for "your" train orders. */ -static constexpr NWidgetPart _nested_orders_train_widgets[] = { +static constexpr std::initializer_list _nested_orders_train_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_O_CAPTION), @@ -1663,7 +1663,7 @@ static WindowDesc _orders_train_desc( ); /** Nested widget definition for "your" orders (non-train). */ -static constexpr NWidgetPart _nested_orders_widgets[] = { +static constexpr std::initializer_list _nested_orders_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_O_CAPTION), SetStringTip(STR_ORDERS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -1736,7 +1736,7 @@ static WindowDesc _orders_desc( ); /** Nested widget definition for competitor orders. */ -static constexpr NWidgetPart _nested_other_orders_widgets[] = { +static constexpr std::initializer_list _nested_other_orders_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_O_CAPTION), SetStringTip(STR_ORDERS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/osk_gui.cpp b/src/osk_gui.cpp index 0e67c0a09e505..cddf84e884b94 100644 --- a/src/osk_gui.cpp +++ b/src/osk_gui.cpp @@ -321,7 +321,7 @@ static std::unique_ptr MakeSpacebarKeys() } -static constexpr NWidgetPart _nested_osk_widgets[] = { +static constexpr std::initializer_list _nested_osk_widgets = { NWidget(WWT_CAPTION, COLOUR_GREY, WID_OSK_CAPTION), SetTextStyle(TC_WHITE), NWidget(WWT_PANEL, COLOUR_GREY), NWidget(WWT_EDITBOX, COLOUR_GREY, WID_OSK_TEXT), SetMinimalSize(252, 0), SetPadding(2, 2, 2, 2), diff --git a/src/picker_gui.cpp b/src/picker_gui.cpp index 2f636cf8f7391..4c4bbc5ae010a 100644 --- a/src/picker_gui.cpp +++ b/src/picker_gui.cpp @@ -738,7 +738,7 @@ void PickerWindow::EnsureSelectedTypeIsVisible() /** Create nested widgets for the class picker widgets. */ std::unique_ptr MakePickerClassWidgets() { - static constexpr NWidgetPart picker_class_widgets[] = { + static constexpr std::initializer_list picker_class_widgets = { NWidget(NWID_SELECTION, INVALID_COLOUR, WID_PW_CLASS_SEL), NWidget(NWID_VERTICAL), NWidget(WWT_PANEL, COLOUR_DARK_GREEN), @@ -761,7 +761,7 @@ std::unique_ptr MakePickerClassWidgets() /** Create nested widgets for the type picker widgets. */ std::unique_ptr MakePickerTypeWidgets() { - static constexpr NWidgetPart picker_type_widgets[] = { + static constexpr std::initializer_list picker_type_widgets = { NWidget(NWID_SELECTION, INVALID_COLOUR, WID_PW_TYPE_SEL), NWidget(NWID_VERTICAL), NWidget(NWID_HORIZONTAL), diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index f577582df0d29..98400d2363fc6 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -857,7 +857,7 @@ struct BuildRailToolbarWindow : Window { }, RailToolbarGlobalHotkeys}; }; -static constexpr NWidgetPart _nested_build_rail_widgets[] = { +static constexpr std::initializer_list _nested_build_rail_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_RAT_CAPTION), SetTextStyle(TC_WHITE), @@ -1383,7 +1383,7 @@ struct BuildRailStationWindow : public PickerWindow { }, BuildRailStationGlobalHotkeys}; }; -static constexpr NWidgetPart _nested_station_builder_widgets[] = { +static constexpr std::initializer_list _nested_station_builder_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_STATION_BUILD_RAIL_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -1625,7 +1625,7 @@ struct BuildSignalWindow : public PickerWindowBase { }; /** Nested widget definition of the build signal window */ -static constexpr NWidgetPart _nested_signal_builder_widgets[] = { +static constexpr std::initializer_list _nested_signal_builder_widgets = { /* Title bar and buttons. */ NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), @@ -1752,7 +1752,7 @@ struct BuildRailDepotWindow : public PickerWindowBase { }; /** Nested widget definition of the build rail depot window */ -static constexpr NWidgetPart _nested_build_depot_widgets[] = { +static constexpr std::initializer_list _nested_build_depot_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_BUILD_DEPOT_TRAIN_ORIENTATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -1877,7 +1877,7 @@ struct BuildRailWaypointWindow : public PickerWindow { }; /** Nested widget definition for the build NewGRF rail waypoint window */ -static constexpr NWidgetPart _nested_build_waypoint_widgets[] = { +static constexpr std::initializer_list _nested_build_waypoint_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_WAYPOINT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 7928f9c5a53ee..7aac90b4b9ff1 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -899,7 +899,7 @@ struct BuildRoadToolbarWindow : Window { }, TramToolbarGlobalHotkeys}; }; -static constexpr NWidgetPart _nested_build_road_widgets[] = { +static constexpr std::initializer_list _nested_build_road_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetTextStyle(TC_WHITE), @@ -946,7 +946,7 @@ static WindowDesc _build_road_desc( &BuildRoadToolbarWindow::road_hotkeys ); -static constexpr NWidgetPart _nested_build_tramway_widgets[] = { +static constexpr std::initializer_list _nested_build_tramway_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetTextStyle(TC_WHITE), @@ -1009,7 +1009,7 @@ Window *ShowBuildRoadToolbar(RoadType roadtype) return AllocateWindowDescFront(RoadTypeIsRoad(_cur_roadtype) ? _build_road_desc : _build_tramway_desc, TRANSPORT_ROAD); } -static constexpr NWidgetPart _nested_build_road_scen_widgets[] = { +static constexpr std::initializer_list _nested_build_road_scen_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetTextStyle(TC_WHITE), @@ -1048,7 +1048,7 @@ static WindowDesc _build_road_scen_desc( &BuildRoadToolbarWindow::road_hotkeys ); -static constexpr NWidgetPart _nested_build_tramway_scen_widgets[] = { +static constexpr std::initializer_list _nested_build_tramway_scen_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetTextStyle(TC_WHITE), @@ -1155,7 +1155,7 @@ struct BuildRoadDepotWindow : public PickerWindowBase { } }; -static constexpr NWidgetPart _nested_build_road_depot_widgets[] = { +static constexpr std::initializer_list _nested_build_road_depot_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_BROD_CAPTION), SetStringTip(STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -1513,7 +1513,7 @@ struct BuildRoadStationWindow : public PickerWindow { }; /** Widget definition of the build road station window */ -static constexpr NWidgetPart _nested_road_station_picker_widgets[] = { +static constexpr std::initializer_list _nested_road_station_picker_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_BROS_CAPTION), @@ -1575,7 +1575,7 @@ static WindowDesc _road_station_picker_desc( ); /** Widget definition of the build tram station window */ -static constexpr NWidgetPart _nested_tram_station_picker_widgets[] = { +static constexpr std::initializer_list _nested_tram_station_picker_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_BROS_CAPTION), @@ -1714,7 +1714,7 @@ struct BuildRoadWaypointWindow : public PickerWindow { }; /** Nested widget definition for the build NewGRF road waypoint window */ -static constexpr NWidgetPart _nested_build_road_waypoint_widgets[] = { +static constexpr std::initializer_list _nested_build_road_waypoint_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_WAYPOINT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/screenshot_gui.cpp b/src/screenshot_gui.cpp index 49a2d73c48d82..5bb532dc50516 100644 --- a/src/screenshot_gui.cpp +++ b/src/screenshot_gui.cpp @@ -47,7 +47,7 @@ struct ScreenshotWindow : Window { } }; -static constexpr NWidgetPart _nested_screenshot[] = { +static constexpr std::initializer_list _nested_screenshot = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_SCREENSHOT_CAPTION), diff --git a/src/script/script_gui.cpp b/src/script/script_gui.cpp index ece3632c6f71b..74d9a11b8cda9 100644 --- a/src/script/script_gui.cpp +++ b/src/script/script_gui.cpp @@ -244,7 +244,7 @@ struct ScriptListWindow : public Window { }; /** Widgets for the AI list window. */ -static constexpr NWidgetPart _nested_script_list_widgets[] = { +static constexpr std::initializer_list _nested_script_list_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_MAUVE), NWidget(WWT_CAPTION, COLOUR_MAUVE, WID_SCRL_CAPTION), @@ -555,7 +555,7 @@ struct ScriptSettingsWindow : public Window { }; /** Widgets for the Script settings window. */ -static constexpr NWidgetPart _nested_script_settings_widgets[] = { +static constexpr std::initializer_list _nested_script_settings_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_MAUVE), NWidget(WWT_CAPTION, COLOUR_MAUVE, WID_SCRS_CAPTION), @@ -1200,7 +1200,7 @@ std::unique_ptr MakeCompanyButtonRowsScriptDebug() } /** Widgets for the Script debug window. */ -static constexpr NWidgetPart _nested_script_debug_widgets[] = { +static constexpr std::initializer_list _nested_script_debug_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_AI_DEBUG, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 7b0c9e1a15143..806d37b688d03 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -202,7 +202,7 @@ static constexpr TextColour GAME_OPTIONS_LABEL = TC_LIGHT_BLUE; /** Colour for selected text of game options. */ static constexpr TextColour GAME_OPTIONS_SELECTED = TC_WHITE; -static constexpr NWidgetPart _nested_social_plugins_widgets[] = { +static constexpr std::initializer_list _nested_social_plugins_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_FRAME, GAME_OPTIONS_BACKGROUND, WID_GO_SOCIAL_PLUGIN_TITLE), SetTextStyle(GAME_OPTIONS_FRAME), NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0), @@ -217,7 +217,7 @@ static constexpr NWidgetPart _nested_social_plugins_widgets[] = { EndContainer(), }; -static constexpr NWidgetPart _nested_social_plugins_none_widgets[] = { +static constexpr std::initializer_list _nested_social_plugins_none_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_TEXT, INVALID_COLOUR), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_GAME_OPTIONS_SOCIAL_PLUGINS_NONE), SetTextStyle(GAME_OPTIONS_LABEL), EndContainer(), @@ -1602,7 +1602,7 @@ struct GameOptionsWindow : Window { } }; -static constexpr NWidgetPart _nested_game_options_widgets[] = { +static constexpr std::initializer_list _nested_game_options_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, GAME_OPTIONS_BACKGROUND), NWidget(WWT_CAPTION, GAME_OPTIONS_BACKGROUND), SetStringTip(STR_GAME_OPTIONS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -2142,7 +2142,7 @@ struct CustomCurrencyWindow : Window { } }; -static constexpr NWidgetPart _nested_cust_currency_widgets[] = { +static constexpr std::initializer_list _nested_cust_currency_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_CURRENCY_WINDOW, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/signs_gui.cpp b/src/signs_gui.cpp index 37b0ccebab229..eb62f3e95ddab 100644 --- a/src/signs_gui.cpp +++ b/src/signs_gui.cpp @@ -329,7 +329,7 @@ struct SignListWindow : Window, SignList { }, SignListGlobalHotkeys}; }; -static constexpr NWidgetPart _nested_sign_list_widgets[] = { +static constexpr std::initializer_list _nested_sign_list_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN, WID_SIL_CAPTION), @@ -504,7 +504,7 @@ struct SignWindow : Window, SignList { } }; -static constexpr NWidgetPart _nested_query_sign_edit_widgets[] = { +static constexpr std::initializer_list _nested_query_sign_edit_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_QES_CAPTION), SetTextStyle(TC_WHITE), diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index 64a5b4c5650be..984083b37d35d 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -1963,14 +1963,14 @@ class NWidgetSmallmapDisplay : public NWidgetContainer { }; /** Widget parts of the smallmap display. */ -static constexpr NWidgetPart _nested_smallmap_display[] = { +static constexpr std::initializer_list _nested_smallmap_display = { NWidget(WWT_PANEL, COLOUR_BROWN, WID_SM_MAP_BORDER), NWidget(WWT_INSET, COLOUR_BROWN, WID_SM_MAP), SetMinimalSize(346, 140), SetResize(1, 1), SetPadding(2, 2, 2, 2), EndContainer(), EndContainer(), }; /** Widget parts of the smallmap legend bar + image buttons. */ -static constexpr NWidgetPart _nested_smallmap_bar[] = { +static constexpr std::initializer_list _nested_smallmap_bar = { NWidget(WWT_PANEL, COLOUR_BROWN), NWidget(NWID_HORIZONTAL), NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SM_LEGEND), SetResize(1, 1), @@ -2020,7 +2020,7 @@ static std::unique_ptr SmallMapDisplay() return map_display; } -static constexpr NWidgetPart _nested_smallmap_widgets[] = { +static constexpr std::initializer_list _nested_smallmap_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN, WID_SM_CAPTION), diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 1f88fe385bb65..9cb198d434f86 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -759,7 +759,7 @@ const std::initializer_list CompanyStation &StationRatingMinSorter }; -static constexpr NWidgetPart _nested_company_stations_widgets[] = { +static constexpr std::initializer_list _nested_company_stations_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_STL_CAPTION), @@ -811,7 +811,7 @@ void ShowCompanyStations(CompanyID company) AllocateWindowDescFront(_company_stations_desc, company); } -static constexpr NWidgetPart _nested_station_view_widgets[] = { +static constexpr std::initializer_list _nested_station_view_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SV_RENAME), SetAspect(WidgetDimensions::ASPECT_RENAME), SetSpriteTip(SPR_RENAME, STR_STATION_VIEW_RENAME_TOOLTIP), @@ -2269,7 +2269,7 @@ static void FindStationsNearby(TileArea ta, bool distant_join) } } -static constexpr NWidgetPart _nested_select_station_widgets[] = { +static constexpr std::initializer_list _nested_select_station_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_JS_CAPTION), SetStringTip(STR_JOIN_STATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/statusbar_gui.cpp b/src/statusbar_gui.cpp index ffd5e904945e0..b6e698731815a 100644 --- a/src/statusbar_gui.cpp +++ b/src/statusbar_gui.cpp @@ -210,7 +210,7 @@ struct StatusBarWindow : Window { }}; }; -static constexpr NWidgetPart _nested_main_status_widgets[] = { +static constexpr std::initializer_list _nested_main_status_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_PANEL, COLOUR_GREY, WID_S_LEFT), SetMinimalSize(140, 12), EndContainer(), NWidget(WWT_PUSHBTN, COLOUR_GREY, WID_S_MIDDLE), SetMinimalSize(40, 12), SetToolTip(STR_STATUSBAR_TOOLTIP_SHOW_LAST_NEWS), SetResize(1, 0), diff --git a/src/story_gui.cpp b/src/story_gui.cpp index f3c1d4feb0d86..1c2605e1b3ebe 100644 --- a/src/story_gui.cpp +++ b/src/story_gui.cpp @@ -937,7 +937,7 @@ const std::initializer_list Story &PageElementOrderSorter, }; -static constexpr NWidgetPart _nested_story_book_widgets[] = { +static constexpr std::initializer_list _nested_story_book_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN, WID_SB_CAPTION), diff --git a/src/subsidy_gui.cpp b/src/subsidy_gui.cpp index b57bcbe35ccc1..77c8807c7e11d 100644 --- a/src/subsidy_gui.cpp +++ b/src/subsidy_gui.cpp @@ -262,7 +262,7 @@ struct SubsidyListWindow : Window { } }; -static constexpr NWidgetPart _nested_subsidies_list_widgets[] = { +static constexpr std::initializer_list _nested_subsidies_list_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN), SetStringTip(STR_SUBSIDIES_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index 7c0f388a603ba..239f347025bc4 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -316,7 +316,7 @@ struct TerraformToolbarWindow : Window { }, TerraformToolbarGlobalHotkeys}; }; -static constexpr NWidgetPart _nested_terraform_widgets[] = { +static constexpr std::initializer_list _nested_terraform_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_LANDSCAPING_TOOLBAR, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -445,7 +445,7 @@ static const int8_t _multi_terraform_coords[][2] = { {-28, 0}, {-24, -2}, {-20, -4}, {-16, -6}, {-12, -8}, { -8,-10}, { -4,-12}, { 0,-14}, { 4,-12}, { 8,-10}, { 12, -8}, { 16, -6}, { 20, -4}, { 24, -2}, { 28, 0}, }; -static constexpr NWidgetPart _nested_scen_edit_land_gen_widgets[] = { +static constexpr std::initializer_list _nested_scen_edit_land_gen_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_TERRAFORM_TOOLBAR_LAND_GENERATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/textfile_gui.cpp b/src/textfile_gui.cpp index 4c3f31d49b461..115467f397eb5 100644 --- a/src/textfile_gui.cpp +++ b/src/textfile_gui.cpp @@ -40,7 +40,7 @@ #include "safeguards.h" /** Widgets for the textfile window. */ -static constexpr NWidgetPart _nested_textfile_widgets[] = { +static constexpr std::initializer_list _nested_textfile_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_MAUVE), NWidget(WWT_PUSHARROWBTN, COLOUR_MAUVE, WID_TF_NAVBACK), SetFill(0, 1), SetMinimalSize(15, 1), SetArrowWidgetTypeTip(AWV_DECREASE, STR_TEXTFILE_NAVBACK_TOOLTIP), diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index 65732342b0e46..ea3e253e59586 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -797,7 +797,7 @@ struct TimetableWindow : Window { }}; }; -static constexpr NWidgetPart _nested_timetable_widgets[] = { +static constexpr std::initializer_list _nested_timetable_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_VT_CAPTION), diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index eba265fc7ba42..b37ef7e837304 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -2207,7 +2207,7 @@ static std::unique_ptr MakeMainToolbar() return hor; } -static constexpr NWidgetPart _nested_toolbar_normal_widgets[] = { +static constexpr std::initializer_list _nested_toolbar_normal_widgets = { NWidgetFunction(MakeMainToolbar), }; @@ -2510,7 +2510,7 @@ struct ScenarioEditorToolbarWindow : Window { }}; }; -static constexpr NWidgetPart _nested_toolb_scen_inner_widgets[] = { +static constexpr std::initializer_list _nested_toolb_scen_inner_widgets = { NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_PAUSE), SetSpriteTip(SPR_IMG_PAUSE, STR_TOOLBAR_TOOLTIP_PAUSE_GAME), NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_FAST_FORWARD), SetSpriteTip(SPR_IMG_FASTFORWARD, STR_TOOLBAR_TOOLTIP_FORWARD), NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_SETTINGS), SetSpriteTip(SPR_IMG_SETTINGS, STR_TOOLBAR_TOOLTIP_OPTIONS), @@ -2550,7 +2550,7 @@ static std::unique_ptr MakeScenarioToolbar() return MakeNWidgets(_nested_toolb_scen_inner_widgets, std::make_unique()); } -static constexpr NWidgetPart _nested_toolb_scen_widgets[] = { +static constexpr std::initializer_list _nested_toolb_scen_widgets = { NWidgetFunction(MakeScenarioToolbar), }; diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 2659adc38a3e1..492d6e75f33d7 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -58,7 +58,7 @@ TownKdtree _town_local_authority_kdtree{}; typedef GUIList GUITownList; -static constexpr NWidgetPart _nested_town_authority_widgets[] = { +static constexpr std::initializer_list _nested_town_authority_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN, WID_TA_CAPTION), @@ -611,7 +611,7 @@ struct TownViewWindow : Window { }}; }; -static constexpr NWidgetPart _nested_town_game_view_widgets[] = { +static constexpr std::initializer_list _nested_town_game_view_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_TV_CHANGE_NAME), SetAspect(WidgetDimensions::ASPECT_RENAME), SetSpriteTip(SPR_RENAME, STR_TOWN_VIEW_RENAME_TOOLTIP), @@ -642,7 +642,7 @@ static WindowDesc _town_game_view_desc( _nested_town_game_view_widgets ); -static constexpr NWidgetPart _nested_town_editor_view_widgets[] = { +static constexpr std::initializer_list _nested_town_editor_view_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_TV_CHANGE_NAME), SetAspect(WidgetDimensions::ASPECT_RENAME), SetSpriteTip(SPR_RENAME, STR_TOWN_VIEW_RENAME_TOOLTIP), @@ -686,7 +686,7 @@ void ShowTownViewWindow(TownID town) } } -static constexpr NWidgetPart _nested_town_directory_widgets[] = { +static constexpr std::initializer_list _nested_town_directory_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN, WID_TD_CAPTION), @@ -1068,7 +1068,7 @@ void CcFoundRandomTown(Commands, const CommandCost &result, Money, TownID town_i if (result.Succeeded()) ScrollMainWindowToTile(Town::Get(town_id)->xy); } -static constexpr NWidgetPart _nested_found_town_widgets[] = { +static constexpr std::initializer_list _nested_found_town_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_FOUND_TOWN_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -1805,7 +1805,7 @@ struct BuildHouseWindow : public PickerWindow { }; /** Nested widget definition for the build NewGRF rail waypoint window */ -static constexpr NWidgetPart _nested_build_house_widgets[] = { +static constexpr std::initializer_list _nested_build_house_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_HOUSE_PICKER_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/transparency_gui.cpp b/src/transparency_gui.cpp index 8574075b1e3ef..ef0791168d51c 100644 --- a/src/transparency_gui.cpp +++ b/src/transparency_gui.cpp @@ -126,7 +126,7 @@ class TransparenciesWindow : public Window } }; -static constexpr NWidgetPart _nested_transparency_widgets[] = { +static constexpr std::initializer_list _nested_transparency_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_TRANSPARENCY_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/tree_gui.cpp b/src/tree_gui.cpp index 8bf4d15af35fe..6bf2ee0281c0e 100644 --- a/src/tree_gui.cpp +++ b/src/tree_gui.cpp @@ -285,7 +285,7 @@ static std::unique_ptr MakeTreeTypeButtons() return vstack; } -static constexpr NWidgetPart _nested_build_trees_widgets[] = { +static constexpr std::initializer_list _nested_build_trees_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_PLANT_TREE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 251b905aa113b..a9a37ecd0e5ed 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -1307,7 +1307,7 @@ struct RefitWindow : public Window { } }; -static constexpr NWidgetPart _nested_vehicle_refit_widgets[] = { +static constexpr std::initializer_list _nested_vehicle_refit_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_VR_CAPTION), @@ -1595,7 +1595,7 @@ void ChangeVehicleViewWindow(VehicleID from_index, VehicleID to_index) ChangeVehicleWindow(WC_VEHICLE_TIMETABLE, from_index, to_index); } -static constexpr NWidgetPart _nested_vehicle_list[] = { +static constexpr std::initializer_list _nested_vehicle_list = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_VL_CAPTION_SELECTION), @@ -2324,7 +2324,7 @@ static_assert(WID_VD_DETAILS_CAPACITY_OF_EACH == WID_VD_DETAILS_CARGO_CARRIED + static_assert(WID_VD_DETAILS_TOTAL_CARGO == WID_VD_DETAILS_CARGO_CARRIED + TDW_TAB_TOTALS ); /** Vehicle details widgets (other than train). */ -static constexpr NWidgetPart _nested_nontrain_vehicle_details_widgets[] = { +static constexpr std::initializer_list _nested_nontrain_vehicle_details_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_VD_CAPTION), @@ -2347,7 +2347,7 @@ static constexpr NWidgetPart _nested_nontrain_vehicle_details_widgets[] = { }; /** Train details widgets. */ -static constexpr NWidgetPart _nested_train_vehicle_details_widgets[] = { +static constexpr std::initializer_list _nested_train_vehicle_details_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_VD_CAPTION), SetStringTip(STR_VEHICLE_DETAILS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), @@ -2820,7 +2820,7 @@ static void ShowVehicleDetailsWindow(const Vehicle *v) /* Unified vehicle GUI - Vehicle View Window */ /** Vehicle view widgets. */ -static constexpr NWidgetPart _nested_vehicle_view_widgets[] = { +static constexpr std::initializer_list _nested_vehicle_view_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_RENAME), SetAspect(WidgetDimensions::ASPECT_RENAME), SetSpriteTip(SPR_RENAME), diff --git a/src/viewport_gui.cpp b/src/viewport_gui.cpp index 0ea8b683da76c..1c6b8413b5b69 100644 --- a/src/viewport_gui.cpp +++ b/src/viewport_gui.cpp @@ -23,7 +23,7 @@ #include "safeguards.h" /* Extra Viewport Window Stuff */ -static constexpr NWidgetPart _nested_extra_viewport_widgets[] = { +static constexpr std::initializer_list _nested_extra_viewport_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_CAPTION, COLOUR_GREY, WID_EV_CAPTION), diff --git a/src/waypoint_gui.cpp b/src/waypoint_gui.cpp index d25020282f76f..6efd4cb29a14f 100644 --- a/src/waypoint_gui.cpp +++ b/src/waypoint_gui.cpp @@ -185,7 +185,7 @@ struct WaypointWindow : Window { }; /** The widgets of the waypoint view. */ -static constexpr NWidgetPart _nested_waypoint_view_widgets[] = { +static constexpr std::initializer_list _nested_waypoint_view_widgets = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_W_RENAME), SetAspect(WidgetDimensions::ASPECT_RENAME), SetSpriteTip(SPR_RENAME, STR_BUOY_VIEW_RENAME_TOOLTIP), From 00cdf1bc562c05d0582b3e864be1397c9cb6912d Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 25 Oct 2025 17:49:10 +0100 Subject: [PATCH 101/137] Codefix: Clear m6 more thoroughly when making tiles. m6 bits 6-7 were previously used to be for bridge above state, but should now be cleared. --- src/bridge_map.h | 1 + src/clear_map.h | 2 +- src/industry_map.h | 1 + src/object_map.h | 2 +- src/rail_map.h | 4 ++-- src/road_map.h | 6 +++--- src/station_map.h | 1 + src/tree_map.h | 2 +- src/tunnel_map.h | 4 ++-- src/water_map.h | 8 ++++---- 10 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/bridge_map.h b/src/bridge_map.h index 5ced7b5d2f27b..452e439329202 100644 --- a/src/bridge_map.h +++ b/src/bridge_map.h @@ -135,6 +135,7 @@ inline void MakeBridgeRamp(Tile t, Owner o, BridgeType bridgetype, DiagDirection t.m4() = 0; t.m5() = 1 << 7 | tt << 2 | d; SB(t.m6(), 2, 4, bridgetype); + SB(t.m6(), 6, 2, 0); t.m7() = 0; t.m8() = 0; } diff --git a/src/clear_map.h b/src/clear_map.h index a1a58612ce489..6f24800f99d21 100644 --- a/src/clear_map.h +++ b/src/clear_map.h @@ -274,7 +274,7 @@ inline void MakeField(Tile t, uint field_type, IndustryID industry) t.m3() = field_type; t.m4() = 0 << 5 | 0 << 2; SetClearGroundDensity(t, CLEAR_FIELDS, 3); - SB(t.m6(), 2, 4, 0); + SB(t.m6(), 2, 6, 0); t.m7() = 0; t.m8() = 0; } diff --git a/src/industry_map.h b/src/industry_map.h index 92957fa9f22ef..64ba712bf5a61 100644 --- a/src/industry_map.h +++ b/src/industry_map.h @@ -285,6 +285,7 @@ inline void MakeIndustry(Tile t, IndustryID index, IndustryGfx gfx, uint8_t rand SetIndustryGfx(t, gfx); // m5, part of m6 SetIndustryRandomTriggers(t, {}); // rest of m6 SetWaterClass(t, wc); + SB(t.m6(), 6, 2, 0); t.m7() = 0; } diff --git a/src/object_map.h b/src/object_map.h index a5280c4f8c7ec..23b623b6fc00b 100644 --- a/src/object_map.h +++ b/src/object_map.h @@ -80,7 +80,7 @@ inline void MakeObject(Tile t, Owner o, ObjectID index, WaterClass wc, uint8_t r t.m3() = random; t.m4() = 0; t.m5() = index.base() >> 16; - SB(t.m6(), 2, 4, 0); + SB(t.m6(), 2, 6, 0); t.m7() = 0; } diff --git a/src/rail_map.h b/src/rail_map.h index 5b06a2cb57756..4f1db937f4fc4 100644 --- a/src/rail_map.h +++ b/src/rail_map.h @@ -524,7 +524,7 @@ inline void MakeRailNormal(Tile t, Owner o, TrackBits b, RailType r) t.m3() = 0; t.m4() = 0; t.m5() = RAIL_TILE_NORMAL << 6 | b; - SB(t.m6(), 2, 4, 0); + SB(t.m6(), 2, 6, 0); t.m7() = 0; t.m8() = r; } @@ -557,7 +557,7 @@ inline void MakeRailDepot(Tile tile, Owner owner, DepotID depot_id, DiagDirectio tile.m3() = 0; tile.m4() = 0; tile.m5() = RAIL_TILE_DEPOT << 6 | dir; - SB(tile.m6(), 2, 4, 0); + SB(tile.m6(), 2, 6, 0); tile.m7() = 0; tile.m8() = rail_type; } diff --git a/src/road_map.h b/src/road_map.h index f8436d4258c7f..bc617197b27a3 100644 --- a/src/road_map.h +++ b/src/road_map.h @@ -619,7 +619,7 @@ inline void MakeRoadNormal(Tile t, RoadBits bits, RoadType road_rt, RoadType tra t.m2() = town.base(); t.m3() = (tram_rt != INVALID_ROADTYPE ? bits : 0); t.m5() = (road_rt != INVALID_ROADTYPE ? bits : 0) | ROAD_TILE_NORMAL << 6; - SB(t.m6(), 2, 4, 0); + SB(t.m6(), 2, 6, 0); t.m7() = 0; SetRoadTypes(t, road_rt, tram_rt); SetRoadOwner(t, RTT_TRAM, tram); @@ -645,7 +645,7 @@ inline void MakeRoadCrossing(Tile t, Owner road, Owner tram, Owner rail, Axis ro t.m3() = 0; t.m4() = INVALID_ROADTYPE; t.m5() = ROAD_TILE_CROSSING << 6 | roaddir; - SB(t.m6(), 2, 4, 0); + SB(t.m6(), 2, 6, 0); t.m7() = road.base(); t.m8() = INVALID_ROADTYPE << 6 | rat; SetRoadTypes(t, road_rt, tram_rt); @@ -679,7 +679,7 @@ inline void MakeRoadDepot(Tile tile, Owner owner, DepotID depot_id, DiagDirectio tile.m3() = 0; tile.m4() = INVALID_ROADTYPE; tile.m5() = ROAD_TILE_DEPOT << 6 | dir; - SB(tile.m6(), 2, 4, 0); + SB(tile.m6(), 2, 6, 0); tile.m7() = owner.base(); tile.m8() = INVALID_ROADTYPE << 6; SetRoadType(tile, GetRoadTramType(rt), rt); diff --git a/src/station_map.h b/src/station_map.h index fcb458dbec0c8..d90cc8dda590c 100644 --- a/src/station_map.h +++ b/src/station_map.h @@ -726,6 +726,7 @@ inline void MakeStation(Tile t, Owner o, StationID sid, StationType st, uint8_t t.m5() = section; SB(t.m6(), 2, 1, 0); SB(t.m6(), 3, 4, to_underlying(st)); + SB(t.m6(), 7, 1, 0); t.m7() = 0; t.m8() = 0; } diff --git a/src/tree_map.h b/src/tree_map.h index 9fa0969ed135c..cd031eac61873 100644 --- a/src/tree_map.h +++ b/src/tree_map.h @@ -250,7 +250,7 @@ inline void MakeTree(Tile t, TreeType type, uint count, TreeGrowthStage growth, t.m3() = type; t.m4() = 0 << 5 | 0 << 2; t.m5() = count << 6 | static_cast(growth); - SB(t.m6(), 2, 4, 0); + SB(t.m6(), 2, 6, 0); t.m7() = 0; } diff --git a/src/tunnel_map.h b/src/tunnel_map.h index 61965c067ca85..86f3027cbcdba 100644 --- a/src/tunnel_map.h +++ b/src/tunnel_map.h @@ -55,7 +55,7 @@ inline void MakeRoadTunnel(Tile t, Owner o, DiagDirection d, RoadType road_rt, R t.m3() = 0; t.m4() = 0; t.m5() = TRANSPORT_ROAD << 2 | d; - SB(t.m6(), 2, 4, 0); + SB(t.m6(), 2, 6, 0); t.m7() = 0; t.m8() = 0; SetRoadOwner(t, RTT_ROAD, o); @@ -78,7 +78,7 @@ inline void MakeRailTunnel(Tile t, Owner o, DiagDirection d, RailType r) t.m3() = 0; t.m4() = 0; t.m5() = TRANSPORT_RAIL << 2 | d; - SB(t.m6(), 2, 4, 0); + SB(t.m6(), 2, 6, 0); t.m7() = 0; t.m8() = 0; SetRailType(t, r); diff --git a/src/water_map.h b/src/water_map.h index 2c424d44b1df5..81e3e709146cb 100644 --- a/src/water_map.h +++ b/src/water_map.h @@ -391,7 +391,7 @@ inline void MakeShore(Tile t) t.m4() = 0; t.m5() = 0; SetWaterTileType(t, WATER_TILE_COAST); - SB(t.m6(), 2, 4, 0); + SB(t.m6(), 2, 6, 0); t.m7() = 0; } @@ -413,7 +413,7 @@ inline void MakeWater(Tile t, Owner o, WaterClass wc, uint8_t random_bits) t.m4() = random_bits; t.m5() = 0; SetWaterTileType(t, WATER_TILE_CLEAR); - SB(t.m6(), 2, 4, 0); + SB(t.m6(), 2, 6, 0); t.m7() = 0; } @@ -468,7 +468,7 @@ inline void MakeShipDepot(Tile t, Owner o, DepotID did, DepotPart part, Axis a, t.m4() = 0; t.m5() = part << WBL_DEPOT_PART | a << WBL_DEPOT_AXIS; SetWaterTileType(t, WATER_TILE_DEPOT); - SB(t.m6(), 2, 4, 0); + SB(t.m6(), 2, 6, 0); t.m7() = 0; } @@ -492,7 +492,7 @@ inline void MakeLockTile(Tile t, Owner o, LockPart part, DiagDirection dir, Wate t.m4() = 0; t.m5() = part << WBL_LOCK_PART_BEGIN | dir << WBL_LOCK_ORIENT_BEGIN; SetWaterTileType(t, WATER_TILE_LOCK); - SB(t.m6(), 2, 4, 0); + SB(t.m6(), 2, 6, 0); t.m7() = 0; } From 9001d4a8843ac979f400aea7587d6a64c11d2476 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 26 Oct 2025 17:53:49 +0000 Subject: [PATCH 102/137] Codefix: Clear m8 when making tiles. m8 should be cleared when tiles do not use it. --- src/industry_map.h | 1 + src/object_map.h | 1 + src/road_map.h | 1 + src/town_map.h | 1 + src/tree_map.h | 1 + src/void_map.h | 1 + src/water_map.h | 4 ++++ 7 files changed, 10 insertions(+) diff --git a/src/industry_map.h b/src/industry_map.h index 64ba712bf5a61..1c8acbadbc666 100644 --- a/src/industry_map.h +++ b/src/industry_map.h @@ -287,6 +287,7 @@ inline void MakeIndustry(Tile t, IndustryID index, IndustryGfx gfx, uint8_t rand SetWaterClass(t, wc); SB(t.m6(), 6, 2, 0); t.m7() = 0; + t.m8() = 0; } #endif /* INDUSTRY_MAP_H */ diff --git a/src/object_map.h b/src/object_map.h index 23b623b6fc00b..d997b673c0fe7 100644 --- a/src/object_map.h +++ b/src/object_map.h @@ -82,6 +82,7 @@ inline void MakeObject(Tile t, Owner o, ObjectID index, WaterClass wc, uint8_t r t.m5() = index.base() >> 16; SB(t.m6(), 2, 6, 0); t.m7() = 0; + t.m8() = 0; } #endif /* OBJECT_MAP_H */ diff --git a/src/road_map.h b/src/road_map.h index bc617197b27a3..aebed25816bc4 100644 --- a/src/road_map.h +++ b/src/road_map.h @@ -621,6 +621,7 @@ inline void MakeRoadNormal(Tile t, RoadBits bits, RoadType road_rt, RoadType tra t.m5() = (road_rt != INVALID_ROADTYPE ? bits : 0) | ROAD_TILE_NORMAL << 6; SB(t.m6(), 2, 6, 0); t.m7() = 0; + t.m8() = 0; SetRoadTypes(t, road_rt, tram_rt); SetRoadOwner(t, RTT_TRAM, tram); } diff --git a/src/town_map.h b/src/town_map.h index 1a982bcb82da5..442d33f37031f 100644 --- a/src/town_map.h +++ b/src/town_map.h @@ -386,6 +386,7 @@ inline void MakeHouseTile(Tile t, TownID tid, uint8_t counter, uint8_t stage, Ho SetHouseProtected(t, house_protected); SetAnimationFrame(t, 0); SetHouseProcessingTime(t, HouseSpec::Get(type)->processing_time); + SB(t.m8(), 12, 4, 0); } #endif /* TOWN_MAP_H */ diff --git a/src/tree_map.h b/src/tree_map.h index cd031eac61873..0cabe6a8eb9cb 100644 --- a/src/tree_map.h +++ b/src/tree_map.h @@ -252,6 +252,7 @@ inline void MakeTree(Tile t, TreeType type, uint count, TreeGrowthStage growth, t.m5() = count << 6 | static_cast(growth); SB(t.m6(), 2, 6, 0); t.m7() = 0; + t.m8() = 0; } #endif /* TREE_MAP_H */ diff --git a/src/void_map.h b/src/void_map.h index e8e031be79835..4a5976db3ba9c 100644 --- a/src/void_map.h +++ b/src/void_map.h @@ -27,6 +27,7 @@ inline void MakeVoid(Tile t) t.m5() = 0; t.m6() = 0; t.m7() = 0; + t.m8() = 0; } #endif /* VOID_MAP_H */ diff --git a/src/water_map.h b/src/water_map.h index 81e3e709146cb..7f8471c00d2f7 100644 --- a/src/water_map.h +++ b/src/water_map.h @@ -393,6 +393,7 @@ inline void MakeShore(Tile t) SetWaterTileType(t, WATER_TILE_COAST); SB(t.m6(), 2, 6, 0); t.m7() = 0; + t.m8() = 0; } /** @@ -415,6 +416,7 @@ inline void MakeWater(Tile t, Owner o, WaterClass wc, uint8_t random_bits) SetWaterTileType(t, WATER_TILE_CLEAR); SB(t.m6(), 2, 6, 0); t.m7() = 0; + t.m8() = 0; } /** @@ -470,6 +472,7 @@ inline void MakeShipDepot(Tile t, Owner o, DepotID did, DepotPart part, Axis a, SetWaterTileType(t, WATER_TILE_DEPOT); SB(t.m6(), 2, 6, 0); t.m7() = 0; + t.m8() = 0; } /** @@ -494,6 +497,7 @@ inline void MakeLockTile(Tile t, Owner o, LockPart part, DiagDirection dir, Wate SetWaterTileType(t, WATER_TILE_LOCK); SB(t.m6(), 2, 6, 0); t.m7() = 0; + t.m8() = 0; } /** From f759b691d7082c58ab719fcba3b8457e15a9383b Mon Sep 17 00:00:00 2001 From: Rito12 <111280526+Rito13@users.noreply.github.com> Date: Mon, 3 Nov 2025 13:25:32 +0100 Subject: [PATCH 103/137] Codechange: Use helper function for company recolour offset (#14740) --- src/company_base.h | 12 ++++++++++++ src/newgrf_industries.cpp | 4 +--- src/object_cmd.cpp | 6 ++---- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/company_base.h b/src/company_base.h index a1409c84edd81..c77f642389b5e 100644 --- a/src/company_base.h +++ b/src/company_base.h @@ -180,6 +180,18 @@ struct Company : CompanyProperties, CompanyPool::PoolItem<&_company_pool> { return !Company::Get(index)->is_ai; } + /** + * Get offset for recolour palette of specific company. + * @param livery_scheme Scheme to use for recolour. + * @param use_secondary Specify whether to add secondary colour offset to the result. + * @return palette offset. + */ + inline uint8_t GetCompanyRecolourOffset(LiveryScheme livery_scheme, bool use_secondary = true) const + { + const Livery &l = this->livery[livery_scheme]; + return use_secondary ? l.colour1 + l.colour2 * 16 : l.colour1; + } + static void PostDestructor(size_t index); }; diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp index 4f532ff1b2ab1..5a1fb6b80fc38 100644 --- a/src/newgrf_industries.cpp +++ b/src/newgrf_industries.cpp @@ -246,10 +246,8 @@ static uint32_t GetCountAndDistanceOfClosestInstance(const ResolverObject &objec const Company *c = Company::GetIfValid(this->industry->founder); if (c != nullptr) { - const Livery *l = &c->livery[LS_DEFAULT]; - is_ai = c->is_ai; - colours = l->colour1 + l->colour2 * 16; + colours = c->GetCompanyRecolourOffset(LS_DEFAULT); } return this->industry->founder.base() | (is_ai ? 0x10000 : 0) | (colours << 24); diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index 6cfed66e4746b..2bb29628f99cf 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -97,8 +97,7 @@ void BuildObject(ObjectType type, TileIndex tile, CompanyID owner, Town *town, u if (owner == OWNER_NONE) { o->colour = Random(); } else { - const Livery &l = Company::Get(owner)->livery[0]; - o->colour = l.colour1 + l.colour2 * 16; + o->colour = Company::Get(owner)->GetCompanyRecolourOffset(LS_DEFAULT); } /* If the object wants only one colour, then give it that colour. */ @@ -193,8 +192,7 @@ void UpdateObjectColours(const Company *c) /* Using the object colour callback, so not using company colour. */ if (spec->callback_mask.Test(ObjectCallbackMask::Colour)) continue; - const Livery &l = c->livery[0]; - obj->colour = (spec->flags.Test(ObjectFlag::Uses2CC) ? (l.colour2 * 16) : 0) + l.colour1; + obj->colour = c->GetCompanyRecolourOffset(LS_DEFAULT, spec->flags.Test(ObjectFlag::Uses2CC)); } } From 8226548e31a0c77e51f708c18a82672169aca1ca Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Mon, 3 Nov 2025 16:33:18 +0000 Subject: [PATCH 104/137] Fix fd32d1447e: Test for empty shares became inverted. (#14751) --- src/cargopacket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cargopacket.cpp b/src/cargopacket.cpp index f8c736c3a8fc1..8be991034ecdd 100644 --- a/src/cargopacket.cpp +++ b/src/cargopacket.cpp @@ -469,7 +469,7 @@ bool VehicleCargoList::Stage(bool accepted, StationID current_station, std::span FlowStat new_shares = flow_it->second; new_shares.ChangeShare(current_station, INT_MIN); for (auto station_it = next_station.rbegin(); station_it != next_station.rend(); ++station_it) { - if (!new_shares.GetShares()->empty()) break; + if (new_shares.GetShares()->empty()) break; new_shares.ChangeShare(*station_it, INT_MIN); } if (new_shares.GetShares()->empty()) { From 3befbdd52fa9273d25a0f677484be113478ea803 Mon Sep 17 00:00:00 2001 From: translators Date: Tue, 4 Nov 2025 04:38:48 +0000 Subject: [PATCH 105/137] Update: Translations from eints hungarian: 12 changes by vargaviktor --- src/lang/hungarian.txt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/lang/hungarian.txt b/src/lang/hungarian.txt index a7269ea7e51e8..b87127ba49594 100644 --- a/src/lang/hungarian.txt +++ b/src/lang/hungarian.txt @@ -317,6 +317,7 @@ STR_UNITS_FORCE_SI :{DECIMAL}{NBSP} STR_UNITS_HEIGHT_IMPERIAL :{DECIMAL}{NBSP}láb STR_UNITS_HEIGHT_METRIC :{DECIMAL}{NBSP}m STR_UNITS_HEIGHT_SI :{DECIMAL}{NBSP}m +STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}{NBSP}szint # Time units used in string control characters STR_UNITS_DAYS :{COMMA}{NBSP}nap @@ -1404,7 +1405,7 @@ STR_CONFIG_SETTING_SUBSIDY_DURATION_VALUE :{UNITS_YEARS_OR STR_CONFIG_SETTING_SUBSIDY_DURATION_DISABLED :Nincsenek támogatások STR_CONFIG_SETTING_CONSTRUCTION_COSTS :Építkezési költségek: {STRING} -STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :Építkezések és beszerzésk költségeinek szintje +STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :Építkezések és beszerzések költségeinek szintje ###length 3 STR_CONFIG_SETTING_CONSTRUCTION_COSTS_LOW :Alacsony STR_CONFIG_SETTING_CONSTRUCTION_COSTS_MEDIUM :Közepes @@ -2226,6 +2227,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :A magassági é STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Angolszász (láb) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metrikus (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :Játékbeli mértékegység (szint) STR_CONFIG_SETTING_LOCALISATION :Honosítás STR_CONFIG_SETTING_GRAPHICS :Megjelenés @@ -3535,6 +3537,8 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Tájkép STR_GENERATION_RIVER_GENERATION :{BLACK}Folyó generálás STR_GENERATION_CLEARING_TILES :{BLACK}Durva és köves területek generálása STR_GENERATION_TOWN_GENERATION :{BLACK}Város generálás +STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}Szárazföldi ipar generálás +STR_GENERATION_WATER_INDUSTRY_GENERATION :{BLACK}Vízi ipar generálás STR_GENERATION_OBJECT_GENERATION :{BLACK}Mozgathatatlan létesítmények létrehozása STR_GENERATION_TREE_GENERATION :{BLACK}Fák generálása STR_GENERATION_SETTINGUP_GAME :{BLACK}Játék beállítása @@ -5332,6 +5336,13 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}A kezdet STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... a híd mindkét végének szárazföldön kell lennie STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... a híd túl hosszú STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}A híd a térképen túl végződne +STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}A híd {HEIGHT} magas, túl alacsony az állomáshoz +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}A híd {HEIGHT} magas, túl alacsony a megállóhoz +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}A híd {HEIGHT} magas, túl alacsony a kikötőhöz +STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}A híd {HEIGHT} magas, túl alacsony a bójához +STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}A híd {HEIGHT} magas, túl alacsony a vasúti ellenőrzőponthoz +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}A híd {HEIGHT} magas, túl alacsony az útponthoz +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}A híd {HEIGHT} magas, túl alacsony a zároláshoz # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Nem áshatsz ide alagutat... From 06d8e039c6b01af51cdccbc7230973168796da63 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 4 Nov 2025 15:26:15 +0000 Subject: [PATCH 106/137] Codechange: Use std-find instead of for-loops in strgen. (#14754) --- src/strgen/strgen.h | 2 ++ src/strgen/strgen_base.cpp | 21 +++++++-------------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/strgen/strgen.h b/src/strgen/strgen.h index 8052107aa9725..f2e4b79014be0 100644 --- a/src/strgen/strgen.h +++ b/src/strgen/strgen.h @@ -137,6 +137,8 @@ struct CmdStruct; struct CmdPair { const CmdStruct *cmd; std::string param; + + auto operator<=>(const CmdPair &other) const = default; }; struct ParsedCommandStruct { diff --git a/src/strgen/strgen_base.cpp b/src/strgen/strgen_base.cpp index 6c733e2cd4845..8184ecf597ea8 100644 --- a/src/strgen/strgen_base.cpp +++ b/src/strgen/strgen_base.cpp @@ -313,9 +313,8 @@ void EmitGender(StringBuilder &builder, std::string_view param, char32_t) static const CmdStruct *FindCmd(std::string_view s) { - for (const auto &cs : _cmd_structs) { - if (cs.cmd == s) return &cs; - } + auto it = std::ranges::find(_cmd_structs, s, &CmdStruct::cmd); + if (it != std::end(_cmd_structs)) return &*it; return nullptr; } @@ -449,17 +448,11 @@ static bool CheckCommandsMatch(std::string_view a, std::string_view b, std::stri for (auto &templ_nc : templ.non_consuming_commands) { /* see if we find it in lang, and zero it out */ - bool found = false; - for (auto &lang_nc : lang.non_consuming_commands) { - if (templ_nc.cmd == lang_nc.cmd && templ_nc.param == lang_nc.param) { - /* it was found in both. zero it out from lang so we don't find it again */ - lang_nc.cmd = nullptr; - found = true; - break; - } - } - - if (!found) { + auto it = std::ranges::find(lang.non_consuming_commands, templ_nc); + if (it != std::end(lang.non_consuming_commands)) { + /* it was found in both. zero it out from lang so we don't find it again */ + it->cmd = nullptr; + } else { StrgenWarning("{}: command '{}' exists in template file but not in language file", name, templ_nc.cmd->cmd); result = false; } From 6d5f150b3ddfc4550a2b40d843941a65cb19af40 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Tue, 4 Nov 2025 19:23:18 +0000 Subject: [PATCH 107/137] Fix: BaseBitSet bit iteration for values which don't fit in 32 bits (#14757) --- src/core/base_bitset_type.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/base_bitset_type.hpp b/src/core/base_bitset_type.hpp index 9ce8528d3160a..3b50d4e033b9f 100644 --- a/src/core/base_bitset_type.hpp +++ b/src/core/base_bitset_type.hpp @@ -254,8 +254,8 @@ class BaseBitSet { return std::nullopt; } - auto begin() const { return SetBitIterator(this->data).begin(); } - auto end() const { return SetBitIterator(this->data).end(); } + auto begin() const { return SetBitIterator(this->data).begin(); } + auto end() const { return SetBitIterator(this->data).end(); } private: Tstorage data; ///< Bitmask of values. From 94052a6ccb32bbd8fa68095371d3c6f991d091d9 Mon Sep 17 00:00:00 2001 From: translators Date: Thu, 6 Nov 2025 04:41:15 +0000 Subject: [PATCH 108/137] Update: Translations from eints korean: 11 changes by telk5093 french: 14 changes by glx22 --- src/lang/french.txt | 17 ++++++++++++++--- src/lang/korean.txt | 11 +++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/lang/french.txt b/src/lang/french.txt index 235e21f98ed3f..d7912b71270bd 100644 --- a/src/lang/french.txt +++ b/src/lang/french.txt @@ -255,6 +255,7 @@ STR_UNITS_FORCE_SI :{DECIMAL}{NBSP} STR_UNITS_HEIGHT_IMPERIAL :{DECIMAL}{NBSP}ft STR_UNITS_HEIGHT_METRIC :{DECIMAL}{NBSP}m STR_UNITS_HEIGHT_SI :{DECIMAL}{NBSP}m +STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}{NBSP}niveau{P "" x} # Time units used in string control characters STR_UNITS_DAYS :{G=m}{COMMA}{NBSP}jour{P "" s} @@ -2092,7 +2093,7 @@ STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Taille moyenne STR_CONFIG_SETTING_LINKGRAPH_RECALC_INTERVAL :Mise à jour du graphe de distribution toutes les {STRING} STR_CONFIG_SETTING_LINKGRAPH_RECALC_INTERVAL_HELPTEXT :Intervalle entre les recalculs successifs du graphe de liaison. Chaque recalcul planifie un composant du graphe. Cela signifie qu'une valeur X pour ce paramètre ne signifie pas que l'ensemble du graphe sera mis à jour toutes les X secondes. Seul un composant le sera. Plus vous définissez cet intervalle court, plus le temps de processeur nécessaire pour le calcul sera important. Plus vous définissez cet intervalle long, plus il faudra de temps pour que la distribution de marchandises commence sur de nouveaux itinéraires -STR_CONFIG_SETTING_LINKGRAPH_RECALC_TIME :Recalcul du graphe de distribution toutes les {STRING} +STR_CONFIG_SETTING_LINKGRAPH_RECALC_TIME :Prend {STRING} pour le recalcul du graphe de distribution STR_CONFIG_SETTING_LINKGRAPH_RECALC_TIME_HELPTEXT :Temps pris pour chaque recalcul d'un composant du graphe de liaison. Lorsqu'un recalcul est lancé, un fil d'exécution est créé et autorisé à fonctionner pendant ce nombre de secondes. Plus vous définissez cette durée courte, plus il est probable que le fil ne soit pas terminé lorsqu'il est censé l'être. Ensuite, le jeu s'arrête jusqu'à ce qu'il le soit ("lag"). Plus vous définissez cette durée longue, plus il faut de temps pour que la distribution soit mise à jour lorsque les itinéraires changent STR_CONFIG_SETTING_DISTRIBUTION_PAX :Type de distribution pour les passagers{NBSP}: {STRING} @@ -2163,6 +2164,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Quand une haute STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Impérial (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Métrique (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :Unités de jeu (niveaux) STR_CONFIG_SETTING_LOCALISATION :Localisation STR_CONFIG_SETTING_GRAPHICS :Graphiques @@ -3472,6 +3474,8 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Généra STR_GENERATION_RIVER_GENERATION :{BLACK}Création des rivières STR_GENERATION_CLEARING_TILES :{BLACK}Création des zones rugueuses et rocheuses STR_GENERATION_TOWN_GENERATION :{BLACK}Génération des villes +STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}Génération des industries terrestres +STR_GENERATION_WATER_INDUSTRY_GENERATION :{BLACK}Génération des industries maritimes STR_GENERATION_OBJECT_GENERATION :{BLACK}Création des objets inamovibles STR_GENERATION_TREE_GENERATION :{BLACK}Création des arbres STR_GENERATION_SETTINGUP_GAME :{BLACK}Configuration du jeu @@ -4188,7 +4192,7 @@ STR_PURCHASE_INFO_ALL_BUT :Tous sauf {CARG STR_PURCHASE_INFO_MAX_TE :{BLACK}Effort de traction max.{NBSP}: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Rayon d'action{NBSP}: {GOLD}{COMMA}{NBSP}cases STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Type d'aéronef{NBSP}: {GOLD}{STRING} -STR_PURCHASE_INFO_RAILTYPES :{BLACK}Types de rail : {GOLD}{STRING} +STR_PURCHASE_INFO_RAILTYPES :{BLACK}Types de rail{NBSP}: {GOLD}{STRING} ###length 3 STR_CARGO_TYPE_FILTER_ALL :Tous les types de cargaison @@ -4372,7 +4376,7 @@ STR_ENGINE_PREVIEW_RUNCOST_YEAR :Coûts d'entret STR_ENGINE_PREVIEW_RUNCOST_PERIOD :Coûts d'entretien{NBSP}: {CURRENCY_LONG}/période STR_ENGINE_PREVIEW_CAPACITY :Capacité{NBSP}: {CARGO_LONG} STR_ENGINE_PREVIEW_CAPACITY_2 :Capacité{NBSP}: {CARGO_LONG}, {CARGO_LONG} -STR_ENGINE_PREVIEW_RAILTYPES :Types de rail : {STRING} +STR_ENGINE_PREVIEW_RAILTYPES :Types de rail{NBSP}: {STRING} # Autoreplace window STR_REPLACE_VEHICLES_WHITE :{WHITE}Remplacer {STRING} - {STRING} @@ -5269,6 +5273,13 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Le débu STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... les deux extrémités du pont doivent être sur la terre ferme STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... pont trop long STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Le pont finirait en dehors de la carte +STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Le pont est {HEIGHT} trop bas pour les gares +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Le pont est {HEIGHT} trop bas pour les arrêts de bus +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Le pont est {HEIGHT} trop bas pour le port +STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Le pont est {HEIGHT} trop bas pour les bouées +STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Le pont est {HEIGHT} trop bas pour les points de contrôle +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Le pont est {HEIGHT} trop bas pour les points de contrôle de route +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Le pont est {HEIGHT} trop bas pour l'écluse # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Impossible de construire un tunnel ici... diff --git a/src/lang/korean.txt b/src/lang/korean.txt index 6faf58f355974..691a84d6b4a4e 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -255,6 +255,7 @@ STR_UNITS_FORCE_SI :{DECIMAL}kN STR_UNITS_HEIGHT_IMPERIAL :{DECIMAL}피트 STR_UNITS_HEIGHT_METRIC :{DECIMAL}m STR_UNITS_HEIGHT_SI :{DECIMAL}m +STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}층 # Time units used in string control characters STR_UNITS_DAYS :{COMMA}일 @@ -2163,6 +2164,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :높이를 표 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :야드파운드법 (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :미터법 (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :국제표준규격 (m) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :게임 단위 (층) STR_CONFIG_SETTING_LOCALISATION :단위 설정 STR_CONFIG_SETTING_GRAPHICS :그래픽 @@ -3472,6 +3474,8 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}지형 STR_GENERATION_RIVER_GENERATION :{BLACK}강 제작 STR_GENERATION_CLEARING_TILES :{BLACK}거친 암석지대 만드는 중 STR_GENERATION_TOWN_GENERATION :{BLACK}도시 생성 +STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}지상 산업시설 생성 +STR_GENERATION_WATER_INDUSTRY_GENERATION :{BLACK}수상 산업시설 생성 STR_GENERATION_OBJECT_GENERATION :{BLACK}움직일수 없는 객체 만드는 중 STR_GENERATION_TREE_GENERATION :{BLACK}나무 심는 중 STR_GENERATION_SETTINGUP_GAME :{BLACK}게임 설정 중 @@ -5269,6 +5273,13 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}시작 STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... 다리의 양 끝은 모두 땅이어야 합니다 STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... 다리가 너무 깁니다! STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}다리 끝이 지도 밖을 넘어갑니다 +STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}다리 밑에 역을 두기에는 다리 높이가 {HEIGHT}만큼 낮습니다 +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}다리 밑에 도로 정류장을 두기에는 다리 높이가 {HEIGHT}만큼 낮습니다 +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}다리 밑에 항구를 두기에는 다리 높이가 {HEIGHT}만큼 낮습니다 +STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}다리 밑에 부표를 두기에는 다리 높이가 {HEIGHT}만큼 낮습니다 +STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}다리 밑에 철도 경유지를 두기에는 다리 높이가 {HEIGHT}만큼 낮습니다 +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}다리 밑에 도로 경유지를 두기에는 다리 높이가 {HEIGHT}만큼 낮습니다 +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}다리 밑에 항구를 두기에는 다리 높이가 {HEIGHT}만큼 낮습니다 # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}여기에 터널을 지을 수 없습니다... From f052ef213ea668db5b20cf4486353a6374ab34ae Mon Sep 17 00:00:00 2001 From: translators Date: Fri, 7 Nov 2025 04:39:02 +0000 Subject: [PATCH 109/137] Update: Translations from eints luxembourgish: 54 changes by phreeze83 --- src/lang/luxembourgish.txt | 60 ++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/src/lang/luxembourgish.txt b/src/lang/luxembourgish.txt index db4bb0e90d2bc..886a31a7176a7 100644 --- a/src/lang/luxembourgish.txt +++ b/src/lang/luxembourgish.txt @@ -621,7 +621,11 @@ STR_GRAPH_COMPANY_VALUES_CAPTION :{WHITE}Firmewä STR_GRAPH_LAST_24_MINUTES_TIME_LABEL :{TINY_FONT}{BLACK}Lescht 24 Minuten STR_GRAPH_LAST_72_MINUTES_TIME_LABEL :{TINY_FONT}{BLACK}Dauert 72 Minutten +STR_GRAPH_LAST_288_MINUTES_TIME_LABEL :{TINY_FONT}{BLACK}Lescht 288 Minuten +STR_GRAPH_LAST_24_MONTHS :{TINY_FONT}{BLACK}2 Joer (pro Mount) +STR_GRAPH_LAST_24_QUARTERS :{TINY_FONT}{BLACK}6 Joer (véirelsjähreg) +STR_GRAPH_LAST_24_YEARS :{TINY_FONT}{BLACK}24 Joer (jährleg) STR_GRAPH_CARGO_PAYMENT_RATES_CAPTION :{WHITE}Luedungs Bezuelraten @@ -635,8 +639,11 @@ STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL :{BLACK}Keng Wue STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO :{BLACK}Schalt d'Grafik fir de Wuerentyp em STR_GRAPH_CARGO_PAYMENT_CARGO :{TINY_FONT}{BLACK}{STRING} +STR_GRAPH_INDUSTRY_CAPTION :{WHITE}{INDUSTRY} - Wuerenhistorie STR_GRAPH_INDUSTRY_RANGE_PRODUCED :Produzéiert STR_GRAPH_INDUSTRY_RANGE_TRANSPORTED :Transportéiert +STR_GRAPH_INDUSTRY_RANGE_DELIVERED :Geliwwert +STR_GRAPH_INDUSTRY_RANGE_WAITING :Warden STR_GRAPH_PERFORMANCE_DETAIL_TOOLTIP :{BLACK}Weis detailléiert Leeschtungsastellungen @@ -967,11 +974,14 @@ STR_GAME_OPTIONS_TAB_SOUND :Sound STR_GAME_OPTIONS_TAB_SOUND_TOOLTIP :Wiel Sound- a Musikastellungen aus STR_GAME_OPTIONS_TAB_SOCIAL :Social STR_GAME_OPTIONS_TAB_SOCIAL_TOOLTIP :Wiel Astellungen déi mat Social Media ze dinn hunn +STR_GAME_OPTIONS_TAB_ADVANCED :Erweidert +STR_GAME_OPTIONS_TAB_ADVANCED_TOOLTIP :Erweidert Astellungen änneren STR_GAME_OPTIONS_VOLUME :Volume STR_GAME_OPTIONS_SFX_VOLUME :Soundeffekter STR_GAME_OPTIONS_MUSIC_VOLUME :Musik +STR_GAME_OPTIONS_SETTING :{STRING}: {ORANGE}{STRING} STR_GAME_OPTIONS_VOLUME_MARK :{NUM}% @@ -1026,6 +1036,7 @@ STR_GAME_OPTIONS_CURRENCY_MYR :Malaysesche Rin STR_GAME_OPTIONS_CURRENCY_LVL :Lettesch Lat STR_GAME_OPTIONS_CURRENCY_PTE :Portugieseschen Escudo STR_GAME_OPTIONS_CURRENCY_UAH :Ukrainesch Hryvnia +STR_GAME_OPTIONS_CURRENCY_VND :Vietnamesesch Dong STR_GAME_OPTIONS_AUTOSAVE_FRAME :Autospäicheren STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :Wiel den Intervall aus fir d'Autospäicherung @@ -1059,6 +1070,7 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :Wiel des Optiou STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :Aktuellen Driver: {STRING} +STR_GAME_OPTIONS_INTERFACE :Interface STR_GAME_OPTIONS_GUI_SCALE_FRAME :Interfacegréisst STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :De Slider zéien fir d'Gréisst vum Interface ze änneren. Ctrl+Zéien fir eng kontinuéierlech Ännerung @@ -1083,6 +1095,7 @@ STR_GAME_OPTIONS_PARTICIPATE_SURVEY_LINK_TOOLTIP :Dëst start e B STR_GAME_OPTIONS_PARTICIPATE_SURVEY_PREVIEW :Preview op d'Emfroresultat STR_GAME_OPTIONS_PARTICIPATE_SURVEY_PREVIEW_TOOLTIP :Weis d'Resultat vun der Emfro vum aktuelle Spill un +STR_GAME_OPTIONS_DISPLAY :Display STR_GAME_OPTIONS_REFRESH_RATE :Bildfrequenz STR_GAME_OPTIONS_REFRESH_RATE_TOOLTIP :Wiel d'Frequenz vum Bildschirm aus @@ -1298,6 +1311,9 @@ STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Zënssaz; kontr STR_CONFIG_SETTING_RUNNING_COSTS :Betribskäschten: {STRING} STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Fixéier den Niveau vun de Betribskäschten vu Gefierer an Infrastruktur ###length 3 +STR_CONFIG_SETTING_RUNNING_COSTS_LOW :Niddreg +STR_CONFIG_SETTING_RUNNING_COSTS_MEDIUM :Mëttel +STR_CONFIG_SETTING_RUNNING_COSTS_HIGH :Héich STR_CONFIG_SETTING_CONSTRUCTION_SPEED :Baugeschwindegkeet: {STRING} STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :Limitéier d'Unzuel u Bauaktiounen fir d'KI @@ -1665,6 +1681,8 @@ STR_CONFIG_SETTING_SCROLLMODE_LMB :Kaart mat der l STR_CONFIG_SETTING_SMOOTH_SCROLLING :Glaate Scrolling: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Kontrolléiert wéi d'Haptusiicht op eng bestëmmten Positioun scrollt, wann een op déi kléng Kaart klickt oder en Befehl fir ob en spezifescht Objet ze scrollen gëtt. Wann ugeschalt, gëtt bis dohin gescrollt, wann ausgeschalt, spréngt d'Vue op den Zielobjet +STR_CONFIG_SETTING_TOOLBAR_DROPDOWN_AUTOSELECT :Traditionellt Toolbarmenuselektiounsverhalen: {STRING} +STR_CONFIG_SETTING_TOOLBAR_DROPDOWN_AUTOSELECT_HELPTEXT :Wiel aus wéi d'Selektioun an den Toolbarmenus sech verhält. Wann ausgeschalt, bleiwen d'Menuer opgeklappt bis eng Selektioun gemet gouf. Wann ugeschalt, aktivéiren sech d'Menuer wann d'Maustast lassgelooss gëtt. STR_CONFIG_SETTING_MEASURE_TOOLTIP :Weis en Mooss-Tooltip wann verschidde Bau-Tools benotzt ginn: {STRING} STR_CONFIG_SETTING_MEASURE_TOOLTIP_HELPTEXT :Weis Felderdistanzen an Héichtenënnerscheed beim Zéien während dem Bauen un @@ -2063,7 +2081,7 @@ STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Ufangs-Gréisst STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Duerchschnëttsgréisst vu Stied an Proportioun zu normalen Dierfer um Spillstart STR_CONFIG_SETTING_LINKGRAPH_RECALC_INTERVAL :Update de Verdeelergraph all {STRING} -STR_CONFIG_SETTING_LINKGRAPH_RECALC_INTERVAL_HELPTEXT :Zäit tëschend zwou Neiberechnungen vun der Linkgrafik. All Neiberechnung berechent eng Komponent vun der Grafik. Dëst bedeit dass e Wäert X net heescht dass de ganze Graph all X Sekonne geupdate gëtt. Nëmmen eng Komponent gëtt berechent. Wat de Wäert méi kuerz gesat gëtt, wat méi CPU Leeschtung gebraucht gëtt fir alles ze berechnen. Je gréisser de Wäert gesat gëtt desto méi laang brauch et bis d'Wuereverdeelung op neie Route gestart gëtt +STR_CONFIG_SETTING_LINKGRAPH_RECALC_INTERVAL_HELPTEXT :Zäit tëschend zwou Neiberechnungen vun der Linkgrafik. All Neiberechnung berechent eng Komponent vun der Grafik. Dëst bedeit dass e Wäert X net heescht dass déi ganze Grafik all X Sekonne geupdate gëtt. Nëmmen eng Komponent gëtt berechent. Wat de Wäert méi kuerz gesat gëtt, wat méi CPU Leeschtung gebraucht gëtt fir alles ze berechnen. Je gréisser de Wäert gesat gëtt desto méi laang brauch et bis d'Wuereverdeelung op neie Route gestart gëtt STR_CONFIG_SETTING_LINKGRAPH_RECALC_TIME :Benotz {STRING} fir d'Neiberechnung vum Verdeelergraph STR_CONFIG_SETTING_LINKGRAPH_RECALC_TIME_HELPTEXT :Zäit déi gebrauch gëtt fir all Neiberechnung vun enger Komponent vun der Linkgrafik. Wann eng Neiberechnung gestart gëtt, gëtt e Prozess erstallt den fir des Unzuel u Sekonne lafen dierf. Wat d'Zäit méi kuerz gesat gëtt, wat d'Chance méi grouss ass dass d'Berechnung net fäerdeg gëtt. Dann stopt d'Spill bis d'Berechnung fäerdeg ass ("laggt"). Je länger d'Zäit gesat gëtt desto länger brauch et bis d'Verdeelung geupdate gëtt wann eng Route ännert @@ -2193,6 +2211,8 @@ STR_VIDEO_DRIVER_ERROR_NO_HARDWARE_ACCELERATION :{WHITE}... keng STR_VIDEO_DRIVER_ERROR_HARDWARE_ACCELERATION_CRASH :{WHITE}... GPU driver huet d'Spill gecrasht. Hardwarebeschleunegung ausgeschalt # Intro window +STR_INTRO_CAPTION :{WHITE}OpenTTD +STR_INTRO_VERSION :OpenTTD {REV} STR_INTRO_NEW_GAME :{BLACK}Neit Spill STR_INTRO_LOAD_GAME :{BLACK}Spill lueden @@ -2326,16 +2346,19 @@ STR_FACE_SIMPLE_TOOLTIP :{BLACK}Einfach STR_FACE_LOAD :{BLACK}Lueden STR_FACE_LOAD_TOOLTIP :{BLACK}Favoriséiert Gesiicht lueden STR_FACE_LOAD_DONE :{WHITE}Äert favoriséiert Gesiicht ass aus der OpenTTD Konfiguratiounsdatei geluede ginn. -STR_FACE_FACECODE :{BLACK}Gesiicht N°. -STR_FACE_FACECODE_TOOLTIP :{BLACK}Kuckt an wielt d'Gesiichtsnummer vum Firmepresident -STR_FACE_FACECODE_CAPTION :{WHITE}Kuckt an wielt d'Gesiichtsnummer -STR_FACE_FACECODE_SET :{WHITE}Nei Gesiichtsnummer ass agestallt ginn -STR_FACE_FACECODE_ERR :{WHITE}Konnt d'Gesiichtsnummer net setzen - muss en numereschen Wäert tëscht 0 an 4,294,967,295 sinn! +STR_FACE_FACECODE :{BLACK}Gesiichtscode +STR_FACE_FACECODE_TOOLTIP :{BLACK}Kuckt a wielt de Gesiichtscode vum Firmepresident +STR_FACE_FACECODE_CAPTION :{WHITE}Kuckt a wielt de Gesiichtscode +STR_FACE_FACECODE_SET :{WHITE}Neit Presidentegesiicht ass agestallt ginn +STR_FACE_FACECODE_ERR :{WHITE}Konnt de Gesiichtscode net astellen - muss e gültege Label an Nummer sinn STR_FACE_SAVE :{BLACK}Späicheren STR_FACE_SAVE_TOOLTIP :{BLACK}Späichert favoriséiert Gesiicht STR_FACE_SAVE_DONE :{WHITE}Dëst Gesiicht gëtt als favoriséiert an der OpenTTD Konfiguratiounsdatei gespäichert. +STR_FACE_SETTING_TOGGLE :{STRING} {ORANGE}{STRING} +STR_FACE_SETTING_NUMERIC :{STRING} {ORANGE}{NUM} / {NUM} STR_FACE_YES :Jo STR_FACE_NO :Nee +STR_FACE_STYLE :Stil: STR_FACE_HAIR :Hoer: STR_FACE_EYEBROWS :Aperhoer: STR_FACE_EYECOLOUR :Aafaarf: @@ -2808,6 +2831,10 @@ STR_PICKER_MODE_USED_TOOLTIP :Wiesselen tësc STR_PICKER_MODE_SAVED :Gespäichert STR_PICKER_MODE_SAVED_TOOLTIP :Wiesselen tëschent gespäicherten Objeten +STR_PICKER_PREVIEW_SHRINK :- +STR_PICKER_PREVIEW_SHRINK_TOOLTIP :D'Héicht vun Virschaubiller erofsetzen. Ctrl+Klick fir op de Minimum ze setzen +STR_PICKER_PREVIEW_EXPAND :+ +STR_PICKER_PREVIEW_EXPAND_TOOLTIP :D'Héicht vun Virschaubiller eropsetzen. Ctrl+Klick fir op de Maximum ze setzen. STR_PICKER_STATION_CLASS_TOOLTIP :Wiel eng Statiounsklass fir unzeweisen STR_PICKER_STATION_TYPE_TOOLTIP :Wiel en Typ vu Statioun fir ze bauen. Ctrl+Klick fir en bei d'gespäichert Objeten dobäizesetzen oder ewechzehuelen @@ -3307,6 +3334,8 @@ STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: STR_SAVELOAD_FILTER_TITLE :{BLACK}Filter: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Datei iwwerschreiwen STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Bass du sécher, dass du d'existéirend Datei iwwerschreiwe wëlls? +STR_SAVELOAD_DELETE_TITLE :{WHITE}Datei läschen +STR_SAVELOAD_DELETE_WARNING :{YELLOW}}Bass du sécher, dass du des Datei läsche wëlls? STR_SAVELOAD_DIRECTORY :{STRING} (Verzeechnis) STR_SAVELOAD_PARENT_DIRECTORY :{STRING} (Een dossier zréck) @@ -3672,6 +3701,10 @@ STR_TOWN_VIEW_RENAME_TOOLTIP :{BLACK}Wiesselt STR_TOWN_VIEW_EXPAND_BUTTON :{BLACK}Erweideren STR_TOWN_VIEW_EXPAND_TOOLTIP :{BLACK}Stad méi grouss maachen +STR_TOWN_VIEW_EXPAND_BUILDINGS_BUTTON :{BLACK}Gebaier erweideren +STR_TOWN_VIEW_EXPAND_BUILDINGS_TOOLTIP :{BLACK}Gebaier vun der Stad vergréisseren +STR_TOWN_VIEW_EXPAND_ROADS_BUTTON :{BLACK}Stroossen erweideren +STR_TOWN_VIEW_EXPAND_ROADS_TOOLTIP :{BLACK}Stroosse vun der Stad erweideren STR_TOWN_VIEW_DELETE_BUTTON :{BLACK}Läschen STR_TOWN_VIEW_DELETE_TOOLTIP :{BLACK}Des Stad ganz läschen @@ -3997,6 +4030,8 @@ STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE :{BLACK}Produkti STR_INDUSTRY_VIEW_PRODUCTION_LAST_MINUTE_TITLE :{BLACK}Produktioun déi läscht Minutt: STR_INDUSTRY_VIEW_TRANSPORTED :{YELLOW}{CARGO_LONG}{STRING}{BLACK} ({COMMA}% transportéiert) STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Zentréiert d'Siicht op d'Industrie. Ctrl+Klick erstellt eng nei Usiicht op d'Industrie +STR_INDUSTRY_VIEW_CARGO_GRAPH :{BLACK}Wueregrafik +STR_INDUSTRY_VIEW_CARGO_GRAPH_TOOLTIP :{BLACK}Weist d'Grafik vun der Industriewuerenhistorie un STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Produktiounslevel: {YELLOW}{COMMA}% STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}D'Industrie annoncéiert dass se zougemaach gëtt @@ -4317,6 +4352,7 @@ STR_ENGINE_PREVIEW_RUNCOST_YEAR :Betribskäschte STR_ENGINE_PREVIEW_RUNCOST_PERIOD :Betribskäschten: {CURRENCY_LONG}/Period STR_ENGINE_PREVIEW_CAPACITY :Kapazitéit: {CARGO_LONG} STR_ENGINE_PREVIEW_CAPACITY_2 :Kapazitéit: {CARGO_LONG}, {CARGO_LONG} +STR_ENGINE_PREVIEW_RAILTYPES :Schinnentypen: {STRING} # Autoreplace window STR_REPLACE_VEHICLES_WHITE :{WHITE}Ersetz {STRING} - {STRING} @@ -5211,6 +5247,7 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Start an STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... dei zwee Enner vun der Bréck mussen u Land sinn STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... Bréck ze laang STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Bréck géif ausserhalb der Kaart ukommen +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Bréck ass {HEIGHT} ze niddreg fir e Stroossestop # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Kann den Tunnel hei net bauen... @@ -5827,6 +5864,8 @@ STR_SAVEGAME_NAME_SPECTATOR :Zuschauer, {1:S # Viewport strings STR_VIEWPORT_TOWN_POP :{TOWN} ({COMMA}) +STR_VIEWPORT_TOWN_CITY :{TOWN} {CITY_ICON} +STR_VIEWPORT_TOWN_CITY_POP :{TOWN} ({COMMA}) {CITY_ICON} STR_VIEWPORT_STATION :{STATION} {STATION_FEATURES} # Simple strings to get specific types of data @@ -5850,6 +5889,7 @@ STR_CURRENCY_SHORT_GIGA :{NBSP}mia STR_CURRENCY_SHORT_TERA :{NBSP}bn STR_JUST_CARGO :{CARGO_LONG} +STR_JUST_LEFT_ARROW :{LEFT_ARROW} STR_JUST_RIGHT_ARROW :{RIGHT_ARROW} STR_JUST_CHECKMARK :{CHECKMARK} STR_JUST_COMMA :{COMMA} @@ -5889,3 +5929,11 @@ STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) STR_BADGE_NAME_LIST :{STRING}: {GOLD}{STRING} +STR_BADGE_CONFIG_MENU_TOOLTIP :Badgekonfiguratioun opman +STR_BADGE_CONFIG_RESET :Reset +STR_BADGE_CONFIG_ICONS :{WHITE}Badgeikoner +STR_BADGE_CONFIG_FILTERS :{WHITE}Badgefilter +STR_BADGE_CONFIG_PREVIEW :Bildvirschau +STR_BADGE_CONFIG_NAME :Numm +STR_BADGE_FILTER_ANY_LABEL :Iergendeen {STRING} +STR_BADGE_FILTER_IS_LABEL :{STRING} ass {STRING} From d48463d2be1b63b970cfe03b85d0f4effdd205ad Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 9 Nov 2025 08:21:55 +0000 Subject: [PATCH 110/137] Fix #14763: Crash if NewGRF currency separator is not valid. (#14764) Ensure separator is a valid string. --- src/newgrf/newgrf_act0_globalvar.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/newgrf/newgrf_act0_globalvar.cpp b/src/newgrf/newgrf_act0_globalvar.cpp index b71fccfb9bdc2..18aa6d67a9f09 100644 --- a/src/newgrf/newgrf_act0_globalvar.cpp +++ b/src/newgrf/newgrf_act0_globalvar.cpp @@ -178,6 +178,7 @@ static ChangeInfoResult GlobalVarChangeInfo(uint first, uint last, int prop, Byt if (curidx < CURRENCY_END) { _currency_specs[curidx].separator.clear(); _currency_specs[curidx].separator.push_back(GB(options, 0, 8)); + StrMakeValidInPlace(_currency_specs[curidx].separator); /* By specifying only one bit, we prevent errors, * since newgrf specs said that only 0 and 1 can be set for symbol_pos */ _currency_specs[curidx].symbol_pos = GB(options, 8, 1); From 9c338cf2122f2de688e6ec8c98c4c0db4a0325d3 Mon Sep 17 00:00:00 2001 From: Rito12 <111280526+Rito13@users.noreply.github.com> Date: Sun, 9 Nov 2025 17:29:44 +0100 Subject: [PATCH 111/137] Codefix 8f14894: Correct the comment for GetClassBadge function. (#14759) --- src/newgrf_badge.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/newgrf_badge.cpp b/src/newgrf_badge.cpp index 59a9a4a1caec6..ba9e803ac09ec 100644 --- a/src/newgrf_badge.cpp +++ b/src/newgrf_badge.cpp @@ -130,9 +130,9 @@ Badge *GetBadgeByLabel(std::string_view label) } /** - * Get the badge class of a badge label. - * @param label Label to get class of. - * @returns Badge class index of label. + * Get the badge for a badge class index. + * @param class_index Index of the badge class. + * @return Class badge for the class index, or nullptr if not present. */ Badge *GetClassBadge(BadgeClassID class_index) { From b563c34ca4689750428287360f9e1b24e59cb72a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Guilloux?= Date: Sun, 9 Nov 2025 22:31:59 +0100 Subject: [PATCH 112/137] Codefix 6d495d1: [Actions] vcpkg caching for codeql requires some permissions (#14767) --- .github/workflows/codeql.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 0aaaea5e00dce..904ad6feed63f 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -21,6 +21,7 @@ jobs: actions: read contents: read security-events: write + packages: read steps: - name: Checkout From 376a39f67ac7d9f44b217d7eb8f4d7966c39aa3e Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 9 Nov 2025 22:40:08 +0000 Subject: [PATCH 113/137] Change: Use proper tooltip strings for freeform edge toggles. (#14765) --- src/genworld_gui.cpp | 8 ++++---- src/lang/english.txt | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index b98c34c6089a2..602ae8d406b9e 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -172,14 +172,14 @@ static constexpr std::initializer_list _nested_generate_landscape_w NWidget(NWID_VERTICAL), NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_NORTHWEST), SetPadding(0, WidgetDimensions::unscaled.hsep_normal, 0, 0), SetFill(1, 1), SetAlignment(SA_RIGHT | SA_VERT_CENTER), - NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_NW), SetToolTip(STR_MAPGEN_NORTHWEST), SetFill(1, 1), - NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_NE), SetToolTip(STR_MAPGEN_NORTHEAST), SetFill(1, 1), + NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_NW), SetToolTip(STR_MAPGEN_NORTHWEST_TOOLTIP), SetFill(1, 1), + NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_NE), SetToolTip(STR_MAPGEN_NORTHEAST_TOOLTIP), SetFill(1, 1), NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_NORTHEAST), SetPadding(0, 0, 0, WidgetDimensions::unscaled.hsep_normal), SetFill(1, 1), EndContainer(), NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize), NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_SOUTHWEST), SetPadding(0, WidgetDimensions::unscaled.hsep_normal, 0, 0), SetFill(1, 1), SetAlignment(SA_RIGHT | SA_VERT_CENTER), - NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_SW), SetToolTip(STR_MAPGEN_SOUTHWEST), SetFill(1, 1), - NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_SE), SetToolTip(STR_MAPGEN_SOUTHEAST), SetFill(1, 1), + NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_SW), SetToolTip(STR_MAPGEN_SOUTHWEST_TOOLTIP), SetFill(1, 1), + NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_SE), SetToolTip(STR_MAPGEN_SOUTHEAST_TOOLTIP), SetFill(1, 1), NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_SOUTHEAST), SetPadding(0, 0, 0, WidgetDimensions::unscaled.hsep_normal), SetFill(1, 1), EndContainer(), EndContainer(), diff --git a/src/lang/english.txt b/src/lang/english.txt index 566fc9ad012e0..dd2f426621a33 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -3427,6 +3427,10 @@ STR_MAPGEN_NORTHWEST :{BLACK}Northwes STR_MAPGEN_NORTHEAST :{BLACK}Northeast STR_MAPGEN_SOUTHEAST :{BLACK}Southeast STR_MAPGEN_SOUTHWEST :{BLACK}Southwest +STR_MAPGEN_NORTHWEST_TOOLTIP :Toggle water or freeform edge on the northwest map edge +STR_MAPGEN_NORTHEAST_TOOLTIP :Toggle water or freeform edge on the northeast map edge +STR_MAPGEN_SOUTHEAST_TOOLTIP :Toggle water or freeform edge on the southeast map edge +STR_MAPGEN_SOUTHWEST_TOOLTIP :Toggle water or freeform edge on the southwest map edge STR_MAPGEN_BORDER_FREEFORM :{BLACK}Freeform STR_MAPGEN_BORDER_WATER :{BLACK}Water STR_MAPGEN_BORDER_RANDOM :{BLACK}Random From 744543e46919c9e006c2b7d19918055ca08d4261 Mon Sep 17 00:00:00 2001 From: translators Date: Mon, 10 Nov 2025 04:41:07 +0000 Subject: [PATCH 114/137] Update: Translations from eints luxembourgish: 54 changes by phreeze83 --- src/lang/luxembourgish.txt | 77 ++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 23 deletions(-) diff --git a/src/lang/luxembourgish.txt b/src/lang/luxembourgish.txt index 886a31a7176a7..81a43c962d74c 100644 --- a/src/lang/luxembourgish.txt +++ b/src/lang/luxembourgish.txt @@ -254,6 +254,7 @@ STR_UNITS_FORCE_SI :{DECIMAL}{NBSP} STR_UNITS_HEIGHT_IMPERIAL :{DECIMAL}{NBSP}ft STR_UNITS_HEIGHT_METRIC :{DECIMAL}{NBSP}m STR_UNITS_HEIGHT_SI :{DECIMAL}{NBSP}m +STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}{NBSP}Niveau{P "" en} # Time units used in string control characters STR_UNITS_DAYS :{COMMA}{NBSP}D{P ag eeg} @@ -267,6 +268,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}Joer STR_UNITS_PERIODS :{NUM}{NBSP}Period{P "" en} STR_LIST_SEPARATOR :,{SPACE} +STR_TRUNCATION_ELLIPSIS :... # Common window strings STR_LIST_FILTER_TITLE :{BLACK}Filter: @@ -285,7 +287,7 @@ STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Fënster STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Fënstertitel - hei zéien fir d'Fënster ze bewegen STR_TOOLTIP_SHADE :{BLACK}Fenster verklengeren - Weis nëmmen Titelbar STR_TOOLTIP_DEBUG :{BLACK}Weis NewGRF Debug Informatioun -STR_TOOLTIP_DEFSIZE :{BLACK}Änner d'Fënster op d'Standardgréisst. Ctrl+Klick fir déi aktuell Gréisst als Standard ze späichern +STR_TOOLTIP_DEFSIZE :{BLACK}Änner d'Fënster op d'Standardgréisst. Ctrl+Klick fir déi aktuell Gréisst als Standard ze späichern. Dubel Ctrl+Klick fir op de Standard ze resetten STR_TOOLTIP_STICKY :{BLACK}Markéier dës Fënster fir net zougemeet ze ginn vun dem "All Fënsteren zoumaachen" Knäppchen. Ctrl+Klick späichert déi Actioun als Standard STR_TOOLTIP_RESIZE :{BLACK}Klicken an zéihen fir d'Fënstergréisst ze änneren STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Wiesselt grouss/kleng Fënstergréisst @@ -627,6 +629,8 @@ STR_GRAPH_LAST_24_MONTHS :{TINY_FONT}{BLA STR_GRAPH_LAST_24_QUARTERS :{TINY_FONT}{BLACK}6 Joer (véirelsjähreg) STR_GRAPH_LAST_24_YEARS :{TINY_FONT}{BLACK}24 Joer (jährleg) +STR_GRAPH_TOGGLE_RANGE :Grafik emschalte fir des Data Range +STR_GRAPH_SELECT_SCALE :Horizontal Skala vun der Grafik änneren STR_GRAPH_CARGO_PAYMENT_RATES_CAPTION :{WHITE}Luedungs Bezuelraten STR_GRAPH_CARGO_PAYMENT_RATES_DAYS :{TINY_FONT}{BLACK}Deeg am Transit @@ -634,8 +638,8 @@ STR_GRAPH_CARGO_PAYMENT_RATES_SECONDS :{TINY_FONT}{BLA STR_GRAPH_CARGO_PAYMENT_RATES_TITLE :{TINY_FONT}{BLACK}Bezuelung fir Liwwerung vun 10 Eenheeten (oder 10.000 liter) Luedungen op Distanz vun 20 Felder STR_GRAPH_CARGO_ENABLE_ALL :{TINY_FONT}{BLACK}All STR_GRAPH_CARGO_DISABLE_ALL :{TINY_FONT}{BLACK}Keng -STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL :{BLACK}All Wueren op der Wuerewäertgrafik uweisen -STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL :{BLACK}Keng Wuer op der Wuerewäertgrafik uweisen +STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL :{BLACK}All Wueren op der Grafik uweisen +STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL :{BLACK}Keng Wuer op der Grafik uweisen STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO :{BLACK}Schalt d'Grafik fir de Wuerentyp em STR_GRAPH_CARGO_PAYMENT_CARGO :{TINY_FONT}{BLACK}{STRING} @@ -645,6 +649,9 @@ STR_GRAPH_INDUSTRY_RANGE_TRANSPORTED :Transportéiert STR_GRAPH_INDUSTRY_RANGE_DELIVERED :Geliwwert STR_GRAPH_INDUSTRY_RANGE_WAITING :Warden +STR_GRAPH_TOWN_CARGO_CAPTION :{WHITE}{TOWN} - Wuerenhistorie +STR_GRAPH_TOWN_RANGE_PRODUCED :Angebot +STR_GRAPH_TOWN_RANGE_TRANSPORTED :Transportéiert STR_GRAPH_PERFORMANCE_DETAIL_TOOLTIP :{BLACK}Weis detailléiert Leeschtungsastellungen @@ -1117,7 +1124,7 @@ STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP :Méi Informatio STR_GAME_OPTIONS_ONLINE_CONTENT :Inhalt eroflueden STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP :Sich no neiem an geupdateten Inhalt fir erofzelueden -STR_GAME_OPTIONS_SOCIAL_PLUGINS_NONE :{LTBLUE}(keng Plugins déi mat Social Platforms kommunizéiren installéiert) +STR_GAME_OPTIONS_SOCIAL_PLUGINS_NONE :(keng Plugins déi mat Sozial-Platforme kommunizéiren installéiert) STR_GAME_OPTIONS_SOCIAL_PLUGIN_TITLE :{STRING} ({STRING}) STR_GAME_OPTIONS_SOCIAL_PLUGIN_PLATFORM :Plattform: @@ -1336,6 +1343,9 @@ STR_CONFIG_SETTING_SUBSIDY_DURATION_DISABLED :Keng Subsiden STR_CONFIG_SETTING_CONSTRUCTION_COSTS :Konstruktiounskäschten: {STRING} STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :Bestëmm den Niveau vu Bau- a Kafkäschten ###length 3 +STR_CONFIG_SETTING_CONSTRUCTION_COSTS_LOW :Niddreg +STR_CONFIG_SETTING_CONSTRUCTION_COSTS_MEDIUM :Mëttel +STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HIGH :Héich STR_CONFIG_SETTING_RECESSIONS :Rezessiounen: {STRING} STR_CONFIG_SETTING_RECESSIONS_HELPTEXT :Wann ugeschalt kann vun Zäit zur Zäit eng Rezessioun kommen. Während enger Rezessioun ass d'Produktioun däitlech méi niddreg (an klëmmt erëm op den alen Niveau no der Rezessioun) @@ -2044,9 +2054,9 @@ STR_CONFIG_SETTING_SOFT_LIMIT_VALUE :{COMMA} ###setting-zero-is-special STR_CONFIG_SETTING_SOFT_LIMIT_DISABLED :Ausgeschalt -STR_CONFIG_SETTING_ZOOM_MIN :Maximale Razoom Level: {STRING} +STR_CONFIG_SETTING_ZOOM_MIN :Maximale Razoomniveau: {STRING} STR_CONFIG_SETTING_ZOOM_MIN_HELPTEXT :Maximal Razoomstuf fir Usiichtsfënsteren. Et gëtt méi Späicher gebraucht wann d'Stufen ze grouss ginn -STR_CONFIG_SETTING_ZOOM_MAX :Maximalen Rauszoom Level: {STRING} +STR_CONFIG_SETTING_ZOOM_MAX :Maximale Rauszoomniveau: {STRING} STR_CONFIG_SETTING_ZOOM_MAX_HELPTEXT :Maximal Rauszoom-Stuf fir Usiichtsfënsteren. Méi grouss Rauszoom-Stufen kënnen Ruckeler verursaachen ###length 6 STR_CONFIG_SETTING_ZOOM_LVL_MIN :4x @@ -2094,9 +2104,9 @@ STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :D'GEPANZERT Wue STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Verdeelungsmodus fir aner Wuereklassen: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asymmetresch" heescht dass eng beléiweg Unzuel un Wueren an béid Richtungen verschéckt ginn. "Manuell" heescht dass keng automatësch Verdeelung stattfënnt ###length 3 -STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manuell -STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asymmetresch -STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :symmetresch +STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :Manuell +STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :Asymmetresch +STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :Symmetresch STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Verdeelungsgenauegkeet: {STRING} STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Wat de Wäert méi héich ass, wat méi CPU benotzt gëtt fir d'Linkgrafik ze zeechnen. Wann ze héich gesat, kann et zu Lags kommen. Ze niddreg gesat kann d'Verdeelung ongenau ginn an d'Wueren net sou verdeelt ginn wéi geduet @@ -2153,6 +2163,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Emmer wann Héi STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Britesch (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Metresch (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :Spilleenheeten (Niveau) STR_CONFIG_SETTING_LOCALISATION :Lokaliséirung STR_CONFIG_SETTING_GRAPHICS :Grafik @@ -3075,6 +3086,11 @@ STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP :{BLACK}Wiel d'S STR_FOUND_TOWN_CITY :{BLACK}Stad STR_FOUND_TOWN_CITY_TOOLTIP :{BLACK}Stied wuessen méi schnell wéi Dierfer{}Ofhängeg vun den Astellungen, sinn se méi grouss am Ufank +STR_FOUND_TOWN_EXPAND_MODE :{YELLOW}Stadvergéisserung: +STR_FOUND_TOWN_EXPAND_BUILDINGS :Gebaier +STR_FOUND_TOWN_EXPAND_BUILDINGS_TOOLTIP :Unzuel Gebaier vun der Stad erhéigen +STR_FOUND_TOWN_EXPAND_ROADS :Stroossen +STR_FOUND_TOWN_EXPAND_ROADS_TOOLTIP :Méi Stroossen an der Stad bauen STR_FOUND_TOWN_ROAD_LAYOUT :{YELLOW}Stroosselayout vun der Stad: STR_FOUND_TOWN_SELECT_LAYOUT_TOOLTIP :{BLACK}Stroosselayout fir des Stad wielen @@ -3416,8 +3432,9 @@ STR_MAPGEN_BORDER_WATER :{BLACK}Waasser STR_MAPGEN_BORDER_RANDOM :{BLACK}Zoufälleg ###length 3 -STR_MAPGEN_BORDER_RANDOMIZE :{BLACK}Zoufall -STR_MAPGEN_BORDER_MANUAL :{BLACK}Manuell +STR_MAPGEN_BORDER_RANDOMIZE :Zoufall +STR_MAPGEN_BORDER_MANUAL :Manuell +STR_MAPGEN_BORDER_INFINITE_WATER :Endlos Waasser STR_MAPGEN_HEIGHTMAP_ROTATION :{BLACK}Héichtekaart-Rotatioun: STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Héichtekaart-Numm: @@ -3456,6 +3473,8 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Landscha STR_GENERATION_RIVER_GENERATION :{BLACK}Generéiren vu Flëss STR_GENERATION_CLEARING_TILES :{BLACK}Generatioun vu knubbelegem a stengege Land STR_GENERATION_TOWN_GENERATION :{BLACK}Stiedgeneratioun +STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}Landindustriegeneratioun +STR_GENERATION_WATER_INDUSTRY_GENERATION :{BLACK}Waasserindustriegeneratioun STR_GENERATION_OBJECT_GENERATION :{BLACK}Objets-Generatioun STR_GENERATION_TREE_GENERATION :{BLACK}Baam Generatioun STR_GENERATION_SETTINGUP_GAME :{BLACK}Spill gëtt opgestallt @@ -3675,6 +3694,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Gëff en STR_TOWN_DIRECTORY_CAPTION :{WHITE}Stied ({COMMA} vu {COMMA}) STR_TOWN_DIRECTORY_NONE :{ORANGE}- Keng - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{BLACK} ({COMMA}) {YELLOW}{CITY_ICON} STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Stiednimm - klick op den Numm fir d'Usiicht drop ze zentréieren. Ctrl+Klick erstellt eng nei Usiicht vun der Stad STR_TOWN_POPULATION :{BLACK}Weltbevölkerung: {COMMA} @@ -3698,6 +3718,8 @@ STR_TOWN_VIEW_CENTER_TOOLTIP :{BLACK}Zentréi STR_TOWN_VIEW_LOCAL_AUTHORITY_BUTTON :{BLACK}Gemeng STR_TOWN_VIEW_LOCAL_AUTHORITY_TOOLTIP :{BLACK}Weist d'Informatiounen zu der Gemeng STR_TOWN_VIEW_RENAME_TOOLTIP :{BLACK}Wiesselt de Stadnumm +STR_TOWN_VIEW_CARGO_GRAPH :Wueregrafik +STR_TOWN_VIEW_CARGO_GRAPH_TOOLTIP :Grafik vun der Stad hierer Wuerenhistorie uweisen STR_TOWN_VIEW_EXPAND_BUTTON :{BLACK}Erweideren STR_TOWN_VIEW_EXPAND_TOOLTIP :{BLACK}Stad méi grouss maachen @@ -4032,7 +4054,7 @@ STR_INDUSTRY_VIEW_TRANSPORTED :{YELLOW}{CARGO_ STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Zentréiert d'Siicht op d'Industrie. Ctrl+Klick erstellt eng nei Usiicht op d'Industrie STR_INDUSTRY_VIEW_CARGO_GRAPH :{BLACK}Wueregrafik STR_INDUSTRY_VIEW_CARGO_GRAPH_TOOLTIP :{BLACK}Weist d'Grafik vun der Industriewuerenhistorie un -STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Produktiounslevel: {YELLOW}{COMMA}% +STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Produktiounsniveau: {YELLOW}{COMMA}% STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}D'Industrie annoncéiert dass se zougemaach gëtt STR_INDUSTRY_VIEW_REQUIRES_N_CARGO :{BLACK}Brauch: {YELLOW}{STRING}{STRING} @@ -4046,7 +4068,7 @@ STR_INDUSTRY_VIEW_ACCEPT_CARGO_NOSUFFIX :{YELLOW}{0:STRI STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT_NOSUFFIX :{YELLOW}{0:STRING}{BLACK}: {1:CARGO_SHORT} warden STR_CONFIG_GAME_PRODUCTION :{WHITE}D'Produktioun änneren (Multipel vun 8, bis op 2040) -STR_CONFIG_GAME_PRODUCTION_LEVEL :{WHITE}Änner de Produktiounslevel (Prozenter, bis zu 800%) +STR_CONFIG_GAME_PRODUCTION_LEVEL :{WHITE}Änner de Produktiounsniveau (Prozenter, bis zu 800%) # Vehicle lists ###length VEHICLE_TYPES @@ -4169,6 +4191,7 @@ STR_PURCHASE_INFO_ALL_BUT :Alles ausser {C STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. Zéikraaft: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Distanz: {GOLD}{COMMA} Felder STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Fliger Typ: {GOLD}{STRING} +STR_PURCHASE_INFO_RAILTYPES :{BLACK}Schinnentypen: {GOLD}{STRING} ###length 3 STR_CARGO_TYPE_FILTER_ALL :All Wuerentyp @@ -4444,10 +4467,10 @@ STR_VEHICLE_VIEW_SHIP_ORDERS_TOOLTIP :{BLACK}Weist d' STR_VEHICLE_VIEW_AIRCRAFT_ORDERS_TOOLTIP :{BLACK}Weist d'Opträg vum Fliger. Ctrl+Klick weist den Zäitplang ###length VEHICLE_TYPES -STR_VEHICLE_VIEW_TRAIN_SHOW_DETAILS_TOOLTIP :{BLACK}Weist d'Detailer vum Zuch -STR_VEHICLE_VIEW_ROAD_VEHICLE_SHOW_DETAILS_TOOLTIP :{BLACK}Weist Stroossegefier Detailer -STR_VEHICLE_VIEW_SHIP_SHOW_DETAILS_TOOLTIP :{BLACK}Weis Schëffsdetailer -STR_VEHICLE_VIEW_AIRCRAFT_SHOW_DETAILS_TOOLTIP :{BLACK}Weist d'Fligerdetailer +STR_VEHICLE_VIEW_TRAIN_SHOW_DETAILS_TOOLTIP :{BLACK}Weist d'Detailer vum Zuch. Ctrl+Klick fir d'Zuchgrupp unzeweisen +STR_VEHICLE_VIEW_ROAD_VEHICLE_SHOW_DETAILS_TOOLTIP :{BLACK}Weist Gefier Detailer. Ctrl+Klick fir d'Gefierergrupp unzeweisen +STR_VEHICLE_VIEW_SHIP_SHOW_DETAILS_TOOLTIP :{BLACK}Weis Schëffsdetailer un. Ctrl+Klick fir d'Schëffsgrupp unzeweisen +STR_VEHICLE_VIEW_AIRCRAFT_SHOW_DETAILS_TOOLTIP :{BLACK}Weist d'Fligerdetailer un. Ctrl+Klick fir d'Fligergrupp unzeweisen ###length VEHICLE_TYPES STR_VEHICLE_VIEW_TRAIN_STATUS_START_STOP_TOOLTIP :{BLACK}Aktuell Zuchs-Aktioun - klick fir den Zuch ze stoppen/starten @@ -4771,14 +4794,15 @@ STR_TIMETABLE_TOOLTIP :{BLACK}Zäitpla STR_TIMETABLE_NO_TRAVEL :Net ënnerwee STR_TIMETABLE_NOT_TIMETABLEABLE :Rees (automatesch; Zäitplang durch manuell Opträg) STR_TIMETABLE_TRAVEL_NOT_TIMETABLED :Ënnerwee (ouni Zäitplang) +STR_TIMETABLE_TRAVEL_NOT_TIMETABLED_SPEED :Fuer maximal {VELOCITY} (ouni Zäitplang) STR_TIMETABLE_TRAVEL_FOR :Ënnerwee während {STRING} STR_TIMETABLE_TRAVEL_FOR_SPEED :Fiert während {STRING} mat maximal {VELOCITY} STR_TIMETABLE_TRAVEL_FOR_ESTIMATED :Fuer (während {STRING}, ouni Zäitplang) STR_TIMETABLE_TRAVEL_FOR_SPEED_ESTIMATED :Fuer (während {STRING}, ouni Zäitplang) mat maximal {VELOCITY} STR_TIMETABLE_STAY_FOR_ESTIMATED :{SPACE}(waard {STRING}, ouni Zäitplang) STR_TIMETABLE_AND_TRAVEL_FOR_ESTIMATED :{SPACE}(fuer während {STRING}, ouni Zäitplang) -STR_TIMETABLE_STAY_FOR :an bleif fir {STRING} -STR_TIMETABLE_AND_TRAVEL_FOR :an ënnerwee während {STRING} +STR_TIMETABLE_STAY_FOR :{SPACE} a bleif fir {STRING} +STR_TIMETABLE_AND_TRAVEL_FOR :{SPACE}an ënnerwee während {STRING} STR_TIMETABLE_APPROX_TIME :{BLACK}Dësen Zäitplang brauch ongeféier {STRING} fir fäerdeg ze ginn STR_TIMETABLE_TOTAL_TIME :{BLACK}Dësen Zäitplang brauch {STRING} fir fäerdeg ze ginn @@ -5007,6 +5031,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}D'Land m STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Land ass an déi falsch Richtung geneigt STR_ERROR_CAN_T_DO_THIS :{WHITE}Kann dat net maachen... STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Gebai muss fir d'éischt ofgerapt ginn +STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... Gebai ass geschützt STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Kann des Plaz net raumen... STR_ERROR_SITE_UNSUITABLE :{WHITE}... Plaz net gëeegent STR_ERROR_ALREADY_BUILT :{WHITE}... scho gebaut @@ -5094,7 +5119,7 @@ STR_ERROR_CAN_T_BUILD_BUS_STATION :{WHITE}Kann de STR_ERROR_CAN_T_BUILD_TRUCK_STATION :{WHITE}Kann d'Camionsgare net bauen... STR_ERROR_CAN_T_BUILD_PASSENGER_TRAM_STATION :{WHITE}Kann d'Passagéier-Tramsarrêt net bauen... STR_ERROR_CAN_T_BUILD_CARGO_TRAM_STATION :{WHITE}Kann d'Wueren-Tramstatioun net bauen... -STR_ERROR_CAN_T_BUILD_DOCK_HERE :{WHITE}Kann den Dock hei net bauen... +STR_ERROR_CAN_T_BUILD_DOCK_HERE :{WHITE}Kann de Quai hei net bauen... STR_ERROR_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Kann de Fluchhafen hei net bauen... STR_ERROR_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Grenzt un méi wéi eng Gare un @@ -5105,7 +5130,7 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Ze vill STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Ze vill Garesdeeler STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Ze vill Busarrêten STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Ze vill Camionsgaren -STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Ze no un engem aaneren Hafen +STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Ze no un engem aanere Quai STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Ze no un engem aanere Fluchhafen STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Kann d'Statioun net ëmbenennen... STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... d'Strooss ass am Besëtz vun der Stad @@ -5128,7 +5153,7 @@ STR_ERROR_MUST_DEMOLISH_BUS_STATION_FIRST :{WHITE}Busarrê STR_ERROR_MUST_DEMOLISH_TRUCK_STATION_FIRST :{WHITE}Muss d'Camionsgare fir d'éischt ofrappen STR_ERROR_MUST_DEMOLISH_PASSENGER_TRAM_STATION_FIRST :{WHITE}Muss d'Tramstatioun fir d'éischt ofrappen STR_ERROR_MUST_DEMOLISH_CARGO_TRAM_STATION_FIRST :{WHITE}Muss d'Tramstatioun fir d'éischt ofrappen -STR_ERROR_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Muss den Hafen fir déischt ofrappen +STR_ERROR_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Muss de Quai fir déischt ofrappen STR_ERROR_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Muss de Fluchhafe fir d'éischt ofrappen # Waypoint related errors @@ -5247,7 +5272,13 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Start an STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... dei zwee Enner vun der Bréck mussen u Land sinn STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... Bréck ze laang STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Bréck géif ausserhalb der Kaart ukommen +STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Bréck ass {HEIGHT} ze niddreg fir d'Gare STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}Bréck ass {HEIGHT} ze niddreg fir e Stroossestop +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}Bréck ass {HEIGHT} ze niddreg fir de Quai +STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}Bréck as {HEIGHT} ze niddreg fir d'Boje +STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}Bréck ass {HEIGHT} ze niddreg fir den Zuchweepunkt +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}Bréck ass {HEIGHT} ze niddreg fir de Stroosseweepunkt +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}Bréck ass {HEIGHT} ze niddreg fir d'Schleis # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Kann den Tunnel hei net bauen... @@ -5396,7 +5427,7 @@ STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... Flig STR_ERROR_NO_RAIL_STATION :{WHITE}Et gëtt keng Zuchgare/statioun STR_ERROR_NO_BUS_STATION :{WHITE}Et gëtt keen Busarrêt STR_ERROR_NO_TRUCK_STATION :{WHITE}Et gëtt keng Camionsgare -STR_ERROR_NO_DOCK :{WHITE}Et gëtt keen Dock +STR_ERROR_NO_DOCK :{WHITE}Et gëtt kee Quai STR_ERROR_NO_AIRPORT :{WHITE}Et gëtt keen Fluchhafen/Helikopterlandeplaz STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE :{WHITE}Et gëtt keen Arret mat engem kompatible Stroossentyp STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE :{WHITE}Et gëtt keen Arret mat engem kompatible Tramtyp From aa6c694c67839b0867b5336c0a18661db3dd67e3 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Mon, 10 Nov 2025 21:41:02 +0000 Subject: [PATCH 115/137] Fix c2d4098afa: Unconfigured badge classes should be visible in column 0 by default. (#14766) --- src/newgrf_badge_config.h | 4 ++-- src/newgrf_badge_gui.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/newgrf_badge_config.h b/src/newgrf_badge_config.h index 1da4fa75b3483..3a4069022c9ad 100644 --- a/src/newgrf_badge_config.h +++ b/src/newgrf_badge_config.h @@ -16,8 +16,8 @@ class BadgeClassConfigItem { public: std::string label; ///< Class label. - int column = -1; ///< UI column, feature-dependent. - bool show_icon = false; ///< Set if the badge icons should be displayed for this class. + uint column = 0; ///< UI column, feature-dependent. + bool show_icon = true; ///< Set if the badge icons should be displayed for this class. bool show_filter = false; ///< Set if a drop down filter should be added for this class. }; diff --git a/src/newgrf_badge_gui.cpp b/src/newgrf_badge_gui.cpp index 0a1290fedb2ee..68f9311a5cf76 100644 --- a/src/newgrf_badge_gui.cpp +++ b/src/newgrf_badge_gui.cpp @@ -81,7 +81,7 @@ GUIBadgeClasses::GUIBadgeClasses(GrfSpecFeature feature) : UsedBadgeClasses(feat const auto [config, sort_order] = GetBadgeClassConfigItem(feature, class_badge->label); this->gui_classes.emplace_back(class_index, config.column, config.show_icon, sort_order, size, class_badge->label); - if (size.width != 0 && config.show_icon) max_column = std::max(max_column, config.column); + if (size.width != 0 && config.show_icon) max_column = std::max(max_column, config.column); } std::sort(std::begin(this->gui_classes), std::end(this->gui_classes)); @@ -436,7 +436,7 @@ static void BadgeClassMoveNext(GrfSpecFeature feature, Badge &class_badge, uint auto pos_cur = std::ranges::find(gui_classes.GetClasses(), class_badge.class_index, &GUIBadgeClasses::Element::class_index); if (std::next(pos_cur) == std::end(gui_classes.GetClasses())) { - if (it->column < static_cast(columns - 1)) ++it->column; + if (it->column < columns - 1) ++it->column; return; } From ca866cc0836fcac70093b66e95bc9d9efd68b023 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Mon, 10 Nov 2025 21:43:35 +0000 Subject: [PATCH 116/137] Fix 394adb654e: Incorrect spacing for badges in dropdown lists. (#14768) --- src/newgrf_badge_gui.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/newgrf_badge_gui.cpp b/src/newgrf_badge_gui.cpp index 68f9311a5cf76..ff0a1d48c9fe9 100644 --- a/src/newgrf_badge_gui.cpp +++ b/src/newgrf_badge_gui.cpp @@ -193,9 +193,12 @@ class DropDownBadges : public TBase { { for (const auto &gc : gui_classes->GetClasses()) { if (gc.column_group != 0) continue; - dim.width += gc.size.width + WidgetDimensions::scaled.hsep_normal; - dim.height = std::max(dim.height, gc.size.height); + dim.width += ScaleGUITrad(gc.size.width) + WidgetDimensions::scaled.hsep_normal; + dim.height = std::max(dim.height, ScaleGUITrad(gc.size.height)); } + + /* Remove trailing `hsep_normal` spacer. */ + if (dim.width > 0) dim.width -= WidgetDimensions::scaled.hsep_normal; } uint Height() const override @@ -206,7 +209,7 @@ class DropDownBadges : public TBase { uint Width() const override { if (this->dim.width == 0) return this->TBase::Width(); - return this->dim.width + WidgetDimensions::scaled.hsep_wide + this->TBase::Width(); + return this->dim.width + WidgetDimensions::scaled.hsep_normal + this->TBase::Width(); } int OnClick(const Rect &r, const Point &pt) const override @@ -215,7 +218,7 @@ class DropDownBadges : public TBase { return this->TBase::OnClick(r, pt); } else { bool rtl = TEnd ^ (_current_text_dir == TD_RTL); - return this->TBase::OnClick(r.Indent(this->dim.width + WidgetDimensions::scaled.hsep_wide, rtl), pt); + return this->TBase::OnClick(r.Indent(this->dim.width + WidgetDimensions::scaled.hsep_normal, rtl), pt); } } @@ -226,7 +229,7 @@ class DropDownBadges : public TBase { } else { bool rtl = TEnd ^ (_current_text_dir == TD_RTL); DrawBadgeColumn(r.WithWidth(this->dim.width, rtl), 0, *this->gui_classes, this->badges, this->feature, this->introduction_date, PAL_NONE); - this->TBase::Draw(full, r.Indent(this->dim.width + WidgetDimensions::scaled.hsep_wide, rtl), sel, click_result, bg_colour); + this->TBase::Draw(full, r.Indent(this->dim.width + WidgetDimensions::scaled.hsep_normal, rtl), sel, click_result, bg_colour); } } From ae413728c1598c7c6f77ff2a7192236fb9bd7ef8 Mon Sep 17 00:00:00 2001 From: translators Date: Tue, 11 Nov 2025 04:40:42 +0000 Subject: [PATCH 117/137] Update: Translations from eints english (au): 4 changes by krysclarke english (us): 4 changes by 2TallTyler greek: 4 changes by gh658804 hungarian: 4 changes by vargaviktor russian: 4 changes by Ln-Wolf finnish: 4 changes by hpiirai portuguese: 4 changes by jcteotonio portuguese (brazilian): 4 changes by pasantoro --- src/lang/brazilian_portuguese.txt | 4 ++++ src/lang/english_AU.txt | 4 ++++ src/lang/english_US.txt | 4 ++++ src/lang/finnish.txt | 4 ++++ src/lang/greek.txt | 4 ++++ src/lang/hungarian.txt | 4 ++++ src/lang/portuguese.txt | 4 ++++ src/lang/russian.txt | 4 ++++ 8 files changed, 32 insertions(+) diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index 42ecbac923035..a187eae9394e5 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -3428,6 +3428,10 @@ STR_MAPGEN_NORTHWEST :{BLACK}Noroeste STR_MAPGEN_NORTHEAST :{BLACK}Nordeste STR_MAPGEN_SOUTHEAST :{BLACK}Sudeste STR_MAPGEN_SOUTHWEST :{BLACK}Sudoeste +STR_MAPGEN_NORTHWEST_TOOLTIP :Alternar entre água ou borda livre na borda noroeste do mapa +STR_MAPGEN_NORTHEAST_TOOLTIP :Alternar entre água ou borda livre na borda nordeste do mapa +STR_MAPGEN_SOUTHEAST_TOOLTIP :Alternar entre água ou borda livre na borda sudeste do mapa +STR_MAPGEN_SOUTHWEST_TOOLTIP :Alternar entre água ou borda livre na borda sudoeste do mapa STR_MAPGEN_BORDER_FREEFORM :{BLACK}Forma livre STR_MAPGEN_BORDER_WATER :{BLACK}Água STR_MAPGEN_BORDER_RANDOM :{BLACK}Aleatório diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt index 92dc23506aa14..55c66782b15f4 100644 --- a/src/lang/english_AU.txt +++ b/src/lang/english_AU.txt @@ -3427,6 +3427,10 @@ STR_MAPGEN_NORTHWEST :{BLACK}Northwes STR_MAPGEN_NORTHEAST :{BLACK}Northeast STR_MAPGEN_SOUTHEAST :{BLACK}Southeast STR_MAPGEN_SOUTHWEST :{BLACK}Southwest +STR_MAPGEN_NORTHWEST_TOOLTIP :Toggle water or freeform edge on the northwest map edge +STR_MAPGEN_NORTHEAST_TOOLTIP :Toggle water or freeform edge on the northeast map edge +STR_MAPGEN_SOUTHEAST_TOOLTIP :Toggle water or freeform edge on the southeast map edge +STR_MAPGEN_SOUTHWEST_TOOLTIP :Toggle water or freeform edge on the southwest map edge STR_MAPGEN_BORDER_FREEFORM :{BLACK}Freeform STR_MAPGEN_BORDER_WATER :{BLACK}Water STR_MAPGEN_BORDER_RANDOM :{BLACK}Random diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index 1a529a17b0048..63796fbe526ef 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -3427,6 +3427,10 @@ STR_MAPGEN_NORTHWEST :{BLACK}Northwes STR_MAPGEN_NORTHEAST :{BLACK}Northeast STR_MAPGEN_SOUTHEAST :{BLACK}Southeast STR_MAPGEN_SOUTHWEST :{BLACK}Southwest +STR_MAPGEN_NORTHWEST_TOOLTIP :Toggle water or freeform edge on the northwest map edge +STR_MAPGEN_NORTHEAST_TOOLTIP :Toggle water or freeform edge on the northeast map edge +STR_MAPGEN_SOUTHEAST_TOOLTIP :Toggle water or freeform edge on the southeast map edge +STR_MAPGEN_SOUTHWEST_TOOLTIP :Toggle water or freeform edge on the southwest map edge STR_MAPGEN_BORDER_FREEFORM :{BLACK}Freeform STR_MAPGEN_BORDER_WATER :{BLACK}Water STR_MAPGEN_BORDER_RANDOM :{BLACK}Random diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index f7b6d68b0d0c7..80a1c2f87b7fe 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -3427,6 +3427,10 @@ STR_MAPGEN_NORTHWEST :{BLACK}Luode STR_MAPGEN_NORTHEAST :{BLACK}Koillinen STR_MAPGEN_SOUTHEAST :{BLACK}Kaakko STR_MAPGEN_SOUTHWEST :{BLACK}Lounas +STR_MAPGEN_NORTHWEST_TOOLTIP :Valitse, onko kartan luoteislaita vettä vai vapaamuotoista reunaa +STR_MAPGEN_NORTHEAST_TOOLTIP :Valitse, onko kartan koillislaita vettä vai vapaamuotoista reunaa +STR_MAPGEN_SOUTHEAST_TOOLTIP :Valitse, onko kartan kaakkoislaita vettä vai vapaamuotoista reunaa +STR_MAPGEN_SOUTHWEST_TOOLTIP :Valitse, onko kartan lounaislaita vettä vai vapaamuotoista reunaa STR_MAPGEN_BORDER_FREEFORM :{BLACK}Vapaa STR_MAPGEN_BORDER_WATER :{BLACK}Vesi STR_MAPGEN_BORDER_RANDOM :{BLACK}Sattumanvarainen diff --git a/src/lang/greek.txt b/src/lang/greek.txt index 051a97e806e9b..ca49e0fa51a44 100644 --- a/src/lang/greek.txt +++ b/src/lang/greek.txt @@ -3520,6 +3520,10 @@ STR_MAPGEN_NORTHWEST :{BLACK}Βορε STR_MAPGEN_NORTHEAST :{BLACK}Βορειοανατολικά STR_MAPGEN_SOUTHEAST :{BLACK}Νοτιοανατολικά STR_MAPGEN_SOUTHWEST :{BLACK}Νοτιοδυτικά +STR_MAPGEN_NORTHWEST_TOOLTIP :Εναλλαγή νερού ή ελεύθερης μορφής άκρης στο βορειοδυτικό άκρο του χάρτη +STR_MAPGEN_NORTHEAST_TOOLTIP :Εναλλαγή νερού ή ελεύθερης μορφής άκρης στο βορειοανατολικό άκρο του χάρτη +STR_MAPGEN_SOUTHEAST_TOOLTIP :Εναλλαγή νερού ή ελεύθερης μορφής άκρης στο νοτιοανατολικό άκρο του χάρτη +STR_MAPGEN_SOUTHWEST_TOOLTIP :Εναλλαγή νερού ή ελεύθερης μορφής άκρης στο νοτιοδυτικό άκρο του χάρτη STR_MAPGEN_BORDER_FREEFORM :{BLACK}Ελεύθερη μορφή STR_MAPGEN_BORDER_WATER :{BLACK}Νερό STR_MAPGEN_BORDER_RANDOM :{BLACK}Τυχαία diff --git a/src/lang/hungarian.txt b/src/lang/hungarian.txt index b87127ba49594..0898e35329e24 100644 --- a/src/lang/hungarian.txt +++ b/src/lang/hungarian.txt @@ -3491,6 +3491,10 @@ STR_MAPGEN_NORTHWEST :{BLACK}Északny STR_MAPGEN_NORTHEAST :{BLACK}Északkelet STR_MAPGEN_SOUTHEAST :{BLACK}Délkelet STR_MAPGEN_SOUTHWEST :{BLACK}Délnyugat +STR_MAPGEN_NORTHWEST_TOOLTIP :Víz vagy szabad formájú térképszél bekapcsolása a térkép északnyugati szélén +STR_MAPGEN_NORTHEAST_TOOLTIP :Víz vagy szabad formájú térképszél bekapcsolása a térkép északkeleti szélén +STR_MAPGEN_SOUTHEAST_TOOLTIP :Víz vagy szabad formájú térképszél bekapcsolása a térkép délkeleti szélén +STR_MAPGEN_SOUTHWEST_TOOLTIP :Víz vagy szabad formájú térképszél bekapcsolása a térkép délnyugati szélén STR_MAPGEN_BORDER_FREEFORM :{BLACK}Szárazföld STR_MAPGEN_BORDER_WATER :{BLACK}Víz STR_MAPGEN_BORDER_RANDOM :{BLACK}Véletlen diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index d5b20f7f15eeb..8c7ffb13bae69 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -3428,6 +3428,10 @@ STR_MAPGEN_NORTHWEST :{BLACK}Noroeste STR_MAPGEN_NORTHEAST :{BLACK}Nordeste STR_MAPGEN_SOUTHEAST :{BLACK}Sudeste STR_MAPGEN_SOUTHWEST :{BLACK}Sudoeste +STR_MAPGEN_NORTHWEST_TOOLTIP :Alternar entre água e modo livre no limite noroeste do mapa +STR_MAPGEN_NORTHEAST_TOOLTIP :Alternar entre água e modo livre no limite nordeste do mapa +STR_MAPGEN_SOUTHEAST_TOOLTIP :Alternar entre água e modo livre no limite sudeste do mapa +STR_MAPGEN_SOUTHWEST_TOOLTIP :Alternar entre água e modo livre no limite sudoeste do mapa STR_MAPGEN_BORDER_FREEFORM :{BLACK}Modo livre STR_MAPGEN_BORDER_WATER :{BLACK}Água STR_MAPGEN_BORDER_RANDOM :{BLACK}Aleatório diff --git a/src/lang/russian.txt b/src/lang/russian.txt index f9ca11109c0ea..309c3a92e555a 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -3602,6 +3602,10 @@ STR_MAPGEN_NORTHWEST :{BLACK}Севе STR_MAPGEN_NORTHEAST :{BLACK}Северо-восток STR_MAPGEN_SOUTHEAST :{BLACK}Юго-восток STR_MAPGEN_SOUTHWEST :{BLACK}Юго-запад +STR_MAPGEN_NORTHWEST_TOOLTIP :Выбрать тип северо-западного края карты: водный или произвольной формы +STR_MAPGEN_NORTHEAST_TOOLTIP :Выбрать тип северо-восточного края карты: водный или произвольной формы +STR_MAPGEN_SOUTHEAST_TOOLTIP :Выбрать тип юго-восточного края карты: водный или произвольной формы +STR_MAPGEN_SOUTHWEST_TOOLTIP :Выбрать тип юго-западного края карты: водный или произвольной формы STR_MAPGEN_BORDER_FREEFORM :{BLACK}Свободный STR_MAPGEN_BORDER_WATER :{BLACK}Водный STR_MAPGEN_BORDER_RANDOM :{BLACK}Случайно From c4b16cb4cdb57fa6c9afe105e877f548a4c6d54f Mon Sep 17 00:00:00 2001 From: translators Date: Wed, 12 Nov 2025 04:39:35 +0000 Subject: [PATCH 118/137] Update: Translations from eints galician: 17 changes by pvillaverde polish: 4 changes by Rito13 --- src/lang/galician.txt | 19 +++++++++++++++++-- src/lang/polish.txt | 4 ++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/lang/galician.txt b/src/lang/galician.txt index 79258e6b87dd9..e5f6f2b46c268 100644 --- a/src/lang/galician.txt +++ b/src/lang/galician.txt @@ -255,6 +255,7 @@ STR_UNITS_FORCE_SI :{DECIMAL} kN STR_UNITS_HEIGHT_IMPERIAL :{DECIMAL} pés STR_UNITS_HEIGHT_METRIC :{DECIMAL} m STR_UNITS_HEIGHT_SI :{DECIMAL} m +STR_UNITS_HEIGHT_GAMEUNITS :{DECIMAL}{NBSP}Nive{P "" is} # Time units used in string control characters STR_UNITS_DAYS :{COMMA}{NBSP}día{P "" s} @@ -1544,7 +1545,7 @@ STR_CONFIG_SETTING_TIMEKEEPING_UNITS_CALENDAR :Calendario STR_CONFIG_SETTING_TIMEKEEPING_UNITS_WALLCLOCK :Reloxo STR_CONFIG_SETTING_MINUTES_PER_YEAR :Minutos por ano: {STRING} -STR_CONFIG_SETTING_MINUTES_PER_YEAR_HELPTEXT :Selecciona o número de minutos dun ano do calendario. Por defecto son 12 minutos. Fíxao en 0 para para conxelar o calendario. Increemntar a duración do ano do calendario ralentiza a introdución de vehículos, casas e outra infraestrutura. Non afecta a velocidade dos vehículos ou a simulación económica excepto pola inflación. Este axuste só está dispoñible cando se usa o modo reloxo de cronometraxe +STR_CONFIG_SETTING_MINUTES_PER_YEAR_HELPTEXT :Selecciona o número de minutos dun ano do calendario. Por defecto son 12 minutos. Fíxao en 0 para para conxelar o calendario. Incrementar a duración do ano do calendario ralentiza a introdución de vehículos, casas e outra infraestrutura. Non afecta a velocidade dos vehículos ou a simulación económica excepto pola inflación. Este axuste só está dispoñible cando se usa o modo reloxo de cronometraxe STR_CONFIG_SETTING_MINUTES_PER_YEAR_VALUE :{NUM} ###setting-zero-is-special @@ -2163,6 +2164,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_HELPTEXT :Cando as cotas STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (ft) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Métrico (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_GAMEUNITS :Unidades de xogo (niveis) STR_CONFIG_SETTING_LOCALISATION :Localización STR_CONFIG_SETTING_GRAPHICS :Gráficos @@ -2295,7 +2297,7 @@ STR_CHEAT_EDIT_MAX_HL_QUERY_CAPT :{WHITE}Trocar a STR_CHEAT_CHANGE_DATE :{LTBLUE}Cambiar data: {ORANGE}{DATE_SHORT} STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Cambiar o ano actual STR_CHEAT_SETUP_PROD :{LTBLUE}Permitir a modificación dos valores de producción: {ORANGE}{STRING} -STR_CHEAT_STATION_RATING :{LTBLUE}Manter a puntuacuón das estacións ao 100%: {ORANGE}{STRING} +STR_CHEAT_STATION_RATING :{LTBLUE}Manter a puntuación das estacións ao 100%: {ORANGE}{STRING} # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Novo esquema de cor @@ -3426,6 +3428,10 @@ STR_MAPGEN_NORTHWEST :{BLACK}Noroeste STR_MAPGEN_NORTHEAST :{BLACK}Nordés STR_MAPGEN_SOUTHEAST :{BLACK}Sueste STR_MAPGEN_SOUTHWEST :{BLACK}Suroeste +STR_MAPGEN_NORTHWEST_TOOLTIP :Alternar auga ou borde de forma libre na esquina noroeste do mapa +STR_MAPGEN_NORTHEAST_TOOLTIP :Alternar auga ou borde de forma libre na esquina nordeste do mapa +STR_MAPGEN_SOUTHEAST_TOOLTIP :Alternar auga ou borde de forma libre na esquina sudeste do mapa +STR_MAPGEN_SOUTHWEST_TOOLTIP :Alternar auga ou borde de forma libre na esquina sudoeste do mapa STR_MAPGEN_BORDER_FREEFORM :{BLACK}Forma libre STR_MAPGEN_BORDER_WATER :{BLACK}Auga STR_MAPGEN_BORDER_RANDOM :{BLACK}Aleatorio @@ -3472,6 +3478,8 @@ STR_GENERATION_LANDSCAPE_GENERATION :{BLACK}Xeració STR_GENERATION_RIVER_GENERATION :{BLACK}Xeración de ríos STR_GENERATION_CLEARING_TILES :{BLACK}Xeración de áreas rochosas e escarpadas STR_GENERATION_TOWN_GENERATION :{BLACK}Xeración de vilas +STR_GENERATION_LAND_INDUSTRY_GENERATION :{BLACK}Xeración de industria terrestre +STR_GENERATION_WATER_INDUSTRY_GENERATION :{BLACK}Xeración de industria marítima STR_GENERATION_OBJECT_GENERATION :{BLACK}Xeración de obxectos STR_GENERATION_TREE_GENERATION :{BLACK}Xeración de árbores STR_GENERATION_SETTINGUP_GAME :{BLACK}Configurando partida @@ -5269,6 +5277,13 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}O inicio STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... ambos extremos da ponte deben estar en terra STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... ponte demasiado longa STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}A ponte remataría fóra do mapa +STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}A ponte é {HEIGHT} demasiado baixa para a estación +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROADSTOP :{WHITE}A ponte é {HEIGHT} demasiado baixa para unha estación de estrada +STR_ERROR_BRIDGE_TOO_LOW_FOR_DOCK :{WHITE}A ponte é {HEIGHT} moi baixa para o porto +STR_ERROR_BRIDGE_TOO_LOW_FOR_BUOY :{WHITE}A ponte é {HEIGHT} demasiado baixa para a boia +STR_ERROR_BRIDGE_TOO_LOW_FOR_RAIL_WAYPOINT :{WHITE}A ponte é {HEIGHT} demasiado baixa para un punto de ruta de ferrocarril +STR_ERROR_BRIDGE_TOO_LOW_FOR_ROAD_WAYPOINT :{WHITE}A ponte é {HEIGHT} demasiado baixa para un punto de ruta de estrada +STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK :{WHITE}A ponte é {HEIGHT} moi baixa para a exclusa # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Non se pode construír un túnel aí... diff --git a/src/lang/polish.txt b/src/lang/polish.txt index 5e983a32f1a35..8a9fc72d45859 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -3807,6 +3807,10 @@ STR_MAPGEN_NORTHWEST :{BLACK}Płn.-za STR_MAPGEN_NORTHEAST :{BLACK}Płn.-wsch. STR_MAPGEN_SOUTHEAST :{BLACK}Płd.-wsch. STR_MAPGEN_SOUTHWEST :{BLACK}Płd.-zach. +STR_MAPGEN_NORTHWEST_TOOLTIP :Przełącz między wodą, a lądem na płn.-zach. krawędzi mapy +STR_MAPGEN_NORTHEAST_TOOLTIP :Przełącz między wodą, a lądem na płn.-wsch. krawędzi mapy +STR_MAPGEN_SOUTHEAST_TOOLTIP :Przełącz między wodą, a lądem na płd.-wsch. krawędzi mapy +STR_MAPGEN_SOUTHWEST_TOOLTIP :Przełącz między wodą, a lądem na płd.-zach. krawędzi mapy STR_MAPGEN_BORDER_FREEFORM :{BLACK}Ląd STR_MAPGEN_BORDER_WATER :{BLACK}Woda STR_MAPGEN_BORDER_RANDOM :{BLACK}Losowe From 120afd29f336ea2232a54fdbff7affbaa250f374 Mon Sep 17 00:00:00 2001 From: Rito12 <111280526+Rito13@users.noreply.github.com> Date: Wed, 12 Nov 2025 17:42:11 +0100 Subject: [PATCH 119/137] Codefix 394adb6: Make newgrf_badge_gui.cpp file docs compatible with the file name. (#14770) --- src/newgrf_badge_gui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/newgrf_badge_gui.h b/src/newgrf_badge_gui.h index bd47f05aaf145..e603308094ac9 100644 --- a/src/newgrf_badge_gui.h +++ b/src/newgrf_badge_gui.h @@ -5,7 +5,7 @@ * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . */ -/** @file newgrf_badge.h Functions related to NewGRF badges. */ +/** @file newgrf_badge_gui.h GUI functions related to NewGRF badges. */ #ifndef NEWGRF_BADGE_GUI_H #define NEWGRF_BADGE_GUI_H From dbe329733c801752372c7acd6e41b902b843a2cf Mon Sep 17 00:00:00 2001 From: translators Date: Thu, 13 Nov 2025 04:40:24 +0000 Subject: [PATCH 120/137] Update: Translations from eints korean: 4 changes by telk5093 --- src/lang/korean.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lang/korean.txt b/src/lang/korean.txt index 691a84d6b4a4e..e79cf65ee7147 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -3428,6 +3428,10 @@ STR_MAPGEN_NORTHWEST :{BLACK}북서 STR_MAPGEN_NORTHEAST :{BLACK}북동 STR_MAPGEN_SOUTHEAST :{BLACK}남동 STR_MAPGEN_SOUTHWEST :{BLACK}남서 +STR_MAPGEN_NORTHWEST_TOOLTIP :남서쪽 지도 맨 가장자리를 물로 할지 육지로 할지 고릅니다 +STR_MAPGEN_NORTHEAST_TOOLTIP :북동쪽 지도 맨 가장자리를 물로 할지 육지로 할지 고릅니다 +STR_MAPGEN_SOUTHEAST_TOOLTIP :남동쪽 지도 맨 가장자리를 물로 할지 육지로 할지 고릅니다 +STR_MAPGEN_SOUTHWEST_TOOLTIP :남서쪽 지도 맨 가장자리를 물로 할지 육지로 할지 고릅니다 STR_MAPGEN_BORDER_FREEFORM :{BLACK}변경 가능 STR_MAPGEN_BORDER_WATER :{BLACK}물 STR_MAPGEN_BORDER_RANDOM :{BLACK}임의 From c38aa9cc869cfcc1182cd5e4969859ef1168a42b Mon Sep 17 00:00:00 2001 From: Rito12 <111280526+Rito13@users.noreply.github.com> Date: Fri, 14 Nov 2025 00:24:46 +0100 Subject: [PATCH 121/137] Fix #14701: Company colour remap for sprites in badge filter dropdowns. (#14732) --- src/build_vehicle_gui.cpp | 3 ++- src/newgrf_badge_gui.cpp | 5 +++-- src/newgrf_badge_gui.h | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index ea6efdcfc4219..27deb5f430617 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -1731,7 +1731,8 @@ struct BuildVehicleWindow : Window { default: if (IsInsideMM(widget, this->badge_filters.first, this->badge_filters.second)) { - ShowDropDownList(this, this->GetWidget(widget)->GetDropDownList(), -1, widget, 0, false); + PaletteID palette = SPR_2CCMAP_BASE + Company::Get(_local_company)->GetCompanyRecolourOffset(LS_DEFAULT); + ShowDropDownList(this, this->GetWidget(widget)->GetDropDownList(palette), -1, widget, 0, false); } break; } diff --git a/src/newgrf_badge_gui.cpp b/src/newgrf_badge_gui.cpp index ff0a1d48c9fe9..93e133cf99214 100644 --- a/src/newgrf_badge_gui.cpp +++ b/src/newgrf_badge_gui.cpp @@ -508,9 +508,10 @@ std::string NWidgetBadgeFilter::GetStringParameter(const BadgeFilterChoices &cho /** * Get the drop down list of badges for this filter. + * @param palette Palette used to remap badge sprites. * @return Drop down list for filter. */ -DropDownList NWidgetBadgeFilter::GetDropDownList() const +DropDownList NWidgetBadgeFilter::GetDropDownList(PaletteID palette) const { DropDownList list; @@ -533,7 +534,7 @@ DropDownList NWidgetBadgeFilter::GetDropDownList() const if (badge.name == STR_NULL) continue; if (!badge.features.Test(this->feature)) continue; - PalSpriteID ps = GetBadgeSprite(badge, this->feature, std::nullopt, PAL_NONE); + PalSpriteID ps = GetBadgeSprite(badge, this->feature, std::nullopt, palette); if (ps.sprite == 0) { list.push_back(MakeDropDownListStringItem(badge.name, badge.index.base())); } else { diff --git a/src/newgrf_badge_gui.h b/src/newgrf_badge_gui.h index e603308094ac9..af2ed4cafcc97 100644 --- a/src/newgrf_badge_gui.h +++ b/src/newgrf_badge_gui.h @@ -65,7 +65,7 @@ class NWidgetBadgeFilter : public NWidgetLeaf { BadgeClassID GetBadgeClassID() const { return this->badge_class; } std::string GetStringParameter(const BadgeFilterChoices &choices) const; - DropDownList GetDropDownList() const; + DropDownList GetDropDownList(PaletteID palette = PAL_NONE) const; private: GrfSpecFeature feature; ///< Feature of this dropdown. From 76621050817a15103bfc8c9ba1462870b89f3bb2 Mon Sep 17 00:00:00 2001 From: mmtunligit <156685720+mmtunligit@users.noreply.github.com> Date: Fri, 14 Nov 2025 00:25:21 +0100 Subject: [PATCH 122/137] Change: Clamp terraform toolbar to main toolbar (#14725) --- src/airport_gui.cpp | 7 ++++++- src/dock_gui.cpp | 7 ++++++- src/rail_gui.cpp | 7 ++++++- src/road_gui.cpp | 9 +++++++-- src/terraform_gui.cpp | 19 +++++++------------ src/window.cpp | 20 +++++++++++++++++++- src/window_gui.h | 1 + 7 files changed, 52 insertions(+), 18 deletions(-) diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index 35208579155b3..b0bdd7cbb8f8a 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -161,6 +161,11 @@ struct BuildAirToolbarWindow : Window { VpSelectTilesWithMethod(pt.x, pt.y, select_method); } + Point OnInitialPosition(int16_t sm_width, [[maybe_unused]] int16_t sm_height, [[maybe_unused]] int window_number) override + { + return AlignInitialConstructionToolbar(sm_width); + } + void OnPlaceMouseUp([[maybe_unused]] ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, [[maybe_unused]] Point pt, TileIndex start_tile, TileIndex end_tile) override { if (pt.x != -1 && select_proc == DDSP_DEMOLISH_AREA) { @@ -211,7 +216,7 @@ static constexpr std::initializer_list _nested_air_toolbar_widgets }; static WindowDesc _air_toolbar_desc( - WDP_ALIGN_TOOLBAR, "toolbar_air", 0, 0, + WDP_MANUAL, "toolbar_air", 0, 0, WC_BUILD_TOOLBAR, WC_NONE, WindowDefaultFlag::Construction, _nested_air_toolbar_widgets, diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index caad21a280417..eea54f16e3477 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -250,6 +250,11 @@ struct BuildDocksToolbarWindow : Window { VpSelectTilesWithMethod(pt.x, pt.y, select_method); } + Point OnInitialPosition(int16_t sm_width, [[maybe_unused]] int16_t sm_height, [[maybe_unused]] int window_number) override + { + return AlignInitialConstructionToolbar(sm_width); + } + void OnPlaceMouseUp([[maybe_unused]] ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, [[maybe_unused]] Point pt, TileIndex start_tile, TileIndex end_tile) override { if (pt.x != -1) { @@ -352,7 +357,7 @@ static constexpr std::initializer_list _nested_build_docks_toolbar_ }; static WindowDesc _build_docks_toolbar_desc( - WDP_ALIGN_TOOLBAR, "toolbar_water", 0, 0, + WDP_MANUAL, "toolbar_water", 0, 0, WC_BUILD_TOOLBAR, WC_NONE, WindowDefaultFlag::Construction, _nested_build_docks_toolbar_widgets, diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 98400d2363fc6..5cbb9de22095c 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -728,6 +728,11 @@ struct BuildRailToolbarWindow : Window { VpSelectTilesWithMethod(pt.x, pt.y, select_method); } + Point OnInitialPosition(int16_t sm_width, [[maybe_unused]] int16_t sm_height, [[maybe_unused]] int window_number) override + { + return AlignInitialConstructionToolbar(sm_width); + } + void OnPlaceMouseUp([[maybe_unused]] ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, [[maybe_unused]] Point pt, TileIndex start_tile, TileIndex end_tile) override { if (pt.x != -1) { @@ -899,7 +904,7 @@ static constexpr std::initializer_list _nested_build_rail_widgets = }; static WindowDesc _build_rail_desc( - WDP_ALIGN_TOOLBAR, "toolbar_rail", 0, 0, + WDP_MANUAL, "toolbar_rail", 0, 0, WC_BUILD_TOOLBAR, WC_NONE, WindowDefaultFlag::Construction, _nested_build_rail_widgets, diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 7aac90b4b9ff1..aecfc9c8cdc3b 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -724,6 +724,11 @@ struct BuildRoadToolbarWindow : Window { VpSelectTilesWithMethod(pt.x, pt.y, select_method); } + Point OnInitialPosition(int16_t sm_width, [[maybe_unused]] int16_t sm_height, [[maybe_unused]] int window_number) override + { + return AlignInitialConstructionToolbar(sm_width); + } + void OnPlaceMouseUp([[maybe_unused]] ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, [[maybe_unused]] Point pt, TileIndex start_tile, TileIndex end_tile) override { if (pt.x != -1) { @@ -939,7 +944,7 @@ static constexpr std::initializer_list _nested_build_road_widgets = }; static WindowDesc _build_road_desc( - WDP_ALIGN_TOOLBAR, "toolbar_road", 0, 0, + WDP_MANUAL, "toolbar_road", 0, 0, WC_BUILD_TOOLBAR, WC_NONE, WindowDefaultFlag::Construction, _nested_build_road_widgets, @@ -984,7 +989,7 @@ static constexpr std::initializer_list _nested_build_tramway_widget }; static WindowDesc _build_tramway_desc( - WDP_ALIGN_TOOLBAR, "toolbar_tramway", 0, 0, + WDP_MANUAL, "toolbar_tramway", 0, 0, WC_BUILD_TOOLBAR, WC_NONE, WindowDefaultFlag::Construction, _nested_build_tramway_widgets, diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index 239f347025bc4..14a4597e1fafb 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -257,7 +257,8 @@ struct TerraformToolbarWindow : Window { Point OnInitialPosition([[maybe_unused]] int16_t sm_width, [[maybe_unused]] int16_t sm_height, [[maybe_unused]] int window_number) override { Point pt = GetToolbarAlignedWindowPosition(sm_width); - pt.y += sm_height; + if (FindWindowByClass(WC_BUILD_TOOLBAR) != nullptr && !_settings_client.gui.link_terraform_toolbar) pt.y += sm_height; + return pt; } @@ -364,19 +365,13 @@ Window *ShowTerraformToolbar(Window *link) { if (!Company::IsValidID(_local_company)) return nullptr; - Window *w; - if (link == nullptr) { - w = AllocateWindowDescFront(_terraform_desc, 0); - return w; - } - /* Delete the terraform toolbar to place it again. */ CloseWindowById(WC_SCEN_LAND_GEN, 0, true); - w = AllocateWindowDescFront(_terraform_desc, 0); - /* Align the terraform toolbar under the main toolbar. */ - w->top -= w->height; - w->SetDirty(); - /* Put the linked toolbar to the left / right of it. */ + + if (link == nullptr) return AllocateWindowDescFront(_terraform_desc, 0); + + Window *w = AllocateWindowDescFront(_terraform_desc, 0); + /* Put the linked toolbar to the left / right of the main toolbar. */ link->left = w->left + (_current_text_dir == TD_RTL ? w->width : -link->width); link->top = w->top; link->SetDirty(); diff --git a/src/window.cpp b/src/window.cpp index 419612e0bf9e8..4422cd86ed6b4 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1677,7 +1677,7 @@ static Point GetAutoPlacePosition(int width, int height) /** * Computer the position of the top-left corner of a window to be opened right * under the toolbar. - * @param window_width the width of the window to get the position for + * @param window_width the width of the window to get the position for. * @return Coordinate of the top-left corner of the new window. */ Point GetToolbarAlignedWindowPosition(int window_width) @@ -1688,6 +1688,24 @@ Point GetToolbarAlignedWindowPosition(int window_width) return pt; } +/** + * Compute the position of the construction toolbars. + * + * If the terraform toolbar is open place them to the right/left of it, + * otherwise use default toolbar aligned position. + * @param window_width the width of the toolbar to get the position for. + * @return Coordinate of the top-left corner of the new toolbar. + */ +Point AlignInitialConstructionToolbar(int window_width) +{ + Point pt = GetToolbarAlignedWindowPosition(window_width); + const Window *w = FindWindowByClass(WC_SCEN_LAND_GEN); + if (w != nullptr && w->top == pt.y && !_settings_client.gui.link_terraform_toolbar) { + pt.x = w->left + (_current_text_dir == TD_RTL ? w->width : - window_width); + } + return pt; +} + /** * Compute the position of the top-left corner of a new window that is opened. * diff --git a/src/window_gui.h b/src/window_gui.h index c6f1909ef29e9..bf09cd198512b 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -158,6 +158,7 @@ enum class WindowDefaultFlag : uint8_t { using WindowDefaultFlags = EnumBitSet; Point GetToolbarAlignedWindowPosition(int window_width); +Point AlignInitialConstructionToolbar(int window_width); struct HotkeyList; From 2693e63247ef58ab20e47640d1ac7bf340a4b93f Mon Sep 17 00:00:00 2001 From: translators Date: Fri, 14 Nov 2025 04:39:19 +0000 Subject: [PATCH 123/137] Update: Translations from eints norwegian (bokmal): 4 changes by eriksorngard --- src/lang/norwegian_bokmal.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lang/norwegian_bokmal.txt b/src/lang/norwegian_bokmal.txt index 0121c8b0fa1c3..454c7c84819e0 100644 --- a/src/lang/norwegian_bokmal.txt +++ b/src/lang/norwegian_bokmal.txt @@ -3429,6 +3429,10 @@ STR_MAPGEN_NORTHWEST :{BLACK}Nordvest STR_MAPGEN_NORTHEAST :{BLACK}Nordøst STR_MAPGEN_SOUTHEAST :{BLACK}Sørøst STR_MAPGEN_SOUTHWEST :{BLACK}Sørvest +STR_MAPGEN_NORTHWEST_TOOLTIP :Veksle mellom vann eller fri kant ved nordvestre kartkant +STR_MAPGEN_NORTHEAST_TOOLTIP :Veksle mellom vann eller fri kant ved nordøstre kartkant +STR_MAPGEN_SOUTHEAST_TOOLTIP :Veksle mellom vann eller fri kant ved sørøstre kartkant +STR_MAPGEN_SOUTHWEST_TOOLTIP :Veksle mellom vann eller fri kant ved sørvestre kartkant STR_MAPGEN_BORDER_FREEFORM :{BLACK}Frihånds STR_MAPGEN_BORDER_WATER :{BLACK}Sjø STR_MAPGEN_BORDER_RANDOM :{BLACK}Tilfeldig From 459d213f748e3359485ba495f2949b6f7abac7d9 Mon Sep 17 00:00:00 2001 From: translators Date: Sat, 15 Nov 2025 04:38:42 +0000 Subject: [PATCH 124/137] Update: Translations from eints polish: 4 changes by pAter-exe --- src/lang/polish.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lang/polish.txt b/src/lang/polish.txt index 8a9fc72d45859..f4c6d6274b079 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -3807,10 +3807,10 @@ STR_MAPGEN_NORTHWEST :{BLACK}Płn.-za STR_MAPGEN_NORTHEAST :{BLACK}Płn.-wsch. STR_MAPGEN_SOUTHEAST :{BLACK}Płd.-wsch. STR_MAPGEN_SOUTHWEST :{BLACK}Płd.-zach. -STR_MAPGEN_NORTHWEST_TOOLTIP :Przełącz między wodą, a lądem na płn.-zach. krawędzi mapy -STR_MAPGEN_NORTHEAST_TOOLTIP :Przełącz między wodą, a lądem na płn.-wsch. krawędzi mapy -STR_MAPGEN_SOUTHEAST_TOOLTIP :Przełącz między wodą, a lądem na płd.-wsch. krawędzi mapy -STR_MAPGEN_SOUTHWEST_TOOLTIP :Przełącz między wodą, a lądem na płd.-zach. krawędzi mapy +STR_MAPGEN_NORTHWEST_TOOLTIP :Przełącz między wodą a lądem na płn.-zach. krawędzi mapy +STR_MAPGEN_NORTHEAST_TOOLTIP :Przełącz między wodą a lądem na płn.-wsch. krawędzi mapy +STR_MAPGEN_SOUTHEAST_TOOLTIP :Przełącz między wodą a lądem na płd.-wsch. krawędzi mapy +STR_MAPGEN_SOUTHWEST_TOOLTIP :Przełącz między wodą a lądem na płd.-zach. krawędzi mapy STR_MAPGEN_BORDER_FREEFORM :{BLACK}Ląd STR_MAPGEN_BORDER_WATER :{BLACK}Woda STR_MAPGEN_BORDER_RANDOM :{BLACK}Losowe From 2b2444414629814fe97b35aff4c2d5ba8eec8e1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Guilloux?= Date: Sat, 15 Nov 2025 09:19:33 +0100 Subject: [PATCH 125/137] Codechange: Detect crashes during regression (#14774) --- cmake/scripts/Regression.cmake | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cmake/scripts/Regression.cmake b/cmake/scripts/Regression.cmake index a6833e2dd1471..e9ce5ea6f29c1 100644 --- a/cmake/scripts/Regression.cmake +++ b/cmake/scripts/Regression.cmake @@ -25,6 +25,10 @@ if(EDITBIN_EXECUTABLE) execute_process(COMMAND ${EDITBIN_EXECUTABLE} /nologo /subsystem:console ${OPENTTD_EXECUTABLE}) endif() +# Remove previous crash files +file(GLOB CRASH_FILES "regression/crash*") +file(REMOVE ${CRASH_FILES}) + # Run the regression test execute_process(COMMAND ${OPENTTD_EXECUTABLE} -x @@ -40,6 +44,13 @@ execute_process(COMMAND ${OPENTTD_EXECUTABLE} OUTPUT_STRIP_TRAILING_WHITESPACE ) +# Detect any crash +file(GLOB CRASH_FILES "regression/crash*.log") +if (CRASH_FILES) + file(READ ${CRASH_FILES} CRASH_LOG) + message(FATAL_ERROR "OpenTTD crashed: ${CRASH_LOG}") +endif() + if(REGRESSION_OUTPUT) message(FATAL_ERROR "Unexpected output: ${REGRESSION_OUTPUT}") endif() From d61a21cc0bd1a4a8d6d38368daadc4a38093dfaf Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 15 Nov 2025 19:33:09 +0000 Subject: [PATCH 126/137] Codechange: Use enum class for command-related enums. (#14775) --- src/autoreplace_cmd.h | 4 ++-- src/command.cpp | 26 +++++++++++++------------- src/command_type.h | 37 +++++++++++++++++++------------------ src/company_cmd.h | 14 +++++++------- src/depot_cmd.h | 2 +- src/economy_cmd.h | 2 +- src/engine_cmd.h | 8 ++++---- src/goal_cmd.h | 16 ++++++++-------- src/group_cmd.h | 16 ++++++++-------- src/industry_cmd.h | 10 +++++----- src/landscape_cmd.h | 4 ++-- src/league_cmd.h | 10 +++++----- src/misc_cmd.h | 12 ++++++------ src/news_cmd.h | 2 +- src/object_cmd.h | 4 ++-- src/order_cmd.h | 16 ++++++++-------- src/rail_cmd.h | 20 ++++++++++---------- src/road_cmd.h | 10 +++++----- src/roadveh_cmd.h | 2 +- src/settings_cmd.h | 4 ++-- src/settings_type.h | 3 ++- src/signs_cmd.h | 4 ++-- src/station_cmd.h | 16 ++++++++-------- src/story_cmd.h | 18 +++++++++--------- src/subsidy_cmd.h | 2 +- src/terraform_cmd.h | 4 ++-- src/texteff.cpp | 2 +- src/timetable_cmd.h | 10 +++++----- src/town_cmd.h | 20 ++++++++++---------- src/train_cmd.h | 6 +++--- src/tree_cmd.h | 2 +- src/tunnelbridge_cmd.h | 4 ++-- src/vehicle_cmd.h | 22 +++++++++++----------- src/viewport_cmd.h | 2 +- src/water_cmd.h | 6 +++--- src/waypoint_cmd.h | 12 ++++++------ 36 files changed, 177 insertions(+), 175 deletions(-) diff --git a/src/autoreplace_cmd.h b/src/autoreplace_cmd.h index 5f9af672d2433..df4c268255367 100644 --- a/src/autoreplace_cmd.h +++ b/src/autoreplace_cmd.h @@ -18,7 +18,7 @@ CommandCost CmdAutoreplaceVehicle(DoCommandFlags flags, VehicleID veh_id); CommandCost CmdSetAutoReplace(DoCommandFlags flags, GroupID id_g, EngineID old_engine_type, EngineID new_engine_type, bool when_old); -DEF_CMD_TRAIT(CMD_AUTOREPLACE_VEHICLE, CmdAutoreplaceVehicle, {}, CMDT_VEHICLE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_SET_AUTOREPLACE, CmdSetAutoReplace, {}, CMDT_VEHICLE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_AUTOREPLACE_VEHICLE, CmdAutoreplaceVehicle, {}, CommandType::VehicleManagement) +DEF_CMD_TRAIT(CMD_SET_AUTOREPLACE, CmdSetAutoReplace, {}, CommandType::VehicleManagement) #endif /* AUTOREPLACE_CMD_H */ diff --git a/src/command.cpp b/src/command.cpp index c11289902e2fb..2cdc9ed3ad4ec 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -144,21 +144,21 @@ std::string_view GetCommandName(Commands cmd) bool IsCommandAllowedWhilePaused(Commands cmd) { /* Lookup table for the command types that are allowed for a given pause level setting. */ - static const int command_type_lookup[] = { - CMDPL_ALL_ACTIONS, ///< CMDT_LANDSCAPE_CONSTRUCTION - CMDPL_NO_LANDSCAPING, ///< CMDT_VEHICLE_CONSTRUCTION - CMDPL_NO_LANDSCAPING, ///< CMDT_MONEY_MANAGEMENT - CMDPL_NO_CONSTRUCTION, ///< CMDT_VEHICLE_MANAGEMENT - CMDPL_NO_CONSTRUCTION, ///< CMDT_ROUTE_MANAGEMENT - CMDPL_NO_CONSTRUCTION, ///< CMDT_OTHER_MANAGEMENT - CMDPL_NO_ACTIONS, ///< CMDT_COMPANY_SETTING - CMDPL_NO_ACTIONS, ///< CMDT_SERVER_SETTING - CMDPL_NO_ACTIONS, ///< CMDT_CHEAT + static constexpr CommandPauseLevel command_type_lookup[] = { + CommandPauseLevel::AllActions, // CommandType::LandscapeConstruction + CommandPauseLevel::NoLandscaping, // CommandType::VehicleConstruction + CommandPauseLevel::NoLandscaping, // CommandType::MoneyManagement + CommandPauseLevel::NoConstruction, // CommandType::VehicleManagement + CommandPauseLevel::NoConstruction, // CommandType::RouteManagement + CommandPauseLevel::NoConstruction, // CommandType::OtherManagement + CommandPauseLevel::NoActions, // CommandType::CompanySetting + CommandPauseLevel::NoActions, // CommandType::ServerSetting + CommandPauseLevel::NoActions, // CommandType::Cheat }; - static_assert(lengthof(command_type_lookup) == CMDT_END); + static_assert(std::size(command_type_lookup) == to_underlying(CommandType::End)); assert(IsValidCommand(cmd)); - return _game_mode == GM_EDITOR || command_type_lookup[_command_proc_table[cmd].type] <= _settings_game.construction.command_pause_level; + return _game_mode == GM_EDITOR || command_type_lookup[to_underlying(_command_proc_table[cmd].type)] <= _settings_game.construction.command_pause_level; } /** @@ -384,7 +384,7 @@ CommandCost CommandHelperBase::InternalExecuteProcessResult(Commands cmd, Comman SubtractMoneyFromCompany(res_exec); /* Record if there was a command issues during pause; ignore pause/other setting related changes. */ - if (_pause_mode.Any() && _command_proc_table[cmd].type != CMDT_SERVER_SETTING) _pause_mode.Set(PauseMode::CommandDuringPause); + if (_pause_mode.Any() && _command_proc_table[cmd].type != CommandType::ServerSetting) _pause_mode.Set(PauseMode::CommandDuringPause); /* update signals if needed */ UpdateSignalsInBuffer(); diff --git a/src/command_type.h b/src/command_type.h index 893a03d44cc8a..babf32dd5489f 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -380,7 +380,7 @@ enum Commands : uint8_t { * * This enums defines some flags which can be used for the commands. */ -enum DoCommandFlag : uint8_t { +enum class DoCommandFlag : uint8_t { Execute, ///< execute the given command Auto, ///< don't allow building on structures QueryCost, ///< query cost only, don't build. @@ -417,26 +417,27 @@ enum class CommandFlag : uint8_t { using CommandFlags = EnumBitSet; /** Types of commands we have. */ -enum CommandType : uint8_t { - CMDT_LANDSCAPE_CONSTRUCTION, ///< Construction and destruction of objects on the map. - CMDT_VEHICLE_CONSTRUCTION, ///< Construction, modification (incl. refit) and destruction of vehicles. - CMDT_MONEY_MANAGEMENT, ///< Management of money, i.e. loans. - CMDT_VEHICLE_MANAGEMENT, ///< Stopping, starting, sending to depot, turning around, replace orders etc. - CMDT_ROUTE_MANAGEMENT, ///< Modifications to route management (orders, groups, etc). - CMDT_OTHER_MANAGEMENT, ///< Renaming stuff, changing company colours, placing signs, etc. - CMDT_COMPANY_SETTING, ///< Changing settings related to a company. - CMDT_SERVER_SETTING, ///< Pausing/removing companies/server settings. - CMDT_CHEAT, ///< A cheat of some sorts. - - CMDT_END, ///< Magic end marker. +enum class CommandType : uint8_t { + LandscapeConstruction, ///< Construction and destruction of objects on the map. + VehicleConstruction, ///< Construction, modification (incl. refit) and destruction of vehicles. + MoneyManagement, ///< Management of money, i.e. loans. + VehicleManagement, ///< Stopping, starting, sending to depot, turning around, replace orders etc. + RouteManagement, ///< Modifications to route management (orders, groups, etc). + OtherManagement, ///< Renaming stuff, changing company colours, placing signs, etc. + CompanySetting, ///< Changing settings related to a company. + ServerSetting, ///< Pausing/removing companies/server settings. + Cheat, ///< A cheat of some sorts. + + End, ///< End marker. }; /** Different command pause levels. */ -enum CommandPauseLevel : uint8_t { - CMDPL_NO_ACTIONS, ///< No user actions may be executed. - CMDPL_NO_CONSTRUCTION, ///< No construction actions may be executed. - CMDPL_NO_LANDSCAPING, ///< No landscaping actions may be executed. - CMDPL_ALL_ACTIONS, ///< All actions may be executed. + +enum class CommandPauseLevel : uint8_t { + NoActions, ///< No user actions may be executed. + NoConstruction, ///< No construction actions may be executed. + NoLandscaping, ///< No landscaping actions may be executed. + AllActions, ///< All actions may be executed. }; diff --git a/src/company_cmd.h b/src/company_cmd.h index eb30f9b361b07..a18af2f8cb7eb 100644 --- a/src/company_cmd.h +++ b/src/company_cmd.h @@ -25,12 +25,12 @@ CommandCost CmdRenamePresident(DoCommandFlags flags, const std::string &text); CommandCost CmdSetCompanyManagerFace(DoCommandFlags flags, uint style, uint32_t bits); CommandCost CmdSetCompanyColour(DoCommandFlags flags, LiveryScheme scheme, bool primary, Colours colour); -DEF_CMD_TRAIT(CMD_COMPANY_CTRL, CmdCompanyCtrl, CommandFlags({CommandFlag::Spectator, CommandFlag::ClientID, CommandFlag::NoEst}), CMDT_SERVER_SETTING) -DEF_CMD_TRAIT(CMD_COMPANY_ALLOW_LIST_CTRL, CmdCompanyAllowListCtrl, CommandFlag::NoEst, CMDT_SERVER_SETTING) -DEF_CMD_TRAIT(CMD_GIVE_MONEY, CmdGiveMoney, {}, CMDT_MONEY_MANAGEMENT) -DEF_CMD_TRAIT(CMD_RENAME_COMPANY, CmdRenameCompany, {}, CMDT_COMPANY_SETTING) -DEF_CMD_TRAIT(CMD_RENAME_PRESIDENT, CmdRenamePresident, {}, CMDT_COMPANY_SETTING) -DEF_CMD_TRAIT(CMD_SET_COMPANY_MANAGER_FACE, CmdSetCompanyManagerFace, {}, CMDT_COMPANY_SETTING) -DEF_CMD_TRAIT(CMD_SET_COMPANY_COLOUR, CmdSetCompanyColour, {}, CMDT_COMPANY_SETTING) +DEF_CMD_TRAIT(CMD_COMPANY_CTRL, CmdCompanyCtrl, CommandFlags({CommandFlag::Spectator, CommandFlag::ClientID, CommandFlag::NoEst}), CommandType::ServerSetting) +DEF_CMD_TRAIT(CMD_COMPANY_ALLOW_LIST_CTRL, CmdCompanyAllowListCtrl, CommandFlag::NoEst, CommandType::ServerSetting) +DEF_CMD_TRAIT(CMD_GIVE_MONEY, CmdGiveMoney, {}, CommandType::MoneyManagement) +DEF_CMD_TRAIT(CMD_RENAME_COMPANY, CmdRenameCompany, {}, CommandType::CompanySetting) +DEF_CMD_TRAIT(CMD_RENAME_PRESIDENT, CmdRenamePresident, {}, CommandType::CompanySetting) +DEF_CMD_TRAIT(CMD_SET_COMPANY_MANAGER_FACE, CmdSetCompanyManagerFace, {}, CommandType::CompanySetting) +DEF_CMD_TRAIT(CMD_SET_COMPANY_COLOUR, CmdSetCompanyColour, {}, CommandType::CompanySetting) #endif /* COMPANY_CMD_H */ diff --git a/src/depot_cmd.h b/src/depot_cmd.h index abd3e1900e9fe..69f558f6c5cab 100644 --- a/src/depot_cmd.h +++ b/src/depot_cmd.h @@ -16,7 +16,7 @@ CommandCost CmdRenameDepot(DoCommandFlags flags, DepotID depot_id, const std::string &text); -DEF_CMD_TRAIT(CMD_RENAME_DEPOT, CmdRenameDepot, {}, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_RENAME_DEPOT, CmdRenameDepot, {}, CommandType::OtherManagement) void CcCloneVehicle(Commands cmd, const CommandCost &result, VehicleID veh_id); diff --git a/src/economy_cmd.h b/src/economy_cmd.h index 15825aa7b8ff5..37aa5eb38e8e4 100644 --- a/src/economy_cmd.h +++ b/src/economy_cmd.h @@ -15,6 +15,6 @@ CommandCost CmdBuyCompany(DoCommandFlags flags, CompanyID target_company, bool hostile_takeover); -DEF_CMD_TRAIT(CMD_BUY_COMPANY, CmdBuyCompany, {}, CMDT_MONEY_MANAGEMENT) +DEF_CMD_TRAIT(CMD_BUY_COMPANY, CmdBuyCompany, {}, CommandType::MoneyManagement) #endif /* ECONOMY_CMD_H */ diff --git a/src/engine_cmd.h b/src/engine_cmd.h index 0f9911914577d..153a5055e1a0c 100644 --- a/src/engine_cmd.h +++ b/src/engine_cmd.h @@ -17,9 +17,9 @@ CommandCost CmdEngineCtrl(DoCommandFlags flags, EngineID engine_id, CompanyID co CommandCost CmdRenameEngine(DoCommandFlags flags, EngineID engine_id, const std::string &text); CommandCost CmdSetVehicleVisibility(DoCommandFlags flags, EngineID engine_id, bool hide); -DEF_CMD_TRAIT(CMD_WANT_ENGINE_PREVIEW, CmdWantEnginePreview, {}, CMDT_VEHICLE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_ENGINE_CTRL, CmdEngineCtrl, CommandFlag::Deity, CMDT_VEHICLE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_RENAME_ENGINE, CmdRenameEngine, CommandFlag::Server, CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_SET_VEHICLE_VISIBILITY, CmdSetVehicleVisibility, {}, CMDT_COMPANY_SETTING) +DEF_CMD_TRAIT(CMD_WANT_ENGINE_PREVIEW, CmdWantEnginePreview, {}, CommandType::VehicleManagement) +DEF_CMD_TRAIT(CMD_ENGINE_CTRL, CmdEngineCtrl, CommandFlag::Deity, CommandType::VehicleManagement) +DEF_CMD_TRAIT(CMD_RENAME_ENGINE, CmdRenameEngine, CommandFlag::Server, CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_SET_VEHICLE_VISIBILITY, CmdSetVehicleVisibility, {}, CommandType::CompanySetting) #endif /* ENGINE_CMD_H */ diff --git a/src/goal_cmd.h b/src/goal_cmd.h index 4cb017ede9f52..7002bad775f32 100644 --- a/src/goal_cmd.h +++ b/src/goal_cmd.h @@ -22,13 +22,13 @@ CommandCost CmdSetGoalCompleted(DoCommandFlags flags, GoalID goal, bool complete CommandCost CmdGoalQuestion(DoCommandFlags flags, uint16_t uniqueid, uint32_t target, bool is_client, uint32_t button_mask, GoalQuestionType type, const EncodedString &text); CommandCost CmdGoalQuestionAnswer(DoCommandFlags flags, uint16_t uniqueid, uint8_t button); -DEF_CMD_TRAIT(CMD_CREATE_GOAL, CmdCreateGoal, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_REMOVE_GOAL, CmdRemoveGoal, CommandFlag::Deity, CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_SET_GOAL_DESTINATION, CmdSetGoalDestination, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_SET_GOAL_TEXT, CmdSetGoalText, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_SET_GOAL_PROGRESS, CmdSetGoalProgress, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_SET_GOAL_COMPLETED, CmdSetGoalCompleted, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_GOAL_QUESTION, CmdGoalQuestion, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_GOAL_QUESTION_ANSWER, CmdGoalQuestionAnswer, CommandFlag::Deity, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_CREATE_GOAL, CmdCreateGoal, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_REMOVE_GOAL, CmdRemoveGoal, CommandFlag::Deity, CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_SET_GOAL_DESTINATION, CmdSetGoalDestination, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_SET_GOAL_TEXT, CmdSetGoalText, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_SET_GOAL_PROGRESS, CmdSetGoalProgress, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_SET_GOAL_COMPLETED, CmdSetGoalCompleted, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_GOAL_QUESTION, CmdGoalQuestion, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_GOAL_QUESTION_ANSWER, CmdGoalQuestionAnswer, CommandFlag::Deity, CommandType::OtherManagement) #endif /* GOAL_CMD_H */ diff --git a/src/group_cmd.h b/src/group_cmd.h index abef37b54270b..dea6d7120f116 100644 --- a/src/group_cmd.h +++ b/src/group_cmd.h @@ -34,14 +34,14 @@ CommandCost CmdRemoveAllVehiclesGroup(DoCommandFlags flags, GroupID group_id); CommandCost CmdSetGroupFlag(DoCommandFlags flags, GroupID group_id, GroupFlag flag, bool value, bool recursive); CommandCost CmdSetGroupLivery(DoCommandFlags flags, GroupID group_id, bool primary, Colours colour); -DEF_CMD_TRAIT(CMD_CREATE_GROUP, CmdCreateGroup, {}, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_DELETE_GROUP, CmdDeleteGroup, {}, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_ALTER_GROUP, CmdAlterGroup, {}, CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_ADD_VEHICLE_GROUP, CmdAddVehicleGroup, {}, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_ADD_SHARED_VEHICLE_GROUP, CmdAddSharedVehicleGroup, {}, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_REMOVE_ALL_VEHICLES_GROUP, CmdRemoveAllVehiclesGroup, {}, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_SET_GROUP_FLAG, CmdSetGroupFlag, {}, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_SET_GROUP_LIVERY, CmdSetGroupLivery, {}, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_CREATE_GROUP, CmdCreateGroup, {}, CommandType::RouteManagement) +DEF_CMD_TRAIT(CMD_DELETE_GROUP, CmdDeleteGroup, {}, CommandType::RouteManagement) +DEF_CMD_TRAIT(CMD_ALTER_GROUP, CmdAlterGroup, {}, CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_ADD_VEHICLE_GROUP, CmdAddVehicleGroup, {}, CommandType::RouteManagement) +DEF_CMD_TRAIT(CMD_ADD_SHARED_VEHICLE_GROUP, CmdAddSharedVehicleGroup, {}, CommandType::RouteManagement) +DEF_CMD_TRAIT(CMD_REMOVE_ALL_VEHICLES_GROUP, CmdRemoveAllVehiclesGroup, {}, CommandType::RouteManagement) +DEF_CMD_TRAIT(CMD_SET_GROUP_FLAG, CmdSetGroupFlag, {}, CommandType::RouteManagement) +DEF_CMD_TRAIT(CMD_SET_GROUP_LIVERY, CmdSetGroupLivery, {}, CommandType::RouteManagement) void CcCreateGroup(Commands cmd, const CommandCost &result, GroupID new_group, VehicleType vt, GroupID parent_group); void CcAddVehicleNewGroup(Commands cmd, const CommandCost &result, GroupID new_group, GroupID, VehicleID veh_id, bool, const VehicleListIdentifier &); diff --git a/src/industry_cmd.h b/src/industry_cmd.h index f1d8b5f4dca01..78a7687cda153 100644 --- a/src/industry_cmd.h +++ b/src/industry_cmd.h @@ -21,10 +21,10 @@ CommandCost CmdIndustrySetExclusivity(DoCommandFlags flags, IndustryID ind_id, O CommandCost CmdIndustrySetText(DoCommandFlags flags, IndustryID ind_id, const EncodedString &text); CommandCost CmdIndustrySetProduction(DoCommandFlags flags, IndustryID ind_id, uint8_t prod_level, bool show_news, const EncodedString &text); -DEF_CMD_TRAIT(CMD_BUILD_INDUSTRY, CmdBuildIndustry, CommandFlag::Deity, CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_INDUSTRY_SET_FLAGS, CmdIndustrySetFlags, CommandFlag::Deity, CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_INDUSTRY_SET_EXCLUSIVITY, CmdIndustrySetExclusivity, CommandFlag::Deity, CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_INDUSTRY_SET_TEXT, CmdIndustrySetText, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_INDUSTRY_SET_PRODUCTION, CmdIndustrySetProduction, CommandFlag::Deity, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_BUILD_INDUSTRY, CmdBuildIndustry, CommandFlag::Deity, CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_INDUSTRY_SET_FLAGS, CmdIndustrySetFlags, CommandFlag::Deity, CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_INDUSTRY_SET_EXCLUSIVITY, CmdIndustrySetExclusivity, CommandFlag::Deity, CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_INDUSTRY_SET_TEXT, CmdIndustrySetText, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_INDUSTRY_SET_PRODUCTION, CmdIndustrySetProduction, CommandFlag::Deity, CommandType::OtherManagement) #endif /* INDUSTRY_CMD_H */ diff --git a/src/landscape_cmd.h b/src/landscape_cmd.h index 2062eac61950f..1ae5b7b1b2352 100644 --- a/src/landscape_cmd.h +++ b/src/landscape_cmd.h @@ -15,7 +15,7 @@ CommandCost CmdLandscapeClear(DoCommandFlags flags, TileIndex tile); std::tuple CmdClearArea(DoCommandFlags flags, TileIndex tile, TileIndex start_tile, bool diagonal); -DEF_CMD_TRAIT(CMD_LANDSCAPE_CLEAR, CmdLandscapeClear, CommandFlag::Deity, CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_CLEAR_AREA, CmdClearArea, CommandFlag::NoTest, CMDT_LANDSCAPE_CONSTRUCTION) // destroying multi-tile houses makes town rating differ between test and execution +DEF_CMD_TRAIT(CMD_LANDSCAPE_CLEAR, CmdLandscapeClear, CommandFlag::Deity, CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_CLEAR_AREA, CmdClearArea, CommandFlag::NoTest, CommandType::LandscapeConstruction) // destroying multi-tile houses makes town rating differ between test and execution #endif /* LANDSCAPE_CMD_H */ diff --git a/src/league_cmd.h b/src/league_cmd.h index 89a58915a4124..83f9f3c5342f2 100644 --- a/src/league_cmd.h +++ b/src/league_cmd.h @@ -20,10 +20,10 @@ CommandCost CmdUpdateLeagueTableElementData(DoCommandFlags flags, LeagueTableEle CommandCost CmdUpdateLeagueTableElementScore(DoCommandFlags flags, LeagueTableElementID element, int64_t rating, const EncodedString &score); CommandCost CmdRemoveLeagueTableElement(DoCommandFlags flags, LeagueTableElementID element); -DEF_CMD_TRAIT(CMD_CREATE_LEAGUE_TABLE, CmdCreateLeagueTable, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_CREATE_LEAGUE_TABLE_ELEMENT, CmdCreateLeagueTableElement, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_UPDATE_LEAGUE_TABLE_ELEMENT_DATA, CmdUpdateLeagueTableElementData, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_UPDATE_LEAGUE_TABLE_ELEMENT_SCORE, CmdUpdateLeagueTableElementScore, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_REMOVE_LEAGUE_TABLE_ELEMENT, CmdRemoveLeagueTableElement, CommandFlag::Deity, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_CREATE_LEAGUE_TABLE, CmdCreateLeagueTable, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_CREATE_LEAGUE_TABLE_ELEMENT, CmdCreateLeagueTableElement, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_UPDATE_LEAGUE_TABLE_ELEMENT_DATA, CmdUpdateLeagueTableElementData, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_UPDATE_LEAGUE_TABLE_ELEMENT_SCORE, CmdUpdateLeagueTableElementScore, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_REMOVE_LEAGUE_TABLE_ELEMENT, CmdRemoveLeagueTableElement, CommandFlag::Deity, CommandType::OtherManagement) #endif /* LEAGUE_CMD_H */ diff --git a/src/misc_cmd.h b/src/misc_cmd.h index 3b60ec562573f..fb5279a7f3950 100644 --- a/src/misc_cmd.h +++ b/src/misc_cmd.h @@ -27,11 +27,11 @@ CommandCost CmdDecreaseLoan(DoCommandFlags flags, LoanCommand cmd, Money amount) CommandCost CmdSetCompanyMaxLoan(DoCommandFlags flags, CompanyID company, Money amount); CommandCost CmdPause(DoCommandFlags flags, PauseMode mode, bool pause); -DEF_CMD_TRAIT(CMD_MONEY_CHEAT, CmdMoneyCheat, CommandFlags({CommandFlag::Offline, CommandFlag::NoEst}), CMDT_CHEAT) -DEF_CMD_TRAIT(CMD_CHANGE_BANK_BALANCE, CmdChangeBankBalance, CommandFlag::Deity, CMDT_MONEY_MANAGEMENT) -DEF_CMD_TRAIT(CMD_INCREASE_LOAN, CmdIncreaseLoan, {}, CMDT_MONEY_MANAGEMENT) -DEF_CMD_TRAIT(CMD_DECREASE_LOAN, CmdDecreaseLoan, {}, CMDT_MONEY_MANAGEMENT) -DEF_CMD_TRAIT(CMD_SET_COMPANY_MAX_LOAN, CmdSetCompanyMaxLoan, CommandFlag::Deity, CMDT_MONEY_MANAGEMENT) -DEF_CMD_TRAIT(CMD_PAUSE, CmdPause, CommandFlags({CommandFlag::Server, CommandFlag::NoEst}), CMDT_SERVER_SETTING) +DEF_CMD_TRAIT(CMD_MONEY_CHEAT, CmdMoneyCheat, CommandFlags({CommandFlag::Offline, CommandFlag::NoEst}), CommandType::Cheat) +DEF_CMD_TRAIT(CMD_CHANGE_BANK_BALANCE, CmdChangeBankBalance, CommandFlag::Deity, CommandType::MoneyManagement) +DEF_CMD_TRAIT(CMD_INCREASE_LOAN, CmdIncreaseLoan, {}, CommandType::MoneyManagement) +DEF_CMD_TRAIT(CMD_DECREASE_LOAN, CmdDecreaseLoan, {}, CommandType::MoneyManagement) +DEF_CMD_TRAIT(CMD_SET_COMPANY_MAX_LOAN, CmdSetCompanyMaxLoan, CommandFlag::Deity, CommandType::MoneyManagement) +DEF_CMD_TRAIT(CMD_PAUSE, CmdPause, CommandFlags({CommandFlag::Server, CommandFlag::NoEst}), CommandType::ServerSetting) #endif /* MISC_CMD_H */ diff --git a/src/news_cmd.h b/src/news_cmd.h index df9523c253784..c84c29e141b37 100644 --- a/src/news_cmd.h +++ b/src/news_cmd.h @@ -16,6 +16,6 @@ CommandCost CmdCustomNewsItem(DoCommandFlags flags, NewsType type, CompanyID company, NewsReference reference, const EncodedString &text); -DEF_CMD_TRAIT(CMD_CUSTOM_NEWS_ITEM, CmdCustomNewsItem, CommandFlags({CommandFlag::StrCtrl, CommandFlag::Deity}), CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_CUSTOM_NEWS_ITEM, CmdCustomNewsItem, CommandFlags({CommandFlag::StrCtrl, CommandFlag::Deity}), CommandType::OtherManagement) #endif /* NEWS_CMD_H */ diff --git a/src/object_cmd.h b/src/object_cmd.h index 0fb18d7fa8bbe..048b3c6dfdf17 100644 --- a/src/object_cmd.h +++ b/src/object_cmd.h @@ -16,7 +16,7 @@ CommandCost CmdBuildObject(DoCommandFlags flags, TileIndex tile, ObjectType type, uint8_t view); CommandCost CmdBuildObjectArea(DoCommandFlags flags, TileIndex tile, TileIndex start_tile, ObjectType type, uint8_t view, bool diagonal); -DEF_CMD_TRAIT(CMD_BUILD_OBJECT, CmdBuildObject, CommandFlags({CommandFlag::Deity, CommandFlag::NoWater, CommandFlag::Auto}), CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_BUILD_OBJECT_AREA, CmdBuildObjectArea, CommandFlags({CommandFlag::Deity, CommandFlag::NoWater, CommandFlag::NoTest, CommandFlag::Auto}), CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_BUILD_OBJECT, CmdBuildObject, CommandFlags({CommandFlag::Deity, CommandFlag::NoWater, CommandFlag::Auto}), CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_BUILD_OBJECT_AREA, CmdBuildObjectArea, CommandFlags({CommandFlag::Deity, CommandFlag::NoWater, CommandFlag::NoTest, CommandFlag::Auto}), CommandType::LandscapeConstruction) #endif /* OBJECT_CMD_H */ diff --git a/src/order_cmd.h b/src/order_cmd.h index 5d1e9039d45f9..405a0e8c95f81 100644 --- a/src/order_cmd.h +++ b/src/order_cmd.h @@ -23,14 +23,14 @@ CommandCost CmdCloneOrder(DoCommandFlags flags, CloneOptions action, VehicleID v CommandCost CmdMoveOrder(DoCommandFlags flags, VehicleID veh, VehicleOrderID moving_order, VehicleOrderID target_order); CommandCost CmdClearOrderBackup(DoCommandFlags flags, TileIndex tile, ClientID user_id); -DEF_CMD_TRAIT(CMD_MODIFY_ORDER, CmdModifyOrder, CommandFlag::Location, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_SKIP_TO_ORDER, CmdSkipToOrder, CommandFlag::Location, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_DELETE_ORDER, CmdDeleteOrder, CommandFlag::Location, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_INSERT_ORDER, CmdInsertOrder, CommandFlag::Location, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_ORDER_REFIT, CmdOrderRefit, CommandFlag::Location, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_CLONE_ORDER, CmdCloneOrder, CommandFlag::Location, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_MOVE_ORDER, CmdMoveOrder, CommandFlag::Location, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_CLEAR_ORDER_BACKUP, CmdClearOrderBackup, CommandFlag::ClientID, CMDT_SERVER_SETTING) +DEF_CMD_TRAIT(CMD_MODIFY_ORDER, CmdModifyOrder, CommandFlag::Location, CommandType::RouteManagement) +DEF_CMD_TRAIT(CMD_SKIP_TO_ORDER, CmdSkipToOrder, CommandFlag::Location, CommandType::RouteManagement) +DEF_CMD_TRAIT(CMD_DELETE_ORDER, CmdDeleteOrder, CommandFlag::Location, CommandType::RouteManagement) +DEF_CMD_TRAIT(CMD_INSERT_ORDER, CmdInsertOrder, CommandFlag::Location, CommandType::RouteManagement) +DEF_CMD_TRAIT(CMD_ORDER_REFIT, CmdOrderRefit, CommandFlag::Location, CommandType::RouteManagement) +DEF_CMD_TRAIT(CMD_CLONE_ORDER, CmdCloneOrder, CommandFlag::Location, CommandType::RouteManagement) +DEF_CMD_TRAIT(CMD_MOVE_ORDER, CmdMoveOrder, CommandFlag::Location, CommandType::RouteManagement) +DEF_CMD_TRAIT(CMD_CLEAR_ORDER_BACKUP, CmdClearOrderBackup, CommandFlag::ClientID, CommandType::ServerSetting) template inline EndianBufferWriter &operator <<(EndianBufferWriter &buffer, const Order &order) diff --git a/src/rail_cmd.h b/src/rail_cmd.h index eb78df1d1c3a9..9ee4ccf2d46ce 100644 --- a/src/rail_cmd.h +++ b/src/rail_cmd.h @@ -27,16 +27,16 @@ CommandCost CmdConvertRail(DoCommandFlags flags, TileIndex tile, TileIndex area_ CommandCost CmdBuildSignalTrack(DoCommandFlags flags, TileIndex tile, TileIndex end_tile, Track track, SignalType sigtype, SignalVariant sigvar, bool mode, bool autofill, bool minimise_gaps, uint8_t signal_density); CommandCost CmdRemoveSignalTrack(DoCommandFlags flags, TileIndex tile, TileIndex end_tile, Track track, bool autofill); -DEF_CMD_TRAIT(CMD_BUILD_RAILROAD_TRACK, CmdBuildRailroadTrack, CommandFlags({CommandFlag::Auto, CommandFlag::NoWater}), CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_REMOVE_RAILROAD_TRACK, CmdRemoveRailroadTrack, CommandFlag::Auto, CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_BUILD_SINGLE_RAIL, CmdBuildSingleRail, CommandFlags({CommandFlag::Auto, CommandFlag::NoWater}), CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_REMOVE_SINGLE_RAIL, CmdRemoveSingleRail, CommandFlag::Auto, CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_BUILD_TRAIN_DEPOT, CmdBuildTrainDepot, CommandFlags({CommandFlag::Auto, CommandFlag::NoWater}), CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_BUILD_SINGLE_SIGNAL, CmdBuildSingleSignal, CommandFlag::Auto, CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_REMOVE_SINGLE_SIGNAL, CmdRemoveSingleSignal, CommandFlag::Auto, CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_CONVERT_RAIL, CmdConvertRail, {}, CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_BUILD_SIGNAL_TRACK, CmdBuildSignalTrack, CommandFlag::Auto, CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_REMOVE_SIGNAL_TRACK, CmdRemoveSignalTrack, CommandFlag::Auto, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_BUILD_RAILROAD_TRACK, CmdBuildRailroadTrack, CommandFlags({CommandFlag::Auto, CommandFlag::NoWater}), CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_REMOVE_RAILROAD_TRACK, CmdRemoveRailroadTrack, CommandFlag::Auto, CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_BUILD_SINGLE_RAIL, CmdBuildSingleRail, CommandFlags({CommandFlag::Auto, CommandFlag::NoWater}), CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_REMOVE_SINGLE_RAIL, CmdRemoveSingleRail, CommandFlag::Auto, CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_BUILD_TRAIN_DEPOT, CmdBuildTrainDepot, CommandFlags({CommandFlag::Auto, CommandFlag::NoWater}), CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_BUILD_SINGLE_SIGNAL, CmdBuildSingleSignal, CommandFlag::Auto, CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_REMOVE_SINGLE_SIGNAL, CmdRemoveSingleSignal, CommandFlag::Auto, CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_CONVERT_RAIL, CmdConvertRail, {}, CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_BUILD_SIGNAL_TRACK, CmdBuildSignalTrack, CommandFlag::Auto, CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_REMOVE_SIGNAL_TRACK, CmdRemoveSignalTrack, CommandFlag::Auto, CommandType::LandscapeConstruction) CommandCallback CcPlaySound_CONSTRUCTION_RAIL; CommandCallback CcStation; diff --git a/src/road_cmd.h b/src/road_cmd.h index 24b4c2b636873..e309edc057e16 100644 --- a/src/road_cmd.h +++ b/src/road_cmd.h @@ -27,11 +27,11 @@ CommandCost CmdBuildRoad(DoCommandFlags flags, TileIndex tile, RoadBits pieces, CommandCost CmdBuildRoadDepot(DoCommandFlags flags, TileIndex tile, RoadType rt, DiagDirection dir); CommandCost CmdConvertRoad(DoCommandFlags flags, TileIndex tile, TileIndex area_start, RoadType to_type, bool diagonal); -DEF_CMD_TRAIT(CMD_BUILD_LONG_ROAD, CmdBuildLongRoad, CommandFlags({CommandFlag::Auto, CommandFlag::NoWater, CommandFlag::Deity}), CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_REMOVE_LONG_ROAD, CmdRemoveLongRoad, CommandFlags({CommandFlag::Auto, CommandFlag::NoTest}), CMDT_LANDSCAPE_CONSTRUCTION) // towns may disallow removing road bits (as they are connected) in test, but in exec they're removed and thus removing is allowed. -DEF_CMD_TRAIT(CMD_BUILD_ROAD, CmdBuildRoad, CommandFlags({CommandFlag::Auto, CommandFlag::NoWater, CommandFlag::Deity}), CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_BUILD_ROAD_DEPOT, CmdBuildRoadDepot, CommandFlags({CommandFlag::Auto, CommandFlag::NoWater}), CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_CONVERT_ROAD, CmdConvertRoad, {}, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_BUILD_LONG_ROAD, CmdBuildLongRoad, CommandFlags({CommandFlag::Auto, CommandFlag::NoWater, CommandFlag::Deity}), CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_REMOVE_LONG_ROAD, CmdRemoveLongRoad, CommandFlags({CommandFlag::Auto, CommandFlag::NoTest}), CommandType::LandscapeConstruction) // towns may disallow removing road bits (as they are connected) in test, but in exec they're removed and thus removing is allowed. +DEF_CMD_TRAIT(CMD_BUILD_ROAD, CmdBuildRoad, CommandFlags({CommandFlag::Auto, CommandFlag::NoWater, CommandFlag::Deity}), CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_BUILD_ROAD_DEPOT, CmdBuildRoadDepot, CommandFlags({CommandFlag::Auto, CommandFlag::NoWater}), CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_CONVERT_ROAD, CmdConvertRoad, {}, CommandType::LandscapeConstruction) CommandCallback CcPlaySound_CONSTRUCTION_OTHER; CommandCallback CcBuildRoadTunnel; diff --git a/src/roadveh_cmd.h b/src/roadveh_cmd.h index ed9a7a11c510b..1fd781f8dddb9 100644 --- a/src/roadveh_cmd.h +++ b/src/roadveh_cmd.h @@ -22,6 +22,6 @@ CommandCost CmdBuildRoadVehicle(DoCommandFlags flags, TileIndex tile, const Engi CommandCost CmdTurnRoadVeh(DoCommandFlags flags, VehicleID veh_id); -DEF_CMD_TRAIT(CMD_TURN_ROADVEH, CmdTurnRoadVeh, CommandFlag::Location, CMDT_VEHICLE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_TURN_ROADVEH, CmdTurnRoadVeh, CommandFlag::Location, CommandType::VehicleManagement) #endif /* ROADVEH_CMD_H */ diff --git a/src/settings_cmd.h b/src/settings_cmd.h index 613fcfb42adfc..4210869eb97d9 100644 --- a/src/settings_cmd.h +++ b/src/settings_cmd.h @@ -15,7 +15,7 @@ CommandCost CmdChangeSetting(DoCommandFlags flags, const std::string &name, int32_t value); CommandCost CmdChangeCompanySetting(DoCommandFlags flags, const std::string &name, int32_t value); -DEF_CMD_TRAIT(CMD_CHANGE_SETTING, CmdChangeSetting, CommandFlags({CommandFlag::Server, CommandFlag::NoEst}), CMDT_SERVER_SETTING) -DEF_CMD_TRAIT(CMD_CHANGE_COMPANY_SETTING, CmdChangeCompanySetting, CommandFlag::NoEst, CMDT_COMPANY_SETTING) +DEF_CMD_TRAIT(CMD_CHANGE_SETTING, CmdChangeSetting, CommandFlags({CommandFlag::Server, CommandFlag::NoEst}), CommandType::ServerSetting) +DEF_CMD_TRAIT(CMD_CHANGE_COMPANY_SETTING, CmdChangeCompanySetting, CommandFlag::NoEst, CommandType::CompanySetting) #endif /* SETTINGS_CMD_H */ diff --git a/src/settings_type.h b/src/settings_type.h index ebbe874da0e77..25a8fd63dec3e 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -10,6 +10,7 @@ #ifndef SETTINGS_TYPE_H #define SETTINGS_TYPE_H +#include "command_type.h" #include "timer/timer_game_calendar.h" #include "economy_type.h" #include "town_type.h" @@ -410,7 +411,7 @@ struct ConstructionSettings { uint8_t industry_platform; ///< the amount of flat land around an industry bool freeform_edges; ///< allow terraforming the tiles at the map edges uint8_t extra_tree_placement; ///< (dis)allow building extra trees in-game - uint8_t command_pause_level; ///< level/amount of commands that can't be executed while paused + CommandPauseLevel command_pause_level; ///< level/amount of commands that can't be executed while paused uint32_t terraform_per_64k_frames; ///< how many tile heights may, over a long period, be terraformed per 65536 frames? uint16_t terraform_frame_burst; ///< how many tile heights may, over a short period, be terraformed? diff --git a/src/signs_cmd.h b/src/signs_cmd.h index 53b76091de4f4..3d8722b070065 100644 --- a/src/signs_cmd.h +++ b/src/signs_cmd.h @@ -16,8 +16,8 @@ std::tuple CmdPlaceSign(DoCommandFlags flags, TileIndex tile, const std::string &text); CommandCost CmdRenameSign(DoCommandFlags flags, SignID sign_id, const std::string &text); -DEF_CMD_TRAIT(CMD_PLACE_SIGN, CmdPlaceSign, CommandFlag::Deity, CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_RENAME_SIGN, CmdRenameSign, CommandFlag::Deity, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_PLACE_SIGN, CmdPlaceSign, CommandFlag::Deity, CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_RENAME_SIGN, CmdRenameSign, CommandFlag::Deity, CommandType::OtherManagement) void CcPlaceSign(Commands cmd, const CommandCost &result, SignID new_sign); diff --git a/src/station_cmd.h b/src/station_cmd.h index cd5c69b7fa382..38382cee27bd9 100644 --- a/src/station_cmd.h +++ b/src/station_cmd.h @@ -32,13 +32,13 @@ CommandCost CmdRemoveRoadStop(DoCommandFlags flags, TileIndex tile, uint8_t widt CommandCost CmdRenameStation(DoCommandFlags flags, StationID station_id, const std::string &text); CommandCost CmdOpenCloseAirport(DoCommandFlags flags, StationID station_id); -DEF_CMD_TRAIT(CMD_BUILD_AIRPORT, CmdBuildAirport, CommandFlags({CommandFlag::Auto, CommandFlag::NoWater}), CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_BUILD_DOCK, CmdBuildDock, CommandFlag::Auto, CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_BUILD_RAIL_STATION, CmdBuildRailStation, CommandFlags({CommandFlag::Auto, CommandFlag::NoWater}), CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_REMOVE_FROM_RAIL_STATION, CmdRemoveFromRailStation, {}, CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_BUILD_ROAD_STOP, CmdBuildRoadStop, CommandFlags({CommandFlag::Auto, CommandFlag::NoWater}), CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_REMOVE_ROAD_STOP, CmdRemoveRoadStop, {}, CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_RENAME_STATION, CmdRenameStation, {}, CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_OPEN_CLOSE_AIRPORT, CmdOpenCloseAirport, {}, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_BUILD_AIRPORT, CmdBuildAirport, CommandFlags({CommandFlag::Auto, CommandFlag::NoWater}), CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_BUILD_DOCK, CmdBuildDock, CommandFlag::Auto, CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_BUILD_RAIL_STATION, CmdBuildRailStation, CommandFlags({CommandFlag::Auto, CommandFlag::NoWater}), CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_REMOVE_FROM_RAIL_STATION, CmdRemoveFromRailStation, {}, CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_BUILD_ROAD_STOP, CmdBuildRoadStop, CommandFlags({CommandFlag::Auto, CommandFlag::NoWater}), CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_REMOVE_ROAD_STOP, CmdRemoveRoadStop, {}, CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_RENAME_STATION, CmdRenameStation, {}, CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_OPEN_CLOSE_AIRPORT, CmdOpenCloseAirport, {}, CommandType::RouteManagement) #endif /* STATION_CMD_H */ diff --git a/src/story_cmd.h b/src/story_cmd.h index 08075db05764e..c001675cbce5e 100644 --- a/src/story_cmd.h +++ b/src/story_cmd.h @@ -25,14 +25,14 @@ CommandCost CmdRemoveStoryPage(DoCommandFlags flags, StoryPageID page_id); CommandCost CmdRemoveStoryPageElement(DoCommandFlags flags, StoryPageElementID page_element_id); CommandCost CmdStoryPageButton(DoCommandFlags flags, TileIndex tile, StoryPageElementID page_element_id, VehicleID reference); -DEF_CMD_TRAIT(CMD_CREATE_STORY_PAGE, CmdCreateStoryPage, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_CREATE_STORY_PAGE_ELEMENT, CmdCreateStoryPageElement, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_UPDATE_STORY_PAGE_ELEMENT, CmdUpdateStoryPageElement, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_SET_STORY_PAGE_TITLE, CmdSetStoryPageTitle, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_SET_STORY_PAGE_DATE, CmdSetStoryPageDate, CommandFlag::Deity, CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_SHOW_STORY_PAGE, CmdShowStoryPage, CommandFlag::Deity, CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_REMOVE_STORY_PAGE, CmdRemoveStoryPage, CommandFlag::Deity, CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_REMOVE_STORY_PAGE_ELEMENT, CmdRemoveStoryPageElement, CommandFlag::Deity, CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_STORY_PAGE_BUTTON, CmdStoryPageButton, CommandFlag::Deity, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_CREATE_STORY_PAGE, CmdCreateStoryPage, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_CREATE_STORY_PAGE_ELEMENT, CmdCreateStoryPageElement, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_UPDATE_STORY_PAGE_ELEMENT, CmdUpdateStoryPageElement, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_SET_STORY_PAGE_TITLE, CmdSetStoryPageTitle, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_SET_STORY_PAGE_DATE, CmdSetStoryPageDate, CommandFlag::Deity, CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_SHOW_STORY_PAGE, CmdShowStoryPage, CommandFlag::Deity, CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_REMOVE_STORY_PAGE, CmdRemoveStoryPage, CommandFlag::Deity, CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_REMOVE_STORY_PAGE_ELEMENT, CmdRemoveStoryPageElement, CommandFlag::Deity, CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_STORY_PAGE_BUTTON, CmdStoryPageButton, CommandFlag::Deity, CommandType::OtherManagement) #endif /* STORY_CMD_H */ diff --git a/src/subsidy_cmd.h b/src/subsidy_cmd.h index a090774490fda..54eb2cfbbebc8 100644 --- a/src/subsidy_cmd.h +++ b/src/subsidy_cmd.h @@ -17,7 +17,7 @@ CommandCost CmdCreateSubsidy(DoCommandFlags flags, CargoType cargo_type, Source src, Source dst); -DEF_CMD_TRAIT(CMD_CREATE_SUBSIDY, CmdCreateSubsidy, CommandFlag::Deity, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_CREATE_SUBSIDY, CmdCreateSubsidy, CommandFlag::Deity, CommandType::OtherManagement) template diff --git a/src/terraform_cmd.h b/src/terraform_cmd.h index 8d4dea20d55fb..a4bfff5f99b44 100644 --- a/src/terraform_cmd.h +++ b/src/terraform_cmd.h @@ -17,8 +17,8 @@ std::tuple CmdTerraformLand(DoCommandFlags flags, TileIndex tile, Slope slope, bool dir_up); std::tuple CmdLevelLand(DoCommandFlags flags, TileIndex tile, TileIndex start_tile, bool diagonal, LevelMode lm); -DEF_CMD_TRAIT(CMD_TERRAFORM_LAND, CmdTerraformLand, CommandFlags({CommandFlag::AllTiles, CommandFlag::Auto}), CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_LEVEL_LAND, CmdLevelLand, CommandFlags({CommandFlag::AllTiles, CommandFlag::Auto, CommandFlag::NoTest}), CMDT_LANDSCAPE_CONSTRUCTION) // test run might clear tiles multiple times, in execution that only happens once +DEF_CMD_TRAIT(CMD_TERRAFORM_LAND, CmdTerraformLand, CommandFlags({CommandFlag::AllTiles, CommandFlag::Auto}), CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_LEVEL_LAND, CmdLevelLand, CommandFlags({CommandFlag::AllTiles, CommandFlag::Auto, CommandFlag::NoTest}), CommandType::LandscapeConstruction) // test run might clear tiles multiple times, in execution that only happens once CommandCallback CcPlaySound_EXPLOSION; void CcTerraform(Commands cmd, const CommandCost &result, Money, TileIndex tile); diff --git a/src/texteff.cpp b/src/texteff.cpp index 82f832e2ded33..36b7a35c231a0 100644 --- a/src/texteff.cpp +++ b/src/texteff.cpp @@ -90,7 +90,7 @@ void RemoveTextEffect(TextEffectID te_id) /** Slowly move text effects upwards. */ const IntervalTimer move_all_text_effects_interval = {std::chrono::milliseconds(30), [](uint count) { - if (_pause_mode.Any() && _game_mode != GM_EDITOR && _settings_game.construction.command_pause_level <= CMDPL_NO_CONSTRUCTION) return; + if (_pause_mode.Any() && _game_mode != GM_EDITOR && _settings_game.construction.command_pause_level <= CommandPauseLevel::NoConstruction) return; for (TextEffect &te : _text_effects) { if (!te.IsValid()) continue; diff --git a/src/timetable_cmd.h b/src/timetable_cmd.h index 221b394174059..45879234de730 100644 --- a/src/timetable_cmd.h +++ b/src/timetable_cmd.h @@ -21,10 +21,10 @@ CommandCost CmdSetVehicleOnTime(DoCommandFlags flags, VehicleID veh, bool apply_ CommandCost CmdAutofillTimetable(DoCommandFlags flags, VehicleID veh, bool autofill, bool preserve_wait_time); CommandCost CmdSetTimetableStart(DoCommandFlags flags, VehicleID veh_id, bool timetable_all, TimerGameTick::TickCounter start_tick); -DEF_CMD_TRAIT(CMD_CHANGE_TIMETABLE, CmdChangeTimetable, {}, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_BULK_CHANGE_TIMETABLE, CmdBulkChangeTimetable, {}, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_SET_VEHICLE_ON_TIME, CmdSetVehicleOnTime, {}, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_AUTOFILL_TIMETABLE, CmdAutofillTimetable, {}, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_SET_TIMETABLE_START, CmdSetTimetableStart, {}, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_CHANGE_TIMETABLE, CmdChangeTimetable, {}, CommandType::RouteManagement) +DEF_CMD_TRAIT(CMD_BULK_CHANGE_TIMETABLE, CmdBulkChangeTimetable, {}, CommandType::RouteManagement) +DEF_CMD_TRAIT(CMD_SET_VEHICLE_ON_TIME, CmdSetVehicleOnTime, {}, CommandType::RouteManagement) +DEF_CMD_TRAIT(CMD_AUTOFILL_TIMETABLE, CmdAutofillTimetable, {}, CommandType::RouteManagement) +DEF_CMD_TRAIT(CMD_SET_TIMETABLE_START, CmdSetTimetableStart, {}, CommandType::RouteManagement) #endif /* TIMETABLE_CMD_H */ diff --git a/src/town_cmd.h b/src/town_cmd.h index 7d247ce7cf452..2a9cce5092310 100644 --- a/src/town_cmd.h +++ b/src/town_cmd.h @@ -29,16 +29,16 @@ CommandCost CmdExpandTown(DoCommandFlags flags, TownID town_id, uint32_t grow_am CommandCost CmdDeleteTown(DoCommandFlags flags, TownID town_id); CommandCost CmdPlaceHouse(DoCommandFlags flags, TileIndex tile, HouseID house, bool house_protected); -DEF_CMD_TRAIT(CMD_FOUND_TOWN, CmdFoundTown, CommandFlags({CommandFlag::Deity, CommandFlag::NoTest}), CMDT_LANDSCAPE_CONSTRUCTION) // founding random town can fail only in exec run -DEF_CMD_TRAIT(CMD_RENAME_TOWN, CmdRenameTown, CommandFlags({CommandFlag::Deity, CommandFlag::Server}), CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_DO_TOWN_ACTION, CmdDoTownAction, CommandFlags({CommandFlag::Location}), CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_TOWN_CARGO_GOAL, CmdTownCargoGoal, CommandFlags({CommandFlag::Deity}), CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_TOWN_GROWTH_RATE, CmdTownGrowthRate, CommandFlags({CommandFlag::Deity}), CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_TOWN_RATING, CmdTownRating, CommandFlags({CommandFlag::Deity}), CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_TOWN_SET_TEXT, CmdTownSetText, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_EXPAND_TOWN, CmdExpandTown, CommandFlags({CommandFlag::Deity}), CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_DELETE_TOWN, CmdDeleteTown, CommandFlags({CommandFlag::Offline}), CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_PLACE_HOUSE, CmdPlaceHouse, CommandFlags({CommandFlag::Deity}), CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_FOUND_TOWN, CmdFoundTown, CommandFlags({CommandFlag::Deity, CommandFlag::NoTest}), CommandType::LandscapeConstruction) // founding random town can fail only in exec run +DEF_CMD_TRAIT(CMD_RENAME_TOWN, CmdRenameTown, CommandFlags({CommandFlag::Deity, CommandFlag::Server}), CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_DO_TOWN_ACTION, CmdDoTownAction, CommandFlags({CommandFlag::Location}), CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_TOWN_CARGO_GOAL, CmdTownCargoGoal, CommandFlags({CommandFlag::Deity}), CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_TOWN_GROWTH_RATE, CmdTownGrowthRate, CommandFlags({CommandFlag::Deity}), CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_TOWN_RATING, CmdTownRating, CommandFlags({CommandFlag::Deity}), CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_TOWN_SET_TEXT, CmdTownSetText, CommandFlags({CommandFlag::Deity, CommandFlag::StrCtrl}), CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_EXPAND_TOWN, CmdExpandTown, CommandFlags({CommandFlag::Deity}), CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_DELETE_TOWN, CmdDeleteTown, CommandFlags({CommandFlag::Offline}), CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_PLACE_HOUSE, CmdPlaceHouse, CommandFlags({CommandFlag::Deity}), CommandType::OtherManagement) CommandCallback CcFoundTown; void CcFoundRandomTown(Commands cmd, const CommandCost &result, Money, TownID town_id); diff --git a/src/train_cmd.h b/src/train_cmd.h index 45a7b5eff1bd9..e3c39aa6f60fa 100644 --- a/src/train_cmd.h +++ b/src/train_cmd.h @@ -22,9 +22,9 @@ CommandCost CmdMoveRailVehicle(DoCommandFlags flags, VehicleID src_veh, VehicleI CommandCost CmdForceTrainProceed(DoCommandFlags flags, VehicleID veh_id); CommandCost CmdReverseTrainDirection(DoCommandFlags flags, VehicleID veh_id, bool reverse_single_veh); -DEF_CMD_TRAIT(CMD_MOVE_RAIL_VEHICLE, CmdMoveRailVehicle, CommandFlag::Location, CMDT_VEHICLE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_FORCE_TRAIN_PROCEED, CmdForceTrainProceed, CommandFlag::Location, CMDT_VEHICLE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_REVERSE_TRAIN_DIRECTION, CmdReverseTrainDirection, CommandFlag::Location, CMDT_VEHICLE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_MOVE_RAIL_VEHICLE, CmdMoveRailVehicle, CommandFlag::Location, CommandType::VehicleConstruction) +DEF_CMD_TRAIT(CMD_FORCE_TRAIN_PROCEED, CmdForceTrainProceed, CommandFlag::Location, CommandType::VehicleManagement) +DEF_CMD_TRAIT(CMD_REVERSE_TRAIN_DIRECTION, CmdReverseTrainDirection, CommandFlag::Location, CommandType::VehicleManagement) void CcBuildWagon(Commands cmd, const CommandCost &result, VehicleID new_veh_id, uint, uint16_t, CargoArray, TileIndex tile, EngineID, bool, CargoType, ClientID); diff --git a/src/tree_cmd.h b/src/tree_cmd.h index 116d50c5f6eb8..65e1a310ad3c9 100644 --- a/src/tree_cmd.h +++ b/src/tree_cmd.h @@ -14,6 +14,6 @@ CommandCost CmdPlantTree(DoCommandFlags flags, TileIndex tile, TileIndex start_tile, uint8_t tree_to_plant, bool diagonal); -DEF_CMD_TRAIT(CMD_PLANT_TREE, CmdPlantTree, CommandFlag::Auto, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_PLANT_TREE, CmdPlantTree, CommandFlag::Auto, CommandType::LandscapeConstruction) #endif /* TREE_CMD_H */ diff --git a/src/tunnelbridge_cmd.h b/src/tunnelbridge_cmd.h index 25bd0cc2263ca..bf468d226285c 100644 --- a/src/tunnelbridge_cmd.h +++ b/src/tunnelbridge_cmd.h @@ -17,8 +17,8 @@ CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex tile_start, TransportType transport_type, BridgeType bridge_type, uint8_t road_rail_type); CommandCost CmdBuildTunnel(DoCommandFlags flags, TileIndex start_tile, TransportType transport_type, uint8_t road_rail_type); -DEF_CMD_TRAIT(CMD_BUILD_BRIDGE, CmdBuildBridge, CommandFlags({CommandFlag::Deity, CommandFlag::Auto, CommandFlag::NoWater}), CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_BUILD_TUNNEL, CmdBuildTunnel, CommandFlags({CommandFlag::Deity, CommandFlag::Auto}), CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_BUILD_BRIDGE, CmdBuildBridge, CommandFlags({CommandFlag::Deity, CommandFlag::Auto, CommandFlag::NoWater}), CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_BUILD_TUNNEL, CmdBuildTunnel, CommandFlags({CommandFlag::Deity, CommandFlag::Auto}), CommandType::LandscapeConstruction) void CcBuildBridge(Commands cmd, const CommandCost &result, TileIndex end_tile, TileIndex tile_start, TransportType transport_type, BridgeType, uint8_t); diff --git a/src/vehicle_cmd.h b/src/vehicle_cmd.h index 8f663673bc15f..b393a6a1f3ede 100644 --- a/src/vehicle_cmd.h +++ b/src/vehicle_cmd.h @@ -29,17 +29,17 @@ CommandCost CmdMassStartStopVehicle(DoCommandFlags flags, TileIndex tile, bool d CommandCost CmdDepotSellAllVehicles(DoCommandFlags flags, TileIndex tile, VehicleType vehicle_type); CommandCost CmdDepotMassAutoReplace(DoCommandFlags flags, TileIndex tile, VehicleType vehicle_type); -DEF_CMD_TRAIT(CMD_BUILD_VEHICLE, CmdBuildVehicle, CommandFlag::ClientID, CMDT_VEHICLE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_SELL_VEHICLE, CmdSellVehicle, CommandFlags({CommandFlag::ClientID, CommandFlag::Location}), CMDT_VEHICLE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_REFIT_VEHICLE, CmdRefitVehicle, CommandFlag::Location, CMDT_VEHICLE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_SEND_VEHICLE_TO_DEPOT, CmdSendVehicleToDepot, {}, CMDT_VEHICLE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_CHANGE_SERVICE_INT, CmdChangeServiceInt, {}, CMDT_VEHICLE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_RENAME_VEHICLE, CmdRenameVehicle, {}, CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_CLONE_VEHICLE, CmdCloneVehicle, CommandFlag::NoTest, CMDT_VEHICLE_CONSTRUCTION) // NewGRF callbacks influence building and refitting making it impossible to correctly estimate the cost -DEF_CMD_TRAIT(CMD_START_STOP_VEHICLE, CmdStartStopVehicle, CommandFlag::Location, CMDT_VEHICLE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_MASS_START_STOP, CmdMassStartStopVehicle, {}, CMDT_VEHICLE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_DEPOT_SELL_ALL_VEHICLES, CmdDepotSellAllVehicles, {}, CMDT_VEHICLE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_DEPOT_MASS_AUTOREPLACE, CmdDepotMassAutoReplace, {}, CMDT_VEHICLE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_BUILD_VEHICLE, CmdBuildVehicle, CommandFlag::ClientID, CommandType::VehicleConstruction) +DEF_CMD_TRAIT(CMD_SELL_VEHICLE, CmdSellVehicle, CommandFlags({CommandFlag::ClientID, CommandFlag::Location}), CommandType::VehicleConstruction) +DEF_CMD_TRAIT(CMD_REFIT_VEHICLE, CmdRefitVehicle, CommandFlag::Location, CommandType::VehicleConstruction) +DEF_CMD_TRAIT(CMD_SEND_VEHICLE_TO_DEPOT, CmdSendVehicleToDepot, {}, CommandType::VehicleManagement) +DEF_CMD_TRAIT(CMD_CHANGE_SERVICE_INT, CmdChangeServiceInt, {}, CommandType::VehicleManagement) +DEF_CMD_TRAIT(CMD_RENAME_VEHICLE, CmdRenameVehicle, {}, CommandType::OtherManagement) +DEF_CMD_TRAIT(CMD_CLONE_VEHICLE, CmdCloneVehicle, CommandFlag::NoTest, CommandType::VehicleConstruction) // NewGRF callbacks influence building and refitting making it impossible to correctly estimate the cost +DEF_CMD_TRAIT(CMD_START_STOP_VEHICLE, CmdStartStopVehicle, CommandFlag::Location, CommandType::VehicleManagement) +DEF_CMD_TRAIT(CMD_MASS_START_STOP, CmdMassStartStopVehicle, {}, CommandType::VehicleManagement) +DEF_CMD_TRAIT(CMD_DEPOT_SELL_ALL_VEHICLES, CmdDepotSellAllVehicles, {}, CommandType::VehicleConstruction) +DEF_CMD_TRAIT(CMD_DEPOT_MASS_AUTOREPLACE, CmdDepotMassAutoReplace, {}, CommandType::VehicleConstruction) void CcBuildPrimaryVehicle(Commands cmd, const CommandCost &result, VehicleID new_veh_id, uint, uint16_t, CargoArray); void CcStartStopVehicle(Commands cmd, const CommandCost &result, VehicleID veh_id, bool); diff --git a/src/viewport_cmd.h b/src/viewport_cmd.h index c50f9db1a7d46..b8d931f56173e 100644 --- a/src/viewport_cmd.h +++ b/src/viewport_cmd.h @@ -15,6 +15,6 @@ CommandCost CmdScrollViewport(DoCommandFlags flags, TileIndex tile, ViewportScrollTarget target, uint32_t ref); -DEF_CMD_TRAIT(CMD_SCROLL_VIEWPORT, CmdScrollViewport, CommandFlag::Deity, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_SCROLL_VIEWPORT, CmdScrollViewport, CommandFlag::Deity, CommandType::OtherManagement) #endif /* VIEWPORT_CMD_H */ diff --git a/src/water_cmd.h b/src/water_cmd.h index 56911695b152a..9193c5b1c4eaa 100644 --- a/src/water_cmd.h +++ b/src/water_cmd.h @@ -17,8 +17,8 @@ CommandCost CmdBuildShipDepot(DoCommandFlags flags, TileIndex tile, Axis axis); CommandCost CmdBuildCanal(DoCommandFlags flags, TileIndex tile, TileIndex start_tile, WaterClass wc, bool diagonal); CommandCost CmdBuildLock(DoCommandFlags flags, TileIndex tile); -DEF_CMD_TRAIT(CMD_BUILD_SHIP_DEPOT, CmdBuildShipDepot, CommandFlag::Auto, CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_BUILD_CANAL, CmdBuildCanal, CommandFlag::Auto, CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_BUILD_LOCK, CmdBuildLock, CommandFlag::Auto, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_BUILD_SHIP_DEPOT, CmdBuildShipDepot, CommandFlag::Auto, CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_BUILD_CANAL, CmdBuildCanal, CommandFlag::Auto, CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_BUILD_LOCK, CmdBuildLock, CommandFlag::Auto, CommandType::LandscapeConstruction) #endif /* WATER_CMD_H */ diff --git a/src/waypoint_cmd.h b/src/waypoint_cmd.h index e0aaf9853c530..2831c5c981395 100644 --- a/src/waypoint_cmd.h +++ b/src/waypoint_cmd.h @@ -23,11 +23,11 @@ CommandCost CmdRemoveFromRoadWaypoint(DoCommandFlags flags, TileIndex start, Til CommandCost CmdBuildBuoy(DoCommandFlags flags, TileIndex tile); CommandCost CmdRenameWaypoint(DoCommandFlags flags, StationID waypoint_id, const std::string &text); -DEF_CMD_TRAIT(CMD_BUILD_RAIL_WAYPOINT, CmdBuildRailWaypoint, {}, CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_REMOVE_FROM_RAIL_WAYPOINT, CmdRemoveFromRailWaypoint, {}, CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_BUILD_ROAD_WAYPOINT, CmdBuildRoadWaypoint, {}, CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_REMOVE_FROM_ROAD_WAYPOINT, CmdRemoveFromRoadWaypoint, {}, CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_BUILD_BUOY, CmdBuildBuoy, CommandFlag::Auto, CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_RENAME_WAYPOINT, CmdRenameWaypoint, {}, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_BUILD_RAIL_WAYPOINT, CmdBuildRailWaypoint, {}, CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_REMOVE_FROM_RAIL_WAYPOINT, CmdRemoveFromRailWaypoint, {}, CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_BUILD_ROAD_WAYPOINT, CmdBuildRoadWaypoint, {}, CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_REMOVE_FROM_ROAD_WAYPOINT, CmdRemoveFromRoadWaypoint, {}, CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_BUILD_BUOY, CmdBuildBuoy, CommandFlag::Auto, CommandType::LandscapeConstruction) +DEF_CMD_TRAIT(CMD_RENAME_WAYPOINT, CmdRenameWaypoint, {}, CommandType::OtherManagement) #endif /* WAYPOINT_CMD_H */ From 05c40a6e55c38a6426bc293b9def22677e42a52a Mon Sep 17 00:00:00 2001 From: Muxy Du Goulp Date: Sat, 15 Nov 2025 21:01:52 +0100 Subject: [PATCH 127/137] Fix #14777: authorized_key: Correctly target key type for add/remove The logic in ConNetworkAuthorizedKey for the `authorized_key` command was inverted. The check `if (StrEqualsIgnoreCase(type, name)) continue;` caused the action (add/remove) to be incorrectly executed on the first key type encountered that *did not* match the requested type, rather than the intended one. This resulted in keys specified for 'admin' being added to 'rcon', for example. This commit inverts the condition to ensure the action is performed only when the requested type matches the iterated key name. --- src/console_cmds.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index ffc6b1366536e..7b97fab118e43 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -2167,7 +2167,7 @@ static bool ConNetworkAuthorizedKey(std::span argv) } for (auto [name, authorized_keys] : _console_cmd_authorized_keys) { - if (StrEqualsIgnoreCase(type, name)) continue; + if (!StrEqualsIgnoreCase(type, name)) continue; PerformNetworkAuthorizedKeyAction(name, authorized_keys, action, authorized_key); return true; From 06d2f448916682d9904a477ec7230c375e6ad3b4 Mon Sep 17 00:00:00 2001 From: SamuXarick <43006711+SamuXarick@users.noreply.github.com> Date: Sat, 15 Nov 2025 21:40:36 +0000 Subject: [PATCH 128/137] Codechange: HighScore sorting to use std::vector (#14779) Replaces the fixed-size array for company sorting with a std::vector and updates sorting to use std::ranges::sort. This removes the need for manual count management. --- src/highscore.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/highscore.cpp b/src/highscore.cpp index 943edab559f71..e46a445c52d22 100644 --- a/src/highscore.cpp +++ b/src/highscore.cpp @@ -87,20 +87,19 @@ static bool HighScoreSorter(const Company * const &a, const Company * const &b) */ int8_t SaveHighScoreValueNetwork() { - const Company *cl[MAX_COMPANIES]; - size_t count = 0; + std::vector cl; int8_t local_company_place = -1; /* Sort all active companies with the highest score first */ - for (const Company *c : Company::Iterate()) cl[count++] = c; + for (const Company *c : Company::Iterate()) cl.push_back(c); - std::sort(std::begin(cl), std::begin(cl) + count, HighScoreSorter); + std::ranges::sort(cl, HighScoreSorter); /* Clear the high scores from the previous network game. */ auto &highscores = _highscore_table[SP_MULTIPLAYER]; std::fill(highscores.begin(), highscores.end(), HighScore{}); - for (size_t i = 0; i < count && i < highscores.size(); i++) { + for (size_t i = 0; i < cl.size() && i < highscores.size(); i++) { const Company *c = cl[i]; auto &highscore = highscores[i]; highscore.name = GetString(STR_HIGHSCORE_NAME, c->index, c->index); // get manager/company name string From 21329071dfb92d5bc3db23913687f739a8fae319 Mon Sep 17 00:00:00 2001 From: translators Date: Sun, 16 Nov 2025 04:40:12 +0000 Subject: [PATCH 129/137] Update: Translations from eints portuguese: 21 changes by jcteotonio --- src/lang/portuguese.txt | 42 ++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index 8c7ffb13bae69..d1c5d94cc7b12 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -619,7 +619,7 @@ STR_GRAPH_Y_LABEL_NUMBER :{TINY_FONT}{COM STR_GRAPH_OPERATING_PROFIT_CAPTION :{WHITE}Gráfico do Lucro Operacional STR_GRAPH_INCOME_CAPTION :{WHITE}Gráfico de Rendimentos STR_GRAPH_CARGO_DELIVERED_CAPTION :{WHITE}Unidades de carga entregues -STR_GRAPH_COMPANY_PERFORMANCE_RATINGS_CAPTION :{WHITE}Classificações do desempenho da empresa (máximo=1000) +STR_GRAPH_COMPANY_PERFORMANCE_RATINGS_CAPTION :{WHITE}Classificações do desempenho da empresa (máx. 1000) STR_GRAPH_COMPANY_VALUES_CAPTION :{WHITE}Gráfico de Valor da Empresa STR_GRAPH_LAST_24_MINUTES_TIME_LABEL :{TINY_FONT}{BLACK}Últimos 24 minutos @@ -636,7 +636,7 @@ STR_GRAPH_SELECT_SCALE :Alterar a escal STR_GRAPH_CARGO_PAYMENT_RATES_CAPTION :{WHITE}Tarifas por tipo de carga STR_GRAPH_CARGO_PAYMENT_RATES_DAYS :{TINY_FONT}{BLACK}Dias em trânsito STR_GRAPH_CARGO_PAYMENT_RATES_SECONDS :{TINY_FONT}{BLACK}Segundos em trânsito -STR_GRAPH_CARGO_PAYMENT_RATES_TITLE :{TINY_FONT}{BLACK}Pagamento por entregar 10 unidades (ou 10 000 litros) de carga numa distância de 20 quadrados +STR_GRAPH_CARGO_PAYMENT_RATES_TITLE :{TINY_FONT}{BLACK}Pagamento por entregar 10 unidades (ou 10 000 litros) de carga numa distância de 20 mosaicos STR_GRAPH_CARGO_ENABLE_ALL :{TINY_FONT}{BLACK}Todos STR_GRAPH_CARGO_DISABLE_ALL :{TINY_FONT}{BLACK}Nenhum STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL :{BLACK}Mostrar todas as cargas no gráfico @@ -1263,8 +1263,8 @@ STR_CONFIG_SETTING_RESTRICT_CATEGORY :Categoria: STR_CONFIG_SETTING_RESTRICT_TYPE :Tipo: STR_CONFIG_SETTING_RESTRICT_DROPDOWN_HELPTEXT :Restringe a lista abaixo para mostrar apenas opções modificadas STR_CONFIG_SETTING_RESTRICT_BASIC :Opções básicas (mostrar apenas definições importantes) -STR_CONFIG_SETTING_RESTRICT_ADVANCED :Avançado (mostra grande parte das definições) -STR_CONFIG_SETTING_RESTRICT_ALL :Avançado (mostrar todas as definições, incluindo as que são estranhas) +STR_CONFIG_SETTING_RESTRICT_ADVANCED :Avançada (mostra grande parte das definições) +STR_CONFIG_SETTING_RESTRICT_ALL :Especialista (mostrar todas as definições, incluindo as que são mais estranhas) STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_DEFAULT :Opções com um valor diferente das de origem STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_NEW :Preferências com um valor diferente das preferências para novos jogos @@ -1371,7 +1371,7 @@ STR_CONFIG_SETTING_AUTOSLOPE :Permitir desní STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Permite alteração de terra sob edifícios e vias sem os remover STR_CONFIG_SETTING_CATCHMENT :Dimensionamento mais realista de áreas de abrangência: {STRING} -STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Haver diferentes áreas de cobertura para diferentes tipos de estações e aeroportos +STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Para ter diferentes áreas de cobertura para diferentes tipos de estações e aeroportos STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Estações da empresa podem servir indústrias com estações neutras anexadas: {STRING} STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Quando ativo, indústrias com estações incluídas (com as Petrolíferas) podem ser servidas por estações-da-empresa construídas nas redondezas. Quando inativo, estas indústrias só podem ser servidas pela sua própria estação. Qualquer estação da empresa não poderá servir a indústria, nem a estação incluída pode servir outra entidade senão a própria indústria @@ -1459,7 +1459,7 @@ STR_CONFIG_SETTING_AUTOSCROLL :Deslocar janela STR_CONFIG_SETTING_AUTOSCROLL_HELPTEXT :Quando ativo, os visualizadores começam a deslocar-se logo que o rato esteja no extremo da janela ###length 4 STR_CONFIG_SETTING_AUTOSCROLL_DISABLED :Desativado -STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT_FULLSCREEN :Visualizador principal, só ecrã cheio +STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT_FULLSCREEN :Visualizador principal, só em ecrã inteiro STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT :Visualizador principal STR_CONFIG_SETTING_AUTOSCROLL_EVERY_VIEWPORT :Todos os visualizadores @@ -1489,7 +1489,7 @@ STR_CONFIG_SETTING_PLANE_SPEED :Fator de veloci STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Definir a velocidade relativa dos aviões em comparação com outros tipos de veículos, para reduzir o valor da receita do transporte por aeronave STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} -STR_CONFIG_SETTING_PLANE_CRASHES :Número de acidentes de aeronaves: {STRING} +STR_CONFIG_SETTING_PLANE_CRASHES :Quantidade de acidentes de aeronaves: {STRING} STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Indicar a hipótese da ocorrência de um acidente aéreo.{}* As aeronaves maiores tem um risco acrescido a despenhar quando aterram em aeroportos pequenos ###length 3 STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Nenhum* @@ -1560,7 +1560,7 @@ STR_CONFIG_SETTING_CARGO_SCALE_VALUE :{NUM}% STR_CONFIG_SETTING_AUTORENEW_VEHICLE :Renovar automaticamente os veículos quando estão a ficar velhos: {STRING} STR_CONFIG_SETTING_AUTORENEW_VEHICLE_HELPTEXT :Quando ativo, um veículo a chegar ao fim de vida é automaticamente substituído quando as condições de renovação estão reunidas -STR_CONFIG_SETTING_AUTORENEW_MONTHS :Renovar automaticamente quando um veículo chega a {STRING} a idade máxima +STR_CONFIG_SETTING_AUTORENEW_MONTHS :Renovar automaticamente quando um veículo chega a {STRING} da idade máxima STR_CONFIG_SETTING_AUTORENEW_MONTHS_HELPTEXT :Idade relativa a partir da qual um veículo deva ser indicado para a renovação automática ###length 2 STR_CONFIG_SETTING_AUTORENEW_MONTHS_VALUE_BEFORE :{COMMA} m{P 0 ês eses} antes @@ -1582,7 +1582,7 @@ STR_CONFIG_SETTING_POPULATION_IN_LABEL :Mostra populaç STR_CONFIG_SETTING_POPULATION_IN_LABEL_HELPTEXT :Mostrar a população das localidades na sua etiqueta no mapa STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS :Espessura das linhas dos gráficos estatísticos: {STRING} -STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Largura da linha nos gráficos. Uma linha mais estreita é de leitura mais precisa, enquanto uma linha mais espessa é mais fácil de ver e as cores distinguem-se melhor. +STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Largura da linha nos gráficos estatísticos. Uma linha mais estreita é de leitura mais precisa, enquanto uma linha mais espessa é mais fácil de ver e as cores distinguem-se melhor. STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Mostrar o nome do NewGRF na janela de compra de veículos: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Adiciona uma linha à janela de compra de veículos, mostrando a qual "NewGRF" pertence o veículo selecionado @@ -1601,11 +1601,11 @@ STR_CONFIG_SETTING_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis STR_CONFIG_SETTING_TERRAIN_TYPE :Tipo de terreno: {STRING} STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT :Escolher a altura das colinas e montanhas da paisagem -STR_CONFIG_SETTING_INDUSTRY_DENSITY :Densidade industrial: {STRING} +STR_CONFIG_SETTING_INDUSTRY_DENSITY :Nível de densidade industrial: {STRING} STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :Define quantas indústrias devem ser geradas e que nível deve ser mantido durante o jogo STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Distância máxima entre o limite do mapa e Refinarias de Petróleo: {STRING} -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Limite de distância entre a borda do mapa e o local de construção de refinarias e plataformas de petróleo. Em mapas de ilhas isto garante que elas fiquem perto da costa. Em mapas com mais de 256 quadrados esse valor é aumentado +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Limite de distância entre a borda do mapa e o local de construção de refinarias e plataformas de petróleo. Em mapas de ilhas isto garante que elas fiquem perto da costa. Em mapas com mais de 256 mosaicos esse valor é aumentado STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Altura da linha de neve: {STRING} STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Escolher a que altura a neve começa na paisagem subártica. A neve também afeta a geração de indústrias e os requisitos de crescimento das localidades. Só pode ser modificado através do Editor de Cenários ou é calculado através da "cobertura de neve" @@ -1657,11 +1657,11 @@ STR_CONFIG_SETTING_SE_FLAT_WORLD_HEIGHT :Altura com que STR_CONFIG_SETTING_EDGES_NOT_EMPTY :{WHITE}Um ou mais mosaicos no canto norte não estão vazios STR_CONFIG_SETTING_EDGES_NOT_WATER :{WHITE}Um ou mais mosaicos num dos cantos não têm água -STR_CONFIG_SETTING_STATION_SPREAD :Espalhamento das estações máximo: {STRING} -STR_CONFIG_SETTING_STATION_SPREAD_HELPTEXT :Área máxima pela qual uma estação pode estar distribuída. Nota que valores elevados irão abrandar o jogo +STR_CONFIG_SETTING_STATION_SPREAD :Máximo de distância de uma estação: {STRING} +STR_CONFIG_SETTING_STATION_SPREAD_HELPTEXT :Distância máxima pela qual uma estação pode estar distribuída. Nota que valores elevados irão abrandar o jogo STR_CONFIG_SETTING_SERVICEATHELIPAD :Manutenção automática de helicópteros em heliportos: {STRING} -STR_CONFIG_SETTING_SERVICEATHELIPAD_HELPTEXT :Efetuar manutenção aos helicópteros após cada aterragem, mesmo que não haja um hangar no aeroporto +STR_CONFIG_SETTING_SERVICEATHELIPAD_HELPTEXT :Efetuar manutenção aos helicópteros após cada aterragem, mesmo que não haja um hangar presente STR_CONFIG_SETTING_LINK_TERRAFORM_TOOLBAR :Ligar ferramentas de paisagem com as de construção: {STRING} STR_CONFIG_SETTING_LINK_TERRAFORM_TOOLBAR_HELPTEXT :Quando se abre a barra de construção para um tipo de transporte, abrir também a barra de terraplanagem @@ -1757,7 +1757,7 @@ STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_ISO :ISO (2008-12-31 STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME :Pausar automaticamente ao iniciar um novo jogo: {STRING} STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME_HELPTEXT :Quando ativo, o jogo ficará em pausa automaticamente num novo jogo, permitindo o estudo ao pormenor do mapa -STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL :Durante pausa permitir: {STRING} +STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL :Durante a pausa permitir: {STRING} STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_HELPTEXT :Selecionar que ações podem ser feitas enquanto o jogo está em pausa ###length 4 STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_NO_ACTIONS :Nenhuma ação @@ -1797,7 +1797,7 @@ STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION_HELPTEXT :Dar cores difer STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS :Deixar ferramentas de construção ativas depois de usadas: {STRING} STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS_HELPTEXT :Manter as ferramentas de construção de pontes, túneis, etc. abertas após uso -STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS :Remover automaticamente os sinais durante a construção de vias férreas: {STRING} +STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS :Remover automaticamente os sinais durante a construção de linhas ferroviárias: {STRING} STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS_HELPTEXT :Remova automaticamente os sinais durante a construção da ferrovia se os sinais estiverem no caminho. Isto pode potencialmente causar acidentes de comboio STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT :Limite de velocidade do avanço rápido: {STRING} @@ -1807,10 +1807,10 @@ STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT_VAL :{NUM}% velocida STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT_ZERO :Sem limite (tão rápido quanto o seu computador permitir) STR_CONFIG_SETTING_SOUND_TICKER :Notícias: {STRING} -STR_CONFIG_SETTING_SOUND_TICKER_HELPTEXT :Reproduzir efeito sonoro para notícias resumidas +STR_CONFIG_SETTING_SOUND_TICKER_HELPTEXT :Reproduzir um efeito sonoro para notícias resumidas STR_CONFIG_SETTING_SOUND_NEWS :Jornal: {STRING} -STR_CONFIG_SETTING_SOUND_NEWS_HELPTEXT :Reproduzir efeito sonoro ao mostrar um jornal +STR_CONFIG_SETTING_SOUND_NEWS_HELPTEXT :Reproduzir um efeito sonoro ao mostrar o jornal ###length 2 STR_CONFIG_SETTING_SOUND_NEW_YEAR :Fim do ano: {STRING} @@ -1821,7 +1821,7 @@ STR_CONFIG_SETTING_SOUND_NEW_YEAR_HELPTEXT :Reproduz um som STR_CONFIG_SETTING_SOUND_NEW_PERIOD_HELPTEXT :Reproduz um som no final do período e resume a performance da empresa desse período em comparação com a do período anterior STR_CONFIG_SETTING_SOUND_CONFIRM :Construção: {STRING} -STR_CONFIG_SETTING_SOUND_CONFIRM_HELPTEXT :Reproduzir efeito sonoro nas construções ou outras acções bem sucedidas +STR_CONFIG_SETTING_SOUND_CONFIRM_HELPTEXT :Reproduzir um efeito sonoro nas construções ou outras ações bem sucedidas STR_CONFIG_SETTING_SOUND_CLICK :Cliques de botões: {STRING} STR_CONFIG_SETTING_SOUND_CLICK_HELPTEXT :Reproduzir um bip quando botões são clicados @@ -2056,9 +2056,9 @@ STR_CONFIG_SETTING_SOFT_LIMIT_VALUE :{COMMA} STR_CONFIG_SETTING_SOFT_LIMIT_DISABLED :Desativado STR_CONFIG_SETTING_ZOOM_MIN :Nível máximo de ampliação: {STRING} -STR_CONFIG_SETTING_ZOOM_MIN_HELPTEXT :O nível máximo de zoom para visualizadores. Níveis máximos de zoom superiores aumenterão os requisitos de memória +STR_CONFIG_SETTING_ZOOM_MIN_HELPTEXT :O nível máximo de ampliação para visualizadores. Níveis máximos de ampliação superiores aumentarão os requisitos de memória do jogo STR_CONFIG_SETTING_ZOOM_MAX :Nível máximo de redução da câmara: {STRING} -STR_CONFIG_SETTING_ZOOM_MAX_HELPTEXT :O nível mínimo de zoom para visualizadores. Níveis mínimos de zoom superiores poderão causar lag quando utilizados +STR_CONFIG_SETTING_ZOOM_MAX_HELPTEXT :O nível mínimo de ampliação para visualizadores. Níveis mínimos de ampliação superiores poderão causar atrasos na execução do jogo quando utilizados ###length 6 STR_CONFIG_SETTING_ZOOM_LVL_MIN :4x STR_CONFIG_SETTING_ZOOM_LVL_IN_2X :2x From 438ac2846f69fbd7989abbcfa55b76d9cf1735f4 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 26 Sep 2025 19:33:37 +0100 Subject: [PATCH 130/137] Codechange: Pass rail and roadtypes separate for tunnel and bridge commands. Avoids passing each via an unrelated type. --- src/bridge_gui.cpp | 28 +++++++++++++++------------- src/dock_gui.cpp | 2 +- src/gui.h | 4 +++- src/rail_gui.cpp | 6 +++--- src/road_gui.cpp | 6 +++--- src/script/api/script_bridge.cpp | 6 +++--- src/script/api/script_tunnel.cpp | 4 ++-- src/town_cmd.cpp | 8 ++++---- src/tunnelbridge_cmd.cpp | 13 ++----------- src/tunnelbridge_cmd.h | 10 ++++++---- 10 files changed, 42 insertions(+), 45 deletions(-) diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp index ca4cc5161ce40..f27cd65fe3242 100644 --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.cpp @@ -54,7 +54,7 @@ typedef GUIList GUIBridgeList; ///< List of bridges, used in #B * @param tile_start start tile * @param transport_type transport type. */ -void CcBuildBridge(Commands, const CommandCost &result, TileIndex end_tile, TileIndex tile_start, TransportType transport_type, BridgeType, uint8_t) +void CcBuildBridge(Commands, const CommandCost &result, TileIndex end_tile, TileIndex tile_start, TransportType transport_type, BridgeType, RailType, RoadType) { if (result.Failed()) return; if (_settings_client.sound.confirm) SndPlayTileFx(SND_27_CONSTRUCTION_BRIDGE, end_tile); @@ -86,7 +86,8 @@ class BuildBridgeWindow : public Window { TileIndex start_tile = INVALID_TILE; TileIndex end_tile = INVALID_TILE; TransportType transport_type = INVALID_TRANSPORT; - uint8_t road_rail_type = 0; + RailType railtype = INVALID_RAILTYPE; + RoadType roadtype = INVALID_ROADTYPE; GUIBridgeList bridges{}; int icon_width = 0; ///< Scaled width of the the bridge icon sprite. Scrollbar *vscroll = nullptr; @@ -117,7 +118,7 @@ class BuildBridgeWindow : public Window { default: break; } Command::Post(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, CcBuildBridge, - this->end_tile, this->start_tile, this->transport_type, type, this->road_rail_type); + this->end_tile, this->start_tile, this->transport_type, type, this->railtype, this->roadtype); } /** Sort the builable bridges */ @@ -154,11 +155,12 @@ class BuildBridgeWindow : public Window { } public: - BuildBridgeWindow(WindowDesc &desc, TileIndex start, TileIndex end, TransportType transport_type, uint8_t road_rail_type, GUIBridgeList &&bl) : Window(desc), + BuildBridgeWindow(WindowDesc &desc, TileIndex start, TileIndex end, TransportType transport_type, RailType railtype, RoadType roadtype, GUIBridgeList &&bl) : Window(desc), start_tile(start), end_tile(end), transport_type(transport_type), - road_rail_type(road_rail_type), + railtype(railtype), + roadtype(roadtype), bridges(std::move(bl)) { this->CreateNestedTree(); @@ -354,7 +356,7 @@ static WindowDesc _build_bridge_desc( * @param transport_type The transport type * @param road_rail_type The road/rail type */ -void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, uint8_t road_rail_type) +void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, RailType railtype, RoadType roadtype) { CloseWindowByClass(WC_BUILD_BRIDGE); @@ -373,13 +375,13 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo default: break; // water ways and air routes don't have bridge types } if (_ctrl_pressed && CheckBridgeAvailability(last_bridge_type, bridge_len).Succeeded()) { - Command::Post(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, CcBuildBridge, end, start, transport_type, last_bridge_type, road_rail_type); + Command::Post(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE, CcBuildBridge, end, start, transport_type, last_bridge_type, railtype, roadtype); return; } /* only query bridge building possibility once, result is the same for all bridges! * returns CMD_ERROR on failure, and price on success */ - CommandCost ret = Command::Do(CommandFlagsToDCFlags(GetCommandFlags()) | DoCommandFlag::QueryCost, end, start, transport_type, 0, road_rail_type); + CommandCost ret = Command::Do(CommandFlagsToDCFlags(GetCommandFlags()) | DoCommandFlag::QueryCost, end, start, transport_type, 0, railtype, roadtype); GUIBridgeList bl; if (!ret.Failed()) { @@ -396,10 +398,10 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo road_rt = GetRoadTypeRoad(start); tram_rt = GetRoadTypeTram(start); } - if (RoadTypeIsRoad((RoadType)road_rail_type)) { - road_rt = (RoadType)road_rail_type; + if (RoadTypeIsRoad(roadtype)) { + road_rt = roadtype; } else { - tram_rt = (RoadType)road_rail_type; + tram_rt = roadtype; } if (road_rt != INVALID_ROADTYPE) infra_cost += (bridge_len + 2) * 2 * RoadBuildCost(road_rt); @@ -407,7 +409,7 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo break; } - case TRANSPORT_RAIL: infra_cost = (bridge_len + 2) * RailBuildCost((RailType)road_rail_type); break; + case TRANSPORT_RAIL: infra_cost = (bridge_len + 2) * RailBuildCost(railtype); break; default: break; } @@ -432,7 +434,7 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo } if (!bl.empty()) { - new BuildBridgeWindow(_build_bridge_desc, start, end, transport_type, road_rail_type, std::move(bl)); + new BuildBridgeWindow(_build_bridge_desc, start, end, transport_type, railtype, roadtype, std::move(bl)); } else { ShowErrorMessage(GetEncodedString(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE), TileX(end) * TILE_SIZE, TileY(end) * TILE_SIZE, ret); } diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index eea54f16e3477..82aec53970eb5 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -238,7 +238,7 @@ struct BuildDocksToolbarWindow : Window { break; case WID_DT_BUILD_AQUEDUCT: // Build aqueduct button - Command::Post(STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE, CcBuildBridge, tile, GetOtherAqueductEnd(tile), TRANSPORT_WATER, 0, 0); + Command::Post(STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE, CcBuildBridge, tile, GetOtherAqueductEnd(tile), TRANSPORT_WATER, 0, INVALID_RAILTYPE, INVALID_ROADTYPE); break; default: NOT_REACHED(); diff --git a/src/gui.h b/src/gui.h index 5cfded5c8f3a7..9c38a02e9db16 100644 --- a/src/gui.h +++ b/src/gui.h @@ -10,6 +10,8 @@ #ifndef GUI_H #define GUI_H +#include "rail_type.h" +#include "road_type.h" #include "strings_type.h" #include "vehicle_type.h" #include "economy_type.h" @@ -72,7 +74,7 @@ void ShowExtraViewportWindow(TileIndex tile = INVALID_TILE); void ShowExtraViewportWindowForTileUnderCursor(); /* bridge_gui.cpp */ -void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, uint8_t bridge_type); +void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, RailType railtype, RoadType roadtype); /* music_gui.cpp */ void ShowMusicWindow(); diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 5cbb9de22095c..15bc67e6d1adc 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -709,7 +709,7 @@ struct BuildRailToolbarWindow : Window { break; case WID_RAT_BUILD_TUNNEL: - Command::Post(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRailTunnel, tile, TRANSPORT_RAIL, _cur_railtype); + Command::Post(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRailTunnel, tile, TRANSPORT_RAIL, _cur_railtype, INVALID_ROADTYPE); break; case WID_RAT_CONVERT_RAIL: @@ -740,7 +740,7 @@ struct BuildRailToolbarWindow : Window { default: NOT_REACHED(); case DDSP_BUILD_BRIDGE: if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); - ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_RAIL, _cur_railtype); + ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_RAIL, _cur_railtype, INVALID_ROADTYPE); break; case DDSP_PLACE_RAIL: @@ -814,7 +814,7 @@ struct BuildRailToolbarWindow : Window { void OnPlacePresize([[maybe_unused]] Point pt, TileIndex tile) override { - Command::Do(DoCommandFlag::Auto, tile, TRANSPORT_RAIL, _cur_railtype); + Command::Do(DoCommandFlag::Auto, tile, TRANSPORT_RAIL, _cur_railtype, INVALID_ROADTYPE); VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile); } diff --git a/src/road_gui.cpp b/src/road_gui.cpp index aecfc9c8cdc3b..f8fe8d3c5e0c5 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -653,7 +653,7 @@ struct BuildRoadToolbarWindow : Window { case WID_ROT_BUILD_TUNNEL: Command::Post(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE, CcBuildRoadTunnel, - tile, TRANSPORT_ROAD, _cur_roadtype); + tile, TRANSPORT_ROAD, INVALID_RAILTYPE, _cur_roadtype); break; case WID_ROT_CONVERT_ROAD: @@ -736,7 +736,7 @@ struct BuildRoadToolbarWindow : Window { default: NOT_REACHED(); case DDSP_BUILD_BRIDGE: if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); - ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_ROAD, _cur_roadtype); + ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_ROAD, INVALID_RAILTYPE, _cur_roadtype); break; case DDSP_DEMOLISH_AREA: @@ -818,7 +818,7 @@ struct BuildRoadToolbarWindow : Window { void OnPlacePresize([[maybe_unused]] Point pt, TileIndex tile) override { - Command::Do(DoCommandFlag::Auto, tile, TRANSPORT_ROAD, _cur_roadtype); + Command::Do(DoCommandFlag::Auto, tile, TRANSPORT_ROAD, INVALID_RAILTYPE, _cur_roadtype); VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile); } diff --git a/src/script/api/script_bridge.cpp b/src/script/api/script_bridge.cpp index f96aaca887f0e..a5b71eee6c376 100644 --- a/src/script/api/script_bridge.cpp +++ b/src/script/api/script_bridge.cpp @@ -86,11 +86,11 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance &instance) case ScriptVehicle::VT_ROAD: ScriptObject::SetCallbackVariable(0, start.base()); ScriptObject::SetCallbackVariable(1, end.base()); - return ScriptObject::Command::Do(&::_DoCommandReturnBuildBridge1, end, start, TRANSPORT_ROAD, bridge_type, ScriptRoad::GetCurrentRoadType()); + return ScriptObject::Command::Do(&::_DoCommandReturnBuildBridge1, end, start, TRANSPORT_ROAD, bridge_type, INVALID_RAILTYPE, static_cast<::RoadType>(ScriptRoad::GetCurrentRoadType())); case ScriptVehicle::VT_RAIL: - return ScriptObject::Command::Do(end, start, TRANSPORT_RAIL, bridge_type, ScriptRail::GetCurrentRailType()); + return ScriptObject::Command::Do(end, start, TRANSPORT_RAIL, bridge_type, static_cast<::RailType>(ScriptRail::GetCurrentRailType()), INVALID_ROADTYPE); case ScriptVehicle::VT_WATER: - return ScriptObject::Command::Do(end, start, TRANSPORT_WATER, bridge_type, 0); + return ScriptObject::Command::Do(end, start, TRANSPORT_WATER, bridge_type, INVALID_RAILTYPE, INVALID_ROADTYPE); default: NOT_REACHED(); } } diff --git a/src/script/api/script_tunnel.cpp b/src/script/api/script_tunnel.cpp index ce7877dd8a561..06c3a8dfdc016 100644 --- a/src/script/api/script_tunnel.cpp +++ b/src/script/api/script_tunnel.cpp @@ -90,10 +90,10 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance &instance) if (vehicle_type == ScriptVehicle::VT_RAIL) { /* For rail we do nothing special */ - return ScriptObject::Command::Do(start, TRANSPORT_RAIL, ScriptRail::GetCurrentRailType()); + return ScriptObject::Command::Do(start, TRANSPORT_RAIL, static_cast<::RailType>(ScriptRail::GetCurrentRailType()), INVALID_ROADTYPE); } else { ScriptObject::SetCallbackVariable(0, start.base()); - return ScriptObject::Command::Do(&::_DoCommandReturnBuildTunnel1, start, TRANSPORT_ROAD, ScriptRoad::GetCurrentRoadType()); + return ScriptObject::Command::Do(&::_DoCommandReturnBuildTunnel1, start, TRANSPORT_ROAD, INVALID_RAILTYPE, static_cast<::RoadType>(ScriptRoad::GetCurrentRoadType())); } } diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 60cde52c29f35..6d2273115e30d 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -1377,8 +1377,8 @@ static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDi /* Can we actually build the bridge? */ RoadType rt = GetTownRoadType(); - if (Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt).Succeeded()) { - Command::Do(CommandFlagsToDCFlags(GetCommandFlags()).Set(DoCommandFlag::Execute), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt); + if (Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, INVALID_RAILTYPE, rt).Succeeded()) { + Command::Do(CommandFlagsToDCFlags(GetCommandFlags()).Set(DoCommandFlag::Execute), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, INVALID_RAILTYPE, rt); return true; } } @@ -1447,8 +1447,8 @@ static bool GrowTownWithTunnel(const Town *t, const TileIndex tile, const DiagDi /* Attempt to build the tunnel. Return false if it fails to let the town build a road instead. */ RoadType rt = GetTownRoadType(); - if (Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), tile, TRANSPORT_ROAD, rt).Succeeded()) { - Command::Do(CommandFlagsToDCFlags(GetCommandFlags()).Set(DoCommandFlag::Execute), tile, TRANSPORT_ROAD, rt); + if (Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), tile, TRANSPORT_ROAD, INVALID_RAILTYPE, rt).Succeeded()) { + Command::Do(CommandFlagsToDCFlags(GetCommandFlags()).Set(DoCommandFlag::Execute), tile, TRANSPORT_ROAD, INVALID_RAILTYPE, rt); return true; } diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 00138c1957675..74f277af7964f 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -307,24 +307,19 @@ static CommandCost CheckBuildAbove(TileIndex tile, DoCommandFlags flags, Axis ax * @param road_rail_type rail type or road types. * @return the cost of this operation or an error */ -CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex tile_start, TransportType transport_type, BridgeType bridge_type, uint8_t road_rail_type) +CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex tile_start, TransportType transport_type, BridgeType bridge_type, RailType railtype, RoadType roadtype) { CompanyID company = _current_company; - RailType railtype = INVALID_RAILTYPE; - RoadType roadtype = INVALID_ROADTYPE; - if (!IsValidTile(tile_start)) return CommandCost(STR_ERROR_BRIDGE_THROUGH_MAP_BORDER); /* type of bridge */ switch (transport_type) { case TRANSPORT_ROAD: - roadtype = (RoadType)road_rail_type; if (!ValParamRoadType(roadtype)) return CMD_ERROR; break; case TRANSPORT_RAIL: - railtype = (RailType)road_rail_type; if (!ValParamRailType(railtype)) return CMD_ERROR; break; @@ -639,21 +634,17 @@ CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex t * @param road_rail_type railtype or roadtype * @return the cost of this operation or an error */ -CommandCost CmdBuildTunnel(DoCommandFlags flags, TileIndex start_tile, TransportType transport_type, uint8_t road_rail_type) +CommandCost CmdBuildTunnel(DoCommandFlags flags, TileIndex start_tile, TransportType transport_type, RailType railtype, RoadType roadtype) { CompanyID company = _current_company; - RailType railtype = INVALID_RAILTYPE; - RoadType roadtype = INVALID_ROADTYPE; _build_tunnel_endtile = TileIndex{}; switch (transport_type) { case TRANSPORT_RAIL: - railtype = (RailType)road_rail_type; if (!ValParamRailType(railtype)) return CMD_ERROR; break; case TRANSPORT_ROAD: - roadtype = (RoadType)road_rail_type; if (!ValParamRoadType(roadtype)) return CMD_ERROR; break; diff --git a/src/tunnelbridge_cmd.h b/src/tunnelbridge_cmd.h index bf468d226285c..460da8f90dd23 100644 --- a/src/tunnelbridge_cmd.h +++ b/src/tunnelbridge_cmd.h @@ -10,16 +10,18 @@ #ifndef TUNNELBRIDGE_CMD_H #define TUNNELBRIDGE_CMD_H +#include "bridge_type.h" #include "command_type.h" +#include "rail_type.h" +#include "road_type.h" #include "transport_type.h" -#include "bridge.h" -CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex tile_start, TransportType transport_type, BridgeType bridge_type, uint8_t road_rail_type); -CommandCost CmdBuildTunnel(DoCommandFlags flags, TileIndex start_tile, TransportType transport_type, uint8_t road_rail_type); +CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex tile_start, TransportType transport_type, BridgeType bridge_type, RailType railtype, RoadType roadtype); +CommandCost CmdBuildTunnel(DoCommandFlags flags, TileIndex start_tile, TransportType transport_type, RailType railtype, RoadType roadtype); DEF_CMD_TRAIT(CMD_BUILD_BRIDGE, CmdBuildBridge, CommandFlags({CommandFlag::Deity, CommandFlag::Auto, CommandFlag::NoWater}), CommandType::LandscapeConstruction) DEF_CMD_TRAIT(CMD_BUILD_TUNNEL, CmdBuildTunnel, CommandFlags({CommandFlag::Deity, CommandFlag::Auto}), CommandType::LandscapeConstruction) -void CcBuildBridge(Commands cmd, const CommandCost &result, TileIndex end_tile, TileIndex tile_start, TransportType transport_type, BridgeType, uint8_t); +void CcBuildBridge(Commands cmd, const CommandCost &result, TileIndex end_tile, TileIndex tile_start, TransportType transport_type, BridgeType, RailType railtype, RoadType roadtype); #endif /* TUNNELBRIDGE_CMD_H */ From 832abe34f84f3abde73d08e5e83a87f5449c4352 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 7 Sep 2025 14:22:37 +0100 Subject: [PATCH 131/137] Codechange: Pass rail/road info by reference when resolving GUI sprites. --- src/rail_cmd.cpp | 46 +++++++++++++++++++++++----------------------- src/road_cmd.cpp | 30 +++++++++++++++--------------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index e2ee0b781be15..455424b33583b 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -72,26 +72,26 @@ void ResetRailTypes() _railtypes_hidden_mask = {}; } -void ResolveRailTypeGUISprites(RailTypeInfo *rti) +static void ResolveRailTypeGUISprites(RailTypeInfo &rti) { - SpriteID cursors_base = GetCustomRailSprite(rti, INVALID_TILE, RTSG_CURSORS); + SpriteID cursors_base = GetCustomRailSprite(&rti, INVALID_TILE, RTSG_CURSORS); if (cursors_base != 0) { - rti->gui_sprites.build_ns_rail = cursors_base + 0; - rti->gui_sprites.build_x_rail = cursors_base + 1; - rti->gui_sprites.build_ew_rail = cursors_base + 2; - rti->gui_sprites.build_y_rail = cursors_base + 3; - rti->gui_sprites.auto_rail = cursors_base + 4; - rti->gui_sprites.build_depot = cursors_base + 5; - rti->gui_sprites.build_tunnel = cursors_base + 6; - rti->gui_sprites.convert_rail = cursors_base + 7; - rti->cursor.rail_ns = cursors_base + 8; - rti->cursor.rail_swne = cursors_base + 9; - rti->cursor.rail_ew = cursors_base + 10; - rti->cursor.rail_nwse = cursors_base + 11; - rti->cursor.autorail = cursors_base + 12; - rti->cursor.depot = cursors_base + 13; - rti->cursor.tunnel = cursors_base + 14; - rti->cursor.convert = cursors_base + 15; + rti.gui_sprites.build_ns_rail = cursors_base + 0; + rti.gui_sprites.build_x_rail = cursors_base + 1; + rti.gui_sprites.build_ew_rail = cursors_base + 2; + rti.gui_sprites.build_y_rail = cursors_base + 3; + rti.gui_sprites.auto_rail = cursors_base + 4; + rti.gui_sprites.build_depot = cursors_base + 5; + rti.gui_sprites.build_tunnel = cursors_base + 6; + rti.gui_sprites.convert_rail = cursors_base + 7; + rti.cursor.rail_ns = cursors_base + 8; + rti.cursor.rail_swne = cursors_base + 9; + rti.cursor.rail_ew = cursors_base + 10; + rti.cursor.rail_nwse = cursors_base + 11; + rti.cursor.autorail = cursors_base + 12; + rti.cursor.depot = cursors_base + 13; + rti.cursor.tunnel = cursors_base + 14; + rti.cursor.convert = cursors_base + 15; } /* Array of default GUI signal sprite numbers. */ @@ -105,10 +105,10 @@ void ResolveRailTypeGUISprites(RailTypeInfo *rti) for (SignalType type = SIGTYPE_BLOCK; type < SIGTYPE_END; type = (SignalType)(type + 1)) { for (SignalVariant var = SIG_ELECTRIC; var <= SIG_SEMAPHORE; var = (SignalVariant)(var + 1)) { - SpriteID red = GetCustomSignalSprite(rti, INVALID_TILE, type, var, SIGNAL_STATE_RED, true); - SpriteID green = GetCustomSignalSprite(rti, INVALID_TILE, type, var, SIGNAL_STATE_GREEN, true); - rti->gui_sprites.signals[type][var][0] = (red != 0) ? red + SIGNAL_TO_SOUTH : _signal_lookup[var][type]; - rti->gui_sprites.signals[type][var][1] = (green != 0) ? green + SIGNAL_TO_SOUTH : _signal_lookup[var][type] + 1; + SpriteID red = GetCustomSignalSprite(&rti, INVALID_TILE, type, var, SIGNAL_STATE_RED, true); + SpriteID green = GetCustomSignalSprite(&rti, INVALID_TILE, type, var, SIGNAL_STATE_GREEN, true); + rti.gui_sprites.signals[type][var][0] = (red != 0) ? red + SIGNAL_TO_SOUTH : _signal_lookup[var][type]; + rti.gui_sprites.signals[type][var][1] = (green != 0) ? green + SIGNAL_TO_SOUTH : _signal_lookup[var][type] + 1; } } } @@ -133,7 +133,7 @@ void InitRailTypes() for (RailTypeInfo &rti : _railtypes) { RailType rt = rti.Index(); - ResolveRailTypeGUISprites(&rti); + ResolveRailTypeGUISprites(rti); _railtypes_hidden_mask.Set(rt, rti.flags.Test(RailTypeFlag::Hidden)); if (rti.label == 0) continue; diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 4b5d93682dd92..694f7f639d99e 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -72,22 +72,22 @@ void ResetRoadTypes() _roadtypes_tram = {ROADTYPE_TRAM}; } -void ResolveRoadTypeGUISprites(RoadTypeInfo *rti) +static void ResolveRoadTypeGUISprites(RoadTypeInfo &rti) { - SpriteID cursors_base = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_CURSORS); + SpriteID cursors_base = GetCustomRoadSprite(&rti, INVALID_TILE, ROTSG_CURSORS); if (cursors_base != 0) { - rti->gui_sprites.build_y_road = cursors_base + 0; - rti->gui_sprites.build_x_road = cursors_base + 1; - rti->gui_sprites.auto_road = cursors_base + 2; - rti->gui_sprites.build_depot = cursors_base + 3; - rti->gui_sprites.build_tunnel = cursors_base + 4; - rti->gui_sprites.convert_road = cursors_base + 5; - rti->cursor.road_swne = cursors_base + 6; - rti->cursor.road_nwse = cursors_base + 7; - rti->cursor.autoroad = cursors_base + 8; - rti->cursor.depot = cursors_base + 9; - rti->cursor.tunnel = cursors_base + 10; - rti->cursor.convert_road = cursors_base + 11; + rti.gui_sprites.build_y_road = cursors_base + 0; + rti.gui_sprites.build_x_road = cursors_base + 1; + rti.gui_sprites.auto_road = cursors_base + 2; + rti.gui_sprites.build_depot = cursors_base + 3; + rti.gui_sprites.build_tunnel = cursors_base + 4; + rti.gui_sprites.convert_road = cursors_base + 5; + rti.cursor.road_swne = cursors_base + 6; + rti.cursor.road_nwse = cursors_base + 7; + rti.cursor.autoroad = cursors_base + 8; + rti.cursor.depot = cursors_base + 9; + rti.cursor.tunnel = cursors_base + 10; + rti.cursor.convert_road = cursors_base + 11; } } @@ -114,7 +114,7 @@ void InitRoadTypes() for (RoadTypeInfo &rti : _roadtypes) { RoadType rt = rti.Index(); - ResolveRoadTypeGUISprites(&rti); + ResolveRoadTypeGUISprites(rti); _roadtypes_hidden_mask.Set(rt, rti.flags.Test(RoadTypeFlag::Hidden)); if (rti.label == 0) continue; From 1d094970c8ece4a489130674d6d4d3aef574cf62 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 7 Sep 2025 14:15:47 +0100 Subject: [PATCH 132/137] Codechange: Use iteration to set up date-introduced rail/road types. --- src/rail.cpp | 14 +++++++------- src/road.cpp | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/rail.cpp b/src/rail.cpp index b977c1c9631d1..3d949d6bb1cca 100644 --- a/src/rail.cpp +++ b/src/rail.cpp @@ -101,24 +101,24 @@ bool ValParamRailType(const RailType rail) */ RailTypes AddDateIntroducedRailTypes(RailTypes current, TimerGameCalendar::Date date) { + extern RailTypeInfo _railtypes[RAILTYPE_END]; RailTypes rts = current; - for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { - const RailTypeInfo *rti = GetRailTypeInfo(rt); + for (RailTypeInfo &rti : _railtypes) { /* Unused rail type. */ - if (rti->label == 0) continue; + if (rti.label == 0) continue; /* Not date introduced. */ - if (!IsInsideMM(rti->introduction_date, 0, CalendarTime::MAX_DATE.base())) continue; + if (!IsInsideMM(rti.introduction_date, 0, CalendarTime::MAX_DATE.base())) continue; /* Not yet introduced at this date. */ - if (rti->introduction_date > date) continue; + if (rti.introduction_date > date) continue; /* Have we introduced all required railtypes? */ - RailTypes required = rti->introduction_required_railtypes; + RailTypes required = rti.introduction_required_railtypes; if (!rts.All(required)) continue; - rts.Set(rti->introduces_railtypes); + rts.Set(rti.introduces_railtypes); } /* When we added railtypes we need to run this method again; the added diff --git a/src/road.cpp b/src/road.cpp index 18478e9598a26..a944e0092af3b 100644 --- a/src/road.cpp +++ b/src/road.cpp @@ -176,24 +176,24 @@ bool ValParamRoadType(RoadType roadtype) */ RoadTypes AddDateIntroducedRoadTypes(RoadTypes current, TimerGameCalendar::Date date) { + extern RoadTypeInfo _roadtypes[ROADTYPE_END]; RoadTypes rts = current; - for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { - const RoadTypeInfo *rti = GetRoadTypeInfo(rt); + for (RoadTypeInfo &rti : _roadtypes) { /* Unused road type. */ - if (rti->label == 0) continue; + if (rti.label == 0) continue; /* Not date introduced. */ - if (!IsInsideMM(rti->introduction_date, 0, CalendarTime::MAX_DATE.base())) continue; + if (!IsInsideMM(rti.introduction_date, 0, CalendarTime::MAX_DATE.base())) continue; /* Not yet introduced at this date. */ - if (rti->introduction_date > date) continue; + if (rti.introduction_date > date) continue; /* Have we introduced all required roadtypes? */ - RoadTypes required = rti->introduction_required_roadtypes; + RoadTypes required = rti.introduction_required_roadtypes; if (!rts.All(required)) continue; - rts.Set(rti->introduces_roadtypes); + rts.Set(rti.introduces_roadtypes); } /* When we added roadtypes we need to run this method again; the added From dff5323d71d8e2a8ff00114f734fdce6894cfb4d Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 7 Sep 2025 13:12:08 +0100 Subject: [PATCH 133/137] Codechange: Store rail/road type infrastructure counts in maps. Removes fixed-size arrays and replaces indexed access with iteration. --- src/company_base.h | 23 +++++++++++++++-------- src/company_cmd.cpp | 18 ++++++++++++++++-- src/company_gui.cpp | 24 +++++++++++++----------- src/economy.cpp | 8 ++++---- src/script/api/script_infrastructure.cpp | 22 ++++++++++++---------- 5 files changed, 60 insertions(+), 35 deletions(-) diff --git a/src/company_base.h b/src/company_base.h index c77f642389b5e..a5b028aa06a6d 100644 --- a/src/company_base.h +++ b/src/company_base.h @@ -30,8 +30,8 @@ struct CompanyEconomyEntry { }; struct CompanyInfrastructure { - std::array rail{}; ///< Count of company owned track bits for each rail type. - std::array road{}; ///< Count of company owned track bits for each road type. + std::map rail{}; ///< Count of company owned track bits for each rail type. + std::map road{}; ///< Count of company owned track bits for each road type. uint32_t signal = 0; ///< Count of company owned signals. uint32_t water = 0; ///< Count of company owned track bits for canals. uint32_t station = 0; ///< Count of company owned station tiles. @@ -39,16 +39,23 @@ struct CompanyInfrastructure { auto operator<=>(const CompanyInfrastructure &) const = default; - /** Get total sum of all owned track bits. */ - uint32_t GetRailTotal() const - { - return std::accumulate(std::begin(this->rail), std::end(this->rail), 0U); - } - + uint32_t GetRailTotal() const; uint32_t GetRoadTramTotal(RoadTramType rtt) const; inline uint32_t GetRoadTotal() const { return GetRoadTramTotal(RTT_ROAD); } inline uint32_t GetTramTotal() const { return GetRoadTramTotal(RTT_TRAM); } + + inline uint32_t GetRailCount(RailType railtype) const + { + auto it = this->rail.find(railtype); + return it == std::end(this->rail) ? 0 : it->second; + } + + inline uint32_t GetRoadCount(RoadType roadtype) const + { + auto it = this->road.find(roadtype); + return it == std::end(this->road) ? 0 : it->second; + } }; class FreeUnitIDGenerator { diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index c336e4bf21cb7..30414d1b7b4e9 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -1289,6 +1289,19 @@ int CompanyServiceInterval(const Company *c, VehicleType type) } } +/** + * Get total sum of all owned track bits. + * @return Combined total rail track bits. + */ +uint32_t CompanyInfrastructure::GetRailTotal() const +{ + uint32_t total = 0; + for (const auto &[_, count] : this->rail) { + total += count; + } + return total; +} + /** * Get total sum of all owned road bits. * @param rtt RoadTramType to get total for. @@ -1297,8 +1310,9 @@ int CompanyServiceInterval(const Company *c, VehicleType type) uint32_t CompanyInfrastructure::GetRoadTramTotal(RoadTramType rtt) const { uint32_t total = 0; - for (RoadType rt : GetMaskForRoadTramType(rtt)) { - total += this->road[rt]; + auto mask = GetMaskForRoadTramType(rtt); + for (const auto &[roadtype, count] : this->road) { + if (mask.Test(roadtype)) total += count; } return total; } diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 29efaf7c3d566..30c77add9cc9e 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -1604,10 +1604,11 @@ struct CompanyInfrastructureWindow : Window this->list.emplace_back(InfrastructureItemType::Header, STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT); for (const RailType &rt : _sorted_railtypes) { - if (c->infrastructure.rail[rt] == 0) continue; - Money monthly_cost = RailMaintenanceCost(rt, c->infrastructure.rail[rt], rail_total); + auto it = c->infrastructure.rail.find(rt); + if (it == std::end(c->infrastructure.rail) || it->second == 0) continue; + Money monthly_cost = RailMaintenanceCost(rt, it->second, rail_total); total_monthly_cost += monthly_cost; - this->list.emplace_back(InfrastructureItemType::Value, GetRailTypeInfo(rt)->strings.name, c->infrastructure.rail[rt], monthly_cost); + this->list.emplace_back(InfrastructureItemType::Value, GetRailTypeInfo(rt)->strings.name, it->second, monthly_cost); } if (c->infrastructure.signal > 0) { @@ -1624,10 +1625,11 @@ struct CompanyInfrastructureWindow : Window for (const RoadType &rt : _sorted_roadtypes) { if (!RoadTypeIsRoad(rt)) continue; - if (c->infrastructure.road[rt] == 0) continue; - Money monthly_cost = RoadMaintenanceCost(rt, c->infrastructure.road[rt], road_total); + auto it = c->infrastructure.road.find(rt); + if (it == std::end(c->infrastructure.road) || it->second == 0) continue; + Money monthly_cost = RoadMaintenanceCost(rt, it->second, road_total); total_monthly_cost += monthly_cost; - this->list.emplace_back(InfrastructureItemType::Value, GetRoadTypeInfo(rt)->strings.name, c->infrastructure.road[rt], monthly_cost); + this->list.emplace_back(InfrastructureItemType::Value, GetRoadTypeInfo(rt)->strings.name, it->second, monthly_cost); } } @@ -1638,10 +1640,11 @@ struct CompanyInfrastructureWindow : Window for (const RoadType &rt : _sorted_roadtypes) { if (!RoadTypeIsTram(rt)) continue; - if (c->infrastructure.road[rt] == 0) continue; - Money monthly_cost = RoadMaintenanceCost(rt, c->infrastructure.road[rt], tram_total); + auto it = c->infrastructure.road.find(rt); + if (it == std::end(c->infrastructure.road) || it->second == 0) continue; + Money monthly_cost = RoadMaintenanceCost(rt, it->second, tram_total); total_monthly_cost += monthly_cost; - this->list.emplace_back(InfrastructureItemType::Value, GetRoadTypeInfo(rt)->strings.name, c->infrastructure.road[rt], monthly_cost); + this->list.emplace_back(InfrastructureItemType::Value, GetRoadTypeInfo(rt)->strings.name, it->second, monthly_cost); } } @@ -2072,8 +2075,7 @@ struct CompanyWindow : Window y += GetCharacterHeight(FS_NORMAL); } - /* GetRoadTotal() skips tram pieces, but we actually want road and tram here. */ - uint road_pieces = std::accumulate(std::begin(c->infrastructure.road), std::end(c->infrastructure.road), 0U); + uint road_pieces = c->infrastructure.GetRoadTotal() + c->infrastructure.GetTramTotal(); if (road_pieces != 0) { DrawString(r.left, r.right, y, GetString(STR_COMPANY_VIEW_INFRASTRUCTURE_ROAD, road_pieces)); y += GetCharacterHeight(FS_NORMAL); diff --git a/src/economy.cpp b/src/economy.cpp index d61372de7eabb..d8d4cecc5926c 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -655,14 +655,14 @@ static void CompaniesGenStatistics() CommandCost cost(EXPENSES_PROPERTY); uint32_t rail_total = c->infrastructure.GetRailTotal(); - for (RailType rt = RAILTYPE_BEGIN; rt < RAILTYPE_END; rt++) { - if (c->infrastructure.rail[rt] != 0) cost.AddCost(RailMaintenanceCost(rt, c->infrastructure.rail[rt], rail_total)); + for (const auto &[railtype, count] : c->infrastructure.rail) { + if (count != 0) cost.AddCost(RailMaintenanceCost(railtype, count, rail_total)); } cost.AddCost(SignalMaintenanceCost(c->infrastructure.signal)); uint32_t road_total = c->infrastructure.GetRoadTotal(); uint32_t tram_total = c->infrastructure.GetTramTotal(); - for (RoadType rt = ROADTYPE_BEGIN; rt < ROADTYPE_END; rt++) { - if (c->infrastructure.road[rt] != 0) cost.AddCost(RoadMaintenanceCost(rt, c->infrastructure.road[rt], RoadTypeIsRoad(rt) ? road_total : tram_total)); + for (const auto &[roadtype, count] : c->infrastructure.road) { + if (count != 0) cost.AddCost(RoadMaintenanceCost(roadtype, count, RoadTypeIsRoad(roadtype) ? road_total : tram_total)); } cost.AddCost(CanalMaintenanceCost(c->infrastructure.water)); cost.AddCost(StationMaintenanceCost(c->infrastructure.station)); diff --git a/src/script/api/script_infrastructure.cpp b/src/script/api/script_infrastructure.cpp index 17e65e932b558..75344dc619730 100644 --- a/src/script/api/script_infrastructure.cpp +++ b/src/script/api/script_infrastructure.cpp @@ -23,7 +23,7 @@ company = ScriptCompany::ResolveCompanyID(company); if (company == ScriptCompany::COMPANY_INVALID || (::RailType)railtype >= RAILTYPE_END) return 0; - return ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->infrastructure.rail[railtype]; + return ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->infrastructure.GetRailCount(static_cast<::RailType>(railtype)); } /* static */ SQInteger ScriptInfrastructure::GetRoadPieceCount(ScriptCompany::CompanyID company, ScriptRoad::RoadType roadtype) @@ -31,7 +31,7 @@ company = ScriptCompany::ResolveCompanyID(company); if (company == ScriptCompany::COMPANY_INVALID || (::RoadType)roadtype >= ROADTYPE_END) return 0; - return ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->infrastructure.road[roadtype]; + return ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->infrastructure.GetRoadCount(static_cast<::RoadType>(roadtype)); } /* static */ SQInteger ScriptInfrastructure::GetInfrastructurePieceCount(ScriptCompany::CompanyID company, Infrastructure infra_type) @@ -66,20 +66,22 @@ /* static */ Money ScriptInfrastructure::GetMonthlyRailCosts(ScriptCompany::CompanyID company, ScriptRail::RailType railtype) { + ::RailType rt = static_cast<::RailType>(railtype); company = ScriptCompany::ResolveCompanyID(company); - if (company == ScriptCompany::COMPANY_INVALID || (::RailType)railtype >= RAILTYPE_END || !_settings_game.economy.infrastructure_maintenance) return 0; + if (company == ScriptCompany::COMPANY_INVALID || rt >= RAILTYPE_END || !_settings_game.economy.infrastructure_maintenance) return 0; const ::Company *c = ::Company::Get(ScriptCompany::FromScriptCompanyID(company)); - return ::RailMaintenanceCost((::RailType)railtype, c->infrastructure.rail[railtype], c->infrastructure.GetRailTotal()); + return ::RailMaintenanceCost(rt, c->infrastructure.GetRailCount(rt), c->infrastructure.GetRailTotal()); } /* static */ Money ScriptInfrastructure::GetMonthlyRoadCosts(ScriptCompany::CompanyID company, ScriptRoad::RoadType roadtype) { + ::RoadType rt = static_cast<::RoadType>(roadtype); company = ScriptCompany::ResolveCompanyID(company); - if (company == ScriptCompany::COMPANY_INVALID || (::RoadType)roadtype >= ROADTYPE_END || !_settings_game.economy.infrastructure_maintenance) return 0; + if (company == ScriptCompany::COMPANY_INVALID || rt >= ROADTYPE_END || !_settings_game.economy.infrastructure_maintenance) return 0; const ::Company *c = ::Company::Get(ScriptCompany::FromScriptCompanyID(company)); - return ::RoadMaintenanceCost((::RoadType)roadtype, c->infrastructure.road[roadtype], RoadTypeIsRoad((::RoadType)roadtype) ? c->infrastructure.GetRoadTotal() : c->infrastructure.GetTramTotal()); + return ::RoadMaintenanceCost(rt, c->infrastructure.GetRoadCount(rt), RoadTypeIsRoad(rt) ? c->infrastructure.GetRoadTotal() : c->infrastructure.GetTramTotal()); } /* static */ Money ScriptInfrastructure::GetMonthlyInfrastructureCosts(ScriptCompany::CompanyID company, Infrastructure infra_type) @@ -92,8 +94,8 @@ case INFRASTRUCTURE_RAIL: { Money cost; uint32_t rail_total = c->infrastructure.GetRailTotal(); - for (::RailType rt = ::RAILTYPE_BEGIN; rt != ::RAILTYPE_END; rt++) { - cost += RailMaintenanceCost(rt, c->infrastructure.rail[rt], rail_total); + for (const auto &[railtype, count] : c->infrastructure.rail) { + cost += RailMaintenanceCost(railtype, count, rail_total); } return cost; } @@ -105,8 +107,8 @@ Money cost; uint32_t road_total = c->infrastructure.GetRoadTotal(); uint32_t tram_total = c->infrastructure.GetTramTotal(); - for (::RoadType rt = ::ROADTYPE_BEGIN; rt != ::ROADTYPE_END; rt++) { - cost += RoadMaintenanceCost(rt, c->infrastructure.road[rt], RoadTypeIsRoad(rt) ? road_total : tram_total); + for (const auto &[roadtype, count] : c->infrastructure.road) { + cost += RoadMaintenanceCost(roadtype, count, RoadTypeIsRoad(roadtype) ? road_total : tram_total); } return cost; } From 5a9cf80149d4fdc3fe64a7ceab033bda113c7a97 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 7 Sep 2025 14:35:01 +0100 Subject: [PATCH 134/137] Codechange: Allocate map railtypes dynamically. --- src/CMakeLists.txt | 1 + src/bridge_map.h | 6 +- src/lang/english.txt | 1 + src/misc.cpp | 2 + src/newgrf_commons.h | 3 +- src/newgrf_railtype.cpp | 34 ++++++-- src/newgrf_railtype.h | 1 + src/rail.cpp | 2 + src/rail_cmd.cpp | 24 +++-- src/rail_map.h | 39 ++++++--- src/rail_type.h | 9 ++ src/road_cmd.cpp | 4 +- src/road_map.h | 6 +- src/saveload/afterload.cpp | 63 +++++++++++--- src/saveload/labelmaps_sl.cpp | 20 ++++- src/saveload/saveload.h | 1 + src/saveload/waypoint_sl.cpp | 2 +- src/script/api/script_infrastructure.cpp | 1 + src/station_cmd.cpp | 11 ++- src/station_map.h | 12 +-- src/transport_mapping.hpp | 106 +++++++++++++++++++++++ src/tunnel_map.h | 6 +- src/tunnelbridge_cmd.cpp | 16 +++- src/waypoint_cmd.cpp | 2 +- 24 files changed, 301 insertions(+), 71 deletions(-) create mode 100644 src/transport_mapping.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 16215e7f8d867..f0e44215211a7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -541,6 +541,7 @@ add_files( transparency.h transparency_gui.cpp transparency_gui.h + transport_mapping.hpp transport_type.h tree_cmd.cpp tree_cmd.h diff --git a/src/bridge_map.h b/src/bridge_map.h index 452e439329202..35ecd8f65311e 100644 --- a/src/bridge_map.h +++ b/src/bridge_map.h @@ -165,12 +165,12 @@ inline void MakeRoadBridgeRamp(Tile t, Owner o, Owner owner_road, Owner owner_tr * @param o the new owner of the bridge ramp * @param bridgetype the type of bridge this bridge ramp belongs to * @param d the direction this ramp must be facing - * @param rt the rail type of the bridge + * @param map_railtype the map rail type of the bridge */ -inline void MakeRailBridgeRamp(Tile t, Owner o, BridgeType bridgetype, DiagDirection d, RailType rt) +inline void MakeRailBridgeRamp(Tile t, Owner o, BridgeType bridgetype, DiagDirection d, MapRailType map_railtype) { MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_RAIL); - SetRailType(t, rt); + SetMapRailType(t, map_railtype); } /** diff --git a/src/lang/english.txt b/src/lang/english.txt index dd2f426621a33..674fca7c6169f 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -5231,6 +5231,7 @@ STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}Can't re STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE :{WHITE}Can't convert signals here... STR_ERROR_THERE_IS_NO_RAILROAD_TRACK :{WHITE}... there is no railway track STR_ERROR_THERE_ARE_NO_SIGNALS :{WHITE}... there are no signals +STR_ERROR_TOO_MANY_RAILTYPES :{WHITE}... too many rail types in use STR_ERROR_CAN_T_CONVERT_RAIL :{WHITE}Can't convert rail type here... diff --git a/src/misc.cpp b/src/misc.cpp index 101f089704541..96f17f0362725 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -167,4 +167,6 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin _gamelog.Mode(); _gamelog.GRFAddList(_grfconfig); _gamelog.StopAction(); + + _railtype_mapping.Init(); } diff --git a/src/newgrf_commons.h b/src/newgrf_commons.h index fb44120a60951..472f3a44b4639 100644 --- a/src/newgrf_commons.h +++ b/src/newgrf_commons.h @@ -473,7 +473,8 @@ struct SubstituteGRFFileProps : StandardGRFFileProps { /** Container for a label for rail or road type conversion. */ template struct LabelObject { - T label = {}; ///< Label of rail or road type. + T label{}; ///< Label of rail or road type. + uint8_t index = 0; ///< Local index of rail or road type. uint8_t subtype = 0; ///< Subtype of type (road or tram). }; diff --git a/src/newgrf_railtype.cpp b/src/newgrf_railtype.cpp index 67754addb2de6..583b83be2847a 100644 --- a/src/newgrf_railtype.cpp +++ b/src/newgrf_railtype.cpp @@ -9,6 +9,7 @@ #include "stdafx.h" #include "core/container_func.hpp" +#include "core/flatset_type.hpp" #include "debug.h" #include "newgrf_railtype.h" #include "newgrf_roadtype.h" @@ -187,13 +188,24 @@ uint8_t GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile) std::vector> _railtype_list; +void PreloadRailTypeMaps() +{ + _railtype_mapping.Init(); + for (auto it = std::begin(_railtype_list); it != std::end(_railtype_list); ++it) { + RailType rt = GetRailTypeByLabel(it->label); + if (rt == INVALID_RAILTYPE) continue; + + _railtype_mapping.Set(static_cast(std::distance(std::begin(_railtype_list), it)), rt); + } +} + /** * Test if any saved rail type labels are different to the currently loaded * rail types. Rail types stored in the map will be converted if necessary. */ void ConvertRailTypes() { - std::vector railtype_conversion_map; + std::vector railtype_conversion_map; bool needs_conversion = false; for (auto it = std::begin(_railtype_list); it != std::end(_railtype_list); ++it) { @@ -202,10 +214,13 @@ void ConvertRailTypes() rt = RAILTYPE_RAIL; } - railtype_conversion_map.push_back(rt); + railtype_conversion_map.push_back(_railtype_mapping.AllocateMapType(rt, true)); + + if (it->label == 0) continue; + if (needs_conversion) continue; /* Conversion is needed if the rail type is in a different position than the list. */ - if (it->label != 0 && rt != std::distance(std::begin(_railtype_list), it)) needs_conversion = true; + if (_railtype_mapping.GetMappedType(rt).base() != it->index) needs_conversion = true; } if (!needs_conversion) return; @@ -213,24 +228,24 @@ void ConvertRailTypes() for (const auto t : Map::Iterate()) { switch (GetTileType(t)) { case MP_RAILWAY: - SetRailType(t, railtype_conversion_map[GetRailType(t)]); + SetMapRailType(t, railtype_conversion_map[GetRailType(t)]); break; case MP_ROAD: if (IsLevelCrossing(t)) { - SetRailType(t, railtype_conversion_map[GetRailType(t)]); + SetMapRailType(t, railtype_conversion_map[GetRailType(t)]); } break; case MP_STATION: if (HasStationRail(t)) { - SetRailType(t, railtype_conversion_map[GetRailType(t)]); + SetMapRailType(t, railtype_conversion_map[GetRailType(t)]); } break; case MP_TUNNELBRIDGE: if (GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL) { - SetRailType(t, railtype_conversion_map[GetRailType(t)]); + SetMapRailType(t, railtype_conversion_map[GetRailType(t)]); } break; @@ -244,9 +259,10 @@ void ConvertRailTypes() void SetCurrentRailTypeLabelList() { _railtype_list.clear(); - for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { - _railtype_list.emplace_back(GetRailTypeInfo(rt)->label, 0); + if (MapRailType map_railtype = _railtype_mapping.GetMappedType(rt); map_railtype != RailTypeMapping::INVALID_MAP_TYPE) { + _railtype_list.emplace_back(GetRailTypeInfo(rt)->label, map_railtype.base(), 0); + } } } diff --git a/src/newgrf_railtype.h b/src/newgrf_railtype.h index e0d36349ca732..62b9173b7f366 100644 --- a/src/newgrf_railtype.h +++ b/src/newgrf_railtype.h @@ -62,5 +62,6 @@ uint8_t GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile) void ConvertRailTypes(); void SetCurrentRailTypeLabelList(); void ClearRailTypeLabelList(); +void PreloadRailTypeMaps(); #endif /* NEWGRF_RAILTYPE_H */ diff --git a/src/rail.cpp b/src/rail.cpp index 3d949d6bb1cca..175e27aeeb3c3 100644 --- a/src/rail.cpp +++ b/src/rail.cpp @@ -208,3 +208,5 @@ RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels) /* No matching label was found, so it is invalid */ return INVALID_RAILTYPE; } + +RailTypeMapping _railtype_mapping; diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 455424b33583b..b3924c19a02bb 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -537,8 +537,11 @@ CommandCost CmdBuildSingleRail(DoCommandFlags flags, TileIndex tile, RailType ra cost.AddCost(num_new_tram_pieces * RoadBuildCost(roadtype_tram)); } + MapRailType map_railtype = _railtype_mapping.AllocateMapType(railtype, flags.Test(DoCommandFlag::Execute)); + if (map_railtype == RailTypeMapping::INVALID_MAP_TYPE) return CommandCost{STR_ERROR_TOO_MANY_RAILTYPES}; + if (flags.Test(DoCommandFlag::Execute)) { - MakeRoadCrossing(tile, road_owner, tram_owner, _current_company, (track == TRACK_X ? AXIS_Y : AXIS_X), railtype, roadtype_road, roadtype_tram, GetTownIndex(tile)); + MakeRoadCrossing(tile, road_owner, tram_owner, _current_company, (track == TRACK_X ? AXIS_Y : AXIS_X), map_railtype, roadtype_road, roadtype_tram, GetTownIndex(tile)); UpdateLevelCrossing(tile, false); MarkDirtyAdjacentLevelCrossingTiles(tile, GetCrossingRoadAxis(tile)); Company::Get(_current_company)->infrastructure.rail[railtype] += LEVELCROSSING_TRACKBIT_FACTOR; @@ -579,8 +582,11 @@ CommandCost CmdBuildSingleRail(DoCommandFlags flags, TileIndex tile, RailType ra cost.AddCost(_price[PR_CLEAR_ROUGH]); } + MapRailType map_railtype = _railtype_mapping.AllocateMapType(railtype, flags.Test(DoCommandFlag::Execute)); + if (map_railtype == RailTypeMapping::INVALID_MAP_TYPE) return CommandCost{STR_ERROR_TOO_MANY_RAILTYPES}; + if (flags.Test(DoCommandFlag::Execute)) { - MakeRailNormal(tile, _current_company, trackbit, railtype); + MakeRailNormal(tile, _current_company, trackbit, map_railtype); if (water_ground) { SetRailGroundType(tile, RAIL_GROUND_WATER); if (IsPossibleDockingTile(tile)) CheckForDockingTile(tile); @@ -1004,13 +1010,16 @@ CommandCost CmdBuildTrainDepot(DoCommandFlags flags, TileIndex tile, RailType ra if (!Depot::CanAllocateItem()) return CMD_ERROR; } + MapRailType map_railtype = _railtype_mapping.AllocateMapType(railtype, flags.Test(DoCommandFlag::Execute)); + if (map_railtype == RailTypeMapping::INVALID_MAP_TYPE) return CommandCost{STR_ERROR_TOO_MANY_RAILTYPES}; + if (flags.Test(DoCommandFlag::Execute)) { if (rotate_existing_depot) { SetRailDepotExitDirection(tile, dir); } else { Depot *d = new Depot(tile); - MakeRailDepot(tile, _current_company, d->index, dir, railtype); + MakeRailDepot(tile, _current_company, d->index, dir, map_railtype); MakeDefaultName(d); Company::Get(_current_company)->infrastructure.rail[railtype]++; @@ -1549,6 +1558,9 @@ CommandCost CmdConvertRail(DoCommandFlags flags, TileIndex tile, TileIndex area_ CommandCost error = CommandCost(STR_ERROR_NO_SUITABLE_RAILROAD_TRACK); // by default, there is no track to convert. bool found_convertible_track = false; // whether we actually did convert some track (see bug #7633) + MapRailType map_railtype = _railtype_mapping.AllocateMapType(totype, flags.Test(DoCommandFlag::Execute)); + if (map_railtype == RailTypeMapping::INVALID_MAP_TYPE) return CommandCost{STR_ERROR_TOO_MANY_RAILTYPES}; + std::unique_ptr iter = TileIterator::Create(area_start, area_end, diagonal); for (; (tile = *iter) != INVALID_TILE; ++(*iter)) { TileType tt = GetTileType(tile); @@ -1624,7 +1636,7 @@ CommandCost CmdConvertRail(DoCommandFlags flags, TileIndex tile, TileIndex area_ DirtyCompanyInfrastructureWindows(c->index); } - SetRailType(tile, totype); + SetMapRailType(tile, map_railtype); MarkTileDirtyByTile(tile); /* update power of train on this tile */ for (Vehicle *v : VehiclesOnTile(tile)) { @@ -1703,8 +1715,8 @@ CommandCost CmdConvertRail(DoCommandFlags flags, TileIndex tile, TileIndex area_ c->infrastructure.rail[totype] += num_pieces; DirtyCompanyInfrastructureWindows(c->index); - SetRailType(tile, totype); - SetRailType(endtile, totype); + SetMapRailType(tile, map_railtype); + SetMapRailType(endtile, map_railtype); for (Vehicle *v : VehiclesOnTile(tile)) { if (v->type == VEH_TRAIN) include(affected_trains, Train::From(v)->First()); diff --git a/src/rail_map.h b/src/rail_map.h index 4f1db937f4fc4..68496e72c0ba9 100644 --- a/src/rail_map.h +++ b/src/rail_map.h @@ -107,24 +107,37 @@ debug_inline static bool IsRailDepotTile(Tile t) return IsTileType(t, MP_RAILWAY) && IsRailDepot(t); } + /** - * Gets the rail type of the given tile - * @param t the tile to get the rail type from - * @return the rail type of the tile + * Gets the map rail type of the given tile + * @param t the tile to get the map rail type from + * @return the map rail type of the tile */ -inline RailType GetRailType(Tile t) +inline MapRailType GetMapRailType(Tile t) { - return (RailType)GB(t.m8(), 0, 6); + return static_cast(GB(t.m8(), 0, 6)); } + /** * Sets the rail type of the given tile * @param t the tile to set the rail type of - * @param r the new rail type for the tile + * @param map_railtype the new mapped rail type for the tile + */ +inline void SetMapRailType(Tile t, MapRailType map_railtype) +{ + SB(t.m8(), 0, 6, map_railtype.base()); +} + + +/** + * Gets the rail type of the given tile + * @param t the tile to get the rail type from + * @return the rail type of the tile */ -inline void SetRailType(Tile t, RailType r) +inline RailType GetRailType(Tile t) { - SB(t.m8(), 0, 6, r); + return _railtype_mapping.GetType(GetMapRailType(t)); } @@ -515,7 +528,7 @@ inline bool IsSnowRailGround(Tile t) } -inline void MakeRailNormal(Tile t, Owner o, TrackBits b, RailType r) +inline void MakeRailNormal(Tile t, Owner o, TrackBits b, MapRailType map_railtype) { SetTileType(t, MP_RAILWAY); SetTileOwner(t, o); @@ -526,7 +539,7 @@ inline void MakeRailNormal(Tile t, Owner o, TrackBits b, RailType r) t.m5() = RAIL_TILE_NORMAL << 6 | b; SB(t.m6(), 2, 6, 0); t.m7() = 0; - t.m8() = r; + t.m8() = map_railtype.base(); } /** @@ -546,9 +559,9 @@ inline void SetRailDepotExitDirection(Tile tile, DiagDirection dir) * @param owner New owner of the depot. * @param depot_id New depot ID. * @param dir Direction of the depot exit. - * @param rail_type Rail type of the depot. + * @param map_railtype Mapped rail type of the depot. */ -inline void MakeRailDepot(Tile tile, Owner owner, DepotID depot_id, DiagDirection dir, RailType rail_type) +inline void MakeRailDepot(Tile tile, Owner owner, DepotID depot_id, DiagDirection dir, MapRailType map_railtype) { SetTileType(tile, MP_RAILWAY); SetTileOwner(tile, owner); @@ -559,7 +572,7 @@ inline void MakeRailDepot(Tile tile, Owner owner, DepotID depot_id, DiagDirectio tile.m5() = RAIL_TILE_DEPOT << 6 | dir; SB(tile.m6(), 2, 6, 0); tile.m7() = 0; - tile.m8() = rail_type; + tile.m8() = map_railtype.base(); } #endif /* RAIL_MAP_H */ diff --git a/src/rail_type.h b/src/rail_type.h index cb12a09e37ee3..7f4081e43a1a0 100644 --- a/src/rail_type.h +++ b/src/rail_type.h @@ -11,6 +11,8 @@ #define RAIL_TYPE_H #include "core/enum_type.hpp" +#include "core/strong_typedef_type.hpp" +#include "transport_mapping.hpp" typedef uint32_t RailTypeLabel; @@ -39,4 +41,11 @@ using RailTypes = EnumBitSet; static constexpr RailTypes INVALID_RAILTYPES{UINT64_MAX}; +/** Mapped rail type. */ +using RailTypeMapping = TransportMapping; +extern RailTypeMapping _railtype_mapping; + +/** Alias for mapped rail type. */ +using MapRailType = RailTypeMapping::MapType; + #endif /* RAIL_TYPE_H */ diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 694f7f639d99e..3ff0b4aa08d86 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -494,7 +494,7 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlags flags, RoadBits pie if (GetRoadType(tile, OtherRoadTramType(rtt)) == INVALID_ROADTYPE) { TrackBits tracks = GetCrossingRailBits(tile); bool reserved = HasCrossingReservation(tile); - MakeRailNormal(tile, GetTileOwner(tile), tracks, GetRailType(tile)); + MakeRailNormal(tile, GetTileOwner(tile), tracks, GetMapRailType(tile)); if (reserved) SetTrackReservation(tile, tracks); /* Update rail count for level crossings. The plain track should still be accounted @@ -765,7 +765,7 @@ CommandCost CmdBuildRoad(DoCommandFlags flags, TileIndex tile, RoadBits pieces, /* Always add road to the roadtypes (can't draw without it) */ bool reserved = HasBit(GetRailReservationTrackBits(tile), railtrack); - MakeRoadCrossing(tile, company, company, GetTileOwner(tile), roaddir, GetRailType(tile), rtt == RTT_ROAD ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, town_id); + MakeRoadCrossing(tile, company, company, GetTileOwner(tile), roaddir, GetMapRailType(tile), rtt == RTT_ROAD ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, town_id); SetCrossingReservation(tile, reserved); UpdateLevelCrossing(tile, false); MarkDirtyAdjacentLevelCrossingTiles(tile, GetCrossingRoadAxis(tile)); diff --git a/src/road_map.h b/src/road_map.h index aebed25816bc4..aed2cd2090d53 100644 --- a/src/road_map.h +++ b/src/road_map.h @@ -633,12 +633,12 @@ inline void MakeRoadNormal(Tile t, RoadBits bits, RoadType road_rt, RoadType tra * @param tram New owner of tram tracks. * @param rail New owner of the rail track. * @param roaddir Axis of the road. - * @param rat New rail type. + * @param map_railtype New map rail type. * @param road_rt The road roadtype to set for the tile. * @param tram_rt The tram roadtype to set for the tile. * @param town Town ID if the road is a town-owned road. */ -inline void MakeRoadCrossing(Tile t, Owner road, Owner tram, Owner rail, Axis roaddir, RailType rat, RoadType road_rt, RoadType tram_rt, TownID town) +inline void MakeRoadCrossing(Tile t, Owner road, Owner tram, Owner rail, Axis roaddir, MapRailType map_railtype, RoadType road_rt, RoadType tram_rt, TownID town) { SetTileType(t, MP_ROAD); SetTileOwner(t, rail); @@ -648,7 +648,7 @@ inline void MakeRoadCrossing(Tile t, Owner road, Owner tram, Owner rail, Axis ro t.m5() = ROAD_TILE_CROSSING << 6 | roaddir; SB(t.m6(), 2, 6, 0); t.m7() = road.base(); - t.m8() = INVALID_ROADTYPE << 6 | rat; + t.m8() = INVALID_ROADTYPE << 6 | map_railtype.base(); SetRoadTypes(t, road_rt, tram_rt); SetRoadOwner(t, RTT_TRAM, tram); } diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 6f2ba03bcb68f..c867b827c52ff 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -50,6 +50,7 @@ #include "../subsidy_base.h" #include "../subsidy_func.h" #include "../newgrf.h" +#include "../newgrf_railtype.h" #include "../newgrf_station.h" #include "../engine_func.h" #include "../rail_gui.h" @@ -209,9 +210,9 @@ static void UpdateVoidTiles() for (uint y = 0; y < Map::SizeY(); y++) MakeVoid(TileXY(Map::MaxX(), y)); } -static inline RailType UpdateRailType(RailType rt, RailType min) +static inline MapRailType UpdateRailType(MapRailType rt, RailType min) { - return rt >= min ? (RailType)(rt + 1): rt; + return static_cast(rt.base() >= to_underlying(min) ? rt.base() + 1 : rt.base()); } /** @@ -552,6 +553,41 @@ static void StartScripts() ShowScriptDebugWindowIfScriptError(); } +/** + * Convert rail/road/tram tiles from raw types to mapped types. + */ +static void ConvertTransportMappings() +{ + auto convert_railtype = [](TileIndex t) { + SetMapRailType(t, _railtype_mapping.AllocateMapType(static_cast(GetMapRailType(t).base()), true)); + }; + for (auto t : Map::Iterate()) { + switch (GetTileType(t)) { + case MP_RAILWAY: + convert_railtype(t); + break; + + case MP_ROAD: + if (IsLevelCrossingTile(t)) convert_railtype(t); + break; + + case MP_STATION: + if (HasStationRail(t)) convert_railtype(t); + break; + + case MP_TUNNELBRIDGE: + switch (GetTunnelBridgeTransportType(t)) { + case TRANSPORT_RAIL: convert_railtype(t); break; + default: break; + } + break; + + default: + break; + } + } +} + /** * Perform a (large) amount of savegame conversion *magic* in order to * load older savegames and to fill the caches for various purposes. @@ -1192,24 +1228,24 @@ bool AfterLoadGame() for (auto t : Map::Iterate()) { switch (GetTileType(t)) { case MP_RAILWAY: - SetRailType(t, (RailType)GB(t.m3(), 0, 4)); + SetMapRailType(t, static_cast(GB(t.m3(), 0, 4))); break; case MP_ROAD: if (IsLevelCrossing(t)) { - SetRailType(t, (RailType)GB(t.m3(), 0, 4)); + SetMapRailType(t, static_cast(GB(t.m3(), 0, 4))); } break; case MP_STATION: if (HasStationRail(t)) { - SetRailType(t, (RailType)GB(t.m3(), 0, 4)); + SetMapRailType(t, static_cast(GB(t.m3(), 0, 4))); } break; case MP_TUNNELBRIDGE: if (GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL) { - SetRailType(t, (RailType)GB(t.m3(), 0, 4)); + SetMapRailType(t, static_cast(GB(t.m3(), 0, 4))); } break; @@ -1232,7 +1268,7 @@ bool AfterLoadGame() t, GetTileOwner(t), axis == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X, - GetRailType(t) + GetMapRailType(t) ); } else { TownID town = IsTileOwner(t, OWNER_TOWN) ? ClosestTownFromTile(t, UINT_MAX)->index : TownID::Begin(); @@ -1344,24 +1380,24 @@ bool AfterLoadGame() for (const auto t : Map::Iterate()) { switch (GetTileType(t)) { case MP_RAILWAY: - SetRailType(t, UpdateRailType(GetRailType(t), min_rail)); + SetMapRailType(t, UpdateRailType(GetMapRailType(t), min_rail)); break; case MP_ROAD: if (IsLevelCrossing(t)) { - SetRailType(t, UpdateRailType(GetRailType(t), min_rail)); + SetMapRailType(t, UpdateRailType(GetMapRailType(t), min_rail)); } break; case MP_STATION: if (HasStationRail(t)) { - SetRailType(t, UpdateRailType(GetRailType(t), min_rail)); + SetMapRailType(t, UpdateRailType(GetMapRailType(t), min_rail)); } break; case MP_TUNNELBRIDGE: if (GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL) { - SetRailType(t, UpdateRailType(GetRailType(t), min_rail)); + SetMapRailType(t, UpdateRailType(GetMapRailType(t), min_rail)); } break; @@ -1371,6 +1407,11 @@ bool AfterLoadGame() } } + PreloadRailTypeMaps(); + if (IsSavegameVersionBefore(SLV_TRANSPORT_TYPE_MAPPING)) { + ConvertTransportMappings(); + } + /* In version 16.1 of the savegame a company can decide if trains, which get * replaced, shall keep their old length. In all prior versions, just default * to false */ diff --git a/src/saveload/labelmaps_sl.cpp b/src/saveload/labelmaps_sl.cpp index 6875cd9ca4ab1..2f4100044a5d6 100644 --- a/src/saveload/labelmaps_sl.cpp +++ b/src/saveload/labelmaps_sl.cpp @@ -38,17 +38,26 @@ struct RAILChunkHandler : ChunkHandler { static inline const SaveLoad description[] = { SLE_VAR(LabelObject, label, SLE_UINT32), + SLE_VAR(LabelObject, index, SLE_UINT8), }; void Save() const override { SlTableHeader(description); + int index = 0; LabelObject lo; for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) { - lo.label = GetRailTypeInfo(r)->label; + const RailTypeInfo *rti = GetRailTypeInfo(r); + if (rti->label == 0) continue; - SlSetArrayIndex(r); + MapRailType map_railtype = _railtype_mapping.GetMappedType(rti->Index()); + if (map_railtype == RailTypeMapping::INVALID_MAP_TYPE) continue; + + lo.label = rti->label; + lo.index = map_railtype.base(); + + SlSetArrayIndex(index++); SlObject(&lo, description); } } @@ -56,13 +65,16 @@ struct RAILChunkHandler : ChunkHandler { void Load() const override { const std::vector slt = SlCompatTableHeader(description, _label_object_sl_compat); + bool convert = IsSavegameVersionBefore(SLV_TRANSPORT_TYPE_MAPPING); - _railtype_list.reserve(RAILTYPE_END); + _railtype_list.reserve(RailTypeMapping::MAX_SIZE); LabelObject lo; - while (SlIterateArray() != -1) { + int index; + while ((index = SlIterateArray()) != -1) { SlObject(&lo, slt); + if (convert) lo.index = index; _railtype_list.push_back(lo); } } diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index e27825a5dc9e3..5aa9427020cb3 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -412,6 +412,7 @@ enum SaveLoadVersion : uint16_t { SLV_DOCKS_UNDER_BRIDGES, ///< 360 PR#14594 Allow docks under bridges. SLV_LOCKS_UNDER_BRIDGES, ///< 361 PR#14595 Allow locks under bridges. SLV_ENGINE_MULTI_RAILTYPE, ///< 362 PR#14357 Train engines can have multiple railtypes. + SLV_TRANSPORT_TYPE_MAPPING, ///< 363 PR#..... Dynamic rail/road/tram type mapping. SL_MAX_VERSION, ///< Highest possible saveload version }; diff --git a/src/saveload/waypoint_sl.cpp b/src/saveload/waypoint_sl.cpp index 57edac03239da..452b4e173f6a9 100644 --- a/src/saveload/waypoint_sl.cpp +++ b/src/saveload/waypoint_sl.cpp @@ -129,7 +129,7 @@ void MoveWaypointsToBaseStations() bool reserved = !IsSavegameVersionBefore(SLV_100) && HasBit(tile.m5(), 4); /* The tile really has our waypoint, so reassign the map array */ - MakeRailWaypoint(tile, GetTileOwner(tile), new_wp->index, (Axis)GB(tile.m5(), 0, 1), 0, GetRailType(tile)); + MakeRailWaypoint(tile, GetTileOwner(tile), new_wp->index, (Axis)GB(tile.m5(), 0, 1), 0, GetMapRailType(tile)); new_wp->facilities.Set(StationFacility::Train); new_wp->owner = GetTileOwner(tile); diff --git a/src/script/api/script_infrastructure.cpp b/src/script/api/script_infrastructure.cpp index 75344dc619730..f801e82c29491 100644 --- a/src/script/api/script_infrastructure.cpp +++ b/src/script/api/script_infrastructure.cpp @@ -79,6 +79,7 @@ ::RoadType rt = static_cast<::RoadType>(roadtype); company = ScriptCompany::ResolveCompanyID(company); if (company == ScriptCompany::COMPANY_INVALID || rt >= ROADTYPE_END || !_settings_game.economy.infrastructure_maintenance) return 0; + if (company == ScriptCompany::COMPANY_INVALID || rt >= ROADTYPE_END || !_settings_game.economy.infrastructure_maintenance) return 0; const ::Company *c = ::Company::Get(ScriptCompany::FromScriptCompanyID(company)); return ::RoadMaintenanceCost(rt, c->infrastructure.GetRoadCount(rt), RoadTypeIsRoad(rt) ? c->infrastructure.GetRoadTotal() : c->infrastructure.GetTramTotal()); diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 0b8703e53dbb2..6e9621237d9a1 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -1427,6 +1427,9 @@ CommandCost CmdBuildRailStation(DoCommandFlags flags, TileIndex tile_org, RailTy if (!ValParamRailType(rt) || !IsValidAxis(axis)) return CMD_ERROR; + MapRailType map_railtype = _railtype_mapping.AllocateMapType(rt, flags.Test(DoCommandFlag::Execute)); + if (map_railtype == RailTypeMapping::INVALID_MAP_TYPE) return CommandCost{STR_ERROR_TOO_MANY_RAILTYPES}; + /* Check if the given station class is valid */ if (static_cast(spec_class) >= StationClass::GetClassCount()) return CMD_ERROR; const StationClass *cls = StationClass::Get(spec_class); @@ -1553,7 +1556,7 @@ CommandCost CmdBuildRailStation(DoCommandFlags flags, TileIndex tile_org, RailTy DeleteAnimatedTile(tile); uint8_t old_specindex = HasStationTileRail(tile) ? GetCustomStationSpecIndex(tile) : 0; - MakeRailStation(tile, st->owner, st->index, axis, *it, rt); + MakeRailStation(tile, st->owner, st->index, axis, *it, map_railtype); /* Free the spec if we overbuild something */ DeallocateSpecFromStation(st, old_specindex); @@ -1772,7 +1775,7 @@ CommandCost RemoveFromRailBaseStation(TileArea ta, std::vector &affected_st uint specindex = GetCustomStationSpecIndex(tile); Track track = GetRailStationTrack(tile); Owner owner = GetTileOwner(tile); - RailType rt = GetRailType(tile); + MapRailType map_railtype = GetMapRailType(tile); Train *v = nullptr; if (HasStationReservation(tile)) { @@ -1781,11 +1784,11 @@ CommandCost RemoveFromRailBaseStation(TileArea ta, std::vector &affected_st } bool build_rail = keep_rail && !IsStationTileBlocked(tile); - if (!build_rail && !IsStationTileBlocked(tile)) Company::Get(owner)->infrastructure.rail[rt]--; + if (!build_rail && !IsStationTileBlocked(tile)) Company::Get(owner)->infrastructure.rail[_railtype_mapping.GetType(map_railtype)]--; DoClearSquare(tile); DeleteNewGRFInspectWindow(GSF_STATIONS, tile.base()); - if (build_rail) MakeRailNormal(tile, owner, TrackToTrackBits(track), rt); + if (build_rail) MakeRailNormal(tile, owner, TrackToTrackBits(track), map_railtype); Company::Get(owner)->infrastructure.station--; DirtyCompanyInfrastructureWindows(owner); diff --git a/src/station_map.h b/src/station_map.h index d90cc8dda590c..15b5b468decb0 100644 --- a/src/station_map.h +++ b/src/station_map.h @@ -738,12 +738,12 @@ inline void MakeStation(Tile t, Owner o, StationID sid, StationType st, uint8_t * @param sid the station to which this tile belongs * @param a the axis of this tile * @param section the StationGfx to be used for this tile - * @param rt the railtype of this tile + * @param map_railtype the map rail type of this tile */ -inline void MakeRailStation(Tile t, Owner o, StationID sid, Axis a, uint8_t section, RailType rt) +inline void MakeRailStation(Tile t, Owner o, StationID sid, Axis a, uint8_t section, MapRailType map_railtype) { MakeStation(t, o, sid, StationType::Rail, section + a); - SetRailType(t, rt); + SetMapRailType(t, map_railtype); SetRailStationReservation(t, false); } @@ -754,12 +754,12 @@ inline void MakeRailStation(Tile t, Owner o, StationID sid, Axis a, uint8_t sect * @param sid the waypoint to which this tile belongs * @param a the axis of this tile * @param section the StationGfx to be used for this tile - * @param rt the railtype of this tile + * @param map_railtype the map rail type of this tile */ -inline void MakeRailWaypoint(Tile t, Owner o, StationID sid, Axis a, uint8_t section, RailType rt) +inline void MakeRailWaypoint(Tile t, Owner o, StationID sid, Axis a, uint8_t section, MapRailType map_railtype) { MakeStation(t, o, sid, StationType::RailWaypoint, section + a); - SetRailType(t, rt); + SetMapRailType(t, map_railtype); SetRailStationReservation(t, false); } diff --git a/src/transport_mapping.hpp b/src/transport_mapping.hpp new file mode 100644 index 0000000000000..95e7692980dc4 --- /dev/null +++ b/src/transport_mapping.hpp @@ -0,0 +1,106 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file transport_mapping.hpp Transport mapping utilities. */ + +#ifndef TRANSPORT_MAPPING_HPP +#define TRANSPORT_MAPPING_HPP + +#include "core/convertible_through_base.hpp" +#include "core/strong_typedef_type.hpp" + +/** + * Transport type (rail, road, etc) mapping helper. + * @tparam TType Native type to be mapped. + * @tparam TInvalidType Invalid value for native type. + * @tparam TMaxSize maximum number of mapped entries. + */ +template +class TransportMapping { +public: + static constexpr size_t MAX_SIZE = TMaxSize; + static constexpr TType INVALID_TYPE = TInvalidType; + + /** Unique type holds a mapped transport type. */ + using MapType = StrongType::Typedef; + static constexpr MapType INVALID_MAP_TYPE = static_cast(TMaxSize); + + TransportMapping() { this->Init(); } + + void Init() + { + std::ranges::fill(this->map, INVALID_TYPE); + } + + /** + * Get the native type of a mapped type. + * @param mapped_type Mapped type to look up. + * @return native type of mapped type, or INVALID_TYPE if invalid. + */ + TType GetType(MapType mapped_type) const + { + if (mapped_type == INVALID_MAP_TYPE) return INVALID_TYPE; + + assert(mapped_type.base() < std::size(this->map)); + return this->map[mapped_type]; + } + + void Set(MapType mapped_type, TType type) + { + this->map[mapped_type] = type; + } + + /** + * Get the mapped type of a native type. + * @param type Native type to look up. + * @return mapped type of native type, or INVALID_MAP_TYPE if invalid. + */ + MapType GetMappedType(TType type) + { + if (type == INVALID_TYPE) return INVALID_MAP_TYPE; + + auto it = std::ranges::find(this->map, type); + if (it != std::end(this->map)) return this->Index(it); + + return INVALID_MAP_TYPE; + } + + /** + * Allocate a mapped type for a native type. + * If the native type is already mapped then the existing allocation is used. + * @param type Native type to map. + * @param exec Whether to actually set the mapping. + * @return mapped type of native type, or INVALID_MAP_TYPE if allocation was not possible. + */ + MapType AllocateMapType(TType type, bool exec) + { + if (type == INVALID_TYPE) return INVALID_MAP_TYPE; + + /* Check for existing mapped type. */ + auto it = std::ranges::find(this->map, type); + if (it != std::end(this->map)) return this->Index(it); + + /* Check for an unused entry. */ + it = std::ranges::find(this->map, INVALID_TYPE); + if (it == std::end(this->map)) return INVALID_MAP_TYPE; + + if (exec) *it = type; + + return this->Index(it); + } + +private: + using MapStorage = TypedIndexContainer, MapType>; + MapStorage map{}; + + MapType Index(MapStorage::iterator iter) const + { + return static_cast(iter - std::begin(this->map)); + } +}; + +#endif /* TRANSPORT_MAPPING_HPP */ diff --git a/src/tunnel_map.h b/src/tunnel_map.h index 86f3027cbcdba..94cf70a013da0 100644 --- a/src/tunnel_map.h +++ b/src/tunnel_map.h @@ -68,9 +68,9 @@ inline void MakeRoadTunnel(Tile t, Owner o, DiagDirection d, RoadType road_rt, R * @param t the entrance of the tunnel * @param o the owner of the entrance * @param d the direction facing out of the tunnel - * @param r the rail type used in the tunnel + * @param map_railtype the map rail type used in the tunnel */ -inline void MakeRailTunnel(Tile t, Owner o, DiagDirection d, RailType r) +inline void MakeRailTunnel(Tile t, Owner o, DiagDirection d, MapRailType map_railtype) { SetTileType(t, MP_TUNNELBRIDGE); SetTileOwner(t, o); @@ -81,7 +81,7 @@ inline void MakeRailTunnel(Tile t, Owner o, DiagDirection d, RailType r) SB(t.m6(), 2, 6, 0); t.m7() = 0; t.m8() = 0; - SetRailType(t, r); + SetMapRailType(t, map_railtype); } #endif /* TUNNEL_MAP_H */ diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 74f277af7964f..06b0ca8d0b67c 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -311,6 +311,8 @@ CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex t { CompanyID company = _current_company; + MapRailType map_railtype = RailTypeMapping::INVALID_MAP_TYPE; + if (!IsValidTile(tile_start)) return CommandCost(STR_ERROR_BRIDGE_THROUGH_MAP_BORDER); /* type of bridge */ @@ -321,6 +323,8 @@ CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex t case TRANSPORT_RAIL: if (!ValParamRailType(railtype)) return CMD_ERROR; + map_railtype = _railtype_mapping.AllocateMapType(railtype, flags.Test(DoCommandFlag::Execute)); + if (map_railtype == RailTypeMapping::INVALID_MAP_TYPE) return CommandCost{STR_ERROR_TOO_MANY_RAILTYPES}; break; case TRANSPORT_WATER: @@ -538,8 +542,8 @@ CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex t case TRANSPORT_RAIL: /* Add to company infrastructure count if required. */ if (is_new_owner && c != nullptr) c->infrastructure.rail[railtype] += bridge_len * TUNNELBRIDGE_TRACKBIT_FACTOR; - MakeRailBridgeRamp(tile_start, owner, bridge_type, dir, railtype); - MakeRailBridgeRamp(tile_end, owner, bridge_type, ReverseDiagDir(dir), railtype); + MakeRailBridgeRamp(tile_start, owner, bridge_type, dir, map_railtype); + MakeRailBridgeRamp(tile_end, owner, bridge_type, ReverseDiagDir(dir), map_railtype); SetTunnelBridgeReservation(tile_start, pbs_reservation); SetTunnelBridgeReservation(tile_end, pbs_reservation); break; @@ -638,10 +642,14 @@ CommandCost CmdBuildTunnel(DoCommandFlags flags, TileIndex start_tile, Transport { CompanyID company = _current_company; + MapRailType map_railtype = RailTypeMapping::INVALID_MAP_TYPE; + _build_tunnel_endtile = TileIndex{}; switch (transport_type) { case TRANSPORT_RAIL: if (!ValParamRailType(railtype)) return CMD_ERROR; + map_railtype = _railtype_mapping.AllocateMapType(railtype, flags.Test(DoCommandFlag::Execute)); + if (map_railtype == RailTypeMapping::INVALID_MAP_TYPE) return CommandCost{STR_ERROR_TOO_MANY_RAILTYPES}; break; case TRANSPORT_ROAD: @@ -781,8 +789,8 @@ CommandCost CmdBuildTunnel(DoCommandFlags flags, TileIndex start_tile, Transport uint num_pieces = (tiles + 2) * TUNNELBRIDGE_TRACKBIT_FACTOR; if (transport_type == TRANSPORT_RAIL) { if (c != nullptr) c->infrastructure.rail[railtype] += num_pieces; - MakeRailTunnel(start_tile, company, direction, railtype); - MakeRailTunnel(end_tile, company, ReverseDiagDir(direction), railtype); + MakeRailTunnel(start_tile, company, direction, map_railtype); + MakeRailTunnel(end_tile, company, ReverseDiagDir(direction), map_railtype); AddSideToSignalBuffer(start_tile, INVALID_DIAGDIR, company); YapfNotifyTrackLayoutChange(start_tile, DiagDirToDiagTrack(direction)); } else { diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index 1a0dba435dea5..a0f61bfafc4d5 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -307,7 +307,7 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlags flags, TileIndex start_tile, Axi bool reserved = IsTileType(tile, MP_RAILWAY) ? HasBit(GetRailReservationTrackBits(tile), AxisToTrack(axis)) : HasStationReservation(tile); - MakeRailWaypoint(tile, wp->owner, wp->index, axis, *it++, GetRailType(tile)); + MakeRailWaypoint(tile, wp->owner, wp->index, axis, *it++, GetMapRailType(tile)); SetCustomStationSpecIndex(tile, *specindex); SetRailStationTileFlags(tile, spec); From 768f470e05d4ec276186b7d0fd0500ad8f171cc1 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 16 Sep 2025 13:20:07 +0100 Subject: [PATCH 135/137] Codechange: Allocate map roadtypes dynamically. --- src/bridge_map.h | 8 +-- src/lang/english.txt | 2 + src/misc.cpp | 2 + src/newgrf_railtype.cpp | 1 + src/newgrf_roadtype.cpp | 57 ++++++++++++++---- src/newgrf_roadtype.h | 1 + src/rail_cmd.cpp | 20 +++---- src/road.cpp | 3 + src/road_cmd.cpp | 69 +++++++++++++++------ src/road_map.h | 109 ++++++++++++++++++---------------- src/road_type.h | 14 +++++ src/saveload/afterload.cpp | 20 +++++-- src/saveload/labelmaps_sl.cpp | 23 ++++++- src/station_cmd.cpp | 36 ++++++----- src/station_map.h | 16 ++--- src/tunnel_map.h | 7 ++- src/tunnelbridge_cmd.cpp | 26 ++++++-- src/waypoint_cmd.cpp | 18 +++--- 18 files changed, 292 insertions(+), 140 deletions(-) diff --git a/src/bridge_map.h b/src/bridge_map.h index 35ecd8f65311e..28ca5f052c264 100644 --- a/src/bridge_map.h +++ b/src/bridge_map.h @@ -148,15 +148,15 @@ inline void MakeBridgeRamp(Tile t, Owner o, BridgeType bridgetype, DiagDirection * @param owner_tram the new owner of the tram on the bridge * @param bridgetype the type of bridge this bridge ramp belongs to * @param d the direction this ramp must be facing - * @param road_rt the road type of the bridge - * @param tram_rt the tram type of the bridge + * @param map_roadtype the map road type of the bridge + * @param map_tramtype the map tram type of the bridge */ -inline void MakeRoadBridgeRamp(Tile t, Owner o, Owner owner_road, Owner owner_tram, BridgeType bridgetype, DiagDirection d, RoadType road_rt, RoadType tram_rt) +inline void MakeRoadBridgeRamp(Tile t, Owner o, Owner owner_road, Owner owner_tram, BridgeType bridgetype, DiagDirection d, MapRoadType map_roadtype, MapTramType map_tramtype) { MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_ROAD); SetRoadOwner(t, RTT_ROAD, owner_road); if (owner_tram != OWNER_TOWN) SetRoadOwner(t, RTT_TRAM, owner_tram); - SetRoadTypes(t, road_rt, tram_rt); + SetMapRoadTypes(t, map_roadtype, map_tramtype); } /** diff --git a/src/lang/english.txt b/src/lang/english.txt index 674fca7c6169f..fa25b4009e50d 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -5248,6 +5248,8 @@ STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Can't co STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Can't convert tram type here... STR_ERROR_NO_SUITABLE_ROAD :{WHITE}No suitable road STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}No suitable tramway +STR_ERROR_TOO_MANY_ROADTYPES :{WHITE}... too many road types in use +STR_ERROR_TOO_MANY_TRAMTYPES :{WHITE}... too many tram types in use # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Can't build canals here... diff --git a/src/misc.cpp b/src/misc.cpp index 96f17f0362725..f95ccbca1a641 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -169,4 +169,6 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin _gamelog.StopAction(); _railtype_mapping.Init(); + _roadtype_mapping.Init(); + _tramtype_mapping.Init(); } diff --git a/src/newgrf_railtype.cpp b/src/newgrf_railtype.cpp index 583b83be2847a..4f9e003a88f10 100644 --- a/src/newgrf_railtype.cpp +++ b/src/newgrf_railtype.cpp @@ -17,6 +17,7 @@ #include "depot_base.h" #include "town.h" #include "tunnelbridge_map.h" +#include "company_base.h" #include "safeguards.h" diff --git a/src/newgrf_roadtype.cpp b/src/newgrf_roadtype.cpp index 6b40a1e0d83b0..f2ea462923961 100644 --- a/src/newgrf_roadtype.cpp +++ b/src/newgrf_roadtype.cpp @@ -218,13 +218,28 @@ uint8_t GetReverseRoadTypeTranslation(RoadType roadtype, const GRFFile *grffile) std::vector> _roadtype_list; +void PreloadRoadTypeMaps() +{ + _roadtype_mapping.Init(); + _tramtype_mapping.Init(); + for (auto it = std::begin(_roadtype_list); it != std::end(_roadtype_list); ++it) { + RoadType rt = GetRoadTypeByLabel(it->label); + if (rt == INVALID_ROADTYPE) continue; + + RoadTramType rtt = GetRoadTramType(rt); + if (rtt == RTT_ROAD) _roadtype_mapping.Set(static_cast(std::distance(std::begin(_roadtype_list), it)), rt); + if (rtt == RTT_TRAM) _tramtype_mapping.Set(static_cast(std::distance(std::begin(_roadtype_list), it)), rt); + } +} + /** * Test if any saved road type labels are different to the currently loaded * road types. Road types stored in the map will be converted if necessary. */ void ConvertRoadTypes() { - std::vector roadtype_conversion_map; + std::vector roadtype_conversion_map; + std::vector tramtype_conversion_map; bool needs_conversion = false; for (auto it = std::begin(_roadtype_list); it != std::end(_roadtype_list); ++it) { RoadType rt = GetRoadTypeByLabel(it->label); @@ -232,31 +247,46 @@ void ConvertRoadTypes() rt = it->subtype ? ROADTYPE_TRAM : ROADTYPE_ROAD; } - roadtype_conversion_map.push_back(rt); + if (it->subtype == 0) { + roadtype_conversion_map.push_back(_roadtype_mapping.AllocateMapType(rt, true)); + + if (it->label == 0) continue; + if (needs_conversion) continue; - /* Conversion is needed if the road type is in a different position than the list. */ - if (it->label != 0 && rt != std::distance(std::begin(_roadtype_list), it)) needs_conversion = true; + /* Conversion is needed if the road type is in a different position than the list. */ + if (_roadtype_mapping.GetMappedType(rt).base() != it->index) needs_conversion = true; + } + + if (it->subtype == 1) { + tramtype_conversion_map.push_back(_tramtype_mapping.AllocateMapType(rt, true)); + + if (it->label == 0) continue; + if (needs_conversion) continue; + + /* Conversion is needed if the road type is in a different position than the list. */ + if (_tramtype_mapping.GetMappedType(rt).base() != it->index) needs_conversion = true; + } } if (!needs_conversion) return; for (TileIndex t : Map::Iterate()) { switch (GetTileType(t)) { case MP_ROAD: - if (RoadType rt = GetRoadTypeRoad(t); rt != INVALID_ROADTYPE) SetRoadTypeRoad(t, roadtype_conversion_map[rt]); - if (RoadType rt = GetRoadTypeTram(t); rt != INVALID_ROADTYPE) SetRoadTypeTram(t, roadtype_conversion_map[rt]); + if (RoadType rt = GetRoadTypeRoad(t); rt != INVALID_ROADTYPE) SetMapRoadTypeRoad(t, roadtype_conversion_map[rt]); + if (RoadType rt = GetRoadTypeTram(t); rt != INVALID_ROADTYPE) SetMapRoadTypeTram(t, tramtype_conversion_map[rt]); break; case MP_STATION: if (IsAnyRoadStop(t)) { - if (RoadType rt = GetRoadTypeRoad(t); rt != INVALID_ROADTYPE) SetRoadTypeRoad(t, roadtype_conversion_map[rt]); - if (RoadType rt = GetRoadTypeTram(t); rt != INVALID_ROADTYPE) SetRoadTypeTram(t, roadtype_conversion_map[rt]); + if (RoadType rt = GetRoadTypeRoad(t); rt != INVALID_ROADTYPE) SetMapRoadTypeRoad(t, roadtype_conversion_map[rt]); + if (RoadType rt = GetRoadTypeTram(t); rt != INVALID_ROADTYPE) SetMapRoadTypeTram(t, tramtype_conversion_map[rt]); } break; case MP_TUNNELBRIDGE: if (GetTunnelBridgeTransportType(t) == TRANSPORT_ROAD) { - if (RoadType rt = GetRoadTypeRoad(t); rt != INVALID_ROADTYPE) SetRoadTypeRoad(t, roadtype_conversion_map[rt]); - if (RoadType rt = GetRoadTypeTram(t); rt != INVALID_ROADTYPE) SetRoadTypeTram(t, roadtype_conversion_map[rt]); + if (RoadType rt = GetRoadTypeRoad(t); rt != INVALID_ROADTYPE) SetMapRoadTypeRoad(t, roadtype_conversion_map[rt]); + if (RoadType rt = GetRoadTypeTram(t); rt != INVALID_ROADTYPE) SetMapRoadTypeTram(t, tramtype_conversion_map[rt]); } break; @@ -271,7 +301,12 @@ void SetCurrentRoadTypeLabelList() { _roadtype_list.clear(); for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { - _roadtype_list.emplace_back(GetRoadTypeInfo(rt)->label, GetRoadTramType(rt)); + if (MapRoadType map_roadtype = _roadtype_mapping.GetMappedType(rt); map_roadtype != RoadTypeMapping::INVALID_MAP_TYPE) { + _roadtype_list.emplace_back(GetRoadTypeInfo(rt)->label, map_roadtype.base(), GetRoadTramType(rt)); + } + if (MapTramType map_tramtype = _tramtype_mapping.GetMappedType(rt); map_tramtype != TramTypeMapping::INVALID_MAP_TYPE) { + _roadtype_list.emplace_back(GetRoadTypeInfo(rt)->label, map_tramtype.base(), GetRoadTramType(rt)); + } } } diff --git a/src/newgrf_roadtype.h b/src/newgrf_roadtype.h index e0fc039856af6..82ab8b8b9aa63 100644 --- a/src/newgrf_roadtype.h +++ b/src/newgrf_roadtype.h @@ -64,5 +64,6 @@ uint32_t GetTrackTypes(TileIndex tile, const GRFFile *grffile); void ConvertRoadTypes(); void SetCurrentRoadTypeLabelList(); void ClearRoadTypeLabelList(); +void PreloadRoadTypeMaps(); #endif /* NEWGRF_ROADTYPE_H */ diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index b3924c19a02bb..898345e470a10 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -508,11 +508,11 @@ CommandCost CmdBuildSingleRail(DoCommandFlags flags, TileIndex tile, RailType ra if (RailNoLevelCrossings(railtype)) return CommandCost(STR_ERROR_CROSSING_DISALLOWED_RAIL); - RoadType roadtype_road = GetRoadTypeRoad(tile); - RoadType roadtype_tram = GetRoadTypeTram(tile); + MapRoadType map_roadtype = GetMapRoadTypeRoad(tile); + MapTramType map_tramtype = GetMapRoadTypeTram(tile); - if (roadtype_road != INVALID_ROADTYPE && RoadNoLevelCrossing(roadtype_road)) return CommandCost(STR_ERROR_CROSSING_DISALLOWED_ROAD); - if (roadtype_tram != INVALID_ROADTYPE && RoadNoLevelCrossing(roadtype_tram)) return CommandCost(STR_ERROR_CROSSING_DISALLOWED_ROAD); + if (map_roadtype != RoadTypeMapping::INVALID_MAP_TYPE && RoadNoLevelCrossing(_roadtype_mapping.GetType(map_roadtype))) return CommandCost(STR_ERROR_CROSSING_DISALLOWED_ROAD); + if (map_tramtype != TramTypeMapping::INVALID_MAP_TYPE && RoadNoLevelCrossing(_tramtype_mapping.GetType(map_tramtype))) return CommandCost(STR_ERROR_CROSSING_DISALLOWED_ROAD); RoadBits road = GetRoadBits(tile, RTT_ROAD); RoadBits tram = GetRoadBits(tile, RTT_TRAM); @@ -529,29 +529,29 @@ CommandCost CmdBuildSingleRail(DoCommandFlags flags, TileIndex tile, RailType ra uint num_new_road_pieces = (road != ROAD_NONE) ? 2 - CountBits(road) : 0; if (num_new_road_pieces > 0) { - cost.AddCost(num_new_road_pieces * RoadBuildCost(roadtype_road)); + cost.AddCost(num_new_road_pieces * RoadBuildCost(_roadtype_mapping.GetType(map_roadtype))); } uint num_new_tram_pieces = (tram != ROAD_NONE) ? 2 - CountBits(tram) : 0; if (num_new_tram_pieces > 0) { - cost.AddCost(num_new_tram_pieces * RoadBuildCost(roadtype_tram)); + cost.AddCost(num_new_tram_pieces * RoadBuildCost(_tramtype_mapping.GetType(map_tramtype))); } MapRailType map_railtype = _railtype_mapping.AllocateMapType(railtype, flags.Test(DoCommandFlag::Execute)); if (map_railtype == RailTypeMapping::INVALID_MAP_TYPE) return CommandCost{STR_ERROR_TOO_MANY_RAILTYPES}; if (flags.Test(DoCommandFlag::Execute)) { - MakeRoadCrossing(tile, road_owner, tram_owner, _current_company, (track == TRACK_X ? AXIS_Y : AXIS_X), map_railtype, roadtype_road, roadtype_tram, GetTownIndex(tile)); + MakeRoadCrossing(tile, road_owner, tram_owner, _current_company, (track == TRACK_X ? AXIS_Y : AXIS_X), map_railtype, map_roadtype, map_tramtype, GetTownIndex(tile)); UpdateLevelCrossing(tile, false); MarkDirtyAdjacentLevelCrossingTiles(tile, GetCrossingRoadAxis(tile)); Company::Get(_current_company)->infrastructure.rail[railtype] += LEVELCROSSING_TRACKBIT_FACTOR; DirtyCompanyInfrastructureWindows(_current_company); if (num_new_road_pieces > 0 && Company::IsValidID(road_owner)) { - Company::Get(road_owner)->infrastructure.road[roadtype_road] += num_new_road_pieces; + Company::Get(road_owner)->infrastructure.road[_roadtype_mapping.GetType(map_roadtype)] += num_new_road_pieces; DirtyCompanyInfrastructureWindows(road_owner); } if (num_new_tram_pieces > 0 && Company::IsValidID(tram_owner)) { - Company::Get(tram_owner)->infrastructure.road[roadtype_tram] += num_new_tram_pieces; + Company::Get(tram_owner)->infrastructure.road[_tramtype_mapping.GetType(map_tramtype)] += num_new_tram_pieces; DirtyCompanyInfrastructureWindows(tram_owner); } } @@ -658,7 +658,7 @@ CommandCost CmdRemoveSingleRail(DoCommandFlags flags, TileIndex tile, Track trac owner = GetTileOwner(tile); Company::Get(owner)->infrastructure.rail[GetRailType(tile)] -= LEVELCROSSING_TRACKBIT_FACTOR; DirtyCompanyInfrastructureWindows(owner); - MakeRoadNormal(tile, GetCrossingRoadBits(tile), GetRoadTypeRoad(tile), GetRoadTypeTram(tile), GetTownIndex(tile), GetRoadOwner(tile, RTT_ROAD), GetRoadOwner(tile, RTT_TRAM)); + MakeRoadNormal(tile, GetCrossingRoadBits(tile), GetMapRoadTypeRoad(tile), GetMapRoadTypeTram(tile), GetTownIndex(tile), GetRoadOwner(tile, RTT_ROAD), GetRoadOwner(tile, RTT_TRAM)); DeleteNewGRFInspectWindow(GSF_RAILTYPES, tile.base()); } break; diff --git a/src/road.cpp b/src/road.cpp index a944e0092af3b..5a115e98490c1 100644 --- a/src/road.cpp +++ b/src/road.cpp @@ -278,3 +278,6 @@ RoadType GetRoadTypeByLabel(RoadTypeLabel label, bool allow_alternate_labels) /* No matching label was found, so it is invalid */ return INVALID_ROADTYPE; } + +RoadTypeMapping _roadtype_mapping; +TramTypeMapping _tramtype_mapping; diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 3ff0b4aa08d86..7b1afa3fa9a72 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -365,8 +365,13 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlags flags, RoadBits pie /* A full diagonal road tile has two road bits. */ UpdateCompanyRoadInfrastructure(existing_rt, GetRoadOwner(tile, rtt), -(int)(len * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR)); - SetRoadType(other_end, rtt, INVALID_ROADTYPE); - SetRoadType(tile, rtt, INVALID_ROADTYPE); + if (rtt == RTT_ROAD) { + SetMapRoadTypeRoad(other_end, RoadTypeMapping::INVALID_MAP_TYPE); + SetMapRoadTypeRoad(tile, RoadTypeMapping::INVALID_MAP_TYPE); + } else { /* rtt == RTT_TRAM */ + SetMapRoadTypeTram(other_end, TramTypeMapping::INVALID_MAP_TYPE); + SetMapRoadTypeTram(tile, TramTypeMapping::INVALID_MAP_TYPE); + } /* If the owner of the bridge sells all its road, also move the ownership * to the owner of the other roadtype, unless the bridge owner is a town. */ @@ -390,7 +395,11 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlags flags, RoadBits pie if (flags.Test(DoCommandFlag::Execute)) { /* A full diagonal road tile has two road bits. */ UpdateCompanyRoadInfrastructure(existing_rt, GetRoadOwner(tile, rtt), -2); - SetRoadType(tile, rtt, INVALID_ROADTYPE); + if (rtt == RTT_ROAD) { + SetMapRoadTypeRoad(tile, RoadTypeMapping::INVALID_MAP_TYPE); + } else { /* rtt == RTT_TRAM */ + SetMapRoadTypeTram(tile, TramTypeMapping::INVALID_MAP_TYPE); + } MarkTileDirtyByTile(tile); } } @@ -459,7 +468,11 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlags flags, RoadBits pie } if (rtt == RTT_ROAD) SetDisallowedRoadDirections(tile, DRD_NONE); SetRoadBits(tile, ROAD_NONE, rtt); - SetRoadType(tile, rtt, INVALID_ROADTYPE); + if (rtt == RTT_ROAD) { + SetMapRoadTypeRoad(tile, RoadTypeMapping::INVALID_MAP_TYPE); + } else { /* rtt == RTT_TRAM */ + SetMapRoadTypeTram(tile, TramTypeMapping::INVALID_MAP_TYPE); + } MarkTileDirtyByTile(tile); } } else { @@ -505,7 +518,11 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlags flags, RoadBits pie DirtyCompanyInfrastructureWindows(c->index); } } else { - SetRoadType(tile, rtt, INVALID_ROADTYPE); + if (rtt == RTT_ROAD) { + SetMapRoadTypeRoad(tile, RoadTypeMapping::INVALID_MAP_TYPE); + } else { /* rtt == RTT_TRAM */ + SetMapRoadTypeTram(tile, TramTypeMapping::INVALID_MAP_TYPE); + } } MarkTileDirtyByTile(tile); YapfNotifyTrackLayoutChange(tile, railtrack); @@ -628,6 +645,11 @@ CommandCost CmdBuildRoad(DoCommandFlags flags, TileIndex tile, RoadBits pieces, Slope tileh = GetTileSlope(tile); RoadTramType rtt = GetRoadTramType(rt); + MapRoadType map_roadtype = rtt == RTT_ROAD ? _roadtype_mapping.AllocateMapType(rt, flags.Test(DoCommandFlag::Execute)) : RoadTypeMapping::INVALID_MAP_TYPE; + if (rtt == RTT_ROAD && map_roadtype == RoadTypeMapping::INVALID_MAP_TYPE) return CommandCost{STR_ERROR_TOO_MANY_ROADTYPES}; + MapTramType map_tramtype = rtt == RTT_TRAM ? _tramtype_mapping.AllocateMapType(rt, flags.Test(DoCommandFlag::Execute)) : TramTypeMapping::INVALID_MAP_TYPE; + if (rtt == RTT_TRAM && map_tramtype == TramTypeMapping::INVALID_MAP_TYPE) return CommandCost{STR_ERROR_TOO_MANY_TRAMTYPES}; + bool need_to_clear = false; switch (GetTileType(tile)) { case MP_ROAD: @@ -765,7 +787,7 @@ CommandCost CmdBuildRoad(DoCommandFlags flags, TileIndex tile, RoadBits pieces, /* Always add road to the roadtypes (can't draw without it) */ bool reserved = HasBit(GetRailReservationTrackBits(tile), railtrack); - MakeRoadCrossing(tile, company, company, GetTileOwner(tile), roaddir, GetMapRailType(tile), rtt == RTT_ROAD ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, town_id); + MakeRoadCrossing(tile, company, company, GetTileOwner(tile), roaddir, GetMapRailType(tile), map_roadtype, map_tramtype, town_id); SetCrossingReservation(tile, reserved); UpdateLevelCrossing(tile, false); MarkDirtyAdjacentLevelCrossingTiles(tile, GetCrossingRoadAxis(tile)); @@ -874,7 +896,7 @@ do_clear:; case MP_ROAD: { RoadTileType rttype = GetRoadTileType(tile); if (existing == ROAD_NONE || rttype == ROAD_TILE_CROSSING) { - SetRoadType(tile, rtt, rt); + SetMapRoadTypes(tile, map_roadtype, map_tramtype, rtt); SetRoadOwner(tile, rtt, company); if (rtt == RTT_ROAD) SetTownIndex(tile, town_id); } @@ -885,8 +907,8 @@ do_clear:; case MP_TUNNELBRIDGE: { TileIndex other_end = GetOtherTunnelBridgeEnd(tile); - SetRoadType(other_end, rtt, rt); - SetRoadType(tile, rtt, rt); + SetMapRoadTypes(other_end, map_roadtype, map_tramtype, rtt); + SetMapRoadTypes(tile, map_roadtype, map_tramtype, rtt); SetRoadOwner(other_end, rtt, company); SetRoadOwner(tile, rtt, company); @@ -902,13 +924,13 @@ do_clear:; case MP_STATION: { assert(IsDriveThroughStopTile(tile)); - SetRoadType(tile, rtt, rt); + SetMapRoadTypes(tile, map_roadtype, map_tramtype, rtt); SetRoadOwner(tile, rtt, company); break; } default: - MakeRoadNormal(tile, pieces, (rtt == RTT_ROAD) ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, town_id, company, company); + MakeRoadNormal(tile, pieces, map_roadtype, map_tramtype, town_id, company, company); break; } @@ -1172,12 +1194,19 @@ CommandCost CmdBuildRoadDepot(DoCommandFlags flags, TileIndex tile, RoadType rt, if (!Depot::CanAllocateItem()) return CMD_ERROR; } + RoadTramType rtt = GetRoadTramType(rt); + + MapRoadType map_roadtype = rtt == RTT_ROAD ? _roadtype_mapping.AllocateMapType(rt, flags.Test(DoCommandFlag::Execute)) : RoadTypeMapping::INVALID_MAP_TYPE; + if (rtt == RTT_ROAD && map_roadtype == RoadTypeMapping::INVALID_MAP_TYPE) return CommandCost{STR_ERROR_TOO_MANY_ROADTYPES}; + MapTramType map_tramtype = rtt == RTT_TRAM ? _tramtype_mapping.AllocateMapType(rt, flags.Test(DoCommandFlag::Execute)) : TramTypeMapping::INVALID_MAP_TYPE; + if (rtt == RTT_TRAM && map_tramtype == TramTypeMapping::INVALID_MAP_TYPE) return CommandCost{STR_ERROR_TOO_MANY_TRAMTYPES}; + if (flags.Test(DoCommandFlag::Execute)) { if (rotate_existing_depot) { SetRoadDepotExitDirection(tile, dir); } else { Depot *dep = new Depot(tile); - MakeRoadDepot(tile, _current_company, dep->index, dir, rt); + MakeRoadDepot(tile, _current_company, dep->index, dir, map_roadtype, map_tramtype); MakeDefaultName(dep); /* A road depot has two road bits. */ @@ -2071,8 +2100,9 @@ static void TileLoop_Road(TileIndex tile) /* Possibly change road type */ if (GetRoadOwner(tile, RTT_ROAD) == OWNER_TOWN) { RoadType rt = GetTownRoadType(); - if (rt != GetRoadTypeRoad(tile)) { - SetRoadType(tile, RTT_ROAD, rt); + MapRoadType map_roadtype = _roadtype_mapping.AllocateMapType(rt, true); + if (map_roadtype != RoadTypeMapping::INVALID_MAP_TYPE && map_roadtype != GetMapRoadTypeRoad(tile)) { + SetMapRoadTypeRoad(tile, map_roadtype); } } @@ -2445,6 +2475,11 @@ CommandCost CmdConvertRoad(DoCommandFlags flags, TileIndex tile, TileIndex area_ CommandCost error = CommandCost((rtt == RTT_TRAM) ? STR_ERROR_NO_SUITABLE_TRAMWAY : STR_ERROR_NO_SUITABLE_ROAD); // by default, there is no road to convert. bool found_convertible_road = false; // whether we actually did convert any road/tram (see bug #7633) + MapRoadType map_roadtype = rtt == RTT_ROAD ? _roadtype_mapping.AllocateMapType(to_type, flags.Test(DoCommandFlag::Execute)) : RoadTypeMapping::INVALID_MAP_TYPE; + if (rtt == RTT_ROAD && map_roadtype == RoadTypeMapping::INVALID_MAP_TYPE) return CommandCost{STR_ERROR_TOO_MANY_ROADTYPES}; + MapTramType map_tramtype = rtt == RTT_TRAM ? _tramtype_mapping.AllocateMapType(to_type, flags.Test(DoCommandFlag::Execute)) : TramTypeMapping::INVALID_MAP_TYPE; + if (rtt == RTT_TRAM && map_tramtype == TramTypeMapping::INVALID_MAP_TYPE) return CommandCost{STR_ERROR_TOO_MANY_TRAMTYPES}; + std::unique_ptr iter = TileIterator::Create(area_start, area_end, diagonal); for (; (tile = *iter) != INVALID_TILE; ++(*iter)) { /* Is road present on tile? */ @@ -2530,7 +2565,7 @@ CommandCost CmdConvertRoad(DoCommandFlags flags, TileIndex tile, TileIndex area_ } /* Perform the conversion */ - SetRoadType(tile, rtt, to_type); + SetMapRoadTypes(tile, map_roadtype, map_tramtype, rtt); MarkTileDirtyByTile(tile); /* update power of train on this tile */ @@ -2590,8 +2625,8 @@ CommandCost CmdConvertRoad(DoCommandFlags flags, TileIndex tile, TileIndex area_ } /* Perform the conversion */ - SetRoadType(tile, rtt, to_type); - SetRoadType(endtile, rtt, to_type); + SetMapRoadTypes(tile, map_roadtype, map_tramtype, rtt); + SetMapRoadTypes(endtile, map_roadtype, map_tramtype, rtt); for (Vehicle *v : VehiclesOnTile(tile)) { if (v->type == VEH_ROAD) include(affected_rvs, RoadVehicle::From(v)->First()); diff --git a/src/road_map.h b/src/road_map.h index aed2cd2090d53..98924e02c5ef3 100644 --- a/src/road_map.h +++ b/src/road_map.h @@ -17,7 +17,6 @@ #include "tile_map.h" #include "road_type.h" - /** The different types of road tiles. */ enum RoadTileType : uint8_t { ROAD_TILE_NORMAL, ///< Normal road @@ -144,21 +143,31 @@ inline void SetRoadBits(Tile t, RoadBits r, RoadTramType rtt) } } -inline RoadType GetRoadTypeRoad(Tile t) +inline MapRoadType GetMapRoadTypeRoad(Tile t) { assert(MayHaveRoad(t)); - return (RoadType)GB(t.m4(), 0, 6); + return static_cast(GB(t.m4(), 0, 6)); } -inline RoadType GetRoadTypeTram(Tile t) +inline MapTramType GetMapRoadTypeTram(Tile t) { assert(MayHaveRoad(t)); - return (RoadType)GB(t.m8(), 6, 6); + return static_cast(GB(t.m8(), 6, 6)); +} + +inline RoadType GetRoadTypeRoad(Tile t) +{ + return _roadtype_mapping.GetType(GetMapRoadTypeRoad(t)); +} + +inline RoadType GetRoadTypeTram(Tile t) +{ + return _tramtype_mapping.GetType(GetMapRoadTypeTram(t)); } inline RoadType GetRoadType(Tile t, RoadTramType rtt) { - return (rtt == RTT_TRAM) ? GetRoadTypeTram(t) : GetRoadTypeRoad(t); + return (rtt == RTT_ROAD) ? GetRoadTypeRoad(t) : GetRoadTypeTram(t); } /** @@ -170,20 +179,20 @@ inline RoadTypes GetPresentRoadTypes(Tile t) { RoadTypes result{}; if (MayHaveRoad(t)) { - if (GetRoadTypeRoad(t) != INVALID_ROADTYPE) result.Set(GetRoadTypeRoad(t)); - if (GetRoadTypeTram(t) != INVALID_ROADTYPE) result.Set(GetRoadTypeTram(t)); + if (GetMapRoadTypeRoad(t) != RoadTypeMapping::INVALID_MAP_TYPE) result.Set(_roadtype_mapping.GetType(GetMapRoadTypeRoad(t))); + if (GetMapRoadTypeTram(t) != TramTypeMapping::INVALID_MAP_TYPE) result.Set(_tramtype_mapping.GetType(GetMapRoadTypeTram(t))); } return result; } inline bool HasRoadTypeRoad(Tile t) { - return GetRoadTypeRoad(t) != INVALID_ROADTYPE; + return GetMapRoadTypeRoad(t) != RoadTypeMapping::INVALID_MAP_TYPE; } inline bool HasRoadTypeTram(Tile t) { - return GetRoadTypeTram(t) != INVALID_ROADTYPE; + return GetMapRoadTypeTram(t) != TramTypeMapping::INVALID_MAP_TYPE; } /** @@ -554,75 +563,72 @@ RoadBits GetAnyRoadBits(Tile tile, RoadTramType rtt, bool straight_tunnel_bridge /** * Set the road road type of a tile. * @param t The tile to change. - * @param rt The road type to set. + * @param map_roadtype The map road type to set. */ -inline void SetRoadTypeRoad(Tile t, RoadType rt) +inline void SetMapRoadTypeRoad(Tile t, MapRoadType map_roadtype) { assert(MayHaveRoad(t)); - assert(rt == INVALID_ROADTYPE || RoadTypeIsRoad(rt)); - SB(t.m4(), 0, 6, rt); + SB(t.m4(), 0, 6, map_roadtype.base()); } /** * Set the tram road type of a tile. * @param t The tile to change. - * @param rt The road type to set. + * @param map_tramtype The map tram type to set. */ -inline void SetRoadTypeTram(Tile t, RoadType rt) +inline void SetMapRoadTypeTram(Tile t, MapTramType map_tramtype) { assert(MayHaveRoad(t)); - assert(rt == INVALID_ROADTYPE || RoadTypeIsTram(rt)); - SB(t.m8(), 6, 6, rt); + SB(t.m8(), 6, 6, map_tramtype.base()); } /** - * Set the road type of a tile. - * @param t The tile to change. - * @param rtt Set road or tram type. - * @param rt The road type to set. + * Set the present road types of a tile. + * @param t The tile to change. + * @param map_roadtype The map road type to set for the tile. + * @param map_tramtype The map tram type to set for the tile. */ -inline void SetRoadType(Tile t, RoadTramType rtt, RoadType rt) +inline void SetMapRoadTypes(Tile t, MapRoadType map_roadtype, MapTramType map_tramtype) { - if (rtt == RTT_TRAM) { - SetRoadTypeTram(t, rt); - } else { - SetRoadTypeRoad(t, rt); - } + SetMapRoadTypeRoad(t, map_roadtype); + SetMapRoadTypeTram(t, map_tramtype); } + /** - * Set the present road types of a tile. + * Conditionally Set the present road types of a tile. * @param t The tile to change. - * @param road_rt The road roadtype to set for the tile. - * @param tram_rt The tram roadtype to set for the tile. + * @param map_roadtype The map road type to set for the tile. + * @param map_tramtype The map tram type to set for the tile. + * @param rtts Road Tram type bits to set. */ -inline void SetRoadTypes(Tile t, RoadType road_rt, RoadType tram_rt) +inline void SetMapRoadTypes(Tile t, MapRoadType map_roadtype, MapTramType map_tramtype, RoadTramType rtt) { - SetRoadTypeRoad(t, road_rt); - SetRoadTypeTram(t, tram_rt); + if (rtt == RTT_ROAD) SetMapRoadTypeRoad(t, map_roadtype); + if (rtt == RTT_TRAM) SetMapRoadTypeTram(t, map_tramtype); } /** * Make a normal road tile. * @param t Tile to make a normal road. * @param bits Road bits to set for all present road types. - * @param road_rt The road roadtype to set for the tile. - * @param tram_rt The tram roadtype to set for the tile. + * @param map_roadtype The map road type to set for the tile. + * @param map_tramtype The map tram type to set for the tile. * @param town Town ID if the road is a town-owned road. * @param road New owner of road. * @param tram New owner of tram tracks. */ -inline void MakeRoadNormal(Tile t, RoadBits bits, RoadType road_rt, RoadType tram_rt, TownID town, Owner road, Owner tram) +inline void MakeRoadNormal(Tile t, RoadBits bits, MapRoadType map_roadtype, MapTramType map_tramtype, TownID town, Owner road, Owner tram) { SetTileType(t, MP_ROAD); SetTileOwner(t, road); t.m2() = town.base(); - t.m3() = (tram_rt != INVALID_ROADTYPE ? bits : 0); - t.m5() = (road_rt != INVALID_ROADTYPE ? bits : 0) | ROAD_TILE_NORMAL << 6; + t.m3() = (map_tramtype != TramTypeMapping::INVALID_MAP_TYPE ? bits : 0); + t.m5() = (map_roadtype != RoadTypeMapping::INVALID_MAP_TYPE ? bits : 0) | ROAD_TILE_NORMAL << 6; SB(t.m6(), 2, 6, 0); t.m7() = 0; t.m8() = 0; - SetRoadTypes(t, road_rt, tram_rt); + SetMapRoadTypes(t, map_roadtype, map_tramtype); SetRoadOwner(t, RTT_TRAM, tram); } @@ -634,22 +640,22 @@ inline void MakeRoadNormal(Tile t, RoadBits bits, RoadType road_rt, RoadType tra * @param rail New owner of the rail track. * @param roaddir Axis of the road. * @param map_railtype New map rail type. - * @param road_rt The road roadtype to set for the tile. - * @param tram_rt The tram roadtype to set for the tile. + * @param map_roadtype The map road type to set for the tile. + * @param map_tramtype The map tram type to set for the tile. * @param town Town ID if the road is a town-owned road. */ -inline void MakeRoadCrossing(Tile t, Owner road, Owner tram, Owner rail, Axis roaddir, MapRailType map_railtype, RoadType road_rt, RoadType tram_rt, TownID town) +inline void MakeRoadCrossing(Tile t, Owner road, Owner tram, Owner rail, Axis roaddir, MapRailType map_railtype, MapRoadType map_roadtype, MapTramType map_tramtype, TownID town) { SetTileType(t, MP_ROAD); SetTileOwner(t, rail); t.m2() = town.base(); t.m3() = 0; - t.m4() = INVALID_ROADTYPE; + t.m4() = RoadTypeMapping::INVALID_MAP_TYPE.base(); t.m5() = ROAD_TILE_CROSSING << 6 | roaddir; SB(t.m6(), 2, 6, 0); t.m7() = road.base(); - t.m8() = INVALID_ROADTYPE << 6 | map_railtype.base(); - SetRoadTypes(t, road_rt, tram_rt); + t.m8() = TramTypeMapping::INVALID_MAP_TYPE.base() << 6 | map_railtype.base(); + SetMapRoadTypes(t, map_roadtype, map_tramtype); SetRoadOwner(t, RTT_TRAM, tram); } @@ -670,20 +676,21 @@ inline void SetRoadDepotExitDirection(Tile tile, DiagDirection dir) * @param owner New owner of the depot. * @param depot_id New depot ID. * @param dir Direction of the depot exit. - * @param rt Road type of the depot. + * @param map_roadtype Map road type of the depot. + * @param map_tramtype Map road type of the depot. */ -inline void MakeRoadDepot(Tile tile, Owner owner, DepotID depot_id, DiagDirection dir, RoadType rt) +inline void MakeRoadDepot(Tile tile, Owner owner, DepotID depot_id, DiagDirection dir, MapRoadType map_roadtype, MapTramType map_tramtype) { SetTileType(tile, MP_ROAD); SetTileOwner(tile, owner); tile.m2() = depot_id.base(); tile.m3() = 0; - tile.m4() = INVALID_ROADTYPE; + tile.m4() = RoadTypeMapping::INVALID_MAP_TYPE.base(); tile.m5() = ROAD_TILE_DEPOT << 6 | dir; SB(tile.m6(), 2, 6, 0); tile.m7() = owner.base(); - tile.m8() = INVALID_ROADTYPE << 6; - SetRoadType(tile, GetRoadTramType(rt), rt); + tile.m8() = TramTypeMapping::INVALID_MAP_TYPE.base() << 6; + SetMapRoadTypes(tile, map_roadtype, map_tramtype); SetRoadOwner(tile, RTT_TRAM, owner); } diff --git a/src/road_type.h b/src/road_type.h index 99b5f8a40bdbd..75ed42fefc304 100644 --- a/src/road_type.h +++ b/src/road_type.h @@ -11,6 +11,7 @@ #define ROAD_TYPE_H #include "core/enum_type.hpp" +#include "transport_mapping.hpp" typedef uint32_t RoadTypeLabel; @@ -83,4 +84,17 @@ enum DisallowedRoadDirections : uint8_t { }; DECLARE_ENUM_AS_BIT_SET(DisallowedRoadDirections) +/** Mapped road type. */ +using RoadTypeMapping = TransportMapping; +extern RoadTypeMapping _roadtype_mapping; + +/** Mapped tram type. */ +using TramTypeMapping = TransportMapping; +extern TramTypeMapping _tramtype_mapping; + +/** Alias for mapped road type. */ +using MapRoadType = RoadTypeMapping::MapType; +/** Alias for mapped tram type. */ +using MapTramType = TramTypeMapping::MapType; + #endif /* ROAD_TYPE_H */ diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index c867b827c52ff..9d1c80728b391 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -51,6 +51,7 @@ #include "../subsidy_func.h" #include "../newgrf.h" #include "../newgrf_railtype.h" +#include "../newgrf_roadtype.h" #include "../newgrf_station.h" #include "../engine_func.h" #include "../rail_gui.h" @@ -561,6 +562,12 @@ static void ConvertTransportMappings() auto convert_railtype = [](TileIndex t) { SetMapRailType(t, _railtype_mapping.AllocateMapType(static_cast(GetMapRailType(t).base()), true)); }; + auto convert_roadtype = [](TileIndex t) { + /* Tiles with roads have a sentinel value to indicate that road or tram is not used. */ + if (auto mrt = GetMapRoadTypeRoad(t); mrt != RoadTypeMapping::INVALID_MAP_TYPE) SetMapRoadTypeRoad(t, _roadtype_mapping.AllocateMapType(static_cast(mrt.base()), true)); + if (auto mtt = GetMapRoadTypeTram(t); mtt != TramTypeMapping::INVALID_MAP_TYPE) SetMapRoadTypeTram(t, _tramtype_mapping.AllocateMapType(static_cast(mtt.base()), true)); + }; + for (auto t : Map::Iterate()) { switch (GetTileType(t)) { case MP_RAILWAY: @@ -568,16 +575,19 @@ static void ConvertTransportMappings() break; case MP_ROAD: + convert_roadtype(t); if (IsLevelCrossingTile(t)) convert_railtype(t); break; case MP_STATION: if (HasStationRail(t)) convert_railtype(t); + if (IsAnyRoadStop(t)) convert_roadtype(t); break; case MP_TUNNELBRIDGE: switch (GetTunnelBridgeTransportType(t)) { case TRANSPORT_RAIL: convert_railtype(t); break; + case TRANSPORT_ROAD: convert_roadtype(t); break; default: break; } break; @@ -1355,11 +1365,12 @@ bool AfterLoadGame() } if (has_road) { - RoadType road_rt = HasBit(t.m7(), 6) ? ROADTYPE_ROAD : INVALID_ROADTYPE; - RoadType tram_rt = HasBit(t.m7(), 7) ? ROADTYPE_TRAM : INVALID_ROADTYPE; + /* Conversion from road type to mapped road type happens later. */ + MapRoadType map_roadtype = HasBit(t.m7(), 6) ? static_cast(ROADTYPE_ROAD) : RoadTypeMapping::INVALID_MAP_TYPE; + MapTramType map_tramtype = HasBit(t.m7(), 7) ? static_cast(ROADTYPE_TRAM) : TramTypeMapping::INVALID_MAP_TYPE; - assert(road_rt != INVALID_ROADTYPE || tram_rt != INVALID_ROADTYPE); - SetRoadTypes(t, road_rt, tram_rt); + assert(map_roadtype != RoadTypeMapping::INVALID_MAP_TYPE || map_tramtype != TramTypeMapping::INVALID_MAP_TYPE); + SetMapRoadTypes(t, map_roadtype, map_tramtype); SB(t.m7(), 6, 2, 0); // Clear pre-NRT road type bits. } } @@ -1408,6 +1419,7 @@ bool AfterLoadGame() } PreloadRailTypeMaps(); + PreloadRoadTypeMaps(); if (IsSavegameVersionBefore(SLV_TRANSPORT_TYPE_MAPPING)) { ConvertTransportMappings(); } diff --git a/src/saveload/labelmaps_sl.cpp b/src/saveload/labelmaps_sl.cpp index 2f4100044a5d6..3d11f6befd568 100644 --- a/src/saveload/labelmaps_sl.cpp +++ b/src/saveload/labelmaps_sl.cpp @@ -85,6 +85,7 @@ struct ROTTChunkHandler : ChunkHandler { static inline const SaveLoad description[] = { SLE_VAR(LabelObject, label, SLE_UINT32), + SLE_VAR(LabelObject, index, SLE_UINT8), SLE_VAR(LabelObject, subtype, SLE_UINT8), }; @@ -92,13 +93,28 @@ struct ROTTChunkHandler : ChunkHandler { { SlTableHeader(description); + int index = 0; LabelObject lo; for (RoadType r = ROADTYPE_BEGIN; r != ROADTYPE_END; r++) { const RoadTypeInfo *rti = GetRoadTypeInfo(r); + if (rti->label == 0) continue; + + if (GetRoadTramType(r) == RTT_ROAD) { + MapRoadType map_roadtype = _roadtype_mapping.GetMappedType(rti->Index()); + if (map_roadtype == RoadTypeMapping::INVALID_MAP_TYPE) continue; + + lo.index = map_roadtype.base(); + } else { + MapTramType map_tramtype = _tramtype_mapping.GetMappedType(rti->Index()); + if (map_tramtype == TramTypeMapping::INVALID_MAP_TYPE) continue; + + lo.index = map_tramtype.base(); + } + lo.label = rti->label; lo.subtype = GetRoadTramType(r); - SlSetArrayIndex(r); + SlSetArrayIndex(index++); SlObject(&lo, description); } } @@ -106,13 +122,16 @@ struct ROTTChunkHandler : ChunkHandler { void Load() const override { const std::vector slt = SlCompatTableHeader(description, _label_object_sl_compat); + bool convert = IsSavegameVersionBefore(SLV_TRANSPORT_TYPE_MAPPING); _roadtype_list.reserve(ROADTYPE_END); LabelObject lo; - while (SlIterateArray() != -1) { + int index; + while ((index = SlIterateArray()) != -1) { SlObject(&lo, slt); + if (convert) lo.index = index; _roadtype_list.push_back(lo); } } diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 6e9621237d9a1..0569a3a709348 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -2131,15 +2131,21 @@ CommandCost CmdBuildRoadStop(DoCommandFlags flags, TileIndex tile, uint8_t width } } + RoadTramType rtt = GetRoadTramType(rt); + MapRoadType new_map_roadtype = rtt == RTT_ROAD ? _roadtype_mapping.AllocateMapType(rt, flags.Test(DoCommandFlag::Execute)) : RoadTypeMapping::INVALID_MAP_TYPE; + if (rtt == RTT_ROAD && new_map_roadtype == RoadTypeMapping::INVALID_MAP_TYPE) return CommandCost{STR_ERROR_TOO_MANY_ROADTYPES}; + MapTramType new_map_tramtype = rtt == RTT_TRAM ? _tramtype_mapping.AllocateMapType(rt, flags.Test(DoCommandFlag::Execute)) : TramTypeMapping::INVALID_MAP_TYPE; + if (rtt == RTT_TRAM && new_map_tramtype == TramTypeMapping::INVALID_MAP_TYPE) return CommandCost{STR_ERROR_TOO_MANY_TRAMTYPES}; + if (flags.Test(DoCommandFlag::Execute)) { if (specindex.has_value()) AssignSpecToRoadStop(roadstopspec, st, *specindex); /* Check every tile in the area. */ for (TileIndex cur_tile : roadstop_area) { /* Get existing road types and owners before any tile clearing */ - RoadType road_rt = MayHaveRoad(cur_tile) ? GetRoadType(cur_tile, RTT_ROAD) : INVALID_ROADTYPE; - RoadType tram_rt = MayHaveRoad(cur_tile) ? GetRoadType(cur_tile, RTT_TRAM) : INVALID_ROADTYPE; - Owner road_owner = road_rt != INVALID_ROADTYPE ? GetRoadOwner(cur_tile, RTT_ROAD) : _current_company; - Owner tram_owner = tram_rt != INVALID_ROADTYPE ? GetRoadOwner(cur_tile, RTT_TRAM) : _current_company; + MapRoadType cur_map_roadtype = MayHaveRoad(cur_tile) ? GetMapRoadTypeRoad(cur_tile) : RoadTypeMapping::INVALID_MAP_TYPE; + MapTramType cur_map_tramtype = MayHaveRoad(cur_tile) ? GetMapRoadTypeTram(cur_tile) : TramTypeMapping::INVALID_MAP_TYPE; + Owner road_owner = cur_map_roadtype != RoadTypeMapping::INVALID_MAP_TYPE ? GetRoadOwner(cur_tile, RTT_ROAD) : _current_company; + Owner tram_owner = cur_map_tramtype != TramTypeMapping::INVALID_MAP_TYPE ? GetRoadOwner(cur_tile, RTT_TRAM) : _current_company; if (IsTileType(cur_tile, MP_STATION) && IsStationRoadStop(cur_tile)) { RemoveRoadStop(cur_tile, flags, *specindex); @@ -2172,22 +2178,22 @@ CommandCost CmdBuildRoadStop(DoCommandFlags flags, TileIndex tile, uint8_t width /* Update company infrastructure counts. If the current tile is a normal road tile, remove the old * bits first. */ if (IsNormalRoadTile(cur_tile)) { - UpdateCompanyRoadInfrastructure(road_rt, road_owner, -(int)CountBits(GetRoadBits(cur_tile, RTT_ROAD))); - UpdateCompanyRoadInfrastructure(tram_rt, tram_owner, -(int)CountBits(GetRoadBits(cur_tile, RTT_TRAM))); + UpdateCompanyRoadInfrastructure(_roadtype_mapping.GetType(cur_map_roadtype), road_owner, -(int)CountBits(GetRoadBits(cur_tile, RTT_ROAD))); + UpdateCompanyRoadInfrastructure(_tramtype_mapping.GetType(cur_map_tramtype), tram_owner, -(int)CountBits(GetRoadBits(cur_tile, RTT_TRAM))); } - if (road_rt == INVALID_ROADTYPE && RoadTypeIsRoad(rt)) road_rt = rt; - if (tram_rt == INVALID_ROADTYPE && RoadTypeIsTram(rt)) tram_rt = rt; + if (cur_map_roadtype == RoadTypeMapping::INVALID_MAP_TYPE && RoadTypeIsRoad(rt)) cur_map_roadtype = new_map_roadtype; + if (cur_map_tramtype == TramTypeMapping::INVALID_MAP_TYPE && RoadTypeIsTram(rt)) cur_map_tramtype = new_map_tramtype; - MakeDriveThroughRoadStop(cur_tile, st->owner, road_owner, tram_owner, st->index, (rs_type == RoadStopType::Bus ? StationType::Bus : StationType::Truck), road_rt, tram_rt, axis); + MakeDriveThroughRoadStop(cur_tile, st->owner, road_owner, tram_owner, st->index, (rs_type == RoadStopType::Bus ? StationType::Bus : StationType::Truck), cur_map_roadtype, cur_map_tramtype, axis); road_stop->MakeDriveThrough(); } else { - if (road_rt == INVALID_ROADTYPE && RoadTypeIsRoad(rt)) road_rt = rt; - if (tram_rt == INVALID_ROADTYPE && RoadTypeIsTram(rt)) tram_rt = rt; - MakeRoadStop(cur_tile, st->owner, st->index, rs_type, road_rt, tram_rt, ddir); + if (cur_map_roadtype == RoadTypeMapping::INVALID_MAP_TYPE && RoadTypeIsRoad(rt)) cur_map_roadtype = new_map_roadtype; + if (cur_map_tramtype == TramTypeMapping::INVALID_MAP_TYPE && RoadTypeIsTram(rt)) cur_map_tramtype = new_map_tramtype; + MakeRoadStop(cur_tile, st->owner, st->index, rs_type, cur_map_roadtype, cur_map_tramtype, ddir); } - UpdateCompanyRoadInfrastructure(road_rt, road_owner, ROAD_STOP_TRACKBIT_FACTOR); - UpdateCompanyRoadInfrastructure(tram_rt, tram_owner, ROAD_STOP_TRACKBIT_FACTOR); + UpdateCompanyRoadInfrastructure(_roadtype_mapping.GetType(cur_map_roadtype), road_owner, ROAD_STOP_TRACKBIT_FACTOR); + UpdateCompanyRoadInfrastructure(_tramtype_mapping.GetType(cur_map_tramtype), tram_owner, ROAD_STOP_TRACKBIT_FACTOR); Company::Get(st->owner)->infrastructure.station++; SetCustomRoadStopSpecIndex(cur_tile, *specindex); @@ -2443,7 +2449,7 @@ static CommandCost RemoveGenericRoadStop(DoCommandFlags flags, const TileArea &r /* Restore roads. */ if (flags.Test(DoCommandFlag::Execute) && (road_type[RTT_ROAD] != INVALID_ROADTYPE || road_type[RTT_TRAM] != INVALID_ROADTYPE)) { - MakeRoadNormal(cur_tile, road_bits, road_type[RTT_ROAD], road_type[RTT_TRAM], ClosestTownFromTile(cur_tile, UINT_MAX)->index, + MakeRoadNormal(cur_tile, road_bits, _roadtype_mapping.GetMappedType(road_type[RTT_ROAD]), _tramtype_mapping.GetMappedType(road_type[RTT_TRAM]), ClosestTownFromTile(cur_tile, UINT_MAX)->index, road_owner[RTT_ROAD], road_owner[RTT_TRAM]); /* Update company infrastructure counts. */ diff --git a/src/station_map.h b/src/station_map.h index 15b5b468decb0..2095df3f2897f 100644 --- a/src/station_map.h +++ b/src/station_map.h @@ -769,14 +769,14 @@ inline void MakeRailWaypoint(Tile t, Owner o, StationID sid, Axis a, uint8_t sec * @param o the owner of the roadstop * @param sid the station to which this tile belongs * @param rst the type of roadstop to make this tile - * @param road_rt the road roadtype on this tile - * @param tram_rt the tram roadtype on this tile + * @param map_roadtype the map road type on this tile + * @param map_tramtype the map tram type on this tile * @param d the direction of the roadstop */ -inline void MakeRoadStop(Tile t, Owner o, StationID sid, RoadStopType rst, RoadType road_rt, RoadType tram_rt, DiagDirection d) +inline void MakeRoadStop(Tile t, Owner o, StationID sid, RoadStopType rst, MapRoadType map_roadtype, MapTramType map_tramtype, DiagDirection d) { MakeStation(t, o, sid, (rst == RoadStopType::Bus ? StationType::Bus : StationType::Truck), d); - SetRoadTypes(t, road_rt, tram_rt); + SetMapRoadTypes(t, map_roadtype, map_tramtype); SetRoadOwner(t, RTT_ROAD, o); SetRoadOwner(t, RTT_TRAM, o); } @@ -789,14 +789,14 @@ inline void MakeRoadStop(Tile t, Owner o, StationID sid, RoadStopType rst, RoadT * @param tram the owner of the tram * @param sid the station to which this tile belongs * @param rst the type of roadstop to make this tile - * @param road_rt the road roadtype on this tile - * @param tram_rt the tram roadtype on this tile + * @param map_roadtype the map road type on this tile + * @param map_tramtype the map tram type on this tile * @param a the direction of the roadstop */ -inline void MakeDriveThroughRoadStop(Tile t, Owner station, Owner road, Owner tram, StationID sid, StationType rst, RoadType road_rt, RoadType tram_rt, Axis a) +inline void MakeDriveThroughRoadStop(Tile t, Owner station, Owner road, Owner tram, StationID sid, StationType rst, MapRoadType map_roadtype, MapTramType map_tramtype, Axis a) { MakeStation(t, station, sid, rst, GFX_TRUCK_BUS_DRIVETHROUGH_OFFSET + a); - SetRoadTypes(t, road_rt, tram_rt); + SetMapRoadTypes(t, map_roadtype, map_tramtype); SetRoadOwner(t, RTT_ROAD, road); SetRoadOwner(t, RTT_TRAM, tram); } diff --git a/src/tunnel_map.h b/src/tunnel_map.h index 94cf70a013da0..ba8841103fb12 100644 --- a/src/tunnel_map.h +++ b/src/tunnel_map.h @@ -45,9 +45,10 @@ bool IsTunnelInWayDir(TileIndex tile, int z, DiagDirection dir); * @param t the entrance of the tunnel * @param o the owner of the entrance * @param d the direction facing out of the tunnel - * @param r the road type used in the tunnel + * @param map_roadtype the map road type used in the tunnel + * @param map_tramtype the map tram type used in the tunnel */ -inline void MakeRoadTunnel(Tile t, Owner o, DiagDirection d, RoadType road_rt, RoadType tram_rt) +inline void MakeRoadTunnel(Tile t, Owner o, DiagDirection d, MapRoadType map_roadtype, MapTramType map_tramtype) { SetTileType(t, MP_TUNNELBRIDGE); SetTileOwner(t, o); @@ -60,7 +61,7 @@ inline void MakeRoadTunnel(Tile t, Owner o, DiagDirection d, RoadType road_rt, R t.m8() = 0; SetRoadOwner(t, RTT_ROAD, o); if (o != OWNER_TOWN) SetRoadOwner(t, RTT_TRAM, o); - SetRoadTypes(t, road_rt, tram_rt); + SetMapRoadTypes(t, map_roadtype, map_tramtype); } /** diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 06b0ca8d0b67c..d45cd828ee2ea 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -312,6 +312,9 @@ CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex t CompanyID company = _current_company; MapRailType map_railtype = RailTypeMapping::INVALID_MAP_TYPE; + RoadTramType rtt = RTT_ROAD; + MapRoadType map_roadtype = RoadTypeMapping::INVALID_MAP_TYPE; + MapTramType map_tramtype = TramTypeMapping::INVALID_MAP_TYPE; if (!IsValidTile(tile_start)) return CommandCost(STR_ERROR_BRIDGE_THROUGH_MAP_BORDER); @@ -319,6 +322,11 @@ CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex t switch (transport_type) { case TRANSPORT_ROAD: if (!ValParamRoadType(roadtype)) return CMD_ERROR; + rtt = GetRoadTramType(roadtype); + map_roadtype = rtt == RTT_ROAD ? _roadtype_mapping.AllocateMapType(roadtype, flags.Test(DoCommandFlag::Execute)) : RoadTypeMapping::INVALID_MAP_TYPE; + if (rtt == RTT_ROAD && map_roadtype == RoadTypeMapping::INVALID_MAP_TYPE) return CommandCost{STR_ERROR_TOO_MANY_ROADTYPES}; + map_tramtype = rtt == RTT_TRAM ? _tramtype_mapping.AllocateMapType(roadtype, flags.Test(DoCommandFlag::Execute)) : TramTypeMapping::INVALID_MAP_TYPE; + if (rtt == RTT_TRAM && map_tramtype == TramTypeMapping::INVALID_MAP_TYPE) return CommandCost{STR_ERROR_TOO_MANY_TRAMTYPES}; break; case TRANSPORT_RAIL: @@ -567,8 +575,8 @@ CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex t } Owner owner_road = hasroad ? GetRoadOwner(tile_start, RTT_ROAD) : company; Owner owner_tram = hastram ? GetRoadOwner(tile_start, RTT_TRAM) : company; - MakeRoadBridgeRamp(tile_start, owner, owner_road, owner_tram, bridge_type, dir, road_rt, tram_rt); - MakeRoadBridgeRamp(tile_end, owner, owner_road, owner_tram, bridge_type, ReverseDiagDir(dir), road_rt, tram_rt); + MakeRoadBridgeRamp(tile_start, owner, owner_road, owner_tram, bridge_type, dir, map_roadtype, map_tramtype); + MakeRoadBridgeRamp(tile_end, owner, owner_road, owner_tram, bridge_type, ReverseDiagDir(dir), map_roadtype, map_tramtype); break; } @@ -643,6 +651,9 @@ CommandCost CmdBuildTunnel(DoCommandFlags flags, TileIndex start_tile, Transport CompanyID company = _current_company; MapRailType map_railtype = RailTypeMapping::INVALID_MAP_TYPE; + RoadTramType rtt = RTT_ROAD; + MapRoadType map_roadtype = RoadTypeMapping::INVALID_MAP_TYPE; + MapTramType map_tramtype = TramTypeMapping::INVALID_MAP_TYPE; _build_tunnel_endtile = TileIndex{}; switch (transport_type) { @@ -654,6 +665,11 @@ CommandCost CmdBuildTunnel(DoCommandFlags flags, TileIndex start_tile, Transport case TRANSPORT_ROAD: if (!ValParamRoadType(roadtype)) return CMD_ERROR; + rtt = GetRoadTramType(roadtype); + map_roadtype = rtt == RTT_ROAD ? _roadtype_mapping.AllocateMapType(roadtype, flags.Test(DoCommandFlag::Execute)) : RoadTypeMapping::INVALID_MAP_TYPE; + if (rtt == RTT_ROAD && map_roadtype == RoadTypeMapping::INVALID_MAP_TYPE) return CommandCost{STR_ERROR_TOO_MANY_ROADTYPES}; + map_tramtype = rtt == RTT_TRAM ? _tramtype_mapping.AllocateMapType(roadtype, flags.Test(DoCommandFlag::Execute)) : TramTypeMapping::INVALID_MAP_TYPE; + if (rtt == RTT_TRAM && map_tramtype == TramTypeMapping::INVALID_MAP_TYPE) return CommandCost{STR_ERROR_TOO_MANY_TRAMTYPES}; break; default: return CMD_ERROR; @@ -795,10 +811,8 @@ CommandCost CmdBuildTunnel(DoCommandFlags flags, TileIndex start_tile, Transport YapfNotifyTrackLayoutChange(start_tile, DiagDirToDiagTrack(direction)); } else { if (c != nullptr) c->infrastructure.road[roadtype] += num_pieces * 2; // A full diagonal road has two road bits. - RoadType road_rt = RoadTypeIsRoad(roadtype) ? roadtype : INVALID_ROADTYPE; - RoadType tram_rt = RoadTypeIsTram(roadtype) ? roadtype : INVALID_ROADTYPE; - MakeRoadTunnel(start_tile, company, direction, road_rt, tram_rt); - MakeRoadTunnel(end_tile, company, ReverseDiagDir(direction), road_rt, tram_rt); + MakeRoadTunnel(start_tile, company, direction, map_roadtype, map_tramtype); + MakeRoadTunnel(end_tile, company, ReverseDiagDir(direction), map_roadtype, map_tramtype); } DirtyCompanyInfrastructureWindows(company); } diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index a0f61bfafc4d5..cce1da5e2d309 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -428,10 +428,10 @@ CommandCost CmdBuildRoadWaypoint(DoCommandFlags flags, TileIndex start_tile, Axi /* Check every tile in the area. */ for (TileIndex cur_tile : roadstop_area) { /* Get existing road types and owners before any tile clearing */ - RoadType road_rt = MayHaveRoad(cur_tile) ? GetRoadType(cur_tile, RTT_ROAD) : INVALID_ROADTYPE; - RoadType tram_rt = MayHaveRoad(cur_tile) ? GetRoadType(cur_tile, RTT_TRAM) : INVALID_ROADTYPE; - Owner road_owner = road_rt != INVALID_ROADTYPE ? GetRoadOwner(cur_tile, RTT_ROAD) : _current_company; - Owner tram_owner = tram_rt != INVALID_ROADTYPE ? GetRoadOwner(cur_tile, RTT_TRAM) : _current_company; + MapRoadType map_roadtype = MayHaveRoad(cur_tile) ? GetMapRoadTypeRoad(cur_tile) : RoadTypeMapping::INVALID_MAP_TYPE; + MapTramType map_tramtype = MayHaveRoad(cur_tile) ? GetMapRoadTypeTram(cur_tile) : TramTypeMapping::INVALID_MAP_TYPE; + Owner road_owner = map_roadtype != RoadTypeMapping::INVALID_MAP_TYPE ? GetRoadOwner(cur_tile, RTT_ROAD) : _current_company; + Owner tram_owner = map_tramtype != TramTypeMapping::INVALID_MAP_TYPE ? GetRoadOwner(cur_tile, RTT_TRAM) : _current_company; if (IsRoadWaypointTile(cur_tile)) { RemoveRoadWaypointStop(cur_tile, flags, *specindex); @@ -444,14 +444,14 @@ CommandCost CmdBuildRoadWaypoint(DoCommandFlags flags, TileIndex start_tile, Axi /* Update company infrastructure counts. If the current tile is a normal road tile, remove the old * bits first. */ if (IsNormalRoadTile(cur_tile)) { - UpdateCompanyRoadInfrastructure(road_rt, road_owner, -(int)CountBits(GetRoadBits(cur_tile, RTT_ROAD))); - UpdateCompanyRoadInfrastructure(tram_rt, tram_owner, -(int)CountBits(GetRoadBits(cur_tile, RTT_TRAM))); + UpdateCompanyRoadInfrastructure(_roadtype_mapping.GetType(map_roadtype), road_owner, -(int)CountBits(GetRoadBits(cur_tile, RTT_ROAD))); + UpdateCompanyRoadInfrastructure(_tramtype_mapping.GetType(map_tramtype), tram_owner, -(int)CountBits(GetRoadBits(cur_tile, RTT_TRAM))); } - UpdateCompanyRoadInfrastructure(road_rt, road_owner, ROAD_STOP_TRACKBIT_FACTOR); - UpdateCompanyRoadInfrastructure(tram_rt, tram_owner, ROAD_STOP_TRACKBIT_FACTOR); + UpdateCompanyRoadInfrastructure(_roadtype_mapping.GetType(map_roadtype), road_owner, ROAD_STOP_TRACKBIT_FACTOR); + UpdateCompanyRoadInfrastructure(_tramtype_mapping.GetType(map_tramtype), tram_owner, ROAD_STOP_TRACKBIT_FACTOR); - MakeDriveThroughRoadStop(cur_tile, wp->owner, road_owner, tram_owner, wp->index, StationType::RoadWaypoint, road_rt, tram_rt, axis); + MakeDriveThroughRoadStop(cur_tile, wp->owner, road_owner, tram_owner, wp->index, StationType::RoadWaypoint, map_roadtype, map_tramtype, axis); SetCustomRoadStopSpecIndex(cur_tile, *specindex); if (roadstopspec != nullptr) wp->SetRoadStopRandomBits(cur_tile, 0); From 3a1a56dce5c38dac881f1da80b9e6ddea1998d9f Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 26 Sep 2025 08:37:11 +0100 Subject: [PATCH 136/137] Codechange: Keep track of infrastructure 'cost' for unowned road pieces. This uses the same cost factors as owned road pieces for consistency. --- src/rail_cmd.cpp | 22 ++++++++++++++++------ src/road.h | 5 +++++ src/road_cmd.cpp | 18 +++++++++++++----- src/saveload/company_sl.cpp | 24 ++++++++++++++++++++---- src/station_cmd.cpp | 6 +++++- src/tunnelbridge_cmd.cpp | 30 ++++++++++++++++++++++-------- 6 files changed, 81 insertions(+), 24 deletions(-) diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 898345e470a10..9d4132258bacb 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -546,13 +546,23 @@ CommandCost CmdBuildSingleRail(DoCommandFlags flags, TileIndex tile, RailType ra MarkDirtyAdjacentLevelCrossingTiles(tile, GetCrossingRoadAxis(tile)); Company::Get(_current_company)->infrastructure.rail[railtype] += LEVELCROSSING_TRACKBIT_FACTOR; DirtyCompanyInfrastructureWindows(_current_company); - if (num_new_road_pieces > 0 && Company::IsValidID(road_owner)) { - Company::Get(road_owner)->infrastructure.road[_roadtype_mapping.GetType(map_roadtype)] += num_new_road_pieces; - DirtyCompanyInfrastructureWindows(road_owner); + if (num_new_road_pieces > 0) { + RoadType roadtype = _roadtype_mapping.GetType(map_roadtype); + if (Company::IsValidID(road_owner)) { + Company::Get(road_owner)->infrastructure.road[roadtype] += num_new_road_pieces; + DirtyCompanyInfrastructureWindows(road_owner); + } else { + RoadTypeInfo::infrastructure_counts[roadtype] += num_new_road_pieces; + } } - if (num_new_tram_pieces > 0 && Company::IsValidID(tram_owner)) { - Company::Get(tram_owner)->infrastructure.road[_tramtype_mapping.GetType(map_tramtype)] += num_new_tram_pieces; - DirtyCompanyInfrastructureWindows(tram_owner); + if (num_new_tram_pieces > 0) { + RoadType tramtype = _tramtype_mapping.GetType(map_tramtype); + if (Company::IsValidID(tram_owner)) { + Company::Get(tram_owner)->infrastructure.road[tramtype] += num_new_tram_pieces; + DirtyCompanyInfrastructureWindows(tram_owner); + } else { + RoadTypeInfo::infrastructure_counts[tramtype] += num_new_tram_pieces; + } } } break; diff --git a/src/road.h b/src/road.h index 4918d7cc80c07..b05525766d1c3 100644 --- a/src/road.h +++ b/src/road.h @@ -174,6 +174,11 @@ class RoadTypeInfo { } RoadType Index() const; + + /** + * Infrastructure counts for unowned road pieces. + */ + static inline std::map infrastructure_counts{}; }; /** diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 7b1afa3fa9a72..21f667dfa5c81 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -182,10 +182,12 @@ void UpdateCompanyRoadInfrastructure(RoadType rt, Owner o, int count) if (rt == INVALID_ROADTYPE) return; Company *c = Company::GetIfValid(o); - if (c == nullptr) return; - - c->infrastructure.road[rt] += count; - DirtyCompanyInfrastructureWindows(c->index); + if (c != nullptr) { + c->infrastructure.road[rt] += count; + DirtyCompanyInfrastructureWindows(c->index); + } else { + RoadTypeInfo::infrastructure_counts[rt] += count; + } } /** Invalid RoadBits on slopes. */ @@ -2346,7 +2348,11 @@ static void ChangeTileOwner_Road(TileIndex tile, Owner old_owner, Owner new_owne /* A level crossing has two road bits. No need to dirty windows here, we'll redraw the whole screen anyway. */ uint num_bits = IsLevelCrossing(tile) ? 2 : CountBits(GetRoadBits(tile, rtt)); Company::Get(old_owner)->infrastructure.road[rt] -= num_bits; - if (new_owner != INVALID_OWNER) Company::Get(new_owner)->infrastructure.road[rt] += num_bits; + if (new_owner != INVALID_OWNER) { + Company::Get(new_owner)->infrastructure.road[rt] += num_bits; + } else { + RoadTypeInfo::infrastructure_counts[rt] += num_bits; + } } SetRoadOwner(tile, rtt, new_owner == INVALID_OWNER ? OWNER_NONE : new_owner); @@ -2438,6 +2444,8 @@ static void ConvertRoadTypeOwner(TileIndex tile, uint num_pieces, Owner owner, R switch (owner.base()) { case OWNER_NONE.base(): + RoadTypeInfo::infrastructure_counts[from_type] += num_pieces; + RoadTypeInfo::infrastructure_counts[to_type] += num_pieces; SetRoadOwner(tile, GetRoadTramType(to_type), (Owner)_current_company); UpdateCompanyRoadInfrastructure(to_type, _current_company, num_pieces); break; diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index 5ed2a63111519..e171acea4a304 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -127,6 +127,7 @@ void AfterLoadCompanyStats() { /* Reset infrastructure statistics to zero. */ for (Company *c : Company::Iterate()) c->infrastructure = {}; + RoadTypeInfo::infrastructure_counts.clear(); /* Collect airport count. */ for (const Station *st : Station::Iterate()) { @@ -163,9 +164,16 @@ void AfterLoadCompanyStats() for (RoadTramType rtt : _roadtramtypes) { RoadType rt = GetRoadType(tile, rtt); if (rt == INVALID_ROADTYPE) continue; - c = Company::GetIfValid(IsRoadDepot(tile) ? GetTileOwner(tile) : GetRoadOwner(tile, rtt)); + /* A level crossings and depots have two road bits. */ - if (c != nullptr) c->infrastructure.road[rt] += IsNormalRoad(tile) ? CountBits(GetRoadBits(tile, rtt)) : 2; + uint num_pieces = IsNormalRoad(tile) ? CountBits(GetRoadBits(tile, rtt)) : 2; + + c = Company::GetIfValid(IsRoadDepot(tile) ? GetTileOwner(tile) : GetRoadOwner(tile, rtt)); + if (c != nullptr) { + c->infrastructure.road[rt] += num_pieces; + } else { + RoadTypeInfo::infrastructure_counts[rt] += num_pieces; + } } break; } @@ -188,7 +196,11 @@ void AfterLoadCompanyStats() RoadType rt = GetRoadType(tile, rtt); if (rt == INVALID_ROADTYPE) continue; c = Company::GetIfValid(GetRoadOwner(tile, rtt)); - if (c != nullptr) c->infrastructure.road[rt] += 2; // A road stop has two road bits. + if (c != nullptr) { + c->infrastructure.road[rt] += 2; // A road stop has two road bits. + } else { + RoadTypeInfo::infrastructure_counts[rt] += 2; + } } break; } @@ -246,7 +258,11 @@ void AfterLoadCompanyStats() RoadType rt = GetRoadType(tile, rtt); if (rt == INVALID_ROADTYPE) continue; c = Company::GetIfValid(GetRoadOwner(tile, rtt)); - if (c != nullptr) c->infrastructure.road[rt] += len * 2; // A full diagonal road has two road bits. + if (c != nullptr) { + c->infrastructure.road[rt] += len * 2; // A full diagonal road has two road bits. + } else { + RoadTypeInfo::infrastructure_counts[rt] += len * 2; + } } break; } diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 0569a3a709348..8509e15607663 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -4722,7 +4722,11 @@ static void ChangeTileOwner_Station(TileIndex tile, Owner old_owner, Owner new_o if (rt != INVALID_ROADTYPE) { /* A drive-through road-stop has always two road bits. No need to dirty windows here, we'll redraw the whole screen anyway. */ Company::Get(old_owner)->infrastructure.road[rt] -= 2; - if (new_owner != INVALID_OWNER) Company::Get(new_owner)->infrastructure.road[rt] += 2; + if (new_owner != INVALID_OWNER) { + Company::Get(new_owner)->infrastructure.road[rt] += 2; + } else { + RoadTypeInfo::infrastructure_counts[rt] += 2; + } } SetRoadOwner(tile, rtt, new_owner == INVALID_OWNER ? OWNER_NONE : new_owner); } diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index d45cd828ee2ea..a1bb27c0e9073 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -562,15 +562,21 @@ CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex t if (hasroad && GetRoadOwner(tile_start, RTT_ROAD) == OWNER_NONE) hasroad = false; if (hastram && GetRoadOwner(tile_start, RTT_TRAM) == OWNER_NONE) hastram = false; } - if (c != nullptr) { - /* Add all new road types to the company infrastructure counter. */ - if (!hasroad && road_rt != INVALID_ROADTYPE) { - /* A full diagonal road tile has two road bits. */ + /* Add all new road types to the company infrastructure counter. */ + if (!hasroad && road_rt != INVALID_ROADTYPE) { + /* A full diagonal road tile has two road bits. */ + if (c != nullptr) { c->infrastructure.road[road_rt] += bridge_len * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR; + } else { + RoadTypeInfo::infrastructure_counts[road_rt] += bridge_len * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR; } - if (!hastram && tram_rt != INVALID_ROADTYPE) { - /* A full diagonal road tile has two road bits. */ + } + if (!hastram && tram_rt != INVALID_ROADTYPE) { + /* A full diagonal road tile has two road bits. */ + if (c != nullptr) { c->infrastructure.road[tram_rt] += bridge_len * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR; + } else { + RoadTypeInfo::infrastructure_counts[tram_rt] += bridge_len * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR; } } Owner owner_road = hasroad ? GetRoadOwner(tile_start, RTT_ROAD) : company; @@ -810,7 +816,11 @@ CommandCost CmdBuildTunnel(DoCommandFlags flags, TileIndex start_tile, Transport AddSideToSignalBuffer(start_tile, INVALID_DIAGDIR, company); YapfNotifyTrackLayoutChange(start_tile, DiagDirToDiagTrack(direction)); } else { - if (c != nullptr) c->infrastructure.road[roadtype] += num_pieces * 2; // A full diagonal road has two road bits. + if (c != nullptr) { + c->infrastructure.road[roadtype] += num_pieces * 2; // A full diagonal road has two road bits. + } else { + RoadTypeInfo::infrastructure_counts[roadtype] += num_pieces * 2; + } MakeRoadTunnel(start_tile, company, direction, map_roadtype, map_tramtype); MakeRoadTunnel(end_tile, company, ReverseDiagDir(direction), map_roadtype, map_tramtype); } @@ -1890,7 +1900,11 @@ static void ChangeTileOwner_TunnelBridge(TileIndex tile, Owner old_owner, Owner /* Update company infrastructure counts. A full diagonal road tile has two road bits. * No need to dirty windows here, we'll redraw the whole screen anyway. */ Company::Get(old_owner)->infrastructure.road[rt] -= num_pieces * 2; - if (new_owner != INVALID_OWNER) Company::Get(new_owner)->infrastructure.road[rt] += num_pieces * 2; + if (new_owner != INVALID_OWNER) { + Company::Get(new_owner)->infrastructure.road[rt] += num_pieces * 2; + } else { + RoadTypeInfo::infrastructure_counts[rt] += num_pieces * 2; + } } SetRoadOwner(tile, rtt, new_owner == INVALID_OWNER ? OWNER_NONE : new_owner); From 684b1c22702e8fe6feb4bbf110a38efb5c15eb78 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 7 Sep 2025 22:40:27 +0100 Subject: [PATCH 137/137] Feature: Increase rail and road type definitions limit. --- src/console_cmds.cpp | 4 +- src/core/flatset_type.hpp | 57 ++++++++++++++ src/engine.cpp | 12 ++- src/engine_gui.cpp | 4 +- src/newgrf.cpp | 15 ++-- src/newgrf.h | 6 +- src/newgrf/newgrf_act0_railtypes.cpp | 9 +-- src/newgrf/newgrf_act0_roadtypes.cpp | 13 ++-- src/newgrf/newgrf_act3.cpp | 6 +- src/newgrf/newgrf_actd.cpp | 14 ++-- src/newgrf_engine.cpp | 2 +- src/newgrf_railtype.cpp | 11 +-- src/newgrf_roadtype.cpp | 13 ++-- src/pathfinder/yapf/yapf_destrail.hpp | 2 +- src/pbs.cpp | 2 +- src/rail.cpp | 55 ++++++++++---- src/rail.h | 33 ++++++--- src/rail_cmd.cpp | 13 ++-- src/rail_gui.cpp | 2 +- src/rail_type.h | 10 +-- src/road.cpp | 94 ++++++++++++++++++------ src/road.h | 25 +++++-- src/road_cmd.cpp | 13 ++-- src/road_func.h | 6 +- src/road_type.h | 8 +- src/roadveh.h | 3 +- src/saveload/labelmaps_sl.cpp | 26 +++---- src/script/api/script_engine.cpp | 5 +- src/script/api/script_infrastructure.cpp | 9 +-- src/script/api/script_rail.cpp | 2 +- src/script/api/script_railtypelist.cpp | 2 +- src/script/api/script_road.cpp | 2 +- src/script/api/script_roadtypelist.cpp | 2 +- src/table/engines.h | 2 +- src/train.h | 3 +- src/transport_mapping.hpp | 8 +- 36 files changed, 322 insertions(+), 171 deletions(-) diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 7b97fab118e43..1e4479fc162b4 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -2715,7 +2715,7 @@ static void ConDumpRoadTypes() IConsolePrint(CC_DEFAULT, " T = buildable by towns"); std::map grfs; - for (RoadType rt = ROADTYPE_BEGIN; rt < ROADTYPE_END; rt++) { + for (RoadType rt = ROADTYPE_BEGIN; rt < GetNumRoadTypes(); rt++) { const RoadTypeInfo *rti = GetRoadTypeInfo(rt); if (rti->label == 0) continue; uint32_t grfid = 0; @@ -2753,7 +2753,7 @@ static void ConDumpRailTypes() IConsolePrint(CC_DEFAULT, " d = always disallow 90 degree turns"); std::map grfs; - for (RailType rt = RAILTYPE_BEGIN; rt < RAILTYPE_END; rt++) { + for (RailType rt = RAILTYPE_BEGIN; rt < GetNumRailTypes(); rt++) { const RailTypeInfo *rti = GetRailTypeInfo(rt); if (rti->label == 0) continue; uint32_t grfid = 0; diff --git a/src/core/flatset_type.hpp b/src/core/flatset_type.hpp index b69f1daebf12b..f114c302f316a 100644 --- a/src/core/flatset_type.hpp +++ b/src/core/flatset_type.hpp @@ -73,4 +73,61 @@ class FlatSet { auto operator<=>(const FlatSet &) const = default; }; +/** + * Adapter for FlatSet that provides part of the (Base)BitSet-like interface. + * @tparam Tkey key type. + * @tparam Tcompare key comparator. + */ +template > +struct FlatBitSet : FlatSet { + FlatBitSet() = default; + + FlatBitSet(Tkey value) + { + this->Set(value); + } + + FlatBitSet(std::initializer_list values) + { + for (const Tkey &value : values) { + this->Set(value); + } + } + + void Set(Tkey value) { this->insert(value); } + + void Set(Tkey value, bool set) + { + if (set) { + this->insert(value); + } else { + this->erase(value); + } + } + + bool Test(Tkey value) const { return this->contains(value); } + + bool Any() const { return this->size() != 0; } + + void Set(const FlatBitSet &other) + { + std::ranges::for_each(other, [this](const Tkey &value) { this->insert(value); }); + } + + void Reset(const FlatBitSet &other) + { + std::ranges::for_each(other, [this](const Tkey &value) { this->erase(value); }); + } + + bool Any(const FlatBitSet &other) const + { + return std::ranges::any_of(other, [this](const Tkey &value) { return this->contains(value); }); + } + + bool All(const FlatBitSet &other) const + { + return std::ranges::all_of(other, [this](const Tkey &value) { return this->contains(value); }); + } +}; + #endif /* FLATSET_TYPE_HPP */ diff --git a/src/engine.cpp b/src/engine.cpp index 15f0cfa5e9ea8..2b80951da8274 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -1108,11 +1108,17 @@ static void NewVehicleAvailable(Engine *e) /* maybe make another rail type available */ assert(e->VehInfo().railtypes != RailTypes{}); RailTypes introduced = GetAllIntroducesRailTypes(e->VehInfo().railtypes); - for (Company *c : Company::Iterate()) c->avail_railtypes = AddDateIntroducedRailTypes(c->avail_railtypes | introduced, TimerGameCalendar::date); + for (Company *c : Company::Iterate()) { + c->avail_railtypes.Set(introduced); + c->avail_railtypes = AddDateIntroducedRailTypes(c->avail_railtypes, TimerGameCalendar::date); + } } else if (e->type == VEH_ROAD) { /* maybe make another road type available */ - assert(e->VehInfo().roadtype < ROADTYPE_END); - for (Company *c : Company::Iterate()) c->avail_roadtypes = AddDateIntroducedRoadTypes(c->avail_roadtypes | GetRoadTypeInfo(e->VehInfo().roadtype)->introduces_roadtypes, TimerGameCalendar::date); + assert(e->VehInfo().roadtype < GetNumRoadTypes()); + for (Company *c : Company::Iterate()) { + c->avail_roadtypes.Set(GetRoadTypeInfo(e->VehInfo().roadtype)->introduces_roadtypes); + c->avail_roadtypes = AddDateIntroducedRoadTypes(c->avail_roadtypes, TimerGameCalendar::date); + } } /* Only broadcast event if AIs are able to build this vehicle type. */ diff --git a/src/engine_gui.cpp b/src/engine_gui.cpp index 43389f974755b..d942a7a80ed5b 100644 --- a/src/engine_gui.cpp +++ b/src/engine_gui.cpp @@ -48,7 +48,7 @@ StringID GetEngineCategoryName(EngineID engine) case VEH_SHIP: return STR_ENGINE_PREVIEW_SHIP; case VEH_TRAIN: assert(e->VehInfo().railtypes.Any()); - return GetRailTypeInfo(e->VehInfo().railtypes.GetNthSetBit(0).value())->strings.new_loco; + return GetRailTypeInfo(*e->VehInfo().railtypes.begin())->strings.new_loco; } } @@ -182,7 +182,7 @@ static std::string GetTrainEngineInfoString(const Engine &e) res << GetString(STR_ENGINE_PREVIEW_COST_WEIGHT, e.GetCost(), e.GetDisplayWeight()); res << '\n'; - if (e.VehInfo().railtypes.Count() > 1) { + if (e.VehInfo().railtypes.size() > 1) { std::string railtypes{}; std::string_view list_separator = GetListSeparator(); diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 15a06a53f40b5..ecbd4982f3944 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -581,19 +581,16 @@ GRFFile::GRFFile(const GRFConfig &config) this->price_base_multipliers.fill(INVALID_PRICE_MODIFIER); /* Initialise rail type map with default rail types */ - this->railtype_map.fill(INVALID_RAILTYPE); - this->railtype_map[0] = RAILTYPE_RAIL; - this->railtype_map[1] = RAILTYPE_ELECTRIC; - this->railtype_map[2] = RAILTYPE_MONO; - this->railtype_map[3] = RAILTYPE_MAGLEV; + this->railtype_map.emplace_back(RAILTYPE_RAIL); + this->railtype_map.emplace_back(RAILTYPE_ELECTRIC); + this->railtype_map.emplace_back(RAILTYPE_MONO); + this->railtype_map.emplace_back(RAILTYPE_MAGLEV); /* Initialise road type map with default road types */ - this->roadtype_map.fill(INVALID_ROADTYPE); - this->roadtype_map[0] = ROADTYPE_ROAD; + this->roadtype_map.emplace_back(ROADTYPE_ROAD); /* Initialise tram type map with default tram types */ - this->tramtype_map.fill(INVALID_ROADTYPE); - this->tramtype_map[0] = ROADTYPE_TRAM; + this->tramtype_map.emplace_back(ROADTYPE_TRAM); /* Copy the initial parameter list */ this->param = config.param; diff --git a/src/newgrf.h b/src/newgrf.h index beb5a0ed4f45b..97bc74dbf1bbf 100644 --- a/src/newgrf.h +++ b/src/newgrf.h @@ -140,13 +140,13 @@ struct GRFFile { std::unordered_map badge_map{}; std::vector railtype_list{}; ///< Railtype translation table - std::array railtype_map{}; + std::vector railtype_map{}; std::vector roadtype_list{}; ///< Roadtype translation table (road) - std::array roadtype_map{}; + std::vector roadtype_map{}; std::vector tramtype_list{}; ///< Roadtype translation table (tram) - std::array tramtype_map{}; + std::vector tramtype_map{}; std::array canal_local_properties{}; ///< Canal properties as set by this NewGRF diff --git a/src/newgrf/newgrf_act0_railtypes.cpp b/src/newgrf/newgrf_act0_railtypes.cpp index d37a3684eca7d..4ac6090af4929 100644 --- a/src/newgrf/newgrf_act0_railtypes.cpp +++ b/src/newgrf/newgrf_act0_railtypes.cpp @@ -28,7 +28,7 @@ static ChangeInfoResult RailTypeChangeInfo(uint first, uint last, int prop, Byte { ChangeInfoResult ret = CIR_SUCCESS; - extern RailTypeInfo _railtypes[RAILTYPE_END]; + extern std::vector _railtypes; const auto &type_map = _cur_gps.grffile->railtype_map; if (last > std::size(type_map)) { @@ -163,13 +163,10 @@ static ChangeInfoResult RailTypeReserveInfo(uint first, uint last, int prop, Byt { ChangeInfoResult ret = CIR_SUCCESS; - extern RailTypeInfo _railtypes[RAILTYPE_END]; + extern std::vector _railtypes; auto &type_map = _cur_gps.grffile->railtype_map; - if (last > std::size(type_map)) { - GrfMsg(1, "RailTypeReserveInfo: Rail type {} is invalid, max {}, ignoring", last, std::size(type_map)); - return CIR_INVALID_ID; - } + if (type_map.size() < last) type_map.resize(last, INVALID_RAILTYPE); for (uint id = first; id < last; ++id) { switch (prop) { diff --git a/src/newgrf/newgrf_act0_roadtypes.cpp b/src/newgrf/newgrf_act0_roadtypes.cpp index 4fa5746ce9bde..b3765ada7a550 100644 --- a/src/newgrf/newgrf_act0_roadtypes.cpp +++ b/src/newgrf/newgrf_act0_roadtypes.cpp @@ -29,8 +29,8 @@ static ChangeInfoResult RoadTypeChangeInfo(uint first, uint last, int prop, Byte { ChangeInfoResult ret = CIR_SUCCESS; - extern RoadTypeInfo _roadtypes[ROADTYPE_END]; - const auto &type_map = (rtt == RTT_TRAM) ? _cur_gps.grffile->tramtype_map : _cur_gps.grffile->roadtype_map; + extern std::vector _roadtypes; + auto &type_map = (rtt == RTT_TRAM) ? _cur_gps.grffile->tramtype_map : _cur_gps.grffile->roadtype_map; if (last > std::size(type_map)) { GrfMsg(1, "RoadTypeChangeInfo: Road type {} is invalid, max {}, ignoring", last, std::size(type_map)); @@ -150,13 +150,10 @@ static ChangeInfoResult RoadTypeReserveInfo(uint first, uint last, int prop, Byt { ChangeInfoResult ret = CIR_SUCCESS; - extern RoadTypeInfo _roadtypes[ROADTYPE_END]; - auto &type_map = (rtt == RTT_TRAM) ? _cur_gps.grffile->tramtype_map : _cur_gps.grffile->roadtype_map; + extern std::vector _roadtypes; + auto &type_map = (rtt == RTT_TRAM) ? _cur_gps.grffile->tramtype_map : _cur_gps.grffile->roadtype_map; - if (last > std::size(type_map)) { - GrfMsg(1, "RoadTypeReserveInfo: Road type {} is invalid, max {}, ignoring", last, std::size(type_map)); - return CIR_INVALID_ID; - } + if (type_map.size() < last) type_map.resize(last, INVALID_ROADTYPE); for (uint id = first; id < last; ++id) { switch (prop) { diff --git a/src/newgrf/newgrf_act3.cpp b/src/newgrf/newgrf_act3.cpp index 3ec90c87b768a..75aab45e812b8 100644 --- a/src/newgrf/newgrf_act3.cpp +++ b/src/newgrf/newgrf_act3.cpp @@ -272,8 +272,7 @@ struct RailTypeMapSpriteGroupHandler : MapSpriteGroupHandler { RailType railtype = local_id < std::size(type_map) ? type_map[local_id] : INVALID_RAILTYPE; if (railtype == INVALID_RAILTYPE) return; - extern RailTypeInfo _railtypes[RAILTYPE_END]; - RailTypeInfo &rti = _railtypes[railtype]; + RailTypeInfo &rti = GetRailTypeInfo()[railtype]; rti.grffile[cid] = _cur_gps.grffile; rti.group[cid] = group; } @@ -291,8 +290,7 @@ struct RoadTypeMapSpriteGroupHandler : MapSpriteGroupHandler { RoadType roadtype = local_id < std::size(type_map) ? type_map[local_id] : INVALID_ROADTYPE; if (roadtype == INVALID_ROADTYPE) return; - extern RoadTypeInfo _roadtypes[ROADTYPE_END]; - RoadTypeInfo &rti = _roadtypes[roadtype]; + RoadTypeInfo &rti = GetRoadTypeInfo()[roadtype]; rti.grffile[cid] = _cur_gps.grffile; rti.group[cid] = group; } diff --git a/src/newgrf/newgrf_actd.cpp b/src/newgrf/newgrf_actd.cpp index 8231c9a192d0c..b24d0cbc40c6f 100644 --- a/src/newgrf/newgrf_actd.cpp +++ b/src/newgrf/newgrf_actd.cpp @@ -424,16 +424,16 @@ static void ParamSet(ByteReader &buf) break; case 0x8F: { // Rail track type cost factors - extern RailTypeInfo _railtypes[RAILTYPE_END]; - _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8); + auto railtypes = GetRailTypeInfo(); + railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8); if (_settings_game.vehicle.disable_elrails) { - _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8); - _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8); + railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8); + railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8); } else { - _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8); - _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8); + railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8); + railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8); } - _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8); + railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8); break; } diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index c1f355fe1cea5..f7de1b47e6c48 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -915,7 +915,7 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec Train *t = Train::From(v); switch (variable - 0x80) { case 0x62: return t->track; - case 0x66: return t->railtypes.GetNthSetBit(0).value_or(RailType::INVALID_RAILTYPE); + case 0x66: return t->railtypes.empty() ? RailType::INVALID_RAILTYPE : *t->railtypes.begin(); case 0x73: return 0x80 + VEHICLE_LENGTH - t->gcache.cached_veh_length; case 0x74: return t->gcache.cached_power; case 0x75: return GB(t->gcache.cached_power, 8, 24); diff --git a/src/newgrf_railtype.cpp b/src/newgrf_railtype.cpp index 4f9e003a88f10..73048fd6ddfb3 100644 --- a/src/newgrf_railtype.cpp +++ b/src/newgrf_railtype.cpp @@ -154,7 +154,7 @@ RailType GetRailTypeTranslation(uint8_t railtype, const GRFFile *grffile) { 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; + if (railtype >= GetNumRailTypes() || GetRailTypeInfo(static_cast(railtype))->label == 0) return INVALID_RAILTYPE; return static_cast(railtype); } else { @@ -192,11 +192,12 @@ std::vector> _railtype_list; void PreloadRailTypeMaps() { _railtype_mapping.Init(); - for (auto it = std::begin(_railtype_list); it != std::end(_railtype_list); ++it) { - RailType rt = GetRailTypeByLabel(it->label); + for (const auto &lo : _railtype_list) { + if (lo.label == 0) continue; + RailType rt = GetRailTypeByLabel(lo.label); if (rt == INVALID_RAILTYPE) continue; - _railtype_mapping.Set(static_cast(std::distance(std::begin(_railtype_list), it)), rt); + _railtype_mapping.Set(static_cast(lo.index), rt); } } @@ -260,7 +261,7 @@ void ConvertRailTypes() void SetCurrentRailTypeLabelList() { _railtype_list.clear(); - for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { + for (RailType rt = RAILTYPE_BEGIN; rt != GetNumRailTypes(); rt++) { if (MapRailType map_railtype = _railtype_mapping.GetMappedType(rt); map_railtype != RailTypeMapping::INVALID_MAP_TYPE) { _railtype_list.emplace_back(GetRailTypeInfo(rt)->label, map_railtype.base(), 0); } diff --git a/src/newgrf_roadtype.cpp b/src/newgrf_roadtype.cpp index f2ea462923961..0395d2a862121 100644 --- a/src/newgrf_roadtype.cpp +++ b/src/newgrf_roadtype.cpp @@ -222,13 +222,16 @@ void PreloadRoadTypeMaps() { _roadtype_mapping.Init(); _tramtype_mapping.Init(); - for (auto it = std::begin(_roadtype_list); it != std::end(_roadtype_list); ++it) { - RoadType rt = GetRoadTypeByLabel(it->label); + for (const auto &lo : _roadtype_list) { + if (lo.label == 0) continue; + RoadType rt = GetRoadTypeByLabel(lo.label); if (rt == INVALID_ROADTYPE) continue; RoadTramType rtt = GetRoadTramType(rt); - if (rtt == RTT_ROAD) _roadtype_mapping.Set(static_cast(std::distance(std::begin(_roadtype_list), it)), rt); - if (rtt == RTT_TRAM) _tramtype_mapping.Set(static_cast(std::distance(std::begin(_roadtype_list), it)), rt); + if (static_cast(lo.subtype) != rtt) continue; + + if (rtt == RTT_ROAD) _roadtype_mapping.Set(static_cast(lo.index), rt); + if (rtt == RTT_TRAM) _tramtype_mapping.Set(static_cast(lo.index), rt); } } @@ -300,7 +303,7 @@ void ConvertRoadTypes() void SetCurrentRoadTypeLabelList() { _roadtype_list.clear(); - for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { + for (RoadType rt = ROADTYPE_BEGIN; rt != GetNumRoadTypes(); rt++) { if (MapRoadType map_roadtype = _roadtype_mapping.GetMappedType(rt); map_roadtype != RoadTypeMapping::INVALID_MAP_TYPE) { _roadtype_list.emplace_back(GetRoadTypeInfo(rt)->label, map_roadtype.base(), GetRoadTramType(rt)); } diff --git a/src/pathfinder/yapf/yapf_destrail.hpp b/src/pathfinder/yapf/yapf_destrail.hpp index 55a3f2bc62f0b..9677b7bec9001 100644 --- a/src/pathfinder/yapf/yapf_destrail.hpp +++ b/src/pathfinder/yapf/yapf_destrail.hpp @@ -30,7 +30,7 @@ class CYapfDestinationRailBase { return this->compatible_railtypes.Test(rt); } - RailTypes GetCompatibleRailTypes() const + const RailTypes &GetCompatibleRailTypes() const { return this->compatible_railtypes; } diff --git a/src/pbs.cpp b/src/pbs.cpp index f47c990c6d2cc..fff806b80e1f2 100644 --- a/src/pbs.cpp +++ b/src/pbs.cpp @@ -188,7 +188,7 @@ void UnreserveRailTrack(TileIndex tile, Track t) /** Follow a reservation starting from a specific tile to the end. */ -static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Trackdir trackdir, bool ignore_oneway = false) +static PBSTileInfo FollowReservation(Owner o, const RailTypes &rts, TileIndex tile, Trackdir trackdir, bool ignore_oneway = false) { TileIndex start_tile = tile; Trackdir start_trackdir = trackdir; diff --git a/src/rail.cpp b/src/rail.cpp index 175e27aeeb3c3..11a859175cf17 100644 --- a/src/rail.cpp +++ b/src/rail.cpp @@ -25,9 +25,8 @@ */ RailType RailTypeInfo::Index() const { - extern RailTypeInfo _railtypes[RAILTYPE_END]; - size_t index = this - _railtypes; - assert(index < RAILTYPE_END); + size_t index = this - GetRailTypeInfo().data(); + assert(index < GetNumRailTypes()); return static_cast(index); } @@ -89,7 +88,7 @@ bool HasAnyRailTypesAvail(const CompanyID company) */ bool ValParamRailType(const RailType rail) { - return rail < RAILTYPE_END && HasRailTypeAvail(_current_company, rail); + return rail < GetNumRailTypes() && HasRailTypeAvail(_current_company, rail); } /** @@ -99,12 +98,11 @@ bool ValParamRailType(const RailType rail) * @return The rail types that should be available when date * introduced rail types are taken into account as well. */ -RailTypes AddDateIntroducedRailTypes(RailTypes current, TimerGameCalendar::Date date) +RailTypes AddDateIntroducedRailTypes(const RailTypes ¤t, TimerGameCalendar::Date date) { - extern RailTypeInfo _railtypes[RAILTYPE_END]; RailTypes rts = current; - for (RailTypeInfo &rti : _railtypes) { + for (RailTypeInfo &rti : GetRailTypeInfo()) { /* Unused rail type. */ if (rti.label == 0) continue; @@ -115,8 +113,7 @@ RailTypes AddDateIntroducedRailTypes(RailTypes current, TimerGameCalendar::Date if (rti.introduction_date > date) continue; /* Have we introduced all required railtypes? */ - RailTypes required = rti.introduction_required_railtypes; - if (!rts.All(required)) continue; + if (!rts.All(rti.introduction_required_railtypes)) continue; rts.Set(rti.introduces_railtypes); } @@ -194,19 +191,49 @@ RailTypes GetRailTypes(bool introduces) */ RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels) { - extern RailTypeInfo _railtypes[RAILTYPE_END]; + auto railtypes = GetRailTypeInfo(); if (label == 0) return INVALID_RAILTYPE; - auto it = std::ranges::find(_railtypes, label, &RailTypeInfo::label); - if (it == std::end(_railtypes) && allow_alternate_labels) { + auto it = std::ranges::find(railtypes, label, &RailTypeInfo::label); + if (it == std::end(railtypes) && allow_alternate_labels) { /* Test if any rail type defines the label as an alternate. */ - it = std::ranges::find_if(_railtypes, [label](const RailTypeInfo &rti) { return rti.alternate_labels.contains(label); }); + it = std::ranges::find_if(railtypes, [label](const RailTypeInfo &rti) { return rti.alternate_labels.contains(label); }); } - if (it != std::end(_railtypes)) return it->Index(); + if (it != std::end(railtypes)) return it->Index(); /* No matching label was found, so it is invalid */ return INVALID_RAILTYPE; } +/** + * Get a set of rail types that are currently in use on the map. + * @return Used rail types. + */ +static RailTypes GetUsedRailTypes() +{ + RailTypes used_types; + for (const Company *c : Company::Iterate()) { + for (const auto &[railtype, count] : c->infrastructure.rail) { + if (count > 0) used_types.Set(railtype); + } + } + return used_types; +} + +/** + * Get the first unused mapped rail type position. + * @return iterator to first unused mapped rail type. + */ +template <> auto RailTypeMapping::FindUnusedMapType() -> MapStorage::iterator +{ + RailTypes used_types = GetUsedRailTypes(); + if (used_types.size() < RailTypeMapping::MAX_SIZE) { + for (auto it = std::begin(this->map); it != std::end(this->map); ++it) { + if (!used_types.contains(*it)) return it; + } + } + return std::end(this->map); +} + RailTypeMapping _railtype_mapping; diff --git a/src/rail.h b/src/rail.h index 9865f810038a1..01e70989e2a52 100644 --- a/src/rail.h +++ b/src/rail.h @@ -292,6 +292,16 @@ class RailTypeInfo { RailType Index() const; }; +inline std::span GetRailTypeInfo() +{ + extern std::vector _railtypes; + return _railtypes; +} + +inline size_t GetNumRailTypes() +{ + return std::size(GetRailTypeInfo()); +} /** * Returns a pointer to the Railtype information for a given railtype @@ -300,9 +310,8 @@ class RailTypeInfo { */ inline const RailTypeInfo *GetRailTypeInfo(RailType railtype) { - extern RailTypeInfo _railtypes[RAILTYPE_END]; - assert(railtype < RAILTYPE_END); - return &_railtypes[railtype]; + assert(railtype < GetNumRailTypes()); + return &GetRailTypeInfo()[railtype]; } /** @@ -310,7 +319,7 @@ inline const RailTypeInfo *GetRailTypeInfo(RailType railtype) * @param railtypes Set of railtypes to get the compatible railtypes from. * @return Union of all compatible railtypes. */ -inline RailTypes GetAllCompatibleRailTypes(RailTypes railtypes) +inline RailTypes GetAllCompatibleRailTypes(const RailTypes &railtypes) { RailTypes compatible{}; for (RailType rt : railtypes) compatible.Set(GetRailTypeInfo(rt)->compatible_railtypes); @@ -322,7 +331,7 @@ inline RailTypes GetAllCompatibleRailTypes(RailTypes railtypes) * @param railtypes Set of railtypes to get the powered railtypes from. * @return Union of all powered railtypes. */ -inline RailTypes GetAllPoweredRailTypes(RailTypes railtypes) +inline RailTypes GetAllPoweredRailTypes(const RailTypes &railtypes) { RailTypes powered{}; for (RailType rt : railtypes) powered.Set(GetRailTypeInfo(rt)->powered_railtypes); @@ -334,7 +343,7 @@ inline RailTypes GetAllPoweredRailTypes(RailTypes railtypes) * @param railtypes Set of railtypes to get the introduced railtypes from. * @return Union of all introduced railtypes. */ -inline RailTypes GetAllIntroducesRailTypes(RailTypes railtypes) +inline RailTypes GetAllIntroducesRailTypes(const RailTypes &railtypes) { RailTypes introduces{}; for (RailType rt : railtypes) introduces.Set(GetRailTypeInfo(rt)->introduces_railtypes); @@ -361,7 +370,7 @@ inline bool IsCompatibleRail(RailType enginetype, RailType tiletype) * @param tiletype The RailType of the tile we are considering. * @return Whether the engine can drive on this tile. */ -inline bool IsCompatibleRail(RailTypes enginetype, RailType tiletype) +inline bool IsCompatibleRail(const RailTypes &enginetype, RailType tiletype) { return GetAllCompatibleRailTypes(enginetype).Test(tiletype); } @@ -386,7 +395,7 @@ inline bool HasPowerOnRail(RailType enginetype, RailType tiletype) * @param tiletype The RailType of the tile we are considering. * @return Whether the engine got power on this tile. */ -inline bool HasPowerOnRail(RailTypes enginetype, RailType tiletype) +inline bool HasPowerOnRail(const RailTypes &enginetype, RailType tiletype) { return GetAllPoweredRailTypes(enginetype).Test(tiletype); } @@ -428,7 +437,7 @@ inline bool Rail90DegTurnDisallowed(RailType rt1, RailType rt2, bool def = _sett */ inline Money RailBuildCost(RailType railtype) { - assert(railtype < RAILTYPE_END); + assert(railtype < GetNumRailTypes()); return (_price[PR_BUILD_RAIL] * GetRailTypeInfo(railtype)->cost_multiplier) >> 3; } @@ -444,7 +453,7 @@ inline Money RailClearCost(RailType railtype) * In this case we limit the removal earnings to 3/4s of the build * cost. */ - assert(railtype < RAILTYPE_END); + assert(railtype < GetNumRailTypes()); return std::max(_price[PR_CLEAR_RAIL], -RailBuildCost(railtype) * 3 / 4); } @@ -483,7 +492,7 @@ inline Money RailConvertCost(RailType from, RailType to) */ inline Money RailMaintenanceCost(RailType railtype, uint32_t num, uint32_t total_num) { - assert(railtype < RAILTYPE_END); + assert(railtype < GetNumRailTypes()); return (_price[PR_INFRASTRUCTURE_RAIL] * GetRailTypeInfo(railtype)->maintenance_multiplier * num * (1 + IntSqrt(total_num))) >> 11; // 4 bits fraction for the multiplier and 7 bits scaling. } @@ -507,7 +516,7 @@ bool HasRailTypeAvail(const CompanyID company, const RailType railtype); bool HasAnyRailTypesAvail(const CompanyID company); bool ValParamRailType(const RailType rail); -RailTypes AddDateIntroducedRailTypes(RailTypes current, TimerGameCalendar::Date date); +RailTypes AddDateIntroducedRailTypes(const RailTypes ¤t, TimerGameCalendar::Date date); RailTypes GetCompanyRailTypes(CompanyID company, bool introduces = true); RailTypes GetRailTypes(bool introduces); diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 9d4132258bacb..5a87493211c2d 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -43,7 +43,7 @@ /** Helper type for lists/vectors of trains */ typedef std::vector TrainList; -RailTypeInfo _railtypes[RAILTYPE_END]; +std::vector _railtypes; std::vector _sorted_railtypes; ///< Sorted list of rail types. RailTypes _railtypes_hidden_mask; @@ -64,10 +64,8 @@ enum SignalOffsets { */ void ResetRailTypes() { - static_assert(std::size(_original_railtypes) <= std::size(_railtypes)); - - auto insert = std::copy(std::begin(_original_railtypes), std::end(_original_railtypes), std::begin(_railtypes)); - std::fill(insert, std::end(_railtypes), RailTypeInfo{}); + _railtypes.clear(); + std::copy(std::begin(_original_railtypes), std::end(_original_railtypes), std::back_inserter(_railtypes)); _railtypes_hidden_mask = {}; } @@ -148,13 +146,12 @@ void InitRailTypes() RailType AllocateRailType(RailTypeLabel label) { auto it = std::ranges::find(_railtypes, 0, &RailTypeInfo::label); - if (it == std::end(_railtypes)) return INVALID_RAILTYPE; + if (it == std::end(_railtypes)) it = _railtypes.emplace(it, _original_railtypes[RAILTYPE_RAIL]); RailTypeInfo &rti = *it; RailType rt = rti.Index(); - /* Set up new rail type based on default rail. */ - rti = _original_railtypes[RAILTYPE_RAIL]; + /* Set up new rail type */ rti.label = label; rti.alternate_labels.clear(); diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 15bc67e6d1adc..f15398570a227 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -1946,7 +1946,7 @@ static void SetDefaultRailGui() switch (_settings_client.gui.default_rail_type) { case 2: { /* Find the most used rail type */ - std::array count{}; + std::vector count(GetNumRailTypes()); for (const auto t : Map::Iterate()) { if (IsTileType(t, MP_RAILWAY) || IsLevelCrossingTile(t) || HasStationTileRail(t) || (IsTileType(t, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL)) { diff --git a/src/rail_type.h b/src/rail_type.h index 7f4081e43a1a0..b1cbc710f6464 100644 --- a/src/rail_type.h +++ b/src/rail_type.h @@ -11,6 +11,7 @@ #define RAIL_TYPE_H #include "core/enum_type.hpp" +#include "core/flatset_type.hpp" #include "core/strong_typedef_type.hpp" #include "transport_mapping.hpp" @@ -24,22 +25,21 @@ static const RailTypeLabel RAILTYPE_LABEL_MAGLEV = 'MGLV'; /** * Enumeration for all possible railtypes. */ -enum RailType : uint8_t { +enum RailType : uint16_t { RAILTYPE_BEGIN = 0, ///< Used for iterations RAILTYPE_RAIL = 0, ///< Standard non-electric rails RAILTYPE_ELECTRIC = 1, ///< Electric rails RAILTYPE_MONO = 2, ///< Monorail RAILTYPE_MAGLEV = 3, ///< Maglev - RAILTYPE_END = 64, ///< Used for iterations - INVALID_RAILTYPE = 0xFF, ///< Flag for invalid railtype + INVALID_RAILTYPE = UINT16_MAX, ///< Flag for invalid railtype }; /** Allow incrementing of Track variables */ DECLARE_INCREMENT_DECREMENT_OPERATORS(RailType) -using RailTypes = EnumBitSet; +using RailTypes = FlatBitSet; -static constexpr RailTypes INVALID_RAILTYPES{UINT64_MAX}; +static const RailTypes INVALID_RAILTYPES{}; /** Mapped rail type. */ using RailTypeMapping = TransportMapping; diff --git a/src/road.cpp b/src/road.cpp index 5a115e98490c1..417ba51334008 100644 --- a/src/road.cpp +++ b/src/road.cpp @@ -10,6 +10,8 @@ #include "stdafx.h" #include "rail_map.h" #include "road_map.h" +#include "station_map.h" +#include "tunnelbridge_map.h" #include "water_map.h" #include "genworld.h" #include "company_func.h" @@ -29,9 +31,8 @@ */ RoadType RoadTypeInfo::Index() const { - extern RoadTypeInfo _roadtypes[ROADTYPE_END]; - size_t index = this - _roadtypes; - assert(index < ROADTYPE_END); + size_t index = this - GetRoadTypeInfo().data(); + assert(index < GetNumRoadTypes()); return static_cast(index); } @@ -135,13 +136,14 @@ bool HasRoadTypeAvail(const CompanyID company, RoadType roadtype) * owned by towns. So if a town may build it, it should be buildable by them too. */ return !rti->flags.Test( RoadTypeFlag::Hidden) || rti->flags.Test( RoadTypeFlag::TownBuild); - } else { - const Company *c = Company::GetIfValid(company); - if (c == nullptr) return false; - RoadTypes avail = c->avail_roadtypes; - avail.Reset(_roadtypes_hidden_mask); - return avail.Test(roadtype); } + + if (_roadtypes_hidden_mask.Test(roadtype)) return false; + + const Company *c = Company::GetIfValid(company); + if (c == nullptr) return false; + + return c->avail_roadtypes.Test(roadtype); } /** @@ -163,7 +165,7 @@ bool HasAnyRoadTypesAvail(CompanyID company, RoadTramType rtt) */ bool ValParamRoadType(RoadType roadtype) { - return roadtype < ROADTYPE_END && HasRoadTypeAvail(_current_company, roadtype); + return roadtype < GetNumRoadTypes() && HasRoadTypeAvail(_current_company, roadtype); } /** @@ -174,12 +176,11 @@ bool ValParamRoadType(RoadType roadtype) * @return The road types that should be available when date * introduced road types are taken into account as well. */ -RoadTypes AddDateIntroducedRoadTypes(RoadTypes current, TimerGameCalendar::Date date) +RoadTypes AddDateIntroducedRoadTypes(const RoadTypes ¤t, TimerGameCalendar::Date date) { - extern RoadTypeInfo _roadtypes[ROADTYPE_END]; RoadTypes rts = current; - for (RoadTypeInfo &rti : _roadtypes) { + for (RoadTypeInfo &rti : GetRoadTypeInfo()) { /* Unused road type. */ if (rti.label == 0) continue; @@ -190,8 +191,7 @@ RoadTypes AddDateIntroducedRoadTypes(RoadTypes current, TimerGameCalendar::Date if (rti.introduction_date > date) continue; /* Have we introduced all required roadtypes? */ - RoadTypes required = rti.introduction_required_roadtypes; - if (!rts.All(required)) continue; + if (!rts.All(rti.introduction_required_roadtypes)) continue; rts.Set(rti.introduces_roadtypes); } @@ -217,7 +217,7 @@ RoadTypes GetCompanyRoadTypes(CompanyID company, bool introduces) if (ei->climates.Test(_settings_game.game_creation.landscape) && (e->company_avail.Test(company) || TimerGameCalendar::date >= e->intro_date + CalendarTime::DAYS_IN_YEAR)) { const RoadVehicleInfo *rvi = &e->VehInfo(); - assert(rvi->roadtype < ROADTYPE_END); + assert(rvi->roadtype < GetNumRoadTypes()); if (introduces) { rts.Set(GetRoadTypeInfo(rvi->roadtype)->introduces_roadtypes); } else { @@ -244,7 +244,7 @@ RoadTypes GetRoadTypes(bool introduces) if (!ei->climates.Test(_settings_game.game_creation.landscape)) continue; const RoadVehicleInfo *rvi = &e->VehInfo(); - assert(rvi->roadtype < ROADTYPE_END); + assert(rvi->roadtype < GetNumRoadTypes()); if (introduces) { rts.Set(GetRoadTypeInfo(rvi->roadtype)->introduces_roadtypes); } else { @@ -264,20 +264,70 @@ RoadTypes GetRoadTypes(bool introduces) */ RoadType GetRoadTypeByLabel(RoadTypeLabel label, bool allow_alternate_labels) { - extern RoadTypeInfo _roadtypes[ROADTYPE_END]; + auto roadtypes = GetRoadTypeInfo(); if (label == 0) return INVALID_ROADTYPE; - auto it = std::ranges::find(_roadtypes, label, &RoadTypeInfo::label); - if (it == std::end(_roadtypes) && allow_alternate_labels) { + auto it = std::ranges::find(roadtypes, label, &RoadTypeInfo::label); + if (it == std::end(roadtypes) && allow_alternate_labels) { /* Test if any road type defines the label as an alternate. */ - it = std::ranges::find_if(_roadtypes, [label](const RoadTypeInfo &rti) { return rti.alternate_labels.contains(label); }); + it = std::ranges::find_if(roadtypes, [label](const RoadTypeInfo &rti) { return rti.alternate_labels.contains(label); }); } - if (it != std::end(_roadtypes)) return it->Index(); + if (it != std::end(roadtypes)) return it->Index(); /* No matching label was found, so it is invalid */ return INVALID_ROADTYPE; } +/** + * Get a set of road types that are currently in use on the map. + * @param rtt Requied RoadTramType of road types. + * @return Used road types. + */ +static RoadTypes GetUsedRoadTypes(RoadTramType rtt) +{ + RoadTypes used_types; + for (const Company *c : Company::Iterate()) { + for (const auto &[roadtype, count] : c->infrastructure.road) { + if (count > 0 && GetRoadTramType(roadtype) == rtt) used_types.Set(roadtype); + } + } + + for (const auto &[roadtype, count] : RoadTypeInfo::infrastructure_counts) { + if (count > 0 && GetRoadTramType(roadtype) == rtt) used_types.Set(roadtype); + } + return used_types; +} + +/** + * Get the first unused mapped road type position. + * @return iterator to first unused mapped road type. + */ +template <> auto RoadTypeMapping::FindUnusedMapType() -> MapStorage::iterator +{ + RoadTypes used_types = GetUsedRoadTypes(RoadTramType::RTT_ROAD); + if (used_types.size() < RoadTypeMapping::MAX_SIZE) { + for (auto it = std::begin(this->map); it != std::end(this->map); ++it) { + if (!used_types.contains(*it)) return it; + } + } + return std::end(this->map); +} + +/** + * Get the first unused mapped tram type position. + * @return iterator to first unused mapped tram type. + */ +template <> auto TramTypeMapping::FindUnusedMapType() -> MapStorage::iterator +{ + RoadTypes used_types = GetUsedRoadTypes(RoadTramType::RTT_TRAM); + if (used_types.size() < RoadTypeMapping::MAX_SIZE) { + for (auto it = std::begin(this->map); it != std::end(this->map); ++it) { + if (!used_types.contains(*it)) return it; + } + } + return std::end(this->map); +} + RoadTypeMapping _roadtype_mapping; TramTypeMapping _tramtype_mapping; diff --git a/src/road.h b/src/road.h index b05525766d1c3..529ee421758cb 100644 --- a/src/road.h +++ b/src/road.h @@ -186,7 +186,7 @@ class RoadTypeInfo { * @param rtt RoadTramType. * @return Mask of road types for RoadTramType. */ -inline RoadTypes GetMaskForRoadTramType(RoadTramType rtt) +inline const RoadTypes &GetMaskForRoadTramType(RoadTramType rtt) { extern RoadTypes _roadtypes_road; extern RoadTypes _roadtypes_tram; @@ -209,10 +209,22 @@ inline RoadTramType GetRoadTramType(RoadType roadtype) } inline RoadTramType OtherRoadTramType(RoadTramType rtt) + { return rtt == RTT_ROAD ? RTT_TRAM : RTT_ROAD; } +inline std::span GetRoadTypeInfo() +{ + extern std::vector _roadtypes; + return _roadtypes; +} + +inline size_t GetNumRoadTypes() +{ + return std::size(GetRoadTypeInfo()); +} + /** * Returns a pointer to the Roadtype information for a given roadtype * @param roadtype the road type which the information is requested for @@ -220,9 +232,8 @@ inline RoadTramType OtherRoadTramType(RoadTramType rtt) */ inline const RoadTypeInfo *GetRoadTypeInfo(RoadType roadtype) { - extern RoadTypeInfo _roadtypes[ROADTYPE_END]; - assert(roadtype < ROADTYPE_END); - return &_roadtypes[roadtype]; + assert(roadtype < GetNumRoadTypes()); + return &GetRoadTypeInfo()[roadtype]; } /** @@ -245,7 +256,7 @@ inline bool HasPowerOnRoad(RoadType enginetype, RoadType tiletype) */ inline Money RoadBuildCost(RoadType roadtype) { - assert(roadtype < ROADTYPE_END); + assert(roadtype < GetNumRoadTypes()); return (_price[PR_BUILD_ROAD] * GetRoadTypeInfo(roadtype)->cost_multiplier) >> 3; } @@ -256,7 +267,7 @@ inline Money RoadBuildCost(RoadType roadtype) */ inline Money RoadClearCost(RoadType roadtype) { - assert(roadtype < ROADTYPE_END); + assert(roadtype < GetNumRoadTypes()); /* Flat fee for removing road. */ if (RoadTypeIsRoad(roadtype)) return _price[PR_CLEAR_ROAD]; @@ -288,7 +299,7 @@ inline Money RoadConvertCost(RoadType from, RoadType to) */ inline bool RoadNoLevelCrossing(RoadType roadtype) { - assert(roadtype < ROADTYPE_END); + assert(roadtype < GetNumRoadTypes()); return GetRoadTypeInfo(roadtype)->flags.Test(RoadTypeFlag::NoLevelCrossing); } diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 21f667dfa5c81..a628772fa3e50 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -51,7 +51,7 @@ /** Helper type for lists/vectors of road vehicles */ typedef std::vector RoadVehicleList; -RoadTypeInfo _roadtypes[ROADTYPE_END]; +std::vector _roadtypes; std::vector _sorted_roadtypes; ///< Sorted list of road types. RoadTypes _roadtypes_hidden_mask; ///< Bitset of hidden roadtypes. RoadTypes _roadtypes_road; ///< Bitset of road roadtypes. @@ -62,10 +62,8 @@ RoadTypes _roadtypes_tram; ///< Bitset of tram roadtypes. */ void ResetRoadTypes() { - static_assert(std::size(_original_roadtypes) <= std::size(_roadtypes)); - - auto insert = std::copy(std::begin(_original_roadtypes), std::end(_original_roadtypes), std::begin(_roadtypes)); - std::fill(insert, std::end(_roadtypes), RoadTypeInfo{}); + _roadtypes.clear(); + std::copy(std::begin(_original_roadtypes), std::end(_original_roadtypes), std::back_inserter(_roadtypes)); _roadtypes_hidden_mask = {}; _roadtypes_road = {ROADTYPE_ROAD}; @@ -129,13 +127,12 @@ void InitRoadTypes() RoadType AllocateRoadType(RoadTypeLabel label, RoadTramType rtt) { auto it = std::ranges::find(_roadtypes, 0, &RoadTypeInfo::label); - if (it == std::end(_roadtypes)) return INVALID_ROADTYPE; + if (it == std::end(_roadtypes)) it = _roadtypes.emplace(it, _original_roadtypes[(rtt == RTT_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD]); RoadTypeInfo &rti = *it; RoadType rt = rti.Index(); - /* Set up new road type based on default tram or road. */ - rti = _original_roadtypes[(rtt == RTT_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD]; + /* Set up new road type */ rti.label = label; rti.alternate_labels.clear(); rti.flags = {}; diff --git a/src/road_func.h b/src/road_func.h index 8f7727af56b59..2ac9e529490ca 100644 --- a/src/road_func.h +++ b/src/road_func.h @@ -124,7 +124,7 @@ inline RoadBits AxisToRoadBits(Axis a) */ inline Money RoadMaintenanceCost(RoadType roadtype, uint32_t num, uint32_t total_num) { - assert(roadtype < ROADTYPE_END); + assert(roadtype < GetNumRoadTypes()); return (_price[PR_INFRASTRUCTURE_ROAD] * GetRoadTypeInfo(roadtype)->maintenance_multiplier * num * (1 + IntSqrt(total_num))) >> 12; } @@ -134,7 +134,7 @@ inline Money RoadMaintenanceCost(RoadType roadtype, uint32_t num, uint32_t total */ inline bool HasRoadCatenary(RoadType roadtype) { - assert(roadtype < ROADTYPE_END); + assert(roadtype < GetNumRoadTypes()); return GetRoadTypeInfo(roadtype)->flags.Test(RoadTypeFlag::Catenary); } @@ -151,7 +151,7 @@ bool HasRoadTypeAvail(CompanyID company, RoadType roadtype); bool ValParamRoadType(RoadType roadtype); RoadTypes GetCompanyRoadTypes(CompanyID company, bool introduces = true); RoadTypes GetRoadTypes(bool introduces); -RoadTypes AddDateIntroducedRoadTypes(RoadTypes current, TimerGameCalendar::Date date); +RoadTypes AddDateIntroducedRoadTypes(const RoadTypes ¤t, TimerGameCalendar::Date date); void UpdateLevelCrossing(TileIndex tile, bool sound = true, bool force_bar = false); void MarkDirtyAdjacentLevelCrossingTiles(TileIndex tile, Axis road_axis); diff --git a/src/road_type.h b/src/road_type.h index 75ed42fefc304..30f5491f95273 100644 --- a/src/road_type.h +++ b/src/road_type.h @@ -11,6 +11,7 @@ #define ROAD_TYPE_H #include "core/enum_type.hpp" +#include "core/flatset_type.hpp" #include "transport_mapping.hpp" typedef uint32_t RoadTypeLabel; @@ -21,16 +22,15 @@ static const RoadTypeLabel ROADTYPE_LABEL_TRAM = 'ELRL'; /** * The different roadtypes we support */ -enum RoadType : uint8_t { +enum RoadType : uint16_t { ROADTYPE_BEGIN = 0, ///< Used for iterations ROADTYPE_ROAD = 0, ///< Basic road type ROADTYPE_TRAM = 1, ///< Trams - ROADTYPE_END = 63, ///< Used for iterations - INVALID_ROADTYPE = 63, ///< flag for invalid roadtype + INVALID_ROADTYPE = UINT16_MAX, ///< flag for invalid roadtype }; DECLARE_INCREMENT_DECREMENT_OPERATORS(RoadType) -using RoadTypes = EnumBitSet; +using RoadTypes = FlatBitSet; /** * The different types of road type. diff --git a/src/roadveh.h b/src/roadveh.h index 8657512d1e95f..5940380ff3c8d 100644 --- a/src/roadveh.h +++ b/src/roadveh.h @@ -272,7 +272,8 @@ struct RoadVehicle final : public GroundVehicle { */ inline uint16_t GetMaxTrackSpeed() const { - return GetRoadTypeInfo(GetRoadType(this->tile, GetRoadTramType(this->roadtype)))->max_speed; + RoadType rt = GetRoadType(this->tile, GetRoadTramType(this->roadtype)); + return GetRoadTypeInfo(rt)->max_speed; } /** diff --git a/src/saveload/labelmaps_sl.cpp b/src/saveload/labelmaps_sl.cpp index 3d11f6befd568..c4167a3c7fd02 100644 --- a/src/saveload/labelmaps_sl.cpp +++ b/src/saveload/labelmaps_sl.cpp @@ -47,14 +47,13 @@ struct RAILChunkHandler : ChunkHandler { int index = 0; LabelObject lo; - for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) { - const RailTypeInfo *rti = GetRailTypeInfo(r); - if (rti->label == 0) continue; + for (const RailTypeInfo &rti : GetRailTypeInfo()) { + if (rti.label == 0) continue; - MapRailType map_railtype = _railtype_mapping.GetMappedType(rti->Index()); + MapRailType map_railtype = _railtype_mapping.GetMappedType(rti.Index()); if (map_railtype == RailTypeMapping::INVALID_MAP_TYPE) continue; - lo.label = rti->label; + lo.label = rti.label; lo.index = map_railtype.base(); SlSetArrayIndex(index++); @@ -95,24 +94,23 @@ struct ROTTChunkHandler : ChunkHandler { int index = 0; LabelObject lo; - for (RoadType r = ROADTYPE_BEGIN; r != ROADTYPE_END; r++) { - const RoadTypeInfo *rti = GetRoadTypeInfo(r); - if (rti->label == 0) continue; + for (const RoadTypeInfo &rti : GetRoadTypeInfo()) { + if (rti.label == 0) continue; - if (GetRoadTramType(r) == RTT_ROAD) { - MapRoadType map_roadtype = _roadtype_mapping.GetMappedType(rti->Index()); + if (GetRoadTramType(rti.Index()) == RTT_ROAD) { + MapRoadType map_roadtype = _roadtype_mapping.GetMappedType(rti.Index()); if (map_roadtype == RoadTypeMapping::INVALID_MAP_TYPE) continue; lo.index = map_roadtype.base(); } else { - MapTramType map_tramtype = _tramtype_mapping.GetMappedType(rti->Index()); + MapTramType map_tramtype = _tramtype_mapping.GetMappedType(rti.Index()); if (map_tramtype == TramTypeMapping::INVALID_MAP_TYPE) continue; lo.index = map_tramtype.base(); } - lo.label = rti->label; - lo.subtype = GetRoadTramType(r); + lo.label = rti.label; + lo.subtype = GetRoadTramType(rti.Index()); SlSetArrayIndex(index++); SlObject(&lo, description); @@ -124,7 +122,7 @@ struct ROTTChunkHandler : ChunkHandler { const std::vector slt = SlCompatTableHeader(description, _label_object_sl_compat); bool convert = IsSavegameVersionBefore(SLV_TRANSPORT_TYPE_MAPPING); - _roadtype_list.reserve(ROADTYPE_END); + _roadtype_list.reserve(64); LabelObject lo; diff --git a/src/script/api/script_engine.cpp b/src/script/api/script_engine.cpp index 873a1154b7407..13b1ad1ea3094 100644 --- a/src/script/api/script_engine.cpp +++ b/src/script/api/script_engine.cpp @@ -242,10 +242,9 @@ if (!IsValidEngine(engine_id)) return ScriptRail::RAILTYPE_INVALID; if (GetVehicleType(engine_id) != ScriptVehicle::VT_RAIL) return ScriptRail::RAILTYPE_INVALID; - auto railtype = ::RailVehInfo(engine_id)->railtypes.GetNthSetBit(0); - if (!railtype.has_value()) return ScriptRail::RAILTYPE_INVALID; + if (::RailVehInfo(engine_id)->railtypes.empty()) return ScriptRail::RAILTYPE_INVALID; - return static_cast(railtype.value()); + return static_cast(*::RailVehInfo(engine_id)->railtypes.begin()); } /* static */ ScriptList *ScriptEngine::GetAllRailTypes(EngineID engine_id) diff --git a/src/script/api/script_infrastructure.cpp b/src/script/api/script_infrastructure.cpp index f801e82c29491..f74daa6f73754 100644 --- a/src/script/api/script_infrastructure.cpp +++ b/src/script/api/script_infrastructure.cpp @@ -21,7 +21,7 @@ /* static */ SQInteger ScriptInfrastructure::GetRailPieceCount(ScriptCompany::CompanyID company, ScriptRail::RailType railtype) { company = ScriptCompany::ResolveCompanyID(company); - if (company == ScriptCompany::COMPANY_INVALID || (::RailType)railtype >= RAILTYPE_END) return 0; + if (company == ScriptCompany::COMPANY_INVALID || (::RailType)railtype >= GetNumRailTypes()) return 0; return ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->infrastructure.GetRailCount(static_cast<::RailType>(railtype)); } @@ -29,7 +29,7 @@ /* static */ SQInteger ScriptInfrastructure::GetRoadPieceCount(ScriptCompany::CompanyID company, ScriptRoad::RoadType roadtype) { company = ScriptCompany::ResolveCompanyID(company); - if (company == ScriptCompany::COMPANY_INVALID || (::RoadType)roadtype >= ROADTYPE_END) return 0; + if (company == ScriptCompany::COMPANY_INVALID || (::RoadType)roadtype >= GetNumRoadTypes()) return 0; return ::Company::Get(ScriptCompany::FromScriptCompanyID(company))->infrastructure.GetRoadCount(static_cast<::RoadType>(roadtype)); } @@ -68,7 +68,7 @@ { ::RailType rt = static_cast<::RailType>(railtype); company = ScriptCompany::ResolveCompanyID(company); - if (company == ScriptCompany::COMPANY_INVALID || rt >= RAILTYPE_END || !_settings_game.economy.infrastructure_maintenance) return 0; + if (company == ScriptCompany::COMPANY_INVALID || rt >= GetNumRailTypes() || !_settings_game.economy.infrastructure_maintenance) return 0; const ::Company *c = ::Company::Get(ScriptCompany::FromScriptCompanyID(company)); return ::RailMaintenanceCost(rt, c->infrastructure.GetRailCount(rt), c->infrastructure.GetRailTotal()); @@ -78,8 +78,7 @@ { ::RoadType rt = static_cast<::RoadType>(roadtype); company = ScriptCompany::ResolveCompanyID(company); - if (company == ScriptCompany::COMPANY_INVALID || rt >= ROADTYPE_END || !_settings_game.economy.infrastructure_maintenance) return 0; - if (company == ScriptCompany::COMPANY_INVALID || rt >= ROADTYPE_END || !_settings_game.economy.infrastructure_maintenance) return 0; + if (company == ScriptCompany::COMPANY_INVALID || rt >= GetNumRoadTypes() || !_settings_game.economy.infrastructure_maintenance) return 0; const ::Company *c = ::Company::Get(ScriptCompany::FromScriptCompanyID(company)); return ::RoadMaintenanceCost(rt, c->infrastructure.GetRoadCount(rt), RoadTypeIsRoad(rt) ? c->infrastructure.GetRoadTotal() : c->infrastructure.GetTramTotal()); diff --git a/src/script/api/script_rail.cpp b/src/script/api/script_rail.cpp index 592fed196a0f7..425a6e9da9e60 100644 --- a/src/script/api/script_rail.cpp +++ b/src/script/api/script_rail.cpp @@ -70,7 +70,7 @@ /* static */ bool ScriptRail::IsRailTypeAvailable(RailType rail_type) { EnforceDeityOrCompanyModeValid(false); - if ((::RailType)rail_type >= RAILTYPE_END) return false; + if ((::RailType)rail_type >= GetNumRailTypes()) return false; return ScriptCompanyMode::IsDeity() || ::HasRailTypeAvail(ScriptObject::GetCompany(), (::RailType)rail_type); } diff --git a/src/script/api/script_railtypelist.cpp b/src/script/api/script_railtypelist.cpp index c5344a43c9280..320eaf92c2b4b 100644 --- a/src/script/api/script_railtypelist.cpp +++ b/src/script/api/script_railtypelist.cpp @@ -19,7 +19,7 @@ ScriptRailTypeList::ScriptRailTypeList() EnforceDeityOrCompanyModeValid_Void(); bool is_deity = ScriptCompanyMode::IsDeity(); ::CompanyID owner = ScriptObject::GetCompany(); - for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { + for (RailType rt = RAILTYPE_BEGIN; rt != GetNumRailTypes(); rt++) { if (is_deity || ::HasRailTypeAvail(owner, rt)) this->AddItem(rt); } } diff --git a/src/script/api/script_road.cpp b/src/script/api/script_road.cpp index 1a689f8647045..b8258165912a6 100644 --- a/src/script/api/script_road.cpp +++ b/src/script/api/script_road.cpp @@ -69,7 +69,7 @@ /* static */ bool ScriptRoad::IsRoadTypeAvailable(RoadType road_type) { EnforceDeityOrCompanyModeValid(false); - return (::RoadType)road_type < ROADTYPE_END && ::HasRoadTypeAvail(ScriptObject::GetCompany(), (::RoadType)road_type); + return (::RoadType)road_type < GetNumRoadTypes() && ::HasRoadTypeAvail(ScriptObject::GetCompany(), (::RoadType)road_type); } /* static */ ScriptRoad::RoadType ScriptRoad::GetCurrentRoadType() diff --git a/src/script/api/script_roadtypelist.cpp b/src/script/api/script_roadtypelist.cpp index b5c23c380262a..b1e4209c825ec 100644 --- a/src/script/api/script_roadtypelist.cpp +++ b/src/script/api/script_roadtypelist.cpp @@ -17,7 +17,7 @@ ScriptRoadTypeList::ScriptRoadTypeList(ScriptRoad::RoadTramTypes rtts) { EnforceDeityOrCompanyModeValid_Void(); ::CompanyID owner = ScriptObject::GetCompany(); - for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { + for (RoadType rt = ROADTYPE_BEGIN; rt != GetNumRoadTypes(); rt++) { if (!HasBit(rtts, GetRoadTramType(rt))) continue; if (::HasRoadTypeAvail(owner, rt)) this->AddItem(rt); } diff --git a/src/table/engines.h b/src/table/engines.h index b5e745c1b2837..687a992b0b372 100644 --- a/src/table/engines.h +++ b/src/table/engines.h @@ -410,7 +410,7 @@ static constexpr EngineInfo _orig_engine_info[] = { #define RC_E PR_RUNNING_TRAIN_ELECTRIC #define RC_W INVALID_PRICE -static constexpr RailVehicleInfo _orig_rail_vehicle_info[] = { +static const RailVehicleInfo _orig_rail_vehicle_info[] = { /* image_index max_speed running_cost engclass * | type | power | running_cost_class * | | cost_factor | weight | | capacity diff --git a/src/train.h b/src/train.h index f4bd7889adf8e..f3214c2f2b275 100644 --- a/src/train.h +++ b/src/train.h @@ -322,7 +322,8 @@ struct Train final : public GroundVehicle { */ inline uint16_t GetMaxTrackSpeed() const { - return GetRailTypeInfo(GetRailType(this->tile))->max_speed; + RailType rt = GetRailType(this->tile); + return GetRailTypeInfo(rt)->max_speed; } /** diff --git a/src/transport_mapping.hpp b/src/transport_mapping.hpp index 95e7692980dc4..87363ad6dc266 100644 --- a/src/transport_mapping.hpp +++ b/src/transport_mapping.hpp @@ -86,7 +86,11 @@ class TransportMapping { /* Check for an unused entry. */ it = std::ranges::find(this->map, INVALID_TYPE); - if (it == std::end(this->map)) return INVALID_MAP_TYPE; + if (it == std::end(this->map)) { + /* Didn't find an unused slot, use slower path to find a free map type. */ + it = this->FindUnusedMapType(); + if (it == std::end(this->map)) return INVALID_MAP_TYPE; + } if (exec) *it = type; @@ -101,6 +105,8 @@ class TransportMapping { { return static_cast(iter - std::begin(this->map)); } + + MapStorage::iterator FindUnusedMapType(); }; #endif /* TRANSPORT_MAPPING_HPP */