From 0be3b053d53909e5b0ab16d94a0c96cbf7095577 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Wed, 22 Jul 2015 21:48:12 +0100 Subject: [PATCH] Add maximum train speed condition variable. --- src/lang/english.txt | 2 ++ src/tracerestrict.cpp | 5 +++ src/tracerestrict.h | 17 ++++++++- src/tracerestrict_gui.cpp | 75 ++++++++++++++++++++++++++++++--------- 4 files changed, 82 insertions(+), 17 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 4efc7db0ce..ad6272d37a 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -2383,8 +2383,10 @@ STR_TRACE_RESTRICT_CONDITIONAL_ORIF :Or if STR_TRACE_RESTRICT_CONDITIONAL_ELSE :Else STR_TRACE_RESTRICT_CONDITIONAL_ENDIF :End if STR_TRACE_RESTRICT_VARIABLE_TRAIN_LENGTH :train length +STR_TRACE_RESTRICT_VARIABLE_MAX_SPEED :max speed STR_TRACE_RESTRICT_VARIABLE_UNDEFINED :undefined STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_INTEGER :{STRING} {STRING} {STRING} {COMMA} then +STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_SPEED :{STRING} {STRING} {STRING} {VELOCITY} then STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_UNDEFINED :{STRING} {RED}undefined {BLACK}{STRING}then STR_TRACE_RESTRICT_PF_PENALTY_ITEM :Add pathfinder penalty: {COMMA} STR_TRACE_RESTRICT_WHITE :{WHITE} diff --git a/src/tracerestrict.cpp b/src/tracerestrict.cpp index 1f8bea6be5..5b25448dd6 100644 --- a/src/tracerestrict.cpp +++ b/src/tracerestrict.cpp @@ -170,6 +170,10 @@ void TraceRestrictProgram::Execute(const Train* v, TraceRestrictProgramResult& o result = TestCondition(CeilDiv(v->gcache.cached_total_length, TILE_SIZE), condop, condvalue); break; + case TRIT_COND_MAX_SPEED: + result = TestCondition(v->GetDisplayMaxSpeed(), condop, condvalue); + break; + default: NOT_REACHED(); } @@ -260,6 +264,7 @@ void SetTraceRestrictValueDefault(TraceRestrictItem &item, TraceRestrictValueTyp case TRVT_NONE: case TRVT_INT: case TRVT_DENY: + case TRVT_SPEED: SetTraceRestrictValue(item, 0); break; diff --git a/src/tracerestrict.h b/src/tracerestrict.h index 43dd55c6d8..87e8cb9b8d 100644 --- a/src/tracerestrict.h +++ b/src/tracerestrict.h @@ -80,6 +80,7 @@ enum TraceRestrictItemType { TRIT_COND_ENDIF = 8, ///< This is an endif block or an else block TRIT_COND_UNDEFINED = 9, ///< This condition has no type defined (evaluate as false) TRIT_COND_TRAIN_LENGTH = 10, ///< Test train length + TRIT_COND_MAX_SPEED = 11, ///< Test train max speed /* space up to 31 */ }; @@ -197,6 +198,7 @@ enum TraceRestrictValueType { TRVT_SPECIAL = 1, ///< special handling of value field TRVT_INT = 2, ///< takes an integer value TRVT_DENY = 3, ///< takes a value 0 = deny, 1 = allow (cancel previous deny) + TRVT_SPEED = 4, ///< takes an integer speed value }; struct TraceRestrictTypePropertySet { @@ -217,7 +219,20 @@ static inline TraceRestrictTypePropertySet GetTraceRestrictTypeProperties(TraceR out.value_type = TRVT_NONE; } else if (IsTraceRestrictConditional(item)) { out.cond_type = TRCOT_ALL; - out.value_type = TRVT_INT; + + switch (GetTraceRestrictType(item)) { + case TRIT_COND_TRAIN_LENGTH: + out.value_type = TRVT_INT; + break; + + case TRIT_COND_MAX_SPEED: + out.value_type = TRVT_SPEED; + break; + + default: + NOT_REACHED(); + break; + } } else { out.cond_type = TRCOT_NONE; if (GetTraceRestrictType(item) == TRIT_PF_PENALTY) { diff --git a/src/tracerestrict_gui.cpp b/src/tracerestrict_gui.cpp index 55c6b39d39..b1e8251898 100644 --- a/src/tracerestrict_gui.cpp +++ b/src/tracerestrict_gui.cpp @@ -27,6 +27,9 @@ #include "error.h" #include "table/sprites.h" +extern uint ConvertSpeedToDisplaySpeed(uint speed); +extern uint ConvertDisplaySpeedToSpeed(uint speed); + enum TraceRestrictWindowWidgets { TR_WIDGET_CAPTION, TR_WIDGET_INSTRUCTION_LIST, @@ -148,11 +151,13 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictI static const StringID str_cond[] = { STR_TRACE_RESTRICT_VARIABLE_TRAIN_LENGTH, + STR_TRACE_RESTRICT_VARIABLE_MAX_SPEED, STR_TRACE_RESTRICT_VARIABLE_UNDEFINED, INVALID_STRING_ID, }; static const uint val_cond[] = { TRIT_COND_TRAIN_LENGTH, + TRIT_COND_MAX_SPEED, TRIT_COND_UNDEFINED, }; static const TraceRestrictDropDownListSet set_cond = { @@ -217,12 +222,50 @@ static const TraceRestrictDropDownListSet *GetCondOpDropDownListSet(TraceRestric return NULL; } +static bool IsIntegerValueType(TraceRestrictValueType type) +{ + switch (type) { + case TRVT_INT: + case TRVT_SPEED: + return true; + + default: + return false; + } +} + +static uint ConvertIntegerValue(TraceRestrictValueType type, uint in, bool to_display) +{ + switch (type) { + case TRVT_INT: + return in; + + case TRVT_SPEED: + return to_display + ? ConvertSpeedToDisplaySpeed(in) * 10 / 16 + : ConvertDisplaySpeedToSpeed(in) * 16 / 10; + + default: + NOT_REACHED(); + return 0; + } +} + static const StringID _program_cond_type[] = { /* 0 */ STR_TRACE_RESTRICT_CONDITIONAL_IF, /* TRCF_ELSE */ STR_TRACE_RESTRICT_CONDITIONAL_ELIF, /* TRCF_OR */ STR_TRACE_RESTRICT_CONDITIONAL_ORIF, }; +static void DrawInstructionStringConditionalIntegerCommon(TraceRestrictItem item, const TraceRestrictTypePropertySet &properties) +{ + assert(GetTraceRestrictCondFlags(item) <= TRCF_OR); + SetDParam(0, _program_cond_type[GetTraceRestrictCondFlags(item)]); + SetDParam(1, GetTypeString(GetTraceRestrictType(item))); + SetDParam(2, GetDropDownStringByValue(GetCondOpDropDownListSet(properties.cond_type), GetTraceRestrictCondOp(item))); + SetDParam(3, GetTraceRestrictValue(item)); +} + /** * Draws an instruction in the programming GUI * @param instruction The instruction to draw @@ -251,12 +294,10 @@ static void DrawInstructionString(TraceRestrictItem item, int y, bool selected, SetDParam(1, selected ? STR_TRACE_RESTRICT_WHITE : STR_EMPTY); } else if (properties.value_type == TRVT_INT) { instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_INTEGER; - - assert(GetTraceRestrictCondFlags(item) <= TRCF_OR); - SetDParam(0, _program_cond_type[GetTraceRestrictCondFlags(item)]); - SetDParam(1, GetTypeString(GetTraceRestrictType(item))); - SetDParam(2, GetDropDownStringByValue(GetCondOpDropDownListSet(properties.cond_type), GetTraceRestrictCondOp(item))); - SetDParam(3, GetTraceRestrictValue(item)); + DrawInstructionStringConditionalIntegerCommon(item, properties); + } else if (properties.value_type == TRVT_SPEED) { + instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_SPEED; + DrawInstructionStringConditionalIntegerCommon(item, properties); } else { NOT_REACHED(); } @@ -383,9 +424,10 @@ public: case TR_WIDGET_VALUE_INT: { TraceRestrictItem item = this->GetSelected(); - if (GetTraceRestrictTypeProperties(item).value_type == TRVT_INT) { - SetDParam(0, GetTraceRestrictValue(item)); - ShowQueryString(STR_JUST_INT, STR_TRACE_RESTRICT_VALUE_CAPTION, 6, this, CS_NUMERAL, QSF_NONE); // 5 digit num, + terminating null + TraceRestrictValueType type = GetTraceRestrictTypeProperties(item).value_type; + if (IsIntegerValueType(type)) { + SetDParam(0, ConvertIntegerValue(type, GetTraceRestrictValue(item), true)); + ShowQueryString(STR_JUST_INT, STR_TRACE_RESTRICT_VALUE_CAPTION, 10, this, CS_NUMERAL, QSF_NONE); } break; } @@ -426,13 +468,14 @@ public: } TraceRestrictItem item = GetSelected(); - if (GetTraceRestrictTypeProperties(item).value_type != TRVT_INT) { + TraceRestrictValueType type = GetTraceRestrictTypeProperties(item).value_type; + if (!IsIntegerValueType(type)) { return; } - uint value = atoi(str); + uint value = ConvertIntegerValue(type, atoi(str), false); if (value >= (1 << TRIFA_VALUE_COUNT)) { - SetDParam(0, (1 << TRIFA_VALUE_COUNT) - 1); + SetDParam(0, ConvertIntegerValue(type, (1 << TRIFA_VALUE_COUNT) - 1, true)); ShowErrorMessage(STR_TRACE_RESTRICT_ERROR_VALUE_TOO_LARGE, STR_EMPTY, WL_INFO); return; } @@ -619,10 +662,10 @@ public: switch (widget) { case TR_WIDGET_VALUE_INT: { SetDParam(0, 0); - TraceRestrictItem item = this->GetSelected(); - if (GetTraceRestrictTypeProperties(item).value_type == TRVT_INT) { - SetDParam(0, GetTraceRestrictValue(item)); + TraceRestrictValueType type = GetTraceRestrictTypeProperties(item).value_type; + if (IsIntegerValueType(type)) { + SetDParam(0, ConvertIntegerValue(type, GetTraceRestrictValue(item), true)); } break; } @@ -846,7 +889,7 @@ private: } } - if (properties.value_type == TRVT_INT) { + if (IsIntegerValueType(properties.value_type)) { right_sel->SetDisplayedPlane(DPR_VALUE_INT); this->EnableWidget(TR_WIDGET_VALUE_INT); } else if (properties.value_type == TRVT_DENY) {