fix(Core/Spells): do not announce form spells (#27767)

This commit is contained in:
EricksOliveira
2026-10-03 13:35:10 -03:00
committed by GitHub
parent 9ce0f3dcce
commit a650258729
3 changed files with 26 additions and 11 deletions
+18 -7
View File
@@ -2796,6 +2796,9 @@ void Player::SendInitialSpells()
std::size_t countPos = data.wpos();
data << uint16(spellCount); // spell count placeholder
// Form spells are shown by the client from its own SpellShapeshiftForm.dbc and never sent as learned
SpellShapeshiftFormEntry const* shapeInfo = sSpellShapeshiftFormStore.LookupEntry(GetShapeshiftForm());
for (PlayerSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
{
if (itr->second->State == PLAYERSPELL_REMOVED)
@@ -2804,6 +2807,10 @@ void Player::SendInitialSpells()
if (!itr->second->Active || !itr->second->IsInSpec(GetActiveSpec()))
continue;
if (shapeInfo && itr->second->State == PLAYERSPELL_TEMPORARY &&
std::ranges::find(shapeInfo->stanceSpell, itr->first) != std::ranges::end(shapeInfo->stanceSpell))
continue;
data << uint32(itr->first);
data << uint16(0); // it's not slot id
@@ -3235,7 +3242,8 @@ bool Player::CheckSkillLearnedBySpell(uint32 spellId)
return true;
}
bool Player::_addSpell(uint32 spellId, uint8 addSpecMask, bool temporary, bool learnFromSkill /*= false*/)
bool Player::_addSpell(uint32 spellId, uint8 addSpecMask, bool temporary, bool learnFromSkill /*= false*/,
bool sendPacket /*= true*/)
{
// pussywizard: this can be called to OVERWRITE currently existing spell params! usually to set active = false for lower ranks of a spell
@@ -3251,7 +3259,9 @@ bool Player::_addSpell(uint32 spellId, uint8 addSpecMask, bool temporary, bool l
// xinef: send packet so client can properly recognize this new spell
// xinef: ignore passive spells and spells with learn effect
// xinef: send spells with no aura effects (ie dual wield)
if (IsInWorld() && !isBeingLoaded() && temporary && !learnFromSkill && (!spellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_PASSIVE | SPELL_ATTR0_DO_NOT_DISPLAY)) || !spellInfo->HasAnyAura()) && !spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL))
if (IsInWorld() && !isBeingLoaded() && temporary && sendPacket && !learnFromSkill &&
(!spellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_PASSIVE | SPELL_ATTR0_DO_NOT_DISPLAY)) ||
!spellInfo->HasAnyAura()) && !spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL))
SendLearnPacket(spellInfo->Id, true);
// xinef: DO NOT allow to learn spell with effect learn spell!
@@ -3268,7 +3278,7 @@ bool Player::_addSpell(uint32 spellId, uint8 addSpecMask, bool temporary, bool l
//ABORT();
}
else if (SpellInfo const* learnSpell = sSpellMgr->GetSpellInfo(spellInfo->Effects[i].TriggerSpell))
_addSpell(learnSpell->Id, SPEC_MASK_ALL, true);
_addSpell(learnSpell->Id, SPEC_MASK_ALL, true, false, sendPacket);
}
return false;
@@ -3498,7 +3508,7 @@ uint8 Player::GetLearnSpellSpecMask(uint32 spellId) const
return specMask;
}
void Player::removeSpell(uint32 spell_id, uint8 removeSpecMask, bool onlyTemporary)
void Player::removeSpell(uint32 spell_id, uint8 removeSpecMask, bool onlyTemporary, bool sendPacket /*= true*/)
{
PlayerSpellMap::iterator itr = m_spells.find(spell_id);
if (itr == m_spells.end())
@@ -3516,7 +3526,7 @@ void Player::removeSpell(uint32 spell_id, uint8 removeSpecMask, bool onlyTempora
// pussywizard: do this at the beginning, not in the middle of removing!
if (uint32 nextSpell = sSpellMgr->GetNextSpellInChain(spell_id))
if (!GetTalentSpellPos(nextSpell))
removeSpell(nextSpell, removeSpecMask, onlyTemporary);
removeSpell(nextSpell, removeSpecMask, onlyTemporary, sendPacket);
// xinef: if current spell has talentcost, remove spells requiring this spell
uint32 firstRankSpellId = sSpellMgr->GetFirstSpellInChain(spell_id);
@@ -3525,7 +3535,7 @@ void Player::removeSpell(uint32 spell_id, uint8 removeSpecMask, bool onlyTempora
SpellsRequiringSpellMapBounds spellsRequiringSpell = sSpellMgr->GetSpellsRequiringSpellBounds(firstRankSpellId);
for (auto spellsItr = spellsRequiringSpell.first; spellsItr != spellsRequiringSpell.second; ++spellsItr)
{
removeSpell(spellsItr->second, removeSpecMask, onlyTemporary);
removeSpell(spellsItr->second, removeSpecMask, onlyTemporary, sendPacket);
}
}
@@ -3647,7 +3657,8 @@ void Player::removeSpell(uint32 spell_id, uint8 removeSpecMask, bool onlyTempora
if (!onlyTemporary || ((!spellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_PASSIVE | SPELL_ATTR0_DO_NOT_DISPLAY)) || !spellInfo->HasAnyAura()) && !spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL)))
{
sScriptMgr->OnPlayerForgotSpell(this, spell_id);
SendLearnPacket(spell_id, false);
if (sendPacket)
SendLearnPacket(spell_id, false);
}
}
+3 -2
View File
@@ -1723,9 +1723,10 @@ public:
void SendInitialSpells();
void SendLearnPacket(uint32 spellId, bool learn);
bool addSpell(uint32 spellId, uint8 addSpecMask, bool updateActive, bool temporary = false, bool learnFromSkill = false);
bool _addSpell(uint32 spellId, uint8 addSpecMask, bool temporary, bool learnFromSkill = false);
bool _addSpell(uint32 spellId, uint8 addSpecMask, bool temporary, bool learnFromSkill = false,
bool sendPacket = true);
void learnSpell(uint32 spellId, bool temporary = false, bool learnFromSkill = false);
void removeSpell(uint32 spellId, uint8 removeSpecMask, bool onlyTemporary);
void removeSpell(uint32 spellId, uint8 removeSpecMask, bool onlyTemporary, bool sendPacket = true);
void resetSpells();
void LearnCustomSpells();
void LearnDefaultSkills();
@@ -2275,14 +2275,17 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo
{
SpellShapeshiftFormEntry const* shapeInfo = sSpellShapeshiftFormStore.LookupEntry(form);
// Learn spells for shapeshift form - no need to send action bars or add spells to spellbook
// The client shows form spells from its own SpellShapeshiftForm.dbc, so no learned/removed spell packet
// (and no chat message) is sent
for (uint8 i = 0; i < MAX_SHAPESHIFT_SPELLS; ++i)
{
if (!shapeInfo->stanceSpell[i])
continue;
if (apply)
target->ToPlayer()->_addSpell(shapeInfo->stanceSpell[i], SPEC_MASK_ALL, true);
target->ToPlayer()->_addSpell(shapeInfo->stanceSpell[i], SPEC_MASK_ALL, true, false,
/*sendPacket*/ false);
else
target->ToPlayer()->removeSpell(shapeInfo->stanceSpell[i], SPEC_MASK_ALL, true);
target->ToPlayer()->removeSpell(shapeInfo->stanceSpell[i], SPEC_MASK_ALL, true, /*sendPacket*/ false);
}
}
}