Otclient 1.0  14/8/2020
position.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #ifndef POSITION_H
24 #define POSITION_H
25 
26 #include "const.h"
27 #include <framework/stdext/types.h>
28 #include <framework/const.h>
29 #include <framework/util/point.h>
30 
31 #include <vector>
32 
33 class Position
34 {
35 public:
36  Position() : x(65535), y(65535), z(255) {}
37  Position(uint16 x, uint16 y, uint8 z) : x(x), y(y), z(z) {}
38 
39  Position(const Position& position) = default;
40 
42  {
43  Position pos = *this;
44  switch(direction) {
45  case Otc::North:
46  --pos.y;
47  break;
48  case Otc::East:
49  ++pos.x;
50  break;
51  case Otc::South:
52  ++pos.y;
53  break;
54  case Otc::West:
55  --pos.x;
56  break;
57  case Otc::NorthEast:
58  ++pos.x;
59  --pos.y;
60  break;
61  case Otc::SouthEast:
62  ++pos.x;
63  ++pos.y;
64  break;
65  case Otc::SouthWest:
66  --pos.x;
67  ++pos.y;
68  break;
69  case Otc::NorthWest:
70  --pos.x;
71  --pos.y;
72  break;
73  default:
74  break;
75  }
76  return pos;
77  }
78 
80  {
81  Position pos = *this;
82  switch(direction) {
83  case Otc::North:
84  ++pos.y;
85  break;
86  case Otc::East:
87  --pos.x;
88  break;
89  case Otc::South:
90  --pos.y;
91  break;
92  case Otc::West:
93  ++pos.x;
94  break;
95  case Otc::NorthEast:
96  --pos.x;
97  ++pos.y;
98  break;
99  case Otc::SouthEast:
100  --pos.x;
101  --pos.y;
102  break;
103  case Otc::SouthWest:
104  ++pos.x;
105  --pos.y;
106  break;
107  case Otc::NorthWest:
108  ++pos.x;
109  ++pos.y;
110  break;
111  default:
112  break;
113  }
114  return pos;
115  }
116 
117  std::vector<Position> translatedToDirections(const std::vector<Otc::Direction>& dirs) const
118  {
119  Position lastPos = *this;
120  std::vector<Position> positions;
121 
122  if(!lastPos.isValid())
123  return positions;
124 
125  positions.push_back(lastPos);
126 
127  for(auto dir : dirs) {
128  lastPos = lastPos.translatedToDirection(dir);
129  if(!lastPos.isValid())
130  break;
131  positions.push_back(lastPos);
132  }
133 
134  return positions;
135  }
136 
137  static bool isDiagonal(const Otc::Direction dir) { return dir == Otc::NorthWest || dir == Otc::NorthEast || dir == Otc::SouthWest || dir == Otc::SouthEast; };
138 
139  static double getAngleFromPositions(const Position& fromPos, const Position& toPos)
140  {
141  // Returns angle in radians from 0 to 2Pi. -1 means positions are equal.
142  const int dx = toPos.x - fromPos.x;
143  const int dy = toPos.y - fromPos.y;
144  if(dx == 0 && dy == 0)
145  return -1;
146 
147  float angle = std::atan2(dy * -1, dx);
148  if(angle < 0)
149  angle += 2 * Fw::pi;
150 
151  return angle;
152  }
153 
154  double getAngleFromPosition(const Position& position) const
155  {
156  return getAngleFromPositions(*this, position);
157  }
158 
159  static Otc::Direction getDirectionFromPositions(const Position& fromPos, const Position& toPos)
160  {
161  const float angle = getAngleFromPositions(fromPos, toPos) * RAD_TO_DEC;
162 
163  if(angle >= 360 - 22.5 || angle < 0 + 22.5)
164  return Otc::East;
165 
166  if(angle >= 45 - 22.5 && angle < 45 + 22.5)
167  return Otc::NorthEast;
168 
169  if(angle >= 90 - 22.5 && angle < 90 + 22.5)
170  return Otc::North;
171 
172  if(angle >= 135 - 22.5 && angle < 135 + 22.5)
173  return Otc::NorthWest;
174 
175  if(angle >= 180 - 22.5 && angle < 180 + 22.5)
176  return Otc::West;
177 
178  if(angle >= 225 - 22.5 && angle < 225 + 22.5)
179  return Otc::SouthWest;
180 
181  if(angle >= 270 - 22.5 && angle < 270 + 22.5)
182  return Otc::South;
183 
184  if(angle >= 315 - 22.5 && angle < 315 + 22.5)
185  return Otc::SouthEast;
186 
187  return Otc::InvalidDirection;
188  }
189 
191  {
192  return getDirectionFromPositions(*this, position);
193  }
194 
195  bool isMapPosition() const { return x >= 0 && y >= 0 && z >= 0 && x < 65535 && y < 65535 && z <= Otc::MAX_Z; }
196  bool isValid() const { return !(x == 65535 && y == 65535 && z == 255); }
197  float distance(const Position& pos) const { return sqrt(pow(pos.x - x, 2) + pow(pos.y - y, 2)); }
198  int manhattanDistance(const Position& pos) const { return std::abs(pos.x - x) + std::abs(pos.y - y); }
199 
200  void translate(int dx, int dy, short dz = 0) { x += dx; y += dy; z += dz; }
201  Position translated(int dx, int dy, short dz = 0) const { Position pos = *this; pos.x += dx; pos.y += dy; pos.z += dz; return pos; }
202 
203  Position operator+(const Position& other) const { return Position(x + other.x, y + other.y, z + other.z); }
204  Position& operator+=(const Position& other) { x += other.x; y += other.y; z += other.z; return *this; }
205  Position operator-(const Position& other) const { return Position(x - other.x, y - other.y, z - other.z); }
206  Position& operator-=(const Position& other) { x -= other.x; y -= other.y; z -= other.z; return *this; }
207  // Point conversion(s)
208  Position operator+(const Point& other) const { return Position(x + other.x, y + other.y, z); }
209  Position& operator+=(const Point& other) { x += other.x; y += other.y; return *this; }
210 
211  Position& operator=(const Position& other) { x = other.x; y = other.y; z = other.z; return *this; }
212  bool operator==(const Position& other) const { return other.x == x && other.y == y && other.z == z; }
213  bool operator!=(const Position& other) const { return other.x != x || other.y != y || other.z != z; }
214  bool isInRange(const Position& pos, int xRange, int yRange) const { return std::abs(x - pos.x) <= xRange && std::abs(y - pos.y) <= yRange && z == pos.z; }
215  bool isInRange(const Position& pos, int minXRange, int maxXRange, int minYRange, int maxYRange) const
216  {
217  return pos.x >= x - minXRange && pos.x <= x + maxXRange && pos.y >= y - minYRange && pos.y <= y + maxYRange && pos.z == z;
218  }
219  // operator less than for std::map
220  bool operator<(const Position& other) const { return x < other.x || y < other.y || z < other.z; }
221 
222  bool up(int n = 1)
223  {
224  const int nz = z - n;
225  if(nz >= 0 && nz <= Otc::MAX_Z) {
226  z = nz;
227  return true;
228  }
229  return false;
230  }
231 
232  bool down(int n = 1)
233  {
234  const int nz = z + n;
235  if(nz >= 0 && nz <= Otc::MAX_Z) {
236  z = nz;
237  return true;
238  }
239 
240  return false;
241  }
242 
243  bool coveredUp(int n = 1)
244  {
245  const int nx = x + n, ny = y + n, nz = z - n;
246  if(nx >= 0 && nx <= 65535 && ny >= 0 && ny <= 65535 && nz >= 0 && nz <= Otc::MAX_Z) {
247  x = nx; y = ny; z = nz;
248  return true;
249  }
250 
251  return false;
252  }
253 
254  bool coveredDown(int n = 1)
255  {
256  const int nx = x - n, ny = y - n, nz = z + n;
257  if(nx >= 0 && nx <= 65535 && ny >= 0 && ny <= 65535 && nz >= 0 && nz <= Otc::MAX_Z) {
258  x = nx; y = ny; z = nz;
259  return true;
260  }
261 
262  return false;
263  }
264 
265  int x;
266  int y;
267  short z;
268 };
269 
270 struct PositionHasher : std::unary_function<Position, std::size_t> {
271  std::size_t operator()(const Position& pos) const
272  {
273  return (pos.x * 8192 + pos.y) * 16 + pos.z;
274  }
275 };
276 
277 inline std::ostream& operator<<(std::ostream& out, const Position& pos)
278 {
279  out << static_cast<int>(pos.x) << " " << static_cast<int>(pos.y) << " " << static_cast<int>(pos.z);
280  return out;
281 }
282 
283 inline std::istream& operator>>(std::istream& in, Position& pos)
284 {
285  int x, y, z;
286  in >> x >> y >> z;
287  pos.x = x;
288  pos.y = y;
289  pos.z = z;
290  return in;
291 }
292 #endif
Otc::InvalidDirection
@ InvalidDirection
Definition: const.h:192
Position::translatedToDirection
Position translatedToDirection(Otc::Direction direction)
Definition: position.h:41
Position::isInRange
bool isInRange(const Position &pos, int xRange, int yRange) const
Definition: position.h:214
const.h
Position::operator+
Position operator+(const Point &other) const
Definition: position.h:208
RAD_TO_DEC
#define RAD_TO_DEC
Definition: const.h:29
point.h
TPoint::y
T y
Definition: point.h:83
types.h
z
gc sort z
Definition: CMakeLists.txt:176
Otc::North
@ North
Definition: const.h:184
Position::distance
float distance(const Position &pos) const
Definition: position.h:197
Position::x
int x
Definition: position.h:265
Position::isValid
bool isValid() const
Definition: position.h:196
Position::operator-
Position operator-(const Position &other) const
Definition: position.h:205
const.h
Position::translatedToDirections
std::vector< Position > translatedToDirections(const std::vector< Otc::Direction > &dirs) const
Definition: position.h:117
Position::translate
void translate(int dx, int dy, short dz=0)
Definition: position.h:200
operator>>
std::istream & operator>>(std::istream &in, Position &pos)
Definition: position.h:283
Position::y
int y
Definition: position.h:266
Position::translatedToReverseDirection
Position translatedToReverseDirection(Otc::Direction direction)
Definition: position.h:79
PositionHasher
Definition: position.h:270
Otc::NorthEast
@ NorthEast
Definition: const.h:188
Position::z
short z
Definition: position.h:267
uint16
uint16_t uint16
Definition: types.h:36
Position::Position
Position(uint16 x, uint16 y, uint8 z)
Definition: position.h:37
Otc::Direction
Direction
Definition: const.h:183
Position::operator+=
Position & operator+=(const Position &other)
Definition: position.h:204
Position::operator==
bool operator==(const Position &other) const
Definition: position.h:212
Position::translated
Position translated(int dx, int dy, short dz=0) const
Definition: position.h:201
Otc::West
@ West
Definition: const.h:187
Position
Definition: position.h:33
Position::getDirectionFromPositions
static Otc::Direction getDirectionFromPositions(const Position &fromPos, const Position &toPos)
Definition: position.h:159
TPoint::x
T x
Definition: point.h:83
Position::isMapPosition
bool isMapPosition() const
Definition: position.h:195
operator<<
std::ostream & operator<<(std::ostream &out, const Position &pos)
Definition: position.h:277
Position::getAngleFromPositions
static double getAngleFromPositions(const Position &fromPos, const Position &toPos)
Definition: position.h:139
Otc::MAX_Z
@ MAX_Z
Definition: const.h:37
Otc::SouthEast
@ SouthEast
Definition: const.h:189
Position::getDirectionFromPosition
Otc::Direction getDirectionFromPosition(const Position &position) const
Definition: position.h:190
Position::getAngleFromPosition
double getAngleFromPosition(const Position &position) const
Definition: position.h:154
Otc::South
@ South
Definition: const.h:186
PositionHasher::operator()
std::size_t operator()(const Position &pos) const
Definition: position.h:271
Position::coveredDown
bool coveredDown(int n=1)
Definition: position.h:254
Position::down
bool down(int n=1)
Definition: position.h:232
Otc::NorthWest
@ NorthWest
Definition: const.h:191
Position::operator<
bool operator<(const Position &other) const
Definition: position.h:220
Otc::East
@ East
Definition: const.h:185
Position::operator+
Position operator+(const Position &other) const
Definition: position.h:203
Position::operator!=
bool operator!=(const Position &other) const
Definition: position.h:213
Position::isInRange
bool isInRange(const Position &pos, int minXRange, int maxXRange, int minYRange, int maxYRange) const
Definition: position.h:215
Position::isDiagonal
static bool isDiagonal(const Otc::Direction dir)
Definition: position.h:137
Position::operator+=
Position & operator+=(const Point &other)
Definition: position.h:209
TPoint< int >
Position::up
bool up(int n=1)
Definition: position.h:222
Position::manhattanDistance
int manhattanDistance(const Position &pos) const
Definition: position.h:198
Position::operator-=
Position & operator-=(const Position &other)
Definition: position.h:206
Otc::SouthWest
@ SouthWest
Definition: const.h:190
uint8
uint8_t uint8
Definition: types.h:37
Position::operator=
Position & operator=(const Position &other)
Definition: position.h:211
Position::Position
Position()
Definition: position.h:36
Position::coveredUp
bool coveredUp(int n=1)
Definition: position.h:243