Skip to content

Commit

Permalink
Fix OpenRCT2#22908: Crash when passing through invalid wall door
Browse files Browse the repository at this point in the history
  • Loading branch information
Gymnasiast committed Oct 27, 2024
1 parent e666550 commit 709a2d8
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 28 deletions.
1 change: 1 addition & 0 deletions distribution/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- Improved: [#23010] Make AppImage compatible with Ubuntu 22.04 and Debian Bookworm again.
- 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.
Expand Down
2 changes: 2 additions & 0 deletions src/openrct2/actions/WallPlaceAction.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include "../world/Scenery.h"
#include "GameAction.h"

struct WallSceneryEntry;

struct WallPlaceActionResult
{
int32_t BaseHeight{};
Expand Down
1 change: 1 addition & 0 deletions src/openrct2/libopenrct2.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,7 @@
<ClCompile Include="object\TerrainEdgeObject.cpp" />
<ClCompile Include="object\TerrainSurfaceObject.cpp" />
<ClCompile Include="object\WallObject.cpp" />
<ClCompile Include="object\WallSceneryEntry.cpp" />
<ClCompile Include="object\WaterObject.cpp" />
<ClCompile Include="OpenRCT2.cpp" />
<ClCompile Include="openrct2_pch.cpp" Condition="'$(UsePCH)'=='true'">
Expand Down
15 changes: 15 additions & 0 deletions src/openrct2/object/WallSceneryEntry.cpp
Original file line number Diff line number Diff line change
@@ -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<DoorSoundType>((flags2 & WALL_SCENERY_2_DOOR_SOUND_MASK) >> WALL_SCENERY_2_DOOR_SOUND_SHIFT);
}
11 changes: 10 additions & 1 deletion src/openrct2/object/WallSceneryEntry.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -49,4 +56,6 @@ struct WallSceneryEntry
money64 price;
ObjectEntryIndex scenery_tab_id;
uint8_t scrolling_mode;

DoorSoundType getDoorSoundType() const;
};
44 changes: 26 additions & 18 deletions src/openrct2/ride/Vehicle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<> bool EntityBase::Is<Vehicle>() const
Expand Down Expand Up @@ -6246,14 +6248,17 @@ 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)
if (wallEntry == nullptr)
return;

auto doorSoundType = wallEntry->getDoorSoundType();
if (doorSoundType == DoorSoundType::none)
return;

auto soundId = DoorOpenSoundIds[EnumValue(doorSoundType)];
if (soundId != OpenRCT2::Audio::SoundId::Null)
{
auto soundId = DoorOpenSoundIds[doorSoundType - 1];
if (soundId != OpenRCT2::Audio::SoundId::Null)
{
OpenRCT2::Audio::Play3D(soundId, loc);
}
OpenRCT2::Audio::Play3D(soundId, loc);
}
}

Expand All @@ -6264,14 +6269,17 @@ 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)
if (wallEntry == nullptr)
return;

auto doorSoundType = wallEntry->getDoorSoundType();
if (doorSoundType == DoorSoundType::none)
return;

auto soundId = DoorCloseSoundIds[EnumValue(doorSoundType)];
if (soundId != OpenRCT2::Audio::SoundId::Null)
{
auto soundId = DoorCloseSoundIds[doorSoundType - 1];
if (soundId != OpenRCT2::Audio::SoundId::Null)
{
Play3D(soundId, loc);
}
Play3D(soundId, loc);
}
}

Expand Down
5 changes: 0 additions & 5 deletions src/openrct2/world/Scenery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 0 additions & 4 deletions src/openrct2/world/Scenery.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 709a2d8

Please sign in to comment.