diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 5 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 1 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 44 |
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) |