/*
* Ascent MMORPG Server
* Copyright (C) 2005-2007 Ascent Team
*
* 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
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#include "StdAfx.h"
pSpellEffect SpellEffectsHandler[TOTAL_SPELL_EFFECTS]={
&Spell::SpellEffectNULL,//SPELL_EFFECT_NULL - 0
&Spell::SpellEffectInstantKill,//SPELL_EFFECT_INSTAKILL - 1
&Spell::SpellEffectSchoolDMG,//SPELL_EFFECT_SCHOOL_DAMAGE - 2
&Spell::SpellEffectDummy,//SPELL_EFFECT_DUMMY - 3
&Spell::SpellEffectNULL,//SPELL_EFFECT_PORTAL_TELEPORT - 4
&Spell::SpellEffectTeleportUnits,//SPELL_EFFECT_TELEPORT_UNITS - 5
&Spell::SpellEffectApplyAura,//SPELL_EFFECT_APPLY_AURA - 6
&Spell::SpellEffectEnvironmentalDamage,//SPELL_EFFECT_ENVIRONMENTAL_DAMAGE - 7
&Spell::SpellEffectPowerDrain,//SPELL_EFFECT_POWER_DRAIN - 8
&Spell::SpellEffectHealthLeech,//SPELL_EFFECT_HEALTH_LEECH - 9
&Spell::SpellEffectHeal,//SPELL_EFFECT_HEAL - 10
&Spell::SpellEffectNULL,//SPELL_EFFECT_BIND - 11
&Spell::SpellEffectNULL,//SPELL_EFFECT_PORTAL - 12
&Spell::SpellEffectNULL,//SPELL_EFFECT_RITUAL_BASE - 13
&Spell::SpellEffectNULL,//SPELL_EFFECT_RITUAL_SPECIALIZE - 14
&Spell::SpellEffectNULL,//SPELL_EFFECT_RITUAL_ACTIVATE_PORTAL - 15
&Spell::SpellEffectQuestComplete,//SPELL_EFFECT_QUEST_COMPLETE - 16
&Spell::SpellEffectWeapondamageNoschool,//SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL - 17
&Spell::SpellEffectResurrect,//SPELL_EFFECT_RESURRECT - 18
&Spell::SpellEffectAddExtraAttacks,//SPELL_EFFECT_ADD_EXTRA_ATTACKS - 19
&Spell::SpellEffectDodge,//SPELL_EFFECT_DODGE - 20
&Spell::SpellEffectNULL,//SPELL_EFFECT_EVADE - 21
&Spell::SpellEffectParry,//SPELL_EFFECT_PARRY - 22
&Spell::SpellEffectBlock,//SPELL_EFFECT_BLOCK - 23
&Spell::SpellEffectCreateItem,//SPELL_EFFECT_CREATE_ITEM - 24
&Spell::SpellEffectWeapon,//SPELL_EFFECT_WEAPON - 25
&Spell::SpellEffectDefense,//SPELL_EFFECT_DEFENSE - 26
&Spell::SpellEffectPersistentAA,//SPELL_EFFECT_PERSISTENT_AREA_AURA - 27
&Spell::SpellEffectSummon,//SPELL_EFFECT_SUMMON - 28
&Spell::SpellEffectLeap,//SPELL_EFFECT_LEAP - 29
&Spell::SpellEffectEnergize,//SPELL_EFFECT_ENERGIZE - 30
&Spell::SpellEffectWeaponDmgPerc,//SPELL_EFFECT_WEAPON_PERCENT_DAMAGE - 31
&Spell::SpellEffectTriggerMissile,//SPELL_EFFECT_TRIGGER_MISSILE - 32
&Spell::SpellEffectOpenLock,//SPELL_EFFECT_OPEN_LOCK - 33
&Spell::SpellEffectTranformItem,//SPELL_EFFECT_TRANSFORM_ITEM - 34
&Spell::SpellEffectApplyAA,//SPELL_EFFECT_APPLY_AREA_AURA - 35
&Spell::SpellEffectLearnSpell,//SPELL_EFFECT_LEARN_SPELL - 36
&Spell::SpellEffectSpellDefense,//SPELL_EFFECT_SPELL_DEFENSE - 37
&Spell::SpellEffectDispel,//SPELL_EFFECT_DISPEL - 38
&Spell::SpellEffectNULL,//SPELL_EFFECT_LANGUAGE - 39
&Spell::SpellEffectDualWield,//SPELL_EFFECT_DUAL_WIELD - 40
&Spell::SpellEffectSummonWild,//SPELL_EFFECT_SUMMON_WILD - 41
&Spell::SpellEffectSummonGuardian,//SPELL_EFFECT_SUMMON_GUARDIAN - 42
&Spell::SpellEffectNULL,//SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER - 43
&Spell::SpellEffectSkillStep,//SPELL_EFFECT_SKILL_STEP - 44
&Spell::SpellEffectAddHonor,//SPELL_ADD_HONOR - 45
&Spell::SpellEffectSpawn,//SPELL_EFFECT_SPAWN - 46
&Spell::SpellEffectNULL,//SPELL_EFFECT_TRADE_SKILL - 47
&Spell::SpellEffectNULL,//SPELL_EFFECT_STEALTH - 48
&Spell::SpellEffectNULL,//SPELL_EFFECT_DETECT - 49
&Spell::SpellEffectSummonObject,//SPELL_EFFECT_SUMMON_OBJECT - 50
&Spell::SpellEffectNULL,//SPELL_EFFECT_FORCE_CRITICAL_HIT - 51 NA
&Spell::SpellEffectNULL,//SPELL_EFFECT_GUARANTEE_HIT - 52 NA
&Spell::SpellEffectEnchantItem,//SPELL_EFFECT_ENCHANT_ITEM - 53
&Spell::SpellEffectEnchantItemTemporary,//SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY - 54
&Spell::SpellEffectTameCreature,//SPELL_EFFECT_TAMECREATURE - 55
&Spell::SpellEffectSummonPet,//SPELL_EFFECT_SUMMON_PET - 56
&Spell::SpellEffectLearnPetSpell,//SPELL_EFFECT_LEARN_PET_SPELL - 57
&Spell::SpellEffectWeapondamage,//SPELL_EFFECT_WEAPON_DAMAGE - 58
&Spell::SpellEffectOpenLockItem,//SPELL_EFFECT_OPEN_LOCK_ITEM - 59
&Spell::SpellEffectProficiency,//SPELL_EFFECT_PROFICIENCY - 60
&Spell::SpellEffectSendEvent,//SPELL_EFFECT_SEND_EVENT - 61
&Spell::SpellEffectPowerBurn,//SPELL_EFFECT_POWER_BURN - 62
&Spell::SpellEffectThreat,//SPELL_EFFECT_THREAT - 63
&Spell::SpellEffectTriggerSpell,//SPELL_EFFECT_TRIGGER_SPELL - 64
&Spell::SpellEffectHealthFunnel,//SPELL_EFFECT_HEALTH_FUNNEL - 65
&Spell::SpellEffectPowerFunnel,//SPELL_EFFECT_POWER_FUNNEL - 66
&Spell::SpellEffectHealMaxHealth,//SPELL_EFFECT_HEAL_MAX_HEALTH - 67
&Spell::SpellEffectInterruptCast,//SPELL_EFFECT_INTERRUPT_CAST - 68
&Spell::SpellEffectDistract,//SPELL_EFFECT_DISTRACT - 69
&Spell::SpellEffectNULL,//SPELL_EFFECT_PULL - 70
&Spell::SpellEffectPickpocket,//SPELL_EFFECT_PICKPOCKET - 71
&Spell::SpellEffectAddFarsight,//SPELL_EFFECT_ADD_FARSIGHT - 72
&Spell::SpellEffectSummonPossessed,//SPELL_EFFECT_SUMMON_POSSESSED - 73
&Spell::SpellEffectCreateSummonTotem,//SPELL_EFFECT_SUMMON_TOTEM - 74
&Spell::SpellEffectHealMechanical,//SPELL_EFFECT_HEAL_MECHANICAL - 75
&Spell::SpellEffectSummonObjectWild,//SPELL_EFFECT_SUMMON_OBJECT_WILD - 76
&Spell::SpellEffectScriptEffect,//SPELL_EFFECT_SCRIPT_EFFECT - 77
&Spell::SpellEffectNULL,//SPELL_EFFECT_ATTACK - 78
&Spell::SpellEffectSanctuary,//SPELL_EFFECT_SANCTUARY - 79
&Spell::SpellEffectAddComboPoints,//SPELL_EFFECT_ADD_COMBO_POINTS - 80
&Spell::SpellEffectNULL,//SPELL_EFFECT_CREATE_HOUSE - 81
&Spell::SpellEffectNULL,//SPELL_EFFECT_BIND_SIGHT - 82
&Spell::SpellEffectDuel,//SPELL_EFFECT_DUEL - 83
&Spell::SpellEffectStuck,//SPELL_EFFECT_STUCK - 84
&Spell::SpellEffectSummonPlayer,//SPELL_EFFECT_SUMMON_PLAYER - 85
&Spell::SpellEffectActivateObject,//SPELL_EFFECT_ACTIVATE_OBJECT - 86
&Spell::SpellEffectSummonTotem,//SPELL_EFFECT_SUMMON_TOTEM_SLOT1 - 87
&Spell::SpellEffectSummonTotem,//SPELL_EFFECT_SUMMON_TOTEM_SLOT2 - 88
&Spell::SpellEffectSummonTotem,//SPELL_EFFECT_SUMMON_TOTEM_SLOT3 - 89
&Spell::SpellEffectSummonTotem,//SPELL_EFFECT_SUMMON_TOTEM_SLOT4 - 90
&Spell::SpellEffectNULL,//SPELL_EFFECT_THREAT_ALL - 91
&Spell::SpellEffectEnchantHeldItem,//SPELL_EFFECT_ENCHANT_HELD_ITEM - 92
&Spell::SpellEffectNULL,//SPELL_EFFECT_SUMMON_PHANTASM - 93 OLD
&Spell::SpellEffectSelfResurrect,//SPELL_EFFECT_SELF_RESURRECT - 94
&Spell::SpellEffectSkinning,//SPELL_EFFECT_SKINNING - 95
&Spell::SpellEffectCharge,//SPELL_EFFECT_CHARGE - 96
&Spell::SpellEffectSummonCritter,//SPELL_EFFECT_SUMMON_CRITTER - 97
&Spell::SpellEffectKnockBack,//SPELL_EFFECT_KNOCK_BACK - 98
&Spell::SpellEffectDisenchant,//SPELL_EFFECT_DISENCHANT - 99
&Spell::SpellEffectInebriate,//SPELL_EFFECT_INEBRIATE - 100
&Spell::SpellEffectFeedPet,//SPELL_EFFECT_FEED_PET - 101
&Spell::SpellEffectDismissPet,//SPELL_EFFECT_DISMISS_PET - 102
&Spell::SpellEffectReputation,//SPELL_EFFECT_REPUTATION - 103
&Spell::SpellEffectSummonObjectSlot,//SPELL_EFFECT_SUMMON_OBJECT_SLOT1 - 104
&Spell::SpellEffectSummonObjectSlot,//SPELL_EFFECT_SUMMON_OBJECT_SLOT2 - 105
&Spell::SpellEffectSummonObjectSlot,//SPELL_EFFECT_SUMMON_OBJECT_SLOT3 - 106
&Spell::SpellEffectSummonObjectSlot,//SPELL_EFFECT_SUMMON_OBJECT_SLOT4 - 107
&Spell::SpellEffectDispelMechanic,//SPELL_EFFECT_DISPEL_MECHANIC - 108
&Spell::SpellEffectSummonDeadPet,//SPELL_EFFECT_SUMMON_DEAD_PET - 109
&Spell::SpellEffectDestroyAllTotems,//SPELL_EFFECT_DESTROY_ALL_TOTEMS - 110
&Spell::SpellEffectNULL,//SPELL_EFFECT_DURABILITY_DAMAGE - 111
&Spell::SpellEffectSummonDemon,//SPELL_EFFECT_SUMMON_DEMON - 112
&Spell::SpellEffectResurrectNew,//SPELL_EFFECT_RESURRECT_NEW - 113
&Spell::SpellEffectAttackMe,//SPELL_EFFECT_ATTACK_ME - 114
&Spell::SpellEffectNULL,//SPELL_EFFECT_DURABILITY_DAMAGE_PCT - 115
&Spell::SpellEffectSkinPlayerCorpse,//SPELL_EFFECT_SKIN_PLAYER_CORPSE - 116
&Spell::SpellEffectNULL,//SPELL_EFFECT_SPIRIT_HEAL - 117//Not used
&Spell::SpellEffectSkill,//SPELL_EFFECT_SKILL - 118
&Spell::SpellEffectApplyPetAura,//SPELL_EFFECT_APPLY_PET_AURA - 119
&Spell::SpellEffectNULL,//SPELL_EFFECT_TELEPORT_GRAVEYARD - 120//Not used
&Spell::SpellEffectDummyMelee,//SPELL_EFFECT_DUMMYMELEE - 121
&Spell::SpellEffectNULL,//unknown - 122 //not used
&Spell::SpellEffectNULL,//SPELL_EFFECT_FILMING - 123 // http://www.thottbot.com/?sp=27998: flightpath
&Spell::SpellEffectNULL,//SPELL_EFFECT_PULL - 124 //http://www.thottbot.com/?sp=28337
&Spell::SpellEffectNULL,//unknown - 125 // Reduce Threat by % //http://www.thottbot.com/?sp=32835
&Spell::SpellEffectSpellSteal,//SPELL_EFFECT_SPELL_STEAL - 126 // Steal Beneficial Buff (Magic) //http://www.thottbot.com/?sp=30449
&Spell::SpellEffectProspecting,//unknown - 127 // Search 5 ore of a base metal for precious gems. This will destroy the ore in the process.
&Spell::SpellEffectApplyAura128,//unknown - 128 // Adjust a stats by %: Mod Stat // ITS FLAT
&Spell::SpellEffectNULL,// unknown - 129 // Mod Dmg % (Spells)
&Spell::SpellEffectNULL,// unknown - 130 // http://www.thottbot.com/s34477
&Spell::SpellEffectNULL,// unknown - 131 // test spell
&Spell::SpellEffectNULL,// unknown - 132 // no spells
&Spell::SpellEffectNULL,// SPELL_EFFECT_FORGET_SPECIALIZATION - 133 // http://www.thottbot.com/s36441 // I think this is a gm/npc spell
&Spell::SpellEffectNULL,// unknown - 134 // related to summoning objects and removing them, http://www.thottbot.com/s39161
&Spell::SpellEffectNULL,// unknown - 135 // no spells
&Spell::SpellEffectNULL,// unknown - 136 // http://www.thottbot.com/s41542 and http://www.thottbot.com/s39703
&Spell::SpellEffectNULL,// unknown - 137 // http://www.thottbot.com/s41542
&Spell::SpellEffectNULL,// unknown - 138 // related to superjump or even "*jump" spells http://www.thottbot.com/?e=Unknown%20138
&Spell::SpellEffectNULL,// unknown - 139 // no spells
&Spell::SpellEffectNULL,// unknown - 140 // triggers spell? I think only visual spell triggers
&Spell::SpellEffectNULL,// unknown - 141 // triggers spell, magic one, (Mother spell) http://www.thottbot.com/s41065
&Spell::SpellEffectNULL,// unknown - 142 // triggers some kind of "Put spell on target" thing... (dono for sure) http://www.thottbot.com/s40872 and http://www.thottbot.com/s33076
&Spell::SpellEffectNULL,// unknown - 143 // Master -> deamon effecting spell, http://www.thottbot.com/s25228 and http://www.thottbot.com/s35696
};
void Spell::SpellEffectNULL(uint32 i)
{
sLog.outDebug("Unhandled spell effect %u in spell %u.\n",m_spellInfo->Effect[i],m_spellInfo->Id);
}
void Spell::SpellEffectInstantKill(uint32 i)
{
if(!unitTarget || !unitTarget->isAlive())
return;
//Sacrifice: if spell caster has "void walker" pet, pet dies and spell caster gets a
/*Sacrifices the Voidwalker, giving its owner a shield that will absorb
305 damage for 30 sec. While the shield holds, spellcasting will not be \
interrupted by damage.*/
/*
Demonic Sacrifice
When activated, sacrifices your summoned demon to grant you an effect that lasts
30 minutes. The effect is canceled if any Demon is summoned.
Imp: Increases your Fire damage by 15%.
Voidwalker: Restores 3% of total Health every 4 sec.
Succubus: Increases your Shadow damage by 15%.
Felhunter: Restores 2% of total Mana every 4 sec.
When activated, sacrifices your summoned demon to grant you an effect that lasts $18789d. The effect is canceled if any Demon is summoned.
Imp: Increases your Fire damage by $18789s1%.
Voidwalker: Restores $18790s1% of total Health every $18790t1 sec.
Succubus: Increases your Shadow damage by $18791s1%.
Felhunter: Restores $18792s1% of total Mana every $18792t1 sec.
*/
if(m_spellInfo->NameHash==0x154BC7DB)
{
/* sacrifice */
return;
}
uint32 spellId = m_spellInfo->Id;
switch(spellId)
{
case 3617://Goblin Bomb Suicide
{
if(m_caster->GetTypeId() != TYPEID_UNIT)
break;
Unit *caster = m_caster->GetMapMgr()->GetPlayer(m_caster->GetUInt64Value(UNIT_FIELD_SUMMONEDBY));
caster->summonPet->RemoveFromWorld(false);
delete caster->summonPet;
caster->summonPet = NULL;
}break;
case 7814:
case 7815:
case 7816:
case 7876:
case 7877:
case 7878:
case 11778:
case 11779:
case 11780:
case 15968:
case 15969:
case 18128:
case 18129:
case 20398:
case 20399:
case 20400:
case 20401:
case 20402:
{
}break;
//sacrifise works
case 7812:
case 19438:
case 19440:
case 19441:
case 19442:
case 19443:
{
}break;
case 18788: //Demonic Sacrifice (508745)
uint32 spellid1 = 0;
switch(unitTarget->GetEntry())
{
case 416: //Imp
{
spellid1 = 18789;
}break;
case 417: //Felhunter
{
spellid1 = 18792;
}break;
case 1860: //VoidWalker
{
spellid1 = 18790;
}break;
case 1863: //Succubus
{
spellid1 = 18791;
}break;
case 17252: //felguard
{
spellid1 = 35701;
}break;
}
//now caster gains this buff
if (spellid1 && spellid1 != 0)
{
u_caster->CastSpell(u_caster, sSpellStore.LookupEntry(spellid1), true);
}
}
//instant kill effects don't have a log
//m_caster->SpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, unitTarget->GetUInt32Value(UNIT_FIELD_HEALTH), true);
m_caster->DealDamage(unitTarget, unitTarget->GetUInt32Value(UNIT_FIELD_HEALTH), 0, 0, 0);
}
void Spell::SpellEffectSchoolDMG(uint32 i) // dmg school
{
if(!unitTarget || !unitTarget->isAlive())
return;
if(unitTarget->SchoolImmunityList[m_spellInfo->School])
{
SendCastResult(SPELL_FAILED_IMMUNE);
return;
}
uint32 dmg;
if(m_spellInfo->EffectChainTarget[i])//chain
{
int32 reduce = (int32)(m_spellInfo->dmg_multiplier[i] * 100.0f);
if(reduce && chaindamage)
{
if(m_spellInfo->SpellGroupType && u_caster)
{
SM_FIValue(u_caster->SM_PJumpReduce,&reduce,m_spellInfo->SpellGroupType);
}
chaindamage = chaindamage * reduce / 100;
}
else
{
chaindamage = damage;
}
dmg = chaindamage;
}
else
{
dmg = damage;
switch(m_spellInfo->NameHash)
{
case 0xddaf1ac7: // Ice Lance
if (dmg>300) //dirty bugfix.
dmg = (int32)(damage/2);
break;
case 0x2bc0ae00: // Incinerate -> Deals x-x extra damage if the target is affected by immolate
{
if(unitTarget->HasAurasWithNameHash(0x3dd5c872))
{
// random extra damage
uint32 extra_dmg = 111 + (m_spellInfo->RankNumber * 11) + sRand.randInt(m_spellInfo->RankNumber * 11);
dmg += extra_dmg;
}
}break;
case 0xccc8a100: // Gouge: turns off your combat
{
if(p_caster)
{
p_caster->EventAttackStop();
p_caster->smsg_AttackStop(unitTarget);
}break;
}
case 0xCBC738B8: // Bloodthirst
{
dmg = u_caster->GetAP()*(m_spellInfo->EffectBasePoints[0]+1) / 100;
}
}
}
// check for no more damage left (chains)
if(!dmg) return;
/**************************************************************************
* This handles the correct damage of "Judgement of Command" (all ranks)
*
* note: "unkne" contains flags related to aura's and other scripted stuff
**************************************************************************/
if (m_spellInfo->unkne == 520)
{
if (!unitTarget->IsStunned())
dmg = dmg / 2;
}
if(m_spellInfo->speed > 0)
{
//FIXME:Use this one and check player movement and update distance
//It now only checks the first distance and hits the player after time expires.
//sEventMgr.AddEvent(this, &Spell::_DamageRangeUpdate, (uint32)100, EVENT_SPELL_DAMAGE_HIT, 100, 0);
float dist = m_caster->CalcDistance(unitTarget);
float time = ((dist*1000.0)/m_spellInfo->speed);
if(time <= 100)
m_caster->SpellNonMeleeDamageLog(unitTarget,m_spellInfo->Id, dmg, pSpellId==0);
else
{
damageToHit = dmg;
/*sEventMgr.AddEvent(m_caster, &Object::SpellNonMeleeDamageLog,
unitTarget,m_spellInfo->Id,dmg, EVENT_SPELL_DAMAGE_HIT, uint32(time), 1);*/
sEventMgr.AddEvent(m_caster, &Object::EventSpellDamage, unitTarget->GetGUID(),
m_spellInfo->Id, dmg, EVENT_SPELL_DAMAGE_HIT, uint32(time), 1,EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT);
}
}
else
{
uint32 dmg_type = GetType();
if(dmg_type == SPELL_TYPE_MAGIC)
{
m_caster->SpellNonMeleeDamageLog(unitTarget,m_spellInfo->Id, dmg, pSpellId==0);
}
else
{
if(u_caster)
u_caster->Strike(unitTarget,dmg_type,m_spellInfo,0,0,dmg, pSpellId==0);
}
}
}
void Spell::SpellEffectDummy(uint32 i) // Dummy(Scripted events)
{
//curse of agony(18230) = periodic damage increased in
//flag 2031678
uint32 spellId = m_spellInfo->Id;
// INTERNAL HANDLERS
if(sScriptMgr.CallScriptedDummySpell(spellId, i, this))
return;
switch(spellId)
{
case 18350: /* paladin talent: illumination - gain mana equal to 60% cost of spell. */
{
if(!p_caster) return;
SpellEntry * sp = p_caster->last_heal_spell ? p_caster->last_heal_spell : m_spellInfo;
uint32 cost = float2int32( float( float(sp->manaCost) * 0.6f ) );
SendHealManaSpellOnPlayer(p_caster, p_caster, cost, 0);
cost+=p_caster->GetUInt32Value(UNIT_FIELD_POWER1);
if(cost>p_caster->GetUInt32Value(UNIT_FIELD_MAXPOWER1))
p_caster->SetUInt32Value(UNIT_FIELD_POWER1,p_caster->GetUInt32Value(UNIT_FIELD_MAXPOWER1));
else
p_caster->SetUInt32Value(UNIT_FIELD_POWER1,cost);
}break;
case 34120:
{//steady shot
if(unitTarget)
if(unitTarget->IsDazed())
{
u_caster->SpellNonMeleeDamageLog(unitTarget,spellId,damage,false);
}
}break;
case 1454://life tap
case 1455:
case 1456:
case 11687:
case 11688:
case 11689:
case 27222:
{//converts base+1 points of health into mana
uint32 damage = m_spellInfo->EffectBasePoints[i]+1;
uint32 man = (damage *(100+playerTarget->m_lifetapbonus))/100;
p_caster->DealDamage(playerTarget,damage,0,0,spellId);
playerTarget->ModUInt32Value(UNIT_FIELD_POWER1,man);
if(playerTarget->GetUInt32Value(UNIT_FIELD_POWER1) > playerTarget->GetUInt32Value(UNIT_FIELD_MAXPOWER1))
playerTarget->SetUInt32Value(UNIT_FIELD_POWER1,playerTarget->GetUInt32Value(UNIT_FIELD_MAXPOWER1));
SendHealManaSpellOnPlayer(p_caster, playerTarget, damage, 0);
}break;
case 14185:
{
if(!p_caster) return;
if(p_caster->HasSpell(5277)) p_caster->ClearCooldownForSpell(5277);
if(p_caster->HasSpell(26699)) p_caster->ClearCooldownForSpell(26699);
if(p_caster->HasSpell(2983)) p_caster->ClearCooldownForSpell(2983);
if(p_caster->HasSpell(8696)) p_caster->ClearCooldownForSpell(8696);
if(p_caster->HasSpell(11305)) p_caster->ClearCooldownForSpell(11305);
if(p_caster->HasSpell(1856)) p_caster->ClearCooldownForSpell(1856);
if(p_caster->HasSpell(1857)) p_caster->ClearCooldownForSpell(1857);
if(p_caster->HasSpell(26889)) p_caster->ClearCooldownForSpell(26889);
if(p_caster->HasSpell(14177)) p_caster->ClearCooldownForSpell(14177);
if(p_caster->HasSpell(13750)) p_caster->ClearCooldownForSpell(13750);
if(p_caster->HasSpell(14183)) p_caster->ClearCooldownForSpell(14183);
}break;
case 974:
case 32593:
case 32594:
{
if(!pSpellId) return;
SpellEntry *spellInfo = sSpellStore.LookupEntry(pSpellId);
if(!spellInfo) return;
uint32 heal32 = CalculateEffect(i);
unitTarget=u_caster; // Should heal caster :p
if(heal32)
Heal(heal32);
}break;
case 28730:
{
// for each mana tap, gives you 12 mana
if(!unitTarget) return;
uint32 count = 0;
for(uint32 x = 0; x < MAX_AURAS; ++x)
{
if(unitTarget->m_auras[x] && unitTarget->m_auras[x]->GetSpellId() == 28734)
{
unitTarget->m_auras[x]->Remove();
++count;
}
}
uint32 gain = count * 12;
gain += unitTarget->GetUInt32Value(UNIT_FIELD_POWER1);
uint32 max = unitTarget->GetUInt32Value(UNIT_FIELD_MAXPOWER1);
if(gain > max)
gain = max;
unitTarget->SetUInt32Value(UNIT_FIELD_POWER1, gain);
SendHealManaSpellOnPlayer(p_caster, ((Player*)unitTarget), count*12, 0);
}break;
case 4141:// Summon Myzrael
{
//we need a NPC for this(we don't have it yet:S http://www.thottbot.com/?m=5608)
//when we have the npc we can cast the spell, the spell itself I think summons ENTRY 2755 name:Myzrael
}break;
/*Normal Spells*/
case 6668:// Red Firework
{
// Shoots a firework into the air that bursts into a thousand red stars
}break;
case 8213:// Cooked Deviate Fish
{
}break;
case 8344:// Universal Remote
{
//FIXME:Allows control of a mechanical target for a short time. It may not always work and may just root the machine or make it very very angry. Gnomish engineering at its finest.
}break;
case 9976:// Polly Eats the E.C.A.C.
{
//FIXME: Don't know what this does
}break;
case 10137:// Fizzule's Whistle
{
//FIXME:Blow on the whistle to let Fizzule know you're an ally
//This item comes after a finish of quest at venture co.
//You must whistle this every time you reach there to make Fizzule
//ally to you.
}break;
case 11540:// Blue Firework
{
//Shoots a firework into the air that bursts into a thousand blue stars
}break;
case 11541:// Green Firework
{
//Shoots a firework into the air that bursts into a thousand green stars
}break;
case 11542:// Red Streaks Firework
{
//Shoots a firework into the air that bursts into a thousand red streaks
}break;
case 11543:// Red, White and Blue Firework
{
//Shoots a firework into the air that bursts into red, white and blue stars
}break;
case 11544:// Yellow Rose Firework
{
//Shoots a firework into the air that bursts in a yellow pattern
}break;
case 12151:// Summon Atal'ai Skeleton
{
//FIXME:Add here remove in time event
}break;
case 13535:// Tame Beast
{
}break;
case 13006:// Shrink Ray
{
//FIXME:Schematic is learned from the gnomish engineering trainer. The gnomish/gobblin engineering decision is made when you are lvl40+ and your engineering is 200+. Interestingly, however, when this item fails to shrink the target, it can do a variety of things, such as...
//-Make you bigger (attack power +250)
//-Make you smaller (attack power -250)
//-Make them bigger (same effect as above)
//-Make your entire party bigger
//-Make your entire party smaller
//-Make every attacking enemy bigger
//-Make ever attacking enemy smaller
//Works to your advantage for the most part (about 70% of the time), but don't use in high-pressure situations, unless you're going to die if you don't. Could tip the scales the wrong way.
//Search for spells of this
//13004 - grow <- this one
//13010 - shrink <-this one
//
}break;
case 13180:// Gnomish Mind Control Cap
{
// FIXME:Take control of humanoid target by chance(it can be player)
}break;
case 13278:// Gnomish Death Ray
{
// FIXME:The devices charges over time using your life force and then directs a burst of energy at your opponent
//Drops life
}break;
case 13280:// Gnomish Death Ray
{
//FIXME: Drop life
}break;
case 14537:// Six Demon Bag
{
// FIXME:Does weird things to target infront of you
}break;
case 17816:// Sharp Dresser
{
//Impress others with your fashion sense
}break;
//
case 20425: //Judgement of Command
case 20961: //Judgement of Command
case 20962: //Judgement of Command
case 20967: //Judgement of Command
case 20968: //Judgement of Command
case 27172: //Judgement of Command
{
uint32 SpellID = m_spellInfo->EffectBasePoints[i]+1;
Spell * spell=new Spell(m_caster,sSpellStore.LookupEntry(SpellID),true,NULL);
SpellCastTargets targets;
targets.m_unitTarget = unitTarget->GetGUID();
spell->prepare(&targets);
}break;
case 20577:// Cannibalize
{
if(!p_caster)
return;
bool check = false;
float rad = GetRadius(i);
rad *= rad;
for(Object::InRangeSet::iterator i = p_caster->GetInRangeSetBegin(); i != p_caster->GetInRangeSetEnd(); ++i)
{
if((*i)->GetTypeId() == TYPEID_UNIT)
{
if(static_cast((*i))->getDeathState() == CORPSE)
{
CreatureInfo *cn = static_cast((*i))->GetCreatureName();
if(cn && cn->Type == HUMANOID || cn->Type == UNDEAD)
{
if(p_caster->GetDistance2dSq((*i)) < rad)
{
check = true;
break;
}
}
}
}
}
if(check)
{
p_caster->cannibalize = true;
p_caster->cannibalizeCount = 0;
sEventMgr.AddEvent(p_caster, &Player::EventCannibalize, uint32(7),
EVENT_CANNIBALIZE, 2000, 5,0);
p_caster->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_CANNIBALIZE);
}
}break;
case 21343:// Snowball
{
}break;
case 23074:// Arcanite Dragonling
case 23075:// Mithril Mechanical Dragonling
case 23076:// Mechanical Dragonling
{
//Open it when AI fixed
break;
uint32 entry = 0;
if(m_spellInfo->Id == 23074)
entry = 12473;
else if(m_spellInfo->Id == 23074)
entry = 2678; //FIXME:this is wrong
else
entry = 2678;
//For 1 min
if(u_caster->summonPet)
{
u_caster->summonPet->RemoveFromWorld(false);
delete u_caster->summonPet;
u_caster->summonPet = NULL;
}
CreatureInfo *ci = CreatureNameStorage.LookupEntry(entry);
if(ci)
{
Creature* NewSummon = m_caster->GetMapMgr()->CreateCreature();
// Create
NewSummon->Create( ci->Name, m_caster->GetMapId(),
m_caster->GetPositionX()+(3*(cos(-(M_PI/2)+m_caster->GetOrientation()))), m_caster->GetPositionY()+(3*(cos(-(M_PI/2)+m_caster->GetOrientation()))), m_caster->GetPositionZ(), m_caster->GetOrientation());
NewSummon->SetInstanceID(m_caster->GetInstanceID());
// Fields
NewSummon->SetUInt32Value(UNIT_FIELD_LEVEL,m_caster->GetUInt32Value(UNIT_FIELD_LEVEL));
NewSummon->SetUInt32Value(UNIT_FIELD_DISPLAYID, ci->DisplayID);
NewSummon->SetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID, ci->DisplayID);
NewSummon->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, m_caster->GetGUID());
NewSummon->SetUInt64Value(UNIT_FIELD_CREATEDBY, m_caster->GetGUID());
NewSummon->SetUInt32Value(UNIT_NPC_FLAGS , 0);
NewSummon->SetUInt32Value(UNIT_FIELD_HEALTH , 1);
NewSummon->SetUInt32Value(UNIT_FIELD_MAXHEALTH , 1);
NewSummon->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, m_caster->GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE));
NewSummon->SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);//m_caster->GetFloatValue(OBJECT_FIELD_SCALE_X));
NewSummon->SetUInt32Value(UNIT_FIELD_BYTES_0, 2048);
NewSummon->SetUInt32Value(UNIT_FIELD_BASEATTACKTIME, 2000);//ci->baseattacktime);
NewSummon->SetUInt32Value(UNIT_FIELD_BASEATTACKTIME+1, 2000);//ci->rangeattacktime);
NewSummon->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 0.1f);
NewSummon->SetFloatValue(UNIT_FIELD_COMBATREACH,m_caster->GetFloatValue(UNIT_FIELD_COMBATREACH));
NewSummon->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
NewSummon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
NewSummon->SetUInt32Value(OBJECT_FIELD_ENTRY, ci->Id);
NewSummon->SetZoneId(m_caster->GetZoneId());
//Setting faction
NewSummon->_setFaction();
// Add To World
//NewSummon->AddToWorld();
NewSummon->PushToWorld(m_caster->GetMapMgr());
NewSummon->GetAIInterface()->Init(NewSummon,AITYPE_PET,MOVEMENTTYPE_NONE,u_caster);
NewSummon->GetAIInterface()->SetUnitToFollow(u_caster);
NewSummon->GetAIInterface()->SetUnitToFollowAngle(-(M_PI/2));
NewSummon->GetAIInterface()->SetFollowDistance(3.0f);
u_caster->summonPet = NewSummon;
u_caster->SetUInt64Value(UNIT_FIELD_PETNUMBER,NewSummon->GetGUID());
sEventMgr.AddEvent(u_caster, &Unit::EventSummonPetExpire, EVENT_SUMMON_PET_EXPIRE, 60000, 1,0);
}
}break;
case 23645:// Hourglass Sand
{
//Indeed used at the Chromo fight in BWL. Chromo has a stunning debuff, uncleansable, unless you have hourglass sand. This debuff will stun you every 4 seconds, for 4 seconds. It is resisted a lot though. Mage's and other casters usually have to do this fight with the debuff on, healers, tanks and hunters will get some to cure themselves from the debuff
}break;
case 23725:// Gift of Life
{
if(!playerTarget)
break;
SpellCastTargets tgt;
tgt.m_unitTarget = playerTarget->GetGUID();
SpellEntry * inf =sSpellStore.LookupEntry(23782);
Spell * spe = new Spell(u_caster,inf,true,NULL);
spe->prepare(&tgt);
}break;
case 12975:// Last Stand
{
if(!playerTarget)
break;
SpellCastTargets tgt;
tgt.m_unitTarget = playerTarget->GetGUID();
SpellEntry * inf =sSpellStore.LookupEntry(12976);
Spell * spe = new Spell(u_caster,inf,true,NULL);
spe->prepare(&tgt);
}break;
case 24325:// Pagle's Point Cast - Create Mudskunk Lure
{
//FIXME:Load with 5 Zulian Mudskunks, and then cast from Pagle's Point in Zul'Gurub
}
case 24392:// Frosty Zap
{
//FIXME:Your Frostbolt spells have a 6% chance to restore 50 mana when cast.
//damage == 50
}break;
case 25822:// Firecrackers
{
//FIXME:Find firecrackers
}break;
case 26373:// Lunar Invititation
{
//FIXME: Teleports the caster from within Greater Moonlight
}break;
case 26374:// Elune's Candle
{
//FIXME:Shoots a firework at target
}break;
case 26889:// Give Friendship Bracelet
{
//Give to a Heartbroken player to cheer them up
//laugh emote
}break;
case 27662:// Throw Cupid's Dart
{
//FIXME:Shoot a player, and Kwee Q. Peddlefeet will find them! (Only works on players with no current critter pets.)
}break;
case 28414:// Call Ashbringer
{
//http://www.thottbot.com/?i=53974
}break;
case 28806:// Toss Fuel on Bonfire
{
//FIXME:Dont know what this dummy does
}break;
/*Normal Spells*/
/* Quest Related */
case 11536:
{
WorldPacket data(12);
data.SetOpcode(SMSG_PLAY_OBJECT_SOUND);
data << uint32(6197) << unitTarget->GetGUID();
p_caster->SendMessageToSet(&data, true);
sQuestMgr.OnPlayerKill(p_caster, ((Creature*)unitTarget)); // this should increment in quest log
}break;
case 19938:
{
if(((Creature*)unitTarget)->GetEntry() == 10556)
{
WorldPacket data(12);
data.SetOpcode(SMSG_PLAY_OBJECT_SOUND);
data << uint32(6197) << unitTarget->GetGUID();
p_caster->SendMessageToSet(&data, true);
sQuestMgr.OnPlayerKill(p_caster, ((Creature*)unitTarget)); // this should increment in quest log
// Send chat message
char msg[100];
snprintf(msg, 100, "Ow! Ok, I'll get back to work, %s", p_caster->GetName());
unitTarget->SendChatMessage(CHAT_MSG_MONSTER_SAY, LANG_UNIVERSAL, msg);
}
else
{
SendCastResult(SPELL_FAILED_BAD_TARGETS);
return;
}
}break;
case 7669:// Bethor's Potion
{
// related to Hex of Ravenclaw,
// its a dispell spell.
//FIXME:Dont know whats the usage of this dummy
}break;
case 8283:// Snufflenose Command
{
//FIXME:Quest Blueleaf Tubers
//For use on a Snufflenose Gopher
}break;
case 8593:// Symbol of Life
{
//Quest The Tome of Divinity
}break;
case 8913:// Sacred Cleansing
{
//FIXME:Removes the protective enchantments around Morbent Fel
//Quest Morbent Fel
}break;
case 9962://Capture Treant
{
//Quest Treant Muisek
}break;
case 10113:// Flare Gun's flare
{
//FIXME:Quest Deep Cover
//1543 may need to cast this
//2 flares and the /salute
}break;
case 10617:// Release Rageclaw
{
//Quest Druid of the Claw
//Use on the fallen body of Rageclaw
}break;
case 11402:// Shay's Bell
{
//FIXME:Quest Wandering Shay
//Ring to call Shay back to you
}break;
case 11548:// Summon Spider God
{
//FIXME:Quest Summoning Shadra (Elite)
//Use at the Shadra'Alor Altar to summon the spider god
}break;
case 11610:// Gammerita Turtle Camera
{
//Quest The Super Snapper FX
}break;
case 11886:// Capture Wildkin
{
//Quest Testing the Vessel
//Shrink and Capture a Fallen Wildkin
}break;
case 11887:// Capture Hippogryph
{
//FIXME:Same with 11888
//Quest Hippogryph Muisek
}break;
case 11888:// Capture Faerie Dragon
{
//FIXME:Check Faerie Dragon Muisek is killed or not if its killed update quest
//And allow create of fearie Dragon which is effect 1
//Quest: Faerie Dragon Muisek
}break;
case 11889:// Capture Mountain Giant
{
//FIXME:Same with 11888
//Quest: Mountain Giant Muisek
}break;
case 12189:// Summon Echeyakee
{
//FIXME:Quest Echeyakee
}break;
case 12283:// Xiggs Signal Flare
{
//Quest Signal for Pickup
//To be used at the makeshift helipad in Azshara. It will summon Pilot Xiggs Fuselighter to pick up the tablet rubbings
}break;
case 12938:// Fel Curse
{
//FIXME:Makes near target killable(servants of Razelikh the Defiler)
}break;
case 14247:// Blazerunner Dispel
{
//FIXME:Quest Aquementas and some more
}break;
case 14250:// Capture Grark
{
//Quest Precarious Predicament
}break;
case 14813:// Rocknot's Ale
{
//you throw the mug
//and the guy gets pissed well everyone gets pissed and he crushes the door so you can get past
//maybe after like 30 seconds so you can get past. but lke I said I have never done it myself
//so i am not 100% sure what happens.
}break;
case 15991://Revive Ringo
{
//Quest A Little Help From My Friends
//Revive Ringo with water
}break;
case 15998:// Capture Worg Pup
{
//FIXME:Ends Kibler's Exotic Pets (Dungeon) quest
}break;
case 16031:// Releasing Corrupt Ooze
{
//FIXME:Released ooze moves to master ooze and "Merged Ooze Sample"
//occurs after some time.This item helps to finish quest
}break;
case 16378:// Temperature Reading
{
//FIXME:Quest Finding the Source
//Take a reading of the temperature at a hot spot.
}break;
case 17166:// Release Umi's Yeti
{
//Quest Are We There, Yeti?
//Select Umi's friend and click to release the Mechanical Yeti
}break;
case 17271:// Test Fetid Skull
{
//FIXME:Marauders of Darrowshire
//Wave over a Fetid skull to test its resonance
}break;
case 18153:// Kodo Kombobulator
{
//FIXME:Kodo Roundup Quest
//Kodo Kombobulator on any Ancient, Aged, or Dying Kodo to lure the Kodo to follow (one at a time)
}break;
case 19250:// Placing Smokey's Explosives
{
//This is something related to quest i think
if(i == 0)
{
}
else
{
}
}break;
case 19512:// Apply Salve
{
//FIXME:Cure a sickly animal afflicted by the taint of poisoning
}break;
case 20473://holy shock r1
case 20929://holy shock rank2
case 20930:
case 27174:
case 33072:
{/*Blasts the target with Holy energy, causing $25912s1 Holy damage to an enemy, or $25914s1 healing to an ally." */
uint32 sp;
if(isAttackable(unitTarget,u_caster))
sp=m_spellInfo->EffectTriggerSpell[0];
else
sp=m_spellInfo->EffectTriggerSpell[1];
SpellCastTargets tgt;
tgt.m_unitTarget = unitTarget->GetGUID();
SpellEntry * inf =sSpellStore.LookupEntry(sp);
Spell * spe = new Spell(u_caster,inf,true,NULL);
spe->prepare(&tgt);
}break;
case 20804:// Triage
{
//Quest Triage
//Use on Injured, Badly Injured, and Critically Injured Soldiers
}break;
case 21050:// Melodious Rapture
{
//Quest Deeprun Rat Roundup
}break;
case 21332:// Aspect of Neptulon
{
//FIXME:Used on plagued water elementals in Eastern Plaguelands
//Quest:Poisoned Water
}break;
case 21960:// Manifest Spirit
{
//FIXME:Forces the spirits of the first centaur Kahns to manifest in the physical world
//thats a quest
//its for maraudon i think
//u use that on the spirit mobs
//to release them
}break;
case 23133:// Gnomish Battle Chicken
{
//FIXME:Creates a Battle Chicken that will fight for you for 1.50 min or until it is destroyed
//Quest Craftsman's Writ - Gnomish Battle Chicken
//Need research
//entryid 8836
}break;
case 23359:// Transmogrify!
{
//Quest Zapped Giants
//Zap a Feralas giant into a more manageable form
}break;
case 27184:// Summon Mor Grayhoof
{
//Related to quests The Left Piece of Lord Valthalak's Amulet (Dungeon)
//and The Right Piece of Lord Valthalak's Amulet (Dungeon)
}break;
case 27190:// Summon Isalien
{
//Related to quests The Left Piece of Lord Valthalak's Amulet (Dungeon)
//and The Right Piece of Lord Valthalak's Amulet (Dungeon)
}break;
case 27191:// Summon the remains of Jarien and Sothos
{
//Related to quests The Left Piece of Lord Valthalak's Amulet (Dungeon)
//and The Right Piece of Lord Valthalak's Amulet (Dungeon)
}break;
case 27201:// Summon the spirit of Kormok
{
//Related to quests The Left Piece of Lord Valthalak's Amulet (Dungeon)
//and The Right Piece of Lord Valthalak's Amulet (Dungeon)
}break;
case 27202:// Summon Lord Valthalak
{
//Related to quests The Left Piece of Lord Valthalak's Amulet (Dungeon)
//and The Right Piece of Lord Valthalak's Amulet (Dungeon)
}break;
case 27203:// Summon the spirits of the dead at haunted locations
{
//Related to quests The Left Piece of Lord Valthalak's Amulet (Dungeon)
//and The Right Piece of Lord Valthalak's Amulet (Dungeon)
}break;
case 27517:// Use this banner at the Arena in Blackrock Depths to challenge Theldren
{
//This is used to make Theldren spawn at the place where it used
//I couldnt find theldrin, and his men in creature names database
//Someone has to write this and this is related to The Challange quest
/*By moving to the center grate, you trigger the arena event.
A random group of mobs (spiders, worms, bats, raptors) spawns,
and you have to kill them. After the last one dies, and a small
break, a boss mob spawns. Successfully completing this event
turns the arena spectators from red to yellow*/
}break;
/* Quest Related */
}
}
void Spell::SpellEffectTeleportUnits(uint32 i) // Teleport Units
{
if(m_spellInfo->NameHash == 0x068d7654 && unitTarget && p_caster && p_caster->IsInWorld()) // Shadowstep
{
/* this is rather tricky actually. we have to calculate the orientation of the creature/player, and then calculate a little bit of distance behind that. */
float ang;
if(unitTarget == m_caster)
{
/* try to get a selection */
unitTarget = m_caster->GetMapMgr()->GetUnit(p_caster->GetSelection());
if(!unitTarget)
return;
}
if(unitTarget->GetTypeId() == TYPEID_UNIT)
{
if(unitTarget->GetUInt64Value(UNIT_FIELD_TARGET) != 0)
{
/* We're chasing a target. We have to calculate the angle to this target, this is our orientation. */
ang = m_caster->calcAngle(m_caster->GetPositionX(), m_caster->GetPositionY(), unitTarget->GetPositionX(), unitTarget->GetPositionY());
/* convert degree angle to radians */
ang = ang * M_PI / 180.0f;
}
else
{
/* Our orientation has already been set. */
ang = unitTarget->GetOrientation();
}
}
else
{
/* Players orientation is sent in movement packets */
ang = unitTarget->GetOrientation();
}
const static float shadowstep_distance = 1.0f; /* 1.0 feet behind the target */
float new_x = unitTarget->GetPositionX() - (shadowstep_distance * cosf(ang));
float new_y = unitTarget->GetPositionY() - (shadowstep_distance * sinf(ang));
/* Send a movement packet to "charge" at this target. Similar to warrior charge. */
p_caster->SafeTeleport(p_caster->GetMapId(), p_caster->GetInstanceID(), LocationVector(new_x, new_y, unitTarget->GetPositionZ(), unitTarget->GetOrientation()));
return;
}
if(!unitTarget || unitTarget->GetTypeId()!= TYPEID_PLAYER)
return;
/* TODO: Remove Player From bg */
// Try a dummy spell handler.
if(sScriptMgr.CallScriptedDummySpell(m_spellInfo->Id, i, this))
return;
HandleTeleport(m_spellInfo->Id,unitTarget);
}
void Spell::SpellEffectApplyAura(uint32 i) // Apply Aura
{
if(!unitTarget)
return;
// can't apply stuns/fear/polymorph/root etc on boss
Creature * c = (Creature*)(unitTarget);
if (c&&c->GetCreatureName()&&c->GetCreatureName()->Rank == 3) //boss
{
switch(m_spellInfo->EffectApplyAuraName[i])
{
case 6:
case 7:
case 12:
case 25:
case 26:
case 27:
case 31:
case 33:
SendCastResult(SPELL_FAILED_IMMUNE);
return;
}
}
//check if we already have stronger aura
Aura *pAura;
std::map::iterator itr=unitTarget->tmpAura.find(m_spellInfo->Id);
if(itr==unitTarget->tmpAura.end())
{
uint32 Duration=GetDuration();
// Handle diminishing returns, if it should be resisted, it'll make duration 0 here.
if(!(m_spellInfo->Attributes & 64)) // Passive
::ApplyDiminishingReturnTimer(&Duration, unitTarget, m_spellInfo);
if(!Duration)
return;
if(g_caster && g_caster->GetUInt32Value(OBJECT_FIELD_CREATED_BY) && g_caster->m_summoner)
pAura=new Aura(m_spellInfo, Duration, g_caster->m_summoner, unitTarget);
else
pAura=new Aura(m_spellInfo, Duration, m_caster, unitTarget);
pAura->pSpellId = pSpellId; //this is required for triggered spells
unitTarget->tmpAura[m_spellInfo->Id] = pAura;
}
else
{
pAura=itr->second;
}
pAura->AddMod(m_spellInfo->EffectApplyAuraName[i],damage,m_spellInfo->EffectMiscValue[i],i);
}
void Spell::SpellEffectPowerDrain(uint32 i) // Power Drain
{
if(!unitTarget || !unitTarget->isAlive())
return;
uint32 powerField = UNIT_FIELD_POWER1+m_spellInfo->EffectMiscValue[i];
uint32 curPower = unitTarget->GetUInt32Value(powerField);
uint32 amt=damage;
if(amt>curPower)
{
amt=curPower;
}
unitTarget->SetUInt32Value(powerField,curPower-amt);
uint32 m=u_caster->GetUInt32Value(UNIT_FIELD_MAXPOWER1+m_spellInfo->EffectMiscValue[i]);
amt+=u_caster->GetUInt32Value(powerField);
if(amt>m)amt=m;
u_caster->SetUInt32Value(powerField,amt);
SendHealManaSpellOnPlayer(u_caster, u_caster, damage,m_spellInfo->EffectMiscValue[i]);
}
void Spell::SpellEffectHealthLeech(uint32 i) // Health Leech
{
if(!unitTarget || !unitTarget->isAlive())
return;
uint32 curHealth = unitTarget->GetUInt32Value(UNIT_FIELD_HEALTH);
uint32 amt = damage;
if(amt > curHealth)
{
amt = curHealth;
}
m_caster->DealDamage(unitTarget, damage, 0, 0, m_spellInfo->Id);
uint32 playerCurHealth = m_caster->GetUInt32Value(UNIT_FIELD_HEALTH);
uint32 playerMaxHealth = m_caster->GetUInt32Value(UNIT_FIELD_MAXHEALTH);
if(playerCurHealth + amt > playerMaxHealth)
{
m_caster->SetUInt32Value(UNIT_FIELD_HEALTH, playerMaxHealth);
}
else
{
m_caster->SetUInt32Value(UNIT_FIELD_HEALTH, playerCurHealth + amt);
}
}
void Spell::SpellEffectHeal(uint32 i) // Heal
{
if(m_spellInfo->EffectChainTarget[i])//chain
{
if(!chaindamage)
{
chaindamage = damage;
}
else
{
int32 reduce=m_spellInfo->EffectDieSides[i]+1;
if(m_spellInfo->SpellGroupType && u_caster)
{
SM_FIValue(u_caster->SM_PJumpReduce,&reduce,m_spellInfo->SpellGroupType);
}
chaindamage -= (reduce * chaindamage) / 100;
Heal((int32)chaindamage);
}
}
else
{
//yep, the usual special case. This one is shaman talen : Nature's guardian
//health is below 30%, we have a mother spell to get value from
if(m_spellInfo->Id==31616)
{
if(unitTarget && unitTarget->IsPlayer() && pSpellId && unitTarget->GetHealthPct()<30)
{
//check for that 10 second cooldown
SpellEntry *spellInfo = sSpellStore.LookupEntry(pSpellId );
if(spellInfo)
{
//heal value is receivad by the level of current active talent :s
//maybe we should use CalculateEffect(uint32 i) to gain SM benefits
int32 value = 0;
int32 basePoints = spellInfo->EffectBasePoints[i]+1;//+(m_caster->getLevel()*basePointsPerLevel);
int32 randomPoints = spellInfo->EffectDieSides[i];
if(randomPoints <= 1)
value = basePoints;
else
value = basePoints + rand() % randomPoints;
//the value is in percent. Until now it's a fixed 10%
Heal(unitTarget->GetUInt32Value(UNIT_FIELD_MAXHEALTH)*value/100);
}
}
}
else Heal((int32)damage);
}
}
void Spell::SpellEffectQuestComplete(uint32 i) // Quest Complete
{
//damage is id of the quest to complete
}
//wand->
void Spell::SpellEffectWeapondamageNoschool(uint32 i) // Weapon damage + (no School)
{
if(!unitTarget ||!u_caster)
return;
u_caster->Strike(unitTarget,GetType() == SPELL_TYPE_RANGED ? SPELL_TYPE_RANGED:SPELL_TYPE_MELEE,m_spellInfo,damage,0,0, false);
}
void Spell::SpellEffectAddExtraAttacks(uint32 i) // Add Extra Attacks
{
if(!u_caster)
return;
u_caster->m_extraattacks = damage;
}
void Spell::SpellEffectDodge(uint32 i)
{
//i think this actually enbles the skill to be able to dodge melee+ranged attacks
//value is static and sets value directly which will be modified by other factors
//this is only basic value and will be overwiten elsewhere !!!
// if(unitTarget->IsPlayer())
// unitTarget->SetFloatValue(PLAYER_DODGE_PERCENTAGE,damage);
}
void Spell::SpellEffectParry(uint32 i)
{
if(unitTarget)
unitTarget->setcanperry(true);
}
void Spell::SpellEffectBlock(uint32 i)
{
//i think this actually enbles the skill to be able to block melee+ranged attacks
//value is static and sets value directly which will be modified by other factors
// if(unitTarget->IsPlayer())
// unitTarget->SetFloatValue(PLAYER_BLOCK_PERCENTAGE,damage);
}
void Spell::SpellEffectCreateItem(uint32 i) // Create item
{
if(!p_caster)
return;
Item* newItem;
Item *add;
uint8 slot;
SlotResult slotresult;
skilllinespell* skill = objmgr.GetSpellSkill(m_spellInfo->Id);
for(int j=0; j<3; j++) // now create the Items
{
ItemPrototype *m_itemProto;
m_itemProto = ItemPrototypeStorage.LookupEntry( m_spellInfo->EffectSpellGroupRelation[j] );
if (!m_itemProto)
continue;
if(m_spellInfo->EffectSpellGroupRelation[j] == 0)
continue;
uint32 item_count = 0;
if (m_itemProto->Class != ITEM_CLASS_CONSUMABLE || m_spellInfo->SpellFamilyName != 3) //SpellFamilyName 3 is mage
item_count = damage;
else if(p_caster->getLevel() >= m_spellInfo->spellLevel)
item_count = ((p_caster->getLevel() - (m_spellInfo->spellLevel-1))*damage);
if(!item_count)
item_count = damage;
//conjure water ranks 7,8 & 9 and conjure food ranks 7 & 8 have different starting amounts
switch(m_spellInfo->Id)
{
case 27389: //Conjure Food 7
case 10140: //Conjure Water 7
case 37420: //Conjure Water 8
item_count += 8;
break;
}
// item count cannot be more than allowed in a single stack
if (item_count > m_itemProto->MaxCount)
item_count = m_itemProto->MaxCount;
// item count cannot be more than item unique value
if (m_itemProto->Unique && item_count > m_itemProto->Unique)
item_count = m_itemProto->Unique;
if(p_caster->GetItemInterface()->CanReceiveItem(m_itemProto, item_count)) //reversed since it sends >1 as invalid and 0 as valid
{
SendCastResult(SPELL_FAILED_TOO_MANY_OF_ITEM);
return;
}
slot = 0;
add = p_caster->GetItemInterface()->FindItemLessMax(m_spellInfo->EffectSpellGroupRelation[j],1, false);
if (!add)
{
slotresult = p_caster->GetItemInterface()->FindFreeInventorySlot(m_itemProto);
if(!slotresult.Result)
{
SendCastResult(SPELL_FAILED_TOO_MANY_OF_ITEM);
return;
}
newItem =objmgr.CreateItem(m_spellInfo->EffectSpellGroupRelation[i],p_caster);
newItem->SetUInt64Value(ITEM_FIELD_CREATOR,m_caster->GetGUID());
newItem->SetUInt32Value(ITEM_FIELD_STACK_COUNT, item_count);
if(p_caster->GetItemInterface()->SafeAddItem(newItem,slotresult.ContainerSlot, slotresult.Slot))
{
WorldPacket data(45);
p_caster->GetSession()->BuildItemPushResult(&data, p_caster->GetGUID(), 1, item_count, m_spellInfo->EffectSpellGroupRelation[i] ,0,0xFF,1,0xFFFFFFFF);
p_caster->SendMessageToSet(&data, true);
} else {
delete newItem;
}
if(skill)
DetermineSkillUp(skill->skilline);
}
else
{
//scale item_count down if total stack will be more than 20
if(add->GetUInt32Value(ITEM_FIELD_STACK_COUNT) + item_count > 20)
{
uint32 item_count_filled;
item_count_filled = 20 - add->GetUInt32Value(ITEM_FIELD_STACK_COUNT);
add->SetCount(20);
add->m_isDirty = true;
slotresult = p_caster->GetItemInterface()->FindFreeInventorySlot(m_itemProto);
if(!slotresult.Result)
item_count = item_count_filled;
else
{
newItem =objmgr.CreateItem(m_spellInfo->EffectSpellGroupRelation[i],p_caster);
newItem->SetUInt64Value(ITEM_FIELD_CREATOR,m_caster->GetGUID());
newItem->SetUInt32Value(ITEM_FIELD_STACK_COUNT, item_count - item_count_filled);
if(!p_caster->GetItemInterface()->SafeAddItem(newItem,slotresult.ContainerSlot, slotresult.Slot))
{
delete newItem;
item_count = item_count_filled;
}
}
}
else
{
add->SetCount(add->GetUInt32Value(ITEM_FIELD_STACK_COUNT) + item_count);
add->m_isDirty = true;
}
WorldPacket data(45);
p_caster->GetSession()->BuildItemPushResult(&data, p_caster->GetGUID(), 1, item_count, m_spellInfo->EffectSpellGroupRelation[i] ,0,0xFF,1,0xFFFFFFFF);
p_caster->SendMessageToSet(&data, true);
if(skill)
DetermineSkillUp(skill->skilline);
}
}
}
void Spell::SpellEffectWeapon(uint32 i)
{
if(!playerTarget)
return;
uint32 skill = 0;
uint32 spell = 0;
switch(this->m_spellInfo->Id)
{
case 201: // one-handed swords
skill = SKILL_SWORDS;
break;
case 202: // two-handed swords
skill = SKILL_2H_SWORDS;
break;
case 203: // Unarmed
skill = SKILL_UNARMED;
break;
case 199: // two-handed maces
skill = SKILL_2H_MACES;
break;
case 198: // one-handed maces
skill = SKILL_MACES;
break;
case 197: // two-handed axes
skill = SKILL_2H_AXES;
break;
case 196: // one-handed axes
skill = SKILL_AXES;
break;
case 5011: // crossbows
{
skill = SKILL_CROSSBOWS;
spell = SPELL_RANGED_GENERAL;
}break;
case 227: // staves
skill = SKILL_STAVES;
break;
case 1180: // daggers
skill = SKILL_DAGGERS;
break;
case 3386: // spears
skill = 0; // ??!!
break;
case 200: // polearms
skill = SKILL_POLEARMS;
break;
case 15590: // fist weapons
skill = SKILL_UNARMED;
break;
case 264: // bows
{
skill = SKILL_BOWS;
spell = SPELL_RANGED_GENERAL;
}break;
case 266: // guns
{
skill = SKILL_GUNS;
spell = SPELL_RANGED_GENERAL;
}break;
case 2567: // thrown
skill = SKILL_THROWN;
break;
default:
{
skill = 0;
sLog.outDebug("WARNING: Could not determine skill for spell id %d (SPELL_EFFECT_WEAPON)", this->m_spellInfo->Id);
}break;
}
// Don't add skills to players logging in.
/*if((m_spellInfo->Attributes & 64) && playerTarget->m_TeleportState == 1)
return;*/
if(skill)
{
if(spell)
playerTarget->addSpell(spell);
// if we do not have the skill line
if(!playerTarget->_HasSkillLine(skill))
{
playerTarget->_AddSkillLine(skill, 1, playerTarget->getLevel()*5);
}
else // unhandled.... if we have the skill line
{
}
}
}
void Spell::SpellEffectDefense(uint32 i)
{
//i think this actually enbles the skill to be able to use defense
//value is static and sets value directly which will be modified by other factors
//this is only basic value and will be overwiten elsewhere !!!
// if(unitTarget->IsPlayer())
// unitTarget->SetFloatValue(UNIT_FIELD_RESISTANCES,damage);
}
void Spell::SpellEffectPersistentAA(uint32 i) // Persistent Area Aura
{
if(m_AreaAura == true || !m_caster->IsInWorld())
return;
//create only 1 dyn object
uint32 dur = GetDuration();
float r = GetRadius(i);
//Note: this code seems to be useless
//this must be only source point or dest point
//this AREA aura it's apllied on area
//it can'be on unit or self or item or object
//uncomment it if i'm wrong
//We are thinking in general so it might be useful later DK
// grep: this is a hack!
// our shitty dynobj system doesnt support GO casters, so we gotta
// kinda have 2 summoners for traps that apply AA.
DynamicObject * dynObj = m_caster->GetMapMgr()->CreateDynamicObject();
if(g_caster && g_caster->m_summoner && !unitTarget)
{
Unit * caster = g_caster->m_summoner;
dynObj->Create(caster, this, g_caster->GetPositionX(), g_caster->GetPositionY(),
g_caster->GetPositionZ(), dur, r);
m_AreaAura = true;
return;
}
switch(m_targets.m_targetMask)
{
case TARGET_FLAG_SELF:
{
dynObj->Create(u_caster, this, m_caster->GetPositionX(),
m_caster->GetPositionY(), m_caster->GetPositionZ(), dur,r);
}break;
case TARGET_FLAG_UNIT:
{
if(!unitTarget||!unitTarget->isAlive())
break;
dynObj->Create( u_caster, this, unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(),
dur, r);
}break;
case TARGET_FLAG_OBJECT:
{
if(!unitTarget)
break;
if(!unitTarget->isAlive())
break;
dynObj->Create(u_caster, this, unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(),
dur, r);
}break;
case TARGET_FLAG_SOURCE_LOCATION:
{
dynObj->SetInstanceID(m_caster->GetInstanceID());
dynObj->Create(u_caster, this, m_targets.m_srcX,
m_targets.m_srcY, m_targets.m_srcZ, dur,r);
}break;
case TARGET_FLAG_DEST_LOCATION:
{
dynObj->SetInstanceID(m_caster->GetInstanceID());
dynObj->Create(u_caster?u_caster:g_caster->m_summoner, this,
m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ,dur,r);
}break;
default:
return;
}
if(u_caster)
if(m_spellInfo->ChannelInterruptFlags > 0)
{
u_caster->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT,dynObj->GetGUID());
u_caster->SetUInt32Value(UNIT_CHANNEL_SPELL,m_spellInfo->Id);
}
m_AreaAura = true;
}
void Spell::SpellEffectSummon(uint32 i) // Summon
{
if(!p_caster || !p_caster->IsInWorld())
return;
if(p_caster->m_tempSummon)
{
p_caster->m_tempSummon->RemoveFromWorld(false);
if(p_caster->m_tempSummon)
p_caster->m_tempSummon->SafeDelete();
p_caster->m_tempSummon = 0;
p_caster->SetUInt64Value(UNIT_FIELD_SUMMON, 0);
}
/* This is for summon water elemenal, etc */
CreatureInfo * ci = CreatureNameStorage.LookupEntry(m_spellInfo->EffectMiscValue[i]);
CreatureProto * cp = CreatureProtoStorage.LookupEntry(m_spellInfo->EffectMiscValue[i]);
if( !ci || !cp )
return;
if(m_spellInfo->EffectMiscValue[i] == 510) // Water Elemental
{
Pet *summon = objmgr.CreatePet();
summon->SetInstanceID(m_caster->GetInstanceID());
summon->CreateAsSummon(m_spellInfo->EffectMiscValue[i], ci, NULL, p_caster, m_spellInfo, 1, 45000);
summon->SetUInt32Value(UNIT_FIELD_LEVEL, p_caster->getLevel());
if (sSpellStore.LookupEntry(31707))
summon->AddSpell(sSpellStore.LookupEntry(31707), true);
if (sSpellStore.LookupEntry(33395))
summon->AddSpell(sSpellStore.LookupEntry(33395), true);
}
else
{
Creature * pCreature = p_caster->GetMapMgr()->CreateCreature();
pCreature->Load(cp, p_caster->GetPositionX(), p_caster->GetPositionY(), p_caster->GetPositionZ());
pCreature->_setFaction();
pCreature->GetAIInterface()->Init(pCreature,AITYPE_PET,MOVEMENTTYPE_NONE,u_caster);
pCreature->GetAIInterface()->SetUnitToFollow(u_caster);
pCreature->GetAIInterface()->SetUnitToFollowAngle(-(M_PI/2));
pCreature->GetAIInterface()->SetFollowDistance(3.0f);
pCreature->SetUInt32Value(UNIT_FIELD_LEVEL, p_caster->getLevel());
pCreature->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, p_caster->GetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE));
pCreature->_setFaction();
p_caster->SetUInt64Value(UNIT_FIELD_SUMMON, pCreature->GetGUID());
p_caster->m_tempSummon = pCreature;
pCreature->PushToWorld(p_caster->GetMapMgr());
if(p_caster->isInCombat())
{
Unit * target = p_caster->GetMapMgr()->GetUnit(p_caster->getAttackTarget());
if(target)
pCreature->GetAIInterface()->AttackReaction(target, 1, 0);
}
/* not sure on this */
sEventMgr.AddEvent(pCreature, &Creature::SafeDelete, EVENT_CREATURE_REMOVE_CORPSE, /*GetDuration()*/45000, 1, 0);
}
}
void Spell::SpellEffectLeap(uint32 i) // Leap
{
float radius = GetRadius(i);
//FIXME: check for obstacles
/*float ori = m_caster->GetOrientation();
float posX = m_caster->GetPositionX()+(radius*(cos(ori)));
float posY = m_caster->GetPositionY()+(radius*(sin(ori)));
float z= m_caster->GetMapMgr()->GetLandHeight(posX,posY);
if(fabs(p_caster->GetPositionZ() - z) > 2)
z=p_caster->GetPositionZ()+2;
m_caster->SetPosition(posX,posY,z,ori,true);
WorldPacket data(MSG_MOVE_HEARTBEAT, 33);
data << m_caster->GetNewGUID();
data << uint32(0) << uint32(0);
data << posX;
data << posY;
data << z;
data << ori;
m_caster->SendMessageToSet(&data, true); */
if(!p_caster) return;
// remove movement impeding auras
p_caster->RemoveAurasByInterruptFlag(AURA_INTERRUPT_ON_ANY_DAMAGE_TAKEN);
p_caster->blinked = true;
WorldPacket data(SMSG_MOVE_KNOCK_BACK, 50);
data << p_caster->GetNewGUID();
data << getMSTime();
data << cosf(p_caster->GetOrientation()) << sinf(p_caster->GetOrientation());
data << radius;
data << float(-10.0f);
m_caster->SendMessageToSet(&data, true);
}
void Spell::SpellEffectEnergize(uint32 i) // Energize
{
if(!unitTarget || !unitTarget->isAlive())
return;
uint32 POWER_TYPE=UNIT_FIELD_POWER1+m_spellInfo->EffectMiscValue[i];
SendHealManaSpellOnPlayer(u_caster, unitTarget, damage, m_spellInfo->EffectMiscValue[i]);
uint32 curEnergy = (uint32)unitTarget->GetUInt32Value(POWER_TYPE);
uint32 maxEnergy = (uint32)unitTarget->GetUInt32Value(POWER_TYPE+6);
uint32 totalEnergy = 0;
//yess there is always someone special : shamanistic rage - talent
if(m_spellInfo->Id==30824)
totalEnergy = curEnergy+damage*GetUnitTarget()->GetAP()/100;
//paladin illumination
else if(m_spellInfo->Id==20272 && ProcedOnSpell)
{
SpellEntry *motherspell=sSpellStore.LookupEntry(pSpellId);
if(motherspell)
totalEnergy = (motherspell->EffectBasePoints[0]+1)*ProcedOnSpell->manaCost/100;
}
else if (m_spellInfo->Id==2687){
totalEnergy = curEnergy+damage;
if(p_caster)
{
for(set::iterator itr = p_caster->mSpells.begin(); itr != p_caster->mSpells.end(); ++itr)
{
if(*itr == 12818)
totalEnergy += 60;
else if(*itr == 12301)
totalEnergy += 30;
}
}
}
else
totalEnergy = curEnergy+damage;
if(totalEnergy > maxEnergy)
unitTarget->SetUInt32Value(POWER_TYPE,maxEnergy);
else
unitTarget->SetUInt32Value(POWER_TYPE,totalEnergy);
}
void Spell::SpellEffectWeaponDmgPerc(uint32 i) // Weapon Percent damage
{
if(!unitTarget || !u_caster)
return;
u_caster->Strike(unitTarget,GetType(),m_spellInfo,add_damage,damage,0, false);
}
void Spell::SpellEffectTriggerMissile(uint32 i) // Trigger Missile
{
//Used by mortar team
//Triggers area affect spell at destinatiom
if(!m_caster)
return;
uint32 spellid = m_spellInfo->EffectTriggerSpell[i];
if(spellid == 0)
return;
SpellEntry *spInfo = sSpellStore.LookupEntry(spellid);
if(!spInfo)
return;
float spellRadius = GetRadius(i);
for(std::set