(svn r16390) -Codechange: move u.road to RoadVehicle.

This commit is contained in:
rubidium 2009-05-22 20:22:20 +00:00
parent d37b840cf3
commit 7a37220881
22 changed files with 308 additions and 287 deletions

View File

@ -45,7 +45,7 @@
case VEH_ROAD: { case VEH_ROAD: {
uint total_length = 0; uint total_length = 0;
for (const Vehicle *u = v; u != NULL; u = u->Next()) { 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; return total_length;
} }
@ -368,7 +368,7 @@
if (!IsValidVehicle(vehicle_id)) return AIRoad::ROADTYPE_INVALID; if (!IsValidVehicle(vehicle_id)) return AIRoad::ROADTYPE_INVALID;
if (GetVehicleType(vehicle_id) != VT_ROAD) 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) /* static */ int32 AIVehicle::GetCapacity(VehicleID vehicle_id, CargoID cargo)

View File

@ -327,28 +327,30 @@ void AddArticulatedParts(Vehicle *first, VehicleType type)
SetArticulatedPart(u); SetArticulatedPart(u);
break; break;
case VEH_ROAD: case VEH_ROAD: {
u = new RoadVehicle(); RoadVehicle *front = (RoadVehicle *)v;
u->subtype = 0; RoadVehicle *rv = new RoadVehicle();
rv->subtype = 0;
previous->SetNext(u); previous->SetNext(u);
u->u.road.first_engine = v->engine_type; rv->first_engine = front->engine_type;
u->u.road.cached_veh_length = 8; // Callback is called when the consist is finished rv->cached_veh_length = 8; // Callback is called when the consist is finished
u->u.road.state = RVSB_IN_DEPOT; rv->state = RVSB_IN_DEPOT;
u->u.road.roadtype = v->u.road.roadtype; rv->roadtype = front->roadtype;
u->u.road.compatible_roadtypes = v->u.road.compatible_roadtypes; rv->compatible_roadtypes = front->compatible_roadtypes;
u->spritenum = e_artic->u.road.image_index; rv->spritenum = e_artic->image_index;
if (e_artic->CanCarryCargo()) { if (e_artic->CanCarryCargo()) {
u->cargo_type = e_artic->GetDefaultCargoType(); rv->cargo_type = e_artic->GetDefaultCargoType();
u->cargo_cap = e_artic->u.road.capacity; // Callback 36 is called when the consist is finished rv->cargo_cap = e_artic->u.road.capacity; // Callback 36 is called when the consist is finished
} else { } else {
u->cargo_type = v->cargo_type; // Needed for livery selection rv->cargo_type = front->cargo_type; // Needed for livery selection
u->cargo_cap = 0; rv->cargo_cap = 0;
} }
SetRoadVehArticPart(u); SetRoadVehArticPart(rv);
break; u = rv;
} break;
} }
/* get common values from first engine */ /* get common values from first engine */

View File

@ -5,6 +5,7 @@
#include "train.h" #include "train.h"
#include "ship.h" #include "ship.h"
#include "aircraft.h" #include "aircraft.h"
#include "roadveh.h"
#include "gui.h" #include "gui.h"
#include "textbuf_gui.h" #include "textbuf_gui.h"
#include "viewport_func.h" #include "viewport_func.h"
@ -517,7 +518,7 @@ struct DepotWindow : Window {
break; break;
case VEH_ROAD: 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; break;
default: default:

View File

@ -314,11 +314,12 @@ static bool DisasterTick_Ufo(DisasterVehicle *v)
return false; return false;
} else { } else {
/* Target a vehicle */ /* Target a vehicle */
Vehicle *u = Vehicle::Get(v->dest_tile); Vehicle *u_tmp = Vehicle::Get(v->dest_tile);
if (u->type != VEH_ROAD || !IsRoadVehFront(u)) { if (u_tmp->type != VEH_ROAD || !IsRoadVehFront(u_tmp)) {
delete v; delete v;
return false; return false;
} }
RoadVehicle *u = (RoadVehicle *)u_tmp;
uint dist = Delta(v->x_pos, u->x_pos) + Delta(v->y_pos, u->y_pos); 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) { if (z <= u->z_pos && (u->vehstatus & VS_HIDDEN) == 0) {
v->age++; v->age++;
if (u->u.road.crashed_ctr == 0) { if (u->crashed_ctr == 0) {
u->u.road.crashed_ctr++; u->crashed_ctr++;
AddNewsItem(STR_NEWS_DISASTER_SMALL_UFO, AddNewsItem(STR_NEWS_DISASTER_SMALL_UFO,
NS_ACCIDENT_VEHICLE, NS_ACCIDENT_VEHICLE,

View File

@ -5,6 +5,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "debug.h" #include "debug.h"
#include "train.h" #include "train.h"
#include "roadveh.h"
#include "company_func.h" #include "company_func.h"
#include "newgrf_engine.h" #include "newgrf_engine.h"
#include "newgrf_spritegroup.h" #include "newgrf_spritegroup.h"
@ -435,7 +436,7 @@ static uint8 LiveryHelper(EngineID engine, const Vehicle *v)
} else if (v->type == VEH_TRAIN) { } else if (v->type == VEH_TRAIN) {
l = GetEngineLivery(v->engine_type, v->owner, v->u.rail.first_engine, v); l = GetEngineLivery(v->engine_type, v->owner, v->u.rail.first_engine, v);
} else if (v->type == VEH_ROAD) { } 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 { } else {
l = GetEngineLivery(v->engine_type, v->owner, INVALID_ENGINE, v); l = GetEngineLivery(v->engine_type, v->owner, INVALID_ENGINE, v);
} }
@ -780,17 +781,18 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, by
} }
break; break;
case VEH_ROAD: case VEH_ROAD: {
RoadVehicle *rv = (RoadVehicle *)v;
switch (variable - 0x80) { switch (variable - 0x80) {
case 0x62: return v->u.road.state; case 0x62: return rv->state;
case 0x64: return v->u.road.blocked_ctr; case 0x64: return rv->blocked_ctr;
case 0x65: return GB(v->u.road.blocked_ctr, 8, 8); case 0x65: return GB(rv->blocked_ctr, 8, 8);
case 0x66: return v->u.road.overtaking; case 0x66: return rv->overtaking;
case 0x67: return v->u.road.overtaking_ctr; case 0x67: return rv->overtaking_ctr;
case 0x68: return v->u.road.crashed_ctr; case 0x68: return rv->crashed_ctr;
case 0x69: return GB(v->u.road.crashed_ctr, 8, 8); case 0x69: return GB(rv->crashed_ctr, 8, 8);
} }
break; } break;
case VEH_AIRCRAFT: { case VEH_AIRCRAFT: {
Aircraft *a = (Aircraft *)v; 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); 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; if (group != NULL) return group;
} else if (v->type == VEH_ROAD) { } 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; if (group != NULL) return group;
} }
} }

View File

@ -1119,7 +1119,7 @@ void StateGameLoop()
switch (v->type) { switch (v->type) {
case VEH_ROAD: { case VEH_ROAD: {
extern byte GetRoadVehLength(const RoadVehicle *v); 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); DEBUG(desync, 2, "cache mismatch: vehicle %i, company %i, unit number %i\n", v->index, (int)v->owner, v->unitnumber);
} }
} break; } break;

View File

@ -1547,20 +1547,22 @@ static VehicleEnterTileStatus VehicleEnter_Road(Vehicle *v, TileIndex tile, int
} }
break; break;
case ROAD_TILE_DEPOT: case ROAD_TILE_DEPOT: {
if (v->type == VEH_ROAD && if (v->type != VEH_ROAD) break;
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;
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; return VETSB_ENTERED_WORMHOLE;
} }
break; } break;
default: break; default: break;
} }

View File

@ -12,6 +12,41 @@
struct RoadVehicle; 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 */ /** State information about the Road Vehicle controller */
enum { enum {
RDE_NEXT_TILE = 0x80, ///< We should enter the next tile 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. * As side-effect the vehicle type is set correctly.
*/ */
struct RoadVehicle : public Vehicle { 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 */ /** Initializes the Vehicle to a road vehicle */
RoadVehicle() { this->type = VEH_ROAD; } RoadVehicle() { this->type = VEH_ROAD; }
@ -99,7 +149,7 @@ struct RoadVehicle : public Vehicle {
int GetDisplaySpeed() const { return this->cur_speed / 2; } int GetDisplaySpeed() const { return this->cur_speed / 2; }
int GetDisplayMaxSpeed() const { return this->max_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); } 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 IsStoppedInDepot() const;
bool Tick(); bool Tick();
void OnNewDay(); void OnNewDay();

View File

@ -142,10 +142,10 @@ void RoadVehUpdateCache(RoadVehicle *v)
assert(u->First() == v); assert(u->First() == v);
/* Update the 'first engine' */ /* 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. */ /* 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 */ /* Invalidate the vehicle colour map */
u->colourmap = PAL_NONE; u->colourmap = PAL_NONE;
@ -206,7 +206,7 @@ CommandCost CmdBuildRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
// v->running_ticks = 0; // 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->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
v->spritenum = rvi->image_index; 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->load_unload_time_rem = 0;
// v->progress = 0; // v->progress = 0;
// v->u.road.overtaking = 0; // v->overtaking = 0;
v->last_station_visited = INVALID_STATION; v->last_station_visited = INVALID_STATION;
v->max_speed = rvi->max_speed; v->max_speed = rvi->max_speed;
@ -242,9 +242,9 @@ CommandCost CmdBuildRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
v->random_bits = VehicleRandomBits(); v->random_bits = VehicleRandomBits();
SetRoadVehFront(v); SetRoadVehFront(v);
v->u.road.roadtype = HasBit(EngInfo(v->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD; v->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->compatible_roadtypes = RoadTypeToRoadTypes(v->roadtype);
v->u.road.cached_veh_length = 8; v->cached_veh_length = 8;
v->vehicle_flags = 0; v->vehicle_flags = 0;
if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); 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 */ /* Call various callbacks after the whole consist has been constructed */
for (RoadVehicle *u = v; u != NULL; u = u->Next()) { 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 */ /* 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); 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) void ClearSlot(RoadVehicle *v)
{ {
RoadStop *rs = v->u.road.slot; RoadStop *rs = v->slot;
if (v->u.road.slot == NULL) return; if (v->slot == NULL) return;
v->u.road.slot = NULL; v->slot = NULL;
v->u.road.slot_age = 0; v->slot_age = 0;
assert(rs->num_vehicles != 0); assert(rs->num_vehicles != 0);
rs->num_vehicles--; rs->num_vehicles--;
@ -299,7 +299,7 @@ bool RoadVehicle::IsStoppedInDepot() const
if (IsRoadVehFront(this) && !(this->vehstatus & VS_STOPPED)) return false; if (IsRoadVehFront(this) && !(this->vehstatus & VS_STOPPED)) return false;
for (const RoadVehicle *v = this; v != NULL; v = v->Next()) { 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; return true;
} }
@ -366,7 +366,7 @@ static const Depot *FindClosestRoadDepot(const RoadVehicle *v)
/* See where we are now */ /* See where we are now */
Trackdir trackdir = v->GetVehicleTrackdir(); 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 if (ftd.best_bird_dist == 0) return GetDepotByTile(ftd.node.tile); // Target found
} break; } break;
@ -380,7 +380,7 @@ static const Depot *FindClosestRoadDepot(const RoadVehicle *v)
/* search in all directions */ /* search in all directions */
for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) { 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); 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) CommandCost CmdTurnRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{ {
Vehicle *v = Vehicle::GetIfValid(p1); Vehicle *u = Vehicle::GetIfValid(p1);
if (v == NULL || v->type != VEH_ROAD || !CheckOwnership(v->owner)) return CMD_ERROR; if (u == NULL || u->type != VEH_ROAD || !CheckOwnership(u->owner)) return CMD_ERROR;
RoadVehicle *v = (RoadVehicle *)u;
if (v->vehstatus & VS_STOPPED || if (v->vehstatus & VS_STOPPED ||
v->vehstatus & VS_CRASHED || v->vehstatus & VS_CRASHED ||
v->breakdown_ctr != 0 || v->breakdown_ctr != 0 ||
v->u.road.overtaking != 0 || v->overtaking != 0 ||
v->u.road.state == RVSB_WORMHOLE || v->state == RVSB_WORMHOLE ||
v->IsInDepot() || v->IsInDepot() ||
v->cur_speed < 5) { v->cur_speed < 5) {
return CMD_ERROR; 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 (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(); return CommandCost();
} }
@ -494,7 +496,7 @@ static void ClearCrashedStation(RoadVehicle *v)
rs->SetEntranceBusy(false); rs->SetEntranceBusy(false);
/* Free the parking bay */ /* 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) static void DeleteLastRoadVeh(RoadVehicle *v)
@ -542,12 +544,12 @@ static void RoadVehSetRandomDirection(RoadVehicle *v)
static bool RoadVehIsCrashed(RoadVehicle *v) static bool RoadVehIsCrashed(RoadVehicle *v)
{ {
v->u.road.crashed_ctr++; v->crashed_ctr++;
if (v->u.road.crashed_ctr == 2) { if (v->crashed_ctr == 2) {
CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE); 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); 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; bool ret = v->Next() != NULL;
DeleteLastRoadVeh(v); DeleteLastRoadVeh(v);
return ret; return ret;
@ -572,7 +574,7 @@ static void RoadVehCrash(RoadVehicle *v)
{ {
uint16 pass = 1; uint16 pass = 1;
v->u.road.crashed_ctr++; v->crashed_ctr++;
for (Vehicle *u = v; u != NULL; u = u->Next()) { for (Vehicle *u = v; u != NULL; u = u->Next()) {
if (IsCargoInClass(u->cargo_type, CC_PASSENGERS)) pass += u->cargo.Count(); 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) static bool RoadVehCheckTrainCrash(RoadVehicle *v)
{ {
for (RoadVehicle *u = v; u != NULL; u = u->Next()) { 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; TileIndex tile = u->tile;
@ -732,7 +734,7 @@ static RoadVehicle *RoadVehFindCloseTo(RoadVehicle *v, int x, int y, Direction d
RoadVehFindData rvf; RoadVehFindData rvf;
RoadVehicle *front = v->First(); RoadVehicle *front = v->First();
if (front->u.road.reverse_ctr != 0) return NULL; if (front->reverse_ctr != 0) return NULL;
rvf.x = x; rvf.x = x;
rvf.y = y; rvf.y = y;
@ -740,7 +742,7 @@ static RoadVehicle *RoadVehFindCloseTo(RoadVehicle *v, int x, int y, Direction d
rvf.veh = v; rvf.veh = v;
rvf.best_diff = UINT_MAX; rvf.best_diff = UINT_MAX;
if (front->u.road.state == RVSB_WORMHOLE) { if (front->state == RVSB_WORMHOLE) {
FindVehicleOnPos(v->tile, &rvf, EnumCheckRoadVehClose); FindVehicleOnPos(v->tile, &rvf, EnumCheckRoadVehClose);
FindVehicleOnPos(GetOtherTunnelBridgeEnd(v->tile), &rvf, EnumCheckRoadVehClose); FindVehicleOnPos(GetOtherTunnelBridgeEnd(v->tile), &rvf, EnumCheckRoadVehClose);
} else { } 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. * drive just through it. The ultimate backup-code of TTD.
* It can be disabled. */ * It can be disabled. */
if (rvf.best_diff == UINT_MAX) { if (rvf.best_diff == UINT_MAX) {
front->u.road.blocked_ctr = 0; front->blocked_ctr = 0;
return NULL; return NULL;
} }
if (++front->u.road.blocked_ctr > 1480) return NULL; if (++front->blocked_ctr > 1480) return NULL;
return (RoadVehicle *)rvf.best; return (RoadVehicle *)rvf.best;
} }
@ -769,7 +771,7 @@ static void RoadVehArrivesAt(const RoadVehicle *v, Station *st)
st->had_vehicle_of_type |= HVOT_BUS; st->had_vehicle_of_type |= HVOT_BUS;
SetDParam(0, st->index); SetDParam(0, st->index);
AddNewsItem( 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->owner == _local_company) ? NS_ARRIVAL_COMPANY : NS_ARRIVAL_OTHER,
v->index, v->index,
st->index st->index
@ -782,7 +784,7 @@ static void RoadVehArrivesAt(const RoadVehicle *v, Station *st)
st->had_vehicle_of_type |= HVOT_TRUCK; st->had_vehicle_of_type |= HVOT_TRUCK;
SetDParam(0, st->index); SetDParam(0, st->index);
AddNewsItem( 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->owner == _local_company) ? NS_ARRIVAL_COMPANY : NS_ARRIVAL_OTHER,
v->index, v->index,
st->index st->index
@ -795,7 +797,7 @@ static void RoadVehArrivesAt(const RoadVehicle *v, Station *st)
static int RoadVehAccelerate(RoadVehicle *v) static int RoadVehAccelerate(RoadVehicle *v)
{ {
uint oldspeed = v->cur_speed; 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; uint spd = v->subspeed + accel;
v->subspeed = (uint8)spd; 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); v->cur_speed = spd = Clamp(v->cur_speed + ((int)spd >> 8), 0, tempmax);
/* Apply bridge speed limit */ /* 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); 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) 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 trackdirbits = TrackStatusToTrackdirBits(ts);
TrackdirBits red_signals = TrackStatusToRedSignals(ts); // barred level crossing TrackdirBits red_signals = TrackStatusToRedSignals(ts); // barred level crossing
TrackBits trackbits = TrackdirBitsToTrackBits(trackdirbits); TrackBits trackbits = TrackdirBitsToTrackBits(trackdirbits);
@ -903,7 +905,7 @@ static void RoadVehCheckOvertake(RoadVehicle *v, RoadVehicle *u)
} }
/* Trams can't overtake other trams */ /* 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 */ /* Don't overtake in stations */
if (IsTileType(v->tile, MP_STATION)) return; 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; 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 */ /* 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)); od.trackdir = DiagDirToDiagTrackdir(DirToDiagDir(v->direction));
@ -932,12 +934,12 @@ static void RoadVehCheckOvertake(RoadVehicle *v, RoadVehicle *u)
if (CheckRoadBlockedForOvertaking(&od)) return; if (CheckRoadBlockedForOvertaking(&od)) return;
if (od.u->cur_speed == 0 || od.u->vehstatus& VS_STOPPED) { if (od.u->cur_speed == 0 || od.u->vehstatus& VS_STOPPED) {
v->u.road.overtaking_ctr = 0x11; v->overtaking_ctr = 0x11;
v->u.road.overtaking = 0x10; v->overtaking = 0x10;
} else { } else {
// if (CheckRoadBlockedForOvertaking(&od)) return; // if (CheckRoadBlockedForOvertaking(&od)) return;
v->u.road.overtaking_ctr = 0; v->overtaking_ctr = 0;
v->u.road.overtaking = 0x10; v->overtaking = 0x10;
} }
} }
@ -1008,12 +1010,12 @@ static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection
FindRoadToChooseData frd; FindRoadToChooseData frd;
Trackdir best_track; 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 red_signals = TrackStatusToRedSignals(ts); // crossing
TrackdirBits trackdirs = TrackStatusToTrackdirBits(ts); TrackdirBits trackdirs = TrackStatusToTrackdirBits(ts);
if (IsTileType(tile, MP_ROAD)) { 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 */ /* Road depot owned by another company or with the wrong orientation */
trackdirs = TRACKDIR_BIT_NONE; trackdirs = TRACKDIR_BIT_NONE;
} }
@ -1052,9 +1054,9 @@ static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection
return_track(_road_reverse_table[enterdir]); return_track(_road_reverse_table[enterdir]);
} }
if (v->u.road.reverse_ctr != 0) { if (v->reverse_ctr != 0) {
bool reverse = true; 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 /* 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) */ * trackbits or when it is a valid turning tile (i.e. one roadbit) */
RoadBits rb = GetAnyRoadBits(tile, ROADTYPE_TRAM); RoadBits rb = GetAnyRoadBits(tile, ROADTYPE_TRAM);
@ -1063,7 +1065,7 @@ static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection
(rb == DiagDirToRoadBits(enterdir)); (rb == DiagDirToRoadBits(enterdir));
} }
if (reverse) { if (reverse) {
v->u.road.reverse_ctr = 0; v->reverse_ctr = 0;
if (v->tile != tile) { if (v->tile != tile) {
return_track(_road_reverse_table[enterdir]); return_track(_road_reverse_table[enterdir]);
} }
@ -1095,7 +1097,7 @@ static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection
Trackdir trackdir = DiagDirToDiagTrackdir(enterdir); Trackdir trackdir = DiagDirToDiagTrackdir(enterdir);
/* debug("Finding path. Enterdir: %d, Trackdir: %d", enterdir, trackdir); */ /* 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) { if (ftd.best_trackdir == INVALID_TRACKDIR) {
/* We are already at our target. Just do something /* We are already at our target. Just do something
* @todo: maybe display error? * @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 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.maxtracklen = UINT_MAX;
frd.mindist = 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)) { if (frd.mindist < best_dist || (frd.mindist == best_dist && frd.maxtracklen < best_maxlen)) {
best_dist = frd.mindist; best_dist = frd.mindist;
@ -1181,7 +1183,7 @@ static uint RoadFindPathToStop(const RoadVehicle *v, TileIndex tile)
fstd.dest_coords = tile; fstd.dest_coords = tile;
fstd.station_index = INVALID_STATION; // indicates that the destination is a tile, not a station 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 */ /* change units from NPF_TILE_LENGTH to # of tiles */
if (dist != UINT_MAX) dist = (dist + NPF_TILE_LENGTH - 1) / NPF_TILE_LENGTH; 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. */ /* Don't leave if not all the wagons are in the depot. */
for (const RoadVehicle *u = v; u != NULL; u = u->Next()) { 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); DiagDirection dir = GetRoadDepotDirection(v->tile);
v->direction = DiagDirToDir(dir); v->direction = DiagDirToDir(dir);
Trackdir tdir = _roadveh_depot_exit_trackdir[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 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); 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->vehstatus &= ~VS_HIDDEN;
v->u.road.state = tdir; v->state = tdir;
v->u.road.frame = RVC_DEPOT_START_FRAME; v->frame = RVC_DEPOT_START_FRAME;
v->UpdateDeltaXY(v->direction); v->UpdateDeltaXY(v->direction);
SetRoadVehPosition(v, x, y); SetRoadVehPosition(v, x, y);
@ -1248,7 +1250,7 @@ static Trackdir FollowPreviousRoadVehicle(const RoadVehicle *v, const RoadVehicl
return _road_reverse_table[entry_dir]; return _road_reverse_table[entry_dir];
} }
byte prev_state = prev->u.road.state; byte prev_state = prev->state;
Trackdir dir; Trackdir dir;
if (prev_state == RVSB_WORMHOLE || prev_state == RVSB_IN_DEPOT) { 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]; 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; dir = INVALID_TRACKDIR;
} }
@ -1327,16 +1329,16 @@ static bool CanBuildTramTrackOnTile(CompanyID c, TileIndex t, RoadBits r)
static bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev) static bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev)
{ {
if (v->u.road.overtaking != 0) { if (v->overtaking != 0) {
if (IsTileType(v->tile, MP_STATION)) { if (IsTileType(v->tile, MP_STATION)) {
/* Force us to be not overtaking! */ /* Force us to be not overtaking! */
v->u.road.overtaking = 0; v->overtaking = 0;
} else if (++v->u.road.overtaking_ctr >= 35) { } else if (++v->overtaking_ctr >= 35) {
/* If overtaking just aborts at a random moment, we can have a out-of-bound problem, /* 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 * if the vehicle started a corner. To protect that, only allow an abort of
* overtake if we are on straight roads */ * overtake if we are on straight roads */
if (v->u.road.state < RVSB_IN_ROAD_STOP && IsStraightRoadTrackdir((Trackdir)v->u.road.state)) { if (v->state < RVSB_IN_ROAD_STOP && IsStraightRoadTrackdir((Trackdir)v->state)) {
v->u.road.overtaking = 0; 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. */ * by the previous vehicle in the chain when it gets to the right place. */
if (v->IsInDepot()) return true; 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 */ /* Vehicle is entering a depot or is on a bridge or in a tunnel */
GetNewVehiclePosResult gp = GetNewVehiclePos(v); GetNewVehiclePosResult gp = GetNewVehiclePos(v);
@ -1373,10 +1375,10 @@ static bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *p
/* Get move position data for next frame. /* Get move position data for next frame.
* For a drive-through road stop use 'straight road' move data. * 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. */ * In this case v->state is masked to give the road stop entry direction. */
RoadDriveEntry rd = _road_drive_data[v->u.road.roadtype][( RoadDriveEntry rd = _road_drive_data[v->roadtype][(
(HasBit(v->u.road.state, RVS_IN_DT_ROAD_STOP) ? v->u.road.state & RVSB_ROAD_STOP_TRACKDIR_MASK : v->u.road.state) + (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->u.road.overtaking][v->u.road.frame + 1]; (_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)) ^ v->overtaking][v->frame + 1];
if (rd.x & RDE_NEXT_TILE) { if (rd.x & RDE_NEXT_TILE) {
TileIndex tile = v->tile + TileOffsByDiagDir((DiagDirection)(rd.x & 3)); TileIndex tile = v->tile + TileOffsByDiagDir((DiagDirection)(rd.x & 3));
@ -1399,7 +1401,7 @@ again:
uint start_frame = RVC_DEFAULT_START_FRAME; uint start_frame = RVC_DEFAULT_START_FRAME;
if (IsReversingRoadTrackdir(dir)) { if (IsReversingRoadTrackdir(dir)) {
/* Turning around */ /* 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 /* Determine the road bits the tram needs to be able to turn around
* using the 'big' corner loop. */ * using the 'big' corner loop. */
RoadBits needed; RoadBits needed;
@ -1451,7 +1453,7 @@ again:
} }
/* Get position data for first frame on the new tile */ /* 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 x = TileX(tile) * TILE_SIZE + rdp[start_frame].x;
int y = TileY(tile) * TILE_SIZE + rdp[start_frame].y; int y = TileY(tile) * TILE_SIZE + rdp[start_frame].y;
@ -1476,8 +1478,8 @@ again:
goto 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 (IsInsideMM(v->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 (IsReversingRoadTrackdir(dir) && IsInsideMM(v->state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) {
/* New direction is trying to turn vehicle around. /* New direction is trying to turn vehicle around.
* We can't turn at the exit of a road stop so wait.*/ * We can't turn at the exit of a road stop so wait.*/
v->cur_speed = 0; v->cur_speed = 0;
@ -1488,9 +1490,9 @@ again:
/* Vehicle is leaving a road stop tile, mark bay as free /* Vehicle is leaving a road stop tile, mark bay as free
* For drive-through stops, only do it if the vehicle stopped here */ * For drive-through stops, only do it if the vehicle stopped here */
if (IsStandardRoadStopTile(v->tile) || HasBit(v->u.road.state, RVS_IS_STOPPING)) { if (IsStandardRoadStopTile(v->tile) || HasBit(v->state, RVS_IS_STOPPING)) {
rs->FreeBay(HasBit(v->u.road.state, RVS_USING_SECOND_BAY)); rs->FreeBay(HasBit(v->state, RVS_USING_SECOND_BAY));
ClrBit(v->u.road.state, RVS_IS_STOPPING); ClrBit(v->state, RVS_IS_STOPPING);
} }
if (IsStandardRoadStopTile(v->tile)) rs->SetEntranceBusy(false); if (IsStandardRoadStopTile(v->tile)) rs->SetEntranceBusy(false);
} }
@ -1498,8 +1500,8 @@ again:
if (!HasBit(r, VETS_ENTERED_WORMHOLE)) { if (!HasBit(r, VETS_ENTERED_WORMHOLE)) {
v->tile = tile; v->tile = tile;
v->u.road.state = (byte)dir; v->state = (byte)dir;
v->u.road.frame = start_frame; v->frame = start_frame;
} }
if (new_dir != v->direction) { if (new_dir != v->direction) {
v->direction = new_dir; v->direction = new_dir;
@ -1517,7 +1519,7 @@ again:
uint turn_around_start_frame = RVC_TURN_AROUND_START_FRAME; uint turn_around_start_frame = RVC_TURN_AROUND_START_FRAME;
RoadBits tram; 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 * The tram is turning around with one tram 'roadbit'. This means that
* it is using the 'big' corner 'drive data'. However, to support the * it is using the 'big' corner 'drive data'. However, to support the
@ -1549,7 +1551,7 @@ again:
return false; 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 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; int y = TileY(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].y;
@ -1563,8 +1565,8 @@ again:
return false; return false;
} }
v->u.road.state = dir; v->state = dir;
v->u.road.frame = turn_around_start_frame; v->frame = turn_around_start_frame;
if (new_dir != v->direction) { if (new_dir != v->direction) {
v->direction = new_dir; 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 * it's on a depot tile, check if it's time to activate the next vehicle in
* the chain yet. */ * the chain yet. */
if (v->Next() != NULL && IsRoadDepotTile(v->tile)) { 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); RoadVehLeaveDepot(v->Next(), false);
} }
} }
@ -1591,7 +1593,7 @@ again:
Direction new_dir = RoadVehGetSlidingDirection(v, x, y); 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. /* Vehicle is not in a road stop.
* Check for another vehicle to overtake */ * Check for another vehicle to overtake */
RoadVehicle *u = RoadVehFindCloseTo(v, x, y, new_dir); RoadVehicle *u = RoadVehFindCloseTo(v, x, y, new_dir);
@ -1599,8 +1601,8 @@ again:
if (u != NULL) { if (u != NULL) {
u = u->First(); u = u->First();
/* There is a vehicle in front overtake it if possible */ /* There is a vehicle in front overtake it if possible */
if (v->u.road.overtaking == 0) RoadVehCheckOvertake(v, u); if (v->overtaking == 0) RoadVehCheckOvertake(v, u);
if (v->u.road.overtaking == 0) v->cur_speed = u->cur_speed; if (v->overtaking == 0) v->cur_speed = u->cur_speed;
return false; return false;
} }
} }
@ -1609,7 +1611,7 @@ again:
if (new_dir != old_dir) { if (new_dir != old_dir) {
v->direction = new_dir; v->direction = new_dir;
v->cur_speed -= (v->cur_speed >> 2); 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 */ /* The vehicle is in a road stop */
v->UpdateDeltaXY(v->direction); v->UpdateDeltaXY(v->direction);
SetRoadVehPosition(v, v->x_pos, v->y_pos); 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... * 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 * (the station test and stop type test ensure that other vehicles, using the road stop as
* a through route, do not stop) */ * a through route, do not stop) */
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) &&
_road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) || _road_veh_data_1[v->state - RVSB_IN_ROAD_STOP + (_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)] == v->frame) ||
(IsInsideMM(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && (IsInsideMM(v->state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) &&
v->current_order.ShouldStopAtStation(v, GetStationIndex(v->tile)) && v->current_order.ShouldStopAtStation(v, GetStationIndex(v->tile)) &&
v->owner == GetTileOwner(v->tile) && v->owner == GetTileOwner(v->tile) &&
GetRoadStopType(v->tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK) && 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)); RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile));
Station *st = GetStationByTile(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)) { if (IsDriveThroughStopTile(next_tile) && (GetRoadStopType(next_tile) == type) && GetStationIndex(v->tile) == GetStationIndex(next_tile)) {
RoadStop *rs_n = GetRoadStopByTile(next_tile, type); 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 */ /* Bay in next stop along is free - use it */
ClearSlot(v); ClearSlot(v);
rs_n->num_vehicles++; rs_n->num_vehicles++;
v->u.road.slot = rs_n; v->slot = rs_n;
v->dest_tile = rs_n->xy; 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)); RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
return true; return true;
} }
@ -1687,10 +1689,10 @@ again:
if (IsStandardRoadStopTile(v->tile)) rs->SetEntranceBusy(true); if (IsStandardRoadStopTile(v->tile)) rs->SetEntranceBusy(true);
if (rs == v->u.road.slot) { if (rs == v->slot) {
/* We are leaving the correct station */ /* We are leaving the correct station */
ClearSlot(v); ClearSlot(v);
} else if (v->u.road.slot != NULL) { } else if (v->slot != NULL) {
/* We are leaving the wrong station /* We are leaving the wrong station
* XXX The question is .. what to do? Actually we shouldn't be here * XXX The question is .. what to do? Actually we shouldn't be here
* but I guess we need to clear the slot */ * but I guess we need to clear the slot */
@ -1698,8 +1700,8 @@ again:
if (v->tile != v->dest_tile) { 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); 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) { if (v->dest_tile != v->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); 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)) { if (!v->current_order.IsType(OT_GOTO_STATION)) {
DEBUG(ms, 2, " current order type (%d) is not OT_GOTO_STATION", v->current_order.GetType()); 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 /* Move to next frame unless vehicle arrived at a stop position
* in a depot or entered a tunnel/bridge */ * 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); v->UpdateDeltaXY(v->direction);
RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y)); RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
@ -1744,7 +1746,7 @@ static bool RoadVehController(RoadVehicle *v)
/* decrease counters */ /* decrease counters */
v->tick_counter++; v->tick_counter++;
v->current_order_time++; 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 */ /* handle crashed */
if (v->vehstatus & VS_CRASHED) { if (v->vehstatus & VS_CRASHED) {
@ -1824,7 +1826,7 @@ bool RoadVehicle::Tick()
static void CheckIfRoadVehNeedsService(RoadVehicle *v) static void CheckIfRoadVehNeedsService(RoadVehicle *v)
{ {
/* If we already got a slot at a stop, use that FIRST, and go to a depot later */ /* 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()) { if (v->IsInDepot()) {
VehicleServiceInDepot(v); VehicleServiceInDepot(v);
return; return;
@ -1860,7 +1862,7 @@ void RoadVehicle::OnNewDay()
if (!IsRoadVehFront(this)) return; if (!IsRoadVehFront(this)) return;
if ((++this->day_counter & 7) == 0) DecreaseVehicleValue(this); 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); AgeVehicle(this);
CheckIfRoadVehNeedsService(this); CheckIfRoadVehNeedsService(this);
@ -1868,14 +1870,14 @@ void RoadVehicle::OnNewDay()
CheckOrders(this); CheckOrders(this);
/* Current slot has expired */ /* 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", 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); ClearSlot(this);
} }
/* update destination */ /* 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()); Station *st = Station::Get(this->current_order.GetDestination());
RoadStop *rs = st->GetPrimaryRoadStop(this); RoadStop *rs = st->GetPrimaryRoadStop(this);
RoadStop *best = NULL; RoadStop *best = NULL;
@ -1921,9 +1923,9 @@ void RoadVehicle::OnNewDay()
best->num_vehicles++; best->num_vehicles++;
DEBUG(ms, 3, "Assigned to stop 0x%X", best->xy); DEBUG(ms, 3, "Assigned to stop 0x%X", best->xy);
this->u.road.slot = best; this->slot = best;
this->dest_tile = best->xy; this->dest_tile = best->xy;
this->u.road.slot_age = 14; this->slot_age = 14;
} else { } else {
DEBUG(ms, 3, "Could not find a suitable stop"); DEBUG(ms, 3, "Could not find a suitable stop");
} }
@ -1965,11 +1967,11 @@ Trackdir RoadVehicle::GetVehicleTrackdir() const
} }
/* Drive through road stops / wormholes (tunnels) */ /* 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, /* If vehicle's state is a valid track direction (vehicle is not turning around) return it,
* otherwise transform it into a valid track direction */ * 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);
} }

View File

@ -130,7 +130,7 @@ void DrawRoadVehImage(const Vehicle *v, int x, int y, VehicleID selection, int c
int highlight_w = 0; int highlight_w = 0;
for (int dx = 0; v != NULL && dx < max_length ; v = v->Next()) { 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) { if (dx + width > 0 && dx <= max_length) {
SpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v); SpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);

View File

@ -914,7 +914,7 @@ bool AfterLoadGame()
if (v->type == VEH_TRAIN) { if (v->type == VEH_TRAIN) {
v->u.rail.track = TRACK_BIT_WORMHOLE; v->u.rail.track = TRACK_BIT_WORMHOLE;
} else { } else {
v->u.road.state = RVSB_WORMHOLE; ((RoadVehicle *)v)->state = RVSB_WORMHOLE;
} }
} }
} }
@ -1049,15 +1049,18 @@ bool AfterLoadGame()
Vehicle *v; Vehicle *v;
FOR_ALL_VEHICLES(v) { FOR_ALL_VEHICLES(v) {
if (v->type == VEH_ROAD) { if (v->type == VEH_ROAD) {
v->vehstatus &= ~0x40; RoadVehicle *rv = (RoadVehicle *)v;
v->u.road.slot = NULL; rv->vehstatus &= ~0x40;
v->u.road.slot_age = 0; rv->slot = NULL;
rv->slot_age = 0;
} }
} }
} else { } else {
Vehicle *v; Vehicle *v;
FOR_ALL_VEHICLES(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 */ /* In some old savegames a bit was cleared when it should not be cleared */
Vehicle *v; Vehicle *v;
FOR_ALL_VEHICLES(v) { FOR_ALL_VEHICLES(v) {
if (v->type == VEH_ROAD && (v->u.road.state == 250 || v->u.road.state == 251)) { if (v->type != VEH_ROAD) continue;
SetBit(v->u.road.state, RVS_IS_STOPPING); RoadVehicle *rv = (RoadVehicle *)v;
if (rv->state == 250 || rv->state == 251) {
SetBit(rv->state, RVS_IS_STOPPING);
} }
} }
} }

View File

@ -175,10 +175,11 @@ void FixOldVehicles()
v->name = CopyFromOldName(_old_vehicle_names[v->index]); v->name = CopyFromOldName(_old_vehicle_names[v->index]);
/* We haven't used this bit for stations for ages */ /* We haven't used this bit for stations for ages */
if (v->type == VEH_ROAD && if (v->type == VEH_ROAD) {
v->u.road.state != RVSB_IN_DEPOT && RoadVehicle *rv = (RoadVehicle *)v;
v->u.road.state != RVSB_WORMHOLE) { if (rv->state != RVSB_IN_DEPOT && rv->state != RVSB_WORMHOLE) {
ClrBit(v->u.road.state, RVS_IS_STOPPING); ClrBit(rv->state, RVS_IS_STOPPING);
}
} }
/* The subtype should be 0, but it sometimes isn't :( */ /* 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[] = { static const OldChunks vehicle_road_chunk[] = {
OCL_SVAR( OC_UINT8, VehicleRoad, state ), OCL_SVAR( OC_UINT8, RoadVehicle, state ),
OCL_SVAR( OC_UINT8, VehicleRoad, frame ), OCL_SVAR( OC_UINT8, RoadVehicle, frame ),
OCL_SVAR( OC_UINT16, VehicleRoad, blocked_ctr ), OCL_SVAR( OC_UINT16, RoadVehicle, blocked_ctr ),
OCL_SVAR( OC_UINT8, VehicleRoad, overtaking ), OCL_SVAR( OC_UINT8, RoadVehicle, overtaking ),
OCL_SVAR( OC_UINT8, VehicleRoad, overtaking_ctr ), OCL_SVAR( OC_UINT8, RoadVehicle, overtaking_ctr ),
OCL_SVAR( OC_UINT16, VehicleRoad, crashed_ctr ), OCL_SVAR( OC_UINT16, RoadVehicle, crashed_ctr ),
OCL_SVAR( OC_UINT8, VehicleRoad, reverse_ctr ), OCL_SVAR( OC_UINT8, RoadVehicle, reverse_ctr ),
OCL_NULL( 1 ), ///< Junk OCL_NULL( 1 ), ///< Junk
@ -1157,7 +1158,7 @@ static bool LoadOldVehicleUnion(LoadgameState *ls, int num)
switch (v->type) { switch (v->type) {
default: NOT_REACHED(); default: NOT_REACHED();
case VEH_TRAIN : res = LoadChunk(ls, &v->u.rail, vehicle_train_chunk); break; 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_SHIP : res = LoadChunk(ls, v, vehicle_ship_chunk); break;
case VEH_AIRCRAFT: res = LoadChunk(ls, v, vehicle_air_chunk); break; case VEH_AIRCRAFT: res = LoadChunk(ls, v, vehicle_air_chunk); break;
case VEH_EFFECT : res = LoadChunk(ls, v, vehicle_effect_chunk); break; case VEH_EFFECT : res = LoadChunk(ls, v, vehicle_effect_chunk); break;

View File

@ -253,7 +253,7 @@ void AfterLoadVehicles(bool part_of_load)
if (part_of_load) v->fill_percent_te_id = INVALID_TE_ID; if (part_of_load) v->fill_percent_te_id = INVALID_TE_ID;
v->first = NULL; v->first = NULL;
if (v->type == VEH_TRAIN) v->u.rail.first_engine = INVALID_ENGINE; 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(); v->cargo.InvalidateCache();
} }
@ -344,9 +344,11 @@ void AfterLoadVehicles(bool part_of_load)
FOR_ALL_VEHICLES(v) { FOR_ALL_VEHICLES(v) {
switch (v->type) { switch (v->type) {
case VEH_ROAD: case VEH_ROAD: {
v->u.road.roadtype = HasBit(EngInfo(v->First()->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD; RoadVehicle *rv = (RoadVehicle *)v;
v->u.road.compatible_roadtypes = RoadTypeToRoadTypes(v->u.road.roadtype); 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 */ /* FALL THROUGH */
case VEH_TRAIN: case VEH_TRAIN:
case VEH_SHIP: case VEH_SHIP:
@ -542,19 +544,19 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
static const SaveLoad _roadveh_desc[] = { static const SaveLoad _roadveh_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_ROAD), SLE_WRITEBYTE(Vehicle, type, VEH_ROAD),
SLE_VEH_INCLUDEX(), SLE_VEH_INCLUDEX(),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, state), SLE_UINT8), SLE_VAR(RoadVehicle, state, SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, frame), SLE_UINT8), SLE_VAR(RoadVehicle, frame, SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, blocked_ctr), SLE_UINT16), SLE_VAR(RoadVehicle, blocked_ctr, SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking), SLE_UINT8), SLE_VAR(RoadVehicle, overtaking, SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking_ctr), SLE_UINT8), SLE_VAR(RoadVehicle, overtaking_ctr, SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, crashed_ctr), SLE_UINT16), SLE_VAR(RoadVehicle, crashed_ctr, SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, reverse_ctr), SLE_UINT8), SLE_VAR(RoadVehicle, reverse_ctr, SLE_UINT8),
SLE_CONDREFX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot), REF_ROADSTOPS, 6, SL_MAX_VERSION), SLE_CONDREF(RoadVehicle, slot, REF_ROADSTOPS, 6, SL_MAX_VERSION),
SLE_CONDNULL(1, 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_CONDVAR(RoadVehicle, slot_age, SLE_UINT8, 6, SL_MAX_VERSION),
/* reserve extra space in savegame here. (currently 16 bytes) */ /* 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() SLE_END()
}; };

View File

@ -114,7 +114,7 @@ RoadStop *Station::GetPrimaryRoadStop(const RoadVehicle *v) const
for (; rs != NULL; rs = rs->next) { for (; rs != NULL; rs = rs->next) {
/* The vehicle cannot go to this roadstop (different roadtype) */ /* 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 */ /* 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) && RoadVehHasArticPart(v)) continue;
@ -462,7 +462,7 @@ RoadStop::~RoadStop()
if (v->type != VEH_ROAD) continue; if (v->type != VEH_ROAD) continue;
RoadVehicle *rv = (RoadVehicle *)v; RoadVehicle *rv = (RoadVehicle *)v;
if (rv->u.road.slot == this) ClearSlot(rv); if (rv->slot == this) ClearSlot(rv);
} }
} }
assert(num_vehicles == 0); 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) { for (RoadStop *rs = this->next; rs != NULL; rs = rs->next) {
/* The vehicle cannot go to this roadstop (different roadtype) */ /* 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 */ /* 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) && RoadVehHasArticPart(v)) continue;

View File

@ -1488,7 +1488,7 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
static Vehicle *ClearRoadStopStatusEnum(Vehicle *v, void *) 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; return NULL;
} }
@ -2649,30 +2649,31 @@ static VehicleEnterTileStatus VehicleEnter_Station(Vehicle *v, TileIndex tile, i
} }
} }
} else if (v->type == VEH_ROAD) { } 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)) { if (IsRoadStop(tile) && IsRoadVehFront(v)) {
/* Attempt to allocate a parking bay in a road stop */ /* Attempt to allocate a parking bay in a road stop */
RoadStop *rs = GetRoadStopByTile(tile, GetRoadStopType(tile)); RoadStop *rs = GetRoadStopByTile(tile, GetRoadStopType(tile));
if (IsDriveThroughStopTile(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). */ /* 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; if (!rs->IsFreeBay(side)) return VETSB_CANNOT_ENTER;
/* Check if the vehicle is stopping at this road stop */ /* Check if the vehicle is stopping at this road stop */
if (GetRoadStopType(tile) == (IsCargoInClass(v->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK) && if (GetRoadStopType(tile) == (IsCargoInClass(rv->cargo_type, CC_PASSENGERS) ? ROADSTOP_BUS : ROADSTOP_TRUCK) &&
v->current_order.GetDestination() == GetStationIndex(tile)) { rv->current_order.GetDestination() == GetStationIndex(tile)) {
SetBit(v->u.road.state, RVS_IS_STOPPING); SetBit(rv->state, RVS_IS_STOPPING);
rs->AllocateDriveThroughBay(side); rs->AllocateDriveThroughBay(side);
} }
/* Indicate if vehicle is using second bay. */ /* 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 */ /* 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; 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. */ * 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() || 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 */ /* Allocate a bay and update the road state */
uint bay_nr = rs->AllocateBay(); 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 */ /* Mark the station entrace as busy */
rs->SetEntranceBusy(true); rs->SetEntranceBusy(true);

View File

@ -16,6 +16,7 @@
#include "variables.h" #include "variables.h"
#include "train.h" #include "train.h"
#include "ship.h" #include "ship.h"
#include "roadveh.h"
#include "water_map.h" #include "water_map.h"
#include "yapf/yapf.h" #include "yapf/yapf.h"
#include "newgrf_sound.h" #include "newgrf_sound.h"
@ -1412,16 +1413,17 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti
return VETSB_ENTERED_WORMHOLE; return VETSB_ENTERED_WORMHOLE;
} }
} else if (v->type == VEH_ROAD) { } else if (v->type == VEH_ROAD) {
RoadVehicle *rv = (RoadVehicle *)v;
fc = (x & 0xF) + (y << 4); fc = (x & 0xF) + (y << 4);
vdir = DirToDiagDir(v->direction); vdir = DirToDiagDir(v->direction);
/* Enter tunnel? */ /* Enter tunnel? */
if (v->u.road.state != RVSB_WORMHOLE && dir == vdir) { if (rv->state != RVSB_WORMHOLE && dir == vdir) {
if (fc == _tunnel_fractcoord_4[dir] || if (fc == _tunnel_fractcoord_4[dir] ||
fc == _tunnel_fractcoord_5[dir]) { fc == _tunnel_fractcoord_5[dir]) {
v->tile = tile; rv->tile = tile;
v->u.road.state = RVSB_WORMHOLE; rv->state = RVSB_WORMHOLE;
v->vehstatus |= VS_HIDDEN; rv->vehstatus |= VS_HIDDEN;
return VETSB_ENTERED_WORMHOLE; return VETSB_ENTERED_WORMHOLE;
} else { } else {
return VETSB_CONTINUE; return VETSB_CONTINUE;
@ -1434,10 +1436,10 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti
fc == _tunnel_fractcoord_7[dir] fc == _tunnel_fractcoord_7[dir]
) && ) &&
z == 0) { z == 0) {
v->tile = tile; rv->tile = tile;
v->u.road.state = _road_exit_tunnel_state[dir]; rv->state = _road_exit_tunnel_state[dir];
v->u.road.frame = _road_exit_tunnel_frame[dir]; rv->frame = _road_exit_tunnel_frame[dir];
v->vehstatus &= ~VS_HIDDEN; rv->vehstatus &= ~VS_HIDDEN;
return VETSB_ENTERED_WORMHOLE; return VETSB_ENTERED_WORMHOLE;
} }
} }
@ -1467,11 +1469,11 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti
break; break;
case VEH_ROAD: case VEH_ROAD:
v->u.road.state = RVSB_WORMHOLE; ((RoadVehicle *)v)->state = RVSB_WORMHOLE;
break; break;
case VEH_SHIP: case VEH_SHIP:
static_cast<Ship*>(v)->state = TRACK_BIT_WORMHOLE; ((Ship *)v)->state = TRACK_BIT_WORMHOLE;
break; break;
default: NOT_REACHED(); default: NOT_REACHED();
@ -1487,20 +1489,22 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti
} }
break; break;
case VEH_ROAD: case VEH_ROAD: {
if (v->u.road.state == RVSB_WORMHOLE) { RoadVehicle *rv = (RoadVehicle *)v;
v->u.road.state = _road_exit_tunnel_state[dir]; if (rv->state == RVSB_WORMHOLE) {
v->u.road.frame = 0; rv->state = _road_exit_tunnel_state[dir];
rv->frame = 0;
return VETSB_ENTERED_WORMHOLE; return VETSB_ENTERED_WORMHOLE;
} }
break; } break;
case VEH_SHIP: case VEH_SHIP: {
if (static_cast<Ship*>(v)->state == TRACK_BIT_WORMHOLE) { Ship *ship = (Ship *)v;
static_cast<Ship*>(v)->state = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y); if (ship->state == TRACK_BIT_WORMHOLE) {
ship->state = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y);
return VETSB_ENTERED_WORMHOLE; return VETSB_ENTERED_WORMHOLE;
} }
break; } break;
default: NOT_REACHED(); default: NOT_REACHED();
} }

View File

@ -1426,7 +1426,7 @@ SpriteID GetVehiclePalette(const Vehicle *v)
if (v->type == VEH_TRAIN) { if (v->type == VEH_TRAIN) {
return GetEngineColourMap(v->engine_type, v->owner, v->u.rail.first_engine, v); return GetEngineColourMap(v->engine_type, v->owner, v->u.rail.first_engine, v);
} else if (v->type == VEH_ROAD) { } 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); return GetEngineColourMap(v->engine_type, v->owner, INVALID_ENGINE, v);

View File

@ -8,7 +8,6 @@
#include "vehicle_type.h" #include "vehicle_type.h"
#include "track_type.h" #include "track_type.h"
#include "rail_type.h" #include "rail_type.h"
#include "road_type.h"
#include "cargo_type.h" #include "cargo_type.h"
#include "direction_type.h" #include "direction_type.h"
#include "gfx_type.h" #include "gfx_type.h"
@ -25,41 +24,6 @@
#include "order_func.h" #include "order_func.h"
#include "transport_type.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 { enum VehStatus {
VS_HIDDEN = 0x01, VS_HIDDEN = 0x01,
VS_STOPPED = 0x02, VS_STOPPED = 0x02,
@ -149,23 +113,6 @@ enum VehicleRailFlags {
VRF_TRAIN_STUCK = 8, 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<Vehicle, VehicleID, 512, 64000> VehiclePool; typedef Pool<Vehicle, VehicleID, 512, 64000> VehiclePool;
extern VehiclePool _vehicle_pool; extern VehiclePool _vehicle_pool;
@ -295,7 +242,6 @@ public:
union { union {
VehicleRail rail; VehicleRail rail;
VehicleRoad road;
} u; } u;
/* cached oftenly queried NewGRF values */ /* cached oftenly queried NewGRF values */

View File

@ -639,9 +639,9 @@ static int CDECL VehicleLengthSorter(const Vehicle * const *a, const Vehicle * c
break; break;
case VEH_ROAD: { case VEH_ROAD: {
const Vehicle *u; const RoadVehicle *u;
for (u = *a; u != NULL; u = u->Next()) r += u->u.road.cached_veh_length; for (u = (RoadVehicle *)*a; u != NULL; u = u->Next()) r += u->cached_veh_length;
for (u = *b; u != NULL; u = u->Next()) r -= u->u.road.cached_veh_length; for (u = (RoadVehicle *)*b; u != NULL; u = u->Next()) r -= u->cached_veh_length;
} break; } break;
default: NOT_REACHED(); default: NOT_REACHED();

View File

@ -822,7 +822,7 @@ static void FloodVehicle(Vehicle *v)
case VEH_ROAD: case VEH_ROAD:
if (IsRoadVehFront(v)) pass += 1; // driver 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); InvalidateWindowClassesData(WC_ROADVEH_LIST, 0);
break; break;

View File

@ -7,6 +7,7 @@
#include "yapf.hpp" #include "yapf.hpp"
#include "../depot_map.h" #include "../depot_map.h"
#include "../roadveh.h"
/** Track follower helper template class (can serve pathfinders and vehicle /** Track follower helper template class (can serve pathfinders and vehicle
* controllers). See 6 different typedefs below for 3 different transport * 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 TransportType TT() {return Ttr_type_;}
FORCEINLINE static bool IsWaterTT() {return TT() == TRANSPORT_WATER;} FORCEINLINE static bool IsWaterTT() {return TT() == TRANSPORT_WATER;}
FORCEINLINE static bool IsRailTT() {return TT() == TRANSPORT_RAIL;} 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 IsRoadTT() {return TT() == TRANSPORT_ROAD;}
FORCEINLINE static bool Allow90degTurns() {return T90deg_turns_allowed_;} FORCEINLINE static bool Allow90degTurns() {return T90deg_turns_allowed_;}
FORCEINLINE static bool DoTrackMasking() {return IsRailTT() && Tmask_reserved_tracks;} FORCEINLINE static bool DoTrackMasking() {return IsRailTT() && Tmask_reserved_tracks;}
@ -205,7 +206,7 @@ protected:
if (IsRailTT() && IsPlainRailTile(m_new_tile)) { if (IsRailTT() && IsPlainRailTile(m_new_tile)) {
m_new_td_bits = (TrackdirBits)(GetTrackBits(m_new_tile) * 0x101); m_new_td_bits = (TrackdirBits)(GetTrackBits(m_new_tile) * 0x101);
} else { } 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) { if (IsTram() && m_new_td_bits == 0) {
/* GetTileTrackStatus() returns 0 for single tram bits. /* GetTileTrackStatus() returns 0 for single tram bits.

View File

@ -4,6 +4,7 @@
#include "../stdafx.h" #include "../stdafx.h"
#include "../depot_base.h" #include "../depot_base.h"
#include "../roadveh.h"
#include "yapf.hpp" #include "yapf.hpp"
#include "yapf_node_road.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) */ /* our source tile will be the next vehicle tile (should be the given one) */
TileIndex src_tile = tile; TileIndex src_tile = tile;
/* get available trackdirs on the start 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 */ /* select reachable trackdirs only */
src_trackdirs &= DiagdirReachesTrackdirs(enterdir); src_trackdirs &= DiagdirReachesTrackdirs(enterdir);
/* get available trackdirs on the destination tile */ /* get available trackdirs on the destination tile */
TileIndex dest_tile = v->dest_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 */ /* set origin and destination nodes */
Yapf().SetOrigin(src_tile, src_trackdirs); Yapf().SetOrigin(src_tile, src_trackdirs);
@ -348,7 +349,7 @@ public:
/* set destination tile, trackdir /* set destination tile, trackdir
* get available trackdirs on the destination tile */ * 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); Yapf().SetDestination(dst_tile, dst_td_bits);
/* if path not found - return distance = UINT_MAX */ /* if path not found - return distance = UINT_MAX */
@ -373,7 +374,7 @@ public:
/* set origin (tile, trackdir) */ /* set origin (tile, trackdir) */
TileIndex src_tile = v->tile; TileIndex src_tile = v->tile;
Trackdir src_td = v->GetVehicleTrackdir(); 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) /* sometimes the roadveh is not on the road (it resides on non-existing track)
* how should we handle that situation? */ * how should we handle that situation? */
return false; return false;
@ -470,7 +471,7 @@ Depot *YapfFindNearestRoadDepot(const Vehicle *v)
{ {
TileIndex tile = v->tile; TileIndex tile = v->tile;
Trackdir trackdir = v->GetVehicleTrackdir(); 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; return NULL;
} }