mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-22 05:06:24 +00:00
feat(Core/Position): own file (#10505)
This commit is contained in:
committed by
GitHub
parent
b0b9fece99
commit
93520f6466
@@ -1009,71 +1009,6 @@ bool Object::PrintIndexError(uint32 index, bool set) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Position::operator==(Position const& a) const
|
||||
{
|
||||
return (G3D::fuzzyEq(a.m_positionX, m_positionX) &&
|
||||
G3D::fuzzyEq(a.m_positionY, m_positionY) &&
|
||||
G3D::fuzzyEq(a.m_positionZ, m_positionZ) &&
|
||||
G3D::fuzzyEq(a.m_orientation, m_orientation));
|
||||
}
|
||||
|
||||
void Position::RelocatePolarOffset(float angle, float dist, float z /*= 0.0f*/)
|
||||
{
|
||||
SetOrientation(GetOrientation() + angle);
|
||||
|
||||
m_positionX = GetPositionX() + dist * std::cos(GetOrientation());
|
||||
m_positionY = GetPositionY() + dist * std::sin(GetOrientation());
|
||||
m_positionZ = GetPositionZ() + z;
|
||||
}
|
||||
|
||||
bool Position::HasInLine(WorldObject const* target, float width) const
|
||||
{
|
||||
if (!HasInArc(M_PI, target))
|
||||
return false;
|
||||
width += target->GetObjectSize();
|
||||
float angle = GetRelativeAngle(target);
|
||||
|
||||
return std::fabs(std::sin(angle)) * GetExactDist2d(target->GetPositionX(), target->GetPositionY()) < width;
|
||||
}
|
||||
|
||||
std::string Position::ToString() const
|
||||
{
|
||||
std::stringstream sstr;
|
||||
sstr << "X: " << m_positionX << " Y: " << m_positionY << " Z: " << m_positionZ << " O: " << m_orientation;
|
||||
return sstr.str();
|
||||
}
|
||||
|
||||
ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer)
|
||||
{
|
||||
float x, y, z, o;
|
||||
buf >> x >> y >> z >> o;
|
||||
streamer.m_pos->Relocate(x, y, z, o);
|
||||
return buf;
|
||||
}
|
||||
ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZStreamer const& streamer)
|
||||
{
|
||||
float x, y, z;
|
||||
streamer.m_pos->GetPosition(x, y, z);
|
||||
buf << x << y << z;
|
||||
return buf;
|
||||
}
|
||||
|
||||
ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZStreamer const& streamer)
|
||||
{
|
||||
float x, y, z;
|
||||
buf >> x >> y >> z;
|
||||
streamer.m_pos->Relocate(x, y, z);
|
||||
return buf;
|
||||
}
|
||||
|
||||
ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer)
|
||||
{
|
||||
float x, y, z, o;
|
||||
streamer.m_pos->GetPosition(x, y, z, o);
|
||||
buf << x << y << z << o;
|
||||
return buf;
|
||||
}
|
||||
|
||||
void MovementInfo::OutDebug()
|
||||
{
|
||||
LOG_INFO("movement", "MOVEMENT INFO");
|
||||
@@ -1528,122 +1463,6 @@ bool WorldObject::IsInRange3d(float x, float y, float z, float minRange, float m
|
||||
return distsq < maxdist * maxdist;
|
||||
}
|
||||
|
||||
void Position::RelocateOffset(const Position& offset)
|
||||
{
|
||||
m_positionX = GetPositionX() + (offset.GetPositionX() * cos(GetOrientation()) + offset.GetPositionY() * std::sin(GetOrientation() + M_PI));
|
||||
m_positionY = GetPositionY() + (offset.GetPositionY() * cos(GetOrientation()) + offset.GetPositionX() * std::sin(GetOrientation()));
|
||||
m_positionZ = GetPositionZ() + offset.GetPositionZ();
|
||||
m_orientation = GetOrientation() + offset.GetOrientation();
|
||||
}
|
||||
|
||||
void Position::GetPositionOffsetTo(const Position& endPos, Position& retOffset) const
|
||||
{
|
||||
float dx = endPos.GetPositionX() - GetPositionX();
|
||||
float dy = endPos.GetPositionY() - GetPositionY();
|
||||
|
||||
retOffset.m_positionX = dx * cos(GetOrientation()) + dy * std::sin(GetOrientation());
|
||||
retOffset.m_positionY = dy * cos(GetOrientation()) - dx * std::sin(GetOrientation());
|
||||
retOffset.m_positionZ = endPos.GetPositionZ() - GetPositionZ();
|
||||
retOffset.m_orientation = endPos.GetOrientation() - GetOrientation();
|
||||
}
|
||||
|
||||
float Position::GetAngle(const Position* obj) const
|
||||
{
|
||||
if (!obj)
|
||||
return 0;
|
||||
|
||||
return GetAngle(obj->GetPositionX(), obj->GetPositionY());
|
||||
}
|
||||
|
||||
// Return angle in range 0..2*pi
|
||||
float Position::GetAngle(const float x, const float y) const
|
||||
{
|
||||
return getAngle(GetPositionX(), GetPositionY(), x, y);
|
||||
}
|
||||
|
||||
void Position::GetSinCos(const float x, const float y, float& vsin, float& vcos) const
|
||||
{
|
||||
float dx = GetPositionX() - x;
|
||||
float dy = GetPositionY() - y;
|
||||
|
||||
if (std::fabs(dx) < 0.001f && std::fabs(dy) < 0.001f)
|
||||
{
|
||||
float angle = (float)rand_norm() * static_cast<float>(2 * M_PI);
|
||||
vcos = cos(angle);
|
||||
vsin = std::sin(angle);
|
||||
}
|
||||
else
|
||||
{
|
||||
float dist = sqrt((dx * dx) + (dy * dy));
|
||||
vcos = dx / dist;
|
||||
vsin = dy / dist;
|
||||
}
|
||||
}
|
||||
|
||||
bool Position::IsWithinBox(const Position& center, float xradius, float yradius, float zradius) const
|
||||
{
|
||||
// rotate the WorldObject position instead of rotating the whole cube, that way we can make a simplified
|
||||
// is-in-cube check and we have to calculate only one point instead of 4
|
||||
|
||||
// 2PI = 360*, keep in mind that ingame orientation is counter-clockwise
|
||||
double rotation = 2 * M_PI - center.GetOrientation();
|
||||
double sinVal = std::sin(rotation);
|
||||
double cosVal = std::cos(rotation);
|
||||
|
||||
float BoxDistX = GetPositionX() - center.GetPositionX();
|
||||
float BoxDistY = GetPositionY() - center.GetPositionY();
|
||||
|
||||
float rotX = float(center.GetPositionX() + BoxDistX * cosVal - BoxDistY * sinVal);
|
||||
float rotY = float(center.GetPositionY() + BoxDistY * cosVal + BoxDistX * sinVal);
|
||||
|
||||
// box edges are parallel to coordiante axis, so we can treat every dimension independently :D
|
||||
float dz = GetPositionZ() - center.GetPositionZ();
|
||||
float dx = rotX - center.GetPositionX();
|
||||
float dy = rotY - center.GetPositionY();
|
||||
if ((std::fabs(dx) > xradius) ||
|
||||
(std::fabs(dy) > yradius) ||
|
||||
(std::fabs(dz) > zradius))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Position::HasInArc(float arc, const Position* obj, float targetRadius) const
|
||||
{
|
||||
// always have self in arc
|
||||
if (obj == this)
|
||||
return true;
|
||||
|
||||
// move arc to range 0.. 2*pi
|
||||
arc = Position::NormalizeOrientation(arc);
|
||||
|
||||
float angle = GetAngle(obj);
|
||||
angle -= m_orientation;
|
||||
|
||||
// move angle to range -pi ... +pi
|
||||
angle = Position::NormalizeOrientation(angle);
|
||||
if (angle > M_PI)
|
||||
angle -= 2.0f * M_PI;
|
||||
|
||||
float lborder = -1 * (arc / 2.0f); // in range -pi..0
|
||||
float rborder = (arc / 2.0f); // in range 0..pi
|
||||
|
||||
// pussywizard: take into consideration target size
|
||||
if (targetRadius > 0.0f)
|
||||
{
|
||||
float distSq = GetExactDist2dSq(obj);
|
||||
// pussywizard: at least a part of target's model is in every direction
|
||||
if (distSq < targetRadius * targetRadius)
|
||||
return true;
|
||||
float angularRadius = 2.0f * atan(targetRadius / (2.0f * sqrt(distSq)));
|
||||
lborder -= angularRadius;
|
||||
rborder += angularRadius;
|
||||
}
|
||||
|
||||
return ((angle >= lborder) && (angle <= rborder));
|
||||
}
|
||||
|
||||
bool WorldObject::IsInBetween(const WorldObject* obj1, const WorldObject* obj2, float size) const
|
||||
{
|
||||
if (!obj1 || !obj2)
|
||||
@@ -1797,11 +1616,6 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float& z, float* grou
|
||||
}
|
||||
}
|
||||
|
||||
bool Position::IsPositionValid() const
|
||||
{
|
||||
return Acore::IsValidMapCoord(m_positionX, m_positionY, m_positionZ, m_orientation);
|
||||
}
|
||||
|
||||
float WorldObject::GetGridActivationRange() const
|
||||
{
|
||||
if (ToPlayer())
|
||||
@@ -2884,7 +2698,7 @@ void WorldObject::GetChargeContactPoint(const WorldObject* obj, float& x, float&
|
||||
|
||||
void WorldObject::MovePosition(Position& pos, float dist, float angle)
|
||||
{
|
||||
angle += m_orientation;
|
||||
angle += GetOrientation();
|
||||
float destx, desty, destz, ground, floor;
|
||||
destx = pos.m_positionX + dist * cos(angle);
|
||||
desty = pos.m_positionY + dist * std::sin(angle);
|
||||
@@ -2924,7 +2738,7 @@ void WorldObject::MovePosition(Position& pos, float dist, float angle)
|
||||
Acore::NormalizeMapCoord(pos.m_positionX);
|
||||
Acore::NormalizeMapCoord(pos.m_positionY);
|
||||
UpdateGroundPositionZ(pos.m_positionX, pos.m_positionY, pos.m_positionZ);
|
||||
pos.m_orientation = m_orientation;
|
||||
pos.SetOrientation(GetOrientation());
|
||||
}
|
||||
|
||||
Position WorldObject::GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY)
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "ObjectDefines.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "Optional.h"
|
||||
#include "Position.h"
|
||||
#include "UpdateData.h"
|
||||
#include "UpdateMask.h"
|
||||
#include <set>
|
||||
@@ -244,295 +245,6 @@ private:
|
||||
Object& operator=(Object const&); // prevent generation assigment operator
|
||||
};
|
||||
|
||||
struct Position
|
||||
{
|
||||
Position(float x = 0, float y = 0, float z = 0, float o = 0)
|
||||
: m_positionX(x), m_positionY(y), m_positionZ(z), m_orientation(NormalizeOrientation(o)) { }
|
||||
|
||||
Position(Position const& loc) { Relocate(loc); }
|
||||
Position(Position&&) = default;
|
||||
Position& operator=(const Position&) = default;
|
||||
Position& operator=(Position&&) = default;
|
||||
|
||||
struct PositionXYStreamer
|
||||
{
|
||||
explicit PositionXYStreamer(Position& pos) : Pos(&pos) { }
|
||||
Position* Pos;
|
||||
};
|
||||
|
||||
struct PositionXYZStreamer
|
||||
{
|
||||
explicit PositionXYZStreamer(Position& pos) : m_pos(&pos) {}
|
||||
Position* m_pos;
|
||||
};
|
||||
|
||||
struct PositionXYZOStreamer
|
||||
{
|
||||
explicit PositionXYZOStreamer(Position& pos) : m_pos(&pos) {}
|
||||
Position* m_pos;
|
||||
};
|
||||
|
||||
float m_positionX = 0;
|
||||
float m_positionY = 0;
|
||||
float m_positionZ = 0;
|
||||
float m_orientation = 0;
|
||||
|
||||
bool operator==(Position const& a) const;
|
||||
|
||||
inline bool operator!=(Position const& a)
|
||||
{
|
||||
return !(operator==(a));
|
||||
}
|
||||
|
||||
operator G3D::Vector3() const
|
||||
{
|
||||
return { m_positionX, m_positionY, m_positionZ };
|
||||
}
|
||||
|
||||
void Relocate(float x, float y)
|
||||
{
|
||||
m_positionX = x;
|
||||
m_positionY = y;
|
||||
}
|
||||
void Relocate(float x, float y, float z)
|
||||
{
|
||||
m_positionX = x;
|
||||
m_positionY = y;
|
||||
m_positionZ = z;
|
||||
}
|
||||
void Relocate(float x, float y, float z, float orientation)
|
||||
{
|
||||
m_positionX = x;
|
||||
m_positionY = y;
|
||||
m_positionZ = z;
|
||||
m_orientation = orientation;
|
||||
}
|
||||
void Relocate(const Position& pos)
|
||||
{
|
||||
m_positionX = pos.m_positionX;
|
||||
m_positionY = pos.m_positionY;
|
||||
m_positionZ = pos.m_positionZ;
|
||||
m_orientation = pos.m_orientation;
|
||||
}
|
||||
void Relocate(const Position* pos)
|
||||
{
|
||||
m_positionX = pos->m_positionX;
|
||||
m_positionY = pos->m_positionY;
|
||||
m_positionZ = pos->m_positionZ;
|
||||
m_orientation = pos->m_orientation;
|
||||
}
|
||||
void RelocatePolarOffset(float angle, float dist, float z = 0.0f);
|
||||
void RelocateOffset(const Position& offset);
|
||||
void SetOrientation(float orientation)
|
||||
{
|
||||
m_orientation = orientation;
|
||||
}
|
||||
|
||||
[[nodiscard]] float GetPositionX() const { return m_positionX; }
|
||||
[[nodiscard]] float GetPositionY() const { return m_positionY; }
|
||||
[[nodiscard]] float GetPositionZ() const { return m_positionZ; }
|
||||
[[nodiscard]] float GetOrientation() const { return m_orientation; }
|
||||
|
||||
void GetPosition(float& x, float& y) const
|
||||
{
|
||||
x = m_positionX;
|
||||
y = m_positionY;
|
||||
}
|
||||
void GetPosition(float& x, float& y, float& z) const
|
||||
{
|
||||
x = m_positionX;
|
||||
y = m_positionY;
|
||||
z = m_positionZ;
|
||||
}
|
||||
void GetPosition(float& x, float& y, float& z, float& o) const
|
||||
{
|
||||
x = m_positionX;
|
||||
y = m_positionY;
|
||||
z = m_positionZ;
|
||||
o = m_orientation;
|
||||
}
|
||||
|
||||
[[nodiscard]] Position GetPosition() const { return *this; }
|
||||
|
||||
Position::PositionXYZStreamer PositionXYZStream()
|
||||
{
|
||||
return PositionXYZStreamer(*this);
|
||||
}
|
||||
Position::PositionXYZOStreamer PositionXYZOStream()
|
||||
{
|
||||
return PositionXYZOStreamer(*this);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsPositionValid() const;
|
||||
|
||||
[[nodiscard]] float GetExactDist2dSq(const float x, const float y) const
|
||||
{
|
||||
float dx = x - m_positionX;
|
||||
float dy = y - m_positionY;
|
||||
return dx*dx + dy*dy;
|
||||
}
|
||||
|
||||
[[nodiscard]] float GetExactDist2dSq(Position const& pos) const { return GetExactDist2dSq(pos.m_positionX, pos.m_positionY); }
|
||||
float GetExactDist2dSq(Position const* pos) const { return GetExactDist2dSq(*pos); }
|
||||
[[nodiscard]] float GetExactDist2d(const float x, const float y) const { return std::sqrt(GetExactDist2dSq(x, y)); }
|
||||
[[nodiscard]] float GetExactDist2d(Position const& pos) const { return GetExactDist2d(pos.m_positionX, pos.m_positionY); }
|
||||
float GetExactDist2d(Position const* pos) const { return GetExactDist2d(*pos); }
|
||||
|
||||
[[nodiscard]] float GetExactDistSq(float x, float y, float z) const
|
||||
{
|
||||
float dz = z - m_positionZ;
|
||||
return GetExactDist2dSq(x, y) + dz*dz;
|
||||
}
|
||||
|
||||
[[nodiscard]] float GetExactDistSq(Position const& pos) const { return GetExactDistSq(pos.m_positionX, pos.m_positionY, pos.m_positionZ); }
|
||||
float GetExactDistSq(Position const* pos) const { return GetExactDistSq(*pos); }
|
||||
[[nodiscard]] float GetExactDist(float x, float y, float z) const { return std::sqrt(GetExactDistSq(x, y, z)); }
|
||||
[[nodiscard]] float GetExactDist(Position const& pos) const { return GetExactDist(pos.m_positionX, pos.m_positionY, pos.m_positionZ); }
|
||||
float GetExactDist(Position const* pos) const { return GetExactDist(*pos); }
|
||||
|
||||
void GetPositionOffsetTo(const Position& endPos, Position& retOffset) const;
|
||||
[[nodiscard]] Position GetPositionWithOffset(Position const& offset) const;
|
||||
|
||||
float GetAngle(const Position* pos) const;
|
||||
[[nodiscard]] float GetAngle(float x, float y) const;
|
||||
[[nodiscard]] float GetAbsoluteAngle(float x, float y) const
|
||||
{
|
||||
return NormalizeOrientation(std::atan2(
|
||||
static_cast<float>(y - m_positionY),
|
||||
static_cast<float>(x - m_positionX))
|
||||
);
|
||||
}
|
||||
[[nodiscard]] float GetAbsoluteAngle(Position const& pos) const { return GetAbsoluteAngle(pos.m_positionX, pos.m_positionY); }
|
||||
[[nodiscard]] float GetAbsoluteAngle(Position const* pos) const { return GetAbsoluteAngle(*pos); }
|
||||
|
||||
float GetRelativeAngle(const Position* pos) const
|
||||
{
|
||||
return GetAngle(pos) - m_orientation;
|
||||
}
|
||||
[[nodiscard]] float GetRelativeAngle(float x, float y) const { return GetAngle(x, y) - m_orientation; }
|
||||
[[nodiscard]] float ToAbsoluteAngle(float relAngle) const { return NormalizeOrientation(relAngle + m_orientation); }
|
||||
|
||||
void GetSinCos(float x, float y, float& vsin, float& vcos) const;
|
||||
|
||||
[[nodiscard]] bool IsInDist2d(float x, float y, float dist) const
|
||||
{
|
||||
return GetExactDist2dSq(x, y) < dist * dist;
|
||||
}
|
||||
bool IsInDist2d(const Position* pos, float dist) const
|
||||
{
|
||||
return GetExactDist2dSq(pos) < dist * dist;
|
||||
}
|
||||
[[nodiscard]] bool IsInDist(float x, float y, float z, float dist) const
|
||||
{
|
||||
return GetExactDistSq(x, y, z) < dist * dist;
|
||||
}
|
||||
bool IsInDist(const Position* pos, float dist) const
|
||||
{
|
||||
return GetExactDistSq(pos) < dist * dist;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsWithinBox(const Position& center, float xradius, float yradius, float zradius) const;
|
||||
bool HasInArc(float arcangle, const Position* pos, float targetRadius = 0.0f) const;
|
||||
bool HasInLine(WorldObject const* target, float width) const;
|
||||
[[nodiscard]] std::string ToString() const;
|
||||
|
||||
// modulos a radian orientation to the range of 0..2PI
|
||||
static float NormalizeOrientation(float o)
|
||||
{
|
||||
// fmod only supports positive numbers. Thus we have
|
||||
// to emulate negative numbers
|
||||
if (o < 0)
|
||||
{
|
||||
float mod = o * -1;
|
||||
mod = std::fmod(mod, 2.0f * static_cast<float>(M_PI));
|
||||
mod = -mod + 2.0f * static_cast<float>(M_PI);
|
||||
return mod;
|
||||
}
|
||||
return std::fmod(o, 2.0f * static_cast<float>(M_PI));
|
||||
}
|
||||
};
|
||||
|
||||
#define MAPID_INVALID 0xFFFFFFFF
|
||||
|
||||
class WorldLocation : public Position
|
||||
{
|
||||
public:
|
||||
explicit WorldLocation(uint32 _mapId = MAPID_INVALID, float x = 0.f, float y = 0.f, float z = 0.f, float o = 0.f)
|
||||
: Position(x, y, z, o), m_mapId(_mapId) { }
|
||||
|
||||
WorldLocation(uint32 mapId, Position const& position)
|
||||
: Position(position), m_mapId(mapId) { }
|
||||
|
||||
void WorldRelocate(const WorldLocation& loc)
|
||||
{
|
||||
m_mapId = loc.GetMapId();
|
||||
Relocate(loc);
|
||||
}
|
||||
|
||||
void WorldRelocate(uint32 mapId = MAPID_INVALID, float x = 0.f, float y = 0.f, float z = 0.f, float o = 0.f)
|
||||
{
|
||||
m_mapId = mapId;
|
||||
Relocate(x, y, z, o);
|
||||
}
|
||||
|
||||
void SetMapId(uint32 mapId)
|
||||
{
|
||||
m_mapId = mapId;
|
||||
}
|
||||
|
||||
[[nodiscard]] uint32 GetMapId() const
|
||||
{
|
||||
return m_mapId;
|
||||
}
|
||||
|
||||
void GetWorldLocation(uint32& mapId, float& x, float& y) const
|
||||
{
|
||||
mapId = m_mapId;
|
||||
x = m_positionX;
|
||||
y = m_positionY;
|
||||
}
|
||||
|
||||
void GetWorldLocation(uint32& mapId, float& x, float& y, float& z) const
|
||||
{
|
||||
mapId = m_mapId;
|
||||
x = m_positionX;
|
||||
y = m_positionY;
|
||||
z = m_positionZ;
|
||||
}
|
||||
|
||||
void GetWorldLocation(uint32& mapId, float& x, float& y, float& z, float& o) const
|
||||
{
|
||||
mapId = m_mapId;
|
||||
x = m_positionX;
|
||||
y = m_positionY;
|
||||
z = m_positionZ;
|
||||
o = m_orientation;
|
||||
}
|
||||
|
||||
void GetWorldLocation(WorldLocation* location) const
|
||||
{
|
||||
if (location)
|
||||
{
|
||||
location->Relocate(m_positionX, m_positionY, m_positionZ, m_orientation);
|
||||
location->SetMapId(m_mapId);
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] WorldLocation GetWorldLocation() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint32 m_mapId;
|
||||
};
|
||||
|
||||
ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYStreamer const& streamer);
|
||||
ByteBuffer& operator >> (ByteBuffer& buf, Position::PositionXYStreamer const& streamer);
|
||||
ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZStreamer const& streamer);
|
||||
ByteBuffer& operator >> (ByteBuffer& buf, Position::PositionXYZStreamer const& streamer);
|
||||
ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer);
|
||||
ByteBuffer& operator >> (ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer);
|
||||
|
||||
struct MovementInfo
|
||||
{
|
||||
// common
|
||||
|
||||
210
src/server/game/Entities/Object/Position.cpp
Normal file
210
src/server/game/Entities/Object/Position.cpp
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 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 Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Position.h"
|
||||
#include "ByteBuffer.h"
|
||||
#include "GridDefines.h"
|
||||
#include "Geometry.h"
|
||||
#include <G3D/g3dmath.h>
|
||||
#include <sstream>
|
||||
|
||||
bool Position::operator==(Position const& a) const
|
||||
{
|
||||
return (G3D::fuzzyEq(a.m_positionX, m_positionX) &&
|
||||
G3D::fuzzyEq(a.m_positionY, m_positionY) &&
|
||||
G3D::fuzzyEq(a.m_positionZ, m_positionZ) &&
|
||||
G3D::fuzzyEq(a.m_orientation, m_orientation));
|
||||
}
|
||||
|
||||
void Position::RelocatePolarOffset(float angle, float dist, float z /*= 0.0f*/)
|
||||
{
|
||||
SetOrientation(GetOrientation() + angle);
|
||||
|
||||
m_positionX = GetPositionX() + dist * std::cos(GetOrientation());
|
||||
m_positionY = GetPositionY() + dist * std::sin(GetOrientation());
|
||||
m_positionZ = GetPositionZ() + z;
|
||||
}
|
||||
|
||||
bool Position::HasInLine(Position const* pos, float width) const
|
||||
{
|
||||
if (!HasInArc(float(M_PI), pos))
|
||||
return false;
|
||||
|
||||
float angle = GetRelativeAngle(pos);
|
||||
return std::fabs(std::sin(angle)) * GetExactDist2d(pos->GetPositionX(), pos->GetPositionY()) < width;
|
||||
}
|
||||
|
||||
std::string Position::ToString() const
|
||||
{
|
||||
std::stringstream sstr;
|
||||
sstr << "X: " << m_positionX << " Y: " << m_positionY << " Z: " << m_positionZ << " O: " << m_orientation;
|
||||
return sstr.str();
|
||||
}
|
||||
|
||||
void Position::RelocateOffset(const Position& offset)
|
||||
{
|
||||
m_positionX = GetPositionX() + (offset.GetPositionX() * std::cos(GetOrientation()) + offset.GetPositionY() * std::sin(GetOrientation() + M_PI));
|
||||
m_positionY = GetPositionY() + (offset.GetPositionY() * std::cos(GetOrientation()) + offset.GetPositionX() * std::sin(GetOrientation()));
|
||||
m_positionZ = GetPositionZ() + offset.GetPositionZ();
|
||||
m_orientation = GetOrientation() + offset.GetOrientation();
|
||||
}
|
||||
|
||||
void Position::GetPositionOffsetTo(const Position& endPos, Position& retOffset) const
|
||||
{
|
||||
float dx = endPos.GetPositionX() - GetPositionX();
|
||||
float dy = endPos.GetPositionY() - GetPositionY();
|
||||
|
||||
retOffset.m_positionX = dx * cos(GetOrientation()) + dy * std::sin(GetOrientation());
|
||||
retOffset.m_positionY = dy * cos(GetOrientation()) - dx * std::sin(GetOrientation());
|
||||
retOffset.m_positionZ = endPos.GetPositionZ() - GetPositionZ();
|
||||
retOffset.m_orientation = endPos.GetOrientation() - GetOrientation();
|
||||
}
|
||||
|
||||
float Position::GetAngle(const Position* obj) const
|
||||
{
|
||||
if (!obj)
|
||||
return 0;
|
||||
|
||||
return GetAngle(obj->GetPositionX(), obj->GetPositionY());
|
||||
}
|
||||
|
||||
// Return angle in range 0..2*pi
|
||||
float Position::GetAngle(const float x, const float y) const
|
||||
{
|
||||
return getAngle(GetPositionX(), GetPositionY(), x, y);
|
||||
}
|
||||
|
||||
void Position::GetSinCos(const float x, const float y, float& vsin, float& vcos) const
|
||||
{
|
||||
float dx = GetPositionX() - x;
|
||||
float dy = GetPositionY() - y;
|
||||
|
||||
if (std::fabs(dx) < 0.001f && std::fabs(dy) < 0.001f)
|
||||
{
|
||||
float angle = (float)rand_norm() * static_cast<float>(2 * M_PI);
|
||||
vcos = std::cos(angle);
|
||||
vsin = std::sin(angle);
|
||||
}
|
||||
else
|
||||
{
|
||||
float dist = sqrt((dx * dx) + (dy * dy));
|
||||
vcos = dx / dist;
|
||||
vsin = dy / dist;
|
||||
}
|
||||
}
|
||||
|
||||
bool Position::IsWithinBox(const Position& center, float xradius, float yradius, float zradius) const
|
||||
{
|
||||
// rotate the WorldObject position instead of rotating the whole cube, that way we can make a simplified
|
||||
// is-in-cube check and we have to calculate only one point instead of 4
|
||||
|
||||
// 2PI = 360*, keep in mind that ingame orientation is counter-clockwise
|
||||
double rotation = 2 * M_PI - center.GetOrientation();
|
||||
double sinVal = std::sin(rotation);
|
||||
double cosVal = std::cos(rotation);
|
||||
|
||||
float BoxDistX = GetPositionX() - center.GetPositionX();
|
||||
float BoxDistY = GetPositionY() - center.GetPositionY();
|
||||
|
||||
float rotX = float(center.GetPositionX() + BoxDistX * cosVal - BoxDistY * sinVal);
|
||||
float rotY = float(center.GetPositionY() + BoxDistY * cosVal + BoxDistX * sinVal);
|
||||
|
||||
// box edges are parallel to coordiante axis, so we can treat every dimension independently :D
|
||||
float dz = GetPositionZ() - center.GetPositionZ();
|
||||
float dx = rotX - center.GetPositionX();
|
||||
float dy = rotY - center.GetPositionY();
|
||||
if ((std::fabs(dx) > xradius) ||
|
||||
(std::fabs(dy) > yradius) ||
|
||||
(std::fabs(dz) > zradius))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Position::HasInArc(float arc, const Position* obj, float targetRadius) const
|
||||
{
|
||||
// always have self in arc
|
||||
if (obj == this)
|
||||
return true;
|
||||
|
||||
// move arc to range 0.. 2*pi
|
||||
arc = Position::NormalizeOrientation(arc);
|
||||
|
||||
float angle = GetAngle(obj);
|
||||
angle -= m_orientation;
|
||||
|
||||
// move angle to range -pi ... +pi
|
||||
angle = Position::NormalizeOrientation(angle);
|
||||
if (angle > M_PI)
|
||||
angle -= 2.0f * M_PI;
|
||||
|
||||
float lborder = -1 * (arc / 2.0f); // in range -pi..0
|
||||
float rborder = (arc / 2.0f); // in range 0..pi
|
||||
|
||||
// pussywizard: take into consideration target size
|
||||
if (targetRadius > 0.0f)
|
||||
{
|
||||
float distSq = GetExactDist2dSq(obj);
|
||||
// pussywizard: at least a part of target's model is in every direction
|
||||
if (distSq < targetRadius * targetRadius)
|
||||
return true;
|
||||
float angularRadius = 2.0f * atan(targetRadius / (2.0f * sqrt(distSq)));
|
||||
lborder -= angularRadius;
|
||||
rborder += angularRadius;
|
||||
}
|
||||
|
||||
return (angle >= lborder) && (angle <= rborder);
|
||||
}
|
||||
|
||||
bool Position::IsPositionValid() const
|
||||
{
|
||||
return Acore::IsValidMapCoord(m_positionX, m_positionY, m_positionZ, m_orientation);
|
||||
}
|
||||
|
||||
ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer)
|
||||
{
|
||||
float x, y, z, o;
|
||||
buf >> x >> y >> z >> o;
|
||||
streamer.m_pos->Relocate(x, y, z, o);
|
||||
return buf;
|
||||
}
|
||||
|
||||
ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZStreamer const& streamer)
|
||||
{
|
||||
float x, y, z;
|
||||
streamer.m_pos->GetPosition(x, y, z);
|
||||
buf << x << y << z;
|
||||
return buf;
|
||||
}
|
||||
|
||||
ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZStreamer const& streamer)
|
||||
{
|
||||
float x, y, z;
|
||||
buf >> x >> y >> z;
|
||||
streamer.m_pos->Relocate(x, y, z);
|
||||
return buf;
|
||||
}
|
||||
|
||||
ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer)
|
||||
{
|
||||
float x, y, z, o;
|
||||
streamer.m_pos->GetPosition(x, y, z, o);
|
||||
buf << x << y << z << o;
|
||||
return buf;
|
||||
}
|
||||
328
src/server/game/Entities/Object/Position.h
Normal file
328
src/server/game/Entities/Object/Position.h
Normal file
@@ -0,0 +1,328 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 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 Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ACore_game_Position_h__
|
||||
#define ACore_game_Position_h__
|
||||
|
||||
#include "Common.h"
|
||||
#include "G3D/Vector3.h"
|
||||
|
||||
class ByteBuffer;
|
||||
|
||||
struct Position
|
||||
{
|
||||
Position(float x = 0, float y = 0, float z = 0, float o = 0)
|
||||
: m_positionX(x), m_positionY(y), m_positionZ(z), m_orientation(NormalizeOrientation(o)) { }
|
||||
|
||||
Position(Position const& loc) { Relocate(loc); }
|
||||
/* requried as of C++ 11 */
|
||||
Position(Position&&) = default;
|
||||
Position& operator=(const Position&) = default;
|
||||
Position& operator=(Position&&) = default;
|
||||
|
||||
struct PositionXYStreamer
|
||||
{
|
||||
explicit PositionXYStreamer(Position& pos) : Pos(&pos) { }
|
||||
Position* Pos;
|
||||
};
|
||||
|
||||
struct PositionXYZStreamer
|
||||
{
|
||||
explicit PositionXYZStreamer(Position& pos) : m_pos(&pos) {}
|
||||
Position* m_pos;
|
||||
};
|
||||
|
||||
struct PositionXYZOStreamer
|
||||
{
|
||||
explicit PositionXYZOStreamer(Position& pos) : m_pos(&pos) {}
|
||||
Position* m_pos;
|
||||
};
|
||||
|
||||
float m_positionX = 0;
|
||||
float m_positionY = 0;
|
||||
float m_positionZ = 0;
|
||||
float m_orientation = 0; // Better to limit access to _orientation field, to guarantee the value is normalized
|
||||
|
||||
bool operator==(Position const& a) const;
|
||||
|
||||
inline bool operator!=(Position const& a)
|
||||
{
|
||||
return !(operator==(a));
|
||||
}
|
||||
|
||||
operator G3D::Vector3() const
|
||||
{
|
||||
return { m_positionX, m_positionY, m_positionZ };
|
||||
}
|
||||
|
||||
void Relocate(float x, float y)
|
||||
{
|
||||
m_positionX = x;
|
||||
m_positionY = y;
|
||||
}
|
||||
|
||||
void Relocate(float x, float y, float z)
|
||||
{
|
||||
m_positionX = x;
|
||||
m_positionY = y;
|
||||
m_positionZ = z;
|
||||
}
|
||||
|
||||
void Relocate(float x, float y, float z, float orientation)
|
||||
{
|
||||
m_positionX = x;
|
||||
m_positionY = y;
|
||||
m_positionZ = z;
|
||||
m_orientation = orientation;
|
||||
}
|
||||
|
||||
void Relocate(const Position& pos)
|
||||
{
|
||||
m_positionX = pos.m_positionX;
|
||||
m_positionY = pos.m_positionY;
|
||||
m_positionZ = pos.m_positionZ;
|
||||
m_orientation = pos.m_orientation;
|
||||
}
|
||||
|
||||
void Relocate(const Position* pos)
|
||||
{
|
||||
m_positionX = pos->m_positionX;
|
||||
m_positionY = pos->m_positionY;
|
||||
m_positionZ = pos->m_positionZ;
|
||||
m_orientation = pos->m_orientation;
|
||||
}
|
||||
|
||||
void RelocatePolarOffset(float angle, float dist, float z = 0.0f);
|
||||
void RelocateOffset(const Position& offset);
|
||||
void SetOrientation(float orientation)
|
||||
{
|
||||
m_orientation = orientation;
|
||||
}
|
||||
|
||||
[[nodiscard]] float GetPositionX() const { return m_positionX; }
|
||||
[[nodiscard]] float GetPositionY() const { return m_positionY; }
|
||||
[[nodiscard]] float GetPositionZ() const { return m_positionZ; }
|
||||
[[nodiscard]] float GetOrientation() const { return m_orientation; }
|
||||
|
||||
void GetPosition(float& x, float& y) const
|
||||
{
|
||||
x = m_positionX;
|
||||
y = m_positionY;
|
||||
}
|
||||
|
||||
void GetPosition(float& x, float& y, float& z) const
|
||||
{
|
||||
x = m_positionX;
|
||||
y = m_positionY;
|
||||
z = m_positionZ;
|
||||
}
|
||||
|
||||
void GetPosition(float& x, float& y, float& z, float& o) const
|
||||
{
|
||||
x = m_positionX;
|
||||
y = m_positionY;
|
||||
z = m_positionZ;
|
||||
o = m_orientation;
|
||||
}
|
||||
|
||||
[[nodiscard]] Position GetPosition() const { return *this; }
|
||||
|
||||
Position::PositionXYZStreamer PositionXYZStream()
|
||||
{
|
||||
return PositionXYZStreamer(*this);
|
||||
}
|
||||
|
||||
Position::PositionXYZOStreamer PositionXYZOStream()
|
||||
{
|
||||
return PositionXYZOStreamer(*this);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsPositionValid() const;
|
||||
|
||||
[[nodiscard]] float GetExactDist2dSq(const float x, const float y) const
|
||||
{
|
||||
float dx = x - m_positionX;
|
||||
float dy = y - m_positionY;
|
||||
return dx*dx + dy*dy;
|
||||
}
|
||||
|
||||
[[nodiscard]] float GetExactDist2dSq(Position const& pos) const { return GetExactDist2dSq(pos.m_positionX, pos.m_positionY); }
|
||||
float GetExactDist2dSq(Position const* pos) const { return GetExactDist2dSq(*pos); }
|
||||
[[nodiscard]] float GetExactDist2d(const float x, const float y) const { return std::sqrt(GetExactDist2dSq(x, y)); }
|
||||
[[nodiscard]] float GetExactDist2d(Position const& pos) const { return GetExactDist2d(pos.m_positionX, pos.m_positionY); }
|
||||
float GetExactDist2d(Position const* pos) const { return GetExactDist2d(*pos); }
|
||||
|
||||
[[nodiscard]] float GetExactDistSq(float x, float y, float z) const
|
||||
{
|
||||
float dz = z - m_positionZ;
|
||||
return GetExactDist2dSq(x, y) + dz*dz;
|
||||
}
|
||||
|
||||
[[nodiscard]] float GetExactDistSq(Position const& pos) const { return GetExactDistSq(pos.m_positionX, pos.m_positionY, pos.m_positionZ); }
|
||||
float GetExactDistSq(Position const* pos) const { return GetExactDistSq(*pos); }
|
||||
[[nodiscard]] float GetExactDist(float x, float y, float z) const { return std::sqrt(GetExactDistSq(x, y, z)); }
|
||||
[[nodiscard]] float GetExactDist(Position const& pos) const { return GetExactDist(pos.m_positionX, pos.m_positionY, pos.m_positionZ); }
|
||||
float GetExactDist(Position const* pos) const { return GetExactDist(*pos); }
|
||||
|
||||
void GetPositionOffsetTo(const Position& endPos, Position& retOffset) const;
|
||||
[[nodiscard]] Position GetPositionWithOffset(Position const& offset) const;
|
||||
|
||||
float GetAngle(const Position* pos) const;
|
||||
[[nodiscard]] float GetAngle(float x, float y) const;
|
||||
[[nodiscard]] float GetAbsoluteAngle(float x, float y) const
|
||||
{
|
||||
return NormalizeOrientation(std::atan2(
|
||||
static_cast<float>(y - m_positionY),
|
||||
static_cast<float>(x - m_positionX))
|
||||
);
|
||||
}
|
||||
[[nodiscard]] float GetAbsoluteAngle(Position const& pos) const { return GetAbsoluteAngle(pos.m_positionX, pos.m_positionY); }
|
||||
[[nodiscard]] float GetAbsoluteAngle(Position const* pos) const { return GetAbsoluteAngle(*pos); }
|
||||
|
||||
float GetRelativeAngle(const Position* pos) const
|
||||
{
|
||||
return GetAngle(pos) - m_orientation;
|
||||
}
|
||||
|
||||
[[nodiscard]] float GetRelativeAngle(float x, float y) const { return GetAngle(x, y) - m_orientation; }
|
||||
[[nodiscard]] float ToAbsoluteAngle(float relAngle) const { return NormalizeOrientation(relAngle + m_orientation); }
|
||||
|
||||
void GetSinCos(float x, float y, float& vsin, float& vcos) const;
|
||||
|
||||
[[nodiscard]] bool IsInDist2d(float x, float y, float dist) const
|
||||
{
|
||||
return GetExactDist2dSq(x, y) < dist * dist;
|
||||
}
|
||||
|
||||
bool IsInDist2d(const Position* pos, float dist) const
|
||||
{
|
||||
return GetExactDist2dSq(pos) < dist * dist;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsInDist(float x, float y, float z, float dist) const
|
||||
{
|
||||
return GetExactDistSq(x, y, z) < dist * dist;
|
||||
}
|
||||
|
||||
bool IsInDist(const Position* pos, float dist) const
|
||||
{
|
||||
return GetExactDistSq(pos) < dist * dist;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsWithinBox(const Position& center, float xradius, float yradius, float zradius) const;
|
||||
bool HasInArc(float arcangle, const Position* pos, float targetRadius = 0.0f) const;
|
||||
bool HasInLine(Position const* pos, float width) const;
|
||||
[[nodiscard]] std::string ToString() const;
|
||||
|
||||
// modulos a radian orientation to the range of 0..2PI
|
||||
static float NormalizeOrientation(float o)
|
||||
{
|
||||
// fmod only supports positive numbers. Thus we have
|
||||
// to emulate negative numbers
|
||||
if (o < 0)
|
||||
{
|
||||
float mod = o * -1;
|
||||
mod = std::fmod(mod, 2.0f * static_cast<float>(M_PI));
|
||||
mod = -mod + 2.0f * static_cast<float>(M_PI);
|
||||
return mod;
|
||||
}
|
||||
return std::fmod(o, 2.0f * static_cast<float>(M_PI));
|
||||
}
|
||||
};
|
||||
|
||||
#define MAPID_INVALID 0xFFFFFFFF
|
||||
|
||||
class WorldLocation : public Position
|
||||
{
|
||||
public:
|
||||
explicit WorldLocation(uint32 _mapId = MAPID_INVALID, float x = 0.f, float y = 0.f, float z = 0.f, float o = 0.f)
|
||||
: Position(x, y, z, o), m_mapId(_mapId) { }
|
||||
|
||||
WorldLocation(uint32 mapId, Position const& position)
|
||||
: Position(position), m_mapId(mapId) { }
|
||||
|
||||
void WorldRelocate(const WorldLocation& loc)
|
||||
{
|
||||
m_mapId = loc.GetMapId();
|
||||
Relocate(loc);
|
||||
}
|
||||
|
||||
void WorldRelocate(uint32 mapId = MAPID_INVALID, float x = 0.f, float y = 0.f, float z = 0.f, float o = 0.f)
|
||||
{
|
||||
m_mapId = mapId;
|
||||
Relocate(x, y, z, o);
|
||||
}
|
||||
|
||||
void SetMapId(uint32 mapId)
|
||||
{
|
||||
m_mapId = mapId;
|
||||
}
|
||||
|
||||
[[nodiscard]] uint32 GetMapId() const
|
||||
{
|
||||
return m_mapId;
|
||||
}
|
||||
|
||||
void GetWorldLocation(uint32& mapId, float& x, float& y) const
|
||||
{
|
||||
mapId = m_mapId;
|
||||
x = m_positionX;
|
||||
y = m_positionY;
|
||||
}
|
||||
|
||||
void GetWorldLocation(uint32& mapId, float& x, float& y, float& z) const
|
||||
{
|
||||
mapId = m_mapId;
|
||||
x = m_positionX;
|
||||
y = m_positionY;
|
||||
z = m_positionZ;
|
||||
}
|
||||
|
||||
void GetWorldLocation(uint32& mapId, float& x, float& y, float& z, float& o) const
|
||||
{
|
||||
mapId = m_mapId;
|
||||
x = m_positionX;
|
||||
y = m_positionY;
|
||||
z = m_positionZ;
|
||||
o = GetOrientation();
|
||||
}
|
||||
|
||||
void GetWorldLocation(WorldLocation* location) const
|
||||
{
|
||||
if (location)
|
||||
{
|
||||
location->Relocate(m_positionX, m_positionY, m_positionZ, GetOrientation());
|
||||
location->SetMapId(m_mapId);
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] WorldLocation GetWorldLocation() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint32 m_mapId;
|
||||
};
|
||||
|
||||
ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYStreamer const& streamer);
|
||||
ByteBuffer& operator >> (ByteBuffer& buf, Position::PositionXYStreamer const& streamer);
|
||||
ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZStreamer const& streamer);
|
||||
ByteBuffer& operator >> (ByteBuffer& buf, Position::PositionXYZStreamer const& streamer);
|
||||
ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer);
|
||||
ByteBuffer& operator >> (ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer);
|
||||
|
||||
#endif // ACore_game_Position_h__
|
||||
@@ -576,7 +576,7 @@ void Unit::UpdateSplinePosition()
|
||||
pos.m_positionX = loc.x;
|
||||
pos.m_positionY = loc.y;
|
||||
pos.m_positionZ = loc.z;
|
||||
pos.m_orientation = loc.orientation;
|
||||
pos.SetOrientation(loc.orientation);
|
||||
|
||||
if (TransportBase* transport = GetDirectTransport())
|
||||
transport->CalculatePassengerPosition(loc.x, loc.y, loc.z, &loc.orientation);
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "ObjectDefines.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "PathGenerator.h"
|
||||
#include "Position.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "Timer.h"
|
||||
#include <bitset>
|
||||
|
||||
@@ -8689,7 +8689,7 @@ namespace Acore
|
||||
}
|
||||
else if (_spellInfo->HasAttribute(SPELL_ATTR0_CU_CONE_LINE))
|
||||
{
|
||||
if (!_caster->HasInLine(target, _caster->GetObjectSize()))
|
||||
if (!_caster->HasInLine(target, _caster->GetObjectSize() + target->GetObjectSize()))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
@@ -8709,7 +8709,7 @@ namespace Acore
|
||||
bool WorldObjectSpellTrajTargetCheck::operator()(WorldObject* target)
|
||||
{
|
||||
// return all targets on missile trajectory (0 - size of a missile)
|
||||
if (!_caster->HasInLine(target, 0))
|
||||
if (!_caster->HasInLine(target, target->GetObjectSize()))
|
||||
return false;
|
||||
return WorldObjectSpellAreaTargetCheck::operator ()(target);
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ public:
|
||||
// Teleports a random player and spawns 9 Sacrificed Trolls to attack player
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
{
|
||||
DoTeleportPlayer(target, TeleportLoc.m_positionX, TeleportLoc.m_positionY, TeleportLoc.m_positionZ, TeleportLoc.m_orientation);
|
||||
DoTeleportPlayer(target, TeleportLoc.m_positionX, TeleportLoc.m_positionY, TeleportLoc.m_positionZ, TeleportLoc.GetOrientation());
|
||||
if (DoGetThreat(me->GetVictim()))
|
||||
DoModifyThreatPercent(target, -100);
|
||||
Creature* SacrificedTroll;
|
||||
|
||||
@@ -319,7 +319,7 @@ public:
|
||||
case EVENT_SPAWN_WAVE_1:
|
||||
{
|
||||
Position spawnPos = c->GetPosition();
|
||||
spawnPos.m_orientation = 5.80f;
|
||||
spawnPos.SetOrientation(5.80f);
|
||||
spawnPos.m_positionX += 5.0f * cos(4.5f);
|
||||
spawnPos.m_positionY += 5.0f * std::sin(4.5f);
|
||||
for (uint8 i = 0; i < 5; ++i)
|
||||
@@ -333,7 +333,7 @@ public:
|
||||
case EVENT_SPAWN_WAVE_2:
|
||||
{
|
||||
Position spawnPos = c->GetPosition();
|
||||
spawnPos.m_orientation = 5.80f;
|
||||
spawnPos.SetOrientation(5.80f);
|
||||
spawnPos.m_positionX += 7.0f * cos(4.0f);
|
||||
spawnPos.m_positionY += 7.0f * std::sin(4.0f);
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
@@ -348,7 +348,7 @@ public:
|
||||
case EVENT_SPAWN_WAVE_3:
|
||||
{
|
||||
Position spawnPos = c->GetPosition();
|
||||
spawnPos.m_orientation = 5.80f;
|
||||
spawnPos.SetOrientation(5.80f);
|
||||
spawnPos.m_positionX += 8.0f * cos(4.0f);
|
||||
spawnPos.m_positionY += 8.0f * std::sin(4.0f);
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
|
||||
@@ -372,12 +372,12 @@ public:
|
||||
void DoSummonPriestess()
|
||||
{
|
||||
// Summon 2 Elune priestess and make each of them move to a different spot
|
||||
if (Creature* priestess = me->SummonCreature(NPC_PRIESTESS_ELUNE, wingThicketLocations[0].m_positionX, wingThicketLocations[0].m_positionY, wingThicketLocations[0].m_positionZ, wingThicketLocations[0].m_orientation, TEMPSUMMON_CORPSE_DESPAWN, 0))
|
||||
if (Creature* priestess = me->SummonCreature(NPC_PRIESTESS_ELUNE, wingThicketLocations[0].m_positionX, wingThicketLocations[0].m_positionY, wingThicketLocations[0].m_positionZ, wingThicketLocations[0].GetOrientation(), TEMPSUMMON_CORPSE_DESPAWN, 0))
|
||||
{
|
||||
priestess->GetMotionMaster()->MovePoint(0, wingThicketLocations[3].m_positionX, wingThicketLocations[3].m_positionY, wingThicketLocations[3].m_positionZ);
|
||||
_firstPriestessGUID = priestess->GetGUID();
|
||||
}
|
||||
if (Creature* priestess = me->SummonCreature(NPC_PRIESTESS_ELUNE, wingThicketLocations[1].m_positionX, wingThicketLocations[1].m_positionY, wingThicketLocations[1].m_positionZ, wingThicketLocations[1].m_orientation, TEMPSUMMON_CORPSE_DESPAWN, 0))
|
||||
if (Creature* priestess = me->SummonCreature(NPC_PRIESTESS_ELUNE, wingThicketLocations[1].m_positionX, wingThicketLocations[1].m_positionY, wingThicketLocations[1].m_positionZ, wingThicketLocations[1].GetOrientation(), TEMPSUMMON_CORPSE_DESPAWN, 0))
|
||||
{
|
||||
// Left priestess should have a distinct move point because she is the one who starts the dialogue at point reach
|
||||
priestess->GetMotionMaster()->MovePoint(1, wingThicketLocations[4].m_positionX, wingThicketLocations[4].m_positionY, wingThicketLocations[4].m_positionZ);
|
||||
@@ -475,7 +475,7 @@ public:
|
||||
break;
|
||||
case SAY_PRIESTESS_ALTAR_13:
|
||||
// summon the Guardian of Elune
|
||||
if (Creature* guard = me->SummonCreature(NPC_GUARDIAN_ELUNE, wingThicketLocations[2].m_positionX, wingThicketLocations[2].m_positionY, wingThicketLocations[2].m_positionZ, wingThicketLocations[2].m_orientation, TEMPSUMMON_CORPSE_DESPAWN, 0))
|
||||
if (Creature* guard = me->SummonCreature(NPC_GUARDIAN_ELUNE, wingThicketLocations[2].m_positionX, wingThicketLocations[2].m_positionY, wingThicketLocations[2].m_positionZ, wingThicketLocations[2].GetOrientation(), TEMPSUMMON_CORPSE_DESPAWN, 0))
|
||||
{
|
||||
guard->GetMotionMaster()->MovePoint(0, wingThicketLocations[5].m_positionX, wingThicketLocations[5].m_positionY, wingThicketLocations[5].m_positionZ);
|
||||
_guardEluneGUID = guard->GetGUID();
|
||||
|
||||
@@ -505,7 +505,7 @@ public:
|
||||
|
||||
if (caster->IsWithinLOS(nx, ny, z))
|
||||
{
|
||||
caster->m_orientation = angle;
|
||||
caster->SetOrientation(angle);
|
||||
caster->CastSpell(nx, ny, z, uint32(GetEffectValue()), true);
|
||||
}
|
||||
}
|
||||
@@ -602,7 +602,7 @@ public:
|
||||
float ny = y + 2.5f * std::sin((M_PI / 4) + (i * (M_PI / 2)));
|
||||
if (caster->IsWithinLOS(nx, ny, z))
|
||||
{
|
||||
caster->m_orientation = (M_PI / 4) + (i * (M_PI / 2));
|
||||
caster->SetOrientation((M_PI / 4) + (i * (M_PI / 2)));
|
||||
caster->CastSpell(nx, ny, z, uint32(GetEffectValue() + i), true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,7 +487,7 @@ public:
|
||||
pos.m_positionX = CenterPos.GetPositionX() + cos(angle) * 40.0f;
|
||||
pos.m_positionY = CenterPos.GetPositionY() + std::sin(angle) * 40.0f;
|
||||
pos.m_positionZ = CenterPos.GetPositionZ() + 20.0f;
|
||||
pos.m_orientation = pos.GetAngle(&CenterPos);
|
||||
pos.SetOrientation(pos.GetAngle(&CenterPos));
|
||||
|
||||
if (Creature* vp = me->SummonCreature(NPC_WORLD_TRIGGER_LAOI, pos, TEMPSUMMON_TIMED_DESPAWN, 14000))
|
||||
{
|
||||
@@ -506,7 +506,7 @@ public:
|
||||
plrpos.m_positionX = CenterPos.GetPositionX() + cos(playerAngle) * 5.0f;
|
||||
plrpos.m_positionY = CenterPos.GetPositionY() + std::sin(playerAngle) * 5.0f;
|
||||
plrpos.m_positionZ = CenterPos.GetPositionZ() + 18.0f;
|
||||
plrpos.m_orientation = plrpos.GetAngle(&CenterPos);
|
||||
plrpos.SetOrientation(plrpos.GetAngle(&CenterPos));
|
||||
|
||||
if (Creature* c = me->SummonCreature(NPC_VORTEX, plrpos, TEMPSUMMON_TIMED_DESPAWN, 15000))
|
||||
{
|
||||
@@ -880,7 +880,7 @@ public:
|
||||
pos.m_positionX = CenterPos.GetPositionX() + VORTEX_RADIUS * cos(angle);
|
||||
pos.m_positionY = CenterPos.GetPositionY() + VORTEX_RADIUS * std::sin(angle);
|
||||
pos.m_positionZ = CenterPos.GetPositionZ() + h;
|
||||
pos.m_orientation = pos.GetAngle(&CenterPos);
|
||||
pos.SetOrientation(pos.GetAngle(&CenterPos));
|
||||
me->SetPosition(pos);
|
||||
timer = 0;
|
||||
despawnTimer = 9500;
|
||||
|
||||
@@ -2470,9 +2470,9 @@ public:
|
||||
break;
|
||||
case EVENT_EMERGENCY_BOT_CHECK:
|
||||
events.RepeatEvent(15000); // just in case, will be rescheduled
|
||||
if( Creature* flame = me->FindNearestCreature(NPC_FLAMES_SPREAD, 150.0f, true) )
|
||||
if (Creature* flame = me->FindNearestCreature(NPC_FLAMES_SPREAD, 150.0f, true))
|
||||
{
|
||||
me->m_orientation = me->GetAngle(flame->GetPositionX(), flame->GetPositionY());
|
||||
me->SetOrientation(me->GetAngle(flame->GetPositionX(), flame->GetPositionY()));
|
||||
float dist = me->GetExactDist2d(flame);
|
||||
if (dist <= 5.0f)
|
||||
events.ScheduleEvent(EVENT_EMERGENCY_BOT_ATTACK, 0);
|
||||
|
||||
@@ -1533,7 +1533,7 @@ public:
|
||||
{
|
||||
if (id == 1)
|
||||
{
|
||||
me->SetFacingTo(PosTalkLocations[talkWing].m_orientation);
|
||||
me->SetFacingTo(PosTalkLocations[talkWing].GetOrientation());
|
||||
TurnAudience();
|
||||
|
||||
switch (talkWing)
|
||||
|
||||
@@ -1093,7 +1093,7 @@ class spell_item_draenic_pale_ale : public SpellScript
|
||||
for (uint8 count = 0; count < GetEffectValue(); ++count)
|
||||
{
|
||||
Position pos = *GetCaster();
|
||||
GetCaster()->GetClosePoint(pos.m_positionX, pos.m_positionY, pos.m_positionZ, pos.m_orientation, radius, M_PI - 1.2f + 0.3f * urand(0, 8));
|
||||
GetCaster()->GetClosePoint(pos.m_positionX, pos.m_positionY, pos.m_positionZ, pos.GetOrientation(), radius, M_PI - 1.2f + 0.3f * urand(0, 8));
|
||||
Creature* summon = GetCaster()->SummonCreature(GetSpellInfo()->Effects[effIndex].MiscValue, pos, TEMPSUMMON_TIMED_DESPAWN, GetSpellInfo()->GetDuration());
|
||||
if (!summon)
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user