Departures: Adjust departure/arrival detection, allow all modes for waypoints

This commit is contained in:
Jonathan G Rennison 2024-09-04 20:31:41 +01:00
parent fa361ef9e9
commit 67bc20a9a9
4 changed files with 55 additions and 48 deletions

View File

@ -63,30 +63,32 @@ struct OrderDate {
}
};
static bool IsDeparture(const Order *order, StationID station) {
return (order->GetType() == OT_GOTO_STATION &&
(StationID)order->GetDestination() == station &&
(order->GetLoadType() != OLFB_NO_LOAD ||
_settings_client.gui.departure_show_all_stops) &&
(order->GetWaitTime() != 0 || order->IsWaitTimetabled()) &&
!(order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION));
template <typename LOAD_FILTER>
bool IsArrivalDepartureTest(const DepartureCallingSettings &settings, const Order *order, StationID station, LOAD_FILTER load_filter)
{
if (order->GetType() == OT_GOTO_STATION && (StationID)order->GetDestination() == station) {
if (!settings.departure_no_load_test && !load_filter(order)) return false;
return settings.allow_via || ((order->GetWaitTime() != 0 || order->IsWaitTimetabled()) && !(order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION));
} else if (order->GetType() == OT_GOTO_WAYPOINT && (StationID)order->GetDestination() == station) {
if (settings.allow_via) return true;
return (order->GetWaitTime() != 0 || order->IsWaitTimetabled());
} else {
return false;
}
}
static bool IsVia(const Order *order, StationID station) {
return ((order->GetType() == OT_GOTO_STATION ||
order->GetType() == OT_GOTO_WAYPOINT) &&
(StationID)order->GetDestination() == station &&
(order->GetNonStopType() == ONSF_NO_STOP_AT_ANY_STATION ||
order->GetNonStopType() == ONSF_NO_STOP_AT_DESTINATION_STATION));
bool DepartureCallingSettings::IsDeparture(const Order *order, StationID station)
{
return IsArrivalDepartureTest(*this, order, station, [](const Order *order) {
return order->GetLoadType() != OLFB_NO_LOAD;
});
}
static bool IsArrival(const Order *order, StationID station) {
return (order->GetType() == OT_GOTO_STATION &&
(StationID)order->GetDestination() == station &&
(order->GetUnloadType() != OUFB_NO_UNLOAD ||
_settings_client.gui.departure_show_all_stops) &&
(order->GetWaitTime() != 0 || order->IsWaitTimetabled()) &&
!(order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION));
bool DepartureCallingSettings::IsArrival(const Order *order, StationID station)
{
return IsArrivalDepartureTest(*this, order, station, [](const Order *order) {
return order->GetUnloadType() != OUFB_NO_UNLOAD;
});
}
static uint8_t GetDepartureConditionalOrderMode(const Order *order, const Vehicle *v, StateTicks eval_tick, const ScheduledDispatchVehicleRecords &records)
@ -262,12 +264,12 @@ static void ScheduledDispatchDepartureLocalFix(DepartureList &departure_list)
* @param station the station to compute the departures of
* @param vehicles set of all the vehicles stopping at this station, of all vehicles types that we are interested in
* @param type the type of departures to get (departures or arrivals)
* @param show_vehicles_via whether to include vehicles that have this station in their orders but do not stop at it
* @param calling_settings departure calling settings
* @param show_pax whether to include passenger vehicles
* @param show_freight whether to include freight vehicles
* @return a list of departures, which is empty if an error occurred
*/
DepartureList MakeDepartureList(StationID station, const std::vector<const Vehicle *> &vehicles, DepartureType type, bool show_vehicles_via, bool show_pax, bool show_freight)
DepartureList MakeDepartureList(StationID station, const std::vector<const Vehicle *> &vehicles, DepartureType type, DepartureCallingSettings calling_settings, bool show_pax, bool show_freight)
{
/* This function is the meat of the departure boards functionality. */
/* As an overview, it works by repeatedly considering the best possible next departure to show. */
@ -415,9 +417,8 @@ DepartureList MakeDepartureList(StationID station, const std::vector<const Vehic
/* If the vehicle will be stopping at and loading from this station, and its wait time is not zero, then it is a departure. */
/* If the vehicle will be stopping at and unloading at this station, and its wait time is not zero, then it is an arrival. */
if ((type == D_DEPARTURE && IsDeparture(order, station)) ||
(type == D_DEPARTURE && show_vehicles_via && IsVia(order, station)) ||
(type == D_ARRIVAL && IsArrival(order, station))) {
if ((type == D_DEPARTURE && calling_settings.IsDeparture(order, station)) ||
(type == D_ARRIVAL && calling_settings.IsArrival(order, station))) {
/* If the departure was scheduled to have already begun and has been cancelled, do not show it. */
if (start_ticks < 0 && status == D_CANCELLED) {
break;
@ -579,7 +580,7 @@ DepartureList MakeDepartureList(StationID station, const std::vector<const Vehic
if (order->GetType() == OT_GOTO_STATION &&
(StationID)order->GetDestination() == station &&
(order->GetUnloadType() != OUFB_NO_UNLOAD ||
_settings_client.gui.departure_show_all_stops) &&
calling_settings.show_all_stops) &&
(((order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) == 0) || ((least_order->order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) != 0))) {
/* If we're not calling anywhere, then skip this departure. */
found_terminus = (d->calling_at.size() > 0);
@ -621,7 +622,7 @@ DepartureList MakeDepartureList(StationID station, const std::vector<const Vehic
/* We're not interested in this order any further if we're not calling at it. */
if ((order->GetUnloadType() == OUFB_NO_UNLOAD &&
!_settings_client.gui.departure_show_all_stops) ||
!calling_settings.show_all_stops) ||
(order->GetType() != OT_GOTO_STATION &&
order->GetType() != OT_IMPLICIT) ||
order->GetNonStopType() == ONSF_NO_STOP_AT_ANY_STATION ||
@ -740,7 +741,7 @@ DepartureList MakeDepartureList(StationID station, const std::vector<const Vehic
while (candidate_origin != least_order->order) {
if ((candidate_origin->GetLoadType() != OLFB_NO_LOAD ||
_settings_client.gui.departure_show_all_stops) &&
calling_settings.show_all_stops) &&
(candidate_origin->GetType() == OT_GOTO_STATION ||
candidate_origin->GetType() == OT_IMPLICIT) &&
candidate_origin->GetDestination() != station &&
@ -782,7 +783,7 @@ DepartureList MakeDepartureList(StationID station, const std::vector<const Vehic
while (order != least_order->order) {
if (order->GetType() == OT_GOTO_STATION &&
(order->GetLoadType() != OLFB_NO_LOAD ||
_settings_client.gui.departure_show_all_stops) &&
calling_settings.show_all_stops) &&
(order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) == 0) {
d->calling_at.push_back(CallAt((StationID)order->GetDestination()));
}
@ -873,9 +874,8 @@ DepartureList MakeDepartureList(StationID station, const std::vector<const Vehic
}
/* If the order loads from this station (or unloads if we're computing arrivals) and has a wait time set, then it is suitable for being a departure. */
if ((type == D_DEPARTURE && IsDeparture(order, station)) ||
(type == D_DEPARTURE && show_vehicles_via && IsVia(order, station)) ||
(type == D_ARRIVAL && IsArrival(order, station))) {
if ((type == D_DEPARTURE && calling_settings.IsDeparture(order, station)) ||
(type == D_ARRIVAL && calling_settings.IsArrival(order, station))) {
least_order->order = order;
found_next_order = true;
break;

View File

@ -17,8 +17,8 @@
#include <vector>
DepartureList MakeDepartureList(StationID station, const std::vector<const Vehicle *> &vehicles, DepartureType type = D_DEPARTURE,
bool show_vehicles_via = false, bool show_pax = true, bool show_freight = true);
DepartureList MakeDepartureList(StationID station, const std::vector<const Vehicle *> &vehicles, DepartureType type,
DepartureCallingSettings calling_settings, bool show_pax = true, bool show_freight = true);
Ticks GetDeparturesMaxTicksAhead();

View File

@ -248,11 +248,9 @@ public:
this->DisableWidget(WID_DB_SHOW_TRAINS + i);
}
this->DisableWidget(WID_DB_DEPARTURE_MODE);
this->DisableWidget(WID_DB_SHOW_VIA);
this->show_via = true;
this->LowerWidget(WID_DB_SHOW_VIA);
this->DisableWidget(WID_DB_SHOW_VIA);
} else {
this->mode = static_cast<DeparturesMode>(_settings_client.gui.departure_default_mode);
this->show_via = _settings_client.gui.departure_default_via;
@ -447,18 +445,12 @@ public:
case WID_DB_DEPARTURE_MODE: {
if (this->mode != index) {
this->mode = static_cast<DeparturesMode>(index);
if (this->mode == DM_ARRIVALS) {
this->show_via = false;
this->RaiseWidget(WID_DB_SHOW_VIA);
this->DisableWidget(WID_DB_SHOW_VIA);
} else {
this->EnableWidget(WID_DB_SHOW_VIA);
this->SetWidgetLoweredState(WID_DB_SHOW_VIA, this->show_via);
}
this->calc_tick_countdown = 0;
if (_pause_mode != PM_UNPAUSED) this->OnGameTick();
}
_settings_client.gui.departure_default_mode = this->mode;
if (!this->is_waypoint) {
_settings_client.gui.departure_default_mode = this->mode;
}
this->SetWidgetDirty(widget);
break;
}
@ -489,13 +481,19 @@ public:
this->calc_tick_countdown = _settings_client.gui.departure_calc_frequency;
bool show_pax = this->cargo_mode != DCF_FREIGHT_ONLY;
bool show_freight = this->cargo_mode != DCF_PAX_ONLY;
DepartureCallingSettings settings;
settings.allow_via = this->is_waypoint || this->show_via;
settings.departure_no_load_test = this->is_waypoint || _settings_client.gui.departure_show_all_stops;
settings.show_all_stops = _settings_client.gui.departure_show_all_stops;
if (this->mode != DM_ARRIVALS) {
this->departures = MakeDepartureList(this->station, this->vehicles, D_DEPARTURE, this->is_waypoint || this->show_via, show_pax, show_freight);
this->departures = MakeDepartureList(this->station, this->vehicles, D_DEPARTURE, settings, show_pax, show_freight);
} else {
this->departures.clear();
}
if (this->mode == DM_ARRIVALS || this->mode == DM_SEPARATE) {
this->arrivals = MakeDepartureList(this->station, this->vehicles, D_ARRIVAL, false, show_pax, show_freight);
this->arrivals = MakeDepartureList(this->station, this->vehicles, D_ARRIVAL, settings, show_pax, show_freight);
} else {
this->arrivals.clear();
}

View File

@ -113,6 +113,15 @@ struct Departure {
}
};
struct DepartureCallingSettings {
bool allow_via = false;
bool departure_no_load_test = false;
bool show_all_stops = false;
bool IsDeparture(const Order *order, StationID station);
bool IsArrival(const Order *order, StationID station);
};
typedef std::vector<std::unique_ptr<Departure>> DepartureList;
#endif /* DEPARTURES_TYPE_H */