Otclient  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  Position pos = *this;
43  switch(direction) {
44  case Otc::North:
45  pos.y--;
46  break;
47  case Otc::East:
48  pos.x++;
49  break;
50  case Otc::South:
51  pos.y++;
52  break;
53  case Otc::West:
54  pos.x--;
55  break;
56  case Otc::NorthEast:
57  pos.x++;
58  pos.y--;
59  break;
60  case Otc::SouthEast:
61  pos.x++;
62  pos.y++;
63  break;
64  case Otc::SouthWest:
65  pos.x--;
66  pos.y++;
67  break;
68  case Otc::NorthWest:
69  pos.x--;
70  pos.y--;
71  break;
72  default:
73  break;
74  }
75  return pos;
76  }
77 
79  Position pos = *this;
80  switch(direction) {
81  case Otc::North:
82  pos.y++;
83  break;
84  case Otc::East:
85  pos.x--;
86  break;
87  case Otc::South:
88  pos.y--;
89  break;
90  case Otc::West:
91  pos.x++;
92  break;
93  case Otc::NorthEast:
94  pos.x--;
95  pos.y++;
96  break;
97  case Otc::SouthEast:
98  pos.x--;
99  pos.y--;
100  break;
101  case Otc::SouthWest:
102  pos.x++;
103  pos.y--;
104  break;
105  case Otc::NorthWest:
106  pos.x++;
107  pos.y++;
108  break;
109  default:
110  break;
111  }
112  return pos;
113  }
114 
115  std::vector<Position> translatedToDirections(const std::vector<Otc::Direction>& dirs) const {
116  Position lastPos = *this;
117  std::vector<Position> positions;
118 
119  if(!lastPos.isValid())
120  return positions;
121 
122  positions.push_back(lastPos);
123 
124  for(auto dir : dirs) {
125  lastPos = lastPos.translatedToDirection(dir);
126  if(!lastPos.isValid())
127  break;
128  positions.push_back(lastPos);
129  }
130 
131  return positions;
132  }
133 
134  static double getAngleFromPositions(const Position& fromPos, const Position& toPos) {
135  // Returns angle in radians from 0 to 2Pi. -1 means positions are equal.
136  int dx = toPos.x - fromPos.x;
137  int dy = toPos.y - fromPos.y;
138  if(dx == 0 && dy == 0)
139  return -1;
140 
141  float angle = std::atan2(dy * -1, dx);
142  if(angle < 0)
143  angle += 2 * Fw::pi;
144 
145  return angle;
146  }
147 
148  double getAngleFromPosition(const Position& position) const {
149  return getAngleFromPositions(*this, position);
150  }
151 
153  const Position& toPos)
154  {
155  float angle = getAngleFromPositions(fromPos, toPos) * RAD_TO_DEC;
156 
157  if(angle >= 360 - 22.5 || angle < 0 + 22.5)
158  return Otc::East;
159  else if(angle >= 45 - 22.5 && angle < 45 + 22.5)
160  return Otc::NorthEast;
161  else if(angle >= 90 - 22.5 && angle < 90 + 22.5)
162  return Otc::North;
163  else if(angle >= 135 - 22.5 && angle < 135 + 22.5)
164  return Otc::NorthWest;
165  else if(angle >= 180 - 22.5 && angle < 180 + 22.5)
166  return Otc::West;
167  else if(angle >= 225 - 22.5 && angle < 225 + 22.5)
168  return Otc::SouthWest;
169  else if(angle >= 270 - 22.5 && angle < 270 + 22.5)
170  return Otc::South;
171  else if(angle >= 315 - 22.5 && angle < 315 + 22.5)
172  return Otc::SouthEast;
173  else
174  return Otc::InvalidDirection;
175  }
176 
178  return getDirectionFromPositions(*this, position);
179  }
180 
181  bool isMapPosition() const { return (x >=0 && y >= 0 && z >= 0 && x < 65535 && y < 65535 && z <= Otc::MAX_Z); }
182  bool isValid() const { return !(x == 65535 && y == 65535 && z == 255); }
183  float distance(const Position& pos) const { return sqrt(pow((pos.x - x), 2) + pow((pos.y - y), 2)); }
184  int manhattanDistance(const Position& pos) const { return std::abs(pos.x - x) + std::abs(pos.y - y); }
185 
186  void translate(int dx, int dy, short dz = 0) { x += dx; y += dy; z += dz; }
187  Position translated(int dx, int dy, short dz = 0) const { Position pos = *this; pos.x += dx; pos.y += dy; pos.z += dz; return pos; }
188 
189  Position operator+(const Position& other) const { return Position(x + other.x, y + other.y, z + other.z); }
190  Position& operator+=(const Position& other) { x+=other.x; y+=other.y; z +=other.z; return *this; }
191  Position operator-(const Position& other) const { return Position(x - other.x, y - other.y, z - other.z); }
192  Position& operator-=(const Position& other) { x-=other.x; y-=other.y; z-=other.z; return *this; }
193  // Point conversion(s)
194  Position operator+(const Point& other) const { return Position(x + other.x, y + other.y, z); }
195  Position& operator+=(const Point& other) { x += other.x; y += other.y; return *this; }
196 
197  Position& operator=(const Position& other) { x = other.x; y = other.y; z = other.z; return *this; }
198  bool operator==(const Position& other) const { return other.x == x && other.y == y && other.z == z; }
199  bool operator!=(const Position& other) const { return other.x!=x || other.y!=y || other.z!=z; }
200  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; }
201  bool isInRange(const Position& pos, int minXRange, int maxXRange, int minYRange, int maxYRange) const {
202  return (pos.x >= x-minXRange && pos.x <= x+maxXRange && pos.y >= y-minYRange && pos.y <= y+maxYRange && pos.z == z);
203  }
204  // operator less than for std::map
205  bool operator<(const Position& other) const { return x < other.x || y < other.y || z < other.z; }
206 
207  bool up(int n = 1) {
208  int nz = z-n;
209  if(nz >= 0 && nz <= Otc::MAX_Z) {
210  z = nz;
211  return true;
212  }
213  return false;
214  }
215 
216  bool down(int n = 1) {
217  int nz = z+n;
218  if(nz >= 0 && nz <= Otc::MAX_Z) {
219  z = nz;
220  return true;
221  }
222  return false;
223  }
224 
225  bool coveredUp(int n = 1) {
226  int nx = x+n, ny = y+n, nz = z-n;
227  if(nx >= 0 && nx <= 65535 && ny >= 0 && ny <= 65535 && nz >= 0 && nz <= Otc::MAX_Z) {
228  x = nx; y = ny; z = nz;
229  return true;
230  }
231  return false;
232  }
233 
234  bool coveredDown(int n = 1) {
235  int nx = x-n, ny = y-n, nz = z+n;
236  if(nx >= 0 && nx <= 65535 && ny >= 0 && ny <= 65535 && nz >= 0 && nz <= Otc::MAX_Z) {
237  x = nx; y = ny; z = nz;
238  return true;
239  }
240  return false;
241  }
242 
243  int x;
244  int y;
245  short z;
246 };
247 
248 struct PositionHasher : std::unary_function<Position, std::size_t> {
249  std::size_t operator()(const Position& pos) const {
250  return (((pos.x * 8192) + pos.y) * 16) + pos.z;
251  }
252 };
253 
254 inline std::ostream& operator<<(std::ostream& out, const Position& pos)
255 {
256  out << (int)pos.x << " " << (int)pos.y << " " << (int)pos.z;
257  return out;
258 }
259 
260 inline std::istream& operator>>(std::istream& in, Position& pos)
261 {
262  int x, y, z;
263  in >> x >> y >> z;
264  pos.x = x;
265  pos.y = y;
266  pos.z = z;
267  return in;
268 }
269 
270 #endif
Otc::InvalidDirection
@ InvalidDirection
Definition: const.h:170
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:200
const.h
Position::operator+
Position operator+(const Point &other) const
Definition: position.h:194
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:162
Position::distance
float distance(const Position &pos) const
Definition: position.h:183
Position::x
int x
Definition: position.h:243
Position::isValid
bool isValid() const
Definition: position.h:182
Position::operator-
Position operator-(const Position &other) const
Definition: position.h:191
const.h
Position::translatedToDirections
std::vector< Position > translatedToDirections(const std::vector< Otc::Direction > &dirs) const
Definition: position.h:115
Position::translate
void translate(int dx, int dy, short dz=0)
Definition: position.h:186
operator>>
std::istream & operator>>(std::istream &in, Position &pos)
Definition: position.h:260
Position::y
int y
Definition: position.h:244
Position::translatedToReverseDirection
Position translatedToReverseDirection(Otc::Direction direction)
Definition: position.h:78
PositionHasher
Definition: position.h:248
Otc::NorthEast
@ NorthEast
Definition: const.h:166
Position::z
short z
Definition: position.h:245
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:161
Position::operator+=
Position & operator+=(const Position &other)
Definition: position.h:190
Position::operator==
bool operator==(const Position &other) const
Definition: position.h:198
Position::translated
Position translated(int dx, int dy, short dz=0) const
Definition: position.h:187
Otc::West
@ West
Definition: const.h:165
Position
Definition: position.h:33
Position::getDirectionFromPositions
static Otc::Direction getDirectionFromPositions(const Position &fromPos, const Position &toPos)
Definition: position.h:152
TPoint::x
T x
Definition: point.h:83
Position::isMapPosition
bool isMapPosition() const
Definition: position.h:181
operator<<
std::ostream & operator<<(std::ostream &out, const Position &pos)
Definition: position.h:254
Position::getAngleFromPositions
static double getAngleFromPositions(const Position &fromPos, const Position &toPos)
Definition: position.h:134
Otc::MAX_Z
@ MAX_Z
Definition: const.h:33
Otc::SouthEast
@ SouthEast
Definition: const.h:167
Position::getDirectionFromPosition
Otc::Direction getDirectionFromPosition(const Position &position) const
Definition: position.h:177
Position::getAngleFromPosition
double getAngleFromPosition(const Position &position) const
Definition: position.h:148
Otc::South
@ South
Definition: const.h:164
PositionHasher::operator()
std::size_t operator()(const Position &pos) const
Definition: position.h:249
Position::coveredDown
bool coveredDown(int n=1)
Definition: position.h:234
Position::down
bool down(int n=1)
Definition: position.h:216
Otc::NorthWest
@ NorthWest
Definition: const.h:169
Position::operator<
bool operator<(const Position &other) const
Definition: position.h:205
Otc::East
@ East
Definition: const.h:163
Position::operator+
Position operator+(const Position &other) const
Definition: position.h:189
Position::operator!=
bool operator!=(const Position &other) const
Definition: position.h:199
Position::isInRange
bool isInRange(const Position &pos, int minXRange, int maxXRange, int minYRange, int maxYRange) const
Definition: position.h:201
Position::operator+=
Position & operator+=(const Point &other)
Definition: position.h:195
TPoint< int >
Position::up
bool up(int n=1)
Definition: position.h:207
Position::manhattanDistance
int manhattanDistance(const Position &pos) const
Definition: position.h:184
Position::operator-=
Position & operator-=(const Position &other)
Definition: position.h:192
Otc::SouthWest
@ SouthWest
Definition: const.h:168
uint8
uint8_t uint8
Definition: types.h:37
Position::operator=
Position & operator=(const Position &other)
Definition: position.h:197
Position::Position
Position()
Definition: position.h:36
Position::coveredUp
bool coveredUp(int n=1)
Definition: position.h:225