Core/Spells: Added SPELL_FAILED_NOTHING_TO_STEAL error (#19036)
Corrected Dispel check in sanctuary area Added root check for SPELL_EFFECT_JUMP and SPELL_EFFECT_JUMP_DEST (cherrypicked from 3c605ba614c45c4b8f99c12fb49f342c068054a5)
This commit is contained in:
@@ -7977,8 +7977,7 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo
|
||||
|
||||
// PvP case - can't attack when attacker or target are in sanctuary
|
||||
// however, 13850 client doesn't allow to attack when one of the unit's has sanctuary flag and is pvp
|
||||
if (target->HasUnitFlag(UNIT_FLAG_PVP_ATTACKABLE) && HasUnitFlag(UNIT_FLAG_PVP_ATTACKABLE)
|
||||
&& ((target->HasPvpFlag(UNIT_BYTE2_FLAG_SANCTUARY)) || (HasPvpFlag(UNIT_BYTE2_FLAG_SANCTUARY))))
|
||||
if (target->HasUnitFlag(UNIT_FLAG_PVP_ATTACKABLE) && HasUnitFlag(UNIT_FLAG_PVP_ATTACKABLE) && (target->IsInSanctuary() || IsInSanctuary()))
|
||||
return false;
|
||||
|
||||
// additional checks - only PvP case
|
||||
@@ -8076,7 +8075,7 @@ bool Unit::_IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) co
|
||||
return false;
|
||||
// can't assist player out of sanctuary from sanctuary if has pvp enabled
|
||||
if (target->HasPvpFlag(UNIT_BYTE2_FLAG_PVP))
|
||||
if (HasPvpFlag(UNIT_BYTE2_FLAG_SANCTUARY) && !target->HasPvpFlag(UNIT_BYTE2_FLAG_SANCTUARY))
|
||||
if (IsInSanctuary() && !target->IsInSanctuary())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1153,6 +1153,7 @@ class TC_GAME_API Unit : public WorldObject
|
||||
void AddPvpFlag(UnitPVPStateFlags flags) { SetUpdateFieldFlagValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::PvpFlags), flags); }
|
||||
void RemovePvpFlag(UnitPVPStateFlags flags) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::PvpFlags), flags); }
|
||||
void SetPvpFlags(UnitPVPStateFlags flags) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::PvpFlags), flags); }
|
||||
bool IsInSanctuary() const { return HasPvpFlag(UNIT_BYTE2_FLAG_SANCTUARY); }
|
||||
bool IsPvP() const { return HasPvpFlag(UNIT_BYTE2_FLAG_PVP); }
|
||||
bool IsFFAPvP() const { return HasPvpFlag(UNIT_BYTE2_FLAG_FFA_PVP); }
|
||||
virtual void SetPvP(bool state);
|
||||
|
||||
@@ -4970,6 +4970,18 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
|
||||
|
||||
if (Unit* target = m_targets.GetUnitTarget())
|
||||
{
|
||||
// do not allow to cast on hostile targets in sanctuary
|
||||
if (!m_caster->IsFriendlyTo(target))
|
||||
{
|
||||
if (m_caster->IsInSanctuary() || target->IsInSanctuary())
|
||||
{
|
||||
// fix for duels
|
||||
Player* player = m_caster->ToPlayer();
|
||||
if (!player || !player->duel || target != player->duel->opponent)
|
||||
return SPELL_FAILED_NOTHING_TO_DISPEL;
|
||||
}
|
||||
}
|
||||
|
||||
SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, m_caster->GetEntry() == WORLD_TRIGGER); // skip stealth checks for GO casts
|
||||
if (castResult != SPELL_CAST_OK)
|
||||
return castResult;
|
||||
@@ -5532,8 +5544,30 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
|
||||
}
|
||||
case SPELL_EFFECT_STEAL_BENEFICIAL_BUFF:
|
||||
{
|
||||
if (m_targets.GetUnitTarget() == m_caster)
|
||||
if (!m_targets.GetUnitTarget() || m_targets.GetUnitTarget() == m_caster)
|
||||
return SPELL_FAILED_BAD_TARGETS;
|
||||
|
||||
uint32 dispelMask = m_spellInfo->GetDispelMask(DispelType(effect->MiscValue));
|
||||
bool hasStealableAura = false;
|
||||
for (AuraApplication* visibleAura : m_targets.GetUnitTarget()->GetVisibleAuras())
|
||||
{
|
||||
if (!visibleAura->IsPositive())
|
||||
continue;
|
||||
|
||||
Aura const* aura = visibleAura->GetBase();
|
||||
if (!(aura->GetSpellInfo()->GetDispelMask() & dispelMask))
|
||||
continue;
|
||||
|
||||
if (aura->IsPassive() || aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_NOT_STEALABLE))
|
||||
continue;
|
||||
|
||||
hasStealableAura = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!hasStealableAura)
|
||||
return SPELL_FAILED_NOTHING_TO_STEAL;
|
||||
|
||||
break;
|
||||
}
|
||||
case SPELL_EFFECT_LEAP_BACK:
|
||||
@@ -5547,6 +5581,13 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPELL_EFFECT_JUMP:
|
||||
case SPELL_EFFECT_JUMP_DEST:
|
||||
{
|
||||
if (m_caster->HasUnitState(UNIT_STATE_ROOT))
|
||||
return SPELL_FAILED_ROOTED;
|
||||
break;
|
||||
}
|
||||
case SPELL_EFFECT_TALENT_SPEC_SELECT:
|
||||
{
|
||||
ChrSpecializationEntry const* spec = sChrSpecializationStore.LookupEntry(m_misc.SpecializationId);
|
||||
|
||||
Reference in New Issue
Block a user