diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.cpp @@ -138,7 +138,7 @@ private: StringID GetBridgeSelectString(const BuildBridgeData &bridge_data) const { SetDParam(0, bridge_data.spec->material); - SetDParam(1, bridge_data.spec->speed); + SetDParam(1, PackVelocity(bridge_data.spec->speed, static_cast(this->transport_type))); SetDParam(2, bridge_data.cost); /* If the bridge has no meaningful speed limit, don't display it. */ if (bridge_data.spec->speed == UINT16_MAX) { diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -611,7 +611,7 @@ static int DrawRailWagonPurchaseInfo(int if (_settings_game.vehicle.wagon_speed_limits) { uint max_speed = e->GetDisplayMaxSpeed(); if (max_speed > 0) { - SetDParam(0, max_speed); + SetDParam(0, PackVelocity(max_speed, e->type)); DrawString(left, right, y, STR_PURCHASE_INFO_SPEED); y += FONT_HEIGHT_NORMAL; } @@ -646,7 +646,7 @@ static int DrawRailEnginePurchaseInfo(in y += FONT_HEIGHT_NORMAL; /* Max speed - Engine power */ - SetDParam(0, e->GetDisplayMaxSpeed()); + SetDParam(0, PackVelocity(e->GetDisplayMaxSpeed(), e->type)); SetDParam(1, e->GetPower()); DrawString(left, right, y, STR_PURCHASE_INFO_SPEED_POWER); y += FONT_HEIGHT_NORMAL; @@ -701,7 +701,7 @@ static int DrawRoadVehPurchaseInfo(int l y += FONT_HEIGHT_NORMAL; /* Max speed - Engine power */ - SetDParam(0, e->GetDisplayMaxSpeed()); + SetDParam(0, PackVelocity(e->GetDisplayMaxSpeed(), e->type)); SetDParam(1, e->GetPower()); DrawString(left, right, y, STR_PURCHASE_INFO_SPEED_POWER); y += FONT_HEIGHT_NORMAL; @@ -715,11 +715,11 @@ static int DrawRoadVehPurchaseInfo(int l if (te.cost != 0) { SetDParam(0, e->GetCost() + te.cost); SetDParam(1, te.cost); - SetDParam(2, e->GetDisplayMaxSpeed()); + SetDParam(2, PackVelocity(e->GetDisplayMaxSpeed(), e->type)); DrawString(left, right, y, STR_PURCHASE_INFO_COST_REFIT_SPEED); } else { SetDParam(0, e->GetCost()); - SetDParam(1, e->GetDisplayMaxSpeed()); + SetDParam(1, PackVelocity(e->GetDisplayMaxSpeed(), e->type)); DrawString(left, right, y, STR_PURCHASE_INFO_COST_SPEED); } y += FONT_HEIGHT_NORMAL; @@ -747,11 +747,11 @@ static int DrawShipPurchaseInfo(int left if (te.cost != 0) { SetDParam(0, e->GetCost() + te.cost); SetDParam(1, te.cost); - SetDParam(2, ocean_speed); + SetDParam(2, PackVelocity(ocean_speed, e->type)); DrawString(left, right, y, STR_PURCHASE_INFO_COST_REFIT_SPEED); } else { SetDParam(0, e->GetCost()); - SetDParam(1, ocean_speed); + SetDParam(1, PackVelocity(ocean_speed, e->type)); DrawString(left, right, y, STR_PURCHASE_INFO_COST_SPEED); } y += FONT_HEIGHT_NORMAL; @@ -766,11 +766,11 @@ static int DrawShipPurchaseInfo(int left } y += FONT_HEIGHT_NORMAL; - SetDParam(0, ocean_speed); + SetDParam(0, PackVelocity(ocean_speed, e->type)); DrawString(left, right, y, STR_PURCHASE_INFO_SPEED_OCEAN); y += FONT_HEIGHT_NORMAL; - SetDParam(0, canal_speed); + SetDParam(0, PackVelocity(canal_speed, e->type)); DrawString(left, right, y, STR_PURCHASE_INFO_SPEED_CANAL); y += FONT_HEIGHT_NORMAL; } @@ -807,11 +807,11 @@ static int DrawAircraftPurchaseInfo(int if (te.cost != 0) { SetDParam(0, e->GetCost() + te.cost); SetDParam(1, te.cost); - SetDParam(2, e->GetDisplayMaxSpeed()); + SetDParam(2, PackVelocity(e->GetDisplayMaxSpeed(), e->type)); DrawString(left, right, y, STR_PURCHASE_INFO_COST_REFIT_SPEED); } else { SetDParam(0, e->GetCost()); - SetDParam(1, e->GetDisplayMaxSpeed()); + SetDParam(1, PackVelocity(e->GetDisplayMaxSpeed(), e->type)); DrawString(left, right, y, STR_PURCHASE_INFO_COST_SPEED); } y += FONT_HEIGHT_NORMAL; diff --git a/src/engine_gui.cpp b/src/engine_gui.cpp --- a/src/engine_gui.cpp +++ b/src/engine_gui.cpp @@ -170,7 +170,7 @@ uint GetTotalCapacityOfArticulatedParts( static StringID GetTrainEngineInfoString(const Engine *e) { SetDParam(0, e->GetCost()); - SetDParam(2, e->GetDisplayMaxSpeed()); + SetDParam(2, PackVelocity(e->GetDisplayMaxSpeed(), e->type)); SetDParam(3, e->GetPower()); SetDParam(1, e->GetDisplayWeight()); SetDParam(7, e->GetDisplayMaxTractiveEffort()); @@ -196,7 +196,7 @@ static StringID GetAircraftEngineInfoStr uint i = 0; SetDParam(i++, e->GetCost()); - SetDParam(i++, e->GetDisplayMaxSpeed()); + SetDParam(i++, PackVelocity(e->GetDisplayMaxSpeed(), e->type)); SetDParam(i++, e->GetAircraftTypeText()); if (range > 0) SetDParam(i++, range); SetDParam(i++, cargo); @@ -217,7 +217,7 @@ static StringID GetRoadVehEngineInfoStri { if (_settings_game.vehicle.roadveh_acceleration_model == AM_ORIGINAL) { SetDParam(0, e->GetCost()); - SetDParam(1, e->GetDisplayMaxSpeed()); + SetDParam(1, PackVelocity(e->GetDisplayMaxSpeed(), e->type)); uint capacity = GetTotalCapacityOfArticulatedParts(e->index); if (capacity != 0) { SetDParam(2, e->GetDefaultCargoType()); @@ -229,7 +229,7 @@ static StringID GetRoadVehEngineInfoStri return STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST; } else { SetDParam(0, e->GetCost()); - SetDParam(2, e->GetDisplayMaxSpeed()); + SetDParam(2, PackVelocity(e->GetDisplayMaxSpeed(), e->type)); SetDParam(3, e->GetPower()); SetDParam(1, e->GetDisplayWeight()); SetDParam(7, e->GetDisplayMaxTractiveEffort()); @@ -250,7 +250,7 @@ static StringID GetRoadVehEngineInfoStri static StringID GetShipEngineInfoString(const Engine *e) { SetDParam(0, e->GetCost()); - SetDParam(1, e->GetDisplayMaxSpeed()); + SetDParam(1, PackVelocity(e->GetDisplayMaxSpeed(), e->type)); SetDParam(2, e->GetDefaultCargoType()); SetDParam(3, e->GetDisplayDefaultCapacity()); SetDParam(4, e->GetRunningCost()); diff --git a/src/lang/english.txt b/src/lang/english.txt --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -195,6 +195,7 @@ STR_UNITS_VELOCITY_IMPERIAL STR_UNITS_VELOCITY_METRIC :{COMMA}{NBSP}km/h STR_UNITS_VELOCITY_SI :{COMMA}{NBSP}m/s STR_UNITS_VELOCITY_GAMEUNITS :{DECIMAL}{NBSP}tiles/day +STR_UNITS_VELOCITY_KNOTS :{COMMA}{NBSP}knots STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp STR_UNITS_POWER_METRIC :{COMMA}{NBSP}hp @@ -1951,13 +1952,15 @@ STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT STR_CONFIG_SETTING_SHORT_PATH_SATURATION :Saturation of short paths before using high-capacity paths: {STRING2} STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT :Frequently there are multiple paths between two given stations. Cargodist will saturate the shortest path first, then use the second shortest path until that is saturated and so on. Saturation is determined by an estimation of capacity and planned usage. Once it has saturated all paths, if there is still demand left, it will overload all paths, prefering the ones with high capacity. Most of the time the algorithm will not estimate the capacity accurately, though. This setting allows you to specify up to which percentage a shorter path must be saturated in the first pass before choosing the next longer one. Set it to less than 100% to avoid overcrowded stations in case of overestimated capacity. -STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY :Speed units: {STRING2} +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY :Speed units (land): {STRING2} +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_NAUTICAL :Speed units (nautical): {STRING2} STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_HELPTEXT :Whenever a speed is shown in the user interface, show it in the selected units -###length 4 +###length 5 STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_IMPERIAL :Imperial (mph) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_METRIC :Metric (km/h) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_SI :SI (m/s) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_GAMEUNITS :Game units (tiles/day) +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_KNOTS :Knots STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER :Vehicle power units: {STRING2} STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_HELPTEXT :Whenever a vehicle's power is shown in the user interface, show it in the selected units diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -267,7 +267,7 @@ public: /* Rail speed limit */ if (td.rail_speed != 0) { - SetDParam(0, td.rail_speed); + SetDParam(0, PackVelocity(td.rail_speed, VEH_TRAIN)); this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT)); } @@ -279,7 +279,7 @@ public: /* Road speed limit */ if (td.road_speed != 0) { - SetDParam(0, td.road_speed); + SetDParam(0, PackVelocity(td.road_speed, VEH_ROAD)); this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT)); } @@ -291,7 +291,7 @@ public: /* Tram speed limit */ if (td.tram_speed != 0) { - SetDParam(0, td.tram_speed); + SetDParam(0, PackVelocity(td.tram_speed, VEH_ROAD)); this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT)); } diff --git a/src/order_gui.cpp b/src/order_gui.cpp --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -177,8 +177,8 @@ static const StringID _order_conditional INVALID_STRING_ID, }; -extern uint ConvertSpeedToDisplaySpeed(uint speed); -extern uint ConvertDisplaySpeedToSpeed(uint speed); +extern uint ConvertSpeedToDisplaySpeed(uint speed, VehicleType type); +extern uint ConvertDisplaySpeedToSpeed(uint speed, VehicleType type); static const StringID _order_depot_action_dropdown[] = { STR_ORDER_DROP_GO_ALWAYS_DEPOT, @@ -345,7 +345,7 @@ void DrawOrderString(const Vehicle *v, c SetDParam(3, STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS + occ); uint value = order->GetConditionValue(); - if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value); + if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value, v->type); SetDParam(4, value); } @@ -1149,7 +1149,7 @@ public: if (order != nullptr && order->IsType(OT_CONDITIONAL)) { uint value = order->GetConditionValue(); - if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value); + if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value, this->vehicle->type); SetDParam(0, value); } break; @@ -1317,7 +1317,7 @@ public: const Order *order = this->vehicle->GetOrder(this->OrderGetSel()); assert(order != nullptr); uint value = order->GetConditionValue(); - if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value); + if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value, this->vehicle->type); SetDParam(0, value); ShowQueryString(STR_JUST_INT, STR_ORDER_CONDITIONAL_VALUE_CAPT, 5, this, CS_NUMERAL, QSF_NONE); break; @@ -1337,7 +1337,7 @@ public: switch (this->vehicle->GetOrder(sel)->GetConditionVariable()) { case OCV_MAX_SPEED: - value = ConvertDisplaySpeedToSpeed(value); + value = ConvertDisplaySpeedToSpeed(value, this->vehicle->type); break; case OCV_RELIABILITY: diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -493,7 +493,7 @@ struct BuildRailToolbarWindow : Window { if (rti->max_speed > 0) { SetDParam(0, STR_TOOLBAR_RAILTYPE_VELOCITY); SetDParam(1, rti->strings.toolbar_caption); - SetDParam(2, rti->max_speed); + SetDParam(2, PackVelocity(rti->max_speed, VEH_TRAIN)); } else { SetDParam(0, rti->strings.toolbar_caption); } diff --git a/src/road_gui.cpp b/src/road_gui.cpp --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -411,7 +411,7 @@ struct BuildRoadToolbarWindow : Window { if (this->rti->max_speed > 0) { SetDParam(0, STR_TOOLBAR_RAILTYPE_VELOCITY); SetDParam(1, this->rti->strings.toolbar_caption); - SetDParam(2, this->rti->max_speed / 2); + SetDParam(2, PackVelocity(this->rti->max_speed / 2, VEH_ROAD)); } else { SetDParam(0, this->rti->strings.toolbar_caption); } diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -2877,6 +2877,11 @@ bool AfterLoadGame() _settings_game.locale.units_height = Clamp(_old_units, 0, 2); } + if (IsSavegameVersionBefore(SLV_VELOCITY_NAUTICAL)) { + /* Match nautical velocity with land velocity units. */ + _settings_game.locale.units_velocity_nautical = _settings_game.locale.units_velocity; + } + if (IsSavegameVersionBefore(SLV_186)) { /* Move ObjectType from map to pool */ for (auto t : Map::Iterate()) { diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -347,6 +347,8 @@ enum SaveLoadVersion : uint16 { SLV_NEWGRF_ROAD_STOPS, ///< 303 PR#10144 NewGRF road stops. SLV_LINKGRAPH_EDGES, ///< 304 PR#10314 Explicitly store link graph edges destination, PR#10471 int64 instead of uint64 league rating + SLV_VELOCITY_NAUTICAL, ///< 305 PR#10594 Separation of land and nautical velocity (knots!) + SL_MAX_VERSION, ///< Highest possible saveload version }; diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -1600,6 +1600,7 @@ static SettingsContainer &GetSettingsTre SettingsPage *localisation = main->Add(new SettingsPage(STR_CONFIG_SETTING_LOCALISATION)); { localisation->Add(new SettingEntry("locale.units_velocity")); + localisation->Add(new SettingEntry("locale.units_velocity_nautical")); localisation->Add(new SettingEntry("locale.units_power")); localisation->Add(new SettingEntry("locale.units_weight")); localisation->Add(new SettingEntry("locale.units_volume")); diff --git a/src/settings_type.h b/src/settings_type.h --- a/src/settings_type.h +++ b/src/settings_type.h @@ -234,7 +234,8 @@ struct MusicSettings { /** Settings related to currency/unit systems. */ struct LocaleSettings { byte currency; ///< currency we currently use - byte units_velocity; ///< unit system for velocity + byte units_velocity; ///< unit system for velocity of trains and road vehicles + byte units_velocity_nautical; ///< unit system for velocity of ships and aircraft byte units_power; ///< unit system for power byte units_weight; ///< unit system for weight byte units_volume; ///< unit system for volume diff --git a/src/strings.cpp b/src/strings.cpp --- a/src/strings.cpp +++ b/src/strings.cpp @@ -703,10 +703,11 @@ struct UnitsLong { /** Unit conversions for velocity. */ static const Units _units_velocity[] = { - { { 1, 0}, STR_UNITS_VELOCITY_IMPERIAL, 0 }, - { { 103, 6}, STR_UNITS_VELOCITY_METRIC, 0 }, - { { 1831, 12}, STR_UNITS_VELOCITY_SI, 0 }, - { {37888, 16}, STR_UNITS_VELOCITY_GAMEUNITS, 1 }, + { { 1, 0}, STR_UNITS_VELOCITY_IMPERIAL, 0 }, + { { 103, 6}, STR_UNITS_VELOCITY_METRIC, 0 }, + { { 1831, 12}, STR_UNITS_VELOCITY_SI, 0 }, + { { 37888, 16}, STR_UNITS_VELOCITY_GAMEUNITS, 1 }, + { { 7289499, 23}, STR_UNITS_VELOCITY_KNOTS, 0 }, }; /** Unit conversions for power. */ @@ -758,16 +759,28 @@ static const Units _units_height[] = { }; /** + * Get index for velocity conversion units for a vehicle type. + * @param type VehicleType to convert velocity for. + * @return Index within velocity conversion units for vehicle type. + */ +static byte GetVelocityUnits(VehicleType type) +{ + if (type == VEH_SHIP || type == VEH_AIRCRAFT) return _settings_game.locale.units_velocity_nautical; + + return _settings_game.locale.units_velocity; +} + +/** * Convert the given (internal) speed to the display speed. * @param speed the speed to convert * @return the converted speed. */ -uint ConvertSpeedToDisplaySpeed(uint speed) +uint ConvertSpeedToDisplaySpeed(uint speed, VehicleType type) { /* For historical reasons we don't want to mess with the * conversion for speed. So, don't round it and keep the * original conversion factors instead of the real ones. */ - return _units_velocity[_settings_game.locale.units_velocity].c.ToDisplay(speed, false); + return _units_velocity[GetVelocityUnits(type)].c.ToDisplay(speed, false); } /** @@ -775,9 +788,9 @@ uint ConvertSpeedToDisplaySpeed(uint spe * @param speed the speed to convert * @return the converted speed. */ -uint ConvertDisplaySpeedToSpeed(uint speed) +uint ConvertDisplaySpeedToSpeed(uint speed, VehicleType type) { - return _units_velocity[_settings_game.locale.units_velocity].c.FromDisplay(speed); + return _units_velocity[GetVelocityUnits(type)].c.FromDisplay(speed); } /** @@ -785,9 +798,9 @@ uint ConvertDisplaySpeedToSpeed(uint spe * @param speed the speed to convert * @return the converted speed. */ -uint ConvertKmhishSpeedToDisplaySpeed(uint speed) +uint ConvertKmhishSpeedToDisplaySpeed(uint speed, VehicleType type) { - return _units_velocity[_settings_game.locale.units_velocity].c.ToDisplay(speed * 10, false) / 16; + return _units_velocity[GetVelocityUnits(type)].c.ToDisplay(speed * 10, false) / 16; } /** @@ -795,9 +808,9 @@ uint ConvertKmhishSpeedToDisplaySpeed(ui * @param speed the speed to convert * @return the converted speed. */ -uint ConvertDisplaySpeedToKmhishSpeed(uint speed) +uint ConvertDisplaySpeedToKmhishSpeed(uint speed, VehicleType type) { - return _units_velocity[_settings_game.locale.units_velocity].c.FromDisplay(speed * 16, true, 10); + return _units_velocity[GetVelocityUnits(type)].c.FromDisplay(speed * 16, true, 10); } static std::vector _game_script_raw_strings; @@ -1291,11 +1304,15 @@ static char *FormatString(char *buff, co } case SCC_VELOCITY: { // {VELOCITY} - assert(_settings_game.locale.units_velocity < lengthof(_units_velocity)); - unsigned int decimal_places = _units_velocity[_settings_game.locale.units_velocity].decimal_places; - uint64 args_array[] = {ConvertKmhishSpeedToDisplaySpeed(args->GetInt64(SCC_VELOCITY)), decimal_places}; + int64 arg = args->GetInt64(SCC_VELOCITY); + // Unpack vehicle type from packed argument to get desired units. + VehicleType vt = static_cast(GB(arg, 56, 8)); + byte units = GetVelocityUnits(vt); + assert(units < lengthof(_units_velocity)); + unsigned int decimal_places = _units_velocity[units].decimal_places; + uint64 args_array[] = {ConvertKmhishSpeedToDisplaySpeed(GB(arg, 0, 56), vt), decimal_places}; StringParameters tmp_params(args_array, decimal_places ? 2 : 1, nullptr); - buff = FormatString(buff, GetStringPtr(_units_velocity[_settings_game.locale.units_velocity].s), &tmp_params, last); + buff = FormatString(buff, GetStringPtr(_units_velocity[units].s), &tmp_params, last); break; } diff --git a/src/strings_func.h b/src/strings_func.h --- a/src/strings_func.h +++ b/src/strings_func.h @@ -14,6 +14,7 @@ #include "string_type.h" #include "gfx_type.h" #include "core/bitmath_func.hpp" +#include "vehicle_type.h" /** * Extract the StringTab from a StringID. @@ -174,8 +175,21 @@ std::string GetString(StringID string); char *GetStringWithArgs(char *buffr, StringID string, StringParameters *args, const char *last, uint case_index = 0, bool game_script = false); const char *GetStringPtr(StringID string); -uint ConvertKmhishSpeedToDisplaySpeed(uint speed); -uint ConvertDisplaySpeedToKmhishSpeed(uint speed); +uint ConvertKmhishSpeedToDisplaySpeed(uint speed, VehicleType type); +uint ConvertDisplaySpeedToKmhishSpeed(uint speed, VehicleType type); + +/** + * Pack velocity and vehicle type for use with SCC_VELOCITY string parameter. + * @param speed Display speed for parameter. + * @param type Type of vehicle for parameter. + * @return Bit-packed velocity and vehicle type, for use with SetDParam(). + */ +static inline int64 PackVelocity(uint speed, VehicleType type) +{ + /* Vehicle type is a byte, so packed into the top 8 bits of the 64-bit + * parameter, although only values from 0-3 are relevant. */ + return speed | (static_cast(type) << 56); +} /** * Set a string parameter \a v at index \a n in a given array \a s. diff --git a/src/table/settings/locale_settings.ini b/src/table/settings/locale_settings.ini --- a/src/table/settings/locale_settings.ini +++ b/src/table/settings/locale_settings.ini @@ -73,7 +73,7 @@ type = SLE_UINT8 from = SLV_184 flags = SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN def = 1 -max = 3 +max = 4 full = _locale_units post_cb = [](auto) { MarkWholeScreenDirty(); } cat = SC_BASIC @@ -82,6 +82,20 @@ strhelp = STR_CONFIG_SETTING_LOCALISATI strval = STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_IMPERIAL [SDT_OMANY] +var = locale.units_velocity_nautical +type = SLE_UINT8 +from = SLV_VELOCITY_NAUTICAL +flags = SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN +def = 1 +max = 4 +full = _locale_units +post_cb = [](auto) { MarkWholeScreenDirty(); } +cat = SC_BASIC +str = STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_NAUTICAL +strhelp = STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_HELPTEXT +strval = STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_IMPERIAL + +[SDT_OMANY] var = locale.units_power type = SLE_UINT8 from = SLV_184 diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -408,7 +408,7 @@ struct TimetableWindow : Window { string = order->GetMaxSpeed() != UINT16_MAX ? STR_TIMETABLE_TRAVEL_FOR_SPEED : STR_TIMETABLE_TRAVEL_FOR; } - SetDParam(2, order->GetMaxSpeed()); + SetDParam(2, PackVelocity(order->GetMaxSpeed(), v->type)); DrawString(rtl ? tr.left : middle, rtl ? middle : tr.right, tr.top, string, colour); @@ -568,7 +568,7 @@ struct TimetableWindow : Window { const Order *order = v->GetOrder(real); if (order != nullptr) { if (order->GetMaxSpeed() != UINT16_MAX) { - SetDParam(0, ConvertKmhishSpeedToDisplaySpeed(order->GetMaxSpeed())); + SetDParam(0, ConvertKmhishSpeedToDisplaySpeed(order->GetMaxSpeed(), v->type)); current = STR_JUST_INT; } } @@ -628,7 +628,7 @@ struct TimetableWindow : Window { uint64 val = StrEmpty(str) ? 0 : strtoul(str, nullptr, 10); if (this->query_is_speed_query) { - val = ConvertDisplaySpeedToKmhishSpeed(val); + val = ConvertDisplaySpeedToKmhishSpeed(val, v->type); } else { if (!_settings_client.gui.timetable_in_ticks) val *= DAY_TICKS; } diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -2493,7 +2493,7 @@ struct VehicleDetailsWindow : Window { if (v->type == VEH_TRAIN || (v->type == VEH_ROAD && _settings_game.vehicle.roadveh_acceleration_model != AM_ORIGINAL)) { const GroundVehicleCache *gcache = v->GetGroundVehicleCache(); - SetDParam(2, v->GetDisplayMaxSpeed()); + SetDParam(2, PackVelocity(v->GetDisplayMaxSpeed(), v->type)); SetDParam(1, gcache->cached_power); SetDParam(0, gcache->cached_weight); SetDParam(3, gcache->cached_max_te / 1000); @@ -2504,7 +2504,7 @@ struct VehicleDetailsWindow : Window { string = STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE; } } else { - SetDParam(0, v->GetDisplayMaxSpeed()); + SetDParam(0, PackVelocity(v->GetDisplayMaxSpeed(), v->type)); if (v->type == VEH_AIRCRAFT) { SetDParam(1, v->GetEngine()->GetAircraftTypeText()); if (Aircraft::From(v)->GetRange() > 0) { @@ -2999,7 +2999,7 @@ public: str = STR_VEHICLE_STATUS_STOPPED; } } else { - SetDParam(0, v->GetDisplaySpeed()); + SetDParam(0, PackVelocity(v->GetDisplaySpeed(), v->type)); str = STR_VEHICLE_STATUS_TRAIN_STOPPING_VEL; } } else { // no train @@ -3020,7 +3020,7 @@ public: switch (v->current_order.GetType()) { case OT_GOTO_STATION: { SetDParam(0, v->current_order.GetDestination()); - SetDParam(1, v->GetDisplaySpeed()); + SetDParam(1, PackVelocity(v->GetDisplaySpeed(), v->type)); str = HasBit(v->vehicle_flags, VF_PATHFINDER_LOST) ? STR_VEHICLE_STATUS_CANNOT_REACH_STATION_VEL : STR_VEHICLE_STATUS_HEADING_FOR_STATION_VEL; break; } @@ -3028,7 +3028,7 @@ public: case OT_GOTO_DEPOT: { SetDParam(0, v->type); SetDParam(1, v->current_order.GetDestination()); - SetDParam(2, v->GetDisplaySpeed()); + SetDParam(2, PackVelocity(v->GetDisplaySpeed(), v->type)); if (v->current_order.GetDestination() == INVALID_DEPOT) { /* This case *only* happens when multiple nearest depot orders * follow each other (including an order list only one order: a @@ -3053,7 +3053,7 @@ public: assert(v->type == VEH_TRAIN || v->type == VEH_SHIP); SetDParam(0, v->current_order.GetDestination()); str = HasBit(v->vehicle_flags, VF_PATHFINDER_LOST) ? STR_VEHICLE_STATUS_CANNOT_REACH_WAYPOINT_VEL : STR_VEHICLE_STATUS_HEADING_FOR_WAYPOINT_VEL; - SetDParam(1, v->GetDisplaySpeed()); + SetDParam(1, PackVelocity(v->GetDisplaySpeed(), v->type)); break; } @@ -3066,7 +3066,7 @@ public: default: if (v->GetNumManualOrders() == 0) { str = STR_VEHICLE_STATUS_NO_ORDERS_VEL; - SetDParam(0, v->GetDisplaySpeed()); + SetDParam(0, PackVelocity(v->GetDisplaySpeed(), v->type)); } else { str = STR_EMPTY; }