Merge branch 'tracerestrict' into tracerestrict-sx
This commit is contained in:
@@ -1287,6 +1287,10 @@ STR_CONFIG_SETTING_POPULATION_IN_LABEL :Show town popul
|
||||
STR_CONFIG_SETTING_POPULATION_IN_LABEL_HELPTEXT :Display the population of towns in their label on the map
|
||||
STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS :Thickness of lines in graphs: {STRING2}
|
||||
STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Width of the line in the graphs. A thin line is more precisely readable, a thicker line is easier to see and colours are easier to distinguish
|
||||
STR_CONFIG_SETTING_SHOW_TRAIN_LENGTH_IN_DETAILS :Show train length in details: {STRING2}
|
||||
STR_CONFIG_SETTING_SHOW_TRAIN_LENGTH_IN_DETAILS_HELPTEXT :Show train length in the vehicle details window
|
||||
STR_CONFIG_SETTING_SHOW_TRAIN_WEIGHT_RATIOS_IN_DETAILS :Show train weight ratios in details: {STRING2}
|
||||
STR_CONFIG_SETTING_SHOW_TRAIN_WEIGHT_RATIOS_IN_DETAILS_HELPTEXT :Show train weight ratios in the vehicle details window
|
||||
STR_CONFIG_SETTING_SHOW_RESTRICTED_SIG_DEF :Show restricted electric signals using default graphics: {STRING2}
|
||||
STR_CONFIG_SETTING_SHOW_RESTRICTED_SIG_DEF_HELPTEXT :Show electric signals with routing restriction programs using the default signal graphics with a blue signal post, instead of using any NewGRF signal graphics. This is to make it easier to visually distinguish restricted signals.
|
||||
|
||||
@@ -2408,8 +2412,8 @@ STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_SPEED :{STRING} {STRIN
|
||||
STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_WEIGHT :{STRING} {STRING} {STRING} {WEIGHT_SHORT} then
|
||||
STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_POWER :{STRING} {STRING} {STRING} {POWER} then
|
||||
STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_FORCE :{STRING} {STRING} {STRING} {FORCE} then
|
||||
STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_POWER_WEIGHT_RATIO :{STRING} {STRING} {STRING} {POWER} / {STRING1} then
|
||||
STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_FORCE_WEIGHT_RATIO :{STRING} {STRING} {STRING} {FORCE} / {STRING1} then
|
||||
STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_POWER_WEIGHT_RATIO :{STRING} {STRING} {STRING} {POWER_WEIGHT_RATIO} then
|
||||
STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_FORCE_WEIGHT_RATIO :{STRING} {STRING} {STRING} {FORCE_WEIGHT_RATIO} then
|
||||
STR_TRACE_RESTRICT_CONDITIONAL_ORDER_STATION :{STRING} {STRING} {STRING} {STATION} then
|
||||
STR_TRACE_RESTRICT_CONDITIONAL_ORDER_WAYPOINT :{STRING} {STRING} {STRING} {WAYPOINT} then
|
||||
STR_TRACE_RESTRICT_CONDITIONAL_ORDER_DEPOT :{STRING} {STRING} {STRING} {DEPOT} then
|
||||
@@ -2471,7 +2475,7 @@ STR_TRACE_RESTRICT_INSTRUCTION_LIST_TOOLTIP :{BLACK}Click an
|
||||
STR_TRACE_RESTRICT_ERROR_CAN_T_INSERT_ITEM :{WHITE}Can't insert instruction
|
||||
STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM :{WHITE}Can't modify instruction
|
||||
STR_TRACE_RESTRICT_ERROR_CAN_T_REMOVE_ITEM :{WHITE}Can't remove instruction
|
||||
STR_TRACE_RESTRICT_ERROR_VALUE_TOO_LARGE :{WHITE}Value too large, maximum is {COMMA}
|
||||
STR_TRACE_RESTRICT_ERROR_VALUE_TOO_LARGE :{WHITE}Value too large, maximum is {DECIMAL}
|
||||
STR_TRACE_RESTRICT_ERROR_NO_PROGRAM :No trace restrict program exists
|
||||
STR_TRACE_RESTRICT_ERROR_OFFSET_TOO_LARGE :Offset too large
|
||||
STR_TRACE_RESTRICT_ERROR_CAN_T_CHANGE_CONDITIONALITY :Can't change conditionality
|
||||
@@ -3776,6 +3780,8 @@ STR_VEHICLE_INFO_MAX_SPEED_RANGE :{BLACK}Max. spe
|
||||
STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Weight: {LTBLUE}{WEIGHT_SHORT} {BLACK}Power: {LTBLUE}{POWER}{BLACK} Max. speed: {LTBLUE}{VELOCITY}
|
||||
STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Weight: {LTBLUE}{WEIGHT_SHORT} {BLACK}Power: {LTBLUE}{POWER}{BLACK} Max. speed: {LTBLUE}{VELOCITY} {BLACK}Max. T.E.: {LTBLUE}{FORCE}
|
||||
|
||||
STR_VEHICLE_INFO_WEIGHT_RATIOS :{BLACK}Power / weight: {LTBLUE}{POWER_WEIGHT_RATIO} {BLACK} Max. T.E / weight: {LTBLUE}{FORCE_WEIGHT_RATIO}
|
||||
|
||||
STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit this year: {LTBLUE}{CURRENCY_LONG} (last year: {CURRENCY_LONG})
|
||||
STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Reliability: {LTBLUE}{COMMA}% {BLACK}Breakdowns since last service: {LTBLUE}{COMMA}
|
||||
|
||||
@@ -5034,6 +5040,7 @@ STR_JUST_CURRENCY_SHORT :{CURRENCY_SHORT
|
||||
STR_JUST_CURRENCY_LONG :{CURRENCY_LONG}
|
||||
STR_JUST_CARGO_LIST :{CARGO_LIST}
|
||||
STR_JUST_INT :{NUM}
|
||||
STR_JUST_DECIMAL :{DECIMAL}
|
||||
STR_JUST_DATE_TINY :{DATE_TINY}
|
||||
STR_JUST_DATE_SHORT :{DATE_SHORT}
|
||||
STR_JUST_DATE_LONG :{DATE_LONG}
|
||||
@@ -5050,6 +5057,7 @@ STR_TINY_COMMA :{TINY_FONT}{COM
|
||||
STR_BLUE_COMMA :{BLUE}{COMMA}
|
||||
STR_RED_COMMA :{RED}{COMMA}
|
||||
STR_WHITE_COMMA :{WHITE}{COMMA}
|
||||
STR_BLACK_DECIMAL :{BLACK}{DECIMAL}
|
||||
STR_TINY_BLACK_DECIMAL :{TINY_FONT}{BLACK}{DECIMAL}
|
||||
STR_COMPANY_MONEY :{WHITE}{CURRENCY_LONG}
|
||||
STR_BLACK_DATE_LONG :{BLACK}{DATE_LONG}
|
||||
|
@@ -1545,6 +1545,7 @@ static SettingsContainer &GetSettingsTree()
|
||||
interface->Add(new SettingEntry("gui.timetable_in_ticks"));
|
||||
interface->Add(new SettingEntry("gui.timetable_arrival_departure"));
|
||||
interface->Add(new SettingEntry("gui.expenses_layout"));
|
||||
interface->Add(new SettingEntry("gui.show_train_weight_ratios_in_details"));
|
||||
}
|
||||
|
||||
SettingsPage *advisors = main->Add(new SettingsPage(STR_CONFIG_SETTING_ADVISORS));
|
||||
|
@@ -135,6 +135,7 @@ struct GUISettings {
|
||||
uint32 last_newgrf_count; ///< the numbers of NewGRFs we found during the last scan
|
||||
byte missing_strings_threshold; ///< the number of missing strings before showing the warning
|
||||
uint8 graph_line_thickness; ///< the thickness of the lines in the various graph guis
|
||||
bool show_train_weight_ratios_in_details; ///< show train weight ratios in vehicle details window top widget
|
||||
bool show_restricted_signal_default; ///< Show restricted electric signals using the default sprite
|
||||
uint8 osk_activation; ///< Mouse gesture to trigger the OSK.
|
||||
|
||||
|
@@ -297,6 +297,54 @@ void str_strip_colours(char *str)
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
/** Scans the string for a wchar and replace it with another wchar
|
||||
* @param str The string buffer
|
||||
* @param last The pointer to the last element of the string buffer
|
||||
* @param find The character to find
|
||||
* @param replace The character to replace, may be 0 to not insert any character
|
||||
* @return The pointer to the terminating null-character in the string buffer
|
||||
*/
|
||||
char *str_replace_wchar(char *str, const char *last, WChar find, WChar replace)
|
||||
{
|
||||
char *dst = str;
|
||||
|
||||
while (str <= last && *str != '\0') {
|
||||
size_t len = Utf8EncodedCharLen(*str);
|
||||
/* If the character is unknown, i.e. encoded length is 0
|
||||
* we assume worst case for the length check.
|
||||
* The length check is needed to prevent Utf8Decode to read
|
||||
* over the terminating '\0' if that happens to be placed
|
||||
* within the encoding of an UTF8 character. */
|
||||
if ((len == 0 && str + 4 > last) || str + len > last) break;
|
||||
|
||||
WChar c;
|
||||
len = Utf8Decode(&c, str);
|
||||
/* It's possible to encode the string termination character
|
||||
* into a multiple bytes. This prevents those termination
|
||||
* characters to be skipped */
|
||||
if (c == '\0') break;
|
||||
|
||||
if (c != find) {
|
||||
/* Copy the character back. Even if dst is current the same as str
|
||||
* (i.e. no characters have been changed) this is quicker than
|
||||
* moving the pointers ahead by len */
|
||||
if (dst + len > last) break;
|
||||
do {
|
||||
*dst++ = *str++;
|
||||
} while (--len != 0);
|
||||
} else {
|
||||
str += len;
|
||||
if (replace) {
|
||||
len = Utf8EncodedCharLen(replace);
|
||||
if (dst + len > last) break;
|
||||
dst += Utf8Encode(dst, replace);
|
||||
}
|
||||
}
|
||||
}
|
||||
*dst = '\0';
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length of an UTF-8 encoded string in number of characters
|
||||
* and thus not the number of bytes that the encoded string contains.
|
||||
@@ -343,9 +391,17 @@ bool strtolower(char *str)
|
||||
*/
|
||||
bool IsValidChar(WChar key, CharSetFilter afilter)
|
||||
{
|
||||
#if !defined(STRGEN) && !defined(SETTINGSGEN)
|
||||
extern WChar GetDecimalSeparatorChar();
|
||||
#endif
|
||||
switch (afilter) {
|
||||
case CS_ALPHANUMERAL: return IsPrintable(key);
|
||||
case CS_NUMERAL: return (key >= '0' && key <= '9');
|
||||
#if !defined(STRGEN) && !defined(SETTINGSGEN)
|
||||
case CS_NUMERAL_DECIMAL: return (key >= '0' && key <= '9') || key == '.' || key == GetDecimalSeparatorChar();
|
||||
#else
|
||||
case CS_NUMERAL_DECIMAL: return (key >= '0' && key <= '9') || key == '.';
|
||||
#endif
|
||||
case CS_NUMERAL_SPACE: return (key >= '0' && key <= '9') || key == ' ';
|
||||
case CS_ALPHA: return IsPrintable(key) && !(key >= '0' && key <= '9');
|
||||
case CS_HEXADECIMAL: return (key >= '0' && key <= '9') || (key >= 'a' && key <= 'f') || (key >= 'A' && key <= 'F');
|
||||
|
@@ -46,6 +46,7 @@ void ValidateString(const char *str);
|
||||
|
||||
void str_fix_scc_encoded(char *str, const char *last);
|
||||
void str_strip_colours(char *str);
|
||||
char *str_replace_wchar(char *str, const char *last, WChar find, WChar replace);
|
||||
bool strtolower(char *str);
|
||||
|
||||
bool StrValid(const char *str, const char *last);
|
||||
|
@@ -26,6 +26,7 @@
|
||||
enum CharSetFilter {
|
||||
CS_ALPHANUMERAL, ///< Both numeric and alphabetic and spaces and stuff
|
||||
CS_NUMERAL, ///< Only numeric ones
|
||||
CS_NUMERAL_DECIMAL, ///< Only numeric and decimal separaters
|
||||
CS_NUMERAL_SPACE, ///< Only numbers and spaces
|
||||
CS_ALPHA, ///< Only alphabetic values
|
||||
CS_HEXADECIMAL, ///< Only hexadecimal characters
|
||||
|
119
src/strings.cpp
119
src/strings.cpp
@@ -366,6 +366,15 @@ static char *FormatHexNumber(char *buff, uint64 number, const char *last)
|
||||
return buff + seprintf(buff, last, "0x" OTTD_PRINTFHEX64, number);
|
||||
}
|
||||
|
||||
WChar GetDecimalSeparatorChar()
|
||||
{
|
||||
WChar decimal_char = '.';
|
||||
const char *decimal_separator = _settings_game.locale.digit_decimal_separator;
|
||||
if (decimal_separator == NULL) decimal_separator = _langpack->digit_decimal_separator;
|
||||
if (decimal_separator != NULL) Utf8Decode(&decimal_char, decimal_separator);
|
||||
return decimal_char;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a given number as a number of bytes with the SI prefix.
|
||||
* @param buff the buffer to write to
|
||||
@@ -821,6 +830,100 @@ uint ConvertDisplayForceToForce(uint force)
|
||||
return _units_force[_settings_game.locale.units_force].c.FromDisplay(force);
|
||||
}
|
||||
|
||||
static void ConvertWeightRatioToDisplay(const Units &unit, uint ratio, int64 &value, int64 &decimals)
|
||||
{
|
||||
int64 input = ratio * 100;
|
||||
decimals = 2;
|
||||
if (_settings_game.locale.units_weight == 2) {
|
||||
input *= 1000;
|
||||
decimals += 3;
|
||||
}
|
||||
|
||||
const UnitConversion &weight_conv = _units_weight[_settings_game.locale.units_weight].c;
|
||||
UnitConversion conv = unit.c;
|
||||
conv.multiplier <<= weight_conv.shift;
|
||||
|
||||
value = conv.ToDisplay(input) / (100 * weight_conv.multiplier);
|
||||
|
||||
if (unit.c.multiplier >> unit.c.shift > 100) {
|
||||
value /= 100;
|
||||
decimals -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
static uint ConvertDisplayToWeightRatio(const Units &unit, double in)
|
||||
{
|
||||
const UnitConversion &weight_conv = _units_weight[_settings_game.locale.units_weight].c;
|
||||
UnitConversion conv = unit.c;
|
||||
conv.multiplier <<= weight_conv.shift;
|
||||
int64 multiplier = _settings_game.locale.units_weight == 2 ? 1000 : 1;
|
||||
|
||||
return conv.FromDisplay(in * 100 * multiplier * weight_conv.multiplier, true, multiplier);
|
||||
}
|
||||
|
||||
static char *FormatUnitWeightRatio(char *buff, const char *last, const Units &unit, int64 raw_value)
|
||||
{
|
||||
const char *unit_str = GetStringPtr(unit.s);
|
||||
const char *weight_str = GetStringPtr(_units_weight[_settings_game.locale.units_weight].s);
|
||||
|
||||
char tmp_buffer[32];
|
||||
strecpy(tmp_buffer, unit_str, lastof(tmp_buffer));
|
||||
char *insert_pt = str_replace_wchar(tmp_buffer, lastof(tmp_buffer), SCC_COMMA, SCC_DECIMAL);
|
||||
strecpy(insert_pt, weight_str, lastof(tmp_buffer));
|
||||
str_replace_wchar(insert_pt, lastof(tmp_buffer), SCC_COMMA, '/');
|
||||
str_replace_wchar(insert_pt, lastof(tmp_buffer), 0xA0 /* NBSP */, 0);
|
||||
|
||||
int64 value, decimals;
|
||||
ConvertWeightRatioToDisplay(unit, raw_value, value, decimals);
|
||||
|
||||
int64 args_array[2] = { value, decimals };
|
||||
StringParameters tmp_params(args_array);
|
||||
buff = FormatString(buff, tmp_buffer, &tmp_params, last);
|
||||
return buff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given internal power / weight ratio to the display decimal.
|
||||
* @param ratio the power / weight ratio to convert
|
||||
* @param value the output value
|
||||
* @param decimals the output decimal offset
|
||||
*/
|
||||
void ConvertPowerWeightRatioToDisplay(uint ratio, int64 &value, int64 &decimals)
|
||||
{
|
||||
ConvertWeightRatioToDisplay(_units_power[_settings_game.locale.units_power], ratio, value, decimals);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given internal force / weight ratio to the display decimal.
|
||||
* @param ratio the force / weight ratio to convert
|
||||
* @param value the output value
|
||||
* @param decimals the output decimal offset
|
||||
*/
|
||||
void ConvertForceWeightRatioToDisplay(uint ratio, int64 &value, int64 &decimals)
|
||||
{
|
||||
ConvertWeightRatioToDisplay(_units_force[_settings_game.locale.units_force], ratio, value, decimals);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given display value to the internal power / weight ratio.
|
||||
* @param in the display value
|
||||
* @return the converted power / weight ratio.
|
||||
*/
|
||||
uint ConvertDisplayToPowerWeightRatio(double in)
|
||||
{
|
||||
return ConvertDisplayToWeightRatio(_units_power[_settings_game.locale.units_power], in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given display value to the internal force / weight ratio.
|
||||
* @param in the display value
|
||||
* @return the converted force / weight ratio.
|
||||
*/
|
||||
uint ConvertDisplayToForceWeightRatio(double in)
|
||||
{
|
||||
return ConvertDisplayToWeightRatio(_units_force[_settings_game.locale.units_force], in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse most format codes within a string and write the result to a buffer.
|
||||
* @param buff The buffer to write the final string to.
|
||||
@@ -1332,6 +1435,22 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg
|
||||
break;
|
||||
}
|
||||
|
||||
case SCC_POWER_WEIGHT_RATIO: { // {POWER_WEIGHT_RATIO}
|
||||
assert(_settings_game.locale.units_power < lengthof(_units_power));
|
||||
assert(_settings_game.locale.units_weight < lengthof(_units_weight));
|
||||
|
||||
buff = FormatUnitWeightRatio(buff, last, _units_power[_settings_game.locale.units_power], args->GetInt64());
|
||||
break;
|
||||
}
|
||||
|
||||
case SCC_FORCE_WEIGHT_RATIO: { // {FORCE_WEIGHT_RATIO}
|
||||
assert(_settings_game.locale.units_force < lengthof(_units_force));
|
||||
assert(_settings_game.locale.units_weight < lengthof(_units_weight));
|
||||
|
||||
buff = FormatUnitWeightRatio(buff, last, _units_force[_settings_game.locale.units_force], args->GetInt64());
|
||||
break;
|
||||
}
|
||||
|
||||
case SCC_COMPANY_NAME: { // {COMPANY}
|
||||
const Company *c = Company::GetIfValid(args->GetInt32());
|
||||
if (c == NULL) break;
|
||||
|
@@ -139,6 +139,8 @@ uint ConvertDisplaySpeedToKmhishSpeed(uint speed);
|
||||
|
||||
void InjectDParam(uint amount);
|
||||
|
||||
WChar GetDecimalSeparatorChar();
|
||||
|
||||
/**
|
||||
* Set a string parameter \a v at index \a n in a given array \a s.
|
||||
* @param s Array of string parameters.
|
||||
|
@@ -62,6 +62,9 @@ enum StringControlCode {
|
||||
SCC_VELOCITY,
|
||||
SCC_HEIGHT,
|
||||
|
||||
SCC_POWER_WEIGHT_RATIO,
|
||||
SCC_FORCE_WEIGHT_RATIO,
|
||||
|
||||
SCC_DATE_TINY,
|
||||
SCC_DATE_SHORT,
|
||||
SCC_DATE_LONG,
|
||||
|
@@ -3135,6 +3135,15 @@ strhelp = STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT
|
||||
strval = STR_JUST_COMMA
|
||||
proc = RedrawScreen
|
||||
|
||||
[SDTC_BOOL]
|
||||
var = gui.show_train_weight_ratios_in_details
|
||||
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
|
||||
def = false
|
||||
str = STR_CONFIG_SETTING_SHOW_TRAIN_WEIGHT_RATIOS_IN_DETAILS
|
||||
strhelp = STR_CONFIG_SETTING_SHOW_TRAIN_WEIGHT_RATIOS_IN_DETAILS_HELPTEXT
|
||||
proc = RedrawScreen
|
||||
cat = SC_EXPERT
|
||||
|
||||
[SDTC_BOOL]
|
||||
var = gui.show_restricted_signal_default
|
||||
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
|
||||
|
@@ -83,6 +83,8 @@ static const CmdStruct _cmd_structs[] = {
|
||||
{"FORCE", EmitSingleChar, SCC_FORCE, 1, 0, C_NONE},
|
||||
{"VELOCITY", EmitSingleChar, SCC_VELOCITY, 1, 0, C_NONE},
|
||||
{"HEIGHT", EmitSingleChar, SCC_HEIGHT, 1, 0, C_NONE},
|
||||
{"POWER_WEIGHT_RATIO",EmitSingleChar, SCC_POWER_WEIGHT_RATIO, 1, 0, C_NONE},
|
||||
{"FORCE_WEIGHT_RATIO",EmitSingleChar, SCC_FORCE_WEIGHT_RATIO, 1, 0, C_NONE},
|
||||
|
||||
{"P", EmitPlural, 0, 0, -1, C_DONTCOUNT}, // plural specifier
|
||||
{"G", EmitGender, 0, 0, -1, C_DONTCOUNT}, // gender specifier
|
||||
|
@@ -56,6 +56,7 @@ enum TraceRestrictWindowWidgets {
|
||||
TR_WIDGET_CONDFLAGS,
|
||||
TR_WIDGET_COMPARATOR,
|
||||
TR_WIDGET_VALUE_INT,
|
||||
TR_WIDGET_VALUE_DECIMAL,
|
||||
TR_WIDGET_VALUE_DROPDOWN,
|
||||
TR_WIDGET_VALUE_DEST,
|
||||
TR_WIDGET_VALUE_SIGNAL,
|
||||
@@ -91,6 +92,7 @@ enum PanelWidgets {
|
||||
|
||||
// Right
|
||||
DPR_VALUE_INT = 0,
|
||||
DPR_VALUE_DECIMAL,
|
||||
DPR_VALUE_DROPDOWN,
|
||||
DPR_VALUE_DEST,
|
||||
DPR_VALUE_SIGNAL,
|
||||
@@ -475,6 +477,19 @@ static bool IsIntegerValueType(TraceRestrictValueType type)
|
||||
case TRVT_WEIGHT:
|
||||
case TRVT_POWER:
|
||||
case TRVT_FORCE:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if item type field @p type is a decimal value type
|
||||
*/
|
||||
static bool IsDecimalValueType(TraceRestrictValueType type)
|
||||
{
|
||||
switch (type) {
|
||||
case TRVT_POWER_WEIGHT_RATIO:
|
||||
case TRVT_FORCE_WEIGHT_RATIO:
|
||||
return true;
|
||||
@@ -516,20 +531,47 @@ static uint ConvertIntegerValue(TraceRestrictValueType type, uint in, bool to_di
|
||||
: ConvertDisplayForceToForce(in);
|
||||
break;
|
||||
|
||||
case TRVT_PF_PENALTY:
|
||||
return in;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert integer values to decimal display units
|
||||
*/
|
||||
static void ConvertValueToDecimal(TraceRestrictValueType type, uint in, int64 &value, int64 &decimal)
|
||||
{
|
||||
switch (type) {
|
||||
case TRVT_POWER_WEIGHT_RATIO:
|
||||
return to_display
|
||||
? ConvertPowerToDisplayPower(in) * 10
|
||||
: ConvertDisplayPowerToPower(in) / 10;
|
||||
ConvertPowerWeightRatioToDisplay(in, value, decimal);
|
||||
break;
|
||||
|
||||
case TRVT_FORCE_WEIGHT_RATIO:
|
||||
return to_display
|
||||
? ConvertForceToDisplayForce(in) * 10
|
||||
: ConvertDisplayForceToForce(in) / 10;
|
||||
ConvertForceWeightRatioToDisplay(in, value, decimal);
|
||||
break;
|
||||
|
||||
case TRVT_PF_PENALTY:
|
||||
return in;
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert decimal (double) display units to integer values
|
||||
*/
|
||||
static uint ConvertDecimalToValue(TraceRestrictValueType type, double in)
|
||||
{
|
||||
switch (type) {
|
||||
case TRVT_POWER_WEIGHT_RATIO:
|
||||
return ConvertDisplayToPowerWeightRatio(in);
|
||||
break;
|
||||
|
||||
case TRVT_FORCE_WEIGHT_RATIO:
|
||||
return ConvertDisplayToForceWeightRatio(in);
|
||||
break;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
@@ -773,15 +815,11 @@ static void DrawInstructionString(const TraceRestrictProgram *prog, TraceRestric
|
||||
case TRVT_POWER_WEIGHT_RATIO:
|
||||
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_POWER_WEIGHT_RATIO;
|
||||
DrawInstructionStringConditionalIntegerCommon(item, properties);
|
||||
SetDParam(4, STR_UNITS_WEIGHT_LONG_METRIC);
|
||||
SetDParam(5, 100);
|
||||
break;
|
||||
|
||||
case TRVT_FORCE_WEIGHT_RATIO:
|
||||
instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_FORCE_WEIGHT_RATIO;
|
||||
DrawInstructionStringConditionalIntegerCommon(item, properties);
|
||||
SetDParam(4, STR_UNITS_WEIGHT_LONG_METRIC);
|
||||
SetDParam(5, 100);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1021,6 +1059,22 @@ public:
|
||||
break;
|
||||
}
|
||||
|
||||
case TR_WIDGET_VALUE_DECIMAL: {
|
||||
TraceRestrictItem item = this->GetSelected();
|
||||
TraceRestrictValueType type = GetTraceRestrictTypeProperties(item).value_type;
|
||||
if (IsDecimalValueType(type)) {
|
||||
int64 value, decimal;
|
||||
ConvertValueToDecimal(type, GetTraceRestrictValue(item), value, decimal);
|
||||
SetDParam(0, value);
|
||||
SetDParam(1, decimal);
|
||||
char *saved = _settings_game.locale.digit_group_separator;
|
||||
_settings_game.locale.digit_group_separator = const_cast<char*>("");
|
||||
ShowQueryString(STR_JUST_DECIMAL, STR_TRACE_RESTRICT_VALUE_CAPTION, 16, this, CS_NUMERAL_DECIMAL, QSF_NONE);
|
||||
_settings_game.locale.digit_group_separator = saved;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TR_WIDGET_VALUE_DROPDOWN: {
|
||||
TraceRestrictItem item = this->GetSelected();
|
||||
switch (GetTraceRestrictTypeProperties(item).value_type) {
|
||||
@@ -1100,19 +1154,35 @@ public:
|
||||
|
||||
TraceRestrictItem item = GetSelected();
|
||||
TraceRestrictValueType type = GetTraceRestrictTypeProperties(item).value_type;
|
||||
if (!IsIntegerValueType(type) && type != TRVT_PF_PENALTY) {
|
||||
return;
|
||||
}
|
||||
uint value;
|
||||
|
||||
uint value = ConvertIntegerValue(type, atoi(str), false);
|
||||
if (value >= (1 << TRIFA_VALUE_COUNT)) {
|
||||
SetDParam(0, ConvertIntegerValue(type, (1 << TRIFA_VALUE_COUNT) - 1, true));
|
||||
ShowErrorMessage(STR_TRACE_RESTRICT_ERROR_VALUE_TOO_LARGE, STR_EMPTY, WL_INFO);
|
||||
return;
|
||||
}
|
||||
if (IsIntegerValueType(type) || type == TRVT_PF_PENALTY) {
|
||||
value = ConvertIntegerValue(type, atoi(str), false);
|
||||
if (value >= (1 << TRIFA_VALUE_COUNT)) {
|
||||
SetDParam(0, ConvertIntegerValue(type, (1 << TRIFA_VALUE_COUNT) - 1, true));
|
||||
SetDParam(1, 0);
|
||||
ShowErrorMessage(STR_TRACE_RESTRICT_ERROR_VALUE_TOO_LARGE, STR_EMPTY, WL_INFO);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == TRVT_PF_PENALTY) {
|
||||
SetTraceRestrictAuxField(item, TRPPAF_VALUE);
|
||||
if (type == TRVT_PF_PENALTY) {
|
||||
SetTraceRestrictAuxField(item, TRPPAF_VALUE);
|
||||
}
|
||||
} else if (IsDecimalValueType(type)) {
|
||||
char tmp_buffer[32];
|
||||
strecpy(tmp_buffer, str, lastof(tmp_buffer));
|
||||
str_replace_wchar(tmp_buffer, lastof(tmp_buffer), GetDecimalSeparatorChar(), '.');
|
||||
value = ConvertDecimalToValue(type, atof(tmp_buffer));
|
||||
if (value >= (1 << TRIFA_VALUE_COUNT)) {
|
||||
int64 value, decimal;
|
||||
ConvertValueToDecimal(type, (1 << TRIFA_VALUE_COUNT) - 1, value, decimal);
|
||||
SetDParam(0, value);
|
||||
SetDParam(1, decimal);
|
||||
ShowErrorMessage(STR_TRACE_RESTRICT_ERROR_VALUE_TOO_LARGE, STR_EMPTY, WL_INFO);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
SetTraceRestrictValue(item, value);
|
||||
@@ -1444,6 +1514,20 @@ public:
|
||||
break;
|
||||
}
|
||||
|
||||
case TR_WIDGET_VALUE_DECIMAL: {
|
||||
SetDParam(0, 0);
|
||||
SetDParam(1, 0);
|
||||
TraceRestrictItem item = this->GetSelected();
|
||||
TraceRestrictValueType type = GetTraceRestrictTypeProperties(item).value_type;
|
||||
if (IsDecimalValueType(type)) {
|
||||
int64 value, decimal;
|
||||
ConvertValueToDecimal(type, GetTraceRestrictValue(item), value, decimal);
|
||||
SetDParam(0, value);
|
||||
SetDParam(1, decimal);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TR_WIDGET_CAPTION: {
|
||||
const TraceRestrictProgram *prog = this->GetProgram();
|
||||
if (prog) {
|
||||
@@ -1603,6 +1687,7 @@ private:
|
||||
this->RaiseWidget(TR_WIDGET_CONDFLAGS);
|
||||
this->RaiseWidget(TR_WIDGET_COMPARATOR);
|
||||
this->RaiseWidget(TR_WIDGET_VALUE_INT);
|
||||
this->RaiseWidget(TR_WIDGET_VALUE_DECIMAL);
|
||||
this->RaiseWidget(TR_WIDGET_VALUE_DROPDOWN);
|
||||
this->RaiseWidget(TR_WIDGET_VALUE_DEST);
|
||||
this->RaiseWidget(TR_WIDGET_VALUE_SIGNAL);
|
||||
@@ -1618,6 +1703,7 @@ private:
|
||||
this->DisableWidget(TR_WIDGET_CONDFLAGS);
|
||||
this->DisableWidget(TR_WIDGET_COMPARATOR);
|
||||
this->DisableWidget(TR_WIDGET_VALUE_INT);
|
||||
this->DisableWidget(TR_WIDGET_VALUE_DECIMAL);
|
||||
this->DisableWidget(TR_WIDGET_VALUE_DROPDOWN);
|
||||
this->DisableWidget(TR_WIDGET_VALUE_DEST);
|
||||
this->DisableWidget(TR_WIDGET_VALUE_SIGNAL);
|
||||
@@ -1753,6 +1839,9 @@ private:
|
||||
if (IsIntegerValueType(properties.value_type)) {
|
||||
right_sel->SetDisplayedPlane(DPR_VALUE_INT);
|
||||
this->EnableWidget(TR_WIDGET_VALUE_INT);
|
||||
} else if(IsDecimalValueType(properties.value_type)) {
|
||||
right_sel->SetDisplayedPlane(DPR_VALUE_DECIMAL);
|
||||
this->EnableWidget(TR_WIDGET_VALUE_DECIMAL);
|
||||
} else {
|
||||
switch (properties.value_type) {
|
||||
case TRVT_DENY:
|
||||
@@ -1965,6 +2054,8 @@ static const NWidgetPart _nested_program_widgets[] = {
|
||||
NWidget(NWID_SELECTION, INVALID_COLOUR, TR_WIDGET_SEL_TOP_RIGHT),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_VALUE_INT), SetMinimalSize(124, 12), SetFill(1, 0),
|
||||
SetDataTip(STR_BLACK_COMMA, STR_TRACE_RESTRICT_COND_VALUE_TOOLTIP), SetResize(1, 0),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_VALUE_DECIMAL), SetMinimalSize(124, 12), SetFill(1, 0),
|
||||
SetDataTip(STR_BLACK_DECIMAL, STR_TRACE_RESTRICT_COND_VALUE_TOOLTIP), SetResize(1, 0),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_GREY, TR_WIDGET_VALUE_DROPDOWN), SetMinimalSize(124, 12), SetFill(1, 0),
|
||||
SetDataTip(STR_NULL, STR_TRACE_RESTRICT_COND_VALUE_TOOLTIP), SetResize(1, 0),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_VALUE_DEST), SetMinimalSize(124, 12), SetFill(1, 0),
|
||||
|
@@ -17,3 +17,7 @@ uint ConvertPowerToDisplayPower(uint power);
|
||||
uint ConvertDisplayPowerToPower(uint power);
|
||||
uint ConvertForceToDisplayForce(uint force);
|
||||
uint ConvertDisplayForceToForce(uint force);
|
||||
void ConvertPowerWeightRatioToDisplay(uint ratio, int64 &value, int64 &decimals);
|
||||
void ConvertForceWeightRatioToDisplay(uint ratio, int64 &value, int64 &decimals);
|
||||
uint ConvertDisplayToPowerWeightRatio(double in);
|
||||
uint ConvertDisplayToForceWeightRatio(double in);
|
||||
|
@@ -1866,6 +1866,7 @@ static StringID _service_interval_dropdown[] = {
|
||||
struct VehicleDetailsWindow : Window {
|
||||
TrainDetailsWindowTabs tab; ///< For train vehicles: which tab is displayed.
|
||||
Scrollbar *vscroll;
|
||||
bool vehicle_weight_ratio_line_shown;
|
||||
|
||||
/** Initialize a newly created vehicle details window */
|
||||
VehicleDetailsWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc)
|
||||
@@ -1927,12 +1928,21 @@ struct VehicleDetailsWindow : Window {
|
||||
return desired_height;
|
||||
}
|
||||
|
||||
bool ShouldShowWeightRatioLine(const Vehicle *v) const
|
||||
{
|
||||
return (v->type == VEH_TRAIN && _settings_client.gui.show_train_weight_ratios_in_details);
|
||||
}
|
||||
|
||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_VD_TOP_DETAILS: {
|
||||
const Vehicle *v = Vehicle::Get(this->window_number);
|
||||
Dimension dim = { 0, 0 };
|
||||
size->height = WD_FRAMERECT_TOP + 4 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM;
|
||||
this->vehicle_weight_ratio_line_shown = ShouldShowWeightRatioLine(v);
|
||||
int lines = 4;
|
||||
if (this->vehicle_weight_ratio_line_shown) lines++;
|
||||
size->height = WD_FRAMERECT_TOP + lines * FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM;
|
||||
|
||||
for (uint i = 0; i < 4; i++) SetDParamMaxValue(i, INT16_MAX);
|
||||
static const StringID info_strings[] = {
|
||||
@@ -1945,6 +1955,11 @@ struct VehicleDetailsWindow : Window {
|
||||
for (uint i = 0; i < lengthof(info_strings); i++) {
|
||||
dim = maxdim(dim, GetStringBoundingBox(info_strings[i]));
|
||||
}
|
||||
if (this->vehicle_weight_ratio_line_shown) {
|
||||
SetDParamMaxValue(0, 1 << 16);
|
||||
SetDParamMaxValue(1, 1 << 16);
|
||||
dim = maxdim(dim, GetStringBoundingBox(STR_VEHICLE_INFO_WEIGHT_RATIOS));
|
||||
}
|
||||
SetDParam(0, STR_VEHICLE_INFO_AGE);
|
||||
dim = maxdim(dim, GetStringBoundingBox(STR_VEHICLE_INFO_AGE_RUNNING_COST_YR));
|
||||
size->width = dim.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
|
||||
@@ -2079,6 +2094,14 @@ struct VehicleDetailsWindow : Window {
|
||||
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, string);
|
||||
y += FONT_HEIGHT_NORMAL;
|
||||
|
||||
bool should_show_weight_ratio = this->ShouldShowWeightRatioLine(v);
|
||||
if (should_show_weight_ratio) {
|
||||
SetDParam(0, (100 * Train::From(v)->gcache.cached_power) / max<uint>(1, Train::From(v)->gcache.cached_weight));
|
||||
SetDParam(1, (Train::From(v)->gcache.cached_max_te / 10) / max<uint>(1, Train::From(v)->gcache.cached_weight));
|
||||
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_WEIGHT_RATIOS);
|
||||
y += FONT_HEIGHT_NORMAL;
|
||||
}
|
||||
|
||||
/* Draw profit */
|
||||
SetDParam(0, v->GetDisplayProfitThisYear());
|
||||
SetDParam(1, v->GetDisplayProfitLastYear());
|
||||
@@ -2089,6 +2112,10 @@ struct VehicleDetailsWindow : Window {
|
||||
SetDParam(0, ToPercent16(v->reliability));
|
||||
SetDParam(1, v->breakdowns_since_last_service);
|
||||
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS);
|
||||
|
||||
if (this->vehicle_weight_ratio_line_shown != should_show_weight_ratio) {
|
||||
const_cast<VehicleDetailsWindow *>(this)->ReInit();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user