Move all Virtual Floor code from Map to its own file.

This commit is contained in:
Aaron van Geffen 2018-03-04 17:44:42 +01:00
parent fdf7adecd9
commit ba1d269227
10 changed files with 208 additions and 194 deletions

View File

@ -23,6 +23,7 @@
#include <openrct2/Input.h> #include <openrct2/Input.h>
#include <openrct2/interface/Chat.h> #include <openrct2/interface/Chat.h>
#include <openrct2/interface/Console.h> #include <openrct2/interface/Console.h>
#include <openrct2/paint/VirtualFloor.h>
#include <openrct2-ui/windows/Window.h> #include <openrct2-ui/windows/Window.h>
#include "KeyboardShortcuts.h" #include "KeyboardShortcuts.h"
#include "Input.h" #include "Input.h"
@ -172,9 +173,9 @@ void input_handle_keyboard(bool isTitle)
if (gConfigGeneral.use_virtual_floor) if (gConfigGeneral.use_virtual_floor)
{ {
if (gInputPlaceObjectModifier & (PLACE_OBJECT_MODIFIER_COPY_Z | PLACE_OBJECT_MODIFIER_SHIFT_Z)) if (gInputPlaceObjectModifier & (PLACE_OBJECT_MODIFIER_COPY_Z | PLACE_OBJECT_MODIFIER_SHIFT_Z))
map_enable_virtual_floor(); virtual_floor_enable();
else else
map_remove_virtual_floor(); virtual_floor_disable();
} }
// Handle key input // Handle key input

View File

@ -34,6 +34,7 @@
#include <openrct2/network/twitch.h> #include <openrct2/network/twitch.h>
#include <openrct2/OpenRCT2.h> #include <openrct2/OpenRCT2.h>
#include <openrct2/ParkImporter.h> #include <openrct2/ParkImporter.h>
#include <openrct2/paint/VirtualFloor.h>
#include <openrct2/peep/Staff.h> #include <openrct2/peep/Staff.h>
#include <openrct2/util/Util.h> #include <openrct2/util/Util.h>
#include <openrct2-ui/interface/Dropdown.h> #include <openrct2-ui/interface/Dropdown.h>
@ -1288,7 +1289,7 @@ static void sub_6E1F34(sint16 x, sint16 y, uint16 selected_scenery, sint16* grid
if (gConfigGeneral.use_virtual_floor) if (gConfigGeneral.use_virtual_floor)
{ {
map_set_virtual_floor_height(gSceneryPlaceZ); virtual_floor_set_height(gSceneryPlaceZ);
} }
return; return;
@ -1544,7 +1545,7 @@ static void sub_6E1F34(sint16 x, sint16 y, uint16 selected_scenery, sint16* grid
if (gConfigGeneral.use_virtual_floor) if (gConfigGeneral.use_virtual_floor)
{ {
map_set_virtual_floor_height(gSceneryPlaceZ); virtual_floor_set_height(gSceneryPlaceZ);
} }
} }
@ -2378,7 +2379,7 @@ static void top_toolbar_tool_update_scenery(sint16 x, sint16 y){
if (gConfigGeneral.use_virtual_floor) if (gConfigGeneral.use_virtual_floor)
{ {
map_invalidate_virtual_floor_tiles(); virtual_floor_invalidate();
} }
gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE; gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE;

View File

@ -21,6 +21,14 @@
#include "Paint.h" #include "Paint.h"
#include "tile_element/TileElement.h" #include "tile_element/TileElement.h"
#include "VirtualFloor.h" #include "VirtualFloor.h"
#include <algorithm>
#include <limits>
static uint16 _virtualFloorBaseSize = 5 * 32;
static uint16 _virtualFloorHeight = 0;
static LocationXYZ16 _virtualFloorLastMinPos;
static LocationXYZ16 _virtualFloorLastMaxPos;
static bool _virtualFloorVisible = false;
static constexpr const CoordsXY offsets[4] = static constexpr const CoordsXY offsets[4] =
{ {
@ -30,6 +38,157 @@ static constexpr const CoordsXY offsets[4] =
{ 0, -32 } { 0, -32 }
}; };
void virtual_floor_set_height(sint16 height)
{
if (!_virtualFloorVisible)
{
// If the modifiers are not set we do not actually care as the floor is invisible.
return;
}
if (_virtualFloorHeight != height)
{
virtual_floor_invalidate();
_virtualFloorHeight = height;
}
}
void virtual_floor_enable()
{
if (_virtualFloorVisible)
{
return;
}
// Force invalidation on the next draw.
_virtualFloorLastMinPos.z = std::numeric_limits<sint16>::max();
_virtualFloorLastMaxPos.z = std::numeric_limits<sint16>::lowest();
_virtualFloorVisible = true;
}
void virtual_floor_disable()
{
if (!_virtualFloorVisible)
{
return;
}
// Force invalidation, even if the position hasn't changed.
_virtualFloorLastMinPos.z = std::numeric_limits<sint16>::max();
_virtualFloorLastMaxPos.z = std::numeric_limits<sint16>::lowest();
virtual_floor_invalidate();
_virtualFloorHeight = 0;
_virtualFloorVisible = false;
}
void virtual_floor_invalidate()
{
if (!_virtualFloorVisible)
{
return;
}
// First, let's figure out how big our selection is.
LocationXY16 min_position = { std::numeric_limits<sint16>::max(), std::numeric_limits<sint16>::max() };
LocationXY16 max_position = { std::numeric_limits<sint16>::lowest(), std::numeric_limits<sint16>::lowest() };
if ((gMapSelectFlags & MAP_SELECT_FLAG_ENABLE))
{
min_position = gMapSelectPositionA;
max_position = gMapSelectPositionB;
}
if (gMapSelectFlags & MAP_SELECT_FLAG_ENABLE_CONSTRUCT)
{
for (LocationXY16 * tile = gMapSelectionTiles; tile->x != -1; tile++)
{
min_position.x = std::min(min_position.x, tile->x);
min_position.y = std::min(min_position.y, tile->y);
max_position.x = std::max(max_position.x, tile->x);
max_position.y = std::max(max_position.y, tile->y);
}
}
// Apply the virtual floor size to the computed invalidation area.
min_position.x -= _virtualFloorBaseSize + 1;
min_position.y -= _virtualFloorBaseSize + 1;
max_position.x += _virtualFloorBaseSize + 1;
max_position.y += _virtualFloorBaseSize + 1;
// Do not invalidate if floor hasn't moved.
if (_virtualFloorLastMinPos.x == min_position.x &&
_virtualFloorLastMinPos.y == min_position.y &&
_virtualFloorLastMinPos.z == _virtualFloorHeight)
{
return;
}
LocationXY16 corr_min_position = min_position;
LocationXY16 corr_max_position = max_position;
// Invalidate previous locations, too, if appropriate.
if (_virtualFloorLastMinPos.z != std::numeric_limits<sint16>::max() &&
_virtualFloorLastMaxPos.z != std::numeric_limits<sint16>::lowest())
{
corr_min_position.x = std::min(min_position.x, _virtualFloorLastMinPos.x);
corr_min_position.y = std::min(min_position.y, _virtualFloorLastMinPos.y);
corr_max_position.x = std::max(max_position.x, _virtualFloorLastMaxPos.x);
corr_max_position.y = std::max(max_position.y, _virtualFloorLastMaxPos.y);
}
for (sint16 x = corr_min_position.x; x < corr_max_position.x; x++)
{
for (sint16 y = corr_min_position.y; y < corr_max_position.y; y++)
{
map_invalidate_tile_full(x, y);
}
}
// Save minimal and maximal positions. Note: not their corrected positions!
_virtualFloorLastMinPos.x = min_position.x;
_virtualFloorLastMinPos.y = min_position.y;
_virtualFloorLastMinPos.z = _virtualFloorHeight;
_virtualFloorLastMaxPos.x = max_position.x;
_virtualFloorLastMaxPos.y = max_position.y;
_virtualFloorLastMaxPos.z = _virtualFloorHeight;
}
bool virtual_floor_tile_is_floor(sint16 x, sint16 y)
{
if (!_virtualFloorVisible)
{
return 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) &&
x >= gMapSelectPositionA.x - _virtualFloorBaseSize &&
y >= gMapSelectPositionA.y - _virtualFloorBaseSize &&
x <= gMapSelectPositionB.x + _virtualFloorBaseSize &&
y <= gMapSelectPositionB.y + _virtualFloorBaseSize)
{
return 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 (x >= tile->x - _virtualFloorBaseSize &&
y >= tile->y - _virtualFloorBaseSize &&
x <= tile->x + _virtualFloorBaseSize &&
y <= tile->y + _virtualFloorBaseSize)
{
return true;
}
}
}
return false;
}
static void virtual_floor_get_tile_properties(sint16 x, sint16 y, sint16 height, bool * outOccupied, uint8 * outOccupiedEdges, bool * outBelowGround, bool * outLit) static void virtual_floor_get_tile_properties(sint16 x, sint16 y, sint16 height, bool * outOccupied, uint8 * outOccupiedEdges, bool * outBelowGround, bool * outLit)
{ {
*outOccupied = false; *outOccupied = false;
@ -119,7 +278,7 @@ void virtual_floor_paint(paint_session * session)
// This is a virtual floor, so no interactions // This is a virtual floor, so no interactions
session->InteractionType = VIEWPORT_INTERACTION_ITEM_NONE; session->InteractionType = VIEWPORT_INTERACTION_ITEM_NONE;
sint16 virtualFloorClipHeight = gMapVirtualFloorHeight / 8; sint16 virtualFloorClipHeight = _virtualFloorHeight / 8;
// Check for occupation and walls // Check for occupation and walls
bool weAreOccupied; bool weAreOccupied;
@ -179,33 +338,38 @@ void virtual_floor_paint(paint_session * session)
sub_98197C( sub_98197C(
session, session,
SPR_G2_SELECTION_EDGE_NE | (!(occupiedEdges & 0x1) ? ((litEdges & 0x1) ? remap_lit : remap_base) : remap_edge), 0, SPR_G2_SELECTION_EDGE_NE | (!(occupiedEdges & 0x1) ? ((litEdges & 0x1) ? remap_lit : remap_base) : remap_edge), 0,
0, 0, 0, 1, gMapVirtualFloorHeight, 5, 5, gMapVirtualFloorHeight + ((dullEdges & 0x1) ? -2 : 0)); 0, 0, 0, 1, _virtualFloorHeight, 5, 5, _virtualFloorHeight + ((dullEdges & 0x1) ? -2 : 0));
} }
if (paintEdges & 0x2) if (paintEdges & 0x2)
{ {
sub_98197C( sub_98197C(
session, session,
SPR_G2_SELECTION_EDGE_SE | (!(occupiedEdges & 0x2) ? ((litEdges & 0x2) ? remap_lit : remap_base) : remap_edge), 0, 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)); 0, 1, 1, 1, _virtualFloorHeight, 16, 27, _virtualFloorHeight + ((dullEdges & 0x2) ? -2 : 0));
} }
if (paintEdges & 0x4) if (paintEdges & 0x4)
{ {
sub_98197C( sub_98197C(
session, session,
SPR_G2_SELECTION_EDGE_SW | (!(occupiedEdges & 0x4) ? ((litEdges & 0x4) ? remap_lit : remap_base) : remap_edge), 0, 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)); 0, 1, 1, 1, _virtualFloorHeight, 27, 16, _virtualFloorHeight + ((dullEdges & 0x4) ? -2 : 0));
} }
if (paintEdges & 0x8) if (paintEdges & 0x8)
{ {
sub_98197C( sub_98197C(
session, session,
SPR_G2_SELECTION_EDGE_NW | (!(occupiedEdges & 0x8) ? ((litEdges & 0x8) ? remap_lit : remap_base) : remap_edge), 0, 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)); 0, 0, 0, 1, _virtualFloorHeight, 5, 5, _virtualFloorHeight + ((dullEdges & 0x8) ? -2 : 0));
} }
if (!weAreOccupied && !weAreLit) if (!weAreOccupied && !weAreLit)
{ {
sint32 imageColourFlats = SPR_G2_SURFACE_GLASSY_RECOLOURABLE | IMAGE_TYPE_REMAP | IMAGE_TYPE_TRANSPARENT | PALETTE_WATER << 19; sint32 imageColourFlats = SPR_G2_SURFACE_GLASSY_RECOLOURABLE | IMAGE_TYPE_REMAP | IMAGE_TYPE_TRANSPARENT | PALETTE_WATER << 19;
sub_98197C(session, imageColourFlats, 0, 0, 30, 30, 0, gMapVirtualFloorHeight, 2, 2, gMapVirtualFloorHeight - 3); sub_98197C(session, imageColourFlats, 0, 0, 30, 30, 0, _virtualFloorHeight, 2, 2, _virtualFloorHeight - 3);
} }
} }
uint16 virtual_floor_get_height()
{
return _virtualFloorHeight;
}

View File

@ -17,5 +17,17 @@
#ifndef _VIRTUAL_FLOOR_H #ifndef _VIRTUAL_FLOOR_H
#define _VIRTUAL_FLOOR_H #define _VIRTUAL_FLOOR_H
uint16 virtual_floor_get_height();
bool virtual_floor_is_enabled();
void virtual_floor_set_height(sint16 height);
void virtual_floor_enable();
void virtual_floor_disable();
void virtual_floor_invalidate();
bool virtual_floor_tile_is_floor(sint16 x, sint16 y);
void virtual_floor_paint(paint_session * session); void virtual_floor_paint(paint_session * session);
#endif #endif

View File

@ -158,7 +158,7 @@ static void sub_68B3FB(paint_session * session, sint32 x, sint32 y)
#ifndef __TESTPAINT__ #ifndef __TESTPAINT__
if (gConfigGeneral.use_virtual_floor) if (gConfigGeneral.use_virtual_floor)
{ {
partOfVirtualFloor = map_tile_is_part_of_virtual_floor(session->MapPosition.x, session->MapPosition.y); partOfVirtualFloor = virtual_floor_tile_is_floor(session->MapPosition.x, session->MapPosition.y);
} }
#endif // __TESTPAINT__ #endif // __TESTPAINT__
@ -236,7 +236,7 @@ static void sub_68B3FB(paint_session * session, sint32 x, sint32 y)
if (partOfVirtualFloor) if (partOfVirtualFloor)
{ {
// We must pretend this tile is at least as tall as the virtual floor // We must pretend this tile is at least as tall as the virtual floor
max_height = Math::Max(max_height, gMapVirtualFloorHeight); max_height = std::max(max_height, virtual_floor_get_height());
} }
#endif // __TESTPAINT__ #endif // __TESTPAINT__

View File

@ -37,6 +37,7 @@
#include "../object/ObjectList.h" #include "../object/ObjectList.h"
#include "../object/ObjectManager.h" #include "../object/ObjectManager.h"
#include "../OpenRCT2.h" #include "../OpenRCT2.h"
#include "../paint/VirtualFloor.h"
#include "../peep/Peep.h" #include "../peep/Peep.h"
#include "../peep/Staff.h" #include "../peep/Staff.h"
#include "../rct1/RCT1.h" #include "../rct1/RCT1.h"
@ -1655,7 +1656,7 @@ void ride_select_next_section()
} }
// Invalidate previous track piece (we may not be changing height!) // Invalidate previous track piece (we may not be changing height!)
map_invalidate_virtual_floor_tiles(); virtual_floor_invalidate();
CoordsXYE inputElement, outputElement; CoordsXYE inputElement, outputElement;
inputElement.x = x; inputElement.x = x;
@ -1668,7 +1669,7 @@ void ride_select_next_section()
if (!scenery_tool_is_active()) if (!scenery_tool_is_active())
{ {
// Set next element's height. // Set next element's height.
map_set_virtual_floor_height(tileElement->base_height << 3); virtual_floor_set_height(tileElement->base_height << 3);
} }
} else { } else {
_rideConstructionState = RIDE_CONSTRUCTION_STATE_FRONT; _rideConstructionState = RIDE_CONSTRUCTION_STATE_FRONT;
@ -1720,7 +1721,7 @@ void ride_select_previous_section()
} }
// Invalidate previous track piece (we may not be changing height!) // Invalidate previous track piece (we may not be changing height!)
map_invalidate_virtual_floor_tiles(); virtual_floor_invalidate();
track_begin_end trackBeginEnd; track_begin_end trackBeginEnd;
if (track_block_get_previous(x, y, tileElement, &trackBeginEnd)) { if (track_block_get_previous(x, y, tileElement, &trackBeginEnd)) {
@ -1734,7 +1735,7 @@ void ride_select_previous_section()
if (!scenery_tool_is_active()) if (!scenery_tool_is_active())
{ {
// Set previous element's height. // Set previous element's height.
map_set_virtual_floor_height(trackBeginEnd.begin_element->base_height << 3); virtual_floor_set_height(trackBeginEnd.begin_element->base_height << 3);
} }
window_ride_construction_update_active_elements(); window_ride_construction_update_active_elements();
} else { } else {

View File

@ -22,6 +22,7 @@
#include "../Input.h" #include "../Input.h"
#include "../interface/Viewport.h" #include "../interface/Viewport.h"
#include "../network/network.h" #include "../network/network.h"
#include "../paint/VirtualFloor.h"
#include "../ride/Track.h" #include "../ride/Track.h"
#include "../ride/TrackData.h" #include "../ride/TrackData.h"
#include "../world/Scenery.h" #include "../world/Scenery.h"
@ -152,10 +153,10 @@ money32 place_provisional_track_piece(sint32 rideIndex, sint32 trackType, sint32
if (!scenery_tool_is_active()) if (!scenery_tool_is_active())
{ {
// Invalidate previous track piece (we may not be changing height!) // Invalidate previous track piece (we may not be changing height!)
map_invalidate_virtual_floor_tiles(); virtual_floor_invalidate();
// Set new virtual floor height. // Set new virtual floor height.
map_set_virtual_floor_height(z); virtual_floor_set_height(z);
} }
return result; return result;
@ -190,10 +191,10 @@ money32 place_provisional_track_piece(sint32 rideIndex, sint32 trackType, sint32
if (!scenery_tool_is_active()) if (!scenery_tool_is_active())
{ {
// Invalidate previous track piece (we may not be changing height!) // Invalidate previous track piece (we may not be changing height!)
map_invalidate_virtual_floor_tiles(); virtual_floor_invalidate();
// Set height to where the next track piece would begin // Set height to where the next track piece would begin
map_set_virtual_floor_height(z - z_begin + z_end); virtual_floor_set_height(z - z_begin + z_end);
} }
return result; return result;

View File

@ -23,6 +23,7 @@
#include "../object/ObjectList.h" #include "../object/ObjectList.h"
#include "../object/ObjectManager.h" #include "../object/ObjectManager.h"
#include "../OpenRCT2.h" #include "../OpenRCT2.h"
#include "../paint/VirtualFloor.h"
#include "../ride/Station.h" #include "../ride/Station.h"
#include "../ride/Track.h" #include "../ride/Track.h"
#include "../ride/TrackData.h" #include "../ride/TrackData.h"
@ -747,25 +748,25 @@ money32 footpath_provisional_set(sint32 type, sint32 x, sint32 y, sint32 z, sint
} }
// Invalidate previous footpath piece. // Invalidate previous footpath piece.
map_invalidate_virtual_floor_tiles(); virtual_floor_invalidate();
if (!scenery_tool_is_active()) if (!scenery_tool_is_active())
{ {
if (cost == MONEY32_UNDEFINED) if (cost == MONEY32_UNDEFINED)
{ {
// If we can't build this, don't show a virtual floor. // If we can't build this, don't show a virtual floor.
map_set_virtual_floor_height(0); virtual_floor_set_height(0);
} }
else if (gFootpathConstructSlope == TILE_ELEMENT_SLOPE_FLAT else if (gFootpathConstructSlope == TILE_ELEMENT_SLOPE_FLAT
|| gFootpathProvisionalPosition.z * 8 < gFootpathConstructFromPosition.z) || gFootpathProvisionalPosition.z * 8 < gFootpathConstructFromPosition.z)
{ {
// Going either straight on, or down. // Going either straight on, or down.
map_set_virtual_floor_height(gFootpathProvisionalPosition.z * 8); virtual_floor_set_height(gFootpathProvisionalPosition.z * 8);
} }
else else
{ {
// Going up in the world! // Going up in the world!
map_set_virtual_floor_height((gFootpathProvisionalPosition.z + 2) * 8); virtual_floor_set_height((gFootpathProvisionalPosition.z + 2) * 8);
} }
} }

View File

@ -47,8 +47,6 @@
#include "TileInspector.h" #include "TileInspector.h"
#include "Wall.h" #include "Wall.h"
#include <limits>
/** /**
* Replaces 0x00993CCC, 0x00993CCE * Replaces 0x00993CCC, 0x00993CCE
*/ */
@ -88,10 +86,6 @@ LocationXY16 gMapSelectPositionB;
LocationXYZ16 gMapSelectArrowPosition; LocationXYZ16 gMapSelectArrowPosition;
uint8 gMapSelectArrowDirection; uint8 gMapSelectArrowDirection;
uint16 gMapVirtualFloorBaseSize = 5*32;
uint16 gMapVirtualFloorHeight;
bool gMapVirtualFloorVisible = false;
uint8 gMapGroundFlags; uint8 gMapGroundFlags;
uint16 gWidePathTileLoopX; uint16 gWidePathTileLoopX;
@ -107,8 +101,6 @@ sint16 gMapBaseZ;
rct_tile_element gTileElements[MAX_TILE_TILE_ELEMENT_POINTERS * 3]; rct_tile_element gTileElements[MAX_TILE_TILE_ELEMENT_POINTERS * 3];
rct_tile_element *gTileElementTilePointers[MAX_TILE_TILE_ELEMENT_POINTERS]; rct_tile_element *gTileElementTilePointers[MAX_TILE_TILE_ELEMENT_POINTERS];
LocationXY16 gMapSelectionTiles[300]; LocationXY16 gMapSelectionTiles[300];
static LocationXYZ16 gVirtualFloorLastMinLocation;
static LocationXYZ16 gVirtualFloorLastMaxLocation;
PeepSpawn gPeepSpawns[MAX_PEEP_SPAWNS]; PeepSpawn gPeepSpawns[MAX_PEEP_SPAWNS];
rct_tile_element *gNextFreeTileElement; rct_tile_element *gNextFreeTileElement;
@ -2988,7 +2980,7 @@ void map_invalidate_map_selection_tiles()
map_invalidate_tile_full(position->x, position->y); map_invalidate_tile_full(position->x, position->y);
} }
static void map_get_bounding_box(sint32 ax, sint32 ay, sint32 bx, sint32 by, sint32 *left, sint32 *top, sint32 *right, sint32 *bottom) void map_get_bounding_box(sint32 ax, sint32 ay, sint32 bx, sint32 by, sint32 *left, sint32 *top, sint32 *right, sint32 *bottom)
{ {
sint32 x, y; sint32 x, y;
x = ax; x = ax;
@ -4748,157 +4740,6 @@ uint8 tile_element_get_ride_index(const rct_tile_element * tileElement)
} }
} }
void map_set_virtual_floor_height(sint16 height)
{
if (!gMapVirtualFloorVisible)
{
// If the modifiers are not set we do not actually care as the floor is invisible.
return;
}
if (gMapVirtualFloorHeight != height)
{
map_invalidate_virtual_floor_tiles();
gMapVirtualFloorHeight = height;
}
}
void map_enable_virtual_floor()
{
if (gMapVirtualFloorVisible)
{
return;
}
// Force invalidation on the next draw.
gVirtualFloorLastMinLocation.z = std::numeric_limits<sint16>::max();
gVirtualFloorLastMaxLocation.z = std::numeric_limits<sint16>::lowest();
gMapVirtualFloorVisible = true;
}
void map_remove_virtual_floor()
{
if (!gMapVirtualFloorVisible)
{
return;
}
// Force invalidation, even if the position hasn't changed.
gVirtualFloorLastMinLocation.z = std::numeric_limits<sint16>::max();
gVirtualFloorLastMaxLocation.z = std::numeric_limits<sint16>::lowest();
map_invalidate_virtual_floor_tiles();
gMapVirtualFloorHeight = 0;
gMapVirtualFloorVisible = false;
}
void map_invalidate_virtual_floor_tiles()
{
if (!gMapVirtualFloorVisible)
{
return;
}
// First, let's figure out how big our selection is.
LocationXY16 min_position = { std::numeric_limits<sint16>::max(), std::numeric_limits<sint16>::max() };
LocationXY16 max_position = { std::numeric_limits<sint16>::lowest(), std::numeric_limits<sint16>::lowest() };
if ((gMapSelectFlags & MAP_SELECT_FLAG_ENABLE))
{
min_position = gMapSelectPositionA;
max_position = gMapSelectPositionB;
}
if (gMapSelectFlags & MAP_SELECT_FLAG_ENABLE_CONSTRUCT)
{
for (LocationXY16 * tile = gMapSelectionTiles; tile->x != -1; tile++)
{
min_position.x = std::min(min_position.x, tile->x);
min_position.y = std::min(min_position.y, tile->y);
max_position.x = std::max(max_position.x, tile->x);
max_position.y = std::max(max_position.y, tile->y);
}
}
// Apply the virtual floor size to the computed invalidation area.
min_position.x -= gMapVirtualFloorBaseSize + 1;
min_position.y -= gMapVirtualFloorBaseSize + 1;
max_position.x += gMapVirtualFloorBaseSize + 1;
max_position.y += gMapVirtualFloorBaseSize + 1;
// Do not invalidate if floor hasn't moved.
if (gVirtualFloorLastMinLocation.x == min_position.x &&
gVirtualFloorLastMinLocation.y == min_position.y &&
gVirtualFloorLastMinLocation.z == gMapVirtualFloorHeight)
{
return;
}
LocationXY16 corr_min_position = min_position;
LocationXY16 corr_max_position = max_position;
// Invalidate previous locations, too, if appropriate.
if (gVirtualFloorLastMinLocation.z != std::numeric_limits<sint16>::max() &&
gVirtualFloorLastMaxLocation.z != std::numeric_limits<sint16>::lowest())
{
corr_min_position.x = std::min(min_position.x, gVirtualFloorLastMinLocation.x);
corr_min_position.y = std::min(min_position.y, gVirtualFloorLastMinLocation.y);
corr_max_position.x = std::max(max_position.x, gVirtualFloorLastMaxLocation.x);
corr_max_position.y = std::max(max_position.y, gVirtualFloorLastMaxLocation.y);
}
for (sint16 x = corr_min_position.x; x < corr_max_position.x; x++)
{
for (sint16 y = corr_min_position.y; y < corr_max_position.y; y++)
{
map_invalidate_tile_full(x, y);
}
}
// Save minimal and maximal positions. Note: not their corrected positions!
gVirtualFloorLastMinLocation.x = min_position.x;
gVirtualFloorLastMinLocation.y = min_position.y;
gVirtualFloorLastMinLocation.z = gMapVirtualFloorHeight;
gVirtualFloorLastMaxLocation.x = max_position.x;
gVirtualFloorLastMaxLocation.y = max_position.y;
gVirtualFloorLastMaxLocation.z = gMapVirtualFloorHeight;
}
bool map_tile_is_part_of_virtual_floor(sint16 x, sint16 y)
{
if (!gMapVirtualFloorVisible)
{
return 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) &&
x >= gMapSelectPositionA.x - gMapVirtualFloorBaseSize &&
y >= gMapSelectPositionA.y - gMapVirtualFloorBaseSize &&
x <= gMapSelectPositionB.x + gMapVirtualFloorBaseSize &&
y <= gMapSelectPositionB.y + gMapVirtualFloorBaseSize)
{
return 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 (x >= tile->x - gMapVirtualFloorBaseSize &&
y >= tile->y - gMapVirtualFloorBaseSize &&
x <= tile->x + gMapVirtualFloorBaseSize &&
y <= tile->y + gMapVirtualFloorBaseSize)
{
return true;
}
}
}
return false;
}
void FixLandOwnershipTiles(std::initializer_list<TileCoordsXY> tiles) void FixLandOwnershipTiles(std::initializer_list<TileCoordsXY> tiles)
{ {
FixLandOwnershipTilesWithOwnership(tiles, OWNERSHIP_AVAILABLE); FixLandOwnershipTilesWithOwnership(tiles, OWNERSHIP_AVAILABLE);

View File

@ -385,10 +385,6 @@ extern LocationXY16 gMapSelectPositionB;
extern LocationXYZ16 gMapSelectArrowPosition; extern LocationXYZ16 gMapSelectArrowPosition;
extern uint8 gMapSelectArrowDirection; extern uint8 gMapSelectArrowDirection;
extern uint16 gMapVirtualFloorHeight;
extern uint16 gMapVirtualFloorBaseSize;
extern bool gMapVirtualFloorVisible;
extern uint8 gMapGroundFlags; extern uint8 gMapGroundFlags;
extern rct_tile_element gTileElements[MAX_TILE_TILE_ELEMENT_POINTERS * 3]; extern rct_tile_element gTileElements[MAX_TILE_TILE_ELEMENT_POINTERS * 3];
@ -458,16 +454,12 @@ bool map_surface_is_blocked(sint16 x, sint16 y);
void tile_element_remove(rct_tile_element *tileElement); void tile_element_remove(rct_tile_element *tileElement);
void map_remove_all_rides(); void map_remove_all_rides();
void map_invalidate_map_selection_tiles(); void map_invalidate_map_selection_tiles();
void map_get_bounding_box(sint32 ax, sint32 ay, sint32 bx, sint32 by, sint32 *left, sint32 *top, sint32 *right, sint32 *bottom);
void map_invalidate_selection_rect(); void map_invalidate_selection_rect();
void map_reorganise_elements(); void map_reorganise_elements();
bool map_check_free_elements_and_reorganise(sint32 num_elements); bool map_check_free_elements_and_reorganise(sint32 num_elements);
rct_tile_element *tile_element_insert(sint32 x, sint32 y, sint32 z, sint32 flags); rct_tile_element *tile_element_insert(sint32 x, sint32 y, sint32 z, sint32 flags);
bool tile_element_check_address(const rct_tile_element * const element); bool tile_element_check_address(const rct_tile_element * const element);
void map_set_virtual_floor_height(sint16 height);
void map_enable_virtual_floor();
void map_remove_virtual_floor();
void map_invalidate_virtual_floor_tiles();
bool map_tile_is_part_of_virtual_floor(sint16 x, sint16 y);
using CLEAR_FUNC = sint32(*)(rct_tile_element** tile_element, sint32 x, sint32 y, uint8 flags, money32* price); using CLEAR_FUNC = sint32(*)(rct_tile_element** tile_element, sint32 x, sint32 y, uint8 flags, money32* price);