1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-10 09:32:29 +01:00

Add see-through option to the "Cut-away View" (#23759)

This commit is contained in:
David Sungaila
2025-02-22 11:09:32 +01:00
committed by GitHub
parent be11e609a2
commit 081a2f44d9
9 changed files with 85 additions and 19 deletions

View File

@@ -248,6 +248,7 @@ Appreciation for contributors who have provided substantial work, but are no lon
* Tom Matalenas (tmatale)
* Brendan Heinonen (staticinvocation)
* (QuestionableDeer)
* David Sungaila (sungaila)
## Toolchain
* (Balletie) - macOS

View File

@@ -3795,3 +3795,5 @@ STR_6729 :Cable lift hill must start immediately after station or block brake
STR_6730 :Export emscripten data
STR_6731 :Import emscripten data
STR_6732 :Show a button in the toolbar to rotate the view anti-clockwise
STR_6733 :See-Through
STR_6734 :Map elements that are at or above the cutting height are rendered translucent.

View File

@@ -1,6 +1,7 @@
0.4.20 (in development)
------------------------------------------------------------------------
- Feature: [#22905] Add diagonal downward-inclined brakes to hybrid coaster and single rail coaster.
- Feature: [#23759] Add see-through option to the “Cut-away View“.
- Improved: [#23677] Building new ride track now inherits the colour scheme from the previous piece.
- Improved: [#23720] Text fields now allow cutting to clipboard (Ctrl+X) in addition to copy and paste.
- Fix: [#1972, #11679] Vehicles passing by toilets can cause them to glitch (original bug).

View File

@@ -2263,6 +2263,8 @@ namespace OpenRCT2
STR_VIEW_CLIPPING_HORIZONTAL_CLIPPING = 6240,
STR_VIEW_CLIPPING_SELECT_AREA = 6241,
STR_VIEW_CLIPPING_VERTICAL_CLIPPING = 6239,
STR_VIEW_CLIPPING_VERTICAL_CLIPPING_SEE_THROUGH = 6733,
STR_VIEW_CLIPPING_VERTICAL_CLIPPING_SEE_THROUGH_TIP = 6734,
// Window: Viewport
STR_LOCATE_SUBJECT_TIP = 1027,

View File

@@ -34,6 +34,7 @@ namespace OpenRCT2::Ui::Windows
WIDX_CLIP_HEIGHT_INCREASE,
WIDX_CLIP_HEIGHT_DECREASE,
WIDX_CLIP_HEIGHT_SLIDER,
WIDX_CLIP_SEE_THROUGH_CHECKBOX_ENABLE,
WIDX_GROUPBOX_HORIZONTAL,
WIDX_CLIP_SELECTOR,
WIDX_CLIP_CLEAR,
@@ -49,18 +50,19 @@ namespace OpenRCT2::Ui::Windows
static constexpr StringId WINDOW_TITLE = STR_VIEW_CLIPPING_TITLE;
static constexpr int32_t WW = 180;
static constexpr int32_t WH = 155;
static constexpr int32_t WH = 172;
// clang-format off
static constexpr Widget _viewClippingWidgets[] = {
WINDOW_SHIM(WINDOW_TITLE, WW, WH),
MakeWidget ({ 11, 19}, { 159, 11}, WindowWidgetType::Checkbox, WindowColour::Primary, STR_VIEW_CLIPPING_HEIGHT_ENABLE, STR_VIEW_CLIPPING_HEIGHT_ENABLE_TIP ), // clip enable/disable check box
MakeWidget ({ 5, 36}, {WW - 10, 48}, WindowWidgetType::Groupbox, WindowColour::Primary, STR_VIEW_CLIPPING_VERTICAL_CLIPPING ),
MakeSpinnerWidgets({ 90, 51}, { 79, 12}, WindowWidgetType::Spinner, WindowColour::Primary, kStringIdNone, STR_VIEW_CLIPPING_HEIGHT_VALUE_TOGGLE), // clip height (3 widgets)
MakeWidget ({ 11, 66}, { 158, 13}, WindowWidgetType::Scroll, WindowColour::Primary, SCROLL_HORIZONTAL, STR_VIEW_CLIPPING_HEIGHT_SCROLL_TIP ), // clip height scrollbar
MakeWidget ({ 5, 90}, {WW - 10, 60}, WindowWidgetType::Groupbox, WindowColour::Primary, STR_VIEW_CLIPPING_HORIZONTAL_CLIPPING ),
MakeWidget ({ 11, 105}, { 158, 17}, WindowWidgetType::Button, WindowColour::Primary, STR_VIEW_CLIPPING_SELECT_AREA ), // selector
MakeWidget ({ 11, 126}, { 158, 18}, WindowWidgetType::Button, WindowColour::Primary, STR_VIEW_CLIPPING_CLEAR_SELECTION ), // clear
MakeWidget ({ 11, 19}, { 159, 11}, WindowWidgetType::Checkbox, WindowColour::Primary, STR_VIEW_CLIPPING_HEIGHT_ENABLE, STR_VIEW_CLIPPING_HEIGHT_ENABLE_TIP ), // clip enable/disable check box
MakeWidget ({ 5, 36}, {WW - 10, 65}, WindowWidgetType::Groupbox, WindowColour::Primary, STR_VIEW_CLIPPING_VERTICAL_CLIPPING ),
MakeSpinnerWidgets({ 90, 51}, { 79, 12}, WindowWidgetType::Spinner, WindowColour::Primary, kStringIdNone, STR_VIEW_CLIPPING_HEIGHT_VALUE_TOGGLE ), // clip height (3 widgets)
MakeWidget ({ 11, 66}, { 158, 13}, WindowWidgetType::Scroll, WindowColour::Primary, SCROLL_HORIZONTAL, STR_VIEW_CLIPPING_HEIGHT_SCROLL_TIP ), // clip height scrollbar
MakeWidget ({ 11, 83}, { 159, 11}, WindowWidgetType::Checkbox, WindowColour::Primary, STR_VIEW_CLIPPING_VERTICAL_CLIPPING_SEE_THROUGH, STR_VIEW_CLIPPING_VERTICAL_CLIPPING_SEE_THROUGH_TIP), // clip height enable/disable see-through check box
MakeWidget ({ 5, 107}, {WW - 10, 60}, WindowWidgetType::Groupbox, WindowColour::Primary, STR_VIEW_CLIPPING_HORIZONTAL_CLIPPING ),
MakeWidget ({ 11, 122}, { 158, 17}, WindowWidgetType::Button, WindowColour::Primary, STR_VIEW_CLIPPING_SELECT_AREA ), // selector
MakeWidget ({ 11, 143}, { 158, 18}, WindowWidgetType::Button, WindowColour::Primary, STR_VIEW_CLIPPING_CLEAR_SELECTION ), // clear
};
// clang-format on
@@ -137,6 +139,17 @@ namespace OpenRCT2::Ui::Windows
gClipSelectionB = { kMaximumMapSizeBig - 1, kMaximumMapSizeBig - 1 };
GfxInvalidateScreen();
break;
case WIDX_CLIP_SEE_THROUGH_CHECKBOX_ENABLE:
{
// Toggle height clipping see-through.
if (auto mainWindow = WindowGetMain(); mainWindow != nullptr)
{
mainWindow->viewport->flags ^= VIEWPORT_FLAG_CLIP_VIEW_SEE_THROUGH;
mainWindow->Invalidate();
}
Invalidate();
break;
}
}
}
@@ -262,6 +275,9 @@ namespace OpenRCT2::Ui::Windows
if (mainWindow != nullptr)
{
WidgetSetCheckboxValue(*this, WIDX_CLIP_CHECKBOX_ENABLE, mainWindow->viewport->flags & VIEWPORT_FLAG_CLIP_VIEW);
WidgetSetCheckboxValue(
*this, WIDX_CLIP_SEE_THROUGH_CHECKBOX_ENABLE,
mainWindow->viewport->flags & VIEWPORT_FLAG_CLIP_VIEW_SEE_THROUGH);
}
if (IsActive())

View File

@@ -1403,6 +1403,18 @@ namespace OpenRCT2
VisibilityKind GetPaintStructVisibility(const PaintStruct* ps, uint32_t viewFlags)
{
// the cut-away view is active and see-through is activated
auto cutAwayViewWithTransparency = (viewFlags & VIEWPORT_FLAG_CLIP_VIEW)
&& (viewFlags & VIEWPORT_FLAG_CLIP_VIEW_SEE_THROUGH);
// the element is above the cut-off height
auto clipped = cutAwayViewWithTransparency && ps->Element == nullptr && ps->Entity != nullptr
&& ps->Entity->GetLocation().z > (gClipHeight * kCoordsZStep);
// the entity is above the cut-off height
clipped |= cutAwayViewWithTransparency && ps->Element != nullptr
&& (ps->Element->GetBaseZ() > gClipHeight * kCoordsZStep);
switch (ps->InteractionItem)
{
case ViewportInteractionItem::Entity:
@@ -1412,14 +1424,14 @@ namespace OpenRCT2
{
case EntityType::Vehicle:
{
if (viewFlags & VIEWPORT_FLAG_HIDE_VEHICLES)
if (viewFlags & VIEWPORT_FLAG_HIDE_VEHICLES || clipped)
{
return (viewFlags & VIEWPORT_FLAG_INVISIBLE_VEHICLES) ? VisibilityKind::Hidden
: VisibilityKind::Partial;
}
// Rides without track can technically have a 'vehicle':
// these should be hidden if 'hide rides' is enabled
if (viewFlags & VIEWPORT_FLAG_HIDE_RIDES)
if (viewFlags & VIEWPORT_FLAG_HIDE_RIDES || clipped)
{
auto vehicle = ps->Entity->As<Vehicle>();
if (vehicle == nullptr)
@@ -1439,20 +1451,32 @@ namespace OpenRCT2
{
return VisibilityKind::Hidden;
}
else if (clipped)
{
return VisibilityKind::Partial;
}
break;
case EntityType::Staff:
if (viewFlags & VIEWPORT_FLAG_HIDE_STAFF)
{
return VisibilityKind::Hidden;
}
else if (clipped)
{
return VisibilityKind::Partial;
}
break;
default:
if (clipped)
{
return VisibilityKind::Partial;
}
break;
}
}
break;
case ViewportInteractionItem::Ride:
if (viewFlags & VIEWPORT_FLAG_HIDE_RIDES)
if (viewFlags & VIEWPORT_FLAG_HIDE_RIDES || clipped)
{
return (viewFlags & VIEWPORT_FLAG_INVISIBLE_RIDES) ? VisibilityKind::Hidden : VisibilityKind::Partial;
}
@@ -1460,7 +1484,7 @@ namespace OpenRCT2
case ViewportInteractionItem::Footpath:
case ViewportInteractionItem::PathAddition:
case ViewportInteractionItem::Banner:
if (viewFlags & VIEWPORT_FLAG_HIDE_PATHS)
if (viewFlags & VIEWPORT_FLAG_HIDE_PATHS || clipped)
{
return (viewFlags & VIEWPORT_FLAG_INVISIBLE_PATHS) ? VisibilityKind::Hidden : VisibilityKind::Partial;
}
@@ -1472,7 +1496,7 @@ namespace OpenRCT2
{
if (IsTileElementVegetation(ps->Element))
{
if (viewFlags & VIEWPORT_FLAG_HIDE_VEGETATION)
if (viewFlags & VIEWPORT_FLAG_HIDE_VEGETATION || clipped)
{
return (viewFlags & VIEWPORT_FLAG_INVISIBLE_VEGETATION) ? VisibilityKind::Hidden
: VisibilityKind::Partial;
@@ -1480,19 +1504,24 @@ namespace OpenRCT2
}
else
{
if (viewFlags & VIEWPORT_FLAG_HIDE_SCENERY)
if (viewFlags & VIEWPORT_FLAG_HIDE_SCENERY || clipped)
{
return (viewFlags & VIEWPORT_FLAG_INVISIBLE_SCENERY) ? VisibilityKind::Hidden
: VisibilityKind::Partial;
}
}
}
if (ps->InteractionItem == ViewportInteractionItem::Wall && (viewFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE))
if (ps->InteractionItem == ViewportInteractionItem::Wall
&& (viewFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE || clipped))
{
return VisibilityKind::Partial;
}
break;
default:
if (clipped)
{
return VisibilityKind::Partial;
}
break;
}
return VisibilityKind::Visible;

View File

@@ -87,7 +87,8 @@ namespace OpenRCT2
VIEWPORT_FLAG_LAND_OWNERSHIP = (1u << 8),
VIEWPORT_FLAG_CONSTRUCTION_RIGHTS = (1u << 9),
VIEWPORT_FLAG_HIDE_ENTITIES = (1u << 14),
VIEWPORT_FLAG_CLIP_VIEW = (1u << 17),
VIEWPORT_FLAG_CLIP_VIEW = (1u << 15),
VIEWPORT_FLAG_CLIP_VIEW_SEE_THROUGH = (1u << 17),
VIEWPORT_FLAG_HIGHLIGHT_PATH_ISSUES = (1u << 18),
VIEWPORT_FLAG_TRANSPARENT_BACKGROUND = (1u << 19),

View File

@@ -83,11 +83,16 @@ void EntityPaintSetup(PaintSession& session, const CoordsXY& pos)
// Here converting from land/path/etc height scale to pixel height scale.
// Note: peeps/scenery on slopes will be above the base
// height of the slope element, and consequently clipped.
if ((session.ViewFlags & VIEWPORT_FLAG_CLIP_VIEW))
if (session.ViewFlags & VIEWPORT_FLAG_CLIP_VIEW)
{
if (entityPos.z > (gClipHeight * kCoordsZStep))
{
continue;
// see-through off: don't paint this entity at all
// see-through on: paint this entity as partial or hidden later on
if ((session.ViewFlags & VIEWPORT_FLAG_CLIP_VIEW_SEE_THROUGH) == 0)
{
continue;
}
}
if (entityPos.x < gClipSelectionA.x || entityPos.x > (gClipSelectionB.x + kCoordsXYStep - 1))
{

View File

@@ -221,7 +221,16 @@ static void PaintTileElementBase(PaintSession& session, const CoordsXY& origCoor
// Only paint tile_elements below the clip height.
if ((session.ViewFlags & VIEWPORT_FLAG_CLIP_VIEW) && (tile_element->GetBaseZ() > gClipHeight * kCoordsZStep))
continue;
{
// see-through off: don't paint this tile_element at all
// see-through on: paint this tile_element as partial or hidden later on
// note: surface elements are not painted even with see-through turned on
if ((session.ViewFlags & VIEWPORT_FLAG_CLIP_VIEW_SEE_THROUGH) == 0
|| tile_element->GetType() == TileElementType::Surface)
{
continue;
}
}
Direction direction = tile_element->GetDirectionWithOffset(rotation);
int32_t baseZ = tile_element->GetBaseZ();