diff options
author | Trisjdc <trisjdc@gmail.com> | 2014-07-05 15:35:21 +0100 |
---|---|---|
committer | Trisjdc <trisjdc@gmail.com> | 2014-07-05 15:35:21 +0100 |
commit | dad9b01b265b9353424150eb9b268a735054238e (patch) | |
tree | c2018530a3413cf413a8aa923d273a35e06bf7ff | |
parent | a1fb24f5ed8f7b0d4abf1bcf02edec5e8afb4747 (diff) |
Core/Spells: Fix Blink/_DEST spell effects when cast inside/near water
-rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 48 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 2 |
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); } |