Index: game/Creature.cpp =================================================================== --- game/Creature.cpp (revision 4909) +++ game/Creature.cpp (working copy) @@ -1542,32 +1542,45 @@ } } -bool Creature::IsImmunedToSpell(SpellEntry const* spellInfo) const +bool Creature::BossImmuneMechanic( Mechanics Mechanic ) const { + switch ( Mechanic ) + { + case MECHANIC_CHARM: + case MECHANIC_CONFUSED: + case MECHANIC_DISTRACT: + case MECHANIC_FEAR: + case MECHANIC_ROOT: + case MECHANIC_SILENCE: + case MECHANIC_SLEEP: + case MECHANIC_SNARE: + case MECHANIC_STUN: + case MECHANIC_FREEZE: + case MECHANIC_KNOCKOUT: + case MECHANIC_POLYMORPH: + case MECHANIC_BANISH: + case MECHANIC_SHACKLE: + case MECHANIC_TURN: + case MECHANIC_HORROR: + case MECHANIC_DAZE: + return true; + default: + return false; + } +} + +bool Creature::IsImmunedToSpell(SpellEntry const* spellInfo, uint32 eff) const +{ if (!spellInfo) return false; - if( isWorldBoss() && ( - (MECHANIC_CHARM == spellInfo->Mechanic) || - (MECHANIC_CONFUSED == spellInfo->Mechanic) || - (MECHANIC_DISTRACT == spellInfo->Mechanic) || - (MECHANIC_FEAR == spellInfo->Mechanic) || - (MECHANIC_ROOT == spellInfo->Mechanic) || - (MECHANIC_SILENCE == spellInfo->Mechanic) || - (MECHANIC_SLEEP == spellInfo->Mechanic) || - (MECHANIC_SNARE == spellInfo->Mechanic) || - (MECHANIC_STUN == spellInfo->Mechanic) || - (MECHANIC_FREEZE == spellInfo->Mechanic) || - (MECHANIC_KNOCKOUT == spellInfo->Mechanic) || - (MECHANIC_POLYMORPH == spellInfo->Mechanic) || - (MECHANIC_BANISH == spellInfo->Mechanic) || - (MECHANIC_SHACKLE == spellInfo->Mechanic) || - (MECHANIC_TURN == spellInfo->Mechanic) || - (MECHANIC_HORROR == spellInfo->Mechanic) || - (MECHANIC_DAZE == spellInfo->Mechanic) )) - return true; + if( isWorldBoss()) + { + if ( BossImmuneMechanic(Mechanics(spellInfo->Mechanic)) || BossImmuneMechanic(Mechanics(spellInfo->EffectMechanic[eff]))) + return true; + } - return Unit::IsImmunedToSpell(spellInfo); + return Unit::IsImmunedToSpell(spellInfo, eff); } SpellEntry const *Creature::reachWithSpellAttack(Unit *pVictim) Index: game/Creature.h =================================================================== --- game/Creature.h (revision 4909) +++ game/Creature.h (working copy) @@ -331,7 +331,8 @@ bool isCanIneractWithBattleMaster(Player* player, bool msg) const; bool isCanTrainingAndResetTalentsOf(Player* pPlayer) const; bool IsOutOfThreatArea(Unit* pVictim) const; - bool IsImmunedToSpell(SpellEntry const* spellInfo) const; + bool IsImmunedToSpell(SpellEntry const* spellInfo, uint32 eff) const; + bool BossImmuneMechanic( Mechanics Mechanic ) const; // redefine Unit::IsImmunedTo bool isElite() const { Index: game/Spell.cpp =================================================================== --- game/Spell.cpp (revision 4909) +++ game/Spell.cpp (working copy) @@ -2524,8 +2524,11 @@ if(IsPositiveSpell(m_spellInfo->Id)) { - if(target->IsImmunedToSpell(m_spellInfo)) - return SPELL_FAILED_TARGET_AURASTATE; + for ( uint32 i=0; i<3;i++) + { + if(target->IsImmunedToSpell(m_spellInfo,i)) + return SPELL_FAILED_TARGET_AURASTATE; + } } /* Causes problems with berserking @@ -3179,7 +3182,9 @@ if(itr->second) { if( ((1 << itr->second->GetSpellProto()->School) & school_immune) || - ((1 << itr->second->GetSpellProto()->Mechanic) & mechanic_immune) ) + ((1 << itr->second->GetSpellProto()->Mechanic) & mechanic_immune) || + ((1 << itr->second->GetSpellProto()->EffectMechanic[itr->second->GetEffIndex()]) & mechanic_immune)) + continue; //Make a second check for spell failed so the right SPELL_FAILED message is returned. @@ -3828,7 +3833,7 @@ return false; //Check targets for immune and remove immunes targets - if (hitPhase && target->IsImmunedToSpell(m_spellInfo)) + if (hitPhase && target->IsImmunedToSpell(m_spellInfo, eff)) { // FIXME: this must be spell immune message instead melee attack message m_caster->SendAttackStateUpdate(HITINFO_NOACTION, target, 1, SpellSchools(m_spellInfo->School), 0, 0, 0, VICTIMSTATE_IS_IMMUNE, 0); Index: game/SpellAuras.cpp =================================================================== --- game/SpellAuras.cpp (revision 4909) +++ game/SpellAuras.cpp (working copy) @@ -1972,7 +1972,9 @@ // Rogue/Blind ability stops attack // TODO: does all confuses ? - if ( caster && (GetSpellProto()->Mechanic == MECHANIC_CONFUSED) && (GetSpellProto()->SpellFamilyName == SPELLFAMILY_ROGUE)) + if ( caster && (GetSpellProto()->Mechanic == MECHANIC_CONFUSED || + GetSpellProto()->EffectMechanic[GetEffIndex()] == MECHANIC_CONFUSED ) && + (GetSpellProto()->SpellFamilyName == SPELLFAMILY_ROGUE)) caster->AttackStop(); // only at real add aura if(Real) @@ -1980,7 +1982,9 @@ //This fixes blind so it doesn't continue to attack // TODO: may other spells casted confuse aura (but not all) stop attack if( caster && caster->GetTypeId() == TYPEID_PLAYER && - GetSpellProto()->Mechanic == MECHANIC_CONFUSED && GetSpellProto()->SpellFamilyName == SPELLFAMILY_ROGUE ) + (GetSpellProto()->Mechanic == MECHANIC_CONFUSED || + GetSpellProto()->EffectMechanic[GetEffIndex()] == MECHANIC_CONFUSED ) && + GetSpellProto()->SpellFamilyName == SPELLFAMILY_ROGUE ) { caster->AttackStop(); } @@ -2165,7 +2169,8 @@ if (caster) { // Stop attack if spell has knockout effect - if(GetSpellProto()->Mechanic == MECHANIC_KNOCKOUT) + if(GetSpellProto()->Mechanic == MECHANIC_KNOCKOUT || + GetSpellProto()->EffectMechanic[GetEffIndex()] == MECHANIC_KNOCKOUT ) caster->AttackStop(); } @@ -2662,17 +2667,20 @@ next = iter; next++; SpellEntry const *spell = iter->second->GetSpellProto(); - if( (1<Mechanic) & mechanic //check for mechanic mask - && !( spell->Attributes & 0x20000000) //spells unaffected by invulnerability - && !iter->second->IsPositive() //only remove negative spells + if (!( spell->Attributes & 0x20000000) //spells unaffected by invulnerability + && !iter->second->IsPositive() //only remove negative spells && spell->Id != GetId()) - { - m_target->RemoveAurasDueToSpell(spell->Id); - if(Auras.empty()) - break; - else - next = Auras.begin(); - } + { + if( ((1<Mechanic) & mechanic) || + ((1<EffectMechanic[iter->second->GetEffIndex()]) & mechanic)) //check for mechanic mask + { + m_target->RemoveAurasDueToSpell(spell->Id); + if(Auras.empty()) + break; + else + next = Auras.begin(); + } + } } } Index: game/SpellEffects.cpp =================================================================== --- game/SpellEffects.cpp (revision 4909) +++ game/SpellEffects.cpp (working copy) @@ -1330,21 +1330,26 @@ if(mech == DIMINISHING_NONE) { - switch(m_spellInfo->EffectApplyAuraName[i]) - { - case SPELL_AURA_MOD_CONFUSE: - mech = DIMINISHING_MECHANIC_CONFUSE; break; - case SPELL_AURA_MOD_CHARM: - case SPELL_AURA_MOD_FEAR: - mech = DIMINISHING_MECHANIC_CHARM; break; - case SPELL_AURA_MOD_STUN: - mech = DIMINISHING_MECHANIC_STUN; break; - case SPELL_AURA_MOD_ROOT: - mech = DIMINISHING_MECHANIC_ROOT; break; - case SPELL_AURA_MOD_DECREASE_SPEED: - mech = DIMINISHING_MECHANIC_SNARE; break; - default: break; - } + mech = Unit::Mechanic2DiminishingMechanics(Aur->GetSpellProto()->EffectMechanic[i]); + + if ( mech == DIMINISHING_NONE ) + { + switch(m_spellInfo->EffectApplyAuraName[i]) + { + case SPELL_AURA_MOD_CONFUSE: + mech = DIMINISHING_MECHANIC_CONFUSE; break; + case SPELL_AURA_MOD_CHARM: + case SPELL_AURA_MOD_FEAR: + mech = DIMINISHING_MECHANIC_CHARM; break; + case SPELL_AURA_MOD_STUN: + mech = DIMINISHING_MECHANIC_STUN; break; + case SPELL_AURA_MOD_ROOT: + mech = DIMINISHING_MECHANIC_ROOT; break; + case SPELL_AURA_MOD_DECREASE_SPEED: + mech = DIMINISHING_MECHANIC_SNARE; break; + default: break; + } + } } // Death Coil and Curse of Exhaustion are not diminished. @@ -4015,7 +4020,8 @@ next = iter; next++; SpellEntry const *spell = sSpellStore.LookupEntry(iter->second->GetSpellProto()->Id); - if(spell->Mechanic == mechanic) + if(spell->Mechanic == mechanic || + spell->EffectMechanic[iter->second->GetEffIndex()] == mechanic ) { unitTarget->RemoveAurasDueToSpell(spell->Id); if(Auras.empty()) Index: game/Unit.cpp =================================================================== --- game/Unit.cpp (revision 4909) +++ game/Unit.cpp (working copy) @@ -3603,9 +3603,13 @@ Aura* Aur = i->second; DiminishingMechanics mech = DIMINISHING_NONE; - if(Aur->GetSpellProto()->Mechanic) + if(Aur->GetSpellProto()->Mechanic || Aur->GetSpellProto()->EffectMechanic[Aur->GetEffIndex()]) { mech = Unit::Mechanic2DiminishingMechanics(Aur->GetSpellProto()->Mechanic); + + if ( mech == DIMINISHING_NONE ) + mech = Unit::Mechanic2DiminishingMechanics(Aur->GetSpellProto()->EffectMechanic[Aur->GetEffIndex()]); + if(mech == DIMINISHING_MECHANIC_STUN || GetTypeId() == TYPEID_PLAYER && mech != DIMINISHING_NONE) UpdateDiminishingTime(mech); } @@ -5522,7 +5526,7 @@ return false; } -bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo) const +bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo, uint32 eff) const { if (!spellInfo) return false; @@ -5534,7 +5538,7 @@ SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC]; for(SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr) - if(itr->type == spellInfo->Mechanic) + if(itr->type == spellInfo->Mechanic || itr->type == spellInfo->EffectMechanic[eff]) return true; if( !(spellInfo->AttributesEx & 0x10000)) // unaffected by school immunity @@ -5549,7 +5553,8 @@ int32 chance = 0; AuraList const& mModMechanicRes = GetAurasByType(SPELL_AURA_MOD_MECHANIC_RESISTANCE); for(AuraList::const_iterator i = mModMechanicRes.begin();i != mModMechanicRes.end(); ++i) - if((*i)->GetModifier()->m_miscvalue == int32(spellInfo->Mechanic)) + if((*i)->GetModifier()->m_miscvalue == int32(spellInfo->Mechanic) || + (*i)->GetModifier()->m_miscvalue == int32(spellInfo->EffectMechanic[eff])) chance+= (*i)->GetModifier()->m_amount; if(roll_chance_i(chance)) return true; @@ -6676,7 +6681,8 @@ int32 durationMod = 0; AuraList const& mMechanicMod = GetAurasByType(SPELL_AURA_MECHANIC_DURATION_MOD); for(AuraList::const_iterator i = mMechanicMod.begin();i != mMechanicMod.end(); ++i) - if((*i)->GetModifier()->m_miscvalue == int32(spellProto->Mechanic)) + if((*i)->GetModifier()->m_miscvalue == int32(spellProto->Mechanic) || + (*i)->GetModifier()->m_miscvalue ==int32(spellProto->EffectMechanic[effect_index]) ) durationMod+= (*i)->GetModifier()->m_amount; *duration = *duration * (100+durationMod) /100; if (*duration < 0) *duration = 0; Index: game/Unit.h =================================================================== --- game/Unit.h (revision 4909) +++ game/Unit.h (working copy) @@ -1128,7 +1128,7 @@ bool SpellCriticalBonus(SpellEntry const *spellProto, uint32 *damage, Unit *pVictim); void MeleeDamageBonus(Unit *pVictim, uint32 *damage, WeaponAttackType attType); void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply); - virtual bool IsImmunedToSpell(SpellEntry const* spellInfo) const; + virtual bool IsImmunedToSpell(SpellEntry const* spellInfo, uint32 eff) const; // redefined in Creature bool IsImmunedToPhysicalDamage() const; bool IsImmunedToSpellDamage(SpellEntry const* spellInfo) const; Index: shared/Database/DBCfmt.cpp =================================================================== --- shared/Database/DBCfmt.cpp (revision 4909) +++ shared/Database/DBCfmt.cpp (working copy) @@ -52,7 +52,7 @@ const char SkillLineAbilityfmt[]="xiniixxiixiixxi"; const char SpellCastTimefmt[]="nixx"; const char SpellDurationfmt[]="niii"; -const char SpellEntryfmt[]="niixiiiiiiixixiiiiixxiiiiiiiiiiiiiiiiiiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiixxxiiiiiiiiiiiiiiifffiiiiiiiiiiiifffixiiissssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiixxfffxxxiii"; +const char SpellEntryfmt[]="niixiiiiiiixixiiiiixxiiiiiiiiiiiiiiiiiiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiifffixiiissssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiixxfffxxxiii"; //const char SpellFocusObjectfmt[]="nsxxxxxxxx"; const char SpellItemEnchantmentfmt[]="niiiiiixxxiiissssssssssssssssxiiii"; const char SpellItemEnchantmentConditionfmt[]="nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX"; Index: shared/Database/DBCStructure.h =================================================================== --- shared/Database/DBCStructure.h (revision 4909) +++ shared/Database/DBCStructure.h (working copy) @@ -457,7 +457,7 @@ float EffectDicePerLevel[3]; //73-75 float EffectRealPointsPerLevel[3]; //76-78 int32 EffectBasePoints[3]; //79-81 (don't must be used in spell/auras explicitly, must be used cached Spell::m_currentBasePoints) - //82-84 not used + uint32 EffectMechanic[3]; //82-84 uint32 EffectImplicitTargetA[3]; //85-87 uint32 EffectImplicitTargetB[3]; //88-90 uint32 EffectRadiusIndex[3]; //91-93 - spellradius.dbc