diff options
author | megamage <none@none> | 2009-08-24 18:36:00 -0500 |
---|---|---|
committer | megamage <none@none> | 2009-08-24 18:36:00 -0500 |
commit | 3675c397435d32e07250c942ec6d402731b6b7e0 (patch) | |
tree | bf7e6362114b76dfe85d2b75113911a6db971506 /src | |
parent | bb8a9d4c3d33bc50f036da931c0f5d626d742af5 (diff) |
*Fix the wrong calculation in spell target selection.
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/game/Spell.cpp | 74 | ||||
-rw-r--r-- | src/game/Unit.cpp | 2 |
2 files changed, 47 insertions, 29 deletions
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index ff96db642a8..8752bf41b41 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -6573,12 +6573,27 @@ void Spell::SetSpellValue(SpellValueMod mod, int32 value) } } +float tangent(float x) +{ + x = tan(x); + //if(x < std::numeric_limits<float>::max() && x > -std::numeric_limits<float>::max()) return x; + //if(x >= std::numeric_limits<float>::max()) return std::numeric_limits<float>::max(); + //if(x <= -std::numeric_limits<float>::max()) return -std::numeric_limits<float>::max(); + if(x < 100000.0f && x > -100000.0f) return x; + if(x >= 100000.0f) return 100000.0f; + if(x <= 100000.0f) return -100000.0f; + return 0.0f; +} + void Spell::SelectTrajTargets() { if(!m_targets.HasTraj()) return; float dist2d = m_targets.GetDist2d(); + if(!dist2d) + return; + float dz = m_targets.m_destZ - m_targets.m_srcZ; UnitList unitList; @@ -6588,13 +6603,10 @@ void Spell::SelectTrajTargets() unitList.sort(TargetDistanceOrder(m_caster)); - float sinE = sin(m_targets.m_elevation); - float dcosE = 2 * cos(m_targets.m_elevation); - float divisor = dist2d * (dist2d - dcosE); - if(abs(divisor) < 0.0001f) divisor = 0.0001f; - float a = (dz - dist2d * sinE) / divisor; - float b = sinE - dcosE * a; - if(a > -0.0001f) a = -0.0001f; + float b = tangent(m_targets.m_elevation); + float a = (dz - dist2d * b) / (dist2d * dist2d); + if(a > -0.0001f) a = 0; + //sLog.outError("Spell::SelectTrajTargets: a %f b %f", a, b); float bestDist; UnitList::const_iterator itr = unitList.begin(); @@ -6603,29 +6615,47 @@ void Spell::SelectTrajTargets() if(m_caster == *itr || m_caster->IsOnVehicle(*itr) || (*itr)->IsOnVehicle(m_caster)) continue; - const float size = (*itr)->GetObjectSize() * 0.6f; // 1/sqrt(3) + const float size = std::max((*itr)->GetObjectSize() * 0.7f, 1.0f); // 1/sqrt(3) const float objDist2d = m_caster->GetExactDistance2d((*itr)->GetPositionX(), (*itr)->GetPositionY()) * cos(m_caster->GetRelativeAngle(*itr)); const float dz = (*itr)->GetPositionZ() - m_caster->GetPositionZ(); + //sLog.outError("Spell::SelectTrajTargets: check %u, dist between %f %f, height between %f %f.", (*itr)->GetEntry(), objDist2d - size, objDist2d + size, dz - size, dz + size); + float dist = objDist2d - size; float height = dist * (a * dist + b); + //sLog.outError("Spell::SelectTrajTargets: dist %f, height %f.", dist, height); if(height < dz + size && height > dz - size) { bestDist = dist > 0 ? dist : 0; break; } +#define CHECK_DIST {\ + //sLog.outError("Spell::SelectTrajTargets: dist %f, height %f.", dist, height); + if(dist < objDist2d + size && dist > objDist2d - size)\ + { bestDist = dist; break; }\ + } + + if(!a) + { + height = dz - size; + dist = height / b; + CHECK_DIST; + + height = dz + size; + dist = height / b; + CHECK_DIST; + + continue; + } + height = dz - size; float sqrt1 = b * b + 4 * a * height; if(sqrt1 > 0) { sqrt1 = sqrt(sqrt1); dist = (sqrt1 - b) / (2 * a); - if(dist < objDist2d + size && dist > objDist2d - size) - { - bestDist = dist; - break; - } + CHECK_DIST; } height = dz + size; @@ -6634,28 +6664,16 @@ void Spell::SelectTrajTargets() { sqrt2 = sqrt(sqrt2); dist = (sqrt2 - b) / (2 * a); - if(dist < objDist2d + size && dist > objDist2d - size) - { - bestDist = dist; - break; - } + CHECK_DIST; dist = (-sqrt2 - b) / (2 * a); - if(dist < objDist2d + size && dist > objDist2d - size) - { - bestDist = dist; - break; - } + CHECK_DIST; } if(sqrt1 > 0) { dist = (-sqrt1 - b) / (2 * a); - if(dist < objDist2d + size && dist > objDist2d - size) - { - bestDist = dist; - break; - } + CHECK_DIST; } } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 2766d31d6bc..6c47b56900e 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -3476,7 +3476,7 @@ bool Unit::isInBackInMap(Unit const* target, float distance, float arc) const bool Unit::isInLine(Unit const* target, float distance, float width) const { if(!HasInArc(M_PI, target) || !IsWithinDistInMap(target, distance)) return false; - width += target->GetObjectSize() * 0.5f; + width += target->GetObjectSize(); float angle = GetRelativeAngle(target); return abs(sin(angle)) * GetExactDistance2d(target->GetPositionX(), target->GetPositionY()) < width; } |