diff --git a/.vs/CMakeSettings.json b/.vs/CMakeSettings.json deleted file mode 100644 index 0e32f3a202..0000000000 --- a/.vs/CMakeSettings.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "configurations": [ - { - "name": "x64-Debug", - "inheritEnvironments": [ "msvc_x64_x64" ], - "generator": "Ninja", - "buildRoot": "${env.LOCALAPPDATA}\\CMakeBuild\\${workspaceHash}\\build\\${name}", - "configurationType": "Debug", - "variables": [ - { - "name": "VCPKG_TARGET_TRIPLET", - "value": "x64-windows-winssl" - }, - { - "name": "CMAKE_TOOLCHAIN_FILE", - "value": "C:\\vcpkg\\scripts\\buildsystems\\vcpkg.cmake" - } - ] - } - ] -} diff --git a/src/openrct2/paint/tile_element/Fence.cpp b/src/openrct2/paint/tile_element/Fence.cpp index 7c75e87662..efb9e2bf46 100644 --- a/src/openrct2/paint/tile_element/Fence.cpp +++ b/src/openrct2/paint/tile_element/Fence.cpp @@ -200,7 +200,7 @@ void fence_paint(paint_session * session, uint8 direction, sint32 height, const if (sceneryEntry->wall.flags & WALL_SCENERY_IS_DOOR) { LocationXYZ16 offset; LocationXYZ16 boundsR1, boundsR1_, boundsR2, boundsR2_, boundsL1, boundsL1_; - uint8 animationFrame = wall_element_get_animation_frame(tile_element); + uint8 animationFrame = wall_get_animation_frame(tile_element); // Add the direction as well animationFrame |= (tile_element->properties.wall.animation & WALL_ANIMATION_FLAG_DIRECTION_BACKWARD) >> 3; uint32 imageId; diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index 824bb79b60..47c7fb2221 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -37,6 +37,7 @@ #include "../world/SmallScenery.h" #include "../world/Sprite.h" #include "../world/Surface.h" +#include "../world/Wall.h" #include "Vehicle.h" #include "CableLift.h" #include "Ride.h" @@ -7481,14 +7482,14 @@ static void vehicle_update_scenery_door(rct_vehicle * vehicle) if (vehicle->next_vehicle_on_train != SPRITE_INDEX_NULL) { tileElement->properties.wall.animation &= ~(WALL_ANIMATION_FLAG_DIRECTION_BACKWARD); - wall_element_set_animation_frame(tileElement, 1); + wall_set_animation_frame(tileElement, 1); map_animation_create(MAP_ANIMATION_TYPE_WALL_DOOR, x, y, z); vehicle_play_scenery_door_open_sound(vehicle, tileElement); } else { tileElement->properties.wall.animation &= ~(WALL_ANIMATION_FLAG_DIRECTION_BACKWARD); - wall_element_set_animation_frame(tileElement, 6); + wall_set_animation_frame(tileElement, 6); vehicle_play_scenery_door_close_sound(vehicle, tileElement); } } @@ -7566,14 +7567,14 @@ static void vehicle_update_handle_scenery_door(rct_vehicle * vehicle) if (vehicle->next_vehicle_on_train != SPRITE_INDEX_NULL) { tileElement->properties.wall.animation |= WALL_ANIMATION_FLAG_DIRECTION_BACKWARD; - wall_element_set_animation_frame(tileElement, 1); + wall_set_animation_frame(tileElement, 1); map_animation_create(MAP_ANIMATION_TYPE_WALL_DOOR, x, y, z); vehicle_play_scenery_door_open_sound(vehicle, tileElement); } else { tileElement->properties.wall.animation &= ~(WALL_ANIMATION_FLAG_DIRECTION_BACKWARD); - wall_element_set_animation_frame(tileElement, 6); + wall_set_animation_frame(tileElement, 6); vehicle_play_scenery_door_close_sound(vehicle, tileElement); } } diff --git a/src/openrct2/world/LargeScenery.h b/src/openrct2/world/LargeScenery.h index 264c98df63..5fbdf8cb8f 100644 --- a/src/openrct2/world/LargeScenery.h +++ b/src/openrct2/world/LargeScenery.h @@ -18,6 +18,7 @@ #include "../common.h" #include "Map.h" +#include "TileElement.h" colour_t scenery_large_get_primary_colour(const rct_tile_element * tileElement); colour_t scenery_large_get_secondary_colour(const rct_tile_element * tileElement); diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 545921b2a7..53e9acab34 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -262,31 +262,6 @@ bool tile_element_is_last_for_tile(const rct_tile_element *element) return (element->flags & TILE_ELEMENT_FLAG_LAST_TILE) != 0; } -bool tile_element_is_ghost(const rct_tile_element *element) -{ - return element->flags & TILE_ELEMENT_FLAG_GHOST; -} - -uint8 tile_element_get_scenery_quadrant(const rct_tile_element *element) -{ - return (element->type & TILE_ELEMENT_QUADRANT_MASK) >> 6; -} - -sint32 tile_element_get_type(const rct_tile_element *element) -{ - return element->type & TILE_ELEMENT_TYPE_MASK; -} - -sint32 tile_element_get_direction(const rct_tile_element *element) -{ - return element->type & TILE_ELEMENT_DIRECTION_MASK; -} - -sint32 tile_element_get_direction_with_offset(const rct_tile_element *element, uint8 offset) -{ - return ((element->type & TILE_ELEMENT_DIRECTION_MASK) + offset) & TILE_ELEMENT_DIRECTION_MASK; -} - rct_tile_element * map_get_surface_element_at(sint32 x, sint32 y) { rct_tile_element *tileElement = map_get_first_element_at(x, y); @@ -3566,63 +3541,6 @@ void map_restore_provisional_elements() } } -sint32 tile_element_get_banner_index(rct_tile_element *tileElement) -{ - rct_scenery_entry* sceneryEntry; - - switch (tile_element_get_type(tileElement)) { - case TILE_ELEMENT_TYPE_LARGE_SCENERY: - sceneryEntry = get_large_scenery_entry(scenery_large_get_type(tileElement)); - if (sceneryEntry->large_scenery.scrolling_mode == 0xFF) - return BANNER_INDEX_NULL; - - return scenery_large_get_banner_id(tileElement); - case TILE_ELEMENT_TYPE_WALL: - sceneryEntry = get_wall_entry(tileElement->properties.wall.type); - if (sceneryEntry == nullptr || sceneryEntry->wall.scrolling_mode == 0xFF) - return BANNER_INDEX_NULL; - - return tileElement->properties.wall.banner_index; - case TILE_ELEMENT_TYPE_BANNER: - return tileElement->properties.banner.index; - default: - return BANNER_INDEX_NULL; - } -} - -void tile_element_set_banner_index(rct_tile_element * tileElement, sint32 bannerIndex) -{ - switch (tile_element_get_type(tileElement)) - { - case TILE_ELEMENT_TYPE_WALL: - tileElement->properties.wall.banner_index = (uint8)bannerIndex; - break; - case TILE_ELEMENT_TYPE_LARGE_SCENERY: - scenery_large_set_banner_id(tileElement, (uint8)bannerIndex); - break; - case TILE_ELEMENT_TYPE_BANNER: - tileElement->properties.banner.index = (uint8)bannerIndex; - break; - default: - log_error("Tried to set banner index on unsuitable tile element!"); - Guard::Assert(false); - } -} - -void tile_element_remove_banner_entry(rct_tile_element *tileElement) -{ - sint32 bannerIndex = tile_element_get_banner_index(tileElement); - if (bannerIndex == BANNER_INDEX_NULL) - return; - - rct_banner* banner = &gBanners[bannerIndex]; - if (banner->type != BANNER_NULL) { - window_close_by_number(WC_BANNER, bannerIndex); - banner->type = BANNER_NULL; - user_string_free(banner->string_idx); - } -} - /** * Removes elements that are out of the map size range and crops the park perimeter. * rct2: 0x0068ADBC @@ -3832,16 +3750,6 @@ sint32 map_get_highest_z(sint32 tileX, sint32 tileY) return z; } -bool tile_element_is_underground(rct_tile_element *tileElement) -{ - do { - tileElement++; - if (tile_element_is_last_for_tile(tileElement - 1)) - return false; - } while (tile_element_get_type(tileElement) != TILE_ELEMENT_TYPE_SURFACE); - return true; -} - rct_tile_element *map_get_large_scenery_segment(sint32 x, sint32 y, sint32 z, sint32 direction, sint32 sequence) { rct_tile_element *tileElement = map_get_first_element_at(x >> 5, y >> 5); @@ -4714,21 +4622,6 @@ uint16 check_max_allowable_land_rights_for_tile(uint8 x, uint8 y, uint8 base_z) return destOwnership; } -uint8 tile_element_get_ride_index(const rct_tile_element * tileElement) -{ - switch (tile_element_get_type(tileElement)) - { - case TILE_ELEMENT_TYPE_TRACK: - return track_element_get_ride_index(tileElement); - case TILE_ELEMENT_TYPE_ENTRANCE: - return tileElement->properties.entrance.ride_index; - case TILE_ELEMENT_TYPE_PATH: - return tileElement->properties.path.ride_index; - default: - return 0xFF; - } -} - void FixLandOwnershipTiles(std::initializer_list tiles) { FixLandOwnershipTilesWithOwnership(tiles, OWNERSHIP_AVAILABLE); diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index 09b19ec010..4744797f50 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -20,196 +20,7 @@ #include #include "../common.h" #include "Location.hpp" - -#pragma pack(push, 1) -struct rct_tile_element_surface_properties { - uint8 slope; //4 0xE0 Edge Style, 0x1F Slope - uint8 terrain; //5 0xE0 Terrain Style, 0x1F Water height - uint8 grass_length; //6 - uint8 ownership; //7 -}; -assert_struct_size(rct_tile_element_surface_properties, 4); - -struct rct_tile_element_path_properties { - uint8 type; //4 0xF0 Path type, 0x08 Ride sign, 0x04 Set when path is diagonal, 0x03 Rotation - uint8 additions; //5 - uint8 edges; //6 - union { - uint8 addition_status; //7 - uint8 ride_index; - }; -}; -assert_struct_size(rct_tile_element_path_properties, 4); - -struct rct_tile_element_track_properties { - uint8 type; //4 - union{ - struct{ - // The lower 4 bits are the track sequence. - // The upper 4 bits are either station bits or on-ride photo bits. - // - // Station bits: - // - Bit 8 marks green light - // - Bit 5-7 are station index. - // - // On-ride photo bits: - // - Bits 7 and 8 are never set - // - Bits 5 and 6 are set when a vehicle triggers the on-ride photo and act like a countdown from 3. - // - If any of the bits 5-8 are set, the game counts it as a photo being taken. - uint8 sequence; //5. - uint8 colour; //6 - }; - uint16 maze_entry; // 5 - }; - uint8 ride_index; //7 -}; -assert_struct_size(rct_tile_element_track_properties, 4); - -struct rct_tile_element_scenery_properties { - uint8 type; //4 - uint8 age; //5 - uint8 colour_1; //6 - uint8 colour_2; //7 -}; -assert_struct_size(rct_tile_element_scenery_properties, 4); - -struct rct_tile_element_entrance_properties { - uint8 type; //4 - uint8 index; //5 - uint8 path_type; //6 - uint8 ride_index; //7 -}; -assert_struct_size(rct_tile_element_entrance_properties, 4); - -struct rct_tile_element_wall_properties { - uint8 type; //4 - union { - uint8 colour_3; //5 - uint8 banner_index; //5 - }; - uint8 colour_1; //6 0b_2221_1111 2 = colour_2 (uses flags for rest of colour2), 1 = colour_1 - uint8 animation; //7 0b_dfff_ft00 d = direction, f = frame num, t = across track flag (not used) -}; -assert_struct_size(rct_tile_element_wall_properties, 4); - -struct rct_tile_element_scenerymultiple_properties { - uint16 type; //4 - uint8 colour[2]; //6 -}; -assert_struct_size(rct_tile_element_scenerymultiple_properties, 4); - -struct rct_tile_element_banner_properties { - uint8 index; //4 - uint8 position; //5 - uint8 flags; //6 - uint8 unused; //7 -}; -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_scenery_properties scenery; - rct_tile_element_entrance_properties entrance; - rct_tile_element_wall_properties wall; - rct_tile_element_scenerymultiple_properties scenerymultiple; - rct_tile_element_banner_properties banner; -}; -assert_struct_size(rct_tile_element_properties, 4); - -/** - * Map element structure - * size: 0x08 - */ -struct rct_tile_element { - uint8 type; //0 - uint8 flags; //1 - uint8 base_height; //2 - uint8 clearance_height; //3 - rct_tile_element_properties properties; -}; -assert_struct_size(rct_tile_element, 8); -#pragma pack(pop) - -enum { - TILE_ELEMENT_QUADRANT_SW, - TILE_ELEMENT_QUADRANT_NW, - TILE_ELEMENT_QUADRANT_NE, - TILE_ELEMENT_QUADRANT_SE -}; - -enum { - TILE_ELEMENT_TYPE_SURFACE = (0 << 2), - TILE_ELEMENT_TYPE_PATH = (1 << 2), - TILE_ELEMENT_TYPE_TRACK = (2 << 2), - TILE_ELEMENT_TYPE_SMALL_SCENERY = (3 << 2), - TILE_ELEMENT_TYPE_ENTRANCE = (4 << 2), - TILE_ELEMENT_TYPE_WALL = (5 << 2), - TILE_ELEMENT_TYPE_LARGE_SCENERY = (6 << 2), - TILE_ELEMENT_TYPE_BANNER = (7 << 2), - // The corrupt element type is used for skipping drawing other following - // elements on a given tile. - TILE_ELEMENT_TYPE_CORRUPT = (8 << 2), -}; - -enum { - TILE_ELEMENT_TYPE_FLAG_HIGHLIGHT = (1 << 6) -}; - -enum { - TILE_ELEMENT_DIRECTION_WEST, - TILE_ELEMENT_DIRECTION_NORTH, - TILE_ELEMENT_DIRECTION_EAST, - TILE_ELEMENT_DIRECTION_SOUTH -}; - -enum { - TILE_ELEMENT_FLAG_GHOST = (1 << 4), - TILE_ELEMENT_FLAG_BROKEN = (1 << 5), - TILE_ELEMENT_FLAG_BLOCK_BRAKE_CLOSED = (1 << 5), - TILE_ELEMENT_FLAG_INDESTRUCTIBLE_TRACK_PIECE = (1 << 6), - TILE_ELEMENT_FLAG_LAST_TILE = (1 << 7) -}; - -enum { - WALL_ANIMATION_FLAG_ACROSS_TRACK = (1 << 2), - // 3 - 6 animation frame number - WALL_ANIMATION_FLAG_DIRECTION_BACKWARD = (1 << 7), - WALL_ANIMATION_FLAG_ALL_FLAGS = WALL_ANIMATION_FLAG_ACROSS_TRACK | WALL_ANIMATION_FLAG_DIRECTION_BACKWARD -}; - -enum { - ENTRANCE_TYPE_RIDE_ENTRANCE, - ENTRANCE_TYPE_RIDE_EXIT, - ENTRANCE_TYPE_PARK_ENTRANCE -}; - -enum { - ELEMENT_IS_ABOVE_GROUND = 1 << 0, - ELEMENT_IS_UNDERGROUND = 1 << 1, - ELEMENT_IS_UNDERWATER = 1 << 2, -}; - -enum -{ - MAP_ELEM_TRACK_SEQUENCE_GREEN_LIGHT = (1 << 7), -}; - -enum -{ - MAP_ELEM_SMALL_SCENERY_COLOUR_FLAG_NEEDS_SUPPORTS = (1 << 5), -}; - -#define TILE_ELEMENT_QUADRANT_MASK 0xC0 -#define TILE_ELEMENT_TYPE_MASK 0x3C -#define TILE_ELEMENT_DIRECTION_MASK 0x03 - -#define TILE_ELEMENT_COLOUR_MASK 0x1F - -#define MAP_ELEM_TRACK_SEQUENCE_STATION_INDEX_MASK 0x70 -#define MAP_ELEM_TRACK_SEQUENCE_SEQUENCE_MASK 0x0F -#define MAP_ELEM_TRACK_SEQUENCE_TAKING_PHOTO_MASK 0xF0 +#include "TileElement.h" #define MINIMUM_LAND_HEIGHT 2 #define MAXIMUM_LAND_HEIGHT 142 @@ -327,11 +138,6 @@ rct_tile_element *map_get_first_element_at(sint32 x, sint32 y); rct_tile_element *map_get_nth_element_at(sint32 x, sint32 y, sint32 n); void map_set_tile_elements(sint32 x, sint32 y, rct_tile_element *elements); bool tile_element_is_last_for_tile(const rct_tile_element *element); -bool tile_element_is_ghost(const rct_tile_element *element); -uint8 tile_element_get_scenery_quadrant(const rct_tile_element *element); -sint32 tile_element_get_type(const rct_tile_element *element); -sint32 tile_element_get_direction(const rct_tile_element *element); -sint32 tile_element_get_direction_with_offset(const rct_tile_element *element, uint8 offset); sint32 map_height_from_slope(sint32 x, sint32 y, sint32 slope); rct_tile_element* map_get_banner_element_at(sint32 x, sint32 y, sint32 z, uint8 direction); rct_tile_element *map_get_surface_element_at(sint32 x, sint32 y); @@ -421,11 +227,6 @@ void wall_remove_intersecting_walls(sint32 x, sint32 y, sint32 z0, sint32 z1, si void map_update_tiles(); sint32 map_get_highest_z(sint32 tileX, sint32 tileY); -sint32 tile_element_get_banner_index(rct_tile_element *tileElement); -void tile_element_set_banner_index(rct_tile_element * tileElement, sint32 bannerIndex); -void tile_element_remove_banner_entry(rct_tile_element *tileElement); - -bool tile_element_is_underground(rct_tile_element *tileElement); bool tile_element_wants_path_connection_towards(TileCoordsXYZD coords, const rct_tile_element * const elementToBeRemoved); void map_remove_out_of_range_elements(); @@ -465,12 +266,9 @@ rct_tile_element *map_get_track_element_at_with_direction_from_ride(sint32 x, si bool map_is_location_at_edge(sint32 x, sint32 y); void map_obstruction_set_error_text(rct_tile_element *tileElement); -uint8 wall_element_get_animation_frame(const rct_tile_element * fenceElement); -void wall_element_set_animation_frame(rct_tile_element * wallElement, uint8 frameNum); uint32 map_get_available_peep_spawn_index_list(uint32* peepSpawnIndexList); uint16 check_max_allowable_land_rights_for_tile(uint8 x, uint8 y, uint8 base_z); -uint8 tile_element_get_ride_index(const rct_tile_element * tileElement); void FixLandOwnershipTiles(std::initializer_list tiles); void FixLandOwnershipTilesWithOwnership(std::initializer_list tiles, uint8 ownership); diff --git a/src/openrct2/world/MapAnimation.cpp b/src/openrct2/world/MapAnimation.cpp index df15aa00dd..66600a9a88 100644 --- a/src/openrct2/world/MapAnimation.cpp +++ b/src/openrct2/world/MapAnimation.cpp @@ -21,6 +21,7 @@ #include "../ride/RideData.h" #include "../ride/Track.h" #include "../interface/Viewport.h" +#include "../world/Wall.h" #include "MapAnimation.h" #include "Map.h" #include "Scenery.h" @@ -471,7 +472,7 @@ static bool map_animation_invalidate_wall_door(sint32 x, sint32 y, sint32 baseZ) bool invalidate = false; - uint8 currentFrame = wall_element_get_animation_frame(tileElement); + uint8 currentFrame = wall_get_animation_frame(tileElement); if (currentFrame != 0) { if (currentFrame == 15) { currentFrame = 0; @@ -486,7 +487,7 @@ static bool map_animation_invalidate_wall_door(sint32 x, sint32 y, sint32 baseZ) } } } - wall_element_set_animation_frame(tileElement, currentFrame); + wall_set_animation_frame(tileElement, currentFrame); if (invalidate) { sint32 z = tileElement->base_height * 8; map_invalidate_tile_zoom1(x, y, z, z + 32); diff --git a/src/openrct2/world/TileElement.cpp b/src/openrct2/world/TileElement.cpp new file mode 100644 index 0000000000..7fd49e2692 --- /dev/null +++ b/src/openrct2/world/TileElement.cpp @@ -0,0 +1,131 @@ +#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers +/***************************************************************************** +* OpenRCT2, an open source clone of Roller Coaster Tycoon 2. +* +* OpenRCT2 is the work of many authors, a full list can be found in contributors.md +* For more information, visit https://github.com/OpenRCT2/OpenRCT2 +* +* OpenRCT2 is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* A full copy of the GNU General Public License can be found in licence.txt +*****************************************************************************/ +#pragma endregion + +#include "../core/Guard.hpp" +#include "../interface/Window.h" +#include "../localisation/Localisation.h" +#include "../ride/Track.h" +#include "Banner.h" +#include "LargeScenery.h" +#include "TileElement.h" +#include "Scenery.h" + +uint8 tile_element_get_scenery_quadrant(const rct_tile_element *element) +{ + return (element->type & TILE_ELEMENT_QUADRANT_MASK) >> 6; +} + +sint32 tile_element_get_type(const rct_tile_element *element) +{ + return element->type & TILE_ELEMENT_TYPE_MASK; +} + +sint32 tile_element_get_direction(const rct_tile_element *element) +{ + return element->type & TILE_ELEMENT_DIRECTION_MASK; +} + +sint32 tile_element_get_direction_with_offset(const rct_tile_element *element, uint8 offset) +{ + return ((element->type & TILE_ELEMENT_DIRECTION_MASK) + offset) & TILE_ELEMENT_DIRECTION_MASK; +} + +bool tile_element_is_ghost(const rct_tile_element *element) +{ + return element->flags & TILE_ELEMENT_FLAG_GHOST; +} + +bool tile_element_is_underground(rct_tile_element *tileElement) +{ + do { + tileElement++; + if (tile_element_is_last_for_tile(tileElement - 1)) + return false; + } while (tile_element_get_type(tileElement) != TILE_ELEMENT_TYPE_SURFACE); + return true; +} + +sint32 tile_element_get_banner_index(rct_tile_element *tileElement) +{ + rct_scenery_entry* sceneryEntry; + + switch (tile_element_get_type(tileElement)) { + case TILE_ELEMENT_TYPE_LARGE_SCENERY: + sceneryEntry = get_large_scenery_entry(scenery_large_get_type(tileElement)); + if (sceneryEntry->large_scenery.scrolling_mode == 0xFF) + return BANNER_INDEX_NULL; + + return scenery_large_get_banner_id(tileElement); + case TILE_ELEMENT_TYPE_WALL: + sceneryEntry = get_wall_entry(tileElement->properties.wall.type); + if (sceneryEntry == nullptr || sceneryEntry->wall.scrolling_mode == 0xFF) + return BANNER_INDEX_NULL; + + return tileElement->properties.wall.banner_index; + case TILE_ELEMENT_TYPE_BANNER: + return tileElement->properties.banner.index; + default: + return BANNER_INDEX_NULL; + } +} + +void tile_element_set_banner_index(rct_tile_element * tileElement, sint32 bannerIndex) +{ + switch (tile_element_get_type(tileElement)) + { + case TILE_ELEMENT_TYPE_WALL: + tileElement->properties.wall.banner_index = (uint8)bannerIndex; + break; + case TILE_ELEMENT_TYPE_LARGE_SCENERY: + scenery_large_set_banner_id(tileElement, (uint8)bannerIndex); + break; + case TILE_ELEMENT_TYPE_BANNER: + tileElement->properties.banner.index = (uint8)bannerIndex; + break; + default: + log_error("Tried to set banner index on unsuitable tile element!"); + Guard::Assert(false); + } +} + +void tile_element_remove_banner_entry(rct_tile_element *tileElement) +{ + sint32 bannerIndex = tile_element_get_banner_index(tileElement); + if (bannerIndex == BANNER_INDEX_NULL) + return; + + rct_banner* banner = &gBanners[bannerIndex]; + if (banner->type != BANNER_NULL) { + window_close_by_number(WC_BANNER, bannerIndex); + banner->type = BANNER_NULL; + user_string_free(banner->string_idx); + } +} + +uint8 tile_element_get_ride_index(const rct_tile_element * tileElement) +{ + switch (tile_element_get_type(tileElement)) + { + case TILE_ELEMENT_TYPE_TRACK: + return track_element_get_ride_index(tileElement); + case TILE_ELEMENT_TYPE_ENTRANCE: + return tileElement->properties.entrance.ride_index; + case TILE_ELEMENT_TYPE_PATH: + return tileElement->properties.path.ride_index; + default: + return 0xFF; + } +} diff --git a/src/openrct2/world/TileElement.h b/src/openrct2/world/TileElement.h new file mode 100644 index 0000000000..2d510b5ac5 --- /dev/null +++ b/src/openrct2/world/TileElement.h @@ -0,0 +1,223 @@ +#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers +/***************************************************************************** +* OpenRCT2, an open source clone of Roller Coaster Tycoon 2. +* +* OpenRCT2 is the work of many authors, a full list can be found in contributors.md +* For more information, visit https://github.com/OpenRCT2/OpenRCT2 +* +* OpenRCT2 is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* A full copy of the GNU General Public License can be found in licence.txt +*****************************************************************************/ +#pragma endregion + +#pragma once + +#include "../common.h" + +#pragma pack(push, 1) +struct rct_tile_element_surface_properties { + uint8 slope; //4 0xE0 Edge Style, 0x1F Slope + uint8 terrain; //5 0xE0 Terrain Style, 0x1F Water height + uint8 grass_length; //6 + uint8 ownership; //7 +}; +assert_struct_size(rct_tile_element_surface_properties, 4); + +struct rct_tile_element_path_properties { + uint8 type; //4 0xF0 Path type, 0x08 Ride sign, 0x04 Set when path is diagonal, 0x03 Rotation + uint8 additions; //5 + uint8 edges; //6 + union { + uint8 addition_status; //7 + uint8 ride_index; + }; +}; +assert_struct_size(rct_tile_element_path_properties, 4); + +struct rct_tile_element_track_properties { + uint8 type; //4 + union { + struct { + // The lower 4 bits are the track sequence. + // The upper 4 bits are either station bits or on-ride photo bits. + // + // Station bits: + // - Bit 8 marks green light + // - Bit 5-7 are station index. + // + // On-ride photo bits: + // - Bits 7 and 8 are never set + // - Bits 5 and 6 are set when a vehicle triggers the on-ride photo and act like a countdown from 3. + // - If any of the bits 5-8 are set, the game counts it as a photo being taken. + uint8 sequence; //5. + uint8 colour; //6 + }; + uint16 maze_entry; // 5 + }; + uint8 ride_index; //7 +}; +assert_struct_size(rct_tile_element_track_properties, 4); + +struct rct_tile_element_scenery_properties { + uint8 type; //4 + uint8 age; //5 + uint8 colour_1; //6 + uint8 colour_2; //7 +}; +assert_struct_size(rct_tile_element_scenery_properties, 4); + +struct rct_tile_element_entrance_properties { + uint8 type; //4 + uint8 index; //5 + uint8 path_type; //6 + uint8 ride_index; //7 +}; +assert_struct_size(rct_tile_element_entrance_properties, 4); + +struct rct_tile_element_wall_properties { + uint8 type; //4 + union { + uint8 colour_3; //5 + uint8 banner_index; //5 + }; + uint8 colour_1; //6 0b_2221_1111 2 = colour_2 (uses flags for rest of colour2), 1 = colour_1 + uint8 animation; //7 0b_dfff_ft00 d = direction, f = frame num, t = across track flag (not used) +}; +assert_struct_size(rct_tile_element_wall_properties, 4); + +struct rct_tile_element_scenerymultiple_properties { + uint16 type; //4 + uint8 colour[2]; //6 +}; +assert_struct_size(rct_tile_element_scenerymultiple_properties, 4); + +struct rct_tile_element_banner_properties { + uint8 index; //4 + uint8 position; //5 + uint8 flags; //6 + uint8 unused; //7 +}; +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_scenery_properties scenery; + rct_tile_element_entrance_properties entrance; + rct_tile_element_wall_properties wall; + rct_tile_element_scenerymultiple_properties scenerymultiple; + rct_tile_element_banner_properties banner; +}; +assert_struct_size(rct_tile_element_properties, 4); + +/** +* Map element structure +* size: 0x08 +*/ +struct rct_tile_element { + uint8 type; //0 + uint8 flags; //1 + uint8 base_height; //2 + uint8 clearance_height; //3 + rct_tile_element_properties properties; +}; +assert_struct_size(rct_tile_element, 8); +#pragma pack(pop) + +enum { + TILE_ELEMENT_QUADRANT_SW, + TILE_ELEMENT_QUADRANT_NW, + TILE_ELEMENT_QUADRANT_NE, + TILE_ELEMENT_QUADRANT_SE +}; + +enum { + TILE_ELEMENT_TYPE_SURFACE = (0 << 2), + TILE_ELEMENT_TYPE_PATH = (1 << 2), + TILE_ELEMENT_TYPE_TRACK = (2 << 2), + TILE_ELEMENT_TYPE_SMALL_SCENERY = (3 << 2), + TILE_ELEMENT_TYPE_ENTRANCE = (4 << 2), + TILE_ELEMENT_TYPE_WALL = (5 << 2), + TILE_ELEMENT_TYPE_LARGE_SCENERY = (6 << 2), + TILE_ELEMENT_TYPE_BANNER = (7 << 2), + // The corrupt element type is used for skipping drawing other following + // elements on a given tile. + TILE_ELEMENT_TYPE_CORRUPT = (8 << 2), +}; + +enum { + TILE_ELEMENT_TYPE_FLAG_HIGHLIGHT = (1 << 6) +}; + +enum { + TILE_ELEMENT_DIRECTION_WEST, + TILE_ELEMENT_DIRECTION_NORTH, + TILE_ELEMENT_DIRECTION_EAST, + TILE_ELEMENT_DIRECTION_SOUTH +}; + +enum { + TILE_ELEMENT_FLAG_GHOST = (1 << 4), + TILE_ELEMENT_FLAG_BROKEN = (1 << 5), + TILE_ELEMENT_FLAG_BLOCK_BRAKE_CLOSED = (1 << 5), + TILE_ELEMENT_FLAG_INDESTRUCTIBLE_TRACK_PIECE = (1 << 6), + TILE_ELEMENT_FLAG_LAST_TILE = (1 << 7) +}; + +enum { + WALL_ANIMATION_FLAG_ACROSS_TRACK = (1 << 2), + // 3 - 6 animation frame number + WALL_ANIMATION_FLAG_DIRECTION_BACKWARD = (1 << 7), + WALL_ANIMATION_FLAG_ALL_FLAGS = WALL_ANIMATION_FLAG_ACROSS_TRACK | WALL_ANIMATION_FLAG_DIRECTION_BACKWARD +}; + +enum { + ENTRANCE_TYPE_RIDE_ENTRANCE, + ENTRANCE_TYPE_RIDE_EXIT, + ENTRANCE_TYPE_PARK_ENTRANCE +}; + +enum { + ELEMENT_IS_ABOVE_GROUND = 1 << 0, + ELEMENT_IS_UNDERGROUND = 1 << 1, + ELEMENT_IS_UNDERWATER = 1 << 2, +}; + +enum +{ + MAP_ELEM_TRACK_SEQUENCE_GREEN_LIGHT = (1 << 7), +}; + +enum +{ + MAP_ELEM_SMALL_SCENERY_COLOUR_FLAG_NEEDS_SUPPORTS = (1 << 5), +}; + +#define TILE_ELEMENT_QUADRANT_MASK 0xC0 +#define TILE_ELEMENT_TYPE_MASK 0x3C +#define TILE_ELEMENT_DIRECTION_MASK 0x03 + +#define TILE_ELEMENT_COLOUR_MASK 0x1F + +#define MAP_ELEM_TRACK_SEQUENCE_STATION_INDEX_MASK 0x70 +#define MAP_ELEM_TRACK_SEQUENCE_SEQUENCE_MASK 0x0F +#define MAP_ELEM_TRACK_SEQUENCE_TAKING_PHOTO_MASK 0xF0 + +uint8 tile_element_get_scenery_quadrant(const rct_tile_element *element); +sint32 tile_element_get_type(const rct_tile_element *element); +sint32 tile_element_get_direction(const rct_tile_element *element); +sint32 tile_element_get_direction_with_offset(const rct_tile_element *element, uint8 offset); +sint32 tile_element_get_banner_index(rct_tile_element *tileElement); +bool tile_element_is_ghost(const rct_tile_element *element); +bool tile_element_is_underground(rct_tile_element *tileElement); + +// ~Oli414: The banner functions should be part of banner. +void tile_element_set_banner_index(rct_tile_element * tileElement, sint32 bannerIndex); +void tile_element_remove_banner_entry(rct_tile_element *tileElement); + +uint8 tile_element_get_ride_index(const rct_tile_element * tileElement); diff --git a/src/openrct2/world/Wall.cpp b/src/openrct2/world/Wall.cpp index 2c64762fd1..a77ccb1f98 100644 --- a/src/openrct2/world/Wall.cpp +++ b/src/openrct2/world/Wall.cpp @@ -689,12 +689,12 @@ static money32 WallSetColour(sint16 x, return 0; } -uint8 wall_element_get_animation_frame(const rct_tile_element * wallElement) +uint8 wall_get_animation_frame(const rct_tile_element * wallElement) { return (wallElement->properties.wall.animation >> 3) & 0xF; } -void wall_element_set_animation_frame(rct_tile_element * wallElement, uint8 frameNum) +void wall_set_animation_frame(rct_tile_element * wallElement, uint8 frameNum) { wallElement->properties.wall.animation &= WALL_ANIMATION_FLAG_ALL_FLAGS; wallElement->properties.wall.animation |= (frameNum & 0xF) << 3; diff --git a/src/openrct2/world/Wall.h b/src/openrct2/world/Wall.h index efafb02aee..e6b85703c2 100644 --- a/src/openrct2/world/Wall.h +++ b/src/openrct2/world/Wall.h @@ -25,4 +25,6 @@ colour_t wall_get_tertiary_colour(const rct_tile_element * tileElement); void wall_set_primary_colour(rct_tile_element * tileElement, colour_t colour); void wall_set_secondary_colour(rct_tile_element * wallElement, colour_t secondaryColour); void wall_set_tertiary_colour(rct_tile_element * tileElement, colour_t colour); +uint8 wall_get_animation_frame(const rct_tile_element * fenceElement); +void wall_set_animation_frame(rct_tile_element * wallElement, uint8 frameNum);