diff --git a/src/lang/english.txt b/src/lang/english.txt index 8ec58c420b..6653f61a7f 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -4884,6 +4884,7 @@ STR_ORDER_CONDITIONAL_TRAIN_IN_SLOT :Train in slot STR_ORDER_CONDITIONAL_CARGO_LOAD_PERCENTAGE :Cargo load percentage STR_ORDER_CONDITIONAL_CARGO_WAITING_AMOUNT :Waiting cargo amount STR_ORDER_CONDITIONAL_COUNTER_VALUE :Counter value +STR_ORDER_CONDITIONAL_TIME_DATE_VALUE :Current time/date STR_ORDER_CONDITIONAL_REQUIRES_SERVICE_ORDER :Requires service {STRING} STR_ORDER_CONDITIONAL_CARGO_WAITING_ORDER :Next station {STRING} {STRING} waiting @@ -4907,6 +4908,7 @@ STR_ORDER_CONDITIONAL_VALUE_TOOLTIP :{BLACK}The valu STR_ORDER_CONDITIONAL_CARGO_TOOLTIP :{BLACK}The cargo to compare the station data against STR_ORDER_CONDITIONAL_SLOT_TOOLTIP :{BLACK}The train slot to check the occupancy of STR_ORDER_CONDITIONAL_COUNTER_TOOLTIP :{BLACK}The counter to check the value of +STR_ORDER_CONDITIONAL_TIME_DATE_TOOLTIP :{BLACK}The current time/date field to check the value of STR_ORDER_CONDITIONAL_VALUE_CAPT :{WHITE}Enter value to compare against STR_ORDER_CONDITIONAL_VIA :{BLACK}Via @@ -5053,6 +5055,7 @@ STR_ORDER_CONDITIONAL_CARGO_WAITING_AMOUNT_DISPLAY :Jump to order { STR_ORDER_CONDITIONAL_CARGO_WAITING_AMOUNT_VIA_DISPLAY :Jump to order {COMMA} when {STRING} at next station via {STATION} {STRING} {CARGO_SHORT} STR_ORDER_CONDITIONAL_COUNTER :Jump to order {COMMA} when value of {TRCOUNTER} {STRING} {COMMA} STR_ORDER_CONDITIONAL_INVALID_COUNTER :Jump to order {COMMA} when value of {PUSH_COLOUR}{RED}{STRING}{POP_COLOUR} {STRING} {COMMA} +STR_ORDER_CONDITIONAL_TIME_HHMM :Jump to order {COMMA} when {STRING} {STRING} {TIME_HHMM} STR_INVALID_ORDER :{RED} (Invalid Order) diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 0029952538..b8e58a561a 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -1797,6 +1797,7 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 case OCV_CARGO_WAITING_AMOUNT: case OCV_COUNTER_VALUE: + case OCV_TIME_DATE: if (data >= (1 << 16)) return CMD_ERROR; break; @@ -1817,6 +1818,10 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 if (data != INVALID_TRACE_RESTRICT_COUNTER_ID && !TraceRestrictCounter::IsValidID(data)) return CMD_ERROR; break; + case OCV_TIME_DATE: + if (data >= TRTDVF_END) return CMD_ERROR; + break; + default: return CMD_ERROR; } @@ -1924,6 +1929,7 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 || order->GetConditionVariable() == OCV_CARGO_LOAD_PERCENTAGE || order->GetConditionVariable() == OCV_CARGO_WAITING_AMOUNT); bool old_var_was_slot = (order->GetConditionVariable() == OCV_SLOT_OCCUPANCY || order->GetConditionVariable() == OCV_TRAIN_IN_SLOT); bool old_var_was_counter = (order->GetConditionVariable() == OCV_COUNTER_VALUE); + bool old_var_was_time = (order->GetConditionVariable() == OCV_TIME_DATE); order->SetConditionVariable((OrderConditionVariable)data); OrderConditionComparator occ = order->GetConditionComparator(); @@ -1944,6 +1950,11 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 if (occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) order->SetConditionComparator(OCC_EQUALS); break; + case OCV_TIME_DATE: + if (!old_var_was_time) order->GetXDataRef() = 0; + if (occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) order->SetConditionComparator(OCC_EQUALS); + break; + case OCV_CARGO_ACCEPTANCE: case OCV_CARGO_WAITING: if (!old_var_was_cargo) order->SetConditionValue((uint16) GetFirstValidCargo()); @@ -1970,7 +1981,7 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 FALLTHROUGH; default: - if (old_var_was_cargo || old_var_was_slot || old_var_was_counter) order->SetConditionValue(0); + if (old_var_was_cargo || old_var_was_slot || old_var_was_counter || old_var_was_time) order->SetConditionValue(0); if (occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) order->SetConditionComparator(OCC_EQUALS); break; } @@ -1986,6 +1997,7 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 case OCV_SLOT_OCCUPANCY: case OCV_TRAIN_IN_SLOT: case OCV_CARGO_LOAD_PERCENTAGE: + case OCV_TIME_DATE: order->GetXDataRef() = data; break; @@ -2780,6 +2792,10 @@ VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v, boo if (ctr != nullptr) skip_order = OrderConditionCompare(occ, ctr->value, GB(order->GetXData(), 0, 16)); break; } + case OCV_TIME_DATE: { + skip_order = OrderConditionCompare(occ, GetTraceRestrictTimeDateValue(static_cast(value)), order->GetXData()); + break; + } default: NOT_REACHED(); } diff --git a/src/order_gui.cpp b/src/order_gui.cpp index 7870b40573..d4f2cbc382 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -655,6 +655,7 @@ static const OrderConditionVariable _order_conditional_variable[] = { OCV_SLOT_OCCUPANCY, OCV_TRAIN_IN_SLOT, OCV_COUNTER_VALUE, + OCV_TIME_DATE, OCV_PERCENT, OCV_UNCONDITIONALLY, }; @@ -749,6 +750,13 @@ static const StringID _order_refit_action_dropdown[] = { INVALID_STRING_ID }; +static const StringID _order_time_date_dropdown[] = { + STR_TRACE_RESTRICT_TIME_MINUTE, + STR_TRACE_RESTRICT_TIME_HOUR, + STR_TRACE_RESTRICT_TIME_HOUR_MINUTE, + INVALID_STRING_ID +}; + /** * Draws an order in order or timetable GUI * @param v Vehicle the order belongs to @@ -970,6 +978,11 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int } SetDParam(3, STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS + order->GetConditionComparator()); SetDParam(4, GB(order->GetXData(), 0, 16)); + } else if (ocv == OCV_TIME_DATE) { + SetDParam(0, (order->GetConditionValue() == TRTDVF_HOUR_MINUTE) ? STR_ORDER_CONDITIONAL_TIME_HHMM : STR_ORDER_CONDITIONAL_NUM); + SetDParam(2, STR_TRACE_RESTRICT_TIME_MINUTE_ITEM + order->GetConditionValue()); + SetDParam(3, STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS + order->GetConditionComparator()); + SetDParam(4, order->GetXData()); } else { OrderConditionComparator occ = order->GetConditionComparator(); SetDParam(0, (occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) ? STR_ORDER_CONDITIONAL_TRUE_FALSE : STR_ORDER_CONDITIONAL_NUM); @@ -1212,7 +1225,8 @@ private: /* WID_O_SEL_COND_AUX */ DP_COND_AUX_CARGO = 0, ///< Display dropdown widget cargo types - DP_COND_COUNTER = 1, ///< Display dropdown widget counters + DP_COND_TIME_DATE = 1, ///< Display dropdown for current time/date field + DP_COND_COUNTER = 2, ///< Display dropdown widget counters /* WID_O_SEL_COND_AUX2 */ DP_COND_AUX2_VIA = 0, ///< Display via button @@ -1881,6 +1895,7 @@ public: bool is_slot_occupancy = (ocv == OCV_SLOT_OCCUPANCY || ocv == OCV_TRAIN_IN_SLOT); bool is_auxiliary_cargo = (ocv == OCV_CARGO_LOAD_PERCENTAGE || ocv == OCV_CARGO_WAITING_AMOUNT); bool is_counter = (ocv == OCV_COUNTER_VALUE); + bool is_time_date = (ocv == OCV_TIME_DATE); if (is_cargo) { if (order == nullptr || !CargoSpec::Get(order->GetConditionValue())->IsValid()) { @@ -1910,6 +1925,9 @@ public: this->GetWidget(WID_O_COND_COUNTER)->widget_data = (ctr_id != INVALID_TRACE_RESTRICT_COUNTER_ID) ? STR_TRACE_RESTRICT_COUNTER_NAME : STR_TRACE_RESTRICT_VARIABLE_UNDEFINED; aux_sel->SetDisplayedPlane(DP_COND_COUNTER); + } else if (is_time_date) { + this->GetWidget(WID_O_COND_TIME_DATE)->widget_data = STR_TRACE_RESTRICT_TIME_MINUTE_ITEM + order->GetConditionValue(); + aux_sel->SetDisplayedPlane(DP_COND_TIME_DATE); } else { aux_sel->SetDisplayedPlane(SZSP_NONE); } @@ -1923,6 +1941,7 @@ public: /* Set the strings for the dropdown boxes. */ this->GetWidget(WID_O_COND_VARIABLE)->widget_data = STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + ocv; this->GetWidget(WID_O_COND_COMPARATOR)->widget_data = GetComparatorStrings(order)[order->GetConditionComparator()]; + this->GetWidget(WID_O_COND_VALUE)->widget_data = (ocv == OCV_TIME_DATE && order->GetConditionValue() == TRTDVF_HOUR_MINUTE) ? STR_BLACK_TIME_HHMM : STR_BLACK_COMMA; this->SetWidgetDisabledState(WID_O_COND_COMPARATOR, ocv == OCV_UNCONDITIONALLY || ocv == OCV_PERCENT); this->SetWidgetDisabledState(WID_O_COND_VALUE, ocv == OCV_REQUIRES_SERVICE || ocv == OCV_UNCONDITIONALLY); break; @@ -2070,6 +2089,7 @@ public: uint value; switch (order->GetConditionVariable()) { case OCV_CARGO_LOAD_PERCENTAGE: + case OCV_TIME_DATE: value = order->GetXData(); break; @@ -2301,6 +2321,12 @@ public: break; } + case WID_O_COND_TIME_DATE: { + ShowDropDownMenu(this, _order_time_date_dropdown, this->vehicle->GetOrder(this->OrderGetSel())->GetConditionValue(), + WID_O_COND_TIME_DATE, 0, 0, UINT_MAX); + break; + } + case WID_O_REVERSE: { VehicleOrderID sel_ord = this->OrderGetSel(); const Order *order = this->vehicle->GetOrder(sel_ord); @@ -2351,6 +2377,7 @@ public: _order_conditional_variable[i] == OCV_COUNTER_VALUE) && !_settings_client.gui.show_adv_tracerestrict_features) { continue; } + if (_order_conditional_variable[i] == OCV_TIME_DATE && !_settings_game.game_time.time_in_minutes) continue; } list.emplace_back(new DropDownListStringItem(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + _order_conditional_variable[i], _order_conditional_variable[i], false)); } @@ -2386,6 +2413,7 @@ public: uint value; switch (order->GetConditionVariable()) { case OCV_CARGO_LOAD_PERCENTAGE: + case OCV_TIME_DATE: value = order->GetXData(); break; @@ -2447,6 +2475,7 @@ public: break; case OCV_COUNTER_VALUE: + case OCV_TIME_DATE: value = Clamp(value, 0, 0xFFFF); break; @@ -2519,6 +2548,10 @@ public: this->ModifyOrder(this->OrderGetSel(), MOF_COND_VALUE_2 | index << 4); break; + case WID_O_COND_TIME_DATE: + this->ModifyOrder(this->OrderGetSel(), MOF_COND_VALUE_2 | index << 4); + break; + case WID_O_MANAGE_LIST: switch (index) { case 0: this->OrderClick_ReverseOrderList(0); break; @@ -2769,6 +2802,8 @@ static const NWidgetPart _nested_orders_train_widgets[] = { NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_COND_AUX), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_AUX_CARGO), SetMinimalSize(124, 12), SetFill(1, 0), SetDataTip(STR_NULL, STR_ORDER_CONDITIONAL_CARGO_TOOLTIP), SetResize(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_TIME_DATE), SetMinimalSize(124, 12), SetFill(1, 0), + SetDataTip(STR_NULL, STR_ORDER_CONDITIONAL_TIME_DATE_TOOLTIP), SetResize(1, 0), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_COUNTER), SetMinimalSize(124, 12), SetFill(1, 0), SetDataTip(STR_NULL, STR_ORDER_CONDITIONAL_COUNTER_TOOLTIP), SetResize(1, 0), EndContainer(), @@ -2871,6 +2906,8 @@ static const NWidgetPart _nested_orders_widgets[] = { NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_COND_AUX), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_AUX_CARGO), SetMinimalSize(124, 12), SetFill(1, 0), SetDataTip(STR_NULL, STR_ORDER_CONDITIONAL_CARGO_TOOLTIP), SetResize(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COND_TIME_DATE), SetMinimalSize(124, 12), SetFill(1, 0), + SetDataTip(STR_NULL, STR_ORDER_CONDITIONAL_TIME_DATE_TOOLTIP), SetResize(1, 0), EndContainer(), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_O_SEL_COND_AUX2), NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_O_COND_AUX_VIA), SetMinimalSize(36, 12), diff --git a/src/order_type.h b/src/order_type.h index fc7fb8c2a3..9eb68af856 100644 --- a/src/order_type.h +++ b/src/order_type.h @@ -146,6 +146,7 @@ enum OrderConditionVariable { OCV_CARGO_LOAD_PERCENTAGE, ///< Skip based on the amount of load of a specific cargo OCV_CARGO_WAITING_AMOUNT, ///< Skip based on the amount of a specific cargo waiting at next station OCV_COUNTER_VALUE, ///< Skip based on counter value + OCV_TIME_DATE, ///< Skip based on current time/date OCV_END }; diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index d162a49ca2..f567b0b70b 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -92,7 +92,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_INFRA_SHARING, XSCF_NULL, 2, 2, "infra_sharing", nullptr, nullptr, "CPDP" }, { XSLFI_VARIABLE_DAY_LENGTH, XSCF_NULL, 2, 2, "variable_day_length", nullptr, nullptr, nullptr }, { XSLFI_ORDER_OCCUPANCY, XSCF_NULL, 2, 2, "order_occupancy", nullptr, nullptr, nullptr }, - { XSLFI_MORE_COND_ORDERS, XSCF_NULL, 7, 7, "more_cond_orders", nullptr, nullptr, nullptr }, + { XSLFI_MORE_COND_ORDERS, XSCF_NULL, 8, 8, "more_cond_orders", nullptr, nullptr, nullptr }, { XSLFI_EXTRA_LARGE_MAP, XSCF_NULL, 0, 1, "extra_large_map", nullptr, nullptr, nullptr }, { XSLFI_REVERSE_AT_WAYPOINT, XSCF_NULL, 1, 1, "reverse_at_waypoint", nullptr, nullptr, nullptr }, { XSLFI_VEH_LIFETIME_PROFIT, XSCF_NULL, 1, 1, "veh_lifetime_profit", nullptr, nullptr, nullptr }, diff --git a/src/tracerestrict.h b/src/tracerestrict.h index 5c803a3689..3b3dd398b5 100644 --- a/src/tracerestrict.h +++ b/src/tracerestrict.h @@ -294,6 +294,7 @@ enum TraceRestrictTimeDateValueField { TRTDVF_MINUTE = 0, ///< Minute TRTDVF_HOUR = 1, ///< Hour TRTDVF_HOUR_MINUTE = 2, ///< Hour and minute + TRTDVF_END = 3, ///< End tag }; /** diff --git a/src/widgets/order_widget.h b/src/widgets/order_widget.h index eb3564ce28..1271aa3e82 100644 --- a/src/widgets/order_widget.h +++ b/src/widgets/order_widget.h @@ -38,6 +38,7 @@ enum OrderWidgets { WID_O_COND_AUX_CARGO, ///< Choose condition cargo. WID_O_COND_SLOT, ///< Choose condition slot. WID_O_COND_COUNTER, ///< Choose condition counter. + WID_O_COND_TIME_DATE, ///< Choose time/date value. WID_O_COND_AUX_VIA, ///< Condition via button. WID_O_SEL_COND_VALUE, ///< Widget for conditional value or conditional cargo type. WID_O_SEL_COND_AUX, ///< Widget for auxiliary conditional cargo type.