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

Refactor tile property checks and code conventions

This commit is contained in:
Jeroen D Stout
2017-10-04 18:18:49 +02:00
committed by Aaron van Geffen
parent 8e8dc89068
commit c8e63de802

View File

@@ -29,118 +29,65 @@ static const rct_xy_element offsets[4] =
{ 0, -32 }
};
void virtual_floor_paint(paint_session * session)
static void virtual_floor_get_tile_properties(sint16 x, sint16 y, sint16 height, bool * outOccupied, uint8 * outOccupiedEdges, bool * outBelowGround, bool * outLit)
{
// We only show when the placement modifier keys are active
if (!input_test_place_object_modifier(PLACE_OBJECT_MODIFIER_COPY_Z | PLACE_OBJECT_MODIFIER_SHIFT_Z))
*outOccupied = false;
*outOccupiedEdges = 0;
*outBelowGround = false;
*outLit = false;
// See if we are a selected tile
if ((gMapSelectFlags & MAP_SELECT_FLAG_ENABLE))
{
return;
}
LocationXY16 * tile;
bool show = false;
bool weAreLit = false;
// Check if map selection (usually single tiles) are enabled
// and if the current tile is near or on them
if ((gMapSelectFlags & MAP_SELECT_FLAG_ENABLE) &&
session->MapPosition.x >= gMapSelectPositionA.x - gMapVirtualFloorBaseSize &&
session->MapPosition.y >= gMapSelectPositionA.y - gMapVirtualFloorBaseSize &&
session->MapPosition.x <= gMapSelectPositionB.x + gMapVirtualFloorBaseSize &&
session->MapPosition.y <= gMapSelectPositionB.y + gMapVirtualFloorBaseSize)
{
show = true;
if (session->MapPosition.x >= gMapSelectPositionA.x &&
session->MapPosition.y >= gMapSelectPositionA.y &&
session->MapPosition.x <= gMapSelectPositionB.x &&
session->MapPosition.y <= gMapSelectPositionB.y)
if (x >= gMapSelectPositionA.x &&
y >= gMapSelectPositionA.y &&
x <= gMapSelectPositionB.x &&
y <= gMapSelectPositionB.y)
{
weAreLit = true;
*outLit = true;
}
}
if (!show)
{
// Check if we are anywhere near the selection tiles (larger scenery / rides)
if (gMapSelectFlags & MAP_SELECT_FLAG_ENABLE_CONSTRUCT)
{
for (tile = gMapSelectionTiles; tile->x != -1; tile++)
{
if (session->MapPosition.x >= tile->x - gMapVirtualFloorBaseSize &&
session->MapPosition.y >= tile->y - gMapVirtualFloorBaseSize &&
session->MapPosition.x <= tile->x + gMapVirtualFloorBaseSize &&
session->MapPosition.y <= tile->y + gMapVirtualFloorBaseSize)
{
show = true;
break;
}
}
if (!show)
{
return;
}
}
else
{
return;
}
}
// See if we are on top of the selectiontiles
// See if we are on top of the selection tiles
if (gMapSelectFlags & MAP_SELECT_FLAG_ENABLE_CONSTRUCT)
{
for (tile = gMapSelectionTiles; tile->x != -1; tile++)
for (LocationXY16 * tile = gMapSelectionTiles; tile->x != -1; tile++)
{
if (session->MapPosition.x == tile->x &&
session->MapPosition.y == tile->y &&
session->MapPosition.x == tile->x &&
session->MapPosition.y == tile->y)
if (x == tile->x &&
y == tile->y)
{
weAreLit = true;
*outLit = true;
break;
}
}
}
// This is a virtual floor, so no interactions
session->InteractionType = VIEWPORT_INTERACTION_ITEM_NONE;
sint16 virtualFloorClipHeight = gMapVirtualFloorHeight / 8;
uint8 occupiedEdges = 0;
uint8 litEdges = 0;
// Check for occupation and walls
bool weAreOccupied = false;
bool weAreBelowGround = false;
// Iterate through the map elements of the current tile to find:
// * Surfaces, which may put us underground
// * Walls / banners, which are displayed as occupied edges
// * Ghost objects, which are displayed as lit squares
rct_tile_element * tileElement = map_get_first_element_at(session->MapPosition.x >> 5, session->MapPosition.y >> 5);
// Iterate through the map elements of the current tile to find:
// * Surfaces, which may put us underground
// * Walls / banners, which are displayed as occupied edges
// * Ghost objects, which are displayed as lit squares
rct_tile_element * tileElement = map_get_first_element_at(x >> 5, y >> 5);
do
{
sint32 elementType = tile_element_get_type(tileElement);
if (elementType == TILE_ELEMENT_TYPE_SURFACE)
{
if (virtualFloorClipHeight < tileElement->clearance_height)
if (height < tileElement->clearance_height)
{
weAreBelowGround = true;
*outBelowGround = true;
}
else if (virtualFloorClipHeight < tileElement->base_height + 2 &&
else if (height < tileElement->base_height + 2 &&
tileElement->properties.surface.slope != 0)
{
weAreBelowGround = true;
weAreOccupied = true;
*outBelowGround = true;
*outOccupied = true;
}
continue;
}
if (virtualFloorClipHeight >= tileElement->clearance_height ||
virtualFloorClipHeight < tileElement->base_height)
if (height >= tileElement->clearance_height ||
height < tileElement->base_height)
{
continue;
}
@@ -149,105 +96,97 @@ void virtual_floor_paint(paint_session * session)
elementType == TILE_ELEMENT_TYPE_BANNER)
{
sint32 direction = tile_element_get_direction(tileElement);
occupiedEdges |= 1 << ((direction + get_current_rotation()) % 4);
*outOccupiedEdges |= 1 << ((direction + get_current_rotation()) % 4);
continue;
}
if (tileElement->flags & TILE_ELEMENT_FLAG_GHOST)
{
weAreLit = true;
*outLit = true;
continue;
}
weAreOccupied = true;
*outOccupied = true;
}
while (!tile_element_is_last_for_tile(tileElement++));
}
// Try the four tiles next to us for the same parameters as above,
// if our parameters differ we set an edge towards that tile
void virtual_floor_paint(paint_session * session)
{
// We only show when the placement modifier keys are active
if (!input_test_place_object_modifier(PLACE_OBJECT_MODIFIER_COPY_Z | PLACE_OBJECT_MODIFIER_SHIFT_Z))
{
return;
}
uint8 direction = get_current_rotation();
bool show = false;
// Check if map selection (usually single tiles) are enabled
// and if the current tile is near or on them
if ((gMapSelectFlags & MAP_SELECT_FLAG_ENABLE) &&
session->MapPosition.x >= gMapSelectPositionA.x - gMapVirtualFloorBaseSize &&
session->MapPosition.y >= gMapSelectPositionA.y - gMapVirtualFloorBaseSize &&
session->MapPosition.x <= gMapSelectPositionB.x + gMapVirtualFloorBaseSize &&
session->MapPosition.y <= gMapSelectPositionB.y + gMapVirtualFloorBaseSize)
{
show = true;
}
else if (gMapSelectFlags & MAP_SELECT_FLAG_ENABLE_CONSTRUCT)
{
// Check if we are anywhere near the selection tiles (larger scenery / rides)
for (LocationXY16 * tile = gMapSelectionTiles; tile->x != -1; tile++)
{
if (session->MapPosition.x >= tile->x - gMapVirtualFloorBaseSize &&
session->MapPosition.y >= tile->y - gMapVirtualFloorBaseSize &&
session->MapPosition.x <= tile->x + gMapVirtualFloorBaseSize &&
session->MapPosition.y <= tile->y + gMapVirtualFloorBaseSize)
{
show = true;
break;
}
}
}
if (!show)
{
return;
}
// This is a virtual floor, so no interactions
session->InteractionType = VIEWPORT_INTERACTION_ITEM_NONE;
sint16 virtualFloorClipHeight = gMapVirtualFloorHeight / 8;
// Check for occupation and walls
bool weAreOccupied;
uint8 occupiedEdges;
bool weAreBelowGround;
bool weAreLit;
uint8 litEdges = 0;
virtual_floor_get_tile_properties(session->MapPosition.x, session->MapPosition.y, virtualFloorClipHeight, &weAreOccupied, &occupiedEdges, &weAreBelowGround, &weAreLit);
// Try the four tiles next to us for the same parameters as above,
// if our parameters differ we set an edge towards that tile
for (uint8 i = 0; i < 4; i++)
{
uint8 effectiveRotation = (4 + i - get_current_rotation()) % 4;
uint8 effectiveRotation = (4 + i - direction) % 4;
sint16 theirLocationX = session->MapPosition.x + offsets[effectiveRotation].x;
sint16 theirLocationY = session->MapPosition.y + offsets[effectiveRotation].y;
bool theyAreOccupied = false;
bool theyAreBelowGround = false;
bool theyAreLit = false;
bool theyAreOccupied;
uint8 theirOccupiedEdges;
bool theyAreBelowGround;
bool theyAreLit;
if ((gMapSelectFlags & MAP_SELECT_FLAG_ENABLE) &&
theirLocationX >= gMapSelectPositionA.x &&
theirLocationY >= gMapSelectPositionA.y &&
theirLocationX <= gMapSelectPositionB.x &&
theirLocationY <= gMapSelectPositionB.y)
virtual_floor_get_tile_properties(theirLocationX, theirLocationY, virtualFloorClipHeight, &theyAreOccupied, &theirOccupiedEdges, &theyAreBelowGround, &theyAreLit);
if (theirOccupiedEdges & (1 << (effectiveRotation + 2) % 4))
{
theyAreLit = true;
occupiedEdges |= 1 << i;
}
if (!theyAreLit)
{
if (gMapSelectFlags & MAP_SELECT_FLAG_ENABLE_CONSTRUCT)
{
for (tile = gMapSelectionTiles; tile->x != -1; tile++)
{
if (theirLocationX == tile->x &&
theirLocationY == tile->y)
{
theyAreLit = true;
}
}
}
}
tileElement = map_get_first_element_at(theirLocationX >> 5, theirLocationY >> 5);
do
{
sint32 elementType = tile_element_get_type(tileElement);
if (elementType == TILE_ELEMENT_TYPE_SURFACE)
{
if (virtualFloorClipHeight < tileElement->clearance_height)
{
theyAreBelowGround = true;
}
else if (virtualFloorClipHeight < tileElement->base_height + 2 &&
tileElement->properties.surface.slope != 0)
{
theyAreBelowGround = true;
theyAreOccupied = true;
}
continue;
}
if (virtualFloorClipHeight >= tileElement->clearance_height ||
virtualFloorClipHeight < tileElement->base_height)
{
continue;
}
if (elementType == TILE_ELEMENT_TYPE_WALL ||
elementType == TILE_ELEMENT_TYPE_BANNER)
{
sint32 direction = tile_element_get_direction(tileElement);
if (direction == (effectiveRotation + 2) % 4)
{
occupiedEdges |= 1 << i;
break;
}
continue;
}
if (tileElement->flags & TILE_ELEMENT_FLAG_GHOST)
{
theyAreLit = true;
}
else
{
theyAreOccupied = true;
}
}
while (!tile_element_is_last_for_tile(tileElement++));
if (weAreLit != theyAreLit)
{
litEdges |= 1 << i;
@@ -263,21 +202,11 @@ void virtual_floor_paint(paint_session * session)
uint32 remap_edge = COLOUR_WHITE << 19 | IMAGE_TYPE_REMAP;
uint32 remap_lit = COLOUR_DARK_BROWN << 19 | IMAGE_TYPE_REMAP;
// Edges which are internal to objects (i.e., the tile on both sides
// is occupied/lit) are not rendered to provide visual clarity.
// Edges which are internal to objects (i.e., the tile on both sides
// is occupied/lit) are not rendered to provide visual clarity.
uint8 dullEdges = 0xF & ~occupiedEdges & ~litEdges;
uint8 paintEdges = (weAreOccupied || weAreLit)? ~dullEdges : 0xF;
if (paintEdges & 0x8)
{
sub_98197C(session, SPR_G2_SELECTION_EDGE_NW | (!(occupiedEdges & 0x8)? ((litEdges & 0x8)? remap_lit : remap_base) : remap_edge),
0, 0, 0, 0, 1, gMapVirtualFloorHeight, 5, 5, gMapVirtualFloorHeight + ((dullEdges & 0x8)? -2 : 0), get_current_rotation());
}
if (paintEdges & 0x4)
{
sub_98197C(session, SPR_G2_SELECTION_EDGE_SW | (!(occupiedEdges & 0x4)? ((litEdges & 0x4)? remap_lit : remap_base) : remap_edge),
0, 0, 1, 1, 1, gMapVirtualFloorHeight, 27, 16, gMapVirtualFloorHeight + ((dullEdges & 0x4)? -2 : 0), get_current_rotation());
}
if (paintEdges & 0x1)
{
sub_98197C(session, SPR_G2_SELECTION_EDGE_NE | (!(occupiedEdges & 0x1)? ((litEdges & 0x1)? remap_lit : remap_base) : remap_edge),
@@ -288,6 +217,16 @@ void virtual_floor_paint(paint_session * session)
sub_98197C(session, SPR_G2_SELECTION_EDGE_SE | (!(occupiedEdges & 0x2)? ((litEdges & 0x2)? remap_lit : remap_base) : remap_edge),
0, 0, 1, 1, 1, gMapVirtualFloorHeight, 16, 27, gMapVirtualFloorHeight + ((dullEdges & 0x2)? -2 : 0), get_current_rotation());
}
if (paintEdges & 0x4)
{
sub_98197C(session, SPR_G2_SELECTION_EDGE_SW | (!(occupiedEdges & 0x4)? ((litEdges & 0x4)? remap_lit : remap_base) : remap_edge),
0, 0, 1, 1, 1, gMapVirtualFloorHeight, 27, 16, gMapVirtualFloorHeight + ((dullEdges & 0x4)? -2 : 0), get_current_rotation());
}
if (paintEdges & 0x8)
{
sub_98197C(session, SPR_G2_SELECTION_EDGE_NW | (!(occupiedEdges & 0x8)? ((litEdges & 0x8)? remap_lit : remap_base) : remap_edge),
0, 0, 0, 0, 1, gMapVirtualFloorHeight, 5, 5, gMapVirtualFloorHeight + ((dullEdges & 0x8)? -2 : 0), get_current_rotation());
}
if (!weAreOccupied && !weAreLit)
{