diff --git a/distribution/changelog.txt b/distribution/changelog.txt
index 3d08d1bb8d..c69bf19bbc 100644
--- a/distribution/changelog.txt
+++ b/distribution/changelog.txt
@@ -5,6 +5,7 @@
- Fix: [#21221] Trains use unbanked sprites on flat to gentle diagonal banked track pieces.
- Fix: [#22615] Crash when drawing Space Rings with an invalid ride entry.
- Fix: [#22633] Crash when drawing loading screen with an outdated g2.dat.
+- Fix: [#22908] Crash when passing through a door from an invalid wall type.
- Fix: [#22918] Zooming with keyboard moves the view off centre.
- Fix: [#22920] Crash when sacking a staff member.
- Fix: [#22921] Wooden RollerCoaster flat to steep railings appear in front of track in front of them.
diff --git a/src/openrct2/actions/WallPlaceAction.h b/src/openrct2/actions/WallPlaceAction.h
index c511e9b307..f8ba664ada 100644
--- a/src/openrct2/actions/WallPlaceAction.h
+++ b/src/openrct2/actions/WallPlaceAction.h
@@ -15,6 +15,8 @@
#include "../world/Scenery.h"
#include "GameAction.h"
+struct WallSceneryEntry;
+
struct WallPlaceActionResult
{
int32_t BaseHeight{};
diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj
index dcfd4acf7c..f64c17b5a6 100644
--- a/src/openrct2/libopenrct2.vcxproj
+++ b/src/openrct2/libopenrct2.vcxproj
@@ -886,6 +886,7 @@
+
diff --git a/src/openrct2/object/WallSceneryEntry.cpp b/src/openrct2/object/WallSceneryEntry.cpp
new file mode 100644
index 0000000000..b66e282e6a
--- /dev/null
+++ b/src/openrct2/object/WallSceneryEntry.cpp
@@ -0,0 +1,15 @@
+/*****************************************************************************
+ * Copyright (c) 2014-2024 OpenRCT2 developers
+ *
+ * For a complete list of all authors, please refer to contributors.md
+ * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
+ *
+ * OpenRCT2 is licensed under the GNU General Public License version 3.
+ *****************************************************************************/
+
+#include "WallSceneryEntry.h"
+
+DoorSoundType WallSceneryEntry::getDoorSoundType() const
+{
+ return static_cast((flags2 & WALL_SCENERY_2_DOOR_SOUND_MASK) >> WALL_SCENERY_2_DOOR_SOUND_SHIFT);
+}
diff --git a/src/openrct2/object/WallSceneryEntry.h b/src/openrct2/object/WallSceneryEntry.h
index eb0b07dbb7..7fd9b0f53f 100644
--- a/src/openrct2/object/WallSceneryEntry.h
+++ b/src/openrct2/object/WallSceneryEntry.h
@@ -30,12 +30,19 @@ enum WALL_SCENERY_FLAGS
enum WALL_SCENERY_2_FLAGS
{
WALL_SCENERY_2_NO_SELECT_PRIMARY_COLOUR = (1 << 0), // 0x1
- WALL_SCENERY_2_DOOR_SOUND_MASK = 0x6,
+ WALL_SCENERY_2_DOOR_SOUND_MASK = 0b0110,
WALL_SCENERY_2_DOOR_SOUND_SHIFT = 1,
WALL_SCENERY_2_IS_OPAQUE = (1 << 3), // 0x8
WALL_SCENERY_2_ANIMATED = (1 << 4), // 0x10
};
+enum class DoorSoundType : uint8_t
+{
+ none,
+ door,
+ portcullis,
+};
+
struct WallSceneryEntry
{
static constexpr auto kObjectType = ObjectType::Walls;
@@ -49,4 +56,6 @@ struct WallSceneryEntry
money64 price;
ObjectEntryIndex scenery_tab_id;
uint8_t scrolling_mode;
+
+ DoorSoundType getDoorSoundType() const;
};
diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp
index 555b73a623..1c98883d50 100644
--- a/src/openrct2/ride/Vehicle.cpp
+++ b/src/openrct2/ride/Vehicle.cpp
@@ -439,13 +439,15 @@ static constexpr CoordsXY AvoidCollisionMoveOffset[] = {
};
static constexpr OpenRCT2::Audio::SoundId DoorOpenSoundIds[] = {
- OpenRCT2::Audio::SoundId::DoorOpen,
- OpenRCT2::Audio::SoundId::Portcullis,
+ OpenRCT2::Audio::SoundId::Null, // DoorSoundType::none
+ OpenRCT2::Audio::SoundId::DoorOpen, // DoorSoundType::door
+ OpenRCT2::Audio::SoundId::Portcullis, // DoorSoundType::portcullis
};
static constexpr OpenRCT2::Audio::SoundId DoorCloseSoundIds[] = {
- OpenRCT2::Audio::SoundId::DoorClose,
- OpenRCT2::Audio::SoundId::Portcullis,
+ OpenRCT2::Audio::SoundId::Null, // DoorSoundType::none
+ OpenRCT2::Audio::SoundId::DoorClose, // DoorSoundType::door
+ OpenRCT2::Audio::SoundId::Portcullis, // DoorSoundType::portcullis
};
template<>
@@ -6247,15 +6249,15 @@ void Vehicle::UpdateAdditionalAnimation()
static void play_scenery_door_open_sound(const CoordsXYZ& loc, WallElement* tileElement)
{
auto* wallEntry = tileElement->GetEntry();
- int32_t doorSoundType = WallEntryGetDoorSound(wallEntry);
- if (doorSoundType != 0)
- {
- auto soundId = DoorOpenSoundIds[doorSoundType - 1];
- if (soundId != OpenRCT2::Audio::SoundId::Null)
- {
- OpenRCT2::Audio::Play3D(soundId, loc);
- }
- }
+ if (wallEntry == nullptr)
+ return;
+
+ auto doorSoundType = wallEntry->getDoorSoundType();
+ if (doorSoundType == DoorSoundType::none)
+ return;
+
+ auto soundId = DoorOpenSoundIds[EnumValue(doorSoundType)];
+ OpenRCT2::Audio::Play3D(soundId, loc);
}
/**
@@ -6265,15 +6267,15 @@ static void play_scenery_door_open_sound(const CoordsXYZ& loc, WallElement* tile
static void play_scenery_door_close_sound(const CoordsXYZ& loc, WallElement* tileElement)
{
auto* wallEntry = tileElement->GetEntry();
- int32_t doorSoundType = WallEntryGetDoorSound(wallEntry);
- if (doorSoundType != 0)
- {
- auto soundId = DoorCloseSoundIds[doorSoundType - 1];
- if (soundId != OpenRCT2::Audio::SoundId::Null)
- {
- Play3D(soundId, loc);
- }
- }
+ if (wallEntry == nullptr)
+ return;
+
+ auto doorSoundType = wallEntry->getDoorSoundType();
+ if (doorSoundType == DoorSoundType::none)
+ return;
+
+ auto soundId = DoorCloseSoundIds[EnumValue(doorSoundType)];
+ Play3D(soundId, loc);
}
template
diff --git a/src/openrct2/world/Scenery.cpp b/src/openrct2/world/Scenery.cpp
index d070fd4c79..33caedd22b 100644
--- a/src/openrct2/world/Scenery.cpp
+++ b/src/openrct2/world/Scenery.cpp
@@ -300,11 +300,6 @@ void SceneryRemoveGhostToolPlacement()
}
}
-int32_t WallEntryGetDoorSound(const WallSceneryEntry* wallEntry)
-{
- return (wallEntry->flags2 & WALL_SCENERY_2_DOOR_SOUND_MASK) >> WALL_SCENERY_2_DOOR_SOUND_SHIFT;
-}
-
bool IsSceneryAvailableToBuild(const ScenerySelection& item)
{
// All scenery can be built when in the scenario editor
diff --git a/src/openrct2/world/Scenery.h b/src/openrct2/world/Scenery.h
index 2d22ae0c55..5810257525 100644
--- a/src/openrct2/world/Scenery.h
+++ b/src/openrct2/world/Scenery.h
@@ -69,10 +69,6 @@ extern const CoordsXY SceneryQuadrantOffsets[];
void SceneryUpdateTile(const CoordsXY& sceneryPos);
void SceneryRemoveGhostToolPlacement();
-struct WallSceneryEntry;
-
-int32_t WallEntryGetDoorSound(const WallSceneryEntry* wallEntry);
-
bool IsSceneryAvailableToBuild(const ScenerySelection& item);
bool IsSceneryItemRestricted(const ScenerySelection& item);