aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2017-12-17 16:45:50 +0100
committerShauren <shauren.trinity@gmail.com>2017-12-17 16:45:50 +0100
commite86a2c439aa2a032ce338d974dae1e5311bcb18f (patch)
treef48cc15721978fdd2722f266a5884e0c0202e657
parente573607ccd01e3e4ae2142f8ef56cce66b173b8a (diff)
Core/Auras: Implemented using all aura interrupt flag fields
-rw-r--r--src/server/game/AI/CoreAI/UnitAI.cpp3
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp1
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp1
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp1
-rw-r--r--src/server/game/DataStores/DB2Structure.h4
-rw-r--r--src/server/game/DataStores/DBCEnums.h2
-rw-r--r--src/server/game/Entities/Player/Player.cpp2
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp57
-rw-r--r--src/server/game/Entities/Unit/Unit.h65
-rw-r--r--src/server/game/Handlers/MovementHandler.cpp22
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp2
-rw-r--r--src/server/game/Spells/Spell.cpp2
-rw-r--r--src/server/game/Spells/SpellEffects.cpp2
-rw-r--r--src/server/game/Spells/SpellInfo.cpp19
-rw-r--r--src/server/game/Spells/SpellInfo.h109
-rw-r--r--src/server/game/Spells/SpellMgr.cpp8
16 files changed, 174 insertions, 126 deletions
diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp
index fc0a0c117f7..a4ee3025130 100644
--- a/src/server/game/AI/CoreAI/UnitAI.cpp
+++ b/src/server/game/AI/CoreAI/UnitAI.cpp
@@ -150,8 +150,7 @@ void UnitAI::DoCast(uint32 spellId)
float range = spellInfo->GetMaxRange(false);
DefaultTargetSelector targetSelector(me, range, playerOnly, -(int32)spellId);
- if (!(spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_VICTIM)
- && targetSelector(me->GetVictim()))
+ if (!spellInfo->HasAuraInterruptFlag(AURA_INTERRUPT_FLAG_NOT_VICTIM) && targetSelector(me->GetVictim()))
target = me->GetVictim();
else
target = SelectTarget(SELECT_TARGET_RANDOM, 0, targetSelector);
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
index 6049e877156..9675186a2f4 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
@@ -26,6 +26,7 @@
#include "Map.h"
#include "Player.h"
#include "Random.h"
+#include "SpellInfo.h"
#include "Util.h"
#include "WorldSession.h"
#include "WorldStatePackets.h"
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
index d36c9d8b575..4ccd3eaee95 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
@@ -28,6 +28,7 @@
#include "ObjectAccessor.h"
#include "Player.h"
#include "Random.h"
+#include "SpellInfo.h"
#include "Util.h"
#include "WorldStatePackets.h"
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
index 1f160b19653..b627b1b22a6 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
@@ -27,6 +27,7 @@
#include "Object.h"
#include "ObjectAccessor.h"
#include "Player.h"
+#include "SpellInfo.h"
#include "WorldPacket.h"
#include "WorldStatePackets.h"
diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h
index ba6bf40090a..72d92e975fa 100644
--- a/src/server/game/DataStores/DB2Structure.h
+++ b/src/server/game/DataStores/DB2Structure.h
@@ -2459,8 +2459,8 @@ struct SpellInterruptsEntry
{
uint32 ID;
uint32 SpellID;
- uint32 AuraInterruptFlags[2];
- uint32 ChannelInterruptFlags[2];
+ uint32 AuraInterruptFlags[MAX_SPELL_AURA_INTERRUPT_FLAGS];
+ uint32 ChannelInterruptFlags[MAX_SPELL_AURA_INTERRUPT_FLAGS];
uint16 InterruptFlags;
uint8 DifficultyID;
};
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index ecade307f26..db91142e146 100644
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -847,6 +847,8 @@ enum SpellCategoryFlags
#define MAX_SPELL_EFFECTS 32
#define MAX_EFFECT_MASK 0xFFFFFFFF
+#define MAX_SPELL_AURA_INTERRUPT_FLAGS 2
+
enum SpellItemEnchantmentFlags
{
ENCHANTMENT_CAN_SOULBOUND = 0x01,
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 6915b68061b..35f768c8338 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -1613,7 +1613,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
InterruptNonMeleeSpells(true);
//remove auras before removing from map...
- RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP | AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_TURNING);
+ RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP | AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_TURNING));
if (!GetSession()->PlayerLogout() && !(options & TELE_TO_SEAMLESS))
{
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index a2a7d5b1697..7430ea90499 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -319,7 +319,7 @@ Unit::Unit(bool isWorldObject) :
m_auraUpdateIterator = m_ownedAuras.end();
- m_interruptMask = 0;
+ m_interruptMask.fill(0);
m_transform = 0;
m_canModifyStats = false;
@@ -644,13 +644,15 @@ void Unit::RemoveVisibleAura(AuraApplication* aurApp)
void Unit::UpdateInterruptMask()
{
- m_interruptMask = 0;
- for (AuraApplicationList::const_iterator i = m_interruptableAuras.begin(); i != m_interruptableAuras.end(); ++i)
- m_interruptMask |= (*i)->GetBase()->GetSpellInfo()->AuraInterruptFlags;
+ m_interruptMask.fill(0);
+ for (AuraApplication const* aurApp : m_interruptableAuras)
+ for (std::size_t i = 0; i < m_interruptMask.size(); ++i)
+ m_interruptMask[i] |= aurApp->GetBase()->GetSpellInfo()->AuraInterruptFlags[i];
if (Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL])
if (spell->getState() == SPELL_STATE_CASTING)
- m_interruptMask |= spell->m_spellInfo->ChannelInterruptFlags;
+ for (std::size_t i = 0; i < m_interruptMask.size(); ++i)
+ m_interruptMask[i] |= spell->m_spellInfo->ChannelInterruptFlags[i];
}
bool Unit::HasAuraTypeWithFamilyFlags(AuraType auraType, uint32 familyName, uint32 familyFlags) const
@@ -670,7 +672,7 @@ bool Unit::HasBreakableByDamageAuraType(AuraType type, uint32 excludeAura) const
AuraEffectList const& auras = GetAuraEffectsByType(type);
for (AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
if ((!excludeAura || excludeAura != (*itr)->GetSpellInfo()->Id) && //Avoid self interrupt of channeled Crowd Control spells like Seduction
- ((*itr)->GetSpellInfo()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_TAKE_DAMAGE))
+ (*itr)->GetSpellInfo()->HasAuraInterruptFlag(AURA_INTERRUPT_FLAG_TAKE_DAMAGE))
return true;
return false;
}
@@ -912,12 +914,8 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
}
if (Spell* spell = victim->m_currentSpells[CURRENT_CHANNELED_SPELL])
- if (spell->getState() == SPELL_STATE_CASTING)
- {
- uint32 channelInterruptFlags = spell->m_spellInfo->ChannelInterruptFlags;
- if (((channelInterruptFlags & CHANNEL_FLAG_DELAY) != 0) && (damagetype != DOT))
- spell->DelayedChannel();
- }
+ if (spell->getState() == SPELL_STATE_CASTING && spell->m_spellInfo->HasChannelInterruptFlag(CHANNEL_FLAG_DELAY) && damagetype != DOT)
+ spell->DelayedChannel();
}
}
@@ -3241,7 +3239,7 @@ AuraApplication * Unit::_CreateAuraApplication(Aura* aura, uint32 effMask)
AuraApplication * aurApp = new AuraApplication(this, caster, aura, effMask);
m_appliedAuras.insert(AuraApplicationMap::value_type(aurId, aurApp));
- if (aurSpellInfo->AuraInterruptFlags)
+ if (aurSpellInfo->HasAnyAuraInterruptFlag())
{
m_interruptableAuras.push_back(aurApp);
AddInterruptMask(aurSpellInfo->AuraInterruptFlags);
@@ -3285,7 +3283,7 @@ void Unit::_ApplyAura(AuraApplication * aurApp, uint32 effMask)
return;
// Sitdown on apply aura req seated
- if (aura->GetSpellInfo()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED && !IsSitState())
+ if (aura->GetSpellInfo()->HasAuraInterruptFlag(AURA_INTERRUPT_FLAG_NOT_SEATED) && !IsSitState())
SetStandState(UNIT_STAND_STATE_SIT);
Unit* caster = aura->GetCaster();
@@ -3326,7 +3324,7 @@ void Unit::_UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMo
// Remove all pointers from lists here to prevent possible pointer invalidation on spellcast/auraapply/auraremove
m_appliedAuras.erase(i);
- if (aura->GetSpellInfo()->AuraInterruptFlags)
+ if (aura->GetSpellInfo()->HasAnyAuraInterruptFlag())
{
m_interruptableAuras.remove(aurApp);
UpdateInterruptMask();
@@ -3904,9 +3902,10 @@ void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase, bool phaseid)
}
}
-void Unit::RemoveAurasWithInterruptFlags(uint32 flag, uint32 except)
+template <typename InterruptFlags>
+void Unit::RemoveAurasWithInterruptFlags(InterruptFlags flag, uint32 except)
{
- if (!(m_interruptMask & flag))
+ if (!(m_interruptMask[AuraInterruptFlagIndex<InterruptFlags>::value] & flag))
return;
// interrupt auras
@@ -3914,7 +3913,7 @@ void Unit::RemoveAurasWithInterruptFlags(uint32 flag, uint32 except)
{
Aura* aura = (*iter)->GetBase();
++iter;
- if ((aura->GetSpellInfo()->AuraInterruptFlags & flag) && (!except || aura->GetId() != except)
+ if (aura->GetSpellInfo()->AuraInterruptFlags[AuraInterruptFlagIndex<InterruptFlags>::value] & flag && (!except || aura->GetId() != except)
&& !(flag & AURA_INTERRUPT_FLAG_MOVE && HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, aura->GetSpellInfo())))
{
uint32 removedAuras = m_removedAurasCount;
@@ -3927,14 +3926,17 @@ void Unit::RemoveAurasWithInterruptFlags(uint32 flag, uint32 except)
// interrupt channeled spell
if (Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL])
if (spell->getState() == SPELL_STATE_CASTING
- && (spell->m_spellInfo->ChannelInterruptFlags & flag)
- && spell->m_spellInfo->Id != except
+ && (spell->GetSpellInfo()->ChannelInterruptFlags[AuraInterruptFlagIndex<InterruptFlags>::value] & flag)
+ && spell->GetSpellInfo()->Id != except
&& !(flag & AURA_INTERRUPT_FLAG_MOVE && HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, spell->GetSpellInfo())))
InterruptNonMeleeSpells(false);
UpdateInterruptMask();
}
+template TC_GAME_API void Unit::RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags flag, uint32 except);
+template TC_GAME_API void Unit::RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags2 flag, uint32 except);
+
void Unit::RemoveAurasWithFamily(SpellFamilyNames family, flag128 const& familyFlag, ObjectGuid casterGUID)
{
for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
@@ -4374,18 +4376,23 @@ bool Unit::HasAuraTypeWithValue(AuraType auratype, int32 value) const
return false;
}
-bool Unit::HasNegativeAuraWithInterruptFlag(uint32 flag, ObjectGuid guid) const
+template <typename InterruptFlags>
+bool Unit::HasNegativeAuraWithInterruptFlag(InterruptFlags flag, ObjectGuid guid) const
{
- if (!(m_interruptMask & flag))
+ if (!(m_interruptMask[AuraInterruptFlagIndex<InterruptFlags>::value] & flag))
return false;
+
for (AuraApplicationList::const_iterator iter = m_interruptableAuras.begin(); iter != m_interruptableAuras.end(); ++iter)
- {
- if (!(*iter)->IsPositive() && (*iter)->GetBase()->GetSpellInfo()->AuraInterruptFlags & flag && (!guid || (*iter)->GetBase()->GetCasterGUID() == guid))
+ if (!(*iter)->IsPositive() && (*iter)->GetBase()->GetSpellInfo()->AuraInterruptFlags[AuraInterruptFlagIndex<InterruptFlags>::value] & flag &&
+ (!guid || (*iter)->GetBase()->GetCasterGUID() == guid))
return true;
- }
+
return false;
}
+template TC_GAME_API bool Unit::HasNegativeAuraWithInterruptFlag(SpellAuraInterruptFlags flag, ObjectGuid guid) const;
+template TC_GAME_API bool Unit::HasNegativeAuraWithInterruptFlag(SpellAuraInterruptFlags2 flag, ObjectGuid guid) const;
+
bool Unit::HasNegativeAuraWithAttribute(uint32 flag, ObjectGuid guid) const
{
for (AuraApplicationMap::const_iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end(); ++iter)
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 59bac640af3..a37081a8153 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -38,56 +38,6 @@
#define ARTIFACTS_ALL_WEAPONS_GENERAL_WEAPON_EQUIPPED_PASSIVE 197886
#define SPELL_DH_DOUBLE_JUMP 196055
-enum SpellInterruptFlags
-{
- SPELL_INTERRUPT_FLAG_MOVEMENT = 0x01, // why need this for instant?
- SPELL_INTERRUPT_FLAG_PUSH_BACK = 0x02, // push back
- SPELL_INTERRUPT_FLAG_UNK3 = 0x04, // any info?
- SPELL_INTERRUPT_FLAG_INTERRUPT = 0x08, // interrupt
- SPELL_INTERRUPT_FLAG_ABORT_ON_DMG = 0x10 // _complete_ interrupt on direct damage
- //SPELL_INTERRUPT_UNK = 0x20 // unk, 564 of 727 spells having this spell start with "Glyph"
-};
-
-// See SpellAuraInterruptFlags for other values definitions
-enum SpellChannelInterruptFlags
-{
- CHANNEL_INTERRUPT_FLAG_INTERRUPT = 0x08, // interrupt
- CHANNEL_FLAG_DELAY = 0x4000
-};
-
-enum SpellAuraInterruptFlags : uint32
-{
- AURA_INTERRUPT_FLAG_HITBYSPELL = 0x00000001, // 0 removed when getting hit by a negative spell?
- AURA_INTERRUPT_FLAG_TAKE_DAMAGE = 0x00000002, // 1 removed by any damage
- AURA_INTERRUPT_FLAG_CAST = 0x00000004, // 2 cast any spells
- AURA_INTERRUPT_FLAG_MOVE = 0x00000008, // 3 removed by any movement
- AURA_INTERRUPT_FLAG_TURNING = 0x00000010, // 4 removed by any turning
- AURA_INTERRUPT_FLAG_JUMP = 0x00000020, // 5 removed by entering combat
- AURA_INTERRUPT_FLAG_NOT_MOUNTED = 0x00000040, // 6 removed by dismounting
- AURA_INTERRUPT_FLAG_NOT_ABOVEWATER = 0x00000080, // 7 removed by entering water
- AURA_INTERRUPT_FLAG_NOT_UNDERWATER = 0x00000100, // 8 removed by leaving water
- AURA_INTERRUPT_FLAG_NOT_SHEATHED = 0x00000200, // 9 removed by unsheathing
- AURA_INTERRUPT_FLAG_TALK = 0x00000400, // 10 talk to npc / loot? action on creature
- AURA_INTERRUPT_FLAG_USE = 0x00000800, // 11 mine/use/open action on gameobject
- AURA_INTERRUPT_FLAG_MELEE_ATTACK = 0x00001000, // 12 removed by attacking
- AURA_INTERRUPT_FLAG_SPELL_ATTACK = 0x00002000, // 13 ???
- AURA_INTERRUPT_FLAG_UNK14 = 0x00004000, // 14
- AURA_INTERRUPT_FLAG_TRANSFORM = 0x00008000, // 15 removed by transform?
- AURA_INTERRUPT_FLAG_UNK16 = 0x00010000, // 16
- AURA_INTERRUPT_FLAG_MOUNT = 0x00020000, // 17 misdirect, aspect, swim speed
- AURA_INTERRUPT_FLAG_NOT_SEATED = 0x00040000, // 18 removed by standing up (used by food and drink mostly and sleep/Fake Death like)
- AURA_INTERRUPT_FLAG_CHANGE_MAP = 0x00080000, // 19 leaving map/getting teleported
- AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION = 0x00100000, // 20 removed by auras that make you invulnerable, or make other to lose selection on you
- AURA_INTERRUPT_FLAG_UNK21 = 0x00200000, // 21
- AURA_INTERRUPT_FLAG_TELEPORTED = 0x00400000, // 22
- AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT = 0x00800000, // 23 removed by entering pvp combat
- AURA_INTERRUPT_FLAG_DIRECT_DAMAGE = 0x01000000, // 24 removed by any direct damage
- AURA_INTERRUPT_FLAG_LANDING = 0x02000000, // 25 removed by hitting the ground
- AURA_INTERRUPT_FLAG_LEAVE_COMBAT = 0x80000000, // 31 removed by leaving combat
-
- AURA_INTERRUPT_FLAG_NOT_VICTIM = (AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE | AURA_INTERRUPT_FLAG_DIRECT_DAMAGE)
-};
-
enum SpellModOp : uint8
{
SPELLMOD_DAMAGE = 0,
@@ -1489,7 +1439,8 @@ class TC_GAME_API Unit : public WorldObject
void RemoveAurasDueToItemSpell(uint32 spellId, ObjectGuid castItemGuid);
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID = ObjectGuid::Empty, Aura* except = NULL, bool negative = true, bool positive = true);
void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0, bool phaseid = false);
- void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except = 0);
+ template <typename InterruptFlags>
+ void RemoveAurasWithInterruptFlags(InterruptFlags flag, uint32 except = 0);
void RemoveAurasWithAttribute(uint32 flags);
void RemoveAurasWithFamily(SpellFamilyNames family, flag128 const& familyFlag, ObjectGuid casterGUID);
void RemoveAurasWithMechanic(uint32 mechanic_mask, AuraRemoveMode removemode = AURA_REMOVE_BY_DEFAULT, uint32 except = 0);
@@ -1533,7 +1484,8 @@ class TC_GAME_API Unit : public WorldObject
bool HasAuraTypeWithMiscvalue(AuraType auratype, int32 miscvalue) const;
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const* affectedSpell) const;
bool HasAuraTypeWithValue(AuraType auratype, int32 value) const;
- bool HasNegativeAuraWithInterruptFlag(uint32 flag, ObjectGuid guid = ObjectGuid::Empty) const;
+ template <typename InterruptFlags>
+ bool HasNegativeAuraWithInterruptFlag(InterruptFlags flag, ObjectGuid guid = ObjectGuid::Empty) const;
bool HasNegativeAuraWithAttribute(uint32 flag, ObjectGuid guid = ObjectGuid::Empty) const;
bool HasAuraWithMechanic(uint32 mechanicMask) const;
@@ -1690,8 +1642,11 @@ class TC_GAME_API Unit : public WorldObject
void SetVisibleAuraUpdate(AuraApplication* aurApp) { m_visibleAurasToUpdate.insert(aurApp); }
void RemoveVisibleAura(AuraApplication* aurApp);
- uint32 GetInterruptMask() const { return m_interruptMask; }
- void AddInterruptMask(uint32 mask) { m_interruptMask |= mask; }
+ void AddInterruptMask(std::array<uint32, 2> const& mask)
+ {
+ for (std::size_t i = 0; i < m_interruptMask.size(); ++i)
+ m_interruptMask[i] |= mask[i];
+ }
void UpdateInterruptMask();
uint32 GetDisplayId() const { return GetUInt32Value(UNIT_FIELD_DISPLAYID); }
@@ -1980,7 +1935,7 @@ class TC_GAME_API Unit : public WorldObject
AuraList m_scAuras; // cast singlecast auras
AuraApplicationList m_interruptableAuras; // auras which have interrupt mask applied on unit
AuraStateAurasMap m_auraStateAuras; // Used for improve performance of aura state checks on aura apply/remove
- uint32 m_interruptMask;
+ std::array<uint32, 2> m_interruptMask;
float m_auraModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_END];
float m_weaponDamage[MAX_ATTACK][2];
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index 03cca539025..11df92f78b0 100644
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -16,23 +16,23 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "Common.h"
-#include "WorldPacket.h"
#include "WorldSession.h"
-#include "Opcodes.h"
-#include "Log.h"
+#include "Battleground.h"
+#include "Common.h"
#include "Corpse.h"
-#include "Player.h"
#include "Garrison.h"
-#include "MapManager.h"
-#include "Transport.h"
-#include "Battleground.h"
-#include "WaypointMovementGenerator.h"
+#include "InstancePackets.h"
#include "InstanceSaveMgr.h"
+#include "Log.h"
+#include "MapManager.h"
+#include "MovementPackets.h"
#include "ObjectMgr.h"
+#include "Opcodes.h"
+#include "Player.h"
+#include "SpellInfo.h"
+#include "Transport.h"
#include "Vehicle.h"
-#include "InstancePackets.h"
-#include "MovementPackets.h"
+#include "WaypointMovementGenerator.h"
#define MOVEMENT_PACKET_TIME_DELAY 0
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 08a712c326a..076452542ff 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -3412,7 +3412,7 @@ void AuraEffect::HandleAuraModEffectImmunity(AuraApplication const* aurApp, uint
// when removing flag aura, handle flag drop
Player* player = target->ToPlayer();
- if (!apply && player && (GetSpellInfo()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION))
+ if (!apply && player && GetSpellInfo()->HasAuraInterruptFlag(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION))
{
if (player->InBattleground())
{
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 2bbe805b5ec..65899f518d8 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -4938,7 +4938,7 @@ SpellCastResult Spell::CheckCast(bool strict)
// skip stuck spell to allow use it in falling case and apply spell limitations at movement
SpellEffectInfo const* effect = GetEffect(EFFECT_0);
if ((!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR) || (effect && effect->Effect != SPELL_EFFECT_STUCK)) &&
- (IsAutoRepeat() || (m_spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) != 0))
+ (IsAutoRepeat() || m_spellInfo->HasAuraInterruptFlag(AURA_INTERRUPT_FLAG_NOT_SEATED)))
return SPELL_FAILED_MOVING;
}
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index b37e632f452..2c0a91c4277 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -3078,7 +3078,7 @@ void Spell::EffectInterruptCast(SpellEffIndex effIndex)
|| (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
&& (curSpellInfo->PreventionType & SPELL_PREVENTION_TYPE_SILENCE)
&& ((i == CURRENT_GENERIC_SPELL && curSpellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_INTERRUPT)
- || (i == CURRENT_CHANNELED_SPELL && curSpellInfo->ChannelInterruptFlags & CHANNEL_INTERRUPT_FLAG_INTERRUPT)))
+ || (i == CURRENT_CHANNELED_SPELL && curSpellInfo->HasChannelInterruptFlag(CHANNEL_INTERRUPT_FLAG_INTERRUPT))))
{
if (m_originalCaster)
{
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index 1de54909348..bda28f6f3ef 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -1103,11 +1103,18 @@ SpellInfo::SpellInfo(SpellInfoLoadHelper const& data, SpellEffectEntryMap const&
EquippedItemInventoryTypeMask = _equipped ? _equipped->EquippedItemInventoryTypeMask : -1;
// SpellInterruptsEntry
- SpellInterruptsEntry const* _interrupt = data.Interrupts;
- InterruptFlags = _interrupt ? _interrupt->InterruptFlags : 0;
- // TODO: 6.x these flags have 2 parts
- AuraInterruptFlags = _interrupt ? _interrupt->AuraInterruptFlags[0] : 0;
- ChannelInterruptFlags = _interrupt ? _interrupt->ChannelInterruptFlags[0] : 0;
+ if (SpellInterruptsEntry const* _interrupt = data.Interrupts)
+ {
+ InterruptFlags = _interrupt->InterruptFlags;
+ std::copy(std::begin(_interrupt->AuraInterruptFlags), std::end(_interrupt->AuraInterruptFlags), AuraInterruptFlags.begin());
+ std::copy(std::begin(_interrupt->ChannelInterruptFlags), std::end(_interrupt->ChannelInterruptFlags), ChannelInterruptFlags.begin());
+ }
+ else
+ {
+ InterruptFlags = 0;
+ AuraInterruptFlags.fill(0);
+ ChannelInterruptFlags.fill(0);
+ }
// SpellLevelsEntry
SpellLevelsEntry const* _levels = data.Levels;
@@ -2294,7 +2301,7 @@ void SpellInfo::_LoadSpellSpecific()
case SPELLFAMILY_GENERIC:
{
// Food / Drinks (mostly)
- if (AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED)
+ if (HasAuraInterruptFlag(AURA_INTERRUPT_FLAG_NOT_SEATED))
{
bool food = false;
bool drink = false;
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index 78e262b6bd8..2d2d93be773 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -198,6 +198,75 @@ enum SpellCustomAttributes
SPELL_ATTR0_CU_NEGATIVE = SPELL_ATTR0_CU_NEGATIVE_EFF0 | SPELL_ATTR0_CU_NEGATIVE_EFF1 | SPELL_ATTR0_CU_NEGATIVE_EFF2
};
+enum SpellInterruptFlags : uint32
+{
+ SPELL_INTERRUPT_FLAG_MOVEMENT = 0x01, // why need this for instant?
+ SPELL_INTERRUPT_FLAG_PUSH_BACK = 0x02, // push back
+ SPELL_INTERRUPT_FLAG_UNK3 = 0x04, // any info?
+ SPELL_INTERRUPT_FLAG_INTERRUPT = 0x08, // interrupt
+ SPELL_INTERRUPT_FLAG_ABORT_ON_DMG = 0x10 // _complete_ interrupt on direct damage
+ //SPELL_INTERRUPT_UNK = 0x20 // unk, 564 of 727 spells having this spell start with "Glyph"
+};
+
+// See SpellAuraInterruptFlags for other values definitions
+enum SpellChannelInterruptFlags : uint32
+{
+ CHANNEL_INTERRUPT_FLAG_INTERRUPT = 0x08, // interrupt
+ CHANNEL_FLAG_DELAY = 0x4000
+};
+
+enum SpellAuraInterruptFlags : uint32
+{
+ AURA_INTERRUPT_FLAG_HITBYSPELL = 0x00000001, // 0 removed when getting hit by a negative spell?
+ AURA_INTERRUPT_FLAG_TAKE_DAMAGE = 0x00000002, // 1 removed by any damage
+ AURA_INTERRUPT_FLAG_CAST = 0x00000004, // 2 cast any spells
+ AURA_INTERRUPT_FLAG_MOVE = 0x00000008, // 3 removed by any movement
+ AURA_INTERRUPT_FLAG_TURNING = 0x00000010, // 4 removed by any turning
+ AURA_INTERRUPT_FLAG_JUMP = 0x00000020, // 5 removed by entering combat
+ AURA_INTERRUPT_FLAG_NOT_MOUNTED = 0x00000040, // 6 removed by dismounting
+ AURA_INTERRUPT_FLAG_NOT_ABOVEWATER = 0x00000080, // 7 removed by entering water
+ AURA_INTERRUPT_FLAG_NOT_UNDERWATER = 0x00000100, // 8 removed by leaving water
+ AURA_INTERRUPT_FLAG_NOT_SHEATHED = 0x00000200, // 9 removed by unsheathing
+ AURA_INTERRUPT_FLAG_TALK = 0x00000400, // 10 talk to npc / loot? action on creature
+ AURA_INTERRUPT_FLAG_USE = 0x00000800, // 11 mine/use/open action on gameobject
+ AURA_INTERRUPT_FLAG_MELEE_ATTACK = 0x00001000, // 12 removed by attacking
+ AURA_INTERRUPT_FLAG_SPELL_ATTACK = 0x00002000, // 13 ???
+ AURA_INTERRUPT_FLAG_UNK14 = 0x00004000, // 14
+ AURA_INTERRUPT_FLAG_TRANSFORM = 0x00008000, // 15 removed by transform?
+ AURA_INTERRUPT_FLAG_UNK16 = 0x00010000, // 16
+ AURA_INTERRUPT_FLAG_MOUNT = 0x00020000, // 17 misdirect, aspect, swim speed
+ AURA_INTERRUPT_FLAG_NOT_SEATED = 0x00040000, // 18 removed by standing up (used by food and drink mostly and sleep/Fake Death like)
+ AURA_INTERRUPT_FLAG_CHANGE_MAP = 0x00080000, // 19 leaving map/getting teleported
+ AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION = 0x00100000, // 20 removed by auras that make you invulnerable, or make other to lose selection on you
+ AURA_INTERRUPT_FLAG_UNK21 = 0x00200000, // 21
+ AURA_INTERRUPT_FLAG_TELEPORTED = 0x00400000, // 22
+ AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT = 0x00800000, // 23 removed by entering pvp combat
+ AURA_INTERRUPT_FLAG_DIRECT_DAMAGE = 0x01000000, // 24 removed by any direct damage
+ AURA_INTERRUPT_FLAG_LANDING = 0x02000000, // 25 removed by hitting the ground
+ AURA_INTERRUPT_FLAG_LEAVE_COMBAT = 0x80000000, // 31 removed by leaving combat
+
+ AURA_INTERRUPT_FLAG_NOT_VICTIM = (AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE | AURA_INTERRUPT_FLAG_DIRECT_DAMAGE)
+};
+
+enum SpellAuraInterruptFlags2 : uint32
+{
+};
+
+template <typename InterruptFlag>
+struct AuraInterruptFlagIndex {};
+
+template <>
+struct AuraInterruptFlagIndex<SpellAuraInterruptFlags>
+{
+ static std::size_t constexpr value = 0;
+};
+
+template <>
+struct AuraInterruptFlagIndex<SpellAuraInterruptFlags2>
+{
+ static std::size_t constexpr value = 1;
+};
+
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType);
class TC_GAME_API SpellImplicitTargetInfo
@@ -379,8 +448,8 @@ class TC_GAME_API SpellInfo
uint32 StartRecoveryCategory;
uint32 StartRecoveryTime;
uint32 InterruptFlags;
- uint32 AuraInterruptFlags;
- uint32 ChannelInterruptFlags;
+ std::array<uint32, MAX_SPELL_AURA_INTERRUPT_FLAGS> AuraInterruptFlags;
+ std::array<uint32, MAX_SPELL_AURA_INTERRUPT_FLAGS> ChannelInterruptFlags;
uint32 ProcFlags;
uint32 ProcChance;
uint32 ProcCharges;
@@ -441,21 +510,27 @@ class TC_GAME_API SpellInfo
bool HasAreaAuraEffect(uint32 difficulty) const;
bool HasAreaAuraEffect() const;
- inline bool HasAttribute(SpellAttr0 attribute) const { return !!(Attributes & attribute); }
- inline bool HasAttribute(SpellAttr1 attribute) const { return !!(AttributesEx & attribute); }
- inline bool HasAttribute(SpellAttr2 attribute) const { return !!(AttributesEx2 & attribute); }
- inline bool HasAttribute(SpellAttr3 attribute) const { return !!(AttributesEx3 & attribute); }
- inline bool HasAttribute(SpellAttr4 attribute) const { return !!(AttributesEx4 & attribute); }
- inline bool HasAttribute(SpellAttr5 attribute) const { return !!(AttributesEx5 & attribute); }
- inline bool HasAttribute(SpellAttr6 attribute) const { return !!(AttributesEx6 & attribute); }
- inline bool HasAttribute(SpellAttr7 attribute) const { return !!(AttributesEx7 & attribute); }
- inline bool HasAttribute(SpellAttr8 attribute) const { return !!(AttributesEx8 & attribute); }
- inline bool HasAttribute(SpellAttr9 attribute) const { return !!(AttributesEx9 & attribute); }
- inline bool HasAttribute(SpellAttr10 attribute) const { return !!(AttributesEx10 & attribute); }
- inline bool HasAttribute(SpellAttr11 attribute) const { return !!(AttributesEx11 & attribute); }
- inline bool HasAttribute(SpellAttr12 attribute) const { return !!(AttributesEx12 & attribute); }
- inline bool HasAttribute(SpellAttr13 attribute) const { return !!(AttributesEx13 & attribute); }
- inline bool HasAttribute(SpellCustomAttributes customAttribute) const { return !!(AttributesCu & customAttribute); }
+ bool HasAttribute(SpellAttr0 attribute) const { return !!(Attributes & attribute); }
+ bool HasAttribute(SpellAttr1 attribute) const { return !!(AttributesEx & attribute); }
+ bool HasAttribute(SpellAttr2 attribute) const { return !!(AttributesEx2 & attribute); }
+ bool HasAttribute(SpellAttr3 attribute) const { return !!(AttributesEx3 & attribute); }
+ bool HasAttribute(SpellAttr4 attribute) const { return !!(AttributesEx4 & attribute); }
+ bool HasAttribute(SpellAttr5 attribute) const { return !!(AttributesEx5 & attribute); }
+ bool HasAttribute(SpellAttr6 attribute) const { return !!(AttributesEx6 & attribute); }
+ bool HasAttribute(SpellAttr7 attribute) const { return !!(AttributesEx7 & attribute); }
+ bool HasAttribute(SpellAttr8 attribute) const { return !!(AttributesEx8 & attribute); }
+ bool HasAttribute(SpellAttr9 attribute) const { return !!(AttributesEx9 & attribute); }
+ bool HasAttribute(SpellAttr10 attribute) const { return !!(AttributesEx10 & attribute); }
+ bool HasAttribute(SpellAttr11 attribute) const { return !!(AttributesEx11 & attribute); }
+ bool HasAttribute(SpellAttr12 attribute) const { return !!(AttributesEx12 & attribute); }
+ bool HasAttribute(SpellAttr13 attribute) const { return !!(AttributesEx13 & attribute); }
+ bool HasAttribute(SpellCustomAttributes customAttribute) const { return !!(AttributesCu & customAttribute); }
+
+ bool HasAnyAuraInterruptFlag() const { return std::find_if(AuraInterruptFlags.begin(), AuraInterruptFlags.end(), [](uint32 flag) { return flag != 0; }) != AuraInterruptFlags.end(); }
+ bool HasAuraInterruptFlag(SpellAuraInterruptFlags flag) const { return (AuraInterruptFlags[AuraInterruptFlagIndex<SpellAuraInterruptFlags>::value] & flag) != 0; }
+ bool HasAuraInterruptFlag(SpellAuraInterruptFlags2 flag) const { return (AuraInterruptFlags[AuraInterruptFlagIndex<SpellAuraInterruptFlags2>::value] & flag) != 0; }
+
+ bool HasChannelInterruptFlag(SpellChannelInterruptFlags flag) const { return (ChannelInterruptFlags[AuraInterruptFlagIndex<SpellAuraInterruptFlags>::value] & flag) != 0; }
bool IsExplicitDiscovery() const;
bool IsLootCrafting() const;
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index ef9d7e6862e..302416e4885 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -2759,7 +2759,7 @@ void SpellMgr::LoadSpellInfoCorrections()
// Easter Lay Noblegarden Egg Aura - Interrupt flags copied from aura which this aura is linked with
ApplySpellFix({ 61719 }, [](SpellInfo* spellInfo)
{
- spellInfo->AuraInterruptFlags = AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE;
+ spellInfo->AuraInterruptFlags[0] = AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE;
});
ApplySpellFix({
@@ -2924,7 +2924,7 @@ void SpellMgr::LoadSpellInfoCorrections()
ApplySpellFix({ 63414 }, [](SpellInfo* spellInfo)
{
const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetB = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
- spellInfo->ChannelInterruptFlags = 0;
+ spellInfo->ChannelInterruptFlags.fill(0);
});
// Rocket Strike (Mimiron)
@@ -3292,7 +3292,7 @@ void SpellMgr::LoadSpellInfoCorrections()
// Threatening Gaze
ApplySpellFix({ 24314 }, [](SpellInfo* spellInfo)
{
- spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CAST | AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_JUMP;
+ spellInfo->AuraInterruptFlags[0] |= AURA_INTERRUPT_FLAG_CAST | AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_JUMP;
});
// Tree of Life (Passive)
@@ -3353,7 +3353,7 @@ void SpellMgr::LoadSpellInfoCorrections()
// Blaze of Glory
ApplySpellFix({ 99252 }, [](SpellInfo* spellInfo)
{
- spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
+ spellInfo->AuraInterruptFlags[0] |= AURA_INTERRUPT_FLAG_CHANGE_MAP;
});
// ENDOF FIRELANDS SPELLS