diff --git a/src/ai/api/ai_vehicle.cpp b/src/ai/api/ai_vehicle.cpp index 3e30601fed..fa324200a1 100644 --- a/src/ai/api/ai_vehicle.cpp +++ b/src/ai/api/ai_vehicle.cpp @@ -45,7 +45,7 @@ case VEH_ROAD: { uint total_length = 0; for (const Vehicle *u = v; u != NULL; u = u->Next()) { - total_length += u->u.road.cached_veh_length; + total_length += ((RoadVehicle*)u)->cached_veh_length; } return total_length; } @@ -368,7 +368,7 @@ if (!IsValidVehicle(vehicle_id)) return AIRoad::ROADTYPE_INVALID; if (GetVehicleType(vehicle_id) != VT_ROAD) return AIRoad::ROADTYPE_INVALID; - return (AIRoad::RoadType)::Vehicle::Get(vehicle_id)->u.road.roadtype; + return (AIRoad::RoadType)((RoadVehicle*)::Vehicle::Get(vehicle_id))->roadtype; } /* static */ int32 AIVehicle::GetCapacity(VehicleID vehicle_id, CargoID cargo) diff --git a/src/articulated_vehicles.cpp b/src/articulated_vehicles.cpp index 43cb29c589..33259ebb47 100644 --- a/src/articulated_vehicles.cpp +++ b/src/articulated_vehicles.cpp @@ -327,28 +327,30 @@ void AddArticulatedParts(Vehicle *first, VehicleType type) SetArticulatedPart(u); break; - case VEH_ROAD: - u = new RoadVehicle(); - u->subtype = 0; + case VEH_ROAD: { + RoadVehicle *front = (RoadVehicle *)v; + RoadVehicle *rv = new RoadVehicle(); + rv->subtype = 0; previous->SetNext(u); - u->u.road.first_engine = v->engine_type; - u->u.road.cached_veh_length = 8; // Callback is called when the consist is finished - u->u.road.state = RVSB_IN_DEPOT; + rv->first_engine = front->engine_type; + rv->cached_veh_length = 8; // Callback is called when the consist is finished + rv->state = RVSB_IN_DEPOT; - u->u.road.roadtype = v->u.road.roadtype; - u->u.road.compatible_roadtypes = v->u.road.compatible_roadtypes; + rv->roadtype = front->roadtype; + rv->compatible_roadtypes = front->compatible_roadtypes; - u->spritenum = e_artic->u.road.image_index; + rv->spritenum = e_artic->image_index; if (e_artic->CanCarryCargo()) { - u->cargo_type = e_artic->GetDefaultCargoType(); - u->cargo_cap = e_artic->u.road.capacity; // Callback 36 is called when the consist is finished + rv->cargo_type = e_artic->GetDefaultCargoType(); + rv->cargo_cap = e_artic->u.road.capacity; // Callback 36 is called when the consist is finished } else { - u->cargo_type = v->cargo_type; // Needed for livery selection - u->cargo_cap = 0; + rv->cargo_type = front->cargo_type; // Needed for livery selection + rv->cargo_cap = 0; } - SetRoadVehArticPart(u); - break; + SetRoadVehArticPart(rv); + u = rv; + } break; } /* get common values from first engine */ diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 002c4b063e..0daf0828fc 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -5,6 +5,7 @@ #include "train.h" #include "ship.h" #include "aircraft.h" +#include "roadveh.h" #include "gui.h" #include "textbuf_gui.h" #include "viewport_func.h" @@ -517,7 +518,7 @@ struct DepotWindow : Window { break; case VEH_ROAD: - _cursor.short_vehicle_offset = 16 - v->u.road.cached_veh_length * 2; + _cursor.short_vehicle_offset = 16 - ((RoadVehicle *)v)->cached_veh_length * 2; break; default: diff --git a/src/disaster_cmd.cpp b/src/disaster_cmd.cpp index c9b05d18bb..8a2ed7e612 100644 --- a/src/disaster_cmd.cpp +++ b/src/disaster_cmd.cpp @@ -314,11 +314,12 @@ static bool DisasterTick_Ufo(DisasterVehicle *v) return false; } else { /* Target a vehicle */ - Vehicle *u = Vehicle::Get(v->dest_tile); - if (u->type != VEH_ROAD || !IsRoadVehFront(u)) { + Vehicle *u_tmp = Vehicle::Get(v->dest_tile); + if (u_tmp->type != VEH_ROAD || !IsRoadVehFront(u_tmp)) { delete v; return false; } + RoadVehicle *u = (RoadVehicle *)u_tmp; uint dist = Delta(v->x_pos, u->x_pos) + Delta(v->y_pos, u->y_pos); @@ -336,8 +337,8 @@ static bool DisasterTick_Ufo(DisasterVehicle *v) if (z <= u->z_pos && (u->vehstatus & VS_HIDDEN) == 0) { v->age++; - if (u->u.road.crashed_ctr == 0) { - u->u.road.crashed_ctr++; + if (u->crashed_ctr == 0) { + u->crashed_ctr++; AddNewsItem(STR_NEWS_DISASTER_SMALL_UFO, NS_ACCIDENT_VEHICLE, diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index 993ff00f90..cc7a6d4ada 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -5,6 +5,7 @@ #include "stdafx.h" #include "debug.h" #include "train.h" +#include "roadveh.h" #include "company_func.h" #include "newgrf_engine.h" #include "newgrf_spritegroup.h" @@ -435,7 +436,7 @@ static uint8 LiveryHelper(EngineID engine, const Vehicle *v) } else if (v->type == VEH_TRAIN) { l = GetEngineLivery(v->engine_type, v->owner, v->u.rail.first_engine, v); } else if (v->type == VEH_ROAD) { - l = GetEngineLivery(v->engine_type, v->owner, v->u.road.first_engine, v); + l = GetEngineLivery(v->engine_type, v->owner, ((RoadVehicle *)v)->first_engine, v); } else { l = GetEngineLivery(v->engine_type, v->owner, INVALID_ENGINE, v); } @@ -780,17 +781,18 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, by } break; - case VEH_ROAD: + case VEH_ROAD: { + RoadVehicle *rv = (RoadVehicle *)v; switch (variable - 0x80) { - case 0x62: return v->u.road.state; - case 0x64: return v->u.road.blocked_ctr; - case 0x65: return GB(v->u.road.blocked_ctr, 8, 8); - case 0x66: return v->u.road.overtaking; - case 0x67: return v->u.road.overtaking_ctr; - case 0x68: return v->u.road.crashed_ctr; - case 0x69: return GB(v->u.road.crashed_ctr, 8, 8); + case 0x62: return rv->state; + case 0x64: return rv->blocked_ctr; + case 0x65: return GB(rv->blocked_ctr, 8, 8); + case 0x66: return rv->overtaking; + case 0x67: return rv->overtaking_ctr; + case 0x68: return rv->crashed_ctr; + case 0x69: return GB(rv->crashed_ctr, 8, 8); } - break; + } break; case VEH_AIRCRAFT: { Aircraft *a = (Aircraft *)v; @@ -885,7 +887,7 @@ static const SpriteGroup *GetVehicleSpriteGroup(EngineID engine, const Vehicle * group = use_cache ? v->u.rail.cached_override : GetWagonOverrideSpriteSet(v->engine_type, v->cargo_type, v->u.rail.first_engine); if (group != NULL) return group; } else if (v->type == VEH_ROAD) { - group = GetWagonOverrideSpriteSet(v->engine_type, v->cargo_type, v->u.road.first_engine); + group = GetWagonOverrideSpriteSet(v->engine_type, v->cargo_type, ((RoadVehicle *)v)->first_engine); if (group != NULL) return group; } } diff --git a/src/openttd.cpp b/src/openttd.cpp index 218f11f2bb..db4f56f4d5 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -1119,7 +1119,7 @@ void StateGameLoop() switch (v->type) { case VEH_ROAD: { extern byte GetRoadVehLength(const RoadVehicle *v); - if (GetRoadVehLength((RoadVehicle *)v) != v->u.road.cached_veh_length) { + if (GetRoadVehLength((RoadVehicle *)v) != ((RoadVehicle *)v)->cached_veh_length) { DEBUG(desync, 2, "cache mismatch: vehicle %i, company %i, unit number %i\n", v->index, (int)v->owner, v->unitnumber); } } break; diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 30b606bc36..231abebe82 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -1547,20 +1547,22 @@ static VehicleEnterTileStatus VehicleEnter_Road(Vehicle *v, TileIndex tile, int } break; - case ROAD_TILE_DEPOT: - if (v->type == VEH_ROAD && - v->u.road.frame == RVC_DEPOT_STOP_FRAME && - _roadveh_enter_depot_dir[GetRoadDepotDirection(tile)] == v->u.road.state) { - v->u.road.state = RVSB_IN_DEPOT; - v->vehstatus |= VS_HIDDEN; - v->direction = ReverseDir(v->direction); - if (v->Next() == NULL) VehicleEnterDepot(v); - v->tile = tile; + case ROAD_TILE_DEPOT: { + if (v->type != VEH_ROAD) break; - InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile); + RoadVehicle *rv = (RoadVehicle *)v; + 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->direction = ReverseDir(rv->direction); + if (rv->Next() == NULL) VehicleEnterDepot(rv); + rv->tile = tile; + + InvalidateWindowData(WC_VEHICLE_DEPOT, rv->tile); return VETSB_ENTERED_WORMHOLE; } - break; + } break; default: break; } diff --git a/src/roadveh.h b/src/roadveh.h index c27ed254d9..905fc5982c 100644 --- a/src/roadveh.h +++ b/src/roadveh.h @@ -12,6 +12,41 @@ struct RoadVehicle; +/** Road vehicle states */ +enum RoadVehicleStates { + /* + * Lower 4 bits are used for vehicle track direction. (Trackdirs) + * When in a road stop (bit 5 or bit 6 set) these bits give the + * track direction of the entry to the road stop. + * As the entry direction will always be a diagonal + * direction (X_NE, Y_SE, X_SW or Y_NW) only bits 0 and 3 + * are needed to hold this direction. Bit 1 is then used to show + * that the vehicle is using the second road stop bay. + * Bit 2 is then used for drive-through stops to show the vehicle + * is stopping at this road stop. + */ + + /* Numeric values */ + RVSB_IN_DEPOT = 0xFE, ///< The vehicle is in a depot + RVSB_WORMHOLE = 0xFF, ///< The vehicle is in a tunnel and/or bridge + + /* Bit numbers */ + RVS_USING_SECOND_BAY = 1, ///< Only used while in a road stop + RVS_IS_STOPPING = 2, ///< Only used for drive-through stops. Vehicle will stop here + RVS_DRIVE_SIDE = 4, ///< Only used when retrieving move data + RVS_IN_ROAD_STOP = 5, ///< The vehicle is in a road stop + RVS_IN_DT_ROAD_STOP = 6, ///< The vehicle is in a drive-through road stop + + /* Bit sets of the above specified bits */ + RVSB_IN_ROAD_STOP = 1 << RVS_IN_ROAD_STOP, ///< The vehicle is in a road stop + RVSB_IN_ROAD_STOP_END = RVSB_IN_ROAD_STOP + TRACKDIR_END, + RVSB_IN_DT_ROAD_STOP = 1 << RVS_IN_DT_ROAD_STOP, ///< The vehicle is in a drive-through road stop + RVSB_IN_DT_ROAD_STOP_END = RVSB_IN_DT_ROAD_STOP + TRACKDIR_END, + + RVSB_TRACKDIR_MASK = 0x0F, ///< The mask used to extract track dirs + RVSB_ROAD_STOP_TRACKDIR_MASK = 0x09 ///< Only bits 0 and 3 are used to encode the trackdir for road stops +}; + /** State information about the Road Vehicle controller */ enum { RDE_NEXT_TILE = 0x80, ///< We should enter the next tile @@ -84,6 +119,21 @@ void RoadVehUpdateCache(RoadVehicle *v); * As side-effect the vehicle type is set correctly. */ struct RoadVehicle : public Vehicle { + byte state; ///< @see RoadVehicleStates + byte frame; + uint16 blocked_ctr; + byte overtaking; + byte overtaking_ctr; + uint16 crashed_ctr; + byte reverse_ctr; + struct RoadStop *slot; + byte slot_age; + EngineID first_engine; + byte cached_veh_length; + + RoadType roadtype; + RoadTypes compatible_roadtypes; + /** Initializes the Vehicle to a road vehicle */ RoadVehicle() { this->type = VEH_ROAD; } @@ -99,7 +149,7 @@ struct RoadVehicle : public Vehicle { int GetDisplaySpeed() const { return this->cur_speed / 2; } int GetDisplayMaxSpeed() const { return this->max_speed / 2; } Money GetRunningCost() const { return RoadVehInfo(this->engine_type)->running_cost * GetPriceByIndex(RoadVehInfo(this->engine_type)->running_cost_class); } - bool IsInDepot() const { return this->u.road.state == RVSB_IN_DEPOT; } + bool IsInDepot() const { return this->state == RVSB_IN_DEPOT; } bool IsStoppedInDepot() const; bool Tick(); void OnNewDay(); diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 61054f180b..cdc797e069 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -142,10 +142,10 @@ void RoadVehUpdateCache(RoadVehicle *v) assert(u->First() == v); /* Update the 'first engine' */ - u->u.road.first_engine = (v == u) ? INVALID_ENGINE : v->engine_type; + u->first_engine = (v == u) ? INVALID_ENGINE : v->engine_type; /* Update the length of the vehicle. */ - u->u.road.cached_veh_length = GetRoadVehLength(u); + u->cached_veh_length = GetRoadVehLength(u); /* Invalidate the vehicle colour map */ u->colourmap = PAL_NONE; @@ -206,7 +206,7 @@ CommandCost CmdBuildRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint // v->running_ticks = 0; - v->u.road.state = RVSB_IN_DEPOT; + v->state = RVSB_IN_DEPOT; v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL; v->spritenum = rvi->image_index; @@ -220,7 +220,7 @@ CommandCost CmdBuildRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint // v->load_unload_time_rem = 0; // v->progress = 0; -// v->u.road.overtaking = 0; +// v->overtaking = 0; v->last_station_visited = INVALID_STATION; v->max_speed = rvi->max_speed; @@ -242,9 +242,9 @@ CommandCost CmdBuildRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint v->random_bits = VehicleRandomBits(); SetRoadVehFront(v); - v->u.road.roadtype = HasBit(EngInfo(v->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD; - v->u.road.compatible_roadtypes = RoadTypeToRoadTypes(v->u.road.roadtype); - v->u.road.cached_veh_length = 8; + v->roadtype = HasBit(EngInfo(v->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD; + v->compatible_roadtypes = RoadTypeToRoadTypes(v->roadtype); + v->cached_veh_length = 8; v->vehicle_flags = 0; if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); @@ -255,7 +255,7 @@ CommandCost CmdBuildRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint /* Call various callbacks after the whole consist has been constructed */ for (RoadVehicle *u = v; u != NULL; u = u->Next()) { - u->u.road.cached_veh_length = GetRoadVehLength(u); + u->cached_veh_length = GetRoadVehLength(u); /* Cargo capacity is zero if and only if the vehicle cannot carry anything */ if (u->cargo_cap != 0) u->cargo_cap = GetVehicleProperty(u, 0x0F, u->cargo_cap); } @@ -279,11 +279,11 @@ CommandCost CmdBuildRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint void ClearSlot(RoadVehicle *v) { - RoadStop *rs = v->u.road.slot; - if (v->u.road.slot == NULL) return; + RoadStop *rs = v->slot; + if (v->slot == NULL) return; - v->u.road.slot = NULL; - v->u.road.slot_age = 0; + v->slot = NULL; + v->slot_age = 0; assert(rs->num_vehicles != 0); rs->num_vehicles--; @@ -299,7 +299,7 @@ bool RoadVehicle::IsStoppedInDepot() const if (IsRoadVehFront(this) && !(this->vehstatus & VS_STOPPED)) return false; for (const RoadVehicle *v = this; v != NULL; v = v->Next()) { - if (v->u.road.state != RVSB_IN_DEPOT || v->tile != tile) return false; + if (v->state != RVSB_IN_DEPOT || v->tile != tile) return false; } return true; } @@ -366,7 +366,7 @@ static const Depot *FindClosestRoadDepot(const RoadVehicle *v) /* See where we are now */ Trackdir trackdir = v->GetVehicleTrackdir(); - NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, v->tile, ReverseTrackdir(trackdir), false, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPES, 0); + NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, v->tile, ReverseTrackdir(trackdir), false, TRANSPORT_ROAD, v->compatible_roadtypes, v->owner, INVALID_RAILTYPES, 0); if (ftd.best_bird_dist == 0) return GetDepotByTile(ftd.node.tile); // Target found } break; @@ -380,7 +380,7 @@ static const Depot *FindClosestRoadDepot(const RoadVehicle *v) /* search in all directions */ for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) { - FollowTrack(v->tile, PATHFIND_FLAGS_NONE, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, d, EnumRoadSignalFindDepot, NULL, &rfdd); + FollowTrack(v->tile, PATHFIND_FLAGS_NONE, TRANSPORT_ROAD, v->compatible_roadtypes, d, EnumRoadSignalFindDepot, NULL, &rfdd); } if (rfdd.best_length != UINT_MAX) return GetDepotByTile(rfdd.tile); @@ -432,14 +432,16 @@ CommandCost CmdSendRoadVehToDepot(TileIndex tile, DoCommandFlag flags, uint32 p1 */ CommandCost CmdTurnRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { - Vehicle *v = Vehicle::GetIfValid(p1); - if (v == NULL || v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR; + Vehicle *u = Vehicle::GetIfValid(p1); + if (u == NULL || u->type != VEH_ROAD || !CheckOwnership(u->owner)) return CMD_ERROR; + + RoadVehicle *v = (RoadVehicle *)u; if (v->vehstatus & VS_STOPPED || v->vehstatus & VS_CRASHED || v->breakdown_ctr != 0 || - v->u.road.overtaking != 0 || - v->u.road.state == RVSB_WORMHOLE || + v->overtaking != 0 || + v->state == RVSB_WORMHOLE || v->IsInDepot() || v->cur_speed < 5) { return CMD_ERROR; @@ -449,7 +451,7 @@ CommandCost CmdTurnRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 if (IsTileType(v->tile, MP_TUNNELBRIDGE) && DirToDiagDir(v->direction) == GetTunnelBridgeDirection(v->tile)) return CMD_ERROR; - if (flags & DC_EXEC) v->u.road.reverse_ctr = 180; + if (flags & DC_EXEC) v->reverse_ctr = 180; return CommandCost(); } @@ -494,7 +496,7 @@ static void ClearCrashedStation(RoadVehicle *v) rs->SetEntranceBusy(false); /* Free the parking bay */ - rs->FreeBay(HasBit(v->u.road.state, RVS_USING_SECOND_BAY)); + rs->FreeBay(HasBit(v->state, RVS_USING_SECOND_BAY)); } static void DeleteLastRoadVeh(RoadVehicle *v) @@ -542,12 +544,12 @@ static void RoadVehSetRandomDirection(RoadVehicle *v) static bool RoadVehIsCrashed(RoadVehicle *v) { - v->u.road.crashed_ctr++; - if (v->u.road.crashed_ctr == 2) { + v->crashed_ctr++; + if (v->crashed_ctr == 2) { CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE); - } else if (v->u.road.crashed_ctr <= 45) { + } else if (v->crashed_ctr <= 45) { if ((v->tick_counter & 7) == 0) RoadVehSetRandomDirection(v); - } else if (v->u.road.crashed_ctr >= 2220 && !(v->tick_counter & 0x1F)) { + } else if (v->crashed_ctr >= 2220 && !(v->tick_counter & 0x1F)) { bool ret = v->Next() != NULL; DeleteLastRoadVeh(v); return ret; @@ -572,7 +574,7 @@ static void RoadVehCrash(RoadVehicle *v) { uint16 pass = 1; - v->u.road.crashed_ctr++; + v->crashed_ctr++; for (Vehicle *u = v; u != NULL; u = u->Next()) { if (IsCargoInClass(u->cargo_type, CC_PASSENGERS)) pass += u->cargo.Count(); @@ -604,7 +606,7 @@ static void RoadVehCrash(RoadVehicle *v) static bool RoadVehCheckTrainCrash(RoadVehicle *v) { for (RoadVehicle *u = v; u != NULL; u = u->Next()) { - if (u->u.road.state == RVSB_WORMHOLE) continue; + if (u->state == RVSB_WORMHOLE) continue; TileIndex tile = u->tile; @@ -732,7 +734,7 @@ static RoadVehicle *RoadVehFindCloseTo(RoadVehicle *v, int x, int y, Direction d RoadVehFindData rvf; RoadVehicle *front = v->First(); - if (front->u.road.reverse_ctr != 0) return NULL; + if (front->reverse_ctr != 0) return NULL; rvf.x = x; rvf.y = y; @@ -740,7 +742,7 @@ static RoadVehicle *RoadVehFindCloseTo(RoadVehicle *v, int x, int y, Direction d rvf.veh = v; rvf.best_diff = UINT_MAX; - if (front->u.road.state == RVSB_WORMHOLE) { + if (front->state == RVSB_WORMHOLE) { FindVehicleOnPos(v->tile, &rvf, EnumCheckRoadVehClose); FindVehicleOnPos(GetOtherTunnelBridgeEnd(v->tile), &rvf, EnumCheckRoadVehClose); } else { @@ -752,11 +754,11 @@ static RoadVehicle *RoadVehFindCloseTo(RoadVehicle *v, int x, int y, Direction d * drive just through it. The ultimate backup-code of TTD. * It can be disabled. */ if (rvf.best_diff == UINT_MAX) { - front->u.road.blocked_ctr = 0; + front->blocked_ctr = 0; return NULL; } - if (++front->u.road.blocked_ctr > 1480) return NULL; + if (++front->blocked_ctr > 1480) return NULL; return (RoadVehicle *)rvf.best; } @@ -769,7 +771,7 @@ static void RoadVehArrivesAt(const RoadVehicle *v, Station *st) st->had_vehicle_of_type |= HVOT_BUS; SetDParam(0, st->index); AddNewsItem( - v->u.road.roadtype == ROADTYPE_ROAD ? STR_NEWS_FIRST_ROAD_BUS_ARRIVAL : STR_NEWS_FIRST_ROAD_PASSENGER_TRAM_ARRIVAL, + v->roadtype == ROADTYPE_ROAD ? STR_NEWS_FIRST_ROAD_BUS_ARRIVAL : STR_NEWS_FIRST_ROAD_PASSENGER_TRAM_ARRIVAL, (v->owner == _local_company) ? NS_ARRIVAL_COMPANY : NS_ARRIVAL_OTHER, v->index, st->index @@ -782,7 +784,7 @@ static void RoadVehArrivesAt(const RoadVehicle *v, Station *st) st->had_vehicle_of_type |= HVOT_TRUCK; SetDParam(0, st->index); AddNewsItem( - v->u.road.roadtype == ROADTYPE_ROAD ? STR_NEWS_FIRST_ROAD_TRUCK_ARRIVAL : STR_NEWS_FIRST_ROAD_CARGO_TRAM_ARRIVAL, + v->roadtype == ROADTYPE_ROAD ? STR_NEWS_FIRST_ROAD_TRUCK_ARRIVAL : STR_NEWS_FIRST_ROAD_CARGO_TRAM_ARRIVAL, (v->owner == _local_company) ? NS_ARRIVAL_COMPANY : NS_ARRIVAL_OTHER, v->index, st->index @@ -795,7 +797,7 @@ static void RoadVehArrivesAt(const RoadVehicle *v, Station *st) static int RoadVehAccelerate(RoadVehicle *v) { uint oldspeed = v->cur_speed; - uint accel = 256 + (v->u.road.overtaking != 0 ? 256 : 0); + uint accel = 256 + (v->overtaking != 0 ? 256 : 0); uint spd = v->subspeed + accel; v->subspeed = (uint8)spd; @@ -808,7 +810,7 @@ static int RoadVehAccelerate(RoadVehicle *v) v->cur_speed = spd = Clamp(v->cur_speed + ((int)spd >> 8), 0, tempmax); /* Apply bridge speed limit */ - if (v->u.road.state == RVSB_WORMHOLE && !(v->vehstatus & VS_HIDDEN)) { + if (v->state == RVSB_WORMHOLE && !(v->vehstatus & VS_HIDDEN)) { v->cur_speed = min(v->cur_speed, GetBridgeSpec(GetBridgeType(v->tile))->speed * 2); } @@ -877,7 +879,7 @@ static Vehicle *EnumFindVehBlockingOvertake(Vehicle *v, void *data) */ static bool CheckRoadBlockedForOvertaking(OvertakeData *od) { - TrackStatus ts = GetTileTrackStatus(od->tile, TRANSPORT_ROAD, od->v->u.road.compatible_roadtypes); + TrackStatus ts = GetTileTrackStatus(od->tile, TRANSPORT_ROAD, od->v->compatible_roadtypes); TrackdirBits trackdirbits = TrackStatusToTrackdirBits(ts); TrackdirBits red_signals = TrackStatusToRedSignals(ts); // barred level crossing TrackBits trackbits = TrackdirBitsToTrackBits(trackdirbits); @@ -903,7 +905,7 @@ static void RoadVehCheckOvertake(RoadVehicle *v, RoadVehicle *u) } /* Trams can't overtake other trams */ - if (v->u.road.roadtype == ROADTYPE_TRAM) return; + if (v->roadtype == ROADTYPE_TRAM) return; /* Don't overtake in stations */ if (IsTileType(v->tile, MP_STATION)) return; @@ -915,7 +917,7 @@ static void RoadVehCheckOvertake(RoadVehicle *v, RoadVehicle *u) if (v->direction != u->direction || !(v->direction & 1)) return; /* Check if vehicle is in a road stop, depot, tunnel or bridge or not on a straight road */ - if (v->u.road.state >= RVSB_IN_ROAD_STOP || !IsStraightRoadTrackdir((Trackdir)(v->u.road.state & RVSB_TRACKDIR_MASK))) return; + if (v->state >= RVSB_IN_ROAD_STOP || !IsStraightRoadTrackdir((Trackdir)(v->state & RVSB_TRACKDIR_MASK))) return; od.trackdir = DiagDirToDiagTrackdir(DirToDiagDir(v->direction)); @@ -932,12 +934,12 @@ static void RoadVehCheckOvertake(RoadVehicle *v, RoadVehicle *u) if (CheckRoadBlockedForOvertaking(&od)) return; if (od.u->cur_speed == 0 || od.u->vehstatus& VS_STOPPED) { - v->u.road.overtaking_ctr = 0x11; - v->u.road.overtaking = 0x10; + v->overtaking_ctr = 0x11; + v->overtaking = 0x10; } else { // if (CheckRoadBlockedForOvertaking(&od)) return; - v->u.road.overtaking_ctr = 0; - v->u.road.overtaking = 0x10; + v->overtaking_ctr = 0; + v->overtaking = 0x10; } } @@ -1008,12 +1010,12 @@ static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection FindRoadToChooseData frd; Trackdir best_track; - TrackStatus ts = GetTileTrackStatus(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes); + TrackStatus ts = GetTileTrackStatus(tile, TRANSPORT_ROAD, v->compatible_roadtypes); TrackdirBits red_signals = TrackStatusToRedSignals(ts); // crossing TrackdirBits trackdirs = TrackStatusToTrackdirBits(ts); if (IsTileType(tile, MP_ROAD)) { - if (IsRoadDepot(tile) && (!IsTileOwner(tile, v->owner) || GetRoadDepotDirection(tile) == enterdir || (GetRoadTypes(tile) & v->u.road.compatible_roadtypes) == 0)) { + if (IsRoadDepot(tile) && (!IsTileOwner(tile, v->owner) || GetRoadDepotDirection(tile) == enterdir || (GetRoadTypes(tile) & v->compatible_roadtypes) == 0)) { /* Road depot owned by another company or with the wrong orientation */ trackdirs = TRACKDIR_BIT_NONE; } @@ -1052,9 +1054,9 @@ static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection return_track(_road_reverse_table[enterdir]); } - if (v->u.road.reverse_ctr != 0) { + if (v->reverse_ctr != 0) { bool reverse = true; - if (v->u.road.roadtype == ROADTYPE_TRAM) { + if (v->roadtype == ROADTYPE_TRAM) { /* Trams may only reverse on a tile if it contains at least the straight * trackbits or when it is a valid turning tile (i.e. one roadbit) */ RoadBits rb = GetAnyRoadBits(tile, ROADTYPE_TRAM); @@ -1063,7 +1065,7 @@ static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection (rb == DiagDirToRoadBits(enterdir)); } if (reverse) { - v->u.road.reverse_ctr = 0; + v->reverse_ctr = 0; if (v->tile != tile) { return_track(_road_reverse_table[enterdir]); } @@ -1095,7 +1097,7 @@ static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection Trackdir trackdir = DiagDirToDiagTrackdir(enterdir); /* debug("Finding path. Enterdir: %d, Trackdir: %d", enterdir, trackdir); */ - NPFFoundTargetData ftd = PerfNPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, true, &fstd, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPES); + NPFFoundTargetData ftd = PerfNPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, true, &fstd, TRANSPORT_ROAD, v->compatible_roadtypes, v->owner, INVALID_RAILTYPES); if (ftd.best_trackdir == INVALID_TRACKDIR) { /* We are already at our target. Just do something * @todo: maybe display error? @@ -1148,7 +1150,7 @@ do_it:; if (best_track == INVALID_TRACKDIR) best_track = (Trackdir)i; // in case we don't find the path, just pick a track frd.maxtracklen = UINT_MAX; frd.mindist = UINT_MAX; - FollowTrack(tile, PATHFIND_FLAGS_NONE, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, _road_pf_directions[i], EnumRoadTrackFindDist, NULL, &frd); + FollowTrack(tile, PATHFIND_FLAGS_NONE, TRANSPORT_ROAD, v->compatible_roadtypes, _road_pf_directions[i], EnumRoadTrackFindDist, NULL, &frd); if (frd.mindist < best_dist || (frd.mindist == best_dist && frd.maxtracklen < best_maxlen)) { best_dist = frd.mindist; @@ -1181,7 +1183,7 @@ static uint RoadFindPathToStop(const RoadVehicle *v, TileIndex tile) fstd.dest_coords = tile; fstd.station_index = INVALID_STATION; // indicates that the destination is a tile, not a station - uint dist = NPFRouteToStationOrTile(v->tile, trackdir, false, &fstd, TRANSPORT_ROAD, v->u.road.compatible_roadtypes, v->owner, INVALID_RAILTYPES).best_path_dist; + uint dist = NPFRouteToStationOrTile(v->tile, trackdir, false, &fstd, TRANSPORT_ROAD, v->compatible_roadtypes, v->owner, INVALID_RAILTYPES).best_path_dist; /* change units from NPF_TILE_LENGTH to # of tiles */ if (dist != UINT_MAX) dist = (dist + NPF_TILE_LENGTH - 1) / NPF_TILE_LENGTH; @@ -1205,14 +1207,14 @@ static bool RoadVehLeaveDepot(RoadVehicle *v, bool first) { /* Don't leave if not all the wagons are in the depot. */ for (const RoadVehicle *u = v; u != NULL; u = u->Next()) { - if (u->u.road.state != RVSB_IN_DEPOT || u->tile != v->tile) return false; + if (u->state != RVSB_IN_DEPOT || u->tile != v->tile) return false; } DiagDirection dir = GetRoadDepotDirection(v->tile); v->direction = DiagDirToDir(dir); Trackdir tdir = _roadveh_depot_exit_trackdir[dir]; - const RoadDriveEntry *rdp = _road_drive_data[v->u.road.roadtype][(_settings_game.vehicle.road_side << RVS_DRIVE_SIDE) + tdir]; + const RoadDriveEntry *rdp = _road_drive_data[v->roadtype][(_settings_game.vehicle.road_side << RVS_DRIVE_SIDE) + tdir]; int x = TileX(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].x & 0xF); int y = TileY(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].y & 0xF); @@ -1229,8 +1231,8 @@ static bool RoadVehLeaveDepot(RoadVehicle *v, bool first) } v->vehstatus &= ~VS_HIDDEN; - v->u.road.state = tdir; - v->u.road.frame = RVC_DEPOT_START_FRAME; + v->state = tdir; + v->frame = RVC_DEPOT_START_FRAME; v->UpdateDeltaXY(v->direction); SetRoadVehPosition(v, x, y); @@ -1248,7 +1250,7 @@ static Trackdir FollowPreviousRoadVehicle(const RoadVehicle *v, const RoadVehicl return _road_reverse_table[entry_dir]; } - byte prev_state = prev->u.road.state; + byte prev_state = prev->state; Trackdir dir; if (prev_state == RVSB_WORMHOLE || prev_state == RVSB_IN_DEPOT) { @@ -1299,7 +1301,7 @@ static Trackdir FollowPreviousRoadVehicle(const RoadVehicle *v, const RoadVehicl }; RoadBits required = required_roadbits[dir & 0x07]; - if ((required & GetAnyRoadBits(tile, v->u.road.roadtype, true)) == ROAD_NONE) { + if ((required & GetAnyRoadBits(tile, v->roadtype, true)) == ROAD_NONE) { dir = INVALID_TRACKDIR; } @@ -1327,16 +1329,16 @@ static bool CanBuildTramTrackOnTile(CompanyID c, TileIndex t, RoadBits r) static bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev) { - if (v->u.road.overtaking != 0) { + if (v->overtaking != 0) { if (IsTileType(v->tile, MP_STATION)) { /* Force us to be not overtaking! */ - v->u.road.overtaking = 0; - } else if (++v->u.road.overtaking_ctr >= 35) { + v->overtaking = 0; + } else if (++v->overtaking_ctr >= 35) { /* If overtaking just aborts at a random moment, we can have a out-of-bound problem, * if the vehicle started a corner. To protect that, only allow an abort of * overtake if we are on straight roads */ - if (v->u.road.state < RVSB_IN_ROAD_STOP && IsStraightRoadTrackdir((Trackdir)v->u.road.state)) { - v->u.road.overtaking = 0; + if (v->state < RVSB_IN_ROAD_STOP && IsStraightRoadTrackdir((Trackdir)v->state)) { + v->overtaking = 0; } } } @@ -1346,7 +1348,7 @@ static bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *p * by the previous vehicle in the chain when it gets to the right place. */ if (v->IsInDepot()) return true; - if (v->u.road.state == RVSB_WORMHOLE) { + if (v->state == RVSB_WORMHOLE) { /* Vehicle is entering a depot or is on a bridge or in a tunnel */ GetNewVehiclePosResult gp = GetNewVehiclePos(v); @@ -1373,10 +1375,10 @@ static bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *p /* Get move position data for next frame. * For a drive-through road stop use 'straight road' move data. - * In this case v->u.road.state is masked to give the road stop entry direction. */ - RoadDriveEntry rd = _road_drive_data[v->u.road.roadtype][( - (HasBit(v->u.road.state, RVS_IN_DT_ROAD_STOP) ? v->u.road.state & RVSB_ROAD_STOP_TRACKDIR_MASK : v->u.road.state) + - (_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking][v->u.road.frame + 1]; + * In this case v->state is masked to give the road stop entry direction. */ + RoadDriveEntry rd = _road_drive_data[v->roadtype][( + (HasBit(v->state, RVS_IN_DT_ROAD_STOP) ? v->state & RVSB_ROAD_STOP_TRACKDIR_MASK : v->state) + + (_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)) ^ v->overtaking][v->frame + 1]; if (rd.x & RDE_NEXT_TILE) { TileIndex tile = v->tile + TileOffsByDiagDir((DiagDirection)(rd.x & 3)); @@ -1399,7 +1401,7 @@ again: uint start_frame = RVC_DEFAULT_START_FRAME; if (IsReversingRoadTrackdir(dir)) { /* Turning around */ - if (v->u.road.roadtype == ROADTYPE_TRAM) { + if (v->roadtype == ROADTYPE_TRAM) { /* Determine the road bits the tram needs to be able to turn around * using the 'big' corner loop. */ RoadBits needed; @@ -1451,7 +1453,7 @@ again: } /* Get position data for first frame on the new tile */ - const RoadDriveEntry *rdp = _road_drive_data[v->u.road.roadtype][(dir + (_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking]; + const RoadDriveEntry *rdp = _road_drive_data[v->roadtype][(dir + (_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)) ^ v->overtaking]; int x = TileX(tile) * TILE_SIZE + rdp[start_frame].x; int y = TileY(tile) * TILE_SIZE + rdp[start_frame].y; @@ -1476,8 +1478,8 @@ again: goto again; } - if (IsInsideMM(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && IsTileType(v->tile, MP_STATION)) { - if (IsReversingRoadTrackdir(dir) && IsInsideMM(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) { + if (IsInsideMM(v->state, RVSB_IN_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && IsTileType(v->tile, MP_STATION)) { + if (IsReversingRoadTrackdir(dir) && IsInsideMM(v->state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) { /* New direction is trying to turn vehicle around. * We can't turn at the exit of a road stop so wait.*/ v->cur_speed = 0; @@ -1488,9 +1490,9 @@ again: /* Vehicle is leaving a road stop tile, mark bay as free * For drive-through stops, only do it if the vehicle stopped here */ - if (IsStandardRoadStopTile(v->tile) || HasBit(v->u.road.state, RVS_IS_STOPPING)) { - rs->FreeBay(HasBit(v->u.road.state, RVS_USING_SECOND_BAY)); - ClrBit(v->u.road.state, RVS_IS_STOPPING); + if (IsStandardRoadStopTile(v->tile) || HasBit(v->state, RVS_IS_STOPPING)) { + rs->FreeBay(HasBit(v->state, RVS_USING_SECOND_BAY)); + ClrBit(v->state, RVS_IS_STOPPING); } if (IsStandardRoadStopTile(v->tile)) rs->SetEntranceBusy(false); } @@ -1498,8 +1500,8 @@ again: if (!HasBit(r, VETS_ENTERED_WORMHOLE)) { v->tile = tile; - v->u.road.state = (byte)dir; - v->u.road.frame = start_frame; + v->state = (byte)dir; + v->frame = start_frame; } if (new_dir != v->direction) { v->direction = new_dir; @@ -1517,7 +1519,7 @@ again: uint turn_around_start_frame = RVC_TURN_AROUND_START_FRAME; RoadBits tram; - if (v->u.road.roadtype == ROADTYPE_TRAM && !IsRoadDepotTile(v->tile) && CountBits(tram = GetAnyRoadBits(v->tile, ROADTYPE_TRAM, true)) == 1) { + if (v->roadtype == ROADTYPE_TRAM && !IsRoadDepotTile(v->tile) && CountBits(tram = GetAnyRoadBits(v->tile, ROADTYPE_TRAM, true)) == 1) { /* * The tram is turning around with one tram 'roadbit'. This means that * it is using the 'big' corner 'drive data'. However, to support the @@ -1549,7 +1551,7 @@ again: return false; } - const RoadDriveEntry *rdp = _road_drive_data[v->u.road.roadtype][(_settings_game.vehicle.road_side << RVS_DRIVE_SIDE) + dir]; + const RoadDriveEntry *rdp = _road_drive_data[v->roadtype][(_settings_game.vehicle.road_side << RVS_DRIVE_SIDE) + dir]; int x = TileX(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].x; int y = TileY(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].y; @@ -1563,8 +1565,8 @@ again: return false; } - v->u.road.state = dir; - v->u.road.frame = turn_around_start_frame; + v->state = dir; + v->frame = turn_around_start_frame; if (new_dir != v->direction) { v->direction = new_dir; @@ -1580,7 +1582,7 @@ again: * it's on a depot tile, check if it's time to activate the next vehicle in * the chain yet. */ if (v->Next() != NULL && IsRoadDepotTile(v->tile)) { - if (v->u.road.frame == v->u.road.cached_veh_length + RVC_DEPOT_START_FRAME) { + if (v->frame == v->cached_veh_length + RVC_DEPOT_START_FRAME) { RoadVehLeaveDepot(v->Next(), false); } } @@ -1591,7 +1593,7 @@ again: Direction new_dir = RoadVehGetSlidingDirection(v, x, y); - if (IsRoadVehFront(v) && !IsInsideMM(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) { + if (IsRoadVehFront(v) && !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); @@ -1599,8 +1601,8 @@ again: if (u != NULL) { u = u->First(); /* There is a vehicle in front overtake it if possible */ - if (v->u.road.overtaking == 0) RoadVehCheckOvertake(v, u); - if (v->u.road.overtaking == 0) v->cur_speed = u->cur_speed; + if (v->overtaking == 0) RoadVehCheckOvertake(v, u); + if (v->overtaking == 0) v->cur_speed = u->cur_speed; return false; } } @@ -1609,7 +1611,7 @@ again: if (new_dir != old_dir) { v->direction = new_dir; v->cur_speed -= (v->cur_speed >> 2); - if (old_dir != v->u.road.state) { + if (old_dir != v->state) { /* The vehicle is in a road stop */ v->UpdateDeltaXY(v->direction); SetRoadVehPosition(v, v->x_pos, v->y_pos); @@ -1625,13 +1627,13 @@ 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->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) && - _road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) || - (IsInsideMM(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && + if (IsRoadVehFront(v) && ((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)) && v->owner == GetTileOwner(v->tile) && GetRoadStopType(v->tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK) && - v->u.road.frame == RVC_DRIVE_THROUGH_STOP_FRAME))) { + v->frame == RVC_DRIVE_THROUGH_STOP_FRAME))) { RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile)); Station *st = GetStationByTile(v->tile); @@ -1650,15 +1652,15 @@ again: if (IsDriveThroughStopTile(next_tile) && (GetRoadStopType(next_tile) == type) && GetStationIndex(v->tile) == GetStationIndex(next_tile)) { RoadStop *rs_n = GetRoadStopByTile(next_tile, type); - if (rs_n->IsFreeBay(HasBit(v->u.road.state, RVS_USING_SECOND_BAY)) && rs_n->num_vehicles < RoadStop::MAX_VEHICLES) { + if (rs_n->IsFreeBay(HasBit(v->state, RVS_USING_SECOND_BAY)) && rs_n->num_vehicles < RoadStop::MAX_VEHICLES) { /* Bay in next stop along is free - use it */ ClearSlot(v); rs_n->num_vehicles++; - v->u.road.slot = rs_n; + v->slot = rs_n; v->dest_tile = rs_n->xy; - v->u.road.slot_age = 14; + v->slot_age = 14; - v->u.road.frame++; + v->frame++; RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y)); return true; } @@ -1687,10 +1689,10 @@ again: if (IsStandardRoadStopTile(v->tile)) rs->SetEntranceBusy(true); - if (rs == v->u.road.slot) { + if (rs == v->slot) { /* We are leaving the correct station */ ClearSlot(v); - } else if (v->u.road.slot != NULL) { + } else if (v->slot != NULL) { /* We are leaving the wrong station * XXX The question is .. what to do? Actually we shouldn't be here * but I guess we need to clear the slot */ @@ -1698,8 +1700,8 @@ again: if (v->tile != v->dest_tile) { DEBUG(ms, 2, " current tile 0x%X is not destination tile 0x%X. Route problem", v->tile, v->dest_tile); } - if (v->dest_tile != v->u.road.slot->xy) { - DEBUG(ms, 2, " stop tile 0x%X is not destination tile 0x%X. Multistop desync", v->u.road.slot->xy, v->dest_tile); + if (v->dest_tile != v->slot->xy) { + DEBUG(ms, 2, " stop tile 0x%X is not destination tile 0x%X. Multistop desync", v->slot->xy, v->dest_tile); } if (!v->current_order.IsType(OT_GOTO_STATION)) { DEBUG(ms, 2, " current order type (%d) is not OT_GOTO_STATION", v->current_order.GetType()); @@ -1732,7 +1734,7 @@ again: /* Move to next frame unless vehicle arrived at a stop position * in a depot or entered a tunnel/bridge */ - if (!HasBit(r, VETS_ENTERED_WORMHOLE)) v->u.road.frame++; + if (!HasBit(r, VETS_ENTERED_WORMHOLE)) v->frame++; v->UpdateDeltaXY(v->direction); RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y)); @@ -1744,7 +1746,7 @@ static bool RoadVehController(RoadVehicle *v) /* decrease counters */ v->tick_counter++; v->current_order_time++; - if (v->u.road.reverse_ctr != 0) v->u.road.reverse_ctr--; + if (v->reverse_ctr != 0) v->reverse_ctr--; /* handle crashed */ if (v->vehstatus & VS_CRASHED) { @@ -1824,7 +1826,7 @@ bool RoadVehicle::Tick() static void CheckIfRoadVehNeedsService(RoadVehicle *v) { /* If we already got a slot at a stop, use that FIRST, and go to a depot later */ - if (v->u.road.slot != NULL || _settings_game.vehicle.servint_roadveh == 0 || !v->NeedsAutomaticServicing()) return; + if (v->slot != NULL || _settings_game.vehicle.servint_roadveh == 0 || !v->NeedsAutomaticServicing()) return; if (v->IsInDepot()) { VehicleServiceInDepot(v); return; @@ -1860,7 +1862,7 @@ void RoadVehicle::OnNewDay() if (!IsRoadVehFront(this)) return; if ((++this->day_counter & 7) == 0) DecreaseVehicleValue(this); - if (this->u.road.blocked_ctr == 0) CheckVehicleBreakdown(this); + if (this->blocked_ctr == 0) CheckVehicleBreakdown(this); AgeVehicle(this); CheckIfRoadVehNeedsService(this); @@ -1868,14 +1870,14 @@ void RoadVehicle::OnNewDay() CheckOrders(this); /* Current slot has expired */ - if (this->current_order.IsType(OT_GOTO_STATION) && this->u.road.slot != NULL && this->u.road.slot_age-- == 0) { + if (this->current_order.IsType(OT_GOTO_STATION) && this->slot != NULL && this->slot_age-- == 0) { DEBUG(ms, 3, "Slot expired for vehicle %d (index %d) at stop 0x%X", - this->unitnumber, this->index, this->u.road.slot->xy); + this->unitnumber, this->index, this->slot->xy); ClearSlot(this); } /* update destination */ - if (!(this->vehstatus & VS_STOPPED) && this->current_order.IsType(OT_GOTO_STATION) && !(this->current_order.GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) && this->u.road.slot == NULL && !(this->vehstatus & VS_CRASHED)) { + if (!(this->vehstatus & VS_STOPPED) && this->current_order.IsType(OT_GOTO_STATION) && !(this->current_order.GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) && this->slot == NULL && !(this->vehstatus & VS_CRASHED)) { Station *st = Station::Get(this->current_order.GetDestination()); RoadStop *rs = st->GetPrimaryRoadStop(this); RoadStop *best = NULL; @@ -1921,9 +1923,9 @@ void RoadVehicle::OnNewDay() best->num_vehicles++; DEBUG(ms, 3, "Assigned to stop 0x%X", best->xy); - this->u.road.slot = best; + this->slot = best; this->dest_tile = best->xy; - this->u.road.slot_age = 14; + this->slot_age = 14; } else { DEBUG(ms, 3, "Could not find a suitable stop"); } @@ -1965,11 +1967,11 @@ Trackdir RoadVehicle::GetVehicleTrackdir() const } /* Drive through road stops / wormholes (tunnels) */ - if (this->u.road.state > RVSB_TRACKDIR_MASK) return DiagDirToDiagTrackdir(DirToDiagDir(this->direction)); + if (this->state > RVSB_TRACKDIR_MASK) return DiagDirToDiagTrackdir(DirToDiagDir(this->direction)); /* If vehicle's state is a valid track direction (vehicle is not turning around) return it, * otherwise transform it into a valid track direction */ - return (Trackdir)((IsReversingRoadTrackdir((Trackdir)this->u.road.state)) ? (this->u.road.state - 6) : this->u.road.state); + return (Trackdir)((IsReversingRoadTrackdir((Trackdir)this->state)) ? (this->state - 6) : this->state); } diff --git a/src/roadveh_gui.cpp b/src/roadveh_gui.cpp index 96130851d2..58d0d06330 100644 --- a/src/roadveh_gui.cpp +++ b/src/roadveh_gui.cpp @@ -130,7 +130,7 @@ void DrawRoadVehImage(const Vehicle *v, int x, int y, VehicleID selection, int c int highlight_w = 0; for (int dx = 0; v != NULL && dx < max_length ; v = v->Next()) { - int width = v->u.road.cached_veh_length; + int width = ((RoadVehicle *)v)->cached_veh_length; if (dx + width > 0 && dx <= max_length) { SpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v); diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index f32af8537e..088aef84f0 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -914,7 +914,7 @@ bool AfterLoadGame() if (v->type == VEH_TRAIN) { v->u.rail.track = TRACK_BIT_WORMHOLE; } else { - v->u.road.state = RVSB_WORMHOLE; + ((RoadVehicle *)v)->state = RVSB_WORMHOLE; } } } @@ -1049,15 +1049,18 @@ bool AfterLoadGame() Vehicle *v; FOR_ALL_VEHICLES(v) { if (v->type == VEH_ROAD) { - v->vehstatus &= ~0x40; - v->u.road.slot = NULL; - v->u.road.slot_age = 0; + RoadVehicle *rv = (RoadVehicle *)v; + rv->vehstatus &= ~0x40; + rv->slot = NULL; + rv->slot_age = 0; } } } else { Vehicle *v; FOR_ALL_VEHICLES(v) { - if (v->type == VEH_ROAD && v->u.road.slot != NULL) v->u.road.slot->num_vehicles++; + if (v->type != VEH_ROAD) continue; + RoadVehicle *rv = (RoadVehicle *)v; + if (rv->slot != NULL) rv->slot->num_vehicles++; } } @@ -1373,8 +1376,10 @@ bool AfterLoadGame() /* In some old savegames a bit was cleared when it should not be cleared */ Vehicle *v; FOR_ALL_VEHICLES(v) { - if (v->type == VEH_ROAD && (v->u.road.state == 250 || v->u.road.state == 251)) { - SetBit(v->u.road.state, RVS_IS_STOPPING); + if (v->type != VEH_ROAD) continue; + RoadVehicle *rv = (RoadVehicle *)v; + if (rv->state == 250 || rv->state == 251) { + SetBit(rv->state, RVS_IS_STOPPING); } } } diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index d1186559c8..842db05dfb 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -175,10 +175,11 @@ void FixOldVehicles() v->name = CopyFromOldName(_old_vehicle_names[v->index]); /* We haven't used this bit for stations for ages */ - if (v->type == VEH_ROAD && - v->u.road.state != RVSB_IN_DEPOT && - v->u.road.state != RVSB_WORMHOLE) { - ClrBit(v->u.road.state, RVS_IS_STOPPING); + if (v->type == VEH_ROAD) { + RoadVehicle *rv = (RoadVehicle *)v; + if (rv->state != RVSB_IN_DEPOT && rv->state != RVSB_WORMHOLE) { + ClrBit(rv->state, RVS_IS_STOPPING); + } } /* The subtype should be 0, but it sometimes isn't :( */ @@ -1089,13 +1090,13 @@ static const OldChunks vehicle_train_chunk[] = { }; static const OldChunks vehicle_road_chunk[] = { - OCL_SVAR( OC_UINT8, VehicleRoad, state ), - OCL_SVAR( OC_UINT8, VehicleRoad, frame ), - OCL_SVAR( OC_UINT16, VehicleRoad, blocked_ctr ), - OCL_SVAR( OC_UINT8, VehicleRoad, overtaking ), - OCL_SVAR( OC_UINT8, VehicleRoad, overtaking_ctr ), - OCL_SVAR( OC_UINT16, VehicleRoad, crashed_ctr ), - OCL_SVAR( OC_UINT8, VehicleRoad, reverse_ctr ), + OCL_SVAR( OC_UINT8, RoadVehicle, state ), + OCL_SVAR( OC_UINT8, RoadVehicle, frame ), + OCL_SVAR( OC_UINT16, RoadVehicle, blocked_ctr ), + OCL_SVAR( OC_UINT8, RoadVehicle, overtaking ), + OCL_SVAR( OC_UINT8, RoadVehicle, overtaking_ctr ), + OCL_SVAR( OC_UINT16, RoadVehicle, crashed_ctr ), + OCL_SVAR( OC_UINT8, RoadVehicle, reverse_ctr ), OCL_NULL( 1 ), ///< Junk @@ -1157,7 +1158,7 @@ static bool LoadOldVehicleUnion(LoadgameState *ls, int num) switch (v->type) { default: NOT_REACHED(); case VEH_TRAIN : res = LoadChunk(ls, &v->u.rail, vehicle_train_chunk); break; - case VEH_ROAD : res = LoadChunk(ls, &v->u.road, vehicle_road_chunk); break; + case VEH_ROAD : res = LoadChunk(ls, v, vehicle_road_chunk); break; case VEH_SHIP : res = LoadChunk(ls, v, vehicle_ship_chunk); break; case VEH_AIRCRAFT: res = LoadChunk(ls, v, vehicle_air_chunk); break; case VEH_EFFECT : res = LoadChunk(ls, v, vehicle_effect_chunk); break; diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index fdfb946666..10b7f3614b 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -253,7 +253,7 @@ void AfterLoadVehicles(bool part_of_load) if (part_of_load) v->fill_percent_te_id = INVALID_TE_ID; v->first = NULL; if (v->type == VEH_TRAIN) v->u.rail.first_engine = INVALID_ENGINE; - if (v->type == VEH_ROAD) v->u.road.first_engine = INVALID_ENGINE; + if (v->type == VEH_ROAD) ((RoadVehicle *)v)->first_engine = INVALID_ENGINE; v->cargo.InvalidateCache(); } @@ -344,9 +344,11 @@ void AfterLoadVehicles(bool part_of_load) FOR_ALL_VEHICLES(v) { switch (v->type) { - case VEH_ROAD: - v->u.road.roadtype = HasBit(EngInfo(v->First()->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD; - v->u.road.compatible_roadtypes = RoadTypeToRoadTypes(v->u.road.roadtype); + case VEH_ROAD: { + RoadVehicle *rv = (RoadVehicle *)v; + rv->roadtype = HasBit(EngInfo(v->First()->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD; + rv->compatible_roadtypes = RoadTypeToRoadTypes(rv->roadtype); + } /* FALL THROUGH */ case VEH_TRAIN: case VEH_SHIP: @@ -542,19 +544,19 @@ const SaveLoad *GetVehicleDescription(VehicleType vt) static const SaveLoad _roadveh_desc[] = { SLE_WRITEBYTE(Vehicle, type, VEH_ROAD), SLE_VEH_INCLUDEX(), - SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, state), SLE_UINT8), - SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, frame), SLE_UINT8), - SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, blocked_ctr), SLE_UINT16), - SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking), SLE_UINT8), - SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking_ctr), SLE_UINT8), - SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, crashed_ctr), SLE_UINT16), - SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, reverse_ctr), SLE_UINT8), + SLE_VAR(RoadVehicle, state, SLE_UINT8), + SLE_VAR(RoadVehicle, frame, SLE_UINT8), + SLE_VAR(RoadVehicle, blocked_ctr, SLE_UINT16), + SLE_VAR(RoadVehicle, overtaking, SLE_UINT8), + SLE_VAR(RoadVehicle, overtaking_ctr, SLE_UINT8), + SLE_VAR(RoadVehicle, crashed_ctr, SLE_UINT16), + SLE_VAR(RoadVehicle, reverse_ctr, SLE_UINT8), - SLE_CONDREFX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot), REF_ROADSTOPS, 6, SL_MAX_VERSION), - SLE_CONDNULL(1, 6, SL_MAX_VERSION), - SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot_age), SLE_UINT8, 6, SL_MAX_VERSION), + SLE_CONDREF(RoadVehicle, slot, REF_ROADSTOPS, 6, SL_MAX_VERSION), + SLE_CONDNULL(1, 6, SL_MAX_VERSION), + SLE_CONDVAR(RoadVehicle, slot_age, SLE_UINT8, 6, SL_MAX_VERSION), /* reserve extra space in savegame here. (currently 16 bytes) */ - SLE_CONDNULL(16, 2, SL_MAX_VERSION), + SLE_CONDNULL(16, 2, SL_MAX_VERSION), SLE_END() }; diff --git a/src/station.cpp b/src/station.cpp index 8f5dfd3f23..c3a3c4e385 100644 --- a/src/station.cpp +++ b/src/station.cpp @@ -114,7 +114,7 @@ RoadStop *Station::GetPrimaryRoadStop(const RoadVehicle *v) const for (; rs != NULL; rs = rs->next) { /* The vehicle cannot go to this roadstop (different roadtype) */ - if ((GetRoadTypes(rs->xy) & v->u.road.compatible_roadtypes) == ROADTYPES_NONE) continue; + 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; @@ -462,7 +462,7 @@ RoadStop::~RoadStop() if (v->type != VEH_ROAD) continue; RoadVehicle *rv = (RoadVehicle *)v; - if (rv->u.road.slot == this) ClearSlot(rv); + if (rv->slot == this) ClearSlot(rv); } } assert(num_vehicles == 0); @@ -542,7 +542,7 @@ RoadStop *RoadStop::GetNextRoadStop(const RoadVehicle *v) const { for (RoadStop *rs = this->next; rs != NULL; rs = rs->next) { /* The vehicle cannot go to this roadstop (different roadtype) */ - if ((GetRoadTypes(rs->xy) & v->u.road.compatible_roadtypes) == ROADTYPES_NONE) continue; + 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; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 8076b95a28..7c7e712f7d 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -1488,7 +1488,7 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin static Vehicle *ClearRoadStopStatusEnum(Vehicle *v, void *) { - if (v->type == VEH_ROAD) ClrBit(v->u.road.state, RVS_IN_DT_ROAD_STOP); + if (v->type == VEH_ROAD) ClrBit(((RoadVehicle *)v)->state, RVS_IN_DT_ROAD_STOP); return NULL; } @@ -2649,30 +2649,31 @@ static VehicleEnterTileStatus VehicleEnter_Station(Vehicle *v, TileIndex tile, i } } } else if (v->type == VEH_ROAD) { - if (v->u.road.state < RVSB_IN_ROAD_STOP && !IsReversingRoadTrackdir((Trackdir)v->u.road.state) && v->u.road.frame == 0) { + RoadVehicle *rv = (RoadVehicle *)v; + if (rv->state < RVSB_IN_ROAD_STOP && !IsReversingRoadTrackdir((Trackdir)rv->state) && rv->frame == 0) { if (IsRoadStop(tile) && IsRoadVehFront(v)) { /* Attempt to allocate a parking bay in a road stop */ RoadStop *rs = GetRoadStopByTile(tile, GetRoadStopType(tile)); if (IsDriveThroughStopTile(tile)) { - if (!v->current_order.ShouldStopAtStation(v, station_id)) return VETSB_CONTINUE; + if (!rv->current_order.ShouldStopAtStation(v, station_id)) return VETSB_CONTINUE; /* Vehicles entering a drive-through stop from the 'normal' side use first bay (bay 0). */ - byte side = ((DirToDiagDir(v->direction) == ReverseDiagDir(GetRoadStopDir(tile))) == (v->u.road.overtaking == 0)) ? 0 : 1; + byte side = ((DirToDiagDir(rv->direction) == ReverseDiagDir(GetRoadStopDir(tile))) == (rv->overtaking == 0)) ? 0 : 1; if (!rs->IsFreeBay(side)) return VETSB_CANNOT_ENTER; /* Check if the vehicle is stopping at this road stop */ - if (GetRoadStopType(tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK) && - v->current_order.GetDestination() == GetStationIndex(tile)) { - SetBit(v->u.road.state, RVS_IS_STOPPING); + if (GetRoadStopType(tile) == (IsCargoInClass(rv->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK) && + rv->current_order.GetDestination() == GetStationIndex(tile)) { + SetBit(rv->state, RVS_IS_STOPPING); rs->AllocateDriveThroughBay(side); } /* Indicate if vehicle is using second bay. */ - if (side == 1) SetBit(v->u.road.state, RVS_USING_SECOND_BAY); + if (side == 1) SetBit(rv->state, RVS_USING_SECOND_BAY); /* Indicate a drive-through stop */ - SetBit(v->u.road.state, RVS_IN_DT_ROAD_STOP); + SetBit(rv->state, RVS_IN_DT_ROAD_STOP); return VETSB_CONTINUE; } @@ -2680,11 +2681,11 @@ static VehicleEnterTileStatus VehicleEnter_Station(Vehicle *v, TileIndex tile, i * 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; - SetBit(v->u.road.state, RVS_IN_ROAD_STOP); + SetBit(rv->state, RVS_IN_ROAD_STOP); /* Allocate a bay and update the road state */ uint bay_nr = rs->AllocateBay(); - SB(v->u.road.state, RVS_USING_SECOND_BAY, 1, bay_nr); + SB(rv->state, RVS_USING_SECOND_BAY, 1, bay_nr); /* Mark the station entrace as busy */ rs->SetEntranceBusy(true); diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 26f5b66352..9a20e31cb4 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -16,6 +16,7 @@ #include "variables.h" #include "train.h" #include "ship.h" +#include "roadveh.h" #include "water_map.h" #include "yapf/yapf.h" #include "newgrf_sound.h" @@ -1412,16 +1413,17 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti return VETSB_ENTERED_WORMHOLE; } } else if (v->type == VEH_ROAD) { + RoadVehicle *rv = (RoadVehicle *)v; fc = (x & 0xF) + (y << 4); vdir = DirToDiagDir(v->direction); /* Enter tunnel? */ - if (v->u.road.state != RVSB_WORMHOLE && dir == vdir) { + if (rv->state != RVSB_WORMHOLE && dir == vdir) { if (fc == _tunnel_fractcoord_4[dir] || fc == _tunnel_fractcoord_5[dir]) { - v->tile = tile; - v->u.road.state = RVSB_WORMHOLE; - v->vehstatus |= VS_HIDDEN; + rv->tile = tile; + rv->state = RVSB_WORMHOLE; + rv->vehstatus |= VS_HIDDEN; return VETSB_ENTERED_WORMHOLE; } else { return VETSB_CONTINUE; @@ -1434,10 +1436,10 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti fc == _tunnel_fractcoord_7[dir] ) && z == 0) { - v->tile = tile; - v->u.road.state = _road_exit_tunnel_state[dir]; - v->u.road.frame = _road_exit_tunnel_frame[dir]; - v->vehstatus &= ~VS_HIDDEN; + rv->tile = tile; + rv->state = _road_exit_tunnel_state[dir]; + rv->frame = _road_exit_tunnel_frame[dir]; + rv->vehstatus &= ~VS_HIDDEN; return VETSB_ENTERED_WORMHOLE; } } @@ -1467,11 +1469,11 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti break; case VEH_ROAD: - v->u.road.state = RVSB_WORMHOLE; + ((RoadVehicle *)v)->state = RVSB_WORMHOLE; break; case VEH_SHIP: - static_cast(v)->state = TRACK_BIT_WORMHOLE; + ((Ship *)v)->state = TRACK_BIT_WORMHOLE; break; default: NOT_REACHED(); @@ -1487,20 +1489,22 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti } break; - case VEH_ROAD: - if (v->u.road.state == RVSB_WORMHOLE) { - v->u.road.state = _road_exit_tunnel_state[dir]; - v->u.road.frame = 0; + case VEH_ROAD: { + RoadVehicle *rv = (RoadVehicle *)v; + if (rv->state == RVSB_WORMHOLE) { + rv->state = _road_exit_tunnel_state[dir]; + rv->frame = 0; return VETSB_ENTERED_WORMHOLE; } - break; + } break; - case VEH_SHIP: - if (static_cast(v)->state == TRACK_BIT_WORMHOLE) { - static_cast(v)->state = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y); + case VEH_SHIP: { + Ship *ship = (Ship *)v; + if (ship->state == TRACK_BIT_WORMHOLE) { + ship->state = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y); return VETSB_ENTERED_WORMHOLE; } - break; + } break; default: NOT_REACHED(); } diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 95f23beb90..fc936d5558 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -1426,7 +1426,7 @@ SpriteID GetVehiclePalette(const Vehicle *v) if (v->type == VEH_TRAIN) { return GetEngineColourMap(v->engine_type, v->owner, v->u.rail.first_engine, v); } else if (v->type == VEH_ROAD) { - return GetEngineColourMap(v->engine_type, v->owner, v->u.road.first_engine, v); + return GetEngineColourMap(v->engine_type, v->owner, ((RoadVehicle *)v)->first_engine, v); } return GetEngineColourMap(v->engine_type, v->owner, INVALID_ENGINE, v); diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 4719dd7af1..7217f3f304 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -8,7 +8,6 @@ #include "vehicle_type.h" #include "track_type.h" #include "rail_type.h" -#include "road_type.h" #include "cargo_type.h" #include "direction_type.h" #include "gfx_type.h" @@ -25,41 +24,6 @@ #include "order_func.h" #include "transport_type.h" -/** Road vehicle states */ -enum RoadVehicleStates { - /* - * Lower 4 bits are used for vehicle track direction. (Trackdirs) - * When in a road stop (bit 5 or bit 6 set) these bits give the - * track direction of the entry to the road stop. - * As the entry direction will always be a diagonal - * direction (X_NE, Y_SE, X_SW or Y_NW) only bits 0 and 3 - * are needed to hold this direction. Bit 1 is then used to show - * that the vehicle is using the second road stop bay. - * Bit 2 is then used for drive-through stops to show the vehicle - * is stopping at this road stop. - */ - - /* Numeric values */ - RVSB_IN_DEPOT = 0xFE, ///< The vehicle is in a depot - RVSB_WORMHOLE = 0xFF, ///< The vehicle is in a tunnel and/or bridge - - /* Bit numbers */ - RVS_USING_SECOND_BAY = 1, ///< Only used while in a road stop - RVS_IS_STOPPING = 2, ///< Only used for drive-through stops. Vehicle will stop here - RVS_DRIVE_SIDE = 4, ///< Only used when retrieving move data - RVS_IN_ROAD_STOP = 5, ///< The vehicle is in a road stop - RVS_IN_DT_ROAD_STOP = 6, ///< The vehicle is in a drive-through road stop - - /* Bit sets of the above specified bits */ - RVSB_IN_ROAD_STOP = 1 << RVS_IN_ROAD_STOP, ///< The vehicle is in a road stop - RVSB_IN_ROAD_STOP_END = RVSB_IN_ROAD_STOP + TRACKDIR_END, - RVSB_IN_DT_ROAD_STOP = 1 << RVS_IN_DT_ROAD_STOP, ///< The vehicle is in a drive-through road stop - RVSB_IN_DT_ROAD_STOP_END = RVSB_IN_DT_ROAD_STOP + TRACKDIR_END, - - RVSB_TRACKDIR_MASK = 0x0F, ///< The mask used to extract track dirs - RVSB_ROAD_STOP_TRACKDIR_MASK = 0x09 ///< Only bits 0 and 3 are used to encode the trackdir for road stops -}; - enum VehStatus { VS_HIDDEN = 0x01, VS_STOPPED = 0x02, @@ -149,23 +113,6 @@ enum VehicleRailFlags { VRF_TRAIN_STUCK = 8, }; -struct VehicleRoad { - byte state; ///< @see RoadVehicleStates - byte frame; - uint16 blocked_ctr; - byte overtaking; - byte overtaking_ctr; - uint16 crashed_ctr; - byte reverse_ctr; - struct RoadStop *slot; - byte slot_age; - EngineID first_engine; - byte cached_veh_length; - - RoadType roadtype; - RoadTypes compatible_roadtypes; -}; - typedef Pool VehiclePool; extern VehiclePool _vehicle_pool; @@ -295,7 +242,6 @@ public: union { VehicleRail rail; - VehicleRoad road; } u; /* cached oftenly queried NewGRF values */ diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 14b9ae4267..7253820771 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -639,9 +639,9 @@ static int CDECL VehicleLengthSorter(const Vehicle * const *a, const Vehicle * c break; case VEH_ROAD: { - const Vehicle *u; - for (u = *a; u != NULL; u = u->Next()) r += u->u.road.cached_veh_length; - for (u = *b; u != NULL; u = u->Next()) r -= u->u.road.cached_veh_length; + const RoadVehicle *u; + for (u = (RoadVehicle *)*a; u != NULL; u = u->Next()) r += u->cached_veh_length; + for (u = (RoadVehicle *)*b; u != NULL; u = u->Next()) r -= u->cached_veh_length; } break; default: NOT_REACHED(); diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 48f4bdb764..4f157aa55e 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -822,7 +822,7 @@ static void FloodVehicle(Vehicle *v) case VEH_ROAD: if (IsRoadVehFront(v)) pass += 1; // driver - v->u.road.crashed_ctr = 2000; // max 2220, disappear pretty fast + ((RoadVehicle *)v)->crashed_ctr = 2000; // max 2220, disappear pretty fast InvalidateWindowClassesData(WC_ROADVEH_LIST, 0); break; diff --git a/src/yapf/follow_track.hpp b/src/yapf/follow_track.hpp index 531e548a6f..f69e4c1906 100644 --- a/src/yapf/follow_track.hpp +++ b/src/yapf/follow_track.hpp @@ -7,6 +7,7 @@ #include "yapf.hpp" #include "../depot_map.h" +#include "../roadveh.h" /** Track follower helper template class (can serve pathfinders and vehicle * controllers). See 6 different typedefs below for 3 different transport @@ -74,7 +75,7 @@ struct CFollowTrackT FORCEINLINE static TransportType TT() {return Ttr_type_;} FORCEINLINE static bool IsWaterTT() {return TT() == TRANSPORT_WATER;} FORCEINLINE static bool IsRailTT() {return TT() == TRANSPORT_RAIL;} - FORCEINLINE bool IsTram() {return IsRoadTT() && HasBit(m_veh->u.road.compatible_roadtypes, ROADTYPE_TRAM);} + FORCEINLINE bool IsTram() {return IsRoadTT() && HasBit(((RoadVehicle *)m_veh)->compatible_roadtypes, ROADTYPE_TRAM);} FORCEINLINE static bool IsRoadTT() {return TT() == TRANSPORT_ROAD;} FORCEINLINE static bool Allow90degTurns() {return T90deg_turns_allowed_;} FORCEINLINE static bool DoTrackMasking() {return IsRailTT() && Tmask_reserved_tracks;} @@ -205,7 +206,7 @@ protected: if (IsRailTT() && IsPlainRailTile(m_new_tile)) { m_new_td_bits = (TrackdirBits)(GetTrackBits(m_new_tile) * 0x101); } else { - m_new_td_bits = TrackStatusToTrackdirBits(GetTileTrackStatus(m_new_tile, TT(), m_veh != NULL ? m_veh->u.road.compatible_roadtypes : 0)); + m_new_td_bits = TrackStatusToTrackdirBits(GetTileTrackStatus(m_new_tile, TT(), m_veh != NULL ? ((RoadVehicle *)m_veh)->compatible_roadtypes : 0)); if (IsTram() && m_new_td_bits == 0) { /* GetTileTrackStatus() returns 0 for single tram bits. diff --git a/src/yapf/yapf_road.cpp b/src/yapf/yapf_road.cpp index facfec14af..75dbc9e279 100644 --- a/src/yapf/yapf_road.cpp +++ b/src/yapf/yapf_road.cpp @@ -4,6 +4,7 @@ #include "../stdafx.h" #include "../depot_base.h" +#include "../roadveh.h" #include "yapf.hpp" #include "yapf_node_road.hpp" @@ -298,13 +299,13 @@ public: /* our source tile will be the next vehicle tile (should be the given one) */ TileIndex src_tile = tile; /* get available trackdirs on the start tile */ - TrackdirBits src_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes)); + TrackdirBits src_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, ((RoadVehicle *)v)->compatible_roadtypes)); /* select reachable trackdirs only */ src_trackdirs &= DiagdirReachesTrackdirs(enterdir); /* get available trackdirs on the destination tile */ TileIndex dest_tile = v->dest_tile; - TrackdirBits dest_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(dest_tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes)); + TrackdirBits dest_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(dest_tile, TRANSPORT_ROAD, ((RoadVehicle *)v)->compatible_roadtypes)); /* set origin and destination nodes */ Yapf().SetOrigin(src_tile, src_trackdirs); @@ -348,7 +349,7 @@ public: /* set destination tile, trackdir * get available trackdirs on the destination tile */ - TrackdirBits dst_td_bits = TrackStatusToTrackdirBits(GetTileTrackStatus(dst_tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes)); + TrackdirBits dst_td_bits = TrackStatusToTrackdirBits(GetTileTrackStatus(dst_tile, TRANSPORT_ROAD, ((RoadVehicle *)v)->compatible_roadtypes)); Yapf().SetDestination(dst_tile, dst_td_bits); /* if path not found - return distance = UINT_MAX */ @@ -373,7 +374,7 @@ public: /* set origin (tile, trackdir) */ TileIndex src_tile = v->tile; Trackdir src_td = v->GetVehicleTrackdir(); - if ((TrackStatusToTrackdirBits(GetTileTrackStatus(src_tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes)) & TrackdirToTrackdirBits(src_td)) == 0) { + if ((TrackStatusToTrackdirBits(GetTileTrackStatus(src_tile, TRANSPORT_ROAD, ((RoadVehicle *)v)->compatible_roadtypes)) & TrackdirToTrackdirBits(src_td)) == 0) { /* sometimes the roadveh is not on the road (it resides on non-existing track) * how should we handle that situation? */ return false; @@ -470,7 +471,7 @@ Depot *YapfFindNearestRoadDepot(const Vehicle *v) { TileIndex tile = v->tile; Trackdir trackdir = v->GetVehicleTrackdir(); - if ((TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes)) & TrackdirToTrackdirBits(trackdir)) == 0) { + if ((TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, ((RoadVehicle *)v)->compatible_roadtypes)) & TrackdirToTrackdirBits(trackdir)) == 0) { return NULL; }