diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h index 2df965e2f..08e05b9ab 100644 --- a/src/game/DBCStructure.h +++ b/src/game/DBCStructure.h @@ -1500,6 +1500,42 @@ struct SoundEntriesEntry // 29 m_soundEntriesAdvancedID }; + +struct ClassFamilyMask +{ + uint64 Flags; + uint32 Flags2; + + ClassFamilyMask() : Flags(0), Flags2(0) {} + explicit ClassFamilyMask(uint64 familyFlags, uint32 familyFlags2 = 0) : Flags(familyFlags), Flags2(familyFlags2) {} + + bool Empty() const { return Flags == 0 && Flags2 == 0; } + bool operator! () const { return Empty(); } + operator void const* () const { return Empty() ? NULL : this; }// for allow normal use in if(mask) + + bool IsFitToFamilyMask(uint64 familyFlags, uint32 familyFlags2 = 0) const + { + return (Flags & familyFlags) || (Flags2 & familyFlags2); + } + + bool IsFitToFamilyMask(ClassFamilyMask const& mask) const + { + return (Flags & mask.Flags) || (Flags2 & mask.Flags2); + } + + uint64 operator& (uint64 mask) const // possible will removed at finish convertion code use IsFitToFamilyMask + { + return Flags & mask; + } + + ClassFamilyMask& operator|= (ClassFamilyMask const& mask) + { + Flags |= mask.Flags; + Flags2 |= mask.Flags2; + return *this; + } +}; + #define MAX_SPELL_REAGENTS 8 #define MAX_SPELL_TOTEMS 2 #define MAX_SPELL_TOTEM_CATEGORIES 2 @@ -1579,9 +1615,7 @@ struct SpellEntry int32 EffectMiscValueB[MAX_EFFECT_INDEX]; // 113-115 m_effectMiscValueB uint32 EffectTriggerSpell[MAX_EFFECT_INDEX]; // 116-118 m_effectTriggerSpell float EffectPointsPerComboPoint[MAX_EFFECT_INDEX]; // 119-121 m_effectPointsPerCombo - uint32 EffectSpellClassMaskA[3]; // 122-124 m_effectSpellClassMaskA, effect 0 - uint32 EffectSpellClassMaskB[3]; // 125-127 m_effectSpellClassMaskB, effect 1 - uint32 EffectSpellClassMaskC[3]; // 128-130 m_effectSpellClassMaskC, effect 2 + ClassFamilyMask EffectSpellClassMask[MAX_EFFECT_INDEX]; // 122-130 m_effectSpellClassMaskA/B/C, effect 0/1/2 uint32 SpellVisual[2]; // 131-132 m_spellVisualID uint32 SpellIconID; // 133 m_spellIconID uint32 activeIconID; // 134 m_activeIconID @@ -1599,8 +1633,7 @@ struct SpellEntry uint32 StartRecoveryTime; // 206 m_startRecoveryTime uint32 MaxTargetLevel; // 207 m_maxTargetLevel uint32 SpellFamilyName; // 208 m_spellClassSet - uint64 SpellFamilyFlags; // 209-210 m_spellClassMask NOTE: size is 12 bytes!!! - uint32 SpellFamilyFlags2; // 211 addition to m_spellClassMask + ClassFamilyMask SpellFamilyFlags; // 209-211 m_spellClassMask NOTE: size is 12 bytes!!! uint32 MaxAffectedTargets; // 212 m_maxTargets uint32 DmgClass; // 213 m_defenseType uint32 PreventionType; // 214 m_preventionType @@ -1621,14 +1654,14 @@ struct SpellEntry // helpers int32 CalculateSimpleValue(SpellEffectIndex eff) const { return EffectBasePoints[eff] + int32(1); } - uint32 const* GetEffectSpellClassMask(SpellEffectIndex effect) const + ClassFamilyMask const& GetEffectSpellClassMask(SpellEffectIndex effect) const { - return EffectSpellClassMaskA + effect * 3; + return EffectSpellClassMask[effect]; } bool IsFitToFamilyMask(uint64 familyFlags, uint32 familyFlags2 = 0) const { - return (SpellFamilyFlags & familyFlags) || (SpellFamilyFlags2 & familyFlags2); + return SpellFamilyFlags.IsFitToFamilyMask(familyFlags, familyFlags2); } bool IsFitToFamily(SpellFamily family, uint64 familyFlags, uint32 familyFlags2 = 0) const @@ -1636,6 +1669,16 @@ struct SpellEntry return SpellFamily(SpellFamilyName) == family && IsFitToFamilyMask(familyFlags, familyFlags2); } + bool IsFitToFamilyMask(ClassFamilyMask const& mask) const + { + return SpellFamilyFlags.IsFitToFamilyMask(mask); + } + + bool IsFitToFamily(SpellFamily family, ClassFamilyMask const& mask) const + { + return SpellFamily(SpellFamilyName) == family && IsFitToFamilyMask(mask); + } + private: // prevent creating custom entries (copy data from original in fact) SpellEntry(SpellEntry const&); // DON'T must have implementation diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 9fe80b4b7..e182e0638 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -274,29 +274,21 @@ std::ostringstream& operator<< (std::ostringstream& ss, PlayerTaxi const& taxi) SpellModifier::SpellModifier( SpellModOp _op, SpellModType _type, int32 _value, SpellEntry const* spellEntry, SpellEffectIndex eff, int16 _charges /*= 0*/ ) : op(_op), type(_type), charges(_charges), value(_value), spellId(spellEntry->Id), lastAffected(NULL) { - uint32 const* ptr = spellEntry->GetEffectSpellClassMask(eff); - mask = uint64(ptr[0]) | (uint64(ptr[1]) << 32); - mask2= ptr[2]; + mask = spellEntry->GetEffectSpellClassMask(eff); } SpellModifier::SpellModifier( SpellModOp _op, SpellModType _type, int32 _value, Aura const* aura, int16 _charges /*= 0*/ ) : op(_op), type(_type), charges(_charges), value(_value), spellId(aura->GetId()), lastAffected(NULL) { - uint32 const* ptr = aura->getAuraSpellClassMask(); - mask = uint64(ptr[0]) | (uint64(ptr[1]) << 32); - mask2= ptr[2]; + mask = aura->GetAuraSpellClassMask(); } bool SpellModifier::isAffectedOnSpell( SpellEntry const *spell ) const { SpellEntry const *affect_spell = sSpellStore.LookupEntry(spellId); // False if affect_spell == NULL or spellFamily not equal - if (!affect_spell || affect_spell->SpellFamilyName != spell->SpellFamilyName) + if (!affect_spell) return false; - if (mask & spell->SpellFamilyFlags) - return true; - if (mask2 & spell->SpellFamilyFlags2) - return true; - return false; + return affect_spell->IsFitToFamily(SpellFamily(spell->SpellFamilyName), spell->SpellFamilyFlags); } //== TradeData ================================================= @@ -18564,12 +18556,12 @@ void Player::AddSpellMod(SpellModifier* mod, bool apply) else _mask2= uint32(1) << (eff - 64); - if ( mod->mask & _mask || mod->mask2 & _mask2) + if (mod->mask.IsFitToFamilyMask(_mask, _mask2)) { int32 val = 0; for (SpellModList::const_iterator itr = m_spellMods[mod->op].begin(); itr != m_spellMods[mod->op].end(); ++itr) { - if ((*itr)->type == mod->type && ((*itr)->mask & _mask || (*itr)->mask2 & _mask2)) + if ((*itr)->type == mod->type && ((*itr)->mask.IsFitToFamilyMask(_mask, _mask2))) val += (*itr)->value; } val += apply ? mod->value : -(mod->value); @@ -20832,8 +20824,7 @@ bool Player::CanNoReagentCast(SpellEntry const* spellInfo) const // Check no reagent use mask uint64 noReagentMask_0_1 = GetUInt64Value(PLAYER_NO_REAGENT_COST_1); uint32 noReagentMask_2 = GetUInt32Value(PLAYER_NO_REAGENT_COST_1+2); - if (spellInfo->SpellFamilyFlags & noReagentMask_0_1 || - spellInfo->SpellFamilyFlags2 & noReagentMask_2) + if (spellInfo->IsFitToFamilyMask(noReagentMask_0_1, noReagentMask_2)) return true; return false; diff --git a/src/game/Player.h b/src/game/Player.h index 3221656ca..78340f9c0 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -120,7 +120,11 @@ struct SpellModifier SpellModifier() : charges(0), lastAffected(NULL) {} SpellModifier(SpellModOp _op, SpellModType _type, int32 _value, uint32 _spellId, uint64 _mask, uint32 _mask2 = 0, int16 _charges = 0) - : op(_op), type(_type), charges(_charges), value(_value), mask(_mask), mask2(_mask2), spellId(_spellId), lastAffected(NULL) + : op(_op), type(_type), charges(_charges), value(_value), mask(_mask, _mask2), spellId(_spellId), lastAffected(NULL) + {} + + SpellModifier(SpellModOp _op, SpellModType _type, int32 _value, uint32 _spellId, ClassFamilyMask _mask, int16 _charges = 0) + : op(_op), type(_type), charges(_charges), value(_value), mask(_mask), spellId(_spellId), lastAffected(NULL) {} SpellModifier(SpellModOp _op, SpellModType _type, int32 _value, SpellEntry const* spellEntry, SpellEffectIndex eff, int16 _charges = 0); @@ -133,8 +137,7 @@ struct SpellModifier SpellModType type : 8; int16 charges : 16; int32 value; - uint64 mask; - uint32 mask2; + ClassFamilyMask mask; uint32 spellId; Spell const* lastAffected; }; diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 4f89c7ba3..f4d925b6d 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -4787,8 +4787,8 @@ SpellCastResult Spell::CheckCast(bool strict) // Exclusion for Pounce: Facing Limitation was removed in 2.0.1, but it still uses the same, old Ex-Flags // Exclusion for Mutilate:Facing Limitation was removed in 2.0.1 and 3.0.3, but they still use the same, old Ex-Flags // Exclusion for Throw: Facing limitation was added in 3.2.x, but that shouldn't be - if ((m_spellInfo->SpellFamilyName != SPELLFAMILY_DRUID || (m_spellInfo->SpellFamilyFlags != UI64LIT(0x0000000000020000))) && - (m_spellInfo->SpellFamilyName != SPELLFAMILY_ROGUE || (m_spellInfo->SpellFamilyFlags != UI64LIT(0x0020000000000000))) && + if (!m_spellInfo->IsFitToFamily(SPELLFAMILY_DRUID, UI64LIT(0x0000000000020000)) && + !m_spellInfo->IsFitToFamily(SPELLFAMILY_ROGUE, UI64LIT(0x0020000000000000)) && m_spellInfo->Id != 2764) { SendInterrupted(2); diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 4740d58bc..57a97fc47 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -852,25 +852,16 @@ void Aura::ApplyModifier(bool apply, bool Real) bool Aura::isAffectedOnSpell(SpellEntry const *spell) const { - // Check family name - if (spell->SpellFamilyName != GetSpellProto()->SpellFamilyName) - return false; - // Check EffectClassMask - uint32 const *ptr = getAuraSpellClassMask(); - if (((uint64*)ptr)[0] & spell->SpellFamilyFlags) - return true; - if (ptr[2] & spell->SpellFamilyFlags2) - return true; - return false; + return spell->IsFitToFamily(SpellFamily(GetSpellProto()->SpellFamilyName), GetAuraSpellClassMask()); } bool Aura::CanProcFrom(SpellEntry const *spell, uint32 EventProcEx, uint32 procEx, bool active, bool useClassMask) const { // Check EffectClassMask - uint32 const *ptr = getAuraSpellClassMask(); + ClassFamilyMask const& mask = GetAuraSpellClassMask(); // if no class mask defined, or spell_proc_event has SpellFamilyName=0 - allow proc - if (!useClassMask || (!((uint64*)ptr)[0] && !ptr[2])) + if (!useClassMask || !mask) { if (!(EventProcEx & PROC_EX_EX_TRIGGER_ALWAYS)) { @@ -896,14 +887,8 @@ bool Aura::CanProcFrom(SpellEntry const *spell, uint32 EventProcEx, uint32 procE { // SpellFamilyName check is performed in SpellMgr::IsSpellProcEventCanTriggeredBy and it is done once for whole holder // note: SpellFamilyName is not checked if no spell_proc_event is defined - - if (((uint64*)ptr)[0] & spell->SpellFamilyFlags) - return true; - - if (ptr[2] & spell->SpellFamilyFlags2) - return true; + return mask.IsFitToFamilyMask(spell->SpellFamilyFlags); } - return false; } void Aura::ReapplyAffectedPassiveAuras( Unit* target, bool owner_mode ) @@ -1042,14 +1027,14 @@ void Aura::HandleAddModifier(bool apply, bool Real) // Everlasting Affliction, overwrite wrong data, if will need more better restore support of spell_affect table if (spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK && spellProto->SpellIconID == 3169) { - m_spellmod->mask = UI64LIT(0x0000010000000002); // Corruption and Unstable Affliction - m_spellmod->mask2 = 0x00000000; + // Corruption and Unstable Affliction + m_spellmod->mask = ClassFamilyMask(UI64LIT(0x0000010000000002)); } // Improved Flametongue Weapon, overwrite wrong data, maybe time re-add table else if (spellProto->Id == 37212) { - m_spellmod->mask = UI64LIT(0x0000000000200000); // Flametongue Weapon (Passive) - m_spellmod->mask2 = 0x00000000; + // Flametongue Weapon (Passive) + m_spellmod->mask = ClassFamilyMask(UI64LIT(0x0000000000200000)); } } @@ -6358,19 +6343,13 @@ void Aura::HandleNoReagentUseAura(bool /*Apply*/, bool Real) if(target->GetTypeId() != TYPEID_PLAYER) return; - uint32 mask[3] = {0, 0, 0}; + ClassFamilyMask mask; Unit::AuraList const& noReagent = target->GetAurasByType(SPELL_AURA_NO_REAGENT_USE); - for(Unit::AuraList::const_iterator i = noReagent.begin(); i != noReagent.end(); ++i) - { - uint32 const *ptr = (*i)->getAuraSpellClassMask(); - mask[0] |= ptr[0]; - mask[1] |= ptr[1]; - mask[2] |= ptr[2]; - } + for(Unit::AuraList::const_iterator i = noReagent.begin(); i != noReagent.end(); ++i) + mask |= (*i)->GetAuraSpellClassMask(); - target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+0, mask[0]); - target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+1, mask[1]); - target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+2, mask[2]); + target->SetUInt64Value(PLAYER_NO_REAGENT_COST_1+0, mask.Flags); + target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+2, mask.Flags2); } /*********************************************************/ @@ -8626,8 +8605,7 @@ void SpellAuraHolder::_RemoveSpellAuraHolder() } uint32 removeState = 0; - uint64 removeFamilyFlag = m_spellProto->SpellFamilyFlags; - uint32 removeFamilyFlag2 = m_spellProto->SpellFamilyFlags2; + ClassFamilyMask removeFamilyFlag = m_spellProto->SpellFamilyFlags; switch(m_spellProto->SpellFamilyName) { case SPELLFAMILY_PALADIN: @@ -8638,8 +8616,7 @@ void SpellAuraHolder::_RemoveSpellAuraHolder() // Conflagrate aura state on Immolate and Shadowflame, if (m_spellProto->IsFitToFamilyMask(UI64LIT(0x0000000000000004), 0x00000002)) { - removeFamilyFlag = UI64LIT(0x0000000000000004); - removeFamilyFlag2 = 0x00000002; + removeFamilyFlag = ClassFamilyMask(UI64LIT(0x0000000000000004), 0x00000002); removeState = AURA_STATE_CONFLAGRATE; } break; @@ -8648,7 +8625,7 @@ void SpellAuraHolder::_RemoveSpellAuraHolder() removeState = AURA_STATE_FAERIE_FIRE; // Faerie Fire (druid versions) else if (m_spellProto->IsFitToFamilyMask(UI64LIT(0x0000000000000050))) { - removeFamilyFlag = 0x50; + removeFamilyFlag = ClassFamilyMask(UI64LIT(0x00000000000050)); removeState = AURA_STATE_SWIFTMEND; // Swiftmend aura state } break; @@ -8673,7 +8650,7 @@ void SpellAuraHolder::_RemoveSpellAuraHolder() for (Unit::SpellAuraHolderMap::const_iterator i = holders.begin(); i != holders.end(); ++i) { SpellEntry const *auraSpellInfo = (*i).second->GetSpellProto(); - if (auraSpellInfo->IsFitToFamily(SpellFamily(m_spellProto->SpellFamilyName), removeFamilyFlag, removeFamilyFlag2)) + if (auraSpellInfo->IsFitToFamily(SpellFamily(m_spellProto->SpellFamilyName), removeFamilyFlag)) { found = true; break; diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index acb36d715..c1c8a381d 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -441,7 +441,7 @@ class MANGOS_DLL_SPEC Aura void TriggerSpell(); void TriggerSpellWithValue(); - uint32 const *getAuraSpellClassMask() const { return m_spellAuraHolder->GetSpellProto()->GetEffectSpellClassMask(m_effIndex); } + ClassFamilyMask const& GetAuraSpellClassMask() const { return m_spellAuraHolder->GetSpellProto()->GetEffectSpellClassMask(m_effIndex); } bool isAffectedOnSpell(SpellEntry const *spell) const; bool CanProcFrom(SpellEntry const *spell, uint32 EventProcEx, uint32 procEx, bool active, bool useClassMask) const; diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 82edd35dd..03631e4c1 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -6061,7 +6061,7 @@ void Spell::EffectWeaponDmg(SpellEffectIndex eff_idx) ((Player*)m_caster)->AddComboPoints(unitTarget, 1); } // Mangle (Cat): CP - else if (m_spellInfo->SpellFamilyName==SPELLFAMILY_DRUID && (m_spellInfo->SpellFamilyFlags==UI64LIT(0x0000040000000000))) + else if (m_spellInfo->IsFitToFamily(SPELLFAMILY_DRUID, UI64LIT(0x0000040000000000))) { if(m_caster->GetTypeId()==TYPEID_PLAYER) ((Player*)m_caster)->AddComboPoints(unitTarget, 1); @@ -7494,8 +7494,8 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) continue; // Search only Serpent Sting, Viper Sting, Scorpid Sting auras - uint64 familyFlag = holder->GetSpellProto()->SpellFamilyFlags; - if (!(familyFlag & UI64LIT(0x000000800000C000))) + ClassFamilyMask const& familyFlag = holder->GetSpellProto()->SpellFamilyFlags; + if (!familyFlag.IsFitToFamilyMask(UI64LIT(0x000000800000C000))) continue; // Refresh aura duration @@ -7507,7 +7507,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) continue; // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting. - if ((familyFlag & UI64LIT(0x0000000000004000))) + if (familyFlag.IsFitToFamilyMask(UI64LIT(0x0000000000004000))) { // m_amount already include RAP bonus basePoint = aura->GetModifier()->m_amount * aura->GetAuraMaxTicks() * 40 / 100; @@ -7515,7 +7515,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) } // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting. - if ((familyFlag & UI64LIT(0x0000008000000000))) + if (familyFlag.IsFitToFamilyMask(UI64LIT(0x0000008000000000))) { uint32 target_max_mana = unitTarget->GetMaxPower(POWER_MANA); if (!target_max_mana) @@ -7538,7 +7538,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) } // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute. - if (familyFlag & UI64LIT(0x0000000000008000)) + if (familyFlag.IsFitToFamilyMask(UI64LIT(0x0000000000008000))) spellId = 53359; // Chimera Shot - Scorpid // ?? nothing say in spell desc (possibly need addition check) //if ((familyFlag & UI64LIT(0x0000010000000000)) || // dot @@ -7743,11 +7743,10 @@ void Spell::EffectSanctuary(SpellEffectIndex /*eff_idx*/) unitTarget->CombatStop(); unitTarget->getHostileRefManager().deleteReferences(); // stop all fighting + // Vanish allows to remove all threat and cast regular stealth so other spells can be used - if(m_spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (m_spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE_VANISH)) - { + if (m_spellInfo->IsFitToFamily(SPELLFAMILY_ROGUE, UI64LIT(0x0000000000000800))) ((Player *)m_caster)->RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT); - } } void Spell::EffectAddComboPoints(SpellEffectIndex /*eff_idx*/) diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 737b62c66..f2e411718 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -1164,13 +1164,7 @@ struct DoSpellProcEvent { if (spe.spellFamilyMask[i] != r_spe.spellFamilyMask[i]) { - sLog.outErrorDb("Spell %u listed in `spell_proc_event` as custom rank have different spellFamilyMask from first rank in chain", spell_id); - break; - } - - if (spe.spellFamilyMask2[i] != r_spe.spellFamilyMask2[i]) - { - sLog.outErrorDb("Spell %u listed in `spell_proc_event` as custom rank have different spellFamilyMask2 from first rank in chain", spell_id); + sLog.outErrorDb("Spell %u listed in `spell_proc_event` as custom rank have different spellFamilyMask/spellFamilyMask2 from first rank in chain", spell_id); break; } } @@ -1244,11 +1238,11 @@ struct DoSpellProcEvent bool empty = !spe.spellFamilyName ? true : false; for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) { - if (spe.spellFamilyMask[i] || spe.spellFamilyMask2[i]) + if (spe.spellFamilyMask[i]) { empty = false; - uint32 const* ptr = spell->GetEffectSpellClassMask(SpellEffectIndex(i)); - if ((((uint64*)ptr)[0] != 0 && spe.spellFamilyMask[i] == ((uint64*)ptr)[0]) && (ptr[2] == 0 || spe.spellFamilyMask2[i] == ptr[2])) + ClassFamilyMask const& mask = spell->GetEffectSpellClassMask(SpellEffectIndex(i)); + if (mask == spe.spellFamilyMask[i]) sLog.outErrorDb("Spell %u listed in `spell_proc_event` has same class mask as in Spell.dbc (EffectIndex %u) and doesn't have any other data", spell->Id, i); } } @@ -1304,8 +1298,9 @@ void SpellMgr::LoadSpellProcEvents() for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) { - spe.spellFamilyMask[i] = (uint64)fields[i+3].GetUInt32()|((uint64)fields[i+6].GetUInt32()<<32); - spe.spellFamilyMask2[i] = fields[i+9].GetUInt32(); + spe.spellFamilyMask[i] = ClassFamilyMask( + (uint64)fields[i+3].GetUInt32() | ((uint64)fields[i+6].GetUInt32()<<32), + fields[i+9].GetUInt32()); } spe.procFlags = fields[12].GetUInt32(); spe.procEx = fields[13].GetUInt32(); @@ -1827,19 +1822,14 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons SpellEntry const *spellInfo_1 = sSpellStore.LookupEntry(spellId_1); SpellEntry const *spellInfo_2 = sSpellStore.LookupEntry(spellId_2); - if(!spellInfo_1 || !spellInfo_2) + if (!spellInfo_1 || !spellInfo_2) return false; - if(spellId_1 == spellId_2) - return false; - - //I think we don't check this correctly because i need a exception for spell: - //72,11327,18461...(called from 1856,1857...) Call Aura 16,31, after trigger another spell who call aura 77 and 77 remove 16 and 31, this should not happen. - if(spellInfo_2->SpellFamilyFlags == 2048) + if (spellId_1 == spellId_2) return false; // Resurrection sickness - if((spellInfo_1->Id == SPELL_ID_PASSIVE_RESURRECTION_SICKNESS) != (spellInfo_2->Id==SPELL_ID_PASSIVE_RESURRECTION_SICKNESS)) + if ((spellInfo_1->Id == SPELL_ID_PASSIVE_RESURRECTION_SICKNESS) != (spellInfo_2->Id==SPELL_ID_PASSIVE_RESURRECTION_SICKNESS)) return false; // Allow stack passive and not passive spells @@ -2255,8 +2245,8 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons return true; // Swift Retribution / Improved Devotion Aura (talents) and Paladin Auras - if (((spellInfo_1->SpellFamilyFlags2 & 0x00000020) && (spellInfo_2->SpellIconID == 291 || spellInfo_2->SpellIconID == 3028)) || - ((spellInfo_2->SpellFamilyFlags2 & 0x00000020) && (spellInfo_1->SpellIconID == 291 || spellInfo_1->SpellIconID == 3028))) + if ((spellInfo_1->IsFitToFamilyMask(UI64LIT(0x0), 0x00000020) && (spellInfo_2->SpellIconID == 291 || spellInfo_2->SpellIconID == 3028)) || + (spellInfo_2->IsFitToFamilyMask(UI64LIT(0x0), 0x00000020) && (spellInfo_1->SpellIconID == 291 || spellInfo_1->SpellIconID == 3028))) return false; // Beacon of Light and Light's Beacon @@ -2302,7 +2292,7 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons { // Windfury weapon if (spellInfo_1->SpellIconID==220 && spellInfo_2->SpellIconID==220 && - spellInfo_1->SpellFamilyFlags != spellInfo_2->SpellFamilyFlags) + !spellInfo_1->IsFitToFamilyMask(spellInfo_2->SpellFamilyFlags)) return false; // Ghost Wolf @@ -4107,7 +4097,7 @@ void SpellMgr::CheckUsedSpells(char const* table) { if(familyMaskA == UI64LIT(0x0000000000000000) && familyMaskB == 0x00000000) { - if(spellEntry->SpellFamilyFlags != 0 || spellEntry->SpellFamilyFlags2 != 0) + if (spellEntry->SpellFamilyFlags) { sLog.outError("Spell %u '%s' not fit to (" I64FMT "," I32FMT ") but used in %s.", spell, name.c_str(), familyMaskA, familyMaskB, code.c_str()); @@ -4117,7 +4107,7 @@ void SpellMgr::CheckUsedSpells(char const* table) } else { - if((spellEntry->SpellFamilyFlags & familyMaskA)==0 && (spellEntry->SpellFamilyFlags2 & familyMaskB)==0) + if (!spellEntry->IsFitToFamilyMask(familyMaskA, familyMaskB)) { sLog.outError("Spell %u '%s' not fit to (" I64FMT "," I32FMT ") but used in %s.",spell,name.c_str(),familyMaskA,familyMaskB,code.c_str()); continue; @@ -4192,12 +4182,12 @@ void SpellMgr::CheckUsedSpells(char const* table) { if(familyMaskA == UI64LIT(0x0000000000000000) && familyMaskB == 0x00000000) { - if(spellEntry->SpellFamilyFlags != 0 || spellEntry->SpellFamilyFlags2 != 0) + if (spellEntry->SpellFamilyFlags) continue; } else { - if ((spellEntry->SpellFamilyFlags & familyMaskA)==0 && (spellEntry->SpellFamilyFlags2 & familyMaskB)==0) + if (!spellEntry->IsFitToFamilyMask(familyMaskA, familyMaskB)) continue; } } diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index ac9e849c7..66292a243 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -47,17 +47,6 @@ enum SpellCategories SPELLCATEGORY_JUDGEMENT = 1210, // Judgement (seal trigger) }; -//Some SpellFamilyFlags -#define SPELLFAMILYFLAG_ROGUE_VANISH UI64LIT(0x0000000000000800) -#define SPELLFAMILYFLAG_ROGUE_STEALTH UI64LIT(0x0000000000400000) -#define SPELLFAMILYFLAG_ROGUE_BACKSTAB UI64LIT(0x0000000000800004) -#define SPELLFAMILYFLAG_ROGUE_SAP UI64LIT(0x0000000000000080) -#define SPELLFAMILYFLAG_ROGUE_FEINT UI64LIT(0x0000000008000000) -#define SPELLFAMILYFLAG_ROGUE_KIDNEYSHOT UI64LIT(0x0000000000200000) -#define SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE UI64LIT(0x00000009003E0000) - -#define SPELLFAMILYFLAG_PALADIN_SEALS UI64LIT(0x26000C000A000000) - // Spell clasification enum SpellSpecific { @@ -179,8 +168,7 @@ bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 spellId_2); inline bool IsSealSpell(SpellEntry const *spellInfo) { //Collection of all the seal family flags. No other paladin spell has any of those. - return spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && - ( spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_PALADIN_SEALS ) && + return spellInfo->IsFitToFamily(SPELLFAMILY_PALADIN, UI64LIT(0x26000C000A000000)) && // avoid counting target triggered effect as seal for avoid remove it or seal by it. spellInfo->EffectImplicitTargetA[EFFECT_INDEX_0] == TARGET_SELF; } @@ -618,8 +606,7 @@ struct SpellProcEventEntry { uint32 schoolMask; // if nonzero - bit mask for matching proc condition based on spell candidate's school: Fire=2, Mask=1<<(2-1)=2 uint32 spellFamilyName; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyNamer value - uint64 spellFamilyMask[MAX_EFFECT_INDEX]; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags (like auras 107 and 108 do) - uint32 spellFamilyMask2[MAX_EFFECT_INDEX]; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags2 (like auras 107 and 108 do) + ClassFamilyMask spellFamilyMask[MAX_EFFECT_INDEX]; // if nonzero - for matching proc condition based on candidate spell's SpellFamilyFlags (like auras 107 and 108 do) uint32 procFlags; // bitmask for matching proc event uint32 procEx; // proc Extend info (see ProcFlagsEx) float ppmRate; // for melee (ranged?) damage spells - proc rate per minute. if zero, falls back to flat chance from Spell.dbc diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index cf715ff2d..1e92106f1 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -2127,7 +2127,7 @@ void Unit::CalculateDamageAbsorbAndResist(Unit *pCaster, SpellSchoolMask schoolM continue; } // Reflective Shield - if (spellProto->SpellFamilyFlags == 0x1 && canReflect) + if (spellProto->IsFitToFamilyMask(UI64LIT(0x0000000000000001)) && canReflect) { if (pCaster == this) break; @@ -9814,9 +9814,9 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag { if (spellProcEvent) { - if (spellProcEvent->spellFamilyMask[i] || spellProcEvent->spellFamilyMask2[i]) + if (spellProcEvent->spellFamilyMask[i]) { - if (!procSpell->IsFitToFamilyMask(spellProcEvent->spellFamilyMask[i], spellProcEvent->spellFamilyMask2[i])) + if (!procSpell->IsFitToFamilyMask(spellProcEvent->spellFamilyMask[i])) continue; } // don't check dbc FamilyFlags if schoolMask exists diff --git a/src/game/UnitAuraProcHandler.cpp b/src/game/UnitAuraProcHandler.cpp index b9d22124d..c5e5b81ca 100644 --- a/src/game/UnitAuraProcHandler.cpp +++ b/src/game/UnitAuraProcHandler.cpp @@ -1154,7 +1154,7 @@ SpellAuraProcResult Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura case SPELLFAMILY_WARRIOR: { // Retaliation - if (dummySpell->SpellFamilyFlags == UI64LIT(0x0000000800000000)) + if (dummySpell->IsFitToFamilyMask(UI64LIT(0x0000000800000000))) { // check attack comes not from behind if (!HasInArc(M_PI_F, pVictim)) @@ -3796,7 +3796,7 @@ SpellAuraProcResult Unit::HandleMendingAuraProc( Unit* /*pVictim*/, uint32 /*dam if(Player* target = ((Player*)this)->GetNextRandomRaidMember(radius)) { // aura will applied from caster, but spell casted from current aura holder - SpellModifier *mod = new SpellModifier(SPELLMOD_CHARGES,SPELLMOD_FLAT,jumps-5,spellProto->Id,spellProto->SpellFamilyFlags,spellProto->SpellFamilyFlags2); + SpellModifier *mod = new SpellModifier(SPELLMOD_CHARGES,SPELLMOD_FLAT,jumps-5,spellProto->Id,spellProto->SpellFamilyFlags); // remove before apply next (locked against deleted) triggeredByAura->SetInUse(true); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 215e5e209..1823ff2b2 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "11622" + #define REVISION_NR "11623" #endif // __REVISION_NR_H__