aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/cata_classic/2024_11_01_00_world.sql14
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp2
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.h11
-rw-r--r--src/server/game/DataStores/DB2Stores.cpp2
-rw-r--r--src/server/game/DataStores/DBCEnums.h2
-rw-r--r--src/server/game/Entities/Creature/GossipDef.cpp12
-rw-r--r--src/server/game/Entities/Item/Container/Bag.h2
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateMask.h2
-rw-r--r--src/server/game/Entities/Player/Player.cpp57
-rw-r--r--src/server/game/Entities/Player/Player.h3
-rw-r--r--src/server/game/Entities/Unit/enuminfo_UnitDefines.cpp2
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp39
-rw-r--r--src/server/game/Globals/ObjectMgr.h1
-rw-r--r--src/server/game/Groups/Group.cpp23
-rw-r--r--src/server/game/Groups/Group.h17
-rw-r--r--src/server/game/Guilds/Guild.cpp1
-rw-r--r--src/server/game/Handlers/BankHandler.cpp41
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp2
-rw-r--r--src/server/game/Handlers/MovementHandler.cpp1
-rw-r--r--src/server/game/Handlers/TaxiHandler.cpp4
-rw-r--r--src/server/game/Quests/QuestDef.cpp50
-rw-r--r--src/server/game/Quests/QuestDef.h97
-rw-r--r--src/server/game/Reputation/ReputationMgr.cpp15
-rw-r--r--src/server/game/Server/Packets/AreaTriggerPackets.cpp1
-rw-r--r--src/server/game/Server/Packets/AreaTriggerPackets.h1
-rw-r--r--src/server/game/Server/Packets/AuctionHousePackets.cpp2
-rw-r--r--src/server/game/Server/Packets/AuthenticationPackets.cpp2
-rw-r--r--src/server/game/Server/Packets/BankPackets.cpp8
-rw-r--r--src/server/game/Server/Packets/BankPackets.h14
-rw-r--r--src/server/game/Server/Packets/CalendarPackets.cpp9
-rw-r--r--src/server/game/Server/Packets/CalendarPackets.h11
-rw-r--r--src/server/game/Server/Packets/CharacterPackets.cpp143
-rw-r--r--src/server/game/Server/Packets/CharacterPackets.h71
-rw-r--r--src/server/game/Server/Packets/ChatPackets.cpp8
-rw-r--r--src/server/game/Server/Packets/CombatLogPackets.cpp2
-rw-r--r--src/server/game/Server/Packets/CombatLogPacketsCommon.cpp6
-rw-r--r--src/server/game/Server/Packets/CombatLogPacketsCommon.h4
-rw-r--r--src/server/game/Server/Packets/CombatPackets.cpp4
-rw-r--r--src/server/game/Server/Packets/CombatPackets.h2
-rw-r--r--src/server/game/Server/Packets/CraftingPacketsCommon.cpp5
-rw-r--r--src/server/game/Server/Packets/CraftingPacketsCommon.h5
-rw-r--r--src/server/game/Server/Packets/EquipmentSetPackets.cpp4
-rw-r--r--src/server/game/Server/Packets/EquipmentSetPackets.h2
-rw-r--r--src/server/game/Server/Packets/GuildPackets.cpp12
-rw-r--r--src/server/game/Server/Packets/GuildPackets.h10
-rw-r--r--src/server/game/Server/Packets/InstancePackets.cpp4
-rw-r--r--src/server/game/Server/Packets/InstancePackets.h4
-rw-r--r--src/server/game/Server/Packets/ItemPackets.cpp2
-rw-r--r--src/server/game/Server/Packets/ItemPackets.h2
-rw-r--r--src/server/game/Server/Packets/ItemPacketsCommon.cpp4
-rw-r--r--src/server/game/Server/Packets/MovementPackets.cpp1
-rw-r--r--src/server/game/Server/Packets/MovementPackets.h1
-rw-r--r--src/server/game/Server/Packets/NPCPackets.cpp10
-rw-r--r--src/server/game/Server/Packets/NPCPackets.h9
-rw-r--r--src/server/game/Server/Packets/PartyPackets.cpp1
-rw-r--r--src/server/game/Server/Packets/PartyPackets.h2
-rw-r--r--src/server/game/Server/Packets/QueryPackets.cpp19
-rw-r--r--src/server/game/Server/Packets/QueryPackets.h8
-rw-r--r--src/server/game/Server/Packets/QuestPackets.cpp80
-rw-r--r--src/server/game/Server/Packets/QuestPackets.h32
-rw-r--r--src/server/game/Server/Packets/ReputationPackets.cpp35
-rw-r--r--src/server/game/Server/Packets/ReputationPackets.h20
-rw-r--r--src/server/game/Server/Packets/ScenePackets.cpp1
-rw-r--r--src/server/game/Server/Packets/ScenePackets.h1
-rw-r--r--src/server/game/Server/Packets/SocialPackets.cpp2
-rw-r--r--src/server/game/Server/Packets/SocialPackets.h2
-rw-r--r--src/server/game/Server/Packets/SpellPackets.cpp4
-rw-r--r--src/server/game/Server/Packets/SpellPackets.h2
-rw-r--r--src/server/game/Server/Packets/SystemPackets.cpp56
-rw-r--r--src/server/game/Server/Packets/SystemPackets.h43
-rw-r--r--src/server/game/Server/Packets/TaxiPackets.cpp7
-rw-r--r--src/server/game/Server/Packets/TaxiPackets.h6
-rw-r--r--src/server/game/Server/WorldSession.h16
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp2
74 files changed, 778 insertions, 324 deletions
diff --git a/sql/updates/world/cata_classic/2024_11_01_00_world.sql b/sql/updates/world/cata_classic/2024_11_01_00_world.sql
new file mode 100644
index 00000000000..c17061079ba
--- /dev/null
+++ b/sql/updates/world/cata_classic/2024_11_01_00_world.sql
@@ -0,0 +1,14 @@
+ALTER TABLE `gossip_menu_addon` ADD `LfgDungeonsID` int NOT NULL DEFAULT '0' AFTER `FriendshipFactionID`;
+
+DROP TABLE IF EXISTS `quest_treasure_pickers`;
+CREATE TABLE `quest_treasure_pickers` (
+ `QuestID` int unsigned NOT NULL,
+ `TreasurePickerID` int NOT NULL,
+ `OrderIndex` int NOT NULL DEFAULT '0',
+ PRIMARY KEY (`QuestID`,`TreasurePickerID`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+INSERT INTO `quest_treasure_pickers` SELECT `ID`, `TreasurePickerID`, 0 FROM `quest_template` WHERE `TreasurePickerID` <> 0;
+
+ALTER TABLE `quest_template`
+ DROP `TreasurePickerID`;
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
index b9576d9ce66..024aa3264f0 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
@@ -322,6 +322,8 @@ private:
return int64(left->BidAmount) - int64(right->BidAmount);
case AuctionHouseSortOrder::Buyout:
return int64(left->BuyoutOrUnitPrice) - int64(right->BuyoutOrUnitPrice);
+ case AuctionHouseSortOrder::TimeRemaining:
+ return (left->EndTime - right->EndTime).count();
default:
break;
}
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.h b/src/server/game/AuctionHouse/AuctionHouseMgr.h
index bdaa0516339..f6354060022 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.h
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.h
@@ -116,11 +116,12 @@ DEFINE_ENUM_FLAG(AuctionHouseFilterMask);
enum class AuctionHouseSortOrder : uint8
{
- Price = 0,
- Name = 1,
- Level = 2,
- Bid = 3,
- Buyout = 4
+ Price = 0,
+ Name = 1,
+ Level = 2,
+ Bid = 3,
+ Buyout = 4,
+ TimeRemaining = 5
};
enum class AuctionHouseBrowseMode : uint8
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp
index bd7795f31cb..734c0caa392 100644
--- a/src/server/game/DataStores/DB2Stores.cpp
+++ b/src/server/game/DataStores/DB2Stores.cpp
@@ -1629,7 +1629,7 @@ std::vector<DB2Manager::HotfixOptionalData> const* DB2Manager::GetHotfixOptional
uint32 DB2Manager::GetEmptyAnimStateID() const
{
//return sAnimationDataStore.GetNumRows();
- return 1778; // the Classic client expects the retail storage size so we have to hardcode the value
+ return 1788; // Yup, again
}
void DB2Manager::InsertNewHotfix(uint32 tableHash, uint32 recordId)
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index 81cba0090b0..55d60d4ec5f 100644
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -1758,7 +1758,7 @@ enum class PlayerInteractionType : int32
PersonalTabardVendor = 65,
ForgeMaster = 66,
CharacterBanker = 67,
- AccountBanker = 68
+ AccountBanker = 68,
};
enum class PowerTypeFlags : int16
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp
index 3de50a81f32..2aef082dd71 100644
--- a/src/server/game/Entities/Creature/GossipDef.cpp
+++ b/src/server/game/Entities/Creature/GossipDef.cpp
@@ -246,7 +246,10 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID)
packet.GossipGUID = objectGUID;
packet.GossipID = _gossipMenu.GetMenuId();
if (GossipMenuAddon const* addon = sObjectMgr->GetGossipMenuAddon(packet.GossipID))
+ {
packet.FriendshipFactionID = addon->FriendshipFactionID;
+ packet.LfgDungeonsID = addon->LfgDungeonsID;
+ }
if (NpcText const* text = sObjectMgr->GetNpcText(titleTextId))
packet.BroadcastTextID = Trinity::Containers::SelectRandomWeightedContainerElement(text->Data, [](NpcTextData const& data) { return data.Probability; })->BroadcastTextID;
@@ -284,8 +287,10 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID)
text.QuestMaxScalingLevel = quest->GetQuestMaxScalingLevel();
text.QuestFlags[0] = quest->GetFlags();
text.QuestFlags[1] = quest->GetFlagsEx();
+ text.QuestFlags[2] = quest->GetFlagsEx2();
text.Repeatable = quest->IsTurnIn() && quest->IsRepeatable() && !quest->IsDailyOrWeekly() && !quest->IsMonthly();
text.Important = quest->IsImportant();
+ text.Meta = quest->IsMeta();
text.QuestTitle = quest->GetLogTitle();
LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex();
@@ -411,8 +416,10 @@ void PlayerMenu::SendQuestGiverQuestListMessage(Object* questgiver)
text.QuestType = questMenuItem.QuestIcon;
text.QuestFlags[0] = quest->GetFlags();
text.QuestFlags[1] = quest->GetFlagsEx();
+ text.QuestFlags[2] = quest->GetFlagsEx2();
text.Repeatable = quest->IsTurnIn() && quest->IsRepeatable() && !quest->IsDailyOrWeekly() && !quest->IsMonthly();
text.Important = quest->IsImportant();
+ text.Meta = quest->IsMeta();
text.QuestTitle = quest->GetLogTitle();
LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex();
@@ -478,6 +485,7 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGU
packet.PortraitGiverMount = quest->GetQuestGiverPortraitMount();
packet.PortraitGiverModelSceneID = quest->GetQuestGiverPortraitModelSceneId();
packet.PortraitTurnIn = quest->GetQuestTurnInPortrait();
+ packet.QuestInfoID = quest->GetQuestInfoID();
packet.QuestSessionBonus = 0; //quest->GetQuestSessionBonus(); // this is only sent while quest session is active
packet.AutoLaunched = autoLaunched;
packet.DisplayPopup = displayPopup;
@@ -510,9 +518,9 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGU
for (uint32 i = 0; i < objs.size(); ++i)
{
packet.Objectives[i].ID = objs[i].ID;
+ packet.Objectives[i].Type = objs[i].Type;
packet.Objectives[i].ObjectID = objs[i].ObjectID;
packet.Objectives[i].Amount = objs[i].Amount;
- packet.Objectives[i].Type = objs[i].Type;
}
_session->SendPacket(packet.Write());
@@ -582,6 +590,7 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, ObjectGuid npcGUI
offer.QuestID = quest->GetQuestId();
offer.AutoLaunched = autoLaunched;
offer.SuggestedPartyMembers = quest->GetSuggestedPlayers();
+ offer.QuestInfoID = quest->GetQuestInfoID();
for (uint32 i = 0; i < QUEST_EMOTE_COUNT && quest->OfferRewardEmote[i]; ++i)
offer.Emotes.emplace_back(quest->OfferRewardEmote[i], quest->OfferRewardEmoteDelay[i]);
@@ -656,6 +665,7 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, ObjectGuid npcGU
packet.QuestFlags[1] = quest->GetFlagsEx();
packet.QuestFlags[2] = quest->GetFlagsEx2();
packet.SuggestPartyMembers = quest->GetSuggestedPlayers();
+ packet.QuestInfoID = quest->GetQuestInfoID();
// incomplete: FD
// incomplete quest with item objective but item objective is complete DD
diff --git a/src/server/game/Entities/Item/Container/Bag.h b/src/server/game/Entities/Item/Container/Bag.h
index cb303ed329a..12d40c84553 100644
--- a/src/server/game/Entities/Item/Container/Bag.h
+++ b/src/server/game/Entities/Item/Container/Bag.h
@@ -19,7 +19,7 @@
#define TRINITY_BAG_H
// Maximum 36 Slots ((CONTAINER_END - CONTAINER_FIELD_SLOT_1)/2
-#define MAX_BAG_SIZE 36 // 2.0.12
+#define MAX_BAG_SIZE 36 // 4.4.1
#include "Item.h"
diff --git a/src/server/game/Entities/Object/Updates/UpdateMask.h b/src/server/game/Entities/Object/Updates/UpdateMask.h
index b8262387907..a79b5c038ab 100644
--- a/src/server/game/Entities/Object/Updates/UpdateMask.h
+++ b/src/server/game/Entities/Object/Updates/UpdateMask.h
@@ -63,7 +63,7 @@ public:
constexpr bool operator[](uint32 index) const
{
- return (_blocks[index / 32] & (1 << (index % 32))) != 0;
+ return (_blocks[UpdateMaskHelpers::GetBlockIndex(index)] & UpdateMaskHelpers::GetBlockFlag(index)) != 0;
}
constexpr bool IsAnySet() const
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index a8291c568ed..9a3adbd32d4 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -6100,6 +6100,35 @@ int32 Player::CalculateReputationGain(ReputationSource source, uint32 creatureOr
return CalculatePct(rep, percent);
}
+void Player::SetVisibleForcedReaction(uint32 factionId, ReputationRank rank)
+{
+ auto itr = std::ranges::find(m_playerData->ForcedReactions, int32(factionId), &UF::ZonePlayerForcedReaction::FactionID);
+ if (itr == m_playerData->ForcedReactions.end())
+ itr = std::ranges::find(m_playerData->ForcedReactions, 0, &UF::ZonePlayerForcedReaction::FactionID);
+
+ if (itr == m_playerData->ForcedReactions.end())
+ return; // no more free slots
+
+ auto setter = m_values.ModifyValue(&Player::m_playerData)
+ .ModifyValue(&UF::PlayerData::ForcedReactions, std::ranges::distance(m_playerData->ForcedReactions.begin(), itr));
+
+ SetUpdateFieldValue(setter.ModifyValue(&UF::ZonePlayerForcedReaction::FactionID), factionId);
+ SetUpdateFieldValue(setter.ModifyValue(&UF::ZonePlayerForcedReaction::Reaction), rank);
+}
+
+void Player::RemoveVisibleForcedReaction(uint32 factionId)
+{
+ auto itr = std::ranges::find(m_playerData->ForcedReactions, int32(factionId), &UF::ZonePlayerForcedReaction::FactionID);
+ if (itr == m_playerData->ForcedReactions.end())
+ return;
+
+ auto setter = m_values.ModifyValue(&Player::m_playerData)
+ .ModifyValue(&UF::PlayerData::ForcedReactions, std::ranges::distance(m_playerData->ForcedReactions.begin(), itr));
+
+ SetUpdateFieldValue(setter.ModifyValue(&UF::ZonePlayerForcedReaction::FactionID), 0);
+ SetUpdateFieldValue(setter.ModifyValue(&UF::ZonePlayerForcedReaction::Reaction), 0);
+}
+
// Calculates how many reputation points player gains in victim's enemy factions
void Player::RewardReputation(Unit* victim, float rate)
{
@@ -12983,6 +13012,7 @@ void Player::SendNewItem(Item* item, uint32 quantity, bool pushed, bool created,
packet.QuestLogItemID = item->GetTemplate()->QuestLogItemId;
packet.Quantity = quantity;
packet.QuantityInInventory = GetItemCount(item->GetEntry());
+
packet.BattlePetSpeciesID = item->GetModifier(ITEM_MODIFIER_BATTLE_PET_SPECIES_ID);
packet.BattlePetBreedID = item->GetModifier(ITEM_MODIFIER_BATTLE_PET_BREED_DATA) & 0xFFFFFF;
packet.BattlePetBreedQuality = (item->GetModifier(ITEM_MODIFIER_BATTLE_PET_BREED_DATA) >> 24) & 0xFF;
@@ -15243,20 +15273,28 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object const* questgiver) const
case QUEST_STATUS_COMPLETE:
if (quest->IsImportant())
result |= quest->HasFlag(QUEST_FLAGS_HIDE_REWARD_POI) ? QuestGiverStatus::ImportantQuestRewardCompleteNoPOI : QuestGiverStatus::ImportantQuestRewardCompletePOI;
+ else if (quest->IsMeta())
+ result |= quest->HasFlag(QUEST_FLAGS_HIDE_REWARD_POI) ? QuestGiverStatus::MetaQuestRewardCompleteNoPOI : QuestGiverStatus::MetaQuestRewardCompletePOI;
else if (quest->GetQuestTag() == QuestTagType::CovenantCalling)
result |= quest->HasFlag(QUEST_FLAGS_HIDE_REWARD_POI) ? QuestGiverStatus::CovenantCallingRewardCompleteNoPOI : QuestGiverStatus::CovenantCallingRewardCompletePOI;
else if (quest->HasFlagEx(QUEST_FLAGS_EX_LEGENDARY))
result |= quest->HasFlag(QUEST_FLAGS_HIDE_REWARD_POI) ? QuestGiverStatus::LegendaryRewardCompleteNoPOI : QuestGiverStatus::LegendaryRewardCompletePOI;
+ else if (quest->IsDailyOrWeekly())
+ result |= quest->HasFlag(QUEST_FLAGS_HIDE_REWARD_POI) ? QuestGiverStatus::RepeatableRewardCompleteNoPOI : QuestGiverStatus::RepeatableRewardCompletePOI;
else
result |= quest->HasFlag(QUEST_FLAGS_HIDE_REWARD_POI) ? QuestGiverStatus::RewardCompleteNoPOI : QuestGiverStatus::RewardCompletePOI;
break;
case QUEST_STATUS_INCOMPLETE:
if (quest->IsImportant())
result |= QuestGiverStatus::ImportantReward;
+ else if (quest->IsMeta())
+ result |= QuestGiverStatus::MetaReward;
else if (quest->GetQuestTag() == QuestTagType::CovenantCalling)
result |= QuestGiverStatus::CovenantCallingReward;
else if (quest->HasFlagEx(QUEST_FLAGS_EX_LEGENDARY))
result |= QuestGiverStatus::LegendaryReward;
+ else if (quest->IsDailyOrWeekly())
+ result |= QuestGiverStatus::RepeatableReward;
else
result |= QuestGiverStatus::Reward;
break;
@@ -15264,12 +15302,17 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object const* questgiver) const
break;
}
- if (quest->IsTurnIn() && CanTakeQuest(quest, false) && quest->IsRepeatable() && !quest->IsDailyOrWeekly() && !quest->IsMonthly())
+ if (quest->IsTurnIn() && CanTakeQuest(quest, false))
{
- if (GetLevel() > (GetQuestLevel(quest) + sWorld->getIntConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF)))
- result |= QuestGiverStatus::RepeatableTurnin;
+ if (quest->IsRepeatable())
+ {
+ if (GetLevel() > (GetQuestLevel(quest) + sWorld->getIntConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF)))
+ result |= QuestGiverStatus::RepeatableTurnin;
+ else
+ result |= QuestGiverStatus::TrivialRepeatableTurnin;
+ }
else
- result |= QuestGiverStatus::TrivialRepeatableTurnin;
+ result |= quest->HasFlag(QUEST_FLAGS_HIDE_REWARD_POI) ? QuestGiverStatus::RewardCompleteNoPOI : QuestGiverStatus::RewardCompletePOI;
}
}
@@ -15291,12 +15334,14 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object const* questgiver) const
bool isTrivial = GetLevel() > (GetQuestLevel(quest) + sWorld->getIntConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF));
if (quest->IsImportant())
result |= isTrivial ? QuestGiverStatus::TrivialImportantQuest : QuestGiverStatus::ImportantQuest;
+ else if (quest->IsMeta())
+ result |= isTrivial ? QuestGiverStatus::TrivialMetaQuest : QuestGiverStatus::MetaQuest;
else if (quest->GetQuestTag() == QuestTagType::CovenantCalling)
result |= QuestGiverStatus::CovenantCallingQuest;
else if (quest->HasFlagEx(QUEST_FLAGS_EX_LEGENDARY))
result |= isTrivial ? QuestGiverStatus::TrivialLegendaryQuest : QuestGiverStatus::LegendaryQuest;
- else if (quest->IsDaily())
- result |= isTrivial ? QuestGiverStatus::TrivialDailyQuest : QuestGiverStatus::DailyQuest;
+ else if (quest->IsDailyOrWeekly())
+ result |= isTrivial ? QuestGiverStatus::TrivialRepeatableQuest : QuestGiverStatus::RepeatableQuest;
else
result |= isTrivial ? QuestGiverStatus::Trivial : QuestGiverStatus::Quest;
}
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index ebbe8672933..0265e2f79db 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -2221,6 +2221,9 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
int32 CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool noQuestBonus = false);
+ void SetVisibleForcedReaction(uint32 factionId, ReputationRank rank);
+ void RemoveVisibleForcedReaction(uint32 factionId);
+
void UpdateSkillsForLevel();
void ModifySkillBonus(uint32 skillid, int32 val, bool talent);
diff --git a/src/server/game/Entities/Unit/enuminfo_UnitDefines.cpp b/src/server/game/Entities/Unit/enuminfo_UnitDefines.cpp
index ba419d8a6b2..0c04002403b 100644
--- a/src/server/game/Entities/Unit/enuminfo_UnitDefines.cpp
+++ b/src/server/game/Entities/Unit/enuminfo_UnitDefines.cpp
@@ -421,7 +421,7 @@ TC_API_EXPORT EnumText EnumUtils<NPCFlags>::ToString(NPCFlags value)
case UNIT_NPC_FLAG_NONE: return { "UNIT_NPC_FLAG_NONE", "UNIT_NPC_FLAG_NONE", "" };
case UNIT_NPC_FLAG_GOSSIP: return { "UNIT_NPC_FLAG_GOSSIP", "has gossip menu", "100%" };
case UNIT_NPC_FLAG_QUESTGIVER: return { "UNIT_NPC_FLAG_QUESTGIVER", "is quest giver", "100%" };
- case UNIT_NPC_FLAG_ACCOUNT_BANKER: return { "UNIT_NPC_FLAG_ACCOUNT_BANKER", "UNIT_NPC_FLAG_ACCOUNT_BANKER", "" };
+ case UNIT_NPC_FLAG_ACCOUNT_BANKER: return { "UNIT_NPC_FLAG_ACCOUNT_BANKER", "is account banker", "" };
case UNIT_NPC_FLAG_UNK2: return { "UNIT_NPC_FLAG_UNK2", "UNIT_NPC_FLAG_UNK2", "" };
case UNIT_NPC_FLAG_TRAINER: return { "UNIT_NPC_FLAG_TRAINER", "is trainer", "100%" };
case UNIT_NPC_FLAG_TRAINER_CLASS: return { "UNIT_NPC_FLAG_TRAINER_CLASS", "is class trainer", "100%" };
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 3a55a5ae777..e4e06525335 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -4303,9 +4303,9 @@ void ObjectMgr::LoadQuests()
"RewardFactionID5, RewardFactionValue5, RewardFactionOverride5, RewardFactionCapIn5, RewardFactionFlags, "
//93 94 95 96 97 98 99 100
"RewardCurrencyID1, RewardCurrencyQty1, RewardCurrencyID2, RewardCurrencyQty2, RewardCurrencyID3, RewardCurrencyQty3, RewardCurrencyID4, RewardCurrencyQty4, "
- //101 102 103 104 105 106 107 108 109
- "AcceptedSoundKitID, CompleteSoundKitID, AreaGroupID, TimeAllowed, AllowableRaces, TreasurePickerID, Expansion, ManagedWorldStateID, QuestSessionBonus, "
- //110 111 112 113 114 115 116 117 118
+ //101 102 103 104 105 106 107 108
+ "AcceptedSoundKitID, CompleteSoundKitID, AreaGroupID, TimeAllowed, AllowableRaces, Expansion, ManagedWorldStateID, QuestSessionBonus, "
+ //109 110 111 112 113 114 115 116 117
"LogTitle, LogDescription, QuestDescription, AreaDescription, PortraitGiverText, PortraitGiverName, PortraitTurnInText, PortraitTurnInName, QuestCompletionLog "
"FROM quest_template");
if (!result)
@@ -4384,7 +4384,10 @@ void ObjectMgr::LoadQuests()
{ "QuestId, PlayerConditionId, QuestgiverCreatureId, Text, locale", "quest_offer_reward_conditional", "ORDER BY OrderIndex", "conditional reward", &Quest::LoadConditionalConditionalOfferRewardText },
// 0 1 2 3 4
- { "QuestId, PlayerConditionId, QuestgiverCreatureId, Text, locale", "quest_completion_log_conditional", "ORDER BY OrderIndex", "conditional completion log", &Quest::LoadConditionalConditionalQuestCompletionLog }
+ { "QuestId, PlayerConditionId, QuestgiverCreatureId, Text, locale", "quest_completion_log_conditional", "ORDER BY OrderIndex", "conditional completion log", &Quest::LoadConditionalConditionalQuestCompletionLog },
+
+ // 0 1
+ { "QuestID, TreasurePickerID", "quest_treasure_pickers", "ORDER BY OrderIndex", "treasure pickers", &Quest::LoadTreasurePickers }
};
for (QuestLoaderHelper const& loader : QuestLoaderHelpers)
@@ -9518,8 +9521,8 @@ void ObjectMgr::LoadGossipMenuAddon()
_gossipMenuAddonStore.clear();
- // 0 1
- QueryResult result = WorldDatabase.Query("SELECT MenuID, FriendshipFactionID FROM gossip_menu_addon");
+ // 0 1 2
+ QueryResult result = WorldDatabase.Query("SELECT MenuID, FriendshipFactionID, LfgDungeonsID FROM gossip_menu_addon");
if (!result)
{
@@ -9534,20 +9537,30 @@ void ObjectMgr::LoadGossipMenuAddon()
uint32 menuID = fields[0].GetUInt32();
GossipMenuAddon& addon = _gossipMenuAddonStore[menuID];
addon.FriendshipFactionID = fields[1].GetInt32();
+ addon.LfgDungeonsID = fields[2].GetInt32();
- if (FactionEntry const* faction = sFactionStore.LookupEntry(addon.FriendshipFactionID))
+ if (addon.FriendshipFactionID)
{
- if (!sFriendshipReputationStore.LookupEntry(faction->FriendshipRepID))
+ if (FactionEntry const* faction = sFactionStore.LookupEntry(addon.FriendshipFactionID))
+ {
+ if (!sFriendshipReputationStore.LookupEntry(faction->FriendshipRepID))
+ {
+ TC_LOG_ERROR("sql.sql", "Table gossip_menu_addon: ID {} is using FriendshipFactionID {} referencing non-existing FriendshipRepID {}",
+ menuID, addon.FriendshipFactionID, faction->FriendshipRepID);
+ addon.FriendshipFactionID = 0;
+ }
+ }
+ else
{
- TC_LOG_ERROR("sql.sql", "Table gossip_menu_addon: ID {} is using FriendshipFactionID {} referencing non-existing FriendshipRepID {}",
- menuID, addon.FriendshipFactionID, faction->FriendshipRepID);
+ TC_LOG_ERROR("sql.sql", "Table gossip_menu_addon: ID {} is using non-existing FriendshipFactionID {}", menuID, addon.FriendshipFactionID);
addon.FriendshipFactionID = 0;
}
}
- else
+
+ if (addon.LfgDungeonsID && sLFGDungeonsStore.LookupEntry(addon.LfgDungeonsID))
{
- TC_LOG_ERROR("sql.sql", "Table gossip_menu_addon: ID {} is using non-existing FriendshipFactionID {}", menuID, addon.FriendshipFactionID);
- addon.FriendshipFactionID = 0;
+ TC_LOG_ERROR("sql.sql", "Table gossip_menu_addon: ID {} is using non-existing LfgDungeonsID {}", menuID, addon.LfgDungeonsID);
+ addon.LfgDungeonsID = 0;
}
} while (result->NextRow());
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index e972ca59ef1..72e0bfaa332 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -779,6 +779,7 @@ struct GossipMenus
struct GossipMenuAddon
{
int32 FriendshipFactionID;
+ int32 LfgDungeonsID;
};
typedef std::multimap<uint32, GossipMenus> GossipMenusContainer;
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index bd173358fa1..90c895d11a3 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -246,6 +246,9 @@ void Group::LoadGroupFromDB(Field* fields)
m_masterLooterGuid = ObjectGuid::Create<HighGuid::Player>(fields[16].GetUInt64());
+ // m_pingRestriction = RestrictPingsTo(fields[18].GetInt8());
+ m_pingRestriction = RestrictPingsTo::None;
+
if (m_groupFlags & GROUP_FLAG_LFG)
sLFGMgr->_LoadFromDB(fields, GetGUID());
}
@@ -870,6 +873,8 @@ void Group::SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot const* slot) co
partyUpdate.SequenceNum = player->NextGroupUpdateSequenceNumber(m_groupCategory);
+ partyUpdate.PingRestriction = m_pingRestriction;
+
partyUpdate.MyIndex = -1;
uint8 index = 0;
for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr, ++index)
@@ -1901,27 +1906,27 @@ void Group::SetEveryoneIsAssistant(bool apply)
SendUpdate();
}
-bool Group::IsRestrictPingsToAssistants() const
+RestrictPingsTo Group::GetRestrictPings() const
{
- return (m_groupFlags & GROUP_FLAG_RESTRICT_PINGS) != 0;
+ return m_pingRestriction;
}
-void Group::SetRestrictPingsToAssistants(bool restrictPingsToAssistants)
+void Group::SetRestrictPingsTo(RestrictPingsTo restrictTo)
{
- if (restrictPingsToAssistants)
- m_groupFlags = GroupFlags(m_groupFlags | GROUP_FLAG_RESTRICT_PINGS);
- else
- m_groupFlags = GroupFlags(m_groupFlags & ~GROUP_FLAG_RESTRICT_PINGS);
+ m_pingRestriction = restrictTo;
+ // Classic only - Disabled
+ /*
if (!isBGGroup() && !isBFGroup())
{
- CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_TYPE);
+ CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_PING_RESTRICTION);
- stmt->setUInt16(0, m_groupFlags);
+ stmt->setInt8(0, int8(m_pingRestriction));
stmt->setUInt32(1, m_dbStoreId);
CharacterDatabase.Execute(stmt);
}
SendUpdate();
+ */
}
diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h
index 8ba2f36e3c3..773c705a08a 100644
--- a/src/server/game/Groups/Group.h
+++ b/src/server/game/Groups/Group.h
@@ -103,7 +103,7 @@ enum GroupFlags : uint16
GROUP_FLAG_EVERYONE_ASSISTANT = 0x040, // Script_IsEveryoneAssistant()
GROUP_FLAG_GUILD_GROUP = 0x100,
GROUP_FLAG_CROSS_FACTION = 0x200,
- GROUP_FLAG_RESTRICT_PINGS = 0x400, // C_PartyInfo::Script_GetRestrictPings()
+ GROUP_FLAG_RESTRICT_PINGS = 0x400, // deprecated
GROUP_MASK_BGRAID = GROUP_FLAG_FAKE_RAID | GROUP_FLAG_RAID,
};
@@ -191,6 +191,15 @@ enum class PingSubjectType : uint8
Max
};
+
+enum class RestrictPingsTo : int32
+{
+ None = 0,
+ Lead = 1,
+ Assist = 2,
+ TankHealer = 3,
+};
+
/** request member stats checken **/
/// @todo uninvite people that not accepted invite
class TC_GAME_API Group
@@ -260,8 +269,8 @@ class TC_GAME_API Group
void SetLfgRoles(ObjectGuid guid, uint8 roles);
uint8 GetLfgRoles(ObjectGuid guid) const;
void SetEveryoneIsAssistant(bool apply);
- bool IsRestrictPingsToAssistants() const;
- void SetRestrictPingsToAssistants(bool restrictPingsToAssistants);
+ RestrictPingsTo GetRestrictPings() const;
+ void SetRestrictPingsTo(RestrictPingsTo restrictTo);
// Update
void UpdateReadyCheck(uint32 diff);
@@ -451,6 +460,8 @@ class TC_GAME_API Group
std::array<std::unique_ptr<CountdownInfo>, 3> m_countdowns;
+ RestrictPingsTo m_pingRestriction;
+
struct NoopGroupDeleter { void operator()(Group*) const { /*noop - not managed*/ } };
Trinity::unique_trackable_ptr<Group> m_scriptRef;
};
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index 28147294e1d..8a5ead4c218 100644
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -2479,7 +2479,6 @@ void Guild::SendEventPresenceChanged(WorldSession* session, bool loggedOn, bool
eventPacket.Name = player->GetName();
eventPacket.VirtualRealmAddress = player->m_playerData->VirtualPlayerRealm;
eventPacket.LoggedOn = loggedOn;
- eventPacket.Mobile = false;
if (broadcast)
BroadcastPacket(eventPacket.Write());
diff --git a/src/server/game/Handlers/BankHandler.cpp b/src/server/game/Handlers/BankHandler.cpp
index f10b2553d19..7e8b49e6ef8 100644
--- a/src/server/game/Handlers/BankHandler.cpp
+++ b/src/server/game/Handlers/BankHandler.cpp
@@ -15,14 +15,15 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "WorldSession.h"
#include "BankPackets.h"
-#include "Item.h"
+#include "Creature.h"
#include "DB2Stores.h"
#include "GossipDef.h"
+#include "Item.h"
#include "Log.h"
#include "NPCPackets.h"
#include "Player.h"
-#include "WorldSession.h"
void WorldSession::HandleAutoBankItemOpcode(WorldPackets::Bank::AutoBankItem& packet)
{
@@ -34,6 +35,9 @@ void WorldSession::HandleAutoBankItemOpcode(WorldPackets::Bank::AutoBankItem& pa
return;
}
+ if (packet.BankType != BankType::Character)
+ return;
+
Item* item = _player->GetItemByPos(packet.Bag, packet.Slot);
if (!item)
return;
@@ -57,22 +61,43 @@ void WorldSession::HandleAutoBankItemOpcode(WorldPackets::Bank::AutoBankItem& pa
_player->BankItem(dest, item, true);
}
-void WorldSession::HandleBankerActivateOpcode(WorldPackets::NPC::Hello& packet)
+void WorldSession::HandleBankerActivateOpcode(WorldPackets::Bank::BankerActivate const& bankerActivate)
{
- Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(packet.Unit, UNIT_NPC_FLAG_BANKER, UNIT_NPC_FLAG_2_NONE);
+ if (bankerActivate.InteractionType != PlayerInteractionType::Banker)
+ return;
+
+ Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(bankerActivate.Banker, UNIT_NPC_FLAG_ACCOUNT_BANKER | UNIT_NPC_FLAG_BANKER, UNIT_NPC_FLAG_2_NONE);
if (!unit)
{
- TC_LOG_ERROR("network", "WORLD: HandleBankerActivateOpcode - {} not found or you can not interact with him.", packet.Unit.ToString());
+ TC_LOG_ERROR("network", "WORLD: HandleBankerActivateOpcode - {} not found or you can not interact with him.", bankerActivate.Banker);
return;
}
+ switch (bankerActivate.InteractionType)
+ {
+ case PlayerInteractionType::Banker:
+ if (!unit->HasNpcFlag(UNIT_NPC_FLAG_ACCOUNT_BANKER) || !unit->HasNpcFlag(UNIT_NPC_FLAG_BANKER))
+ return;
+ break;
+ case PlayerInteractionType::CharacterBanker:
+ if (!unit->HasNpcFlag(UNIT_NPC_FLAG_BANKER))
+ return;
+ break;
+ case PlayerInteractionType::AccountBanker:
+ if (!unit->HasNpcFlag(UNIT_NPC_FLAG_ACCOUNT_BANKER))
+ return;
+ break;
+ default:
+ break;
+ }
+
// remove fake death
if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
// set currentBankerGUID for other bank action
- SendShowBank(packet.Unit);
+ SendShowBank(bankerActivate.Banker, bankerActivate.InteractionType);
}
void WorldSession::HandleAutoStoreBankItemOpcode(WorldPackets::Bank::AutoStoreBankItem& packet)
@@ -149,13 +174,13 @@ void WorldSession::HandleBuyBankSlotOpcode(WorldPackets::Bank::BuyBankSlot& pack
_player->UpdateCriteria(CriteriaType::BankSlotsPurchased);
}
-void WorldSession::SendShowBank(ObjectGuid guid)
+void WorldSession::SendShowBank(ObjectGuid guid, PlayerInteractionType interactionType)
{
_player->PlayerTalkClass->GetInteractionData().Reset();
_player->PlayerTalkClass->GetInteractionData().SourceGuid = guid;
WorldPackets::NPC::NPCInteractionOpenResult npcInteraction;
npcInteraction.Npc = guid;
- npcInteraction.InteractionType = PlayerInteractionType::Banker;
+ npcInteraction.InteractionType = interactionType;
npcInteraction.Success = true;
SendPacket(npcInteraction.Write());
}
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 3603e793405..6f4bf4e2091 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -349,7 +349,7 @@ void WorldSession::HandleCharEnum(CharacterDatabaseQueryHolder const& holder)
{
charEnum.Characters.emplace_back(result->Fetch());
- WorldPackets::Character::EnumCharactersResult::CharacterInfo& charInfo = charEnum.Characters.back();
+ WorldPackets::Character::EnumCharactersResult::CharacterInfoBasic& charInfo = charEnum.Characters.back().Basic;
if (std::vector<UF::ChrCustomizationChoice>* customizationsForChar = Trinity::Containers::MapGetValuePtr(customizations, charInfo.Guid.GetCounter()))
charInfo.Customizations = std::move(*customizationsForChar);
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index 9217e42225b..5f2ab41c856 100644
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -260,6 +260,7 @@ void WorldSession::HandleSuspendTokenResponse(WorldPackets::Movement::SuspendTok
packet.MapID = loc.Location.GetMapId();
packet.Loc.Pos = loc.Location;
packet.Reason = !_player->IsBeingTeleportedSeamlessly() ? NEW_WORLD_NORMAL : NEW_WORLD_SEAMLESS;
+ packet.Counter = _player->GetNewWorldCounter();
SendPacket(packet.Write());
if (_player->IsBeingTeleportedSeamlessly())
diff --git a/src/server/game/Handlers/TaxiHandler.cpp b/src/server/game/Handlers/TaxiHandler.cpp
index 39f9a55f601..49066237cc2 100644
--- a/src/server/game/Handlers/TaxiHandler.cpp
+++ b/src/server/game/Handlers/TaxiHandler.cpp
@@ -133,7 +133,7 @@ bool WorldSession::SendLearnNewTaxiNode(Creature* unit)
if (GetPlayer()->m_taxi.SetTaximaskNode(curloc))
{
- SendPacket(WorldPackets::Taxi::NewTaxiPath().Write());
+ SendPacket(WorldPackets::Taxi::NewTaxiPath(curloc).Write());
WorldPackets::Taxi::TaxiNodeStatus data;
data.Unit = unit->GetGUID();
@@ -149,7 +149,7 @@ bool WorldSession::SendLearnNewTaxiNode(Creature* unit)
void WorldSession::SendDiscoverNewTaxiNode(uint32 nodeid)
{
if (GetPlayer()->m_taxi.SetTaximaskNode(nodeid))
- SendPacket(WorldPackets::Taxi::NewTaxiPath().Write());
+ SendPacket(WorldPackets::Taxi::NewTaxiPath(nodeid).Write());
}
void WorldSession::HandleActivateTaxiOpcode(WorldPackets::Taxi::ActivateTaxi& activateTaxi)
diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp
index 55db20cb361..beddc00ba99 100644
--- a/src/server/game/Quests/QuestDef.cpp
+++ b/src/server/game/Quests/QuestDef.cpp
@@ -118,20 +118,19 @@ Quest::Quest(Field* questRecord)
_areaGroupID = questRecord[103].GetUInt32();
_limitTime = questRecord[104].GetInt64();
_allowableRaces.RawValue = questRecord[105].GetUInt64();
- _treasurePickerID = questRecord[106].GetInt32();
- _expansion = questRecord[107].GetInt32();
- _managedWorldStateID = questRecord[108].GetInt32();
- _questSessionBonus = questRecord[109].GetInt32();
-
- _logTitle = questRecord[110].GetString();
- _logDescription = questRecord[111].GetString();
- _questDescription = questRecord[112].GetString();
- _areaDescription = questRecord[113].GetString();
- _portraitGiverText = questRecord[114].GetString();
- _portraitGiverName = questRecord[115].GetString();
- _portraitTurnInText = questRecord[116].GetString();
- _portraitTurnInName = questRecord[117].GetString();
- _questCompletionLog = questRecord[118].GetString();
+ _expansion = questRecord[106].GetInt32();
+ _managedWorldStateID = questRecord[107].GetInt32();
+ _questSessionBonus = questRecord[108].GetInt32();
+
+ _logTitle = questRecord[109].GetString();
+ _logDescription = questRecord[110].GetString();
+ _questDescription = questRecord[111].GetString();
+ _areaDescription = questRecord[112].GetString();
+ _portraitGiverText = questRecord[113].GetString();
+ _portraitGiverName = questRecord[114].GetString();
+ _portraitTurnInText = questRecord[115].GetString();
+ _portraitTurnInName = questRecord[116].GetString();
+ _questCompletionLog = questRecord[117].GetString();
}
Quest::~Quest()
@@ -408,6 +407,11 @@ void Quest::LoadConditionalConditionalQuestCompletionLog(Field* fields)
ObjectMgr::AddLocaleString(fields[3].GetStringView(), locale, text.Text);
}
+void Quest::LoadTreasurePickers(Field* fields)
+{
+ _treasurePickerID.push_back(fields[1].GetInt32());
+}
+
uint32 Quest::XPValue(Player const* player) const
{
return XPValue(player ? player->GetLevel() : 0, GetQuestLevelForPlayer(player), _level, _rewardXPDifficulty, _rewardXPMultiplier);
@@ -468,6 +472,14 @@ bool Quest::IsImportant() const
return false;
}
+bool Quest::IsMeta() const
+{
+ if (QuestInfoEntry const* questInfo = sQuestInfoStore.LookupEntry(GetQuestInfoID()))
+ return (questInfo->Modifiers & 0x800) != 0;
+
+ return false;
+}
+
uint32 Quest::GetQuestLevelForPlayer(Player const* player) const
{
if (_level != -1)
@@ -511,7 +523,7 @@ void Quest::BuildQuestRewards(WorldPackets::Quest::QuestRewards& rewards, Player
rewards.SpellCompletionID = GetRewSpell();
rewards.SkillLineID = GetRewardSkillId();
rewards.NumSkillUps = GetRewardSkillPoints();
- rewards.TreasurePickerID = GetTreasurePickerId();
+ //rewards.TreasurePickerID = GetTreasurePickerId();
for (uint32 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
{
@@ -522,8 +534,8 @@ void Quest::BuildQuestRewards(WorldPackets::Quest::QuestRewards& rewards, Player
for (uint32 i = 0; i < QUEST_REWARD_ITEM_COUNT; ++i)
{
- rewards.ItemID[i] = RewardItemId[i];
- rewards.ItemQty[i] = RewardItemCount[i];
+ rewards.Items[i].ItemID = RewardItemId[i];
+ rewards.Items[i].ItemQty = RewardItemCount[i];
}
for (uint32 i = 0; i < QUEST_REWARD_REPUTATIONS_COUNT; ++i)
@@ -536,8 +548,8 @@ void Quest::BuildQuestRewards(WorldPackets::Quest::QuestRewards& rewards, Player
for (uint32 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
{
- rewards.CurrencyID[i] = RewardCurrencyId[i];
- rewards.CurrencyQty[i] = RewardCurrencyCount[i];
+ rewards.Currencies[i].CurrencyID = RewardCurrencyId[i];
+ rewards.Currencies[i].CurrencyQty = RewardCurrencyCount[i];
}
}
diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h
index 3b800a679bc..4934b838a97 100644
--- a/src/server/game/Quests/QuestDef.h
+++ b/src/server/game/Quests/QuestDef.h
@@ -124,39 +124,53 @@ enum QuestStatus : uint8
enum class QuestGiverStatus : uint64
{
- None = 0x000000000,
- Future = 0x000000002,
- Trivial = 0x000000004,
- TrivialRepeatableTurnin = 0x000000008,
- TrivialDailyQuest = 0x000000010,
- Reward = 0x000000020,
- JourneyReward = 0x000000040,
- CovenantCallingReward = 0x000000080,
- RepeatableTurnin = 0x000000100,
- DailyQuest = 0x000000200,
- Quest = 0x000000400,
- RewardCompleteNoPOI = 0x000000800,
- RewardCompletePOI = 0x000001000,
- LegendaryQuest = 0x000002000,
- LegendaryRewardCompleteNoPOI = 0x000004000,
- LegendaryRewardCompletePOI = 0x000008000,
- JourneyQuest = 0x000010000,
- JourneyRewardCompleteNoPOI = 0x000020000,
- JourneyRewardCompletePOI = 0x000040000,
- CovenantCallingQuest = 0x000080000,
- CovenantCallingRewardCompleteNoPOI = 0x000100000,
- CovenantCallingRewardCompletePOI = 0x000200000,
- TrivialLegendaryQuest = 0x000400000,
- FutureLegendaryQuest = 0x000800000,
- LegendaryReward = 0x001000000,
- ImportantReward = 0x002000000,
- ImportantQuest = 0x004000000,
- TrivialImportantQuest = 0x008000000,
- FutureImportantQuest = 0x010000000,
- ImportantQuestRewardCompleteNoPOI = 0x020000000,
- ImportantQuestRewardCompletePOI = 0x040000000,
- TrivialJourneyQuest = 0x080000000,
- FutureJourneyQuest = 0x100000000,
+ None = 0x000000000000,
+ Future = 0x000000000002,
+ FutureJourneyQuest = 0x000000000004,
+ FutureLegendaryQuest = 0x000000000008,
+ FutureImportantQuest = 0x000000000010,
+ TrivialRepeatableTurnin = 0x000000000020,
+ Trivial = 0x000000000040,
+ TrivialDailyQuest = 0x000000000080,
+ TrivialRepeatableQuest = 0x000000000100,
+ TrivialMetaQuest = 0x000000000200,
+ TrivialJourneyQuest = 0x000000000400,
+ TrivialLegendaryQuest = 0x000000000800,
+ TrivialImportantQuest = 0x000000001000,
+ Reward = 0x000000002000,
+ RepeatableReward = 0x000000004000,
+ MetaReward = 0x000000008000,
+ JourneyReward = 0x000000010000,
+ CovenantCallingReward = 0x000000020000,
+ LegendaryReward = 0x000000040000,
+ ImportantReward = 0x000000080000,
+ RepeatableTurnin = 0x000000100000,
+ QuestAccountCompleted = 0x000000200000,
+ Quest = 0x000000400000,
+ DailyQuest = 0x000000800000,
+ RepeatableQuest = 0x000001000000,
+ MetaQuest = 0x000002000000,
+ CovenantCallingQuest = 0x000004000000,
+ JourneyQuestAccountCompleted = 0x000008000000,
+ JourneyQuest = 0x000010000000,
+ LegendaryQuestAccountCompleted = 0x000020000000,
+ LegendaryQuest = 0x000040000000,
+ ImportantQuestAccountCompleted = 0x000080000000,
+ ImportantQuest = 0x000100000000,
+ RewardCompleteNoPOI = 0x000200000000,
+ RewardCompletePOI = 0x000400000000,
+ RepeatableRewardCompleteNoPOI = 0x000800000000,
+ RepeatableRewardCompletePOI = 0x001000000000,
+ MetaQuestRewardCompleteNoPOI = 0x002000000000,
+ MetaQuestRewardCompletePOI = 0x004000000000,
+ CovenantCallingRewardCompleteNoPOI = 0x008000000000,
+ CovenantCallingRewardCompletePOI = 0x010000000000,
+ JourneyRewardCompleteNoPOI = 0x020000000000,
+ JourneyRewardCompletePOI = 0x040000000000,
+ LegendaryRewardCompleteNoPOI = 0x080000000000,
+ LegendaryRewardCompletePOI = 0x100000000000,
+ ImportantQuestRewardCompleteNoPOI = 0x200000000000,
+ ImportantQuestRewardCompletePOI = 0x400000000000,
};
DEFINE_ENUM_FLAG(QuestGiverStatus);
@@ -262,6 +276,8 @@ enum QuestFlagsEx2 : uint32
QUEST_FLAGS_EX2_IGNORE_SOULBOUND_ITEMS = 0x00200000,
QUEST_FLAGS_EX2_DONT_DEFER_START_EFFECTS = 0x00400000,
QUEST_FLAGS_EX2_HIDE_REQUIRED_ITEMS_PRE_TURN_IN = 0x00800000,
+
+ QUEST_FLAGS_EX2_ABANDON_ON_DISABLE = 0x04000000,
};
enum QuestSpecialFlags
@@ -360,6 +376,13 @@ enum class QuestCompleteSpellType : uint32
Max
};
+enum class QuestRewardContextFlags : int32
+{
+ None = 0x0,
+ FirstCompletionBonus = 0x1,
+ RepeatCompletionBonus = 0x2
+};
+
struct QuestGreeting
{
uint16 EmoteType;
@@ -417,7 +440,7 @@ struct QuestObjective
{
uint32 ID = 0;
uint32 QuestID = 0;
- uint8 Type = 0;
+ int32 Type = 0;
int8 StorageIndex = 0;
int32 ObjectID = 0;
int32 Amount = 0;
@@ -530,12 +553,14 @@ class TC_GAME_API Quest
void LoadConditionalConditionalRequestItemsText(Field* fields);
void LoadConditionalConditionalOfferRewardText(Field* fields);
void LoadConditionalConditionalQuestCompletionLog(Field* fields);
+ void LoadTreasurePickers(Field* fields);
uint32 XPValue(Player const* player) const;
static uint32 XPValue(uint8 playerLevel, uint32 questLevel, int32 unscaledQuestLevel, uint32 xpDifficulty, float xpMultiplier = 1.0f);
uint32 GetMoneyReward(Player const* player) const;
Optional<QuestTagType> GetQuestTag() const;
bool IsImportant() const;
+ bool IsMeta() const;
uint32 GetQuestLevelForPlayer(Player const* player) const;
bool HasFlag(QuestFlags flag) const { return (_flags & uint32(flag)) != 0; }
@@ -638,7 +663,7 @@ class TC_GAME_API Quest
uint32 GetRewardSkillId() const { return _rewardSkillId; }
uint32 GetRewardSkillPoints() const { return _rewardSkillPoints; }
uint32 GetRewardReputationMask() const { return _rewardReputationMask; }
- int32 GetTreasurePickerId() const { return _treasurePickerID; }
+ std::vector<int32> const& GetTreasurePickerId() const { return _treasurePickerID; }
int32 GetExpansion() const { return _expansion; }
int32 GetManagedWorldStateId() const { return _managedWorldStateID; }
int32 GetQuestSessionBonus() const { return _questSessionBonus; }
@@ -752,7 +777,7 @@ class TC_GAME_API Quest
uint32 _areaGroupID = 0;
int64 _limitTime = 0;
Trinity::RaceMask<uint64> _allowableRaces;
- int32 _treasurePickerID = 0;
+ std::vector<int32> _treasurePickerID;
int32 _expansion = 0;
int32 _managedWorldStateID = 0;
int32 _questSessionBonus = 0;
diff --git a/src/server/game/Reputation/ReputationMgr.cpp b/src/server/game/Reputation/ReputationMgr.cpp
index 770a0dc632f..ed049e73cf6 100644
--- a/src/server/game/Reputation/ReputationMgr.cpp
+++ b/src/server/game/Reputation/ReputationMgr.cpp
@@ -299,9 +299,15 @@ int32 ReputationMgr::GetRenownMaxLevel(FactionEntry const* renownFactionEntry) c
void ReputationMgr::ApplyForceReaction(uint32 faction_id, ReputationRank rank, bool apply)
{
if (apply)
+ {
_forcedReactions[faction_id] = rank;
+ _player->SetVisibleForcedReaction(faction_id, rank);
+ }
else
+ {
_forcedReactions.erase(faction_id);
+ _player->RemoveVisibleForcedReaction(faction_id);
+ }
}
ReputationFlags ReputationMgr::GetDefaultStateFlags(FactionEntry const* factionEntry) const
@@ -356,9 +362,14 @@ void ReputationMgr::SendInitialReputations()
for (FactionStateList::iterator itr = _factions.begin(); itr != _factions.end(); ++itr)
{
- initFactions.FactionFlags[itr->first] = itr->second.Flags.AsUnderlyingType();
- initFactions.FactionStandings[itr->first] = itr->second.Standing;
+ WorldPackets::Reputation::FactionData& factionData = initFactions.Factions.emplace_back();
+ factionData.FactionID = itr->second.ID;
+ factionData.Flags = itr->second.Flags.AsUnderlyingType();
+ factionData.Standing = itr->second.Standing;
/// @todo faction bonus
+ WorldPackets::Reputation::FactionBonusData& bonus = initFactions.Bonuses.emplace_back();
+ bonus.FactionID = itr->second.ID;
+ bonus.FactionHasBonus = false;
itr->second.needSend = false;
}
diff --git a/src/server/game/Server/Packets/AreaTriggerPackets.cpp b/src/server/game/Server/Packets/AreaTriggerPackets.cpp
index ae6dfddb134..c03ddb7d058 100644
--- a/src/server/game/Server/Packets/AreaTriggerPackets.cpp
+++ b/src/server/game/Server/Packets/AreaTriggerPackets.cpp
@@ -82,6 +82,7 @@ WorldPacket const* WorldPackets::AreaTrigger::AreaTriggerDenied::Write()
WorldPacket const* WorldPackets::AreaTrigger::AreaTriggerRePath::Write()
{
_worldPacket << TriggerGUID;
+ _worldPacket << Unused_1100;
_worldPacket.WriteBit(AreaTriggerSpline.has_value());
_worldPacket.WriteBit(AreaTriggerOrbit.has_value());
diff --git a/src/server/game/Server/Packets/AreaTriggerPackets.h b/src/server/game/Server/Packets/AreaTriggerPackets.h
index 2af22e72d2c..1186b772b60 100644
--- a/src/server/game/Server/Packets/AreaTriggerPackets.h
+++ b/src/server/game/Server/Packets/AreaTriggerPackets.h
@@ -82,6 +82,7 @@ namespace WorldPackets
Optional<AreaTriggerOrbitInfo> AreaTriggerOrbit;
Optional<AreaTriggerMovementScriptInfo> AreaTriggerMovementScript;
ObjectGuid TriggerGUID;
+ ObjectGuid Unused_1100;
};
class AreaTriggerPlaySpellVisual final : public ServerPacket
diff --git a/src/server/game/Server/Packets/AuctionHousePackets.cpp b/src/server/game/Server/Packets/AuctionHousePackets.cpp
index f8d951c1c3f..1f4913779f1 100644
--- a/src/server/game/Server/Packets/AuctionHousePackets.cpp
+++ b/src/server/game/Server/Packets/AuctionHousePackets.cpp
@@ -327,7 +327,7 @@ void AuctionSellItem::Read()
if (_worldPacket.ReadBit())
TaintedBy.emplace();
- Items.resize(_worldPacket.ReadBits(6));
+ Items.resize(_worldPacket.ReadBits(5));
if (TaintedBy)
_worldPacket >> *TaintedBy;
diff --git a/src/server/game/Server/Packets/AuthenticationPackets.cpp b/src/server/game/Server/Packets/AuthenticationPackets.cpp
index 5ae68849569..4a948e6ca35 100644
--- a/src/server/game/Server/Packets/AuthenticationPackets.cpp
+++ b/src/server/game/Server/Packets/AuthenticationPackets.cpp
@@ -327,8 +327,8 @@ void WorldPackets::Auth::AuthContinuedSession::Read()
void WorldPackets::Auth::ConnectToFailed::Read()
{
- _worldPacket >> As<uint32>(Serial);
_worldPacket >> Con;
+ _worldPacket >> As<uint32>(Serial);
}
bool WorldPackets::Auth::EnterEncryptedMode::InitializeEncryption()
diff --git a/src/server/game/Server/Packets/BankPackets.cpp b/src/server/game/Server/Packets/BankPackets.cpp
index 0e299e6a5d0..94691712a93 100644
--- a/src/server/game/Server/Packets/BankPackets.cpp
+++ b/src/server/game/Server/Packets/BankPackets.cpp
@@ -16,10 +16,12 @@
*/
#include "BankPackets.h"
+#include "DBCEnums.h"
void WorldPackets::Bank::AutoBankItem::Read()
{
_worldPacket >> Inv
+ >> As<int8>(BankType)
>> Bag
>> Slot;
}
@@ -35,3 +37,9 @@ void WorldPackets::Bank::BuyBankSlot::Read()
{
_worldPacket >> Guid;
}
+
+void WorldPackets::Bank::BankerActivate::Read()
+{
+ _worldPacket >> Banker;
+ _worldPacket >> As<int32>(InteractionType);
+}
diff --git a/src/server/game/Server/Packets/BankPackets.h b/src/server/game/Server/Packets/BankPackets.h
index 4277a33a5eb..054bf6d6688 100644
--- a/src/server/game/Server/Packets/BankPackets.h
+++ b/src/server/game/Server/Packets/BankPackets.h
@@ -22,6 +22,8 @@
#include "ItemPacketsCommon.h"
#include "ObjectGuid.h"
+enum class PlayerInteractionType : int32;
+
namespace WorldPackets
{
namespace Bank
@@ -34,6 +36,7 @@ namespace WorldPackets
void Read() override;
WorldPackets::Item::InvUpdate Inv;
+ ::BankType BankType = ::BankType::Character;
uint8 Bag = 0;
uint8 Slot = 0;
};
@@ -59,6 +62,17 @@ namespace WorldPackets
ObjectGuid Guid;
};
+
+ class BankerActivate final : public ClientPacket
+ {
+ public:
+ explicit BankerActivate(WorldPacket&& packet) : ClientPacket(CMSG_BANKER_ACTIVATE, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Banker;
+ PlayerInteractionType InteractionType = { };
+ };
}
}
#endif // BankPackets_h__
diff --git a/src/server/game/Server/Packets/CalendarPackets.cpp b/src/server/game/Server/Packets/CalendarPackets.cpp
index 62eebccf188..ae2ca129f20 100644
--- a/src/server/game/Server/Packets/CalendarPackets.cpp
+++ b/src/server/game/Server/Packets/CalendarPackets.cpp
@@ -22,7 +22,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Calendar::CalendarSendCal
data << uint64(eventInfo.EventID);
data << uint8(eventInfo.EventType);
data << eventInfo.Date;
- data << uint32(eventInfo.Flags);
+ data << uint16(eventInfo.Flags);
data << int32(eventInfo.TextureID);
data << uint64(eventInfo.EventClubID);
data << eventInfo.OwnerGuid;
@@ -278,7 +278,7 @@ WorldPacket const* WorldPackets::Calendar::CalendarSendEvent::Write()
_worldPacket << uint64(EventID);
_worldPacket << uint8(GetEventType);
_worldPacket << int32(TextureID);
- _worldPacket << uint32(Flags);
+ _worldPacket << uint16(Flags);
_worldPacket << Date;
_worldPacket << LockDate;
_worldPacket << uint64(EventClubID);
@@ -300,7 +300,7 @@ WorldPacket const* WorldPackets::Calendar::CalendarInviteAlert::Write()
{
_worldPacket << uint64(EventID);
_worldPacket << Date;
- _worldPacket << uint32(Flags);
+ _worldPacket << uint16(Flags);
_worldPacket << uint8(EventType);
_worldPacket << int32(TextureID);
_worldPacket << uint64(EventClubID);
@@ -313,6 +313,7 @@ WorldPacket const* WorldPackets::Calendar::CalendarInviteAlert::Write()
_worldPacket << OwnerGuid;
_worldPacket << BitsSize<8>(EventName);
+ _worldPacket << Bits<1>(Unknown_1100);
_worldPacket.FlushBits();
_worldPacket.WriteString(EventName);
@@ -376,7 +377,7 @@ WorldPacket const* WorldPackets::Calendar::CalendarEventUpdatedAlert::Write()
_worldPacket << OriginalDate;
_worldPacket << Date;
_worldPacket << LockDate;
- _worldPacket << uint32(Flags);
+ _worldPacket << uint16(Flags);
_worldPacket << uint32(TextureID);
_worldPacket << uint8(EventType);
diff --git a/src/server/game/Server/Packets/CalendarPackets.h b/src/server/game/Server/Packets/CalendarPackets.h
index cab6ecec89a..cc789a4022d 100644
--- a/src/server/game/Server/Packets/CalendarPackets.h
+++ b/src/server/game/Server/Packets/CalendarPackets.h
@@ -103,7 +103,7 @@ namespace WorldPackets
uint8 EventType = 0;
uint32 TextureID = 0;
WowTime Time;
- uint32 Flags = 0;
+ uint16 Flags = 0;
};
class CalendarUpdateEvent final : public ClientPacket
@@ -185,7 +185,7 @@ namespace WorldPackets
std::string EventName;
uint8 EventType = 0;
WowTime Date;
- uint32 Flags = 0;
+ uint16 Flags = 0;
int32 TextureID = 0;
uint64 EventClubID = 0;
ObjectGuid OwnerGuid;
@@ -228,7 +228,7 @@ namespace WorldPackets
uint64 EventID = 0;
WowTime Date;
WowTime LockDate;
- uint32 Flags = 0;
+ uint16 Flags = 0;
int32 TextureID = 0;
uint8 GetEventType = 0;
uint8 EventType = 0;
@@ -249,13 +249,14 @@ namespace WorldPackets
ObjectGuid InvitedByGuid;
uint64 InviteID = 0;
uint64 EventID = 0;
- uint32 Flags = 0;
+ uint16 Flags = 0;
WowTime Date;
int32 TextureID = 0;
uint8 Status = 0;
uint8 EventType = 0;
uint8 ModeratorStatus = 0;
std::string EventName;
+ bool Unknown_1100 = false;
};
class CalendarInvite final : public ClientPacket
@@ -358,7 +359,7 @@ namespace WorldPackets
uint64 EventClubID = 0;
uint64 EventID = 0;
WowTime Date;
- uint32 Flags = 0;
+ uint16 Flags = 0;
WowTime LockDate;
WowTime OriginalDate;
int32 TextureID = 0;
diff --git a/src/server/game/Server/Packets/CharacterPackets.cpp b/src/server/game/Server/Packets/CharacterPackets.cpp
index e7bfac49d1b..c6fbda45636 100644
--- a/src/server/game/Server/Packets/CharacterPackets.cpp
+++ b/src/server/game/Server/Packets/CharacterPackets.cpp
@@ -79,7 +79,7 @@ EnumCharacters::EnumCharacters(WorldPacket&& packet) : ClientPacket(std::move(pa
ASSERT(GetOpcode() == CMSG_ENUM_CHARACTERS || GetOpcode() == CMSG_ENUM_CHARACTERS_DELETED_BY_CLIENT);
}
-EnumCharactersResult::CharacterInfo::CharacterInfo(Field const* fields)
+EnumCharactersResult::CharacterInfoBasic::CharacterInfoBasic(Field const* fields)
{
// 0 1 2 3 4 5
// "SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.level, "
@@ -95,6 +95,7 @@ EnumCharactersResult::CharacterInfo::CharacterInfo(Field const* fields)
// "character_declinedname.genitive"
Guid = ObjectGuid::Create<HighGuid::Player>(fields[0].GetUInt64());
+ VirtualRealmAddress = GetVirtualRealmAddress();
GuildClubMemberID = ::Battlenet::Services::Clubs::CreateClubMemberId(Guid);
Name = fields[1].GetString();
RaceID = fields[2].GetUInt8();
@@ -137,7 +138,6 @@ EnumCharactersResult::CharacterInfo::CharacterInfo(Field const* fields)
Flags2 = CHAR_CUSTOMIZE_FLAG_RACE;
Flags3 = 0;
- Flags4 = 0;
FirstLogin = (atLoginFlags & AT_LOGIN_FIRST) != 0;
// show pet at selection character in character list only for non-ghost character
@@ -151,7 +151,6 @@ EnumCharactersResult::CharacterInfo::CharacterInfo(Field const* fields)
}
}
- BoostInProgress = false;
ProfessionIds[0] = 0;
ProfessionIds[1] = 0;
@@ -180,80 +179,115 @@ EnumCharactersResult::CharacterInfo::CharacterInfo(Field const* fields)
}
}
-ByteBuffer& operator<<(ByteBuffer& data, EnumCharactersResult::CharacterInfo::VisualItemInfo const& visualItem)
+ByteBuffer& operator<<(ByteBuffer& data, EnumCharactersResult::CharacterInfoBasic::VisualItemInfo const& visualItem)
{
data << uint32(visualItem.DisplayID);
- data << uint32(visualItem.DisplayEnchantID);
- data << int32(visualItem.SecondaryItemModifiedAppearanceID);
data << uint8(visualItem.InvType);
+ data << uint32(visualItem.DisplayEnchantID);
data << uint8(visualItem.Subclass);
+ data << int32(visualItem.SecondaryItemModifiedAppearanceID);
+ data << uint32(visualItem.ItemID);
+ data << uint32(visualItem.TransmogrifiedItemID);
return data;
}
-ByteBuffer& operator<<(ByteBuffer& data, EnumCharactersResult::CharacterInfo const& charInfo)
+ByteBuffer& operator<<(ByteBuffer& data, EnumCharactersResult::CharacterInfoBasic const& charInfo)
{
- ASSERT(charInfo.MailSenders.size() == charInfo.MailSenderTypes.size());
-
data << charInfo.Guid;
- data << uint64(charInfo.GuildClubMemberID);
+ data << uint32(charInfo.VirtualRealmAddress);
data << uint8(charInfo.ListPosition);
data << uint8(charInfo.RaceID);
- data << uint8(charInfo.ClassID);
data << uint8(charInfo.SexID);
+ data << uint8(charInfo.ClassID);
+ data << int16(charInfo.SpecID);
data << uint32(charInfo.Customizations.size());
data << uint8(charInfo.ExperienceLevel);
- data << int32(charInfo.ZoneID);
data << int32(charInfo.MapID);
+ data << int32(charInfo.ZoneID);
data << charInfo.PreloadPos;
+ data << uint64(charInfo.GuildClubMemberID);
data << charInfo.GuildGUID;
data << uint32(charInfo.Flags);
data << uint32(charInfo.Flags2);
data << uint32(charInfo.Flags3);
+ data << uint8(charInfo.unkWod61x);
+
data << uint32(charInfo.PetCreatureDisplayID);
data << uint32(charInfo.PetExperienceLevel);
data << uint32(charInfo.PetCreatureFamilyID);
- data << uint32(charInfo.ProfessionIds[0]);
- data << uint32(charInfo.ProfessionIds[1]);
-
- for (EnumCharactersResult::CharacterInfo::VisualItemInfo const& visualItem : charInfo.VisualItems)
+ for (EnumCharactersResult::CharacterInfoBasic::VisualItemInfo const& visualItem : charInfo.VisualItems)
data << visualItem;
- data << charInfo.LastPlayedTime;
- data << int16(charInfo.SpecID);
data << int32(charInfo.Unknown703);
+ data << charInfo.LastPlayedTime;
data << int32(charInfo.LastLoginVersion);
- data << uint32(charInfo.Flags4);
- data << uint32(charInfo.MailSenders.size());
- data << uint32(charInfo.MailSenderTypes.size());
- data << uint32(charInfo.OverrideSelectScreenFileDataID);
data << charInfo.PersonalTabard;
+ data << uint32(charInfo.ProfessionIds[0]);
+ data << uint32(charInfo.ProfessionIds[1]);
+
+ data << int32(charInfo.TimerunningSeasonID);
+ data << uint32(charInfo.OverrideSelectScreenFileDataID);
+
for (ChrCustomizationChoice const& customization : charInfo.Customizations)
data << customization;
- if (!charInfo.MailSenderTypes.empty())
- data.append(charInfo.MailSenderTypes.data(), charInfo.MailSenderTypes.size());
-
data << BitsSize<6>(charInfo.Name);
data << Bits<1>(charInfo.FirstLogin);
- data << Bits<1>(charInfo.BoostInProgress);
- data << Bits<5>(charInfo.unkWod61x);
- data << Bits<2>(0); // unk
- data << Bits<1>(charInfo.RpeResetAvailable);
- data << Bits<1>(charInfo.RpeResetQuestClearAvailable);
- for (std::string const& str : charInfo.MailSenders)
+ data.FlushBits();
+
+ data.WriteString(charInfo.Name);
+
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, EnumCharactersResult::CharacterRestrictionAndMailData const& restrictionsAndMails)
+{
+ ASSERT(restrictionsAndMails.MailSenders.size() == restrictionsAndMails.MailSenderTypes.size());
+
+ data << Bits<1>(restrictionsAndMails.BoostInProgress);
+ data << Bits<1>(restrictionsAndMails.RpeResetAvailable);
+ data << Bits<1>(restrictionsAndMails.RpeResetQuestClearAvailable);
+ data.FlushBits();
+
+ data << uint32(restrictionsAndMails.Flags4);
+ data << uint32(restrictionsAndMails.MailSenders.size());
+ data << uint32(restrictionsAndMails.MailSenderTypes.size());
+
+ if (!restrictionsAndMails.MailSenderTypes.empty())
+ data.append(restrictionsAndMails.MailSenderTypes.data(), restrictionsAndMails.MailSenderTypes.size());
+
+ for (std::string const& str : restrictionsAndMails.MailSenders)
data << Bits<6>(str.length() + 1);
data.FlushBits();
- for (std::string const& str : charInfo.MailSenders)
+ for (std::string const& str : restrictionsAndMails.MailSenders)
if (!str.empty())
data << str;
- data.WriteString(charInfo.Name);
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, EnumCharactersResult::CharacterInfo const& charInfo)
+{
+ data << charInfo.Basic;
+ data << charInfo.RestrictionsAndMails;
+
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, EnumCharactersResult::RegionwideCharacterListEntry const& charInfo)
+{
+ data << charInfo.Basic;
+ data << uint64(charInfo.Money);
+ data << float(charInfo.CurrentSeasonMythicPlusOverallScore);
+ data << int32(charInfo.CurrentSeasonBestPvpRating);
+ data << int8(charInfo.PvpRatingBracket);
+ data << int16(charInfo.PvpRatingAssociatedSpecID);
return data;
}
@@ -265,6 +299,7 @@ ByteBuffer& operator<<(ByteBuffer& data, EnumCharactersResult::RaceUnlock const&
data << Bits<1>(raceUnlock.HasAchievement);
data << Bits<1>(raceUnlock.HasHeritageArmor);
data << Bits<1>(raceUnlock.IsLocked);
+ data << Bits<1>(raceUnlock.Unused1027);
data.FlushBits();
return data;
@@ -286,22 +321,57 @@ ByteBuffer& operator<<(ByteBuffer& data, EnumCharactersResult::RaceLimitDisableI
return data;
}
+ByteBuffer& operator<<(ByteBuffer& data, WarbandGroupMember const& warbandGroupMember)
+{
+ data << int32(warbandGroupMember.WarbandScenePlacementID);
+ data << int32(warbandGroupMember.Type);
+ if (warbandGroupMember.Type == 0)
+ data << warbandGroupMember.Guid;
+
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WarbandGroup const& warbandGroup)
+{
+ data << uint64(warbandGroup.GroupID);
+ data << uint8(warbandGroup.Unknown_1100);
+ data << int32(warbandGroup.Flags);
+ data << uint32(warbandGroup.Members.size());
+
+ for (WarbandGroupMember const& member : warbandGroup.Members)
+ data << member;
+
+ return data;
+}
+
+EnumCharactersResult::CharacterInfo::CharacterInfo(Field const* fields) : Basic(fields)
+{
+}
+
+EnumCharactersResult::RegionwideCharacterListEntry::RegionwideCharacterListEntry(Field const* fields) : Basic(fields)
+{
+}
+
WorldPacket const* EnumCharactersResult::Write()
{
_worldPacket.reserve(9 + Characters.size() * sizeof(CharacterInfo) + RaceUnlockData.size() * sizeof(RaceUnlock));
_worldPacket << Bits<1>(Success);
+ _worldPacket << Bits<1>(Realmless);
_worldPacket << Bits<1>(IsDeletedCharacters);
_worldPacket << Bits<1>(IsNewPlayerRestrictionSkipped);
_worldPacket << Bits<1>(IsNewPlayerRestricted);
_worldPacket << Bits<1>(IsNewPlayer);
_worldPacket << Bits<1>(IsTrialAccountRestricted);
_worldPacket << OptionalInit(DisabledClassesMask);
+ _worldPacket << Bits<1>(DontCreateCharacterDisplays);
_worldPacket << uint32(Characters.size());
+ _worldPacket << uint32(RegionwideCharacters.size());
_worldPacket << int32(MaxCharacterLevel);
_worldPacket << uint32(RaceUnlockData.size());
_worldPacket << uint32(UnlockedConditionalAppearances.size());
_worldPacket << uint32(RaceLimitDisables.size());
+ _worldPacket << uint32(WarbandGroups.size());
if (DisabledClassesMask)
_worldPacket << uint32(*DisabledClassesMask);
@@ -312,9 +382,15 @@ WorldPacket const* EnumCharactersResult::Write()
for (RaceLimitDisableInfo const& raceLimitDisableInfo : RaceLimitDisables)
_worldPacket << raceLimitDisableInfo;
+ for (WarbandGroup const& warbandGroup : WarbandGroups)
+ _worldPacket << warbandGroup;
+
for (CharacterInfo const& charInfo : Characters)
_worldPacket << charInfo;
+ for (RegionwideCharacterListEntry const& charInfo : RegionwideCharacters)
+ _worldPacket << charInfo;
+
for (RaceUnlock const& raceUnlock : RaceUnlockData)
_worldPacket << raceUnlock;
@@ -579,6 +655,7 @@ void AlterApperance::Read()
_worldPacket >> NewSex;
_worldPacket >> CustomizedRace;
_worldPacket >> CustomizedChrModelID;
+ _worldPacket >> UnalteredVisualRaceID;
for (ChrCustomizationChoice& customization : Customizations)
_worldPacket >> customization;
diff --git a/src/server/game/Server/Packets/CharacterPackets.h b/src/server/game/Server/Packets/CharacterPackets.h
index 312955cafae..deeb8314e06 100644
--- a/src/server/game/Server/Packets/CharacterPackets.h
+++ b/src/server/game/Server/Packets/CharacterPackets.h
@@ -114,10 +114,25 @@ namespace WorldPackets
int32 BackgroundColor = -1;
};
+ struct WarbandGroupMember
+ {
+ int32 WarbandScenePlacementID = 0;
+ int32 Type = 0;
+ ObjectGuid Guid;
+ };
+
+ struct WarbandGroup
+ {
+ uint64 GroupID = 0;
+ uint8 Unknown_1100 = 0;
+ int32 Flags = 0; ///< enum WarbandGroupFlags { Collapsed = 1 }
+ std::vector<WarbandGroupMember> Members;
+ };
+
class EnumCharactersResult final : public ServerPacket
{
public:
- struct CharacterInfo
+ struct CharacterInfoBasic
{
/**
* @fn void WorldPackets::Character::EnumCharactersResult::CharacterInfo::CharacterInfo(Field* fields);
@@ -126,9 +141,10 @@ namespace WorldPackets
*
* @param fields Field set of CharacterDatabaseStatements::CHAR_SEL_ENUM
*/
- CharacterInfo(Field const* fields);
+ CharacterInfoBasic(Field const* fields);
ObjectGuid Guid;
+ uint32 VirtualRealmAddress = 0;
uint64 GuildClubMemberID = 0; ///< same as bgs.protocol.club.v1.MemberId.unique_id, guessed basing on SMSG_QUERY_PLAYER_NAME_RESPONSE (that one is known)
std::string Name;
uint8 ListPosition = 0; ///< Order of the characters in list
@@ -144,7 +160,6 @@ namespace WorldPackets
uint32 Flags = 0; ///< Character flag @see enum CharacterFlags
uint32 Flags2 = 0; ///< Character customization flags @see enum CharacterCustomizeFlags
uint32 Flags3 = 0; ///< Character flags 3 @todo research
- uint32 Flags4 = 0;
bool FirstLogin = false;
uint8 unkWod61x = 0;
Timestamp<> LastPlayedTime;
@@ -152,29 +167,57 @@ namespace WorldPackets
uint32 Unknown703 = 0;
uint32 LastLoginVersion = 0;
uint32 OverrideSelectScreenFileDataID = 0;
+ int32 TimerunningSeasonID = 0;
uint32 PetCreatureDisplayID = 0;
uint32 PetExperienceLevel = 0;
uint32 PetCreatureFamilyID = 0;
- bool BoostInProgress = false; ///< @todo
int32 ProfessionIds[2] = { }; ///< @todo
struct VisualItemInfo
{
- uint32 DisplayID = 0;
+ uint32 DisplayID = 0;
uint32 DisplayEnchantID = 0;
int32 SecondaryItemModifiedAppearanceID = 0; // also -1 is some special value
- uint8 InvType = 0;
- uint8 Subclass = 0;
+ uint8 InvType = 0;
+ uint8 Subclass = 0;
+ uint32 ItemID = 0;
+ uint32 TransmogrifiedItemID = 0;
};
- std::array<VisualItemInfo, 34> VisualItems = { };
+ std::array<VisualItemInfo, 19> VisualItems = { };
+ CustomTabardInfo PersonalTabard;
+ };
+
+ struct CharacterRestrictionAndMailData
+ {
+ bool BoostInProgress = false; ///< @todo
+ uint32 Flags4 = 0;
std::vector<std::string> MailSenders;
std::vector<uint32> MailSenderTypes;
bool RpeResetAvailable = false;
bool RpeResetQuestClearAvailable = false;
- CustomTabardInfo PersonalTabard;
+ };
+
+ struct CharacterInfo
+ {
+ CharacterInfo(Field const* fields);
+
+ CharacterInfoBasic Basic;
+ CharacterRestrictionAndMailData RestrictionsAndMails;
+ };
+
+ struct RegionwideCharacterListEntry
+ {
+ RegionwideCharacterListEntry(Field const* fields);
+
+ CharacterInfoBasic Basic;
+ uint64 Money = 0;
+ float CurrentSeasonMythicPlusOverallScore = 0.0f;
+ uint32 CurrentSeasonBestPvpRating = 0;
+ int8 PvpRatingBracket = 0;
+ int16 PvpRatingAssociatedSpecID = 0;
};
struct RaceUnlock
@@ -184,6 +227,7 @@ namespace WorldPackets
bool HasAchievement = false;
bool HasHeritageArmor = false;
bool IsLocked = false;
+ bool Unused1027 = false;
};
struct UnlockedConditionalAppearance
@@ -208,20 +252,24 @@ namespace WorldPackets
WorldPacket const* Write() override;
- bool Success = false; ///<
+ bool Success = false;
+ bool Realmless = false;
bool IsDeletedCharacters = false; ///< used for character undelete list
bool IsNewPlayerRestrictionSkipped = false; ///< allows client to skip new player restrictions
bool IsNewPlayerRestricted = false; ///< forbids using level boost and class trials
bool IsNewPlayer = false; ///< forbids hero classes and allied races
bool IsTrialAccountRestricted = false;
+ bool DontCreateCharacterDisplays = false;
int32 MaxCharacterLevel = 1;
Optional<uint32> DisabledClassesMask;
std::vector<CharacterInfo> Characters; ///< all characters on the list
- std::vector<RaceUnlock> RaceUnlockData; ///<
+ std::vector<RegionwideCharacterListEntry> RegionwideCharacters;
+ std::vector<RaceUnlock> RaceUnlockData;
std::vector<UnlockedConditionalAppearance> UnlockedConditionalAppearances;
std::vector<RaceLimitDisableInfo> RaceLimitDisables;
+ std::vector<WarbandGroup> WarbandGroups;
};
class CheckCharacterNameAvailabilityResult final : public ServerPacket
@@ -641,6 +689,7 @@ namespace WorldPackets
Array<ChrCustomizationChoice, 250> Customizations;
int32 CustomizedRace = 0;
int32 CustomizedChrModelID = 0;
+ int32 UnalteredVisualRaceID = 0;
};
class BarberShopResult final : public ServerPacket
diff --git a/src/server/game/Server/Packets/ChatPackets.cpp b/src/server/game/Server/Packets/ChatPackets.cpp
index 64fc9765539..75029adc9e5 100644
--- a/src/server/game/Server/Packets/ChatPackets.cpp
+++ b/src/server/game/Server/Packets/ChatPackets.cpp
@@ -47,7 +47,7 @@ void WorldPackets::Chat::ChatMessageWhisper::Read()
_worldPacket >> TargetGUID;
_worldPacket >> TargetVirtualRealmAddress;
- uint32 targetLen = _worldPacket.ReadBits(6);
+ uint32 targetLen = _worldPacket.ReadBits(7);
uint32 textLen = _worldPacket.ReadBits(11);
if (targetLen > 1)
@@ -100,8 +100,8 @@ void WorldPackets::Chat::ChatAddonMessageTargeted::Read()
_worldPacket >> PlayerGUID;
_worldPacket >> PlayerVirtualRealmAddress;
- uint32 playerNameLength = _worldPacket.ReadBits(6);
- uint32 channelNameLength = _worldPacket.ReadBits(6);
+ uint32 playerNameLength = _worldPacket.ReadBits(7);
+ uint32 channelNameLength = _worldPacket.ReadBits(7);
if (playerNameLength > 1)
{
@@ -208,6 +208,7 @@ WorldPacket const* WorldPackets::Chat::Chat::Write()
_worldPacket << uint32(TargetVirtualAddress);
_worldPacket << uint32(SenderVirtualAddress);
_worldPacket << int32(AchievementID);
+ _worldPacket << uint16(_ChatFlags);
_worldPacket << float(DisplayTime);
_worldPacket << int32(SpellID);
_worldPacket.WriteBits(SenderName.length(), 11);
@@ -215,7 +216,6 @@ WorldPacket const* WorldPackets::Chat::Chat::Write()
_worldPacket.WriteBits(Prefix.length(), 5);
_worldPacket.WriteBits(_Channel.length(), 7);
_worldPacket.WriteBits(ChatText.length(), 12);
- _worldPacket.WriteBits(_ChatFlags, 15);
_worldPacket.WriteBit(HideChatLog);
_worldPacket.WriteBit(FakeSenderName);
_worldPacket.WriteBit(Unused_801.has_value());
diff --git a/src/server/game/Server/Packets/CombatLogPackets.cpp b/src/server/game/Server/Packets/CombatLogPackets.cpp
index 934b4c80000..83fad7d24be 100644
--- a/src/server/game/Server/Packets/CombatLogPackets.cpp
+++ b/src/server/game/Server/Packets/CombatLogPackets.cpp
@@ -102,7 +102,7 @@ WorldPacket const* SpellExecuteLog::Write()
{
*this << powerDrainTarget.Victim;
*this << uint32(powerDrainTarget.Points);
- *this << uint32(powerDrainTarget.PowerType);
+ *this << int8(powerDrainTarget.PowerType);
*this << float(powerDrainTarget.Amplitude);
}
}
diff --git a/src/server/game/Server/Packets/CombatLogPacketsCommon.cpp b/src/server/game/Server/Packets/CombatLogPacketsCommon.cpp
index 0ac7591c034..9a2519dc1b4 100644
--- a/src/server/game/Server/Packets/CombatLogPacketsCommon.cpp
+++ b/src/server/game/Server/Packets/CombatLogPacketsCommon.cpp
@@ -48,13 +48,13 @@ void SpellCastLogData::Initialize(Spell const* spell)
bool primaryPowerAdded = false;
for (SpellPowerCost const& cost : spell->GetPowerCost())
{
- PowerData.emplace_back(int32(cost.Power), unitCaster->GetPower(Powers(cost.Power)), int32(cost.Amount));
+ PowerData.emplace_back(int8(cost.Power), unitCaster->GetPower(Powers(cost.Power)), int32(cost.Amount));
if (cost.Power == primaryPowerType)
primaryPowerAdded = true;
}
if (!primaryPowerAdded)
- PowerData.emplace(PowerData.begin(), int32(primaryPowerType), unitCaster->GetPower(primaryPowerType), 0);
+ PowerData.emplace(PowerData.begin(), int8(primaryPowerType), unitCaster->GetPower(primaryPowerType), 0);
}
}
@@ -135,7 +135,7 @@ ByteBuffer& operator<<(ByteBuffer& data, SpellCastLogData const& spellCastLogDat
for (SpellLogPowerData const& powerData : spellCastLogData.PowerData)
{
- data << int32(powerData.PowerType);
+ data << int8(powerData.PowerType);
data << int32(powerData.Amount);
data << int32(powerData.Cost);
}
diff --git a/src/server/game/Server/Packets/CombatLogPacketsCommon.h b/src/server/game/Server/Packets/CombatLogPacketsCommon.h
index 8165e7bab35..8589b07d2da 100644
--- a/src/server/game/Server/Packets/CombatLogPacketsCommon.h
+++ b/src/server/game/Server/Packets/CombatLogPacketsCommon.h
@@ -30,9 +30,9 @@ namespace WorldPackets
{
struct SpellLogPowerData
{
- SpellLogPowerData(int32 powerType, int32 amount, int32 cost) : PowerType(powerType), Amount(amount), Cost(cost) { }
+ SpellLogPowerData(int8 powerType, int32 amount, int32 cost) : PowerType(powerType), Amount(amount), Cost(cost) { }
- int32 PowerType = 0;
+ int8 PowerType = 0;
int32 Amount = 0;
int32 Cost = 0;
};
diff --git a/src/server/game/Server/Packets/CombatPackets.cpp b/src/server/game/Server/Packets/CombatPackets.cpp
index 33dd2c9a64a..51de6ecde50 100644
--- a/src/server/game/Server/Packets/CombatPackets.cpp
+++ b/src/server/game/Server/Packets/CombatPackets.cpp
@@ -107,8 +107,8 @@ WorldPacket const* WorldPackets::Combat::PowerUpdate::Write()
_worldPacket << uint32(Powers.size());
for (PowerUpdatePower const& power : Powers)
{
- _worldPacket << int32(power.Power);
_worldPacket << uint8(power.PowerType);
+ _worldPacket << int32(power.Power);
}
return &_worldPacket;
@@ -116,7 +116,7 @@ WorldPacket const* WorldPackets::Combat::PowerUpdate::Write()
WorldPacket const* WorldPackets::Combat::InterruptPowerRegen::Write()
{
- _worldPacket << int32(PowerType);
+ _worldPacket << int8(PowerType);
return &_worldPacket;
}
diff --git a/src/server/game/Server/Packets/CombatPackets.h b/src/server/game/Server/Packets/CombatPackets.h
index 27dc7ec44ad..42424d8f18b 100644
--- a/src/server/game/Server/Packets/CombatPackets.h
+++ b/src/server/game/Server/Packets/CombatPackets.h
@@ -163,7 +163,7 @@ namespace WorldPackets
class InterruptPowerRegen final : public ServerPacket
{
public:
- explicit InterruptPowerRegen(Powers powerType) : ServerPacket(SMSG_INTERRUPT_POWER_REGEN, 4), PowerType(powerType) { }
+ explicit InterruptPowerRegen(Powers powerType) : ServerPacket(SMSG_INTERRUPT_POWER_REGEN, 1), PowerType(powerType) { }
WorldPacket const* Write() override;
diff --git a/src/server/game/Server/Packets/CraftingPacketsCommon.cpp b/src/server/game/Server/Packets/CraftingPacketsCommon.cpp
index d5518dda79e..ee03eedbb75 100644
--- a/src/server/game/Server/Packets/CraftingPacketsCommon.cpp
+++ b/src/server/game/Server/Packets/CraftingPacketsCommon.cpp
@@ -44,6 +44,9 @@ ByteBuffer& operator<<(ByteBuffer& data, CraftingData const& craftingData)
data << craftingData.ItemGUID;
data << int32(craftingData.Quantity);
data << int32(craftingData.EnchantID);
+ data << int32(craftingData.ConcentrationCurrencyID);
+ data << int32(craftingData.ConcentrationSpent);
+ data << int32(craftingData.IngenuityRefund);
for (SpellReducedReagent const& spellReducedReagent : craftingData.ResourcesReturned)
data << spellReducedReagent;
@@ -52,6 +55,8 @@ ByteBuffer& operator<<(ByteBuffer& data, CraftingData const& craftingData)
data << Bits<1>(craftingData.field_29);
data << Bits<1>(craftingData.field_2A);
data << Bits<1>(craftingData.BonusCraft);
+ data << Bits<1>(craftingData.HasIngenuityProc);
+ data << Bits<1>(craftingData.ApplyConcentration);
data.FlushBits();
data << craftingData.OldItem;
diff --git a/src/server/game/Server/Packets/CraftingPacketsCommon.h b/src/server/game/Server/Packets/CraftingPacketsCommon.h
index 9426662d460..2182a28627b 100644
--- a/src/server/game/Server/Packets/CraftingPacketsCommon.h
+++ b/src/server/game/Server/Packets/CraftingPacketsCommon.h
@@ -52,6 +52,11 @@ struct CraftingData
Item::ItemInstance OldItem;
Item::ItemInstance NewItem;
int32 EnchantID = 0;
+ int32 ConcentrationCurrencyID = 0;
+ int32 ConcentrationSpent = 0;
+ int32 IngenuityRefund = 0;
+ bool HasIngenuityProc = false;
+ bool ApplyConcentration = false;
};
ByteBuffer& operator<<(ByteBuffer& data, SpellReducedReagent const& spellReducedReagent);
diff --git a/src/server/game/Server/Packets/EquipmentSetPackets.cpp b/src/server/game/Server/Packets/EquipmentSetPackets.cpp
index 7d7fa640b9a..f8423393343 100644
--- a/src/server/game/Server/Packets/EquipmentSetPackets.cpp
+++ b/src/server/game/Server/Packets/EquipmentSetPackets.cpp
@@ -19,9 +19,9 @@
WorldPacket const* WorldPackets::EquipmentSet::EquipmentSetID::Write()
{
- _worldPacket << uint64(GUID);
_worldPacket << int32(Type);
_worldPacket << uint32(SetID);
+ _worldPacket << uint64(GUID);
return &_worldPacket;
}
@@ -119,8 +119,8 @@ void WorldPackets::EquipmentSet::UseEquipmentSet::Read()
WorldPacket const* WorldPackets::EquipmentSet::UseEquipmentSetResult::Write()
{
+ _worldPacket << int32(Reason);
_worldPacket << uint64(GUID);
- _worldPacket << uint8(Reason);
return &_worldPacket;
}
diff --git a/src/server/game/Server/Packets/EquipmentSetPackets.h b/src/server/game/Server/Packets/EquipmentSetPackets.h
index a36c95829e0..ed4165b4236 100644
--- a/src/server/game/Server/Packets/EquipmentSetPackets.h
+++ b/src/server/game/Server/Packets/EquipmentSetPackets.h
@@ -94,7 +94,7 @@ namespace WorldPackets
WorldPacket const* Write() override;
uint64 GUID = 0; ///< Set Identifier
- uint8 Reason = 0;
+ int32 Reason = 0;
};
}
}
diff --git a/src/server/game/Server/Packets/GuildPackets.cpp b/src/server/game/Server/Packets/GuildPackets.cpp
index c8166747dbe..f6c75915527 100644
--- a/src/server/game/Server/Packets/GuildPackets.cpp
+++ b/src/server/game/Server/Packets/GuildPackets.cpp
@@ -99,6 +99,17 @@ WorldPacket const* WorldPackets::Guild::GuildCommandResult::Write()
return &_worldPacket;
}
+void WorldPackets::Guild::AcceptGuildInvite::Read()
+{
+ _worldPacket >> GuildGuid;
+}
+
+void WorldPackets::Guild::GuildDeclineInvitation::Read()
+{
+ _worldPacket >> GuildGuid;
+ _worldPacket >> Bits<1>(IsAuto);
+}
+
void WorldPackets::Guild::DeclineGuildInvites::Read()
{
Allow = _worldPacket.ReadBit();
@@ -204,7 +215,6 @@ WorldPacket const* WorldPackets::Guild::GuildEventPresenceChange::Write()
_worldPacket.WriteBits(Name.length(), 6);
_worldPacket.WriteBit(LoggedOn);
- _worldPacket.WriteBit(Mobile);
_worldPacket.FlushBits();
_worldPacket.WriteString(Name);
diff --git a/src/server/game/Server/Packets/GuildPackets.h b/src/server/game/Server/Packets/GuildPackets.h
index 035c9304bd2..2ca2fdbc202 100644
--- a/src/server/game/Server/Packets/GuildPackets.h
+++ b/src/server/game/Server/Packets/GuildPackets.h
@@ -163,7 +163,9 @@ namespace WorldPackets
public:
AcceptGuildInvite(WorldPacket&& packet) : ClientPacket(CMSG_ACCEPT_GUILD_INVITE, std::move(packet)) { }
- void Read() override { }
+ void Read() override;
+
+ ObjectGuid GuildGuid;
};
class GuildDeclineInvitation final : public ClientPacket
@@ -171,7 +173,10 @@ namespace WorldPackets
public:
GuildDeclineInvitation(WorldPacket&& packet) : ClientPacket(CMSG_GUILD_DECLINE_INVITATION, std::move(packet)) { }
- void Read() override { }
+ void Read() override;
+
+ ObjectGuid GuildGuid;
+ bool IsAuto = false;
};
class DeclineGuildInvites final : public ClientPacket
@@ -240,7 +245,6 @@ namespace WorldPackets
ObjectGuid Guid;
uint32 VirtualRealmAddress = 0;
std::string Name;
- bool Mobile = false;
bool LoggedOn = false;
};
diff --git a/src/server/game/Server/Packets/InstancePackets.cpp b/src/server/game/Server/Packets/InstancePackets.cpp
index 41e73128573..86caa86b6ee 100644
--- a/src/server/game/Server/Packets/InstancePackets.cpp
+++ b/src/server/game/Server/Packets/InstancePackets.cpp
@@ -108,9 +108,11 @@ WorldPacket const* WorldPackets::Instance::PendingRaidLock::Write()
WorldPacket const* WorldPackets::Instance::RaidInstanceMessage::Write()
{
- _worldPacket << uint8(Type);
+ _worldPacket << int32(Type);
_worldPacket << uint32(MapID);
_worldPacket << uint32(DifficultyID);
+ _worldPacket << int32(TimeLeft);
+ _worldPacket << BitsSize<8>(WarningMessage);
_worldPacket << Bits<1>(Locked);
_worldPacket << Bits<1>(Extended);
_worldPacket.FlushBits();
diff --git a/src/server/game/Server/Packets/InstancePackets.h b/src/server/game/Server/Packets/InstancePackets.h
index 86f6838946f..ab980ca148f 100644
--- a/src/server/game/Server/Packets/InstancePackets.h
+++ b/src/server/game/Server/Packets/InstancePackets.h
@@ -157,9 +157,11 @@ namespace WorldPackets
WorldPacket const* Write() override;
- uint8 Type = 0;
+ int32 Type = 0;
uint32 MapID = 0;
uint32 DifficultyID = 0;
+ int32 TimeLeft = 0;
+ std::string_view WarningMessage; // GlobalStrings tag
bool Locked = false;
bool Extended = false;
};
diff --git a/src/server/game/Server/Packets/ItemPackets.cpp b/src/server/game/Server/Packets/ItemPackets.cpp
index fd07ebf5a0c..58cdac4959f 100644
--- a/src/server/game/Server/Packets/ItemPackets.cpp
+++ b/src/server/game/Server/Packets/ItemPackets.cpp
@@ -257,7 +257,7 @@ WorldPacket const* WorldPackets::Item::ItemPushResult::Write()
_worldPacket << int32(DungeonEncounterID);
_worldPacket << int32(BattlePetSpeciesID);
_worldPacket << int32(BattlePetBreedID);
- _worldPacket << uint32(BattlePetBreedQuality);
+ _worldPacket << uint8(BattlePetBreedQuality);
_worldPacket << int32(BattlePetLevel);
_worldPacket << ItemGUID;
diff --git a/src/server/game/Server/Packets/ItemPackets.h b/src/server/game/Server/Packets/ItemPackets.h
index 093db816652..040b6746ed6 100644
--- a/src/server/game/Server/Packets/ItemPackets.h
+++ b/src/server/game/Server/Packets/ItemPackets.h
@@ -349,7 +349,7 @@ namespace WorldPackets
int32 DungeonEncounterID = 0;
int32 BattlePetSpeciesID = 0;
int32 BattlePetBreedID = 0;
- uint32 BattlePetBreedQuality = 0;
+ uint8 BattlePetBreedQuality = 0;
int32 BattlePetLevel = 0;
ObjectGuid ItemGUID;
bool Pushed = false;
diff --git a/src/server/game/Server/Packets/ItemPacketsCommon.cpp b/src/server/game/Server/Packets/ItemPacketsCommon.cpp
index 63843747a63..961b387f8fd 100644
--- a/src/server/game/Server/Packets/ItemPacketsCommon.cpp
+++ b/src/server/game/Server/Packets/ItemPacketsCommon.cpp
@@ -160,16 +160,16 @@ ByteBuffer& operator>>(ByteBuffer& data, ItemBonuses& itemBonusInstanceData)
ByteBuffer& operator<<(ByteBuffer& data, ItemMod const& itemMod)
{
- data << int32(itemMod.Value);
data << uint8(itemMod.Type);
+ data << int32(itemMod.Value);
return data;
}
ByteBuffer& operator>>(ByteBuffer& data, ItemMod& itemMod)
{
- data >> itemMod.Value;
data >> As<uint8>(itemMod.Type);
+ data >> itemMod.Value;
return data;
}
diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp
index 3105c46b6f9..ef05b6ebe08 100644
--- a/src/server/game/Server/Packets/MovementPackets.cpp
+++ b/src/server/game/Server/Packets/MovementPackets.cpp
@@ -681,6 +681,7 @@ WorldPacket const* WorldPackets::Movement::NewWorld::Write()
_worldPacket << Loc;
_worldPacket << uint32(Reason);
_worldPacket << MovementOffset;
+ _worldPacket << int32(Counter);
return &_worldPacket;
}
diff --git a/src/server/game/Server/Packets/MovementPackets.h b/src/server/game/Server/Packets/MovementPackets.h
index 51a0c4c002a..1ed4e1d70d5 100644
--- a/src/server/game/Server/Packets/MovementPackets.h
+++ b/src/server/game/Server/Packets/MovementPackets.h
@@ -270,6 +270,7 @@ namespace WorldPackets
uint32 Reason = 0;
TeleportLocation Loc;
TaggedPosition<Position::XYZ> MovementOffset; // Adjusts all pending movement events by this offset
+ int32 Counter = 0;
};
class WorldPortResponse final : public ClientPacket
diff --git a/src/server/game/Server/Packets/NPCPackets.cpp b/src/server/game/Server/Packets/NPCPackets.cpp
index ca1213cadd2..390fd319753 100644
--- a/src/server/game/Server/Packets/NPCPackets.cpp
+++ b/src/server/game/Server/Packets/NPCPackets.cpp
@@ -24,6 +24,7 @@ ByteBuffer& operator<<(ByteBuffer& data, TreasureItem const& treasureItem)
data << Bits<1>(treasureItem.Type);
data << int32(treasureItem.ID);
data << int32(treasureItem.Quantity);
+ data << int8(treasureItem.ItemContext);
return data;
}
@@ -51,6 +52,7 @@ ByteBuffer& operator<<(ByteBuffer& data, ClientGossipOptions const& gossipOption
data << Bits<2>(gossipOption.Status);
data << OptionalInit(gossipOption.SpellID);
data << OptionalInit(gossipOption.OverrideIconID);
+ data << Bits<8>(gossipOption.FailureDescription.length() + 1);
data.FlushBits();
data << gossipOption.Treasure;
@@ -64,6 +66,9 @@ ByteBuffer& operator<<(ByteBuffer& data, ClientGossipOptions const& gossipOption
if (gossipOption.OverrideIconID)
data << int32(*gossipOption.OverrideIconID);
+ if (!gossipOption.FailureDescription.empty())
+ data << gossipOption.FailureDescription;
+
return data;
}
@@ -74,11 +79,15 @@ ByteBuffer& operator<<(ByteBuffer& data, ClientGossipText const& gossipText)
data << int32(gossipText.QuestType);
data << int32(gossipText.QuestLevel);
data << int32(gossipText.QuestMaxScalingLevel);
+ data << int32(gossipText.Unused1102);
data << int32(gossipText.QuestFlags[0]);
data << int32(gossipText.QuestFlags[1]);
+ data << int32(gossipText.QuestFlags[2]);
data << Bits<1>(gossipText.Repeatable);
+ data << Bits<1>(gossipText.ResetByScheduler);
data << Bits<1>(gossipText.Important);
+ data << Bits<1>(gossipText.Meta);
data << BitsSize<9>(gossipText.QuestTitle);
data.FlushBits();
@@ -106,6 +115,7 @@ WorldPacket const* GossipMessage::Write()
{
_worldPacket << GossipGUID;
_worldPacket << int32(GossipID);
+ _worldPacket << int32(LfgDungeonsID);
_worldPacket << int32(FriendshipFactionID);
_worldPacket << uint32(GossipOptions.size());
_worldPacket << uint32(GossipText.size());
diff --git a/src/server/game/Server/Packets/NPCPackets.h b/src/server/game/Server/Packets/NPCPackets.h
index 8b398f72f87..526f1c1432c 100644
--- a/src/server/game/Server/Packets/NPCPackets.h
+++ b/src/server/game/Server/Packets/NPCPackets.h
@@ -34,7 +34,6 @@ namespace WorldPackets
{
namespace NPC
{
- // CMSG_BANKER_ACTIVATE
// CMSG_BINDER_ACTIVATE
// CMSG_BINDER_CONFIRM
// CMSG_GOSSIP_HELLO
@@ -68,6 +67,7 @@ namespace WorldPackets
GossipOptionRewardType Type = GossipOptionRewardType(0);
int32 ID = 0;
int32 Quantity = 0;
+ int8 ItemContext = 0;
};
struct TreasureLootList
@@ -90,6 +90,7 @@ namespace WorldPackets
TreasureLootList Treasure;
Optional<int32> SpellID;
Optional<int32> OverrideIconID;
+ std::string FailureDescription;
};
struct ClientGossipText
@@ -97,12 +98,15 @@ namespace WorldPackets
int32 QuestID = 0;
int32 ContentTuningID = 0;
int32 QuestType = 0;
+ int32 Unused1102 = 0;
int32 QuestLevel = 0;
int32 QuestMaxScalingLevel = 0;
bool Repeatable = false;
+ bool ResetByScheduler = false;
bool Important = false;
+ bool Meta = false;
std::string QuestTitle;
- std::array<int32, 2> QuestFlags = { };
+ std::array<int32, 3> QuestFlags = { };
};
ByteBuffer& operator<<(ByteBuffer& data, ClientGossipText const& gossipText);
@@ -121,6 +125,7 @@ namespace WorldPackets
Optional<int32> TextID; // in classic variants this still holds npc_text id
Optional<int32> BroadcastTextID;
int32 GossipID = 0;
+ int32 LfgDungeonsID = 0;
};
class GossipSelectOption final : public ClientPacket
diff --git a/src/server/game/Server/Packets/PartyPackets.cpp b/src/server/game/Server/Packets/PartyPackets.cpp
index 7a015e4bdae..25393445918 100644
--- a/src/server/game/Server/Packets/PartyPackets.cpp
+++ b/src/server/game/Server/Packets/PartyPackets.cpp
@@ -507,6 +507,7 @@ WorldPacket const* WorldPackets::Party::PartyUpdate::Write()
_worldPacket << uint32(SequenceNum);
_worldPacket << LeaderGUID;
_worldPacket << uint8(LeaderFactionGroup);
+ _worldPacket << int32(PingRestriction);
_worldPacket << uint32(PlayerList.size());
_worldPacket.WriteBit(LfgInfos.has_value());
_worldPacket.WriteBit(LootSettings.has_value());
diff --git a/src/server/game/Server/Packets/PartyPackets.h b/src/server/game/Server/Packets/PartyPackets.h
index f450f25ee90..986fcbde694 100644
--- a/src/server/game/Server/Packets/PartyPackets.h
+++ b/src/server/game/Server/Packets/PartyPackets.h
@@ -560,6 +560,8 @@ namespace WorldPackets
int32 MyIndex = 0;
int32 SequenceNum = 0;
+ RestrictPingsTo PingRestriction = RestrictPingsTo::None;
+
std::vector<PartyPlayerInfo> PlayerList;
Optional<PartyLFGInfo> LfgInfos;
diff --git a/src/server/game/Server/Packets/QueryPackets.cpp b/src/server/game/Server/Packets/QueryPackets.cpp
index fd124ea5095..afd92df1306 100644
--- a/src/server/game/Server/Packets/QueryPackets.cpp
+++ b/src/server/game/Server/Packets/QueryPackets.cpp
@@ -153,21 +153,6 @@ void QueryPlayerNames::Read()
_worldPacket >> player;
}
-ByteBuffer& operator<<(ByteBuffer& data, PlayerGuidLookupHint const& lookupHint)
-{
- data.WriteBit(lookupHint.VirtualRealmAddress.has_value());
- data.WriteBit(lookupHint.NativeRealmAddress.has_value());
- data.FlushBits();
-
- if (lookupHint.VirtualRealmAddress)
- data << uint32(*lookupHint.VirtualRealmAddress);
-
- if (lookupHint.NativeRealmAddress)
- data << uint32(*lookupHint.NativeRealmAddress);
-
- return data;
-}
-
bool PlayerGuidLookupData::Initialize(ObjectGuid const& guid, Player const* player /*= nullptr*/)
{
CharacterCacheEntry const* characterInfo = sCharacterCache->GetCharacterCacheByGuid(guid);
@@ -185,6 +170,7 @@ bool PlayerGuidLookupData::Initialize(ObjectGuid const& guid, Player const* play
Sex = player->GetNativeGender();
ClassID = player->GetClass();
Level = player->GetLevel();
+ TimerunningSeasonID = 0; // player->m_activePlayerData->TimerunningSeasonID;
if (UF::DeclinedNames const* names = player->GetDeclinedNames())
DeclinedNames = *names;
@@ -232,6 +218,7 @@ ByteBuffer& operator<<(ByteBuffer& data, PlayerGuidLookupData const& lookupData)
data << uint8(lookupData.ClassID);
data << uint8(lookupData.Level);
data << uint8(lookupData.Unused915);
+ data << int32(lookupData.TimerunningSeasonID);
data.WriteString(lookupData.Name);
return data;
@@ -391,9 +378,9 @@ WorldPacket const* CorpseLocation::Write()
_worldPacket << Player;
_worldPacket << ActualMapID;
- _worldPacket << Position;
_worldPacket << MapID;
_worldPacket << Transport;
+ _worldPacket << Position;
return &_worldPacket;
}
diff --git a/src/server/game/Server/Packets/QueryPackets.h b/src/server/game/Server/Packets/QueryPackets.h
index ea286d6ea9b..726791ebdf8 100644
--- a/src/server/game/Server/Packets/QueryPackets.h
+++ b/src/server/game/Server/Packets/QueryPackets.h
@@ -101,12 +101,6 @@ namespace WorldPackets
uint32 CreatureID = 0;
};
- struct PlayerGuidLookupHint
- {
- Optional<uint32> VirtualRealmAddress; ///< current realm (?) (identifier made from the Index, BattleGroup and Region)
- Optional<uint32> NativeRealmAddress; ///< original realm (?) (identifier made from the Index, BattleGroup and Region)
- };
-
class QueryPlayerNames final : public ClientPacket
{
public:
@@ -133,6 +127,7 @@ namespace WorldPackets
uint8 ClassID = CLASS_NONE;
uint8 Level = 0;
uint8 Unused915 = 0;
+ int32 TimerunningSeasonID = 0;
DeclinedName DeclinedNames;
};
@@ -443,7 +438,6 @@ namespace WorldPackets
WorldPackets::Auth::VirtualRealmNameInfo NameInfo;
};
- ByteBuffer& operator<<(ByteBuffer& data, PlayerGuidLookupHint const& lookupHint);
ByteBuffer& operator<<(ByteBuffer& data, PlayerGuidLookupData const& lookupData);
}
}
diff --git a/src/server/game/Server/Packets/QuestPackets.cpp b/src/server/game/Server/Packets/QuestPackets.cpp
index c000257862c..1b5878981cb 100644
--- a/src/server/game/Server/Packets/QuestPackets.cpp
+++ b/src/server/game/Server/Packets/QuestPackets.cpp
@@ -185,12 +185,19 @@ WorldPacket const* QueryQuestInfoResponse::Write()
_worldPacket << uint32(Info.Objectives.size());
_worldPacket << uint64(Info.AllowableRaces.RawValue);
- _worldPacket << int32(Info.TreasurePickerID);
+ _worldPacket << uint32(Info.TreasurePickerID.size());
+ _worldPacket << uint32(Info.TreasurePickerID2.size());
_worldPacket << int32(Info.Expansion);
_worldPacket << int32(Info.ManagedWorldStateID);
_worldPacket << int32(Info.QuestSessionBonus);
_worldPacket << int32(Info.QuestGiverCreatureID);
+ if (!Info.TreasurePickerID.empty())
+ _worldPacket.append(Info.TreasurePickerID.data(), Info.TreasurePickerID.size());
+
+ if (!Info.TreasurePickerID2.empty())
+ _worldPacket.append(Info.TreasurePickerID2.data(), Info.TreasurePickerID2.size());
+
_worldPacket << BitsSize<9>(Info.LogTitle);
_worldPacket << BitsSize<12>(Info.LogDescription);
_worldPacket << BitsSize<12>(Info.QuestDescription);
@@ -206,7 +213,7 @@ WorldPacket const* QueryQuestInfoResponse::Write()
for (QuestObjective const& questObjective : Info.Objectives)
{
_worldPacket << uint32(questObjective.ID);
- _worldPacket << uint8(questObjective.Type);
+ _worldPacket << int32(questObjective.Type);
_worldPacket << int8(questObjective.StorageIndex);
_worldPacket << int32(questObjective.ObjectID);
_worldPacket << int32(questObjective.Amount);
@@ -267,6 +274,14 @@ WorldPacket const* QuestUpdateAddPvPCredit::Write()
return &_worldPacket;
}
+ByteBuffer& operator<<(ByteBuffer& data, QuestRewardItem const& questRewardItem)
+{
+ data << int32(questRewardItem.ItemID);
+ data << int32(questRewardItem.ItemQty);
+
+ return data;
+}
+
ByteBuffer& operator<<(ByteBuffer& data, QuestChoiceItem const& questChoiceItem)
{
data << Bits<2>(questChoiceItem.LootItemType);
@@ -286,17 +301,25 @@ ByteBuffer& operator>>(ByteBuffer& data, QuestChoiceItem& questChoiceItem)
return data;
}
+ByteBuffer& operator<<(ByteBuffer& data, QuestRewardCurrency const& questRewardCurrency)
+{
+ data << int32(questRewardCurrency.CurrencyID);
+ data << int32(questRewardCurrency.CurrencyQty);
+ data << int32(questRewardCurrency.BonusQty);
+
+ return data;
+}
+
ByteBuffer& operator<<(ByteBuffer& data, QuestRewards const& questRewards)
{
- data << int32(questRewards.ChoiceItemCount);
- data << int32(questRewards.ItemCount);
+ for (QuestRewardItem const& item : questRewards.Items)
+ data << item;
- for (uint32 i = 0; i < QUEST_REWARD_ITEM_COUNT; ++i)
- {
- data << int32(questRewards.ItemID[i]);
- data << int32(questRewards.ItemQty[i]);
- }
+ for (QuestRewardCurrency const& currency : questRewards.Currencies)
+ data << currency;
+ data << int32(questRewards.ChoiceItemCount);
+ data << int32(questRewards.ItemCount);
data << int32(questRewards.Money);
data << int32(questRewards.XP);
data << int64(questRewards.ArtifactXP);
@@ -316,16 +339,11 @@ ByteBuffer& operator<<(ByteBuffer& data, QuestRewards const& questRewards)
data.append(questRewards.SpellCompletionDisplayID.data(), questRewards.SpellCompletionDisplayID.size());
data << int32(questRewards.SpellCompletionID);
-
- for (uint32 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
- {
- data << int32(questRewards.CurrencyID[i]);
- data << int32(questRewards.CurrencyQty[i]);
- }
-
data << int32(questRewards.SkillLineID);
data << int32(questRewards.NumSkillUps);
- data << int32(questRewards.TreasurePickerID);
+ data << uint32(questRewards.TreasurePickerID.size());
+ if (!questRewards.TreasurePickerID.empty())
+ data.append(questRewards.TreasurePickerID.data(), questRewards.TreasurePickerID.size());
for (QuestChoiceItem const& choiceItem : questRewards.ChoiceItems)
data << choiceItem;
@@ -338,14 +356,16 @@ ByteBuffer& operator<<(ByteBuffer& data, QuestRewards const& questRewards)
ByteBuffer& operator<<(ByteBuffer& data, QuestGiverOfferReward const& offer)
{
+ data << offer.Rewards; // QuestRewards
+ data << int32(offer.Emotes.size());
data << offer.QuestGiverGUID;
- data << int32(offer.QuestGiverCreatureID);
- data << int32(offer.QuestID);
data << int32(offer.QuestFlags[0]); // Flags
data << int32(offer.QuestFlags[1]); // FlagsEx
data << int32(offer.QuestFlags[2]); // FlagsEx2
+ data << int32(offer.QuestGiverCreatureID);
+ data << int32(offer.QuestID);
data << int32(offer.SuggestedPartyMembers);
- data << int32(offer.Emotes.size());
+ data << int32(offer.QuestInfoID);
for (QuestDescEmote const& emote : offer.Emotes)
{
data << int32(emote.Type);
@@ -354,10 +374,9 @@ ByteBuffer& operator<<(ByteBuffer& data, QuestGiverOfferReward const& offer)
data << Bits<1>(offer.AutoLaunched);
data << Bits<1>(false); // Unused
+ data << Bits<1>(offer.ResetByScheduler);
data.FlushBits();
- data << offer.Rewards; // QuestRewards
-
return data;
}
@@ -447,6 +466,7 @@ WorldPacket const* QuestGiverQuestDetails::Write()
_worldPacket << uint32(DescEmotes.size());
_worldPacket << uint32(Objectives.size());
_worldPacket << int32(QuestStartItemID);
+ _worldPacket << int32(QuestInfoID);
_worldPacket << int32(QuestSessionBonus);
_worldPacket << int32(QuestGiverCreatureID);
_worldPacket << uint32(ConditionalDescriptionText.size());
@@ -463,9 +483,9 @@ WorldPacket const* QuestGiverQuestDetails::Write()
for (QuestObjectiveSimple const& obj : Objectives)
{
_worldPacket << int32(obj.ID);
+ _worldPacket << int32(obj.Type);
_worldPacket << int32(obj.ObjectID);
_worldPacket << int32(obj.Amount);
- _worldPacket << uint8(obj.Type);
}
_worldPacket << BitsSize<9>(QuestTitle);
@@ -498,19 +518,20 @@ WorldPacket const* QuestGiverQuestDetails::Write()
WorldPacket const* QuestGiverRequestItems::Write()
{
+ _worldPacket << int32(Collect.size());
+ _worldPacket << int32(Currency.size());
_worldPacket << QuestGiverGUID;
+ _worldPacket << uint32(QuestFlags[0]);
+ _worldPacket << uint32(QuestFlags[1]);
+ _worldPacket << uint32(QuestFlags[2]);
+ _worldPacket << int32(StatusFlags);
_worldPacket << int32(QuestGiverCreatureID);
_worldPacket << int32(QuestID);
_worldPacket << int32(CompEmoteDelay);
_worldPacket << int32(CompEmoteType);
- _worldPacket << uint32(QuestFlags[0]);
- _worldPacket << uint32(QuestFlags[1]);
- _worldPacket << uint32(QuestFlags[2]);
_worldPacket << int32(SuggestPartyMembers);
_worldPacket << int32(MoneyToGet);
- _worldPacket << int32(Collect.size());
- _worldPacket << int32(Currency.size());
- _worldPacket << int32(StatusFlags);
+ _worldPacket << int32(QuestInfoID);
for (QuestObjectiveCollect const& obj : Collect)
{
@@ -526,6 +547,7 @@ WorldPacket const* QuestGiverRequestItems::Write()
}
_worldPacket << Bits<1>(AutoLaunched);
+ _worldPacket << Bits<1>(ResetByScheduler);
_worldPacket.FlushBits();
_worldPacket << int32(QuestGiverCreatureID);
diff --git a/src/server/game/Server/Packets/QuestPackets.h b/src/server/game/Server/Packets/QuestPackets.h
index f90977ef07a..3c956bc1d4e 100644
--- a/src/server/game/Server/Packets/QuestPackets.h
+++ b/src/server/game/Server/Packets/QuestPackets.h
@@ -188,7 +188,8 @@ namespace WorldPackets
int32 CompleteSoundKitID = 0;
int32 AreaGroupID = 0;
int64 TimeAllowed = 0;
- int32 TreasurePickerID = 0;
+ std::span<int32 const> TreasurePickerID;
+ std::span<int32 const> TreasurePickerID2; // unknown purpose, used only sometimes and only if TreasurePickerID is empty
int32 Expansion = 0;
int32 ManagedWorldStateID = 0;
int32 QuestSessionBonus = 0;
@@ -258,6 +259,13 @@ namespace WorldPackets
uint16 Count = 0;
};
+ struct QuestRewardItem
+ {
+ int32 ItemID = 0;
+ int32 ItemQty = 0;
+ };
+
+
struct QuestChoiceItem
{
::LootItemType LootItemType = ::LootItemType::Item;
@@ -265,6 +273,13 @@ namespace WorldPackets
int32 Quantity = 0;
};
+ struct QuestRewardCurrency
+ {
+ int32 CurrencyID = 0;
+ int32 CurrencyQty = 0;
+ int32 BonusQty = 0;
+ };
+
struct QuestRewards
{
int32 ChoiceItemCount = 0;
@@ -280,16 +295,14 @@ namespace WorldPackets
int32 SpellCompletionID = 0;
int32 SkillLineID = 0;
int32 NumSkillUps = 0;
- int32 TreasurePickerID = 0;
+ std::span<int32 const> TreasurePickerID;
std::array<QuestChoiceItem, QUEST_REWARD_CHOICES_COUNT> ChoiceItems = { };
- std::array<int32, QUEST_REWARD_ITEM_COUNT> ItemID = { };
- std::array<int32, QUEST_REWARD_ITEM_COUNT> ItemQty = { };
+ std::array<QuestRewardItem, QUEST_REWARD_ITEM_COUNT> Items = { };
std::array<int32, QUEST_REWARD_REPUTATIONS_COUNT> FactionID = { };
std::array<int32, QUEST_REWARD_REPUTATIONS_COUNT> FactionValue = { };
std::array<int32, QUEST_REWARD_REPUTATIONS_COUNT> FactionOverride = { };
std::array<int32, QUEST_REWARD_REPUTATIONS_COUNT> FactionCapIn = { };
- std::array<int32, QUEST_REWARD_CURRENCY_COUNT> CurrencyID = { };
- std::array<int32, QUEST_REWARD_CURRENCY_COUNT> CurrencyQty = { };
+ std::array<QuestRewardCurrency, QUEST_REWARD_CURRENCY_COUNT> Currencies = { };
bool IsBoostSpell = false;
};
@@ -306,10 +319,12 @@ namespace WorldPackets
int32 QuestGiverCreatureID = 0;
int32 QuestID = 0;
bool AutoLaunched = false;
+ bool ResetByScheduler = false;
int32 SuggestedPartyMembers = 0;
QuestRewards Rewards;
std::vector<QuestDescEmote> Emotes;
std::array<int32, 3> QuestFlags = { };
+ int32 QuestInfoID = 0;
};
class QuestGiverOfferRewardMessage final : public ServerPacket
@@ -391,9 +406,9 @@ namespace WorldPackets
struct QuestObjectiveSimple
{
int32 ID = 0;
+ int32 Type = 0;
int32 ObjectID = 0;
int32 Amount = 0;
- uint8 Type = 0;
};
class QuestGiverQuestDetails final : public ServerPacket
@@ -418,6 +433,7 @@ namespace WorldPackets
int32 PortraitGiverMount = 0;
int32 PortraitGiverModelSceneID = 0;
int32 QuestStartItemID = 0;
+ int32 QuestInfoID = 0;
int32 QuestSessionBonus = 0;
int32 QuestGiverCreatureID = 0;
std::string PortraitGiverText;
@@ -461,11 +477,13 @@ namespace WorldPackets
int32 CompEmoteDelay = 0;
int32 CompEmoteType = 0;
bool AutoLaunched = false;
+ bool ResetByScheduler = false;
int32 SuggestPartyMembers = 0;
int32 MoneyToGet = 0;
std::vector<QuestObjectiveCollect> Collect;
std::vector<QuestCurrency> Currency;
int32 StatusFlags = 0;
+ int32 QuestInfoID = 0;
uint32 QuestFlags[3] = { };
std::string QuestTitle;
std::string CompletionText;
diff --git a/src/server/game/Server/Packets/ReputationPackets.cpp b/src/server/game/Server/Packets/ReputationPackets.cpp
index 9f77a774f73..0f867067736 100644
--- a/src/server/game/Server/Packets/ReputationPackets.cpp
+++ b/src/server/game/Server/Packets/ReputationPackets.cpp
@@ -18,18 +18,37 @@
#include "ReputationPackets.h"
#include "PacketUtilities.h"
+namespace WorldPackets::Reputation
+{
+ByteBuffer& operator<<(ByteBuffer& data, FactionData const& factionData)
+{
+ data << int32(factionData.FactionID);
+ data << uint16(factionData.Flags);
+ data << int32(factionData.Standing);
+
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, FactionBonusData const& factionBonusData)
+{
+ data << int32(factionBonusData.FactionID);
+ data << Bits<1>(factionBonusData.FactionHasBonus);
+ data.FlushBits();
+
+ return data;
+}
+}
+
WorldPacket const* WorldPackets::Reputation::InitializeFactions::Write()
{
- for (uint16 i = 0; i < FactionCount; ++i)
- {
- _worldPacket << uint16(FactionFlags[i]);
- _worldPacket << int32(FactionStandings[i]);
- }
+ _worldPacket << uint32(Factions.size());
+ _worldPacket << uint32(Bonuses.size());
- for (uint16 i = 0; i < FactionCount; ++i)
- _worldPacket.WriteBit(FactionHasBonus[i]);
+ for (FactionData const& faction : Factions)
+ _worldPacket << faction;
- _worldPacket.FlushBits();
+ for (FactionBonusData const& bonus : Bonuses)
+ _worldPacket << bonus;
return &_worldPacket;
}
diff --git a/src/server/game/Server/Packets/ReputationPackets.h b/src/server/game/Server/Packets/ReputationPackets.h
index 2acaa859ed6..30199fdd246 100644
--- a/src/server/game/Server/Packets/ReputationPackets.h
+++ b/src/server/game/Server/Packets/ReputationPackets.h
@@ -25,18 +25,28 @@ namespace WorldPackets
{
namespace Reputation
{
- static constexpr uint16 FactionCount = 1000;
+ struct FactionData
+ {
+ int32 FactionID = 0;
+ uint16 Flags = 0;
+ int32 Standing = 0;
+ };
+
+ struct FactionBonusData
+ {
+ int32 FactionID = 0;
+ bool FactionHasBonus = false;
+ };
class InitializeFactions final : public ServerPacket
{
public:
- InitializeFactions() : ServerPacket(SMSG_INITIALIZE_FACTIONS, FactionCount * (4 + 2) + FactionCount / 8) { }
+ InitializeFactions() : ServerPacket(SMSG_INITIALIZE_FACTIONS, 0x1000) { }
WorldPacket const* Write() override;
- std::array<int32, FactionCount> FactionStandings = { };
- std::array<bool, FactionCount> FactionHasBonus = { }; ///< @todo: implement faction bonus
- std::array<uint16, FactionCount> FactionFlags = { }; ///< @see enum FactionFlags
+ std::vector<FactionData> Factions;
+ std::vector<FactionBonusData> Bonuses;
};
struct FactionStandingData
diff --git a/src/server/game/Server/Packets/ScenePackets.cpp b/src/server/game/Server/Packets/ScenePackets.cpp
index f474b11c2b7..5ee41987e85 100644
--- a/src/server/game/Server/Packets/ScenePackets.cpp
+++ b/src/server/game/Server/Packets/ScenePackets.cpp
@@ -26,6 +26,7 @@ WorldPacket const* WorldPackets::Scenes::PlayScene::Write()
_worldPacket << int32(SceneScriptPackageID);
_worldPacket << TransportGUID;
_worldPacket << Location;
+ _worldPacket << int32(MovieID);
_worldPacket << Bits<1>(Encrypted);
_worldPacket.FlushBits();
diff --git a/src/server/game/Server/Packets/ScenePackets.h b/src/server/game/Server/Packets/ScenePackets.h
index ce63a086e38..56d60a1f776 100644
--- a/src/server/game/Server/Packets/ScenePackets.h
+++ b/src/server/game/Server/Packets/ScenePackets.h
@@ -37,6 +37,7 @@ namespace WorldPackets
uint32 PlaybackFlags = 0;
uint32 SceneInstanceID = 0;
int32 SceneScriptPackageID = 0;
+ int32 MovieID = 0;
ObjectGuid TransportGUID;
TaggedPosition<Position::XYZO> Location;
bool Encrypted = false;
diff --git a/src/server/game/Server/Packets/SocialPackets.cpp b/src/server/game/Server/Packets/SocialPackets.cpp
index 7e7d7e188e5..839a9ea91f0 100644
--- a/src/server/game/Server/Packets/SocialPackets.cpp
+++ b/src/server/game/Server/Packets/SocialPackets.cpp
@@ -50,7 +50,6 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Social::ContactInfo const
data << uint32(contact.Level);
data << uint32(contact.ClassID);
data.WriteBits(contact.Notes.length(), 10);
- data.WriteBit(contact.Mobile);
data.FlushBits();
data.WriteString(contact.Notes);
@@ -93,7 +92,6 @@ WorldPacket const* WorldPackets::Social::FriendStatus::Write()
_worldPacket << uint32(Level);
_worldPacket << uint32(ClassID);
_worldPacket.WriteBits(Notes.length(), 10);
- _worldPacket.WriteBit(Mobile);
_worldPacket.FlushBits();
_worldPacket.WriteString(Notes);
diff --git a/src/server/game/Server/Packets/SocialPackets.h b/src/server/game/Server/Packets/SocialPackets.h
index 3007cb3800b..9ee43e163b1 100644
--- a/src/server/game/Server/Packets/SocialPackets.h
+++ b/src/server/game/Server/Packets/SocialPackets.h
@@ -53,7 +53,6 @@ namespace WorldPackets
uint32 AreaID = 0;
uint32 Level = 0;
uint32 ClassID = CLASS_NONE;
- bool Mobile = false;
};
class ContactList final : public ServerPacket
@@ -85,7 +84,6 @@ namespace WorldPackets
uint32 Level = 0;
uint32 AreaID = 0;
uint8 FriendResult = 0; ///< @see enum FriendsResult
- bool Mobile = false;
};
struct QualifiedGUID
diff --git a/src/server/game/Server/Packets/SpellPackets.cpp b/src/server/game/Server/Packets/SpellPackets.cpp
index ccb284edfe5..3f142ed0671 100644
--- a/src/server/game/Server/Packets/SpellPackets.cpp
+++ b/src/server/game/Server/Packets/SpellPackets.cpp
@@ -220,6 +220,7 @@ ByteBuffer& operator>>(ByteBuffer& buffer, SpellCastRequest& request)
request.OptionalCurrencies.resize(buffer.read<uint32>());
request.OptionalReagents.resize(buffer.read<uint32>());
request.RemovedModifications.resize(buffer.read<uint32>());
+ buffer >> request.CraftingFlags;
for (SpellExtraCurrencyCost& optionalCurrency : request.OptionalCurrencies)
buffer >> optionalCurrency;
@@ -328,8 +329,8 @@ ByteBuffer& operator<<(ByteBuffer& data, SpellMissStatus const& spellMissStatus)
ByteBuffer& operator<<(ByteBuffer& data, SpellPowerData const& spellPowerData)
{
- data << int32(spellPowerData.Cost);
data << int8(spellPowerData.Type);
+ data << int32(spellPowerData.Cost);
return data;
}
@@ -742,6 +743,7 @@ WorldPacket const* PlayOrphanSpellVisual::Write()
_worldPacket << SourceRotation;
_worldPacket << TargetLocation;
_worldPacket << Target;
+ _worldPacket << TargetTransport;
_worldPacket << int32(SpellVisualID);
_worldPacket << float(TravelSpeed);
_worldPacket << float(LaunchDelay);
diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h
index dd60478e9b6..cd8523c34df 100644
--- a/src/server/game/Server/Packets/SpellPackets.h
+++ b/src/server/game/Server/Packets/SpellPackets.h
@@ -241,6 +241,7 @@ namespace WorldPackets
Array<SpellCraftingReagent, 6> RemovedModifications;
Array<SpellExtraCurrencyCost, 5 /*MAX_ITEM_EXT_COST_CURRENCIES*/> OptionalCurrencies;
Optional<uint64> CraftingOrderID;
+ uint8 CraftingFlags = 0; // 1 = ApplyConcentration
ObjectGuid CraftingNPC;
int32 Misc[2] = { };
};
@@ -695,6 +696,7 @@ namespace WorldPackets
WorldPacket const* Write() override;
ObjectGuid Target; // Exclusive with TargetLocation
+ ObjectGuid TargetTransport;
TaggedPosition<Position::XYZ> SourceLocation;
int32 SpellVisualID = 0;
bool SpeedAsTime = false;
diff --git a/src/server/game/Server/Packets/SystemPackets.cpp b/src/server/game/Server/Packets/SystemPackets.cpp
index c336555ea28..c14bc777465 100644
--- a/src/server/game/Server/Packets/SystemPackets.cpp
+++ b/src/server/game/Server/Packets/SystemPackets.cpp
@@ -82,6 +82,8 @@ WorldPacket const* FeatureSystemStatus::Write()
_worldPacket << int32(ActiveSeason);
_worldPacket << uint32(GameRuleValues.size());
+ _worldPacket << int32(ActiveTimerunningSeasonID);
+ _worldPacket << int32(RemainingTimerunningSeasonSeconds);
_worldPacket << int16(MaxPlayerNameQueriesPerPacket);
_worldPacket << int16(PlayerNameQueryTelemetryInterval);
@@ -126,7 +128,7 @@ WorldPacket const* FeatureSystemStatus::Write()
_worldPacket << Bits<1>(QuestSessionEnabled);
_worldPacket << Bits<1>(IsMuted);
_worldPacket << Bits<1>(ClubFinderEnabled);
- _worldPacket << Bits<1>(IsCommunityFinderEnabled);
+ _worldPacket << Bits<1>(CommunityFinderEnabled);
_worldPacket << Bits<1>(Unknown901CheckoutRelated);
_worldPacket << Bits<1>(TextToSpeechFeatureEnabled);
@@ -134,22 +136,25 @@ WorldPacket const* FeatureSystemStatus::Write()
_worldPacket << Bits<1>(ChatDisabledByPlayer);
_worldPacket << Bits<1>(LFGListCustomRequiresAuthenticator);
_worldPacket << Bits<1>(AddonsDisabled);
+ _worldPacket << Bits<1>(TimerunningEnabled);
_worldPacket << Bits<1>(WarGamesEnabled);
- _worldPacket << Bits<1>(Unk440_1); // unk, unused 4.4.0
- _worldPacket << Bits<1>(false); // unk, unused 4.4.0
_worldPacket << Bits<1>(ContentTrackingEnabled);
-
_worldPacket << Bits<1>(IsSellAllJunkEnabled);
+
_worldPacket << Bits<1>(IsGroupFinderEnabled);
_worldPacket << Bits<1>(IsLFDEnabled);
_worldPacket << Bits<1>(IsLFREnabled);
_worldPacket << Bits<1>(IsPremadeGroupEnabled);
_worldPacket << Bits<1>(CanShowSetRoleButton);
- _worldPacket << Bits<1>(PetHappinessEnabled);
- _worldPacket << Bits<1>(CanEditGuildEvent);
+ _worldPacket << Bits<1>(false); // unused 10.2.7
+ _worldPacket << Bits<1>(GuildEventsEditsEnabled);
+ _worldPacket << Bits<1>(GuildTradeSkillsEnabled);
+
+ _worldPacket << BitsSize<7>(Unknown1027);
+ _worldPacket << Bits<1>(BNSendWhisperUseV2Services);
- _worldPacket.WriteBit(IsGuildTradeSkillsEnabled);
- _worldPacket << BitsSize<7>(Field_16F);
+ _worldPacket << Bits<1>(BNSendGameDataUseV2Services);
+ _worldPacket << Bits<1>(IsAccountCurrencyTransferEnabled);
_worldPacket.FlushBits();
@@ -186,16 +191,10 @@ WorldPacket const* FeatureSystemStatus::Write()
_worldPacket << int32(SessionAlert->DisplayTime);
}
- if (Unk440_1)
- {
- _worldPacket << uint32(Unk440_2.size());
- _worldPacket.append(Unk440_2.data(), Unk440_2.size());
- }
-
- _worldPacket.WriteString(Field_16F);
+ _worldPacket.WriteString(Unknown1027);
{
- _worldPacket.WriteBit(Squelch.IsSquelched);
+ _worldPacket << Bits<1>(Squelch.IsSquelched);
_worldPacket << Squelch.BnetAccountGuid;
_worldPacket << Squelch.GuildGuid;
}
@@ -222,29 +221,30 @@ WorldPacket const* FeatureSystemStatusGlueScreen::Write()
_worldPacket << Bits<1>(IsBoostEnabled);
_worldPacket << Bits<1>(TrialBoostEnabled);
_worldPacket << Bits<1>(TokenBalanceEnabled);
+ _worldPacket << Bits<1>(PaidCharacterTransfersBetweenBnetAccountsEnabled);
_worldPacket << Bits<1>(LiveRegionCharacterListEnabled);
_worldPacket << Bits<1>(LiveRegionCharacterCopyEnabled);
- _worldPacket << Bits<1>(LiveRegionAccountCopyEnabled);
+ _worldPacket << Bits<1>(LiveRegionAccountCopyEnabled);
_worldPacket << Bits<1>(LiveRegionKeyBindingsCopyEnabled);
_worldPacket << Bits<1>(Unknown901CheckoutRelated);
_worldPacket << Bits<1>(false); // unused, 10.0.2
_worldPacket << OptionalInit(EuropaTicketSystemStatus);
_worldPacket << Bits<1>(IsNameReservationEnabled);
_worldPacket << OptionalInit(LaunchETA);
- _worldPacket << Bits<1>(false); // unused, 4.4.0
- _worldPacket << Bits<1>(false); // unused, 4.4.0
+ _worldPacket << Bits<1>(TimerunningEnabled);
- _worldPacket << Bits<1>(false); // unused, 4.4.0
- _worldPacket << Bits<1>(IsSoMNotificationEnabled);
_worldPacket << Bits<1>(AddonsDisabled);
_worldPacket << Bits<1>(Unused1000);
_worldPacket << Bits<1>(AccountSaveDataExportEnabled);
_worldPacket << Bits<1>(AccountLockedByExport);
- _worldPacket << OptionalInit(RealmHiddenAlert);
- if (RealmHiddenAlert)
- _worldPacket << Bits<11>(RealmHiddenAlert->length() + 1);
+ _worldPacket << Bits<11>(RealmHiddenAlert.length() + 1);
+
+ _worldPacket << Bits<1>(BNSendWhisperUseV2Services);
+
+ _worldPacket << Bits<1>(BNSendGameDataUseV2Services);
+ _worldPacket << Bits<1>(CharacterSelectListModeRealmless);
_worldPacket.FlushBits();
@@ -263,18 +263,20 @@ WorldPacket const* FeatureSystemStatusGlueScreen::Write()
_worldPacket << int32(MaximumExpansionLevel);
_worldPacket << int32(ActiveSeason);
_worldPacket << uint32(GameRuleValues.size());
+ _worldPacket << int32(ActiveTimerunningSeasonID);
+ _worldPacket << int32(RemainingTimerunningSeasonSeconds);
_worldPacket << int16(MaxPlayerNameQueriesPerPacket);
_worldPacket << int16(PlayerNameQueryTelemetryInterval);
_worldPacket << PlayerNameQueryInterval;
_worldPacket << uint32(DebugTimeEvents.size());
_worldPacket << int32(Unused1007);
- _worldPacket << int32(EventRealmQueues);
+ _worldPacket << uint32(EventRealmQueues);
if (LaunchETA)
_worldPacket << int32(*LaunchETA);
- if (RealmHiddenAlert && !RealmHiddenAlert->empty())
- _worldPacket.WriteString(*RealmHiddenAlert);
+ if (!RealmHiddenAlert.empty())
+ _worldPacket << RealmHiddenAlert;
if (!LiveRegionCharacterCopySourceRegions.empty())
_worldPacket.append(LiveRegionCharacterCopySourceRegions.data(), LiveRegionCharacterCopySourceRegions.size());
diff --git a/src/server/game/Server/Packets/SystemPackets.h b/src/server/game/Server/Packets/SystemPackets.h
index 4ffd3ebd806..8c1ff5f18e5 100644
--- a/src/server/game/Server/Packets/SystemPackets.h
+++ b/src/server/game/Server/Packets/SystemPackets.h
@@ -106,7 +106,7 @@ namespace WorldPackets
uint32 Unknown1007 = 0;
};
- struct AddonChatThrottleInfo
+ struct AddonChatThrottleParams
{
int32 MaxTries = 0;
int32 TriesRestoredPerSecond = 0;
@@ -158,33 +158,36 @@ namespace WorldPackets
bool QuestSessionEnabled = false;
bool IsMuted = false;
bool ClubFinderEnabled = false;
- bool IsCommunityFinderEnabled = false;
+ bool CommunityFinderEnabled = false;
bool Unknown901CheckoutRelated = false;
bool TextToSpeechFeatureEnabled = false;
bool ChatDisabledByDefault = false;
bool ChatDisabledByPlayer = false;
bool LFGListCustomRequiresAuthenticator = false;
bool AddonsDisabled = false;
+ bool TimerunningEnabled = false;
bool WarGamesEnabled = false; // classic only
- bool Unk440_1 = false; // classic only
bool ContentTrackingEnabled = false;
bool IsSellAllJunkEnabled = false;
- bool IsGroupFinderEnabled = false; // classic only
- bool IsLFDEnabled = false; // classic only
- bool IsLFREnabled = false; // classic only
- bool IsPremadeGroupEnabled = false; // classic only
- bool CanShowSetRoleButton = false; // classic only
- bool PetHappinessEnabled = false; // classic only
- bool CanEditGuildEvent = false; // classic only
- bool IsGuildTradeSkillsEnabled = false; // classic only
+ bool IsGroupFinderEnabled = true; // classic only
+ bool IsLFDEnabled = true; // classic only
+ bool IsLFREnabled = true; // classic only
+ bool IsPremadeGroupEnabled = true; // classic only
+ bool CanShowSetRoleButton = true;
+ bool GuildEventsEditsEnabled = true;
+ bool GuildTradeSkillsEnabled = true;
+ bool BNSendWhisperUseV2Services = true; ///< BNSendWhisper will send to v2.WhisperService instead of v1.NotificationService
+ bool BNSendGameDataUseV2Services = true; ///< BNSendGameData will send to v2.NotificationService instead of v1.NotificationService
+ bool IsAccountCurrencyTransferEnabled = false;
SocialQueueConfig QuickJoinConfig;
SquelchInfo Squelch;
RafSystemFeatureInfo RAFSystem;
- AddonChatThrottleInfo AddonChatThrottle;
std::vector<GameRuleValuePair> GameRuleValues;
- std::vector<uint8> Unk440_2;
- std::string Field_16F = "";
+ int32 ActiveTimerunningSeasonID = 0;
+ int32 RemainingTimerunningSeasonSeconds = 0;
+ std::string Unknown1027; // related to movement lua functions used by keybinds
+ AddonChatThrottleParams AddonChatThrottle;
};
struct DebugTimeEventInfo
@@ -213,17 +216,21 @@ namespace WorldPackets
bool IsBoostEnabled = false; // classic only
bool TrialBoostEnabled = false; // NYI
bool TokenBalanceEnabled = false; // NYI
+ bool PaidCharacterTransfersBetweenBnetAccountsEnabled = false;
bool LiveRegionCharacterListEnabled = false; // NYI
bool LiveRegionCharacterCopyEnabled = false; // NYI
bool LiveRegionAccountCopyEnabled = false; // NYI
bool LiveRegionKeyBindingsCopyEnabled = false;
bool Unknown901CheckoutRelated = false; // NYI
+ bool IsNameReservationEnabled = false; // classic only
+ bool TimerunningEnabled = false; // NYI
bool AddonsDisabled = false;
- bool IsSoMNotificationEnabled = false; // NYI
bool Unused1000 = false;
bool AccountSaveDataExportEnabled = false;
bool AccountLockedByExport = false;
- bool IsNameReservationEnabled = false; // NYI classic only
+ bool BNSendWhisperUseV2Services = true; ///< BNSendWhisper will send to v2.WhisperService instead of v1.NotificationService
+ bool BNSendGameDataUseV2Services = true; ///< BNSendGameData will send to v2.NotificationService instead of v1.NotificationService
+ bool CharacterSelectListModeRealmless = false;
Optional<EuropaTicketConfig> EuropaTicketSystemStatus;
std::vector<int32> LiveRegionCharacterCopySourceRegions;
uint32 TokenPollTimeSeconds = 0; // NYI
@@ -237,6 +244,8 @@ namespace WorldPackets
uint32 KioskSessionMinutes = 0;
int32 ActiveSeason = 0; // Currently active Classic season
std::vector<GameRuleValuePair> GameRuleValues;
+ int32 ActiveTimerunningSeasonID = 0;
+ int32 RemainingTimerunningSeasonSeconds = 0;
int16 MaxPlayerNameQueriesPerPacket = 50;
int16 PlayerNameQueryTelemetryInterval = 600;
Duration<Seconds, uint32> PlayerNameQueryInterval = 10s;
@@ -244,7 +253,7 @@ namespace WorldPackets
std::vector<DebugTimeEventInfo> DebugTimeEvents;
int32 Unused1007 = 0;
uint32 EventRealmQueues = 0;
- Optional<std::string> RealmHiddenAlert;
+ std::string RealmHiddenAlert;
};
class SetTimeZoneInformation final : public ServerPacket
diff --git a/src/server/game/Server/Packets/TaxiPackets.cpp b/src/server/game/Server/Packets/TaxiPackets.cpp
index 3fe652aa590..f11519b5c9c 100644
--- a/src/server/game/Server/Packets/TaxiPackets.cpp
+++ b/src/server/game/Server/Packets/TaxiPackets.cpp
@@ -69,6 +69,13 @@ void WorldPackets::Taxi::ActivateTaxi::Read()
_worldPacket >> FlyingMountID;
}
+WorldPacket const* WorldPackets::Taxi::NewTaxiPath::Write()
+{
+ _worldPacket << int32(TaxiNodesID);
+
+ return &_worldPacket;
+}
+
WorldPacket const* WorldPackets::Taxi::ActivateTaxiReply::Write()
{
_worldPacket.WriteBits(Reply, 4);
diff --git a/src/server/game/Server/Packets/TaxiPackets.h b/src/server/game/Server/Packets/TaxiPackets.h
index ddeb7920d3d..0f80a7b2020 100644
--- a/src/server/game/Server/Packets/TaxiPackets.h
+++ b/src/server/game/Server/Packets/TaxiPackets.h
@@ -102,9 +102,11 @@ namespace WorldPackets
class NewTaxiPath final : public ServerPacket
{
public:
- NewTaxiPath() : ServerPacket(SMSG_NEW_TAXI_PATH, 0) { }
+ explicit NewTaxiPath(int32 taxiNodesId) : ServerPacket(SMSG_NEW_TAXI_PATH, 4), TaxiNodesID(taxiNodesId) { }
- WorldPacket const* Write() override { return &_worldPacket; }
+ WorldPacket const* Write() override;
+
+ int32 TaxiNodesID = 0;
};
class ActivateTaxiReply final : public ServerPacket
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 315c44bfcea..5b5a72e7df0 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -66,6 +66,7 @@ struct Petition;
struct Position;
enum class AuctionCommand : int8;
enum class AuctionResult : int8;
+enum class PlayerInteractionType : int32;
enum InventoryResult : uint8;
enum class StableResult : uint8;
enum class TabardVendorType : int32;
@@ -134,6 +135,7 @@ namespace WorldPackets
{
class AutoBankItem;
class AutoStoreBankItem;
+ class BankerActivate;
class BuyBankSlot;
}
@@ -786,13 +788,15 @@ enum AccountDataType
PER_CHARACTER_CLICK_BINDINGS_CACHE = 12,
GLOBAL_EDIT_MODE_CACHE = 13,
PER_CHARACTER_EDIT_MODE_CACHE = 14,
+ GLOBAL_FRONTEND_CHAT_SETTINGS = 15,
+ GLOBAL_CHARACTER_LIST_ORDER = 16
};
-#define NUM_ACCOUNT_DATA_TYPES 15
+#define NUM_ACCOUNT_DATA_TYPES 17
-#define ALL_ACCOUNT_DATA_CACHE_MASK 0x7FFF
-#define GLOBAL_CACHE_MASK 0x2515
-#define PER_CHARACTER_CACHE_MASK 0x5AEA
+#define ALL_ACCOUNT_DATA_CACHE_MASK 0x0001FFFFu
+#define GLOBAL_CACHE_MASK 0x0001A515u
+#define PER_CHARACTER_CACHE_MASK 0x00005AEAu
struct AccountData
{
@@ -983,7 +987,7 @@ class TC_GAME_API WorldSession
void SendTrainerList(Creature* npc, uint32 trainerId);
void SendListInventory(ObjectGuid guid);
- void SendShowBank(ObjectGuid guid);
+ void SendShowBank(ObjectGuid guid, PlayerInteractionType interactionType);
bool CanOpenMailBox(ObjectGuid guid);
void SendShowMailBox(ObjectGuid guid);
void SendTabardVendorActivate(ObjectGuid guid, TabardVendorType type);
@@ -1327,7 +1331,7 @@ class TC_GAME_API WorldSession
void HandleTaxiRequestEarlyLanding(WorldPackets::Taxi::TaxiRequestEarlyLanding& taxiRequestEarlyLanding);
void HandleTabardVendorActivateOpcode(WorldPackets::NPC::TabardVendorActivate const& tabardVendorActivate);
- void HandleBankerActivateOpcode(WorldPackets::NPC::Hello& packet);
+ void HandleBankerActivateOpcode(WorldPackets::Bank::BankerActivate const& bankerActivate);
void HandleTrainerListOpcode(WorldPackets::NPC::Hello& packet);
void HandleTrainerBuySpellOpcode(WorldPackets::NPC::TrainerBuySpell& packet);
void HandlePetitionShowList(WorldPackets::Petition::PetitionShowList& packet);
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 8f0e6bde021..7a7fe2122d3 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -1388,7 +1388,7 @@ public:
static bool HandleBankCommand(ChatHandler* handler)
{
- handler->GetSession()->SendShowBank(handler->GetSession()->GetPlayer()->GetGUID());
+ handler->GetSession()->SendShowBank(handler->GetSession()->GetPlayer()->GetGUID(), PlayerInteractionType::Banker);
return true;
}