Changeset - r27050:d85c65824c1e
[Not reviewed]
master
0 17 0
PeterN - 14 months ago 2023-04-08 16:26:13
peter1138@openttd.org
Feature: Separate rail/road and sea/air velocity units, and add knots. (#10594)

This is achieved by packing vehicle type along with the velocity so that
the string system can decode and pick the appropriate unit.
17 files changed with 117 insertions and 60 deletions:
0 comments (0 inline, 0 general)
src/bridge_gui.cpp
Show inline comments
 
@@ -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<VehicleType>(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) {
src/build_vehicle_gui.cpp
Show inline comments
 
@@ -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;
src/engine_gui.cpp
Show inline comments
 
@@ -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());
src/lang/english.txt
Show inline comments
 
@@ -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
src/misc_gui.cpp
Show inline comments
 
@@ -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));
 
		}
 

	
src/order_gui.cpp
Show inline comments
 
@@ -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:
src/rail_gui.cpp
Show inline comments
 
@@ -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);
 
			}
src/road_gui.cpp
Show inline comments
 
@@ -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);
 
			}
src/saveload/afterload.cpp
Show inline comments
 
@@ -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()) {
src/saveload/saveload.h
Show inline comments
 
@@ -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
 
};
 

	
src/settings_gui.cpp
Show inline comments
 
@@ -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"));
src/settings_type.h
Show inline comments
 
@@ -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
src/strings.cpp
Show inline comments
 
@@ -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<const char *> _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<VehicleType>(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;
 
			}
 

	
src/strings_func.h
Show inline comments
 
@@ -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<uint64>(type) << 56);
 
}
 

	
 
/**
 
 * Set a string parameter \a v at index \a n in a given array \a s.
src/table/settings/locale_settings.ini
Show inline comments
 
@@ -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
src/timetable_gui.cpp
Show inline comments
 
@@ -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;
 
		}
src/vehicle_gui.cpp
Show inline comments
 
@@ -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;
 
					}
0 comments (0 inline, 0 general)