Merge pull request #7992 from Gymnasiast/more-tile-element-stuff

More tile element stuff
This commit is contained in:
Michael Steenbeek 2018-09-17 13:56:41 +02:00 committed by GitHub
commit c7632f29a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
58 changed files with 856 additions and 811 deletions

View File

@ -316,7 +316,7 @@ int32_t viewport_interaction_get_item_right(int32_t x, int32_t y, viewport_inter
break;
case VIEWPORT_INTERACTION_ITEM_LARGE_SCENERY:
sceneryEntry = get_large_scenery_entry(scenery_large_get_type(tileElement));
sceneryEntry = tileElement->AsLargeScenery()->GetEntry();
if (sceneryEntry->large_scenery.scrolling_mode != 255)
{
set_map_tooltip_format_arg(0, rct_string_id, STR_MAP_TOOLTIP_STRINGID_CLICK_TO_MODIFY);
@ -389,7 +389,7 @@ int32_t viewport_interaction_get_item_right(int32_t x, int32_t y, viewport_inter
return info->type;
case VIEWPORT_INTERACTION_ITEM_LARGE_SCENERY:
sceneryEntry = get_large_scenery_entry(tileElement->properties.scenerymultiple.type & 0x3FF);
sceneryEntry = tileElement->AsLargeScenery()->GetEntry();
set_map_tooltip_format_arg(0, rct_string_id, STR_MAP_TOOLTIP_STRINGID_CLICK_TO_REMOVE);
set_map_tooltip_format_arg(2, rct_string_id, sceneryEntry->name);
return info->type;
@ -518,7 +518,7 @@ static void viewport_interaction_remove_footpath_item(rct_tile_element* tileElem
*/
void viewport_interaction_remove_park_entrance(rct_tile_element* tileElement, int32_t x, int32_t y)
{
int32_t rotation = tile_element_get_direction_with_offset(tileElement, 1);
int32_t rotation = tileElement->GetDirectionWithOffset(1);
switch (tileElement->properties.entrance.index & 0x0F)
{
case 1:
@ -559,19 +559,20 @@ static void viewport_interaction_remove_park_wall(rct_tile_element* tileElement,
*/
static void viewport_interaction_remove_large_scenery(rct_tile_element* tileElement, int32_t x, int32_t y)
{
rct_scenery_entry* sceneryEntry = get_large_scenery_entry(scenery_large_get_type(tileElement));
rct_scenery_entry* sceneryEntry = tileElement->AsLargeScenery()->GetEntry();
if (sceneryEntry->large_scenery.scrolling_mode != 0xFF)
{
BannerIndex bannerIndex = scenery_large_get_banner_id(tileElement);
BannerIndex bannerIndex = tileElement->AsLargeScenery()->GetBannerIndex();
context_open_detail_window(WD_SIGN, bannerIndex);
}
else
{
gGameCommandErrorTitle = STR_CANT_REMOVE_THIS;
game_do_command(
x, 1 | (tile_element_get_direction(tileElement) << 8), y,
tileElement->base_height | (scenery_large_get_sequence(tileElement) << 8), GAME_COMMAND_REMOVE_LARGE_SCENERY, 0, 0);
x, 1 | (tileElement->GetDirection() << 8), y,
tileElement->base_height | (tileElement->AsLargeScenery()->GetSequenceIndex() << 8),
GAME_COMMAND_REMOVE_LARGE_SCENERY, 0, 0);
}
}
@ -639,7 +640,7 @@ void sub_68A15E(int32_t screenX, int32_t screenY, int16_t* x, int16_t* y, int32_
int16_t originalZ = 0;
if (interactionType == VIEWPORT_INTERACTION_ITEM_WATER)
{
originalZ = surface_get_water_height(myTileElement) << 4;
originalZ = myTileElement->AsSurface()->GetWaterHeight() << 4;
}
LocationXY16 start_vp_pos = screen_coord_to_viewport_coord(viewport, screenX, screenY);

View File

@ -755,7 +755,7 @@ static void window_footpath_set_provisional_path_at_point(int32_t x, int32_t y)
switch (interactionType)
{
case VIEWPORT_INTERACTION_ITEM_TERRAIN:
slope = DefaultPathSlope[tileElement->properties.surface.slope & TILE_ELEMENT_SURFACE_RAISED_CORNERS_MASK];
slope = DefaultPathSlope[tileElement->AsSurface()->GetSlope() & TILE_ELEMENT_SURFACE_RAISED_CORNERS_MASK];
break;
case VIEWPORT_INTERACTION_ITEM_FOOTPATH:
slope = tileElement->properties.path.type
@ -804,7 +804,7 @@ static void window_footpath_set_selection_start_bridge_at_point(int32_t screenX,
if (tileElement->GetType() == TILE_ELEMENT_TYPE_SURFACE)
{
uint8_t slope = tileElement->properties.surface.slope;
uint8_t slope = tileElement->AsSurface()->GetSlope();
if (slope & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP)
{
z += 2;
@ -851,7 +851,7 @@ static void window_footpath_place_path_at_point(int32_t x, int32_t y)
switch (interactionType)
{
case VIEWPORT_INTERACTION_ITEM_TERRAIN:
presentType = DefaultPathSlope[tileElement->properties.surface.slope & TILE_ELEMENT_SURFACE_RAISED_CORNERS_MASK];
presentType = DefaultPathSlope[tileElement->AsSurface()->GetSlope() & TILE_ELEMENT_SURFACE_RAISED_CORNERS_MASK];
break;
case VIEWPORT_INTERACTION_ITEM_FOOTPATH:
presentType = tileElement->properties.path.type
@ -897,7 +897,7 @@ static void window_footpath_start_bridge_at_point(int32_t screenX, int32_t scree
{
// If we start the path on a slope, the arrow is slightly raised, so we
// expect the path to be slightly raised as well.
uint8_t slope = tileElement->properties.surface.slope;
uint8_t slope = tileElement->AsSurface()->GetSlope();
z = tileElement->base_height;
if (slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
{

View File

@ -1197,14 +1197,14 @@ static void place_park_entrance_get_map_position(
return;
tileElement = map_get_surface_element_at(*mapX >> 5, *mapY >> 5);
*mapZ = surface_get_water_height(tileElement);
*mapZ = tileElement->AsSurface()->GetWaterHeight();
if (*mapZ == 0)
{
*mapZ = tileElement->base_height / 2;
if ((tileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP) != 0)
if ((tileElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP) != 0)
{
(*mapZ)++;
if (tileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
if (tileElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
{
(*mapZ)++;
}
@ -1280,9 +1280,9 @@ static void window_map_set_peep_spawn_tool_update(int32_t x, int32_t y)
mapZ = tileElement->base_height * 8;
if (tileElement->GetType() == TILE_ELEMENT_TYPE_SURFACE)
{
if ((tileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP) != 0)
if ((tileElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP) != 0)
mapZ += 16;
if (tileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
if (tileElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
mapZ += 16;
}
@ -1542,11 +1542,11 @@ static constexpr const uint8_t RideColourKey[] = {
static uint16_t map_window_get_pixel_colour_peep(CoordsXY c)
{
rct_tile_element* tileElement = map_get_surface_element_at(c);
uint16_t colour = TerrainColour[surface_get_terrain(tileElement)];
if (surface_get_water_height(tileElement) > 0)
uint16_t colour = TerrainColour[tileElement->AsSurface()->GetSurfaceStyle()];
if (tileElement->AsSurface()->GetWaterHeight() > 0)
colour = WaterColour;
if (!(tileElement->properties.surface.ownership & OWNERSHIP_OWNED))
if (!(tileElement->AsSurface()->GetOwnership() & OWNERSHIP_OWNED))
colour = MAP_COLOUR_UNOWNED(colour);
const int32_t maxSupportedTileElementType = (int32_t)Util::CountOf(ElementTypeAddColour);
@ -1577,10 +1577,10 @@ static uint16_t map_window_get_pixel_colour_ride(CoordsXY c)
switch (tileElement->GetType())
{
case TILE_ELEMENT_TYPE_SURFACE:
if (surface_get_water_height(tileElement) > 0)
if (tileElement->AsSurface()->GetWaterHeight() > 0)
// Why is this a different water colour as above (195)?
colourB = MAP_COLOUR(PALETTE_INDEX_194);
if (!(tileElement->properties.surface.ownership & OWNERSHIP_OWNED))
if (!(tileElement->AsSurface()->GetOwnership() & OWNERSHIP_OWNED))
colourB = MAP_COLOUR_UNOWNED(colourB);
break;
case TILE_ELEMENT_TYPE_PATH:

View File

@ -4267,7 +4267,7 @@ static void window_ride_set_track_colour_scheme(rct_window* w, int32_t x, int32_
return;
z = tileElement->base_height * 8;
direction = tile_element_get_direction(tileElement);
direction = tileElement->GetDirection();
sub_6C683D(&x, &y, &z, direction, track_element_get_type(tileElement), newColourScheme, nullptr, 4);
}

View File

@ -1759,7 +1759,7 @@ static void window_ride_construction_construct(rct_window* w)
_currentTrackBeginX = next_track.x;
_currentTrackBeginY = next_track.y;
_currentTrackBeginZ = z;
_currentTrackPieceDirection = tile_element_get_direction(next_track.element);
_currentTrackPieceDirection = next_track.element->GetDirection();
_currentTrackPieceType = track_element_get_type(next_track.element);
_currentTrackSelectionFlags = 0;
_rideConstructionArrowPulseTime = 0;
@ -1846,7 +1846,7 @@ static void window_ride_construction_mouseup_demolish(rct_window* w)
{
x = outputElement.x;
y = outputElement.y;
direction = tile_element_get_direction(outputElement.element);
direction = outputElement.element->GetDirection();
type = track_element_get_type(outputElement.element);
gGotoStartPlacementMode = false;
}

View File

@ -20,6 +20,7 @@
#include <openrct2/network/network.h>
#include <openrct2/object/ObjectList.h>
#include <openrct2/sprites.h>
#include <openrct2/world/LargeScenery.h>
#include <openrct2/world/Park.h>
#include <openrct2/world/Scenery.h>
#include <openrct2/world/SmallScenery.h>

View File

@ -160,10 +160,10 @@ rct_window* window_sign_open(rct_windownumber number)
{
if (tile_element->GetType() == TILE_ELEMENT_TYPE_LARGE_SCENERY)
{
rct_scenery_entry* scenery_entry = get_large_scenery_entry(scenery_large_get_type(tile_element));
rct_scenery_entry* scenery_entry = tile_element->AsLargeScenery()->GetEntry();
if (scenery_entry->large_scenery.scrolling_mode != 0xFF)
{
BannerIndex bannerIndex = scenery_large_get_banner_id(tile_element);
BannerIndex bannerIndex = tile_element->AsLargeScenery()->GetBannerIndex();
if (bannerIndex == w->number)
break;
@ -175,9 +175,9 @@ rct_window* window_sign_open(rct_windownumber number)
int32_t view_z = tile_element->base_height << 3;
w->frame_no = view_z;
w->list_information_type = scenery_large_get_primary_colour(tile_element);
w->var_492 = scenery_large_get_secondary_colour(tile_element);
w->var_48C = scenery_large_get_type(tile_element);
w->list_information_type = tile_element->AsLargeScenery()->GetPrimaryColour();
w->var_492 = tile_element->AsLargeScenery()->GetSecondaryColour();
w->var_48C = tile_element->AsLargeScenery()->GetEntryIndex();
view_x += 16;
view_y += 16;
@ -218,10 +218,10 @@ static void window_sign_mouseup(rct_window* w, rct_widgetindex widgetIndex)
{
if (tile_element->GetType() == TILE_ELEMENT_TYPE_LARGE_SCENERY)
{
rct_scenery_entry* scenery_entry = get_large_scenery_entry(scenery_large_get_type(tile_element));
rct_scenery_entry* scenery_entry = tile_element->AsLargeScenery()->GetEntry();
if (scenery_entry->large_scenery.scrolling_mode != 0xFF)
{
BannerIndex bannerIndex = scenery_large_get_banner_id(tile_element);
BannerIndex bannerIndex = tile_element->AsLargeScenery()->GetBannerIndex();
if (bannerIndex == w->number)
break;
}
@ -230,8 +230,8 @@ static void window_sign_mouseup(rct_window* w, rct_widgetindex widgetIndex)
}
game_do_command(
x, 1 | (tile_element->GetDirection() << 8), y,
tile_element->base_height | (scenery_large_get_sequence(tile_element) << 8), GAME_COMMAND_REMOVE_LARGE_SCENERY,
0, 0);
tile_element->base_height | (tile_element->AsLargeScenery()->GetSequenceIndex() << 8),
GAME_COMMAND_REMOVE_LARGE_SCENERY, 0, 0);
break;
case WIDX_SIGN_TEXT:
if (banner->flags & BANNER_FLAG_LINKED_TO_RIDE)

View File

@ -1476,18 +1476,18 @@ static void window_tile_inspector_invalidate(rct_window* w)
w->widgets[WIDX_SURFACE_CHECK_DIAGONAL].bottom = w->widgets[WIDX_SURFACE_CHECK_DIAGONAL].top + 13;
widget_set_checkbox_value(
w, WIDX_SURFACE_CHECK_CORNER_N,
tileElement->properties.surface.slope & (1 << ((2 - get_current_rotation()) & 3)));
tileElement->AsSurface()->GetSlope() & (1 << ((2 - get_current_rotation()) & 3)));
widget_set_checkbox_value(
w, WIDX_SURFACE_CHECK_CORNER_E,
tileElement->properties.surface.slope & (1 << ((3 - get_current_rotation()) & 3)));
tileElement->AsSurface()->GetSlope() & (1 << ((3 - get_current_rotation()) & 3)));
widget_set_checkbox_value(
w, WIDX_SURFACE_CHECK_CORNER_S,
tileElement->properties.surface.slope & (1 << ((0 - get_current_rotation()) & 3)));
tileElement->AsSurface()->GetSlope() & (1 << ((0 - get_current_rotation()) & 3)));
widget_set_checkbox_value(
w, WIDX_SURFACE_CHECK_CORNER_W,
tileElement->properties.surface.slope & (1 << ((1 - get_current_rotation()) & 3)));
tileElement->AsSurface()->GetSlope() & (1 << ((1 - get_current_rotation()) & 3)));
widget_set_checkbox_value(
w, WIDX_SURFACE_CHECK_DIAGONAL, tileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT);
w, WIDX_SURFACE_CHECK_DIAGONAL, tileElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT);
break;
case TILE_INSPECTOR_PAGE_PATH:
w->widgets[WIDX_PATH_SPINNER_HEIGHT].top = GBBT(propertiesAnchor, 0) + 3;
@ -1757,33 +1757,33 @@ static void window_tile_inspector_paint(rct_window* w, rct_drawpixelinfo* dpi)
{
// Details
// Terrain texture name
rct_string_id terrainNameId = TerrainTypeStringIds[surface_get_terrain(tileElement)];
rct_string_id terrainNameId = TerrainTypeStringIds[tileElement->AsSurface()->GetSurfaceStyle()];
gfx_draw_string_left(dpi, STR_TILE_INSPECTOR_SURFACE_TERAIN, &terrainNameId, COLOUR_DARK_GREEN, x, y);
// Edge texture name
int32_t idx = surface_get_terrain_edge(tileElement);
uint32_t idx = tileElement->AsSurface()->GetEdgeStyle();
openrct2_assert(
(uint32_t)idx < Util::CountOf(TerrainEdgeTypeStringIds),
"Tried accessing invalid entry %d in terrainEdgeTypeStringIds", idx);
rct_string_id terrainEdgeNameId = TerrainEdgeTypeStringIds[surface_get_terrain_edge(tileElement)];
rct_string_id terrainEdgeNameId = TerrainEdgeTypeStringIds[tileElement->AsSurface()->GetEdgeStyle()];
gfx_draw_string_left(dpi, STR_TILE_INSPECTOR_SURFACE_EDGE, &terrainEdgeNameId, COLOUR_DARK_GREEN, x, y + 11);
// Land ownership
rct_string_id landOwnership;
if (tileElement->properties.surface.ownership & OWNERSHIP_OWNED)
if (tileElement->AsSurface()->GetOwnership() & OWNERSHIP_OWNED)
landOwnership = STR_LAND_OWNED;
else if (tileElement->properties.surface.ownership & OWNERSHIP_AVAILABLE)
else if (tileElement->AsSurface()->GetOwnership() & OWNERSHIP_AVAILABLE)
landOwnership = STR_LAND_SALE;
else if (tileElement->properties.surface.ownership & OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)
else if (tileElement->AsSurface()->GetOwnership() & OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)
landOwnership = STR_CONSTRUCTION_RIGHTS_OWNED;
else if (tileElement->properties.surface.ownership & OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE)
else if (tileElement->AsSurface()->GetOwnership() & OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE)
landOwnership = STR_CONSTRUCTION_RIGHTS_SALE;
else
landOwnership = STR_TILE_INSPECTOR_LAND_NOT_OWNED_AND_NOT_AVAILABLE;
gfx_draw_string_left(dpi, STR_TILE_INSPECTOR_SURFACE_OWNERSHIP, &landOwnership, COLOUR_DARK_GREEN, x, y + 22);
// Water level
int32_t waterLevel = surface_get_water_height(tileElement);
uint32_t waterLevel = tileElement->AsSurface()->GetWaterHeight();
gfx_draw_string_left(dpi, STR_TILE_INSPECTOR_SURFACE_WATER_LEVEL, &waterLevel, COLOUR_DARK_GREEN, x, y + 33);
// Properties
@ -2015,18 +2015,19 @@ static void window_tile_inspector_paint(rct_window* w, rct_drawpixelinfo* dpi)
{
// Details
// Type
int16_t largeSceneryType = scenery_large_get_type(tileElement);
auto sceneryElement = tileElement->AsLargeScenery();
int16_t largeSceneryType = sceneryElement->GetEntryIndex();
gfx_draw_string_left(dpi, STR_TILE_INSPECTOR_LARGE_SCENERY_TYPE, &largeSceneryType, COLOUR_DARK_GREEN, x, y);
// Part ID
int16_t pieceID = scenery_large_get_sequence(tileElement);
int16_t pieceID = sceneryElement->GetSequenceIndex();
gfx_draw_string_left(dpi, STR_TILE_INSPECTOR_LARGE_SCENERY_PIECE_ID, &pieceID, COLOUR_DARK_GREEN, x, y + 11);
// Banner info
rct_scenery_entry* largeSceneryEntry = get_large_scenery_entry(scenery_large_get_type(tileElement));
rct_scenery_entry* largeSceneryEntry = get_large_scenery_entry(largeSceneryType);
if (largeSceneryEntry->large_scenery.scrolling_mode != 0xFF)
{
const BannerIndex bannerIndex = scenery_large_get_banner_id(tileElement);
const BannerIndex bannerIndex = sceneryElement->GetBannerIndex();
rct_string_id* string = &gBanners[bannerIndex].string_idx;
gfx_draw_string_left(dpi, STR_TILE_INSPECTOR_ENTRY_BANNER_TEXT, string, COLOUR_DARK_GREEN, x, y + 22);
}

View File

@ -1010,13 +1010,13 @@ static void repaint_scenery_tool_down(int16_t x, int16_t y, rct_widgetindex widg
gGameCommandErrorTitle = STR_CANT_REPAINT_THIS;
game_do_command(
grid_x, 1 | (gWindowSceneryPrimaryColour << 8), grid_y,
(tile_element->type & TILE_ELEMENT_DIRECTION_MASK) | (tile_element->base_height << 8),
GAME_COMMAND_SET_WALL_COLOUR, 0, gWindowScenerySecondaryColour | (gWindowSceneryTertiaryColour << 8));
tile_element->GetDirection() | (tile_element->base_height << 8), GAME_COMMAND_SET_WALL_COLOUR, 0,
gWindowScenerySecondaryColour | (gWindowSceneryTertiaryColour << 8));
break;
}
case VIEWPORT_INTERACTION_ITEM_LARGE_SCENERY:
{
rct_scenery_entry* scenery_entry = get_large_scenery_entry(scenery_large_get_type(tile_element));
rct_scenery_entry* scenery_entry = tile_element->AsLargeScenery()->GetEntry();
// If can't repaint
if (!(scenery_entry->large_scenery.flags & LARGE_SCENERY_FLAG_HAS_PRIMARY_COLOUR))
@ -1025,7 +1025,7 @@ static void repaint_scenery_tool_down(int16_t x, int16_t y, rct_widgetindex widg
gGameCommandErrorTitle = STR_CANT_REPAINT_THIS;
game_do_command(
grid_x, 1 | (tile_element->GetDirection() << 8), grid_y,
tile_element->base_height | (scenery_large_get_sequence(tile_element) << 8),
tile_element->base_height | (tile_element->AsLargeScenery()->GetSequenceIndex() << 8),
GAME_COMMAND_SET_LARGE_SCENERY_COLOUR, 0, gWindowSceneryPrimaryColour | (gWindowScenerySecondaryColour << 8));
break;
}
@ -1097,16 +1097,16 @@ static void scenery_eyedropper_tool_down(int16_t x, int16_t y, rct_widgetindex w
}
case VIEWPORT_INTERACTION_ITEM_LARGE_SCENERY:
{
int32_t entryIndex = scenery_large_get_type(tileElement);
int32_t entryIndex = tileElement->AsLargeScenery()->GetEntryIndex();
rct_scenery_entry* sceneryEntry = get_large_scenery_entry(entryIndex);
if (sceneryEntry != nullptr)
{
int32_t sceneryId = get_scenery_id_from_entry_index(OBJECT_TYPE_LARGE_SCENERY, entryIndex);
if (sceneryId != -1 && window_scenery_set_selected_item(sceneryId))
{
gWindowSceneryRotation = (get_current_rotation() + tile_element_get_direction(tileElement)) & 3;
gWindowSceneryPrimaryColour = scenery_large_get_primary_colour(tileElement);
gWindowScenerySecondaryColour = scenery_large_get_secondary_colour(tileElement);
gWindowSceneryRotation = (get_current_rotation() + tileElement->GetDirection()) & 3;
gWindowSceneryPrimaryColour = tileElement->AsLargeScenery()->GetPrimaryColour();
gWindowScenerySecondaryColour = tileElement->AsLargeScenery()->GetSecondaryColour();
gWindowSceneryEyedropperEnabled = false;
}
}
@ -1373,7 +1373,7 @@ static void sub_6E1F34(
}
gSceneryPlaceZ = 0;
uint16_t water_height = surface_get_water_height(tile_element);
uint16_t water_height = tile_element->AsSurface()->GetWaterHeight();
if (water_height != 0)
{
gSceneryPlaceZ = water_height * 16;

View File

@ -413,24 +413,24 @@ static void window_track_place_clear_provisional()
static int32_t window_track_place_get_base_z(int32_t x, int32_t y)
{
rct_tile_element* tileElement;
int32_t z;
uint32_t z;
tileElement = map_get_surface_element_at(x >> 5, y >> 5);
z = tileElement->base_height * 8;
// Increase Z above slope
if (tileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP)
if (tileElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP)
{
z += 16;
// Increase Z above double slope
if (tileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
if (tileElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
z += 16;
}
// Increase Z above water
if (surface_get_water_height(tileElement) > 0)
z = std::max(z, surface_get_water_height(tileElement) << 4);
if (tileElement->AsSurface()->GetWaterHeight() > 0)
z = std::max(z, tileElement->AsSurface()->GetWaterHeight() << 4);
return z + place_virtual_track(_trackDesign, PTD_OPERATION_GET_PLACE_Z, true, 0, x, y, z);
}

View File

@ -66,16 +66,16 @@ static void cheat_set_grass_length(int32_t length)
for (x = 0; x < MAXIMUM_MAP_SIZE_TECHNICAL; x++)
{
tileElement = map_get_surface_element_at(x, y);
if (!(tileElement->properties.surface.ownership & OWNERSHIP_OWNED))
if (!(tileElement->AsSurface()->GetOwnership() & OWNERSHIP_OWNED))
continue;
if (surface_get_terrain(tileElement) != TERRAIN_GRASS)
if (tileElement->AsSurface()->GetSurfaceStyle() != TERRAIN_GRASS)
continue;
if (surface_get_water_height(tileElement) > 0)
if (tileElement->AsSurface()->GetWaterHeight() > 0)
continue;
tileElement->properties.surface.grass_length = length;
tileElement->AsSurface()->SetGrassLength(length);
}
}
@ -461,7 +461,7 @@ static void cheat_own_all_land()
rct_tile_element* surfaceElement = map_get_surface_element_at(coords);
// Ignore already owned tiles.
if (surfaceElement->properties.surface.ownership & OWNERSHIP_OWNED)
if (surfaceElement->AsSurface()->GetOwnership() & OWNERSHIP_OWNED)
continue;
int32_t base_z = surfaceElement->base_height;
@ -470,7 +470,7 @@ static void cheat_own_all_land()
// only own tiles that were not set to 0
if (destOwnership != OWNERSHIP_UNOWNED)
{
surfaceElement->properties.surface.ownership |= destOwnership;
surfaceElement->AsSurface()->SetOwnership(destOwnership);
update_park_fences_around_tile(coords);
uint16_t baseHeight = surfaceElement->base_height * 8;
map_invalidate_tile(coords.x, coords.y, baseHeight, baseHeight + 16);
@ -486,7 +486,7 @@ static void cheat_own_all_land()
if (x != PEEP_SPAWN_UNDEFINED)
{
rct_tile_element* surfaceElement = map_get_surface_element_at({ x, y });
surfaceElement->properties.surface.ownership = OWNERSHIP_UNOWNED;
surfaceElement->AsSurface()->SetOwnership(OWNERSHIP_UNOWNED);
update_park_fences_around_tile({ x, y });
uint16_t baseHeight = surfaceElement->base_height * 8;
map_invalidate_tile(x, y, baseHeight, baseHeight + 16);

View File

@ -166,7 +166,7 @@ void setup_in_use_selection_flags()
Editor::SetSelectedObject(OBJECT_TYPE_WALLS, type, OBJECT_SELECTION_FLAG_SELECTED);
break;
case TILE_ELEMENT_TYPE_LARGE_SCENERY:
type = scenery_large_get_type(iter.element);
type = iter.element->AsLargeScenery()->GetEntryIndex();
assert(type < object_entry_group_counts[OBJECT_TYPE_LARGE_SCENERY]);
Editor::SetSelectedObject(OBJECT_TYPE_LARGE_SCENERY, type, OBJECT_SELECTION_FLAG_SELECTED);
break;

View File

@ -1084,7 +1084,8 @@ void game_fix_save_vars()
{
tileElement->base_height = 2;
tileElement->clearance_height = 2;
tileElement->properties.surface.slope = TILE_ELEMENT_SLOPE_FLAT;
tileElement->AsSurface()->SetSlope(0);
tileElement->AsSurface()->SetWaterHeight(0);
}
}
}

View File

@ -105,11 +105,11 @@ private:
rct_tile_element* footpathElement = nullptr;
if (tileElement != nullptr)
{
if (getGhostPath && tile_element_is_ghost(tileElement) == false)
if (getGhostPath && !tileElement->IsGhost())
{
while (!(tileElement++)->IsLastForTile())
{
if (tileElement->type != TILE_ELEMENT_TYPE_PATH && !tile_element_is_ghost(tileElement))
if (tileElement->type != TILE_ELEMENT_TYPE_PATH && !tileElement->IsGhost())
{
continue;
}
@ -132,7 +132,7 @@ private:
bool isNotOwnedByPark = (GetFlags() & GAME_COMMAND_FLAG_5);
bool moneyDisabled = (gParkFlags & PARK_FLAGS_NO_MONEY);
bool isGhost = (footpathElement == nullptr) || (tile_element_is_ghost(footpathElement));
bool isGhost = (footpathElement == nullptr) || (footpathElement->IsGhost());
if (isNotOwnedByPark || moneyDisabled || isGhost)
{

View File

@ -19,6 +19,7 @@
#include "../world/MapAnimation.h"
#include "../world/Park.h"
#include "../world/Sprite.h"
#include "../world/Surface.h"
#include "GameAction.h"
struct PlaceParkEntranceAction : public GameActionBase<GAME_COMMAND_PLACE_PARK_ENTRANCE, GameActionResult>
@ -176,8 +177,8 @@ public:
if (!(flags & GAME_COMMAND_FLAG_GHOST))
{
rct_tile_element* surfaceElement = map_get_surface_element_at(entranceLoc);
surfaceElement->properties.surface.ownership = 0;
SurfaceElement* surfaceElement = map_get_surface_element_at(entranceLoc)->AsSurface();
surfaceElement->SetOwnership(OWNERSHIP_UNOWNED);
}
rct_tile_element* newElement = tile_element_insert(entranceLoc.x / 32, entranceLoc.y / 32, zLow, 0xF);

View File

@ -16,6 +16,7 @@
#include "../management/Finance.h"
#include "../world/Footpath.h"
#include "../world/Park.h"
#include "../world/Surface.h"
#include "GameAction.h"
static int32_t _nextPeepSpawnIndex = 0;
@ -87,7 +88,7 @@ public:
{
return std::make_unique<GameActionResult>(GA_ERROR::UNKNOWN, STR_ERR_CANT_PLACE_PEEP_SPAWN_HERE, STR_NONE);
}
if (surfaceMapElement->properties.surface.ownership & 0xF0)
if (surfaceMapElement->AsSurface()->GetOwnership() != OWNERSHIP_UNOWNED)
{
return std::make_unique<GameActionResult>(
GA_ERROR::INVALID_PARAMETERS, STR_ERR_CANT_PLACE_PEEP_SPAWN_HERE, STR_ERR_MUST_BE_OUTSIDE_PARK_BOUNDARIES);

View File

@ -293,7 +293,7 @@ private:
int32_t x = it.x * 32, y = it.y * 32;
int32_t z = it.element->base_height * 8;
uint8_t rotation = tile_element_get_direction(it.element);
uint8_t rotation = it.element->GetDirection();
uint8_t type = track_element_get_type(it.element);
if (type != TRACK_ELEM_INVERTED_90_DEG_UP_TO_FLAT_QUARTER_LOOP)

View File

@ -1146,7 +1146,7 @@ static int32_t cc_remove_park_fences(
if (it.element->GetType() == TILE_ELEMENT_TYPE_SURFACE)
{
// Remove all park fence flags
it.element->properties.surface.ownership &= 0xF0;
it.element->AsSurface()->SetParkFences(0);
}
} while (tile_element_iterator_next(&it));

View File

@ -253,7 +253,7 @@ static void virtual_floor_get_tile_properties(
{
*outBelowGround = true;
}
else if (height < tileElement->base_height + 2 && tileElement->properties.surface.slope != 0)
else if (height < tileElement->base_height + 2 && tileElement->AsSurface()->GetSlope() != 0)
{
*outBelowGround = true;
*outOccupied = true;
@ -272,7 +272,7 @@ static void virtual_floor_get_tile_properties(
if (elementType == TILE_ELEMENT_TYPE_WALL || elementType == TILE_ELEMENT_TYPE_BANNER)
{
int32_t direction = tile_element_get_direction(tileElement);
int32_t direction = tileElement->GetDirection();
*outOccupiedEdges |= 1 << direction;
continue;
}

View File

@ -46,7 +46,7 @@ static void ride_entrance_exit_paint(
lightfx_add_3d_light_magic_from_drawing_tile(session->MapPosition, 0, 0, height + 45, LIGHTFX_LIGHT_TYPE_LANTERN_3);
}
switch (tile_element_get_direction(tile_element))
switch (tile_element->GetDirection())
{
case 0:
lightfx_add_3d_light_magic_from_drawing_tile(

View File

@ -225,8 +225,8 @@ void large_scenery_paint(paint_session* session, uint8_t direction, uint16_t hei
return;
}
session->InteractionType = VIEWPORT_INTERACTION_ITEM_LARGE_SCENERY;
uint32_t sequenceNum = scenery_large_get_sequence(tileElement);
rct_scenery_entry* entry = get_large_scenery_entry(scenery_large_get_type(tileElement));
uint32_t sequenceNum = tileElement->AsLargeScenery()->GetSequenceIndex();
rct_scenery_entry* entry = tileElement->AsLargeScenery()->GetEntry();
if (entry == nullptr)
return;
@ -234,7 +234,7 @@ void large_scenery_paint(paint_session* session, uint8_t direction, uint16_t hei
rct_large_scenery_tile* tile = &entry->large_scenery.tiles[sequenceNum];
uint32_t dword_F4387C = 0;
image_id |= SPRITE_ID_PALETTE_COLOUR_2(
scenery_large_get_primary_colour(tileElement), scenery_large_get_secondary_colour(tileElement));
tileElement->AsLargeScenery()->GetPrimaryColour(), tileElement->AsLargeScenery()->GetSecondaryColour());
LocationXYZ16 boxlength;
LocationXYZ16 boxoffset;
if (gTrackDesignSaveMode)
@ -285,7 +285,7 @@ void large_scenery_paint(paint_session* session, uint8_t direction, uint16_t hei
{
if (entry->large_scenery.tiles[1].x_offset != (int16_t)(uint16_t)0xFFFF)
{
int32_t sequenceDirection = (scenery_large_get_sequence(tileElement) - 1) & 3;
int32_t sequenceDirection = (tileElement->AsLargeScenery()->GetSequenceIndex() - 1) & 3;
if (sequenceDirection != direction)
{
large_scenery_paint_supports(session, direction, height, tileElement, dword_F4387C, tile);
@ -302,13 +302,13 @@ void large_scenery_paint(paint_session* session, uint8_t direction, uint16_t hei
// Draw sign text:
set_format_arg(0, uint32_t, 0);
set_format_arg(4, uint32_t, 0);
int32_t textColour = scenery_large_get_secondary_colour(tileElement);
int32_t textColour = tileElement->AsLargeScenery()->GetSecondaryColour();
if (dword_F4387C)
{
textColour = COLOUR_GREY;
}
textColour = (textColour << 19) | IMAGE_TYPE_REMAP;
BannerIndex bannerIndex = scenery_large_get_banner_id(tileElement);
BannerIndex bannerIndex = tileElement->AsLargeScenery()->GetBannerIndex();
rct_banner* banner = &gBanners[bannerIndex];
rct_string_id stringId = banner->string_idx;
if (banner->flags & BANNER_FLAG_LINKED_TO_RIDE)
@ -405,7 +405,7 @@ void large_scenery_paint(paint_session* session, uint8_t direction, uint16_t hei
large_scenery_paint_supports(session, direction, height, tileElement, dword_F4387C, tile);
return;
}
uint8_t sequenceDirection2 = (scenery_large_get_sequence(tileElement) - 1) & 3;
uint8_t sequenceDirection2 = (tileElement->AsLargeScenery()->GetSequenceIndex() - 1) & 3;
if (sequenceDirection2 != direction)
{
large_scenery_paint_supports(session, direction, height, tileElement, dword_F4387C, tile);
@ -414,7 +414,7 @@ void large_scenery_paint(paint_session* session, uint8_t direction, uint16_t hei
// Draw scrolling text:
set_format_arg(0, uint32_t, 0);
set_format_arg(4, uint32_t, 0);
uint8_t textColour = scenery_large_get_secondary_colour(tileElement);
uint8_t textColour = tileElement->AsLargeScenery()->GetSecondaryColour();
if (dword_F4387C)
{
textColour = COLOUR_GREY;
@ -425,7 +425,7 @@ void large_scenery_paint(paint_session* session, uint8_t direction, uint16_t hei
}
// 6B809A:
set_format_arg(7, uint8_t, textColour);
BannerIndex bannerIndex = scenery_large_get_banner_id(tileElement);
BannerIndex bannerIndex = tileElement->AsLargeScenery()->GetBannerIndex();
uint16_t scrollMode = entry->large_scenery.scrolling_mode + ((direction + 1) & 0x3);
rct_banner* banner = &gBanners[bannerIndex];
set_format_arg(0, rct_string_id, banner->string_idx);

View File

@ -860,15 +860,14 @@ void path_paint(paint_session* session, uint16_t height, const rct_tile_element*
{
// Diagonal path
if ((surface->properties.surface.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK)
!= byte_98D800[footpath_element_get_slope_direction(tile_element)])
if (surface->AsSurface()->GetSlope() != byte_98D800[footpath_element_get_slope_direction(tile_element)])
{
word_F3F038 = true;
}
}
else
{
if (surface->properties.surface.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK)
if (surface->AsSurface()->GetSlope() != TILE_ELEMENT_SLOPE_FLAT)
{
word_F3F038 = true;
}

View File

@ -507,7 +507,7 @@ static uint32_t get_tunnel_image(uint8_t index, uint8_t type)
static uint8_t viewport_surface_paint_setup_get_relative_slope(const rct_tile_element* tileElement, int32_t rotation)
{
const uint8_t slope = tileElement->properties.surface.slope;
const uint8_t slope = tileElement->AsSurface()->GetSlope();
const uint8_t slopeHeight = slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT;
uint16_t slopeCorners = (slope & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP) << rotation;
slopeCorners = ((slopeCorners >> 4) | slopeCorners) & 0x0F;
@ -691,7 +691,7 @@ static void viewport_surface_draw_tile_side_bottom(
if (isWater)
{
uint8_t waterHeight = surface_get_water_height(neighbour.tile_element);
uint8_t waterHeight = neighbour.tile_element->AsSurface()->GetWaterHeight();
if (waterHeight == height && !neighbourIsClippedAway)
{
// Don't draw the edge when the neighbour's water level is the same
@ -853,7 +853,7 @@ static void viewport_surface_draw_tile_side_top(
if (!is_csg_loaded() && terrain >= TERRAIN_EDGE_RCT2_COUNT)
terrain = TERRAIN_EDGE_ROCK;
int16_t al, ah, cl, ch, dl = 0, dh;
int16_t al, ah, cl, ch, dl = 0, waterHeight;
sLocationXY8 offset = { 0, 0 };
sLocationXY8 bounds = { 0, 0 };
@ -899,8 +899,8 @@ static void viewport_surface_draw_tile_side_top(
{
if (isWater)
{
dh = surface_get_water_height(neighbour.tile_element);
if (dl == dh)
waterHeight = neighbour.tile_element->AsSurface()->GetWaterHeight();
if (dl == waterHeight)
{
return;
}
@ -1019,7 +1019,7 @@ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, c
const uint16_t zoomLevel = dpi->zoom_level;
const uint8_t rotation = session->CurrentRotation;
const uint32_t terrain_type = surface_get_terrain(tileElement);
const uint32_t terrain_type = tileElement->AsSurface()->GetSurfaceStyle();
const uint8_t surfaceShape = viewport_surface_paint_setup_get_relative_slope(tileElement, rotation);
const LocationXY16& base = session->SpritePosition;
const corner_height& cornerHeights = corner_heights[surfaceShape];
@ -1068,7 +1068,7 @@ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, c
descriptor.tile_coords = { position.x / 32, position.y / 32 };
descriptor.tile_element = surfaceElement;
descriptor.terrain = surface_get_terrain(surfaceElement);
descriptor.terrain = surfaceElement->AsSurface()->GetSurfaceStyle();
descriptor.slope = surfaceSlope;
descriptor.corner_heights.top = baseHeight + ch.top;
descriptor.corner_heights.right = baseHeight + ch.right;
@ -1105,15 +1105,15 @@ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, c
const bool showGridlines = (gCurrentViewportFlags & VIEWPORT_FLAG_GRIDLINES);
int32_t branch = -1;
if ((tileElement->properties.surface.terrain & 0xE0) == 0)
if (tileElement->AsSurface()->GetSurfaceStyle() == TERRAIN_GRASS)
{
if (tile_element_get_direction(tileElement) == 0)
if (tileElement->GetDirection() == 0)
{
if (zoomLevel == 0)
{
if ((gCurrentViewportFlags & (VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_UNDERGROUND_INSIDE)) == 0)
{
branch = tileElement->properties.surface.grass_length & 0x7;
branch = tileElement->AsSurface()->GetGrassLength() & 0x7;
}
}
}
@ -1235,12 +1235,12 @@ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, c
if (gCurrentViewportFlags & VIEWPORT_FLAG_LAND_OWNERSHIP)
{
// loc_660E9A:
if (tileElement->properties.surface.ownership & OWNERSHIP_OWNED)
if (tileElement->AsSurface()->GetOwnership() & OWNERSHIP_OWNED)
{
assert(surfaceShape < Util::CountOf(byte_97B444));
paint_attach_to_previous_ps(session, SPR_TERRAIN_SELECTION_SQUARE + byte_97B444[surfaceShape], 0, 0);
}
else if (tileElement->properties.surface.ownership & OWNERSHIP_AVAILABLE)
else if (tileElement->AsSurface()->GetOwnership() & OWNERSHIP_AVAILABLE)
{
const LocationXY16& pos = session->MapPosition;
const int32_t height2 = (tile_element_height(pos.x + 16, pos.y + 16) & 0xFFFF) + 3;
@ -1251,14 +1251,14 @@ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, c
}
if (gCurrentViewportFlags & VIEWPORT_FLAG_CONSTRUCTION_RIGHTS
&& !(tileElement->properties.surface.ownership & OWNERSHIP_OWNED))
&& !(tileElement->AsSurface()->GetOwnership() & OWNERSHIP_OWNED))
{
if (tileElement->properties.surface.ownership & OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)
if (tileElement->AsSurface()->GetOwnership() & OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)
{
assert(surfaceShape < Util::CountOf(byte_97B444));
paint_attach_to_previous_ps(session, SPR_TERRAIN_SELECTION_DOTTED + byte_97B444[surfaceShape], 0, 0);
}
else if (tileElement->properties.surface.ownership & OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE)
else if (tileElement->AsSurface()->GetOwnership() & OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE)
{
const LocationXY16& pos = session->MapPosition;
const int32_t height2 = tile_element_height(pos.x + 16, pos.y + 16) & 0xFFFF;
@ -1314,9 +1314,9 @@ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, c
int32_t local_surfaceShape = surfaceShape;
int32_t local_height = height;
// Water tool
if (surface_get_water_height(tileElement) > 0)
if (tileElement->AsSurface()->GetWaterHeight() > 0)
{
int32_t waterHeight = surface_get_water_height(tileElement) * 16;
int32_t waterHeight = tileElement->AsSurface()->GetWaterHeight() * 16;
if (waterHeight > height)
{
local_height += 16;
@ -1393,14 +1393,10 @@ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, c
if (!(gCurrentViewportFlags & VIEWPORT_FLAG_HIDE_VERTICAL))
{
// loc_66122C:
const uint8_t al_edgeStyle = tileElement->properties.surface.slope & TILE_ELEMENT_SURFACE_EDGE_STYLE_MASK;
const uint8_t di_type = tileElement->type & 0x80;
const uint32_t eax = al_edgeStyle + di_type * 2;
if (eax != 32 && eax != 0 && eax != 96 && eax != 64)
const uint32_t edgeStyle = tileElement->AsSurface()->GetEdgeStyle();
if (edgeStyle >= TERRAIN_EDGE_COUNT)
{
log_verbose("eax: %d", eax);
log_verbose("edgeStyle: %d", edgeStyle);
}
tunnel_entry backupLeftTunnels[TUNNEL_MAX_COUNT];
@ -1410,25 +1406,25 @@ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, c
memcpy(backupRightTunnels, session->RightTunnels, sizeof(tunnel_entry) * TUNNEL_MAX_COUNT);
viewport_surface_draw_land_side_top(
session, EDGE_TOPLEFT, height / 16, eax / 32, tileDescriptors[0], tileDescriptors[3]);
session, EDGE_TOPLEFT, height / 16, edgeStyle, tileDescriptors[0], tileDescriptors[3]);
viewport_surface_draw_land_side_top(
session, EDGE_TOPRIGHT, height / 16, eax / 32, tileDescriptors[0], tileDescriptors[4]);
session, EDGE_TOPRIGHT, height / 16, edgeStyle, tileDescriptors[0], tileDescriptors[4]);
viewport_surface_draw_land_side_bottom(
session, EDGE_BOTTOMLEFT, height / 16, eax / 32, tileDescriptors[0], tileDescriptors[1]);
session, EDGE_BOTTOMLEFT, height / 16, edgeStyle, tileDescriptors[0], tileDescriptors[1]);
viewport_surface_draw_land_side_bottom(
session, EDGE_BOTTOMRIGHT, height / 16, eax / 32, tileDescriptors[0], tileDescriptors[2]);
session, EDGE_BOTTOMRIGHT, height / 16, edgeStyle, tileDescriptors[0], tileDescriptors[2]);
memcpy(session->LeftTunnels, backupLeftTunnels, sizeof(tunnel_entry) * TUNNEL_MAX_COUNT);
memcpy(session->RightTunnels, backupRightTunnels, sizeof(tunnel_entry) * TUNNEL_MAX_COUNT);
}
if (surface_get_water_height(tileElement) > 0)
if (tileElement->AsSurface()->GetWaterHeight() > 0)
{
// loc_6615A9: (water height)
session->InteractionType = VIEWPORT_INTERACTION_ITEM_WATER;
const uint16_t localHeight = height + 16;
const uint16_t waterHeight = surface_get_water_height(tileElement) * 16;
const uint16_t waterHeight = tileElement->AsSurface()->GetWaterHeight() * 16;
if (!gTrackDesignSaveMode)
{
@ -1447,30 +1443,27 @@ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, c
paint_attach_to_previous_ps(session, SPR_WATER_OVERLAY + image_offset, 0, 0);
// This wasn't in the original, but the code depended on globals that were only set in a different conditional
const uint8_t al_edgeStyle = tileElement->properties.surface.slope & TILE_ELEMENT_SURFACE_EDGE_STYLE_MASK;
const uint8_t di_type = tileElement->type & 0x80;
const uint32_t eax = al_edgeStyle + di_type * 2;
assert(eax % 32 == 0);
const uint32_t edgeStyle = tileElement->AsSurface()->GetEdgeStyle();
// end new code
viewport_surface_draw_water_side_top(
session, EDGE_TOPLEFT, waterHeight / 16, eax / 32, tileDescriptors[0], tileDescriptors[3]);
session, EDGE_TOPLEFT, waterHeight / 16, edgeStyle, tileDescriptors[0], tileDescriptors[3]);
viewport_surface_draw_water_side_top(
session, EDGE_TOPRIGHT, waterHeight / 16, eax / 32, tileDescriptors[0], tileDescriptors[4]);
session, EDGE_TOPRIGHT, waterHeight / 16, edgeStyle, tileDescriptors[0], tileDescriptors[4]);
viewport_surface_draw_water_side_bottom(
session, EDGE_BOTTOMLEFT, waterHeight / 16, eax / 32, tileDescriptors[0], tileDescriptors[1]);
session, EDGE_BOTTOMLEFT, waterHeight / 16, edgeStyle, tileDescriptors[0], tileDescriptors[1]);
viewport_surface_draw_water_side_bottom(
session, EDGE_BOTTOMRIGHT, waterHeight / 16, eax / 32, tileDescriptors[0], tileDescriptors[2]);
session, EDGE_BOTTOMRIGHT, waterHeight / 16, edgeStyle, tileDescriptors[0], tileDescriptors[2]);
}
}
if ((tileElement->properties.surface.ownership & 0x0F) && !gTrackDesignSaveMode)
if ((tileElement->AsSurface()->GetParkFences()) && !gTrackDesignSaveMode)
{
// Owned land boundary fences
session->InteractionType = VIEWPORT_INTERACTION_ITEM_PARK;
registers regs = {};
regs.al = tileElement->properties.surface.ownership & 0x0F;
regs.al = tileElement->AsSurface()->GetParkFences();
regs.ax = regs.ax << rotation;
regs.ah = regs.al >> 4;

View File

@ -216,9 +216,9 @@ static void sub_68B3FB(paint_session* session, int32_t x, int32_t y)
element--;
if (element->GetType() == TILE_ELEMENT_TYPE_SURFACE && (surface_get_water_height(element) > 0))
if (element->GetType() == TILE_ELEMENT_TYPE_SURFACE && (element->AsSurface()->GetWaterHeight() > 0))
{
max_height = surface_get_water_height(element) * 2;
max_height = element->AsSurface()->GetWaterHeight() * 2;
}
max_height *= 8;
@ -248,7 +248,7 @@ static void sub_68B3FB(paint_session* session, int32_t x, int32_t y)
if ((gCurrentViewportFlags & VIEWPORT_FLAG_CLIP_VIEW) && (tile_element->base_height > gClipHeight))
continue;
int32_t direction = tile_element_get_direction_with_offset(tile_element, rotation);
int32_t direction = tile_element->GetDirectionWithOffset(rotation);
int32_t height = tile_element->base_height * 8;
// If we are on a new height level, look through elements on the

View File

@ -3463,7 +3463,7 @@ static void peep_update_ride_leave_entrance_spiral_slide(rct_peep* peep, Ride* r
rct_tile_element* tile_element = ride_get_station_start_track_element(ride, peep->current_ride_station);
uint8_t direction_track = (tile_element == nullptr ? 0 : tile_element_get_direction(tile_element));
uint8_t direction_track = (tile_element == nullptr ? 0 : tile_element->GetDirection());
peep->var_37 = (entrance_loc.direction << 2) | (direction_track << 4);
@ -3519,7 +3519,7 @@ static void peep_update_ride_leave_entrance_waypoints(rct_peep* peep, Ride* ride
rct_tile_element* tile_element = ride_get_station_start_track_element(ride, peep->current_ride_station);
uint8_t direction_track = (tile_element == nullptr ? 0 : tile_element_get_direction(tile_element));
uint8_t direction_track = (tile_element == nullptr ? 0 : tile_element->GetDirection());
auto vehicle = GET_VEHICLE(ride->vehicles[peep->current_train]);
auto ride_entry = get_ride_entry(vehicle->ride_subtype);
@ -4125,7 +4125,7 @@ void rct_peep::UpdateRideLeaveVehicle()
rct_tile_element* trackElement = ride_get_station_start_track_element(ride, current_ride_station);
uint8_t station_direction = (trackElement == nullptr ? 0 : tile_element_get_direction(trackElement));
uint8_t station_direction = (trackElement == nullptr ? 0 : trackElement->GetDirection());
vehicle = GET_VEHICLE(ride->vehicles[current_train]);
@ -5253,7 +5253,7 @@ void rct_peep::UpdateWalking()
{
rct_tile_element* tile_element = map_get_surface_element_at({ next_x, next_y });
int32_t water_height = surface_get_water_height(tile_element);
int32_t water_height = tile_element->AsSurface()->GetWaterHeight();
if (water_height)
{
Invalidate();
@ -6187,7 +6187,7 @@ static bool peep_should_watch_ride(rct_tile_element* tileElement)
// as that may lead to a desync.
if (network_get_mode() != NETWORK_MODE_NONE)
{
if (tile_element_is_ghost(tileElement))
if (tileElement->IsGhost())
return false;
}
@ -6292,12 +6292,12 @@ static bool peep_find_ride_to_look_at(rct_peep* peep, uint8_t edge, uint8_t* rid
// as that may lead to a desync.
if (network_get_mode() != NETWORK_MODE_NONE)
{
if (tile_element_is_ghost(tileElement))
if (tileElement->IsGhost())
continue;
}
if (tileElement->GetType() != TILE_ELEMENT_TYPE_WALL)
continue;
if (tile_element_get_direction(tileElement) != edge)
if (tileElement->GetDirection() != edge)
continue;
auto wallEntry = get_wall_entry(tileElement->properties.wall.type);
if (wallEntry == nullptr || (wallEntry->wall.flags2 & WALL_SCENERY_2_IS_OPAQUE))
@ -6326,12 +6326,12 @@ static bool peep_find_ride_to_look_at(rct_peep* peep, uint8_t edge, uint8_t* rid
// as that may lead to a desync.
if (network_get_mode() != NETWORK_MODE_NONE)
{
if (tile_element_is_ghost(tileElement))
if (tileElement->IsGhost())
continue;
}
if (tileElement->GetType() != TILE_ELEMENT_TYPE_WALL)
continue;
if (tile_element_get_direction_with_offset(tileElement, 2) != edge)
if (tileElement->GetDirectionWithOffset(2) != edge)
continue;
auto wallEntry = get_wall_entry(tileElement->properties.wall.type);
if (wallEntry == nullptr || (wallEntry->wall.flags2 & WALL_SCENERY_2_IS_OPAQUE))
@ -6353,7 +6353,7 @@ static bool peep_find_ride_to_look_at(rct_peep* peep, uint8_t edge, uint8_t* rid
// as that may lead to a desync.
if (network_get_mode() != NETWORK_MODE_NONE)
{
if (tile_element_is_ghost(tileElement))
if (tileElement->IsGhost())
continue;
}
@ -6372,8 +6372,7 @@ static bool peep_find_ride_to_look_at(rct_peep* peep, uint8_t edge, uint8_t* rid
if (tileElement->GetType() == TILE_ELEMENT_TYPE_LARGE_SCENERY)
{
if (!(get_large_scenery_entry(scenery_large_get_type(tileElement))->large_scenery.flags
& LARGE_SCENERY_FLAG_PHOTOGENIC))
if (!(tileElement->AsLargeScenery()->GetEntry()->large_scenery.flags & LARGE_SCENERY_FLAG_PHOTOGENIC))
{
continue;
}
@ -6398,7 +6397,7 @@ static bool peep_find_ride_to_look_at(rct_peep* peep, uint8_t edge, uint8_t* rid
// as that may lead to a desync.
if (network_get_mode() != NETWORK_MODE_NONE)
{
if (tile_element_is_ghost(tileElement))
if (tileElement->IsGhost())
continue;
}
if (tileElement->clearance_height + 1 < peep->next_z)
@ -6439,12 +6438,12 @@ static bool peep_find_ride_to_look_at(rct_peep* peep, uint8_t edge, uint8_t* rid
// as that may lead to a desync.
if (network_get_mode() != NETWORK_MODE_NONE)
{
if (tile_element_is_ghost(tileElement))
if (tileElement->IsGhost())
continue;
}
if (tileElement->GetType() != TILE_ELEMENT_TYPE_WALL)
continue;
if (tile_element_get_direction_with_offset(tileElement, 2) != edge)
if (tileElement->GetDirectionWithOffset(2) != edge)
continue;
auto wallEntry = get_wall_entry(tileElement->properties.wall.type);
if (wallEntry == nullptr || (wallEntry->wall.flags2 & WALL_SCENERY_2_IS_OPAQUE))
@ -6465,7 +6464,7 @@ static bool peep_find_ride_to_look_at(rct_peep* peep, uint8_t edge, uint8_t* rid
// as that may lead to a desync.
if (network_get_mode() != NETWORK_MODE_NONE)
{
if (tile_element_is_ghost(tileElement))
if (tileElement->IsGhost())
continue;
}
if (tileElement->clearance_height + 1 < peep->next_z)
@ -6483,7 +6482,7 @@ static bool peep_find_ride_to_look_at(rct_peep* peep, uint8_t edge, uint8_t* rid
if (tileElement->GetType() == TILE_ELEMENT_TYPE_LARGE_SCENERY)
{
auto sceneryEntry = get_large_scenery_entry(scenery_large_get_type(tileElement));
auto sceneryEntry = tileElement->AsLargeScenery()->GetEntry();
if (!(sceneryEntry == nullptr || sceneryEntry->large_scenery.flags & LARGE_SCENERY_FLAG_PHOTOGENIC))
{
continue;
@ -6509,7 +6508,7 @@ static bool peep_find_ride_to_look_at(rct_peep* peep, uint8_t edge, uint8_t* rid
// as that may lead to a desync.
if (network_get_mode() != NETWORK_MODE_NONE)
{
if (tile_element_is_ghost(tileElement))
if (tileElement->IsGhost())
continue;
}
if (tileElement->clearance_height + 1 < peep->next_z)
@ -6550,12 +6549,12 @@ static bool peep_find_ride_to_look_at(rct_peep* peep, uint8_t edge, uint8_t* rid
// as that may lead to a desync.
if (network_get_mode() != NETWORK_MODE_NONE)
{
if (tile_element_is_ghost(tileElement))
if (tileElement->IsGhost())
continue;
}
if (tileElement->GetType() != TILE_ELEMENT_TYPE_WALL)
continue;
if (tile_element_get_direction_with_offset(tileElement, 2) != edge)
if (tileElement->GetDirectionWithOffset(2) != edge)
continue;
auto wallEntry = get_wall_entry(tileElement->properties.wall.type);
if (wallEntry == nullptr || (wallEntry->wall.flags2 & WALL_SCENERY_2_IS_OPAQUE))
@ -6576,7 +6575,7 @@ static bool peep_find_ride_to_look_at(rct_peep* peep, uint8_t edge, uint8_t* rid
// as that may lead to a desync.
if (network_get_mode() != NETWORK_MODE_NONE)
{
if (tile_element_is_ghost(tileElement))
if (tileElement->IsGhost())
continue;
}
if (tileElement->clearance_height + 1 < peep->next_z)
@ -6594,8 +6593,7 @@ static bool peep_find_ride_to_look_at(rct_peep* peep, uint8_t edge, uint8_t* rid
if (tileElement->GetType() == TILE_ELEMENT_TYPE_LARGE_SCENERY)
{
if (!(get_large_scenery_entry(scenery_large_get_type(tileElement))->large_scenery.flags
& LARGE_SCENERY_FLAG_PHOTOGENIC))
if (!(tileElement->AsLargeScenery()->GetEntry()->large_scenery.flags & LARGE_SCENERY_FLAG_PHOTOGENIC))
{
continue;
}

View File

@ -316,7 +316,7 @@ static uint8_t footpath_element_dest_in_dir(
switch (tileElement->properties.entrance.type)
{
case ENTRANCE_TYPE_RIDE_ENTRANCE:
direction = tile_element_get_direction(tileElement);
direction = tileElement->GetDirection();
if (direction == chosenDirection)
{
*outRideIndex = tileElement->properties.entrance.ride_index;
@ -324,7 +324,7 @@ static uint8_t footpath_element_dest_in_dir(
}
break;
case ENTRANCE_TYPE_RIDE_EXIT:
direction = tile_element_get_direction(tileElement);
direction = tileElement->GetDirection();
if (direction == chosenDirection)
{
*outRideIndex = tileElement->properties.entrance.ride_index;
@ -681,7 +681,7 @@ static void peep_pathfind_heuristic_search(
* For mechanics heading for the ride entrance
* (in the case when the station has no exit),
* the goal is the ride entrance tile. */
direction = tile_element_get_direction(tileElement);
direction = tileElement->GetDirection();
if (direction == test_edge)
{
/* The rideIndex will be useful for
@ -701,7 +701,7 @@ static void peep_pathfind_heuristic_search(
case ENTRANCE_TYPE_RIDE_EXIT:
/* For mechanics heading for the ride exit, the
* goal is the ride exit tile. */
direction = tile_element_get_direction(tileElement);
direction = tileElement->GetDirection();
if (direction == test_edge)
{
searchResult = PATH_SEARCH_RIDE_EXIT;
@ -1749,7 +1749,7 @@ static void get_ride_queue_end(TileCoordsXYZ& loc)
if (!found)
return;
uint8_t direction = tile_element_get_direction_with_offset(tileElement, 2);
uint8_t direction = tileElement->GetDirectionWithOffset(2);
rct_tile_element* lastPathElement = nullptr;
rct_tile_element* firstPathElement = nullptr;

View File

@ -1021,7 +1021,7 @@ void rct_peep::UpdateFalling()
// If a path check if we are on it
if (tile_element->GetType() == TILE_ELEMENT_TYPE_PATH)
{
int32_t height = map_height_from_slope(x, y, tile_element->properties.surface.slope)
int32_t height = map_height_from_slope(x, y, tile_element->properties.path.type)
+ tile_element->base_height * 8;
if (height < z - 1 || height > z + 4)
@ -1034,9 +1034,9 @@ void rct_peep::UpdateFalling()
else if (tile_element->GetType() == TILE_ELEMENT_TYPE_SURFACE)
{
// If the surface is water check to see if we could be drowning
if (surface_get_water_height(tile_element) > 0)
if (tile_element->AsSurface()->GetWaterHeight() > 0)
{
int32_t height = surface_get_water_height(tile_element) * 16;
int32_t height = tile_element->AsSurface()->GetWaterHeight() * 16;
if (height - 4 >= z && height < z + 20)
{
@ -2544,7 +2544,7 @@ static void peep_interact_with_entrance(
return;
}
uint8_t entranceDirection = tile_element_get_direction(tile_element);
uint8_t entranceDirection = tile_element->GetDirection();
if (entranceDirection != peep->direction)
{
if ((entranceDirection ^ (1 << 1)) != peep->direction)
@ -3243,7 +3243,7 @@ void rct_peep::PerformNextAction(uint8_t& pathing_result, rct_tile_element*& til
return;
}
int16_t water_height = surface_get_water_height(tileElement);
int16_t water_height = tileElement->AsSurface()->GetWaterHeight();
if (water_height)
{
peep_return_to_centre_of_tile(this);

View File

@ -967,11 +967,10 @@ static uint8_t staff_handyman_direction_to_uncut_grass(rct_peep* peep, uint8_t v
if (peep->GetNextIsSloped())
{
if ((tileElement->properties.surface.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK)
!= byte_98D800[peep->GetNextDirection()])
if (tileElement->AsSurface()->GetSlope() != byte_98D800[peep->GetNextDirection()])
return 0xFF;
}
else if ((tileElement->properties.surface.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK) != 0)
else if (tileElement->AsSurface()->GetSlope() != TILE_ELEMENT_SLOPE_FLAT)
return 0xFF;
}
@ -993,13 +992,13 @@ static uint8_t staff_handyman_direction_to_uncut_grass(rct_peep* peep, uint8_t v
rct_tile_element* tileElement = map_get_surface_element_at(chosenTile);
if (surface_get_terrain(tileElement) != 0)
if (tileElement->AsSurface()->GetSurfaceStyle() != TERRAIN_GRASS)
continue;
if (abs(tileElement->base_height - peep->next_z) > 2)
continue;
if ((tileElement->properties.surface.grass_length & 0x7) < GRASS_LENGTH_CLEAR_1)
if ((tileElement->AsSurface()->GetGrassLength() & 0x7) < GRASS_LENGTH_CLEAR_1)
continue;
return chosenDirection;
@ -1680,9 +1679,9 @@ void rct_peep::UpdateMowing()
for (; (tile_element->GetType() != TILE_ELEMENT_TYPE_SURFACE); tile_element++)
;
if ((tile_element->properties.surface.terrain & TILE_ELEMENT_SURFACE_TERRAIN_MASK) == (TERRAIN_GRASS << 5))
if (tile_element->AsSurface()->GetSurfaceStyle() == TERRAIN_GRASS)
{
tile_element->properties.surface.grass_length = GRASS_LENGTH_MOWED;
tile_element->AsSurface()->SetGrassLength(GRASS_LENGTH_MOWED);
map_invalidate_tile_zoom0(next_x, next_y, tile_element->base_height * 8, tile_element->base_height * 8 + 16);
}
staff_lawns_mown++;
@ -1952,7 +1951,7 @@ void rct_peep::UpdateHeadingToInspect()
}
}
direction = tile_element_get_direction(rideEntranceExitElement);
direction = rideEntranceExitElement->GetDirection();
int32_t destX = next_x + 16 + word_981D6C[direction].x * 53;
int32_t destY = next_y + 16 + word_981D6C[direction].y * 53;
@ -2070,7 +2069,7 @@ void rct_peep::UpdateAnswering()
}
}
direction = tile_element_get_direction(rideEntranceExitElement);
direction = rideEntranceExitElement->GetDirection();
int32_t destX = next_x + 16 + word_981D6C[direction].x * 53;
int32_t destY = next_y + 16 + word_981D6C[direction].y * 53;
@ -2266,10 +2265,10 @@ static int32_t peep_update_patrolling_find_grass(rct_peep* peep)
rct_tile_element* tile_element = map_get_surface_element_at({ peep->next_x, peep->next_y });
if ((tile_element->properties.surface.terrain & TILE_ELEMENT_SURFACE_TERRAIN_MASK) != TERRAIN_GRASS)
if ((tile_element->AsSurface()->GetSurfaceStyle()) != TERRAIN_GRASS)
return 0;
if ((tile_element->properties.surface.grass_length & 0x7) < GRASS_LENGTH_CLEAR_1)
if ((tile_element->AsSurface()->GetGrassLength() & 0x7) < GRASS_LENGTH_CLEAR_1)
return 0;
peep->SetState(PEEP_STATE_MOWING);
@ -2368,7 +2367,7 @@ void rct_peep::UpdatePatrolling()
if (tile_element != nullptr)
{
int32_t water_height = surface_get_water_height(tile_element);
int32_t water_height = tile_element->AsSurface()->GetWaterHeight();
if (water_height)
{
Invalidate();
@ -2805,7 +2804,7 @@ bool rct_peep::UpdateFixingMoveToStationEnd(bool firstRun, Ride* ride)
return false;
}
int32_t trackDirection = tile_element_get_direction(tileElement);
int32_t trackDirection = tileElement->GetDirection();
CoordsXY offset = _StationFixingOffsets[trackDirection];
stationX += 16 + offset.x;
@ -2911,7 +2910,7 @@ bool rct_peep::UpdateFixingMoveToStationStart(bool firstRun, Ride* ride)
input.y = trackBeginEnd.begin_y;
input.element = trackBeginEnd.begin_element;
stationDirection = tile_element_get_direction(trackBeginEnd.begin_element);
stationDirection = trackBeginEnd.begin_element->GetDirection();
continue;
}

View File

@ -493,7 +493,7 @@ private:
AddEntryForSmallScenery(tileElement->AsSmallScenery()->GetEntryIndex());
break;
case TILE_ELEMENT_TYPE_LARGE_SCENERY:
AddEntryForLargeScenery(scenery_large_get_type(tileElement));
AddEntryForLargeScenery(tileElement->AsLargeScenery()->GetEntryIndex());
break;
case TILE_ELEMENT_TYPE_WALL:
{
@ -2410,10 +2410,11 @@ private:
nextFreeTileElement->flags = TILE_ELEMENT_FLAG_LAST_TILE;
nextFreeTileElement->base_height = 2;
nextFreeTileElement->clearance_height = 0;
nextFreeTileElement->properties.surface.slope = TILE_ELEMENT_SLOPE_FLAT;
nextFreeTileElement->properties.surface.terrain = 0;
nextFreeTileElement->properties.surface.grass_length = GRASS_LENGTH_CLEAR_0;
nextFreeTileElement->properties.surface.ownership = 0;
nextFreeTileElement->AsSurface()->SetSlope(TILE_ELEMENT_SLOPE_FLAT);
nextFreeTileElement->AsSurface()->SetSurfaceStyle(TERRAIN_GRASS);
nextFreeTileElement->AsSurface()->SetEdgeStyle(TERRAIN_EDGE_ROCK);
nextFreeTileElement->AsSurface()->SetGrassLength(GRASS_LENGTH_CLEAR_0);
nextFreeTileElement->AsSurface()->SetOwnership(OWNERSHIP_UNOWNED);
*tilePointer++ = nextFreeTileElement++;
}
}
@ -2425,10 +2426,11 @@ private:
nextFreeTileElement->flags = TILE_ELEMENT_FLAG_LAST_TILE;
nextFreeTileElement->base_height = 2;
nextFreeTileElement->clearance_height = 0;
nextFreeTileElement->properties.surface.slope = TILE_ELEMENT_SLOPE_FLAT;
nextFreeTileElement->properties.surface.terrain = 0;
nextFreeTileElement->properties.surface.grass_length = GRASS_LENGTH_CLEAR_0;
nextFreeTileElement->properties.surface.ownership = 0;
nextFreeTileElement->AsSurface()->SetSlope(TILE_ELEMENT_SLOPE_FLAT);
nextFreeTileElement->AsSurface()->SetSurfaceStyle(TERRAIN_GRASS);
nextFreeTileElement->AsSurface()->SetEdgeStyle(TERRAIN_EDGE_ROCK);
nextFreeTileElement->AsSurface()->SetGrassLength(GRASS_LENGTH_CLEAR_0);
nextFreeTileElement->AsSurface()->SetOwnership(OWNERSHIP_UNOWNED);
*tilePointer++ = nextFreeTileElement++;
}
@ -2467,11 +2469,11 @@ private:
}
break;
case TILE_ELEMENT_TYPE_LARGE_SCENERY:
colour = RCT1::GetColour(scenery_large_get_primary_colour(tileElement));
scenery_large_set_primary_colour(tileElement, colour);
colour = RCT1::GetColour(tileElement->AsLargeScenery()->GetPrimaryColour());
tileElement->AsLargeScenery()->SetPrimaryColour(colour);
colour = RCT1::GetColour(scenery_large_get_secondary_colour(tileElement));
scenery_large_set_secondary_colour(tileElement, colour);
colour = RCT1::GetColour(tileElement->AsLargeScenery()->GetSecondaryColour());
tileElement->AsLargeScenery()->SetSecondaryColour(colour);
break;
}
@ -2683,8 +2685,8 @@ private:
rct_tile_element* element = it.element;
if (element->GetType() == TILE_ELEMENT_TYPE_SURFACE)
{
surface_set_terrain(element, RCT1::GetTerrain(surface_get_terrain(element)));
surface_set_terrain_edge(element, RCT1::GetTerrainEdge(surface_get_terrain_edge(element)));
element->AsSurface()->SetSurfaceStyle(RCT1::GetTerrain(element->AsSurface()->GetSurfaceStyle()));
element->AsSurface()->SetEdgeStyle(RCT1::GetTerrainEdge(element->AsSurface()->GetEdgeStyle()));
}
}
}
@ -2714,7 +2716,7 @@ private:
gParkEntrances[entranceIndex].x = it.x * 32;
gParkEntrances[entranceIndex].y = it.y * 32;
gParkEntrances[entranceIndex].z = element->base_height * 8;
gParkEntrances[entranceIndex].direction = tile_element_get_direction(element);
gParkEntrances[entranceIndex].direction = element->GetDirection();
entranceIndex++;
}
}
@ -2736,8 +2738,8 @@ private:
}
case TILE_ELEMENT_TYPE_LARGE_SCENERY:
{
uint8_t type = scenery_large_get_type(tileElement);
scenery_large_set_type(tileElement, _largeSceneryTypeToEntryMap[type]);
uint8_t type = tileElement->AsLargeScenery()->GetEntryIndex();
tileElement->AsLargeScenery()->SetEntryIndex(_largeSceneryTypeToEntryMap[type]);
break;
}
}

View File

@ -567,7 +567,7 @@ bool track_block_get_next_from_zero(
const rct_preview_track* nextTrackBlock = get_track_def_from_ride(ride, track_element_get_type(tileElement));
const rct_track_coordinates* nextTrackCoordinate = get_track_coord_from_ride(ride, track_element_get_type(tileElement));
uint8_t nextRotation = tile_element_get_direction_with_offset(tileElement, nextTrackCoordinate->rotation_begin)
uint8_t nextRotation = tileElement->GetDirectionWithOffset(nextTrackCoordinate->rotation_begin)
| (nextTrackCoordinate->rotation_begin & (1 << 2));
if (nextRotation != direction_start)
@ -616,7 +616,7 @@ bool track_block_get_next(CoordsXYE* input, CoordsXYE* output, int32_t* z, int32
int32_t y = input->y;
int32_t OriginZ = input->element->base_height * 8;
uint8_t rotation = tile_element_get_direction(input->element);
uint8_t rotation = input->element->GetDirection();
switch (rotation)
{
case 0:
@ -701,7 +701,7 @@ bool track_block_get_previous_from_zero(
if ((nextTrackBlock + 1)->index != 255)
continue;
uint8_t nextRotation = tile_element_get_direction_with_offset(tileElement, nextTrackCoordinate->rotation_end)
uint8_t nextRotation = tileElement->GetDirectionWithOffset(nextTrackCoordinate->rotation_end)
| (nextTrackCoordinate->rotation_end & (1 << 2));
if (nextRotation != directionStart)
@ -711,7 +711,7 @@ bool track_block_get_previous_from_zero(
if (nextZ != z)
continue;
nextRotation = tile_element_get_direction_with_offset(tileElement, nextTrackCoordinate->rotation_begin)
nextRotation = tileElement->GetDirectionWithOffset(nextTrackCoordinate->rotation_begin)
| (nextTrackCoordinate->rotation_begin & (1 << 2));
outTrackBeginEnd->begin_element = tileElement;
outTrackBeginEnd->begin_x = x;
@ -775,7 +775,7 @@ bool track_block_get_previous(int32_t x, int32_t y, rct_tile_element* tileElemen
int32_t z = tileElement->base_height * 8;
uint8_t rotation = tile_element_get_direction(tileElement);
uint8_t rotation = tileElement->GetDirection();
switch (rotation)
{
case 0:
@ -1283,7 +1283,7 @@ int32_t sub_6C683D(
if (tileElement->GetType() != TILE_ELEMENT_TYPE_TRACK)
continue;
if ((tile_element_get_direction(tileElement)) != direction)
if ((tileElement->GetDirection()) != direction)
continue;
if (type != track_element_get_type(tileElement))
@ -1302,7 +1302,7 @@ int32_t sub_6C683D(
const rct_preview_track* trackBlock = get_track_def_from_ride_index(track_element_get_ride_index(tileElement), type);
int32_t sequence = tile_element_get_track_sequence(tileElement);
uint8_t mapDirection = tile_element_get_direction(tileElement);
uint8_t mapDirection = tileElement->GetDirection();
switch (mapDirection)
{
@ -1363,7 +1363,7 @@ int32_t sub_6C683D(
if (tileElement->GetType() != TILE_ELEMENT_TYPE_TRACK)
continue;
if ((tile_element_get_direction(tileElement)) != direction)
if ((tileElement->GetDirection()) != direction)
continue;
if (tile_element_get_track_sequence(tileElement) != trackBlock[i].index)
@ -1782,7 +1782,7 @@ void ride_select_next_section()
_currentTrackBeginX = x;
_currentTrackBeginY = y;
_currentTrackBeginZ = z;
_currentTrackPieceDirection = tile_element_get_direction(tileElement);
_currentTrackPieceDirection = tileElement->GetDirection();
_currentTrackPieceType = track_element_get_type(tileElement);
_currentTrackSelectionFlags = 0;
_rideConstructionArrowPulseTime = 0;
@ -2001,7 +2001,7 @@ int32_t ride_modify(CoordsXYE* input)
x = tileElement.x;
y = tileElement.y;
z = tileElement.element->base_height * 8;
direction = tile_element_get_direction(tileElement.element);
direction = tileElement.element->GetDirection();
type = track_element_get_type(tileElement.element);
if (sub_6C683D(&x, &y, &z, direction, type, 0, nullptr, 0))
@ -2345,7 +2345,7 @@ static void ride_spiral_slide_update(Ride* ride)
if (tileElement == nullptr)
continue;
int32_t rotation = tile_element_get_direction(tileElement);
int32_t rotation = tileElement->GetDirection();
x *= 32;
y *= 32;
x += ride_spiral_slide_main_tile_offset[rotation][current_rotation].x;
@ -3484,7 +3484,7 @@ static void ride_shop_connected(Ride* ride, int32_t ride_idx)
entrance_directions = TrackSequenceProperties[track_type][0];
}
uint8_t tile_direction = tile_element_get_direction(tileElement);
uint8_t tile_direction = tileElement->GetDirection();
entrance_directions <<= tile_direction;
entrance_directions = ((entrance_directions >> 12) | entrance_directions) & 0xF;
@ -4376,7 +4376,7 @@ static void sub_6B5952(int32_t rideIndex)
if (tileElement->base_height != z)
continue;
int32_t direction = tile_element_get_direction(tileElement);
int32_t direction = tileElement->GetDirection();
footpath_chain_ride_queue(rideIndex, i, x, y, tileElement, direction ^ 2);
} while (!(tileElement++)->IsLastForTile());
}
@ -4866,7 +4866,7 @@ static rct_vehicle* vehicle_create_car(
{
// loc_6DDCA4:
vehicle->var_CD = 0;
int32_t direction = tile_element_get_direction(tileElement);
int32_t direction = tileElement->GetDirection();
x += word_9A3AB4[direction].x;
y += word_9A3AB4[direction].y;
z = tileElement->base_height * 8;
@ -4934,7 +4934,7 @@ static rct_vehicle* vehicle_create_car(
vehicle->track_x = x;
vehicle->track_y = y;
int32_t direction = tile_element_get_direction(tileElement);
int32_t direction = tileElement->GetDirection();
vehicle->sprite_direction = direction << 3;
if (ride->type == RIDE_TYPE_SPACE_RINGS)
@ -5195,7 +5195,7 @@ static bool ride_create_vehicles(Ride* ride, int32_t rideIndex, CoordsXYE* eleme
int32_t x = element->x;
int32_t y = element->y;
int32_t z = element->element->base_height;
int32_t direction = tile_element_get_direction(tileElement);
int32_t direction = tileElement->GetDirection();
//
if (ride->mode == RIDE_MODE_STATION_TO_STATION)
@ -5214,7 +5214,7 @@ static bool ride_create_vehicles(Ride* ride, int32_t rideIndex, CoordsXYE* eleme
} while (!(tileElement++)->IsLastForTile());
z = tileElement->base_height;
direction = tile_element_get_direction(tileElement);
direction = tileElement->GetDirection();
}
vehicle_create_trains(rideIndex, x, y, z, tileElement);
@ -5416,7 +5416,7 @@ static bool ride_initialise_cable_lift_track(Ride* ride, bool isApplying)
if (isApplying)
{
z = tileElement->base_height * 8;
int32_t direction = tile_element_get_direction(tileElement);
int32_t direction = tileElement->GetDirection();
trackType = track_element_get_type(tileElement);
x = it.current.x;
y = it.current.y;
@ -5474,7 +5474,7 @@ static bool ride_create_cable_lift(int32_t rideIndex, bool isApplying)
continue;
break;
} while (!(tileElement++)->IsLastForTile());
int32_t direction = tile_element_get_direction(tileElement);
int32_t direction = tileElement->GetDirection();
rct_vehicle* head = nullptr;
rct_vehicle* tail = nullptr;
@ -5951,7 +5951,7 @@ int32_t ride_get_refund_price(int32_t ride_id)
// Find the start in case it is not a complete circuit
ride_get_start_of_track(&trackElement);
uint8_t direction = tile_element_get_direction(trackElement.element);
uint8_t direction = trackElement.element->GetDirection();
// Used in the following loop to know when we have
// completed all of the elements and are back at the
@ -5983,7 +5983,7 @@ int32_t ride_get_refund_price(int32_t ride_id)
}
}
direction = tile_element_get_direction(trackElement.element);
direction = trackElement.element->GetDirection();
} while (trackElement.element != initial_map);
@ -6305,7 +6305,7 @@ void game_command_callback_ride_construct_placed_front(
_currentTrackBeginX = next_track.x;
_currentTrackBeginY = next_track.y;
_currentTrackBeginZ = z;
_currentTrackPieceDirection = tile_element_get_direction(next_track.element);
_currentTrackPieceDirection = next_track.element->GetDirection();
_currentTrackPieceType = track_element_get_type(next_track.element);
_currentTrackSelectionFlags = 0;
_rideConstructionArrowPulseTime = 0;
@ -7155,7 +7155,7 @@ void ride_get_entrance_or_exit_position_from_screen_position(
if (tile_element_get_station(tileElement) != gRideEntranceExitPlaceStationIndex)
continue;
int32_t eax = (direction + 2 - tile_element_get_direction(tileElement)) & TILE_ELEMENT_DIRECTION_MASK;
int32_t eax = (direction + 2 - tileElement->GetDirection()) & TILE_ELEMENT_DIRECTION_MASK;
if (FlatRideTrackSequenceProperties[track_element_get_type(tileElement)]
[tile_element_get_track_sequence(tileElement)]
& (1 << eax))
@ -7183,7 +7183,7 @@ void ride_get_entrance_or_exit_position_from_screen_position(
*outX = 0x8000;
return;
}
direction = tile_element_get_direction(tileElement);
direction = tileElement->GetDirection();
stationDirection = direction;
while (true)
@ -7284,7 +7284,7 @@ bool ride_select_forwards_from_back()
_currentTrackBeginX = next_track.x;
_currentTrackBeginY = next_track.y;
_currentTrackBeginZ = z;
_currentTrackPieceDirection = tile_element_get_direction(next_track.element);
_currentTrackPieceDirection = next_track.element->GetDirection();
_currentTrackPieceType = track_element_get_type(next_track.element);
_currentTrackSelectionFlags = 0;
_rideConstructionArrowPulseTime = 0;
@ -8025,7 +8025,7 @@ void sub_6CB945(int32_t rideIndex)
}
tile_element_set_station(tileElement, stationId);
direction = tile_element_get_direction(tileElement);
direction = tileElement->GetDirection();
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_3))
{
@ -8125,8 +8125,8 @@ void sub_6CB945(int32_t rideIndex)
continue;
CoordsXY nextLocation = location;
nextLocation.x += CoordsDirectionDelta[tile_element_get_direction(tileElement)].x;
nextLocation.y += CoordsDirectionDelta[tile_element_get_direction(tileElement)].y;
nextLocation.x += CoordsDirectionDelta[tileElement->GetDirection()].x;
nextLocation.y += CoordsDirectionDelta[tileElement->GetDirection()].y;
bool shouldRemove = true;
rct_tile_element* trackElement = map_get_first_element_at(nextLocation.x >> 5, nextLocation.y >> 5);
@ -8142,8 +8142,7 @@ void sub_6CB945(int32_t rideIndex)
uint8_t trackType = track_element_get_type(trackElement);
uint8_t trackSequence = tile_element_get_track_sequence(trackElement);
uint8_t direction = (tile_element_get_direction(tileElement) - tile_element_get_direction(trackElement) + 2)
& 3;
uint8_t direction = (tileElement->GetDirection() - trackElement->GetDirectionWithOffset(2)) & 3;
if (!(TrackSequenceProperties[trackType][trackSequence] & (1 << direction)))
{
@ -8164,7 +8163,7 @@ void sub_6CB945(int32_t rideIndex)
ride_set_exit_location(
ride, stationId,
{ location.x / 32, location.y / 32, ride->station_heights[stationId],
(uint8_t)tile_element_get_direction(tileElement) });
(uint8_t)tileElement->GetDirection() });
}
else
{
@ -8175,7 +8174,7 @@ void sub_6CB945(int32_t rideIndex)
location.x / 32,
location.y / 32,
ride->station_heights[stationId],
(uint8_t)tile_element_get_direction(tileElement),
(uint8_t)tileElement->GetDirection(),
};
ride_set_entrance_location(ride, stationId, entranceLocation);
}
@ -8469,7 +8468,7 @@ bool ride_has_adjacent_station(Ride* ride)
continue;
}
/* Check the first side of the station */
int32_t direction = tile_element_get_direction_with_offset(stationElement, 1);
int32_t direction = stationElement->GetDirectionWithOffset(1);
found = check_for_adjacent_station(stationX, stationY, stationZ, direction);
if (found)
break;
@ -8784,7 +8783,7 @@ void determine_ride_entrance_and_exit_locations()
}
else
{
ride->entrances[stationIndex].direction = (uint8_t)tile_element_get_direction(tileElement);
ride->entrances[stationIndex].direction = (uint8_t)tileElement->GetDirection();
}
}
@ -8799,7 +8798,7 @@ void determine_ride_entrance_and_exit_locations()
}
else
{
ride->exits[stationIndex].direction = (uint8_t)tile_element_get_direction(tileElement);
ride->exits[stationIndex].direction = (uint8_t)tileElement->GetDirection();
}
}
@ -8853,7 +8852,7 @@ void determine_ride_entrance_and_exit_locations()
x,
y,
tileElement->base_height,
(uint8_t)tile_element_get_direction(tileElement),
(uint8_t)tileElement->GetDirection(),
};
ride_set_entrance_location(ride, stationIndex, newEntranceLoc);
alreadyFoundEntrance = true;
@ -8875,7 +8874,7 @@ void determine_ride_entrance_and_exit_locations()
// Found our exit
ride_set_exit_location(
ride, stationIndex,
{ x, y, tileElement->base_height, (uint8_t)tile_element_get_direction(tileElement) });
{ x, y, tileElement->base_height, (uint8_t)tileElement->GetDirection() });
alreadyFoundExit = true;
log_verbose(

View File

@ -509,7 +509,7 @@ static void ride_ratings_score_close_proximity_loops(rct_tile_element* inputTile
int32_t y = gRideRatingsCalcData.proximity_y;
ride_ratings_score_close_proximity_loops_helper(inputTileElement, x, y);
int32_t direction = tile_element_get_direction(inputTileElement);
int32_t direction = inputTileElement->GetDirection();
x = gRideRatingsCalcData.proximity_x + CoordsDirectionDelta[direction].x;
y = gRideRatingsCalcData.proximity_y + CoordsDirectionDelta[direction].y;
ride_ratings_score_close_proximity_loops_helper(inputTileElement, x, y);
@ -542,7 +542,7 @@ static void ride_ratings_score_close_proximity(rct_tile_element* inputTileElemen
{
proximity_score_increment(PROXIMITY_SURFACE_TOUCH);
}
waterHeight = surface_get_water_height(tileElement);
waterHeight = tileElement->AsSurface()->GetWaterHeight();
if (waterHeight != 0)
{
int32_t z = waterHeight * 16;
@ -687,7 +687,7 @@ static void ride_ratings_score_close_proximity(rct_tile_element* inputTileElemen
} // switch tileElement->GetType
} while (!(tileElement++)->IsLastForTile());
uint8_t direction = tile_element_get_direction(inputTileElement);
uint8_t direction = inputTileElement->GetDirection();
ride_ratings_score_close_proximity_in_direction(inputTileElement, (direction + 1) & 3);
ride_ratings_score_close_proximity_in_direction(inputTileElement, (direction - 1) & 3);
ride_ratings_score_close_proximity_loops(inputTileElement);

View File

@ -607,7 +607,7 @@ static rct_tile_element* find_station_element(int32_t x, int32_t y, int32_t z, i
continue;
if (tileElement->GetType() != TILE_ELEMENT_TYPE_TRACK)
continue;
if (tile_element_get_direction(tileElement) != direction)
if (tileElement->GetDirection() != direction)
continue;
if (track_element_get_ride_index(tileElement) != rideIndex)
continue;
@ -1274,7 +1274,7 @@ static money32 track_place(
{
tileElement = map_get_surface_element_at({ x, y });
uint8_t water_height = surface_get_water_height(tileElement) * 2;
uint8_t water_height = tileElement->AsSurface()->GetWaterHeight() * 2;
if (water_height == 0)
{
gGameCommandErrorText = STR_CAN_ONLY_BUILD_THIS_ON_WATER;
@ -1289,7 +1289,7 @@ static money32 track_place(
water_height -= 2;
if (water_height == tileElement->base_height)
{
bh = tileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP;
bh = tileElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP;
if (bh == TILE_ELEMENT_SLOPE_W_CORNER_DN || bh == TILE_ELEMENT_SLOPE_S_CORNER_DN
|| bh == TILE_ELEMENT_SLOPE_E_CORNER_DN || bh == TILE_ELEMENT_SLOPE_N_CORNER_DN)
{
@ -1606,7 +1606,7 @@ static money32 track_remove(
if (tileElement->GetType() != TILE_ELEMENT_TYPE_TRACK)
continue;
if ((tile_element_get_direction(tileElement)) != rotation)
if ((tileElement->GetDirection()) != rotation)
continue;
if (tile_element_get_track_sequence(tileElement) != sequence)
@ -1650,7 +1650,7 @@ static money32 track_remove(
const rct_preview_track* trackBlock = get_track_def_from_ride(ride, type);
trackBlock += tile_element_get_track_sequence(tileElement);
uint8_t originDirection = tile_element_get_direction(tileElement);
uint8_t originDirection = tileElement->GetDirection();
switch (originDirection)
{
case 0:
@ -1719,7 +1719,7 @@ static money32 track_remove(
if (tileElement->GetType() != TILE_ELEMENT_TYPE_TRACK)
continue;
if ((tile_element_get_direction(tileElement)) != rotation)
if ((tileElement->GetDirection()) != rotation)
continue;
if (tile_element_get_track_sequence(tileElement) != trackBlock->index)

View File

@ -1304,18 +1304,18 @@ static int32_t track_design_place_maze(rct_track_td6* td6, int16_t x, int16_t y,
rct_tile_element* tile_element = map_get_surface_element_at(mapCoord);
int16_t map_height = tile_element->base_height * 8;
if (tile_element->properties.surface.slope & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP)
if (tile_element->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP)
{
map_height += 16;
if (tile_element->properties.surface.slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
if (tile_element->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
{
map_height += 16;
}
}
if (surface_get_water_height(tile_element) > 0)
if (tile_element->AsSurface()->GetWaterHeight() > 0)
{
int16_t water_height = surface_get_water_height(tile_element);
int16_t water_height = tile_element->AsSurface()->GetWaterHeight();
water_height *= 16;
if (water_height > map_height)
{
@ -1471,16 +1471,16 @@ static bool track_design_place_ride(rct_track_td6* td6, int16_t x, int16_t y, in
}
int32_t height = tileElement->base_height * 8;
if (tileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP)
if (tileElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP)
{
height += 16;
if (tileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
if (tileElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
{
height += 16;
}
}
uint8_t water_height = surface_get_water_height(tileElement) * 16;
uint8_t water_height = tileElement->AsSurface()->GetWaterHeight() * 16;
if (water_height > 0 && water_height > height)
{
height = water_height;
@ -2326,14 +2326,18 @@ static void track_design_preview_clear_map()
for (int32_t i = 0; i < MAX_TILE_TILE_ELEMENT_POINTERS; i++)
{
rct_tile_element* tile_element = &gTileElements[i];
memset(tile_element, 0, sizeof(rct_tile_element));
tile_element->type = TILE_ELEMENT_TYPE_SURFACE;
tile_element->flags = TILE_ELEMENT_FLAG_LAST_TILE;
tile_element->base_height = 2;
tile_element->clearance_height = 0;
tile_element->properties.surface.slope = 0;
tile_element->properties.surface.terrain = 0;
tile_element->properties.surface.grass_length = GRASS_LENGTH_CLEAR_0;
tile_element->properties.surface.ownership = OWNERSHIP_OWNED;
tile_element->AsSurface()->SetSlope(TILE_ELEMENT_SLOPE_FLAT);
tile_element->AsSurface()->SetWaterHeight(0);
tile_element->AsSurface()->SetSurfaceStyle(TERRAIN_GRASS);
tile_element->AsSurface()->SetEdgeStyle(TERRAIN_EDGE_ROCK);
tile_element->AsSurface()->SetGrassLength(GRASS_LENGTH_CLEAR_0);
tile_element->AsSurface()->SetOwnership(OWNERSHIP_UNOWNED);
tile_element->AsSurface()->SetParkFences(0);
}
map_update_tile_pointers();
}

View File

@ -220,7 +220,7 @@ static int32_t tile_element_get_total_element_count(rct_tile_element* tileElemen
return 1;
case TILE_ELEMENT_TYPE_LARGE_SCENERY:
sceneryEntry = get_large_scenery_entry(scenery_large_get_type(tileElement));
sceneryEntry = tileElement->AsLargeScenery()->GetEntry();
tile = sceneryEntry->large_scenery.tiles;
elementCount = 0;
do
@ -312,13 +312,13 @@ static void track_design_save_add_large_scenery(int32_t x, int32_t y, rct_tile_e
int32_t x0, y0, z0, z;
int32_t direction, sequence;
int32_t entryType = scenery_large_get_type(tileElement);
int32_t entryType = tileElement->AsLargeScenery()->GetEntryIndex();
auto entry = object_entry_get_entry(OBJECT_TYPE_LARGE_SCENERY, entryType);
sceneryTiles = get_large_scenery_entry(entryType)->large_scenery.tiles;
z = tileElement->base_height;
direction = tileElement->type & 3;
sequence = scenery_large_get_sequence(tileElement);
sequence = tileElement->AsLargeScenery()->GetSequenceIndex();
if (!map_large_scenery_get_origin(x, y, z, direction, sequence, &x0, &y0, &z0, nullptr))
{
@ -342,8 +342,8 @@ static void track_design_save_add_large_scenery(int32_t x, int32_t y, rct_tile_e
if (sequence == 0)
{
uint8_t flags = tileElement->type & 3;
uint8_t primaryColour = scenery_large_get_primary_colour(tileElement);
uint8_t secondaryColour = scenery_large_get_secondary_colour(tileElement);
uint8_t primaryColour = tileElement->AsLargeScenery()->GetPrimaryColour();
uint8_t secondaryColour = tileElement->AsLargeScenery()->GetSecondaryColour();
track_design_save_push_tile_element_desc(entry, x, y, z, flags, primaryColour, secondaryColour);
}
@ -503,13 +503,13 @@ static void track_design_save_remove_large_scenery(int32_t x, int32_t y, rct_til
int32_t x0, y0, z0, z;
int32_t direction, sequence;
int32_t entryType = scenery_large_get_type(tileElement);
int32_t entryType = tileElement->AsLargeScenery()->GetEntryIndex();
auto entry = object_entry_get_entry(OBJECT_TYPE_LARGE_SCENERY, entryType);
sceneryTiles = get_large_scenery_entry(entryType)->large_scenery.tiles;
z = tileElement->base_height;
direction = tileElement->type & 3;
sequence = scenery_large_get_sequence(tileElement);
sequence = tileElement->AsLargeScenery()->GetSequenceIndex();
if (!map_large_scenery_get_origin(x, y, z, direction, sequence, &x0, &y0, &z0, nullptr))
{
@ -933,7 +933,7 @@ static bool track_design_save_to_td6_for_maze(uint8_t rideIndex, rct_track_td6*
} while (!(tileElement++)->IsLastForTile());
// Add something that stops this from walking off the end
uint8_t entrance_direction = tile_element_get_direction(tileElement);
uint8_t entrance_direction = tileElement->GetDirection();
maze->direction = entrance_direction;
maze->type = 8;
maze->x = (int8_t)((x - startX) / 32);
@ -963,7 +963,7 @@ static bool track_design_save_to_td6_for_maze(uint8_t rideIndex, rct_track_td6*
} while (!(tileElement++)->IsLastForTile());
// Add something that stops this from walking off the end
uint8_t exit_direction = tile_element_get_direction(tileElement);
uint8_t exit_direction = tileElement->GetDirection();
maze->direction = exit_direction;
maze->type = 0x80;
maze->x = (int8_t)((x - startX) / 32);
@ -1014,7 +1014,7 @@ static bool track_design_save_to_td6_for_tracked_ride(uint8_t rideIndex, rct_tra
int32_t z = trackElement.element->base_height * 8;
uint8_t track_type = track_element_get_type(trackElement.element);
uint8_t direction = tile_element_get_direction(trackElement.element);
uint8_t direction = trackElement.element->GetDirection();
_trackSaveDirection = direction;
if (sub_6C683D(&trackElement.x, &trackElement.y, &z, direction, track_type, 0, &trackElement.element, 0))
@ -1073,7 +1073,7 @@ static bool track_design_save_to_td6_for_tracked_ride(uint8_t rideIndex, rct_tra
}
z = trackElement.element->base_height * 8;
direction = tile_element_get_direction(trackElement.element);
direction = trackElement.element->GetDirection();
track_type = track_element_get_type(trackElement.element);
if (sub_6C683D(&trackElement.x, &trackElement.y, &z, direction, track_type, 0, &trackElement.element, 0))
@ -1132,7 +1132,7 @@ static bool track_design_save_to_td6_for_tracked_ride(uint8_t rideIndex, rct_tra
} while (!(tile_element++)->IsLastForTile());
// Add something that stops this from walking off the end
uint8_t entrance_direction = tile_element_get_direction(tile_element);
uint8_t entrance_direction = tile_element->GetDirection();
entrance_direction -= _trackSaveDirection;
entrance_direction &= TILE_ELEMENT_DIRECTION_MASK;
entrance->direction = entrance_direction;

View File

@ -4663,7 +4663,7 @@ static bool vehicle_boat_is_location_accessible(const TileCoordsXYZ& location)
{
if (tileElement->GetType() == TILE_ELEMENT_TYPE_SURFACE)
{
int32_t waterZ = surface_get_water_height(tileElement) * 2;
int32_t waterZ = tileElement->AsSurface()->GetWaterHeight() * 2;
if (location.z != waterZ)
{
return false;

View File

@ -407,7 +407,7 @@ static bool mini_golf_paint_util_should_draw_fence(paint_session* session, const
return true;
}
if (surfaceElement->properties.surface.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK)
if (surfaceElement->AsSurface()->GetSlope() != TILE_ELEMENT_SLOPE_FLAT)
{
return true;
}

View File

@ -39,7 +39,7 @@ static void paint_enterprise_structure(
session->CurrentlyDrawnItem = vehicle;
}
uint32_t imageOffset = tile_element_get_direction_with_offset(tileElement, session->CurrentRotation);
uint32_t imageOffset = tileElement->GetDirectionWithOffset(session->CurrentRotation);
if (vehicle != nullptr)
{
imageOffset = (vehicle->vehicle_sprite_type << 2) + (((vehicle->sprite_direction >> 3) + session->CurrentRotation) % 4);

View File

@ -139,7 +139,7 @@ static bool chairlift_paint_util_is_first_track(
return false;
}
CoordsXY delta = CoordsDirectionDelta[tile_element_get_direction(tileElement)];
CoordsXY delta = CoordsDirectionDelta[tileElement->GetDirection()];
CoordsXY newPos = {
static_cast<int32_t>(pos.x - delta.x),
static_cast<int32_t>(pos.y - delta.y),
@ -159,7 +159,7 @@ static bool chairlift_paint_util_is_last_track(
return false;
}
CoordsXY delta = CoordsDirectionDelta[tile_element_get_direction(tileElement)];
CoordsXY delta = CoordsDirectionDelta[tileElement->GetDirection()];
CoordsXY newPos = {
static_cast<int32_t>(pos.x + delta.x),
static_cast<int32_t>(pos.y + delta.y),

View File

@ -123,7 +123,7 @@ void rct_duck::UpdateFlyToWater()
int32_t manhattanDistanceN = abs(target_x - newX) + abs(target_y - newY);
rct_tile_element* tileElement = map_get_surface_element_at({ target_x, target_y });
int32_t waterHeight = surface_get_water_height(tileElement);
int32_t waterHeight = tileElement->AsSurface()->GetWaterHeight();
if (waterHeight == 0)
{
state = DUCK_STATE::FLY_AWAY;

View File

@ -278,13 +278,11 @@ static money32 RideEntranceExitPlace(
if (isExit)
{
ride_set_exit_location(
ride, stationNum, { x / 32, y / 32, z / 8, (uint8_t)tile_element_get_direction(tileElement) });
ride_set_exit_location(ride, stationNum, { x / 32, y / 32, z / 8, (uint8_t)tileElement->GetDirection() });
}
else
{
ride_set_entrance_location(
ride, stationNum, { x / 32, y / 32, z / 8, (uint8_t)tile_element_get_direction(tileElement) });
ride_set_entrance_location(ride, stationNum, { x / 32, y / 32, z / 8, (uint8_t)tileElement->GetDirection() });
ride->last_peep_in_queue[stationNum] = SPRITE_INDEX_NULL;
ride->queue_length[stationNum] = 0;
@ -546,7 +544,7 @@ void game_command_remove_ride_entrance_or_exit(
*/
void maze_entrance_hedge_replacement(int32_t x, int32_t y, rct_tile_element* tileElement)
{
int32_t direction = tile_element_get_direction(tileElement);
int32_t direction = tileElement->GetDirection();
x += CoordsDirectionDelta[direction].x;
y += CoordsDirectionDelta[direction].y;
int32_t z = tileElement->base_height;
@ -582,7 +580,7 @@ void maze_entrance_hedge_replacement(int32_t x, int32_t y, rct_tile_element* til
*/
void maze_entrance_hedge_removal(int32_t x, int32_t y, rct_tile_element* tileElement)
{
int32_t direction = tile_element_get_direction(tileElement);
int32_t direction = tileElement->GetDirection();
x += CoordsDirectionDelta[direction].x;
y += CoordsDirectionDelta[direction].y;
int32_t z = tileElement->base_height;

View File

@ -949,7 +949,7 @@ void footpath_bridge_get_info_from_pos(
int32_t directions = entrance_get_directions(*tileElement);
if (directions & 0x0F)
{
int32_t bx = tile_element_get_direction_with_offset(*tileElement, bitscanforward(directions));
int32_t bx = (*tileElement)->GetDirectionWithOffset(bitscanforward(directions));
if (direction != nullptr)
*direction = bx;
return;
@ -1034,7 +1034,7 @@ bool fence_in_the_way(int32_t x, int32_t y, int32_t z0, int32_t z1, int32_t dire
continue;
if (z1 <= tileElement->base_height)
continue;
if ((tile_element_get_direction(tileElement)) != direction)
if ((tileElement->GetDirection()) != direction)
continue;
return true;
@ -1376,7 +1376,7 @@ static void loc_6A6D7E(
{
return;
}
uint16_t dx = ((direction - tile_element_get_direction(tileElement)) & TILE_ELEMENT_DIRECTION_MASK) ^ 2;
uint16_t dx = ((direction - tileElement->GetDirection()) & TILE_ELEMENT_DIRECTION_MASK) ^ 2;
if (!(FlatRideTrackSequenceProperties[trackType][trackSequence] & (1 << dx)))
{
return;
@ -1391,7 +1391,7 @@ static void loc_6A6D7E(
case TILE_ELEMENT_TYPE_ENTRANCE:
if (z == tileElement->base_height)
{
if (entrance_has_direction(tileElement, (direction - tile_element_get_direction(tileElement)) ^ 2))
if (entrance_has_direction(tileElement, (direction - tileElement->GetDirection()) ^ 2))
{
if (query)
{
@ -1484,7 +1484,7 @@ static void loc_6A6C85(
if (tileElement->GetType() == TILE_ELEMENT_TYPE_ENTRANCE)
{
if (!entrance_has_direction(tileElement, direction - tile_element_get_direction(tileElement)))
if (!entrance_has_direction(tileElement, direction - tileElement->GetDirection()))
{
return;
}
@ -1503,7 +1503,7 @@ static void loc_6A6C85(
{
return;
}
uint16_t dx = (direction - tile_element_get_direction(tileElement)) & TILE_ELEMENT_DIRECTION_MASK;
uint16_t dx = (direction - tileElement->GetDirection()) & TILE_ELEMENT_DIRECTION_MASK;
if (!(FlatRideTrackSequenceProperties[trackType][trackSequence] & (1 << dx)))
{
return;
@ -1758,7 +1758,7 @@ void footpath_update_queue_chains()
if (tileElement->properties.entrance.ride_index != rideIndex)
continue;
uint8_t direction = tile_element_get_direction_with_offset(tileElement, 2);
uint8_t direction = tileElement->GetDirectionWithOffset(2);
footpath_chain_ride_queue(rideIndex, i, location.x << 5, location.y << 5, tileElement, direction);
} while (!(tileElement++)->IsLastForTile());
}
@ -1785,7 +1785,7 @@ static void footpath_fix_ownership(int32_t x, int32_t y)
// If the tile is safe to own construction rights of, do not erase contruction rights.
else
{
ownership = surfaceElement->properties.surface.ownership;
ownership = surfaceElement->AsSurface()->GetOwnership();
// You can't own the entrance path.
if (ownership == OWNERSHIP_OWNED || ownership == OWNERSHIP_AVAILABLE)
{
@ -2339,7 +2339,7 @@ void footpath_update_queue_entrance_banner(int32_t x, int32_t y, rct_tile_elemen
if (tileElement->properties.entrance.type == ENTRANCE_TYPE_RIDE_ENTRANCE)
{
footpath_queue_chain_push(tileElement->properties.entrance.ride_index);
footpath_chain_ride_queue(255, 0, x, y, tileElement, tile_element_get_direction_with_offset(tileElement, 2));
footpath_chain_ride_queue(255, 0, x, y, tileElement, tileElement->GetDirectionWithOffset(2));
}
break;
}
@ -2478,8 +2478,7 @@ bool tile_element_wants_path_connection_towards(TileCoordsXYZD coords, const rct
const uint8_t trackSequence = tile_element_get_track_sequence(tileElement);
if (FlatRideTrackSequenceProperties[trackType][trackSequence] & TRACK_SEQUENCE_FLAG_CONNECTS_TO_PATH)
{
uint16_t dx
= ((coords.direction - tile_element_get_direction(tileElement)) & TILE_ELEMENT_DIRECTION_MASK);
uint16_t dx = ((coords.direction - tileElement->GetDirection()) & TILE_ELEMENT_DIRECTION_MASK);
if (FlatRideTrackSequenceProperties[trackType][trackSequence] & (1 << dx))
{
// Track element has the flags required for the given direction
@ -2491,7 +2490,7 @@ bool tile_element_wants_path_connection_towards(TileCoordsXYZD coords, const rct
case TILE_ELEMENT_TYPE_ENTRANCE:
if (tileElement->base_height == coords.z)
{
if (entrance_has_direction(tileElement, coords.direction - tile_element_get_direction(tileElement)))
if (entrance_has_direction(tileElement, coords.direction - tileElement->GetDirection()))
{
// Entrance wants to be connected towards the given direction
return true;
@ -2600,7 +2599,7 @@ void footpath_remove_edges_at(int32_t x, int32_t y, rct_tile_element* tileElemen
}
// Only fix corners when needed, to avoid changing corners that have been set for its looks.
if (fixCorners && tile_element_is_ghost(tileElement))
if (fixCorners && tileElement->IsGhost())
{
footpath_fix_corners_around(x / 32, y / 32, tileElement);
}

View File

@ -9,64 +9,83 @@
#include "LargeScenery.h"
#include "../Context.h"
#include "../common.h"
#include "../object/ObjectManager.h"
#include "TileElement.h"
colour_t scenery_large_get_primary_colour(const rct_tile_element* tileElement)
colour_t LargeSceneryElement::GetPrimaryColour() const
{
return tileElement->properties.scenerymultiple.colour[0] & TILE_ELEMENT_COLOUR_MASK;
return colour[0] & TILE_ELEMENT_COLOUR_MASK;
}
colour_t scenery_large_get_secondary_colour(const rct_tile_element* tileElement)
colour_t LargeSceneryElement::GetSecondaryColour() const
{
return tileElement->properties.scenerymultiple.colour[1] & TILE_ELEMENT_COLOUR_MASK;
return colour[1] & TILE_ELEMENT_COLOUR_MASK;
}
void scenery_large_set_primary_colour(rct_tile_element* tileElement, colour_t colour)
void LargeSceneryElement::SetPrimaryColour(colour_t newColour)
{
assert(colour <= 31);
tileElement->properties.scenerymultiple.colour[0] &= ~TILE_ELEMENT_COLOUR_MASK;
tileElement->properties.scenerymultiple.colour[0] |= colour;
assert(newColour <= 31);
colour[0] &= ~TILE_ELEMENT_COLOUR_MASK;
colour[0] |= newColour;
}
void scenery_large_set_secondary_colour(rct_tile_element* tileElement, colour_t colour)
void LargeSceneryElement::SetSecondaryColour(colour_t newColour)
{
assert(colour <= 31);
tileElement->properties.scenerymultiple.colour[1] &= ~TILE_ELEMENT_COLOUR_MASK;
tileElement->properties.scenerymultiple.colour[1] |= colour;
assert(newColour <= 31);
colour[1] &= ~TILE_ELEMENT_COLOUR_MASK;
colour[1] |= newColour;
}
BannerIndex scenery_large_get_banner_id(const rct_tile_element* tileElement)
BannerIndex LargeSceneryElement::GetBannerIndex() const
{
return (tileElement->type & 0xC0) | (((tileElement->properties.scenerymultiple.colour[0]) & ~TILE_ELEMENT_COLOUR_MASK) >> 2)
| (((tileElement->properties.scenerymultiple.colour[1]) & ~TILE_ELEMENT_COLOUR_MASK) >> 5);
return (entryIndex & 0xC0) | (((colour[0]) & ~TILE_ELEMENT_COLOUR_MASK) >> 2)
| (((colour[1]) & ~TILE_ELEMENT_COLOUR_MASK) >> 5);
}
void scenery_large_set_banner_id(rct_tile_element* tileElement, BannerIndex bannerIndex)
void LargeSceneryElement::SetBannerIndex(BannerIndex newIndex)
{
tileElement->type |= bannerIndex & 0xC0;
tileElement->properties.scenerymultiple.colour[0] |= (bannerIndex & 0x38) << 2;
tileElement->properties.scenerymultiple.colour[1] |= (bannerIndex & 7) << 5;
entryIndex |= newIndex & 0xC0;
colour[0] |= (newIndex & 0x38) << 2;
colour[1] |= (newIndex & 7) << 5;
}
int32_t scenery_large_get_type(const rct_tile_element* tileElement)
uint32_t LargeSceneryElement::GetEntryIndex() const
{
return (tileElement->properties.scenerymultiple.type & TILE_ELEMENT_LARGE_TYPE_MASK);
return entryIndex & TILE_ELEMENT_LARGE_TYPE_MASK;
}
int32_t scenery_large_get_sequence(const rct_tile_element* tileElement)
rct_scenery_entry* LargeSceneryElement::GetEntry() const
{
return (tileElement->properties.scenerymultiple.type >> 10);
return get_large_scenery_entry(GetEntryIndex());
}
void scenery_large_set_type(rct_tile_element* tileElement, uint16_t type)
uint16_t LargeSceneryElement::GetSequenceIndex() const
{
tileElement->properties.scenerymultiple.type &= ~TILE_ELEMENT_LARGE_TYPE_MASK;
tileElement->properties.scenerymultiple.type |= (type & TILE_ELEMENT_LARGE_TYPE_MASK);
return (entryIndex >> 10);
}
void scenery_large_set_sequence(rct_tile_element* tileElement, uint16_t sequence)
void LargeSceneryElement::SetEntryIndex(uint32_t newIndex)
{
tileElement->properties.scenerymultiple.type &= TILE_ELEMENT_LARGE_TYPE_MASK;
tileElement->properties.scenerymultiple.type |= (sequence << 10);
entryIndex &= ~TILE_ELEMENT_LARGE_TYPE_MASK;
entryIndex |= (newIndex & TILE_ELEMENT_LARGE_TYPE_MASK);
}
void LargeSceneryElement::SetSequenceIndex(uint16_t sequence)
{
entryIndex &= TILE_ELEMENT_LARGE_TYPE_MASK;
entryIndex |= (sequence << 10);
}
rct_scenery_entry* get_large_scenery_entry(int32_t entryIndex)
{
rct_scenery_entry* result = nullptr;
auto& objMgr = OpenRCT2::GetContext()->GetObjectManager();
auto obj = objMgr.GetLoadedObject(OBJECT_TYPE_LARGE_SCENERY, entryIndex);
if (obj != nullptr)
{
result = (rct_scenery_entry*)obj->GetLegacyData();
}
return result;
}

View File

@ -13,13 +13,4 @@
#include "Map.h"
#include "TileElement.h"
colour_t scenery_large_get_primary_colour(const rct_tile_element* tileElement);
colour_t scenery_large_get_secondary_colour(const rct_tile_element* tileElement);
void scenery_large_set_primary_colour(rct_tile_element* tileElement, colour_t colour);
void scenery_large_set_secondary_colour(rct_tile_element* tileElement, colour_t colour);
BannerIndex scenery_large_get_banner_id(const rct_tile_element* tileElement);
void scenery_large_set_banner_id(rct_tile_element* tileElement, BannerIndex bannerIndex);
int32_t scenery_large_get_type(const rct_tile_element* tileElement);
int32_t scenery_large_get_sequence(const rct_tile_element* tileElement);
void scenery_large_set_type(rct_tile_element* tileElement, uint16_t type);
void scenery_large_set_sequence(rct_tile_element* tileElement, uint16_t sequence);
rct_scenery_entry* get_large_scenery_entry(int32_t entryIndex);

View File

@ -114,8 +114,6 @@ LocationXYZ16 gCommandPosition;
bool gMapLandRightsUpdateSuccess;
static void map_update_grass_length(int32_t x, int32_t y, rct_tile_element* tileElement);
static void map_set_grass_length(int32_t x, int32_t y, rct_tile_element* tileElement, int32_t length);
static void clear_elements_at(int32_t x, int32_t y);
static void translate_3d_to_2d(int32_t rotation, int32_t* x, int32_t* y);
@ -344,17 +342,18 @@ void map_init(int32_t size)
for (int32_t i = 0; i < MAX_TILE_TILE_ELEMENT_POINTERS; i++)
{
rct_tile_element* tile_element = &gTileElements[i];
memset(tile_element, 0, sizeof(rct_tile_element));
tile_element->type = (TILE_ELEMENT_TYPE_SURFACE << 2);
tile_element->flags = TILE_ELEMENT_FLAG_LAST_TILE;
tile_element->base_height = 14;
tile_element->clearance_height = 14;
tile_element->properties.surface.slope = TILE_ELEMENT_SLOPE_FLAT;
tile_element->properties.surface.grass_length = GRASS_LENGTH_CLEAR_0;
tile_element->properties.surface.ownership = 0;
tile_element->properties.surface.terrain = 0;
surface_set_terrain(tile_element, TERRAIN_GRASS);
surface_set_terrain_edge(tile_element, TERRAIN_EDGE_ROCK);
tile_element->AsSurface()->SetWaterHeight(0);
tile_element->AsSurface()->SetSlope(TILE_ELEMENT_SLOPE_FLAT);
tile_element->AsSurface()->SetGrassLength(GRASS_LENGTH_CLEAR_0);
tile_element->AsSurface()->SetOwnership(OWNERSHIP_UNOWNED);
tile_element->AsSurface()->SetParkFences(0);
tile_element->AsSurface()->SetSurfaceStyle(TERRAIN_GRASS);
tile_element->AsSurface()->SetEdgeStyle(TERRAIN_EDGE_ROCK);
}
gGrassSceneryTileLoopPosition = 0;
@ -393,7 +392,7 @@ void map_count_remaining_land_rights()
continue;
}
uint8_t flags = element->properties.surface.ownership;
uint8_t flags = element->AsSurface()->GetOwnership();
// Do not combine this condition with (flags & OWNERSHIP_AVAILABLE)
// As some RCT1 parks have owned tiles with the 'construction rights available' flag also set
@ -486,9 +485,9 @@ int32_t tile_element_height(int32_t x, int32_t y)
return 16;
}
uint32_t height = (surface_get_water_height(tileElement) << 20) | (tileElement->base_height << 3);
uint32_t height = (tileElement->AsSurface()->GetWaterHeight() << 20) | (tileElement->base_height << 3);
uint32_t slope = (tileElement->properties.surface.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK);
uint32_t slope = tileElement->AsSurface()->GetSlope();
uint8_t extra_height = (slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT) >> 4; // 0x10 is the 5th bit - sets slope to double height
// Remove the extra height bit
slope &= TILE_ELEMENT_SLOPE_ALL_CORNERS_UP;
@ -698,18 +697,18 @@ void map_update_path_wide_flags()
*/
int32_t map_height_from_slope(int32_t x, int32_t y, int32_t slope)
{
if (!(slope & TILE_ELEMENT_SLOPE_S_CORNER_UP))
if (!(slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED))
return 0;
switch (slope & TILE_ELEMENT_SLOPE_NE_SIDE_UP)
switch (slope & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK)
{
case TILE_ELEMENT_SLOPE_FLAT:
case TILE_ELEMENT_DIRECTION_WEST:
return (31 - (x & 31)) / 2;
case TILE_ELEMENT_SLOPE_N_CORNER_UP:
case TILE_ELEMENT_DIRECTION_NORTH:
return (y & 31) / 2;
case TILE_ELEMENT_SLOPE_E_CORNER_UP:
case TILE_ELEMENT_DIRECTION_EAST:
return (x & 31) / 2;
case TILE_ELEMENT_SLOPE_NE_SIDE_UP:
case TILE_ELEMENT_DIRECTION_SOUTH:
return (31 - (y & 31)) / 2;
}
return 0;
@ -753,10 +752,10 @@ bool map_is_location_owned(int32_t x, int32_t y, int32_t z)
rct_tile_element* tileElement = map_get_surface_element_at({ x, y });
if (tileElement != nullptr)
{
if (tileElement->properties.surface.ownership & OWNERSHIP_OWNED)
if (tileElement->AsSurface()->GetOwnership() & OWNERSHIP_OWNED)
return true;
if (tileElement->properties.surface.ownership & OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)
if (tileElement->AsSurface()->GetOwnership() & OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)
{
z /= 8;
if (z < tileElement->base_height || z - 2 > tileElement->base_height)
@ -780,7 +779,7 @@ bool map_is_location_in_park(const CoordsXY coords)
rct_tile_element* tileElement = map_get_surface_element_at(coords);
if (tileElement == nullptr)
return false;
if (tileElement->properties.surface.ownership & OWNERSHIP_OWNED)
if (tileElement->AsSurface()->GetOwnership() & OWNERSHIP_OWNED)
return true;
}
@ -797,9 +796,9 @@ bool map_is_location_owned_or_has_rights(int32_t x, int32_t y)
{
return false;
}
if (tileElement->properties.surface.ownership & OWNERSHIP_OWNED)
if (tileElement->AsSurface()->GetOwnership() & OWNERSHIP_OWNED)
return true;
if (tileElement->properties.surface.ownership & OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)
if (tileElement->AsSurface()->GetOwnership() & OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)
return true;
}
return false;
@ -848,10 +847,10 @@ void game_command_remove_large_scenery(
if (tileElement->base_height != base_height)
continue;
if (scenery_large_get_sequence(tileElement) != tileIndex)
if (tileElement->AsLargeScenery()->GetSequenceIndex() != tileIndex)
continue;
if ((tile_element_get_direction(tileElement)) != tile_element_direction)
if (tileElement->GetDirection() != tile_element_direction)
continue;
// If we are removing ghost elements
@ -873,7 +872,7 @@ void game_command_remove_large_scenery(
tile_element_remove_banner_entry(tileElement);
}
rct_scenery_entry* scenery_entry = get_large_scenery_entry(scenery_large_get_type(tileElement));
rct_scenery_entry* scenery_entry = tileElement->AsLargeScenery()->GetEntry();
LocationXYZ16 firstTile = {
scenery_entry->large_scenery.tiles[tileIndex].x_offset, scenery_entry->large_scenery.tiles[tileIndex].y_offset,
static_cast<int16_t>((base_height * 8) - scenery_entry->large_scenery.tiles[tileIndex].z_offset)
@ -925,10 +924,10 @@ void game_command_remove_large_scenery(
if (sceneryElement->GetType() != TILE_ELEMENT_TYPE_LARGE_SCENERY)
continue;
if (tile_element_get_direction(sceneryElement) != tile_element_direction)
if (sceneryElement->GetDirection() != tile_element_direction)
continue;
if (scenery_large_get_sequence(sceneryElement) != i)
if (sceneryElement->AsLargeScenery()->GetSequenceIndex() != i)
continue;
if (sceneryElement->base_height != currentTile.z / 8)
@ -1002,7 +1001,7 @@ void game_command_set_large_scenery_colour(
return;
}
rct_scenery_entry* scenery_entry = get_large_scenery_entry(scenery_large_get_type(tile_element));
rct_scenery_entry* scenery_entry = tile_element->AsLargeScenery()->GetEntry();
// Work out the base tile coordinates (Tile with index 0)
LocationXYZ16 baseTile = {
@ -1040,8 +1039,8 @@ void game_command_set_large_scenery_colour(
rct_tile_element* tileElement = map_get_large_scenery_segment(
currentTile.x, currentTile.y, base_height, tile_element_direction, i);
scenery_large_set_primary_colour(tileElement, colour1);
scenery_large_set_secondary_colour(tileElement, colour2);
tileElement->AsLargeScenery()->SetPrimaryColour(colour1);
tileElement->AsLargeScenery()->SetSecondaryColour(colour2);
map_invalidate_tile_full(currentTile.x, currentTile.y);
}
@ -1129,9 +1128,9 @@ restart_from_beginning:
if (clear & (1 << 1))
{
int32_t eax = x * 32;
int32_t ebx = flags | ((tile_element_get_direction(tileElement)) << 8);
int32_t ebx = flags | ((tileElement->GetDirection()) << 8);
int32_t ecx = y * 32;
int32_t edx = tileElement->base_height | (scenery_large_get_sequence(tileElement) << 8);
int32_t edx = tileElement->base_height | (tileElement->AsLargeScenery()->GetSequenceIndex() << 8);
int32_t edi = 0, ebp = 0;
cost = game_do_command(eax, ebx | (1 << 7), ecx, edx, GAME_COMMAND_REMOVE_LARGE_SCENERY, edi, ebp);
@ -1305,8 +1304,7 @@ static money32 map_change_surface_style(
if (surfaceStyle != 0xFF)
{
uint8_t cur_terrain = (tile_element_get_direction(tileElement) << 3)
| (tileElement->properties.surface.terrain >> 5);
uint8_t cur_terrain = tileElement->AsSurface()->GetSurfaceStyle();
if (surfaceStyle != cur_terrain)
{
@ -1321,14 +1319,7 @@ static money32 map_change_surface_style(
if (flags & GAME_COMMAND_FLAG_APPLY)
{
tileElement->properties.surface.terrain &= TILE_ELEMENT_SURFACE_WATER_HEIGHT_MASK;
tileElement->type &= TILE_ELEMENT_QUADRANT_MASK | TILE_ELEMENT_TYPE_MASK;
// Save the new terrain
tileElement->properties.surface.terrain |= surfaceStyle << 5;
// Save the new direction mask
tileElement->type |= (surfaceStyle >> 3) & TILE_ELEMENT_DIRECTION_MASK;
tileElement->AsSurface()->SetSurfaceStyle(surfaceStyle);
map_invalidate_tile_full(x, y);
footpath_remove_litter(x, y, tile_element_height(x, y));
@ -1338,38 +1329,28 @@ static money32 map_change_surface_style(
if (edgeStyle != 0xFF)
{
uint8_t currentEdge = ((tileElement->type & 0x80) >> 4) | (tileElement->properties.surface.slope >> 5);
uint8_t currentEdge = tileElement->AsSurface()->GetEdgeStyle();
if (edgeStyle != currentEdge)
{
edgeCost += 100;
if (flags & 1)
if (flags & GAME_COMMAND_FLAG_APPLY)
{
tileElement->properties.surface.slope &= TILE_ELEMENT_SURFACE_SLOPE_MASK;
tileElement->type &= 0x7F;
// Save edge style
tileElement->properties.surface.slope |= edgeStyle << 5;
// Save ???
tileElement->type |= (edgeStyle << 4) & 0x80;
tileElement->AsSurface()->SetEdgeStyle(edgeStyle);
map_invalidate_tile_full(x, y);
}
}
}
if (flags & 1)
if (flags & GAME_COMMAND_FLAG_APPLY)
{
if (!(tileElement->properties.surface.terrain & TILE_ELEMENT_SURFACE_TERRAIN_MASK))
if (tileElement->AsSurface()->GetSurfaceStyle() == TERRAIN_GRASS)
{
if (!(tile_element_get_direction(tileElement)))
if ((tileElement->AsSurface()->GetGrassLength() & 7) != GRASS_LENGTH_CLEAR_0)
{
if ((tileElement->properties.surface.grass_length & 7) != GRASS_LENGTH_CLEAR_0)
{
tileElement->properties.surface.grass_length = GRASS_LENGTH_CLEAR_0;
map_invalidate_tile_full(x, y);
}
tileElement->AsSurface()->SetGrassLength(GRASS_LENGTH_CLEAR_0);
map_invalidate_tile_full(x, y);
}
}
}
@ -1520,7 +1501,7 @@ static int32_t map_get_corner_height(int32_t z, int32_t slope, int32_t direction
static int32_t tile_element_get_corner_height(const rct_tile_element* tileElement, int32_t direction)
{
int32_t z = tileElement->base_height;
int32_t slope = tileElement->properties.surface.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK;
int32_t slope = tileElement->AsSurface()->GetSlope();
return map_get_corner_height(z, slope, direction);
}
@ -1649,7 +1630,7 @@ static money32 map_set_land_height(int32_t flags, int32_t x, int32_t y, int32_t
rct_tile_element* surfaceElement = map_get_surface_element_at({ x, y });
if (surfaceElement->type & TILE_ELEMENT_TYPE_FLAG_HIGHLIGHT)
{
int32_t waterHeight = surface_get_water_height(surfaceElement);
uint32_t waterHeight = surfaceElement->AsSurface()->GetWaterHeight();
if (waterHeight != 0)
{
if (style & 0x1F)
@ -1741,11 +1722,10 @@ static money32 map_set_land_height(int32_t flags, int32_t x, int32_t y, int32_t
surfaceElement = map_get_surface_element_at({ x, y });
surfaceElement->base_height = height;
surfaceElement->clearance_height = height;
surfaceElement->properties.surface.slope &= TILE_ELEMENT_SURFACE_EDGE_STYLE_MASK;
surfaceElement->properties.surface.slope |= style;
int32_t slope = surfaceElement->properties.surface.terrain & TILE_ELEMENT_SURFACE_SLOPE_MASK;
if (slope != TILE_ELEMENT_SLOPE_FLAT && slope <= height / 2)
surfaceElement->properties.surface.terrain &= TILE_ELEMENT_SURFACE_TERRAIN_MASK;
surfaceElement->AsSurface()->SetSlope(style);
int32_t waterHeight = surfaceElement->AsSurface()->GetWaterHeight();
if (waterHeight != 0 && waterHeight <= height / 2)
surfaceElement->AsSurface()->SetWaterHeight(0);
map_invalidate_tile_full(x, y);
}
if (gParkFlags & PARK_FLAGS_NO_MONEY)
@ -1844,9 +1824,9 @@ static uint8_t map_get_highest_land_height(int32_t xMin, int32_t xMax, int32_t y
if (tile_element != nullptr)
{
uint8_t base_height = tile_element->base_height;
if (tile_element->properties.surface.slope & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP)
if (tile_element->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP)
base_height += 2;
if (tile_element->properties.surface.slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
if (tile_element->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
base_height += 2;
if (max_height < base_height)
max_height = base_height;
@ -1890,7 +1870,7 @@ static money32 raise_land(
uint8_t height = tile_element->base_height;
if (height <= min_height)
{
uint8_t raisedCorners = tile_element->properties.surface.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK;
uint8_t raisedCorners = tile_element->AsSurface()->GetSlope();
uint8_t slope = tile_element_raise_styles[tableRow][raisedCorners];
if (slope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT)
@ -1950,15 +1930,15 @@ static money32 lower_land(
if (tile_element != nullptr)
{
uint8_t height = tile_element->base_height;
if (tile_element->properties.surface.slope & TILE_ELEMENT_SURFACE_RAISED_CORNERS_MASK)
if (tile_element->AsSurface()->GetSlope() & TILE_ELEMENT_SURFACE_RAISED_CORNERS_MASK)
height += 2;
if (tile_element->properties.surface.slope & TILE_ELEMENT_SURFACE_DIAGONAL_FLAG)
if (tile_element->AsSurface()->GetSlope() & TILE_ELEMENT_SURFACE_DIAGONAL_FLAG)
height += 2;
if (height >= max_height)
{
height = tile_element->base_height;
uint8_t currentSlope = tile_element->properties.surface.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK;
uint8_t currentSlope = tile_element->AsSurface()->GetSlope();
uint8_t newSlope = tile_element_lower_styles[tableRow][currentSlope];
if (newSlope & SURFACE_STYLE_FLAG_RAISE_OR_LOWER_BASE_HEIGHT)
height -= 2;
@ -2005,8 +1985,8 @@ money32 raise_water(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint8_t flag
if (tile_element != nullptr)
{
uint8_t height = tile_element->base_height;
if (surface_get_water_height(tile_element) > 0)
height = surface_get_water_height(tile_element) * 2;
if (tile_element->AsSurface()->GetWaterHeight() > 0)
height = tile_element->AsSurface()->GetWaterHeight() * 2;
if (max_height > height)
max_height = height;
}
@ -2022,7 +2002,7 @@ money32 raise_water(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint8_t flag
{
if (tile_element->base_height <= max_height)
{
uint8_t height = surface_get_water_height(tile_element);
uint8_t height = tile_element->AsSurface()->GetWaterHeight();
if (height != 0)
{
height *= 2;
@ -2098,7 +2078,7 @@ money32 lower_water(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint8_t flag
rct_tile_element* tile_element = map_get_surface_element_at({ xi, yi });
if (tile_element != nullptr)
{
uint8_t height = surface_get_water_height(tile_element);
uint8_t height = tile_element->AsSurface()->GetWaterHeight();
if (height != 0)
{
height *= 2;
@ -2116,7 +2096,7 @@ money32 lower_water(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint8_t flag
rct_tile_element* tile_element = map_get_surface_element_at({ xi, yi });
if (tile_element != nullptr)
{
uint8_t height = surface_get_water_height(tile_element);
uint8_t height = tile_element->AsSurface()->GetWaterHeight();
if (height != 0)
{
height *= 2;
@ -2194,7 +2174,7 @@ static money32 smooth_land_tile(
int32_t direction, uint8_t flags, int32_t x, int32_t y, rct_tile_element* tileElement, bool raiseLand)
{
int32_t targetBaseZ = tileElement->base_height;
int32_t slope = tileElement->properties.surface.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK;
int32_t slope = tileElement->AsSurface()->GetSlope();
if (raiseLand)
{
slope = tile_element_raise_styles[direction][slope];
@ -2301,7 +2281,7 @@ static money32 smooth_land_row_by_edge(
// change land of current tile
int32_t targetBaseZ = tileElement->base_height;
int32_t slope = tileElement->properties.surface.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK;
int32_t slope = tileElement->AsSurface()->GetSlope();
int32_t oldSlope = slope;
if (raiseLand)
{
@ -2543,7 +2523,7 @@ static money32 smooth_land(
{
rct_tile_element* tileElement = map_get_surface_element_at({ mapLeft, mapTop });
uint8_t newBaseZ = tileElement->base_height;
uint8_t newSlope = tileElement->properties.surface.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK;
uint8_t newSlope = tileElement->AsSurface()->GetSlope();
if (raiseLand)
{
@ -2621,7 +2601,7 @@ static money32 smooth_land(
// Get the two corners to raise
rct_tile_element* surfaceElement = map_get_surface_element_at({ mapLeft, mapTop });
uint8_t newBaseZ = surfaceElement->base_height;
uint8_t oldSlope = surfaceElement->properties.surface.slope;
uint8_t oldSlope = surfaceElement->AsSurface()->GetSlope();
uint8_t newSlope = oldSlope;
int32_t rowIndex = selectionType - (MAP_SELECT_TYPE_EDGE_0 - MAP_SELECT_TYPE_FULL - 1);
@ -2820,9 +2800,9 @@ void game_command_set_water_height(
rct_tile_element* tile_element = map_get_surface_element_at({ x, y });
int32_t zHigh = tile_element->base_height;
int32_t zLow = base_height;
if (surface_get_water_height(tile_element) > 0)
if (tile_element->AsSurface()->GetWaterHeight() > 0)
{
zHigh = surface_get_water_height(tile_element) * 2;
zHigh = tile_element->AsSurface()->GetWaterHeight() * 2;
}
if (zLow > zHigh)
{
@ -2841,12 +2821,14 @@ void game_command_set_water_height(
}
if (*ebx & GAME_COMMAND_FLAG_APPLY)
{
int32_t new_terrain = tile_element->properties.surface.terrain & 0xE0;
if (base_height > tile_element->base_height)
{
new_terrain |= (base_height / 2);
tile_element->AsSurface()->SetWaterHeight(base_height / 2);
}
else
{
tile_element->AsSurface()->SetWaterHeight(0);
}
tile_element->properties.surface.terrain = new_terrain;
map_invalidate_tile_full(x, y);
}
*ebx = 250;
@ -2961,7 +2943,7 @@ void game_command_place_large_scenery(
if (tile_element != nullptr)
{
int32_t height = tile_element->base_height * 8;
int32_t slope = tile_element->properties.surface.slope;
int32_t slope = tile_element->AsSurface()->GetSlope();
if (slope & 0xF)
{
@ -3079,15 +3061,16 @@ void game_command_place_large_scenery(
new_tile_element->clearance_height = zHigh;
new_tile_element->type = TILE_ELEMENT_TYPE_LARGE_SCENERY | rotation;
scenery_large_set_type(new_tile_element, entry_index);
scenery_large_set_sequence(new_tile_element, tile_num);
auto newSceneryElement = new_tile_element->AsLargeScenery();
newSceneryElement->SetEntryIndex(entry_index);
newSceneryElement->SetSequenceIndex(tile_num);
scenery_large_set_primary_colour(new_tile_element, colour1);
scenery_large_set_secondary_colour(new_tile_element, colour2);
newSceneryElement->SetPrimaryColour(colour1);
newSceneryElement->SetSecondaryColour(colour2);
if (banner_id != BANNER_INDEX_NULL)
{
scenery_large_set_banner_id(new_tile_element, banner_id);
newSceneryElement->SetBannerIndex(banner_id);
}
if (flags & GAME_COMMAND_FLAG_GHOST)
@ -3464,8 +3447,7 @@ void map_obstruction_set_error_text(rct_tile_element* tileElement)
set_format_arg(0, rct_string_id, sceneryEntry->name);
break;
case TILE_ELEMENT_TYPE_LARGE_SCENERY:
// Fixme: replace by proper call.
sceneryEntry = get_large_scenery_entry(tileElement->properties.scenerymultiple.type & 0x3FF);
sceneryEntry = tileElement->AsLargeScenery()->GetEntry();
errorStringId = STR_X_IN_THE_WAY;
set_format_arg(0, rct_string_id, sceneryEntry->name);
break;
@ -3520,7 +3502,7 @@ bool map_can_construct_with_clear_at(
}
continue;
}
water_height = surface_get_water_height(tileElement) * 2;
water_height = tileElement->AsSurface()->GetWaterHeight() * 2;
if (water_height && water_height > zLow && tileElement->base_height < zHigh)
{
gMapGroundFlags |= ELEMENT_IS_UNDERWATER;
@ -3545,8 +3527,7 @@ bool map_can_construct_with_clear_at(
// Only allow building crossings directly on a flat surface tile.
if (tileElement->GetType() == TILE_ELEMENT_TYPE_SURFACE
&& (tileElement->properties.surface.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK) == TILE_ELEMENT_SLOPE_FLAT
&& tileElement->base_height == zLow)
&& (tileElement->AsSurface()->GetSlope()) == TILE_ELEMENT_SLOPE_FLAT && tileElement->base_height == zLow)
{
canBuildCrossing = true;
}
@ -3565,7 +3546,7 @@ bool map_can_construct_with_clear_at(
ah = al;
cl = al;
ch = al;
slope = tileElement->properties.surface.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK;
slope = tileElement->AsSurface()->GetSlope();
if (slope & TILE_ELEMENT_SLOPE_N_CORNER_UP)
{
al += 2;
@ -3687,10 +3668,10 @@ void map_update_tiles()
interleaved_xy >>= 1;
}
rct_tile_element* tileElement = map_get_surface_element_at(x, y);
SurfaceElement* tileElement = map_get_surface_element_at(x, y)->AsSurface();
if (tileElement != nullptr)
{
map_update_grass_length(x * 32, y * 32, tileElement);
tileElement->UpdateGrassLength({ x * 32, y * 32 });
scenery_update_tile(x * 32, y * 32);
}
@ -3699,112 +3680,6 @@ void map_update_tiles()
}
}
/**
*
* rct2: 0x006647A1
*/
static void map_update_grass_length(int32_t x, int32_t y, rct_tile_element* tileElement)
{
// Check if tile is grass
if ((tileElement->properties.surface.terrain & 0xE0) && !(tileElement->type & 3))
return;
int32_t grassLength = tileElement->properties.surface.grass_length & 7;
// Check if grass is underwater or outside park
int32_t waterHeight = surface_get_water_height(tileElement) * 2;
if (waterHeight > tileElement->base_height || !map_is_location_in_park({ x, y }))
{
if (grassLength != GRASS_LENGTH_CLEAR_0)
map_set_grass_length(x, y, tileElement, GRASS_LENGTH_CLEAR_0);
return;
}
// Grass can't grow any further than CLUMPS_2 but this code also cuts grass
// if there is an object placed on top of it.
int32_t z0 = tileElement->base_height;
int32_t z1 = tileElement->base_height + 2;
if (tileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
z1 += 2;
// Check objects above grass
rct_tile_element* tileElementAbove = tileElement;
for (;;)
{
if (tileElementAbove->flags & TILE_ELEMENT_FLAG_LAST_TILE)
{
// Grow grass
// Check interim grass lengths
uint8_t lengthNibble = (tileElement->properties.surface.grass_length & 0xF0) >> 4;
if (lengthNibble < 0xF)
{
tileElement->properties.surface.grass_length += 0x10;
}
else
{
// Zeros the length nibble
tileElement->properties.surface.grass_length += 0x10;
tileElement->properties.surface.grass_length ^= 8;
if (tileElement->properties.surface.grass_length & 8)
{
// Random growth rate (length nibble)
tileElement->properties.surface.grass_length |= scenario_rand() & 0x70;
}
else
{
// Increase length if not at max length
if (grassLength != GRASS_LENGTH_CLUMPS_2)
map_set_grass_length(x, y, tileElement, grassLength + 1);
}
}
}
else
{
tileElementAbove++;
if (tileElementAbove->GetType() == TILE_ELEMENT_TYPE_WALL)
continue;
// Grass should not be affected by ghost elements.
if (tile_element_is_ghost(tileElementAbove))
continue;
if (z0 >= tileElementAbove->clearance_height)
continue;
if (z1 < tileElementAbove->base_height)
continue;
if (grassLength != GRASS_LENGTH_CLEAR_0)
map_set_grass_length(x, y, tileElement, GRASS_LENGTH_CLEAR_0);
}
break;
}
}
static void map_set_grass_length(int32_t x, int32_t y, rct_tile_element* tileElement, int32_t length)
{
int32_t oldLength = tileElement->properties.surface.grass_length & 0x7;
int32_t newLength = length & 0x7;
tileElement->properties.surface.grass_length = length;
if (newLength == oldLength)
{
return;
}
// If the new grass length won't result in an actual visual change
// then skip invalidating the tile, no point
if (((oldLength > 0 && oldLength < 4) && (newLength > 0 && newLength < 4))
|| ((oldLength > 3 && oldLength < 7) && (newLength > 3 && newLength < 7)))
{
return;
}
int32_t z = tileElement->base_height * 8;
map_invalidate_tile(x, y, z, z + 16);
}
void map_remove_provisional_elements()
{
if (gFootpathProvisionalFlags & PROVISIONAL_PATH_FLAG_1)
@ -3862,35 +3737,33 @@ void map_remove_out_of_range_elements()
*/
void map_extend_boundary_surface()
{
rct_tile_element *existingTileElement, *newTileElement;
SurfaceElement *existingTileElement, *newTileElement;
int32_t x, y, z, slope;
y = gMapSize - 2;
for (x = 0; x < MAXIMUM_MAP_SIZE_TECHNICAL; x++)
{
existingTileElement = map_get_surface_element_at(x, y - 1);
newTileElement = map_get_surface_element_at(x, y);
newTileElement->type = (newTileElement->type & 0x7C) | (existingTileElement->type & 0x83);
newTileElement->properties.surface.slope = existingTileElement->properties.surface.slope
& TILE_ELEMENT_SURFACE_EDGE_STYLE_MASK;
newTileElement->properties.surface.terrain = existingTileElement->properties.surface.terrain;
newTileElement->properties.surface.grass_length = existingTileElement->properties.surface.grass_length;
newTileElement->properties.surface.ownership = 0;
existingTileElement = map_get_surface_element_at(x, y - 1)->AsSurface();
newTileElement = map_get_surface_element_at(x, y)->AsSurface();
newTileElement->SetSurfaceStyle(existingTileElement->GetSurfaceStyle());
newTileElement->SetEdgeStyle(existingTileElement->GetEdgeStyle());
newTileElement->SetGrassLength(existingTileElement->GetGrassLength());
newTileElement->SetOwnership(OWNERSHIP_UNOWNED);
newTileElement->SetWaterHeight(existingTileElement->GetWaterHeight());
z = existingTileElement->base_height;
slope = existingTileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_NW_SIDE_UP;
slope = existingTileElement->GetSlope() & TILE_ELEMENT_SLOPE_NW_SIDE_UP;
if (slope == TILE_ELEMENT_SLOPE_NW_SIDE_UP)
{
z += 2;
slope = TILE_ELEMENT_SLOPE_FLAT;
if (existingTileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
if (existingTileElement->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
{
slope = TILE_ELEMENT_SLOPE_N_CORNER_UP;
if (existingTileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_S_CORNER_UP)
if (existingTileElement->GetSlope() & TILE_ELEMENT_SLOPE_S_CORNER_UP)
{
slope = TILE_ELEMENT_SLOPE_W_CORNER_UP;
if (existingTileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_E_CORNER_UP)
if (existingTileElement->GetSlope() & TILE_ELEMENT_SLOPE_E_CORNER_UP)
{
slope = TILE_ELEMENT_SLOPE_FLAT;
}
@ -3902,7 +3775,7 @@ void map_extend_boundary_surface()
if (slope & TILE_ELEMENT_SLOPE_W_CORNER_UP)
slope |= TILE_ELEMENT_SLOPE_S_CORNER_UP;
newTileElement->properties.surface.slope |= slope;
newTileElement->SetSlope(slope);
newTileElement->base_height = z;
newTileElement->clearance_height = z;
@ -3912,29 +3785,28 @@ void map_extend_boundary_surface()
x = gMapSize - 2;
for (y = 0; y < MAXIMUM_MAP_SIZE_TECHNICAL; y++)
{
existingTileElement = map_get_surface_element_at(x - 1, y);
newTileElement = map_get_surface_element_at(x, y);
existingTileElement = map_get_surface_element_at(x - 1, y)->AsSurface();
newTileElement = map_get_surface_element_at(x, y)->AsSurface();
newTileElement->type = (newTileElement->type & 0x7C) | (existingTileElement->type & 0x83);
newTileElement->properties.surface.slope = existingTileElement->properties.surface.slope
& TILE_ELEMENT_SURFACE_EDGE_STYLE_MASK;
newTileElement->properties.surface.terrain = existingTileElement->properties.surface.terrain;
newTileElement->properties.surface.grass_length = existingTileElement->properties.surface.grass_length;
newTileElement->properties.surface.ownership = 0;
newTileElement->SetSurfaceStyle(existingTileElement->GetSurfaceStyle());
newTileElement->SetEdgeStyle(existingTileElement->GetEdgeStyle());
newTileElement->SetGrassLength(existingTileElement->GetGrassLength());
newTileElement->SetOwnership(OWNERSHIP_UNOWNED);
newTileElement->SetWaterHeight(existingTileElement->GetWaterHeight());
z = existingTileElement->base_height;
slope = existingTileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_NE_SIDE_UP;
slope = existingTileElement->GetSlope() & TILE_ELEMENT_SLOPE_NE_SIDE_UP;
if (slope == TILE_ELEMENT_SLOPE_NE_SIDE_UP)
{
z += 2;
slope = TILE_ELEMENT_SLOPE_FLAT;
if (existingTileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
if (existingTileElement->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
{
slope = TILE_ELEMENT_SLOPE_N_CORNER_UP;
if (existingTileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_S_CORNER_UP)
if (existingTileElement->GetSlope() & TILE_ELEMENT_SLOPE_S_CORNER_UP)
{
slope = TILE_ELEMENT_SLOPE_E_CORNER_UP;
if (existingTileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_W_CORNER_UP)
if (existingTileElement->GetSlope() & TILE_ELEMENT_SLOPE_W_CORNER_UP)
{
slope = TILE_ELEMENT_SLOPE_FLAT;
}
@ -3946,7 +3818,7 @@ void map_extend_boundary_surface()
if (slope & TILE_ELEMENT_SLOPE_E_CORNER_UP)
slope |= TILE_ELEMENT_SLOPE_S_CORNER_UP;
newTileElement->properties.surface.slope |= slope;
newTileElement->SetSlope(slope);
newTileElement->base_height = z;
newTileElement->clearance_height = z;
@ -3966,17 +3838,20 @@ static void clear_element_at(int32_t x, int32_t y, rct_tile_element** elementPtr
case TILE_ELEMENT_TYPE_SURFACE:
element->base_height = 2;
element->clearance_height = 2;
element->properties.surface.slope = TILE_ELEMENT_SLOPE_FLAT;
element->properties.surface.terrain = 0;
element->properties.surface.grass_length = GRASS_LENGTH_CLEAR_0;
element->properties.surface.ownership = 0;
element->AsSurface()->SetSlope(TILE_ELEMENT_SLOPE_FLAT);
element->AsSurface()->SetSurfaceStyle(TERRAIN_GRASS);
element->AsSurface()->SetEdgeStyle(TERRAIN_EDGE_ROCK);
element->AsSurface()->SetGrassLength(GRASS_LENGTH_CLEAR_0);
element->AsSurface()->SetOwnership(OWNERSHIP_UNOWNED);
element->AsSurface()->SetParkFences(0);
element->AsSurface()->SetWaterHeight(0);
// Because this element is not completely removed, the pointer must be updated manually
// The rest of the elements are removed from the array, so the pointer doesn't need to be updated.
(*elementPtr)++;
break;
case TILE_ELEMENT_TYPE_ENTRANCE:
{
int32_t rotation = tile_element_get_direction_with_offset(element, 1);
int32_t rotation = element->GetDirectionWithOffset(1);
switch (element->properties.entrance.index & 0x0F)
{
case 1:
@ -4002,8 +3877,9 @@ static void clear_element_at(int32_t x, int32_t y, rct_tile_element** elementPtr
case TILE_ELEMENT_TYPE_LARGE_SCENERY:
gGameCommandErrorTitle = STR_CANT_REMOVE_THIS;
game_do_command(
x, (GAME_COMMAND_FLAG_APPLY) | (tile_element_get_direction(element) << 8), y,
(element->base_height) | (scenery_large_get_sequence(element) << 8), GAME_COMMAND_REMOVE_LARGE_SCENERY, 0, 0);
x, (GAME_COMMAND_FLAG_APPLY) | (element->GetDirection() << 8), y,
(element->base_height) | (element->AsLargeScenery()->GetSequenceIndex() << 8),
GAME_COMMAND_REMOVE_LARGE_SCENERY, 0, 0);
break;
case TILE_ELEMENT_TYPE_BANNER:
gGameCommandErrorTitle = STR_CANT_REMOVE_THIS;
@ -4046,7 +3922,7 @@ static void clear_elements_at(int32_t x, int32_t y)
int32_t map_get_highest_z(int32_t tileX, int32_t tileY)
{
rct_tile_element* tileElement;
int32_t z;
uint32_t z;
tileElement = map_get_surface_element_at(tileX, tileY);
if (tileElement == nullptr)
@ -4055,12 +3931,12 @@ int32_t map_get_highest_z(int32_t tileX, int32_t tileY)
z = tileElement->base_height * 8;
// Raise z so that is above highest point of land and water on tile
if ((tileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP) != TILE_ELEMENT_SLOPE_FLAT)
if ((tileElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP) != TILE_ELEMENT_SLOPE_FLAT)
z += 16;
if ((tileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT) != 0)
if ((tileElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT) != 0)
z += 16;
z = std::max(z, surface_get_water_height(tileElement) * 16);
z = std::max(z, tileElement->AsSurface()->GetWaterHeight() * 16);
return z;
}
@ -4077,9 +3953,9 @@ rct_tile_element* map_get_large_scenery_segment(int32_t x, int32_t y, int32_t z,
continue;
if (tileElement->base_height != z)
continue;
if (scenery_large_get_sequence(tileElement) != sequence)
if (tileElement->AsLargeScenery()->GetSequenceIndex() != sequence)
continue;
if ((tile_element_get_direction(tileElement)) != direction)
if ((tileElement->GetDirection()) != direction)
continue;
return tileElement;
@ -4197,7 +4073,7 @@ bool map_large_scenery_get_origin(
if (tileElement == nullptr)
return false;
sceneryEntry = get_large_scenery_entry(scenery_large_get_type(tileElement));
sceneryEntry = tileElement->AsLargeScenery()->GetEntry();
tile = &sceneryEntry->large_scenery.tiles[sequence];
offsetX = tile->x_offset;
@ -4230,7 +4106,7 @@ bool sign_set_colour(
return false;
}
sceneryEntry = get_large_scenery_entry(scenery_large_get_type(tileElement));
sceneryEntry = tileElement->AsLargeScenery()->GetEntry();
sceneryTiles = sceneryEntry->large_scenery.tiles;
// Iterate through each tile of the large scenery element
@ -4247,8 +4123,8 @@ bool sign_set_colour(
tileElement = map_get_large_scenery_segment(x, y, z, direction, sequence);
if (tileElement != nullptr)
{
scenery_large_set_primary_colour(tileElement, mainColour);
scenery_large_set_secondary_colour(tileElement, textColour);
tileElement->AsLargeScenery()->SetPrimaryColour(mainColour);
tileElement->AsLargeScenery()->SetSecondaryColour(textColour);
map_invalidate_tile(x, y, tileElement->base_height * 8, tileElement->clearance_height * 8);
}
@ -4438,14 +4314,14 @@ bool map_surface_is_blocked(int16_t x, int16_t y)
return true;
}
int16_t water_height = surface_get_water_height(tileElement);
int16_t water_height = tileElement->AsSurface()->GetWaterHeight();
water_height *= 2;
if (water_height > tileElement->base_height)
return true;
int16_t base_z = tileElement->base_height;
int16_t clear_z = tileElement->base_height + 2;
if (tileElement->properties.surface.slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
if (tileElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
clear_z += 2;
while (!(tileElement++)->IsLastForTile())
@ -4554,8 +4430,8 @@ void game_command_set_sign_style(
}
if (!sign_set_colour(
banner->x * 32, banner->y * 32, tileElement->base_height, tile_element_get_direction(tileElement),
scenery_large_get_sequence(tileElement), mainColour, textColour))
banner->x * 32, banner->y * 32, tileElement->base_height, tileElement->GetDirection(),
tileElement->AsLargeScenery()->GetSequenceIndex(), mainColour, textColour))
{
*ebx = MONEY32_UNDEFINED;
return;
@ -4872,7 +4748,7 @@ rct_tile_element* map_get_track_element_at_with_direction_from_ride(
continue;
if (track_element_get_ride_index(tileElement) != rideIndex)
continue;
if (tile_element_get_direction(tileElement) != direction)
if (tileElement->GetDirection() != direction)
continue;
return tileElement;
@ -4913,7 +4789,7 @@ rct_tile_element* map_get_wall_element_at(int32_t x, int32_t y, int32_t z, int32
continue;
if (tileElement->base_height != z)
continue;
if (tile_element_get_direction(tileElement) != direction)
if (tileElement->GetDirection() != direction)
continue;
return tileElement;
@ -4975,7 +4851,7 @@ void FixLandOwnershipTilesWithOwnership(std::initializer_list<TileCoordsXY> tile
for (const TileCoordsXY* tile = tiles.begin(); tile != tiles.end(); ++tile)
{
currentElement = map_get_surface_element_at((*tile).x, (*tile).y);
currentElement->properties.surface.ownership |= ownership;
currentElement->AsSurface()->SetOwnership(ownership);
update_park_fences_around_tile({ (*tile).x * 32, (*tile).y * 32 });
}
}

View File

@ -16,6 +16,7 @@
#include "../ride/Track.h"
#include "../world/Wall.h"
#include "Footpath.h"
#include "LargeScenery.h"
#include "Map.h"
#include "Scenery.h"
#include "SmallScenery.h"
@ -195,7 +196,7 @@ static bool map_animation_invalidate_small_scenery(int32_t x, int32_t y, int32_t
// Peep, looking at scenery
if (!(gCurrentTicks & 0x3FF) && game_is_not_paused())
{
int32_t direction = tile_element_get_direction(tileElement);
int32_t direction = tileElement->GetDirection();
int32_t x2 = x - CoordsDirectionDelta[direction].x;
int32_t y2 = y - CoordsDirectionDelta[direction].y;
@ -458,7 +459,7 @@ static bool map_animation_invalidate_large_scenery(int32_t x, int32_t y, int32_t
if (tileElement->GetType() != TILE_ELEMENT_TYPE_LARGE_SCENERY)
continue;
sceneryEntry = get_large_scenery_entry(tileElement->properties.scenerymultiple.type & 0x3FF);
sceneryEntry = tileElement->AsLargeScenery()->GetEntry();
if (sceneryEntry->large_scenery.flags & LARGE_SCENERY_FLAG_ANIMATED)
{
int32_t z = tileElement->base_height * 8;

View File

@ -121,8 +121,8 @@ void mapgen_generate_blank(mapgen_settings* settings)
for (x = 1; x < settings->mapSize - 1; x++)
{
tileElement = map_get_surface_element_at(x, y);
surface_set_terrain(tileElement, settings->floor);
surface_set_terrain_edge(tileElement, settings->wall);
tileElement->AsSurface()->SetSurfaceStyle(settings->floor);
tileElement->AsSurface()->SetEdgeStyle(settings->wall);
tileElement->base_height = settings->height;
tileElement->clearance_height = settings->height;
}
@ -172,8 +172,8 @@ void mapgen_generate(mapgen_settings* settings)
for (x = 1; x < mapSize - 1; x++)
{
tileElement = map_get_surface_element_at(x, y);
surface_set_terrain(tileElement, floorTexture);
surface_set_terrain_edge(tileElement, wallTexture);
tileElement->AsSurface()->SetSurfaceStyle(floorTexture);
tileElement->AsSurface()->SetEdgeStyle(wallTexture);
tileElement->base_height = settings->height;
tileElement->clearance_height = settings->height;
}
@ -220,7 +220,7 @@ void mapgen_generate(mapgen_settings* settings)
tileElement = map_get_surface_element_at(x, y);
if (tileElement->base_height < waterLevel + 6)
surface_set_terrain(tileElement, beachTexture);
tileElement->AsSurface()->SetSurfaceStyle(beachTexture);
}
}
@ -317,7 +317,7 @@ static void mapgen_place_trees()
rct_tile_element* tileElement = map_get_surface_element_at(x, y);
// Exclude water tiles
if (surface_get_water_height(tileElement) > 0)
if (tileElement->AsSurface()->GetWaterHeight() > 0)
continue;
pos.x = x;
@ -349,7 +349,7 @@ static void mapgen_place_trees()
int32_t type = -1;
rct_tile_element* tileElement = map_get_surface_element_at(pos.x, pos.y);
switch (surface_get_terrain(tileElement))
switch (tileElement->AsSurface()->GetSurfaceStyle())
{
case TERRAIN_GRASS:
case TERRAIN_DIRT:
@ -399,7 +399,7 @@ static void mapgen_set_water_level(int32_t waterLevel)
{
tileElement = map_get_surface_element_at(x, y);
if (tileElement->base_height < waterLevel)
tileElement->properties.surface.terrain |= (waterLevel / 2);
tileElement->AsSurface()->SetWaterHeight(waterLevel / 2);
}
}
}
@ -464,14 +464,18 @@ static void mapgen_set_height()
tileElement->base_height = std::max(2, baseHeight * 2);
tileElement->clearance_height = tileElement->base_height;
uint8_t currentSlope = tileElement->AsSurface()->GetSlope();
if (q00 > baseHeight)
tileElement->properties.surface.slope |= TILE_ELEMENT_SLOPE_S_CORNER_UP;
currentSlope |= TILE_ELEMENT_SLOPE_S_CORNER_UP;
if (q01 > baseHeight)
tileElement->properties.surface.slope |= TILE_ELEMENT_SLOPE_W_CORNER_UP;
currentSlope |= TILE_ELEMENT_SLOPE_W_CORNER_UP;
if (q10 > baseHeight)
tileElement->properties.surface.slope |= TILE_ELEMENT_SLOPE_E_CORNER_UP;
currentSlope |= TILE_ELEMENT_SLOPE_E_CORNER_UP;
if (q11 > baseHeight)
tileElement->properties.surface.slope |= TILE_ELEMENT_SLOPE_N_CORNER_UP;
currentSlope |= TILE_ELEMENT_SLOPE_N_CORNER_UP;
tileElement->AsSurface()->SetSlope(currentSlope);
}
}
}
@ -830,7 +834,7 @@ void mapgen_generate_from_heightmap(mapgen_settings* settings)
// Set water level
if (surfaceElement->base_height < settings->water_level)
{
surfaceElement->properties.surface.terrain |= settings->water_level / 2;
surfaceElement->AsSurface()->SetWaterHeight(settings->water_level / 2);
}
}
}

View File

@ -27,7 +27,7 @@ int32_t map_smooth(int32_t l, int32_t t, int32_t r, int32_t b)
for (x = l; x < r; x++)
{
tileElement = map_get_surface_element_at(x, y);
tileElement->properties.surface.slope &= ~TILE_ELEMENT_SURFACE_SLOPE_MASK;
tileElement->AsSurface()->SetSlope(TILE_ELEMENT_SLOPE_FLAT);
// Raise to edge height - 2
highest = tileElement->base_height;
@ -125,65 +125,68 @@ int32_t map_smooth(int32_t l, int32_t t, int32_t r, int32_t b)
if (doubleCorner != -1)
{
tileElement->properties.surface.slope |= TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT;
uint8_t slope = tileElement->AsSurface()->GetSlope() | TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT;
switch (doubleCorner)
{
case 0:
tileElement->properties.surface.slope |= TILE_ELEMENT_SLOPE_N_CORNER_DN;
slope |= TILE_ELEMENT_SLOPE_N_CORNER_DN;
break;
case 1:
tileElement->properties.surface.slope |= TILE_ELEMENT_SLOPE_W_CORNER_DN;
slope |= TILE_ELEMENT_SLOPE_W_CORNER_DN;
break;
case 2:
tileElement->properties.surface.slope |= TILE_ELEMENT_SLOPE_S_CORNER_DN;
slope |= TILE_ELEMENT_SLOPE_S_CORNER_DN;
break;
case 3:
tileElement->properties.surface.slope |= TILE_ELEMENT_SLOPE_E_CORNER_DN;
slope |= TILE_ELEMENT_SLOPE_E_CORNER_DN;
break;
}
tileElement->AsSurface()->SetSlope(slope);
}
else
{
uint8_t slope = tileElement->AsSurface()->GetSlope();
// Corners
tileElement2 = map_get_surface_element_at(x + 1, y + 1);
if (tileElement2->base_height > tileElement->base_height)
tileElement->properties.surface.slope |= TILE_ELEMENT_SLOPE_N_CORNER_UP;
slope |= TILE_ELEMENT_SLOPE_N_CORNER_UP;
tileElement2 = map_get_surface_element_at(x - 1, y + 1);
if (tileElement2->base_height > tileElement->base_height)
tileElement->properties.surface.slope |= TILE_ELEMENT_SLOPE_W_CORNER_UP;
slope |= TILE_ELEMENT_SLOPE_W_CORNER_UP;
tileElement2 = map_get_surface_element_at(x + 1, y - 1);
if (tileElement2->base_height > tileElement->base_height)
tileElement->properties.surface.slope |= TILE_ELEMENT_SLOPE_E_CORNER_UP;
slope |= TILE_ELEMENT_SLOPE_E_CORNER_UP;
tileElement2 = map_get_surface_element_at(x - 1, y - 1);
if (tileElement2->base_height > tileElement->base_height)
tileElement->properties.surface.slope |= TILE_ELEMENT_SLOPE_S_CORNER_UP;
slope |= TILE_ELEMENT_SLOPE_S_CORNER_UP;
// Sides
tileElement2 = map_get_surface_element_at(x + 1, y + 0);
if (tileElement2->base_height > tileElement->base_height)
tileElement->properties.surface.slope |= TILE_ELEMENT_SLOPE_NE_SIDE_UP;
slope |= TILE_ELEMENT_SLOPE_NE_SIDE_UP;
tileElement2 = map_get_surface_element_at(x - 1, y + 0);
if (tileElement2->base_height > tileElement->base_height)
tileElement->properties.surface.slope |= TILE_ELEMENT_SLOPE_SW_SIDE_UP;
slope |= TILE_ELEMENT_SLOPE_SW_SIDE_UP;
tileElement2 = map_get_surface_element_at(x + 0, y - 1);
if (tileElement2->base_height > tileElement->base_height)
tileElement->properties.surface.slope |= TILE_ELEMENT_SLOPE_SE_SIDE_UP;
slope |= TILE_ELEMENT_SLOPE_SE_SIDE_UP;
tileElement2 = map_get_surface_element_at(x + 0, y + 1);
if (tileElement2->base_height > tileElement->base_height)
tileElement->properties.surface.slope |= TILE_ELEMENT_SLOPE_NW_SIDE_UP;
slope |= TILE_ELEMENT_SLOPE_NW_SIDE_UP;
// Raise
if (tileElement->properties.surface.slope == TILE_ELEMENT_SLOPE_ALL_CORNERS_UP)
if (slope == TILE_ELEMENT_SLOPE_ALL_CORNERS_UP)
{
tileElement->properties.surface.slope &= ~TILE_ELEMENT_SURFACE_SLOPE_MASK;
slope = TILE_ELEMENT_SLOPE_FLAT;
tileElement->base_height = tileElement->clearance_height += 2;
}
tileElement->AsSurface()->SetSlope(slope);
}
}
}
@ -274,28 +277,27 @@ int32_t tile_smooth(int32_t x, int32_t y)
}
// Check if the calculated slope is the same already
uint8_t currentSlope = surfaceElement->properties.surface.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK;
uint8_t currentSlope = surfaceElement->AsSurface()->GetSlope();
if (currentSlope == slope)
{
return 0;
}
// Remove old slope value
surfaceElement->properties.surface.slope &= ~TILE_ELEMENT_SURFACE_SLOPE_MASK;
if ((slope & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP) == TILE_ELEMENT_SLOPE_ALL_CORNERS_UP)
{
// All corners are raised, raise the entire tile instead.
surfaceElement->AsSurface()->SetSlope(TILE_ELEMENT_SLOPE_FLAT);
surfaceElement->base_height = (surfaceElement->clearance_height += 2);
uint8_t waterHeight = surface_get_water_height(surfaceElement) * 2;
uint8_t waterHeight = surfaceElement->AsSurface()->GetWaterHeight() * 2;
if (waterHeight <= surfaceElement->base_height)
{
surfaceElement->properties.surface.terrain &= ~TILE_ELEMENT_SURFACE_WATER_HEIGHT_MASK;
surfaceElement->AsSurface()->SetWaterHeight(0);
}
}
else
{
// Apply the slope to this tile
surfaceElement->properties.surface.slope |= slope;
surfaceElement->AsSurface()->SetSlope(slope);
// Set correct clearance height
if (slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)

View File

@ -173,8 +173,8 @@ void update_park_fences(const CoordsXY coords)
if (surfaceElement == nullptr)
return;
uint8_t newOwnership = surfaceElement->properties.surface.ownership & 0xF0;
if ((surfaceElement->properties.surface.ownership & OWNERSHIP_OWNED) == 0)
uint8_t newFences = 0;
if ((surfaceElement->AsSurface()->GetOwnership() & OWNERSHIP_OWNED) == 0)
{
bool fenceRequired = true;
@ -202,34 +202,34 @@ void update_park_fences(const CoordsXY coords)
rct_string_id previous_error = gGameCommandErrorText;
if (map_is_location_in_park({ coords.x - 32, coords.y }))
{
newOwnership |= 0x8;
newFences |= 0x8;
}
if (map_is_location_in_park({ coords.x, coords.y - 32 }))
{
newOwnership |= 0x4;
newFences |= 0x4;
}
if (map_is_location_in_park({ coords.x + 32, coords.y }))
{
newOwnership |= 0x2;
newFences |= 0x2;
}
if (map_is_location_in_park({ coords.x, coords.y + 32 }))
{
newOwnership |= 0x1;
newFences |= 0x1;
}
gGameCommandErrorText = previous_error;
}
}
if (surfaceElement->properties.surface.ownership != newOwnership)
if (surfaceElement->AsSurface()->GetParkFences() != newFences)
{
int32_t z0 = surfaceElement->base_height * 8;
int32_t z1 = z0 + 16;
map_invalidate_tile(coords.x, coords.y, z0, z1);
surfaceElement->properties.surface.ownership = newOwnership;
surfaceElement->AsSurface()->SetParkFences(newFences);
}
}
@ -254,45 +254,46 @@ void park_set_name(const char* name)
static money32 map_buy_land_rights_for_tile(int32_t x, int32_t y, int32_t setting, int32_t flags)
{
rct_tile_element* surfaceElement = map_get_surface_element_at({ x, y });
SurfaceElement* surfaceElement = map_get_surface_element_at({ x, y })->AsSurface();
if (surfaceElement == nullptr)
return MONEY32_UNDEFINED;
switch (setting)
{
case BUY_LAND_RIGHTS_FLAG_BUY_LAND: // 0
if ((surfaceElement->properties.surface.ownership & OWNERSHIP_OWNED) != 0)
if ((surfaceElement->GetOwnership() & OWNERSHIP_OWNED) != 0)
{ // If the land is already owned
return 0;
}
if ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) != 0
|| (surfaceElement->properties.surface.ownership & OWNERSHIP_AVAILABLE) == 0)
|| (surfaceElement->GetOwnership() & OWNERSHIP_AVAILABLE) == 0)
{
gGameCommandErrorText = STR_LAND_NOT_FOR_SALE;
return MONEY32_UNDEFINED;
}
if (flags & GAME_COMMAND_FLAG_APPLY)
{
surfaceElement->properties.surface.ownership |= OWNERSHIP_OWNED;
surfaceElement->SetOwnership(OWNERSHIP_OWNED);
update_park_fences_around_tile({ x, y });
}
return gLandPrice;
case BUY_LAND_RIGHTS_FLAG_UNOWN_TILE: // 1
if (flags & GAME_COMMAND_FLAG_APPLY)
{
surfaceElement->properties.surface.ownership &= ~(OWNERSHIP_OWNED | OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED);
surfaceElement->SetOwnership(
surfaceElement->GetOwnership() & ~(OWNERSHIP_OWNED | OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED));
update_park_fences_around_tile({ x, y });
}
return 0;
case BUY_LAND_RIGHTS_FLAG_BUY_CONSTRUCTION_RIGHTS: // 2
if ((surfaceElement->properties.surface.ownership & (OWNERSHIP_OWNED | OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)) != 0)
if ((surfaceElement->GetOwnership() & (OWNERSHIP_OWNED | OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED)) != 0)
{ // If the land or construction rights are already owned
return 0;
}
if ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) != 0
|| (surfaceElement->properties.surface.ownership & OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE) == 0)
|| (surfaceElement->GetOwnership() & OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE) == 0)
{
gGameCommandErrorText = STR_CONSTRUCTION_RIGHTS_NOT_FOR_SALE;
return MONEY32_UNDEFINED;
@ -300,7 +301,7 @@ static money32 map_buy_land_rights_for_tile(int32_t x, int32_t y, int32_t settin
if (flags & GAME_COMMAND_FLAG_APPLY)
{
surfaceElement->properties.surface.ownership |= OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED;
surfaceElement->SetOwnership(surfaceElement->GetOwnership() | OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED);
uint16_t baseHeight = surfaceElement->base_height * 8;
map_invalidate_tile(x, y, baseHeight, baseHeight + 16);
}
@ -308,7 +309,7 @@ static money32 map_buy_land_rights_for_tile(int32_t x, int32_t y, int32_t settin
case BUY_LAND_RIGHTS_FLAG_UNOWN_CONSTRUCTION_RIGHTS: // 3
if (flags & GAME_COMMAND_FLAG_APPLY)
{
surfaceElement->properties.surface.ownership &= ~OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED;
surfaceElement->SetOwnership(surfaceElement->GetOwnership() & ~OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED);
uint16_t baseHeight = surfaceElement->base_height * 8;
map_invalidate_tile(x, y, baseHeight, baseHeight + 16);
}
@ -316,7 +317,7 @@ static money32 map_buy_land_rights_for_tile(int32_t x, int32_t y, int32_t settin
case BUY_LAND_RIGHTS_FLAG_SET_FOR_SALE: // 4
if (flags & GAME_COMMAND_FLAG_APPLY)
{
surfaceElement->properties.surface.ownership |= OWNERSHIP_AVAILABLE;
surfaceElement->SetOwnership(surfaceElement->GetOwnership() | OWNERSHIP_AVAILABLE);
uint16_t baseHeight = surfaceElement->base_height * 8;
map_invalidate_tile(x, y, baseHeight, baseHeight + 16);
}
@ -324,7 +325,7 @@ static money32 map_buy_land_rights_for_tile(int32_t x, int32_t y, int32_t settin
case BUY_LAND_RIGHTS_FLAG_SET_CONSTRUCTION_RIGHTS_FOR_SALE: // 5
if (flags & GAME_COMMAND_FLAG_APPLY)
{
surfaceElement->properties.surface.ownership |= OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE;
surfaceElement->SetOwnership(surfaceElement->GetOwnership() | OWNERSHIP_CONSTRUCTION_RIGHTS_AVAILABLE);
uint16_t baseHeight = surfaceElement->base_height * 8;
map_invalidate_tile(x, y, baseHeight, baseHeight + 16);
}
@ -349,7 +350,7 @@ static money32 map_buy_land_rights_for_tile(int32_t x, int32_t y, int32_t settin
}
uint8_t newOwnership = (flags & 0xFF00) >> 4;
if (newOwnership == (surfaceElement->properties.surface.ownership & 0xF0))
if (newOwnership == surfaceElement->GetOwnership())
{
return 0;
}
@ -392,8 +393,7 @@ static money32 map_buy_land_rights_for_tile(int32_t x, int32_t y, int32_t settin
}
}
}
surfaceElement->properties.surface.ownership &= 0x0F;
surfaceElement->properties.surface.ownership |= newOwnership;
surfaceElement->SetOwnership(newOwnership);
update_park_fences_around_tile({ x, y });
gMapLandRightsUpdateSuccess = true;
return 0;
@ -637,7 +637,7 @@ int32_t Park::CalculateParkSize() const
{
if (it.element->GetType() == TILE_ELEMENT_TYPE_SURFACE)
{
if (it.element->properties.surface.ownership & (OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED | OWNERSHIP_OWNED))
if (it.element->AsSurface()->GetOwnership() & (OWNERSHIP_CONSTRUCTION_RIGHTS_OWNED | OWNERSHIP_OWNED))
{
tiles++;
}

View File

@ -78,7 +78,7 @@ void scenery_update_tile(int32_t x, int32_t y)
// as that may lead to a desync.
if (network_get_mode() != NETWORK_MODE_NONE)
{
if (tile_element_is_ghost(tileElement))
if (tileElement->IsGhost())
continue;
}
@ -142,7 +142,7 @@ void scenery_update_age(int32_t x, int32_t y, rct_tile_element* tileElement)
// Ghosts are purely this-client-side and should not cause any interaction,
// as that may lead to a desync.
if (tile_element_is_ghost(tileElementAbove))
if (tileElementAbove->IsGhost())
continue;
switch (tileElementAbove->GetType())
@ -231,18 +231,6 @@ void scenery_remove_ghost_tool_placement()
}
}
rct_scenery_entry* get_large_scenery_entry(int32_t entryIndex)
{
rct_scenery_entry* result = nullptr;
auto& objMgr = OpenRCT2::GetContext()->GetObjectManager();
auto obj = objMgr.GetLoadedObject(OBJECT_TYPE_LARGE_SCENERY, entryIndex);
if (obj != nullptr)
{
result = (rct_scenery_entry*)obj->GetLegacyData();
}
return result;
}
rct_scenery_entry* get_wall_entry(int32_t entryIndex)
{
rct_scenery_entry* result = nullptr;

View File

@ -300,7 +300,6 @@ void scenery_update_age(int32_t x, int32_t y, rct_tile_element* tileElement);
void scenery_set_default_placement_configuration();
void scenery_remove_ghost_tool_placement();
rct_scenery_entry* get_large_scenery_entry(int32_t entryIndex);
rct_scenery_entry* get_wall_entry(int32_t entryIndex);
rct_scenery_entry* get_banner_entry(int32_t entryIndex);
rct_scenery_entry* get_footpath_item_entry(int32_t entryIndex);

View File

@ -154,7 +154,7 @@ static money32 SmallScenerySetColour(
}
static money32 SmallSceneryPlace(
int16_t x, int16_t y, int16_t targetHeight, uint8_t quadrant, uint8_t rotation, uint8_t sceneryType, uint8_t primaryColour,
int16_t x, int16_t y, uint16_t targetHeight, uint8_t quadrant, uint8_t rotation, uint8_t sceneryType, uint8_t primaryColour,
uint8_t secondaryColour, uint8_t flags)
{
gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING;
@ -260,9 +260,9 @@ static money32 SmallSceneryPlace(
rct_tile_element* surfaceElement = map_get_surface_element_at({ x, y });
if (surfaceElement != nullptr && !gCheatsDisableClearanceChecks && surface_get_water_height(surfaceElement) > 0)
if (surfaceElement != nullptr && !gCheatsDisableClearanceChecks && surfaceElement->AsSurface()->GetWaterHeight() > 0)
{
int32_t water_height = (surface_get_water_height(surfaceElement) * 16) - 1;
int32_t water_height = (surfaceElement->AsSurface()->GetWaterHeight() * 16) - 1;
if (water_height > targetHeight)
{
gGameCommandErrorText = STR_CANT_BUILD_THIS_UNDERWATER;
@ -278,9 +278,9 @@ static money32 SmallSceneryPlace(
return MONEY32_UNDEFINED;
}
if (surfaceElement != nullptr && surface_get_water_height(surfaceElement) > 0)
if (surfaceElement != nullptr && surfaceElement->AsSurface()->GetWaterHeight() > 0)
{
if ((surface_get_water_height(surfaceElement) * 16) > targetHeight)
if ((surfaceElement->AsSurface()->GetWaterHeight() * 16) > targetHeight)
{
gGameCommandErrorText = STR_CAN_ONLY_BUILD_THIS_ON_LAND;
return MONEY32_UNDEFINED;
@ -290,7 +290,7 @@ static money32 SmallSceneryPlace(
if (!gCheatsDisableClearanceChecks && (scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_REQUIRE_FLAT_SURFACE))
&& !supportsRequired && !isOnWater && surfaceElement != nullptr
&& (surfaceElement->properties.surface.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK))
&& (surfaceElement->AsSurface()->GetSlope() != TILE_ELEMENT_SLOPE_FLAT))
{
gGameCommandErrorText = STR_LEVEL_LAND_REQUIRED;
return MONEY32_UNDEFINED;
@ -303,7 +303,7 @@ static money32 SmallSceneryPlace(
{
if (surfaceElement != nullptr)
{
if (surface_get_water_height(surfaceElement) || (surfaceElement->base_height * 8) != targetHeight)
if (surfaceElement->AsSurface()->GetWaterHeight() || (surfaceElement->base_height * 8) != targetHeight)
{
gGameCommandErrorText = STR_LEVEL_LAND_REQUIRED;
return MONEY32_UNDEFINED;

View File

@ -9,49 +9,209 @@
#include "Surface.h"
int32_t surface_get_terrain(const rct_tile_element* element)
#include "../scenario/Scenario.h"
#include "Location.hpp"
#include "Map.h"
uint32_t SurfaceElement::GetSurfaceStyle() const
{
int32_t terrain = (element->properties.surface.terrain >> 5) & 7;
if (element->type & 1)
terrain |= (1 << 3);
return terrain;
uint32_t retVal = (terrain >> 5) & 7;
if (type & 1)
retVal |= (1 << 3);
return retVal;
}
int32_t surface_get_terrain_edge(const rct_tile_element* element)
uint32_t SurfaceElement::GetEdgeStyle() const
{
int32_t terrain_edge = (element->properties.surface.slope >> 5) & 7;
if (element->type & 128)
uint32_t terrain_edge = (slope >> 5) & 7;
if (type & 128)
terrain_edge |= (1 << 3);
return terrain_edge;
}
void surface_set_terrain(rct_tile_element* element, int32_t terrain)
void SurfaceElement::SetSurfaceStyle(uint32_t newStyle)
{
// Bit 3 for terrain is stored in element.type bit 0
if (terrain & 8)
element->type |= 1;
if (newStyle & 8)
type |= 1;
else
element->type &= ~1;
type &= ~1;
// Bits 0, 1, 2 for terrain are stored in element.terrain bit 5, 6, 7
element->properties.surface.terrain &= ~0xE0;
element->properties.surface.terrain |= (terrain & 7) << 5;
terrain &= ~0xE0;
terrain |= (newStyle & 7) << 5;
}
void surface_set_terrain_edge(rct_tile_element* element, int32_t terrain)
void SurfaceElement::SetEdgeStyle(uint32_t newStyle)
{
// Bit 3 for terrain is stored in element.type bit 7
if (terrain & 8)
element->type |= 128;
if (newStyle & 8)
type |= 128;
else
element->type &= ~128;
type &= ~128;
// Bits 0, 1, 2 for terrain are stored in element.slope bit 5, 6, 7
element->properties.surface.slope &= ~TILE_ELEMENT_SURFACE_EDGE_STYLE_MASK;
element->properties.surface.slope |= (terrain & 7) << 5;
slope &= ~TILE_ELEMENT_SURFACE_EDGE_STYLE_MASK;
slope |= (newStyle & 7) << 5;
}
int32_t surface_get_water_height(const rct_tile_element* tileElement)
uint32_t SurfaceElement::GetWaterHeight() const
{
return tileElement->properties.surface.terrain & TILE_ELEMENT_SURFACE_WATER_HEIGHT_MASK;
return terrain & TILE_ELEMENT_SURFACE_WATER_HEIGHT_MASK;
}
void SurfaceElement::SetWaterHeight(uint32_t newWaterHeight)
{
newWaterHeight &= 0x1F;
terrain &= ~TILE_ELEMENT_SURFACE_WATER_HEIGHT_MASK;
terrain |= newWaterHeight;
}
uint8_t SurfaceElement::GetGrassLength() const
{
return grass_length;
}
void SurfaceElement::SetGrassLength(uint8_t newLength)
{
grass_length = newLength;
}
void SurfaceElement::SetGrassLengthAndInvalidate(uint8_t length, CoordsXY coords)
{
uint8_t oldLength = grass_length & 0x7;
uint8_t newLength = length & 0x7;
grass_length = length;
if (newLength == oldLength)
{
return;
}
// If the new grass length won't result in an actual visual change
// then skip invalidating the tile, no point
if (((oldLength > 0 && oldLength < 4) && (newLength > 0 && newLength < 4))
|| ((oldLength > 3 && oldLength < 7) && (newLength > 3 && newLength < 7)))
{
return;
}
int32_t z = base_height * 8;
map_invalidate_tile(coords.x, coords.y, z, z + 16);
}
/**
*
* rct2: 0x006647A1
*/
void SurfaceElement::UpdateGrassLength(CoordsXY coords)
{
// Check if tile is grass
if (GetSurfaceStyle() != TERRAIN_GRASS)
return;
uint8_t grassLengthTmp = grass_length & 7;
// Check if grass is underwater or outside park
uint32_t waterHeight = GetWaterHeight() * 2;
if (waterHeight > base_height || !map_is_location_in_park(coords))
{
if (grassLengthTmp != GRASS_LENGTH_CLEAR_0)
SetGrassLengthAndInvalidate(GRASS_LENGTH_CLEAR_0, coords);
return;
}
// Grass can't grow any further than CLUMPS_2 but this code also cuts grass
// if there is an object placed on top of it.
int32_t z0 = base_height;
int32_t z1 = base_height + 2;
if (slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
z1 += 2;
// Check objects above grass
rct_tile_element* tileElementAbove = (rct_tile_element*)this;
for (;;)
{
if (tileElementAbove->flags & TILE_ELEMENT_FLAG_LAST_TILE)
{
// Grow grass
// Check interim grass lengths
uint8_t lengthNibble = (GetGrassLength() & 0xF0) >> 4;
if (lengthNibble < 0xF)
{
grass_length += 0x10;
}
else
{
// Zeros the length nibble
grass_length += 0x10;
grass_length ^= 8;
if (grass_length & 8)
{
// Random growth rate (length nibble)
grass_length |= scenario_rand() & 0x70;
}
else
{
// Increase length if not at max length
if (grassLengthTmp != GRASS_LENGTH_CLUMPS_2)
SetGrassLengthAndInvalidate(grassLengthTmp + 1, coords);
}
}
}
else
{
tileElementAbove++;
if (tileElementAbove->GetType() == TILE_ELEMENT_TYPE_WALL)
continue;
// Grass should not be affected by ghost elements.
if (tileElementAbove->IsGhost())
continue;
if (z0 >= tileElementAbove->clearance_height)
continue;
if (z1 < tileElementAbove->base_height)
continue;
if (grassLengthTmp != GRASS_LENGTH_CLEAR_0)
SetGrassLengthAndInvalidate(GRASS_LENGTH_CLEAR_0, coords);
}
break;
}
}
uint8_t SurfaceElement::GetOwnership() const
{
return (ownership & TILE_ELEMENT_SURFACE_OWNERSHIP_MASK);
}
void SurfaceElement::SetOwnership(uint8_t newOwnership)
{
ownership &= ~TILE_ELEMENT_SURFACE_OWNERSHIP_MASK;
ownership |= (newOwnership & TILE_ELEMENT_SURFACE_OWNERSHIP_MASK);
}
uint8_t SurfaceElement::GetParkFences() const
{
return (ownership & TILE_ELEMENT_SURFACE_PARK_FENCE_MASK);
}
void SurfaceElement::SetParkFences(uint8_t newParkFences)
{
ownership &= ~TILE_ELEMENT_SURFACE_PARK_FENCE_MASK;
ownership |= (newParkFences & TILE_ELEMENT_SURFACE_PARK_FENCE_MASK);
}
uint8_t SurfaceElement::GetSlope() const
{
return (slope & TILE_ELEMENT_SURFACE_SLOPE_MASK);
}
void SurfaceElement::SetSlope(uint8_t newSlope)
{
slope &= ~TILE_ELEMENT_SURFACE_SLOPE_MASK;
slope |= (newSlope & TILE_ELEMENT_SURFACE_SLOPE_MASK);
}

View File

@ -108,14 +108,9 @@ enum
#define TILE_ELEMENT_SURFACE_SLOPE_MASK \
(TILE_ELEMENT_SURFACE_DIAGONAL_FLAG \
| TILE_ELEMENT_SURFACE_RAISED_CORNERS_MASK) // in rct_tile_element.properties.surface.slope
#define TILE_ELEMENT_SURFACE_EDGE_STYLE_MASK 0xE0 // in rct_tile_tile_element_set_terrainelement.properties.surface.slope
#define TILE_ELEMENT_SURFACE_EDGE_STYLE_MASK 0xE0 // in rct_tile_element.properties.surface.slope
#define TILE_ELEMENT_SURFACE_WATER_HEIGHT_MASK 0x1F // in rct_tile_element.properties.surface.terrain
#define TILE_ELEMENT_SURFACE_TERRAIN_MASK 0xE0 // in rct_tile_element.properties.surface.terrain
int32_t surface_get_terrain(const rct_tile_element* element);
int32_t surface_get_terrain_edge(const rct_tile_element* element);
void surface_set_terrain(rct_tile_element* element, int32_t terrain);
void surface_set_terrain_edge(rct_tile_element* element, int32_t terrain);
// ~Oli414: Needs to renamed. This function is specific to the surface object.
int32_t surface_get_water_height(const rct_tile_element* tileElement);
#define TILE_ELEMENT_SURFACE_OWNERSHIP_MASK 0xF0
#define TILE_ELEMENT_SURFACE_PARK_FENCE_MASK 0x0F

View File

@ -59,21 +59,6 @@ uint8_t WallElement::GetSlope() const
return (this->type & TILE_ELEMENT_QUADRANT_MASK) >> 6;
}
int32_t tile_element_get_direction(const rct_tile_element* element)
{
return element->GetDirection();
}
int32_t tile_element_get_direction_with_offset(const rct_tile_element* element, uint8_t offset)
{
return element->GetDirectionWithOffset(offset);
}
bool tile_element_is_ghost(const rct_tile_element* element)
{
return element->IsGhost();
}
bool tile_element_is_underground(rct_tile_element* tileElement)
{
do
@ -92,11 +77,11 @@ BannerIndex tile_element_get_banner_index(rct_tile_element* tileElement)
switch (tileElement->GetType())
{
case TILE_ELEMENT_TYPE_LARGE_SCENERY:
sceneryEntry = get_large_scenery_entry(scenery_large_get_type(tileElement));
sceneryEntry = tileElement->AsLargeScenery()->GetEntry();
if (sceneryEntry->large_scenery.scrolling_mode == 0xFF)
return BANNER_INDEX_NULL;
return scenery_large_get_banner_id(tileElement);
return tileElement->AsLargeScenery()->GetBannerIndex();
case TILE_ELEMENT_TYPE_WALL:
sceneryEntry = get_wall_entry(tileElement->properties.wall.type);
if (sceneryEntry == nullptr || sceneryEntry->wall.scrolling_mode == 0xFF)
@ -118,7 +103,7 @@ void tile_element_set_banner_index(rct_tile_element* tileElement, BannerIndex ba
tileElement->properties.wall.banner_index = bannerIndex;
break;
case TILE_ELEMENT_TYPE_LARGE_SCENERY:
scenery_large_set_banner_id(tileElement, bannerIndex);
tileElement->AsLargeScenery()->SetBannerIndex(bannerIndex);
break;
case TILE_ELEMENT_TYPE_BANNER:
tileElement->properties.banner.index = bannerIndex;

View File

@ -10,19 +10,11 @@
#pragma once
#include "../common.h"
#include "Location.hpp"
struct rct_scenery_entry;
#pragma pack(push, 1)
struct rct_tile_element_surface_properties
{
uint8_t slope; // 4 0xE0 Edge Style, 0x1F Slope
uint8_t terrain; // 5 0xE0 Terrain Style, 0x1F Water height
uint8_t grass_length; // 6
uint8_t ownership; // 7
};
assert_struct_size(rct_tile_element_surface_properties, 4);
struct rct_tile_element_path_properties
{
uint8_t type; // 4 0xF0 Path type, 0x08 Ride sign, 0x04 Set when path is diagonal, 0x03 Rotation
@ -85,13 +77,6 @@ struct rct_tile_element_wall_properties
};
assert_struct_size(rct_tile_element_wall_properties, 4);
struct rct_tile_element_scenerymultiple_properties
{
uint16_t type; // 4
uint8_t colour[2]; // 6
};
assert_struct_size(rct_tile_element_scenerymultiple_properties, 4);
struct rct_tile_element_banner_properties
{
BannerIndex index; // 4
@ -103,12 +88,10 @@ assert_struct_size(rct_tile_element_banner_properties, 4);
union rct_tile_element_properties
{
rct_tile_element_surface_properties surface;
rct_tile_element_path_properties path;
rct_tile_element_track_properties track;
rct_tile_element_entrance_properties entrance;
rct_tile_element_wall_properties wall;
rct_tile_element_scenerymultiple_properties scenerymultiple;
rct_tile_element_banner_properties banner;
};
assert_struct_size(rct_tile_element_properties, 4);
@ -223,7 +206,33 @@ assert_struct_size(rct_tile_element, 8);
struct SurfaceElement : TileElementBase
{
rct_tile_element_surface_properties temp;
private:
uint8_t slope; // 4 0xE0 Edge Style, 0x1F Slope
uint8_t terrain; // 5 0xE0 Terrain Style, 0x1F Water height
uint8_t grass_length; // 6
uint8_t ownership; // 7
public:
uint8_t GetSlope() const;
void SetSlope(uint8_t newSlope);
uint32_t GetSurfaceStyle() const;
void SetSurfaceStyle(uint32_t newStyle);
uint32_t GetEdgeStyle() const;
void SetEdgeStyle(uint32_t newStyle);
uint8_t GetGrassLength() const;
void SetGrassLength(uint8_t newLength);
void SetGrassLengthAndInvalidate(uint8_t newLength, CoordsXY coords);
void UpdateGrassLength(CoordsXY coords);
uint8_t GetOwnership() const;
void SetOwnership(uint8_t newOwnership);
uint32_t GetWaterHeight() const;
void SetWaterHeight(uint32_t newWaterHeight);
uint8_t GetParkFences() const;
void SetParkFences(uint8_t newParkFences);
};
assert_struct_size(SurfaceElement, 8);
@ -265,7 +274,24 @@ assert_struct_size(SmallSceneryElement, 8);
struct LargeSceneryElement : TileElementBase
{
rct_tile_element_scenerymultiple_properties temp;
private:
uint16_t entryIndex; // 4
uint8_t colour[2]; // 6
public:
uint32_t GetEntryIndex() const;
void SetEntryIndex(uint32_t newIndex);
rct_scenery_entry* GetEntry() const;
uint16_t GetSequenceIndex() const;
void SetSequenceIndex(uint16_t newIndex);
colour_t GetPrimaryColour() const;
void SetPrimaryColour(colour_t colour);
colour_t GetSecondaryColour() const;
void SetSecondaryColour(colour_t colour);
BannerIndex GetBannerIndex() const;
void SetBannerIndex(BannerIndex newIndex);
};
assert_struct_size(LargeSceneryElement, 8);
@ -357,12 +383,8 @@ enum
#define MAP_ELEM_TRACK_SEQUENCE_SEQUENCE_MASK 0b00001111
#define MAP_ELEM_TRACK_SEQUENCE_TAKING_PHOTO_MASK 0b11110000
int32_t tile_element_get_direction(const rct_tile_element* element);
int32_t tile_element_get_direction_with_offset(const rct_tile_element* element, uint8_t offset);
BannerIndex tile_element_get_banner_index(rct_tile_element* tileElement);
bool tile_element_is_ghost(const rct_tile_element* element);
bool tile_element_is_underground(rct_tile_element* tileElement);
bool tile_element_is_last_for_tile(const rct_tile_element* element);
// ~Oli414: The banner functions should probably be part of banner.
void tile_element_set_banner_index(rct_tile_element* tileElement, BannerIndex bannerIndex);

View File

@ -237,7 +237,7 @@ int32_t tile_inspector_rotate_element_at(int32_t x, int32_t y, int32_t elementIn
case TILE_ELEMENT_TYPE_ENTRANCE:
{
// Update element rotation
newRotation = tile_element_get_direction_with_offset(tileElement, 1);
newRotation = tileElement->GetDirectionWithOffset(1);
tileElement->type &= ~TILE_ELEMENT_DIRECTION_MASK;
tileElement->type |= newRotation;
@ -263,7 +263,7 @@ int32_t tile_inspector_rotate_element_at(int32_t x, int32_t y, int32_t elementIn
case TILE_ELEMENT_TYPE_TRACK:
case TILE_ELEMENT_TYPE_SMALL_SCENERY:
case TILE_ELEMENT_TYPE_WALL:
newRotation = tile_element_get_direction_with_offset(tileElement, 1);
newRotation = tileElement->GetDirectionWithOffset(1);
tileElement->type &= ~TILE_ELEMENT_DIRECTION_MASK;
tileElement->type |= newRotation;
break;
@ -485,7 +485,7 @@ int32_t tile_inspector_surface_show_park_fences(int32_t x, int32_t y, bool showF
if (flags & GAME_COMMAND_FLAG_APPLY)
{
if (!showFences)
surfaceelement->properties.surface.ownership &= ~0x0F;
surfaceelement->AsSurface()->SetParkFences(0);
else
update_park_fences({ x << 5, y << 5 });
@ -512,11 +512,12 @@ int32_t tile_inspector_surface_toggle_corner(int32_t x, int32_t y, int32_t corne
if (flags & GAME_COMMAND_FLAG_APPLY)
{
const uint8_t originalSlope = surfaceElement->properties.surface.slope;
const uint8_t originalSlope = surfaceElement->AsSurface()->GetSlope();
const bool diagonal = (originalSlope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT) >> 4;
surfaceElement->properties.surface.slope ^= 1 << cornerIndex;
if (surfaceElement->properties.surface.slope & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP)
uint8_t newSlope = surfaceElement->AsSurface()->GetSlope() ^ (1 << cornerIndex);
surfaceElement->AsSurface()->SetSlope(newSlope);
if (surfaceElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP)
{
surfaceElement->clearance_height = surfaceElement->base_height + 2;
}
@ -526,28 +527,29 @@ int32_t tile_inspector_surface_toggle_corner(int32_t x, int32_t y, int32_t corne
}
// All corners are raised
if ((surfaceElement->properties.surface.slope & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP) == TILE_ELEMENT_SLOPE_ALL_CORNERS_UP)
if ((surfaceElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP) == TILE_ELEMENT_SLOPE_ALL_CORNERS_UP)
{
surfaceElement->properties.surface.slope &= ~TILE_ELEMENT_SURFACE_SLOPE_MASK;
uint8_t slope = TILE_ELEMENT_SLOPE_FLAT;
if (diagonal)
{
switch (originalSlope & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP)
{
case TILE_ELEMENT_SLOPE_S_CORNER_DN:
surfaceElement->properties.surface.slope |= TILE_ELEMENT_SLOPE_N_CORNER_UP;
slope |= TILE_ELEMENT_SLOPE_N_CORNER_UP;
break;
case TILE_ELEMENT_SLOPE_W_CORNER_DN:
surfaceElement->properties.surface.slope |= TILE_ELEMENT_SLOPE_E_CORNER_UP;
slope |= TILE_ELEMENT_SLOPE_E_CORNER_UP;
break;
case TILE_ELEMENT_SLOPE_N_CORNER_DN:
surfaceElement->properties.surface.slope |= TILE_ELEMENT_SLOPE_S_CORNER_UP;
slope |= TILE_ELEMENT_SLOPE_S_CORNER_UP;
break;
case TILE_ELEMENT_SLOPE_E_CORNER_DN:
surfaceElement->properties.surface.slope |= TILE_ELEMENT_SLOPE_W_CORNER_UP;
slope |= TILE_ELEMENT_SLOPE_W_CORNER_UP;
break;
}
}
surfaceElement->AsSurface()->SetSlope(slope);
// Update base and clearance heights
surfaceElement->base_height += 2;
@ -577,12 +579,13 @@ int32_t tile_inspector_surface_toggle_diagonal(int32_t x, int32_t y, int32_t fla
if (flags & GAME_COMMAND_FLAG_APPLY)
{
surfaceElement->properties.surface.slope ^= TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT;
if (surfaceElement->properties.surface.slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
uint8_t newSlope = surfaceElement->AsSurface()->GetSlope() ^ TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT;
surfaceElement->AsSurface()->SetSlope(newSlope);
if (surfaceElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
{
surfaceElement->clearance_height = surfaceElement->base_height + 4;
}
else if (surfaceElement->properties.surface.slope & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP)
else if (surfaceElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP)
{
surfaceElement->clearance_height = surfaceElement->base_height + 2;
}
@ -676,13 +679,11 @@ int32_t tile_inspector_entrance_make_usable(int32_t x, int32_t y, int32_t elemen
{
case ENTRANCE_TYPE_RIDE_ENTRANCE:
ride_set_entrance_location(
ride, stationIndex,
{ x, y, entranceElement->base_height, (uint8_t)tile_element_get_direction(entranceElement) });
ride, stationIndex, { x, y, entranceElement->base_height, (uint8_t)entranceElement->GetDirection() });
break;
case ENTRANCE_TYPE_RIDE_EXIT:
ride_set_exit_location(
ride, stationIndex,
{ x, y, entranceElement->base_height, (uint8_t)tile_element_get_direction(entranceElement) });
ride, stationIndex, { x, y, entranceElement->base_height, (uint8_t)entranceElement->GetDirection() });
break;
}
@ -741,13 +742,13 @@ int32_t tile_inspector_track_base_height_offset(int32_t x, int32_t y, int32_t el
int16_t originX = x << 5;
int16_t originY = y << 5;
int16_t originZ = trackElement->base_height * 8;
uint8_t rotation = tile_element_get_direction(trackElement);
uint8_t rotation = trackElement->GetDirection();
uint8_t rideIndex = track_element_get_ride_index(trackElement);
Ride* ride = get_ride(rideIndex);
const rct_preview_track* trackBlock = get_track_def_from_ride(ride, type);
trackBlock += tile_element_get_track_sequence(trackElement);
uint8_t originDirection = tile_element_get_direction(trackElement);
uint8_t originDirection = trackElement->GetDirection();
switch (originDirection)
{
case 0:
@ -809,7 +810,7 @@ int32_t tile_inspector_track_base_height_offset(int32_t x, int32_t y, int32_t el
if (tileElement->GetType() != TILE_ELEMENT_TYPE_TRACK)
continue;
if ((tile_element_get_direction(tileElement)) != rotation)
if ((tileElement->GetDirection()) != rotation)
continue;
if (tile_element_get_track_sequence(tileElement) != trackBlock->index)
@ -874,13 +875,13 @@ int32_t tile_inspector_track_set_chain(
int16_t originX = x << 5;
int16_t originY = y << 5;
int16_t originZ = trackElement->base_height * 8;
uint8_t rotation = tile_element_get_direction(trackElement);
uint8_t rotation = trackElement->GetDirection();
uint8_t rideIndex = track_element_get_ride_index(trackElement);
Ride* ride = get_ride(rideIndex);
const rct_preview_track* trackBlock = get_track_def_from_ride(ride, type);
trackBlock += tile_element_get_track_sequence(trackElement);
uint8_t originDirection = tile_element_get_direction(trackElement);
uint8_t originDirection = trackElement->GetDirection();
switch (originDirection)
{
case 0:
@ -942,7 +943,7 @@ int32_t tile_inspector_track_set_chain(
if (tileElement->GetType() != TILE_ELEMENT_TYPE_TRACK)
continue;
if ((tile_element_get_direction(tileElement)) != rotation)
if ((tileElement->GetDirection()) != rotation)
continue;
if (tile_element_get_track_sequence(tileElement) != trackBlock->index)

View File

@ -64,7 +64,7 @@ static bool WallCheckObstructionWithTrack(
{
int32_t trackType = track_element_get_type(trackElement);
int32_t sequence = tile_element_get_track_sequence(trackElement);
int32_t direction = (edge - tile_element_get_direction(trackElement)) & TILE_ELEMENT_DIRECTION_MASK;
int32_t direction = (edge - trackElement->GetDirection()) & TILE_ELEMENT_DIRECTION_MASK;
Ride* ride = get_ride(track_element_get_ride_index(trackElement));
if (TrackIsAllowedWallEdges(ride->type, trackType, sequence, direction))
@ -108,7 +108,7 @@ static bool WallCheckObstructionWithTrack(
{
if (!(TrackCoordinates[trackType].rotation_begin & 4))
{
direction = tile_element_get_direction_with_offset(trackElement, 2);
direction = trackElement->GetDirectionWithOffset(2);
if (direction == edge)
{
const rct_preview_track* trackBlock = &TrackBlocks[trackType][sequence];
@ -140,7 +140,7 @@ static bool WallCheckObstructionWithTrack(
return false;
}
direction = tile_element_get_direction(trackElement);
direction = trackElement->GetDirection();
if (direction != edge)
{
return false;
@ -183,7 +183,7 @@ static bool WallCheckObstruction(
continue;
if (elementType == TILE_ELEMENT_TYPE_WALL)
{
int32_t direction = tile_element_get_direction(tileElement);
int32_t direction = tileElement->GetDirection();
if (edge == direction)
{
map_obstruction_set_error_text(tileElement);
@ -207,12 +207,12 @@ static bool WallCheckObstruction(
}
break;
case TILE_ELEMENT_TYPE_LARGE_SCENERY:
entryType = scenery_large_get_type(tileElement);
sequence = scenery_large_get_sequence(tileElement);
entryType = tileElement->AsLargeScenery()->GetEntryIndex();
sequence = tileElement->AsLargeScenery()->GetSequenceIndex();
entry = get_large_scenery_entry(entryType);
tile = &entry->large_scenery.tiles[sequence];
{
int32_t direction = ((edge - tile_element_get_direction(tileElement)) & TILE_ELEMENT_DIRECTION_MASK) + 8;
int32_t direction = ((edge - tileElement->GetDirection()) & TILE_ELEMENT_DIRECTION_MASK) + 8;
if (!(tile->flags & (1 << direction)))
{
map_obstruction_set_error_text(tileElement);
@ -340,7 +340,7 @@ static money32 WallPlace(
}
position.z = surfaceElement->base_height * 8;
uint8_t slope = surfaceElement->properties.surface.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK;
uint8_t slope = surfaceElement->AsSurface()->GetSlope();
edgeSlope = EdgeSlopes[slope][edge & 3];
if (edgeSlope & EDGE_SLOPE_ELEVATED)
{
@ -355,9 +355,9 @@ static money32 WallPlace(
return MONEY32_UNDEFINED;
}
if (surface_get_water_height(surfaceElement) > 0)
if (surfaceElement->AsSurface()->GetWaterHeight() > 0)
{
uint16_t waterHeight = surface_get_water_height(surfaceElement) * 16;
uint16_t waterHeight = surfaceElement->AsSurface()->GetWaterHeight() * 16;
if (position.z < waterHeight && !gCheatsDisableClearanceChecks)
{
@ -377,7 +377,7 @@ static money32 WallPlace(
uint8_t newEdge = (edge + 2) & 3;
uint8_t newBaseHeight = surfaceElement->base_height;
newBaseHeight += 2;
if (surfaceElement->properties.surface.slope & (1 << newEdge))
if (surfaceElement->AsSurface()->GetSlope() & (1 << newEdge))
{
if (position.z / 8 < newBaseHeight)
{
@ -385,14 +385,14 @@ static money32 WallPlace(
return MONEY32_UNDEFINED;
}
if (surfaceElement->properties.surface.slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
if (surfaceElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
{
newEdge = (newEdge - 1) & 3;
if (surfaceElement->properties.surface.slope & (1 << newEdge))
if (surfaceElement->AsSurface()->GetSlope() & (1 << newEdge))
{
newEdge = (newEdge + 2) & 3;
if (surfaceElement->properties.surface.slope & (1 << newEdge))
if (surfaceElement->AsSurface()->GetSlope() & (1 << newEdge))
{
newBaseHeight += 2;
if (position.z / 8 < newBaseHeight)
@ -407,7 +407,7 @@ static money32 WallPlace(
}
newEdge = (edge + 3) & 3;
if (surfaceElement->properties.surface.slope & (1 << newEdge))
if (surfaceElement->AsSurface()->GetSlope() & (1 << newEdge))
{
if (position.z / 8 < newBaseHeight)
{
@ -415,14 +415,14 @@ static money32 WallPlace(
return MONEY32_UNDEFINED;
}
if (surfaceElement->properties.surface.slope & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
if (surfaceElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT)
{
newEdge = (newEdge - 1) & 3;
if (surfaceElement->properties.surface.slope & (1 << newEdge))
if (surfaceElement->AsSurface()->GetSlope() & (1 << newEdge))
{
newEdge = (newEdge + 2) & 3;
if (surfaceElement->properties.surface.slope & (1 << newEdge))
if (surfaceElement->AsSurface()->GetSlope() & (1 << newEdge))
{
newBaseHeight += 2;
if (position.z / 8 < newBaseHeight)
@ -700,7 +700,7 @@ void wall_remove_intersecting_walls(int32_t x, int32_t y, int32_t z0, int32_t z1
if (tileElement->clearance_height <= z0 || tileElement->base_height >= z1)
continue;
if (direction != tile_element_get_direction(tileElement))
if (direction != tileElement->GetDirection())
continue;
tile_element_remove_banner_entry(tileElement);

View File

@ -164,16 +164,6 @@ uint8_t TileElementBase::GetType() const
return this->type & TILE_ELEMENT_TYPE_MASK;
}
int tile_element_get_direction(const rct_tile_element* element)
{
return element->type & TILE_ELEMENT_DIRECTION_MASK;
}
int tile_element_get_direction_with_offset(const rct_tile_element* element, uint8_t offset)
{
return ((element->type & TILE_ELEMENT_DIRECTION_MASK) + offset) & TILE_ELEMENT_DIRECTION_MASK;
}
rct_tile_element* map_get_first_element_at(int x, int y)
{
if (x < 0 || y < 0 || x > 255 || y > 255)
@ -250,11 +240,6 @@ void tile_element_decrement_onride_photo_timout(rct_tile_element* tileElement)
}
}
int32_t surface_get_water_height(const rct_tile_element* tileElement)
{
return tileElement->properties.surface.terrain & TILE_ELEMENT_SURFACE_WATER_HEIGHT_MASK;
}
bool ride_type_has_flag(int rideType, int flag)
{
return (RideProperties[rideType].flags & flag) != 0;
@ -346,3 +331,23 @@ TileCoordsXYZD ride_get_exit_location(const Ride* ride, const int32_t stationInd
{
return ride->exits[stationIndex];
}
uint8_t TileElementBase::GetDirection() const
{
return this->type & TILE_ELEMENT_DIRECTION_MASK;
}
uint8_t TileElementBase::GetDirectionWithOffset(uint8_t offset) const
{
return ((this->type & TILE_ELEMENT_DIRECTION_MASK) + offset) & TILE_ELEMENT_DIRECTION_MASK;
}
uint8_t SurfaceElement::GetSlope() const
{
return (slope & TILE_ELEMENT_SURFACE_SLOPE_MASK);
}
uint32_t SurfaceElement::GetWaterHeight() const
{
return terrain & TILE_ELEMENT_SURFACE_WATER_HEIGHT_MASK;
}