1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-06 06:32:56 +01:00

Merge pull request #22164 from Gymnasiast/refactor/more-trackdesign

More small track design refactors
This commit is contained in:
Michael Steenbeek
2024-06-14 21:28:15 +02:00
committed by GitHub
16 changed files with 445 additions and 445 deletions

View File

@@ -170,7 +170,7 @@ static Widget window_install_track_widgets[] = {
// Warnings
const TrackDesign* td6 = _trackDesign.get();
if (td6->track_flags & TRACK_DESIGN_FLAG_SCENERY_UNAVAILABLE)
if (td6->trackFlags & TRACK_DESIGN_FLAG_SCENERY_UNAVAILABLE)
{
if (!gTrackDesignSceneryToggle)
{
@@ -198,7 +198,7 @@ static Widget window_install_track_widgets[] = {
{
auto ft = Formatter();
const auto* objectEntry = ObjectManagerLoadObject(&td6->vehicle_object.Entry);
const auto* objectEntry = ObjectManagerLoadObject(&td6->vehicleObject.Entry);
if (objectEntry != nullptr)
{
auto groupIndex = ObjectManagerGetLoadedObjectEntryIndex(objectEntry);
@@ -254,7 +254,7 @@ static Widget window_install_track_widgets[] = {
{
// Maximum speed
{
uint16_t speed = ((td6->max_speed << 16) * 9) >> 18;
uint16_t speed = ((td6->maxSpeed << 16) * 9) >> 18;
auto ft = Formatter();
ft.Add<uint16_t>(speed);
DrawTextBasic(dpi, screenPos, STR_MAX_SPEED, ft);
@@ -262,7 +262,7 @@ static Widget window_install_track_widgets[] = {
}
// Average speed
{
uint16_t speed = ((td6->average_speed << 16) * 9) >> 18;
uint16_t speed = ((td6->averageSpeed << 16) * 9) >> 18;
auto ft = Formatter();
ft.Add<uint16_t>(speed);
DrawTextBasic(dpi, screenPos, STR_AVERAGE_SPEED, ft);
@@ -273,7 +273,7 @@ static Widget window_install_track_widgets[] = {
// Ride length
auto ft = Formatter();
ft.Add<StringId>(STR_RIDE_LENGTH_ENTRY);
ft.Add<uint16_t>(td6->ride_length);
ft.Add<uint16_t>(td6->rideLength);
DrawTextEllipsised(dpi, screenPos, 214, STR_TRACK_LIST_RIDE_LENGTH, ft);
screenPos.y += kListRowHeight;
}
@@ -282,7 +282,7 @@ static Widget window_install_track_widgets[] = {
{
// Maximum positive vertical Gs
{
int32_t gForces = td6->max_positive_vertical_g * 32;
int32_t gForces = td6->maxPositiveVerticalG * 32;
auto ft = Formatter();
ft.Add<int32_t>(gForces);
DrawTextBasic(dpi, screenPos, STR_MAX_POSITIVE_VERTICAL_G, ft);
@@ -290,7 +290,7 @@ static Widget window_install_track_widgets[] = {
}
// Maximum negative vertical Gs
{
int32_t gForces = td6->max_negative_vertical_g * 32;
int32_t gForces = td6->maxNegativeVerticalG * 32;
auto ft = Formatter();
ft.Add<int32_t>(gForces);
DrawTextBasic(dpi, screenPos, STR_MAX_NEGATIVE_VERTICAL_G, ft);
@@ -298,16 +298,16 @@ static Widget window_install_track_widgets[] = {
}
// Maximum lateral Gs
{
int32_t gForces = td6->max_lateral_g * 32;
int32_t gForces = td6->maxLateralG * 32;
auto ft = Formatter();
ft.Add<int32_t>(gForces);
DrawTextBasic(dpi, screenPos, STR_MAX_LATERAL_G, ft);
screenPos.y += kListRowHeight;
}
if (td6->total_air_time != 0)
if (td6->totalAirTime != 0)
{
// Total air time
int32_t airTime = td6->total_air_time * 25;
int32_t airTime = td6->totalAirTime * 25;
auto ft = Formatter();
ft.Add<int32_t>(airTime);
DrawTextBasic(dpi, screenPos, STR_TOTAL_AIR_TIME, ft);
@@ -343,12 +343,12 @@ static Widget window_install_track_widgets[] = {
}
screenPos.y += 4;
if (td6->space_required_x != 0xFF)
if (td6->spaceRequiredX != 0xFF)
{
// Space required
auto ft = Formatter();
ft.Add<uint16_t>(td6->space_required_x);
ft.Add<uint16_t>(td6->space_required_y);
ft.Add<uint16_t>(td6->spaceRequiredX);
ft.Add<uint16_t>(td6->spaceRequiredY);
DrawTextBasic(dpi, screenPos, STR_TRACK_LIST_SPACE_REQUIRED, ft);
screenPos.y += kListRowHeight;
}
@@ -422,7 +422,7 @@ static Widget window_install_track_widgets[] = {
LOG_ERROR("Failed to load track (ride type null): %s", path);
return nullptr;
}
if (ObjectManagerLoadObject(&trackDesign->vehicle_object.Entry) == nullptr)
if (ObjectManagerLoadObject(&trackDesign->vehicleObject.Entry) == nullptr)
{
LOG_ERROR("Failed to load track (vehicle load fail): %s", path);
return nullptr;

View File

@@ -438,9 +438,9 @@ static Widget _trackPlaceWidgets[] = {
void DrawMiniPreviewEntrances(
const TrackDesign& td6, int32_t pass, const CoordsXY& origin, CoordsXY& min, CoordsXY& max, Direction rotation)
{
for (const auto& entrance : td6.entrance_elements)
for (const auto& entrance : td6.entranceElements)
{
auto rotatedAndOffsetEntrance = origin + entrance.Location.ToCoordsXY().Rotate(rotation);
auto rotatedAndOffsetEntrance = origin + entrance.location.ToCoordsXY().Rotate(rotation);
if (pass == 0)
{
@@ -455,7 +455,7 @@ static Widget _trackPlaceWidgets[] = {
if (DrawMiniPreviewIsPixelInBounds(pixelPosition))
{
uint8_t* pixel = DrawMiniPreviewGetPixelPtr(pixelPosition);
uint8_t colour = entrance.IsExit ? _PaletteIndexColourExit : _PaletteIndexColourEntrance;
uint8_t colour = entrance.isExit ? _PaletteIndexColourExit : _PaletteIndexColourEntrance;
for (int32_t i = 0; i < 4; i++)
{
pixel[338 + i] = colour; // x + 2, y + 2
@@ -474,7 +474,7 @@ static Widget _trackPlaceWidgets[] = {
CoordsXY curTrackStart = origin;
uint8_t curTrackRotation = rotation;
for (const auto& trackElement : td6->track_elements)
for (const auto& trackElement : td6->trackElements)
{
// Follow a single track piece shape
const auto& ted = GetTrackElementDescriptor(trackElement.Type);
@@ -545,9 +545,9 @@ static Widget _trackPlaceWidgets[] = {
void DrawMiniPreviewMaze(TrackDesign* td6, int32_t pass, const CoordsXY& origin, CoordsXY& min, CoordsXY& max)
{
uint8_t rotation = (_currentTrackPieceDirection + GetCurrentRotation()) & 3;
for (const auto& mazeElement : td6->maze_elements)
for (const auto& mazeElement : td6->mazeElements)
{
auto rotatedMazeCoords = origin + TileCoordsXY{ mazeElement.x, mazeElement.y }.ToCoordsXY().Rotate(rotation);
auto rotatedMazeCoords = origin + mazeElement.location.ToCoordsXY().Rotate(rotation);
if (pass == 0)
{

View File

@@ -136,7 +136,7 @@ static Widget _trackListWidgets[] = {
return;
}
if (_loadedTrackDesign->track_flags & TRACK_DESIGN_FLAG_SCENERY_UNAVAILABLE)
if (_loadedTrackDesign->trackFlags & TRACK_DESIGN_FLAG_SCENERY_UNAVAILABLE)
{
gTrackDesignSceneryToggle = true;
}
@@ -152,7 +152,7 @@ static Widget _trackListWidgets[] = {
else
{
if (_loadedTrackDesignIndex != TRACK_DESIGN_INDEX_UNLOADED
&& (_loadedTrackDesign->track_flags & TRACK_DESIGN_FLAG_VEHICLE_UNAVAILABLE))
&& (_loadedTrackDesign->trackFlags & TRACK_DESIGN_FLAG_VEHICLE_UNAVAILABLE))
{
ContextShowError(STR_THIS_DESIGN_WILL_BE_BUILT_WITH_AN_ALTERNATIVE_VEHICLE_TYPE, STR_NONE, {});
}
@@ -515,7 +515,7 @@ static Widget _trackListWidgets[] = {
screenPos.y = windowPos.y + tdWidget.bottom - 12;
// Warnings
if ((_loadedTrackDesign->track_flags & TRACK_DESIGN_FLAG_VEHICLE_UNAVAILABLE)
if ((_loadedTrackDesign->trackFlags & TRACK_DESIGN_FLAG_VEHICLE_UNAVAILABLE)
&& !(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER))
{
// Vehicle design not available
@@ -523,7 +523,7 @@ static Widget _trackListWidgets[] = {
screenPos.y -= kScrollableRowHeight;
}
if (_loadedTrackDesign->track_flags & TRACK_DESIGN_FLAG_SCENERY_UNAVAILABLE)
if (_loadedTrackDesign->trackFlags & TRACK_DESIGN_FLAG_SCENERY_UNAVAILABLE)
{
if (!gTrackDesignSceneryToggle)
{
@@ -576,13 +576,13 @@ static Widget _trackListWidgets[] = {
{
// Maximum speed
ft = Formatter();
ft.Add<uint16_t>(((_loadedTrackDesign->max_speed << 16) * 9) >> 18);
ft.Add<uint16_t>(((_loadedTrackDesign->maxSpeed << 16) * 9) >> 18);
DrawTextBasic(dpi, screenPos, STR_MAX_SPEED, ft);
screenPos.y += kListRowHeight;
// Average speed
ft = Formatter();
ft.Add<uint16_t>(((_loadedTrackDesign->average_speed << 16) * 9) >> 18);
ft.Add<uint16_t>(((_loadedTrackDesign->averageSpeed << 16) * 9) >> 18);
DrawTextBasic(dpi, screenPos, STR_AVERAGE_SPEED, ft);
screenPos.y += kListRowHeight;
}
@@ -590,7 +590,7 @@ static Widget _trackListWidgets[] = {
// Ride length
ft = Formatter();
ft.Add<StringId>(STR_RIDE_LENGTH_ENTRY);
ft.Add<uint16_t>(_loadedTrackDesign->ride_length);
ft.Add<uint16_t>(_loadedTrackDesign->rideLength);
DrawTextEllipsised(dpi, screenPos, 214, STR_TRACK_LIST_RIDE_LENGTH, ft);
screenPos.y += kListRowHeight;
}
@@ -599,27 +599,27 @@ static Widget _trackListWidgets[] = {
{
// Maximum positive vertical Gs
ft = Formatter();
ft.Add<int32_t>(_loadedTrackDesign->max_positive_vertical_g * 32);
ft.Add<int32_t>(_loadedTrackDesign->maxPositiveVerticalG * 32);
DrawTextBasic(dpi, screenPos, STR_MAX_POSITIVE_VERTICAL_G, ft);
screenPos.y += kListRowHeight;
// Maximum negative vertical Gs
ft = Formatter();
ft.Add<int32_t>(_loadedTrackDesign->max_negative_vertical_g * 32);
ft.Add<int32_t>(_loadedTrackDesign->maxNegativeVerticalG * 32);
DrawTextBasic(dpi, screenPos, STR_MAX_NEGATIVE_VERTICAL_G, ft);
screenPos.y += kListRowHeight;
// Maximum lateral Gs
ft = Formatter();
ft.Add<int32_t>(_loadedTrackDesign->max_lateral_g * 32);
ft.Add<int32_t>(_loadedTrackDesign->maxLateralG * 32);
DrawTextBasic(dpi, screenPos, STR_MAX_LATERAL_G, ft);
screenPos.y += kListRowHeight;
if (_loadedTrackDesign->total_air_time != 0)
if (_loadedTrackDesign->totalAirTime != 0)
{
// Total air time
ft = Formatter();
ft.Add<int32_t>(_loadedTrackDesign->total_air_time * 25);
ft.Add<int32_t>(_loadedTrackDesign->totalAirTime * 25);
DrawTextBasic(dpi, screenPos, STR_TOTAL_AIR_TIME, ft);
screenPos.y += kListRowHeight;
}
@@ -635,7 +635,7 @@ static Widget _trackListWidgets[] = {
// Drop height is multiplied by 0.75
ft = Formatter();
ft.Add<uint16_t>((_loadedTrackDesign->highest_drop_height * 3) / 4);
ft.Add<uint16_t>((_loadedTrackDesign->highestDropHeight * 3) / 4);
DrawTextBasic(dpi, screenPos, STR_HIGHEST_DROP_HEIGHT, ft);
screenPos.y += kListRowHeight;
}
@@ -655,12 +655,12 @@ static Widget _trackListWidgets[] = {
screenPos.y += 4;
}
if (_loadedTrackDesign->space_required_x != 0xFF)
if (_loadedTrackDesign->spaceRequiredX != 0xFF)
{
// Space required
ft = Formatter();
ft.Add<uint16_t>(_loadedTrackDesign->space_required_x);
ft.Add<uint16_t>(_loadedTrackDesign->space_required_y);
ft.Add<uint16_t>(_loadedTrackDesign->spaceRequiredX);
ft.Add<uint16_t>(_loadedTrackDesign->spaceRequiredY);
DrawTextBasic(dpi, screenPos, STR_TRACK_LIST_SPACE_REQUIRED, ft);
screenPos.y += kListRowHeight;
}

View File

@@ -66,7 +66,7 @@ GameActions::Result TrackDesignAction::Query() const
auto& gameState = GetGameState();
auto& objManager = GetContext()->GetObjectManager();
auto entryIndex = objManager.GetLoadedObjectEntryIndex(_td.vehicle_object);
auto entryIndex = objManager.GetLoadedObjectEntryIndex(_td.vehicleObject);
if (entryIndex == OBJECT_ENTRY_INDEX_NULL)
{
// Force a fallback if the entry is not invented yet a td6 of it is selected,
@@ -140,7 +140,7 @@ GameActions::Result TrackDesignAction::Execute() const
auto& gameState = GetGameState();
auto& objManager = GetContext()->GetObjectManager();
auto entryIndex = objManager.GetLoadedObjectEntryIndex(_td.vehicle_object);
auto entryIndex = objManager.GetLoadedObjectEntryIndex(_td.vehicleObject);
if (entryIndex != OBJECT_ENTRY_INDEX_NULL)
{
// Force a fallback if the entry is not invented yet a track design using it is selected.
@@ -224,21 +224,20 @@ GameActions::Result TrackDesignAction::Execute() const
GameActions::ExecuteNested(&rideSetVehicleAction);
}
SetOperatingSettingNested(ride->id, RideSetSetting::Mode, static_cast<uint8_t>(_td.ride_mode), GAME_COMMAND_FLAG_APPLY);
auto rideSetVehicleAction2 = RideSetVehicleAction(ride->id, RideSetVehicleType::NumTrains, _td.number_of_trains);
SetOperatingSettingNested(ride->id, RideSetSetting::Mode, static_cast<uint8_t>(_td.rideMode), GAME_COMMAND_FLAG_APPLY);
auto rideSetVehicleAction2 = RideSetVehicleAction(ride->id, RideSetVehicleType::NumTrains, _td.numberOfTrains);
GameActions::ExecuteNested(&rideSetVehicleAction2);
auto rideSetVehicleAction3 = RideSetVehicleAction(
ride->id, RideSetVehicleType::NumCarsPerTrain, _td.number_of_cars_per_train);
auto rideSetVehicleAction3 = RideSetVehicleAction(ride->id, RideSetVehicleType::NumCarsPerTrain, _td.numberOfCarsPerTrain);
GameActions::ExecuteNested(&rideSetVehicleAction3);
SetOperatingSettingNested(ride->id, RideSetSetting::Departure, _td.depart_flags, GAME_COMMAND_FLAG_APPLY);
SetOperatingSettingNested(ride->id, RideSetSetting::MinWaitingTime, _td.min_waiting_time, GAME_COMMAND_FLAG_APPLY);
SetOperatingSettingNested(ride->id, RideSetSetting::MaxWaitingTime, _td.max_waiting_time, GAME_COMMAND_FLAG_APPLY);
SetOperatingSettingNested(ride->id, RideSetSetting::Operation, _td.operation_setting, GAME_COMMAND_FLAG_APPLY);
SetOperatingSettingNested(ride->id, RideSetSetting::LiftHillSpeed, _td.lift_hill_speed & 0x1F, GAME_COMMAND_FLAG_APPLY);
SetOperatingSettingNested(ride->id, RideSetSetting::Departure, _td.departFlags, GAME_COMMAND_FLAG_APPLY);
SetOperatingSettingNested(ride->id, RideSetSetting::MinWaitingTime, _td.minWaitingTime, GAME_COMMAND_FLAG_APPLY);
SetOperatingSettingNested(ride->id, RideSetSetting::MaxWaitingTime, _td.maxWaitingTime, GAME_COMMAND_FLAG_APPLY);
SetOperatingSettingNested(ride->id, RideSetSetting::Operation, _td.operationSetting, GAME_COMMAND_FLAG_APPLY);
SetOperatingSettingNested(ride->id, RideSetSetting::LiftHillSpeed, _td.liftHillSpeed & 0x1F, GAME_COMMAND_FLAG_APPLY);
uint8_t num_circuits = _td.num_circuits;
uint8_t num_circuits = _td.numCircuits;
if (num_circuits == 0)
{
num_circuits = 1;
@@ -246,9 +245,9 @@ GameActions::Result TrackDesignAction::Execute() const
SetOperatingSettingNested(ride->id, RideSetSetting::NumCircuits, num_circuits, GAME_COMMAND_FLAG_APPLY);
ride->SetToDefaultInspectionInterval();
ride->lifecycle_flags |= RIDE_LIFECYCLE_NOT_CUSTOM_DESIGN;
ride->colour_scheme_type = _td.colour_scheme;
ride->colour_scheme_type = _td.colourScheme;
ride->entrance_style = objManager.GetLoadedObjectEntryIndex(_td.StationObjectIdentifier);
ride->entrance_style = objManager.GetLoadedObjectEntryIndex(_td.stationObjectIdentifier);
if (ride->entrance_style == OBJECT_ENTRY_INDEX_NULL)
{
ride->entrance_style = gameState.LastEntranceStyle;
@@ -256,14 +255,14 @@ GameActions::Result TrackDesignAction::Execute() const
for (int32_t i = 0; i < Limits::kNumColourSchemes; i++)
{
ride->track_colour[i].main = _td.track_spine_colour[i];
ride->track_colour[i].additional = _td.track_rail_colour[i];
ride->track_colour[i].supports = _td.track_support_colour[i];
ride->track_colour[i].main = _td.trackSpineColour[i];
ride->track_colour[i].additional = _td.trackRailColour[i];
ride->track_colour[i].supports = _td.trackSupportColour[i];
}
for (size_t i = 0; i < Limits::kMaxVehicleColours; i++)
{
ride->vehicle_colours[i] = _td.vehicle_colours[i];
ride->vehicle_colours[i] = _td.vehicleColours[i];
}
for (int32_t count = 1; count == 1 || r.Error != GameActions::Status::Ok; ++count)

View File

@@ -703,19 +703,20 @@ template<> struct DataSerializerTraitsT<TrackDesignMazeElement>
{
static void encode(OpenRCT2::IStream* stream, const TrackDesignMazeElement& val)
{
uint32_t temp = ByteSwapBE(val.all);
stream->Write(&temp);
stream->Write(&val.location);
stream->Write(&val.mazeEntry);
}
static void decode(OpenRCT2::IStream* stream, TrackDesignMazeElement& val)
{
uint32_t temp;
stream->Read(&temp);
val.all = ByteSwapBE(temp);
stream->Read(&val.location);
stream->Read(&val.mazeEntry);
}
static void log(OpenRCT2::IStream* stream, const TrackDesignMazeElement& val)
{
char msg[128] = {};
snprintf(msg, sizeof(msg), "TrackDesignMazeElement(all = %d)", val.all);
snprintf(
msg, sizeof(msg), "TrackDesignMazeElement(x = %d, y = %d, entry = %d)", val.location.x, val.location.y,
val.mazeEntry);
stream->Write(msg, strlen(msg));
}
};
@@ -724,20 +725,20 @@ template<> struct DataSerializerTraitsT<TrackDesignEntranceElement>
{
static void encode(OpenRCT2::IStream* stream, const TrackDesignEntranceElement& val)
{
stream->Write(&val.Location);
stream->Write(&val.IsExit);
stream->Write(&val.location);
stream->Write(&val.isExit);
}
static void decode(OpenRCT2::IStream* stream, TrackDesignEntranceElement& val)
{
stream->Read(&val.Location);
stream->Read(&val.IsExit);
stream->Read(&val.location);
stream->Read(&val.isExit);
}
static void log(OpenRCT2::IStream* stream, const TrackDesignEntranceElement& val)
{
char msg[128] = {};
snprintf(
msg, sizeof(msg), "TrackDesignEntranceElement(x = %d, y = %d, z = %d, dir = %d, isExit = %d)", val.Location.x,
val.Location.y, val.Location.z, val.Location.direction, val.IsExit);
msg, sizeof(msg), "TrackDesignEntranceElement(x = %d, y = %d, z = %d, dir = %d, isExit = %d)", val.location.x,
val.location.y, val.location.z, val.location.direction, val.isExit);
stream->Write(msg, strlen(msg));
}
};
@@ -748,29 +749,32 @@ template<> struct DataSerializerTraitsT<TrackDesignSceneryElement>
{
stream->Write(&val.loc);
stream->Write(&val.flags);
stream->Write(&val.primary_colour);
stream->Write(&val.secondary_colour);
stream->Write(&val.primaryColour);
stream->Write(&val.secondaryColour);
stream->Write(&val.tertiaryColour);
DataSerializerTraits<ObjectEntryDescriptor> s;
s.encode(stream, val.scenery_object);
s.encode(stream, val.sceneryObject);
}
static void decode(OpenRCT2::IStream* stream, TrackDesignSceneryElement& val)
{
stream->Read(&val.loc);
stream->Read(&val.flags);
stream->Read(&val.primary_colour);
stream->Read(&val.secondary_colour);
stream->Read(&val.primaryColour);
stream->Read(&val.secondaryColour);
stream->Read(&val.tertiaryColour);
DataSerializerTraits<ObjectEntryDescriptor> s;
s.decode(stream, val.scenery_object);
s.decode(stream, val.sceneryObject);
}
static void log(OpenRCT2::IStream* stream, const TrackDesignSceneryElement& val)
{
char msg[128] = {};
snprintf(
msg, sizeof(msg), "TrackDesignSceneryElement(x = %d, y = %d, z = %d, flags = %d, colour1 = %d, colour2 = %d)",
val.loc.x, val.loc.y, val.loc.z, val.flags, val.primary_colour, val.secondary_colour);
msg, sizeof(msg),
"TrackDesignSceneryElement(x = %d, y = %d, z = %d, flags = %d, colour1 = %d, colour2 = %d, colour3 = %d)",
val.loc.x, val.loc.y, val.loc.z, val.flags, val.primaryColour, val.secondaryColour, val.tertiaryColour);
stream->Write(msg, strlen(msg));
auto identifier = val.scenery_object.GetName();
auto identifier = val.sceneryObject.GetName();
stream->WriteArray(identifier.data(), identifier.size());
}
};

View File

@@ -47,7 +47,7 @@ using namespace OpenRCT2;
// It is used for making sure only compatible builds get connected, even within
// single OpenRCT2 version.
constexpr uint8_t kNetworkStreamVersion = 1;
constexpr uint8_t kNetworkStreamVersion = 2;
const std::string kNetworkStreamID = std::string(OPENRCT2_VERSION) + "-" + std::to_string(kNetworkStreamVersion);

View File

@@ -89,13 +89,11 @@ namespace RCT1
for (int32_t i = 0; i < Limits::kNumColourSchemes; i++)
{
td->track_spine_colour[i] = RCT1::GetColour(td4aa.TrackSpineColour[i]);
td->track_rail_colour[i] = RCT1::GetColour(td4aa.TrackRailColour[i]);
td->track_support_colour[i] = RCT1::GetColour(td4aa.TrackSupportColour[i]);
td->trackSpineColour[i] = RCT1::GetColour(td4aa.TrackSpineColour[i]);
td->trackRailColour[i] = RCT1::GetColour(td4aa.TrackRailColour[i]);
td->trackSupportColour[i] = RCT1::GetColour(td4aa.TrackSupportColour[i]);
}
td->flags2 = td4aa.Flags2;
return ImportTD4Base(std::move(td), td4aa);
}
@@ -106,22 +104,22 @@ namespace RCT1
_stream.Read(&td4, sizeof(TD4));
for (int32_t i = 0; i < OpenRCT2::Limits::kNumColourSchemes; i++)
{
td->track_spine_colour[i] = RCT1::GetColour(td4.TrackSpineColourV0);
td->track_rail_colour[i] = RCT1::GetColour(td4.TrackRailColourV0);
td->track_support_colour[i] = RCT1::GetColour(td4.TrackSupportColourV0);
td->trackSpineColour[i] = RCT1::GetColour(td4.TrackSpineColourV0);
td->trackRailColour[i] = RCT1::GetColour(td4.TrackRailColourV0);
td->trackSupportColour[i] = RCT1::GetColour(td4.TrackSupportColourV0);
// Mazes were only hedges
if (td4.Type == RideType::HedgeMaze)
{
td->track_support_colour[i] = MAZE_WALL_TYPE_HEDGE;
td->trackSupportColour[i] = MAZE_WALL_TYPE_HEDGE;
}
else if (td4.Type == RideType::RiverRapids)
{
td->track_spine_colour[i] = COLOUR_WHITE;
td->track_rail_colour[i] = COLOUR_WHITE;
td->trackSpineColour[i] = COLOUR_WHITE;
td->trackRailColour[i] = COLOUR_WHITE;
}
}
td->flags2 = 0;
return ImportTD4Base(std::move(td), td4);
}
@@ -130,10 +128,10 @@ namespace RCT1
td->type = RCT1::GetRideType(td4Base.Type, td4Base.VehicleType);
// All TD4s that use powered launch use the type that doesn't pass the station.
td->ride_mode = static_cast<RideMode>(td4Base.Mode);
td->rideMode = static_cast<RideMode>(td4Base.Mode);
if (td4Base.Mode == RCT1_RIDE_MODE_POWERED_LAUNCH)
{
td->ride_mode = RideMode::PoweredLaunch;
td->rideMode = RideMode::PoweredLaunch;
}
std::string_view vehicleObject;
@@ -146,11 +144,10 @@ namespace RCT1
vehicleObject = RCT1::GetVehicleObject(td4Base.VehicleType);
}
assert(!vehicleObject.empty());
td->vehicle_object = ObjectEntryDescriptor(vehicleObject);
td->vehicle_type = EnumValue(td4Base.VehicleType);
td->vehicleObject = ObjectEntryDescriptor(vehicleObject);
td->vehicleType = EnumValue(td4Base.VehicleType);
td->flags = td4Base.Flags;
td->colour_scheme = td4Base.VersionAndColourScheme & 0x3;
td->colourScheme = td4Base.VersionAndColourScheme & 0x3;
// Vehicle colours
for (int32_t i = 0; i < Limits::kMaxTrainsPerRide; i++)
@@ -160,63 +157,63 @@ namespace RCT1
td4Base.VehicleType);
if (colourSchemeCopyDescriptor.colour1 == COPY_COLOUR_1)
{
td->vehicle_colours[i].Body = RCT1::GetColour(td4Base.VehicleColours[i].BodyColour);
td->vehicleColours[i].Body = RCT1::GetColour(td4Base.VehicleColours[i].BodyColour);
}
else if (colourSchemeCopyDescriptor.colour1 == COPY_COLOUR_2)
{
td->vehicle_colours[i].Body = RCT1::GetColour(td4Base.VehicleColours[i].TrimColour);
td->vehicleColours[i].Body = RCT1::GetColour(td4Base.VehicleColours[i].TrimColour);
}
else
{
td->vehicle_colours[i].Body = colourSchemeCopyDescriptor.colour1;
td->vehicleColours[i].Body = colourSchemeCopyDescriptor.colour1;
}
if (colourSchemeCopyDescriptor.colour2 == COPY_COLOUR_1)
{
td->vehicle_colours[i].Trim = RCT1::GetColour(td4Base.VehicleColours[i].BodyColour);
td->vehicleColours[i].Trim = RCT1::GetColour(td4Base.VehicleColours[i].BodyColour);
}
else if (colourSchemeCopyDescriptor.colour2 == COPY_COLOUR_2)
{
td->vehicle_colours[i].Trim = RCT1::GetColour(td4Base.VehicleColours[i].TrimColour);
td->vehicleColours[i].Trim = RCT1::GetColour(td4Base.VehicleColours[i].TrimColour);
}
else
{
td->vehicle_colours[i].Trim = colourSchemeCopyDescriptor.colour2;
td->vehicleColours[i].Trim = colourSchemeCopyDescriptor.colour2;
}
if (colourSchemeCopyDescriptor.colour3 == COPY_COLOUR_1)
{
td->vehicle_colours[i].Tertiary = RCT1::GetColour(td4Base.VehicleColours[i].BodyColour);
td->vehicleColours[i].Tertiary = RCT1::GetColour(td4Base.VehicleColours[i].BodyColour);
}
else if (colourSchemeCopyDescriptor.colour3 == COPY_COLOUR_2)
{
td->vehicle_colours[i].Tertiary = RCT1::GetColour(td4Base.VehicleColours[i].TrimColour);
td->vehicleColours[i].Tertiary = RCT1::GetColour(td4Base.VehicleColours[i].TrimColour);
}
else
{
td->vehicle_colours[i].Tertiary = colourSchemeCopyDescriptor.colour3;
td->vehicleColours[i].Tertiary = colourSchemeCopyDescriptor.colour3;
}
}
// Set remaining vehicles to same colour as first vehicle
for (size_t i = Limits::kMaxTrainsPerRide; i < std::size(td->vehicle_colours); i++)
for (size_t i = Limits::kMaxTrainsPerRide; i < std::size(td->vehicleColours); i++)
{
td->vehicle_colours[i] = td->vehicle_colours[0];
td->vehicleColours[i] = td->vehicleColours[0];
}
td->StationObjectIdentifier = GetStationIdentifierFromStyle(RCT12_STATION_STYLE_PLAIN);
td->depart_flags = td4Base.DepartFlags;
td->number_of_trains = td4Base.NumberOfTrains;
td->number_of_cars_per_train = td4Base.NumberOfCarsPerTrain;
td->min_waiting_time = td4Base.MinWaitingTime;
td->max_waiting_time = td4Base.MaxWaitingTime;
td->operation_setting = std::min(
td->stationObjectIdentifier = GetStationIdentifierFromStyle(RCT12_STATION_STYLE_PLAIN);
td->departFlags = td4Base.DepartFlags;
td->numberOfTrains = td4Base.NumberOfTrains;
td->numberOfCarsPerTrain = td4Base.NumberOfCarsPerTrain;
td->minWaitingTime = td4Base.MinWaitingTime;
td->maxWaitingTime = td4Base.MaxWaitingTime;
td->operationSetting = std::min(
td4Base.OperationSetting, GetRideTypeDescriptor(td->type).OperatingSettings.MaxValue);
td->max_speed = td4Base.MaxSpeed;
td->average_speed = td4Base.AverageSpeed;
td->ride_length = td4Base.RideLength;
td->max_positive_vertical_g = td4Base.MaxPositiveVerticalG;
td->max_negative_vertical_g = td4Base.MaxNegativeVerticalG;
td->max_lateral_g = td4Base.MaxLateralG;
td->maxSpeed = td4Base.MaxSpeed;
td->averageSpeed = td4Base.AverageSpeed;
td->rideLength = td4Base.RideLength;
td->maxPositiveVerticalG = td4Base.MaxPositiveVerticalG;
td->maxNegativeVerticalG = td4Base.MaxNegativeVerticalG;
td->maxLateralG = td4Base.MaxLateralG;
if (td->type == RIDE_TYPE_MINI_GOLF)
{
@@ -228,16 +225,16 @@ namespace RCT1
}
td->drops = td4Base.NumDrops;
td->highest_drop_height = td4Base.HighestDropHeight / 2;
td->highestDropHeight = td4Base.HighestDropHeight / 2;
td->excitement = td4Base.Excitement;
td->intensity = td4Base.Intensity;
td->nausea = td4Base.Nausea;
td->upkeep_cost = ToMoney64(td4Base.UpkeepCost);
td->space_required_x = 255;
td->space_required_y = 255;
td->lift_hill_speed = 5;
td->num_circuits = 0;
td->operation_setting = std::min(td->operation_setting, GetRideTypeDescriptor(td->type).OperatingSettings.MaxValue);
td->upkeepCost = ToMoney64(td4Base.UpkeepCost);
td->spaceRequiredX = 255;
td->spaceRequiredY = 255;
td->liftHillSpeed = 5;
td->numCircuits = 0;
td->operationSetting = std::min(td->operationSetting, GetRideTypeDescriptor(td->type).OperatingSettings.MaxValue);
const auto& rtd = GetRideTypeDescriptor(td->type);
if (rtd.HasFlag(RIDE_TYPE_FLAG_IS_MAZE))
@@ -263,7 +260,7 @@ namespace RCT1
TrackDesignTrackElement trackElement{};
trackElement.Type = RCT1TrackTypeToOpenRCT2(t4TrackElement.Type, td->type);
ConvertFromTD46Flags(trackElement, t4TrackElement.Flags);
td->track_elements.push_back(trackElement);
td->trackElements.push_back(trackElement);
}
}

View File

@@ -939,18 +939,17 @@ void ImportMazeElement(TrackDesign& td, const TD46MazeElement& td46MazeElement)
if (td46MazeElement.IsEntrance() || td46MazeElement.IsExit())
{
TrackDesignEntranceElement element{};
element.Location = TileCoordsXYZD(td46MazeElement.x, td46MazeElement.y, 0, td46MazeElement.Direction);
element.IsExit = td46MazeElement.IsExit();
td.entrance_elements.push_back(element);
element.location = TileCoordsXYZD(td46MazeElement.x, td46MazeElement.y, 0, td46MazeElement.Direction);
element.isExit = td46MazeElement.IsExit();
td.entranceElements.push_back(element);
}
else
{
TrackDesignMazeElement mazeElement{};
mazeElement.x = td46MazeElement.x;
mazeElement.y = td46MazeElement.y;
mazeElement.direction = td46MazeElement.Direction;
mazeElement.type = td46MazeElement.Type;
td.maze_elements.push_back(mazeElement);
mazeElement.location.x = td46MazeElement.x;
mazeElement.location.y = td46MazeElement.y;
mazeElement.mazeEntry = td46MazeElement.MazeEntry;
td.mazeElements.push_back(mazeElement);
}
}

View File

@@ -263,4 +263,9 @@ namespace RCT2
return result;
return {};
}
colour_t TD6SceneryElement::getTertiaryWallColour() const
{
return (Flags & 0xFC) >> 2;
}
} // namespace RCT2

View File

@@ -323,6 +323,9 @@ namespace RCT2
uint8_t Flags; // 0x13 direction quadrant tertiary colour
uint8_t PrimaryColour; // 0x14
uint8_t SecondaryColour; // 0x15
colour_t getTertiaryWallColour() const;
void setTertiaryWallColour(colour_t colour);
};
assert_struct_size(TD6SceneryElement, 0x16);

View File

@@ -53,74 +53,76 @@ namespace RCT2
{
OpenRCT2::MemoryStream tempStream;
tempStream.WriteValue<uint8_t>(OpenRCT2RideTypeToRCT2RideType(_trackDesign->type));
tempStream.WriteValue<uint8_t>(_trackDesign->vehicle_type);
tempStream.WriteValue<uint32_t>(_trackDesign->flags);
tempStream.WriteValue<uint8_t>(static_cast<uint8_t>(_trackDesign->ride_mode));
tempStream.WriteValue<uint8_t>((_trackDesign->colour_scheme & 0x3) | (2 << 2));
tempStream.WriteValue<uint8_t>(_trackDesign->vehicleType);
tempStream.WriteValue<uint32_t>(0);
tempStream.WriteValue<uint8_t>(static_cast<uint8_t>(_trackDesign->rideMode));
tempStream.WriteValue<uint8_t>((_trackDesign->colourScheme & 0x3) | (2 << 2));
for (auto i = 0; i < RCT2::Limits::kMaxVehicleColours; i++)
{
tempStream.WriteValue<uint8_t>(_trackDesign->vehicle_colours[i].Body);
tempStream.WriteValue<uint8_t>(_trackDesign->vehicle_colours[i].Trim);
tempStream.WriteValue<uint8_t>(_trackDesign->vehicleColours[i].Body);
tempStream.WriteValue<uint8_t>(_trackDesign->vehicleColours[i].Trim);
}
tempStream.WriteValue<uint8_t>(0);
auto entranceStyle = GetStationStyleFromIdentifier(_trackDesign->StationObjectIdentifier);
auto entranceStyle = GetStationStyleFromIdentifier(_trackDesign->stationObjectIdentifier);
tempStream.WriteValue<uint8_t>(entranceStyle);
tempStream.WriteValue<uint8_t>(_trackDesign->total_air_time);
tempStream.WriteValue<uint8_t>(_trackDesign->depart_flags);
tempStream.WriteValue<uint8_t>(_trackDesign->number_of_trains);
tempStream.WriteValue<uint8_t>(_trackDesign->number_of_cars_per_train);
tempStream.WriteValue<uint8_t>(_trackDesign->min_waiting_time);
tempStream.WriteValue<uint8_t>(_trackDesign->max_waiting_time);
tempStream.WriteValue<uint8_t>(_trackDesign->operation_setting);
tempStream.WriteValue<int8_t>(_trackDesign->max_speed);
tempStream.WriteValue<int8_t>(_trackDesign->average_speed);
tempStream.WriteValue<uint16_t>(_trackDesign->ride_length);
tempStream.WriteValue<uint8_t>(_trackDesign->max_positive_vertical_g);
tempStream.WriteValue<int8_t>(_trackDesign->max_negative_vertical_g);
tempStream.WriteValue<uint8_t>(_trackDesign->max_lateral_g);
tempStream.WriteValue<uint8_t>(_trackDesign->totalAirTime);
tempStream.WriteValue<uint8_t>(_trackDesign->departFlags);
tempStream.WriteValue<uint8_t>(_trackDesign->numberOfTrains);
tempStream.WriteValue<uint8_t>(_trackDesign->numberOfCarsPerTrain);
tempStream.WriteValue<uint8_t>(_trackDesign->minWaitingTime);
tempStream.WriteValue<uint8_t>(_trackDesign->maxWaitingTime);
tempStream.WriteValue<uint8_t>(_trackDesign->operationSetting);
tempStream.WriteValue<int8_t>(_trackDesign->maxSpeed);
tempStream.WriteValue<int8_t>(_trackDesign->averageSpeed);
tempStream.WriteValue<uint16_t>(_trackDesign->rideLength);
tempStream.WriteValue<uint8_t>(_trackDesign->maxPositiveVerticalG);
tempStream.WriteValue<int8_t>(_trackDesign->maxNegativeVerticalG);
tempStream.WriteValue<uint8_t>(_trackDesign->maxLateralG);
tempStream.WriteValue<uint8_t>(
_trackDesign->type == RIDE_TYPE_MINI_GOLF ? _trackDesign->holes : _trackDesign->inversions);
tempStream.WriteValue<uint8_t>(_trackDesign->drops);
tempStream.WriteValue<uint8_t>(_trackDesign->highest_drop_height);
tempStream.WriteValue<uint8_t>(_trackDesign->highestDropHeight);
tempStream.WriteValue<uint8_t>(_trackDesign->excitement);
tempStream.WriteValue<uint8_t>(_trackDesign->intensity);
tempStream.WriteValue<uint8_t>(_trackDesign->nausea);
tempStream.WriteValue<money16>(ToMoney16(_trackDesign->upkeep_cost));
tempStream.WriteArray(_trackDesign->track_spine_colour, Limits::kNumColourSchemes);
tempStream.WriteArray(_trackDesign->track_rail_colour, Limits::kNumColourSchemes);
tempStream.WriteArray(_trackDesign->track_support_colour, Limits::kNumColourSchemes);
tempStream.WriteValue<uint32_t>(_trackDesign->flags2);
tempStream.Write(&_trackDesign->vehicle_object.Entry, sizeof(RCTObjectEntry));
tempStream.WriteValue<uint8_t>(_trackDesign->space_required_x);
tempStream.WriteValue<uint8_t>(_trackDesign->space_required_y);
tempStream.WriteValue<money16>(ToMoney16(_trackDesign->upkeepCost));
tempStream.WriteArray(_trackDesign->trackSpineColour, Limits::kNumColourSchemes);
tempStream.WriteArray(_trackDesign->trackRailColour, Limits::kNumColourSchemes);
tempStream.WriteArray(_trackDesign->trackSupportColour, Limits::kNumColourSchemes);
tempStream.WriteValue<uint32_t>(0);
tempStream.Write(&_trackDesign->vehicleObject.Entry, sizeof(RCTObjectEntry));
tempStream.WriteValue<uint8_t>(_trackDesign->spaceRequiredX);
tempStream.WriteValue<uint8_t>(_trackDesign->spaceRequiredY);
for (auto i = 0; i < RCT2::Limits::kMaxVehicleColours; i++)
{
tempStream.WriteValue<uint8_t>(_trackDesign->vehicle_colours[i].Tertiary);
tempStream.WriteValue<uint8_t>(_trackDesign->vehicleColours[i].Tertiary);
}
tempStream.WriteValue<uint8_t>(_trackDesign->lift_hill_speed | (_trackDesign->num_circuits << 5));
tempStream.WriteValue<uint8_t>(_trackDesign->liftHillSpeed | (_trackDesign->numCircuits << 5));
const auto& rtd = GetRideTypeDescriptor(_trackDesign->type);
if (rtd.HasFlag(RIDE_TYPE_FLAG_IS_MAZE))
{
for (const auto& mazeElement : _trackDesign->maze_elements)
for (const auto& mazeElement : _trackDesign->mazeElements)
{
tempStream.WriteValue<uint32_t>(mazeElement.all);
tempStream.WriteValue<int8_t>(mazeElement.location.x);
tempStream.WriteValue<int8_t>(mazeElement.location.y);
tempStream.WriteValue<uint16_t>(mazeElement.mazeEntry);
}
for (const auto& entranceElement : _trackDesign->entrance_elements)
for (const auto& entranceElement : _trackDesign->entranceElements)
{
tempStream.WriteValue<int8_t>(entranceElement.Location.x);
tempStream.WriteValue<int8_t>(entranceElement.Location.y);
tempStream.WriteValue<int8_t>(entranceElement.Location.direction);
tempStream.WriteValue<int8_t>(entranceElement.location.x);
tempStream.WriteValue<int8_t>(entranceElement.location.y);
tempStream.WriteValue<int8_t>(entranceElement.location.direction);
tempStream.WriteValue<int8_t>(
EnumValue(entranceElement.IsExit ? TD46MazeElementType::Exit : TD46MazeElementType::Entrance));
EnumValue(entranceElement.isExit ? TD46MazeElementType::Exit : TD46MazeElementType::Entrance));
}
tempStream.WriteValue<uint32_t>(0);
}
else
{
for (const auto& trackElement : _trackDesign->track_elements)
for (const auto& trackElement : _trackDesign->trackElements)
{
auto trackType = OpenRCT2TrackTypeToRCT2(trackElement.Type);
if (trackType == TrackElemType::MultiDimInvertedUp90ToFlatQuarterLoop)
@@ -134,12 +136,12 @@ namespace RCT2
tempStream.WriteValue<uint8_t>(0xFF);
for (const auto& entranceElement : _trackDesign->entrance_elements)
for (const auto& entranceElement : _trackDesign->entranceElements)
{
tempStream.WriteValue<uint8_t>(
entranceElement.Location.z == -1 ? static_cast<uint8_t>(0x80) : entranceElement.Location.z);
tempStream.WriteValue<uint8_t>(entranceElement.Location.direction | (entranceElement.IsExit << 7));
auto xy = entranceElement.Location.ToCoordsXY();
entranceElement.location.z == -1 ? static_cast<uint8_t>(0x80) : entranceElement.location.z);
tempStream.WriteValue<uint8_t>(entranceElement.location.direction | (entranceElement.isExit << 7));
auto xy = entranceElement.location.ToCoordsXY();
tempStream.WriteValue<int16_t>(xy.x);
tempStream.WriteValue<int16_t>(xy.y);
}
@@ -147,15 +149,23 @@ namespace RCT2
tempStream.WriteValue<uint8_t>(0xFF);
}
for (const auto& sceneryElement : _trackDesign->scenery_elements)
for (const auto& sceneryElement : _trackDesign->sceneryElements)
{
tempStream.Write(&sceneryElement.scenery_object.Entry, sizeof(RCTObjectEntry));
tempStream.WriteValue<int8_t>(sceneryElement.loc.x / COORDS_XY_STEP);
tempStream.WriteValue<int8_t>(sceneryElement.loc.y / COORDS_XY_STEP);
tempStream.WriteValue<int8_t>(sceneryElement.loc.z / COORDS_Z_STEP);
tempStream.WriteValue<uint8_t>(sceneryElement.flags);
tempStream.WriteValue<uint8_t>(sceneryElement.primary_colour);
tempStream.WriteValue<uint8_t>(sceneryElement.secondary_colour);
auto flags = sceneryElement.flags;
if (sceneryElement.sceneryObject.Entry.GetType() == ObjectType::Walls)
{
flags &= ~0xFC;
flags |= (sceneryElement.tertiaryColour << 2);
}
tempStream.Write(&sceneryElement.sceneryObject.Entry, sizeof(RCTObjectEntry));
auto tileCoords = TileCoordsXYZ(sceneryElement.loc);
tempStream.WriteValue<int8_t>(tileCoords.x);
tempStream.WriteValue<int8_t>(tileCoords.y);
tempStream.WriteValue<int8_t>(tileCoords.z);
tempStream.WriteValue<uint8_t>(flags);
tempStream.WriteValue<uint8_t>(sceneryElement.primaryColour);
tempStream.WriteValue<uint8_t>(sceneryElement.secondaryColour);
}
tempStream.WriteValue<uint8_t>(0xFF);

View File

@@ -72,33 +72,32 @@ namespace RCT2
_stream.Read(&td6, 0xA3);
td->type = td6.Type; // 0x00
td->vehicle_type = td6.VehicleType;
td->vehicleType = td6.VehicleType;
td->cost = 0.00_GBP;
td->flags = td6.Flags;
td->ride_mode = static_cast<RideMode>(td6.RideMode);
td->track_flags = 0;
td->colour_scheme = td6.VersionAndColourScheme & 0x3;
td->rideMode = static_cast<RideMode>(td6.RideMode);
td->trackFlags = 0;
td->colourScheme = td6.VersionAndColourScheme & 0x3;
for (auto i = 0; i < Limits::kMaxVehicleColours; ++i)
{
td->vehicle_colours[i].Body = td6.VehicleColours[i].BodyColour;
td->vehicle_colours[i].Trim = td6.VehicleColours[i].TrimColour;
td->vehicle_colours[i].Tertiary = td6.VehicleAdditionalColour[i];
td->vehicleColours[i].Body = td6.VehicleColours[i].BodyColour;
td->vehicleColours[i].Trim = td6.VehicleColours[i].TrimColour;
td->vehicleColours[i].Tertiary = td6.VehicleAdditionalColour[i];
}
td->StationObjectIdentifier = GetStationIdentifierFromStyle(td6.EntranceStyle);
td->total_air_time = td6.TotalAirTime;
td->depart_flags = td6.DepartFlags;
td->number_of_trains = td6.NumberOfTrains;
td->number_of_cars_per_train = td6.NumberOfCarsPerTrain;
td->min_waiting_time = td6.MinWaitingTime;
td->max_waiting_time = td6.MaxWaitingTime;
td->operation_setting = td6.OperationSetting;
td->max_speed = td6.MaxSpeed;
td->average_speed = td6.AverageSpeed;
td->ride_length = td6.RideLength;
td->max_positive_vertical_g = td6.MaxPositiveVerticalG;
td->max_negative_vertical_g = td6.MaxNegativeVerticalG;
td->max_lateral_g = td6.MaxLateralG;
td->stationObjectIdentifier = GetStationIdentifierFromStyle(td6.EntranceStyle);
td->totalAirTime = td6.TotalAirTime;
td->departFlags = td6.DepartFlags;
td->numberOfTrains = td6.NumberOfTrains;
td->numberOfCarsPerTrain = td6.NumberOfCarsPerTrain;
td->minWaitingTime = td6.MinWaitingTime;
td->maxWaitingTime = td6.MaxWaitingTime;
td->operationSetting = td6.OperationSetting;
td->maxSpeed = td6.MaxSpeed;
td->averageSpeed = td6.AverageSpeed;
td->rideLength = td6.RideLength;
td->maxPositiveVerticalG = td6.MaxPositiveVerticalG;
td->maxNegativeVerticalG = td6.MaxNegativeVerticalG;
td->maxLateralG = td6.MaxLateralG;
if (td->type == RIDE_TYPE_MINI_GOLF)
{
@@ -110,23 +109,22 @@ namespace RCT2
}
td->drops = td6.Drops;
td->highest_drop_height = td6.HighestDropHeight;
td->highestDropHeight = td6.HighestDropHeight;
td->excitement = td6.Excitement;
td->intensity = td6.Intensity;
td->nausea = td6.Nausea;
td->upkeep_cost = ToMoney64(td6.UpkeepCost);
td->upkeepCost = ToMoney64(td6.UpkeepCost);
for (auto i = 0; i < Limits::kNumColourSchemes; ++i)
{
td->track_spine_colour[i] = td6.TrackSpineColour[i];
td->track_rail_colour[i] = td6.TrackRailColour[i];
td->track_support_colour[i] = td6.TrackSupportColour[i];
td->trackSpineColour[i] = td6.TrackSpineColour[i];
td->trackRailColour[i] = td6.TrackRailColour[i];
td->trackSupportColour[i] = td6.TrackSupportColour[i];
}
td->flags2 = td6.Flags2;
td->vehicle_object = ObjectEntryDescriptor(td6.VehicleObject);
td->space_required_x = td6.SpaceRequiredX;
td->space_required_y = td6.SpaceRequiredY;
td->lift_hill_speed = td6.LiftHillSpeedNumCircuits & 0b00011111;
td->num_circuits = td6.LiftHillSpeedNumCircuits >> 5;
td->vehicleObject = ObjectEntryDescriptor(td6.VehicleObject);
td->spaceRequiredX = td6.SpaceRequiredX;
td->spaceRequiredY = td6.SpaceRequiredY;
td->liftHillSpeed = td6.LiftHillSpeedNumCircuits & 0b00011111;
td->numCircuits = td6.LiftHillSpeedNumCircuits >> 5;
auto version = static_cast<RCT12TrackDesignVersion>((td6.VersionAndColourScheme >> 2) & 3);
if (version != RCT12TrackDesignVersion::TD6)
@@ -135,7 +133,7 @@ namespace RCT2
return nullptr;
}
td->operation_setting = std::min(td->operation_setting, GetRideTypeDescriptor(td->type).OperatingSettings.MaxValue);
td->operationSetting = std::min(td->operationSetting, GetRideTypeDescriptor(td->type).OperatingSettings.MaxValue);
const auto& rtd = GetRideTypeDescriptor(td->type);
if (rtd.HasFlag(RIDE_TYPE_FLAG_IS_MAZE))
@@ -168,7 +166,7 @@ namespace RCT2
trackElement.Type = trackType;
ConvertFromTD46Flags(trackElement, t6TrackElement.Flags);
td->track_elements.push_back(trackElement);
td->trackElements.push_back(trackElement);
}
TD6EntranceElement t6EntranceElement{};
@@ -179,9 +177,9 @@ namespace RCT2
TrackDesignEntranceElement entranceElement{};
auto xy = CoordsXY(t6EntranceElement.x, t6EntranceElement.y);
auto z = (t6EntranceElement.z == -128) ? -1 : t6EntranceElement.z;
entranceElement.Location = TileCoordsXYZD(TileCoordsXY(xy), z, t6EntranceElement.GetDirection());
entranceElement.IsExit = t6EntranceElement.IsExit();
td->entrance_elements.push_back(entranceElement);
entranceElement.location = TileCoordsXYZD(TileCoordsXY(xy), z, t6EntranceElement.GetDirection());
entranceElement.isExit = t6EntranceElement.IsExit();
td->entranceElements.push_back(entranceElement);
}
}
@@ -191,14 +189,16 @@ namespace RCT2
TD6SceneryElement t6SceneryElement{};
_stream.Read(&t6SceneryElement, sizeof(TD6SceneryElement));
TrackDesignSceneryElement sceneryElement{};
sceneryElement.scenery_object = ObjectEntryDescriptor(t6SceneryElement.SceneryObject);
sceneryElement.loc.x = t6SceneryElement.x * COORDS_XY_STEP;
sceneryElement.loc.y = t6SceneryElement.y * COORDS_XY_STEP;
sceneryElement.loc.z = t6SceneryElement.z * COORDS_Z_STEP;
sceneryElement.sceneryObject = ObjectEntryDescriptor(t6SceneryElement.SceneryObject);
TileCoordsXYZ tileCoords = { t6SceneryElement.x, t6SceneryElement.y, t6SceneryElement.z };
sceneryElement.loc = tileCoords.ToCoordsXYZ();
sceneryElement.flags = t6SceneryElement.Flags;
sceneryElement.primary_colour = t6SceneryElement.PrimaryColour;
sceneryElement.secondary_colour = t6SceneryElement.SecondaryColour;
td->scenery_elements.push_back(std::move(sceneryElement));
sceneryElement.primaryColour = t6SceneryElement.PrimaryColour;
sceneryElement.secondaryColour = t6SceneryElement.SecondaryColour;
if (t6SceneryElement.SceneryObject.GetType() == ObjectType::Walls)
sceneryElement.tertiaryColour = t6SceneryElement.getTertiaryWallColour();
td->sceneryElements.push_back(std::move(sceneryElement));
}
td->name = _name;
@@ -213,7 +213,7 @@ namespace RCT2
if (RCT2RideTypeNeedsConversion(td->type))
{
std::scoped_lock<std::mutex> lock(_objectLookupMutex);
auto rawObject = ObjectRepositoryLoadObject(&td->vehicle_object.Entry);
auto rawObject = ObjectRepositoryLoadObject(&td->vehicleObject.Entry);
if (rawObject != nullptr)
{
const auto* rideEntry = static_cast<const RideObjectEntry*>(

View File

@@ -106,60 +106,58 @@ ResultWithMessage TrackDesign::CreateTrackDesign(TrackDesignState& tds, const Ri
{
return { false, STR_VEHICLE_UNSUPPORTED_TD6 };
}
vehicle_object = ObjectEntryDescriptor(entry);
vehicleObject = ObjectEntryDescriptor(entry);
}
ride_mode = ride.mode;
colour_scheme = ride.colour_scheme_type & 3;
rideMode = ride.mode;
colourScheme = ride.colour_scheme_type & 3;
for (size_t i = 0; i < std::size(vehicle_colours); i++)
for (size_t i = 0; i < std::size(vehicleColours); i++)
{
vehicle_colours[i] = ride.vehicle_colours[i];
vehicleColours[i] = ride.vehicle_colours[i];
}
for (int32_t i = 0; i < OpenRCT2::Limits::kNumColourSchemes; i++)
{
track_spine_colour[i] = ride.track_colour[i].main;
track_rail_colour[i] = ride.track_colour[i].additional;
track_support_colour[i] = ride.track_colour[i].supports;
trackSpineColour[i] = ride.track_colour[i].main;
trackRailColour[i] = ride.track_colour[i].additional;
trackSupportColour[i] = ride.track_colour[i].supports;
}
depart_flags = ride.depart_flags;
number_of_trains = ride.NumTrains;
number_of_cars_per_train = ride.num_cars_per_train;
min_waiting_time = ride.min_waiting_time;
max_waiting_time = ride.max_waiting_time;
operation_setting = ride.operation_option;
lift_hill_speed = ride.lift_hill_speed;
num_circuits = ride.num_circuits;
departFlags = ride.depart_flags;
numberOfTrains = ride.NumTrains;
numberOfCarsPerTrain = ride.num_cars_per_train;
minWaitingTime = ride.min_waiting_time;
maxWaitingTime = ride.max_waiting_time;
operationSetting = ride.operation_option;
liftHillSpeed = ride.lift_hill_speed;
numCircuits = ride.num_circuits;
StationObjectIdentifier = TrackDesignGetStationObjectIdentifier(ride);
max_speed = static_cast<int8_t>(ride.max_speed / 65536);
average_speed = static_cast<int8_t>(ride.average_speed / 65536);
ride_length = ride.GetTotalLength() / 65536;
max_positive_vertical_g = ride.max_positive_vertical_g / 32;
max_negative_vertical_g = ride.max_negative_vertical_g / 32;
max_lateral_g = ride.max_lateral_g / 32;
stationObjectIdentifier = TrackDesignGetStationObjectIdentifier(ride);
maxSpeed = static_cast<int8_t>(ride.max_speed / 65536);
averageSpeed = static_cast<int8_t>(ride.average_speed / 65536);
rideLength = ride.GetTotalLength() / 65536;
maxPositiveVerticalG = ride.max_positive_vertical_g / 32;
maxNegativeVerticalG = ride.max_negative_vertical_g / 32;
maxLateralG = ride.max_lateral_g / 32;
holes = ride.holes & 0x1F;
inversions = ride.inversions & 0x1F;
inversions |= (ride.sheltered_eighths << 5);
drops = ride.drops;
highest_drop_height = ride.highest_drop_height;
highestDropHeight = ride.highest_drop_height;
uint16_t totalAirTime = (ride.total_air_time * 123) / 1024;
if (totalAirTime > 255)
uint16_t _totalAirTime = (ride.total_air_time * 123) / 1024;
if (_totalAirTime > 255)
{
totalAirTime = 0;
_totalAirTime = 0;
}
total_air_time = static_cast<uint8_t>(totalAirTime);
totalAirTime = static_cast<uint8_t>(_totalAirTime);
excitement = ride.ratings.Excitement / 10;
intensity = ride.ratings.Intensity / 10;
nausea = ride.ratings.Nausea / 10;
upkeep_cost = ride.upkeep_cost;
flags = 0;
flags2 = 0;
upkeepCost = ride.upkeep_cost;
const auto& rtd = GetRideTypeDescriptor(type);
@@ -242,7 +240,7 @@ ResultWithMessage TrackDesign::CreateTrackDesignTrack(TrackDesignState& tds, con
track.SetFlag(TrackDesignTrackElementFlag::IsInverted);
}
track_elements.push_back(track);
trackElements.push_back(track);
if (!TrackBlockGetNext(&trackElement, &trackElement, nullptr, nullptr))
{
@@ -262,7 +260,7 @@ ResultWithMessage TrackDesign::CreateTrackDesignTrack(TrackDesignState& tds, con
trackElement.x = newCoords->x;
trackElement.y = newCoords->y;
if (track_elements.size() > RCT2::Limits::kTD6MaxTrackElements)
if (trackElements.size() > RCT2::Limits::kTD6MaxTrackElements)
{
return { false, STR_TRACK_TOO_LARGE_OR_TOO_MUCH_SCENERY };
}
@@ -323,14 +321,14 @@ ResultWithMessage TrackDesign::CreateTrackDesignTrack(TrackDesignState& tds, con
}
TrackDesignEntranceElement entrance{};
entrance.Location = TileCoordsXYZD(rotatedMapLocation, z, entranceDirection);
entrance.location = TileCoordsXYZD(rotatedMapLocation, z, entranceDirection);
// If this is the exit version
if (i == 1)
{
entrance.IsExit = true;
entrance.isExit = true;
}
entrance_elements.push_back(entrance);
entranceElements.push_back(entrance);
}
}
@@ -343,8 +341,8 @@ ResultWithMessage TrackDesign::CreateTrackDesignTrack(TrackDesignState& tds, con
gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_ARROW;
gMapSelectFlags &= ~MAP_SELECT_FLAG_GREEN;
space_required_x = ((tds.PreviewMax.x - tds.PreviewMin.x) / 32) + 1;
space_required_y = ((tds.PreviewMax.y - tds.PreviewMin.y) / 32) + 1;
spaceRequiredX = ((tds.PreviewMax.x - tds.PreviewMin.x) / 32) + 1;
spaceRequiredY = ((tds.PreviewMax.y - tds.PreviewMin.y) / 32) + 1;
return { true, warningMessage };
}
@@ -378,13 +376,13 @@ ResultWithMessage TrackDesign::CreateTrackDesignMaze(TrackDesignState& tds, cons
TrackDesignMazeElement maze{};
maze.maze_entry = tileElement->AsTrack()->GetMazeEntry();
maze.x = (x - startLoc.x) / COORDS_XY_STEP;
maze.y = (y - startLoc.y) / COORDS_XY_STEP;
maze.mazeEntry = tileElement->AsTrack()->GetMazeEntry();
maze.location.x = (x - startLoc.x) / COORDS_XY_STEP;
maze.location.y = (y - startLoc.y) / COORDS_XY_STEP;
_saveDirection = tileElement->GetDirection();
maze_elements.push_back(maze);
mazeElements.push_back(maze);
if (maze_elements.size() >= 2000)
if (mazeElements.size() >= 2000)
{
return { false, STR_TRACK_TOO_LARGE_OR_TOO_MUCH_SCENERY };
}
@@ -416,9 +414,9 @@ ResultWithMessage TrackDesign::CreateTrackDesignMaze(TrackDesignState& tds, cons
auto entranceOffset = entranceLoc - startLoc;
TrackDesignEntranceElement mazeEntrance{};
mazeEntrance.Location = TileCoordsXYZD(CoordsXYZD(entranceOffset, 0, tileElement->GetDirection()));
mazeEntrance.IsExit = false;
entrance_elements.push_back(mazeEntrance);
mazeEntrance.location = TileCoordsXYZD(CoordsXYZD(entranceOffset, 0, tileElement->GetDirection()));
mazeEntrance.isExit = false;
entranceElements.push_back(mazeEntrance);
location = ride.GetStation().Exit;
if (location.IsNull())
@@ -443,9 +441,9 @@ ResultWithMessage TrackDesign::CreateTrackDesignMaze(TrackDesignState& tds, cons
auto exitOffset = exitLoc - startLoc;
TrackDesignEntranceElement mazeExit{};
mazeExit.Location = TileCoordsXYZD(CoordsXYZD(exitOffset, 0, tileElement->GetDirection()));
mazeExit.IsExit = true;
entrance_elements.push_back(mazeExit);
mazeExit.location = TileCoordsXYZD(CoordsXYZD(exitOffset, 0, tileElement->GetDirection()));
mazeExit.isExit = true;
entranceElements.push_back(mazeExit);
// Save global vars as they are still used by scenery????
int32_t startZ = tds.Origin.z;
@@ -456,8 +454,8 @@ ResultWithMessage TrackDesign::CreateTrackDesignMaze(TrackDesignState& tds, cons
gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_ARROW;
gMapSelectFlags &= ~MAP_SELECT_FLAG_GREEN;
space_required_x = ((tds.PreviewMax.x - tds.PreviewMin.x) / 32) + 1;
space_required_y = ((tds.PreviewMax.y - tds.PreviewMin.y) / 32) + 1;
spaceRequiredX = ((tds.PreviewMax.x - tds.PreviewMin.x) / 32) + 1;
spaceRequiredY = ((tds.PreviewMax.y - tds.PreviewMin.y) / 32) + 1;
return { true };
}
@@ -489,11 +487,11 @@ CoordsXYE TrackDesign::MazeGetFirstElement(const Ride& ride)
ResultWithMessage TrackDesign::CreateTrackDesignScenery(TrackDesignState& tds)
{
scenery_elements = _trackSavedTileElementsDesc;
sceneryElements = _trackSavedTileElementsDesc;
// Run an element loop
for (auto& scenery : scenery_elements)
for (auto& scenery : sceneryElements)
{
switch (scenery.scenery_object.GetType())
switch (scenery.sceneryObject.GetType())
{
case ObjectType::Paths:
{
@@ -564,49 +562,47 @@ void TrackDesign::Serialise(DataSerialiser& stream)
return;
}
stream << DS_TAG(type);
stream << DS_TAG(vehicle_type);
stream << DS_TAG(vehicleType);
stream << DS_TAG(cost);
stream << DS_TAG(flags);
stream << DS_TAG(ride_mode);
stream << DS_TAG(track_flags);
stream << DS_TAG(colour_scheme);
stream << DS_TAG(vehicle_colours);
stream << DS_TAG(StationObjectIdentifier);
stream << DS_TAG(total_air_time);
stream << DS_TAG(depart_flags);
stream << DS_TAG(number_of_trains);
stream << DS_TAG(number_of_cars_per_train);
stream << DS_TAG(min_waiting_time);
stream << DS_TAG(max_waiting_time);
stream << DS_TAG(operation_setting);
stream << DS_TAG(max_speed);
stream << DS_TAG(average_speed);
stream << DS_TAG(ride_length);
stream << DS_TAG(max_positive_vertical_g);
stream << DS_TAG(max_negative_vertical_g);
stream << DS_TAG(max_lateral_g);
stream << DS_TAG(rideMode);
stream << DS_TAG(trackFlags);
stream << DS_TAG(colourScheme);
stream << DS_TAG(vehicleColours);
stream << DS_TAG(stationObjectIdentifier);
stream << DS_TAG(totalAirTime);
stream << DS_TAG(departFlags);
stream << DS_TAG(numberOfTrains);
stream << DS_TAG(numberOfCarsPerTrain);
stream << DS_TAG(minWaitingTime);
stream << DS_TAG(maxWaitingTime);
stream << DS_TAG(operationSetting);
stream << DS_TAG(maxSpeed);
stream << DS_TAG(averageSpeed);
stream << DS_TAG(rideLength);
stream << DS_TAG(maxPositiveVerticalG);
stream << DS_TAG(maxNegativeVerticalG);
stream << DS_TAG(maxLateralG);
stream << DS_TAG(inversions);
stream << DS_TAG(holes);
stream << DS_TAG(drops);
stream << DS_TAG(highest_drop_height);
stream << DS_TAG(highestDropHeight);
stream << DS_TAG(excitement);
stream << DS_TAG(intensity);
stream << DS_TAG(nausea);
stream << DS_TAG(upkeep_cost);
stream << DS_TAG(track_spine_colour);
stream << DS_TAG(track_rail_colour);
stream << DS_TAG(track_support_colour);
stream << DS_TAG(flags2);
stream << DS_TAG(vehicle_object);
stream << DS_TAG(space_required_x);
stream << DS_TAG(space_required_y);
stream << DS_TAG(lift_hill_speed);
stream << DS_TAG(num_circuits);
stream << DS_TAG(upkeepCost);
stream << DS_TAG(trackSpineColour);
stream << DS_TAG(trackRailColour);
stream << DS_TAG(trackSupportColour);
stream << DS_TAG(vehicleObject);
stream << DS_TAG(spaceRequiredX);
stream << DS_TAG(spaceRequiredY);
stream << DS_TAG(liftHillSpeed);
stream << DS_TAG(numCircuits);
stream << DS_TAG(maze_elements);
stream << DS_TAG(track_elements);
stream << DS_TAG(entrance_elements);
stream << DS_TAG(scenery_elements);
stream << DS_TAG(mazeElements);
stream << DS_TAG(trackElements);
stream << DS_TAG(entranceElements);
stream << DS_TAG(sceneryElements);
stream << DS_TAG(name);
}
@@ -637,17 +633,17 @@ static void TrackDesignLoadSceneryObjects(TrackDesign* td6)
objectManager.UnloadAllTransient();
// Load ride object
if (td6->vehicle_object.HasValue())
if (td6->vehicleObject.HasValue())
{
objectManager.LoadObject(td6->vehicle_object);
objectManager.LoadObject(td6->vehicleObject);
}
// Load scenery objects
for (const auto& scenery : td6->scenery_elements)
for (const auto& scenery : td6->sceneryElements)
{
if (scenery.scenery_object.HasValue())
if (scenery.sceneryObject.HasValue())
{
objectManager.LoadObject(scenery.scenery_object);
objectManager.LoadObject(scenery.sceneryObject);
}
}
}
@@ -700,13 +696,13 @@ static std::optional<TrackSceneryEntry> TrackDesignPlaceSceneryElementGetEntry(c
TrackSceneryEntry result;
auto& objectMgr = OpenRCT2::GetContext()->GetObjectManager();
if (scenery.scenery_object.GetType() == ObjectType::Paths)
if (scenery.sceneryObject.GetType() == ObjectType::Paths)
{
auto footpathMapping = RCT2::GetFootpathSurfaceId(scenery.scenery_object, true, scenery.IsQueue());
auto footpathMapping = RCT2::GetFootpathSurfaceId(scenery.sceneryObject, true, scenery.IsQueue());
if (footpathMapping == nullptr)
{
// Check if legacy path object is loaded
auto obj = objectMgr.GetLoadedObject(scenery.scenery_object);
auto obj = objectMgr.GetLoadedObject(scenery.sceneryObject);
if (obj != nullptr)
{
result.Type = obj->GetObjectType();
@@ -738,7 +734,7 @@ static std::optional<TrackSceneryEntry> TrackDesignPlaceSceneryElementGetEntry(c
}
else
{
auto obj = objectMgr.GetLoadedObject(scenery.scenery_object);
auto obj = objectMgr.GetLoadedObject(scenery.sceneryObject);
bool objectUnavailable = obj == nullptr;
if (obj != nullptr)
{
@@ -765,7 +761,7 @@ static std::optional<TrackSceneryEntry> TrackDesignPlaceSceneryElementGetEntry(c
static void TrackDesignMirrorScenery(TrackDesign* td6)
{
auto& objectMgr = OpenRCT2::GetContext()->GetObjectManager();
for (auto& scenery : td6->scenery_elements)
for (auto& scenery : td6->sceneryElements)
{
auto entryInfo = TrackDesignPlaceSceneryElementGetEntry(scenery);
if (!entryInfo)
@@ -874,12 +870,12 @@ static void TrackDesignMirrorScenery(TrackDesign* td6)
static void TrackDesignMirrorEntrances(TrackDesign& td)
{
for (auto& entrance : td.entrance_elements)
for (auto& entrance : td.entranceElements)
{
entrance.Location.y = -entrance.Location.y;
if (entrance.Location.direction & 1)
entrance.location.y = -entrance.location.y;
if (entrance.location.direction & 1)
{
entrance.Location.direction = DirectionReverse(entrance.Location.direction);
entrance.location.direction = DirectionReverse(entrance.location.direction);
}
}
}
@@ -890,7 +886,7 @@ static void TrackDesignMirrorEntrances(TrackDesign& td)
*/
static void TrackDesignMirrorRide(TrackDesign* td6)
{
for (auto& track : td6->track_elements)
for (auto& track : td6->trackElements)
{
const auto& ted = GetTrackElementDescriptor(track.Type);
track.Type = ted.MirrorElement;
@@ -908,18 +904,18 @@ static constexpr uint8_t maze_segment_mirror_map[] = {
*/
static void TrackDesignMirrorMaze(TrackDesign* td6)
{
for (auto& maze : td6->maze_elements)
for (auto& maze : td6->mazeElements)
{
maze.y = -maze.y;
maze.location.y = -maze.location.y;
uint16_t maze_entry = maze.maze_entry;
uint16_t new_entry = 0;
for (uint8_t position = UtilBitScanForward(maze_entry); position != 0xFF; position = UtilBitScanForward(maze_entry))
auto mazeEntry = maze.mazeEntry;
uint16_t newEntry = 0;
for (uint8_t position = UtilBitScanForward(mazeEntry); position != 0xFF; position = UtilBitScanForward(mazeEntry))
{
maze_entry &= ~(1 << position);
new_entry |= (1 << maze_segment_mirror_map[position]);
mazeEntry &= ~(1 << position);
newEntry |= (1 << maze_segment_mirror_map[position]);
}
maze.maze_entry = new_entry;
maze.mazeEntry = newEntry;
}
}
@@ -1100,8 +1096,8 @@ static GameActions::Result TrackDesignPlaceSceneryElement(
}
auto smallSceneryPlace = SmallSceneryPlaceAction(
{ mapCoord.x, mapCoord.y, z, rotation }, quadrant, entryInfo->Index, scenery.primary_colour,
scenery.secondary_colour, COLOUR_DARK_BROWN);
{ mapCoord.x, mapCoord.y, z, rotation }, quadrant, entryInfo->Index, scenery.primaryColour,
scenery.secondaryColour, scenery.tertiaryColour);
smallSceneryPlace.SetFlags(flags);
auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&smallSceneryPlace)
@@ -1142,8 +1138,8 @@ static GameActions::Result TrackDesignPlaceSceneryElement(
flags |= GAME_COMMAND_FLAG_REPLAY;
}
auto sceneryPlaceAction = LargeSceneryPlaceAction(
{ mapCoord.x, mapCoord.y, z, rotation }, entryInfo->Index, scenery.primary_colour, scenery.secondary_colour,
COLOUR_DARK_BROWN);
{ mapCoord.x, mapCoord.y, z, rotation }, entryInfo->Index, scenery.primaryColour, scenery.secondaryColour,
scenery.tertiaryColour);
sceneryPlaceAction.SetFlags(flags);
auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&sceneryPlaceAction)
: GameActions::QueryNested(&sceneryPlaceAction);
@@ -1182,8 +1178,8 @@ static GameActions::Result TrackDesignPlaceSceneryElement(
flags |= GAME_COMMAND_FLAG_REPLAY;
}
auto wallPlaceAction = WallPlaceAction(
entryInfo->Index, { mapCoord.x, mapCoord.y, z }, rotation, scenery.primary_colour, scenery.secondary_colour,
(scenery.flags & 0xFC) >> 2);
entryInfo->Index, { mapCoord.x, mapCoord.y, z }, rotation, scenery.primaryColour, scenery.secondaryColour,
scenery.tertiaryColour);
wallPlaceAction.SetFlags(flags);
auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&wallPlaceAction)
: GameActions::QueryNested(&wallPlaceAction);
@@ -1343,10 +1339,10 @@ static GameActions::Result TrackDesignPlaceAllScenery(
static std::optional<GameActions::Result> TrackDesignPlaceEntrances(
TrackDesignState& tds, const TrackDesign& td, CoordsXYZ newCoords, RideId rideId, money64& totalCost)
{
for (const auto& entrance : td.entrance_elements)
for (const auto& entrance : td.entranceElements)
{
auto rotation = _currentTrackPieceDirection & 3;
CoordsXY entranceMapPos = entrance.Location.ToCoordsXY();
CoordsXY entranceMapPos = entrance.location.ToCoordsXY();
auto rotatedEntranceMapPos = entranceMapPos.Rotate(rotation);
newCoords = { rotatedEntranceMapPos + tds.Origin, newCoords.z };
@@ -1362,8 +1358,8 @@ static std::optional<GameActions::Result> TrackDesignPlaceEntrances(
case PTD_OPERATION_PLACE_GHOST:
case PTD_OPERATION_PLACE_TRACK_PREVIEW:
{
rotation = (rotation + entrance.Location.direction) & 3;
newCoords.z = entrance.Location.z * COORDS_Z_STEP;
rotation = (rotation + entrance.location.direction) & 3;
newCoords.z = entrance.location.z * COORDS_Z_STEP;
newCoords.z += tds.Origin.z;
if (tds.PlaceOperation != PTD_OPERATION_PLACE_QUERY)
@@ -1409,7 +1405,7 @@ static std::optional<GameActions::Result> TrackDesignPlaceEntrances(
}
auto rideEntranceExitPlaceAction = RideEntranceExitPlaceAction(
newCoords, rotation, rideId, stationIndex, entrance.IsExit);
newCoords, rotation, rideId, stationIndex, entrance.isExit);
rideEntranceExitPlaceAction.SetFlags(flags);
auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&rideEntranceExitPlaceAction)
: GameActions::QueryNested(&rideEntranceExitPlaceAction);
@@ -1457,10 +1453,10 @@ static GameActions::Result TrackDesignPlaceMaze(
tds.PlaceZ = 0;
money64 totalCost = 0;
for (const auto& maze_element : td.maze_elements)
for (const auto& maze_element : td.mazeElements)
{
uint8_t rotation = _currentTrackPieceDirection & 3;
CoordsXY mazeMapPos = TileCoordsXY(maze_element.x, maze_element.y).ToCoordsXY();
CoordsXY mazeMapPos = maze_element.location.ToCoordsXY();
auto mapCoord = mazeMapPos.Rotate(rotation);
mapCoord += origin;
@@ -1477,7 +1473,7 @@ static GameActions::Result TrackDesignPlaceMaze(
uint8_t flags;
money64 cost = 0;
uint16_t maze_entry = Numerics::rol16(maze_element.maze_entry, rotation * 4);
uint16_t mazeEntry = Numerics::rol16(maze_element.mazeEntry, rotation * 4);
if (tds.PlaceOperation == PTD_OPERATION_PLACE_TRACK_PREVIEW)
{
@@ -1501,7 +1497,7 @@ static GameActions::Result TrackDesignPlaceMaze(
flags |= GAME_COMMAND_FLAG_REPLAY;
}
auto mazePlace = MazePlaceTrackAction({ mapCoord, origin.z }, ride.id, maze_entry);
auto mazePlace = MazePlaceTrackAction({ mapCoord, origin.z }, ride.id, mazeEntry);
mazePlace.SetFlags(flags);
auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&mazePlace)
: GameActions::QueryNested(&mazePlace);
@@ -1585,7 +1581,7 @@ static GameActions::Result TrackDesignPlaceRide(TrackDesignState& tds, TrackDesi
// Track elements
auto newCoords = origin;
for (const auto& track : td6->track_elements)
for (const auto& track : td6->trackElements)
{
auto trackType = track.Type;
const auto& ted = GetTrackElementDescriptor(trackType);
@@ -1810,7 +1806,7 @@ static GameActions::Result TrackDesignPlaceVirtual(
}
// Scenery elements
auto sceneryPlaceRes = TrackDesignPlaceAllScenery(tds, td6->scenery_elements, coords.direction);
auto sceneryPlaceRes = TrackDesignPlaceAllScenery(tds, td6->sceneryElements, coords.direction);
if (sceneryPlaceRes.Error != GameActions::Status::Ok)
{
return sceneryPlaceRes;
@@ -1903,7 +1899,7 @@ static bool TrackDesignPlacePreview(TrackDesignState& tds, TrackDesign* td6, mon
auto& gameState = GetGameState();
auto& objManager = GetContext()->GetObjectManager();
auto entry_index = objManager.GetLoadedObjectEntryIndex(td6->vehicle_object);
auto entry_index = objManager.GetLoadedObjectEntryIndex(td6->vehicleObject);
RideId rideIndex;
uint8_t rideCreateFlags = GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND;
@@ -1918,7 +1914,7 @@ static bool TrackDesignPlacePreview(TrackDesignState& tds, TrackDesign* td6, mon
ride->custom_name = {};
ride->entrance_style = objManager.GetLoadedObjectEntryIndex(td6->StationObjectIdentifier);
ride->entrance_style = objManager.GetLoadedObjectEntryIndex(td6->stationObjectIdentifier);
if (ride->entrance_style == OBJECT_ENTRY_INDEX_NULL)
{
ride->entrance_style = gameState.LastEntranceStyle;
@@ -1926,9 +1922,9 @@ static bool TrackDesignPlacePreview(TrackDesignState& tds, TrackDesign* td6, mon
for (int32_t i = 0; i < OpenRCT2::Limits::kNumColourSchemes; i++)
{
ride->track_colour[i].main = td6->track_spine_colour[i];
ride->track_colour[i].additional = td6->track_rail_colour[i];
ride->track_colour[i].supports = td6->track_support_colour[i];
ride->track_colour[i].main = td6->trackSpineColour[i];
ride->track_colour[i].additional = td6->trackRailColour[i];
ride->track_colour[i].supports = td6->trackSupportColour[i];
}
// Flat rides need their vehicle colours loaded for display
@@ -1937,7 +1933,7 @@ static bool TrackDesignPlacePreview(TrackDesignState& tds, TrackDesign* td6, mon
{
for (size_t i = 0; i < std::size(ride->vehicle_colours); i++)
{
ride->vehicle_colours[i] = td6->vehicle_colours[i];
ride->vehicle_colours[i] = td6->vehicleColours[i];
}
}
@@ -2022,7 +2018,7 @@ void TrackDesignDrawPreview(TrackDesign* td6, uint8_t* pixels)
return;
}
td6->cost = cost;
td6->track_flags = flags & 7;
td6->trackFlags = flags & 7;
CoordsXYZ centre = { (tds.PreviewMin.x + tds.PreviewMax.x) / 2 + 16, (tds.PreviewMin.y + tds.PreviewMax.y) / 2 + 16,
(tds.PreviewMin.z + tds.PreviewMax.z) / 2 };

View File

@@ -40,17 +40,18 @@ struct TrackDesignState
/* Track Entrance entry */
struct TrackDesignEntranceElement
{
TileCoordsXYZD Location{};
bool IsExit{};
TileCoordsXYZD location{};
bool isExit{};
};
struct TrackDesignSceneryElement
{
ObjectEntryDescriptor scenery_object;
ObjectEntryDescriptor sceneryObject;
CoordsXYZ loc;
uint8_t flags;
uint8_t primary_colour;
uint8_t secondary_colour;
colour_t primaryColour;
colour_t secondaryColour;
colour_t tertiaryColour = COLOUR_DARK_BROWN;
bool IsQueue() const
{
@@ -90,27 +91,10 @@ struct TrackDesignTrackElement
}
};
/* Maze Element entry size: 0x04 */
struct TrackDesignMazeElement
{
union
{
uint32_t all;
struct
{
int8_t x;
int8_t y;
union
{
uint16_t maze_entry;
struct
{
uint8_t direction;
uint8_t type;
};
};
};
};
TileCoordsXY location{};
uint16_t mazeEntry{};
};
class DataSerialiser;
@@ -119,49 +103,47 @@ enum class RideMode : uint8_t;
struct TrackDesign
{
uint8_t type;
uint8_t vehicle_type;
uint8_t vehicleType;
money64 cost;
uint32_t flags;
RideMode ride_mode;
uint8_t track_flags;
uint8_t colour_scheme;
std::array<VehicleColour, OpenRCT2::Limits::kMaxVehicleColours> vehicle_colours;
u8string StationObjectIdentifier{};
uint8_t total_air_time;
uint8_t depart_flags;
uint8_t number_of_trains;
uint8_t number_of_cars_per_train;
uint8_t min_waiting_time;
uint8_t max_waiting_time;
uint8_t operation_setting;
int8_t max_speed;
int8_t average_speed;
uint16_t ride_length;
uint8_t max_positive_vertical_g;
int8_t max_negative_vertical_g;
uint8_t max_lateral_g;
RideMode rideMode;
uint8_t trackFlags;
uint8_t colourScheme;
std::array<VehicleColour, OpenRCT2::Limits::kMaxVehicleColours> vehicleColours;
u8string stationObjectIdentifier{};
uint8_t totalAirTime;
uint8_t departFlags;
uint8_t numberOfTrains;
uint8_t numberOfCarsPerTrain;
uint8_t minWaitingTime;
uint8_t maxWaitingTime;
uint8_t operationSetting;
int8_t maxSpeed;
int8_t averageSpeed;
uint16_t rideLength;
uint8_t maxPositiveVerticalG;
int8_t maxNegativeVerticalG;
uint8_t maxLateralG;
uint8_t inversions;
uint8_t holes;
uint8_t drops;
uint8_t highest_drop_height;
uint8_t highestDropHeight;
uint8_t excitement;
uint8_t intensity;
uint8_t nausea;
money64 upkeep_cost;
uint8_t track_spine_colour[OpenRCT2::Limits::kNumColourSchemes];
uint8_t track_rail_colour[OpenRCT2::Limits::kNumColourSchemes];
uint8_t track_support_colour[OpenRCT2::Limits::kNumColourSchemes];
uint32_t flags2;
ObjectEntryDescriptor vehicle_object;
uint8_t space_required_x;
uint8_t space_required_y;
uint8_t lift_hill_speed;
uint8_t num_circuits;
money64 upkeepCost;
uint8_t trackSpineColour[OpenRCT2::Limits::kNumColourSchemes];
uint8_t trackRailColour[OpenRCT2::Limits::kNumColourSchemes];
uint8_t trackSupportColour[OpenRCT2::Limits::kNumColourSchemes];
ObjectEntryDescriptor vehicleObject;
uint8_t spaceRequiredX;
uint8_t spaceRequiredY;
uint8_t liftHillSpeed;
uint8_t numCircuits;
std::vector<TrackDesignMazeElement> maze_elements;
std::vector<TrackDesignTrackElement> track_elements;
std::vector<TrackDesignEntranceElement> entrance_elements;
std::vector<TrackDesignSceneryElement> scenery_elements;
std::vector<TrackDesignMazeElement> mazeElements;
std::vector<TrackDesignTrackElement> trackElements;
std::vector<TrackDesignEntranceElement> entranceElements;
std::vector<TrackDesignSceneryElement> sceneryElements;
std::string name;

View File

@@ -80,7 +80,7 @@ public:
item.Name = GetNameFromTrackPath(path);
item.Path = path;
item.RideType = td6->type;
item.ObjectEntry = std::string(td6->vehicle_object.Entry.name, 8);
item.ObjectEntry = std::string(td6->vehicleObject.Entry.name, 8);
item.Flags = 0;
if (IsTrackReadOnly(path))
{

View File

@@ -209,20 +209,23 @@ static bool TrackDesignSaveIsSupportedObject(const Object* obj)
}
static void TrackDesignSavePushTileElementDesc(
const RCTObjectEntry& entry, const CoordsXYZ& loc, uint8_t flags, uint8_t primaryColour, uint8_t secondaryColour)
const RCTObjectEntry& entry, const CoordsXYZ& loc, uint8_t flags, colour_t primaryColour, colour_t secondaryColour,
colour_t tertiaryColour)
{
TrackDesignSceneryElement item{};
item.scenery_object = ObjectEntryDescriptor(entry);
item.sceneryObject = ObjectEntryDescriptor(entry);
item.loc = loc;
item.flags = flags;
item.primary_colour = primaryColour;
item.secondary_colour = secondaryColour;
item.primaryColour = primaryColour;
item.secondaryColour = secondaryColour;
item.tertiaryColour = tertiaryColour;
_trackSavedTileElementsDesc.push_back(std::move(item));
}
static void TrackDesignSavePushTileElementDesc(
const Object* obj, const CoordsXYZ& loc, uint8_t flags, uint8_t primaryColour, uint8_t secondaryColour)
const Object* obj, const CoordsXYZ& loc, uint8_t flags, uint8_t primaryColour, uint8_t secondaryColour,
colour_t tertiaryColour)
{
const auto& entry = obj->GetObjectEntry();
if (entry.IsEmpty())
@@ -231,7 +234,7 @@ static void TrackDesignSavePushTileElementDesc(
assert(false);
}
TrackDesignSavePushTileElementDesc(entry, loc, flags, primaryColour, secondaryColour);
TrackDesignSavePushTileElementDesc(entry, loc, flags, primaryColour, secondaryColour, tertiaryColour);
}
static TrackDesignAddStatus TrackDesignSaveAddSmallScenery(const CoordsXY& loc, SmallSceneryElement* sceneryElement)
@@ -244,12 +247,13 @@ static TrackDesignAddStatus TrackDesignSaveAddSmallScenery(const CoordsXY& loc,
flags |= sceneryElement->GetDirection();
flags |= sceneryElement->GetSceneryQuadrant() << 2;
uint8_t primaryColour = sceneryElement->GetPrimaryColour();
uint8_t secondaryColour = sceneryElement->GetSecondaryColour();
auto primaryColour = sceneryElement->GetPrimaryColour();
auto secondaryColour = sceneryElement->GetSecondaryColour();
auto tertiaryColour = sceneryElement->GetTertiaryColour();
TrackDesignSavePushTileElement(loc, reinterpret_cast<TileElement*>(sceneryElement));
TrackDesignSavePushTileElementDesc(
obj, { loc.x, loc.y, sceneryElement->GetBaseZ() }, flags, primaryColour, secondaryColour);
obj, { loc.x, loc.y, sceneryElement->GetBaseZ() }, flags, primaryColour, secondaryColour, tertiaryColour);
return TrackDesignAddStatus::Success();
}
@@ -292,10 +296,11 @@ static TrackDesignAddStatus TrackDesignSaveAddLargeScenery(const CoordsXY& loc,
if (sequence == 0)
{
uint8_t flags = largeElement->GetDirection();
uint8_t primaryColour = largeElement->GetPrimaryColour();
uint8_t secondaryColour = largeElement->GetSecondaryColour();
auto primaryColour = largeElement->GetPrimaryColour();
auto secondaryColour = largeElement->GetSecondaryColour();
auto tertiaryColour = largeElement->GetTertiaryColour();
TrackDesignSavePushTileElementDesc(obj, tileLoc, flags, primaryColour, secondaryColour);
TrackDesignSavePushTileElementDesc(obj, tileLoc, flags, primaryColour, secondaryColour, tertiaryColour);
}
TrackDesignSavePushTileElement({ tileLoc.x, tileLoc.y }, reinterpret_cast<TileElement*>(largeElement));
}
@@ -314,14 +319,14 @@ static TrackDesignAddStatus TrackDesignSaveAddWall(const CoordsXY& loc, WallElem
{
uint8_t flags = 0;
flags |= wallElement->GetDirection();
flags |= wallElement->GetTertiaryColour() << 2;
uint8_t secondaryColour = wallElement->GetSecondaryColour();
uint8_t primaryColour = wallElement->GetPrimaryColour();
auto primaryColour = wallElement->GetPrimaryColour();
auto secondaryColour = wallElement->GetSecondaryColour();
auto tertiaryColour = wallElement->GetTertiaryColour();
TrackDesignSavePushTileElement(loc, reinterpret_cast<TileElement*>(wallElement));
TrackDesignSavePushTileElementDesc(
obj, { loc.x, loc.y, wallElement->GetBaseZ() }, flags, primaryColour, secondaryColour);
obj, { loc.x, loc.y, wallElement->GetBaseZ() }, flags, primaryColour, secondaryColour, tertiaryColour);
return TrackDesignAddStatus::Success();
}
@@ -371,7 +376,7 @@ static TrackDesignAddStatus TrackDesignSaveAddFootpath(const CoordsXY& loc, Path
flags |= 1 << 7;
TrackDesignSavePushTileElement(loc, reinterpret_cast<TileElement*>(pathElement));
TrackDesignSavePushTileElementDesc(*pathEntry, { loc.x, loc.y, pathElement->GetBaseZ() }, flags, 0, 0);
TrackDesignSavePushTileElementDesc(*pathEntry, { loc.x, loc.y, pathElement->GetBaseZ() }, flags, 0, 0, 0);
return TrackDesignAddStatus::Success();
}
@@ -439,7 +444,7 @@ static void TrackDesignSavePopTileElementDesc(const ObjectEntryDescriptor& entry
continue;
if (item->flags != flags)
continue;
if (item->scenery_object != entry)
if (item->sceneryObject != entry)
continue;
removeIndex = i;