1
0
mirror of https://github.com/OpenTTD/OpenTTD synced 2026-01-26 05:34:12 +01:00

Codechange: make aircraft vehicle flags enum-class and EnumBitSet

This commit is contained in:
Rubidium
2026-01-15 18:05:02 +01:00
committed by rubidium42
parent d2757ca5f6
commit d4f0ff927e
5 changed files with 27 additions and 25 deletions

View File

@@ -33,17 +33,18 @@ enum AircraftSubType : uint8_t {
};
/** Flags for air vehicles; shared with disaster vehicles. */
enum AirVehicleFlags : uint8_t {
VAF_DEST_TOO_FAR = 0, ///< Next destination is too far away.
enum class VehicleAirFlag : uint8_t {
DestinationTooFar = 0, ///< Next destination is too far away.
/* The next two flags are to prevent stair climbing of the aircraft. The idea is that the aircraft
* will ascend or descend multiple flight levels at a time instead of following the contours of the
* landscape at a fixed altitude. This only has effect when there are more than 15 height levels. */
VAF_IN_MAX_HEIGHT_CORRECTION = 1, ///< The vehicle is currently lowering its altitude because it hit the upper bound.
VAF_IN_MIN_HEIGHT_CORRECTION = 2, ///< The vehicle is currently raising its altitude because it hit the lower bound.
InMaximumHeightCorrection = 1, ///< The vehicle is currently lowering its altitude because it hit the upper bound.
InMinimumHeightCorrection = 2, ///< The vehicle is currently raising its altitude because it hit the lower bound.
VAF_HELI_DIRECT_DESCENT = 3, ///< The helicopter is descending directly at its destination (helipad or in front of hangar)
HelicopterDirectDescent = 3, ///< The helicopter is descending directly at its destination (helipad or in front of hangar)
};
using VehicleAirFlags = EnumBitSet<VehicleAirFlag, uint8_t>;
static const int ROTOR_Z_OFFSET = 5; ///< Z Offset between helicopter- and rotorsprite.
@@ -78,7 +79,7 @@ struct Aircraft final : public SpecializedVehicle<Aircraft, VEH_AIRCRAFT> {
Direction last_direction = INVALID_DIR;
uint8_t number_consecutive_turns = 0; ///< Protection to prevent the aircraft of making a lot of turns in order to reach a specific point.
uint8_t turn_counter = 0; ///< Ticks between each turn to prevent > 45 degree turns.
uint8_t flags = 0; ///< Aircraft flags. @see AirVehicleFlags
VehicleAirFlags flags{}; ///< Aircraft flags. @see VehicleAirFlags
AircraftCache acache{};

View File

@@ -778,24 +778,24 @@ int GetAircraftFlightLevel(T *v, bool takeoff)
int z = v->z_pos;
if (z < aircraft_min_altitude ||
(HasBit(v->flags, VAF_IN_MIN_HEIGHT_CORRECTION) && z < aircraft_middle_altitude)) {
(v->flags.Test(VehicleAirFlag::InMinimumHeightCorrection) && z < aircraft_middle_altitude)) {
/* Ascend. And don't fly into that mountain right ahead.
* And avoid our aircraft become a stairclimber, so if we start
* correcting altitude, then we stop correction not too early. */
SetBit(v->flags, VAF_IN_MIN_HEIGHT_CORRECTION);
v->flags.Set(VehicleAirFlag::InMinimumHeightCorrection);
z += takeoff ? 2 : 1;
} else if (!takeoff && (z > aircraft_max_altitude ||
(HasBit(v->flags, VAF_IN_MAX_HEIGHT_CORRECTION) && z > aircraft_middle_altitude))) {
(v->flags.Test(VehicleAirFlag::InMaximumHeightCorrection) && z > aircraft_middle_altitude))) {
/* Descend lower. You are an aircraft, not an space ship.
* And again, don't stop correcting altitude too early. */
SetBit(v->flags, VAF_IN_MAX_HEIGHT_CORRECTION);
v->flags.Set(VehicleAirFlag::InMaximumHeightCorrection);
z--;
} else if (HasBit(v->flags, VAF_IN_MIN_HEIGHT_CORRECTION) && z >= aircraft_middle_altitude) {
} else if (v->flags.Test(VehicleAirFlag::InMinimumHeightCorrection) && z >= aircraft_middle_altitude) {
/* Now, we have corrected altitude enough. */
ClrBit(v->flags, VAF_IN_MIN_HEIGHT_CORRECTION);
} else if (HasBit(v->flags, VAF_IN_MAX_HEIGHT_CORRECTION) && z <= aircraft_middle_altitude) {
v->flags.Reset(VehicleAirFlag::InMinimumHeightCorrection);
} else if (v->flags.Test(VehicleAirFlag::InMaximumHeightCorrection) && z <= aircraft_middle_altitude) {
/* Now, we have corrected altitude enough. */
ClrBit(v->flags, VAF_IN_MAX_HEIGHT_CORRECTION);
v->flags.Reset(VehicleAirFlag::InMaximumHeightCorrection);
}
return z;
@@ -940,7 +940,7 @@ static bool AircraftController(Aircraft *v)
/* Helicopter landing. */
if (amd.flags.Test(AirportMovingDataFlag::HeliLower)) {
SetBit(v->flags, VAF_HELI_DIRECT_DESCENT);
v->flags.Set(VehicleAirFlag::HelicopterDirectDescent);
if (st == nullptr) {
v->state = FLYING;
@@ -967,7 +967,7 @@ static bool AircraftController(Aircraft *v)
/* Increase speed of rotors. When speed is 80, we've landed. */
if (u->cur_speed >= 80) {
ClrBit(v->flags, VAF_HELI_DIRECT_DESCENT);
v->flags.Reset(VehicleAirFlag::HelicopterDirectDescent);
return true;
}
u->cur_speed += 4;
@@ -1688,7 +1688,7 @@ static void AircraftEventHandler_Flying(Aircraft *v, const AirportFTAClass *apc)
uint16_t tsubspeed = v->subspeed;
if (!AirportHasBlock(v, current, apc)) {
v->state = landingtype; // LANDING / HELILANDING
if (v->state == HELILANDING) SetBit(v->flags, VAF_HELI_DIRECT_DESCENT);
if (v->state == HELILANDING) v->flags.Set(VehicleAirFlag::HelicopterDirectDescent);
/* it's a bit dirty, but I need to set position to next position, otherwise
* if there are multiple runways, plane won't know which one it took (because
* they all have heading LANDING). And also occupy that block! */
@@ -2072,8 +2072,8 @@ static bool AirportFindFreeHelipad(Aircraft *v, const AirportFTAClass *apc)
static void AircraftHandleDestTooFar(Aircraft *v, bool too_far)
{
if (too_far) {
if (!HasBit(v->flags, VAF_DEST_TOO_FAR)) {
SetBit(v->flags, VAF_DEST_TOO_FAR);
if (!v->flags.Test(VehicleAirFlag::DestinationTooFar)) {
v->flags.Set(VehicleAirFlag::DestinationTooFar);
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
AI::NewEvent(v->owner, new ScriptEventAircraftDestTooFar(v->index));
if (v->owner == _local_company) {
@@ -2084,9 +2084,9 @@ static void AircraftHandleDestTooFar(Aircraft *v, bool too_far)
return;
}
if (HasBit(v->flags, VAF_DEST_TOO_FAR)) {
if (v->flags.Test(VehicleAirFlag::DestinationTooFar)) {
/* Not too far anymore, clear flag and message. */
ClrBit(v->flags, VAF_DEST_TOO_FAR);
v->flags.Reset(VehicleAirFlag::DestinationTooFar);
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
DeleteVehicleNews(v->index, AdviceType::AircraftDestinationTooFar);
}
@@ -2123,7 +2123,7 @@ static bool AircraftEventHandler(Aircraft *v, int loop)
}
}
if (!HasBit(v->flags, VAF_DEST_TOO_FAR)) AirportGoToNextPosition(v);
if (!v->flags.Test(VehicleAirFlag::DestinationTooFar)) AirportGoToNextPosition(v);
return true;
}

View File

@@ -11,6 +11,7 @@
#define DISASTER_VEHICLE_H
#include "vehicle_base.h"
#include "aircraft.h"
/** Different sub types of disaster vehicles. */
enum DisasterSubType : uint8_t {
@@ -37,7 +38,7 @@ enum DisasterSubType : uint8_t {
struct DisasterVehicle final : public SpecializedVehicle<DisasterVehicle, VEH_DISASTER> {
SpriteID image_override{}; ///< Override for the default disaster vehicle sprite.
VehicleID big_ufo_destroyer_target = VehicleID::Invalid(); ///< The big UFO that this destroyer is supposed to bomb.
uint8_t flags = 0; ///< Flags about the state of the vehicle, @see AirVehicleFlags
VehicleAirFlags flags{}; ///< Flags about the state of the vehicle, @see VehicleAirFlags
uint16_t state = 0; ///< Action stage of the disaster vehicle.
/** For use by saveload. */

View File

@@ -598,7 +598,7 @@ CommandCost CmdStartStopVehicle(DoCommandFlags flags, VehicleID veh_id, bool eva
Aircraft *a = Aircraft::From(v);
/* cannot stop airplane when in flight, or when taking off / landing */
if (a->state >= STARTTAKEOFF && a->state < TERM7) return CommandCost(STR_ERROR_AIRCRAFT_IS_IN_FLIGHT);
if (HasBit(a->flags, VAF_HELI_DIRECT_DESCENT)) return CommandCost(STR_ERROR_AIRCRAFT_IS_IN_FLIGHT);
if (a->flags.Test(VehicleAirFlag::HelicopterDirectDescent)) return CommandCost(STR_ERROR_AIRCRAFT_IS_IN_FLIGHT);
break;
}

View File

@@ -3145,7 +3145,7 @@ public:
if (v->type == VEH_TRAIN && Train::From(v)->flags.Test(VehicleRailFlag::Stuck) && !v->current_order.IsType(OT_LOADING)) return GetString(STR_VEHICLE_STATUS_TRAIN_STUCK);
if (v->type == VEH_AIRCRAFT && HasBit(Aircraft::From(v)->flags, VAF_DEST_TOO_FAR) && !v->current_order.IsType(OT_LOADING)) return GetString(STR_VEHICLE_STATUS_AIRCRAFT_TOO_FAR);
if (v->type == VEH_AIRCRAFT && Aircraft::From(v)->flags.Test(VehicleAirFlag::DestinationTooFar) && !v->current_order.IsType(OT_LOADING)) return GetString(STR_VEHICLE_STATUS_AIRCRAFT_TOO_FAR);
/* Vehicle is in a "normal" state, show current order. */
if (mouse_over_start_stop) {