From 1403f24fa90c69bdc18c658e932b51c04ce69831 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Sat, 20 Jan 2024 15:58:37 +0100 Subject: [PATCH 01/27] Codechange: replace LeastCommonMultiple with std::lcm --- src/newgrf_gui.cpp | 8 ++++---- src/widget.cpp | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index 769ee5d6f9..0ad96c7b4a 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -1642,20 +1642,20 @@ public: this->smallest_y = std::max(min_inf_height, min_acs_height + WidgetDimensions::scaled.vsep_wide + min_avs_height); /* Filling. */ - this->fill_x = LeastCommonMultiple(this->avs->fill_x, this->acs->fill_x); + this->fill_x = std::lcm(this->avs->fill_x, this->acs->fill_x); if (this->inf->fill_x > 0 && (this->fill_x == 0 || this->fill_x > this->inf->fill_x)) this->fill_x = this->inf->fill_x; this->fill_y = this->avs->fill_y; if (this->acs->fill_y > 0 && (this->fill_y == 0 || this->fill_y > this->acs->fill_y)) this->fill_y = this->acs->fill_y; - this->fill_y = LeastCommonMultiple(this->fill_y, this->inf->fill_y); + this->fill_y = std::lcm(this->fill_y, this->inf->fill_y); /* Resizing. */ - this->resize_x = LeastCommonMultiple(this->avs->resize_x, this->acs->resize_x); + this->resize_x = std::lcm(this->avs->resize_x, this->acs->resize_x); if (this->inf->resize_x > 0 && (this->resize_x == 0 || this->resize_x > this->inf->resize_x)) this->resize_x = this->inf->resize_x; this->resize_y = this->avs->resize_y; if (this->acs->resize_y > 0 && (this->resize_y == 0 || this->resize_y > this->acs->resize_y)) this->resize_y = this->acs->resize_y; - this->resize_y = LeastCommonMultiple(this->resize_y, this->inf->resize_y); + this->resize_y = std::lcm(this->resize_y, this->inf->resize_y); /* Make sure the height suits the 3 column (resp. not-editable) format; the 2 column format can easily fill space between the lists */ this->smallest_y = ComputeMaxSize(min_acs_height, this->smallest_y + this->resize_y - 1, this->resize_y); diff --git a/src/widget.cpp b/src/widget.cpp index 962e3f3148..65d105292b 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -1239,10 +1239,10 @@ void NWidgetStacked::SetupSmallestSize(Window *w) this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding.Horizontal()); this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.Vertical()); - this->fill_x = LeastCommonMultiple(this->fill_x, child_wid->fill_x); - this->fill_y = LeastCommonMultiple(this->fill_y, child_wid->fill_y); - this->resize_x = LeastCommonMultiple(this->resize_x, child_wid->resize_x); - this->resize_y = LeastCommonMultiple(this->resize_y, child_wid->resize_y); + this->fill_x = std::lcm(this->fill_x, child_wid->fill_x); + this->fill_y = std::lcm(this->fill_y, child_wid->fill_y); + this->resize_x = std::lcm(this->resize_x, child_wid->resize_x); + this->resize_y = std::lcm(this->resize_y, child_wid->resize_y); } } @@ -1409,12 +1409,12 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w) if (child_wid->fill_x > 0) { if (this->fill_x == 0 || this->fill_x > child_wid->fill_x) this->fill_x = child_wid->fill_x; } - this->fill_y = LeastCommonMultiple(this->fill_y, child_wid->fill_y); + this->fill_y = std::lcm(this->fill_y, child_wid->fill_y); if (child_wid->resize_x > 0) { if (this->resize_x == 0 || this->resize_x > child_wid->resize_x) this->resize_x = child_wid->resize_x; } - this->resize_y = LeastCommonMultiple(this->resize_y, child_wid->resize_y); + this->resize_y = std::lcm(this->resize_y, child_wid->resize_y); } if (this->fill_x == 0 && this->pip_ratio_pre + this->pip_ratio_inter + this->pip_ratio_post > 0) this->fill_x = 1; /* 4. Increase by required PIP space. */ @@ -1598,12 +1598,12 @@ void NWidgetVertical::SetupSmallestSize(Window *w) if (child_wid->fill_y > 0) { if (this->fill_y == 0 || this->fill_y > child_wid->fill_y) this->fill_y = child_wid->fill_y; } - this->fill_x = LeastCommonMultiple(this->fill_x, child_wid->fill_x); + this->fill_x = std::lcm(this->fill_x, child_wid->fill_x); if (child_wid->resize_y > 0) { if (this->resize_y == 0 || this->resize_y > child_wid->resize_y) this->resize_y = child_wid->resize_y; } - this->resize_x = LeastCommonMultiple(this->resize_x, child_wid->resize_x); + this->resize_x = std::lcm(this->resize_x, child_wid->resize_x); } if (this->fill_y == 0 && this->pip_ratio_pre + this->pip_ratio_inter + this->pip_ratio_post > 0) this->fill_y = 1; /* 4. Increase by required PIP space. */ From 4c51534b6a19f5707e577c3e09a93bf44dfd2aa9 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Sat, 20 Jan 2024 15:59:53 +0100 Subject: [PATCH 02/27] Remove: LeastCommonMultiple / GreatestCommonDivisor Use std::lcm / std::gcd instead. --- src/core/math_func.cpp | 35 ----------------------------------- src/core/math_func.hpp | 2 -- src/tests/math_func.cpp | 35 ----------------------------------- 3 files changed, 72 deletions(-) diff --git a/src/core/math_func.cpp b/src/core/math_func.cpp index db705092a8..f094e9ece8 100644 --- a/src/core/math_func.cpp +++ b/src/core/math_func.cpp @@ -12,41 +12,6 @@ #include "../safeguards.h" -/** - * Compute least common multiple (lcm) of arguments \a a and \a b, the smallest - * integer value that is a multiple of both \a a and \a b. - * @param a First number. - * @param b second number. - * @return Least common multiple of values \a a and \a b. - * - * @note This function only works for non-negative values of \a a and \a b. - */ -int LeastCommonMultiple(int a, int b) -{ - if (a == 0 || b == 0) return 0; // By definition. - if (a == 1 || a == b) return b; - if (b == 1) return a; - - return a * b / GreatestCommonDivisor(a, b); -} - -/** - * Compute greatest common divisor (gcd) of \a a and \a b. - * @param a First number. - * @param b second number. - * @return Greatest common divisor of \a a and \a b. - */ -int GreatestCommonDivisor(int a, int b) -{ - while (b != 0) { - int t = b; - b = a % b; - a = t; - } - return a; - -} - /** * Deterministic approximate division. * Cancels out division errors stemming from the integer nature of the division over multiple runs. diff --git a/src/core/math_func.hpp b/src/core/math_func.hpp index 6cf0567015..561f8fb754 100644 --- a/src/core/math_func.hpp +++ b/src/core/math_func.hpp @@ -309,8 +309,6 @@ inline uint ToPercent16(uint i) return i * 101 >> 16; } -int LeastCommonMultiple(int a, int b); -int GreatestCommonDivisor(int a, int b); int DivideApprox(int a, int b); /** diff --git a/src/tests/math_func.cpp b/src/tests/math_func.cpp index 769e344145..1f53d005b7 100644 --- a/src/tests/math_func.cpp +++ b/src/tests/math_func.cpp @@ -13,41 +13,6 @@ #include "../core/math_func.hpp" -TEST_CASE("LeastCommonMultipleTest - Zero") -{ - CHECK(0 == LeastCommonMultiple(0, 0)); - CHECK(0 == LeastCommonMultiple(0, 600)); - CHECK(0 == LeastCommonMultiple(600, 0)); -} - -TEST_CASE("LeastCommonMultipleTest - FindLCM") -{ - CHECK(25 == LeastCommonMultiple(5, 25)); - CHECK(25 == LeastCommonMultiple(25, 5)); - CHECK(130 == LeastCommonMultiple(5, 26)); - CHECK(130 == LeastCommonMultiple(26, 5)); -} - -TEST_CASE("GreatestCommonDivisorTest - Negative") -{ - CHECK(4 == GreatestCommonDivisor(4, -52)); - // CHECK(3 == GreatestCommonDivisor(-27, 6)); // error - returns -3 -} - -TEST_CASE("GreatestCommonDivisorTest - Zero") -{ - CHECK(27 == GreatestCommonDivisor(0, 27)); - CHECK(27 == GreatestCommonDivisor(27, 0)); -} - -TEST_CASE("GreatestCommonDivisorTest - FindGCD") -{ - CHECK(5 == GreatestCommonDivisor(5, 25)); - CHECK(5 == GreatestCommonDivisor(25, 5)); - CHECK(1 == GreatestCommonDivisor(7, 27)); - CHECK(1 == GreatestCommonDivisor(27, 7)); -} - TEST_CASE("DivideApproxTest - Negative") { CHECK(-2 == DivideApprox(-5, 2)); From dfe70181f1986cc8df68396061fe8175d1f74ee2 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Sat, 20 Jan 2024 16:09:30 +0100 Subject: [PATCH 03/27] Codechange: add constexpr to bitmath functions where applicable --- src/core/bitmath_func.hpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/core/bitmath_func.hpp b/src/core/bitmath_func.hpp index 7a6683bdc6..c7f7e0c072 100644 --- a/src/core/bitmath_func.hpp +++ b/src/core/bitmath_func.hpp @@ -55,7 +55,7 @@ debug_inline constexpr static uint GB(const T x, const uint8_t s, const uint8_t * @return The new value of \a x */ template -inline T SB(T &x, const uint8_t s, const uint8_t n, const U d) +constexpr T SB(T &x, const uint8_t s, const uint8_t n, const U d) { x &= (T)(~((((T)1U << n) - 1) << s)); x |= (T)(d << s); @@ -80,7 +80,7 @@ inline T SB(T &x, const uint8_t s, const uint8_t n, const U d) * @return The new value of \a x */ template -inline T AB(T &x, const uint8_t s, const uint8_t n, const U i) +constexpr T AB(T &x, const uint8_t s, const uint8_t n, const U i) { const T mask = ((((T)1U << n) - 1) << s); x = (T)((x & ~mask) | ((x + (i << s)) & mask)); @@ -100,7 +100,7 @@ inline T AB(T &x, const uint8_t s, const uint8_t n, const U i) * @return True if the bit is set, false else. */ template -debug_inline static bool HasBit(const T x, const uint8_t y) +debug_inline constexpr bool HasBit(const T x, const uint8_t y) { return (x & ((T)1U << y)) != 0; } @@ -118,7 +118,7 @@ debug_inline static bool HasBit(const T x, const uint8_t y) * @return The new value of the old value with the bit set */ template -inline T SetBit(T &x, const uint8_t y) +constexpr T SetBit(T &x, const uint8_t y) { return x = (T)(x | ((T)1U << y)); } @@ -148,7 +148,7 @@ inline T SetBit(T &x, const uint8_t y) * @return The new value of the old value with the bit cleared */ template -inline T ClrBit(T &x, const uint8_t y) +constexpr T ClrBit(T &x, const uint8_t y) { return x = (T)(x & ~((T)1U << y)); } @@ -178,7 +178,7 @@ inline T ClrBit(T &x, const uint8_t y) * @return The new value of the old value with the bit toggled */ template -inline T ToggleBit(T &x, const uint8_t y) +constexpr T ToggleBit(T &x, const uint8_t y) { return x = (T)(x ^ ((T)1U << y)); } @@ -228,7 +228,7 @@ constexpr uint8_t FindLastBit(T x) * @return The new value with the first bit cleared */ template -inline T KillFirstBit(T value) +constexpr T KillFirstBit(T value) { return value &= (T)(value - 1); } @@ -256,7 +256,7 @@ constexpr uint CountBits(T value) * @return does \a value have exactly 1 bit set? */ template -inline bool HasExactlyOneBit(T value) +constexpr bool HasExactlyOneBit(T value) { return value != 0 && (value & (value - 1)) == 0; } @@ -268,7 +268,7 @@ inline bool HasExactlyOneBit(T value) * @return does \a value have at most 1 bit set? */ template -inline bool HasAtMostOneBit(T value) +constexpr bool HasAtMostOneBit(T value) { return (value & (value - 1)) == 0; } From 086cbd0d72f5f0c888564c8824d12bdeaed7d043 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Sat, 20 Jan 2024 16:11:43 +0100 Subject: [PATCH 04/27] Codechange: add constexpr to math functions where applicable --- src/core/math_func.hpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/core/math_func.hpp b/src/core/math_func.hpp index 561f8fb754..b50e84d299 100644 --- a/src/core/math_func.hpp +++ b/src/core/math_func.hpp @@ -20,7 +20,7 @@ * @return The unsigned value */ template -inline T abs(const T a) +constexpr T abs(const T a) { return (a < (T)0) ? -a : a; } @@ -34,7 +34,7 @@ inline T abs(const T a) * @return The smallest multiple of n equal or greater than x */ template -inline T Align(const T x, uint n) +constexpr T Align(const T x, uint n) { assert((n & (n - 1)) == 0 && n != 0); n--; @@ -52,7 +52,7 @@ inline T Align(const T x, uint n) * @see Align() */ template -inline T *AlignPtr(T *x, uint n) +constexpr T *AlignPtr(T *x, uint n) { static_assert(sizeof(size_t) == sizeof(void *)); return reinterpret_cast(Align((size_t)x, n)); @@ -76,7 +76,7 @@ inline T *AlignPtr(T *x, uint n) * @see Clamp(int, int, int) */ template -inline T Clamp(const T a, const T min, const T max) +constexpr T Clamp(const T a, const T min, const T max) { assert(min <= max); if (a <= min) return min; @@ -99,7 +99,7 @@ inline T Clamp(const T a, const T min, const T max) * @returns A value between min and max which is closest to a. */ template -inline T SoftClamp(const T a, const T min, const T max) +constexpr T SoftClamp(const T a, const T min, const T max) { if (min > max) { using U = std::make_unsigned_t; @@ -126,7 +126,7 @@ inline T SoftClamp(const T a, const T min, const T max) * @returns A value between min and max which is closest to a. * @see ClampU(uint, uint, uint) */ -inline int Clamp(const int a, const int min, const int max) +constexpr int Clamp(const int a, const int min, const int max) { return Clamp(a, min, max); } @@ -147,7 +147,7 @@ inline int Clamp(const int a, const int min, const int max) * @returns A value between min and max which is closest to a. * @see Clamp(int, int, int) */ -inline uint ClampU(const uint a, const uint min, const uint max) +constexpr uint ClampU(const uint a, const uint min, const uint max) { return Clamp(a, min, max); } @@ -231,7 +231,7 @@ constexpr To ClampTo(From value) * @return The absolute difference between the given scalars */ template -inline T Delta(const T a, const T b) +constexpr T Delta(const T a, const T b) { return (a < b) ? b - a : a - b; } @@ -249,7 +249,7 @@ inline T Delta(const T a, const T b) * @return True if the value is in the interval, false else. */ template -inline bool IsInsideBS(const T x, const size_t base, const size_t size) +constexpr bool IsInsideBS(const T x, const size_t base, const size_t size) { return (size_t)(x - base) < size; } @@ -265,7 +265,7 @@ inline bool IsInsideBS(const T x, const size_t base, const size_t size) * @see IsInsideBS() */ template , std::is_base_of>, int> = 0> -static constexpr inline bool IsInsideMM(const T x, const size_t min, const size_t max) noexcept +constexpr bool IsInsideMM(const T x, const size_t min, const size_t max) noexcept { if constexpr (std::is_base_of_v) { return (size_t)(x.base() - min) < (max - min); @@ -280,7 +280,7 @@ static constexpr inline bool IsInsideMM(const T x, const size_t min, const size_ * @param b variable to swap with a */ template -inline void Swap(T &a, T &b) +constexpr void Swap(T &a, T &b) { T t = a; a = b; @@ -292,7 +292,7 @@ inline void Swap(T &a, T &b) * @param i value to convert, range 0..255 * @return value in range 0..100 */ -inline uint ToPercent8(uint i) +constexpr uint ToPercent8(uint i) { assert(i < 256); return i * 101 >> 8; @@ -303,7 +303,7 @@ inline uint ToPercent8(uint i) * @param i value to convert, range 0..65535 * @return value in range 0..100 */ -inline uint ToPercent16(uint i) +constexpr uint ToPercent16(uint i) { assert(i < 65536); return i * 101 >> 16; @@ -317,7 +317,7 @@ int DivideApprox(int a, int b); * @param b Denominator * @return Quotient, rounded up */ -inline uint CeilDiv(uint a, uint b) +constexpr uint CeilDiv(uint a, uint b) { return (a + b - 1) / b; } @@ -328,7 +328,7 @@ inline uint CeilDiv(uint a, uint b) * @param b Denominator * @return a rounded up to the nearest multiple of b. */ -inline uint Ceil(uint a, uint b) +constexpr uint Ceil(uint a, uint b) { return CeilDiv(a, b) * b; } @@ -339,7 +339,7 @@ inline uint Ceil(uint a, uint b) * @param b Denominator * @return Quotient, rounded to nearest */ -inline int RoundDivSU(int a, uint b) +constexpr int RoundDivSU(int a, uint b) { if (a > 0) { /* 0.5 is rounded to 1 */ @@ -356,7 +356,7 @@ inline int RoundDivSU(int a, uint b) * @param b Denominator * @return Quotient, rounded away from zero */ -inline int DivAwayFromZero(int a, uint b) +constexpr int DivAwayFromZero(int a, uint b) { const int _b = static_cast(b); if (a > 0) { From d6ccfdbbd9daa6e42a9cbe927a2a6d607ffe1909 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 20 Jan 2024 17:16:42 +0000 Subject: [PATCH 05/27] Fix #11827: Make Layouter::GetCharPosition() aware of ligatures. (#11831) When ligatures happen the precise individual character position is not known, so instead return the previous position (which is that of the ligature.) --- src/gfx_layout.cpp | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/gfx_layout.cpp b/src/gfx_layout.cpp index 1ebe5dc251..6909b4cd28 100644 --- a/src/gfx_layout.cpp +++ b/src/gfx_layout.cpp @@ -244,10 +244,12 @@ Point Layouter::GetCharPosition(std::string_view::const_iterator ch) const if (!IsConsumedFormattingCode(c)) index += line->GetInternalCharLength(c); } + /* Initial position, returned if character not found. */ + static const std::vector zero = { {0, 0} }; + auto position = zero.begin(); + /* We couldn't find the code point index. */ - if (str != ch) { - return { 0, 0 }; - } + if (str != ch) return *position; /* Valid character. */ @@ -257,15 +259,24 @@ Point Layouter::GetCharPosition(std::string_view::const_iterator ch) const const auto &positions = run.GetPositions(); const auto &charmap = run.GetGlyphToCharMap(); - for (int i = 0; i < run.GetGlyphCount(); i++) { - /* Matching glyph? Return position. */ - if ((size_t)charmap[i] == index) { - return positions[i]; - } + /* Run starts after our character, use the last found position. */ + if ((size_t)charmap.front() > index) return *position; + + position = positions.begin(); + for (auto it = charmap.begin(); it != charmap.end(); /* nothing */) { + /* Plain honest-to-$deity match. */ + if ((size_t)*it == index) return *position; + ++it; + if (it == charmap.end()) break; + + /* We just passed our character, it's probably a ligature, use the last found position. */ + if ((size_t)*it > index) return *position; + ++position; } } - NOT_REACHED(); + /* At the end of the run but still didn't find our character so probably a trailing ligature, use the last found position. */ + return *position; } /** From 4d79d868122a804cf3434928e2fe647f5c16ef77 Mon Sep 17 00:00:00 2001 From: translators Date: Sat, 20 Jan 2024 18:38:38 +0000 Subject: [PATCH 06/27] Update: Translations from eints catalan: 18 changes by J0anJosep --- src/lang/catalan.txt | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index 49b3b075de..4487fdb8a1 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -772,7 +772,7 @@ STR_SMALLMAP_LEGENDA_AIRCRAFT :{TINY_FONT}{BLA STR_SMALLMAP_LEGENDA_TRANSPORT_ROUTES :{TINY_FONT}{BLACK}Rutes de transport STR_SMALLMAP_LEGENDA_FOREST :{TINY_FONT}{BLACK}Bosc STR_SMALLMAP_LEGENDA_RAILROAD_STATION :{TINY_FONT}{BLACK}Estació de ferrocarril -STR_SMALLMAP_LEGENDA_TRUCK_LOADING_BAY :{TINY_FONT}{BLACK}Moll de càrrega de camions +STR_SMALLMAP_LEGENDA_TRUCK_LOADING_BAY :{TINY_FONT}{BLACK}Estació per a camions STR_SMALLMAP_LEGENDA_BUS_STATION :{TINY_FONT}{BLACK}Parada d'autobús STR_SMALLMAP_LEGENDA_AIRPORT_HELIPORT :{TINY_FONT}{BLACK}Aeroport/Heliport STR_SMALLMAP_LEGENDA_DOCK :{TINY_FONT}{BLACK}Moll @@ -904,7 +904,7 @@ STR_NEWS_VEHICLE_IS_UNPROFITABLE :{WHITE}El benef STR_NEWS_AIRCRAFT_DEST_TOO_FAR :{WHITE}{VEHICLE} no pot arribar al proper destí perquè és fora del seu abast STR_NEWS_ORDER_REFIT_FAILED :{WHITE}El {VEHICLE} s'ha parat perquè l'ordre de remodelació ha fallat -STR_NEWS_VEHICLE_AUTORENEW_FAILED :{WHITE}L'autorenovació ha fallat en el {VEHICLE}{}{STRING} +STR_NEWS_VEHICLE_AUTORENEW_FAILED :{WHITE}L'autorenovació de {VEHICLE} ha fallat.{}{STRING} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLACK}No{G u va} {STRING} disponible! STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} @@ -1003,6 +1003,7 @@ STR_GAME_OPTIONS_CURRENCY_HKD :Dòlar de Hong STR_GAME_OPTIONS_CURRENCY_INR :Rúpia índia STR_GAME_OPTIONS_CURRENCY_IDR :Rupia indonèsia STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit +STR_GAME_OPTIONS_CURRENCY_LVL :Lats letó STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Desa automàticament STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Selecciona l'interval de desada automàtica de la partida @@ -1044,6 +1045,10 @@ STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Marqueu STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Escala els bisells STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Marqueu aquesta opció si voleu que s'escalin els bisells segons la mida de la interfície. +STR_GAME_OPTIONS_GUI_FONT_SPRITE :{BLACK}Fes servir la font tradicional +STR_GAME_OPTIONS_GUI_FONT_SPRITE_TOOLTIP :{BLACK}Marqueu aquesta casella si preferiu fer servir la font tradicional de mida fixa i pixelada. +STR_GAME_OPTIONS_GUI_FONT_AA :{BLACK}Aplica anti-àlies a les fonts +STR_GAME_OPTIONS_GUI_FONT_AA_TOOLTIP :{BLACK}Marqueu aquesta casella per a fer servir tècniques d'anti-àlies a les fonts redimensionables. STR_GAME_OPTIONS_GUI_SCALE_1X :x1 STR_GAME_OPTIONS_GUI_SCALE_2X :x2 @@ -1779,6 +1784,8 @@ STR_CONFIG_SETTING_SERVINT_DISABLED :Desactivat STR_CONFIG_SETTING_NOSERVICE :Desactiva les revisions quan les avaries s'estableixen a cap: {STRING} STR_CONFIG_SETTING_NOSERVICE_HELPTEXT :Quan està activat, els vehicles no són revisats si no es poden espatllar +STR_CONFIG_SETTING_STATION_LENGTH_LOADING_PENALTY :Penalització de la velocitat de càrrega per a trens més llargs que l'estació: {STRING} +STR_CONFIG_SETTING_STATION_LENGTH_LOADING_PENALTY_HELPTEXT :Quan s'activa, els trens que són massa llargs per a l'estació es carreguen més a poc a poc que un tren que sí que hi cap. Aquesta opció no afecta als encaminadors; és a dir, no afecta als algoritmes que fan servir els trens per a decidir el camí per a arribar a l'estació. STR_CONFIG_SETTING_WAGONSPEEDLIMITS :Activa límits de velocitat per als vagons: {STRING} STR_CONFIG_SETTING_WAGONSPEEDLIMITS_HELPTEXT :Quan està activat, també utilitza els límits de velocitat dels vagons per decidir la velocitat màxima del tren @@ -2055,14 +2062,17 @@ STR_CONFIG_SETTING_ACCOUNTING :Comptabilitat STR_CONFIG_SETTING_VEHICLES :Vehicles STR_CONFIG_SETTING_VEHICLES_PHYSICS :Lleis físiques STR_CONFIG_SETTING_VEHICLES_ROUTING :Recorreguts +STR_CONFIG_SETTING_VEHICLES_ORDERS :Ordres STR_CONFIG_SETTING_LIMITATIONS :Limitacions STR_CONFIG_SETTING_ACCIDENTS :Desastres / Accidents STR_CONFIG_SETTING_GENWORLD :Generació del món STR_CONFIG_SETTING_ENVIRONMENT :Interacció amb l'entorn +STR_CONFIG_SETTING_ENVIRONMENT_TIME :Temps STR_CONFIG_SETTING_ENVIRONMENT_AUTHORITIES :Autoritats STR_CONFIG_SETTING_ENVIRONMENT_TOWNS :Poblacions STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES :Indústries STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :Distribució de la càrrega +STR_CONFIG_SETTING_ENVIRONMENT_TREES :Arbres STR_CONFIG_SETTING_AI :Competidors STR_CONFIG_SETTING_AI_NPC :Jugadors IA STR_CONFIG_SETTING_NETWORK :Xarxa @@ -2720,9 +2730,9 @@ STR_RAIL_TOOLBAR_MAGLEV_CONSTRUCTION_CAPTION :Construcció de STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Construeix vies de tren. Ctrl canvia entre contrueix/treu la construcció de vies. Shift commuta construeix/mostra el cost estimat STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}Construeix vies de tren utilitzant el mode Autorail. Ctrl canvia entre construeix/treu la construcció de vies de tren. Shift commuta construeix/mostra el cost estimat STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Construeix unes cotxeres (per construir i revisar trens). Shift commuta construeix/mostra el cost estimat -STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Converteix una via en un punt de control. Ctrl permet ajuntar punts de control. Shift commuta construeix/mostra el cost estimat +STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Construeix un punt de control en una via de ferrocarril. Ctrl permet ajuntar punts de control. Amb Maj. es commuta entre construir o mostrar el cost estimat. STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}Construeix una estació de tren. Ctrl permet ajuntar estacions. Shift commuta construeix/mostra el cost estimat -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Construeix senyals de tren. Ctrl commuta entre semàfors mecànics i elèctrics{}Arrossegant es construeixen senyals al llarg d'un tros recte de rail. Ctrl construeix senyals fins a la propera intersecció o senyal{}Ctrl+Clic commuta l'obertura de la finestra de detecció de senyals. Shift commuta construir/mostrar el cost estimat +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Construeix senyals de tren en vies de ferrocarril. Ctrl commuta entre semàfors mecànics i elèctrics.{}Arrossegant es construeixen senyals al llarg d'un tros recte de rail. Ctrl construeix senyals fins a la propera intersecció o senyal.{}Ctrl+Clic commuta l'obertura de la finestra de detecció de senyals. Shift commuta construir/mostrar el cost estimat. STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE :{BLACK}Construeix un pont de tren. Shift commuta construeix/mostra el cost estimat STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL :{BLACK}Construeix un túnel per a trens. Shift commuta construeix/mostra el cost estimat STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Commuta construeix/treu per vies de tren, senyals, punts de control i estacions. Mantingueu Ctrl per treure també les vies dels punts de control i de les estacions @@ -2810,7 +2820,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Construe STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT :{BLACK}Construeix cotxeres de tramvies (per comprar i revisar tramvies). Shift commuta construeix/mostra el cost estimat STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION :{BLACK}Construeix estacions d'autobús. Ctrl permet ajuntar estacions. Shift commuta construeix/mostra el cost estimat STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION :{BLACK}Construeix una estació de tramvies. Ctrl permet ajuntar estacions. Shift commuta construeix/mostra el cost estimat -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY :{BLACK}Construeix un moll de càrrega. Ctrl permet ajuntar estacions. Shift commuta construeix/mostra el cost estimat +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY :{BLACK}Construeix una estació per a camions. Ctrl permet ajuntar estacions. Amb Maj. es commuta entre construir o mostrar el cost estimat. STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION :{BLACK}Construeix una estació de tramvies de mercaderies. Ctrl permet ajuntar estacions. Shift commuta construeix/mostra el cost estimat STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD :{BLACK}Activa/Desactiva les carreteres d'un sentit STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE :{BLACK}Construeix un pont per carretera. Shift commuta construeix/mostra el cost estimat @@ -2835,7 +2845,7 @@ STR_BUILD_DEPOT_TRAM_ORIENTATION_SELECT_TOOLTIP :{BLACK}Seleccio STR_STATION_BUILD_BUS_ORIENTATION :{WHITE}Orientació Parada d'autobús STR_STATION_BUILD_BUS_ORIENTATION_TOOLTIP :{BLACK}Selecciona l'orientació de la parada d'autobús STR_STATION_BUILD_TRUCK_ORIENTATION :{WHITE}Orientació Estació de Mercaderies -STR_STATION_BUILD_TRUCK_ORIENTATION_TOOLTIP :{BLACK}Selecciona l'orientació del moll de càrrega de camions +STR_STATION_BUILD_TRUCK_ORIENTATION_TOOLTIP :{BLACK}Seleccioneu l'orientació de l'estació per a camions. STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION :{WHITE}Orientació estació de tramvies de passatgers STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION_TOOLTIP :{BLACK}Selecciona l'orientació de l'estació de tramvies de passatgers STR_STATION_BUILD_CARGO_TRAM_ORIENTATION :{WHITE}Orientació estació de tramvies de mercaderies @@ -3013,7 +3023,7 @@ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Propieta STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Autoritat local: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Cap STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordenades: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) -STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construït: {LTBLUE}{DATE_LONG} +STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construït/renovat: {LTBLUE}{DATE_LONG} STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Classe d'estació: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Tipus d'estació: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Classe de l'aeroport: {LTBLUE}{STRING} @@ -3079,7 +3089,7 @@ STR_LAI_TREE_NAME_CACTUS_PLANTS :Plantes de Cact STR_LAI_STATION_DESCRIPTION_RAILROAD_STATION :Estació de Ferrocarril STR_LAI_STATION_DESCRIPTION_AIRCRAFT_HANGAR :Hangar d'Avions STR_LAI_STATION_DESCRIPTION_AIRPORT :Aeroport -STR_LAI_STATION_DESCRIPTION_TRUCK_LOADING_AREA :Moll de càrrega de camions +STR_LAI_STATION_DESCRIPTION_TRUCK_LOADING_AREA :Estació de camions STR_LAI_STATION_DESCRIPTION_BUS_STATION :Parada d'autobús STR_LAI_STATION_DESCRIPTION_SHIP_DOCK :Moll per vaixells STR_LAI_STATION_DESCRIPTION_BUOY :Boia From 500870627d1c9bdd10a31afe76f808aef7610e04 Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Sat, 20 Jan 2024 13:49:34 -0500 Subject: [PATCH 07/27] Change: Rewrite a few main toolbar tooltips (#11717) --- src/lang/english.txt | 80 ++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 4a07f6cf00..0d0f0fbf2f 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -370,32 +370,32 @@ STR_TOOLBAR_TOOLTIP_PAUSE_GAME :{BLACK}Pause ga STR_TOOLBAR_TOOLTIP_FORWARD :{BLACK}Fast forward the game STR_TOOLBAR_TOOLTIP_OPTIONS :{BLACK}Options and settings STR_TOOLBAR_TOOLTIP_SAVE_GAME_ABANDON_GAME :{BLACK}Save, load or abandon game, exit program -STR_TOOLBAR_TOOLTIP_DISPLAY_MAP :{BLACK}Display map, extra viewport, cargo flow or list of signs -STR_TOOLBAR_TOOLTIP_DISPLAY_TOWN_DIRECTORY :{BLACK}Display town directory -STR_TOOLBAR_TOOLTIP_DISPLAY_SUBSIDIES :{BLACK}Display subsidies -STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_STATIONS :{BLACK}Display list of company's stations -STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_FINANCES :{BLACK}Display company finances information -STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_GENERAL :{BLACK}Display general company information -STR_TOOLBAR_TOOLTIP_DISPLAY_STORY_BOOK :{BLACK}Display story book -STR_TOOLBAR_TOOLTIP_DISPLAY_GOALS_LIST :{BLACK}Display goal list -STR_TOOLBAR_TOOLTIP_DISPLAY_GRAPHS :{BLACK}Display company graphs and cargo payment rates -STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_LEAGUE :{BLACK}Display company league table -STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}Examine industries or fund construction of a new industry -STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_TRAINS :{BLACK}Display list of company's trains. Ctrl+Click toggles opening the group/vehicle list -STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_ROAD_VEHICLES :{BLACK}Display list of company's road vehicles. Ctrl+Click toggles opening the group/vehicle list -STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_SHIPS :{BLACK}Display list of company's ships. Ctrl+Click toggles opening the group/vehicle list -STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_AIRCRAFT :{BLACK}Display list of company's aircraft. Ctrl+Click toggles opening the group/vehicle list -STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Zoom the view in -STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Zoom the view out -STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Build railway track -STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Build roads -STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Build tramways -STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Build ship docks +STR_TOOLBAR_TOOLTIP_DISPLAY_MAP :{BLACK}Open map, extra viewport, cargo flow or list of signs +STR_TOOLBAR_TOOLTIP_DISPLAY_TOWN_DIRECTORY :{BLACK}Open town directory or found town +STR_TOOLBAR_TOOLTIP_DISPLAY_SUBSIDIES :{BLACK}Open subsidy list +STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_STATIONS :{BLACK}Open list of company's stations +STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_FINANCES :{BLACK}Open company finances information +STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_GENERAL :{BLACK}Open general company information +STR_TOOLBAR_TOOLTIP_DISPLAY_STORY_BOOK :{BLACK}Open story book +STR_TOOLBAR_TOOLTIP_DISPLAY_GOALS_LIST :{BLACK}Open goal list +STR_TOOLBAR_TOOLTIP_DISPLAY_GRAPHS :{BLACK}Open company graphs and cargo payment rates +STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_LEAGUE :{BLACK}Open company league table +STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}Open industry directory, industry chain, or fund construction of a new industry +STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_TRAINS :{BLACK}Open list of company's trains. Ctrl+Click toggles opening the group/vehicle list +STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_ROAD_VEHICLES :{BLACK}Open list of company's road vehicles. Ctrl+Click toggles opening the group/vehicle list +STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_SHIPS :{BLACK}Open list of company's ships. Ctrl+Click toggles opening the group/vehicle list +STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_AIRCRAFT :{BLACK}Open list of company's aircraft. Ctrl+Click toggles opening the group/vehicle list +STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Zoom in +STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Zoom out +STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Build railway infrastructure +STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Build road infrastructure +STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Build tramway infrastructure +STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Build waterway infrastructure STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Build airports -STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Open the landscaping toolbar to raise/lower land, plant trees, etc. -STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Show sound/music window -STR_TOOLBAR_TOOLTIP_SHOW_LAST_MESSAGE_NEWS :{BLACK}Show last message/news report, messages history or delete all messages -STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION :{BLACK}Land area information, screenshot, about OpenTTD and developer tools +STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Open landscaping menu, tree menu, or place a sign +STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Open sound/music window +STR_TOOLBAR_TOOLTIP_SHOW_LAST_MESSAGE_NEWS :{BLACK}Open last message/news report, messages history or delete all messages +STR_TOOLBAR_TOOLTIP_LAND_BLOCK_INFORMATION :{BLACK}Open land information, screenshot menu, OpenTTD credits, or developer tools STR_TOOLBAR_TOOLTIP_SWITCH_TOOLBAR :{BLACK}Switch toolbars # Extra tooltips for the scenario editor toolbar @@ -405,12 +405,12 @@ STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR :{YELLOW}Scenari STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD :{BLACK}Move the starting date backward 1 year STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD :{BLACK}Move the starting date forward 1 year STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE :{BLACK}Click to enter the starting year -STR_SCENEDIT_TOOLBAR_TOOLTIP_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Display map, town directory -STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Landscape generation -STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Town generation -STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Industry generation -STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Road construction -STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Tramway construction +STR_SCENEDIT_TOOLBAR_TOOLTIP_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Open map, extra viewport, sign list, or town or industry directory +STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Open landscaping menu or generate a new world +STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Build or generate towns +STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Build or generate industries +STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Build road infrastructure +STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Build tramway infrastructure STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plant trees. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Place sign STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Place object. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate @@ -2147,14 +2147,14 @@ STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE :{BLACK}Select ' STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE :{BLACK}Select 'sub-tropical' landscape style STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE :{BLACK}Select 'toyland' landscape style -STR_INTRO_TOOLTIP_GAME_OPTIONS :{BLACK}Display game options -STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Display highscore table +STR_INTRO_TOOLTIP_GAME_OPTIONS :{BLACK}Open game options +STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Open highscore table STR_INTRO_TOOLTIP_HELP :{BLACK}Get access to documentation and online resources -STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Display settings -STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Display NewGRF settings +STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Open settings +STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Open NewGRF settings STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Check for new and updated content to download -STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Display AI settings -STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Display Game script settings +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Open AI settings +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Open Game script settings STR_INTRO_TOOLTIP_QUIT :{BLACK}Exit 'OpenTTD' STR_INTRO_BASESET :{BLACK}The currently selected base graphics set is missing {NUM} sprite{P "" s}. Please check for updates for the baseset. @@ -3257,11 +3257,11 @@ STR_MAPGEN_VARIETY :{BLACK}Variety STR_MAPGEN_GENERATE :{WHITE}Generate STR_MAPGEN_GENERATE_TOOLTIP :{BLACK}Create the world and play OpenTTD! STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}NewGRF Settings -STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Display NewGRF settings +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Open NewGRF settings STR_MAPGEN_AI_SETTINGS :{BLACK}AI Settings -STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Display AI settings +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Open AI settings STR_MAPGEN_GS_SETTINGS :{BLACK}Game Script Settings -STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Display game script settings +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Open game script settings ###length 21 STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :English (Original) From fa479c4a7c062ba5c52aeb0cf2e3bcfd982cea7a Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Sat, 20 Jan 2024 14:26:39 -0500 Subject: [PATCH 08/27] Cleanup: Describe modifier keys more consistently in tooltips (#11716) --- src/lang/english.txt | 238 +++++++++++++++++++++---------------------- 1 file changed, 119 insertions(+), 119 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 0d0f0fbf2f..35600f0b19 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -282,7 +282,7 @@ STR_TOOLTIP_RESIZE :{BLACK}Click an STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Toggle large/small window size STR_TOOLTIP_VSCROLL_BAR_SCROLLS_LIST :{BLACK}Scroll bar - scrolls list up/down STR_TOOLTIP_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Scroll bar - scrolls list left/right -STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC :{BLACK}Demolish buildings etc. on a square of land. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate +STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC :{BLACK}Demolish buildings etc. on a square of land. Ctrl+Click+Drag to select the area diagonally. Also press Shift to show cost estimate only # Show engines button ###length VEHICLE_TYPES @@ -381,10 +381,10 @@ STR_TOOLBAR_TOOLTIP_DISPLAY_GOALS_LIST :{BLACK}Open goa STR_TOOLBAR_TOOLTIP_DISPLAY_GRAPHS :{BLACK}Open company graphs and cargo payment rates STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_LEAGUE :{BLACK}Open company league table STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}Open industry directory, industry chain, or fund construction of a new industry -STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_TRAINS :{BLACK}Open list of company's trains. Ctrl+Click toggles opening the group/vehicle list -STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_ROAD_VEHICLES :{BLACK}Open list of company's road vehicles. Ctrl+Click toggles opening the group/vehicle list -STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_SHIPS :{BLACK}Open list of company's ships. Ctrl+Click toggles opening the group/vehicle list -STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_AIRCRAFT :{BLACK}Open list of company's aircraft. Ctrl+Click toggles opening the group/vehicle list +STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_TRAINS :{BLACK}Open list of company's trains. Ctrl+Click to show or hide vehicle groups, opposite of the chosen setting +STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_ROAD_VEHICLES :{BLACK}Open list of company's road vehicles. Ctrl+Click to show or hide vehicle groups, opposite of the chosen setting +STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_SHIPS :{BLACK}Open list of company's ships. Ctrl+Click to show or hide vehicle groups, opposite of the chosen setting +STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_AIRCRAFT :{BLACK}Open list of company's aircraft. Ctrl+Click to show or hide vehicle groups, opposite of the chosen setting STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Zoom in STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Zoom out STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Build railway infrastructure @@ -411,9 +411,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Build or STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Build or generate industries STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Build road infrastructure STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Build tramway infrastructure -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plant trees. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plant trees. Ctrl+Click+Drag to select the area diagonally. Also press Shift to show cost estimate only STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Place sign -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Place object. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Place object. Ctrl+Click+Drag to select the area diagonally. Also press Shift to show cost estimate only # Scenario editor file menu ###length 7 @@ -1037,7 +1037,7 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Check th STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Current driver: {RAW_STRING} STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Interface size -STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Drag slider to set interface size. Hold Ctrl for continuous adjustment +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Drag slider to set interface size. Ctrl+Drag for continuous adjustment STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Auto-detect size STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Check this box to detect interface size automatically @@ -1334,7 +1334,7 @@ STR_CONFIG_SETTING_FORBID_90_DEG :Forbid trains f STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90 degree turns occur when a horizontal track is directly followed by a vertical track piece on the adjacent tile, thus making the train turn by 90 degree when traversing the tile edge instead of the usual 45 degrees for other track combinations. STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Allow to join stations not directly adjacent: {STRING2} -STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Allow adding parts to a station without directly touching the existing parts. Needs Ctrl+Click while placing the new parts +STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Allow adding parts to a station without directly touching the existing parts, by Ctrl+Clicking while placing the new parts STR_CONFIG_SETTING_INFLATION :Inflation: {STRING2} STR_CONFIG_SETTING_INFLATION_HELPTEXT :Enable inflation in the economy, where costs are slightly faster rising than payments @@ -1874,7 +1874,7 @@ STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE :Automatically b STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE_HELPTEXT :Set the year when electric signals will be used for tracks. Before this year, non-electric signals will be used (which have the exact same function, but different looks) STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES :Cycle through signal types: {STRING2} -STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT :Select which signal types to cycle through when Ctrl+clicking on a built signal with the signal tool +STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT :Select which signal types to cycle through when Ctrl+Clicking on a built signal with the signal tool ###length 2 STR_CONFIG_SETTING_CYCLE_SIGNAL_PBS :Path signals only STR_CONFIG_SETTING_CYCLE_SIGNAL_ALL :All visible @@ -2212,8 +2212,8 @@ STR_LIVERY_TRAIN_GROUP_TOOLTIP :{BLACK}Show col STR_LIVERY_ROAD_VEHICLE_GROUP_TOOLTIP :{BLACK}Show colours of road vehicle groups STR_LIVERY_SHIP_GROUP_TOOLTIP :{BLACK}Show colours of ship groups STR_LIVERY_AIRCRAFT_GROUP_TOOLTIP :{BLACK}Show colours of aircraft groups -STR_LIVERY_PRIMARY_TOOLTIP :{BLACK}Choose the primary colour for the selected scheme. Ctrl+Click will set this colour for every scheme -STR_LIVERY_SECONDARY_TOOLTIP :{BLACK}Choose the secondary colour for the selected scheme. Ctrl+Click will set this colour for every scheme +STR_LIVERY_PRIMARY_TOOLTIP :{BLACK}Choose the primary colour for the selected scheme. Ctrl+Click to set this colour for every scheme +STR_LIVERY_SECONDARY_TOOLTIP :{BLACK}Choose the secondary colour for the selected scheme. Ctrl+Click to set this colour for every scheme STR_LIVERY_PANEL_TOOLTIP :{BLACK}Select a colour scheme to change, or multiple schemes with Ctrl+Click. Click on the box to toggle use of the scheme STR_LIVERY_TRAIN_GROUP_EMPTY :No train groups are set up STR_LIVERY_ROAD_VEHICLE_GROUP_EMPTY :No road vehicle groups are set up @@ -2726,16 +2726,16 @@ STR_RAIL_TOOLBAR_ELRAIL_CONSTRUCTION_CAPTION :Electrified Rai STR_RAIL_TOOLBAR_MONORAIL_CONSTRUCTION_CAPTION :Monorail Construction STR_RAIL_TOOLBAR_MAGLEV_CONSTRUCTION_CAPTION :Maglev Construction -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Build railway track. Ctrl toggles build/remove for railway construction. Shift toggles building/showing cost estimate -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}Build railway track using the Autorail mode. Ctrl toggles build/remove for railway construction. Shift toggles building/showing cost estimate -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Build train depot (for buying and servicing trains). Shift toggles building/showing cost estimate -STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Build waypoint on railway. Ctrl enables joining waypoints. Shift toggles building/showing cost estimate -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}Build railway station. Ctrl enables joining stations. Shift toggles building/showing cost estimate -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Build signal on railway. Ctrl toggles semaphore/light signals{}Dragging builds signals along a straight stretch of rail. Ctrl builds signals up to the next junction or signal{}Ctrl+Click toggles opening the signal selection window. Shift toggles building/showing cost estimate -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE :{BLACK}Build railway bridge. Shift toggles building/showing cost estimate -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL :{BLACK}Build railway tunnel. Shift toggles building/showing cost estimate -STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Toggle build/remove for railway track, signals, waypoints and stations. Hold Ctrl to also remove the rail of waypoints and stations -STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL :{BLACK}Convert/Upgrade the type of rail. Shift toggles building/showing cost estimate +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Build railway track. Ctrl+Click to remove railway track. Also press Shift to show cost estimate only +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}Build railway track using the Autorail mode. Ctrl+Click to remove railway track. Also press Shift to show cost estimate only +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Build train depot (for buying and servicing trains). Also press Shift to show cost estimate only +STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Build waypoint on railway. Ctrl+Click to select another waypoint to join. Also press Shift to show cost estimate only +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}Build railway station. Ctrl+Click to select another station to join. Also press Shift to show cost estimate only +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Build signal on railway. Ctrl+Click to build the alternate signal style{}Click+Drag to fill the selected section of rail with signals at the chosen spacing. Ctrl+Click+Drag to fill signals up to the next junction, station, or signal. Also press Shift to show cost estimate only +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE :{BLACK}Build railway bridge. Also press Shift to show cost estimate only +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL :{BLACK}Build railway tunnel. Also press Shift to show cost estimate only +STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Toggle build/remove for railway track, signals, waypoints and stations. Ctrl+Click to also remove the rail of waypoints and stations +STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL :{BLACK}Convert/Upgrade the type of rail. Also press Shift to show cost estimate only STR_RAIL_NAME_RAILROAD :Railway STR_RAIL_NAME_ELRAIL :Electrified railway @@ -2785,7 +2785,7 @@ STR_BUILD_SIGNAL_ELECTRIC_EXIT_TOOLTIP :{BLACK}Exit Sig STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Combo Signal (electric){}The combo signal simply acts as both an entry and exit signal. This allows you to build large "trees" of pre-signals STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Path Signal (electric){}A path signal allows more than one train to enter a signal block at the same time, if the train can reserve a path to a safe stopping point. Standard path signals can be passed from the back side STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}One-way Path Signal (electric){}A path signal allows more than one train to enter a signal block at the same time, if the train can reserve a path to a safe stopping point. One-way path signals can't be passed from the back side -STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Signal Convert{}When selected, clicking an existing signal will convert it to the selected signal type and variant. Ctrl+Click will toggle the existing variant. Shift+Click shows estimated conversion cost +STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Signal Convert{}Click an existing signal to convert it to the selected signal type and variant. Ctrl+Click to toggle the existing variant. Shift+Click shows estimated conversion cost STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP :{BLACK}Dragging signal distance STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP :{BLACK}Decrease dragging signal distance STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Increase dragging signal distance @@ -2811,25 +2811,25 @@ STR_BRIDGE_TUBULAR_SILICON :Tubular, Silico # Road construction toolbar STR_ROAD_TOOLBAR_ROAD_CONSTRUCTION_CAPTION :{WHITE}Road Construction STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION :{WHITE}Tramway Construction -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION :{BLACK}Build road section. Ctrl toggles build/remove for road construction. Shift toggles building/showing cost estimate -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION :{BLACK}Build tramway section. Ctrl toggles build/remove for tramway construction. Shift toggles building/showing cost estimate -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD :{BLACK}Build road section using the Autoroad mode. Ctrl toggles build/remove for road construction. Shift toggles building/showing cost estimate -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM :{BLACK}Build tramway section using the Autotram mode. Ctrl toggles build/remove for tramway construction. Shift toggles building/showing cost estimate -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Build road vehicle depot (for buying and servicing vehicles). Shift toggles building/showing cost estimate -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT :{BLACK}Build tram vehicle depot (for buying and servicing vehicles). Shift toggles building/showing cost estimate -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION :{BLACK}Build bus station. Ctrl enables joining stations. Shift toggles building/showing cost estimate -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION :{BLACK}Build passenger tram station. Ctrl enables joining stations. Shift toggles building/showing cost estimate -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY :{BLACK}Build lorry station. Ctrl enables joining stations. Shift toggles building/showing cost estimate -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION :{BLACK}Build freight tram station. Ctrl enables joining stations. Shift toggles building/showing cost estimate +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION :{BLACK}Build road section. Ctrl+Click to remove road section. Also press Shift to show cost estimate only +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION :{BLACK}Build tramway section. Ctrl+Click to remove tramway section. Also press Shift to show cost estimate only +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD :{BLACK}Build road section using the Autoroad mode. Ctrl+Click to remove road section. Also press Shift to show cost estimate only +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM :{BLACK}Build tramway section using the Autotram mode. Ctrl+Click to remove tramway section. Also press Shift to show cost estimate only +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Build road vehicle depot (for buying and servicing vehicles). Also press Shift to show cost estimate only +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT :{BLACK}Build tram vehicle depot (for buying and servicing vehicles). Also press Shift to show cost estimate only +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION :{BLACK}Build bus station. Ctrl+Click to select another station to join. Also press Shift to show cost estimate only +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION :{BLACK}Build passenger tram station. Ctrl+Click to select another station to join. Also press Shift to show cost estimate only +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY :{BLACK}Build lorry station. Ctrl+Click to select another station to join. Also press Shift to show cost estimate only +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION :{BLACK}Build freight tram station. Ctrl+Click to select another station to join. Also press Shift to show cost estimate only STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD :{BLACK}Activate/Deactivate one way roads -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE :{BLACK}Build road bridge. Shift toggles building/showing cost estimate -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE :{BLACK}Build tramway bridge. Shift toggles building/showing cost estimate -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Build road tunnel. Shift toggles building/showing cost estimate -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Build tramway tunnel. Shift toggles building/showing cost estimate +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE :{BLACK}Build road bridge. Also press Shift to show cost estimate only +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE :{BLACK}Build tramway bridge. Also press Shift to show cost estimate only +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Build road tunnel. Also press Shift to show cost estimate only +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Build tramway tunnel. Also press Shift to show cost estimate only STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Toggle build/remove for road construction STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Toggle build/remove for tramway construction -STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Convert/Upgrade the type of road. Shift toggles building/showing cost estimate -STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Convert/Upgrade the type of tram. Shift toggles building/showing cost estimate +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Convert/Upgrade the type of road. Also press Shift to show cost estimate only +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Convert/Upgrade the type of tram. Also press Shift to show cost estimate only STR_ROAD_NAME_ROAD :Road STR_ROAD_NAME_TRAM :Tramway @@ -2853,14 +2853,14 @@ STR_STATION_BUILD_CARGO_TRAM_ORIENTATION_TOOLTIP :{BLACK}Select f # Waterways toolbar (last two for SE only) STR_WATERWAYS_TOOLBAR_CAPTION :{WHITE}Waterways Construction STR_WATERWAYS_TOOLBAR_CAPTION_SE :{WHITE}Waterways -STR_WATERWAYS_TOOLBAR_BUILD_CANALS_TOOLTIP :{BLACK}Build canals. Shift toggles building/showing cost estimate -STR_WATERWAYS_TOOLBAR_BUILD_LOCKS_TOOLTIP :{BLACK}Build locks. Shift toggles building/showing cost estimate -STR_WATERWAYS_TOOLBAR_BUILD_DEPOT_TOOLTIP :{BLACK}Build ship depot (for buying and servicing ships). Shift toggles building/showing cost estimate -STR_WATERWAYS_TOOLBAR_BUILD_DOCK_TOOLTIP :{BLACK}Build ship dock. Ctrl enables joining stations. Shift toggles building/showing cost estimate -STR_WATERWAYS_TOOLBAR_BUOY_TOOLTIP :{BLACK}Place a buoy which can be used as a waypoint. Shift toggles building/showing cost estimate -STR_WATERWAYS_TOOLBAR_BUILD_AQUEDUCT_TOOLTIP :{BLACK}Build aqueduct. Shift toggles building/showing cost estimate -STR_WATERWAYS_TOOLBAR_CREATE_LAKE_TOOLTIP :{BLACK}Define water area.{}Make a canal, unless Ctrl is held down at sea level, when it will flood the surroundings instead -STR_WATERWAYS_TOOLBAR_CREATE_RIVER_TOOLTIP :{BLACK}Place rivers. Ctrl selects the area diagonally +STR_WATERWAYS_TOOLBAR_BUILD_CANALS_TOOLTIP :{BLACK}Build canals. Also press Shift to show cost estimate only +STR_WATERWAYS_TOOLBAR_BUILD_LOCKS_TOOLTIP :{BLACK}Build locks. Also press Shift to show cost estimate only +STR_WATERWAYS_TOOLBAR_BUILD_DEPOT_TOOLTIP :{BLACK}Build ship depot (for buying and servicing ships). Also press Shift to show cost estimate only +STR_WATERWAYS_TOOLBAR_BUILD_DOCK_TOOLTIP :{BLACK}Build ship dock. Ctrl+Click to select another station to join. Also press Shift to show cost estimate only +STR_WATERWAYS_TOOLBAR_BUOY_TOOLTIP :{BLACK}Place a buoy which can be used as a waypoint. Also press Shift to show cost estimate only +STR_WATERWAYS_TOOLBAR_BUILD_AQUEDUCT_TOOLTIP :{BLACK}Build aqueduct. Also press Shift to show cost estimate only +STR_WATERWAYS_TOOLBAR_CREATE_LAKE_TOOLTIP :{BLACK}Build canal. Ctrl+Click at sea level to flood with sea water instead +STR_WATERWAYS_TOOLBAR_CREATE_RIVER_TOOLTIP :{BLACK}Place rivers. Ctrl+Click to select diagonally # Ship depot construction window STR_DEPOT_BUILD_SHIP_CAPTION :{WHITE}Ship Depot Orientation @@ -2871,7 +2871,7 @@ STR_STATION_BUILD_DOCK_CAPTION :{WHITE}Dock # Airport toolbar STR_TOOLBAR_AIRCRAFT_CAPTION :{WHITE}Airports -STR_TOOLBAR_AIRCRAFT_BUILD_AIRPORT_TOOLTIP :{BLACK}Build airport. Ctrl enables joining stations. Shift toggles building/showing cost estimate +STR_TOOLBAR_AIRCRAFT_BUILD_AIRPORT_TOOLTIP :{BLACK}Build airport. Ctrl+Click to select another station to join. Also press Shift to show cost estimate only # Airport construction window STR_STATION_BUILD_AIRPORT_CAPTION :{WHITE}Airport Selection @@ -2898,14 +2898,14 @@ STR_STATION_BUILD_NOISE :{BLACK}Noise ge # Landscaping toolbar STR_LANDSCAPING_TOOLBAR :{WHITE}Landscaping -STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Lower a corner of land. Dragging lowers the first selected corner and levels the selected area to the new corner height. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate -STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Raise a corner of land. Dragging raises the first selected corner and levels the selected area to the new corner height. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate -STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Level an area of land to the height of the first selected corner. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Purchase land for future use. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate +STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Lower a corner of land. Click+Drag to lower the first selected corner and level the selected area to the new corner height. Ctrl+Click+Drag to select the area diagonally. Also press Shift to show cost estimate only +STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Raise a corner of land. Click+Drag to raise the first selected corner and level the selected area to the new corner height. Ctrl+Click+Drag to select the area diagonally. Also press Shift to show cost estimate only +STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Level an area of land to the height of the first selected corner. Ctrl+Click+Drag to select the area diagonally. Also press Shift to show cost estimate only +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Purchase land for future use. Ctrl+Click+Drag to select the area diagonally. Also press Shift to show cost estimate only # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Object Selection -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Select object to build. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Select object to build. Ctrl+Click+Drag to select the area diagonally. Also press Shift to show cost estimate only STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Select class of the object to build STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Preview of the object STR_OBJECT_BUILD_SIZE :{BLACK}Size: {GOLD}{NUM} x {NUM} tiles @@ -2917,7 +2917,7 @@ STR_OBJECT_CLASS_TRNS :Transmitters STR_PLANT_TREE_CAPTION :{WHITE}Trees STR_PLANT_TREE_TOOLTIP :{BLACK}Select tree type to plant. If the tile already has a tree, this will add more trees of mixed types independent of the selected type STR_TREES_RANDOM_TYPE :{BLACK}Trees of random type -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Place trees of random type. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Place trees of random type. Ctrl+Click+Drag to select the area diagonally. Also press Shift to show cost estimate only STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Random Trees STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Plant trees randomly throughout the landscape STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal @@ -2930,7 +2930,7 @@ STR_TREES_MODE_FOREST_LG_TOOLTIP :{BLACK}Plant la # Land generation window (SE) STR_TERRAFORM_TOOLBAR_LAND_GENERATION_CAPTION :{WHITE}Land Generation STR_TERRAFORM_TOOLTIP_PLACE_ROCKY_AREAS_ON_LANDSCAPE :{BLACK}Place rocky areas on landscape -STR_TERRAFORM_TOOLTIP_DEFINE_DESERT_AREA :{BLACK}Define desert area.{}Hold Ctrl to remove it +STR_TERRAFORM_TOOLTIP_DEFINE_DESERT_AREA :{BLACK}Define desert area.{}Ctrl+Click to remove desert area STR_TERRAFORM_TOOLTIP_INCREASE_SIZE_OF_LAND_AREA :{BLACK}Increase area of land to lower/raise STR_TERRAFORM_TOOLTIP_DECREASE_SIZE_OF_LAND_AREA :{BLACK}Decrease area of land to lower/raise STR_TERRAFORM_TOOLTIP_GENERATE_RANDOM_LAND :{BLACK}Generate random land @@ -2944,7 +2944,7 @@ STR_RESET_LANDSCAPE_CONFIRMATION_TEXT :{WHITE}Are you # Town generation window (SE) STR_FOUND_TOWN_CAPTION :{WHITE}Town Generation STR_FOUND_TOWN_NEW_TOWN_BUTTON :{BLACK}New Town -STR_FOUND_TOWN_NEW_TOWN_TOOLTIP :{BLACK}Found new town. Shift+Click shows only estimated cost +STR_FOUND_TOWN_NEW_TOWN_TOOLTIP :{BLACK}Found new town. Also press Shift to show cost estimate only STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Random Town STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Found town in random location STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Many random towns @@ -3010,7 +3010,7 @@ STR_INDUSTRY_CARGOES_SELECT_INDUSTRY_TOOLTIP :{BLACK}Select t # Land area window STR_LAND_AREA_INFORMATION_CAPTION :{WHITE}Land Area Information -STR_LAND_AREA_INFORMATION_LOCATION_TOOLTIP :{BLACK}Centre the main view on tile location. Ctrl+Click opens a new viewport on tile location +STR_LAND_AREA_INFORMATION_LOCATION_TOOLTIP :{BLACK}Centre the main view on tile location. Ctrl+Click to open a new viewport on tile location STR_LAND_AREA_INFORMATION_COST_TO_CLEAR_N_A :{BLACK}Cost to clear: {LTBLUE}N/A STR_LAND_AREA_INFORMATION_COST_TO_CLEAR :{BLACK}Cost to clear: {RED}{CURRENCY_LONG} STR_LAND_AREA_INFORMATION_REVENUE_WHEN_CLEARED :{BLACK}Revenue when cleared: {LTBLUE}{CURRENCY_LONG} @@ -3537,7 +3537,7 @@ STR_SIGN_LIST_MATCH_CASE_TOOLTIP :{BLACK}Toggle m # Sign window STR_EDIT_SIGN_CAPTION :{WHITE}Edit sign text -STR_EDIT_SIGN_LOCATION_TOOLTIP :{BLACK}Centre the main view on sign location. Ctrl+Click opens a new viewport on sign location +STR_EDIT_SIGN_LOCATION_TOOLTIP :{BLACK}Centre the main view on sign location. Ctrl+Click to open a new viewport on sign location STR_EDIT_SIGN_NEXT_SIGN_TOOLTIP :{BLACK}Go to next sign STR_EDIT_SIGN_PREVIOUS_SIGN_TOOLTIP :{BLACK}Go to previous sign @@ -3548,7 +3548,7 @@ STR_TOWN_DIRECTORY_CAPTION :{WHITE}Towns 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 opens a new viewport on town location +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} # Town view window @@ -3566,7 +3566,7 @@ STR_TOWN_VIEW_TOWN_GROWS_EVERY :{BLACK}Town gro STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED :{BLACK}Town grows every {ORANGE}{COMMA}{BLACK}{NBSP}day{P "" s} (funded) STR_TOWN_VIEW_TOWN_GROW_STOPPED :{BLACK}Town is {RED}not{BLACK} growing STR_TOWN_VIEW_NOISE_IN_TOWN :{BLACK}Noise limit in town: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} -STR_TOWN_VIEW_CENTER_TOOLTIP :{BLACK}Centre the main view on town location. Ctrl+Click opens a new viewport on town location +STR_TOWN_VIEW_CENTER_TOOLTIP :{BLACK}Centre the main view on town location. Ctrl+Click to open a new viewport on town location STR_TOWN_VIEW_LOCAL_AUTHORITY_BUTTON :{BLACK}Local Authority STR_TOWN_VIEW_LOCAL_AUTHORITY_TOOLTIP :{BLACK}Show information on local authority STR_TOWN_VIEW_RENAME_TOOLTIP :{BLACK}Change town name @@ -3621,7 +3621,7 @@ STR_GOALS_TEXT :{ORANGE}{RAW_ST STR_GOALS_NONE :{ORANGE}- None - STR_GOALS_PROGRESS :{ORANGE}{RAW_STRING} STR_GOALS_PROGRESS_COMPLETE :{GREEN}{RAW_STRING} -STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Click on goal to centre main view on industry/town/tile. Ctrl+Click opens a new viewport on industry/town/tile location +STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Click on goal to centre main view on industry/town/tile. Ctrl+Click to open a new viewport on industry/town/tile location # Goal question window STR_GOAL_QUESTION_CAPTION_QUESTION :{BLACK}Question @@ -3657,7 +3657,7 @@ STR_SUBSIDIES_OFFERED_FROM_TO :{ORANGE}{STRING STR_SUBSIDIES_NONE :{ORANGE}- None - STR_SUBSIDIES_SUBSIDISED_TITLE :{BLACK}Services already subsidised: STR_SUBSIDIES_SUBSIDISED_FROM_TO :{ORANGE}{STRING} from {STRING2} to {STRING2}{YELLOW} ({COMPANY}{YELLOW}, until {DATE_SHORT}) -STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Click on service to centre main view on industry/town. Ctrl+Click opens a new viewport on industry/town location +STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Click on service to centre main view on industry/town. Ctrl+Click to open a new viewport on industry/town location # Story book window STR_STORY_BOOK_CAPTION :{WHITE}{COMPANY} Story Book @@ -3673,8 +3673,8 @@ STR_STORY_BOOK_NEXT_PAGE_TOOLTIP :{BLACK}Go to ne STR_STORY_BOOK_INVALID_GOAL_REF :{RED}Invalid goal reference # Station list window -STR_STATION_LIST_TOOLTIP :{BLACK}Station names - click on name to centre main view on station. Ctrl+Click opens a new viewport on station location -STR_STATION_LIST_USE_CTRL_TO_SELECT_MORE :{BLACK}Hold Ctrl to select more than one item +STR_STATION_LIST_TOOLTIP :{BLACK}Station names - click on name to centre main view on station. Ctrl+Click to open a new viewport on station location +STR_STATION_LIST_USE_CTRL_TO_SELECT_MORE :{BLACK}Ctrl+Click to select multiple items STR_STATION_LIST_CAPTION :{WHITE}{COMPANY} - {COMMA} Station{P "" s} STR_STATION_LIST_STATION :{YELLOW}{STATION} {STATION_FEATURES} STR_STATION_LIST_WAYPOINT :{YELLOW}{WAYPOINT} @@ -3733,7 +3733,7 @@ STR_CARGO_RATING_VERY_GOOD :Very Good STR_CARGO_RATING_EXCELLENT :Excellent STR_CARGO_RATING_OUTSTANDING :Outstanding -STR_STATION_VIEW_CENTER_TOOLTIP :{BLACK}Centre main view on station location. Ctrl+Click opens a new viewport on station location +STR_STATION_VIEW_CENTER_TOOLTIP :{BLACK}Centre main view on station location. Ctrl+Click to open a new viewport on station location STR_STATION_VIEW_RENAME_TOOLTIP :{BLACK}Change name of station STR_STATION_VIEW_SCHEDULED_TRAINS_TOOLTIP :{BLACK}Show all trains which have this station on their schedule @@ -3748,9 +3748,9 @@ STR_STATION_VIEW_CLOSE_AIRPORT_TOOLTIP :{BLACK}Prevent # Waypoint/buoy view window STR_WAYPOINT_VIEW_CAPTION :{WHITE}{WAYPOINT} -STR_WAYPOINT_VIEW_CENTER_TOOLTIP :{BLACK}Centre main view on waypoint location. Ctrl+Click opens a new viewport on waypoint location +STR_WAYPOINT_VIEW_CENTER_TOOLTIP :{BLACK}Centre main view on waypoint location. Ctrl+Click to open a new viewport on waypoint location STR_WAYPOINT_VIEW_CHANGE_WAYPOINT_NAME :{BLACK}Change waypoint name -STR_BUOY_VIEW_CENTER_TOOLTIP :{BLACK}Centre main view on buoy location. Ctrl+Click opens a new viewport on buoy location +STR_BUOY_VIEW_CENTER_TOOLTIP :{BLACK}Centre main view on buoy location. Ctrl+Click to open a new viewport on buoy location STR_BUOY_VIEW_CHANGE_BUOY_NAME :{BLACK}Change buoy name STR_EDIT_WAYPOINT_NAME :{WHITE}Edit waypoint name @@ -3793,9 +3793,9 @@ STR_FINANCES_MAX_LOAN :{WHITE}Maximum STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Borrow {CURRENCY_LONG} -STR_FINANCES_BORROW_TOOLTIP :{BLACK}Increase size of loan. Ctrl+Click borrows as much as possible +STR_FINANCES_BORROW_TOOLTIP :{BLACK}Increase size of loan. Ctrl+Click to borrow as much as possible STR_FINANCES_REPAY_BUTTON :{BLACK}Repay {CURRENCY_LONG} -STR_FINANCES_REPAY_TOOLTIP :{BLACK}Repay part of loan. Ctrl+Click repays as much loan as possible +STR_FINANCES_REPAY_TOOLTIP :{BLACK}Repay part of loan. Ctrl+Click to repay as much loan as possible STR_FINANCES_INFRASTRUCTURE_BUTTON :{BLACK}Infrastructure # Company view @@ -3824,7 +3824,7 @@ STR_COMPANY_VIEW_BUILD_HQ_TOOLTIP :{BLACK}Build co STR_COMPANY_VIEW_VIEW_HQ_BUTTON :{BLACK}View HQ STR_COMPANY_VIEW_VIEW_HQ_TOOLTIP :{BLACK}View company headquarters STR_COMPANY_VIEW_RELOCATE_HQ :{BLACK}Relocate HQ -STR_COMPANY_VIEW_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Rebuild company headquarters elsewhere for 1% cost of company value. Shift+Click shows estimated cost without relocating HQ +STR_COMPANY_VIEW_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Rebuild company headquarters elsewhere for 1% cost of company value. Also press Shift to show cost estimate only STR_COMPANY_VIEW_INFRASTRUCTURE_BUTTON :{BLACK}Details STR_COMPANY_VIEW_INFRASTRUCTURE_TOOLTIP :{BLACK}View detailed infrastructure counts STR_COMPANY_VIEW_GIVE_MONEY_BUTTON :{BLACK}Give money @@ -3870,7 +3870,7 @@ STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUST STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING4}, {STRING4} STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING4}, {STRING4}, {STRING4} STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUSTRY} {STRING4}, {STRING4}, {STRING4} and {NUM} more... -STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Industry names - click on name to centre main view on industry. Ctrl+Click opens a new viewport on industry location +STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Industry names - click on name to centre main view on industry. Ctrl+Click to open a new viewport on industry location STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER :{BLACK}Accepted cargo: {SILVER}{STRING} STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER :{BLACK}Produced cargo: {SILVER}{STRING} STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES :All cargo types @@ -3880,7 +3880,7 @@ STR_INDUSTRY_DIRECTORY_FILTER_NONE :None STR_INDUSTRY_VIEW_CAPTION :{WHITE}{INDUSTRY} STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE :{BLACK}Production last month: STR_INDUSTRY_VIEW_TRANSPORTED :{YELLOW}{CARGO_LONG}{RAW_STRING}{BLACK} ({COMMA}% transported) -STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Centre the main view on industry location. Ctrl+Click opens a new viewport on industry location +STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Centre the main view on industry location. Ctrl+Click to open a new viewport on industry location STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Production level: {YELLOW}{COMMA}% STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}The industry has announced imminent closure! @@ -4019,10 +4019,10 @@ STR_CARGO_TYPE_FILTER_FREIGHT :Freight STR_CARGO_TYPE_FILTER_NONE :None ###length VEHICLE_TYPES -STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Train vehicle selection list. Click on vehicle for information. Ctrl+Click for toggling hiding of the vehicle type -STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Road vehicle selection list. Click on vehicle for information. Ctrl+Click for toggling hiding of the vehicle type -STR_BUY_VEHICLE_SHIP_LIST_TOOLTIP :{BLACK}Ship selection list. Click on ship for information. Ctrl+Click for toggling hiding of the ship type -STR_BUY_VEHICLE_AIRCRAFT_LIST_TOOLTIP :{BLACK}Aircraft selection list. Click on aircraft for information. Ctrl+Click for toggling hiding of the aircraft type +STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Train vehicle selection list. Click on vehicle for information. Ctrl+Click to show/hide this vehicle type +STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Road vehicle selection list. Click on vehicle for information. Ctrl+Click to show/hide of the vehicle type +STR_BUY_VEHICLE_SHIP_LIST_TOOLTIP :{BLACK}Ship selection list. Click on ship for information. Ctrl+Click to show/hide of the ship type +STR_BUY_VEHICLE_AIRCRAFT_LIST_TOOLTIP :{BLACK}Aircraft selection list. Click on aircraft for information. Ctrl+Click to show/hide of the aircraft type ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_BUTTON :{BLACK}Buy Vehicle @@ -4037,16 +4037,16 @@ STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Buy and STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Buy and Refit Aircraft ###length VEHICLE_TYPES -STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted train vehicle. Shift+Click shows estimated cost without purchase -STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted road vehicle. Shift+Click shows estimated cost without purchase -STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted ship. Shift+Click shows estimated cost without purchase -STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted aircraft. Shift+Click shows estimated cost without purchase +STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted train vehicle. Also press Shift to show cost estimate only +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted road vehicle. Also press Shift to show cost estimate only +STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted ship. Also press Shift to show cost estimate only +STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted aircraft. Also press Shift to show cost estimate only ###length VEHICLE_TYPES -STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted train vehicle. Shift+Click shows estimated cost without purchase -STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted road vehicle. Shift+Click shows estimated cost without purchase -STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted ship. Shift+Click shows estimated cost without purchase -STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted aircraft. Shift+Click shows estimated cost without purchase +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted train vehicle. Also press Shift to show cost estimate only +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted road vehicle. Also press Shift to show cost estimate only +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted ship. Also press Shift to show cost estimate only +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted aircraft. Also press Shift to show cost estimate only ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Rename @@ -4096,7 +4096,7 @@ STR_DEPOT_VEHICLE_TOOLTIP_CHAIN :{BLACK}{NUM} ve STR_DEPOT_VEHICLE_TOOLTIP_CARGO :{}{CARGO_LONG} ({CARGO_SHORT}) ###length VEHICLE_TYPES -STR_DEPOT_TRAIN_LIST_TOOLTIP :{BLACK}Trains - drag vehicle with left-click to add/remove from train, right-click for information. Hold Ctrl to make both functions apply to the following chain +STR_DEPOT_TRAIN_LIST_TOOLTIP :{BLACK}Trains - drag vehicle with left-click to add/remove from train, right-click for information. Ctrl+Click to apply either function to the following chain STR_DEPOT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Vehicles - right-click on vehicle for information STR_DEPOT_SHIP_LIST_TOOLTIP :{BLACK}Ships - right-click on ship for information STR_DEPOT_AIRCRAFT_LIST_TOOLTIP :{BLACK}Aircraft - right-click on aircraft for information @@ -4138,16 +4138,16 @@ STR_DEPOT_CLONE_SHIP :{BLACK}Clone Sh STR_DEPOT_CLONE_AIRCRAFT :{BLACK}Clone Aircraft ###length VEHICLE_TYPES -STR_DEPOT_CLONE_TRAIN_DEPOT_INFO :{BLACK}This will buy a copy of a train including all cars. Click this button and then on a train inside or outside the depot. Ctrl+Click will share the orders. Shift+Click shows estimated cost without purchase -STR_DEPOT_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}This will buy a copy of a road vehicle. Click this button and then on a road vehicle inside or outside the depot. Ctrl+Click will share the orders. Shift+Click shows estimated cost without purchase -STR_DEPOT_CLONE_SHIP_DEPOT_INFO :{BLACK}This will buy a copy of a ship. Click this button and then on a ship inside or outside the depot. Ctrl+Click will share the orders. Shift+Click shows estimated cost without purchase -STR_DEPOT_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}This will buy a copy of an aircraft. Click this button and then on an aircraft inside or outside the hangar. Ctrl+Click will share the orders. Shift+Click shows estimated cost without purchase +STR_DEPOT_CLONE_TRAIN_DEPOT_INFO :{BLACK}Buy a copy of a train including all cars. Click this button and then on a train inside or outside the depot. Ctrl+Click to share the orders. Also press Shift to show cost estimate only +STR_DEPOT_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Buy a copy of a road vehicle. Click this button and then on a road vehicle inside or outside the depot. Ctrl+Click to share the orders. Also press Shift to show cost estimate only +STR_DEPOT_CLONE_SHIP_DEPOT_INFO :{BLACK}Buy a copy of a ship. Click this button and then on a ship inside or outside the depot. Ctrl+Click to share the orders. Also press Shift to show cost estimate only +STR_DEPOT_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Buy a copy of an aircraft. Click this button and then on an aircraft inside or outside the hangar. Ctrl+Click to share the orders. Also press Shift to show cost estimate only ###length VEHICLE_TYPES -STR_DEPOT_TRAIN_LOCATION_TOOLTIP :{BLACK}Centre main view on train depot location. Ctrl+Click opens a new viewport on train depot location -STR_DEPOT_ROAD_VEHICLE_LOCATION_TOOLTIP :{BLACK}Centre main view on road vehicle depot location. Ctrl+Click opens a new viewport on road depot location -STR_DEPOT_SHIP_LOCATION_TOOLTIP :{BLACK}Centre main view on ship depot location. Ctrl+Click opens a new viewport on ship depot location -STR_DEPOT_AIRCRAFT_LOCATION_TOOLTIP :{BLACK}Centre main view on hangar location. Ctrl+Click opens a new viewport on hangar location +STR_DEPOT_TRAIN_LOCATION_TOOLTIP :{BLACK}Centre main view on train depot location. Ctrl+Click to open a new viewport on train depot location +STR_DEPOT_ROAD_VEHICLE_LOCATION_TOOLTIP :{BLACK}Centre main view on road vehicle depot location. Ctrl+Click to open a new viewport on road depot location +STR_DEPOT_SHIP_LOCATION_TOOLTIP :{BLACK}Centre main view on ship depot location. Ctrl+Click to open a new viewport on ship depot location +STR_DEPOT_AIRCRAFT_LOCATION_TOOLTIP :{BLACK}Centre main view on hangar location. Ctrl+Click to open a new viewport on hangar location ###length VEHICLE_TYPES STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TOOLTIP :{BLACK}Get a list of all trains with the current depot in their orders @@ -4248,27 +4248,27 @@ STR_REPLACE_REMOVE_WAGON_GROUP_HELP :{STRING}. Ctrl+ STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} ###length VEHICLE_TYPES -STR_VEHICLE_VIEW_TRAIN_CENTER_TOOLTIP :{BLACK}Centre main view on train's location. Double click will follow train in main view. Ctrl+Click opens a new viewport on train's location -STR_VEHICLE_VIEW_ROAD_VEHICLE_CENTER_TOOLTIP :{BLACK}Centre main view on vehicle's location. Double click will follow vehicle in main view. Ctrl+Click opens a new viewport on vehicle's location -STR_VEHICLE_VIEW_SHIP_CENTER_TOOLTIP :{BLACK}Centre main view on ship's location. Double click will follow ship in main view. Ctrl+Click opens a new viewport on ship's location -STR_VEHICLE_VIEW_AIRCRAFT_CENTER_TOOLTIP :{BLACK}Centre main view on aircraft's location. Double click will follow aircraft in main view. Ctrl+Click opens a new viewport on aircraft's location +STR_VEHICLE_VIEW_TRAIN_CENTER_TOOLTIP :{BLACK}Centre main view on train's location. Double click to follow train in main view. Ctrl+Click to open a new viewport on train's location +STR_VEHICLE_VIEW_ROAD_VEHICLE_CENTER_TOOLTIP :{BLACK}Centre main view on vehicle's location. Double click to follow vehicle in main view. Ctrl+Click to open a new viewport on vehicle's location +STR_VEHICLE_VIEW_SHIP_CENTER_TOOLTIP :{BLACK}Centre main view on ship's location. Double click to follow ship in main view. Ctrl+Click to open a new viewport on ship's location +STR_VEHICLE_VIEW_AIRCRAFT_CENTER_TOOLTIP :{BLACK}Centre main view on aircraft's location. Double click to follow aircraft in main view. Ctrl+Click to open a new viewport on aircraft's location ###length VEHICLE_TYPES -STR_VEHICLE_VIEW_TRAIN_SEND_TO_DEPOT_TOOLTIP :{BLACK}Send train to depot. Ctrl+Click will only service -STR_VEHICLE_VIEW_ROAD_VEHICLE_SEND_TO_DEPOT_TOOLTIP :{BLACK}Send vehicle to depot. Ctrl+Click will only service -STR_VEHICLE_VIEW_SHIP_SEND_TO_DEPOT_TOOLTIP :{BLACK}Send ship to depot. Ctrl+Click will only service -STR_VEHICLE_VIEW_AIRCRAFT_SEND_TO_DEPOT_TOOLTIP :{BLACK}Send aircraft to hangar. Ctrl+Click will only service +STR_VEHICLE_VIEW_TRAIN_SEND_TO_DEPOT_TOOLTIP :{BLACK}Send train to depot. Ctrl+Click to only service +STR_VEHICLE_VIEW_ROAD_VEHICLE_SEND_TO_DEPOT_TOOLTIP :{BLACK}Send vehicle to depot. Ctrl+Click to only service +STR_VEHICLE_VIEW_SHIP_SEND_TO_DEPOT_TOOLTIP :{BLACK}Send ship to depot. Ctrl+Click to only service +STR_VEHICLE_VIEW_AIRCRAFT_SEND_TO_DEPOT_TOOLTIP :{BLACK}Send aircraft to hangar. Ctrl+Click to only service ###length VEHICLE_TYPES -STR_VEHICLE_VIEW_CLONE_TRAIN_INFO :{BLACK}This will buy a copy of the train including all cars. Ctrl+Click will share the orders. Shift+Click shows estimated cost without purchase -STR_VEHICLE_VIEW_CLONE_ROAD_VEHICLE_INFO :{BLACK}This will buy a copy of the road vehicle. Ctrl+Click will share the orders. Shift+Click shows estimated cost without purchase -STR_VEHICLE_VIEW_CLONE_SHIP_INFO :{BLACK}This will buy a copy of the ship. Ctrl+Click will share the orders. Shift+Click shows estimated cost without purchase -STR_VEHICLE_VIEW_CLONE_AIRCRAFT_INFO :{BLACK}This will buy a copy of the aircraft. Ctrl+Click will share the orders. Shift+Click shows estimated cost without purchase +STR_VEHICLE_VIEW_CLONE_TRAIN_INFO :{BLACK}Buy a copy of the train including all cars. Ctrl+Click to share orders. Also press Shift to show cost estimate only +STR_VEHICLE_VIEW_CLONE_ROAD_VEHICLE_INFO :{BLACK}Buy a copy of the road vehicle. Ctrl+Click to share orders. Also press Shift to show cost estimate only +STR_VEHICLE_VIEW_CLONE_SHIP_INFO :{BLACK}Buy a copy of the ship. Ctrl+Click to share orders. Also press Shift to show cost estimate only +STR_VEHICLE_VIEW_CLONE_AIRCRAFT_INFO :{BLACK}Buy a copy of the aircraft. Ctrl+Click to share orders. Also press Shift to show cost estimate only STR_VEHICLE_VIEW_TRAIN_IGNORE_SIGNAL_TOOLTIP :{BLACK}Force train to proceed without waiting for signal to clear it STR_VEHICLE_VIEW_TRAIN_REVERSE_TOOLTIP :{BLACK}Reverse direction of train STR_VEHICLE_VIEW_ROAD_VEHICLE_REVERSE_TOOLTIP :{BLACK}Force vehicle to turn around -STR_VEHICLE_VIEW_ORDER_LOCATION_TOOLTIP :{BLACK}Centre main view on order destination. Ctrl+Click opens a new viewport on the order destination's location +STR_VEHICLE_VIEW_ORDER_LOCATION_TOOLTIP :{BLACK}Centre main view on order destination. Ctrl+Click to open a new viewport on the order destination's location ###length VEHICLE_TYPES STR_VEHICLE_VIEW_TRAIN_REFIT_TOOLTIP :{BLACK}Refit train to carry a different cargo type @@ -4358,8 +4358,8 @@ STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Transfer STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS :{BLACK}Servicing interval: {LTBLUE}{COMMA}{NBSP}days{BLACK} Last service: {LTBLUE}{DATE_LONG} STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT :{BLACK}Servicing interval: {LTBLUE}{COMMA}%{BLACK} Last service: {LTBLUE}{DATE_LONG} -STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}Increase servicing interval by 10. Ctrl+Click increases servicing interval by 5 -STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}Decrease servicing interval by 10. Ctrl+Click decreases servicing interval by 5 +STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}Increase servicing interval by 10. Ctrl+Click to increase servicing interval by 5 +STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}Decrease servicing interval by 10. Ctrl+Click to decrease servicing interval by 5 STR_SERVICE_INTERVAL_DROPDOWN_TOOLTIP :{BLACK}Change servicing interval type STR_VEHICLE_DETAILS_DEFAULT :Default @@ -4402,7 +4402,7 @@ STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}New capa STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT :{BLACK}New capacity: {GOLD}{CARGO_LONG}{}{BLACK}Income from refit: {GREEN}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}New capacity: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Cost of refit: {RED}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT :{BLACK}New capacity: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Income from refit: {GREEN}{CURRENCY_LONG} -STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}Select the vehicles to refit. Dragging with the mouse allows to select multiple vehicles. Clicking on an empty space will select the whole vehicle. Ctrl+Click will select a vehicle and the following chain +STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}Select the vehicles to refit. Click+Drag to select multiple vehicles. Click on an empty space to select the whole vehicle. Ctrl+Click to select a vehicle and the following chain ###length VEHICLE_TYPES STR_REFIT_TRAIN_LIST_TOOLTIP :{BLACK}Select type of cargo for train to carry @@ -4427,7 +4427,7 @@ STR_ORDERS_CAPTION :{WHITE}{VEHICLE STR_ORDERS_TIMETABLE_VIEW :{BLACK}Timetable STR_ORDERS_TIMETABLE_VIEW_TOOLTIP :{BLACK}Switch to the timetable view -STR_ORDERS_LIST_TOOLTIP :{BLACK}Order list - click on an order to highlight it. Ctrl+Click scrolls to the order's destination +STR_ORDERS_LIST_TOOLTIP :{BLACK}Order list - click on an order to highlight it. Ctrl+Click to scroll to the order's destination STR_ORDER_INDEX :{COMMA}:{NBSP} STR_ORDER_TEXT :{STRING4} {STRING2} {STRING} @@ -4497,20 +4497,20 @@ STR_ORDER_CONDITIONAL_VALUE_TOOLTIP :{BLACK}The valu STR_ORDER_CONDITIONAL_VALUE_CAPT :{WHITE}Enter value to compare against STR_ORDERS_SKIP_BUTTON :{BLACK}Skip -STR_ORDERS_SKIP_TOOLTIP :{BLACK}Skip the current order, and start the next. Ctrl+Click skips to the selected order +STR_ORDERS_SKIP_TOOLTIP :{BLACK}Skip the current order, and start the next. Ctrl+Click to skip to the selected order STR_ORDERS_DELETE_BUTTON :{BLACK}Delete STR_ORDERS_DELETE_TOOLTIP :{BLACK}Delete the highlighted order STR_ORDERS_DELETE_ALL_TOOLTIP :{BLACK}Delete all orders STR_ORDERS_STOP_SHARING_BUTTON :{BLACK}Stop sharing -STR_ORDERS_STOP_SHARING_TOOLTIP :{BLACK}Stop sharing the order list. Ctrl+Click additionally deletes all orders for this vehicle +STR_ORDERS_STOP_SHARING_TOOLTIP :{BLACK}Stop sharing the order list. Ctrl+Click to additionally delete all orders for this vehicle STR_ORDERS_GO_TO_BUTTON :{BLACK}Go To STR_ORDER_GO_TO_NEAREST_DEPOT :Go to nearest depot STR_ORDER_GO_TO_NEAREST_HANGAR :Go to nearest hangar STR_ORDER_CONDITIONAL :Conditional order jump STR_ORDER_SHARE :Share orders -STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Insert a new order before the highlighted order, or add to end of list. Ctrl makes station orders 'full load any cargo', waypoint orders 'non-stop' and depot orders 'service'. 'Share orders' or Ctrl lets this vehicle share orders with the selected vehicle. Clicking a vehicle copies the orders from that vehicle. A depot order disables automatic servicing of the vehicle +STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Insert a new order before the highlighted order, or add to end of list. Ctrl+Click on a station for 'full load any cargo', on a waypoint for 'non-stop', or on a depot for 'service'. Click on another vehicle to copy its orders or Ctrl+Click to share orders. A depot order disables automatic servicing of the vehicle STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP :{BLACK}Show all vehicles that share this schedule @@ -4616,24 +4616,24 @@ STR_TIMETABLE_STATUS_START_AT_DATE :{BLACK}This tim STR_TIMETABLE_STATUS_START_IN_SECONDS :{BLACK}This timetable will start in {COMMA} seconds STR_TIMETABLE_START :{BLACK}Start Timetable -STR_TIMETABLE_START_TOOLTIP :{BLACK}Select when this timetable starts. Ctrl+Click evenly distributes the start of all vehicles sharing this order based on their relative order, if the order is completely timetabled +STR_TIMETABLE_START_TOOLTIP :{BLACK}Select when this timetable starts. Ctrl+Click to evenly distribute the start of all vehicles sharing this order based on their relative order, if the order is completely timetabled STR_TIMETABLE_START_SECONDS_QUERY :Seconds until timetable starts STR_TIMETABLE_CHANGE_TIME :{BLACK}Change Time -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Change the amount of time that the highlighted order should take. Ctrl+Click sets the time for all orders +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Change the amount of time that the highlighted order should take. Ctrl+Click to set the time for all orders STR_TIMETABLE_CLEAR_TIME :{BLACK}Clear Time -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Clear the amount of time for the highlighted order. Ctrl+Click clears the time for all orders +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Clear the amount of time for the highlighted order. Ctrl+Click to clear the time for all orders STR_TIMETABLE_CHANGE_SPEED :{BLACK}Change Speed Limit -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Change the maximum travel speed of the highlighted order. Ctrl+Click sets the speed for all orders +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Change the maximum travel speed of the highlighted order. Ctrl+Click to set the speed for all orders STR_TIMETABLE_CLEAR_SPEED :{BLACK}Clear Speed Limit -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Clear the maximum travel speed of the highlighted order. Ctrl+Click clears the speed for all orders +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Clear the maximum travel speed of the highlighted order. Ctrl+Click to clear the speed for all orders STR_TIMETABLE_RESET_LATENESS :{BLACK}Reset Late Counter -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Reset the lateness counter, so the vehicle will be on time. Ctrl+Click will reset the entire group so the latest vehicle will be on time and all others will be early +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Reset the lateness counter, so the vehicle will be on time. Ctrl+Click to reset the entire group so the latest vehicle will be on time and all others will be early STR_TIMETABLE_AUTOFILL :{BLACK}Autofill STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Fill the timetable automatically with the values from the next journey. Ctrl+Click to try to keep waiting times From 71b8801b61463209134a4d7b7e6ebcb7a3fc5623 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sat, 20 Jan 2024 21:43:06 +0100 Subject: [PATCH 09/27] Fix bd85f61a: [Linux] don't include sys/random.h on older glibc systems (#11844) --- src/core/random_func.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/random_func.cpp b/src/core/random_func.cpp index 0a18360953..dfbd2311fe 100644 --- a/src/core/random_func.cpp +++ b/src/core/random_func.cpp @@ -24,10 +24,12 @@ #if defined(_WIN32) # include # include +#elif defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__) +// No includes required. +#elif defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 25))) +# include #elif defined(__EMSCRIPTEN__) # include -#elif !defined(__APPLE__) && !defined(__NetBSD__) && !defined(__FreeBSD__) -# include #endif #include "../safeguards.h" From 2d77f09a81a1f2df43e0643a3dc8f6b91941bd84 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Sat, 20 Jan 2024 21:04:49 +0100 Subject: [PATCH 10/27] Codechange: use std::shared_ptr for vector of TCPConnecters --- src/network/core/tcp.h | 14 ++++++++++++++ src/network/core/tcp_connect.cpp | 27 ++++++--------------------- src/network/network.cpp | 8 ++++---- src/network/network_content.cpp | 4 ++-- src/network/network_coordinator.cpp | 8 ++++---- src/network/network_coordinator.h | 2 +- src/network/network_stun.cpp | 2 +- src/network/network_stun.h | 2 +- src/network/network_turn.cpp | 2 +- src/network/network_turn.h | 2 +- 10 files changed, 35 insertions(+), 36 deletions(-) diff --git a/src/network/core/tcp.h b/src/network/core/tcp.h index da79e1fa80..caade125b0 100644 --- a/src/network/core/tcp.h +++ b/src/network/core/tcp.h @@ -100,6 +100,8 @@ private: NetworkAddress bind_address; ///< Address we're binding to, if any. int family = AF_UNSPEC; ///< Family we are using to connect with. + static std::vector> connecters; ///< List of connections that are currently being created. + void Resolve(); void OnResolved(addrinfo *ai); bool TryNextAddress(); @@ -132,6 +134,18 @@ public: static void CheckCallbacks(); static void KillAll(); + + /** + * Create the connecter, and initiate connecting by putting it in the collection of TCP connections to make. + * @tparam T The type of connecter to create. + * @param args The arguments to the constructor of T. + * @return Shared pointer to the connecter. + */ + template + static std::shared_ptr Create(Args&& ... args) + { + return TCPConnecter::connecters.emplace_back(std::make_shared(std::forward(args)...)); + } }; class TCPServerConnecter : public TCPConnecter { diff --git a/src/network/core/tcp_connect.cpp b/src/network/core/tcp_connect.cpp index ed424249cc..f0cf8c3b4f 100644 --- a/src/network/core/tcp_connect.cpp +++ b/src/network/core/tcp_connect.cpp @@ -18,8 +18,7 @@ #include "../../safeguards.h" -/** List of connections that are currently being created */ -static std::vector _tcp_connecters; +/* static */ std::vector> TCPConnecter::connecters; /** * Create a new connecter for the given address. @@ -32,8 +31,6 @@ TCPConnecter::TCPConnecter(const std::string &connection_string, uint16_t defaul family(family) { this->connection_string = NormalizeConnectionString(connection_string, default_port); - - _tcp_connecters.push_back(this); } /** @@ -57,8 +54,6 @@ TCPServerConnecter::TCPServerConnecter(const std::string &connection_string, uin default: NOT_REACHED(); } - - _tcp_connecters.push_back(this); } TCPConnecter::~TCPConnecter() @@ -467,24 +462,14 @@ void TCPServerConnecter::SetFailure() */ /* static */ void TCPConnecter::CheckCallbacks() { - for (auto iter = _tcp_connecters.begin(); iter < _tcp_connecters.end(); /* nothing */) { - TCPConnecter *cur = *iter; - - if (cur->CheckActivity()) { - iter = _tcp_connecters.erase(iter); - delete cur; - } else { - iter++; - } - } + TCPConnecter::connecters.erase( + std::remove_if(TCPConnecter::connecters.begin(), TCPConnecter::connecters.end(), + [](auto &connecter) { return connecter->CheckActivity(); }), + TCPConnecter::connecters.end()); } /** Kill all connection attempts. */ /* static */ void TCPConnecter::KillAll() { - for (auto iter = _tcp_connecters.begin(); iter < _tcp_connecters.end(); /* nothing */) { - TCPConnecter *cur = *iter; - iter = _tcp_connecters.erase(iter); - delete cur; - } + TCPConnecter::connecters.clear(); } diff --git a/src/network/network.cpp b/src/network/network.cpp index 66fc844e64..9fa5562333 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -624,7 +624,7 @@ static void NetworkInitialize(bool close_admins = true) } /** Non blocking connection to query servers for their game info. */ -class TCPQueryConnecter : TCPServerConnecter { +class TCPQueryConnecter : public TCPServerConnecter { private: std::string connection_string; @@ -658,7 +658,7 @@ void NetworkQueryServer(const std::string &connection_string) NetworkGameList *item = NetworkGameListAddItem(connection_string); item->refreshing = true; - new TCPQueryConnecter(connection_string); + TCPConnecter::Create(connection_string); } /** @@ -721,7 +721,7 @@ void NetworkRebuildHostList() } /** Non blocking connection create to actually connect to servers */ -class TCPClientConnecter : TCPServerConnecter { +class TCPClientConnecter : public TCPServerConnecter { private: std::string connection_string; @@ -800,7 +800,7 @@ void NetworkClientJoinGame() _network_join_status = NETWORK_JOIN_STATUS_CONNECTING; ShowJoinStatusWindow(); - new TCPClientConnecter(_network_join.connection_string); + TCPConnecter::Create(_network_join.connection_string); } static void NetworkInitGameInfo() diff --git a/src/network/network_content.cpp b/src/network/network_content.cpp index a9305f0d2f..e4a8ea8675 100644 --- a/src/network/network_content.cpp +++ b/src/network/network_content.cpp @@ -756,7 +756,7 @@ ClientNetworkContentSocketHandler::~ClientNetworkContentSocketHandler() } /** Connect to the content server. */ -class NetworkContentConnecter : TCPConnecter { +class NetworkContentConnecter : public TCPConnecter { public: /** * Initiate the connecting. @@ -791,7 +791,7 @@ void ClientNetworkContentSocketHandler::Connect() this->isCancelled = false; this->isConnecting = true; - new NetworkContentConnecter(NetworkContentServerConnectionString()); + TCPConnecter::Create(NetworkContentServerConnectionString()); } /** diff --git a/src/network/network_coordinator.cpp b/src/network/network_coordinator.cpp index 4298b382ef..b049376cc9 100644 --- a/src/network/network_coordinator.cpp +++ b/src/network/network_coordinator.cpp @@ -100,7 +100,7 @@ public: }; /** Connect to the Game Coordinator server. */ -class NetworkCoordinatorConnecter : TCPConnecter { +class NetworkCoordinatorConnecter : public TCPConnecter { public: /** * Initiate the connecting. @@ -306,7 +306,7 @@ bool ClientNetworkCoordinatorSocketHandler::Receive_GC_DIRECT_CONNECT(Packet *p) this->game_connecter = nullptr; } - this->game_connecter = new NetworkDirectConnecter(hostname, port, token, tracking_number); + this->game_connecter = TCPConnecter::Create(hostname, port, token, tracking_number); return true; } @@ -349,7 +349,7 @@ bool ClientNetworkCoordinatorSocketHandler::Receive_GC_STUN_CONNECT(Packet *p) * STUN server. This means that if there is any NAT in the local network, * the public ip:port is still pointing to the local address, and as such * a connection can be established. */ - this->game_connecter = new NetworkReuseStunConnecter(host, port, family_it->second->local_addr, token, tracking_number, family); + this->game_connecter = TCPConnecter::Create(host, port, family_it->second->local_addr, token, tracking_number, family); return true; } @@ -426,7 +426,7 @@ void ClientNetworkCoordinatorSocketHandler::Connect() this->connecting = true; this->last_activity = std::chrono::steady_clock::now(); - new NetworkCoordinatorConnecter(NetworkCoordinatorConnectionString()); + TCPConnecter::Create(NetworkCoordinatorConnectionString()); } NetworkRecvStatus ClientNetworkCoordinatorSocketHandler::CloseConnection(bool error) diff --git a/src/network/network_coordinator.h b/src/network/network_coordinator.h index 71fc599457..ccb74e4921 100644 --- a/src/network/network_coordinator.h +++ b/src/network/network_coordinator.h @@ -57,7 +57,7 @@ private: std::map connecter_pre; ///< Based on invite codes, the current connecters that are pending. std::map>> stun_handlers; ///< All pending STUN handlers, stored by token:family. std::map> turn_handlers; ///< Pending TURN handler (if any), stored by token. - TCPConnecter *game_connecter = nullptr; ///< Pending connecter to the game server. + std::shared_ptr game_connecter{}; ///< Pending connecter to the game server. uint32_t newgrf_lookup_table_cursor = 0; ///< Last received cursor for the #GameInfoNewGRFLookupTable updates. GameInfoNewGRFLookupTable newgrf_lookup_table; ///< Table to look up NewGRFs in the GC_LISTING packets. diff --git a/src/network/network_stun.cpp b/src/network/network_stun.cpp index d49c8ebbf8..dd0624fb65 100644 --- a/src/network/network_stun.cpp +++ b/src/network/network_stun.cpp @@ -71,7 +71,7 @@ void ClientNetworkStunSocketHandler::Connect(const std::string &token, uint8_t f this->token = token; this->family = family; - this->connecter = new NetworkStunConnecter(this, NetworkStunConnectionString(), token, family); + this->connecter = TCPConnecter::Create(this, NetworkStunConnectionString(), token, family); } /** diff --git a/src/network/network_stun.h b/src/network/network_stun.h index 0ad69d4abe..3e0b9d6ef4 100644 --- a/src/network/network_stun.h +++ b/src/network/network_stun.h @@ -20,7 +20,7 @@ private: bool sent_result = false; ///< Did we sent the result of the STUN connection? public: - TCPConnecter *connecter = nullptr; ///< Connecter instance. + std::shared_ptr connecter{}; ///< Connecter instance. NetworkAddress local_addr; ///< Local addresses of the socket. NetworkRecvStatus CloseConnection(bool error = true) override; diff --git a/src/network/network_turn.cpp b/src/network/network_turn.cpp index e6f48d535a..db018f6f7a 100644 --- a/src/network/network_turn.cpp +++ b/src/network/network_turn.cpp @@ -73,7 +73,7 @@ bool ClientNetworkTurnSocketHandler::Receive_TURN_CONNECTED(Packet *p) void ClientNetworkTurnSocketHandler::Connect() { this->connect_started = true; - this->connecter = new NetworkTurnConnecter(this, this->connection_string); + this->connecter = TCPConnecter::Create(this, this->connection_string); } /** diff --git a/src/network/network_turn.h b/src/network/network_turn.h index 9ff8980157..0b0ca8a851 100644 --- a/src/network/network_turn.h +++ b/src/network/network_turn.h @@ -24,7 +24,7 @@ protected: bool Receive_TURN_CONNECTED(Packet *p) override; public: - TCPConnecter *connecter = nullptr; ///< Connecter instance. + std::shared_ptr connecter{}; ///< Connecter instance. bool connect_started = false; ///< Whether we started the connection. ClientNetworkTurnSocketHandler(const std::string &token, uint8_t tracking_number, const std::string &connection_string) : token(token), tracking_number(tracking_number), connection_string(connection_string) {} From 526a0db9567f55f1474a1e1a11e2cd7e69dc15f9 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sat, 20 Jan 2024 23:05:56 +0100 Subject: [PATCH 11/27] Fix: [CI] don't share Rust cache between legacy and generic linux (#11848) The resulting binaries of generic can't run on legacy. --- .github/workflows/release-linux-legacy.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release-linux-legacy.yml b/.github/workflows/release-linux-legacy.yml index 8cf8d840f3..a9c1a23b32 100644 --- a/.github/workflows/release-linux-legacy.yml +++ b/.github/workflows/release-linux-legacy.yml @@ -52,6 +52,8 @@ jobs: - name: Enable Rust cache uses: Swatinem/rust-cache@v2.7.0 + with: + key: legacy - name: Setup vcpkg caching uses: actions/github-script@v6 From 66a16d5ddf6734db7c1985ad95d0245f01982871 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sun, 21 Jan 2024 00:51:50 +0100 Subject: [PATCH 12/27] Fix: [CI] wait for all targets to succeeded before uploading to any (#11845) Otherwise it is possible Steam upload happens while CDN upload does not, which is a bit awkward. --- .github/workflows/release.yml | 43 +++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2617d9f2b7..0c4fd78932 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -86,8 +86,8 @@ jobs: with: version: ${{ needs.source.outputs.version }} - upload-cdn: - name: Upload (CDN) + upload: + name: Upload needs: - source - docs @@ -101,6 +101,25 @@ jobs: # The always() makes sure the rest is always evaluated. if: always() && needs.source.result == 'success' && needs.docs.result == 'success' && needs.linux-legacy.result == 'success' && needs.linux.result == 'success' && needs.macos.result == 'success' && needs.windows.result == 'success' && (needs.windows-store.result == 'success' || needs.windows-store.result == 'skipped') + runs-on: ubuntu-latest + + # This job is empty, but ensures no upload job starts before all targets finished and are successful. + steps: + - name: Build completed + run: | + true + + upload-cdn: + name: Upload (CDN) + needs: + - source + - upload + + # As windows-store is condition, we need to check ourselves if we need to run. + # The always() makes sure the rest is always evaluated. + # Yes, you even need to do this if you yourself don't depend on the condition. + if: always() && needs.source.result == 'success' && needs.upload.result == 'success' + uses: ./.github/workflows/upload-cdn.yml secrets: inherit @@ -113,11 +132,13 @@ jobs: name: Upload (Steam) needs: - source - - linux - - macos - - windows + - upload - if: needs.source.outputs.trigger_type == 'new-master' || needs.source.outputs.trigger_type == 'new-tag' + # As windows-store is condition, we need to check ourselves if we need to run. + # The always() makes sure the rest is always evaluated. + # Yes, you even need to do this if you yourself don't depend on the condition. + # Additionally, only nightlies and releases go to Steam; not PRs. + if: always() && needs.source.result == 'success' && needs.upload.result == 'success' && (needs.source.outputs.trigger_type == 'new-master' || needs.source.outputs.trigger_type == 'new-tag') uses: ./.github/workflows/upload-steam.yml secrets: inherit @@ -130,11 +151,13 @@ jobs: name: Upload (GOG) needs: - source - - linux - - macos - - windows + - upload - if: needs.source.outputs.trigger_type == 'new-tag' + # As windows-store is condition, we need to check ourselves if we need to run. + # The always() makes sure the rest is always evaluated. + # Yes, you even need to do this if you yourself don't depend on the condition. + # Additionally, only releases go to GOG; not nightlies or PRs. + if: always() && needs.source.result == 'success' && needs.upload.result == 'success' && needs.source.outputs.trigger_type == 'new-tag' uses: ./.github/workflows/upload-gog.yml secrets: inherit From 0841978304df05e72539558c5c674db5396a5466 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 21 Jan 2024 09:21:22 +0000 Subject: [PATCH 13/27] Codechange: Use vector and iterators to store old/new vehicles during autoreplace. (#11851) This avoids malloc/free of 3 arrays along index counting, and the data for each part is kept together. --- src/autoreplace_cmd.cpp | 91 +++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index c67f3b4092..5d6b6eeaaf 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -490,6 +490,21 @@ static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, b return cost; } +/** Struct for recording vehicle chain replacement information. */ +struct ReplaceChainItem { + Vehicle *old_veh; ///< Old vehicle to replace. + Vehicle *new_veh; ///< Replacement vehicle, or nullptr if no replacement. + Money cost; /// Cost of buying and refitting replacement. + + ReplaceChainItem(Vehicle *old_veh, Vehicle *new_veh, Money cost) : old_veh(old_veh), new_veh(new_veh), cost(cost) { } + + /** + * Get vehicle to use for this position. + * @return Either the new vehicle, or the old vehicle if there is no replacement. + */ + Vehicle *GetVehicle() const { return new_veh == nullptr ? old_veh : new_veh; } +}; + /** * Replace a whole vehicle chain * @param chain vehicle chain to let autoreplace/renew operator on @@ -509,29 +524,21 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon /* Store the length of the old vehicle chain, rounded up to whole tiles */ uint16_t old_total_length = CeilDiv(Train::From(old_head)->gcache.cached_total_length, TILE_SIZE) * TILE_SIZE; - int num_units = 0; ///< Number of units in the chain - for (Train *w = Train::From(old_head); w != nullptr; w = w->GetNextUnit()) num_units++; - - Train **old_vehs = CallocT(num_units); ///< Will store vehicles of the old chain in their order - Train **new_vehs = CallocT(num_units); ///< New vehicles corresponding to old_vehs or nullptr if no replacement - Money *new_costs = MallocT(num_units); ///< Costs for buying and refitting the new vehicles + std::vector replacements; /* Collect vehicles and build replacements * Note: The replacement vehicles can only successfully build as long as the old vehicles are still in their chain */ - int i; - Train *w; - for (w = Train::From(old_head), i = 0; w != nullptr; w = w->GetNextUnit(), i++) { - assert(i < num_units); - old_vehs[i] = w; + for (Train *w = Train::From(old_head); w != nullptr; w = w->GetNextUnit()) { + ReplaceChainItem &replacement = replacements.emplace_back(w, nullptr, 0); - CommandCost ret = BuildReplacementVehicle(old_vehs[i], (Vehicle**)&new_vehs[i], true); + CommandCost ret = BuildReplacementVehicle(replacement.old_veh, &replacement.new_veh, true); cost.AddCost(ret); if (cost.Failed()) break; - new_costs[i] = ret.GetCost(); - if (new_vehs[i] != nullptr) *nothing_to_do = false; + replacement.cost = ret.GetCost(); + if (replacement.new_veh != nullptr) *nothing_to_do = false; } - Train *new_head = (new_vehs[0] != nullptr ? new_vehs[0] : old_vehs[0]); + Vehicle *new_head = replacements.front().GetVehicle(); /* Note: When autoreplace has already failed here, old_vehs[] is not completely initialized. But it is also not needed. */ if (cost.Succeeded()) { @@ -545,18 +552,18 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon * We do this from back to front, so that the head of the temporary vehicle chain does not change all the time. * That way we also have less trouble when exceeding the unitnumber limit. * OTOH the vehicle attach callback is more expensive this way :s */ - Train *last_engine = nullptr; ///< Shall store the last engine unit after this step + Vehicle *last_engine = nullptr; ///< Shall store the last engine unit after this step if (cost.Succeeded()) { - for (int i = num_units - 1; i > 0; i--) { - Train *append = (new_vehs[i] != nullptr ? new_vehs[i] : old_vehs[i]); + for (auto it = std::rbegin(replacements); it != std::rend(replacements); ++it) { + Vehicle *append = it->GetVehicle(); if (RailVehInfo(append->engine_type)->railveh_type == RAILVEH_WAGON) continue; - if (new_vehs[i] != nullptr) { + if (it->new_veh != nullptr) { /* Move the old engine to a separate row with DC_AUTOREPLACE. Else * moving the wagon in front may fail later due to unitnumber limit. * (We have to attach wagons without DC_AUTOREPLACE.) */ - CmdMoveVehicle(old_vehs[i], nullptr, DC_EXEC | DC_AUTOREPLACE, false); + CmdMoveVehicle(it->old_veh, nullptr, DC_EXEC | DC_AUTOREPLACE, false); } if (last_engine == nullptr) last_engine = append; @@ -567,15 +574,15 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon } /* When wagon removal is enabled and the new engines without any wagons are already longer than the old, we have to fail */ - if (cost.Succeeded() && wagon_removal && new_head->gcache.cached_total_length > old_total_length) cost = CommandCost(STR_ERROR_TRAIN_TOO_LONG_AFTER_REPLACEMENT); + if (cost.Succeeded() && wagon_removal && Train::From(new_head)->gcache.cached_total_length > old_total_length) cost = CommandCost(STR_ERROR_TRAIN_TOO_LONG_AFTER_REPLACEMENT); /* Append/insert wagons into the new vehicle chain * We do this from back to front, so we can stop when wagon removal or maximum train length (i.e. from mammoth-train setting) is triggered. */ if (cost.Succeeded()) { - for (int i = num_units - 1; i > 0; i--) { + for (auto it = std::rbegin(replacements); it != std::rend(replacements); ++it) { assert(last_engine != nullptr); - Vehicle *append = (new_vehs[i] != nullptr ? new_vehs[i] : old_vehs[i]); + Vehicle *append = it->GetVehicle(); if (RailVehInfo(append->engine_type)->railveh_type == RAILVEH_WAGON) { /* Insert wagon after 'last_engine' */ @@ -584,7 +591,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon /* When we allow removal of wagons, either the move failing due * to the train becoming too long, or the train becoming longer * would move the vehicle to the empty vehicle chain. */ - if (wagon_removal && (res.Failed() ? res.GetErrorMessage() == STR_ERROR_TRAIN_TOO_LONG : new_head->gcache.cached_total_length > old_total_length)) { + if (wagon_removal && (res.Failed() ? res.GetErrorMessage() == STR_ERROR_TRAIN_TOO_LONG : Train::From(new_head)->gcache.cached_total_length > old_total_length)) { CmdMoveVehicle(append, nullptr, DC_EXEC | DC_AUTOREPLACE, false); break; } @@ -594,16 +601,16 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon } else { /* We have reached 'last_engine', continue with the next engine towards the front */ assert(append == last_engine); - last_engine = last_engine->GetPrevUnit(); + last_engine = Train::From(last_engine)->GetPrevUnit(); } } } /* Sell superfluous new vehicles that could not be inserted. */ if (cost.Succeeded() && wagon_removal) { - assert(new_head->gcache.cached_total_length <= _settings_game.vehicle.max_train_length * TILE_SIZE); - for (int i = 1; i < num_units; i++) { - Vehicle *wagon = new_vehs[i]; + assert(Train::From(new_head)->gcache.cached_total_length <= _settings_game.vehicle.max_train_length * TILE_SIZE); + for (auto it = std::next(std::begin(replacements)); it != std::end(replacements); ++it) { + Vehicle *wagon = it->new_veh; if (wagon == nullptr) continue; if (wagon->First() == new_head) break; @@ -612,11 +619,11 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon /* Sell wagon */ [[maybe_unused]] CommandCost ret = Command::Do(DC_EXEC, wagon->index, false, false, INVALID_CLIENT_ID); assert(ret.Succeeded()); - new_vehs[i] = nullptr; + it->new_veh = nullptr; /* Revert the money subtraction when the vehicle was built. * This value is different from the sell value, esp. because of refitting */ - cost.AddCost(-new_costs[i]); + cost.AddCost(-it->cost); } } @@ -631,8 +638,8 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon } /* Transfer cargo of old vehicles and sell them */ - for (int i = 0; i < num_units; i++) { - Vehicle *w = old_vehs[i]; + for (auto it = std::begin(replacements); it != std::end(replacements); ++it) { + Vehicle *w = it->old_veh; /* Is the vehicle again part of the new chain? * Note: We cannot test 'new_vehs[i] != nullptr' as wagon removal might cause to remove both */ if (w->First() == new_head) continue; @@ -644,8 +651,8 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon * it from failing due to engine limits. */ cost.AddCost(Command::Do(flags | DC_AUTOREPLACE, w->index, false, false, INVALID_CLIENT_ID)); if ((flags & DC_EXEC) != 0) { - old_vehs[i] = nullptr; - if (i == 0) old_head = nullptr; + it->old_veh = nullptr; + if (it == std::begin(replacements)) old_head = nullptr; } } @@ -662,8 +669,8 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon assert(Train::From(old_head)->GetNextUnit() == nullptr); - for (int i = num_units - 1; i > 0; i--) { - [[maybe_unused]] CommandCost ret = CmdMoveVehicle(old_vehs[i], old_head, DC_EXEC | DC_AUTOREPLACE, false); + for (auto it = std::rbegin(replacements); it != std::rend(replacements); ++it) { + [[maybe_unused]] CommandCost ret = CmdMoveVehicle(it->old_veh, old_head, DC_EXEC | DC_AUTOREPLACE, false); assert(ret.Succeeded()); } } @@ -671,17 +678,13 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon /* Finally undo buying of new vehicles */ if ((flags & DC_EXEC) == 0) { - for (int i = num_units - 1; i >= 0; i--) { - if (new_vehs[i] != nullptr) { - Command::Do(DC_EXEC, new_vehs[i]->index, false, false, INVALID_CLIENT_ID); - new_vehs[i] = nullptr; + for (auto it = std::rbegin(replacements); it != std::rend(replacements); ++it) { + if (it->new_veh != nullptr) { + Command::Do(DC_EXEC, it->new_veh->index, false, false, INVALID_CLIENT_ID); + it->new_veh = nullptr; } } } - - free(old_vehs); - free(new_vehs); - free(new_costs); } else { /* Build and refit replacement vehicle */ Vehicle *new_head = nullptr; From c0ab436077d2e2f425d8b3969de392a640256b88 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 21 Jan 2024 13:23:04 +0000 Subject: [PATCH 14/27] Codechange: Store Colours in Colours type. (#11625) This reduces casts, some magic numbers, and introduces a bit of type-safety. --- src/company_base.h | 4 ++-- src/company_cmd.cpp | 8 ++++---- src/company_gui.cpp | 18 ++++++++++++------ src/company_manager_face.h | 2 +- src/group_cmd.cpp | 4 ++-- src/house.h | 2 +- src/industry.h | 2 +- src/industry_cmd.cpp | 4 ++-- src/linkgraph/linkgraph_gui.cpp | 2 +- src/livery.h | 5 +++-- src/main_gui.cpp | 2 +- src/newgrf.cpp | 11 ++++++----- src/newgrf_house.cpp | 2 +- src/news_type.h | 3 ++- src/openttd.cpp | 4 ++-- src/saveload/afterload.cpp | 2 +- src/saveload/company_sl.cpp | 2 +- src/saveload/oldloader_sl.cpp | 6 +++--- src/settings_type.h | 4 ++-- src/story.cpp | 2 +- src/table/town_land.h | 2 +- 21 files changed, 50 insertions(+), 41 deletions(-) diff --git a/src/company_base.h b/src/company_base.h index eea9974089..bcdbeef11a 100644 --- a/src/company_base.h +++ b/src/company_base.h @@ -67,7 +67,7 @@ struct CompanyProperties { byte money_fraction; ///< Fraction of money of the company, too small to represent in #money. Money current_loan; ///< Amount of money borrowed from the bank. - byte colour; ///< Company colour. + Colours colour; ///< Company colour. byte block_preview; ///< Number of quarters that the company is not allowed to get new exclusive engine previews (see CompaniesGenStatistics). @@ -105,7 +105,7 @@ struct CompanyProperties { // TODO: Change some of these member variables to use relevant INVALID_xxx constants CompanyProperties() : name_2(0), name_1(0), president_name_1(0), president_name_2(0), - face(0), money(0), money_fraction(0), current_loan(0), colour(0), block_preview(0), + face(0), money(0), money_fraction(0), current_loan(0), colour(COLOUR_BEGIN), block_preview(0), location_of_HQ(0), last_build_coordinate(0), inaugurated_year(0), months_of_bankruptcy(0), bankrupt_asked(0), bankrupt_timeout(0), bankrupt_value(0), terraform_limit(0), clear_limit(0), tree_limit(0), build_object_limit(0), is_ai(false), engine_renew_list(nullptr) {} diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 7d14fafbd1..d6166d4571 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -457,7 +457,7 @@ static Colours GenerateCompanyColour() /* Move the colours that look similar to each company's colour to the side */ for (const Company *c : Company::Iterate()) { - Colours pcolour = (Colours)c->colour; + Colours pcolour = c->colour; for (uint i = 0; i < COLOUR_END; i++) { if (colours[i] == pcolour) { @@ -559,7 +559,7 @@ Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY) c->colour = colour; ResetCompanyLivery(c); - _company_colours[c->index] = (Colours)c->colour; + _company_colours[c->index] = c->colour; /* Scale the initial loan based on the inflation rounded down to the loan interval. The maximum loan has already been inflation adjusted. */ c->money = c->current_loan = std::min((INITIAL_LOAN * _economy.inflation_prices >> 16) / LOAN_INTERVAL * LOAN_INTERVAL, _economy.max_loan); @@ -991,7 +991,7 @@ CommandCost CmdSetCompanyColour(DoCommandFlag flags, LiveryScheme scheme, bool p if (flags & DC_EXEC) { if (primary) { if (scheme != LS_DEFAULT) SB(c->livery[scheme].in_use, 0, 1, colour != INVALID_COLOUR); - if (colour == INVALID_COLOUR) colour = (Colours)c->livery[LS_DEFAULT].colour1; + if (colour == INVALID_COLOUR) colour = c->livery[LS_DEFAULT].colour1; c->livery[scheme].colour1 = colour; /* If setting the first colour of the default scheme, adjust the @@ -1004,7 +1004,7 @@ CommandCost CmdSetCompanyColour(DoCommandFlag flags, LiveryScheme scheme, bool p } } else { if (scheme != LS_DEFAULT) SB(c->livery[scheme].in_use, 1, 1, colour != INVALID_COLOUR); - if (colour == INVALID_COLOUR) colour = (Colours)c->livery[LS_DEFAULT].colour2; + if (colour == INVALID_COLOUR) colour = c->livery[LS_DEFAULT].colour2; c->livery[scheme].colour2 = colour; if (scheme == LS_DEFAULT) { diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 272dbda3b5..0e4ac392a4 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -582,7 +582,7 @@ static const LiveryClass _livery_class[LS_END] = { template class DropDownListColourItem : public DropDownIcon> { public: - DropDownListColourItem(int colour, bool masked) : DropDownIcon>(TSprite, PALETTE_RECOLOUR_START + (colour % COLOUR_END), colour < COLOUR_END ? _colour_dropdown[colour] : STR_COLOUR_DEFAULT, colour, masked) + DropDownListColourItem(int colour, bool masked) : DropDownIcon>(TSprite, GENERAL_SPRITE_COLOUR(colour % COLOUR_END), colour < COLOUR_END ? _colour_dropdown[colour] : STR_COLOUR_DEFAULT, colour, masked) { } }; @@ -647,7 +647,12 @@ private: list.push_back(std::make_unique>(i, HasBit(used_colours, i))); } - byte sel = (default_livery == nullptr || HasBit(livery->in_use, primary ? 0 : 1)) ? (primary ? livery->colour1 : livery->colour2) : default_col; + byte sel; + if (default_livery == nullptr || HasBit(livery->in_use, primary ? 0 : 1)) { + sel = primary ? livery->colour1 : livery->colour2; + } else { + sel = default_col; + } ShowDropDownList(this, std::move(list), sel, widget); } @@ -1034,19 +1039,20 @@ public: bool local = (CompanyID)this->window_number == _local_company; if (!local) return; - if (index >= COLOUR_END) index = INVALID_COLOUR; + Colours colour = static_cast(index); + if (colour >= COLOUR_END) colour = INVALID_COLOUR; if (this->livery_class < LC_GROUP_RAIL) { /* Set company colour livery */ for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) { /* Changed colour for the selected scheme, or all visible schemes if CTRL is pressed. */ if (HasBit(this->sel, scheme) || (_ctrl_pressed && _livery_class[scheme] == this->livery_class && HasBit(_loaded_newgrf_features.used_liveries, scheme))) { - Command::Post(scheme, widget == WID_SCL_PRI_COL_DROPDOWN, (Colours)index); + Command::Post(scheme, widget == WID_SCL_PRI_COL_DROPDOWN, colour); } } } else { /* Setting group livery */ - Command::Post(this->sel, widget == WID_SCL_PRI_COL_DROPDOWN, (Colours)index); + Command::Post(this->sel, widget == WID_SCL_PRI_COL_DROPDOWN, colour); } } @@ -1149,7 +1155,7 @@ void ShowCompanyLiveryWindow(CompanyID company, GroupID group) * @param colour the (background) colour of the gradient * @param r position to draw the face */ -void DrawCompanyManagerFace(CompanyManagerFace cmf, int colour, const Rect &r) +void DrawCompanyManagerFace(CompanyManagerFace cmf, Colours colour, const Rect &r) { GenderEthnicity ge = (GenderEthnicity)GetCompanyManagerFaceBits(cmf, CMFV_GEN_ETHN, GE_WM); diff --git a/src/company_manager_face.h b/src/company_manager_face.h index 0d8cc68da6..113a4c728b 100644 --- a/src/company_manager_face.h +++ b/src/company_manager_face.h @@ -236,6 +236,6 @@ inline SpriteID GetCompanyManagerFaceSprite(CompanyManagerFace cmf, CompanyManag return _cmf_info[cmfv].first_sprite[ge] + GB(cmf, _cmf_info[cmfv].offset, _cmf_info[cmfv].length); } -void DrawCompanyManagerFace(CompanyManagerFace face, int colour, const Rect &r); +void DrawCompanyManagerFace(CompanyManagerFace face, Colours colour, const Rect &r); #endif /* COMPANY_MANAGER_FACE_H */ diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp index a96d65585c..b0091ab303 100644 --- a/src/group_cmd.cpp +++ b/src/group_cmd.cpp @@ -672,11 +672,11 @@ CommandCost CmdSetGroupLivery(DoCommandFlag flags, GroupID group_id, bool primar if (flags & DC_EXEC) { if (primary) { SB(g->livery.in_use, 0, 1, colour != INVALID_COLOUR); - if (colour == INVALID_COLOUR) colour = (Colours)GetParentLivery(g)->colour1; + if (colour == INVALID_COLOUR) colour = GetParentLivery(g)->colour1; g->livery.colour1 = colour; } else { SB(g->livery.in_use, 1, 1, colour != INVALID_COLOUR); - if (colour == INVALID_COLOUR) colour = (Colours)GetParentLivery(g)->colour2; + if (colour == INVALID_COLOUR) colour = GetParentLivery(g)->colour2; g->livery.colour2 = colour; } diff --git a/src/house.h b/src/house.h index 2724506686..4831e289ac 100644 --- a/src/house.h +++ b/src/house.h @@ -113,7 +113,7 @@ struct HouseSpec { /* NewHouses properties */ GRFFileProps grf_prop; ///< Properties related the the grf file uint16_t callback_mask; ///< Bitmask of house callbacks that have to be called - byte random_colour[4]; ///< 4 "random" colours + Colours random_colour[4]; ///< 4 "random" colours byte probability; ///< Relative probability of appearing (16 is the standard value) HouseExtraFlags extra_flags; ///< some more flags HouseClassID class_id; ///< defines the class this house has (not grf file based) diff --git a/src/industry.h b/src/industry.h index bc6f79bb23..0d1bbe29b1 100644 --- a/src/industry.h +++ b/src/industry.h @@ -102,7 +102,7 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> { IndustryType type; ///< type of industry. Owner owner; ///< owner of the industry. Which SHOULD always be (imho) OWNER_NONE - byte random_colour; ///< randomized colour of the industry, for display purpose + Colours random_colour; ///< randomized colour of the industry, for display purpose TimerGameCalendar::Year last_prod_year; ///< last year of production byte was_cargo_delivered; ///< flag that indicate this has been the closest industry chosen for cargo delivery by a station. see DeliverGoodsToIndustry IndustryControlFlags ctlflags; ///< flags overriding standard behaviours diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 92861e29ec..68cfe9f312 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -1778,7 +1778,7 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, i->owner = OWNER_NONE; uint16_t r = Random(); - i->random_colour = GB(r, 0, 4); + i->random_colour = static_cast(GB(r, 0, 4)); i->counter = GB(r, 4, 12); i->random = initial_random_bits; i->was_cargo_delivered = false; @@ -1832,7 +1832,7 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, uint16_t res = GetIndustryCallback(CBID_INDUSTRY_DECIDE_COLOUR, 0, 0, i, type, INVALID_TILE); if (res != CALLBACK_FAILED) { if (GB(res, 4, 11) != 0) ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_DECIDE_COLOUR, res); - i->random_colour = GB(res, 0, 4); + i->random_colour = static_cast(GB(res, 0, 4)); } } diff --git a/src/linkgraph/linkgraph_gui.cpp b/src/linkgraph/linkgraph_gui.cpp index 883484c26a..6bb9dd60a9 100644 --- a/src/linkgraph/linkgraph_gui.cpp +++ b/src/linkgraph/linkgraph_gui.cpp @@ -332,7 +332,7 @@ void LinkGraphOverlay::DrawStationDots(const DrawPixelInfo *dpi) const LinkGraphOverlay::DrawVertex(pt.x, pt.y, r, _colour_gradient[st->owner != OWNER_NONE ? - (Colours)Company::Get(st->owner)->colour : COLOUR_GREY][5], + Company::Get(st->owner)->colour : COLOUR_GREY][5], _colour_gradient[COLOUR_GREY][1]); } } diff --git a/src/livery.h b/src/livery.h index cfb54aa182..302d40e404 100644 --- a/src/livery.h +++ b/src/livery.h @@ -11,6 +11,7 @@ #define LIVERY_H #include "company_type.h" +#include "gfx_type.h" static const byte LIT_NONE = 0; ///< Don't show the liveries at all static const byte LIT_COMPANY = 1; ///< Show the liveries of your own company @@ -76,8 +77,8 @@ DECLARE_ENUM_AS_ADDABLE(LiveryClass) /** Information about a particular livery. */ struct Livery { byte in_use; ///< Bit 0 set if this livery should override the default livery first colour, Bit 1 for the second colour. - byte colour1; ///< First colour, for all vehicles. - byte colour2; ///< Second colour, for vehicles with 2CC support. + Colours colour1; ///< First colour, for all vehicles. + Colours colour2; ///< Second colour, for vehicles with 2CC support. }; void ResetCompanyLivery(Company *c); diff --git a/src/main_gui.cpp b/src/main_gui.cpp index d6ffa71ba2..aaac9a11eb 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -541,7 +541,7 @@ void ShowSelectGameWindow(); void SetupColoursAndInitialWindow() { for (uint i = 0; i != 16; i++) { - const byte *b = GetNonSprite(PALETTE_RECOLOUR_START + i, SpriteType::Recolour); + const byte *b = GetNonSprite(GENERAL_SPRITE_COLOUR(i), SpriteType::Recolour); assert(b); memcpy(_colour_gradient[i], b + 0xC6, sizeof(_colour_gradient[i])); diff --git a/src/newgrf.cpp b/src/newgrf.cpp index e38027190a..621dd971f2 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -2405,10 +2405,11 @@ static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, Byt housespec->grf_prop.local_id = hid + i; housespec->grf_prop.subst_id = subs_id; housespec->grf_prop.grffile = _cur.grffile; - housespec->random_colour[0] = 0x04; // those 4 random colours are the base colour - housespec->random_colour[1] = 0x08; // for all new houses - housespec->random_colour[2] = 0x0C; // they stand for red, blue, orange and green - housespec->random_colour[3] = 0x06; + /* Set default colours for randomization, used if not overridden. */ + housespec->random_colour[0] = COLOUR_RED; + housespec->random_colour[1] = COLOUR_BLUE; + housespec->random_colour[2] = COLOUR_ORANGE; + housespec->random_colour[3] = COLOUR_GREEN; /* House flags 40 and 80 are exceptions; these flags are never set automatically. */ housespec->building_flags &= ~(BUILDING_IS_CHURCH | BUILDING_IS_STADIUM); @@ -2502,7 +2503,7 @@ static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, Byt break; case 0x17: // Four random colours to use - for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte(); + for (uint j = 0; j < 4; j++) housespec->random_colour[j] = static_cast(GB(buf->ReadByte(), 0, 4)); break; case 0x18: // Relative probability of appearing diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp index 63e7c44d69..6175920ca5 100644 --- a/src/newgrf_house.cpp +++ b/src/newgrf_house.cpp @@ -429,7 +429,7 @@ static void DrawTileLayout(const TileInfo *ti, const TileLayoutSpriteGroup *grou const DrawTileSprites *dts = group->ProcessRegisters(&stage); const HouseSpec *hs = HouseSpec::Get(house_id); - PaletteID palette = hs->random_colour[TileHash2Bit(ti->x, ti->y)] + PALETTE_RECOLOUR_START; + PaletteID palette = GENERAL_SPRITE_COLOUR(hs->random_colour[TileHash2Bit(ti->x, ti->y)]); if (HasBit(hs->callback_mask, CBM_HOUSE_COLOUR)) { uint16_t callback = GetHouseCallback(CBID_HOUSE_COLOUR, 0, 0, house_id, Town::GetByTile(ti->tile), ti->tile); if (callback != CALLBACK_FAILED) { diff --git a/src/news_type.h b/src/news_type.h index e2d32a5ae7..ca6343d6d6 100644 --- a/src/news_type.h +++ b/src/news_type.h @@ -11,6 +11,7 @@ #define NEWS_TYPE_H #include "core/enum_type.hpp" +#include "gfx_type.h" #include "timer/timer_game_calendar.h" #include "strings_type.h" #include "sound_type.h" @@ -161,7 +162,7 @@ struct CompanyNewsInformation : NewsAllocatedData { std::string other_company_name; ///< The name of the company taking over this one uint32_t face; ///< The face of the president - byte colour; ///< The colour related to the company + Colours colour; ///< The colour related to the company CompanyNewsInformation(const struct Company *c, const struct Company *other = nullptr); }; diff --git a/src/openttd.cpp b/src/openttd.cpp index 37729c82ca..542952b5ec 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -876,11 +876,11 @@ static void MakeNewGameDone() if (_settings_client.gui.starting_colour != COLOUR_END) { c->colour = _settings_client.gui.starting_colour; ResetCompanyLivery(c); - _company_colours[c->index] = (Colours)c->colour; + _company_colours[c->index] = c->colour; } if (_settings_client.gui.starting_colour_secondary != COLOUR_END && HasBit(_loaded_newgrf_features.used_liveries, LS_DEFAULT)) { - Command::Post(LS_DEFAULT, false, (Colours)_settings_client.gui.starting_colour_secondary); + Command::Post(LS_DEFAULT, false, _settings_client.gui.starting_colour_secondary); } OnStartGame(false); diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 22a0ca811b..33d12648b5 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -2463,7 +2463,7 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_148)) { for (Object *o : Object::Iterate()) { Owner owner = GetTileOwner(o->location.tile); - o->colour = (owner == OWNER_NONE) ? Random() & 0xF : Company::Get(owner)->livery->colour1; + o->colour = (owner == OWNER_NONE) ? static_cast(GB(Random(), 0, 4)) : Company::Get(owner)->livery->colour1; } } diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index 9f65198f9e..6ed8c5a8c4 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -516,7 +516,7 @@ struct PLYRChunkHandler : ChunkHandler { while ((index = SlIterateArray()) != -1) { Company *c = new (index) Company(); SlObject(c, slt); - _company_colours[index] = (Colours)c->colour; + _company_colours[index] = c->colour; } } diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index 06c0af9084..9ba3397412 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -455,10 +455,10 @@ static void FixTTOCompanies() } } -static inline byte RemapTTOColour(byte tto) +static inline Colours RemapTTOColour(Colours tto) { /** Lossy remapping of TTO colours to TTD colours. SVXConverter uses the same conversion. */ - static const byte tto_colour_remap[] = { + static const Colours tto_colour_remap[] = { COLOUR_DARK_BLUE, COLOUR_GREY, COLOUR_YELLOW, COLOUR_RED, COLOUR_PURPLE, COLOUR_DARK_GREEN, COLOUR_ORANGE, COLOUR_PALE_GREEN, COLOUR_BLUE, COLOUR_GREEN, COLOUR_CREAM, COLOUR_BROWN, @@ -1033,7 +1033,7 @@ static bool LoadOldCompany(LoadgameState *ls, int num) if (c->money == 893288) c->money = c->current_loan = 100000; } - _company_colours[num] = (Colours)c->colour; + _company_colours[num] = c->colour; c->inaugurated_year -= CalendarTime::ORIGINAL_BASE_YEAR; return true; diff --git a/src/settings_type.h b/src/settings_type.h index dcae83b814..b90eaacab3 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -186,8 +186,8 @@ struct GUISettings { byte missing_strings_threshold; ///< the number of missing strings before showing the warning uint8_t graph_line_thickness; ///< the thickness of the lines in the various graph guis uint8_t osk_activation; ///< Mouse gesture to trigger the OSK. - byte starting_colour; ///< default color scheme for the company to start a new game with - byte starting_colour_secondary; ///< default secondary color scheme for the company to start a new game with + Colours starting_colour; ///< default color scheme for the company to start a new game with + Colours starting_colour_secondary; ///< default secondary color scheme for the company to start a new game with bool show_newgrf_name; ///< Show the name of the NewGRF in the build vehicle window bool show_cargo_in_vehicle_lists; ///< Show the cargoes the vehicles can carry in the list windows bool auto_remove_signals; ///< automatically remove signals when in the way during rail construction diff --git a/src/story.cpp b/src/story.cpp index a03c2a12f7..ad732f9d37 100644 --- a/src/story.cpp +++ b/src/story.cpp @@ -143,7 +143,7 @@ void StoryPageButtonData::SetVehicleType(VehicleType vehtype) /** Get the button background colour. */ Colours StoryPageButtonData::GetColour() const { - Colours colour = (Colours)GB(this->referenced_id, 0, 8); + Colours colour = static_cast(GB(this->referenced_id, 0, 8)); if (!IsValidColours(colour)) return INVALID_COLOUR; return colour; } diff --git a/src/table/town_land.h b/src/table/town_land.h index 83b663add1..d2d991c328 100644 --- a/src/table/town_land.h +++ b/src/table/town_land.h @@ -1813,7 +1813,7 @@ static_assert(lengthof(_town_draw_tile_data) == (NEW_HOUSE_OFFSET) * 4 * 4); {mnd, mxd, p, rc, bn, rr, mg, \ {ca1, ca2, ca3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \ {cg1, cg2, cg3, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID}, \ - bf, ba, true, GRFFileProps(INVALID_HOUSE_ID), 0, {0, 0, 0, 0}, \ + bf, ba, true, GRFFileProps(INVALID_HOUSE_ID), 0, {COLOUR_BEGIN, COLOUR_BEGIN, COLOUR_BEGIN, COLOUR_BEGIN}, \ 16, NO_EXTRA_FLAG, HOUSE_NO_CLASS, {0, 2, 0, 0}, 0, 0, 0} /** House specifications from original data */ static const HouseSpec _original_house_specs[] = { From 8797cc7ef25700e414809244a9bcde682cdff067 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 21 Jan 2024 14:09:44 +0000 Subject: [PATCH 15/27] Codechange: Replace GroupStatistics' num_engines with std::map. (#11849) This removes manual memory management with calloc/free calls, and prevents potentially large arrays being allocated for each group. --- src/group.h | 7 +++---- src/group_cmd.cpp | 29 +++++++++++++++-------------- src/script/api/script_engine.cpp | 2 +- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/group.h b/src/group.h index a6c46d84ae..3886b155c4 100644 --- a/src/group.h +++ b/src/group.h @@ -24,15 +24,12 @@ extern GroupPool _group_pool; ///< Pool of groups. struct GroupStatistics { Money profit_last_year; ///< Sum of profits for all vehicles. Money profit_last_year_min_age; ///< Sum of profits for vehicles considered for profit statistics. - uint16_t *num_engines; ///< Caches the number of engines of each type the company owns. + std::map num_engines; ///< Caches the number of engines of each type the company owns. uint16_t num_vehicle; ///< Number of vehicles. uint16_t num_vehicle_min_age; ///< Number of vehicles considered for profit statistics; bool autoreplace_defined; ///< Are any autoreplace rules set? bool autoreplace_finished; ///< Have all autoreplacement finished? - GroupStatistics(); - ~GroupStatistics(); - void Clear(); void ClearProfits() @@ -49,6 +46,8 @@ struct GroupStatistics { this->autoreplace_finished = false; } + uint16_t GetNumEngines(EngineID engine) const; + static GroupStatistics &Get(CompanyID company, GroupID id_g, VehicleType type); static GroupStatistics &Get(const Vehicle *v); static GroupStatistics &GetAllGroup(const Vehicle *v); diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp index b0091ab303..bc379e3212 100644 --- a/src/group_cmd.cpp +++ b/src/group_cmd.cpp @@ -27,16 +27,6 @@ GroupPool _group_pool("Group"); INSTANTIATE_POOL_METHODS(Group) -GroupStatistics::GroupStatistics() -{ - this->num_engines = CallocT(Engine::GetPoolSize()); -} - -GroupStatistics::~GroupStatistics() -{ - free(this->num_engines); -} - /** * Clear all caches. */ @@ -47,9 +37,20 @@ void GroupStatistics::Clear() this->num_vehicle_min_age = 0; this->profit_last_year_min_age = 0; - /* This is also called when NewGRF change. So the number of engines might have changed. Reallocate. */ - free(this->num_engines); - this->num_engines = CallocT(Engine::GetPoolSize()); + /* This is also called when NewGRF change. So the number of engines might have changed. Reset. */ + this->num_engines.clear(); +} + +/** + * Get number of vehicles of a specific engine ID. + * @param engine Engine ID. + * @returns number of vehicles of this engine ID. + */ +uint16_t GroupStatistics::GetNumEngines(EngineID engine) const +{ + auto found = this->num_engines.find(engine); + if (found != std::end(this->num_engines)) return found->second; + return 0; } /** @@ -800,7 +801,7 @@ uint GetGroupNumEngines(CompanyID company, GroupID id_g, EngineID id_e) for (const Group *g : Group::Iterate()) { if (g->parent == id_g) count += GetGroupNumEngines(company, g->index, id_e); } - return count + GroupStatistics::Get(company, id_g, e->type).num_engines[id_e]; + return count + GroupStatistics::Get(company, id_g, e->type).GetNumEngines(id_e); } /** diff --git a/src/script/api/script_engine.cpp b/src/script/api/script_engine.cpp index c142c5fd30..088b692925 100644 --- a/src/script/api/script_engine.cpp +++ b/src/script/api/script_engine.cpp @@ -32,7 +32,7 @@ /* AIs have only access to engines they can purchase or still have in use. * Deity has access to all engined that will be or were available ever. */ CompanyID company = ScriptObject::GetCompany(); - return ScriptCompanyMode::IsDeity() || ::IsEngineBuildable(engine_id, e->type, company) || ::Company::Get(company)->group_all[e->type].num_engines[engine_id] > 0; + return ScriptCompanyMode::IsDeity() || ::IsEngineBuildable(engine_id, e->type, company) || ::Company::Get(company)->group_all[e->type].GetNumEngines(engine_id) > 0; } /* static */ bool ScriptEngine::IsBuildable(EngineID engine_id) From fe035c306e6cafbb856a4c2c2c3e5c7c2f9de17a Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sun, 21 Jan 2024 15:25:00 +0100 Subject: [PATCH 16/27] Codechange: prevent out-of-bound read (even if the result is never used) (#11853) --- src/ai/ai_config.cpp | 2 ++ src/ai/ai_gui.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ai/ai_config.cpp b/src/ai/ai_config.cpp index 7493556736..55e9bc0ba1 100644 --- a/src/ai/ai_config.cpp +++ b/src/ai/ai_config.cpp @@ -18,6 +18,8 @@ /* static */ AIConfig *AIConfig::GetConfig(CompanyID company, ScriptSettingSource source) { + assert(company < MAX_COMPANIES); + AIConfig **config; if (source == SSS_FORCE_NEWGAME || (source == SSS_DEFAULT && _game_mode == GM_MENU)) { config = &_settings_newgame.ai_config[company]; diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp index c51f0be993..4469974c63 100644 --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.cpp @@ -289,7 +289,7 @@ struct AIConfigWindow : public Window { if (!gui_scope) return; - AIConfig *config = AIConfig::GetConfig(this->selected_slot); + AIConfig *config = this->selected_slot == INVALID_COMPANY ? nullptr : AIConfig::GetConfig(this->selected_slot); this->SetWidgetDisabledState(WID_AIC_DECREASE_NUMBER, GetGameSettings().difficulty.max_no_competitors == 0); this->SetWidgetDisabledState(WID_AIC_INCREASE_NUMBER, GetGameSettings().difficulty.max_no_competitors == MAX_COMPANIES - 1); From fa8294ebe79adf52f9bf940512caf0023958c065 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sun, 21 Jan 2024 16:38:15 +0100 Subject: [PATCH 17/27] Remove: rdtsc and TIC/TOC based on CPU ticks (#11856) Use TIC/TOC based on std::chrono instead. This information is also easier to compare with others, as although it depends on CPU, it means a bit more if "yours takes 4ms and mine takes 10ms". --- src/cpu.cpp | 80 ----------------------------------------------------- src/cpu.h | 6 ---- src/debug.h | 23 +++------------ 3 files changed, 4 insertions(+), 105 deletions(-) diff --git a/src/cpu.cpp b/src/cpu.cpp index 239c0e2347..f1b498b6c1 100644 --- a/src/cpu.cpp +++ b/src/cpu.cpp @@ -12,86 +12,6 @@ #include "safeguards.h" -#undef RDTSC_AVAILABLE - -/* rdtsc for MSC_VER, uses simple inline assembly, or _rdtsc - * from external win64.asm because VS2005 does not support inline assembly */ -#if defined(_MSC_VER) && !defined(RDTSC_AVAILABLE) -#include -#include -uint64_t ottd_rdtsc() -{ -#if defined(_M_ARM) - return __rdpmccntr64(); -#elif defined(_M_ARM64) - return _ReadStatusReg(ARM64_PMCCNTR_EL0); -#else - return __rdtsc(); -#endif -} -#define RDTSC_AVAILABLE -#endif - -/* rdtsc for all other *nix-en (hopefully). Use GCC syntax */ -#if (defined(__i386__) || defined(__x86_64__)) && !defined(RDTSC_AVAILABLE) -uint64_t ottd_rdtsc() -{ - uint32_t high, low; - __asm__ __volatile__ ("rdtsc" : "=a" (low), "=d" (high)); - return ((uint64_t)high << 32) | low; -} -# define RDTSC_AVAILABLE -#endif - -/* rdtsc for PPC which has this not */ -#if (defined(__POWERPC__) || defined(__powerpc__)) && !defined(RDTSC_AVAILABLE) -uint64_t ottd_rdtsc() -{ - uint32_t high = 0, high2 = 0, low; - /* PPC does not have rdtsc, so we cheat by reading the two 32-bit time-counters - * it has, 'Move From Time Base (Upper)'. Since these are two reads, in the - * very unlikely event that the lower part overflows to the upper part while we - * read it; we double-check and reread the registers */ - asm volatile ( - "mftbu %0\n" - "mftb %1\n" - "mftbu %2\n" - "cmpw %3,%4\n" - "bne- $-16\n" - : "=r" (high), "=r" (low), "=r" (high2) - : "0" (high), "2" (high2) - ); - return ((uint64_t)high << 32) | low; -} -# define RDTSC_AVAILABLE -#endif - -/* rdtsc for MCST Elbrus 2000 */ -#if defined(__e2k__) && !defined(RDTSC_AVAILABLE) -uint64_t ottd_rdtsc() -{ - uint64_t dst; -# pragma asm_inline - asm("rrd %%clkr, %0" : "=r" (dst)); - return dst; -} -# define RDTSC_AVAILABLE -#endif - -#if defined(__EMSCRIPTEN__) && !defined(RDTSC_AVAILABLE) -/* On emscripten doing TIC/TOC would be ill-advised */ -uint64_t ottd_rdtsc() {return 0;} -# define RDTSC_AVAILABLE -#endif - -/* In all other cases we have no support for rdtsc. No major issue, - * you just won't be able to profile your code with TIC()/TOC() */ -#if !defined(RDTSC_AVAILABLE) -#warning "(non-fatal) No support for rdtsc(), you won't be able to profile with TIC/TOC" -uint64_t ottd_rdtsc() {return 0;} -#endif - - /** * Definitions for CPU detection: * diff --git a/src/cpu.h b/src/cpu.h index edaa8d7c17..116ec8b0ea 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -10,12 +10,6 @@ #ifndef CPU_H #define CPU_H -/** - * Get the tick counter from the CPU (high precision timing). - * @return The count. - */ -uint64_t ottd_rdtsc(); - /** * Get the CPUID information from the CPU. * @param info The retrieved info. All zeros on architectures without CPUID. diff --git a/src/debug.h b/src/debug.h index a7e6300683..c6433df546 100644 --- a/src/debug.h +++ b/src/debug.h @@ -63,7 +63,8 @@ std::string GetDebugString(); /* Shorter form for passing filename and linenumber */ #define FILE_LINE __FILE__, __LINE__ -/* Used for profiling +/** + * Used for profiling. * * Usage: * TIC(); @@ -84,30 +85,14 @@ std::string GetDebugString(); * TIC() / TOC() creates its own block, so make sure not the mangle * it with another block. * - * The output is counted in CPU cycles, and not comparable across - * machines. Mainly useful for local optimisations. + * The output is counted in microseconds. Mainly useful for local optimisations. **/ #define TIC() {\ - uint64_t _xxx_ = ottd_rdtsc();\ - static uint64_t _sum_ = 0;\ - static uint32_t _i_ = 0; - -#define TOC(str, count)\ - _sum_ += ottd_rdtsc() - _xxx_;\ - if (++_i_ == count) {\ - Debug(misc, 0, "[{}] {} [avg: {:.1f}]", str, _sum_, _sum_/(double)_i_);\ - _i_ = 0;\ - _sum_ = 0;\ - }\ -} - -/* Chrono based version. The output is in microseconds. */ -#define TICC() {\ auto _start_ = std::chrono::high_resolution_clock::now();\ static uint64_t _sum_ = 0;\ static uint32_t _i_ = 0; -#define TOCC(str, _count_)\ +#define TOC(str, _count_)\ _sum_ += (std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - _start_)).count();\ if (++_i_ == _count_) {\ Debug(misc, 0, "[{}] {} us [avg: {:.1f} us]", str, _sum_, _sum_/(double)_i_);\ From 89474701bcd16be16cd4a5e5dfbc25d8e70bca8e Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 21 Jan 2024 16:23:17 +0000 Subject: [PATCH 18/27] Codechange: Use templates to deduplicate goal widgets. (#11852) --- src/goal_gui.cpp | 131 ++++++++++++----------------------------------- 1 file changed, 33 insertions(+), 98 deletions(-) diff --git a/src/goal_gui.cpp b/src/goal_gui.cpp index a19180c058..d8be74d358 100644 --- a/src/goal_gui.cpp +++ b/src/goal_gui.cpp @@ -405,110 +405,45 @@ struct GoalQuestionWindow : public Window { } }; -/** Widgets of the goal question window. */ -static constexpr NWidgetPart _nested_goal_question_widgets_question[] = { - NWidget(NWID_HORIZONTAL), - NWidget(WWT_CLOSEBOX, COLOUR_LIGHT_BLUE), - NWidget(WWT_CAPTION, COLOUR_LIGHT_BLUE, WID_GQ_CAPTION), SetDataTip(STR_GOAL_QUESTION_CAPTION_QUESTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), - EndContainer(), - NWidget(WWT_PANEL, COLOUR_LIGHT_BLUE), - NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.modalpopup), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GQ_QUESTION), SetMinimalSize(300, 0), SetFill(1, 0), - NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GQ_BUTTONS), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(85, WidgetDimensions::unscaled.hsep_wide, 85), SetPadding(WidgetDimensions::unscaled.vsep_wide, 0, 0, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - EndContainer(), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(65, WidgetDimensions::unscaled.hsep_wide, 65), SetPadding(WidgetDimensions::unscaled.vsep_wide, 0, 0, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_2), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - EndContainer(), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(25, WidgetDimensions::unscaled.hsep_wide, 25), SetPadding(WidgetDimensions::unscaled.vsep_wide, 0, 0, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_2), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_3), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - EndContainer(), - EndContainer(), +/** + * Widgets of the goal question window. + * @tparam bg_colour Background colour. + * @tparam btn_colour Button colour. + * @tparam caption Window caption string. + */ +template +struct NestedGoalWidgets { + static constexpr auto widgetparts = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, bg_colour), + NWidget(WWT_CAPTION, bg_colour, WID_GQ_CAPTION), SetDataTip(STR_GOAL_QUESTION_CAPTION_QUESTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), EndContainer(), - EndContainer(), -}; - -static constexpr NWidgetPart _nested_goal_question_widgets_info[] = { - NWidget(NWID_HORIZONTAL), - NWidget(WWT_CLOSEBOX, COLOUR_LIGHT_BLUE), - NWidget(WWT_CAPTION, COLOUR_LIGHT_BLUE, WID_GQ_CAPTION), SetDataTip(STR_GOAL_QUESTION_CAPTION_INFORMATION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), - EndContainer(), - NWidget(WWT_PANEL, COLOUR_LIGHT_BLUE), - NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.modalpopup), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GQ_QUESTION), SetMinimalSize(300, 0), SetFill(1, 0), - NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GQ_BUTTONS), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(85, WidgetDimensions::unscaled.hsep_wide, 85), SetPadding(WidgetDimensions::unscaled.vsep_wide, 0, 0, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - EndContainer(), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(65, WidgetDimensions::unscaled.hsep_wide, 65), SetPadding(WidgetDimensions::unscaled.vsep_wide, 0, 0, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_2), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - EndContainer(), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(25, WidgetDimensions::unscaled.hsep_wide, 25), SetPadding(WidgetDimensions::unscaled.vsep_wide, 0, 0, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_2), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_3), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PANEL, bg_colour), + NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.modalpopup), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GQ_QUESTION), SetMinimalSize(300, 0), SetFill(1, 0), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GQ_BUTTONS), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(85, WidgetDimensions::unscaled.hsep_wide, 85), + NWidget(WWT_PUSHTXTBTN, btn_colour, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(65, WidgetDimensions::unscaled.hsep_wide, 65), + NWidget(WWT_PUSHTXTBTN, btn_colour, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, btn_colour, WID_GQ_BUTTON_2), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(25, WidgetDimensions::unscaled.hsep_wide, 25), + NWidget(WWT_PUSHTXTBTN, btn_colour, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, btn_colour, WID_GQ_BUTTON_2), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, btn_colour, WID_GQ_BUTTON_3), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + EndContainer(), EndContainer(), EndContainer(), EndContainer(), - EndContainer(), + }; }; -static constexpr NWidgetPart _nested_goal_question_widgets_warning[] = { - NWidget(NWID_HORIZONTAL), - NWidget(WWT_CLOSEBOX, COLOUR_YELLOW), - NWidget(WWT_CAPTION, COLOUR_YELLOW, WID_GQ_CAPTION), SetDataTip(STR_GOAL_QUESTION_CAPTION_WARNING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), - EndContainer(), - NWidget(WWT_PANEL, COLOUR_YELLOW), - NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.modalpopup), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GQ_QUESTION), SetMinimalSize(300, 0), SetFill(1, 0), - NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GQ_BUTTONS), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(85, WidgetDimensions::unscaled.hsep_wide, 85), SetPadding(WidgetDimensions::unscaled.vsep_wide, 0, 0, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - EndContainer(), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(65, WidgetDimensions::unscaled.hsep_wide, 65), SetPadding(WidgetDimensions::unscaled.vsep_wide, 0, 0, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_2), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - EndContainer(), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(25, WidgetDimensions::unscaled.hsep_wide, 25), SetPadding(WidgetDimensions::unscaled.vsep_wide, 0, 0, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_2), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_3), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - EndContainer(), - EndContainer(), - EndContainer(), - EndContainer(), -}; - -static constexpr NWidgetPart _nested_goal_question_widgets_error[] = { - NWidget(NWID_HORIZONTAL), - NWidget(WWT_CLOSEBOX, COLOUR_RED), - NWidget(WWT_CAPTION, COLOUR_RED, WID_GQ_CAPTION), SetDataTip(STR_GOAL_QUESTION_CAPTION_ERROR, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), - EndContainer(), - NWidget(WWT_PANEL, COLOUR_RED), - NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.modalpopup), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GQ_QUESTION), SetMinimalSize(300, 0), SetFill(1, 0), - NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GQ_BUTTONS), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(85, WidgetDimensions::unscaled.hsep_wide, 85), SetPadding(WidgetDimensions::unscaled.vsep_wide, 0, 0, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - EndContainer(), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(65, WidgetDimensions::unscaled.hsep_wide, 65), SetPadding(WidgetDimensions::unscaled.vsep_wide, 0, 0, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_2), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - EndContainer(), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(25, WidgetDimensions::unscaled.hsep_wide, 25), SetPadding(WidgetDimensions::unscaled.vsep_wide, 0, 0, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_1), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_2), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GQ_BUTTON_3), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - EndContainer(), - EndContainer(), - EndContainer(), - EndContainer(), -}; +static constexpr auto _nested_goal_question_widgets_question = NestedGoalWidgets::widgetparts; +static constexpr auto _nested_goal_question_widgets_info = NestedGoalWidgets::widgetparts; +static constexpr auto _nested_goal_question_widgets_warning = NestedGoalWidgets::widgetparts; +static constexpr auto _nested_goal_question_widgets_error = NestedGoalWidgets::widgetparts; static WindowDesc _goal_question_list_desc[] = { { From a9a0bfffc1a4b38e1701902a656a86c7a695836e Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 21 Jan 2024 16:51:23 +0000 Subject: [PATCH 19/27] Change: Disable building rail infrastructure if train build limit is zero. (#11847) This matches the behaviour of road, ship and aircraft infrastructure. --- src/rail_gui.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 0b7e84ea0a..4b443941d2 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -414,6 +414,7 @@ struct BuildRailToolbarWindow : Window { this->InitNested(TRANSPORT_RAIL); this->SetupRailToolbar(railtype); this->DisableWidget(WID_RAT_REMOVE); + this->OnInvalidateData(); this->last_user_action = INVALID_WID_RAT; if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this); @@ -428,6 +429,39 @@ struct BuildRailToolbarWindow : Window { this->Window::Close(); } + /** List of widgets to be disabled if infrastructure limit prevents building. */ + static inline const std::initializer_list can_build_widgets = { + WID_RAT_BUILD_NS, WID_RAT_BUILD_X, WID_RAT_BUILD_EW, WID_RAT_BUILD_Y, WID_RAT_AUTORAIL, + WID_RAT_BUILD_DEPOT, WID_RAT_BUILD_WAYPOINT, WID_RAT_BUILD_STATION, WID_RAT_BUILD_SIGNALS, + WID_RAT_BUILD_BRIDGE, WID_RAT_BUILD_TUNNEL, WID_RAT_CONVERT_RAIL, + }; + + void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override + { + if (!gui_scope) return; + + bool can_build = CanBuildVehicleInfrastructure(VEH_TRAIN); + for (const WidgetID widget : can_build_widgets) this->SetWidgetDisabledState(widget, !can_build); + if (!can_build) { + CloseWindowById(WC_BUILD_SIGNAL, TRANSPORT_RAIL); + CloseWindowById(WC_BUILD_STATION, TRANSPORT_RAIL); + CloseWindowById(WC_BUILD_DEPOT, TRANSPORT_RAIL); + CloseWindowById(WC_BUILD_WAYPOINT, TRANSPORT_RAIL); + CloseWindowById(WC_SELECT_STATION, 0); + } + } + + bool OnTooltip([[maybe_unused]] Point pt, WidgetID widget, TooltipCloseCondition close_cond) override + { + bool can_build = CanBuildVehicleInfrastructure(VEH_TRAIN); + if (can_build) return false; + + if (std::find(std::begin(can_build_widgets), std::end(can_build_widgets), widget) == std::end(can_build_widgets)) return false; + + GuiShowTooltips(this, STR_TOOLBAR_DISABLED_NO_VEHICLE_AVAILABLE, close_cond); + return true; + } + /** * Configures the rail toolbar for railtype given * @param railtype the railtype to display From f35e257adc00b48a5a0d6734b4dfa261bac053c3 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sun, 21 Jan 2024 18:36:33 +0100 Subject: [PATCH 20/27] Fix #9722: create vital windows as soon as local_company is set (#11858) Many places use local_company to detect whether world generation is done, and blindly assume all vital windows exists when local_company is set. --- src/genworld.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/genworld.cpp b/src/genworld.cpp index 31ce5c7425..9c78403777 100644 --- a/src/genworld.cpp +++ b/src/genworld.cpp @@ -72,8 +72,6 @@ static void CleanupGeneration() _generating_world = false; SetMouseCursorBusy(false); - /* Show all vital windows again, because we have hidden them */ - if (_game_mode != GM_MENU) ShowVitalWindows(); SetModalProgress(false); _gw.proc = nullptr; _gw.abortp = nullptr; @@ -182,6 +180,8 @@ static void _GenerateWorld() ResetObjectToPlace(); _cur_company.Trash(); _current_company = _local_company = _gw.lc; + /* Show all vital windows again, because we have hidden them. */ + if (_game_mode != GM_MENU) ShowVitalWindows(); SetGeneratingWorldProgress(GWP_GAME_START, 1); /* Call any callback */ From 6588680cccfe19517618ca46a7f7314c27064282 Mon Sep 17 00:00:00 2001 From: SamuXarick <43006711+SamuXarick@users.noreply.github.com> Date: Sun, 21 Jan 2024 14:28:27 +0000 Subject: [PATCH 21/27] Revert #6923: start_date parameter is no longer in use There was an issue with the start_date parameter for AIs. It did not let Random AIs to have their configure button clickable once the game has started, and this was due to the start_date not being pushed into the config. But now that start_date is no longer in use since #10653, this workaround can be safely removed. --- src/openttd.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/openttd.cpp b/src/openttd.cpp index 542952b5ec..57a7fb9a41 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -358,9 +358,6 @@ void MakeNewgameSettingsLive() _settings_game.ai_config[c] = nullptr; if (_settings_newgame.ai_config[c] != nullptr) { _settings_game.ai_config[c] = new AIConfig(_settings_newgame.ai_config[c]); - if (!AIConfig::GetConfig(c, AIConfig::SSS_FORCE_GAME)->HasScript()) { - AIConfig::GetConfig(c, AIConfig::SSS_FORCE_GAME)->Change(std::nullopt); - } } } _settings_game.game_config = nullptr; From 0c81579363b442b470361340401e2cd629715b78 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sun, 21 Jan 2024 19:06:58 +0100 Subject: [PATCH 22/27] Fix #6377: two tarballs with the same folder in them were considered as one (#11855) --- src/fileio.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/fileio.cpp b/src/fileio.cpp index 089e25e702..05aa8718b7 100644 --- a/src/fileio.cpp +++ b/src/fileio.cpp @@ -529,6 +529,9 @@ bool TarScanner::AddFile(const std::string &filename, size_t, [[maybe_unused]] c _tar_list[this->subdir][filename] = std::string{}; + std::string filename_base = std::filesystem::path(filename).filename().string(); + SimplifyFileName(filename_base); + TarLinkList links; ///< Temporary list to collect links TarHeader th; @@ -583,7 +586,7 @@ bool TarScanner::AddFile(const std::string &filename, size_t, [[maybe_unused]] c SimplifyFileName(name); Debug(misc, 6, "Found file in tar: {} ({} bytes, {} offset)", name, skip, pos); - if (_tar_filelist[this->subdir].insert(TarFileList::value_type(name, entry)).second) num++; + if (_tar_filelist[this->subdir].insert(TarFileList::value_type(filename_base + PATHSEPCHAR + name, entry)).second) num++; break; } @@ -615,7 +618,7 @@ bool TarScanner::AddFile(const std::string &filename, size_t, [[maybe_unused]] c /* Store links in temporary list */ Debug(misc, 6, "Found link in tar: {} -> {}", name, dest); - links.insert(TarLinkList::value_type(name, dest)); + links.insert(TarLinkList::value_type(filename_base + PATHSEPCHAR + name, filename_base + PATHSEPCHAR + dest)); break; } From 691c628b079ddda6d7bdd684544e5704412f66cd Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 21 Jan 2024 18:10:49 +0000 Subject: [PATCH 23/27] Codechange: Use named initialization for unscaled WidgetDimensions. (#11859) Remove now-unused WD_* enums. --- src/window_gui.h | 212 +++++++++++++---------------------------------- 1 file changed, 59 insertions(+), 153 deletions(-) diff --git a/src/window_gui.h b/src/window_gui.h index 903581332e..a6a94496e2 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -33,27 +33,27 @@ DECLARE_ENUM_AS_BIT_SET(FrameFlags) class WidgetDimensions { public: - RectPadding imgbtn; - RectPadding inset; - RectPadding vscrollbar; - RectPadding hscrollbar; - RectPadding bevel; ///< Widths of bevel border. - RectPadding fullbevel; ///< Always-scaled bevel border. - RectPadding framerect; ///< Offsets within frame area. - RectPadding frametext; ///< Offsets within a text frame area. - RectPadding matrix; ///< Offsets within a matrix cell. - RectPadding shadebox; - RectPadding stickybox; - RectPadding debugbox; - RectPadding defsizebox; - RectPadding resizebox; - RectPadding closebox; - RectPadding captiontext; ///< Offsets of text within a caption. - RectPadding dropdowntext; ///< Offsets of text within a dropdown widget. - RectPadding dropdownlist; ///< Offsets used by a dropdown list itself. - RectPadding modalpopup; ///< Padding for a modal popup. - RectPadding picker; ///< Padding for a picker (dock, station, etc) window. - RectPadding sparse; ///< Padding used for 'sparse' widget window, usually containing multiple frames. + RectPadding imgbtn; ///< Padding around image button image. + RectPadding inset; ///< Padding inside inset container. + RectPadding vscrollbar; ///< Padding inside vertical scrollbar buttons. + RectPadding hscrollbar; ///< Padding inside horizontal scrollbar buttons. + RectPadding bevel; ///< Bevel thickness, affected by "scaled bevels" game option. + RectPadding fullbevel; ///< Always-scaled bevel thickness. + RectPadding framerect; ///< Standard padding inside many panels. + RectPadding frametext; ///< Padding inside frame with text. + RectPadding matrix; ///< Padding of WWT_MATRIX items. + RectPadding shadebox; ///< Padding around image in shadebox widget. + RectPadding stickybox; ///< Padding around image in stickybox widget. + RectPadding debugbox; ///< Padding around image in debugbox widget. + RectPadding defsizebox; ///< Padding around image in defsizebox widget. + RectPadding resizebox; ///< Padding around image in resizebox widget. + RectPadding closebox; ///< Padding around image in closebox widget. + RectPadding captiontext; ///< Padding for text within caption widget. + RectPadding dropdowntext; ///< Padding of drop down list item. + RectPadding dropdownlist; ///< Padding of complete drop down list. + RectPadding modalpopup; ///< Spacing for popup warning/information windows. + RectPadding picker; ///< Padding for a picker (dock, station, etc) window. + RectPadding sparse; ///< Padding used for 'sparse' widget window, usually containing multiple frames. RectPadding sparse_resize; ///< Padding used for a resizeable 'sparse' widget window, usually containing multiple frames. int vsep_picker; ///< Vertical spacing of picker-window widgets. @@ -73,144 +73,50 @@ private: * These constants should not be used elsewhere, use scaled/unscaled WidgetDimensions instead. */ enum WidgetDrawDistances { - /* WWT_IMGBTN(_2) */ - WD_IMGBTN_LEFT = 1, ///< Left offset of the image in the button. - WD_IMGBTN_RIGHT = 2, ///< Right offset of the image in the button. - WD_IMGBTN_TOP = 1, ///< Top offset of image in the button. - WD_IMGBTN_BOTTOM = 2, ///< Bottom offset of image in the button. - - /* WWT_INSET */ - WD_INSET_LEFT = 2, ///< Left offset of string. - WD_INSET_RIGHT = 2, ///< Right offset of string. - WD_INSET_TOP = 1, ///< Top offset of string. - - WD_VSCROLLBAR_LEFT = 2, ///< Left offset of vertical scrollbar. - WD_VSCROLLBAR_RIGHT = 2, ///< Right offset of vertical scrollbar. - WD_VSCROLLBAR_TOP = 3, ///< Top offset of vertical scrollbar. - WD_VSCROLLBAR_BOTTOM = 3, ///< Bottom offset of vertical scrollbar. - - WD_HSCROLLBAR_LEFT = 3, ///< Left offset of horizontal scrollbar. - WD_HSCROLLBAR_RIGHT = 3, ///< Right offset of horizontal scrollbar. - WD_HSCROLLBAR_TOP = 2, ///< Top offset of horizontal scrollbar. - WD_HSCROLLBAR_BOTTOM = 2, ///< Bottom offset of horizontal scrollbar. - - /* Size of the pure frame bevel without any padding. */ - WD_BEVEL_LEFT = 1, ///< Width of left bevel border. - WD_BEVEL_RIGHT = 1, ///< Width of right bevel border. - WD_BEVEL_TOP = 1, ///< Height of top bevel border. - WD_BEVEL_BOTTOM = 1, ///< Height of bottom bevel border. - - /* FrameRect widgets, all text buttons, panel, editbox */ - WD_FRAMERECT_LEFT = 2, ///< Offset at left to draw the frame rectangular area - WD_FRAMERECT_RIGHT = 2, ///< Offset at right to draw the frame rectangular area - WD_FRAMERECT_TOP = 1, ///< Offset at top to draw the frame rectangular area - WD_FRAMERECT_BOTTOM = 1, ///< Offset at bottom to draw the frame rectangular area - - /* WWT_FRAME */ - WD_FRAMETEXT_LEFT = 6, ///< Left offset of the text of the frame. - WD_FRAMETEXT_RIGHT = 6, ///< Right offset of the text of the frame. - WD_FRAMETEXT_TOP = 6, ///< Top offset of the text of the frame - WD_FRAMETEXT_BOTTOM = 6, ///< Bottom offset of the text of the frame - - /* WWT_MATRIX */ - WD_MATRIX_LEFT = 2, ///< Offset at left of a matrix cell. - WD_MATRIX_RIGHT = 2, ///< Offset at right of a matrix cell. - WD_MATRIX_TOP = 3, ///< Offset at top of a matrix cell. - WD_MATRIX_BOTTOM = 1, ///< Offset at bottom of a matrix cell. - - /* WWT_SHADEBOX */ - WD_SHADEBOX_WIDTH = 12, ///< Width of a standard shade box widget. - WD_SHADEBOX_LEFT = 2, ///< Left offset of shade sprite. - WD_SHADEBOX_RIGHT = 2, ///< Right offset of shade sprite. - WD_SHADEBOX_TOP = 3, ///< Top offset of shade sprite. - WD_SHADEBOX_BOTTOM = 3, ///< Bottom offset of shade sprite. - - /* WWT_STICKYBOX */ - WD_STICKYBOX_WIDTH = 12, ///< Width of a standard sticky box widget. - WD_STICKYBOX_LEFT = 2, ///< Left offset of sticky sprite. - WD_STICKYBOX_RIGHT = 2, ///< Right offset of sticky sprite. - WD_STICKYBOX_TOP = 3, ///< Top offset of sticky sprite. - WD_STICKYBOX_BOTTOM = 3, ///< Bottom offset of sticky sprite. - - /* WWT_DEBUGBOX */ - WD_DEBUGBOX_WIDTH = 12, ///< Width of a standard debug box widget. - WD_DEBUGBOX_LEFT = 2, ///< Left offset of debug sprite. - WD_DEBUGBOX_RIGHT = 2, ///< Right offset of debug sprite. - WD_DEBUGBOX_TOP = 3, ///< Top offset of debug sprite. - WD_DEBUGBOX_BOTTOM = 3, ///< Bottom offset of debug sprite. - - /* WWT_DEFSIZEBOX */ - WD_DEFSIZEBOX_WIDTH = 12, ///< Width of a standard defsize box widget. - WD_DEFSIZEBOX_LEFT = 2, ///< Left offset of defsize sprite. - WD_DEFSIZEBOX_RIGHT = 2, ///< Right offset of defsize sprite. - WD_DEFSIZEBOX_TOP = 3, ///< Top offset of defsize sprite. - WD_DEFSIZEBOX_BOTTOM = 3, ///< Bottom offset of defsize sprite. - - /* WWT_RESIZEBOX */ - WD_RESIZEBOX_WIDTH = 12, ///< Width of a resize box widget. - WD_RESIZEBOX_LEFT = 2, ///< Left offset of resize sprite. - WD_RESIZEBOX_RIGHT = 2, ///< Right offset of resize sprite. - WD_RESIZEBOX_TOP = 2, ///< Top offset of resize sprite. - WD_RESIZEBOX_BOTTOM = 2, ///< Bottom offset of resize sprite. - - /* WWT_CLOSEBOX */ - WD_CLOSEBOX_WIDTH = 11, ///< Width of a close box widget. - WD_CLOSEBOX_LEFT = 2, ///< Left offset of closebox string. - WD_CLOSEBOX_RIGHT = 1, ///< Right offset of closebox string. - WD_CLOSEBOX_TOP = 2, ///< Top offset of closebox string. - WD_CLOSEBOX_BOTTOM = 2, ///< Bottom offset of closebox string. - - /* WWT_CAPTION */ - WD_CAPTION_HEIGHT = 14, ///< Height of a title bar. - WD_CAPTIONTEXT_LEFT = 2, ///< Offset of the caption text at the left. - WD_CAPTIONTEXT_RIGHT = 2, ///< Offset of the caption text at the right. - WD_CAPTIONTEXT_TOP = 2, ///< Offset of the caption text at the top. - WD_CAPTIONTEXT_BOTTOM = 2, ///< Offset of the caption text at the bottom. - - /* Dropdown widget. */ - WD_DROPDOWN_HEIGHT = 12, ///< Height of a drop down widget. - WD_DROPDOWNTEXT_LEFT = 2, ///< Left offset of the dropdown widget string. - WD_DROPDOWNTEXT_RIGHT = 2, ///< Right offset of the dropdown widget string. - WD_DROPDOWNTEXT_TOP = 1, ///< Top offset of the dropdown widget string. - WD_DROPDOWNTEXT_BOTTOM = 1, ///< Bottom offset of the dropdown widget string. - - WD_PAR_VSEP_NORMAL = 2, ///< Normal amount of vertical space between two paragraphs of text. - WD_PAR_VSEP_WIDE = 8, ///< Large amount of vertical space between two paragraphs of text. + WD_SHADEBOX_WIDTH = 12, ///< Minimum width of a standard shade box widget. + WD_STICKYBOX_WIDTH = 12, ///< Minimum width of a standard sticky box widget. + WD_DEBUGBOX_WIDTH = 12, ///< Minimum width of a standard debug box widget. + WD_DEFSIZEBOX_WIDTH = 12, ///< Minimum width of a standard defsize box widget. + WD_RESIZEBOX_WIDTH = 12, ///< Minimum width of a resize box widget. + WD_CLOSEBOX_WIDTH = 11, ///< Minimum width of a close box widget. + + WD_CAPTION_HEIGHT = 14, ///< Minimum height of a title bar. + WD_DROPDOWN_HEIGHT = 12, ///< Minimum height of a drop down widget. }; friend NWidgetLeaf; }; inline constexpr WidgetDimensions WidgetDimensions::unscaled = { - {WD_IMGBTN_LEFT, WD_IMGBTN_TOP, WD_IMGBTN_RIGHT, WD_IMGBTN_BOTTOM}, ///< imgbtn - {WD_INSET_LEFT, WD_INSET_TOP, WD_INSET_RIGHT, WD_BEVEL_BOTTOM}, ///< inset - {WD_VSCROLLBAR_LEFT, WD_VSCROLLBAR_TOP, WD_VSCROLLBAR_RIGHT, WD_VSCROLLBAR_BOTTOM}, ///< vscrollbar - {WD_HSCROLLBAR_LEFT, WD_HSCROLLBAR_TOP, WD_HSCROLLBAR_RIGHT, WD_HSCROLLBAR_BOTTOM}, ///< hscrollbar - {WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM}, ///< bevel - {WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM}, ///< fullbevel - {WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM}, ///< framerect - {WD_FRAMETEXT_LEFT, WD_FRAMETEXT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM}, ///< frametext - {WD_MATRIX_LEFT, WD_MATRIX_TOP, WD_MATRIX_RIGHT, WD_MATRIX_BOTTOM}, ///< matrix - {WD_SHADEBOX_LEFT, WD_SHADEBOX_TOP, WD_SHADEBOX_RIGHT, WD_SHADEBOX_BOTTOM}, ///< shadebox - {WD_STICKYBOX_LEFT, WD_STICKYBOX_TOP, WD_STICKYBOX_RIGHT, WD_STICKYBOX_BOTTOM}, ///< stickybox - {WD_DEBUGBOX_LEFT, WD_DEBUGBOX_TOP, WD_DEBUGBOX_RIGHT, WD_DEBUGBOX_BOTTOM}, ///< debugbox - {WD_DEFSIZEBOX_LEFT, WD_DEFSIZEBOX_TOP, WD_DEFSIZEBOX_RIGHT, WD_DEFSIZEBOX_BOTTOM}, ///< defsizebox - {WD_RESIZEBOX_LEFT, WD_RESIZEBOX_TOP, WD_RESIZEBOX_RIGHT, WD_RESIZEBOX_BOTTOM}, ///< resizebox - {WD_CLOSEBOX_LEFT, WD_CLOSEBOX_TOP, WD_CLOSEBOX_RIGHT, WD_CLOSEBOX_BOTTOM}, ///< closebox - {WD_CAPTIONTEXT_LEFT, WD_CAPTIONTEXT_TOP, WD_CAPTIONTEXT_RIGHT, WD_CAPTIONTEXT_BOTTOM}, ///< captiontext - {WD_DROPDOWNTEXT_LEFT, WD_DROPDOWNTEXT_TOP, WD_DROPDOWNTEXT_RIGHT, WD_DROPDOWNTEXT_BOTTOM}, ///< dropdowntext - {WD_BEVEL_LEFT, WD_BEVEL_TOP * 2, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM * 2}, ///< dropdownmenu - {20, 10, 20, 10}, ///< modalpopup - {3, 3, 3, 3}, ///< picker - {10, 8, 10, 8}, ///< sparse window padding - {10, 8, 10, 1}, ///< resizable sparse window padding - 1, ///< vsep_picker - WD_PAR_VSEP_NORMAL, ///< vsep_normal - 4, ///< vsep_sparse - WD_PAR_VSEP_WIDE, ///< vsep_wide - 2, ///< hsep_normal - 6, ///< hsep_wide - 10, ///< hsep_indent + .imgbtn = { .left = 1, .top = 1, .right = 1, .bottom = 1}, + .inset = { .left = 2, .top = 1, .right = 2, .bottom = 1}, + .vscrollbar = { .left = 2, .top = 3, .right = 2, .bottom = 3}, + .hscrollbar = { .left = 3, .top = 2, .right = 3, .bottom = 2}, + .bevel = { .left = 1, .top = 1, .right = 1, .bottom = 1}, + .fullbevel = { .left = 1, .top = 1, .right = 1, .bottom = 1}, + .framerect = { .left = 2, .top = 1, .right = 2, .bottom = 1}, + .frametext = { .left = 6, .top = 6, .right = 6, .bottom = 6}, + .matrix = { .left = 2, .top = 3, .right = 2, .bottom = 1}, + .shadebox = { .left = 2, .top = 3, .right = 2, .bottom = 3}, + .stickybox = { .left = 2, .top = 3, .right = 2, .bottom = 3}, + .debugbox = { .left = 2, .top = 3, .right = 2, .bottom = 3}, + .defsizebox = { .left = 2, .top = 3, .right = 2, .bottom = 3}, + .resizebox = { .left = 2, .top = 2, .right = 2, .bottom = 2}, + .closebox = { .left = 2, .top = 2, .right = 1, .bottom = 2}, + .captiontext = { .left = 2, .top = 2, .right = 2, .bottom = 2}, + .dropdowntext = { .left = 2, .top = 1, .right = 2, .bottom = 1}, + .dropdownlist = { .left = 1, .top = 2, .right = 1, .bottom = 2}, + .modalpopup = { .left = 20, .top = 10, .right = 20, .bottom = 10}, + .picker = { .left = 3, .top = 3, .right = 3, .bottom = 3}, + .sparse = { .left = 10, .top = 8, .right = 10, .bottom = 8}, + .sparse_resize = { .left = 10, .top = 8, .right = 10, .bottom = 0}, + .vsep_picker = 1, + .vsep_normal = 2, + .vsep_sparse = 4, + .vsep_wide = 8, + .hsep_normal = 2, + .hsep_wide = 6, + .hsep_indent = 10, }; /* widget.cpp */ From c7d5cedc7b094a698b65a6d6c600462d559b0eb5 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 21 Jan 2024 18:38:40 +0000 Subject: [PATCH 24/27] Codechange: Replace C-style TICC/TOCC macros with C++ RAII implementation. (#11857) Usage is more robust, and will always include timing when the TicToc object goes out of scope. --- src/debug.h | 66 ++++++++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 36 deletions(-) diff --git a/src/debug.h b/src/debug.h index c6433df546..a46bb8ec53 100644 --- a/src/debug.h +++ b/src/debug.h @@ -63,44 +63,38 @@ std::string GetDebugString(); /* Shorter form for passing filename and linenumber */ #define FILE_LINE __FILE__, __LINE__ -/** - * Used for profiling. - * +/** TicToc profiling. * Usage: - * TIC(); - * --Do your code-- - * TOC("A name", 1); - * - * When you run the TIC() / TOC() multiple times, you can increase the '1' - * to only display average stats every N values. Some things to know: - * - * for (int i = 0; i < 5; i++) { - * TIC(); - * --Do your code-- - * TOC("A name", 5); - * } - * - * Is the correct usage for multiple TIC() / TOC() calls. - * - * TIC() / TOC() creates its own block, so make sure not the mangle - * it with another block. - * - * The output is counted in microseconds. Mainly useful for local optimisations. - **/ -#define TIC() {\ - auto _start_ = std::chrono::high_resolution_clock::now();\ - static uint64_t _sum_ = 0;\ - static uint32_t _i_ = 0; - -#define TOC(str, _count_)\ - _sum_ += (std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - _start_)).count();\ - if (++_i_ == _count_) {\ - Debug(misc, 0, "[{}] {} us [avg: {:.1f} us]", str, _sum_, _sum_/(double)_i_);\ - _i_ = 0;\ - _sum_ = 0;\ - }\ -} + * static TicToc::State state("A name", 1); + * TicToc tt(state); + * --Do your code-- + */ +struct TicToc { + /** Persistent state for TicToc profiling. */ + struct State { + const std::string_view name; + const uint32_t max_count; + uint32_t count = 0; + uint64_t chrono_sum = 0; + + constexpr State(std::string_view name, uint32_t max_count) : name(name), max_count(max_count) { } + }; + + State &state; + std::chrono::high_resolution_clock::time_point chrono_start; ///< real time count. + + inline TicToc(State &state) : state(state), chrono_start(std::chrono::high_resolution_clock::now()) { } + inline ~TicToc() + { + this->state.chrono_sum += (std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - this->chrono_start)).count(); + if (++this->state.count == this->state.max_count) { + Debug(misc, 0, "[{}] {} us [avg: {:.1f} us]", this->state.name, this->state.chrono_sum, this->state.chrono_sum / static_cast(this->state.count)); + this->state.count = 0; + this->state.chrono_sum = 0; + } + } +}; void ShowInfoI(const std::string &str); #define ShowInfo(format_string, ...) ShowInfoI(fmt::format(FMT_STRING(format_string), ## __VA_ARGS__)) From 1985e7415b5c6c5341f87c49fbc1f7f043bec28a Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Sun, 21 Jan 2024 21:52:44 +0100 Subject: [PATCH 25/27] Fix: smooth-scrolling large distances didn't got smoothly in one direction (#11861) --- src/viewport.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/viewport.cpp b/src/viewport.cpp index 7179846b44..f07fd514a5 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -1894,9 +1894,20 @@ void UpdateViewportPosition(Window *w) if (delta_x != 0 || delta_y != 0) { if (_settings_client.gui.smooth_scroll) { int max_scroll = Map::ScaleBySize1D(512 * ZOOM_LVL_BASE); - /* Not at our desired position yet... */ - w->viewport->scrollpos_x += Clamp(DivAwayFromZero(delta_x, 4), -max_scroll, max_scroll); - w->viewport->scrollpos_y += Clamp(DivAwayFromZero(delta_y, 4), -max_scroll, max_scroll); + + int delta_x_clamped; + int delta_y_clamped; + + if (abs(delta_x) > abs(delta_y)) { + delta_x_clamped = Clamp(DivAwayFromZero(delta_x, 4), -max_scroll, max_scroll); + delta_y_clamped = delta_y * delta_x_clamped / delta_x; + } else { + delta_y_clamped = Clamp(DivAwayFromZero(delta_y, 4), -max_scroll, max_scroll); + delta_x_clamped = delta_x * delta_y_clamped / delta_y; + } + + w->viewport->scrollpos_x += delta_x_clamped; + w->viewport->scrollpos_y += delta_y_clamped; } else { w->viewport->scrollpos_x = w->viewport->dest_scrollpos_x; w->viewport->scrollpos_y = w->viewport->dest_scrollpos_y; From b38d3c22087608bc75b40462245ddb23d7951325 Mon Sep 17 00:00:00 2001 From: Kuhnovic <68320206+Kuhnovic@users.noreply.github.com> Date: Sun, 21 Jan 2024 21:56:50 +0100 Subject: [PATCH 26/27] Change: simplified water region evaluation, removed savegame data (#11750) --- src/genworld.cpp | 3 --- src/landscape.cpp | 3 +++ src/map.cpp | 3 +++ src/object_cmd.cpp | 2 ++ src/pathfinder/water_regions.cpp | 34 +++++++------------------- src/pathfinder/water_regions.h | 10 +------- src/saveload/afterload.cpp | 3 --- src/saveload/saveload.h | 2 ++ src/saveload/water_regions_sl.cpp | 40 +++++++------------------------ src/tunnelbridge_cmd.cpp | 2 -- src/water_cmd.cpp | 14 ----------- src/waypoint_cmd.cpp | 1 - 12 files changed, 29 insertions(+), 88 deletions(-) diff --git a/src/genworld.cpp b/src/genworld.cpp index 9c78403777..762cc9a69e 100644 --- a/src/genworld.cpp +++ b/src/genworld.cpp @@ -35,7 +35,6 @@ #include "string_func.h" #include "thread.h" #include "tgp.h" -#include "pathfinder/water_regions.h" #include "safeguards.h" @@ -173,8 +172,6 @@ static void _GenerateWorld() } } - InitializeWaterRegions(); - BasePersistentStorageArray::SwitchMode(PSM_LEAVE_GAMELOOP); ResetObjectToPlace(); diff --git a/src/landscape.cpp b/src/landscape.cpp index 880c77b576..5437995a4d 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -36,6 +36,7 @@ #include "landscape_cmd.h" #include "terraform_cmd.h" #include "station_func.h" +#include "pathfinder/water_regions.h" #include "table/strings.h" #include "table/sprites.h" @@ -538,6 +539,8 @@ void DoClearSquare(TileIndex tile) MakeClear(tile, CLEAR_GRASS, _generating_world ? 3 : 0); MarkTileDirtyByTile(tile); if (remove) RemoveDockingTile(tile); + + InvalidateWaterRegion(tile); } /** diff --git a/src/map.cpp b/src/map.cpp index 77e510d498..91d02b3f9d 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -13,6 +13,7 @@ #include "water_map.h" #include "error_func.h" #include "string_func.h" +#include "pathfinder/water_regions.h" #include "safeguards.h" @@ -62,6 +63,8 @@ extern "C" _CRTIMP void __cdecl _assert(void *, void *, unsigned); Tile::base_tiles = CallocT(Map::size); Tile::extended_tiles = CallocT(Map::size); + + AllocateWaterRegions(); } diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index f8c503499b..066e4a2f55 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -35,6 +35,7 @@ #include "station_func.h" #include "object_cmd.h" #include "landscape_cmd.h" +#include "pathfinder/water_regions.h" #include "table/strings.h" #include "table/object_land.h" @@ -362,6 +363,7 @@ CommandCost CmdBuildObject(DoCommandFlag flags, TileIndex tile, ObjectType type, if (flags & DC_EXEC) { BuildObject(type, tile, _current_company == OWNER_DEITY ? OWNER_NONE : _current_company, nullptr, view); + for (TileIndex t : ta) InvalidateWaterRegion(t); /* Make sure the HQ starts at the right size. */ if (type == OBJECT_HQ) UpdateCompanyHQ(tile, hq_score); diff --git a/src/pathfinder/water_regions.cpp b/src/pathfinder/water_regions.cpp index 2bda5aa1cf..477e3edfd3 100644 --- a/src/pathfinder/water_regions.cpp +++ b/src/pathfinder/water_regions.cpp @@ -18,6 +18,7 @@ #include "tunnelbridge_map.h" #include "follow_track.hpp" #include "ship.h" +#include "debug.h" using TWaterRegionTraversabilityBits = uint16_t; constexpr TWaterRegionPatchLabel FIRST_REGION_LABEL = 1; @@ -114,6 +115,7 @@ public: */ void ForceUpdate() { + Debug(map, 3, "Updating water region ({},{})", GetWaterRegionX(this->tile_area.tile), GetWaterRegionY(this->tile_area.tile)); this->has_cross_region_aqueducts = false; this->tile_patch_labels.fill(INVALID_WATER_REGION_PATCH); @@ -267,8 +269,9 @@ WaterRegionPatchDesc GetWaterRegionPatchInfo(TileIndex tile) void InvalidateWaterRegion(TileIndex tile) { const int index = GetWaterRegionIndex(tile); - if (index > static_cast(_water_regions.size())) return; _water_regions[index].Invalidate(); + + Debug(map, 3, "Invalidated water region ({},{})", GetWaterRegionX(tile), GetWaterRegionY(tile)); } /** @@ -342,38 +345,19 @@ void VisitWaterRegionPatchNeighbors(const WaterRegionPatchDesc &water_region_pat } } -std::vector GetWaterRegionSaveLoadInfo() -{ - std::vector result; - for (WaterRegion ®ion : _water_regions) result.push_back({ region.IsInitialized() }); - return result; -} - -void LoadWaterRegions(const std::vector &save_load_info) -{ - _water_regions.clear(); - _water_regions.reserve(save_load_info.size()); - TWaterRegionIndex index = 0; - for (const auto &loaded_region_info : save_load_info) { - const int region_x = index % GetWaterRegionMapSizeX(); - const int region_y = index / GetWaterRegionMapSizeX(); - WaterRegion ®ion = _water_regions.emplace_back(region_x, region_y); - if (loaded_region_info.initialized) region.ForceUpdate(); - index++; - } -} - /** - * Initializes all water regions. All water tiles will be scanned and interconnected water patches within regions will be identified. + * Allocates the appropriate amount of water regions for the current map size */ -void InitializeWaterRegions() +void AllocateWaterRegions() { _water_regions.clear(); _water_regions.reserve(static_cast(GetWaterRegionMapSizeX()) * GetWaterRegionMapSizeY()); + Debug(map, 2, "Allocating {} x {} water regions", GetWaterRegionMapSizeX(), GetWaterRegionMapSizeY()); + for (int region_y = 0; region_y < GetWaterRegionMapSizeY(); region_y++) { for (int region_x = 0; region_x < GetWaterRegionMapSizeX(); region_x++) { - _water_regions.emplace_back(region_x, region_y).ForceUpdate(); + _water_regions.emplace_back(region_x, region_y); } } } diff --git a/src/pathfinder/water_regions.h b/src/pathfinder/water_regions.h index 801c83b563..8cbb6e6ee9 100644 --- a/src/pathfinder/water_regions.h +++ b/src/pathfinder/water_regions.h @@ -60,14 +60,6 @@ void InvalidateWaterRegion(TileIndex tile); using TVisitWaterRegionPatchCallBack = std::function; void VisitWaterRegionPatchNeighbors(const WaterRegionPatchDesc &water_region_patch, TVisitWaterRegionPatchCallBack &callback); -void InitializeWaterRegions(); - -struct WaterRegionSaveLoadInfo -{ - bool initialized; -}; - -std::vector GetWaterRegionSaveLoadInfo(); -void LoadWaterRegions(const std::vector &save_load_info); +void AllocateWaterRegions(); #endif /* WATER_REGIONS_H */ diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 33d12648b5..e6fd1c7ba1 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -61,7 +61,6 @@ #include "../timer/timer.h" #include "../timer/timer_game_calendar.h" #include "../timer/timer_game_tick.h" -#include "../pathfinder/water_regions.h" #include "saveload_internal.h" @@ -3297,8 +3296,6 @@ bool AfterLoadGame() } } - if (IsSavegameVersionBefore(SLV_WATER_REGIONS)) InitializeWaterRegions(); - return true; } diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index be139df5ab..4c784ba70d 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -367,6 +367,8 @@ enum SaveLoadVersion : uint16_t { SLV_TIMETABLE_TICKS_TYPE, ///< 323 PR#11435 Convert timetable current order time to ticks. SLV_WATER_REGIONS, ///< 324 PR#10543 Water Regions for ship pathfinder. + SLV_WATER_REGION_EVAL_SIMPLIFIED, ///< 325 PR#11750 Simplified Water Region evaluation. + SL_MAX_VERSION, ///< Highest possible saveload version }; diff --git a/src/saveload/water_regions_sl.cpp b/src/saveload/water_regions_sl.cpp index ae872ccfd9..92e601dca3 100644 --- a/src/saveload/water_regions_sl.cpp +++ b/src/saveload/water_regions_sl.cpp @@ -10,45 +10,23 @@ #include "../stdafx.h" #include "saveload.h" -#include "pathfinder/water_regions.h" #include "../safeguards.h" -static const SaveLoad _water_region_desc[] = { - SLE_VAR(WaterRegionSaveLoadInfo, initialized, SLE_BOOL), -}; - -struct WRGNChunkHandler : ChunkHandler { - WRGNChunkHandler() : ChunkHandler('WRGN', CH_TABLE) {} - - void Save() const override - { - SlTableHeader(_water_region_desc); +extern void SlSkipArray(); - int index = 0; - for (WaterRegionSaveLoadInfo ®ion : GetWaterRegionSaveLoadInfo()) { - SlSetArrayIndex(index++); - SlObject(®ion, _water_region_desc); - } - } +/* Water Region savegame data is no longer used, but still needed for old savegames to load without errors. */ +struct WaterRegionChunkHandler : ChunkHandler { + WaterRegionChunkHandler() : ChunkHandler('WRGN', CH_READONLY) + {} void Load() const override { - const std::vector slt = SlTableHeader(_water_region_desc); - - int index; - - std::vector loaded_info; - while ((index = SlIterateArray()) != -1) { - WaterRegionSaveLoadInfo region_info; - SlObject(®ion_info, slt); - loaded_info.push_back(std::move(region_info)); - } - - LoadWaterRegions(loaded_info); - } + SlTableHeader({}); + SlSkipArray(); + }; }; -static const WRGNChunkHandler WRGN; +static const WaterRegionChunkHandler WRGN; static const ChunkHandlerRef water_region_chunk_handlers[] = { WRGN }; extern const ChunkHandlerTable _water_region_chunk_handlers(water_region_chunk_handlers); diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 1805f476df..a2e9d67f1c 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -562,8 +562,6 @@ CommandCost CmdBuildBridge(DoCommandFlag flags, TileIndex tile_end, TileIndex ti MakeAqueductBridgeRamp(tile_end, owner, ReverseDiagDir(dir)); CheckForDockingTile(tile_start); CheckForDockingTile(tile_end); - InvalidateWaterRegion(tile_start); - InvalidateWaterRegion(tile_end); break; default: diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index aec29645a3..8325c4da19 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -134,9 +134,6 @@ CommandCost CmdBuildShipDepot(DoCommandFlag flags, TileIndex tile, Axis axis) } if (flags & DC_EXEC) { - InvalidateWaterRegion(tile); - InvalidateWaterRegion(tile2); - Depot *depot = new Depot(tile); depot->build_date = TimerGameCalendar::date; @@ -247,7 +244,6 @@ void MakeWaterKeepingClass(TileIndex tile, Owner o) /* Zero map array and terminate animation */ DoClearSquare(tile); - InvalidateWaterRegion(tile); /* Maybe change to water */ switch (wc) { @@ -345,10 +341,6 @@ static CommandCost DoBuildLock(TileIndex tile, DiagDirection dir, DoCommandFlag } if (flags & DC_EXEC) { - InvalidateWaterRegion(tile); - InvalidateWaterRegion(tile + delta); - InvalidateWaterRegion(tile - delta); - /* Update company infrastructure counts. */ Company *c = Company::GetIfValid(_current_company); if (c != nullptr) { @@ -491,8 +483,6 @@ CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, TileIndex start_t if (!water) cost.AddCost(ret); if (flags & DC_EXEC) { - InvalidateWaterRegion(current_tile); - if (IsTileType(current_tile, MP_WATER) && IsCanal(current_tile)) { Owner owner = GetTileOwner(current_tile); if (Company::IsValidID(owner)) { @@ -543,8 +533,6 @@ CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, TileIndex start_t static CommandCost ClearTile_Water(TileIndex tile, DoCommandFlag flags) { - if (flags & DC_EXEC) InvalidateWaterRegion(tile); - switch (GetWaterTileType(tile)) { case WATER_TILE_CLEAR: { if (flags & DC_NO_WATER) return_cmd_error(STR_ERROR_CAN_T_BUILD_ON_WATER); @@ -1175,8 +1163,6 @@ void DoFloodTile(TileIndex target) } if (flooded) { - InvalidateWaterRegion(target); - /* Mark surrounding canal tiles dirty too to avoid glitches */ MarkCanalsAndRiversAroundDirty(target); diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index 11e16b9a41..38165a62c8 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -347,7 +347,6 @@ CommandCost CmdBuildBuoy(DoCommandFlag flags, TileIndex tile) if (wp->town == nullptr) MakeDefaultName(wp); MakeBuoy(tile, wp->index, GetWaterClass(tile)); - InvalidateWaterRegion(tile); CheckForDockingTile(tile); MarkTileDirtyByTile(tile); From 419f48dfb3201fbc6913f8342a9aa14858dc7e88 Mon Sep 17 00:00:00 2001 From: EmperorJake <68182631+EmperorJake@users.noreply.github.com> Date: Mon, 22 Jan 2024 08:23:35 +1100 Subject: [PATCH 27/27] Change: set amount of smoke/sparks to "realistic" by default (#11624) --- src/table/settings/game_settings.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/table/settings/game_settings.ini b/src/table/settings/game_settings.ini index 7902d17a4c..932330c0aa 100644 --- a/src/table/settings/game_settings.ini +++ b/src/table/settings/game_settings.ini @@ -228,7 +228,7 @@ var = vehicle.smoke_amount type = SLE_UINT8 from = SLV_145 flags = SF_GUI_DROPDOWN -def = 1 +def = 2 min = 0 max = 2 str = STR_CONFIG_SETTING_SMOKE_AMOUNT