1 /***************************************************************************** 2 * Copyright (c) 2014-2020 OpenRCT2 developers 3 * 4 * For a complete list of all authors, please refer to contributors.md 5 * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 6 * 7 * OpenRCT2 is licensed under the GNU General Public License version 3. 8 *****************************************************************************/ 9 10 #pragma once 11 12 #include "../actions/GameActionResult.h" 13 #include "../common.h" 14 #include "../object/Object.h" 15 #include "../rct12/RCT12.h" 16 #include "../rct2/RCT2.h" 17 #include "../world/Map.h" 18 19 struct Ride; 20 21 #define TRACK_PREVIEW_IMAGE_SIZE (370 * 217) 22 23 struct TrackDesignState 24 { 25 CoordsXYZ PreviewMin; 26 CoordsXYZ PreviewMax; 27 CoordsXYZ Origin; 28 uint8_t PlaceOperation{}; 29 int16_t PlaceZ{}; 30 int16_t PlaceSceneryZ{}; 31 bool EntranceExitPlaced{}; 32 bool HasScenery{}; 33 bool PlaceScenery{}; 34 bool IsReplay{}; 35 }; 36 37 /* Track Entrance entry */ 38 struct TrackDesignEntranceElement 39 { 40 int8_t z; 41 uint8_t direction; 42 int16_t x; 43 int16_t y; 44 bool isExit; 45 }; 46 47 /* Track Scenery entry size: 0x16 */ 48 struct TrackDesignSceneryElement 49 { 50 ObjectEntryDescriptor scenery_object; 51 int8_t x; 52 int8_t y; 53 int8_t z; 54 uint8_t flags; 55 uint8_t primary_colour; 56 uint8_t secondary_colour; 57 IsQueueTrackDesignSceneryElement58 bool IsQueue() const 59 { 60 return (flags & (1 << 7)) != 0; 61 } 62 }; 63 64 /** 65 * Track design structure. 66 */ 67 68 /* Track Element entry size: 0x03 */ 69 struct TrackDesignTrackElement 70 { 71 track_type_t type; // 0x00 72 uint8_t flags; // 0x02 73 }; 74 75 /* Maze Element entry size: 0x04 */ 76 struct TrackDesignMazeElement 77 { 78 union 79 { 80 uint32_t all; 81 struct 82 { 83 int8_t x; 84 int8_t y; 85 union 86 { 87 uint16_t maze_entry; 88 struct 89 { 90 uint8_t direction; 91 uint8_t type; 92 }; 93 }; 94 }; 95 }; 96 }; 97 98 class DataSerialiser; 99 enum class RideMode : uint8_t; 100 101 struct TrackDesign 102 { 103 uint8_t type; 104 uint8_t vehicle_type; 105 money32 cost; 106 uint32_t flags; 107 RideMode ride_mode; 108 uint8_t track_flags; 109 uint8_t colour_scheme; 110 std::array<rct_vehicle_colour, RCT2_MAX_CARS_PER_TRAIN> vehicle_colours; 111 uint8_t entrance_style; 112 uint8_t total_air_time; 113 uint8_t depart_flags; 114 uint8_t number_of_trains; 115 uint8_t number_of_cars_per_train; 116 uint8_t min_waiting_time; 117 uint8_t max_waiting_time; 118 uint8_t operation_setting; 119 int8_t max_speed; 120 int8_t average_speed; 121 uint16_t ride_length; 122 uint8_t max_positive_vertical_g; 123 int8_t max_negative_vertical_g; 124 uint8_t max_lateral_g; 125 uint8_t inversions; 126 uint8_t holes; 127 uint8_t drops; 128 uint8_t highest_drop_height; 129 uint8_t excitement; 130 uint8_t intensity; 131 uint8_t nausea; 132 money16 upkeep_cost; 133 uint8_t track_spine_colour[RCT12_NUM_COLOUR_SCHEMES]; 134 uint8_t track_rail_colour[RCT12_NUM_COLOUR_SCHEMES]; 135 uint8_t track_support_colour[RCT12_NUM_COLOUR_SCHEMES]; 136 uint32_t flags2; 137 ObjectEntryDescriptor vehicle_object; 138 uint8_t space_required_x; 139 uint8_t space_required_y; 140 uint8_t vehicle_additional_colour[RCT2_MAX_CARS_PER_TRAIN]; 141 uint8_t lift_hill_speed; 142 uint8_t num_circuits; 143 144 std::vector<TrackDesignMazeElement> maze_elements; 145 std::vector<TrackDesignTrackElement> track_elements; 146 std::vector<TrackDesignEntranceElement> entrance_elements; 147 std::vector<TrackDesignSceneryElement> scenery_elements; 148 149 std::string name; 150 151 public: 152 rct_string_id CreateTrackDesign(TrackDesignState& tds, const Ride& ride); 153 rct_string_id CreateTrackDesignScenery(TrackDesignState& tds); 154 void Serialise(DataSerialiser& stream); 155 156 private: 157 uint8_t _saveDirection; 158 rct_string_id CreateTrackDesignTrack(TrackDesignState& tds, const Ride& ride); 159 rct_string_id CreateTrackDesignMaze(TrackDesignState& tds, const Ride& ride); 160 CoordsXYE MazeGetFirstElement(const Ride& ride); 161 }; 162 163 // Only written to in RCT2, not used in OpenRCT2. All of these are elements that had to be invented in RCT1. 164 enum : uint32_t 165 { 166 TRACK_FLAGS_CONTAINS_VERTICAL_LOOP = (1 << 7), 167 TRACK_FLAGS_CONTAINS_INLINE_TWIST = (1 << 17), 168 TRACK_FLAGS_CONTAINS_HALF_LOOP = (1 << 18), 169 TRACK_FLAGS_CONTAINS_CORKSCREW = (1 << 19), 170 TRACK_FLAGS_CONTAINS_WATER_SPLASH = (1 << 27), 171 TRACK_FLAGS_CONTAINS_BARREL_ROLL = (1 << 29), 172 TRACK_FLAGS_CONTAINS_POWERED_LIFT = (1 << 30), 173 TRACK_FLAGS_CONTAINS_LARGE_HALF_LOOP = (1u << 31), 174 }; 175 176 enum : uint32_t 177 { 178 TRACK_FLAGS2_CONTAINS_LOG_FLUME_REVERSER = (1 << 1), 179 TRACK_FLAGS2_SIX_FLAGS_RIDE_DEPRECATED = (1u << 31) // Not used anymore. 180 }; 181 182 enum 183 { 184 TDPF_PLACE_SCENERY = 1 << 0, 185 }; 186 187 enum 188 { 189 TRACK_DESIGN_FLAG_SCENERY_UNAVAILABLE = (1 << 0), 190 TRACK_DESIGN_FLAG_HAS_SCENERY = (1 << 1), 191 TRACK_DESIGN_FLAG_VEHICLE_UNAVAILABLE = (1 << 2), 192 }; 193 194 enum 195 { 196 PTD_OPERATION_DRAW_OUTLINES, 197 PTD_OPERATION_PLACE_QUERY, 198 PTD_OPERATION_PLACE, 199 PTD_OPERATION_GET_PLACE_Z, 200 PTD_OPERATION_PLACE_GHOST, 201 PTD_OPERATION_PLACE_TRACK_PREVIEW, 202 PTD_OPERATION_REMOVE_GHOST, 203 }; 204 205 static constexpr uint8_t PTD_OPERATION_FLAG_IS_REPLAY = (1 << 7); 206 207 enum 208 { 209 MAZE_ELEMENT_TYPE_MAZE_TRACK = 0, 210 MAZE_ELEMENT_TYPE_ENTRANCE = (1 << 3), 211 MAZE_ELEMENT_TYPE_EXIT = (1 << 7) 212 }; 213 214 static constexpr ride_id_t PreviewRideId = static_cast<ride_id_t>(0); 215 216 extern bool gTrackDesignSceneryToggle; 217 218 extern bool _trackDesignDrawingPreview; 219 220 extern bool _trackDesignPlaceStateSceneryUnavailable; 221 extern bool gTrackDesignSaveMode; 222 extern ride_id_t gTrackDesignSaveRideIndex; 223 224 [[nodiscard]] std::unique_ptr<TrackDesign> TrackDesignImport(const utf8* path); 225 226 void TrackDesignMirror(TrackDesign* td6); 227 228 GameActions::Result::Ptr TrackDesignPlace( 229 TrackDesign* td6, uint32_t flags, bool placeScenery, Ride* ride, const CoordsXYZ& coords); 230 void TrackDesignPreviewRemoveGhosts(TrackDesign* td6, Ride* ride, const CoordsXYZ& coords); 231 void TrackDesignPreviewDrawOutlines(TrackDesign* td6, Ride* ride, const CoordsXYZ& coords); 232 int32_t TrackDesignGetZPlacement(TrackDesign* td6, Ride* ride, const CoordsXYZ& coords); 233 234 /////////////////////////////////////////////////////////////////////////////// 235 // Track design preview 236 /////////////////////////////////////////////////////////////////////////////// 237 void TrackDesignDrawPreview(TrackDesign* td6, uint8_t* pixels); 238 239 /////////////////////////////////////////////////////////////////////////////// 240 // Track design saving 241 /////////////////////////////////////////////////////////////////////////////// 242 void track_design_save_init(); 243 void track_design_save_reset_scenery(); 244 bool track_design_save_contains_tile_element(const TileElement* tileElement); 245 void track_design_save_select_nearby_scenery(ride_id_t rideIndex); 246 void track_design_save_select_tile_element( 247 ViewportInteractionItem interactionType, const CoordsXY& loc, TileElement* tileElement, bool collect); 248 249 bool track_design_are_entrance_and_exit_placed(); 250 251 extern std::vector<TrackDesignSceneryElement> _trackSavedTileElementsDesc; 252 extern std::vector<const TileElement*> _trackSavedTileElements; 253