fix(Core/Crash): safe calculation in GetMeleeAttackPoint (#4235)

Should solve: https://github.com/azerothcore/azerothcore-wotlk/issues/4225
This commit is contained in:
Yehonal
2021-01-08 16:55:51 +01:00
committed by GitHub
parent 37cb9f5242
commit aeab8d8bc6

View File

@@ -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);
}