diff --git a/src/openrct2-ui/interface/ViewportInteraction.cpp b/src/openrct2-ui/interface/ViewportInteraction.cpp index 5eeb86d108..42232072d5 100644 --- a/src/openrct2-ui/interface/ViewportInteraction.cpp +++ b/src/openrct2-ui/interface/ViewportInteraction.cpp @@ -734,22 +734,21 @@ PeepDistance GetClosestPeep(const ScreenCoordsXY& viewportCoords, const int32_t static Peep* ViewportInteractionGetClosestPeep(ScreenCoordsXY screenCoords, int32_t maxDistance) { - rct_window* w; - rct_viewport* viewport; - - w = window_find_from_point(screenCoords); + auto* w = window_find_from_point(screenCoords); if (w == nullptr) return nullptr; - viewport = w->viewport; + auto* viewport = w->viewport; if (viewport == nullptr || viewport->zoom >= ZoomLevel{ 2 }) return nullptr; auto viewportCoords = viewport->ScreenToViewportCoord(screenCoords); - auto goal = GetClosestPeep(viewportCoords, maxDistance, {}); - goal = GetClosestPeep(viewportCoords, maxDistance, goal); - + PeepDistance goal; + if (!(viewport->flags & VIEWPORT_FLAG_INVISIBLE_GUESTS)) + goal = GetClosestPeep(viewportCoords, maxDistance, goal); + if (!(viewport->flags & VIEWPORT_FLAG_INVISIBLE_STAFF)) + goal = GetClosestPeep(viewportCoords, maxDistance, goal); return goal.peep; } diff --git a/src/openrct2/drawing/LightFX.cpp b/src/openrct2/drawing/LightFX.cpp index 888b416e21..3b434fac5f 100644 --- a/src/openrct2/drawing/LightFX.cpp +++ b/src/openrct2/drawing/LightFX.cpp @@ -311,7 +311,8 @@ void lightfx_prepare_light_list() paint_session* session = PaintSessionAlloc(&dpi, w->viewport->flags); PaintSessionGenerate(*session); PaintSessionArrange(*session); - auto info = set_interaction_info_from_paint_session(session, ViewportInteractionItemAll); + auto info = set_interaction_info_from_paint_session( + session, w->viewport->flags, ViewportInteractionItemAll); PaintSessionFree(session); // log_warning("[%i, %i]", dpi->x, dpi->y); diff --git a/src/openrct2/entity/Peep.cpp b/src/openrct2/entity/Peep.cpp index f23bff8305..cfca4da97a 100644 --- a/src/openrct2/entity/Peep.cpp +++ b/src/openrct2/entity/Peep.cpp @@ -2733,15 +2733,6 @@ void Peep::Paint(paint_session& session, int32_t imageDirection) const return; } - if ((session.ViewFlags & VIEWPORT_FLAG_INVISIBLE_GUESTS) && Is()) - { - return; - } - if ((session.ViewFlags & VIEWPORT_FLAG_INVISIBLE_STAFF) && Is()) - { - return; - } - PeepActionSpriteType actionSpriteType = ActionSpriteType; uint8_t imageOffset = ActionSpriteImageOffset; diff --git a/src/openrct2/interface/Viewport.cpp b/src/openrct2/interface/Viewport.cpp index 1299878974..68286f8295 100644 --- a/src/openrct2/interface/Viewport.cpp +++ b/src/openrct2/interface/Viewport.cpp @@ -32,6 +32,7 @@ #include "../util/Math.hpp" #include "../world/Climate.h" #include "../world/Map.h" +#include "../world/SmallScenery.h" #include "Colour.h" #include "Window.h" #include "Window_internal.h" @@ -1352,6 +1353,98 @@ void viewport_set_visibility(uint8_t mode) } } +static bool IsTileElementTree(const TileElement* tileElement) +{ + auto sceneryItem = tileElement->AsSmallScenery(); + if (sceneryItem != nullptr) + { + auto sceneryEntry = sceneryItem->GetEntry(); + if (sceneryEntry != nullptr && sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_IS_TREE)) + { + return true; + } + } + return false; +} + +VisibilityKind GetPaintStructVisibility(const paint_struct* ps, uint32_t viewFlags) +{ + switch (ps->sprite_type) + { + case ViewportInteractionItem::Entity: + if (ps->entity != nullptr) + { + switch (ps->entity->Type) + { + case EntityType::Vehicle: + if (viewFlags & VIEWPORT_FLAG_SEETHROUGH_VEHICLES) + { + return (viewFlags & VIEWPORT_FLAG_INVISIBLE_VEHICLES) ? VisibilityKind::Hidden + : VisibilityKind::Partial; + } + break; + case EntityType::Guest: + if (viewFlags & VIEWPORT_FLAG_INVISIBLE_GUESTS) + { + return VisibilityKind::Hidden; + } + break; + case EntityType::Staff: + if (viewFlags & VIEWPORT_FLAG_INVISIBLE_STAFF) + { + return VisibilityKind::Hidden; + } + break; + } + } + break; + case ViewportInteractionItem::Ride: + if (viewFlags & VIEWPORT_FLAG_SEETHROUGH_RIDES) + { + return (viewFlags & VIEWPORT_FLAG_INVISIBLE_RIDES) ? VisibilityKind::Hidden : VisibilityKind::Partial; + } + break; + case ViewportInteractionItem::Footpath: + case ViewportInteractionItem::FootpathItem: + case ViewportInteractionItem::Banner: + if (viewFlags & VIEWPORT_FLAG_SEETHROUGH_PATHS) + { + return (viewFlags & VIEWPORT_FLAG_INVISIBLE_PATHS) ? VisibilityKind::Hidden : VisibilityKind::Partial; + } + break; + case ViewportInteractionItem::Scenery: + if (ps->tileElement != nullptr && IsTileElementTree(ps->tileElement)) + { + if (viewFlags & VIEWPORT_FLAG_SEETHROUGH_TREES) + { + return (viewFlags & VIEWPORT_FLAG_INVISIBLE_TREES) ? VisibilityKind::Hidden : VisibilityKind::Partial; + } + } + else if (viewFlags & VIEWPORT_FLAG_SEETHROUGH_SCENERY) + { + return (viewFlags & VIEWPORT_FLAG_INVISIBLE_SCENERY) ? VisibilityKind::Hidden : VisibilityKind::Partial; + } + break; + case ViewportInteractionItem::Wall: + if (viewFlags & VIEWPORT_FLAG_SEETHROUGH_SCENERY) + { + return (viewFlags & VIEWPORT_FLAG_INVISIBLE_SCENERY) ? VisibilityKind::Hidden : VisibilityKind::Partial; + } + if (viewFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE) + { + return VisibilityKind::Partial; + } + break; + case ViewportInteractionItem::LargeScenery: + if (viewFlags & VIEWPORT_FLAG_SEETHROUGH_SCENERY) + { + return (viewFlags & VIEWPORT_FLAG_INVISIBLE_SCENERY) ? VisibilityKind::Hidden : VisibilityKind::Partial; + } + break; + } + return VisibilityKind::Visible; +} + /** * Checks if a paint_struct sprite type is in the filter mask. */ @@ -1673,7 +1766,7 @@ static bool is_sprite_interacted_with(rct_drawpixelinfo* dpi, ImageId imageId, c * * rct2: 0x0068862C */ -InteractionInfo set_interaction_info_from_paint_session(paint_session* session, uint16_t filter) +InteractionInfo set_interaction_info_from_paint_session(paint_session* session, uint32_t viewFlags, uint16_t filter) { PROFILED_FUNCTION(); @@ -1690,7 +1783,7 @@ InteractionInfo set_interaction_info_from_paint_session(paint_session* session, ps = next_ps; if (is_sprite_interacted_with(dpi, ps->image_id, { ps->x, ps->y })) { - if (PSSpriteTypeIsInFilter(ps, filter)) + if (PSSpriteTypeIsInFilter(ps, filter) && GetPaintStructVisibility(ps, viewFlags) != VisibilityKind::Hidden) { info = { ps }; } @@ -1702,7 +1795,7 @@ InteractionInfo set_interaction_info_from_paint_session(paint_session* session, { if (is_sprite_interacted_with(dpi, attached_ps->image_id, { (attached_ps->x + ps->x), (attached_ps->y + ps->y) })) { - if (PSSpriteTypeIsInFilter(ps, filter)) + if (PSSpriteTypeIsInFilter(ps, filter) && GetPaintStructVisibility(ps, viewFlags) != VisibilityKind::Hidden) { info = { ps }; } @@ -1764,7 +1857,7 @@ InteractionInfo get_map_coordinates_from_pos_window(rct_window* window, const Sc paint_session* session = PaintSessionAlloc(&dpi, myviewport->flags); PaintSessionGenerate(*session); PaintSessionArrange(*session); - info = set_interaction_info_from_paint_session(session, flags & 0xFFFF); + info = set_interaction_info_from_paint_session(session, myviewport->flags, flags & 0xFFFF); PaintSessionFree(session); } return info; diff --git a/src/openrct2/interface/Viewport.h b/src/openrct2/interface/Viewport.h index 542b76d1f8..64b1477bf0 100644 --- a/src/openrct2/interface/Viewport.h +++ b/src/openrct2/interface/Viewport.h @@ -60,6 +60,13 @@ enum VIEWPORT_FLAG_SEETHROUGH_SUPPORTS = (1 << 29), }; +enum class VisibilityKind +{ + Visible, + Partial, + Hidden +}; + enum class ViewportInteractionItem : uint8_t { None, @@ -142,7 +149,7 @@ void viewport_set_visibility(uint8_t mode); InteractionInfo get_map_coordinates_from_pos(const ScreenCoordsXY& screenCoords, int32_t flags); InteractionInfo get_map_coordinates_from_pos_window(rct_window* window, const ScreenCoordsXY& screenCoords, int32_t flags); -InteractionInfo set_interaction_info_from_paint_session(paint_session* session, uint16_t filter); +InteractionInfo set_interaction_info_from_paint_session(paint_session* session, uint32_t viewFlags, uint16_t filter); InteractionInfo ViewportInteractionGetItemLeft(const ScreenCoordsXY& screenCoords); bool ViewportInteractionLeftOver(const ScreenCoordsXY& screenCoords); bool ViewportInteractionLeftClick(const ScreenCoordsXY& screenCoords); @@ -165,3 +172,5 @@ uint8_t get_current_rotation(); int32_t get_height_marker_offset(); void viewport_set_saved_view(); + +VisibilityKind GetPaintStructVisibility(const paint_struct* ps, uint32_t viewFlags); diff --git a/src/openrct2/paint/Paint.cpp b/src/openrct2/paint/Paint.cpp index a979a7208a..51dff01d52 100644 --- a/src/openrct2/paint/Paint.cpp +++ b/src/openrct2/paint/Paint.cpp @@ -57,9 +57,7 @@ bool gPaintBlockedTiles; static void PaintAttachedPS(rct_drawpixelinfo* dpi, paint_struct* ps, uint32_t viewFlags); static void PaintPSImageWithBoundingBoxes(rct_drawpixelinfo* dpi, paint_struct* ps, ImageId imageId, int32_t x, int32_t y); static void PaintPSImage(rct_drawpixelinfo* dpi, paint_struct* ps, ImageId imageId, int32_t x, int32_t y); -static ImageId PaintPSColourifyImage( - ImageId imageId, ViewportInteractionItem spriteType, uint32_t viewFlags, const TileElement* tileElement, - const EntityBase* entity); +static ImageId PaintPSColourifyImage(const paint_struct* ps, ImageId imageId, uint32_t viewFlags); static int32_t RemapPositionToQuadrant(const paint_struct& ps, uint8_t rotation) { @@ -507,7 +505,7 @@ static void PaintDrawStruct(paint_session& session, paint_struct* ps) } } - auto imageId = PaintPSColourifyImage(ps->image_id, ps->sprite_type, session.ViewFlags, ps->tileElement, ps->entity); + auto imageId = PaintPSColourifyImage(ps, ps->image_id, session.ViewFlags); if (gPaintBoundingBoxes && dpi->zoom_level == ZoomLevel{ 0 }) { PaintPSImageWithBoundingBoxes(dpi, ps, imageId, x, y); @@ -557,7 +555,7 @@ static void PaintAttachedPS(rct_drawpixelinfo* dpi, paint_struct* ps, uint32_t v { auto screenCoords = ScreenCoordsXY{ attached_ps->x + ps->x, attached_ps->y + ps->y }; - auto imageId = PaintPSColourifyImage(attached_ps->image_id, ps->sprite_type, viewFlags, ps->tileElement, ps->entity); + auto imageId = PaintPSColourifyImage(ps, attached_ps->image_id, viewFlags); if (attached_ps->flags & PAINT_STRUCT_FLAG_IS_MASKED) { gfx_draw_sprite_raw_masked(dpi, screenCoords, imageId, attached_ps->colour_image_id); @@ -665,83 +663,18 @@ static void PaintPSImage(rct_drawpixelinfo* dpi, paint_struct* ps, ImageId image gfx_draw_sprite(dpi, imageId, { x, y }); } -static bool IsTileElementTree(const TileElement* tileElement) +static ImageId PaintPSColourifyImage(const paint_struct* ps, ImageId imageId, uint32_t viewFlags) { - auto sceneryItem = tileElement->AsSmallScenery(); - if (sceneryItem != nullptr) + auto visibility = GetPaintStructVisibility(ps, viewFlags); + switch (visibility) { - auto sceneryEntry = sceneryItem->GetEntry(); - if (sceneryEntry != nullptr && sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_IS_TREE)) - { - return true; - } + case VisibilityKind::Partial: + return imageId.WithTransparancy(FilterPaletteID::PaletteDarken1); + case VisibilityKind::Hidden: + return ImageId(); + default: + return imageId; } - return false; -} - -static ImageId PaintPSColourifyImage( - ImageId imageId, ViewportInteractionItem spriteType, uint32_t viewFlags, const TileElement* tileElement, - const EntityBase* entity) -{ - auto seeThrough = imageId.WithTransparancy(FilterPaletteID::PaletteDarken1); - if (viewFlags & VIEWPORT_FLAG_SEETHROUGH_RIDES) - { - if (spriteType == ViewportInteractionItem::Ride) - { - return (viewFlags & VIEWPORT_FLAG_INVISIBLE_RIDES) ? ImageId() : seeThrough; - } - } - if (viewFlags & VIEWPORT_FLAG_SEETHROUGH_VEHICLES) - { - if (spriteType == ViewportInteractionItem::Entity && (entity != nullptr && entity->Type == EntityType::Vehicle)) - { - return (viewFlags & VIEWPORT_FLAG_INVISIBLE_VEHICLES) ? ImageId() : seeThrough; - } - } - if (viewFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE) - { - if (spriteType == ViewportInteractionItem::Wall) - { - return seeThrough; - } - } - if (viewFlags & VIEWPORT_FLAG_SEETHROUGH_PATHS) - { - switch (spriteType) - { - case ViewportInteractionItem::Footpath: - case ViewportInteractionItem::FootpathItem: - case ViewportInteractionItem::Banner: - return (viewFlags & VIEWPORT_FLAG_INVISIBLE_PATHS) ? ImageId() : seeThrough; - default: - break; - } - } - if (viewFlags & VIEWPORT_FLAG_SEETHROUGH_SCENERY) - { - switch (spriteType) - { - case ViewportInteractionItem::Scenery: - if (!IsTileElementTree(tileElement)) - { - return (viewFlags & VIEWPORT_FLAG_INVISIBLE_SCENERY) ? ImageId() : seeThrough; - } - break; - case ViewportInteractionItem::LargeScenery: - case ViewportInteractionItem::Wall: - return (viewFlags & VIEWPORT_FLAG_INVISIBLE_SCENERY) ? ImageId() : seeThrough; - default: - break; - } - } - if (viewFlags & VIEWPORT_FLAG_SEETHROUGH_TREES) - { - if (spriteType == ViewportInteractionItem::Scenery && IsTileElementTree(tileElement)) - { - return (viewFlags & VIEWPORT_FLAG_INVISIBLE_TREES) ? ImageId() : seeThrough; - } - } - return imageId; } paint_session* PaintSessionAlloc(rct_drawpixelinfo* dpi, uint32_t viewFlags) diff --git a/src/openrct2/ride/gentle/MiniGolf.cpp b/src/openrct2/ride/gentle/MiniGolf.cpp index 65671bf759..8a835beaf2 100644 --- a/src/openrct2/ride/gentle/MiniGolf.cpp +++ b/src/openrct2/ride/gentle/MiniGolf.cpp @@ -1213,11 +1213,6 @@ void vehicle_visual_mini_golf_player( return; } - if (session.ViewFlags & VIEWPORT_FLAG_INVISIBLE_GUESTS) - { - return; - } - auto ride = vehicle->GetRide(); if (ride == nullptr) return; @@ -1255,11 +1250,6 @@ void vehicle_visual_mini_golf_ball( return; } - if (session.ViewFlags & VIEWPORT_FLAG_INVISIBLE_GUESTS) - { - return; - } - auto ride = vehicle->GetRide(); if (ride == nullptr) return;