From 74ccf010e627c321fa90d71ed84a1c7503b6240d Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Fri, 14 Sep 2018 14:54:12 +0200 Subject: [PATCH] Port surface elements to new structure --- .../interface/ViewportInteraction.cpp | 2 +- src/openrct2-ui/windows/Footpath.cpp | 8 +- src/openrct2-ui/windows/Map.cpp | 20 +- src/openrct2-ui/windows/TileInspector.cpp | 26 +- src/openrct2-ui/windows/TopToolbar.cpp | 2 +- src/openrct2-ui/windows/TrackDesignPlace.cpp | 10 +- src/openrct2/Cheats.cpp | 14 +- src/openrct2/Game.cpp | 3 +- .../actions/PlaceParkEntranceAction.hpp | 5 +- src/openrct2/actions/PlacePeepSpawnAction.hpp | 3 +- src/openrct2/interface/InteractiveConsole.cpp | 2 +- src/openrct2/paint/VirtualFloor.cpp | 2 +- .../paint/tile_element/Paint.Path.cpp | 5 +- .../paint/tile_element/Paint.Surface.cpp | 83 +++-- .../paint/tile_element/Paint.TileElement.cpp | 4 +- src/openrct2/peep/Guest.cpp | 2 +- src/openrct2/peep/Peep.cpp | 8 +- src/openrct2/peep/Staff.cpp | 19 +- src/openrct2/rct1/S4Importer.cpp | 22 +- src/openrct2/ride/RideRatings.cpp | 2 +- src/openrct2/ride/Track.cpp | 4 +- src/openrct2/ride/TrackDesign.cpp | 23 +- src/openrct2/ride/Vehicle.cpp | 2 +- src/openrct2/ride/gentle/MiniGolf.cpp | 2 +- src/openrct2/world/Duck.cpp | 2 +- src/openrct2/world/Footpath.cpp | 2 +- src/openrct2/world/Map.cpp | 311 +++++------------- src/openrct2/world/MapGen.cpp | 30 +- src/openrct2/world/MapHelpers.cpp | 46 +-- src/openrct2/world/Park.cpp | 37 +-- src/openrct2/world/SmallScenery.cpp | 12 +- src/openrct2/world/Surface.cpp | 203 ++++++++++-- src/openrct2/world/Surface.h | 11 +- src/openrct2/world/TileElement.h | 39 ++- src/openrct2/world/TileInspector.cpp | 27 +- src/openrct2/world/Wall.cpp | 22 +- 36 files changed, 527 insertions(+), 488 deletions(-) diff --git a/src/openrct2-ui/interface/ViewportInteraction.cpp b/src/openrct2-ui/interface/ViewportInteraction.cpp index 2c717c8386..43a7fa7822 100644 --- a/src/openrct2-ui/interface/ViewportInteraction.cpp +++ b/src/openrct2-ui/interface/ViewportInteraction.cpp @@ -639,7 +639,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); diff --git a/src/openrct2-ui/windows/Footpath.cpp b/src/openrct2-ui/windows/Footpath.cpp index c6af682408..d7fb758cfe 100644 --- a/src/openrct2-ui/windows/Footpath.cpp +++ b/src/openrct2-ui/windows/Footpath.cpp @@ -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) { diff --git a/src/openrct2-ui/windows/Map.cpp b/src/openrct2-ui/windows/Map.cpp index fa33ec25ca..cfc4d56bb3 100644 --- a/src/openrct2-ui/windows/Map.cpp +++ b/src/openrct2-ui/windows/Map.cpp @@ -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: diff --git a/src/openrct2-ui/windows/TileInspector.cpp b/src/openrct2-ui/windows/TileInspector.cpp index f3003c03b7..f5d98cd02b 100644 --- a/src/openrct2-ui/windows/TileInspector.cpp +++ b/src/openrct2-ui/windows/TileInspector.cpp @@ -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 diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 54258a2404..6c7936c3be 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -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; diff --git a/src/openrct2-ui/windows/TrackDesignPlace.cpp b/src/openrct2-ui/windows/TrackDesignPlace.cpp index 8f27e81b76..eedd2c2889 100644 --- a/src/openrct2-ui/windows/TrackDesignPlace.cpp +++ b/src/openrct2-ui/windows/TrackDesignPlace.cpp @@ -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); } diff --git a/src/openrct2/Cheats.cpp b/src/openrct2/Cheats.cpp index 40347a3a46..3d1b72d946 100644 --- a/src/openrct2/Cheats.cpp +++ b/src/openrct2/Cheats.cpp @@ -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); diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index b78ceac250..a3d37a4f27 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -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); } } } diff --git a/src/openrct2/actions/PlaceParkEntranceAction.hpp b/src/openrct2/actions/PlaceParkEntranceAction.hpp index 4f20b3e52e..c6654fdbb6 100644 --- a/src/openrct2/actions/PlaceParkEntranceAction.hpp +++ b/src/openrct2/actions/PlaceParkEntranceAction.hpp @@ -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 @@ -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); diff --git a/src/openrct2/actions/PlacePeepSpawnAction.hpp b/src/openrct2/actions/PlacePeepSpawnAction.hpp index de66233558..d195991f01 100644 --- a/src/openrct2/actions/PlacePeepSpawnAction.hpp +++ b/src/openrct2/actions/PlacePeepSpawnAction.hpp @@ -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(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( GA_ERROR::INVALID_PARAMETERS, STR_ERR_CANT_PLACE_PEEP_SPAWN_HERE, STR_ERR_MUST_BE_OUTSIDE_PARK_BOUNDARIES); diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index a70d7f450c..09f09103c1 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -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()->SetOwnership(it.element->AsSurface()->GetOwnership()); } } while (tile_element_iterator_next(&it)); diff --git a/src/openrct2/paint/VirtualFloor.cpp b/src/openrct2/paint/VirtualFloor.cpp index a3464b1329..d73a0ef4f5 100644 --- a/src/openrct2/paint/VirtualFloor.cpp +++ b/src/openrct2/paint/VirtualFloor.cpp @@ -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; diff --git a/src/openrct2/paint/tile_element/Paint.Path.cpp b/src/openrct2/paint/tile_element/Paint.Path.cpp index 466cd3ed8a..a14ab6f8c0 100644 --- a/src/openrct2/paint/tile_element/Paint.Path.cpp +++ b/src/openrct2/paint/tile_element/Paint.Path.cpp @@ -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; } diff --git a/src/openrct2/paint/tile_element/Paint.Surface.cpp b/src/openrct2/paint/tile_element/Paint.Surface.cpp index d4c46ee1b5..dbe1f0e670 100644 --- a/src/openrct2/paint/tile_element/Paint.Surface.cpp +++ b/src/openrct2/paint/tile_element/Paint.Surface.cpp @@ -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; @@ -565,26 +565,26 @@ static void viewport_surface_smoothen_edge( return; } - uint8_t dh = 0, cl = 0; + uint8_t waterHeight = 0, cl = 0; switch (edge) { case EDGE_BOTTOMLEFT: - dh = byte_97B524[byte_97B444[self.slope]]; + waterHeight = byte_97B524[byte_97B444[self.slope]]; cl = byte_97B54A[byte_97B444[neighbour.slope]]; break; case EDGE_TOPLEFT: - dh = byte_97B537[byte_97B444[self.slope]]; + waterHeight = byte_97B537[byte_97B444[self.slope]]; cl = byte_97B55D[byte_97B444[neighbour.slope]]; break; case EDGE_BOTTOMRIGHT: - dh = byte_97B55D[byte_97B444[self.slope]]; + waterHeight = byte_97B55D[byte_97B444[self.slope]]; cl = byte_97B537[byte_97B444[neighbour.slope]]; break; case EDGE_TOPRIGHT: - dh = byte_97B54A[byte_97B444[self.slope]]; + waterHeight = byte_97B54A[byte_97B444[self.slope]]; cl = byte_97B524[byte_97B444[neighbour.slope]]; break; } @@ -592,7 +592,7 @@ static void viewport_surface_smoothen_edge( if (self.terrain == neighbour.terrain) { // same tint - if (cl == dh) + if (cl == waterHeight) return; if (byte_97B83C[self.terrain] & FLAG_DONT_SMOOTHEN_SELF) @@ -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,7 +1105,7 @@ 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 (tileElement->GetDirection() == 0) { @@ -1113,7 +1113,7 @@ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, c { 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; diff --git a/src/openrct2/paint/tile_element/Paint.TileElement.cpp b/src/openrct2/paint/tile_element/Paint.TileElement.cpp index bf2ba6eba8..788d689373 100644 --- a/src/openrct2/paint/tile_element/Paint.TileElement.cpp +++ b/src/openrct2/paint/tile_element/Paint.TileElement.cpp @@ -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; diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index 75435e026a..fba09b4f8b 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -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(); diff --git a/src/openrct2/peep/Peep.cpp b/src/openrct2/peep/Peep.cpp index e5cfe64ff3..4d07837ccd 100644 --- a/src/openrct2/peep/Peep.cpp +++ b/src/openrct2/peep/Peep.cpp @@ -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->AsSurface()->GetSlope()) + 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) { @@ -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); diff --git a/src/openrct2/peep/Staff.cpp b/src/openrct2/peep/Staff.cpp index 9f696d4dcd..a6fc1b146e 100644 --- a/src/openrct2/peep/Staff.cpp +++ b/src/openrct2/peep/Staff.cpp @@ -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++; @@ -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(); diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 7a843ad660..346eaf544c 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -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++; } @@ -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())); } } } diff --git a/src/openrct2/ride/RideRatings.cpp b/src/openrct2/ride/RideRatings.cpp index a98684f74c..2d1d4266dd 100644 --- a/src/openrct2/ride/RideRatings.cpp +++ b/src/openrct2/ride/RideRatings.cpp @@ -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; diff --git a/src/openrct2/ride/Track.cpp b/src/openrct2/ride/Track.cpp index 49c8836739..7fdf3b23c1 100644 --- a/src/openrct2/ride/Track.cpp +++ b/src/openrct2/ride/Track.cpp @@ -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) { diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 5585bdf44e..151545ffeb 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -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; @@ -2330,10 +2330,11 @@ static void track_design_preview_clear_map() 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()->SetSurfaceStyle(TERRAIN_GRASS); + tile_element->AsSurface()->SetEdgeStyle(TERRAIN_EDGE_ROCK); + tile_element->AsSurface()->SetGrassLength(GRASS_LENGTH_CLEAR_0); + tile_element->AsSurface()->SetOwnership(OWNERSHIP_UNOWNED); } map_update_tile_pointers(); } diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index 8194367388..e108b3d684 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -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; diff --git a/src/openrct2/ride/gentle/MiniGolf.cpp b/src/openrct2/ride/gentle/MiniGolf.cpp index b80ad6f845..d76a31ef09 100644 --- a/src/openrct2/ride/gentle/MiniGolf.cpp +++ b/src/openrct2/ride/gentle/MiniGolf.cpp @@ -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; } diff --git a/src/openrct2/world/Duck.cpp b/src/openrct2/world/Duck.cpp index cf21e51876..faabf8dabb 100644 --- a/src/openrct2/world/Duck.cpp +++ b/src/openrct2/world/Duck.cpp @@ -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; diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index 94dec4105a..50f1735c67 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -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) { diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index c3b5a136a6..55eede6cb4 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -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); @@ -348,13 +346,11 @@ void map_init(int32_t size) 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()->SetSlope(TILE_ELEMENT_SLOPE_FLAT); + tile_element->AsSurface()->SetGrassLength(GRASS_LENGTH_CLEAR_0); + tile_element->AsSurface()->SetOwnership(OWNERSHIP_UNOWNED); + tile_element->AsSurface()->SetSurfaceStyle(TERRAIN_GRASS); + tile_element->AsSurface()->SetEdgeStyle(TERRAIN_EDGE_ROCK); } gGrassSceneryTileLoopPosition = 0; @@ -393,7 +389,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 +482,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; @@ -753,10 +749,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 +776,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 +793,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; @@ -1305,8 +1301,7 @@ static money32 map_change_surface_style( if (surfaceStyle != 0xFF) { - uint8_t cur_terrain = (tileElement->GetDirection() << 3) - | (tileElement->properties.surface.terrain >> 5); + uint8_t cur_terrain = tileElement->AsSurface()->GetSurfaceStyle(); if (surfaceStyle != cur_terrain) { @@ -1321,14 +1316,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 +1326,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 (!(tileElement->GetDirection())) + 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 +1498,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 +1627,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 +1719,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 +1821,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 +1867,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 +1927,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 +1982,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 +1999,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 +2075,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 +2093,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 +2171,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 +2278,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 +2520,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 +2598,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 +2797,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 +2818,10 @@ 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); } - tile_element->properties.surface.terrain = new_terrain; map_invalidate_tile_full(x, y); } *ebx = 250; @@ -2961,7 +2936,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) { @@ -3520,7 +3495,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,7 +3520,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->AsSurface()->GetSlope()) == TILE_ELEMENT_SLOPE_FLAT && tileElement->base_height == zLow) { canBuildCrossing = true; @@ -3565,7 +3540,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 +3662,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 +3674,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 (tileElementAbove->IsGhost()) - 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 +3731,32 @@ 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); 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 +3768,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 +3778,27 @@ 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); 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 +3810,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,10 +3830,11 @@ 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); // 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)++; @@ -4046,7 +3911,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 +3920,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; } @@ -4438,14 +4303,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()) @@ -4975,7 +4840,7 @@ void FixLandOwnershipTilesWithOwnership(std::initializer_list 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 }); } } diff --git a/src/openrct2/world/MapGen.cpp b/src/openrct2/world/MapGen.cpp index 1f1761221a..35a4825513 100644 --- a/src/openrct2/world/MapGen.cpp +++ b/src/openrct2/world/MapGen.cpp @@ -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); } } } diff --git a/src/openrct2/world/MapHelpers.cpp b/src/openrct2/world/MapHelpers.cpp index 5b7fc84b3b..06182ba4ca 100644 --- a/src/openrct2/world/MapHelpers.cpp +++ b/src/openrct2/world/MapHelpers.cpp @@ -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) diff --git a/src/openrct2/world/Park.cpp b/src/openrct2/world/Park.cpp index 539b62c98f..fd19d0ca7a 100644 --- a/src/openrct2/world/Park.cpp +++ b/src/openrct2/world/Park.cpp @@ -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 newOwnership = surfaceElement->AsSurface()->GetOwnership(); + if ((surfaceElement->AsSurface()->GetOwnership() & OWNERSHIP_OWNED) == 0) { bool fenceRequired = true; @@ -224,12 +224,12 @@ void update_park_fences(const CoordsXY coords) } } - if (surfaceElement->properties.surface.ownership != newOwnership) + if (surfaceElement->AsSurface()->GetOwnership() != newOwnership) { 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()->SetOwnership(newOwnership); } } @@ -254,45 +254,45 @@ 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 +300,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 +308,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 +316,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 +324,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 +349,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 +392,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 +636,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++; } diff --git a/src/openrct2/world/SmallScenery.cpp b/src/openrct2/world/SmallScenery.cpp index fd66554f2a..d56372969d 100644 --- a/src/openrct2/world/SmallScenery.cpp +++ b/src/openrct2/world/SmallScenery.cpp @@ -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; diff --git a/src/openrct2/world/Surface.cpp b/src/openrct2/world/Surface.cpp index b358432c8f..1dcfa8dbbc 100644 --- a/src/openrct2/world/Surface.cpp +++ b/src/openrct2/world/Surface.cpp @@ -7,51 +7,210 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ +#include "../scenario/Scenario.h" +#include "Location.hpp" #include "Surface.h" +#include "Map.h" -int32_t surface_get_terrain(const rct_tile_element* element) +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); +} \ No newline at end of file diff --git a/src/openrct2/world/Surface.h b/src/openrct2/world/Surface.h index b101cb32d9..8e030517ac 100644 --- a/src/openrct2/world/Surface.h +++ b/src/openrct2/world/Surface.h @@ -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 diff --git a/src/openrct2/world/TileElement.h b/src/openrct2/world/TileElement.h index dff8fef456..87a55b6577 100644 --- a/src/openrct2/world/TileElement.h +++ b/src/openrct2/world/TileElement.h @@ -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 @@ -96,7 +88,6 @@ 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; @@ -215,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); diff --git a/src/openrct2/world/TileInspector.cpp b/src/openrct2/world/TileInspector.cpp index 7ad49a6cbc..80811d6bed 100644 --- a/src/openrct2/world/TileInspector.cpp +++ b/src/openrct2/world/TileInspector.cpp @@ -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,11 @@ 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) + surfaceElement->AsSurface()->SetSlope(surfaceElement->AsSurface()->GetSlope() ^ (1 << cornerIndex)); + if (surfaceElement->AsSurface()->GetSlope() & TILE_ELEMENT_SLOPE_ALL_CORNERS_UP) { surfaceElement->clearance_height = surfaceElement->base_height + 2; } @@ -526,28 +526,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 +578,12 @@ 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) + surfaceElement->AsSurface()->SetSlope(surfaceElement->AsSurface()->GetSlope() ^ TILE_ELEMENT_SLOPE_DOUBLE_HEIGHT); + 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; } diff --git a/src/openrct2/world/Wall.cpp b/src/openrct2/world/Wall.cpp index 98f95f7e1e..c67174cb81 100644 --- a/src/openrct2/world/Wall.cpp +++ b/src/openrct2/world/Wall.cpp @@ -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)