diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -1680,18 +1680,15 @@ static int GetSlopePixelZ_TunnelBridge(T /* On the bridge ramp? */ if (ground_vehicle) { - int delta; - if (tileh != SLOPE_FLAT) return z + TILE_HEIGHT; switch (dir) { default: NOT_REACHED(); - case DIAGDIR_NE: delta = (TILE_SIZE - 1 - x) / 2; break; - case DIAGDIR_SE: delta = y / 2; break; - case DIAGDIR_SW: delta = x / 2; break; - case DIAGDIR_NW: delta = (TILE_SIZE - 1 - y) / 2; break; + case DIAGDIR_NE: tileh = SLOPE_NE; break; + case DIAGDIR_SE: tileh = SLOPE_SE; break; + case DIAGDIR_SW: tileh = SLOPE_SW; break; + case DIAGDIR_NW: tileh = SLOPE_NW; break; } - return z + 1 + delta; } } @@ -1859,6 +1856,29 @@ static void ChangeTileOwner_TunnelBridge } /** + * Helper to prepare the ground vehicle when entering a bridge. This get called + * when entering the bridge, at the last frame of travel on the bridge head. + * Our calling function gets called before UpdateInclination/UpdateZPosition, + * which normally controls the Z-coordinate. However, in the wormhole of the + * bridge the vehicle is in a strange state so UpdateInclination does not get + * called for the wormhole of the bridge and as such the going up/down bits + * would remain set. As such, this function clears those. In doing so, the call + * to UpdateInclination will not update the Z-coordinate, so that has to be + * done here as well. + * @param gv The ground vehicle entering the bridge. + */ +template +static void PrepareToEnterBridge(T *gv) +{ + if (HasBit(gv->gv_flags, GVF_GOINGUP_BIT)) { + gv->z_pos++; + ClrBit(gv->gv_flags, GVF_GOINGUP_BIT); + } else { + ClrBit(gv->gv_flags, GVF_GOINGDOWN_BIT); + } +} + +/** * Frame when the 'enter tunnel' sound should be played. This is the second * frame on a tile, so the sound is played shortly after entering the tunnel * tile, while the vehicle is still visible. @@ -1959,17 +1979,14 @@ static VehicleEnterTileStatus VehicleEnt case VEH_TRAIN: { Train *t = Train::From(v); t->track = TRACK_BIT_WORMHOLE; - ClrBit(t->gv_flags, GVF_GOINGUP_BIT); - ClrBit(t->gv_flags, GVF_GOINGDOWN_BIT); + PrepareToEnterBridge(t); break; } case VEH_ROAD: { RoadVehicle *rv = RoadVehicle::From(v); rv->state = RVSB_WORMHOLE; - /* There are no slopes inside bridges / tunnels. */ - ClrBit(rv->gv_flags, GVF_GOINGUP_BIT); - ClrBit(rv->gv_flags, GVF_GOINGDOWN_BIT); + PrepareToEnterBridge(rv); break; }