implement ride construction

This commit is contained in:
IntelOrca 2015-06-27 15:17:54 +01:00
parent dd95353878
commit 57fd914a52
17 changed files with 4685 additions and 735 deletions

View File

@ -96,6 +96,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release with Tests|Win32'">
</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\src\windows\maze_construction.c" />
<ClCompile Include="..\test\management\finance_test.c" />
<ClCompile Include="..\test\ride\ride_ratings_test.c" />
<ClCompile Include="..\test\tests.c" />

View File

@ -489,6 +489,9 @@
<ClCompile Include="..\src\windows\title_command_editor.c">
<Filter>Source\Windows</Filter>
</ClCompile>
<ClCompile Include="..\src\windows\maze_construction.c">
<Filter>Source\Windows</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\management\award.h">

View File

@ -27,8 +27,8 @@ enum GAME_COMMAND {
GAME_COMMAND_SET_RIDE_APPEARANCE,
GAME_COMMAND_1,
GAME_COMMAND_TOGGLE_PAUSE, // 2
GAME_COMMAND_3, //Has something to do with ride construction
GAME_COMMAND_4,
GAME_COMMAND_PLACE_TRACK,
GAME_COMMAND_REMOVE_TRACK,
GAME_COMMAND_LOAD_OR_QUIT, // 5
GAME_COMMAND_6,
GAME_COMMAND_7,
@ -36,8 +36,8 @@ enum GAME_COMMAND {
GAME_COMMAND_9,
GAME_COMMAND_SET_RIDE_NAME,
GAME_COMMAND_SET_RIDE_SETTING,
GAME_COMMAND_12,
GAME_COMMAND_13,
GAME_COMMAND_PLACE_RIDE_ENTRANCE_OR_EXIT,
GAME_COMMAND_REMOVE_RIDE_ENTRANCE_OR_EXIT,
GAME_COMMAND_REMOVE_SCENERY,
GAME_COMMAND_PLACE_SCENERY,
GAME_COMMAND_16,
@ -71,7 +71,7 @@ enum GAME_COMMAND {
GAME_COMMAND_REMOVE_LARGE_SCENERY,
GAME_COMMAND_SET_CURRENT_LOAN, // 45
GAME_COMMAND_SET_RESEARCH_FUNDING, // 46
GAME_COMMAND_PLACE_TRACK,
GAME_COMMAND_PLACE_TRACK_DESIGN,
GAME_COMMAND_START_MARKETING_CAMPAIGN, // 48
GAME_COMMAND_49,
GAME_COMMAND_PLACE_BANNER, // New banner? (possibly scenery)

View File

@ -126,4 +126,8 @@ void sub_68A15E(int screenX, int screenY, short *x, short *y, int *direction, rc
void viewport_interaction_remove_park_entrance(rct_map_element *mapElement, int x, int y);
void sub_0x68615B(int ebp);
void sub_688485();
void sub_688217();
#endif

View File

@ -564,7 +564,8 @@ rct_window *window_ride_open_vehicle(rct_vehicle *vehicle);
void window_ride_demolish_prompt_open(int rideIndex);
void window_ride_construct(rct_window *w);
void window_ride_list_open();
rct_window * window_construction_open();
rct_window *window_ride_construction_open();
rct_window *window_maze_construction_open();
void window_track_place_open();
rct_window *window_new_ride_open();
rct_window *window_new_ride_open_research();

View File

@ -73,7 +73,7 @@ enum {
STR_CLOSE_X = 824,
STR_CHOSEN_NAME_IN_USE_ALREADY = 825,
STR_TOO_MANY_NAMES_DEFINED = 826,
STR_NOT_ENOUGH_CASH_REQUIRES = 827,
STR_CLOSE_WINDOW_TIP = 828,
STR_WINDOW_TITLE_TIP = 829,
@ -124,6 +124,45 @@ enum {
STR_SCREENSHOT_FAILED = 893,
STR_CANT_BUILD_PARTLY_ABOVE_AND_PARTLY_BELOW_GROUND = 895,
STR_RIDE_CONSTRUCTION_DIRECTION = 897,
STR_RIDE_CONSTRUCTION_LEFT_CURVE_TIP = 898,
STR_RIDE_CONSTRUCTION_RIGHT_CURVE_TIP = 899,
STR_RIDE_CONSTRUCTION_LEFT_CURVE_SMALL_TIP = 900,
STR_RIDE_CONSTRUCTION_RIGHT_CURVE_SMALL_TIP = 901,
STR_RIDE_CONSTRUCTION_LEFT_CURVE_VERY_SMALL_TIP = 902,
STR_RIDE_CONSTRUCTION_RIGHT_CURVE_VERY_SMALL_TIP = 903,
STR_RIDE_CONSTRUCTION_LEFT_CURVE_LARGE_TIP = 904,
STR_RIDE_CONSTRUCTION_RIGHT_CURVE_LARGE_TIP = 905,
STR_RIDE_CONSTRUCTION_STRAIGHT_TIP = 906,
STR_RIDE_CONSTRUCTION_SLOPE = 907,
STR_RIDE_CONSTRUCTION_ROLL_BANKING = 908,
STR_RIDE_CONSTRUCTION_SEAT_ROT = 909,
STR_RIDE_CONSTRUCTION_ROLL_FOR_LEFT_CURVE_TIP = 910,
STR_RIDE_CONSTRUCTION_ROLL_FOR_RIGHT_CURVE_TIP = 911,
STR_RIDE_CONSTRUCTION_NO_ROLL_TIP = 912,
STR_RIDE_CONSTRUCTION_MOVE_TO_PREVIOUS_SECTION_TIP = 913,
STR_RIDE_CONSTRUCTION_MOVE_TO_NEXT_SECTION_TIP = 914,
STR_RIDE_CONSTRUCTION_CONSTRUCT_SELECTED_SECTION_TIP = 915,
STR_RIDE_CONSTRUCTION_REMOVE_HIGHLIGHTED_SECTION_TIP = 916,
STR_RIDE_CONSTRUCTION_VERTICAL_DROP_TIP = 917,
STR_RIDE_CONSTRUCTION_STEEP_SLOPE_DOWN_TIP = 918,
STR_RIDE_CONSTRUCTION_SLOPE_DOWN_TIP = 919,
STR_RIDE_CONSTRUCTION_LEVEL_TIP = 920,
STR_RIDE_CONSTRUCTION_SLOPE_UP_TIP = 921,
STR_RIDE_CONSTRUCTION_STEEP_SLOPE_UP_TIP = 922,
STR_RIDE_CONSTRUCTION_VERTICAL_RISE_TIP = 923,
STR_RIDE_CONSTRUCTION_HELIX_DOWN_TIP = 924,
STR_RIDE_CONSTRUCTION_HELIX_UP_TIP = 925,
STR_RIDE_CONSTRUCTION_CANT_REMOVE_THIS = 926,
STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE = 927,
STR_RIDE_CONSTRUCTION_CHAIN_LIFT_TIP = 928,
STR_S_BEND_LEFT = 929,
STR_S_BEND_RIGHT = 930,
STR_VERTICAL_LOOP_LEFT = 931,
STR_VERTICAL_LOOP_RIGHT = 932,
STR_VIEW_OPTIONS_TIP = 937,
STR_ADJUST_LAND_TIP = 938,
STR_UNDERGROUND_VIEW = 939,
@ -145,6 +184,24 @@ enum {
STR_QUIT_GAME_2_PROMPT_TITLE = 952,
STR_LOAD_LANDSCAPE_PROMPT_TITLE = 953,
STR_RIDE_CONSTRUCTION_SELECT_SEAT_ROTATION_ANGLE_TIP = 955,
STR_RIDE_CONSTRUCTION_SEAT_ROTATION_ANGLE_NEG_180 = 956,
STR_RIDE_CONSTRUCTION_SEAT_ROTATION_ANGLE_NEG_135 = 957,
STR_RIDE_CONSTRUCTION_SEAT_ROTATION_ANGLE_NEG_90 = 958,
STR_RIDE_CONSTRUCTION_SEAT_ROTATION_ANGLE_NEG_45 = 959,
STR_RIDE_CONSTRUCTION_SEAT_ROTATION_ANGLE_0 = 960,
STR_RIDE_CONSTRUCTION_SEAT_ROTATION_ANGLE_45 = 961,
STR_RIDE_CONSTRUCTION_SEAT_ROTATION_ANGLE_90 = 962,
STR_RIDE_CONSTRUCTION_SEAT_ROTATION_ANGLE_135 = 963,
STR_RIDE_CONSTRUCTION_SEAT_ROTATION_ANGLE_180 = 964,
STR_RIDE_CONSTRUCTION_SEAT_ROTATION_ANGLE_225 = 965,
STR_RIDE_CONSTRUCTION_SEAT_ROTATION_ANGLE_270 = 966,
STR_RIDE_CONSTRUCTION_SEAT_ROTATION_ANGLE_315 = 967,
STR_RIDE_CONSTRUCTION_SEAT_ROTATION_ANGLE_360 = 968,
STR_RIDE_CONSTRUCTION_SEAT_ROTATION_ANGLE_405 = 969,
STR_RIDE_CONSTRUCTION_SEAT_ROTATION_ANGLE_450 = 970,
STR_RIDE_CONSTRUCTION_SEAT_ROTATION_ANGLE_495 = 971,
STR_CANCEL = 972,
STR_OK = 973,
@ -166,6 +223,8 @@ enum {
STR_CONSTRUCTION = 990,
STR_STATION_PLATFORM = 991,
STR_DEMOLISH_RIDE_TIP = 992,
STR_DEMOLISH_RIDE = 993,
STR_DEMOLISH = 994,
@ -197,6 +256,11 @@ enum {
STR_LOCATE_SUBJECT_TIP = 1027,
STR_OFF_EDGE_OF_MAP = 1028,
STR_CANNOT_BUILD_PARTLY_ABOVE_AND_PARTLY_BELOW_WATER = 1029,
STR_CAN_ONLY_BUILD_THIS_UNDERWATER = 1030,
STR_RIDE_CANT_BUILD_THIS_UNDERWATER = 1031,
STR_CAN_ONLY_BUILD_THIS_ON_WATER = 1032,
STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND = 1033,
STR_CAN_ONLY_BUILD_THIS_ON_LAND = 1034,
STR_LOAD_GAME_DIALOG_TITLE = 1036,
@ -304,6 +368,11 @@ enum {
STR_SELECT_VEHICLE_COLOUR_SCHEME_TIP = 1140,
STR_SELECT_VEHICLE_TO_MODIFY_TIP = 1141,
STR_CANT_BUILD_MOVE_ENTRANCE_FOR_THIS_RIDE_ATTRACTION = 1144,
STR_CANT_BUILD_MOVE_EXIT_FOR_THIS_RIDE_ATTRACTION = 1145,
STR_ENTRANCE_NOT_YET_BUILT = 1146,
STR_EXIT_NOT_YET_BUILT = 1147,
STR_QUARTER_LOAD = 1148,
STR_HALF_LOAD = 1149,
STR_THREE_QUARTER_LOAD = 1150,
@ -411,6 +480,31 @@ enum {
STR_QUEUE_TIME_MINUTE = 1359,
STR_QUEUE_TIME_MINUTES = 1360,
STR_TOO_HIGH_FOR_SUPPORTS = 1363,
STR_IN_LINE_TWIST_LEFT = 1365,
STR_IN_LINE_TWIST_RIGHT = 1366,
STR_HALF_LOOP = 1367,
STR_HALF_CORKSCREW_LEFT = 1368,
STR_HALF_CORKSCREW_RIGHT = 1369,
STR_BARREL_ROLL_LEFT = 1370,
STR_BARREL_ROLL_RIGHT = 1371,
STR_LAUNCHED_LIFT_HILL = 1372,
STR_LARGE_HALF_LOOP_LEFT = 1373,
STR_LARGE_HALF_LOOP_RIGHT = 1374,
STR_UPPER_TRANSFER = 1375,
STR_LOWER_TRANSFER = 1376,
STR_HEARTLINE_ROLL_LEFT = 1377,
STR_HEARTLINE_ROLL_RIGHT = 1378,
STR_REVERSER_LEFT = 1379,
STR_REVERSER_RIGHT = 1380,
STR_CURVED_LIFT_HILL_LEFT = 1381,
STR_CURVED_LIFT_HILL_RIGHT = 1382,
STR_QUARTER_LOOP = 1383,
STR_RIDE_CONSTRUCTION_OTHER_TRACK_CONFIGURATIONS_TIP = 1385,
STR_RIDE_CONSTRUCTION_SPECIAL = 1386,
STR_VIEW_OF_RIDE_ATTRACTION_TIP = 1392,
STR_VEHICLE_DETAILS_AND_OPTIONS_TIP = 1393,
STR_OPERATING_OPTIONS_TIP = 1394,
@ -420,6 +514,10 @@ enum {
STR_MEASUREMENTS_AND_TEST_DATA_TIP = 1398,
STR_GRAPHS_TIP = 1399,
STR_RIDE_CONSTRUCTION_ENTRANCE = 1400,
STR_RIDE_CONSTRUCTION_EXIT = 1401,
STR_RIDE_CONSTRUCTION_ENTRANCE_TIP = 1402,
STR_RIDE_CONSTRUCTION_EXIT_TIP = 1403,
STR_ROTATE_90_TIP = 1404,
STR_MIRROR_IMAGE_TIP = 1405,
STR_TOGGLE_SCENERY_TIP = 1406,
@ -427,6 +525,9 @@ enum {
STR_BUILD_THIS = 1407,
STR_COST_LABEL = 1408,
STR_ENTRY_EXIT_PLATFORM = 1409,
STR_VERTICAL_TOWER = 1410,
STR_DATA_LOGGING_NOT_AVAILABLE_FOR_THIS_TYPE_OF_RIDE = 1412,
STR_DATA_LOGGING_WILL_START_WHEN_NEXT_LEAVES = 1413,
STR_LOGGING_DATA_FROM_TIP = 1422,
@ -455,9 +556,18 @@ enum {
STR_LOOKING_AT_SCENERY = 1446,
STR_LEAVING_PARK = 1447,
STR_WATCHING_NEW_RIDE_BEING_CONSTRUCTED = 1448,
STR_RIDE_CONSTRUCTION_TRACK_STYLE = 1459,
STR_RIDE_CONSTRUCTION_U_SHAPED_OPEN_TRACK_TIP = 1460,
STR_RIDE_CONSTRUCTION_O_SHAPED_ENCLOSED_TRACK_TIP = 1461,
STR_GUESTS = 1463,
STR_HELIX_UP_SMALL = 1464,
STR_HELIX_UP_LARGE = 1465,
STR_HELIX_DOWN_SMALL = 1466,
STR_HELIX_DOWN_LARGE = 1467,
STR_STAFF = 1468,
STR_RIDE_MUST_START_AND_END_WITH_STATIONS = 1469,
@ -484,9 +594,27 @@ enum {
STR_TOTAL_CUSTOMERS = 1670,
STR_TOTAL_PROFIT = 1671,
STR_BRAKES = 1672,
STR_SPINNING_CONTROL_TOGGLE_TRACK = 1673,
STR_RIDE_CONSTRUCTION_BRAKE_SPEED = 1674,
STR_RIDE_CONSTRUCTION_BRAKE_SPEED_LIMIT_TIP = 1676,
STR_POPULARITY_UNKNOWN = 1677,
STR_POPULARITY_PERCENT = 1678,
STR_HELIX_UP_LEFT = 1679,
STR_HELIX_UP_RIGHT = 1680,
STR_HELIX_DOWN_LEFT = 1681,
STR_HELIX_DOWN_RIGHT = 1682,
STR_BASE_SIZE_2_X_2 = 1683,
STR_BASE_SIZE_4_X_4 = 1684,
STR_BASE_SIZE_2_X_4 = 1685,
STR_BASE_SIZE_5_X_1 = 1686,
STR_WATER_SPLASH = 1687,
STR_BASE_SIZE_4_X_1 = 1688,
STR_BLOCK_BRAKES = 1689,
STR_GUESTS_TIP = 1693,
STR_STAFF_TIP = 1694,
@ -523,6 +651,9 @@ enum {
STR_BANNER_TEXT = 1731,
STR_RIDE_CONSTRUCTION_BUILD = 1732,
STR_RIDE_CONSTRUCTION_MODE = 1733,
STR_NUMBER_OF_LAPS = 1734,
STR_NUMBER_OF_LAPS_TIP = 1735,
@ -542,6 +673,18 @@ enum {
STR_ADMISSION_PRICE = 1756,
STR_RELIABILITY_LABEL_1757 = 1757,
STR_RIDE_CONSTRUCTION_BUILD_MODE = 1758,
STR_RIDE_CONSTRUCTION_MOVE_MODE = 1759,
STR_RIDE_CONSTRUCTION_FILL_IN_MODE = 1760,
STR_RIDE_CONSTRUCTION_BUILD_MAZE_IN_THIS_DIRECTION_TIP = 1761,
STR_WATERFALLS = 1762,
STR_RAPIDS = 1763,
STR_LOG_BUMPS = 1764,
STR_ON_RIDE_PHOTO_SECTION = 1765,
STR_REVERSER_TURNTABLE = 1766,
STR_SPINNING_TUNNEL = 1767,
STR_NUMBER_OF_SWINGS = 1769,
STR_NUMBER_OF_SWINGS_TIP = 1770,
@ -557,6 +700,8 @@ enum {
STR_ANSWERING_RADIO_CALL = 1795,
STR_HAS_BROKEN_DOWN_AND_REQUIRES_FIXING = 1796,
STR_WHIRLPOOL = 1798,
STR_SAFETY_CUT_OUT = 1800,
STR_RESTRAINTS_STUCK_CLOSED = 1801,
STR_RESTRAINTS_STUCK_OPEN = 1802,
@ -735,6 +880,11 @@ enum {
STR_COMPANY_VALUE_LABEL = 2227,
STR_LAST_MONTH_PROFIT_FROM_FOOD_DRINK_MERCHANDISE_SALES_LABEL = 2228,
STR_SLOPE_UP_TO_VERTICAL = 2229,
STR_VERTICAL_TRACK = 2230,
STR_HOLDING_BRAKE_FOR_DROP = 2231,
STR_CABLE_LIFT_HILL = 2232,
STR_PARK_INFORMATION_TIP = 2233,
STR_RECENT_MESSAGES = 2234,
@ -995,6 +1145,15 @@ enum {
STR_SHORTCUT_DESCRIPTION_31 = 2524,
STR_INDIVIDUAL_KEYS_BASE = 2525,
STR_GOLF_HOLE_A = 3049,
STR_GOLF_HOLE_B = 3050,
STR_GOLF_HOLE_C = 3051,
STR_GOLF_HOLE_D = 3052,
STR_GOLF_HOLE_E = 3053,
STR_TOP_SECTION = 3069,
STR_SLOPE_TO_LEVEL = 3070,
// Cheats
STR_CHEAT_TITLE = 5217,
STR_CHEAT_TITLE_FINANCIAL = 5345,
@ -1220,6 +1379,9 @@ enum {
STR_HEDGES = 3059,
STR_ICE_BLOCKS = 3060,
STR_WOODEN_FENCES = 3061,
STR_RIDE_CONSTRUCTION_STANDARD_RC_TRACK_TIP = 3062,
STR_RIDE_CONSTRUCTION_WATER_CHANNEL_TIP = 3063,
STR_BEGINNER_PARKS = 3064,
STR_CHALLENGING_PARKS = STR_BEGINNER_PARKS + 1,

View File

@ -328,7 +328,7 @@ int sub_6CAF80(int rideIndex, rct_xy_element *output)
*
* rct2: 0x006C60C2
*/
int track_get_next(rct_xy_element *input, rct_xy_element *output)
bool track_get_next(rct_xy_element *input, rct_xy_element *output, int *z, int *direction)
{
int eax, ebx, ecx, edx, esi, edi, ebp, result;
@ -339,10 +339,37 @@ int track_get_next(rct_xy_element *input, rct_xy_element *output)
output->x = *((uint16*)&eax);
output->y = *((uint16*)&ecx);
output->element = (rct_map_element*)esi;
if (z != NULL) *z = (edx & 0xFFFF);
if (direction != NULL) *direction = (ebx & 0xFF);
return (result & 0x100) == 0;
}
/**
*
* rct2: 0x006C6402
*/
bool track_get_previous(int x, int y, rct_map_element *mapElement, track_begin_end *outTrackBeginEnd)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
eax = x;
ecx = y;
esi = (int)mapElement;
int result = RCT2_CALLFUNC_X(0x006C6402, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
if (outTrackBeginEnd != NULL) {
outTrackBeginEnd->begin_x = ((eax >> 16) & 0xFFFF);
outTrackBeginEnd->begin_y = ((ecx >> 16) & 0xFFFF);
outTrackBeginEnd->begin_z = (edx & 0xFFFF);
outTrackBeginEnd->begin_direction = ((ebx >> 8) & 0xFF);
outTrackBeginEnd->begin_element = (rct_map_element*)esi;
outTrackBeginEnd->end_x = (eax & 0xFFFF);
outTrackBeginEnd->end_y = (ecx & 0xFFFF);
outTrackBeginEnd->end_direction = (ebx & 0xFF);
}
return (result & 0x100) == 0;
}
/**
*
* Make sure to pass in the x and y of the start track element too.
@ -367,12 +394,12 @@ int ride_find_track_gap(rct_xy_element *input, rct_xy_element *output)
return 0;
w = window_find_by_class(WC_RIDE_CONSTRUCTION);
if (w != NULL && RCT2_GLOBAL(0x00F440A6, uint8) != 0 && RCT2_GLOBAL(0x00F440A7, uint8) == rideIndex)
if (w != NULL && _rideConstructionState != RIDE_CONSTRUCTION_STATE_0 && _currentRideIndex == rideIndex)
sub_6C9627();
loopTrackElement = NULL;
while (1) {
if (!track_get_next(&trackElement, &nextTrackElement)) {
if (!track_get_next(&trackElement, &nextTrackElement, NULL, NULL)) {
*output = trackElement;
return 1;
}
@ -544,11 +571,11 @@ static rct_window *ride_create_or_find_construction_window(int rideIndex)
w = window_find_by_class(WC_RIDE_CONSTRUCTION);
if (w == NULL || w->number != rideIndex) {
window_close_construction_windows();
RCT2_GLOBAL(0x00F440A7, uint8) = rideIndex;
w = window_construction_open(rideIndex);
_currentRideIndex = rideIndex;
w = window_ride_construction_open(rideIndex);
} else {
sub_6C9627();
RCT2_GLOBAL(0x00F440A7, uint8) = rideIndex;
_currentRideIndex = rideIndex;
}
return w;
@ -604,15 +631,6 @@ void ride_construct(int rideIndex)
}
}
/**
*
* rct2: 0x006C84CE
*/
static void sub_6C84CE()
{
RCT2_CALLPROC_X(0x006C84CE, 0, 0, 0, 0, 0, 0, 0);
}
/**
*
* rct2: 0x006DD4D5
@ -779,7 +797,9 @@ void ride_remove_peeps(int rideIndex)
ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN;
}
/* rct2: 0x006C683D
/**
* Gets the origin track element (sequence 0). Seems to do more than that though and even invalidates track.
* rct2: 0x006C683D
* ax : x
* bx : direction << 8, type
* cx : y
@ -790,49 +810,38 @@ void ride_remove_peeps(int rideIndex)
*/
int sub_6C683D(int* x, int* y, int* z, int direction, int type, uint16 extra_params, rct_map_element** output_element, uint16 flags)
{
rct_map_element* map_element = map_get_first_element_at(*x / 32, *y / 32);
rct_map_element* success_map = NULL;
rct_map_element *mapElement = map_get_first_element_at(*x / 32, *y / 32);
rct_map_element *successMapElement = NULL;
do{
if (map_element->base_height != *z / 8)
do {
if (mapElement->base_height != *z / 8)
continue;
if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_TRACK)
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_TRACK)
continue;
if ((map_element->type & MAP_ELEMENT_DIRECTION_MASK) != direction)
if ((mapElement->type & MAP_ELEMENT_DIRECTION_MASK) != direction)
continue;
if (type != map_element->properties.track.type)
if (type != mapElement->properties.track.type)
continue;
success_map = map_element;
if (!(map_element->properties.track.sequence & 0xF))
successMapElement = mapElement;
if ((mapElement->properties.track.sequence & 0x0F) == 0)
break;
}while(!map_element_is_last_for_tile(map_element++));
} while (!map_element_is_last_for_tile(mapElement++));
map_element = success_map;
if (map_element == NULL){
mapElement = successMapElement;
if (mapElement == NULL)
return 1;
}
// Possibly z should be &0xF8
rct_ride* ride = GET_RIDE(map_element->properties.track.ride_index);
rct_preview_track *trackBlock;
// Possibly z should be & 0xF8
rct_preview_track *trackBlock = get_track_def_from_ride_index(mapElement->properties.track.ride_index, type);
if (RCT2_ADDRESS(RCT2_ADDRESS_RIDE_FLAGS, uint32)[ride->type * 2] & RIDE_TYPE_FLAG_FLAT_RIDE){
trackBlock = RCT2_ADDRESS(0x00994A38, rct_preview_track*)[type];
}
else{
trackBlock = RCT2_ADDRESS(0x00994638, rct_preview_track*)[type];
}
int sequence = mapElement->properties.track.sequence & 0x0F;
uint8 mapDirection = mapElement->type & MAP_ELEMENT_DIRECTION_MASK;
int sequence = map_element->properties.track.sequence & 0xF;
uint8 map_direction = map_element->type & MAP_ELEMENT_DIRECTION_MASK;
switch (map_direction){
switch (mapDirection){
case MAP_ELEMENT_DIRECTION_WEST:
*x -= trackBlock[sequence].x;
*y -= trackBlock[sequence].y;
@ -850,17 +859,13 @@ int sub_6C683D(int* x, int* y, int* z, int direction, int type, uint16 extra_par
*y -= trackBlock[sequence].x;
break;
}
*z -= trackBlock[sequence].z;
int start_x = *x, start_y = *y, start_z = *z;
*z += trackBlock[0].z;
for (int i = 0; trackBlock[i].var_00 != 0xFF; ++i){
int cur_x = start_x, cur_y = start_y, cur_z = start_z;
switch (map_direction){
switch (mapDirection){
case MAP_ELEMENT_DIRECTION_WEST:
cur_x += trackBlock[i].x;
cur_y += trackBlock[i].y;
@ -878,134 +883,334 @@ int sub_6C683D(int* x, int* y, int* z, int direction, int type, uint16 extra_par
cur_y += trackBlock[i].x;
break;
}
cur_z += trackBlock[i].z;
map_invalidate_tile_full(cur_x, cur_y);
map_element = map_get_first_element_at(cur_x / 32, cur_y / 32);
success_map = NULL;
do{
if (map_element->base_height != cur_z / 8)
mapElement = map_get_first_element_at(cur_x / 32, cur_y / 32);
successMapElement = NULL;
do {
if (mapElement->base_height != cur_z / 8)
continue;
if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_TRACK)
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_TRACK)
continue;
if ((map_element->type & MAP_ELEMENT_DIRECTION_MASK) != direction)
if ((mapElement->type & MAP_ELEMENT_DIRECTION_MASK) != direction)
continue;
if ((map_element->properties.track.sequence & 0xF) != trackBlock[i].var_00)
if ((mapElement->properties.track.sequence & 0xF) != trackBlock[i].var_00)
continue;
if (type == map_element->properties.track.type)
{
success_map = map_element;
if (type == mapElement->properties.track.type) {
successMapElement = mapElement;
break;
}
} while (!map_element_is_last_for_tile(map_element++));
} while (!map_element_is_last_for_tile(mapElement++));
if (success_map == NULL){
if (successMapElement == NULL) {
return 1;
}
if (i == 0 && output_element != NULL)
*output_element = map_element;
if (flags & (1 << 0)){
// Quadrant related ??
map_element->type &= ~(1 << 6);
if (i == 0 && output_element != NULL) {
*output_element = mapElement;
}
if (flags & (1 << 1)){
// Quadrant related ??
map_element->type |= (1 << 6);
if (flags & (1 << 0)) {
// Switch highlight off
mapElement->type &= ~MAP_ELEMENT_TYPE_FLAG_HIGHLIGHT;
}
if (flags & (1 << 2)){
map_element->properties.track.colour &= 0xFC;
map_element->properties.track.colour |= extra_params & 0xFF;
if (flags & (1 << 1)) {
// Switch highlight on
mapElement->type |= MAP_ELEMENT_TYPE_FLAG_HIGHLIGHT;
}
if (flags & (1 << 5)){
map_element->properties.track.colour &= 0x0F;
map_element->properties.track.colour |= (extra_params & 0xFF) << 4;
if (flags & (1 << 2)) {
mapElement->properties.track.colour &= 0xFC;
mapElement->properties.track.colour |= extra_params & 0xFF;
}
if (flags & (1 << 3)){
map_element->properties.track.colour |= (1 << 3);
if (flags & (1 << 5)) {
// Seat rotation
mapElement->properties.track.colour &= 0x0F;
mapElement->properties.track.colour |= (extra_params & 0xFF) << 4;
}
if (flags & (1 << 4)){
map_element->properties.track.colour &= 0xF7;
if (flags & (1 << 3)) {
mapElement->properties.track.colour |= (1 << 3);
}
if (flags & (1 << 4)) {
mapElement->properties.track.colour &= 0xF7;
}
}
return 0;
}
/**
*
* rct2: 0x006C6096
*/
rct_map_element *sub_6C6096(int *x, int *y, int *z, int *direction, int *direction2)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
eax = *x;
ecx = *y;
edx = *z;
ebx = *direction;
if (RCT2_CALLFUNC_X(0x006C6096, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp) & 0x100)
return NULL;
*x = (eax & 0xFFFF);
*y = (ecx & 0xFFFF);
*z = (edx & 0xFFFF);
*direction = (ebx & 0xFF);
if (direction2 != NULL) *direction2 = ((ebx >> 8) & 0xFF);
return (rct_map_element*)esi;
}
/**
* Returns the begin position / direction and end position / direction of the track piece that procedes the given location.
* rct2: 0x006C63D6
*/
bool sub_6C63D6(int inX, int inY, int inZ, int inDirection, track_begin_end *outTrackBeginEnd)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
eax = inX;
ecx = inY;
edx = inZ;
ebx = inDirection;
if (RCT2_CALLFUNC_X(0x006C63D6, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp) & 0x100)
return false;
if (outTrackBeginEnd != NULL) {
outTrackBeginEnd->begin_x = ((eax >> 16) & 0xFFFF);
outTrackBeginEnd->begin_y = ((ecx >> 16) & 0xFFFF);
outTrackBeginEnd->begin_z = (edx & 0xFFFF);
outTrackBeginEnd->begin_direction = ((ebx >> 8) & 0xFF);
outTrackBeginEnd->begin_element = (rct_map_element*)esi;
outTrackBeginEnd->end_x = (eax & 0xFFFF);
outTrackBeginEnd->end_y = (ecx & 0xFFFF);
outTrackBeginEnd->end_direction = (ebx & 0xFF);
}
return true;
}
/**
*
* rct2: 0x006C96C0
*/
void sub_6C96C0()
{
RCT2_CALLPROC_X(0x006C96C0, 0, 0, 0, 0, 0, 0, 0);
// RCT2_CALLPROC_X(0x006C96C0, 0, 0, 0, 0, 0, 0, 0); return;
rct_ride *ride;
rct_map_element *trackElement;
int rideIndex, x, y, z, direction;
if (_currentTrackSelectionFlags & 4) {
_currentTrackSelectionFlags &= ~4;
game_do_command(
RCT2_GLOBAL(0x00F440BF, uint16),
41,
RCT2_GLOBAL(0x00F440C1, uint16),
_currentRideIndex,
GAME_COMMAND_REMOVE_RIDE_ENTRANCE_OR_EXIT,
RCT2_GLOBAL(0x00F440C4, uint8),
0
);
}
if (_currentTrackSelectionFlags & 2) {
_currentTrackSelectionFlags &= ~2;
rideIndex = _currentRideIndex;
RCT2_GLOBAL(0x00F441D2, uint8) = rideIndex;
x = RCT2_GLOBAL(0x00F440C5, uint16);
y = RCT2_GLOBAL(0x00F440C7, uint16);
z = RCT2_GLOBAL(0x00F440C9, uint16);
ride = GET_RIDE(rideIndex);
if (ride->type == RIDE_TYPE_MAZE) {
game_do_command(x , 41 | (0 << 8), y , rideIndex | (2 << 8), GAME_COMMAND_38, z, 0);
game_do_command(x , 41 | (1 << 8), y + 16, rideIndex | (2 << 8), GAME_COMMAND_38, z, 0);
game_do_command(x + 16, 41 | (2 << 8), y + 16, rideIndex | (2 << 8), GAME_COMMAND_38, z, 0);
game_do_command(x + 16, 41 | (3 << 8), y , rideIndex | (2 << 8), GAME_COMMAND_38, z, 0);
} else {
direction = RCT2_GLOBAL(0x00F440CB, uint8);
if (!(direction & 4)) {
x -= TileDirectionDelta[direction].x;
y -= TileDirectionDelta[direction].y;
}
trackElement = sub_6C6096(&x, &y, &z, &direction, NULL);
if (trackElement != NULL) {
game_do_command(
x,
105 | ((direction & 3) << 8),
y,
trackElement->properties.track.type | ((trackElement->properties.track.sequence & 0x0F) << 8),
GAME_COMMAND_REMOVE_TRACK,
z,
0
);
}
}
}
}
void sub_6C9627()
{
switch (RCT2_GLOBAL(0x00F440A6, uint8)) {
case 3:
{
int x = RCT2_GLOBAL(0x00F440A8, uint16), y = RCT2_GLOBAL(0x00F440AA, uint16), z = RCT2_GLOBAL(0x00F440AC, uint16);
int x, y, z;
switch (_rideConstructionState) {
case RIDE_CONSTRUCTION_STATE_SELECTED:
x = _currentTrackBeginX;
y = _currentTrackBeginY;
z = _currentTrackBeginZ;
sub_6C683D(
&x,
&y,
&z,
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint8) & 3,
RCT2_GLOBAL(0x00F440AF, uint8),
0,
_currentTrackPieceDirection & 3,
_currentTrackPieceType,
0,
NULL,
1
);
}
);
break;
case 6:
case 7:
case 8:
if (RCT2_GLOBAL(0x00F440B0, uint8) & 1) {
case RIDE_CONSTRUCTION_STATE_6:
case RIDE_CONSTRUCTION_STATE_7:
case RIDE_CONSTRUCTION_STATE_8:
if (_currentTrackSelectionFlags & 1) {
map_invalidate_tile_full(
RCT2_GLOBAL(0x00F440A8, uint16) & 0xFFE0,
RCT2_GLOBAL(0x00F440AA, uint16) & 0xFFE0
_currentTrackBeginX & 0xFFE0,
_currentTrackBeginY & 0xFFE0
);
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~4;
}
break;
default:
if (RCT2_GLOBAL(0x00F440B0, uint8) & 1) {
RCT2_GLOBAL(0x00F440B0, uint8) &= ~1;
if (_currentTrackSelectionFlags & 1) {
_currentTrackSelectionFlags &= ~1;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint8) &= ~4;
map_invalidate_tile_full(RCT2_GLOBAL(0x00F440A8, uint16), RCT2_GLOBAL(0x00F440AA, uint16));
map_invalidate_tile_full(_currentTrackBeginX, _currentTrackBeginY);
}
sub_6C96C0();
break;
}
}
/**
*
* rct2: 0x006C9800
*/
void sub_6C9800()
{
RCT2_CALLPROC_EBPSAFE(0x006C9800);
}
/**
*
* rct2: 0x006C9296
*/
static void sub_6C9296()
void ride_select_next_section()
{
RCT2_CALLPROC_X(0x006C9296, 0, 0, 0, 0, 0, 0, 0);
int x, y, z, direction, type;
rct_map_element *mapElement;
rct_xy_element inputElement, outputElement;
if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_SELECTED) {
sub_6C9627();
x = _currentTrackBeginX;
y = _currentTrackBeginY;
z = _currentTrackBeginZ;
direction = _currentTrackPieceDirection;
type = _currentTrackPieceType;
if (sub_6C683D(&x, &y, &z, direction & 3, type, 0, &mapElement, 0)) {
_rideConstructionState = RIDE_CONSTRUCTION_STATE_0;
sub_6C84CE();
return;
}
inputElement.x = x;
inputElement.y = y;
inputElement.element = mapElement;
if (track_get_next(&inputElement, &outputElement, &z, &direction)) {
x = outputElement.x;
y = outputElement.y;
mapElement = outputElement.element;
} else {
_rideConstructionState = RIDE_CONSTRUCTION_STATE_FRONT;
_currentTrackBeginX = outputElement.x;
_currentTrackBeginY = outputElement.y;
_currentTrackBeginZ = z;
_currentTrackPieceDirection = direction;
_currentTrackPieceType = mapElement->properties.track.type;
_currentTrackSelectionFlags = 0;
_rideConstructionArrowPulseTime = 0;
sub_6C9800();
sub_6C84CE();
return;
}
_currentTrackBeginX = x;
_currentTrackBeginY = y;
_currentTrackBeginZ = z;
_currentTrackPieceDirection = (mapElement->type & MAP_ELEMENT_DIRECTION_MASK);
_currentTrackPieceType = mapElement->properties.track.type;
_currentTrackSelectionFlags = 0;
_rideConstructionArrowPulseTime = 0;
sub_6C84CE();
} else if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK) {
if (ride_select_forwards_from_back()) {
sub_6C84CE();
}
}
}
/**
*
* rct2: 0x006C93B8
*/
static void sub_6C93B8()
void ride_select_previous_section()
{
RCT2_CALLPROC_X(0x006C93B8, 0, 0, 0, 0, 0, 0, 0);
int x, y, z, direction, type;
rct_map_element *mapElement;
track_begin_end trackBeginEnd;
if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_SELECTED) {
sub_6C9627();
x = _currentTrackBeginX;
y = _currentTrackBeginY;
z = _currentTrackBeginZ;
direction = _currentTrackPieceDirection;
type = _currentTrackPieceType;
if (sub_6C683D(&x, &y, &z, direction & 3, type, 0, &mapElement, 0)) {
_rideConstructionState = RIDE_CONSTRUCTION_STATE_0;
sub_6C84CE();
return;
}
if (track_get_previous(x, y, mapElement, &trackBeginEnd)) {
_currentTrackBeginX = trackBeginEnd.begin_x;
_currentTrackBeginY = trackBeginEnd.begin_y;
_currentTrackBeginZ = trackBeginEnd.begin_z;
_currentTrackPieceDirection = trackBeginEnd.begin_direction;
_currentTrackPieceType = trackBeginEnd.begin_element->properties.track.type;
_currentTrackSelectionFlags = 0;
_rideConstructionArrowPulseTime = 0;
sub_6C84CE();
} else {
_rideConstructionState = RIDE_CONSTRUCTION_STATE_BACK;
_currentTrackBeginX = trackBeginEnd.end_x;
_currentTrackBeginY = trackBeginEnd.end_y;
_currentTrackBeginZ = trackBeginEnd.begin_z;
_currentTrackPieceDirection = trackBeginEnd.end_direction;
_currentTrackPieceType = mapElement->properties.track.type;
_currentTrackSelectionFlags = 0;
_rideConstructionArrowPulseTime = 0;
sub_6C9800();
sub_6C84CE();
}
} else if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_FRONT) {
if (ride_select_backwards_from_front()) {
sub_6C84CE();
}
}
}
/**
@ -1038,7 +1243,7 @@ static int ride_modify_entrance_or_exit(rct_map_element *mapElement, int x, int
sub_6C9627();
if (
RCT2_GLOBAL(0x00F440A6, uint8) != 5 ||
_rideConstructionState != RIDE_CONSTRUCTION_STATE_ENTRANCE_EXIT ||
!(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint8) & INPUT_FLAG_TOOL_ACTIVE) ||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) != WC_RIDE_CONSTRUCTION
) {
@ -1048,17 +1253,16 @@ static int ride_modify_entrance_or_exit(rct_map_element *mapElement, int x, int
RCT2_GLOBAL(0x00F44192, uint8) = rideIndex;
RCT2_GLOBAL(0x00F44193, uint8) = bl;
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint8) |= INPUT_FLAG_6;
int al = RCT2_GLOBAL(0x00F440A6, uint8);
if (al != 5) {
RCT2_GLOBAL(0x00F440A6, uint8) = 5;
RCT2_GLOBAL(0x00F440CC, uint8) = al;
if (_rideConstructionState != RIDE_CONSTRUCTION_STATE_ENTRANCE_EXIT) {
RCT2_GLOBAL(0x00F440CC, uint8) = _rideConstructionState;
_rideConstructionState = RIDE_CONSTRUCTION_STATE_ENTRANCE_EXIT;
}
sub_6C84CE();
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~2;
} else {
// Remove entrance / exit
game_do_command(x, 9, y, rideIndex, GAME_COMMAND_13, bl, 0);
game_do_command(x, 9, y, rideIndex, GAME_COMMAND_REMOVE_RIDE_ENTRANCE_OR_EXIT, bl, 0);
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16) = entranceType == ENTRANCE_TYPE_RIDE_ENTRANCE ? 29 : 30;
RCT2_GLOBAL(0x00F44191, uint8) = entranceType;
}
@ -1073,13 +1277,13 @@ static int ride_modify_entrance_or_exit(rct_map_element *mapElement, int x, int
*/
int ride_modify_maze(rct_map_element *mapElement, int x, int y)
{
RCT2_GLOBAL(0x00F440A7, uint8) = mapElement->properties.track.ride_index;
RCT2_GLOBAL(0x00F440A6, uint8) = 6;
RCT2_GLOBAL(0x00F440A8, uint16) = x;
RCT2_GLOBAL(0x00F440AA, uint16) = y;
RCT2_GLOBAL(0x00F440AC, uint16) = mapElement->base_height * 8;
RCT2_GLOBAL(0x00F440B0, uint8) = 0;
RCT2_GLOBAL(0x00F440B1, uint8) = 0;
_currentRideIndex = mapElement->properties.track.ride_index;
_rideConstructionState = RIDE_CONSTRUCTION_STATE_6;
_currentTrackBeginX = x;
_currentTrackBeginY = y;
_currentTrackBeginZ = mapElement->base_height * 8;
_currentTrackSelectionFlags = 0;
_rideConstructionArrowPulseTime = 0;
RCT2_CALLPROC_X(0x006CD887, 0, 0, 0, 0, 0, 0, 0);
return 1;
}
@ -1139,50 +1343,50 @@ int ride_modify(rct_xy_element *input)
direction = mapElement.element->type & 3;
type = mapElement.element->properties.track.type;
if (sub_6C683D(&x, &y, &z, direction, type, 0, 0, 0))
if (sub_6C683D(&x, &y, &z, direction, type, 0, NULL, 0))
return 0;
RCT2_GLOBAL(0x00F440A7, uint8) = rideIndex;
RCT2_GLOBAL(0x00F440A6, uint8) = 3;
RCT2_GLOBAL(0x00F440A8, uint16) = x;
RCT2_GLOBAL(0x00F440AA, uint16) = y;
RCT2_GLOBAL(0x00F440AC, uint16) = z;
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint8) = direction;
RCT2_GLOBAL(0x00F440AF, uint8) = type;
RCT2_GLOBAL(0x00F440B0, uint8) = 0;
RCT2_GLOBAL(0x00F440B1, uint8) = 0;
_currentRideIndex = rideIndex;
_rideConstructionState = RIDE_CONSTRUCTION_STATE_SELECTED;
_currentTrackBeginX = x;
_currentTrackBeginY = y;
_currentTrackBeginZ = z;
_currentTrackPieceDirection = direction;
_currentTrackPieceType = type;
_currentTrackSelectionFlags = 0;
_rideConstructionArrowPulseTime = 0;
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_15)) {
sub_6C84CE();
return 1;
}
sub_6C9296();
if (RCT2_GLOBAL(0x00F440A6, uint8) == 1) {
ride_select_next_section();
if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_FRONT) {
sub_6C84CE();
return 1;
}
RCT2_GLOBAL(0x00F440A6, uint8) = 3;
RCT2_GLOBAL(0x00F440A8, uint16) = x;
RCT2_GLOBAL(0x00F440AA, uint16) = y;
RCT2_GLOBAL(0x00F440AC, uint16) = z;
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint8) = direction;
RCT2_GLOBAL(0x00F440AF, uint8) = type;
RCT2_GLOBAL(0x00F440B0, uint8) = 0;
RCT2_GLOBAL(0x00F440B1, uint8) = 0;
_rideConstructionState = RIDE_CONSTRUCTION_STATE_SELECTED;
_currentTrackBeginX = x;
_currentTrackBeginY = y;
_currentTrackBeginZ = z;
_currentTrackPieceDirection = direction;
_currentTrackPieceType = type;
_currentTrackSelectionFlags = 0;
_rideConstructionArrowPulseTime = 0;
sub_6C93B8();
ride_select_previous_section();
if (RCT2_GLOBAL(0x00F440A6, uint8) != 2) {
RCT2_GLOBAL(0x00F440A6, uint8) = 3;
RCT2_GLOBAL(0x00F440A8, uint16) = x;
RCT2_GLOBAL(0x00F440AA, uint16) = y;
RCT2_GLOBAL(0x00F440AC, uint16) = z;
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint8) = direction;
RCT2_GLOBAL(0x00F440AF, uint8) = type;
RCT2_GLOBAL(0x00F440B0, uint8) = 0;
RCT2_GLOBAL(0x00F440B1, uint8) = 0;
if (_rideConstructionState != RIDE_CONSTRUCTION_STATE_BACK) {
_rideConstructionState = RIDE_CONSTRUCTION_STATE_SELECTED;
_currentTrackBeginX = x;
_currentTrackBeginY = y;
_currentTrackBeginZ = z;
_currentTrackPieceDirection = direction;
_currentTrackPieceType = type;
_currentTrackSelectionFlags = 0;
_rideConstructionArrowPulseTime = 0;
}
sub_6C84CE();
@ -1212,24 +1416,24 @@ int sub_6CC3FB(int rideIndex)
tool_set(w, 23, 12);
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
ride = GET_RIDE(RCT2_GLOBAL(0x00F440A7, uint8));
ride = GET_RIDE(_currentRideIndex);
RCT2_GLOBAL(0x00F440A0, uint16) = RCT2_ADDRESS(0x0097CC68, uint8)[ride->type * 2] | 0x100;
RCT2_GLOBAL(0x00F440B2, uint8) = 0;
_currentTrackCurve = RCT2_ADDRESS(0x0097CC68, uint8)[ride->type * 2] | 0x100;
_currentTrackSlopeEnd = 0;
RCT2_GLOBAL(0x00F440B3, uint8) = 0;
RCT2_GLOBAL(0x00F440B4, uint8) = 0;
RCT2_GLOBAL(0x00F440B5, uint8) = 0;
_currentTrackLiftHill = 0;
_currentTrackCovered = 0;
if (RCT2_GLOBAL(0x0097D4F2 + (ride->type * 8), uint16) & 0x8000)
RCT2_GLOBAL(0x00F440B5, uint8) |= 2;
_currentTrackCovered |= 2;
RCT2_GLOBAL(0x00F440B6, uint8) = 0;
RCT2_GLOBAL(0x00F440B7, uint8) = 0;
_previousTrackBankEnd = 0;
_previousTrackSlopeEnd = 0;
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint8) = 0;
RCT2_GLOBAL(0x00F440A6, uint8) = 4;
RCT2_GLOBAL(0x00F440B0, uint8) = 0;
RCT2_GLOBAL(0x00F440B1, uint8) = 0;
_currentTrackPieceDirection = 0;
_rideConstructionState = RIDE_CONSTRUCTION_STATE_PLACE;
_currentTrackSelectionFlags = 0;
_rideConstructionArrowPulseTime = 0;
RCT2_GLOBAL(0x00F44159, uint8) = 0;
RCT2_GLOBAL(0x00F4415C, uint8) = 0;
@ -3339,12 +3543,12 @@ int ride_check_block_brakes(rct_xy_element *input, rct_xy_element *output)
trackElement = *input;
rideIndex = trackElement.element->properties.track.ride_index;
w = window_find_by_class(WC_RIDE_CONSTRUCTION);
if (w != NULL && RCT2_GLOBAL(0x00F440A6, uint8) != 0 && RCT2_GLOBAL(0x00F440A7, uint8) == rideIndex)
if (w != NULL && _rideConstructionState != RIDE_CONSTRUCTION_STATE_0 && _currentRideIndex == rideIndex)
sub_6C9627();
loopTrackElement = NULL;
while (1) {
if (!track_get_next(&trackElement, &nextTrackElement)) {
if (!track_get_next(&trackElement, &nextTrackElement, NULL, NULL)) {
// Not sure why this is the case...
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_BLOCK_BRAKES_CANNOT_BE_USED_DIRECTLY_AFTER_STATION;
*output = trackElement;
@ -3502,7 +3706,7 @@ void sub_6B4D26(int rideIndex, rct_xy_element *startElement)
currentElement.element->flags &= ~(1 << 5);
break;
}
} while (track_get_next(&currentElement, &currentElement) && currentElement.element != startElement->element);
} while (track_get_next(&currentElement, &currentElement, NULL, NULL) && currentElement.element != startElement->element);
}
}
@ -4091,7 +4295,7 @@ int ride_get_refund_price(int ride_id)
}else{
edx |= 0xFF << 8;
edx &= ((map_element->properties.track.sequence & 0xF) << 8) | 0xFF;
RCT2_GLOBAL(0x00F4413A, int) += game_do_command_p(GAME_COMMAND_4, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
RCT2_GLOBAL(0x00F4413A, int) += game_do_command_p(GAME_COMMAND_REMOVE_TRACK, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
}
y -= 32;
break;
@ -4509,7 +4713,6 @@ void ride_all_has_any_track_elements(bool *rideIndexArray)
}
}
/* rct2: 0x006847BA */
void set_vehicle_type_image_max_sizes(rct_ride_type_vehicle* vehicle_type, int num_images){
char bitmap[200][200] = { 0 };
@ -4590,4 +4793,115 @@ void set_vehicle_type_image_max_sizes(rct_ride_type_vehicle* vehicle_type, int n
vehicle_type->var_0E = al;
vehicle_type->var_0F = bl;
vehicle_type->var_10 = bh;
}
/**
*
* rct2: 0x006CA28C
*/
money32 ride_get_entrance_or_exit_price(int rideIndex, int x, int y, int direction, int dh, int di)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
eax = x;
ebx = direction << 8;
ecx = y;
edx = rideIndex | (dh << 8);
edi = di;
RCT2_CALLFUNC_X(0x006CA28C, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
return ebx;
}
/**
*
* rct2: 0x006CCF70
*/
void ride_get_entrance_or_exit_position_from_screen_position(int x, int y, int *outX, int *outY, int *outDirection)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
eax = x;
ebx = y;
RCT2_CALLFUNC_X(0x006CCF70, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
if (outX != NULL) *outX = eax & 0xFFFF;
if (outY != NULL) *outY = ecx & 0xFFFF;
if (outDirection != NULL) *outDirection = ebx & 0xFF;
}
bool ride_select_backwards_from_front()
{
track_begin_end trackBeginEnd;
sub_6C9627();
RCT2_GLOBAL(0x00F441D2, uint8) = _currentRideIndex;
if (sub_6C63D6(_currentTrackBeginX, _currentTrackBeginY, _currentTrackBeginZ, _currentTrackPieceDirection, &trackBeginEnd)) {
_rideConstructionState = RIDE_CONSTRUCTION_STATE_SELECTED;
_currentTrackBeginX = trackBeginEnd.begin_x;
_currentTrackBeginY = trackBeginEnd.begin_y;
_currentTrackBeginZ = trackBeginEnd.begin_z;
_currentTrackPieceDirection = trackBeginEnd.begin_direction;
_currentTrackPieceType = trackBeginEnd.begin_element->properties.track.type;
_currentTrackSelectionFlags = 0;
_rideConstructionArrowPulseTime = 0;
return true;
} else {
return false;
}
}
bool ride_select_forwards_from_back()
{
rct_map_element *mapElement;
int x, y, z, direction;
sub_6C9627();
RCT2_GLOBAL(0x00F441D2, uint8) = _currentRideIndex;
x = _currentTrackBeginX;
y = _currentTrackBeginY;
z = _currentTrackBeginZ;
direction = _currentTrackPieceDirection ^ 2;
mapElement = sub_6C6096(&x, &y, &z, &direction, NULL);
if (mapElement != NULL) {
_rideConstructionState = RIDE_CONSTRUCTION_STATE_SELECTED;
_currentTrackBeginX = x;
_currentTrackBeginY = y;
_currentTrackBeginZ = z;
_currentTrackPieceDirection = (mapElement->type & MAP_ELEMENT_DIRECTION_MASK);
_currentTrackPieceType = mapElement->properties.track.type;
_currentTrackSelectionFlags = 0;
_rideConstructionArrowPulseTime = 0;
return true;
} else {
return false;
}
}
money32 ride_remove_track_piece(int x, int y, int z, int direction, int type)
{
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, rct_string_id) = STR_RIDE_CONSTRUCTION_CANT_REMOVE_THIS;
return game_do_command(x, (GAME_COMMAND_FLAG_APPLY) | ((direction & 3) << 8), y, type, GAME_COMMAND_REMOVE_TRACK, z, 0);
}
/**
*
* rct2: 0x006B58EF
*/
bool ride_are_all_possible_entrances_and_exits_built(rct_ride *ride)
{
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP))
return true;
for (int i = 0; i < 4; i++) {
if (ride->station_starts[i] == 0xFFFF) continue;
if (ride->entrances[i] == 0xFFFF) {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id) = STR_ENTRANCE_NOT_YET_BUILT;
return false;
}
if (ride->exits[i] == 0xFFFF) {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id) = STR_EXIT_NOT_YET_BUILT;
return false;
}
}
return true;
}

View File

@ -21,6 +21,7 @@
#ifndef _RIDE_H_
#define _RIDE_H_
#include "../addresses.h"
#include "../common.h"
#include "../peep/peep.h"
#include "../world/map.h"
@ -343,6 +344,18 @@ typedef struct {
uint8 altitude[RIDE_MEASUREMENT_MAX_ITEMS]; // 0x384C
} rct_ride_measurement;
typedef struct {
int begin_x;
int begin_y;
int begin_z;
int begin_direction;
rct_map_element *begin_element;
int end_x;
int end_y;
int end_direction;
rct_map_element *end_element;
} track_begin_end;
enum {
RIDE_CLASS_RIDE,
RIDE_CLASS_SHOP_OR_STALL,
@ -747,6 +760,18 @@ enum {
RIDE_CRASH_TYPE_FATALITIES = 8
};
enum {
RIDE_CONSTRUCTION_STATE_0,
RIDE_CONSTRUCTION_STATE_FRONT,
RIDE_CONSTRUCTION_STATE_BACK,
RIDE_CONSTRUCTION_STATE_SELECTED,
RIDE_CONSTRUCTION_STATE_PLACE,
RIDE_CONSTRUCTION_STATE_ENTRANCE_EXIT,
RIDE_CONSTRUCTION_STATE_6,
RIDE_CONSTRUCTION_STATE_7,
RIDE_CONSTRUCTION_STATE_8
};
#define MAX_RIDES 255
#define MAX_RIDE_MEASUREMENTS 8
@ -776,6 +801,43 @@ extern rct_ride* g_ride_list;
extern const uint8 gRideClassifications[255];
// Macros for very commonly used varaibles, eventually will be changed to locals or globals
#define _enabledRidePieces RCT2_GLOBAL(0x00F44048, uint64)
#define _enabledRidePiecesA RCT2_GLOBAL(0x00F44048, uint32)
#define _enabledRidePiecesB RCT2_GLOBAL(0x00F4404C, uint32)
#define _currentTrackPrice RCT2_GLOBAL(0x00F44070, money32)
#define _numCurrentPossibleRideConfigurations RCT2_GLOBAL(0x00F44078, uint16)
#define _numCurrentPossibleSpecialTrackPieces RCT2_GLOBAL(0x00F4407A, uint16)
#define _currentTrackCurve RCT2_GLOBAL(0x00F440A0, uint16)
#define _currentTrackEndX RCT2_GLOBAL(0x00F440A2, uint16)
#define _currentTrackEndY RCT2_GLOBAL(0x00F440A4, uint16)
#define _rideConstructionState RCT2_GLOBAL(0x00F440A6, uint8)
#define _currentRideIndex RCT2_GLOBAL(0x00F440A7, uint8)
#define _currentTrackBeginX RCT2_GLOBAL(0x00F440A8, uint16)
#define _currentTrackBeginY RCT2_GLOBAL(0x00F440AA, uint16)
#define _currentTrackBeginZ RCT2_GLOBAL(0x00F440AC, uint16)
#define _currentTrackPieceDirection RCT2_GLOBAL(0x00F440AE, uint8)
#define _currentTrackPieceType RCT2_GLOBAL(0x00F440AF, uint8)
#define _currentTrackSelectionFlags RCT2_GLOBAL(0x00F440B0, uint8)
#define _rideConstructionArrowPulseTime RCT2_GLOBAL(0x00F440B1, sint8)
#define _currentTrackSlopeEnd RCT2_GLOBAL(0x00F440B2, uint8)
#define _currentTrackBankEnd RCT2_GLOBAL(0x00F440B3, uint8)
#define _currentTrackLiftHill RCT2_GLOBAL(0x00F440B4, uint8)
#define _currentTrackCovered RCT2_GLOBAL(0x00F440B5, uint8)
#define _previousTrackBankEnd RCT2_GLOBAL(0x00F440B6, uint8)
#define _previousTrackSlopeEnd RCT2_GLOBAL(0x00F440B7, uint8)
#define _previousTrackPieceX RCT2_GLOBAL(0x00F440B9, uint16)
#define _previousTrackPieceY RCT2_GLOBAL(0x00F440BB, uint16)
#define _previousTrackPieceZ RCT2_GLOBAL(0x00F440BD, uint16)
#define _currentSeatRotationAngle RCT2_GLOBAL(0x00F440CF, uint8)
int ride_get_count();
int ride_get_total_queue_length(rct_ride *ride);
int ride_get_max_queue_time(rct_ride *ride);
@ -787,7 +849,6 @@ void ride_check_all_reachable();
void ride_update_satisfaction(rct_ride* ride, uint8 happiness);
void ride_update_popularity(rct_ride* ride, uint8 pop_amount);
int sub_6CAF80(int rideIndex, rct_xy_element *output);
int track_get_next(rct_xy_element *input, rct_xy_element *output);
int ride_find_track_gap(rct_xy_element *input, rct_xy_element *output);
void ride_construct_new(ride_list_item listItem);
void ride_construct(int rideIndex);
@ -828,6 +889,9 @@ void game_command_set_ride_price(int *eax, int *ebx, int *ecx, int *edx, int *es
void ride_clear_for_construction(int rideIndex);
void set_vehicle_type_image_max_sizes(rct_ride_type_vehicle* vehicle_type, int num_images);
void ride_select_next_section();
void ride_select_previous_section();
int get_var_10E_unk_1(rct_ride* ride);
int get_var_10E_unk_2(rct_ride* ride);
int get_var_10E_unk_3(rct_ride* ride);
@ -852,4 +916,24 @@ bool ride_is_powered_launched(rct_ride *ride);
bool ride_has_any_track_elements(int rideIndex);
void ride_all_has_any_track_elements(bool *rideIndexArray);
void sub_6C9800();
bool track_get_next(rct_xy_element *input, rct_xy_element *output, int *z, int *direction);
bool track_get_previous(int x, int y, rct_map_element *mapElement, track_begin_end *outTrackBeginEnd);
rct_map_element *sub_6C6096(int *x, int *y, int *z, int *direction, int *direction2);
bool sub_6C63D6(int inX, int inY, int inZ, int inDirection, track_begin_end *outTrackBeginEnd);
void sub_6C84CE();
void sub_6C96C0();
money32 ride_get_entrance_or_exit_price(int rideIndex, int x, int y, int direction, int dh, int di);
void ride_get_entrance_or_exit_position_from_screen_position(int x, int y, int *outX, int *outY, int *outDirection);
bool ride_select_backwards_from_front();
bool ride_select_forwards_from_back();
money32 ride_remove_track_piece(int x, int y, int z, int direction, int type);
bool ride_are_all_possible_entrances_and_exits_built(rct_ride *ride);
#endif

View File

@ -51,21 +51,6 @@ static void loc_6B5BB2();
static void ride_ratings_calculate(rct_ride *ride);
static void ride_ratings_calculate_value(rct_ride *ride);
int sub_6C6402(rct_map_element **mapElement, int *x, int *y, int *z)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
eax = *x;
ecx = *y;
esi = (int)*mapElement;
int result = RCT2_CALLFUNC_X(0x006C6402, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
*x = *((uint16*)&eax);
*y = *((uint16*)&ecx);
*z = *((uint8*)&edx);
*mapElement = (rct_map_element*)esi;
return result & (0x100);
}
/**
*
* rct2: 0x006B5A2A
@ -245,7 +230,7 @@ static void ride_ratings_update_state_2()
trackElement.x = RCT2_GLOBAL(0x0138B584, uint16);
trackElement.y = RCT2_GLOBAL(0x0138B586, uint16);
trackElement.element = mapElement;
if (!track_get_next(&trackElement, &nextTrackElement)) {
if (!track_get_next(&trackElement, &nextTrackElement, NULL, NULL)) {
_rideRatingsState = RIDE_RATINGS_STATE_4;
return;
}
@ -339,7 +324,7 @@ static void ride_ratings_update_state_5()
x = RCT2_GLOBAL(0x0138B584, uint16);
y = RCT2_GLOBAL(0x0138B586, uint16);
if (!sub_6C6402(&mapElement, &x, &y, &z)) {
if (!track_get_previous(x, y, mapElement, NULL)) {
_rideRatingsState = RIDE_RATINGS_STATE_CALCULATE;
return;
}

View File

@ -25,6 +25,5 @@
#include "ride.h"
void ride_ratings_update_all();
int sub_6C6402(rct_map_element **mapElement, int *x, int *y, int *z);
#endif

View File

@ -47,193 +47,193 @@ const rct_trackdefinition *gTrackDefinitions = (rct_trackdefinition*)0x00997C9D;
// TODO This table is incorrect or at least missing 69 elements. There should be 256 in total!
const rct_trackdefinition gTrackDefinitions_INCORRECT[] = {
// TYPE VANGLE END VANGLE START BANK END BANK START SPECIAL
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_END_STATION
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_BEGIN_STATION
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_MIDDLE_STATION
{ TRACK_FLAT, TRACK_UP_25, TRACK_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_UP
{ TRACK_FLAT, TRACK_UP_60, TRACK_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_UP
{ TRACK_FLAT, TRACK_UP_25, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_TO_25_DEG_UP
{ TRACK_FLAT, TRACK_UP_60, TRACK_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_UP_TO_60_DEG_UP
{ TRACK_FLAT, TRACK_UP_25, TRACK_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_UP_TO_25_DEG_UP
{ TRACK_FLAT, TRACK_NONE, TRACK_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_UP_TO_FLAT
{ TRACK_FLAT, TRACK_DOWN_25, TRACK_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_DOWN
{ TRACK_FLAT, TRACK_DOWN_60, TRACK_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_DOWN
{ TRACK_FLAT, TRACK_DOWN_25, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_TO_25_DEG_DOWN
{ TRACK_FLAT, TRACK_DOWN_60, TRACK_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_DOWN_TO_60_DEG_DOWN
{ TRACK_FLAT, TRACK_DOWN_25, TRACK_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_DOWN_TO_25_DEG_DOWN
{ TRACK_FLAT, TRACK_NONE, TRACK_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_DOWN_TO_FLAT
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_5_TILES
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_5_TILES
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_LEFT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_TO_LEFT_BANK
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_RIGHT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_TO_RIGHT_BANK
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_BANK_TO_FLAT
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_BANK_TO_FLAT
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_BANKED_LEFT_QUARTER_TURN_5_TILES
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_BANKED_RIGHT_QUARTER_TURN_5_TILES
{ TRACK_FLAT, TRACK_UP_25, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_BANK_TO_25_DEG_UP
{ TRACK_FLAT, TRACK_UP_25, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_BANK_TO_25_DEG_UP
{ TRACK_FLAT, TRACK_NONE, TRACK_UP_25, TRACK_BANK_LEFT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_UP_TO_LEFT_BANK
{ TRACK_FLAT, TRACK_NONE, TRACK_UP_25, TRACK_BANK_RIGHT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_UP_TO_RIGHT_BANK
{ TRACK_FLAT, TRACK_DOWN_25, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_BANK_TO_25_DEG_DOWN
{ TRACK_FLAT, TRACK_DOWN_25, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_BANK_TO_25_DEG_DOWN
{ TRACK_FLAT, TRACK_NONE, TRACK_DOWN_25, TRACK_BANK_LEFT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_DOWN_TO_LEFT_BANK
{ TRACK_FLAT, TRACK_NONE, TRACK_DOWN_25, TRACK_BANK_RIGHT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_DOWN_TO_RIGHT_BANK
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_BANK
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_BANK
{ TRACK_FLAT, TRACK_UP_25, TRACK_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP
{ TRACK_FLAT, TRACK_UP_25, TRACK_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP
{ TRACK_FLAT, TRACK_DOWN_25, TRACK_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_5_TILES_25_DEG_DOWN
{ TRACK_FLAT, TRACK_DOWN_25, TRACK_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_5_TILES_25_DEG_DOWN
{ TRACK_S_BEND, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_S_BEND_LEFT
{ TRACK_S_BEND, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_S_BEND_RIGHT
{ TRACK_VERTICAL_LOOP, TRACK_DOWN_25, TRACK_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_UNKNOWN_VERTICAL_LOOP }, // ELEM_LEFT_VERTICAL_LOOP
{ TRACK_VERTICAL_LOOP, TRACK_DOWN_25, TRACK_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_UNKNOWN_VERTICAL_LOOP }, // ELEM_RIGHT_VERTICAL_LOOP
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_3_TILES
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_3_TILES
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_3_TILES_BANK
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_3_TILES_BANK
{ TRACK_FLAT, TRACK_UP_25, TRACK_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_3_TILES_25_DEG_UP
{ TRACK_FLAT, TRACK_UP_25, TRACK_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP
{ TRACK_FLAT, TRACK_DOWN_25, TRACK_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_3_TILES_25_DEG_DOWN
{ TRACK_FLAT, TRACK_DOWN_25, TRACK_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_1_TILE
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_1_TILE
{ TRACK_TWIST, TRACK_NONE, TRACK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_TWIST_DOWN_TO_UP
{ TRACK_TWIST, TRACK_NONE, TRACK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_TWIST_DOWN_TO_UP
{ TRACK_TWIST, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_NONE }, // ELEM_LEFT_TWIST_UP_TO_DOWN
{ TRACK_TWIST, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_NONE }, // ELEM_RIGHT_TWIST_UP_TO_DOWN
{ TRACK_HALF_LOOP, TRACK_NONE, TRACK_UP_25, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, TRACK_HALF_LOOP_UP }, // ELEM_HALF_LOOP_UP
{ TRACK_HALF_LOOP, TRACK_DOWN_25, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_HALF_LOOP_DOWN }, // ELEM_HALF_LOOP_DOWN
{ TRACK_CORKSCREW, TRACK_NONE, TRACK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_CORKSCREW_UP
{ TRACK_CORKSCREW, TRACK_NONE, TRACK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_CORKSCREW_UP
{ TRACK_CORKSCREW, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_CORKSCREW_DOWN }, // ELEM_LEFT_CORKSCREW_DOWN
{ TRACK_CORKSCREW, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_CORKSCREW_DOWN }, // ELEM_RIGHT_CORKSCREW_DOWN
{ TRACK_FLAT, TRACK_UP_60, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_TO_60_DEG_UP
{ TRACK_FLAT, TRACK_NONE, TRACK_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_UP_TO_FLAT
{ TRACK_FLAT, TRACK_DOWN_60, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_TO_60_DEG_DOWN
{ TRACK_FLAT, TRACK_NONE, TRACK_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_DOWN_TO_FLAT
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_END_STATION
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_BEGIN_STATION
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_MIDDLE_STATION
{ TRACK_FLAT, TRACK_SLOPE_UP_25, TRACK_SLOPE_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_UP_60, TRACK_SLOPE_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_UP_25, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_TO_25_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_UP_60, TRACK_SLOPE_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_UP_TO_60_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_UP_25, TRACK_SLOPE_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_UP_TO_25_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_UP_TO_FLAT
{ TRACK_FLAT, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_DOWN_60, TRACK_SLOPE_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_TO_25_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_DOWN_60, TRACK_SLOPE_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_DOWN_TO_60_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_DOWN_TO_25_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_DOWN_TO_FLAT
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_5_TILES
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_5_TILES
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_LEFT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_TO_LEFT_BANK
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_RIGHT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_TO_RIGHT_BANK
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_BANK_TO_FLAT
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_BANK_TO_FLAT
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_BANKED_LEFT_QUARTER_TURN_5_TILES
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_BANKED_RIGHT_QUARTER_TURN_5_TILES
{ TRACK_FLAT, TRACK_SLOPE_UP_25, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_BANK_TO_25_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_UP_25, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_BANK_TO_25_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_UP_25, TRACK_BANK_LEFT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_UP_TO_LEFT_BANK
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_UP_25, TRACK_BANK_RIGHT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_UP_TO_RIGHT_BANK
{ TRACK_FLAT, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_BANK_TO_25_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_BANK_TO_25_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_DOWN_25, TRACK_BANK_LEFT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_DOWN_TO_LEFT_BANK
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_DOWN_25, TRACK_BANK_RIGHT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_DOWN_TO_RIGHT_BANK
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_BANK
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_BANK
{ TRACK_FLAT, TRACK_SLOPE_UP_25, TRACK_SLOPE_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_UP_25, TRACK_SLOPE_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_5_TILES_25_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_5_TILES_25_DEG_DOWN
{ TRACK_S_BEND, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_S_BEND_LEFT
{ TRACK_S_BEND, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_S_BEND_RIGHT
{ TRACK_VERTICAL_LOOP, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_UNKNOWN_VERTICAL_LOOP }, // ELEM_LEFT_VERTICAL_LOOP
{ TRACK_VERTICAL_LOOP, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_UNKNOWN_VERTICAL_LOOP }, // ELEM_RIGHT_VERTICAL_LOOP
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_3_TILES
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_3_TILES
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_3_TILES_BANK
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_3_TILES_BANK
{ TRACK_FLAT, TRACK_SLOPE_UP_25, TRACK_SLOPE_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_3_TILES_25_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_UP_25, TRACK_SLOPE_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_3_TILES_25_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_1_TILE
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_1_TILE
{ TRACK_TWIST, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_TWIST_DOWN_TO_UP
{ TRACK_TWIST, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_TWIST_DOWN_TO_UP
{ TRACK_TWIST, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_NONE }, // ELEM_LEFT_TWIST_UP_TO_DOWN
{ TRACK_TWIST, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_NONE }, // ELEM_RIGHT_TWIST_UP_TO_DOWN
{ TRACK_HALF_LOOP, TRACK_SLOPE_NONE, TRACK_SLOPE_UP_25, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, TRACK_HALF_LOOP_UP }, // ELEM_HALF_LOOP_UP
{ TRACK_HALF_LOOP, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_HALF_LOOP_DOWN }, // ELEM_HALF_LOOP_DOWN
{ TRACK_CORKSCREW, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_CORKSCREW_UP
{ TRACK_CORKSCREW, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_CORKSCREW_UP
{ TRACK_CORKSCREW, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_CORKSCREW_DOWN }, // ELEM_LEFT_CORKSCREW_DOWN
{ TRACK_CORKSCREW, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_CORKSCREW_DOWN }, // ELEM_RIGHT_CORKSCREW_DOWN
{ TRACK_FLAT, TRACK_SLOPE_UP_60, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_TO_60_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_UP_TO_FLAT
{ TRACK_FLAT, TRACK_SLOPE_DOWN_60, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_TO_60_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_DOWN_TO_FLAT
{ TRACK_TOWER_BASE, TRACK_VANGLE_TOWER, TRACK_VANGLE_TOWER, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_TOWER_BASE
{ TRACK_TOWER_BASE, TRACK_VANGLE_TOWER, TRACK_VANGLE_TOWER, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_TOWER_SECTION
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_COVERED
{ TRACK_FLAT, TRACK_UP_25, TRACK_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_UP_COVERED
{ TRACK_FLAT, TRACK_UP_60, TRACK_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_UP_COVERED
{ TRACK_FLAT, TRACK_UP_25, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_TO_25_DEG_UP_COVERED
{ TRACK_FLAT, TRACK_UP_60, TRACK_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_UP_TO_60_DEG_UP_COVERED
{ TRACK_FLAT, TRACK_UP_25, TRACK_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_UP_TO_25_DEG_UP_COVERED
{ TRACK_FLAT, TRACK_NONE, TRACK_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_UP_TO_FLAT_COVERED
{ TRACK_FLAT, TRACK_DOWN_25, TRACK_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_DOWN_COVERED
{ TRACK_FLAT, TRACK_DOWN_60, TRACK_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_DOWN_COVERED
{ TRACK_FLAT, TRACK_DOWN_25, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_TO_25_DEG_DOWN_COVERED
{ TRACK_FLAT, TRACK_DOWN_60, TRACK_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_DOWN_TO_60_DEG_DOWN_COVERED
{ TRACK_FLAT, TRACK_DOWN_25, TRACK_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_DOWN_TO_25_DEG_DOWN_COVERED
{ TRACK_FLAT, TRACK_NONE, TRACK_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_DOWN_TO_FLAT_COVERED
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_5_TILES_COVERED
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_5_TILES_COVERED
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_S_BEND_LEFT_COVERED
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_S_BEND_RIGHT_COVERED
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_3_TILES_COVERED
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_3_TILES_COVERED
{ TRACK_HELIX_SMALL, TRACK_NONE, TRACK_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_HALF_BANKED_HELIX_UP_SMALL
{ TRACK_HELIX_SMALL, TRACK_NONE, TRACK_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_HALF_BANKED_HELIX_UP_SMALL
{ TRACK_HELIX_SMALL, TRACK_NONE, TRACK_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_HALF_BANKED_HELIX_DOWN_SMALL
{ TRACK_HELIX_SMALL, TRACK_NONE, TRACK_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL
{ TRACK_HELIX_SMALL, TRACK_NONE, TRACK_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_HALF_BANKED_HELIX_UP_LARGE
{ TRACK_HELIX_SMALL, TRACK_NONE, TRACK_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_HALF_BANKED_HELIX_UP_LARGE
{ TRACK_HELIX_SMALL, TRACK_NONE, TRACK_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_HALF_BANKED_HELIX_DOWN_LARGE
{ TRACK_HELIX_SMALL, TRACK_NONE, TRACK_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE
{ TRACK_FLAT, TRACK_UP_60, TRACK_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_1_TILE_60_DEG_UP
{ TRACK_FLAT, TRACK_UP_60, TRACK_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_1_TILE_60_DEG_UP
{ TRACK_FLAT, TRACK_DOWN_60, TRACK_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_1_TILE_60_DEG_DOWN
{ TRACK_FLAT, TRACK_DOWN_60, TRACK_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_1_TILE_60_DEG_DOWN
{ TRACK_BRAKES, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_BRAKES
{ TRACK_ROTATION_CONTROL_TOGGLE,TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_ROTATION_CONTROL_TOGGLE
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_INVERTED_90_DEG_UP_TO_FLAT_QUARTER_LOOP
{ TRACK_HELIX_LARGE, TRACK_NONE, TRACK_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_QUARTER_BANKED_HELIX_LARGE_UP
{ TRACK_HELIX_LARGE, TRACK_NONE, TRACK_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_QUARTER_BANKED_HELIX_LARGE_UP
{ TRACK_HELIX_LARGE, TRACK_NONE, TRACK_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_QUARTER_BANKED_HELIX_LARGE_DOWN
{ TRACK_HELIX_LARGE, TRACK_NONE, TRACK_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_QUARTER_BANKED_HELIX_LARGE_DOWN
{ TRACK_HELIX_LARGE_UNBANKED, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_HELIX_LARGE_UP
{ TRACK_HELIX_LARGE_UNBANKED, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_HELIX_LARGE_UP
{ TRACK_HELIX_LARGE_UNBANKED, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_HELIX_LARGE_DOWN
{ TRACK_HELIX_LARGE_UNBANKED, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_HELIX_LARGE_DOWN
{ TRACK_FLAT, TRACK_UP_25, TRACK_UP_25, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_25_DEG_UP_LEFT_BANKED
{ TRACK_FLAT, TRACK_UP_25, TRACK_UP_25, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_25_DEG_UP_RIGHT_BANKED
{ TRACK_WATERFALL, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_WATERFALL
{ TRACK_RAPIDS, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RAPIDS
{ TRACK_ON_RIDE_PHOTO, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_ON_RIDE_PHOTO
{ TRACK_FLAT, TRACK_DOWN_25, TRACK_DOWN_25, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_25_DEG_DOWN_LEFT_BANKED
{ TRACK_FLAT, TRACK_DOWN_25, TRACK_DOWN_25, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_25_DEG_DOWN_RIGHT_BANKED
{ TRACK_WATER_SPLASH, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_WATER_SPLASH
{ TRACK_FLAT, TRACK_UP_60, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_TO_60_DEG_UP_LONG_BASE
{ TRACK_FLAT, TRACK_NONE, TRACK_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_UP_TO_FLAT_LONG_BASE
{ TRACK_WHIRLPOOL, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_WHIRLPOOL
{ TRACK_FLAT, TRACK_NONE, TRACK_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_TO_60_DEG_DOWN_LONG_BASE
{ TRACK_FLAT, TRACK_DOWN_60, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_UP_TO_FLAT_LONG_BASE
{ TRACK_LIFT_HILL, TRACK_DOWN_60, TRACK_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_CABLE_LIFT_HILL
{ TRACK_WHOA_BELLY, TRACK_VANGLE_WHOA_BELLY, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_REVERSE_WHOA_BELLY_SLOPE
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_COVERED
{ TRACK_FLAT, TRACK_SLOPE_UP_25, TRACK_SLOPE_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_UP_COVERED
{ TRACK_FLAT, TRACK_SLOPE_UP_60, TRACK_SLOPE_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_UP_COVERED
{ TRACK_FLAT, TRACK_SLOPE_UP_25, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_TO_25_DEG_UP_COVERED
{ TRACK_FLAT, TRACK_SLOPE_UP_60, TRACK_SLOPE_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_UP_TO_60_DEG_UP_COVERED
{ TRACK_FLAT, TRACK_SLOPE_UP_25, TRACK_SLOPE_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_UP_TO_25_DEG_UP_COVERED
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_UP_TO_FLAT_COVERED
{ TRACK_FLAT, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_DOWN_COVERED
{ TRACK_FLAT, TRACK_SLOPE_DOWN_60, TRACK_SLOPE_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_DOWN_COVERED
{ TRACK_FLAT, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_TO_25_DEG_DOWN_COVERED
{ TRACK_FLAT, TRACK_SLOPE_DOWN_60, TRACK_SLOPE_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_DOWN_TO_60_DEG_DOWN_COVERED
{ TRACK_FLAT, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_DOWN_TO_25_DEG_DOWN_COVERED
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_25_DEG_DOWN_TO_FLAT_COVERED
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_5_TILES_COVERED
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_5_TILES_COVERED
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_S_BEND_LEFT_COVERED
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_S_BEND_RIGHT_COVERED
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_3_TILES_COVERED
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_3_TILES_COVERED
{ TRACK_HELIX_SMALL, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_HALF_BANKED_HELIX_UP_SMALL
{ TRACK_HELIX_SMALL, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_HALF_BANKED_HELIX_UP_SMALL
{ TRACK_HELIX_SMALL, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_HALF_BANKED_HELIX_DOWN_SMALL
{ TRACK_HELIX_SMALL, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL
{ TRACK_HELIX_SMALL, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_HALF_BANKED_HELIX_UP_LARGE
{ TRACK_HELIX_SMALL, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_HALF_BANKED_HELIX_UP_LARGE
{ TRACK_HELIX_SMALL, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_HALF_BANKED_HELIX_DOWN_LARGE
{ TRACK_HELIX_SMALL, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE
{ TRACK_FLAT, TRACK_SLOPE_UP_60, TRACK_SLOPE_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_1_TILE_60_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_UP_60, TRACK_SLOPE_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_1_TILE_60_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_DOWN_60, TRACK_SLOPE_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_1_TILE_60_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_DOWN_60, TRACK_SLOPE_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_1_TILE_60_DEG_DOWN
{ TRACK_BRAKES, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_BRAKES
{ TRACK_ROTATION_CONTROL_TOGGLE,TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_ROTATION_CONTROL_TOGGLE
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_INVERTED_90_DEG_UP_TO_FLAT_QUARTER_LOOP
{ TRACK_HELIX_LARGE, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_QUARTER_BANKED_HELIX_LARGE_UP
{ TRACK_HELIX_LARGE, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_QUARTER_BANKED_HELIX_LARGE_UP
{ TRACK_HELIX_LARGE, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_QUARTER_BANKED_HELIX_LARGE_DOWN
{ TRACK_HELIX_LARGE, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_QUARTER_BANKED_HELIX_LARGE_DOWN
{ TRACK_HELIX_LARGE_UNBANKED, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_HELIX_LARGE_UP
{ TRACK_HELIX_LARGE_UNBANKED, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_HELIX_LARGE_UP
{ TRACK_HELIX_LARGE_UNBANKED, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_HELIX_LARGE_DOWN
{ TRACK_HELIX_LARGE_UNBANKED, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_HELIX_LARGE_DOWN
{ TRACK_FLAT, TRACK_SLOPE_UP_25, TRACK_SLOPE_UP_25, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_25_DEG_UP_LEFT_BANKED
{ TRACK_FLAT, TRACK_SLOPE_UP_25, TRACK_SLOPE_UP_25, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_25_DEG_UP_RIGHT_BANKED
{ TRACK_WATERFALL, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_WATERFALL
{ TRACK_RAPIDS, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RAPIDS
{ TRACK_ON_RIDE_PHOTO, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_ON_RIDE_PHOTO
{ TRACK_FLAT, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_DOWN_25, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_25_DEG_DOWN_LEFT_BANKED
{ TRACK_FLAT, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_DOWN_25, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_25_DEG_DOWN_RIGHT_BANKED
{ TRACK_WATER_SPLASH, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_WATER_SPLASH
{ TRACK_FLAT, TRACK_SLOPE_UP_60, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_TO_60_DEG_UP_LONG_BASE
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_UP_TO_FLAT_LONG_BASE
{ TRACK_WHIRLPOOL, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_WHIRLPOOL
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT_TO_60_DEG_DOWN_LONG_BASE
{ TRACK_FLAT, TRACK_SLOPE_DOWN_60, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_UP_TO_FLAT_LONG_BASE
{ TRACK_LIFT_HILL, TRACK_SLOPE_DOWN_60, TRACK_SLOPE_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_CABLE_LIFT_HILL
{ TRACK_WHOA_BELLY, TRACK_VANGLE_WHOA_BELLY, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_REVERSE_WHOA_BELLY_SLOPE
{ TRACK_WHOA_BELLY, TRACK_VANGLE_WHOA_BELLY, TRACK_VANGLE_WHOA_BELLY, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_REVERSE_WHOA_BELLY_VERTICAL
{ TRACK_FLAT, TRACK_UP_90, TRACK_UP_90, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_90_DEG_UP
{ TRACK_FLAT, TRACK_DOWN_90, TRACK_DOWN_90, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_90_DEG_DOWN
{ TRACK_FLAT, TRACK_UP_90, TRACK_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_UP_TO_90_DEG_UP
{ TRACK_FLAT, TRACK_DOWN_60, TRACK_DOWN_90, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_90_DEG_DOWN_TO_60_DEG_DOWN
{ TRACK_FLAT, TRACK_UP_60, TRACK_UP_90, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_90_DEG_UP_TO_60_DEG_UP
{ TRACK_FLAT, TRACK_DOWN_90, TRACK_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_DOWN_TO_90_DEG_DOWN
{ TRACK_BRAKE_FOR_DROP, TRACK_DOWN_60, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_BRAKE_FOR_DROP
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_EIGHTH_TO_DIAG
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_EIGHTH_TO_DIAG
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_EIGHTH_TO_ORTHOGONAL
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_EIGHTH_TO_ORTHOGONAL
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_EIGHTH_BANK_TO_DIAG
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_EIGHTH_BANK_TO_DIAG
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_EIGHTH_BANK_TO_ORTHOGONAL
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_EIGHTH_BANK_TO_ORTHOGONAL
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_FLAT
{ TRACK_FLAT, TRACK_UP_25, TRACK_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_25_DEG_UP
{ TRACK_FLAT, TRACK_UP_60, TRACK_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_60_DEG_UP
{ TRACK_FLAT, TRACK_UP_25, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_FLAT_TO_25_DEG_UP
{ TRACK_FLAT, TRACK_UP_60, TRACK_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_25_DEG_UP_TO_60_DEG_UP
{ TRACK_FLAT, TRACK_UP_25, TRACK_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_60_DEG_UP_TO_25_DEG_UP
{ TRACK_FLAT, TRACK_NONE, TRACK_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_25_DEG_UP_TO_FLAT
{ TRACK_FLAT, TRACK_DOWN_25, TRACK_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_25_DEG_DOWN
{ TRACK_FLAT, TRACK_DOWN_60, TRACK_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_60_DEG_DOWN
{ TRACK_FLAT, TRACK_DOWN_25, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_FLAT_TO_25_DEG_DOWN
{ TRACK_FLAT, TRACK_DOWN_60, TRACK_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_25_DEG_DOWN_TO_60_DEG_DOWN
{ TRACK_FLAT, TRACK_DOWN_25, TRACK_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_60_DEG_DOWN_TO_25_DEG_DOWN
{ TRACK_FLAT, TRACK_NONE, TRACK_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_25_DEG_DOWN_TO_FLAT
{ TRACK_FLAT, TRACK_UP_60, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_FLAT_TO_60_DEG_UP
{ TRACK_FLAT, TRACK_NONE, TRACK_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_60_DEG_UP_TO_FLAT
{ TRACK_FLAT, TRACK_DOWN_60, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_FLAT_TO_60_DEG_DOWN
{ TRACK_FLAT, TRACK_NONE, TRACK_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_60_DEG_DOWN_TO_FLAT
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_LEFT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_FLAT_TO_LEFT_BANK
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_RIGHT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_FLAT_TO_RIGHT_BANK
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_DIAG_LEFT_BANK_TO_FLAT
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_DIAG_RIGHT_BANK_TO_FLAT
{ TRACK_FLAT, TRACK_UP_25, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_DIAG_LEFT_BANK_TO_25_DEG_UP
{ TRACK_FLAT, TRACK_UP_25, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_DIAG_RIGHT_BANK_TO_25_DEG_UP
{ TRACK_FLAT, TRACK_NONE, TRACK_UP_25, TRACK_BANK_LEFT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_25_DEG_UP_TO_LEFT_BANK
{ TRACK_FLAT, TRACK_NONE, TRACK_UP_25, TRACK_BANK_RIGHT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_25_DEG_UP_TO_RIGHT_BANK
{ TRACK_FLAT, TRACK_DOWN_25, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_DIAG_LEFT_BANK_TO_25_DEG_DOWN
{ TRACK_FLAT, TRACK_DOWN_25, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_DIAG_RIGHT_BANK_TO_25_DEG_DOWN
{ TRACK_FLAT, TRACK_NONE, TRACK_DOWN_25, TRACK_BANK_LEFT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_25_DEG_DOWN_TO_LEFT_BANK
{ TRACK_FLAT, TRACK_NONE, TRACK_DOWN_25, TRACK_BANK_RIGHT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_25_DEG_DOWN_TO_RIGHT_BANK
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_DIAG_LEFT_BANK
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_DIAG_RIGHT_BANK
{ TRACK_LOG_FLUME_REVERSER, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LOG_FLUME_REVERSER
{ TRACK_SPINNING_TUNNEL, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_SPINNING_TUNNEL
{ TRACK_BARREL_ROLL, TRACK_NONE, TRACK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_BARREL_ROLL_UP_TO_DOWN
{ TRACK_BARREL_ROLL, TRACK_NONE, TRACK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_BARREL_ROLL_UP_TO_DOWN
{ TRACK_BARREL_ROLL, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_NONE }, // ELEM_LEFT_BARREL_ROLL_DOWN_TO_UP
{ TRACK_BARREL_ROLL, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_NONE }, // ELEM_RIGHT_BARREL_ROLL_DOWN_TO_UP
{ TRACK_FLAT, TRACK_UP_25, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_TILES_25_DEG_UP
{ TRACK_FLAT, TRACK_UP_25, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP
{ TRACK_FLAT, TRACK_NONE, TRACK_DOWN_25, TRACK_BANK_LEFT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_3_TILES_25_DEG_DOWN_TO_LEFT_BANK
{ TRACK_FLAT, TRACK_NONE, TRACK_DOWN_25, TRACK_BANK_RIGHT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_TO_RIGHT_BANK
{ TRACK_POWERED_LIFT, TRACK_UP_25, TRACK_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_POWERED_LIFT
{ TRACK_HALF_LOOP_2, TRACK_NONE, TRACK_UP_25, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, TRACK_HALF_LOOP_UP }, // ELEM_LEFT_LARGE_HALF_LOOP_UP
{ TRACK_HALF_LOOP_2, TRACK_NONE, TRACK_UP_25, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, TRACK_HALF_LOOP_UP }, // ELEM_RIGHT_LARGE_HALF_LOOP_UP
{ TRACK_HALF_LOOP_2, TRACK_DOWN_25, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_HALF_LOOP_DOWN }, // ELEM_RIGHT_LARGE_HALF_LOOP_DOWN
{ TRACK_HALF_LOOP_2, TRACK_DOWN_25, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_HALF_LOOP_DOWN }, // ELEM_LEFT_LARGE_HALF_LOOP_DOWN
{ TRACK_FLAT, TRACK_SLOPE_UP_90, TRACK_SLOPE_UP_90, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_90_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_DOWN_90, TRACK_SLOPE_DOWN_90, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_90_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_UP_90, TRACK_SLOPE_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_UP_TO_90_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_DOWN_60, TRACK_SLOPE_DOWN_90, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_90_DEG_DOWN_TO_60_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_UP_60, TRACK_SLOPE_UP_90, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_90_DEG_UP_TO_60_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_DOWN_90, TRACK_SLOPE_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_60_DEG_DOWN_TO_90_DEG_DOWN
{ TRACK_BRAKE_FOR_DROP, TRACK_SLOPE_DOWN_60, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_BRAKE_FOR_DROP
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_EIGHTH_TO_DIAG
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_EIGHTH_TO_DIAG
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_EIGHTH_TO_ORTHOGONAL
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_EIGHTH_TO_ORTHOGONAL
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_EIGHTH_BANK_TO_DIAG
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_EIGHTH_BANK_TO_DIAG
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_EIGHTH_BANK_TO_ORTHOGONAL
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_EIGHTH_BANK_TO_ORTHOGONAL
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_FLAT
{ TRACK_FLAT, TRACK_SLOPE_UP_25, TRACK_SLOPE_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_25_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_UP_60, TRACK_SLOPE_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_60_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_UP_25, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_FLAT_TO_25_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_UP_60, TRACK_SLOPE_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_25_DEG_UP_TO_60_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_UP_25, TRACK_SLOPE_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_60_DEG_UP_TO_25_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_25_DEG_UP_TO_FLAT
{ TRACK_FLAT, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_25_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_DOWN_60, TRACK_SLOPE_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_60_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_FLAT_TO_25_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_DOWN_60, TRACK_SLOPE_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_25_DEG_DOWN_TO_60_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_60_DEG_DOWN_TO_25_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_DOWN_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_25_DEG_DOWN_TO_FLAT
{ TRACK_FLAT, TRACK_SLOPE_UP_60, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_FLAT_TO_60_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_UP_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_60_DEG_UP_TO_FLAT
{ TRACK_FLAT, TRACK_SLOPE_DOWN_60, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_FLAT_TO_60_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_60_DEG_DOWN_TO_FLAT
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_LEFT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_FLAT_TO_LEFT_BANK
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_RIGHT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_FLAT_TO_RIGHT_BANK
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_DIAG_LEFT_BANK_TO_FLAT
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_DIAG_RIGHT_BANK_TO_FLAT
{ TRACK_FLAT, TRACK_SLOPE_UP_25, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_DIAG_LEFT_BANK_TO_25_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_UP_25, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_DIAG_RIGHT_BANK_TO_25_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_UP_25, TRACK_BANK_LEFT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_25_DEG_UP_TO_LEFT_BANK
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_UP_25, TRACK_BANK_RIGHT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_25_DEG_UP_TO_RIGHT_BANK
{ TRACK_FLAT, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_DIAG_LEFT_BANK_TO_25_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_DIAG_RIGHT_BANK_TO_25_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_DOWN_25, TRACK_BANK_LEFT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_25_DEG_DOWN_TO_LEFT_BANK
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_DOWN_25, TRACK_BANK_RIGHT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_DIAG_25_DEG_DOWN_TO_RIGHT_BANK
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_DIAG_LEFT_BANK
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_DIAG_RIGHT_BANK
{ TRACK_LOG_FLUME_REVERSER, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LOG_FLUME_REVERSER
{ TRACK_SPINNING_TUNNEL, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_SPINNING_TUNNEL
{ TRACK_BARREL_ROLL, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_BARREL_ROLL_UP_TO_DOWN
{ TRACK_BARREL_ROLL, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_BARREL_ROLL_UP_TO_DOWN
{ TRACK_BARREL_ROLL, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_NONE }, // ELEM_LEFT_BARREL_ROLL_DOWN_TO_UP
{ TRACK_BARREL_ROLL, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_NONE }, // ELEM_RIGHT_BARREL_ROLL_DOWN_TO_UP
{ TRACK_FLAT, TRACK_SLOPE_UP_25, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_LEFT, TRACK_NONE }, // ELEM_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_TILES_25_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_UP_25, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_RIGHT, TRACK_NONE }, // ELEM_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_DOWN_25, TRACK_BANK_LEFT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_LEFT_QUARTER_TURN_3_TILES_25_DEG_DOWN_TO_LEFT_BANK
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_DOWN_25, TRACK_BANK_RIGHT, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_TO_RIGHT_BANK
{ TRACK_POWERED_LIFT, TRACK_SLOPE_UP_25, TRACK_SLOPE_UP_25, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_POWERED_LIFT
{ TRACK_HALF_LOOP_LARGE, TRACK_SLOPE_NONE, TRACK_SLOPE_UP_25, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, TRACK_HALF_LOOP_UP }, // ELEM_LEFT_LARGE_HALF_LOOP_UP
{ TRACK_HALF_LOOP_LARGE, TRACK_SLOPE_NONE, TRACK_SLOPE_UP_25, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, TRACK_HALF_LOOP_UP }, // ELEM_RIGHT_LARGE_HALF_LOOP_UP
{ TRACK_HALF_LOOP_LARGE, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_HALF_LOOP_DOWN }, // ELEM_RIGHT_LARGE_HALF_LOOP_DOWN
{ TRACK_HALF_LOOP_LARGE, TRACK_SLOPE_DOWN_25, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_HALF_LOOP_DOWN }, // ELEM_LEFT_LARGE_HALF_LOOP_DOWN
};
static bool track_save_should_select_scenery_around(int rideIndex, rct_map_element *mapElement);
@ -1404,10 +1404,10 @@ int track_place_maze(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint8** trac
bl = 1;
if (RCT2_GLOBAL(0x00F440D4, uint8) == 4)bl = 0x69;
if (RCT2_GLOBAL(0x00F440D4, uint8) == 1){
cost = game_do_command(mapCoord.x, 0 | rotation << 8, mapCoord.y, (z / 16) & 0xFF, GAME_COMMAND_12, -1, 0);
cost = game_do_command(mapCoord.x, 0 | rotation << 8, mapCoord.y, (z / 16) & 0xFF, GAME_COMMAND_PLACE_RIDE_ENTRANCE_OR_EXIT, -1, 0);
}
else{
cost = game_do_command(mapCoord.x, bl | rotation << 8, mapCoord.y, rideIndex, GAME_COMMAND_12, 0, 0);
cost = game_do_command(mapCoord.x, bl | rotation << 8, mapCoord.y, rideIndex, GAME_COMMAND_PLACE_RIDE_ENTRANCE_OR_EXIT, 0, 0);
}
if (cost != MONEY32_UNDEFINED){
RCT2_GLOBAL(0x00F4414E, uint8) |= (1 << 0);
@ -1423,10 +1423,10 @@ int track_place_maze(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint8** trac
bl = 1;
if (RCT2_GLOBAL(0x00F440D4, uint8) == 4)bl = 0x69;
if (RCT2_GLOBAL(0x00F440D4, uint8) == 1){
cost = game_do_command(mapCoord.x, 0 | rotation << 8, mapCoord.y, ((z / 16) & 0xFF) | (1 << 8), GAME_COMMAND_12, -1, 0);
cost = game_do_command(mapCoord.x, 0 | rotation << 8, mapCoord.y, ((z / 16) & 0xFF) | (1 << 8), GAME_COMMAND_PLACE_RIDE_ENTRANCE_OR_EXIT, -1, 0);
}
else{
cost = game_do_command(mapCoord.x, bl | rotation << 8, mapCoord.y, rideIndex | (1 << 8), GAME_COMMAND_12, 0, 0);
cost = game_do_command(mapCoord.x, bl | rotation << 8, mapCoord.y, rideIndex | (1 << 8), GAME_COMMAND_PLACE_RIDE_ENTRANCE_OR_EXIT, 0, 0);
}
if (cost != MONEY32_UNDEFINED){
RCT2_GLOBAL(0x00F4414E, uint8) |= (1 << 0);
@ -1588,7 +1588,7 @@ int track_place_ride(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint8** trac
temp_z += trackBlock->z;
// rotation in bh
// track_type in dl
game_do_command(x, 0x69 | ((rotation & 3) << 8), y, track_type, GAME_COMMAND_4, temp_z, 0);
game_do_command(x, 0x69 | ((rotation & 3) << 8), y, track_type, GAME_COMMAND_REMOVE_TRACK, temp_z, 0);
}
if (RCT2_GLOBAL(0x00F440D4, uint8) == 1 ||
@ -1616,7 +1616,7 @@ int track_place_ride(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint8** trac
if (RCT2_GLOBAL(0x00F440D4, uint8) == 1)bl = 0;
RCT2_GLOBAL(0x00141E9AE, rct_string_id) = 927;
money32 cost = game_do_command(x, bl | (rotation << 8), y, edx, GAME_COMMAND_3, edi, 0);
money32 cost = game_do_command(x, bl | (rotation << 8), y, edx, GAME_COMMAND_PLACE_TRACK, edi, 0);
RCT2_GLOBAL(0x00F440D5, money32) += cost;
if (cost == MONEY32_UNDEFINED){
@ -1822,7 +1822,7 @@ int track_place_ride(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint8** trac
if (RCT2_GLOBAL(0x00F440D4, uint8) == 1)bl = 0;
RCT2_GLOBAL(0x00141E9AE, rct_string_id) = 927;
money32 cost = game_do_command(x, bl | (rotation << 8), y, rideIndex | (is_exit << 8), GAME_COMMAND_12, di, 0);
money32 cost = game_do_command(x, bl | (rotation << 8), y, rideIndex | (is_exit << 8), GAME_COMMAND_PLACE_RIDE_ENTRANCE_OR_EXIT, di, 0);
RCT2_GLOBAL(0x00F440D5, money32) += cost;
if (cost == MONEY32_UNDEFINED){
@ -1841,7 +1841,7 @@ int track_place_ride(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint8** trac
z /= 16;
RCT2_GLOBAL(0x00141E9AE, rct_string_id) = 927;
money32 cost = game_do_command(x, 0 | (rotation << 8), y, z | (is_exit << 8), GAME_COMMAND_12, -1, 0);
money32 cost = game_do_command(x, 0 | (rotation << 8), y, z | (is_exit << 8), GAME_COMMAND_PLACE_RIDE_ENTRANCE_OR_EXIT, -1, 0);
RCT2_GLOBAL(0x00F440D5, money32) += cost;
if (cost == MONEY32_UNDEFINED){
@ -2617,10 +2617,11 @@ int maze_ride_to_td6(uint8 rideIndex, rct_track_td6* track_design, uint8* track_
}
/* rct2: 0x006CE68D */
int tracked_ride_to_td6(uint8 rideIndex, rct_track_td6* track_design, uint8* track_elements){
int tracked_ride_to_td6(uint8 rideIndex, rct_track_td6* track_design, uint8* track_elements)
{
rct_ride* ride = GET_RIDE(rideIndex);
rct_xy_element trackElement;
track_begin_end trackBeginEnd;
if (sub_6CAF80(rideIndex, &trackElement) == 0){
RCT2_GLOBAL(0x00141E9AC, uint16) = 3347;
@ -2629,18 +2630,12 @@ int tracked_ride_to_td6(uint8 rideIndex, rct_track_td6* track_design, uint8* tra
int z = 0;
//6ce69e
if (!(sub_6C6402(&trackElement.element, &trackElement.x, &trackElement.y, &z))){
if (track_get_previous(trackElement.x, trackElement.y, trackElement.element, &trackBeginEnd)) {
rct_map_element* initial_map = trackElement.element;
do {
int x = trackElement.x;
int y = trackElement.y;
rct_map_element* map_element = trackElement.element;
if (sub_6C6402(&map_element, &x, &y, &z)){
if (!track_get_previous(trackBeginEnd.begin_x, trackBeginEnd.begin_y, trackBeginEnd.begin_element, &trackBeginEnd)) {
break;
}
trackElement.x = x;
trackElement.y = y;
trackElement.element = map_element;
} while (initial_map != trackElement.element);
}
@ -2733,7 +2728,7 @@ int tracked_ride_to_td6(uint8 rideIndex, rct_track_td6* track_design, uint8* tra
track->flags = flags;
track++;
if (!track_get_next(&trackElement, &trackElement))
if (!track_get_next(&trackElement, &trackElement, NULL, NULL))
break;
z = trackElement.element->base_height * 8;
@ -3432,3 +3427,15 @@ static void track_save_add_map_element(int mapElementSelectType, int x, int y, r
{
RCT2_CALLPROC_X(0x006D2B3C, x, mapElementSelectType, y, (int)mapElement, 0, 0, 0);
}
rct_preview_track *get_track_def_from_ride(rct_ride *ride, int trackType)
{
return ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_FLAT_RIDE) ?
RCT2_ADDRESS(0x00994A38, rct_preview_track*)[trackType] :
RCT2_ADDRESS(0x00994638, rct_preview_track*)[trackType];
}
rct_preview_track *get_track_def_from_ride_index(int rideIndex, int trackType)
{
return get_track_def_from_ride(GET_RIDE(rideIndex), trackType);
}

View File

@ -43,7 +43,7 @@ typedef struct {
sint16 x; // 0x01
sint16 y; // 0x03
sint16 z;
uint8 pad_07;
uint8 var_07;
uint8 var_08;
uint8 var_09;
} rct_preview_track;
@ -181,40 +181,86 @@ enum {
TRACK_NONE = 0,
TRACK_FLAT = 0,
TRACK_STATION_END = 2,
TRACK_VERTICAL_LOOP = 7,
TRACK_S_BEND = 13,
TRACK_TWIST = 17,
TRACK_HALF_LOOP = 18,
TRACK_CORKSCREW = 19,
TRACK_TOWER_BASE = 20,
TRACK_HELIX_SMALL= 21,
TRACK_HELIX_LARGE= 22,
TRACK_HELIX_LARGE_UNBANKED = 23,
TRACK_BRAKES = 24,
TRACK_ON_RIDE_PHOTO = 26,
TRACK_WATER_SPLASH = 27,
TRACK_BARREL_ROLL = 29,
TRACK_POWERED_LIFT = 30,
TRACK_HALF_LOOP_2 = 31, // ?
TRACK_LOG_FLUME_REVERSER = 33,
TRACK_WHOA_BELLY = 36,
TRACK_LIFT_HILL = 43,
TRACK_SPINNING_TUNNEL = 46,
TRACK_ROTATION_CONTROL_TOGGLE = 47,
TRACK_RAPIDS = 52,
TRACK_STRAIGHT,
TRACK_STATION_END,
TRACK_LIFT_HILL,
TRACK_LIFT_HILL_STEEP,
TRACK_LIFT_HILL_CURVE,
TRACK_FLAT_ROLL_BANKING,
TRACK_VERTICAL_LOOP,
TRACK_SLOPE,
TRACK_SLOPE_STEEP,
TRACK_SLOPE_LONG,
TRACK_SLOPE_CURVE,
TRACK_SLOPE_CURVE_STEEP,
TRACK_S_BEND,
TRACK_CURVE_VERY_SMALL,
TRACK_CURVE_SMALL,
TRACK_CURVE,
TRACK_TWIST,
TRACK_HALF_LOOP,
TRACK_CORKSCREW,
TRACK_TOWER_BASE,
TRACK_HELIX_SMALL,
TRACK_HELIX_LARGE,
TRACK_HELIX_LARGE_UNBANKED,
TRACK_BRAKES,
TRACK_25,
TRACK_ON_RIDE_PHOTO,
TRACK_WATER_SPLASH,
TRACK_SLOPE_VERTICAL,
TRACK_BARREL_ROLL,
TRACK_POWERED_LIFT,
TRACK_HALF_LOOP_LARGE,
TRACK_SLOPE_CURVE_BANKED,
TRACK_LOG_FLUME_REVERSER,
TRACK_HEARTLINE_ROLL,
TRACK_REVERSER,
TRACK_WHOA_BELLY,
TRACK_SLOPE_TO_FLAT,
TRACK_BLOCK_BRAKES,
TRACK_SLOPE_ROLL_BANKING,
TRACK_SLOPE_STEEP_LONG,
TRACK_CURVE_VERTICAL,
TRACK_42,
TRACK_LIFT_HILL_CABLE,
TRACK_LIFT_HILL_CURVED,
TRACK_QUARTER_LOOP,
TRACK_SPINNING_TUNNEL,
TRACK_ROTATION_CONTROL_TOGGLE,
TRACK_INLINE_TWIST_UNINVERTED,
TRACK_INLINE_TWIST_INVERTED,
TRACK_QUARTER_LOOP_UNINVERTED,
TRACK_QUARTER_LOOP_INVERTED,
TRACK_RAPIDS,
TRACK_HALF_LOOP_UNINVERTED,
TRACK_HALF_LOOP_INVERTED,
TRACK_WATERFALL = 152,
TRACK_WHIRLPOOL = 152,
TRACK_BRAKE_FOR_DROP = 172
};
enum {
TRACK_UP_25 = 2,
TRACK_UP_60 = 4,
TRACK_DOWN_25 = 6,
TRACK_DOWN_60 = 8,
TRACK_UP_90 = 10,
TRACK_DOWN_90 = 18,
TRACK_CURVE_LEFT_VERY_SMALL = 5,
TRACK_CURVE_LEFT_SMALL = 3,
TRACK_CURVE_LEFT = 1,
TRACK_CURVE_LEFT_LARGE = 7,
TRACK_CURVE_NONE = 0,
TRACK_CURVE_RIGHT_LARGE = 8,
TRACK_CURVE_RIGHT = 2,
TRACK_CURVE_RIGHT_SMALL = 4,
TRACK_CURVE_RIGHT_VERY_SMALL = 6
};
enum {
TRACK_SLOPE_NONE = 0,
TRACK_SLOPE_UP_25 = 2,
TRACK_SLOPE_UP_60 = 4,
TRACK_SLOPE_DOWN_25 = 6,
TRACK_SLOPE_DOWN_60 = 8,
TRACK_SLOPE_UP_90 = 10,
TRACK_SLOPE_DOWN_90 = 18,
TRACK_VANGLE_TOWER = 10,
TRACK_VANGLE_WHOA_BELLY = 10
@ -445,4 +491,7 @@ void game_command_place_track(int* eax, int* ebx, int* ecx, int* edx, int* esi,
void track_save_reset_scenery();
void track_save_select_nearby_scenery(int rideIndex);
rct_preview_track *get_track_def_from_ride(rct_ride *ride, int trackType);
rct_preview_track *get_track_def_from_ride_index(int rideIndex, int trackType);
#endif

View File

@ -0,0 +1,211 @@
/*****************************************************************************
* Copyright (c) 2014 Ted John
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* This file is part of 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.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include "../addresses.h"
#include "../audio/audio.h"
#include "../drawing/drawing.h"
#include "../game.h"
#include "../input.h"
#include "../interface/themes.h"
#include "../interface/viewport.h"
#include "../interface/widget.h"
#include "../interface/window.h"
#include "../localisation/localisation.h"
#include "../ride/track.h"
#include "dropdown.h"
#pragma region Widgets
enum {
WIDX_BACKGROUND,
WIDX_TITLE,
WIDX_CLOSE,
WIDX_MAZE_MODE_GROUPBOX,
WIDX_MAZE_BUILD_MODE = 6,
WIDX_MAZE_MOVE_MODE,
WIDX_MAZE_FILL_MODE,
WIDX_MAZE_DIRECTION_GROUPBOX = 23,
WIDX_MAZE_DIRECTION_NW,
WIDX_MAZE_DIRECTION_NE,
WIDX_MAZE_DIRECTION_SW,
WIDX_MAZE_DIRECTION_SE,
};
static rct_widget window_maze_construction_widgets[] = {
{ WWT_FRAME, 0, 0, 165, 0, 199, 0xFFFFFFFF, STR_NONE },
{ WWT_CAPTION, 0, 1, 164, 1, 14, 896, STR_WINDOW_TITLE_TIP },
{ WWT_CLOSEBOX, 0, 153, 163, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP },
{ WWT_GROUPBOX, 0, 3, 162, 17, 71, STR_RIDE_CONSTRUCTION_MODE, STR_NONE },
{ WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, STR_NONE },
{ WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, STR_NONE },
{ WWT_FLATBTN, 1, 35, 66, 29, 60, 0x15C8, STR_RIDE_CONSTRUCTION_BUILD_MODE },
{ WWT_FLATBTN, 1, 67, 98, 29, 60, 0x15C9, STR_RIDE_CONSTRUCTION_MOVE_MODE },
{ WWT_FLATBTN, 1, 99, 130, 29, 60, 0x15CA, STR_RIDE_CONSTRUCTION_FILL_IN_MODE },
{ WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, STR_NONE },
{ WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, STR_NONE },
{ WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, STR_NONE },
{ WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, STR_NONE },
{ WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, STR_NONE },
{ WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, STR_NONE },
{ WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, STR_NONE },
{ WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, STR_NONE },
{ WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, STR_NONE },
{ WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, STR_NONE },
{ WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, STR_NONE },
{ WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, STR_NONE },
{ WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, STR_NONE },
{ WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, STR_NONE },
{ WWT_GROUPBOX, 0, 3, 162, 80, 166, STR_RIDE_CONSTRUCTION_BUILD, STR_NONE },
{ WWT_FLATBTN, 1, 83, 127, 96, 124, 0x1603, STR_RIDE_CONSTRUCTION_BUILD_MAZE_IN_THIS_DIRECTION_TIP },
{ WWT_FLATBTN, 1, 83, 127, 125, 153, 0x1604, STR_RIDE_CONSTRUCTION_BUILD_MAZE_IN_THIS_DIRECTION_TIP },
{ WWT_FLATBTN, 1, 38, 82, 125, 153, 0x1605, STR_RIDE_CONSTRUCTION_BUILD_MAZE_IN_THIS_DIRECTION_TIP },
{ WWT_FLATBTN, 1, 38, 82, 96, 124, 0x1606, STR_RIDE_CONSTRUCTION_BUILD_MAZE_IN_THIS_DIRECTION_TIP },
{ WWT_GROUPBOX, 0, 3, 162, 168, 195, 0xFFFFFFFF, STR_NONE },
{ WWT_DROPDOWN_BUTTON, 1, 9, 78, 178, 189, STR_RIDE_CONSTRUCTION_ENTRANCE, STR_RIDE_CONSTRUCTION_ENTRANCE_TIP },
{ WWT_DROPDOWN_BUTTON, 1, 87, 156, 178, 189, STR_RIDE_CONSTRUCTION_EXIT, STR_RIDE_CONSTRUCTION_EXIT_TIP },
{ WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, STR_NONE },
{ WWT_EMPTY, 0, 0, 0, 0, 0, 0xFFFFFFFF, STR_NONE },
{ WIDGETS_END }
};
#pragma endregion
#pragma region Events
static void window_maze_construction_emptysub() {}
static void window_maze_construction_close();
static void window_maze_construction_invalidate();
static void window_maze_construction_paint();
// 0x993F6C
static void* window_maze_construction_events[] = {
window_maze_construction_close,
(void*)0x006CD461,
(void*)0x006CD623,
(void*)0x006CD48C,
window_maze_construction_emptysub,
window_maze_construction_emptysub,
(void*)0x006CD767,
window_maze_construction_emptysub,
window_maze_construction_emptysub,
(void*)0x006CD63E,
(void*)0x006CD65D,
window_maze_construction_emptysub,
window_maze_construction_emptysub,
window_maze_construction_emptysub,
window_maze_construction_emptysub,
window_maze_construction_emptysub,
window_maze_construction_emptysub,
window_maze_construction_emptysub,
window_maze_construction_emptysub,
window_maze_construction_emptysub,
window_maze_construction_emptysub,
window_maze_construction_emptysub,
window_maze_construction_emptysub,
window_maze_construction_emptysub,
window_maze_construction_emptysub,
window_maze_construction_invalidate,
window_maze_construction_paint,
window_maze_construction_emptysub
};
#pragma endregion
/**
*
* rct2: 0x006CB481
*/
rct_window *window_maze_construction_open()
{
rct_window *w = window_create(0, 29, 166, 200, (uint32*)window_maze_construction_events, WC_RIDE_CONSTRUCTION, WF_9);
w->widgets = window_maze_construction_widgets;
w->enabled_widgets = 0x6F0001C4;
window_init_scroll_widgets(w);
colour_scheme_update(w);
w->number = _currentRideIndex;
window_push_others_right(w);
show_gridlines();
return w;
}
/**
*
* rct2: 0x006CD811
*/
static void window_maze_construction_close()
{
rct_window *w;
window_get_register(w);
sub_6C9627();
viewport_set_visibility(0);
map_invalidate_map_selection_tiles();
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 1);
// In order to cancel the yellow arrow correctly the
// selection tool should be cancelled.
tool_cancel();
hide_gridlines();
uint8 rideIndex = _currentRideIndex;
rct_ride* ride = GET_RIDE(rideIndex);
if (ride->overall_view == 0xFFFF) {
int savedPausedState = RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8);
RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) = 0;
game_do_command(0, 9, 0, rideIndex, GAME_COMMAND_7, 0, 0);
RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) = savedPausedState;
} else {
window_ride_main_open(rideIndex);
}
}
/**
*
* rct2: 0x006CD435
*/
static void window_maze_construction_invalidate()
{
rct_ride *ride = GET_RIDE(_currentRideIndex);
// Set window title arguments
RCT2_GLOBAL(0x013CE956, rct_string_id) = ride->name;
RCT2_GLOBAL(0x013CE958, uint32) = ride->name_arguments;
}
/**
*
* rct2: 0x006CD45B
*/
static void window_maze_construction_paint()
{
rct_window *w;
rct_drawpixelinfo *dpi;
window_paint_get_registers(w, dpi);
window_draw_widgets(w, dpi);
}

File diff suppressed because it is too large Load Diff

View File

@ -357,7 +357,7 @@ static void window_track_place_attempt_placement(int x, int y, int z, int bl, mo
ebx = bl;
ecx = y;
edi = z;
result = game_do_command_p(GAME_COMMAND_PLACE_TRACK, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
result = game_do_command_p(GAME_COMMAND_PLACE_TRACK_DESIGN, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
if (cost != NULL) *cost = result;
if (rideIndex != NULL) *rideIndex = edi & 0xFF;

View File

@ -153,14 +153,22 @@ void map_element_iterator_restart_for_tile(map_element_iterator *it)
rct_map_element *map_get_first_element_at(int x, int y)
{
if (x < 0 || y < 0 || x > 255 || y > 255)
{
log_error("Trying to access element outside of range");
if (x < 0 || y < 0 || x > 255 || y > 255) {
log_error("Trying to access element outside of range");
return NULL;
}
return TILE_MAP_ELEMENT_POINTER(x + y * 256);
}
void map_set_tile_elements(int x, int y, rct_map_element *elements)
{
if (x < 0 || y < 0 || x > 255 || y > 255) {
log_error("Trying to access element outside of range");
return;
}
TILE_MAP_ELEMENT_POINTER(x + y * 256) = elements;
}
int map_element_is_last_for_tile(rct_map_element *element)
{
return element->flags & MAP_ELEMENT_FLAG_LAST_TILE;
@ -171,6 +179,11 @@ int map_element_get_type(rct_map_element *element)
return element->type & MAP_ELEMENT_TYPE_MASK;
}
int map_element_get_direction(rct_map_element *element)
{
return element->type & MAP_ELEMENT_DIRECTION_MASK;
}
int map_element_get_terrain(rct_map_element *element)
{
int terrain = (element->properties.surface.terrain >> 5) & 7;
@ -3061,3 +3074,24 @@ static void sub_68AE2A(int x, int y)
}
}
}
int map_get_highest_z(int tileX, int tileY)
{
rct_map_element *mapElement;
int z;
mapElement = map_get_surface_element_at(tileX, tileY);
if (mapElement == NULL)
return -1;
z = mapElement->base_height * 8;
// Raise z so that is above highest point of land and water on tile
if ((mapElement->properties.surface.slope & 0x0F) != 0)
z += 16;
if ((mapElement->properties.surface.slope & 0x10) != 0)
z += 16;
z = max(z, (mapElement->properties.surface.terrain & 0x1F) * 16);
return z;
}

View File

@ -121,6 +121,10 @@ enum {
MAP_ELEMENT_TYPE_BANNER = (7 << 2)
};
enum {
MAP_ELEMENT_TYPE_FLAG_HIGHLIGHT = (1 << 6)
};
enum {
MAP_ELEMENT_DIRECTION_WEST,
MAP_ELEMENT_DIRECTION_NORTH,
@ -254,8 +258,10 @@ extern bool gClearFootpath;
void map_init(int size);
void map_update_tile_pointers();
rct_map_element *map_get_first_element_at(int x, int y);
void map_set_tile_elements(int x, int y, rct_map_element *elements);
int map_element_is_last_for_tile(rct_map_element *element);
int map_element_get_type(rct_map_element *element);
int map_element_get_direction(rct_map_element *element);
int map_element_get_terrain(rct_map_element *element);
int map_element_get_terrain_edge(rct_map_element *element);
void map_element_set_terrain(rct_map_element *element, int terrain);
@ -322,6 +328,7 @@ void map_element_iterator_restart_for_tile(map_element_iterator *it);
void map_remove_intersecting_walls(int x, int y, int z0, int z1, int direction);
void map_update_tiles();
int map_get_highest_z(int tileX, int tileY);
void sub_6A7594();
int map_element_get_banner_index(rct_map_element *mapElement);