1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-18 04:23:20 +01:00
Files
OpenRCT2/src/openrct2/ride/RideGroupManager.cpp
2020-06-17 21:46:37 +02:00

248 lines
12 KiB
C++

/*****************************************************************************
* Copyright (c) 2014-2019 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 "RideGroupManager.h"
#include "../Context.h"
#include "../config/Config.h"
#include "../core/String.hpp"
#include "../localisation/StringIds.h"
#include "../management/Research.h"
#include "../object/ObjectManager.h"
#include "Ride.h"
#include "RideData.h"
#include "Track.h"
#include "TrackData.h"
#include <memory>
#include <vector>
static constexpr const RideGroup ride_group_corkscrew_rc = {
/*.RideType =*/RIDE_TYPE_CORKSCREW_ROLLER_COASTER,
/*.MaximumHeight =*/28,
/*.AvailableTrackPieces =*/(1ULL << TRACK_STRAIGHT) | (1ULL << TRACK_STATION_END) | (1ULL << TRACK_LIFT_HILL)
| (1ULL << TRACK_FLAT_ROLL_BANKING) | (1ULL << TRACK_VERTICAL_LOOP) | (1ULL << TRACK_SLOPE)
| (1ULL << TRACK_SLOPE_STEEP) | (1ULL << TRACK_SLOPE_CURVE) | (1ULL << TRACK_SLOPE_CURVE_STEEP) | (1ULL << TRACK_S_BEND)
| (1ULL << TRACK_CURVE_SMALL) | (1ULL << TRACK_CURVE) | (1ULL << TRACK_HALF_LOOP) | (1ULL << TRACK_CORKSCREW)
| (1ULL << TRACK_HELIX_SMALL) | (1ULL << TRACK_BRAKES) | (1ULL << TRACK_ON_RIDE_PHOTO) | (1ULL << TRACK_BLOCK_BRAKES)
| (1ULL << TRACK_BOOSTER),
/*.Naming =*/{ STR_CORKSCREW_RC_GROUP, STR_CORKSCREW_RC_GROUP_DESC },
/*.Flags =*/0,
};
static constexpr const RideGroup ride_group_hypercoaster = {
/*.RideType =*/RIDE_TYPE_CORKSCREW_ROLLER_COASTER,
/*.MaximumHeight =*/55,
/*.AvailableTrackPieces =*/(1ULL << TRACK_STRAIGHT) | (1ULL << TRACK_STATION_END) | (1ULL << TRACK_LIFT_HILL)
| (1ULL << TRACK_FLAT_ROLL_BANKING) | (1ULL << TRACK_SLOPE) | (1ULL << TRACK_SLOPE_STEEP) | (1ULL << TRACK_SLOPE_CURVE)
| (1ULL << TRACK_SLOPE_CURVE_STEEP) | (1ULL << TRACK_S_BEND) | (1ULL << TRACK_CURVE_SMALL) | (1ULL << TRACK_CURVE)
| (1ULL << TRACK_HELIX_SMALL) | (1ULL << TRACK_BRAKES) | (1ULL << TRACK_ON_RIDE_PHOTO) | (1ULL << TRACK_BLOCK_BRAKES)
| (1ULL << TRACK_SLOPE_STEEP_LONG),
/*.Naming =*/{ STR_HYPERCOASTER_GROUP, STR_HYPERCOASTER_GROUP_DESC },
/*.Flags =*/0,
};
static constexpr const RideGroup ride_group_car_ride = {
/*.RideType =*/RIDE_TYPE_CAR_RIDE,
/*.MaximumHeight =*/6,
/*.AvailableTrackPieces =*/(1ULL << TRACK_STRAIGHT) | (1ULL << TRACK_STATION_END) | (1ULL << TRACK_SLOPE)
| (1ULL << TRACK_CURVE_VERY_SMALL) | (1ULL << TRACK_CURVE_SMALL) | (1ULL << TRACK_SPINNING_TUNNEL),
/*.Naming =*/{ STR_CAR_RIDE_GROUP, STR_CAR_RIDE_GROUP_DESC },
/*.Flags =*/RIDE_GROUP_FLAG_ALLOW_DOORS_ON_TRACK,
};
static constexpr const RideGroup ride_group_monster_trucks = {
/*.RideType =*/RIDE_TYPE_CAR_RIDE,
/*.MaximumHeight =*/18,
/*.AvailableTrackPieces =*/(1ULL << TRACK_STRAIGHT) | (1ULL << TRACK_STATION_END) | (1ULL << TRACK_SLOPE)
| (1ULL << TRACK_SLOPE_STEEP) | (1ULL << TRACK_CURVE_VERY_SMALL) | (1ULL << TRACK_CURVE_SMALL) | (1ULL << TRACK_RAPIDS),
/*.Naming =*/{ STR_MONSTER_TRUCKS_GROUP, STR_MONSTER_TRUCKS_GROUP_DESC },
/*.Flags =*/RIDE_GROUP_FLAG_ALLOW_DOORS_ON_TRACK,
};
static constexpr const RideGroup ride_group_steel_twister_rc = {
/*.RideType =*/RIDE_TYPE_TWISTER_ROLLER_COASTER,
/*.MaximumHeight =*/40,
/*.AvailableTrackPieces =*/(1ULL << TRACK_FLAT) | (1ULL << TRACK_STRAIGHT) | (1ULL << TRACK_STATION_END)
| (1ULL << TRACK_LIFT_HILL) | (1ULL << TRACK_FLAT_ROLL_BANKING) | (1ULL << TRACK_VERTICAL_LOOP) | (1ULL << TRACK_SLOPE)
| (1ULL << TRACK_SLOPE_STEEP) | (1ULL << TRACK_SLOPE_CURVE) | (1ULL << TRACK_SLOPE_CURVE_STEEP) | (1ULL << TRACK_S_BEND)
| (1ULL << TRACK_CURVE_SMALL) | (1ULL << TRACK_CURVE) | (1ULL << TRACK_HALF_LOOP) | (1ULL << TRACK_CORKSCREW)
| (1ULL << TRACK_HELIX_SMALL) | (1ULL << TRACK_BRAKES) | (1ULL << TRACK_ON_RIDE_PHOTO) | (1ULL << TRACK_SLOPE_VERTICAL)
| (1ULL << TRACK_BARREL_ROLL) | (1ULL << TRACK_POWERED_LIFT) | (1ULL << TRACK_HALF_LOOP_LARGE)
| (1ULL << TRACK_SLOPE_CURVE_BANKED) | (1ULL << TRACK_BLOCK_BRAKES) | (1ULL << TRACK_SLOPE_ROLL_BANKING)
| (1ULL << TRACK_SLOPE_STEEP_LONG) | (1ULL << TRACK_CURVE_VERTICAL) | (1ULL << TRACK_QUARTER_LOOP)
| (1ULL << TRACK_BOOSTER),
/*.Naming =*/{ STR_STEEL_TWISTER_GROUP, STR_STEEL_TWISTER_GROUP_DESC },
/*.Flags =*/0,
};
static constexpr const RideGroup ride_group_hyper_twister = {
/*.RideType =*/RIDE_TYPE_TWISTER_ROLLER_COASTER,
/*.MaximumHeight =*/54,
/*.AvailableTrackPieces =*/(1ULL << TRACK_FLAT) | (1ULL << TRACK_STRAIGHT) | (1ULL << TRACK_STATION_END)
| (1ULL << TRACK_LIFT_HILL) | (1ULL << TRACK_FLAT_ROLL_BANKING) | (1ULL << TRACK_SLOPE) | (1ULL << TRACK_SLOPE_STEEP)
| (1ULL << TRACK_SLOPE_CURVE) | (1ULL << TRACK_SLOPE_CURVE_STEEP) | (1ULL << TRACK_S_BEND) | (1ULL << TRACK_CURVE_SMALL)
| (1ULL << TRACK_CURVE) | (1ULL << TRACK_HELIX_SMALL) | (1ULL << TRACK_BRAKES) | (1ULL << TRACK_ON_RIDE_PHOTO)
| (1ULL << TRACK_SLOPE_CURVE_BANKED) | (1ULL << TRACK_BLOCK_BRAKES) | (1ULL << TRACK_SLOPE_ROLL_BANKING)
| (1ULL << TRACK_SLOPE_STEEP_LONG) | (1ULL << TRACK_SLOPE_VERTICAL) | (1ULL << TRACK_CURVE_VERTICAL),
/*.Naming =*/{ STR_HYPER_TWISTER_GROUP, STR_HYPER_TWISTER_GROUP_DESC },
/*.Flags =*/0,
};
static constexpr const RideGroup ride_group_junior_rc = {
/*.RideType =*/RIDE_TYPE_JUNIOR_ROLLER_COASTER,
/*.MaximumHeight =*/12,
/*.AvailableTrackPieces =*/(1ULL << TRACK_STRAIGHT) | (1ULL << TRACK_STATION_END) | (1ULL << TRACK_LIFT_HILL)
| (1ULL << TRACK_LIFT_HILL_CURVE) | (1ULL << TRACK_FLAT_ROLL_BANKING) | (1ULL << TRACK_SLOPE)
| (1ULL << TRACK_SLOPE_LONG) | (1ULL << TRACK_SLOPE_CURVE) | (1ULL << TRACK_S_BEND) | (1ULL << TRACK_CURVE_SMALL)
| (1ULL << TRACK_CURVE) | (1ULL << TRACK_HELIX_SMALL) | (1ULL << TRACK_BRAKES) | (1ULL << TRACK_BLOCK_BRAKES)
| (1ULL << TRACK_BOOSTER),
/*.Naming =*/{ STR_JUNIOR_RC_GROUP, STR_JUNIOR_RC_GROUP_DESC },
/*.Flags =*/RIDE_GROUP_FLAG_ALLOW_DOORS_ON_TRACK,
};
static constexpr const RideGroup ride_group_classic_mini_coaster = {
/*.RideType =*/RIDE_TYPE_JUNIOR_ROLLER_COASTER,
/*.MaximumHeight =*/15,
/*.AvailableTrackPieces =*/(1ULL << TRACK_STRAIGHT) | (1ULL << TRACK_STATION_END) | (1ULL << TRACK_LIFT_HILL)
| (1ULL << TRACK_LIFT_HILL_CURVE) | (1ULL << TRACK_FLAT_ROLL_BANKING) | (1ULL << TRACK_SLOPE)
| (1ULL << TRACK_SLOPE_STEEP) | (1ULL << TRACK_SLOPE_LONG) | (1ULL << TRACK_SLOPE_CURVE) | (1ULL << TRACK_S_BEND)
| (1ULL << TRACK_CURVE_SMALL) | (1ULL << TRACK_CURVE) | (1ULL << TRACK_HELIX_SMALL) | (1ULL << TRACK_BRAKES)
| (1ULL << TRACK_BLOCK_BRAKES) | (1ULL << TRACK_BOOSTER),
/*.Naming =*/{ STR_CLASSIC_MINI_COASTER_GROUP, STR_CLASSIC_MINI_COASTER_GROUP_DESC },
/*.Flags =*/RIDE_GROUP_FLAG_ALLOW_DOORS_ON_TRACK,
};
static constexpr const RideGroup ride_group_steel_wild_mouse = {
/*.RideType =*/RIDE_TYPE_STEEL_WILD_MOUSE,
/*.MaximumHeight =*/16,
/*.AvailableTrackPieces =*/(1ULL << TRACK_STRAIGHT) | (1ULL << TRACK_STATION_END) | (1ULL << TRACK_LIFT_HILL)
| (1ULL << TRACK_LIFT_HILL_STEEP) | (1ULL << TRACK_SLOPE) | (1ULL << TRACK_SLOPE_STEEP) | (1ULL << TRACK_SLOPE_LONG)
| (1ULL << TRACK_SLOPE_CURVE) | (1ULL << TRACK_CURVE_VERY_SMALL) | (1ULL << TRACK_CURVE_SMALL) | (1ULL << TRACK_BRAKES)
| (1ULL << TRACK_BLOCK_BRAKES),
/*.Naming =*/{ STR_RIDE_NAME_WILD_MOUSE, STR_RIDE_DESCRIPTION_WILD_MOUSE },
/*.Flags =*/RIDE_GROUP_FLAG_ALLOW_DOORS_ON_TRACK,
};
static constexpr const RideGroup ride_group_spinning_wild_mouse = {
/*.RideType =*/RIDE_TYPE_STEEL_WILD_MOUSE,
/*.MaximumHeight =*/16,
/*.AvailableTrackPieces =*/(1ULL << TRACK_STRAIGHT) | (1ULL << TRACK_STATION_END) | (1ULL << TRACK_LIFT_HILL)
| (1ULL << TRACK_SLOPE) | (1ULL << TRACK_SLOPE_LONG) | (1ULL << TRACK_CURVE_VERY_SMALL) | (1ULL << TRACK_CURVE_SMALL)
| (1ULL << TRACK_BRAKES) | (1ULL << TRACK_BLOCK_BRAKES) | (1ULL << TRACK_ROTATION_CONTROL_TOGGLE),
/*.Naming =*/{ STR_SPINNING_WILD_MOUSE_GROUP, STR_SPINNING_WILD_MOUSE_GROUP_DESC },
/*.Flags =*/0,
};
static constexpr const RideGroup corkscrew_rc_groups[MAX_RIDE_GROUPS_PER_RIDE_TYPE] = {
ride_group_corkscrew_rc,
ride_group_hypercoaster,
};
static constexpr const RideGroup junior_rc_groups[MAX_RIDE_GROUPS_PER_RIDE_TYPE] = {
ride_group_junior_rc,
ride_group_classic_mini_coaster,
};
static constexpr const RideGroup car_ride_groups[MAX_RIDE_GROUPS_PER_RIDE_TYPE] = {
ride_group_car_ride,
ride_group_monster_trucks,
};
static constexpr const RideGroup twister_rc_groups[MAX_RIDE_GROUPS_PER_RIDE_TYPE] = {
ride_group_steel_twister_rc,
ride_group_hyper_twister,
};
static constexpr const RideGroup steel_wild_mouse_groups[MAX_RIDE_GROUPS_PER_RIDE_TYPE] = {
ride_group_steel_wild_mouse,
ride_group_spinning_wild_mouse,
};
bool RideGroup::Equals(const RideGroup* otherRideGroup) const
{
return this->Naming.Name == otherRideGroup->Naming.Name && this->Naming.Description == otherRideGroup->Naming.Description;
}
bool RideGroup::IsInvented() const
{
if (!ride_type_is_invented(this->RideType))
return false;
auto& objManager = OpenRCT2::GetContext()->GetObjectManager();
auto& rideEntries = objManager.GetAllRideEntries(this->RideType);
for (auto rideEntryIndex : rideEntries)
{
if (ride_entry_is_invented(rideEntryIndex))
{
auto rideEntry = get_ride_entry(rideEntryIndex);
auto rideEntryRideGroup = RideGroupManager::GetRideGroup(this->RideType, rideEntry);
if (this->Equals(rideEntryRideGroup))
{
// The ride entry is invented and belongs to the same ride group. This means the ride group is invented.
return true;
}
}
}
return false;
}
const RideGroup* RideGroupManager::GetRideGroup(const uint8_t rideType, const rct_ride_entry* rideEntry)
{
switch (rideType)
{
case RIDE_TYPE_CORKSCREW_ROLLER_COASTER:
if (ride_entry_get_supported_track_pieces(rideEntry) & (1ULL << TRACK_VERTICAL_LOOP))
return &ride_group_corkscrew_rc;
else
return &ride_group_hypercoaster;
case RIDE_TYPE_JUNIOR_ROLLER_COASTER:
if (ride_entry_get_supported_track_pieces(rideEntry) & (1ULL << TRACK_SLOPE_STEEP))
return &ride_group_classic_mini_coaster;
else
return &ride_group_junior_rc;
case RIDE_TYPE_CAR_RIDE:
if (ride_entry_get_supported_track_pieces(rideEntry) & (1ULL << TRACK_SLOPE_STEEP))
return &ride_group_monster_trucks;
else
return &ride_group_car_ride;
case RIDE_TYPE_TWISTER_ROLLER_COASTER:
if (!(rideEntry->flags & RIDE_ENTRY_FLAG_NO_INVERSIONS))
return &ride_group_steel_twister_rc;
else
return &ride_group_hyper_twister;
case RIDE_TYPE_STEEL_WILD_MOUSE:
if (ride_entry_get_supported_track_pieces(rideEntry) & (1ULL << TRACK_SLOPE_STEEP))
return &ride_group_steel_wild_mouse;
else
return &ride_group_spinning_wild_mouse;
default:
return nullptr;
}
}
const RideGroup* RideGroupManager::RideGroupFind(const uint8_t rideType, const uint8_t index)
{
if (index >= MAX_RIDE_GROUPS_PER_RIDE_TYPE)
return nullptr;
switch (rideType)
{
case RIDE_TYPE_CORKSCREW_ROLLER_COASTER:
return &corkscrew_rc_groups[index];
case RIDE_TYPE_JUNIOR_ROLLER_COASTER:
return &junior_rc_groups[index];
case RIDE_TYPE_CAR_RIDE:
return &car_ride_groups[index];
case RIDE_TYPE_TWISTER_ROLLER_COASTER:
return &twister_rc_groups[index];
case RIDE_TYPE_STEEL_WILD_MOUSE:
return &steel_wild_mouse_groups[index];
default:
return nullptr;
}
}