aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp5
-rw-r--r--src/server/game/Entities/Unit/Unit.h1
-rw-r--r--src/server/game/Spells/Spell.cpp44
3 files changed, 46 insertions, 4 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index e2f7e32c46b..5338e65fb80 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -8845,8 +8845,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->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE)
- && ((target->GetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG) & UNIT_BYTE2_FLAG_SANCTUARY) || (GetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG) & UNIT_BYTE2_FLAG_SANCTUARY)))
+ if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && (target->IsInSanctuary() || IsInSanctuary()))
return false;
// additional checks - only PvP case
@@ -8944,7 +8943,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->GetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG) & UNIT_BYTE2_FLAG_PVP)
- if ((GetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG) & UNIT_BYTE2_FLAG_SANCTUARY) && !(target->GetByteValue(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG) & UNIT_BYTE2_FLAG_SANCTUARY))
+ if (IsInSanctuary() && !target->IsInSanctuary())
return false;
}
}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index a885147d06f..2f953c453e6 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1440,6 +1440,7 @@ class TC_GAME_API Unit : public WorldObject
bool IsInRaidWith(Unit const* unit) const;
void GetPartyMembers(std::list<Unit*> &units);
bool IsContestedGuard() const;
+ bool IsInSanctuary() const { return HasByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, UNIT_BYTE2_FLAG_SANCTUARY); }
bool IsPvP() const { return HasByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, UNIT_BYTE2_FLAG_PVP); }
bool IsFFAPvP() const { return HasByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, UNIT_BYTE2_FLAG_FFA_PVP); }
virtual void SetPvP(bool state);
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 2b3c764bfbd..4ea9982ae35 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -5149,6 +5149,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;
+ }
+ }
+
DispelChargesList dispelList;
target->GetDispellableAuraList(m_caster, dispelMask, dispelList);
if (dispelList.empty())
@@ -5511,8 +5523,31 @@ 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 = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
+ bool hasStealableAura = false;
+ Unit::VisibleAuraMap const* visibleAuras = m_targets.GetUnitTarget()->GetVisibleAuras();
+ for (Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
+ {
+ if (!itr->second->IsPositive())
+ continue;
+
+ Aura const* aura = itr->second->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:
@@ -5526,6 +5561,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:
// can't change during already started arena/battleground
if (m_caster->GetTypeId() == TYPEID_PLAYER)