diff options
Diffstat (limited to 'src/game/SpellEffects.cpp')
| -rw-r--r-- | src/game/SpellEffects.cpp | 4219 | 
1 files changed, 2285 insertions, 1934 deletions
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 190f9934b84..a6d5cb2ce74 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 @@ -19,10 +19,8 @@   */  #include "Common.h" -#include "SharedDefines.h"  #include "Database/DatabaseEnv.h"  #include "WorldPacket.h" -#include "WorldSession.h"  #include "Opcodes.h"  #include "Log.h"  #include "UpdateMask.h" @@ -32,7 +30,6 @@  #include "Player.h"  #include "SkillExtraItems.h"  #include "Unit.h" -#include "CreatureAI.h"  #include "Spell.h"  #include "DynamicObject.h"  #include "SpellAuras.h" @@ -47,6 +44,7 @@  #include "Creature.h"  #include "Totem.h"  #include "CreatureAI.h" +#include "BattleGroundMgr.h"  #include "BattleGround.h"  #include "BattleGroundEY.h"  #include "BattleGroundWS.h" @@ -60,6 +58,9 @@  #include "CellImpl.h"  #include "GridNotifiers.h"  #include "GridNotifiersImpl.h" +#include "SkillDiscovery.h" +#include "Formulas.h" +#include "Vehicle.h"  pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=  { @@ -104,8 +105,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::EffectJump,                                     // 41 SPELL_EFFECT_JUMP +    &Spell::EffectJump,                                     // 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 +129,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 +151,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::EffectWMODamage,                                // 87 SPELL_EFFECT_WMO_DAMAGE +    &Spell::EffectWMORepair,                                // 88 SPELL_EFFECT_WMO_REPAIR +    &Spell::EffectUnused,                                   // 89 SPELL_EFFECT_WMO_CHANGE +    &Spell::EffectKillCredit,                               // 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::EffectCharge,                                   // 96 SPELL_EFFECT_CHARGE +    &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 +176,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 +196,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::EffectJump2,                                    //138 SPELL_EFFECT_138                      Leap +    &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::EffectPlayerPull,                               //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 +218,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*/) @@ -269,18 +276,17 @@ void Spell::EffectInstaKill(uint32 /*i*/)              case  1863: spellID=18791; break;               //succubus              case 17252: spellID=35701; break;               //fellguard              default: -                sLog.outError("EffectInstaKill: Unhandled creature entry (%u) case.",entry); +                sLog.outError("EffectInstaKill: Unhandled creature entry (%u) case.", entry);                  return;          } -        m_caster->CastSpell(m_caster,spellID,true); +        m_caster->CastSpell(m_caster, spellID, true);      } -    if(m_caster==unitTarget)                                // prevent interrupt message +    if(m_caster == unitTarget)                              // prevent interrupt message          finish(); -    uint32 health = unitTarget->GetHealth(); -    m_caster->DealDamage(unitTarget, health, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); +    m_caster->DealDamage(unitTarget, unitTarget->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);  }  void Spell::EffectEnvirinmentalDMG(uint32 i) @@ -291,13 +297,13 @@ void Spell::EffectEnvirinmentalDMG(uint32 i)      // Note: this hack with damage replace required until GO casting not implemented      // environment damage spells already have around enemies targeting but this not help in case not existed GO casting support      // 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]; +    damage = m_spellInfo->CalculateSimpleValue(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) -        ((Player*)m_caster)->EnvironmentalDamage(m_caster->GetGUID(),DAMAGE_FIRE,damage); +        ((Player*)m_caster)->EnvironmentalDamage(DAMAGE_FIRE, damage);  }  void Spell::EffectSchoolDMG(uint32 effect_idx) @@ -315,7 +321,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)                  //Gore                  if(m_spellInfo->SpellIconID == 2269 )                  { -                  damage+= (uint32)unitTarget->GetMap()->rand32()%2 ? damage : 0; +                    damage+= rand()%2 ? damage : 0;                  }                  // Meteor like spells (divided damage to targets) @@ -331,14 +337,48 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)                  switch(m_spellInfo->Id)                     // better way to check unknown                  { -                    case 35354: //Hand of Death -                    { -                        if(unitTarget && unitTarget->HasAura(38528,0)) //Protection of Elune +                    // Positive/Negative Charge +                    case 28062: +                    case 28085: +                    case 39090: +                    case 39093: +                        if(!m_triggeredByAuraSpell) +                            break; +                        if(unitTarget == m_caster)                          { -                            damage = 0; +                            uint8 count = 0; +                            for(std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) +                                if(ihit->targetGUID != m_caster->GetGUID()) +                                    if(Player *target = ObjectAccessor::FindPlayer(ihit->targetGUID)) +                                        if(target->HasAura(m_triggeredByAuraSpell->Id)) +                                            ++count; +                            if(count) +                            { +                                uint32 spellId; +                                switch(m_spellInfo->Id) +                                { +                                    case 28062: spellId = 29659; break; +                                    case 28085: spellId = 29660; break; +                                    case 39090: spellId = 39089; break; +                                    case 39093: spellId = 39092; break; +                                } +                                Aura *aur = m_caster->GetAura(spellId); +                                if(!aur) +                                { +                                    m_caster->CastSpell(m_caster, spellId, true); +                                    aur = m_caster->GetAura(spellId); +                                } +                                if(aur) +                                    aur->SetStackAmount(count); +                            }                          } +                        else if(unitTarget->HasAura(m_triggeredByAuraSpell->Id)) +                            damage = 0; +                        break; +                    // Consumption +                    case 28865: +                        damage = (m_caster->GetMap()->IsHeroic() ? 4250 : 2750);                          break; -                    }                      // percent from health with min                      case 25599:                             // Thundercrash                      { @@ -347,6 +387,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 +409,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)); @@ -376,121 +423,111 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)                  break;              } -            case SPELLFAMILY_MAGE: -            { -                // Arcane Blast -                if(m_spellInfo->SpellFamilyFlags & 0x20000000LL) -                { -                    m_caster->CastSpell(m_caster,36032,true); -                } -                break; -            }              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 && m_spellInfo->Category==1209)                      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; +                } +                // Thunder Clap +                else if(m_spellInfo->SpellFamilyFlags[0] & 0x80) +                { +                    damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 12 / 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); +                    if(unitTarget->HasAuraState(AURA_STATE_IMMOLATE, m_spellInfo, m_caster)) +                        damage += int32(damage*0.25f);                  } -                  // Conflagrate - consumes immolate                  if (m_spellInfo->TargetAuraState == AURA_STATE_IMMOLATE)                  { +                    // Glyph of Conflagrate +                    if (m_caster->HasAura(56235)) +                        break;                      // for caster applied auras only -                    Unit::AuraList const &mPeriodic = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); -                    for(Unit::AuraList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i) +                    Unit::AuraEffectList const &mPeriodic = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); +                    for(Unit::AuraEffectList::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)->GetSpellProto()->SpellFamilyFlags[2] & 2) &&                              (*i)->GetCasterGUID()==m_caster->GetGUID() )                          { -                            unitTarget->RemoveAurasByCasterSpell((*i)->GetId(), m_caster->GetGUID()); +                            unitTarget->RemoveAurasDueToSpell((*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) +                    Unit::AuraEffectList const& mDummyAuras = unitTarget->GetAurasByType(SPELL_AURA_DUMMY); +                    for(Unit::AuraEffectList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i) +                        if((*i)->GetSpellProto()->SpellFamilyFlags[1] & 0x00000440 && (*i)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_DRUID)                          { -                            damage = int32(damage*(100.0f+(*i)->GetModifier()->m_amount)/100.0f); +                            damage = int32(damage*(100.0f+(*i)->GetAmount())/100.0f);                              break;                          }                  } @@ -499,78 +536,97 @@ 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 -                        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() ) +                        Aura *poison = 0; +                        // Lookup for Deadly poison (only attacker applied) +                        Unit::AuraEffectList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); +                        for(Unit::AuraEffectList::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)->GetParentAura(); +                                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->RemoveAuraFromStack(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.21f); +                } +                // 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.2); +                    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.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 = m_caster->GetMap()->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); +                    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.1f);                      bool found = false;                      // check dazed affect -                    Unit::AuraList const& decSpeedList = unitTarget->GetAurasByType(SPELL_AURA_MOD_DECREASE_SPEED); -                    for(Unit::AuraList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter) +                    Unit::AuraEffectList const& decSpeedList = unitTarget->GetAurasByType(SPELL_AURA_MOD_DECREASE_SPEED); +                    for(Unit::AuraEffectList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter)                      {                          if((*iter)->GetSpellProto()->SpellIconID==15 && (*iter)->GetSpellProto()->Dispel==0)                          { @@ -583,28 +639,39 @@ 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) -                { -                    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; +                // Avenger's Shield ($m1+0.07*$SPH+0.07*$AP) +                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 average = (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(average * IN_MILISECONDS) / m_caster->GetAttackTime(BASE_ATTACK); +                } +                // Shield of Righteousness +                else if(m_spellInfo->SpellFamilyFlags[1]&0x00100000) +                { +                    damage+=int32(m_caster->GetShieldBlockValue());                  }                  break;              } @@ -664,9 +731,9 @@ 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)) +                        creatureTarget->GetOrientation(), 0, 0, 0, 0, 100, GO_STATE_READY))                      {                          delete pGameObj;                          return; @@ -708,7 +775,7 @@ void Spell::EffectDummy(uint32 i)                          return;                      uint32 spell_id = 0; -                    switch(m_caster->GetMap()->urand(1,5)) +                    switch(urand(1,5))                      {                          case 1: spell_id = 8064; break;     // Sleepy                          case 2: spell_id = 8065; break;     // Invigorate @@ -716,7 +783,7 @@ void Spell::EffectDummy(uint32 i)                          case 4: spell_id = 8067; break;     // Party Time!                          case 5: spell_id = 8068; break;     // Healthy Spirit                      } -                    m_caster->CastSpell(m_caster,spell_id,true,NULL); +                    m_caster->CastSpell(m_caster, spell_id, true, NULL);                      return;                  }                  case 8213:                                  // Savory Deviate Delight @@ -725,7 +792,7 @@ void Spell::EffectDummy(uint32 i)                          return;                      uint32 spell_id = 0; -                    switch(m_caster->GetMap()->urand(1,2)) +                    switch(urand(1,2))                      {                          // Flip Out - ninja                          case 1: spell_id = (m_caster->getGender() == GENDER_MALE ? 8219 : 8220); break; @@ -738,7 +805,7 @@ void Spell::EffectDummy(uint32 i)                  case 8593:                                  // Symbol of life (restore creature to life)                  case 31225:                                 // Shimmering Vessel (restore creature to life)                  { -                    if(!unitTarget || unitTarget->GetTypeId()!=TYPEID_UNIT) +                    if(!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT)                          return;                      ((Creature*)unitTarget)->setDeathState(JUST_ALIVED);                      return; @@ -772,12 +839,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) @@ -785,7 +846,7 @@ void Spell::EffectDummy(uint32 i)                      uint32 spell_id = 0; -                    uint32 roll = m_caster->GetMap()->urand(0, 99); +                    uint32 roll = urand(0, 99);                      if(roll < 2)                            // 2% for 30 sec self root (off-like chance unknown)                          spell_id = 16566; @@ -814,30 +875,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                  { @@ -852,18 +889,18 @@ void Spell::EffectDummy(uint32 i)                  }                  case 16589:                                 // Noggenfogger Elixir                  { -                    if(m_caster->GetTypeId()!=TYPEID_PLAYER) +                    if(m_caster->GetTypeId() != TYPEID_PLAYER)                          return;                      uint32 spell_id = 0; -                    switch(m_caster->GetMap()->urand(1,3)) +                    switch(urand(1, 3))                      {                          case 1: spell_id = 16595; break;                          case 2: spell_id = 16593; break;                          default:spell_id = 16591; break;                      } -                    m_caster->CastSpell(m_caster,spell_id,true,NULL); +                    m_caster->CastSpell(m_caster, spell_id, true, NULL);                      return;                  }                  case 17251:                                 // Spirit Healer Res @@ -874,7 +911,7 @@ void Spell::EffectDummy(uint32 i)                      if(m_originalCaster->GetTypeId() == TYPEID_PLAYER)                      {                          WorldPacket data(SMSG_SPIRIT_HEALER_CONFIRM, 8); -                        data << unitTarget->GetGUID(); +                        data << uint64(unitTarget->GetGUID());                          ((Player*)m_originalCaster)->GetSession()->SendPacket( &data );                      }                      return; @@ -886,12 +923,12 @@ void Spell::EffectDummy(uint32 i)                      uint32 spell_id = roll_chance_i(50) ? 17269 : 17270; -                    m_caster->CastSpell(m_caster,spell_id,true,NULL); +                    m_caster->CastSpell(m_caster, spell_id, true, NULL);                      return;                  }                  case 20577:                                 // Cannibalize                      if (unitTarget) -                        m_caster->CastSpell(m_caster,20578,false,NULL); +                        m_caster->CastSpell(m_caster, 20578, false, NULL);                      return;                  case 23019:                                 // Crystal Prison Dummy DND                  { @@ -902,57 +939,58 @@ 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"); +                      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); +                    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); +                    m_caster->CastSpell(m_caster, 19804, true, m_CastItem);                      return;                  case 23075:                                 // Mithril Mechanical Dragonling                      if (!m_CastItem) return; -                    m_caster->CastSpell(m_caster,12749,true,m_CastItem); +                    m_caster->CastSpell(m_caster, 12749, true, m_CastItem);                      return;                  case 23076:                                 // Mechanical Dragonling                      if (!m_CastItem) return; -                    m_caster->CastSpell(m_caster,4073,true,m_CastItem); +                    m_caster->CastSpell(m_caster, 4073, true, m_CastItem);                      return;                  case 23133:                                 // Gnomish Battle Chicken                      if (!m_CastItem) return; -                    m_caster->CastSpell(m_caster,13166,true,m_CastItem); +                    m_caster->CastSpell(m_caster, 13166, true, m_CastItem);                      return;                  case 23448:                                 // Ultrasafe Transporter: Gadgetzan - backfires                  { -                  int32 r = m_caster->GetMap()->irand(0, 119); +                    int32 r = irand(0, 119);                      if ( r < 20 )                           // 1/6 polymorph -                        m_caster->CastSpell(m_caster,23444,true); +                        m_caster->CastSpell(m_caster, 23444, true);                      else if ( r < 100 )                     // 4/6 evil twin -                        m_caster->CastSpell(m_caster,23445,true); +                        m_caster->CastSpell(m_caster, 23445, true);                      else                                    // 1/6 miss the target -                        m_caster->CastSpell(m_caster,36902,true); +                        m_caster->CastSpell(m_caster, 36902, true);                      return;                  }                  case 23453:                                 // Ultrasafe Transporter: Gadgetzan                      if ( roll_chance_i(50) )                // success -                        m_caster->CastSpell(m_caster,23441,true); +                        m_caster->CastSpell(m_caster, 23441, true);                      else                                    // failure -                        m_caster->CastSpell(m_caster,23446,true); +                        m_caster->CastSpell(m_caster, 23446, true);                      return;                  case 23645:                                 // Hourglass Sand                      m_caster->RemoveAurasDueToSpell(23170);                      return;                  case 23725:                                 // Gift of Life (warrior bwl trinket) -                    m_caster->CastSpell(m_caster,23782,true); -                    m_caster->CastSpell(m_caster,23783,true); +                    m_caster->CastSpell(m_caster, 23782, true); +                    m_caster->CastSpell(m_caster, 23783, true);                      return;                  case 25860:                                 // Reindeer Transformation                  { @@ -962,7 +1000,7 @@ void Spell::EffectDummy(uint32 i)                      float flyspeed = m_caster->GetSpeedRate(MOVE_FLIGHT);                      float speed = m_caster->GetSpeedRate(MOVE_RUN); -                    m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); +                    m_caster->RemoveAurasByType(SPELL_AURA_MOUNTED);                      //5 different spells used depending on mounted speed and if mount can fly or not                      if (flyspeed >= 4.1f) @@ -982,21 +1020,20 @@ void Spell::EffectDummy(uint32 i)                  //    return; -- implemented at client side                  case 28006:                                 // Arcane Cloaking                  { -                    if( unitTarget->GetTypeId() == TYPEID_PLAYER ) -                        m_caster->CastSpell(unitTarget,29294,true); -                    return; -                } -                case 28730:                                 // Arcane Torrent (Mana) -                { -                    Aura * dummy = m_caster->GetDummyAura(28734); -                    if (dummy) -                    { -                        int32 bp = damage * dummy->GetStackAmount(); -                        m_caster->CastCustomSpell(m_caster, 28733, &bp, NULL, NULL, true); -                        m_caster->RemoveAurasDueToSpell(28734); -                    } +                    if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER ) +                        m_caster->CastSpell(unitTarget, 29294, true);                      return;                  } +                // Polarity Shift +                case 28089: +                    if(unitTarget) +                        unitTarget->CastSpell(unitTarget, roll_chance_i(50) ? 28059 : 28084, true, NULL, NULL, m_caster->GetGUID()); +                    break; +                // Polarity Shift +                case 39096: +                    if(unitTarget) +                        unitTarget->CastSpell(unitTarget, roll_chance_i(50) ? 39088 : 39091, true, NULL, NULL, m_caster->GetGUID()); +                    break;                  case 29200:                                 // Purify Helboar Meat                  {                      if( m_caster->GetTypeId() != TYPEID_PLAYER ) @@ -1026,6 +1063,13 @@ void Spell::EffectDummy(uint32 i)                      else                                    // backfire 20%                          m_caster->CastSpell(unitTarget, 30504, true, m_CastItem);                      return; +                case 55004: //Nitro Boosts +                    if(!m_CastItem) return; +                    if(roll_chance_i(95)) //success +                        m_caster->CastSpell(m_caster, 54861, true, m_CastItem); +                    else                  //backfire 5% +                        m_caster->CastSpell(m_caster, 46014, true, m_CastItem); +                    return;                  case 33060:                                         // Make a Wish                  {                      if(m_caster->GetTypeId()!=TYPEID_PLAYER) @@ -1033,7 +1077,7 @@ void Spell::EffectDummy(uint32 i)                      uint32 spell_id = 0; -                    switch(m_caster->GetMap()->urand(1,5)) +                    switch(urand(1,5))                      {                          case 1: spell_id = 33053; break;                          case 2: spell_id = 33057; break; @@ -1042,7 +1086,7 @@ void Spell::EffectDummy(uint32 i)                          case 5: spell_id = 33064; break;                      } -                    m_caster->CastSpell(m_caster,spell_id,true,NULL); +                    m_caster->CastSpell(m_caster, spell_id, true, NULL);                      return;                  }                  case 35745: @@ -1055,7 +1099,7 @@ void Spell::EffectDummy(uint32 i)                          default: return;                      } -                    m_caster->CastSpell(m_caster,spell_id,true); +                    m_caster->CastSpell(m_caster, spell_id, true);                      return;                  }                  case 37674:                                 // Chaos Blast @@ -1064,14 +1108,14 @@ void Spell::EffectDummy(uint32 i)                          return;                      int32 basepoints0 = 100; -                    m_caster->CastCustomSpell(unitTarget,37675,&basepoints0,NULL,NULL,true); +                    m_caster->CastCustomSpell(unitTarget, 37675, &basepoints0, NULL, NULL, true);                      return;                  }                  case 40802:                                 // Mingo's Fortune Generator (Mingo's Fortune Giblets)                  {                      // selecting one from Bloodstained Fortune item                      uint32 newitemid; -                    switch(m_caster->GetMap()->urand(1,20)) +                    switch(urand(1, 20))                      {                          case 1:  newitemid = 32688; break;                          case 2:  newitemid = 32689; break; @@ -1097,7 +1141,7 @@ void Spell::EffectDummy(uint32 i)                              return;                      } -                    DoCreateItem(i,newitemid); +                    DoCreateItem(i, newitemid);                      return;                  }                  // Demon Broiled Surprise @@ -1123,37 +1167,7 @@ void Spell::EffectDummy(uint32 i)                      creatureTarget->SetHealth(0);           // just for nice GM-mode view                      //cast spell Raptor Capture Credit -                    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[m_caster->GetMap()->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); - +                    m_caster->CastSpell(m_caster, 42337, true, NULL);                      return;                  }                  case 34665:                                 //Administer Antidote @@ -1164,7 +1178,7 @@ void Spell::EffectDummy(uint32 i)                      if(!unitTarget)                          return; -                    TemporarySummon* tempSummon = dynamic_cast<TemporarySummon*>(unitTarget); +                    TempSummon* tempSummon = dynamic_cast<TempSummon*>(unitTarget);                      if(!tempSummon)                          return; @@ -1181,7 +1195,7 @@ void Spell::EffectDummy(uint32 i)                          return;                      pCreature->SetHealth(health); -                    ((Player*)m_caster)->KilledMonster(16992,pCreature->GetGUID()); +                    ((Player*)m_caster)->RewardPlayerAndGroupAtEvent(16992, pCreature);                      if (pCreature->IsAIEnabled)                          pCreature->AI()->AttackStart(m_caster); @@ -1231,7 +1245,52 @@ void Spell::EffectDummy(uint32 i)                      m_caster->CastSpell(m_caster, 30452, true, NULL);                      return; -                }                 +                } +                case 51592:                                 // Pickup Primordial Hatchling +                { +                    if(!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT) +                        return; + +                    Creature* creatureTarget = (Creature*)unitTarget; + +                    creatureTarget->setDeathState(JUST_DIED); +                    creatureTarget->RemoveCorpse(); +                    creatureTarget->SetHealth(0);           // just for nice GM-mode view +                    return; + +                } +                case 52308: +                { +                    switch(i) +                    { +                        case 0: +                        { +                            uint32 spellID = m_spellInfo->CalculateSimpleValue(0); +                            uint32 reqAuraID = m_spellInfo->CalculateSimpleValue(1); + +                            if (m_caster->HasAuraEffect(reqAuraID,0)) +                                m_caster->CastSpell(m_caster,spellID,true,NULL); +                            return; +                        } +                        case 1: +                            return;                         // additional data for dummy[0] +                    } +                    return; +                } +                case 52759:                                 // Ancestral Awakening +                    if (!unitTarget) +                        return; +                    m_caster->CastCustomSpell(unitTarget, 52752, &damage, NULL, NULL, true); +                    return; +                case 53341: +                case 53343: +                { +                    m_caster->CastSpell(m_caster, 54586, true); +                    return; +                } +                case 58418:                                 // Portal to Orgrimmar +                case 58420:                                 // Portal to Stormwind +                    return;                                 // implemented in EffectScript[0]              }              //All IconID Check in there @@ -1253,7 +1312,7 @@ void Spell::EffectDummy(uint32 i)                      // FIXME: custom spell required this aura state by some unknown reason, we not need remove it anyway                      m_caster->ModifyAuraState(AURA_STATE_BERSERKING,true); -                    m_caster->CastCustomSpell(m_caster,26635,&hasteModBasePoints0,&hasteModBasePoints1,&hasteModBasePoints2,true,NULL); +                    m_caster->CastCustomSpell(m_caster, 26635, &hasteModBasePoints0, &hasteModBasePoints1, &hasteModBasePoints2, true, NULL);                      return;                  }              } @@ -1281,12 +1340,7 @@ void Spell::EffectDummy(uint32 i)                              (GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_FROST) &&                              spellInfo->Id != 11958 && GetSpellRecoveryTime(spellInfo) > 0 )                          { -                            ((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); +                            ((Player*)m_caster)->RemoveSpellCooldown(classspell, true);                          }                      }                      return; @@ -1297,7 +1351,7 @@ void Spell::EffectDummy(uint32 i)                      {                          //Polymorph Cast Visual Rank 1                          const uint32 spell_list[6] = {32813, 32816, 32817, 32818, 32819, 32820}; -                        unitTarget->CastSpell( unitTarget, spell_list[m_caster->GetMap()->urand(0, 5)], true); +                        unitTarget->CastSpell( unitTarget, spell_list[urand(0, 5)], true);                      }                      return;                  } @@ -1305,65 +1359,140 @@ 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); +                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=0; +                // Glyph of Execution bonus +                if (AuraEffect *aura = m_caster->GetDummyAura(58367)) +                    rage+=aura->GetAmount(); +                  spell_id = 20647; -                bp = damage+int32(m_caster->GetPower(POWER_RAGE) * m_spellInfo->DmgMultiplier[i]); -                m_caster->SetPower(POWER_RAGE,0); +                // Sudden death cost modifier +                if (Aura * aur = m_caster->GetAura(52437)) +                { +                    rage += m_powerCost; +                    m_caster->ModifyPower(POWER_RAGE,- m_powerCost); +                    if (m_caster->GetPower(POWER_RAGE)<100) +                        m_caster->SetPower(POWER_RAGE,100); +                    m_caster->RemoveAura(aur); +                } +                else +                { +                    rage += m_caster->GetPower(POWER_RAGE); +                    m_caster->SetPower(POWER_RAGE,0); +                } + +                bp = damage+int32(rage * m_spellInfo->DmgMultiplier[i] + +                                                 m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f);                  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;              } +            // Concussion Blow +            if(m_spellInfo->SpellFamilyFlags[0] & 0x4000000) +            { +                m_damage+= uint32(damage * m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100); +                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 = uint32(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(unitTarget && (int32(unitTarget->GetHealth()) > damage))                  {                      // Shouldn't Appear in Combat Log -                    m_caster->ModifyHealth(-dmg); - -                    int32 mana = dmg; +                    unitTarget->ModifyHealth(-damage); -                    Unit::AuraList const& auraDummy = m_caster->GetAurasByType(SPELL_AURA_DUMMY); -                    for(Unit::AuraList::const_iterator itr = auraDummy.begin(); itr != auraDummy.end(); ++itr) +                    int32 mana = damage; +                    // Improved Life Tap mod +                    Unit::AuraEffectList const& auraDummy = m_caster->GetAurasByType(SPELL_AURA_DUMMY); +                    for(Unit::AuraEffectList::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; +                            mana = ((*itr)->GetAmount() + 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::AuraEffectList const& mod = m_caster->GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER); +                    for(Unit::AuraEffectList::const_iterator itr = mod.begin(); itr != mod.end(); ++itr) +                    { +                        if((*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (*itr)->GetSpellProto()->SpellIconID == 1982) +                            manaFeedVal+= (*itr)->GetAmount(); +                    }                      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); @@ -1371,52 +1500,54 @@ void Spell::EffectDummy(uint32 i)              }              break;          case SPELLFAMILY_PRIEST: -            switch(m_spellInfo->Id ) +            // Penance +            if (m_spellInfo->SpellFamilyFlags[1] & 0x00800000)              { -                case 28598:                                 // Touch of Weakness triggered spell +                if (!unitTarget || !unitTarget->isAlive()) +                    return; + +                int hurt = 0; +                int heal = 0; +                switch(m_spellInfo->Id)                  { -                    if(!unitTarget || !m_triggeredByAuraSpell) +                    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; - -                    uint32 spellid = 0; -                    switch(m_triggeredByAuraSpell->Id) -                    { -                        case 2652:  spellid =  2943; break; // Rank 1 -                        case 19261: spellid = 19249; break; // Rank 2 -                        case 19262: spellid = 19251; break; // Rank 3 -                        case 19264: spellid = 19252; break; // Rank 4 -                        case 19265: spellid = 19253; break; // Rank 5 -                        case 19266: spellid = 19254; break; // Rank 6 -                        case 25461: spellid = 25460; break; // Rank 7 -                        default: -                            sLog.outError("Spell::EffectDummy: Spell 28598 triggered by unhandled spell %u",m_triggeredByAuraSpell->Id); -                            return; -                    } -                    m_caster->CastSpell(unitTarget, spellid, true, NULL); -                    return;                  } +                if (m_caster->IsFriendlyTo(unitTarget)) +                    m_caster->CastSpell(unitTarget, heal, true, 0); +                else +                    m_caster->CastSpell(unitTarget, hurt, true, 0); +                return;              }              break;          case SPELLFAMILY_DRUID: -            switch(m_spellInfo->Id ) +            // Starfall +            if (m_spellInfo->SpellFamilyFlags[2] & 0x100)              { -                case 5420:                                  // Tree of Life passive +                //Shapeshifting into an animal form or mounting cancels the effect. +                if(m_caster->GetCreatureType() == CREATURE_TYPE_BEAST || m_caster->IsMounted())                  { -                    // 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); +                    if(m_triggeredByAuraSpell) +                        m_caster->RemoveAurasDueToSpell(m_triggeredByAuraSpell->Id);                      return;                  } + +                //Any effect which causes you to lose control of your character will supress the starfall effect. +                if(m_caster->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_ROOT | UNIT_STAT_CONFUSED)) +                    return; + +                m_caster->CastSpell(unitTarget, damage, true); +                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) @@ -1452,36 +1583,31 @@ 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()) +                        if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags[1] & 0x00000240 || spellInfo->SpellFamilyFlags[0] & 0x00000860)) +                            ((Player*)m_caster)->RemoveSpellCooldown(classspell,true); +                    }                      return; - -                uint32 spell_id = 0; -                switch (m_spellInfo->Id) +                } +                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 @@ -1497,14 +1623,7 @@ void Spell::EffectDummy(uint32 i)                          SpellEntry const *spellInfo = sSpellStore.LookupEntry(classspell);                          if (spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && spellInfo->Id != 23989 && GetSpellRecoveryTime(spellInfo) > 0 ) -                        { -                            ((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); -                        } +                            ((Player*)m_caster)->RemoveSpellCooldown(classspell,true);                      }                      return;                  } @@ -1524,6 +1643,13 @@ void Spell::EffectDummy(uint32 i)          case SPELLFAMILY_PALADIN:              switch(m_spellInfo->SpellIconID)              { +                // Divine Storm +                if (m_spellInfo->SpellFamilyFlags[1] & 0x20000) +                { +                    int32 damage=m_currentBasePoints[0] * damage /100; +                    m_caster->CastCustomSpell(unitTarget, 54172, &damage , 0, 0, true); +                    return; +                }                  case  156:                                  // Holy Shock                  {                      if(!unitTarget) @@ -1539,6 +1665,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; @@ -1551,43 +1679,38 @@ void Spell::EffectDummy(uint32 i)                      return;                  } -                case 561:                                   // Judgement of command +            } + +            switch(m_spellInfo->Id) +            { +                case 20425:                                   // Judgement of command                  {                      if(!unitTarget)                          return; -                    uint32 spell_id = m_spellInfo->EffectBasePoints[i]+1;//m_currentBasePoints[i]+1; -                    SpellEntry const* spell_proto = sSpellStore.LookupEntry(spell_id); +                    SpellEntry const* spell_proto = sSpellStore.LookupEntry(damage);                      if(!spell_proto)                          return; -                    if( !unitTarget->hasUnitState(UNIT_STAT_STUNNED) && m_caster->GetTypeId()==TYPEID_PLAYER) +                    if(unitTarget->hasUnitState(UNIT_STAT_STUNNED) && m_caster->GetTypeId()==TYPEID_PLAYER)                      { -                        // decreased damage (/2) for non-stunned target. +                        // always critical for stunned target                          SpellModifier *mod = new SpellModifier; -                        mod->op = SPELLMOD_DAMAGE; -                        mod->value = -50; -                        mod->type = SPELLMOD_PCT; +                        mod->op = SPELLMOD_CRITICAL_CHANCE; +                        mod->value = 100; +                        mod->type = SPELLMOD_FLAT;                          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); -                                                            // mod deleted                          ((Player*)m_caster)->AddSpellMod(mod, false);                      }                      else -                        m_caster->CastSpell(unitTarget,spell_proto,true,NULL); +                        m_caster->CastSpell(unitTarget, spell_proto, true, NULL);                      return;                  } -            } - -            switch(m_spellInfo->Id) -            {                  case 31789:                                 // Righteous Defense (step 1)                  {                      // 31989 -> dummy effect (step 1) + dummy effect (step 2) -> 31709 (taunt like spell for each target) @@ -1595,17 +1718,8 @@ void Spell::EffectDummy(uint32 i)                      // non-standard cast requirement check                      if (!unitTarget || unitTarget->getAttackers().empty())                      { -                        // clear cooldown at fail                          if(m_caster->GetTypeId()==TYPEID_PLAYER) -                        { -                            ((Player*)m_caster)->RemoveSpellCooldown(m_spellInfo->Id); - -                            WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8)); -                            data << uint32(m_spellInfo->Id); -                            data << uint64(m_caster->GetGUID()); -                            ((Player*)m_caster)->GetSession()->SendPacket(&data); -                        } - +                            ((Player*)m_caster)->RemoveSpellCooldown(m_spellInfo->Id,true);                          SendCastResult(SPELL_FAILED_TARGET_AFFECTING_COMBAT);                          return;                      } @@ -1647,15 +1761,17 @@ void Spell::EffectDummy(uint32 i)                          default: return;                    // ignore for not healing classes                      } -                    m_caster->CastSpell(m_caster,spell_id,true); +                    m_caster->CastSpell(m_caster, spell_id, true);                      return;                  }              }              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)                  { @@ -1663,13 +1779,8 @@ 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); +                        sLog.outError("Spell::EffectDummy: Spell %u not handled in RW", m_spellInfo->Id);                          return;                  } @@ -1677,16 +1788,16 @@ void Spell::EffectDummy(uint32 i)                  if(!spellInfo)                  { -                    sLog.outError("WORLD: unknown spell id %i\n", spell_id); +                    sLog.outError("WORLD: unknown spell id %i", spell_id);                      return;                  }                  if(m_caster->GetTypeId() != TYPEID_PLAYER)                      return; -                for(int i = BASE_ATTACK; i <= OFF_ATTACK; ++i) +                for(int j = BASE_ATTACK; j <= OFF_ATTACK; ++j)                  { -                    if(Item* item = ((Player*)m_caster)->GetWeaponForAttack(WeaponAttackType(i))) +                    if(Item* item = ((Player*)m_caster)->GetWeaponForAttack(WeaponAttackType(j)))                      {                          if(item->IsFitToSpellRequirements(m_spellInfo))                          { @@ -1705,18 +1816,89 @@ void Spell::EffectDummy(uint32 i)                  }                  return;              } - -            if(m_spellInfo->Id == 39610)                    // Mana-Tide Totem effect +            // Cleansing Totem +            if(m_spellInfo->SpellFamilyFlags[0] & 0x04000000 && m_spellInfo->SpellIconID==1673) +            { +                m_caster->CastSpell(unitTarget, 52025, true, 0, 0, m_originalCasterGUID); +                return; +            } +            // 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 (AuraEffect *dummy = owner->GetDummyAura(55441)) +                        damage+=dummy->GetAmount();                  // 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); +                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) +                { +                    if (m_caster->GetAura(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, 0x200000)) +                    { +                           m_damage += m_damage * damage / 100; +                    } +                } +                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;              } +            // Death Coil +            else if(m_spellInfo->SpellFamilyFlags[0] & 0x002000) +            { +                if(m_caster->IsFriendlyTo(unitTarget)) +                { +                    if(unitTarget->GetCreatureType() != CREATURE_TYPE_UNDEAD) +                        return; +                    int32 bp = damage * 1.5f; +                    m_caster->CastCustomSpell(unitTarget, 47633, &bp, NULL, NULL, true); +                } +                else +                { +                    int32 bp = damage; +                    m_caster->CastCustomSpell(unitTarget, 47632, &bp, NULL, NULL, true); +                } +                return; +            } +            // Death Grip +            else if(m_spellInfo->Id == 49560) +            { +                unitTarget->CastSpell(m_caster, damage, true); +                return; +            }              break;      } @@ -1744,6 +1926,15 @@ void Spell::EffectDummy(uint32 i)          m_caster->AddPetAura(petSpell);          return;      } + +    // Script based implementation. Must be used only for not good for implementation in core spell effects +    // So called only for not proccessed cases +    if(gameObjTarget) +        Script->EffectDummyGameObj(m_caster, m_spellInfo->Id, i, gameObjTarget); +    else if(unitTarget && unitTarget->GetTypeId()==TYPEID_UNIT) +        Script->EffectDummyCreature(m_caster, m_spellInfo->Id, i, (Creature*)unitTarget); +    else if(itemTarget) +        Script->EffectDummyItem(m_caster, m_spellInfo->Id, i, itemTarget);  }  void Spell::EffectTriggerSpellWithValue(uint32 i) @@ -1755,7 +1946,7 @@ void Spell::EffectTriggerSpellWithValue(uint32 i)      if(!spellInfo)      { -        sLog.outError("EffectTriggerSpellWithValue of spell %u: triggering unknown spell id %i\n", m_spellInfo->Id,triggered_spell_id); +        sLog.outError("EffectTriggerSpellWithValue of spell %u: triggering unknown spell id %i", m_spellInfo->Id,triggered_spell_id);          return;      } @@ -1781,8 +1972,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()]);  } @@ -1802,7 +1993,7 @@ void Spell::EffectForceCast(uint32 i)          return;      } -    unitTarget->CastSpell(unitTarget,spellInfo,true,NULL,NULL,m_originalCasterGUID); +    unitTarget->CastSpell(unitTarget, spellInfo, true, NULL, NULL, m_originalCasterGUID);  }  void Spell::EffectTriggerSpell(uint32 i) @@ -1815,16 +2006,15 @@ void Spell::EffectTriggerSpell(uint32 i)          // Vanish          case 18461:          { -            m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT); -            m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOD_DECREASE_SPEED); -            m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOD_STALKED); +            m_caster->RemoveMovementImpairingAuras(); +            m_caster->RemoveAurasByType(SPELL_AURA_MOD_STALKED);              // if this spell is given to NPC it must handle rest by it's own AI              if ( m_caster->GetTypeId() != TYPEID_PLAYER )                  return;              // get highest rank of the Stealth spell -            bool found = false; +            uint32 spellId = 0;              SpellEntry const *spellInfo;              const PlayerSpellMap& sp_list = ((Player*)m_caster)->GetSpellMap();              for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr) @@ -1837,24 +2027,36 @@ 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)                  { -                    found=true; +                    spellId = spellInfo->Id;                      break;                  }              }              // no Stealth spell found -            if (!found) +            if (!spellId)                  return;              // reset cooldown on it if needed -            if(((Player*)m_caster)->HasSpellCooldown(spellInfo->Id)) -                ((Player*)m_caster)->RemoveSpellCooldown(spellInfo->Id); +            if(((Player*)m_caster)->HasSpellCooldown(spellId)) +                ((Player*)m_caster)->RemoveSpellCooldown(spellId); +            // Push stealth to list because it must be handled after combat remove              m_TriggerSpells.push_back(spellInfo);              return;          } +        // Demonic Empowerment -- succubus +        case 54437: +        { +            unitTarget->RemoveMovementImpairingAuras(); +            unitTarget->RemoveAurasByType(SPELL_AURA_MOD_STALKED); +            unitTarget->RemoveAurasByType(SPELL_AURA_MOD_STUN); + +            // Cast Lesser Invisibility +            triggered_spell_id = 7870; +            break; +        }          // just skip          case 23770:                                         // Sayge's Dark Fortune of *              // not exist, common cooldown can be implemented in scripts if need. @@ -1866,8 +2068,8 @@ void Spell::EffectTriggerSpell(uint32 i)              if (!spell)                  return; -            for (int i=0; i < spell->StackAmount; ++i) -                m_caster->CastSpell(unitTarget,spell->Id, true, m_CastItem, NULL, m_originalCasterGUID); +            for (int j=0; j < spell->StackAmount; ++j) +                m_caster->CastSpell(unitTarget, spell->Id, true, m_CastItem, NULL, m_originalCasterGUID);              return;          }          // Mercurial Shield - (need add max stack of 26464 Mercurial Shield) @@ -1877,14 +2079,14 @@ void Spell::EffectTriggerSpell(uint32 i)              if (!spell)                  return; -            for (int i=0; i < spell->StackAmount; ++i) -                m_caster->CastSpell(unitTarget,spell->Id, true, m_CastItem, NULL, m_originalCasterGUID); +            for (int j=0; j < spell->StackAmount; ++j) +                m_caster->CastSpell(unitTarget, spell->Id, true, m_CastItem, NULL, m_originalCasterGUID);              return;          }          // Righteous Defense          case 31980:          { -            m_caster->CastSpell(unitTarget, 31790, true,m_CastItem,NULL,m_originalCasterGUID); +            m_caster->CastSpell(unitTarget, 31790, true, m_CastItem, NULL, m_originalCasterGUID);              return;          }          // Cloak of Shadows @@ -1892,7 +2094,7 @@ void Spell::EffectTriggerSpell(uint32 i)          {              uint32 dispelMask = GetDispellMask(DISPEL_ALL);              Unit::AuraMap& Auras = m_caster->GetAuras(); -            for(Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end(); ++iter) +            for(Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end();)              {                  // remove all harmful spells on you...                  SpellEntry const* spell = iter->second->GetSpellProto(); @@ -1901,16 +2103,17 @@ void Spell::EffectTriggerSpell(uint32 i)                      // ignore positive and passive auras                      && !iter->second->IsPositive() && !iter->second->IsPassive())                  { -                    m_caster->RemoveAurasDueToSpell(spell->Id); -                    iter = Auras.begin(); +                    m_caster->RemoveAura(iter);                  } +                else +                    iter++;              }              return;          }          // Priest Shadowfiend (34433) need apply mana gain trigger aura on pet          case 41967:          { -            if (Unit *pet = m_caster->GetPet()) +            if (Unit *pet = m_caster->GetGuardianPet())                  pet->CastSpell(pet, 28305, true);              return;          } @@ -1925,44 +2128,13 @@ void Spell::EffectTriggerSpell(uint32 i)          return;      } -    // some triggered spells require specific equipment -    if(spellInfo->EquippedItemClass >=0 && m_caster->GetTypeId()==TYPEID_PLAYER) -    { -        // main hand weapon required -        if(spellInfo->AttributesEx3 & SPELL_ATTR_EX3_MAIN_HAND) -        { -            Item* item = ((Player*)m_caster)->GetWeaponForAttack(BASE_ATTACK); - -            // skip spell if no weapon in slot or broken -            if(!item || item->IsBroken() ) -                return; - -            // skip spell if weapon not fit to triggered spell -            if(!item->IsFitToSpellRequirements(spellInfo)) -                return; -        } - -        // offhand hand weapon required -        if(spellInfo->AttributesEx3 & SPELL_ATTR_EX3_REQ_OFFHAND) -        { -            Item* item = ((Player*)m_caster)->GetWeaponForAttack(OFF_ATTACK); - -            // skip spell if no weapon in slot or broken -            if(!item || item->IsBroken() ) -                return; - -            // skip spell if weapon not fit to triggered spell -            if(!item->IsFitToSpellRequirements(spellInfo)) -                return; -        } -    } -      // some triggered spells must be casted instantly (for example, if next effect case instant kill caster)      bool instant = false;      for(uint32 j = i+1; j < 3; ++j)      {          if(m_spellInfo->EffectImplicitTargetA[j] == TARGET_UNIT_CASTER -            && (m_spellInfo->Effect[j]==SPELL_EFFECT_INSTAKILL)) +            && (m_spellInfo->Effect[j]==SPELL_EFFECT_INSTAKILL  +            || m_spellInfo->Effect[j]==SPELL_EFFECT_SANCTUARY))          {              instant = true;              break; @@ -1995,12 +2167,65 @@ 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 ); +    m_caster->CastSpell(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, spellInfo->Id, true, m_CastItem, 0, 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); +void Spell::EffectJump(uint32 i) +{ +    if(m_caster->isInFlight()) +        return; + +    // Init dest coordinates +    float x,y,z,o; +    if(m_targets.HasDst()) +    { +        x = m_targets.m_destX; +        y = m_targets.m_destY; +        z = m_targets.m_destZ; + +        if(m_spellInfo->EffectImplicitTargetA[i] == TARGET_DEST_TARGET_BACK) +        { +            // explicit cast data from client or server-side cast +            // some spell at client send caster +            Unit* pTarget = NULL; +            if(m_targets.getUnitTarget() && m_targets.getUnitTarget()!=m_caster) +                pTarget = m_targets.getUnitTarget(); +            else if(m_caster->getVictim()) +                pTarget = m_caster->getVictim(); +            else if(m_caster->GetTypeId() == TYPEID_PLAYER) +                pTarget = ObjectAccessor::GetUnit(*m_caster, ((Player*)m_caster)->GetSelection()); + +            o = pTarget ? pTarget->GetOrientation() : m_caster->GetOrientation(); +        } +        else +            o = m_caster->GetOrientation(); +    } +    else if(m_targets.getUnitTarget()) +    { +        m_targets.getUnitTarget()->GetContactPoint(m_caster,x,y,z,CONTACT_DISTANCE); +        o = m_caster->GetOrientation(); +    } +    else if(m_targets.getGOTarget()) +    { +        m_targets.getGOTarget()->GetContactPoint(m_caster,x,y,z,CONTACT_DISTANCE); +        o = m_caster->GetOrientation(); +    } +    else +    { +        sLog.outError( "Spell::EffectJump - unsupported target mode for spell ID %u", m_spellInfo->Id ); +        return; +    } + +    //m_caster->NearTeleportTo(x,y,z,o,true); +    float speedZ; +    if(m_spellInfo->EffectMiscValue[i]) +        speedZ = float(m_spellInfo->EffectMiscValue[i])/10; +    else if(m_spellInfo->EffectMiscValueB[i]) +        speedZ = float(m_spellInfo->EffectMiscValueB[i])/10; +    else +        speedZ = 10.0f; +    float speedXY = m_caster->GetExactDistance2d(x, y) * 10.0f / speedZ; +    m_caster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ);  }  void Spell::EffectTeleportUnits(uint32 i) @@ -2014,6 +2239,7 @@ void Spell::EffectTeleportUnits(uint32 i)          sLog.outError( "Spell::EffectTeleportUnits - does not have destination for spell ID %u\n", m_spellInfo->Id );          return;      } +      // Init dest coordinates      int32 mapid = m_targets.m_mapId;      if(mapid < 0) mapid = (int32)unitTarget->GetMapId(); @@ -2022,16 +2248,11 @@ void Spell::EffectTeleportUnits(uint32 i)      float z = m_targets.m_destZ;      float orientation = m_targets.getUnitTarget() ? m_targets.getUnitTarget()->GetOrientation() : unitTarget->GetOrientation();      sLog.outDebug("Spell::EffectTeleportUnits - teleport unit to %u %f %f %f\n", mapid, x, y, z); -    // Teleport -    if(unitTarget->GetTypeId() == TYPEID_PLAYER) -        ((Player*)unitTarget)->TeleportTo(mapid, x, y, z, orientation, TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (unitTarget==m_caster ? TELE_TO_SPELL : 0)); -    else -    { -        MapManager::Instance().GetMap(mapid, m_caster)->CreatureRelocation((Creature*)unitTarget, x, y, z, orientation); -        WorldPacket data; -        unitTarget->BuildTeleportAckMsg(&data, x, y, z, orientation); -        unitTarget->SendMessageToSet(&data, false); -    } + +    if(mapid == unitTarget->GetMapId()) +        unitTarget->NearTeleportTo(x, y, z, orientation, unitTarget == m_caster); +    else if(unitTarget->GetTypeId() == TYPEID_PLAYER) +        ((Player*)unitTarget)->TeleportTo(mapid, x, y, z, orientation, unitTarget==m_caster ? TELE_TO_SPELL : 0);      // post effects for TARGET_DST_DB      switch ( m_spellInfo->Id ) @@ -2039,13 +2260,13 @@ void Spell::EffectTeleportUnits(uint32 i)          // Dimensional Ripper - Everlook          case 23442:          { -          int32 r = m_caster->GetMap()->irand(0, 119); +            int32 r = irand(0, 119);              if ( r >= 70 )                                  // 7/12 success              {                  if ( r < 100 )                              // 4/12 evil twin -                    m_caster->CastSpell(m_caster,23445,true); +                    m_caster->CastSpell(m_caster, 23445, true);                  else                                        // 1/12 fire -                    m_caster->CastSpell(m_caster,23449,true); +                    m_caster->CastSpell(m_caster, 23449, true);              }              return;          } @@ -2054,41 +2275,41 @@ void Spell::EffectTeleportUnits(uint32 i)          {              if ( roll_chance_i(50) )                        // 50% success              { -              int32 rand_eff = m_caster->GetMap()->urand(1,7); +                int32 rand_eff = urand(1, 7);                  switch ( rand_eff )                  {                      case 1:                          // soul split - evil -                        m_caster->CastSpell(m_caster,36900,true); +                        m_caster->CastSpell(m_caster, 36900, true);                          break;                      case 2:                          // soul split - good -                        m_caster->CastSpell(m_caster,36901,true); +                        m_caster->CastSpell(m_caster, 36901, true);                          break;                      case 3:                          // Increase the size -                        m_caster->CastSpell(m_caster,36895,true); +                        m_caster->CastSpell(m_caster, 36895, true);                          break;                      case 4:                          // Decrease the size -                        m_caster->CastSpell(m_caster,36893,true); +                        m_caster->CastSpell(m_caster, 36893, true);                          break;                      case 5:                      // Transform                      {                          if (((Player*)m_caster)->GetTeam() == ALLIANCE ) -                            m_caster->CastSpell(m_caster,36897,true); +                            m_caster->CastSpell(m_caster, 36897, true);                          else -                            m_caster->CastSpell(m_caster,36899,true); +                            m_caster->CastSpell(m_caster, 36899, true);                          break;                      }                      case 6:                          // chicken -                        m_caster->CastSpell(m_caster,36940,true); +                        m_caster->CastSpell(m_caster, 36940, true);                          break;                      case 7:                          // evil twin -                        m_caster->CastSpell(m_caster,23445,true); +                        m_caster->CastSpell(m_caster, 23445, true);                          break;                  }              } @@ -2099,28 +2320,28 @@ void Spell::EffectTeleportUnits(uint32 i)          {              if ( roll_chance_i(50) )                        // 50% success              { -              int32 rand_eff = m_caster->GetMap()->urand(1,4); +                int32 rand_eff = urand(1, 4);                  switch ( rand_eff )                  {                      case 1:                          // soul split - evil -                        m_caster->CastSpell(m_caster,36900,true); +                        m_caster->CastSpell(m_caster, 36900, true);                          break;                      case 2:                          // soul split - good -                        m_caster->CastSpell(m_caster,36901,true); +                        m_caster->CastSpell(m_caster, 36901, true);                          break;                      case 3:                          // Increase the size -                        m_caster->CastSpell(m_caster,36895,true); +                        m_caster->CastSpell(m_caster, 36895, true);                          break;                      case 4:                      // Transform                      {                          if (((Player*)m_caster)->GetTeam() == ALLIANCE ) -                            m_caster->CastSpell(m_caster,36897,true); +                            m_caster->CastSpell(m_caster, 36897, true);                          else -                            m_caster->CastSpell(m_caster,36899,true); +                            m_caster->CastSpell(m_caster, 36899, true);                          break;                      }                  } @@ -2132,84 +2353,16 @@ void Spell::EffectTeleportUnits(uint32 i)  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; -    if(!caster) -        return; - -    sLog.outDebug("Spell: Aura is: %u", m_spellInfo->EffectApplyAuraName[i]); - -    Aura* Aur = CreateAura(m_spellInfo, i, &damage, unitTarget, caster, m_CastItem); - -    // Now Reduce spell duration using data received at spell hit -    int32 duration = Aur->GetAuraMaxDuration(); -    unitTarget->ApplyDiminishingToDuration(m_diminishGroup,duration,caster,m_diminishLevel); -    Aur->setDiminishGroup(m_diminishGroup); - -    // if Aura removed and deleted, do not continue. -    if(duration== 0 && !(Aur->IsPermanent())) -    { -        delete Aur; -        return; -    } - -    if(duration != Aur->GetAuraMaxDuration()) -    { -        Aur->SetAuraMaxDuration(duration); -        Aur->SetAuraDuration(duration); -    } - -    bool added = unitTarget->AddAura(Aur); - -    // Aura not added and deleted in AddAura call; -    if (!added) -        return; - -    // found crash at character loading, broken pointer to Aur... -    // Aur was deleted in AddAura()... -    if(!Aur) -        return; - -    // TODO Make a way so it works for every related spell! -    if(unitTarget->GetTypeId()==TYPEID_PLAYER ||( unitTarget->GetTypeId()==TYPEID_UNIT && ((Creature*)unitTarget)->isPet() ) )              // 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]); -        } -    } +    if (m_spellAura) +        if (AuraEffect * AurEff = m_spellAura->GetPartAura(i)) +            unitTarget->HandleAuraEffect(AurEff, true); +} -    // Prayer of Mending (jump animation), we need formal caster instead original for correct animation -    if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && (m_spellInfo->SpellFamilyFlags & 0x00002000000000LL)) -        m_caster->CastSpell(unitTarget, 41637, true, NULL, Aur, m_originalCasterGUID); +void Spell::EffectApplyAreaAura(uint32 i) +{ +    if (m_spellAura) +        if (AuraEffect * AurEff = m_spellAura->GetPartAura(i)) +            unitTarget->HandleAuraEffect(AurEff, true);  }  void Spell::EffectUnlearnSpecialization( uint32 i ) @@ -2259,7 +2412,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) @@ -2268,70 +2422,19 @@ void Spell::EffectPowerDrain(uint32 i)          if(Player *modOwner = m_caster->GetSpellModOwner())              modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_MULTIPLE_VALUE, manaMultiplier); -        int32 gain = int32(new_damage*manaMultiplier); +        int32 gain = int32(new_damage * manaMultiplier);          m_caster->ModifyPower(POWER_MANA,gain);          //send log -        m_caster->SendEnergizeSpellLog(m_caster, m_spellInfo->Id,gain,POWER_MANA); +        m_caster->SendEnergizeSpellLog(m_caster, m_spellInfo->Id, gain, POWER_MANA);      }  }  void Spell::EffectSendEvent(uint32 EffectIndex)  { -    if (m_caster->GetTypeId() == TYPEID_PLAYER && ((Player*)m_caster)->InBattleGround()) -    { -        BattleGround* bg = ((Player *)m_caster)->GetBattleGround(); -        if(bg && bg->GetStatus() == STATUS_IN_PROGRESS) -        { -            switch(m_spellInfo->Id) -            { -                case 23333:                                 // Pickup Horde Flag -                    /*do not uncomment . -                    if(bg->GetTypeID()==BATTLEGROUND_WS) -                        bg->EventPlayerClickedOnFlag((Player*)m_caster, gameObjTarget); -                    sLog.outDebug("Send Event Horde Flag Picked Up"); -                    break; -                    /* not used : -                    case 23334:                                 // Drop Horde Flag -                        if(bg->GetTypeID()==BATTLEGROUND_WS) -                            bg->EventPlayerDroppedFlag((Player*)m_caster); -                        sLog.outDebug("Drop Horde Flag"); -                        break; -                    */ -                case 23335:                                 // Pickup Alliance Flag -                    /*do not uncomment ... (it will cause crash, because of null targetobject!) anyway this is a bad way to call that event, because it would cause recursion -                    if(bg->GetTypeID()==BATTLEGROUND_WS) -                        bg->EventPlayerClickedOnFlag((Player*)m_caster, gameObjTarget); -                    sLog.outDebug("Send Event Alliance Flag Picked Up"); -                    break; -                    /* not used : -                    case 23336:                                 // Drop Alliance Flag -                        if(bg->GetTypeID()==BATTLEGROUND_WS) -                            bg->EventPlayerDroppedFlag((Player*)m_caster); -                        sLog.outDebug("Drop Alliance Flag"); -                        break; -                    case 23385:                                 // Alliance Flag Returns -                        if(bg->GetTypeID()==BATTLEGROUND_WS) -                            bg->EventPlayerClickedOnFlag((Player*)m_caster, gameObjTarget); -                        sLog.outDebug("Alliance Flag Returned"); -                        break; -                    case 23386:                                   // Horde Flag Returns -                        if(bg->GetTypeID()==BATTLEGROUND_WS) -                            bg->EventPlayerClickedOnFlag((Player*)m_caster, gameObjTarget); -                        sLog.outDebug("Horde Flag Returned"); -                        break;*/ -                case 34976: -                    /* -                    if(bg->GetTypeID()==BATTLEGROUND_EY) -                        bg->EventPlayerClickedOnFlag((Player*)m_caster, gameObjTarget); -                    */ -                    break; -                default: -                    sLog.outDebug("Unknown spellid %u in BG event", m_spellInfo->Id); -                    break; -            } -        } -    } +    /* +    we do not handle a flag dropping or clicking on flag in battleground by sendevent system +    */      sLog.outDebug("Spell ScriptStart %u for spellid %u in EffectSendEvent ", m_spellInfo->EffectMiscValue[EffectIndex], m_spellInfo->Id);      sWorld.ScriptsStart(sEventScripts, m_spellInfo->EffectMiscValue[EffectIndex], m_caster, focusObject);  } @@ -2352,16 +2455,26 @@ void Spell::EffectPowerBurn(uint32 i)      if(damage < 0)          return; +    Unit* caster = m_originalCaster ? m_originalCaster : m_caster; + +    // burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn) +    if(m_spellInfo->ManaCostPercentage) +    { +        uint32 maxdamage = m_caster->GetMaxPower(powertype) * damage * 2 / 100; +        damage = unitTarget->GetMaxPower(powertype) * damage / 100; +        if(damage > maxdamage) damage = maxdamage; +    } +      int32 curPower = int32(unitTarget->GetPower(powertype)); -    // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)      uint32 power = damage; +    // 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);      int32 new_damage = (curPower < power) ? curPower : power; -    unitTarget->ModifyPower(powertype,-new_damage); +    unitTarget->ModifyPower(powertype, -new_damage);      float multiplier = m_spellInfo->EffectMultipleValue[i];      if(Player *modOwner = m_caster->GetSpellModOwner()) @@ -2397,60 +2510,74 @@ void Spell::SpellDamageHeal(uint32 /*i*/)          {              // Amount of heal - depends from stacked Holy Energy              int damageAmount = 0; -            Unit::AuraList const& mDummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY); -            for(Unit::AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i) +            Unit::AuraEffectList const& mDummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY); +            for(Unit::AuraEffectList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)                  if((*i)->GetId() == 45062) -                    damageAmount+=(*i)->GetModifierValue(); +                    damageAmount+=(*i)->GetAmount();              if (damageAmount)                  m_caster->RemoveAurasDueToSpell(45062);              addhealth += damageAmount;          }          // Swiftmend - consumes Regrowth or Rejuvenation -        else if (m_spellInfo->TargetAuraState == AURA_STATE_SWIFTMEND && unitTarget->HasAuraState(AURA_STATE_SWIFTMEND)) +        else if (m_spellInfo->TargetAuraState == AURA_STATE_SWIFTMEND && unitTarget->HasAuraState(AURA_STATE_SWIFTMEND, m_spellInfo, m_caster))          { -            Unit::AuraList const& RejorRegr = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_HEAL); +            Unit::AuraEffectList const& RejorRegr = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_HEAL);              // find most short by duration -            Aura *targetAura = NULL; -            for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i) +            AuraEffect *targetAura = NULL; +            for(Unit::AuraEffectList::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()) +                    if(!targetAura || (*i)->GetParentAura()->GetAuraDuration() < targetAura->GetParentAura()->GetAuraDuration())                          targetAura = *i;                  }              }              if(!targetAura)              { -                sLog.outError("Target(GUID:" I64FMTD ") has aurastate AURA_STATE_SWIFTMEND but no matching aura.", unitTarget->GetGUID()); +                sLog.outError("Target(GUID:" UI64FMTD ") has aurastate AURA_STATE_SWIFTMEND but no matching aura.", unitTarget->GetGUID());                  return;              } -            int32 tickheal = targetAura->GetModifierValuePerStack(); +            int32 tickheal = targetAura->GetAmount();              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])                  {                      case 0x10:  tickcount = 4;  break; // Rejuvenation                      case 0x40:  tickcount = 6;  break; // Regrowth                  }              }              addhealth += tickheal * tickcount; -            unitTarget->RemoveAurasByCasterSpell(targetAura->GetId(), targetAura->GetCasterGUID()); + +            // Glyph of Swiftmend +            if(!caster->GetDummyAura(54824)) +                unitTarget->RemoveAura(targetAura->GetId(), targetAura->GetCasterGUID());              //addhealth += tickheal * tickcount;              //addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth,HEAL, unitTarget);          } +        // Riptide - increase healing done by Chain Heal +        else if (m_spellInfo->SpellFamilyName==SPELLFAMILY_SHAMAN && m_spellInfo->SpellFamilyFlags[0] & 0x100) +        { +            addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, addhealth, HEAL); +            if (AuraEffect * aurEff = unitTarget->GetAura(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_SHAMAN, 0, 0, 0x10, m_originalCasterGUID)) +            { +                addhealth *= 1.25f; +                // consume aura +                unitTarget->RemoveAura(aurEff->GetParentAura()); +            } +        }          else -            addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth,HEAL, unitTarget); +            addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, addhealth, HEAL);          m_damage -= addhealth;      } @@ -2468,14 +2595,11 @@ void Spell::EffectHealPct( uint32 /*i*/ )              return;          uint32 addhealth = unitTarget->GetMaxHealth() * damage / 100; -        caster->SendHealSpellLog(unitTarget, m_spellInfo->Id, addhealth, false); +        if(Player* modOwner = m_caster->GetSpellModOwner()) +            modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DAMAGE, addhealth, this); -        int32 gain = unitTarget->ModifyHealth( int32(addhealth) ); +        int32 gain = caster->DealHeal(unitTarget, addhealth, m_spellInfo);          unitTarget->getHostilRefManager().threatAssist(m_caster, float(gain) * 0.5f, m_spellInfo); - -        if(caster->GetTypeId()==TYPEID_PLAYER) -            if(BattleGround *bg = ((Player*)caster)->GetBattleGround()) -                bg->UpdatePlayerScore(((Player*)caster), SCORE_HEALING_DONE, gain);      }  } @@ -2491,9 +2615,8 @@ void Spell::EffectHealMechanical( uint32 /*i*/ )          if (!caster)              return; -        uint32 addhealth = caster->SpellHealingBonus(m_spellInfo, uint32(damage), HEAL, unitTarget); -        caster->SendHealSpellLog(unitTarget, m_spellInfo->Id, addhealth, false); -        unitTarget->ModifyHealth( int32(damage) ); +        uint32 addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, uint32(damage), HEAL); +        caster->DealHeal(unitTarget, addhealth, m_spellInfo);      }  } @@ -2516,18 +2639,14 @@ void Spell::EffectHealthLeech(uint32 i)      int32 new_damage = int32(damage*multiplier);      uint32 curHealth = unitTarget->GetHealth(); -    new_damage = m_caster->SpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, new_damage, m_IsTriggeredSpell, true); +    new_damage = m_caster->SpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, new_damage );      if(curHealth < new_damage)          new_damage = curHealth;      if(m_caster->isAlive())      { -        new_damage = m_caster->SpellHealingBonus(m_spellInfo, new_damage, HEAL, m_caster); - -        m_caster->ModifyHealth(new_damage); - -        if(m_caster->GetTypeId() == TYPEID_PLAYER) -            m_caster->SendHealSpellLog(m_caster, m_spellInfo->Id, uint32(new_damage)); +        new_damage = m_caster->SpellHealingBonus(m_caster, m_spellInfo, new_damage, HEAL); +        m_caster->DealHeal(m_caster, uint32(new_damage), m_spellInfo);      }  //    m_healthLeech+=tmpvalue;  //    m_damage+=new_damage; @@ -2557,7 +2676,7 @@ void Spell::DoCreateItem(uint32 i, uint32 itemtype)          /*int32 basePoints = m_currentBasePoints[i];          int32 randomPoints = m_spellInfo->EffectDieSides[i];          if (randomPoints) -            num_to_add = basePoints + m_caster->GetMap()->irand(1, randomPoints); +            num_to_add = basePoints + irand(1, randomPoints);          else              num_to_add = basePoints + 1;*/      } @@ -2575,8 +2694,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; @@ -2626,7 +2745,7 @@ void Spell::DoCreateItem(uint32 i, uint32 itemtype)          // set the "Crafted by ..." property of the item          if( pItem->GetProto()->Class != ITEM_CLASS_CONSUMABLE && pItem->GetProto()->Class != ITEM_CLASS_QUEST) -            pItem->SetUInt32Value(ITEM_FIELD_CREATOR,player->GetGUIDLow()); +            pItem->SetUInt32Value(ITEM_FIELD_CREATOR, player->GetGUIDLow());          // send info to the client          if(pItem) @@ -2634,7 +2753,7 @@ void Spell::DoCreateItem(uint32 i, uint32 itemtype)          // we succeeded in creating at least one item, so a levelup is possible          player->UpdateCraftSkill(m_spellInfo->Id); -    }        +    }  }  void Spell::EffectCreateItem(uint32 i) @@ -2642,9 +2761,37 @@ void Spell::EffectCreateItem(uint32 i)      DoCreateItem(i,m_spellInfo->EffectItemType[i]);  } +void Spell::EffectCreateItem2(uint32 i) +{ +    if(m_caster->GetTypeId()!=TYPEID_PLAYER) +        return; +    Player* player = (Player*)m_caster; + +    uint32 item_id = m_spellInfo->EffectItemType[i]; +    if(item_id) +        DoCreateItem(i, item_id); + +    // special case: fake item replaced by generate using spell_loot_template +    if(IsLootCraftingSpell(m_spellInfo)) +    { +        if(item_id) +        { +            if(!player->HasItemCount(item_id, 1)) +                return; + +            // remove reagent +            uint32 count = 1; +            player->DestroyItemCount(item_id, count, true); +        } + +        // create some random items +        player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); +    } +} +  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); @@ -2672,6 +2819,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; @@ -2699,11 +2848,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; @@ -2747,7 +2903,7 @@ void Spell::EffectEnergize(uint32 i)          if (!elixirs.empty())          {              // cast random elixir on target -          uint32 rand_spell = m_caster->GetMap()->urand(0,elixirs.size()-1); +            uint32 rand_spell = urand(0,elixirs.size()-1);              m_caster->CastSpell(unitTarget,elixirs[rand_spell],true,m_CastItem);          }      } @@ -2771,7 +2927,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) @@ -2811,6 +2967,7 @@ void Spell::SendLoot(uint64 guid, LootType loottype)                  {                      sLog.outDebug("Goober ScriptStart id %u for GO %u", gameObjTarget->GetGOInfo()->goober.eventId,gameObjTarget->GetDBTableGUIDLow());                      sWorld.ScriptsStart(sEventScripts, gameObjTarget->GetGOInfo()->goober.eventId, player, gameObjTarget); +                    gameObjTarget->EventInform(gameObjTarget->GetGOInfo()->goober.eventId);                  }                  // cast goober spell @@ -2850,6 +3007,8 @@ void Spell::SendLoot(uint64 guid, LootType loottype)                      gameObjTarget->TriggeringLinkedGameObject(trapEntry,m_caster);                  // Don't return, let loots been taken +            default: +                break;          }      } @@ -2857,7 +3016,7 @@ void Spell::SendLoot(uint64 guid, LootType loottype)      player->SendLoot(guid, loottype);  } -void Spell::EffectOpenLock(uint32 /*i*/) +void Spell::EffectOpenLock(uint32 effIndex)  {      if(!m_caster || m_caster->GetTypeId() != TYPEID_PLAYER)      { @@ -2867,7 +3026,6 @@ void Spell::EffectOpenLock(uint32 /*i*/)      Player* player = (Player*)m_caster; -    LootType loottype = LOOT_CORPSE;      uint32 lockId = 0;      uint64 guid = 0; @@ -2879,7 +3037,7 @@ void Spell::EffectOpenLock(uint32 /*i*/)          if( goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune ||              goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK )          { -            //isAllowUseBattleGroundObject() already called in CanCast() +            //CanUseBattleGroundObject() already called in CheckCast()              // in battleground check              if(BattleGround *bg = player->GetBattleGround())              { @@ -2891,7 +3049,7 @@ void Spell::EffectOpenLock(uint32 /*i*/)          }          else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)          { -            //isAllowUseBattleGroundObject() already called in CanCast() +            //CanUseBattleGroundObject() already called in CheckCast()              // in battleground check              if(BattleGround *bg = player->GetBattleGround())              { @@ -2918,93 +3076,39 @@ void Spell::EffectOpenLock(uint32 /*i*/)          return;      } -    if(!lockId)                                             // possible case for GO and maybe for items. -    { -        SendLoot(guid, loottype); -        return; -    } - -    // Get LockInfo -    LockEntry const *lockInfo = sLockStore.LookupEntry(lockId); +    SkillType skillId = SKILL_NONE; +    int32 reqSkillValue = 0; +    int32 skillValue; -    if (!lockInfo) +    SpellCastResult res = CanOpenLock(effIndex, lockId, skillId, reqSkillValue, skillValue); +    if(res != SPELL_CAST_OK)      { -        sLog.outError( "Spell::EffectOpenLock: %s [guid = %u] has an unknown lockId: %u!", -            (gameObjTarget ? "gameobject" : "item"), GUID_LOPART(guid), lockId); -        SendCastResult(SPELL_FAILED_BAD_TARGETS); +        SendCastResult(res);          return;      } -    // check key -    for(int i = 0; i < 5; ++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]) -        { -            SendLoot(guid, loottype); -            return; -        } -    } - -    uint32 SkillId = 0; -    // Check and skill-up skill -    if( m_spellInfo->Effect[1] == SPELL_EFFECT_SKILL ) -        SkillId = m_spellInfo->EffectMiscValue[1]; -                                                            // pickpocketing spells -    else if( m_spellInfo->EffectMiscValue[0] == LOCKTYPE_PICKLOCK ) -        SkillId = SKILL_LOCKPICKING; - -    // skill bonus provided by casting spell (mostly item spells) -    uint32 spellSkillBonus = uint32(damage/*m_currentBasePoints[0]+1*/); - -    uint32 reqSkillValue = lockInfo->requiredminingskill; - -    if(lockInfo->requiredlockskill)                         // required pick lock skill applying -    { -        if(SkillId != SKILL_LOCKPICKING)                    // wrong skill (cheating?) -        { -            SendCastResult(SPELL_FAILED_FIZZLE); -            return; -        } +    SendLoot(guid, LOOT_SKINNING); -        reqSkillValue = lockInfo->requiredlockskill; -    } -    else if(SkillId == SKILL_LOCKPICKING)                   // apply picklock skill to wrong target +    // not allow use skill grow at item base open +    if(!m_CastItem && skillId != SKILL_NONE)      { -        SendCastResult(SPELL_FAILED_BAD_TARGETS); -        return; -    } - -    if ( SkillId ) -    { -        loottype = LOOT_SKINNING; -        if ( player->GetSkillValue(SkillId) + spellSkillBonus < reqSkillValue ) -        { -            SendCastResult(SPELL_FAILED_LOW_CASTLEVEL); -            return; -        } -          // update skill if really known -        uint32 SkillValue = player->GetPureSkillValue(SkillId); -        if(SkillValue)                                      // non only item base skill +        if(uint32 pureSkillValue = player->GetPureSkillValue(skillId))          {              if(gameObjTarget)              {                  // Allow one skill-up until respawned                  if ( !gameObjTarget->IsInSkillupList( player->GetGUIDLow() ) && -                    player->UpdateGatherSkill(SkillId, SkillValue, reqSkillValue) ) +                    player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue) )                      gameObjTarget->AddToSkillupList( player->GetGUIDLow() );              }              else if(itemTarget)              {                  // Do one skill-up -                uint32 SkillValue = player->GetPureSkillValue(SkillId); -                player->UpdateGatherSkill(SkillId, SkillValue, reqSkillValue); +                player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);              }          }      } - -    SendLoot(guid, loottype);  }  void Spell::EffectSummonChangeItem(uint32 i) @@ -3032,10 +3136,10 @@ void Spell::EffectSummonChangeItem(uint32 i)      if( !pNewItem )          return; -    for(uint8 i= PERM_ENCHANTMENT_SLOT; i<=TEMP_ENCHANTMENT_SLOT; ++i) +    for(uint8 j= PERM_ENCHANTMENT_SLOT; j<=TEMP_ENCHANTMENT_SLOT; ++j)      { -        if(m_CastItem->GetEnchantmentId(EnchantmentSlot(i))) -            pNewItem->SetEnchantment(EnchantmentSlot(i), m_CastItem->GetEnchantmentId(EnchantmentSlot(i)), m_CastItem->GetEnchantmentDuration(EnchantmentSlot(i)), m_CastItem->GetEnchantmentCharges(EnchantmentSlot(i))); +        if(m_CastItem->GetEnchantmentId(EnchantmentSlot(j))) +            pNewItem->SetEnchantment(EnchantmentSlot(j), m_CastItem->GetEnchantmentId(EnchantmentSlot(j)), m_CastItem->GetEnchantmentDuration(EnchantmentSlot(j)), m_CastItem->GetEnchantmentCharges(EnchantmentSlot(j)));      }      if(m_CastItem->GetUInt32Value(ITEM_FIELD_DURABILITY) < m_CastItem->GetUInt32Value(ITEM_FIELD_MAXDURABILITY)) @@ -3050,7 +3154,7 @@ void Spell::EffectSummonChangeItem(uint32 i)          uint8 msg = player->CanStoreItem( m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true );          if( msg == EQUIP_ERR_OK )          { -            player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(),true); +            player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);              // prevent crash at access and unexpected charges counting with item update queue corrupt              if(m_CastItem==m_targets.getItemTarget()) @@ -3068,7 +3172,7 @@ void Spell::EffectSummonChangeItem(uint32 i)          uint8 msg = player->CanBankItem( m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true );          if( msg == EQUIP_ERR_OK )          { -            player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(),true); +            player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);              // prevent crash at access and unexpected charges counting with item update queue corrupt              if(m_CastItem==m_targets.getItemTarget()) @@ -3086,7 +3190,7 @@ void Spell::EffectSummonChangeItem(uint32 i)          uint8 msg = player->CanEquipItem( m_CastItem->GetSlot(), dest, pNewItem, true );          if( msg == EQUIP_ERR_OK )          { -            player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(),true); +            player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);              // prevent crash at access and unexpected charges counting with item update queue corrupt              if(m_CastItem==m_targets.getItemTarget()) @@ -3116,114 +3220,182 @@ void Spell::EffectProficiency(uint32 /*i*/)      Player *p_target = (Player*)unitTarget;      uint32 subClassMask = m_spellInfo->EquippedItemSubClassMask; -    if(m_spellInfo->EquippedItemClass == 2 && !(p_target->GetWeaponProficiency() & subClassMask)) +    if(m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask))      {          p_target->AddWeaponProficiency(subClassMask); -        p_target->SendProficiency(uint8(0x02),p_target->GetWeaponProficiency()); +        p_target->SendProficiency(ITEM_CLASS_WEAPON, p_target->GetWeaponProficiency());      } -    if(m_spellInfo->EquippedItemClass == 4 && !(p_target->GetArmorProficiency() & subClassMask)) +    if(m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & subClassMask))      {          p_target->AddArmorProficiency(subClassMask); -        p_target->SendProficiency(uint8(0x04),p_target->GetArmorProficiency()); +        p_target->SendProficiency(ITEM_CLASS_ARMOR, p_target->GetArmorProficiency());      }  } -void Spell::EffectApplyAreaAura(uint32 i) +void Spell::EffectSummonType(uint32 i)  { -    if(!unitTarget) -        return; -    if(!unitTarget->isAlive()) +    uint32 entry = m_spellInfo->EffectMiscValue[i]; +    if(!entry)          return; -    AreaAura* Aur = new AreaAura(m_spellInfo, i, &damage, unitTarget, m_caster, m_CastItem); -    unitTarget->AddAura(Aur); -} - -void Spell::EffectSummonType(uint32 i) -{ -    switch(m_spellInfo->EffectMiscValueB[i]) +    SummonPropertiesEntry const *properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->EffectMiscValueB[i]); +    if(!properties)      { -        case SUMMON_TYPE_GUARDIAN: -            EffectSummonGuardian(i); -            break; -        case SUMMON_TYPE_POSESSED: -        case SUMMON_TYPE_POSESSED2: -        case SUMMON_TYPE_POSESSED3: -            EffectSummonPossessed(i); -            break; -        case SUMMON_TYPE_WILD: -            EffectSummonWild(i); -            break; -        case SUMMON_TYPE_DEMON: -            EffectSummonDemon(i); -            break; -        case SUMMON_TYPE_SUMMON: -            EffectSummon(i); -            break; -        case SUMMON_TYPE_CRITTER: -        case SUMMON_TYPE_CRITTER2: -        case SUMMON_TYPE_CRITTER3: -            EffectSummonCritter(i); -            break; -        case SUMMON_TYPE_TOTEM_SLOT1: -        case SUMMON_TYPE_TOTEM_SLOT2: -        case SUMMON_TYPE_TOTEM_SLOT3: -        case SUMMON_TYPE_TOTEM_SLOT4: -        case SUMMON_TYPE_TOTEM: -            EffectSummonTotem(i); -            break; -        case SUMMON_TYPE_UNKNOWN1: -        case SUMMON_TYPE_UNKNOWN3: -        case SUMMON_TYPE_UNKNOWN4: -        case SUMMON_TYPE_UNKNOWN5: -            break; -        default: -            sLog.outError("EffectSummonType: Unhandled summon type %u", m_spellInfo->EffectMiscValueB[i]); -            break; +        sLog.outError("EffectSummonType: Unhandled summon type %u", m_spellInfo->EffectMiscValueB[i]); +        return;      } -} -void Spell::EffectSummon(uint32 i) -{ -    uint32 pet_entry = m_spellInfo->EffectMiscValue[i]; -    if(!pet_entry) +    if(!m_originalCaster)          return; -    if(!m_originalCaster || m_originalCaster->GetTypeId() != TYPEID_PLAYER) -    { -        EffectSummonWild(i); -        return; -    } +    int32 duration = GetSpellDuration(m_spellInfo); +    if(Player* modOwner = m_originalCaster->GetSpellModOwner()) +        modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration); -    Player *owner = (Player*)m_originalCaster; +    float x, y, z; +    GetSummonPosition(i, x, y, z); -    if(owner->GetPetGUID()) -        return; +    /*//totem must be at same Z in case swimming caster and etc. +        if( fabs( z - m_caster->GetPositionZ() ) > 5 ) +            z = m_caster->GetPositionZ(); -    // Summon in dest location -    float x,y,z; -    if(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) +    uint32 level = m_caster->getLevel(); + +    // level of creature summoned using engineering item based at engineering skill level +    if(m_caster->GetTypeId()==TYPEID_PLAYER && m_CastItem)      { -        x = m_targets.m_destX; -        y = m_targets.m_destY; -        z = m_targets.m_destZ; -    } -    else -        m_caster->GetClosePoint(x,y,z,owner->GetObjectSize()); +        ItemPrototype const *proto = m_CastItem->GetProto(); +        if(proto && proto->RequiredSkill == SKILL_ENGINERING) +        { +            uint16 skill202 = ((Player*)m_caster)->GetSkillValue(SKILL_ENGINERING); +            if(skill202) +            { +                level = skill202/5; +            } +        } +    }*/ -    Pet *spawnCreature = owner->SummonPet(pet_entry, x, y, z, m_caster->GetOrientation(), SUMMON_PET, GetSpellDuration(m_spellInfo)); -    if(!spawnCreature) -        return; +    TempSummon *summon = NULL; -    spawnCreature->SetUInt32Value(UNIT_NPC_FLAGS, 0); -    spawnCreature->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, 0); -    spawnCreature->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); +    switch(properties->Category) +    { +        default: +            switch(properties->Type) +            { +                case SUMMON_TYPE_PET: +                case SUMMON_TYPE_GUARDIAN: +                case SUMMON_TYPE_MINION: +                    SummonGuardian(entry, properties); +                    break; +                case SUMMON_TYPE_VEHICLE: +                case SUMMON_TYPE_VEHICLE2: +                { +                    Vehicle *vehicle = m_caster->SummonVehicle(entry, x, y, z, m_caster->GetOrientation()); +                    if(!vehicle) +                        return; -    std::string name = owner->GetName(); -    name.append(petTypeSuffix[spawnCreature->getPetType()]); -    spawnCreature->SetName( name ); +                    //vehicle->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, m_caster->GetGUID()); +                    vehicle->setFaction(m_caster->getFaction()); +                    vehicle->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); +                    break; +                } +                case SUMMON_TYPE_TOTEM: +                { +                    summon = m_caster->GetMap()->SummonCreature(entry, x, y, z, m_caster->GetOrientation(), properties, duration, m_originalCaster); +                    if(!summon || !summon->isTotem()) +                        return; + +                    if(damage)                                             // if not spell info, DB values used +                    { +                        summon->SetMaxHealth(damage); +                        summon->SetHealth(damage); +                    } + +                    //summon->SetUInt32Value(UNIT_CREATED_BY_SPELL,m_spellInfo->Id); + +                    if(m_originalCaster->GetTypeId() == TYPEID_PLAYER +                        && properties->Slot >= SUMMON_SLOT_TOTEM +                        && properties->Slot < MAX_TOTEM_SLOT) +                    { +                        //summon->SendUpdateToPlayer((Player*)m_originalCaster); +                        WorldPacket data(SMSG_TOTEM_CREATED, 1+8+4+4); +                        data << uint8(properties->Slot-1); +                        data << uint64(m_originalCaster->GetGUID()); +                        data << uint32(duration); +                        data << uint32(m_spellInfo->Id); +                        ((Player*)m_originalCaster)->SendDirectMessage(&data); +                    } +                    break; +                } +                case SUMMON_TYPE_MINIPET: +                { +                    summon = m_caster->GetMap()->SummonCreature(entry, x, y, z, m_caster->GetOrientation(), properties, duration, m_originalCaster); +                    if(!summon || !summon->HasSummonMask(SUMMON_MASK_MINION)) +                        return; + +                    //summon->InitPetCreateSpells();                         // e.g. disgusting oozeling has a create spell as summon... +                    summon->SelectLevel(summon->GetCreatureInfo());       // some summoned creaters have different from 1 DB data for level/hp +                    summon->SetUInt32Value(UNIT_NPC_FLAGS, summon->GetCreatureInfo()->npcflag); + +                    summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + +                    summon->AI()->EnterEvadeMode(); + +                    std::string name = m_originalCaster->GetName(); +                    name.append(petTypeSuffix[3]); +                    summon->SetName( name ); +                    break; +                } +                default: +                { +                    float radius = GetSpellRadiusForHostile(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); + +                    int32 amount = damage > 0 ? damage : 1; + +                    for(int32 count = 0; count < amount; ++count) +                    { +                        float px, py, pz; +                        GetSummonPosition(i, px, py, pz, radius, count); + +                        TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN; -    spawnCreature->SetReactState( REACT_DEFENSIVE ); +                        m_originalCaster->SummonCreature(entry,px,py,pz,m_caster->GetOrientation(),summonType,duration); +                    } +                    break; +                } +            }//switch +            break; +        case SUMMON_CATEGORY_PET: +            SummonGuardian(entry, properties); +            break; +        case SUMMON_CATEGORY_PUPPET: +            summon = m_caster->GetMap()->SummonCreature(entry, x, y, z, m_caster->GetOrientation(), properties, duration, m_originalCaster); +            break; +        case SUMMON_CATEGORY_VEHICLE: +        { +            float x, y, z; +            m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE); +            Vehicle *vehicle = m_caster->SummonVehicle(entry, x, y, z, m_caster->GetOrientation()); +            if(!vehicle) +                return; + +            vehicle->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, m_caster->GetGUID()); +            vehicle->setFaction(m_caster->getFaction()); +            vehicle->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); + +            if(damage) +            { +                m_caster->CastSpell(vehicle, damage, true); +                m_caster->EnterVehicle(vehicle); +            } +            break; +        } +    } + +    if(summon) +    { +        summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); +    }  }  void Spell::EffectLearnSpell(uint32 i) @@ -3241,8 +3413,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() );  } @@ -3252,8 +3424,7 @@ void Spell::EffectDispel(uint32 i)      if(!unitTarget)          return; -    // Fill possible dispel list -    std::vector <Aura *> dispel_list; +    std::list < Aura * > dispel_list;      // Create dispel mask by dispel type      uint32 dispel_type = m_spellInfo->EffectMiscValue[i]; @@ -3262,7 +3433,7 @@ void Spell::EffectDispel(uint32 i)      for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)      {          Aura *aur = (*itr).second; -        if (aur && (1<<aur->GetSpellProto()->Dispel) & dispelMask) +        if (aur && ((1<<aur->GetSpellProto()->Dispel) & dispelMask))          {              if(aur->GetSpellProto()->Dispel == DISPEL_MAGIC)              { @@ -3277,80 +3448,67 @@ void Spell::EffectDispel(uint32 i)                  if(positive == unitTarget->IsFriendlyTo(m_caster))                      continue;              } -            // Add every aura stack to dispel list -            for(uint32 stack_amount = 0; stack_amount < aur->GetStackAmount(); ++stack_amount) +            for (uint8 i = aur->GetStackAmount();i!=0;--i)                  dispel_list.push_back(aur);          }      }      // Ok if exist some buffs for dispel try dispel it -    if (!dispel_list.empty()) +    if (uint32 list_size = dispel_list.size())      { -        std::list < std::pair<uint32,uint64> > success_list;// (spell_id,casterGuid) -        std::list < uint32 > fail_list;                     // spell_id -        int32 list_size = dispel_list.size(); +        uint32 failCount = 0; +        std::list < Aura * > success_list; +        WorldPacket dataFail(SMSG_DISPEL_FAILED, 8+8+4+4+damage*4);          // dispel N = damage buffs (or while exist buffs for dispel) -        for (int32 count=0; count < damage && list_size > 0; ++count) +        for (int32 count=0; count < damage && list_size > 0; ++count, list_size = dispel_list.size())          {              // Random select buff for dispel -          Aura *aur = dispel_list[m_caster->GetMap()->urand(0, list_size-1)]; - -            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()) +            std::list < Aura * > ::iterator itr = dispel_list.begin(); +            for (uint32 i=urand(0, list_size-1);i>0;--i) +                 itr++; + +            if (GetDispelChance((*itr)->GetCaster(), (*itr)->GetId()))              { -                if ( Player* modOwner = caster->GetSpellModOwner() ) -                    modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_RESIST_DISPEL_CHANCE, miss_chance, this); +                success_list.push_back(*itr); +                dispel_list.erase(itr);              } -            // Try dispel -            if (roll_chance_i(miss_chance)) -                fail_list.push_back(aur->GetId());              else -                success_list.push_back(std::pair<uint32,uint64>(aur->GetId(),aur->GetCasterGUID())); -            // Remove buff from list for prevent doubles -            for (std::vector<Aura *>::iterator j = dispel_list.begin(); j != dispel_list.end(); )              { -                Aura *dispelled = *j; -                if (dispelled->GetId() == aur->GetId() && dispelled->GetCasterGUID() == aur->GetCasterGUID()) +                if (!failCount)                  { -                    j = dispel_list.erase(j); -                    --list_size; -                    break; +                    // Failed to dispell +                    dataFail << uint64(m_caster->GetGUID());            // Caster GUID +                    dataFail << uint64(unitTarget->GetGUID());          // Victim GUID +                    dataFail << uint32(m_spellInfo->Id);                // dispel spell id                  } -                else -                    ++j; +                failCount++; +                dataFail << uint32((*itr)->GetId());                         // Spell Id              }          } -        // Send success log and really remove auras -        if (!success_list.empty()) +        if (failCount)          { -            int32 count = success_list.size(); -            WorldPacket data(SMSG_SPELLDISPELLOG, 8+8+4+1+4+count*5); -            data.append(unitTarget->GetPackGUID());         // Victim GUID -            data.append(m_caster->GetPackGUID());           // Caster GUID -            data << uint32(m_spellInfo->Id);                // dispel spell id -            data << uint8(0);                               // not used -            data << uint32(count);                          // count -            for (std::list<std::pair<uint32,uint64> >::iterator j = success_list.begin(); j != success_list.end(); ++j) +            m_caster->SendMessageToSet(&dataFail, true); +        } +        if (success_list.size()) +        { +            WorldPacket dataSuccess(SMSG_SPELLDISPELLOG, 8+8+4+1+4+damage*5); +            // Send packet header +            dataSuccess.append(unitTarget->GetPackGUID());         // Victim GUID +            dataSuccess.append(m_caster->GetPackGUID());           // Caster GUID +            dataSuccess << uint32(m_spellInfo->Id);                // dispel spell id +            dataSuccess << uint8(0);                               // not used +            dataSuccess << uint32(success_list.size());            // count +            for (std::list < Aura * > ::iterator itr = success_list.begin();itr!=success_list.end();++itr)              { -                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 -                unitTarget->RemoveAurasDueToSpellByDispel(spellInfo->Id, j->second, m_caster); -             } -            m_caster->SendMessageToSet(&data, true); +                // Send dispelled spell info +                dataSuccess << uint32((*itr)->GetId());         // Spell Id +                dataSuccess << uint8(0);                           // 0 - dispelled !=0 cleansed +                unitTarget->RemoveAurasDueToSpellByDispel((*itr)->GetId(), (*itr)->GetCasterGUID(), m_caster); +            } +            m_caster->SendMessageToSet(&dataSuccess, 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) @@ -3361,6 +3519,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; @@ -3369,18 +3528,6 @@ void Spell::EffectDispel(uint32 i)                      m_caster->CastSpell(m_caster, heal_spell, true);              }          } -        // Send fail log to client -        if (!fail_list.empty()) -        { -            // Failed to dispell -            WorldPacket data(SMSG_DISPEL_FAILED, 8+8+4+4*fail_list.size()); -            data << uint64(m_caster->GetGUID());            // Caster GUID -            data << uint64(unitTarget->GetGUID());          // Victim GUID -            data << uint32(m_spellInfo->Id);                // dispel spell id -            for (std::list< uint32 >::iterator j = fail_list.begin(); j != fail_list.end(); ++j) -                data << uint32(*j);                         // Spell Id -            m_caster->SendMessageToSet(&data, true); -        }      }  } @@ -3422,7 +3569,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);      }  } @@ -3440,7 +3587,7 @@ void Spell::EffectPickPocket(uint32 /*i*/)      {          int32 chance = 10 + int32(m_caster->getLevel()) - int32(unitTarget->getLevel()); -        if (chance > m_caster->GetMap()->irand(0, 19)) +        if (chance > irand(0, 19))          {              // Stealing successful              //sLog.outDebug("Sending loot from pickpocket"); @@ -3450,8 +3597,7 @@ void Spell::EffectPickPocket(uint32 /*i*/)          {              // Reveal action + get attack              m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TALK); -            if (((Creature*)unitTarget)->IsAIEnabled) -                ((Creature*)unitTarget)->AI()->AttackStart(m_caster); +            m_caster->CombatStart(unitTarget);          }      }  } @@ -3461,7 +3607,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)) @@ -3477,190 +3623,8 @@ void Spell::EffectAddFarsight(uint32 i)      dynObj->GetMap()->Add(dynObj); //grid will also be loaded      // Need to update visibility of object for client to accept farsight guid +    ((Player*)m_caster)->SetViewpoint(dynObj, true);      ((Player*)m_caster)->UpdateVisibilityOf(dynObj); -    ((Player*)m_caster)->SetFarsightTarget(dynObj); -} - -void Spell::EffectSummonWild(uint32 i) -{ -    uint32 creature_entry = m_spellInfo->EffectMiscValue[i]; -    if(!creature_entry) -        return; - -    uint32 level = m_caster->getLevel(); - -    // level of creature summoned using engineering item based at engineering skill level -    if(m_caster->GetTypeId()==TYPEID_PLAYER && m_CastItem) -    { -        ItemPrototype const *proto = m_CastItem->GetProto(); -        if(proto && proto->RequiredSkill == SKILL_ENGINERING) -        { -            uint16 skill202 = ((Player*)m_caster)->GetSkillValue(SKILL_ENGINERING); -            if(skill202) -            { -                level = skill202/5; -            } -        } -    } - -    // select center of summon position -    float center_x = m_targets.m_destX; -    float center_y = m_targets.m_destY; -    float center_z = m_targets.m_destZ; - -    float radius = GetSpellRadius(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) -        { -            // Summon 1 unit in dest location -            if (count == 0) -            { -                px = m_targets.m_destX; -                py = m_targets.m_destY; -                pz = m_targets.m_destZ; -            } -            // Summon in random point all other units if location present -            else -                m_caster->GetRandomPoint(center_x,center_y,center_z,radius,px,py,pz); -        } -        // Summon if dest location not present near caster -        else -            m_caster->GetClosePoint(px,py,pz,3.0f); - -        int32 duration = GetSpellDuration(m_spellInfo); - -        TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN; - -        if(m_originalCaster) -            m_originalCaster->SummonCreature(creature_entry,px,py,pz,m_caster->GetOrientation(),summonType,duration); -        else -            m_caster->SummonCreature(creature_entry,px,py,pz,m_caster->GetOrientation(),summonType,duration); -    } -} - -void Spell::EffectSummonGuardian(uint32 i) -{ -    uint32 pet_entry = m_spellInfo->EffectMiscValue[i]; -    if(!pet_entry) -        return; - -    // Jewelery statue case (totem like) -    if(m_spellInfo->SpellIconID==2056) -    { -        EffectSummonTotem(i); -        return; -    } - -    Player *caster = NULL; -    if(m_originalCaster) -    { -        if(m_originalCaster->GetTypeId() == TYPEID_PLAYER) -            caster = (Player*)m_originalCaster; -        else if(((Creature*)m_originalCaster)->isTotem()) -            caster = m_originalCaster->GetCharmerOrOwnerPlayerOrPlayerItself(); -    } - -    if(!caster) -    { -        EffectSummonWild(i); -        return; -    } - -    // set timer for unsummon -    int32 duration = GetSpellDuration(m_spellInfo); - -    // Search old Guardian only for players (if casted spell not have duration or cooldown) -    // FIXME: some guardians have control spell applied and controlled by player and anyway player can't summon in this time -    //        so this code hack in fact -    if(duration <= 0 || GetSpellRecoveryTime(m_spellInfo)==0) -        if(caster->HasGuardianWithEntry(pet_entry)) -            return;                                         // find old guardian, ignore summon - -    // in another case summon new -    uint32 level = caster->getLevel(); - -    // level of pet summoned using engineering item based at engineering skill level -    if(m_CastItem) -    { -        ItemPrototype const *proto = m_CastItem->GetProto(); -        if(proto && proto->RequiredSkill == SKILL_ENGINERING) -        { -            uint16 skill202 = caster->GetSkillValue(SKILL_ENGINERING); -            if(skill202) -            { -                level = skill202/5; -            } -        } -    } - -    // select center of summon position -    float center_x = m_targets.m_destX; -    float center_y = m_targets.m_destY; -    float center_z = m_targets.m_destZ; - -    float radius = GetSpellRadius(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) -        { -            // Summon 1 unit in dest location -            if (count == 0) -            { -                px = m_targets.m_destX; -                py = m_targets.m_destY; -                pz = m_targets.m_destZ; -            } -            // Summon in random point all other units if location present -            else -                m_caster->GetRandomPoint(center_x,center_y,center_z,radius,px,py,pz); -        } -        // Summon if dest location not present near caster -        else -            m_caster->GetClosePoint(px,py,pz,m_caster->GetObjectSize()); - -        Pet *spawnCreature = caster->SummonPet(m_spellInfo->EffectMiscValue[i], px, py, pz, m_caster->GetOrientation(), GUARDIAN_PET, duration); -        if(!spawnCreature) -            return; - -        spawnCreature->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP,0); -        spawnCreature->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); -        spawnCreature->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE); -    } -} - -void Spell::EffectSummonPossessed(uint32 i) -{ -    uint32 entry = m_spellInfo->EffectMiscValue[i]; -    if(!entry) -        return; - -    if(m_caster->GetTypeId() != TYPEID_PLAYER) -        return; - -    uint32 level = m_caster->getLevel(); - -    float x, y, z; -    m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE); - -    int32 duration = GetSpellDuration(m_spellInfo); - -    Pet* pet = ((Player*)m_caster)->SummonPet(entry, x, y, z, m_caster->GetOrientation(), POSSESSED_PET, duration); -    if(!pet) -        return; - -    pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); -    pet->SetCharmedOrPossessedBy(m_caster, true);  }  void Spell::EffectTeleUnitsFaceCaster(uint32 i) @@ -3671,16 +3635,12 @@ void Spell::EffectTeleUnitsFaceCaster(uint32 i)      if(unitTarget->isInFlight())          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); -    if(unitTarget->GetTypeId() == TYPEID_PLAYER) -        ((Player*)unitTarget)->TeleportTo(mapid, fx, fy, fz, -m_caster->GetOrientation(), TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (unitTarget==m_caster ? TELE_TO_SPELL : 0)); -    else -        m_caster->GetMap()->CreatureRelocation((Creature*)m_caster, fx, fy, fz, -m_caster->GetOrientation()); +    unitTarget->NearTeleportTo(fx,fy,fz,-m_caster->GetOrientation(),unitTarget==m_caster);  }  void Spell::EffectLearnSkill(uint32 i) @@ -3701,13 +3661,27 @@ void Spell::EffectAddHonor(uint32 /*i*/)      if(unitTarget->GetTypeId() != TYPEID_PLAYER)          return; -    sLog.outDebug("SpellEffect::AddHonor called for spell_id %u , that rewards %d honor points to player: %u", m_spellInfo->Id, damage, ((Player*)unitTarget)->GetGUIDLow()); - -    // TODO: find formula for honor reward based on player's level! +    // not scale value for item based reward (/10 value expected) +    if(m_CastItem) +    { +        ((Player*)unitTarget)->RewardHonor(NULL, 1, damage/10); +        sLog.outError("SpellEffect::AddHonor (spell_id %u) rewards %d honor points (item %u) for player: %u", m_spellInfo->Id, damage/10, m_CastItem->GetEntry(),((Player*)unitTarget)->GetGUIDLow()); +        return; +    } -    // now fixed only for level 70 players: -    if (((Player*)unitTarget)->getLevel() == 70) +    // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80 +    if( damage <= 50) +    { +        uint32 honor_reward = MaNGOS::Honor::hk_honor_at_level(unitTarget->getLevel(), damage); +        ((Player*)unitTarget)->RewardHonor(NULL, 1, honor_reward); +        sLog.outDebug("SpellEffect::AddHonor (spell_id %u) rewards %u honor points (scale) to player: %u", m_spellInfo->Id, honor_reward, ((Player*)unitTarget)->GetGUIDLow()); +    } +    else +    { +        //maybe we have correct honor_gain in damage already          ((Player*)unitTarget)->RewardHonor(NULL, 1, damage); +        sLog.outError("SpellEffect::AddHonor (spell_id %u) rewards %u honor points (non scale) for player: %u", m_spellInfo->Id, damage, ((Player*)unitTarget)->GetGUIDLow()); +    }  }  void Spell::EffectTradeSkill(uint32 /*i*/) @@ -3719,7 +3693,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; @@ -3728,11 +3702,27 @@ void Spell::EffectEnchantItemPerm(uint32 i)      Player* p_caster = (Player*)m_caster; -    p_caster->UpdateCraftSkill(m_spellInfo->Id); - -    if (m_spellInfo->EffectMiscValue[i]) +    // Handle vellums +    if (itemTarget->IsWeaponVellum() || itemTarget->IsArmorVellum())      { -        uint32 enchant_id = m_spellInfo->EffectMiscValue[i]; +        // destroy one vellum from stack +        uint32 count=1; +        p_caster->DestroyItemCount(itemTarget,count,true); +        unitTarget=p_caster; +        // and add a scroll +        DoCreateItem(effect_idx,m_spellInfo->EffectItemType[effect_idx]); +        itemTarget=NULL; +        m_targets.setItemTarget(NULL); +    } +    else +    { +        // do not increase skill if vellum used +        if (!(m_CastItem && m_CastItem->GetProto()->Flags & ITEM_FLAGS_TRIGGERED_CAST)) +            p_caster->UpdateCraftSkill(m_spellInfo->Id); + +        uint32 enchant_id = m_spellInfo->EffectMiscValue[effect_idx]; +        if (!enchant_id) +            return;          SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);          if(!pEnchant) @@ -3761,6 +3751,64 @@ void Spell::EffectEnchantItemPerm(uint32 i)      }  } +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) +        { +            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; +        } +    } + +    // 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) ) +    { +        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)  {      if(m_caster->GetTypeId() != TYPEID_PLAYER) @@ -3844,26 +3892,26 @@ void Spell::EffectEnchantItemTmp(uint32 i)      uint32 duration;      // rogue family enchantments exception by duration -    if(m_spellInfo->Id==38615) +    if(m_spellInfo->Id == 38615)          duration = 1800;                                    // 30 mins      // other rogue family enchantments always 1 hour (some have spell damage=0, but some have wrong data in EffBasePoints) -    else if(m_spellInfo->SpellFamilyName==SPELLFAMILY_ROGUE) +    else if(m_spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE)          duration = 3600;                                    // 1 hour      // shaman family enchantments -    else if(m_spellInfo->SpellFamilyName==SPELLFAMILY_SHAMAN) +    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) +    else if(m_spellInfo->Id == 29702)          duration = 300;                                     // 5 mins -    else if(m_spellInfo->Id==37360) +    else if(m_spellInfo->Id == 37360)          duration = 300;                                     // 5 mins      // default case      else @@ -3877,18 +3925,18 @@ void Spell::EffectEnchantItemTmp(uint32 i)      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(temp): %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()); +            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,TEMP_ENCHANTMENT_SLOT,false); +    item_owner->ApplyEnchantment(itemTarget,TEMP_ENCHANTMENT_SLOT, false); -    itemTarget->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, duration*1000, 0); +    itemTarget->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, duration * 1000, 0);      // add new enchanting if equipped -    item_owner->ApplyEnchantment(itemTarget,TEMP_ENCHANTMENT_SLOT,true); +    item_owner->ApplyEnchantment(itemTarget, TEMP_ENCHANTMENT_SLOT, true);  }  void Spell::EffectTameCreature(uint32 /*i*/) @@ -3922,17 +3970,19 @@ 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); +    m_caster->SetMinion(pet, true);      if(m_caster->GetTypeId() == TYPEID_PLAYER)      { @@ -3952,14 +4002,16 @@ void Spell::EffectSummonPet(uint32 i)              owner = m_originalCaster->GetCharmerOrOwnerPlayerOrPlayerItself();      } +    uint32 petentry = m_spellInfo->EffectMiscValue[i]; +      if(!owner)      { -        EffectSummonWild(i); +        SummonPropertiesEntry const *properties = sSummonPropertiesStore.LookupEntry(67); +        if(properties) +            SummonGuardian(petentry, properties);          return;      } -    uint32 petentry = m_spellInfo->EffectMiscValue[i]; -      Pet *OldSummon = owner->GetPet();      // if pet requested type already exist @@ -3998,7 +4050,7 @@ void Spell::EffectSummonPet(uint32 i)      Pet* pet = owner->SummonPet(petentry, x, y, z, owner->GetOrientation(), SUMMON_PET, 0);      if(!pet)          return; -         +      if(m_caster->GetTypeId() == TYPEID_UNIT)      {          if ( ((Creature*)m_caster)->isTotem() ) @@ -4009,10 +4061,6 @@ 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); -    pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL)); -      // generate new name for summon pet      std::string new_name=objmgr.GeneratePetName(petentry);      if(!new_name.empty()) @@ -4036,7 +4084,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); @@ -4045,6 +4092,9 @@ void Spell::EffectLearnPetSpell(uint32 i)  void Spell::EffectTaunt(uint32 /*i*/)  { +    if (!unitTarget) +        return; +      // this effect use before aura Taunt apply for prevent taunt already attacking target      // for spell as marked "non effective at already attacking target"      if(!unitTarget || !unitTarget->CanHaveThreatList() @@ -4063,7 +4113,7 @@ void Spell::EffectTaunt(uint32 /*i*/)              unitTarget->getThreatManager().addThreat(m_caster, itsThreat - myThreat);      } -    if(((Creature*)unitTarget)->IsAIEnabled) +    if(((Creature*)unitTarget)->IsAIEnabled && !((Creature*)unitTarget)->HasReactState(REACT_PASSIVE))          ((Creature*)unitTarget)->AI()->AttackStart(m_caster);  } @@ -4081,7 +4131,7 @@ void Spell::SpellDamageWeaponDmg(uint32 i)      // multiple weapon dmg effect workaround      // execute only the last weapon damage      // and handle all effects at once -    for (int j = 0; j < 3; j++) +    for (int j = 0; j < 3; ++j)      {          switch(m_spellInfo->Effect[j])          { @@ -4096,7 +4146,6 @@ void Spell::SpellDamageWeaponDmg(uint32 i)      }      // some spell specific modifiers -    //float weaponDamagePercentMod = 1.0f;                    // applied to weapon damage (and to fixed effect damage bonus if customBonusDamagePercentMod not set      float totalDamagePercentMod  = 1.0f;                    // applied to final bonus+weapon damage      int32 fixed_bonus = 0;      int32 spell_bonus = 0;                                  // bonus specific for spell @@ -4106,23 +4155,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->SpellFamilyFlags[1] & 0x40)              { +                if (m_caster->GetTypeId()!=TYPEID_PLAYER) +                    return; +                SpellEntry const *spellInfo = NULL;                  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) +                if (AuraEffect * aur = unitTarget->GetAura(SPELL_AURA_MOD_RESISTANCE,SPELLFAMILY_WARRIOR,SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR, 0, 0, m_caster->GetGUID()))                  { -                    SpellEntry const *proto = (*itr)->GetSpellProto(); -                    if(proto->SpellFamilyName == SPELLFAMILY_WARRIOR -                        && proto->SpellFamilyFlags == SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR) -                    { -                        int32 duration = GetSpellDuration(proto); -                        (*itr)->SetAuraDuration(duration); -                        (*itr)->UpdateAuraDuration(); -                        stack = (*itr)->GetStackAmount(); -                        break; -                    } +                    aur->GetParentAura()->RefreshAura(); +                    spellInfo = aur->GetSpellProto(); +                    stack = aur->GetParentAura()->GetStackAmount();                  }                  for(int j = 0; j < 3; j++) @@ -4134,7 +4178,7 @@ void Spell::SpellDamageWeaponDmg(uint32 i)                      }                  } -                if(stack < 5) +                if(!spellInfo)                  {                      // get highest rank of the Sunder Armor spell                      const PlayerSpellMap& sp_list = ((Player*)m_caster)->GetSpellMap(); @@ -4144,68 +4188,99 @@ void Spell::SpellDamageWeaponDmg(uint32 i)                          if(!itr->second->active || itr->second->disabled || itr->second->state == PLAYERSPELL_REMOVED)                              continue; -                        SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first); -                        if (!spellInfo) +                        SpellEntry const *spellProto = sSpellStore.LookupEntry(itr->first); +                        if (!spellProto)                              continue; -                        if (spellInfo->SpellFamilyFlags == SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR -                            && spellInfo->Id != m_spellInfo->Id -                            && spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR) +                        if (spellProto->SpellFamilyFlags[0] & SPELLFAMILYFLAG_WARRIOR_SUNDERARMOR +                            && spellProto->Id != m_spellInfo->Id +                            && spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR)                          { -                            m_caster->CastSpell(unitTarget, spellInfo, true); +                            spellInfo = spellProto;                              break;                          }                      }                  } +                if (!spellInfo) +                    break; +                m_caster->CastSpell(unitTarget, spellInfo, true); +                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);              } +            // Fan of Knives +            else if(m_spellInfo->SpellFamilyFlags[1] & 0x40000) +            { +                // 50% more damage with daggers +                if (Item* item = ((Player*)m_caster)->GetWeaponForAttack(m_attackType)) +                    if (item->GetProto()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER) +                        totalDamagePercentMod *= 1.5f; +            }              // Mutilate (for each hand) -            else if(m_spellInfo->SpellFamilyFlags & 0x600000000LL) +            else if(m_spellInfo->SpellFamilyFlags[1] & 0x6)              { -                Unit::AuraMap const& auras = unitTarget->GetAuras(); -                for(Unit::AuraMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) +                bool found = false; +                // fast check +                if(unitTarget->HasAuraState(AURA_STATE_DEADLY_POISON, m_spellInfo, m_caster)) +                    found = true; +                // full aura scan +                else                  { -                    if(itr->second->GetSpellProto()->Dispel == DISPEL_POISON) +                    Unit::AuraMap const& auras = unitTarget->GetAuras(); +                    for(Unit::AuraMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)                      { -                        totalDamagePercentMod *= 1.5f;          // 150% if poisoned -                        break; +                        if(itr->second->GetSpellProto()->Dispel == DISPEL_POISON) +                        { +                            found = true; +                            break; +                        }                      }                  } + +                if(found) +                    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));              } + +            // Seal of Command Unleashed +            else if(m_spellInfo->Id==20467) +            { +                spell_bonus += int32(0.16f*m_caster->GetTotalAttackPowerValue(BASE_ATTACK)); +                spell_bonus += int32(0.25f*m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo))); +            }              break;          }          case SPELLFAMILY_SHAMAN:          {              // 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) +                Unit::AuraEffectList const& m_OverrideClassScript = m_caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); +                for(Unit::AuraEffectList::const_iterator citr = m_OverrideClassScript.begin(); citr != m_OverrideClassScript.end(); ++citr)                  {                      // Stormstrike AP Buff -                    if ( (*i)->GetModifier()->m_miscvalue == 5634 ) +                    if ( (*citr)->GetMiscValue() == 5634 )                      { -                        m_caster->CastSpell(m_caster,38430,true,NULL,*i); +                        m_caster->CastSpell(m_caster, 38430, true, NULL, *citr);                          break;                      }                  } @@ -4215,7 +4290,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); @@ -4232,14 +4307,15 @@ void Spell::SpellDamageWeaponDmg(uint32 i)          {              case SPELL_EFFECT_WEAPON_DAMAGE:              case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL: -                fixed_bonus += CalculateDamage(j,unitTarget); +                fixed_bonus += CalculateDamage(j, unitTarget);                  break;              case SPELL_EFFECT_NORMALIZED_WEAPON_DMG: -                fixed_bonus += CalculateDamage(j,unitTarget); +                fixed_bonus += CalculateDamage(j, unitTarget);                  normalized = true;                  break;              case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE:                  weaponDamagePercentMod *= float(CalculateDamage(j,unitTarget)) / 100.0f; +                break;              default:                  break;                                      // not weapon damage effect, just skip          } @@ -4300,33 +4376,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*/) @@ -4347,10 +4396,13 @@ void Spell::EffectHealMaxHealth(uint32 /*i*/)      if(!unitTarget->isAlive())          return; -    uint32 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth(); -    unitTarget->SetHealth(unitTarget->GetMaxHealth()); +    int32 addhealth; +    if(m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN) // Lay on Hands +        addhealth = m_caster->GetMaxHealth(); +    else +        addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();      if(m_originalCaster) -        m_originalCaster->SendHealSpellLog(unitTarget, m_spellInfo->Id, addhealth, false); +        m_originalCaster->DealHeal(unitTarget, addhealth, m_spellInfo);  }  void Spell::EffectInterruptCast(uint32 i) @@ -4371,7 +4423,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, unitTarget, m_originalCaster->CalcSpellDuration(m_spellInfo), false);                      unitTarget->ProhibitSpellScholl(GetSpellSchoolMask(unitTarget->m_currentSpells[i]->m_spellInfo), duration/*GetSpellDuration(m_spellInfo)*/);                  }                  unitTarget->InterruptSpell(i,false); @@ -4390,7 +4442,7 @@ void Spell::EffectSummonObjectWild(uint32 i)      if( !target )          target = m_caster; -    float x,y,z; +    float x, y, z;      if(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)      {          x = m_targets.m_destX; @@ -4398,19 +4450,19 @@ void Spell::EffectSummonObjectWild(uint32 i)          z = m_targets.m_destZ;      }      else -        m_caster->GetClosePoint(x,y,z,DEFAULT_WORLD_OBJECT_SIZE); +        m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);      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.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY))      {          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)... @@ -4451,9 +4503,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.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY))          { -            linkedGO->SetRespawnTime(duration > 0 ? duration/1000 : 0); +            linkedGO->SetRespawnTime(duration > 0 ? duration/IN_MILISECONDS : 0);              linkedGO->SetSpellId(m_spellInfo->Id);              m_caster->AddGameObject(linkedGO); @@ -4472,450 +4524,764 @@ 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->HasAuraEffect(spells[j],0)) +                            return; -            switch(m_caster->GetMap()->urand(0,3)) -            { -                case 0: -                    iTmpSpellId = 26272; +                    // select spell +                    uint32 iTmpSpellId = spells[urand(0,3)]; + +                    // cast +                    unitTarget->CastSpell(unitTarget, iTmpSpellId, true); +                    return; +                } +                // Bending Shinbone +                case 8856: +                { +                    if(!itemTarget && m_caster->GetTypeId()!=TYPEID_PLAYER) +                        return; + +                    uint32 spell_id = 0; +                    switch(urand(1, 5)) +                    { +                    case 1:  spell_id = 8854; break; +                    default: spell_id = 8855; break; +                    } + +                    m_caster->CastSpell(m_caster,spell_id,true,NULL); +                    return; +                } +                // Brittle Armor - need remove one 24575 Brittle Armor aura +                case 24590: +                    unitTarget->RemoveAuraFromStack(24575); +                    return; +                // Mercurial Shield - need remove one 26464 Mercurial Shield aura +                case 26465: +                    unitTarget->RemoveAuraFromStack(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 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; +                    } + +                    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; + +                    // Onyxia Scale Cloak +                    if(unitTarget->GetDummyAura(22683)) +                        return; + +                    // Shadow Flame +                    m_caster->CastSpell(unitTarget, 22682, true); +                    return; +                } +                // Summon Black Qiraji Battle Tank +                case 26656: +                { +                    if(!unitTarget) +                        return; + +                    // Prevent stacking of mounts +                    unitTarget->RemoveAurasByType(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); +                    return; +                } +                // Piccolo of the Flaming Fire +                case 17512: +                { +                    if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) +                        return; +                    unitTarget->HandleEmoteCommand(EMOTE_STATE_DANCE); +                    return; +                } +                // Escape artist +                case 20589: +                { +                    if(!unitTarget) +                        return; +                    // It is said that removing effects by script should include dispel resist mods +                    unitTarget->RemoveAurasByTypeWithDispel(SPELL_AURA_MOD_ROOT, this); +                    unitTarget->RemoveAurasByTypeWithDispel(SPELL_AURA_MOD_DECREASE_SPEED, this); +                    return; +                } +                // Decimate +                case 28374: +                case 54426: +                    if(unitTarget) +                    { +                        int32 damage = (int32)unitTarget->GetHealth() - (int32)unitTarget->GetMaxHealth() * 0.05f; +                        if(damage > 0) +                            m_caster->CastCustomSpell(28375, SPELLVALUE_BASE_POINT0, damage, unitTarget); +                    } +                    return; +                // 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; -                case 1: -                    iTmpSpellId = 26157; +                } +                // 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();) +                    { +                        Aura *aur = iter->second; +                        if (!aur->IsPositive())             //only remove negative spells +                        { +                            // check for mechanic mask +                            if(GetAllSpellMechanicMask(aur->GetSpellProto()) & mechanic_mask) +                            { +                                unitTarget->RemoveAura(iter); +                            } +                            else +                                iter++; +                        } +                        else +                            iter++; +                    }                      break; -                case 2: -                    iTmpSpellId = 26273; +                } +                /*// Flame Crash +                case 41126: +                { +                    if(!unitTarget) +                        return; + +                    unitTarget->CastSpell(unitTarget, 41131, true);                      break; -                case 3: -                    iTmpSpellId = 26274; +                }*/ +                // Draw Soul +                case 40904: +                { +                    if(!unitTarget) +                        return; + +                    unitTarget->CastSpell(m_caster, 40903, true);                      break; -            } +                } +                case 48025:                                     // Headless Horseman's Mount +                { +                if(!unitTarget) +                        return; -            unitTarget->CastSpell(unitTarget, iTmpSpellId, true); +                    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; -            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; -        // Bending Shinbone -        case 8856: -        { -            if(!itemTarget && m_caster->GetTypeId()!=TYPEID_PLAYER) -                return; +                    int bag=19; +                    int slot=0; +                    Item* item = NULL; -            uint32 spell_id = 0; -            switch(m_caster->GetMap()->urand(1,5)) -            { -                case 1:  spell_id = 8854; break; -                default: spell_id = 8855; break; -            } +                    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; -            m_caster->CastSpell(m_caster,spell_id,true,NULL); -            return; -        } +                    unitTarget->CastSpell(unitTarget, 44870, true); +                    break; +                }                +                // spell of Brutallus - Stomp +                case 45185: +                { +                        if(!unitTarget) +                            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) +                        if(unitTarget->HasAura(46394)) // spell of Brutallus - Burn +                            unitTarget->RemoveAurasDueToSpell(46394); + +                        break; +                } +                // Negative Energy +                case 46289:                  { -                    rank = 1; +                    if(!unitTarget) +                        return; +               +                    m_caster->CastSpell(unitTarget, 46285, true);                      break; -                } -                else if((*i)->GetId() == 18693) +                }                 +                // Goblin Weather Machine +                case 46203:                  { -                    rank = 2; +                    if(!unitTarget) +                        return; + +                    uint32 spellId = 0; +                    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; -            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 -            }; +                    ((Player*)unitTarget)->ModifyMoney(50000000); -            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; +                    break; +                } +                // Vigilance +                case 50725: +                { +                    if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) +                        return; + +                    // Remove Taunt cooldown +                    ((Player*)unitTarget)->RemoveSpellCooldown(355, true); -            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; -            } +                } +                // Emblazon Runeblade +                case 51770: +                { +                    if(!m_originalCaster) +                        return; -            unitTarget->CastSpell(unitTarget,spellid,false); -            return; -        } +                    m_originalCaster->CastSpell(m_originalCaster, damage, false); +                    break; +                } +                // Summon Ghouls On Scarlet Crusade +                case 51904: +                { +                    if(!m_targets.HasDst()) +                        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; +                    float x, y, z; +                    float radius = GetSpellRadius(m_spellInfo, effIndex, true); +                    for(uint32 i = 0; i < 15; ++i) +                    { +                        m_caster->GetRandomPoint(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, radius, x, y, z); +                        m_caster->CastSpell(x, y, z, 54522, true); +                    } +                    break; +                } +                // Sky Darkener Assault +                case 52124: +                    if(unitTarget) +                        m_caster->CastSpell(unitTarget, 52125, false); +                    return; +                // 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; +                } +                // Winged Steed of the Ebon Blade +                case 54729: +                { +                    if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) +                        return; -            // Onyxia Scale Cloak -            if(unitTarget->GetDummyAura(22683)) -                return; +                    // Prevent stacking of mounts +                    unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED); -            // Shadow Flame -            m_caster->CastSpell(unitTarget, 22682, true); -            return; -        } -        break; +                    // Triggered spell id dependent of riding skill +                    if(uint16 skillval = ((Player*)unitTarget)->GetSkillValue(SKILL_RIDING)) +                    { +                        if (skillval >= 300) +                            unitTarget->CastSpell(unitTarget, 54727, true); +                        else +                            unitTarget->CastSpell(unitTarget, 54726, true); +                    } +                    return; +                } +                case 58418:                                 // Portal to Orgrimmar +                case 58420:                                 // Portal to Stormwind +                { +                    if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER || effIndex!=0) +                        return; -        // Summon Black Qiraji Battle Tank -        case 26656: -        { -            if(!unitTarget) -                return; +                    uint32 spellID = m_spellInfo->CalculateSimpleValue(0); +                    uint32 questID = m_spellInfo->CalculateSimpleValue(1); -            // Prevent stacking of mounts -            unitTarget->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); +                    if (((Player*)unitTarget)->GetQuestStatus(questID) == QUEST_STATUS_COMPLETE && !((Player*)unitTarget)->GetQuestRewardStatus (questID)) +                        unitTarget->CastSpell(unitTarget, spellID, true); -            // 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; +                    return; +                } +                case 58941:                                 // Rock Shards +                    if(unitTarget && m_originalCaster) +                    { +                        for(uint32 i = 0; i < 3; ++i) +                        { +                            m_originalCaster->CastSpell(unitTarget, 58689, true); +                            m_originalCaster->CastSpell(unitTarget, 58692, true); +                        } +                        if(m_originalCaster->GetMap()->IsHeroic()) +                        { +                            m_originalCaster->CastSpell(unitTarget, 60883, true); +                            m_originalCaster->CastSpell(unitTarget, 60884, true); +                        } +                        else +                        { +                            m_originalCaster->CastSpell(unitTarget, 58695, true); +                            m_originalCaster->CastSpell(unitTarget, 58696, true); +                        } +                    } +                    return; +                case 59317:                                 // Teleporting +                    if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) +                        return; -            // 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; +                    // return from top +                    if (((Player*)unitTarget)->GetAreaId() == 4637) +                        unitTarget->CastSpell(unitTarget, 59316, true); +                    // teleport atop +                    else +                        unitTarget->CastSpell(unitTarget, 59314, true); -            // don't overwrite an existing aura -            for(uint8 i=0; i<5; i++) -                if(unitTarget->HasAura(spellid+i, 0))                      return; -            unitTarget->CastSpell(unitTarget, spellid+m_caster->GetMap()->urand(0, 4), true); -            break; -        } - -        // 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; -        } +                // 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(m_caster->GetTypeId() != TYPEID_PLAYER) +                        return; -        // Mirren's Drinking Hat -        case 29830: -        { -            uint32 item = 0; -            switch ( m_caster->GetMap()->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 +                    // learn random explicit discovery recipe (if any) +                    if(uint32 discoveredSpell = GetExplicitDiscoverySpell(m_spellInfo->Id, (Player*)m_caster)) +                        ((Player*)m_caster)->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::AuraEffectList const& mDummyAuras = unitTarget->GetAurasByType(SPELL_AURA_DUMMY); +                    for(Unit::AuraEffectList::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; +                    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 +                    }; -            uint32 spellId; -            switch((uint32)m_caster->GetMap()->rand32()%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) +                    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 +                        case 47871: +                            itemtype=itypes[6][rank];break; // Demonic Healthstone +                        case 47878: +                            itemtype=itypes[7][rank];break; // Fel Healthstone +                        default: +                            return; +                    } +                    DoCreateItem( effIndex, itemtype );                      return; - -                if(unitTarget) +                } +                // Everlasting Affliction +                case 47422: +                    // Refresh corruption on target +                    if (AuraEffect * aur = unitTarget->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_WARLOCK, 0x2, 0, 0, m_caster->GetGUID())) +                        aur->GetParentAura()->RefreshAura(); +                    return; +                // Demonic Empowerment +                case 47193:                  { -                    switch(((Player*)unitTarget)->GetBaseSkillValue(762)) +                    if(!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT || !((Creature *)unitTarget)->isPet()) +                        return; +                    CreatureInfo const * ci = objmgr.GetCreatureTemplate(unitTarget->GetEntry()); +                    switch (ci->family)                      { -                    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 CREATURE_FAMILY_SUCCUBUS: +                        unitTarget->CastSpell(unitTarget, 54435, true); +                        break; +                    case CREATURE_FAMILY_VOIDWALKER: +                    { +                        SpellEntry const* spellInfo = sSpellStore.LookupEntry(54443); +                        int32 hp = unitTarget->GetMaxHealth() * m_caster->CalculateSpellDamage(spellInfo, 0, spellInfo->EffectBasePoints[0], unitTarget) /100; +                        unitTarget->CastCustomSpell(unitTarget, 54443,&hp, NULL, NULL,true); +                        //unitTarget->CastSpell(unitTarget, 54441, true); +                        break; +                    } +                    case CREATURE_FAMILY_FELGUARD: +                        unitTarget->CastSpell(unitTarget, 54508, true); +                        break; +                    case CREATURE_FAMILY_FELHUNTER: +                        unitTarget->CastSpell(unitTarget, 54509, true); +                        break; +                    case CREATURE_FAMILY_IMP: +                        unitTarget->CastSpell(unitTarget, 54444, true); +                        break;                      } +                    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 +                    if (AuraEffect * aur = unitTarget->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x8000, 0, 0, m_caster->GetGUID())) +                        aur->GetParentAura()->RefreshAura(); +                    return;                  } +                // Divine Hymn +                case 47951: +                { +                    if (!unitTarget) +                        return; +                    Unit * target=NULL; +                    unitTarget->CastSpell(target, 59600, false); +                    unitTarget->CastSpell(target, 47953, false); +                    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; + +                        // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting. +                        if (familyFlag[0] & 0x4000) +                        { +                            spellId = 53353; // 53353 Chimera Shot - Serpent +                            basePoint = aura->GetPartAura(0)->GetAmount() * 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) +                        { +                            int32 tickCount = aura->GetPartAura(0)->GetTickNumber(); +                            spellId = 53358; // 53358 Chimera Shot - Viper +                                // Amount of one aura tick +                            basePoint = aura->GetPartAura(0)->GetAmount() * aura->GetTarget()->GetMaxPower(POWER_MANA) / 100 ; +                            int32 casterBasePoint = aura->GetPartAura(0)->GetAmount() * unitTarget->GetMaxPower(POWER_MANA) / 50 ; +                            if (basePoint > casterBasePoint) +                                basePoint = casterBasePoint; +                            basePoint = basePoint * tickCount * 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 +                        //} + +                        // Refresh aura duration +                        aura->RefreshAura(); +                        break; +                    } +                    if (spellId) +                        m_caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, true); +                    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; -        // spell of Brutallus - Stomp -        case 45185: -        { -            if(unitTarget->HasAura(46394, 0)) // spell of Brutallus - Burn -                unitTarget->RemoveAurasDueToSpell(46394); -            break; -        } -        // Negative Energy -        case 46289: m_caster->CastSpell(unitTarget, 46285, 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 -                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) +                // Judgement self add switch +                switch (m_spellInfo->Id)                  { -                    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 ) -                        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) -                        continue; - -                    // 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) +                    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::AuraMap & sealAuras = m_caster->GetAuras(); +                for(Unit::AuraMap::iterator iter = sealAuras.begin(); iter != sealAuras.end();) +                { +                    if (IsSealSpell(iter->second->GetSpellProto()))                      { -                        if ((*i)->GetSpellProto()->SpellIconID == 205 && (*i)->GetSpellProto()->Attributes == 0x01D0LL) +                        if (AuraEffect * aureff = iter->second->GetPartAura(2)) +                            if (aureff->GetAuraName()==SPELL_AURA_DUMMY) +                            { +                                if (sSpellStore.LookupEntry(aureff->GetAmount())) +                                    spellId2 = aureff->GetAmount(); +                                break; +                            } +                        if (!spellId2)                          { -                            int32 chance = (*i)->GetModifier()->m_amount; -                            if ( roll_chance_i(chance) ) +                            switch (iter->first)                              { -                                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); +                            // Seal of light, Seal of wisdom, Seal of justice +                                case 20165: +                                case 20166: +                                case 20164: +                                spellId2 = 54158;                              } -                            break;                          } +                        break;                      } +                    else +                        ++iter; +                } +                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; + +                    // 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->HasAuraEffect(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;          }      } @@ -4931,7 +5297,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)      { @@ -4951,9 +5317,9 @@ 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); +        ((Player *)m_caster)->RemoveAurasByType(SPELL_AURA_MOD_ROOT);      }  } @@ -4986,6 +5352,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; @@ -5011,11 +5378,12 @@ 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(), -        m_caster->GetOrientation(), 0, 0, 0, 0, 0, 1)) +        m_caster->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY))      {          delete pGameObj;          return; @@ -5024,7 +5392,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); @@ -5032,9 +5400,9 @@ void Spell::EffectDuel(uint32 i)      //END      // Send request -    WorldPacket data(SMSG_DUEL_REQUESTED, 16); -    data << pGameObj->GetGUID(); -    data << caster->GetGUID(); +    WorldPacket data(SMSG_DUEL_REQUESTED, 8 + 8); +    data << uint64(pGameObj->GetGUID()); +    data << uint64(caster->GetGUID());      caster->GetSession()->SendPacket(&data);      target->GetSession()->SendPacket(&data); @@ -5053,8 +5421,8 @@ void Spell::EffectDuel(uint32 i)      duel2->startTimer = 0;      target->duel      = duel2; -    caster->SetUInt64Value(PLAYER_DUEL_ARBITER,pGameObj->GetGUID()); -    target->SetUInt64Value(PLAYER_DUEL_ARBITER,pGameObj->GetGUID()); +    caster->SetUInt64Value(PLAYER_DUEL_ARBITER, pGameObj->GetGUID()); +    target->SetUInt64Value(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());  }  void Spell::EffectStuck(uint32 /*i*/) @@ -5080,7 +5448,7 @@ void Spell::EffectStuck(uint32 /*i*/)      SpellEntry const *spellInfo = sSpellStore.LookupEntry(8690);      if(!spellInfo)          return; -    Spell spell(pTarget,spellInfo,true,0); +    Spell spell(pTarget, spellInfo, true, 0);      spell.SendSpellCooldown();  } @@ -5093,15 +5461,15 @@ void Spell::EffectSummonPlayer(uint32 /*i*/)      if(unitTarget->GetDummyAura(23445))          return; -    float x,y,z; -    m_caster->GetClosePoint(x,y,z,unitTarget->GetObjectSize()); +    float x, y, z; +    m_caster->GetClosePoint(x, y, z, unitTarget->GetObjectSize());      ((Player*)unitTarget)->SetSummonPoint(m_caster->GetMapId(),x,y,z);      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);  } @@ -5124,89 +5492,40 @@ void Spell::EffectActivateObject(uint32 effect_idx)      sWorld.ScriptCommandStart(activateCommand, delay_secs, m_caster, gameObjTarget);  } -void Spell::EffectSummonTotem(uint32 i) +void Spell::EffectApplyGlyph(uint32 i)  { -    uint8 slot = 0; -    switch(m_spellInfo->EffectMiscValueB[i]) -    { -        case SUMMON_TYPE_TOTEM_SLOT1: slot = 0; break; -        case SUMMON_TYPE_TOTEM_SLOT2: slot = 1; break; -        case SUMMON_TYPE_TOTEM_SLOT3: slot = 2; break; -        case SUMMON_TYPE_TOTEM_SLOT4: slot = 3; break; -        // Battle standard case -        case SUMMON_TYPE_TOTEM:       slot = 254; break; -        // jewelery statue case, like totem without slot -        case SUMMON_TYPE_GUARDIAN:    slot = 255; break; -        default: return; -    } - -    if(slot < MAX_TOTEM) -    { -        uint64 guid = m_caster->m_TotemSlot[slot]; -        if(guid != 0) -        { -            Creature *OldTotem = ObjectAccessor::GetCreature(*m_caster, guid); -            if(OldTotem && OldTotem->isTotem()) -                ((Totem*)OldTotem)->UnSummon(); -        } -    } - -    uint32 team = 0; -    if (m_caster->GetTypeId()==TYPEID_PLAYER) -        team = ((Player*)m_caster)->GetTeam(); - -    Totem* pTotem = new Totem; - -    if(!pTotem->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), m_caster->GetMap(), m_spellInfo->EffectMiscValue[i], team )) -    { -        delete pTotem; +    if(m_caster->GetTypeId() != TYPEID_PLAYER)          return; -    } - -    float angle = slot < MAX_TOTEM ? M_PI/MAX_TOTEM - (slot*2*M_PI/MAX_TOTEM) : 0; - -    float x,y,z; -    m_caster->GetClosePoint(x,y,z,pTotem->GetObjectSize(),2.0f,angle); - -    // totem must be at same Z in case swimming caster and etc. -    if( fabs( z - m_caster->GetPositionZ() ) > 5 ) -        z = m_caster->GetPositionZ(); - -    pTotem->Relocate(x, y, z, m_caster->GetOrientation()); -    if(slot < MAX_TOTEM) -        m_caster->m_TotemSlot[slot] = pTotem->GetGUID(); - -    pTotem->SetOwner(m_caster->GetGUID()); -    pTotem->SetTypeBySummonSpell(m_spellInfo);              // must be after Create call where m_spells initilized - -    int32 duration=GetSpellDuration(m_spellInfo); -    if(Player* modOwner = m_caster->GetSpellModOwner()) -        modOwner->ApplySpellMod(m_spellInfo->Id,SPELLMOD_DURATION, duration); -    pTotem->SetDuration(duration); +    Player *player = (Player*)m_caster; -    if (damage)                                             // if not spell info, DB values used +    // apply new one +    if(uint32 glyph = m_spellInfo->EffectMiscValue[i])      { -        pTotem->SetMaxHealth(damage); -        pTotem->SetHealth(damage); -    } - -    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(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 mismatch +                } +            } -    pTotem->Summon(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); +                } +            } -    if(slot < MAX_TOTEM && m_caster->GetTypeId() == TYPEID_PLAYER) -    { -        WorldPacket data(SMSG_TOTEM_CREATED, 1+8+4+4); -        data << uint8(slot); -        data << uint64(pTotem->GetGUID()); -        data << uint32(duration); -        data << uint32(m_spellInfo->Id); -        ((Player*)m_caster)->SendDirectMessage(&data); +            player->CastSpell(m_caster, gp->SpellId, true); +            player->SetGlyph(m_glyphIndex, glyph); +        }      }  } @@ -5247,8 +5566,8 @@ void Spell::EffectEnchantHeldItem(uint32 i)              return;          // Apply the temporary enchantment -        item->SetEnchantment(slot, enchant_id, duration*1000, 0); -        item_owner->ApplyEnchantment(item,slot,true); +        item->SetEnchantment(slot, enchant_id, duration*IN_MILISECONDS, 0); +        item_owner->ApplyEnchantment(item, slot, true);      }  } @@ -5280,7 +5599,7 @@ void Spell::EffectInebriate(uint32 /*i*/)          currentDrunk = 0xFFFF;      else          currentDrunk += drunkMod; -    player->SetDrunkValue(currentDrunk, m_CastItem?m_CastItem->GetEntry():0); +    player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0);  }  void Spell::EffectFeedPet(uint32 i) @@ -5290,7 +5609,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(); @@ -5300,15 +5620,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*/) @@ -5316,13 +5636,13 @@ void Spell::EffectDismissPet(uint32 /*i*/)      if(m_caster->GetTypeId() != TYPEID_PLAYER)          return; -    Pet* pet = m_caster->GetPet(); +    Pet* pet = ((Player*)m_caster)->GetPet();      // not let dismiss dead pet      if(!pet||!pet->isAlive())          return; -    ((Player*)m_caster)->RemovePet(pet,PET_SAVE_NOT_IN_SLOT); +    ((Player*)m_caster)->RemovePet(pet, PET_SAVE_NOT_IN_SLOT);  }  void Spell::EffectSummonObject(uint32 i) @@ -5344,7 +5664,7 @@ void Spell::EffectSummonObject(uint32 i)      {          GameObject* obj = NULL;          if( m_caster ) -            obj = ObjectAccessor::GetGameObject(*m_caster, guid); +            obj = m_caster->GetMap()->GetGameObject(guid);          if(obj) obj->Delete();          m_caster->m_ObjectSlot[slot] = 0; @@ -5352,10 +5672,7 @@ void Spell::EffectSummonObject(uint32 i)      GameObject* pGameObj = new GameObject; -    float rot2 = sin(m_caster->GetOrientation()/2); -    float rot3 = cos(m_caster->GetOrientation()/2); - -    float x,y,z; +    float x, y, z;      // If dest location if present      if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)      { @@ -5365,10 +5682,11 @@ void Spell::EffectSummonObject(uint32 i)      }      // Summon in random point all other units if location present      else -        m_caster->GetClosePoint(x,y,z,DEFAULT_WORLD_OBJECT_SIZE); +        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.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY))      {          delete pGameObj;          return; @@ -5376,14 +5694,14 @@ 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);      map->Add(pGameObj);      WorldPacket data(SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE, 8); -    data << pGameObj->GetGUID(); -    m_caster->SendMessageToSet(&data,true); +    data << uint64(pGameObj->GetGUID()); +    m_caster->SendMessageToSet(&data, true);      m_caster->m_ObjectSlot[slot] = pGameObj->GetGUID();  } @@ -5460,18 +5778,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) @@ -5483,7 +5797,7 @@ void Spell::EffectMomentMove(uint32 i)          return;      uint32 mapid = m_caster->GetMapId(); -    float dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); +    float dist = m_caster->GetSpellRadiusForTarget(unitTarget, sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));      float x,y,z;      float destx,desty,destz,ground,floor;      float orientation = unitTarget->GetOrientation(), step = dist/10.0f; @@ -5522,11 +5836,7 @@ void Spell::EffectMomentMove(uint32 i)        {  	return;        } - -    if(unitTarget->GetTypeId() == TYPEID_PLAYER) -      ((Player*)unitTarget)->TeleportTo(mapid, destx, desty, destz+0.07531f, unitTarget->GetOrientation(), TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (unitTarget==m_caster ? TELE_TO_SPELL : 0)); -    else -        unitTarget->GetMap()->CreatureRelocation((Creature*)unitTarget, destx, desty, destz,unitTarget->GetOrientation()); +    unitTarget->NearTeleportTo(destx, desty, destz + 0.07531, orientation, unitTarget==m_caster);  } @@ -5546,7 +5856,7 @@ void Spell::EffectReputation(uint32 i)      if(!factionEntry)          return; -    _player->ModifyFactionReputation(factionEntry,rep_change); +    _player->GetReputationMgr().ModifyReputation(factionEntry, rep_change);  }  void Spell::EffectQuestComplete(uint32 i) @@ -5640,97 +5950,11 @@ void Spell::EffectCharge(uint32 /*i*/)          m_caster->Attack(target, true);  } -void Spell::EffectSummonCritter(uint32 i) -{ -    if(m_caster->GetTypeId() != TYPEID_PLAYER) -        return; -    Player* player = (Player*)m_caster; - -    uint32 pet_entry = m_spellInfo->EffectMiscValue[i]; -    if(!pet_entry) -        return; - -    Pet* old_critter = player->GetMiniPet(); - -    // for same pet just despawn -    if(old_critter && old_critter->GetEntry() == pet_entry) -    { -        player->RemoveMiniPet(); -        return; -    } - -    // despawn old pet before summon new -    if(old_critter) -        player->RemoveMiniPet(); - -    // summon new pet -    Pet* critter = new Pet(MINI_PET); - -    Map *map = m_caster->GetMap(); -    uint32 pet_number = objmgr.GeneratePetNumber(); -    if(!critter->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), -        map, pet_entry, pet_number)) -    { -        sLog.outError("Spell::EffectSummonCritter, spellid %u: no such creature entry %u", m_spellInfo->Id, pet_entry); -        delete critter; -        return; -    } - -    float x,y,z; -    // If dest location if present -    if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) -    { -         x = m_targets.m_destX; -         y = m_targets.m_destY; -         z = m_targets.m_destZ; -     } -     // Summon if dest location not present near caster -     else -         m_caster->GetClosePoint(x,y,z,critter->GetObjectSize()); - -    critter->Relocate(x,y,z,m_caster->GetOrientation()); - -    if(!critter->IsPositionValid()) -    { -        sLog.outError("ERROR: Pet (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %f Y: %f)", -            critter->GetGUIDLow(), critter->GetEntry(), critter->GetPositionX(), critter->GetPositionY()); -        delete critter; -        return; -    } - -    critter->SetOwnerGUID(m_caster->GetGUID()); -    critter->SetCreatorGUID(m_caster->GetGUID()); -    critter->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,m_caster->getFaction()); -    critter->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); - -    critter->AIM_Initialize(); -    critter->InitPetCreateSpells();                         // e.g. disgusting oozeling has a create spell as critter... -    critter->SetMaxHealth(1); -    critter->SetHealth(1); -    critter->SetLevel(1); - -    // set timer for unsummon -    int32 duration = GetSpellDuration(m_spellInfo); -    if(duration > 0) -        critter->SetDuration(duration); - -    std::string name = player->GetName(); -    name.append(petTypeSuffix[critter->getPetType()]); -    critter->SetName( name ); -    player->SetMiniPet(critter); - -    map->Add((Creature*)critter); -} -  void Spell::EffectKnockBack(uint32 i)  {      if(!unitTarget)          return; -    // Effect only works on players -    if(unitTarget->GetTypeId()!=TYPEID_PLAYER) -        return; -      float x, y;      if(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)      { @@ -5743,31 +5967,26 @@ void Spell::EffectKnockBack(uint32 i)          y = m_caster->GetPositionY();      } -    float dx = unitTarget->GetPositionX() - x; -    float dy = unitTarget->GetPositionY() - y; -    float vcos, vsin; -    if(dx < 0.001f && dy < 0.001f) +    float speedxy = float(m_spellInfo->EffectMiscValue[i])/10; +    float speedz = float(damage/10); + +    unitTarget->KnockbackFrom(x, y, speedxy, speedz); +} + +void Spell::EffectJump2(uint32 i) +{ +    float speedxy = float(m_spellInfo->EffectMiscValue[i])/10; +    float speedz = float(damage/10); +    if(!speedxy)      { -      float angle = m_caster->GetMap()->rand_norm()*2*M_PI; -        vcos = cos(angle); -        vsin = sin(angle); +        if(m_targets.getUnitTarget()) +            m_caster->JumpTo(m_targets.getUnitTarget(), speedz);      }      else      { -        float dist = sqrt((dx*dx) + (dy*dy)); -        vcos = dx / dist; -        vsin = dy / dist; +        //1891: Disengage +        m_caster->JumpTo(speedxy, speedz, m_spellInfo->SpellIconID != 1891);                 } - -    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) - -    ((Player*)unitTarget)->GetSession()->SendPacket(&data);  }  void Spell::EffectSendTaxi(uint32 i) @@ -5775,38 +5994,7 @@ void Spell::EffectSendTaxi(uint32 i)      if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)          return; -    TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(m_spellInfo->EffectMiscValue[i]); -    if(!entry) -        return; - -    std::vector<uint32> nodes; - -    nodes.resize(2); -    nodes[0] = entry->from; -    nodes[1] = entry->to; - -    uint32 mountid = 0; -    switch(m_spellInfo->Id) -    { -        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 -            mountid = 22840; -            break; -        case 34905:      //Stealth Flight -            mountid = 6851; -            break; -        case 41533:      //Fly of the Netherwing -        case 41540:      //Fly of the Netherwing -            mountid = 23468; -            break; -    } - -    ((Player*)unitTarget)->ActivateTaxiPathTo(nodes,mountid); - +    ((Player*)unitTarget)->ActivateTaxiPathTo(m_spellInfo->EffectMiscValue[i],m_spellInfo->Id);  }  void Spell::EffectPlayerPull(uint32 i) @@ -5821,7 +6009,7 @@ void Spell::EffectPlayerPull(uint32 i)      float vsin = sin(unitTarget->GetAngle(m_caster));      float vcos = cos(unitTarget->GetAngle(m_caster)); -    WorldPacket data(SMSG_MOVE_KNOCK_BACK, (8+4+4+4+4+4)); +    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 @@ -5840,22 +6028,21 @@ void Spell::EffectDispelMechanic(uint32 i)      uint32 mechanic = m_spellInfo->EffectMiscValue[i]; +    std::queue < std::pair < uint32, uint64 > > 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(); iter != Auras.end(); iter++)      { -        next = iter; -        ++next; -        SpellEntry const *spell = sSpellStore.LookupEntry(iter->second->GetSpellProto()->Id); -        if(spell->Mechanic == mechanic || spell->EffectMechanic[iter->second->GetEffIndex()] == mechanic) -        { -            unitTarget->RemoveAurasDueToSpell(spell->Id); -            if(Auras.empty()) -                break; -            else -                next = Auras.begin(); -        } +       if((GetAllSpellMechanicMask(iter->second->GetSpellProto()) & (1<<(mechanic))) && GetDispelChance(iter->second->GetCaster(), iter->second->GetId())) +       { +           dispel_list.push(std::make_pair(iter->second->GetId(), iter->second->GetCasterGUID() ) ); +       } +    } + +    for(;dispel_list.size();dispel_list.pop()) +    { +        unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, AURA_REMOVE_BY_ENEMY_SPELL);      } -    return;  }  void Spell::EffectSummonDeadPet(uint32 /*i*/) @@ -5870,39 +6057,43 @@ void Spell::EffectSummonDeadPet(uint32 /*i*/)          return;      if(damage < 0)          return; +      pet->SetUInt32Value(UNIT_DYNAMIC_FLAGS, 0);      pet->RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);      pet->setDeathState( ALIVE );      pet->clearUnitState(UNIT_STAT_ALL_STATE);      pet->SetHealth( uint32(pet->GetMaxHealth()*(float(damage)/100))); -    pet->AIM_Initialize(); - -    _player->PetSpellInitialize(); +    //pet->AIM_Initialize(); +    //_player->PetSpellInitialize();      pet->SavePetToDB(PET_SAVE_AS_CURRENT);  }  void Spell::EffectDestroyAllTotems(uint32 /*i*/)  { -    float mana = 0; -    for(int slot = 0;  slot < MAX_TOTEM; ++slot) +    int32 mana = 0; +    for(int slot = SUMMON_SLOT_TOTEM; slot < MAX_TOTEM_SLOT; ++slot)      { -        if(!m_caster->m_TotemSlot[slot]) +        if(!m_caster->m_SummonSlot[slot])              continue; -        Creature* totem = ObjectAccessor::GetCreature(*m_caster,m_caster->m_TotemSlot[slot]); +        Creature* totem = m_caster->GetMap()->GetCreature(m_caster->m_SummonSlot[slot]);          if(totem && totem->isTotem())          {              uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);              SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell_id);              if(spellInfo) -                mana += spellInfo->manaCost * damage / 100; +            { +                mana += spellInfo->manaCost; +                mana += spellInfo->ManaCostPercentage * m_caster->GetCreateMana() / 100; +            }              ((Totem*)totem)->UnSummon();          }      } +    mana = mana * damage / 100; -    int32 gain = m_caster->ModifyPower(POWER_MANA,int32(mana)); -    m_caster->SendEnergizeSpellLog(m_caster, m_spellInfo->Id, gain, POWER_MANA); +    if (mana) +        m_caster->CastCustomSpell(m_caster, 39104, &mana, NULL, NULL, true);  }  void Spell::EffectDurabilityDamage(uint32 i) @@ -5916,7 +6107,7 @@ void Spell::EffectDurabilityDamage(uint32 i)      // Possibly its mean -1 all player equipped items and -2 all items      if(slot < 0)      { -        ((Player*)unitTarget)->DurabilityPointsLossAll(damage,(slot < -1)); +        ((Player*)unitTarget)->DurabilityPointsLossAll(damage, (slot < -1));          return;      } @@ -5924,8 +6115,8 @@ void Spell::EffectDurabilityDamage(uint32 i)      if(slot >= INVENTORY_SLOT_BAG_END)          return; -    if(Item* item = ((Player*)unitTarget)->GetItemByPos(INVENTORY_SLOT_BAG_0,slot)) -        ((Player*)unitTarget)->DurabilityPointsLoss(item,damage); +    if(Item* item = ((Player*)unitTarget)->GetItemByPos(INVENTORY_SLOT_BAG_0, slot)) +        ((Player*)unitTarget)->DurabilityPointsLoss(item, damage);  }  void Spell::EffectDurabilityDamagePCT(uint32 i) @@ -5939,7 +6130,7 @@ void Spell::EffectDurabilityDamagePCT(uint32 i)      // Possibly its mean -1 all player equipped items and -2 all items      if(slot < 0)      { -        ((Player*)unitTarget)->DurabilityLossAll(double(damage)/100.0f,(slot < -1)); +        ((Player*)unitTarget)->DurabilityLossAll(double(damage)/100.0f, (slot < -1));          return;      } @@ -5950,8 +6141,8 @@ void Spell::EffectDurabilityDamagePCT(uint32 i)      if(damage <= 0)          return; -    if(Item* item = ((Player*)unitTarget)->GetItemByPos(INVENTORY_SLOT_BAG_0,slot)) -        ((Player*)unitTarget)->DurabilityLoss(item,double(damage)/100.0f); +    if(Item* item = ((Player*)unitTarget)->GetItemByPos(INVENTORY_SLOT_BAG_0, slot)) +        ((Player*)unitTarget)->DurabilityLoss(item, double(damage)/100.0f);  }  void Spell::EffectModifyThreatPercent(uint32 /*effIndex*/) @@ -5974,7 +6165,7 @@ void Spell::EffectTransmitted(uint32 effIndex)          return;      } -    float fx,fy,fz; +    float fx, fy, fz;      if(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)      { @@ -5985,23 +6176,24 @@ 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])); -        m_caster->GetClosePoint(fx,fy,fz,DEFAULT_WORLD_OBJECT_SIZE, dis); +        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)); -        float dis = m_caster->GetMap()->rand_norm() * (max_dis - min_dis) + min_dis; +        //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); +        m_caster->GetClosePoint(fx, fy, fz, DEFAULT_WORLD_OBJECT_SIZE, dis);      }      Map *cMap = m_caster->GetMap();      if(goinfo->type==GAMEOBJECT_TYPE_FISHINGNODE)      { -        if ( !cMap->IsInWater(fx,fy,fz-0.5f)) // Hack to prevent fishing bobber from failing to land on fishing hole +        if ( !cMap->IsInWater(fx, fy, fz-0.5f))             // Hack to prevent fishing bobber from failing to land on fishing hole          { // but this is not proper, we really need to ignore not materialized objects              SendCastResult(SPELL_FAILED_NOT_HERE);              SendChannelUpdate(0); @@ -6009,18 +6201,18 @@ void Spell::EffectTransmitted(uint32 effIndex)          }          // replace by water level in this case -        fz = cMap->GetWaterLevel(fx,fy); +        fz = cMap->GetWaterLevel(fx, fy);      }      // if gameobject is summoning object, it should be spawned right on caster's position      else if(goinfo->type==GAMEOBJECT_TYPE_SUMMONING_RITUAL)      { -        m_caster->GetPosition(fx,fy,fz); +        m_caster->GetPosition(fx, fy, fz);      }      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.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY))      {          delete pGameObj;          return; @@ -6033,16 +6225,12 @@ void Spell::EffectTransmitted(uint32 effIndex)          case GAMEOBJECT_TYPE_FISHINGNODE:          {              m_caster->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT,pGameObj->GetGUID()); -                                                            // Orientation3 -            pGameObj->SetFloatValue(GAMEOBJECT_ROTATION + 2, 0.88431775569915771 ); -                                                            // Orientation4 -            pGameObj->SetFloatValue(GAMEOBJECT_ROTATION + 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))              // start time == fish-FISHING_BOBBER_READY_TIME (0..GetDuration(m_spellInfo)-FISHING_BOBBER_READY_TIME) -            int32 lastSec; -            switch(m_caster->GetMap()->urand(0, 3)) +            int32 lastSec = 0; +            switch(urand(0, 3))              {                  case 0: lastSec =  3; break;                  case 1: lastSec =  7; break; @@ -6050,12 +6238,12 @@ 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:          { -            if(m_caster->GetTypeId()==TYPEID_PLAYER) +            if(m_caster->GetTypeId() == TYPEID_PLAYER)              {                  pGameObj->AddUniqueUse((Player*)m_caster);                  m_caster->AddGameObject(pGameObj);          // will removed at spell cancel @@ -6070,14 +6258,14 @@ 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() );      //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel() );      pGameObj->SetSpellId(m_spellInfo->Id); -    DEBUG_LOG("AddObject at SpellEfects.cpp EffectTransmitted\n"); +    DEBUG_LOG("AddObject at SpellEfects.cpp EffectTransmitted");      //m_caster->AddGameObject(pGameObj);      //m_ObjToDel.push_back(pGameObj); @@ -6091,9 +6279,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.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY))          { -            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() ); @@ -6131,6 +6319,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"); @@ -6138,26 +6348,34 @@ void Spell::EffectSkill(uint32 /*i*/)  void Spell::EffectSummonDemon(uint32 i)  { -    float px = m_targets.m_destX; -    float py = m_targets.m_destY; -    float pz = m_targets.m_destZ; +    float radius = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); -    Creature* Charmed = m_caster->SummonCreature(m_spellInfo->EffectMiscValue[i], px, py, pz, m_caster->GetOrientation(),TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,3600000); -    if (!Charmed) -        return; +    int32 amount = damage > 0 ? damage : 1; -    // might not always work correctly, maybe the creature that dies from CoD casts the effect on itself and is therefore the caster? -    Charmed->SetLevel(m_caster->getLevel()); +    for(int32 count = 0; count < amount; ++count) +    { +        float px, py, pz; +        GetSummonPosition(i, px, py, pz, radius, count); -    // TODO: Add damage/mana/hp according to level +        int32 duration = GetSpellDuration(m_spellInfo); -    if (m_spellInfo->EffectMiscValue[i] == 89)              // Inferno summon -    { -        // Enslave demon effect, without mana cost and cooldown -        m_caster->CastSpell(Charmed, 20882, true);          // FIXME: enslave does not scale with level, level 62+ minions cannot be enslaved +        Creature* Charmed = m_caster->SummonCreature(m_spellInfo->EffectMiscValue[i], px, py, pz, m_caster->GetOrientation(),TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,duration); +        if (!Charmed)                                       // something fatal, not attempt more +            return; + +        // might not always work correctly, maybe the creature that dies from CoD casts the effect on itself and is therefore the caster? +        Charmed->SetLevel(m_caster->getLevel()); -        // Inferno effect -        Charmed->CastSpell(Charmed, 22703, true, 0); +        // TODO: Add damage/mana/hp according to level + +        if (m_spellInfo->EffectMiscValue[i] == 89)          // Inferno summon +        { +            // Enslave demon effect, without mana cost and cooldown +            m_caster->CastSpell(Charmed, 20882, true);      // FIXME: enslave does not scale with level, level 62+ minions cannot be enslaved + +            // Inferno effect +            Charmed->CastSpell(Charmed, 22703, true, 0); +        }      }  } @@ -6199,7 +6417,7 @@ void Spell::EffectStealBeneficialBuff(uint32 i)      if(!unitTarget || unitTarget==m_caster)                 // can't steal from self          return; -    std::vector <Aura *> steal_list; +    std::list <Aura *> steal_list;      // Create dispel mask by dispel type      uint32 dispelMask  = GetDispellMask( DispelType(m_spellInfo->EffectMiscValue[i]) );      Unit::AuraMap const& auras = unitTarget->GetAuras(); @@ -6209,53 +6427,38 @@ void Spell::EffectStealBeneficialBuff(uint32 i)          if (aur && (1<<aur->GetSpellProto()->Dispel) & dispelMask)          {              // Need check for passive? this -            if (aur->IsPositive() && !aur->IsPassive()) +            if (aur->IsPositive() && !aur->IsPassive() && !(aur->GetSpellProto()->AttributesEx4 & SPELL_ATTR_EX4_NOT_STEALABLE))                  steal_list.push_back(aur);          }      }      // Ok if exist some buffs for dispel try dispel it -    if (!steal_list.empty()) +    if (uint32 list_size = steal_list.size())      { -        std::list < std::pair<uint32,uint64> > success_list; -        int32 list_size = steal_list.size(); +        std::list < Aura * > success_list; +          // dispel N = damage buffs (or while exist buffs for dispel) -        for (int32 count=0; count < damage && list_size > 0; ++count) +        for (int32 count=0; count < damage && list_size > 0; ++count, list_size = steal_list.size())          {              // Random select buff for dispel -          Aura *aur = steal_list[m_caster->GetMap()->urand(0, list_size-1)]; -            // Not use chance for steal -            // TODO possible need do it -            success_list.push_back( std::pair<uint32,uint64>(aur->GetId(),aur->GetCasterGUID())); - -            // Remove buff from list for prevent doubles -            for (std::vector<Aura *>::iterator j = steal_list.begin(); j != steal_list.end(); ) -            { -                Aura *stealed = *j; -                if (stealed->GetId() == aur->GetId() && stealed->GetCasterGUID() == aur->GetCasterGUID()) -                { -                    j = steal_list.erase(j); -                    --list_size; -                } -                else -                    ++j; -            } +            std::list < Aura * > ::iterator itr = steal_list.begin(); +            for (uint32 i=urand(0, list_size-1);i>0;--i) +                 itr++; +            success_list.push_back(*itr); +            steal_list.erase(itr);          } -        // Really try steal and send log -        if (!success_list.empty()) +        if (success_list.size())          { -            int32 count = success_list.size(); -            WorldPacket data(SMSG_SPELLSTEALLOG, 8+8+4+1+4+count*5); +            WorldPacket data(SMSG_SPELLSTEALLOG, 8+8+4+1+4+damage*5);              data.append(unitTarget->GetPackGUID());  // Victim GUID              data.append(m_caster->GetPackGUID());    // Caster GUID              data << uint32(m_spellInfo->Id);         // dispel spell id              data << uint8(0);                        // not used -            data << uint32(count);                   // count -            for (std::list<std::pair<uint32,uint64> >::iterator j = success_list.begin(); j != success_list.end(); ++j) +            data << uint32(success_list.size());     // count +            for (std::list < Aura * > ::iterator itr = success_list.begin();itr!=success_list.end();++itr)              { -                SpellEntry const* spellInfo = sSpellStore.LookupEntry(j->first); -                data << uint32(spellInfo->Id);       // Spell Id +                data << uint32((*itr)->GetId());       // Spell Id                  data << uint8(0);                    // 0 - steals !=0 transfers -                unitTarget->RemoveAurasDueToSpellBySteal(spellInfo->Id, j->second, m_caster); +                unitTarget->RemoveAurasDueToSpellBySteal((*itr)->GetId(), (*itr)->GetCasterGUID(), m_caster);              }              m_caster->SendMessageToSet(&data, true);          } @@ -6267,7 +6470,15 @@ void Spell::EffectKillCredit(uint32 i)      if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)          return; -    ((Player*)unitTarget)->KilledMonster(m_spellInfo->EffectMiscValue[i], 0); +    int32 creatureEntry = m_spellInfo->EffectMiscValue[i]; +    if(!creatureEntry) +    { +        if(m_spellInfo->Id == 42793) // Burn Body +            creatureEntry = 24008; // Fallen Combatant +    } + +    if(creatureEntry) +        ((Player*)unitTarget)->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);  }  void Spell::EffectQuestFail(uint32 i) @@ -6278,9 +6489,149 @@ 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(100, unitTarget->GetGUID()); +        m_caster->SetReducedThreatPercent((uint32)damage, unitTarget->GetGUID()); +} + +void Spell::EffectWMODamage(uint32 /*i*/) +{ +    if(gameObjTarget && gameObjTarget->GetGoType() == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING) +        gameObjTarget->TakenDamage((uint32)damage); +} + +void Spell::EffectWMORepair(uint32 /*i*/) +{ +    if(gameObjTarget && gameObjTarget->GetGoType() == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING) +        gameObjTarget->Rebuild(); +} + +void Spell::SummonGuardian(uint32 entry, SummonPropertiesEntry const *properties) +{ +    Unit *caster = m_originalCaster; +    if(caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem()) +        caster = ((Totem*)caster)->GetOwner(); +    if(!caster) +        return; + +    // in another case summon new +    uint32 level = caster->getLevel(); + +    // level of pet summoned using engineering item based at engineering skill level +    if(m_CastItem && caster->GetTypeId() == TYPEID_PLAYER) +    { +        ItemPrototype const *proto = m_CastItem->GetProto(); +        if(proto && proto->RequiredSkill == SKILL_ENGINERING) +        { +            uint16 skill202 = ((Player*)caster)->GetSkillValue(SKILL_ENGINERING); +            if(skill202) +            { +                level = skill202/5; +            } +        } +    } + +    //float radius = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); +    float radius = 5.0f; +    int32 amount = damage > 0 ? damage : 1; +    switch(m_spellInfo->Id) +    { +        case 1122: // Inferno +        case 18662: // Curse of Doom +            amount = 1; +            break; +    } +    int32 duration = GetSpellDuration(m_spellInfo); +    TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN; +    Map *map = caster->GetMap(); + +    for(int32 count = 0; count < amount; ++count) +    { +        float px, py, pz; +        GetSummonPosition(0, px, py, pz, radius, count); + +        TempSummon *summon = map->SummonCreature(entry, px, py, pz, m_caster->GetOrientation(), properties, duration, caster); +        if(!summon) +            return; + +        if(summon->HasSummonMask(SUMMON_MASK_GUARDIAN)) +            ((Guardian*)summon)->InitStatsForLevel(level); + +        summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); + +        summon->AI()->EnterEvadeMode(); +    }  } +void Spell::GetSummonPosition(uint32 i, float &x, float &y, float &z, float radius, uint32 count) +{ +    if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) +    { +        // Summon 1 unit in dest location +        if (count == 0) +        { +            x = m_targets.m_destX; +            y = m_targets.m_destY; +            z = m_targets.m_destZ; +        } +        // Summon in random point all other units if location present +        else +        { +            //This is a workaround. Do not have time to write much about it +            switch(m_spellInfo->EffectImplicitTargetA[i]) +            { +                case TARGET_MINION: +                case TARGET_DEST_CASTER_RANDOM: +                    m_caster->GetGroundPointAroundUnit(x, y, z, radius * rand_norm(), rand_norm()*2*M_PI); +                    break; +                case TARGET_DEST_DEST_RANDOM: +                case TARGET_DEST_TARGET_RANDOM: +                    m_caster->GetRandomPoint(m_targets.m_destX,m_targets.m_destY,m_targets.m_destZ,radius,x,y,z); +                    break; +                default: +                    x = m_targets.m_destX; +                    y = m_targets.m_destY; +                    z = m_targets.m_destZ; +                    break; +            } +        } +    } +    // Summon if dest location not present near caster +    else +        m_caster->GetClosePoint(x,y,z,3.0f); +} + +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); +}
\ No newline at end of file  | 
