refactor some of the track design place code

This commit is contained in:
Ted John 2016-04-28 19:43:20 +01:00
parent 68520765fc
commit e9935fee09
7 changed files with 203 additions and 285 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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