diff --git a/src/lang/english.txt b/src/lang/english.txt index d8e1031e64..147ababafe 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -2399,6 +2399,8 @@ STR_TRACE_RESTRICT_VARIABLE_TRAIN_GROUP :train group STR_TRACE_RESTRICT_VARIABLE_TRAIN_WEIGHT :weight STR_TRACE_RESTRICT_VARIABLE_TRAIN_POWER :power STR_TRACE_RESTRICT_VARIABLE_TRAIN_MAX_TE :max T.E. +STR_TRACE_RESTRICT_VARIABLE_TRAIN_POWER_WEIGHT_RATIO :power / weight ratio +STR_TRACE_RESTRICT_VARIABLE_TRAIN_MAX_TE_WEIGHT_RATIO :max T.E. / weight ratio STR_TRACE_RESTRICT_VARIABLE_UNDEFINED :undefined STR_TRACE_RESTRICT_VARIABLE_UNDEFINED_RED :{RED}undefined STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_INTEGER :{STRING} {STRING} {STRING} {COMMA} then @@ -2406,6 +2408,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_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 diff --git a/src/tracerestrict.cpp b/src/tracerestrict.cpp index cdff1f809f..8e70ed6d56 100644 --- a/src/tracerestrict.cpp +++ b/src/tracerestrict.cpp @@ -370,6 +370,23 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp break; } + case TRIT_COND_PHYS_RATIO: { + switch (static_cast(GetTraceRestrictAuxField(item))) { + case TRPPRCAF_POWER_WEIGHT: + result = TestCondition(min(UINT16_MAX, (100 * v->gcache.cached_power) / max(1, v->gcache.cached_weight)), condop, condvalue); + break; + + case TRPPRCAF_MAX_TE_WEIGHT: + result = TestCondition(min(UINT16_MAX, (v->gcache.cached_max_te / 10) / max(1, v->gcache.cached_weight)), condop, condvalue); + break; + + default: + NOT_REACHED(); + break; + } + break; + } + default: NOT_REACHED(); } @@ -508,6 +525,7 @@ CommandCost TraceRestrictProgram::Validate(const std::vector case TRIT_COND_PBS_ENTRY_SIGNAL: case TRIT_COND_TRAIN_GROUP: case TRIT_COND_PHYS_PROP: + case TRIT_COND_PHYS_RATIO: break; default: @@ -584,8 +602,12 @@ void SetTraceRestrictValueDefault(TraceRestrictItem &item, TraceRestrictValueTyp case TRVT_WEIGHT: case TRVT_POWER: case TRVT_FORCE: + case TRVT_POWER_WEIGHT_RATIO: + case TRVT_FORCE_WEIGHT_RATIO: SetTraceRestrictValue(item, 0); - SetTraceRestrictAuxField(item, 0); + if (!IsTraceRestrictTypeAuxSubtype(GetTraceRestrictType(item))) { + SetTraceRestrictAuxField(item, 0); + } break; case TRVT_ORDER: @@ -633,10 +655,8 @@ void SetTraceRestrictTypeAndNormalise(TraceRestrictItem &item, TraceRestrictItem TraceRestrictTypePropertySet old_properties = GetTraceRestrictTypeProperties(item); SetTraceRestrictType(item, type); - bool set_aux_field = false; - if (type == TRIT_COND_PHYS_PROP) { + if (IsTraceRestrictTypeAuxSubtype(type)) { SetTraceRestrictAuxField(item, aux_data); - set_aux_field = true; } else { assert(aux_data == 0); } @@ -646,9 +666,6 @@ void SetTraceRestrictTypeAndNormalise(TraceRestrictItem &item, TraceRestrictItem old_properties.value_type != new_properties.value_type) { SetTraceRestrictCondOp(item, TRCO_IS); SetTraceRestrictValueDefault(item, new_properties.value_type); - if (set_aux_field) { - SetTraceRestrictAuxField(item, aux_data); - } } if (GetTraceRestrictType(item) == TRIT_COND_LAST_STATION && GetTraceRestrictAuxField(item) != TROCAF_STATION) { // if changing type from another order type to last visited station, reset value if not currently a station diff --git a/src/tracerestrict.h b/src/tracerestrict.h index f6e92cd87e..03a0b85a31 100644 --- a/src/tracerestrict.h +++ b/src/tracerestrict.h @@ -114,6 +114,7 @@ enum TraceRestrictItemType { TRIT_COND_PBS_ENTRY_SIGNAL = 17, ///< Test tile and PBS-state of previous signal TRIT_COND_TRAIN_GROUP = 18, ///< Test train group membership TRIT_COND_PHYS_PROP = 19, ///< Test train physical property + TRIT_COND_PHYS_RATIO = 20, ///< Test train physical property ratio //TRIT_COND_TRAIN_OWNER = 24, ///< Test train owner: reserved for future use /* space up to 31 */ }; @@ -183,6 +184,15 @@ enum TraceRestrictPhysPropCondAuxField { /* space up to 3 */ }; +/** + * TraceRestrictItem auxiliary type field, for physical property ratio type conditionals + */ +enum TraceRestrictPhysPropRatioCondAuxField { + TRPPRCAF_POWER_WEIGHT = 0, ///< value field is a 100 * power / weight ratio + TRPPRCAF_MAX_TE_WEIGHT = 1, ///< value field is a 100 * tractive effort / weight ratio + /* space up to 3 */ +}; + /** * TraceRestrictItem auxiliary type field, for order type conditionals */ @@ -428,6 +438,8 @@ enum TraceRestrictValueType { TRVT_WEIGHT = 13,///< takes a weight TRVT_POWER = 14,///< takes a power TRVT_FORCE = 15,///< takes a force + TRVT_POWER_WEIGHT_RATIO = 16,///< takes a power / weight ratio, * 100 + TRVT_FORCE_WEIGHT_RATIO = 17,///< takes a force / weight ratio, * 100 }; /** @@ -514,6 +526,22 @@ static inline TraceRestrictTypePropertySet GetTraceRestrictTypeProperties(TraceR } break; + case TRIT_COND_PHYS_RATIO: + switch (static_cast(GetTraceRestrictAuxField(item))) { + case TRPPRCAF_POWER_WEIGHT: + out.value_type = TRVT_POWER_WEIGHT_RATIO; + break; + + case TRPPRCAF_MAX_TE_WEIGHT: + out.value_type = TRVT_FORCE_WEIGHT_RATIO; + break; + + default: + NOT_REACHED(); + break; + } + break; + default: NOT_REACHED(); break; @@ -536,6 +564,19 @@ static inline TraceRestrictTypePropertySet GetTraceRestrictTypeProperties(TraceR return out; } +/** Is the aux field for this TraceRestrictItemType used as a subtype which changes the type of the value field? */ +static inline bool IsTraceRestrictTypeAuxSubtype(TraceRestrictItemType type) +{ + switch (type) { + case TRIT_COND_PHYS_PROP: + case TRIT_COND_PHYS_RATIO: + return true; + + default: + return false; + } +} + /** Get mapping ref ID from tile and track */ static inline TraceRestrictRefId MakeTraceRestrictRefId(TileIndex t, Track track) { diff --git a/src/tracerestrict_gui.cpp b/src/tracerestrict_gui.cpp index f1dce0f2e2..f95604d279 100644 --- a/src/tracerestrict_gui.cpp +++ b/src/tracerestrict_gui.cpp @@ -242,11 +242,12 @@ typedef uint TraceRestrictGuiItemType; static TraceRestrictGuiItemType GetItemGuiType(TraceRestrictItem item) { - TraceRestrictGuiItemType type = GetTraceRestrictType(item); - if (type == TRIT_COND_PHYS_PROP) { - type |= GetTraceRestrictAuxField(item) << 16; + TraceRestrictItemType type = GetTraceRestrictType(item); + if (IsTraceRestrictTypeAuxSubtype(type)) { + return type | (GetTraceRestrictAuxField(item) << 16); + } else { + return type; } - return type; } static TraceRestrictItemType ItemTypeFromGuiType(TraceRestrictGuiItemType type) @@ -289,6 +290,8 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG STR_TRACE_RESTRICT_VARIABLE_TRAIN_WEIGHT, STR_TRACE_RESTRICT_VARIABLE_TRAIN_POWER, STR_TRACE_RESTRICT_VARIABLE_TRAIN_MAX_TE, + STR_TRACE_RESTRICT_VARIABLE_TRAIN_POWER_WEIGHT_RATIO, + STR_TRACE_RESTRICT_VARIABLE_TRAIN_MAX_TE_WEIGHT_RATIO, STR_TRACE_RESTRICT_VARIABLE_UNDEFINED, INVALID_STRING_ID, }; @@ -305,6 +308,8 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG TRIT_COND_PHYS_PROP | (TRPPCAF_WEIGHT << 16), TRIT_COND_PHYS_PROP | (TRPPCAF_POWER << 16), TRIT_COND_PHYS_PROP | (TRPPCAF_MAX_TE << 16), + TRIT_COND_PHYS_RATIO | (TRPPRCAF_POWER_WEIGHT << 16), + TRIT_COND_PHYS_RATIO | (TRPPRCAF_MAX_TE_WEIGHT << 16), TRIT_COND_UNDEFINED, }; static const TraceRestrictDropDownListSet set_cond = { @@ -470,6 +475,8 @@ static bool IsIntegerValueType(TraceRestrictValueType type) case TRVT_WEIGHT: case TRVT_POWER: case TRVT_FORCE: + case TRVT_POWER_WEIGHT_RATIO: + case TRVT_FORCE_WEIGHT_RATIO: return true; default: @@ -509,6 +516,18 @@ static uint ConvertIntegerValue(TraceRestrictValueType type, uint in, bool to_di : ConvertDisplayForceToForce(in); break; + case TRVT_POWER_WEIGHT_RATIO: + return to_display + ? ConvertPowerToDisplayPower(in) * 10 + : ConvertDisplayPowerToPower(in) / 10; + break; + + case TRVT_FORCE_WEIGHT_RATIO: + return to_display + ? ConvertForceToDisplayForce(in) * 10 + : ConvertDisplayForceToForce(in) / 10; + break; + case TRVT_PF_PENALTY: return in; @@ -751,6 +770,20 @@ static void DrawInstructionString(const TraceRestrictProgram *prog, TraceRestric DrawInstructionStringConditionalIntegerCommon(item, properties); break; + 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: NOT_REACHED(); break;