diff --git a/src/aircraft.h b/src/aircraft.h index 47a29ad748..d3b9336f1f 100644 --- a/src/aircraft.h +++ b/src/aircraft.h @@ -101,7 +101,7 @@ struct Aircraft final : public SpecializedVehicle { bool IsInDepot() const override { assert(this->IsPrimaryVehicle()); - return (this->vehstatus & VS_HIDDEN) != 0 && IsHangarTile(this->tile); + return this->vehstatus.Test(VehState::Hidden) && IsHangarTile(this->tile); } bool Tick() override; diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 91027c96bc..6169c97fd9 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -299,8 +299,8 @@ CommandCost CmdBuildAircraft(DoCommandFlags flags, TileIndex tile, const Engine u->z_pos = GetSlopePixelZ(x, y); v->z_pos = u->z_pos + 1; - v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL; - u->vehstatus = VS_HIDDEN | VS_UNCLICKABLE | VS_SHADOW; + v->vehstatus = {VehState::Hidden, VehState::Stopped, VehState::DefaultPalette}; + u->vehstatus = {VehState::Hidden, VehState::Unclickable, VehState::Shadow}; v->spritenum = avi->image_index; @@ -378,7 +378,7 @@ CommandCost CmdBuildAircraft(DoCommandFlags flags, TileIndex tile, const Engine w->x_pos = v->x_pos; w->y_pos = v->y_pos; w->z_pos = v->z_pos + ROTOR_Z_OFFSET; - w->vehstatus = VS_HIDDEN | VS_UNCLICKABLE; + w->vehstatus = {VehState::Hidden, VehState::Unclickable}; w->spritenum = 0xFF; w->subtype = AIR_ROTOR; w->sprite_cache.sprite_seq.Set(SPR_ROTOR_STOPPED); @@ -482,11 +482,11 @@ static void HelicopterTickHandler(Aircraft *v) { Aircraft *u = v->Next()->Next(); - if (u->vehstatus & VS_HIDDEN) return; + if (u->vehstatus.Test(VehState::Hidden)) return; /* if true, helicopter rotors do not rotate. This should only be the case if a helicopter is * loading/unloading at a terminal or stopped */ - if (v->current_order.IsType(OT_LOADING) || (v->vehstatus & VS_STOPPED)) { + if (v->current_order.IsType(OT_LOADING) || v->vehstatus.Test(VehState::Stopped)) { if (u->cur_speed != 0) { u->cur_speed++; if (u->cur_speed >= 0x80 && u->state == HRS_ROTOR_MOVING_3) { @@ -576,10 +576,10 @@ void HandleAircraftEnterHangar(Aircraft *v) v->progress = 0; Aircraft *u = v->Next(); - u->vehstatus |= VS_HIDDEN; + u->vehstatus.Set(VehState::Hidden); u = u->Next(); if (u != nullptr) { - u->vehstatus |= VS_HIDDEN; + u->vehstatus.Set(VehState::Hidden); u->cur_speed = 0; } @@ -660,7 +660,7 @@ static int UpdateAircraftSpeed(Aircraft *v, uint speed_limit = SPEED_LIMIT_NONE, speed_limit *= _settings_game.vehicle.plane_speed; /* adjust speed for broken vehicles */ - if (v->vehstatus & VS_AIRCRAFT_BROKEN) { + if (v->vehstatus.Test(VehState::AircraftBroken)) { if (SPEED_LIMIT_BROKEN < speed_limit) hard_limit = false; speed_limit = std::min(speed_limit, SPEED_LIMIT_BROKEN); } @@ -1020,7 +1020,7 @@ static bool AircraftController(Aircraft *v) if (amd.flags.Test(AirportMovingDataFlag::Brake) && v->cur_speed > SPEED_LIMIT_TAXI * _settings_game.vehicle.plane_speed) { MaybeCrashAirplane(v); - if ((v->vehstatus & VS_CRASHED) != 0) return false; + if (v->vehstatus.Test(VehState::Crashed)) return false; } uint speed_limit = SPEED_LIMIT_TAXI; @@ -1247,11 +1247,11 @@ static void HandleAircraftSmoke(Aircraft *v, bool mode) { 0, 6 } }; - if (!(v->vehstatus & VS_AIRCRAFT_BROKEN)) return; + if (!v->vehstatus.Test(VehState::AircraftBroken)) return; /* Stop smoking when landed */ if (v->cur_speed < 10) { - v->vehstatus &= ~VS_AIRCRAFT_BROKEN; + v->vehstatus.Reset(VehState::AircraftBroken); v->breakdown_ctr = 0; return; } @@ -1468,15 +1468,15 @@ void AircraftLeaveHangar(Aircraft *v, Direction exit_dir) v->subspeed = 0; v->progress = 0; v->direction = exit_dir; - v->vehstatus &= ~VS_HIDDEN; + v->vehstatus.Reset(VehState::Hidden); { Vehicle *u = v->Next(); - u->vehstatus &= ~VS_HIDDEN; + u->vehstatus.Reset(VehState::Hidden); /* Rotor blades */ u = u->Next(); if (u != nullptr) { - u->vehstatus &= ~VS_HIDDEN; + u->vehstatus.Reset(VehState::Hidden); u->cur_speed = 80; } } @@ -1522,7 +1522,7 @@ static void AircraftEventHandler_InHangar(Aircraft *v, const AirportFTAClass *ap } /* if we were sent to the depot, stay there */ - if (v->current_order.IsType(OT_GOTO_DEPOT) && (v->vehstatus & VS_STOPPED)) { + if (v->current_order.IsType(OT_GOTO_DEPOT) && v->vehstatus.Test(VehState::Stopped)) { v->current_order.Free(); return; } @@ -2077,11 +2077,11 @@ static void AircraftHandleDestTooFar(Aircraft *v, bool too_far) static bool AircraftEventHandler(Aircraft *v, int loop) { - if (v->vehstatus & VS_CRASHED) { + if (v->vehstatus.Test(VehState::Crashed)) { return HandleCrashedAircraft(v); } - if (v->vehstatus & VS_STOPPED) return true; + if (v->vehstatus.Test(VehState::Stopped)) return true; v->HandleBreakdown(); @@ -2119,7 +2119,7 @@ bool Aircraft::Tick() this->tick_counter++; - if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++; + if (!this->vehstatus.Test(VehState::Stopped)) this->running_ticks++; if (this->subtype == AIR_HELICOPTER) HelicopterTickHandler(this); diff --git a/src/aircraft_gui.cpp b/src/aircraft_gui.cpp index 991186b7ca..1ba0a311d5 100644 --- a/src/aircraft_gui.cpp +++ b/src/aircraft_gui.cpp @@ -87,8 +87,8 @@ void DrawAircraftImage(const Vehicle *v, const Rect &r, VehicleID selection, Eng int heli_offs = 0; - PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v); - seq.Draw(x, y, pal, (v->vehstatus & VS_CRASHED) != 0); + PaletteID pal = v->vehstatus.Test(VehState::Crashed) ? PALETTE_CRASH : GetVehiclePalette(v); + seq.Draw(x, y, pal, v->vehstatus.Test(VehState::Crashed)); /* Aircraft can store cargo in their shadow, show this if present. */ const Vehicle *u = v->Next(); diff --git a/src/articulated_vehicles.cpp b/src/articulated_vehicles.cpp index c26e03ed51..1f547b2615 100644 --- a/src/articulated_vehicles.cpp +++ b/src/articulated_vehicles.cpp @@ -420,7 +420,8 @@ void AddArticulatedParts(Vehicle *first) v->date_of_last_service = first->date_of_last_service; v->date_of_last_service_newgrf = first->date_of_last_service_newgrf; v->build_year = first->build_year; - v->vehstatus = first->vehstatus & ~VS_STOPPED; + v->vehstatus = first->vehstatus; + v->vehstatus.Reset(VehState::Stopped); v->cargo_subtype = 0; v->max_age = CalendarTime::MIN_DATE; diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index e1060fcd1e..b51ce3519e 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -423,7 +423,7 @@ static CommandCost CopyHeadSpecificThings(Vehicle *old_head, Vehicle *new_head, /* Perform start/stop check whether the new vehicle suits newgrf restrictions etc. */ if (cost.Succeeded()) { /* Start the vehicle, might be denied by certain things */ - assert((new_head->vehstatus & VS_STOPPED) != 0); + assert(new_head->vehstatus.Test(VehState::Stopped)); cost.AddCost(DoCmdStartStopVehicle(new_head, true)); /* Stop the vehicle again, but do not care about evil newgrfs allowing starting but not stopping :p */ @@ -741,7 +741,7 @@ CommandCost CmdAutoreplaceVehicle(DoCommandFlags flags, VehicleID veh_id) CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; - if (v->vehstatus & VS_CRASHED) return CMD_ERROR; + if (v->vehstatus.Test(VehState::Crashed)) return CMD_ERROR; bool free_wagon = false; if (v->type == VEH_TRAIN) { @@ -775,7 +775,7 @@ CommandCost CmdAutoreplaceVehicle(DoCommandFlags flags, VehicleID veh_id) bool nothing_to_do = true; if (any_replacements) { - bool was_stopped = free_wagon || ((v->vehstatus & VS_STOPPED) != 0); + bool was_stopped = free_wagon || v->vehstatus.Test(VehState::Stopped); /* Stop the vehicle */ if (!was_stopped) cost.AddCost(DoCmdStartStopVehicle(v, true)); diff --git a/src/cachecheck.cpp b/src/cachecheck.cpp index d971bbb878..8f39f8d5ed 100644 --- a/src/cachecheck.cpp +++ b/src/cachecheck.cpp @@ -85,7 +85,7 @@ void CheckCaches() std::vector tra_cache; for (Vehicle *v : Vehicle::Iterate()) { - if (v != v->First() || v->vehstatus & VS_CRASHED || !v->IsPrimaryVehicle()) continue; + if (v != v->First() || v->vehstatus.Test(VehState::Crashed) || !v->IsPrimaryVehicle()) continue; for (const Vehicle *u = v; u != nullptr; u = u->Next()) { FillNewGRFVehicleCache(u); diff --git a/src/core/bitmath_func.hpp b/src/core/bitmath_func.hpp index ed4461e2c1..01822301e7 100644 --- a/src/core/bitmath_func.hpp +++ b/src/core/bitmath_func.hpp @@ -123,18 +123,6 @@ constexpr T SetBit(T &x, const uint8_t y) return x = (T)(x | ((T)1U << y)); } -/** - * Sets several bits in a variable. - * - * This macro sets several bits in a variable. The bits to set are provided - * by a value. The new value is also returned. - * - * @param x The variable to set some bits - * @param y The value with set bits for setting them in the variable - * @return The new value of x - */ -#define SETBITS(x, y) ((x) |= (y)) - /** * Clears a bit in a variable. * diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 28ccf035db..86083c9581 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -356,7 +356,7 @@ struct DepotWindow : Window { DrawString(text, STR_DEPOT_NO_ENGINE); } else { Rect flag = r.WithWidth(this->flag_size.width, rtl).WithHeight(this->flag_size.height).Translate(0, diff_y); - DrawSpriteIgnorePadding((v->vehstatus & VS_STOPPED) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, flag, SA_CENTER); + DrawSpriteIgnorePadding((v->vehstatus.Test(VehState::Stopped)) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, flag, SA_CENTER); DrawString(text, GetString(STR_JUST_COMMA, v->unitnumber), (v->max_age - CalendarTime::DAYS_IN_LEAP_YEAR) >= v->age ? TC_BLACK : TC_RED); } diff --git a/src/disaster_vehicle.cpp b/src/disaster_vehicle.cpp index c8506c3672..acced3ef5a 100644 --- a/src/disaster_vehicle.cpp +++ b/src/disaster_vehicle.cpp @@ -127,7 +127,7 @@ void DisasterVehicle::UpdateImage() DisasterVehicle::DisasterVehicle(int x, int y, Direction direction, DisasterSubType subtype, VehicleID big_ufo_destroyer_target) : SpecializedVehicleBase(), big_ufo_destroyer_target(big_ufo_destroyer_target) { - this->vehstatus = VS_UNCLICKABLE; + this->vehstatus = VehState::Unclickable; this->x_pos = x; this->y_pos = y; @@ -158,7 +158,7 @@ DisasterVehicle::DisasterVehicle(int x, int y, Direction direction, DisasterSubT case ST_BIG_UFO_SHADOW: case ST_BIG_UFO_DESTROYER_SHADOW: this->z_pos = 0; - this->vehstatus |= VS_SHADOW; + this->vehstatus.Set(VehState::Shadow); break; } @@ -368,7 +368,7 @@ static bool DisasterTick_Ufo(DisasterVehicle *v) uint dist = Delta(v->x_pos, u->x_pos) + Delta(v->y_pos, u->y_pos); - if (dist < TILE_SIZE && !(u->vehstatus & VS_HIDDEN) && u->breakdown_ctr == 0) { + if (dist < TILE_SIZE && !u->vehstatus.Test(VehState::Hidden) && u->breakdown_ctr == 0) { u->breakdown_ctr = 3; u->breakdown_delay = 140; } @@ -380,7 +380,7 @@ static bool DisasterTick_Ufo(DisasterVehicle *v) if (dist <= TILE_SIZE && z > u->z_pos) z--; v->UpdatePosition(gp.x, gp.y, z); - if (z <= u->z_pos && (u->vehstatus & VS_HIDDEN) == 0) { + if (z <= u->z_pos && !u->vehstatus.Test(VehState::Hidden)) { v->age++; if (u->crashed_ctr == 0) { uint victims = u->Crash(); @@ -588,7 +588,7 @@ static bool DisasterTick_Big_Ufo(DisasterVehicle *v) return t->IsFrontEngine() // Only the engines && Company::IsHumanID(t->owner) // Don't break AIs && IsPlainRailTile(t->tile) // No tunnels - && (t->vehstatus & VS_CRASHED) == 0; // Not crashed + && !t->vehstatus.Test(VehState::Crashed); // Not crashed }; uint n = 0; // Total number of targetable trains. diff --git a/src/economy.cpp b/src/economy.cpp index 88482c87ae..fd07c921e2 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -1941,7 +1941,7 @@ void LoadUnloadStation(Station *st) /* Check if anything will be loaded at all. Otherwise we don't need to reserve either. */ for (Vehicle *v : st->loading_vehicles) { - if ((v->vehstatus & (VS_STOPPED | VS_CRASHED))) continue; + if (v->vehstatus.Any({VehState::Stopped, VehState::Crashed})) continue; assert(v->load_unload_ticks != 0); if (--v->load_unload_ticks == 0) last_loading = v; @@ -1957,7 +1957,7 @@ void LoadUnloadStation(Station *st) if (last_loading == nullptr) return; for (Vehicle *v : st->loading_vehicles) { - if (!(v->vehstatus & (VS_STOPPED | VS_CRASHED))) LoadUnloadVehicle(v); + if (!v->vehstatus.Any({VehState::Stopped, VehState::Crashed})) LoadUnloadVehicle(v); if (v == last_loading) break; } diff --git a/src/effectvehicle.cpp b/src/effectvehicle.cpp index 3174581a16..c98d7a8a17 100644 --- a/src/effectvehicle.cpp +++ b/src/effectvehicle.cpp @@ -574,7 +574,7 @@ EffectVehicle *CreateEffectVehicle(int x, int y, int z, EffectVehicleType type) v->z_pos = z; v->tile = TileIndex{}; v->UpdateDeltaXY(); - v->vehstatus = VS_UNCLICKABLE; + v->vehstatus = VehState::Unclickable; _effect_procs[type].init_proc(v); diff --git a/src/ground_vehicle.cpp b/src/ground_vehicle.cpp index d57445203e..97e21bafe1 100644 --- a/src/ground_vehicle.cpp +++ b/src/ground_vehicle.cpp @@ -60,7 +60,7 @@ void GroundVehicle::PowerChanged() max_te /= 256; // Tractive effort is a [0-255] coefficient. if (this->gcache.cached_power != total_power || this->gcache.cached_max_te != max_te) { /* Stop the vehicle if it has no power. */ - if (total_power == 0) this->vehstatus |= VS_STOPPED; + if (total_power == 0) this->vehstatus.Set(VehState::Stopped); this->gcache.cached_power = total_power; this->gcache.cached_max_te = max_te; diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index 4d36769173..bbc7c21435 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -639,7 +639,7 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec * zz - Signed difference of z position between the selected and this vehicle. * yy - Signed difference of y position between the selected and this vehicle. * xx - Signed difference of x position between the selected and this vehicle. - * F - Flags, bit 7 corresponds to VS_HIDDEN. + * F - Flags, bit 7 corresponds to VehState::Hidden. * D - Dir difference, like in 0x45. */ if (!v->IsGroundVehicle()) return 0; @@ -652,7 +652,7 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec uint32_t ret = prev ? DirDifference(u->direction, v->direction) : DirDifference(v->direction, u->direction); if (ret > DIRDIFF_REVERSE) ret |= 0x08; - if (u->vehstatus & VS_HIDDEN) ret |= 0x80; + if (u->vehstatus.Test(VehState::Hidden)) ret |= 0x80; /* Get position difference. */ ret |= ((prev ? u->x_pos - v->x_pos : v->x_pos - u->x_pos) & 0xFF) << 8; @@ -815,7 +815,7 @@ static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *objec case 0x2F: break; // not implemented case 0x30: break; // not implemented case 0x31: break; // not implemented - case 0x32: return v->vehstatus; + case 0x32: return v->vehstatus.base(); case 0x33: return 0; // non-existent high byte of vehstatus case 0x34: return v->type == VEH_AIRCRAFT ? (v->cur_speed * 10) / 128 : v->cur_speed; case 0x35: return GB(v->type == VEH_AIRCRAFT ? (v->cur_speed * 10) / 128 : v->cur_speed, 8, 8); diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 32a33e4c4b..6ad26ed1a3 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -1699,10 +1699,10 @@ void CheckOrders(const Vehicle *v) if (_settings_client.gui.order_review_system == 0) return; /* Do nothing for crashed vehicles */ - if (v->vehstatus & VS_CRASHED) return; + if (v->vehstatus.Test(VehState::Crashed)) return; /* Do nothing for stopped vehicles if setting is '1' */ - if (_settings_client.gui.order_review_system == 1 && (v->vehstatus & VS_STOPPED)) return; + if (_settings_client.gui.order_review_system == 1 && v->vehstatus.Test(VehState::Stopped)) return; /* do nothing we we're not the first vehicle in a share-chain */ if (v->FirstShared() != v) return; diff --git a/src/pathfinder/yapf/yapf_ship.cpp b/src/pathfinder/yapf/yapf_ship.cpp index f3a953097a..4552c0141b 100644 --- a/src/pathfinder/yapf/yapf_ship.cpp +++ b/src/pathfinder/yapf/yapf_ship.cpp @@ -359,7 +359,7 @@ public: { uint *count = (uint*)data; /* Ignore other vehicles (aircraft) and ships inside depot. */ - if (v->type == VEH_SHIP && (v->vehstatus & VS_HIDDEN) == 0) (*count)++; + if (v->type == VEH_SHIP && !v->vehstatus.Test(VehState::Hidden)) (*count)++; return nullptr; } diff --git a/src/pbs.cpp b/src/pbs.cpp index 6c68c15a1e..9e37633a04 100644 --- a/src/pbs.cpp +++ b/src/pbs.cpp @@ -264,7 +264,7 @@ static Vehicle *FindTrainOnTrackEnum(Vehicle *v, void *data) { FindTrainOnTrackInfo *info = (FindTrainOnTrackInfo *)data; - if (v->type != VEH_TRAIN || (v->vehstatus & VS_CRASHED)) return nullptr; + if (v->type != VEH_TRAIN || v->vehstatus.Test(VehState::Crashed)) return nullptr; Train *t = Train::From(v); if (t->track == TRACK_BIT_WORMHOLE || HasBit((TrackBits)t->track, TrackdirToTrack(info->res.trackdir))) { diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index f118ad7a58..621aa6bd1c 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -1185,7 +1185,7 @@ CommandCost CmdBuildSingleSignal(DoCommandFlags flags, TileIndex tile, Track tra YapfNotifyTrackLayoutChange(tile, track); if (v != nullptr && v->track != TRACK_BIT_DEPOT) { /* Extend the train's path if it's not stopped or loading, or not at a safe position. */ - if (!(((v->vehstatus & VS_STOPPED) && v->cur_speed == 0) || v->current_order.IsType(OT_LOADING)) || + if (!((v->vehstatus.Test(VehState::Stopped) && v->cur_speed == 0) || v->current_order.IsType(OT_LOADING)) || !IsSafeWaitingPosition(v, v->tile, v->GetVehicleTrackdir(), true, _settings_game.pf.forbid_90_deg)) { TryPathReserve(v, true); } @@ -2962,7 +2962,7 @@ static VehicleEnterTileStatus VehicleEnter_Track(Vehicle *u, TileIndex tile, int if (fract_coord_leave == fract_coord) { /* Leave the depot. */ if ((v = v->Next()) != nullptr) { - v->vehstatus &= ~VS_HIDDEN; + v->vehstatus.Reset(VehState::Hidden); v->track = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y); } } @@ -2970,7 +2970,7 @@ static VehicleEnterTileStatus VehicleEnter_Track(Vehicle *u, TileIndex tile, int /* Entering depot. */ assert(DiagDirToDir(ReverseDiagDir(dir)) == v->direction); v->track = TRACK_BIT_DEPOT, - v->vehstatus |= VS_HIDDEN; + v->vehstatus.Set(VehState::Hidden); v->direction = ReverseDir(v->direction); if (v->Next() == nullptr) VehicleEnterDepot(v->First()); v->tile = tile; diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 5c0e0e23cf..73dd252cb6 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -2265,7 +2265,7 @@ static VehicleEnterTileStatus VehicleEnter_Road(Vehicle *v, TileIndex tile, int, if (rv->frame == RVC_DEPOT_STOP_FRAME && _roadveh_enter_depot_dir[GetRoadDepotDirection(tile)] == rv->state) { rv->state = RVSB_IN_DEPOT; - rv->vehstatus |= VS_HIDDEN; + rv->vehstatus.Set(VehState::Hidden); rv->direction = ReverseDir(rv->direction); if (rv->Next() == nullptr) VehicleEnterDepot(rv->First()); rv->tile = tile; diff --git a/src/roadstop.cpp b/src/roadstop.cpp index 7fa254ccfa..4c68e2688f 100644 --- a/src/roadstop.cpp +++ b/src/roadstop.cpp @@ -327,7 +327,7 @@ Vehicle *FindVehiclesInRoadStop(Vehicle *v, void *data) { RoadStopEntryRebuilderHelper *rserh = (RoadStopEntryRebuilderHelper*)data; /* Not a RV or not in the right direction or crashed :( */ - if (v->type != VEH_ROAD || DirToDiagDir(v->direction) != rserh->dir || !v->IsPrimaryVehicle() || (v->vehstatus & VS_CRASHED) != 0) return nullptr; + if (v->type != VEH_ROAD || DirToDiagDir(v->direction) != rserh->dir || !v->IsPrimaryVehicle() || v->vehstatus.Test(VehState::Crashed)) return nullptr; RoadVehicle *rv = RoadVehicle::From(v); /* Don't add ones not in a road stop */ diff --git a/src/roadveh.h b/src/roadveh.h index b0dbaba42c..56aae919c4 100644 --- a/src/roadveh.h +++ b/src/roadveh.h @@ -222,7 +222,7 @@ protected: // These functions should not be called outside acceleration code. */ inline AccelStatus GetAccelerationStatus() const { - return (this->vehstatus & VS_STOPPED) ? AS_BRAKE : AS_ACCEL; + return this->vehstatus.Test(VehState::Stopped) ? AS_BRAKE : AS_ACCEL; } /** diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 91eec46aa3..fcc5cbdae4 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -281,7 +281,7 @@ CommandCost CmdBuildRoadVehicle(DoCommandFlags flags, TileIndex tile, const Engi v->z_pos = GetSlopePixelZ(x, y, true); v->state = RVSB_IN_DEPOT; - v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL; + v->vehstatus = {VehState::Hidden, VehState::Stopped, VehState::DefaultPalette}; v->spritenum = rvi->image_index; v->cargo_type = e->GetDefaultCargoType(); @@ -368,8 +368,7 @@ CommandCost CmdTurnRoadVeh(DoCommandFlags flags, VehicleID veh_id) CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; - if ((v->vehstatus & VS_STOPPED) || - (v->vehstatus & VS_CRASHED) || + if (v->vehstatus.Any({VehState::Stopped, VehState::Crashed}) || v->breakdown_ctr != 0 || v->overtaking != 0 || v->state == RVSB_WORMHOLE || @@ -449,7 +448,7 @@ inline int RoadVehicle::GetCurrentMaxSpeed() const } /* Vehicle is on the middle part of a bridge. */ - if (u->state == RVSB_WORMHOLE && !(u->vehstatus & VS_HIDDEN)) { + if (u->state == RVSB_WORMHOLE && !u->vehstatus.Test(VehState::Hidden)) { max_speed = std::min(max_speed, GetBridgeSpec(GetBridgeType(u->tile))->speed * 2); } } @@ -818,7 +817,7 @@ static void RoadVehCheckOvertake(RoadVehicle *v, RoadVehicle *u) * Original acceleration always accelerates, so always use the maximum speed. */ int u_speed = (_settings_game.vehicle.roadveh_acceleration_model == AM_ORIGINAL || u->GetAcceleration() > 0) ? u->GetCurrentMaxSpeed() : u->cur_speed; if (u_speed >= v->GetCurrentMaxSpeed() && - !(u->vehstatus & VS_STOPPED) && + !u->vehstatus.Test(VehState::Stopped) && u->cur_speed != 0) { return; } @@ -839,7 +838,7 @@ static void RoadVehCheckOvertake(RoadVehicle *v, RoadVehicle *u) /* When the vehicle in front of us is stopped we may only take * half the time to pass it than when the vehicle is moving. */ - v->overtaking_ctr = (od.u->cur_speed == 0 || (od.u->vehstatus & VS_STOPPED)) ? RV_OVERTAKE_TIMEOUT / 2 : 0; + v->overtaking_ctr = (od.u->cur_speed == 0 || od.u->vehstatus.Test(VehState::Stopped)) ? RV_OVERTAKE_TIMEOUT / 2 : 0; v->overtaking = RVSB_DRIVE_SIDE; } @@ -1028,7 +1027,7 @@ bool RoadVehLeaveDepot(RoadVehicle *v, bool first) v->cur_speed = 0; } - v->vehstatus &= ~VS_HIDDEN; + v->vehstatus.Reset(VehState::Hidden); v->state = tdir; v->frame = RVC_DEPOT_START_FRAME; @@ -1172,7 +1171,7 @@ bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev) v->x_pos = gp.x; v->y_pos = gp.y; v->UpdatePosition(); - if ((v->vehstatus & VS_HIDDEN) == 0) v->Vehicle::UpdateViewport(true); + if (!v->vehstatus.Test(VehState::Hidden)) v->Vehicle::UpdateViewport(true); return true; } @@ -1560,13 +1559,13 @@ static bool RoadVehController(RoadVehicle *v) if (v->reverse_ctr != 0) v->reverse_ctr--; /* handle crashed */ - if (v->vehstatus & VS_CRASHED || RoadVehCheckTrainCrash(v)) { + if (v->vehstatus.Test(VehState::Crashed) || RoadVehCheckTrainCrash(v)) { return RoadVehIsCrashed(v); } /* road vehicle has broken down? */ if (v->HandleBreakdown()) return true; - if (v->vehstatus & VS_STOPPED) { + if (v->vehstatus.Test(VehState::Stopped)) { v->SetLastSpeed(); return true; } @@ -1611,7 +1610,7 @@ static bool RoadVehController(RoadVehicle *v) v->SetLastSpeed(); for (RoadVehicle *u = v; u != nullptr; u = u->Next()) { - if ((u->vehstatus & VS_HIDDEN) != 0) continue; + if (u->vehstatus.Test(VehState::Hidden)) continue; u->UpdateViewport(false, false); } @@ -1642,7 +1641,7 @@ bool RoadVehicle::Tick() this->tick_counter++; if (this->IsFrontEngine()) { - if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++; + if (!this->vehstatus.Test(VehState::Stopped)) this->running_ticks++; return RoadVehController(this); } @@ -1729,7 +1728,7 @@ void RoadVehicle::OnNewEconomyDay() Trackdir RoadVehicle::GetVehicleTrackdir() const { - if (this->vehstatus & VS_CRASHED) return INVALID_TRACKDIR; + if (this->vehstatus.Test(VehState::Crashed)) return INVALID_TRACKDIR; if (this->IsInDepot()) { /* We'll assume the road vehicle is facing outwards */ diff --git a/src/roadveh_gui.cpp b/src/roadveh_gui.cpp index c462a44e04..4a98d58dfa 100644 --- a/src/roadveh_gui.cpp +++ b/src/roadveh_gui.cpp @@ -134,10 +134,10 @@ void DrawRoadVehImage(const Vehicle *v, const Rect &r, VehicleID selection, Engi int width = u->GetDisplayImageWidth(&offset); if (rtl ? px + width > 0 : px - width < max_width) { - PaletteID pal = (u->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(u); + PaletteID pal = u->vehstatus.Test(VehState::Crashed) ? PALETTE_CRASH : GetVehiclePalette(u); VehicleSpriteSeq seq; u->GetImage(dir, image_type, &seq); - seq.Draw(px + (rtl ? -offset.x : offset.x), y + offset.y, pal, (u->vehstatus & VS_CRASHED) != 0); + seq.Draw(px + (rtl ? -offset.x : offset.x), y + offset.y, pal, u->vehstatus.Test(VehState::Crashed)); } if (do_overlays) AddCargoIconOverlay(overlays, px, width, u); diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 14d2ecb76d..1ed166d1e6 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -1421,8 +1421,10 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_25)) { + /* Remove obsolete VS_WAIT_FOR_SLOT state from road vehicles. */ + static constexpr VehStates OLD_VS_WAIT_FOR_SLOT{0x40}; for (RoadVehicle *rv : RoadVehicle::Iterate()) { - rv->vehstatus &= ~0x40; + rv->vehstatus.Reset(OLD_VS_WAIT_FOR_SLOT); } } @@ -1646,7 +1648,7 @@ bool AfterLoadGame() /* Added a FIFO queue of vehicles loading at stations */ for (Vehicle *v : Vehicle::Iterate()) { if ((v->type != VEH_TRAIN || Train::From(v)->IsFrontEngine()) && // for all locs - !(v->vehstatus & (VS_STOPPED | VS_CRASHED)) && // not stopped or crashed + !v->vehstatus.Any({VehState::Stopped, VehState::Crashed}) && // not stopped or crashed v->current_order.IsType(OT_LOADING)) { // loading Station::Get(v->last_station_visited)->loading_vehicles.push_back(v); @@ -2506,7 +2508,7 @@ bool AfterLoadGame() UpdateAircraftCache(v); AircraftNextAirportPos_and_Order(v); /* get aircraft back on running altitude */ - if ((v->vehstatus & VS_CRASHED) == 0) { + if (!v->vehstatus.Test(VehState::Crashed)) { GetAircraftFlightLevelBounds(v, &v->z_pos, nullptr); SetAircraftPosition(v, v->x_pos, v->y_pos, GetAircraftFlightLevel(v)); } @@ -2624,7 +2626,7 @@ bool AfterLoadGame() } if (hidden) { - v->vehstatus |= VS_HIDDEN; + v->vehstatus.Set(VehState::Hidden); switch (v->type) { case VEH_TRAIN: Train::From(v)->track = TRACK_BIT_WORMHOLE; break; @@ -2632,7 +2634,7 @@ bool AfterLoadGame() default: NOT_REACHED(); } } else { - v->vehstatus &= ~VS_HIDDEN; + v->vehstatus.Reset(VehState::Hidden); switch (v->type) { case VEH_TRAIN: Train::From(v)->track = DiagDirToDiagTrackBits(vdir); break; @@ -2709,7 +2711,7 @@ bool AfterLoadGame() ClrBit(t->gv_flags, GVF_GOINGDOWN_BIT); /* Crashed vehicles can't be going up/down. */ - if (t->vehstatus & VS_CRASHED) break; + if (t->vehstatus.Test(VehState::Crashed)) break; /* Only X/Y tracks can be sloped. */ if (t->track != TRACK_BIT_X && t->track != TRACK_BIT_Y) break; @@ -2723,7 +2725,7 @@ bool AfterLoadGame() ClrBit(rv->gv_flags, GVF_GOINGDOWN_BIT); /* Crashed vehicles can't be going up/down. */ - if (rv->vehstatus & VS_CRASHED) break; + if (rv->vehstatus.Test(VehState::Crashed)) break; if (rv->state == RVSB_IN_DEPOT || rv->state == RVSB_WORMHOLE) break; @@ -2760,7 +2762,7 @@ bool AfterLoadGame() * by loading and saving the game in a new version. */ v->z_pos = GetSlopePixelZ(v->x_pos, v->y_pos, true); DiagDirection dir = GetTunnelBridgeDirection(v->tile); - if (v->type == VEH_TRAIN && !(v->vehstatus & VS_CRASHED) && + if (v->type == VEH_TRAIN && !v->vehstatus.Test(VehState::Crashed) && v->direction != DiagDirToDir(dir)) { /* If the train has left the bridge, it shouldn't have * track == TRACK_BIT_WORMHOLE - this could happen @@ -3250,7 +3252,7 @@ bool AfterLoadGame() if (rv->cur_speed > 0) continue; /* Ignore crashed vehicles. */ - if (rv->vehstatus & VS_CRASHED) continue; + if (rv->vehstatus.Test(VehState::Crashed)) continue; /* Ignore vehicles not on level crossings. */ TileIndex cur_tile = rv->tile; @@ -3269,7 +3271,7 @@ bool AfterLoadGame() u->y_pos = y; u->z_pos = GetSlopePixelZ(x, y, true); - u->vehstatus |= VS_HIDDEN; + u->vehstatus.Set(VehState::Hidden); u->state = RVSB_IN_DEPOT; u->UpdatePosition(); } diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 919b4c9631..c98f8df68a 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -174,13 +174,13 @@ void UpdateOldAircraft() * skip those */ if (a->IsNormalAircraft()) { /* airplane in terminal stopped doesn't hurt anyone, so goto next */ - if ((a->vehstatus & VS_STOPPED) && a->state == 0) { + if (a->vehstatus.Test(VehState::Stopped) && a->state == 0) { a->state = HANGAR; continue; } AircraftLeaveHangar(a, a->direction); // make airplane visible if it was in a depot for example - a->vehstatus &= ~VS_STOPPED; // make airplane moving + a->vehstatus.Reset(VehState::Stopped); // make airplane moving UpdateAircraftCache(a); a->cur_speed = a->vcache.cached_max_speed; // so aircraft don't have zero speed while in air if (!a->current_order.IsType(OT_GOTO_STATION) && !a->current_order.IsType(OT_GOTO_DEPOT)) { @@ -465,7 +465,7 @@ void AfterLoadVehiclesPhase2(bool part_of_load) if (v->type == VEH_TRAIN) { Train *t = Train::From(v); if (!t->IsFrontEngine()) { - if (t->IsEngine()) t->vehstatus |= VS_STOPPED; + if (t->IsEngine()) t->vehstatus.Set(VehState::Stopped); /* cur_speed is now relevant for non-front parts - nonzero breaks * moving-wagons-inside-depot- and autoreplace- code */ t->cur_speed = 0; @@ -473,7 +473,7 @@ void AfterLoadVehiclesPhase2(bool part_of_load) } /* trains weren't stopping gradually in old OTTD versions (and TTO/TTD) * other vehicle types didn't have zero speed while stopped (even in 'recent' OTTD versions) */ - if ((v->vehstatus & VS_STOPPED) && (v->type != VEH_TRAIN || IsSavegameVersionBefore(SLV_2, 1))) { + if (v->vehstatus.Test(VehState::Stopped) && (v->type != VEH_TRAIN || IsSavegameVersionBefore(SLV_2, 1))) { v->cur_speed = 0; } } @@ -556,7 +556,7 @@ void FixupTrainLengths() * so we need to move all vehicles forward to cover the difference to the * old center, otherwise wagon spacing in trains would be broken upon load. */ for (Train *u = Train::From(v); u != nullptr; u = u->Next()) { - if (u->track == TRACK_BIT_DEPOT || (u->vehstatus & VS_CRASHED)) continue; + if (u->track == TRACK_BIT_DEPOT || u->vehstatus.Test(VehState::Crashed)) continue; Train *next = u->Next(); @@ -617,7 +617,7 @@ void FixupTrainLengths() int d = TicksToLeaveDepot(u); if (d <= 0) { /* Next vehicle should have left the depot already, show it and pull forward. */ - next->vehstatus &= ~VS_HIDDEN; + next->vehstatus.Reset(VehState::Hidden); next->track = TrackToTrackBits(GetRailDepotTrack(next->tile)); for (int i = 0; i >= d; i--) TrainController(next, nullptr); } diff --git a/src/script/api/script_vehicle.cpp b/src/script/api/script_vehicle.cpp index 10f5204393..efce579f62 100644 --- a/src/script/api/script_vehicle.cpp +++ b/src/script/api/script_vehicle.cpp @@ -344,7 +344,7 @@ if (!IsPrimaryVehicle(vehicle_id)) return -1; const ::Vehicle *v = ::Vehicle::Get(vehicle_id); - return (v->vehstatus & (::VS_STOPPED | ::VS_CRASHED)) == 0 ? v->GetDisplaySpeed() : 0; // km-ish/h + return !v->vehstatus.Any({::VehState::Stopped, ::VehState::Crashed}) ? v->GetDisplaySpeed() : 0; // km-ish/h } /* static */ ScriptVehicle::VehicleState ScriptVehicle::GetState(VehicleID vehicle_id) @@ -352,12 +352,12 @@ if (!IsValidVehicle(vehicle_id)) return ScriptVehicle::VS_INVALID; const Vehicle *v = ::Vehicle::Get(vehicle_id); - uint8_t vehstatus = v->vehstatus; + VehStates vehstatus = v->vehstatus; - if (vehstatus & ::VS_CRASHED) return ScriptVehicle::VS_CRASHED; + if (vehstatus.Test(::VehState::Crashed)) return ScriptVehicle::VS_CRASHED; if (v->breakdown_ctr != 0) return ScriptVehicle::VS_BROKEN; if (v->IsStoppedInDepot()) return ScriptVehicle::VS_IN_DEPOT; - if (vehstatus & ::VS_STOPPED) return ScriptVehicle::VS_STOPPED; + if (vehstatus.Test(::VehState::Stopped)) return ScriptVehicle::VS_STOPPED; if (v->current_order.IsType(OT_LOADING)) return ScriptVehicle::VS_AT_STATION; return ScriptVehicle::VS_RUNNING; } diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 04165b2000..68970d58b5 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -287,7 +287,7 @@ void Ship::OnNewEconomyDay() Trackdir Ship::GetVehicleTrackdir() const { - if (this->vehstatus & VS_CRASHED) return INVALID_TRACKDIR; + if (this->vehstatus.Test(VehState::Crashed)) return INVALID_TRACKDIR; if (this->IsInDepot()) { /* We'll assume the ship is facing outwards */ @@ -420,7 +420,7 @@ static bool CheckShipLeaveDepot(Ship *v) } v->state = AxisToTrackBits(axis); - v->vehstatus &= ~VS_HIDDEN; + v->vehstatus.Reset(VehState::Hidden); v->cur_speed = 0; v->UpdateViewport(true, true); @@ -702,7 +702,7 @@ static void ShipController(Ship *v) if (v->HandleBreakdown()) return; - if (v->vehstatus & VS_STOPPED) return; + if (v->vehstatus.Test(VehState::Stopped)) return; if (ProcessOrders(v) && CheckReverseShip(v)) return ReverseShip(v); @@ -847,7 +847,7 @@ static void ShipController(Ship *v) v->x_pos = gp.x; v->y_pos = gp.y; v->UpdatePosition(); - if ((v->vehstatus & VS_HIDDEN) == 0) v->Vehicle::UpdateViewport(true); + if (!v->vehstatus.Test(VehState::Hidden)) v->Vehicle::UpdateViewport(true); continue; } @@ -869,7 +869,7 @@ bool Ship::Tick() { PerformanceAccumulator framerate(PFE_GL_SHIPS); - if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++; + if (!this->vehstatus.Test(VehState::Stopped)) this->running_ticks++; ShipController(this); @@ -917,7 +917,7 @@ CommandCost CmdBuildShip(DoCommandFlags flags, TileIndex tile, const Engine *e, v->rotation = v->direction; v->UpdateDeltaXY(); - v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL; + v->vehstatus = {VehState::Hidden, VehState::Stopped, VehState::DefaultPalette}; v->spritenum = svi->image_index; v->cargo_type = e->GetDefaultCargoType(); diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index e87f9fddc5..c4453442ee 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -949,7 +949,7 @@ protected: { for (const Vehicle *v : Vehicle::Iterate()) { if (v->type == VEH_EFFECT) continue; - if (v->vehstatus & (VS_HIDDEN | VS_UNCLICKABLE)) continue; + if (v->vehstatus.Any({VehState::Hidden, VehState::Unclickable})) continue; /* Remap into flat coordinates. */ Point pt = this->RemapTile(v->x_pos / (int)TILE_SIZE, v->y_pos / (int)TILE_SIZE); diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index fb60798130..85b98217db 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -3728,7 +3728,7 @@ static VehicleEnterTileStatus VehicleEnter_Station(Vehicle *v, TileIndex tile, i if (x == stop) { return VETSB_ENTERED_STATION | static_cast(station_id.base() << VETS_STATION_ID_OFFSET); // enter station } else if (x < stop) { - v->vehstatus |= VS_TRAIN_SLOWING; + v->vehstatus.Set(VehState::TrainSlowing); uint16_t spd = std::max(0, (stop - x) * 20 - 15); if (spd < v->cur_speed) v->cur_speed = spd; } diff --git a/src/train.h b/src/train.h index 1693cf3534..33145df101 100644 --- a/src/train.h +++ b/src/train.h @@ -254,7 +254,7 @@ protected: // These functions should not be called outside acceleration code. inline uint8_t GetAirDragArea() const { /* Air drag is higher in tunnels due to the limited cross-section. */ - return (this->track == TRACK_BIT_WORMHOLE && this->vehstatus & VS_HIDDEN) ? 28 : 14; + return (this->track == TRACK_BIT_WORMHOLE && this->vehstatus.Test(VehState::Hidden)) ? 28 : 14; } /** @@ -272,7 +272,7 @@ protected: // These functions should not be called outside acceleration code. */ inline AccelStatus GetAccelerationStatus() const { - return (this->vehstatus & VS_STOPPED) || HasBit(this->flags, VRF_REVERSING) || HasBit(this->flags, VRF_TRAIN_STUCK) ? AS_BRAKE : AS_ACCEL; + return this->vehstatus.Test(VehState::Stopped) || HasBit(this->flags, VRF_REVERSING) || HasBit(this->flags, VRF_TRAIN_STUCK) ? AS_BRAKE : AS_ACCEL; } /** diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index a6b64967c2..665ba6ce95 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -78,7 +78,7 @@ void CheckTrainsLengths() bool first = true; for (const Train *v : Train::Iterate()) { - if (v->First() == v && !(v->vehstatus & VS_CRASHED)) { + if (v->First() == v && !v->vehstatus.Test(VehState::Crashed)) { for (const Train *u = v, *w = v->Next(); w != nullptr; u = w, w = w->Next()) { if (u->track != TRACK_BIT_DEPOT) { if ((w->track != TRACK_BIT_DEPOT && @@ -415,7 +415,7 @@ int Train::GetCurrentMaxSpeed() const } /* Vehicle is on the middle part of a bridge. */ - if (u->track == TRACK_BIT_WORMHOLE && !(u->vehstatus & VS_HIDDEN)) { + if (u->track == TRACK_BIT_WORMHOLE && !u->vehstatus.Test(VehState::Hidden)) { max_speed = std::min(max_speed, GetBridgeSpec(GetBridgeType(u->tile))->speed); } } @@ -639,7 +639,7 @@ static CommandCost CmdBuildRailWagon(DoCommandFlags flags, TileIndex tile, const v->z_pos = GetSlopePixelZ(x, y, true); v->owner = _current_company; v->track = TRACK_BIT_DEPOT; - v->vehstatus = VS_HIDDEN | VS_DEFPAL; + v->vehstatus = {VehState::Hidden, VehState::DefaultPalette}; v->SetWagon(); @@ -676,7 +676,7 @@ static CommandCost CmdBuildRailWagon(DoCommandFlags flags, TileIndex tile, const w->IsFreeWagon() && ///< A free wagon chain w->engine_type == e->index && ///< Same type w->First() != v && ///< Don't connect to ourself - !(w->vehstatus & VS_CRASHED)) { ///< Not crashed/flooded + !w->vehstatus.Test(VehState::Crashed)) { ///< Not crashed/flooded if (Command::Do(DoCommandFlag::Execute, v->index, w->Last()->index, true).Succeeded()) { break; } @@ -713,7 +713,8 @@ static void AddRearEngineToMultiheadedTrain(Train *v) u->y_pos = v->y_pos; u->z_pos = v->z_pos; u->track = TRACK_BIT_DEPOT; - u->vehstatus = v->vehstatus & ~VS_STOPPED; + u->vehstatus = v->vehstatus; + u->vehstatus.Reset(VehState::Stopped); u->spritenum = v->spritenum + 1; u->cargo_type = v->cargo_type; u->cargo_subtype = v->cargo_subtype; @@ -769,7 +770,7 @@ CommandCost CmdBuildRailVehicle(DoCommandFlags flags, TileIndex tile, const Engi v->y_pos = y; v->z_pos = GetSlopePixelZ(x, y, true); v->track = TRACK_BIT_DEPOT; - v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL; + v->vehstatus = {VehState::Hidden, VehState::Stopped, VehState::DefaultPalette}; v->spritenum = rvi->image_index; v->cargo_type = e->GetDefaultCargoType(); assert(IsValidCargoType(v->cargo_type)); @@ -826,7 +827,7 @@ static Train *FindGoodVehiclePos(const Train *src) TileIndex tile = src->tile; for (Train *dst : Train::Iterate()) { - if (dst->IsFreeWagon() && dst->tile == tile && !(dst->vehstatus & VS_CRASHED)) { + if (dst->IsFreeWagon() && dst->tile == tile && !dst->vehstatus.Test(VehState::Crashed)) { /* check so all vehicles in the line have the same engine. */ Train *t = dst; while (t->engine_type == eng) { @@ -1197,7 +1198,7 @@ CommandCost CmdMoveRailVehicle(DoCommandFlags flags, VehicleID src_veh, VehicleI if (ret.Failed()) return ret; /* Do not allow moving crashed vehicles inside the depot, it is likely to cause asserts later */ - if (src->vehstatus & VS_CRASHED) return CMD_ERROR; + if (src->vehstatus.Test(VehState::Crashed)) return CMD_ERROR; /* if nothing is selected as destination, try and find a matching vehicle to drag to. */ Train *dst; @@ -1211,7 +1212,7 @@ CommandCost CmdMoveRailVehicle(DoCommandFlags flags, VehicleID src_veh, VehicleI if (ret.Failed()) return ret; /* Do not allow appending to crashed vehicles, too */ - if (dst->vehstatus & VS_CRASHED) return CMD_ERROR; + if (dst->vehstatus.Test(VehState::Crashed)) return CMD_ERROR; } /* if an articulated part is being handled, deal with its parent vehicle */ @@ -1636,9 +1637,10 @@ void ReverseTrainSwapVeh(Train *v, int l, int r) if (a != b) { /* swap the hidden bits */ { - uint16_t tmp = (a->vehstatus & ~VS_HIDDEN) | (b->vehstatus & VS_HIDDEN); - b->vehstatus = (b->vehstatus & ~VS_HIDDEN) | (a->vehstatus & VS_HIDDEN); - a->vehstatus = tmp; + bool a_hidden = a->vehstatus.Test(VehState::Hidden); + bool b_hidden = b->vehstatus.Test(VehState::Hidden); + b->vehstatus.Set(VehState::Hidden, a_hidden); + a->vehstatus.Set(VehState::Hidden, b_hidden); } Swap(a->track, b->track); @@ -1694,7 +1696,7 @@ bool TrainOnCrossing(TileIndex tile) */ static Vehicle *TrainApproachingCrossingEnum(Vehicle *v, void *data) { - if (v->type != VEH_TRAIN || (v->vehstatus & VS_CRASHED)) return nullptr; + if (v->type != VEH_TRAIN || v->vehstatus.Test(VehState::Crashed)) return nullptr; Train *t = Train::From(v); if (!t->IsFrontEngine()) return nullptr; @@ -1912,7 +1914,7 @@ static void AdvanceWagonsAfterSwap(Train *v) int d = TicksToLeaveDepot(dep); if (d <= 0) { - leave->vehstatus &= ~VS_HIDDEN; // move it out of the depot + leave->vehstatus.Reset(VehState::Hidden); // move it out of the depot leave->track = TrackToTrackBits(GetRailDepotTrack(leave->tile)); for (int i = 0; i >= d; i--) TrainController(leave, nullptr); // maybe move it, and maybe let another wagon leave } @@ -2087,7 +2089,7 @@ CommandCost CmdReverseTrainDirection(DoCommandFlags flags, VehicleID veh_id, boo } else { /* turn the whole train around */ if (!v->IsPrimaryVehicle()) return CMD_ERROR; - if ((v->vehstatus & VS_CRASHED) || v->breakdown_ctr != 0) return CMD_ERROR; + if (v->vehstatus.Test(VehState::Crashed) || v->breakdown_ctr != 0) return CMD_ERROR; if (flags.Test(DoCommandFlag::Execute)) { /* Properly leave the station if we are loading and won't be loading anymore */ @@ -2163,7 +2165,7 @@ CommandCost CmdForceTrainProceed(DoCommandFlags flags, VehicleID veh_id) */ static FindDepotData FindClosestTrainDepot(Train *v, int max_distance) { - assert(!(v->vehstatus & VS_CRASHED)); + assert(!v->vehstatus.Test(VehState::Crashed)); return YapfTrainFindNearestDepot(v, max_distance); } @@ -2267,7 +2269,7 @@ static bool CheckTrainStayInDepot(Train *v) /* if the train got no power, then keep it in the depot */ if (v->gcache.cached_power == 0) { - v->vehstatus |= VS_STOPPED; + v->vehstatus.Set(VehState::Stopped); SetWindowDirty(WC_VEHICLE_DEPOT, v->tile); return true; } @@ -2322,7 +2324,7 @@ static bool CheckTrainStayInDepot(Train *v) v->track = TRACK_BIT_X; if (v->direction & 2) v->track = TRACK_BIT_Y; - v->vehstatus &= ~VS_HIDDEN; + v->vehstatus.Reset(VehState::Hidden); v->cur_speed = 0; v->UpdateViewport(true, true); @@ -3148,7 +3150,7 @@ static uint TrainCrashed(Train *v) uint victims = 0; /* do not crash train twice */ - if (!(v->vehstatus & VS_CRASHED)) { + if (!v->vehstatus.Test(VehState::Crashed)) { victims = v->Crash(); AI::NewEvent(v->owner, new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_TRAIN, victims)); Game::NewEvent(new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_TRAIN, victims)); @@ -3251,7 +3253,7 @@ static bool CheckTrainCollision(Train *v) static Vehicle *CheckTrainAtSignal(Vehicle *v, void *data) { - if (v->type != VEH_TRAIN || (v->vehstatus & VS_CRASHED)) return nullptr; + if (v->type != VEH_TRAIN || v->vehstatus.Test(VehState::Crashed)) return nullptr; Train *t = Train::From(v); DiagDirection exitdir = *(DiagDirection *)data; @@ -3516,7 +3518,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse) v->x_pos = gp.x; v->y_pos = gp.y; v->UpdatePosition(); - if ((v->vehstatus & VS_HIDDEN) == 0) v->Vehicle::UpdateViewport(true); + if (!v->vehstatus.Test(VehState::Hidden)) v->Vehicle::UpdateViewport(true); continue; } } @@ -3596,7 +3598,7 @@ static Vehicle *CollectTrackbitsFromCrashedVehiclesEnum(Vehicle *v, void *data) { TrackBits *trackbits = (TrackBits *)data; - if (v->type == VEH_TRAIN && (v->vehstatus & VS_CRASHED) != 0) { + if (v->type == VEH_TRAIN && v->vehstatus.Test(VehState::Crashed)) { TrackBits train_tbits = Train::From(v)->track; if (train_tbits == TRACK_BIT_WORMHOLE) { /* Vehicle is inside a wormhole, v->track contains no useful value then. */ @@ -3708,7 +3710,7 @@ static void ChangeTrainDirRandomly(Train *v) do { /* We don't need to twist around vehicles if they're not visible */ - if (!(v->vehstatus & VS_HIDDEN)) { + if (!v->vehstatus.Test(VehState::Hidden)) { v->direction = ChangeDir(v->direction, delta[GB(Random(), 0, 2)]); /* Refrain from updating the z position of the vehicle when on * a bridge, because UpdateInclination() will put the vehicle under @@ -3732,7 +3734,7 @@ static bool HandleCrashedTrain(Train *v) { int state = ++v->crash_anim_pos; - if (state == 4 && !(v->vehstatus & VS_HIDDEN)) { + if (state == 4 && !v->vehstatus.Test(VehState::Hidden)) { CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE); } @@ -3812,7 +3814,7 @@ static bool TrainApproachingLineEnd(Train *v, bool signal, bool reverse) } /* slow down */ - v->vehstatus |= VS_TRAIN_SLOWING; + v->vehstatus.Set(VehState::TrainSlowing); uint16_t break_speed = _breakdown_speeds[x & 0xF]; if (break_speed < v->cur_speed) v->cur_speed = break_speed; @@ -3858,7 +3860,7 @@ static bool TrainCanLeaveTile(const Train *v) static TileIndex TrainApproachingCrossingTile(const Train *v) { assert(v->IsFrontEngine()); - assert(!(v->vehstatus & VS_CRASHED)); + assert(!v->vehstatus.Test(VehState::Crashed)); if (!TrainCanLeaveTile(v)) return INVALID_TILE; @@ -3888,12 +3890,12 @@ static bool TrainCheckIfLineEnds(Train *v, bool reverse) int t = v->breakdown_ctr; if (t > 1) { - v->vehstatus |= VS_TRAIN_SLOWING; + v->vehstatus.Set(VehState::TrainSlowing); uint16_t break_speed = _breakdown_speeds[GB(~t, 4, 4)]; if (break_speed < v->cur_speed) v->cur_speed = break_speed; } else { - v->vehstatus &= ~VS_TRAIN_SLOWING; + v->vehstatus.Reset(VehState::TrainSlowing); } if (!TrainCanLeaveTile(v)) return true; @@ -3936,7 +3938,7 @@ static bool TrainCheckIfLineEnds(Train *v, bool reverse) static bool TrainLocoHandler(Train *v, bool mode) { /* train has crashed? */ - if (v->vehstatus & VS_CRASHED) { + if (v->vehstatus.Test(VehState::Crashed)) { return mode ? true : HandleCrashedTrain(v); // 'this' can be deleted here } @@ -3953,7 +3955,7 @@ static bool TrainLocoHandler(Train *v, bool mode) } /* exit if train is stopped */ - if ((v->vehstatus & VS_STOPPED) && v->cur_speed == 0) return true; + if (v->vehstatus.Test(VehState::Stopped) && v->cur_speed == 0) return true; bool valid_order = !v->current_order.IsType(OT_NOTHING) && v->current_order.GetType() != OT_CONDITIONAL; if (ProcessOrders(v) && CheckReverseTrain(v)) { @@ -4025,7 +4027,7 @@ static bool TrainLocoHandler(Train *v, bool mode) int j = v->UpdateSpeed(); /* we need to invalidate the widget if we are stopping from 'Stopping 0 km/h' to 'Stopped' */ - if (v->cur_speed == 0 && (v->vehstatus & VS_STOPPED)) { + if (v->cur_speed == 0 && v->vehstatus.Test(VehState::Stopped)) { /* If we manually stopped, we're not force-proceeding anymore. */ v->force_proceed = TFP_NONE; SetWindowDirty(WC_VEHICLE_VIEW, v->index); @@ -4062,7 +4064,7 @@ static bool TrainLocoHandler(Train *v, bool mode) } for (Train *u = v; u != nullptr; u = u->Next()) { - if ((u->vehstatus & VS_HIDDEN) != 0) continue; + if (u->vehstatus.Test(VehState::Hidden)) continue; u->UpdateViewport(false, false); } @@ -4108,14 +4110,14 @@ bool Train::Tick() if (this->IsFrontEngine()) { PerformanceAccumulator framerate(PFE_GL_TRAINS); - if (!(this->vehstatus & VS_STOPPED) || this->cur_speed > 0) this->running_ticks++; + if (!this->vehstatus.Test(VehState::Stopped) || this->cur_speed > 0) this->running_ticks++; this->current_order_time++; if (!TrainLocoHandler(this, false)) return false; return TrainLocoHandler(this, true); - } else if (this->IsFreeWagon() && (this->vehstatus & VS_CRASHED)) { + } else if (this->IsFreeWagon() && this->vehstatus.Test(VehState::Crashed)) { /* Delete flooded standalone wagon chain */ if (++this->crash_anim_pos >= 4400) { delete this; @@ -4214,7 +4216,7 @@ void Train::OnNewEconomyDay() */ Trackdir Train::GetVehicleTrackdir() const { - if (this->vehstatus & VS_CRASHED) return INVALID_TRACKDIR; + if (this->vehstatus.Test(VehState::Crashed)) return INVALID_TRACKDIR; if (this->track == TRACK_BIT_DEPOT) { /* We'll assume the train is facing outwards */ diff --git a/src/train_gui.cpp b/src/train_gui.cpp index 205bff2039..a0c5804e56 100644 --- a/src/train_gui.cpp +++ b/src/train_gui.cpp @@ -126,10 +126,10 @@ void DrawTrainImage(const Train *v, const Rect &r, VehicleID selection, EngineIm int width = Train::From(v)->GetDisplayImageWidth(&offset); if (rtl ? px + width > 0 : px - width < max_width) { - PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v); + PaletteID pal = v->vehstatus.Test(VehState::Crashed) ? PALETTE_CRASH : GetVehiclePalette(v); VehicleSpriteSeq seq; v->GetImage(dir, image_type, &seq); - seq.Draw(px + (rtl ? -offset.x : offset.x), y + offset.y, pal, (v->vehstatus & VS_CRASHED) != 0); + seq.Draw(px + (rtl ? -offset.x : offset.x), y + offset.y, pal, v->vehstatus.Test(VehState::Crashed)); } if (!v->IsArticulatedPart()) sel_articulated = false; @@ -373,10 +373,10 @@ void DrawTrainDetails(const Train *v, const Rect &r, int vscroll_pos, uint16_t v if (e->GetGRF() != nullptr) { pitch = ScaleSpriteTrad(e->GetGRF()->traininfo_vehicle_pitch); } - PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(u); + PaletteID pal = v->vehstatus.Test(VehState::Crashed) ? PALETTE_CRASH : GetVehiclePalette(u); VehicleSpriteSeq seq; u->GetImage(dir, EIT_IN_DETAILS, &seq); - seq.Draw(px + (rtl ? -offset.x : offset.x), r.top - line_height * vscroll_pos + sprite_y_offset + pitch, pal, (v->vehstatus & VS_CRASHED) != 0); + seq.Draw(px + (rtl ? -offset.x : offset.x), r.top - line_height * vscroll_pos + sprite_y_offset + pitch, pal, v->vehstatus.Test(VehState::Crashed)); } px += rtl ? -width : width; dx += width; diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index a33989ca81..cfcae74c6d 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -1907,7 +1907,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti if (frame == _tunnel_visibility_frame[dir]) { t->tile = tile; t->track = TRACK_BIT_WORMHOLE; - t->vehstatus |= VS_HIDDEN; + t->vehstatus.Set(VehState::Hidden); return VETSB_ENTERED_WORMHOLE; } } @@ -1917,7 +1917,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti t->tile = tile; t->track = DiagDirToDiagTrackBits(vdir); assert(t->track); - t->vehstatus &= ~VS_HIDDEN; + t->vehstatus.Reset(VehState::Hidden); return VETSB_ENTERED_WORMHOLE; } } else if (v->type == VEH_ROAD) { @@ -1930,7 +1930,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti assert(frame == rv->frame + 1); rv->tile = tile; rv->state = RVSB_WORMHOLE; - rv->vehstatus |= VS_HIDDEN; + rv->vehstatus.Set(VehState::Hidden); return VETSB_ENTERED_WORMHOLE; } else { return VETSB_CONTINUE; @@ -1942,7 +1942,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti rv->tile = tile; rv->state = DiagDirToDiagTrackdir(vdir); rv->frame = frame; - rv->vehstatus &= ~VS_HIDDEN; + rv->vehstatus.Reset(VehState::Hidden); return VETSB_ENTERED_WORMHOLE; } } diff --git a/src/vehicle.cpp b/src/vehicle.cpp index e6d75cbf16..2648a2efb8 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -191,7 +191,7 @@ bool Vehicle::NeedsServicing() const { /* Stopped or crashed vehicles will not move, as such making unmovable * vehicles to go for service is lame. */ - if (this->vehstatus & (VS_STOPPED | VS_CRASHED)) return false; + if (this->vehstatus.Any({VehState::Stopped, VehState::Crashed})) return false; /* Are we ready for the next service cycle? */ const Company *c = Company::Get(this->owner); @@ -279,17 +279,17 @@ bool Vehicle::NeedsAutomaticServicing() const uint Vehicle::Crash(bool) { - assert((this->vehstatus & VS_CRASHED) == 0); + assert(!this->vehstatus.Test(VehState::Crashed)); assert(this->Previous() == nullptr); // IsPrimaryVehicle fails for free-wagon-chains uint pass = 0; /* Stop the vehicle. */ - if (this->IsPrimaryVehicle()) this->vehstatus |= VS_STOPPED; + if (this->IsPrimaryVehicle()) this->vehstatus.Set(VehState::Stopped); /* crash all wagons, and count passengers */ for (Vehicle *v = this; v != nullptr; v = v->Next()) { /* We do not transfer reserver cargo back, so TotalCount() instead of StoredCount() */ if (IsCargoInClass(v->cargo_type, CargoClass::Passengers)) pass += v->cargo.TotalCount(); - v->vehstatus |= VS_CRASHED; + v->vehstatus.Set(VehState::Crashed); v->MarkAllViewportsDirty(); } @@ -856,7 +856,7 @@ void Vehicle::PreDestructor() if (this->type == VEH_ROAD && this->IsPrimaryVehicle()) { RoadVehicle *v = RoadVehicle::From(this); - if (!(v->vehstatus & VS_CRASHED) && IsInsideMM(v->state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END)) { + if (!v->vehstatus.Test(VehState::Crashed) && IsInsideMM(v->state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END)) { /* Leave the drive through roadstop, when you have not already left it. */ RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile))->Leave(v); } @@ -895,7 +895,7 @@ Vehicle::~Vehicle() /* sometimes, eg. for disaster vehicles, when company bankrupts, when removing crashed/flooded vehicles, * it may happen that vehicle chain is deleted when visible */ - if (!(this->vehstatus & VS_HIDDEN)) this->MarkAllViewportsDirty(); + if (!this->vehstatus.Test(VehState::Hidden)) this->MarkAllViewportsDirty(); Vehicle *v = this->Next(); this->SetNext(nullptr); @@ -917,14 +917,14 @@ Vehicle::~Vehicle() void VehicleEnteredDepotThisTick(Vehicle *v) { /* Vehicle should stop in the depot if it was in 'stopping' state */ - _vehicles_to_autoreplace[v->index] = !(v->vehstatus & VS_STOPPED); + _vehicles_to_autoreplace[v->index] = !v->vehstatus.Test(VehState::Stopped); /* We ALWAYS set the stopped state. Even when the vehicle does not plan on * stopping in the depot, so we stop it to ensure that it will not reserve * the path out of the depot before we might autoreplace it to a different * engine. The new engine would not own the reserved path we store that we * stopped the vehicle, so autoreplace can start it again */ - v->vehstatus |= VS_STOPPED; + v->vehstatus.Set(VehState::Stopped); } /** @@ -1021,13 +1021,13 @@ void CallVehicleTicks() } /* Do not play any sound when crashed */ - if (front->vehstatus & VS_CRASHED) continue; + if (front->vehstatus.Test(VehState::Crashed)) continue; /* Do not play any sound when in depot or tunnel */ - if (v->vehstatus & VS_HIDDEN) continue; + if (v->vehstatus.Test(VehState::Hidden)) continue; /* Do not play any sound when stopped */ - if ((front->vehstatus & VS_STOPPED) && (front->type != VEH_TRAIN || front->cur_speed == 0)) continue; + if (front->vehstatus.Test(VehState::Stopped) && (front->type != VEH_TRAIN || front->cur_speed == 0)) continue; /* Update motion counter for animation purposes. */ v->motion_counter += front->cur_speed; @@ -1056,7 +1056,7 @@ void CallVehicleTicks() /* Play an alternating running sound every 16 ticks */ if (GB(v->tick_counter, 0, 4) == 0) { /* Play running sound when speed > 0 and not braking */ - bool running = (front->cur_speed > 0) && !(front->vehstatus & (VS_STOPPED | VS_TRAIN_SLOWING)); + bool running = (front->cur_speed > 0) && !front->vehstatus.Any({VehState::Stopped, VehState::TrainSlowing}); PlayVehicleSound(v, running ? VSE_RUNNING_16 : VSE_STOPPED_16); } @@ -1074,7 +1074,7 @@ void CallVehicleTicks() /* Start vehicle if we stopped them in VehicleEnteredDepotThisTick() * We need to stop them between VehicleEnteredDepotThisTick() and here or we risk that * they are already leaving the depot again before being replaced. */ - if (it.second) v->vehstatus &= ~VS_STOPPED; + if (it.second) v->vehstatus.Reset(VehState::Stopped); /* Store the position of the effect as the vehicle pointer will become invalid later */ int x = v->x_pos; @@ -1119,10 +1119,10 @@ static void DoDrawVehicle(const Vehicle *v) { PaletteID pal = PAL_NONE; - if (v->vehstatus & VS_DEFPAL) pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v); + if (v->vehstatus.Test(VehState::DefaultPalette)) pal = v->vehstatus.Test(VehState::Crashed) ? PALETTE_CRASH : GetVehiclePalette(v); /* Check whether the vehicle shall be transparent due to the game state */ - bool shadowed = (v->vehstatus & VS_SHADOW) != 0; + bool shadowed = v->vehstatus.Test(VehState::Shadow); if (v->type == VEH_EFFECT) { /* Check whether the vehicle shall be transparent/invisible due to GUI settings. @@ -1134,7 +1134,7 @@ static void DoDrawVehicle(const Vehicle *v) StartSpriteCombine(); for (uint i = 0; i < v->sprite_cache.sprite_seq.count; ++i) { PaletteID pal2 = v->sprite_cache.sprite_seq.seq[i].pal; - if (!pal2 || (v->vehstatus & VS_CRASHED)) pal2 = pal; + if (!pal2 || v->vehstatus.Test(VehState::Crashed)) pal2 = pal; AddSortableSpriteToDraw(v->sprite_cache.sprite_seq.seq[i].sprite, pal2, v->x_pos + v->x_offs, v->y_pos + v->y_offs, v->x_extent, v->y_extent, v->z_extent, v->z_pos, shadowed, v->x_bb_offs, v->y_bb_offs); } @@ -1184,7 +1184,7 @@ void ViewportAddVehicles(DrawPixelInfo *dpi) while (v != nullptr) { - if (!(v->vehstatus & VS_HIDDEN) && + if (!v->vehstatus.Test(VehState::Hidden) && l <= v->coord.right + xb && t <= v->coord.bottom + yb && r >= v->coord.left - xb && @@ -1264,7 +1264,7 @@ Vehicle *CheckClickOnVehicle(const Viewport *vp, int x, int y) Vehicle *v = _vehicle_viewport_hash[hx + hy]; // already masked & 0xFFF while (v != nullptr) { - if ((v->vehstatus & (VS_HIDDEN | VS_UNCLICKABLE)) == 0 && + if (!v->vehstatus.Any({VehState::Hidden, VehState::Unclickable}) && x >= v->coord.left && x <= v->coord.right && y >= v->coord.top && y <= v->coord.bottom) { @@ -1320,7 +1320,7 @@ void CheckVehicleBreakdown(Vehicle *v) if ((rel_old >> 8) != (rel >> 8)) SetWindowDirty(WC_VEHICLE_DETAILS, v->index); } - if (v->breakdown_ctr != 0 || (v->vehstatus & VS_STOPPED) || + if (v->breakdown_ctr != 0 || v->vehstatus.Test(VehState::Stopped) || _settings_game.difficulty.vehicle_breakdowns < 1 || v->cur_speed < 5 || _game_mode == GM_MENU) { return; @@ -1374,7 +1374,7 @@ bool Vehicle::HandleBreakdown() if (this->type == VEH_AIRCRAFT) { /* Aircraft just need this flag, the rest is handled elsewhere */ - this->vehstatus |= VS_AIRCRAFT_BROKEN; + this->vehstatus.Set(VehState::AircraftBroken); } else { this->cur_speed = 0; @@ -1385,7 +1385,7 @@ bool Vehicle::HandleBreakdown() (train_or_ship ? SND_3A_BREAKDOWN_TRAIN_SHIP_TOYLAND : SND_35_BREAKDOWN_ROADVEHICLE_TOYLAND), this); } - if (!(this->vehstatus & VS_HIDDEN) && !EngInfo(this->engine_type)->misc_flags.Test(EngineMiscFlag::NoBreakdownSmoke)) { + if (!this->vehstatus.Test(VehState::Hidden) && !EngInfo(this->engine_type)->misc_flags.Test(EngineMiscFlag::NoBreakdownSmoke)) { EffectVehicle *u = CreateEffectVehicleRel(this, 4, 4, 5, EV_BREAKDOWN_SMOKE); if (u != nullptr) u->animation_state = this->breakdown_delay * 2; } @@ -1452,7 +1452,7 @@ void AgeVehicle(Vehicle *v) if (!_settings_client.gui.old_vehicle_warn) return; /* Don't warn about vehicles which are non-primary (e.g., part of an articulated vehicle), don't belong to us, are crashed, or are stopped */ - if (v->Previous() != nullptr || v->owner != _local_company || (v->vehstatus & VS_CRASHED) != 0 || (v->vehstatus & VS_STOPPED) != 0) return; + if (v->Previous() != nullptr || v->owner != _local_company || v->vehstatus.Any({VehState::Crashed, VehState::Stopped})) return; const Company *c = Company::Get(v->owner); /* Don't warn if a renew is active */ @@ -1592,7 +1592,7 @@ void VehicleEnterDepot(Vehicle *v) } SetWindowDirty(WC_VEHICLE_DEPOT, v->tile); - v->vehstatus |= VS_HIDDEN; + v->vehstatus.Set(VehState::Hidden); v->cur_speed = 0; VehicleServiceInDepot(v); @@ -2375,7 +2375,7 @@ void Vehicle::LeaveStation() HideFillingPercent(&this->fill_percent_te_id); trip_occupancy = CalcPercentVehicleFilled(this, nullptr); - if (this->type == VEH_TRAIN && !(this->vehstatus & VS_CRASHED)) { + if (this->type == VEH_TRAIN && !this->vehstatus.Test(VehState::Crashed)) { /* Trigger station animation (trains only) */ if (IsTileType(this->tile, MP_STATION)) { TriggerStationRandomisation(st, this->tile, SRT_TRAIN_DEPARTS); @@ -2384,7 +2384,7 @@ void Vehicle::LeaveStation() SetBit(Train::From(this)->flags, VRF_LEAVING_STATION); } - if (this->type == VEH_ROAD && !(this->vehstatus & VS_CRASHED)) { + if (this->type == VEH_ROAD && !this->vehstatus.Test(VehState::Crashed)) { /* Trigger road stop animation */ if (IsStationRoadStopTile(this->tile)) { TriggerRoadStopRandomisation(st, this->tile, RSRT_VEH_DEPARTS); @@ -2521,7 +2521,7 @@ void Vehicle::LeaveUnbunchingDepot() Vehicle *u = this->FirstShared(); for (; u != nullptr; u = u->NextShared()) { /* Ignore vehicles that are manually stopped or crashed. */ - if (u->vehstatus & (VS_STOPPED | VS_CRASHED)) continue; + if (u->vehstatus.Any({VehState::Stopped, VehState::Crashed})) continue; num_vehicles++; total_travel_time += u->round_trip_time; @@ -2538,7 +2538,7 @@ void Vehicle::LeaveUnbunchingDepot() u = this->FirstShared(); for (; u != nullptr; u = u->NextShared()) { /* Ignore vehicles that are manually stopped or crashed. */ - if (u->vehstatus & (VS_STOPPED | VS_CRASHED)) continue; + if (u->vehstatus.Any({VehState::Stopped, VehState::Crashed})) continue; u->depot_unbunching_next_departure = next_departure; SetWindowDirty(WC_VEHICLE_VIEW, u->index); @@ -2576,7 +2576,7 @@ CommandCost Vehicle::SendToDepot(DoCommandFlags flags, DepotCommandFlags command CommandCost ret = CheckOwnership(this->owner); if (ret.Failed()) return ret; - if (this->vehstatus & VS_CRASHED) return CMD_ERROR; + if (this->vehstatus.Test(VehState::Crashed)) return CMD_ERROR; if (this->IsStoppedInDepot()) return CMD_ERROR; /* No matter why we're headed to the depot, unbunching data is no longer valid. */ @@ -2786,7 +2786,7 @@ void Vehicle::ShowVisualEffect() const * - the vehicle is moving very slowly */ if (_settings_game.vehicle.smoke_amount == 0 || - this->vehstatus & (VS_TRAIN_SLOWING | VS_STOPPED) || + this->vehstatus.Any({VehState::TrainSlowing, VehState::Stopped}) || this->cur_speed < 2) { return; } @@ -2833,7 +2833,7 @@ void Vehicle::ShowVisualEffect() const * - The vehicle is on a tunnel tile * - The vehicle is a train engine that is currently unpowered */ if (effect_model == VESM_NONE || - v->vehstatus & VS_HIDDEN || + v->vehstatus.Test(VehState::Hidden) || IsBridgeAbove(v->tile) || IsDepotTile(v->tile) || IsTunnelTile(v->tile) || diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 51cc130e49..aab52c5928 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -28,17 +28,18 @@ const uint TILE_AXIAL_DISTANCE = 192; // Logical length of the tile in any DiagDirection used in vehicle movement. const uint TILE_CORNER_DISTANCE = 128; // Logical length of the tile corner crossing in any non-diagonal direction used in vehicle movement. -/** Vehicle status bits in #Vehicle::vehstatus. */ -enum VehStatus : uint8_t { - VS_HIDDEN = 0x01, ///< Vehicle is not visible. - VS_STOPPED = 0x02, ///< Vehicle is stopped by the player. - VS_UNCLICKABLE = 0x04, ///< Vehicle is not clickable by the user (shadow vehicles). - VS_DEFPAL = 0x08, ///< Use default vehicle palette. @see DoDrawVehicle - VS_TRAIN_SLOWING = 0x10, ///< Train is slowing down. - VS_SHADOW = 0x20, ///< Vehicle is a shadow vehicle. - VS_AIRCRAFT_BROKEN = 0x40, ///< Aircraft is broken down. - VS_CRASHED = 0x80, ///< Vehicle is crashed. +/** Vehicle state bits in #Vehicle::vehstatus. */ +enum class VehState : uint8_t { + Hidden = 0, ///< Vehicle is not visible. + Stopped = 1, ///< Vehicle is stopped by the player. + Unclickable = 2, ///< Vehicle is not clickable by the user (shadow vehicles). + DefaultPalette = 3, ///< Use default vehicle palette. @see DoDrawVehicle + TrainSlowing = 4, ///< Train is slowing down. + Shadow = 5, ///< Vehicle is a shadow vehicle. + AircraftBroken = 6, ///< Aircraft is broken down. + Crashed = 7, ///< Vehicle is crashed. }; +using VehStates = EnumBitSet; /** Bit numbers in #Vehicle::vehicle_flags. */ enum VehicleFlags : uint8_t { @@ -345,7 +346,7 @@ public: uint8_t running_ticks = 0; ///< Number of ticks this vehicle was not stopped this day uint16_t load_unload_ticks = 0; ///< Ticks to wait before starting next cycle. - uint8_t vehstatus = 0; ///< Status + VehStates vehstatus{}; ///< Status uint8_t subtype = 0; ///< subtype (Filled with values from #AircraftSubType/#DisasterSubType/#EffectVehicleType/#GroundVehicleSubtypeFlags) Order current_order{}; ///< The current order (+ status, like: loading) @@ -554,8 +555,8 @@ public: bool IsStoppedInDepot() const { assert(this == this->First()); - /* Free wagons have no VS_STOPPED state */ - if (this->IsPrimaryVehicle() && !(this->vehstatus & VS_STOPPED)) return false; + /* Free wagons have no VehState::Stopped state */ + if (this->IsPrimaryVehicle() && !this->vehstatus.Test(VehState::Stopped)) return false; return this->IsChainInDepot(); } diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index 0dfd0ceac7..f43de0aeac 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -244,7 +244,7 @@ CommandCost CmdSellVehicle(DoCommandFlags flags, VehicleID v_id, bool sell_chain CommandCost ret = CheckOwnership(front->owner); if (ret.Failed()) return ret; - if (front->vehstatus & VS_CRASHED) return CommandCost(STR_ERROR_VEHICLE_IS_DESTROYED); + if (front->vehstatus.Test(VehState::Crashed)) return CommandCost(STR_ERROR_VEHICLE_IS_DESTROYED); if (!front->IsStoppedInDepot()) return CommandCost(STR_ERROR_TRAIN_MUST_BE_STOPPED_INSIDE_DEPOT + front->type); @@ -528,7 +528,7 @@ std::tuple CmdRefitVehicle(DoCommandFla return { CommandCost(STR_ERROR_TRAIN_MUST_BE_STOPPED_INSIDE_DEPOT + front->type), 0, 0, {} }; } - if (front->vehstatus & VS_CRASHED) return { CommandCost(STR_ERROR_VEHICLE_IS_DESTROYED), 0, 0, {} }; + if (front->vehstatus.Test(VehState::Crashed)) return { CommandCost(STR_ERROR_VEHICLE_IS_DESTROYED), 0, 0, {} }; /* Check cargo */ if (new_cargo_type >= NUM_CARGO) return { CMD_ERROR, 0, 0, {} }; @@ -594,11 +594,11 @@ CommandCost CmdStartStopVehicle(DoCommandFlags flags, VehicleID veh_id, bool eva CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; - if (v->vehstatus & VS_CRASHED) return CommandCost(STR_ERROR_VEHICLE_IS_DESTROYED); + if (v->vehstatus.Test(VehState::Crashed)) return CommandCost(STR_ERROR_VEHICLE_IS_DESTROYED); switch (v->type) { case VEH_TRAIN: - if ((v->vehstatus & VS_STOPPED) && Train::From(v)->gcache.cached_power == 0) return CommandCost(STR_ERROR_TRAIN_START_NO_POWER); + if (v->vehstatus.Test(VehState::Stopped) && Train::From(v)->gcache.cached_power == 0) return CommandCost(STR_ERROR_TRAIN_START_NO_POWER); break; case VEH_SHIP: @@ -645,7 +645,7 @@ CommandCost CmdStartStopVehicle(DoCommandFlags flags, VehicleID veh_id, bool eva if (flags.Test(DoCommandFlag::Execute)) { if (v->IsStoppedInDepot() && !flags.Test(DoCommandFlag::AutoReplace)) DeleteVehicleNews(veh_id, AdviceType::VehicleWaiting); - v->vehstatus ^= VS_STOPPED; + v->vehstatus.Flip(VehState::Stopped); if (v->type != VEH_TRAIN) v->cur_speed = 0; // trains can stop 'slowly' /* Unbunching data is no longer valid. */ @@ -685,7 +685,7 @@ CommandCost CmdMassStartStopVehicle(DoCommandFlags flags, TileIndex tile, bool d } for (const Vehicle *v : list) { - if (!!(v->vehstatus & VS_STOPPED) != do_start) continue; + if (v->vehstatus.Test(VehState::Stopped) != do_start) continue; if (!vehicle_list_window && !v->IsChainInDepot()) continue; diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 9bfa5ecfb0..946dbcb88d 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -2926,7 +2926,7 @@ void CcStartStopVehicle(Commands, const CommandCost &result, VehicleID veh_id, b const Vehicle *v = Vehicle::GetIfValid(veh_id); if (v == nullptr || !v->IsPrimaryVehicle() || v->owner != _local_company) return; - StringID msg = (v->vehstatus & VS_STOPPED) ? STR_VEHICLE_COMMAND_STOPPED : STR_VEHICLE_COMMAND_STARTED; + StringID msg = v->vehstatus.Test(VehState::Stopped) ? STR_VEHICLE_COMMAND_STOPPED : STR_VEHICLE_COMMAND_STARTED; Point pt = RemapCoords(v->x_pos, v->y_pos, v->z_pos); AddTextEffect(GetEncodedString(msg), pt.x, pt.y, Ticks::DAY_TICKS, TE_RISING); } @@ -3121,11 +3121,11 @@ public: { text_colour = TC_BLACK; - if (v->vehstatus & VS_CRASHED) return GetString(STR_VEHICLE_STATUS_CRASHED); + if (v->vehstatus.Test(VehState::Crashed)) return GetString(STR_VEHICLE_STATUS_CRASHED); if (v->type != VEH_AIRCRAFT && v->breakdown_ctr == 1) return GetString(STR_VEHICLE_STATUS_BROKEN_DOWN); - if (v->vehstatus & VS_STOPPED && (!mouse_over_start_stop || v->IsStoppedInDepot())) { + if (v->vehstatus.Test(VehState::Stopped) && (!mouse_over_start_stop || v->IsStoppedInDepot())) { if (v->type != VEH_TRAIN) return GetString(STR_VEHICLE_STATUS_STOPPED); if (v->cur_speed != 0) return GetString(STR_VEHICLE_STATUS_TRAIN_STOPPING_VEL, PackVelocity(v->GetDisplaySpeed(), v->type)); if (Train::From(v)->gcache.cached_power == 0) return GetString(STR_VEHICLE_STATUS_TRAIN_NO_POWER); @@ -3140,7 +3140,7 @@ public: /* Vehicle is in a "normal" state, show current order. */ if (mouse_over_start_stop) { - if (v->vehstatus & VS_STOPPED) { + if (v->vehstatus.Test(VehState::Stopped)) { text_colour = TC_RED | TC_FORCED; } else if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_TRAIN_STUCK) && !v->current_order.IsType(OT_LOADING)) { text_colour = TC_ORANGE | TC_FORCED; @@ -3206,7 +3206,7 @@ public: Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); const Vehicle *v = Vehicle::Get(this->window_number); - SpriteID image = ((v->vehstatus & VS_STOPPED) != 0) ? SPR_FLAG_VEH_STOPPED : (HasBit(v->vehicle_flags, VF_PATHFINDER_LOST)) ? SPR_WARNING_SIGN : SPR_FLAG_VEH_RUNNING; + SpriteID image = v->vehstatus.Test(VehState::Stopped) ? SPR_FLAG_VEH_STOPPED : (HasBit(v->vehicle_flags, VF_PATHFINDER_LOST)) ? SPR_WARNING_SIGN : SPR_FLAG_VEH_RUNNING; DrawSpriteIgnorePadding(image, PAL_NONE, tr.WithWidth(icon_width, rtl), SA_CENTER); tr = tr.Indent(icon_width + WidgetDimensions::scaled.imgbtn.Horizontal(), rtl); @@ -3557,7 +3557,7 @@ void SetMouseCursorVehicle(const Vehicle *v, EngineImageType image_type) while (v != nullptr) { if (total_width >= ScaleSpriteTrad(2 * (int)VEHICLEINFO_FULL_VEHICLE_WIDTH)) break; - PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v); + PaletteID pal = v->vehstatus.Test(VehState::Crashed) ? PALETTE_CRASH : GetVehiclePalette(v); VehicleSpriteSeq seq; if (rotor_seq) { @@ -3572,7 +3572,7 @@ void SetMouseCursorVehicle(const Vehicle *v, EngineImageType image_type) if (v->type == VEH_TRAIN) x_offs = Train::From(v)->GetCursorImageOffset(); for (uint i = 0; i < seq.count; ++i) { - PaletteID pal2 = (v->vehstatus & VS_CRASHED) || !seq.seq[i].pal ? pal : seq.seq[i].pal; + PaletteID pal2 = v->vehstatus.Test(VehState::Crashed) || !seq.seq[i].pal ? pal : seq.seq[i].pal; _cursor.sprites.emplace_back(seq.seq[i].sprite, pal2, rtl ? (-total_width + x_offs) : (total_width + x_offs), y_offset); } diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index f9052c9d15..cd47c33c46 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -1020,7 +1020,7 @@ static void FloodVehicle(Vehicle *v) */ static Vehicle *FloodVehicleProc(Vehicle *v, void *data) { - if ((v->vehstatus & VS_CRASHED) != 0) return nullptr; + if (v->vehstatus.Test(VehState::Crashed)) return nullptr; switch (v->type) { default: break;