1 parent
4305129672
commit
fa7026cee3
4 files changed
+63
-40
No files matched your search
@@ -5928,43 +5928,73 @@ SpellCastResult Spell::CheckRange(bool strict)
|
||||
if (!strict && m_casttime == 0)
|
||||
return SPELL_CAST_OK;
|
||||
|
||||
uint32 range_type = 0;
|
||||
|
||||
if (m_spellInfo->RangeEntry)
|
||||
Unit* target = m_targets.GetUnitTarget();
|
||||
float minRange = 0.0f;
|
||||
float maxRange = 0.0f;
|
||||
float rangeMod = 0.0f;
|
||||
if (strict && IsNextMeleeSwingSpell())
|
||||
maxRange = 100.0f;
|
||||
else if (m_spellInfo->RangeEntry)
|
||||
{
|
||||
// check needed by 68766 51693 - both spells are cast on enemies and have 0 max range
|
||||
// these are triggered by other spells - possibly we should omit range check in that case?
|
||||
if (m_spellInfo->RangeEntry->ID == 1)
|
||||
return SPELL_CAST_OK;
|
||||
if (m_spellInfo->RangeEntry->type & SPELL_RANGE_MELEE)
|
||||
{
|
||||
rangeMod = m_caster->GetCombatReach() + 4.0f / 3.0f;
|
||||
if (target)
|
||||
rangeMod += target->GetCombatReach();
|
||||
else
|
||||
rangeMod += m_caster->GetCombatReach();
|
||||
|
||||
range_type = m_spellInfo->RangeEntry->type;
|
||||
rangeMod = std::max(rangeMod, NOMINAL_MELEE_RANGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
float meleeRange = 0.0f;
|
||||
if (m_spellInfo->RangeEntry->type & SPELL_RANGE_RANGED)
|
||||
{
|
||||
meleeRange = m_caster->GetCombatReach() + 4.0f / 3.0f;
|
||||
if (target)
|
||||
meleeRange += target->GetCombatReach();
|
||||
else
|
||||
meleeRange += m_caster->GetCombatReach();
|
||||
|
||||
meleeRange = std::max(meleeRange, NOMINAL_MELEE_RANGE);
|
||||
}
|
||||
|
||||
minRange = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo) + meleeRange;
|
||||
maxRange = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo);
|
||||
|
||||
if (target || m_targets.GetCorpseTarget())
|
||||
{
|
||||
rangeMod = m_caster->GetCombatReach();
|
||||
if (target)
|
||||
rangeMod += target->GetCombatReach();
|
||||
|
||||
if (minRange > 0.0f && !(m_spellInfo->RangeEntry->type & SPELL_RANGE_RANGED))
|
||||
minRange += rangeMod;
|
||||
}
|
||||
}
|
||||
|
||||
if (target && m_caster->isMoving() && target->isMoving() && !m_caster->IsWalking() && !target->IsWalking() &&
|
||||
(m_spellInfo->RangeEntry->type & SPELL_RANGE_MELEE || target->GetTypeId() == TYPEID_PLAYER))
|
||||
rangeMod += 5.0f / 3.0f;
|
||||
}
|
||||
|
||||
Unit* target = m_targets.GetUnitTarget();
|
||||
float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo);
|
||||
float min_range = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo);
|
||||
if (m_spellInfo->HasAttribute(SPELL_ATTR0_REQ_AMMO) && m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
if (Item* ranged = m_caster->ToPlayer()->GetWeaponForAttack(RANGED_ATTACK, true))
|
||||
maxRange *= ranged->GetTemplate()->RangedModRange * 0.01f;
|
||||
|
||||
if (Player* modOwner = m_caster->GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
|
||||
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, maxRange, this);
|
||||
|
||||
maxRange += rangeMod;
|
||||
|
||||
if (target && target != m_caster)
|
||||
{
|
||||
if (range_type == SPELL_RANGE_MELEE)
|
||||
{
|
||||
// Because of lag, we can not check too strictly here.
|
||||
if (!m_caster->IsWithinMeleeRange(target, max_range))
|
||||
return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_OUT_OF_RANGE : SPELL_FAILED_DONT_REPORT;
|
||||
}
|
||||
else if (!m_caster->IsWithinCombatRange(target, max_range))
|
||||
return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_OUT_OF_RANGE : SPELL_FAILED_DONT_REPORT; //0x5A;
|
||||
if (!m_caster->IsInDist(target, maxRange))
|
||||
return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_OUT_OF_RANGE : SPELL_FAILED_DONT_REPORT;
|
||||
|
||||
if (range_type == SPELL_RANGE_RANGED)
|
||||
{
|
||||
if (m_caster->IsWithinMeleeRange(target))
|
||||
return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_TOO_CLOSE : SPELL_FAILED_DONT_REPORT;
|
||||
}
|
||||
else if (min_range && m_caster->IsWithinCombatRange(target, min_range)) // skip this check if min_range = 0
|
||||
return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_TOO_CLOSE : SPELL_FAILED_DONT_REPORT;
|
||||
if (minRange > 0.0f && m_caster->IsInDist(target, minRange))
|
||||
return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_OUT_OF_RANGE : SPELL_FAILED_DONT_REPORT;
|
||||
|
||||
if (m_caster->GetTypeId() == TYPEID_PLAYER &&
|
||||
(m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(static_cast<float>(M_PI), target))
|
||||
@@ -5973,10 +6003,10 @@ SpellCastResult Spell::CheckRange(bool strict)
|
||||
|
||||
if (m_targets.HasDst() && !m_targets.HasTraj())
|
||||
{
|
||||
if (!m_caster->IsWithinDist3d(m_targets.GetDstPos(), max_range))
|
||||
return SPELL_FAILED_OUT_OF_RANGE;
|
||||
if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
|
||||
return SPELL_FAILED_TOO_CLOSE;
|
||||
if (!m_caster->IsInDist(m_targets.GetDstPos(), maxRange))
|
||||
return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_OUT_OF_RANGE : SPELL_FAILED_DONT_REPORT;
|
||||
if (minRange > 0.0f && m_caster->IsInDist(m_targets.GetDstPos(), minRange))
|
||||
return !(_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_OUT_OF_RANGE : SPELL_FAILED_DONT_REPORT;
|
||||
}
|
||||
|
||||
return SPELL_CAST_OK;
|
||||
|
||||
Reference in new issue
Block a user