Add support for multiple scheduled dispatch schedules per order list
This commit is contained in:
@@ -269,10 +269,12 @@ CommandProc CmdScheduledDispatch;
|
|||||||
CommandProcEx CmdScheduledDispatchAdd;
|
CommandProcEx CmdScheduledDispatchAdd;
|
||||||
CommandProc CmdScheduledDispatchRemove;
|
CommandProc CmdScheduledDispatchRemove;
|
||||||
CommandProc CmdScheduledDispatchSetDuration;
|
CommandProc CmdScheduledDispatchSetDuration;
|
||||||
CommandProc CmdScheduledDispatchSetStartDate;
|
CommandProcEx CmdScheduledDispatchSetStartDate;
|
||||||
CommandProc CmdScheduledDispatchSetDelay;
|
CommandProc CmdScheduledDispatchSetDelay;
|
||||||
CommandProc CmdScheduledDispatchResetLastDispatch;
|
CommandProc CmdScheduledDispatchResetLastDispatch;
|
||||||
CommandProc CmdScheduledDispatchClear;
|
CommandProc CmdScheduledDispatchClear;
|
||||||
|
CommandProcEx CmdScheduledDispatchAddNewSchedule;
|
||||||
|
CommandProc CmdScheduledDispatchRemoveSchedule;
|
||||||
|
|
||||||
CommandProc CmdAddPlan;
|
CommandProc CmdAddPlan;
|
||||||
CommandProcEx CmdAddPlanLine;
|
CommandProcEx CmdAddPlanLine;
|
||||||
@@ -509,6 +511,8 @@ static const Command _command_proc_table[] = {
|
|||||||
DEF_CMD(CmdScheduledDispatchSetDelay, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SCHEDULED_DISPATCH_SET_DELAY
|
DEF_CMD(CmdScheduledDispatchSetDelay, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SCHEDULED_DISPATCH_SET_DELAY
|
||||||
DEF_CMD(CmdScheduledDispatchResetLastDispatch, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SCHEDULED_DISPATCH_RESET_LAST_DISPATCH
|
DEF_CMD(CmdScheduledDispatchResetLastDispatch, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SCHEDULED_DISPATCH_RESET_LAST_DISPATCH
|
||||||
DEF_CMD(CmdScheduledDispatchClear, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SCHEDULED_DISPATCH_CLEAR
|
DEF_CMD(CmdScheduledDispatchClear, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SCHEDULED_DISPATCH_CLEAR
|
||||||
|
DEF_CMD(CmdScheduledDispatchAddNewSchedule, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SCHEDULED_DISPATCH_ADD_NEW_SCHEDULE
|
||||||
|
DEF_CMD(CmdScheduledDispatchRemoveSchedule, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SCHEDULED_DISPATCH_REMOVE_SCHEDULE
|
||||||
|
|
||||||
DEF_CMD(CmdAddPlan, CMD_NO_TEST, CMDT_OTHER_MANAGEMENT ), // CMD_ADD_PLAN
|
DEF_CMD(CmdAddPlan, CMD_NO_TEST, CMDT_OTHER_MANAGEMENT ), // CMD_ADD_PLAN
|
||||||
DEF_CMD(CmdAddPlanLine, CMD_NO_TEST, CMDT_OTHER_MANAGEMENT ), // CMD_ADD_PLAN_LINE
|
DEF_CMD(CmdAddPlanLine, CMD_NO_TEST, CMDT_OTHER_MANAGEMENT ), // CMD_ADD_PLAN_LINE
|
||||||
|
@@ -154,4 +154,7 @@ CommandCallback CcDeleteVirtualTrain;
|
|||||||
CommandCallback CcAddVirtualEngine;
|
CommandCallback CcAddVirtualEngine;
|
||||||
CommandCallback CcMoveNewVirtualEngine;
|
CommandCallback CcMoveNewVirtualEngine;
|
||||||
|
|
||||||
|
/* schdispatch_gui.cpp */
|
||||||
|
CommandCallback CcAddNewSchDispatchSchedule;
|
||||||
|
|
||||||
#endif /* COMMAND_FUNC_H */
|
#endif /* COMMAND_FUNC_H */
|
||||||
|
@@ -450,6 +450,8 @@ enum Commands {
|
|||||||
CMD_SCHEDULED_DISPATCH_SET_DELAY, ///< scheduled dispatch set maximum allow delay
|
CMD_SCHEDULED_DISPATCH_SET_DELAY, ///< scheduled dispatch set maximum allow delay
|
||||||
CMD_SCHEDULED_DISPATCH_RESET_LAST_DISPATCH, ///< scheduled dispatch reset last dispatch date
|
CMD_SCHEDULED_DISPATCH_RESET_LAST_DISPATCH, ///< scheduled dispatch reset last dispatch date
|
||||||
CMD_SCHEDULED_DISPATCH_CLEAR, ///< scheduled dispatch clear schedule
|
CMD_SCHEDULED_DISPATCH_CLEAR, ///< scheduled dispatch clear schedule
|
||||||
|
CMD_SCHEDULED_DISPATCH_ADD_NEW_SCHEDULE, ///< scheduled dispatch add new schedule
|
||||||
|
CMD_SCHEDULED_DISPATCH_REMOVE_SCHEDULE, ///< scheduled dispatch remove schedule
|
||||||
|
|
||||||
CMD_ADD_PLAN,
|
CMD_ADD_PLAN,
|
||||||
CMD_ADD_PLAN_LINE,
|
CMD_ADD_PLAN_LINE,
|
||||||
|
@@ -88,21 +88,23 @@ static uint8 GetDepartureConditionalOrderMode(const Order *order)
|
|||||||
static inline bool VehicleSetNextDepartureTime(DateTicks *previous_departure, uint *waiting_time, const DateTicksScaled date_only_scaled, const Vehicle *v, const Order *order, bool arrived_at_timing_point, schdispatch_cache_t &dept_schedule_last)
|
static inline bool VehicleSetNextDepartureTime(DateTicks *previous_departure, uint *waiting_time, const DateTicksScaled date_only_scaled, const Vehicle *v, const Order *order, bool arrived_at_timing_point, schdispatch_cache_t &dept_schedule_last)
|
||||||
{
|
{
|
||||||
if (HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH)) {
|
if (HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH)) {
|
||||||
/* Loop over all order to find the first waiting order */
|
auto is_current_implicit_order = [&v](const Order *o) -> bool {
|
||||||
for (int j = 0; j < v->orders.list->GetNumOrders(); ++j) {
|
if (v->cur_implicit_order_index >= v->orders.list->GetNumOrders()) return false;
|
||||||
Order* iterating_order = v->orders.list->GetOrderAt(j);
|
return v->orders.list->GetOrderAt(v->cur_implicit_order_index) == o;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This condition means that we want departure time for the dispatch order */
|
||||||
|
/* but not if the vehicle has arrived at the dispatch order because the timetable is already shifted */
|
||||||
|
if (order->IsScheduledDispatchOrder(true) && !(arrived_at_timing_point && is_current_implicit_order(order))) {
|
||||||
|
const DispatchSchedule &ds = v->orders.list->GetDispatchScheduleByIndex(order->GetDispatchScheduleIndex());
|
||||||
|
|
||||||
if (iterating_order->IsWaitTimetabled() && !iterating_order->IsType(OT_IMPLICIT)) {
|
|
||||||
/* This condition means that we want departure time for the first order */
|
|
||||||
/* but not if the vehicle has arrived at the first order because the timetable is already shifted */
|
|
||||||
if (iterating_order == order && !(arrived_at_timing_point && v->cur_implicit_order_index == j)) {
|
|
||||||
DateTicksScaled actual_departure = -1;
|
DateTicksScaled actual_departure = -1;
|
||||||
const DateTicksScaled begin_time = v->orders.list->GetScheduledDispatchStartTick();
|
const DateTicksScaled begin_time = ds.GetScheduledDispatchStartTick();
|
||||||
const uint32 dispatch_duration = v->orders.list->GetScheduledDispatchDuration();
|
const uint32 dispatch_duration = ds.GetScheduledDispatchDuration();
|
||||||
const int32 max_delay = v->orders.list->GetScheduledDispatchDelay();
|
const int32 max_delay = ds.GetScheduledDispatchDelay();
|
||||||
|
|
||||||
/* Earliest possible departure according to schedue */
|
/* Earliest possible departure according to schedue */
|
||||||
DateTicksScaled earliest_departure = begin_time + v->orders.list->GetScheduledDispatchLastDispatch();
|
DateTicksScaled earliest_departure = begin_time + ds.GetScheduledDispatchLastDispatch();
|
||||||
|
|
||||||
/* Earliest possible departure according to vehicle current timetable */
|
/* Earliest possible departure according to vehicle current timetable */
|
||||||
if (earliest_departure + max_delay < date_only_scaled + *previous_departure + order->GetTravelTime()) {
|
if (earliest_departure + max_delay < date_only_scaled + *previous_departure + order->GetTravelTime()) {
|
||||||
@@ -111,7 +113,7 @@ static inline bool VehicleSetNextDepartureTime(DateTicks *previous_departure, ui
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Find next available slots */
|
/* Find next available slots */
|
||||||
for (auto current_offset : v->orders.list->GetScheduledDispatch()) {
|
for (auto current_offset : ds.GetScheduledDispatch()) {
|
||||||
if (current_offset >= dispatch_duration) continue;
|
if (current_offset >= dispatch_duration) continue;
|
||||||
DateTicksScaled current_departure = begin_time + current_offset;
|
DateTicksScaled current_departure = begin_time + current_offset;
|
||||||
while (current_departure <= earliest_departure) {
|
while (current_departure <= earliest_departure) {
|
||||||
@@ -137,14 +139,11 @@ static inline bool VehicleSetNextDepartureTime(DateTicks *previous_departure, ui
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* This is special case for proper calculation of arrival time. */
|
/* This is special case for proper calculation of arrival time. */
|
||||||
if (arrived_at_timing_point && v->cur_implicit_order_index == j) {
|
if (arrived_at_timing_point && v->cur_implicit_order_index < v->orders.list->GetNumOrders() && v->orders.list->GetOrderAt(v->cur_implicit_order_index)->IsScheduledDispatchOrder(true)) {
|
||||||
*previous_departure += order->GetTravelTime() + order->GetWaitTime();
|
*previous_departure += order->GetTravelTime() + order->GetWaitTime();
|
||||||
*waiting_time = -v->lateness_counter + order->GetWaitTime();
|
*waiting_time = -v->lateness_counter + order->GetWaitTime();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
} /* if it is first waiting order */
|
|
||||||
} /* for in order list */
|
|
||||||
} /* if vehicle is on scheduled dispatch */
|
} /* if vehicle is on scheduled dispatch */
|
||||||
|
|
||||||
/* Not using schedule for this departure time */
|
/* Not using schedule for this departure time */
|
||||||
|
@@ -5701,8 +5701,9 @@ STR_TIMETABLE_AUTO_SEPARATION_TOOLTIP :{BLACK}Automati
|
|||||||
|
|
||||||
STR_TIMETABLE_SCHEDULED_DISPATCH :{BLACK}Scheduled Dispatch
|
STR_TIMETABLE_SCHEDULED_DISPATCH :{BLACK}Scheduled Dispatch
|
||||||
STR_TIMETABLE_SCHEDULED_DISPATCH_TOOLTIP :{BLACK}Open scheduled dispatch windows for automatic setting of timetable start time
|
STR_TIMETABLE_SCHEDULED_DISPATCH_TOOLTIP :{BLACK}Open scheduled dispatch windows for automatic setting of timetable start time
|
||||||
STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER :[scheduled dispatch]
|
STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER :[{STRING1}scheduled dispatch]
|
||||||
STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME :{PUSH_COLOUR}{RED}[scheduled dispatch - no wait time timetabled]{POP_COLOUR}
|
STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME :{PUSH_COLOUR}{RED}[{STRING1}scheduled dispatch - no wait time timetabled]{POP_COLOUR}
|
||||||
|
STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER_SCHEDULE_INDEX :{NUM}{NBSP}-{NBSP}
|
||||||
|
|
||||||
STR_TIMETABLE_EXPECTED :{BLACK}Expected
|
STR_TIMETABLE_EXPECTED :{BLACK}Expected
|
||||||
STR_TIMETABLE_SCHEDULED :{BLACK}Scheduled
|
STR_TIMETABLE_SCHEDULED :{BLACK}Scheduled
|
||||||
@@ -5721,6 +5722,11 @@ STR_TIMETABLE_LEAVE_EARLY_FULL_ALL :Leave early if
|
|||||||
STR_TIMETABLE_EXTRA_DROP_DOWN :{BLACK}Extra
|
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.{}Leave Early if Any Full: As above, if any cargo is fully loaded.{}Leave Early if All Full: As above, if all cargoes are fully loaded.
|
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.{}Leave Early if Any Full: As above, if any cargo is fully loaded.{}Leave Early if All Full: As above, if all cargoes are fully loaded.
|
||||||
|
|
||||||
|
STR_TIMETABLE_ASSIGN_SCHEDULE_DROP_DOWN :{BLACK}Assign Schedule
|
||||||
|
STR_TIMETABLE_ASSIGN_SCHEDULE_DROP_DOWN_TOOLTIP :{BLACK}Assign or unassign a scheduled dispatch schedule to the selected order
|
||||||
|
STR_TIMETABLE_ASSIGN_SCHEDULE_NONE :No Schedule
|
||||||
|
STR_TIMETABLE_ASSIGN_SCHEDULE_ID :Schedule {NUM}
|
||||||
|
|
||||||
STR_TIMETABLE_ARRIVAL_ABBREVIATION :A:
|
STR_TIMETABLE_ARRIVAL_ABBREVIATION :A:
|
||||||
STR_TIMETABLE_DEPARTURE_ABBREVIATION :D:
|
STR_TIMETABLE_DEPARTURE_ABBREVIATION :D:
|
||||||
|
|
||||||
@@ -5730,10 +5736,11 @@ STR_TIMETABLE_AUTOSEP_SINGLE_VEH :{BLACK}This tim
|
|||||||
STR_TIMETABLE_WARNING_AUTOSEP_CONDITIONAL :{BLACK}Cannot auto separate timetable: conditional order(s) present
|
STR_TIMETABLE_WARNING_AUTOSEP_CONDITIONAL :{BLACK}Cannot auto separate timetable: conditional order(s) present
|
||||||
STR_TIMETABLE_WARNING_AUTOSEP_MISSING_TIMINGS :{BLACK}Cannot auto separate timetable: wait or travel time(s) missing
|
STR_TIMETABLE_WARNING_AUTOSEP_MISSING_TIMINGS :{BLACK}Cannot auto separate timetable: wait or travel time(s) missing
|
||||||
STR_TIMETABLE_WARNING_FULL_LOAD :{BLACK}Timetabling full-load orders is not recommended
|
STR_TIMETABLE_WARNING_FULL_LOAD :{BLACK}Timetabling full-load orders is not recommended
|
||||||
STR_TIMETABLE_WARNING_AUTOFILL_CONDITIONAL :{BLACK}Autofill will only update taken branch of conditional orders.
|
STR_TIMETABLE_WARNING_AUTOFILL_CONDITIONAL :{BLACK}Autofill will only update taken branch of conditional orders
|
||||||
STR_TIMETABLE_NON_TIMETABLED_BRANCH :{BLACK}Not all conditional order branch-taken travel times are timetabled.
|
STR_TIMETABLE_NON_TIMETABLED_BRANCH :{BLACK}Not all conditional order branch-taken travel times are timetabled
|
||||||
STR_TIMETABLE_WARNING_NO_SCHEDULED_DISPATCH_ORDER :{BLACK}No order is suitable for use with scheduled dispatch.
|
STR_TIMETABLE_WARNING_NO_SCHEDULED_DISPATCH_ORDER_ASSIGNED :{BLACK}The dispatch schedule is not assigned to an order
|
||||||
STR_TIMETABLE_WARNING_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME :{BLACK}The scheduled dispatch order should have a timetabled wait time.
|
STR_TIMETABLE_WARNING_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME :{BLACK}The scheduled dispatch order should have a timetabled wait time
|
||||||
|
STR_TIMETABLE_WARNING_SCHEDULE_ID :{BLACK}Schedule {NUM}: {STRING}
|
||||||
|
|
||||||
# Date window (for timetable)
|
# Date window (for timetable)
|
||||||
STR_DATE_CAPTION :{WHITE}Set date
|
STR_DATE_CAPTION :{WHITE}Set date
|
||||||
@@ -7115,7 +7122,17 @@ STR_SCHDISPATCH_RESET_LAST_DISPATCH_TOOLTIP :{BLACK}Reset wh
|
|||||||
STR_SCHDISPATCH_CLEAR :{BLACK}Clear Departure Slots
|
STR_SCHDISPATCH_CLEAR :{BLACK}Clear Departure Slots
|
||||||
STR_SCHDISPATCH_CLEAR_TOOLTIP :{BLACK}Clear all departure slots from the schedule.
|
STR_SCHDISPATCH_CLEAR_TOOLTIP :{BLACK}Clear all departure slots from the schedule.
|
||||||
STR_SCHDISPATCH_MANAGE :{BLACK}Manage Schedule
|
STR_SCHDISPATCH_MANAGE :{BLACK}Manage Schedule
|
||||||
STR_SCHDISPATCH_MANAGE_TOOLTIP :{STRING}{}{}{STRING}
|
STR_SCHDISPATCH_MANAGE_TOOLTIP :{STRING}{}{}{STRING}{}{}{STRING}
|
||||||
|
STR_SCHDISPATCH_PREV_SCHEDULE :{BLACK}Previous
|
||||||
|
STR_SCHDISPATCH_PREV_SCHEDULE_TOOLTIP :{BLACK}Go to previous dispatch schedule
|
||||||
|
STR_SCHDISPATCH_NEXT_SCHEDULE :{BLACK}Next
|
||||||
|
STR_SCHDISPATCH_NEXT_SCHEDULE_TOOLTIP :{BLACK}Go to next dispatch schedule
|
||||||
|
STR_SCHDISPATCH_ADD_SCHEDULE :{BLACK}Add
|
||||||
|
STR_SCHDISPATCH_ADD_SCHEDULE_TOOLTIP :{BLACK}Add a new dispatch schedule
|
||||||
|
STR_SCHDISPATCH_REMOVE_SCHEDULE :{BLACK}Remove Current Schedule
|
||||||
|
STR_SCHDISPATCH_REMOVE_SCHEDULE_TOOLTIP :{BLACK}Remove this dispatch schedule entirely.
|
||||||
|
STR_SCHDISPATCH_NO_SCHEDULES :{BLACK}No Schedules
|
||||||
|
STR_SCHDISPATCH_SCHEDULE_ID :{BLACK}Schedule {NUM} of {NUM}
|
||||||
|
|
||||||
STR_SCHDISPATCH_SUMMARY_LAST_DEPARTURE_PAST :{BLACK}Last departure at {DATE_WALLCLOCK_TINY}.
|
STR_SCHDISPATCH_SUMMARY_LAST_DEPARTURE_PAST :{BLACK}Last departure at {DATE_WALLCLOCK_TINY}.
|
||||||
STR_SCHDISPATCH_SUMMARY_LAST_DEPARTURE_FUTURE :{BLACK}Last departure has not left yet, it will depart at {DATE_WALLCLOCK_TINY}.
|
STR_SCHDISPATCH_SUMMARY_LAST_DEPARTURE_FUTURE :{BLACK}Last departure has not left yet, it will depart at {DATE_WALLCLOCK_TINY}.
|
||||||
|
@@ -6681,8 +6681,8 @@ STR_TIMETABLE_AUTO_SEPARATION :{BLACK}Auto Sep
|
|||||||
STR_TIMETABLE_AUTO_SEPARATION_TOOLTIP :{BLACK}Automáticamente axusta a hora de comezo dos horarios para asegurar a separación dos vehículos
|
STR_TIMETABLE_AUTO_SEPARATION_TOOLTIP :{BLACK}Automáticamente axusta a hora de comezo dos horarios para asegurar a separación dos vehículos
|
||||||
STR_TIMETABLE_SCHEDULED_DISPATCH :{BLACK}Saída programada
|
STR_TIMETABLE_SCHEDULED_DISPATCH :{BLACK}Saída programada
|
||||||
STR_TIMETABLE_SCHEDULED_DISPATCH_TOOLTIP :{BLACK}Abrir fiestras de saídas programadas para configurar automáticamente a hora de inicio dos horarios
|
STR_TIMETABLE_SCHEDULED_DISPATCH_TOOLTIP :{BLACK}Abrir fiestras de saídas programadas para configurar automáticamente a hora de inicio dos horarios
|
||||||
STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER :[saída programada]
|
STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER :[{STRING}saída programada]
|
||||||
STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME :{PUSH_COLOUR}{RED}[saída programadda - sen tempo de espera no horario]{POP_COLOUR}
|
STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME :{PUSH_COLOUR}{RED}[{STRING}saída programadda - sen tempo de espera no horario]{POP_COLOUR}
|
||||||
STR_TIMETABLE_LOCK_ORDER_TIME_TOOLTIP :{BLACK}Bloquear/desbloquear a cantidade de tempo para a orde resaltada (Ctrl+Click fixa o estado de bloqueo para todas as ordes).{}Cando estea bloqueado, a hora non se modificará mediante o autocompletado ou automatización do horario.
|
STR_TIMETABLE_LOCK_ORDER_TIME_TOOLTIP :{BLACK}Bloquear/desbloquear a cantidade de tempo para a orde resaltada (Ctrl+Click fixa o estado de bloqueo para todas as ordes).{}Cando estea bloqueado, a hora non se modificará mediante o autocompletado ou automatización do horario.
|
||||||
STR_TIMETABLE_LEAVE_EARLY_ORDER :[saír cedo]
|
STR_TIMETABLE_LEAVE_EARLY_ORDER :[saír cedo]
|
||||||
STR_TIMETABLE_LEAVE_EARLY_ORDER_FULL_ANY :[saír cedo se calquera cargamento está cheo]
|
STR_TIMETABLE_LEAVE_EARLY_ORDER_FULL_ANY :[saír cedo se calquera cargamento está cheo]
|
||||||
@@ -6701,7 +6701,6 @@ STR_TIMETABLE_WARNING_AUTOSEP_MISSING_TIMINGS :{BLACK}Non se p
|
|||||||
STR_TIMETABLE_WARNING_FULL_LOAD :{BLACK}Non se recomenda a programación de ordes a carga completa
|
STR_TIMETABLE_WARNING_FULL_LOAD :{BLACK}Non se recomenda a programación de ordes a carga completa
|
||||||
STR_TIMETABLE_WARNING_AUTOFILL_CONDITIONAL :{BLACK}O enchemento automático só actualizará as ordes condicionais da rama escollida
|
STR_TIMETABLE_WARNING_AUTOFILL_CONDITIONAL :{BLACK}O enchemento automático só actualizará as ordes condicionais da rama escollida
|
||||||
STR_TIMETABLE_NON_TIMETABLED_BRANCH :{BLACK}Non todas as ordes da rama condicional escollida están programadas.
|
STR_TIMETABLE_NON_TIMETABLED_BRANCH :{BLACK}Non todas as ordes da rama condicional escollida están programadas.
|
||||||
STR_TIMETABLE_WARNING_NO_SCHEDULED_DISPATCH_ORDER :{BLACK}Non hai unha orde axeitada para usar coa saída programada.
|
|
||||||
STR_TIMETABLE_WARNING_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME :{BLACK}A orde de saída programada debería ter un temepo de espera programado.
|
STR_TIMETABLE_WARNING_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME :{BLACK}A orde de saída programada debería ter un temepo de espera programado.
|
||||||
|
|
||||||
STR_DATE_MINUTES_MINUTE_TOOLTIP :{BLACK}Seleccionar minuto
|
STR_DATE_MINUTES_MINUTE_TOOLTIP :{BLACK}Seleccionar minuto
|
||||||
|
@@ -5479,8 +5479,8 @@ STR_TIMETABLE_AUTO_SEPARATION_TOOLTIP :{BLACK}Passt au
|
|||||||
|
|
||||||
STR_TIMETABLE_SCHEDULED_DISPATCH :{BLACK}Geplante Beförderung
|
STR_TIMETABLE_SCHEDULED_DISPATCH :{BLACK}Geplante Beförderung
|
||||||
STR_TIMETABLE_SCHEDULED_DISPATCH_TOOLTIP :{BLACK}Öffnet das Fenster für die geplante Beförderung, um den Beginn des Fahrplans automatisch zu setzen
|
STR_TIMETABLE_SCHEDULED_DISPATCH_TOOLTIP :{BLACK}Öffnet das Fenster für die geplante Beförderung, um den Beginn des Fahrplans automatisch zu setzen
|
||||||
STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER :[Geplante Beförderung]
|
STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER :[{STRING}Geplante Beförderung]
|
||||||
STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME :{PUSH_COLOUR}{RED}[Geplante Beförderung - keine Wartezeit geplant]{POP_COLOUR}
|
STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME :{PUSH_COLOUR}{RED}[{STRING}Geplante Beförderung - keine Wartezeit geplant]{POP_COLOUR}
|
||||||
|
|
||||||
STR_TIMETABLE_EXPECTED :{BLACK}Voraussichtlich
|
STR_TIMETABLE_EXPECTED :{BLACK}Voraussichtlich
|
||||||
STR_TIMETABLE_SCHEDULED :{BLACK}Fahrplanmäßig
|
STR_TIMETABLE_SCHEDULED :{BLACK}Fahrplanmäßig
|
||||||
@@ -5510,7 +5510,6 @@ STR_TIMETABLE_WARNING_AUTOSEP_MISSING_TIMINGS :{BLACK}Kann Fah
|
|||||||
STR_TIMETABLE_WARNING_FULL_LOAD :{BLACK}Volllade-Aufträge zu planen ist nicht empfohlen
|
STR_TIMETABLE_WARNING_FULL_LOAD :{BLACK}Volllade-Aufträge zu planen ist nicht empfohlen
|
||||||
STR_TIMETABLE_WARNING_AUTOFILL_CONDITIONAL :{BLACK}Es werden nur bedingte Sprünge erfasst, die genommen wurden
|
STR_TIMETABLE_WARNING_AUTOFILL_CONDITIONAL :{BLACK}Es werden nur bedingte Sprünge erfasst, die genommen wurden
|
||||||
STR_TIMETABLE_NON_TIMETABLED_BRANCH :{BLACK}Nicht alle Reisezeiten der bedingten Sprünge sind geplant
|
STR_TIMETABLE_NON_TIMETABLED_BRANCH :{BLACK}Nicht alle Reisezeiten der bedingten Sprünge sind geplant
|
||||||
STR_TIMETABLE_WARNING_NO_SCHEDULED_DISPATCH_ORDER :{BLACK}Kein Auftrag ist geeignet für die Nutzung der geplanten Beförderung
|
|
||||||
STR_TIMETABLE_WARNING_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME :{BLACK}Der geplant beförderte Auftrag sollte eine geplante Wartezeit haben
|
STR_TIMETABLE_WARNING_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME :{BLACK}Der geplant beförderte Auftrag sollte eine geplante Wartezeit haben
|
||||||
|
|
||||||
# Date window (for timetable)
|
# Date window (for timetable)
|
||||||
|
@@ -5697,8 +5697,8 @@ STR_TIMETABLE_AUTO_SEPARATION_TOOLTIP :{BLACK}시간
|
|||||||
|
|
||||||
STR_TIMETABLE_SCHEDULED_DISPATCH :{BLACK}배차 일정
|
STR_TIMETABLE_SCHEDULED_DISPATCH :{BLACK}배차 일정
|
||||||
STR_TIMETABLE_SCHEDULED_DISPATCH_TOOLTIP :{BLACK}시간표 시작 시간 자동 설정을 위한 '배차 일정' 창을 엽니다.
|
STR_TIMETABLE_SCHEDULED_DISPATCH_TOOLTIP :{BLACK}시간표 시작 시간 자동 설정을 위한 '배차 일정' 창을 엽니다.
|
||||||
STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER :[배차 기준]
|
STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER :[배{STRING}차 기준]
|
||||||
STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME :{PUSH_COLOUR}{RED}[배차 기준 - 대기 시간표가 작성되지 않음]{POP_COLOUR}
|
STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME :{PUSH_COLOUR}{RED}[{STRING}배차 기준 - 대기 시간표가 작성되지 않음]{POP_COLOUR}
|
||||||
|
|
||||||
STR_TIMETABLE_EXPECTED :{BLACK}예정일 기준
|
STR_TIMETABLE_EXPECTED :{BLACK}예정일 기준
|
||||||
STR_TIMETABLE_SCHEDULED :{BLACK}예정 소요시간 기준
|
STR_TIMETABLE_SCHEDULED :{BLACK}예정 소요시간 기준
|
||||||
@@ -5728,7 +5728,6 @@ STR_TIMETABLE_WARNING_AUTOSEP_MISSING_TIMINGS :{BLACK}자동
|
|||||||
STR_TIMETABLE_WARNING_FULL_LOAD :{BLACK}'가득 싣기'가 설정되어 있는 경로에 시간표를 지정하는 것은 권장하지 않습니다.
|
STR_TIMETABLE_WARNING_FULL_LOAD :{BLACK}'가득 싣기'가 설정되어 있는 경로에 시간표를 지정하는 것은 권장하지 않습니다.
|
||||||
STR_TIMETABLE_WARNING_AUTOFILL_CONDITIONAL :{BLACK}자동 시간 설정은 조건부 경로 중 한 경로만 채울 것입니다.
|
STR_TIMETABLE_WARNING_AUTOFILL_CONDITIONAL :{BLACK}자동 시간 설정은 조건부 경로 중 한 경로만 채울 것입니다.
|
||||||
STR_TIMETABLE_NON_TIMETABLED_BRANCH :{BLACK}하나 이상의 조건부 경로 운행 시간이 채워지지 않았습니다.
|
STR_TIMETABLE_NON_TIMETABLED_BRANCH :{BLACK}하나 이상의 조건부 경로 운행 시간이 채워지지 않았습니다.
|
||||||
STR_TIMETABLE_WARNING_NO_SCHEDULED_DISPATCH_ORDER :{BLACK}배차 일정을 사용하기에 적합한 경로가 존재하지 않습니다.
|
|
||||||
STR_TIMETABLE_WARNING_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME :{BLACK}배차 기준은 대기 시간이 작성되어 있어야 합니다.
|
STR_TIMETABLE_WARNING_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME :{BLACK}배차 기준은 대기 시간이 작성되어 있어야 합니다.
|
||||||
|
|
||||||
# Date window (for timetable)
|
# Date window (for timetable)
|
||||||
@@ -7111,7 +7110,7 @@ STR_SCHDISPATCH_RESET_LAST_DISPATCH_TOOLTIP :{BLACK}최근
|
|||||||
STR_SCHDISPATCH_CLEAR :{BLACK}출발 슬롯 초기화
|
STR_SCHDISPATCH_CLEAR :{BLACK}출발 슬롯 초기화
|
||||||
STR_SCHDISPATCH_CLEAR_TOOLTIP :{BLACK}일정에서 모든 출발 슬롯을 제거합니다.
|
STR_SCHDISPATCH_CLEAR_TOOLTIP :{BLACK}일정에서 모든 출발 슬롯을 제거합니다.
|
||||||
STR_SCHDISPATCH_MANAGE :{BLACK}일정 관리
|
STR_SCHDISPATCH_MANAGE :{BLACK}일정 관리
|
||||||
STR_SCHDISPATCH_MANAGE_TOOLTIP :{STRING}{}{}{STRING}
|
STR_SCHDISPATCH_MANAGE_TOOLTIP :{STRING}{}{}{STRING}{}{}{STRING}
|
||||||
|
|
||||||
STR_SCHDISPATCH_SUMMARY_LAST_DEPARTURE_PAST :{BLACK}최근 출발: {DATE_WALLCLOCK_TINY}
|
STR_SCHDISPATCH_SUMMARY_LAST_DEPARTURE_PAST :{BLACK}최근 출발: {DATE_WALLCLOCK_TINY}
|
||||||
STR_SCHDISPATCH_SUMMARY_LAST_DEPARTURE_FUTURE :{BLACK}최근 배차된 열차가 아직 출발하지 않았습니다. {DATE_WALLCLOCK_TINY}에 출발할 예정입니다.
|
STR_SCHDISPATCH_SUMMARY_LAST_DEPARTURE_FUTURE :{BLACK}최근 배차된 열차가 아직 출발하지 않았습니다. {DATE_WALLCLOCK_TINY}에 출발할 예정입니다.
|
||||||
|
@@ -69,11 +69,7 @@ OrderBackup::OrderBackup(const Vehicle *v, uint32 user)
|
|||||||
|
|
||||||
if (v->orders.list != nullptr && HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH)) {
|
if (v->orders.list != nullptr && HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH)) {
|
||||||
SetBit(this->vehicle_flags, VF_SCHEDULED_DISPATCH);
|
SetBit(this->vehicle_flags, VF_SCHEDULED_DISPATCH);
|
||||||
this->scheduled_dispatch = v->orders.list->GetScheduledDispatch();
|
this->dispatch_schedules = v->orders.list->GetScheduledDispatchScheduleSet();
|
||||||
this->scheduled_dispatch_duration = v->orders.list->GetScheduledDispatchDuration();
|
|
||||||
this->scheduled_dispatch_start_date = v->orders.list->GetScheduledDispatchStartDatePart();
|
|
||||||
this->scheduled_dispatch_start_full_date_fract = v->orders.list->GetScheduledDispatchStartDateFractPart();
|
|
||||||
this->scheduled_dispatch_max_delay = v->orders.list->GetScheduledDispatchDelay();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,12 +91,7 @@ void OrderBackup::DoRestore(Vehicle *v)
|
|||||||
|
|
||||||
if (HasBit(this->vehicle_flags, VF_SCHEDULED_DISPATCH)) {
|
if (HasBit(this->vehicle_flags, VF_SCHEDULED_DISPATCH)) {
|
||||||
SetBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH);
|
SetBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH);
|
||||||
v->orders.list->SetScheduledDispatchDuration(this->scheduled_dispatch_duration);
|
v->orders.list->GetScheduledDispatchScheduleSet() = std::move(this->dispatch_schedules);
|
||||||
v->orders.list->SetScheduledDispatchDelay(this->scheduled_dispatch_max_delay);
|
|
||||||
v->orders.list->SetScheduledDispatchStartDate(this->scheduled_dispatch_start_date,
|
|
||||||
this->scheduled_dispatch_start_full_date_fract);
|
|
||||||
v->orders.list->SetScheduledDispatchLastDispatch(0);
|
|
||||||
v->orders.list->SetScheduledDispatch(std::move(this->scheduled_dispatch));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure buoys/oil rigs are updated in the station list. */
|
/* Make sure buoys/oil rigs are updated in the station list. */
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
#include "tile_type.h"
|
#include "tile_type.h"
|
||||||
#include "vehicle_type.h"
|
#include "vehicle_type.h"
|
||||||
#include "base_consist.h"
|
#include "base_consist.h"
|
||||||
|
#include "order_base.h"
|
||||||
#include "saveload/saveload_common.h"
|
#include "saveload/saveload_common.h"
|
||||||
|
|
||||||
/** Unique identifier for an order backup. */
|
/** Unique identifier for an order backup. */
|
||||||
@@ -43,6 +44,7 @@ private:
|
|||||||
friend SaveLoadTable GetOrderBackupDescription(); ///< Saving and loading of order backups.
|
friend SaveLoadTable GetOrderBackupDescription(); ///< Saving and loading of order backups.
|
||||||
friend upstream_sl::SaveLoadTable upstream_sl::GetOrderBackupDescription(); ///< Saving and loading of order backups.
|
friend upstream_sl::SaveLoadTable upstream_sl::GetOrderBackupDescription(); ///< Saving and loading of order backups.
|
||||||
friend void Load_BKOR(); ///< Creating empty orders upon savegame loading.
|
friend void Load_BKOR(); ///< Creating empty orders upon savegame loading.
|
||||||
|
friend void Save_BKOR(); ///< Saving orders upon savegame saving.
|
||||||
friend upstream_sl::BKORChunkHandler;
|
friend upstream_sl::BKORChunkHandler;
|
||||||
uint32 user; ///< The user that requested the backup.
|
uint32 user; ///< The user that requested the backup.
|
||||||
TileIndex tile; ///< Tile of the depot where the order was changed.
|
TileIndex tile; ///< Tile of the depot where the order was changed.
|
||||||
@@ -51,12 +53,7 @@ private:
|
|||||||
const Vehicle *clone; ///< Vehicle this vehicle was a clone of.
|
const Vehicle *clone; ///< Vehicle this vehicle was a clone of.
|
||||||
Order *orders; ///< The actual orders if the vehicle was not a clone.
|
Order *orders; ///< The actual orders if the vehicle was not a clone.
|
||||||
|
|
||||||
std::vector<uint32> scheduled_dispatch; ///< Scheduled dispatch time
|
std::vector<DispatchSchedule> dispatch_schedules; ///< Scheduled dispatch schedules
|
||||||
uint32 scheduled_dispatch_duration; ///< Scheduled dispatch duration
|
|
||||||
Date scheduled_dispatch_start_date; ///< Scheduled dispatch start date
|
|
||||||
uint16 scheduled_dispatch_start_full_date_fract;///< Scheduled dispatch start full date fraction;
|
|
||||||
/// this count to (DAY_TICK * _settings_game.economy.day_length_factor)
|
|
||||||
int32 scheduled_dispatch_max_delay; ///< Maximum allowed delay
|
|
||||||
|
|
||||||
static uint update_counter;
|
static uint update_counter;
|
||||||
|
|
||||||
|
215
src/order_base.h
215
src/order_base.h
@@ -53,6 +53,7 @@ void ClearOrderDestinationRefcountMap();
|
|||||||
struct OrderExtraInfo {
|
struct OrderExtraInfo {
|
||||||
uint8 cargo_type_flags[NUM_CARGO] = {}; ///< Load/unload types for each cargo type.
|
uint8 cargo_type_flags[NUM_CARGO] = {}; ///< Load/unload types for each cargo type.
|
||||||
uint32 xdata = 0; ///< Extra arbitrary data
|
uint32 xdata = 0; ///< Extra arbitrary data
|
||||||
|
uint16 dispatch_index = 0; ///< Scheduled dispatch index + 1
|
||||||
uint8 xflags = 0; ///< Extra flags
|
uint8 xflags = 0; ///< Extra flags
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -526,6 +527,24 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int GetDispatchScheduleIndex() const
|
||||||
|
{
|
||||||
|
return this->extra != nullptr ? (int)this->extra->dispatch_index - 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SetDispatchScheduleIndex(int schedule_index)
|
||||||
|
{
|
||||||
|
if (schedule_index != this->GetDispatchScheduleIndex()) {
|
||||||
|
this->CheckExtraInfoAlloced();
|
||||||
|
this->extra->dispatch_index = (uint16)(schedule_index + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsScheduledDispatchOrder(bool require_wait_timetabled) const
|
||||||
|
{
|
||||||
|
return this->extra != nullptr && this->extra->dispatch_index > 0 && (!require_wait_timetabled || this->IsWaitTimetabled());
|
||||||
|
}
|
||||||
|
|
||||||
void AssignOrder(const Order &other);
|
void AssignOrder(const Order &other);
|
||||||
bool Equals(const Order &other) const;
|
bool Equals(const Order &other) const;
|
||||||
|
|
||||||
@@ -587,6 +606,103 @@ template <typename T, typename F> T CargoMaskValueFilter(CargoTypes &cargo_mask,
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DispatchSchedule {
|
||||||
|
private:
|
||||||
|
friend SaveLoadTable GetDispatchScheduleDescription(); ///< Saving and loading of dispatch schedules
|
||||||
|
|
||||||
|
std::vector<uint32> scheduled_dispatch; ///< Scheduled dispatch time
|
||||||
|
uint32 scheduled_dispatch_duration = 0; ///< Scheduled dispatch duration
|
||||||
|
Date scheduled_dispatch_start_date = -1; ///< Scheduled dispatch start date
|
||||||
|
uint16 scheduled_dispatch_start_full_date_fract = 0; ///< Scheduled dispatch start full date fraction;
|
||||||
|
/// this counts to (DAY_TICK * _settings_game.economy.day_length_factor)
|
||||||
|
int32 scheduled_dispatch_last_dispatch = 0; ///< Last vehicle dispatched offset
|
||||||
|
int32 scheduled_dispatch_max_delay = 0; ///< Maximum allowed delay
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Get the vector of all scheduled dispatch slot
|
||||||
|
* @return first scheduled dispatch
|
||||||
|
*/
|
||||||
|
inline const std::vector<uint32> &GetScheduledDispatch() const { return this->scheduled_dispatch; }
|
||||||
|
|
||||||
|
void SetScheduledDispatch(std::vector<uint32> dispatch_list);
|
||||||
|
void AddScheduledDispatch(uint32 offset);
|
||||||
|
void RemoveScheduledDispatch(uint32 offset);
|
||||||
|
void ClearScheduledDispatch() { this->scheduled_dispatch.clear(); }
|
||||||
|
void UpdateScheduledDispatch();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the scheduled dispatch duration, in scaled tick
|
||||||
|
* @param duration New duration
|
||||||
|
*/
|
||||||
|
inline void SetScheduledDispatchDuration(uint32 duration) { this->scheduled_dispatch_duration = duration; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the scheduled dispatch duration, in scaled tick
|
||||||
|
* @return scheduled dispatch duration
|
||||||
|
*/
|
||||||
|
inline uint32 GetScheduledDispatchDuration() const { return this->scheduled_dispatch_duration; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the scheduled dispatch start
|
||||||
|
* @param start New start date
|
||||||
|
* @param fract New start full date fraction, see \c CmdScheduledDispatchSetStartDate
|
||||||
|
*/
|
||||||
|
inline void SetScheduledDispatchStartDate(Date start_date, uint16 start_full_date_fract)
|
||||||
|
{
|
||||||
|
this->scheduled_dispatch_start_date = start_date;
|
||||||
|
this->scheduled_dispatch_start_full_date_fract = start_full_date_fract;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the scheduled dispatch start date part
|
||||||
|
* @return scheduled dispatch start date part
|
||||||
|
*/
|
||||||
|
inline Date GetScheduledDispatchStartDatePart() const { return this->scheduled_dispatch_start_date; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the scheduled dispatch start date fract part
|
||||||
|
* @return scheduled dispatch start date fract part
|
||||||
|
*/
|
||||||
|
inline uint16 GetScheduledDispatchStartDateFractPart() const { return this->scheduled_dispatch_start_full_date_fract; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the scheduled dispatch start date, in absolute scaled tick
|
||||||
|
* @return scheduled dispatch start date
|
||||||
|
*/
|
||||||
|
inline DateTicksScaled GetScheduledDispatchStartTick() const { return SchdispatchConvertToScaledTick(this->scheduled_dispatch_start_date, this->scheduled_dispatch_start_full_date_fract); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the scheduled dispatch setting is valid
|
||||||
|
* @return scheduled dispatch start date fraction
|
||||||
|
*/
|
||||||
|
inline bool IsScheduledDispatchValid() const { return this->scheduled_dispatch_start_date >= 0 && this->scheduled_dispatch_duration > 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the scheduled dispatch last dispatch offset, in scaled tick
|
||||||
|
* @param duration New last dispatch offset
|
||||||
|
*/
|
||||||
|
inline void SetScheduledDispatchLastDispatch(int32 offset) { this->scheduled_dispatch_last_dispatch = offset; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the scheduled dispatch last dispatch offset, in scaled tick
|
||||||
|
* @return scheduled dispatch last dispatch
|
||||||
|
*/
|
||||||
|
inline int32 GetScheduledDispatchLastDispatch() const { return this->scheduled_dispatch_last_dispatch; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the scheduled dispatch maximum allowed delay, in scaled tick
|
||||||
|
* @param delay New maximum allow delay
|
||||||
|
*/
|
||||||
|
inline void SetScheduledDispatchDelay(int32 delay) { this->scheduled_dispatch_max_delay = delay; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the scheduled dispatch maximum alowed delay, in scaled tick
|
||||||
|
* @return scheduled dispatch last dispatch
|
||||||
|
*/
|
||||||
|
inline int32 GetScheduledDispatchDelay() const { return this->scheduled_dispatch_max_delay; }
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shared order list linking together the linked list of orders and the list
|
* Shared order list linking together the linked list of orders and the list
|
||||||
* of vehicles sharing this order list.
|
* of vehicles sharing this order list.
|
||||||
@@ -611,21 +727,13 @@ private:
|
|||||||
Ticks timetable_duration; ///< NOSAVE: Total timetabled duration of the order list.
|
Ticks timetable_duration; ///< NOSAVE: Total timetabled duration of the order list.
|
||||||
Ticks total_duration; ///< NOSAVE: Total (timetabled or not) duration of the order list.
|
Ticks total_duration; ///< NOSAVE: Total (timetabled or not) duration of the order list.
|
||||||
|
|
||||||
std::vector<uint32> scheduled_dispatch; ///< Scheduled dispatch time
|
std::vector<DispatchSchedule> dispatch_schedules; ///< Scheduled dispatch schedules
|
||||||
uint32 scheduled_dispatch_duration; ///< Scheduled dispatch duration
|
|
||||||
Date scheduled_dispatch_start_date; ///< Scheduled dispatch start date
|
|
||||||
uint16 scheduled_dispatch_start_full_date_fract;///< Scheduled dispatch start full date fraction;
|
|
||||||
/// this count to (DAY_TICK * _settings_game.economy.day_length_factor)
|
|
||||||
int32 scheduled_dispatch_last_dispatch; ///< Last vehicle dispatched offset
|
|
||||||
int32 scheduled_dispatch_max_delay; ///< Maximum allowed delay
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Default constructor producing an invalid order list. */
|
/** Default constructor producing an invalid order list. */
|
||||||
OrderList(VehicleOrderID num_orders = INVALID_VEH_ORDER_ID)
|
OrderList(VehicleOrderID num_orders = INVALID_VEH_ORDER_ID)
|
||||||
: first(nullptr), num_manual_orders(0), num_vehicles(0), first_shared(nullptr),
|
: first(nullptr), num_manual_orders(0), num_vehicles(0), first_shared(nullptr),
|
||||||
timetable_duration(0), total_duration(0), scheduled_dispatch_duration(0),
|
timetable_duration(0), total_duration(0) { }
|
||||||
scheduled_dispatch_start_date(-1), scheduled_dispatch_start_full_date_fract(0),
|
|
||||||
scheduled_dispatch_last_dispatch(0), scheduled_dispatch_max_delay(0) { }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an order list with the given order chain for the given vehicle.
|
* Create an order list with the given order chain for the given vehicle.
|
||||||
@@ -752,90 +860,13 @@ public:
|
|||||||
void DebugCheckSanity() const;
|
void DebugCheckSanity() const;
|
||||||
bool CheckOrderListIndexing() const;
|
bool CheckOrderListIndexing() const;
|
||||||
|
|
||||||
/**
|
inline std::vector<DispatchSchedule> &GetScheduledDispatchScheduleSet() { return this->dispatch_schedules; }
|
||||||
* Get the vector of all scheduled dispatch slot
|
inline const std::vector<DispatchSchedule> &GetScheduledDispatchScheduleSet() const { return this->dispatch_schedules; }
|
||||||
* @return first scheduled dispatch
|
|
||||||
*/
|
|
||||||
inline const std::vector<uint32> &GetScheduledDispatch() const { return this->scheduled_dispatch; }
|
|
||||||
|
|
||||||
void SetScheduledDispatch(std::vector<uint32> dispatch_list);
|
inline uint GetScheduledDispatchScheduleCount() const { return (uint)this->dispatch_schedules.size(); }
|
||||||
void AddScheduledDispatch(uint32 offset);
|
|
||||||
void RemoveScheduledDispatch(uint32 offset);
|
|
||||||
void ClearScheduledDispatch() { this->scheduled_dispatch.clear(); }
|
|
||||||
void UpdateScheduledDispatch();
|
|
||||||
void ResetScheduledDispatch();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the scheduled dispatch duration, in scaled tick
|
|
||||||
* @param duration New duration
|
|
||||||
*/
|
|
||||||
inline void SetScheduledDispatchDuration(uint32 duration) { this->scheduled_dispatch_duration = duration; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the scheduled dispatch duration, in scaled tick
|
|
||||||
* @return scheduled dispatch duration
|
|
||||||
*/
|
|
||||||
inline uint32 GetScheduledDispatchDuration() const { return this->scheduled_dispatch_duration; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the scheduled dispatch start
|
|
||||||
* @param start New start date
|
|
||||||
* @param fract New start full date fraction, see \c CmdScheduledDispatchSetStartDate
|
|
||||||
*/
|
|
||||||
inline void SetScheduledDispatchStartDate(Date start_date, uint16 start_full_date_fract)
|
|
||||||
{
|
|
||||||
this->scheduled_dispatch_start_date = start_date;
|
|
||||||
this->scheduled_dispatch_start_full_date_fract = start_full_date_fract;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the scheduled dispatch start date part
|
|
||||||
* @return scheduled dispatch start date part
|
|
||||||
*/
|
|
||||||
inline Date GetScheduledDispatchStartDatePart() const { return this->scheduled_dispatch_start_date; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the scheduled dispatch start date fract part
|
|
||||||
* @return scheduled dispatch start date fract part
|
|
||||||
*/
|
|
||||||
inline uint16 GetScheduledDispatchStartDateFractPart() const { return this->scheduled_dispatch_start_full_date_fract; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the scheduled dispatch start date, in absolute scaled tick
|
|
||||||
* @return scheduled dispatch start date
|
|
||||||
*/
|
|
||||||
inline DateTicksScaled GetScheduledDispatchStartTick() const { return SchdispatchConvertToScaledTick(this->scheduled_dispatch_start_date, this->scheduled_dispatch_start_full_date_fract); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the scheduled dispatch setting is valid
|
|
||||||
* @return scheduled dispatch start date fraction
|
|
||||||
*/
|
|
||||||
inline bool IsScheduledDispatchValid() const { return this->scheduled_dispatch_start_date >= 0 && this->scheduled_dispatch_duration > 0; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the scheduled dispatch last dispatch offset, in scaled tick
|
|
||||||
* @param duration New last dispatch offset
|
|
||||||
*/
|
|
||||||
inline void SetScheduledDispatchLastDispatch(int32 offset) { this->scheduled_dispatch_last_dispatch = offset; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the scheduled dispatch last dispatch offset, in scaled tick
|
|
||||||
* @return scheduled dispatch last dispatch
|
|
||||||
*/
|
|
||||||
inline int32 GetScheduledDispatchLastDispatch() const { return this->scheduled_dispatch_last_dispatch; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the scheduled dispatch maximum allowed delay, in scaled tick
|
|
||||||
* @param delay New maximum allow delay
|
|
||||||
*/
|
|
||||||
inline void SetScheduledDispatchDelay(int32 delay) { this->scheduled_dispatch_max_delay = delay; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the scheduled dispatch maximum alowed delay, in scaled tick
|
|
||||||
* @return scheduled dispatch last dispatch
|
|
||||||
*/
|
|
||||||
inline int32 GetScheduledDispatchDelay() const { return this->scheduled_dispatch_max_delay; }
|
|
||||||
|
|
||||||
|
inline DispatchSchedule &GetDispatchScheduleByIndex(uint index) { return this->dispatch_schedules[index]; }
|
||||||
|
inline const DispatchSchedule &GetDispatchScheduleByIndex(uint index) const { return this->dispatch_schedules[index]; }
|
||||||
};
|
};
|
||||||
|
|
||||||
void ShiftOrderDates(int interval);
|
void ShiftOrderDates(int interval);
|
||||||
|
@@ -370,7 +370,7 @@ void Order::AssignOrder(const Order &other)
|
|||||||
this->travel_time = other.travel_time;
|
this->travel_time = other.travel_time;
|
||||||
this->max_speed = other.max_speed;
|
this->max_speed = other.max_speed;
|
||||||
|
|
||||||
if (other.extra != nullptr && (this->GetUnloadType() == OUFB_CARGO_TYPE_UNLOAD || this->GetLoadType() == OLFB_CARGO_TYPE_LOAD || other.extra->xdata != 0 || other.extra->xflags != 0)) {
|
if (other.extra != nullptr && (this->GetUnloadType() == OUFB_CARGO_TYPE_UNLOAD || this->GetLoadType() == OLFB_CARGO_TYPE_LOAD || other.extra->xdata != 0 || other.extra->xflags != 0 || other.extra->dispatch_index != 0)) {
|
||||||
this->AllocExtraInfo();
|
this->AllocExtraInfo();
|
||||||
*(this->extra) = *(other.extra);
|
*(this->extra) = *(other.extra);
|
||||||
} else {
|
} else {
|
||||||
@@ -1894,6 +1894,9 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
|
|||||||
if (order->IsWaitTimetabled() || order->GetWaitTime() > 0) {
|
if (order->IsWaitTimetabled() || order->GetWaitTime() > 0) {
|
||||||
DoCommandEx(tile, v->index | (MTF_WAIT_TIME << 28) | (1 << 31), 0, p3, flags, CMD_CHANGE_TIMETABLE);
|
DoCommandEx(tile, v->index | (MTF_WAIT_TIME << 28) | (1 << 31), 0, p3, flags, CMD_CHANGE_TIMETABLE);
|
||||||
}
|
}
|
||||||
|
if (order->IsScheduledDispatchOrder(false)) {
|
||||||
|
DoCommandEx(tile, v->index | (MTF_ASSIGN_SCHEDULE << 28), -1, p3, flags, CMD_CHANGE_TIMETABLE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -2390,12 +2393,7 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
|||||||
/* Copy over scheduled dispatch data */
|
/* Copy over scheduled dispatch data */
|
||||||
assert(dst->orders.list != nullptr);
|
assert(dst->orders.list != nullptr);
|
||||||
if (src->orders.list != nullptr) {
|
if (src->orders.list != nullptr) {
|
||||||
dst->orders.list->SetScheduledDispatchDuration(src->orders.list->GetScheduledDispatchDuration());
|
dst->orders.list->GetScheduledDispatchScheduleSet() = src->orders.list->GetScheduledDispatchScheduleSet();
|
||||||
dst->orders.list->SetScheduledDispatchDelay(src->orders.list->GetScheduledDispatchDelay());
|
|
||||||
dst->orders.list->SetScheduledDispatchStartDate(src->orders.list->GetScheduledDispatchStartDatePart(),
|
|
||||||
src->orders.list->GetScheduledDispatchStartDateFractPart());
|
|
||||||
dst->orders.list->SetScheduledDispatchLastDispatch(0);
|
|
||||||
dst->orders.list->SetScheduledDispatch(src->orders.list->GetScheduledDispatch());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set automation bit if target has it. */
|
/* Set automation bit if target has it. */
|
||||||
@@ -3223,8 +3221,10 @@ CommandCost CmdMassChangeOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, u
|
|||||||
void ShiftOrderDates(int interval)
|
void ShiftOrderDates(int interval)
|
||||||
{
|
{
|
||||||
for (OrderList *orderlist : OrderList::Iterate()) {
|
for (OrderList *orderlist : OrderList::Iterate()) {
|
||||||
if (orderlist->GetScheduledDispatchStartDatePart() >= 0) {
|
for (DispatchSchedule &ds : orderlist->GetScheduledDispatchScheduleSet()) {
|
||||||
orderlist->SetScheduledDispatchStartDate(orderlist->GetScheduledDispatchStartDatePart() + interval, orderlist->GetScheduledDispatchStartDateFractPart());
|
if (ds.GetScheduledDispatchStartDatePart() >= 0) {
|
||||||
|
ds.SetScheduledDispatchStartDate(ds.GetScheduledDispatchStartDatePart() + interval, ds.GetScheduledDispatchStartDateFractPart());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1057,8 +1057,10 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
|
|||||||
if (timetable && timetable_wait_time_valid && order->GetLeaveType() != OLT_NORMAL && edge != 0) {
|
if (timetable && timetable_wait_time_valid && order->GetLeaveType() != OLT_NORMAL && edge != 0) {
|
||||||
edge = DrawString(rtl ? left : edge + 3, rtl ? edge - 3 : right, y, STR_TIMETABLE_LEAVE_EARLY_ORDER + order->GetLeaveType() - OLT_LEAVE_EARLY, colour);
|
edge = DrawString(rtl ? left : edge + 3, rtl ? edge - 3 : right, y, STR_TIMETABLE_LEAVE_EARLY_ORDER + order->GetLeaveType() - OLT_LEAVE_EARLY, colour);
|
||||||
}
|
}
|
||||||
if (timetable && HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH) && v->GetFirstWaitingLocation(false) == order_index && edge != 0) {
|
if (timetable && HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH) && order->IsScheduledDispatchOrder(false) && edge != 0) {
|
||||||
StringID str = order->IsWaitTimetabled() ? STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER : STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME;
|
StringID str = order->IsWaitTimetabled() ? STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER : STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME;
|
||||||
|
SetDParam(0, v->orders.list->GetScheduledDispatchScheduleCount() > 1 ? STR_TIMETABLE_SCHEDULED_DISPATCH_ORDER_SCHEDULE_INDEX : STR_EMPTY);
|
||||||
|
SetDParam(1, order->GetDispatchScheduleIndex() + 1);
|
||||||
edge = DrawString(rtl ? left : edge + 3, rtl ? edge - 3 : right, y, str, colour);
|
edge = DrawString(rtl ? left : edge + 3, rtl ? edge - 3 : right, y, str, colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -238,6 +238,7 @@ enum ModifyTimetableFlags {
|
|||||||
MTF_SET_WAIT_FIXED,///< Set wait time fixed flag state.
|
MTF_SET_WAIT_FIXED,///< Set wait time fixed flag state.
|
||||||
MTF_SET_TRAVEL_FIXED,///< Set travel time fixed flag state.
|
MTF_SET_TRAVEL_FIXED,///< Set travel time fixed flag state.
|
||||||
MTF_SET_LEAVE_TYPE,///< Passes an OrderLeaveType.
|
MTF_SET_LEAVE_TYPE,///< Passes an OrderLeaveType.
|
||||||
|
MTF_ASSIGN_SCHEDULE, ///< Assign a dispatch schedule.
|
||||||
MTF_END
|
MTF_END
|
||||||
};
|
};
|
||||||
template <> struct EnumPropsT<ModifyTimetableFlags> : MakeEnumPropsT<ModifyTimetableFlags, byte, MTF_WAIT_TIME, MTF_END, MTF_END, 3> {};
|
template <> struct EnumPropsT<ModifyTimetableFlags> : MakeEnumPropsT<ModifyTimetableFlags, byte, MTF_WAIT_TIME, MTF_END, MTF_END, 3> {};
|
||||||
|
@@ -3999,6 +3999,22 @@ bool AfterLoadGame()
|
|||||||
_settings_game.vehicle.through_load_speed_limit = 15;
|
_settings_game.vehicle.through_load_speed_limit = 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 1, 2)) {
|
||||||
|
for (OrderList *order_list : OrderList::Iterate()) {
|
||||||
|
if (order_list->GetScheduledDispatchScheduleCount() == 1) {
|
||||||
|
const DispatchSchedule &ds = order_list->GetDispatchScheduleByIndex(0);
|
||||||
|
if (!ds.IsScheduledDispatchValid() && ds.GetScheduledDispatch().empty()) {
|
||||||
|
order_list->GetScheduledDispatchScheduleSet().clear();
|
||||||
|
} else {
|
||||||
|
VehicleOrderID idx = order_list->GetFirstSharedVehicle()->GetFirstWaitingLocation(false);
|
||||||
|
if (idx != INVALID_VEH_ORDER_ID) {
|
||||||
|
order_list->GetOrderAt(idx)->SetDispatchScheduleIndex(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
InitializeRoadGUI();
|
InitializeRoadGUI();
|
||||||
|
|
||||||
/* This needs to be done after conversion. */
|
/* This needs to be done after conversion. */
|
||||||
|
@@ -109,7 +109,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
|||||||
{ XSLFI_STATION_CATCHMENT_INC, XSCF_NULL, 1, 1, "station_catchment_inc", nullptr, nullptr, nullptr },
|
{ XSLFI_STATION_CATCHMENT_INC, XSCF_NULL, 1, 1, "station_catchment_inc", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_CUSTOM_BRIDGE_HEADS, XSCF_NULL, 4, 4, "custom_bridge_heads", nullptr, nullptr, nullptr },
|
{ XSLFI_CUSTOM_BRIDGE_HEADS, XSCF_NULL, 4, 4, "custom_bridge_heads", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_CHUNNEL, XSCF_NULL, 2, 2, "chunnel", nullptr, nullptr, "TUNN" },
|
{ XSLFI_CHUNNEL, XSCF_NULL, 2, 2, "chunnel", nullptr, nullptr, "TUNN" },
|
||||||
{ XSLFI_SCHEDULED_DISPATCH, XSCF_NULL, 2, 2, "scheduled_dispatch", nullptr, nullptr, nullptr },
|
{ XSLFI_SCHEDULED_DISPATCH, XSCF_NULL, 3, 3, "scheduled_dispatch", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_MORE_TOWN_GROWTH_RATES, XSCF_NULL, 1, 1, "more_town_growth_rates", nullptr, nullptr, nullptr },
|
{ XSLFI_MORE_TOWN_GROWTH_RATES, XSCF_NULL, 1, 1, "more_town_growth_rates", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_MULTIPLE_DOCKS, XSCF_NULL, 2, 2, "multiple_docks", nullptr, nullptr, nullptr },
|
{ XSLFI_MULTIPLE_DOCKS, XSCF_NULL, 2, 2, "multiple_docks", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_TIMETABLE_EXTRA, XSCF_NULL, 7, 7, "timetable_extra", nullptr, nullptr, "ORDX" },
|
{ XSLFI_TIMETABLE_EXTRA, XSCF_NULL, 7, 7, "timetable_extra", nullptr, nullptr, "ORDX" },
|
||||||
|
@@ -217,6 +217,7 @@ const SaveLoadTable GetOrderExtraInfoDescription()
|
|||||||
SLE_CONDARR_X(OrderExtraInfo, cargo_type_flags, SLE_UINT8, NUM_CARGO, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_CARGO_TYPE_ORDERS, 3)),
|
SLE_CONDARR_X(OrderExtraInfo, cargo_type_flags, SLE_UINT8, NUM_CARGO, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_CARGO_TYPE_ORDERS, 3)),
|
||||||
SLE_CONDVAR_X(OrderExtraInfo, xflags, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLE_EXTRA)),
|
SLE_CONDVAR_X(OrderExtraInfo, xflags, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLE_EXTRA)),
|
||||||
SLE_CONDVAR_X(OrderExtraInfo, xdata, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ORDER_EXTRA_DATA)),
|
SLE_CONDVAR_X(OrderExtraInfo, xdata, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ORDER_EXTRA_DATA)),
|
||||||
|
SLE_CONDVAR_X(OrderExtraInfo, dispatch_index, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 3)),
|
||||||
};
|
};
|
||||||
|
|
||||||
return _order_extra_info_desc;
|
return _order_extra_info_desc;
|
||||||
@@ -255,16 +256,24 @@ static void Ptrs_ORDR()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SaveLoadTable GetDispatchScheduleDescription()
|
||||||
|
{
|
||||||
|
static const SaveLoad _order_extra_info_desc[] = {
|
||||||
|
SLE_VARVEC(DispatchSchedule, scheduled_dispatch, SLE_UINT32),
|
||||||
|
SLE_VAR(DispatchSchedule, scheduled_dispatch_duration, SLE_UINT32),
|
||||||
|
SLE_VAR(DispatchSchedule, scheduled_dispatch_start_date, SLE_INT32),
|
||||||
|
SLE_VAR(DispatchSchedule, scheduled_dispatch_start_full_date_fract, SLE_UINT16),
|
||||||
|
SLE_VAR(DispatchSchedule, scheduled_dispatch_last_dispatch, SLE_INT32),
|
||||||
|
SLE_VAR(DispatchSchedule, scheduled_dispatch_max_delay, SLE_INT32),
|
||||||
|
};
|
||||||
|
|
||||||
|
return _order_extra_info_desc;
|
||||||
|
}
|
||||||
|
|
||||||
SaveLoadTable GetOrderListDescription()
|
SaveLoadTable GetOrderListDescription()
|
||||||
{
|
{
|
||||||
static const SaveLoad _orderlist_desc[] = {
|
static const SaveLoad _orderlist_desc[] = {
|
||||||
SLE_REF(OrderList, first, REF_ORDER),
|
SLE_REF(OrderList, first, REF_ORDER),
|
||||||
SLE_CONDVARVEC_X(OrderList, scheduled_dispatch, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH)),
|
|
||||||
SLE_CONDVAR_X(OrderList, scheduled_dispatch_duration, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH)),
|
|
||||||
SLE_CONDVAR_X(OrderList, scheduled_dispatch_start_date, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH)),
|
|
||||||
SLE_CONDVAR_X(OrderList, scheduled_dispatch_start_full_date_fract, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH)),
|
|
||||||
SLE_CONDVAR_X(OrderList, scheduled_dispatch_last_dispatch, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH)),
|
|
||||||
SLE_CONDVAR_X(OrderList, scheduled_dispatch_max_delay, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH)),
|
|
||||||
SLEG_CONDVAR_X(_jokerpp_separation_mode, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)),
|
SLEG_CONDVAR_X(_jokerpp_separation_mode, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)),
|
||||||
SLE_CONDNULL_X(21, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)),
|
SLE_CONDNULL_X(21, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)),
|
||||||
};
|
};
|
||||||
@@ -276,7 +285,14 @@ static void Save_ORDL()
|
|||||||
{
|
{
|
||||||
for (OrderList *list : OrderList::Iterate()) {
|
for (OrderList *list : OrderList::Iterate()) {
|
||||||
SlSetArrayIndex(list->index);
|
SlSetArrayIndex(list->index);
|
||||||
|
SlAutolength([](void *data) {
|
||||||
|
OrderList *list = static_cast<OrderList *>(data);
|
||||||
SlObject(list, GetOrderListDescription());
|
SlObject(list, GetOrderListDescription());
|
||||||
|
SlWriteUint32(list->GetScheduledDispatchScheduleCount());
|
||||||
|
for (DispatchSchedule &ds : list->GetScheduledDispatchScheduleSet()) {
|
||||||
|
SlObject(&ds, GetDispatchScheduleDescription());
|
||||||
|
}
|
||||||
|
}, list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,8 +313,14 @@ static void Load_ORDL()
|
|||||||
_jokerpp_non_auto_separation.push_back(list);
|
_jokerpp_non_auto_separation.push_back(list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH)) {
|
||||||
|
uint count = SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 3) ? SlReadUint32() : 1;
|
||||||
|
list->GetScheduledDispatchScheduleSet().resize(count);
|
||||||
|
for (DispatchSchedule &ds : list->GetScheduledDispatchScheduleSet()) {
|
||||||
|
SlObject(&ds, GetDispatchScheduleDescription());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ptrs_ORDL()
|
void Ptrs_ORDL()
|
||||||
@@ -330,17 +352,13 @@ SaveLoadTable GetOrderBackupDescription()
|
|||||||
SLE_CONDVAR(OrderBackup, vehicle_flags, SLE_FILE_U8 | SLE_VAR_U16, SLV_176, SLV_180),
|
SLE_CONDVAR(OrderBackup, vehicle_flags, SLE_FILE_U8 | SLE_VAR_U16, SLV_176, SLV_180),
|
||||||
SLE_CONDVAR(OrderBackup, vehicle_flags, SLE_UINT16, SLV_180, SL_MAX_VERSION),
|
SLE_CONDVAR(OrderBackup, vehicle_flags, SLE_UINT16, SLV_180, SL_MAX_VERSION),
|
||||||
SLE_REF(OrderBackup, orders, REF_ORDER),
|
SLE_REF(OrderBackup, orders, REF_ORDER),
|
||||||
SLE_CONDVARVEC_X(OrderBackup, scheduled_dispatch, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 2)),
|
SLE_CONDNULL_X(18, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 2, 2)),
|
||||||
SLE_CONDVAR_X(OrderBackup, scheduled_dispatch_duration, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 2)),
|
|
||||||
SLE_CONDVAR_X(OrderBackup, scheduled_dispatch_start_date, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 2)),
|
|
||||||
SLE_CONDVAR_X(OrderBackup, scheduled_dispatch_start_full_date_fract, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 2)),
|
|
||||||
SLE_CONDVAR_X(OrderBackup, scheduled_dispatch_max_delay, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 2)),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return _order_backup_desc;
|
return _order_backup_desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Save_BKOR()
|
void Save_BKOR()
|
||||||
{
|
{
|
||||||
/* We only save this when we're a network server
|
/* We only save this when we're a network server
|
||||||
* as we want this information on our clients. For
|
* as we want this information on our clients. For
|
||||||
@@ -349,7 +367,14 @@ static void Save_BKOR()
|
|||||||
|
|
||||||
for (OrderBackup *ob : OrderBackup::Iterate()) {
|
for (OrderBackup *ob : OrderBackup::Iterate()) {
|
||||||
SlSetArrayIndex(ob->index);
|
SlSetArrayIndex(ob->index);
|
||||||
|
SlAutolength([](void *data) {
|
||||||
|
OrderBackup *ob = static_cast<OrderBackup *>(data);
|
||||||
SlObject(ob, GetOrderBackupDescription());
|
SlObject(ob, GetOrderBackupDescription());
|
||||||
|
SlWriteUint32((uint)ob->dispatch_schedules.size());
|
||||||
|
for (DispatchSchedule &ds : ob->dispatch_schedules) {
|
||||||
|
SlObject(&ds, GetDispatchScheduleDescription());
|
||||||
|
}
|
||||||
|
}, ob);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,6 +386,13 @@ void Load_BKOR()
|
|||||||
/* set num_orders to 0 so it's a valid OrderList */
|
/* set num_orders to 0 so it's a valid OrderList */
|
||||||
OrderBackup *ob = new (index) OrderBackup();
|
OrderBackup *ob = new (index) OrderBackup();
|
||||||
SlObject(ob, GetOrderBackupDescription());
|
SlObject(ob, GetOrderBackupDescription());
|
||||||
|
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 3)) {
|
||||||
|
uint count = SlReadUint32();
|
||||||
|
ob->dispatch_schedules.resize(count);
|
||||||
|
for (DispatchSchedule &ds : ob->dispatch_schedules) {
|
||||||
|
SlObject(&ds, GetDispatchScheduleDescription());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -327,6 +327,14 @@ DECLARE_ENUM_AS_BIT_SET(SaveLoadChunkExtHeaderFlags)
|
|||||||
*/
|
*/
|
||||||
#define SLE_VEC(base, variable, type) SLE_CONDVEC(base, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
|
#define SLE_VEC(base, variable, type) SLE_CONDVEC(base, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Storage of a variable vector in every savegame version.
|
||||||
|
* @param base Name of the class or struct containing the list.
|
||||||
|
* @param variable Name of the variable in the class or struct referenced by \a base.
|
||||||
|
* @param type Storage of the data in memory and in the savegame.
|
||||||
|
*/
|
||||||
|
#define SLE_VARVEC(base, variable, type) SLE_CONDVARVEC(base, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Empty space in every savegame version.
|
* Empty space in every savegame version.
|
||||||
* @param length Length of the empty space.
|
* @param length Length of the empty space.
|
||||||
|
@@ -82,6 +82,7 @@ CommandCost CmdScheduledDispatch(TileIndex tile, DoCommandFlag flags, uint32 p1,
|
|||||||
CommandCost CmdScheduledDispatchAdd(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, uint32 binary_length)
|
CommandCost CmdScheduledDispatchAdd(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, uint32 binary_length)
|
||||||
{
|
{
|
||||||
VehicleID veh = GB(p1, 0, 20);
|
VehicleID veh = GB(p1, 0, 20);
|
||||||
|
uint schedule_index = GB(p1, 20, 12);
|
||||||
uint32 offset = GB(p3, 0, 32);
|
uint32 offset = GB(p3, 0, 32);
|
||||||
uint32 extra_slots = GB(p3, 32, 16);
|
uint32 extra_slots = GB(p3, 32, 16);
|
||||||
|
|
||||||
@@ -93,14 +94,17 @@ CommandCost CmdScheduledDispatchAdd(TileIndex tile, DoCommandFlag flags, uint32
|
|||||||
|
|
||||||
if (v->orders.list == nullptr) return CMD_ERROR;
|
if (v->orders.list == nullptr) return CMD_ERROR;
|
||||||
|
|
||||||
|
if (schedule_index >= v->orders.list->GetScheduledDispatchScheduleCount()) return CMD_ERROR;
|
||||||
|
|
||||||
if (extra_slots > 512) return_cmd_error(STR_ERROR_SCHDISPATCH_TRIED_TO_ADD_TOO_MANY_SLOTS);
|
if (extra_slots > 512) return_cmd_error(STR_ERROR_SCHDISPATCH_TRIED_TO_ADD_TOO_MANY_SLOTS);
|
||||||
if (extra_slots > 0 && offset == 0) return CMD_ERROR;
|
if (extra_slots > 0 && offset == 0) return CMD_ERROR;
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
v->orders.list->AddScheduledDispatch(p2);
|
DispatchSchedule &ds = v->orders.list->GetDispatchScheduleByIndex(schedule_index);
|
||||||
|
ds.AddScheduledDispatch(p2);
|
||||||
for (uint i = 0; i < extra_slots; i++) {
|
for (uint i = 0; i < extra_slots; i++) {
|
||||||
p2 += offset;
|
p2 += offset;
|
||||||
v->orders.list->AddScheduledDispatch(p2);
|
ds.AddScheduledDispatch(p2);
|
||||||
}
|
}
|
||||||
SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index);
|
SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index);
|
||||||
}
|
}
|
||||||
@@ -120,6 +124,7 @@ CommandCost CmdScheduledDispatchAdd(TileIndex tile, DoCommandFlag flags, uint32
|
|||||||
CommandCost CmdScheduledDispatchRemove(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
CommandCost CmdScheduledDispatchRemove(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||||
{
|
{
|
||||||
VehicleID veh = GB(p1, 0, 20);
|
VehicleID veh = GB(p1, 0, 20);
|
||||||
|
uint schedule_index = GB(p1, 20, 12);
|
||||||
|
|
||||||
Vehicle *v = Vehicle::GetIfValid(veh);
|
Vehicle *v = Vehicle::GetIfValid(veh);
|
||||||
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
|
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
|
||||||
@@ -129,8 +134,10 @@ CommandCost CmdScheduledDispatchRemove(TileIndex tile, DoCommandFlag flags, uint
|
|||||||
|
|
||||||
if (v->orders.list == nullptr) return CMD_ERROR;
|
if (v->orders.list == nullptr) return CMD_ERROR;
|
||||||
|
|
||||||
|
if (schedule_index >= v->orders.list->GetScheduledDispatchScheduleCount()) return CMD_ERROR;
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
v->orders.list->RemoveScheduledDispatch(p2);
|
v->orders.list->GetDispatchScheduleByIndex(schedule_index).RemoveScheduledDispatch(p2);
|
||||||
SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index);
|
SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,6 +157,7 @@ CommandCost CmdScheduledDispatchRemove(TileIndex tile, DoCommandFlag flags, uint
|
|||||||
CommandCost CmdScheduledDispatchSetDuration(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
CommandCost CmdScheduledDispatchSetDuration(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||||
{
|
{
|
||||||
VehicleID veh = GB(p1, 0, 20);
|
VehicleID veh = GB(p1, 0, 20);
|
||||||
|
uint schedule_index = GB(p1, 20, 12);
|
||||||
|
|
||||||
Vehicle *v = Vehicle::GetIfValid(veh);
|
Vehicle *v = Vehicle::GetIfValid(veh);
|
||||||
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
|
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
|
||||||
@@ -159,9 +167,12 @@ CommandCost CmdScheduledDispatchSetDuration(TileIndex tile, DoCommandFlag flags,
|
|||||||
|
|
||||||
if (v->orders.list == nullptr) return CMD_ERROR;
|
if (v->orders.list == nullptr) return CMD_ERROR;
|
||||||
|
|
||||||
|
if (schedule_index >= v->orders.list->GetScheduledDispatchScheduleCount()) return CMD_ERROR;
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
v->orders.list->SetScheduledDispatchDuration(p2);
|
DispatchSchedule &ds = v->orders.list->GetDispatchScheduleByIndex(schedule_index);
|
||||||
v->orders.list->UpdateScheduledDispatch();
|
ds.SetScheduledDispatchDuration(p2);
|
||||||
|
ds.UpdateScheduledDispatch();
|
||||||
SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index);
|
SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,23 +184,22 @@ CommandCost CmdScheduledDispatchSetDuration(TileIndex tile, DoCommandFlag flags,
|
|||||||
*
|
*
|
||||||
* The parameter is quite tricky. The default maximum of daylength factor is 125,
|
* The parameter is quite tricky. The default maximum of daylength factor is 125,
|
||||||
* and with DAY_TICKS of 74 the result (maximum scaled tick per day) fits in 14 bit.
|
* and with DAY_TICKS of 74 the result (maximum scaled tick per day) fits in 14 bit.
|
||||||
* Vehicle index in p1 takes 20 bit, so we have 12 bit here. The MSB of the fraction is stored here.
|
|
||||||
* The 2-bit LSB is stored in MSB of p2, which is start date. The default date is stored in int32,
|
|
||||||
* which only have topmost bit available. However, if the date reached 31 bits, that means it is over 1,000,000 years,
|
|
||||||
* so I think it is safe to steal another bit here.
|
|
||||||
*
|
*
|
||||||
* See also the static_assert at the top of the file.
|
* See also the static_assert at the top of the file.
|
||||||
*
|
*
|
||||||
* @param tile Not used.
|
* @param tile Not used.
|
||||||
* @param flags Operation to perform.
|
* @param flags Operation to perform.
|
||||||
* @param p1 MSB of Start Full Date Fraction || Vehicle index
|
* @param p1 Vehicle index
|
||||||
* @param p2 LSB of Start Full Date Fraction || Date to add.
|
* @param p2 Date to add.
|
||||||
|
* @param p3 various bitstuffed elements
|
||||||
|
* - p3 = (bit 0 - 15) - Full date fraction
|
||||||
* @param text unused
|
* @param text unused
|
||||||
* @return the cost of this operation or an error
|
* @return the cost of this operation or an error
|
||||||
*/
|
*/
|
||||||
CommandCost CmdScheduledDispatchSetStartDate(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
CommandCost CmdScheduledDispatchSetStartDate(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, uint32 binary_length)
|
||||||
{
|
{
|
||||||
VehicleID veh = GB(p1, 0, 20);
|
VehicleID veh = GB(p1, 0, 20);
|
||||||
|
uint schedule_index = GB(p1, 20, 12);
|
||||||
|
|
||||||
Vehicle *v = Vehicle::GetIfValid(veh);
|
Vehicle *v = Vehicle::GetIfValid(veh);
|
||||||
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
|
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
|
||||||
@@ -199,12 +209,15 @@ CommandCost CmdScheduledDispatchSetStartDate(TileIndex tile, DoCommandFlag flags
|
|||||||
|
|
||||||
if (v->orders.list == nullptr) return CMD_ERROR;
|
if (v->orders.list == nullptr) return CMD_ERROR;
|
||||||
|
|
||||||
int32 date = (int32) GB(p2, 0, 30);
|
if (schedule_index >= v->orders.list->GetScheduledDispatchScheduleCount()) return CMD_ERROR;
|
||||||
uint16 full_date_fract = (GB(p1, 20, 12) << 2) + GB(p2, 30, 2);
|
|
||||||
|
int32 date = (int32)p2;
|
||||||
|
uint16 full_date_fract = GB(p3, 0, 16);
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
v->orders.list->SetScheduledDispatchStartDate(date, full_date_fract);
|
DispatchSchedule &ds = v->orders.list->GetDispatchScheduleByIndex(schedule_index);
|
||||||
v->orders.list->UpdateScheduledDispatch();
|
ds.SetScheduledDispatchStartDate(date, full_date_fract);
|
||||||
|
ds.UpdateScheduledDispatch();
|
||||||
SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index);
|
SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,6 +237,7 @@ CommandCost CmdScheduledDispatchSetStartDate(TileIndex tile, DoCommandFlag flags
|
|||||||
CommandCost CmdScheduledDispatchSetDelay(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
CommandCost CmdScheduledDispatchSetDelay(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||||
{
|
{
|
||||||
VehicleID veh = GB(p1, 0, 20);
|
VehicleID veh = GB(p1, 0, 20);
|
||||||
|
uint schedule_index = GB(p1, 20, 12);
|
||||||
|
|
||||||
Vehicle *v = Vehicle::GetIfValid(veh);
|
Vehicle *v = Vehicle::GetIfValid(veh);
|
||||||
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
|
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
|
||||||
@@ -233,8 +247,10 @@ CommandCost CmdScheduledDispatchSetDelay(TileIndex tile, DoCommandFlag flags, ui
|
|||||||
|
|
||||||
if (v->orders.list == nullptr) return CMD_ERROR;
|
if (v->orders.list == nullptr) return CMD_ERROR;
|
||||||
|
|
||||||
|
if (schedule_index >= v->orders.list->GetScheduledDispatchScheduleCount()) return CMD_ERROR;
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
v->orders.list->SetScheduledDispatchDelay(p2);
|
v->orders.list->GetDispatchScheduleByIndex(schedule_index).SetScheduledDispatchDelay(p2);
|
||||||
SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index);
|
SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,6 +275,7 @@ CommandCost CmdScheduledDispatchSetDelay(TileIndex tile, DoCommandFlag flags, ui
|
|||||||
CommandCost CmdScheduledDispatchResetLastDispatch(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
CommandCost CmdScheduledDispatchResetLastDispatch(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||||
{
|
{
|
||||||
VehicleID veh = GB(p1, 0, 20);
|
VehicleID veh = GB(p1, 0, 20);
|
||||||
|
uint schedule_index = GB(p1, 20, 12);
|
||||||
|
|
||||||
Vehicle *v = Vehicle::GetIfValid(veh);
|
Vehicle *v = Vehicle::GetIfValid(veh);
|
||||||
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
|
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
|
||||||
@@ -268,8 +285,10 @@ CommandCost CmdScheduledDispatchResetLastDispatch(TileIndex tile, DoCommandFlag
|
|||||||
|
|
||||||
if (v->orders.list == nullptr) return CMD_ERROR;
|
if (v->orders.list == nullptr) return CMD_ERROR;
|
||||||
|
|
||||||
|
if (schedule_index >= v->orders.list->GetScheduledDispatchScheduleCount()) return CMD_ERROR;
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
v->orders.list->SetScheduledDispatchLastDispatch(0);
|
v->orders.list->GetDispatchScheduleByIndex(schedule_index).SetScheduledDispatchLastDispatch(0);
|
||||||
SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index);
|
SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,6 +308,7 @@ CommandCost CmdScheduledDispatchResetLastDispatch(TileIndex tile, DoCommandFlag
|
|||||||
CommandCost CmdScheduledDispatchClear(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
CommandCost CmdScheduledDispatchClear(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||||
{
|
{
|
||||||
VehicleID veh = GB(p1, 0, 20);
|
VehicleID veh = GB(p1, 0, 20);
|
||||||
|
uint schedule_index = GB(p1, 20, 12);
|
||||||
|
|
||||||
Vehicle *v = Vehicle::GetIfValid(veh);
|
Vehicle *v = Vehicle::GetIfValid(veh);
|
||||||
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
|
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
|
||||||
@@ -298,19 +318,106 @@ CommandCost CmdScheduledDispatchClear(TileIndex tile, DoCommandFlag flags, uint3
|
|||||||
|
|
||||||
if (v->orders.list == nullptr) return CMD_ERROR;
|
if (v->orders.list == nullptr) return CMD_ERROR;
|
||||||
|
|
||||||
|
if (schedule_index >= v->orders.list->GetScheduledDispatchScheduleCount()) return CMD_ERROR;
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
v->orders.list->ClearScheduledDispatch();
|
v->orders.list->GetDispatchScheduleByIndex(schedule_index).ClearScheduledDispatch();
|
||||||
SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index);
|
SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CommandCost();
|
return CommandCost();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new scheduled dispatch schedule
|
||||||
|
*
|
||||||
|
* @param tile Not used.
|
||||||
|
* @param flags Operation to perform.
|
||||||
|
* @param p1 Vehicle index
|
||||||
|
* @param p2 Duration, in scaled tick
|
||||||
|
* @param p3 various bitstuffed elements
|
||||||
|
* - p3 = (bit 0 - 31) - Start date
|
||||||
|
* - p3 = (bit 32 - 47) - Full date fraction
|
||||||
|
* @param text unused
|
||||||
|
* @return the cost of this operation or an error
|
||||||
|
*/
|
||||||
|
CommandCost CmdScheduledDispatchAddNewSchedule(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, uint32 binary_length)
|
||||||
|
{
|
||||||
|
VehicleID veh = GB(p1, 0, 20);
|
||||||
|
|
||||||
|
Vehicle *v = Vehicle::GetIfValid(veh);
|
||||||
|
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
|
||||||
|
|
||||||
|
CommandCost ret = CheckOwnership(v->owner);
|
||||||
|
if (ret.Failed()) return ret;
|
||||||
|
|
||||||
|
if (v->orders.list == nullptr) return CMD_ERROR;
|
||||||
|
if (v->orders.list->GetScheduledDispatchScheduleCount() >= 4096) return CMD_ERROR;
|
||||||
|
|
||||||
|
int32 date = GB(p3, 0, 32);
|
||||||
|
uint16 full_date_fract = GB(p3, 32, 16);
|
||||||
|
|
||||||
|
if (flags & DC_EXEC) {
|
||||||
|
v->orders.list->GetScheduledDispatchScheduleSet().emplace_back();
|
||||||
|
DispatchSchedule &ds = v->orders.list->GetScheduledDispatchScheduleSet().back();
|
||||||
|
ds.SetScheduledDispatchDuration(p2);
|
||||||
|
ds.SetScheduledDispatchStartDate(date, full_date_fract);
|
||||||
|
ds.UpdateScheduledDispatch();
|
||||||
|
SetWindowClassesDirty(WC_VEHICLE_TIMETABLE);
|
||||||
|
SetWindowDirty(WC_SCHDISPATCH_SLOTS, v->index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CommandCost();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove scheduled dispatch schedule
|
||||||
|
*
|
||||||
|
* @param tile Not used.
|
||||||
|
* @param flags Operation to perform.
|
||||||
|
* @param p1 Vehicle index
|
||||||
|
* @param p2 Not used
|
||||||
|
* @param text unused
|
||||||
|
* @return the cost of this operation or an error
|
||||||
|
*/
|
||||||
|
CommandCost CmdScheduledDispatchRemoveSchedule(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
|
||||||
|
{
|
||||||
|
VehicleID veh = GB(p1, 0, 20);
|
||||||
|
uint schedule_index = GB(p1, 20, 12);
|
||||||
|
|
||||||
|
Vehicle *v = Vehicle::GetIfValid(veh);
|
||||||
|
if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
|
||||||
|
|
||||||
|
CommandCost ret = CheckOwnership(v->owner);
|
||||||
|
if (ret.Failed()) return ret;
|
||||||
|
|
||||||
|
if (v->orders.list == nullptr) return CMD_ERROR;
|
||||||
|
|
||||||
|
if (schedule_index >= v->orders.list->GetScheduledDispatchScheduleCount()) return CMD_ERROR;
|
||||||
|
|
||||||
|
if (flags & DC_EXEC) {
|
||||||
|
std::vector<DispatchSchedule> &scheds = v->orders.list->GetScheduledDispatchScheduleSet();
|
||||||
|
scheds.erase(scheds.begin() + schedule_index);
|
||||||
|
for (Order *o = v->GetFirstOrder(); o != nullptr; o = o->next) {
|
||||||
|
int idx = o->GetDispatchScheduleIndex();
|
||||||
|
if (idx == (int)schedule_index) {
|
||||||
|
o->SetDispatchScheduleIndex(-1);
|
||||||
|
} else if (idx > (int)schedule_index) {
|
||||||
|
o->SetDispatchScheduleIndex(idx - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SetWindowClassesDirty(WC_VEHICLE_TIMETABLE);
|
||||||
|
InvalidateWindowClassesData(WC_SCHDISPATCH_SLOTS, VIWD_MODIFY_ORDERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CommandCost();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set scheduled dispatch slot list.
|
* Set scheduled dispatch slot list.
|
||||||
* @param dispatch_list The offset time list, must be correctly sorted.
|
* @param dispatch_list The offset time list, must be correctly sorted.
|
||||||
*/
|
*/
|
||||||
void OrderList::SetScheduledDispatch(std::vector<uint32> dispatch_list)
|
void DispatchSchedule::SetScheduledDispatch(std::vector<uint32> dispatch_list)
|
||||||
{
|
{
|
||||||
this->scheduled_dispatch = std::move(dispatch_list);
|
this->scheduled_dispatch = std::move(dispatch_list);
|
||||||
assert(std::is_sorted(this->scheduled_dispatch.begin(), this->scheduled_dispatch.end()));
|
assert(std::is_sorted(this->scheduled_dispatch.begin(), this->scheduled_dispatch.end()));
|
||||||
@@ -321,7 +428,7 @@ void OrderList::SetScheduledDispatch(std::vector<uint32> dispatch_list)
|
|||||||
* Add new scheduled dispatch slot at offsets time.
|
* Add new scheduled dispatch slot at offsets time.
|
||||||
* @param offset The offset time to add.
|
* @param offset The offset time to add.
|
||||||
*/
|
*/
|
||||||
void OrderList::AddScheduledDispatch(uint32 offset)
|
void DispatchSchedule::AddScheduledDispatch(uint32 offset)
|
||||||
{
|
{
|
||||||
/* Maintain sorted list status */
|
/* Maintain sorted list status */
|
||||||
auto insert_position = std::lower_bound(this->scheduled_dispatch.begin(), this->scheduled_dispatch.end(), offset);
|
auto insert_position = std::lower_bound(this->scheduled_dispatch.begin(), this->scheduled_dispatch.end(), offset);
|
||||||
@@ -336,7 +443,7 @@ void OrderList::AddScheduledDispatch(uint32 offset)
|
|||||||
* Remove scheduled dispatch slot at offsets time.
|
* Remove scheduled dispatch slot at offsets time.
|
||||||
* @param offset The offset time to remove.
|
* @param offset The offset time to remove.
|
||||||
*/
|
*/
|
||||||
void OrderList::RemoveScheduledDispatch(uint32 offset)
|
void DispatchSchedule::RemoveScheduledDispatch(uint32 offset)
|
||||||
{
|
{
|
||||||
/* Maintain sorted list status */
|
/* Maintain sorted list status */
|
||||||
auto erase_position = std::lower_bound(this->scheduled_dispatch.begin(), this->scheduled_dispatch.end(), offset);
|
auto erase_position = std::lower_bound(this->scheduled_dispatch.begin(), this->scheduled_dispatch.end(), offset);
|
||||||
@@ -349,7 +456,7 @@ void OrderList::RemoveScheduledDispatch(uint32 offset)
|
|||||||
/**
|
/**
|
||||||
* Update the scheduled dispatch start time to be the most recent possible.
|
* Update the scheduled dispatch start time to be the most recent possible.
|
||||||
*/
|
*/
|
||||||
void OrderList::UpdateScheduledDispatch()
|
void DispatchSchedule::UpdateScheduledDispatch()
|
||||||
{
|
{
|
||||||
bool update_windows = false;
|
bool update_windows = false;
|
||||||
if (this->GetScheduledDispatchStartTick() == 0) {
|
if (this->GetScheduledDispatchStartTick() == 0) {
|
||||||
@@ -388,45 +495,3 @@ void OrderList::UpdateScheduledDispatch()
|
|||||||
}
|
}
|
||||||
if (update_windows) InvalidateWindowClassesData(WC_SCHDISPATCH_SLOTS, VIWD_MODIFY_ORDERS);
|
if (update_windows) InvalidateWindowClassesData(WC_SCHDISPATCH_SLOTS, VIWD_MODIFY_ORDERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset the scheduled dispatch schedule.
|
|
||||||
*
|
|
||||||
* This only occurs during initialization of the scheduled dispatch for each shared order. Basically we set
|
|
||||||
* proper default value for start time and duration
|
|
||||||
*/
|
|
||||||
void OrderList::ResetScheduledDispatch()
|
|
||||||
{
|
|
||||||
uint32 windex = this->first_shared->index;
|
|
||||||
|
|
||||||
Date start_date;
|
|
||||||
uint16 start_full_date_fract;
|
|
||||||
uint32 duration;
|
|
||||||
|
|
||||||
if (_settings_time.time_in_minutes) {
|
|
||||||
/* Set to 00:00 of today, and 1 day */
|
|
||||||
|
|
||||||
DateTicksScaled val;
|
|
||||||
val = MINUTES_DATE(MINUTES_DAY(CURRENT_MINUTE), 0, 0);
|
|
||||||
val -= _settings_time.clock_offset;
|
|
||||||
val *= _settings_time.ticks_per_minute;
|
|
||||||
SchdispatchConvertToFullDateFract(val, &start_date, &start_full_date_fract);
|
|
||||||
|
|
||||||
duration = 24 * 60 * _settings_time.ticks_per_minute;
|
|
||||||
} else {
|
|
||||||
/* Set Jan 1st and 365 day */
|
|
||||||
start_date = DAYS_TILL(_cur_year);
|
|
||||||
start_full_date_fract = 0;
|
|
||||||
duration = 365*DAY_TICKS;
|
|
||||||
}
|
|
||||||
|
|
||||||
DoCommandP(0, windex, duration, CMD_SCHEDULED_DISPATCH_SET_DURATION | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
|
|
||||||
|
|
||||||
uint32 p1 = 0, p2 = 0;
|
|
||||||
SB(p1, 0, 20, windex);
|
|
||||||
SB(p1, 20, 12, GB(start_full_date_fract, 2, 12));
|
|
||||||
SB(p2, 0, 30, start_date);
|
|
||||||
SB(p2, 30, 2, GB(start_full_date_fract, 0, 2));
|
|
||||||
|
|
||||||
DoCommandP(0, p1, p2, CMD_SCHEDULED_DISPATCH_SET_START_DATE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
|
|
||||||
}
|
|
||||||
|
@@ -43,6 +43,11 @@ enum SchdispatchWidgets {
|
|||||||
WID_SCHDISPATCH_SUMMARY_PANEL, ///< Summary panel
|
WID_SCHDISPATCH_SUMMARY_PANEL, ///< Summary panel
|
||||||
|
|
||||||
WID_SCHDISPATCH_ENABLED, ///< Enable button.
|
WID_SCHDISPATCH_ENABLED, ///< Enable button.
|
||||||
|
WID_SCHDISPATCH_HEADER, ///< Header text.
|
||||||
|
WID_SCHDISPATCH_PREV, ///< Previous schedule.
|
||||||
|
WID_SCHDISPATCH_NEXT, ///< Next schedule.
|
||||||
|
WID_SCHDISPATCH_ADD_SCHEDULE, ///< Add schedule.
|
||||||
|
|
||||||
WID_SCHDISPATCH_ADD, ///< Add Departure Time button
|
WID_SCHDISPATCH_ADD, ///< Add Departure Time button
|
||||||
WID_SCHDISPATCH_SET_DURATION, ///< Duration button
|
WID_SCHDISPATCH_SET_DURATION, ///< Duration button
|
||||||
WID_SCHDISPATCH_SET_START_DATE, ///< Start Date button
|
WID_SCHDISPATCH_SET_START_DATE, ///< Start Date button
|
||||||
@@ -52,22 +57,16 @@ enum SchdispatchWidgets {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for when a time has been chosen to start the schedule
|
* Callback for when a time has been chosen to start the schedule
|
||||||
* @param windex The windows index
|
* @param p1 The p1 parameter to send to CmdScheduledDispatchSetStartDate
|
||||||
* @param date the actually chosen date
|
* @param date the actually chosen date
|
||||||
*/
|
*/
|
||||||
static void SetScheduleStartDateIntl(uint32 windex, DateTicksScaled date)
|
static void SetScheduleStartDateIntl(uint32 p1, DateTicksScaled date)
|
||||||
{
|
{
|
||||||
Date start_date;
|
Date start_date;
|
||||||
uint16 start_full_date_fract;
|
uint16 start_full_date_fract;
|
||||||
SchdispatchConvertToFullDateFract(date, &start_date, &start_full_date_fract);
|
SchdispatchConvertToFullDateFract(date, &start_date, &start_full_date_fract);
|
||||||
|
|
||||||
uint32 p1 = 0, p2 = 0;
|
DoCommandPEx(0, p1, start_date, start_full_date_fract, CMD_SCHEDULED_DISPATCH_SET_START_DATE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), nullptr, nullptr, 0);
|
||||||
SB(p1, 0, 20, windex);
|
|
||||||
SB(p1, 20, 12, GB(start_full_date_fract, 2, 12));
|
|
||||||
SB(p2, 0, 30, start_date);
|
|
||||||
SB(p2, 30, 2, GB(start_full_date_fract, 0, 2));
|
|
||||||
|
|
||||||
DoCommandP(0, p1, p2, CMD_SCHEDULED_DISPATCH_SET_START_DATE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -88,12 +87,15 @@ static void SetScheduleStartDateCallback(const Window *w, DateTicksScaled date)
|
|||||||
static void ScheduleAddIntl(uint32 p1, DateTicksScaled date, uint extra_slots, uint offset)
|
static void ScheduleAddIntl(uint32 p1, DateTicksScaled date, uint extra_slots, uint offset)
|
||||||
{
|
{
|
||||||
VehicleID veh = GB(p1, 0, 20);
|
VehicleID veh = GB(p1, 0, 20);
|
||||||
|
uint schedule_index = GB(p1, 20, 12);
|
||||||
Vehicle *v = Vehicle::GetIfValid(veh);
|
Vehicle *v = Vehicle::GetIfValid(veh);
|
||||||
if (v == nullptr || !v->IsPrimaryVehicle()) return;
|
if (v == nullptr || !v->IsPrimaryVehicle() || schedule_index >= v->orders.list->GetScheduledDispatchScheduleCount()) return;
|
||||||
|
|
||||||
|
const DispatchSchedule &ds = v->orders.list->GetDispatchScheduleByIndex(schedule_index);
|
||||||
|
|
||||||
/* Make sure the time is the closest future to the timetable start */
|
/* Make sure the time is the closest future to the timetable start */
|
||||||
DateTicksScaled start_tick = v->orders.list->GetScheduledDispatchStartTick();
|
DateTicksScaled start_tick = ds.GetScheduledDispatchStartTick();
|
||||||
uint32 duration = v->orders.list->GetScheduledDispatchDuration();
|
uint32 duration = ds.GetScheduledDispatchDuration();
|
||||||
while (date > start_tick) date -= duration;
|
while (date > start_tick) date -= duration;
|
||||||
while (date < start_tick) date += duration;
|
while (date < start_tick) date += duration;
|
||||||
|
|
||||||
@@ -104,7 +106,7 @@ static void ScheduleAddIntl(uint32 p1, DateTicksScaled date, uint extra_slots, u
|
|||||||
extra_slots = std::min<uint>(extra_slots, UINT16_MAX);
|
extra_slots = std::min<uint>(extra_slots, UINT16_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
DoCommandPEx(0, v->index, (uint32)(date - start_tick), (((uint64)extra_slots) << 32) | offset, CMD_SCHEDULED_DISPATCH_ADD | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), nullptr, nullptr, 0);
|
DoCommandPEx(0, p1, (uint32)(date - start_tick), (((uint64)extra_slots) << 32) | offset, CMD_SCHEDULED_DISPATCH_ADD | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), nullptr, nullptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -152,8 +154,39 @@ static int CalculateMaxRequiredVehicle(Ticks timetable_duration, uint32 schedule
|
|||||||
return vehicle_count;
|
return vehicle_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void AddNewScheduledDispatchSchedule(VehicleID vindex)
|
||||||
|
{
|
||||||
|
Date start_date;
|
||||||
|
uint16 start_full_date_fract;
|
||||||
|
uint32 duration;
|
||||||
|
|
||||||
|
if (_settings_time.time_in_minutes) {
|
||||||
|
/* Set to 00:00 of today, and 1 day */
|
||||||
|
|
||||||
|
DateTicksScaled val;
|
||||||
|
val = MINUTES_DATE(MINUTES_DAY(CURRENT_MINUTE), 0, 0);
|
||||||
|
val -= _settings_time.clock_offset;
|
||||||
|
val *= _settings_time.ticks_per_minute;
|
||||||
|
SchdispatchConvertToFullDateFract(val, &start_date, &start_full_date_fract);
|
||||||
|
|
||||||
|
duration = 24 * 60 * _settings_time.ticks_per_minute;
|
||||||
|
} else {
|
||||||
|
/* Set Jan 1st and 365 day */
|
||||||
|
start_date = DAYS_TILL(_cur_year);
|
||||||
|
start_full_date_fract = 0;
|
||||||
|
duration = 365 * DAY_TICKS;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64 p3 = 0;
|
||||||
|
SB(p3, 0, 32, start_date);
|
||||||
|
SB(p3, 32, 16, start_full_date_fract);
|
||||||
|
|
||||||
|
DoCommandPEx(0, vindex, duration, p3, CMD_SCHEDULED_DISPATCH_ADD_NEW_SCHEDULE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), CcAddNewSchDispatchSchedule, nullptr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
struct SchdispatchWindow : Window {
|
struct SchdispatchWindow : Window {
|
||||||
const Vehicle *vehicle; ///< Vehicle monitored by the window.
|
const Vehicle *vehicle; ///< Vehicle monitored by the window.
|
||||||
|
int schedule_index;
|
||||||
int clicked_widget; ///< The widget that was clicked (used to determine what to do in OnQueryTextFinished)
|
int clicked_widget; ///< The widget that was clicked (used to determine what to do in OnQueryTextFinished)
|
||||||
Scrollbar *vscroll; ///< Verticle scrollbar
|
Scrollbar *vscroll; ///< Verticle scrollbar
|
||||||
uint num_columns; ///< Number of columns.
|
uint num_columns; ///< Number of columns.
|
||||||
@@ -171,6 +204,8 @@ struct SchdispatchWindow : Window {
|
|||||||
this->FinishInitNested(window_number);
|
this->FinishInitNested(window_number);
|
||||||
|
|
||||||
this->owner = this->vehicle->owner;
|
this->owner = this->vehicle->owner;
|
||||||
|
this->schedule_index = -1;
|
||||||
|
this->AutoSelectSchedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
~SchdispatchWindow()
|
~SchdispatchWindow()
|
||||||
@@ -188,8 +223,30 @@ struct SchdispatchWindow : Window {
|
|||||||
enum ManagementDropdown {
|
enum ManagementDropdown {
|
||||||
SCH_MD_RESET_LAST_DISPATCHED,
|
SCH_MD_RESET_LAST_DISPATCHED,
|
||||||
SCH_MD_CLEAR_SCHEDULE,
|
SCH_MD_CLEAR_SCHEDULE,
|
||||||
|
SCH_MD_REMOVE_SCHEDULE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool IsScheduleSelected() const
|
||||||
|
{
|
||||||
|
return this->vehicle->orders.list != nullptr && this->schedule_index >= 0 && (uint)this->schedule_index < this->vehicle->orders.list->GetScheduledDispatchScheduleCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AutoSelectSchedule()
|
||||||
|
{
|
||||||
|
if (!this->IsScheduleSelected()) {
|
||||||
|
if (this->vehicle->orders.list != nullptr && this->vehicle->orders.list->GetScheduledDispatchScheduleCount() > 0) {
|
||||||
|
this->schedule_index = Clamp<int>(this->schedule_index, 0, this->vehicle->orders.list->GetScheduledDispatchScheduleCount() - 1);
|
||||||
|
} else {
|
||||||
|
this->schedule_index = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const DispatchSchedule &GetSelectedSchedule() const
|
||||||
|
{
|
||||||
|
return this->vehicle->orders.list->GetDispatchScheduleByIndex(this->schedule_index);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
|
||||||
{
|
{
|
||||||
switch (widget) {
|
switch (widget) {
|
||||||
@@ -232,8 +289,8 @@ struct SchdispatchWindow : Window {
|
|||||||
void CountItem()
|
void CountItem()
|
||||||
{
|
{
|
||||||
this->item_count = 0;
|
this->item_count = 0;
|
||||||
if (this->vehicle->orders.list != nullptr) {
|
if (this->IsScheduleSelected()) {
|
||||||
this->item_count = (uint)this->vehicle->orders.list->GetScheduledDispatch().size();
|
this->item_count = (uint)this->GetSelectedSchedule().GetScheduledDispatch().size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,6 +304,7 @@ struct SchdispatchWindow : Window {
|
|||||||
switch (data) {
|
switch (data) {
|
||||||
case VIWD_MODIFY_ORDERS:
|
case VIWD_MODIFY_ORDERS:
|
||||||
if (!gui_scope) break;
|
if (!gui_scope) break;
|
||||||
|
this->AutoSelectSchedule();
|
||||||
this->ReInit();
|
this->ReInit();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -257,9 +315,15 @@ struct SchdispatchWindow : Window {
|
|||||||
const Vehicle *v = this->vehicle;
|
const Vehicle *v = this->vehicle;
|
||||||
CountItem();
|
CountItem();
|
||||||
|
|
||||||
this->SetWidgetDisabledState(WID_SCHDISPATCH_ENABLED, (v->owner != _local_company) || HasBit(v->vehicle_flags, VF_TIMETABLE_SEPARATION));
|
bool unusable = (v->owner != _local_company) || (v->orders.list == nullptr);
|
||||||
|
|
||||||
bool disabled = (v->owner != _local_company) || !HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH) || (v->orders.list == nullptr);
|
this->SetWidgetDisabledState(WID_SCHDISPATCH_ENABLED, unusable || HasBit(v->vehicle_flags, VF_TIMETABLE_SEPARATION));
|
||||||
|
|
||||||
|
this->SetWidgetDisabledState(WID_SCHDISPATCH_PREV, v->orders.list == nullptr || this->schedule_index <= 0);
|
||||||
|
this->SetWidgetDisabledState(WID_SCHDISPATCH_NEXT, v->orders.list == nullptr || this->schedule_index >= (int)(v->orders.list->GetScheduledDispatchScheduleCount() - 1));
|
||||||
|
this->SetWidgetDisabledState(WID_SCHDISPATCH_ADD_SCHEDULE, unusable || v->orders.list->GetScheduledDispatchScheduleCount() >= 4096);
|
||||||
|
|
||||||
|
bool disabled = unusable || !HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH) || !this->IsScheduleSelected();
|
||||||
this->SetWidgetDisabledState(WID_SCHDISPATCH_ADD, disabled);
|
this->SetWidgetDisabledState(WID_SCHDISPATCH_ADD, disabled);
|
||||||
this->SetWidgetDisabledState(WID_SCHDISPATCH_SET_DURATION, disabled);
|
this->SetWidgetDisabledState(WID_SCHDISPATCH_SET_DURATION, disabled);
|
||||||
this->SetWidgetDisabledState(WID_SCHDISPATCH_SET_START_DATE, disabled);
|
this->SetWidgetDisabledState(WID_SCHDISPATCH_SET_START_DATE, disabled);
|
||||||
@@ -275,7 +339,19 @@ struct SchdispatchWindow : Window {
|
|||||||
virtual void SetStringParameters(int widget) const override
|
virtual void SetStringParameters(int widget) const override
|
||||||
{
|
{
|
||||||
switch (widget) {
|
switch (widget) {
|
||||||
case WID_SCHDISPATCH_CAPTION: SetDParam(0, this->vehicle->index); break;
|
case WID_SCHDISPATCH_CAPTION:
|
||||||
|
SetDParam(0, this->vehicle->index);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WID_SCHDISPATCH_HEADER:
|
||||||
|
if (this->IsScheduleSelected()) {
|
||||||
|
SetDParam(0, STR_SCHDISPATCH_SCHEDULE_ID);
|
||||||
|
SetDParam(1, this->schedule_index + 1);
|
||||||
|
SetDParam(2, this->vehicle->orders.list->GetScheduledDispatchScheduleCount());
|
||||||
|
} else {
|
||||||
|
SetDParam(0, STR_SCHDISPATCH_NO_SCHEDULES);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,10 +369,11 @@ struct SchdispatchWindow : Window {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case WID_SCHDISPATCH_MANAGEMENT: {
|
case WID_SCHDISPATCH_MANAGEMENT: {
|
||||||
uint64 params[2];
|
uint64 params[3];
|
||||||
params[0] = STR_SCHDISPATCH_RESET_LAST_DISPATCH_TOOLTIP;
|
params[0] = STR_SCHDISPATCH_RESET_LAST_DISPATCH_TOOLTIP;
|
||||||
params[1] = STR_SCHDISPATCH_CLEAR_TOOLTIP;
|
params[1] = STR_SCHDISPATCH_CLEAR_TOOLTIP;
|
||||||
GuiShowTooltips(this, STR_SCHDISPATCH_MANAGE_TOOLTIP, 2, params, close_cond);
|
params[2] = STR_SCHDISPATCH_REMOVE_SCHEDULE_TOOLTIP;
|
||||||
|
GuiShowTooltips(this, STR_SCHDISPATCH_MANAGE_TOOLTIP, 3, params, close_cond);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,9 +409,9 @@ struct SchdispatchWindow : Window {
|
|||||||
|
|
||||||
virtual void OnGameTick() override
|
virtual void OnGameTick() override
|
||||||
{
|
{
|
||||||
const Vehicle *v = this->vehicle;
|
if (HasBit(this->vehicle->vehicle_flags, VF_SCHEDULED_DISPATCH) && this->IsScheduleSelected()) {
|
||||||
if (HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH) && v->orders.list != nullptr) {
|
const DispatchSchedule &ds = this->GetSelectedSchedule();
|
||||||
if (((v->orders.list->GetScheduledDispatchStartTick() + v->orders.list->GetScheduledDispatchLastDispatch()) > _scaled_date_ticks) != this->last_departure_future) {
|
if (((ds.GetScheduledDispatchStartTick() + ds.GetScheduledDispatchLastDispatch()) > _scaled_date_ticks) != this->last_departure_future) {
|
||||||
SetWidgetDirty(WID_SCHDISPATCH_SUMMARY_PANEL);
|
SetWidgetDirty(WID_SCHDISPATCH_SUMMARY_PANEL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -347,7 +424,7 @@ struct SchdispatchWindow : Window {
|
|||||||
switch (widget) {
|
switch (widget) {
|
||||||
case WID_SCHDISPATCH_MATRIX: {
|
case WID_SCHDISPATCH_MATRIX: {
|
||||||
/* If order is not initialized, don't draw */
|
/* If order is not initialized, don't draw */
|
||||||
if (v->orders.list == nullptr) break;
|
if (!this->IsScheduleSelected()) break;
|
||||||
|
|
||||||
bool rtl = _current_text_dir == TD_RTL;
|
bool rtl = _current_text_dir == TD_RTL;
|
||||||
|
|
||||||
@@ -355,19 +432,21 @@ struct SchdispatchWindow : Window {
|
|||||||
const NWidgetCore *wid = this->GetWidget<NWidgetCore>(WID_SCHDISPATCH_MATRIX);
|
const NWidgetCore *wid = this->GetWidget<NWidgetCore>(WID_SCHDISPATCH_MATRIX);
|
||||||
const uint16 rows_in_display = wid->current_y / wid->resize_y;
|
const uint16 rows_in_display = wid->current_y / wid->resize_y;
|
||||||
|
|
||||||
|
const DispatchSchedule &ds = this->GetSelectedSchedule();
|
||||||
|
|
||||||
uint num = this->vscroll->GetPosition() * this->num_columns;
|
uint num = this->vscroll->GetPosition() * this->num_columns;
|
||||||
if (num >= v->orders.list->GetScheduledDispatch().size()) break;
|
if (num >= ds.GetScheduledDispatch().size()) break;
|
||||||
|
|
||||||
const uint maxval = std::min<uint>(this->item_count, num + (rows_in_display * this->num_columns));
|
const uint maxval = std::min<uint>(this->item_count, num + (rows_in_display * this->num_columns));
|
||||||
|
|
||||||
auto current_schedule = v->orders.list->GetScheduledDispatch().begin() + num;
|
auto current_schedule = ds.GetScheduledDispatch().begin() + num;
|
||||||
const DateTicksScaled start_tick = v->orders.list->GetScheduledDispatchStartTick();
|
const DateTicksScaled start_tick = ds.GetScheduledDispatchStartTick();
|
||||||
const DateTicksScaled end_tick = v->orders.list->GetScheduledDispatchStartTick() + v->orders.list->GetScheduledDispatchDuration();
|
const DateTicksScaled end_tick = ds.GetScheduledDispatchStartTick() + ds.GetScheduledDispatchDuration();
|
||||||
|
|
||||||
for (int y = r.top + 1; num < maxval; y += this->resize.step_height) { /* Draw the rows */
|
for (int y = r.top + 1; num < maxval; y += this->resize.step_height) { /* Draw the rows */
|
||||||
for (byte i = 0; i < this->num_columns && num < maxval; i++, num++) {
|
for (byte i = 0; i < this->num_columns && num < maxval; i++, num++) {
|
||||||
/* Draw all departure time in the current row */
|
/* Draw all departure time in the current row */
|
||||||
if (current_schedule != v->orders.list->GetScheduledDispatch().end()) {
|
if (current_schedule != ds.GetScheduledDispatch().end()) {
|
||||||
int x = r.left + (rtl ? (this->num_columns - i - 1) : i) * this->resize.step_width;
|
int x = r.left + (rtl ? (this->num_columns - i - 1) : i) * this->resize.step_width;
|
||||||
DateTicksScaled draw_time = start_tick + *current_schedule;
|
DateTicksScaled draw_time = start_tick + *current_schedule;
|
||||||
this->DrawScheduledTime(draw_time, x, x + this->resize.step_width - 1, y, draw_time >= end_tick ? TC_RED : TC_BLACK);
|
this->DrawScheduledTime(draw_time, x, x + this->resize.step_width - 1, y, draw_time >= end_tick ? TC_RED : TC_BLACK);
|
||||||
@@ -381,15 +460,14 @@ struct SchdispatchWindow : Window {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case WID_SCHDISPATCH_SUMMARY_PANEL: {
|
case WID_SCHDISPATCH_SUMMARY_PANEL: {
|
||||||
|
|
||||||
int y = r.top + WD_FRAMERECT_TOP;
|
int y = r.top + WD_FRAMERECT_TOP;
|
||||||
|
|
||||||
if (!HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH) || v->orders.list == nullptr) {
|
if (!HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH) || !this->IsScheduleSelected()) {
|
||||||
y += FONT_HEIGHT_NORMAL;
|
y += FONT_HEIGHT_NORMAL;
|
||||||
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SCHDISPATCH_SUMMARY_NOT_ENABLED);
|
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SCHDISPATCH_SUMMARY_NOT_ENABLED);
|
||||||
} else {
|
} else {
|
||||||
|
const DispatchSchedule &ds = this->GetSelectedSchedule();
|
||||||
const DateTicksScaled last_departure = v->orders.list->GetScheduledDispatchStartTick() + v->orders.list->GetScheduledDispatchLastDispatch();
|
const DateTicksScaled last_departure = ds.GetScheduledDispatchStartTick() + ds.GetScheduledDispatchLastDispatch();
|
||||||
SetDParam(0, last_departure);
|
SetDParam(0, last_departure);
|
||||||
const_cast<SchdispatchWindow*>(this)->last_departure_future = (last_departure > _scaled_date_ticks);
|
const_cast<SchdispatchWindow*>(this)->last_departure_future = (last_departure > _scaled_date_ticks);
|
||||||
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y,
|
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y,
|
||||||
@@ -404,7 +482,7 @@ struct SchdispatchWindow : Window {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!have_conditional) {
|
if (!have_conditional) {
|
||||||
const int required_vehicle = CalculateMaxRequiredVehicle(v->orders.list->GetTimetableTotalDuration(), v->orders.list->GetScheduledDispatchDuration(), v->orders.list->GetScheduledDispatch());
|
const int required_vehicle = CalculateMaxRequiredVehicle(v->orders.list->GetTimetableTotalDuration(), ds.GetScheduledDispatchDuration(), ds.GetScheduledDispatch());
|
||||||
if (required_vehicle > 0) {
|
if (required_vehicle > 0) {
|
||||||
SetDParam(0, required_vehicle);
|
SetDParam(0, required_vehicle);
|
||||||
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SCHDISPATCH_SUMMARY_L1);
|
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SCHDISPATCH_SUMMARY_L1);
|
||||||
@@ -412,16 +490,16 @@ struct SchdispatchWindow : Window {
|
|||||||
}
|
}
|
||||||
y += FONT_HEIGHT_NORMAL;
|
y += FONT_HEIGHT_NORMAL;
|
||||||
|
|
||||||
SetTimetableParams(0, v->orders.list->GetScheduledDispatchDuration(), true);
|
SetTimetableParams(0, ds.GetScheduledDispatchDuration(), true);
|
||||||
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SCHDISPATCH_SUMMARY_L2);
|
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SCHDISPATCH_SUMMARY_L2);
|
||||||
y += FONT_HEIGHT_NORMAL;
|
y += FONT_HEIGHT_NORMAL;
|
||||||
|
|
||||||
SetDParam(0, v->orders.list->GetScheduledDispatchStartTick());
|
SetDParam(0, ds.GetScheduledDispatchStartTick());
|
||||||
SetDParam(1, v->orders.list->GetScheduledDispatchStartTick() + v->orders.list->GetScheduledDispatchDuration());
|
SetDParam(1, ds.GetScheduledDispatchStartTick() + ds.GetScheduledDispatchDuration());
|
||||||
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SCHDISPATCH_SUMMARY_L3);
|
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SCHDISPATCH_SUMMARY_L3);
|
||||||
y += FONT_HEIGHT_NORMAL;
|
y += FONT_HEIGHT_NORMAL;
|
||||||
|
|
||||||
SetTimetableParams(0, v->orders.list->GetScheduledDispatchDelay());
|
SetTimetableParams(0, ds.GetScheduledDispatchDelay());
|
||||||
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SCHDISPATCH_SUMMARY_L4);
|
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SCHDISPATCH_SUMMARY_L4);
|
||||||
y += FONT_HEIGHT_NORMAL;
|
y += FONT_HEIGHT_NORMAL;
|
||||||
|
|
||||||
@@ -443,8 +521,8 @@ struct SchdispatchWindow : Window {
|
|||||||
warnings++;
|
warnings++;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32 duration = v->orders.list->GetScheduledDispatchDuration();
|
uint32 duration = ds.GetScheduledDispatchDuration();
|
||||||
for (uint32 slot : v->orders.list->GetScheduledDispatch()) {
|
for (uint32 slot : ds.GetScheduledDispatch()) {
|
||||||
if (slot >= duration) {
|
if (slot >= duration) {
|
||||||
draw_warning(STR_SCHDISPATCH_SLOT_OUTSIDE_SCHEDULE);
|
draw_warning(STR_SCHDISPATCH_SLOT_OUTSIDE_SCHEDULE);
|
||||||
break;
|
break;
|
||||||
@@ -470,6 +548,8 @@ struct SchdispatchWindow : Window {
|
|||||||
*/
|
*/
|
||||||
void TimeClick(int x, int y)
|
void TimeClick(int x, int y)
|
||||||
{
|
{
|
||||||
|
if (!this->IsScheduleSelected()) return;
|
||||||
|
|
||||||
const NWidgetCore *matrix_widget = this->GetWidget<NWidgetCore>(WID_SCHDISPATCH_MATRIX);
|
const NWidgetCore *matrix_widget = this->GetWidget<NWidgetCore>(WID_SCHDISPATCH_MATRIX);
|
||||||
/* In case of RTL the widgets are swapped as a whole */
|
/* In case of RTL the widgets are swapped as a whole */
|
||||||
if (_current_text_dir == TD_RTL) x = matrix_widget->current_x - x;
|
if (_current_text_dir == TD_RTL) x = matrix_widget->current_x - x;
|
||||||
@@ -484,10 +564,12 @@ struct SchdispatchWindow : Window {
|
|||||||
|
|
||||||
uint pos = ((row + this->vscroll->GetPosition()) * this->num_columns) + xt;
|
uint pos = ((row + this->vscroll->GetPosition()) * this->num_columns) + xt;
|
||||||
|
|
||||||
if (pos >= this->item_count) return;
|
const DispatchSchedule &ds = this->GetSelectedSchedule();
|
||||||
|
|
||||||
|
if (pos >= this->item_count || pos >= ds.GetScheduledDispatch().size()) return;
|
||||||
|
|
||||||
if (xm <= this->header_width) {
|
if (xm <= this->header_width) {
|
||||||
DoCommandP(0, this->vehicle->index, this->vehicle->orders.list->GetScheduledDispatch()[pos], CMD_SCHEDULED_DISPATCH_REMOVE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
|
DoCommandP(0, this->vehicle->index | (this->schedule_index << 20), ds.GetScheduledDispatch()[pos], CMD_SCHEDULED_DISPATCH_REMOVE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -522,30 +604,35 @@ struct SchdispatchWindow : Window {
|
|||||||
uint32 p2 = 0;
|
uint32 p2 = 0;
|
||||||
if (!HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH)) SetBit(p2, 0);
|
if (!HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH)) SetBit(p2, 0);
|
||||||
|
|
||||||
if (!v->orders.list->IsScheduledDispatchValid()) v->orders.list->ResetScheduledDispatch();
|
|
||||||
DoCommandP(0, v->index, p2, CMD_SCHEDULED_DISPATCH | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
|
DoCommandP(0, v->index, p2, CMD_SCHEDULED_DISPATCH | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
|
||||||
|
if (HasBit(p2, 0) && this->vehicle->orders.list != nullptr && this->vehicle->orders.list->GetScheduledDispatchScheduleCount() == 0) {
|
||||||
|
AddNewScheduledDispatchSchedule(v->index);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WID_SCHDISPATCH_ADD: {
|
case WID_SCHDISPATCH_ADD: {
|
||||||
|
if (!this->IsScheduleSelected()) break;
|
||||||
if (_settings_time.time_in_minutes && _ctrl_pressed) {
|
if (_settings_time.time_in_minutes && _ctrl_pressed) {
|
||||||
void ShowScheduledDispatchAddSlotsWindow(SchdispatchWindow *parent, int window_number);
|
void ShowScheduledDispatchAddSlotsWindow(SchdispatchWindow *parent, int window_number);
|
||||||
ShowScheduledDispatchAddSlotsWindow(this, v->index);
|
ShowScheduledDispatchAddSlotsWindow(this, v->index);
|
||||||
} else if (_settings_time.time_in_minutes && _settings_client.gui.timetable_start_text_entry) {
|
} else if (_settings_time.time_in_minutes && _settings_client.gui.timetable_start_text_entry) {
|
||||||
ShowQueryString(STR_EMPTY, STR_SCHDISPATCH_ADD_CAPTION, 31, this, CS_NUMERAL, QSF_NONE);
|
ShowQueryString(STR_EMPTY, STR_SCHDISPATCH_ADD_CAPTION, 31, this, CS_NUMERAL, QSF_NONE);
|
||||||
} else {
|
} else {
|
||||||
ShowSetDateWindow(this, v->index, _scaled_date_ticks, _cur_year, _cur_year + 15, ScheduleAddCallback, STR_SCHDISPATCH_ADD, STR_SCHDISPATCH_ADD_TOOLTIP);
|
ShowSetDateWindow(this, v->index | (this->schedule_index << 20), _scaled_date_ticks, _cur_year, _cur_year + 15, ScheduleAddCallback, STR_SCHDISPATCH_ADD, STR_SCHDISPATCH_ADD_TOOLTIP);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WID_SCHDISPATCH_SET_DURATION: {
|
case WID_SCHDISPATCH_SET_DURATION: {
|
||||||
SetDParam(0, ProcessDurationForQueryString(v->orders.list->GetScheduledDispatchDuration()));
|
if (!this->IsScheduleSelected()) break;
|
||||||
|
SetDParam(0, ProcessDurationForQueryString(this->GetSelectedSchedule().GetScheduledDispatchDuration()));
|
||||||
ShowQueryString(STR_JUST_INT, STR_SCHDISPATCH_DURATION_CAPTION_MINUTE + this->GetQueryStringCaptionOffset(), 31, this, CS_NUMERAL, QSF_NONE);
|
ShowQueryString(STR_JUST_INT, STR_SCHDISPATCH_DURATION_CAPTION_MINUTE + this->GetQueryStringCaptionOffset(), 31, this, CS_NUMERAL, QSF_NONE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WID_SCHDISPATCH_SET_START_DATE: {
|
case WID_SCHDISPATCH_SET_START_DATE: {
|
||||||
|
if (!this->IsScheduleSelected()) break;
|
||||||
if (_settings_time.time_in_minutes && _settings_client.gui.timetable_start_text_entry) {
|
if (_settings_time.time_in_minutes && _settings_client.gui.timetable_start_text_entry) {
|
||||||
uint64 time = _scaled_date_ticks;
|
uint64 time = _scaled_date_ticks;
|
||||||
time /= _settings_time.ticks_per_minute;
|
time /= _settings_time.ticks_per_minute;
|
||||||
@@ -555,24 +642,43 @@ struct SchdispatchWindow : Window {
|
|||||||
SetDParam(0, time);
|
SetDParam(0, time);
|
||||||
ShowQueryString(STR_JUST_INT, STR_SCHDISPATCH_START_CAPTION_MINUTE, 31, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED);
|
ShowQueryString(STR_JUST_INT, STR_SCHDISPATCH_START_CAPTION_MINUTE, 31, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED);
|
||||||
} else {
|
} else {
|
||||||
ShowSetDateWindow(this, v->index, _scaled_date_ticks, _cur_year, _cur_year + 15, SetScheduleStartDateCallback, STR_SCHDISPATCH_SET_START, STR_SCHDISPATCH_START_TOOLTIP);
|
ShowSetDateWindow(this, v->index | (this->schedule_index << 20), _scaled_date_ticks, _cur_year, _cur_year + 15, SetScheduleStartDateCallback, STR_SCHDISPATCH_SET_START, STR_SCHDISPATCH_START_TOOLTIP);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WID_SCHDISPATCH_SET_DELAY: {
|
case WID_SCHDISPATCH_SET_DELAY: {
|
||||||
SetDParam(0, ProcessDurationForQueryString(v->orders.list->GetScheduledDispatchDelay()));
|
if (!this->IsScheduleSelected()) break;
|
||||||
|
SetDParam(0, ProcessDurationForQueryString(this->GetSelectedSchedule().GetScheduledDispatchDelay()));
|
||||||
ShowQueryString(STR_JUST_INT, STR_SCHDISPATCH_DELAY_CAPTION_MINUTE + this->GetQueryStringCaptionOffset(), 31, this, CS_NUMERAL, QSF_NONE);
|
ShowQueryString(STR_JUST_INT, STR_SCHDISPATCH_DELAY_CAPTION_MINUTE + this->GetQueryStringCaptionOffset(), 31, this, CS_NUMERAL, QSF_NONE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WID_SCHDISPATCH_MANAGEMENT: {
|
case WID_SCHDISPATCH_MANAGEMENT: {
|
||||||
|
if (!this->IsScheduleSelected()) break;
|
||||||
DropDownList list;
|
DropDownList list;
|
||||||
list.emplace_back(new DropDownListStringItem(STR_SCHDISPATCH_RESET_LAST_DISPATCH, SCH_MD_RESET_LAST_DISPATCHED, false));
|
list.emplace_back(new DropDownListStringItem(STR_SCHDISPATCH_RESET_LAST_DISPATCH, SCH_MD_RESET_LAST_DISPATCHED, false));
|
||||||
list.emplace_back(new DropDownListStringItem(STR_SCHDISPATCH_CLEAR, SCH_MD_CLEAR_SCHEDULE, false));
|
list.emplace_back(new DropDownListStringItem(STR_SCHDISPATCH_CLEAR, SCH_MD_CLEAR_SCHEDULE, false));
|
||||||
|
list.emplace_back(new DropDownListStringItem(STR_SCHDISPATCH_REMOVE_SCHEDULE, SCH_MD_REMOVE_SCHEDULE, false));
|
||||||
ShowDropDownList(this, std::move(list), -1, WID_SCHDISPATCH_MANAGEMENT);
|
ShowDropDownList(this, std::move(list), -1, WID_SCHDISPATCH_MANAGEMENT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case WID_SCHDISPATCH_PREV:
|
||||||
|
if (!this->IsScheduleSelected()) break;
|
||||||
|
if (this->schedule_index > 0) this->schedule_index--;
|
||||||
|
this->ReInit();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WID_SCHDISPATCH_NEXT:
|
||||||
|
if (!this->IsScheduleSelected()) break;
|
||||||
|
if (this->schedule_index < (int)(this->vehicle->orders.list->GetScheduledDispatchScheduleCount() - 1)) this->schedule_index++;
|
||||||
|
this->ReInit();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WID_SCHDISPATCH_ADD_SCHEDULE:
|
||||||
|
AddNewScheduledDispatchSchedule(this->vehicle->index);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->SetDirty();
|
this->SetDirty();
|
||||||
@@ -582,13 +688,18 @@ struct SchdispatchWindow : Window {
|
|||||||
{
|
{
|
||||||
switch (widget) {
|
switch (widget) {
|
||||||
case WID_SCHDISPATCH_MANAGEMENT: {
|
case WID_SCHDISPATCH_MANAGEMENT: {
|
||||||
|
if (!this->IsScheduleSelected()) break;
|
||||||
switch((ManagementDropdown)index) {
|
switch((ManagementDropdown)index) {
|
||||||
case SCH_MD_RESET_LAST_DISPATCHED:
|
case SCH_MD_RESET_LAST_DISPATCHED:
|
||||||
DoCommandP(0, this->vehicle->index, 0, CMD_SCHEDULED_DISPATCH_RESET_LAST_DISPATCH | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
|
DoCommandP(0, this->vehicle->index | (this->schedule_index << 20), 0, CMD_SCHEDULED_DISPATCH_RESET_LAST_DISPATCH | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCH_MD_CLEAR_SCHEDULE:
|
case SCH_MD_CLEAR_SCHEDULE:
|
||||||
DoCommandP(0, this->vehicle->index, 0, CMD_SCHEDULED_DISPATCH_CLEAR | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
|
DoCommandP(0, this->vehicle->index | (this->schedule_index << 20), 0, CMD_SCHEDULED_DISPATCH_CLEAR | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCH_MD_REMOVE_SCHEDULE:
|
||||||
|
DoCommandP(0, this->vehicle->index | (this->schedule_index << 20), 0, CMD_SCHEDULED_DISPATCH_REMOVE_SCHEDULE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -607,6 +718,7 @@ struct SchdispatchWindow : Window {
|
|||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
|
|
||||||
case WID_SCHDISPATCH_ADD: {
|
case WID_SCHDISPATCH_ADD: {
|
||||||
|
if (!this->IsScheduleSelected()) break;
|
||||||
char *end;
|
char *end;
|
||||||
int32 val = StrEmpty(str) ? -1 : strtoul(str, &end, 10);
|
int32 val = StrEmpty(str) ? -1 : strtoul(str, &end, 10);
|
||||||
|
|
||||||
@@ -616,12 +728,13 @@ struct SchdispatchWindow : Window {
|
|||||||
DateTicksScaled slot = MINUTES_DATE(MINUTES_DAY(CURRENT_MINUTE), hours, minutes);
|
DateTicksScaled slot = MINUTES_DATE(MINUTES_DAY(CURRENT_MINUTE), hours, minutes);
|
||||||
slot -= _settings_time.clock_offset;
|
slot -= _settings_time.clock_offset;
|
||||||
slot *= _settings_time.ticks_per_minute;
|
slot *= _settings_time.ticks_per_minute;
|
||||||
ScheduleAddIntl(v->index, slot, 0, 0);
|
ScheduleAddIntl(v->index | (this->schedule_index << 20), slot, 0, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WID_SCHDISPATCH_SET_START_DATE: {
|
case WID_SCHDISPATCH_SET_START_DATE: {
|
||||||
|
if (!this->IsScheduleSelected()) break;
|
||||||
char *end;
|
char *end;
|
||||||
int32 val = StrEmpty(str) ? -1 : strtoul(str, &end, 10);
|
int32 val = StrEmpty(str) ? -1 : strtoul(str, &end, 10);
|
||||||
|
|
||||||
@@ -631,30 +744,32 @@ struct SchdispatchWindow : Window {
|
|||||||
DateTicksScaled start = MINUTES_DATE(MINUTES_DAY(CURRENT_MINUTE), hours, minutes);
|
DateTicksScaled start = MINUTES_DATE(MINUTES_DAY(CURRENT_MINUTE), hours, minutes);
|
||||||
start -= _settings_time.clock_offset;
|
start -= _settings_time.clock_offset;
|
||||||
start *= _settings_time.ticks_per_minute;
|
start *= _settings_time.ticks_per_minute;
|
||||||
SetScheduleStartDateIntl(v->index, start);
|
SetScheduleStartDateIntl(v->index | (this->schedule_index << 20), start);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WID_SCHDISPATCH_SET_DURATION: {
|
case WID_SCHDISPATCH_SET_DURATION: {
|
||||||
|
if (!this->IsScheduleSelected()) break;
|
||||||
int32 val = StrEmpty(str) ? 0 : strtoul(str, nullptr, 10);
|
int32 val = StrEmpty(str) ? 0 : strtoul(str, nullptr, 10);
|
||||||
|
|
||||||
if (val > 0) {
|
if (val > 0) {
|
||||||
if (!_settings_client.gui.timetable_in_ticks) val *= DATE_UNIT_SIZE;
|
if (!_settings_client.gui.timetable_in_ticks) val *= DATE_UNIT_SIZE;
|
||||||
|
|
||||||
DoCommandP(0, v->index, val, CMD_SCHEDULED_DISPATCH_SET_DURATION | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
|
DoCommandP(0, v->index | (this->schedule_index << 20), val, CMD_SCHEDULED_DISPATCH_SET_DURATION | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WID_SCHDISPATCH_SET_DELAY: {
|
case WID_SCHDISPATCH_SET_DELAY: {
|
||||||
|
if (!this->IsScheduleSelected()) break;
|
||||||
char *end;
|
char *end;
|
||||||
int32 val = StrEmpty(str) ? -1 : strtoul(str, &end, 10);
|
int32 val = StrEmpty(str) ? -1 : strtoul(str, &end, 10);
|
||||||
|
|
||||||
if (val >= 0 && end && *end == 0) {
|
if (val >= 0 && end && *end == 0) {
|
||||||
if (!_settings_client.gui.timetable_in_ticks) val *= DATE_UNIT_SIZE;
|
if (!_settings_client.gui.timetable_in_ticks) val *= DATE_UNIT_SIZE;
|
||||||
|
|
||||||
DoCommandP(0, v->index, val, CMD_SCHEDULED_DISPATCH_SET_DELAY | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
|
DoCommandP(0, v->index | (this->schedule_index << 20), val, CMD_SCHEDULED_DISPATCH_SET_DELAY | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -685,15 +800,25 @@ struct SchdispatchWindow : Window {
|
|||||||
|
|
||||||
void AddMultipleDepartureSlots(uint start, uint step, uint end)
|
void AddMultipleDepartureSlots(uint start, uint step, uint end)
|
||||||
{
|
{
|
||||||
if (end < start || step == 0) return;
|
if (end < start || step == 0 || !this->IsScheduleSelected()) return;
|
||||||
|
|
||||||
DateTicksScaled slot = MINUTES_DATE(MINUTES_DAY(CURRENT_MINUTE), 0, start);
|
DateTicksScaled slot = MINUTES_DATE(MINUTES_DAY(CURRENT_MINUTE), 0, start);
|
||||||
slot -= _settings_time.clock_offset;
|
slot -= _settings_time.clock_offset;
|
||||||
slot *= _settings_time.ticks_per_minute;
|
slot *= _settings_time.ticks_per_minute;
|
||||||
ScheduleAddIntl(this->vehicle->index, slot, (end - start) / step, step * _settings_time.ticks_per_minute);
|
ScheduleAddIntl(this->vehicle->index | (this->schedule_index << 20), slot, (end - start) / step, step * _settings_time.ticks_per_minute);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void CcAddNewSchDispatchSchedule(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd)
|
||||||
|
{
|
||||||
|
SchdispatchWindow *w = dynamic_cast<SchdispatchWindow*>(FindWindowById(WC_SCHDISPATCH_SLOTS, p1));
|
||||||
|
if (w != nullptr) {
|
||||||
|
w->schedule_index = INT_MAX;
|
||||||
|
w->AutoSelectSchedule();
|
||||||
|
w->ReInit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const NWidgetPart _nested_schdispatch_widgets[] = {
|
static const NWidgetPart _nested_schdispatch_widgets[] = {
|
||||||
NWidget(NWID_HORIZONTAL),
|
NWidget(NWID_HORIZONTAL),
|
||||||
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
|
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
|
||||||
@@ -702,6 +827,16 @@ static const NWidgetPart _nested_schdispatch_widgets[] = {
|
|||||||
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
|
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
|
||||||
NWidget(WWT_STICKYBOX, COLOUR_GREY),
|
NWidget(WWT_STICKYBOX, COLOUR_GREY),
|
||||||
EndContainer(),
|
EndContainer(),
|
||||||
|
NWidget(WWT_PANEL, COLOUR_GREY),
|
||||||
|
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
|
||||||
|
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCHDISPATCH_ENABLED), SetDataTip(STR_SCHDISPATCH_ENABLED, STR_SCHDISPATCH_ENABLED_TOOLTIP), SetFill(1, 1), SetResize(1, 0),
|
||||||
|
NWidget(WWT_TEXT, COLOUR_GREY, WID_SCHDISPATCH_HEADER), SetAlignment(SA_CENTER), SetDataTip(STR_JUST_STRING2, STR_NULL), SetFill(1, 1), SetResize(1, 0),
|
||||||
|
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
|
||||||
|
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCHDISPATCH_PREV), SetDataTip(STR_SCHDISPATCH_PREV_SCHEDULE, STR_SCHDISPATCH_PREV_SCHEDULE_TOOLTIP), SetFill(1, 1), SetResize(1, 0),
|
||||||
|
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCHDISPATCH_NEXT), SetDataTip(STR_SCHDISPATCH_NEXT_SCHEDULE, STR_SCHDISPATCH_NEXT_SCHEDULE_TOOLTIP), SetFill(1, 1), SetResize(1, 0),
|
||||||
|
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCHDISPATCH_ADD_SCHEDULE), SetDataTip(STR_SCHDISPATCH_ADD_SCHEDULE, STR_SCHDISPATCH_ADD_SCHEDULE_TOOLTIP), SetFill(1, 1), SetResize(1, 0),
|
||||||
|
EndContainer(),
|
||||||
|
EndContainer(),
|
||||||
NWidget(NWID_HORIZONTAL),
|
NWidget(NWID_HORIZONTAL),
|
||||||
NWidget(WWT_MATRIX, COLOUR_GREY, WID_SCHDISPATCH_MATRIX), SetResize(1, 1), SetScrollbar(WID_SCHDISPATCH_V_SCROLL),
|
NWidget(WWT_MATRIX, COLOUR_GREY, WID_SCHDISPATCH_MATRIX), SetResize(1, 1), SetScrollbar(WID_SCHDISPATCH_V_SCROLL),
|
||||||
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SCHDISPATCH_V_SCROLL),
|
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SCHDISPATCH_V_SCROLL),
|
||||||
@@ -709,8 +844,8 @@ static const NWidgetPart _nested_schdispatch_widgets[] = {
|
|||||||
NWidget(WWT_PANEL, COLOUR_GREY, WID_SCHDISPATCH_SUMMARY_PANEL), SetMinimalSize(400, 22), SetResize(1, 0), EndContainer(),
|
NWidget(WWT_PANEL, COLOUR_GREY, WID_SCHDISPATCH_SUMMARY_PANEL), SetMinimalSize(400, 22), SetResize(1, 0), EndContainer(),
|
||||||
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
|
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
|
||||||
NWidget(NWID_VERTICAL, NC_EQUALSIZE),
|
NWidget(NWID_VERTICAL, NC_EQUALSIZE),
|
||||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCHDISPATCH_ENABLED), SetDataTip(STR_SCHDISPATCH_ENABLED, STR_SCHDISPATCH_ENABLED_TOOLTIP), SetFill(1, 1), SetResize(1, 0),
|
|
||||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCHDISPATCH_ADD), SetDataTip(STR_SCHDISPATCH_ADD, STR_SCHDISPATCH_ADD_TOOLTIP), SetFill(1, 1), SetResize(1, 0),
|
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCHDISPATCH_ADD), SetDataTip(STR_SCHDISPATCH_ADD, STR_SCHDISPATCH_ADD_TOOLTIP), SetFill(1, 1), SetResize(1, 0),
|
||||||
|
NWidget(NWID_SPACER), SetFill(1, 1),
|
||||||
EndContainer(),
|
EndContainer(),
|
||||||
NWidget(NWID_VERTICAL, NC_EQUALSIZE),
|
NWidget(NWID_VERTICAL, NC_EQUALSIZE),
|
||||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCHDISPATCH_SET_DURATION), SetDataTip(STR_SCHDISPATCH_DURATION, STR_SCHDISPATCH_DURATION_TOOLTIP), SetFill(1, 1), SetResize(1, 0),
|
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCHDISPATCH_SET_DURATION), SetDataTip(STR_SCHDISPATCH_DURATION, STR_SCHDISPATCH_DURATION_TOOLTIP), SetFill(1, 1), SetResize(1, 0),
|
||||||
@@ -722,6 +857,7 @@ static const NWidgetPart _nested_schdispatch_widgets[] = {
|
|||||||
EndContainer(),
|
EndContainer(),
|
||||||
NWidget(WWT_RESIZEBOX, COLOUR_GREY),
|
NWidget(WWT_RESIZEBOX, COLOUR_GREY),
|
||||||
EndContainer(),
|
EndContainer(),
|
||||||
|
EndContainer(),
|
||||||
};
|
};
|
||||||
|
|
||||||
static WindowDesc _schdispatch_desc(
|
static WindowDesc _schdispatch_desc(
|
||||||
|
@@ -48,7 +48,7 @@ static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint32 val,
|
|||||||
}
|
}
|
||||||
order->SetWaitTime(val);
|
order->SetWaitTime(val);
|
||||||
order->SetWaitTimetabled(timetabled);
|
order->SetWaitTimetabled(timetabled);
|
||||||
if (HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH) && timetabled && order->IsWaitTimetabled() && v->GetFirstWaitingLocation(true) == order_number) {
|
if (HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH) && timetabled && order->IsScheduledDispatchOrder(true)) {
|
||||||
for (Vehicle *u = v->FirstShared(); u != nullptr; u = u->NextShared()) {
|
for (Vehicle *u = v->FirstShared(); u != nullptr; u = u->NextShared()) {
|
||||||
if (u->cur_implicit_order_index == order_number && (u->last_station_visited == order->GetDestination())) {
|
if (u->cur_implicit_order_index == order_number && (u->last_station_visited == order->GetDestination())) {
|
||||||
u->lateness_counter += timetable_delta;
|
u->lateness_counter += timetable_delta;
|
||||||
@@ -84,6 +84,18 @@ static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint32 val,
|
|||||||
order->SetLeaveType((OrderLeaveType)val);
|
order->SetLeaveType((OrderLeaveType)val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MTF_ASSIGN_SCHEDULE:
|
||||||
|
if ((int)val >= 0) {
|
||||||
|
for (int n = 0; n < v->GetNumOrders(); n++) {
|
||||||
|
Order *o = v->GetOrder(n);
|
||||||
|
if (o->GetDispatchScheduleIndex() == (int)val) {
|
||||||
|
o->SetDispatchScheduleIndex(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
order->SetDispatchScheduleIndex((int)val);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
}
|
}
|
||||||
@@ -119,6 +131,10 @@ static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint32 val,
|
|||||||
v->current_order.SetLeaveType((OrderLeaveType)val);
|
v->current_order.SetLeaveType((OrderLeaveType)val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MTF_ASSIGN_SCHEDULE:
|
||||||
|
v->current_order.SetDispatchScheduleIndex((int)val);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
}
|
}
|
||||||
@@ -170,6 +186,7 @@ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, u
|
|||||||
bool wait_fixed = order->IsWaitFixed();
|
bool wait_fixed = order->IsWaitFixed();
|
||||||
bool travel_fixed = order->IsTravelFixed();
|
bool travel_fixed = order->IsTravelFixed();
|
||||||
OrderLeaveType leave_type = order->GetLeaveType();
|
OrderLeaveType leave_type = order->GetLeaveType();
|
||||||
|
int dispatch_index = order->GetDispatchScheduleIndex();
|
||||||
switch (mtf) {
|
switch (mtf) {
|
||||||
case MTF_WAIT_TIME:
|
case MTF_WAIT_TIME:
|
||||||
wait_time = p2;
|
wait_time = p2;
|
||||||
@@ -199,6 +216,11 @@ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, u
|
|||||||
if (leave_type >= OLT_END) return CMD_ERROR;
|
if (leave_type >= OLT_END) return CMD_ERROR;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MTF_ASSIGN_SCHEDULE:
|
||||||
|
dispatch_index = (int)p2;
|
||||||
|
if (dispatch_index < -1 || dispatch_index >= (int)v->orders.list->GetScheduledDispatchScheduleCount()) return CMD_ERROR;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
}
|
}
|
||||||
@@ -223,6 +245,23 @@ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, u
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dispatch_index != order->GetDispatchScheduleIndex()) {
|
||||||
|
switch (order->GetType()) {
|
||||||
|
case OT_GOTO_STATION:
|
||||||
|
if (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) {
|
||||||
|
if (mtf == MTF_ASSIGN_SCHEDULE && dispatch_index == -1) break;
|
||||||
|
return_cmd_error(STR_ERROR_TIMETABLE_NOT_STOPPING_HERE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OT_GOTO_DEPOT:
|
||||||
|
case OT_GOTO_WAYPOINT:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: return_cmd_error(STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (travel_time != order->GetTravelTime() && order->IsType(OT_CONDITIONAL)) return CMD_ERROR;
|
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 (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 (wait_fixed != order->IsWaitFixed() && order->IsType(OT_CONDITIONAL)) return CMD_ERROR;
|
||||||
@@ -268,6 +307,12 @@ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, u
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MTF_ASSIGN_SCHEDULE:
|
||||||
|
if (dispatch_index != order->GetDispatchScheduleIndex()) {
|
||||||
|
ChangeTimetable(v, order_number, dispatch_index, MTF_ASSIGN_SCHEDULE, true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -733,21 +778,16 @@ void UpdateSeparationOrder(Vehicle *v_start)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsVehicleAtFirstWaitingLocation(const Vehicle *v)
|
static DateTicksScaled GetScheduledDispatchTime(const DispatchSchedule &ds, int wait_offset)
|
||||||
{
|
|
||||||
return (v->cur_implicit_order_index == v->GetFirstWaitingLocation(true));
|
|
||||||
}
|
|
||||||
|
|
||||||
static DateTicksScaled GetScheduledDispatchTime(Vehicle *v, int wait_offset)
|
|
||||||
{
|
{
|
||||||
DateTicksScaled first_slot = -1;
|
DateTicksScaled first_slot = -1;
|
||||||
const DateTicksScaled begin_time = v->orders.list->GetScheduledDispatchStartTick();
|
const DateTicksScaled begin_time = ds.GetScheduledDispatchStartTick();
|
||||||
const int32 last_dispatched_offset = v->orders.list->GetScheduledDispatchLastDispatch();
|
const int32 last_dispatched_offset = ds.GetScheduledDispatchLastDispatch();
|
||||||
const uint32 dispatch_duration = v->orders.list->GetScheduledDispatchDuration();
|
const uint32 dispatch_duration = ds.GetScheduledDispatchDuration();
|
||||||
const int32 max_delay = v->orders.list->GetScheduledDispatchDelay();
|
const int32 max_delay = ds.GetScheduledDispatchDelay();
|
||||||
|
|
||||||
/* Find next available slots */
|
/* Find next available slots */
|
||||||
for (auto current_offset : v->orders.list->GetScheduledDispatch()) {
|
for (auto current_offset : ds.GetScheduledDispatch()) {
|
||||||
if (current_offset >= dispatch_duration) continue;
|
if (current_offset >= dispatch_duration) continue;
|
||||||
if (int32(current_offset) <= last_dispatched_offset) {
|
if (int32(current_offset) <= last_dispatched_offset) {
|
||||||
current_offset += dispatch_duration * ((last_dispatched_offset + dispatch_duration - current_offset) / dispatch_duration);
|
current_offset += dispatch_duration * ((last_dispatched_offset + dispatch_duration - current_offset) / dispatch_duration);
|
||||||
@@ -801,17 +841,20 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling)
|
|||||||
bool set_scheduled_dispatch = false;
|
bool set_scheduled_dispatch = false;
|
||||||
|
|
||||||
/* Start scheduled dispatch at first opportunity */
|
/* Start scheduled dispatch at first opportunity */
|
||||||
if (HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH)) {
|
if (HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH) && v->cur_implicit_order_index != INVALID_VEH_ORDER_ID) {
|
||||||
if (IsVehicleAtFirstWaitingLocation(v) && travelling) {
|
Order *real_implicit_order = v->GetOrder(v->cur_implicit_order_index);
|
||||||
|
if (real_implicit_order->IsScheduledDispatchOrder(true) && travelling) {
|
||||||
|
DispatchSchedule &ds = v->orders.list->GetDispatchScheduleByIndex(real_implicit_order->GetDispatchScheduleIndex());
|
||||||
|
|
||||||
/* Update scheduled information */
|
/* Update scheduled information */
|
||||||
v->orders.list->UpdateScheduledDispatch();
|
ds.UpdateScheduledDispatch();
|
||||||
|
|
||||||
const int wait_offset = real_current_order->GetTimetabledWait();
|
const int wait_offset = real_current_order->GetTimetabledWait();
|
||||||
DateTicksScaled slot = GetScheduledDispatchTime(v, wait_offset);
|
DateTicksScaled slot = GetScheduledDispatchTime(ds, wait_offset);
|
||||||
if (slot > -1) {
|
if (slot > -1) {
|
||||||
SetBit(v->vehicle_flags, VF_TIMETABLE_STARTED);
|
SetBit(v->vehicle_flags, VF_TIMETABLE_STARTED);
|
||||||
v->lateness_counter = _scaled_date_ticks - slot + wait_offset;
|
v->lateness_counter = _scaled_date_ticks - slot + wait_offset;
|
||||||
v->orders.list->SetScheduledDispatchLastDispatch(slot - v->orders.list->GetScheduledDispatchStartTick());
|
ds.SetScheduledDispatchLastDispatch(slot - ds.GetScheduledDispatchStartTick());
|
||||||
set_scheduled_dispatch = true;
|
set_scheduled_dispatch = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -123,9 +123,6 @@ static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID
|
|||||||
table[i].arrival = table[i].departure = INVALID_TICKS;
|
table[i].arrival = table[i].departure = INVALID_TICKS;
|
||||||
}
|
}
|
||||||
|
|
||||||
VehicleOrderID scheduled_dispatch_order = INVALID_VEH_ORDER_ID;
|
|
||||||
if (HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH)) scheduled_dispatch_order = v->GetFirstWaitingLocation(true);
|
|
||||||
|
|
||||||
/* Cyclically loop over all orders until we reach the current one again.
|
/* Cyclically loop over all orders until we reach the current one again.
|
||||||
* As we may start at the current order, do a post-checking loop */
|
* As we may start at the current order, do a post-checking loop */
|
||||||
do {
|
do {
|
||||||
@@ -139,7 +136,7 @@ static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID
|
|||||||
table[i].arrival = sum;
|
table[i].arrival = sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == scheduled_dispatch_order && !(i == start && !travelling)) return;
|
if (order->IsScheduledDispatchOrder(true) && !(i == start && !travelling)) return;
|
||||||
if (!CanDetermineTimeTaken(order, false)) return;
|
if (!CanDetermineTimeTaken(order, false)) return;
|
||||||
sum += order->GetTimetabledWait();
|
sum += order->GetTimetabledWait();
|
||||||
table[i].departure = sum;
|
table[i].departure = sum;
|
||||||
@@ -240,12 +237,30 @@ void ProcessTimetableWarnings(const Vehicle *v, std::function<void(StringID, boo
|
|||||||
if (have_bad_full_load) handler(STR_TIMETABLE_WARNING_FULL_LOAD, true);
|
if (have_bad_full_load) handler(STR_TIMETABLE_WARNING_FULL_LOAD, true);
|
||||||
if (have_conditional && HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE)) handler(STR_TIMETABLE_WARNING_AUTOFILL_CONDITIONAL, true);
|
if (have_conditional && HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE)) handler(STR_TIMETABLE_WARNING_AUTOFILL_CONDITIONAL, true);
|
||||||
if (total_time && have_non_timetabled_conditional_branch) handler(STR_TIMETABLE_NON_TIMETABLED_BRANCH, false);
|
if (total_time && have_non_timetabled_conditional_branch) handler(STR_TIMETABLE_NON_TIMETABLED_BRANCH, false);
|
||||||
if (HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH)) {
|
if (HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH) && v->orders.list != nullptr) {
|
||||||
VehicleOrderID n = v->GetFirstWaitingLocation(false);
|
auto sd_warning = [&](int schedule_index, StringID str) {
|
||||||
if (n == INVALID_VEH_ORDER_ID) {
|
if (v->orders.list->GetScheduledDispatchScheduleCount() > 1) {
|
||||||
handler(STR_TIMETABLE_WARNING_NO_SCHEDULED_DISPATCH_ORDER, true);
|
SetDParam(0, schedule_index + 1);
|
||||||
} else if (!v->GetOrder(n)->IsWaitTimetabled()) {
|
SetDParam(1, str);
|
||||||
handler(STR_TIMETABLE_WARNING_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME, true);
|
handler(STR_TIMETABLE_WARNING_SCHEDULE_ID, true);
|
||||||
|
} else {
|
||||||
|
handler(str, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
std::vector<bool> seen_sched_dispatch_orders(v->orders.list->GetScheduledDispatchScheduleCount());
|
||||||
|
|
||||||
|
for (int n = 0; n < v->GetNumOrders(); n++) {
|
||||||
|
const Order *order = v->GetOrder(n);
|
||||||
|
int schedule_index = order->GetDispatchScheduleIndex();
|
||||||
|
if (schedule_index >= 0) {
|
||||||
|
seen_sched_dispatch_orders[schedule_index] = true;
|
||||||
|
if (!order->IsWaitTimetabled()) {
|
||||||
|
sd_warning(schedule_index, STR_TIMETABLE_WARNING_SCHEDULED_DISPATCH_ORDER_NO_WAIT_TIME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (uint i = 0; i < seen_sched_dispatch_orders.size(); i++) {
|
||||||
|
if (!seen_sched_dispatch_orders[i]) sd_warning(i, STR_TIMETABLE_WARNING_NO_SCHEDULED_DISPATCH_ORDER_ASSIGNED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -483,6 +498,7 @@ struct TimetableWindow : Window {
|
|||||||
this->SetWidgetDisabledState(WID_VT_LOCK_ORDER_TIME, !wait_lockable);
|
this->SetWidgetDisabledState(WID_VT_LOCK_ORDER_TIME, !wait_lockable);
|
||||||
this->SetWidgetLoweredState(WID_VT_LOCK_ORDER_TIME, wait_locked);
|
this->SetWidgetLoweredState(WID_VT_LOCK_ORDER_TIME, wait_locked);
|
||||||
this->SetWidgetDisabledState(WID_VT_EXTRA, disable || (selected % 2 != 0));
|
this->SetWidgetDisabledState(WID_VT_EXTRA, disable || (selected % 2 != 0));
|
||||||
|
this->SetWidgetDisabledState(WID_VT_ASSIGN_SCHEDULE, disable || (selected % 2 != 0) || !HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH));
|
||||||
} else {
|
} else {
|
||||||
this->DisableWidget(WID_VT_START_DATE);
|
this->DisableWidget(WID_VT_START_DATE);
|
||||||
this->DisableWidget(WID_VT_CHANGE_TIME);
|
this->DisableWidget(WID_VT_CHANGE_TIME);
|
||||||
@@ -497,14 +513,17 @@ struct TimetableWindow : Window {
|
|||||||
this->DisableWidget(WID_VT_ADD_VEH_GROUP);
|
this->DisableWidget(WID_VT_ADD_VEH_GROUP);
|
||||||
this->DisableWidget(WID_VT_LOCK_ORDER_TIME);
|
this->DisableWidget(WID_VT_LOCK_ORDER_TIME);
|
||||||
this->DisableWidget(WID_VT_EXTRA);
|
this->DisableWidget(WID_VT_EXTRA);
|
||||||
|
this->DisableWidget(WID_VT_ASSIGN_SCHEDULE);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->SetWidgetLoweredState(WID_VT_AUTOFILL, HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE));
|
this->SetWidgetLoweredState(WID_VT_AUTOFILL, HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE));
|
||||||
this->SetWidgetLoweredState(WID_VT_AUTOMATE, HasBit(v->vehicle_flags, VF_AUTOMATE_TIMETABLE));
|
this->SetWidgetLoweredState(WID_VT_AUTOMATE, HasBit(v->vehicle_flags, VF_AUTOMATE_TIMETABLE));
|
||||||
this->SetWidgetLoweredState(WID_VT_AUTO_SEPARATION, HasBit(v->vehicle_flags, VF_TIMETABLE_SEPARATION));
|
this->SetWidgetLoweredState(WID_VT_AUTO_SEPARATION, HasBit(v->vehicle_flags, VF_TIMETABLE_SEPARATION));
|
||||||
this->SetWidgetLoweredState(WID_VT_SCHEDULED_DISPATCH, HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH));
|
this->SetWidgetLoweredState(WID_VT_SCHEDULED_DISPATCH, HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH));
|
||||||
|
this->SetWidgetLoweredState(WID_VT_SCHEDULED_DISPATCH, HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH));
|
||||||
|
|
||||||
this->SetWidgetDisabledState(WID_VT_SCHEDULED_DISPATCH, v->orders.list == nullptr);
|
this->SetWidgetDisabledState(WID_VT_SCHEDULED_DISPATCH, v->orders.list == nullptr);
|
||||||
|
this->GetWidget<NWidgetStacked>(WID_VT_START_DATE_SELECTION)->SetDisplayedPlane(HasBit(v->vehicle_flags, VF_SCHEDULED_DISPATCH) ? 1 : 0);
|
||||||
|
|
||||||
this->DrawWidgets();
|
this->DrawWidgets();
|
||||||
}
|
}
|
||||||
@@ -944,6 +963,22 @@ struct TimetableWindow : Window {
|
|||||||
ShowDropDownList(this, std::move(list), order != nullptr ? order->GetLeaveType() : -1, WID_VT_EXTRA);
|
ShowDropDownList(this, std::move(list), order != nullptr ? order->GetLeaveType() : -1, WID_VT_EXTRA);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case WID_VT_ASSIGN_SCHEDULE: {
|
||||||
|
VehicleOrderID real = (this->sel_index + 1) / 2;
|
||||||
|
if (real >= this->vehicle->GetNumOrders()) real = 0;
|
||||||
|
const Order *order = this->vehicle->GetOrder(real);
|
||||||
|
DropDownList list;
|
||||||
|
list.emplace_back(new DropDownListStringItem(STR_TIMETABLE_ASSIGN_SCHEDULE_NONE, -1, false));
|
||||||
|
|
||||||
|
for (uint i = 0; i < v->orders.list->GetScheduledDispatchScheduleCount(); i++) {
|
||||||
|
DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_TIMETABLE_ASSIGN_SCHEDULE_ID, i, false);
|
||||||
|
item->SetParam(0, i + 1);
|
||||||
|
list.emplace_back(item);
|
||||||
|
}
|
||||||
|
ShowDropDownList(this, std::move(list), order->GetDispatchScheduleIndex(), WID_VT_ASSIGN_SCHEDULE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->SetDirty();
|
this->SetDirty();
|
||||||
@@ -952,9 +987,13 @@ struct TimetableWindow : Window {
|
|||||||
void OnDropdownSelect(int widget, int index) override
|
void OnDropdownSelect(int widget, int index) override
|
||||||
{
|
{
|
||||||
switch (widget) {
|
switch (widget) {
|
||||||
case WID_VT_EXTRA: {
|
case WID_VT_EXTRA:
|
||||||
ExecuteTimetableCommand(this->vehicle, false, this->sel_index, MTF_SET_LEAVE_TYPE, index, false);
|
ExecuteTimetableCommand(this->vehicle, false, this->sel_index, MTF_SET_LEAVE_TYPE, index, false);
|
||||||
}
|
break;
|
||||||
|
|
||||||
|
case WID_VT_ASSIGN_SCHEDULE:
|
||||||
|
ExecuteTimetableCommand(this->vehicle, false, this->sel_index, MTF_ASSIGN_SCHEDULE, index, false);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -1068,7 +1107,10 @@ static const NWidgetPart _nested_timetable_widgets[] = {
|
|||||||
NWidget(NWID_HORIZONTAL),
|
NWidget(NWID_HORIZONTAL),
|
||||||
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
|
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
|
||||||
NWidget(NWID_VERTICAL, NC_EQUALSIZE),
|
NWidget(NWID_VERTICAL, NC_EQUALSIZE),
|
||||||
|
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_VT_START_DATE_SELECTION),
|
||||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_START_DATE), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_STARTING_DATE, STR_TIMETABLE_STARTING_DATE_TOOLTIP),
|
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_START_DATE), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_STARTING_DATE, STR_TIMETABLE_STARTING_DATE_TOOLTIP),
|
||||||
|
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VT_ASSIGN_SCHEDULE), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_ASSIGN_SCHEDULE_DROP_DOWN, STR_TIMETABLE_ASSIGN_SCHEDULE_DROP_DOWN_TOOLTIP),
|
||||||
|
EndContainer(),
|
||||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_CHANGE_TIME), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_CHANGE_TIME, STR_TIMETABLE_WAIT_TIME_TOOLTIP),
|
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_CHANGE_TIME), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_CHANGE_TIME, STR_TIMETABLE_WAIT_TIME_TOOLTIP),
|
||||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_CLEAR_TIME), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_CLEAR_TIME, STR_TIMETABLE_CLEAR_TIME_TOOLTIP),
|
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_CLEAR_TIME), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_CLEAR_TIME, STR_TIMETABLE_CLEAR_TIME_TOOLTIP),
|
||||||
EndContainer(),
|
EndContainer(),
|
||||||
|
@@ -37,6 +37,8 @@ enum VehicleTimetableWidgets {
|
|||||||
WID_VT_SCHEDULED_DISPATCH, ///< Scheduled Dispatch button.
|
WID_VT_SCHEDULED_DISPATCH, ///< Scheduled Dispatch button.
|
||||||
WID_VT_LOCK_ORDER_TIME, ///< Lock order time button.
|
WID_VT_LOCK_ORDER_TIME, ///< Lock order time button.
|
||||||
WID_VT_EXTRA, ///< Extra drop down menu.
|
WID_VT_EXTRA, ///< Extra drop down menu.
|
||||||
|
WID_VT_ASSIGN_SCHEDULE, ///< Assign scheduled dispatch schedule.
|
||||||
|
WID_VT_START_DATE_SELECTION, ///< #NWID_SELECTION widget for WID_VT_START_DATE and WID_VT_ASSIGN_SCHEDULE.
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* WIDGETS_TIMETABLE_WIDGET_H */
|
#endif /* WIDGETS_TIMETABLE_WIDGET_H */
|
||||||
|
Reference in New Issue
Block a user