aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Entities')
-rw-r--r--src/server/game/Entities/Player/Player.cpp89
-rw-r--r--src/server/game/Entities/Player/Player.h37
2 files changed, 108 insertions, 18 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 68a4f60e72f..491397a5a70 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -256,7 +256,6 @@ Player::Player(WorldSession* session) : Unit(true)
m_prevMapDifficulty = DIFFICULTY_NORMAL_RAID;
m_lastPotionId = 0;
- _talentMgr = new PlayerTalentInfo();
for (uint8 i = 0; i < BASEMOD_END; ++i)
{
@@ -352,8 +351,6 @@ Player::~Player()
for (PlayerSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
delete itr->second;
- delete _talentMgr;
-
//all mailed items should be deleted, also all mail should be deallocated
for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ++itr)
delete *itr;
@@ -4077,6 +4074,10 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe
stmt->setUInt64(0, guid);
trans->Append(stmt);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_GLYPHS);
+ stmt->setUInt64(0, guid);
+ trans->Append(stmt);
+
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_QUESTSTATUS_DAILY);
stmt->setUInt64(0, guid);
trans->Append(stmt);
@@ -17638,7 +17639,9 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
LearnSpecializationSpells();
+ _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 (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
m_deathState = DEAD;
@@ -18002,6 +18005,12 @@ 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))
@@ -19657,6 +19666,7 @@ void Player::SaveToDB(bool create /*=false*/)
_SaveWeeklyQuestStatus(trans);
_SaveSeasonalQuestStatus(trans);
_SaveMonthlyQuestStatus(trans);
+ _SaveGlyphs(trans);
_SaveTalents(trans);
_SaveSpells(trans);
GetSpellHistory()->SaveToDB<Player>(trans);
@@ -23078,6 +23088,17 @@ 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();
@@ -25882,6 +25903,51 @@ void Player::SetMap(Map* map)
m_mapRef.link(map, this);
}
+void Player::_LoadGlyphs(PreparedQueryResult result)
+{
+ // SELECT talentGroup, glyphId from character_glyphs WHERE guid = ?
+ if (!result)
+ return;
+
+ do
+ {
+ Field* fields = result->Fetch();
+
+ uint8 spec = fields[0].GetUInt8();
+ if (spec >= MAX_SPECIALIZATIONS || !sDB2Manager.GetChrSpecializationByIndex(getClass(), spec))
+ continue;
+
+ uint16 glyphId = fields[1].GetUInt16();
+ if (!sGlyphPropertiesStore.LookupEntry(glyphId))
+ continue;
+
+ GetGlyphs(spec).push_back(glyphId);
+
+ } while (result->NextRow());
+}
+
+void Player::_SaveGlyphs(SQLTransaction& trans) const
+{
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_GLYPHS);
+ stmt->setUInt64(0, GetGUID().GetCounter());
+ trans->Append(stmt);
+
+ for (uint8 spec = 0; spec < MAX_SPECIALIZATIONS; ++spec)
+ {
+ for (uint32 glyphId : GetGlyphs(spec))
+ {
+ uint8 index = 0;
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_GLYPHS);
+ stmt->setUInt64(index++, GetGUID().GetCounter());
+ stmt->setUInt8(index++, spec);
+ stmt->setUInt16(index++, uint16(glyphId));
+
+ trans->Append(stmt);
+ }
+ }
+}
+
void Player::_LoadTalents(PreparedQueryResult result)
{
// SetPQuery(PLAYER_LOGIN_QUERY_LOADTALENTS, "SELECT spell, spec FROM character_talent WHERE guid = '%u'", GUID_LOPART(m_guid));
@@ -25985,6 +26051,9 @@ void Player::ActivateTalentGroup(ChrSpecializationEntry const* spec)
// Remove spec specific spells
RemoveSpecializationSpells();
+ for (uint32 glyphId : GetGlyphs(GetActiveTalentGroup()))
+ RemoveAurasDueToSpell(sGlyphPropertiesStore.AssertEntry(glyphId)->SpellID);
+
SetActiveTalentGroup(spec->OrderIndex);
SetUInt32Value(PLAYER_FIELD_CURRENT_SPEC_ID, spec->ID);
if (!GetPrimarySpecialization())
@@ -26041,6 +26110,20 @@ void Player::ActivateTalentGroup(ChrSpecializationEntry const* spec)
for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
if (Item* equippedItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
SetVisibleItemSlot(i, equippedItem);
+
+ for (uint32 glyphId : GetGlyphs(spec->OrderIndex))
+ CastSpell(this, sGlyphPropertiesStore.AssertEntry(glyphId)->SpellID, true);
+
+ WorldPackets::Talent::ActiveGlyphs activeGlyphs;
+ activeGlyphs.Glyphs.reserve(GetGlyphs(spec->OrderIndex).size());
+ for (uint32 glyphId : GetGlyphs(spec->OrderIndex))
+ 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());
}
void Player::ResetTimeSync()
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index fd044cad8c2..1a6481d296a 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -972,6 +972,7 @@ enum PlayerLoginQueryIndex
PLAYER_LOGIN_QUERY_LOAD_EQUIPMENT_SETS,
PLAYER_LOGIN_QUERY_LOAD_TRANSMOG_OUTFITS,
PLAYER_LOGIN_QUERY_LOAD_BG_DATA,
+ PLAYER_LOGIN_QUERY_LOAD_GLYPHS,
PLAYER_LOGIN_QUERY_LOAD_TALENTS,
PLAYER_LOGIN_QUERY_LOAD_ACCOUNT_DATA,
PLAYER_LOGIN_QUERY_LOAD_SKILLS,
@@ -1173,21 +1174,22 @@ static uint32 const DefaultTalentRowLevels[MAX_TALENT_TIERS] = { 15, 30, 45, 60,
static uint32 const DKTalentRowLevels[MAX_TALENT_TIERS] = { 57, 58, 59, 60, 75, 90, 100 };
static uint32 const DHTalentRowLevels[MAX_TALENT_TIERS] = { 99, 100, 102, 104, 106, 108, 110 };
-struct TC_GAME_API PlayerTalentInfo
+struct TC_GAME_API SpecializationInfo
{
- PlayerTalentInfo() : ResetTalentsCost(0), ResetTalentsTime(0), PrimarySpecialization(0), ActiveGroup(0)
+ SpecializationInfo() : ResetTalentsCost(0), ResetTalentsTime(0), PrimarySpecialization(0), ActiveGroup(0)
{
}
PlayerTalentMap Talents[MAX_SPECIALIZATIONS];
+ std::vector<uint32> Glyphs[MAX_SPECIALIZATIONS];
uint32 ResetTalentsCost;
time_t ResetTalentsTime;
uint32 PrimarySpecialization;
uint8 ActiveGroup;
private:
- PlayerTalentInfo(PlayerTalentInfo const&) = delete;
- PlayerTalentInfo& operator=(PlayerTalentInfo const&) = delete;
+ SpecializationInfo(SpecializationInfo const&) = delete;
+ SpecializationInfo& operator=(SpecializationInfo const&) = delete;
};
class TC_GAME_API Player : public Unit, public GridObject<Player>
@@ -1767,14 +1769,14 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
uint32 GetLootSpecId() const { return GetUInt32Value(PLAYER_FIELD_LOOT_SPEC_ID); }
// Talents
- uint32 GetTalentResetCost() const { return _talentMgr->ResetTalentsCost; }
- void SetTalentResetCost(uint32 cost) { _talentMgr->ResetTalentsCost = cost; }
- time_t GetTalentResetTime() const { return _talentMgr->ResetTalentsTime; }
- void SetTalentResetTime(time_t time_) { _talentMgr->ResetTalentsTime = time_; }
- uint32 GetPrimarySpecialization() const { return _talentMgr->PrimarySpecialization; }
- void SetPrimarySpecialization(uint32 spec) { _talentMgr->PrimarySpecialization = spec; }
- uint8 GetActiveTalentGroup() const { return _talentMgr->ActiveGroup; }
- void SetActiveTalentGroup(uint8 group){ _talentMgr->ActiveGroup = group; }
+ uint32 GetTalentResetCost() const { return _specializationInfo.ResetTalentsCost; }
+ void SetTalentResetCost(uint32 cost) { _specializationInfo.ResetTalentsCost = cost; }
+ time_t GetTalentResetTime() const { return _specializationInfo.ResetTalentsTime; }
+ void SetTalentResetTime(time_t time_) { _specializationInfo.ResetTalentsTime = time_; }
+ uint32 GetPrimarySpecialization() const { return _specializationInfo.PrimarySpecialization; }
+ void SetPrimarySpecialization(uint32 spec) { _specializationInfo.PrimarySpecialization = spec; }
+ uint8 GetActiveTalentGroup() const { return _specializationInfo.ActiveGroup; }
+ void SetActiveTalentGroup(uint8 group){ _specializationInfo.ActiveGroup = group; }
uint32 GetDefaultSpecId() const;
bool ResetTalents(bool noCost = false);
@@ -1791,8 +1793,10 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
// Dual Spec
void ActivateTalentGroup(ChrSpecializationEntry const* spec);
- PlayerTalentMap const* GetTalentMap(uint8 spec) const { return &_talentMgr->Talents[spec]; }
- PlayerTalentMap* GetTalentMap(uint8 spec) { return &_talentMgr->Talents[spec]; }
+ PlayerTalentMap const* GetTalentMap(uint8 spec) const { return &_specializationInfo.Talents[spec]; }
+ PlayerTalentMap* GetTalentMap(uint8 spec) { return &_specializationInfo.Talents[spec]; }
+ std::vector<uint32> const& GetGlyphs(uint8 spec) const { return _specializationInfo.Glyphs[spec]; }
+ std::vector<uint32>& GetGlyphs(uint8 spec) { return _specializationInfo.Glyphs[spec]; }
ActionButtonList const& GetActionButtons() const { return m_actionButtons; }
uint32 GetFreePrimaryProfessionPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS); }
@@ -2522,6 +2526,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void _LoadActions(PreparedQueryResult result);
void _LoadAuras(PreparedQueryResult auraResult, PreparedQueryResult effectResult, uint32 timediff);
+ void _LoadGlyphAuras();
void _LoadBoundInstances(PreparedQueryResult result);
void _LoadInventory(PreparedQueryResult result, PreparedQueryResult artifactsResult, uint32 timeDiff);
void _LoadVoidStorage(PreparedQueryResult result);
@@ -2545,6 +2550,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void _LoadEquipmentSets(PreparedQueryResult result);
void _LoadTransmogOutfits(PreparedQueryResult result);
void _LoadBGData(PreparedQueryResult result);
+ void _LoadGlyphs(PreparedQueryResult result);
void _LoadTalents(PreparedQueryResult result);
void _LoadInstanceTimeRestrictions(PreparedQueryResult result);
void _LoadCurrency(PreparedQueryResult result);
@@ -2568,6 +2574,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void _SaveSpells(SQLTransaction& trans);
void _SaveEquipmentSets(SQLTransaction& trans);
void _SaveBGData(SQLTransaction& trans);
+ void _SaveGlyphs(SQLTransaction& trans) const;
void _SaveTalents(SQLTransaction& trans);
void _SaveStats(SQLTransaction& trans) const;
void _SaveInstanceTimeRestrictions(SQLTransaction& trans);
@@ -2648,7 +2655,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
std::unordered_map<uint32 /*overridenSpellId*/, std::unordered_set<uint32> /*newSpellId*/> m_overrideSpells;
uint32 m_lastPotionId; // last used health/mana potion in combat, that block next potion use
- PlayerTalentInfo* _talentMgr;
+ SpecializationInfo _specializationInfo;
ActionButtonList m_actionButtons;