diff options
Diffstat (limited to 'src')
9 files changed, 44 insertions, 6 deletions
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 63244513846..a0b64f7ba09 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -1431,6 +1431,9 @@ void GameObject::Use(Unit* user) if (Player* playerUser = user->ToPlayer()) { + if (m_goInfo->CannotBeUsedUnderImmunity() && playerUser->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE)) + return; + if (!m_goInfo->IsUsableMounted()) playerUser->RemoveAurasByType(SPELL_AURA_MOUNTED); diff --git a/src/server/game/Entities/GameObject/GameObjectData.h b/src/server/game/Entities/GameObject/GameObjectData.h index ecb5ba8e684..eb92b7605ea 100644 --- a/src/server/game/Entities/GameObject/GameObjectData.h +++ b/src/server/game/Entities/GameObject/GameObjectData.h @@ -491,6 +491,21 @@ struct GameObjectTemplate } } + bool CannotBeUsedUnderImmunity() const // Cannot be used/activated/looted by players under immunity effects (example: Divine Shield) + { + switch (type) + { + case GAMEOBJECT_TYPE_DOOR: return door.noDamageImmune != 0; + case GAMEOBJECT_TYPE_BUTTON: return button.noDamageImmune != 0; + case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.noDamageImmune != 0; + case GAMEOBJECT_TYPE_CHEST: return true; // All chests cannot be opened while immune on 3.3.5a + case GAMEOBJECT_TYPE_GOOBER: return goober.noDamageImmune != 0; + case GAMEOBJECT_TYPE_FLAGSTAND: return flagstand.noDamageImmune != 0; + case GAMEOBJECT_TYPE_FLAGDROP: return flagdrop.noDamageImmune != 0; + default: return false; + } + } + uint32 GetCharges() const // despawn at uses amount { switch (type) diff --git a/src/server/game/Entities/Unit/UnitDefines.h b/src/server/game/Entities/Unit/UnitDefines.h index cbd934dcff1..731843bc82c 100644 --- a/src/server/game/Entities/Unit/UnitDefines.h +++ b/src/server/game/Entities/Unit/UnitDefines.h @@ -152,7 +152,7 @@ enum UnitFlags : uint32 UNIT_FLAG_UNK_28 = 0x10000000, UNIT_FLAG_UNK_29 = 0x20000000, // used in Feing Death spell UNIT_FLAG_SHEATHE = 0x40000000, - UNIT_FLAG_UNK_31 = 0x80000000, + UNIT_FLAG_IMMUNE = 0x80000000, // Immune to damage }; // Value masks for UNIT_FIELD_FLAGS_2 diff --git a/src/server/game/Entities/Unit/enuminfo_UnitDefines.cpp b/src/server/game/Entities/Unit/enuminfo_UnitDefines.cpp index f1a064ee105..e56cc94ac5c 100644 --- a/src/server/game/Entities/Unit/enuminfo_UnitDefines.cpp +++ b/src/server/game/Entities/Unit/enuminfo_UnitDefines.cpp @@ -64,7 +64,7 @@ TC_API_EXPORT EnumText EnumUtils<UnitFlags>::ToString(UnitFlags value) case UNIT_FLAG_UNK_28: return { "UNIT_FLAG_UNK_28", "UNIT_FLAG_UNK_28", "" }; case UNIT_FLAG_UNK_29: return { "UNIT_FLAG_UNK_29", "UNIT_FLAG_UNK_29", "used in Feing Death spell" }; case UNIT_FLAG_SHEATHE: return { "UNIT_FLAG_SHEATHE", "UNIT_FLAG_SHEATHE", "" }; - case UNIT_FLAG_UNK_31: return { "UNIT_FLAG_UNK_31", "UNIT_FLAG_UNK_31", "" }; + case UNIT_FLAG_IMMUNE: return { "UNIT_FLAG_IMMUNE", "UNIT_FLAG_IMMUNE", "is affected by a damage immunity aura" }; default: throw std::out_of_range("value"); } } @@ -108,7 +108,7 @@ TC_API_EXPORT UnitFlags EnumUtils<UnitFlags>::FromIndex(size_t index) case 28: return UNIT_FLAG_UNK_28; case 29: return UNIT_FLAG_UNK_29; case 30: return UNIT_FLAG_SHEATHE; - case 31: return UNIT_FLAG_UNK_31; + case 31: return UNIT_FLAG_IMMUNE; default: throw std::out_of_range("index"); } } diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index c05437350d6..2c71de6f3b0 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -3162,7 +3162,17 @@ void AuraEffect::HandleAuraModSchoolImmunity(AuraApplication const* aurApp, uint target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION); if (apply) + { + target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE); target->GetThreatManager().EvaluateSuppressed(); + } + else + { + // do not remove unit flag if there are more than this auraEffect of that kind on unit + if (target->HasAuraType(GetAuraType())) + return; + target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE); + } } void AuraEffect::HandleAuraModDmgImmunity(AuraApplication const* aurApp, uint8 mode, bool apply) const diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 3a4adeeec0b..6851f890ff0 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -5010,6 +5010,13 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint if (m_caster->ToUnit() && !m_caster->ToUnit()->IsAlive() && !m_spellInfo->IsPassive() && !(m_spellInfo->HasAttribute(SPELL_ATTR0_CASTABLE_WHILE_DEAD) || (IsTriggered() && !m_triggeredByAuraSpell))) return SPELL_FAILED_CASTER_DEAD; + // Prevent cheating in case the player has an immunity effect and tries to interact with a non-allowed gameobject. The error message is handled by the client so we don't report anything here + if (m_caster->ToPlayer() && m_targets.GetGOTarget()) + { + if (m_targets.GetGOTarget()->GetGOInfo()->CannotBeUsedUnderImmunity() && m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE)) + return SPELL_FAILED_DONT_REPORT; + } + // check cooldowns to prevent cheating if (!m_spellInfo->IsPassive()) { diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index ffa990f9191..978974359a1 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -1873,6 +1873,10 @@ void Spell::EffectOpenLock(SpellEffIndex effIndex) if (gameObjTarget) { GameObjectTemplate const* goInfo = gameObjTarget->GetGOInfo(); + + if (goInfo->CannotBeUsedUnderImmunity() && m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE)) + return; + // Arathi Basin banner opening. /// @todo Verify correctness of this check if ((goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune) || (goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK)) diff --git a/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp b/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp index 607d9c07447..1c2f7a3f0ce 100644 --- a/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp +++ b/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp @@ -314,13 +314,13 @@ class spell_ichoron_drained : public SpellScriptLoader void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - GetTarget()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_UNK_31); + GetTarget()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); GetTarget()->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH); } void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { - GetTarget()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_UNK_31); + GetTarget()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); GetTarget()->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH); if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE) diff --git a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp index cdd08f1e599..ca27f061b89 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp @@ -262,7 +262,6 @@ struct boss_ahune : public BossAI if (Creature* frozenCore = instance->GetCreature(DATA_FROZEN_CORE)) frozenCore->AI()->DoAction(ACTION_AHUNE_RETREAT); me->RemoveAurasDueToSpell(SPELL_AHUNES_SHIELD); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_31); DoCastSelf(SPELL_SUBMERGED, true); DoCastSelf(SPELL_AHUNE_SELF_STUN, true); DoCastSelf(SPELL_STAY_SUBMERGED, true); |