aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrisjdc <trisjdc@gmail.com>2014-07-05 15:35:21 +0100
committerTrisjdc <trisjdc@gmail.com>2014-07-05 15:35:21 +0100
commitdad9b01b265b9353424150eb9b268a735054238e (patch)
treec2018530a3413cf413a8aa923d273a35e06bf7ff
parenta1fb24f5ed8f7b0d4abf1bcf02edec5e8afb4747 (diff)
Core/Spells: Fix Blink/_DEST spell effects when cast inside/near water
-rw-r--r--src/server/game/Entities/Object/Object.cpp48
-rw-r--r--src/server/game/Spells/SpellEffects.cpp2
2 files changed, 35 insertions, 15 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 4ff0153dea8..08d984e0790 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -2603,13 +2603,39 @@ void WorldObject::MovePosition(Position &pos, float dist, float angle)
pos.SetOrientation(GetOrientation());
}
+// @todo: replace with WorldObject::UpdateAllowedPositionZ
+float NormalizeZforCollision(WorldObject* obj, float x, float y, float z)
+{
+ float ground = obj->GetMap()->GetHeight(obj->GetPhaseMask(), x, y, MAX_HEIGHT, true);
+ float floor = obj->GetMap()->GetHeight(obj->GetPhaseMask(), x, y, z + 2.0f, true);
+ float helper = fabs(ground - z) <= fabs(floor - z) ? ground : floor;
+ if (z > helper) // must be above ground
+ {
+ if (Unit* unit = obj->ToUnit())
+ {
+ if (unit->CanFly())
+ return z;
+ }
+ LiquidData liquid_status;
+ ZLiquidStatus res = obj->GetMap()->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquid_status);
+ if (res && liquid_status.level > helper) // water must be above ground
+ {
+ if (liquid_status.level > z) // z is underwater
+ return z;
+ else
+ return fabs(liquid_status.level - z) <= fabs(helper - z) ? liquid_status.level : helper;
+ }
+ }
+ return helper;
+}
+
void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float angle)
{
angle += GetOrientation();
- float destx, desty, destz, ground, floor;
- pos.m_positionZ += 2.0f;
+ float destx, desty, destz;
destx = pos.m_positionX + dist * std::cos(angle);
desty = pos.m_positionY + dist * std::sin(angle);
+ destz = NormalizeZforCollision(this, destx, desty, pos.GetPositionZ());
// Prevent invalid coordinates here, position is unchanged
if (!Trinity::IsValidMapCoord(destx, desty))
@@ -2618,11 +2644,7 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float
return;
}
- ground = GetMap()->GetHeight(GetPhaseMask(), destx, desty, MAX_HEIGHT, true);
- floor = GetMap()->GetHeight(GetPhaseMask(), destx, desty, pos.m_positionZ, true);
- destz = fabs(ground - pos.m_positionZ) <= fabs(floor - pos.m_positionZ) ? ground : floor;
-
- bool col = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(GetMapId(), pos.m_positionX, pos.m_positionY, pos.m_positionZ+0.5f, destx, desty, destz+0.5f, destx, desty, destz, -0.5f);
+ bool col = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(GetMapId(), pos.m_positionX, pos.m_positionY, pos.m_positionZ + 0.5f, destx, desty, destz + 0.5f, destx, desty, destz, -0.5f);
// collision occured
if (col)
@@ -2634,7 +2656,7 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float
}
// 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);
+ 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)
@@ -2644,18 +2666,16 @@ 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));
}
- float step = dist/10.0f;
+ float step = dist / 10.0f;
for (uint8 j = 0; j < 10; ++j)
{
// do not allow too big z changes
- if (fabs(pos.m_positionZ - destz) > 6)
+ if (fabs(pos.m_positionZ - destz) > 6.0f)
{
destx -= step * std::cos(angle);
desty -= step * std::sin(angle);
- ground = GetMap()->GetHeight(GetPhaseMask(), destx, desty, MAX_HEIGHT, true);
- floor = GetMap()->GetHeight(GetPhaseMask(), destx, desty, pos.m_positionZ, true);
- destz = fabs(ground - pos.m_positionZ) <= fabs(floor - pos.m_positionZ) ? ground : floor;
+ destz = NormalizeZforCollision(this, destx, desty, pos.GetPositionZ());
}
// we have correct destz now
else
@@ -2667,7 +2687,7 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float
Trinity::NormalizeMapCoord(pos.m_positionX);
Trinity::NormalizeMapCoord(pos.m_positionY);
- UpdateAllowedPositionZ(pos.m_positionX, pos.m_positionY, pos.m_positionZ);
+ pos.m_positionZ = NormalizeZforCollision(this, destx, desty, pos.GetPositionZ());
pos.SetOrientation(GetOrientation());
}
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 0a5d265cbfa..abeeb394218 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -4586,7 +4586,7 @@ void Spell::EffectLeap(SpellEffIndex /*effIndex*/)
return;
Position pos = destTarget->GetPosition();
- pos = unitTarget->GetFirstCollisionPosition(unitTarget->GetDistance(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ() + 2.0f), 0.0f);
+ pos = unitTarget->GetFirstCollisionPosition(unitTarget->GetDistance(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()), 0.0f);
unitTarget->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), unitTarget == m_caster);
}