Core/Misc: don't allow players to use/activate/loot non-allowed gameobjects while under the effect of a damage immunity aura (#23319)
* Core/Misc: don't allow players to use/activate/loot non-allowed gameobjects while under the effect of a damage immunity aura. * Forgot to change this in last-second rename. * Apply suggested changes, thanks Shauren! # Conflicts: # src/server/game/Entities/GameObject/GameObject.cpp # src/server/game/Entities/Unit/UnitDefines.h # src/server/game/Entities/Unit/enuminfo_UnitDefines.cpp # src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_ahune.cpp
This commit is contained in:
1 parent
1fd66b4621
commit
d2b27bc43c
8 files changed
+45
-4
No files matched your search
@@ -1428,6 +1428,12 @@ 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);
|
||||
|
||||
playerUser->PlayerTalkClass->ClearMenus();
|
||||
if (AI()->GossipHello(playerUser))
|
||||
return;
|
||||
|
||||
@@ -486,6 +486,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)
|
||||
|
||||
@@ -151,7 +151,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
|
||||
MAX_UNIT_FLAGS = 33
|
||||
};
|
||||
|
||||
|
||||
@@ -3269,7 +3269,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
|
||||
|
||||
@@ -5402,6 +5402,13 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint
|
||||
if (!m_caster->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())
|
||||
{
|
||||
|
||||
@@ -1600,6 +1600,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))
|
||||
|
||||
@@ -312,13 +312,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().HasFlag(AuraRemoveFlags::Expired))
|
||||
|
||||
@@ -277,7 +277,6 @@ public:
|
||||
if (Creature* frozenCore = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_FROZEN_CORE)))
|
||||
frozenCore->AI()->DoAction(ACTION_AHUNE_RETREAT);
|
||||
me->RemoveAurasDueToSpell(SPELL_AHUNES_SHIELD);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_31);
|
||||
DoCast(me, SPELL_SUBMERGED, true);
|
||||
DoCast(me, SPELL_AHUNE_SELF_STUN, true);
|
||||
DoCast(me, SPELL_STAY_SUBMERGED, true);
|
||||
|
||||
Reference in new issue
Block a user