|
@@ -444,55 +444,49 @@ void RoadVehicle::UpdateDeltaXY(Directio
|
|
|
{
|
|
|
#define MKIT(a, b, c, d) ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | ((d & 0xFF) << 0)
|
|
|
static const uint32 _delta_xy_table[8] = {
|
|
|
MKIT(3, 3, -1, -1),
|
|
|
MKIT(3, 7, -1, -3),
|
|
|
MKIT(3, 3, -1, -1),
|
|
|
MKIT(7, 3, -3, -1),
|
|
|
MKIT(3, 3, -1, -1),
|
|
|
MKIT(3, 7, -1, -3),
|
|
|
MKIT(3, 3, -1, -1),
|
|
|
MKIT(7, 3, -3, -1),
|
|
|
};
|
|
|
#undef MKIT
|
|
|
|
|
|
uint32 x = _delta_xy_table[direction];
|
|
|
this->x_offs = GB(x, 0, 8);
|
|
|
this->y_offs = GB(x, 8, 8);
|
|
|
this->x_extent = GB(x, 16, 8);
|
|
|
this->y_extent = GB(x, 24, 8);
|
|
|
this->z_extent = 6;
|
|
|
}
|
|
|
|
|
|
static void ClearCrashedStation(RoadVehicle *v)
|
|
|
{
|
|
|
RoadStop *rs = RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile));
|
|
|
|
|
|
/* Mark the station entrance as not busy */
|
|
|
rs->SetEntranceBusy(false);
|
|
|
|
|
|
/* Free the parking bay */
|
|
|
rs->FreeBay(HasBit(v->state, RVS_USING_SECOND_BAY));
|
|
|
RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile))->Leave(v);
|
|
|
}
|
|
|
|
|
|
static void DeleteLastRoadVeh(RoadVehicle *v)
|
|
|
{
|
|
|
Vehicle *u = v;
|
|
|
for (; v->Next() != NULL; v = v->Next()) u = v;
|
|
|
u->SetNext(NULL);
|
|
|
|
|
|
if (IsTileType(v->tile, MP_STATION)) ClearCrashedStation(v);
|
|
|
|
|
|
delete v;
|
|
|
}
|
|
|
|
|
|
static byte SetRoadVehPosition(RoadVehicle *v, int x, int y, bool turned)
|
|
|
{
|
|
|
byte new_z, old_z;
|
|
|
|
|
|
/* need this hint so it returns the right z coordinate on bridges. */
|
|
|
v->x_pos = x;
|
|
|
v->y_pos = y;
|
|
|
new_z = GetSlopeZ(x, y);
|
|
|
|
|
|
old_z = v->z_pos;
|
|
|
v->z_pos = new_z;
|
|
@@ -1296,59 +1290,49 @@ again:
|
|
|
if (u != NULL) {
|
|
|
v->cur_speed = u->First()->cur_speed;
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
uint32 r = VehicleEnterTile(v, tile, x, y);
|
|
|
if (HasBit(r, VETS_CANNOT_ENTER)) {
|
|
|
if (!IsTileType(tile, MP_TUNNELBRIDGE)) {
|
|
|
v->cur_speed = 0;
|
|
|
return false;
|
|
|
}
|
|
|
/* Try an about turn to re-enter the previous tile */
|
|
|
dir = _road_reverse_table[rd.x & 3];
|
|
|
goto again;
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
return false;
|
|
|
}
|
|
|
if (IsRoadStop(v->tile)) {
|
|
|
RoadStop *rs = RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile));
|
|
|
|
|
|
/* 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->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);
|
|
|
}
|
|
|
if (IsRoadStop(v->tile)) RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile))->Leave(v);
|
|
|
}
|
|
|
|
|
|
if (!HasBit(r, VETS_ENTERED_WORMHOLE)) {
|
|
|
v->tile = tile;
|
|
|
v->state = (byte)dir;
|
|
|
v->frame = start_frame;
|
|
|
}
|
|
|
if (new_dir != v->direction) {
|
|
|
v->direction = new_dir;
|
|
|
v->cur_speed -= v->cur_speed >> 2;
|
|
|
}
|
|
|
|
|
|
RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y, true));
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (rd.x & RDE_TURNED) {
|
|
|
/* Vehicle has finished turning around, it will now head back onto the same tile */
|
|
|
Trackdir dir;
|
|
|
uint turn_around_start_frame = RVC_TURN_AROUND_START_FRAME;
|
|
|
|
|
|
RoadBits tram;
|
|
|
if (v->roadtype == ROADTYPE_TRAM && !IsRoadDepotTile(v->tile) && CountBits(tram = GetAnyRoadBits(v->tile, ROADTYPE_TRAM, true)) == 1) {
|
|
|
/*
|