1
0
mirror of https://github.com/OpenTTD/OpenTTD synced 2026-01-23 04:04:09 +01:00

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

This commit is contained in:
Peter Nelson
2025-12-06 12:29:11 +00:00
committed by GitHub
parent c1d37d8699
commit 046b0c6267
20 changed files with 358 additions and 340 deletions

View File

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