diff --git a/src/ai/api/ai_vehicle.cpp b/src/ai/api/ai_vehicle.cpp --- a/src/ai/api/ai_vehicle.cpp +++ b/src/ai/api/ai_vehicle.cpp @@ -412,7 +412,7 @@ const Vehicle *v = ::Vehicle::Get(vehicle_id); switch (v->type) { - case VEH_ROAD: return ::RoadVehHasArticPart(v); + case VEH_ROAD: return ::RoadVehicle::From(v)->RoadVehHasArticPart(); case VEH_TRAIN: return ::Train::From(v)->EngineHasArticPart(); default: NOT_REACHED(); } diff --git a/src/articulated_vehicles.cpp b/src/articulated_vehicles.cpp --- a/src/articulated_vehicles.cpp +++ b/src/articulated_vehicles.cpp @@ -211,7 +211,7 @@ bool IsArticulatedVehicleCarryingDiffere break; case VEH_ROAD: - v = (RoadVehHasArticPart(v) ? v->Next() : NULL); + v = RoadVehicle::From(v)->RoadVehHasArticPart() ? v->Next() : NULL; break; default: @@ -258,7 +258,7 @@ void CheckConsistencyOfArticulatedVehicl break; case VEH_ROAD: - v = (RoadVehHasArticPart(v) ? v->Next() : NULL); + v = RoadVehicle::From(v)->RoadVehHasArticPart() ? v->Next() : NULL; break; default: @@ -348,7 +348,7 @@ void AddArticulatedParts(Vehicle *first, rv->cargo_cap = 0; } - SetRoadVehArticPart(rv); + rv->SetArticulatedPart(); } break; } diff --git a/src/disaster_cmd.cpp b/src/disaster_cmd.cpp --- a/src/disaster_cmd.cpp +++ b/src/disaster_cmd.cpp @@ -302,7 +302,7 @@ static bool DisasterTick_Ufo(DisasterVeh RoadVehicle *u; FOR_ALL_ROADVEHICLES(u) { - if (IsRoadVehFront(u)) { + if (u->IsRoadVehFront()) { v->dest_tile = u->index; v->age = 0; return true; @@ -314,7 +314,7 @@ static bool DisasterTick_Ufo(DisasterVeh } else { /* Target a vehicle */ RoadVehicle *u = RoadVehicle::Get(v->dest_tile); - assert(u != NULL && u->type == VEH_ROAD && IsRoadVehFront(u)); + assert(u != NULL && u->type == VEH_ROAD && u->IsRoadVehFront()); uint dist = Delta(v->x_pos, u->x_pos) + Delta(v->y_pos, u->y_pos); diff --git a/src/roadstop.cpp b/src/roadstop.cpp --- a/src/roadstop.cpp +++ b/src/roadstop.cpp @@ -40,7 +40,7 @@ RoadStop *RoadStop::GetNextRoadStop(cons /* The vehicle cannot go to this roadstop (different roadtype) */ if ((GetRoadTypes(rs->xy) & v->compatible_roadtypes) == ROADTYPES_NONE) continue; /* The vehicle is articulated and can therefor not go the a standard road stop */ - if (IsStandardRoadStopTile(rs->xy) && RoadVehHasArticPart(v)) continue; + if (IsStandardRoadStopTile(rs->xy) && v->RoadVehHasArticPart()) continue; /* The vehicle can actually go to this road stop. So, return it! */ return rs; diff --git a/src/roadveh.h b/src/roadveh.h --- a/src/roadveh.h +++ b/src/roadveh.h @@ -72,36 +72,6 @@ enum RoadVehicleSubType { RVST_ARTIC_PART, }; -static inline bool IsRoadVehFront(const Vehicle *v) -{ - assert(v->type == VEH_ROAD); - return v->subtype == RVST_FRONT; -} - -static inline void SetRoadVehFront(Vehicle *v) -{ - assert(v->type == VEH_ROAD); - v->subtype = RVST_FRONT; -} - -static inline bool IsRoadVehArticPart(const Vehicle *v) -{ - assert(v->type == VEH_ROAD); - return v->subtype == RVST_ARTIC_PART; -} - -static inline void SetRoadVehArticPart(Vehicle *v) -{ - assert(v->type == VEH_ROAD); - v->subtype = RVST_ARTIC_PART; -} - -static inline bool RoadVehHasArticPart(const Vehicle *v) -{ - assert(v->type == VEH_ROAD); - return v->Next() != NULL && IsRoadVehArticPart(v->Next()); -} - void CcBuildRoadVeh(bool success, TileIndex tile, uint32 p1, uint32 p2); @@ -142,7 +112,7 @@ struct RoadVehicle : public SpecializedV void MarkDirty(); void UpdateDeltaXY(Direction direction); ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_ROADVEH_INC : EXPENSES_ROADVEH_RUN; } - bool IsPrimaryVehicle() const { return IsRoadVehFront(this); } + bool IsPrimaryVehicle() const { return this->IsRoadVehFront(); } SpriteID GetImage(Direction direction) const; int GetDisplaySpeed() const { return this->cur_speed / 2; } int GetDisplayMaxSpeed() const { return this->max_speed / 2; } @@ -154,6 +124,34 @@ struct RoadVehicle : public SpecializedV Trackdir GetVehicleTrackdir() const; TileIndex GetOrderStationLocation(StationID station); bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse); + + /** + * Check if vehicle is a front engine + * @return Returns true if vehicle is a front engine + */ + FORCEINLINE bool IsRoadVehFront() const { return this->subtype == RVST_FRONT; } + + /** + * Set front engine state + */ + FORCEINLINE void SetRoadVehFront() { this->subtype = RVST_FRONT; } + + /** + * Check if vehicl is an articulated part of an engine + * @return Returns true if vehicle is an articulated part + */ + FORCEINLINE bool IsArticulatedPart() const { return this->subtype == RVST_ARTIC_PART; } + + /** + * Set a vehicle to be an articulated part + */ + FORCEINLINE void SetArticulatedPart() { this->subtype = RVST_ARTIC_PART; } + + /** + * Check if an engine has an articulated part. + * @return True if the engine has an articulated part. + */ + FORCEINLINE bool RoadVehHasArticPart() const { return this->Next() != NULL && this->Next()->IsArticulatedPart(); } }; #define FOR_ALL_ROADVEHICLES(var) FOR_ALL_VEHICLES_OF_TYPE(RoadVehicle, var) diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -138,7 +138,7 @@ byte GetRoadVehLength(const RoadVehicle void RoadVehUpdateCache(RoadVehicle *v) { assert(v->type == VEH_ROAD); - assert(IsRoadVehFront(v)); + assert(v->IsRoadVehFront()); v->InvalidateNewGRFCacheOfChain(); @@ -245,7 +245,7 @@ CommandCost CmdBuildRoadVeh(TileIndex ti v->cur_image = SPR_IMG_QUERY; v->random_bits = VehicleRandomBits(); - SetRoadVehFront(v); + v->SetRoadVehFront(); v->roadtype = HasBit(EngInfo(v->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD; v->compatible_roadtypes = RoadTypeToRoadTypes(v->roadtype); @@ -304,7 +304,7 @@ bool RoadVehicle::IsStoppedInDepot() con TileIndex tile = this->tile; if (!IsRoadDepotTile(tile)) return false; - if (IsRoadVehFront(this) && !(this->vehstatus & VS_STOPPED)) return false; + if (this->IsRoadVehFront() && !(this->vehstatus & VS_STOPPED)) return false; for (const RoadVehicle *v = this; v != NULL; v = v->Next()) { if (v->state != RVSB_IN_DEPOT || v->tile != tile) return false; @@ -916,7 +916,7 @@ static void RoadVehCheckOvertake(RoadVeh if (IsTileType(v->tile, MP_STATION)) return; /* For now, articulated road vehicles can't overtake anything. */ - if (RoadVehHasArticPart(v)) return; + if (v->RoadVehHasArticPart()) return; /* Vehicles are not driving in same direction || direction is not a diagonal direction */ if (v->direction != u->direction || !(v->direction & 1)) return; @@ -1027,7 +1027,7 @@ static Trackdir RoadFindPathToDest(RoadV } else if (IsTileType(tile, MP_STATION) && IsStandardRoadStopTile(tile)) { /* Standard road stop (drive-through stops are treated as normal road) */ - if (!IsTileOwner(tile, v->owner) || GetRoadStopDir(tile) == enterdir || RoadVehHasArticPart(v)) { + if (!IsTileOwner(tile, v->owner) || GetRoadStopDir(tile) == enterdir || v->RoadVehHasArticPart()) { /* different station owner or wrong orientation or the vehicle has articulated parts */ trackdirs = TRACKDIR_BIT_NONE; } else { @@ -1357,7 +1357,7 @@ static bool IndividualRoadVehicleControl /* Vehicle is entering a depot or is on a bridge or in a tunnel */ GetNewVehiclePosResult gp = GetNewVehiclePos(v); - if (IsRoadVehFront(v)) { + if (v->IsRoadVehFront()) { const Vehicle *u = RoadVehFindCloseTo(v, gp.x, gp.y, v->direction); if (u != NULL) { v->cur_speed = u->First()->cur_speed; @@ -1389,7 +1389,7 @@ static bool IndividualRoadVehicleControl TileIndex tile = v->tile + TileOffsByDiagDir((DiagDirection)(rd.x & 3)); Trackdir dir; - if (IsRoadVehFront(v)) { + if (v->IsRoadVehFront()) { /* If this is the front engine, look for the right path. */ dir = RoadFindPathToDest(v, tile, (DiagDirection)(rd.x & 3)); } else { @@ -1397,7 +1397,7 @@ static bool IndividualRoadVehicleControl } if (dir == INVALID_TRACKDIR) { - if (!IsRoadVehFront(v)) error("Disconnecting road vehicle."); + if (!v->IsRoadVehFront()) error("Disconnecting road vehicle."); v->cur_speed = 0; return false; } @@ -1418,7 +1418,7 @@ again: case TRACKDIR_RVREV_NW: needed = ROAD_SE; break; } if ((v->Previous() != NULL && v->Previous()->tile == tile) || - (IsRoadVehFront(v) && IsNormalRoadTile(tile) && !HasRoadWorks(tile) && + (v->IsRoadVehFront() && IsNormalRoadTile(tile) && !HasRoadWorks(tile) && (needed & GetRoadBits(tile, ROADTYPE_TRAM)) != ROAD_NONE)) { /* * Taking the 'big' corner for trams only happens when: @@ -1430,7 +1430,7 @@ again: * going to cause the tram to split up. * - Or the front of the tram can drive over the next tile. */ - } else if (!IsRoadVehFront(v) || !CanBuildTramTrackOnTile(v->owner, tile, needed) || ((~needed & GetAnyRoadBits(v->tile, ROADTYPE_TRAM, false)) == ROAD_NONE)) { + } else if (!v->IsRoadVehFront() || !CanBuildTramTrackOnTile(v->owner, tile, needed) || ((~needed & GetAnyRoadBits(v->tile, ROADTYPE_TRAM, false)) == ROAD_NONE)) { /* * Taking the 'small' corner for trams only happens when: * - We are not the from vehicle of an articulated tram. @@ -1464,7 +1464,7 @@ again: int y = TileY(tile) * TILE_SIZE + rdp[start_frame].y; Direction new_dir = RoadVehGetSlidingDirection(v, x, y); - if (IsRoadVehFront(v)) { + if (v->IsRoadVehFront()) { Vehicle *u = RoadVehFindCloseTo(v, x, y, new_dir); if (u != NULL) { v->cur_speed = u->First()->cur_speed; @@ -1543,7 +1543,7 @@ again: case DIAGDIR_SW: dir = TRACKDIR_RVREV_NE; break; } } else { - if (IsRoadVehFront(v)) { + if (v->IsRoadVehFront()) { /* If this is the front engine, look for the right path. */ dir = RoadFindPathToDest(v, v->tile, (DiagDirection)(rd.x & 3)); } else { @@ -1562,7 +1562,7 @@ again: int y = TileY(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].y; Direction new_dir = RoadVehGetSlidingDirection(v, x, y); - if (IsRoadVehFront(v) && RoadVehFindCloseTo(v, x, y, new_dir) != NULL) return false; + if (v->IsRoadVehFront() && RoadVehFindCloseTo(v, x, y, new_dir) != NULL) return false; uint32 r = VehicleEnterTile(v, v->tile, x, y); if (HasBit(r, VETS_CANNOT_ENTER)) { @@ -1598,7 +1598,7 @@ again: Direction new_dir = RoadVehGetSlidingDirection(v, x, y); - if (IsRoadVehFront(v) && !IsInsideMM(v->state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) { + if (v->IsRoadVehFront() && !IsInsideMM(v->state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) { /* Vehicle is not in a road stop. * Check for another vehicle to overtake */ RoadVehicle *u = RoadVehFindCloseTo(v, x, y, new_dir); @@ -1632,7 +1632,7 @@ again: * and it's the correct type of stop (bus or truck) and the frame equals the stop frame... * (the station test and stop type test ensure that other vehicles, using the road stop as * a through route, do not stop) */ - if (IsRoadVehFront(v) && ((IsInsideMM(v->state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) && + if (v->IsRoadVehFront() && ((IsInsideMM(v->state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) && _road_veh_data_1[v->state - RVSB_IN_ROAD_STOP + (_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)] == v->frame) || (IsInsideMM(v->state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && v->current_order.ShouldStopAtStation(v, GetStationIndex(v->tile)) && @@ -1820,7 +1820,7 @@ bool RoadVehicle::Tick() { AgeRoadVehCargo(this); - if (IsRoadVehFront(this)) { + if (this->IsRoadVehFront()) { if (!(this->vehstatus & VS_STOPPED)) this->running_ticks++; return RoadVehController(this); } @@ -1864,7 +1864,7 @@ static void CheckIfRoadVehNeedsService(R void RoadVehicle::OnNewDay() { - if (!IsRoadVehFront(this)) return; + if (!this->IsRoadVehFront()) return; if ((++this->day_counter & 7) == 0) DecreaseVehicleValue(this); if (this->blocked_ctr == 0) CheckVehicleBreakdown(this); diff --git a/src/roadveh_gui.cpp b/src/roadveh_gui.cpp --- a/src/roadveh_gui.cpp +++ b/src/roadveh_gui.cpp @@ -24,7 +24,9 @@ */ void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y) { - uint y_offset = RoadVehHasArticPart(v) ? 15 : 0; + const RoadVehicle *rv = RoadVehicle::From(v); + + uint y_offset = rv->RoadVehHasArticPart() ? 15 : 0; StringID str; Money feeder_share = 0; @@ -33,7 +35,7 @@ void DrawRoadVehDetails(const Vehicle *v SetDParam(2, v->value); DrawString(left, right, y + y_offset, STR_VEHICLE_INFO_BUILT_VALUE); - if (RoadVehHasArticPart(v)) { + if (rv->RoadVehHasArticPart()) { CargoArray max_cargo; StringID subtype_text[NUM_CARGO]; char capacity[512]; diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -314,8 +314,11 @@ void AfterLoadVehicles(bool part_of_load t->tcache.last_speed = t->cur_speed; // update displayed train speed TrainConsistChanged(t, false); } - } else if (v->type == VEH_ROAD && IsRoadVehFront(v)) { - RoadVehUpdateCache(RoadVehicle::From(v)); + } else if (v->type == VEH_ROAD) { + RoadVehicle *rv = RoadVehicle::From(v); + if (rv->IsRoadVehFront()) { + RoadVehUpdateCache(rv); + } } } diff --git a/src/station.cpp b/src/station.cpp --- a/src/station.cpp +++ b/src/station.cpp @@ -121,7 +121,7 @@ RoadStop *Station::GetPrimaryRoadStop(co /* The vehicle cannot go to this roadstop (different roadtype) */ if ((GetRoadTypes(rs->xy) & v->compatible_roadtypes) == ROADTYPES_NONE) continue; /* The vehicle is articulated and can therefor not go the a standard road stop */ - if (IsStandardRoadStopTile(rs->xy) && RoadVehHasArticPart(v)) continue; + if (IsStandardRoadStopTile(rs->xy) && v->RoadVehHasArticPart()) continue; /* The vehicle can actually go to this road stop. So, return it! */ break; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -2542,7 +2542,7 @@ static VehicleEnterTileStatus VehicleEnt } else if (v->type == VEH_ROAD) { RoadVehicle *rv = RoadVehicle::From(v); if (rv->state < RVSB_IN_ROAD_STOP && !IsReversingRoadTrackdir((Trackdir)rv->state) && rv->frame == 0) { - if (IsRoadStop(tile) && IsRoadVehFront(v)) { + if (IsRoadStop(tile) && rv->IsRoadVehFront()) { /* Attempt to allocate a parking bay in a road stop */ RoadStop *rs = RoadStop::GetByTile(tile, GetRoadStopType(tile)); @@ -2570,7 +2570,7 @@ static VehicleEnterTileStatus VehicleEnt /* For normal (non drive-through) road stops * Check if station is busy or if there are no free bays or whether it is a articulated vehicle. */ - if (rs->IsEntranceBusy() || !rs->HasFreeBay() || RoadVehHasArticPart(v)) return VETSB_CANNOT_ENTER; + if (rs->IsEntranceBusy() || !rs->HasFreeBay() || rv->RoadVehHasArticPart()) return VETSB_CANNOT_ENTER; SetBit(rv->state, RVS_IN_ROAD_STOP); diff --git a/src/vehicle.cpp b/src/vehicle.cpp --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -483,7 +483,7 @@ bool IsEngineCountable(const Vehicle *v) case VEH_TRAIN: return !Train::From(v)->IsArticulatedPart() && // tenders and other articulated parts !Train::From(v)->IsRearDualheaded(); // rear parts of multiheaded engines - case VEH_ROAD: return IsRoadVehFront(v); + case VEH_ROAD: return RoadVehicle::From(v)->IsRoadVehFront(); case VEH_SHIP: return true; default: return false; // Only count company buildable vehicles } @@ -603,7 +603,7 @@ void CallVehicleTicks() case VEH_SHIP: if (v->type == VEH_TRAIN && Train::From(v)->IsWagon()) continue; if (v->type == VEH_AIRCRAFT && v->subtype != AIR_HELICOPTER) continue; - if (v->type == VEH_ROAD && !IsRoadVehFront(v)) continue; + if (v->type == VEH_ROAD && !RoadVehicle::From(v)->IsRoadVehFront()) continue; v->motion_counter += (v->direction & 1) ? (v->cur_speed * 3) / 4 : v->cur_speed; /* Play a running sound if the motion counter passes 256 (Do we not skip sounds?) */ @@ -976,7 +976,7 @@ void VehicleEnterDepot(Vehicle *v) case VEH_ROAD: InvalidateWindowClasses(WC_ROADVEH_LIST); - if (!IsRoadVehFront(v)) v = v->First(); + if (!RoadVehicle::From(v)->IsRoadVehFront()) v = v->First(); break; case VEH_SHIP: diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -439,7 +439,7 @@ CommandCost CmdCloneVehicle(TileIndex ti if (w->type == VEH_TRAIN && Train::From(w)->EngineHasArticPart()) { w = GetNextArticPart(Train::From(w)); - } else if (w->type == VEH_ROAD && RoadVehHasArticPart(w)) { + } else if (w->type == VEH_ROAD && RoadVehicle::From(w)->RoadVehHasArticPart()) { w = w->Next(); } else { break; @@ -455,7 +455,7 @@ CommandCost CmdCloneVehicle(TileIndex ti if (v->type == VEH_TRAIN && Train::From(v)->EngineHasArticPart()) { v = GetNextArticPart(Train::From(v)); - } else if (v->type == VEH_ROAD && RoadVehHasArticPart(v)) { + } else if (v->type == VEH_ROAD && RoadVehicle::From(v)->RoadVehHasArticPart()) { v = v->Next(); } else { break; diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -1355,7 +1355,7 @@ struct VehicleDetailsWindow : Window { case VEH_ROAD: { this->widget[VLD_WIDGET_RENAME_VEHICLE].tooltips = STR_QUERY_RENAME_ROAD_CAPTION; - if (!RoadVehHasArticPart(v)) break; + if (!RoadVehicle::From(v)->RoadVehHasArticPart()) break; /* Draw the text under the vehicle instead of next to it, minus the * height already allocated for the cargo of the first vehicle. */ diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -813,11 +813,12 @@ static void FloodVehicle(Vehicle *v) break; } - case VEH_ROAD: - if (IsRoadVehFront(v)) pass += 1; // driver - RoadVehicle::From(v)->crashed_ctr = 2000; // max 2220, disappear pretty fast + case VEH_ROAD: { + RoadVehicle *rv = RoadVehicle::From(v); + if (rv->IsRoadVehFront()) pass += 1; // driver + rv->crashed_ctr = 2000; // max 2220, disappear pretty fast InvalidateWindowClassesData(WC_ROADVEH_LIST, 0); - break; + } break; case VEH_AIRCRAFT: pass += 2; // driver