diff --git a/Source/Framework/Constants/CreatureConst.cs b/Source/Framework/Constants/CreatureConst.cs
index 827eb93da..52a41854d 100644
--- a/Source/Framework/Constants/CreatureConst.cs
+++ b/Source/Framework/Constants/CreatureConst.cs
@@ -79,7 +79,7 @@ namespace Framework.Constants
Unk28 = 0x10000000,
Unk29 = 0x20000000,
Sheathe = 0x40000000,
- Unk31 = 0x80000000
+ Immune = 0x80000000
}
public enum UnitFlags2 : uint
diff --git a/Source/Game/Entities/GameObject/GameObject.cs b/Source/Game/Entities/GameObject/GameObject.cs
index 6e5cf9e8c..07eb67b57 100644
--- a/Source/Game/Entities/GameObject/GameObject.cs
+++ b/Source/Game/Entities/GameObject/GameObject.cs
@@ -1448,6 +1448,9 @@ namespace Game.Entities
Player playerUser = user.ToPlayer();
if (playerUser != null)
{
+ if (m_goInfo.GetNoDamageImmune() != 0 && playerUser.HasUnitFlag(UnitFlags.Immune))
+ return;
+
if (!m_goInfo.IsUsableMounted())
playerUser.RemoveAurasByType(AuraType.Mounted);
diff --git a/Source/Game/Entities/GameObject/GameObjectData.cs b/Source/Game/Entities/GameObject/GameObjectData.cs
index bb6918116..30550f846 100644
--- a/Source/Game/Entities/GameObject/GameObjectData.cs
+++ b/Source/Game/Entities/GameObject/GameObjectData.cs
@@ -352,7 +352,37 @@ namespace Game.Entities
}
}
- // despawn at uses amount
+ ///
+ /// Cannot be used/activated/looted by players under immunity effects (example: Divine Shield)
+ ///
+ ///
+ public uint GetNoDamageImmune()
+ {
+ switch (type)
+ {
+ case GameObjectTypes.Door:
+ return Door.noDamageImmune;
+ case GameObjectTypes.Button:
+ return Button.noDamageImmune;
+ case GameObjectTypes.QuestGiver:
+ return QuestGiver.noDamageImmune;
+ case GameObjectTypes.Chest:
+ return 1;
+ case GameObjectTypes.Goober:
+ return Goober.noDamageImmune;
+ case GameObjectTypes.FlagStand:
+ return FlagStand.noDamageImmune;
+ case GameObjectTypes.FlagDrop:
+ return FlagDrop.noDamageImmune;
+ default:
+ return 0;
+ }
+ }
+
+ ///
+ /// despawn at uses amount
+ ///
+ ///
public uint GetCharges()
{
switch (type)
diff --git a/Source/Game/Spells/Auras/AuraEffect.cs b/Source/Game/Spells/Auras/AuraEffect.cs
index 02a6764ec..22bdd65bc 100644
--- a/Source/Game/Spells/Auras/AuraEffect.cs
+++ b/Source/Game/Spells/Auras/AuraEffect.cs
@@ -2799,7 +2799,18 @@ namespace Game.Spells
}
if (apply)
+ {
+ target.AddUnitFlag(UnitFlags.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.RemoveUnitFlag(UnitFlags.Immune);
+ }
}
[AuraEffectHandler(AuraType.DamageImmunity)]
diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs
index 162eee1e7..a7dd199a0 100644
--- a/Source/Game/Spells/Spell.cs
+++ b/Source/Game/Spells/Spell.cs
@@ -4365,6 +4365,13 @@ namespace Game.Spells
if (m_caster.ToUnit() && !m_caster.ToUnit().IsAlive() && !m_spellInfo.IsPassive() && !(m_spellInfo.HasAttribute(SpellAttr0.CastableWhileDead) || (IsTriggered() && m_triggeredByAuraSpell == null)))
return SpellCastResult.CasterDead;
+ // 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.IsPlayer() && m_targets.GetGOTarget() != null)
+ {
+ if (m_targets.GetGOTarget().GetGoInfo().GetNoDamageImmune() != 0 && m_caster.ToUnit().HasUnitFlag(UnitFlags.Immune))
+ return SpellCastResult.DontReport;
+ }
+
// check cooldowns to prevent cheating
if (!m_spellInfo.IsPassive())
{
diff --git a/Source/Game/Spells/SpellEffects.cs b/Source/Game/Spells/SpellEffects.cs
index b9a347709..a3c83e829 100644
--- a/Source/Game/Spells/SpellEffects.cs
+++ b/Source/Game/Spells/SpellEffects.cs
@@ -1324,6 +1324,10 @@ namespace Game.Spells
if (gameObjTarget != null)
{
GameObjectTemplate goInfo = gameObjTarget.GetGoInfo();
+
+ if (goInfo.GetNoDamageImmune() != 0 && player.HasUnitFlag(UnitFlags.Immune))
+ return;
+
// Arathi Basin banner opening. // @todo Verify correctness of this check
if ((goInfo.type == GameObjectTypes.Button && goInfo.Button.noDamageImmune != 0) ||
(goInfo.type == GameObjectTypes.Goober && goInfo.Goober.requireLOS != 0))