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 "../common.h"
13 #include "../ride/RideTypes.h"
14 #include "../ride/Station.h"
15 #include "Banner.h"
16 #include "Footpath.h"
17 
18 struct Banner;
19 struct CoordsXY;
20 struct LargeSceneryEntry;
21 struct SmallSceneryEntry;
22 struct WallSceneryEntry;
23 struct PathBitEntry;
24 struct BannerSceneryEntry;
25 struct rct_footpath_entry;
26 class LargeSceneryObject;
27 class TerrainSurfaceObject;
28 class TerrainEdgeObject;
29 class FootpathObject;
30 class FootpathSurfaceObject;
31 class FootpathRailingsObject;
32 using track_type_t = uint16_t;
33 
34 constexpr const uint8_t MAX_ELEMENT_HEIGHT = 255;
35 constexpr const uint8_t OWNER_MASK = 0b00001111;
36 
37 #pragma pack(push, 1)
38 
39 enum
40 {
41     TILE_ELEMENT_TYPE_SURFACE = (0 << 2),
42     TILE_ELEMENT_TYPE_PATH = (1 << 2),
43     TILE_ELEMENT_TYPE_TRACK = (2 << 2),
44     TILE_ELEMENT_TYPE_SMALL_SCENERY = (3 << 2),
45     TILE_ELEMENT_TYPE_ENTRANCE = (4 << 2),
46     TILE_ELEMENT_TYPE_WALL = (5 << 2),
47     TILE_ELEMENT_TYPE_LARGE_SCENERY = (6 << 2),
48     TILE_ELEMENT_TYPE_BANNER = (7 << 2),
49     // The corrupt element type is used for skipping drawing other following
50     // elements on a given tile.
51     TILE_ELEMENT_TYPE_CORRUPT = (8 << 2),
52 };
53 
54 enum class TileElementType : uint8_t
55 {
56     Surface = (0 << 2),
57     Path = (1 << 2),
58     Track = (2 << 2),
59     SmallScenery = (3 << 2),
60     Entrance = (4 << 2),
61     Wall = (5 << 2),
62     LargeScenery = (6 << 2),
63     Banner = (7 << 2),
64     Corrupt = (8 << 2),
65 };
66 
67 struct TileElement;
68 struct SurfaceElement;
69 struct PathElement;
70 struct TrackElement;
71 struct SmallSceneryElement;
72 struct LargeSceneryElement;
73 struct WallElement;
74 struct EntranceElement;
75 struct BannerElement;
76 struct CorruptElement;
77 
78 struct TileElementBase
79 {
80     uint8_t type;             // 0
81     uint8_t Flags;            // 1. Upper nibble: flags. Lower nibble: occupied quadrants (one bit per quadrant).
82     uint8_t base_height;      // 2
83     uint8_t clearance_height; // 3
84     uint8_t owner;            // 4
85 
86     void Remove();
87 
88     uint8_t GetType() const;
89     void SetType(uint8_t newType);
90 
91     Direction GetDirection() const;
92     void SetDirection(Direction direction);
93     Direction GetDirectionWithOffset(uint8_t offset) const;
94 
95     bool IsLastForTile() const;
96     void SetLastForTile(bool on);
97     bool IsGhost() const;
98     void SetGhost(bool isGhost);
99 
100     uint8_t GetOccupiedQuadrants() const;
101     void SetOccupiedQuadrants(uint8_t quadrants);
102 
103     int32_t GetBaseZ() const;
104     void SetBaseZ(int32_t newZ);
105 
106     int32_t GetClearanceZ() const;
107     void SetClearanceZ(int32_t newZ);
108 
109     uint8_t GetOwner() const;
110     void SetOwner(uint8_t newOwner);
111 
asTileElementBase112     template<typename TType> const TType* as() const
113     {
114         if constexpr (std::is_same_v<TType, TileElement>)
115             return reinterpret_cast<const TileElement*>(this);
116         else
117             return static_cast<TileElementType>(GetType()) == TType::ElementType ? reinterpret_cast<const TType*>(this)
118                                                                                  : nullptr;
119     }
120 
asTileElementBase121     template<typename TType> TType* as()
122     {
123         if constexpr (std::is_same_v<TType, TileElement>)
124             return reinterpret_cast<TileElement*>(this);
125         else
126             return static_cast<TileElementType>(GetType()) == TType::ElementType ? reinterpret_cast<TType*>(this) : nullptr;
127     }
128 
AsSurfaceTileElementBase129     const SurfaceElement* AsSurface() const
130     {
131         return as<SurfaceElement>();
132     }
AsSurfaceTileElementBase133     SurfaceElement* AsSurface()
134     {
135         return as<SurfaceElement>();
136     }
AsPathTileElementBase137     const PathElement* AsPath() const
138     {
139         return as<PathElement>();
140     }
AsPathTileElementBase141     PathElement* AsPath()
142     {
143         return as<PathElement>();
144     }
AsTrackTileElementBase145     const TrackElement* AsTrack() const
146     {
147         return as<TrackElement>();
148     }
AsTrackTileElementBase149     TrackElement* AsTrack()
150     {
151         return as<TrackElement>();
152     }
AsSmallSceneryTileElementBase153     const SmallSceneryElement* AsSmallScenery() const
154     {
155         return as<SmallSceneryElement>();
156     }
AsSmallSceneryTileElementBase157     SmallSceneryElement* AsSmallScenery()
158     {
159         return as<SmallSceneryElement>();
160     }
AsLargeSceneryTileElementBase161     const LargeSceneryElement* AsLargeScenery() const
162     {
163         return as<LargeSceneryElement>();
164     }
AsLargeSceneryTileElementBase165     LargeSceneryElement* AsLargeScenery()
166     {
167         return as<LargeSceneryElement>();
168     }
AsWallTileElementBase169     const WallElement* AsWall() const
170     {
171         return as<WallElement>();
172     }
AsWallTileElementBase173     WallElement* AsWall()
174     {
175         return as<WallElement>();
176     }
AsEntranceTileElementBase177     const EntranceElement* AsEntrance() const
178     {
179         return as<EntranceElement>();
180     }
AsEntranceTileElementBase181     EntranceElement* AsEntrance()
182     {
183         return as<EntranceElement>();
184     }
AsBannerTileElementBase185     const BannerElement* AsBanner() const
186     {
187         return as<BannerElement>();
188     }
AsBannerTileElementBase189     BannerElement* AsBanner()
190     {
191         return as<BannerElement>();
192     }
193 };
194 
195 /**
196  * Map element structure
197  * size: 0x10
198  */
199 struct TileElement : public TileElementBase
200 {
201     uint8_t pad_05[3];
202     uint8_t pad_08[8];
203 
204     void ClearAs(uint8_t newType);
205 
206     ride_id_t GetRideIndex() const;
207 
208     void SetBannerIndex(BannerIndex newIndex);
209     void RemoveBannerEntry();
210     BannerIndex GetBannerIndex() const;
211 };
212 assert_struct_size(TileElement, 16);
213 
214 struct SurfaceElement : TileElementBase
215 {
216     static constexpr TileElementType ElementType = TileElementType::Surface;
217 
218 private:
219     uint8_t Slope;
220     uint8_t WaterHeight;
221     uint8_t GrassLength;
222     uint8_t Ownership;
223     uint8_t SurfaceStyle;
224     uint8_t EdgeStyle;
225 #pragma clang diagnostic push
226 #pragma clang diagnostic ignored "-Wunused-private-field"
227     uint8_t pad_0B[5];
228 #pragma clang diagnostic pop
229 
230 public:
231     uint8_t GetSlope() const;
232     void SetSlope(uint8_t newSlope);
233 
234     uint32_t GetSurfaceStyle() const;
235     TerrainSurfaceObject* GetSurfaceStyleObject() const;
236     void SetSurfaceStyle(uint32_t newStyle);
237     uint32_t GetEdgeStyle() const;
238     TerrainEdgeObject* GetEdgeStyleObject() const;
239     void SetEdgeStyle(uint32_t newStyle);
240 
241     bool CanGrassGrow() const;
242     uint8_t GetGrassLength() const;
243     void SetGrassLength(uint8_t newLength);
244     void SetGrassLengthAndInvalidate(uint8_t newLength, const CoordsXY& coords);
245     void UpdateGrassLength(const CoordsXY& coords);
246 
247     uint8_t GetOwnership() const;
248     void SetOwnership(uint8_t newOwnership);
249 
250     int32_t GetWaterHeight() const;
251     void SetWaterHeight(int32_t newWaterHeight);
252 
253     uint8_t GetParkFences() const;
254     void SetParkFences(uint8_t newParkFences);
255 
256     bool HasTrackThatNeedsWater() const;
257     void SetHasTrackThatNeedsWater(bool on);
258 };
259 assert_struct_size(SurfaceElement, 16);
260 
261 struct PathElement : TileElementBase
262 {
263     static constexpr TileElementType ElementType = TileElementType::Path;
264 
265 private:
266     ObjectEntryIndex SurfaceIndex;  // 5
267     ObjectEntryIndex RailingsIndex; // 7
268     uint8_t Additions;              // 9 (0 means no addition)
269     uint8_t EdgesAndCorners;        // 10 (edges in lower 4 bits, corners in upper 4)
270     uint8_t Flags2;                 // 11
271     uint8_t SlopeDirection;         // 12
272     union
273     {
274         uint8_t AdditionStatus; // 13, only used for litter bins
275         ride_id_t rideIndex;    // 13
276     };
277     ::StationIndex StationIndex; // 15
278 
279 public:
280     ObjectEntryIndex GetLegacyPathEntryIndex() const;
281     const FootpathObject* GetLegacyPathEntry() const;
282     void SetLegacyPathEntryIndex(ObjectEntryIndex newIndex);
283     bool HasLegacyPathEntry() const;
284 
285     ObjectEntryIndex GetSurfaceEntryIndex() const;
286     const FootpathSurfaceObject* GetSurfaceEntry() const;
287     void SetSurfaceEntryIndex(ObjectEntryIndex newIndex);
288 
289     ObjectEntryIndex GetRailingsEntryIndex() const;
290     const FootpathRailingsObject* GetRailingsEntry() const;
291     void SetRailingsEntryIndex(ObjectEntryIndex newIndex);
292 
293     const PathSurfaceDescriptor* GetSurfaceDescriptor() const;
294     const PathRailingsDescriptor* GetRailingsDescriptor() const;
295 
296     uint8_t GetQueueBannerDirection() const;
297     void SetQueueBannerDirection(uint8_t direction);
298 
299     bool IsSloped() const;
300     void SetSloped(bool isSloped);
301 
302     Direction GetSlopeDirection() const;
303     void SetSlopeDirection(Direction newSlope);
304 
305     ride_id_t GetRideIndex() const;
306     void SetRideIndex(ride_id_t newRideIndex);
307 
308     ::StationIndex GetStationIndex() const;
309     void SetStationIndex(::StationIndex newStationIndex);
310 
311     bool IsWide() const;
312     void SetWide(bool isWide);
313 
314     bool IsQueue() const;
315     void SetIsQueue(bool isQueue);
316     bool HasQueueBanner() const;
317     void SetHasQueueBanner(bool hasQueueBanner);
318 
319     bool IsBroken() const;
320     void SetIsBroken(bool isBroken);
321 
322     bool IsBlockedByVehicle() const;
323     void SetIsBlockedByVehicle(bool isBlocked);
324 
325     uint8_t GetEdges() const;
326     void SetEdges(uint8_t newEdges);
327     uint8_t GetCorners() const;
328     void SetCorners(uint8_t newCorners);
329     uint8_t GetEdgesAndCorners() const;
330     void SetEdgesAndCorners(uint8_t newEdgesAndCorners);
331 
332     bool HasAddition() const;
333     uint8_t GetAddition() const;
334     ObjectEntryIndex GetAdditionEntryIndex() const;
335     PathBitEntry* GetAdditionEntry() const;
336     void SetAddition(uint8_t newAddition);
337 
338     bool AdditionIsGhost() const;
339     void SetAdditionIsGhost(bool isGhost);
340 
341     uint8_t GetAdditionStatus() const;
342     void SetAdditionStatus(uint8_t newStatus);
343 
344     bool ShouldDrawPathOverSupports() const;
345     void SetShouldDrawPathOverSupports(bool on);
346 
347     bool IsLevelCrossing(const CoordsXY& coords) const;
348 };
349 assert_struct_size(PathElement, 16);
350 
351 struct TrackElement : TileElementBase
352 {
353     static constexpr TileElementType ElementType = TileElementType::Track;
354 
355 private:
356     track_type_t TrackType;
357     union
358     {
359         struct
360         {
361             uint8_t Sequence;
362             uint8_t ColourScheme;
363             union
364             {
365                 // - Bits 3 and 4 are never set
366                 // - Bits 1 and 2 are set when a vehicle triggers the on-ride photo and act like a countdown from 3.
367                 // - If any of the bits 1-4 are set, the game counts it as a photo being taken.
368                 uint8_t OnridePhotoBits;
369                 // Contains the brake/booster speed, divided by 2.
370                 uint8_t BrakeBoosterSpeed;
371             };
372             uint8_t StationIndex;
373         };
374         struct
375         {
376             uint16_t MazeEntry; // 6
377         };
378     };
379     uint8_t Flags2;
380     ride_id_t RideIndex;
381     ride_type_t RideType;
382 
383 public:
384     track_type_t GetTrackType() const;
385     void SetTrackType(track_type_t newEntryIndex);
386 
387     ride_type_t GetRideType() const;
388     void SetRideType(const ride_type_t rideType);
389 
390     uint8_t GetSequenceIndex() const;
391     void SetSequenceIndex(uint8_t newSequenceIndex);
392 
393     ride_id_t GetRideIndex() const;
394     void SetRideIndex(ride_id_t newRideIndex);
395 
396     uint8_t GetColourScheme() const;
397     void SetColourScheme(uint8_t newColourScheme);
398 
399     uint8_t GetStationIndex() const;
400     void SetStationIndex(uint8_t newStationIndex);
401 
402     bool HasChain() const;
403     void SetHasChain(bool on);
404 
405     bool HasCableLift() const;
406     void SetHasCableLift(bool on);
407 
408     bool IsInverted() const;
409     void SetInverted(bool inverted);
410 
411     bool BlockBrakeClosed() const;
412     void SetBlockBrakeClosed(bool isClosed);
413 
414     bool IsIndestructible() const;
415     void SetIsIndestructible(bool isIndestructible);
416 
417     uint8_t GetBrakeBoosterSpeed() const;
418     void SetBrakeBoosterSpeed(uint8_t speed);
419 
420     bool HasGreenLight() const;
421     void SetHasGreenLight(bool on);
422 
423     uint8_t GetSeatRotation() const;
424     void SetSeatRotation(uint8_t newSeatRotation);
425 
426     uint16_t GetMazeEntry() const;
427     void SetMazeEntry(uint16_t newMazeEntry);
428     void MazeEntryAdd(uint16_t addVal);
429     void MazeEntrySubtract(uint16_t subVal);
430 
431     bool IsTakingPhoto() const;
432     void SetPhotoTimeout();
433     void SetPhotoTimeout(uint8_t newValue);
434     void DecrementPhotoTimeout();
435     uint8_t GetPhotoTimeout() const;
436 
437     bool IsHighlighted() const;
438     void SetHighlight(bool on);
439 
440     // Used by ghost train, RCT1 feature, will be reintroduced at some point.
441     // (See https://github.com/OpenRCT2/OpenRCT2/issues/7059)
442     uint8_t GetDoorAState() const;
443     uint8_t GetDoorBState() const;
444     void SetDoorAState(uint8_t newState);
445     void SetDoorBState(uint8_t newState);
446 
447     bool IsStation() const;
448     bool IsBlockStart() const;
449 };
450 assert_struct_size(TrackElement, 16);
451 
452 struct SmallSceneryElement : TileElementBase
453 {
454     static constexpr TileElementType ElementType = TileElementType::SmallScenery;
455 
456 private:
457     ObjectEntryIndex entryIndex; // 5
458     uint8_t age;                 // 7
459     uint8_t colour_1;            // 8
460     uint8_t colour_2;            // 9
461 #pragma clang diagnostic push
462 #pragma clang diagnostic ignored "-Wunused-private-field"
463     uint8_t pad_0A[6];
464 #pragma clang diagnostic pop
465 
466 public:
467     ObjectEntryIndex GetEntryIndex() const;
468     void SetEntryIndex(ObjectEntryIndex newIndex);
469     SmallSceneryEntry* GetEntry() const;
470     uint8_t GetAge() const;
471     void SetAge(uint8_t newAge);
472     void IncreaseAge(const CoordsXY& sceneryPos);
473     uint8_t GetSceneryQuadrant() const;
474     void SetSceneryQuadrant(uint8_t newQuadrant);
475     colour_t GetPrimaryColour() const;
476     void SetPrimaryColour(colour_t colour);
477     colour_t GetSecondaryColour() const;
478     void SetSecondaryColour(colour_t colour);
479     bool NeedsSupports() const;
480     void SetNeedsSupports();
481     void UpdateAge(const CoordsXY& sceneryPos);
482 };
483 assert_struct_size(SmallSceneryElement, 16);
484 
485 struct LargeSceneryElement : TileElementBase
486 {
487     static constexpr TileElementType ElementType = TileElementType::LargeScenery;
488 
489 private:
490     ObjectEntryIndex EntryIndex;
491     ::BannerIndex BannerIndex;
492     uint8_t SequenceIndex;
493     uint8_t Colour[3];
494     uint8_t Flags2;
495 #pragma clang diagnostic push
496 #pragma clang diagnostic ignored "-Wunused-private-field"
497     uint8_t pad[2];
498 #pragma clang diagnostic pop
499 
500 public:
501     ObjectEntryIndex GetEntryIndex() const;
502     void SetEntryIndex(ObjectEntryIndex newIndex);
503     LargeSceneryEntry* GetEntry() const;
504     const LargeSceneryObject* GetObject() const;
505 
506     uint8_t GetSequenceIndex() const;
507     void SetSequenceIndex(uint8_t newIndex);
508 
509     colour_t GetPrimaryColour() const;
510     void SetPrimaryColour(colour_t colour);
511     colour_t GetSecondaryColour() const;
512     void SetSecondaryColour(colour_t colour);
513 
514     Banner* GetBanner() const;
515     ::BannerIndex GetBannerIndex() const;
516     void SetBannerIndex(::BannerIndex newIndex);
517 
518     bool IsAccounted() const;
519     void SetIsAccounted(bool isAccounted);
520 };
521 assert_struct_size(LargeSceneryElement, 16);
522 
523 struct WallElement : TileElementBase
524 {
525     static constexpr TileElementType ElementType = TileElementType::Wall;
526 
527 private:
528     ObjectEntryIndex entryIndex; // 05
529     colour_t colour_1;           // 07
530     colour_t colour_2;           // 08
531     colour_t colour_3;           // 09
532     BannerIndex banner_index;    // 0A
533     uint8_t animation;           // 0C 0b_dfff_ft00 d = direction, f = frame num, t = across track flag (not used)
534 #pragma clang diagnostic push
535 #pragma clang diagnostic ignored "-Wunused-private-field"
536     uint8_t pad_0D[3];
537 #pragma clang diagnostic pop
538 
539 public:
540     uint16_t GetEntryIndex() const;
541     void SetEntryIndex(uint16_t newIndex);
542     WallSceneryEntry* GetEntry() const;
543 
544     uint8_t GetSlope() const;
545     void SetSlope(uint8_t newslope);
546 
547     colour_t GetPrimaryColour() const;
548     void SetPrimaryColour(colour_t newColour);
549     colour_t GetSecondaryColour() const;
550     void SetSecondaryColour(colour_t newColour);
551     colour_t GetTertiaryColour() const;
552     void SetTertiaryColour(colour_t newColour);
553 
554     uint8_t GetAnimationFrame() const;
555     void SetAnimationFrame(uint8_t frameNum);
556 
557     Banner* GetBanner() const;
558     BannerIndex GetBannerIndex() const;
559     void SetBannerIndex(BannerIndex newIndex);
560 
561     bool IsAcrossTrack() const;
562     void SetAcrossTrack(bool acrossTrack);
563     bool AnimationIsBackwards() const;
564     void SetAnimationIsBackwards(bool isBackwards);
565 };
566 assert_struct_size(WallElement, 16);
567 
568 struct EntranceElement : TileElementBase
569 {
570     static constexpr TileElementType ElementType = TileElementType::Entrance;
571 
572 private:
573     uint8_t entranceType;      // 5
574     uint8_t SequenceIndex;     // 6. Only uses the lower nibble.
575     uint8_t StationIndex;      // 7
576     ObjectEntryIndex PathType; // 8
577     ride_id_t rideIndex;       // A
578     uint8_t flags2;            // C
579 #pragma clang diagnostic push
580 #pragma clang diagnostic ignored "-Wunused-private-field"
581     uint8_t pad_0D[3];
582 #pragma clang diagnostic pop
583 
584 public:
585     uint8_t GetEntranceType() const;
586     void SetEntranceType(uint8_t newType);
587 
588     ride_id_t GetRideIndex() const;
589     void SetRideIndex(ride_id_t newRideIndex);
590 
591     uint8_t GetStationIndex() const;
592     void SetStationIndex(uint8_t newStationIndex);
593 
594     uint8_t GetSequenceIndex() const;
595     void SetSequenceIndex(uint8_t newSequenceIndex);
596 
597     bool HasLegacyPathEntry() const;
598 
599     ObjectEntryIndex GetLegacyPathEntryIndex() const;
600     const FootpathObject* GetLegacyPathEntry() const;
601     void SetLegacyPathEntryIndex(ObjectEntryIndex newPathType);
602 
603     ObjectEntryIndex GetSurfaceEntryIndex() const;
604     const FootpathSurfaceObject* GetSurfaceEntry() const;
605     void SetSurfaceEntryIndex(ObjectEntryIndex newIndex);
606 
607     const PathSurfaceDescriptor* GetPathSurfaceDescriptor() const;
608 
609     int32_t GetDirections() const;
610 };
611 assert_struct_size(EntranceElement, 16);
612 
613 struct BannerElement : TileElementBase
614 {
615     static constexpr TileElementType ElementType = TileElementType::Banner;
616 
617 private:
618     BannerIndex index;    // 5
619     uint8_t position;     // 7
620     uint8_t AllowedEdges; // 8
621 #pragma clang diagnostic push
622 #pragma clang diagnostic ignored "-Wunused-private-field"
623     uint8_t pad_09[7];
624 #pragma clang diagnostic pop
625 public:
626     Banner* GetBanner() const;
627     BannerSceneryEntry* GetEntry() const;
628 
629     BannerIndex GetIndex() const;
630     void SetIndex(BannerIndex newIndex);
631 
632     uint8_t GetPosition() const;
633     void SetPosition(uint8_t newPosition);
634 
635     uint8_t GetAllowedEdges() const;
636     void SetAllowedEdges(uint8_t newEdges);
637     void ResetAllowedEdges();
638 };
639 assert_struct_size(BannerElement, 16);
640 
641 struct CorruptElement : TileElementBase
642 {
643     static constexpr TileElementType ElementType = TileElementType::Corrupt;
644 
645     uint8_t pad[3];
646     uint8_t pad_08[8];
647 };
648 assert_struct_size(CorruptElement, 16);
649 #pragma pack(pop)
650 
651 class QuarterTile
652 {
653 private:
654     uint8_t _val{ 0 };
655 
656 public:
QuarterTile(uint8_t tileQuarter,uint8_t zQuarter)657     constexpr QuarterTile(uint8_t tileQuarter, uint8_t zQuarter)
658         : _val(tileQuarter | (zQuarter << 4))
659     {
660     }
661 
QuarterTile(uint8_t tileAndZQuarter)662     QuarterTile(uint8_t tileAndZQuarter)
663         : _val(tileAndZQuarter)
664     {
665     }
666 
667     // Rotate both of the values amount. Returns new RValue QuarterTile
668     const QuarterTile Rotate(uint8_t amount) const;
669 
GetBaseQuarterOccupied()670     uint8_t GetBaseQuarterOccupied() const
671     {
672         return _val & 0xF;
673     }
674 
GetZQuarterOccupied()675     uint8_t GetZQuarterOccupied() const
676     {
677         return (_val >> 4) & 0xF;
678     }
679 };
680 
681 enum
682 {
683     TILE_ELEMENT_QUADRANT_SW,
684     TILE_ELEMENT_QUADRANT_NW,
685     TILE_ELEMENT_QUADRANT_NE,
686     TILE_ELEMENT_QUADRANT_SE
687 };
688 
689 enum
690 {
691     SURFACE_ELEMENT_HAS_TRACK_THAT_NEEDS_WATER = (1 << 6),
692 };
693 
694 enum
695 {
696     TILE_ELEMENT_DIRECTION_WEST,
697     TILE_ELEMENT_DIRECTION_NORTH,
698     TILE_ELEMENT_DIRECTION_EAST,
699     TILE_ELEMENT_DIRECTION_SOUTH
700 };
701 
702 enum
703 {
704     TILE_ELEMENT_FLAG_GHOST = (1 << 4),
705     TILE_ELEMENT_FLAG_LAST_TILE = (1 << 7)
706 };
707 
708 enum
709 {
710     ENTRANCE_TYPE_RIDE_ENTRANCE,
711     ENTRANCE_TYPE_RIDE_EXIT,
712     ENTRANCE_TYPE_PARK_ENTRANCE
713 };
714 
715 enum
716 {
717     ELEMENT_IS_ABOVE_GROUND = 1 << 0,
718     ELEMENT_IS_UNDERGROUND = 1 << 1,
719     ELEMENT_IS_UNDERWATER = 1 << 2,
720 };
721 
722 enum
723 {
724     MAP_ELEM_TRACK_SEQUENCE_GREEN_LIGHT = (1 << 7),
725 };
726 
727 #define TILE_ELEMENT_QUADRANT_MASK 0b11000000
728 #define TILE_ELEMENT_TYPE_MASK 0b00111100
729 #define TILE_ELEMENT_DIRECTION_MASK 0b00000011
730 #define TILE_ELEMENT_OCCUPIED_QUADRANTS_MASK 0b00001111
731 
732 #define TILE_ELEMENT_COLOUR_MASK 0b00011111
733 
734 enum
735 {
736     LANDSCAPE_DOOR_CLOSED = 0,
737     LANDSCAPE_DOOR_HALF_OPEN = 2,
738     LANDSCAPE_DOOR_OPEN = 3,
739 };
740 
741 bool tile_element_is_underground(TileElement* tileElement);
742