1//////////////////////////////////////////////////////////////////////
2// This file is part of Remere's Map Editor
3//////////////////////////////////////////////////////////////////////
4// Remere's Map Editor is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Remere's Map Editor is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16//////////////////////////////////////////////////////////////////////
17
18#ifndef __POSITION_HPP__
19#define __POSITION_HPP__
20
21#include <ostream>
22#include <cstdint>
23#include <vector>
24#include <list>
25
26class SmallPosition;
27
28class Position {
29public:
30 // We use int since it's the native machine type and can be several times faster than
31 // the other integer types in most cases, also, the position may be negative in some
32 // cases
33 int x, y, z;
34
35 Position() :
36 x(0), y(0), z(0) { }
37 Position(int _x, int _y, int _z) :
38 x(_x), y(_y), z(_z) { }
39
40 bool operator<(const Position& p) const {
41 if (z < p.z) {
42 return true;
43 }
44 if (z > p.z) {
45 return false;
46 }
47
48 if (y < p.y) {
49 return true;
50 }
51 if (y > p.y) {
52 return false;
53 }
54
55 if (x < p.x) {
56 return true;
57 }
58 // if(x > p.x)
59 // return false;
60
61 return false;
62 }
63
64 bool operator>(const Position& p) const {
65 return !(*this < p);
66 }
67
68 Position operator-(const Position& p) const {
69 Position newpos;
70 newpos.x = x - p.x;
71 newpos.y = y - p.y;
72 newpos.z = z - p.z;
73 return newpos;
74 }
75
76 Position operator+(const Position& p) const {
77 Position newpos;
78 newpos.x = x + p.x;
79 newpos.y = y + p.y;
80 newpos.z = z + p.z;
81 return newpos;
82 }
83
84 Position& operator+=(const Position& p) {
85 *this = *this + p;
86 return *this;
87 }
88
89 bool operator==(const Position& p) const {
90 return p.x == x && p.y == y && p.z == z;
91 }
92
93 bool operator!=(const Position& p) const {
94 return !(*this == p);
95 }
96
97 bool isValid() const;
98};
99
100inline std::ostream& operator<<(std::ostream& os, const Position& pos) {
101 os << pos.x << ':' << pos.y << ':' << pos.z;
102 return os;
103}
104
105inline std::istream& operator>>(std::istream& is, Position& pos) {
106 char a, b;
107 int x, y, z;
108 is >> x;
109 if (!is) {
110 return is;
111 }
112 is >> a;
113 if (!is || a != ':') {
114 return is;
115 }
116 is >> y;
117 if (!is) {
118 return is;
119 }
120 is >> b;
121 if (!is || b != ':') {
122 return is;
123 }
124 is >> z;
125 if (!is) {
126 return is;
127 }
128
129 pos.x = x;
130 pos.y = y;
131 pos.z = z;
132
133 return is;
134}
135
136inline bool Position::isValid() const {
137 return x >= 0 && x <= MAP_MAX_WIDTH && y >= 0 && y <= MAP_MAX_HEIGHT && z >= 0 && z <= MAP_MAX_LAYER;
138}
139
140inline Position abs(const Position& position) {
141 return Position(
142 std::abs(position.x),
143 std::abs(position.y),
144 std::abs(position.z)
145 );
146}
147
148typedef std::vector<Position> PositionVector;
149typedef std::list<Position> PositionList;
150
151#endif
152