diff --git a/src/openrct2-ui/windows/TrackDesignPlace.cpp b/src/openrct2-ui/windows/TrackDesignPlace.cpp index c3dcd8bff8..dd1dea5027 100644 --- a/src/openrct2-ui/windows/TrackDesignPlace.cpp +++ b/src/openrct2-ui/windows/TrackDesignPlace.cpp @@ -506,7 +506,7 @@ private: // Draw entrance and exit preview. for (const auto& entrance : td6->entrance_elements) { - auto rotatedAndOffsetEntrance = origin + CoordsXY{ entrance.x, entrance.y }.Rotate(rotation); + auto rotatedAndOffsetEntrance = origin + entrance.Location.ToCoordsXY().Rotate(rotation); if (pass == 0) { @@ -521,7 +521,7 @@ private: if (DrawMiniPreviewIsPixelInBounds(pixelPosition)) { uint8_t* pixel = DrawMiniPreviewGetPixelPtr(pixelPosition); - uint8_t colour = entrance.isExit ? _PaletteIndexColourExit : _PaletteIndexColourEntrance; + uint8_t colour = entrance.IsExit ? _PaletteIndexColourExit : _PaletteIndexColourEntrance; for (int32_t i = 0; i < 4; i++) { pixel[338 + i] = colour; // x + 2, y + 2 diff --git a/src/openrct2/core/DataSerialiserTraits.h b/src/openrct2/core/DataSerialiserTraits.h index 6f783e8007..10a685da5b 100644 --- a/src/openrct2/core/DataSerialiserTraits.h +++ b/src/openrct2/core/DataSerialiserTraits.h @@ -724,26 +724,20 @@ template<> struct DataSerializerTraitsT { static void encode(OpenRCT2::IStream* stream, const TrackDesignEntranceElement& val) { - stream->Write(&val.x); - stream->Write(&val.y); - stream->Write(&val.z); - stream->Write(&val.direction); - stream->Write(&val.isExit); + stream->Write(&val.Location); + stream->Write(&val.IsExit); } static void decode(OpenRCT2::IStream* stream, TrackDesignEntranceElement& val) { - stream->Read(&val.x); - stream->Read(&val.y); - stream->Read(&val.z); - stream->Read(&val.direction); - stream->Read(&val.isExit); + stream->Read(&val.Location); + stream->Read(&val.IsExit); } static void log(OpenRCT2::IStream* stream, const TrackDesignEntranceElement& val) { char msg[128] = {}; snprintf( - msg, sizeof(msg), "TrackDesignEntranceElement(x = %d, y = %d, z = %d, dir = %d, isExit = %d)", val.x, val.y, val.z, - val.direction, val.isExit); + msg, sizeof(msg), "TrackDesignEntranceElement(x = %d, y = %d, z = %d, dir = %d, isExit = %d)", val.Location.x, + val.Location.y, val.Location.z, val.Location.direction, val.IsExit); stream->Write(msg, strlen(msg)); } }; diff --git a/src/openrct2/rct2/RCT2.h b/src/openrct2/rct2/RCT2.h index 2505de3d39..fb44885efe 100644 --- a/src/openrct2/rct2/RCT2.h +++ b/src/openrct2/rct2/RCT2.h @@ -298,6 +298,16 @@ namespace RCT2 uint8_t direction; // 0x01 int16_t x; // 0x02 int16_t y; // 0x04 + + constexpr Direction GetDirection() const + { + return (direction & 0b00001111); + } + + constexpr bool IsExit() const + { + return !!(direction >> 7); + } }; assert_struct_size(TD6EntranceElement, 0x06); diff --git a/src/openrct2/rct2/T6Exporter.cpp b/src/openrct2/rct2/T6Exporter.cpp index 7b68ec762d..f1d44d754f 100644 --- a/src/openrct2/rct2/T6Exporter.cpp +++ b/src/openrct2/rct2/T6Exporter.cpp @@ -125,10 +125,12 @@ namespace RCT2 for (const auto& entranceElement : _trackDesign->entrance_elements) { - tempStream.WriteValue(entranceElement.z == -1 ? static_cast(0x80) : entranceElement.z); - tempStream.WriteValue(entranceElement.direction | (entranceElement.isExit << 7)); - tempStream.WriteValue(entranceElement.x); - tempStream.WriteValue(entranceElement.y); + tempStream.WriteValue( + entranceElement.Location.z == -1 ? static_cast(0x80) : entranceElement.Location.z); + tempStream.WriteValue(entranceElement.Location.direction | (entranceElement.IsExit << 7)); + auto xy = entranceElement.Location.ToCoordsXY(); + tempStream.WriteValue(xy.x); + tempStream.WriteValue(xy.y); } tempStream.WriteValue(0xFF); diff --git a/src/openrct2/rct2/T6Importer.cpp b/src/openrct2/rct2/T6Importer.cpp index 0679d6614e..6746d651ff 100644 --- a/src/openrct2/rct2/T6Importer.cpp +++ b/src/openrct2/rct2/T6Importer.cpp @@ -182,11 +182,10 @@ namespace RCT2 _stream.SetPosition(_stream.GetPosition() - 1); _stream.Read(&t6EntranceElement, sizeof(TD6EntranceElement)); TrackDesignEntranceElement entranceElement{}; - entranceElement.z = (t6EntranceElement.z == -128) ? -1 : t6EntranceElement.z; - entranceElement.direction = t6EntranceElement.direction & 0x7F; - entranceElement.x = t6EntranceElement.x; - entranceElement.y = t6EntranceElement.y; - entranceElement.isExit = t6EntranceElement.direction >> 7; + auto xy = CoordsXY(t6EntranceElement.x, t6EntranceElement.y); + auto z = (t6EntranceElement.z == -128) ? -1 : t6EntranceElement.z; + entranceElement.Location = TileCoordsXYZD(TileCoordsXY(xy), z, t6EntranceElement.GetDirection()); + entranceElement.IsExit = t6EntranceElement.IsExit(); td->entrance_elements.push_back(entranceElement); } } diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 9a8158d3a9..0001a9f851 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -300,30 +300,25 @@ ResultWithMessage TrackDesign::CreateTrackDesignTrack(TrackDesignState& tds, con entranceDirection -= _saveDirection; entranceDirection &= TILE_ELEMENT_DIRECTION_MASK; - TrackDesignEntranceElement entrance{}; - entrance.direction = entranceDirection; - mapLocation -= tds.Origin; - // Rotate entrance coordinates backwards to the correct direction - auto rotatedMapLocation = mapLocation.Rotate(0 - _saveDirection); - entrance.x = rotatedMapLocation.x; - entrance.y = rotatedMapLocation.y; + auto rotatedMapLocation = TileCoordsXY(mapLocation.Rotate(0 - _saveDirection)); z -= tds.Origin.z; - z /= 8; + z /= COORDS_Z_STEP; if (z > 127 || z < -126) { return { false, STR_TRACK_TOO_LARGE_OR_TOO_MUCH_SCENERY }; } - entrance.z = z; + TrackDesignEntranceElement entrance{}; + entrance.Location = TileCoordsXYZD(rotatedMapLocation, z, entranceDirection); // If this is the exit version if (i == 1) { - entrance.isExit = true; + entrance.IsExit = true; } entrance_elements.push_back(entrance); } @@ -885,10 +880,10 @@ static void TrackDesignMirrorRide(TrackDesign* td6) for (auto& entrance : td6->entrance_elements) { - entrance.y = -entrance.y; - if (entrance.direction & 1) + entrance.Location.y = -entrance.Location.y; + if (entrance.Location.direction & 1) { - entrance.direction = DirectionReverse(entrance.direction); + entrance.Location.direction = DirectionReverse(entrance.Location.direction); } } } @@ -1722,7 +1717,7 @@ static GameActions::Result TrackDesignPlaceRide(TrackDesignState& tds, TrackDesi for (const auto& entrance : td6->entrance_elements) { rotation = _currentTrackPieceDirection & 3; - CoordsXY entranceMapPos{ entrance.x, entrance.y }; + CoordsXY entranceMapPos = entrance.Location.ToCoordsXY(); auto rotatedEntranceMapPos = entranceMapPos.Rotate(rotation); newCoords = { rotatedEntranceMapPos + tds.Origin, newCoords.z }; @@ -1738,13 +1733,14 @@ static GameActions::Result TrackDesignPlaceRide(TrackDesignState& tds, TrackDesi case PTD_OPERATION_PLACE_GHOST: case PTD_OPERATION_PLACE_TRACK_PREVIEW: { - rotation = (rotation + entrance.direction) & 3; + rotation = (rotation + entrance.Location.direction) & 3; + newCoords.z = entrance.Location.z * COORDS_Z_STEP; + newCoords.z += tds.Origin.z; + if (tds.PlaceOperation != PTD_OPERATION_PLACE_QUERY) { auto tile = CoordsXY{ newCoords } + CoordsDirectionDelta[rotation]; TileElement* tile_element = MapGetFirstElementAt(tile); - newCoords.z = tds.Origin.z / COORDS_Z_STEP; - newCoords.z += entrance.z; if (tile_element == nullptr) { return GameActions::Result(GameActions::Status::InvalidParameters, STR_NONE, STR_NONE); @@ -1756,7 +1752,7 @@ static GameActions::Result TrackDesignPlaceRide(TrackDesignState& tds, TrackDesi { continue; } - if (tile_element->BaseHeight != newCoords.z) + if (tile_element->GetBaseZ() != newCoords.z) { continue; } @@ -1783,7 +1779,7 @@ static GameActions::Result TrackDesignPlaceRide(TrackDesignState& tds, TrackDesi } auto rideEntranceExitPlaceAction = RideEntranceExitPlaceAction( - newCoords, rotation, ride.id, stationIndex, entrance.isExit); + newCoords, rotation, ride.id, stationIndex, entrance.IsExit); rideEntranceExitPlaceAction.SetFlags(flags); auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&rideEntranceExitPlaceAction) : GameActions::QueryNested(&rideEntranceExitPlaceAction); @@ -1800,9 +1796,6 @@ static GameActions::Result TrackDesignPlaceRide(TrackDesignState& tds, TrackDesi } else { - newCoords.z = entrance.z * COORDS_Z_STEP; - newCoords.z += tds.Origin.z; - auto res = RideEntranceExitPlaceAction::TrackPlaceQuery(newCoords, false); if (res.Error != GameActions::Status::Ok) { diff --git a/src/openrct2/ride/TrackDesign.h b/src/openrct2/ride/TrackDesign.h index 07e6777735..d461120c1a 100644 --- a/src/openrct2/ride/TrackDesign.h +++ b/src/openrct2/ride/TrackDesign.h @@ -41,11 +41,8 @@ struct TrackDesignState /* Track Entrance entry */ struct TrackDesignEntranceElement { - int8_t z; - uint8_t direction; - int16_t x; - int16_t y; - bool isExit; + TileCoordsXYZD Location{}; + bool IsExit{}; }; struct TrackDesignSceneryElement