Get old path objects working

This commit is contained in:
Ted John 2021-04-21 01:21:54 +01:00
parent 00f22958f1
commit d742290794
15 changed files with 219 additions and 120 deletions

View File

@ -173,7 +173,7 @@ void setup_in_use_selection_flags()
Editor::SetSelectedObject(ObjectType::ParkEntrance, 0, OBJECT_SELECTION_FLAG_SELECTED); Editor::SetSelectedObject(ObjectType::ParkEntrance, 0, OBJECT_SELECTION_FLAG_SELECTED);
type = iter.element->AsEntrance()->GetPathType(); type = iter.element->AsEntrance()->GetSurfaceEntryIndex();
Editor::SetSelectedObject(ObjectType::Paths, type, OBJECT_SELECTION_FLAG_SELECTED); Editor::SetSelectedObject(ObjectType::Paths, type, OBJECT_SELECTION_FLAG_SELECTED);
break; break;
case TILE_ELEMENT_TYPE_WALL: case TILE_ELEMENT_TYPE_WALL:

View File

@ -242,7 +242,7 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementInsertQuery(GameActions::Re
{ {
entrancePath = true; entrancePath = true;
// Make the price the same as replacing a path // Make the price the same as replacing a path
if (entranceElement->GetPathType() == (_type & 0xF)) if (entranceElement->GetSurfaceEntryIndex() == _type)
entranceIsSamePath = true; entranceIsSamePath = true;
else else
res->Cost -= MONEY(6, 00); res->Cost -= MONEY(6, 00);
@ -306,7 +306,7 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementInsertExecute(GameActions::
{ {
entrancePath = true; entrancePath = true;
// Make the price the same as replacing a path // Make the price the same as replacing a path
if (entranceElement->GetPathType() == (_type & 0xF)) if (entranceElement->GetSurfaceEntryIndex() == _type)
entranceIsSamePath = true; entranceIsSamePath = true;
else else
res->Cost -= MONEY(6, 00); res->Cost -= MONEY(6, 00);
@ -338,8 +338,7 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementInsertExecute(GameActions::
{ {
if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && !entranceIsSamePath) if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && !entranceIsSamePath)
{ {
// Set the path type but make sure it's not a queue as that will not show up entranceElement->SetSurfaceEntryIndex(_type);
entranceElement->SetPathType(_type & 0x7F);
map_invalidate_tile_full(_loc); map_invalidate_tile_full(_loc);
} }
} }

View File

@ -123,7 +123,7 @@ GameActions::Result::Ptr FootpathPlaceFromTrackAction::ElementInsertQuery(GameAc
{ {
entrancePath = true; entrancePath = true;
// Make the price the same as replacing a path // Make the price the same as replacing a path
if (entranceElement->GetPathType() == (_type & 0xF)) if (entranceElement->GetSurfaceEntryIndex() == _type)
entranceIsSamePath = true; entranceIsSamePath = true;
else else
res->Cost -= MONEY(6, 00); res->Cost -= MONEY(6, 00);
@ -190,7 +190,7 @@ GameActions::Result::Ptr FootpathPlaceFromTrackAction::ElementInsertExecute(Game
{ {
entrancePath = true; entrancePath = true;
// Make the price the same as replacing a path // Make the price the same as replacing a path
if (entranceElement->GetPathType() == (_type & 0xF)) if (entranceElement->GetSurfaceEntryIndex() == _type)
entranceIsSamePath = true; entranceIsSamePath = true;
else else
res->Cost -= MONEY(6, 00); res->Cost -= MONEY(6, 00);
@ -225,7 +225,7 @@ GameActions::Result::Ptr FootpathPlaceFromTrackAction::ElementInsertExecute(Game
if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && !entranceIsSamePath) if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && !entranceIsSamePath)
{ {
// Set the path type but make sure it's not a queue as that will not show up // Set the path type but make sure it's not a queue as that will not show up
entranceElement->SetPathType(_type & 0x7F); entranceElement->SetSurfaceEntryIndex(_type);
map_invalidate_tile_full(_loc); map_invalidate_tile_full(_loc);
} }
} }

View File

@ -146,7 +146,7 @@ GameActions::Result::Ptr PlaceParkEntranceAction::Execute() const
entranceElement->SetDirection(_loc.direction); entranceElement->SetDirection(_loc.direction);
entranceElement->SetSequenceIndex(index); entranceElement->SetSequenceIndex(index);
entranceElement->SetEntranceType(ENTRANCE_TYPE_PARK_ENTRANCE); entranceElement->SetEntranceType(ENTRANCE_TYPE_PARK_ENTRANCE);
entranceElement->SetPathType(gFootpathSelectedId); entranceElement->SetSurfaceEntryIndex(gFootpathSelectedId);
if (!entranceElement->IsGhost()) if (!entranceElement->IsGhost())
{ {

View File

@ -200,6 +200,7 @@ struct FootpathPaintInfo
uint32_t RailingFlags{}; uint32_t RailingFlags{};
uint8_t ScrollingMode{}; uint8_t ScrollingMode{};
RailingEntrySupportType SupportType{}; RailingEntrySupportType SupportType{};
colour_t SupportColour = 255;
}; };
extern paint_session gPaintSession; extern paint_session gPaintSession;

View File

@ -14,6 +14,7 @@
#include "../../drawing/LightFX.h" #include "../../drawing/LightFX.h"
#include "../../interface/Viewport.h" #include "../../interface/Viewport.h"
#include "../../localisation/Localisation.h" #include "../../localisation/Localisation.h"
#include "../../object/FootpathObject.h"
#include "../../object/FootpathSurfaceObject.h" #include "../../object/FootpathSurfaceObject.h"
#include "../../object/StationObject.h" #include "../../object/StationObject.h"
#include "../../ride/RideData.h" #include "../../ride/RideData.h"
@ -232,12 +233,6 @@ static void park_entrance_paint(paint_session* session, uint8_t direction, int32
// Index to which part of the entrance // Index to which part of the entrance
// Middle, left, right // Middle, left, right
uint8_t part_index = tile_element->AsEntrance()->GetSequenceIndex(); uint8_t part_index = tile_element->AsEntrance()->GetSequenceIndex();
FootpathSurfaceObject* path_entry = nullptr;
// The left and right of the park entrance often have this set to 127.
// So only attempt to get the footpath type if we're dealing with the middle bit of the entrance.
if (part_index == 0)
path_entry = get_path_surface_entry(tile_element->AsEntrance()->GetPathType());
rct_entrance_type* entrance; rct_entrance_type* entrance;
uint8_t di = ((direction / 2 + part_index / 2) & 1) ? 0x1A : 0x20; uint8_t di = ((direction / 2 + part_index / 2) & 1) ? 0x1A : 0x20;
@ -245,11 +240,23 @@ static void park_entrance_paint(paint_session* session, uint8_t direction, int32
switch (part_index) switch (part_index)
{ {
case 0: case 0:
if (path_entry != nullptr) {
auto footpathObj = tile_element->AsEntrance()->GetPathEntry();
if (footpathObj != nullptr)
{ {
image_id = (path_entry->BaseImageId + 5 * (1 + (direction & 1))) | ghost_id; auto footpathEntry = reinterpret_cast<rct_footpath_entry*>(footpathObj->GetLegacyData());
image_id = (footpathEntry->image + 5 * (1 + (direction & 1))) | ghost_id;
PaintAddImageAsParent(session, image_id, 0, 0, 32, 0x1C, 0, height, 0, 2, height); PaintAddImageAsParent(session, image_id, 0, 0, 32, 0x1C, 0, height, 0, 2, height);
} }
else
{
auto footpathSurfaceObj = tile_element->AsEntrance()->GetSurfaceEntry();
if (footpathSurfaceObj != nullptr)
{
image_id = (footpathSurfaceObj->BaseImageId + 5 * (1 + (direction & 1))) | ghost_id;
PaintAddImageAsParent(session, image_id, 0, 0, 32, 0x1C, 0, height, 0, 2, height);
}
}
entrance = static_cast<rct_entrance_type*>(object_entry_get_chunk(ObjectType::ParkEntrance, 0)); entrance = static_cast<rct_entrance_type*>(object_entry_get_chunk(ObjectType::ParkEntrance, 0));
if (entrance == nullptr) if (entrance == nullptr)
@ -302,6 +309,7 @@ static void park_entrance_paint(paint_session* session, uint8_t direction, int32
PaintAddImageAsChild(session, stsetup, 0, 0, 0x1C, 0x1C, 0x2F, text_height, 2, 2, text_height); PaintAddImageAsChild(session, stsetup, 0, 0, 0x1C, 0x1C, 0x2F, text_height, 2, 2, text_height);
} }
break; break;
}
case 1: case 1:
case 2: case 2:
entrance = static_cast<rct_entrance_type*>(object_entry_get_chunk(ObjectType::ParkEntrance, 0)); entrance = static_cast<rct_entrance_type*>(object_entry_get_chunk(ObjectType::ParkEntrance, 0));

View File

@ -13,6 +13,7 @@
#include "../../drawing/LightFX.h" #include "../../drawing/LightFX.h"
#include "../../interface/Viewport.h" #include "../../interface/Viewport.h"
#include "../../localisation/Localisation.h" #include "../../localisation/Localisation.h"
#include "../../object/FootpathObject.h"
#include "../../object/FootpathRailingsObject.h" #include "../../object/FootpathRailingsObject.h"
#include "../../object/FootpathSurfaceObject.h" #include "../../object/FootpathSurfaceObject.h"
#include "../../object/ObjectList.h" #include "../../object/ObjectList.h"
@ -90,7 +91,7 @@ void path_paint_box_support(
bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags); bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags);
void path_paint_pole_support( void path_paint_pole_support(
paint_session* session, const TileElement* tileElement, int16_t height, const FootpathPaintInfo& pathPaintInfo, paint_session* session, const TileElement* tileElement, int16_t height, const FootpathPaintInfo& pathPaintInfo,
bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags, colour_t colour = 255); bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags);
/* rct2: 0x006A5AE5 */ /* rct2: 0x006A5AE5 */
static void path_bit_lights_paint( static void path_bit_lights_paint(
@ -805,6 +806,52 @@ static void sub_6A3F61(
} }
} }
static FootpathPaintInfo GetFootpathPaintInfo(const PathElement* pathEl)
{
FootpathPaintInfo pathPaintInfo;
auto footpathObj = pathEl->GetPathEntry();
if (footpathObj != nullptr)
{
auto footpathEntry = reinterpret_cast<rct_footpath_entry*>(footpathObj->GetLegacyData());
if (pathEl->IsQueue())
{
pathPaintInfo.SurfaceImageId = footpathEntry->image + 51;
pathPaintInfo.SurfaceFlags = footpathEntry->flags | FOOTPATH_ENTRY_FLAG_IS_QUEUE;
}
else
{
pathPaintInfo.SurfaceImageId = footpathEntry->image;
pathPaintInfo.SurfaceFlags = footpathEntry->flags;
}
pathPaintInfo.ScrollingMode = footpathEntry->scrolling_mode;
pathPaintInfo.SupportType = footpathEntry->support_type;
pathPaintInfo.BridgeImageId = footpathEntry->bridge_image;
pathPaintInfo.RailingFlags = footpathEntry->flags;
pathPaintInfo.RailingsImageId = footpathEntry->image + 73;
}
else
{
auto footpathSurfaceObj = pathEl->GetSurfaceEntry();
if (footpathSurfaceObj != nullptr)
{
pathPaintInfo.SurfaceImageId = footpathSurfaceObj->BaseImageId;
pathPaintInfo.SurfaceFlags = footpathSurfaceObj->Flags;
auto railingObj = pathEl->GetRailingEntry();
if (railingObj != nullptr)
{
pathPaintInfo.BridgeImageId = railingObj->BridgeImageId;
pathPaintInfo.RailingsImageId = railingObj->RailingsImageId;
pathPaintInfo.RailingFlags = railingObj->Flags;
pathPaintInfo.ScrollingMode = railingObj->ScrollingMode;
pathPaintInfo.SupportType = railingObj->SupportType;
pathPaintInfo.SupportColour = railingObj->Colour;
}
}
}
return pathPaintInfo;
}
/** /**
* rct2: 0x0006A3590 * rct2: 0x0006A3590
*/ */
@ -817,11 +864,12 @@ void path_paint(paint_session* session, uint16_t height, const TileElement* tile
uint32_t sceneryImageFlags = 0; uint32_t sceneryImageFlags = 0;
uint32_t imageFlags = 0; uint32_t imageFlags = 0;
auto pathEl = tile_element->AsPath();
if (gTrackDesignSaveMode) if (gTrackDesignSaveMode)
{ {
if (tile_element->AsPath()->IsQueue()) if (pathEl->IsQueue())
{ {
if (tile_element->AsPath()->GetRideIndex() != gTrackDesignSaveRideIndex) if (pathEl->GetRideIndex() != gTrackDesignSaveRideIndex)
{ {
return; return;
} }
@ -838,7 +886,7 @@ void path_paint(paint_session* session, uint16_t height, const TileElement* tile
imageFlags = SPRITE_ID_PALETTE_COLOUR_1(EnumValue(FilterPaletteID::Palette46)); imageFlags = SPRITE_ID_PALETTE_COLOUR_1(EnumValue(FilterPaletteID::Palette46));
} }
if (tile_element->AsPath()->AdditionIsGhost()) if (pathEl->AdditionIsGhost())
{ {
sceneryImageFlags = CONSTRUCTION_MARKER; sceneryImageFlags = CONSTRUCTION_MARKER;
} }
@ -850,13 +898,13 @@ void path_paint(paint_session* session, uint16_t height, const TileElement* tile
} }
// For debugging purpose, show blocked tiles with a colour // For debugging purpose, show blocked tiles with a colour
if (gPaintBlockedTiles && tile_element->AsPath()->IsBlockedByVehicle()) if (gPaintBlockedTiles && pathEl->IsBlockedByVehicle())
{ {
imageFlags = COLOUR_BRIGHT_GREEN << 19 | COLOUR_GREY << 24 | IMAGE_TYPE_REMAP; imageFlags = COLOUR_BRIGHT_GREEN << 19 | COLOUR_GREY << 24 | IMAGE_TYPE_REMAP;
} }
// Draw wide flags as ghosts, leaving only the "walkable" paths to be drawn normally // Draw wide flags as ghosts, leaving only the "walkable" paths to be drawn normally
if (gPaintWidePathsAsGhost && tile_element->AsPath()->IsWide()) if (gPaintWidePathsAsGhost && pathEl->IsWide())
{ {
imageFlags &= 0x7FFFF; imageFlags &= 0x7FFFF;
imageFlags |= CONSTRUCTION_MARKER; imageFlags |= CONSTRUCTION_MARKER;
@ -874,11 +922,11 @@ void path_paint(paint_session* session, uint16_t height, const TileElement* tile
} }
else else
{ {
if (tile_element->AsPath()->IsSloped()) if (pathEl->IsSloped())
{ {
// Diagonal path // Diagonal path
if (surface->GetSlope() != PathSlopeToLandSlope[tile_element->AsPath()->GetSlopeDirection()]) if (surface->GetSlope() != PathSlopeToLandSlope[pathEl->GetSlopeDirection()])
{ {
hasSupports = true; hasSupports = true;
} }
@ -920,9 +968,9 @@ void path_paint(paint_session* session, uint16_t height, const TileElement* tile
{ {
uint32_t imageId = 2618; uint32_t imageId = 2618;
int32_t patrolAreaBaseZ = tile_element->GetBaseZ(); int32_t patrolAreaBaseZ = tile_element->GetBaseZ();
if (tile_element->AsPath()->IsSloped()) if (pathEl->IsSloped())
{ {
imageId = 2619 + ((tile_element->AsPath()->GetSlopeDirection() + session->CurrentRotation) & 3); imageId = 2619 + ((pathEl->GetSlopeDirection() + session->CurrentRotation) & 3);
patrolAreaBaseZ += 16; patrolAreaBaseZ += 16;
} }
@ -934,7 +982,7 @@ void path_paint(paint_session* session, uint16_t height, const TileElement* tile
if (PaintShouldShowHeightMarkers(session, VIEWPORT_FLAG_PATH_HEIGHTS)) if (PaintShouldShowHeightMarkers(session, VIEWPORT_FLAG_PATH_HEIGHTS))
{ {
uint16_t heightMarkerBaseZ = tile_element->GetBaseZ() + 3; uint16_t heightMarkerBaseZ = tile_element->GetBaseZ() + 3;
if (tile_element->AsPath()->IsSloped()) if (pathEl->IsSloped())
{ {
heightMarkerBaseZ += 8; heightMarkerBaseZ += 8;
} }
@ -944,66 +992,38 @@ void path_paint(paint_session* session, uint16_t height, const TileElement* tile
PaintAddImageAsParent(session, imageId, 16, 16, 1, 1, 0, heightMarkerBaseZ); PaintAddImageAsParent(session, imageId, 16, 16, 1, 1, 0, heightMarkerBaseZ);
} }
auto footpathSurfaceObj = tile_element->AsPath()->GetSurfaceEntry(); auto pathPaintInfo = GetFootpathPaintInfo(pathEl);
if (footpathSurfaceObj != nullptr) if (pathPaintInfo.SupportType == RailingEntrySupportType::Pole)
{ {
FootpathPaintInfo pathPaintInfo; path_paint_pole_support(session, tile_element, height, pathPaintInfo, hasSupports, imageFlags, sceneryImageFlags);
pathPaintInfo.SurfaceImageId = footpathSurfaceObj->BaseImageId; }
pathPaintInfo.SurfaceFlags = footpathSurfaceObj->Flags; else
{
colour_t colour = COLOUR_NULL; path_paint_box_support(session, tile_element, height, pathPaintInfo, hasSupports, imageFlags, sceneryImageFlags);
auto railingObj = tile_element->AsPath()->GetRailingEntry();
if (railingObj != nullptr)
{
pathPaintInfo.BridgeImageId = railingObj->BridgeImageId;
pathPaintInfo.RailingsImageId = railingObj->RailingsImageId;
pathPaintInfo.RailingFlags = railingObj->Flags;
pathPaintInfo.ScrollingMode = railingObj->ScrollingMode;
pathPaintInfo.SupportType = railingObj->SupportType;
colour = railingObj->Colour;
}
// else
// {
// pathPaintInfo.BridgeImageId = railingsEntry->bridge_image;
// pathPaintInfo.RailingsImageId = railingsEntry->railings_image;
// pathPaintInfo.RailingFlags = railingsEntry->flags;
// pathPaintInfo.ScrollingMode = railingsEntry->scrolling_mode;
// pathPaintInfo.SupportType = railingsEntry->support_type;
// }
if (pathPaintInfo.SupportType == RailingEntrySupportType::Pole)
{
path_paint_pole_support(
session, tile_element, height, pathPaintInfo, hasSupports, imageFlags, sceneryImageFlags, colour);
}
else
{
path_paint_box_support(session, tile_element, height, pathPaintInfo, hasSupports, imageFlags, sceneryImageFlags);
}
} }
#ifdef __ENABLE_LIGHTFX__ #ifdef __ENABLE_LIGHTFX__
if (lightfx_is_available()) if (lightfx_is_available())
{ {
if (tile_element->AsPath()->HasAddition() && !(tile_element->AsPath()->IsBroken())) if (pathEl->HasAddition() && !(pathEl->IsBroken()))
{ {
rct_scenery_entry* sceneryEntry = tile_element->AsPath()->GetAdditionEntry(); rct_scenery_entry* sceneryEntry = pathEl->GetAdditionEntry();
if (sceneryEntry != nullptr && sceneryEntry->path_bit.flags & PATH_BIT_FLAG_LAMP) if (sceneryEntry != nullptr && sceneryEntry->path_bit.flags & PATH_BIT_FLAG_LAMP)
{ {
if (!(tile_element->AsPath()->GetEdges() & EDGE_NE)) if (!(pathEl->GetEdges() & EDGE_NE))
{ {
lightfx_add_3d_light_magic_from_drawing_tile( lightfx_add_3d_light_magic_from_drawing_tile(
session->MapPosition, -16, 0, height + 23, LightType::Lantern3); session->MapPosition, -16, 0, height + 23, LightType::Lantern3);
} }
if (!(tile_element->AsPath()->GetEdges() & EDGE_SE)) if (!(pathEl->GetEdges() & EDGE_SE))
{ {
lightfx_add_3d_light_magic_from_drawing_tile(session->MapPosition, 0, 16, height + 23, LightType::Lantern3); lightfx_add_3d_light_magic_from_drawing_tile(session->MapPosition, 0, 16, height + 23, LightType::Lantern3);
} }
if (!(tile_element->AsPath()->GetEdges() & EDGE_SW)) if (!(pathEl->GetEdges() & EDGE_SW))
{ {
lightfx_add_3d_light_magic_from_drawing_tile(session->MapPosition, 16, 0, height + 23, LightType::Lantern3); lightfx_add_3d_light_magic_from_drawing_tile(session->MapPosition, 16, 0, height + 23, LightType::Lantern3);
} }
if (!(tile_element->AsPath()->GetEdges() & EDGE_NW)) if (!(pathEl->GetEdges() & EDGE_NW))
{ {
lightfx_add_3d_light_magic_from_drawing_tile( lightfx_add_3d_light_magic_from_drawing_tile(
session->MapPosition, 0, -16, height + 23, LightType::Lantern3); session->MapPosition, 0, -16, height + 23, LightType::Lantern3);
@ -1158,7 +1178,7 @@ void path_paint_box_support(
void path_paint_pole_support( void path_paint_pole_support(
paint_session* session, const TileElement* tileElement, int16_t height, const FootpathPaintInfo& pathPaintInfo, paint_session* session, const TileElement* tileElement, int16_t height, const FootpathPaintInfo& pathPaintInfo,
bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags, colour_t colour) bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags)
{ {
const PathElement* pathElement = tileElement->AsPath(); const PathElement* pathElement = tileElement->AsPath();
@ -1261,7 +1281,9 @@ void path_paint_pole_support(
{ {
if (!(edges & (1 << i))) if (!(edges & (1 << i)))
{ {
const int32_t extraFlags = (colour != COLOUR_NULL) ? SPRITE_ID_PALETTE_COLOUR_1(colour) : 0; const int32_t extraFlags = (pathPaintInfo.SupportColour != COLOUR_NULL)
? SPRITE_ID_PALETTE_COLOUR_1(pathPaintInfo.SupportColour)
: 0;
path_b_supports_paint_setup(session, supports[i], ax, height, imageFlags | extraFlags, pathPaintInfo); path_b_supports_paint_setup(session, supports[i], ax, height, imageFlags | extraFlags, pathPaintInfo);
} }
} }

View File

@ -1812,7 +1812,7 @@ private:
pathType = RCT1_FOOTPATH_TYPE_TARMAC_GRAY; pathType = RCT1_FOOTPATH_TYPE_TARMAC_GRAY;
} }
auto entryIndex = _footpathSurfaceTypeToEntryMap[pathType]; auto entryIndex = _footpathSurfaceTypeToEntryMap[pathType];
dst2->SetPathType(entryIndex & 0x7F); dst2->SetSurfaceEntryIndex(entryIndex);
} }
return 1; return 1;

View File

@ -1140,8 +1140,7 @@ public:
if (surfaceEntry == OBJECT_ENTRY_INDEX_NULL) if (surfaceEntry == OBJECT_ENTRY_INDEX_NULL)
{ {
// Legacy footpath object // Legacy footpath object
dst2->SetSurfaceEntryIndex(OBJECT_ENTRY_INDEX_NULL); dst2->SetPathEntryIndex(pathEntryIndex);
dst2->SetRailingEntryIndex(OBJECT_ENTRY_INDEX_NULL);
} }
else else
{ {
@ -1240,17 +1239,24 @@ public:
dst2->SetStationIndex(src2->GetStationIndex()); dst2->SetStationIndex(src2->GetStationIndex());
dst2->SetSequenceIndex(src2->GetSequenceIndex()); dst2->SetSequenceIndex(src2->GetSequenceIndex());
auto pathEntryIndex = src2->GetPathType(); if (src2->GetSequenceIndex() == 0)
auto surfaceEntry = _pathToSurfaceMap[pathEntryIndex];
if (surfaceEntry == OBJECT_ENTRY_INDEX_NULL)
{ {
// Legacy footpath object auto pathEntryIndex = src2->GetPathType();
dst2->SetPathType(OBJECT_ENTRY_INDEX_NULL); auto surfaceEntry = _pathToSurfaceMap[pathEntryIndex];
if (surfaceEntry == OBJECT_ENTRY_INDEX_NULL)
{
// Legacy footpath object
dst2->SetPathEntryIndex(pathEntryIndex);
}
else
{
// Surface
dst2->SetSurfaceEntryIndex(surfaceEntry);
}
} }
else else
{ {
// Surface dst2->SetSurfaceEntryIndex(OBJECT_ENTRY_INDEX_NULL);
dst2->SetPathType(surfaceEntry);
} }
break; break;
} }

View File

@ -1338,7 +1338,7 @@ namespace OpenRCT2::Scripting
auto ctx = GetContext()->GetScriptEngine().GetContext(); auto ctx = GetContext()->GetScriptEngine().GetContext();
auto el = _element->AsEntrance(); auto el = _element->AsEntrance();
if (el != nullptr) if (el != nullptr)
duk_push_int(ctx, el->GetPathType()); duk_push_int(ctx, el->GetSurfaceEntryIndex());
else else
duk_push_null(ctx); duk_push_null(ctx);
return DukValue::take_from_stack(ctx); return DukValue::take_from_stack(ctx);
@ -1349,7 +1349,7 @@ namespace OpenRCT2::Scripting
auto el = _element->AsEntrance(); auto el = _element->AsEntrance();
if (el != nullptr) if (el != nullptr)
{ {
el->SetPathType(value); el->SetSurfaceEntryIndex(value);
Invalidate(); Invalidate();
} }
} }

View File

@ -10,6 +10,7 @@
#include "Entrance.h" #include "Entrance.h"
#include "../Cheats.h" #include "../Cheats.h"
#include "../Context.h"
#include "../Game.h" #include "../Game.h"
#include "../OpenRCT2.h" #include "../OpenRCT2.h"
#include "../actions/ParkEntranceRemoveAction.h" #include "../actions/ParkEntranceRemoveAction.h"
@ -18,6 +19,9 @@
#include "../localisation/StringIds.h" #include "../localisation/StringIds.h"
#include "../management/Finance.h" #include "../management/Finance.h"
#include "../network/network.h" #include "../network/network.h"
#include "../object/FootpathObject.h"
#include "../object/FootpathSurfaceObject.h"
#include "../object/ObjectManager.h"
#include "../ride/Station.h" #include "../ride/Station.h"
#include "../ride/Track.h" #include "../ride/Track.h"
#include "Footpath.h" #include "Footpath.h"
@ -272,12 +276,42 @@ void EntranceElement::SetSequenceIndex(uint8_t newSequenceIndex)
SequenceIndex |= (newSequenceIndex & 0xF); SequenceIndex |= (newSequenceIndex & 0xF);
} }
ObjectEntryIndex EntranceElement::GetPathType() const FootpathObject* EntranceElement::GetPathEntry() const
{ {
return PathType; auto& objMgr = OpenRCT2::GetContext()->GetObjectManager();
return static_cast<FootpathObject*>(objMgr.GetLoadedObject(ObjectType::Paths, GetPathEntryIndex()));
} }
void EntranceElement::SetPathType(ObjectEntryIndex newPathType) ObjectEntryIndex EntranceElement::GetPathEntryIndex() const
{ {
PathType = newPathType; if (flags2 & ENTRANCE_ELEMENT_FLAGS2_PATH_ENTRY)
return PathType;
else
return OBJECT_ENTRY_INDEX_NULL;
}
void EntranceElement::SetPathEntryIndex(ObjectEntryIndex newIndex)
{
PathType = newIndex;
flags2 |= ENTRANCE_ELEMENT_FLAGS2_PATH_ENTRY;
}
ObjectEntryIndex EntranceElement::GetSurfaceEntryIndex() const
{
if (flags2 & ENTRANCE_ELEMENT_FLAGS2_PATH_ENTRY)
return OBJECT_ENTRY_INDEX_NULL;
else
return PathType;
}
FootpathSurfaceObject* EntranceElement::GetSurfaceEntry() const
{
auto& objMgr = OpenRCT2::GetContext()->GetObjectManager();
return static_cast<FootpathSurfaceObject*>(objMgr.GetLoadedObject(ObjectType::FootpathSurface, GetSurfaceEntryIndex()));
}
void EntranceElement::SetSurfaceEntryIndex(ObjectEntryIndex newIndex)
{
PathType = newIndex;
flags2 &= ~ENTRANCE_ELEMENT_FLAGS2_PATH_ENTRY;
} }

View File

@ -29,6 +29,11 @@ assert_struct_size(rct_entrance_type, 8);
struct TileElement; struct TileElement;
enum
{
ENTRANCE_ELEMENT_FLAGS2_PATH_ENTRY = (1 << 0),
};
constexpr const uint8_t ParkEntranceHeight = 12 * COORDS_Z_STEP; constexpr const uint8_t ParkEntranceHeight = 12 * COORDS_Z_STEP;
constexpr const uint8_t RideEntranceHeight = 7 * COORDS_Z_STEP; constexpr const uint8_t RideEntranceHeight = 7 * COORDS_Z_STEP;
constexpr const uint8_t RideExitHeight = 5 * COORDS_Z_STEP; constexpr const uint8_t RideExitHeight = 5 * COORDS_Z_STEP;

View File

@ -19,6 +19,7 @@
#include "../localisation/Localisation.h" #include "../localisation/Localisation.h"
#include "../management/Finance.h" #include "../management/Finance.h"
#include "../network/network.h" #include "../network/network.h"
#include "../object/FootpathObject.h"
#include "../object/FootpathRailingsObject.h" #include "../object/FootpathRailingsObject.h"
#include "../object/FootpathSurfaceObject.h" #include "../object/FootpathSurfaceObject.h"
#include "../object/ObjectList.h" #include "../object/ObjectList.h"
@ -1654,18 +1655,41 @@ void PathElement::SetAdditionIsGhost(bool isGhost)
Flags2 |= FOOTPATH_ELEMENT_FLAGS2_ADDITION_IS_GHOST; Flags2 |= FOOTPATH_ELEMENT_FLAGS2_ADDITION_IS_GHOST;
} }
FootpathObject* PathElement::GetPathEntry() const
{
auto& objMgr = OpenRCT2::GetContext()->GetObjectManager();
return static_cast<FootpathObject*>(objMgr.GetLoadedObject(ObjectType::Paths, GetPathEntryIndex()));
}
ObjectEntryIndex PathElement::GetPathEntryIndex() const
{
if (Flags2 & FOOTPATH_ELEMENT_FLAGS2_PATH_ENTRY)
return SurfaceIndex;
else
return OBJECT_ENTRY_INDEX_NULL;
}
void PathElement::SetPathEntryIndex(ObjectEntryIndex newIndex)
{
SurfaceIndex = newIndex;
RailingsIndex = OBJECT_ENTRY_INDEX_NULL;
Flags2 |= FOOTPATH_ELEMENT_FLAGS2_PATH_ENTRY;
}
ObjectEntryIndex PathElement::GetSurfaceEntryIndex() const ObjectEntryIndex PathElement::GetSurfaceEntryIndex() const
{ {
return SurfaceIndex; if (Flags2 & FOOTPATH_ELEMENT_FLAGS2_PATH_ENTRY)
return OBJECT_ENTRY_INDEX_NULL;
else
return SurfaceIndex;
} }
ObjectEntryIndex PathElement::GetRailingEntryIndex() const ObjectEntryIndex PathElement::GetRailingEntryIndex() const
{ {
if (RailingsIndex == std::numeric_limits<uint8_t>::max()) if (Flags2 & FOOTPATH_ELEMENT_FLAGS2_PATH_ENTRY)
{
return OBJECT_ENTRY_INDEX_NULL; return OBJECT_ENTRY_INDEX_NULL;
} else
return RailingsIndex; return RailingsIndex;
} }
FootpathSurfaceObject* PathElement::GetSurfaceEntry() const FootpathSurfaceObject* PathElement::GetSurfaceEntry() const
@ -1689,18 +1713,13 @@ FootpathRailingsObject* PathElement::GetRailingEntry() const
void PathElement::SetSurfaceEntryIndex(ObjectEntryIndex newIndex) void PathElement::SetSurfaceEntryIndex(ObjectEntryIndex newIndex)
{ {
SurfaceIndex = newIndex; SurfaceIndex = newIndex;
Flags2 &= ~FOOTPATH_ELEMENT_FLAGS2_PATH_ENTRY;
} }
void PathElement::SetRailingEntryIndex(ObjectEntryIndex newEntryIndex) void PathElement::SetRailingEntryIndex(ObjectEntryIndex newEntryIndex)
{ {
if (newEntryIndex == OBJECT_ENTRY_INDEX_NULL) RailingsIndex = newEntryIndex;
{ Flags2 &= ~FOOTPATH_ELEMENT_FLAGS2_PATH_ENTRY;
RailingsIndex = std::numeric_limits<uint8_t>::max();
}
else
{
RailingsIndex = static_cast<uint8_t>(newEntryIndex);
}
} }
uint8_t PathElement::GetQueueBannerDirection() const uint8_t PathElement::GetQueueBannerDirection() const

View File

@ -98,6 +98,7 @@ enum
FOOTPATH_ELEMENT_FLAGS2_ADDITION_IS_GHOST = (1 << 2), FOOTPATH_ELEMENT_FLAGS2_ADDITION_IS_GHOST = (1 << 2),
FOOTPATH_ELEMENT_FLAGS2_BLOCKED_BY_VEHICLE = (1 << 3), FOOTPATH_ELEMENT_FLAGS2_BLOCKED_BY_VEHICLE = (1 << 3),
FOOTPATH_ELEMENT_FLAGS2_ADDITION_IS_BROKEN = (1 << 4), FOOTPATH_ELEMENT_FLAGS2_ADDITION_IS_BROKEN = (1 << 4),
FOOTPATH_ELEMENT_FLAGS2_PATH_ENTRY = (1 << 5),
}; };
enum enum

View File

@ -22,6 +22,7 @@ struct rct_footpath_entry;
class LargeSceneryObject; class LargeSceneryObject;
class TerrainSurfaceObject; class TerrainSurfaceObject;
class TerrainEdgeObject; class TerrainEdgeObject;
class FootpathObject;
class FootpathSurfaceObject; class FootpathSurfaceObject;
class FootpathRailingsObject; class FootpathRailingsObject;
using track_type_t = uint16_t; using track_type_t = uint16_t;
@ -255,27 +256,24 @@ struct PathElement : TileElementBase
static constexpr TileElementType ElementType = TileElementType::Path; static constexpr TileElementType ElementType = TileElementType::Path;
private: private:
ObjectEntryIndex SurfaceIndex; // 5 ObjectEntryIndex SurfaceIndex; // 5
#pragma clang diagnostic push ObjectEntryIndex RailingsIndex; // 7
#pragma clang diagnostic ignored "-Wunused-private-field" uint8_t Additions; // 9 (0 means no addition)
uint8_t RailingsIndex; // 7 uint8_t EdgesAndCorners; // 11 (edges in lower 4 bits, corners in upper 4)
#pragma clang diagnostic pop uint8_t Flags2; // 12
uint8_t Additions; // 8 (0 means no addition) uint8_t SlopeDirection; // 13
uint8_t EdgesAndCorners; // 9 (edges in lower 4 bits, corners in upper 4)
uint8_t Flags2; // 10
uint8_t SlopeDirection; // 11
union union
{ {
uint8_t AdditionStatus; // 12, only used for litter bins uint8_t AdditionStatus; // 14, only used for litter bins
ride_id_t rideIndex; // 12 ride_id_t rideIndex; // 14
}; };
::StationIndex StationIndex; // 14 ::StationIndex StationIndex; // 15
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-private-field"
uint8_t pad_0F[1];
#pragma clang diagnostic pop
public: public:
FootpathObject* GetPathEntry() const;
ObjectEntryIndex GetPathEntryIndex() const;
void SetPathEntryIndex(ObjectEntryIndex newIndex);
ObjectEntryIndex GetSurfaceEntryIndex() const; ObjectEntryIndex GetSurfaceEntryIndex() const;
FootpathSurfaceObject* GetSurfaceEntry() const; FootpathSurfaceObject* GetSurfaceEntry() const;
void SetSurfaceEntryIndex(ObjectEntryIndex newIndex); void SetSurfaceEntryIndex(ObjectEntryIndex newIndex);
@ -562,10 +560,11 @@ private:
uint8_t SequenceIndex; // 6. Only uses the lower nibble. uint8_t SequenceIndex; // 6. Only uses the lower nibble.
uint8_t StationIndex; // 7 uint8_t StationIndex; // 7
ObjectEntryIndex PathType; // 8 ObjectEntryIndex PathType; // 8
ride_id_t rideIndex; // 9 ride_id_t rideIndex; // A
uint8_t flags2; // C
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-private-field" #pragma clang diagnostic ignored "-Wunused-private-field"
uint8_t pad_0C[4]; uint8_t pad_0C[3];
#pragma clang diagnostic pop #pragma clang diagnostic pop
public: public:
@ -581,8 +580,13 @@ public:
uint8_t GetSequenceIndex() const; uint8_t GetSequenceIndex() const;
void SetSequenceIndex(uint8_t newSequenceIndex); void SetSequenceIndex(uint8_t newSequenceIndex);
ObjectEntryIndex GetPathType() const; FootpathObject* GetPathEntry() const;
void SetPathType(ObjectEntryIndex newPathType); ObjectEntryIndex GetPathEntryIndex() const;
void SetPathEntryIndex(ObjectEntryIndex newIndex);
ObjectEntryIndex GetSurfaceEntryIndex() const;
FootpathSurfaceObject* GetSurfaceEntry() const;
void SetSurfaceEntryIndex(ObjectEntryIndex newIndex);
}; };
assert_struct_size(EntranceElement, 16); assert_struct_size(EntranceElement, 16);