diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index b4c2912241..2b41fbaa98 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -208,7 +208,6 @@ C666EE181F33E3800061AA04 /* EditorMain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C666ED851F33E3520061AA04 /* EditorMain.cpp */; }; C666EE1A1F33E3800061AA04 /* EditorObjectSelection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C666ED871F33E3520061AA04 /* EditorObjectSelection.cpp */; }; C666EE1F1F33E3800061AA04 /* GameBottomToolbar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C666ED8C1F33E3520061AA04 /* GameBottomToolbar.cpp */; }; - C666EE391F33E3800061AA04 /* RideConstruction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C666EDA61F33E3520061AA04 /* RideConstruction.cpp */; }; C666EE3C1F33E3800061AA04 /* Scenery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C666EDA91F33E3520061AA04 /* Scenery.cpp */; }; C666EE451F33E3800061AA04 /* TileInspector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C666EDB21F33E3520061AA04 /* TileInspector.cpp */; }; C666EE4D1F33E3800061AA04 /* Tooltip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C666EDBA1F33E3520061AA04 /* Tooltip.cpp */; }; @@ -245,6 +244,7 @@ C6D2BEE71F9BAACE008B557C /* MapTooltip.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C6D2BEE41F9BAACD008B557C /* MapTooltip.cpp */; }; C6D2BEE81F9BAACE008B557C /* MazeConstruction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C6D2BEE51F9BAACD008B557C /* MazeConstruction.cpp */; }; C6D2BEEA1F9BB83C008B557C /* NetworkStatus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C6D2BEE91F9BB83B008B557C /* NetworkStatus.cpp */; }; + C6E415511FAFD6DC00D4A52A /* RideConstruction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C6E415501FAFD6DB00D4A52A /* RideConstruction.cpp */; }; C6E96E361E0408B40076A04F /* libzip.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C6E96E351E0408B40076A04F /* libzip.dylib */; }; C6E96E371E040E040076A04F /* libzip.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C6E96E351E0408B40076A04F /* libzip.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; D41B73EF1C2101890080A7B9 /* libcurl.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D41B73EE1C2101890080A7B9 /* libcurl.tbd */; }; @@ -821,7 +821,6 @@ C666ED851F33E3520061AA04 /* EditorMain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EditorMain.cpp; sourceTree = ""; }; C666ED871F33E3520061AA04 /* EditorObjectSelection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EditorObjectSelection.cpp; sourceTree = ""; }; C666ED8C1F33E3520061AA04 /* GameBottomToolbar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GameBottomToolbar.cpp; sourceTree = ""; }; - C666EDA61F33E3520061AA04 /* RideConstruction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RideConstruction.cpp; sourceTree = ""; }; C666EDA91F33E3520061AA04 /* Scenery.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Scenery.cpp; sourceTree = ""; }; C666EDB21F33E3520061AA04 /* TileInspector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TileInspector.cpp; sourceTree = ""; }; C666EDBA1F33E3520061AA04 /* Tooltip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Tooltip.cpp; sourceTree = ""; }; @@ -873,6 +872,7 @@ C6D2BEE41F9BAACD008B557C /* MapTooltip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MapTooltip.cpp; sourceTree = ""; }; C6D2BEE51F9BAACD008B557C /* MazeConstruction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MazeConstruction.cpp; sourceTree = ""; }; C6D2BEE91F9BB83B008B557C /* NetworkStatus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkStatus.cpp; sourceTree = ""; }; + C6E415501FAFD6DB00D4A52A /* RideConstruction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RideConstruction.cpp; sourceTree = ""; }; C6E96E331E0408A80076A04F /* zip.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = zip.h; sourceTree = ""; }; C6E96E341E0408A80076A04F /* zipconf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = zipconf.h; sourceTree = ""; }; C6E96E351E0408B40076A04F /* libzip.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libzip.dylib; sourceTree = ""; }; @@ -2525,7 +2525,6 @@ C666ED8C1F33E3520061AA04 /* GameBottomToolbar.cpp */, C654DF3E1F69C18C0040F43D /* Intent.cpp */, C654DF3F1F69C18C0040F43D /* Intent.h */, - C666EDA61F33E3520061AA04 /* RideConstruction.cpp */, C666EDA91F33E3520061AA04 /* Scenery.cpp */, F76C854A1EC4E7CD00FA49E2 /* tile_inspector.h */, C666EDB21F33E3520061AA04 /* TileInspector.cpp */, @@ -2717,6 +2716,7 @@ C654DF251F69C0430040F43D /* Player.cpp */, C685E5181F8907840090598F /* Research.cpp */, C6D2BEE11F9BAA6C008B557C /* Ride.cpp */, + C6E415501FAFD6DB00D4A52A /* RideConstruction.cpp */, C632C81E1F8A445700781F6D /* RideList.cpp */, C666EE611F37ACB10061AA04 /* SavePrompt.cpp */, C666EE621F37ACB10061AA04 /* ServerList.cpp */, @@ -3192,6 +3192,7 @@ 4C93F1501F8B744400A9330D /* SideFrictionRollerCoaster.cpp in Sources */, 4C93F13D1F8B744400A9330D /* CompactInvertedCoaster.cpp in Sources */, 4C93F1581F8B744400A9330D /* WoodenRollerCoaster.cpp in Sources */, + C6E415511FAFD6DC00D4A52A /* RideConstruction.cpp in Sources */, C685E51B1F8907850090598F /* Guest.cpp in Sources */, C64644F91F3FA4120026AC2D /* EditorInventionsList.cpp in Sources */, C6D2BEE61F9BAACE008B557C /* TrackList.cpp in Sources */, @@ -3484,7 +3485,6 @@ F76C871C1EC4E88400FA49E2 /* TrackDesignRepository.cpp in Sources */, F76C87251EC4E88400FA49E2 /* vehicle_data.c in Sources */, F76C87271EC4E88400FA49E2 /* vehicle_paint.c in Sources */, - C666EE391F33E3800061AA04 /* RideConstruction.cpp in Sources */, F76C87311EC4E88400FA49E2 /* scenario.c in Sources */, F76C87331EC4E88400FA49E2 /* ScenarioRepository.cpp in Sources */, F76C87351EC4E88400FA49E2 /* ScenarioSources.cpp in Sources */, diff --git a/src/openrct2-ui/WindowManager.cpp b/src/openrct2-ui/WindowManager.cpp index 4c14862939..e41bdd414a 100644 --- a/src/openrct2-ui/WindowManager.cpp +++ b/src/openrct2-ui/WindowManager.cpp @@ -81,6 +81,8 @@ public: return window_park_entrance_open(); case WC_RECENT_NEWS: return window_news_open(); + case WC_RIDE_CONSTRUCTION: + return window_ride_construction_open(); case WC_RESEARCH: return window_research_open(); case WC_RIDE_LIST: @@ -281,6 +283,14 @@ public: case INTENT_ACTION_UPDATE_MAZE_CONSTRUCTION: window_maze_construction_update_pressed_widgets(); break; + + case INTENT_ACTION_RIDE_CONSTRUCTION_UPDATE_PIECES: + window_ride_construction_update_enabled_track_pieces(); + break; + + case INTENT_ACTION_RIDE_CONSTRUCTION_UPDATE_ACTIVE_ELEMENTS: + window_ride_construction_update_active_elements_impl(); + break; } } diff --git a/src/openrct2/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp similarity index 90% rename from src/openrct2/windows/RideConstruction.cpp rename to src/openrct2-ui/windows/RideConstruction.cpp index 3ad4ce9cbc..56a592e7e8 100644 --- a/src/openrct2/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -14,28 +14,29 @@ *****************************************************************************/ #pragma endregion -#include "../config/Config.h" -#include "../Context.h" -#include "../network/network.h" -#include "../ride/RideGroupManager.h" -#include "../core/Math.hpp" -#include "../core/Util.hpp" +#include -#include "../audio/audio.h" -#include "../cheats.h" -#include "../game.h" -#include "../input.h" -#include "../interface/viewport.h" -#include "../interface/widget.h" -#include "../localisation/localisation.h" -#include "../ride/ride_data.h" -#include "../ride/Track.h" -#include "../ride/TrackData.h" -#include "../world/footpath.h" -#include "dropdown.h" -#include "../sprites.h" -#include "../world/entrance.h" -#include "Intent.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #pragma region Widgets @@ -442,7 +443,6 @@ static const rct_string_id RideConfigurationStringIds[] = { #pragma endregion -static uint64 _enabledRidePieces; static bool _trackPlaceCtrlState; static sint32 _trackPlaceCtrlZ; static bool _trackPlaceShiftState; @@ -452,17 +452,11 @@ static sint32 _trackPlaceShiftZ; static sint32 _trackPlaceZ; static money32 _trackPlaceCost; static bool _autoOpeningShop; -static uint8 _rideConstructionState2; static uint8 _currentlyShowingBrakeOrBoosterSpeed; static bool _boosterTrackSelected; static uint32 _currentDisabledSpecialTrackPieces; -// This variable is updated separately from ride->num_stations because the latter -// is unreliable if currently in station construction mode -static bool _stationConstructed; -static bool _deferClose; - static void window_ride_construction_construct(rct_window *w); static void window_ride_construction_mouseup_demolish(rct_window* w); static void window_ride_construction_rotate(rct_window *w); @@ -474,8 +468,6 @@ static void window_ride_construction_draw_track_piece( sint32 rideIndex, sint32 trackType, sint32 trackDirection, sint32 unknown, sint32 width, sint32 height ); -static void window_ride_construction_update_enabled_track_pieces(); -static bool _sub_6CA2DF(sint32 *trackType, sint32 *trackDirection, sint32 *rideIndex, sint32 *_liftHillAndAlternativeState, sint32 *x, sint32 *y, sint32 *z, sint32 *properties); static void sub_6CBCE2( rct_drawpixelinfo * dpi, sint32 rideIndex, sint32 trackType, sint32 trackDirection, sint32 edx, @@ -485,7 +477,6 @@ static void window_ride_construction_update_map_selection(); static void window_ride_construction_update_possible_ride_configurations(); static void window_ride_construction_update_widgets(rct_window *w); static void window_ride_construction_select_map_tiles(Ride *ride, sint32 trackType, sint32 trackDirection, sint32 x, sint32 y); -static money32 _place_provisional_track_piece(sint32 rideIndex, sint32 trackType, sint32 trackDirection, sint32 liftHillAndAlternativeState, sint32 x, sint32 y, sint32 z); static void window_ride_construction_show_special_track_dropdown(rct_window *w, rct_widget *widget); static void ride_selected_track_set_seat_rotation(sint32 seatRotation); static void loc_6C7502(sint32 al); @@ -656,14 +647,14 @@ static void window_ride_construction_close(rct_window *w) return; } - if (ride_try_get_origin_element(rideIndex, nullptr)) + if (ride_try_get_origin_element(rideIndex, nullptr)) { // Auto open shops if required. - if (ride->mode == RIDE_MODE_SHOP_STALL && gConfigGeneral.auto_open_shops) + if (ride->mode == RIDE_MODE_SHOP_STALL && gConfigGeneral.auto_open_shops) { // HACK: Until we find a good a way to defer the game command for opening the shop, stop this // from getting stuck in an infinite loop as opening the ride will try to close this window - if (!_autoOpeningShop) + if (!_autoOpeningShop) { _autoOpeningShop = true; ride_set_status(rideIndex, RIDE_STATUS_OPEN); @@ -676,7 +667,7 @@ static void window_ride_construction_close(rct_window *w) intent.putExtra(INTENT_EXTRA_RIDE_ID, rideIndex); context_open_intent(&intent); } - else + else { sint32 previousPauseState = gGamePaused; gGamePaused = 0; @@ -1237,12 +1228,12 @@ static void window_ride_construction_resize(rct_window *w) } if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_FRONT) { disabledWidgets |= (1ULL << WIDX_NEXT_SECTION); - if (_sub_6CA2DF(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)) { + if (sub_6CA2DF(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)) { disabledWidgets |= (1ULL << WIDX_CONSTRUCT); } } else if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK) { disabledWidgets |= (1ULL << WIDX_PREVIOUS_SECTION); - if (_sub_6CA2DF(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)) { + if (sub_6CA2DF(nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)) { disabledWidgets |= (1ULL << WIDX_CONSTRUCT); } } @@ -1658,7 +1649,7 @@ static void window_ride_construction_construct(rct_window *w) _currentTrackPrice = MONEY32_UNDEFINED; _trackPlaceCost = MONEY32_UNDEFINED; ride_construction_invalidate_current_track(); - if (_sub_6CA2DF(&trackType, &trackDirection, &rideIndex, &liftHillAndAlternativeState, &x, &y, &z, &properties)) { + if (sub_6CA2DF(&trackType, &trackDirection, &rideIndex, &liftHillAndAlternativeState, &x, &y, &z, &properties)) { window_ride_construction_update_active_elements(); return; } @@ -1867,74 +1858,6 @@ static void window_ride_construction_mouseup_demolish(rct_window* w) } } -void window_ride_construction_mouseup_demolish_next_piece(sint32 x, sint32 y, sint32 z, sint32 direction, sint32 type) -{ - if (gGotoStartPlacementMode) { - z &= 0xFFF0; - _currentTrackBeginZ = z; - _rideConstructionState = RIDE_CONSTRUCTION_STATE_FRONT; - _currentTrackSelectionFlags = 0; - _rideConstructionArrowPulseTime = 0; - direction = _currentTrackPieceDirection; - sint32 slope = _currentTrackCurve; - sint32 slopeEnd = _previousTrackSlopeEnd; - sint32 b2 = _currentTrackSlopeEnd; - sint32 bankEnd = _previousTrackBankEnd; - sint32 bankStart = _currentTrackBankEnd; - sint32 b5 = _currentTrackAlternative; - sint32 b4 = _currentTrackLiftHill; - ride_construction_set_default_next_piece(); - window_ride_construction_update_active_elements(); - if (!ride_try_get_origin_element(_currentRideIndex, nullptr)) { - ride_initialise_construction_window(_currentRideIndex); - _currentTrackPieceDirection = direction; - if (!(slope & 0x100)) { - _currentTrackCurve = slope; - _previousTrackSlopeEnd = slopeEnd; - _currentTrackSlopeEnd = b2; - _previousTrackBankEnd = bankEnd; - _currentTrackBankEnd = bankStart; - _currentTrackAlternative = b5; - _currentTrackLiftHill = b4; - window_ride_construction_update_active_elements(); - } - } - } - else { - if (_rideConstructionState2 == RIDE_CONSTRUCTION_STATE_SELECTED || - _rideConstructionState2 == RIDE_CONSTRUCTION_STATE_FRONT - ) { - if (type == TRACK_ELEM_MIDDLE_STATION || type == TRACK_ELEM_BEGIN_STATION) { - type = TRACK_ELEM_END_STATION; - } - } - if (_rideConstructionState2 == RIDE_CONSTRUCTION_STATE_BACK) { - if (type == TRACK_ELEM_MIDDLE_STATION) { - type = TRACK_ELEM_BEGIN_STATION; - } - } - if (network_get_mode() == NETWORK_MODE_CLIENT) - { - // rideConstructionState needs to be set again to the proper value, this only affects the client - _rideConstructionState = RIDE_CONSTRUCTION_STATE_SELECTED; - } - _currentTrackBeginX = x; - _currentTrackBeginY = y; - _currentTrackBeginZ = z; - _currentTrackPieceDirection = direction; - _currentTrackPieceType = type; - _currentTrackSelectionFlags = 0; - _rideConstructionArrowPulseTime = 0; - if (_rideConstructionState2 == RIDE_CONSTRUCTION_STATE_FRONT) { - ride_select_next_section(); - } - else if (_rideConstructionState2 == RIDE_CONSTRUCTION_STATE_BACK) { - ride_select_previous_section(); - } - window_ride_construction_update_active_elements(); - } -} - /** * * rct2: 0x006C78AA @@ -2210,7 +2133,7 @@ static void window_ride_construction_paint(rct_window *w, rct_drawpixelinfo *dpi return; sint32 trackType, trackDirection, rideIndex, liftHillAndAlternativeState; - if (_sub_6CA2DF(&trackType, &trackDirection, &rideIndex, &liftHillAndAlternativeState, nullptr, nullptr, nullptr, nullptr)) + if (sub_6CA2DF(&trackType, &trackDirection, &rideIndex, &liftHillAndAlternativeState, nullptr, nullptr, nullptr, nullptr)) return; // Draw track piece @@ -2443,7 +2366,7 @@ static void sub_6CBCE2( * * rct2: 0x006C84CE */ -void window_ride_construction_update_active_elements() +void window_ride_construction_update_active_elements_impl() { rct_window *w; rct_tile_element *tileElement; @@ -2472,244 +2395,11 @@ void window_ride_construction_update_active_elements() window_ride_construction_update_widgets(w); } -static bool sub_6CA2DF_get_track_element(uint8 *trackElement) { - window_ride_construction_update_enabled_track_pieces(); - - uint8 startSlope = _previousTrackSlopeEnd; - uint8 endSlope = _currentTrackSlopeEnd; - uint8 startBank = _previousTrackBankEnd; - uint8 endBank = _currentTrackBankEnd; - - if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK) { - startSlope = _currentTrackSlopeEnd; - endSlope = _previousTrackSlopeEnd; - startBank = _currentTrackBankEnd; - endBank = _previousTrackBankEnd; - } - - uint16 curve = _currentTrackCurve; - if (curve == 0xFFFF) { - return false; - } - - bool startsDiagonal = (_currentTrackPieceDirection & (1 << 2)) != 0; - if (curve == TRACK_CURVE_LEFT_LARGE || curve == TRACK_CURVE_RIGHT_LARGE) { - if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK) { - startsDiagonal = !startsDiagonal; - } - } - - if (curve <= 8) { - for (auto trackDescriptor : gTrackDescriptors) { - if (trackDescriptor.track_curve != curve) continue; - if (trackDescriptor.starts_diagonal != startsDiagonal) continue; - if (trackDescriptor.slope_start != startSlope) continue; - if (trackDescriptor.slope_end != endSlope) continue; - if (trackDescriptor.bank_start != startBank) continue; - if (trackDescriptor.bank_end != endBank) continue; - - *trackElement = trackDescriptor.track_element; - return true; - } - - return false; - } - - *trackElement = curve & 0xFF; - switch (*trackElement) { - case TRACK_ELEM_END_STATION: - case TRACK_ELEM_S_BEND_LEFT: - case TRACK_ELEM_S_BEND_RIGHT: - if (startSlope != TRACK_SLOPE_NONE || endSlope != TRACK_SLOPE_NONE) { - return false; - } - - if (startBank != TRACK_BANK_NONE || endBank != TRACK_BANK_NONE) { - return false; - } - - return true; - - case TRACK_ELEM_LEFT_VERTICAL_LOOP: - case TRACK_ELEM_RIGHT_VERTICAL_LOOP: - if (startBank != TRACK_BANK_NONE || endBank != TRACK_BANK_NONE) { - return false; - } - - if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK) { - if (endSlope != TRACK_SLOPE_DOWN_25) { - return false; - } - } else { - if (startSlope != TRACK_SLOPE_UP_25) { - return false; - } - } - - return true; - - default: - return true; - } -} - -/** - * rct2: 0x006CA2DF - * - * @param[out] _trackType (dh) - * @param[out] _trackDirection (bh) - * @param[out] _rideIndex (dl) - * @param[out] _liftHillAndAlternativeState (liftHillAndAlternativeState) - * @param[out] _x (ax) - * @param[out] _y (cx) - * @param[out] _z (di) - * @param[out] _properties (edirs16) - * @return (CF) - */ -bool _sub_6CA2DF(sint32 *_trackType, sint32 *_trackDirection, sint32 *_rideIndex, sint32 *_liftHillAndAlternativeState, sint32 *_x, sint32 *_y, sint32 *_z, sint32 *_properties) { - uint8 trackType, trackDirection, rideIndex; - uint16 z, x, y, liftHillAndAlternativeState, properties; - - if (!sub_6CA2DF_get_track_element(&trackType)) { - return true; - } - - liftHillAndAlternativeState = 0; - rideIndex = _currentRideIndex; - if (_currentTrackLiftHill & CONSTRUCTION_LIFT_HILL_SELECTED) { - liftHillAndAlternativeState |= CONSTRUCTION_LIFT_HILL_SELECTED; - } - - if (_currentTrackAlternative & RIDE_TYPE_ALTERNATIVE_TRACK_TYPE) { - liftHillAndAlternativeState |= RIDE_TYPE_ALTERNATIVE_TRACK_TYPE; - } - - Ride *ride = get_ride(rideIndex); - - if (_enabledRidePieces & (1ULL << TRACK_SLOPE_STEEP_LONG)) { - switch (trackType) { - case TRACK_ELEM_FLAT_TO_60_DEG_UP: - trackType = TRACK_ELEM_FLAT_TO_60_DEG_UP_LONG_BASE; - break; - - case TRACK_ELEM_60_DEG_UP_TO_FLAT: - trackType = TRACK_ELEM_60_DEG_UP_TO_FLAT_LONG_BASE; - break; - - case TRACK_ELEM_FLAT_TO_60_DEG_DOWN: - trackType = TRACK_ELEM_60_DEG_UP_TO_FLAT_LONG_BASE_122; - break; - - case TRACK_ELEM_60_DEG_DOWN_TO_FLAT: - trackType = TRACK_ELEM_FLAT_TO_60_DEG_DOWN_LONG_BASE; - break; - - case TRACK_ELEM_DIAG_FLAT_TO_60_DEG_UP: - case TRACK_ELEM_DIAG_60_DEG_UP_TO_FLAT: - case TRACK_ELEM_DIAG_FLAT_TO_60_DEG_DOWN: - case TRACK_ELEM_DIAG_60_DEG_DOWN_TO_FLAT: - return true; - } - } - - if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_TRACK_ELEMENTS_HAVE_TWO_VARIETIES) && _currentTrackAlternative & RIDE_TYPE_ALTERNATIVE_TRACK_PIECES) { - if (ride->type != RIDE_TYPE_WATER_COASTER || trackType == TRACK_ELEM_FLAT || trackType == TRACK_ELEM_LEFT_QUARTER_TURN_5_TILES || trackType == TRACK_ELEM_RIGHT_QUARTER_TURN_5_TILES) { - sint16 alternativeType = AlternativeTrackTypes[trackType]; - if (alternativeType > -1) { - trackType = (uint8) alternativeType; - } - liftHillAndAlternativeState &= ~CONSTRUCTION_LIFT_HILL_SELECTED; - } - } - - const rct_track_coordinates *trackCoordinates = get_track_coord_from_ride(ride, trackType); - - x = _currentTrackBeginX; - y = _currentTrackBeginY; - z = _currentTrackBeginZ; - if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK) { - z -= trackCoordinates->z_end; - trackDirection = _currentTrackPieceDirection ^ 0x02; - trackDirection -= trackCoordinates->rotation_end; - trackDirection += trackCoordinates->rotation_begin; - trackDirection &= 0x03; - - if (trackCoordinates->rotation_begin & (1 << 2)) { - trackDirection |= 0x04; - } - - switch (trackDirection & 0x03) { - case 0: - x -= trackCoordinates->x; - y -= trackCoordinates->y; - break; - - case 1: - x -= trackCoordinates->y; - y += trackCoordinates->x; - break; - - case 2: - x += trackCoordinates->x; - y += trackCoordinates->y; - break; - - case 3: - x += trackCoordinates->y; - y -= trackCoordinates->x; - break; - } - } else { - z -= trackCoordinates->z_begin; - trackDirection = _currentTrackPieceDirection; - } - - - bool turnOffLiftHill = false; - if (!(_enabledRidePieces & (1ULL << TRACK_LIFT_HILL_CURVE))) { - if (TrackFlags[trackType] & TRACK_ELEM_FLAG_CURVE_ALLOWS_LIFT) { - turnOffLiftHill = true; - } - } - - if (!(TrackFlags[trackType] & TRACK_ELEM_FLAG_ALLOW_LIFT_HILL)) { - turnOffLiftHill = true; - } - - if (turnOffLiftHill && !gCheatsEnableChainLiftOnAllTrack) { - liftHillAndAlternativeState &= ~CONSTRUCTION_LIFT_HILL_SELECTED; - _currentTrackLiftHill &= ~CONSTRUCTION_LIFT_HILL_SELECTED; - - if (trackType == TRACK_ELEM_LEFT_CURVED_LIFT_HILL || trackType == TRACK_ELEM_RIGHT_CURVED_LIFT_HILL) { - liftHillAndAlternativeState |= CONSTRUCTION_LIFT_HILL_SELECTED; - } - } - - - if (track_element_has_speed_setting(trackType)) { - properties = _currentBrakeSpeed2; - } else { - properties = _currentSeatRotationAngle << 12; - } - - - if (_trackType != nullptr) *_trackType = trackType; - if (_trackDirection != nullptr) *_trackDirection = trackDirection; - if (_rideIndex != nullptr) *_rideIndex = rideIndex; - if (_liftHillAndAlternativeState != nullptr) *_liftHillAndAlternativeState = liftHillAndAlternativeState; - if (_x != nullptr) *_x = x; - if (_y != nullptr) *_y = y; - if (_z != nullptr) *_z = z; - if (_properties != nullptr) *_properties = properties; - - return false; -} - /** * * rct2: 0x006C6A77 */ -static void window_ride_construction_update_enabled_track_pieces() +void window_ride_construction_update_enabled_track_pieces() { Ride *ride = get_ride(_currentRideIndex); rct_ride_entry *rideEntry = get_ride_entry_by_ride(ride); @@ -2744,54 +2434,6 @@ static void window_ride_construction_update_enabled_track_pieces() } -/** - * - * rct2: 0x006CA162 - */ -money32 _place_provisional_track_piece(sint32 rideIndex, sint32 trackType, sint32 trackDirection, sint32 liftHillAndAlternativeState, sint32 x, sint32 y, sint32 z) -{ - Ride *ride; - money32 result; - - ride_construction_remove_ghosts(); - ride = get_ride(rideIndex); - if (ride->type == RIDE_TYPE_MAZE) { - result = game_do_command(x, 105 | (4 << 8), y, rideIndex | (trackType << 8) | (liftHillAndAlternativeState << 16), GAME_COMMAND_SET_MAZE_TRACK, z, 0); - if (result == MONEY32_UNDEFINED) - return result; - - _unkF440C5.x = x; - _unkF440C5.y = y; - _unkF440C5.z = z; - _unkF440C5.direction = trackDirection; - _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_TRACK; - viewport_set_visibility((gTrackGroundFlags & TRACK_ELEMENT_LOCATION_IS_UNDERGROUND) ? 1 : 3); - if (_currentTrackSlopeEnd != 0) - viewport_set_visibility(2); - - return result; - } else { - result = game_do_command(x, 105 | (trackDirection << 8), y, rideIndex | (trackType << 8) | (liftHillAndAlternativeState << 16), GAME_COMMAND_PLACE_TRACK, z, 0); - if (result == MONEY32_UNDEFINED) - return result; - - _unkF440C5.x = x; - _unkF440C5.y = y; - z += ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_FLAT_RIDE) ? - FlatTrackCoordinates[trackType].z_begin: - TrackCoordinates[trackType].z_begin; - - _unkF440C5.z = z; - _unkF440C5.direction = trackDirection; - _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_TRACK; - viewport_set_visibility((gTrackGroundFlags & TRACK_ELEMENT_LOCATION_IS_UNDERGROUND) ? 1 : 3); - if (_currentTrackSlopeEnd != 0) - viewport_set_visibility(2); - - return result; - } -} - /** * * rct2: 0x006C94D8 @@ -2811,10 +2453,10 @@ void sub_6C94D8() case RIDE_CONSTRUCTION_STATE_FRONT: case RIDE_CONSTRUCTION_STATE_BACK: if (!(_currentTrackSelectionFlags & TRACK_SELECTION_FLAG_TRACK)) { - if (_sub_6CA2DF(&type, &direction, &rideIndex, &liftHillAndAlternativeState, &x, &y, &z, nullptr)) { + if (sub_6CA2DF(&type, &direction, &rideIndex, &liftHillAndAlternativeState, &x, &y, &z, nullptr)) { ride_construction_remove_ghosts(); } else { - _currentTrackPrice = _place_provisional_track_piece(rideIndex, type, direction, liftHillAndAlternativeState, x, y, z); + _currentTrackPrice = place_provisional_track_piece(rideIndex, type, direction, liftHillAndAlternativeState, x, y, z); window_ride_construction_update_active_elements(); } } @@ -2918,7 +2560,7 @@ static void window_ride_construction_update_map_selection() y = _currentTrackBeginY; break; default: - if (_sub_6CA2DF(&trackType, &trackDirection, nullptr, nullptr, &x, &y, nullptr, nullptr)) { + if (sub_6CA2DF(&trackType, &trackDirection, nullptr, nullptr, &x, &y, nullptr, nullptr)) { trackDirection = _currentTrackPieceDirection; trackType = 0; x = _currentTrackBeginX; @@ -3680,7 +3322,7 @@ void ride_construction_toolupdate_construct(sint32 screenX, sint32 screenY) gMapSelectionTiles[1].y = -1; sint32 trackType, trackDirection, rideIndex, liftHillAndAlternativeState; - if (_sub_6CA2DF(&trackType, &trackDirection, &rideIndex, &liftHillAndAlternativeState, nullptr, nullptr, nullptr, nullptr)) { + if (sub_6CA2DF(&trackType, &trackDirection, &rideIndex, &liftHillAndAlternativeState, nullptr, nullptr, nullptr, nullptr)) { ride_construction_invalidate_current_track(); map_invalidate_map_selection_tiles(); return; @@ -3740,8 +3382,8 @@ void ride_construction_toolupdate_construct(sint32 screenX, sint32 screenY) _previousTrackPieceZ = z; if (ride->type == RIDE_TYPE_MAZE) { for (;;) { - _sub_6CA2DF(&trackType, &trackDirection, &rideIndex, &liftHillAndAlternativeState, &x, &y, &z, nullptr); - _currentTrackPrice = _place_provisional_track_piece(rideIndex, trackType, trackDirection, liftHillAndAlternativeState, x, y, z); + sub_6CA2DF(&trackType, &trackDirection, &rideIndex, &liftHillAndAlternativeState, &x, &y, &z, nullptr); + _currentTrackPrice = place_provisional_track_piece(rideIndex, trackType, trackDirection, liftHillAndAlternativeState, x, y, z); if (_currentTrackPrice != MONEY32_UNDEFINED) break; @@ -3764,8 +3406,8 @@ void ride_construction_toolupdate_construct(sint32 screenX, sint32 screenY) } for (;;) { - _sub_6CA2DF(&trackType, &trackDirection, &rideIndex, &liftHillAndAlternativeState, &x, &y, &z, nullptr); - _currentTrackPrice = _place_provisional_track_piece(rideIndex, trackType, trackDirection, liftHillAndAlternativeState, x, y, z); + sub_6CA2DF(&trackType, &trackDirection, &rideIndex, &liftHillAndAlternativeState, &x, &y, &z, nullptr); + _currentTrackPrice = place_provisional_track_piece(rideIndex, trackType, trackDirection, liftHillAndAlternativeState, x, y, z); if (_currentTrackPrice != MONEY32_UNDEFINED) break; @@ -3846,7 +3488,7 @@ void ride_construction_tooldown_construct(sint32 screenX, sint32 screenY) map_invalidate_map_selection_tiles(); ride_construction_invalidate_current_track(); - if (_sub_6CA2DF(&trackType, &trackDirection, &rideIndex, &liftHillAndAlternativeState, &x, &y, &z, &properties)) + if (sub_6CA2DF(&trackType, &trackDirection, &rideIndex, &liftHillAndAlternativeState, &x, &y, &z, &properties)) return; _currentTrackPieceType = trackType; @@ -4068,57 +3710,6 @@ static void ride_construction_tooldown_entrance_exit(sint32 screenX, sint32 scre ); } -void game_command_callback_place_ride_entrance_or_exit(sint32 eax, sint32 ebx, sint32 ecx, sint32 edx, sint32 esi, sint32 edi, sint32 ebp) -{ - audio_play_sound_at_location( - SOUND_PLACE_ITEM, - gCommandPosition.x, - gCommandPosition.y, - gCommandPosition.z - ); - - Ride *ride = get_ride(gRideEntranceExitPlaceRideIndex); - if (ride_are_all_possible_entrances_and_exits_built(ride)) { - tool_cancel(); - if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_NO_TRACK)) { - window_close_by_class(WC_RIDE_CONSTRUCTION); - } - } else { - gRideEntranceExitPlaceType ^= 1; - gCurrentToolWidget.widget_index = (gRideEntranceExitPlaceType == ENTRANCE_TYPE_RIDE_ENTRANCE) ? - WIDX_ENTRANCE : WIDX_EXIT; - } -} - -void window_ride_construction_do_station_check() -{ - Ride *ride = get_ride(_currentRideIndex); - if (ride != nullptr) { - _stationConstructed = ride->num_stations != 0; - } -} - -void window_ride_construction_do_entrance_exit_check() -{ - rct_window *w = window_find_by_class(WC_RIDE_CONSTRUCTION); - Ride *ride = get_ride(_currentRideIndex); - - if (w == nullptr || ride == nullptr) { - return; - } - - if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_0) { - w = window_find_by_class(WC_RIDE_CONSTRUCTION); - if (w != nullptr) { - if (!ride_are_all_possible_entrances_and_exits_built(ride)) { - window_event_mouse_up_call(w, WIDX_ENTRANCE); - } else { - _deferClose = true; - } - } - } -} - void window_ride_construction_keyboard_shortcut_turn_left() { rct_window *w = window_find_by_class(WC_RIDE_CONSTRUCTION); @@ -4594,18 +4185,3 @@ void window_ride_construction_keyboard_shortcut_demolish_current() window_event_mouse_up_call(w, WIDX_DEMOLISH); } - -extern "C" -{ - money32 place_provisional_track_piece(sint32 rideIndex, sint32 trackType, sint32 trackDirection, - sint32 liftHillAndAlternativeState, sint32 x, sint32 y, sint32 z) - { - return _place_provisional_track_piece(rideIndex, trackType, trackDirection, liftHillAndAlternativeState, x, y, z); - } - - bool sub_6CA2DF(sint32 *trackType, sint32 *trackDirection, sint32 *rideIndex, sint32 *_liftHillAndAlternativeState, - sint32 *x, sint32 *y, sint32 *z, sint32 *properties) - { - return _sub_6CA2DF(trackType, trackDirection, rideIndex, _liftHillAndAlternativeState, x, y, z, properties); - } -} diff --git a/src/openrct2-ui/windows/Window.h b/src/openrct2-ui/windows/Window.h index ca958cdc79..1512f59e77 100644 --- a/src/openrct2-ui/windows/Window.h +++ b/src/openrct2-ui/windows/Window.h @@ -131,3 +131,8 @@ void window_text_input_open(rct_window * call_w, rct_widgetindex call_widget, rc void window_text_input_raw_open(rct_window * call_w, rct_widgetindex call_widget, rct_string_id title, rct_string_id description, utf8string existing_text, sint32 maxLength); rct_window * window_object_load_error_open(utf8 * path, size_t numMissingObjects, const rct_object_entry * missingObjects); + +rct_window * window_ride_construction_open(); +void window_ride_construction_update_active_elements_impl(); +void window_ride_construction_update_enabled_track_pieces(); + diff --git a/src/openrct2/interface/window.h b/src/openrct2/interface/window.h index 3353bc85cf..974bda085f 100644 --- a/src/openrct2/interface/window.h +++ b/src/openrct2/interface/window.h @@ -717,7 +717,6 @@ void window_top_toolbar_open(); void window_game_bottom_toolbar_open(); void window_game_bottom_toolbar_invalidate_news_item(); void window_ride_construct(rct_window *w); -rct_window *window_ride_construction_open(); void ride_construction_toolupdate_entrance_exit(sint32 screenX, sint32 screenY); void ride_construction_toolupdate_construct(sint32 screenX, sint32 screenY); void ride_construction_tooldown_construct(sint32 screenX, sint32 screenY); @@ -805,6 +804,10 @@ void window_ride_construction_keyboard_shortcut_demolish_current(); bool sub_6CA2DF(sint32 *trackType, sint32 *trackDirection, sint32 *rideIndex, sint32 *_liftHillAndAlternativeState, sint32 *x, sint32 *y, sint32 *z, sint32 *properties); money32 place_provisional_track_piece(sint32 rideIndex, sint32 trackType, sint32 trackDirection, sint32 liftHillAndAlternativeState, sint32 x, sint32 y, sint32 z); +extern uint64 _enabledRidePieces; +extern uint8 _rideConstructionState2; +extern bool _stationConstructed; +extern bool _deferClose; #ifdef __cplusplus } diff --git a/src/openrct2/ride/ride.c b/src/openrct2/ride/ride.c index 9c38eb8e06..8d617cd096 100644 --- a/src/openrct2/ride/ride.c +++ b/src/openrct2/ride/ride.c @@ -1006,7 +1006,7 @@ static rct_window *ride_create_or_find_construction_window(sint32 rideIndex) if (w == NULL || w->number != rideIndex) { window_close_construction_windows(); _currentRideIndex = rideIndex; - w = window_ride_construction_open(); + w = context_open_window(WC_RIDE_CONSTRUCTION); } else { ride_construction_invalidate_current_track(); _currentRideIndex = rideIndex; diff --git a/src/openrct2/windows/Intent.h b/src/openrct2/windows/Intent.h index 29cfaab506..50263bb987 100644 --- a/src/openrct2/windows/Intent.h +++ b/src/openrct2/windows/Intent.h @@ -76,6 +76,8 @@ extern "C" { INTENT_ACTION_REFRESH_NEW_RIDES, INTENT_ACTION_REFRESH_RIDE_LIST, INTENT_ACTION_UPDATE_MAZE_CONSTRUCTION, + INTENT_ACTION_RIDE_CONSTRUCTION_UPDATE_PIECES, + INTENT_ACTION_RIDE_CONSTRUCTION_UPDATE_ACTIVE_ELEMENTS, }; Intent *intent_create(rct_windowclass clss); diff --git a/src/openrct2/windows/_legacy.c b/src/openrct2/windows/_legacy.c index acbf24ef12..24a5b7ab53 100644 --- a/src/openrct2/windows/_legacy.c +++ b/src/openrct2/windows/_legacy.c @@ -19,6 +19,14 @@ #include "../peep/Staff.h" #include "Intent.h" #include "../Context.h" +#include "../audio/audio.h" +#include "../input.h" +#include "../game.h" +#include "../interface/viewport.h" +#include "../ride/Track.h" +#include "../ride/TrackData.h" +#include "../cheats.h" +#include "../network/network.h" #pragma warning(disable : 4295) // 'identifier': array is too small to include a terminating null character @@ -133,3 +141,427 @@ void game_command_callback_pickup_staff(sint32 eax, sint32 ebx, sint32 ecx, sint break; } } + +uint64 _enabledRidePieces; +uint8 _rideConstructionState2; + +// This variable is updated separately from ride->num_stations because the latter +// is unreliable if currently in station construction mode +bool _stationConstructed; +bool _deferClose; + +void game_command_callback_place_ride_entrance_or_exit(sint32 eax, sint32 ebx, sint32 ecx, sint32 edx, sint32 esi, sint32 edi, sint32 ebp) +{ + audio_play_sound_at_location( + SOUND_PLACE_ITEM, + gCommandPosition.x, + gCommandPosition.y, + gCommandPosition.z + ); + + Ride *ride = get_ride(gRideEntranceExitPlaceRideIndex); + if (ride_are_all_possible_entrances_and_exits_built(ride)) { + tool_cancel(); + if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_NO_TRACK)) { + window_close_by_class(WC_RIDE_CONSTRUCTION); + } + } else { + gRideEntranceExitPlaceType ^= 1; + gCurrentToolWidget.widget_index = (gRideEntranceExitPlaceType == ENTRANCE_TYPE_RIDE_ENTRANCE) ? + WC_RIDE_CONSTRUCTION__WIDX_ENTRANCE : WC_RIDE_CONSTRUCTION__WIDX_EXIT; + } +} + +/** + * + * rct2: 0x006CA162 + */ +money32 place_provisional_track_piece(sint32 rideIndex, sint32 trackType, sint32 trackDirection, sint32 liftHillAndAlternativeState, sint32 x, sint32 y, sint32 z) +{ + Ride *ride; + money32 result; + + ride_construction_remove_ghosts(); + ride = get_ride(rideIndex); + if (ride->type == RIDE_TYPE_MAZE) { + result = game_do_command(x, 105 | (4 << 8), y, rideIndex | (trackType << 8) | (liftHillAndAlternativeState << 16), GAME_COMMAND_SET_MAZE_TRACK, z, 0); + if (result == MONEY32_UNDEFINED) + return result; + + _unkF440C5.x = x; + _unkF440C5.y = y; + _unkF440C5.z = z; + _unkF440C5.direction = trackDirection; + _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_TRACK; + viewport_set_visibility((gTrackGroundFlags & TRACK_ELEMENT_LOCATION_IS_UNDERGROUND) ? 1 : 3); + if (_currentTrackSlopeEnd != 0) + viewport_set_visibility(2); + + return result; + } else { + result = game_do_command(x, 105 | (trackDirection << 8), y, rideIndex | (trackType << 8) | (liftHillAndAlternativeState << 16), GAME_COMMAND_PLACE_TRACK, z, 0); + if (result == MONEY32_UNDEFINED) + return result; + + _unkF440C5.x = x; + _unkF440C5.y = y; + z += ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_FLAT_RIDE) ? + FlatTrackCoordinates[trackType].z_begin: + TrackCoordinates[trackType].z_begin; + + _unkF440C5.z = z; + _unkF440C5.direction = trackDirection; + _currentTrackSelectionFlags |= TRACK_SELECTION_FLAG_TRACK; + viewport_set_visibility((gTrackGroundFlags & TRACK_ELEMENT_LOCATION_IS_UNDERGROUND) ? 1 : 3); + if (_currentTrackSlopeEnd != 0) + viewport_set_visibility(2); + + return result; + } +} + +static bool sub_6CA2DF_get_track_element(uint8 *trackElement) { + Intent * intent = intent_create(INTENT_ACTION_RIDE_CONSTRUCTION_UPDATE_PIECES); + context_broadcast_intent(intent); + intent_release(intent); + + uint8 startSlope = _previousTrackSlopeEnd; + uint8 endSlope = _currentTrackSlopeEnd; + uint8 startBank = _previousTrackBankEnd; + uint8 endBank = _currentTrackBankEnd; + + if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK) { + startSlope = _currentTrackSlopeEnd; + endSlope = _previousTrackSlopeEnd; + startBank = _currentTrackBankEnd; + endBank = _previousTrackBankEnd; + } + + uint16 curve = _currentTrackCurve; + if (curve == 0xFFFF) { + return false; + } + + bool startsDiagonal = (_currentTrackPieceDirection & (1 << 2)) != 0; + if (curve == TRACK_CURVE_LEFT_LARGE || curve == TRACK_CURVE_RIGHT_LARGE) { + if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK) { + startsDiagonal = !startsDiagonal; + } + } + + if (curve <= 8) { + for (int i = 0; i < countof(gTrackDescriptors); i++) + { + const track_descriptor * trackDescriptor = &gTrackDescriptors[i]; + + if (trackDescriptor->track_curve != curve) continue; + if (trackDescriptor->starts_diagonal != startsDiagonal) continue; + if (trackDescriptor->slope_start != startSlope) continue; + if (trackDescriptor->slope_end != endSlope) continue; + if (trackDescriptor->bank_start != startBank) continue; + if (trackDescriptor->bank_end != endBank) continue; + + *trackElement = trackDescriptor->track_element; + return true; + } + + return false; + } + + *trackElement = curve & 0xFF; + switch (*trackElement) { + case TRACK_ELEM_END_STATION: + case TRACK_ELEM_S_BEND_LEFT: + case TRACK_ELEM_S_BEND_RIGHT: + if (startSlope != TRACK_SLOPE_NONE || endSlope != TRACK_SLOPE_NONE) { + return false; + } + + if (startBank != TRACK_BANK_NONE || endBank != TRACK_BANK_NONE) { + return false; + } + + return true; + + case TRACK_ELEM_LEFT_VERTICAL_LOOP: + case TRACK_ELEM_RIGHT_VERTICAL_LOOP: + if (startBank != TRACK_BANK_NONE || endBank != TRACK_BANK_NONE) { + return false; + } + + if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK) { + if (endSlope != TRACK_SLOPE_DOWN_25) { + return false; + } + } else { + if (startSlope != TRACK_SLOPE_UP_25) { + return false; + } + } + + return true; + + default: + return true; + } +} + +/** + * rct2: 0x006CA2DF + * + * @param[out] _trackType (dh) + * @param[out] _trackDirection (bh) + * @param[out] _rideIndex (dl) + * @param[out] _liftHillAndAlternativeState (liftHillAndAlternativeState) + * @param[out] _x (ax) + * @param[out] _y (cx) + * @param[out] _z (di) + * @param[out] _properties (edirs16) + * @return (CF) + */ +bool sub_6CA2DF(sint32 *_trackType, sint32 *_trackDirection, sint32 *_rideIndex, sint32 *_liftHillAndAlternativeState, sint32 *_x, sint32 *_y, sint32 *_z, sint32 *_properties) { + uint8 trackType, trackDirection, rideIndex; + uint16 z, x, y, liftHillAndAlternativeState, properties; + + if (!sub_6CA2DF_get_track_element(&trackType)) { + return true; + } + + liftHillAndAlternativeState = 0; + rideIndex = _currentRideIndex; + if (_currentTrackLiftHill & CONSTRUCTION_LIFT_HILL_SELECTED) { + liftHillAndAlternativeState |= CONSTRUCTION_LIFT_HILL_SELECTED; + } + + if (_currentTrackAlternative & RIDE_TYPE_ALTERNATIVE_TRACK_TYPE) { + liftHillAndAlternativeState |= RIDE_TYPE_ALTERNATIVE_TRACK_TYPE; + } + + Ride *ride = get_ride(rideIndex); + + if (_enabledRidePieces & (1ULL << TRACK_SLOPE_STEEP_LONG)) { + switch (trackType) { + case TRACK_ELEM_FLAT_TO_60_DEG_UP: + trackType = TRACK_ELEM_FLAT_TO_60_DEG_UP_LONG_BASE; + break; + + case TRACK_ELEM_60_DEG_UP_TO_FLAT: + trackType = TRACK_ELEM_60_DEG_UP_TO_FLAT_LONG_BASE; + break; + + case TRACK_ELEM_FLAT_TO_60_DEG_DOWN: + trackType = TRACK_ELEM_60_DEG_UP_TO_FLAT_LONG_BASE_122; + break; + + case TRACK_ELEM_60_DEG_DOWN_TO_FLAT: + trackType = TRACK_ELEM_FLAT_TO_60_DEG_DOWN_LONG_BASE; + break; + + case TRACK_ELEM_DIAG_FLAT_TO_60_DEG_UP: + case TRACK_ELEM_DIAG_60_DEG_UP_TO_FLAT: + case TRACK_ELEM_DIAG_FLAT_TO_60_DEG_DOWN: + case TRACK_ELEM_DIAG_60_DEG_DOWN_TO_FLAT: + return true; + } + } + + if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_TRACK_ELEMENTS_HAVE_TWO_VARIETIES) && _currentTrackAlternative & RIDE_TYPE_ALTERNATIVE_TRACK_PIECES) { + if (ride->type != RIDE_TYPE_WATER_COASTER || trackType == TRACK_ELEM_FLAT || trackType == TRACK_ELEM_LEFT_QUARTER_TURN_5_TILES || trackType == TRACK_ELEM_RIGHT_QUARTER_TURN_5_TILES) { + sint16 alternativeType = AlternativeTrackTypes[trackType]; + if (alternativeType > -1) { + trackType = (uint8) alternativeType; + } + liftHillAndAlternativeState &= ~CONSTRUCTION_LIFT_HILL_SELECTED; + } + } + + const rct_track_coordinates *trackCoordinates = get_track_coord_from_ride(ride, trackType); + + x = _currentTrackBeginX; + y = _currentTrackBeginY; + z = _currentTrackBeginZ; + if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_BACK) { + z -= trackCoordinates->z_end; + trackDirection = _currentTrackPieceDirection ^ 0x02; + trackDirection -= trackCoordinates->rotation_end; + trackDirection += trackCoordinates->rotation_begin; + trackDirection &= 0x03; + + if (trackCoordinates->rotation_begin & (1 << 2)) { + trackDirection |= 0x04; + } + + switch (trackDirection & 0x03) { + case 0: + x -= trackCoordinates->x; + y -= trackCoordinates->y; + break; + + case 1: + x -= trackCoordinates->y; + y += trackCoordinates->x; + break; + + case 2: + x += trackCoordinates->x; + y += trackCoordinates->y; + break; + + case 3: + x += trackCoordinates->y; + y -= trackCoordinates->x; + break; + } + } else { + z -= trackCoordinates->z_begin; + trackDirection = _currentTrackPieceDirection; + } + + + bool turnOffLiftHill = false; + if (!(_enabledRidePieces & (1ULL << TRACK_LIFT_HILL_CURVE))) { + if (TrackFlags[trackType] & TRACK_ELEM_FLAG_CURVE_ALLOWS_LIFT) { + turnOffLiftHill = true; + } + } + + if (!(TrackFlags[trackType] & TRACK_ELEM_FLAG_ALLOW_LIFT_HILL)) { + turnOffLiftHill = true; + } + + if (turnOffLiftHill && !gCheatsEnableChainLiftOnAllTrack) { + liftHillAndAlternativeState &= ~CONSTRUCTION_LIFT_HILL_SELECTED; + _currentTrackLiftHill &= ~CONSTRUCTION_LIFT_HILL_SELECTED; + + if (trackType == TRACK_ELEM_LEFT_CURVED_LIFT_HILL || trackType == TRACK_ELEM_RIGHT_CURVED_LIFT_HILL) { + liftHillAndAlternativeState |= CONSTRUCTION_LIFT_HILL_SELECTED; + } + } + + + if (track_element_has_speed_setting(trackType)) { + properties = _currentBrakeSpeed2; + } else { + properties = _currentSeatRotationAngle << 12; + } + + + if (_trackType != NULL) *_trackType = trackType; + if (_trackDirection != NULL) *_trackDirection = trackDirection; + if (_rideIndex != NULL) *_rideIndex = rideIndex; + if (_liftHillAndAlternativeState != NULL) *_liftHillAndAlternativeState = liftHillAndAlternativeState; + if (_x != NULL) *_x = x; + if (_y != NULL) *_y = y; + if (_z != NULL) *_z = z; + if (_properties != NULL) *_properties = properties; + + return false; +} + +void window_ride_construction_do_entrance_exit_check() +{ + rct_window *w = window_find_by_class(WC_RIDE_CONSTRUCTION); + Ride *ride = get_ride(_currentRideIndex); + + if (w == NULL || ride == NULL) { + return; + } + + if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_0) { + w = window_find_by_class(WC_RIDE_CONSTRUCTION); + if (w != NULL) { + if (!ride_are_all_possible_entrances_and_exits_built(ride)) { + window_event_mouse_up_call(w, WC_RIDE_CONSTRUCTION__WIDX_ENTRANCE); + } else { + _deferClose = true; + } + } + } +} + +void window_ride_construction_do_station_check() +{ + Ride *ride = get_ride(_currentRideIndex); + if (ride != NULL) { + _stationConstructed = ride->num_stations != 0; + } +} + +void window_ride_construction_mouseup_demolish_next_piece(sint32 x, sint32 y, sint32 z, sint32 direction, sint32 type) +{ + if (gGotoStartPlacementMode) { + z &= 0xFFF0; + _currentTrackBeginZ = z; + _rideConstructionState = RIDE_CONSTRUCTION_STATE_FRONT; + _currentTrackSelectionFlags = 0; + _rideConstructionArrowPulseTime = 0; + direction = _currentTrackPieceDirection; + sint32 slope = _currentTrackCurve; + sint32 slopeEnd = _previousTrackSlopeEnd; + sint32 b2 = _currentTrackSlopeEnd; + sint32 bankEnd = _previousTrackBankEnd; + sint32 bankStart = _currentTrackBankEnd; + sint32 b5 = _currentTrackAlternative; + sint32 b4 = _currentTrackLiftHill; + ride_construction_set_default_next_piece(); + window_ride_construction_update_active_elements(); + if (!ride_try_get_origin_element(_currentRideIndex, NULL)) { + ride_initialise_construction_window(_currentRideIndex); + _currentTrackPieceDirection = direction; + if (!(slope & 0x100)) { + _currentTrackCurve = slope; + _previousTrackSlopeEnd = slopeEnd; + _currentTrackSlopeEnd = b2; + _previousTrackBankEnd = bankEnd; + _currentTrackBankEnd = bankStart; + _currentTrackAlternative = b5; + _currentTrackLiftHill = b4; + window_ride_construction_update_active_elements(); + } + } + } + else { + if (_rideConstructionState2 == RIDE_CONSTRUCTION_STATE_SELECTED || + _rideConstructionState2 == RIDE_CONSTRUCTION_STATE_FRONT + ) { + if (type == TRACK_ELEM_MIDDLE_STATION || type == TRACK_ELEM_BEGIN_STATION) { + type = TRACK_ELEM_END_STATION; + } + } + if (_rideConstructionState2 == RIDE_CONSTRUCTION_STATE_BACK) { + if (type == TRACK_ELEM_MIDDLE_STATION) { + type = TRACK_ELEM_BEGIN_STATION; + } + } + if (network_get_mode() == NETWORK_MODE_CLIENT) + { + // rideConstructionState needs to be set again to the proper value, this only affects the client + _rideConstructionState = RIDE_CONSTRUCTION_STATE_SELECTED; + } + _currentTrackBeginX = x; + _currentTrackBeginY = y; + _currentTrackBeginZ = z; + _currentTrackPieceDirection = direction; + _currentTrackPieceType = type; + _currentTrackSelectionFlags = 0; + _rideConstructionArrowPulseTime = 0; + if (_rideConstructionState2 == RIDE_CONSTRUCTION_STATE_FRONT) { + ride_select_next_section(); + } + else if (_rideConstructionState2 == RIDE_CONSTRUCTION_STATE_BACK) { + ride_select_previous_section(); + } + window_ride_construction_update_active_elements(); + } +} + +/** + * + * rct2: 0x006C84CE + */ +void window_ride_construction_update_active_elements() +{ + Intent * intent = intent_create(INTENT_ACTION_RIDE_CONSTRUCTION_UPDATE_ACTIVE_ELEMENTS); + context_broadcast_intent(intent); + intent_release(intent); +}