Reduce direct ride type checking; move available piece lookup to RTD (#11353)

This commit is contained in:
Michael Steenbeek 2020-04-19 13:32:43 +02:00 committed by GitHub
parent d17b4606f3
commit 8127437de1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 42 additions and 41 deletions

View File

@ -2780,7 +2780,7 @@ static rct_string_id window_ride_get_status_vehicle(rct_window* w, void* argumen
|| trackType == TRACK_ELEM_25_DEG_UP_TO_FLAT || trackType == TRACK_ELEM_60_DEG_UP_TO_FLAT
|| trackType == TRACK_ELEM_DIAG_25_DEG_UP_TO_FLAT || trackType == TRACK_ELEM_DIAG_60_DEG_UP_TO_FLAT)
{
if (track_piece_is_available_for_ride_type(ride->type, TRACK_BLOCK_BRAKES) && vehicle->velocity == 0)
if (RideTypeDescriptors[ride->type].SupportsTrackPiece(TRACK_BLOCK_BRAKES) && vehicle->velocity == 0)
{
*reinterpret_cast<rct_string_id*>(reinterpret_cast<uintptr_t>(arguments)) = STR_STOPPED_BY_BLOCK_BRAKES;
return STR_BLACK_STRING;
@ -3646,10 +3646,10 @@ static void window_ride_operating_invalidate(rct_window* w)
| (1ULL << WIDX_SYNCHRONISE_WITH_ADJACENT_STATIONS_CHECKBOX));
// Sometimes, only one of the alternatives support lift hill pieces. Make sure to check both.
bool hasAlternativeType = (RideTypeDescriptors[ride->type].Flags & RIDE_TYPE_FLAG_HAS_ALTERNATIVE_TRACK_TYPE) != 0;
if (track_piece_is_available_for_ride_type(ride->type, TRACK_LIFT_HILL)
bool hasAlternativeType = RideTypeDescriptors[ride->type].HasFlag(RIDE_TYPE_FLAG_HAS_ALTERNATIVE_TRACK_TYPE);
if (RideTypeDescriptors[ride->type].SupportsTrackPiece(TRACK_LIFT_HILL)
|| (hasAlternativeType
&& track_piece_is_available_for_ride_type(RideData4[ride->type].alternate_type, TRACK_LIFT_HILL)))
&& RideTypeDescriptors[RideData4[ride->type].alternate_type].SupportsTrackPiece(TRACK_LIFT_HILL)))
{
window_ride_operating_widgets[WIDX_LIFT_HILL_SPEED_LABEL].type = WWT_LABEL;
window_ride_operating_widgets[WIDX_LIFT_HILL_SPEED].type = WWT_SPINNER;

View File

@ -1109,7 +1109,7 @@ static void window_ride_construction_resize(rct_window* w)
disabledWidgets |= (1ULL << WIDX_SLOPE_UP_STEEP);
}
disabledWidgets |= (1ULL << WIDX_LEFT_CURVE_LARGE) | (1ULL << WIDX_RIGHT_CURVE_LARGE);
if (rideType == RIDE_TYPE_REVERSE_FREEFALL_COASTER || rideType == RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER)
if (RideTypeDescriptors[ride->type].SupportsTrackPiece(TRACK_REVERSE_FREEFALL))
{
disabledWidgets |= (1ULL << WIDX_STRAIGHT) | (1ULL << WIDX_RIGHT_CURVE) | (1ULL << WIDX_RIGHT_CURVE_SMALL)
| (1ULL << WIDX_LEFT_CURVE_SMALL) | (1ULL << WIDX_LEFT_CURVE);
@ -1122,7 +1122,7 @@ static void window_ride_construction_resize(rct_window* w)
disabledWidgets |= (1ULL << WIDX_SLOPE_DOWN_STEEP);
}
disabledWidgets |= (1ULL << WIDX_LEFT_CURVE_LARGE) | (1ULL << WIDX_RIGHT_CURVE_LARGE);
if (rideType == RIDE_TYPE_REVERSE_FREEFALL_COASTER || rideType == RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER)
if (RideTypeDescriptors[ride->type].SupportsTrackPiece(TRACK_REVERSE_FREEFALL))
{
disabledWidgets |= (1ULL << WIDX_STRAIGHT) | (1ULL << WIDX_RIGHT_CURVE) | (1ULL << WIDX_RIGHT_CURVE_SMALL)
| (1ULL << WIDX_LEFT_CURVE_SMALL) | (1ULL << WIDX_LEFT_CURVE);
@ -1433,7 +1433,7 @@ static void window_ride_construction_mousedown(rct_window* w, rct_widgetindex wi
{
_currentTrackBankEnd = TRACK_BANK_NONE;
}
if (ride->type == RIDE_TYPE_REVERSE_FREEFALL_COASTER || ride->type == RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER)
if (RideTypeDescriptors[ride->type].SupportsTrackPiece(TRACK_REVERSE_FREEFALL))
{
if (_rideConstructionState == RIDE_CONSTRUCTION_STATE_FRONT && _currentTrackCurve == TRACK_CURVE_NONE)
{
@ -2542,20 +2542,15 @@ void window_ride_construction_update_enabled_track_pieces()
int32_t rideType = (_currentTrackAlternative & RIDE_TYPE_ALTERNATIVE_TRACK_TYPE) ? RideData4[ride->type].alternate_type
: ride->type;
if (gCheatsEnableAllDrawableTrackPieces)
{
_enabledRidePieces = get_available_track_pieces_for_ride_type(rideType);
return;
}
if (RideGroupManager::RideTypeHasRideGroups(rideType))
if (!gCheatsEnableAllDrawableTrackPieces && RideGroupManager::RideTypeHasRideGroups(rideType))
{
const RideGroup* rideGroup = RideGroupManager::GetRideGroup(rideType, rideEntry);
_enabledRidePieces = rideGroup->AvailableTrackPieces;
}
else
{
_enabledRidePieces = get_available_track_pieces_for_ride_type(rideType);
_enabledRidePieces = RideTypeDescriptors[rideType].GetAvailableTrackPieces();
}
}
@ -2919,7 +2914,7 @@ static void window_ride_construction_update_widgets(rct_window* w)
window_ride_construction_widgets[WIDX_SLOPE_DOWN_STEEP].tooltip = STR_RIDE_CONSTRUCTION_STEEP_SLOPE_DOWN_TIP;
window_ride_construction_widgets[WIDX_SLOPE_UP_STEEP].image = SPR_RIDE_CONSTRUCTION_SLOPE_UP_STEEP;
window_ride_construction_widgets[WIDX_SLOPE_UP_STEEP].tooltip = STR_RIDE_CONSTRUCTION_STEEP_SLOPE_UP_TIP;
if (rideType == RIDE_TYPE_REVERSE_FREEFALL_COASTER || rideType == RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER)
if (RideTypeDescriptors[rideType].SupportsTrackPiece(TRACK_REVERSE_FREEFALL))
{
window_ride_construction_widgets[WIDX_LEVEL].type = WWT_FLATBTN;
window_ride_construction_widgets[WIDX_SLOPE_UP].type = WWT_FLATBTN;

View File

@ -151,7 +151,7 @@ public:
}
// Backwards steep lift hills are allowed, even on roller coasters that do not support forwards steep lift hills.
if ((_trackPlaceFlags & CONSTRUCTION_LIFT_HILL_SELECTED)
&& !track_piece_is_available_for_ride_type(ride->type, TRACK_LIFT_HILL_STEEP)
&& !RideTypeDescriptors[ride->type].SupportsTrackPiece(TRACK_LIFT_HILL_STEEP)
&& !gCheatsEnableChainLiftOnAllTrack)
{
if (TrackFlags[_trackType] & TRACK_ELEM_FLAG_IS_STEEP_UP)
@ -231,7 +231,8 @@ public:
return std::make_unique<TrackPlaceActionResult>(GA_ERROR::INVALID_PARAMETERS, STR_TOO_HIGH);
}
uint8_t crossingMode = (ride->type == RIDE_TYPE_MINIATURE_RAILWAY && _trackType == TRACK_ELEM_FLAT)
uint8_t crossingMode = (RideTypeDescriptors[ride->type].HasFlag(RIDE_TYPE_FLAG_SUPPORTS_LEVEL_CROSSINGS)
&& _trackType == TRACK_ELEM_FLAT)
? CREATE_CROSSING_MODE_TRACK_OVER_PATH
: CREATE_CROSSING_MODE_NONE;
if (!map_can_construct_with_clear_at(
@ -469,7 +470,8 @@ public:
clearanceZ = floor2(clearanceZ, COORDS_Z_STEP) + baseZ;
const auto mapLocWithClearance = CoordsXYRangedZ(mapLoc, baseZ, clearanceZ);
uint8_t crossingMode = (ride->type == RIDE_TYPE_MINIATURE_RAILWAY && _trackType == TRACK_ELEM_FLAT)
uint8_t crossingMode = (RideTypeDescriptors[ride->type].HasFlag(RIDE_TYPE_FLAG_SUPPORTS_LEVEL_CROSSINGS)
&& _trackType == TRACK_ELEM_FLAT)
? CREATE_CROSSING_MODE_TRACK_OVER_PATH
: CREATE_CROSSING_MODE_NONE;
if (!map_can_construct_with_clear_at(

View File

@ -572,22 +572,6 @@ bool ride_entry_is_invented(int32_t rideEntryIndex)
return _researchedRideEntries[rideEntryIndex];
}
uint64_t get_available_track_pieces_for_ride_type(uint8_t rideType)
{
uint64_t baseVals = RideTypeDescriptors[rideType].EnabledTrackPieces;
uint64_t extendedVals = 0;
if (gCheatsEnableAllDrawableTrackPieces)
{
extendedVals = RideTypeDescriptors[rideType].ExtraTrackPieces;
}
return baseVals | extendedVals;
}
bool track_piece_is_available_for_ride_type(uint8_t rideType, int32_t trackType)
{
return (get_available_track_pieces_for_ride_type(rideType)) & (1ULL << trackType);
}
void ride_type_set_invented(uint32_t rideType)
{
Guard::Assert(rideType < std::size(_researchedRideTypes), GUARD_LINE);

View File

@ -131,8 +131,6 @@ void scenery_set_invented(const ScenerySelection& sceneryItem);
void scenery_set_not_invented(const ScenerySelection& sceneryItem);
bool ride_type_is_invented(uint32_t rideType);
bool ride_entry_is_invented(int32_t rideEntryIndex);
uint64_t get_available_track_pieces_for_ride_type(uint8_t rideType);
bool track_piece_is_available_for_ride_type(uint8_t rideType, int32_t trackType);
bool scenery_group_is_invented(int32_t sgIndex);
void scenery_group_set_invented(int32_t sgIndex);
bool scenery_is_invented(const ScenerySelection& sceneryItem);

View File

@ -19,6 +19,7 @@
#include "RideData.h"
#include "../Cheats.h"
#include "../audio/audio.h"
#include "../interface/Colour.h"
#include "../localisation/Localisation.h"
@ -2505,3 +2506,17 @@ bool RideTypeDescriptor::HasFlag(uint64_t flag) const
{
return Flags & flag;
}
uint64_t RideTypeDescriptor::GetAvailableTrackPieces() const
{
if (gCheatsEnableAllDrawableTrackPieces)
{
return EnabledTrackPieces | ExtraTrackPieces;
}
return EnabledTrackPieces;
}
bool RideTypeDescriptor::SupportsTrackPiece(const uint64_t trackPiece) const
{
return GetAvailableTrackPieces() & (1ULL << trackPiece);
}

View File

@ -99,6 +99,8 @@ struct RideTypeDescriptor
uint8_t AvailableBreakdowns;
bool HasFlag(uint64_t flag) const;
uint64_t GetAvailableTrackPieces() const;
bool SupportsTrackPiece(const uint64_t trackPiece) const;
};
#ifdef _WIN32
@ -176,6 +178,7 @@ enum ride_type_flags : uint64_t
RIDE_TYPE_FLAG_START_CONSTRUCTION_INVERTED = (1ULL << 47), // This is only set on the Flying RC and its alternative type.
RIDE_TYPE_FLAG_LIST_VEHICLES_SEPARATELY = (1ULL << 48),
RIDE_TYPE_FLAG_SUPPORTS_LEVEL_CROSSINGS = (1ULL << 49),
};
// Set on ride types that have a main colour, additional colour and support colour.

View File

@ -9855,8 +9855,9 @@ void Vehicle::UpdateCrossings() const
auto curRide = get_ride(ride);
// Many New Element parks have invisible rides hacked into the path.
// Limit path blocking to Miniature Railway to prevent peeps getting stuck everywhere.
if (pathElement && curRide != nullptr && curRide->type == RIDE_TYPE_MINIATURE_RAILWAY)
// Limit path blocking to rides actually supporting level crossings to prevent peeps getting stuck everywhere.
if (pathElement && curRide != nullptr
&& RideTypeDescriptors[curRide->type].HasFlag(RIDE_TYPE_FLAG_SUPPORTS_LEVEL_CROSSINGS))
{
if (!playedClaxon && !pathElement->IsBlockedByVehicle())
{

View File

@ -23,7 +23,8 @@ constexpr const RideTypeDescriptor MiniatureRailwayRTD =
RIDE_TYPE_FLAG_HAS_DATA_LOGGING | RIDE_TYPE_FLAG_HAS_LOAD_OPTIONS | RIDE_TYPE_FLAG_HAS_VEHICLE_COLOURS |
RIDE_TYPE_FLAG_HAS_TRACK | RIDE_TYPE_FLAG_HAS_LARGE_CURVES | RIDE_TYPE_FLAG_SUPPORTS_MULTIPLE_TRACK_COLOUR |
RIDE_TYPE_FLAG_ALLOW_MUSIC | RIDE_TYPE_FLAG_HAS_ENTRANCE_EXIT | RIDE_TYPE_FLAG_ALLOW_MORE_VEHICLES_THAN_STATION_FITS |
RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS | RIDE_TYPE_FLAG_TRANSPORT_RIDE | RIDE_TYPE_FLAG_SHOW_IN_TRACK_DESIGNER),
RIDE_TYPE_FLAG_ALLOW_MULTIPLE_CIRCUITS | RIDE_TYPE_FLAG_TRANSPORT_RIDE | RIDE_TYPE_FLAG_SHOW_IN_TRACK_DESIGNER |
RIDE_TYPE_FLAG_SUPPORTS_LEVEL_CROSSINGS),
SET_FIELD(NameConvention, { RIDE_COMPONENT_TYPE_TRAIN, RIDE_COMPONENT_TYPE_TRACK, RIDE_COMPONENT_TYPE_STATION }),
SET_FIELD(AvailableBreakdowns, (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION)),
};

View File

@ -2260,5 +2260,5 @@ bool PathElement::IsLevelCrossing(const CoordsXY& coords) const
return false;
}
return (ride->type == RIDE_TYPE_MINIATURE_RAILWAY);
return RideTypeDescriptors[ride->type].HasFlag(RIDE_TYPE_FLAG_SUPPORTS_LEVEL_CROSSINGS);
}

View File

@ -1436,7 +1436,7 @@ static GameActionResult::Ptr map_can_construct_with_clear_at(
&& tileElement->GetBaseZ() == pos.baseZ && tileElement->AsTrack()->GetTrackType() == TRACK_ELEM_FLAT)
{
auto ride = get_ride(tileElement->AsTrack()->GetRideIndex());
if (ride != nullptr && ride->type == RIDE_TYPE_MINIATURE_RAILWAY)
if (ride != nullptr && RideTypeDescriptors[ride->type].HasFlag(RIDE_TYPE_FLAG_SUPPORTS_LEVEL_CROSSINGS))
{
continue;
}

View File

@ -28,6 +28,8 @@ class StationObject;
#define gTileElementTilePointers RCT2_ADDRESS(0x013CE9A4, TileElement*)
rct_sprite* sprite_list = RCT2_ADDRESS(0x010E63BC, rct_sprite);
bool gCheatsEnableAllDrawableTrackPieces = false;
Ride gRideList[MAX_RIDES];
int16_t gMapSizeUnits;
int16_t gMapBaseZ;