diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index 71b74cc56b..7eb127a82b 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -6380,8 +6380,8 @@ void Vehicle::UpdateLandscapeDoor() const } const auto coords = CoordsXYZ{ x, y, TrackLocation.z }.ToTileStart(); - auto* const tileElement = MapGetTrackElementAtFromRide(coords, ride); - if (tileElement != nullptr && tileElement->GetType() == TileElementType::Track) + const auto [tileElement, isUnderground] = MapGetTrackElementAtFromRideIsUnderground(coords, ride); + if (isUnderground && tileElement != nullptr) { AnimateLandscapeDoor(coords, *tileElement->AsTrack(), next_vehicle_on_train.IsNull()); } @@ -6441,8 +6441,8 @@ void Vehicle::UpdateLandscapeDoorBackwards() const } const auto coords = CoordsXYZ{ TrackLocation, TrackLocation.z }; - auto* const tileElement = MapGetTrackElementAtFromRide(coords, ride); - if (tileElement != nullptr && tileElement->GetType() == TileElementType::Track) + const auto [tileElement, isUnderground] = MapGetTrackElementAtFromRideIsUnderground(coords, ride); + if (isUnderground && tileElement != nullptr) { AnimateLandscapeDoor(coords, *tileElement->AsTrack(), next_vehicle_on_train.IsNull()); } diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 7fc738d894..70b67dd8b3 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -2096,6 +2096,36 @@ TileElement* MapGetTrackElementAtFromRide(const CoordsXYZ& trackPos, RideId ride return nullptr; }; +/** + * Gets the track element at x, y, z that is the given track type and sequence, and whether it is underground. + * @param x x units, not tiles. + * @param y y units, not tiles. + * @param z Base height. + */ +std::pair MapGetTrackElementAtFromRideIsUnderground(const CoordsXYZ& trackPos, const RideId rideIndex) +{ + TileElement* tileElement = MapGetFirstElementAt(trackPos); + if (tileElement == nullptr) + return std::pair(nullptr, false); + const auto trackTilePos = TileCoordsXYZ{ trackPos }; + bool isUnderground = true; + do + { + if (tileElement->GetType() == TileElementType::Surface) + isUnderground = false; + if (tileElement->GetType() != TileElementType::Track) + continue; + if (tileElement->BaseHeight != trackTilePos.z) + continue; + if (tileElement->AsTrack()->GetRideIndex() != rideIndex) + continue; + + return std::pair(tileElement, isUnderground); + } while (!(tileElement++)->IsLastForTile()); + + return std::pair(nullptr, false); +}; + /** * Gets the track element at x, y, z that is the given track type and sequence. * @param x x units, not tiles. diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index 5673076c6a..5844bfccbd 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -247,6 +247,7 @@ TrackElement* MapGetTrackElementAtOfTypeSeq(const CoordsXYZD& location, OpenRCT2 TileElement* MapGetTrackElementAtOfTypeFromRide(const CoordsXYZ& trackPos, OpenRCT2::TrackElemType trackType, RideId rideIndex); TileElement* MapGetTrackElementAtFromRide(const CoordsXYZ& trackPos, RideId rideIndex); TileElement* MapGetTrackElementAtWithDirectionFromRide(const CoordsXYZD& trackPos, RideId rideIndex); +std::pair MapGetTrackElementAtFromRideIsUnderground(const CoordsXYZ& trackPos, RideId rideIndex); bool MapIsLocationAtEdge(const CoordsXY& loc);