Fix #19503. Hide 3+ queue junction railings behind a flag (#19644)

* Fix #19503. Hide 3+ queue junction railings behind a flag

This is to prevent existing parks from changing their behaviour

* Clang format

* Bump version numbers. Update changelog

* Update text
This commit is contained in:
Duncan 2023-03-23 08:16:32 +00:00 committed by GitHub
parent 826fa4769c
commit e904ef406f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 133 additions and 51 deletions

View File

@ -3649,6 +3649,7 @@ STR_6544 :Loan cannot be negative!
STR_6545 :Use RCT1 interest calculation
STR_6546 :Use the interest calculation algorithm of RollerCoaster Tycoon 1, which used a fixed percentage of approximately 1.33%.
STR_6547 :All Scenery
STR_6548 :Show railings at junction
#############
# Scenarios #

View File

@ -23,7 +23,7 @@
- Improved: [#18975] Add lift sprites for 60 steep hills on the wooden roller coaster.
- Improved: [#19044] Added special thanks to RMC and Wiegand to the About page.
- Improved: [#19131] Track missing objects when selecting scenery groups in console.
- Improved: [#19253] Queue junctions drawn properly when using regular paths as queue.
- Improved: [#19253] Queue junctions drawn properly when using regular paths as queue. Note: Requires using tile inspector to indicate railings can be used at T or X junctions.
- Improved: [#19067] New Ride window now allows filtering similarly to Object Selection.
- Improved: [#19272] Scenery window now allows filtering similarly to Object Selection.
- Improved: [#19447] The control key now enables word jumping in text input fields.

View File

@ -109,6 +109,7 @@ enum WindowTileInspectorWidgetIdx
WIDX_PATH_SPINNER_HEIGHT_DECREASE,
WIDX_PATH_CHECK_BROKEN,
WIDX_PATH_CHECK_SLOPED,
WIDX_PATH_CHECK_JUNCTION_RAILINGS,
WIDX_PATH_CHECK_EDGE_NE, // Note: This is NOT named after the world orientation, but after the way
WIDX_PATH_CHECK_EDGE_E, // it looks in the window (top corner is north). Their order is important,
WIDX_PATH_CHECK_EDGE_SE, // as this is the same order paths use for their corners / edges.
@ -290,7 +291,7 @@ static Widget SurfaceWidgets[] = {
WIDGETS_END,
};
constexpr int32_t NumPathProperties = 5;
constexpr int32_t NumPathProperties = 6;
constexpr int32_t NumPathDetails = 3;
constexpr int32_t PathPropertiesHeight = 16 + NumPathProperties * 21;
constexpr int32_t PathDetailsHeight = 20 + NumPathDetails * 11;
@ -299,14 +300,15 @@ static Widget PathWidgets[] = {
MakeSpinnerWidgets(PropertyRowCol({ 12, 0 }, 0, 1), PropertyButtonSize, WindowWidgetType::Spinner, WindowColour::Secondary), // WIDX_PATH_SPINNER_HEIGHT{,_INCREASE,_DECREASE}
MakeWidget(PropertyRowCol({ 12, 0 }, 1, 0), PropertyFullWidth, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_TILE_INSPECTOR_PATH_BROKEN), // WIDX_PATH_CHECK_BROKEN
MakeWidget(PropertyRowCol({ 12, 0 }, 2, 0), PropertyFullWidth, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_TILE_INSPECTOR_PATH_SLOPED), // WIDX_PATH_CHECK_SLOPED
MakeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 3, 1), 3, 1), { 12, 12 }, WindowWidgetType::Checkbox, WindowColour::Secondary), // WIDX_PATH_CHECK_EDGE_NE
MakeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 3, 1), 4, 2), { 12, 12 }, WindowWidgetType::Checkbox, WindowColour::Secondary), // WIDX_PATH_CHECK_EDGE_E
MakeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 3, 1), 3, 3), { 12, 12 }, WindowWidgetType::Checkbox, WindowColour::Secondary), // WIDX_PATH_CHECK_EDGE_SE
MakeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 3, 1), 2, 4), { 12, 12 }, WindowWidgetType::Checkbox, WindowColour::Secondary), // WIDX_PATH_CHECK_EDGE_S
MakeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 3, 1), 1, 3), { 12, 12 }, WindowWidgetType::Checkbox, WindowColour::Secondary), // WIDX_PATH_CHECK_EDGE_SW
MakeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 3, 1), 0, 2), { 12, 12 }, WindowWidgetType::Checkbox, WindowColour::Secondary), // WIDX_PATH_CHECK_EDGE_W
MakeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 3, 1), 1, 1), { 12, 12 }, WindowWidgetType::Checkbox, WindowColour::Secondary), // WIDX_PATH_CHECK_EDGE_NW
MakeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 3, 1), 2, 0), { 12, 12 }, WindowWidgetType::Checkbox, WindowColour::Secondary), // WIDX_PATH_CHECK_EDGE_N
MakeWidget(PropertyRowCol({ 12, 0 }, 3, 0), PropertyFullWidth, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_TILE_INSPECTOR_PATH_JUNCTION_RAILINGS), // WIDX_PATH_CHECK_JUNCTION_RAILINGS
MakeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 4, 1), 3, 1), { 12, 12 }, WindowWidgetType::Checkbox, WindowColour::Secondary), // WIDX_PATH_CHECK_EDGE_NE
MakeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 4, 1), 4, 2), { 12, 12 }, WindowWidgetType::Checkbox, WindowColour::Secondary), // WIDX_PATH_CHECK_EDGE_E
MakeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 4, 1), 3, 3), { 12, 12 }, WindowWidgetType::Checkbox, WindowColour::Secondary), // WIDX_PATH_CHECK_EDGE_SE
MakeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 4, 1), 2, 4), { 12, 12 }, WindowWidgetType::Checkbox, WindowColour::Secondary), // WIDX_PATH_CHECK_EDGE_S
MakeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 4, 1), 1, 3), { 12, 12 }, WindowWidgetType::Checkbox, WindowColour::Secondary), // WIDX_PATH_CHECK_EDGE_SW
MakeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 4, 1), 0, 2), { 12, 12 }, WindowWidgetType::Checkbox, WindowColour::Secondary), // WIDX_PATH_CHECK_EDGE_W
MakeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 4, 1), 1, 1), { 12, 12 }, WindowWidgetType::Checkbox, WindowColour::Secondary), // WIDX_PATH_CHECK_EDGE_NW
MakeWidget(CheckboxGroupOffset(PropertyRowCol({ 12, 0 }, 4, 1), 2, 0), { 12, 12 }, WindowWidgetType::Checkbox, WindowColour::Secondary), // WIDX_PATH_CHECK_EDGE_N
WIDGETS_END,
};
@ -596,6 +598,10 @@ public:
case WIDX_PATH_CHECK_SLOPED:
PathSetSloped(windowTileInspectorSelectedIndex, !tileElement->AsPath()->IsSloped());
break;
case WIDX_PATH_CHECK_JUNCTION_RAILINGS:
PathSetJunctionRailings(
windowTileInspectorSelectedIndex, !tileElement->AsPath()->HasJunctionRailings());
break;
case WIDX_PATH_CHECK_BROKEN:
PathSetBroken(windowTileInspectorSelectedIndex, !tileElement->AsPath()->IsBroken());
@ -1868,6 +1874,13 @@ private:
GameActions::Execute(&modifyTile);
}
void PathSetJunctionRailings(int32_t elementIndex, bool hasJunctionRailings)
{
auto modifyTile = TileModifyAction(
_toolMap, TileModifyType::PathSetJunctionRailings, elementIndex, hasJunctionRailings);
GameActions::Execute(&modifyTile);
}
void PathSetBroken(int32_t elementIndex, bool broken)
{
auto modifyTile = TileModifyAction(_toolMap, TileModifyType::PathSetBroken, elementIndex, broken);
@ -2129,23 +2142,26 @@ private:
widgets[WIDX_PATH_CHECK_BROKEN].bottom = GBBB(propertiesAnchor, 1);
widgets[WIDX_PATH_CHECK_SLOPED].top = GBBT(propertiesAnchor, 2);
widgets[WIDX_PATH_CHECK_SLOPED].bottom = GBBB(propertiesAnchor, 2);
widgets[WIDX_PATH_CHECK_EDGE_N].top = GBBT(propertiesAnchor, 3) + 7 * 0;
widgets[WIDX_PATH_CHECK_JUNCTION_RAILINGS].top = GBBT(propertiesAnchor, 3);
widgets[WIDX_PATH_CHECK_JUNCTION_RAILINGS].bottom = GBBB(propertiesAnchor, 3);
widgets[WIDX_PATH_CHECK_EDGE_N].top = GBBT(propertiesAnchor, 4) + 7 * 0;
widgets[WIDX_PATH_CHECK_EDGE_N].bottom = widgets[WIDX_PATH_CHECK_EDGE_N].top + 13;
widgets[WIDX_PATH_CHECK_EDGE_NE].top = GBBT(propertiesAnchor, 3) + 7 * 1;
widgets[WIDX_PATH_CHECK_EDGE_NE].top = GBBT(propertiesAnchor, 4) + 7 * 1;
widgets[WIDX_PATH_CHECK_EDGE_NE].bottom = widgets[WIDX_PATH_CHECK_EDGE_NE].top + 13;
widgets[WIDX_PATH_CHECK_EDGE_E].top = GBBT(propertiesAnchor, 3) + 7 * 2;
widgets[WIDX_PATH_CHECK_EDGE_E].top = GBBT(propertiesAnchor, 4) + 7 * 2;
widgets[WIDX_PATH_CHECK_EDGE_E].bottom = widgets[WIDX_PATH_CHECK_EDGE_E].top + 13;
widgets[WIDX_PATH_CHECK_EDGE_SE].top = GBBT(propertiesAnchor, 3) + 7 * 3;
widgets[WIDX_PATH_CHECK_EDGE_SE].top = GBBT(propertiesAnchor, 4) + 7 * 3;
widgets[WIDX_PATH_CHECK_EDGE_SE].bottom = widgets[WIDX_PATH_CHECK_EDGE_SE].top + 13;
widgets[WIDX_PATH_CHECK_EDGE_S].top = GBBT(propertiesAnchor, 3) + 7 * 4;
widgets[WIDX_PATH_CHECK_EDGE_S].top = GBBT(propertiesAnchor, 4) + 7 * 4;
widgets[WIDX_PATH_CHECK_EDGE_S].bottom = widgets[WIDX_PATH_CHECK_EDGE_S].top + 13;
widgets[WIDX_PATH_CHECK_EDGE_SW].top = GBBT(propertiesAnchor, 3) + 7 * 3;
widgets[WIDX_PATH_CHECK_EDGE_SW].top = GBBT(propertiesAnchor, 4) + 7 * 3;
widgets[WIDX_PATH_CHECK_EDGE_SW].bottom = widgets[WIDX_PATH_CHECK_EDGE_SW].top + 13;
widgets[WIDX_PATH_CHECK_EDGE_W].top = GBBT(propertiesAnchor, 3) + 7 * 2;
widgets[WIDX_PATH_CHECK_EDGE_W].top = GBBT(propertiesAnchor, 4) + 7 * 2;
widgets[WIDX_PATH_CHECK_EDGE_W].bottom = widgets[WIDX_PATH_CHECK_EDGE_W].top + 13;
widgets[WIDX_PATH_CHECK_EDGE_NW].top = GBBT(propertiesAnchor, 3) + 7 * 1;
widgets[WIDX_PATH_CHECK_EDGE_NW].top = GBBT(propertiesAnchor, 4) + 7 * 1;
widgets[WIDX_PATH_CHECK_EDGE_NW].bottom = widgets[WIDX_PATH_CHECK_EDGE_NW].top + 13;
SetCheckboxValue(WIDX_PATH_CHECK_SLOPED, tileElement->AsPath()->IsSloped());
SetCheckboxValue(WIDX_PATH_CHECK_JUNCTION_RAILINGS, tileElement->AsPath()->HasJunctionRailings());
SetCheckboxValue(WIDX_PATH_CHECK_BROKEN, tileElement->AsPath()->IsBroken());
SetCheckboxValue(
WIDX_PATH_CHECK_EDGE_NE, tileElement->AsPath()->GetEdges() & (1 << ((0 - GetCurrentRotation()) & 3)));

View File

@ -128,6 +128,13 @@ GameActions::Result TileModifyAction::QueryExecute(bool isExecuting) const
res = TileInspector::PathSetSloped(_loc, elementIndex, sloped, isExecuting);
break;
}
case TileModifyType::PathSetJunctionRailings:
{
const auto elementIndex = _value1;
const bool hasJunctionRailing = _value2;
res = TileInspector::PathSetJunctionRailings(_loc, elementIndex, hasJunctionRailing, isExecuting);
break;
}
case TileModifyType::PathSetBroken:
{
const auto elementIndex = _value1;

View File

@ -26,6 +26,7 @@ enum class TileModifyType : uint8_t
PathSetSlope,
PathSetBroken,
PathToggleEdge,
PathSetJunctionRailings,
EntranceMakeUsable,
WallSetSlope,
WallSetAnimationFrame,

View File

@ -3945,6 +3945,8 @@ enum : uint16_t
STR_RCT1_INTEREST_TIP = 6546,
STR_ALL_SCENERY = 6547,
STR_TILE_INSPECTOR_PATH_JUNCTION_RAILINGS = 6548,
// Have to include resource strings (from scenarios and objects) for the time being now that language is partially working
/* MAX_STR_COUNT = 32768 */ // MAX_STR_COUNT - upper limit for number of strings, not the current count strings
};

View File

@ -43,7 +43,7 @@
// It is used for making sure only compatible builds get connected, even within
// single OpenRCT2 version.
#define NETWORK_STREAM_VERSION "14"
#define NETWORK_STREAM_VERSION "15"
#define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION

View File

@ -376,12 +376,15 @@ static void PathPaintFencesAndQueueBanners(
session, imageId.WithIndexOffset(26), { 0, 0, height }, { { 28, 28, height + 2 }, { 4, 4, 7 } });
break;
case 0b0111:
PaintAddImageAsParent(
session, imageId.WithIndexOffset(15), { 0, 4, height }, { { 0, 4, height + 2 }, { 32, 1, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(25), { 0, 0, height }, { { 0, 28, height + 2 }, { 4, 4, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(26), { 0, 0, height }, { { 28, 28, height + 2 }, { 4, 4, 7 } });
if (pathElement.HasJunctionRailings())
{
PaintAddImageAsParent(
session, imageId.WithIndexOffset(15), { 0, 4, height }, { { 0, 4, height + 2 }, { 32, 1, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(25), { 0, 0, height }, { { 0, 28, height + 2 }, { 4, 4, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(26), { 0, 0, height }, { { 28, 28, height + 2 }, { 4, 4, 7 } });
}
break;
case 0b1000:
PaintAddImageAsParent(
@ -404,12 +407,15 @@ static void PathPaintFencesAndQueueBanners(
session, imageId.WithIndexOffset(14), { 28, 0, height }, { { 28, 0, height + 2 }, { 1, 32, 7 } });
break;
case 0b1011:
PaintAddImageAsParent(
session, imageId.WithIndexOffset(14), { 28, 0, height }, { { 28, 0, height + 2 }, { 1, 32, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(24), { 0, 0, height }, { { 0, 0, height + 2 }, { 4, 4, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(25), { 0, 0, height }, { { 0, 28, height + 2 }, { 4, 4, 7 } });
if (pathElement.HasJunctionRailings())
{
PaintAddImageAsParent(
session, imageId.WithIndexOffset(14), { 28, 0, height }, { { 28, 0, height + 2 }, { 1, 32, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(24), { 0, 0, height }, { { 0, 0, height + 2 }, { 4, 4, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(25), { 0, 0, height }, { { 0, 28, height + 2 }, { 4, 4, 7 } });
}
break;
case 0b1100:
PaintAddImageAsParent(
@ -421,30 +427,39 @@ static void PathPaintFencesAndQueueBanners(
session, imageId.WithIndexOffset(27), { 0, 0, height }, { { 28, 0, height + 2 }, { 4, 4, 7 } });
break;
case 0b1101:
PaintAddImageAsParent(
session, imageId.WithIndexOffset(15), { 0, 28, height }, { { 0, 28, height + 2 }, { 32, 1, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(24), { 0, 0, height }, { { 0, 0, height + 2 }, { 4, 4, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(27), { 0, 0, height }, { { 28, 0, height + 2 }, { 4, 4, 7 } });
if (pathElement.HasJunctionRailings())
{
PaintAddImageAsParent(
session, imageId.WithIndexOffset(15), { 0, 28, height }, { { 0, 28, height + 2 }, { 32, 1, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(24), { 0, 0, height }, { { 0, 0, height + 2 }, { 4, 4, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(27), { 0, 0, height }, { { 28, 0, height + 2 }, { 4, 4, 7 } });
}
break;
case 0b1110:
PaintAddImageAsParent(
session, imageId.WithIndexOffset(14), { 4, 0, height }, { { 4, 0, height + 2 }, { 1, 32, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(26), { 0, 0, height }, { { 28, 28, height + 2 }, { 4, 4, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(27), { 0, 0, height }, { { 28, 0, height + 2 }, { 4, 4, 7 } });
if (pathElement.HasJunctionRailings())
{
PaintAddImageAsParent(
session, imageId.WithIndexOffset(14), { 4, 0, height }, { { 4, 0, height + 2 }, { 1, 32, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(26), { 0, 0, height }, { { 28, 28, height + 2 }, { 4, 4, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(27), { 0, 0, height }, { { 28, 0, height + 2 }, { 4, 4, 7 } });
}
break;
case 0b1111:
PaintAddImageAsParent(
session, imageId.WithIndexOffset(24), { 0, 0, height }, { { 0, 0, height + 2 }, { 4, 4, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(25), { 0, 0, height }, { { 0, 28, height + 2 }, { 4, 4, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(26), { 0, 0, height }, { { 28, 28, height + 2 }, { 4, 4, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(27), { 0, 0, height }, { { 28, 0, height + 2 }, { 4, 4, 7 } });
if (pathElement.HasJunctionRailings())
{
PaintAddImageAsParent(
session, imageId.WithIndexOffset(24), { 0, 0, height }, { { 0, 0, height + 2 }, { 4, 4, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(25), { 0, 0, height }, { { 0, 28, height + 2 }, { 4, 4, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(26), { 0, 0, height }, { { 28, 28, height + 2 }, { 4, 4, 7 } });
PaintAddImageAsParent(
session, imageId.WithIndexOffset(27), { 0, 0, height }, { { 28, 0, height + 2 }, { 4, 4, 7 } });
}
}
}

View File

@ -1514,6 +1514,18 @@ void PathElement::SetSloped(bool isSloped)
Flags2 |= FOOTPATH_ELEMENT_FLAGS2_IS_SLOPED;
}
bool PathElement::HasJunctionRailings() const
{
return Flags2 & FOOTPATH_ELEMENT_FLAGS2_HAS_JUNCTION_RAILINGS;
}
void PathElement::SetJunctionRailings(bool hasJunctionRailings)
{
Flags2 &= ~FOOTPATH_ELEMENT_FLAGS2_HAS_JUNCTION_RAILINGS;
if (hasJunctionRailings)
Flags2 |= FOOTPATH_ELEMENT_FLAGS2_HAS_JUNCTION_RAILINGS;
}
Direction PathElement::GetSlopeDirection() const
{
return SlopeDirection;

View File

@ -121,6 +121,7 @@ enum
FOOTPATH_ELEMENT_FLAGS2_BLOCKED_BY_VEHICLE = (1 << 3),
FOOTPATH_ELEMENT_FLAGS2_ADDITION_IS_BROKEN = (1 << 4),
FOOTPATH_ELEMENT_FLAGS2_LEGACY_PATH_ENTRY = (1 << 5),
FOOTPATH_ELEMENT_FLAGS2_HAS_JUNCTION_RAILINGS = (1 << 6),
};
enum

View File

@ -273,6 +273,9 @@ public:
bool IsSloped() const;
void SetSloped(bool isSloped);
bool HasJunctionRailings() const;
void SetJunctionRailings(bool hasJunctionRailings);
Direction GetSlopeDirection() const;
void SetSlopeDirection(Direction newSlope);

View File

@ -634,6 +634,28 @@ namespace OpenRCT2::TileInspector
return GameActions::Result();
}
GameActions::Result PathSetJunctionRailings(
const CoordsXY& loc, int32_t elementIndex, bool hasJunctionRailings, bool isExecuting)
{
TileElement* const pathElement = MapGetNthElementAt(loc, elementIndex);
if (pathElement == nullptr || pathElement->GetType() != TileElementType::Path)
return GameActions::Result(GameActions::Status::Unknown, STR_NONE, STR_NONE);
if (isExecuting)
{
pathElement->AsPath()->SetJunctionRailings(hasJunctionRailings);
MapInvalidateTileFull(loc);
if (auto* inspector = GetTileInspectorWithPos(loc); inspector != nullptr)
{
inspector->Invalidate();
}
}
return GameActions::Result();
}
GameActions::Result PathSetBroken(const CoordsXY& loc, int32_t elementIndex, bool broken, bool isExecuting)
{
TileElement* const pathElement = MapGetNthElementAt(loc, elementIndex);

View File

@ -34,6 +34,8 @@ namespace OpenRCT2::TileInspector
GameActions::Result SurfaceToggleCorner(const CoordsXY& loc, int32_t cornerIndex, bool isExecuting);
GameActions::Result SurfaceToggleDiagonal(const CoordsXY& loc, bool isExecuting);
GameActions::Result PathSetSloped(const CoordsXY& loc, int32_t elementIndex, bool sloped, bool isExecuting);
GameActions::Result PathSetJunctionRailings(
const CoordsXY& loc, int32_t elementIndex, bool hasJunctionRailings, bool isExecuting);
GameActions::Result PathSetBroken(const CoordsXY& loc, int32_t elementIndex, bool broken, bool isExecuting);
GameActions::Result PathToggleEdge(const CoordsXY& loc, int32_t elementIndex, int32_t cornerIndex, bool isExecuting);
GameActions::Result EntranceMakeUsable(const CoordsXY& loc, int32_t elementIndex, bool isExecuting);