1 /*****************************************************************************
2  * Copyright (c) 2014-2021 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 "../rct12/RCT12.h"
14 #include "Entity.h"
15 #include "EntityBase.h"
16 #include "Location.hpp"
17 
18 #include <list>
19 #include <vector>
20 
21 enum class EntityListId : uint8_t
22 {
23     Count = 6,
24 };
25 
26 const std::list<uint16_t>& GetEntityList(const EntityType id);
27 
28 uint16_t GetEntityListCount(EntityType list);
29 uint16_t GetMiscEntityCount();
30 uint16_t GetNumFreeEntities();
31 const std::vector<uint16_t>& GetEntityTileList(const CoordsXY& spritePos);
32 
33 template<typename T> class EntityTileIterator
34 {
35 private:
36     std::vector<uint16_t>::const_iterator iter;
37     std::vector<uint16_t>::const_iterator end;
38     T* Entity = nullptr;
39 
40 public:
EntityTileIterator(std::vector<uint16_t>::const_iterator _iter,std::vector<uint16_t>::const_iterator _end)41     EntityTileIterator(std::vector<uint16_t>::const_iterator _iter, std::vector<uint16_t>::const_iterator _end)
42         : iter(_iter)
43         , end(_end)
44     {
45         ++(*this);
46     }
47     EntityTileIterator& operator++()
48     {
49         Entity = nullptr;
50 
51         while (iter != end && Entity == nullptr)
52         {
53             Entity = GetEntity<T>(*iter++);
54         }
55         return *this;
56     }
57 
58     EntityTileIterator operator++(int)
59     {
60         EntityTileIterator retval = *this;
61         ++(*this);
62         return *iter;
63     }
64     bool operator==(EntityTileIterator other) const
65     {
66         return Entity == other.Entity;
67     }
68     bool operator!=(EntityTileIterator other) const
69     {
70         return !(*this == other);
71     }
72     T* operator*()
73     {
74         return Entity;
75     }
76     // iterator traits
77     using difference_type = std::ptrdiff_t;
78     using value_type = T;
79     using pointer = const T*;
80     using reference = const T&;
81     using iterator_category = std::forward_iterator_tag;
82 };
83 
84 template<typename T = EntityBase> class EntityTileList
85 {
86 private:
87     const std::vector<uint16_t>& vec;
88 
89 public:
EntityTileList(const CoordsXY & loc)90     EntityTileList(const CoordsXY& loc)
91         : vec(GetEntityTileList(loc))
92     {
93     }
94 
begin()95     EntityTileIterator<T> begin()
96     {
97         return EntityTileIterator<T>(std::begin(vec), std::end(vec));
98     }
end()99     EntityTileIterator<T> end()
100     {
101         return EntityTileIterator<T>(std::end(vec), std::end(vec));
102     }
103 };
104 
105 template<typename T> class EntityListIterator
106 {
107 private:
108     std::list<uint16_t>::const_iterator iter;
109     std::list<uint16_t>::const_iterator end;
110     T* Entity = nullptr;
111 
112 public:
EntityListIterator(std::list<uint16_t>::const_iterator _iter,std::list<uint16_t>::const_iterator _end)113     EntityListIterator(std::list<uint16_t>::const_iterator _iter, std::list<uint16_t>::const_iterator _end)
114         : iter(_iter)
115         , end(_end)
116     {
117         ++(*this);
118     }
119     EntityListIterator& operator++()
120     {
121         Entity = nullptr;
122 
123         while (iter != end && Entity == nullptr)
124         {
125             Entity = GetEntity<T>(*iter++);
126         }
127         return *this;
128     }
129 
130     EntityListIterator operator++(int)
131     {
132         EntityListIterator retval = *this;
133         ++(*this);
134         return *iter;
135     }
136     bool operator==(EntityListIterator other) const
137     {
138         return Entity == other.Entity;
139     }
140     bool operator!=(EntityListIterator other) const
141     {
142         return !(*this == other);
143     }
144     T* operator*()
145     {
146         return Entity;
147     }
148     // iterator traits
149     using difference_type = std::ptrdiff_t;
150     using value_type = T;
151     using pointer = const T*;
152     using reference = const T&;
153     using iterator_category = std::forward_iterator_tag;
154 };
155 
156 template<typename T = EntityBase> class EntityList
157 {
158 private:
159     using EntityListIterator_t = EntityListIterator<T>;
160     const std::list<uint16_t>& vec;
161 
162 public:
EntityList()163     EntityList()
164         : vec(GetEntityList(T::cEntityType))
165     {
166     }
167 
begin()168     EntityListIterator_t begin() const
169     {
170         return EntityListIterator_t(std::cbegin(vec), std::cend(vec));
171     }
end()172     EntityListIterator_t end() const
173     {
174         return EntityListIterator_t(std::cend(vec), std::cend(vec));
175     }
176 };
177