mirror of https://github.com/OpenRCT2/OpenRCT2.git
"Reversed Trains" Option (#19305)
* Initial commit for backwards-facing trains * Allow persistence for reversed cars across save/load * Make log flume turntable compatible with new reversal implementation * Style fixes + Better implementation of inverted bank angles * Further Style Fixes * Code cleanup from PR feedback * Fix GetBankRotationForDrawing function declaration * Use update flag for reversed state * Replace modulo operation with bit mask * Correct guest pathing destination when entering reversed cars * More style fixes * Add plugin support for reversed vehicles * Fix formatting error * Derive reversal from ride mode for car spawning * Formatting * Rename function to GetPaintBankRotation * Add reversed trains modes to Multi Dimension Coaster * Change name of isReversed plugin API parameter for consistency * Replace reversal operating modes with separate ride setting * Add ALLOW_REVERSED_TRAINS flag to more ride types * Make clang-format happy * More Formatting * Fix ALLOW_REVERSED_TRAINS flag on a couple rides * Exclude flat rides from Reverse Trains tickbox when cheats are enabled * Formatting * Use Disable Vehicle Limits cheat for checkbox appearance condition * Use correct swinging sprites when cars are reversed * Update changelog and Plugin/Network/Park version numbers * Formatting * Add separate error String ID for clarity * Add name to contributors.md * Fix ride vehicle preview window with reversed trains for RCT1 train types * Bump version numbers again --------- Co-authored-by: Trevor Finney <8711258+finneyt@users.noreply.github.com>
This commit is contained in:
parent
8f0db4cb20
commit
6dfc6225e2
|
@ -104,7 +104,7 @@ The following people are not part of the development team, but have been contrib
|
|||
* Umar Ahmed (umar-ahmed) - MacOS file watcher
|
||||
* Andrew Arnold (fidwell) - Added window support for more scenery groups.
|
||||
* Josh Trzebiatowski (trzejos) - Ride and scenery filtering
|
||||
* (kyphii) - Extended color selection
|
||||
* (kyphii) - Extended color selection, reversed ride vehicles, misc.
|
||||
* Phumdol Lookthipnapha (beam41) - Misc.
|
||||
* Nikolas Parshook (nparshook) - Misc.
|
||||
* Wenzhao Qiu (qwzhaox) - Misc.
|
||||
|
|
|
@ -3687,6 +3687,10 @@ STR_6580 :Reset
|
|||
STR_6581 :Are you sure you want to reset all shortcut keys on this tab?
|
||||
STR_6582 :Open keyboard shortcuts window
|
||||
|
||||
STR_6583 :{WINDOW_COLOUR_2}Reversed Trains
|
||||
STR_6584 :Select to run trains backwards
|
||||
STR_6585 :Can’t make changes…
|
||||
|
||||
#############
|
||||
# Scenarios #
|
||||
################
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
------------------------------------------------------------------------
|
||||
- Feature: [#18713] Block brakes have speed control and brakes slower than adjacent block brakes copy block brake speed when block brake open.
|
||||
- Feature: [#19276] Add Powered Lifthill to Giga Coaster.
|
||||
- Feature: [#19305] Add new Reversed Trains ride setting to run trains backwards.
|
||||
- Feature: [#19305] [Plugin] Add “Car.isReversed” to allow individual ride vehicles to run backwards.
|
||||
- Feature: [#19446] Add new color options to color dropdown.
|
||||
- Feature: [#19547] Add large sloped turns to hybrid coaster and single rail coaster.
|
||||
- Feature: [OpenMusic#25] Added Prehistoric ride music style.
|
||||
|
|
|
@ -2327,6 +2327,11 @@ declare global {
|
|||
* The current tilt of the car in the X/Y axis.
|
||||
*/
|
||||
bankRotation: number;
|
||||
|
||||
/**
|
||||
* Whether the car sprite is reversed or not.
|
||||
*/
|
||||
isReversed: boolean;
|
||||
|
||||
/**
|
||||
* The colour of the car.
|
||||
|
|
|
@ -126,6 +126,7 @@ enum {
|
|||
|
||||
WIDX_VEHICLE_TYPE = 14,
|
||||
WIDX_VEHICLE_TYPE_DROPDOWN,
|
||||
WIDX_VEHICLE_REVERSED_TRAINS_CHECKBOX,
|
||||
WIDX_VEHICLE_TRAINS_PREVIEW,
|
||||
WIDX_VEHICLE_TRAINS,
|
||||
WIDX_VEHICLE_TRAINS_INCREASE,
|
||||
|
@ -264,9 +265,10 @@ static Widget window_ride_vehicle_widgets[] = {
|
|||
MAIN_RIDE_WIDGETS,
|
||||
MakeWidget ({ 7, 50}, {302, 12}, WindowWidgetType::DropdownMenu, WindowColour::Secondary ),
|
||||
MakeWidget ({297, 51}, { 11, 10}, WindowWidgetType::Button, WindowColour::Secondary, STR_DROPDOWN_GLYPH ),
|
||||
MakeWidget ({ 7, 147}, {302, 43}, WindowWidgetType::Scroll, WindowColour::Secondary, STR_EMPTY ),
|
||||
MakeSpinnerWidgets({ 7, 196}, {145, 12}, WindowWidgetType::Spinner, WindowColour::Secondary, STR_RIDE_VEHICLE_COUNT, STR_MAX_VEHICLES_TIP ),
|
||||
MakeSpinnerWidgets({164, 196}, {145, 12}, WindowWidgetType::Spinner, WindowColour::Secondary, STR_1_CAR_PER_TRAIN, STR_MAX_CARS_PER_TRAIN_TIP),
|
||||
MakeWidget ({ 7, 137}, {302, 12}, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_OPTION_REVERSE_TRAINS, STR_OPTION_REVERSE_TRAINS_TIP ),
|
||||
MakeWidget ({ 7, 154}, {302, 43}, WindowWidgetType::Scroll, WindowColour::Secondary, STR_EMPTY ),
|
||||
MakeSpinnerWidgets({ 7, 203}, {145, 12}, WindowWidgetType::Spinner, WindowColour::Secondary, STR_RIDE_VEHICLE_COUNT, STR_MAX_VEHICLES_TIP ),
|
||||
MakeSpinnerWidgets({164, 203}, {145, 12}, WindowWidgetType::Spinner, WindowColour::Secondary, STR_1_CAR_PER_TRAIN, STR_MAX_CARS_PER_TRAIN_TIP),
|
||||
WIDGETS_END,
|
||||
};
|
||||
|
||||
|
@ -2670,7 +2672,7 @@ static void WindowRideVehicleMouseup(WindowBase* w, WidgetIndex widgetIndex)
|
|||
*/
|
||||
static void WindowRideVehicleResize(WindowBase* w)
|
||||
{
|
||||
WindowSetResize(*w, 316, 214, 316, 214);
|
||||
WindowSetResize(*w, 316, 221, 316, 221);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2688,6 +2690,9 @@ static void WindowRideVehicleMousedown(WindowBase* w, WidgetIndex widgetIndex, W
|
|||
case WIDX_VEHICLE_TYPE_DROPDOWN:
|
||||
WindowRideShowVehicleTypeDropdown(w, &w->widgets[widgetIndex]);
|
||||
break;
|
||||
case WIDX_VEHICLE_REVERSED_TRAINS_CHECKBOX:
|
||||
ride->SetReversedTrains(!ride->HasLifecycleFlag(RIDE_LIFECYCLE_REVERSED_TRAINS));
|
||||
break;
|
||||
case WIDX_VEHICLE_TRAINS_INCREASE:
|
||||
if (ride->NumTrains < OpenRCT2::Limits::MaxTrainsPerRide)
|
||||
ride->SetNumTrains(ride->NumTrains + 1);
|
||||
|
@ -2853,6 +2858,24 @@ static void WindowRideVehicleInvalidate(WindowBase* w)
|
|||
window_ride_vehicle_widgets[WIDX_VEHICLE_CARS_PER_TRAIN_DECREASE].type = WindowWidgetType::Empty;
|
||||
}
|
||||
|
||||
if (ride->GetRideTypeDescriptor().HasFlag(RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS)
|
||||
|| (gCheatsDisableTrainLengthLimit && !ride->GetRideTypeDescriptor().HasFlag(RIDE_TYPE_FLAG_FLAT_RIDE)))
|
||||
{
|
||||
window_ride_vehicle_widgets[WIDX_VEHICLE_REVERSED_TRAINS_CHECKBOX].type = WindowWidgetType::Checkbox;
|
||||
if (ride->HasLifecycleFlag(RIDE_LIFECYCLE_REVERSED_TRAINS))
|
||||
{
|
||||
w->pressed_widgets |= (1uLL << WIDX_VEHICLE_REVERSED_TRAINS_CHECKBOX);
|
||||
}
|
||||
else
|
||||
{
|
||||
w->pressed_widgets &= ~(1uLL << WIDX_VEHICLE_REVERSED_TRAINS_CHECKBOX);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
window_ride_vehicle_widgets[WIDX_VEHICLE_REVERSED_TRAINS_CHECKBOX].type = WindowWidgetType::Empty;
|
||||
}
|
||||
|
||||
auto ft = Formatter::Common();
|
||||
ft.Increment(6);
|
||||
ft.Add<uint16_t>(carsPerTrain);
|
||||
|
@ -2979,7 +3002,11 @@ static void WindowRideVehicleScrollpaint(WindowBase* w, DrawPixelInfo& dpi, int3
|
|||
int32_t startX = std::max(2, (widget->width() - ((ride->NumTrains - 1) * 36)) / 2 - 25);
|
||||
int32_t startY = widget->height() - 4;
|
||||
|
||||
const auto& firstCarEntry = rideEntry->Cars[RideEntryGetVehicleAtPosition(ride->subtype, ride->num_cars_per_train, 0)];
|
||||
bool isReversed = ride->HasLifecycleFlag(RIDE_LIFECYCLE_REVERSED_TRAINS);
|
||||
int32_t carIndex = (isReversed) ? ride->num_cars_per_train - 1 : 0;
|
||||
|
||||
const auto& firstCarEntry = rideEntry
|
||||
->Cars[RideEntryGetVehicleAtPosition(ride->subtype, ride->num_cars_per_train, carIndex)];
|
||||
startY += firstCarEntry.tab_height;
|
||||
|
||||
// For each train
|
||||
|
@ -2994,7 +3021,10 @@ static void WindowRideVehicleScrollpaint(WindowBase* w, DrawPixelInfo& dpi, int3
|
|||
static_assert(std::numeric_limits<decltype(ride->num_cars_per_train)>::max() <= std::size(trainCarImages));
|
||||
for (int32_t j = 0; j < ride->num_cars_per_train; j++)
|
||||
{
|
||||
const auto& carEntry = rideEntry->Cars[RideEntryGetVehicleAtPosition(ride->subtype, ride->num_cars_per_train, j)];
|
||||
carIndex = (isReversed) ? (ride->num_cars_per_train - 1) - j : j;
|
||||
|
||||
const auto& carEntry = rideEntry
|
||||
->Cars[RideEntryGetVehicleAtPosition(ride->subtype, ride->num_cars_per_train, carIndex)];
|
||||
x += carEntry.spacing / 17432;
|
||||
y -= (carEntry.spacing / 2) / 17432;
|
||||
|
||||
|
@ -3009,12 +3039,19 @@ static void WindowRideVehicleScrollpaint(WindowBase* w, DrawPixelInfo& dpi, int3
|
|||
vehicleColourIndex = i;
|
||||
break;
|
||||
case VEHICLE_COLOUR_SCHEME_PER_VEHICLE:
|
||||
vehicleColourIndex = j;
|
||||
vehicleColourIndex = carIndex;
|
||||
break;
|
||||
}
|
||||
VehicleColour vehicleColour = RideGetVehicleColour(*ride, vehicleColourIndex);
|
||||
|
||||
ImageIndex imageIndex = carEntry.SpriteByYaw(OpenRCT2::Entity::Yaw::BaseRotation / 2, SpriteGroupType::SlopeFlat);
|
||||
if (isReversed)
|
||||
{
|
||||
auto baseRotation = carEntry.NumRotationSprites(SpriteGroupType::SlopeFlat);
|
||||
imageIndex = carEntry.SpriteByYaw(
|
||||
(imageIndex + (baseRotation / 2)) & (baseRotation - 1), SpriteGroupType::SlopeFlat);
|
||||
}
|
||||
|
||||
imageIndex &= carEntry.TabRotationMask;
|
||||
imageIndex *= carEntry.base_num_frames;
|
||||
imageIndex += carEntry.base_image_id;
|
||||
|
|
|
@ -29,6 +29,7 @@ constexpr static StringId SetVehicleTypeErrorTitle[] = {
|
|||
STR_RIDE_SET_VEHICLE_SET_NUM_TRAINS_FAIL,
|
||||
STR_RIDE_SET_VEHICLE_SET_NUM_CARS_PER_TRAIN_FAIL,
|
||||
STR_RIDE_SET_VEHICLE_TYPE_FAIL,
|
||||
STR_RIDE_SET_VEHICLE_REVERSED_FAIL,
|
||||
};
|
||||
|
||||
RideSetVehicleAction::RideSetVehicleAction(RideId rideIndex, RideSetVehicleType type, uint16_t value, uint8_t colour)
|
||||
|
@ -87,6 +88,7 @@ GameActions::Result RideSetVehicleAction::Query() const
|
|||
{
|
||||
case RideSetVehicleType::NumTrains:
|
||||
case RideSetVehicleType::NumCarsPerTrain:
|
||||
case RideSetVehicleType::TrainsReversed:
|
||||
break;
|
||||
case RideSetVehicleType::RideEntry:
|
||||
{
|
||||
|
@ -184,6 +186,15 @@ GameActions::Result RideSetVehicleAction::Execute() const
|
|||
}
|
||||
break;
|
||||
}
|
||||
case RideSetVehicleType::TrainsReversed:
|
||||
{
|
||||
RideClearForConstruction(*ride);
|
||||
ride->RemovePeeps();
|
||||
ride->vehicle_change_timeout = 100;
|
||||
|
||||
ride->SetLifecycleFlag(RIDE_LIFECYCLE_REVERSED_TRAINS, _value);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
LOG_ERROR("Unknown vehicle command. type = %d", _type);
|
||||
|
|
|
@ -16,6 +16,7 @@ enum class RideSetVehicleType : uint8_t
|
|||
NumTrains,
|
||||
NumCarsPerTrain,
|
||||
RideEntry,
|
||||
TrainsReversed,
|
||||
Count,
|
||||
};
|
||||
|
||||
|
|
|
@ -3748,19 +3748,20 @@ void Guest::UpdateRideAdvanceThroughEntrance()
|
|||
}
|
||||
|
||||
auto destination = GetDestination();
|
||||
auto loadPositionWithReversal = (vehicle->HasFlag(VehicleFlags::CarIsReversed)) ? -load_position : load_position;
|
||||
switch (vehicle->Orientation / 8)
|
||||
{
|
||||
case 0:
|
||||
destination.x = vehicle->x - load_position;
|
||||
destination.x = vehicle->x - loadPositionWithReversal;
|
||||
break;
|
||||
case 1:
|
||||
destination.y = vehicle->y + load_position;
|
||||
destination.y = vehicle->y + loadPositionWithReversal;
|
||||
break;
|
||||
case 2:
|
||||
destination.x = vehicle->x + load_position;
|
||||
destination.x = vehicle->x + loadPositionWithReversal;
|
||||
break;
|
||||
case 3:
|
||||
destination.y = vehicle->y - load_position;
|
||||
destination.y = vehicle->y - loadPositionWithReversal;
|
||||
break;
|
||||
}
|
||||
SetDestination(destination);
|
||||
|
|
|
@ -3986,6 +3986,10 @@ enum : uint16_t
|
|||
|
||||
STR_SHORTCUT_OPEN_KEYBOARD_SHORTCUTS_WINDOW = 6582,
|
||||
|
||||
STR_OPTION_REVERSE_TRAINS = 6583,
|
||||
STR_OPTION_REVERSE_TRAINS_TIP = 6584,
|
||||
STR_RIDE_SET_VEHICLE_REVERSED_FAIL = 6585,
|
||||
|
||||
// Have to include resource strings (from scenarios and objects) for the time being now that language is partially working
|
||||
/* MAX_STR_COUNT = 32768 */ // MAX_STR_COUNT - upper limit for number of strings, not the current count strings
|
||||
};
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
// It is used for making sure only compatible builds get connected, even within
|
||||
// single OpenRCT2 version.
|
||||
|
||||
#define NETWORK_STREAM_VERSION "12"
|
||||
#define NETWORK_STREAM_VERSION "13"
|
||||
|
||||
#define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@ struct ObjectRepositoryItem;
|
|||
namespace OpenRCT2
|
||||
{
|
||||
// Current version that is saved.
|
||||
constexpr uint32_t PARK_FILE_CURRENT_VERSION = 29;
|
||||
constexpr uint32_t PARK_FILE_CURRENT_VERSION = 30;
|
||||
|
||||
// The minimum version that is forwards compatible with the current version.
|
||||
constexpr uint32_t PARK_FILE_MIN_VERSION = 28;
|
||||
constexpr uint32_t PARK_FILE_MIN_VERSION = 30;
|
||||
|
||||
// The minimum version that is backwards compatible with the current version.
|
||||
// If this is increased beyond 0, uncomment the checks in ParkFile.cpp and Context.cpp!
|
||||
|
|
|
@ -3370,6 +3370,12 @@ static Vehicle* VehicleCreateCar(
|
|||
}
|
||||
}
|
||||
vehicle->SetState(Vehicle::Status::MovingToEndOfStation);
|
||||
|
||||
if (ride.HasLifecycleFlag(RIDE_LIFECYCLE_REVERSED_TRAINS))
|
||||
{
|
||||
vehicle->SubType = carIndex == (ride.num_cars_per_train - 1) ? Vehicle::Type::Head : Vehicle::Type::Tail;
|
||||
vehicle->SetFlag(VehicleFlags::CarIsReversed);
|
||||
}
|
||||
}
|
||||
|
||||
// Loc6DDD5E:
|
||||
|
@ -3387,11 +3393,14 @@ static TrainReference VehicleCreateTrain(
|
|||
Ride& ride, const CoordsXYZ& trainPos, int32_t vehicleIndex, int32_t* remainingDistance, TrackElement* trackElement)
|
||||
{
|
||||
TrainReference train = { nullptr, nullptr };
|
||||
bool isReversed = ride.HasLifecycleFlag(RIDE_LIFECYCLE_REVERSED_TRAINS);
|
||||
|
||||
for (int32_t carIndex = 0; carIndex < ride.num_cars_per_train; carIndex++)
|
||||
{
|
||||
auto vehicle = RideEntryGetVehicleAtPosition(ride.subtype, ride.num_cars_per_train, carIndex);
|
||||
auto car = VehicleCreateCar(ride, vehicle, carIndex, vehicleIndex, trainPos, remainingDistance, trackElement);
|
||||
auto carSpawnIndex = (isReversed) ? (ride.num_cars_per_train - 1) - carIndex : carIndex;
|
||||
|
||||
auto vehicle = RideEntryGetVehicleAtPosition(ride.subtype, ride.num_cars_per_train, carSpawnIndex);
|
||||
auto car = VehicleCreateCar(ride, vehicle, carSpawnIndex, vehicleIndex, trainPos, remainingDistance, trackElement);
|
||||
if (car == nullptr)
|
||||
break;
|
||||
|
||||
|
@ -4661,7 +4670,15 @@ void RideUpdateVehicleColours(const Ride& ride)
|
|||
colours = ride.vehicle_colours[i];
|
||||
break;
|
||||
case RIDE_COLOUR_SCHEME_MODE_DIFFERENT_PER_CAR:
|
||||
colours = ride.vehicle_colours[std::min(carIndex, OpenRCT2::Limits::MaxCarsPerTrain - 1)];
|
||||
if (vehicle->HasFlag(VehicleFlags::CarIsReversed))
|
||||
{
|
||||
colours = ride.vehicle_colours[std::min(
|
||||
(ride.num_cars_per_train - 1) - carIndex, OpenRCT2::Limits::MaxCarsPerTrain - 1)];
|
||||
}
|
||||
else
|
||||
{
|
||||
colours = ride.vehicle_colours[std::min(carIndex, OpenRCT2::Limits::MaxCarsPerTrain - 1)];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -5146,6 +5163,12 @@ void Ride::SetNumCarsPerVehicle(int32_t numCarsPerVehicle)
|
|||
GameActions::Execute(&rideSetVehicleAction);
|
||||
}
|
||||
|
||||
void Ride::SetReversedTrains(bool reverseTrains)
|
||||
{
|
||||
auto rideSetVehicleAction = RideSetVehicleAction(id, RideSetVehicleType::TrainsReversed, reverseTrains);
|
||||
GameActions::Execute(&rideSetVehicleAction);
|
||||
}
|
||||
|
||||
void Ride::SetToDefaultInspectionInterval()
|
||||
{
|
||||
uint8_t defaultInspectionInterval = gConfigGeneral.DefaultInspectionInterval;
|
||||
|
|
|
@ -327,6 +327,7 @@ public:
|
|||
|
||||
void SetNumTrains(int32_t numTrains);
|
||||
void SetNumCarsPerVehicle(int32_t numCarsPerVehicle);
|
||||
void SetReversedTrains(bool reversedTrains);
|
||||
void UpdateMaxVehicles();
|
||||
void UpdateNumberOfCircuits();
|
||||
|
||||
|
@ -455,6 +456,7 @@ enum
|
|||
RIDE_LIFECYCLE_SIX_FLAGS_DEPRECATED = 1 << 19, // Not used anymore
|
||||
RIDE_LIFECYCLE_FIXED_RATINGS = 1 << 20, // When set, the ratings will not be updated (useful for hacked rides).
|
||||
RIDE_LIFECYCLE_RANDOM_SHOP_COLOURS = 1 << 21,
|
||||
RIDE_LIFECYCLE_REVERSED_TRAINS = 1 << 22,
|
||||
};
|
||||
|
||||
// Constants used by the ride_type->flags property at 0x008
|
||||
|
|
|
@ -347,6 +347,7 @@ enum ride_type_flags : uint64_t
|
|||
RIDE_TYPE_FLAG_IS_FIRST_AID = (1uLL << 57),
|
||||
RIDE_TYPE_FLAG_IS_MAZE = (1uLL << 58),
|
||||
RIDE_TYPE_FLAG_IS_SPIRAL_SLIDE = (1uLL << 59),
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS = (1uLL << 60),
|
||||
};
|
||||
|
||||
// Set on ride types that have a main colour, additional colour and support colour.
|
||||
|
|
|
@ -6351,6 +6351,10 @@ static uint8_t GetSwingSprite(int16_t swingPosition)
|
|||
void Vehicle::UpdateSwingingCar()
|
||||
{
|
||||
int32_t dword_F64E08 = abs(_vehicleVelocityF64E08);
|
||||
if (HasFlag(VehicleFlags::CarIsReversed))
|
||||
{
|
||||
dword_F64E08 *= -1;
|
||||
}
|
||||
SwingSpeed += (-SwingPosition) >> 6;
|
||||
int32_t swingAmount = GetSwingAmount();
|
||||
if (swingAmount < 0)
|
||||
|
|
|
@ -450,6 +450,7 @@ namespace VehicleFlags
|
|||
constexpr uint32_t MoveSingleCar = (1 << 14); // OpenRCT2 Flag: Used to override UpdateMotion to move the position of
|
||||
// an individual car on a train
|
||||
constexpr uint32_t Crashed = (1 << 15); // Car displays as smoke plume
|
||||
constexpr uint32_t CarIsReversed = (1 << 16); // Car is displayed running backwards
|
||||
} // namespace VehicleFlags
|
||||
|
||||
enum
|
||||
|
|
|
@ -935,6 +935,21 @@ const VehicleBoundBox VehicleBoundboxes[16][224] = {
|
|||
}
|
||||
};
|
||||
|
||||
// Opposite Pitch values for reversed cars
|
||||
const uint8_t PitchInvertTable[] = {
|
||||
0, // Flat Track
|
||||
5, 6, 7, 8, 1, 2, 3, 4, // Slopes 1
|
||||
17, 18, 19, 20, 21, 22, 23, 16, 9, 10, 11, 12, 13, 14, 15, // Vertical Loop
|
||||
29, 30, 31, 32, 33, 24, 25, 26, 27, 28, 39, 40, 41, 42, 43, 34, 35, 36, 37, 38, // Corkscrews
|
||||
0, 0, 0, 0, 0, 0, // Helices
|
||||
53, 54, 55, 50, 51, 52, // Slopes 2
|
||||
56, 57, 58, // Zero-G Rolls
|
||||
0 // 59 = Spiral Lift. This is the only pitch with no corresponding pitch down, so flat will be used instead
|
||||
};
|
||||
|
||||
// Opposite Bank values for reversed cars
|
||||
const uint8_t BankInvertTable[] = { 0, 3, 4, 1, 2, 10, 11, 12, 13, 14, 5, 6, 7, 8, 9, 15, 18, 19, 16, 17 };
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region VehiclePaintUtil
|
||||
|
@ -1028,6 +1043,12 @@ static void VehicleSpritePaintRestraints(
|
|||
vehicle_sprite_paint(session, vehicle, spriteNum, VehicleBoundboxes[carEntry->draw_order][boundingBoxNum], z, carEntry);
|
||||
}
|
||||
|
||||
// Returns the opposite of the bank angle for reversed cars, normal bank angle otherwise
|
||||
static uint8_t GetPaintBankRotation(const Vehicle* vehicle)
|
||||
{
|
||||
return (vehicle->HasFlag(VehicleFlags::CarIsReversed)) ? BankInvertTable[vehicle->bank_rotation] : vehicle->bank_rotation;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region FlatSlope
|
||||
|
@ -1349,7 +1370,7 @@ static void VehiclePitchFlat(
|
|||
PaintSession& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const CarEntry* carEntry)
|
||||
{
|
||||
// 0x009A3DE4:
|
||||
switch (vehicle->bank_rotation)
|
||||
switch (GetPaintBankRotation(vehicle))
|
||||
{
|
||||
case 0:
|
||||
VehiclePitchFlatUnbanked(session, vehicle, imageDirection, z, carEntry);
|
||||
|
@ -1506,7 +1527,7 @@ static void VehiclePitchUp12(
|
|||
PaintSession& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const CarEntry* carEntry)
|
||||
{
|
||||
// 0x009A3C04:
|
||||
switch (vehicle->bank_rotation)
|
||||
switch (GetPaintBankRotation(vehicle))
|
||||
{
|
||||
case 0:
|
||||
VehiclePitchUp12Unbanked(session, vehicle, imageDirection, z, carEntry);
|
||||
|
@ -1788,7 +1809,7 @@ static void VehiclePitchUp25(
|
|||
PaintSession& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const CarEntry* carEntry)
|
||||
{
|
||||
// 0x009A3CA4:
|
||||
switch (vehicle->bank_rotation)
|
||||
switch (GetPaintBankRotation(vehicle))
|
||||
{
|
||||
case 0:
|
||||
VehiclePitchUp25Unbanked(session, vehicle, imageDirection, z, carEntry);
|
||||
|
@ -1999,7 +2020,7 @@ static void VehiclePitchUp42BankedRight90(
|
|||
static void VehiclePitchUp42(
|
||||
PaintSession& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const CarEntry* carEntry)
|
||||
{
|
||||
switch (vehicle->bank_rotation)
|
||||
switch (GetPaintBankRotation(vehicle))
|
||||
{
|
||||
case 0:
|
||||
VehiclePitchUp42Unbanked(session, vehicle, imageDirection, z, carEntry);
|
||||
|
@ -2082,7 +2103,7 @@ static void VehiclePitchUp60BankedRight22(
|
|||
static void VehiclePitchUp60(
|
||||
PaintSession& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const CarEntry* carEntry)
|
||||
{
|
||||
switch (vehicle->bank_rotation)
|
||||
switch (GetPaintBankRotation(vehicle))
|
||||
{
|
||||
case 0:
|
||||
VehiclePitchUp60Unbanked(session, vehicle, imageDirection, z, carEntry);
|
||||
|
@ -2189,7 +2210,7 @@ static void VehiclePitchDown12(
|
|||
PaintSession& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const CarEntry* carEntry)
|
||||
{
|
||||
// 0x009A3C54:
|
||||
switch (vehicle->bank_rotation)
|
||||
switch (GetPaintBankRotation(vehicle))
|
||||
{
|
||||
case 0:
|
||||
VehiclePitchDown12Unbanked(session, vehicle, imageDirection, z, carEntry);
|
||||
|
@ -2506,7 +2527,7 @@ static void VehiclePitchDown25(
|
|||
PaintSession& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const CarEntry* carEntry)
|
||||
{
|
||||
// 0x009A3CF4:
|
||||
switch (vehicle->bank_rotation)
|
||||
switch (GetPaintBankRotation(vehicle))
|
||||
{
|
||||
case 0:
|
||||
VehiclePitchDown25Unbanked(session, vehicle, imageDirection, z, carEntry);
|
||||
|
@ -2716,7 +2737,7 @@ static void VehiclePitchDown42BankedRight90(
|
|||
static void VehiclePitchDown42(
|
||||
PaintSession& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const CarEntry* carEntry)
|
||||
{
|
||||
switch (vehicle->bank_rotation)
|
||||
switch (GetPaintBankRotation(vehicle))
|
||||
{
|
||||
case 0:
|
||||
VehiclePitchDown42Unbanked(session, vehicle, imageDirection, z, carEntry);
|
||||
|
@ -2799,7 +2820,7 @@ static void VehiclePitchDown60BankedRight22(
|
|||
static void VehiclePitchDown60(
|
||||
PaintSession& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const CarEntry* carEntry)
|
||||
{
|
||||
switch (vehicle->bank_rotation)
|
||||
switch (GetPaintBankRotation(vehicle))
|
||||
{
|
||||
case 0:
|
||||
VehiclePitchDown60Unbanked(session, vehicle, imageDirection, z, carEntry);
|
||||
|
@ -3225,7 +3246,7 @@ static void VehiclePitchUp8(
|
|||
PaintSession& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const CarEntry* carEntry)
|
||||
{
|
||||
// 0x009A3D44:
|
||||
switch (vehicle->bank_rotation)
|
||||
switch (GetPaintBankRotation(vehicle))
|
||||
{
|
||||
case 0:
|
||||
VehiclePitchUp8Unbanked(session, vehicle, imageDirection, z, carEntry);
|
||||
|
@ -3467,7 +3488,7 @@ static void VehiclePitchDown8(
|
|||
PaintSession& session, const Vehicle* vehicle, int32_t imageDirection, int32_t z, const CarEntry* carEntry)
|
||||
{
|
||||
// 0x009A3D94:
|
||||
switch (vehicle->bank_rotation)
|
||||
switch (GetPaintBankRotation(vehicle))
|
||||
{
|
||||
case 0:
|
||||
VehiclePitchDown8Unbanked(session, vehicle, imageDirection, z, carEntry);
|
||||
|
@ -3907,7 +3928,17 @@ void VehicleVisualDefault(
|
|||
{
|
||||
if (vehicle->Pitch < std::size(PaintFunctionsByPitch))
|
||||
{
|
||||
PaintFunctionsByPitch[vehicle->Pitch](session, vehicle, imageDirection, z, carEntry);
|
||||
if (vehicle->HasFlag(VehicleFlags::CarIsReversed))
|
||||
{
|
||||
auto imagePitch = PitchInvertTable[vehicle->Pitch];
|
||||
auto imageYaw = (imageDirection + (OpenRCT2::Entity::Yaw::BaseRotation / 2))
|
||||
& (OpenRCT2::Entity::Yaw::BaseRotation - 1);
|
||||
PaintFunctionsByPitch[imagePitch](session, vehicle, imageYaw, z, carEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
PaintFunctionsByPitch[vehicle->Pitch](session, vehicle, imageDirection, z, carEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,8 @@ constexpr const RideTypeDescriptor ClassicMiniRollerCoasterRTD =
|
|||
SET_FIELD(TrackPaintFunction, GetTrackPaintFunctionJuniorRC),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT |
|
||||
RIDE_TYPE_FLAG_ALLOW_DOORS_ON_TRACK | RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS),
|
||||
RIDE_TYPE_FLAG_ALLOW_DOORS_ON_TRACK | RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS |
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::ContinuousCircuit, RideMode::ContinuousCircuitBlockSectioned, RideMode::ReverseInclineLaunchedShuttle)),
|
||||
SET_FIELD(DefaultMode, RideMode::ContinuousCircuit),
|
||||
SET_FIELD(OperatingSettings, { 0, 0, 0, 17, 16, -1 }),
|
||||
|
|
|
@ -26,7 +26,8 @@ constexpr const RideTypeDescriptor ClassicWoodenRollerCoasterRTD =
|
|||
SET_FIELD(TrackPaintFunction, GetTrackPaintFunctionClassicWoodenRC),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT |
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS),
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS |
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::ContinuousCircuit, RideMode::ContinuousCircuitBlockSectioned)),
|
||||
SET_FIELD(DefaultMode, RideMode::ContinuousCircuit),
|
||||
SET_FIELD(OperatingSettings, { 0, 0, 0, 0, 68, 0 }),
|
||||
|
|
|
@ -26,7 +26,8 @@ constexpr const RideTypeDescriptor CorkscrewRollerCoasterRTD =
|
|||
SET_FIELD(TrackPaintFunction, GetTrackPaintFunctionCorkscrewRC),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT |
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS),
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS |
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::ContinuousCircuit, RideMode::ContinuousCircuitBlockSectioned, RideMode::PoweredLaunchPasstrough, RideMode::PoweredLaunch, RideMode::ReverseInclineLaunchedShuttle)),
|
||||
SET_FIELD(DefaultMode, RideMode::ContinuousCircuit),
|
||||
SET_FIELD(OperatingSettings, { 10, 27, 30, 25, 25, 0 }),
|
||||
|
|
|
@ -26,7 +26,8 @@ constexpr const RideTypeDescriptor GigaCoasterRTD =
|
|||
SET_FIELD(TrackPaintFunction, GetTrackPaintFunctionGigaRC),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT |
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS | RIDE_TYPE_FLAG_ALLOW_CABLE_LIFT_HILL),
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS | RIDE_TYPE_FLAG_ALLOW_CABLE_LIFT_HILL |
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::ContinuousCircuit, RideMode::ContinuousCircuitBlockSectioned)),
|
||||
SET_FIELD(DefaultMode, RideMode::ContinuousCircuit),
|
||||
SET_FIELD(OperatingSettings, { 10, 27, 30, 17, 68, 1 }),
|
||||
|
|
|
@ -25,7 +25,8 @@ constexpr const RideTypeDescriptor HeartlineTwisterCoasterRTD =
|
|||
SET_FIELD(StartTrackPiece, TrackElemType::EndStation),
|
||||
SET_FIELD(TrackPaintFunction, GetTrackPaintFunctionHeartlineTwisterRC),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT | RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES),
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT | RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES |
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::ContinuousCircuit)),
|
||||
SET_FIELD(DefaultMode, RideMode::ContinuousCircuit),
|
||||
SET_FIELD(OperatingSettings, { 10, 27, 30, 25, 25, 0 }),
|
||||
|
|
|
@ -24,7 +24,7 @@ constexpr const RideTypeDescriptor HybridCoasterRTD =
|
|||
SET_FIELD(TrackPaintFunction, HybridRC::GetTrackPaintFunction),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_MAIN | RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_SUPPORTS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT |
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS),
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS | RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::ContinuousCircuit, RideMode::ContinuousCircuitBlockSectioned)),
|
||||
SET_FIELD(DefaultMode, RideMode::ContinuousCircuit),
|
||||
SET_FIELD(OperatingSettings, { 0, 0, 30, 15, 52, 0 }),
|
||||
|
|
|
@ -27,7 +27,8 @@ constexpr const RideTypeDescriptor HyperTwisterRTD =
|
|||
SET_FIELD(TrackPaintFunction, GetTrackPaintFunctionBolligerMabillard<METAL_SUPPORTS_TUBES>),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT |
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS),
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS |
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::ContinuousCircuit, RideMode::ContinuousCircuitBlockSectioned)),
|
||||
SET_FIELD(DefaultMode, RideMode::ContinuousCircuit),
|
||||
SET_FIELD(OperatingSettings, { 10, 27, 30, 17, 68, 0 }),
|
||||
|
|
|
@ -25,7 +25,8 @@ constexpr const RideTypeDescriptor HypercoasterRTD =
|
|||
SET_FIELD(TrackPaintFunction, GetTrackPaintFunctionCorkscrewRC),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT |
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS),
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS |
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::ContinuousCircuit, RideMode::ContinuousCircuitBlockSectioned, RideMode::PoweredLaunchPasstrough, RideMode::PoweredLaunch, RideMode::ReverseInclineLaunchedShuttle)),
|
||||
SET_FIELD(DefaultMode, RideMode::ContinuousCircuit),
|
||||
SET_FIELD(OperatingSettings, { 10, 27, 30, 25, 25, 0 }),
|
||||
|
|
|
@ -26,7 +26,8 @@ constexpr const RideTypeDescriptor InvertedImpulseCoasterRTD =
|
|||
SET_FIELD(TrackPaintFunction, GetTrackPaintFunctionInvertedImpulseRC),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT | RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES |
|
||||
RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS | RIDE_TYPE_FLAG_IS_SUSPENDED),
|
||||
RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS | RIDE_TYPE_FLAG_IS_SUSPENDED |
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::PoweredLaunchPasstrough, RideMode::PoweredLaunch)),
|
||||
SET_FIELD(DefaultMode, RideMode::PoweredLaunchPasstrough),
|
||||
SET_FIELD(OperatingSettings, { 10, 33, 30, 25, 25, 0 }),
|
||||
|
|
|
@ -26,7 +26,8 @@ constexpr const RideTypeDescriptor InvertedRollerCoasterRTD =
|
|||
SET_FIELD(TrackPaintFunction, GetTrackPaintFunctionInvertedRC),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT |
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS | RIDE_TYPE_FLAG_IS_SUSPENDED),
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS | RIDE_TYPE_FLAG_IS_SUSPENDED |
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::ContinuousCircuit, RideMode::ContinuousCircuitBlockSectioned, RideMode::PoweredLaunchPasstrough, RideMode::PoweredLaunch)),
|
||||
SET_FIELD(DefaultMode, RideMode::ContinuousCircuit),
|
||||
SET_FIELD(OperatingSettings, { 7, 27, 0, 0, 38, 0 }),
|
||||
|
|
|
@ -26,7 +26,8 @@ constexpr const RideTypeDescriptor JuniorRollerCoasterRTD =
|
|||
SET_FIELD(TrackPaintFunction, GetTrackPaintFunctionJuniorRC),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT |
|
||||
RIDE_TYPE_FLAG_ALLOW_DOORS_ON_TRACK | RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS),
|
||||
RIDE_TYPE_FLAG_ALLOW_DOORS_ON_TRACK | RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS |
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::ContinuousCircuit, RideMode::ContinuousCircuitBlockSectioned)),
|
||||
SET_FIELD(DefaultMode, RideMode::ContinuousCircuit),
|
||||
SET_FIELD(OperatingSettings, { 0, 0, 0, 17, 16, -1 }),
|
||||
|
|
|
@ -26,7 +26,8 @@ constexpr const RideTypeDescriptor LIMLaunchedRollerCoasterRTD =
|
|||
SET_FIELD(TrackPaintFunction, GetTrackPaintFunctionLimLaunchedRC),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT |
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS),
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS |
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::PoweredLaunchPasstrough, RideMode::PoweredLaunch, RideMode::PoweredLaunchBlockSectioned)),
|
||||
SET_FIELD(DefaultMode, RideMode::PoweredLaunchPasstrough),
|
||||
SET_FIELD(OperatingSettings, { 10, 31, 26, 18, 52, 0 }),
|
||||
|
|
|
@ -26,7 +26,8 @@ constexpr const RideTypeDescriptor LoopingRollerCoasterRTD =
|
|||
SET_FIELD(TrackPaintFunction, GetTrackPaintFunctionLoopingRC),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT |
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS),
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS |
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::ContinuousCircuit, RideMode::ContinuousCircuitBlockSectioned, RideMode::ReverseInclineLaunchedShuttle, RideMode::PoweredLaunchPasstrough, RideMode::PoweredLaunch)),
|
||||
SET_FIELD(DefaultMode, RideMode::ContinuousCircuit),
|
||||
SET_FIELD(OperatingSettings, { 10, 27, 26, 18, 18, 0 }),
|
||||
|
|
|
@ -26,7 +26,8 @@ constexpr const RideTypeDescriptor MineRideRTD =
|
|||
SET_FIELD(TrackPaintFunction, GetTrackPaintFunctionMineRide),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT |
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS),
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS |
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::ContinuousCircuit)),
|
||||
SET_FIELD(DefaultMode, RideMode::ContinuousCircuit),
|
||||
SET_FIELD(OperatingSettings, { 0, 0, 0, 0, 0, 0 }),
|
||||
|
|
|
@ -27,7 +27,8 @@ constexpr const RideTypeDescriptor MineTrainCoasterRTD =
|
|||
SET_FIELD(TrackPaintFunction, GetTrackPaintFunctionMineTrainRC),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT |
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS),
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS |
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::ContinuousCircuit, RideMode::ContinuousCircuitBlockSectioned)),
|
||||
SET_FIELD(DefaultMode, RideMode::ContinuousCircuit),
|
||||
SET_FIELD(OperatingSettings, { 0, 0, 0, 0, 0, 0 }),
|
||||
|
|
|
@ -26,7 +26,8 @@ constexpr const RideTypeDescriptor MiniRollerCoasterRTD =
|
|||
SET_FIELD(TrackPaintFunction, GetTrackPaintFunctionMiniRC),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT |
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS),
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS |
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::ContinuousCircuit, RideMode::ContinuousCircuitBlockSectioned)),
|
||||
SET_FIELD(DefaultMode, RideMode::ContinuousCircuit),
|
||||
SET_FIELD(OperatingSettings, { 0, 0, 0, 0, 68, 1 }),
|
||||
|
|
|
@ -27,7 +27,8 @@ constexpr const RideTypeDescriptor MultiDimensionRollerCoasterRTD =
|
|||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT |
|
||||
RIDE_TYPE_FLAG_HAS_ALTERNATIVE_TRACK_TYPE | RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES |
|
||||
RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS | RIDE_TYPE_FLAG_HAS_SEAT_ROTATION),
|
||||
RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS | RIDE_TYPE_FLAG_HAS_SEAT_ROTATION |
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::ContinuousCircuit, RideMode::ContinuousCircuitBlockSectioned)),
|
||||
SET_FIELD(DefaultMode, RideMode::ContinuousCircuit),
|
||||
SET_FIELD(OperatingSettings, { 10, 27, 30, 25, 25, 0 }),
|
||||
|
|
|
@ -24,7 +24,7 @@ constexpr const RideTypeDescriptor ReverseFreefallCoasterRTD =
|
|||
SET_FIELD(CoveredTrackPieces, {}),
|
||||
SET_FIELD(StartTrackPiece, TrackElemType::EndStation),
|
||||
SET_FIELD(TrackPaintFunction, GetTrackPaintFunctionReverseFreefallRC),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT | RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::LimPoweredLaunch)),
|
||||
SET_FIELD(DefaultMode, RideMode::LimPoweredLaunch),
|
||||
SET_FIELD(OperatingSettings, { 7, 30, 30, 40, 40, 0 }),
|
||||
|
|
|
@ -26,7 +26,8 @@ constexpr const RideTypeDescriptor SideFrictionRollerCoasterRTD =
|
|||
SET_FIELD(TrackPaintFunction, GetTrackPaintFunctionSideFrictionRC),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT |
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS),
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS |
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::ContinuousCircuit)),
|
||||
SET_FIELD(DefaultMode, RideMode::ContinuousCircuit),
|
||||
SET_FIELD(OperatingSettings, { 0, 0, 0, 0, 0, 0 }),
|
||||
|
|
|
@ -24,7 +24,8 @@ constexpr const RideTypeDescriptor SingleRailRollerCoasterRTD =
|
|||
SET_FIELD(TrackPaintFunction, SingleRailRC::GetTrackPaintFunction),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_SUPPORTS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT |
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS),
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS |
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::ContinuousCircuit, RideMode::ContinuousCircuitBlockSectioned)),
|
||||
SET_FIELD(DefaultMode, RideMode::ContinuousCircuit),
|
||||
SET_FIELD(OperatingSettings, { 0, 0, 30, 15, 52, 0 }),
|
||||
|
|
|
@ -26,7 +26,8 @@ constexpr const RideTypeDescriptor StandUpRollerCoasterRTD =
|
|||
SET_FIELD(TrackPaintFunction, GetTrackPaintFunctionStandUpRC),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT |
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS),
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS |
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::ContinuousCircuit, RideMode::ContinuousCircuitBlockSectioned, RideMode::ReverseInclineLaunchedShuttle, RideMode::PoweredLaunchPasstrough, RideMode::PoweredLaunch)),
|
||||
SET_FIELD(DefaultMode, RideMode::ContinuousCircuit),
|
||||
SET_FIELD(OperatingSettings, { 7, 27, 0, 0, 0, 0 }),
|
||||
|
|
|
@ -28,7 +28,8 @@ constexpr const RideTypeDescriptor TwisterRollerCoasterRTD =
|
|||
SET_FIELD(TrackPaintFunction, GetTrackPaintFunctionBolligerMabillard<METAL_SUPPORTS_TUBES>),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT |
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS),
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS |
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::ContinuousCircuit, RideMode::ContinuousCircuitBlockSectioned)),
|
||||
SET_FIELD(DefaultMode, RideMode::ContinuousCircuit),
|
||||
SET_FIELD(OperatingSettings, { 10, 27, 30, 17, 68, 0 }),
|
||||
|
|
|
@ -26,7 +26,8 @@ constexpr const RideTypeDescriptor WoodenRollerCoasterRTD =
|
|||
SET_FIELD(TrackPaintFunction, GetTrackPaintFunctionWoodenRC),
|
||||
SET_FIELD(Flags, RIDE_TYPE_FLAGS_TRACK_HAS_3_COLOURS | RIDE_TYPE_FLAG_HAS_LEAVE_WHEN_ANOTHER_VEHICLE_ARRIVES_AT_STATION |
|
||||
RIDE_TYPE_FLAGS_COMMON_COASTER | RIDE_TYPE_FLAGS_COMMON_COASTER_NON_ALT |
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS),
|
||||
RIDE_TYPE_FLAG_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS |
|
||||
RIDE_TYPE_FLAG_ALLOW_REVERSED_TRAINS),
|
||||
SET_FIELD(RideModes, EnumsToFlags(RideMode::ContinuousCircuit, RideMode::ContinuousCircuitBlockSectioned, RideMode::ReverseInclineLaunchedShuttle)),
|
||||
SET_FIELD(DefaultMode, RideMode::ContinuousCircuit),
|
||||
SET_FIELD(OperatingSettings, { 0, 0, 0, 0, 68, 0 }),
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace OpenRCT2
|
|||
|
||||
namespace OpenRCT2::Scripting
|
||||
{
|
||||
static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 74;
|
||||
static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 75;
|
||||
|
||||
// Versions marking breaking changes.
|
||||
static constexpr int32_t API_VERSION_33_PEEP_DEPRECATION = 33;
|
||||
|
|
|
@ -71,6 +71,7 @@ namespace OpenRCT2::Scripting
|
|||
dukglue_register_property(ctx, &ScVehicle::acceleration_get, &ScVehicle::acceleration_set, "acceleration");
|
||||
dukglue_register_property(ctx, &ScVehicle::velocity_get, &ScVehicle::velocity_set, "velocity");
|
||||
dukglue_register_property(ctx, &ScVehicle::bankRotation_get, &ScVehicle::bankRotation_set, "bankRotation");
|
||||
dukglue_register_property(ctx, &ScVehicle::isReversed_get, &ScVehicle::isReversed_set, "isReversed");
|
||||
dukglue_register_property(ctx, &ScVehicle::colours_get, &ScVehicle::colours_set, "colours");
|
||||
dukglue_register_property(ctx, &ScVehicle::trackLocation_get, &ScVehicle::trackLocation_set, "trackLocation");
|
||||
dukglue_register_property(ctx, &ScVehicle::trackProgress_get, nullptr, "trackProgress");
|
||||
|
@ -332,6 +333,28 @@ namespace OpenRCT2::Scripting
|
|||
}
|
||||
}
|
||||
|
||||
bool ScVehicle::isReversed_get() const
|
||||
{
|
||||
auto vehicle = GetVehicle();
|
||||
return vehicle != nullptr ? vehicle->HasFlag(VehicleFlags::CarIsReversed) : false;
|
||||
}
|
||||
void ScVehicle::isReversed_set(bool value)
|
||||
{
|
||||
ThrowIfGameStateNotMutable();
|
||||
auto vehicle = GetVehicle();
|
||||
if (vehicle != nullptr)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
vehicle->SetFlag(VehicleFlags::CarIsReversed);
|
||||
}
|
||||
else
|
||||
{
|
||||
vehicle->ClearFlag(VehicleFlags::CarIsReversed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DukValue ScVehicle::colours_get() const
|
||||
{
|
||||
auto ctx = GetContext()->GetScriptEngine().GetContext();
|
||||
|
|
|
@ -67,6 +67,9 @@ namespace OpenRCT2::Scripting
|
|||
uint8_t bankRotation_get() const;
|
||||
void bankRotation_set(uint8_t value);
|
||||
|
||||
bool isReversed_get() const;
|
||||
void isReversed_set(bool value);
|
||||
|
||||
DukValue colours_get() const;
|
||||
void colours_set(const DukValue& value);
|
||||
|
||||
|
|
Loading…
Reference in New Issue