mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-15 11:03:00 +01:00
Create struct for footpath slope
This commit is contained in:
@@ -51,7 +51,7 @@ using namespace OpenRCT2::Numerics;
|
||||
namespace OpenRCT2::Ui::Windows
|
||||
{
|
||||
static money64 FootpathProvisionalSet(
|
||||
ObjectEntryIndex type, ObjectEntryIndex railingsType, const CoordsXYZ& footpathLoc, int32_t slope,
|
||||
ObjectEntryIndex type, ObjectEntryIndex railingsType, const CoordsXYZ& footpathLoc, FootpathSlope slope,
|
||||
PathConstructFlags constructFlags);
|
||||
|
||||
enum class PathConstructionMode : uint8_t
|
||||
@@ -82,7 +82,7 @@ namespace OpenRCT2::Ui::Windows
|
||||
{
|
||||
ObjectEntryIndex type;
|
||||
CoordsXYZ position;
|
||||
uint8_t slope;
|
||||
FootpathSlope slope;
|
||||
ProvisionalPathFlags flags;
|
||||
ObjectEntryIndex surfaceIndex;
|
||||
ObjectEntryIndex railingsIndex;
|
||||
@@ -533,7 +533,7 @@ namespace OpenRCT2::Ui::Windows
|
||||
FootpathPlacementResult FootpathGetPlacementFromScreenCoords(const ScreenCoordsXY& screenCoords)
|
||||
{
|
||||
if (_footpathPlaceZ > 0)
|
||||
return { _footpathPlaceZ, kTileSlopeFlat };
|
||||
return { _footpathPlaceZ, {} };
|
||||
|
||||
auto info = GetMapCoordinatesFromPos(
|
||||
screenCoords, EnumsToFlags(ViewportInteractionItem::terrain, ViewportInteractionItem::footpath));
|
||||
@@ -566,7 +566,7 @@ namespace OpenRCT2::Ui::Windows
|
||||
ObjectEntryIndex railings = gFootpathSelection.Railings;
|
||||
|
||||
CoordsXYZ footpathLoc;
|
||||
int32_t slope;
|
||||
FootpathSlope slope;
|
||||
FootpathGetNextPathInfo(&type, footpathLoc, &slope);
|
||||
auto pathConstructFlags = FootpathCreateConstructFlags(type);
|
||||
|
||||
@@ -583,7 +583,7 @@ namespace OpenRCT2::Ui::Windows
|
||||
|
||||
_provisionalFootpath.flags.flip(ProvisionalPathFlag::showArrow);
|
||||
CoordsXYZ footpathLoc;
|
||||
int32_t slope;
|
||||
FootpathSlope slope;
|
||||
FootpathGetNextPathInfo(nullptr, footpathLoc, &slope);
|
||||
gMapSelectArrowPosition = footpathLoc;
|
||||
gMapSelectArrowDirection = _footpathConstructDirection;
|
||||
@@ -946,10 +946,11 @@ namespace OpenRCT2::Ui::Windows
|
||||
auto pathElement = info.Element->AsPath();
|
||||
if (pathElement != nullptr)
|
||||
{
|
||||
auto slope = pathElement->GetSlopeDirection();
|
||||
auto slopeDirection = pathElement->GetSlopeDirection();
|
||||
FootpathSlope slope = { FootpathSlopeType::flat, slopeDirection };
|
||||
if (pathElement->IsSloped())
|
||||
{
|
||||
slope |= FOOTPATH_PROPERTIES_FLAG_IS_SLOPED;
|
||||
slope.type = FootpathSlopeType::sloped;
|
||||
}
|
||||
return { pathElement->GetBaseZ(), slope };
|
||||
}
|
||||
@@ -1166,7 +1167,7 @@ namespace OpenRCT2::Ui::Windows
|
||||
FootpathUpdateProvisional();
|
||||
|
||||
ObjectEntryIndex type;
|
||||
int32_t slope;
|
||||
FootpathSlope slope;
|
||||
CoordsXYZ footpathLoc;
|
||||
FootpathGetNextPathInfo(&type, footpathLoc, &slope);
|
||||
|
||||
@@ -1416,7 +1417,7 @@ namespace OpenRCT2::Ui::Windows
|
||||
*
|
||||
* rct2: 0x006A7B20
|
||||
*/
|
||||
void FootpathGetNextPathInfo(ObjectEntryIndex* type, CoordsXYZ& footpathLoc, int32_t* slope)
|
||||
void FootpathGetNextPathInfo(ObjectEntryIndex* type, CoordsXYZ& footpathLoc, FootpathSlope* slope)
|
||||
{
|
||||
auto direction = _footpathConstructDirection;
|
||||
footpathLoc.x = _footpathConstructFromPosition.x + CoordsDirectionDelta[direction].x;
|
||||
@@ -1426,14 +1427,14 @@ namespace OpenRCT2::Ui::Windows
|
||||
{
|
||||
*type = gFootpathSelection.GetSelectedSurface();
|
||||
}
|
||||
*slope = kTileSlopeFlat;
|
||||
*slope = {};
|
||||
if (_footpathConstructSlope != 0)
|
||||
{
|
||||
*slope = _footpathConstructDirection | kTileSlopeSCornerUp;
|
||||
*slope = { FootpathSlopeType::sloped, _footpathConstructDirection };
|
||||
if (_footpathConstructSlope != 2)
|
||||
{
|
||||
footpathLoc.z -= kPathHeightStep;
|
||||
*slope ^= kTileSlopeECornerUp;
|
||||
slope->direction = DirectionReverse(slope->direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1686,7 +1687,7 @@ namespace OpenRCT2::Ui::Windows
|
||||
* rct2: 0x006A76FF
|
||||
*/
|
||||
static money64 FootpathProvisionalSet(
|
||||
ObjectEntryIndex type, ObjectEntryIndex railingsType, const CoordsXYZ& footpathLoc, int32_t slope,
|
||||
ObjectEntryIndex type, ObjectEntryIndex railingsType, const CoordsXYZ& footpathLoc, FootpathSlope slope,
|
||||
PathConstructFlags constructFlags)
|
||||
{
|
||||
FootpathRemoveProvisional();
|
||||
@@ -1725,7 +1726,7 @@ namespace OpenRCT2::Ui::Windows
|
||||
VirtualFloorSetHeight(0);
|
||||
}
|
||||
else if (
|
||||
_provisionalFootpath.slope == kTileSlopeFlat
|
||||
_provisionalFootpath.slope.type == FootpathSlopeType::flat
|
||||
|| _provisionalFootpath.position.z < _footpathConstructFromPosition.z)
|
||||
{
|
||||
// Going either straight on, or down.
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
namespace OpenRCT2::GameActions
|
||||
{
|
||||
FootpathLayoutPlaceAction::FootpathLayoutPlaceAction(
|
||||
const CoordsXYZ& loc, uint8_t slope, ObjectEntryIndex type, ObjectEntryIndex railingsType, uint8_t edges,
|
||||
const CoordsXYZ& loc, FootpathSlope slope, ObjectEntryIndex type, ObjectEntryIndex railingsType, uint8_t edges,
|
||||
PathConstructFlags constructFlags)
|
||||
: _loc(loc)
|
||||
, _slope(slope)
|
||||
@@ -52,7 +52,8 @@ namespace OpenRCT2::GameActions
|
||||
void FootpathLayoutPlaceAction::AcceptParameters(GameActionParameterVisitor& visitor)
|
||||
{
|
||||
visitor.Visit(_loc);
|
||||
visitor.Visit("slope", _slope);
|
||||
visitor.Visit("slopeType", _slope.type);
|
||||
visitor.Visit("slopeDirection", _slope.direction);
|
||||
visitor.Visit("object", _type);
|
||||
visitor.Visit("railingsObject", _railingsType);
|
||||
visitor.Visit("edges", _edges);
|
||||
@@ -131,9 +132,9 @@ namespace OpenRCT2::GameActions
|
||||
QuarterTile quarterTile{ 0b1111, 0 };
|
||||
auto zLow = _loc.z;
|
||||
auto zHigh = zLow + kPathClearance;
|
||||
if (_slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED)
|
||||
if (_slope.type == FootpathSlopeType::sloped)
|
||||
{
|
||||
quarterTile = QuarterTile{ 0b1111, 0b1100 }.Rotate(_slope & kTileElementDirectionMask);
|
||||
quarterTile = QuarterTile{ 0b1111, 0b1100 }.Rotate(_slope.direction);
|
||||
zHigh += kPathHeightStep;
|
||||
}
|
||||
|
||||
@@ -151,8 +152,8 @@ namespace OpenRCT2::GameActions
|
||||
|
||||
// Do not attempt to build a crossing with a queue or a sloped path.
|
||||
auto isQueue = _constructFlags & PathConstructFlag::IsQueue;
|
||||
auto crossingMode = isQueue || (_slope != kTileSlopeFlat) ? CreateCrossingMode::none
|
||||
: CreateCrossingMode::pathOverTrack;
|
||||
auto crossingMode = isQueue || (_slope.type != FootpathSlopeType::flat) ? CreateCrossingMode::none
|
||||
: CreateCrossingMode::pathOverTrack;
|
||||
auto canBuild = MapCanConstructWithClearAt(
|
||||
{ _loc, zLow, zHigh }, &MapPlaceNonSceneryClearFunc, quarterTile, GetFlags(), kTileSlopeFlat, crossingMode);
|
||||
if (!entrancePath && canBuild.Error != Status::Ok)
|
||||
@@ -200,9 +201,9 @@ namespace OpenRCT2::GameActions
|
||||
QuarterTile quarterTile{ 0b1111, 0 };
|
||||
auto zLow = _loc.z;
|
||||
auto zHigh = zLow + kPathClearance;
|
||||
if (_slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED)
|
||||
if (_slope.type == FootpathSlopeType::sloped)
|
||||
{
|
||||
quarterTile = QuarterTile{ 0b1111, 0b1100 }.Rotate(_slope & kTileElementDirectionMask);
|
||||
quarterTile = QuarterTile{ 0b1111, 0b1100 }.Rotate(_slope.direction);
|
||||
zHigh += kPathHeightStep;
|
||||
}
|
||||
|
||||
@@ -220,8 +221,8 @@ namespace OpenRCT2::GameActions
|
||||
|
||||
// Do not attempt to build a crossing with a queue or a sloped path.
|
||||
auto isQueue = _constructFlags & PathConstructFlag::IsQueue;
|
||||
auto crossingMode = isQueue || (_slope != kTileSlopeFlat) ? CreateCrossingMode::none
|
||||
: CreateCrossingMode::pathOverTrack;
|
||||
auto crossingMode = isQueue || (_slope.type != FootpathSlopeType::flat) ? CreateCrossingMode::none
|
||||
: CreateCrossingMode::pathOverTrack;
|
||||
auto canBuild = MapCanConstructWithClearAt(
|
||||
{ _loc, zLow, zHigh }, &MapPlaceNonSceneryClearFunc, quarterTile, GAME_COMMAND_FLAG_APPLY | GetFlags(),
|
||||
kTileSlopeFlat, crossingMode);
|
||||
@@ -274,8 +275,8 @@ namespace OpenRCT2::GameActions
|
||||
pathElement->SetSurfaceEntryIndex(_type);
|
||||
pathElement->SetRailingsEntryIndex(_railingsType);
|
||||
}
|
||||
pathElement->SetSlopeDirection(_slope & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK);
|
||||
pathElement->SetSloped(_slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED);
|
||||
pathElement->SetSlopeDirection(_slope.direction);
|
||||
pathElement->SetSloped(_slope.type == FootpathSlopeType::sloped);
|
||||
pathElement->SetIsQueue(isQueue);
|
||||
pathElement->SetAddition(0);
|
||||
pathElement->SetRideIndex(RideId::GetNull());
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace OpenRCT2::GameActions
|
||||
{
|
||||
private:
|
||||
CoordsXYZ _loc;
|
||||
uint8_t _slope{};
|
||||
FootpathSlope _slope{};
|
||||
ObjectEntryIndex _type{};
|
||||
ObjectEntryIndex _railingsType{};
|
||||
uint8_t _edges{};
|
||||
@@ -27,7 +27,7 @@ namespace OpenRCT2::GameActions
|
||||
public:
|
||||
FootpathLayoutPlaceAction() = default;
|
||||
FootpathLayoutPlaceAction(
|
||||
const CoordsXYZ& loc, uint8_t slope, ObjectEntryIndex type, ObjectEntryIndex railingsType, uint8_t edges,
|
||||
const CoordsXYZ& loc, FootpathSlope slope, ObjectEntryIndex type, ObjectEntryIndex railingsType, uint8_t edges,
|
||||
PathConstructFlags constructFlags = 0);
|
||||
|
||||
void AcceptParameters(GameActionParameterVisitor&) final;
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
namespace OpenRCT2::GameActions
|
||||
{
|
||||
FootpathPlaceAction::FootpathPlaceAction(
|
||||
const CoordsXYZ& loc, uint8_t slope, ObjectEntryIndex type, ObjectEntryIndex railingsType, Direction direction,
|
||||
const CoordsXYZ& loc, FootpathSlope slope, ObjectEntryIndex type, ObjectEntryIndex railingsType, Direction direction,
|
||||
PathConstructFlags constructFlags)
|
||||
: _loc(loc)
|
||||
, _slope(slope)
|
||||
@@ -56,7 +56,8 @@ namespace OpenRCT2::GameActions
|
||||
visitor.Visit("object", _type);
|
||||
visitor.Visit("railingsObject", _railingsType);
|
||||
visitor.Visit("direction", _direction);
|
||||
visitor.Visit("slope", _slope);
|
||||
visitor.Visit("slopeType", _slope.type);
|
||||
visitor.Visit("slopeDirection", _slope.direction);
|
||||
visitor.Visit("constructFlags", _constructFlags);
|
||||
}
|
||||
|
||||
@@ -92,7 +93,7 @@ namespace OpenRCT2::GameActions
|
||||
return Result(Status::Disallowed, STR_CANT_BUILD_FOOTPATH_HERE, STR_LAND_NOT_OWNED_BY_PARK);
|
||||
}
|
||||
|
||||
if (_slope & SLOPE_IS_IRREGULAR_FLAG)
|
||||
if (_slope.type == FootpathSlopeType::irregular || _slope.type == FootpathSlopeType::raise)
|
||||
{
|
||||
return Result(Status::Disallowed, STR_CANT_BUILD_FOOTPATH_HERE, STR_LAND_SLOPE_UNSUITABLE);
|
||||
}
|
||||
@@ -116,7 +117,7 @@ namespace OpenRCT2::GameActions
|
||||
auto intent = Intent(INTENT_ACTION_REMOVE_PROVISIONAL_FOOTPATH);
|
||||
ContextBroadcastIntent(&intent);
|
||||
|
||||
auto tileElement = MapGetFootpathElementSlope(_loc, _slope);
|
||||
auto tileElement = MapGetFootpathElementWithSlope(_loc, _slope);
|
||||
if (tileElement == nullptr)
|
||||
{
|
||||
return ElementInsertQuery(std::move(res));
|
||||
@@ -149,14 +150,15 @@ namespace OpenRCT2::GameActions
|
||||
auto zLow = _loc.z;
|
||||
auto zHigh = zLow + kPathClearance;
|
||||
WallRemoveIntersectingWalls(
|
||||
{ _loc, zLow, zHigh + ((_slope & kTileSlopeRaisedCornersMask) ? 16 : 0) }, DirectionReverse(_direction));
|
||||
{ _loc, zLow, zHigh + ((_slope.type == FootpathSlopeType::sloped) ? 16 : 0) },
|
||||
DirectionReverse(_direction));
|
||||
WallRemoveIntersectingWalls(
|
||||
{ _loc.x - CoordsDirectionDelta[_direction].x, _loc.y - CoordsDirectionDelta[_direction].y, zLow, zHigh },
|
||||
_direction);
|
||||
}
|
||||
}
|
||||
|
||||
auto tileElement = MapGetFootpathElementSlope(_loc, _slope);
|
||||
auto tileElement = MapGetFootpathElementWithSlope(_loc, _slope);
|
||||
if (tileElement == nullptr)
|
||||
{
|
||||
return ElementInsertExecute(std::move(res));
|
||||
@@ -295,9 +297,9 @@ namespace OpenRCT2::GameActions
|
||||
QuarterTile quarterTile{ 0b1111, 0 };
|
||||
auto zLow = _loc.z;
|
||||
auto zHigh = zLow + kPathClearance;
|
||||
if (_slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED)
|
||||
if (_slope.type == FootpathSlopeType::sloped)
|
||||
{
|
||||
quarterTile = QuarterTile{ 0b1111, 0b1100 }.Rotate(_slope & kTileElementDirectionMask);
|
||||
quarterTile = QuarterTile{ 0b1111, 0b1100 }.Rotate(_slope.direction);
|
||||
zHigh += kPathHeightStep;
|
||||
}
|
||||
|
||||
@@ -315,8 +317,8 @@ namespace OpenRCT2::GameActions
|
||||
|
||||
// Do not attempt to build a crossing with a queue or a sloped path.
|
||||
auto isQueue = _constructFlags & PathConstructFlag::IsQueue;
|
||||
auto crossingMode = isQueue || (_slope != kTileSlopeFlat) ? CreateCrossingMode::none
|
||||
: CreateCrossingMode::pathOverTrack;
|
||||
auto crossingMode = isQueue || (_slope.type != FootpathSlopeType::flat) ? CreateCrossingMode::none
|
||||
: CreateCrossingMode::pathOverTrack;
|
||||
auto canBuild = MapCanConstructWithClearAt(
|
||||
{ _loc, zLow, zHigh }, &MapPlaceNonSceneryClearFunc, quarterTile, GetFlags(), kTileSlopeFlat, crossingMode);
|
||||
if (!entrancePath && canBuild.Error != Status::Ok)
|
||||
@@ -363,9 +365,9 @@ namespace OpenRCT2::GameActions
|
||||
QuarterTile quarterTile{ 0b1111, 0 };
|
||||
auto zLow = _loc.z;
|
||||
auto zHigh = zLow + kPathClearance;
|
||||
if (_slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED)
|
||||
if (_slope.type == FootpathSlopeType::sloped)
|
||||
{
|
||||
quarterTile = QuarterTile{ 0b1111, 0b1100 }.Rotate(_slope & kTileElementDirectionMask);
|
||||
quarterTile = QuarterTile{ 0b1111, 0b1100 }.Rotate(_slope.direction);
|
||||
zHigh += kPathHeightStep;
|
||||
}
|
||||
|
||||
@@ -383,8 +385,8 @@ namespace OpenRCT2::GameActions
|
||||
|
||||
// Do not attempt to build a crossing with a queue or a sloped.
|
||||
auto isQueue = _constructFlags & PathConstructFlag::IsQueue;
|
||||
auto crossingMode = isQueue || (_slope != kTileSlopeFlat) ? CreateCrossingMode::none
|
||||
: CreateCrossingMode::pathOverTrack;
|
||||
auto crossingMode = isQueue || (_slope.type != FootpathSlopeType::flat) ? CreateCrossingMode::none
|
||||
: CreateCrossingMode::pathOverTrack;
|
||||
auto canBuild = MapCanConstructWithClearAt(
|
||||
{ _loc, zLow, zHigh }, &MapPlaceNonSceneryClearFunc, quarterTile, GAME_COMMAND_FLAG_APPLY | GetFlags(),
|
||||
kTileSlopeFlat, crossingMode);
|
||||
@@ -436,8 +438,8 @@ namespace OpenRCT2::GameActions
|
||||
pathElement->SetSurfaceEntryIndex(_type);
|
||||
pathElement->SetRailingsEntryIndex(_railingsType);
|
||||
}
|
||||
pathElement->SetSlopeDirection(_slope & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK);
|
||||
pathElement->SetSloped(_slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED);
|
||||
pathElement->SetSlopeDirection(_slope.direction);
|
||||
pathElement->SetSloped(_slope.type == FootpathSlopeType::sloped);
|
||||
pathElement->SetIsQueue(isQueue);
|
||||
pathElement->SetAddition(0);
|
||||
pathElement->SetRideIndex(RideId::GetNull());
|
||||
@@ -525,10 +527,9 @@ namespace OpenRCT2::GameActions
|
||||
MapInvalidateTileFull(_loc);
|
||||
}
|
||||
|
||||
PathElement* FootpathPlaceAction::MapGetFootpathElementSlope(const CoordsXYZ& footpathPos, int32_t slope) const
|
||||
PathElement* FootpathPlaceAction::MapGetFootpathElementWithSlope(const CoordsXYZ& footpathPos, FootpathSlope slope) const
|
||||
{
|
||||
const bool isSloped = slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED;
|
||||
const auto slopeDirection = slope & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK;
|
||||
const bool isSloped = slope.type == FootpathSlopeType::sloped;
|
||||
|
||||
for (auto* pathElement : TileElementsView<PathElement>(footpathPos))
|
||||
{
|
||||
@@ -536,7 +537,7 @@ namespace OpenRCT2::GameActions
|
||||
continue;
|
||||
if (pathElement->IsSloped() != isSloped)
|
||||
continue;
|
||||
if (pathElement->GetSlopeDirection() != slopeDirection)
|
||||
if (pathElement->GetSlopeDirection() != slope.direction)
|
||||
continue;
|
||||
return pathElement;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace OpenRCT2::GameActions
|
||||
{
|
||||
private:
|
||||
CoordsXYZ _loc;
|
||||
uint8_t _slope{};
|
||||
FootpathSlope _slope{};
|
||||
ObjectEntryIndex _type{};
|
||||
ObjectEntryIndex _railingsType{};
|
||||
Direction _direction{ kInvalidDirection };
|
||||
@@ -27,7 +27,7 @@ namespace OpenRCT2::GameActions
|
||||
public:
|
||||
FootpathPlaceAction() = default;
|
||||
FootpathPlaceAction(
|
||||
const CoordsXYZ& loc, uint8_t slope, ObjectEntryIndex type, ObjectEntryIndex railingsType,
|
||||
const CoordsXYZ& loc, FootpathSlope slope, ObjectEntryIndex type, ObjectEntryIndex railingsType,
|
||||
Direction direction = kInvalidDirection, PathConstructFlags constructFlags = 0);
|
||||
void AcceptParameters(GameActionParameterVisitor&) final;
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace OpenRCT2::GameActions
|
||||
Result ElementInsertExecute(Result res) const;
|
||||
void AutomaticallySetPeepSpawn() const;
|
||||
void RemoveIntersectingWalls(PathElement* pathElement) const;
|
||||
PathElement* MapGetFootpathElementSlope(const CoordsXYZ& footpathPos, int32_t slope) const;
|
||||
PathElement* MapGetFootpathElementWithSlope(const CoordsXYZ& footpathPos, FootpathSlope slope) const;
|
||||
bool IsSameAsPathElement(const PathElement* pathElement) const;
|
||||
bool IsSameAsEntranceElement(const EntranceElement& entranceElement) const;
|
||||
};
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "../ride/RideColour.h"
|
||||
#include "../ride/TrackDesign.h"
|
||||
#include "../world/Banner.h"
|
||||
#include "../world/Footpath.h"
|
||||
#include "../world/Location.hpp"
|
||||
#include "../world/tile_element/TileElement.h"
|
||||
#include "DataSerialiserTag.h"
|
||||
@@ -989,3 +990,28 @@ struct DataSerializerTraitsT<Banner>
|
||||
stream->Write(msg, strlen(msg));
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct DataSerializerTraitsT<FootpathSlope>
|
||||
{
|
||||
static void encode(OpenRCT2::IStream* stream, const FootpathSlope& slope)
|
||||
{
|
||||
uint8_t combined = (EnumValue(slope.type) << 2) | (slope.direction % kNumOrthogonalDirections);
|
||||
stream->WriteValue(combined);
|
||||
}
|
||||
|
||||
static void decode(OpenRCT2::IStream* stream, FootpathSlope& slope)
|
||||
{
|
||||
auto combined = stream->ReadValue<uint8_t>();
|
||||
auto type = static_cast<FootpathSlopeType>(combined >> 2);
|
||||
Direction direction = combined & 0b00000011;
|
||||
slope = FootpathSlope{ type, direction };
|
||||
}
|
||||
|
||||
static void log(OpenRCT2::IStream* stream, const FootpathSlope& slope)
|
||||
{
|
||||
char msg[128] = {};
|
||||
snprintf(msg, sizeof(msg), "FootpathSlope(type = %d, direction = %d)", EnumValue(slope.type), slope.direction);
|
||||
stream->Write(msg, strlen(msg));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -194,7 +194,7 @@ static void PathPaintSlopedFences(
|
||||
PaintSession& session, const PathElement& pathElement, uint16_t height, ImageId imageId, bool isQueue)
|
||||
{
|
||||
auto queueOffset = isQueue ? 14 : 0;
|
||||
switch ((pathElement.GetSlopeDirection() + session.CurrentRotation) & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK)
|
||||
switch ((pathElement.GetSlopeDirection() + session.CurrentRotation) % kNumOrthogonalDirections)
|
||||
{
|
||||
case 0:
|
||||
PaintAddImageAsParent(
|
||||
@@ -630,7 +630,7 @@ static void PathPaintFencesAdditionsTunnels(
|
||||
}
|
||||
|
||||
// This is about tunnel drawing
|
||||
uint8_t direction = (pathElement.GetSlopeDirection() + session.CurrentRotation) & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK;
|
||||
uint8_t direction = (pathElement.GetSlopeDirection() + session.CurrentRotation) % kNumOrthogonalDirections;
|
||||
bool sloped = pathElement.IsSloped();
|
||||
|
||||
if (connectedEdges & EDGE_SE)
|
||||
@@ -864,8 +864,7 @@ static ImageIndex PathPaintGetBaseImage(
|
||||
ImageIndex surfaceBaseImageIndex = pathPaintInfo.SurfaceImageId;
|
||||
if (pathElement.IsSloped())
|
||||
{
|
||||
auto directionOffset = (pathElement.GetSlopeDirection() + session.CurrentRotation)
|
||||
& FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK;
|
||||
auto directionOffset = (pathElement.GetSlopeDirection() + session.CurrentRotation) % kNumOrthogonalDirections;
|
||||
surfaceBaseImageIndex += 16 + directionOffset;
|
||||
}
|
||||
else
|
||||
@@ -973,8 +972,7 @@ void PathPaintBoxSupport(
|
||||
ImageIndex bridgeBaseImageIndex;
|
||||
if (pathElement.IsSloped())
|
||||
{
|
||||
auto directionOffset = (pathElement.GetSlopeDirection() + session.CurrentRotation)
|
||||
& FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK;
|
||||
auto directionOffset = (pathElement.GetSlopeDirection() + session.CurrentRotation) % kNumOrthogonalDirections;
|
||||
bridgeBaseImageIndex = pathPaintInfo.BridgeImageId + 51 + directionOffset;
|
||||
}
|
||||
else
|
||||
@@ -1028,8 +1026,7 @@ void PathPaintPoleSupport(
|
||||
ImageIndex bridgeBaseImageIndex;
|
||||
if (pathElement.IsSloped())
|
||||
{
|
||||
bridgeBaseImageIndex = ((pathElement.GetSlopeDirection() + session.CurrentRotation)
|
||||
& FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK)
|
||||
bridgeBaseImageIndex = ((pathElement.GetSlopeDirection() + session.CurrentRotation) % kNumOrthogonalDirections)
|
||||
+ pathPaintInfo.BridgeImageId + 16;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -655,9 +655,10 @@ static void ApplyPathFixes(const json_t& scenarioPatch)
|
||||
|
||||
for (auto coordinate : coordinates)
|
||||
{
|
||||
auto slope = direction != kInvalidDirection ? direction + 4 : 0;
|
||||
auto slopeType = direction != kInvalidDirection ? FootpathSlopeType::sloped : FootpathSlopeType::flat;
|
||||
auto footpathPlaceAction = GameActions::FootpathPlaceAction(
|
||||
coordinate.ToCoordsXYZ(), slope, surfaceObjIndex, railingsObjIndex, direction, constructionFlags);
|
||||
coordinate.ToCoordsXYZ(), { slopeType, direction }, surfaceObjIndex, railingsObjIndex, direction,
|
||||
constructionFlags);
|
||||
auto& gameState = getGameState();
|
||||
auto result = footpathPlaceAction.Execute(gameState);
|
||||
if (result.Error != GameActions::Status::Ok)
|
||||
|
||||
@@ -1196,9 +1196,10 @@ static GameActions::Result TrackDesignPlaceSceneryElement(
|
||||
{
|
||||
flags |= GAME_COMMAND_FLAG_REPLAY;
|
||||
}
|
||||
uint8_t slope = (scenery.getSlopeDirection() + rotation) & 0x3;
|
||||
uint8_t slopeDirection = (scenery.getSlopeDirection() + rotation) & 0x3;
|
||||
FootpathSlope slope = { FootpathSlopeType::flat, slopeDirection };
|
||||
if (scenery.hasSlope())
|
||||
slope |= FOOTPATH_PROPERTIES_FLAG_IS_SLOPED;
|
||||
slope.type = FootpathSlopeType::sloped;
|
||||
uint8_t edges = Numerics::rol4(scenery.getEdges(), rotation);
|
||||
PathConstructFlags constructFlags = 0;
|
||||
if (scenery.isQueue())
|
||||
|
||||
@@ -102,23 +102,13 @@ static constexpr uint8_t connected_path_count[] = {
|
||||
};
|
||||
|
||||
/** rct2: 0x0098D8B4 */
|
||||
static constexpr uint8_t kDefaultPathSlope[] = {
|
||||
0,
|
||||
SLOPE_IS_IRREGULAR_FLAG,
|
||||
SLOPE_IS_IRREGULAR_FLAG,
|
||||
FOOTPATH_PROPERTIES_FLAG_IS_SLOPED | 2,
|
||||
SLOPE_IS_IRREGULAR_FLAG,
|
||||
SLOPE_IS_IRREGULAR_FLAG,
|
||||
FOOTPATH_PROPERTIES_FLAG_IS_SLOPED | 3,
|
||||
RAISE_FOOTPATH_FLAG,
|
||||
SLOPE_IS_IRREGULAR_FLAG,
|
||||
FOOTPATH_PROPERTIES_FLAG_IS_SLOPED | 1,
|
||||
SLOPE_IS_IRREGULAR_FLAG,
|
||||
RAISE_FOOTPATH_FLAG,
|
||||
FOOTPATH_PROPERTIES_FLAG_IS_SLOPED | 0,
|
||||
RAISE_FOOTPATH_FLAG,
|
||||
RAISE_FOOTPATH_FLAG,
|
||||
SLOPE_IS_IRREGULAR_FLAG,
|
||||
static constexpr FootpathSlope kDefaultPathSlope[] = {
|
||||
{ FootpathSlopeType::flat }, { FootpathSlopeType::irregular }, { FootpathSlopeType::irregular },
|
||||
{ FootpathSlopeType::sloped, 2 }, { FootpathSlopeType::irregular }, { FootpathSlopeType::irregular },
|
||||
{ FootpathSlopeType::sloped, 3 }, { FootpathSlopeType::raise }, { FootpathSlopeType::irregular },
|
||||
{ FootpathSlopeType::sloped, 1 }, { FootpathSlopeType::irregular }, { FootpathSlopeType::raise },
|
||||
{ FootpathSlopeType::sloped, 0 }, { FootpathSlopeType::raise }, { FootpathSlopeType::raise },
|
||||
{ FootpathSlopeType::irregular },
|
||||
};
|
||||
|
||||
static bool entrance_has_direction(const EntranceElement& entranceElement, int32_t direction)
|
||||
@@ -1923,10 +1913,10 @@ FootpathPlacementResult FootpathGetOnTerrainPlacement(const TileCoordsXY& locati
|
||||
FootpathPlacementResult FootpathGetOnTerrainPlacement(const SurfaceElement& surfaceElement)
|
||||
{
|
||||
int32_t baseZ = surfaceElement.GetBaseZ();
|
||||
uint8_t slope = kDefaultPathSlope[surfaceElement.GetSlope() & kTileSlopeRaisedCornersMask];
|
||||
if (slope & RAISE_FOOTPATH_FLAG)
|
||||
auto slope = kDefaultPathSlope[surfaceElement.GetSlope() & kTileSlopeRaisedCornersMask];
|
||||
if (slope.type == FootpathSlopeType::raise)
|
||||
{
|
||||
slope &= ~RAISE_FOOTPATH_FLAG;
|
||||
slope.type = FootpathSlopeType::flat;
|
||||
baseZ += kPathHeightStep;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,10 +76,31 @@ struct FootpathSelection
|
||||
}
|
||||
};
|
||||
|
||||
enum class FootpathSlopeType : uint8_t
|
||||
{
|
||||
flat,
|
||||
sloped,
|
||||
/**
|
||||
* Land has one corner down, raise the Z coordinate and place a flat piece.
|
||||
*/
|
||||
raise,
|
||||
/**
|
||||
* Terrain has a shape that allows for two different path slopes, and as such it cannot autoplace a piece
|
||||
* without further context of the surrounding paths.
|
||||
*/
|
||||
irregular,
|
||||
};
|
||||
|
||||
struct FootpathSlope
|
||||
{
|
||||
FootpathSlopeType type{};
|
||||
Direction direction{};
|
||||
};
|
||||
|
||||
struct FootpathPlacementResult
|
||||
{
|
||||
int32_t baseZ{};
|
||||
uint8_t slope{};
|
||||
FootpathSlope slope{};
|
||||
|
||||
bool isValid()
|
||||
{
|
||||
|
||||
@@ -32,15 +32,6 @@ namespace OpenRCT2
|
||||
FOOTPATH_ELEMENT_TYPE_DIRECTION_MASK = (1 << 6) | (1 << 7),
|
||||
};
|
||||
|
||||
// Masks and flags for values stored in TileElement.properties.path.type
|
||||
enum
|
||||
{
|
||||
FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK = (1 << 0) | (1 << 1),
|
||||
FOOTPATH_PROPERTIES_FLAG_IS_SLOPED = (1 << 2),
|
||||
FOOTPATH_PROPERTIES_FLAG_HAS_QUEUE_BANNER = (1 << 3),
|
||||
FOOTPATH_PROPERTIES_TYPE_MASK = (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7),
|
||||
};
|
||||
|
||||
// Masks and flags for values stored in TileElement.properties.path.edges
|
||||
enum
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user