Seperate tile element from map

This commit is contained in:
oli414 2018-05-01 17:47:00 +02:00
parent 3bff12c081
commit c5fd9e67eb
11 changed files with 369 additions and 340 deletions

View File

@ -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"
}
]
}
]
}

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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<TileCoordsXY> tiles)
{
FixLandOwnershipTilesWithOwnership(tiles, OWNERSHIP_AVAILABLE);

View File

@ -20,196 +20,7 @@
#include <initializer_list>
#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<TileCoordsXY> tiles);
void FixLandOwnershipTilesWithOwnership(std::initializer_list<TileCoordsXY> tiles, uint8 ownership);

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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;

View File

@ -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);