diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index 5b4a21251e..f478ce47c6 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -1870,7 +1870,7 @@ static void window_ride_construction_construct(rct_window* w) */ static void window_ride_construction_mouseup_demolish(rct_window* w) { - int32_t x, y, z, direction, type; + int32_t direction, type; TileElement* tileElement; CoordsXYE inputElement, outputElement; track_begin_end trackBeginEnd; @@ -1901,47 +1901,41 @@ static void window_ride_construction_mouseup_demolish(rct_window* w) } // Invalidate the selected track element or make sure it's at origin??? - x = _currentTrackBegin.x; - y = _currentTrackBegin.y; - z = _currentTrackBegin.z; direction = _currentTrackPieceDirection; type = _currentTrackPieceType; - if (sub_6C683D(&x, &y, &z, direction & 3, type, 0, &tileElement, 0)) + auto newCoords = sub_6C683D({ _currentTrackBegin, static_cast(direction & 3) }, type, 0, &tileElement, 0); + if (newCoords == std::nullopt) { window_ride_construction_update_active_elements(); return; } // Get the previous track element to go to after the selected track element is deleted - inputElement.x = x; - inputElement.y = y; + inputElement.x = newCoords->x; + inputElement.y = newCoords->y; inputElement.element = tileElement; - if (track_block_get_previous(x, y, tileElement, &trackBeginEnd)) + if (track_block_get_previous(newCoords->x, newCoords->y, tileElement, &trackBeginEnd)) { - x = trackBeginEnd.begin_x; - y = trackBeginEnd.begin_y; - z = trackBeginEnd.begin_z; + *newCoords = { trackBeginEnd.begin_x, trackBeginEnd.begin_y, trackBeginEnd.begin_z }; direction = trackBeginEnd.begin_direction; type = trackBeginEnd.begin_element->AsTrack()->GetTrackType(); gGotoStartPlacementMode = false; } - else if (track_block_get_next(&inputElement, &outputElement, &z, &direction)) + else if (track_block_get_next(&inputElement, &outputElement, &newCoords->z, &direction)) { - x = outputElement.x; - y = outputElement.y; + newCoords->x = outputElement.x; + newCoords->y = outputElement.y; direction = outputElement.element->GetDirection(); type = outputElement.element->AsTrack()->GetTrackType(); gGotoStartPlacementMode = false; } else { - x = _currentTrackBegin.x; - y = _currentTrackBegin.y; - z = _currentTrackBegin.z; direction = _currentTrackPieceDirection; type = _currentTrackPieceType; + newCoords = sub_6C683D({ _currentTrackBegin, static_cast(direction & 3) }, type, 0, &tileElement, 0); - if (sub_6C683D(&x, &y, &z, direction & 3, type, 0, &tileElement, 0)) + if (newCoords == std::nullopt) { window_ride_construction_update_active_elements(); return; @@ -1949,7 +1943,7 @@ static void window_ride_construction_mouseup_demolish(rct_window* w) const rct_preview_track* trackBlock = get_track_def_from_ride_index( _currentRideIndex, tileElement->AsTrack()->GetTrackType()); - z = (tileElement->GetBaseZ()) - trackBlock->z; + newCoords->z = (tileElement->GetBaseZ()) - trackBlock->z; gGotoStartPlacementMode = true; } @@ -1968,7 +1962,7 @@ static void window_ride_construction_mouseup_demolish(rct_window* w) if (ride != nullptr) { _stationConstructed = ride->num_stations != 0; - window_ride_construction_mouseup_demolish_next_piece(x, y, z, direction, type); + window_ride_construction_mouseup_demolish_next_piece(newCoords->x, newCoords->y, newCoords->z, direction, type); } } }); @@ -2516,10 +2510,10 @@ void window_ride_construction_update_active_elements_impl() _selectedTrackType = 255; if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_SELECTED) { - int32_t x = _currentTrackBegin.x; - int32_t y = _currentTrackBegin.y; - int32_t z = _currentTrackBegin.z; - if (!sub_6C683D(&x, &y, &z, _currentTrackPieceDirection & 3, _currentTrackPieceType, 0, &tileElement, 0)) + if (sub_6C683D( + { _currentTrackBegin, static_cast(_currentTrackPieceDirection & 3) }, _currentTrackPieceType, 0, + &tileElement, 0) + != std::nullopt) { _selectedTrackType = tileElement->AsTrack()->GetTrackType(); if (track_element_has_speed_setting(tileElement->AsTrack()->GetTrackType())) @@ -2622,24 +2616,25 @@ void sub_6C94D8() map_invalidate_tile_full({ x, y }); break; case RIDE_CONSTRUCTION_STATE_SELECTED: + { _rideConstructionArrowPulseTime--; if (_rideConstructionArrowPulseTime >= 0) break; _rideConstructionArrowPulseTime = 5; _currentTrackSelectionFlags ^= TRACK_SELECTION_FLAG_ARROW; - x = _currentTrackBegin.x; - y = _currentTrackBegin.y; - z = _currentTrackBegin.z; direction = _currentTrackPieceDirection & 3; type = _currentTrackPieceType; - if (sub_6C683D( - &x, &y, &z, direction, type, 0, nullptr, _currentTrackSelectionFlags & TRACK_SELECTION_FLAG_ARROW ? 2 : 1)) + auto newCoords = sub_6C683D( + { _currentTrackBegin, static_cast(direction) }, type, 0, nullptr, + _currentTrackSelectionFlags & TRACK_SELECTION_FLAG_ARROW ? 2 : 1); + if (newCoords == std::nullopt) { ride_construction_remove_ghosts(); _rideConstructionState = RIDE_CONSTRUCTION_STATE_0; } break; + } case 6: case 7: case 8: @@ -3409,11 +3404,9 @@ static void window_ride_construction_show_special_track_dropdown(rct_window* w, */ static void ride_selected_track_set_seat_rotation(int32_t seatRotation) { - int32_t x, y, z; - x = _currentTrackBegin.x; - y = _currentTrackBegin.y; - z = _currentTrackBegin.z; - sub_6C683D(&x, &y, &z, _currentTrackPieceDirection & 3, _currentTrackPieceType, seatRotation, nullptr, (1 << 5)); + sub_6C683D( + { _currentTrackBegin, static_cast(_currentTrackPieceDirection & 3) }, _currentTrackPieceType, seatRotation, + nullptr, (1 << 5)); window_ride_construction_update_active_elements(); } @@ -3442,16 +3435,14 @@ static void loc_6C7502(int32_t al) static void ride_construction_set_brakes_speed(int32_t brakesSpeed) { TileElement* tileElement; - int32_t x, y, z; - x = _currentTrackBegin.x; - y = _currentTrackBegin.y; - z = _currentTrackBegin.z; - if (!sub_6C683D(&x, &y, &z, _currentTrackPieceDirection & 3, _currentTrackPieceType, 0, &tileElement, 0)) + if (sub_6C683D( + { _currentTrackBegin, static_cast(_currentTrackPieceDirection & 3) }, _currentTrackPieceType, 0, + &tileElement, 0) + != std::nullopt) { auto trackSetBrakeSpeed = TrackSetBrakeSpeedAction( - { _currentTrackBegin.x, _currentTrackBegin.y, _currentTrackBegin.z }, tileElement->AsTrack()->GetTrackType(), - brakesSpeed); + _currentTrackBegin, tileElement->AsTrack()->GetTrackType(), brakesSpeed); trackSetBrakeSpeed.SetCallback( [](const GameAction* ga, const GameActionResult* result) { window_ride_construction_update_active_elements(); }); GameActions::Execute(&trackSetBrakeSpeed); diff --git a/src/openrct2/actions/RideSetColourScheme.hpp b/src/openrct2/actions/RideSetColourScheme.hpp index a73a85a562..bb95db30d5 100644 --- a/src/openrct2/actions/RideSetColourScheme.hpp +++ b/src/openrct2/actions/RideSetColourScheme.hpp @@ -60,8 +60,7 @@ public: res->Expenditure = ExpenditureType::RideConstruction; res->ErrorTitle = STR_CANT_SET_COLOUR_SCHEME; - int32_t x = _loc.x, y = _loc.y, z = _loc.z; - sub_6C683D(&x, &y, &z, _loc.direction, _trackType, _newColourScheme, nullptr, 4); + sub_6C683D(_loc, _trackType, _newColourScheme, nullptr, 4); return res; } diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 40e7b24593..8e1326c4d6 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -1147,44 +1147,40 @@ void ride_clear_blocked_tiles(Ride* ride) * di : output_element * bp : flags */ -int32_t sub_6C683D( - int32_t* x, int32_t* y, int32_t* z, int32_t direction, int32_t type, uint16_t extra_params, TileElement** output_element, - uint16_t flags) +std::optional sub_6C683D( + const CoordsXYZD& location, int32_t type, uint16_t extra_params, TileElement** output_element, uint16_t flags) { // Find the relevant track piece, prefer sequence 0 (this ensures correct behaviour for diagonal track pieces) - auto location = CoordsXYZD{ *x, *y, *z, static_cast(direction) }; auto trackElement = map_get_track_element_at_of_type_seq(location, type, 0); if (trackElement == nullptr) { trackElement = map_get_track_element_at_of_type(location, type); if (trackElement == nullptr) { - return 1; + return std::nullopt; } } // Possibly z should be & 0xF8 auto trackBlock = get_track_def_from_ride_index(trackElement->GetRideIndex(), type); if (trackBlock == nullptr) - return 1; + return std::nullopt; // Now find all the elements that belong to this track piece int32_t sequence = trackElement->GetSequenceIndex(); uint8_t mapDirection = trackElement->GetDirection(); CoordsXY offsets = { trackBlock[sequence].x, trackBlock[sequence].y }; - CoordsXY newCoords = { *x, *y }; + CoordsXY newCoords = location; newCoords += offsets.Rotate(direction_reverse(mapDirection)); - *x = newCoords.x; - *y = newCoords.y; - *z -= trackBlock[sequence].z; + auto retCoordsXYZ = CoordsXYZ{ newCoords.x, newCoords.y, location.z - trackBlock[sequence].z }; - int32_t start_x = *x, start_y = *y, start_z = *z; - *z += trackBlock[0].z; + int32_t start_z = retCoordsXYZ.z; + retCoordsXYZ.z += trackBlock[0].z; for (int32_t i = 0; trackBlock[i].index != 0xFF; ++i) { - CoordsXY cur = { start_x, start_y }; + CoordsXY cur = { retCoordsXYZ }; offsets = { trackBlock[i].x, trackBlock[i].y }; cur += offsets.Rotate(mapDirection); int32_t cur_z = start_z + trackBlock[i].z; @@ -1192,10 +1188,10 @@ int32_t sub_6C683D( map_invalidate_tile_full(cur); trackElement = map_get_track_element_at_of_type_seq( - { cur.x, cur.y, cur_z, static_cast(direction) }, type, trackBlock[i].index); + { cur, cur_z, static_cast(location.direction) }, type, trackBlock[i].index); if (trackElement == nullptr) { - return 1; + return std::nullopt; } if (i == 0 && output_element != nullptr) { @@ -1226,7 +1222,7 @@ int32_t sub_6C683D( trackElement->SetHasCableLift(false); } } - return 0; + return retCoordsXYZ; } void ride_restore_provisional_track_piece() @@ -1316,15 +1312,12 @@ void ride_construction_remove_ghosts() */ void ride_construction_invalidate_current_track() { - int32_t x, y, z; - switch (_rideConstructionState) { case RIDE_CONSTRUCTION_STATE_SELECTED: - x = _currentTrackBegin.x; - y = _currentTrackBegin.y; - z = _currentTrackBegin.z; - sub_6C683D(&x, &y, &z, _currentTrackPieceDirection & 3, _currentTrackPieceType, 0, nullptr, 1); + sub_6C683D( + { _currentTrackBegin, static_cast(_currentTrackPieceDirection & 3) }, _currentTrackPieceType, 0, + nullptr, 1); break; case RIDE_CONSTRUCTION_STATE_MAZE_BUILD: case RIDE_CONSTRUCTION_STATE_MAZE_MOVE: @@ -1544,13 +1537,11 @@ void ride_select_next_section() if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_SELECTED) { ride_construction_invalidate_current_track(); - int32_t x = _currentTrackBegin.x; - int32_t y = _currentTrackBegin.y; - int32_t z = _currentTrackBegin.z; int32_t direction = _currentTrackPieceDirection; int32_t type = _currentTrackPieceType; TileElement* tileElement; - if (sub_6C683D(&x, &y, &z, direction & 3, type, 0, &tileElement, 0)) + auto newCoords = sub_6C683D({ _currentTrackBegin, static_cast(direction & 3) }, type, 0, &tileElement, 0); + if (newCoords == std::nullopt) { _rideConstructionState = RIDE_CONSTRUCTION_STATE_0; window_ride_construction_update_active_elements(); @@ -1561,13 +1552,13 @@ void ride_select_next_section() virtual_floor_invalidate(); CoordsXYE inputElement, outputElement; - inputElement.x = x; - inputElement.y = y; + inputElement.x = newCoords->x; + inputElement.y = newCoords->y; inputElement.element = tileElement; - if (track_block_get_next(&inputElement, &outputElement, &z, &direction)) + if (track_block_get_next(&inputElement, &outputElement, &newCoords->z, &direction)) { - x = outputElement.x; - y = outputElement.y; + newCoords->x = outputElement.x; + newCoords->y = outputElement.y; tileElement = outputElement.element; if (!scenery_tool_is_active()) { @@ -1578,9 +1569,7 @@ void ride_select_next_section() else { _rideConstructionState = RIDE_CONSTRUCTION_STATE_FRONT; - _currentTrackBegin.x = outputElement.x; - _currentTrackBegin.y = outputElement.y; - _currentTrackBegin.z = z; + _currentTrackBegin = { outputElement, newCoords->z }; _currentTrackPieceDirection = direction; _currentTrackPieceType = tileElement->AsTrack()->GetTrackType(); _currentTrackSelectionFlags = 0; @@ -1590,9 +1579,7 @@ void ride_select_next_section() return; } - _currentTrackBegin.x = x; - _currentTrackBegin.y = y; - _currentTrackBegin.z = z; + _currentTrackBegin = *newCoords; _currentTrackPieceDirection = tileElement->GetDirection(); _currentTrackPieceType = tileElement->AsTrack()->GetTrackType(); _currentTrackSelectionFlags = 0; @@ -1617,13 +1604,11 @@ void ride_select_previous_section() if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_SELECTED) { ride_construction_invalidate_current_track(); - int32_t x = _currentTrackBegin.x; - int32_t y = _currentTrackBegin.y; - int32_t z = _currentTrackBegin.z; int32_t direction = _currentTrackPieceDirection; int32_t type = _currentTrackPieceType; TileElement* tileElement; - if (sub_6C683D(&x, &y, &z, direction & 3, type, 0, &tileElement, 0)) + auto newCoords = sub_6C683D({ _currentTrackBegin, static_cast(direction & 3) }, type, 0, &tileElement, 0); + if (newCoords == std::nullopt) { _rideConstructionState = RIDE_CONSTRUCTION_STATE_0; window_ride_construction_update_active_elements(); @@ -1634,7 +1619,7 @@ void ride_select_previous_section() virtual_floor_invalidate(); track_begin_end trackBeginEnd; - if (track_block_get_previous(x, y, tileElement, &trackBeginEnd)) + if (track_block_get_previous(newCoords->x, newCoords->y, tileElement, &trackBeginEnd)) { _currentTrackBegin.x = trackBeginEnd.begin_x; _currentTrackBegin.y = trackBeginEnd.begin_y; @@ -1834,20 +1819,16 @@ bool ride_modify(CoordsXYE* input) if (tileElement.element == nullptr || tileElement.element->GetType() != TILE_ELEMENT_TYPE_TRACK) return false; - int32_t x = tileElement.x; - int32_t y = tileElement.y; - int32_t z = tileElement.element->GetBaseZ(); - int32_t direction = tileElement.element->GetDirection(); + auto tileCoords = CoordsXYZ{ tileElement, tileElement.element->GetBaseZ() }; + auto direction = tileElement.element->GetDirection(); int32_t type = tileElement.element->AsTrack()->GetTrackType(); - - if (sub_6C683D(&x, &y, &z, direction, type, 0, nullptr, 0)) + auto newCoords = sub_6C683D({ tileCoords, direction }, type, 0, nullptr, 0); + if (newCoords == std::nullopt) return false; _currentRideIndex = rideIndex; _rideConstructionState = RIDE_CONSTRUCTION_STATE_SELECTED; - _currentTrackBegin.x = x; - _currentTrackBegin.y = y; - _currentTrackBegin.z = z; + _currentTrackBegin = *newCoords; _currentTrackPieceDirection = direction; _currentTrackPieceType = type; _currentTrackSelectionFlags = 0; @@ -1867,9 +1848,7 @@ bool ride_modify(CoordsXYE* input) } _rideConstructionState = RIDE_CONSTRUCTION_STATE_SELECTED; - _currentTrackBegin.x = x; - _currentTrackBegin.y = y; - _currentTrackBegin.z = z; + _currentTrackBegin = *newCoords; _currentTrackPieceDirection = direction; _currentTrackPieceType = type; _currentTrackSelectionFlags = 0; @@ -1880,9 +1859,7 @@ bool ride_modify(CoordsXYE* input) if (_rideConstructionState != RIDE_CONSTRUCTION_STATE_BACK) { _rideConstructionState = RIDE_CONSTRUCTION_STATE_SELECTED; - _currentTrackBegin.x = x; - _currentTrackBegin.y = y; - _currentTrackBegin.z = z; + _currentTrackBegin = *newCoords; _currentTrackPieceDirection = direction; _currentTrackPieceType = type; _currentTrackSelectionFlags = 0; @@ -4154,14 +4131,12 @@ static void ride_set_boat_hire_return_point(Ride* ride, CoordsXYE* startElement) if (trackType != -1 && startX == trackBeginEnd.begin_x && startY == trackBeginEnd.begin_y) break; - int32_t x = trackBeginEnd.begin_x; - int32_t y = trackBeginEnd.begin_y; - int32_t z = trackBeginEnd.begin_z; + auto trackCoords = CoordsXYZ{ trackBeginEnd.begin_x, trackBeginEnd.begin_y, trackBeginEnd.begin_z }; int32_t direction = trackBeginEnd.begin_direction; trackType = trackBeginEnd.begin_element->AsTrack()->GetTrackType(); - sub_6C683D(&x, &y, &z, direction, trackType, 0, &returnTrackElement, 0); - returnX = x; - returnY = y; + auto newCoords = sub_6C683D({ trackCoords, static_cast(direction) }, trackType, 0, &returnTrackElement, 0); + returnX = newCoords == std::nullopt ? trackCoords.x : newCoords->x; + returnY = newCoords == std::nullopt ? trackCoords.y : newCoords->y; }; trackType = returnTrackElement->AsTrack()->GetTrackType(); @@ -4914,9 +4889,9 @@ static bool ride_initialise_cable_lift_track(Ride* ride, bool isApplying) if (isApplying) { auto tmpLoc = CoordsXYZ{ it.current, tileElement->GetBaseZ() }; - int32_t direction = tileElement->GetDirection(); + auto direction = tileElement->GetDirection(); trackType = tileElement->AsTrack()->GetTrackType(); - sub_6C683D(&tmpLoc.x, &tmpLoc.y, &tmpLoc.z, direction, trackType, 0, &tileElement, flags); + sub_6C683D({ tmpLoc, direction }, trackType, 0, &tileElement, flags); } } return true; diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 884abbcac8..1d48b2a9e3 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -1108,9 +1108,8 @@ int32_t ride_is_valid_for_open(Ride* ride, int32_t goingToBeOpen, bool isApplyin int32_t ride_is_valid_for_test(Ride* ride, int32_t status, bool isApplying); int32_t ride_initialise_construction_window(Ride* ride); void ride_construction_invalidate_current_track(); -int32_t sub_6C683D( - int32_t* x, int32_t* y, int32_t* z, int32_t direction, int32_t type, uint16_t extra_params, TileElement** output_element, - uint16_t flags); +std::optional sub_6C683D( + const CoordsXYZD& location, int32_t type, uint16_t extra_params, TileElement** output_element, uint16_t flags); void ride_set_map_tooltip(TileElement* tileElement); int32_t ride_music_params_update( const CoordsXYZ& rideCoords, Ride* ride, uint16_t sampleRate, uint32_t position, uint8_t* tuneId); diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 14a484e407..7263da3f29 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -186,11 +186,15 @@ rct_string_id TrackDesign::CreateTrackDesignTrack(const Ride& ride) auto trackType = trackElement.element->AsTrack()->GetTrackType(); uint8_t direction = trackElement.element->GetDirection(); _saveDirection = direction; + auto newCoords = sub_6C683D({ trackElement, z, direction }, trackType, 0, &trackElement.element, 0); - if (sub_6C683D(&trackElement.x, &trackElement.y, &z, direction, trackType, 0, &trackElement.element, 0)) + if (newCoords == std::nullopt) { return STR_TRACK_TOO_LARGE_OR_TOO_MUCH_SCENERY; } + trackElement.x = newCoords->x; + trackElement.y = newCoords->y; + z = newCoords->z; const rct_track_coordinates* trackCoordinates = &TrackCoordinates[trackElement.element->AsTrack()->GetTrackType()]; // Used in the following loop to know when we have @@ -241,11 +245,15 @@ rct_string_id TrackDesign::CreateTrackDesignTrack(const Ride& ride) z = trackElement.element->GetBaseZ(); direction = trackElement.element->GetDirection(); trackType = trackElement.element->AsTrack()->GetTrackType(); + newCoords = sub_6C683D({ trackElement, z, direction }, trackType, 0, &trackElement.element, 0); - if (sub_6C683D(&trackElement.x, &trackElement.y, &z, direction, trackType, 0, &trackElement.element, 0)) + if (newCoords == std::nullopt) { break; } + trackElement.x = newCoords->x; + trackElement.y = newCoords->y; + z = newCoords->z; if (track_elements.size() > TD6MaxTrackElements) {