Core/Spells: Blink wont be able to trespass solid objects anymore (walls/doors)
Refactored some code Signed-off-by: Subv <[email protected]>
This commit is contained in:
@@ -176,6 +176,54 @@ struct DynamicTreeIntersectionCallback_WithLogger
|
||||
bool didHit() const { return did_hit;}
|
||||
};
|
||||
|
||||
bool DynamicMapTree::getIntersectionTime(const uint32 phasemask, const G3D::Ray& ray, const Vector3& endPos, float& maxDist) const
|
||||
{
|
||||
float distance = maxDist;
|
||||
DynamicTreeIntersectionCallback callback(phasemask);
|
||||
impl.intersectRay(ray, callback, distance, endPos);
|
||||
if (callback.didHit())
|
||||
maxDist = distance;
|
||||
return callback.didHit();
|
||||
}
|
||||
|
||||
bool DynamicMapTree::getObjectHitPos(const uint32 phasemask, const Vector3& startPos, const Vector3& endPos, Vector3& resultHit, float modifyDist) const
|
||||
{
|
||||
bool result = false;
|
||||
float maxDist = (endPos - startPos).magnitude();
|
||||
// valid map coords should *never ever* produce float overflow, but this would produce NaNs too
|
||||
ASSERT(maxDist < std::numeric_limits<float>::max());
|
||||
// prevent NaN values which can cause BIH intersection to enter infinite loop
|
||||
if (maxDist < 1e-10f)
|
||||
{
|
||||
resultHit = endPos;
|
||||
return false;
|
||||
}
|
||||
Vector3 dir = (endPos - startPos)/maxDist; // direction with length of 1
|
||||
G3D::Ray ray(startPos, dir);
|
||||
float dist = maxDist;
|
||||
if (getIntersectionTime(phasemask, ray, endPos, dist))
|
||||
{
|
||||
resultHit = startPos + dir * dist;
|
||||
if (modifyDist < 0)
|
||||
{
|
||||
if ((resultHit - startPos).magnitude() > -modifyDist)
|
||||
resultHit = resultHit + dir*modifyDist;
|
||||
else
|
||||
resultHit = startPos;
|
||||
}
|
||||
else
|
||||
resultHit = resultHit + dir*modifyDist;
|
||||
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
resultHit = endPos;
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DynamicMapTree::isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const
|
||||
{
|
||||
Vector3 v1(x1,y1,z1), v2(x2,y2,z2);
|
||||
|
||||
@@ -46,6 +46,8 @@ public:
|
||||
~DynamicMapTree();
|
||||
|
||||
bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const;
|
||||
bool getIntersectionTime(uint32 phasemask, const G3D::Ray& ray, const Vector3& endPos, float& maxDist) const;
|
||||
bool getObjectHitPos(uint32 phasemask, const Vector3& pPos1, const Vector3& pPos2, Vector3& pResultHitPos, float pModifyDist) const;
|
||||
float getHeight(float x, float y, float z, float maxSearchDist, uint32 phasemask) const;
|
||||
|
||||
void insert(const GameObjectModel&);
|
||||
|
||||
@@ -2671,7 +2671,7 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float
|
||||
{
|
||||
angle += m_orientation;
|
||||
float destx, desty, destz, ground, floor;
|
||||
|
||||
pos.m_positionZ += 2.0f;
|
||||
destx = pos.m_positionX + dist * cos(angle);
|
||||
desty = pos.m_positionY + dist * sin(angle);
|
||||
ground = GetMap()->GetHeight(GetPhaseMask(), destx, desty, MAX_HEIGHT, true);
|
||||
@@ -2689,6 +2689,17 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float
|
||||
dist = sqrt((pos.m_positionX - destx)*(pos.m_positionX - destx) + (pos.m_positionY - desty)*(pos.m_positionY - desty));
|
||||
}
|
||||
|
||||
// check dynamic collision
|
||||
col = GetMap()->getObjectHitPos(GetPhaseMask(), pos.m_positionX, pos.m_positionY, pos.m_positionZ+0.5f, destx, desty, destz+0.5f, destx, desty, destz, -0.5f);
|
||||
|
||||
// Collided with a gameobject
|
||||
if (col)
|
||||
{
|
||||
destx -= CONTACT_DISTANCE * cos(angle);
|
||||
desty -= CONTACT_DISTANCE * sin(angle);
|
||||
dist = sqrt((pos.m_positionX - destx)*(pos.m_positionX - destx) + (pos.m_positionY - desty)*(pos.m_positionY - desty));
|
||||
}
|
||||
|
||||
float step = dist/10.0f;
|
||||
|
||||
for (uint8 j = 0; j < 10; ++j)
|
||||
@@ -2712,7 +2723,7 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float
|
||||
|
||||
Trinity::NormalizeMapCoord(pos.m_positionX);
|
||||
Trinity::NormalizeMapCoord(pos.m_positionY);
|
||||
UpdateGroundPositionZ(pos.m_positionX, pos.m_positionY, pos.m_positionZ);
|
||||
UpdateAllowedPositionZ(pos.m_positionX, pos.m_positionY, pos.m_positionZ);
|
||||
pos.m_orientation = m_orientation;
|
||||
}
|
||||
|
||||
|
||||
@@ -500,7 +500,7 @@ void Map::VisitNearbyCellsOf(WorldObject* obj, TypeContainerVisitor<Trinity::Obj
|
||||
|
||||
void Map::Update(const uint32 t_diff)
|
||||
{
|
||||
m_dyn_tree.update(t_diff);
|
||||
_dynamicTree.update(t_diff);
|
||||
/// update worldsessions for existing players
|
||||
for (m_mapRefIter = m_mapRefManager.begin(); m_mapRefIter != m_mapRefManager.end(); ++m_mapRefIter)
|
||||
{
|
||||
@@ -1800,12 +1800,26 @@ void Map::GetZoneAndAreaIdByAreaFlag(uint32& zoneid, uint32& areaid, uint16 area
|
||||
bool Map::isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const
|
||||
{
|
||||
return VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(GetId(), x1, y1, z1, x2, y2, z2)
|
||||
&& m_dyn_tree.isInLineOfSight(x1, y1, z1, x2, y2, z2, phasemask);
|
||||
&& _dynamicTree.isInLineOfSight(x1, y1, z1, x2, y2, z2, phasemask);
|
||||
}
|
||||
|
||||
bool Map::getObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist)
|
||||
{
|
||||
Vector3 startPos = Vector3(x1, y1, z1);
|
||||
Vector3 dstPos = Vector3(x2, y2, z2);
|
||||
|
||||
Vector3 resultPos;
|
||||
bool result = _dynamicTree.getObjectHitPos(phasemask, startPos, dstPos, resultPos, modifyDist);
|
||||
|
||||
rx = resultPos.x;
|
||||
ry = resultPos.y;
|
||||
rz = resultPos.z;
|
||||
return result;
|
||||
}
|
||||
|
||||
float Map::GetHeight(uint32 phasemask, float x, float y, float z, bool vmap/*=true*/, float maxSearchDist/*=DEFAULT_HEIGHT_SEARCH*/) const
|
||||
{
|
||||
return std::max<float>(GetHeight(x, y, z, vmap, maxSearchDist), m_dyn_tree.getHeight(x, y, z, maxSearchDist, phasemask));
|
||||
return std::max<float>(GetHeight(x, y, z, vmap, maxSearchDist), _dynamicTree.getHeight(x, y, z, maxSearchDist, phasemask));
|
||||
}
|
||||
|
||||
bool Map::IsInWater(float x, float y, float pZ, LiquidData* data) const
|
||||
|
||||
@@ -429,10 +429,11 @@ class Map : public GridRefManager<NGridType>
|
||||
float GetWaterOrGroundLevel(float x, float y, float z, float* ground = NULL, bool swim = false) const;
|
||||
float GetHeight(uint32 phasemask, float x, float y, float z, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const;
|
||||
bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask) const;
|
||||
void Balance() { m_dyn_tree.balance(); }
|
||||
void Remove(const GameObjectModel& mdl) { m_dyn_tree.remove(mdl); }
|
||||
void Insert(const GameObjectModel& mdl) { m_dyn_tree.insert(mdl); }
|
||||
bool Contains(const GameObjectModel& mdl) const { return m_dyn_tree.contains(mdl);}
|
||||
void Balance() { _dynamicTree.balance(); }
|
||||
void Remove(const GameObjectModel& mdl) { _dynamicTree.remove(mdl); }
|
||||
void Insert(const GameObjectModel& mdl) { _dynamicTree.insert(mdl); }
|
||||
bool Contains(const GameObjectModel& mdl) const { return _dynamicTree.contains(mdl);}
|
||||
bool getObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist);
|
||||
private:
|
||||
void LoadMapAndVMap(int gx, int gy);
|
||||
void LoadVMap(int gx, int gy);
|
||||
@@ -488,7 +489,7 @@ class Map : public GridRefManager<NGridType>
|
||||
uint32 i_InstanceId;
|
||||
uint32 m_unloadTimer;
|
||||
float m_VisibleDistance;
|
||||
DynamicMapTree m_dyn_tree;
|
||||
DynamicMapTree _dynamicTree;
|
||||
|
||||
MapRefManager m_mapRefManager;
|
||||
MapRefManager::iterator m_mapRefIter;
|
||||
|
||||
@@ -6076,7 +6076,10 @@ void Spell::EffectLeap(SpellEffIndex /*effIndex*/)
|
||||
if (!m_targets.HasDst())
|
||||
return;
|
||||
|
||||
unitTarget->NearTeleportTo(m_targets.GetDst()->GetPositionX(), m_targets.GetDst()->GetPositionY(), m_targets.GetDst()->GetPositionZ(), m_targets.GetDst()->GetOrientation(), unitTarget == m_caster);
|
||||
Position pos;
|
||||
m_targets.GetDst()->GetPosition(&pos);
|
||||
unitTarget->GetFirstCollisionPosition(pos, unitTarget->GetDistance(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ() + 2.0f), 0.0f);
|
||||
unitTarget->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), unitTarget == m_caster);
|
||||
}
|
||||
|
||||
void Spell::EffectReputation(SpellEffIndex effIndex)
|
||||
|
||||
Reference in New Issue
Block a user