1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-16 03:23:15 +01:00

Move ride construction window to UI module

This commit is contained in:
Marijn van der Werf
2017-11-06 00:31:16 +01:00
parent 75e5f44717
commit c247bbcb82
8 changed files with 499 additions and 471 deletions

View File

@@ -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 = "<group>"; };
C666ED871F33E3520061AA04 /* EditorObjectSelection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EditorObjectSelection.cpp; sourceTree = "<group>"; };
C666ED8C1F33E3520061AA04 /* GameBottomToolbar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GameBottomToolbar.cpp; sourceTree = "<group>"; };
C666EDA61F33E3520061AA04 /* RideConstruction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RideConstruction.cpp; sourceTree = "<group>"; };
C666EDA91F33E3520061AA04 /* Scenery.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Scenery.cpp; sourceTree = "<group>"; };
C666EDB21F33E3520061AA04 /* TileInspector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TileInspector.cpp; sourceTree = "<group>"; };
C666EDBA1F33E3520061AA04 /* Tooltip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Tooltip.cpp; sourceTree = "<group>"; };
@@ -873,6 +872,7 @@
C6D2BEE41F9BAACD008B557C /* MapTooltip.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MapTooltip.cpp; sourceTree = "<group>"; };
C6D2BEE51F9BAACD008B557C /* MazeConstruction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MazeConstruction.cpp; sourceTree = "<group>"; };
C6D2BEE91F9BB83B008B557C /* NetworkStatus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkStatus.cpp; sourceTree = "<group>"; };
C6E415501FAFD6DB00D4A52A /* RideConstruction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RideConstruction.cpp; sourceTree = "<group>"; };
C6E96E331E0408A80076A04F /* zip.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = zip.h; sourceTree = "<group>"; };
C6E96E341E0408A80076A04F /* zipconf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = zipconf.h; sourceTree = "<group>"; };
C6E96E351E0408B40076A04F /* libzip.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libzip.dylib; sourceTree = "<group>"; };
@@ -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 */,

View File

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

View File

@@ -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 <openrct2-ui/windows/Window.h>
#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 <openrct2/audio/audio.h>
#include <openrct2/cheats.h>
#include <openrct2/config/Config.h>
#include <openrct2/Context.h>
#include <openrct2/core/Math.hpp>
#include <openrct2/core/Util.hpp>
#include <openrct2/game.h>
#include <openrct2/input.h>
#include <openrct2/interface/viewport.h>
#include <openrct2/interface/widget.h>
#include <openrct2/localisation/localisation.h>
#include <openrct2/network/network.h>
#include <openrct2/ride/RideGroupManager.h>
#include <openrct2/ride/ride_data.h>
#include <openrct2/ride/Track.h>
#include <openrct2/ride/TrackData.h>
#include <openrct2/sprites.h>
#include <openrct2/windows/dropdown.h>
#include <openrct2/windows/Intent.h>
#include <openrct2/world/entrance.h>
#include <openrct2/world/footpath.h>
#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);
}
}

View File

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

View File

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

View File

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

View File

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

View File

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