Separate booster track elem type (#13857)

* add data to Track.cpp

add data to TrackData.cpp

add import helper functions

fix Booster value

import booster as 256

export booster as 100

add vehicle subposition data

add SV4 import

add TD4 import

add TD6 import

use track_type_t when importing TD6

add TD6 export

change peep tracktype type to auto

fix SV4 track element import

fix import of booster speed

add None enum to TrackElemType

move _legacy RideConstruction functions to Ride.cpp

change _currentPossibleRideConfigurations to use track_type_t

fix booster track category

add booster string tto

expand _currentTrackCurve to 32 bits

expand track_curve_chain to 32 bits

update get_track_element et al. to handle 16 bit track types

run clang-format

remove unused #includes from _legacy.cpp

Revert "remove unused #includes from _legacy.cpp"

This reverts commit 4c4d4b06edb0c130314789d8fe371246be246c9f.

Revert "update get_track_element et al. to handle 16 bit track types"

This reverts commit 73920dafd4a6c9e7c9f0c7ee1098d493f8f5d262.

Revert "move _legacy RideConstruction functions to Ride.cpp"

This reverts commit 2d83a75c1477d387ad77a7a5085f37a28f72a589.

update _legacy functions for 16-bit track types

update ride_construction_reset_current_piece behavior with new enum

fix declaration of _currentTrackCurve to match other track tcurve vars

remove unused include from T4Importer.cpp

move SCT to 256 part 1: RideConstruction.cpp

move SCT to 256 part 2: TrackData.cpp

move SCT to 256 part 3: Ride.h/Ride.cpp

move SCT to 256 Part 4: revert changes to S4Importer.cpp, T4Importer.cpp

fix stations appearing as curves

fix too many initializers in TrackData.cpp

move SCT to 256 part 5: S6/T6 importing and exporting

move SCT to 256 part 6: simplify RCT12.cpp functions

fix comments in S6Exporter.cpp, S6Importer.cpp

fix clang-format on S6Importer.cpp

add missing data to TrackData.cpp

revert new functions for checking if track type is a booster

revert unused include

change trackType to auto and add comment to S6Exporter.cpp

move track type aliasing from TrackDesign.cpp to T6Import.cpp, T6Export.cpp

add comment about sv6 vehicle.track_type

static cast to uint8_t in T6Exporter.cpp`

set type to auto when setting value to _currentTrackCurve

revert moving function in S6Importer.cpp

fix value names in RideData.cpp

revert cahnge to uint16_t return for GetTrackType() in RCT12.cpp

fix GetTrackType return type for real

add changelog entry

bump network version

cast alternate track type to track_type_t

static_cast tuple input value in _legacy.cpp

change _currentTrackCurve to uint32

use TrackElemType::Count to determine length of subposition array

perform some changes

remove padding from rct_trackdefinition

fix alternative type check

remove _boosterTrackSelected

add missing condition for booster speed

add comments for TrackElemType::MultiDimInvertedUp90ToFlatQuarterLoop

add missing comments to RideData.cpp

remove extra entry

simplify some things

fix formatting

remove redundant checks todo: fix building the track piece

use TrackElemType::None more

remove git.txt

* bump network version

* make conditional more explicit w/ parentheses

* move booster check to RCT12.cpp

* implement getters and setters for vehicle track type and direction

* fix formatting

* rename RCT12TrackTypeIsBooster to RCT2TrackTypeIsBooster

* add whitespace in RCT2.h

* change the thing I thought I changed

* move booster check function to RCT2.cpp

* move function into if condition

* fix scope issues with setters
This commit is contained in:
spacek531 2021-01-29 07:24:53 -08:00 committed by GitHub
parent 109a06663d
commit 1e3fe9b550
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 514 additions and 442 deletions

View File

@ -19,6 +19,7 @@
- Feature: [#13614] Add terrain surfaces from RollerCoaster Tycoon 1.
- Feature: [#13675] [Plugin] Add context.setInterval and context.setTimeout.
- Change: [#13346] [Plugin] Renamed FootpathScenery to FootpathAddition, fix typos.
- Change: [#13857] Change Rotation Control Toggle to track element number 256
- Fix: [#4605, #11912] Water palettes are not updated properly when selected in Object Selection.
- Fix: [#9631, #10716] Banners drawing glitches when there are more than 32 on the screen at once.
- Fix: [#11438] Freeze when shrinking map size.

View File

@ -269,7 +269,7 @@ static constexpr const rct_string_id RideConfigurationStringIds[] = {
0, // 97
0, // 98
STR_BRAKES, // 99
STR_SPINNING_CONTROL_TOGGLE_TRACK, // 100
STR_BOOSTER, // 100
0, // 101
STR_HELIX_UP_LARGE, // 102
STR_HELIX_UP_LARGE, // 103
@ -424,7 +424,8 @@ static constexpr const rct_string_id RideConfigurationStringIds[] = {
0, // 252
STR_QUARTER_LOOP, // 253
STR_QUARTER_LOOP, // 254
STR_QUARTER_LOOP // 255
STR_QUARTER_LOOP, // 255
STR_SPINNING_CONTROL_TOGGLE_TRACK, // 256
};
// clang-format on
@ -440,7 +441,6 @@ static money32 _trackPlaceCost;
static bool _autoOpeningShop;
static bool _autoRotatingShop;
static uint8_t _currentlyShowingBrakeOrBoosterSpeed;
static bool _boosterTrackSelected;
static uint32_t _currentDisabledSpecialTrackPieces;
@ -2249,12 +2249,6 @@ static void window_ride_construction_invalidate(rct_window* w)
{
stringId = STR_LOG_BUMPS;
}
else if (
stringId == STR_SPINNING_CONTROL_TOGGLE_TRACK && ride->type != RIDE_TYPE_SPINNING_WILD_MOUSE
&& ride->type != RIDE_TYPE_STEEL_WILD_MOUSE)
{
stringId = STR_BOOSTER;
}
}
auto ft = Formatter::Common();
ft.Add<uint16_t>(stringId);
@ -2262,7 +2256,8 @@ static void window_ride_construction_invalidate(rct_window* w)
if (_currentlyShowingBrakeOrBoosterSpeed)
{
uint16_t brakeSpeed2 = ((_currentBrakeSpeed2 * 9) >> 2) & 0xFFFF;
if (_boosterTrackSelected)
if (_selectedTrackType == TrackElemType::Booster
|| _currentTrackCurve == (RideConstructionSpecialPieceSelected | TrackElemType::Booster))
{
brakeSpeed2 = get_booster_speed(ride->type, brakeSpeed2);
}
@ -2492,7 +2487,7 @@ void window_ride_construction_update_active_elements_impl()
window_ride_construction_update_map_selection();
_selectedTrackType = 255;
_selectedTrackType = TrackElemType::None;
if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_SELECTED)
{
if (sub_6C683D(
@ -3062,11 +3057,10 @@ static void window_ride_construction_update_widgets(rct_window* w)
bool brakesSelected = _selectedTrackType == TrackElemType::Brakes
|| _currentTrackCurve == (RideConstructionSpecialPieceSelected | TrackElemType::Brakes);
_boosterTrackSelected = TrackTypeIsBooster(ride->type, _selectedTrackType)
|| (ride->type != RIDE_TYPE_SPINNING_WILD_MOUSE && ride->type != RIDE_TYPE_STEEL_WILD_MOUSE
&& _currentTrackCurve == (RideConstructionSpecialPieceSelected | TrackElemType::Booster));
bool boosterTrackSelected = _selectedTrackType == TrackElemType::Booster
|| _currentTrackCurve == (RideConstructionSpecialPieceSelected | TrackElemType::Booster);
if (!brakesSelected && !_boosterTrackSelected)
if (!brakesSelected && !boosterTrackSelected)
{
if (is_track_enabled(TRACK_FLAT_ROLL_BANKING))
{
@ -3351,12 +3345,6 @@ static void window_ride_construction_show_special_track_dropdown(rct_window* w,
if (ride != nullptr && (ride->type == RIDE_TYPE_MONSTER_TRUCKS || ride->type == RIDE_TYPE_CAR_RIDE))
trackPieceStringId = STR_LOG_BUMPS;
}
if (trackPieceStringId == STR_SPINNING_CONTROL_TOGGLE_TRACK)
{
auto ride = get_ride(_currentRideIndex);
if (ride != nullptr && ride->type != RIDE_TYPE_SPINNING_WILD_MOUSE && ride->type != RIDE_TYPE_STEEL_WILD_MOUSE)
trackPieceStringId = STR_BOOSTER;
}
gDropdownItemsFormat[i] = trackPieceStringId;
if ((trackPiece | RideConstructionSpecialPieceSelected) == _currentTrackCurve)
{
@ -3842,7 +3830,7 @@ void ride_construction_tooldown_construct(const ScreenCoordsXY& screenCoords)
|| z < 0)
{
int32_t saveTrackDirection = _currentTrackPieceDirection;
int32_t saveCurrentTrackCurve = _currentTrackCurve;
auto saveCurrentTrackCurve = _currentTrackCurve;
int32_t savePreviousTrackSlopeEnd = _previousTrackSlopeEnd;
int32_t saveCurrentTrackSlopeEnd = _currentTrackSlopeEnd;
int32_t savePreviousTrackBankEnd = _previousTrackBankEnd;

View File

@ -134,3 +134,10 @@ void rct2_ride::SetMaxCarsPerTrain(uint8_t newValue)
min_max_cars_per_train &= ~0x0F;
min_max_cars_per_train |= newValue & 0x0F;
}
bool RCT2TrackTypeIsBooster(uint8_t rideType, uint16_t trackType)
{
// Boosters share their ID with the Spinning Control track.
return rideType != RIDE_TYPE_SPINNING_WILD_MOUSE && rideType != RIDE_TYPE_STEEL_WILD_MOUSE
&& trackType == TrackElemType::Booster;
}

View File

@ -571,6 +571,27 @@ struct RCT2SpriteVehicle : RCT12SpriteBase
uint8_t colours_extended; // 0xD7
uint8_t seat_rotation; // 0xD8
uint8_t target_seat_rotation; // 0xD9
uint16_t GetTrackType() const
{
return track_type >> 2;
}
uint8_t GetTrackDirection() const
{
return track_direction & 3;
}
void SetTrackType(uint16_t trackType)
{
// set the upper 14 bits to 0
track_type &= 3;
track_type |= trackType << 2;
}
void SetTrackDirection(uint8_t trackDirection)
{
// set the lower 2 bits only
track_direction &= ~3;
track_direction |= trackDirection & 3;
}
};
assert_struct_size(RCT2SpriteVehicle, 0xDA);
@ -779,6 +800,7 @@ assert_struct_size(RCT2RideRatingCalculationData, 76);
std::vector<uint8_t> DecryptSea(const fs::path& path);
ObjectEntryIndex RCT2RideTypeToOpenRCT2RideType(uint8_t rct2RideType, const rct_ride_entry* rideEntry);
bool RCT2TrackTypeIsBooster(uint8_t rideType, uint16_t trackType);
bool RCT2RideTypeNeedsConversion(uint8_t rct2RideType);
uint8_t OpenRCT2RideTypeToRCT2RideType(ObjectEntryIndex openrct2Type);

View File

@ -1109,9 +1109,13 @@ void S6Exporter::ExportSpriteVehicle(RCT2SpriteVehicle* dst, const Vehicle* src)
}
else
{
// export SpinningControlToggle (256) as SpinningControlToggleAlias (100) for backwards compatability with OpenRCT2
auto trackType = src->GetTrackType();
if (trackType == TrackElemType::RotationControlToggle)
trackType = TrackElemType::RotationControlToggleAlias;
// Track direction and type are in the same field
dst->track_direction = src->track_direction;
// dst->track_type = src->track_type;
dst->SetTrackType(trackType);
dst->SetTrackDirection(src->GetTrackDirection());
}
dst->track_x = src->TrackLocation.x;
dst->track_y = src->TrackLocation.y;
@ -1569,7 +1573,11 @@ void S6Exporter::ExportTileElement(RCT12TileElement* dst, TileElement* src)
auto dst2 = dst->AsTrack();
auto src2 = src->AsTrack();
dst2->SetTrackType(src2->GetTrackType());
auto trackType = src2->GetTrackType();
if (trackType == TrackElemType::RotationControlToggle)
trackType = TrackElemType::RotationControlToggleAlias;
// SV6 track type is uint8_t; we have aliased Rotation Control (256) to Booster (100) to allow this
dst2->SetTrackType(static_cast<uint8_t>(trackType));
dst2->SetSequenceIndex(src2->GetSequenceIndex());
dst2->SetRideIndex(src2->GetRideIndex());
dst2->SetColourScheme(src2->GetColourScheme());

View File

@ -1137,7 +1137,12 @@ public:
auto dst2 = dst->AsTrack();
auto src2 = src->AsTrack();
dst2->SetTrackType(src2->GetTrackType());
auto rideType = _s6.rides[src2->GetRideIndex()].type;
track_type_t trackType = static_cast<track_type_t>(src2->GetTrackType());
if (trackType == TrackElemType::RotationControlToggleAlias && !RCT2TrackTypeIsBooster(rideType, trackType))
trackType = TrackElemType::RotationControlToggle;
dst2->SetTrackType(trackType);
dst2->SetSequenceIndex(src2->GetSequenceIndex());
dst2->SetRideIndex(src2->GetRideIndex());
dst2->SetColourScheme(src2->GetColourScheme());
@ -1150,7 +1155,6 @@ public:
dst2->SetIsIndestructible(src2->IsIndestructible());
// Skipping IsHighlighted()
auto trackType = dst2->GetTrackType();
if (TrackTypeHasSpeedSetting(trackType))
{
dst2->SetBrakeBoosterSpeed(src2->GetBrakeBoosterSpeed());
@ -1161,7 +1165,6 @@ public:
}
// This has to be done last, since the maze entry shares fields with the colour and sequence fields.
auto rideType = _s6.rides[src2->GetRideIndex()].type;
if (rideType == RIDE_TYPE_MAZE)
{
dst2->SetMazeEntry(src2->GetMazeEntry());
@ -1368,12 +1371,27 @@ public:
dst->vehicle_type = src->vehicle_type;
dst->colours = src->colours;
dst->track_progress = src->track_progress;
dst->track_direction = src->track_direction;
dst->TrackLocation = { src->track_x, src->track_y, src->track_z };
if (src->boat_location.isNull() || static_cast<RideMode>(ride.mode) != RideMode::BoatHire
|| src->status != static_cast<uint8_t>(Vehicle::Status::TravellingBoat))
{
dst->BoatLocation.setNull();
dst->track_type = src->track_type;
dst->SetTrackDirection(src->GetTrackDirection());
dst->SetTrackType(src->GetTrackType());
// RotationControlToggle and Booster are saved as the same track piece ID
// Which one the vehicle is using must be determined
if (src->GetTrackType() == TrackElemType::RotationControlToggleAlias)
{
// Merging hacks mean the track type that's appropriate for the ride type is not necessarily the track type the
// ride is on. It's possible to create unwanted behavior if a user layers spinning control track on top of
// booster track but this is unlikely since only two rides have spinning control track - by default they load as
// booster
TileElement* tileElement2 = map_get_track_element_at_of_type_seq(
dst->TrackLocation, TrackElemType::RotationControlToggle, 0);
if (tileElement2 != nullptr)
dst->SetTrackType(TrackElemType::RotationControlToggle);
}
}
else
{
@ -1381,7 +1399,6 @@ public:
dst->track_type = 0;
}
dst->TrackLocation = { src->track_x, src->track_y, src->track_z };
dst->next_vehicle_on_train = src->next_vehicle_on_train;
dst->prev_vehicle_on_ride = src->prev_vehicle_on_ride;
dst->next_vehicle_on_ride = src->next_vehicle_on_ride;

View File

@ -99,7 +99,16 @@ bool T6Exporter::SaveTrack(OpenRCT2::IStream* stream)
{
for (const auto& trackElement : _trackDesign->track_elements)
{
tempStream.WriteValue<uint8_t>(trackElement.type);
auto trackType = trackElement.type;
if (trackElement.type == TrackElemType::RotationControlToggle)
{
trackType = TrackElemType::RotationControlToggleAlias;
}
else if (trackType == TrackElemType::MultiDimInvertedUp90ToFlatQuarterLoop)
{
trackType = TrackElemType::InvertedUp90ToFlatQuarterLoopAlias;
}
tempStream.WriteValue<uint8_t>(static_cast<uint8_t>(trackType));
tempStream.WriteValue<uint8_t>(trackElement.flags);
}

View File

@ -169,7 +169,18 @@ public:
_stream.SetPosition(_stream.GetPosition() - 1);
_stream.Read(&t6TrackElement, sizeof(rct_td46_track_element));
TrackDesignTrackElement trackElement{};
trackElement.type = t6TrackElement.type;
track_type_t trackType = t6TrackElement.type;
if (trackType == TrackElemType::RotationControlToggleAlias && !RCT2TrackTypeIsBooster(td->type, trackType))
{
trackType = TrackElemType::RotationControlToggle;
}
else if (trackType == TrackElemType::InvertedUp90ToFlatQuarterLoopAlias)
{
trackType = TrackElemType::MultiDimInvertedUp90ToFlatQuarterLoop;
}
trackElement.type = trackType;
trackElement.flags = t6TrackElement.flags;
td->track_elements.push_back(trackElement);
}

View File

@ -94,7 +94,7 @@ money32 _currentTrackPrice;
uint16_t _numCurrentPossibleRideConfigurations;
uint16_t _numCurrentPossibleSpecialTrackPieces;
uint16_t _currentTrackCurve;
uint32_t _currentTrackCurve;
uint8_t _rideConstructionState;
ride_id_t _currentRideIndex;
@ -1454,7 +1454,7 @@ static void ride_construction_reset_current_piece()
}
else
{
_currentTrackCurve = 0xFFFF;
_currentTrackCurve = TrackElemType::None;
_rideConstructionState = RIDE_CONSTRUCTION_STATE_0;
}
}
@ -1513,14 +1513,7 @@ void ride_construction_set_default_next_piece()
}
else
{
if (TrackTypeIsBooster(ride->type, trackType))
{
curve = RideConstructionSpecialPieceSelected | TrackElemType::Booster;
}
else
{
curve = gTrackCurveChain[trackType].next;
}
curve = gTrackCurveChain[trackType].next;
bank = TrackDefinitions[trackType].bank_end;
slope = TrackDefinitions[trackType].vangle_end;
}
@ -1574,14 +1567,7 @@ void ride_construction_set_default_next_piece()
}
else
{
if (TrackTypeIsBooster(ride->type, trackType))
{
curve = RideConstructionSpecialPieceSelected | TrackElemType::Booster;
}
else
{
curve = gTrackCurveChain[trackType].previous;
}
curve = gTrackCurveChain[trackType].previous;
bank = TrackDefinitions[trackType].bank_start;
slope = TrackDefinitions[trackType].vangle_start;
}

View File

@ -1071,7 +1071,7 @@ extern money32 _currentTrackPrice;
extern uint16_t _numCurrentPossibleRideConfigurations;
extern uint16_t _numCurrentPossibleSpecialTrackPieces;
extern uint16_t _currentTrackCurve;
extern uint32_t _currentTrackCurve;
extern uint8_t _rideConstructionState;
extern ride_id_t _currentRideIndex;

View File

@ -139,7 +139,7 @@ const rct_trackdefinition TrackDefinitions[TrackElemType::Count] =
{ TRACK_FLAT, TRACK_SLOPE_DOWN_60, TRACK_SLOPE_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, 0 }, // ELEM_LEFT_QUARTER_TURN_1_TILE_60_DEG_DOWN
{ TRACK_FLAT, TRACK_SLOPE_DOWN_60, TRACK_SLOPE_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, 0 }, // ELEM_RIGHT_QUARTER_TURN_1_TILE_60_DEG_DOWN
{ TRACK_BRAKES, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, 0 }, // ELEM_BRAKES
{ TRACK_ROTATION_CONTROL_TOGGLE,TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, 0 }, // ELEM_ROTATION_CONTROL_TOGGLE
{ TRACK_BOOSTER, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, 0 }, // ELEM_BOOSTER
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, 0 }, // ELEM_INVERTED_90_DEG_UP_TO_FLAT_QUARTER_LOOP
{ TRACK_HELIX_LARGE, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, 0 }, // ELEM_LEFT_QUARTER_BANKED_HELIX_LARGE_UP
{ TRACK_HELIX_LARGE, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, 0 }, // ELEM_RIGHT_QUARTER_BANKED_HELIX_LARGE_UP
@ -295,6 +295,7 @@ const rct_trackdefinition TrackDefinitions[TrackElemType::Count] =
{ TRACK_QUARTER_LOOP_UNINVERTED,TRACK_SLOPE_NONE, TRACK_SLOPE_UP_90, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, 0 }, // ELEM_MULTIDIM_90_DEG_UP_TO_INVERTED_FLAT_QUARTER_LOOP
{ TRACK_QUARTER_LOOP_UNINVERTED,TRACK_SLOPE_DOWN_90, TRACK_SLOPE_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, 0 }, // ELEM_MULTIDIM_FLAT_TO_90_DEG_DOWN_QUARTER_LOOP
{ TRACK_QUARTER_LOOP_INVERTED, TRACK_SLOPE_NONE, TRACK_SLOPE_UP_90, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, 0 }, // 255
{ TRACK_ROTATION_CONTROL_TOGGLE,TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, 0 }, // ELEM_ROTATION_CONTROL_TOGGLE
};
/** rct2: 0x0099849D */
@ -401,7 +402,7 @@ const rct_trackdefinition FlatRideTrackDefinitions[TrackElemType::Count] =
{ TRACK_FLAT, TRACK_SLOPE_DOWN_60, TRACK_SLOPE_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, 0 }, // 97
{ TRACK_FLAT, TRACK_SLOPE_DOWN_60, TRACK_SLOPE_DOWN_60, TRACK_BANK_NONE, TRACK_BANK_NONE, 0 }, // 98
{ TRACK_BRAKES, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, 0 }, // 99
{ TRACK_ROTATION_CONTROL_TOGGLE,TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, 0 }, // 100
{ TRACK_BOOSTER, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, 0 }, // 100
{ TRACK_FLAT, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, 0 }, // 101
{ TRACK_HELIX_LARGE, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_LEFT, TRACK_BANK_LEFT, 0 }, // 102
{ TRACK_HELIX_LARGE, TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_RIGHT, TRACK_BANK_RIGHT, 0 }, // 103
@ -556,6 +557,7 @@ const rct_trackdefinition FlatRideTrackDefinitions[TrackElemType::Count] =
{ TRACK_FLAT, TRACK_SLOPE_DOWN_90, TRACK_SLOPE_DOWN_90, TRACK_BANK_NONE, TRACK_BANK_NONE, 0 }, // 252
{ TRACK_QUARTER_LOOP_UNINVERTED,TRACK_SLOPE_NONE, TRACK_SLOPE_UP_90, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, 0 }, // 253
{ TRACK_QUARTER_LOOP_UNINVERTED,TRACK_SLOPE_DOWN_90, TRACK_SLOPE_NONE, TRACK_BANK_UPSIDE_DOWN, TRACK_BANK_NONE, 0 }, // 254
{ TRACK_ROTATION_CONTROL_TOGGLE,TRACK_SLOPE_NONE, TRACK_SLOPE_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, 0 }, // 256
};
// clang-format on
@ -1195,13 +1197,6 @@ bool track_element_is_covered(track_type_t trackElementType)
}
}
bool TrackTypeIsBooster(uint8_t rideType, track_type_t trackType)
{
// Boosters share their ID with the Spinning Control track.
return rideType != RIDE_TYPE_SPINNING_WILD_MOUSE && rideType != RIDE_TYPE_STEEL_WILD_MOUSE
&& trackType == TrackElemType::Booster;
}
bool TrackTypeHasSpeedSetting(track_type_t trackType)
{
// This does not check if the element is really a Spinning Control track instead of a booster,

View File

@ -13,7 +13,7 @@
#include "../object/Object.h"
#include "Ride.h"
constexpr const uint16_t RideConstructionSpecialPieceSelected = 0x100;
constexpr const uint32_t RideConstructionSpecialPieceSelected = 0x10000;
constexpr const int32_t BLOCK_BRAKE_BASE_SPEED = 0x20364;
@ -21,19 +21,15 @@ using track_type_t = uint16_t;
using roll_type_t = uint8_t;
using pitch_type_t = uint8_t;
#pragma pack(push, 1)
struct rct_trackdefinition
{
uint8_t type;
track_type_t type;
pitch_type_t vangle_end;
pitch_type_t vangle_start;
roll_type_t bank_end;
roll_type_t bank_start;
int8_t preview_z_offset;
uint8_t pad[2] = {};
};
assert_struct_size(rct_trackdefinition, 8);
#pragma pack(pop)
struct PitchAndRoll
{
@ -161,8 +157,7 @@ enum
TRACK_LIFT_HILL_CURVED,
TRACK_QUARTER_LOOP,
TRACK_SPINNING_TUNNEL,
TRACK_ROTATION_CONTROL_TOGGLE,
TRACK_BOOSTER = TRACK_ROTATION_CONTROL_TOGGLE,
TRACK_BOOSTER,
TRACK_INLINE_TWIST_UNINVERTED,
TRACK_INLINE_TWIST_INVERTED,
TRACK_QUARTER_LOOP_UNINVERTED,
@ -178,6 +173,7 @@ enum
TRACK_CORKSCREW_INVERTED,
TRACK_HEARTLINE_TRANSFER,
TRACK_MINI_GOLF_HOLE,
TRACK_ROTATION_CONTROL_TOGGLE,
TRACK_GROUP_COUNT,
};
@ -341,7 +337,7 @@ namespace TrackElemType
constexpr track_type_t LeftQuarterTurn1TileDown60 = 97;
constexpr track_type_t RightQuarterTurn1TileDown60 = 98;
constexpr track_type_t Brakes = 99;
constexpr track_type_t RotationControlToggle = 100;
constexpr track_type_t RotationControlToggleAlias = 100;
constexpr track_type_t Booster = 100;
constexpr track_type_t Maze = 101;
// Used by the multi-dimension coaster, as TD6 cannot handle index 255.
@ -500,8 +496,10 @@ namespace TrackElemType
constexpr track_type_t MultiDimUp90ToInvertedFlatQuarterLoop = 253;
constexpr track_type_t MultiDimFlatToDown90QuarterLoop = 254;
constexpr track_type_t MultiDimInvertedUp90ToFlatQuarterLoop = 255;
constexpr track_type_t RotationControlToggle = 256;
constexpr uint16_t Count = 256;
constexpr track_type_t Count = 257;
constexpr track_type_t None = 65535;
}; // namespace TrackElemType
enum
@ -580,5 +578,4 @@ money32 maze_set_track(
uint16_t x, uint16_t y, uint16_t z, uint8_t flags, bool initialPlacement, uint8_t direction, ride_id_t rideIndex,
uint8_t mode);
bool TrackTypeIsBooster(uint8_t rideType, track_type_t trackType);
bool TrackTypeHasSpeedSetting(track_type_t trackType);

View File

@ -269,6 +269,7 @@ const rct_track_coordinates FlatTrackCoordinates[TrackElemType::Count] = {
{ 0, 1, 0, 96, 0, -32 },
{ 0, 3, 96, 0, 0, 32 },
{ 0, 1, 96, 0, 0, -32 },
{ 0, 0, 0, 0, 0, 0 },
};
const rct_track_coordinates TrackCoordinates[TrackElemType::Count] = {
@ -527,7 +528,8 @@ const rct_track_coordinates TrackCoordinates[TrackElemType::Count] = {
{ 0, 1, 96, 0, 0, -32 },
{ 0, 2, 0, 96, 64, 0 },
{ 0, 2, 0, -128, -96, 0 },
{ 0, 2, 0, 128, 64, 0 }
{ 0, 2, 0, 128, 64, 0 },
{ 0, 0, 0, 0, 0, 0 },
};
/** rct2: 0x0099BA64 */
@ -2936,6 +2938,11 @@ static constexpr const rct_preview_track TrackBlocks255[] = {
TRACK_BLOCK_END
};
static constexpr const rct_preview_track TrackBlocksRotationControlToggle[] = {
{ 0, 0, 0, 0, 16, { 0b1111, 0b1100 }, 0 },
TRACK_BLOCK_END
};
// rct2: 0x00994638
const rct_preview_track *TrackBlocks[TrackElemType::Count] = {
TrackBlocks000,
@ -3193,7 +3200,8 @@ const rct_preview_track *TrackBlocks[TrackElemType::Count] = {
TrackBlocks252,
TrackBlocks253,
TrackBlocks254,
TrackBlocks255
TrackBlocks255,
TrackBlocksRotationControlToggle,
};
static constexpr const rct_preview_track FlatRideTrackBlocks095[] = {
@ -3553,7 +3561,8 @@ const rct_preview_track *FlatRideTrackBlocks[TrackElemType::Count] = {
TrackBlocks252,
TrackBlocks253,
TrackBlocks254,
FlatRideTrackBlocks255
FlatRideTrackBlocks255,
TrackBlocksRotationControlToggle,
};
const uint8_t TrackPieceLengths[TrackElemType::Count] = {
@ -3657,7 +3666,7 @@ const uint8_t TrackPieceLengths[TrackElemType::Count] = {
64, // TrackElemType::LeftQuarterTurn1TileDown60
64, // TrackElemType::RightQuarterTurn1TileDown60
32, // TrackElemType::Brakes
32, // TrackElemType::RotationControlToggle
32, // TrackElemType::Booster
32, // TrackElemType::InvertedUp90ToFlatQuarterLoopAlias / Maze
124, // TrackElemType::LeftQuarterBankedHelixLargeUp
124, // TrackElemType::RightQuarterBankedHelixLargeUp
@ -3744,75 +3753,76 @@ const uint8_t TrackPieceLengths[TrackElemType::Count] = {
100, // TrackElemType::RightLargeHalfLoopUp
100, // TrackElemType::RightLargeHalfLoopDown
100, // TrackElemType::LeftLargeHalfLoopDown
96, //
96, //
96, //
96, //
64, //
64, //
64, //
64, //
64, //
64, //
16, //
16, //
64, //
64, //
32, //
32, //
32, //
32, //
32, //
80, //
80, //
80, //
64, //
64, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
32, //
80, //
80, //
80, //
96, // TrackElemType::LeftFlyerTwistUp
96, // TrackElemType::RightFlyerTwistUp
96, // TrackElemType::LeftFlyerTwistDown
96, // TrackElemType::RightFlyerTwistDown
64, // TrackElemType::FlyerHalfLoopUp
64, // TrackElemType::FlyerHalfLoopDown
64, // TrackElemType::LeftFlyerCorkscrewUp
64, // TrackElemType::RightFlyerCorkscrewUp
64, // TrackElemType::LeftFlyerCorkscrewDown
64, // TrackElemType::RightFlyerCorkscrewDown
16, // TrackElemType::HeartLineTransferUp
16, // TrackElemType::HeartLineTransferDown
64, // TrackElemType::LeftHeartLineRoll
64, // TrackElemType::RightHeartLineRoll
32, // TrackElemType::MinigolfHoleA
32, // TrackElemType::MinigolfHoleB
32, // TrackElemType::MinigolfHoleC
32, // TrackElemType::MinigolfHoleD
32, // TrackElemType::MinigolfHoleE
80, // TrackElemType::MultiDimInvertedFlatToDown90QuarterLoop
80, // TrackElemType::Up90ToInvertedFlatQuarterLoop
80, // TrackElemType::InvertedFlatToDown90QuarterLoop
64, // TrackElemType::LeftCurvedLiftHill
64, // TrackElemType::RightCurvedLiftHill
32, // TrackElemType::LeftReverser
32, // TrackElemType::RightReverser
32, // TrackElemType::AirThrustTopCap
32, // TrackElemType::AirThrustVerticalDown
32, // TrackElemType::AirThrustVerticalDownToLevel
32, // TrackElemType::BlockBrakes
32, // TrackElemType::LeftBankedQuarterTurn3TileUp25
32, // TrackElemType::RightBankedQuarterTurn3TileUp25
32, // TrackElemType::LeftBankedQuarterTurn3TileDown25
32, // TrackElemType::RightBankedQuarterTurn3TileDown25
32, // TrackElemType::LeftBankedQuarterTurn5TileUp25
32, // TrackElemType::RightBankedQuarterTurn5TileUp25
32, // TrackElemType::LeftBankedQuarterTurn5TileDown25
32, // TrackElemType::RightBankedQuarterTurn5TileDown25
32, // TrackElemType::Up25ToLeftBankedUp25
32, // TrackElemType::Up25ToRightBankedUp25
32, // TrackElemType::LeftBankedUp25ToUp25
32, // TrackElemType::RightBankedUp25ToUp25
32, // TrackElemType::Down25ToLeftBankedDown25
32, // TrackElemType::Down25ToRightBankedDown25
32, // TrackElemType::LeftBankedDown25ToDown25
32, // TrackElemType::RightBankedDown25ToDown25
32, // TrackElemType::LeftBankedFlatToLeftBankedUp25
32, // TrackElemType::RightBankedFlatToRightBankedUp25
32, // TrackElemType::LeftBankedUp25ToLeftBankedFlat
32, // TrackElemType::RightBankedUp25ToRightBankedFlat
32, // TrackElemType::LeftBankedFlatToLeftBankedDown25
32, // TrackElemType::RightBankedFlatToRightBankedDown25
32, // TrackElemType::LeftBankedDown25ToLeftBankedFlat
32, // TrackElemType::RightBankedDown25ToRightBankedFlat
32, // TrackElemType::FlatToLeftBankedUp25
32, // TrackElemType::FlatToRightBankedUp25
32, // TrackElemType::LeftBankedUp25ToFlat
32, // TrackElemType::RightBankedUp25ToFlat
32, // TrackElemType::FlatToLeftBankedDown25
32, // TrackElemType::FlatToRightBankedDown25
32, // TrackElemType::LeftBankedDown25ToFlat
32, // TrackElemType::RightBankedDown25ToFlat
32, // TrackElemType::LeftQuarterTurn1TileUp90
32, // TrackElemType::RightQuarterTurn1TileUp90
32, // TrackElemType::LeftQuarterTurn1TileDown90
32, // TrackElemType::RightQuarterTurn1TileDown90
80, // TrackElemType::MultiDimUp90ToInvertedFlatQuarterLoop
80, // TrackElemType::MultiDimFlatToDown90QuarterLoop
80, // TrackElemType::MultiDimInvertedUp90ToFlatQuarterLoop
32, // TrackElemType::RotationControlToggle
};
// rct2: 0x00998C95
@ -3917,7 +3927,7 @@ const track_curve_chain gTrackCurveChain[TrackElemType::Count] = {
{ TRACK_CURVE_LEFT_SMALL, TRACK_CURVE_LEFT_SMALL },
{ TRACK_CURVE_RIGHT_SMALL, TRACK_CURVE_RIGHT_SMALL },
{ RideConstructionSpecialPieceSelected | TrackElemType::Brakes, RideConstructionSpecialPieceSelected | TrackElemType::Brakes },
{ TRACK_CURVE_NONE, TRACK_CURVE_NONE },
{ RideConstructionSpecialPieceSelected | TrackElemType::Booster, RideConstructionSpecialPieceSelected | TrackElemType::Booster },
{ TRACK_CURVE_NONE, TRACK_CURVE_NONE },
{ RideConstructionSpecialPieceSelected | TrackElemType::LeftQuarterBankedHelixLargeUp, RideConstructionSpecialPieceSelected | TrackElemType::LeftQuarterBankedHelixLargeUp },
{ RideConstructionSpecialPieceSelected | TrackElemType::RightQuarterBankedHelixLargeUp, RideConstructionSpecialPieceSelected | TrackElemType::RightQuarterBankedHelixLargeUp },
@ -4073,6 +4083,7 @@ const track_curve_chain gTrackCurveChain[TrackElemType::Count] = {
{ TRACK_CURVE_NONE, TRACK_CURVE_NONE },
{ TRACK_CURVE_NONE, TRACK_CURVE_NONE },
{ TRACK_CURVE_NONE, TRACK_CURVE_NONE },
{ TRACK_CURVE_NONE, TRACK_CURVE_NONE },
};
// rct2: 0x00999095
@ -4333,6 +4344,7 @@ const track_curve_chain gFlatRideTrackCurveChain[TrackElemType::Count] = {
{ 0, 0 },
{ 0, 0 },
{ 0, 57088 },
{ 0, 0 },
};
const track_descriptor gTrackDescriptors[142] = {
@ -4481,11 +4493,11 @@ const track_descriptor gTrackDescriptors[142] = {
};
/** rct2: 0x00993D1C */
const int16_t AlternativeTrackTypes[TrackElemType::Count] = {
const track_type_t AlternativeTrackTypes[TrackElemType::Count] = {
TrackElemType::FlatCovered, // TrackElemType::Flat
-1,
-1,
-1,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::Up25Covered, // TrackElemType::Up25
TrackElemType::Up60Covered, // TrackElemType::Up60
TrackElemType::FlatToUp25Covered, // TrackElemType::FlatToUp25
@ -4500,248 +4512,249 @@ const int16_t AlternativeTrackTypes[TrackElemType::Count] = {
TrackElemType::Down25ToFlatCovered, // TrackElemType::Down25ToFlat
TrackElemType::LeftQuarterTurn5TilesCovered, // TrackElemType::LeftQuarterTurn5Tiles
TrackElemType::RightQuarterTurn5TilesCovered, // TrackElemType::RightQuarterTurn5Tiles
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::SBendLeftCovered, // TrackElemType::SBendLeft
TrackElemType::SBendRightCovered, // TrackElemType::SBendRight
-1,
-1,
TrackElemType::None,
TrackElemType::None,
TrackElemType::LeftQuarterTurn3TilesCovered, // TrackElemType::LeftQuarterTurn3Tiles
TrackElemType::RightQuarterTurn3TilesCovered, // TrackElemType::RightQuarterTurn3Tiles
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
-1,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None,
TrackElemType::None
};
/** rct2: 0x0099DA34 */
const money32 TrackPricing[] = {
const money32 TrackPricing[TrackElemType::Count] = {
65536, // TrackElemType::Flat
98304, // TrackElemType::EndStation
98304, // TrackElemType::BeginStation
@ -4842,7 +4855,7 @@ const money32 TrackPricing[] = {
126976, // TrackElemType::LeftQuarterTurn1TileDown60
126976, // TrackElemType::RightQuarterTurn1TileDown60
90112, // TrackElemType::Brakes
77824, // TrackElemType::RotationControlToggle
77824, // TrackElemType::Booster
65536, // TrackElemType::InvertedUp90ToFlatQuarterLoopAlias / Maze
273539, // TrackElemType::LeftQuarterBankedHelixLargeUp
273539, // TrackElemType::RightQuarterBankedHelixLargeUp
@ -4997,11 +5010,12 @@ const money32 TrackPricing[] = {
151552, // TrackElemType::RightQuarterTurn1TileDown90
360448, // TrackElemType::MultiDimUp90ToInvertedFlatQuarterLoop
360448, // TrackElemType::MultiDimFlatToDown90QuarterLoop
360448, //
360448, // TrackElemType::MultiDimInvertedUp90ToFlatQuarterLoop
77824, // TrackElemType::RotationControlToggle
};
/** rct2: 0x0099DE34 */
const money32 FlatRideTrackPricing[] = {
const money32 FlatRideTrackPricing[TrackElemType::Count] = {
65536,
98304,
98304,
@ -5255,10 +5269,14 @@ const money32 FlatRideTrackPricing[] = {
151552,
151552,
151552,
360448, // TrackElemType::MultiDimUp90ToInvertedFlatQuarterLoop
360448, // TrackElemType::MultiDimFlatToDown90QuarterLoop
360448, // TrackElemType::MultiDimInvertedUp90ToFlatQuarterLoop
77824, // TrackElemType::RotationControlToggle
};
/** rct2: 0x0099E228, 0x0099E229, 0x0099E22A, 0x0099E22B */
const dodgems_track_size DodgemsTrackSize[] = {
const dodgems_track_size DodgemsTrackSize[TrackElemType::Count] = {
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
@ -5512,10 +5530,14 @@ const dodgems_track_size DodgemsTrackSize[] = {
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
};
/** rct2: 0x0099EA1C */
const uint8_t TrackElementMirrorMap[] = {
const track_type_t TrackElementMirrorMap[TrackElemType::Count] = {
TrackElemType::Flat,
TrackElemType::EndStation,
TrackElemType::BeginStation,
@ -5616,7 +5638,7 @@ const uint8_t TrackElementMirrorMap[] = {
TrackElemType::RightQuarterTurn1TileDown60, // TrackElemType::LeftQuarterTurn1TileDown60
TrackElemType::LeftQuarterTurn1TileDown60, // TrackElemType::RightQuarterTurn1TileDown60
TrackElemType::Brakes,
TrackElemType::RotationControlToggle,
TrackElemType::Booster,
TrackElemType::Maze,
TrackElemType::RightQuarterBankedHelixLargeUp, // TrackElemType::LeftQuarterBankedHelixLargeUp
TrackElemType::LeftQuarterBankedHelixLargeUp, // TrackElemType::RightQuarterBankedHelixLargeUp
@ -5771,7 +5793,8 @@ const uint8_t TrackElementMirrorMap[] = {
TrackElemType::LeftQuarterTurn1TileDown90, // TrackElemType::RightQuarterTurn1TileDown90
TrackElemType::MultiDimUp90ToInvertedFlatQuarterLoop,
TrackElemType::MultiDimFlatToDown90QuarterLoop,
255,
TrackElemType::MultiDimInvertedUp90ToFlatQuarterLoop,
TrackElemType::RotationControlToggle,
};
/** rct2: 0x00999694 */
@ -5876,7 +5899,7 @@ const uint32_t TrackHeightMarkerPositions[TrackElemType::Count] = {
(1 << 0), // TrackElemType::LeftQuarterTurn1TileDown60
(1 << 0), // TrackElemType::RightQuarterTurn1TileDown60
(1 << 0), // TrackElemType::Brakes
(1 << 0), // TrackElemType::RotationControlToggle
(1 << 0), // TrackElemType::Booster
(1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) | (1 << 13) | (1 << 14) | (1 << 15), // TrackElemType::InvertedUp90ToFlatQuarterLoopAlias / Maze
(1 << 0) | (1 << 6), // TrackElemType::LeftQuarterBankedHelixLargeUp
(1 << 0) | (1 << 6), // TrackElemType::RightQuarterBankedHelixLargeUp
@ -6031,11 +6054,12 @@ const uint32_t TrackHeightMarkerPositions[TrackElemType::Count] = {
(1 << 0), // TrackElemType::RightQuarterTurn1TileDown90
(1 << 0) | (1 << 2), // TrackElemType::MultiDimUp90ToInvertedFlatQuarterLoop
(1 << 0) | (1 << 2), // TrackElemType::MultiDimFlatToDown90QuarterLoop
(1 << 0) | (1 << 2), // 255
(1 << 0) | (1 << 2), // TrackElemType::MultiDimInvertedUp90ToFlatQuarterLoop
(1 << 0), // TrackElemType::RotationControlToggle
};
/** rct2: 0x00999A94 */
const uint8_t TrackSequenceElementAllowedWallEdges[][MaxSequencesPerPiece] = {
const uint8_t TrackSequenceElementAllowedWallEdges[TrackElemType::Count][MaxSequencesPerPiece] = {
{ 0b1010, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // TrackElemType::Flat
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // TrackElemType::EndStation
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // TrackElemType::BeginStation
@ -6136,7 +6160,7 @@ const uint8_t TrackSequenceElementAllowedWallEdges[][MaxSequencesPerPiece] = {
{ 0b0011, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // TrackElemType::LeftQuarterTurn1TileDown60
{ 0b1001, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // TrackElemType::RightQuarterTurn1TileDown60
{ 0b1010, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // TrackElemType::Brakes
{ 0b1010, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // TrackElemType::RotationControlToggle
{ 0b1010, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // TrackElemType::Booster
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // TrackElemType::InvertedUp90ToFlatQuarterLoopAlias / Maze
{ 0b0010, 0b1100, 0b0011, 0, 0b1100, 0b0011, 0b0001, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // TrackElemType::LeftQuarterBankedHelixLargeUp
{ 0b1000, 0b0110, 0b1001, 0, 0b0110, 0b1001, 0b0001, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // TrackElemType::RightQuarterBankedHelixLargeUp
@ -6291,11 +6315,12 @@ const uint8_t TrackSequenceElementAllowedWallEdges[][MaxSequencesPerPiece] = {
{ 0b1111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // TrackElemType::RightQuarterTurn1TileDown90
{ 0b1010, 0b1010, 0b1010, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // TrackElemType::MultiDimUp90ToInvertedFlatQuarterLoop
{ 0b1010, 0b1010, 0b1010, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // TrackElemType::MultiDimFlatToDown90QuarterLoop
{ 0b1010, 0b1010, 0b1010, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 255
{ 0b1010, 0b1010, 0b1010, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // TrackElemType::MultiDimInvertedUp90ToFlatQuarterLoop
{ 0b1010, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // TrackElemType::RotationControlToggle
};
/** rct2: 0x0099AA94 */
const uint8_t FlatRideTrackSequenceElementAllowedWallEdges[][MaxSequencesPerPiece] = {
const uint8_t FlatRideTrackSequenceElementAllowedWallEdges[TrackElemType::Count][MaxSequencesPerPiece] = {
{ 0b1010, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
@ -6549,10 +6574,14 @@ const uint8_t FlatRideTrackSequenceElementAllowedWallEdges[][MaxSequencesPerPiec
{ 0b1111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0b1111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0b1111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0b1010, 0b1010, 0b1010, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // TrackElemType::MultiDimUp90ToInvertedFlatQuarterLoop
{ 0b1010, 0b1010, 0b1010, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // TrackElemType::MultiDimFlatToDown90QuarterLoop
{ 0b1010, 0b1010, 0b1010, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // TrackElemType::MultiDimInvertedUp90ToFlatQuarterLoop
{ 0b1010, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // TrackElemType::Booster
};
/** rct2: 0x0099443C */
const uint16_t FlatTrackFlags[] = {
const uint16_t FlatTrackFlags[TrackElemType::Count] = {
/* */ TRACK_ELEM_FLAG_ALLOW_LIFT_HILL,
/* */ 0,
/* */ 0,
@ -6807,10 +6836,13 @@ const uint16_t FlatTrackFlags[] = {
/* */ TRACK_ELEM_FLAG_TURN_LEFT | TRACK_ELEM_FLAG_TURN_SLOPED | TRACK_ELEM_FLAG_DOWN,
/* */ TRACK_ELEM_FLAG_TURN_RIGHT | TRACK_ELEM_FLAG_TURN_SLOPED | TRACK_ELEM_FLAG_DOWN,
/* ??? */ 0,
/* ??? */ 0,
/* ??? */ 0,
/* TrackElemType::RotationControlToggle */ 0,
};
/** rct2: 0x0099423C */
const uint16_t TrackFlags[] = {
const uint16_t TrackFlags[TrackElemType::Count] = {
/* TrackElemType::Flat */ TRACK_ELEM_FLAG_ALLOW_LIFT_HILL,
/* TrackElemType::EndStation */ 0,
/* TrackElemType::BeginStation */ 0,
@ -6911,7 +6943,7 @@ const uint16_t TrackFlags[] = {
/* TrackElemType::LeftQuarterTurn1TileDown60 */ TRACK_ELEM_FLAG_TURN_LEFT | TRACK_ELEM_FLAG_TURN_SLOPED | TRACK_ELEM_FLAG_DOWN | TRACK_ELEM_FLAG_STARTS_AT_HALF_HEIGHT,
/* TrackElemType::RightQuarterTurn1TileDown60 */ TRACK_ELEM_FLAG_TURN_RIGHT | TRACK_ELEM_FLAG_TURN_SLOPED | TRACK_ELEM_FLAG_DOWN | TRACK_ELEM_FLAG_STARTS_AT_HALF_HEIGHT,
/* TrackElemType::Brakes */ 0,
/* TrackElemType::RotationControlToggle */ 0,
/* TrackElemType::Booster */ 0,
/* TrackElemType::InvertedUp90ToFlatQuarterLoopAlias / Maze */ TRACK_ELEM_FLAG_ONLY_ABOVE_GROUND,
/* TrackElemType::LeftQuarterBankedHelixLargeUp */ TRACK_ELEM_FLAG_TURN_LEFT | TRACK_ELEM_FLAG_HELIX | TRACK_ELEM_FLAG_BANKED,
/* TrackElemType::RightQuarterBankedHelixLargeUp */ TRACK_ELEM_FLAG_TURN_RIGHT | TRACK_ELEM_FLAG_HELIX | TRACK_ELEM_FLAG_BANKED,
@ -7066,6 +7098,7 @@ const uint16_t TrackFlags[] = {
/* TrackElemType::RightQuarterTurn1TileDown90 */ TRACK_ELEM_FLAG_TURN_RIGHT | TRACK_ELEM_FLAG_TURN_SLOPED | TRACK_ELEM_FLAG_DOWN,
/* TrackElemType::MultiDimUp90ToInvertedFlatQuarterLoop */ TRACK_ELEM_FLAG_UP | TRACK_ELEM_FLAG_NORMAL_TO_INVERSION | TRACK_ELEM_FLAG_INVERSION_TO_NORMAL,
/* TrackElemType::MultiDimFlatToDown90QuarterLoop */ TRACK_ELEM_FLAG_DOWN | TRACK_ELEM_FLAG_INVERSION_TO_NORMAL,
/* */ TRACK_ELEM_FLAG_UP | TRACK_ELEM_FLAG_NORMAL_TO_INVERSION | TRACK_ELEM_FLAG_INVERSION_TO_NORMAL,
/* TrackElemType::MultiDimInvertedUp90ToFlatQuarterLoop */ TRACK_ELEM_FLAG_UP | TRACK_ELEM_FLAG_NORMAL_TO_INVERSION | TRACK_ELEM_FLAG_INVERSION_TO_NORMAL,
/* TrackElemType::RotationControlToggle */ 0,
};
// clang-format on

View File

@ -30,8 +30,8 @@ extern const uint8_t TrackPieceLengths[TrackElemType::Count];
struct track_curve_chain
{
uint16_t next;
uint16_t previous;
int32_t next;
int32_t previous;
};
extern const track_curve_chain gTrackCurveChain[TrackElemType::Count];
@ -50,7 +50,7 @@ struct track_descriptor
extern const track_descriptor gTrackDescriptors[142];
extern const int16_t AlternativeTrackTypes[TrackElemType::Count];
extern const track_type_t AlternativeTrackTypes[TrackElemType::Count];
extern const money32 TrackPricing[TrackElemType::Count];
extern const money32 FlatRideTrackPricing[TrackElemType::Count];
@ -65,7 +65,7 @@ struct dodgems_track_size
extern const dodgems_track_size DodgemsTrackSize[TrackElemType::Count];
extern const uint8_t TrackElementMirrorMap[TrackElemType::Count];
extern const track_type_t TrackElementMirrorMap[TrackElemType::Count];
extern const uint32_t TrackHeightMarkerPositions[TrackElemType::Count];

View File

@ -212,11 +212,6 @@ rct_string_id TrackDesign::CreateTrackDesignTrack(const Ride& ride)
{
TrackDesignTrackElement track{};
track.type = trackElement.element->AsTrack()->GetTrackType();
// TODO move to RCT2 limit
if (track.type == TrackElemType::MultiDimInvertedUp90ToFlatQuarterLoop)
{
track.type = TrackElemType::InvertedUp90ToFlatQuarterLoopAlias;
}
uint8_t trackFlags;
if (TrackTypeHasSpeedSetting(track.type))
@ -1531,10 +1526,6 @@ static bool track_design_place_ride(TrackDesign* td6, const CoordsXYZ& origin, R
for (const auto& track : td6->track_elements)
{
auto trackType = track.type;
if (trackType == TrackElemType::InvertedUp90ToFlatQuarterLoopAlias)
{
trackType = TrackElemType::MultiDimInvertedUp90ToFlatQuarterLoop;
}
track_design_update_max_min_coordinates(newCoords);

View File

@ -746,7 +746,7 @@ static bool vehicle_move_info_valid(VehicleTrackSubposition trackSubposition, in
switch (trackSubposition)
{
case VehicleTrackSubposition::Default:
size = 1024;
size = TrackElemType::Count * 4;
break;
case VehicleTrackSubposition::ChairliftGoingOut:
size = 692;
@ -8154,17 +8154,9 @@ bool Vehicle::UpdateTrackMotionForwardsGetNewTrack(uint16_t trackType, Ride* cur
{
trigger_on_ride_photo(TrackLocation, tileElement);
}
if (trackType == TrackElemType::RotationControlToggle)
{
curRide = get_ride(tileElement->AsTrack()->GetRideIndex());
if (curRide != nullptr)
{
uint16_t rideType = curRide->type;
if (trackType == TrackElemType::RotationControlToggle
&& (rideType == RIDE_TYPE_SPINNING_WILD_MOUSE || rideType == RIDE_TYPE_STEEL_WILD_MOUSE))
{
update_flags ^= VEHICLE_UPDATE_FLAG_ROTATION_OFF_WILD_MOUSE;
}
}
update_flags ^= VEHICLE_UPDATE_FLAG_ROTATION_OFF_WILD_MOUSE;
}
// Change from original: this used to check if the vehicle allowed doors.
UpdateSceneryDoorBackwards();
@ -8219,7 +8211,7 @@ loc_6DAEB9:
}
}
}
else if (TrackTypeIsBooster(curRide->type, trackType))
else if (trackType == TrackElemType::Booster)
{
auto boosterSpeed = get_booster_speed(curRide->type, (brake_speed << 16));
if (boosterSpeed > _vehicleVelocityF64E08)
@ -8594,7 +8586,7 @@ loc_6DBA33:;
}
}
if (TrackTypeIsBooster(curRide->type, trackType))
if (trackType == TrackElemType::Booster)
{
auto boosterSpeed = get_booster_speed(curRide->type, (brake_speed << 16));
if (boosterSpeed < _vehicleVelocityF64E08)

View File

@ -221,7 +221,7 @@ struct Vehicle : SpriteBase
union
{
int16_t track_direction; // (0000 0000 0000 0011)
int16_t track_type; // (0000 0011 1111 1100)
int16_t track_type; // (1111 1111 1111 1100)
};
CoordsXYZ TrackLocation;
uint16_t next_vehicle_on_train;
@ -340,12 +340,26 @@ struct Vehicle : SpriteBase
* Instantly moves the specific car forward or backwards along the track.
*/
void MoveRelativeDistance(int32_t distance);
track_type_t GetTrackType() const
{
return track_type >> 2;
}
uint8_t GetTrackDirection() const
{
return track_direction & 3;
}
void SetTrackType(track_type_t trackType)
{
// set the upper 14 bits to 0, then set track type
track_type &= 3;
track_type |= trackType << 2;
}
void SetTrackDirection(uint8_t trackDirection)
{
// set the lower 2 bits only
track_direction &= ~3;
track_direction |= trackDirection & 3;
}
bool HasUpdateFlag(uint32_t flag) const
{
return (update_flags & flag) != 0;

View File

@ -24060,7 +24060,8 @@ static constexpr const rct_vehicle_info_list *TrackVehicleInfoListDefault[] = {
&TrackVehicleInfo_96C062, &TrackVehicleInfo_96C3C4, &TrackVehicleInfo_96AC16, &TrackVehicleInfo_96AF78, &TrackVehicleInfo_96B2DA, &TrackVehicleInfo_96B63C,
&TrackVehicleInfo_96C726, &TrackVehicleInfo_96CA88, &TrackVehicleInfo_96CDEA, &TrackVehicleInfo_96D14C, &TrackVehicleInfo_9761F2, &TrackVehicleInfo_9766C5,
&TrackVehicleInfo_976B98, &TrackVehicleInfo_97706B, &TrackVehicleInfo_97753E, &TrackVehicleInfo_977A11, &TrackVehicleInfo_977EE4, &TrackVehicleInfo_9783B7,
&TrackVehicleInfo_97888A, &TrackVehicleInfo_978D5D, &TrackVehicleInfo_979230, &TrackVehicleInfo_979703,
&TrackVehicleInfo_97888A, &TrackVehicleInfo_978D5D, &TrackVehicleInfo_979230, &TrackVehicleInfo_979703, &TrackVehicleInfo_8BE57A, &TrackVehicleInfo_8BE69C,
&TrackVehicleInfo_8BE7BE, &TrackVehicleInfo_8BE8E0
};
static constexpr const rct_vehicle_info_list *TrackVehicleInfoListChairliftGoingOut[] = {

View File

@ -124,7 +124,7 @@ money32 place_provisional_track_piece(
}
}
static std::tuple<bool, uint8_t> window_ride_construction_update_state_get_track_element()
static std::tuple<bool, track_type_t> window_ride_construction_update_state_get_track_element()
{
auto intent = Intent(INTENT_ACTION_RIDE_CONSTRUCTION_UPDATE_PIECES);
context_broadcast_intent(&intent);
@ -142,8 +142,8 @@ static std::tuple<bool, uint8_t> window_ride_construction_update_state_get_track
endBank = _previousTrackBankEnd;
}
uint16_t curve = _currentTrackCurve;
if (curve == 0xFFFF)
auto curve = _currentTrackCurve;
if (curve == TrackElemType::None)
{
return std::make_tuple(false, 0);
}
@ -182,7 +182,7 @@ static std::tuple<bool, uint8_t> window_ride_construction_update_state_get_track
return std::make_tuple(false, 0);
}
switch (curve & 0xFF)
switch (curve & 0xFFFF)
{
case TrackElemType::EndStation:
case TrackElemType::SBendLeft:
@ -197,7 +197,7 @@ static std::tuple<bool, uint8_t> window_ride_construction_update_state_get_track
return std::make_tuple(false, 0);
}
return std::make_tuple(true, curve & 0xFF);
return std::make_tuple(true, static_cast<track_type_t>(curve & 0xFFFF));
case TrackElemType::LeftVerticalLoop:
case TrackElemType::RightVerticalLoop:
@ -221,10 +221,10 @@ static std::tuple<bool, uint8_t> window_ride_construction_update_state_get_track
}
}
return std::make_tuple(true, curve & 0xFF);
return std::make_tuple(true, static_cast<track_type_t>(curve & 0xFFFF));
default:
return std::make_tuple(true, curve & 0xFF);
return std::make_tuple(true, static_cast<track_type_t>(curve & 0xFFFF));
}
}
@ -306,9 +306,9 @@ bool window_ride_construction_update_state(
{
auto availablePieces = rtd.CoveredTrackPieces;
auto alternativeType = AlternativeTrackTypes[trackType];
if (alternativeType != -1 && availablePieces & (1ULL << trackType))
if (alternativeType != TrackElemType::None && (availablePieces & (1ULL << trackType)))
{
trackType = static_cast<uint8_t>(alternativeType);
trackType = alternativeType;
liftHillAndInvertedState &= ~CONSTRUCTION_LIFT_HILL_SELECTED;
}
}
@ -436,7 +436,7 @@ void window_ride_construction_mouseup_demolish_next_piece(const CoordsXYZD& piec
_rideConstructionState = RIDE_CONSTRUCTION_STATE_FRONT;
_currentTrackSelectionFlags = 0;
_currentTrackPieceDirection = piecePos.direction & 3;
int32_t savedCurrentTrackCurve = _currentTrackCurve;
auto savedCurrentTrackCurve = _currentTrackCurve;
int32_t savedPreviousTrackSlopeEnd = _previousTrackSlopeEnd;
int32_t savedCurrentTrackSlopeEnd = _currentTrackSlopeEnd;
int32_t savedPreviousTrackBankEnd = _previousTrackBankEnd;