diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index a257b4df65d..538f890766e 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -1514,10 +1514,10 @@ bool Pet::addSpell(uint32 spell_id, ActiveStates active /*= ACT_DECIDE*/, PetSpe if (active == ACT_DECIDE) // active was not used before, so we save it's autocast/passive state here { - if (IsPassiveSpell(spellInfo)) - newspell.active = ACT_PASSIVE; - else + if (IsAutocastable(spellInfo)) newspell.active = ACT_DISABLED; + else + newspell.active = ACT_PASSIVE; } else newspell.active = active; @@ -1959,7 +1959,7 @@ uint8 Pet::GetMaxTalentPointsForLevel(uint32 level) void Pet::ToggleAutocast(uint32 spellid, bool apply) { - if (IsPassiveSpell(spellid)) + if (!IsAutocastable(spellid)) return; PetSpellMap::iterator itr = m_spells.find(spellid); diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index beae6d7441f..21b66b0e2c8 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -696,7 +696,7 @@ void WorldSession::HandlePetSpellAutocastOpcode(WorldPacket& recvPacket) } // do not add not learned spells/ passive spells - if (!pet->HasSpell(spellid) || IsPassiveSpell(spellid)) + if (!pet->HasSpell(spellid) || !IsAutocastable(spellid)) return; CharmInfo* charmInfo = pet->GetCharmInfo(); diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 0b3ec91836e..459b6bcc9bb 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -397,7 +397,7 @@ enum SpellAttributesEx4 SPELL_ATTR_EX4_UNK2 = 0x00000004,// 2 SPELL_ATTR_EX4_UNK3 = 0x00000008,// 3 SPELL_ATTR_EX4_UNK4 = 0x00000010,// 4 This will no longer cause guards to attack on use?? - SPELL_ATTR_EX4_UNK5 = 0x00000020,// 5 + SPELL_ATTR_EX4_UNAUTOCASTABLE = 0x00000020,// 5 SPELL_ATTR_EX4_NOT_STEALABLE = 0x00000040,// 6 although such auras might be dispellable, they cannot be stolen SPELL_ATTR_EX4_CAN_CAST_WHILE_CASTING = 0x00000080,// 7 In theory, can use this spell while another is channeled/cast/autocast SPELL_ATTR_EX4_STACK_DOT_MODIFIER = 0x00000100,// 8 no effect on non DoTs? diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index aa119a6ff7b..a2b6ec1ece5 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -232,6 +232,19 @@ inline bool IsPassiveSpellStackableWithRanks(SpellEntry const* spellProto) return !IsSpellHaveEffect(spellProto, SPELL_EFFECT_APPLY_AURA); } +inline bool IsAutocastable(SpellEntry const* spellInfo) +{ + return !(spellInfo->HasAttribute(SPELL_ATTR_EX4_UNAUTOCASTABLE) || spellInfo->HasAttribute(SPELL_ATTR_PASSIVE)); +} + +inline bool IsAutocastable(uint32 spellId) +{ + SpellEntry const* spellInfo = sSpellTemplate.LookupEntry(spellId); + if (!spellInfo) + return false; + return IsAutocastable(spellInfo); +} + inline bool IsSpellRemoveAllMovementAndControlLossEffects(SpellEntry const* spellProto) { return spellProto->EffectApplyAuraName[EFFECT_INDEX_0] == SPELL_AURA_MECHANIC_IMMUNITY && diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 728d68c4c08..1ef7910b502 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -10010,7 +10010,7 @@ bool CharmInfo::AddSpellToActionBar(uint32 spellId, ActiveStates newstate /*= AC { if (!PetActionBar[i].GetAction() && PetActionBar[i].IsActionBarForSpell()) { - SetActionBar(i, spellId, newstate == ACT_DECIDE ? ACT_DISABLED : newstate); + SetActionBar(i, spellId, newstate == ACT_DECIDE ? IsAutocastable(spellId) ? ACT_DISABLED : ACT_PASSIVE : newstate); return true; } } @@ -10076,8 +10076,14 @@ void CharmInfo::LoadPetActionBar(const std::string& data) PetActionBar[index].SetActionAndType(action, ActiveStates(type)); // check correctness - if (PetActionBar[index].IsActionBarForSpell() && !sSpellStore.LookupEntry(PetActionBar[index].GetAction())) - SetActionBar(index, 0, ACT_DISABLED); + if (PetActionBar[index].IsActionBarForSpell()) + { + SpellEntry const* spellInfo = sSpellStore.LookupEntry(PetActionBar[index].GetAction()); + if (!spellInfo) + SetActionBar(index, 0, ACT_DISABLED); + else if (!IsAutocastable(spellInfo)) + SetActionBar(index, PetActionBar[index].GetAction(), ACT_PASSIVE); + } } }