OpenRCT2/src/openrct2-ui/ride/Construction.cpp

100 lines
4.1 KiB
C++

/*****************************************************************************
* Copyright (c) 2014-2024 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#include "Construction.h"
#include <openrct2/actions/RideCreateAction.h>
#include <openrct2/ride/Ride.h>
#include <openrct2/ride/RideConstruction.h>
#include <openrct2/ride/RideData.h>
#include <openrct2/ride/RideTypes.h>
#include <openrct2/ride/TrackData.h>
using namespace OpenRCT2::TrackMetaData;
/**
*
* rct2: 0x006B4800
*/
void RideConstructNew(RideSelection listItem)
{
int32_t rideEntryIndex = RideGetEntryIndex(listItem.Type, listItem.EntryIndex);
int32_t colour1 = RideGetRandomColourPresetIndex(listItem.Type);
int32_t colour2 = RideGetUnusedPresetVehicleColour(rideEntryIndex);
auto gameAction = RideCreateAction(listItem.Type, listItem.EntryIndex, colour1, colour2, gLastEntranceStyle);
gameAction.SetCallback([](const GameAction* ga, const GameActions::Result* result) {
if (result->Error != GameActions::Status::Ok)
return;
const auto rideIndex = result->GetData<RideId>();
auto ride = GetRide(rideIndex);
RideConstructionStart(*ride);
});
GameActions::Execute(&gameAction);
}
SpecialElementsDropdownState BuildSpecialElementsList(
const Ride& currentRide, uint8_t buildDirection, uint8_t buildSlope, uint8_t buildBank, RideConstructionState state)
{
auto buildDirectionIsDiagonal = TrackPieceDirectionIsDiagonal(buildDirection);
SpecialElementsDropdownState list;
// if it's building neither forwards nor backwards, no list is available
if (state != RideConstructionState::Front && state != RideConstructionState::Place && state != RideConstructionState::Back)
return list;
for (track_type_t trackType : DropdownOrder)
{
const auto& ted = GetTrackElementDescriptor(trackType);
if (!IsTrackEnabled(ted.Definition.type))
continue;
bool entryIsDisabled;
// If the current build orientation (slope, bank, diagonal) matches the track element's, show the piece as enabled
if (state == RideConstructionState::Back)
{
entryIsDisabled = ted.Definition.vangle_end != buildSlope || ted.Definition.bank_end != buildBank
|| TrackPieceDirectionIsDiagonal(ted.Coordinates.rotation_end) != buildDirectionIsDiagonal;
}
else
{
entryIsDisabled = ted.Definition.vangle_start != buildSlope || ted.Definition.bank_start != buildBank
|| TrackPieceDirectionIsDiagonal(ted.Coordinates.rotation_begin) != buildDirectionIsDiagonal;
}
// Additional tower bases can only be built if the ride allows for it (elevator)
if (trackType == TrackElemType::TowerBase
&& !currentRide.GetRideTypeDescriptor().HasFlag(RIDE_TYPE_FLAG_ALLOW_EXTRA_TOWER_BASES))
entryIsDisabled = true;
// Check if a previous element exists, to collate entries if possible
if (!list.Elements.empty() && GetTrackElementDescriptor(list.Elements.back().TrackType).Description == ted.Description)
{
// If the current element is disabled, do not add current element.
if (entryIsDisabled)
continue;
auto& lastElement = list.Elements.back();
// If the previous element is disabled and current element is enabled, replace the previous element
if (lastElement.Disabled && !entryIsDisabled)
{
lastElement.TrackType = trackType;
lastElement.Disabled = false;
list.HasActiveElements = true;
continue;
}
// If the previous element and current element are enabled, add both to the list
}
list.Elements.push_back({ trackType, entryIsDisabled });
list.HasActiveElements |= !entryIsDisabled;
}
return list;
}