diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 7e596fcec..cfad1cc5f 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -2284,6 +2284,7 @@ Position* Unit::GetMeleeAttackPoint(Unit* attacker) } double ray = attackerSize > refUnit->GetObjectSize() ? attackerSize / 2.0f : refUnit->GetObjectSize() / 2.0f; + double angle = 0; // Equation of tangent point to get the ideal angle to // move away from collisions with another unit during combat @@ -2301,11 +2302,6 @@ Position* Unit::GetMeleeAttackPoint(Unit* attacker) double b = 8.0f * ( (refUnitX * refUnitY) + (victimX * victimY) - (victimX * refUnitY) - (refUnitX * victimY) ); double c = 4.0f * (- pow(victimY,2.0f) - pow(refUnitY,2.0f) + (2.0f*victimY*refUnitY) + pow(ray,2.0f)); - if (a == 0) // should not happen - { - return nullptr; - } - double sq = sqrt(pow(b,2.0f)-4.0f*a*c); double m1 = (-b + sq) / (2.0f*a); @@ -2323,18 +2319,25 @@ Position* Unit::GetMeleeAttackPoint(Unit* attacker) double ortDist = sqrt(pow(exactDist,2.0f) - pow(distance/2.0f,2.0f)); - double angle = frand(0.1f,0.3f) + currentAngle + 2.0f * atan(distance / (2.0f * ortDist)) * (urand(0, 1) ? -1 : 1); - - float x, y, z; - GetNearPoint(attacker, x, y, z, attackerSize, 0.0f, angle); - - return new Position(x,y,z); + angle = 2.0f * atan(distance / (2.0f * ortDist)); } - float angle = frand(0.1f,0.3f) + currentAngle + atan(attackerSize / (meleeReach)) * (urand(0, 1) ? -1 : 1); + int8 direction = (urand(0, 1) ? -1 : 1); + angle = frand(0.1f,0.3f) + (angle && !isnan(angle) ? angle : atan(attackerSize / (meleeReach))); // or fallback to the simpler method + float x, y, z; - GetNearPoint(attacker, x, y, z, attackerSize, 0.0f, angle); + GetNearPoint(attacker, x, y, z, attackerSize, 0.0f, currentAngle + angle * direction); + + if (!GetMap()->CanReachPositionAndGetCoords(this, x, y, z)) + { + GetNearPoint(attacker, x, y, z, attackerSize, 0.0f, currentAngle + angle * (direction * -1)); // try the other side + + if (!GetMap()->CanReachPositionAndGetCoords(this, x, y, z)) + { + return nullptr; + } + } return new Position(x,y,z); }