aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Player/Player.cpp32
-rw-r--r--src/server/game/Entities/Player/Player.h4
-rw-r--r--src/server/game/Handlers/LootHandler.cpp14
-rw-r--r--src/server/game/Server/Packets/LootPackets.cpp5
-rw-r--r--src/server/game/Server/Packets/LootPackets.h10
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp2
-rw-r--r--src/server/game/Server/WorldSession.h3
-rw-r--r--src/server/shared/Database/Implementation/CharacterDatabase.cpp8
8 files changed, 63 insertions, 15 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 187f02b15ed..f36f3162399 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -99,6 +99,7 @@
#include "WorldPacket.h"
#include "WorldSession.h"
#include "WorldStatePackets.h"
+#include "DBCStructure.h"
#define ZONE_UPDATE_INTERVAL (1*IN_MILLISECONDS)
@@ -16675,9 +16676,9 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
//"resettalents_time, talentTree, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeonDifficulty, "
// 40 41 42 43 44 45
//"totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, "
- // 46 47 48 49 50 51 52 53 54 55 56 57
- //"health, power1, power2, power3, power4, power5, power6, instance_id, speccount, activespec, exploredZones, equipmentCache, "
- // 58 59 60 61 62
+ // 46 47 48 49 50 51 52 53 54 55 56 57 58
+ //"health, power1, power2, power3, power4, power5, power6, instance_id, speccount, activespec, lootSpecId, exploredZones, equipmentCache, "
+ // 59 60 61 62 63
//"knownTitles, actionBars, grantableLevels, raidDifficulty, legacyRaidDifficulty FROM characters WHERE guid = '%u'", guid);
PreparedQueryResult result = holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_FROM);
if (!result)
@@ -16747,8 +16748,8 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
SetUInt32Value(UNIT_FIELD_LEVEL, fields[6].GetUInt8());
SetUInt32Value(PLAYER_XP, fields[7].GetUInt32());
- _LoadIntoDataField(fields[56].GetCString(), PLAYER_EXPLORED_ZONES_1, PLAYER_EXPLORED_ZONES_SIZE);
- _LoadIntoDataField(fields[58].GetCString(), PLAYER__FIELD_KNOWN_TITLES, KNOWN_TITLES_SIZE*2);
+ _LoadIntoDataField(fields[57].GetCString(), PLAYER_EXPLORED_ZONES_1, PLAYER_EXPLORED_ZONES_SIZE);
+ _LoadIntoDataField(fields[59].GetCString(), PLAYER__FIELD_KNOWN_TITLES, KNOWN_TITLES_SIZE*2);
SetObjectScale(1.0f);
SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f);
@@ -16782,7 +16783,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
}
// set which actionbars the client has active - DO NOT REMOVE EVER AGAIN (can be changed though, if it does change fieldwise)
- SetByteValue(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTES_OFFSET_ACTION_BAR_TOGGLES, fields[59].GetUInt8());
+ SetByteValue(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTES_OFFSET_ACTION_BAR_TOGGLES, fields[60].GetUInt8());
InitDisplayIds();
@@ -16818,8 +16819,8 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
uint32 instanceId = fields[53].GetUInt32();
SetDungeonDifficultyID(CheckLoadedDungeonDifficultyID(Difficulty(fields[39].GetUInt8())));
- SetRaidDifficultyID(CheckLoadedRaidDifficultyID(Difficulty(fields[61].GetUInt8())));
- SetLegacyRaidDifficultyID(CheckLoadedLegacyRaidDifficultyID(Difficulty(fields[62].GetUInt8())));
+ SetRaidDifficultyID(CheckLoadedRaidDifficultyID(Difficulty(fields[62].GetUInt8())));
+ SetLegacyRaidDifficultyID(CheckLoadedLegacyRaidDifficultyID(Difficulty(fields[63].GetUInt8())));
std::string taxi_nodes = fields[38].GetString();
@@ -17190,8 +17191,15 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
//mails are loaded only when needed ;-) - when player in game click on mailbox.
//_LoadMail();
- SetTalentGroupsCount(fields[53].GetUInt8());
- SetActiveTalentGroup(fields[54].GetUInt8());
+ SetTalentGroupsCount(fields[54].GetUInt8());
+ SetActiveTalentGroup(fields[55].GetUInt8());
+
+ uint32 lootSpecId = fields[56].GetUInt32();
+ if (ChrSpecializationEntry const* chrSpec = sChrSpecializationStore.LookupEntry(lootSpecId))
+ {
+ if (chrSpec->ClassID == getClass())
+ SetLootSpecId(lootSpecId);
+ }
// sanity check
if (GetTalentGroupsCount() > MAX_TALENT_GROUPS || GetActiveTalentGroup() > MAX_TALENT_GROUP || GetTalentGroupsCount() < MIN_TALENT_GROUPS)
@@ -18936,6 +18944,8 @@ void Player::SaveToDB(bool create /*=false*/)
stmt->setUInt8(index++, GetTalentGroupsCount());
stmt->setUInt8(index++, GetActiveTalentGroup());
+ stmt->setUInt32(index++, GetLootSpecId());
+
ss.str("");
for (uint32 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; ++i)
ss << GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + i) << ' ';
@@ -19073,6 +19083,8 @@ void Player::SaveToDB(bool create /*=false*/)
stmt->setUInt8(index++, GetTalentGroupsCount());
stmt->setUInt8(index++, GetActiveTalentGroup());
+ stmt->setUInt32(index++, GetLootSpecId());
+
ss.str("");
for (uint32 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; ++i)
ss << GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + i) << ' ';
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index e6fee15ec9a..99f6154bede 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1894,6 +1894,10 @@ class Player : public Unit, public GridObject<Player>
uint32 GetReputation(uint32 factionentry) const;
std::string GetGuildName();
+ // Loot Spec
+ void SetLootSpecId(uint32 id) { SetUInt32Value(PLAYER_FIELD_LOOT_SPEC_ID, id); }
+ uint32 GetLootSpecId() const { return GetUInt32Value(PLAYER_FIELD_LOOT_SPEC_ID); }
+
// Talents
uint32 GetTalentResetCost() const { return _talentMgr->ResetTalentsCost; }
void SetTalentResetCost(uint32 cost) { _talentMgr->ResetTalentsCost = cost; }
diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp
index fe6cb4674bc..34649e80e1c 100644
--- a/src/server/game/Handlers/LootHandler.cpp
+++ b/src/server/game/Handlers/LootHandler.cpp
@@ -482,3 +482,17 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recvData)
loot->NotifyItemRemoved(slotid);
--loot->unlootedCount;
}
+
+void WorldSession::HandleSetLootSpecialization(WorldPackets::Loot::SetLootSpecialization& packet)
+{
+ if (packet.SpecID)
+ {
+ if (ChrSpecializationEntry const* chrSpec = sChrSpecializationStore.LookupEntry(packet.SpecID))
+ {
+ if (chrSpec->ClassID == GetPlayer()->getClass())
+ GetPlayer()->SetLootSpecId(packet.SpecID);
+ }
+ }
+ else
+ GetPlayer()->SetLootSpecId(packet.SpecID);
+}
diff --git a/src/server/game/Server/Packets/LootPackets.cpp b/src/server/game/Server/Packets/LootPackets.cpp
index 23fd1cd580e..9380f25acf8 100644
--- a/src/server/game/Server/Packets/LootPackets.cpp
+++ b/src/server/game/Server/Packets/LootPackets.cpp
@@ -139,3 +139,8 @@ WorldPacket const* WorldPackets::Loot::LootList::Write()
return &_worldPacket;
}
+void WorldPackets::Loot::SetLootSpecialization::Read()
+{
+ _worldPacket >> SpecID;
+}
+
diff --git a/src/server/game/Server/Packets/LootPackets.h b/src/server/game/Server/Packets/LootPackets.h
index b3f9e703ba2..9bdd8bd3a4f 100644
--- a/src/server/game/Server/Packets/LootPackets.h
+++ b/src/server/game/Server/Packets/LootPackets.h
@@ -178,6 +178,16 @@ namespace WorldPackets
Optional<ObjectGuid> Master;
Optional<ObjectGuid> RoundRobinWinner;
};
+
+ class SetLootSpecialization final : public ClientPacket
+ {
+ public:
+ SetLootSpecialization(WorldPacket&& packet) : ClientPacket(CMSG_SET_LOOT_SPECIALIZATION, std::move(packet)) { }
+
+ void Read() override;
+
+ uint32 SpecID = 0;
+ };
}
}
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 7047cc5a071..e7dad904831 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -727,7 +727,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_SET_INSERT_ITEMS_LEFT_TO_RIGHT, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_SET_LFG_BONUS_FACTION_ID, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_SET_LOOT_METHOD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Party::SetLootMethod, &WorldSession::HandleSetLootMethodOpcode);
- DEFINE_HANDLER(CMSG_SET_LOOT_SPECIALIZATION, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
+ DEFINE_HANDLER(CMSG_SET_LOOT_SPECIALIZATION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Loot::SetLootSpecialization, &WorldSession::HandleSetLootSpecialization);
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_PARTY_ASSIGNMENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePartyAssignmentOpcode );
DEFINE_HANDLER(CMSG_SET_PARTY_LEADER, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::SetPartyLeader, &WorldSession::HandleSetPartyLeaderOpcode);
DEFINE_HANDLER(CMSG_SET_PET_SLOT, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index ed39993fd45..18f7afab82f 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -328,6 +328,7 @@ namespace WorldPackets
class LootRelease;
class LootMoney;
class LootRoll;
+ class SetLootSpecialization;
}
namespace Mail
@@ -1052,6 +1053,8 @@ class WorldSession
void HandleLootOpcode(WorldPackets::Loot::LootUnit& packet);
void HandleLootReleaseOpcode(WorldPackets::Loot::LootRelease& packet);
void HandleLootMasterGiveOpcode(WorldPacket& recvPacket);
+ void HandleSetLootSpecialization(WorldPackets::Loot::SetLootSpecialization& packet);
+
void HandleWhoOpcode(WorldPackets::Who::WhoRequestPkt& whoRequest);
void HandleLogoutRequestOpcode(WorldPackets::Character::LogoutRequest& logoutRequest);
void HandleLogoutCancelOpcode(WorldPackets::Character::LogoutCancel& logoutCancel);
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
index 5b92a105e1e..9fa6e7f29ec 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
@@ -79,7 +79,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
"position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, "
"resettalents_time, talentTree, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeonDifficulty, "
"totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, "
- "health, power1, power2, power3, power4, power5, power6, instance_id, talentGroupsCount, activeTalentGroup, exploredZones, equipmentCache, knownTitles, actionBars, grantableLevels, raidDifficulty, legacyRaidDifficulty "
+ "health, power1, power2, power3, power4, power5, power6, instance_id, talentGroupsCount, activeTalentGroup, lootSpecId, exploredZones, equipmentCache, knownTitles, actionBars, grantableLevels, raidDifficulty, legacyRaidDifficulty "
"FROM characters WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_GROUP_MEMBER, "SELECT guid FROM group_member WHERE memberGuid = ?", CONNECTION_BOTH);
@@ -393,13 +393,13 @@ void CharacterDatabaseConnection::DoPrepareStatements()
"extra_flags, stable_slots, at_login, zone, "
"death_expire_time, taxi_path, totalKills, "
"todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, health, power1, power2, power3, "
- "power4, power5, power6, latency, talentGroupsCount, activeTalentGroup, exploredZones, equipmentCache, knownTitles, actionBars, grantableLevels) VALUES "
- "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC);
+ "power4, power5, power6, latency, talentGroupsCount, activeTalentGroup, lootSpecId, exploredZones, equipmentCache, knownTitles, actionBars, grantableLevels) VALUES "
+ "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHARACTER, "UPDATE characters SET name=?,race=?,class=?,gender=?,level=?,xp=?,money=?,playerBytes=?,playerBytes2=?,playerFlags=?,"
"map=?,instance_id=?,dungeonDifficulty=?,raidDifficulty=?,legacyRaidDifficulty=?,position_x=?,position_y=?,position_z=?,orientation=?,trans_x=?,trans_y=?,trans_z=?,trans_o=?,transguid=?,taximask=?,cinematic=?,totaltime=?,leveltime=?,rest_bonus=?,"
"logout_time=?,is_logout_resting=?,resettalents_cost=?,resettalents_time=?,talentTree=?,extra_flags=?,stable_slots=?,at_login=?,zone=?,death_expire_time=?,taxi_path=?,"
"totalKills=?,todayKills=?,yesterdayKills=?,chosenTitle=?,"
- "watchedFaction=?,drunk=?,health=?,power1=?,power2=?,power3=?,power4=?,power5=?,power6=?,latency=?,talentGroupsCount=?,activeTalentGroup=?,exploredZones=?,"
+ "watchedFaction=?,drunk=?,health=?,power1=?,power2=?,power3=?,power4=?,power5=?,power6=?,latency=?,talentGroupsCount=?,activeTalentGroup=?,lootSpecId=?,exploredZones=?,"
"equipmentCache=?,knownTitles=?,actionBars=?,grantableLevels=?,online=? WHERE guid=?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG, "UPDATE characters SET at_login = at_login | ? WHERE guid = ?", CONNECTION_ASYNC);