diff --git a/src/order_base.h b/src/order_base.h index d43e294244..f95784b44d 100644 --- a/src/order_base.h +++ b/src/order_base.h @@ -426,10 +426,19 @@ public: /** Does this order have a fixed wait time? */ inline bool IsWaitFixed() const { return HasBit(this->GetXFlags(), 1); } - /** Set if the wait time is fixed */ + /** Set if the wait time is fixed */ inline void SetWaitFixed(bool fixed) { - if (!this->IsType(OT_CONDITIONAL) && fixed != IsWaitFixed()) SB(this->GetXFlagsRef(), 1, 1, fixed ? 1 : 0); + if (!this->IsType(OT_CONDITIONAL) && fixed != this->IsWaitFixed()) SB(this->GetXFlagsRef(), 1, 1, fixed ? 1 : 0); + } + + /** Does this order have a fixed travel time? */ + inline bool IsTravelFixed() const { return HasBit(this->GetXFlags(), 4); } + + /** Set if the travel time is fixed */ + inline void SetTravelFixed(bool fixed) + { + if (!this->IsType(OT_CONDITIONAL) && fixed != IsTravelFixed()) SB(this->GetXFlagsRef(), 4, 1, fixed ? 1 : 0); } /** Get the leave type */ diff --git a/src/order_type.h b/src/order_type.h index f28a2605cf..8d649c20d5 100644 --- a/src/order_type.h +++ b/src/order_type.h @@ -213,6 +213,7 @@ enum ModifyTimetableFlags { MTF_TRAVEL_TIME, ///< Set travel time. MTF_TRAVEL_SPEED, ///< Set max travel speed. MTF_SET_WAIT_FIXED,///< Set wait time fixed flag state. + MTF_SET_TRAVEL_FIXED,///< Set travel time fixed flag state. MTF_SET_LEAVE_TYPE,///< Passes an OrderLeaveType. MTF_END }; diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index a647b030ac..d63868273e 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -80,7 +80,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_SCHEDULED_DISPATCH, XSCF_NULL, 1, 1, "scheduled_dispatch", NULL, NULL, NULL }, { XSLFI_MORE_TOWN_GROWTH_RATES, XSCF_NULL, 1, 1, "more_town_growth_rates", NULL, NULL, NULL }, { XSLFI_MULTIPLE_DOCKS, XSCF_NULL, 1, 1, "multiple_docks", NULL, NULL, "DOCK" }, - { XSLFI_TIMETABLE_EXTRA, XSCF_NULL, 3, 3, "timetable_extra", NULL, NULL, "ORDX" }, + { XSLFI_TIMETABLE_EXTRA, XSCF_NULL, 4, 4, "timetable_extra", NULL, NULL, "ORDX" }, { XSLFI_TRAIN_FLAGS_EXTRA, XSCF_NULL, 1, 1, "train_flags_extra", NULL, NULL, NULL }, { XSLFI_TRAIN_THROUGH_LOAD, XSCF_NULL, 2, 2, "train_through_load", NULL, NULL, NULL }, { XSLFI_ORDER_EXTRA_DATA, XSCF_NULL, 1, 1, "order_extra_data", NULL, NULL, NULL }, diff --git a/src/timetable_cmd.cpp b/src/timetable_cmd.cpp index 7db6843889..49d876a26a 100644 --- a/src/timetable_cmd.cpp +++ b/src/timetable_cmd.cpp @@ -54,6 +54,7 @@ static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint16 val, break; case MTF_TRAVEL_TIME: + if (!ignore_lock && order->IsTravelFixed()) return; if (!order->IsType(OT_CONDITIONAL)) { total_delta = val - order->GetTravelTime(); timetable_delta = (timetabled ? val : 0) - order->GetTimetabledTravel(); @@ -71,6 +72,10 @@ static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint16 val, order->SetWaitFixed(val != 0); break; + case MTF_SET_TRAVEL_FIXED: + order->SetTravelFixed(val != 0); + break; + case MTF_SET_LEAVE_TYPE: order->SetLeaveType((OrderLeaveType)val); break; @@ -102,6 +107,10 @@ static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint16 val, v->current_order.SetWaitFixed(val != 0); break; + case MTF_SET_TRAVEL_FIXED: + v->current_order.SetTravelFixed(val != 0); + break; + default: NOT_REACHED(); } @@ -148,6 +157,7 @@ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, u int travel_time = order->GetTravelTime(); int max_speed = order->GetMaxSpeed(); bool wait_fixed = order->IsWaitFixed(); + bool travel_fixed = order->IsTravelFixed(); OrderLeaveType leave_type = order->GetLeaveType(); switch (mtf) { case MTF_WAIT_TIME: @@ -169,6 +179,10 @@ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, u wait_fixed = GB(p2, 0, 16) != 0; break; + case MTF_SET_TRAVEL_FIXED: + travel_fixed = GB(p2, 0, 16) != 0; + break; + case MTF_SET_LEAVE_TYPE: leave_type = (OrderLeaveType)GB(p2, 0, 16); if (leave_type >= OLT_END) return CMD_ERROR; @@ -227,6 +241,12 @@ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, u } break; + case MTF_SET_TRAVEL_FIXED: + if (travel_fixed != order->IsTravelFixed()) { + ChangeTimetable(v, order_number, travel_fixed ? 1 : 0, MTF_SET_TRAVEL_FIXED, false, true); + } + break; + case MTF_SET_LEAVE_TYPE: if (leave_type != order->GetLeaveType()) { ChangeTimetable(v, order_number, leave_type, MTF_SET_LEAVE_TYPE, true); diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index 17c5e98bc4..1bd1500162 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -364,6 +364,8 @@ struct TimetableWindow : Window { if (selected % 2 == 1) { /* Travel time */ disable = order != NULL && (order->IsType(OT_CONDITIONAL) || order->IsType(OT_IMPLICIT)); + wait_lockable = !disable; + wait_locked = wait_lockable && order->IsTravelFixed(); } else { /* Wait time */ disable = (order == NULL) || @@ -485,7 +487,20 @@ struct TimetableWindow : Window { } SetDParam(string == STR_TIMETABLE_TRAVEL_NOT_TIMETABLED_SPEED ? 2 : 4, order->GetMaxSpeed()); - DrawString(rtl ? r.left + WD_FRAMERECT_LEFT : middle, rtl ? middle : r.right - WD_FRAMERECT_LEFT, y, string, colour); + int edge = DrawString(rtl ? r.left + WD_FRAMERECT_LEFT : middle, rtl ? middle : r.right - WD_FRAMERECT_LEFT, y, string, colour); + + if (order->IsTravelFixed()) { + Dimension lock_d = GetSpriteSize(SPR_LOCK); + DrawPixelInfo tmp_dpi; + if (FillDrawPixelInfo(&tmp_dpi, rtl ? r.left + WD_FRAMERECT_LEFT : middle, y, rtl ? middle : r.right - WD_FRAMERECT_LEFT, lock_d.height)) { + DrawPixelInfo *old_dpi = _cur_dpi; + _cur_dpi = &tmp_dpi; + + DrawSprite(SPR_LOCK, PAL_NONE, rtl ? edge - 3 - lock_d.width - (r.left + WD_FRAMERECT_LEFT) : edge + 3 - middle, 0); + + _cur_dpi = old_dpi; + } + } if (final_order) break; } @@ -790,10 +805,10 @@ struct TimetableWindow : Window { const Order *order = v->GetOrder(order_number); if (order != NULL) { - locked = order->IsWaitFixed(); + locked = (selected % 2 == 1) ? order->IsTravelFixed() : order->IsWaitFixed(); } - uint32 p1 = v->index | (order_number << 20) | (MTF_SET_WAIT_FIXED << 28); + uint32 p1 = v->index | (order_number << 20) | (((selected % 2 == 1) ? MTF_SET_TRAVEL_FIXED : MTF_SET_WAIT_FIXED) << 28); DoCommandP(0, p1, locked ? 0 : 1, (_ctrl_pressed ? CMD_BULK_CHANGE_TIMETABLE : CMD_CHANGE_TIMETABLE) | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE)); break; }