Index: src/saveload/afterload.cpp =================================================================== --- src/saveload/afterload.cpp (revision 20942) +++ src/saveload/afterload.cpp (working copy) @@ -2320,6 +2320,57 @@ } } + if (CheckSavegameVersion(149)) { + Trackdir _road_tunnel_state[DIAGDIR_END] = {TRACKDIR_X_NE, TRACKDIR_Y_SE, TRACKDIR_X_SW, TRACKDIR_Y_NW}; + Vehicle *v; + FOR_ALL_VEHICLES(v) { + if (v->type != VEH_TRAIN && v->type != VEH_ROAD) continue; + if (!IsTunnelTile(v->tile)) continue; + + TileIndex tile = TileVirtXY(v->x_pos, v->y_pos); + if (v->tile != tile && GetOtherTunnelBridgeEnd(v->tile) != tile) continue; // in wormhole not on tunnel tile + + DiagDirection dir = GetTunnelBridgeDirection(tile); + v->tile = tile; + + switch (v->type) { + case VEH_TRAIN: { + Train *t = Train::From(v); + if (t->track != TRACK_BIT_WORMHOLE) continue; + t->track = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y); + } break; + + case VEH_ROAD: { + RoadVehicle *rv = RoadVehicle::From(v); + if (rv->state != RVSB_WORMHOLE) continue; + + DiagDirection vdir = DirToDiagDir(v->direction); + rv->state = _road_tunnel_state[vdir]; + + byte pos = DiagDirToAxis(vdir) == AXIS_X ? v->x_pos: v->y_pos; + /* position of the vehicle on the tile */ + pos &= TILE_UNIT_MASK; + /* Number of units moved since entering the tile */ + rv->frame = (vdir == DIAGDIR_NE || vdir == DIAGDIR_NW) ? TILE_SIZE - pos - 1: pos; + + } break; + + default: NOT_REACHED(); + } + + if (dir != DirToDiagDir(v->direction)) continue; + + switch (dir) { + default: NOT_REACHED(); + case DIAGDIR_NE: if ((v->x_pos & 0xF) != 0) continue; break; + case DIAGDIR_SE: if ((v->y_pos & 0xF) != TILE_SIZE - 1) continue; break; + case DIAGDIR_SW: if ((v->x_pos & 0xF) != TILE_SIZE - 1) continue; break; + case DIAGDIR_NW: if ((v->y_pos & 0xF) != 0) continue; break; + } + VehicleEnterTile(v, tile, v->x_pos, v->y_pos); // just before leaving ramp and enter wormhole + } + } + /* Road stops is 'only' updating some caches */ AfterLoadRoadStops(); AfterLoadLabelMaps();