Add a "leave early" order timetable flag
Re-arrange timetable GUI slightly. Add an "extra" drop-down item.
This commit is contained in:
@@ -2029,7 +2029,8 @@ static void LoadUnloadVehicle(Vehicle *front)
|
||||
/* We loaded less cargo than possible for all cargo types and it's not full
|
||||
* load and we're not supposed to wait any longer: stop loading. */
|
||||
if (!anything_unloaded && full_load_amount == 0 && reservation_left == 0 && !has_full_load_order &&
|
||||
front->current_order_time >= (uint)max(front->current_order.GetTimetabledWait() - front->lateness_counter, 0)) {
|
||||
(front->current_order_time >= (uint)max(front->current_order.GetTimetabledWait() - front->lateness_counter, 0) ||
|
||||
front->current_order.GetLeaveType() == OLT_LEAVE_EARLY)) {
|
||||
SetBit(front->vehicle_flags, VF_STOP_LOADING);
|
||||
}
|
||||
|
||||
|
@@ -4749,6 +4749,13 @@ STR_TIMETABLE_EXPECTED_TOOLTIP :{BLACK}Switch b
|
||||
|
||||
STR_TIMETABLE_LOCK_ORDER_TIME_TOOLTIP :{BLACK}Lock/unlock the amount of time for the highlighted order (Ctrl+Click set lock state for all orders).{}When locked the time will not be changed by timetable autofill or automate.
|
||||
|
||||
STR_TIMETABLE_LEAVE_EARLY_ORDER :[leave early]
|
||||
STR_TIMETABLE_LEAVE_NORMAL :Leave as timetabled
|
||||
STR_TIMETABLE_LEAVE_EARLY :Leave early
|
||||
|
||||
STR_TIMETABLE_EXTRA_DROP_DOWN :{BLACK}Extra
|
||||
STR_TIMETABLE_EXTRA_DROP_DOWN_TOOLTIP :{BLACK}Extra Options{}{}Leave as timetabled: Vehicles wait until their timetabled departure time before leaving (default).{}Leave Early: Vehicles leave as soon as loading/unloading is done, possibly before the timetabled departure time.
|
||||
|
||||
STR_TIMETABLE_ARRIVAL_ABBREVIATION :A:
|
||||
STR_TIMETABLE_DEPARTURE_ABBREVIATION :D:
|
||||
|
||||
|
@@ -432,6 +432,15 @@ public:
|
||||
if (!this->IsType(OT_CONDITIONAL) && fixed != IsWaitFixed()) SB(this->GetXFlagsRef(), 1, 1, fixed ? 1 : 0);
|
||||
}
|
||||
|
||||
/** Get the leave type */
|
||||
inline OrderLeaveType GetLeaveType() const { return (OrderLeaveType)GB(this->GetXFlags(), 2, 2); }
|
||||
|
||||
/** Set the leave type */
|
||||
inline void SetLeaveType(OrderLeaveType leave_type)
|
||||
{
|
||||
if (leave_type != this->GetLeaveType()) SB(this->GetXFlagsRef(), 2, 2, leave_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the occupancy value
|
||||
* @return occupancy
|
||||
|
@@ -893,6 +893,10 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
|
||||
|
||||
int edge = DrawString(rtl ? left : middle, rtl ? middle : right, y, STR_ORDER_TEXT, colour);
|
||||
|
||||
if (timetable && timetable_wait_time_valid && order->GetLeaveType() == OLT_LEAVE_EARLY) {
|
||||
edge = DrawString(rtl ? left : edge + 3, rtl ? edge - 3 : right, y, STR_TIMETABLE_LEAVE_EARLY_ORDER, colour);
|
||||
}
|
||||
|
||||
if (timetable && timetable_wait_time_valid && order->IsWaitFixed()) {
|
||||
Dimension lock_d = GetSpriteSize(SPR_LOCK);
|
||||
DrawPixelInfo tmp_dpi;
|
||||
|
@@ -196,6 +196,15 @@ enum OrderDepotAction {
|
||||
DA_END
|
||||
};
|
||||
|
||||
/**
|
||||
* When to leave the station/waiting point.
|
||||
*/
|
||||
enum OrderLeaveType {
|
||||
OLT_NORMAL = 0, ///< Leave when timetabled
|
||||
OLT_LEAVE_EARLY = 1, ///< Leave as soon as possible
|
||||
OLT_END
|
||||
};
|
||||
|
||||
/**
|
||||
* Enumeration for the data to set in #CmdChangeTimetable.
|
||||
*/
|
||||
@@ -204,9 +213,10 @@ 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_LEAVE_TYPE,///< Passes an OrderLeaveType.
|
||||
MTF_END
|
||||
};
|
||||
template <> struct EnumPropsT<ModifyTimetableFlags> : MakeEnumPropsT<ModifyTimetableFlags, byte, MTF_WAIT_TIME, MTF_END, MTF_END, 2> {};
|
||||
template <> struct EnumPropsT<ModifyTimetableFlags> : MakeEnumPropsT<ModifyTimetableFlags, byte, MTF_WAIT_TIME, MTF_END, MTF_END, 3> {};
|
||||
|
||||
|
||||
/** Clone actions. */
|
||||
|
@@ -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, 2, 2, "timetable_extra", NULL, NULL, "ORDX" },
|
||||
{ XSLFI_TIMETABLE_EXTRA, XSCF_NULL, 3, 3, "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 },
|
||||
|
@@ -71,6 +71,10 @@ static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint16 val,
|
||||
order->SetWaitFixed(val != 0);
|
||||
break;
|
||||
|
||||
case MTF_SET_LEAVE_TYPE:
|
||||
order->SetLeaveType((OrderLeaveType)val);
|
||||
break;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
@@ -113,8 +117,8 @@ static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint16 val,
|
||||
* @param p1 Various bitstuffed elements
|
||||
* - p1 = (bit 0-19) - Vehicle with the orders to change.
|
||||
* - p1 = (bit 20-27) - Order index to modify.
|
||||
* - p1 = (bit 28-29) - Timetable data to change (@see ModifyTimetableFlags)
|
||||
* - p1 = (bit 30) - 0 to set timetable wait/travel time, 1 to clear it
|
||||
* - p1 = (bit 28-30) - Timetable data to change (@see ModifyTimetableFlags)
|
||||
* - p1 = (bit 31) - 0 to set timetable wait/travel time, 1 to clear it
|
||||
* @param p2 The amount of time to wait.
|
||||
* - p2 = (bit 0-15) - The data to modify as specified by p1 bits 28-29.
|
||||
* 0 to clear times, UINT16_MAX to clear speed limit.
|
||||
@@ -135,15 +139,16 @@ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, u
|
||||
Order *order = v->GetOrder(order_number);
|
||||
if (order == NULL || order->IsType(OT_IMPLICIT)) return CMD_ERROR;
|
||||
|
||||
ModifyTimetableFlags mtf = Extract<ModifyTimetableFlags, 28, 2>(p1);
|
||||
ModifyTimetableFlags mtf = Extract<ModifyTimetableFlags, 28, 3>(p1);
|
||||
if (mtf >= MTF_END) return CMD_ERROR;
|
||||
|
||||
bool clear_field = GB(p1, 30, 1) == 1;
|
||||
bool clear_field = GB(p1, 31, 1) == 1;
|
||||
|
||||
int wait_time = order->GetWaitTime();
|
||||
int travel_time = order->GetTravelTime();
|
||||
int max_speed = order->GetMaxSpeed();
|
||||
bool wait_fixed = order->IsWaitFixed();
|
||||
OrderLeaveType leave_type = order->GetLeaveType();
|
||||
switch (mtf) {
|
||||
case MTF_WAIT_TIME:
|
||||
wait_time = GB(p2, 0, 16);
|
||||
@@ -164,11 +169,16 @@ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, u
|
||||
wait_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;
|
||||
break;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
|
||||
if (wait_time != order->GetWaitTime()) {
|
||||
if (wait_time != order->GetWaitTime() || leave_type != order->GetLeaveType()) {
|
||||
switch (order->GetType()) {
|
||||
case OT_GOTO_STATION:
|
||||
if (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) return_cmd_error(STR_ERROR_TIMETABLE_NOT_STOPPING_HERE);
|
||||
@@ -187,6 +197,7 @@ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, u
|
||||
if (travel_time != order->GetTravelTime() && order->IsType(OT_CONDITIONAL)) return CMD_ERROR;
|
||||
if (max_speed != order->GetMaxSpeed() && (order->IsType(OT_CONDITIONAL) || v->type == VEH_AIRCRAFT)) return CMD_ERROR;
|
||||
if (wait_fixed != order->IsWaitFixed() && order->IsType(OT_CONDITIONAL)) return CMD_ERROR;
|
||||
if (leave_type != order->GetLeaveType() && order->IsType(OT_CONDITIONAL)) return CMD_ERROR;
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
switch (mtf) {
|
||||
@@ -216,6 +227,12 @@ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, u
|
||||
}
|
||||
break;
|
||||
|
||||
case MTF_SET_LEAVE_TYPE:
|
||||
if (leave_type != order->GetLeaveType()) {
|
||||
ChangeTimetable(v, order_number, leave_type, MTF_SET_LEAVE_TYPE, true);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -231,8 +248,8 @@ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, u
|
||||
* @param p1 Various bitstuffed elements
|
||||
* - p1 = (bit 0-19) - Vehicle with the orders to change.
|
||||
* - p1 = (bit 20-27) - unused
|
||||
* - p1 = (bit 28-29) - Timetable data to change (@see ModifyTimetableFlags)
|
||||
* - p1 = (bit 30) - 0 to set timetable wait/travel time, 1 to clear it
|
||||
* - p1 = (bit 28-30) - Timetable data to change (@see ModifyTimetableFlags)
|
||||
* - p1 = (bit 31) - 0 to set timetable wait/travel time, 1 to clear it
|
||||
* @param p2 The amount of time to wait.
|
||||
* - p2 = (bit 0-15) - The data to modify as specified by p1 bits 28-29.
|
||||
* 0 to clear times, UINT16_MAX to clear speed limit.
|
||||
@@ -249,7 +266,7 @@ CommandCost CmdBulkChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p
|
||||
CommandCost ret = CheckOwnership(v->owner);
|
||||
if (ret.Failed()) return ret;
|
||||
|
||||
ModifyTimetableFlags mtf = Extract<ModifyTimetableFlags, 28, 2>(p1);
|
||||
ModifyTimetableFlags mtf = Extract<ModifyTimetableFlags, 28, 3>(p1);
|
||||
if (mtf >= MTF_END) return CMD_ERROR;
|
||||
|
||||
if (v->GetNumOrders() == 0) return CMD_ERROR;
|
||||
|
@@ -389,6 +389,7 @@ struct TimetableWindow : Window {
|
||||
this->EnableWidget(WID_VT_ADD_VEH_GROUP);
|
||||
this->SetWidgetDisabledState(WID_VT_LOCK_ORDER_TIME, !wait_lockable);
|
||||
this->SetWidgetLoweredState(WID_VT_LOCK_ORDER_TIME, wait_locked);
|
||||
this->SetWidgetDisabledState(WID_VT_EXTRA, disable || (selected % 2 != 0));
|
||||
} else {
|
||||
this->DisableWidget(WID_VT_START_DATE);
|
||||
this->DisableWidget(WID_VT_CHANGE_TIME);
|
||||
@@ -402,6 +403,7 @@ struct TimetableWindow : Window {
|
||||
this->DisableWidget(WID_VT_SHARED_ORDER_LIST);
|
||||
this->DisableWidget(WID_VT_ADD_VEH_GROUP);
|
||||
this->DisableWidget(WID_VT_LOCK_ORDER_TIME);
|
||||
this->DisableWidget(WID_VT_EXTRA);
|
||||
}
|
||||
|
||||
this->SetWidgetLoweredState(WID_VT_AUTOFILL, HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE));
|
||||
@@ -673,7 +675,7 @@ struct TimetableWindow : Window {
|
||||
|
||||
if (order_number >= v->GetNumOrders()) order_number = 0;
|
||||
|
||||
return v->index | (order_number << 20) | (mtf << 28) | (clear ? 1 << 30 : 0);
|
||||
return v->index | (order_number << 20) | (mtf << 28) | (clear ? 1 << 31 : 0);
|
||||
}
|
||||
|
||||
virtual void OnClick(Point pt, int widget, int click_count)
|
||||
@@ -840,11 +842,41 @@ struct TimetableWindow : Window {
|
||||
ShowQueryString(STR_EMPTY, STR_GROUP_RENAME_CAPTION, MAX_LENGTH_GROUP_NAME_CHARS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS);
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_VT_EXTRA: {
|
||||
VehicleOrderID real = (this->sel_index + 1) / 2;
|
||||
if (real >= this->vehicle->GetNumOrders()) real = 0;
|
||||
const Order *order = this->vehicle->GetOrder(real);
|
||||
bool leave_type_disabled = (order == NULL) ||
|
||||
((!(order->IsType(OT_GOTO_STATION) || (order->IsType(OT_GOTO_DEPOT) && !(order->GetDepotActionType() & ODATFB_HALT))) ||
|
||||
(order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION)) && !order->IsType(OT_CONDITIONAL));
|
||||
DropDownList *list = new DropDownList();
|
||||
*list->Append() = new DropDownListStringItem(STR_TIMETABLE_LEAVE_NORMAL, OLT_NORMAL, leave_type_disabled);
|
||||
*list->Append() = new DropDownListStringItem(STR_TIMETABLE_LEAVE_EARLY, OLT_LEAVE_EARLY, leave_type_disabled);
|
||||
ShowDropDownList(this, list, order != NULL ? order->GetLeaveType() : -1, WID_VT_EXTRA);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this->SetDirty();
|
||||
}
|
||||
|
||||
virtual void OnDropdownSelect(int widget, int index) OVERRIDE
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_VT_EXTRA: {
|
||||
VehicleOrderID order_number = (this->sel_index + 1) / 2;
|
||||
if (order_number >= this->vehicle->GetNumOrders()) order_number = 0;
|
||||
|
||||
uint32 p1 = this->vehicle->index | (order_number << 20) | (MTF_SET_LEAVE_TYPE << 28);
|
||||
DoCommandP(0, p1, index, CMD_CHANGE_TIMETABLE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnQueryTextFinished(char *str)
|
||||
{
|
||||
if (str == NULL) return;
|
||||
@@ -963,12 +995,13 @@ static const NWidgetPart _nested_timetable_widgets[] = {
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_CLEAR_SPEED), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_CLEAR_SPEED, STR_TIMETABLE_CLEAR_SPEED_TOOLTIP),
|
||||
EndContainer(),
|
||||
NWidget(NWID_VERTICAL, NC_EQUALSIZE),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_SCHEDULED_DISPATCH), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_SCHEDULED_DISPATCH, STR_TIMETABLE_SCHEDULED_DISPATCH_TOOLTIP),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_AUTOMATE), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_AUTOMATE, STR_TIMETABLE_AUTOMATE_TOOLTIP),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_AUTO_SEPARATION), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_AUTO_SEPARATION, STR_TIMETABLE_AUTO_SEPARATION_TOOLTIP),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_RESET_LATENESS), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_RESET_LATENESS, STR_TIMETABLE_RESET_LATENESS_TOOLTIP),
|
||||
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VT_EXTRA), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_EXTRA_DROP_DOWN, STR_TIMETABLE_EXTRA_DROP_DOWN_TOOLTIP),
|
||||
EndContainer(),
|
||||
NWidget(NWID_VERTICAL, NC_EQUALSIZE),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_AUTOMATE), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_AUTOMATE, STR_TIMETABLE_AUTOMATE_TOOLTIP),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_SCHEDULED_DISPATCH), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_SCHEDULED_DISPATCH, STR_TIMETABLE_SCHEDULED_DISPATCH_TOOLTIP),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_RESET_LATENESS), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_RESET_LATENESS, STR_TIMETABLE_RESET_LATENESS_TOOLTIP),
|
||||
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_VT_EXPECTED_SELECTION),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_EXPECTED), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_BLACK_STRING, STR_TIMETABLE_EXPECTED_TOOLTIP),
|
||||
NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), SetFill(1, 1), EndContainer(),
|
||||
|
@@ -2961,7 +2961,7 @@ void Vehicle::HandleLoading(bool mode)
|
||||
if (!mode && this->type != VEH_TRAIN) PayStationSharingFee(this, Station::Get(this->last_station_visited));
|
||||
|
||||
/* Not the first call for this tick, or still loading */
|
||||
if (mode || !HasBit(this->vehicle_flags, VF_LOADING_FINISHED) || this->current_order_time < wait_time) {
|
||||
if (mode || !HasBit(this->vehicle_flags, VF_LOADING_FINISHED) || (this->current_order_time < wait_time && this->current_order.GetLeaveType() != OLT_LEAVE_EARLY)) {
|
||||
if (!mode && this->type == VEH_TRAIN && HasBit(Train::From(this)->flags, VRF_ADVANCE_IN_PLATFORM)) this->AdvanceLoadingInStation();
|
||||
return;
|
||||
}
|
||||
@@ -2999,7 +2999,7 @@ void Vehicle::HandleWaiting(bool stop_waiting)
|
||||
case OT_WAITING: {
|
||||
uint wait_time = max(this->current_order.GetTimetabledWait() - this->lateness_counter, 0);
|
||||
/* Vehicles holds on until waiting Timetabled time expires. */
|
||||
if (!stop_waiting && this->current_order_time < wait_time) {
|
||||
if (!stop_waiting && this->current_order_time < wait_time && this->current_order.GetLeaveType() != OLT_LEAVE_EARLY) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -38,6 +38,7 @@ enum VehicleTimetableWidgets {
|
||||
WID_VT_CLEAR_SPEED, ///< Clear speed limit button.
|
||||
WID_VT_SCHEDULED_DISPATCH, ///< Scheduled Dispatch button.
|
||||
WID_VT_LOCK_ORDER_TIME, ///< Lock order time button.
|
||||
WID_VT_EXTRA, ///< Extra drop down menu.
|
||||
};
|
||||
|
||||
#endif /* WIDGETS_TIMETABLE_WIDGET_H */
|
||||
|
Reference in New Issue
Block a user