Skip to content

Commit

Permalink
Fix #19503. Hide 3+ queue junction railings behind a flag (#19644)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
duncanspumpkin committed Mar 23, 2023
1 parent 826fa47 commit e904ef4
Show file tree
Hide file tree
Showing 13 changed files with 133 additions and 51 deletions.
1 change: 1 addition & 0 deletions data/language/en-GB.txt
Expand Up @@ -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 #
Expand Down
2 changes: 1 addition & 1 deletion distribution/changelog.txt
Expand Up @@ -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.
Expand Down
50 changes: 33 additions & 17 deletions src/openrct2-ui/windows/TileInspector.cpp
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand All @@ -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,
};

Expand Down Expand Up @@ -596,6 +598,10 @@ class TileInspector final : public Window
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());
Expand Down Expand Up @@ -1868,6 +1874,13 @@ class TileInspector final : public Window
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);
Expand Down Expand Up @@ -2129,23 +2142,26 @@ class TileInspector final : public Window
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)));
Expand Down
7 changes: 7 additions & 0 deletions src/openrct2/actions/TileModifyAction.cpp
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/openrct2/actions/TileModifyAction.h
Expand Up @@ -26,6 +26,7 @@ enum class TileModifyType : uint8_t
PathSetSlope,
PathSetBroken,
PathToggleEdge,
PathSetJunctionRailings,
EntranceMakeUsable,
WallSetSlope,
WallSetAnimationFrame,
Expand Down
2 changes: 2 additions & 0 deletions src/openrct2/localisation/StringIds.h
Expand Up @@ -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
};
2 changes: 1 addition & 1 deletion src/openrct2/network/NetworkBase.cpp
Expand Up @@ -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

Expand Down
79 changes: 47 additions & 32 deletions src/openrct2/paint/tile_element/Paint.Path.cpp
Expand Up @@ -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(
Expand All @@ -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(
Expand All @@ -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 } });
}
}
}

Expand Down
12 changes: 12 additions & 0 deletions src/openrct2/world/Footpath.cpp
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/openrct2/world/Footpath.h
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions src/openrct2/world/TileElement.h
Expand Up @@ -273,6 +273,9 @@ struct PathElement : TileElementBase
bool IsSloped() const;
void SetSloped(bool isSloped);

bool HasJunctionRailings() const;
void SetJunctionRailings(bool hasJunctionRailings);

Direction GetSlopeDirection() const;
void SetSlopeDirection(Direction newSlope);

Expand Down

0 comments on commit e904ef4

Please sign in to comment.