1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-21 05:53:02 +01:00

Fix #22908: Crash when passing through invalid wall door

This commit is contained in:
Michael Steenbeek
2024-10-30 19:44:08 +01:00
committed by GitHub
parent bdc0276fce
commit 4ea3e334f6
8 changed files with 53 additions and 32 deletions

View File

@@ -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.

View File

@@ -15,6 +15,8 @@
#include "../world/Scenery.h"
#include "GameAction.h"
struct WallSceneryEntry;
struct WallPlaceActionResult
{
int32_t BaseHeight{};

View File

@@ -886,6 +886,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'">

View File

@@ -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);
}

View File

@@ -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;
};

View File

@@ -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<bool isBackwards>

View File

@@ -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

View File

@@ -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);