diff --git a/src/openrct2/rct2/RCT2.h b/src/openrct2/rct2/RCT2.h index c8786193c9..17edab1aac 100644 --- a/src/openrct2/rct2/RCT2.h +++ b/src/openrct2/rct2/RCT2.h @@ -14,7 +14,7 @@ #include "../object/Object.h" #include "../rct12/RCT12.h" #include "../ride/RideRatings.h" -#include "../ride/Vehicle.h" +#include "../ride/VehicleColour.h" #include @@ -90,6 +90,8 @@ constexpr const int32_t rct2_object_entry_group_counts[] = { #pragma pack(push, 1) +struct rct_ride_entry; + /** * Ride structure. * size: 0x0260 diff --git a/src/openrct2/ride/CableLift.h b/src/openrct2/ride/CableLift.h index 6d773d0d9e..2c1ec083bd 100644 --- a/src/openrct2/ride/CableLift.h +++ b/src/openrct2/ride/CableLift.h @@ -11,7 +11,9 @@ #define _CABLE_LIFT_H_ #include "../common.h" -#include "Vehicle.h" +#include "Ride.h" + +struct Vehicle; Vehicle* cable_lift_segment_create( Ride& ride, int32_t x, int32_t y, int32_t z, int32_t direction, uint16_t var_44, int32_t remaining_distance, bool head); diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index a2894272c5..3b7a2640de 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -18,7 +18,7 @@ #include "RideRatings.h" #include "RideTypes.h" #include "ShopItem.h" -#include "Vehicle.h" +#include "VehicleEntry.h" #include #include @@ -30,6 +30,7 @@ struct Peep; struct Ride; struct RideTypeDescriptor; struct Staff; +struct Vehicle; #define MAX_RIDE_TYPES_PER_RIDE_ENTRY 3 // The max number of different types of vehicle. diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index b8d652b98f..c956d1025e 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -57,6 +57,7 @@ #include "Track.h" #include "TrackData.h" #include "TrackDesignRepository.h" +#include "Vehicle.h" #include #include diff --git a/src/openrct2/ride/TrackDesign.h b/src/openrct2/ride/TrackDesign.h index 6c1d08be29..a1161469c0 100644 --- a/src/openrct2/ride/TrackDesign.h +++ b/src/openrct2/ride/TrackDesign.h @@ -15,7 +15,6 @@ #include "../rct12/RCT12.h" #include "../rct2/RCT2.h" #include "../world/Map.h" -#include "Vehicle.h" struct Ride; diff --git a/src/openrct2/ride/Vehicle.h b/src/openrct2/ride/Vehicle.h index db97d5c6ef..25eb39bd3c 100644 --- a/src/openrct2/ride/Vehicle.h +++ b/src/openrct2/ride/Vehicle.h @@ -16,6 +16,9 @@ #include "../world/Location.hpp" #include "../world/SpriteBase.h" #include "Station.h" +#include "VehicleColour.h" +#include "VehicleEntry.h" +#include "VehicleSubpositionData.h" #include #include @@ -23,118 +26,6 @@ using track_type_t = uint16_t; -struct rct_vehicle_colour -{ - uint8_t body_colour; - uint8_t trim_colour; -}; - -struct VehicleColour -{ - uint8_t Body; - uint8_t Trim; - uint8_t Ternary; -}; - -#ifdef __TESTPAINT__ -# pragma pack(push, 1) -#endif // __TESTPAINT__ -/** - * Ride type vehicle structure. - * size: 0x65 - */ -struct rct_ride_entry_vehicle -{ - uint16_t rotation_frame_mask; // 0x00 , 0x1A - uint8_t num_vertical_frames; // 0x02 , 0x1C, Appears to be unused, except as a temporary variable in RCT2 (not needed for - // OpenRCT2) - uint8_t num_horizontal_frames; // 0x03 , 0x1D, Appears to be unused, except as a temporary variable in RCT2 (not needed for - // OpenRCT2) - uint32_t spacing; // 0x04 , 0x1E - uint16_t car_mass; // 0x08 , 0x22 - int8_t tab_height; // 0x0A , 0x24 - uint8_t num_seats; // 0x0B , 0x25 - uint16_t sprite_flags; // 0x0C , 0x26 - uint8_t sprite_width; // 0x0E , 0x28 - uint8_t sprite_height_negative; // 0x0F , 0x29 - uint8_t sprite_height_positive; // 0x10 , 0x2A - uint8_t animation; // 0x11 , 0x2B - uint32_t flags; // 0x12 , 0x2C - uint16_t base_num_frames; // 0x16 , 0x30, The number of sprites for a flat non-banked track piece. - uint32_t base_image_id; // 0x18 , 0x32, Following image_id's populated during loading - uint32_t restraint_image_id; // 0x1C , 0x36 - uint32_t gentle_slope_image_id; // 0x20 , 0x3A - uint32_t steep_slope_image_id; // 0x24 , 0x3E - uint32_t vertical_slope_image_id; // 0x28 , 0x42 - uint32_t diagonal_slope_image_id; // 0x2C , 0x46 - uint32_t banked_image_id; // 0x30 , 0x4A - uint32_t inline_twist_image_id; // 0x34 , 0x4E - uint32_t flat_to_gentle_bank_image_id; // 0x38 , 0x52 - uint32_t diagonal_to_gentle_slope_bank_image_id; // 0x3C , 0x56 - uint32_t gentle_slope_to_bank_image_id; // 0x40 , 0x5A - uint32_t gentle_slope_bank_turn_image_id; // 0x44 , 0x5E - uint32_t flat_bank_to_gentle_slope_image_id; // 0x48 , 0x62 - union - { - uint32_t curved_lift_hill_image_id; // 0x4C , 0x66 - uint32_t corkscrew_image_id; // 0x4C , 0x66 - }; - uint32_t no_vehicle_images; // 0x50 , 0x6A - uint8_t no_seating_rows; // 0x54 , 0x6E - uint8_t spinning_inertia; // 0x55 , 0x6F - uint8_t spinning_friction; // 0x56 , 0x70 - OpenRCT2::Audio::SoundId friction_sound_id; // 0x57 , 0x71 - uint8_t log_flume_reverser_vehicle_type; // 0x58 , 0x72 - uint8_t sound_range; // 0x59 , 0x73 - uint8_t - double_sound_frequency; // 0x5A , 0x74 (Doubles the velocity when working out the sound frequency {used on go karts}) - uint8_t powered_acceleration; // 0x5B , 0x75 - uint8_t powered_max_speed; // 0x5C , 0x76 - uint8_t car_visual; // 0x5D , 0x77 - uint8_t effect_visual; - uint8_t draw_order; - uint8_t num_vertical_frames_override; // 0x60 , 0x7A, A custom number that can be used rather than letting RCT2 determine - // it. Needs the VEHICLE_ENTRY_FLAG_OVERRIDE_NUM_VERTICAL_FRAMES flag to be set. - uint8_t peep_loading_waypoint_segments; // 0x61 new - uint8_t pad_62[6] = {}; // 0x62 , 0x7B - std::vector> peep_loading_waypoints = {}; - std::vector peep_loading_positions = {}; // previously 0x61 , 0x7B -}; -#ifdef __TESTPAINT__ -# pragma pack(pop) -#endif // __TESTPAINT__ -#ifdef PLATFORM_32BIT -static_assert(sizeof(rct_ride_entry_vehicle) % 4 == 0, "Invalid struct size"); -#else -static_assert(sizeof(rct_ride_entry_vehicle) % 8 == 0, "Invalid struct size"); -#endif - -enum class VehicleTrackSubposition : uint8_t -{ - Default, - // Going out means "moving away from the start". Viewed from Station 1, this is the left hand side of the track. - ChairliftGoingOut, - ChairliftGoingBack, - // End and start bullwheel as viewed from Station 1. - ChairliftEndBullwheel, - ChairliftStartBullwheel, - GoKartsLeftLane, - GoKartsRightLane, - GoKartsMovingToRightLane, - GoKartsMovingToLeftLane, - MiniGolfStart9 = 9, - MiniGolfPathA9 = 9, - MiniGolfBallPathA10, - MiniGolfPathB11, - MiniGolfBallPathB12, - MiniGolfPathC13, - MiniGolfBallPathC14, - ReverserRCFrontBogie, - ReverserRCRearBogie, - - Count, -}; - struct Ride; struct rct_ride_entry; diff --git a/src/openrct2/ride/VehicleColour.h b/src/openrct2/ride/VehicleColour.h new file mode 100644 index 0000000000..308c7e2d3d --- /dev/null +++ b/src/openrct2/ride/VehicleColour.h @@ -0,0 +1,28 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 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. + *****************************************************************************/ + +#ifndef VEHICLECOLOUR_H_ +#define VEHICLECOLOUR_H_ + +#include "../common.h" + +struct rct_vehicle_colour +{ + uint8_t body_colour; + uint8_t trim_colour; +}; + +struct VehicleColour +{ + uint8_t Body; + uint8_t Trim; + uint8_t Ternary; +}; + +#endif // VEHICLECOLOUR_H_ diff --git a/src/openrct2/ride/VehicleEntry.h b/src/openrct2/ride/VehicleEntry.h new file mode 100644 index 0000000000..e58657ff4e --- /dev/null +++ b/src/openrct2/ride/VehicleEntry.h @@ -0,0 +1,92 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 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. + *****************************************************************************/ + +#ifndef VEHICLEENTRY_H_ +#define VEHICLEENTRY_H_ + +#include "../audio/AudioMixer.h" +#include "../common.h" + +#include +#include + +#ifdef __TESTPAINT__ +# pragma pack(push, 1) +#endif // __TESTPAINT__ +/** + * Ride type vehicle structure. + * size: 0x65 + */ +struct rct_ride_entry_vehicle +{ + uint16_t rotation_frame_mask; // 0x00 , 0x1A + uint8_t num_vertical_frames; // 0x02 , 0x1C, Appears to be unused, except as a temporary variable in RCT2 (not needed for + // OpenRCT2) + uint8_t num_horizontal_frames; // 0x03 , 0x1D, Appears to be unused, except as a temporary variable in RCT2 (not needed for + // OpenRCT2) + uint32_t spacing; // 0x04 , 0x1E + uint16_t car_mass; // 0x08 , 0x22 + int8_t tab_height; // 0x0A , 0x24 + uint8_t num_seats; // 0x0B , 0x25 + uint16_t sprite_flags; // 0x0C , 0x26 + uint8_t sprite_width; // 0x0E , 0x28 + uint8_t sprite_height_negative; // 0x0F , 0x29 + uint8_t sprite_height_positive; // 0x10 , 0x2A + uint8_t animation; // 0x11 , 0x2B + uint32_t flags; // 0x12 , 0x2C + uint16_t base_num_frames; // 0x16 , 0x30, The number of sprites for a flat non-banked track piece. + uint32_t base_image_id; // 0x18 , 0x32, Following image_id's populated during loading + uint32_t restraint_image_id; // 0x1C , 0x36 + uint32_t gentle_slope_image_id; // 0x20 , 0x3A + uint32_t steep_slope_image_id; // 0x24 , 0x3E + uint32_t vertical_slope_image_id; // 0x28 , 0x42 + uint32_t diagonal_slope_image_id; // 0x2C , 0x46 + uint32_t banked_image_id; // 0x30 , 0x4A + uint32_t inline_twist_image_id; // 0x34 , 0x4E + uint32_t flat_to_gentle_bank_image_id; // 0x38 , 0x52 + uint32_t diagonal_to_gentle_slope_bank_image_id; // 0x3C , 0x56 + uint32_t gentle_slope_to_bank_image_id; // 0x40 , 0x5A + uint32_t gentle_slope_bank_turn_image_id; // 0x44 , 0x5E + uint32_t flat_bank_to_gentle_slope_image_id; // 0x48 , 0x62 + union + { + uint32_t curved_lift_hill_image_id; // 0x4C , 0x66 + uint32_t corkscrew_image_id; // 0x4C , 0x66 + }; + uint32_t no_vehicle_images; // 0x50 , 0x6A + uint8_t no_seating_rows; // 0x54 , 0x6E + uint8_t spinning_inertia; // 0x55 , 0x6F + uint8_t spinning_friction; // 0x56 , 0x70 + OpenRCT2::Audio::SoundId friction_sound_id; // 0x57 , 0x71 + uint8_t log_flume_reverser_vehicle_type; // 0x58 , 0x72 + uint8_t sound_range; // 0x59 , 0x73 + uint8_t + double_sound_frequency; // 0x5A , 0x74 (Doubles the velocity when working out the sound frequency {used on go karts}) + uint8_t powered_acceleration; // 0x5B , 0x75 + uint8_t powered_max_speed; // 0x5C , 0x76 + uint8_t car_visual; // 0x5D , 0x77 + uint8_t effect_visual; + uint8_t draw_order; + uint8_t num_vertical_frames_override; // 0x60 , 0x7A, A custom number that can be used rather than letting RCT2 determine + // it. Needs the VEHICLE_ENTRY_FLAG_OVERRIDE_NUM_VERTICAL_FRAMES flag to be set. + uint8_t peep_loading_waypoint_segments; // 0x61 new + uint8_t pad_62[6] = {}; // 0x62 , 0x7B + std::vector> peep_loading_waypoints = {}; + std::vector peep_loading_positions = {}; // previously 0x61 , 0x7B +}; +#ifdef __TESTPAINT__ +# pragma pack(pop) +#endif // __TESTPAINT__ +#ifdef PLATFORM_32BIT +static_assert(sizeof(rct_ride_entry_vehicle) % 4 == 0, "Invalid struct size"); +#else +static_assert(sizeof(rct_ride_entry_vehicle) % 8 == 0, "Invalid struct size"); +#endif + +#endif // VEHICLEENTRY_H_ diff --git a/src/openrct2/ride/VehicleSubpositionData.cpp b/src/openrct2/ride/VehicleSubpositionData.cpp index 8e93e109d8..66d99434e9 100644 --- a/src/openrct2/ride/VehicleSubpositionData.cpp +++ b/src/openrct2/ride/VehicleSubpositionData.cpp @@ -9,6 +9,8 @@ #include "VehicleSubpositionData.h" +#include "Vehicle.h" + #define CREATE_VEHICLE_INFO(VAR, ...) \ static constexpr const rct_vehicle_info VAR##_data[] = __VA_ARGS__; \ static constexpr const rct_vehicle_info_list VAR = { static_cast(std::size(VAR##_data)), VAR##_data }; diff --git a/src/openrct2/ride/VehicleSubpositionData.h b/src/openrct2/ride/VehicleSubpositionData.h index f32488a0a2..6c647086e7 100644 --- a/src/openrct2/ride/VehicleSubpositionData.h +++ b/src/openrct2/ride/VehicleSubpositionData.h @@ -9,14 +9,40 @@ #pragma once -#include "../world/Location.hpp" #include "Track.h" -#include "Vehicle.h" #include constexpr const size_t VehicleTrackSubpositionSizeDefault = TrackElemType::Count * NumOrthogonalDirections; +struct rct_vehicle_info; + +enum class VehicleTrackSubposition : uint8_t +{ + Default, + // Going out means "moving away from the start". Viewed from Station 1, this is the left hand side of the track. + ChairliftGoingOut, + ChairliftGoingBack, + // End and start bullwheel as viewed from Station 1. + ChairliftEndBullwheel, + ChairliftStartBullwheel, + GoKartsLeftLane, + GoKartsRightLane, + GoKartsMovingToRightLane, + GoKartsMovingToLeftLane, + MiniGolfStart9 = 9, + MiniGolfPathA9 = 9, + MiniGolfBallPathA10, + MiniGolfPathB11, + MiniGolfBallPathB12, + MiniGolfPathC13, + MiniGolfBallPathC14, + ReverserRCFrontBogie, + ReverserRCRearBogie, + + Count, +}; + struct rct_vehicle_info_list { uint16_t size; diff --git a/src/openrct2/ride/coaster/VirginiaReel.cpp b/src/openrct2/ride/coaster/VirginiaReel.cpp index 231c43fa16..e559de03b5 100644 --- a/src/openrct2/ride/coaster/VirginiaReel.cpp +++ b/src/openrct2/ride/coaster/VirginiaReel.cpp @@ -13,6 +13,7 @@ #include "../../paint/Supports.h" #include "../Track.h" #include "../TrackPaint.h" +#include "../Vehicle.h" #include "../VehiclePaint.h" // 0x009927E6: diff --git a/src/openrct2/ride/gentle/ObservationTower.cpp b/src/openrct2/ride/gentle/ObservationTower.cpp index 121916215e..e04c4fc1f7 100644 --- a/src/openrct2/ride/gentle/ObservationTower.cpp +++ b/src/openrct2/ride/gentle/ObservationTower.cpp @@ -14,6 +14,7 @@ #include "../../world/Map.h" #include "../Track.h" #include "../TrackPaint.h" +#include "../Vehicle.h" #include "../VehiclePaint.h" enum diff --git a/src/openrct2/ride/thrill/RotoDrop.cpp b/src/openrct2/ride/thrill/RotoDrop.cpp index de6adf00e5..e2fc9ada3e 100644 --- a/src/openrct2/ride/thrill/RotoDrop.cpp +++ b/src/openrct2/ride/thrill/RotoDrop.cpp @@ -13,6 +13,7 @@ #include "../../paint/Supports.h" #include "../Track.h" #include "../TrackPaint.h" +#include "../Vehicle.h" #include "../VehiclePaint.h" #include diff --git a/src/openrct2/world/EntityList.h b/src/openrct2/world/EntityList.h new file mode 100644 index 0000000000..d7e4de5f1a --- /dev/null +++ b/src/openrct2/world/EntityList.h @@ -0,0 +1,241 @@ +/***************************************************************************** + * Copyright (c) 2014-2021 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. + *****************************************************************************/ + +#ifndef ENTITYLIST_H_ +#define ENTITYLIST_H_ + +#include "../common.h" +#include "../rct12/RCT12.h" +#include "Location.hpp" +#include "SpriteBase.h" + +#include +#include + +enum class EntityListId : uint8_t +{ + Free, + TrainHead, + Peep, + Misc, + Litter, + Vehicle, + Count, +}; + +const std::list& GetEntityList(const EntityListId id); + +uint16_t GetEntityListCount(EntityListId list); +uint16_t GetNumFreeEntities(); +void RebuildEntityLists(); +const std::vector& GetEntityTileList(const CoordsXY& spritePos); +template T* GetEntity(size_t sprite_idx); + +template class EntityIterator +{ +private: + T* Entity = nullptr; + uint16_t NextEntityId = SPRITE_INDEX_NULL; + +public: + EntityIterator(const uint16_t _EntityId) + : NextEntityId(_EntityId) + { + ++(*this); + } + EntityIterator& operator++() + { + Entity = nullptr; + + while (NextEntityId != SPRITE_INDEX_NULL && Entity == nullptr) + { + auto baseEntity = GetEntity(NextEntityId); + if (!baseEntity) + { + NextEntityId = SPRITE_INDEX_NULL; + continue; + } + NextEntityId = baseEntity->*NextList; + Entity = baseEntity->template As(); + } + return *this; + } + + EntityIterator operator++(int) + { + EntityIterator retval = *this; + ++(*this); + return retval; + } + bool operator==(EntityIterator other) const + { + return Entity == other.Entity; + } + bool operator!=(EntityIterator other) const + { + return !(*this == other); + } + T* operator*() + { + return Entity; + } + // iterator traits + using difference_type = std::ptrdiff_t; + using value_type = T; + using pointer = const T*; + using reference = const T&; + using iterator_category = std::forward_iterator_tag; +}; + +template class EntityTileIterator +{ +private: + std::vector::const_iterator iter; + std::vector::const_iterator end; + T* Entity = nullptr; + +public: + EntityTileIterator(std::vector::const_iterator _iter, std::vector::const_iterator _end) + : iter(_iter) + , end(_end) + { + ++(*this); + } + EntityTileIterator& operator++() + { + Entity = nullptr; + + while (iter != end && Entity == nullptr) + { + Entity = GetEntity(*iter++); + } + return *this; + } + + EntityTileIterator operator++(int) + { + EntityTileIterator retval = *this; + ++(*this); + return *iter; + } + bool operator==(EntityTileIterator other) const + { + return Entity == other.Entity; + } + bool operator!=(EntityTileIterator other) const + { + return !(*this == other); + } + T* operator*() + { + return Entity; + } + // iterator traits + using difference_type = std::ptrdiff_t; + using value_type = T; + using pointer = const T*; + using reference = const T&; + using iterator_category = std::forward_iterator_tag; +}; + +template class EntityTileList +{ +private: + const std::vector& vec; + +public: + EntityTileList(const CoordsXY& loc) + : vec(GetEntityTileList(loc)) + { + } + + EntityTileIterator begin() + { + return EntityTileIterator(std::begin(vec), std::end(vec)); + } + EntityTileIterator end() + { + return EntityTileIterator(std::end(vec), std::end(vec)); + } +}; + +template class EntityListIterator +{ +private: + std::list::const_iterator iter; + std::list::const_iterator end; + T* Entity = nullptr; + +public: + EntityListIterator(std::list::const_iterator _iter, std::list::const_iterator _end) + : iter(_iter) + , end(_end) + { + ++(*this); + } + EntityListIterator& operator++() + { + Entity = nullptr; + + while (iter != end && Entity == nullptr) + { + Entity = GetEntity(*iter++); + } + return *this; + } + + EntityListIterator operator++(int) + { + EntityListIterator retval = *this; + ++(*this); + return *iter; + } + bool operator==(EntityListIterator other) const + { + return Entity == other.Entity; + } + bool operator!=(EntityListIterator other) const + { + return !(*this == other); + } + T* operator*() + { + return Entity; + } + // iterator traits + using difference_type = std::ptrdiff_t; + using value_type = T; + using pointer = const T*; + using reference = const T&; + using iterator_category = std::forward_iterator_tag; +}; + +template class EntityList +{ +private: + using EntityListIterator_t = EntityListIterator; + const std::list& vec; + +public: + EntityList(EntityListId type) + : vec(GetEntityList(type)) + { + } + + EntityListIterator_t begin() + { + return EntityListIterator_t(std::cbegin(vec), std::cend(vec)); + } + EntityListIterator_t end() + { + return EntityListIterator_t(std::cend(vec), std::cend(vec)); + } +}; + +#endif // ENTITYLIST_H_