diff --git a/src/addresses.h b/src/addresses.h index 9accccfc0f..9377fdc0e3 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -252,8 +252,6 @@ #define RCT2_ADDRESS_TRACK_DESIGN_INDEX_CACHE 0x00F44109 #define RCT2_ADDRESS_TRACK_DESIGN_NEXT_INDEX_CACHE 0x00F44119 -#define RCT2_ADDRESS_TRACK_DESIGN_COST 0x00F4411D - #define RCT2_ADDRESS_TRACK_DESIGN_SCENERY_TOGGLE 0x00F44152 #define RCT2_ADDRESS_ABOVE_GROUND_FLAGS 0x00F441D4 @@ -603,6 +601,7 @@ #define RCT2_ADDRESS_CONSTRUCT_PATH_VALID_DIRECTIONS 0x00F3EF9E #define RCT2_ADDRESS_TRACK_PREVIEW_ROTATION 0x00F440AE +#define RCT2_ADDRESS_TRACK_DESIGN_COST 0x00F4411D #define RCT2_ADDRESS_NEXT_FREE_MAP_ELEMENT 0x0140E9A4 diff --git a/src/ride/track.c b/src/ride/track.c index d645359680..d423247482 100644 --- a/src/ride/track.c +++ b/src/ride/track.c @@ -241,6 +241,8 @@ const rct_trackdefinition gTrackDefinitions_INCORRECT[] = { rct_map_element **gTrackSavedMapElements = (rct_map_element**)0x00F63674; rct_track_td6 *gActiveTrackDesign; +money32 gTrackDesignCost; +uint8 gTrackDesignPlaceFlags; static bool track_save_should_select_scenery_around(int rideIndex, rct_map_element *mapElement); static void track_save_select_nearby_scenery_for_tile(int rideIndex, int cx, int cy); @@ -1010,6 +1012,23 @@ void track_update_max_min_coordinates(sint16 x, sint16 y, sint16 z){ } } +static void track_add_selection_tile(sint16 x, sint16 y) +{ + rct_xy16 *selectionTile = gMapSelectionTiles; + for (; selectionTile->x != -1; selectionTile++) { + if (selectionTile->x == x && selectionTile->y == y) { + return; + } + if (selectionTile + 1 >= &gMapSelectionTiles[300]) { + return; + } + } + selectionTile->x = x; + selectionTile->y = y; + selectionTile++; + selectionTile->x = -1; +} + /** * * rct2: 0x006D0964 @@ -1561,7 +1580,7 @@ int track_place_ride(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint8** trac RCT2_GLOBAL(0x00F44144, sint16) = y; RCT2_GLOBAL(0x00F44146, sint16) = z; - if (RCT2_GLOBAL(0x00F440D4, uint8) == 0){ + if (RCT2_GLOBAL(0x00F440D4, uint8) == 0) { gMapSelectionTiles->x = -1; RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_X, sint16) = x; RCT2_GLOBAL(RCT2_ADDRESS_MAP_ARROW_Y, sint16) = y; @@ -1574,83 +1593,42 @@ int track_place_ride(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint8** trac uint8 rotation = _currentTrackPieceDirection; rct_track_element* track = (rct_track_element*)(*track_elements); - for (; track->type != 0xFF; track++){ - - uint8 track_type = track->type; - if (track_type == TRACK_ELEM_INVERTED_90_DEG_UP_TO_FLAT_QUARTER_LOOP) - track_type = 0xFF; + for (; track->type != 0xFF; track++) { + uint8 trackType = track->type; + if (trackType == TRACK_ELEM_INVERTED_90_DEG_UP_TO_FLAT_QUARTER_LOOP) { + trackType = 0xFF; + } track_update_max_min_coordinates(x, y, z); - if (RCT2_GLOBAL(0x00F440D4, uint8) == 0){ - for (const rct_preview_track* trackBlock = TrackBlocks[track_type]; - trackBlock->index != 0xFF; - trackBlock++){ - rct_xy16 tile; - tile.x = x; - tile.y = y; - - switch (rotation & 3){ - case MAP_ELEMENT_DIRECTION_WEST: - tile.x += trackBlock->x; - tile.y += trackBlock->y; - break; - case MAP_ELEMENT_DIRECTION_NORTH: - tile.x += trackBlock->y; - tile.y -= trackBlock->x; - break; - case MAP_ELEMENT_DIRECTION_EAST: - tile.x -= trackBlock->x; - tile.y -= trackBlock->y; - break; - case MAP_ELEMENT_DIRECTION_SOUTH: - tile.x -= trackBlock->y; - tile.y += trackBlock->x; - break; - } - + if (RCT2_GLOBAL(0x00F440D4, uint8) == 0) { + for (const rct_preview_track* trackBlock = TrackBlocks[trackType]; trackBlock->index != 0xFF; trackBlock++) { + rct_xy16 tile = { x, y }; + map_offset_with_rotation(&tile.x, &tile.y, trackBlock->x, trackBlock->y, rotation); track_update_max_min_coordinates(tile.x, tile.y, z); - - uint8 new_tile = 1; - rct_xy16* selectionTile = gMapSelectionTiles; - for (; selectionTile->x != -1; selectionTile++){ - if (selectionTile->x == tile.x && selectionTile->y == tile.y){ - new_tile = 0; - break; - } - if (selectionTile + 1 >= &gMapSelectionTiles[300]){ - new_tile = 0; - break; - } - } - if (new_tile){ - selectionTile->x = tile.x; - selectionTile->y = tile.y; - selectionTile++; - selectionTile->x = -1; - } + track_add_selection_tile(tile.x, tile.y); } } - if (RCT2_GLOBAL(0x00F440D4, uint8) == 6){ - const rct_track_coordinates* track_coordinates = &TrackCoordinates[track_type]; + if (RCT2_GLOBAL(0x00F440D4, uint8) == 6) { + const rct_track_coordinates* track_coordinates = &TrackCoordinates[trackType]; //di int temp_z = z; temp_z -= track_coordinates->z_begin; - const rct_preview_track* trackBlock = TrackBlocks[track_type]; + const rct_preview_track* trackBlock = TrackBlocks[trackType]; temp_z += trackBlock->z; // rotation in bh // track_type in dl - game_do_command(x, 0x69 | ((rotation & 3) << 8), y, track_type, GAME_COMMAND_REMOVE_TRACK, temp_z, 0); + game_do_command(x, 0x69 | ((rotation & 3) << 8), y, trackType, GAME_COMMAND_REMOVE_TRACK, temp_z, 0); } if (RCT2_GLOBAL(0x00F440D4, uint8) == 1 || RCT2_GLOBAL(0x00F440D4, uint8) == 2 || RCT2_GLOBAL(0x00F440D4, uint8) == 4 || RCT2_GLOBAL(0x00F440D4, uint8) == 5){ - const rct_track_coordinates* track_coordinates = &TrackCoordinates[track_type]; + const rct_track_coordinates* track_coordinates = &TrackCoordinates[trackType]; //di int temp_z = z; @@ -1660,10 +1638,9 @@ int track_place_ride(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint8** trac (((track->flags >> 4) & 0x3) << 24) | (temp_z & 0xFFFF); - int edx = _currentRideIndex | (track_type << 8); - - if (track->flags & 0x80)edx |= 0x10000; - if (track->flags & 0x40)edx |= 0x20000; + int edx = _currentRideIndex | (trackType << 8); + if (track->flags & 0x80) edx |= 0x10000; + if (track->flags & 0x40) edx |= 0x20000; uint8 bl = 1; if (RCT2_GLOBAL(0x00F440D4, uint8) == 5)bl = 41; @@ -1680,103 +1657,48 @@ int track_place_ride(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint8** trac } } - if (RCT2_GLOBAL(0x00F440D4, uint8) == 3){ - int temp_z = z - TrackCoordinates[track_type].z_begin; - for (const rct_preview_track* trackBlock = TrackBlocks[track_type]; - trackBlock->index != 0xFF; - trackBlock++){ - rct_xy16 tile; - tile.x = x; - tile.y = y; - - switch (rotation & 3){ - case MAP_ELEMENT_DIRECTION_WEST: - tile.x += trackBlock->x; - tile.y += trackBlock->y; - break; - case MAP_ELEMENT_DIRECTION_NORTH: - tile.x += trackBlock->y; - tile.y -= trackBlock->x; - break; - case MAP_ELEMENT_DIRECTION_EAST: - tile.x -= trackBlock->x; - tile.y -= trackBlock->y; - break; - case MAP_ELEMENT_DIRECTION_SOUTH: - tile.x -= trackBlock->y; - tile.y += trackBlock->x; - break; + if (RCT2_GLOBAL(0x00F440D4, uint8) == 3) { + int tempZ = z - TrackCoordinates[trackType].z_begin; + for (const rct_preview_track* trackBlock = TrackBlocks[trackType]; trackBlock->index != 0xFF; trackBlock++) { + rct_xy16 tile = { x, y }; + map_offset_with_rotation(&tile.x, &tile.y, trackBlock->x, trackBlock->y, rotation); + if (tile.x < 0 || tile.y < 0 || tile.x >= (256 * 32) || tile.y >= (256 * 32)) { + continue; } - if (tile.x > 0x1FFF) - continue; - - if (tile.y > 0x1FFF) - continue; - - if (tile.x < 0) - continue; - - if (tile.y < 0) - continue; - - rct_map_element* map_element = map_get_surface_element_at(tile.x / 32, tile.y / 32); - - if (map_element == NULL) + rct_map_element *mapElement = map_get_surface_element_at(tile.x >> 5, tile.y >> 5); + if (mapElement == NULL) { return 0; + } - int height = map_element->base_height * 8; - if (map_element->properties.surface.slope & 0xF){ + int height = mapElement->base_height * 8; + if (mapElement->properties.surface.slope & 0x0F) { height += 16; - if (map_element->properties.surface.slope & 0x10){ + if (mapElement->properties.surface.slope & 0x10) { height += 16; } } - uint8 water_height = 16 * map_element->properties.surface.terrain & MAP_ELEMENT_WATER_HEIGHT_MASK; - if (water_height){ - if (water_height > height){ - height = water_height; - } + uint8 water_height = 16 * mapElement->properties.surface.terrain & MAP_ELEMENT_WATER_HEIGHT_MASK; + if (water_height > 0 && water_height > height) { + height = water_height; } - int height_diff = temp_z + RCT2_GLOBAL(0x00F440D5, sint16) + trackBlock->z - height; - - if (height_diff < 0){ - RCT2_GLOBAL(0x00F440D5, sint16) -= height_diff; + int heightDifference = tempZ + RCT2_GLOBAL(0x00F440D5, sint16) + trackBlock->z - height; + if (heightDifference < 0) { + RCT2_GLOBAL(0x00F440D5, sint16) -= heightDifference; } } } - const rct_track_coordinates* track_coordinates = &TrackCoordinates[track_type]; - rotation &= 3; - switch (rotation & 3){ - case 0: - x += track_coordinates->x; - y += track_coordinates->y; - break; - case 1: - x += track_coordinates->y; - y -= track_coordinates->x; - break; - case 2: - x -= track_coordinates->x; - y -= track_coordinates->y; - break; - case 3: - x -= track_coordinates->y; - y += track_coordinates->x; - break; - } - + const rct_track_coordinates *track_coordinates = &TrackCoordinates[trackType]; + map_offset_with_rotation(&x, &y, track_coordinates->x, track_coordinates->y, rotation); z -= track_coordinates->z_begin; z += track_coordinates->z_end; - rotation += track_coordinates->rotation_end - track_coordinates->rotation_begin; - rotation &= 3; - if (track_coordinates->rotation_end & (1 << 2)) + rotation = (rotation + track_coordinates->rotation_end - track_coordinates->rotation_begin) & 3; + if (track_coordinates->rotation_end & (1 << 2)) { rotation |= (1 << 2); - - if (!(rotation & (1 << 2))){ + } else { x += TileDirectionDelta[rotation].x; y += TileDirectionDelta[rotation].y; } @@ -1787,128 +1709,81 @@ int track_place_ride(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint8** trac *track_elements = (uint8*)track + 1; rct_track_entrance* entrance = (rct_track_entrance*)(*track_elements); for (; entrance->z != -1; entrance++){ - rotation = _currentTrackPieceDirection; + rotation = _currentTrackPieceDirection & 3; x = entrance->x; y = entrance->y; - - switch (rotation & 3){ - case MAP_ELEMENT_DIRECTION_WEST: - break; - case MAP_ELEMENT_DIRECTION_NORTH:{ - int temp_x = -x; - x = y; - y = temp_x; - } - break; - case MAP_ELEMENT_DIRECTION_EAST: - x = -x; - y = -y; - break; - case MAP_ELEMENT_DIRECTION_SOUTH:{ - int temp_y = -y; - y = x; - x = temp_y; - } - break; - } - + rotate_map_coordinates(&x, &y, rotation); x += RCT2_GLOBAL(0x00F44142, sint16); y += RCT2_GLOBAL(0x00F44144, sint16); - track_update_max_min_coordinates(x, y, z); - if (RCT2_GLOBAL(0x00F440D4, uint8) == 0){ - uint8 new_tile = 1; - rct_xy16* selectionTile = gMapSelectionTiles; - for (; selectionTile->x != -1; selectionTile++){ - if (selectionTile->x == x && selectionTile->y == y){ - new_tile = 0; - break; - } - if (selectionTile + 1 >= &gMapSelectionTiles[300]){ - new_tile = 0; - break; - } - } - if (new_tile){ - selectionTile->x = x; - selectionTile->y = y; - selectionTile++; - selectionTile->x = -1; - } + if (RCT2_GLOBAL(0x00F440D4, uint8) == 0) { + track_add_selection_tile(x, y); } if (RCT2_GLOBAL(0x00F440D4, uint8) == 1 || RCT2_GLOBAL(0x00F440D4, uint8) == 2 || RCT2_GLOBAL(0x00F440D4, uint8) == 4 || - RCT2_GLOBAL(0x00F440D4, uint8) == 5){ - - //bh - rotation += entrance->direction; - rotation &= 3; - - //dh rideIndex is dl - uint8 is_exit = 0; - if (entrance->direction & (1 << 7)){ - is_exit = 1; + RCT2_GLOBAL(0x00F440D4, uint8) == 5 + ) { + rotation = (rotation + entrance->direction) & 3; + uint8 isExit = 0; + if (entrance->direction & (1 << 7)) { + isExit = 1; } if (RCT2_GLOBAL(0x00F440D4, uint8) != 1){ - rct_xy16 tile; - tile.x = x + TileDirectionDelta[rotation].x; - tile.y = y + TileDirectionDelta[rotation].y; - - rct_map_element* map_element = map_get_first_element_at(tile.x / 32, tile.y / 32); + rct_xy16 tile = { + x + TileDirectionDelta[rotation].x, + y + TileDirectionDelta[rotation].y + }; + rct_map_element* map_element = map_get_first_element_at(tile.x >> 5, tile.y >> 5); z = RCT2_GLOBAL(0x00F44146, sint16) / 8; - z += (entrance->z == (sint8)0x80) ? -1 : entrance->z; - do{ - if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_TRACK) - continue; - if (map_element->base_height != z) - continue; + do { + if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_TRACK) continue; + if (map_element->base_height != z) continue; - int di = (map_element->properties.track.sequence >> 4) & 0x7; + int di = (map_element->properties.track.sequence >> 4) & 0x07; uint8 bl = 1; - if (RCT2_GLOBAL(0x00F440D4, uint8) == 5)bl = 41; - if (RCT2_GLOBAL(0x00F440D4, uint8) == 4)bl = 105; - if (RCT2_GLOBAL(0x00F440D4, uint8) == 1)bl = 0; + if (RCT2_GLOBAL(0x00F440D4, uint8) == 5) bl = 41; + if (RCT2_GLOBAL(0x00F440D4, uint8) == 4) bl = 105; + if (RCT2_GLOBAL(0x00F440D4, uint8) == 1) bl = 0; gGameCommandErrorTitle = STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE; - money32 cost = game_do_command(x, bl | (rotation << 8), y, rideIndex | (is_exit << 8), GAME_COMMAND_PLACE_RIDE_ENTRANCE_OR_EXIT, di, 0); + money32 cost = game_do_command(x, bl | (rotation << 8), y, rideIndex | (isExit << 8), GAME_COMMAND_PLACE_RIDE_ENTRANCE_OR_EXIT, di, 0); RCT2_GLOBAL(0x00F440D5, money32) += cost; - if (cost == MONEY32_UNDEFINED){ + if (cost == MONEY32_UNDEFINED) { RCT2_GLOBAL(0x00F440D5, money32) = cost; return 0; } RCT2_GLOBAL(0x00F4414E, uint8) |= (1 << 0); break; } while (!map_element_is_last_for_tile(map_element++)); - } - else{ + } else { //dl z = (entrance->z == (sint8)0x80) ? -1 : entrance->z; z *= 8; z += RCT2_GLOBAL(0x00F44146, sint16); - z /= 16; + z >>= 4; gGameCommandErrorTitle = STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE; - 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){ + money32 cost = game_do_command(x, 0 | (rotation << 8), y, z | (isExit << 8), GAME_COMMAND_PLACE_RIDE_ENTRANCE_OR_EXIT, -1, 0); + if (cost == MONEY32_UNDEFINED) { RCT2_GLOBAL(0x00F440D5, money32) = cost; return 0; + } else { + RCT2_GLOBAL(0x00F440D5, money32) += cost; + RCT2_GLOBAL(0x00F4414E, uint8) |= (1 << 0); } - RCT2_GLOBAL(0x00F4414E, uint8) |= (1 << 0); } } } - if (RCT2_GLOBAL(0x00F440D4, uint8) == 6){ + if (RCT2_GLOBAL(0x00F440D4, uint8) == 6) { sub_6CB945(_currentRideIndex); rct_ride* ride = get_ride(_currentRideIndex); user_string_free(ride->name); @@ -1916,7 +1791,6 @@ int track_place_ride(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint8** trac } *track_elements = ((uint8*)(entrance)) + 1; - return 1; } @@ -1986,53 +1860,62 @@ int sub_6D01B3(rct_track_td6 *td6, uint8 bl, uint8 rideIndex, int x, int y, int return RCT2_GLOBAL(0x00F440D5, money32); } +money32 ride_create_command(int type, int subType, int flags, uint8 *outRideIndex, uint8 *outRideColour) +{ + int eax = 0; + int ebx = flags; + int ecx = 0; + int edx = type | (subType << 8); + int esi = 0; + int edi = 0; + int ebp = 0; + money32 cost = game_do_command_p(GAME_COMMAND_CREATE_RIDE, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + *outRideIndex = edi & 0xFF; + *outRideColour = eax; + return cost; +} + /** * * rct2: 0x006D2189 * ebx = ride_id * cost = edi */ -int sub_6D2189(rct_track_td6 *td6, int* cost, uint8* ride_id) +bool sub_6D2189(rct_track_td6 *td6, money32 *cost, uint8 *rideId) { - RCT2_GLOBAL(0xF44151, uint8) = 0; + RCT2_GLOBAL(0x00F44151, uint8) = 0; + uint8 entry_type, entry_index; - - if (!find_object_in_entry_group(&td6->vehicle_object, &entry_type, &entry_index)) + if (!find_object_in_entry_group(&td6->vehicle_object, &entry_type, &entry_index)) { entry_index = 0xFF; + } - int eax = 0, ebx, ecx = 0, edx, esi, edi = 0, ebp = 0; - ebx = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; - edx = td6->type | (entry_index << 8); - esi = GAME_COMMAND_CREATE_RIDE; + uint8 rideIndex; + uint8 colour; + uint8 rideCreateFlags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_5; + if (ride_create_command(td6->type, entry_index, rideCreateFlags, &rideIndex, &colour) == MONEY32_UNDEFINED) { + return false; + } - if (MONEY32_UNDEFINED == game_do_command_p(GAME_COMMAND_CREATE_RIDE, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp)) return 1; - - // bh - *ride_id = edi & 0xFF; - - rct_ride* ride = get_ride(*ride_id); - - const utf8* ride_name = RCT2_ADDRESS(0x9E3504, const utf8); + rct_ride *ride = get_ride(rideIndex); + const utf8 *ride_name = RCT2_ADDRESS(0x009E3504, const utf8); rct_string_id new_ride_name = user_string_allocate(132, ride_name); - - if (new_ride_name){ + if (new_ride_name != 0) { rct_string_id old_name = ride->name; ride->name = new_ride_name; user_string_free(old_name); } uint8 version = td6->version_and_colour_scheme >> 2; - - if (version == 2){ + if (version == 2) { ride->entrance_style = td6->entrance_style; } - if (version != 0){ + if (version != 0) { memcpy(&ride->track_colour_main, &td6->track_spine_colour, 4); memcpy(&ride->track_colour_additional, &td6->track_rail_colour, 4); memcpy(&ride->track_colour_supports, &td6->track_support_colour, 4); - } - else{ + } else { memset(&ride->track_colour_main, td6->track_spine_colour_rct1, 4); memset(&ride->track_colour_additional, td6->track_rail_colour_rct1, 4); memset(&ride->track_colour_supports, td6->track_support_colour_rct1, 4); @@ -2042,43 +1925,42 @@ int sub_6D2189(rct_track_td6 *td6, int* cost, uint8* ride_id) uint8 backup_rotation = _currentTrackPieceDirection; uint32 backup_park_flags = gParkFlags; gParkFlags &= ~PARK_FLAGS_FORBID_HIGH_CONSTRUCTION; - int map_size = gMapSize << 4; + int mapSize = gMapSize << 4; _currentTrackPieceDirection = 0; - int z = sub_6D01B3(td6, 3, 0, map_size, map_size, 16); + int z = sub_6D01B3(td6, PTD_OPERATION_GET_PLACE_Z, 0, mapSize, mapSize, 16); - if (RCT2_GLOBAL(0xF4414E, uint8) & 4){ - RCT2_GLOBAL(0xF44151, uint8) |= 2; + if (RCT2_GLOBAL(0x00F4414E, uint8) & 4){ + RCT2_GLOBAL(0x00F44151, uint8) |= 2; } - //dx + z += 16 - RCT2_GLOBAL(0xF44129, uint16); - int bl = 5; - if (RCT2_GLOBAL(0xF4414E, uint8) & 2){ - bl |= 0x80; - RCT2_GLOBAL(0xF44151, uint8) |= 1; + int operation = PTD_OPERATION_GET_COST; + if (RCT2_GLOBAL(0x00F4414E, uint8) & 2) { + operation |= 0x80; + RCT2_GLOBAL(0x00F44151, uint8) |= 1; } - edi = sub_6D01B3(td6, bl, *ride_id, map_size, map_size, z); + + money32 resultCost = sub_6D01B3(td6, operation, rideIndex, mapSize, mapSize, z); gParkFlags = backup_park_flags; - if (edi != MONEY32_UNDEFINED){ - + if (resultCost != MONEY32_UNDEFINED) { if (!find_object_in_entry_group(&td6->vehicle_object, &entry_type, &entry_index)){ - RCT2_GLOBAL(0xF44151, uint8) |= 4; + RCT2_GLOBAL(0x00F44151, uint8) |= 4; } _currentTrackPieceDirection = backup_rotation; RCT2_GLOBAL(0x009D8150, uint8) &= ~1; - *cost = edi; - return 1; - } - else{ - + *cost = resultCost; + *rideId = rideIndex; + return true; + } else { _currentTrackPieceDirection = backup_rotation; user_string_free(ride->name); ride->type = RIDE_TYPE_NULL; RCT2_GLOBAL(0x009D8150, uint8) &= ~1; - return 0; + return false; } } @@ -2107,16 +1989,14 @@ void draw_track_preview(rct_track_td6 *td6, uint8** preview) load_track_scenery_objects(); } - int cost; + money32 cost; uint8 ride_id; - if (!sub_6D2189(td6, &cost, &ride_id)) { memset(preview, 0, TRACK_PREVIEW_IMAGE_SIZE * 4); reload_map_backup(); return; } - - RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_COST, money32) = cost; + gTrackDesignCost = cost; rct_viewport* view = RCT2_ADDRESS(0x9D8161, rct_viewport); rct_drawpixelinfo* dpi = RCT2_ADDRESS(0x9D8151, rct_drawpixelinfo); @@ -2274,7 +2154,7 @@ rct_track_design *track_get_info(int index, uint8** preview) // Load in a new preview image, calculate cost variable, calculate var_06 draw_track_preview(&trackDesign->track_td6, (uint8**)trackDesign->preview); - trackDesign->track_td6.cost = RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_COST, money32); + trackDesign->track_td6.cost = gTrackDesignCost; trackDesign->track_td6.track_flags = RCT2_GLOBAL(0x00F44151, uint8) & 7; } @@ -2629,7 +2509,7 @@ int maze_ride_to_td6(uint8 rideIndex, rct_track_td6* track_design, uint8* track_ // Save global vars as they are still used by scenery sint16 start_z = RCT2_GLOBAL(0x00F44146, sint16); - sub_6D01B3(track_design, 0, 0, 4096, 4096, 0); + sub_6D01B3(track_design, PTD_OPERATION_DRAW_OUTLINES, 0, 4096, 4096, 0); RCT2_GLOBAL(0x00F44142, sint16) = start_x; RCT2_GLOBAL(0x00F44144, sint16) = start_y; RCT2_GLOBAL(0x00F44146, sint16) = start_z; @@ -2888,7 +2768,7 @@ int tracked_ride_to_td6(uint8 rideIndex, rct_track_td6* track_design, uint8* tra RCT2_GLOBAL(0x00F44058, uint8*) = track_elements; - sub_6D01B3(track_design, 0, 0, 4096, 4096, 0); + sub_6D01B3(track_design, PTD_OPERATION_DRAW_OUTLINES, 0, 4096, 4096, 0); // Resave global vars for scenery reasons. RCT2_GLOBAL(0x00F44142, sint16) = start_x; @@ -3166,7 +3046,7 @@ rct_track_design *temp_track_get_info(char* path, uint8** preview) // Load in a new preview image, calculate cost variable, calculate var_06 draw_track_preview(&trackDesign->track_td6, (uint8**)trackDesign->preview); - trackDesign->track_td6.cost = RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_COST, money32); + trackDesign->track_td6.cost = gTrackDesignCost; trackDesign->track_td6.track_flags = RCT2_GLOBAL(0x00F44151, uint8) & 7; } @@ -3302,19 +3182,18 @@ void game_command_place_track_design(int* eax, int* ebx, int* ecx, int* edx, int money32 cost = 0; if (!(flags & GAME_COMMAND_FLAG_APPLY)){ RCT2_GLOBAL(0x00F44150, uint8) = 0; - cost = sub_6D01B3(track_design, 1, rideIndex, x, y, z); + cost = sub_6D01B3(track_design, PTD_OPERATION_1, rideIndex, x, y, z); if (RCT2_GLOBAL(0x00F4414E, uint8) & (1 << 1)){ RCT2_GLOBAL(0x00F44150, uint8) |= 1 << 7; - cost = sub_6D01B3(track_design, 0x81, rideIndex, x, y, z); + cost = sub_6D01B3(track_design, 0x80 | PTD_OPERATION_1, rideIndex, x, y, z); } } else{ - uint8 bl = 0; - if (flags & GAME_COMMAND_FLAG_GHOST){ - bl = 4; - } - else{ - bl = 2; + uint8 bl; + if (flags & GAME_COMMAND_FLAG_GHOST) { + bl = PTD_OPERATION_4; + } else { + bl = PTD_OPERATION_2; } bl |= RCT2_GLOBAL(0x00F44150, uint8); cost = sub_6D01B3(track_design, bl, rideIndex, x, y, z); diff --git a/src/ride/track.h b/src/ride/track.h index c90f1b2f2e..7845637713 100644 --- a/src/ride/track.h +++ b/src/ride/track.h @@ -573,6 +573,20 @@ enum { TRACK_ELEMENT_LOCATION_IS_UNDERGROUND = 2, }; +enum { + TDPF_PLACE_SCENERY = 1 << 0, +}; + +enum { + PTD_OPERATION_DRAW_OUTLINES, + PTD_OPERATION_1, + PTD_OPERATION_2, + PTD_OPERATION_GET_PLACE_Z, + PTD_OPERATION_4, + PTD_OPERATION_GET_COST, + PTD_OPERATION_CLEAR_OUTLINES +}; + typedef struct { rct_xy_element last; rct_xy_element current; @@ -594,6 +608,8 @@ extern const rct_trackdefinition *gTrackDefinitions; extern rct_map_element **gTrackSavedMapElements; extern rct_track_td6 *gActiveTrackDesign; +extern money32 gTrackDesignCost; +extern uint8 gTrackDesignPlaceFlags; void track_load_list(ride_list_item item); int sub_67726A(const char *path); diff --git a/src/windows/track_list.c b/src/windows/track_list.c index 314d236bb9..71662c358a 100644 --- a/src/windows/track_list.c +++ b/src/windows/track_list.c @@ -413,7 +413,7 @@ static void window_track_list_paint(rct_window *w, rct_drawpixelinfo *dpi) // Load in a new preview image, calculate cost variable, calculate var_06 draw_track_preview(td6, (uint8**)_loadedTrackDesignPreview); - td6->cost = RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_COST, money32); + td6->cost = gTrackDesignCost; td6->track_flags = RCT2_GLOBAL(0x00F44151, uint8) & 7; _loadedTrackDesignIndex = trackIndex; diff --git a/src/windows/track_place.c b/src/windows/track_place.c index 8b17650b9d..25ce3bfab8 100644 --- a/src/windows/track_place.c +++ b/src/windows/track_place.c @@ -307,7 +307,7 @@ static void window_track_place_clear_provisional() if (_window_track_place_last_was_valid) { sub_6D01B3( gActiveTrackDesign, - 6, + PTD_OPERATION_CLEAR_OUTLINES, RCT2_GLOBAL(0x00F440EB, uint8), _window_track_place_last_valid_x, _window_track_place_last_valid_y, @@ -342,7 +342,7 @@ static int window_track_place_get_base_z(int x, int y) if (mapElement->properties.surface.terrain & 0x1F) z = max(z, (mapElement->properties.surface.terrain & 0x1F) << 4); - return z + sub_6D01B3(gActiveTrackDesign, 3, 0, x, y, z); + return z + sub_6D01B3(gActiveTrackDesign, PTD_OPERATION_GET_PLACE_Z, 0, x, y, z); } static void window_track_place_attempt_placement(int x, int y, int z, int bl, money32 *cost, uint8 *rideIndex) @@ -475,7 +475,7 @@ static void window_track_place_toolupdate(rct_window* w, int widgetIndex, int x, // Check if tool map position has changed since last update if (mapX == _window_track_place_last_x && mapY == _window_track_place_last_y) { - sub_6D01B3(gActiveTrackDesign, 0, 0, mapX, mapY, 0); + sub_6D01B3(gActiveTrackDesign, PTD_OPERATION_DRAW_OUTLINES, 0, mapX, mapY, 0); return; } @@ -508,7 +508,7 @@ static void window_track_place_toolupdate(rct_window* w, int widgetIndex, int x, widget_invalidate(w, WIDX_PRICE); } - sub_6D01B3(gActiveTrackDesign, 0, 0, mapX, mapY, mapZ); + sub_6D01B3(gActiveTrackDesign, PTD_OPERATION_DRAW_OUTLINES, 0, mapX, mapY, mapZ); } /** diff --git a/src/world/map.c b/src/world/map.c index 1c969d75c4..28c0a1c3d5 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -5494,3 +5494,25 @@ rct_map_element *map_get_track_element_at_with_direction_from_ride(int x, int y, return NULL; }; + +void map_offset_with_rotation(sint16 *x, sint16 *y, sint16 offsetX, sint16 offsetY, uint8 rotation) +{ + switch (rotation & 3) { + case MAP_ELEMENT_DIRECTION_WEST: + *x += offsetX; + *y += offsetY; + break; + case MAP_ELEMENT_DIRECTION_NORTH: + *x += offsetY; + *y -= offsetX; + break; + case MAP_ELEMENT_DIRECTION_EAST: + *x -= offsetX; + *y -= offsetY; + break; + case MAP_ELEMENT_DIRECTION_SOUTH: + *x -= offsetY; + *y += offsetX; + break; + } +} diff --git a/src/world/map.h b/src/world/map.h index 99dd11c160..1f46b5a738 100644 --- a/src/world/map.h +++ b/src/world/map.h @@ -425,6 +425,8 @@ bool map_large_scenery_get_origin( int *outX, int *outY, int *outZ, rct_map_element** outElement ); +void map_offset_with_rotation(sint16 *x, sint16 *y, sint16 offsetX, sint16 offsetY, uint8 rotation); + rct_map_element *map_get_track_element_at(int x, int y, int z); rct_map_element *map_get_track_element_at_of_type(int x, int y, int z, int trackType); rct_map_element *map_get_track_element_at_of_type_seq(int x, int y, int z, int trackType, int sequence);