Core/Auras: Implemented using all aura interrupt flag fields

This commit is contained in:
Shauren
2017-12-17 16:45:50 +01:00
parent e573607ccd
commit e86a2c439a
16 changed files with 176 additions and 128 deletions

View File

@@ -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);

View File

@@ -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"

View File

@@ -28,6 +28,7 @@
#include "ObjectAccessor.h"
#include "Player.h"
#include "Random.h"
#include "SpellInfo.h"
#include "Util.h"
#include "WorldStatePackets.h"

View File

@@ -27,6 +27,7 @@
#include "Object.h"
#include "ObjectAccessor.h"
#include "Player.h"
#include "SpellInfo.h"
#include "WorldPacket.h"
#include "WorldStatePackets.h"

View File

@@ -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;
};

View File

@@ -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,

View File

@@ -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))
{

View File

@@ -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)

View File

@@ -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];

View File

@@ -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 "Corpse.h"
#include "Player.h"
#include "Garrison.h"
#include "MapManager.h"
#include "Transport.h"
#include "Battleground.h"
#include "WaypointMovementGenerator.h"
#include "InstanceSaveMgr.h"
#include "ObjectMgr.h"
#include "Vehicle.h"
#include "Common.h"
#include "Corpse.h"
#include "Garrison.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 "WaypointMovementGenerator.h"
#define MOVEMENT_PACKET_TIME_DELAY 0

View File

@@ -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())
{

View File

@@ -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;
}

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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;

View File

@@ -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