mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-17 10:55:43 +00:00
fix(Core/Vmaps): Stop M2s from occluding for spellcast LoS. Original autho… (#11341)
* Core/Vmaps: Stop M2s from occluding for spellcast LoS. Original authors: @Shauren & @HelloKitty Fixes #11293 * buildfix. Co-Authored-By: HelloKitty <5829095+HelloKitty@users.noreply.github.com>
This commit is contained in:
@@ -2049,7 +2049,7 @@ void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTar
|
||||
if (Unit* unit = (*itr)->ToUnit())
|
||||
{
|
||||
uint32 deficit = unit->GetMaxHealth() - unit->GetHealth();
|
||||
if ((deficit > maxHPDeficit || foundItr == tempTargets.end()) && target->IsWithinDist(unit, jumpRadius) && target->IsWithinLOSInMap(unit, LINEOFSIGHT_ALL_CHECKS))
|
||||
if ((deficit > maxHPDeficit || foundItr == tempTargets.end()) && target->IsWithinDist(unit, jumpRadius) && target->IsWithinLOSInMap(unit, VMAP::ModelIgnoreFlags::M2))
|
||||
{
|
||||
foundItr = itr;
|
||||
maxHPDeficit = deficit;
|
||||
@@ -2064,10 +2064,10 @@ void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTar
|
||||
{
|
||||
if (foundItr == tempTargets.end())
|
||||
{
|
||||
if ((!isBouncingFar || target->IsWithinDist(*itr, jumpRadius)) && target->IsWithinLOSInMap(*itr, LINEOFSIGHT_ALL_CHECKS))
|
||||
if ((!isBouncingFar || target->IsWithinDist(*itr, jumpRadius)) && target->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
|
||||
foundItr = itr;
|
||||
}
|
||||
else if (target->GetDistanceOrder(*itr, *foundItr) && target->IsWithinLOSInMap(*itr, LINEOFSIGHT_ALL_CHECKS))
|
||||
else if (target->GetDistanceOrder(*itr, *foundItr) && target->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
|
||||
foundItr = itr;
|
||||
}
|
||||
}
|
||||
@@ -5617,9 +5617,38 @@ SpellCastResult Spell::CheckCast(bool strict)
|
||||
if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
|
||||
return SPELL_FAILED_NOT_INFRONT;
|
||||
|
||||
if (m_caster->GetEntry() != WORLD_TRIGGER) // Ignore LOS for gameobjects casts (wrongly casted by a trigger)
|
||||
if ((!m_caster->IsTotem() || !m_spellInfo->IsPositive()) && !m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) && !m_spellInfo->HasAttribute(SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT) && !m_caster->IsWithinLOSInMap(target, LINEOFSIGHT_ALL_CHECKS) && !(m_spellFlags & SPELL_FLAG_REDIRECTED))
|
||||
if ((!m_caster->IsTotem() || !m_spellInfo->IsPositive()) && !m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) &&
|
||||
!m_spellInfo->HasAttribute(SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT) && !(m_spellFlags & SPELL_FLAG_REDIRECTED))
|
||||
{
|
||||
WorldObject* losCenter = nullptr;
|
||||
uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
|
||||
if (m_originalCasterGUID.IsGameObject())
|
||||
{
|
||||
losCenter = m_caster->GetMap()->GetGameObject(m_originalCasterGUID);
|
||||
}
|
||||
else if (m_caster->GetEntry() == WORLD_TRIGGER)
|
||||
{
|
||||
if (TempSummon* tempSummon = m_caster->ToTempSummon())
|
||||
{
|
||||
losCenter = tempSummon->GetSummonerGameObject();
|
||||
}
|
||||
}
|
||||
|
||||
if (losCenter)
|
||||
{
|
||||
// If spell casted by gameobject then ignore M2 models
|
||||
losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
|
||||
}
|
||||
else
|
||||
{
|
||||
losCenter = m_caster;
|
||||
}
|
||||
|
||||
if (!losCenter->IsWithinLOSInMap(target, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks(losChecks)))
|
||||
{
|
||||
return SPELL_FAILED_LINE_OF_SIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5629,8 +5658,38 @@ SpellCastResult Spell::CheckCast(bool strict)
|
||||
float x, y, z;
|
||||
m_targets.GetDstPos()->GetPosition(x, y, z);
|
||||
|
||||
if ((!m_caster->IsTotem() || !m_spellInfo->IsPositive()) && !m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) && !m_spellInfo->HasAttribute(SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT) && !m_caster->IsWithinLOS(x, y, z, LINEOFSIGHT_ALL_CHECKS))
|
||||
return SPELL_FAILED_LINE_OF_SIGHT;
|
||||
if ((!m_caster->IsTotem() || !m_spellInfo->IsPositive()) && !m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) &&
|
||||
!m_spellInfo->HasAttribute(SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT))
|
||||
{
|
||||
WorldObject* losCenter = nullptr;
|
||||
uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
|
||||
if (m_originalCasterGUID.IsGameObject())
|
||||
{
|
||||
losCenter = m_caster->GetMap()->GetGameObject(m_originalCasterGUID);
|
||||
}
|
||||
else if (m_caster->GetEntry() == WORLD_TRIGGER)
|
||||
{
|
||||
if (TempSummon* tempSummon = m_caster->ToTempSummon())
|
||||
{
|
||||
losCenter = tempSummon->GetSummonerGameObject();
|
||||
}
|
||||
}
|
||||
|
||||
if (losCenter)
|
||||
{
|
||||
// If spell casted by gameobject then ignore M2 models
|
||||
losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
|
||||
}
|
||||
else
|
||||
{
|
||||
losCenter = m_caster;
|
||||
}
|
||||
|
||||
if (!losCenter->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks((losChecks))))
|
||||
{
|
||||
return SPELL_FAILED_LINE_OF_SIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check pet presence
|
||||
@@ -7626,7 +7685,7 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff) const
|
||||
{
|
||||
case SPELL_EFFECT_RESURRECT_NEW:
|
||||
// player far away, maybe his corpse near?
|
||||
if (target != m_caster && !target->IsWithinLOSInMap(m_caster, LINEOFSIGHT_ALL_CHECKS))
|
||||
if (target != m_caster && !target->IsWithinLOSInMap(m_caster))
|
||||
{
|
||||
if (!m_targets.GetCorpseTargetGUID())
|
||||
return false;
|
||||
@@ -7638,7 +7697,7 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff) const
|
||||
if (target->GetGUID() != corpse->GetOwnerGUID())
|
||||
return false;
|
||||
|
||||
if (!corpse->IsWithinLOSInMap(m_caster, LINEOFSIGHT_ALL_CHECKS) && !(m_spellFlags & SPELL_FLAG_REDIRECTED))
|
||||
if (!corpse->IsWithinLOSInMap(m_caster) && !(m_spellFlags & SPELL_FLAG_REDIRECTED))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@@ -7646,7 +7705,7 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff) const
|
||||
{
|
||||
if (!m_targets.GetCorpseTargetGUID())
|
||||
{
|
||||
if (target->IsWithinLOSInMap(m_caster, LINEOFSIGHT_ALL_CHECKS) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE))
|
||||
if (target->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -7662,7 +7721,7 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff) const
|
||||
if (!corpse->HasFlag(CORPSE_FIELD_FLAGS, CORPSE_FLAG_LOOTABLE))
|
||||
return false;
|
||||
|
||||
if (!corpse->IsWithinLOSInMap(m_caster, LINEOFSIGHT_ALL_CHECKS))
|
||||
if (!corpse->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@@ -7676,14 +7735,40 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff) const
|
||||
if (target->ToPlayer()->getLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
|
||||
return false;
|
||||
break;
|
||||
|
||||
default: // normal case
|
||||
// Get GO cast coordinates if original caster -> GO
|
||||
WorldObject* caster = nullptr;
|
||||
default: // normal case
|
||||
{
|
||||
uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
|
||||
GameObject* gobCaster = nullptr;
|
||||
if (m_originalCasterGUID.IsGameObject())
|
||||
caster = m_caster->GetMap()->GetGameObject(m_originalCasterGUID);
|
||||
if (!caster)
|
||||
{
|
||||
gobCaster = m_caster->GetMap()->GetGameObject(m_originalCasterGUID);
|
||||
}
|
||||
else if (m_caster->GetEntry() == WORLD_TRIGGER)
|
||||
{
|
||||
if (TempSummon* tempSummon = m_caster->ToTempSummon())
|
||||
{
|
||||
gobCaster = tempSummon->GetSummonerGameObject();
|
||||
}
|
||||
}
|
||||
|
||||
WorldObject* caster = nullptr;
|
||||
if (gobCaster)
|
||||
{
|
||||
if (gobCaster->GetGOInfo()->IsIgnoringLOSChecks())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
caster = gobCaster;
|
||||
|
||||
// If spell casted by gameobject then ignore M2 models
|
||||
losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
|
||||
}
|
||||
else
|
||||
{
|
||||
caster = m_caster;
|
||||
}
|
||||
|
||||
if (target != m_caster)
|
||||
{
|
||||
if (m_targets.HasDst())
|
||||
@@ -7692,13 +7777,18 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff) const
|
||||
float y = m_targets.GetDstPos()->GetPositionY();
|
||||
float z = m_targets.GetDstPos()->GetPositionZ();
|
||||
|
||||
if (!target->IsWithinLOS(x, y, z, LINEOFSIGHT_ALL_CHECKS))
|
||||
if (!target->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks(losChecks)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!target->IsWithinLOSInMap(caster, LINEOFSIGHT_ALL_CHECKS))
|
||||
else if (!target->IsWithinLOSInMap(caster, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks(losChecks)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user