diff options
Diffstat (limited to 'src/game/SpellEffects.cpp')
| -rw-r--r-- | src/game/SpellEffects.cpp | 2102 | 
1 files changed, 1273 insertions, 829 deletions
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 64b7811d462..3715e5d0b4f 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -1,7 +1,7 @@  /* - * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>   * - * Copyright (C) 2008 Trinity <http://www.trinitycore.org/> + * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License as published by @@ -47,6 +47,7 @@  #include "Creature.h"  #include "Totem.h"  #include "CreatureAI.h" +#include "BattleGroundMgr.h"  #include "BattleGround.h"  #include "BattleGroundEY.h"  #include "BattleGroundWS.h" @@ -60,6 +61,7 @@  #include "CellImpl.h"  #include "GridNotifiers.h"  #include "GridNotifiersImpl.h" +#include "SkillDiscovery.h"  pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=  { @@ -104,8 +106,8 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=      &Spell::EffectDispel,                                   // 38 SPELL_EFFECT_DISPEL      &Spell::EffectUnused,                                   // 39 SPELL_EFFECT_LANGUAGE      &Spell::EffectDualWield,                                // 40 SPELL_EFFECT_DUAL_WIELD -    &Spell::EffectSummonWild,                               // 41 SPELL_EFFECT_SUMMON_WILD -    &Spell::EffectSummonGuardian,                           // 42 SPELL_EFFECT_SUMMON_GUARDIAN +    &Spell::EffectUnused,                                   // 41 SPELL_EFFECT_JUMP +    &Spell::EffectUnused,                                   // 42 SPELL_EFFECT_JUMP2      &Spell::EffectTeleUnitsFaceCaster,                      // 43 SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER      &Spell::EffectLearnSkill,                               // 44 SPELL_EFFECT_SKILL_STEP      &Spell::EffectAddHonor,                                 // 45 SPELL_EFFECT_ADD_HONOR                honor/pvp related @@ -128,16 +130,16 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=      &Spell::EffectPowerBurn,                                // 62 SPELL_EFFECT_POWER_BURN      &Spell::EffectThreat,                                   // 63 SPELL_EFFECT_THREAT      &Spell::EffectTriggerSpell,                             // 64 SPELL_EFFECT_TRIGGER_SPELL -    &Spell::EffectUnused,                                   // 65 SPELL_EFFECT_HEALTH_FUNNEL            unused -    &Spell::EffectUnused,                                   // 66 SPELL_EFFECT_POWER_FUNNEL             unused +    &Spell::EffectApplyAreaAura,                            // 65 SPELL_EFFECT_APPLY_AREA_AURA_RAID +    &Spell::EffectUnused,                                   // 66 SPELL_EFFECT_CREATE_MANA_GEM          (possibly recharge it, misc - is item ID)      &Spell::EffectHealMaxHealth,                            // 67 SPELL_EFFECT_HEAL_MAX_HEALTH      &Spell::EffectInterruptCast,                            // 68 SPELL_EFFECT_INTERRUPT_CAST      &Spell::EffectDistract,                                 // 69 SPELL_EFFECT_DISTRACT      &Spell::EffectPull,                                     // 70 SPELL_EFFECT_PULL                     one spell: Distract Move      &Spell::EffectPickPocket,                               // 71 SPELL_EFFECT_PICKPOCKET      &Spell::EffectAddFarsight,                              // 72 SPELL_EFFECT_ADD_FARSIGHT -    &Spell::EffectSummonPossessed,                          // 73 SPELL_EFFECT_SUMMON_POSSESSED -    &Spell::EffectSummonTotem,                              // 74 SPELL_EFFECT_SUMMON_TOTEM +    &Spell::EffectUnused,                                   // 73 SPELL_EFFECT_UNTRAIN_TALENTS +    &Spell::EffectApplyGlyph,                               // 74 SPELL_EFFECT_APPLY_GLYPH      &Spell::EffectHealMechanical,                           // 75 SPELL_EFFECT_HEAL_MECHANICAL          one spell: Mechanical Patch Kit      &Spell::EffectSummonObjectWild,                         // 76 SPELL_EFFECT_SUMMON_OBJECT_WILD      &Spell::EffectScriptEffect,                             // 77 SPELL_EFFECT_SCRIPT_EFFECT @@ -150,17 +152,17 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=      &Spell::EffectStuck,                                    // 84 SPELL_EFFECT_STUCK      &Spell::EffectSummonPlayer,                             // 85 SPELL_EFFECT_SUMMON_PLAYER      &Spell::EffectActivateObject,                           // 86 SPELL_EFFECT_ACTIVATE_OBJECT -    &Spell::EffectSummonTotem,                              // 87 SPELL_EFFECT_SUMMON_TOTEM_SLOT1 -    &Spell::EffectSummonTotem,                              // 88 SPELL_EFFECT_SUMMON_TOTEM_SLOT2 -    &Spell::EffectSummonTotem,                              // 89 SPELL_EFFECT_SUMMON_TOTEM_SLOT3 -    &Spell::EffectSummonTotem,                              // 90 SPELL_EFFECT_SUMMON_TOTEM_SLOT4 +    &Spell::EffectUnused,                                   // 87 SPELL_EFFECT_WMO_DAMAGE +    &Spell::EffectUnused,                                   // 88 SPELL_EFFECT_WMO_REPAIR +    &Spell::EffectUnused,                                   // 89 SPELL_EFFECT_WMO_CHANGE +    &Spell::EffectUnused,                                   // 90 SPELL_EFFECT_KILL_CREDIT      &Spell::EffectUnused,                                   // 91 SPELL_EFFECT_THREAT_ALL               one spell: zzOLDBrainwash      &Spell::EffectEnchantHeldItem,                          // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM      &Spell::EffectUnused,                                   // 93 SPELL_EFFECT_SUMMON_PHANTASM      &Spell::EffectSelfResurrect,                            // 94 SPELL_EFFECT_SELF_RESURRECT      &Spell::EffectSkinning,                                 // 95 SPELL_EFFECT_SKINNING      &Spell::EffectUnused,                                   // 96 SPELL_EFFECT_CHARGE -    &Spell::EffectSummonCritter,                            // 97 SPELL_EFFECT_SUMMON_CRITTER +    &Spell::EffectUnused,                                   // 97 SPELL_EFFECT_97      &Spell::EffectKnockBack,                                // 98 SPELL_EFFECT_KNOCK_BACK      &Spell::EffectDisEnchant,                               // 99 SPELL_EFFECT_DISENCHANT      &Spell::EffectInebriate,                                //100 SPELL_EFFECT_INEBRIATE @@ -175,7 +177,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=      &Spell::EffectSummonDeadPet,                            //109 SPELL_EFFECT_SUMMON_DEAD_PET      &Spell::EffectDestroyAllTotems,                         //110 SPELL_EFFECT_DESTROY_ALL_TOTEMS      &Spell::EffectDurabilityDamage,                         //111 SPELL_EFFECT_DURABILITY_DAMAGE -    &Spell::EffectSummonDemon,                              //112 SPELL_EFFECT_SUMMON_DEMON +    &Spell::EffectUnused,                                   //112 SPELL_EFFECT_112      &Spell::EffectResurrectNew,                             //113 SPELL_EFFECT_RESURRECT_NEW      &Spell::EffectTaunt,                                    //114 SPELL_EFFECT_ATTACK_ME      &Spell::EffectDurabilityDamagePCT,                      //115 SPELL_EFFECT_DURABILITY_DAMAGE_PCT @@ -195,21 +197,21 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=      &Spell::EffectApplyAreaAura,                            //129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY      &Spell::EffectRedirectThreat,                           //130 SPELL_EFFECT_REDIRECT_THREAT      &Spell::EffectUnused,                                   //131 SPELL_EFFECT_131                      used in some test spells -    &Spell::EffectNULL,                                     //132 SPELL_EFFECT_PLAY_MUSIC               sound id in misc value +    &Spell::EffectNULL,                                     //132 SPELL_EFFECT_PLAY_MUSIC               sound id in misc value (SoundEntries.dbc)      &Spell::EffectUnlearnSpecialization,                    //133 SPELL_EFFECT_UNLEARN_SPECIALIZATION   unlearn profession specialization      &Spell::EffectKillCredit,                               //134 SPELL_EFFECT_KILL_CREDIT              misc value is creature entry      &Spell::EffectNULL,                                     //135 SPELL_EFFECT_CALL_PET      &Spell::EffectHealPct,                                  //136 SPELL_EFFECT_HEAL_PCT      &Spell::EffectEnergisePct,                              //137 SPELL_EFFECT_ENERGIZE_PCT      &Spell::EffectNULL,                                     //138 SPELL_EFFECT_138                      Leap -    &Spell::EffectUnused,                                   //139 SPELL_EFFECT_139                      unused +    &Spell::EffectUnused,                                   //139 SPELL_EFFECT_CLEAR_QUEST              (misc - is quest ID)      &Spell::EffectForceCast,                                //140 SPELL_EFFECT_FORCE_CAST      &Spell::EffectNULL,                                     //141 SPELL_EFFECT_141                      damage and reduce speed?      &Spell::EffectTriggerSpellWithValue,                    //142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE      &Spell::EffectApplyAreaAura,                            //143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER      &Spell::EffectKnockBack,                                //144 SPELL_EFFECT_KNOCK_BACK_2             Spectral Blast      &Spell::EffectNULL,                                     //145 SPELL_EFFECT_145                      Black Hole Effect -    &Spell::EffectUnused,                                   //146 SPELL_EFFECT_146                      unused +    &Spell::EffectActivateRune,                             //146 SPELL_EFFECT_ACTIVATE_RUNE      &Spell::EffectQuestFail,                                //147 SPELL_EFFECT_QUEST_FAIL               quest fail      &Spell::EffectUnused,                                   //148 SPELL_EFFECT_148                      unused      &Spell::EffectNULL,                                     //149 SPELL_EFFECT_149                      swoop @@ -217,6 +219,12 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=      &Spell::EffectTriggerRitualOfSummoning,                 //151 SPELL_EFFECT_TRIGGER_SPELL_2      &Spell::EffectNULL,                                     //152 SPELL_EFFECT_152                      summon Refer-a-Friend      &Spell::EffectNULL,                                     //153 SPELL_EFFECT_CREATE_PET               misc value is creature entry +    &Spell::EffectNULL,                                     //154 unused +    &Spell::EffectTitanGrip,                                //155 SPELL_EFFECT_TITAN_GRIP Allows you to equip two-handed axes, maces and swords in one hand, but you attack $49152s1% slower than normal. +    &Spell::EffectEnchantItemPrismatic,                     //156 SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC +    &Spell::EffectCreateItem2,                              //157 SPELL_EFFECT_CREATE_ITEM_2            create/learn item/spell for profession +    &Spell::EffectMilling,                                  //158 SPELL_EFFECT_MILLING                  milling +    &Spell::EffectRenamePet                                 //159 SPELL_EFFECT_ALLOW_RENAME_PET         allow rename pet once again  };  void Spell::EffectNULL(uint32 /*i*/) @@ -293,7 +301,7 @@ void Spell::EffectEnvirinmentalDMG(uint32 i)      // currently each enemy selected explicitly and self cast damage, we prevent apply self casted spell bonuses/etc      damage = m_spellInfo->EffectBasePoints[i]+m_spellInfo->EffectBaseDice[i]; -    m_caster->CalcAbsorbResist(m_caster,GetSpellSchoolMask(m_spellInfo), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist); +    m_caster->CalcAbsorbResist(m_caster,GetSpellSchoolMask(m_spellInfo), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist, m_spellInfo);      m_caster->SendSpellNonMeleeDamageLog(m_caster, m_spellInfo->Id, damage, GetSpellSchoolMask(m_spellInfo), absorb, resist, false, 0, false);      if(m_caster->GetTypeId() == TYPEID_PLAYER) @@ -347,6 +355,13 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)                              damage = 200;                          break;                      } +                    // Intercept (warrior spell trigger) +                    case 20253: +                    case 61491: +                    { +                        damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.12f); +                        break; +                    }                      // arcane charge. must only affect demons (also undead?)                      case 45072:                      { @@ -362,7 +377,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)                          if(unitTarget->GetGUID() == m_caster->GetGUID() || unitTarget->GetTypeId() != TYPEID_PLAYER)                              return; -                        float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[0])); +                        float radius = GetSpellRadiusForHostile(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[0]));                          if(!radius) return;                          float distance = m_caster->GetDistance2d(unitTarget);                          damage = (distance > radius ) ? 0 : (int32)(m_spellInfo->EffectBasePoints[0]*((radius - distance)/radius)); @@ -374,7 +389,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)              case SPELLFAMILY_MAGE:              {                  // Arcane Blast -                if(m_spellInfo->SpellFamilyFlags & 0x20000000LL) +                if(m_spellInfo->SpellFamilyFlags[0] & 0x20000000)                  {                      m_caster->CastSpell(m_caster,36032,true);                  } @@ -383,29 +398,50 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)              case SPELLFAMILY_WARRIOR:              {                  // Bloodthirst -                if(m_spellInfo->SpellFamilyFlags & 0x40000000000LL) +                if(m_spellInfo->SpellFamilyFlags[1] & 0x400)                  {                      damage = uint32(damage * (m_caster->GetTotalAttackPowerValue(BASE_ATTACK)) / 100);                  }                  // Shield Slam -                else if(m_spellInfo->SpellFamilyFlags & 0x100000000LL) +                else if(m_spellInfo->SpellFamilyFlags[1] & 0x200)                      damage += int32(m_caster->GetShieldBlockValue());                  // Victory Rush -                else if(m_spellInfo->SpellFamilyFlags & 0x10000000000LL) +                else if(m_spellInfo->SpellFamilyFlags[1] & 0x100)                  {                      damage = uint32(damage * m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100);                      m_caster->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, false);                  } +                // Revenge ${$m1+$AP*0.207} to ${$M1+$AP*0.207} +                else if(m_spellInfo->SpellFamilyFlags[0] & 0x400) +                    damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.207f); +                // Heroic Throw ${$m1+$AP*.50} +                else if(m_spellInfo->SpellFamilyFlags[1] & 0x00000001) +                    damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.5f); +                // Shockwave ${$m3/100*$AP} +                else if(m_spellInfo->SpellFamilyFlags[1] & 0x00008000) +                { +                    int32 pct = m_caster->CalculateSpellDamage(m_spellInfo, 2, m_spellInfo->EffectBasePoints[2], unitTarget); +                    if (pct > 0) +                        damage+= int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * pct / 100); +                    break; +                }                  break;              }              case SPELLFAMILY_WARLOCK:              {                  // Incinerate Rank 1 & 2 -                if((m_spellInfo->SpellFamilyFlags & 0x00004000000000LL) && m_spellInfo->SpellIconID==2128) +                if((m_spellInfo->SpellFamilyFlags[1] & 0x000040) && m_spellInfo->SpellIconID==2128)                  {                      // Incinerate does more dmg (dmg*0.25) if the target is Immolated.                      if(unitTarget->HasAuraState(AURA_STATE_IMMOLATE)) -                        damage += int32(damage*0.25); +                        damage += int32(damage*0.25f); +                } +                // Haunt +                else if (m_spellInfo->SpellFamilyFlags[1] & 0x40000) +                { +                    // Save damage for future healing +                    // TODO: Implement spell proc on aura expire +                    m_currentBasePoints[1] = int32(damage * m_currentBasePoints[1] / 100);                  }                  // Conflagrate - consumes immolate @@ -415,75 +451,52 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)                      Unit::AuraList const &mPeriodic = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);                      for(Unit::AuraList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)                      { -                        if( (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && ((*i)->GetSpellProto()->SpellFamilyFlags & 4) && +                        if( (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && ((*i)->GetSpellProto()->SpellFamilyFlags[0] & 4) &&                              (*i)->GetCasterGUID()==m_caster->GetGUID() )                          { -                            unitTarget->RemoveAurasDueToCasterSpell((*i)->GetId(), m_caster->GetGUID()); +                            unitTarget->RemoveAurasByCasterSpell((*i)->GetId(), m_caster->GetGUID());                              break;                          }                      }                  }                  break;              } +            case SPELLFAMILY_PRIEST: +            { +                // Shadow Word: Death - deals damage equal to damage done to caster +                if (m_spellInfo->SpellFamilyFlags[1] & 0x2) +                    m_caster->CastCustomSpell(m_caster, 32409, &damage, 0, 0, true); +                break; +            }              case SPELLFAMILY_DRUID:              {                  // Ferocious Bite -                if((m_spellInfo->SpellFamilyFlags & 0x000800000) && m_spellInfo->SpellVisual==6587) +                if(m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags[0] & 0x000800000) && m_spellInfo->SpellVisual[0]==6587)                  { -                    // converts each extra point of energy into ($f1+$AP/630) additional damage -                    float multiple = m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 630 + m_spellInfo->DmgMultiplier[effect_idx]; +                    // converts each extra point of energy into ($f1+$AP/410) additional damage +                    float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); +                    float multiple = ap / 410 + m_spellInfo->DmgMultiplier[effect_idx];                      damage += int32(m_caster->GetPower(POWER_ENERGY) * multiple); +                    damage += int32(((Player*)m_caster)->GetComboPoints() * ap * 7 / 100);                      m_caster->SetPower(POWER_ENERGY,0);                  }                  // Rake -                else if(m_spellInfo->SpellFamilyFlags & 0x0000000000001000LL) +                else if(m_spellInfo->SpellFamilyFlags[0] & 0x1000)                  {                      damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100);                  }                  // Swipe -                else if(m_spellInfo->SpellFamilyFlags & 0x0010000000000000LL) +                else if(m_spellInfo->SpellFamilyFlags[1] & 0x00100000)                  {                      damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.08f);                  } -                // Starfire -                else if ( m_spellInfo->SpellFamilyFlags & 0x0004LL ) -                { -                    Unit::AuraList const& m_OverrideClassScript = m_caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); -                    for(Unit::AuraList::const_iterator i = m_OverrideClassScript.begin(); i != m_OverrideClassScript.end(); ++i) -                    { -                        // Starfire Bonus (caster) -                        switch((*i)->GetModifier()->m_miscvalue) -                        { -                            case 5481:                      // Nordrassil Regalia - bonus -                            { -                                Unit::AuraList const& m_periodicDamageAuras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); -                                for(Unit::AuraList::const_iterator itr = m_periodicDamageAuras.begin(); itr != m_periodicDamageAuras.end(); ++itr) -                                { -                                    // Moonfire or Insect Swarm (target debuff from any casters) -                                    if ( (*itr)->GetSpellProto()->SpellFamilyFlags & 0x00200002LL ) -                                    { -                                        int32 mod = (*i)->GetModifier()->m_amount; -                                        damage += damage*mod/100; -                                        break; -                                    } -                                } -                                break; -                            } -                            case 5148:                      //Improved Starfire - Ivory Idol of the Moongoddes Aura -                            { -                                damage += (*i)->GetModifier()->m_amount; -                                break; -                            } -                        } -                    } -                }                  //Mangle Bonus for the initial damage of Lacerate and Rake -                if((m_spellInfo->SpellFamilyFlags==0x0000000000001000LL && m_spellInfo->SpellIconID==494) || -                    (m_spellInfo->SpellFamilyFlags==0x0000010000000000LL && m_spellInfo->SpellIconID==2246)) +                if((m_spellInfo->SpellFamilyFlags.IsEqual(0x1000,0,0) && m_spellInfo->SpellIconID==494) || +                    (m_spellInfo->SpellFamilyFlags.IsEqual(0,0x100,0) && m_spellInfo->SpellIconID==2246))                  {                      Unit::AuraList const& mDummyAuras = unitTarget->GetAurasByType(SPELL_AURA_DUMMY);                      for(Unit::AuraList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i) -                        if((*i)->GetSpellProto()->SpellFamilyFlags & 0x0000044000000000LL && (*i)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_DRUID) +                        if((*i)->GetSpellProto()->SpellFamilyFlags[1] & 0x00000440 && (*i)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_DRUID)                          {                              damage = int32(damage*(100.0f+(*i)->GetModifier()->m_amount)/100.0f);                              break; @@ -494,72 +507,91 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)              case SPELLFAMILY_ROGUE:              {                  // Envenom -                if(m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & 0x800000000LL)) +                if(m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags[1] & 0x8))                  {                      // consume from stack dozes not more that have combo-points                      if(uint32 combo = ((Player*)m_caster)->GetComboPoints())                      { -                        // count consumed deadly poison doses at target -                        uint32 doses = 0; - -                        // remove consumed poison doses +                        Aura *poison = 0; +                        // Lookup for Deadly poison (only attacker applied)                          Unit::AuraList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); -                        for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end() && combo;) -                        { -                            // Deadly poison (only attacker applied) -                            if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE && ((*itr)->GetSpellProto()->SpellFamilyFlags & 0x10000) && -                                (*itr)->GetSpellProto()->SpellVisual==5100 && (*itr)->GetCasterGUID()==m_caster->GetGUID() ) +                        for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) +                            if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE && +                                (*itr)->GetSpellProto()->SpellFamilyFlags[0] & 0x10000 && +                                (*itr)->GetCasterGUID()==m_caster->GetGUID() )                              { -                                --combo; -                                ++doses; - -                                unitTarget->RemoveSingleAuraFromStack((*itr)->GetId(), (*itr)->GetEffIndex()); - -                                itr = auras.begin(); +                                poison = *itr; +                                break;                              } -                            else -                                ++itr; +                        // count consumed deadly poison doses at target +                        if (poison) +                        { +                            uint32 spellId = poison->GetId(); +                            uint32 doses = poison->GetStackAmount(); +                            if (doses > combo) +                                doses = combo; +                            for (int i=0; i< doses; i++) +                                unitTarget->RemoveSingleSpellAurasFromStack(spellId); +                            damage *= doses; +                            damage += int32(((Player*)m_caster)->GetTotalAttackPowerValue(BASE_ATTACK) * 0.03f * doses);                          } - -                        damage *= doses; -                        damage += int32(((Player*)m_caster)->GetTotalAttackPowerValue(BASE_ATTACK) * 0.03f * doses); -                          // Eviscerate and Envenom Bonus Damage (item set effect)                          if(m_caster->GetDummyAura(37169))                              damage += ((Player*)m_caster)->GetComboPoints()*40;                      }                  }                  // Eviscerate -                else if((m_spellInfo->SpellFamilyFlags & 0x00020000LL) && m_caster->GetTypeId()==TYPEID_PLAYER) +                else if((m_spellInfo->SpellFamilyFlags[0] & 0x00020000) && m_caster->GetTypeId()==TYPEID_PLAYER)                  {                      if(uint32 combo = ((Player*)m_caster)->GetComboPoints())                      { -                        damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * combo * 0.03f); +                        float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); +                        damage += irand(int32(ap * combo * 0.03f), int32(ap * combo * 0.07f));                          // Eviscerate and Envenom Bonus Damage (item set effect)                          if(m_caster->GetDummyAura(37169))                              damage += combo*40;                      }                  } +                // Gouge +                else if(m_spellInfo->SpellFamilyFlags[0] & 0x8) +                { +                    damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.02f); +                } +                // Instant Poison +                else if(m_spellInfo->SpellFamilyFlags[0] & 0x2000) +                { +                    damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.10f); +                } +                // Wound Poison +                else if(m_spellInfo->SpellFamilyFlags[0] & 0x10000000) +                { +                    damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.04f); +                }                  break;              }              case SPELLFAMILY_HUNTER:              {                  // Mongoose Bite -                if((m_spellInfo->SpellFamilyFlags & 0x000000002) && m_spellInfo->SpellVisual==342) +                if((m_spellInfo->SpellFamilyFlags[0] & 0x2) && m_spellInfo->SpellVisual[0]==342) +                { +                    damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f); +                } +                // Counterattack +                else if(m_spellInfo->SpellFamilyFlags[1] & 0x00080000)                  { -                    damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2); +                    damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f);                  }                  // Arcane Shot -                else if((m_spellInfo->SpellFamilyFlags & 0x00000800) && m_spellInfo->maxLevel > 0) +                else if((m_spellInfo->SpellFamilyFlags[0] & 0x00000800) && m_spellInfo->maxLevel > 0)                  { -                    damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.15); +                    damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.15f);                  }                  // Steady Shot -                else if(m_spellInfo->SpellFamilyFlags & 0x100000000LL) +                else if(m_spellInfo->SpellFamilyFlags[1] & 0x1)                  {                      int32 base = irand((int32)m_caster->GetWeaponDamageRange(RANGED_ATTACK, MINDAMAGE),(int32)m_caster->GetWeaponDamageRange(RANGED_ATTACK, MAXDAMAGE)); -                    damage += int32(float(base)/m_caster->GetAttackTime(RANGED_ATTACK)*2800 + m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.2f); +                    damage += int32(float(base)/m_caster->GetAttackTime(RANGED_ATTACK)*2800 + m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.1f);                      bool found = false; @@ -578,28 +610,54 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)                      if(found)                          damage += m_spellInfo->EffectBasePoints[1];                  } -                //Explosive Trap Effect -                else if(m_spellInfo->SpellFamilyFlags & 0x00000004) +                // Explosive Trap Effect +                else if(m_spellInfo->SpellFamilyFlags[0] & 0x00000004)                  { -                    damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.1); +                    damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.1f);                  }                  break;              }              case SPELLFAMILY_PALADIN:              { -                //Judgement of Vengeance -                if((m_spellInfo->SpellFamilyFlags & 0x800000000LL) && m_spellInfo->SpellIconID==2292) +                // Judgement of Vengeance/Corruption ${1+0.22*$SPH+0.14*$AP} + 10% for each application of Holy Vengeance/Blood Corruption on the target +                if((m_spellInfo->SpellFamilyFlags[1] & 0x400000) && m_spellInfo->SpellIconID==2292)                  { +                    float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); +                    int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) + +                                 m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget); +                    damage+=int32(ap * 0.14f) + int32(holy * 22 / 100); +                    // Get stack of Holy Vengeance/Blood Corruption on the target added by caster                      uint32 stacks = 0;                      Unit::AuraList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);                      for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) -                        if((*itr)->GetId() == 31803 && (*itr)->GetCasterGUID()==m_caster->GetGUID()) -                            ++stacks; -                    if(!stacks) -                        //No damage if the target isn't affected by this -                        damage = -1; -                    else -                        damage *= stacks; +                        if(((*itr)->GetId() == 31803 || (*itr)->GetId() == 53742) && (*itr)->GetCasterGUID()==m_caster->GetGUID()) +                        { +                            stacks = (*itr)->GetStackAmount(); +                            break; +                        } +                    // + 10% for each application of Holy Vengeance/Blood Corruption on the target +                    if(stacks) +                        damage += damage * stacks * 10 /100; +                } +                // Avenger's Shield ($m1+0.07*$SPH+0.07*$AP) +                else if(m_spellInfo->SpellFamilyFlags[0] & 0x4000) +                { +                    float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); +                    damage += int32(ap * 0.07f); +                } +                // Hammer of Wrath ($m1+0.15*$SPH+0.15*$AP) +                else if(m_spellInfo->SpellFamilyFlags[1] & 0x00000080) +                { +                    float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); +                    damage += int32(ap * 0.15f); +                } +                // Hammer of the Righteous +                else if(m_spellInfo->SpellFamilyFlags[1]&0x00040000) +                { +                    // Add main hand dps * effect[2] amount +                    float averange = (m_caster->GetFloatValue(UNIT_FIELD_MINDAMAGE) + m_caster->GetFloatValue(UNIT_FIELD_MAXDAMAGE)) / 2; +                    int32 count = m_caster->CalculateSpellDamage(m_spellInfo, 2, m_spellInfo->EffectBasePoints[2], unitTarget); +                    damage += count * int32(averange * IN_MILISECONDS) / m_caster->GetAttackTime(BASE_ATTACK);                  }                  break;              } @@ -659,7 +717,7 @@ void Spell::EffectDummy(uint32 i)                      if (!creatureTarget || !pGameObj) return; -                    if (!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), 181574, creatureTarget->GetMap(), +                    if (!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), 181574, creatureTarget->GetMap(), creatureTarget->GetPhaseMask(),                          creatureTarget->GetPositionX(), creatureTarget->GetPositionY(), creatureTarget->GetPositionZ(),                          creatureTarget->GetOrientation(), 0, 0, 0, 0, 100, 1))                      { @@ -767,12 +825,6 @@ void Spell::EffectDummy(uint32 i)                      m_caster->CastCustomSpell(unitTarget, 12721, &deepWoundsDotBasePoints0, NULL, NULL, true, NULL);                      return;                  } -                case 12975:                                 //Last Stand -                { -                    int32 healthModSpellBasePoints0 = int32(m_caster->GetMaxHealth()*0.3); -                    m_caster->CastCustomSpell(m_caster, 12976, &healthModSpellBasePoints0, NULL, NULL, true, NULL); -                    return; -                }                  case 13120:                                 // net-o-matic                  {                      if(!unitTarget) @@ -809,30 +861,6 @@ void Spell::EffectDummy(uint32 i)                      }                      return;                  } -                case 14185:                                 // Preparation Rogue -                { -                    if(m_caster->GetTypeId()!=TYPEID_PLAYER) -                        return; - -                    //immediately finishes the cooldown on certain Rogue abilities -                    const PlayerSpellMap& sp_list = ((Player *)m_caster)->GetSpellMap(); -                    for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr) -                    { -                        uint32 classspell = itr->first; -                        SpellEntry const *spellInfo = sSpellStore.LookupEntry(classspell); - -                        if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags & 0x26000000860LL)) -                        { -                            ((Player*)m_caster)->RemoveSpellCooldown(classspell); - -                            WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); -                            data << uint32(classspell); -                            data << uint64(m_caster->GetGUID()); -                            ((Player*)m_caster)->GetSession()->SendPacket(&data); -                        } -                    } -                    return; -                }                  case 15998:                                 // Capture Worg Pup                  case 29435:                                 // Capture Female Kaliri Hatchling                  { @@ -897,19 +925,20 @@ void Spell::EffectDummy(uint32 i)                      if(creatureTarget->isPet())                          return; +                    GameObject* Crystal_Prison = m_caster->SummonGameObject(179644, creatureTarget->GetPositionX(), creatureTarget->GetPositionY(), creatureTarget->GetPositionZ(), creatureTarget->GetOrientation(), 0, 0, 0, 0, creatureTarget->GetRespawnTime()-time(NULL)); +                    sLog.outDebug("SummonGameObject at SpellEfects.cpp EffectDummy for Spell 23019\n"); +                      creatureTarget->setDeathState(JUST_DIED);                      creatureTarget->RemoveCorpse();                      creatureTarget->SetHealth(0);                   // just for nice GM-mode view -                    GameObject* Crystal_Prison = m_caster->SummonGameObject(179644, creatureTarget->GetPositionX(), creatureTarget->GetPositionY(), creatureTarget->GetPositionZ(), creatureTarget->GetOrientation(), 0, 0, 0, 0, creatureTarget->GetRespawnTime()-time(NULL)); -                    sLog.outDebug("SummonGameObject at SpellEfects.cpp EffectDummy for Spell 23019\n");                      WorldPacket data(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, 8);                      data << uint64(Crystal_Prison->GetGUID());                      m_caster->SendMessageToSet(&data,true);                      return;                  } -                case 23074:                                 // Arc. Dragonling +                case 23074:                                 // Arcanite Dragonling                      if (!m_CastItem) return;                      m_caster->CastSpell(m_caster,19804,true,m_CastItem);                      return; @@ -1121,36 +1150,6 @@ void Spell::EffectDummy(uint32 i)                      m_caster->CastSpell(m_caster,42337,true,NULL);                      return;                  } -                case 37573:                                 //Temporal Phase Modulator -                { -                    if(!unitTarget) -                        return; - -                    TemporarySummon* tempSummon = dynamic_cast<TemporarySummon*>(unitTarget); -                    if(!tempSummon) -                        return; - -                    uint32 health = tempSummon->GetHealth(); -                    const uint32 entry_list[6] = {21821, 21820, 21817}; - -                    float x = tempSummon->GetPositionX(); -                    float y = tempSummon->GetPositionY(); -                    float z = tempSummon->GetPositionZ(); -                    float o = tempSummon->GetOrientation(); - -                    tempSummon->UnSummon(); - -                    Creature* pCreature = m_caster->SummonCreature(entry_list[urand(0, 2)], x, y, z, o,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,180000); -                    if (!pCreature) -                        return; - -                    pCreature->SetHealth(health); - -                    if(pCreature->IsAIEnabled) -                        pCreature->AI()->AttackStart(m_caster); - -                    return; -                }                  case 34665:                                 //Administer Antidote                  {                      if(!unitTarget || m_caster->GetTypeId() != TYPEID_PLAYER ) @@ -1227,6 +1226,28 @@ void Spell::EffectDummy(uint32 i)                      m_caster->CastSpell(m_caster, 30452, true, NULL);                      return;                  }                 +                case 53341: +                case 53343: +                { +                    m_caster->CastSpell(m_caster,54586,true); +                    return; +                } +                case 58418:                                 // Portal to Orgrimmar +                { +                    if(!unitTarget) +                        return; + +                    unitTarget->CastSpell(unitTarget, 58419, true); +                    break; +                } +                case 58420:                                 // Portal to Stormwind +                { +                    if(!unitTarget) +                        return; + +                    unitTarget->CastSpell(unitTarget, 58421, true); +                    break; +                }              }              //All IconID Check in there @@ -1300,65 +1321,120 @@ void Spell::EffectDummy(uint32 i)              break;          case SPELLFAMILY_WARRIOR:              // Charge -            if(m_spellInfo->SpellFamilyFlags & 0x1 && m_spellInfo->SpellVisual == 867) +            if(m_spellInfo->SpellFamilyFlags & 0x1 && m_spellInfo->SpellVisual[0] == 867)              {                  int32 chargeBasePoints0 = damage;                  m_caster->CastCustomSpell(m_caster,34846,&chargeBasePoints0,NULL,NULL,true);                  return;              } +			//Slam +			if(m_spellInfo->SpellFamilyFlags[0] & 0x200000 && m_spellInfo->SpellIconID == 559) +			{ +				int32 bp0 = damage; +				m_caster->CastCustomSpell(unitTarget, 50783, &bp0, NULL, NULL, true, 0); +                return; +			}              // Execute -            if(m_spellInfo->SpellFamilyFlags & 0x20000000) +            if(m_spellInfo->SpellFamilyFlags[0] & 0x20000000)              {                  if(!unitTarget)                      return; +                uint32 rage = m_caster->GetPower(POWER_RAGE); +                // Glyph of Execution bonus +                if (Aura *aura = m_caster->GetDummyAura(58367)) +                    rage+=aura->GetModifier()->m_amount; +                  spell_id = 20647; -                bp = damage+int32(m_caster->GetPower(POWER_RAGE) * m_spellInfo->DmgMultiplier[i]); +                bp = damage+int32(rage * m_spellInfo->DmgMultiplier[i] + +                                                 m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f);                  m_caster->SetPower(POWER_RAGE,0);                  break;              } -            if(m_spellInfo->Id==21977)                      //Warrior's Wrath +            // Slam +            if(m_spellInfo->SpellFamilyFlags[0] & 0x200000)              {                  if(!unitTarget)                      return; - -                m_caster->CastSpell(unitTarget,21887,true); // spell mod +                m_damage+=m_caster->CalculateDamage(m_attackType, false); +                m_damage+=damage;                  return;              } +            switch(m_spellInfo->Id) +            { +                // Warrior's Wrath +                case 21977: +                { +                    if(!unitTarget) +                        return; +                    m_caster->CastSpell(unitTarget,21887,true); // spell mod +                    return; +                } +                // Last Stand +                case 12975: +                { +                    int32 healthModSpellBasePoints0 = int32(m_caster->GetMaxHealth()*0.3); +                    m_caster->CastCustomSpell(m_caster, 12976, &healthModSpellBasePoints0, NULL, NULL, true, NULL); +                    return; +                } +                // Bloodthirst +                case 23881: +                { +                    m_caster->CastCustomSpell(unitTarget, 23885, &damage, NULL, NULL, true, NULL); +                    return; +                } +            }              break;          case SPELLFAMILY_WARLOCK: -            //Life Tap (only it have this with dummy effect) -            if (m_spellInfo->SpellFamilyFlags == 0x40000) +            // Life Tap +            if (m_spellInfo->SpellFamilyFlags[0] & 0x40000)              { -                float cost = damage; - -                if(Player* modOwner = m_caster->GetSpellModOwner()) -                    modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, cost,this); - -                int32 dmg = m_caster->SpellDamageBonus(m_caster, m_spellInfo,uint32(cost > 0 ? cost : 0), SPELL_DIRECT_DAMAGE); - -                if(int32(m_caster->GetHealth()) > dmg) +                // In 303 exist spirit depend +                uint32 spirit = m_caster->GetStat(STAT_SPIRIT); +                switch (m_spellInfo->Id) +                { +                    case  1454: damage+=spirit; break; +                    case  1455: damage+=spirit*15/10; break; +                    case  1456: damage+=spirit*2; break; +                    case 11687: damage+=spirit*25/10; break; +                    case 11688: +                    case 11689: +                    case 27222: +                    case 57946: damage+=spirit*3; break; +                    default: +                        sLog.outError("Spell::EffectDummy: %u Life Tap need set spirit multipler", m_spellInfo->Id); +                        return; +                } +//              Think its not need (also need remove Life Tap from SpellDamageBonus or add new value) +//              damage = m_caster->SpellDamageBonus(m_caster, m_spellInfo,uint32(damage > 0 ? damage : 0), SPELL_DIRECT_DAMAGE); +                if(int32(unitTarget->GetHealth()) > damage)                  {                      // Shouldn't Appear in Combat Log -                    m_caster->ModifyHealth(-dmg); - -                    int32 mana = dmg; +                    unitTarget->ModifyHealth(-damage); +                    int32 mana = damage; +                    // Improved Life Tap mod                      Unit::AuraList const& auraDummy = m_caster->GetAurasByType(SPELL_AURA_DUMMY);                      for(Unit::AuraList::const_iterator itr = auraDummy.begin(); itr != auraDummy.end(); ++itr)                      { -                        // only Imp. Life Tap have this in combination with dummy aura                          if((*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (*itr)->GetSpellProto()->SpellIconID == 208)                              mana = ((*itr)->GetModifier()->m_amount + 100)* mana / 100;                      } - -                    m_caster->CastCustomSpell(m_caster,31818,&mana,NULL,NULL,true,NULL); +                    m_caster->CastCustomSpell(unitTarget, 31818, &mana, NULL, NULL, true);                      // Mana Feed -                    int32 manaFeedVal = m_caster->CalculateSpellDamage(m_spellInfo,1, m_spellInfo->EffectBasePoints[1],m_caster); -                    manaFeedVal = manaFeedVal * mana / 100; +                    int32 manaFeedVal = 0; +                    Unit::AuraList const& mod = m_caster->GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER); +                    for(Unit::AuraList::const_iterator itr = mod.begin(); itr != mod.end(); ++itr) +                    { +                        if((*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (*itr)->GetSpellProto()->SpellIconID == 1982) +                            manaFeedVal+= (*itr)->GetModifier()->m_amount; +                    }                      if(manaFeedVal > 0) -                        m_caster->CastCustomSpell(m_caster,32553,&manaFeedVal,NULL,NULL,true,NULL); +                    { +                        manaFeedVal = manaFeedVal * mana / 100; +                        m_caster->CastCustomSpell(m_caster, 32553, &manaFeedVal, NULL, NULL, true, NULL); +                    }                  }                  else                      SendCastResult(SPELL_FAILED_FIZZLE); @@ -1366,6 +1442,30 @@ void Spell::EffectDummy(uint32 i)              }              break;          case SPELLFAMILY_PRIEST: +            // Penance +            if (m_spellInfo->SpellFamilyFlags[1] & 0x00800000) +            { +                if (!unitTarget) +                    return; + +                int hurt = 0; +                int heal = 0; +                switch(m_spellInfo->Id) +                { +                    case 47540: hurt = 47758; heal = 47757; break; +                    case 53005: hurt = 53001; heal = 52986; break; +                    case 53006: hurt = 53002; heal = 52987; break; +                    case 53007: hurt = 53003; heal = 52988; break; +                    default: +                        sLog.outError("Spell::EffectDummy: Spell %u Penance need set correct heal/damage spell", m_spellInfo->Id); +                        return; +                } +                if (m_caster->IsFriendlyTo(unitTarget)) +                    m_caster->CastSpell(unitTarget, heal, true, 0); +                else +                    m_caster->CastSpell(unitTarget, hurt, true, 0); +                return; +            }              switch(m_spellInfo->Id )              {                  case 28598:                                 // Touch of Weakness triggered spell @@ -1393,25 +1493,16 @@ void Spell::EffectDummy(uint32 i)              }              break;          case SPELLFAMILY_DRUID: -            switch(m_spellInfo->Id ) +            // Starfall +            if (m_spellInfo->SpellFamilyFlags[2] & 0x100)              { -                case 5420:                                  // Tree of Life passive -                { -                    // Tree of Life area effect -                    int32 health_mod = int32(m_caster->GetStat(STAT_SPIRIT)/4); -                    m_caster->CastCustomSpell(m_caster,34123,&health_mod,NULL,NULL,true,NULL); -                    return; -                } +                m_caster->CastSpell(unitTarget, damage, true, NULL); +                return;              }              break;          case SPELLFAMILY_ROGUE:              switch(m_spellInfo->Id )              { -                case 31231:                                 // Cheat Death -                { -                    m_caster->CastSpell(m_caster,45182,true); -                    return; -                }                  case 5938:                                  // Shiv                  {                      if(m_caster->GetTypeId() != TYPEID_PLAYER) @@ -1447,36 +1538,38 @@ void Spell::EffectDummy(uint32 i)                      m_caster->CastSpell(unitTarget, 5940, true);                      return;                  } -            } -            break; -        case SPELLFAMILY_HUNTER: -            // Kill command -            if(m_spellInfo->SpellFamilyFlags & 0x00080000000000LL) -            { -                if(m_caster->getClass()!=CLASS_HUNTER) -                    return; +                case 14185:                                 // Preparation Rogue +                { +                    if(m_caster->GetTypeId()!=TYPEID_PLAYER) +                        return; -                // clear hunter crit aura state -                m_caster->ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE,false); +                    //immediately finishes the cooldown on certain Rogue abilities +                    const PlayerSpellMap& sp_list = ((Player *)m_caster)->GetSpellMap(); +                    for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr) +                    { +                        uint32 classspell = itr->first; +                        SpellEntry const *spellInfo = sSpellStore.LookupEntry(classspell); -                // additional damage from pet to pet target -                Pet* pet = m_caster->GetPet(); -                if(!pet || !pet->getVictim()) -                    return; +                        if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags[1] & 0x00000240 || spellInfo->SpellFamilyFlags[0] & 0x00000860)) +                        { +                            ((Player*)m_caster)->RemoveSpellCooldown(classspell); -                uint32 spell_id = 0; -                switch (m_spellInfo->Id) +                            WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); +                            data << uint32(classspell); +                            data << uint64(m_caster->GetGUID()); +                            ((Player*)m_caster)->GetSession()->SendPacket(&data); +                        } +                    } +                    return; +                } +                case 31231:                                 // Cheat Death                  { -                case 34026: spell_id = 34027; break;        // rank 1 -                default: -                    sLog.outError("Spell::EffectDummy: Spell %u not handled in KC",m_spellInfo->Id); +                    m_caster->CastSpell(m_caster,45182,true);                      return;                  } - -                pet->CastSpell(pet->getVictim(), spell_id, true); -                return;              } - +            break; +        case SPELLFAMILY_HUNTER:              switch(m_spellInfo->Id)              {                  case 23989:                                 //Readiness talent @@ -1534,6 +1627,8 @@ void Spell::EffectDummy(uint32 i)                          case 20930: hurt = 25902; heal = 25903; break;                          case 27174: hurt = 27176; heal = 27175; break;                          case 33072: hurt = 33073; heal = 33074; break; +                        case 48824: hurt = 48822; heal = 48820; break; +                        case 48825: hurt = 48823; heal = 48821; break;                          default:                              sLog.outError("Spell::EffectDummy: Spell %u not handled in HS",m_spellInfo->Id);                              return; @@ -1564,10 +1659,7 @@ void Spell::EffectDummy(uint32 i)                          mod->value = -50;                          mod->type = SPELLMOD_PCT;                          mod->spellId = m_spellInfo->Id; -                        mod->effectId = i; -                        mod->lastAffected = NULL; -                        mod->mask = 0x0000020000000000LL; -                        mod->charges = 0; +                        mod->mask[1] = 0x00000200;                          ((Player*)m_caster)->AddSpellMod(mod, true);                          m_caster->CastSpell(unitTarget,spell_proto,true,NULL); @@ -1583,6 +1675,14 @@ void Spell::EffectDummy(uint32 i)              switch(m_spellInfo->Id)              { +                // Judgement of Righteousness (0.2*$AP+0.32*$SPH) holy added in spellDamagBonus +                case 20187: +                { +                    if (!unitTarget) +                        return; +                    m_damage+=int32(0.2f*m_caster->GetTotalAttackPowerValue(BASE_ATTACK)); +                    return; +                }                  case 31789:                                 // Righteous Defense (step 1)                  {                      // 31989 -> dummy effect (step 1) + dummy effect (step 2) -> 31709 (taunt like spell for each target) @@ -1649,8 +1749,10 @@ void Spell::EffectDummy(uint32 i)              break;          case SPELLFAMILY_SHAMAN:              //Shaman Rockbiter Weapon -            if (m_spellInfo->SpellFamilyFlags == 0x400000) +            if (m_spellInfo->SpellFamilyFlags.IsEqual(0x400000))              { +                // TODO: use expect spell for enchant (if exist talent) +                // In 3.0.3 no mods present for rockbiter                  uint32 spell_id = 0;                  switch(m_spellInfo->Id)                  { @@ -1658,11 +1760,6 @@ void Spell::EffectDummy(uint32 i)                      case  8018: spell_id = 36750; break;    // Rank 2                      case  8019: spell_id = 36755; break;    // Rank 3                      case 10399: spell_id = 36759; break;    // Rank 4 -                    case 16314: spell_id = 36763; break;    // Rank 5 -                    case 16315: spell_id = 36766; break;    // Rank 6 -                    case 16316: spell_id = 36771; break;    // Rank 7 -                    case 25479: spell_id = 36775; break;    // Rank 8 -                    case 25485: spell_id = 36499; break;    // Rank 9                      default:                          sLog.outError("Spell::EffectDummy: Spell %u not handled in RW",m_spellInfo->Id);                          return; @@ -1700,19 +1797,68 @@ void Spell::EffectDummy(uint32 i)                  }                  return;              } - -            if(m_spellInfo->Id == 39610)                    // Mana-Tide Totem effect +            // Healing Stream Totem +            if(m_spellInfo->SpellFamilyFlags[0] & 0x2000) +            { +                m_caster->CastCustomSpell(unitTarget, 52042, &damage, 0, 0, true, 0, 0, m_originalCasterGUID); +                return; +            } +            // Mana Spring Totem +            if(m_spellInfo->SpellFamilyFlags[0] & 0x4000) +            { +                if(unitTarget->getPowerType()!=POWER_MANA) +                    return; +                m_caster->CastCustomSpell(unitTarget, 52032, &damage, 0, 0, true, 0, 0, m_originalCasterGUID); +                return; +            } +            if(m_spellInfo->Id == 39610)                    // Mana Tide Totem effect              {                  if(!unitTarget || unitTarget->getPowerType() != POWER_MANA)                      return; - +                // Glyph of Mana Tide +                Unit *owner = m_caster->GetOwner(); +                if (owner) +                    if (Aura *dummy = owner->GetDummyAura(55441)) +                        damage+=dummy->GetModifier()->m_amount;                  // Regenerate 6% of Total Mana Every 3 secs                  int32 EffectBasePoints0 = unitTarget->GetMaxPower(POWER_MANA)  * damage / 100;                  m_caster->CastCustomSpell(unitTarget,39609,&EffectBasePoints0,NULL,NULL,true,NULL,NULL,m_originalCasterGUID);                  return;              } - +            // Lava Lash +            if (m_spellInfo->SpellFamilyFlags[2] & 0x00000004) +            { +                if (m_caster->GetTypeId()!=TYPEID_PLAYER) +                    return; +                Item *item = ((Player*)m_caster)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); +                if (item) +                { +                    // Damage is increased if your off-hand weapon is enchanted with Flametongue. +                    Unit::AuraList const& auraDummy = m_caster->GetAurasByType(SPELL_AURA_DUMMY); +                    for(Unit::AuraList::const_iterator itr = auraDummy.begin(); itr != auraDummy.end(); ++itr) +                    { +                        if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_SHAMAN && +                            (*itr)->GetSpellProto()->SpellFamilyFlags[0] & 0x200000 && +                            (*itr)->GetCastItemGUID() == item->GetGUID()) +                        { +                           m_damage += m_damage * damage / 100; +                           return; +                        } +                    } +                } +                return; +            }              break; +        case SPELLFAMILY_DEATHKNIGHT: +            // Death strike dummy aura apply +            // Used to proc healing later +            if (m_spellInfo->SpellFamilyFlags[0] & 0x00000010) +            { +                spell_id=45469; +                m_caster->CastSpell(m_caster,spell_id,true); +                return; +            } +      }      //spells triggered by dummy effect should not miss @@ -1725,7 +1871,7 @@ void Spell::EffectDummy(uint32 i)              sLog.outError("EffectDummy of spell %u: triggering unknown spell id %i\n", m_spellInfo->Id, spell_id);              return;          } - +                      Spell* spell = new Spell(m_caster, spellInfo, true, m_originalCasterGUID, NULL, true);          if(bp) spell->m_currentBasePoints[0] = bp;          SpellCastTargets targets; @@ -1776,8 +1922,8 @@ void Spell::EffectTriggerRitualOfSummoning(uint32 i)      targets.setUnitTarget( unitTarget);      spell->prepare(&targets); -    m_caster->SetCurrentCastedSpell(spell); -    spell->m_selfContainer = &(m_caster->m_currentSpells[spell->GetCurrentContainer()]); +    //m_caster->SetCurrentCastedSpell(spell); +    //spell->m_selfContainer = &(m_caster->m_currentSpells[spell->GetCurrentContainer()]);  } @@ -1831,7 +1977,7 @@ void Spell::EffectTriggerSpell(uint32 i)                  if (!spellInfo)                      continue; -                if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE_STEALTH) +                if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG_ROGUE_STEALTH)                  {                      spellId = spellInfo->Id;                      break; @@ -1988,12 +2134,7 @@ void Spell::EffectTriggerMissileSpell(uint32 effect_idx)      if (m_CastItem)          DEBUG_LOG("WORLD: cast Item spellId - %i", spellInfo->Id); -    Spell *spell = new Spell(m_caster, spellInfo, true, m_originalCasterGUID ); - -    SpellCastTargets targets; -    targets.setDestination(m_targets.m_destX,m_targets.m_destY,m_targets.m_destZ); -    spell->m_CastItem = m_CastItem; -    spell->prepare(&targets, NULL); +    m_caster->CastSpell(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, spellInfo->Id, true, m_CastItem, 0, m_originalCasterGUID);  }  void Spell::EffectTeleportUnits(uint32 i) @@ -2128,17 +2269,12 @@ void Spell::EffectApplyAura(uint32 i)      if(!unitTarget)          return; -    SpellImmuneList const& list = unitTarget->m_spellImmune[IMMUNITY_STATE]; -    for(SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr) -        if(itr->type == m_spellInfo->EffectApplyAuraName[i]) -            return; -      // ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load)      if( !unitTarget->isAlive() && m_spellInfo->Id != 20584 && m_spellInfo->Id != 8326 &&          (unitTarget->GetTypeId()!=TYPEID_PLAYER || !((Player*)unitTarget)->GetSession()->PlayerLoading()) )          return; -    Unit* caster = m_originalCasterGUID ? m_originalCaster : m_caster; +    Unit* caster = m_originalCaster ? m_originalCaster : m_caster;      if(!caster)          return; @@ -2151,6 +2287,13 @@ void Spell::EffectApplyAura(uint32 i)      unitTarget->ApplyDiminishingToDuration(m_diminishGroup,duration,caster,m_diminishLevel);      Aur->setDiminishGroup(m_diminishGroup); +    //apply mods only here, area auras don't have duration +    duration = caster->ModSpellDuration(m_spellInfo, i, unitTarget, duration); + +    //mod duration of channeled aura by spell haste +    if (IsChanneledSpell(m_spellInfo)) +        caster->ModSpellCastTime(m_spellInfo, duration, this); +      // if Aura removed and deleted, do not continue.      if(duration== 0 && !(Aur->IsPermanent()))      { @@ -2175,33 +2318,8 @@ void Spell::EffectApplyAura(uint32 i)      if(!Aur)          return; -    // TODO Make a way so it works for every related spell! -    if(unitTarget->GetTypeId()==TYPEID_PLAYER)              // Negative buff should only be applied on players -    { -        uint32 spellId = 0; -        if(m_spellInfo->CasterAuraStateNot==AURA_STATE_WEAKENED_SOUL || m_spellInfo->TargetAuraStateNot==AURA_STATE_WEAKENED_SOUL) -            spellId = 6788;                                 // Weakened Soul -        else if(m_spellInfo->CasterAuraStateNot==AURA_STATE_FORBEARANCE || m_spellInfo->TargetAuraStateNot==AURA_STATE_FORBEARANCE) -            spellId = 25771;                                // Forbearance -        else if(m_spellInfo->CasterAuraStateNot==AURA_STATE_HYPOTHERMIA) -            spellId = 41425;                                // Hypothermia -        else if (m_spellInfo->Mechanic == MECHANIC_BANDAGE) // Bandages -            spellId = 11196;                                // Recently Bandaged -        else if( (m_spellInfo->AttributesEx & 0x20) && (m_spellInfo->AttributesEx2 & 0x20000) ) -            spellId = 23230;                                // Blood Fury - Healing Reduction - -        SpellEntry const *AdditionalSpellInfo = sSpellStore.LookupEntry(spellId); -        if (AdditionalSpellInfo) -        { -            // applied at target by target -            Aura* AdditionalAura = CreateAura(AdditionalSpellInfo, 0, NULL, unitTarget,unitTarget, 0); -            unitTarget->AddAura(AdditionalAura); -            sLog.outDebug("Spell: Additional Aura is: %u", AdditionalSpellInfo->EffectApplyAuraName[0]); -        } -    } -      // Prayer of Mending (jump animation), we need formal caster instead original for correct animation -    if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && (m_spellInfo->SpellFamilyFlags & 0x00002000000000LL)) +    if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && (m_spellInfo->SpellFamilyFlags[1] & 0x000020))          m_caster->CastSpell(unitTarget, 41637, true, NULL, Aur, m_originalCasterGUID);  } @@ -2252,7 +2370,8 @@ void Spell::EffectPowerDrain(uint32 i)      unitTarget->ModifyPower(drain_power,-new_damage); -    if(drain_power == POWER_MANA) +    // Don`t restore from self drain +    if(drain_power == POWER_MANA && m_caster != unitTarget)      {          float manaMultiplier = m_spellInfo->EffectMultipleValue[i];          if(manaMultiplier==0) @@ -2345,10 +2464,24 @@ void Spell::EffectPowerBurn(uint32 i)      if(damage < 0)          return; +    Unit* caster = m_originalCaster ? m_originalCaster : m_caster; +      int32 curPower = int32(unitTarget->GetPower(powertype)); -    // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)      uint32 power = damage; +    //Mana burn take mana % amount from target, but not bigger than amount*2 of caster mana +    if ( m_spellInfo->SpellFamilyName==SPELLFAMILY_PRIEST && m_spellInfo->SpellFamilyFlags[0] & 0x10) +    { +        // Burn percentage of target's mana +        power = damage * curPower / 100; +        if (caster) +        { +            uint32 casterPower = damage * caster->GetPower(powertype) / 50; +            if (casterPower<curPower) +                curPower = casterPower; +        } +    } +    // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)      if ( powertype == POWER_MANA && unitTarget->GetTypeId() == TYPEID_PLAYER )          power -= ((Player*)unitTarget)->GetSpellCritDamageReduction(power); @@ -2393,7 +2526,7 @@ void Spell::SpellDamageHeal(uint32 /*i*/)              Unit::AuraList const& mDummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY);              for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)                  if((*i)->GetId() == 45062) -                    damageAmount+=(*i)->GetModifierValue(); +                    damageAmount+=(*i)->GetModifier()->m_amount;              if (damageAmount)                  m_caster->RemoveAurasDueToSpell(45062); @@ -2408,7 +2541,7 @@ void Spell::SpellDamageHeal(uint32 /*i*/)              for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)              {                  if((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID -                    && ((*i)->GetSpellProto()->SpellFamilyFlags == 0x40 || (*i)->GetSpellProto()->SpellFamilyFlags == 0x10) ) +                    && ((*i)->GetSpellProto()->SpellFamilyFlags.IsEqual(0x40) || (*i)->GetSpellProto()->SpellFamilyFlags.IsEqual(0x10)) )                  {                      if(!targetAura || (*i)->GetAuraDuration() < targetAura->GetAuraDuration())                          targetAura = *i; @@ -2421,29 +2554,29 @@ void Spell::SpellDamageHeal(uint32 /*i*/)                  return;              } -            int32 tickheal = targetAura->GetModifierValuePerStack(); +            int32 tickheal = targetAura->GetModifier()->m_amount;              if(Unit* auraCaster = targetAura->GetCaster()) -                tickheal = auraCaster->SpellHealingBonus(targetAura->GetSpellProto(), tickheal, DOT, unitTarget); +                tickheal = auraCaster->SpellHealingBonus(unitTarget, targetAura->GetSpellProto(), tickheal, DOT);              //int32 tickheal = targetAura->GetSpellProto()->EffectBasePoints[idx] + 1;              //It is said that talent bonus should not be included -            //int32 tickheal = targetAura->GetModifierValue(); +              int32 tickcount = 0;              if(targetAura->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID)              { -                switch(targetAura->GetSpellProto()->SpellFamilyFlags)//TODO: proper spellfamily for 3.0.x +                switch(targetAura->GetSpellProto()->SpellFamilyFlags[0])//TODO: proper spellfamily for 3.0.x                  {                      case 0x10:  tickcount = 4;  break; // Rejuvenation                      case 0x40:  tickcount = 6;  break; // Regrowth                  }              }              addhealth += tickheal * tickcount; -            unitTarget->RemoveAurasDueToCasterSpell(targetAura->GetId(), targetAura->GetCasterGUID()); +            unitTarget->RemoveAurasByCasterSpell(targetAura->GetId(), targetAura->GetCasterGUID());              //addhealth += tickheal * tickcount;              //addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth,HEAL, unitTarget);          }          else -            addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth,HEAL, unitTarget); +            addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, addhealth, HEAL);          m_damage -= addhealth;      } @@ -2484,7 +2617,7 @@ void Spell::EffectHealMechanical( uint32 /*i*/ )          if (!caster)              return; -        uint32 addhealth = caster->SpellHealingBonus(m_spellInfo, uint32(damage), HEAL, unitTarget); +        uint32 addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, uint32(damage), HEAL);          caster->SendHealSpellLog(unitTarget, m_spellInfo->Id, addhealth, false);          unitTarget->ModifyHealth( int32(damage) );      } @@ -2515,7 +2648,7 @@ void Spell::EffectHealthLeech(uint32 i)      if(m_caster->isAlive())      { -        new_damage = m_caster->SpellHealingBonus(m_spellInfo, new_damage, HEAL, m_caster); +        new_damage = m_caster->SpellHealingBonus(m_caster, m_spellInfo, new_damage, HEAL);          m_caster->ModifyHealth(new_damage); @@ -2568,8 +2701,8 @@ void Spell::DoCreateItem(uint32 i, uint32 itemtype)      if (num_to_add < 1)          num_to_add = 1; -    if (num_to_add > pProto->Stackable) -        num_to_add = pProto->Stackable; +    if (num_to_add > pProto->GetMaxStackSize()) +        num_to_add = pProto->GetMaxStackSize();      // init items_count to 1, since 1 item will be created regardless of specialization      int items_count=1; @@ -2661,9 +2794,24 @@ void Spell::EffectCreateItem(uint32 i)      DoCreateItem(i,m_spellInfo->EffectItemType[i]);  } +void Spell::EffectCreateItem2(uint32 i) +{ +    // special case: generate using spell_loot_template +    if(!m_spellInfo->EffectItemType[i]) +    { +        if(m_caster->GetTypeId()!=TYPEID_PLAYER) +            return; + +        // create some random items +        ((Player*)m_caster)->AutoStoreLoot(m_spellInfo->Id,LootTemplates_Spell); +        return; +    } +    DoCreateItem(i,m_spellInfo->EffectItemType[i]); +} +  void Spell::EffectPersistentAA(uint32 i)  { -    float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); +    float radius = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));      if(Player* modOwner = m_originalCaster->GetSpellModOwner())          modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius); @@ -2691,6 +2839,8 @@ void Spell::EffectEnergize(uint32 i)      if(m_spellInfo->EffectMiscValue[i] < 0 || m_spellInfo->EffectMiscValue[i] >= MAX_POWERS)          return; +    Powers power = Powers(m_spellInfo->EffectMiscValue[i]); +      // Some level depends spells      int multiplier = 0;      int level_diff = 0; @@ -2718,11 +2868,18 @@ void Spell::EffectEnergize(uint32 i)      if (level_diff > 0)          damage -= multiplier * level_diff; +    //Judgement of wisdom energize effect +    if(m_spellInfo->Id == 20268) +    { +        if(unitTarget->GetTypeId() == TYPEID_PLAYER) +        { +            damage = unitTarget->GetCreateMana() * damage / 100; +        } +    } +      if(damage < 0)          return; -    Powers power = Powers(m_spellInfo->EffectMiscValue[i]); -      if(unitTarget->GetMaxPower(power) == 0)          return; @@ -2790,7 +2947,7 @@ void Spell::EffectEnergisePct(uint32 i)      uint32 gain = damage * maxPower / 100;      unitTarget->ModifyPower(power, gain); -    m_caster->SendEnergizeSpellLog(unitTarget, m_spellInfo->Id, damage, power); +    m_caster->SendEnergizeSpellLog(unitTarget, m_spellInfo->Id, gain, power);  }  void Spell::SendLoot(uint64 guid, LootType loottype) @@ -2957,10 +3114,10 @@ void Spell::EffectOpenLock(uint32 /*i*/)      }      // check key -    for(int i = 0; i < 5; ++i) +    for(int i = 0; i < 8; ++i)      { -        // type==1 This means lockInfo->key[i] is an item -        if(lockInfo->keytype[i]==LOCK_KEY_ITEM && lockInfo->key[i] && m_CastItem && m_CastItem->GetEntry()==lockInfo->key[i]) +        // Type==1 This means lockInfo->Index[i] is an item +        if(lockInfo->Type[i]==LOCK_KEY_ITEM && lockInfo->Index[i] && m_CastItem && m_CastItem->GetEntry()==lockInfo->Index[i])          {              SendLoot(guid, loottype);              return; @@ -2978,9 +3135,9 @@ void Spell::EffectOpenLock(uint32 /*i*/)      // skill bonus provided by casting spell (mostly item spells)      uint32 spellSkillBonus = uint32(damage/*m_currentBasePoints[0]+1*/); -    uint32 reqSkillValue = lockInfo->requiredminingskill; +    uint32 reqSkillValue = lockInfo->Skill[0]; -    if(lockInfo->requiredlockskill)                         // required pick lock skill applying +    if(lockInfo->Skill[1])                                  // required pick lock skill applying      {          if(SkillId != SKILL_LOCKPICKING)                    // wrong skill (cheating?)          { @@ -2988,7 +3145,7 @@ void Spell::EffectOpenLock(uint32 /*i*/)              return;          } -        reqSkillValue = lockInfo->requiredlockskill; +        reqSkillValue = lockInfo->Skill[1];      }      else if(SkillId == SKILL_LOCKPICKING)                   // apply picklock skill to wrong target      { @@ -3006,8 +3163,7 @@ void Spell::EffectOpenLock(uint32 /*i*/)          }          // update skill if really known -        uint32 SkillValue = player->GetPureSkillValue(SkillId); -        if(SkillValue)                                      // non only item base skill +        if(uint32 SkillValue = player->GetPureSkillValue(SkillId))          {              if(gameObjTarget)              { @@ -3019,7 +3175,6 @@ void Spell::EffectOpenLock(uint32 /*i*/)              else if(itemTarget)              {                  // Do one skill-up -                uint32 SkillValue = player->GetPureSkillValue(SkillId);                  player->UpdateGatherSkill(SkillId, SkillValue, reqSkillValue);              }          } @@ -3172,7 +3327,12 @@ void Spell::EffectSummonType(uint32 i)          case SUMMON_TYPE_POSESSED3:              EffectSummonPossessed(i);              break; +        case SUMMON_TYPE_FORCE_OF_NATURE: +        case SUMMON_TYPE_GUARDIAN2: +            EffectSummonGuardian(i); +            break;          case SUMMON_TYPE_WILD: +        case SUMMON_TYPE_WILD2:              EffectSummonWild(i);              break;          case SUMMON_TYPE_DEMON: @@ -3262,8 +3422,8 @@ void Spell::EffectLearnSpell(uint32 i)      Player *player = (Player*)unitTarget; -    uint32 spellToLearn = (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) ? damage : m_spellInfo->EffectTriggerSpell[i]; -    player->learnSpell(spellToLearn); +    uint32 spellToLearn = ((m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) || (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN_PET)) ? damage : m_spellInfo->EffectTriggerSpell[i]; +    player->learnSpell(spellToLearn,false);      sLog.outDebug( "Spell: Player %u have learned spell %u from NpcGUID=%u", player->GetGUIDLow(), spellToLearn, m_caster->GetGUIDLow() );  } @@ -3318,18 +3478,10 @@ void Spell::EffectDispel(uint32 i)              SpellEntry const* spellInfo = aur->GetSpellProto();              // Base dispel chance              // TODO: possible chance depend from spell level?? -            int32 miss_chance = 0; -            // Apply dispel mod from aura caster -            if (Unit *caster = aur->GetCaster()) -            { -                if ( Player* modOwner = caster->GetSpellModOwner() ) -                    modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_RESIST_DISPEL_CHANCE, miss_chance, this); -            } -            // Try dispel -            if (roll_chance_i(miss_chance)) -                fail_list.push_back(aur->GetId()); -            else +            if (aur->GetDispelChance(this))                  success_list.push_back(std::pair<uint32,uint64>(aur->GetId(),aur->GetCasterGUID())); +            else +                fail_list.push_back(aur->GetId());              // Remove buff from list for prevent doubles              for (std::vector<Aura *>::iterator j = dispel_list.begin(); j != dispel_list.end(); )              { @@ -3359,19 +3511,14 @@ void Spell::EffectDispel(uint32 i)                  SpellEntry const* spellInfo = sSpellStore.LookupEntry(j->first);                  data << uint32(spellInfo->Id);              // Spell Id                  data << uint8(0);                           // 0 - dispelled !=0 cleansed -                if(spellInfo->StackAmount!= 0) -                { -                    //Why are Aura's Removed by EffIndex? Auras should be removed as a whole..... -                    unitTarget->RemoveSingleAuraFromStackByDispel(spellInfo->Id); -                } -                else +                //Why are Aura's Removed by EffIndex? Auras should be removed as a whole.....                  unitTarget->RemoveAurasDueToSpellByDispel(spellInfo->Id, j->second, m_caster);               }              m_caster->SendMessageToSet(&data, true);              // On succes dispel              // Devour Magic -            if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->Category == 12) +            if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->Category == SPELLCATEGORY_DEVOUR_MAGIC)              {                  uint32 heal_spell = 0;                  switch (m_spellInfo->Id) @@ -3382,6 +3529,7 @@ void Spell::EffectDispel(uint32 i)                      case 19736: heal_spell = 19735; break;                      case 27276: heal_spell = 27278; break;                      case 27277: heal_spell = 27279; break; +                    case 48011: heal_spell = 48010; break;                      default:                          sLog.outDebug("Spell for Devour Magic %d not handled in Spell::EffectDispel", m_spellInfo->Id);                          break; @@ -3443,7 +3591,7 @@ void Spell::EffectDistract(uint32 /*i*/)          // Set creature Distracted, Stop it, And turn it          unitTarget->SetOrientation(angle);          unitTarget->StopMoving(); -        unitTarget->GetMotionMaster()->MoveDistract(damage*1000); +        unitTarget->GetMotionMaster()->MoveDistract(damage*IN_MILISECONDS);      }  } @@ -3482,7 +3630,7 @@ void Spell::EffectAddFarsight(uint32 i)      if (m_caster->GetTypeId() != TYPEID_PLAYER)          return; -    float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); +    float radius = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));      int32 duration = GetSpellDuration(m_spellInfo);      DynamicObject* dynObj = new DynamicObject;      if(!dynObj->Create(objmgr.GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, 4, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, duration, radius)) @@ -3529,7 +3677,7 @@ void Spell::EffectSummonWild(uint32 i)      float center_y = m_targets.m_destY;      float center_z = m_targets.m_destZ; -    float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); +    float radius = GetSpellRadiusForHostile(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));      int32 amount = damage > 0 ? damage : 1; @@ -3625,12 +3773,13 @@ void Spell::EffectSummonGuardian(uint32 i)      float center_y = m_targets.m_destY;      float center_z = m_targets.m_destZ; -    float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); +    float radius = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));      int32 amount = damage > 0 ? damage : 1;      for(int32 count = 0; count < amount; ++count)      { +          float px, py, pz;          // If dest location if present          if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) @@ -3692,7 +3841,7 @@ void Spell::EffectTeleUnitsFaceCaster(uint32 i)          return;      uint32 mapid = m_caster->GetMapId(); -    float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); +    float dis = m_caster->GetSpellRadiusForTarget(unitTarget, sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));      float fx,fy,fz;      m_caster->GetClosePoint(fx,fy,fz,unitTarget->GetObjectSize(),dis); @@ -3739,7 +3888,7 @@ void Spell::EffectTradeSkill(uint32 /*i*/)      // ((Player*)unitTarget)->SetSkill(skillid,skillval?skillval:1,skillmax+75);  } -void Spell::EffectEnchantItemPerm(uint32 i) +void Spell::EffectEnchantItemPerm(uint32 effect_idx)  {      if(m_caster->GetTypeId() != TYPEID_PLAYER)          return; @@ -3748,37 +3897,95 @@ void Spell::EffectEnchantItemPerm(uint32 i)      Player* p_caster = (Player*)m_caster; +    // not grow at item use at item case      p_caster->UpdateCraftSkill(m_spellInfo->Id); -    if (m_spellInfo->EffectMiscValue[i]) +    uint32 enchant_id = m_spellInfo->EffectMiscValue[effect_idx]; +    if (!enchant_id) +        return; + +    SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); +    if(!pEnchant) +        return; + +    // item can be in trade slot and have owner diff. from caster +    Player* item_owner = itemTarget->GetOwner(); +    if(!item_owner) +        return; + +    if(item_owner!=p_caster && p_caster->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) )      { -        uint32 enchant_id = m_spellInfo->EffectMiscValue[i]; +        sLog.outCommand(p_caster->GetSession()->GetAccountId(),"GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)", +            p_caster->GetName(),p_caster->GetSession()->GetAccountId(), +            itemTarget->GetProto()->Name1,itemTarget->GetEntry(), +            item_owner->GetName(),item_owner->GetSession()->GetAccountId()); +    } -        SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); -        if(!pEnchant) -            return; +    // remove old enchanting before applying new if equipped +    item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,false); -        // item can be in trade slot and have owner diff. from caster -        Player* item_owner = itemTarget->GetOwner(); -        if(!item_owner) -            return; +    itemTarget->SetEnchantment(PERM_ENCHANTMENT_SLOT, enchant_id, 0, 0); -        if(item_owner!=p_caster && p_caster->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) ) +    // add new enchanting if equipped +    item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,true); +} + +void Spell::EffectEnchantItemPrismatic(uint32 effect_idx) +{ +    if(m_caster->GetTypeId() != TYPEID_PLAYER) +        return; +    if (!itemTarget) +        return; + +    Player* p_caster = (Player*)m_caster; + +    uint32 enchant_id = m_spellInfo->EffectMiscValue[effect_idx]; +    if (!enchant_id) +        return; + +    SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); +    if(!pEnchant) +        return; + +    // support only enchantings with add socket in this slot +    { +        bool add_socket = false; +        for(int i = 0; i < 3; ++i)          { -            sLog.outCommand(p_caster->GetSession()->GetAccountId(),"GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)", -                p_caster->GetName(),p_caster->GetSession()->GetAccountId(), -                itemTarget->GetProto()->Name1,itemTarget->GetEntry(), -                item_owner->GetName(),item_owner->GetSession()->GetAccountId()); +            if(pEnchant->type[i]==ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET) +            { +                add_socket = true; +                break; +            }          } +        if(!add_socket) +        { +            sLog.outError("Spell::EffectEnchantItemPrismatic: attempt apply enchant spell %u with SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC (%u) but without ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET (u), not suppoted yet.", +                m_spellInfo->Id,SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC,ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET); +            return; +        } +    } -        // remove old enchanting before applying new if equipped -        item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,false); - -        itemTarget->SetEnchantment(PERM_ENCHANTMENT_SLOT, enchant_id, 0, 0); +    // item can be in trade slot and have owner diff. from caster +    Player* item_owner = itemTarget->GetOwner(); +    if(!item_owner) +        return; -        // add new enchanting if equipped -        item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,true); +    if(item_owner!=p_caster && p_caster->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) ) +    { +        sLog.outCommand(p_caster->GetSession()->GetAccountId(),"GM %s (Account: %u) enchanting(perm): %s (Entry: %d) for player: %s (Account: %u)", +            p_caster->GetName(),p_caster->GetSession()->GetAccountId(), +            itemTarget->GetProto()->Name1,itemTarget->GetEntry(), +            item_owner->GetName(),item_owner->GetSession()->GetAccountId());      } + +    // remove old enchanting before applying new if equipped +    item_owner->ApplyEnchantment(itemTarget,PRISMATIC_ENCHANTMENT_SLOT,false); + +    itemTarget->SetEnchantment(PRISMATIC_ENCHANTMENT_SLOT, enchant_id, 0, 0); + +    // add new enchanting if equipped +    item_owner->ApplyEnchantment(itemTarget,PRISMATIC_ENCHANTMENT_SLOT,true);  }  void Spell::EffectEnchantItemTmp(uint32 i) @@ -3873,13 +4080,13 @@ void Spell::EffectEnchantItemTmp(uint32 i)      else if(m_spellInfo->SpellFamilyName==SPELLFAMILY_SHAMAN)          duration = 1800;                                    // 30 mins      // other cases with this SpellVisual already selected -    else if(m_spellInfo->SpellVisual==215) +    else if(m_spellInfo->SpellVisual[0]==215)          duration = 1800;                                    // 30 mins      // some fishing pole bonuses -    else if(m_spellInfo->SpellVisual==563) +    else if(m_spellInfo->SpellVisual[0]==563)          duration = 600;                                     // 10 mins      // shaman rockbiter enchantments -    else if(m_spellInfo->SpellVisual==0) +    else if(m_spellInfo->SpellVisual[0]==0)          duration = 1800;                                    // 30 mins      else if(m_spellInfo->Id==29702)          duration = 300;                                     // 5 mins @@ -3942,14 +4149,16 @@ void Spell::EffectTameCreature(uint32 /*i*/)      creatureTarget->RemoveCorpse();      creatureTarget->SetHealth(0);                       // just for nice GM-mode view +    uint32 level = (creatureTarget->getLevel() < (m_caster->getLevel() - 5)) ? (m_caster->getLevel() - 5) : creatureTarget->getLevel(); +      // prepare visual effect for levelup -    pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()-1); +    pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);      // add to world      pet->GetMap()->Add((Creature*)pet);      // visual effect for levelup -    pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()); +    pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);      // caster have pet now      m_caster->SetPet(pet); @@ -4017,6 +4226,7 @@ void Spell::EffectSummonPet(uint32 i)      owner->GetClosePoint(x, y, z, owner->GetObjectSize());      Pet* pet = owner->SummonPet(petentry, x, y, z, owner->GetOrientation(), SUMMON_PET, 0);      if(!pet) +          return;      if(m_caster->GetTypeId() == TYPEID_UNIT) @@ -4030,9 +4240,12 @@ void Spell::EffectSummonPet(uint32 i)      pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);      // this enables popup window (pet dismiss, cancel), hunter pet additional flags set later -    pet->SetUInt32Value(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE); +    if(m_caster->GetTypeId() == TYPEID_PLAYER) +        pet->SetUInt32Value(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE); +      pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL)); +    pet->InitTalentForLevel();      // generate new name for summon pet      std::string new_name=objmgr.GeneratePetName(petentry);      if(!new_name.empty()) @@ -4056,7 +4269,6 @@ void Spell::EffectLearnPetSpell(uint32 i)      if(!learn_spellproto)          return; -    pet->SetTP(pet->m_TrainingPoints - pet->GetTPForSpell(learn_spellproto->Id));      pet->learnSpell(learn_spellproto->Id);      pet->SavePetToDB(PET_SAVE_AS_CURRENT); @@ -4120,20 +4332,18 @@ void Spell::SpellDamageWeaponDmg(uint32 i)          case SPELLFAMILY_WARRIOR:          {              // Devastate bonus and sunder armor refresh -            if(m_spellInfo->SpellVisual == 671 && m_spellInfo->SpellIconID == 1508) +            if(m_spellInfo->SpellVisual[0] == 671 && m_spellInfo->SpellIconID == 1508)              {                  uint32 stack = 0; -                  Unit::AuraList const& list = unitTarget->GetAurasByType(SPELL_AURA_MOD_RESISTANCE);                  for(Unit::AuraList::const_iterator itr=list.begin();itr!=list.end();++itr)                  {                      SpellEntry const *proto = (*itr)->GetSpellProto();                      if(proto->SpellFamilyName == SPELLFAMILY_WARRIOR -                        && proto->SpellFamilyFlags == SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR) +                        && proto->SpellFamilyFlags.IsEqual(SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR) +                        && (*itr)->GetCasterGUID() == m_caster->GetGUID())                      { -                        int32 duration = GetSpellDuration(proto); -                        (*itr)->SetAuraDuration(duration); -                        (*itr)->UpdateAuraDuration(); +                        (*itr)->RefreshAura();                          stack = (*itr)->GetStackAmount();                          break;                      } @@ -4162,7 +4372,7 @@ void Spell::SpellDamageWeaponDmg(uint32 i)                          if (!spellInfo)                              continue; -                        if (spellInfo->SpellFamilyFlags == SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR +                        if (spellInfo->SpellFamilyFlags.IsEqual(SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR)                              && spellInfo->Id != m_spellInfo->Id                              && spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR)                          { @@ -4171,19 +4381,21 @@ void Spell::SpellDamageWeaponDmg(uint32 i)                          }                      }                  } +                if (stack) +                    spell_bonus += stack * CalculateDamage(2, unitTarget);              }              break;          }          case SPELLFAMILY_ROGUE:          {              // Hemorrhage -            if(m_spellInfo->SpellFamilyFlags & 0x2000000) +            if(m_spellInfo->SpellFamilyFlags[0] & 0x2000000)              {                  if(m_caster->GetTypeId()==TYPEID_PLAYER)                      ((Player*)m_caster)->AddComboPoints(unitTarget, 1);              }              // Mutilate (for each hand) -            else if(m_spellInfo->SpellFamilyFlags & 0x600000000LL) +            else if(m_spellInfo->SpellFamilyFlags[1] & 0x6)              {                  bool found = false;                  // fast check @@ -4204,16 +4416,16 @@ void Spell::SpellDamageWeaponDmg(uint32 i)                  }                  if(found) -                    totalDamagePercentMod *= 1.5f;          // 150% if poisoned +                    totalDamagePercentMod *= 1.2f;          // 120% if poisoned              }              break;          }          case SPELLFAMILY_PALADIN:          {              // Seal of Command - receive benefit from Spell Damage and Healing -            if(m_spellInfo->SpellFamilyFlags & 0x00000002000000LL) +            if(m_spellInfo->SpellFamilyFlags[0] & 0x2000000)              { -                spell_bonus += int32(0.20f*m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo))); +                spell_bonus += int32(0.23f*m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)));                  spell_bonus += int32(0.29f*m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget));              }              break; @@ -4222,7 +4434,7 @@ void Spell::SpellDamageWeaponDmg(uint32 i)          {              // Skyshatter Harness item set bonus              // Stormstrike -            if(m_spellInfo->SpellFamilyFlags & 0x001000000000LL) +            if(m_spellInfo->SpellFamilyFlags[1] & 0x0010)              {                  Unit::AuraList const& m_OverrideClassScript = m_caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);                  for(Unit::AuraList::const_iterator i = m_OverrideClassScript.begin(); i != m_OverrideClassScript.end(); ++i) @@ -4240,7 +4452,7 @@ void Spell::SpellDamageWeaponDmg(uint32 i)          case SPELLFAMILY_DRUID:          {              // Mangle (Cat): CP -            if(m_spellInfo->SpellFamilyFlags==0x0000040000000000LL) +            if(m_spellInfo->SpellFamilyFlags.IsEqual(0,0x00000400))              {                  if(m_caster->GetTypeId()==TYPEID_PLAYER)                      ((Player*)m_caster)->AddComboPoints(unitTarget,1); @@ -4325,33 +4537,6 @@ void Spell::SpellDamageWeaponDmg(uint32 i)      // Add melee damage bonuses (also check for negative)      m_caster->MeleeDamageBonus(unitTarget, &eff_damage, m_attackType, m_spellInfo);      m_damage+= eff_damage; - -    // take ammo -    if(m_attackType == RANGED_ATTACK && m_caster->GetTypeId() == TYPEID_PLAYER) -    { -        Item *pItem = ((Player*)m_caster)->GetWeaponForAttack( RANGED_ATTACK ); - -        // wands don't have ammo -        if(!pItem  || pItem->IsBroken() || pItem->GetProto()->SubClass==ITEM_SUBCLASS_WEAPON_WAND) -            return; - -        if( pItem->GetProto()->InventoryType == INVTYPE_THROWN ) -        { -            if(pItem->GetMaxStackCount()==1) -            { -                // decrease durability for non-stackable throw weapon -                ((Player*)m_caster)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_RANGED); -            } -            else -            { -                // decrease items amount for stackable throw weapon -                uint32 count = 1; -                ((Player*)m_caster)->DestroyItemCount( pItem, count, true); -            } -        } -        else if(uint32 ammo = ((Player*)m_caster)->GetUInt32Value(PLAYER_AMMO_ID)) -            ((Player*)m_caster)->DestroyItemCount(ammo, 1, true); -    }  }  void Spell::EffectThreat(uint32 /*i*/) @@ -4396,7 +4581,7 @@ void Spell::EffectInterruptCast(uint32 i)              {                  if(m_originalCaster)                  { -                    int32 duration = m_originalCaster->CalculateSpellDuration(m_spellInfo, i, unitTarget); +                    int32 duration = m_originalCaster->ModSpellDuration(m_spellInfo, i, unitTarget, m_originalCaster->CalcSpellDuration(m_spellInfo));                      unitTarget->ProhibitSpellScholl(GetSpellSchoolMask(unitTarget->m_currentSpells[i]->m_spellInfo), duration/*GetSpellDuration(m_spellInfo)*/);                  }                  unitTarget->InterruptSpell(i,false); @@ -4428,14 +4613,14 @@ void Spell::EffectSummonObjectWild(uint32 i)      Map *map = target->GetMap();      if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), gameobject_id, map, -        x, y, z, target->GetOrientation(), 0, 0, 0, 0, 100, 1)) +        m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), 0, 0, 0, 0, 100, 1))      {          delete pGameObj;          return;      }      int32 duration = GetSpellDuration(m_spellInfo); -    pGameObj->SetRespawnTime(duration > 0 ? duration/1000 : 0); +    pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILISECONDS : 0);      pGameObj->SetSpellId(m_spellInfo->Id);      if(pGameObj->GetGoType() != GAMEOBJECT_TYPE_FLAGDROP)   // make dropped flag clickable for other players (not set owner guid (created by) for this)... @@ -4476,9 +4661,9 @@ void Spell::EffectSummonObjectWild(uint32 i)      {          GameObject* linkedGO = new GameObject;          if(linkedGO->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), linkedEntry, map, -            x, y, z, target->GetOrientation(), 0, 0, 0, 0, 100, 1)) +            m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), 0, 0, 0, 0, 100, 1))          { -            linkedGO->SetRespawnTime(duration > 0 ? duration/1000 : 0); +            linkedGO->SetRespawnTime(duration > 0 ? duration/IN_MILISECONDS : 0);              linkedGO->SetSpellId(m_spellInfo->Id);              m_caster->AddGameObject(linkedGO); @@ -4497,441 +4682,596 @@ void Spell::EffectScriptEffect(uint32 effIndex)  {      // TODO: we must implement hunter pet summon at login there (spell 6962) -    // by spell id -    switch(m_spellInfo->Id) +    switch(m_spellInfo->SpellFamilyName)      { -        // PX-238 Winter Wondervolt TRAP -        case 26275: +        case SPELLFAMILY_GENERIC:          { -            if( unitTarget->HasAura(26272,0) -             || unitTarget->HasAura(26157,0) -             || unitTarget->HasAura(26273,0) -             || unitTarget->HasAura(26274,0)) -                return; +            switch(m_spellInfo->Id) +            { +                // PX-238 Winter Wondervolt TRAP +                case 26275: +                { +                    uint32 spells[4] = { 26272, 26157, 26273, 26274 }; -            uint32 iTmpSpellId; +                    // check presence +                    for(int j = 0; j < 4; ++j) +                        if(unitTarget->HasAura(spells[j],0)) +                            return; -            switch(urand(0,3)) -            { -                case 0: -                    iTmpSpellId = 26272; -                    break; -                case 1: -                    iTmpSpellId = 26157; -                    break; -                case 2: -                    iTmpSpellId = 26273; -                    break; -                case 3: -                    iTmpSpellId = 26274; -                    break; -            } +                    // select spell +                    uint32 iTmpSpellId = spells[urand(0,3)]; -            unitTarget->CastSpell(unitTarget, iTmpSpellId, true); +                    // cast +                    unitTarget->CastSpell(unitTarget, iTmpSpellId, true); +                    return; +                } +                // Bending Shinbone +                case 8856: +                { +                    if(!itemTarget && m_caster->GetTypeId()!=TYPEID_PLAYER) +                        return; -            return; -        } +                    uint32 spell_id = 0; +                    switch(urand(1,5)) +                    { +                    case 1:  spell_id = 8854; break; +                    default: spell_id = 8855; break; +                    } -        // Bending Shinbone -        case 8856: -        { -            if(!itemTarget && m_caster->GetTypeId()!=TYPEID_PLAYER) -                return; +                    m_caster->CastSpell(m_caster,spell_id,true,NULL); +                    return; +                } +                // Brittle Armor - need remove one 24575 Brittle Armor aura +                case 24590: +                    unitTarget->RemoveSingleSpellAurasFromStack(24575); +                    return; +                // Mercurial Shield - need remove one 26464 Mercurial Shield aura +                case 26465: +                    unitTarget->RemoveSingleSpellAurasFromStack(26464); +                    return; +                // Orb teleport spells +                case 25140: +                case 25143: +                case 25650: +                case 25652: +                case 29128: +                case 29129: +                case 35376: +                case 35727: +                { +                    if(!unitTarget) +                        return; -            uint32 spell_id = 0; -            switch(urand(1,5)) -            { -                case 1:  spell_id = 8854; break; -                default: spell_id = 8855; break; -            } +                    uint32 spellid; +                    switch(m_spellInfo->Id) +                    { +                        case 25140: spellid =  32571; break; +                        case 25143: spellid =  32572; break; +                        case 25650: spellid =  30140; break; +                        case 25652: spellid =  30141; break; +                        case 29128: spellid =  32568; break; +                        case 29129: spellid =  32569; break; +                        case 35376: spellid =  25649; break; +                        case 35727: spellid =  35730; break; +                        default: +                            return; +                    } -            m_caster->CastSpell(m_caster,spell_id,true,NULL); -            return; -        } +                    unitTarget->CastSpell(unitTarget,spellid,false); +                    return; +                } +                // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell) +                case 22539: +                case 22972: +                case 22975: +                case 22976: +                case 22977: +                case 22978: +                case 22979: +                case 22980: +                case 22981: +                case 22982: +                case 22983: +                case 22984: +                case 22985: +                { +                    if(!unitTarget || !unitTarget->isAlive()) +                        return; -        // Healthstone creating spells -        case  6201: -        case  6202: -        case  5699: -        case 11729: -        case 11730: -        case 27230: -        { -            uint32 itemtype; -            uint32 rank = 0; -            Unit::AuraList const& mDummyAuras = unitTarget->GetAurasByType(SPELL_AURA_DUMMY); -            for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i) -            { -                if((*i)->GetId() == 18692) +                    // Onyxia Scale Cloak +                    if(unitTarget->GetDummyAura(22683)) +                        return; + +                    // Shadow Flame +                    m_caster->CastSpell(unitTarget, 22682, true); +                    return; +                } +                // Summon Black Qiraji Battle Tank +                case 26656:                  { -                    rank = 1; +                    if(!unitTarget) +                        return; + +                    // Prevent stacking of mounts +                    unitTarget->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); + +                    // Two separate mounts depending on area id (allows use both in and out of specific instance) +                    if (unitTarget->GetAreaId() == 3428) +                        unitTarget->CastSpell(unitTarget, 25863, false); +                    else +                        unitTarget->CastSpell(unitTarget, 26655, false);                      break;                  } -                else if((*i)->GetId() == 18693) +                // Piccolo of the Flaming Fire +                case 17512:                  { -                    rank = 2; +                    if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) +                        return; +                    unitTarget->HandleEmoteCommand(EMOTE_STATE_DANCE);                      break;                  } -            } +                // Escape artist +                case 20589: +                { +                    if(!unitTarget) +                        return; +                    // It is said that removing effects by script should include dispel resist mods +                    unitTarget->RemoveSpellsCausingAuraWithDispel(SPELL_AURA_MOD_ROOT, this); +                    unitTarget->RemoveSpellsCausingAuraWithDispel(SPELL_AURA_MOD_DECREASE_SPEED, this); +                } +                // Mirren's Drinking Hat +                case 29830: +                { +                    uint32 item = 0; +                    switch ( urand(1,6) ) +                    { +                        case 1:case 2:case 3: +                            item = 23584;break;             // Loch Modan Lager +                        case 4:case 5: +                            item = 23585;break;             // Stouthammer Lite +                        case 6: +                            item = 23586;break;             // Aerie Peak Pale Ale +                    } +                    if (item) +                        DoCreateItem(effIndex,item); +                    break; +                } +                // Improved Sprint +                case 30918: +                { +                    // Removes snares and roots. +                    uint32 mechanic_mask = (1<<MECHANIC_ROOT) | (1<<MECHANIC_SNARE); +                    Unit::AuraMap& Auras = unitTarget->GetAuras(); +                    for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) +                    { +                        next = iter; +                        ++next; +                        Aura *aur = iter->second; +                        if (!aur->IsPositive())             //only remove negative spells +                        { +                            // check for mechanic mask +                            if(GetSpellMechanicMask(aur->GetSpellProto(), aur->GetEffIndex()) & mechanic_mask) +                            { +                                unitTarget->RemoveAurasDueToSpell(aur->GetId()); +                                if(Auras.empty()) +                                    break; +                                else +                                    next = Auras.begin(); +                            } +                        } +                    } +                    break; +                } +                /*// Flame Crash +                case 41126: +                { +                    if(!unitTarget) +                        return; -            static uint32 const itypes[6][3] = { -                { 5512,19004,19005},                        // Minor Healthstone -                { 5511,19006,19007},                        // Lesser Healthstone -                { 5509,19008,19009},                        // Healthstone -                { 5510,19010,19011},                        // Greater Healthstone -                { 9421,19012,19013},                        // Major Healthstone -                {22103,22104,22105}                         // Master Healthstone -            }; +                    unitTarget->CastSpell(unitTarget, 41131, true); +                    break; +                }*/ +                // Draw Soul +                case 40904: +                { +                    if(!unitTarget) +                        return; -            switch(m_spellInfo->Id) -            { -                case  6201: itemtype=itypes[0][rank];break; // Minor Healthstone -                case  6202: itemtype=itypes[1][rank];break; // Lesser Healthstone -                case  5699: itemtype=itypes[2][rank];break; // Healthstone -                case 11729: itemtype=itypes[3][rank];break; // Greater Healthstone -                case 11730: itemtype=itypes[4][rank];break; // Major Healthstone -                case 27230: itemtype=itypes[5][rank];break; // Master Healthstone -                default: -                    return; -            } -            DoCreateItem( effIndex, itemtype ); -            return; -        } -        // Brittle Armor - need remove one 24575 Brittle Armor aura -        case 24590: -            unitTarget->RemoveSingleAuraFromStack(24575, 0); -            unitTarget->RemoveSingleAuraFromStack(24575, 1); -            return; -        // Mercurial Shield - need remove one 26464 Mercurial Shield aura -        case 26465: -            unitTarget->RemoveSingleAuraFromStack(26464, 0); -            return; -        // Orb teleport spells -        case 25140: -        case 25143: -        case 25650: -        case 25652: -        case 29128: -        case 29129: -        case 35376: -        case 35727: -        { -            if(!unitTarget) -                return; +                    unitTarget->CastSpell(m_caster, 40903, true); +                    break; +                } +                case 48025:                                     // Headless Horseman's Mount +                { +                if(!unitTarget) +                        return; +                 +                    switch(((Player*)unitTarget)->GetBaseSkillValue(762)) +                    { +                    case 75: unitTarget->CastSpell(unitTarget, 51621, true); break;; +                    case 150: unitTarget->CastSpell(unitTarget, 48024, true); break; +                    case 225: unitTarget->CastSpell(unitTarget, 51617, true); break; +                    case 300: unitTarget->CastSpell(unitTarget, 48023, true); break; +                    default: break; +                    } +                    break; +                } +                case 47977:                                     // Magic Broom +                { +                    if(!unitTarget) +                        return; -            uint32 spellid; -            switch(m_spellInfo->Id) -            { -                case 25140: spellid =  32571; break; -                case 25143: spellid =  32572; break; -                case 25650: spellid =  30140; break; -                case 25652: spellid =  30141; break; -                case 29128: spellid =  32568; break; -                case 29129: spellid =  32569; break; -                case 35376: spellid =  25649; break; -                case 35727: spellid =  35730; break; -                default: -                    return; -            } +                    if(unitTarget) +                    { +                        switch(((Player*)unitTarget)->GetBaseSkillValue(762)) +                        { +                        case 75: unitTarget->CastSpell(unitTarget, 42680, true); break;; +                        case 150: case 225: case 300: unitTarget->CastSpell(unitTarget, 42683, true); break; +                        default: break; +                        } +                    } +                    break; +                } +                case 41931: +                { +                    if(m_caster->GetTypeId() != TYPEID_PLAYER) +                        return; -            unitTarget->CastSpell(unitTarget,spellid,false); -            return; -        } +                    int bag=19; +                    int slot=0; +                    Item* item = NULL; +                     +                    while (bag < 256) +                    { +                        item = ((Player*)m_caster)->GetItemByPos(bag,slot); +                        if (item && item->GetEntry() == 38587) break; +                        slot++; +                        if (slot == 39) +                        { +                            slot = 0; +                            bag++; +                        } +                    } +                    if (bag < 256) +                    { +                        if (((Player*)m_caster)->GetItemByPos(bag,slot)->GetCount() == 1) ((Player*)m_caster)->RemoveItem(bag,slot,true); +                        else ((Player*)m_caster)->GetItemByPos(bag,slot)->SetCount(((Player*)m_caster)->GetItemByPos(bag,slot)->GetCount()-1); +                        // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen) +                        m_caster->CastSpell(m_caster,42518,true); +                        return; +                    } +                    break; +                } +                // Force Cast - Portal Effect: Sunwell Isle +                case 44876: +                { +                    if(!unitTarget) +                        return; -        // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell) -        case 22539: -        case 22972: -        case 22975: -        case 22976: -        case 22977: -        case 22978: -        case 22979: -        case 22980: -        case 22981: -        case 22982: -        case 22983: -        case 22984: -        case 22985: -        { -            if(!unitTarget || !unitTarget->isAlive()) -                return; +                    unitTarget->CastSpell(unitTarget, 44870, true); +                    break; +                } +                // Goblin Weather Machine +                case 46203: +                { +                    if(!unitTarget) +                        return; -            // Onyxia Scale Cloak -            if(unitTarget->GetDummyAura(22683)) -                return; +                    uint32 spellId; +                    switch(rand()%4) +                    { +                        case 0: spellId = 46740; break; +                        case 1: spellId = 46739; break; +                        case 2: spellId = 46738; break; +                        case 3: spellId = 46736; break; +                    } +                    unitTarget->CastSpell(unitTarget, spellId, true); +                    break; +                } +                //5,000 Gold +                case 46642: +                { +                    if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) +                        return; -            // Shadow Flame -            m_caster->CastSpell(unitTarget, 22682, true); -            return; -        } -        break; +                    ((Player*)unitTarget)->ModifyMoney(50000000); -        // Summon Black Qiraji Battle Tank -        case 26656: -        { -            if(!unitTarget) -                return; +                    break; +                } +                // Emblazon Runeblade +                case 51770: +                { +                    if(!unitTarget) +                        return; -            // Prevent stacking of mounts -            unitTarget->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); +                    unitTarget->CastSpell(unitTarget,51771,false); +                    break; +                } +                // Death Gate +                case 52751: +                { +                    if(!unitTarget || unitTarget->getClass() != CLASS_DEATH_KNIGHT) +                        return; +                    // triggered spell is stored in m_spellInfo->EffectBasePoints[0] +                    unitTarget->CastSpell(unitTarget, damage, false); +                    break; +                } +                // random spell learn instead placeholder +                case 60893:                                 // Northrend Alchemy Research +                case 61177:                                 // Northrend Inscription Research +                case 61288:                                 // Minor Inscription Research +                case 61756:                                 // Northrend Inscription Research (FAST QA VERSION) +                { +                    if(!IsExplicitDiscoverySpell(m_spellInfo)) +                    { +                        sLog.outError("Wrong explicit discovery spell %u structure, or outdated...",m_spellInfo->Id); +                        return; +                    } -            // Two separate mounts depending on area id (allows use both in and out of specific instance) -            if (unitTarget->GetAreaId() == 3428) -                unitTarget->CastSpell(unitTarget, 25863, false); -            else -                unitTarget->CastSpell(unitTarget, 26655, false); -            break; -        } -        // Piccolo of the Flaming Fire -        case 17512: -        { -            if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) -                return; -            unitTarget->HandleEmoteCommand(EMOTE_STATE_DANCE); -            break; -        } -        // Netherbloom -        case 28702: -        { -            if(!unitTarget) -                return; -            // 25% chance of casting a random buff -            if(roll_chance_i(75)) -                return; +                    if(m_caster->GetTypeId()!=TYPEID_PLAYER) +                        return; +                    Player* player = (Player*)m_caster; -            // triggered spells are 28703 to 28707 -            // Note: some sources say, that there was the possibility of -            //       receiving a debuff. However, this seems to be removed by a patch. -            const uint32 spellid = 28703; +                    // need replace effect 0 item by loot +                    uint32 reagent_id = m_spellInfo->EffectItemType[0]; -            // don't overwrite an existing aura -            for(uint8 i=0; i<5; i++) -                if(unitTarget->HasAura(spellid+i, 0)) -                    return; -            unitTarget->CastSpell(unitTarget, spellid+urand(0, 4), true); -            break; -        } +                    if(!player->HasItemCount(reagent_id,1)) +                        return; -        // Nightmare Vine -        case 28720: -        { -            if(!unitTarget) -                return; -            // 25% chance of casting Nightmare Pollen -            if(roll_chance_i(75)) -                return; -            unitTarget->CastSpell(unitTarget, 28721, true); -            break; -        } +                    // remove reagent +                    uint32 count = 1; +                    player->DestroyItemCount (reagent_id,count,true); -        // Mirren's Drinking Hat -        case 29830: -        { -            uint32 item = 0; -            switch ( urand(1,6) ) -            { -                case 1: case 2: case 3: item = 23584; break;// Loch Modan Lager -                case 4: case 5:         item = 23585; break;// Stouthammer Lite -                case 6:                 item = 23586; break;// Aerie Peak Pale Ale +                    // create some random items +                    player->AutoStoreLoot(m_spellInfo->Id,LootTemplates_Spell); + +                    // learn random explicit discovery recipe (if any) +                    if(uint32 discoveredSpell = GetExplicitDiscoverySpell(m_spellInfo->Id, player)) +                        player->learnSpell(discoveredSpell,false); +                    return; +                }              } -            if (item) -                DoCreateItem(effIndex,item);              break;          } -        // Improved Sprint -        case 30918: +        case SPELLFAMILY_WARLOCK:          { -            // Removes snares and roots. -            uint32 mechanic_mask = (1<<MECHANIC_ROOT) | (1<<MECHANIC_SNARE); -            Unit::AuraMap& Auras = unitTarget->GetAuras(); -            for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) +            switch(m_spellInfo->Id)              { -                next = iter; -                ++next; -                Aura *aur = iter->second; -                if (!aur->IsPositive())             //only remove negative spells +                // Healthstone creating spells +                case  6201: +                case  6202: +                case  5699: +                case 11729: +                case 11730: +                case 27230: +                case 47871: +                case 47878:                  { -                    // check for mechanic mask -                    if(GetSpellMechanicMask(aur->GetSpellProto(), aur->GetEffIndex()) & mechanic_mask) +                    uint32 itemtype; +                    uint32 rank = 0; +                    Unit::AuraList const& mDummyAuras = unitTarget->GetAurasByType(SPELL_AURA_DUMMY); +                    for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)                      { -                        unitTarget->RemoveAurasDueToSpell(aur->GetId()); -                        if(Auras.empty()) +                        if((*i)->GetId() == 18692) +                        { +                            rank = 1;                              break; -                        else -                            next = Auras.begin(); +                        } +                        else if((*i)->GetId() == 18693) +                        { +                            rank = 2; +                            break; +                        }                      } -                } -            } -            break; -        } -        // Goblin Weather Machine -        case 46203: -        { -            if(!unitTarget) -                return; - -            uint32 spellId; -            switch(rand()%4) -            { -                case 0: -                    spellId=46740; -                    break; -                case 1: -                    spellId=46739; -                    break; -                case 2: -                    spellId=46738; -                    break; -                case 3: -                    spellId=46736; -                    break; -            } -            unitTarget->CastSpell(unitTarget, spellId, true); -            break; -        } -        case 48025:                                     // Headless Horseman's Mount -        { -                if(!unitTarget) -                    return; +                    static uint32 const itypes[8][3] = { +                        { 5512,19004,19005},                // Minor Healthstone +                        { 5511,19006,19007},                // Lesser Healthstone +                        { 5509,19008,19009},                // Healthstone +                        { 5510,19010,19011},                // Greater Healthstone +                        { 9421,19012,19013},                // Major Healthstone +                        {22103,22104,22105},                // Master Healthstone +                        {36889,36890,36891},                // Demonic Healthstone +                        {36892,36893,36894}                 // Fel Healthstone +                    }; -                if(unitTarget) -                { -                    switch(((Player*)unitTarget)->GetBaseSkillValue(762)) +                    switch(m_spellInfo->Id)                      { -                    case 75: unitTarget->CastSpell(unitTarget, 51621, true); break;; -                    case 150: unitTarget->CastSpell(unitTarget, 48024, true); break; -                    case 225: unitTarget->CastSpell(unitTarget, 51617, true); break; -                    case 300: unitTarget->CastSpell(unitTarget, 48023, true); break; -                    default: break; +                        case  6201: +                            itemtype=itypes[0][rank];break; // Minor Healthstone +                        case  6202: +                            itemtype=itypes[1][rank];break; // Lesser Healthstone +                        case  5699: +                            itemtype=itypes[2][rank];break; // Healthstone +                        case 11729: +                            itemtype=itypes[3][rank];break; // Greater Healthstone +                        case 11730: +                            itemtype=itypes[4][rank];break; // Major Healthstone +                        case 27230: +                            itemtype=itypes[5][rank];break; // Master Healthstone +                        case 47871: +                            itemtype=itypes[6][rank];break; // Demonic Healthstone +                        case 47878: +                            itemtype=itypes[7][rank];break; // Fel Healthstone +                        default: +                            return;                      } +                    DoCreateItem( effIndex, itemtype ); +                    return;                  } -                break; +            } +            break;          } -        case 47977:                                     // Magic Broom +        case SPELLFAMILY_PRIEST:          { -            if(!unitTarget) -                return; - -            if(unitTarget) +            switch(m_spellInfo->Id)              { -                switch(((Player*)unitTarget)->GetBaseSkillValue(762)) +                // Pain and Suffering +                case 47948:                  { -                case 75: unitTarget->CastSpell(unitTarget, 42680, true); break;; -                case 150: case 225: case 300: unitTarget->CastSpell(unitTarget, 42683, true); break; -                default: break; +                    if (!unitTarget) +                        return; +                    // Refresh Shadow Word: Pain on target +                    Unit::AuraMap& auras = unitTarget->GetAuras(); +                    for(Unit::AuraMap::iterator itr = auras.begin(); itr != auras.end(); ++itr) +                    { +                        SpellEntry const *spellInfo = (*itr).second->GetSpellProto(); +                        if( spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && +                            spellInfo->SpellFamilyFlags[0] &  0x8000 && +                            (*itr).second->GetCasterGUID() == m_caster->GetGUID()) +                        { +                            (*itr).second->RefreshAura(); +                            return; +                        } +                    } +                    return;                  } +                default: +                    break;              }              break;          } -    } - -    if(!unitTarget || !unitTarget->isAlive()) // can we remove this check? -    { -        sLog.outError("Spell %u in EffectScriptEffect does not have unitTarget", m_spellInfo->Id); -        return; -    } - -    switch(m_spellInfo->Id) -    { -        // Dreaming Glory -        case 28698: unitTarget->CastSpell(unitTarget, 28694, true); break; -        // Needle Spine -        //case 39835: unitTarget->CastSpell(unitTarget, 39968, true); break; -        // Draw Soul -        case 40904: unitTarget->CastSpell(m_caster, 40903, true); break; -        // Flame Crash -        //case 41126: unitTarget->CastSpell(unitTarget, 41131, true); break; -        case 41931: +        case SPELLFAMILY_HUNTER:          { -            int bag=19; -            int slot=0; -            Item* item = NULL; - -            while (bag < 256) +            switch(m_spellInfo->Id)              { -                item = ((Player*)m_caster)->GetItemByPos(bag,slot); -                if (item && item->GetEntry() == 38587) break; -                slot++; -                if (slot == 39) +                // Chimera Shot +                case 53209:                  { -                    slot = 0; -                    bag++; +                    uint32 spellId = 0; +                    int32 basePoint = 0; +                    Unit::AuraMap& Auras = unitTarget->GetAuras(); +                    for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i) +                    { +                        Aura *aura = (*i).second; +                        if (aura->GetCasterGUID() != m_caster->GetGUID()) +                            continue; +                        // Search only Serpent Sting, Viper Sting, Scorpid Sting auras +                        flag96 familyFlag = aura->GetSpellProto()->SpellFamilyFlags; +                        if (!(familyFlag[1] & 0x00000080 || familyFlag[0] & 0x0000C000)) +                            continue; +                        // Refresh aura duration +                        aura->RefreshAura(); + +                        // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting. +                        if (familyFlag[0] & 0x4000 && aura->GetEffIndex() == 0) +                        { +                            spellId = 53353; // 53353 Chimera Shot - Serpent +                            basePoint = aura->GetModifier()->m_amount * 5 * 40 / 100; +                        } +                        // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting. +                        if (familyFlag[1] & 0x00000080 && aura->GetEffIndex() == 0) +                        { +                            spellId = 53358; // 53358 Chimera Shot - Viper +                            basePoint = aura->GetModifier()->m_amount * 4 * 60 / 100; +                        } +                        // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute. +                        if (familyFlag[0] & 0x00008000) +                            spellId = 53359; // 53359 Chimera Shot - Scorpid +                        // ?? nothing say in spell desc (possibly need addition check) +                        //if (familyFlag & 0x0000010000000000LL || // dot +                        //    familyFlag & 0x0000100000000000LL)   // stun +                        //{ +                        //    spellId = 53366; // 53366 Chimera Shot - Wyvern +                        //} +                    } +                    if (spellId) +                        m_caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, false); +                    return;                  } +                default: +                    break;              } -            if (bag < 256) -            { -                if (((Player*)m_caster)->GetItemByPos(bag,slot)->GetCount() == 1) ((Player*)m_caster)->RemoveItem(bag,slot,true); -                else ((Player*)m_caster)->GetItemByPos(bag,slot)->SetCount(((Player*)m_caster)->GetItemByPos(bag,slot)->GetCount()-1); -                // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen) -                m_caster->CastSpell(m_caster,42518,true); -                return; -            } -        } -        // Force Cast - Portal Effect: Sunwell Isle -        case 44876: unitTarget->CastSpell(unitTarget, 44870, true); break; -        //5,000 Gold -        case 46642: -        { -            if(unitTarget->GetTypeId() == TYPEID_PLAYER) -                ((Player*)unitTarget)->ModifyMoney(50000000);              break;          } -    } - -    if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN ) -    { -        switch(m_spellInfo->SpellFamilyFlags) +        case SPELLFAMILY_PALADIN:          {              // Judgement -            case 0x800000: +            if (m_spellInfo->SpellFamilyFlags[0] & 0x800000)              { +                if(!unitTarget || !unitTarget->isAlive()) +                    return; +                uint32 spellId1 = 0;                  uint32 spellId2 = 0; -                // all seals have aura dummy +                // Judgement self add switch +                switch (m_spellInfo->Id) +                { +                    case 41467: break;                      // Judgement +                    case 53407: spellId1 = 20184; break;    // Judgement of Justice +                    case 20271:                             // Judgement of Light +                    case 57774: spellId1 = 20185; break;    // Judgement of Light +                    case 53408: spellId1 = 20186; break;    // Judgement of Wisdom +                    default: +                        return; +                } +                // all seals have aura dummy in 2 effect                  Unit::AuraList const& m_dummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY);                  for(Unit::AuraList::const_iterator itr = m_dummyAuras.begin(); itr != m_dummyAuras.end(); ++itr)                  {                      SpellEntry const *spellInfo = (*itr)->GetSpellProto(); -                      // search seal (all seals have judgement's aura dummy spell id in 2 effect -                    if ( !spellInfo || !IsSealSpell((*itr)->GetSpellProto()) || (*itr)->GetEffIndex() != 2 ) +                    if ((*itr)->GetEffIndex() != 2 || !spellInfo || !IsSealSpell(spellInfo))                          continue; - -                    // must be calculated base at raw base points in spell proto, GetModifier()->m_value for S.Righteousness modified by SPELLMOD_DAMAGE -                    spellId2 = (*itr)->GetSpellProto()->EffectBasePoints[2]+1; - -                    if(spellId2 <= 1) +                    spellId2 = (*itr)->GetModifier()->m_amount; +                    SpellEntry const *judge = sSpellStore.LookupEntry(spellId2); +                    if (!judge)                          continue; +                    break; +                } +                if (spellId1) +                    m_caster->CastSpell(unitTarget, spellId1, true); +                if (spellId2) +                    m_caster->CastSpell(unitTarget, spellId2, true); +                return; +            } +        } +        case SPELLFAMILY_POTION: +        { +            switch(m_spellInfo->Id) +            { +                // Dreaming Glory +                case 28698: +                { +                    if(!unitTarget) +                        return; +                    unitTarget->CastSpell(unitTarget, 28694, true); +                    break; +                } +                // Netherbloom +                case 28702: +                { +                    if(!unitTarget) +                        return; +                    // 25% chance of casting a random buff +                    if(roll_chance_i(75)) +                        return; -                    // found, remove seal -                    m_caster->RemoveAurasDueToSpell((*itr)->GetId()); - -                    // Sanctified Judgement -                    Unit::AuraList const& m_auras = m_caster->GetAurasByType(SPELL_AURA_DUMMY); -                    for(Unit::AuraList::const_iterator i = m_auras.begin(); i != m_auras.end(); ++i) -                    { -                        if ((*i)->GetSpellProto()->SpellIconID == 205 && (*i)->GetSpellProto()->Attributes == 0x01D0LL) -                        { -                            int32 chance = (*i)->GetModifier()->m_amount; -                            if ( roll_chance_i(chance) ) -                            { -                                int32 mana = spellInfo->manaCost; -                                if ( Player* modOwner = m_caster->GetSpellModOwner() ) -                                    modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_COST, mana); -                                mana = int32(mana* 0.8f); -                                m_caster->CastCustomSpell(m_caster,31930,&mana,NULL,NULL,true,NULL,*i); -                            } -                            break; -                        } -                    } +                    // triggered spells are 28703 to 28707 +                    // Note: some sources say, that there was the possibility of +                    //       receiving a debuff. However, this seems to be removed by a patch. +                    const uint32 spellid = 28703; +                    // don't overwrite an existing aura +                    for(uint8 i=0; i<5; i++) +                        if(unitTarget->HasAura(spellid+i, 0)) +                            return; +                    unitTarget->CastSpell(unitTarget, spellid+urand(0, 4), true);                      break;                  } -                m_caster->CastSpell(unitTarget,spellId2,true); -                return; +                // Nightmare Vine +                case 28720: +                { +                    if(!unitTarget) +                        return; +                    // 25% chance of casting Nightmare Pollen +                    if(roll_chance_i(75)) +                        return; +                    unitTarget->CastSpell(unitTarget, 28721, true); +                    break; +                }              } +            break;          }      } @@ -4947,7 +5287,7 @@ void Spell::EffectSanctuary(uint32 /*i*/)      std::list<Unit*> targets;      Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, World::GetMaxVisibleDistance()); -    Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(targets, u_check); +    Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(unitTarget, targets, u_check);      unitTarget->VisitNearbyObject(World::GetMaxVisibleDistance(), searcher);      for(std::list<Unit*>::iterator iter = targets.begin(); iter != targets.end(); ++iter)      { @@ -4967,7 +5307,7 @@ void Spell::EffectSanctuary(uint32 /*i*/)      unitTarget->CombatStop();      unitTarget->getHostilRefManager().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->SpellFamilyName == SPELLFAMILY_ROGUE && (m_spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG_ROGUE_VANISH))      {          ((Player *)m_caster)->RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT);      } @@ -5002,6 +5342,7 @@ void Spell::EffectDuel(uint32 i)      // Players can only fight a duel with each other outside (=not inside dungeons and not in capital cities)      // Don't have to check the target's map since you cannot challenge someone across maps      if(caster->GetMap()->Instanceable()) +    //if( mapid != 0 && mapid != 1 && mapid != 530 && mapid != 571 && mapid != 609)      {          SendCastResult(SPELL_FAILED_NO_DUELING);            // Dueling isn't allowed here          return; @@ -5027,7 +5368,8 @@ void Spell::EffectDuel(uint32 i)      uint32 gameobject_id = m_spellInfo->EffectMiscValue[i];      Map *map = m_caster->GetMap(); -    if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), gameobject_id, map, +    if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), gameobject_id, +        map, m_caster->GetPhaseMask(),          m_caster->GetPositionX()+(unitTarget->GetPositionX()-m_caster->GetPositionX())/2 ,          m_caster->GetPositionY()+(unitTarget->GetPositionY()-m_caster->GetPositionY())/2 ,          m_caster->GetPositionZ(), @@ -5040,7 +5382,7 @@ void Spell::EffectDuel(uint32 i)      pGameObj->SetUInt32Value(GAMEOBJECT_FACTION, m_caster->getFaction() );      pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()+1 );      int32 duration = GetSpellDuration(m_spellInfo); -    pGameObj->SetRespawnTime(duration > 0 ? duration/1000 : 0); +    pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILISECONDS : 0);      pGameObj->SetSpellId(m_spellInfo->Id);      m_caster->AddGameObject(pGameObj); @@ -5117,7 +5459,7 @@ void Spell::EffectSummonPlayer(uint32 /*i*/)      WorldPacket data(SMSG_SUMMON_REQUEST, 8+4+4);      data << uint64(m_caster->GetGUID());                    // summoner guid      data << uint32(m_caster->GetZoneId());                  // summoner zone -    data << uint32(MAX_PLAYER_SUMMON_DELAY*1000);           // auto decline after msecs +    data << uint32(MAX_PLAYER_SUMMON_DELAY*IN_MILISECONDS); // auto decline after msecs      ((Player*)unitTarget)->GetSession()->SendPacket(&data);  } @@ -5140,6 +5482,43 @@ void Spell::EffectActivateObject(uint32 effect_idx)      sWorld.ScriptCommandStart(activateCommand, delay_secs, m_caster, gameObjTarget);  } +void Spell::EffectApplyGlyph(uint32 i) +{ +    if(m_caster->GetTypeId() != TYPEID_PLAYER) +        return; + +    Player *player = (Player*)m_caster; + +    // remove old glyph +    if(uint32 oldglyph = player->GetGlyph(m_glyphIndex)) +    { +        if(GlyphPropertiesEntry const *old_gp = sGlyphPropertiesStore.LookupEntry(oldglyph)) +        { +            player->RemoveAurasDueToSpell(old_gp->SpellId); +            player->SetGlyph(m_glyphIndex, 0); +        } +    } + +    // apply new one +    if(uint32 glyph = m_spellInfo->EffectMiscValue[i]) +    { +        if(GlyphPropertiesEntry const *gp = sGlyphPropertiesStore.LookupEntry(glyph)) +        { +            if(GlyphSlotEntry const *gs = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex))) +            { +                if(gp->TypeFlags != gs->TypeFlags) +                { +                    SendCastResult(SPELL_FAILED_INVALID_GLYPH); +                    return;                                 // glyph slot missmatch +                } +            } + +            player->CastSpell(m_caster, gp->SpellId, true); +            player->SetGlyph(m_glyphIndex, glyph); +        } +    } +} +  void Spell::EffectSummonTotem(uint32 i)  {      uint8 slot = 0; @@ -5173,7 +5552,8 @@ void Spell::EffectSummonTotem(uint32 i)      Totem* pTotem = new Totem; -    if(!pTotem->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), m_caster->GetMap(), m_spellInfo->EffectMiscValue[i], team )) +    if(!pTotem->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), m_caster->GetMap(), m_caster->GetPhaseMask(), +        m_spellInfo->EffectMiscValue[i], team ))      {          delete pTotem;          return; @@ -5208,10 +5588,9 @@ void Spell::EffectSummonTotem(uint32 i)      }      pTotem->SetUInt32Value(UNIT_CREATED_BY_SPELL,m_spellInfo->Id); -    pTotem->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE); -    pTotem->ApplySpellImmune(m_spellInfo->Id,IMMUNITY_STATE,SPELL_AURA_MOD_FEAR,true); -    pTotem->ApplySpellImmune(m_spellInfo->Id,IMMUNITY_STATE,SPELL_AURA_TRANSFORM,true); +    if(m_caster->GetTypeId() == TYPEID_PLAYER) +        pTotem->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE);      pTotem->Summon(m_caster); @@ -5263,7 +5642,7 @@ void Spell::EffectEnchantHeldItem(uint32 i)              return;          // Apply the temporary enchantment -        item->SetEnchantment(slot, enchant_id, duration*1000, 0); +        item->SetEnchantment(slot, enchant_id, duration*IN_MILISECONDS, 0);          item_owner->ApplyEnchantment(item,slot,true);      }  } @@ -5306,7 +5685,8 @@ void Spell::EffectFeedPet(uint32 i)      Player *_player = (Player*)m_caster; -    if(!itemTarget) +    Item* foodItem = m_targets.getItemTarget(); +    if(!foodItem)          return;      Pet *pet = _player->GetPet(); @@ -5316,15 +5696,15 @@ void Spell::EffectFeedPet(uint32 i)      if(!pet->isAlive())          return; -    int32 benefit = pet->GetCurrentFoodBenefitLevel(itemTarget->GetProto()->ItemLevel); +    int32 benefit = pet->GetCurrentFoodBenefitLevel(foodItem->GetProto()->ItemLevel);      if(benefit <= 0)          return;      uint32 count = 1; -    _player->DestroyItemCount(itemTarget,count,true); +    _player->DestroyItemCount(foodItem,count,true);      // TODO: fix crash when a spell has two effects, both pointed at the same item target -    m_caster->CastCustomSpell(m_caster,m_spellInfo->EffectTriggerSpell[i],&benefit,NULL,NULL,true); +    m_caster->CastCustomSpell(pet,m_spellInfo->EffectTriggerSpell[i],&benefit,NULL,NULL,true);  }  void Spell::EffectDismissPet(uint32 /*i*/) @@ -5384,7 +5764,8 @@ void Spell::EffectSummonObject(uint32 i)          m_caster->GetClosePoint(x,y,z,DEFAULT_WORLD_OBJECT_SIZE);      Map *map = m_caster->GetMap(); -    if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), go_id, map, x, y, z, m_caster->GetOrientation(), 0, 0, rot2, rot3, 0, 1)) +    if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), go_id, map, +        m_caster->GetPhaseMask(), x, y, z, m_caster->GetOrientation(), 0, 0, rot2, rot3, 0, 1))      {          delete pGameObj;          return; @@ -5392,7 +5773,7 @@ void Spell::EffectSummonObject(uint32 i)      //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL,m_caster->getLevel());      int32 duration = GetSpellDuration(m_spellInfo); -    pGameObj->SetRespawnTime(duration > 0 ? duration/1000 : 0); +    pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILISECONDS : 0);      pGameObj->SetSpellId(m_spellInfo->Id);      m_caster->AddGameObject(pGameObj); @@ -5463,18 +5844,14 @@ void Spell::EffectAddExtraAttacks(uint32 /*i*/)  void Spell::EffectParry(uint32 /*i*/)  { -    if (unitTarget->GetTypeId() == TYPEID_PLAYER) -    { +    if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER)          ((Player*)unitTarget)->SetCanParry(true); -    }  }  void Spell::EffectBlock(uint32 /*i*/)  { -    if (unitTarget->GetTypeId() != TYPEID_PLAYER) -        return; - -    ((Player*)unitTarget)->SetCanBlock(true); +    if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER) +        ((Player*)unitTarget)->SetCanBlock(true);  }  void Spell::EffectMomentMove(uint32 i) @@ -5486,7 +5863,7 @@ void Spell::EffectMomentMove(uint32 i)          return;      uint32 mapid = m_caster->GetMapId(); -    float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); +    float dis = m_caster->GetSpellRadiusForTarget(unitTarget, sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));      // src point      float *fx = new float[11], *fy = new float[11], *fz = new float[11]; @@ -5684,8 +6061,8 @@ void Spell::EffectSummonCritter(uint32 i)      Map *map = m_caster->GetMap();      uint32 pet_number = objmgr.GeneratePetNumber(); -    if(!critter->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), -        map, pet_entry, pet_number)) +    if(!critter->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), map, m_caster->GetPhaseMask(), +        pet_entry, pet_number))      {          sLog.outError("Spell::EffectSummonCritter, spellid %u: no such creature entry %u", m_spellInfo->Id, pet_entry);          delete critter; @@ -5774,14 +6151,16 @@ void Spell::EffectKnockBack(uint32 i)          vcos = dx / dist;          vsin = dy / dist;      } +    float speedxy = float(m_spellInfo->EffectMiscValue[i])/10; +    float speedz = float(damage/-10);         WorldPacket data(SMSG_MOVE_KNOCK_BACK, (8+4+4+4+4+4));      data.append(unitTarget->GetPackGUID());      data << uint32(0);                                      // Sequence      data << float(vcos);                                    // x direction      data << float(vsin);                                    // y direction -    data << float(m_spellInfo->EffectMiscValue[i])/10;      // Horizontal speed -    data << float(damage/-10);                              // Z Movement speed (vertical) +    data << float(speedxy);                                 // Horizontal speed +    data << float(speedz);                                  // Z Movement speed (vertical)      ((Player*)unitTarget)->GetSession()->SendPacket(&data);  } @@ -5804,17 +6183,26 @@ void Spell::EffectSendTaxi(uint32 i)      uint32 mountid = 0;      switch(m_spellInfo->Id)      { -        case 31606:       //Stormcrow Amulet +        case 31606:                                         //Stormcrow Amulet              mountid = 17447;              break; -        case 45071:      //Quest - Sunwell Daily - Dead Scar Bombing Run -        case 45113:      //Quest - Sunwell Daily - Ship Bombing Run -        case 45353:      //Quest - Sunwell Daily - Ship Bombing Run Return +        case 45071:                                         //Quest - Sunwell Daily - Dead Scar Bombing Run +        case 45113:                                         //Quest - Sunwell Daily - Ship Bombing Run +        case 45353:                                         //Quest - Sunwell Daily - Ship Bombing Run Return              mountid = 22840;              break; -        case 34905:      //Stealth Flight +        case 34905:                                         //Stealth Flight              mountid = 6851;              break; +        case 45883:                                         //Amber Ledge to Beryl Point +            mountid = 23524; +            break; +        case 46064:                                         //Amber Ledge to Coldarra +            mountid = 6371; +            break; +        case 53335:                                         //Stormwind Harbor Flight - Peaceful +            mountid = 6852; +            break;          case 41533:      //Fly of the Netherwing          case 41540:      //Fly of the Netherwing              mountid = 23468; @@ -5856,22 +6244,22 @@ void Spell::EffectDispelMechanic(uint32 i)      uint32 mechanic = m_spellInfo->EffectMiscValue[i]; +    std::deque <Aura *> dispel_list; +      Unit::AuraMap& Auras = unitTarget->GetAuras(); -    for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) +    for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter++)      { -        next = iter; -        ++next; -        SpellEntry const *spell = sSpellStore.LookupEntry(iter->second->GetSpellProto()->Id); +        if (!iter->second->GetDispelChance(this)) +            continue; +        SpellEntry const *spell = iter->second->GetSpellProto();          if(spell->Mechanic == mechanic || spell->EffectMechanic[iter->second->GetEffIndex()] == mechanic) -        { -            unitTarget->RemoveAurasDueToSpell(spell->Id); -            if(Auras.empty()) -                break; -            else -                next = Auras.begin(); -        } +            dispel_list.push_back(iter->second); +    } +    for(;!dispel_list.empty();) +    { +        unitTarget->RemoveAurasDueToSpell(dispel_list.front()->GetId()); +        dispel_list.pop_front();      } -    return;  }  void Spell::EffectSummonDeadPet(uint32 /*i*/) @@ -6001,13 +6389,14 @@ void Spell::EffectTransmitted(uint32 effIndex)      //FIXME: this can be better check for most objects but still hack      else if(m_spellInfo->EffectRadiusIndex[effIndex] && m_spellInfo->speed==0)      { -        float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[effIndex])); +        float dis = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[effIndex]));          m_caster->GetClosePoint(fx,fy,fz,DEFAULT_WORLD_OBJECT_SIZE, dis);      }      else      { -        float min_dis = GetSpellMinRange(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex)); -        float max_dis = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex)); +        //GO is always friendly to it's creator, get range for friends +        float min_dis = GetSpellMinRangeForFriend(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex)); +        float max_dis = GetSpellMaxRangeForFriend(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex));          float dis = rand_norm() * (max_dis - min_dis) + min_dis;          m_caster->GetClosePoint(fx,fy,fz,DEFAULT_WORLD_OBJECT_SIZE, dis); @@ -6036,7 +6425,7 @@ void Spell::EffectTransmitted(uint32 effIndex)      GameObject* pGameObj = new GameObject;      if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), name_id, cMap, -        fx, fy, fz, m_caster->GetOrientation(), 0, 0, 0, 0, 100, 1)) +        m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), 0, 0, 0, 0, 100, 1))      {          delete pGameObj;          return; @@ -6050,9 +6439,9 @@ void Spell::EffectTransmitted(uint32 effIndex)          {              m_caster->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT,pGameObj->GetGUID());                                                              // Orientation3 -            pGameObj->SetFloatValue(GAMEOBJECT_ROTATION + 2, 0.88431775569915771 ); +            pGameObj->SetFloatValue(GAMEOBJECT_PARENTROTATION + 2, 0.88431775569915771 );                                                              // Orientation4 -            pGameObj->SetFloatValue(GAMEOBJECT_ROTATION + 3, -0.4668855369091033 ); +            pGameObj->SetFloatValue(GAMEOBJECT_PARENTROTATION + 3, -0.4668855369091033 );              m_caster->AddGameObject(pGameObj);              // will removed at spell cancel              // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo)) @@ -6066,7 +6455,7 @@ void Spell::EffectTransmitted(uint32 effIndex)                  case 3: lastSec = 17; break;              } -            duration = duration - lastSec*1000 + FISHING_BOBBER_READY_TIME*1000; +            duration = duration - lastSec*IN_MILISECONDS + FISHING_BOBBER_READY_TIME*IN_MILISECONDS;              break;          }          case GAMEOBJECT_TYPE_SUMMONING_RITUAL: @@ -6086,7 +6475,7 @@ void Spell::EffectTransmitted(uint32 effIndex)          }      } -    pGameObj->SetRespawnTime(duration > 0 ? duration/1000 : 0); +    pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILISECONDS : 0);      pGameObj->SetOwnerGUID(m_caster->GetGUID() ); @@ -6107,9 +6496,9 @@ void Spell::EffectTransmitted(uint32 effIndex)      {          GameObject* linkedGO = new GameObject;          if(linkedGO->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), linkedEntry, cMap, -            fx, fy, fz, m_caster->GetOrientation(), 0, 0, 0, 0, 100, 1)) +            m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), 0, 0, 0, 0, 100, 1))          { -            linkedGO->SetRespawnTime(duration > 0 ? duration/1000 : 0); +            linkedGO->SetRespawnTime(duration > 0 ? duration/IN_MILISECONDS : 0);              //linkedGO->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel() );              linkedGO->SetSpellId(m_spellInfo->Id);              linkedGO->SetOwnerGUID(m_caster->GetGUID() ); @@ -6147,6 +6536,28 @@ void Spell::EffectProspecting(uint32 /*i*/)      ((Player*)m_caster)->SendLoot(itemTarget->GetGUID(), LOOT_PROSPECTING);  } +void Spell::EffectMilling(uint32 /*i*/) +{ +    if(m_caster->GetTypeId() != TYPEID_PLAYER) +        return; + +    Player* p_caster = (Player*)m_caster; +    if(!itemTarget || !(itemTarget->GetProto()->BagFamily & BAG_FAMILY_MASK_HERBS)) +        return; + +    if(itemTarget->GetCount() < 5) +        return; + +    if( sWorld.getConfig(CONFIG_SKILL_MILLING)) +    { +        uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION); +        uint32 reqSkillValue = itemTarget->GetProto()->RequiredSkillRank; +        p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue); +    } + +    ((Player*)m_caster)->SendLoot(itemTarget->GetGUID(), LOOT_MILLING); +} +  void Spell::EffectSkill(uint32 /*i*/)  {      sLog.outDebug("WORLD: SkillEFFECT"); @@ -6294,9 +6705,42 @@ void Spell::EffectQuestFail(uint32 i)      ((Player*)unitTarget)->FailQuest(m_spellInfo->EffectMiscValue[i]);  } +void Spell::EffectActivateRune(uint32  eff_idx) +{ +    if(m_caster->GetTypeId() != TYPEID_PLAYER) +        return; + +    Player *plr = (Player*)m_caster; + +    if(plr->getClass() != CLASS_DEATH_KNIGHT) +        return; + +    for(uint32 j = 0; j < MAX_RUNES; ++j) +    { +        if(plr->GetRuneCooldown(j) && plr->GetCurrentRune(j) == m_spellInfo->EffectMiscValue[eff_idx]) +        { +            plr->SetRuneCooldown(j, 0); +        } +    } +} + +void Spell::EffectTitanGrip(uint32 /*eff_idx*/) +{ +    if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER) +        ((Player*)unitTarget)->SetCanTitanGrip(true); +} +  void Spell::EffectRedirectThreat(uint32 /*i*/)  {      if(unitTarget)          m_caster->SetReducedThreatPercent((uint32)damage, unitTarget->GetGUID());  } +void Spell::EffectRenamePet(uint32 /*eff_idx*/) +{ +    if (!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT || +        !((Creature*)unitTarget)->isPet() || ((Pet*)unitTarget)->getPetType() != HUNTER_PET) +        return; + +    unitTarget->SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_ALLOWED); +}  | 
