Implement railing override logic

This commit is contained in:
Ted John 2021-04-14 01:34:07 +01:00
parent 476ee6ff5c
commit 23c709c197
12 changed files with 155 additions and 111 deletions

View File

@ -19,6 +19,7 @@
#include <openrct2/core/Guard.hpp>
#include <openrct2/localisation/Localisation.h>
#include <openrct2/localisation/StringIds.h>
#include <openrct2/object/FootpathObject.h>
#include <openrct2/object/TerrainEdgeObject.h>
#include <openrct2/object/TerrainSurfaceObject.h>
#include <openrct2/ride/RideData.h>
@ -1813,7 +1814,9 @@ static void window_tile_inspector_paint(rct_window* w, rct_drawpixelinfo* dpi)
{
// Details
// Path name
rct_string_id pathNameId = tileElement->AsPath()->GetSurfaceEntry()->string_idx;
auto legacyFootpathEntry = reinterpret_cast<rct_footpath_entry*>(
tileElement->AsPath()->GetSurfaceEntry()->GetLegacyData());
rct_string_id pathNameId = legacyFootpathEntry->string_idx;
DrawTextBasic(dpi, screenCoords, STR_TILE_INSPECTOR_PATH_NAME, &pathNameId, { COLOUR_WHITE });
// Path addition

View File

@ -182,6 +182,7 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementUpdateExecute(PathElement*
}
pathElement->SetSurfaceEntryIndex(_type & ~FOOTPATH_ELEMENT_INSERT_QUEUE);
pathElement->SetRailingEntryIndex(OBJECT_ENTRY_INDEX_NULL);
bool isQueue = _type & FOOTPATH_ELEMENT_INSERT_QUEUE;
pathElement->SetIsQueue(isQueue);
@ -348,6 +349,7 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementInsertExecute(GameActions::
pathElement->SetClearanceZ(zHigh);
pathElement->SetSurfaceEntryIndex(_type & ~FOOTPATH_ELEMENT_INSERT_QUEUE);
pathElement->SetRailingEntryIndex(OBJECT_ENTRY_INDEX_NULL);
pathElement->SetSlopeDirection(_slope & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK);
pathElement->SetSloped(_slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED);
pathElement->SetIsQueue(_type & FOOTPATH_ELEMENT_INSERT_QUEUE);

View File

@ -235,6 +235,7 @@ GameActions::Result::Ptr FootpathPlaceFromTrackAction::ElementInsertExecute(Game
pathElement->SetClearanceZ(zHigh);
pathElement->SetSurfaceEntryIndex(_type & ~FOOTPATH_ELEMENT_INSERT_QUEUE);
pathElement->SetRailingEntryIndex(OBJECT_ENTRY_INDEX_NULL);
pathElement->SetSlopeDirection(_slope & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK);
pathElement->SetSloped(_slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED);
pathElement->SetIsQueue(_type & FOOTPATH_ELEMENT_INSERT_QUEUE);

View File

@ -16,6 +16,7 @@
#include "../world/Location.hpp"
struct TileElement;
enum class RailingEntrySupportType : uint8_t;
enum class ViewportInteractionItem : uint8_t;
struct attached_paint_struct
@ -190,6 +191,17 @@ struct paint_session
}
};
struct FootpathPaintInfo
{
uint32_t SurfaceImageId{};
uint32_t BridgeImageId{};
uint32_t RailingsImageId{};
uint32_t SurfaceFlags{};
uint32_t RailingFlags{};
uint8_t ScrollingMode{};
RailingEntrySupportType SupportType{};
};
extern paint_session gPaintSession;
// Globals for paint clipping

View File

@ -1204,7 +1204,7 @@ bool metal_b_supports_paint_setup(
*/
bool path_a_supports_paint_setup(
paint_session* session, int32_t supportType, int32_t special, int32_t height, uint32_t imageColourFlags,
FootpathRailingsObject* railingEntry, bool* underground)
const FootpathPaintInfo& pathPaintInfo, bool* underground)
{
if (underground != nullptr)
{
@ -1237,7 +1237,7 @@ bool path_a_supports_paint_setup(
if (session->Support.slope & 0x20)
{
// save dx2
PaintAddImageAsParent(session, (railingEntry->BridgeImageId + 48) | imageColourFlags, 0, 0, 32, 32, 0, baseHeight - 2);
PaintAddImageAsParent(session, (pathPaintInfo.BridgeImageId + 48) | imageColourFlags, 0, 0, 32, 32, 0, baseHeight - 2);
hasSupports = true;
}
else if (session->Support.slope & 0x10)
@ -1251,7 +1251,7 @@ bool path_a_supports_paint_setup(
}
uint32_t imageId = (supportType * 24) + word_97B3C4[session->Support.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK]
+ railingEntry->BridgeImageId;
+ pathPaintInfo.BridgeImageId;
PaintAddImageAsParent(session, imageId | imageColourFlags, 0, 0, 32, 32, 11, baseHeight, 0, 0, baseHeight + 2);
baseHeight += 16;
@ -1272,7 +1272,7 @@ bool path_a_supports_paint_setup(
}
uint32_t ebx = (supportType * 24) + word_97B3C4[session->Support.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK]
+ railingEntry->BridgeImageId;
+ pathPaintInfo.BridgeImageId;
PaintAddImageAsParent(session, ebx | imageColourFlags, 0, 0, 32, 32, 11, baseHeight, 0, 0, baseHeight + 2);
@ -1284,7 +1284,7 @@ bool path_a_supports_paint_setup(
{
if (baseHeight & 0x10 || heightSteps == 1 || baseHeight + 16 == session->WaterHeight)
{
uint32_t imageId = (supportType * 24) + railingEntry->BridgeImageId + 23;
uint32_t imageId = (supportType * 24) + pathPaintInfo.BridgeImageId + 23;
PaintAddImageAsParent(session, imageId | imageColourFlags, 0, 0, 32, 32, ((heightSteps == 1) ? 7 : 12), baseHeight);
heightSteps -= 1;
@ -1293,7 +1293,7 @@ bool path_a_supports_paint_setup(
}
else
{
uint32_t imageId = (supportType * 24) + railingEntry->BridgeImageId + 22;
uint32_t imageId = (supportType * 24) + pathPaintInfo.BridgeImageId + 22;
PaintAddImageAsParent(
session, imageId | imageColourFlags, 0, 0, 32, 32, ((heightSteps == 2) ? 23 : 28), baseHeight);
@ -1307,7 +1307,7 @@ bool path_a_supports_paint_setup(
{
uint16_t specialIndex = (special - 1) & 0xFFFF;
uint32_t imageId = railingEntry->BridgeImageId + 55 + specialIndex;
uint32_t imageId = pathPaintInfo.BridgeImageId + 55 + specialIndex;
unk_supports_desc supportsDesc = byte_98D8D4[specialIndex];
unk_supports_desc_bound_box boundBox = supportsDesc.bounding_box;
@ -1352,7 +1352,7 @@ bool path_a_supports_paint_setup(
*/
bool path_b_supports_paint_setup(
paint_session* session, int32_t segment, int32_t special, int32_t height, uint32_t imageColourFlags,
FootpathRailingsObject* railingEntry)
const FootpathPaintInfo& pathPaintInfo)
{
support_height* supportSegments = session->SupportSegments;
@ -1374,7 +1374,7 @@ bool path_b_supports_paint_setup(
uint16_t baseHeight;
if ((supportSegments[segment].slope & 0x20) || (height - supportSegments[segment].height < 6)
|| !(railingEntry->Flags & RAILING_ENTRY_FLAG_HAS_SUPPORT_BASE_SPRITE))
|| !(pathPaintInfo.RailingFlags & RAILING_ENTRY_FLAG_HAS_SUPPORT_BASE_SPRITE))
{
baseHeight = supportSegments[segment].height;
}
@ -1384,7 +1384,7 @@ bool path_b_supports_paint_setup(
baseHeight = supportSegments[segment].height;
PaintAddImageAsParent(
session, (railingEntry->BridgeImageId + 37 + imageOffset) | imageColourFlags, SupportBoundBoxes[segment].x,
session, (pathPaintInfo.BridgeImageId + 37 + imageOffset) | imageColourFlags, SupportBoundBoxes[segment].x,
SupportBoundBoxes[segment].y, 0, 0, 5, baseHeight);
baseHeight += 6;
}
@ -1403,7 +1403,7 @@ bool path_b_supports_paint_setup(
if (heightDiff > 0)
{
PaintAddImageAsParent(
session, (railingEntry->BridgeImageId + 20 + (heightDiff - 1)) | imageColourFlags, SupportBoundBoxes[segment].x,
session, (pathPaintInfo.BridgeImageId + 20 + (heightDiff - 1)) | imageColourFlags, SupportBoundBoxes[segment].x,
SupportBoundBoxes[segment].y, 0, 0, heightDiff - 1, baseHeight);
}
@ -1436,7 +1436,7 @@ bool path_b_supports_paint_setup(
}
PaintAddImageAsParent(
session, (railingEntry->BridgeImageId + 20 + (z - 1)) | imageColourFlags, SupportBoundBoxes[segment].x,
session, (pathPaintInfo.BridgeImageId + 20 + (z - 1)) | imageColourFlags, SupportBoundBoxes[segment].x,
SupportBoundBoxes[segment].y, 0, 0, (z - 1), baseHeight);
baseHeight += z;
@ -1447,7 +1447,7 @@ bool path_b_supports_paint_setup(
break;
}
uint32_t imageId = railingEntry->BridgeImageId + 20 + (z - 1);
uint32_t imageId = pathPaintInfo.BridgeImageId + 20 + (z - 1);
if (z == 16)
{
imageId += 1;
@ -1482,7 +1482,7 @@ bool path_b_supports_paint_setup(
break;
}
uint32_t imageId = railingEntry->BridgeImageId + 20 + (z - 1);
uint32_t imageId = pathPaintInfo.BridgeImageId + 20 + (z - 1);
PaintAddImageAsParent(
session, imageId | imageColourFlags, SupportBoundBoxes[segment].x, SupportBoundBoxes[segment].y, 0, 0, 0,
baseHeight, SupportBoundBoxes[segment].x, SupportBoundBoxes[segment].y, baseHeight);

View File

@ -13,6 +13,8 @@
#include "../common.h"
#include "../world/Footpath.h"
struct FootpathPaintInfo;
constexpr const uint8_t NumVanillaWoodenSupportTypes = 49;
bool wooden_a_supports_paint_setup(
@ -25,10 +27,10 @@ bool metal_b_supports_paint_setup(
paint_session* session, uint8_t supportType, uint8_t segment, int32_t special, int32_t height, uint32_t imageColourFlags);
bool path_a_supports_paint_setup(
paint_session* session, int32_t supportType, int32_t special, int32_t height, uint32_t imageColourFlags,
FootpathRailingsObject* railingEntry, bool* underground);
const FootpathPaintInfo& pathPaintInfo, bool* underground);
bool path_b_supports_paint_setup(
paint_session* session, int32_t supportType, int32_t special, int32_t height, uint32_t imageColourFlags,
FootpathRailingsObject* railingEntry);
const FootpathPaintInfo& pathPaintInfo);
// There are 13 types of metal supports. A graphic showing all of them is available here:
// https://cloud.githubusercontent.com/assets/737603/19420485/7eaba28e-93ec-11e6-83cb-03190accc094.png

View File

@ -13,6 +13,7 @@
#include "../../drawing/LightFX.h"
#include "../../interface/Viewport.h"
#include "../../localisation/Localisation.h"
#include "../../object/FootpathObject.h"
#include "../../object/FootpathRailingsObject.h"
#include "../../object/ObjectList.h"
#include "../../object/ObjectManager.h"
@ -85,11 +86,11 @@ static constexpr const uint8_t byte_98D8A4[] = {
// clang-format on
void path_paint_box_support(
paint_session* session, const TileElement* tileElement, int32_t height, PathSurfaceEntry* footpathEntry,
FootpathRailingsObject* railingEntry, bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags);
paint_session* session, const TileElement* tileElement, int32_t height, const FootpathPaintInfo& pathPaintInfo,
bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags);
void path_paint_pole_support(
paint_session* session, const TileElement* tileElement, int16_t height, PathSurfaceEntry* footpathEntry,
FootpathRailingsObject* railingEntry, bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags);
paint_session* session, const TileElement* tileElement, int16_t height, const FootpathPaintInfo& pathPaintInfo,
bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags);
/* rct2: 0x006A5AE5 */
static void path_bit_lights_paint(
@ -325,9 +326,9 @@ static void path_bit_jumping_fountains_paint(
*/
static void sub_6A4101(
paint_session* session, const TileElement* tile_element, uint16_t height, uint32_t connectedEdges, bool hasSupports,
PathSurfaceEntry* surfaceEntry, FootpathRailingsObject* railingEntry, uint32_t imageFlags)
const FootpathPaintInfo& pathPaintInfo, uint32_t imageFlags)
{
uint32_t base_image_id = railingEntry->RailingsImageId | imageFlags;
uint32_t base_image_id = pathPaintInfo.RailingsImageId | imageFlags;
if (tile_element->AsPath()->IsQueue())
{
@ -449,7 +450,7 @@ static void sub_6A4101(
auto ride = get_ride(tile_element->AsPath()->GetRideIndex());
if (direction < 2 && ride != nullptr && imageFlags == 0)
{
uint16_t scrollingMode = railingEntry->ScrollingMode;
uint16_t scrollingMode = pathPaintInfo.ScrollingMode;
scrollingMode += direction;
auto ft = Formatter();
@ -492,12 +493,12 @@ static void sub_6A4101(
uint32_t drawnCorners = 0;
// If the path is not drawn over the supports, then no corner sprites will be drawn (making double-width paths
// look like connected series of intersections).
if (railingEntry->Flags & RAILING_ENTRY_FLAG_DRAW_PATH_OVER_SUPPORTS)
if (pathPaintInfo.RailingFlags & RAILING_ENTRY_FLAG_DRAW_PATH_OVER_SUPPORTS)
{
drawnCorners = (connectedEdges & FOOTPATH_PROPERTIES_EDGES_CORNERS_MASK) >> 4;
}
auto slopeRailingsSupported = !(surfaceEntry->flags & FOOTPATH_ENTRY_FLAG_NO_SLOPE_RAILINGS);
auto slopeRailingsSupported = !(pathPaintInfo.SurfaceFlags & FOOTPATH_ENTRY_FLAG_NO_SLOPE_RAILINGS);
if ((hasSupports || slopeRailingsSupported) && tile_element->AsPath()->IsSloped())
{
switch ((tile_element->AsPath()->GetSlopeDirection() + session->CurrentRotation)
@ -673,8 +674,7 @@ static void sub_6A4101(
*/
static void sub_6A3F61(
paint_session* session, const TileElement* tile_element, uint16_t connectedEdges, uint16_t height,
PathSurfaceEntry* surfaceEntry, FootpathRailingsObject* railingEntry, uint32_t imageFlags, uint32_t sceneryImageFlags,
bool hasSupports)
const FootpathPaintInfo& pathPaintInfo, uint32_t imageFlags, uint32_t sceneryImageFlags, bool hasSupports)
{
// eax --
// ebx --
@ -754,7 +754,7 @@ static void sub_6A3F61(
// Redundant zoom-level check removed
if (paintScenery)
sub_6A4101(session, tile_element, height, connectedEdges, hasSupports, surfaceEntry, railingEntry, imageFlags);
sub_6A4101(session, tile_element, height, connectedEdges, hasSupports, pathPaintInfo, imageFlags);
}
// This is about tunnel drawing
@ -944,20 +944,42 @@ void path_paint(paint_session* session, uint16_t height, const TileElement* tile
PaintAddImageAsParent(session, imageId, 16, 16, 1, 1, 0, heightMarkerBaseZ);
}
PathSurfaceEntry* footpathEntry = tile_element->AsPath()->GetSurfaceEntry();
auto railingEntry = tile_element->AsPath()->GetRailingEntry();
if (footpathEntry != nullptr && railingEntry != nullptr)
auto footpathObj = tile_element->AsPath()->GetSurfaceEntry();
if (footpathObj != nullptr)
{
if (railingEntry->SupportType == RailingEntrySupportType::Pole)
auto surfaceEntry = tile_element->AsPath()->IsQueue() ? footpathObj->GetQueueEntry()
: footpathObj->GetPathSurfaceEntry();
auto railingsEntry = footpathObj->GetPathRailingsEntry();
FootpathPaintInfo pathPaintInfo;
pathPaintInfo.SurfaceImageId = surfaceEntry->image;
pathPaintInfo.SurfaceFlags = surfaceEntry->flags;
auto railingObj = tile_element->AsPath()->GetRailingEntry();
if (railingObj != nullptr)
{
path_paint_pole_support(
session, tile_element, height, footpathEntry, railingEntry, hasSupports, imageFlags, sceneryImageFlags);
pathPaintInfo.BridgeImageId = railingObj->BridgeImageId;
pathPaintInfo.RailingsImageId = railingObj->RailingsImageId;
pathPaintInfo.RailingFlags = railingObj->Flags;
pathPaintInfo.ScrollingMode = railingObj->ScrollingMode;
pathPaintInfo.SupportType = railingObj->SupportType;
}
else
{
path_paint_box_support(
session, tile_element, height, footpathEntry, railingEntry, hasSupports, imageFlags, sceneryImageFlags);
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);
}
else
{
path_paint_box_support(session, tile_element, height, pathPaintInfo, hasSupports, imageFlags, sceneryImageFlags);
}
}
@ -994,8 +1016,8 @@ void path_paint(paint_session* session, uint16_t height, const TileElement* tile
}
void path_paint_box_support(
paint_session* session, const TileElement* tileElement, int32_t height, PathSurfaceEntry* footpathEntry,
FootpathRailingsObject* railingEntry, bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags)
paint_session* session, const TileElement* tileElement, int32_t height, const FootpathPaintInfo& pathPaintInfo,
bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags)
{
const PathElement* pathElement = tileElement->AsPath();
@ -1011,20 +1033,18 @@ void path_paint_box_support(
uint16_t edi = edges | (corners << 4);
uint32_t imageId;
uint32_t imageId = pathPaintInfo.SurfaceImageId;
if (tileElement->AsPath()->IsSloped())
{
imageId = ((tileElement->AsPath()->GetSlopeDirection() + session->CurrentRotation)
& FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK)
imageId += ((tileElement->AsPath()->GetSlopeDirection() + session->CurrentRotation)
& FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK)
+ 16;
}
else
{
imageId = byte_98D6E0[edi];
imageId += byte_98D6E0[edi];
}
imageId += footpathEntry->image;
if (!session->DidPassSurface)
{
boundBoxOffset.x = 3;
@ -1059,11 +1079,11 @@ void path_paint_box_support(
{
image_id = ((tileElement->AsPath()->GetSlopeDirection() + session->CurrentRotation)
& FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK)
+ railingEntry->BridgeImageId + 51;
+ pathPaintInfo.BridgeImageId + 51;
}
else
{
image_id = byte_98D8A4[edges] + railingEntry->BridgeImageId + 49;
image_id = byte_98D8A4[edges] + pathPaintInfo.BridgeImageId + 49;
}
PaintAddImageAsParent(
@ -1071,7 +1091,7 @@ void path_paint_box_support(
height + boundingBoxZOffset);
// TODO: Revert this when path import works correctly.
if (!pathElement->IsQueue() && !(railingEntry->Flags & RAILING_ENTRY_FLAG_DRAW_PATH_OVER_SUPPORTS))
if (!pathElement->IsQueue() && !(pathPaintInfo.RailingFlags & RAILING_ENTRY_FLAG_DRAW_PATH_OVER_SUPPORTS))
{
// don't draw
}
@ -1083,7 +1103,7 @@ void path_paint_box_support(
}
}
sub_6A3F61(session, tileElement, edi, height, footpathEntry, railingEntry, imageFlags, sceneryImageFlags, hasSupports);
sub_6A3F61(session, tileElement, edi, height, pathPaintInfo, imageFlags, sceneryImageFlags, hasSupports);
uint16_t ax = 0;
if (tileElement->AsPath()->IsSloped())
@ -1091,14 +1111,8 @@ void path_paint_box_support(
ax = ((tileElement->AsPath()->GetSlopeDirection() + session->CurrentRotation) & 0x3) + 1;
}
if (byte_98D8A4[edges] == 0)
{
path_a_supports_paint_setup(session, 0, ax, height, imageFlags, railingEntry, nullptr);
}
else
{
path_a_supports_paint_setup(session, 1, ax, height, imageFlags, railingEntry, nullptr);
}
auto supportType = byte_98D8A4[edges] == 0 ? 0 : 1;
path_a_supports_paint_setup(session, supportType, ax, height, imageFlags, pathPaintInfo, nullptr);
height += 32;
if (tileElement->AsPath()->IsSloped())
@ -1144,8 +1158,8 @@ void path_paint_box_support(
}
void path_paint_pole_support(
paint_session* session, const TileElement* tileElement, int16_t height, PathSurfaceEntry* footpathEntry,
FootpathRailingsObject* railingEntry, bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags)
paint_session* session, const TileElement* tileElement, int16_t height, const FootpathPaintInfo& pathPaintInfo,
bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags)
{
const PathElement* pathElement = tileElement->AsPath();
@ -1162,18 +1176,16 @@ void path_paint_pole_support(
uint16_t edi = edges | (corners << 4);
uint32_t imageId;
uint32_t imageId = pathPaintInfo.SurfaceImageId;
if (tileElement->AsPath()->IsSloped())
{
imageId = ((tileElement->AsPath()->GetSlopeDirection() + session->CurrentRotation) & 3) + 16;
imageId += ((tileElement->AsPath()->GetSlopeDirection() + session->CurrentRotation) & 3) + 16;
}
else
{
imageId = byte_98D6E0[edi];
imageId += byte_98D6E0[edi];
}
imageId += footpathEntry->image;
// Below Surface
if (!session->DidPassSurface)
{
@ -1209,11 +1221,11 @@ void path_paint_pole_support(
{
bridgeImage = ((tileElement->AsPath()->GetSlopeDirection() + session->CurrentRotation)
& FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK)
+ railingEntry->BridgeImageId + 16;
+ pathPaintInfo.BridgeImageId + 16;
}
else
{
bridgeImage = edges + railingEntry->BridgeImageId;
bridgeImage = edges + pathPaintInfo.BridgeImageId;
bridgeImage |= imageFlags;
}
@ -1222,7 +1234,7 @@ void path_paint_pole_support(
boundBoxOffset.y, height + boundingBoxZOffset);
// TODO: Revert this when path import works correctly.
if (pathElement->IsQueue() || (railingEntry->Flags & RAILING_ENTRY_FLAG_DRAW_PATH_OVER_SUPPORTS))
if (pathElement->IsQueue() || (pathPaintInfo.RailingFlags & RAILING_ENTRY_FLAG_DRAW_PATH_OVER_SUPPORTS))
{
PaintAddImageAsChild(
session, imageId | imageFlags, 0, 0, boundBoxSize.x, boundBoxSize.y, 0, height, boundBoxOffset.x,
@ -1230,9 +1242,8 @@ void path_paint_pole_support(
}
}
sub_6A3F61(
session, tileElement, edi, height, footpathEntry, railingEntry, imageFlags, sceneryImageFlags,
hasSupports); // TODO: arguments
sub_6A3F61(session, tileElement, edi, height, pathPaintInfo, imageFlags, sceneryImageFlags,
hasSupports); // TODO: arguments
uint16_t ax = 0;
if (tileElement->AsPath()->IsSloped())
@ -1251,7 +1262,7 @@ void path_paint_pole_support(
{
if (!(edges & (1 << i)))
{
path_b_supports_paint_setup(session, supports[i], ax, height, imageFlags, railingEntry);
path_b_supports_paint_setup(session, supports[i], ax, height, imageFlags, pathPaintInfo);
}
}

View File

@ -1132,6 +1132,7 @@ public:
auto src2 = src->AsPath();
dst2->SetSurfaceEntryIndex(src2->GetEntryIndex());
dst2->SetRailingEntryIndex(OBJECT_ENTRY_INDEX_NULL);
dst2->SetQueueBannerDirection(src2->GetQueueBannerDirection());
dst2->SetSloped(src2->IsSloped());
dst2->SetSlopeDirection(src2->GetSlopeDirection());
@ -1567,6 +1568,14 @@ public:
}
RCT12AddDefaultObjects(objectList);
// Add default railings
objectList.SetObject(ObjectType::FootpathRailings, 0, "rct2.railings.wood");
objectList.SetObject(ObjectType::FootpathRailings, 1, "rct2.railings.concrete");
objectList.SetObject(ObjectType::FootpathRailings, 2, "rct2.railings.space");
objectList.SetObject(ObjectType::FootpathRailings, 3, "rct2.railings.black");
objectList.SetObject(ObjectType::FootpathRailings, 4, "rct2.railings.brown");
return objectList;
}
};

View File

@ -272,12 +272,12 @@ void EntranceElement::SetSequenceIndex(uint8_t newSequenceIndex)
SequenceIndex |= (newSequenceIndex & 0xF);
}
PathSurfaceIndex EntranceElement::GetPathType() const
ObjectEntryIndex EntranceElement::GetPathType() const
{
return PathType;
}
void EntranceElement::SetPathType(PathSurfaceIndex newPathType)
void EntranceElement::SetPathType(ObjectEntryIndex newPathType)
{
PathType = newPathType;
}

View File

@ -1649,37 +1649,53 @@ void PathElement::SetAdditionIsGhost(bool isGhost)
Flags2 |= FOOTPATH_ELEMENT_FLAGS2_ADDITION_IS_GHOST;
}
PathSurfaceIndex PathElement::GetSurfaceEntryIndex() const
ObjectEntryIndex PathElement::GetSurfaceEntryIndex() const
{
return SurfaceIndex;
}
PathRailingsIndex PathElement::GetRailingEntryIndex() const
ObjectEntryIndex PathElement::GetRailingEntryIndex() const
{
if (RailingsIndex == std::numeric_limits<uint8_t>::max())
{
return OBJECT_ENTRY_INDEX_NULL;
}
return RailingsIndex;
}
PathSurfaceEntry* PathElement::GetSurfaceEntry() const
FootpathObject* PathElement::GetSurfaceEntry() const
{
if (!IsQueue())
return get_path_surface_entry(GetSurfaceEntryIndex());
else
return get_path_surface_entry(GetSurfaceEntryIndex() + MAX_PATH_OBJECTS);
auto& objMgr = OpenRCT2::GetContext()->GetObjectManager();
return static_cast<FootpathObject*>(objMgr.GetLoadedObject(ObjectType::Paths, GetSurfaceEntryIndex()));
}
FootpathRailingsObject* PathElement::GetRailingEntry() const
{
return get_path_railings_entry(GetRailingEntryIndex());
auto entryIndex = GetRailingEntryIndex();
if (entryIndex == OBJECT_ENTRY_INDEX_NULL)
{
return nullptr;
}
auto& objMgr = OpenRCT2::GetContext()->GetObjectManager();
return static_cast<FootpathRailingsObject*>(objMgr.GetLoadedObject(ObjectType::FootpathRailings, entryIndex));
}
void PathElement::SetSurfaceEntryIndex(PathSurfaceIndex newIndex)
void PathElement::SetSurfaceEntryIndex(ObjectEntryIndex newIndex)
{
SurfaceIndex = newIndex & ~FOOTPATH_ELEMENT_INSERT_QUEUE;
SurfaceIndex = newIndex;
}
void PathElement::SetRailingEntryIndex(PathRailingsIndex newEntryIndex)
void PathElement::SetRailingEntryIndex(ObjectEntryIndex newEntryIndex)
{
RailingsIndex = newEntryIndex;
if (newEntryIndex == OBJECT_ENTRY_INDEX_NULL)
{
RailingsIndex = std::numeric_limits<uint8_t>::max();
}
else
{
RailingsIndex = static_cast<uint8_t>(newEntryIndex);
}
}
uint8_t PathElement::GetQueueBannerDirection() const
@ -2243,7 +2259,7 @@ void footpath_remove_edges_at(const CoordsXY& footpathPos, TileElement* tileElem
tileElement->AsPath()->SetEdgesAndCorners(0);
}
PathSurfaceEntry* get_path_surface_entry(PathSurfaceIndex entryIndex)
PathSurfaceEntry* get_path_surface_entry(ObjectEntryIndex entryIndex)
{
PathSurfaceEntry* result = nullptr;
auto& objMgr = OpenRCT2::GetContext()->GetObjectManager();
@ -2259,12 +2275,6 @@ PathSurfaceEntry* get_path_surface_entry(PathSurfaceIndex entryIndex)
return result;
}
FootpathRailingsObject* get_path_railings_entry(PathRailingsIndex entryIndex)
{
auto& objMgr = OpenRCT2::GetContext()->GetObjectManager();
return static_cast<FootpathRailingsObject*>(objMgr.GetLoadedObject(ObjectType::FootpathRailings, entryIndex));
}
ride_id_t PathElement::GetRideIndex() const
{
return rideIndex;

View File

@ -29,12 +29,6 @@ constexpr auto PATH_CLEARANCE = 4 * COORDS_Z_STEP;
#define FOOTPATH_ELEMENT_INSERT_QUEUE 0x80
using PathSurfaceIndex = uint16_t;
constexpr PathSurfaceIndex PATH_SURFACE_INDEX_NULL = static_cast<PathSurfaceIndex>(-1);
using PathRailingsIndex = uint8_t;
constexpr PathRailingsIndex PATH_RAILINGS_INDEX_NULL = static_cast<PathRailingsIndex>(-1);
enum class RailingEntrySupportType : uint8_t
{
Box = 0,
@ -201,8 +195,7 @@ int32_t footpath_is_connected_to_map_edge(const CoordsXYZ& footpathPos, int32_t
void footpath_remove_edges_at(const CoordsXY& footpathPos, TileElement* tileElement);
int32_t entrance_get_directions(const TileElement* tileElement);
PathSurfaceEntry* get_path_surface_entry(PathSurfaceIndex entryIndex);
FootpathRailingsObject* get_path_railings_entry(PathRailingsIndex entryIndex);
PathSurfaceEntry* get_path_surface_entry(ObjectEntryIndex entryIndex);
void footpath_queue_chain_reset();
void footpath_queue_chain_push(ride_id_t rideIndex);

View File

@ -22,6 +22,7 @@ struct rct_footpath_entry;
class LargeSceneryObject;
class TerrainSurfaceObject;
class TerrainEdgeObject;
class FootpathObject;
class FootpathRailingsObject;
using track_type_t = uint16_t;
@ -254,10 +255,10 @@ struct PathElement : TileElementBase
static constexpr TileElementType ElementType = TileElementType::Path;
private:
PathSurfaceIndex SurfaceIndex; // 5
ObjectEntryIndex SurfaceIndex; // 5
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-private-field"
PathRailingsIndex RailingsIndex; // 7
uint8_t RailingsIndex; // 7
#pragma clang diagnostic pop
uint8_t Additions; // 8 (0 means no addition)
uint8_t EdgesAndCorners; // 9 (edges in lower 4 bits, corners in upper 4)
@ -275,13 +276,13 @@ private:
#pragma clang diagnostic pop
public:
PathSurfaceIndex GetSurfaceEntryIndex() const;
PathSurfaceEntry* GetSurfaceEntry() const;
void SetSurfaceEntryIndex(PathSurfaceIndex newIndex);
ObjectEntryIndex GetSurfaceEntryIndex() const;
FootpathObject* GetSurfaceEntry() const;
void SetSurfaceEntryIndex(ObjectEntryIndex newIndex);
PathRailingsIndex GetRailingEntryIndex() const;
ObjectEntryIndex GetRailingEntryIndex() const;
FootpathRailingsObject* GetRailingEntry() const;
void SetRailingEntryIndex(PathRailingsIndex newIndex);
void SetRailingEntryIndex(ObjectEntryIndex newIndex);
uint8_t GetQueueBannerDirection() const;
void SetQueueBannerDirection(uint8_t direction);
@ -560,7 +561,7 @@ private:
uint8_t entranceType; // 5
uint8_t SequenceIndex; // 6. Only uses the lower nibble.
uint8_t StationIndex; // 7
PathSurfaceIndex PathType; // 8
ObjectEntryIndex PathType; // 8
ride_id_t rideIndex; // 9
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-private-field"
@ -580,8 +581,8 @@ public:
uint8_t GetSequenceIndex() const;
void SetSequenceIndex(uint8_t newSequenceIndex);
PathSurfaceIndex GetPathType() const;
void SetPathType(PathSurfaceIndex newPathType);
ObjectEntryIndex GetPathType() const;
void SetPathType(ObjectEntryIndex newPathType);
};
assert_struct_size(EntranceElement, 16);