aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.cpp4
-rw-r--r--src/server/game/Entities/Player/Player.cpp120
-rw-r--r--src/server/game/Entities/Player/Player.h3
-rw-r--r--src/server/game/Spells/Spell.cpp43
-rw-r--r--src/server/game/Spells/Spell.h2
-rw-r--r--src/server/game/Spells/SpellEffects.cpp38
6 files changed, 92 insertions, 118 deletions
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp
index 56792e2b8f9..3e0c15c42af 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp
@@ -149,7 +149,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
"appearance5, appearance6, appearance7, appearance8, appearance9, appearance10, appearance11, appearance12, appearance13, appearance14, appearance15, appearance16, "
"appearance17, appearance18, mainHandEnchant, offHandEnchant FROM character_transmog_outfits WHERE guid = ? ORDER BY setindex", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_BGDATA, "SELECT instanceId, team, joinX, joinY, joinZ, joinO, joinMapId, taxiStart, taxiEnd, mountSpell, queueId FROM character_battleground_data WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_SEL_CHARACTER_GLYPHS, "SELECT talentGroup, glyphId FROM character_glyphs WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_CHARACTER_GLYPHS, "SELECT talentGroup, glyphSlot, glyphId FROM character_glyphs WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_TALENTS, "SELECT talentGroup, talentId, `rank` FROM character_talent WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_TALENT_GROUPS, "SELECT id, talentTabId FROM character_talent_group WHERE guid = ? ORDER BY id ASC", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_SKILLS, "SELECT skill, value, max, professionSlot FROM character_skills WHERE guid = ?", CONNECTION_ASYNC);
@@ -616,7 +616,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
"attackPower, rangedAttackPower, spellPower, resilience, mastery, versatility) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PETITION_BY_OWNER, "DELETE FROM petition WHERE ownerguid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER, "DELETE FROM petition_sign WHERE ownerguid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_INS_CHAR_GLYPHS, "INSERT INTO character_glyphs VALUES(?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_CHAR_GLYPHS, "INSERT INTO character_glyphs (guid, talentGroup, glyphSlot, glyphId) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_TALENT, "INSERT INTO character_talent (guid, talentGroup, talentId, `rank`) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_TALENT_GROUP, "INSERT INTO character_talent_group (guid, id, talentTabId) VALUES (?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHAR_LIST_SLOT, "UPDATE characters SET slot = ? WHERE guid = ? AND account = ?", CONNECTION_ASYNC);
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 68542620d12..781934a88ed 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -17365,8 +17365,8 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol
RegisterPowerTypes();
UpdateDisplayPower();
-
_LoadTalents(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_TALENT_GROUPS), holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_TALENTS));
+ _LoadGlyphs(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_GLYPHS));
SetActiveTalentGroup(HasTalentGroupUnlocked(fields.activeTalentGroup) ? fields.activeTalentGroup : 0, false);
_LoadSpells(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SPELLS), holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SPELL_FAVORITES));
@@ -17376,9 +17376,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol
GetSession()->GetCollectionMgr()->LoadItemAppearances();
GetSession()->GetCollectionMgr()->LoadTransmogIllusions();
- _LoadGlyphs(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_GLYPHS));
_LoadAuras(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_AURAS), holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_AURA_EFFECTS), time_diff);
- _LoadGlyphAuras();
// add ghost flag (must be after aura load: PLAYER_FLAGS_GHOST set in aura)
if (HasPlayerFlag(PLAYER_FLAGS_GHOST))
m_deathState = DEAD;
@@ -17796,12 +17794,6 @@ void Player::_LoadAuras(PreparedQueryResult auraResult, PreparedQueryResult effe
}
}
-void Player::_LoadGlyphAuras()
-{
- for (uint32 glyphId : GetGlyphs(GetActiveTalentGroup()))
- CastSpell(this, sGlyphPropertiesStore.AssertEntry(glyphId)->SpellID, true);
-}
-
void Player::LoadCorpse(PreparedQueryResult result)
{
if (IsAlive() || HasAtLoginFlag(AT_LOGIN_RESURRECT))
@@ -23307,17 +23299,6 @@ void Player::SendInitialPacketsBeforeAddToMap()
GetSpellHistory()->WritePacket(&sendSpellCharges);
SendDirectMessage(sendSpellCharges.Write());
- WorldPackets::Talent::ActiveGlyphs activeGlyphs;
- activeGlyphs.Glyphs.reserve(GetGlyphs(GetActiveTalentGroup()).size());
- for (uint32 glyphId : GetGlyphs(GetActiveTalentGroup()))
- if (std::vector<uint32> const* bindableSpells = sDB2Manager.GetGlyphBindableSpells(glyphId))
- for (uint32 bindableSpell : *bindableSpells)
- if (HasSpell(bindableSpell) && m_overrideSpells.find(bindableSpell) == m_overrideSpells.end())
- activeGlyphs.Glyphs.emplace_back(uint32(bindableSpell), uint16(glyphId));
-
- activeGlyphs.IsFullUpdate = true;
- SendDirectMessage(activeGlyphs.Write());
-
/// SMSG_ACTION_BUTTONS
SendInitialActionButtons();
@@ -25944,8 +25925,6 @@ void Player::InitGlyphsForLevel()
break;
SetGlyphSlot(slotIndex, glyphSlot->ID);
- SetGlyph(slotIndex, 0);
-
++slotIndex;
}
@@ -25962,6 +25941,36 @@ void Player::InitGlyphsForLevel()
SetGlyphsEnabled(slotMask);
}
+void Player::ApplyGlyph(uint8 index, uint32 glyphRecId)
+{
+ if (index >= m_activePlayerData->Glyphs.size())
+ return;
+
+ GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyphRecId);
+ if (!glyphEntry)
+ return;
+
+ _talentGroups[_activeTalentGroup].Glyphs[index] = glyphRecId;
+ SetGlyph(index, glyphRecId);
+ CastSpell(this, glyphEntry->SpellID, true);
+
+ SendTalentsInfoData();
+}
+
+void Player::RemoveGlyph(uint8 index)
+{
+ if (index >= m_activePlayerData->Glyphs.size())
+ return;
+
+ if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(m_activePlayerData->Glyphs[index]))
+ RemoveAurasDueToSpell(glyphEntry->SpellID);
+
+ _talentGroups[_activeTalentGroup].Glyphs[index] = 0;
+ SetGlyph(index, 0);
+
+ SendTalentsInfoData();
+}
+
void Player::UpdateFallInformationIfNeed(MovementInfo const& minfo, uint16 opcode)
{
if (m_lastFallTime >= minfo.jump.fallTime || m_lastFallZ <= minfo.pos.GetPositionZ() || opcode == CMSG_MOVE_FALL_LAND)
@@ -26371,7 +26380,7 @@ void Player::SetMap(Map* map)
void Player::_LoadGlyphs(PreparedQueryResult result)
{
- // SELECT talentGroup, glyphId from character_glyphs WHERE guid = ?
+ // SELECT talentGroup, glyphSlot, glyphId from character_glyphs WHERE guid = ?
if (!result)
return;
@@ -26379,16 +26388,21 @@ void Player::_LoadGlyphs(PreparedQueryResult result)
{
Field* fields = result->Fetch();
- uint8 spec = fields[0].GetUInt8();
- if (spec >= MAX_SPECIALIZATIONS || !sDB2Manager.GetChrSpecializationByIndex(GetClass(), spec))
+ uint8 talentGroupIndex = fields[0].GetUInt8();
+ if (_talentGroups.size() < uint8(talentGroupIndex + 1))
continue;
- uint16 glyphId = fields[1].GetUInt16();
- if (!sGlyphPropertiesStore.LookupEntry(glyphId))
+ TalentGroupInfo& talentGroup = _talentGroups[talentGroupIndex];
+
+ uint8 glyphSlot = fields[1].GetUInt8();
+ if (glyphSlot >= talentGroup.Glyphs.size())
continue;
- GetGlyphs(spec).push_back(glyphId);
+ uint16 glyphId = fields[2].GetUInt16();
+ if (!sGlyphPropertiesStore.HasRecord(glyphId))
+ continue;
+ talentGroup.Glyphs[glyphSlot] = glyphId;
} while (result->NextRow());
}
@@ -26398,19 +26412,27 @@ void Player::_SaveGlyphs(CharacterDatabaseTransaction trans) const
stmt->setUInt64(0, GetGUID().GetCounter());
trans->Append(stmt);
- for (uint8 spec = 0; spec < MAX_SPECIALIZATIONS; ++spec)
+ uint8 talentGroupIndex = 0;
+ for (TalentGroupInfo const& talentGroup : _talentGroups)
{
- for (uint32 glyphId : GetGlyphs(spec))
+ uint8 glyphSlot = 0;
+ for (uint16 glyphId : talentGroup.Glyphs)
{
- uint8 index = 0;
-
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_GLYPHS);
- stmt->setUInt64(index++, GetGUID().GetCounter());
- stmt->setUInt8(index++, spec);
- stmt->setUInt16(index++, uint16(glyphId));
+ if (glyphId)
+ {
+ uint8 index = 0;
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_GLYPHS);
+ stmt->setUInt64(index++, GetGUID().GetCounter());
+ stmt->setUInt8(index++, talentGroupIndex);
+ stmt->setUInt8(index++, glyphSlot);
+ stmt->setUInt16(index++, glyphId);
- trans->Append(stmt);
+ trans->Append(stmt);
+ }
+ ++glyphSlot;
}
+
+ ++talentGroupIndex;
}
}
@@ -28377,6 +28399,10 @@ void Player::SetActiveTalentGroup(uint8 group, bool withUpdate /*= true*/)
if (oldTalentTabId != newTalentTabId)
UnlearnTalentTreePrimarySpells();
+ for (uint16 glyphId : _talentGroups[_activeTalentGroup].Glyphs)
+ if (glyphId)
+ RemoveAurasDueToSpell(sGlyphPropertiesStore.AssertEntry(glyphId)->SpellID);
+
if (IsNonMeleeSpellCast(false))
InterruptNonMeleeSpells(false);
@@ -28433,17 +28459,24 @@ void Player::SetActiveTalentGroup(uint8 group, bool withUpdate /*= true*/)
RemoveSpell(spellId, false, false);
}
}
-
- for (uint32 glyphId : GetGlyphs(GetActiveTalentGroup()))
- RemoveAurasDueToSpell(sGlyphPropertiesStore.AssertEntry(glyphId)->SpellID);
}
_activeTalentGroup = group;
- SetPrimaryTalentTree(newTalentTabId);
-
{
// Perform post switch actions - resetting powers, loading action bars, updating shapeshifting auras
+ SetPrimaryTalentTree(newTalentTabId);
+
+ uint8 glyphSlot = 0;
+ for (uint16 glyphId : _talentGroups[_activeTalentGroup].Glyphs)
+ {
+ if (glyphId)
+ CastSpell(this, sGlyphPropertiesStore.AssertEntry(glyphId)->SpellID, true);
+
+ SetGlyph(glyphSlot, glyphId);
+ ++glyphSlot;
+ }
+
StartLoadingActionButtons();
UpdateDisplayPower();
@@ -28458,9 +28491,6 @@ void Player::SetActiveTalentGroup(uint8 group, bool withUpdate /*= true*/)
if (Item* equippedItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
SetVisibleItemSlot(i, equippedItem);
- for (uint32 glyphId : GetGlyphs(GetActiveTalentGroup()))
- CastSpell(this, sGlyphPropertiesStore.AssertEntry(glyphId)->SpellID, true);
-
Unit::AuraEffectList const& shapeshiftAuras = GetAuraEffectsByType(SPELL_AURA_MOD_SHAPESHIFT);
for (AuraEffect* aurEff : shapeshiftAuras)
{
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index f725ed05c1d..1569b2f00f8 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1869,6 +1869,8 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
void SendTalentsInfoData();
void InitGlyphsForLevel();
+ void ApplyGlyph(uint8 index, uint32 glyphRecId);
+ void RemoveGlyph(uint8 index);
void SetGlyph(uint8 index, uint32 glyphRecId) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::Glyphs, index), glyphRecId); }
void SetGlyphSlot(uint8 index, uint32 glyphSlotRecId) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::GlyphSlots, index), glyphSlotRecId); }
void SetGlyphsEnabled(uint32 slotMask) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::GlyphsEnabled), slotMask); }
@@ -2909,7 +2911,6 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
void _LoadActions(PreparedQueryResult result);
void _LoadAuras(PreparedQueryResult auraResult, PreparedQueryResult effectResult, uint32 timediff);
- void _LoadGlyphAuras();
void _LoadInventory(PreparedQueryResult result, uint32 timeDiff);
void _LoadVoidStorage(PreparedQueryResult result);
void _LoadMail(PreparedQueryResult mailsResult, PreparedQueryResult mailItemsResult);
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index be00aaa4bf9..7ef1c4d6547 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -6178,8 +6178,6 @@ SpellCastResult Spell::CheckCast(bool strict, int32* param1 /*= nullptr*/, int32
return SPELL_FAILED_GLYPH_NO_SPEC;
Player* caster = m_caster->ToPlayer();
- if (!caster->HasSpell(m_misc.SpellId))
- return SPELL_FAILED_NOT_KNOWN;
if (uint32 glyphId = spellEffectInfo.MiscValue)
{
@@ -6187,45 +6185,16 @@ SpellCastResult Spell::CheckCast(bool strict, int32* param1 /*= nullptr*/, int32
if (!glyphProperties)
return SPELL_FAILED_INVALID_GLYPH;
- std::vector<uint32> const* glyphBindableSpells = sDB2Manager.GetGlyphBindableSpells(glyphId);
- if (!glyphBindableSpells)
- return SPELL_FAILED_INVALID_GLYPH;
-
- if (std::find(glyphBindableSpells->begin(), glyphBindableSpells->end(), m_misc.SpellId) == glyphBindableSpells->end())
- return SPELL_FAILED_INVALID_GLYPH;
-
- if (std::vector<ChrSpecialization> const* glyphRequiredSpecs = sDB2Manager.GetGlyphRequiredSpecs(glyphId))
- {
- if (caster->GetPrimarySpecialization() == ChrSpecialization::None)
- return SPELL_FAILED_GLYPH_NO_SPEC;
-
- if (std::find(glyphRequiredSpecs->begin(), glyphRequiredSpecs->end(), caster->GetPrimarySpecialization()) == glyphRequiredSpecs->end())
- return SPELL_FAILED_GLYPH_INVALID_SPEC;
- }
-
- uint32 replacedGlyph = 0;
- for (uint32 activeGlyphId : caster->GetGlyphs(caster->GetActiveTalentGroup()))
- {
- if (std::vector<uint32> const* activeGlyphBindableSpells = sDB2Manager.GetGlyphBindableSpells(activeGlyphId))
- {
- if (std::find(activeGlyphBindableSpells->begin(), activeGlyphBindableSpells->end(), m_misc.SpellId) != activeGlyphBindableSpells->end())
- {
- replacedGlyph = activeGlyphId;
- break;
- }
- }
- }
-
- for (uint32 activeGlyphId : caster->GetGlyphs(caster->GetActiveTalentGroup()))
+ uint8 glyphSlot = 0;
+ for (uint32 activeGlyphId : caster->m_activePlayerData->Glyphs)
{
- if (activeGlyphId == replacedGlyph)
- continue;
-
if (activeGlyphId == glyphId)
return SPELL_FAILED_UNIQUE_GLYPH;
- if (sGlyphPropertiesStore.AssertEntry(activeGlyphId)->GlyphExclusiveCategoryID == glyphProperties->GlyphExclusiveCategoryID)
- return SPELL_FAILED_GLYPH_EXCLUSIVE_CATEGORY;
+ if (m_misc.GlyphSlot == glyphSlot && activeGlyphId != 0)
+ return SPELL_FAILED_NO_ACTIVE_GLYPHS;
+
+ ++glyphSlot;
}
}
break;
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index dd2df2c068c..9e91b29cd72 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -572,7 +572,7 @@ class TC_GAME_API Spell
uint32 TalentId;
// SPELL_EFFECT_APPLY_GLYPH
- uint32 SpellId;
+ uint32 GlyphSlot;
// SPELL_EFFECT_TALENT_SPEC_SELECT
uint32 SpecializationId;
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index c91b83e5156..b959ec5858c 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -3331,41 +3331,15 @@ void Spell::EffectApplyGlyph()
if (!player)
return;
- std::vector<uint32>& glyphs = player->GetGlyphs(player->GetActiveTalentGroup());
- std::size_t replacedGlyph = glyphs.size();
- for (std::size_t i = 0; i < glyphs.size(); ++i)
- {
- if (std::vector<uint32> const* activeGlyphBindableSpells = sDB2Manager.GetGlyphBindableSpells(glyphs[i]))
- {
- if (std::find(activeGlyphBindableSpells->begin(), activeGlyphBindableSpells->end(), m_misc.SpellId) != activeGlyphBindableSpells->end())
- {
- replacedGlyph = i;
- player->RemoveAurasDueToSpell(sGlyphPropertiesStore.AssertEntry(glyphs[i])->SpellID);
- break;
- }
- }
- }
+ if (m_misc.GlyphSlot >= player->m_activePlayerData->Glyphs.size())
+ return;
uint32 glyphId = effectInfo->MiscValue;
- if (replacedGlyph < glyphs.size())
- {
- if (glyphId)
- glyphs[replacedGlyph] = glyphId;
- else
- glyphs.erase(glyphs.begin() + replacedGlyph);
- }
- else if (glyphId)
- glyphs.push_back(glyphId);
-
player->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags2::ChangeGlyph);
-
- if (GlyphPropertiesEntry const* glyphProperties = sGlyphPropertiesStore.LookupEntry(glyphId))
- player->CastSpell(player, glyphProperties->SpellID, this);
-
- WorldPackets::Talent::ActiveGlyphs activeGlyphs;
- activeGlyphs.Glyphs.emplace_back(m_misc.SpellId, uint16(glyphId));
- activeGlyphs.IsFullUpdate = false;
- player->SendDirectMessage(activeGlyphs.Write());
+ if (glyphId)
+ player->ApplyGlyph(m_misc.GlyphSlot, glyphId);
+ else
+ player->RemoveGlyph(m_misc.GlyphSlot);
}
void Spell::EffectEnchantHeldItem()