diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index df1efee..7373ff2 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -1339,10 +1339,16 @@ bool Pet::addSpell(uint32 spell_id,ActiveStates active /*= ACT_DECIDE*/, PetSpel if(IsPassiveSpell(spell_id)) newspell.active = ACT_PASSIVE; else - newspell.active = ACT_DISABLED; + newspell.active = IsPetAutoCastableSpell(spell_id) ? ACT_DISABLED : ACT_PASSIVE; } else - newspell.active = active; + { + if (((active != ACT_DISABLED) && (active != ACT_ENABLED)) || + IsPetAutoCastableSpell(spell_id)) + newspell.active = active; + else + newspell.active = ACT_PASSIVE; + } // talent: unlearn all other talent ranks (high and low) if(TalentSpellPos const* talentPos = GetTalentSpellPos(spell_id)) @@ -1726,6 +1732,9 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply) if(IsPassiveSpell(spellid)) return; + if (!IsPetAutoCastableSpell(spellid)) + return; + PetSpellMap::iterator itr = m_spells.find(spellid); int i; diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 874df02..c4a483c 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -259,7 +259,7 @@ enum ItemQualities #define SPELL_ATTR_EX_UNK14 0x00004000 // 14 #define SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY 0x00008000 // 15 remove auras on immunity #define SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE 0x00010000 // 16 unaffected by school immunity -#define SPELL_ATTR_EX_UNK17 0x00020000 // 17 +#define SPELL_ATTR_EX_PET_NOT_AUTOCASTABLE 0x00020000 // 17 not autocastable by pets?? #define SPELL_ATTR_EX_UNK18 0x00040000 // 18 #define SPELL_ATTR_EX_UNK19 0x00080000 // 19 #define SPELL_ATTR_EX_REQ_COMBO_POINTS1 0x00100000 // 20 Req combo points on target diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 5b7ba08..5949f47 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -98,6 +98,30 @@ bool IsPassiveSpell(uint32 spellId) return (spellInfo->Attributes & SPELL_ATTR_PASSIVE) != 0; } +bool IsPetAutoCastableSpell(uint32 spellId) +{ + // obtain spell info + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); + if (!spellInfo) + return false; + + // class-based check + if (spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK) + { + // family-based check + if ((spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_WARLOCK_PET_SPELLS) || + (spellInfo->SpellFamilyFlags2 & SPELLFAMILYFLAG_WARLOCK_PET_SPELLS2)) + { + // this is pet spell, verify autocastability + if (spellInfo->AttributesEx & SPELL_ATTR_EX_PET_NOT_AUTOCASTABLE) + return false; + } + } + + // default is autocastable + return true; +} + bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2) { SpellEntry const *spellInfo_1 = sSpellStore.LookupEntry(spellId_1); diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 48ef3f7..2690ecf 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -76,6 +76,9 @@ enum SpellFamilyNames #define SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE 0x9003E0000LL #define SPELLFAMILYFLAG_PALADIN_SEALS 0x26000C000A000000LL + +#define SPELLFAMILYFLAG_WARLOCK_PET_SPELLS 0x0350000042803000LL +#define SPELLFAMILYFLAG_WARLOCK_PET_SPELLS2 0x00000400LL // Spell clasification enum SpellSpecific { @@ -148,6 +151,7 @@ int32 CompareAuraRanks(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, ui bool IsSingleFromSpellSpecificPerCaster(SpellSpecific spellSpec1,SpellSpecific spellSpec2); bool IsSingleFromSpellSpecificRanksPerTarget(SpellSpecific spellId_spec, SpellSpecific i_spellId_spec); bool IsPassiveSpell(uint32 spellId); +bool IsPetAutoCastableSpell(uint32 spellId); inline bool IsPassiveSpellStackableWithRanks(SpellEntry const* spellProto) { diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index c49de70..6fdf843 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -10388,7 +10388,7 @@ void CharmInfo::InitCharmCreateSpells() } if(onlyselfcast || !IsPositiveSpell(spellId)) //only self cast and spells versus enemies are autocastable - newstate = ACT_DISABLED; + newstate = IsPetAutoCastableSpell(spellId) ? ACT_DISABLED : ACT_PASSIVE; else newstate = ACT_PASSIVE; @@ -10415,10 +10415,21 @@ bool CharmInfo::AddSpellToAB(uint32 oldid, uint32 newid, ActiveStates newstate) PetActionBar[i].SpellOrAction = newid; if (!oldid) { - if (newstate == ACT_DECIDE) - PetActionBar[i].Type = ACT_DISABLED; + if(newstate == ACT_DECIDE) + { + if(IsPassiveSpell(newid)) + PetActionBar[i].Type = ACT_PASSIVE; + else + PetActionBar[i].Type = IsPetAutoCastableSpell(newid) ? ACT_DISABLED : ACT_PASSIVE; + } else - PetActionBar[i].Type = newstate; + { + if (((newstate != ACT_DISABLED) && (newstate != ACT_ENABLED)) || + IsPetAutoCastableSpell(newid)) + PetActionBar[i].Type = newstate; + else + PetActionBar[i].Type = ACT_PASSIVE; + } } return true; @@ -10433,6 +10444,9 @@ void CharmInfo::ToggleCreatureAutocast(uint32 spellid, bool apply) if(IsPassiveSpell(spellid)) return; + if (!IsPetAutoCastableSpell(spellid)) + return; + for(uint32 x = 0; x < CREATURE_MAX_SPELLS; ++x) { if(spellid == m_charmspells[x].spellId)