diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 20de291c7b..eea0879dc0 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -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); diff --git a/src/order_backup.cpp b/src/order_backup.cpp index ae52f635c9..2bd2032956 100644 --- a/src/order_backup.cpp +++ b/src/order_backup.cpp @@ -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) { diff --git a/src/order_base.h b/src/order_base.h index 5dac764838..5697522bf8 100644 --- a/src/order_base.h +++ b/src/order_base.h @@ -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(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(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(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(GB(this->flags, 3, 4)); } /** What variable do we have to compare? */ inline OrderConditionVariable GetConditionVariable() const { return static_cast(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(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; diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 8754c96874..a6f604d123 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -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(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(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(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(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(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(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(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); } diff --git a/src/order_gui.cpp b/src/order_gui.cpp index d131681252..c9f6127a2b 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -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 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::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, sel_ord, MOF_DEPOT_ACTION, i); + Command::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::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 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::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, sel_ord, MOF_NON_STOP, non_stop); + Command::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(WID_O_COND_VARIABLE)->SetString(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + ocv); - this->GetWidget(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(WID_O_COND_VARIABLE)->SetString(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + to_underlying(ocv)); + this->GetWidget(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::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(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(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(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; diff --git a/src/order_type.h b/src/order_type.h index d52b33599b..fda91c9d59 100644 --- a/src/order_type.h +++ b/src/order_type.h @@ -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; + /** * 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; + /** * 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; /** * 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 }; /** diff --git a/src/pathfinder/yapf/yapf_destrail.hpp b/src/pathfinder/yapf/yapf_destrail.hpp index 55a3f2bc62..21dc517848 100644 --- a/src/pathfinder/yapf/yapf_destrail.hpp +++ b/src/pathfinder/yapf/yapf_destrail.hpp @@ -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]]; diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 060ec3694b..79ef10c9c5 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -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); } diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 388b30f564..8487f304b1 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -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(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(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); } } } diff --git a/src/saveload/order_sl.cpp b/src/saveload/order_sl.cpp index da1c0983e1..89427c2fdb 100644 --- a/src/saveload/order_sl.cpp +++ b/src/saveload/order_sl.cpp @@ -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); } } diff --git a/src/script/api/script_order.cpp b/src/script/api/script_order.cpp index fbd98e2189..abe76d3f29 100644 --- a/src/script/api/script_order.cpp +++ b/src/script/api/script_order.cpp @@ -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(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(GB(order_flags, 0, 2))); int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position); return ScriptObject::Command::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::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::Do(&::_DoCommandReturnSetOrderFlags, vehicle_id, order_pos, MOF_DEPOT_ACTION, to_underlying(data)); } break; diff --git a/src/script/api/script_order.hpp b/src/script/api/script_order.hpp index e373e1e562..534e0b92b5 100644 --- a/src/script/api/script_order.hpp +++ b/src/script/api/script_order.hpp @@ -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. diff --git a/src/settings_type.h b/src/settings_type.h index eeef3aac22..83a5f828d3 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -169,7 +169,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 diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 8300b03c15..777e983b4e 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -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); } diff --git a/src/timetable_cmd.cpp b/src/timetable_cmd.cpp index 8022137ba6..8b548f5228 100644 --- a/src/timetable_cmd.cpp +++ b/src/timetable_cmd.cpp @@ -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). diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index f7413e6678..a380b37779 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -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; diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 6f143f5112..d17584491a 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -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); } diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 95764752d2..849f09338b 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -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) */ diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 9b0e0af438..49a7087c98 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -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); } diff --git a/src/vehiclelist.cpp b/src/vehiclelist.cpp index bf5ac560b8..da4e36e7a9 100644 --- a/src/vehiclelist.cpp +++ b/src/vehiclelist.cpp @@ -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;