Codechange: Use enum class and EnumBitSet for various order flags. (#14783)

This commit is contained in:
Peter Nelson
2025-12-06 12:29:11 +00:00
committed by dP
parent 40b58429e6
commit e858b2d7b0
20 changed files with 358 additions and 340 deletions

View File

@@ -130,7 +130,7 @@ static StationID FindNearestHangar(const Aircraft *v)
const Station *next_dest = nullptr;
if (max_range != 0) {
if (v->current_order.IsType(OT_GOTO_STATION) ||
(v->current_order.IsType(OT_GOTO_DEPOT) && (v->current_order.GetDepotActionType() & ODATFB_NEAREST_DEPOT) == 0)) {
(v->current_order.IsType(OT_GOTO_DEPOT) && !v->current_order.GetDepotActionType().Test(OrderDepotActionFlag::NearestDepot))) {
last_dest = Station::GetIfValid(v->last_station_visited);
next_dest = Station::GetIfValid(v->current_order.GetDestination().ToStationID());
} else {
@@ -428,7 +428,7 @@ static void CheckIfAircraftNeedsService(Aircraft *v)
/* only goto depot if the target airport has a depot */
if (st->airport.HasHangar() && CanVehicleUseStation(v, st)) {
v->current_order.MakeGoToDepot(st->index, ODTFB_SERVICE);
v->current_order.MakeGoToDepot(st->index, OrderDepotTypeFlag::Service);
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
} else if (v->current_order.IsType(OT_GOTO_DEPOT)) {
v->current_order.MakeDummy();
@@ -2187,7 +2187,7 @@ void UpdateAirplanesOnNewStation(const Station *st)
Order *o = &v->current_order;
/* The aircraft is heading to a hangar, but the new station doesn't have one,
* or the aircraft can't land on the new station. Cancel current order. */
if (o->IsType(OT_GOTO_DEPOT) && !(o->GetDepotOrderType() & ODTFB_PART_OF_ORDERS) && o->GetDestination() == st->index &&
if (o->IsType(OT_GOTO_DEPOT) && !o->GetDepotOrderType().Test(OrderDepotTypeFlag::PartOfOrders) && o->GetDestination() == st->index &&
(!st->airport.HasHangar() || !CanVehicleUseStation(v, st))) {
o->MakeDummy();
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);

View File

@@ -233,7 +233,7 @@ CommandCost CmdClearOrderBackup(DoCommandFlags flags, TileIndex tile, ClientID u
for (OrderBackup *ob : OrderBackup::Iterate()) {
for (Order &order : ob->orders) {
OrderType ot = order.GetType();
if (ot == OT_GOTO_DEPOT && (order.GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) continue;
if (ot == OT_GOTO_DEPOT && order.GetDepotActionType().Test(OrderDepotActionFlag::NearestDepot)) continue;
if (ot == OT_GOTO_DEPOT && hangar && !IsHangarTile(ob->tile)) continue; // Not an aircraft? Can't have a hangar order.
if (ot == OT_IMPLICIT || (IsHangarTile(ob->tile) && ot == OT_GOTO_DEPOT && !hangar)) ot = OT_GOTO_STATION;
if (ot == type && order.GetDestination() == destination) {

View File

@@ -74,7 +74,7 @@ public:
void Free();
void MakeGoToStation(StationID destination);
void MakeGoToDepot(DestinationID destination, OrderDepotTypeFlags order, OrderNonStopFlags non_stop_type = ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS, OrderDepotActionFlags action = ODATF_SERVICE_ONLY, CargoType cargo = CARGO_NO_REFIT);
void MakeGoToDepot(DestinationID destination, OrderDepotTypeFlags order, OrderNonStopFlags non_stop_type = OrderNonStopFlag::NoIntermediate, OrderDepotActionFlags action = {}, CargoType cargo = CARGO_NO_REFIT);
void MakeGoToWaypoint(StationID destination);
void MakeLoading(bool ordered);
void MakeLeaveStation();
@@ -133,17 +133,17 @@ public:
/** How must the consist be unloaded? */
inline OrderUnloadFlags GetUnloadType() const { return (OrderUnloadFlags)GB(this->flags, 0, 3); }
/** At which stations must we stop? */
inline OrderNonStopFlags GetNonStopType() const { return (OrderNonStopFlags)GB(this->type, 6, 2); }
inline OrderNonStopFlags GetNonStopType() const { return static_cast<OrderNonStopFlags>(GB(this->type, 6, 2)); }
/** Where must we stop at the platform? */
inline OrderStopLocation GetStopLocation() const { return (OrderStopLocation)GB(this->type, 4, 2); }
inline OrderStopLocation GetStopLocation() const { return static_cast<OrderStopLocation>(GB(this->type, 4, 2)); }
/** What caused us going to the depot? */
inline OrderDepotTypeFlags GetDepotOrderType() const { return (OrderDepotTypeFlags)GB(this->flags, 0, 3); }
inline OrderDepotTypeFlags GetDepotOrderType() const { return static_cast<OrderDepotTypeFlags>(GB(this->flags, 0, 3)); }
/** What are we going to do when in the depot. */
inline OrderDepotActionFlags GetDepotActionType() const { return (OrderDepotActionFlags)GB(this->flags, 3, 4); }
inline OrderDepotActionFlags GetDepotActionType() const { return static_cast<OrderDepotActionFlags>(GB(this->flags, 3, 4)); }
/** What variable do we have to compare? */
inline OrderConditionVariable GetConditionVariable() const { return static_cast<OrderConditionVariable>(GB(this->dest.value, 11, 5)); }
/** What is the comparator to use? */
inline OrderConditionComparator GetConditionComparator() const { return (OrderConditionComparator)GB(this->type, 5, 3); }
inline OrderConditionComparator GetConditionComparator() const { return static_cast<OrderConditionComparator>(GB(this->type, 5, 3)); }
/** Get the order to skip to. */
inline VehicleOrderID GetConditionSkipToOrder() const { return this->flags; }
/** Get the value to base the skip on. */
@@ -154,17 +154,17 @@ public:
/** Set how the consist must be unloaded. */
inline void SetUnloadType(OrderUnloadFlags unload_type) { SB(this->flags, 0, 3, unload_type); }
/** Set whether we must stop at stations or not. */
inline void SetNonStopType(OrderNonStopFlags non_stop_type) { SB(this->type, 6, 2, non_stop_type); }
inline void SetNonStopType(OrderNonStopFlags non_stop_type) { SB(this->type, 6, 2, non_stop_type.base()); }
/** Set where we must stop at the platform. */
inline void SetStopLocation(OrderStopLocation stop_location) { SB(this->type, 4, 2, stop_location); }
inline void SetStopLocation(OrderStopLocation stop_location) { SB(this->type, 4, 2, to_underlying(stop_location)); }
/** Set the cause to go to the depot. */
inline void SetDepotOrderType(OrderDepotTypeFlags depot_order_type) { SB(this->flags, 0, 3, depot_order_type); }
inline void SetDepotOrderType(OrderDepotTypeFlags depot_order_type) { SB(this->flags, 0, 3, depot_order_type.base()); }
/** Set what we are going to do in the depot. */
inline void SetDepotActionType(OrderDepotActionFlags depot_service_type) { SB(this->flags, 3, 4, depot_service_type); }
inline void SetDepotActionType(OrderDepotActionFlags depot_service_type) { SB(this->flags, 3, 4, depot_service_type.base()); }
/** Set variable we have to compare. */
inline void SetConditionVariable(OrderConditionVariable condition_variable) { SB(this->dest.value, 11, 5, condition_variable); }
inline void SetConditionVariable(OrderConditionVariable condition_variable) { SB(this->dest.value, 11, 5, to_underlying(condition_variable)); }
/** Set the comparator to use. */
inline void SetConditionComparator(OrderConditionComparator condition_comparator) { SB(this->type, 5, 3, condition_comparator); }
inline void SetConditionComparator(OrderConditionComparator condition_comparator) { SB(this->type, 5, 3, to_underlying(condition_comparator)); }
/** Get the order to skip to. */
inline void SetConditionSkipToOrder(VehicleOrderID order_id) { this->flags = order_id; }
/** Set the value to base the skip on. */
@@ -231,7 +231,7 @@ public:
{
if (!this->IsTravelTimetabled() && !this->IsType(OT_CONDITIONAL)) return false;
if (!this->IsWaitTimetabled() && this->IsType(OT_GOTO_STATION) &&
!(this->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION)) {
!this->GetNonStopType().Test(OrderNonStopFlag::NoDestination)) {
return false;
}
return true;

View File

@@ -164,10 +164,10 @@ bool Order::Equals(const Order &other) const
* evaluation. If we do not do this the order will continuously be seen as
* a different order and it will try to find a "nearest depot" every tick. */
if ((this->IsType(OT_GOTO_DEPOT) && this->type == other.type) &&
((this->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0 ||
(other.GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0)) {
(this->GetDepotActionType().Test(OrderDepotActionFlag::NearestDepot) ||
other.GetDepotActionType().Test(OrderDepotActionFlag::NearestDepot))) {
return this->GetDepotOrderType() == other.GetDepotOrderType() &&
(this->GetDepotActionType() & ~ODATFB_NEAREST_DEPOT) == (other.GetDepotActionType() & ~ODATFB_NEAREST_DEPOT);
this->GetDepotActionType().Reset(OrderDepotActionFlag::NearestDepot) == other.GetDepotActionType().Reset(OrderDepotActionFlag::NearestDepot);
}
return this->type == other.type && this->flags == other.flags && this->dest == other.dest;
@@ -185,11 +185,11 @@ uint16_t Order::MapOldOrder() const
case OT_GOTO_STATION:
if (this->GetUnloadType() & OUFB_UNLOAD) SetBit(order, 5);
if (this->GetLoadType() & OLFB_FULL_LOAD) SetBit(order, 6);
if (this->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) SetBit(order, 7);
if (this->GetNonStopType().Test(OrderNonStopFlag::NoIntermediate)) SetBit(order, 7);
order |= GB(this->GetDestination().value, 0, 8) << 8;
break;
case OT_GOTO_DEPOT:
if (!(this->GetDepotOrderType() & ODTFB_PART_OF_ORDERS)) SetBit(order, 6);
if (!this->GetDepotOrderType().Test(OrderDepotTypeFlag::PartOfOrders)) SetBit(order, 6);
SetBit(order, 7);
order |= GB(this->GetDestination().value, 0, 8) << 8;
break;
@@ -331,7 +331,7 @@ VehicleOrderID OrderList::GetNextDecisionNode(VehicleOrderID next, uint hops) co
const Order &order_next = this->orders[next];
if (order_next.IsType(OT_CONDITIONAL)) {
if (order_next.GetConditionVariable() != OCV_UNCONDITIONALLY) return next;
if (order_next.GetConditionVariable() != OrderConditionVariable::Unconditionally) return next;
/* We can evaluate trivial conditions right away. They're conceptually
* the same as regular order progression. */
@@ -341,7 +341,7 @@ VehicleOrderID OrderList::GetNextDecisionNode(VehicleOrderID next, uint hops) co
}
if (order_next.IsType(OT_GOTO_DEPOT)) {
if ((order_next.GetDepotActionType() & ODATFB_HALT) != 0) return INVALID_VEH_ORDER_ID;
if (order_next.GetDepotActionType().Test(OrderDepotActionFlag::Halt)) return INVALID_VEH_ORDER_ID;
if (order_next.IsRefit()) return next;
}
@@ -648,7 +648,7 @@ CommandCost CmdInsertOrder(DoCommandFlags flags, VehicleID veh, VehicleOrderID s
}
/* Non stop only allowed for ground vehicles. */
if (new_order.GetNonStopType() != ONSF_STOP_EVERYWHERE && !v->IsGroundVehicle()) return CMD_ERROR;
if (new_order.GetNonStopType().Any() && !v->IsGroundVehicle()) return CMD_ERROR;
/* Filter invalid load/unload types. */
switch (new_order.GetLoadType()) {
@@ -671,12 +671,12 @@ CommandCost CmdInsertOrder(DoCommandFlags flags, VehicleID veh, VehicleOrderID s
/* Filter invalid stop locations */
switch (new_order.GetStopLocation()) {
case OSL_PLATFORM_NEAR_END:
case OSL_PLATFORM_MIDDLE:
case OrderStopLocation::NearEnd:
case OrderStopLocation::Middle:
if (v->type != VEH_TRAIN) return CMD_ERROR;
[[fallthrough]];
case OSL_PLATFORM_FAR_END:
case OrderStopLocation::FarEnd:
break;
default:
@@ -687,7 +687,7 @@ CommandCost CmdInsertOrder(DoCommandFlags flags, VehicleID veh, VehicleOrderID s
}
case OT_GOTO_DEPOT: {
if ((new_order.GetDepotActionType() & ODATFB_NEAREST_DEPOT) == 0) {
if (!new_order.GetDepotActionType().Test(OrderDepotActionFlag::NearestDepot)) {
if (v->type == VEH_AIRCRAFT) {
const Station *st = Station::GetIfValid(new_order.GetDestination().ToStationID());
@@ -725,15 +725,22 @@ CommandCost CmdInsertOrder(DoCommandFlags flags, VehicleID veh, VehicleOrderID s
}
}
if (new_order.GetNonStopType() != ONSF_STOP_EVERYWHERE && !v->IsGroundVehicle()) return CMD_ERROR;
if (new_order.GetDepotOrderType() & ~(ODTFB_PART_OF_ORDERS | ((new_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) != 0 ? ODTFB_SERVICE : 0))) return CMD_ERROR;
if (new_order.GetDepotActionType() & ~(ODATFB_HALT | ODATFB_NEAREST_DEPOT | ODATFB_UNBUNCH)) return CMD_ERROR;
if (new_order.GetNonStopType().Any() && !v->IsGroundVehicle()) return CMD_ERROR;
/* Check depot order type is valid. */
OrderDepotTypeFlags depot_order_type = new_order.GetDepotOrderType();
if (depot_order_type.Test(OrderDepotTypeFlag::PartOfOrders)) depot_order_type.Reset(OrderDepotTypeFlag::Service);
depot_order_type.Reset(OrderDepotTypeFlag::PartOfOrders);
if (depot_order_type.Any()) return CMD_ERROR;
/* Check depot action type is valid. */
if (new_order.GetDepotActionType().Reset({OrderDepotActionFlag::Halt, OrderDepotActionFlag::NearestDepot, OrderDepotActionFlag::Unbunch}).Any()) return CMD_ERROR;
/* Vehicles cannot have a "service if needed" order that also has a depot action. */
if ((new_order.GetDepotOrderType() & ODTFB_SERVICE) && (new_order.GetDepotActionType() & (ODATFB_HALT | ODATFB_UNBUNCH))) return CMD_ERROR;
if (new_order.GetDepotOrderType().Test(OrderDepotTypeFlag::Service) && new_order.GetDepotActionType().Any({OrderDepotActionFlag::Halt, OrderDepotActionFlag::Unbunch})) return CMD_ERROR;
/* Check if we're allowed to have a new unbunching order. */
if ((new_order.GetDepotActionType() & ODATFB_UNBUNCH)) {
if (new_order.GetDepotActionType().Test(OrderDepotActionFlag::Unbunch)) {
if (v->HasFullLoadOrder()) return CommandCost(STR_ERROR_CAN_T_ADD_ORDER, STR_ERROR_UNBUNCHING_NO_UNBUNCHING_FULL_LOAD);
if (v->HasUnbunchingOrder()) return CommandCost(STR_ERROR_CAN_T_ADD_ORDER, STR_ERROR_UNBUNCHING_ONLY_ONE_ALLOWED);
if (v->HasConditionalOrder()) return CommandCost(STR_ERROR_CAN_T_ADD_ORDER, STR_ERROR_UNBUNCHING_NO_UNBUNCHING_CONDITIONAL);
@@ -776,35 +783,35 @@ CommandCost CmdInsertOrder(DoCommandFlags flags, VehicleID veh, VehicleOrderID s
/* Order flags can be any of the following for waypoints:
* [non-stop]
* non-stop orders (if any) are only valid for trains and road vehicles */
if (new_order.GetNonStopType() != ONSF_STOP_EVERYWHERE && !v->IsGroundVehicle()) return CMD_ERROR;
if (new_order.GetNonStopType().Any() && !v->IsGroundVehicle()) return CMD_ERROR;
break;
}
case OT_CONDITIONAL: {
VehicleOrderID skip_to = new_order.GetConditionSkipToOrder();
if (skip_to != 0 && skip_to >= v->GetNumOrders()) return CMD_ERROR; // Always allow jumping to the first (even when there is no order).
if (new_order.GetConditionVariable() >= OCV_END) return CMD_ERROR;
if (new_order.GetConditionVariable() >= OrderConditionVariable::End) return CMD_ERROR;
if (v->HasUnbunchingOrder()) return CommandCost(STR_ERROR_UNBUNCHING_NO_CONDITIONAL);
OrderConditionComparator occ = new_order.GetConditionComparator();
if (occ >= OCC_END) return CMD_ERROR;
if (occ >= OrderConditionComparator::End) return CMD_ERROR;
switch (new_order.GetConditionVariable()) {
case OCV_REQUIRES_SERVICE:
if (occ != OCC_IS_TRUE && occ != OCC_IS_FALSE) return CMD_ERROR;
case OrderConditionVariable::RequiresService:
if (occ != OrderConditionComparator::IsTrue && occ != OrderConditionComparator::IsFalse) return CMD_ERROR;
break;
case OCV_UNCONDITIONALLY:
if (occ != OCC_EQUALS) return CMD_ERROR;
case OrderConditionVariable::Unconditionally:
if (occ != OrderConditionComparator::Equal) return CMD_ERROR;
if (new_order.GetConditionValue() != 0) return CMD_ERROR;
break;
case OCV_LOAD_PERCENTAGE:
case OCV_RELIABILITY:
case OrderConditionVariable::LoadPercentage:
case OrderConditionVariable::Reliability:
if (new_order.GetConditionValue() > 100) return CMD_ERROR;
[[fallthrough]];
default:
if (occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) return CMD_ERROR;
if (occ == OrderConditionComparator::IsTrue || occ == OrderConditionComparator::IsFalse) return CMD_ERROR;
break;
}
break;
@@ -945,7 +952,7 @@ static void CancelLoadingDueToDeletedOrder(Vehicle *v)
assert(v->current_order.IsType(OT_LOADING));
/* NON-stop flag is misused to see if a train is in a station that is
* on its order list or not */
v->current_order.SetNonStopType(ONSF_STOP_EVERYWHERE);
v->current_order.SetNonStopType({});
/* When full loading, "cancel" that order so the vehicle doesn't
* stay indefinitely at this station anymore. */
if (v->current_order.GetLoadType() & OLFB_FULL_LOAD) v->current_order.SetLoadType(OLF_LOAD_IF_POSSIBLE);
@@ -1195,19 +1202,25 @@ CommandCost CmdModifyOrder(DoCommandFlags flags, VehicleID veh, VehicleOrderID s
switch (mof) {
default: NOT_REACHED();
case MOF_NON_STOP:
case MOF_NON_STOP: {
if (!v->IsGroundVehicle()) return CMD_ERROR;
if (data >= ONSF_END) return CMD_ERROR;
if (data == order->GetNonStopType()) return CMD_ERROR;
OrderNonStopFlags nonstop_flags = static_cast<OrderNonStopFlags>(data);
if (nonstop_flags == order->GetNonStopType()) return CMD_ERROR;
/* Test for invalid flags. */
nonstop_flags.Reset({OrderNonStopFlag::NoIntermediate, OrderNonStopFlag::NoDestination});
if (nonstop_flags.Any()) return CMD_ERROR;
break;
}
case MOF_STOP_LOCATION:
if (v->type != VEH_TRAIN) return CMD_ERROR;
if (data >= OSL_END) return CMD_ERROR;
if (data >= to_underlying(OrderStopLocation::End)) return CMD_ERROR;
break;
case MOF_UNLOAD:
if (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) return CMD_ERROR;
if (order->GetNonStopType().Test(OrderNonStopFlag::NoDestination)) return CMD_ERROR;
if ((data & ~(OUFB_UNLOAD | OUFB_TRANSFER | OUFB_NO_UNLOAD)) != 0) return CMD_ERROR;
/* Unload and no-unload are mutual exclusive and so are transfer and no unload. */
if (data != 0 && ((data & (OUFB_UNLOAD | OUFB_TRANSFER)) != 0) == ((data & OUFB_NO_UNLOAD) != 0)) return CMD_ERROR;
@@ -1215,52 +1228,58 @@ CommandCost CmdModifyOrder(DoCommandFlags flags, VehicleID veh, VehicleOrderID s
break;
case MOF_LOAD:
if (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) return CMD_ERROR;
if (order->GetNonStopType().Test(OrderNonStopFlag::NoDestination)) return CMD_ERROR;
if (data > OLFB_NO_LOAD || data == 1) return CMD_ERROR;
if (data == order->GetLoadType()) return CMD_ERROR;
if ((data & (OLFB_FULL_LOAD | OLF_FULL_LOAD_ANY)) && v->HasUnbunchingOrder()) return CommandCost(STR_ERROR_UNBUNCHING_NO_FULL_LOAD);
break;
case MOF_DEPOT_ACTION:
if (data >= DA_END) return CMD_ERROR;
case MOF_DEPOT_ACTION: {
OrderDepotAction depot_action = static_cast<OrderDepotAction>(data);
if (depot_action >= OrderDepotAction::End) return CMD_ERROR;
/* Check if we are allowed to add unbunching. We are always allowed to remove it. */
if (data == DA_UNBUNCH) {
if (depot_action == OrderDepotAction::Unbunch) {
/* Only one unbunching order is allowed in a vehicle's orders. If this order already has an unbunching action, no error is needed. */
if (v->HasUnbunchingOrder() && !(order->GetDepotActionType() & ODATFB_UNBUNCH)) return CommandCost(STR_ERROR_UNBUNCHING_ONLY_ONE_ALLOWED);
if (v->HasUnbunchingOrder() && !order->GetDepotActionType().Test(OrderDepotActionFlag::Unbunch)) return CommandCost(STR_ERROR_UNBUNCHING_ONLY_ONE_ALLOWED);
/* We don't allow unbunching if the vehicle has a conditional order. */
if (v->HasConditionalOrder()) return CommandCost(STR_ERROR_UNBUNCHING_NO_UNBUNCHING_CONDITIONAL);
/* We don't allow unbunching if the vehicle has a full load order. */
if (v->HasFullLoadOrder()) return CommandCost(STR_ERROR_UNBUNCHING_NO_UNBUNCHING_FULL_LOAD);
}
break;
}
case MOF_COND_VARIABLE:
if (data >= OCV_END) return CMD_ERROR;
case MOF_COND_VARIABLE: {
OrderConditionVariable cond_variable = static_cast<OrderConditionVariable>(data);
if (cond_variable >= OrderConditionVariable::End) return CMD_ERROR;
break;
}
case MOF_COND_COMPARATOR:
if (data >= OCC_END) return CMD_ERROR;
case MOF_COND_COMPARATOR: {
OrderConditionComparator cond_comparator = static_cast<OrderConditionComparator>(data);
if (cond_comparator >= OrderConditionComparator::End) return CMD_ERROR;
switch (order->GetConditionVariable()) {
case OCV_UNCONDITIONALLY: return CMD_ERROR;
case OrderConditionVariable::Unconditionally: return CMD_ERROR;
case OCV_REQUIRES_SERVICE:
if (data != OCC_IS_TRUE && data != OCC_IS_FALSE) return CMD_ERROR;
case OrderConditionVariable::RequiresService:
if (cond_comparator != OrderConditionComparator::IsTrue && cond_comparator != OrderConditionComparator::IsFalse) return CMD_ERROR;
break;
default:
if (data == OCC_IS_TRUE || data == OCC_IS_FALSE) return CMD_ERROR;
if (cond_comparator == OrderConditionComparator::IsTrue || cond_comparator == OrderConditionComparator::IsFalse) return CMD_ERROR;
break;
}
break;
}
case MOF_COND_VALUE:
switch (order->GetConditionVariable()) {
case OCV_UNCONDITIONALLY:
case OCV_REQUIRES_SERVICE:
case OrderConditionVariable::Unconditionally:
case OrderConditionVariable::RequiresService:
return CMD_ERROR;
case OCV_LOAD_PERCENTAGE:
case OCV_RELIABILITY:
case OrderConditionVariable::LoadPercentage:
case OrderConditionVariable::Reliability:
if (data > 100) return CMD_ERROR;
break;
@@ -1278,8 +1297,8 @@ CommandCost CmdModifyOrder(DoCommandFlags flags, VehicleID veh, VehicleOrderID s
if (flags.Test(DoCommandFlag::Execute)) {
switch (mof) {
case MOF_NON_STOP:
order->SetNonStopType((OrderNonStopFlags)data);
if (data & ONSF_NO_STOP_AT_DESTINATION_STATION) {
order->SetNonStopType(static_cast<OrderNonStopFlags>(data));
if (order->GetNonStopType().Test(OrderNonStopFlag::NoDestination)) {
order->SetRefit(CARGO_NO_REFIT);
order->SetLoadType(OLF_LOAD_IF_POSSIBLE);
order->SetUnloadType(OUF_UNLOAD_IF_POSSIBLE);
@@ -1287,7 +1306,7 @@ CommandCost CmdModifyOrder(DoCommandFlags flags, VehicleID veh, VehicleOrderID s
break;
case MOF_STOP_LOCATION:
order->SetStopLocation((OrderStopLocation)data);
order->SetStopLocation(static_cast<OrderStopLocation>(data));
break;
case MOF_UNLOAD:
@@ -1300,31 +1319,27 @@ CommandCost CmdModifyOrder(DoCommandFlags flags, VehicleID veh, VehicleOrderID s
break;
case MOF_DEPOT_ACTION: {
switch (data) {
case DA_ALWAYS_GO:
order->SetDepotOrderType((OrderDepotTypeFlags)(order->GetDepotOrderType() & ~ODTFB_SERVICE));
order->SetDepotActionType((OrderDepotActionFlags)(order->GetDepotActionType() & ~ODATFB_HALT));
order->SetDepotActionType((OrderDepotActionFlags)(order->GetDepotActionType() & ~ODATFB_UNBUNCH));
switch (static_cast<OrderDepotAction>(data)) {
case OrderDepotAction::AlwaysGo:
order->SetDepotOrderType(order->GetDepotOrderType().Reset(OrderDepotTypeFlag::Service));
order->SetDepotActionType(order->GetDepotActionType().Reset({OrderDepotActionFlag::Halt, OrderDepotActionFlag::Unbunch}));
break;
case DA_SERVICE:
order->SetDepotOrderType((OrderDepotTypeFlags)(order->GetDepotOrderType() | ODTFB_SERVICE));
order->SetDepotActionType((OrderDepotActionFlags)(order->GetDepotActionType() & ~ODATFB_HALT));
order->SetDepotActionType((OrderDepotActionFlags)(order->GetDepotActionType() & ~ODATFB_UNBUNCH));
case OrderDepotAction::Service:
order->SetDepotOrderType(order->GetDepotOrderType().Set(OrderDepotTypeFlag::Service));
order->SetDepotActionType(order->GetDepotActionType().Reset({OrderDepotActionFlag::Halt, OrderDepotActionFlag::Unbunch}));
order->SetRefit(CARGO_NO_REFIT);
break;
case DA_STOP:
order->SetDepotOrderType((OrderDepotTypeFlags)(order->GetDepotOrderType() & ~ODTFB_SERVICE));
order->SetDepotActionType((OrderDepotActionFlags)(order->GetDepotActionType() | ODATFB_HALT));
order->SetDepotActionType((OrderDepotActionFlags)(order->GetDepotActionType() & ~ODATFB_UNBUNCH));
case OrderDepotAction::Stop:
order->SetDepotOrderType(order->GetDepotOrderType().Reset(OrderDepotTypeFlag::Service));
order->SetDepotActionType(order->GetDepotActionType().Set(OrderDepotActionFlag::Halt).Reset(OrderDepotActionFlag::Unbunch));
order->SetRefit(CARGO_NO_REFIT);
break;
case DA_UNBUNCH:
order->SetDepotOrderType((OrderDepotTypeFlags)(order->GetDepotOrderType() & ~ODTFB_SERVICE));
order->SetDepotActionType((OrderDepotActionFlags)(order->GetDepotActionType() & ~ODATFB_HALT));
order->SetDepotActionType((OrderDepotActionFlags)(order->GetDepotActionType() | ODATFB_UNBUNCH));
case OrderDepotAction::Unbunch:
order->SetDepotOrderType(order->GetDepotOrderType().Reset(OrderDepotTypeFlag::Service));
order->SetDepotActionType(order->GetDepotActionType().Reset(OrderDepotActionFlag::Halt).Set(OrderDepotActionFlag::Unbunch));
break;
default:
@@ -1338,23 +1353,23 @@ CommandCost CmdModifyOrder(DoCommandFlags flags, VehicleID veh, VehicleOrderID s
OrderConditionComparator occ = order->GetConditionComparator();
switch (order->GetConditionVariable()) {
case OCV_UNCONDITIONALLY:
order->SetConditionComparator(OCC_EQUALS);
case OrderConditionVariable::Unconditionally:
order->SetConditionComparator(OrderConditionComparator::Equal);
order->SetConditionValue(0);
break;
case OCV_REQUIRES_SERVICE:
if (occ != OCC_IS_TRUE && occ != OCC_IS_FALSE) order->SetConditionComparator(OCC_IS_TRUE);
case OrderConditionVariable::RequiresService:
if (occ != OrderConditionComparator::IsTrue && occ != OrderConditionComparator::IsFalse) order->SetConditionComparator(OrderConditionComparator::IsTrue);
order->SetConditionValue(0);
break;
case OCV_LOAD_PERCENTAGE:
case OCV_RELIABILITY:
case OrderConditionVariable::LoadPercentage:
case OrderConditionVariable::Reliability:
if (order->GetConditionValue() > 100) order->SetConditionValue(100);
[[fallthrough]];
default:
if (occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) order->SetConditionComparator(OCC_EQUALS);
if (occ == OrderConditionComparator::IsTrue || occ == OrderConditionComparator::IsFalse) order->SetConditionComparator(OrderConditionComparator::Equal);
break;
}
break;
@@ -1605,8 +1620,8 @@ CommandCost CmdOrderRefit(DoCommandFlags flags, VehicleID veh, VehicleOrderID or
/* Make the depot order an 'always go' order. */
if (cargo != CARGO_NO_REFIT && order->IsType(OT_GOTO_DEPOT)) {
order->SetDepotOrderType((OrderDepotTypeFlags)(order->GetDepotOrderType() & ~ODTFB_SERVICE));
order->SetDepotActionType((OrderDepotActionFlags)(order->GetDepotActionType() & ~ODATFB_HALT));
order->SetDepotOrderType(order->GetDepotOrderType().Reset(OrderDepotTypeFlag::Service));
order->SetDepotActionType(order->GetDepotActionType().Reset(OrderDepotActionFlag::Halt));
}
for (Vehicle *u = v->FirstShared(); u != nullptr; u = u->NextShared()) {
@@ -1614,7 +1629,7 @@ CommandCost CmdOrderRefit(DoCommandFlags flags, VehicleID veh, VehicleOrderID or
InvalidateVehicleOrder(u, VIWD_MODIFY_ORDERS);
/* If the vehicle already got the current depot set as current order, then update current order as well */
if (u->cur_real_order_index == order_number && (u->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS)) {
if (u->cur_real_order_index == order_number && u->current_order.GetDepotOrderType().Test(OrderDepotTypeFlag::PartOfOrders)) {
u->current_order.SetRefit(cargo);
}
}
@@ -1725,7 +1740,7 @@ void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination, bool
next_id = id + 1;
Order *order = v->orders->GetOrderAt(id);
OrderType ot = order->GetType();
if (ot == OT_GOTO_DEPOT && (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) continue;
if (ot == OT_GOTO_DEPOT && order->GetDepotActionType().Test(OrderDepotActionFlag::NearestDepot)) continue;
if (ot == OT_GOTO_DEPOT && hangar && v->type != VEH_AIRCRAFT) continue; // Not an aircraft? Can't have a hangar order.
if (ot == OT_IMPLICIT || (v->type == VEH_AIRCRAFT && ot == OT_GOTO_DEPOT && !hangar)) ot = OT_GOTO_STATION;
if (ot == type && order->GetDestination() == destination) {
@@ -1844,14 +1859,14 @@ static bool CheckForValidOrders(const Vehicle *v)
static bool OrderConditionCompare(OrderConditionComparator occ, int variable, int value)
{
switch (occ) {
case OCC_EQUALS: return variable == value;
case OCC_NOT_EQUALS: return variable != value;
case OCC_LESS_THAN: return variable < value;
case OCC_LESS_EQUALS: return variable <= value;
case OCC_MORE_THAN: return variable > value;
case OCC_MORE_EQUALS: return variable >= value;
case OCC_IS_TRUE: return variable != 0;
case OCC_IS_FALSE: return variable == 0;
case OrderConditionComparator::Equal: return variable == value;
case OrderConditionComparator::NotEqual: return variable != value;
case OrderConditionComparator::LessThan: return variable < value;
case OrderConditionComparator::LessThanOrEqual: return variable <= value;
case OrderConditionComparator::MoreThan: return variable > value;
case OrderConditionComparator::MoreThanOrEqual: return variable >= value;
case OrderConditionComparator::IsTrue: return variable != 0;
case OrderConditionComparator::IsFalse: return variable == 0;
default: NOT_REACHED();
}
}
@@ -1876,14 +1891,14 @@ VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v)
uint16_t value = order->GetConditionValue();
switch (order->GetConditionVariable()) {
case OCV_LOAD_PERCENTAGE: skip_order = OrderConditionCompare(occ, CalcPercentVehicleFilled(v, nullptr), value); break;
case OCV_RELIABILITY: skip_order = OrderConditionCompare(occ, ToPercent16(v->reliability), value); break;
case OCV_MAX_RELIABILITY: skip_order = OrderConditionCompare(occ, ToPercent16(v->GetEngine()->reliability), value); break;
case OCV_MAX_SPEED: skip_order = OrderConditionCompare(occ, v->GetDisplayMaxSpeed() * 10 / 16, value); break;
case OCV_AGE: skip_order = OrderConditionCompare(occ, TimerGameCalendar::DateToYear(v->age), value); break;
case OCV_REQUIRES_SERVICE: skip_order = OrderConditionCompare(occ, v->NeedsServicing(), value); break;
case OCV_UNCONDITIONALLY: skip_order = true; break;
case OCV_REMAINING_LIFETIME: skip_order = OrderConditionCompare(occ, std::max(TimerGameCalendar::DateToYear(v->max_age - v->age + CalendarTime::DAYS_IN_LEAP_YEAR - 1), TimerGameCalendar::Year(0)), value); break;
case OrderConditionVariable::LoadPercentage: skip_order = OrderConditionCompare(occ, CalcPercentVehicleFilled(v, nullptr), value); break;
case OrderConditionVariable::Reliability: skip_order = OrderConditionCompare(occ, ToPercent16(v->reliability), value); break;
case OrderConditionVariable::MaxReliability: skip_order = OrderConditionCompare(occ, ToPercent16(v->GetEngine()->reliability), value); break;
case OrderConditionVariable::MaxSpeed: skip_order = OrderConditionCompare(occ, v->GetDisplayMaxSpeed() * 10 / 16, value); break;
case OrderConditionVariable::Age: skip_order = OrderConditionCompare(occ, TimerGameCalendar::DateToYear(v->age), value); break;
case OrderConditionVariable::RequiresService: skip_order = OrderConditionCompare(occ, v->NeedsServicing(), value); break;
case OrderConditionVariable::Unconditionally: skip_order = true; break;
case OrderConditionVariable::RemainingLifetime: skip_order = OrderConditionCompare(occ, std::max(TimerGameCalendar::DateToYear(v->max_age - v->age + CalendarTime::DAYS_IN_LEAP_YEAR - 1), TimerGameCalendar::Year(0)), value); break;
default: NOT_REACHED();
}
@@ -1911,14 +1926,14 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth, bool
return true;
case OT_GOTO_DEPOT:
if ((order->GetDepotOrderType() & ODTFB_SERVICE) && !v->NeedsServicing()) {
if (order->GetDepotOrderType().Test(OrderDepotTypeFlag::Service) && !v->NeedsServicing()) {
assert(!pbs_look_ahead);
UpdateVehicleTimetable(v, true);
v->IncrementRealOrderIndex();
break;
}
if (v->current_order.GetDepotActionType() & ODATFB_NEAREST_DEPOT) {
if (v->current_order.GetDepotActionType().Test(OrderDepotActionFlag::NearestDepot)) {
/* If the vehicle can't find its destination, delay its next search.
* In case many vehicles are in this state, use the vehicle index to spread out pathfinder calls. */
if (v->dest_tile == 0 && TimerGameEconomy::date_fract != (v->index % Ticks::DAY_TICKS)) break;
@@ -2031,7 +2046,7 @@ bool ProcessOrders(Vehicle *v)
switch (v->current_order.GetType()) {
case OT_GOTO_DEPOT:
/* Let a depot order in the orderlist interrupt. */
if (!(v->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS)) return false;
if (!v->current_order.GetDepotOrderType().Test(OrderDepotTypeFlag::PartOfOrders)) return false;
break;
case OT_LOADING:
@@ -2054,7 +2069,7 @@ bool ProcessOrders(Vehicle *v)
bool may_reverse = v->current_order.IsType(OT_NOTHING);
/* Check if we've reached a 'via' destination. */
if (((v->current_order.IsType(OT_GOTO_STATION) && (v->current_order.GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION)) || v->current_order.IsType(OT_GOTO_WAYPOINT)) &&
if (((v->current_order.IsType(OT_GOTO_STATION) && v->current_order.GetNonStopType().Test(OrderNonStopFlag::NoDestination)) || v->current_order.IsType(OT_GOTO_WAYPOINT)) &&
IsTileType(v->tile, MP_STATION) &&
v->current_order.GetDestination() == GetStationIndex(v->tile)) {
v->DeleteUnreachedImplicitOrders();
@@ -2128,16 +2143,16 @@ bool Order::ShouldStopAtStation(const Vehicle *v, StationID station) const
{
bool is_dest_station = this->IsType(OT_GOTO_STATION) && this->dest == station;
return (!this->IsType(OT_GOTO_DEPOT) || (this->GetDepotOrderType() & ODTFB_PART_OF_ORDERS) != 0) &&
return (!this->IsType(OT_GOTO_DEPOT) || this->GetDepotOrderType().Test(OrderDepotTypeFlag::PartOfOrders)) &&
v->last_station_visited != station && // Do stop only when we've not just been there
/* Finally do stop when there is no non-stop flag set for this type of station. */
!(this->GetNonStopType() & (is_dest_station ? ONSF_NO_STOP_AT_DESTINATION_STATION : ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS));
!this->GetNonStopType().Test(is_dest_station ? OrderNonStopFlag::NoDestination : OrderNonStopFlag::NoIntermediate);
}
bool Order::CanLoadOrUnload() const
{
return (this->IsType(OT_GOTO_STATION) || this->IsType(OT_IMPLICIT)) &&
(this->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) == 0 &&
!this->GetNonStopType().Test(OrderNonStopFlag::NoDestination) &&
((this->GetLoadType() & OLFB_NO_LOAD) == 0 ||
(this->GetUnloadType() & OUFB_NO_UNLOAD) == 0);
}

View File

@@ -155,14 +155,14 @@ static const StringID _order_goto_dropdown_aircraft[] = {
/** Variables for conditional orders; this defines the order of appearance in the dropdown box */
static const OrderConditionVariable _order_conditional_variable[] = {
OCV_LOAD_PERCENTAGE,
OCV_RELIABILITY,
OCV_MAX_RELIABILITY,
OCV_MAX_SPEED,
OCV_AGE,
OCV_REMAINING_LIFETIME,
OCV_REQUIRES_SERVICE,
OCV_UNCONDITIONALLY,
OrderConditionVariable::LoadPercentage,
OrderConditionVariable::Reliability,
OrderConditionVariable::MaxReliability,
OrderConditionVariable::MaxSpeed,
OrderConditionVariable::Age,
OrderConditionVariable::RemainingLifetime,
OrderConditionVariable::RequiresService,
OrderConditionVariable::Unconditionally,
};
static const StringID _order_conditional_condition[] = {
@@ -186,17 +186,12 @@ static const StringID _order_depot_action_dropdown[] = {
STR_ORDER_DROP_UNBUNCH,
};
static int DepotActionStringIndex(const Order *order)
static OrderDepotAction DepotActionStringIndex(const Order *order)
{
if (order->GetDepotActionType() & ODATFB_HALT) {
return DA_STOP;
} else if (order->GetDepotOrderType() & ODTFB_SERVICE) {
return DA_SERVICE;
} else if (order->GetDepotActionType() & ODATFB_UNBUNCH) {
return DA_UNBUNCH;
} else {
return DA_ALWAYS_GO;
}
if (order->GetDepotActionType().Test(OrderDepotActionFlag::Halt)) return OrderDepotAction::Stop;
if (order->GetDepotOrderType().Test(OrderDepotTypeFlag::Service)) return OrderDepotAction::Service;
if (order->GetDepotActionType().Test(OrderDepotActionFlag::Unbunch)) return OrderDepotAction::Unbunch;
return OrderDepotAction::AlwaysGo;
}
static const StringID _order_refit_action_dropdown[] = {
@@ -206,10 +201,10 @@ static const StringID _order_refit_action_dropdown[] = {
static StringID GetOrderGoToString(const Order &order)
{
if (order.GetDepotOrderType() & ODTFB_SERVICE) {
return (order.GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_ORDER_SERVICE_NON_STOP_AT : STR_ORDER_SERVICE_AT;
if (order.GetDepotOrderType().Test(OrderDepotTypeFlag::Service)) {
return order.GetNonStopType().Test(OrderNonStopFlag::NoIntermediate) ? STR_ORDER_SERVICE_NON_STOP_AT : STR_ORDER_SERVICE_AT;
} else {
return (order.GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_ORDER_GO_NON_STOP_TO : STR_ORDER_GO_TO;
return order.GetNonStopType().Test(OrderNonStopFlag::NoIntermediate) ? STR_ORDER_GO_NON_STOP_TO : STR_ORDER_GO_TO;
}
}
@@ -266,7 +261,7 @@ void DrawOrderString(const Vehicle *v, const Order *order, VehicleOrderID order_
OrderUnloadFlags unload = order->GetUnloadType();
bool valid_station = CanVehicleUseStation(v, Station::Get(order->GetDestination().ToStationID()));
line = GetString(valid_station ? STR_ORDER_GO_TO_STATION : STR_ORDER_GO_TO_STATION_CAN_T_USE_STATION, STR_ORDER_GO_TO + (v->IsGroundVehicle() ? order->GetNonStopType() : 0), order->GetDestination());
line = GetString(valid_station ? STR_ORDER_GO_TO_STATION : STR_ORDER_GO_TO_STATION_CAN_T_USE_STATION, STR_ORDER_GO_TO + (v->IsGroundVehicle() ? order->GetNonStopType() : OrderNonStopFlags{}).base(), order->GetDestination());
if (timetable) {
/* Show only wait time in the timetable window. */
if (order->GetWaitTime() > 0) {
@@ -275,7 +270,7 @@ void DrawOrderString(const Vehicle *v, const Order *order, VehicleOrderID order_
}
} else {
/* Show non-stop, refit and stop location only in the order window. */
if (!(order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION)) {
if (!order->GetNonStopType().Test(OrderNonStopFlag::NoDestination)) {
StringID str = _station_load_types[order->IsRefit()][unload][load];
if (str != INVALID_STRING_ID) {
if (order->IsRefit()) {
@@ -286,10 +281,10 @@ void DrawOrderString(const Vehicle *v, const Order *order, VehicleOrderID order_
}
}
if (v->type == VEH_TRAIN && (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) == 0) {
if (v->type == VEH_TRAIN && !order->GetNonStopType().Test(OrderNonStopFlag::NoDestination)) {
/* Only show the stopping location if other than the default chosen by the player. */
if (order->GetStopLocation() != (OrderStopLocation)(_settings_client.gui.stop_location)) {
line += GetString(STR_ORDER_STOP_LOCATION_NEAR_END + order->GetStopLocation());
if (order->GetStopLocation() != _settings_client.gui.stop_location) {
line += GetString(STR_ORDER_STOP_LOCATION_NEAR_END + to_underlying(order->GetStopLocation()));
}
}
}
@@ -297,7 +292,7 @@ void DrawOrderString(const Vehicle *v, const Order *order, VehicleOrderID order_
}
case OT_GOTO_DEPOT:
if (!(order->GetDepotActionType() & ODATFB_NEAREST_DEPOT)) {
if (!order->GetDepotActionType().Test(OrderDepotActionFlag::NearestDepot)) {
/* Going to a specific depot. */
line = GetString(STR_ORDER_GO_TO_DEPOT_FORMAT, GetOrderGoToString(*order), v->type, order->GetDestination());
} else if (v->type == VEH_AIRCRAFT) {
@@ -309,38 +304,38 @@ void DrawOrderString(const Vehicle *v, const Order *order, VehicleOrderID order_
}
/* Do not show stopping in the depot in the timetable window. */
if (!timetable && (order->GetDepotActionType() & ODATFB_HALT)) {
if (!timetable && order->GetDepotActionType().Test(OrderDepotActionFlag::Halt)) {
line += GetString(STR_ORDER_STOP_ORDER);
}
/* Do not show refitting in the depot in the timetable window. */
if (!timetable && order->IsRefit()) {
line += GetString((order->GetDepotActionType() & ODATFB_HALT) ? STR_ORDER_REFIT_STOP_ORDER : STR_ORDER_REFIT_ORDER, CargoSpec::Get(order->GetRefitCargo())->name);
line += GetString(order->GetDepotActionType().Test(OrderDepotActionFlag::Halt) ? STR_ORDER_REFIT_STOP_ORDER : STR_ORDER_REFIT_ORDER, CargoSpec::Get(order->GetRefitCargo())->name);
}
/* Show unbunching depot in both order and timetable windows. */
if (order->GetDepotActionType() & ODATFB_UNBUNCH) {
if (order->GetDepotActionType().Test(OrderDepotActionFlag::Unbunch)) {
line += GetString(STR_ORDER_WAIT_TO_UNBUNCH);
}
break;
case OT_GOTO_WAYPOINT:
line = GetString((order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_ORDER_GO_NON_STOP_TO_WAYPOINT : STR_ORDER_GO_TO_WAYPOINT, order->GetDestination());
line = GetString(order->GetNonStopType().Test(OrderNonStopFlag::NoIntermediate) ? STR_ORDER_GO_NON_STOP_TO_WAYPOINT : STR_ORDER_GO_TO_WAYPOINT, order->GetDestination());
break;
case OT_CONDITIONAL:
if (order->GetConditionVariable() == OCV_UNCONDITIONALLY) {
if (order->GetConditionVariable() == OrderConditionVariable::Unconditionally) {
line = GetString(STR_ORDER_CONDITIONAL_UNCONDITIONAL, order->GetConditionSkipToOrder() + 1);
} else {
OrderConditionComparator occ = order->GetConditionComparator();
uint value = order->GetConditionValue();
if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value, v->type);
if (order->GetConditionVariable() == OrderConditionVariable::MaxSpeed) value = ConvertSpeedToDisplaySpeed(value, v->type);
line = GetString((occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) ? STR_ORDER_CONDITIONAL_TRUE_FALSE : STR_ORDER_CONDITIONAL_NUM,
line = GetString((occ == OrderConditionComparator::IsTrue || occ == OrderConditionComparator::IsFalse) ? STR_ORDER_CONDITIONAL_TRUE_FALSE : STR_ORDER_CONDITIONAL_NUM,
order->GetConditionSkipToOrder() + 1,
STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + order->GetConditionVariable(),
STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS + occ,
STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + to_underlying(order->GetConditionVariable()),
STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS + to_underlying(occ),
value);
}
@@ -376,8 +371,8 @@ static Order GetOrderCmdFromTile(const Vehicle *v, TileIndex tile)
/* check depot first */
if (IsDepotTypeTile(tile, (TransportType)(uint)v->type) && IsTileOwner(tile, _local_company)) {
order.MakeGoToDepot(GetDepotDestinationIndex(tile),
ODTFB_PART_OF_ORDERS,
(_settings_client.gui.new_nonstop && v->IsGroundVehicle()) ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE);
OrderDepotTypeFlag::PartOfOrders,
(_settings_client.gui.new_nonstop && v->IsGroundVehicle()) ? OrderNonStopFlag::NoIntermediate : OrderNonStopFlags{});
if (_ctrl_pressed) {
/* Check to see if we are allowed to make this an unbunching order. */
@@ -403,7 +398,7 @@ static Order GetOrderCmdFromTile(const Vehicle *v, TileIndex tile)
}
/* Now we are allowed to set the action type. */
order.SetDepotActionType(ODATFB_UNBUNCH);
order.SetDepotActionType(OrderDepotActionFlag::Unbunch);
}
return order;
@@ -414,7 +409,7 @@ static Order GetOrderCmdFromTile(const Vehicle *v, TileIndex tile)
v->type == VEH_TRAIN &&
IsTileOwner(tile, _local_company)) {
order.MakeGoToWaypoint(GetStationIndex(tile));
if (_settings_client.gui.new_nonstop != _ctrl_pressed) order.SetNonStopType(ONSF_NO_STOP_AT_ANY_STATION);
if (_settings_client.gui.new_nonstop != _ctrl_pressed) order.SetNonStopType({});
return order;
}
@@ -423,7 +418,7 @@ static Order GetOrderCmdFromTile(const Vehicle *v, TileIndex tile)
v->type == VEH_ROAD &&
IsTileOwner(tile, _local_company)) {
order.MakeGoToWaypoint(GetStationIndex(tile));
if (_settings_client.gui.new_nonstop != _ctrl_pressed) order.SetNonStopType(ONSF_NO_STOP_AT_ANY_STATION);
if (_settings_client.gui.new_nonstop != _ctrl_pressed) order.SetNonStopType({});
return order;
}
@@ -455,8 +450,8 @@ static Order GetOrderCmdFromTile(const Vehicle *v, TileIndex tile)
if (st->facilities.Any(facil)) {
order.MakeGoToStation(st->index);
if (_ctrl_pressed) order.SetLoadType(OLF_FULL_LOAD_ANY);
if (_settings_client.gui.new_nonstop && v->IsGroundVehicle()) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
order.SetStopLocation(v->type == VEH_TRAIN ? (OrderStopLocation)(_settings_client.gui.stop_location) : OSL_PLATFORM_FAR_END);
if (_settings_client.gui.new_nonstop && v->IsGroundVehicle()) order.SetNonStopType(OrderNonStopFlag::NoIntermediate);
order.SetStopLocation(v->type == VEH_TRAIN ? (OrderStopLocation)(_settings_client.gui.stop_location) : OrderStopLocation::FarEnd);
return order;
}
}
@@ -637,16 +632,16 @@ private:
/**
* Handle the click on the service.
*/
void OrderClick_Service(int i)
void OrderClick_Service(std::optional<OrderDepotAction> i)
{
VehicleOrderID sel_ord = this->OrderGetSel();
if (i < 0) {
if (!i.has_value()) {
const Order *order = this->vehicle->GetOrder(sel_ord);
if (order == nullptr) return;
i = (order->GetDepotOrderType() & ODTFB_SERVICE) ? DA_ALWAYS_GO : DA_SERVICE;
i = order->GetDepotOrderType().Test(OrderDepotTypeFlag::Service) ? OrderDepotAction::AlwaysGo : OrderDepotAction::Service;
}
Command<CMD_MODIFY_ORDER>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, sel_ord, MOF_DEPOT_ACTION, i);
Command<CMD_MODIFY_ORDER>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, sel_ord, MOF_DEPOT_ACTION, to_underlying(i.value()));
}
/**
@@ -655,9 +650,9 @@ private:
void OrderClick_NearestDepot()
{
Order order{};
order.MakeGoToDepot(DepotID::Invalid(), ODTFB_PART_OF_ORDERS,
_settings_client.gui.new_nonstop && this->vehicle->IsGroundVehicle() ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE);
order.SetDepotActionType(ODATFB_NEAREST_DEPOT);
order.MakeGoToDepot(DepotID::Invalid(), OrderDepotTypeFlag::PartOfOrders,
_settings_client.gui.new_nonstop && this->vehicle->IsGroundVehicle() ? OrderNonStopFlag::NoIntermediate : OrderNonStopFlags{});
order.SetDepotActionType(OrderDepotActionFlag::NearestDepot);
Command<CMD_INSERT_ORDER>::Post(STR_ERROR_CAN_T_INSERT_NEW_ORDER, this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), order);
}
@@ -690,9 +685,9 @@ private:
/**
* Handle the click on the nonstop button.
* @param non_stop what non-stop type to use; -1 to use the 'next' one.
* @param non_stop what non-stop type to use; std::nullopt to use the 'next' one.
*/
void OrderClick_Nonstop(int non_stop)
void OrderClick_Nonstop(std::optional<OrderNonStopFlags> non_stop)
{
if (!this->vehicle->IsGroundVehicle()) return;
@@ -701,13 +696,13 @@ private:
if (order == nullptr || order->GetNonStopType() == non_stop) return;
/* Keypress if negative, so 'toggle' to the next */
if (non_stop < 0) {
non_stop = order->GetNonStopType() ^ ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS;
/* Keypress if no value, so 'toggle' to the next */
if (!non_stop.has_value()) {
non_stop = order->GetNonStopType().Flip(OrderNonStopFlag::NoIntermediate);
}
this->SetWidgetDirty(WID_O_NON_STOP);
Command<CMD_MODIFY_ORDER>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, sel_ord, MOF_NON_STOP, non_stop);
Command<CMD_MODIFY_ORDER>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, sel_ord, MOF_NON_STOP, non_stop.value().base());
}
/**
@@ -829,7 +824,7 @@ public:
case WID_O_COND_VARIABLE: {
Dimension d = {0, 0};
for (const auto &ocv : _order_conditional_variable) {
d = maxdim(d, GetStringBoundingBox(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + ocv));
d = maxdim(d, GetStringBoundingBox(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + to_underlying(ocv)));
}
d.width += padding.width;
d.height += padding.height;
@@ -985,8 +980,8 @@ public:
this->DisableWidget(WID_O_UNLOAD);
this->DisableWidget(WID_O_REFIT_DROPDOWN);
} else {
this->SetWidgetDisabledState(WID_O_FULL_LOAD, (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) != 0); // full load
this->SetWidgetDisabledState(WID_O_UNLOAD, (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) != 0); // unload
this->SetWidgetDisabledState(WID_O_FULL_LOAD, order->GetNonStopType().Test(OrderNonStopFlag::NoDestination)); // full load
this->SetWidgetDisabledState(WID_O_UNLOAD, order->GetNonStopType().Test(OrderNonStopFlag::NoDestination)); // unload
switch (order->GetType()) {
case OT_GOTO_STATION:
@@ -998,7 +993,7 @@ public:
middle_sel->SetDisplayedPlane(DP_MIDDLE_UNLOAD);
right_sel->SetDisplayedPlane(DP_RIGHT_REFIT);
this->EnableWidget(WID_O_NON_STOP);
this->SetWidgetLoweredState(WID_O_NON_STOP, order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
this->SetWidgetLoweredState(WID_O_NON_STOP, order->GetNonStopType().Test(OrderNonStopFlag::NoIntermediate));
}
this->SetWidgetLoweredState(WID_O_FULL_LOAD, order->GetLoadType() == OLF_FULL_LOAD_ANY);
this->SetWidgetLoweredState(WID_O_UNLOAD, order->GetUnloadType() == OUFB_UNLOAD);
@@ -1006,7 +1001,7 @@ public:
/* Can only do refitting when stopping at the destination and loading cargo.
* Also enable the button if a refit is already set to allow clearing it. */
this->SetWidgetDisabledState(WID_O_REFIT_DROPDOWN,
order->GetLoadType() == OLFB_NO_LOAD || (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) ||
order->GetLoadType() == OLFB_NO_LOAD || order->GetNonStopType().Test(OrderNonStopFlag::NoDestination) ||
((!this->can_do_refit || !this->can_do_autorefit) && !order->IsRefit()));
break;
@@ -1020,7 +1015,7 @@ public:
middle_sel->SetDisplayedPlane(DP_MIDDLE_UNLOAD);
right_sel->SetDisplayedPlane(DP_RIGHT_EMPTY);
this->EnableWidget(WID_O_NON_STOP);
this->SetWidgetLoweredState(WID_O_NON_STOP, order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
this->SetWidgetLoweredState(WID_O_NON_STOP, order->GetNonStopType().Test(OrderNonStopFlag::NoIntermediate));
}
this->DisableWidget(WID_O_FULL_LOAD);
this->DisableWidget(WID_O_UNLOAD);
@@ -1036,12 +1031,12 @@ public:
middle_sel->SetDisplayedPlane(DP_MIDDLE_SERVICE);
right_sel->SetDisplayedPlane(DP_RIGHT_EMPTY);
this->EnableWidget(WID_O_NON_STOP);
this->SetWidgetLoweredState(WID_O_NON_STOP, order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
this->SetWidgetLoweredState(WID_O_NON_STOP, order->GetNonStopType().Test(OrderNonStopFlag::NoIntermediate));
}
/* Disable refit button if the order is no 'always go' order.
* However, keep the service button enabled for refit-orders to allow clearing refits (without knowing about ctrl). */
this->SetWidgetDisabledState(WID_O_REFIT,
(order->GetDepotOrderType() & ODTFB_SERVICE) || (order->GetDepotActionType() & ODATFB_HALT) ||
order->GetDepotOrderType().Test(OrderDepotTypeFlag::Service) || order->GetDepotActionType().Test(OrderDepotActionFlag::Halt) ||
(!this->can_do_refit && !order->IsRefit()));
break;
@@ -1053,10 +1048,10 @@ public:
}
OrderConditionVariable ocv = order->GetConditionVariable();
/* Set the strings for the dropdown boxes. */
this->GetWidget<NWidgetCore>(WID_O_COND_VARIABLE)->SetString(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + ocv);
this->GetWidget<NWidgetCore>(WID_O_COND_COMPARATOR)->SetString(_order_conditional_condition[order->GetConditionComparator()]);
this->SetWidgetDisabledState(WID_O_COND_COMPARATOR, ocv == OCV_UNCONDITIONALLY);
this->SetWidgetDisabledState(WID_O_COND_VALUE, ocv == OCV_REQUIRES_SERVICE || ocv == OCV_UNCONDITIONALLY);
this->GetWidget<NWidgetCore>(WID_O_COND_VARIABLE)->SetString(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + to_underlying(ocv));
this->GetWidget<NWidgetCore>(WID_O_COND_COMPARATOR)->SetString(_order_conditional_condition[to_underlying(order->GetConditionComparator())]);
this->SetWidgetDisabledState(WID_O_COND_COMPARATOR, ocv == OrderConditionVariable::Unconditionally);
this->SetWidgetDisabledState(WID_O_COND_VALUE, ocv == OrderConditionVariable::RequiresService || ocv == OrderConditionVariable::Unconditionally);
break;
}
@@ -1159,7 +1154,7 @@ public:
if (order != nullptr && order->IsType(OT_CONDITIONAL)) {
uint value = order->GetConditionValue();
if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value, this->vehicle->type);
if (order->GetConditionVariable() == OrderConditionVariable::MaxSpeed) value = ConvertSpeedToDisplaySpeed(value, this->vehicle->type);
return GetString(STR_JUST_COMMA, value);
}
return {};
@@ -1174,9 +1169,9 @@ public:
if (order == nullptr || !order->IsType(OT_GOTO_DEPOT)) return {};
/* Select the current action selected in the dropdown. The flags don't match the dropdown so we can't just use an index. */
if (order->GetDepotOrderType() & ODTFB_SERVICE) return GetString(STR_ORDER_DROP_SERVICE_DEPOT);
if (order->GetDepotActionType() & ODATFB_HALT) return GetString(STR_ORDER_DROP_HALT_DEPOT);
if (order->GetDepotActionType() & ODATFB_UNBUNCH) return GetString(STR_ORDER_DROP_UNBUNCH);
if (order->GetDepotOrderType().Test(OrderDepotTypeFlag::Service)) return GetString(STR_ORDER_DROP_SERVICE_DEPOT);
if (order->GetDepotActionType().Test(OrderDepotActionFlag::Halt)) return GetString(STR_ORDER_DROP_HALT_DEPOT);
if (order->GetDepotActionType().Test(OrderDepotActionFlag::Unbunch)) return GetString(STR_ORDER_DROP_UNBUNCH);
return GetString(STR_ORDER_DROP_GO_ALWAYS_DEPOT);
}
@@ -1220,7 +1215,7 @@ public:
if (this->vehicle->type == VEH_TRAIN && sel < this->vehicle->GetNumOrders()) {
Command<CMD_MODIFY_ORDER>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER,
this->vehicle->tile, this->vehicle->index, sel,
MOF_STOP_LOCATION, (this->vehicle->GetOrder(sel)->GetStopLocation() + 1) % OSL_END);
MOF_STOP_LOCATION, (to_underlying(this->vehicle->GetOrder(sel)->GetStopLocation()) + 1) % to_underlying(OrderStopLocation::End));
}
} else {
/* Select clicked order */
@@ -1250,11 +1245,11 @@ public:
case WID_O_NON_STOP:
if (this->GetWidget<NWidgetLeaf>(widget)->ButtonHit(pt)) {
this->OrderClick_Nonstop(-1);
this->OrderClick_Nonstop(std::nullopt);
} else {
const Order *o = this->vehicle->GetOrder(this->OrderGetSel());
assert(o != nullptr);
ShowDropDownMenu(this, _order_non_stop_dropdown, o->GetNonStopType(), WID_O_NON_STOP, 0,
ShowDropDownMenu(this, _order_non_stop_dropdown, o->GetNonStopType().base(), WID_O_NON_STOP, 0,
o->IsType(OT_GOTO_STATION) ? 0 : (o->IsType(OT_GOTO_WAYPOINT) ? 3 : 12));
}
break;
@@ -1300,7 +1295,7 @@ public:
break;
case WID_O_DEPOT_ACTION:
ShowDropDownMenu(this, _order_depot_action_dropdown, DepotActionStringIndex(this->vehicle->GetOrder(this->OrderGetSel())), WID_O_DEPOT_ACTION, 0, 0);
ShowDropDownMenu(this, _order_depot_action_dropdown, to_underlying(DepotActionStringIndex(this->vehicle->GetOrder(this->OrderGetSel()))), WID_O_DEPOT_ACTION, 0, 0);
break;
case WID_O_REFIT_DROPDOWN:
@@ -1318,16 +1313,16 @@ public:
case WID_O_COND_VARIABLE: {
DropDownList list;
for (const auto &ocv : _order_conditional_variable) {
list.push_back(MakeDropDownListStringItem(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + ocv, ocv));
list.push_back(MakeDropDownListStringItem(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + to_underlying(ocv), to_underlying(ocv)));
}
ShowDropDownList(this, std::move(list), this->vehicle->GetOrder(this->OrderGetSel())->GetConditionVariable(), WID_O_COND_VARIABLE);
ShowDropDownList(this, std::move(list), to_underlying(this->vehicle->GetOrder(this->OrderGetSel())->GetConditionVariable()), WID_O_COND_VARIABLE);
break;
}
case WID_O_COND_COMPARATOR: {
const Order *o = this->vehicle->GetOrder(this->OrderGetSel());
assert(o != nullptr);
ShowDropDownMenu(this, _order_conditional_condition, o->GetConditionComparator(), WID_O_COND_COMPARATOR, 0, (o->GetConditionVariable() == OCV_REQUIRES_SERVICE) ? 0x3F : 0xC0);
ShowDropDownMenu(this, _order_conditional_condition, to_underlying(o->GetConditionComparator()), WID_O_COND_COMPARATOR, 0, (o->GetConditionVariable() == OrderConditionVariable::RequiresService) ? 0x3F : 0xC0);
break;
}
@@ -1335,7 +1330,7 @@ public:
const Order *order = this->vehicle->GetOrder(this->OrderGetSel());
assert(order != nullptr);
uint value = order->GetConditionValue();
if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value, this->vehicle->type);
if (order->GetConditionVariable() == OrderConditionVariable::MaxSpeed) value = ConvertSpeedToDisplaySpeed(value, this->vehicle->type);
ShowQueryString(GetString(STR_JUST_INT, value), STR_ORDER_CONDITIONAL_VALUE_CAPT, 5, this, CS_NUMERAL, {});
break;
}
@@ -1355,12 +1350,12 @@ public:
if (!value.has_value()) return;
switch (this->vehicle->GetOrder(sel)->GetConditionVariable()) {
case OCV_MAX_SPEED:
case OrderConditionVariable::MaxSpeed:
value = ConvertDisplaySpeedToSpeed(*value, this->vehicle->type);
break;
case OCV_RELIABILITY:
case OCV_LOAD_PERCENTAGE:
case OrderConditionVariable::Reliability:
case OrderConditionVariable::LoadPercentage:
value = Clamp(*value, 0, 100);
break;
@@ -1374,7 +1369,7 @@ public:
{
switch (widget) {
case WID_O_NON_STOP:
this->OrderClick_Nonstop(index);
this->OrderClick_Nonstop(static_cast<OrderNonStopFlags>(index));
break;
case WID_O_FULL_LOAD:
@@ -1396,7 +1391,7 @@ public:
break;
case WID_O_DEPOT_ACTION:
this->OrderClick_Service(index);
this->OrderClick_Service(static_cast<OrderDepotAction>(index));
break;
case WID_O_REFIT_DROPDOWN:
@@ -1454,11 +1449,11 @@ public:
case OHK_SKIP: this->OrderClick_Skip(); break;
case OHK_DELETE: this->OrderClick_Delete(); break;
case OHK_GOTO: this->OrderClick_Goto(OPOS_GOTO); break;
case OHK_NONSTOP: this->OrderClick_Nonstop(-1); break;
case OHK_NONSTOP: this->OrderClick_Nonstop(std::nullopt); break;
case OHK_FULLLOAD: this->OrderClick_FullLoad(OLF_FULL_LOAD_ANY, true); break;
case OHK_UNLOAD: this->OrderClick_Unload(OUFB_UNLOAD, true); break;
case OHK_NEAREST_DEPOT: this->OrderClick_NearestDepot(); break;
case OHK_ALWAYS_SERVICE: this->OrderClick_Service(-1); break;
case OHK_ALWAYS_SERVICE: this->OrderClick_Service(std::nullopt); break;
case OHK_TRANSFER: this->OrderClick_Unload(OUFB_TRANSFER, true); break;
case OHK_NO_UNLOAD: this->OrderClick_Unload(OUFB_NO_UNLOAD, true); break;
case OHK_NO_LOAD: this->OrderClick_FullLoad(OLFB_NO_LOAD, true); break;

View File

@@ -84,72 +84,72 @@ enum OrderLoadFlags : uint8_t {
/**
* Non-stop order flags.
*/
enum OrderNonStopFlags : uint8_t {
ONSF_STOP_EVERYWHERE = 0, ///< The vehicle will stop at any station it passes and the destination.
ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS = 1, ///< The vehicle will not stop at any stations it passes except the destination.
ONSF_NO_STOP_AT_DESTINATION_STATION = 2, ///< The vehicle will stop at any station it passes except the destination.
ONSF_NO_STOP_AT_ANY_STATION = 3, ///< The vehicle will not stop at any stations it passes including the destination.
ONSF_END
enum class OrderNonStopFlag : uint8_t {
NoIntermediate = 0, ///< The vehicle will not stop at any stations it passes except the destination, aka non-stop.
NoDestination = 1, ///< The vehicle will stop at any station it passes except the destination, aka via.
};
using OrderNonStopFlags = EnumBitSet<OrderNonStopFlag, uint8_t>;
/**
* Where to stop the trains.
*/
enum OrderStopLocation : uint8_t {
OSL_PLATFORM_NEAR_END = 0, ///< Stop at the near end of the platform
OSL_PLATFORM_MIDDLE = 1, ///< Stop at the middle of the platform
OSL_PLATFORM_FAR_END = 2, ///< Stop at the far end of the platform
OSL_END
enum class OrderStopLocation : uint8_t {
NearEnd = 0, ///< Stop at the near end of the platform
Middle = 1, ///< Stop at the middle of the platform
FarEnd = 2, ///< Stop at the far end of the platform
End,
};
/**
* Reasons that could cause us to go to the depot.
*/
enum OrderDepotTypeFlags : uint8_t {
ODTF_MANUAL = 0, ///< Manually initiated order.
ODTFB_SERVICE = 1 << 0, ///< This depot order is because of the servicing limit.
ODTFB_PART_OF_ORDERS = 1 << 1, ///< This depot order is because of a regular order.
enum class OrderDepotTypeFlag : uint8_t {
Service = 0, ///< This depot order is because of the servicing limit.
PartOfOrders = 1, ///< This depot order is because of a regular order.
};
using OrderDepotTypeFlags = EnumBitSet<OrderDepotTypeFlag, uint8_t>;
/**
* Actions that can be performed when the vehicle enters the depot.
*/
enum OrderDepotActionFlags : uint8_t {
ODATF_SERVICE_ONLY = 0, ///< Only service the vehicle.
ODATFB_HALT = 1 << 0, ///< Service the vehicle and then halt it.
ODATFB_NEAREST_DEPOT = 1 << 1, ///< Send the vehicle to the nearest depot.
ODATFB_UNBUNCH = 1 << 2, ///< Service the vehicle and then unbunch it.
enum class OrderDepotActionFlag : uint8_t {
Halt = 0, ///< Service the vehicle and then halt it.
NearestDepot = 1, ///< Send the vehicle to the nearest depot.
Unbunch = 2, ///< Service the vehicle and then unbunch it.
};
DECLARE_ENUM_AS_BIT_SET(OrderDepotActionFlags)
using OrderDepotActionFlags = EnumBitSet<OrderDepotActionFlag, uint8_t>;
/**
* Variables (of a vehicle) to 'cause' skipping on.
*/
enum OrderConditionVariable : uint8_t {
OCV_LOAD_PERCENTAGE, ///< Skip based on the amount of load
OCV_RELIABILITY, ///< Skip based on the reliability
OCV_MAX_SPEED, ///< Skip based on the maximum speed
OCV_AGE, ///< Skip based on the age
OCV_REQUIRES_SERVICE, ///< Skip when the vehicle requires service
OCV_UNCONDITIONALLY, ///< Always skip
OCV_REMAINING_LIFETIME, ///< Skip based on the remaining lifetime
OCV_MAX_RELIABILITY, ///< Skip based on the maximum reliability
OCV_END
enum class OrderConditionVariable : uint8_t {
LoadPercentage = 0, ///< Skip based on the amount of load
Reliability = 1, ///< Skip based on the reliability
MaxSpeed = 2, ///< Skip based on the maximum speed
Age = 3, ///< Skip based on the age
RequiresService = 4, ///< Skip when the vehicle requires service
Unconditionally = 5, ///< Always skip
RemainingLifetime = 6, ///< Skip based on the remaining lifetime
MaxReliability = 7, ///< Skip based on the maximum reliability
End,
};
/**
* Comparator for the skip reasoning.
*/
enum OrderConditionComparator : uint8_t {
OCC_EQUALS, ///< Skip if both values are equal
OCC_NOT_EQUALS, ///< Skip if both values are not equal
OCC_LESS_THAN, ///< Skip if the value is less than the limit
OCC_LESS_EQUALS, ///< Skip if the value is less or equal to the limit
OCC_MORE_THAN, ///< Skip if the value is more than the limit
OCC_MORE_EQUALS, ///< Skip if the value is more or equal to the limit
OCC_IS_TRUE, ///< Skip if the variable is true
OCC_IS_FALSE, ///< Skip if the variable is false
OCC_END
enum class OrderConditionComparator : uint8_t {
Equal = 0, ///< Skip if both values are equal
NotEqual = 1, ///< Skip if both values are not equal
LessThan = 2, ///< Skip if the value is less than the limit
LessThanOrEqual = 3, ///< Skip if the value is less or equal to the limit
MoreThan = 4, ///< Skip if the value is more than the limit
MoreThanOrEqual = 5, ///< Skip if the value is more or equal to the limit
IsTrue = 6, ///< Skip if the variable is true
IsFalse = 7, ///< Skip if the variable is false
End,
};
@@ -172,12 +172,12 @@ enum ModifyOrderFlags : uint8_t {
/**
* Depot action to switch to when doing a #MOF_DEPOT_ACTION.
*/
enum OrderDepotAction : uint8_t {
DA_ALWAYS_GO, ///< Always go to the depot
DA_SERVICE, ///< Service only if needed
DA_STOP, ///< Go to the depot and stop there
DA_UNBUNCH, ///< Go to the depot and unbunch
DA_END
enum class OrderDepotAction : uint8_t {
AlwaysGo = 0, ///< Always go to the depot
Service = 1, ///< Service only if needed
Stop = 2, ///< Go to the depot and stop there
Unbunch = 3, ///< Go to the depot and unbunch
End
};
/**

View File

@@ -152,7 +152,7 @@ public:
break;
case OT_GOTO_DEPOT:
if (v->current_order.GetDepotActionType() & ODATFB_NEAREST_DEPOT) {
if (v->current_order.GetDepotActionType().Test(OrderDepotActionFlag::NearestDepot)) {
this->any_depot = true;
}
[[fallthrough]];

View File

@@ -1700,13 +1700,13 @@ static void CheckIfRoadVehNeedsService(RoadVehicle *v)
DepotID depot = GetDepotIndex(rfdd.tile);
if (v->current_order.IsType(OT_GOTO_DEPOT) &&
v->current_order.GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS &&
v->current_order.GetNonStopType().Test(OrderNonStopFlag::NoIntermediate) &&
!Chance16(1, 20)) {
return;
}
SetBit(v->gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
v->current_order.MakeGoToDepot(depot, ODTFB_SERVICE);
v->current_order.MakeGoToDepot(depot, OrderDepotTypeFlag::Service);
v->SetDestTile(rfdd.tile);
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
}

View File

@@ -1823,7 +1823,7 @@ bool AfterLoadGame()
v->current_order.ConvertFromOldSavegame();
if (v->type == VEH_ROAD && v->IsPrimaryVehicle() && v->FirstShared() == v) {
for (Order &order : v->Orders()) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
for (Order &order : v->Orders()) order.SetNonStopType(OrderNonStopFlag::NoIntermediate);
}
}
} else if (IsSavegameVersionBefore(SLV_94)) {
@@ -1848,13 +1848,13 @@ bool AfterLoadGame()
for (OrderList *orderlist : OrderList::Iterate()) {
for (Order &order : orderlist->GetOrders()) {
if (!order.IsType(OT_GOTO_DEPOT)) continue;
order.SetDepotActionType((OrderDepotActionFlags)(order.GetDepotActionType() >> 1));
order.SetDepotActionType(static_cast<OrderDepotActionFlags>(order.GetDepotActionType().base() >> 1));
}
}
for (Vehicle *v : Vehicle::Iterate()) {
if (!v->current_order.IsType(OT_GOTO_DEPOT)) continue;
v->current_order.SetDepotActionType((OrderDepotActionFlags)(v->current_order.GetDepotActionType() >> 1));
v->current_order.SetDepotActionType(static_cast<OrderDepotActionFlags>(v->current_order.GetDepotActionType().base() >> 1));
}
}
@@ -2213,7 +2213,7 @@ bool AfterLoadGame()
if (IsSavegameVersionBefore(SLV_117)) {
for (OrderList *orderlist : OrderList::Iterate()) {
for (Order &o : orderlist->GetOrders()) {
if (o.IsType(OT_GOTO_STATION)) o.SetStopLocation(OSL_PLATFORM_FAR_END);
if (o.IsType(OT_GOTO_STATION)) o.SetStopLocation(OrderStopLocation::FarEnd);
}
}
}

View File

@@ -31,9 +31,9 @@ void Order::ConvertFromOldSavegame()
/* First handle non-stop - use value from savegame if possible, else use value from config file */
if (_settings_client.gui.sg_new_nonstop || (IsSavegameVersionBefore(SLV_22) && _savegame_type != SGT_TTO && _savegame_type != SGT_TTD && _settings_client.gui.new_nonstop)) {
/* OFB_NON_STOP */
this->SetNonStopType((old_flags & 8) ? ONSF_NO_STOP_AT_ANY_STATION : ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
this->SetNonStopType((old_flags & 8) ? OrderNonStopFlags{OrderNonStopFlag::NoIntermediate, OrderNonStopFlag::NoDestination} : OrderNonStopFlag::NoIntermediate);
} else {
this->SetNonStopType((old_flags & 8) ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE);
this->SetNonStopType((old_flags & 8) ? OrderNonStopFlag::NoIntermediate : OrderNonStopFlags{});
}
switch (this->GetType()) {
@@ -53,7 +53,7 @@ void Order::ConvertFromOldSavegame()
this->SetLoadType(_settings_client.gui.sg_full_load_any || IsSavegameVersionBefore(SLV_22) ? OLF_FULL_LOAD_ANY : OLFB_FULL_LOAD);
}
if (this->IsType(OT_GOTO_STATION)) this->SetStopLocation(OSL_PLATFORM_FAR_END);
if (this->IsType(OT_GOTO_STATION)) this->SetStopLocation(OrderStopLocation::FarEnd);
/* Finally fix the unload flags */
if ((old_flags & 1) != 0) { // OFB_TRANSFER
@@ -65,12 +65,15 @@ void Order::ConvertFromOldSavegame()
}
} else {
/* Then the depot action flags */
this->SetDepotActionType(((old_flags & 6) == 4) ? ODATFB_HALT : ODATF_SERVICE_ONLY);
OrderDepotActionFlags action_flags{};
if ((old_flags & 6) == 4) action_flags.Set(OrderDepotActionFlag::Halt);
this->SetDepotActionType(action_flags);
/* Finally fix the depot type flags */
uint t = ((old_flags & 6) == 6) ? ODTFB_SERVICE : ODTF_MANUAL;
if ((old_flags & 2) != 0) t |= ODTFB_PART_OF_ORDERS;
this->SetDepotOrderType((OrderDepotTypeFlags)t);
OrderDepotTypeFlags type_flags{};
if ((old_flags & 6) == 6) type_flags.Set(OrderDepotTypeFlag::Service);
if ((old_flags & 2) != 0) type_flags.Set(OrderDepotTypeFlag::PartOfOrders);
this->SetDepotOrderType(type_flags);
}
}

View File

@@ -64,7 +64,7 @@ static const Order *ResolveOrder(VehicleID vehicle_id, ScriptOrder::OrderPositio
const Vehicle *v = ::Vehicle::Get(vehicle_id);
if (order_position == ScriptOrder::ORDER_CURRENT) {
const Order *order = &v->current_order;
if (order->GetType() == OT_GOTO_DEPOT && !(order->GetDepotOrderType() & ODTFB_PART_OF_ORDERS)) return order;
if (order->GetType() == OT_GOTO_DEPOT && !order->GetDepotOrderType().Test(OrderDepotTypeFlag::PartOfOrders)) return order;
order_position = ScriptOrder::ResolveOrderPosition(vehicle_id, order_position);
if (order_position == ScriptOrder::ORDER_INVALID) return nullptr;
}
@@ -170,7 +170,7 @@ static ScriptOrder::OrderPosition RealOrderPositionToScriptOrderPosition(Vehicle
const Order *order = &::Vehicle::Get(vehicle_id)->current_order;
if (order->GetType() != OT_GOTO_DEPOT) return true;
return (order->GetDepotOrderType() & ODTFB_PART_OF_ORDERS) != 0;
return order->GetDepotOrderType().Test(OrderDepotTypeFlag::PartOfOrders);
}
/* static */ ScriptOrder::OrderPosition ScriptOrder::ResolveOrderPosition(VehicleID vehicle_id, OrderPosition order_position)
@@ -249,7 +249,7 @@ static ScriptOrder::OrderPosition RealOrderPositionToScriptOrderPosition(Vehicle
switch (order->GetType()) {
case OT_GOTO_DEPOT: {
/* We don't know where the nearest depot is... (yet) */
if (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) return INVALID_TILE;
if (order->GetDepotActionType().Test(OrderDepotActionFlag::NearestDepot)) return INVALID_TILE;
if (v->type != VEH_AIRCRAFT) return ::Depot::Get(order->GetDestination().ToDepotID())->xy;
/* Aircraft's hangars are referenced by StationID, not DepotID */
@@ -306,12 +306,12 @@ static ScriptOrder::OrderPosition RealOrderPositionToScriptOrderPosition(Vehicle
if (order == nullptr || order->GetType() == OT_CONDITIONAL || order->GetType() == OT_DUMMY) return OF_INVALID;
ScriptOrderFlags order_flags = OF_NONE;
order_flags |= (ScriptOrderFlags)order->GetNonStopType();
order_flags |= static_cast<ScriptOrderFlags>(order->GetNonStopType().base());
switch (order->GetType()) {
case OT_GOTO_DEPOT:
if (order->GetDepotOrderType() & ODTFB_SERVICE) order_flags |= OF_SERVICE_IF_NEEDED;
if (order->GetDepotActionType() & ODATFB_HALT) order_flags |= OF_STOP_IN_DEPOT;
if (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) order_flags |= OF_GOTO_NEAREST_DEPOT;
if (order->GetDepotOrderType().Test(OrderDepotTypeFlag::Service)) order_flags |= OF_SERVICE_IF_NEEDED;
if (order->GetDepotActionType().Test(OrderDepotActionFlag::Halt)) order_flags |= OF_STOP_IN_DEPOT;
if (order->GetDepotActionType().Test(OrderDepotActionFlag::NearestDepot)) order_flags |= OF_GOTO_NEAREST_DEPOT;
break;
case OT_GOTO_STATION:
@@ -359,7 +359,7 @@ static ScriptOrder::OrderPosition RealOrderPositionToScriptOrderPosition(Vehicle
const Order *order = ::ResolveOrder(vehicle_id, order_position);
SQInteger value = order->GetConditionValue();
if (order->GetConditionVariable() == OCV_MAX_SPEED) value = value * 16 / 10;
if (order->GetConditionVariable() == OrderConditionVariable::MaxSpeed) value = value * 16 / 10;
return value;
}
@@ -484,11 +484,16 @@ static ScriptOrder::OrderPosition RealOrderPositionToScriptOrderPosition(Vehicle
OrderType ot = (order_flags & OF_GOTO_NEAREST_DEPOT) ? OT_GOTO_DEPOT : ::GetOrderTypeByTile(destination);
switch (ot) {
case OT_GOTO_DEPOT: {
OrderDepotTypeFlags odtf = (OrderDepotTypeFlags)(ODTFB_PART_OF_ORDERS | ((order_flags & OF_SERVICE_IF_NEEDED) ? ODTFB_SERVICE : 0));
OrderDepotActionFlags odaf = (OrderDepotActionFlags)(ODATF_SERVICE_ONLY | ((order_flags & OF_STOP_IN_DEPOT) ? ODATFB_HALT : 0));
if (order_flags & OF_GOTO_NEAREST_DEPOT) odaf |= ODATFB_NEAREST_DEPOT;
OrderNonStopFlags onsf = (OrderNonStopFlags)((order_flags & OF_NON_STOP_INTERMEDIATE) ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE);
if (order_flags & OF_GOTO_NEAREST_DEPOT) {
OrderDepotTypeFlags odtf = OrderDepotTypeFlag::PartOfOrders;
if ((order_flags & OF_SERVICE_IF_NEEDED) != 0) odtf.Set(OrderDepotTypeFlag::Service);
OrderDepotActionFlags odaf{};
if ((order_flags & OF_STOP_IN_DEPOT) != 0) odaf.Set(OrderDepotActionFlag::Halt);
if ((order_flags & OF_GOTO_NEAREST_DEPOT) != 0) odaf.Set(OrderDepotActionFlag::NearestDepot);
OrderNonStopFlags onsf{};
if ((order_flags & OF_NON_STOP_INTERMEDIATE) != 0) onsf.Set(OrderNonStopFlag::NoIntermediate);
if ((order_flags & OF_GOTO_NEAREST_DEPOT) != 0) {
order.MakeGoToDepot(DepotID::Invalid(), odtf, onsf, odaf);
} else {
/* Check explicitly if the order is to a station (for aircraft) or
@@ -508,7 +513,7 @@ static ScriptOrder::OrderPosition RealOrderPositionToScriptOrderPosition(Vehicle
order.MakeGoToStation(::GetStationIndex(destination));
order.SetLoadType((OrderLoadFlags)GB(order_flags, 5, 3));
order.SetUnloadType((OrderUnloadFlags)GB(order_flags, 2, 3));
order.SetStopLocation(OSL_PLATFORM_FAR_END);
order.SetStopLocation(OrderStopLocation::FarEnd);
break;
case OT_GOTO_WAYPOINT:
@@ -519,7 +524,7 @@ static ScriptOrder::OrderPosition RealOrderPositionToScriptOrderPosition(Vehicle
return false;
}
order.SetNonStopType((OrderNonStopFlags)GB(order_flags, 0, 2));
order.SetNonStopType(static_cast<OrderNonStopFlags>(GB(order_flags, 0, 2)));
int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position);
return ScriptObject::Command<CMD_INSERT_ORDER>::Do(0, vehicle_id, order_pos, order);
@@ -613,10 +618,10 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance &instance)
switch (order->GetType()) {
case OT_GOTO_DEPOT:
if ((current & OF_DEPOT_FLAGS) != (order_flags & OF_DEPOT_FLAGS)) {
uint data = DA_ALWAYS_GO;
if (order_flags & OF_SERVICE_IF_NEEDED) data = DA_SERVICE;
if (order_flags & OF_STOP_IN_DEPOT) data = DA_STOP;
return ScriptObject::Command<CMD_MODIFY_ORDER>::Do(&::_DoCommandReturnSetOrderFlags, vehicle_id, order_pos, MOF_DEPOT_ACTION, data);
OrderDepotAction data = OrderDepotAction::AlwaysGo;
if ((order_flags & OF_SERVICE_IF_NEEDED) != 0) data = OrderDepotAction::Service;
if ((order_flags & OF_STOP_IN_DEPOT) != 0) data = OrderDepotAction::Stop;
return ScriptObject::Command<CMD_MODIFY_ORDER>::Do(&::_DoCommandReturnSetOrderFlags, vehicle_id, order_pos, MOF_DEPOT_ACTION, to_underlying(data));
}
break;

View File

@@ -89,14 +89,14 @@ public:
*/
enum OrderCondition {
/* Note: these values represent part of the in-game OrderConditionVariable enum */
OC_LOAD_PERCENTAGE = ::OCV_LOAD_PERCENTAGE, ///< Skip based on the amount of load, value is in tons.
OC_RELIABILITY = ::OCV_RELIABILITY, ///< Skip based on the reliability, value is percent (0..100).
OC_MAX_RELIABILITY = ::OCV_MAX_RELIABILITY, ///< Skip based on the maximum reliability. Value in percent
OC_MAX_SPEED = ::OCV_MAX_SPEED, ///< Skip based on the maximum speed, value is in OpenTTD's internal speed unit, see ScriptEngine::GetMaxSpeed.
OC_AGE = ::OCV_AGE, ///< Skip based on the age, value is in calendar-years. @see \ref ScriptCalendarTime
OC_REQUIRES_SERVICE = ::OCV_REQUIRES_SERVICE, ///< Skip when the vehicle requires service, no value.
OC_UNCONDITIONALLY = ::OCV_UNCONDITIONALLY, ///< Always skip, no compare function, no value.
OC_REMAINING_LIFETIME = ::OCV_REMAINING_LIFETIME, ///< Skip based on the remaining lifetime in calendar-years. @see \ref ScriptCalendarTime
OC_LOAD_PERCENTAGE = to_underlying(::OrderConditionVariable::LoadPercentage), ///< Skip based on the amount of load, value is in tons.
OC_RELIABILITY = to_underlying(::OrderConditionVariable::Reliability), ///< Skip based on the reliability, value is percent (0..100).
OC_MAX_RELIABILITY = to_underlying(::OrderConditionVariable::MaxReliability), ///< Skip based on the maximum reliability. Value in percent
OC_MAX_SPEED = to_underlying(::OrderConditionVariable::MaxSpeed), ///< Skip based on the maximum speed, value is in OpenTTD's internal speed unit, see ScriptEngine::GetMaxSpeed.
OC_AGE = to_underlying(::OrderConditionVariable::Age), ///< Skip based on the age, value is in calendar-years. @see \ref ScriptCalendarTime
OC_REQUIRES_SERVICE = to_underlying(::OrderConditionVariable::RequiresService), ///< Skip when the vehicle requires service, no value.
OC_UNCONDITIONALLY = to_underlying(::OrderConditionVariable::Unconditionally), ///< Always skip, no compare function, no value.
OC_REMAINING_LIFETIME = to_underlying(::OrderConditionVariable::RemainingLifetime), ///< Skip based on the remaining lifetime in calendar-years. @see \ref ScriptCalendarTime
/* Custom added value, only valid for this API */
OC_INVALID = -1, ///< An invalid condition, do not use.
@@ -107,14 +107,14 @@ public:
*/
enum CompareFunction {
/* Note: these values represent part of the in-game OrderConditionComparator enum */
CF_EQUALS = ::OCC_EQUALS, ///< Skip if both values are equal
CF_NOT_EQUALS = ::OCC_NOT_EQUALS, ///< Skip if both values are not equal
CF_LESS_THAN = ::OCC_LESS_THAN, ///< Skip if the value is less than the limit
CF_LESS_EQUALS = ::OCC_LESS_EQUALS, ///< Skip if the value is less or equal to the limit
CF_MORE_THAN = ::OCC_MORE_THAN, ///< Skip if the value is more than the limit
CF_MORE_EQUALS = ::OCC_MORE_EQUALS, ///< Skip if the value is more or equal to the limit
CF_IS_TRUE = ::OCC_IS_TRUE, ///< Skip if the variable is true
CF_IS_FALSE = ::OCC_IS_FALSE, ///< Skip if the variable is false
CF_EQUALS = to_underlying(::OrderConditionComparator::Equal), ///< Skip if both values are equal
CF_NOT_EQUALS = to_underlying(::OrderConditionComparator::NotEqual), ///< Skip if both values are not equal
CF_LESS_THAN = to_underlying(::OrderConditionComparator::LessThan), ///< Skip if the value is less than the limit
CF_LESS_EQUALS = to_underlying(::OrderConditionComparator::LessThanOrEqual), ///< Skip if the value is less or equal to the limit
CF_MORE_THAN = to_underlying(::OrderConditionComparator::MoreThan), ///< Skip if the value is more than the limit
CF_MORE_EQUALS = to_underlying(::OrderConditionComparator::MoreThanOrEqual), ///< Skip if the value is more or equal to the limit
CF_IS_TRUE = to_underlying(::OrderConditionComparator::IsTrue), ///< Skip if the variable is true
CF_IS_FALSE = to_underlying(::OrderConditionComparator::IsFalse), ///< Skip if the variable is false
/* Custom added value, only valid for this API */
CF_INVALID = -1, ///< Invalid compare function, do not use.

View File

@@ -171,7 +171,7 @@ struct GUISettings {
bool show_finances; ///< show finances at end of year
bool sg_new_nonstop; ///< ttdpatch compatible nonstop handling read from pre v93 savegames
bool new_nonstop; ///< ttdpatch compatible nonstop handling
uint8_t stop_location; ///< what is the default stop location of trains?
OrderStopLocation stop_location; ///< what is the default stop location of trains?
uint8_t auto_scrolling; ///< scroll when moving mouse to the edge (see #ViewportAutoscrolling)
uint8_t errmsg_duration; ///< duration of error message
uint16_t hover_delay_ms; ///< time required to activate a hover event, in milliseconds

View File

@@ -220,7 +220,7 @@ static void CheckIfShipNeedsService(Vehicle *v)
return;
}
v->current_order.MakeGoToDepot(depot->index, ODTFB_SERVICE);
v->current_order.MakeGoToDepot(depot->index, OrderDepotTypeFlag::Service);
v->SetDestTile(depot->xy);
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
}

View File

@@ -167,7 +167,7 @@ CommandCost CmdChangeTimetable(DoCommandFlags flags, VehicleID veh, VehicleOrder
if (wait_time != order->GetWaitTime()) {
switch (order->GetType()) {
case OT_GOTO_STATION:
if (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) return CommandCost(STR_ERROR_TIMETABLE_NOT_STOPPING_HERE);
if (order->GetNonStopType().Test(OrderNonStopFlag::NoDestination)) return CommandCost(STR_ERROR_TIMETABLE_NOT_STOPPING_HERE);
break;
case OT_CONDITIONAL:
@@ -317,8 +317,8 @@ static bool VehicleTimetableSorter(Vehicle * const &a, Vehicle * const &b)
int j = (int)b_order - (int)a_order;
/* Are we currently at an ordered station (un)loading? */
bool a_load = a->current_order.IsType(OT_LOADING) && a->current_order.GetNonStopType() != ONSF_STOP_EVERYWHERE;
bool b_load = b->current_order.IsType(OT_LOADING) && b->current_order.GetNonStopType() != ONSF_STOP_EVERYWHERE;
bool a_load = a->current_order.IsType(OT_LOADING) && a->current_order.GetNonStopType().Any();
bool b_load = b->current_order.IsType(OT_LOADING) && b->current_order.GetNonStopType().Any();
/* If the current order is not loading at the ordered station, decrease the order index by one since we have
* not yet arrived at the station (and thus the timetable entry; still in the travelling of the previous one).

View File

@@ -110,7 +110,7 @@ static bool CanDetermineTimeTaken(const Order &order, bool travelling)
if (travelling && !order.IsTravelTimetabled()) return false;
/* No wait time but we are loading at this timetabled station */
if (!travelling && !order.IsWaitTimetabled() && order.IsType(OT_GOTO_STATION) &&
!(order.GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION)) {
!order.GetNonStopType().Test(OrderNonStopFlag::NoDestination)) {
return false;
}
@@ -208,7 +208,7 @@ struct TimetableWindow : Window {
{
assert(v->vehicle_flags.Test(VehicleFlag::TimetableStarted));
bool travelling = (!v->current_order.IsType(OT_LOADING) || v->current_order.GetNonStopType() == ONSF_STOP_EVERYWHERE);
bool travelling = (!v->current_order.IsType(OT_LOADING) || v->current_order.GetNonStopType().None());
TimerGameTick::Ticks start_time = -v->current_order_time;
/* If arrival and departure times are in days, compensate for the current date_fract. */
@@ -348,7 +348,7 @@ struct TimetableWindow : Window {
if (selected % 2 != 0) {
disable = order != nullptr && (order->IsType(OT_CONDITIONAL) || order->IsType(OT_IMPLICIT));
} else {
disable = order == nullptr || ((!order->IsType(OT_GOTO_STATION) || (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION)) && !order->IsType(OT_CONDITIONAL));
disable = order == nullptr || ((!order->IsType(OT_GOTO_STATION) || order->GetNonStopType().Test(OrderNonStopFlag::NoDestination)) && !order->IsType(OT_CONDITIONAL));
}
}
bool disable_speed = disable || selected % 2 == 0 || v->type == VEH_AIRCRAFT;

View File

@@ -265,10 +265,10 @@ int GetTrainStopLocation(StationID station_id, TileIndex tile, const Train *v, i
/* Default to the middle of the station for stations stops that are not in
* the order list like intermediate stations when non-stop is disabled */
OrderStopLocation osl = OSL_PLATFORM_MIDDLE;
OrderStopLocation osl = OrderStopLocation::Middle;
if (v->gcache.cached_total_length >= *station_length) {
/* The train is longer than the station, make it stop at the far end of the platform */
osl = OSL_PLATFORM_FAR_END;
osl = OrderStopLocation::FarEnd;
} else if (v->current_order.IsType(OT_GOTO_STATION) && v->current_order.GetDestination() == station_id) {
osl = v->current_order.GetStopLocation();
}
@@ -278,15 +278,15 @@ int GetTrainStopLocation(StationID station_id, TileIndex tile, const Train *v, i
switch (osl) {
default: NOT_REACHED();
case OSL_PLATFORM_NEAR_END:
case OrderStopLocation::NearEnd:
stop = v->gcache.cached_total_length;
break;
case OSL_PLATFORM_MIDDLE:
case OrderStopLocation::Middle:
stop = *station_length - (*station_length - v->gcache.cached_total_length) / 2;
break;
case OSL_PLATFORM_FAR_END:
case OrderStopLocation::FarEnd:
stop = *station_length;
break;
}
@@ -2675,7 +2675,7 @@ public:
switch (order->GetType()) {
case OT_GOTO_DEPOT:
/* Skip service in depot orders when the train doesn't need service. */
if ((order->GetDepotOrderType() & ODTFB_SERVICE) && !this->v->NeedsServicing()) break;
if (order->GetDepotOrderType().Test(OrderDepotTypeFlag::Service) && !this->v->NeedsServicing()) break;
[[fallthrough]];
case OT_GOTO_STATION:
case OT_GOTO_WAYPOINT:
@@ -2859,7 +2859,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
orders.Restore();
if (v->current_order.IsType(OT_GOTO_DEPOT) &&
(v->current_order.GetDepotActionType() & ODATFB_NEAREST_DEPOT) &&
v->current_order.GetDepotActionType().Test(OrderDepotActionFlag::NearestDepot) &&
final_dest != INVALID_TILE && IsRailDepotTile(final_dest)) {
v->current_order.SetDestination(GetDepotIndex(final_dest));
v->dest_tile = final_dest;
@@ -4042,7 +4042,7 @@ static bool TrainLocoHandler(Train *v, bool mode)
OrderType order_type = v->current_order.GetType();
/* Do not skip waypoints (incl. 'via' stations) when passing through at full speed. */
if ((order_type == OT_GOTO_WAYPOINT || order_type == OT_GOTO_STATION) &&
(v->current_order.GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) &&
v->current_order.GetNonStopType().Test(OrderNonStopFlag::NoDestination) &&
IsTileType(v->tile, MP_STATION) &&
v->current_order.GetDestination() == GetStationIndex(v->tile)) {
ProcessOrders(v);
@@ -4152,7 +4152,7 @@ static void CheckIfTrainNeedsService(Train *v)
}
SetBit(v->gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
v->current_order.MakeGoToDepot(depot, ODTFB_SERVICE, ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS, ODATFB_NEAREST_DEPOT);
v->current_order.MakeGoToDepot(depot, OrderDepotTypeFlag::Service, OrderNonStopFlag::NoIntermediate, OrderDepotActionFlag::NearestDepot);
v->dest_tile = tfdd.tile;
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
}

View File

@@ -284,7 +284,7 @@ bool Vehicle::NeedsAutomaticServicing() const
{
if (this->HasDepotOrder()) return false;
if (this->current_order.IsType(OT_LOADING)) return false;
if (this->current_order.IsType(OT_GOTO_DEPOT) && (this->current_order.GetDepotOrderType() & ODTFB_SERVICE) == 0) return false;
if (this->current_order.IsType(OT_GOTO_DEPOT) && !this->current_order.GetDepotOrderType().Test(OrderDepotTypeFlag::Service)) return false;
return NeedsServicing();
}
@@ -1588,8 +1588,8 @@ void VehicleEnterDepot(Vehicle *v)
/* Test whether we are heading for this depot. If not, do nothing.
* Note: The target depot for nearest-/manual-depot-orders is only updated on junctions, but we want to accept every depot. */
if ((v->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) &&
real_order != nullptr && !(real_order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) &&
if (v->current_order.GetDepotOrderType().Test(OrderDepotTypeFlag::PartOfOrders) &&
real_order != nullptr && !real_order->GetDepotActionType().Test(OrderDepotActionFlag::NearestDepot) &&
(v->type == VEH_AIRCRAFT ? v->current_order.GetDestination() != GetStationIndex(v->tile) : v->dest_tile != v->tile)) {
/* We are heading for another depot, keep driving. */
return;
@@ -1614,13 +1614,13 @@ void VehicleEnterDepot(Vehicle *v)
}
}
if (v->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) {
if (v->current_order.GetDepotOrderType().Test(OrderDepotTypeFlag::PartOfOrders)) {
/* Part of orders */
v->DeleteUnreachedImplicitOrders();
UpdateVehicleTimetable(v, true);
v->IncrementImplicitOrderIndex();
}
if (v->current_order.GetDepotActionType() & ODATFB_HALT) {
if (v->current_order.GetDepotActionType().Test(OrderDepotActionFlag::Halt)) {
/* Vehicles are always stopped on entering depots. Do not restart this one. */
_vehicles_to_autoreplace[v->index] = false;
/* Invalidate last_loading_station. As the link from the station
@@ -1639,7 +1639,7 @@ void VehicleEnterDepot(Vehicle *v)
}
/* If we've entered our unbunching depot, record the round trip duration. */
if (v->current_order.GetDepotActionType() & ODATFB_UNBUNCH && v->depot_unbunching_last_departure > 0) {
if (v->current_order.GetDepotActionType().Test(OrderDepotActionFlag::Unbunch) && v->depot_unbunching_last_departure > 0) {
TimerGameTick::Ticks measured_round_trip = TimerGameTick::counter - v->depot_unbunching_last_departure;
if (v->round_trip_time == 0) {
/* This might be our first round trip. */
@@ -2198,7 +2198,7 @@ void Vehicle::BeginLoading()
* necessary to be known for HandleTrainLoading to determine
* whether the train is lost or not; not marking a train lost
* that arrives at random stations is bad. */
this->current_order.SetNonStopType(ONSF_NO_STOP_AT_ANY_STATION);
this->current_order.SetNonStopType({OrderNonStopFlag::NoIntermediate, OrderNonStopFlag::NoDestination});
} else {
/* We weren't scheduled to stop here. Insert an implicit order
@@ -2332,7 +2332,7 @@ void Vehicle::LeaveStation()
assert(this->cargo_payment == nullptr); // cleared by ~CargoPayment
/* Only update the timetable if the vehicle was supposed to stop here. */
if (this->current_order.GetNonStopType() != ONSF_STOP_EVERYWHERE) UpdateVehicleTimetable(this, false);
if (this->current_order.GetNonStopType().Any()) UpdateVehicleTimetable(this, false);
if ((this->current_order.GetLoadType() & OLFB_NO_LOAD) == 0 ||
(this->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0) {
@@ -2462,7 +2462,7 @@ bool Vehicle::HasConditionalOrder() const
bool Vehicle::HasUnbunchingOrder() const
{
return std::ranges::any_of(this->Orders(), [](const Order &o) {
return o.IsType(OT_GOTO_DEPOT) && (o.GetDepotActionType() & ODATFB_UNBUNCH);
return o.IsType(OT_GOTO_DEPOT) && o.GetDepotActionType().Test(OrderDepotActionFlag::Unbunch);
});
}
@@ -2477,7 +2477,7 @@ static bool PreviousOrderIsUnbunching(const Vehicle *v)
const Order *previous_order = (is_first_order) ? v->GetLastOrder() : v->GetOrder(v->cur_implicit_order_index - 1);
if (previous_order == nullptr || !previous_order->IsType(OT_GOTO_DEPOT)) return false;
return (previous_order->GetDepotActionType() & ODATFB_UNBUNCH) != 0;
return previous_order->GetDepotActionType().Test(OrderDepotActionFlag::Unbunch);
}
/**
@@ -2564,14 +2564,14 @@ CommandCost Vehicle::SendToDepot(DoCommandFlags flags, DepotCommandFlags command
if (flags.Test(DoCommandFlag::Execute)) this->ResetDepotUnbunching();
if (this->current_order.IsType(OT_GOTO_DEPOT)) {
bool halt_in_depot = (this->current_order.GetDepotActionType() & ODATFB_HALT) != 0;
bool halt_in_depot = this->current_order.GetDepotActionType().Test(OrderDepotActionFlag::Halt);
if (command.Test(DepotCommandFlag::Service) == halt_in_depot) {
/* We called with a different DEPOT_SERVICE setting.
* Now we change the setting to apply the new one and let the vehicle head for the same depot.
* Note: the if is (true for requesting service == true for ordered to stop in depot) */
if (flags.Test(DoCommandFlag::Execute)) {
this->current_order.SetDepotOrderType(ODTF_MANUAL);
this->current_order.SetDepotActionType(halt_in_depot ? ODATF_SERVICE_ONLY : ODATFB_HALT);
this->current_order.SetDepotOrderType({});
this->current_order.SetDepotActionType(halt_in_depot ? OrderDepotActionFlags{} : OrderDepotActionFlag::Halt);
SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
}
return CommandCost();
@@ -2581,7 +2581,7 @@ CommandCost Vehicle::SendToDepot(DoCommandFlags flags, DepotCommandFlags command
if (flags.Test(DoCommandFlag::Execute)) {
/* If the orders to 'goto depot' are in the orders list (forced servicing),
* then skip to the next order; effectively cancelling this forced service */
if (this->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) this->IncrementRealOrderIndex();
if (this->current_order.GetDepotOrderType().Test(OrderDepotTypeFlag::PartOfOrders)) this->IncrementRealOrderIndex();
if (this->IsGroundVehicle()) {
uint16_t &gv_flags = this->GetGroundVehicleFlags();
@@ -2607,8 +2607,8 @@ CommandCost Vehicle::SendToDepot(DoCommandFlags flags, DepotCommandFlags command
}
this->SetDestTile(closest_depot.location);
this->current_order.MakeGoToDepot(closest_depot.destination.ToDepotID(), ODTF_MANUAL);
if (!command.Test(DepotCommandFlag::Service)) this->current_order.SetDepotActionType(ODATFB_HALT);
this->current_order.MakeGoToDepot(closest_depot.destination.ToDepotID(), {});
if (!command.Test(DepotCommandFlag::Service)) this->current_order.SetDepotActionType(OrderDepotActionFlag::Halt);
SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
/* If there is no depot in front and the train is not already reversing, reverse automatically (trains only) */

View File

@@ -3164,11 +3164,11 @@ public:
if (v->current_order.GetDestination() == DepotID::Invalid()) return {};
auto params = MakeParameters(v->type, v->current_order.GetDestination(), PackVelocity(v->GetDisplaySpeed(), v->type));
if (v->current_order.GetDepotActionType() & ODATFB_HALT) {
if (v->current_order.GetDepotActionType().Test(OrderDepotActionFlag::Halt)) {
return GetStringWithArgs(v->vehicle_flags.Test(VehicleFlag::PathfinderLost) ? STR_VEHICLE_STATUS_CANNOT_REACH_DEPOT_VEL : STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_VEL, params);
}
if (v->current_order.GetDepotActionType() & ODATFB_UNBUNCH) {
if (v->current_order.GetDepotActionType().Test(OrderDepotActionFlag::Unbunch)) {
return GetStringWithArgs(v->vehicle_flags.Test(VehicleFlag::PathfinderLost) ? STR_VEHICLE_STATUS_CANNOT_REACH_DEPOT_SERVICE_VEL : STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_UNBUNCH_VEL, params);
}

View File

@@ -114,7 +114,7 @@ bool GenerateVehicleSortList(VehicleList *list, const VehicleListIdentifier &vli
case VL_DEPOT_LIST:
FindVehiclesWithOrder(
[&vli](const Vehicle *v) { return v->type == vli.vtype; },
[&vli](const Order *order) { return order->IsType(OT_GOTO_DEPOT) && !(order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) && order->GetDestination() == vli.ToDestinationID(); },
[&vli](const Order *order) { return order->IsType(OT_GOTO_DEPOT) && !order->GetDepotActionType().Test(OrderDepotActionFlag::NearestDepot) && order->GetDestination() == vli.ToDestinationID(); },
[&list](const Vehicle *v) { list->push_back(v); }
);
break;