Updated spells stuff

This commit is contained in:
tomrus88 2008-10-26 10:15:52 +03:00
parent f7049657c9
commit 629da9de32
9 changed files with 479 additions and 370 deletions

View file

@ -574,6 +574,7 @@ void Spell::FillTargetMap()
case SPELL_EFFECT_SUMMON_GUARDIAN:
case SPELL_EFFECT_TRANS_DOOR:
case SPELL_EFFECT_ADD_FARSIGHT:
case SPELL_EFFECT_APPLY_GLYPH:
case SPELL_EFFECT_STUCK:
case SPELL_EFFECT_DESTROY_ALL_TOTEMS:
case SPELL_EFFECT_SUMMON_DEMON:
@ -2539,9 +2540,9 @@ void Spell::SendCastResult(uint8 result)
if(result != 0)
{
WorldPacket data(SMSG_CAST_FAILED, (4+1+1));
data << uint8(m_cast_count); // single cast or multi 2.3 (0/1)
data << uint32(m_spellInfo->Id);
data << uint8(result); // problem
data << uint8(m_cast_count); // single cast or multi 2.3 (0/1)
switch (result)
{
case SPELL_FAILED_REQUIRES_SPELL_FOCUS:
@ -2579,7 +2580,7 @@ void Spell::SendCastResult(uint8 result)
}
else
{
WorldPacket data(SMSG_CLEAR_EXTRA_AURA_INFO, (8+4));
WorldPacket data(SMSG_CLEAR_EXTRA_AURA_INFO_OBSOLETE, (8+4));
data.append(m_caster->GetPackGUID());
data << uint32(m_spellInfo->Id);
((Player*)m_caster)->GetSession()->SendPacket(&data);
@ -2593,7 +2594,7 @@ void Spell::SendSpellStart()
sLog.outDebug("Sending SMSG_SPELL_START id=%u",m_spellInfo->Id);
uint16 castFlags = CAST_FLAG_UNKNOWN1;
uint32 castFlags = CAST_FLAG_UNKNOWN1;
if(IsRangedSpell())
castFlags |= CAST_FLAG_AMMO;
@ -2610,14 +2611,29 @@ void Spell::SendSpellStart()
data.append(m_caster->GetPackGUID());
data.append(m_caster->GetPackGUID());
data << uint8(m_cast_count); // pending spell cast?
data << uint32(m_spellInfo->Id);
data << uint8(m_cast_count); // single cast or multi 2.3 (0/1)
data << uint16(castFlags);
data << uint32(castFlags);
data << uint32(m_timer);
m_targets.write(&data);
if( castFlags & CAST_FLAG_AMMO )
if ( castFlags & CAST_FLAG_UNKNOWN6 )
data << uint32(0);
if ( castFlags & CAST_FLAG_UNKNOWN7 )
{
uint8 v1 = 0;
uint8 v2 = 0;
data << v1; // v1
data << v2; // v2
for(uint8 i = 0; i < 6; ++i)
if((1 << i) & v1)
if(!(1 << i) & v2)
data << uint8(0);
}
if ( castFlags & CAST_FLAG_AMMO )
WriteAmmoToPacket(&data);
m_caster->SendMessageToSet(&data, true);
@ -2637,7 +2653,7 @@ void Spell::SendSpellGo()
else
target = m_targets.getUnitTarget();
uint16 castFlags = CAST_FLAG_UNKNOWN3;
uint32 castFlags = CAST_FLAG_UNKNOWN3;
if(IsRangedSpell())
castFlags |= CAST_FLAG_AMMO;
@ -2648,17 +2664,50 @@ void Spell::SendSpellGo()
data.append(m_caster->GetPackGUID());
data.append(m_caster->GetPackGUID());
data << uint8(m_cast_count); // pending spell cast?
data << uint32(m_spellInfo->Id);
data << uint16(castFlags);
data << uint32(castFlags);
data << uint32(getMSTime()); // timestamp
WriteSpellGoTargets(&data);
m_targets.write(&data);
if( castFlags & CAST_FLAG_AMMO )
if ( castFlags & CAST_FLAG_UNKNOWN6 ) // unknown wotlk
data << uint32(0);
if ( castFlags & CAST_FLAG_UNKNOWN7 )
{
uint8 v1 = 0;
uint8 v2 = 0;
data << v1; // v1
data << v2; // v2
for(uint8 i = 0; i < 6; ++i)
if((1 << i) & v1)
if(!(1 << i) & v2)
data << uint8(0);
}
if ( castFlags & CAST_FLAG_UNKNOWN4 ) // unknown wotlk
{
data << float(0);
data << uint32(0);
}
if ( castFlags & CAST_FLAG_AMMO )
WriteAmmoToPacket(&data);
if ( castFlags & CAST_FLAG_UNKNOWN5 ) // unknown wotlk
{
data << uint32(0);
data << uint32(0);
}
if ( m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION )
{
data << uint8(0);
}
m_caster->SendMessageToSet(&data, true);
}
@ -2794,7 +2843,7 @@ void Spell::SendLogExecute()
case SPELL_EFFECT_TRANS_DOOR:
case SPELL_EFFECT_SUMMON_PET:
case SPELL_EFFECT_SUMMON_POSSESSED:
case SPELL_EFFECT_SUMMON_TOTEM:
//case SPELL_EFFECT_SUMMON_TOTEM:
case SPELL_EFFECT_SUMMON_OBJECT_WILD:
case SPELL_EFFECT_CREATE_HOUSE:
case SPELL_EFFECT_DUEL:
@ -2841,13 +2890,16 @@ void Spell::SendInterrupted(uint8 result)
{
WorldPacket data(SMSG_SPELL_FAILURE, (8+4+1));
data.append(m_caster->GetPackGUID());
data << m_spellInfo->Id;
data << result;
data << uint8(m_cast_count);
data << uint32(m_spellInfo->Id);
data << uint8(result);
m_caster->SendMessageToSet(&data, true);
data.Initialize(SMSG_SPELL_FAILED_OTHER, (8+4));
data.append(m_caster->GetPackGUID());
data << m_spellInfo->Id;
data << uint8(m_cast_count);
data << uint32(m_spellInfo->Id);
data << uint8(result);
m_caster->SendMessageToSet(&data, true);
}
@ -2873,7 +2925,7 @@ void Spell::SendChannelStart(uint32 duration)
{
WorldObject* target = NULL;
// select first not rsusted target from target list for _0_ effect
// select first not resisted target from target list for _0_ effect
if(!m_UniqueTargetInfo.empty())
{
for(std::list<TargetInfo>::iterator itr= m_UniqueTargetInfo.begin();itr != m_UniqueTargetInfo.end();++itr)
@ -3548,15 +3600,9 @@ uint8 Spell::CanCast(bool strict)
if(!learn_spellproto)
return SPELL_FAILED_NOT_KNOWN;
if(!pet->CanTakeMoreActiveSpells(learn_spellproto->Id))
return SPELL_FAILED_TOO_MANY_SKILLS;
if(m_spellInfo->spellLevel > pet->getLevel())
return SPELL_FAILED_LOWLEVEL;
if(!pet->HasTPForSpell(learn_spellproto->Id))
return SPELL_FAILED_TRAINING_POINTS;
break;
}
case SPELL_EFFECT_LEARN_PET_SPELL:
@ -3571,15 +3617,9 @@ uint8 Spell::CanCast(bool strict)
if(!learn_spellproto)
return SPELL_FAILED_NOT_KNOWN;
if(!pet->CanTakeMoreActiveSpells(learn_spellproto->Id))
return SPELL_FAILED_TOO_MANY_SKILLS;
if(m_spellInfo->spellLevel > pet->getLevel())
return SPELL_FAILED_LOWLEVEL;
if(!pet->HasTPForSpell(learn_spellproto->Id))
return SPELL_FAILED_TRAINING_POINTS;
break;
}
case SPELL_EFFECT_FEED_PET:
@ -3688,27 +3728,27 @@ uint8 Spell::CanCast(bool strict)
{
// check for lock - key pair (checked by client also, just prevent cheating
bool ok_key = false;
for(int it = 0; it < 5; ++it)
for(int it = 0; it < 8; ++it)
{
switch(lockInfo->keytype[it])
switch(lockInfo->Type[it])
{
case LOCK_KEY_NONE:
break;
case LOCK_KEY_ITEM:
{
if(lockInfo->key[it])
if(lockInfo->Index[it])
{
if(m_CastItem && m_CastItem->GetEntry()==lockInfo->key[it])
if(m_CastItem && m_CastItem->GetEntry()==lockInfo->Index[it])
ok_key =true;
break;
}
}
case LOCK_KEY_SKILL:
{
if(uint32(m_spellInfo->EffectMiscValue[i])!=lockInfo->key[it])
if(uint32(m_spellInfo->EffectMiscValue[i])!=lockInfo->Index[it])
break;
switch(lockInfo->key[it])
switch(lockInfo->Index[it])
{
case LOCKTYPE_HERBALISM:
if(((Player*)m_caster)->HasSkill(SKILL_HERBALISM))
@ -3765,9 +3805,9 @@ uint8 Spell::CanCast(bool strict)
{
// check for lock - key pair
bool ok = false;
for(int it = 0; it < 5; ++it)
for(int it = 0; it < 8; ++it)
{
if(lockInfo->keytype[it]==LOCK_KEY_ITEM && lockInfo->key[it] && m_CastItem && m_CastItem->GetEntry()==lockInfo->key[it])
if(lockInfo->Type[it]==LOCK_KEY_ITEM && lockInfo->Index[it] && m_CastItem && m_CastItem->GetEntry()==lockInfo->Index[it])
{
// if so, we're good to go
ok = true;
@ -3778,9 +3818,9 @@ uint8 Spell::CanCast(bool strict)
break;
if (m_spellInfo->EffectMiscValue[i] == LOCKTYPE_PICKLOCK)
ReqValue = lockInfo->requiredlockskill;
ReqValue = lockInfo->Skill[1];
else
ReqValue = lockInfo->requiredminingskill;
ReqValue = lockInfo->Skill[0];
}
// skill doesn't meet the required value
@ -4297,9 +4337,12 @@ int32 Spell::CalculatePowerCost()
case POWER_FOCUS:
case POWER_ENERGY:
case POWER_HAPPINESS:
// case POWER_RUNES:
powerCost += m_spellInfo->ManaCostPercentage * m_caster->GetMaxPower(Powers(m_spellInfo->powerType)) / 100;
break;
case POWER_RUNE:
case POWER_RUNIC_POWER:
sLog.outDebug("Spell::CalculateManaCost: Not implemented yet!");
break;
default:
sLog.outError("Spell::CalculateManaCost: Unknown power type '%d' in spell %d", m_spellInfo->powerType, m_spellInfo->Id);
return 0;
@ -4616,7 +4659,7 @@ uint8 Spell::CheckItems()
return SPELL_FAILED_LOW_CASTLEVEL;
//make sure the player has the required ores in inventory
if(m_targets.getItemTarget()->GetCount() < 5)
return SPELL_FAILED_PROSPECT_NEED_MORE;
return SPELL_FAILED_NEED_MORE_ITEMS;
if(!LootTemplates_Prospecting.HaveLootFor(m_targets.getItemTargetEntry()))
return SPELL_FAILED_CANT_BE_PROSPECTED;

View file

@ -56,7 +56,8 @@ enum SpellCastTargetFlags
TARGET_FLAG_STRING = 0x00002000, // string
TARGET_FLAG_UNK1 = 0x00004000, // ?
TARGET_FLAG_CORPSE = 0x00008000, // pguid
TARGET_FLAG_UNK2 = 0x00010000 // pguid
TARGET_FLAG_UNK2 = 0x00010000, // pguid
TARGET_FLAG_GLYPH = 0x00020000
};
enum SpellCastFlags
@ -252,6 +253,7 @@ class Spell
void EffectStuck(uint32 i);
void EffectSummonPlayer(uint32 i);
void EffectActivateObject(uint32 i);
void EffectApplyGlyph(uint32 i);
void EffectSummonTotem(uint32 i);
void EffectEnchantHeldItem(uint32 i);
void EffectSummonObject(uint32 i);
@ -362,6 +364,7 @@ class Spell
int32 m_currentBasePoints[3]; // cache SpellEntry::EffectBasePoints and use for set custom base points
Item* m_CastItem;
uint8 m_cast_count;
uint32 m_glyphIndex;
SpellCastTargets m_targets;
int32 GetCastTime() const { return m_casttime; }

View file

@ -18,11 +18,20 @@
#ifndef MANGOS_SPELLAURADEFINES_H
#define MANGOS_SPELLAURADEFINES_H
#define MAX_AURAS 56
#define MAX_AURAS 56 // probably changes to 64 in WotLK
#define MAX_POSITIVE_AURAS 40
enum AURA_FLAGS
{
AFLAG_NONE = 0x00,
AFLAG_EFF_INDEX_0 = 0x01,
AFLAG_EFF_INDEX_1 = 0x02,
AFLAG_EFF_INDEX_2 = 0x04,
AFLAG_NOT_GUID = 0x08,
AFLAG_UNK1 = 0x10, // positive?
AFLAG_DURATION = 0x20,
AFLAG_UNK2 = 0x40,
AFLAG_UNK3 = 0x80,
AFLAG_NEGATIVE = 0x09,
AFLAG_POSITIVE = 0x1F,
AFLAG_MASK = 0xFF
@ -273,7 +282,7 @@ enum AuraType
SPELL_AURA_233 = 233,
SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK = 234,
SPELL_AURA_MOD_DISPEL_RESIST = 235,
SPELL_AURA_236 = 236,
SPELL_AURA_CONTROL_VEHICLE = 236,
SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER = 237,
SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER = 238,
SPELL_AURA_MOD_SCALE_2 = 239,
@ -299,7 +308,14 @@ enum AuraType
SPELL_AURA_259 = 259,
SPELL_AURA_260 = 260,
SPELL_AURA_261 = 261,
TOTAL_AURAS=262
SPELL_AURA_262 = 262,
SPELL_AURA_263 = 263,
SPELL_AURA_264 = 264,
SPELL_AURA_265 = 265,
SPELL_AURA_266 = 266,
SPELL_AURA_267 = 267,
SPELL_AURA_268 = 268,
TOTAL_AURAS = 269
};
enum AreaAuraType

View file

@ -286,7 +286,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleNULL, //233 set model id to the one of the creature with id m_modifier.m_miscvalue
&Aura::HandleNoImmediateEffect, //234 SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK implement in Unit::CalculateSpellDuration
&Aura::HandleAuraModDispelResist, //235 SPELL_AURA_MOD_DISPEL_RESIST implement in Unit::MagicSpellHitResult
&Aura::HandleUnused, //236 unused
&Aura::HandleAuraControlVehicle, //236 SPELL_AURA_CONTROL_VEHICLE
&Aura::HandleModSpellDamagePercentFromAttackPower, //237 SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER implemented in Unit::SpellBaseDamageBonus
&Aura::HandleModSpellHealingPercentFromAttackPower, //238 SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER implemented in Unit::SpellBaseHealingBonus
&Aura::HandleAuraModScale, //239 SPELL_AURA_MOD_SCALE_2 only in Noggenfogger Elixir (16595) before 2.3.0 aura 61
@ -302,16 +302,23 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleNULL, //249
&Aura::HandleAuraModIncreaseHealth, //250 SPELL_AURA_MOD_INCREASE_HEALTH_2
&Aura::HandleNULL, //251 SPELL_AURA_MOD_ENEMY_DODGE
&Aura::HandleUnused, //252 unused
&Aura::HandleUnused, //253 unused
&Aura::HandleUnused, //254 unused
&Aura::HandleUnused, //255 unused
&Aura::HandleUnused, //256 unused
&Aura::HandleUnused, //257 unused
&Aura::HandleUnused, //258 unused
&Aura::HandleUnused, //259 unused
&Aura::HandleUnused, //260 unused
&Aura::HandleNULL //261 SPELL_AURA_261 some phased state (44856 spell)
&Aura::HandleNULL, //252
&Aura::HandleNULL, //253
&Aura::HandleNULL, //254
&Aura::HandleNULL, //255 SPELL_AURA_MOD_DAMAGE_PERCENT_MECHANIC
&Aura::HandleNULL, //256
&Aura::HandleNULL, //257 SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS
&Aura::HandleNULL, //258 SPELL_AURA_MOD_SPELL_VISUAL
&Aura::HandleNULL, //259 corrupt healing over time spell
&Aura::HandleNULL, //260
&Aura::HandleNULL, //261 out of phase?
&Aura::HandleNULL, //262
&Aura::HandleNULL, //263
&Aura::HandleNULL, //264
&Aura::HandleNULL, //265
&Aura::HandleNULL, //266
&Aura::HandleNULL, //267
&Aura::HandleNULL //268
};
Aura::Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem) :
@ -401,7 +408,7 @@ m_periodicTimer(0), m_PeriodicEventId(0), m_AuraDRGroup(DIMINISHING_NONE)
modOwner->ApplySpellMod(GetId(), SPELLMOD_CHARGES, m_procCharges);
}
else
m_procCharges = -1;
m_procCharges = 0;
m_isRemovedOnShapeLost = (m_caster_guid==m_target->GetGUID() && m_spellProto->Stances &&
!(m_spellProto->AttributesEx2 & 0x80000) && !(m_spellProto->Attributes & 0x10000));
@ -809,47 +816,6 @@ void Aura::ApplyModifier(bool apply, bool Real)
m_in_use = false;
}
void Aura::UpdateAuraDuration()
{
if(m_auraSlot >= MAX_AURAS || m_isPassive)
return;
if( m_target->GetTypeId() == TYPEID_PLAYER)
{
WorldPacket data(SMSG_UPDATE_AURA_DURATION, 5);
data << (uint8)m_auraSlot << (uint32)m_duration;
((Player*)m_target)->SendDirectMessage(&data);
data.Initialize(SMSG_SET_EXTRA_AURA_INFO, (8+1+4+4+4));
data.append(m_target->GetPackGUID());
data << uint8(m_auraSlot);
data << uint32(GetId());
data << uint32(GetAuraMaxDuration());
data << uint32(GetAuraDuration());
((Player*)m_target)->SendDirectMessage(&data);
}
// not send in case player loading (will not work anyway until player not added to map), sent in visibility change code
if(m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading())
return;
Unit* caster = GetCaster();
if(caster && caster->GetTypeId() == TYPEID_PLAYER && caster != m_target)
SendAuraDurationForCaster((Player*)caster);
}
void Aura::SendAuraDurationForCaster(Player* caster)
{
WorldPacket data(SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE, (8+1+4+4+4));
data.append(m_target->GetPackGUID());
data << uint8(m_auraSlot);
data << uint32(GetId());
data << uint32(GetAuraMaxDuration()); // full
data << uint32(GetAuraDuration()); // remain
caster->GetSession()->SendPacket(&data);
}
void Aura::_AddAura()
{
if (!GetId())
@ -913,7 +879,7 @@ void Aura::_AddAura()
{
for (uint8 i = 0; i < MAX_POSITIVE_AURAS; i++)
{
if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
if (m_target->GetVisibleAura(i) == 0)
{
slot = i;
break;
@ -924,7 +890,7 @@ void Aura::_AddAura()
{
for (uint8 i = MAX_POSITIVE_AURAS; i < MAX_AURAS; i++)
{
if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
if (m_target->GetVisibleAura(i) == 0)
{
slot = i;
break;
@ -939,16 +905,15 @@ void Aura::_AddAura()
{
if(slot < MAX_AURAS) // slot found
{
SetAura(slot, false);
SetAuraFlag(slot, true);
SetAuraLevel(slot,caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
SetAura(false);
SetAuraFlags(AFLAG_EFF_INDEX_0 | AFLAG_NOT_GUID | (GetAuraMaxDuration() ? AFLAG_DURATION : AFLAG_NONE) | (IsPositive() ? AFLAG_UNK1 : AFLAG_NONE));
SetAuraLevel(caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
UpdateAuraCharges();
SendAuraUpdate(false);
// update for out of range group members
m_target->UpdateAuraForGroup(slot);
}
UpdateAuraDuration();
}
}
else // use found slot
@ -1005,7 +970,7 @@ void Aura::_RemoveAura()
if(slot >= MAX_AURAS) // slot not set
return;
if(m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + slot)) == 0)
if(m_target->GetVisibleAura(slot) == 0)
return;
bool samespell = false;
@ -1034,11 +999,12 @@ void Aura::_RemoveAura()
// only remove icon when the last aura of the spell is removed (current aura already removed from list)
if (!samespell)
{
SetAura(slot, true);
SetAuraFlag(slot, false);
SetAuraLevel(slot,caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
SetAura(true);
SetAuraFlags(AFLAG_NONE);
SetAuraLevel(0);
SetAuraCharges(0);
SendAuraUpdate(true);
SetAuraApplication(slot, 0);
// update for out of range group members
m_target->UpdateAuraForGroup(slot);
@ -1075,44 +1041,40 @@ void Aura::_RemoveAura()
((Player*)caster)->SendCooldownEvent(GetSpellProto());
}
}
else if(sameaura) // decrease count for spell, only for same aura effect, or this spell auras in remove proccess.
else if(sameaura) // decrease count for spell, only for same aura effect, or this spell auras in remove process.
UpdateSlotCounterAndDuration(false);
}
void Aura::SetAuraFlag(uint32 slot, bool add)
void Aura::SendAuraUpdate(bool remove)
{
uint32 index = slot / 4;
uint32 byte = (slot % 4) * 8;
uint32 val = m_target->GetUInt32Value(UNIT_FIELD_AURAFLAGS + index);
val &= ~((uint32)AFLAG_MASK << byte);
if(add)
WorldPacket data(SMSG_AURA_UPDATE);
data.append(m_target->GetPackGUID());
data << uint8(GetAuraSlot());
data << uint32(remove ? 0 : GetId());
if(remove)
{
if (IsPositive())
val |= ((uint32)AFLAG_POSITIVE << byte);
else
val |= ((uint32)AFLAG_NEGATIVE << byte);
m_target->SendMessageToSet(&data, true);
return;
}
m_target->SetUInt32Value(UNIT_FIELD_AURAFLAGS + index, val);
}
void Aura::SetAuraLevel(uint32 slot,uint32 level)
{
uint32 index = slot / 4;
uint32 byte = (slot % 4) * 8;
uint32 val = m_target->GetUInt32Value(UNIT_FIELD_AURALEVELS + index);
val &= ~(0xFF << byte);
val |= (level << byte);
m_target->SetUInt32Value(UNIT_FIELD_AURALEVELS + index, val);
}
uint8 auraFlags = GetAuraFlags();
data << uint8(auraFlags);
data << uint8(GetAuraLevel());
data << uint8(GetAuraCharges());
void Aura::SetAuraApplication(uint32 slot, int8 count)
{
uint32 index = slot / 4;
uint32 byte = (slot % 4) * 8;
uint32 val = m_target->GetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS + index);
val &= ~(0xFF << byte);
val |= ((uint8(count)) << byte);
m_target->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS + index, val);
/*if(!(auraFlags & AFLAG_NOT_GUID))
{
data << uint8(0); // pguid
}*/
if(auraFlags & AFLAG_DURATION)
{
data << uint32(GetAuraMaxDuration());
data << uint32(GetAuraDuration());
}
m_target->SendMessageToSet(&data, true);
}
void Aura::UpdateSlotCounterAndDuration(bool add)
@ -1143,9 +1105,8 @@ void Aura::UpdateSlotCounterAndDuration(bool add)
if(!add)
--count;
SetAuraApplication(slot, count);
UpdateAuraDuration();
SetAuraCharges(count);
SendAuraUpdate(false);
}
/*********************************************************/
@ -2933,6 +2894,7 @@ void Aura::HandleModPossess(bool apply, bool Real)
{
WorldPacket data(SMSG_PET_SPELLS, 8);
data << uint64(0);
data << uint32(0);
((Player*)caster)->GetSession()->SendPacket(&data);
}
if(m_target->GetTypeId() == TYPEID_UNIT)
@ -3065,6 +3027,7 @@ void Aura::HandleModCharm(bool apply, bool Real)
{
WorldPacket data(SMSG_PET_SPELLS, 8);
data << uint64(0);
data << uint32(0);
((Player*)caster)->GetSession()->SendPacket(&data);
}
if(m_target->GetTypeId() == TYPEID_UNIT)
@ -5634,6 +5597,7 @@ void Aura::PeriodicTick()
data << (uint32)GetSpellSchoolMask(GetSpellProto()); // will be mask in 2.4.x
data << (uint32)absorb;
data << (uint32)resist;
data << uint32(0); // wotlk
m_target->SendMessageToSet(&data,true);
Unit* target = m_target; // aura can be deleted in DealDamage
@ -5811,6 +5775,7 @@ void Aura::PeriodicTick()
data << uint32(1);
data << uint32(m_modifier.m_auraname);
data << (uint32)pdamage;
data << uint32(0); // wotlk
m_target->SendMessageToSet(&data,true);
int32 gain = m_target->ModifyHealth(pdamage);
@ -6340,3 +6305,18 @@ void Aura::HandleArenaPreparation(bool apply, bool Real)
else
m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION);
}
void Aura::HandleAuraControlVehicle(bool apply, bool Real)
{
if(!Real)
return;
if(m_target->GetTypeId() != TYPEID_PLAYER)
return;
if(Pet *pet = m_target->GetPet())
pet->Remove(PET_SAVE_AS_CURRENT);
WorldPacket data(SMSG_UNKNOWN_1181, 0);
((Player*)m_target)->GetSession()->SendPacket(&data);
}

View file

@ -198,6 +198,7 @@ class MANGOS_DLL_SPEC Aura
void HandleModSpellDamagePercentFromStat(bool apply, bool Real);
void HandleModSpellHealingPercentFromStat(bool apply, bool Real);
void HandleAuraModDispelResist(bool apply, bool Real);
void HandleAuraControlVehicle(bool apply, bool Real);
void HandleModSpellDamagePercentFromAttackPower(bool apply, bool Real);
void HandleModSpellHealingPercentFromAttackPower(bool apply, bool Real);
void HandleAuraModPacifyAndSilence(bool Apply, bool Real);
@ -229,8 +230,6 @@ class MANGOS_DLL_SPEC Aura
int32 GetAuraDuration() const { return m_duration; }
void SetAuraDuration(int32 duration) { m_duration = duration; }
time_t GetAuraApplyTime() { return m_applyTime; }
void UpdateAuraDuration();
void SendAuraDurationForCaster(Player* caster);
uint64 const& GetCasterGUID() const { return m_caster_guid; }
Unit* GetCaster() const;
@ -247,13 +246,19 @@ class MANGOS_DLL_SPEC Aura
uint8 GetAuraSlot() const { return m_auraSlot; }
void SetAuraSlot(uint8 slot) { m_auraSlot = slot; }
uint8 GetAuraFlags() const { return m_auraFlags; }
void SetAuraFlags(uint8 flags) { m_auraFlags = flags; }
uint8 GetAuraLevel() const { return m_auraLevel; }
void SetAuraLevel(uint8 level) { m_auraLevel = level; }
uint8 GetAuraCharges() const { return m_procCharges; }
void SetAuraCharges(uint8 charges) { m_procCharges = charges; }
void SetAura(bool remove) { m_target->SetVisibleAura(m_auraSlot, remove ? 0 : GetId()); }
void SendAuraUpdate(bool remove);
void UpdateAuraCharges()
{
uint8 slot = GetAuraSlot();
// only aura in slot with charges and without stack limitation
if (slot < MAX_AURAS && m_procCharges >= 1 && GetSpellProto()->StackAmount==0)
SetAuraApplication(slot, m_procCharges - 1);
if (m_auraSlot < MAX_AURAS && m_procCharges >= 1 && GetSpellProto()->StackAmount==0)
SetAuraCharges(m_procCharges - 1);
}
bool IsPositive() { return m_positive; }
@ -314,6 +319,8 @@ class MANGOS_DLL_SPEC Aura
AuraRemoveMode m_removeMode;
uint8 m_auraSlot;
uint8 m_auraFlags;
uint8 m_auraLevel;
bool m_positive:1;
bool m_permanent:1;
@ -333,10 +340,6 @@ class MANGOS_DLL_SPEC Aura
private:
void UpdateSlotCounterAndDuration(bool add);
void CleanupTriggeredSpells();
void SetAura(uint32 slot, bool remove) { m_target->SetUInt32Value(UNIT_FIELD_AURA + slot, remove ? 0 : GetId()); }
void SetAuraFlag(uint32 slot, bool add);
void SetAuraLevel(uint32 slot, uint32 level);
void SetAuraApplication(uint32 slot, int8 count);
};
class MANGOS_DLL_SPEC AreaAura : public Aura

View file

@ -130,7 +130,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectPickPocket, // 71 SPELL_EFFECT_PICKPOCKET
&Spell::EffectAddFarsight, // 72 SPELL_EFFECT_ADD_FARSIGHT
&Spell::EffectSummonGuardian, // 73 SPELL_EFFECT_SUMMON_POSSESSED
&Spell::EffectSummonTotem, // 74 SPELL_EFFECT_SUMMON_TOTEM
&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
@ -210,6 +210,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
&Spell::EffectNULL, //155 Allows you to equip two-handed axes, maces and swords in one hand, but you attack $49152s1% slower than normal.
&Spell::EffectNULL, //156 Test Add Sockets Enchant
&Spell::EffectNULL, //157
&Spell::EffectNULL, //158
&Spell::EffectNULL //159
};
void Spell::EffectNULL(uint32 /*i*/)
@ -2892,10 +2898,10 @@ void Spell::EffectOpenLock(uint32 /*i*/)
}
// check key
for(int i = 0; i < 5; ++i)
for(int i = 0; i < 8; ++i)
{
// type==1 This means lockInfo->key[i] is an item
if(lockInfo->keytype[i]==LOCK_KEY_ITEM && lockInfo->key[i] && m_CastItem && m_CastItem->GetEntry()==lockInfo->key[i])
// Type==1 This means lockInfo->Index[i] is an item
if(lockInfo->Type[i]==LOCK_KEY_ITEM && lockInfo->Index[i] && m_CastItem && m_CastItem->GetEntry()==lockInfo->Index[i])
{
SendLoot(guid, loottype);
return;
@ -2913,9 +2919,9 @@ void Spell::EffectOpenLock(uint32 /*i*/)
// skill bonus provided by casting spell (mostly item spells)
uint32 spellSkillBonus = uint32(m_currentBasePoints[0]+1);
uint32 reqSkillValue = lockInfo->requiredminingskill;
uint32 reqSkillValue = lockInfo->Skill[0];
if(lockInfo->requiredlockskill) // required pick lock skill applying
if(lockInfo->Skill[1]) // required pick lock skill applying
{
if(SkillId != SKILL_LOCKPICKING) // wrong skill (cheating?)
{
@ -2923,7 +2929,7 @@ void Spell::EffectOpenLock(uint32 /*i*/)
return;
}
reqSkillValue = lockInfo->requiredlockskill;
reqSkillValue = lockInfo->Skill[1];
}
else if(SkillId == SKILL_LOCKPICKING) // apply picklock skill to wrong target
{
@ -3194,16 +3200,16 @@ void Spell::EffectSummon(uint32 i)
if(duration > 0)
spawnCreature->SetDuration(duration);
spawnCreature->SetUInt64Value(UNIT_FIELD_SUMMONEDBY,m_caster->GetGUID());
spawnCreature->SetUInt32Value(UNIT_NPC_FLAGS , 0);
spawnCreature->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, m_caster->GetGUID());
spawnCreature->SetUInt32Value(UNIT_NPC_FLAGS, 0);
spawnCreature->setPowerType(POWER_MANA);
spawnCreature->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,m_caster->getFaction());
spawnCreature->SetUInt32Value(UNIT_FIELD_FLAGS,0);
spawnCreature->SetUInt32Value(UNIT_FIELD_BYTES_0,2048);
spawnCreature->SetUInt32Value(UNIT_FIELD_BYTES_1,0);
spawnCreature->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP,0);
spawnCreature->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE,0);
spawnCreature->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP,1000);
spawnCreature->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, m_caster->getFaction());
spawnCreature->SetUInt32Value(UNIT_FIELD_FLAGS, 0);
spawnCreature->SetUInt32Value(UNIT_FIELD_BYTES_0, 2048);
spawnCreature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
spawnCreature->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, 0);
spawnCreature->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0);
spawnCreature->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, 1000);
spawnCreature->SetUInt64Value(UNIT_FIELD_CREATEDBY, m_caster->GetGUID());
spawnCreature->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
@ -3246,7 +3252,7 @@ void Spell::EffectLearnSpell(uint32 i)
Player *player = (Player*)unitTarget;
uint32 spellToLearn = (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) ? damage : m_spellInfo->EffectTriggerSpell[i];
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);
sLog.outDebug( "Spell: Player %u have learned spell %u from NpcGUID=%u", player->GetGUIDLow(), spellToLearn, m_caster->GetGUIDLow() );
@ -3904,10 +3910,13 @@ void Spell::EffectTameCreature(uint32 /*i*/)
pet->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, m_caster->GetGUID());
pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, m_caster->GetGUID());
pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,m_caster->getFaction());
pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, m_caster->getFaction());
pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
if(!pet->InitStatsForLevel(creatureTarget->getLevel()))
uint32 level = (creatureTarget->getLevel() < (m_caster->getLevel() - 5)) ? (m_caster->getLevel() - 5) : creatureTarget->getLevel();
pet->SetFreeTalentPoints(pet->GetMaxTalentPointsForLevel(level));
if(!pet->InitStatsForLevel(level))
{
sLog.outError("ERROR: InitStatsForLevel() in EffectTameCreature failed! Pet deleted.");
delete pet;
@ -3915,7 +3924,7 @@ void Spell::EffectTameCreature(uint32 /*i*/)
}
// prepare visual effect for levelup
pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()-1);
pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
pet->GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true);
// this enables pet details window (Shift+P)
@ -3926,7 +3935,7 @@ void Spell::EffectTameCreature(uint32 /*i*/)
MapManager::Instance().GetMap(pet->GetMapId(), pet)->Add((Creature*)pet);
// visual effect for levelup
pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel());
pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
if(m_caster->GetTypeId() == TYPEID_PLAYER)
{
@ -4048,13 +4057,13 @@ void Spell::EffectSummonPet(uint32 i)
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_NPC_FLAGS, 0);
NewSummon->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, faction);
NewSummon->SetUInt32Value(UNIT_FIELD_BYTES_0,2048);
NewSummon->SetUInt32Value(UNIT_FIELD_BYTES_1,0);
NewSummon->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP,time(NULL));
NewSummon->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE,0);
NewSummon->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP,1000);
NewSummon->SetUInt32Value(UNIT_FIELD_BYTES_0, 2048);
NewSummon->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
NewSummon->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
NewSummon->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0);
NewSummon->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, 1000);
NewSummon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
NewSummon->GetCharmInfo()->SetPetNumber(pet_number, true);
@ -4063,7 +4072,7 @@ void Spell::EffectSummonPet(uint32 i)
// this enables popup window (pet dismiss, cancel), hunter pet additional flags set later
NewSummon->SetUInt32Value(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE);
NewSummon->InitStatsForLevel( petlevel);
NewSummon->InitStatsForLevel(petlevel);
NewSummon->InitPetCreateSpells();
if(NewSummon->getPetType()==SUMMON_PET)
@ -4122,7 +4131,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);
@ -4203,7 +4211,7 @@ void Spell::EffectWeaponDmg(uint32 i)
{
int32 duration = GetSpellDuration(proto);
(*itr)->SetAuraDuration(duration);
(*itr)->UpdateAuraDuration();
(*itr)->SendAuraUpdate(false);
bonusDamagePercentMod += 1.0f; // +100%
}
}
@ -5089,6 +5097,45 @@ void Spell::EffectActivateObject(uint32 effect_idx)
sWorld.ScriptCommandStart(activateCommand, delay_secs, m_caster, gameObjTarget);
}
void Spell::EffectApplyGlyph(uint32 i)
{
if(m_caster->GetTypeId() != TYPEID_PLAYER)
return;
Player *player = (Player*)m_caster;
// remove old glyph
if(uint32 oldglyph = player->GetGlyph(m_glyphIndex))
{
if(GlyphPropertiesEntry const *old_gp = sGlyphPropertiesStore.LookupEntry(oldglyph))
{
player->RemoveAurasDueToSpell(old_gp->SpellId);
player->SetGlyph(m_glyphIndex, 0);
}
}
// apply new one
if(uint32 glyph = m_spellInfo->EffectMiscValue[i])
{
if(GlyphPropertiesEntry const *gp = sGlyphPropertiesStore.LookupEntry(glyph))
{
if(GlyphSlotEntry const *gs = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
{
if(gp->TypeFlags != gs->TypeFlags)
{
SendCastResult(SPELL_FAILED_INVALID_GLYPH);
return; // glyph slot missmatch
}
}
player->CastSpell(m_caster, gp->SpellId, true);
player->SetGlyph(m_glyphIndex, glyph);
if(m_CastItem)
player->DestroyItemCount(m_CastItem->GetEntry(), 1, true);
}
}
}
void Spell::EffectSummonTotem(uint32 i)
{
uint8 slot = 0;
@ -5941,9 +5988,9 @@ void Spell::EffectTransmitted(uint32 effIndex)
{
m_caster->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT,pGameObj->GetGUID());
// Orientation3
pGameObj->SetFloatValue(GAMEOBJECT_ROTATION + 2, 0.88431775569915771 );
pGameObj->SetFloatValue(GAMEOBJECT_PARENTROTATION + 2, 0.88431775569915771 );
// Orientation4
pGameObj->SetFloatValue(GAMEOBJECT_ROTATION + 3, -0.4668855369091033 );
pGameObj->SetFloatValue(GAMEOBJECT_PARENTROTATION + 3, -0.4668855369091033 );
m_caster->AddGameObject(pGameObj); // will removed at spell cancel
// end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo))

View file

@ -35,15 +35,17 @@
void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
{
// TODO: add targets.read() check
CHECK_PACKET_SIZE(recvPacket,1+1+1+1+8);
CHECK_PACKET_SIZE(recvPacket,1+1+1+4+8+4+1);
Player* pUser = _player;
uint8 bagIndex, slot;
uint8 spell_count; // number of spells at item, not used
uint8 unk_flags; // flags (if 0x02 - some additional data are received)
uint8 cast_count; // next cast if exists (single or not)
uint64 item_guid;
uint32 glyphIndex; // something to do with glyphs?
uint32 spellid; // casted spell id
recvPacket >> bagIndex >> slot >> spell_count >> cast_count >> item_guid;
recvPacket >> bagIndex >> slot >> cast_count >> spellid >> item_guid >> glyphIndex >> unk_flags;
Item *pItem = pUser->GetItemByPos(bagIndex, slot);
if(!pItem)
@ -58,7 +60,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
return;
}
sLog.outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, spell_count: %u , cast_count: %u, Item: %u, data length = %i", bagIndex, slot, spell_count, cast_count, pItem->GetEntry(), recvPacket.size());
sLog.outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, cast_count: %u, spellid: %u, Item: %u, glyphIndex: %u, unk_flags: %u, data length = %i", bagIndex, slot, cast_count, spellid, pItem->GetEntry(), glyphIndex, unk_flags, recvPacket.size());
ItemPrototype const *proto = pItem->GetProto();
if(!proto)
@ -125,14 +127,15 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
// no script or script not process request by self
// special learning case
if(pItem->GetProto()->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN)
if((pItem->GetProto()->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN) || (pItem->GetProto()->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN_PET))
{
uint32 learn_spell_id = pItem->GetProto()->Spells[0].SpellId;
uint32 learning_spell_id = pItem->GetProto()->Spells[1].SpellId;
SpellEntry const *spellInfo = sSpellStore.LookupEntry(SPELL_ID_GENERIC_LEARN);
SpellEntry const *spellInfo = sSpellStore.LookupEntry(learn_spell_id);
if(!spellInfo)
{
sLog.outError("Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, SPELL_ID_GENERIC_LEARN);
sLog.outError("Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, learn_spell_id);
pUser->SendEquipError(EQUIP_ERR_NONE,pItem,NULL);
return;
}
@ -169,7 +172,8 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
Spell *spell = new Spell(pUser, spellInfo, (count > 0));
spell->m_CastItem = pItem;
spell->m_cast_count = cast_count; //set count of casts
spell->m_cast_count = cast_count; // set count of casts
spell->m_glyphIndex = glyphIndex; // glyph index
spell->prepare(&targets);
++count;
@ -224,7 +228,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
}
// required picklocking
if(lockInfo->requiredlockskill || lockInfo->requiredminingskill)
if(lockInfo->Skill[1] || lockInfo->Skill[0])
{
pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, pItem, NULL );
return;
@ -260,10 +264,9 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data )
{
CHECK_PACKET_SIZE(recv_data,8);
CHECK_PACKET_SIZE(recv_data, 8);
uint64 guid;
uint32 spellId = OPEN_CHEST;
recv_data >> guid;
@ -281,15 +284,16 @@ void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data )
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
{
CHECK_PACKET_SIZE(recvPacket,4+1+2);
CHECK_PACKET_SIZE(recvPacket,1+4+1);
uint32 spellId;
uint8 cast_count;
recvPacket >> spellId;
uint8 cast_count, unk_flags;
recvPacket >> cast_count;
recvPacket >> spellId;
recvPacket >> unk_flags; // flags (if 0x02 - some additional data are received)
sLog.outDebug("WORLD: got cast spell packet, spellId - %u, cast_count: %u data length = %i",
spellId, cast_count, recvPacket.size());
sLog.outDebug("WORLD: got cast spell packet, spellId - %u, cast_count: %u, unk_flags %u, data length = %i",
spellId, cast_count, unk_flags, recvPacket.size());
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );

View file

@ -1549,12 +1549,12 @@ void SpellMgr::LoadSpellChains()
continue;
}
if(node.req!=talentEntry->DependsOnSpell)
/*if(node.req!=talentEntry->DependsOnSpell)
{
sLog.outErrorDb("Talent %u (prev: %u, first: %u, rank: %d, req: %u) listed in `spell_chain` has wrong required spell.",
spell_id,node.prev,node.first,node.rank,node.req);
continue;
}
}*/
}
}
@ -2046,7 +2046,7 @@ bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg)
bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id)
{
// normal case
if( spellInfo->AreaId && spellInfo->AreaId != zone_id && spellInfo->AreaId != area_id )
if( spellInfo->AreaId > 0 && spellInfo->AreaId != zone_id && spellInfo->AreaId != area_id )
return false;
// elixirs (all area dependent elixirs have family SPELLFAMILY_POTION, use this for speedup)

View file

@ -36,175 +36,188 @@ extern SQLStorage sSpellThreatStore;
enum SpellFailedReason
{
SPELL_FAILED_AFFECTING_COMBAT = 0x00,
SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 0x01,
SPELL_FAILED_ALREADY_AT_FULL_MANA = 0x02,
SPELL_FAILED_ALREADY_AT_FULL_POWER = 0x03,
SPELL_FAILED_ALREADY_BEING_TAMED = 0x04,
SPELL_FAILED_ALREADY_HAVE_CHARM = 0x05,
SPELL_FAILED_ALREADY_HAVE_SUMMON = 0x06,
SPELL_FAILED_ALREADY_OPEN = 0x07,
SPELL_FAILED_AURA_BOUNCED = 0x08,
SPELL_FAILED_AUTOTRACK_INTERRUPTED = 0x09,
SPELL_FAILED_BAD_IMPLICIT_TARGETS = 0x0A,
SPELL_FAILED_BAD_TARGETS = 0x0B,
SPELL_FAILED_CANT_BE_CHARMED = 0x0C,
SPELL_FAILED_CANT_BE_DISENCHANTED = 0x0D,
SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 0x0E,
SPELL_FAILED_CANT_BE_PROSPECTED = 0x0F,
SPELL_FAILED_CANT_CAST_ON_TAPPED = 0x10,
SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 0x11,
SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 0x12,
SPELL_FAILED_CANT_STEALTH = 0x13,
SPELL_FAILED_CASTER_AURASTATE = 0x14,
SPELL_FAILED_CASTER_DEAD = 0x15,
SPELL_FAILED_CHARMED = 0x16,
SPELL_FAILED_CHEST_IN_USE = 0x17,
SPELL_FAILED_CONFUSED = 0x18,
SPELL_FAILED_DONT_REPORT = 0x19,
SPELL_FAILED_EQUIPPED_ITEM = 0x1A,
SPELL_FAILED_EQUIPPED_ITEM_CLASS = 0x1B,
SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 0x1C,
SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 0x1D,
SPELL_FAILED_ERROR = 0x1E,
SPELL_FAILED_FIZZLE = 0x1F,
SPELL_FAILED_FLEEING = 0x20,
SPELL_FAILED_FOOD_LOWLEVEL = 0x21,
SPELL_FAILED_HIGHLEVEL = 0x22,
SPELL_FAILED_HUNGER_SATIATED = 0x23,
SPELL_FAILED_IMMUNE = 0x24,
SPELL_FAILED_INTERRUPTED = 0x25,
SPELL_FAILED_INTERRUPTED_COMBAT = 0x26,
SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 0x27,
SPELL_FAILED_ITEM_GONE = 0x28,
SPELL_FAILED_ITEM_NOT_FOUND = 0x29,
SPELL_FAILED_ITEM_NOT_READY = 0x2A,
SPELL_FAILED_LEVEL_REQUIREMENT = 0x2B,
SPELL_FAILED_LINE_OF_SIGHT = 0x2C,
SPELL_FAILED_LOWLEVEL = 0x2D,
SPELL_FAILED_LOW_CASTLEVEL = 0x2E,
SPELL_FAILED_MAINHAND_EMPTY = 0x2F,
SPELL_FAILED_MOVING = 0x30,
SPELL_FAILED_NEED_AMMO = 0x31,
SPELL_FAILED_NEED_AMMO_POUCH = 0x32,
SPELL_FAILED_NEED_EXOTIC_AMMO = 0x33,
SPELL_FAILED_NOPATH = 0x34,
SPELL_FAILED_NOT_BEHIND = 0x35,
SPELL_FAILED_NOT_FISHABLE = 0x36,
SPELL_FAILED_NOT_FLYING = 0x37,
SPELL_FAILED_NOT_HERE = 0x38,
SPELL_FAILED_NOT_INFRONT = 0x39,
SPELL_FAILED_NOT_IN_CONTROL = 0x3A,
SPELL_FAILED_NOT_KNOWN = 0x3B,
SPELL_FAILED_NOT_MOUNTED = 0x3C,
SPELL_FAILED_NOT_ON_TAXI = 0x3D,
SPELL_FAILED_NOT_ON_TRANSPORT = 0x3E,
SPELL_FAILED_NOT_READY = 0x3F,
SPELL_FAILED_NOT_SHAPESHIFT = 0x40,
SPELL_FAILED_NOT_STANDING = 0x41,
SPELL_FAILED_NOT_TRADEABLE = 0x42,
SPELL_FAILED_NOT_TRADING = 0x43,
SPELL_FAILED_NOT_UNSHEATHED = 0x44,
SPELL_FAILED_NOT_WHILE_GHOST = 0x45,
SPELL_FAILED_NO_AMMO = 0x46,
SPELL_FAILED_NO_CHARGES_REMAIN = 0x47,
SPELL_FAILED_NO_CHAMPION = 0x48,
SPELL_FAILED_NO_COMBO_POINTS = 0x49,
SPELL_FAILED_NO_DUELING = 0x4A,
SPELL_FAILED_NO_ENDURANCE = 0x4B,
SPELL_FAILED_NO_FISH = 0x4C,
SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 0x4D,
SPELL_FAILED_NO_MOUNTS_ALLOWED = 0x4E,
SPELL_FAILED_NO_PET = 0x4F,
SPELL_FAILED_NO_POWER = 0x50,
SPELL_FAILED_NOTHING_TO_DISPEL = 0x51,
SPELL_FAILED_NOTHING_TO_STEAL = 0x52,
SPELL_FAILED_ONLY_ABOVEWATER = 0x53,
SPELL_FAILED_ONLY_DAYTIME = 0x54,
SPELL_FAILED_ONLY_INDOORS = 0x55,
SPELL_FAILED_ONLY_MOUNTED = 0x56,
SPELL_FAILED_ONLY_NIGHTTIME = 0x57,
SPELL_FAILED_ONLY_OUTDOORS = 0x58,
SPELL_FAILED_ONLY_SHAPESHIFT = 0x59,
SPELL_FAILED_ONLY_STEALTHED = 0x5A,
SPELL_FAILED_ONLY_UNDERWATER = 0x5B,
SPELL_FAILED_OUT_OF_RANGE = 0x5C,
SPELL_FAILED_PACIFIED = 0x5D,
SPELL_FAILED_POSSESSED = 0x5E,
SPELL_FAILED_REAGENTS = 0x5F,
SPELL_FAILED_REQUIRES_AREA = 0x60,
SPELL_FAILED_REQUIRES_SPELL_FOCUS = 0x61,
SPELL_FAILED_ROOTED = 0x62,
SPELL_FAILED_SILENCED = 0x63,
SPELL_FAILED_SPELL_IN_PROGRESS = 0x64,
SPELL_FAILED_SPELL_LEARNED = 0x65,
SPELL_FAILED_SPELL_UNAVAILABLE = 0x66,
SPELL_FAILED_STUNNED = 0x67,
SPELL_FAILED_TARGETS_DEAD = 0x68,
SPELL_FAILED_TARGET_AFFECTING_COMBAT = 0x69,
SPELL_FAILED_TARGET_AURASTATE = 0x6A,
SPELL_FAILED_TARGET_DUELING = 0x6B,
SPELL_FAILED_TARGET_ENEMY = 0x6C,
SPELL_FAILED_TARGET_ENRAGED = 0x6D,
SPELL_FAILED_TARGET_FRIENDLY = 0x6E,
SPELL_FAILED_TARGET_IN_COMBAT = 0x6F,
SPELL_FAILED_TARGET_IS_PLAYER = 0x70,
SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 0x71,
SPELL_FAILED_TARGET_NOT_DEAD = 0x72,
SPELL_FAILED_TARGET_NOT_IN_PARTY = 0x73,
SPELL_FAILED_TARGET_NOT_LOOTED = 0x74,
SPELL_FAILED_TARGET_NOT_PLAYER = 0x75,
SPELL_FAILED_TARGET_NO_POCKETS = 0x76,
SPELL_FAILED_TARGET_NO_WEAPONS = 0x77,
SPELL_FAILED_TARGET_UNSKINNABLE = 0x78,
SPELL_FAILED_THIRST_SATIATED = 0x79,
SPELL_FAILED_TOO_CLOSE = 0x7A,
SPELL_FAILED_TOO_MANY_OF_ITEM = 0x7B,
SPELL_FAILED_TOTEM_CATEGORY = 0x7C,
SPELL_FAILED_TOTEMS = 0x7D,
SPELL_FAILED_TRAINING_POINTS = 0x7E,
SPELL_FAILED_TRY_AGAIN = 0x7F,
SPELL_FAILED_UNIT_NOT_BEHIND = 0x80,
SPELL_FAILED_UNIT_NOT_INFRONT = 0x81,
SPELL_FAILED_WRONG_PET_FOOD = 0x82,
SPELL_FAILED_NOT_WHILE_FATIGUED = 0x83,
SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 0x84,
SPELL_FAILED_NOT_WHILE_TRADING = 0x85,
SPELL_FAILED_TARGET_NOT_IN_RAID = 0x86,
SPELL_FAILED_DISENCHANT_WHILE_LOOTING = 0x87,
SPELL_FAILED_PROSPECT_WHILE_LOOTING = 0x88,
SPELL_FAILED_PROSPECT_NEED_MORE = 0x89,
SPELL_FAILED_TARGET_FREEFORALL = 0x8A,
SPELL_FAILED_NO_EDIBLE_CORPSES = 0x8B,
SPELL_FAILED_ONLY_BATTLEGROUNDS = 0x8C,
SPELL_FAILED_TARGET_NOT_GHOST = 0x8D,
SPELL_FAILED_TOO_MANY_SKILLS = 0x8E,
SPELL_FAILED_TRANSFORM_UNUSABLE = 0x8F,
SPELL_FAILED_WRONG_WEATHER = 0x90,
SPELL_FAILED_DAMAGE_IMMUNE = 0x91,
SPELL_FAILED_PREVENTED_BY_MECHANIC = 0x92,
SPELL_FAILED_PLAY_TIME = 0x93,
SPELL_FAILED_REPUTATION = 0x94,
SPELL_FAILED_MIN_SKILL = 0x95,
SPELL_FAILED_NOT_IN_ARENA = 0x96,
SPELL_FAILED_NOT_ON_SHAPESHIFT = 0x97,
SPELL_FAILED_NOT_ON_STEALTHED = 0x98,
SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 0x99,
SPELL_FAILED_NOT_ON_MOUNTED = 0x9A,
SPELL_FAILED_TOO_SHALLOW = 0x9B,
SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 0x9C,
SPELL_FAILED_TARGET_IS_TRIVIAL = 0x9D,
SPELL_FAILED_BM_OR_INVISGOD = 0x9E,
SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 0x9F,
SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 0xA0,
SPELL_FAILED_NOT_IDLE = 0xA1,
SPELL_FAILED_NOT_INACTIVE = 0xA2,
SPELL_FAILED_PARTIAL_PLAYTIME = 0xA3,
SPELL_FAILED_NO_PLAYTIME = 0xA4,
SPELL_FAILED_NOT_IN_BATTLEGROUND = 0xA5,
SPELL_FAILED_ONLY_IN_ARENA = 0xA6,
SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 0xA7,
SPELL_FAILED_UNKNOWN = 0xA8,
SPELL_FAILED_AFFECTING_COMBAT = 0,
SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 1,
SPELL_FAILED_ALREADY_AT_FULL_MANA = 2,
SPELL_FAILED_ALREADY_AT_FULL_POWER = 3,
SPELL_FAILED_ALREADY_BEING_TAMED = 4,
SPELL_FAILED_ALREADY_HAVE_CHARM = 5,
SPELL_FAILED_ALREADY_HAVE_SUMMON = 6,
SPELL_FAILED_ALREADY_OPEN = 7,
SPELL_FAILED_AURA_BOUNCED = 8,
SPELL_FAILED_AUTOTRACK_INTERRUPTED = 9,
SPELL_FAILED_BAD_IMPLICIT_TARGETS = 10,
SPELL_FAILED_BAD_TARGETS = 11,
SPELL_FAILED_CANT_BE_CHARMED = 12,
SPELL_FAILED_CANT_BE_DISENCHANTED = 13,
SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 14,
SPELL_FAILED_CANT_BE_MILLED = 15,
SPELL_FAILED_CANT_BE_PROSPECTED = 16,
SPELL_FAILED_CANT_CAST_ON_TAPPED = 17,
SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 18,
SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 19,
SPELL_FAILED_CANT_STEALTH = 20,
SPELL_FAILED_CASTER_AURASTATE = 21,
SPELL_FAILED_CASTER_DEAD = 22,
SPELL_FAILED_CHARMED = 23,
SPELL_FAILED_CHEST_IN_USE = 24,
SPELL_FAILED_CONFUSED = 25,
SPELL_FAILED_DONT_REPORT = 26,
SPELL_FAILED_EQUIPPED_ITEM = 27,
SPELL_FAILED_EQUIPPED_ITEM_CLASS = 28,
SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 29,
SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 30,
SPELL_FAILED_ERROR = 31,
SPELL_FAILED_FIZZLE = 32,
SPELL_FAILED_FLEEING = 33,
SPELL_FAILED_FOOD_LOWLEVEL = 34,
SPELL_FAILED_HIGHLEVEL = 35,
SPELL_FAILED_HUNGER_SATIATED = 36,
SPELL_FAILED_IMMUNE = 37,
SPELL_FAILED_INCORRECT_AREA = 38,
SPELL_FAILED_INTERRUPTED = 39,
SPELL_FAILED_INTERRUPTED_COMBAT = 40,
SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 41,
SPELL_FAILED_ITEM_GONE = 42,
SPELL_FAILED_ITEM_NOT_FOUND = 43,
SPELL_FAILED_ITEM_NOT_READY = 44,
SPELL_FAILED_LEVEL_REQUIREMENT = 45,
SPELL_FAILED_LINE_OF_SIGHT = 46,
SPELL_FAILED_LOWLEVEL = 47,
SPELL_FAILED_LOW_CASTLEVEL = 48,
SPELL_FAILED_MAINHAND_EMPTY = 49,
SPELL_FAILED_MOVING = 50,
SPELL_FAILED_NEED_AMMO = 51,
SPELL_FAILED_NEED_AMMO_POUCH = 52,
SPELL_FAILED_NEED_EXOTIC_AMMO = 53,
SPELL_FAILED_NEED_MORE_ITEMS = 54,
SPELL_FAILED_NOPATH = 55,
SPELL_FAILED_NOT_BEHIND = 56,
SPELL_FAILED_NOT_FISHABLE = 57,
SPELL_FAILED_NOT_FLYING = 58,
SPELL_FAILED_NOT_HERE = 59,
SPELL_FAILED_NOT_INFRONT = 60,
SPELL_FAILED_NOT_IN_CONTROL = 61,
SPELL_FAILED_NOT_KNOWN = 62,
SPELL_FAILED_NOT_MOUNTED = 63,
SPELL_FAILED_NOT_ON_TAXI = 64,
SPELL_FAILED_NOT_ON_TRANSPORT = 65,
SPELL_FAILED_NOT_READY = 66,
SPELL_FAILED_NOT_SHAPESHIFT = 67,
SPELL_FAILED_NOT_STANDING = 68,
SPELL_FAILED_NOT_TRADEABLE = 69,
SPELL_FAILED_NOT_TRADING = 70,
SPELL_FAILED_NOT_UNSHEATHED = 71,
SPELL_FAILED_NOT_WHILE_GHOST = 72,
SPELL_FAILED_NOT_WHILE_LOOTING = 73,
SPELL_FAILED_NO_AMMO = 74,
SPELL_FAILED_NO_CHARGES_REMAIN = 75,
SPELL_FAILED_NO_CHAMPION = 76,
SPELL_FAILED_NO_COMBO_POINTS = 77,
SPELL_FAILED_NO_DUELING = 78,
SPELL_FAILED_NO_ENDURANCE = 79,
SPELL_FAILED_NO_FISH = 80,
SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 81,
SPELL_FAILED_NO_MOUNTS_ALLOWED = 82,
SPELL_FAILED_NO_PET = 83,
SPELL_FAILED_NO_POWER = 84,
SPELL_FAILED_NOTHING_TO_DISPEL = 85,
SPELL_FAILED_NOTHING_TO_STEAL = 86,
SPELL_FAILED_ONLY_ABOVEWATER = 87,
SPELL_FAILED_ONLY_DAYTIME = 88,
SPELL_FAILED_ONLY_INDOORS = 89,
SPELL_FAILED_ONLY_MOUNTED = 90,
SPELL_FAILED_ONLY_NIGHTTIME = 91,
SPELL_FAILED_ONLY_OUTDOORS = 92,
SPELL_FAILED_ONLY_SHAPESHIFT = 93,
SPELL_FAILED_ONLY_STEALTHED = 94,
SPELL_FAILED_ONLY_UNDERWATER = 95,
SPELL_FAILED_OUT_OF_RANGE = 96,
SPELL_FAILED_PACIFIED = 97,
SPELL_FAILED_POSSESSED = 98,
SPELL_FAILED_REAGENTS = 99,
SPELL_FAILED_REQUIRES_AREA = 100,
SPELL_FAILED_REQUIRES_SPELL_FOCUS = 101,
SPELL_FAILED_ROOTED = 102,
SPELL_FAILED_SILENCED = 103,
SPELL_FAILED_SPELL_IN_PROGRESS = 104,
SPELL_FAILED_SPELL_LEARNED = 105,
SPELL_FAILED_SPELL_UNAVAILABLE = 106,
SPELL_FAILED_STUNNED = 107,
SPELL_FAILED_TARGETS_DEAD = 108,
SPELL_FAILED_TARGET_AFFECTING_COMBAT = 109,
SPELL_FAILED_TARGET_AURASTATE = 110,
SPELL_FAILED_TARGET_DUELING = 111,
SPELL_FAILED_TARGET_ENEMY = 112,
SPELL_FAILED_TARGET_ENRAGED = 113,
SPELL_FAILED_TARGET_FRIENDLY = 114,
SPELL_FAILED_TARGET_IN_COMBAT = 115,
SPELL_FAILED_TARGET_IS_PLAYER = 116,
SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 117,
SPELL_FAILED_TARGET_NOT_DEAD = 118,
SPELL_FAILED_TARGET_NOT_IN_PARTY = 119,
SPELL_FAILED_TARGET_NOT_LOOTED = 120,
SPELL_FAILED_TARGET_NOT_PLAYER = 121,
SPELL_FAILED_TARGET_NO_POCKETS = 122,
SPELL_FAILED_TARGET_NO_WEAPONS = 123,
SPELL_FAILED_TARGET_NO_RANGED_WEAPONS = 124,
SPELL_FAILED_TARGET_UNSKINNABLE = 125,
SPELL_FAILED_THIRST_SATIATED = 126,
SPELL_FAILED_TOO_CLOSE = 127,
SPELL_FAILED_TOO_MANY_OF_ITEM = 128,
SPELL_FAILED_TOTEM_CATEGORY = 129,
SPELL_FAILED_TOTEMS = 130,
SPELL_FAILED_TRY_AGAIN = 131,
SPELL_FAILED_UNIT_NOT_BEHIND = 132,
SPELL_FAILED_UNIT_NOT_INFRONT = 133,
SPELL_FAILED_WRONG_PET_FOOD = 134,
SPELL_FAILED_NOT_WHILE_FATIGUED = 135,
SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 136,
SPELL_FAILED_NOT_WHILE_TRADING = 137,
SPELL_FAILED_TARGET_NOT_IN_RAID = 138,
SPELL_FAILED_TARGET_FREEFORALL = 139,
SPELL_FAILED_NO_EDIBLE_CORPSES = 140,
SPELL_FAILED_ONLY_BATTLEGROUNDS = 141,
SPELL_FAILED_TARGET_NOT_GHOST = 142,
SPELL_FAILED_TRANSFORM_UNUSABLE = 143,
SPELL_FAILED_WRONG_WEATHER = 144,
SPELL_FAILED_DAMAGE_IMMUNE = 145,
SPELL_FAILED_PREVENTED_BY_MECHANIC = 146,
SPELL_FAILED_PLAY_TIME = 147,
SPELL_FAILED_REPUTATION = 148,
SPELL_FAILED_MIN_SKILL = 149,
SPELL_FAILED_NOT_IN_ARENA = 150,
SPELL_FAILED_NOT_ON_SHAPESHIFT = 151,
SPELL_FAILED_NOT_ON_STEALTHED = 152,
SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 153,
SPELL_FAILED_NOT_ON_MOUNTED = 154,
SPELL_FAILED_TOO_SHALLOW = 155,
SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 156,
SPELL_FAILED_TARGET_IS_TRIVIAL = 157,
SPELL_FAILED_BM_OR_INVISGOD = 158,
SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 159,
SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 160,
SPELL_FAILED_NOT_IDLE = 161,
SPELL_FAILED_NOT_INACTIVE = 162,
SPELL_FAILED_PARTIAL_PLAYTIME = 163,
SPELL_FAILED_NO_PLAYTIME = 164,
SPELL_FAILED_NOT_IN_BATTLEGROUND = 165,
SPELL_FAILED_NOT_IN_RAID_INSTANCE = 166,
SPELL_FAILED_ONLY_IN_ARENA = 167,
SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 168,
SPELL_FAILED_ON_USE_ENCHANT = 169,
SPELL_FAILED_NOT_ON_GROUND = 170,
SPELL_FAILED_CUSTOM_ERROR = 171,
SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW = 172,
SPELL_FAILED_TOO_MANY_SOCKETS = 173,
SPELL_FAILED_INVALID_GLYPH = 174,
SPELL_FAILED_UNIQUE_GLYPH = 175,
SPELL_FAILED_GLYPH_SOCKET_LOCKED = 176,
SPELL_FAILED_NO_VALID_TARGETS = 177,
SPELL_FAILED_ITEM_AT_MAX_CHARGES = 178,
SPELL_FAILED_NOT_IN_BARBERSHOP = 179,
SPELL_FAILED_FISHING_TOO_LOW = 180,
SPELL_FAILED_UNKNOWN = 181
};
enum SpellFamilyNames