diff --git a/src/game/Player.cpp b/src/game/Player.cpp index a37a7634a..b7909f51c 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2339,6 +2339,9 @@ void Player::InitStatsForLevel(bool reapplyMods) SetFloatValue(UNIT_FIELD_POWER_COST_MODIFIER+i,0.0f); SetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+i,0.0f); } + // Reset no reagent cost field + for(int i = 0; i < 3; i++) + SetUInt32Value(PLAYER_NO_REAGENT_COST_1 + i, 0); // Init data for form but skip reapply item mods for form InitDataForForm(reapplyMods); @@ -18353,6 +18356,21 @@ bool Player::HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item cons return false; } +bool Player::CanNoReagentCast(SpellEntry const* spellInfo) +{ + // don't take reagents for spells with SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP + if (spellInfo->AttributesEx5 & SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP && + HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION)) + return true; + // Check no reagent use mask + uint64 noReagentMask_0_1 = GetUInt64Value(PLAYER_NO_REAGENT_COST_1); + uint32 noReagentMask_2 = GetUInt64Value(PLAYER_NO_REAGENT_COST_1+2); + if (spellInfo->SpellFamilyFlags & noReagentMask_0_1 || + spellInfo->SpellFamilyFlags2 & noReagentMask_2) + return true; + return false; +} + void Player::RemoveItemDependentAurasAndCasts( Item * pItem ) { AuraMap& auras = GetAuras(); diff --git a/src/game/Player.h b/src/game/Player.h index ba9c251c1..86c425b6b 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1102,6 +1102,7 @@ class MANGOS_DLL_SPEC Player : public Unit bool HasBankBagSlot( uint8 slot ) const; bool HasItemCount( uint32 item, uint32 count, bool inBankAlso = false ) const; bool HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item const* ignoreItem = NULL); + bool CanNoReagentCast(SpellEntry const* spellInfo); Item* GetItemOrItemWithGemEquipped( uint32 item ) const; uint8 CanTakeMoreSimilarItems(Item* pItem) const { return _CanTakeMoreSimilarItems(pItem->GetEntry(),pItem->GetCount(),pItem); } uint8 CanTakeMoreSimilarItems(uint32 entry, uint32 count) const { return _CanTakeMoreSimilarItems(entry,count,NULL); } diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 297ddf6be..44d5ce31d 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -3260,11 +3260,9 @@ void Spell::TakeReagents() if (m_caster->GetTypeId() != TYPEID_PLAYER) return; - if (m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP && - m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION)) - return; - Player* p_caster = (Player*)m_caster; + if (p_caster->CanNoReagentCast(m_spellInfo)) + return; for(uint32 x=0;x<8;x++) { @@ -4693,8 +4691,11 @@ uint8 Spell::CheckItems() focusObject = ok; // game object found in range } - if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP && - m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION))) + bool needReagentCheck = true; + if (m_caster->GetTypeId() == TYPEID_PLAYER && ((Player*)m_caster)->CanNoReagentCast(m_spellInfo)) + needReagentCheck = false; + + if (needReagentCheck) { for(uint32 i=0;i<8;i++) { diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h index f0100f8d7..cb5951a5f 100644 --- a/src/game/SpellAuraDefines.h +++ b/src/game/SpellAuraDefines.h @@ -295,17 +295,17 @@ enum AuraType SPELL_AURA_MOD_INCREASE_HEALTH_2 = 250, SPELL_AURA_MOD_ENEMY_DODGE = 251, SPELL_AURA_252 = 252, - SPELL_AURA_253 = 253, - SPELL_AURA_254 = 254, - SPELL_AURA_255 = 255, - SPELL_AURA_256 = 256, - SPELL_AURA_257 = 257, + SPELL_AURA_MOD_BLOCK_CRIT_CHANCE = 253, + SPELL_AURA_MOD_DISARM_SHIELD = 254, + SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT = 255, + SPELL_AURA_NO_REAGENT_USE = 256, + SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS = 257, SPELL_AURA_258 = 258, SPELL_AURA_259 = 259, SPELL_AURA_260 = 260, SPELL_AURA_261 = 261, SPELL_AURA_262 = 262, - SPELL_AURA_263 = 263, + SPELL_AURA_ALLOW_ONLY_ABILITY = 263, SPELL_AURA_264 = 264, SPELL_AURA_265 = 265, SPELL_AURA_266 = 266, @@ -318,11 +318,11 @@ enum AuraType SPELL_AURA_273 = 273, SPELL_AURA_274 = 274, SPELL_AURA_275 = 275, - SPELL_AURA_276 = 276, // Only "Test Mod Damage % Mechanic" spell + SPELL_AURA_276 = 276, // Only "Test Mod Damage % Mechanic" spell, possible mod damage done SPELL_AURA_277 = 277, - SPELL_AURA_278 = 278, + SPELL_AURA_MOD_DISARM_RANGED = 278, SPELL_AURA_279 = 279, - SPELL_AURA_280 = 280, + SPELL_AURA_MOD_TARGET_ARMOR_PCT = 280, SPELL_AURA_MOD_HONOR_GAIN = 281, SPELL_AURA_MOD_BASE_HEALTH_PCT = 282, SPELL_AURA_MOD_HEALING_RECEIVED = 283, // Possibly only for some spell family class spells diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index fb6fe333a..809ee2462 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -296,42 +296,42 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleUnused, //243 used by two test spells &Aura::HandleComprehendLanguage, //244 Comprehend language &Aura::HandleUnused, //245 SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS - &Aura::HandleUnused, //246 unused + &Aura::HandleUnused, //246 SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL &Aura::HandleUnused, //247 unused &Aura::HandleNoImmediateEffect, //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst &Aura::HandleAuraConvertRune, //249 SPELL_AURA_CONVERT_RUNE &Aura::HandleAuraModIncreaseHealth, //250 SPELL_AURA_MOD_INCREASE_HEALTH_2 &Aura::HandleNULL, //251 SPELL_AURA_MOD_ENEMY_DODGE - &Aura::HandleNULL, //252 - &Aura::HandleNULL, //253 - &Aura::HandleNULL, //254 - &Aura::HandleNULL, //255 SPELL_AURA_MOD_DAMAGE_PERCENT_MECHANIC - &Aura::HandleNULL, //256 - &Aura::HandleNULL, //257 SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS + &Aura::HandleNULL, //252 haste all? + &Aura::HandleNULL, //253 SPELL_AURA_MOD_BLOCK_CRIT_CHANCE + &Aura::HandleNULL, //254 SPELL_AURA_MOD_DISARM_SHIELD disarm Shield + &Aura::HandleNULL, //255 SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT + &Aura::HandleNoReagentUseAura, //256 SPELL_AURA_NO_REAGENT_USE Use SpellClassMask for spell select + &Aura::HandleNULL, //257 SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS Use SpellClassMask for spell select &Aura::HandleNULL, //258 SPELL_AURA_MOD_SPELL_VISUAL &Aura::HandleNULL, //259 corrupt healing over time spell &Aura::HandleNULL, //260 &Aura::HandleNULL, //261 out of phase? &Aura::HandleNULL, //262 - &Aura::HandleNULL, //263 melee AOE + &Aura::HandleNULL, //263 SPELL_AURA_ALLOW_ONLY_ABILITY player can use only abilites set in SpellClassMask &Aura::HandleNULL, //264 unused &Aura::HandleNULL, //265 unused &Aura::HandleNULL, //266 unused &Aura::HandleNULL, //267 some immunity? - &Aura::HandleNULL, //268 attack power from stat X + &Aura::HandleNULL, //268 SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT &Aura::HandleNULL, //269 ignore DR effects? &Aura::HandleNULL, //270 &Aura::HandleNULL, //271 increase damage done? &Aura::HandleNULL, //272 reduce spell cast time? &Aura::HandleNULL, //273 &Aura::HandleNULL, //274 proc free shot? - &Aura::HandleNULL, //275 ignore shapeshift? + &Aura::HandleNULL, //275 ignore shapeshift Use SpellClassMask for spell select &Aura::HandleNULL, //276 mod damage % mechanic? - &Aura::HandleNULL, //277 increase max targets? - &Aura::HandleNULL, //278 disarm/silence + &Aura::HandleNULL, //277 increase max targets? Use SpellClassMask for spell select + &Aura::HandleNULL, //278 SPELL_AURA_MOD_DISARM_RANGED disarm ranged weapon &Aura::HandleNULL, //279 - &Aura::HandleNULL, //280 ignore armor? - &Aura::HandleNULL, //281 increase honor gain? + &Aura::HandleNULL, //280 SPELL_AURA_MOD_TARGET_ARMOR_PCT + &Aura::HandleNULL, //281 SPELL_AURA_MOD_HONOR_GAIN &Aura::HandleAuraIncreaseBaseHealthPercent, //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT &Aura::HandleNULL //283 SPD/heal from AP? }; @@ -1171,7 +1171,19 @@ void Aura::UpdateSlotCounterAndDuration(bool add) SetAuraCharges(count); SendAuraUpdate(false); } - +bool Aura::isAffectedOnSpell(SpellEntry const *spell) +{ + // Check family name + if (spell->SpellFamilyName != m_spellProto->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; +} /*********************************************************/ /*** BASIC AURA FUNCTION ***/ /*********************************************************/ @@ -5192,6 +5204,28 @@ void Aura::HandleModPowerCost(bool apply, bool Real) m_target->ApplyModInt32Value(UNIT_FIELD_POWER_COST_MODIFIER+i,m_modifier.m_amount,apply); } +void Aura::HandleNoReagentUseAura(bool Apply, bool Real) +{ + // spells required only Real aura add/remove + if(!Real) + return; + if(m_target->GetTypeId() != TYPEID_PLAYER) + return; + uint32 mask[3] = {0, 0, 0}; + Unit::AuraList const& noReagent = m_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]; + } + + m_target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1 , mask[0]); + m_target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+1, mask[1]); + m_target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+2, mask[2]); +} + /*********************************************************/ /*** OTHERS ***/ /*********************************************************/ diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index 09ee97eb5..387b0a36c 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -211,6 +211,7 @@ class MANGOS_DLL_SPEC Aura void HandleArenaPreparation(bool apply, bool Real); void HandleAuraConvertRune(bool apply, bool Real); void HandleAuraIncreaseBaseHealthPercent(bool Apply, bool Real); + void HandleNoReagentUseAura(bool Apply, bool Real); virtual ~Aura(); @@ -302,6 +303,9 @@ class MANGOS_DLL_SPEC Aura void PeriodicTick(); void PeriodicDummyTick(); + + inline uint32 const *getAuraSpellClassMask() {return m_spellProto->EffectSpellClassMaskA + m_effIndex * 3; } + bool isAffectedOnSpell(SpellEntry const *spell); protected: Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster = NULL, Item* castItem = NULL);