aboutsummaryrefslogtreecommitdiff
path: root/src/game/SpellEffects.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/SpellEffects.cpp')
-rw-r--r--src/game/SpellEffects.cpp4250
1 files changed, 2304 insertions, 1946 deletions
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index f2ea33c5cc4..725da3ee565 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.2f);
+ }
+ // Counterattack
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x00080000)
{
- damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2);
+ damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f);
}
// Arcane Shot
- else if((m_spellInfo->SpellFamilyFlags & 0x00000800) && m_spellInfo->maxLevel > 0)
+ else if((m_spellInfo->SpellFamilyFlags[0] & 0x00000800) && m_spellInfo->maxLevel > 0)
{
- damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.15);
+ damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.15f);
}
// Steady Shot
- else if(m_spellInfo->SpellFamilyFlags & 0x100000000LL)
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x1)
{
- int32 base = 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,95 @@ 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;
+ }
+ // Scourge Strike
+ else if(m_spellInfo->SpellFamilyFlags[1] & 0x8000000)
+ {
+ m_damage += int32(m_spellInfo->CalculateSimpleValue(0)*m_spellInfo->CalculateSimpleValue(1) * damage * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 10000);
+ 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 +1932,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 +1952,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 +1978,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 +1999,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 +2012,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 +2033,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 +2074,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 +2085,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 +2100,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 +2109,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,37 +2134,11 @@ 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;
- }
- }
+ // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
+ // Needed by freezing arrow and few other spells
+ if (m_caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->CategoryRecoveryTime && spellInfo->CategoryRecoveryTime
+ && m_spellInfo->Category == spellInfo->Category)
+ ((Player*)m_caster)->RemoveSpellCooldown(spellInfo->Id);
// some triggered spells must be casted instantly (for example, if next effect case instant kill caster)
bool instant = false;
@@ -1995,12 +2178,71 @@ 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 );
+ // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
+ // Needed by freezing arrow and few other spells
+ if (m_caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->CategoryRecoveryTime && spellInfo->CategoryRecoveryTime
+ && m_spellInfo->Category == spellInfo->Category)
+ ((Player*)m_caster)->RemoveSpellCooldown(spellInfo->Id);
- SpellCastTargets targets;
- targets.setDestination(m_targets.m_destX,m_targets.m_destY,m_targets.m_destZ);
- spell->m_CastItem = m_CastItem;
- spell->prepare(&targets, NULL);
+ m_caster->CastSpell(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, spellInfo->Id, true, m_CastItem, 0, m_originalCasterGUID);
+}
+
+void Spell::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 +2256,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 +2265,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 +2277,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 +2292,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 +2337,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 +2370,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 +2429,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 +2439,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 +2472,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 +2527,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 +2612,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 +2632,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 +2656,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 +2693,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 +2711,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 +2762,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 +2770,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 +2778,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 +2836,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;
@@ -2702,8 +2868,6 @@ void Spell::EffectEnergize(uint32 i)
if(damage < 0)
return;
- Powers power = Powers(m_spellInfo->EffectMiscValue[i]);
-
if(unitTarget->GetMaxPower(power) == 0)
return;
@@ -2747,7 +2911,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 +2935,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 +2975,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 +3015,8 @@ void Spell::SendLoot(uint64 guid, LootType loottype)
gameObjTarget->TriggeringLinkedGameObject(trapEntry,m_caster);
// Don't return, let loots been taken
+ default:
+ break;
}
}
@@ -2857,7 +3024,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 +3034,6 @@ void Spell::EffectOpenLock(uint32 /*i*/)
Player* player = (Player*)m_caster;
- LootType loottype = LOOT_CORPSE;
uint32 lockId = 0;
uint64 guid = 0;
@@ -2879,7 +3045,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 +3057,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 +3084,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*/);
+ SendLoot(guid, LOOT_SKINNING);
- uint32 reqSkillValue = lockInfo->requiredminingskill;
-
- if(lockInfo->requiredlockskill) // required pick lock skill applying
- {
- if(SkillId != SKILL_LOCKPICKING) // wrong skill (cheating?)
- {
- SendCastResult(SPELL_FAILED_FIZZLE);
- return;
- }
-
- reqSkillValue = lockInfo->requiredlockskill;
- }
- else if(SkillId == SKILL_LOCKPICKING) // apply picklock skill to wrong target
- {
- SendCastResult(SPELL_FAILED_BAD_TARGETS);
- return;
- }
-
- if ( SkillId )
+ // not allow use skill grow at item base open
+ if(!m_CastItem && skillId != SKILL_NONE)
{
- 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 +3144,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 +3162,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 +3180,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 +3198,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 +3228,183 @@ 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;
+
+ 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;
+
+ //vehicle->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, m_caster->GetGUID());
+ if(m_originalCaster)
+ vehicle->setFaction(m_originalCaster->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);
- spawnCreature->SetUInt32Value(UNIT_NPC_FLAGS, 0);
- spawnCreature->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, 0);
- spawnCreature->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
+ summon->AI()->EnterEvadeMode();
- std::string name = owner->GetName();
- name.append(petTypeSuffix[spawnCreature->getPetType()]);
- spawnCreature->SetName( name );
+ 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 +3422,8 @@ void Spell::EffectLearnSpell(uint32 i)
Player *player = (Player*)unitTarget;
- uint32 spellToLearn = (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) ? damage : m_spellInfo->EffectTriggerSpell[i];
- player->learnSpell(spellToLearn);
+ uint32 spellToLearn = ((m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) || (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN_PET)) ? damage : m_spellInfo->EffectTriggerSpell[i];
+ player->learnSpell(spellToLearn,false);
sLog.outDebug( "Spell: Player %u have learned spell %u from NpcGUID=%u", player->GetGUIDLow(), spellToLearn, m_caster->GetGUIDLow() );
}
@@ -3252,8 +3433,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 +3442,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 +3457,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 +3528,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 +3537,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 +3578,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 +3596,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 +3606,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 +3616,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 +3632,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 +3644,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 +3670,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 +3702,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 +3711,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 +3760,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 +3901,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 +3934,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*/)
@@ -3915,24 +3972,27 @@ void Spell::EffectTameCreature(uint32 /*i*/)
finish();
Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget,m_spellInfo->Id);
- if(!pet) return;
+ if(!pet) // in versy specific state like near world end/etc.
+ return;
// kill original creature
creatureTarget->setDeathState(JUST_DIED);
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 +4012,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 +4060,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 +4071,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 +4094,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 +4102,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 +4123,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 +4141,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 +4156,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 +4165,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 +4188,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 +4198,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 +4300,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 +4317,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 +4386,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,23 +4406,13 @@ void Spell::EffectHealMaxHealth(uint32 /*i*/)
if(!unitTarget->isAlive())
return;
- uint32 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
-
- // Lay on Hands
- if(m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && m_spellInfo->SpellFamilyFlags & 0x0000000000008000)
- {
- if(!m_originalCaster)
- return;
- addhealth = addhealth > m_originalCaster->GetMaxHealth() ? m_originalCaster->GetMaxHealth() : addhealth;
- uint32 LoHamount = unitTarget->GetHealth() + m_originalCaster->GetMaxHealth();
- LoHamount = LoHamount > unitTarget->GetMaxHealth() ? unitTarget->GetMaxHealth() : LoHamount;
- unitTarget->SetHealth(LoHamount);
- }
+ int32 addhealth;
+ if(m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN) // Lay on Hands
+ addhealth = m_caster->GetMaxHealth();
else
- unitTarget->SetHealth(unitTarget->GetMaxHealth());
-
+ 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)
@@ -4384,7 +4433,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);
@@ -4403,7 +4452,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;
@@ -4411,19 +4460,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)...
@@ -4464,9 +4513,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);
@@ -4485,450 +4534,768 @@ 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;
+ }*/
+ // Draw Soul
+ case 40904:
+ {
+ if(!unitTarget)
+ return;
+
+ unitTarget->CastSpell(m_caster, 40903, true);
break;
- case 3:
- iTmpSpellId = 26274;
+ }
+ case 48025: // Headless Horseman's Mount
+ {
+ if(!unitTarget)
+ return;
+
+ switch(((Player*)unitTarget)->GetBaseSkillValue(762))
+ {
+ case 75: unitTarget->CastSpell(unitTarget, 51621, true); break;;
+ case 150: unitTarget->CastSpell(unitTarget, 48024, true); break;
+ case 225: unitTarget->CastSpell(unitTarget, 51617, true); break;
+ case 300: unitTarget->CastSpell(unitTarget, 48023, true); break;
+ default: break;
+ }
break;
- }
+ }
+ case 47977: // Magic Broom
+ {
+ if(!unitTarget)
+ return;
- unitTarget->CastSpell(unitTarget, iTmpSpellId, true);
+ 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;
- return;
- }
+ int bag=19;
+ int slot=0;
+ Item* item = NULL;
- // Bending Shinbone
- case 8856:
- {
- if(!itemTarget && m_caster->GetTypeId()!=TYPEID_PLAYER)
- return;
+ 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;
- uint32 spell_id = 0;
- switch(m_caster->GetMap()->urand(1,5))
- {
- case 1: spell_id = 8854; break;
- default: spell_id = 8855; break;
- }
+ unitTarget->CastSpell(unitTarget, 44870, true);
+ break;
+ }
+ // spell of Brutallus - Stomp
+ case 45185:
+ {
+ if(!unitTarget)
+ return;
- m_caster->CastSpell(m_caster,spell_id,true,NULL);
- return;
- }
+ if(unitTarget->HasAura(46394)) // spell of Brutallus - Burn
+ unitTarget->RemoveAurasDueToSpell(46394);
- // 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)
+ 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;
+ case 52479: // Gift of the Harvester
+ if(unitTarget && m_originalCaster)
+ m_originalCaster->CastSpell(unitTarget, urand(0, 1) ? damage : 52505, true);
+ 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;
}
}
@@ -4944,7 +5311,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)
{
@@ -4964,9 +5331,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);
}
}
@@ -4999,6 +5366,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;
@@ -5024,11 +5392,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;
@@ -5037,7 +5406,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);
@@ -5045,9 +5414,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);
@@ -5066,8 +5435,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*/)
@@ -5093,7 +5462,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();
}
@@ -5106,15 +5475,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);
}
@@ -5137,89 +5506,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);
+ }
}
}
@@ -5260,8 +5580,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);
}
}
@@ -5293,7 +5613,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)
@@ -5303,7 +5623,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();
@@ -5313,15 +5634,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*/)
@@ -5329,13 +5650,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)
@@ -5357,18 +5678,21 @@ 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();
+ if(obj)
+ {
+ // Recast case - null spell id to make auras not be removed on object remove from world
+ if (m_spellInfo->Id == obj->GetSpellId())
+ obj->SetSpellId(0);
+ obj->Delete();
+ }
m_caster->m_ObjectSlot[slot] = 0;
}
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)
{
@@ -5378,10 +5702,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;
@@ -5389,14 +5714,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();
}
@@ -5473,18 +5798,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)
@@ -5496,7 +5817,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;
@@ -5535,11 +5856,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);
}
@@ -5559,7 +5876,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)
@@ -5653,97 +5970,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)
{
@@ -5756,31 +5987,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)
@@ -5788,38 +6014,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)
@@ -5834,7 +6029,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
@@ -5853,22 +6048,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*/)
@@ -5883,39 +6077,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)
@@ -5929,7 +6127,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;
}
@@ -5937,8 +6135,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)
@@ -5952,7 +6150,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;
}
@@ -5963,8 +6161,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*/)
@@ -5987,7 +6185,7 @@ void Spell::EffectTransmitted(uint32 effIndex)
return;
}
- float fx,fy,fz;
+ float fx, fy, fz;
if(m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)
{
@@ -5998,23 +6196,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);
@@ -6022,18 +6221,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;
@@ -6046,16 +6245,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;
@@ -6063,12 +6258,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
@@ -6083,14 +6278,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);
@@ -6104,9 +6299,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() );
@@ -6144,6 +6339,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");
@@ -6151,26 +6368,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());
+
+ // TODO: Add damage/mana/hp according to level
- // Inferno effect
- Charmed->CastSpell(Charmed, 22703, true, 0);
+ 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);
+ }
}
}
@@ -6212,7 +6437,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();
@@ -6222,53 +6447,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);
}
@@ -6280,7 +6490,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)
@@ -6291,9 +6509,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