SabrehavenServer/src/position.h
2019-09-16 20:38:16 +03:00

135 lines
3.8 KiB
C++

/**
* Tibia GIMUD Server - a free and open-source MMORPG server emulator
* Copyright (C) 2019 Sabrehaven and Mark Samman <mark.samman@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef FS_POSITION_H_5B684192F7034FB8857C8280D2CC6C75
#define FS_POSITION_H_5B684192F7034FB8857C8280D2CC6C75
enum Direction : uint8_t {
DIRECTION_NORTH = 0,
DIRECTION_EAST = 1,
DIRECTION_SOUTH = 2,
DIRECTION_WEST = 3,
DIRECTION_DIAGONAL_MASK = 4,
DIRECTION_SOUTHWEST = DIRECTION_DIAGONAL_MASK | 0,
DIRECTION_SOUTHEAST = DIRECTION_DIAGONAL_MASK | 1,
DIRECTION_NORTHWEST = DIRECTION_DIAGONAL_MASK | 2,
DIRECTION_NORTHEAST = DIRECTION_DIAGONAL_MASK | 3,
DIRECTION_LAST = DIRECTION_NORTHEAST,
DIRECTION_NONE = 8,
};
struct Position
{
constexpr Position() = default;
constexpr Position(uint16_t x, uint16_t y, uint8_t z) : x(x), y(y), z(z) {}
template<int_fast32_t deltax, int_fast32_t deltay>
inline static bool areInRange(const Position& p1, const Position& p2) {
return Position::getDistanceX(p1, p2) <= deltax && Position::getDistanceY(p1, p2) <= deltay;
}
template<int_fast32_t deltax, int_fast32_t deltay, int_fast16_t deltaz>
inline static bool areInRange(const Position& p1, const Position& p2) {
return Position::getDistanceX(p1, p2) <= deltax && Position::getDistanceY(p1, p2) <= deltay && Position::getDistanceZ(p1, p2) <= deltaz;
}
inline static int_fast32_t getOffsetX(const Position& p1, const Position& p2) {
return p1.getX() - p2.getX();
}
inline static int_fast32_t getOffsetY(const Position& p1, const Position& p2) {
return p1.getY() - p2.getY();
}
inline static int_fast16_t getOffsetZ(const Position& p1, const Position& p2) {
return p1.getZ() - p2.getZ();
}
inline static int32_t getDistanceX(const Position& p1, const Position& p2) {
return std::abs(Position::getOffsetX(p1, p2));
}
inline static int32_t getDistanceY(const Position& p1, const Position& p2) {
return std::abs(Position::getOffsetY(p1, p2));
}
inline static int16_t getDistanceZ(const Position& p1, const Position& p2) {
return std::abs(Position::getOffsetZ(p1, p2));
}
uint16_t x = 0;
uint16_t y = 0;
uint8_t z = 0;
bool operator<(const Position& p) const {
if (z < p.z) {
return true;
}
if (z > p.z) {
return false;
}
if (y < p.y) {
return true;
}
if (y > p.y) {
return false;
}
if (x < p.x) {
return true;
}
if (x > p.x) {
return false;
}
return false;
}
bool operator>(const Position& p) const {
return ! (*this < p);
}
bool operator==(const Position& p) const {
return p.x == x && p.y == y && p.z == z;
}
bool operator!=(const Position& p) const {
return p.x != x || p.y != y || p.z != z;
}
Position operator+(const Position& p1) const {
return Position(x + p1.x, y + p1.y, z + p1.z);
}
Position operator-(const Position& p1) const {
return Position(x - p1.x, y - p1.y, z - p1.z);
}
inline int_fast32_t getX() const { return x; }
inline int_fast32_t getY() const { return y; }
inline int_fast16_t getZ() const { return z; }
};
std::ostream& operator<<(std::ostream&, const Position&);
std::ostream& operator<<(std::ostream&, const Direction&);
#endif