diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 6779b9b836..d5013f7c6e 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -285,9 +285,10 @@ struct DepotWindow : Window { DrawTrainImage(u, image_left + (rtl ? 0 : x_space), image_right - (rtl ? x_space : 0), sprite_y - 1, this->sel, free_wagon ? 0 : this->hscroll->GetPosition(), this->vehicle_over); - /* Length of consist in tiles (rounded up) */ - SetDParam(0, CeilDiv(u->gcache.cached_total_length, TILE_SIZE)); - DrawString(rtl ? left + WD_FRAMERECT_LEFT : right - this->count_width, rtl ? left + this->count_width : right - WD_FRAMERECT_RIGHT, y + (this->resize.step_height - FONT_HEIGHT_SMALL) / 2, STR_TINY_BLACK_COMA, TC_FROMSTRING, SA_RIGHT); // Draw the counter + /* Length of consist in tiles with 1 fractional digit (rounded up) */ + SetDParam(0, CeilDiv(u->gcache.cached_total_length * 10, TILE_SIZE)); + SetDParam(1, 1); + DrawString(rtl ? left + WD_FRAMERECT_LEFT : right - this->count_width, rtl ? left + this->count_width : right - WD_FRAMERECT_RIGHT, y + (this->resize.step_height - FONT_HEIGHT_SMALL) / 2, STR_TINY_BLACK_DECIMAL, TC_FROMSTRING, SA_RIGHT); // Draw the counter break; } @@ -598,8 +599,9 @@ struct DepotWindow : Window { uint min_height = 0; if (this->type == VEH_TRAIN) { - SetDParam(0, 100); - this->count_width = GetStringBoundingBox(STR_TINY_BLACK_COMA).width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; + SetDParam(0, 1000); + SetDParam(1, 1); + this->count_width = GetStringBoundingBox(STR_TINY_BLACK_DECIMAL).width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; } else { this->count_width = 0; } diff --git a/src/lang/english.txt b/src/lang/english.txt index 72367f45c8..bb0317550a 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -4242,6 +4242,7 @@ STR_TINY_BLACK_COMA :{TINYFONT}{BLAC STR_TINY_COMMA :{TINYFONT}{COMMA} STR_BLUE_COMMA :{BLUE}{COMMA} STR_RED_COMMA :{RED}{COMMA} +STR_TINY_BLACK_DECIMAL :{TINYFONT}{BLACK}{DECIMAL} STR_COMPANY_MONEY :{WHITE}{CURRENCY} STR_BLACK_DATE_LONG :{BLACK}{DATE_LONG} STR_BLACK_CROSS :{BLACK}{CROSS} diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 502e6dd1c6..f97ec436f4 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -7606,6 +7606,33 @@ static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseS return true; } +/** + * Make sure there is at least one house available in the year 0 for the given + * climate / housezone combination. + * @param bitmask The climate and housezone to check for. Exactly one climate + * bit and one housezone bit should be set. + */ +static void EnsureEarlyHouse(HouseZones bitmask) +{ + Year min_year = MAX_YEAR; + + for (int i = 0; i < HOUSE_MAX; i++) { + HouseSpec *hs = HouseSpec::Get(i); + if (hs == NULL || !hs->enabled) continue; + if ((hs->building_availability & bitmask) != bitmask) continue; + if (hs->min_year < min_year) min_year = hs->min_year; + } + + if (min_year == 0) return; + + for (int i = 0; i < HOUSE_MAX; i++) { + HouseSpec *hs = HouseSpec::Get(i); + if (hs == NULL || !hs->enabled) continue; + if ((hs->building_availability & bitmask) != bitmask) continue; + if (hs->min_year == min_year) hs->min_year = 0; + } +} + /** * Add all new houses to the house array. House properties can be set at any * time in the GRF file, so we can only add a house spec to the house array @@ -7623,8 +7650,6 @@ static void FinaliseHouseArray() * On the other hand, why 1930? Just 'fix' the houses with the lowest * minimum introduction date to 0. */ - Year min_year = MAX_YEAR; - const GRFFile * const *end = _grf_files.End(); for (GRFFile **file = _grf_files.Begin(); file != end; file++) { HouseSpec **&housespec = (*file)->housespec; @@ -7642,7 +7667,6 @@ static void FinaliseHouseArray() if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue; _house_mngr.SetEntitySpec(hs); - if (hs->min_year < min_year) min_year = hs->min_year; } } @@ -7666,12 +7690,19 @@ static void FinaliseHouseArray() } } - if (min_year != 0) { - for (int i = 0; i < HOUSE_MAX; i++) { - HouseSpec *hs = HouseSpec::Get(i); + HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12)); + EnsureEarlyHouse(HZ_ZON1 | climate_mask); + EnsureEarlyHouse(HZ_ZON2 | climate_mask); + EnsureEarlyHouse(HZ_ZON3 | climate_mask); + EnsureEarlyHouse(HZ_ZON4 | climate_mask); + EnsureEarlyHouse(HZ_ZON5 | climate_mask); - if (hs->enabled && hs->min_year == min_year) hs->min_year = 0; - } + if (_settings_game.game_creation.landscape == LT_ARCTIC) { + EnsureEarlyHouse(HZ_ZON1 | HZ_SUBARTC_ABOVE); + EnsureEarlyHouse(HZ_ZON2 | HZ_SUBARTC_ABOVE); + EnsureEarlyHouse(HZ_ZON3 | HZ_SUBARTC_ABOVE); + EnsureEarlyHouse(HZ_ZON4 | HZ_SUBARTC_ABOVE); + EnsureEarlyHouse(HZ_ZON5 | HZ_SUBARTC_ABOVE); } } diff --git a/src/screenshot.cpp b/src/screenshot.cpp index d5a188a8dd..46f54360d2 100644 --- a/src/screenshot.cpp +++ b/src/screenshot.cpp @@ -277,7 +277,7 @@ static bool MakePNGImage(const char *name, ScreenshotCallback *callb, void *user text[0].text_length = strlen(_openttd_revision); text[0].compression = PNG_TEXT_COMPRESSION_NONE; - char buf[2048]; + char buf[8192]; char *p = buf; p += seprintf(p, lastof(buf), "Graphics set: %s (%u)\n", BaseGraphics::GetUsedSet()->name, BaseGraphics::GetUsedSet()->version); p = strecpy(p, "NewGRFs:\n", lastof(buf)); diff --git a/src/strings.cpp b/src/strings.cpp index aae4849974..36f67d7420 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -231,9 +231,23 @@ void InjectDParam(uint amount) memmove(_decode_parameters + amount, _decode_parameters, sizeof(_decode_parameters) - amount * sizeof(uint64)); } -static char *FormatNumber(char *buff, int64 number, const char *last, const char *separator, int zerofill_from = 19) +/** + * Format a number into a string. + * @param buff the buffer to write to + * @param number the number to write down + * @param last the last element in the buffer + * @param separator the thousands-separator to use + * @param zerofill minimum number of digits to print for the integer part. The number will be filled with zeros at the front if necessary. + * @param fractional_digits number of fractional digits to display after a decimal separator. The decimal separator is inserted + * in front of the \a fractional_digits last digit of \a number. + * @return till where we wrote + */ +static char *FormatNumber(char *buff, int64 number, const char *last, const char *separator, int zerofill = 1, int fractional_digits = 0) { + static const int max_digits = 20; uint64 divisor = 10000000000000000000ULL; + zerofill += fractional_digits; + int thousands_offset = (max_digits - fractional_digits - 1) % 3; if (number < 0) { buff += seprintf(buff, last, "-"); @@ -242,15 +256,21 @@ static char *FormatNumber(char *buff, int64 number, const char *last, const char uint64 num = number; uint64 tot = 0; - for (int i = 0; i < 20; i++) { + for (int i = 0; i < max_digits; i++) { + if (i == max_digits - fractional_digits) { + const char *decimal_separator = _settings_game.locale.digit_decimal_separator; + if (decimal_separator == NULL) decimal_separator = _langpack->digit_decimal_separator; + buff += seprintf(buff, last, "%s", decimal_separator); + } + uint64 quot = 0; if (num >= divisor) { quot = num / divisor; num = num % divisor; } - if (tot |= quot || i >= zerofill_from) { + if (tot |= quot || i >= max_digits - zerofill) { buff += seprintf(buff, last, "%i", (int)quot); - if ((i % 3) == 1 && i != 19) buff = strecpy(buff, separator, last); + if ((i % 3) == thousands_offset && i < max_digits - 1 - fractional_digits) buff = strecpy(buff, separator, last); } divisor /= 10; @@ -261,11 +281,11 @@ static char *FormatNumber(char *buff, int64 number, const char *last, const char return buff; } -static char *FormatCommaNumber(char *buff, int64 number, const char *last) +static char *FormatCommaNumber(char *buff, int64 number, const char *last, int fractional_digits = 0) { const char *separator = _settings_game.locale.digit_group_separator; if (separator == NULL) separator = _langpack->digit_group_separator; - return FormatNumber(buff, number, last, separator); + return FormatNumber(buff, number, last, separator, 1, fractional_digits); } static char *FormatNoCommaNumber(char *buff, int64 number, const char *last) @@ -275,7 +295,7 @@ static char *FormatNoCommaNumber(char *buff, int64 number, const char *last) static char *FormatZerofillNumber(char *buff, int64 number, int64 count, const char *last) { - return FormatNumber(buff, number, last, "", 20 - count); + return FormatNumber(buff, number, last, "", count); } static char *FormatHexNumber(char *buff, uint64 number, const char *last) @@ -989,6 +1009,13 @@ static char *FormatString(char *buff, const char *str_arg, int64 *argv, const in buff = FormatCommaNumber(buff, GetInt64(&argv, argve, &argt, SCC_COMMA), last); break; + case SCC_DECIMAL: {// {DECIMAL} + int64 number = GetInt64(&argv, argve, &argt, SCC_DECIMAL); + int digits = GetInt32(&argv, argve, &argt, SCC_DECIMAL); + buff = FormatCommaNumber(buff, number, last, digits); + break; + } + case SCC_ARG_INDEX: { // Move argument pointer byte offset = (byte)*str++; argv = argv_orig + offset; diff --git a/src/table/control_codes.h b/src/table/control_codes.h index ccebcc864e..73d4a2b91b 100644 --- a/src/table/control_codes.h +++ b/src/table/control_codes.h @@ -72,6 +72,7 @@ enum StringControlCode { SCC_STRING, SCC_COMMA, + SCC_DECIMAL, SCC_NUM, SCC_ZEROFILL_NUM, SCC_HEX, diff --git a/src/table/strgen_tables.h b/src/table/strgen_tables.h index ecc3bbedd4..9979b10f36 100644 --- a/src/table/strgen_tables.h +++ b/src/table/strgen_tables.h @@ -92,6 +92,7 @@ static const CmdStruct _cmd_structs[] = { /* Numbers */ {"COMMA", EmitSingleChar, SCC_COMMA, 1, C_NONE}, // Number with comma + {"DECIMAL", EmitSingleChar, SCC_DECIMAL, 2, C_NONE}, // Number with comma and fractional part. Second parameter is number of fractional digits, first parameter is number times 10**(second parameter). {"NUM", EmitSingleChar, SCC_NUM, 1, C_NONE}, // Signed number {"ZEROFILL_NUM", EmitSingleChar, SCC_ZEROFILL_NUM, 2, C_NONE}, // Unsigned number with zero fill, e.g. "02". First parameter is number, second minimum length {"BYTES", EmitSingleChar, SCC_BYTES, 1, C_NONE}, // Unsigned number with "bytes", i.e. "1.02 MiB or 123 KiB"