1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-21 05:53:02 +01:00

Refactor visibility control

This commit is contained in:
Ted John
2022-03-04 02:46:37 +00:00
parent 9794be6a09
commit c68359662d
7 changed files with 128 additions and 112 deletions

View File

@@ -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<Guest>(viewportCoords, maxDistance, {});
goal = GetClosestPeep<Staff>(viewportCoords, maxDistance, goal);
PeepDistance goal;
if (!(viewport->flags & VIEWPORT_FLAG_INVISIBLE_GUESTS))
goal = GetClosestPeep<Guest>(viewportCoords, maxDistance, goal);
if (!(viewport->flags & VIEWPORT_FLAG_INVISIBLE_STAFF))
goal = GetClosestPeep<Staff>(viewportCoords, maxDistance, goal);
return goal.peep;
}

View File

@@ -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);

View File

@@ -2733,15 +2733,6 @@ void Peep::Paint(paint_session& session, int32_t imageDirection) const
return;
}
if ((session.ViewFlags & VIEWPORT_FLAG_INVISIBLE_GUESTS) && Is<Guest>())
{
return;
}
if ((session.ViewFlags & VIEWPORT_FLAG_INVISIBLE_STAFF) && Is<Staff>())
{
return;
}
PeepActionSpriteType actionSpriteType = ActionSpriteType;
uint8_t imageOffset = ActionSpriteImageOffset;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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)

View File

@@ -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;