aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2022-12-04 15:13:20 +0100
committerShauren <shauren.trinity@gmail.com>2022-12-04 15:13:20 +0100
commite98e1283ea0034baf6be9aa2ffb386eb5582801b (patch)
treeb1dd854d88e6e049d26b208bb259cdc7d31f29f8 /src/server/game/Entities
parentde7c03c8385780f05530c2b3cf952a712d5f8f00 (diff)
Core: Updated to 10.0.2
Diffstat (limited to 'src/server/game/Entities')
-rw-r--r--src/server/game/Entities/Corpse/Corpse.cpp6
-rw-r--r--src/server/game/Entities/Creature/GossipDef.cpp216
-rw-r--r--src/server/game/Entities/Creature/GossipDef.h125
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp25
-rw-r--r--src/server/game/Entities/GameObject/GameObjectData.h19
-rw-r--r--src/server/game/Entities/Item/AzeriteItem/AzeriteEmpoweredItem.cpp2
-rw-r--r--src/server/game/Entities/Item/Item.cpp34
-rw-r--r--src/server/game/Entities/Item/Item.h1
-rw-r--r--src/server/game/Entities/Item/ItemDefines.h5
-rw-r--r--src/server/game/Entities/Item/ItemTemplate.h62
-rw-r--r--src/server/game/Entities/Item/enuminfo_ItemDefines.cpp17
-rw-r--r--src/server/game/Entities/Object/MovementInfo.h13
-rw-r--r--src/server/game/Entities/Object/Object.cpp44
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateFields.cpp1534
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateFields.h761
-rw-r--r--src/server/game/Entities/Player/CollectionMgr.cpp6
-rw-r--r--src/server/game/Entities/Player/Player.cpp373
-rw-r--r--src/server/game/Entities/Player/Player.h94
-rw-r--r--src/server/game/Entities/Unit/StatSystem.cpp12
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp5
-rw-r--r--src/server/game/Entities/Unit/Unit.h3
-rw-r--r--src/server/game/Entities/Unit/UnitDefines.h2
22 files changed, 2232 insertions, 1127 deletions
diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp
index 518cad8b3a1..15b175f5c19 100644
--- a/src/server/game/Entities/Corpse/Corpse.cpp
+++ b/src/server/game/Entities/Corpse/Corpse.cpp
@@ -108,7 +108,7 @@ void Corpse::SaveToDB()
DeleteFromDB(trans);
std::ostringstream items;
- for (uint16 index = 0; index < EQUIPMENT_SLOT_END; ++index)
+ for (size_t index = 0; index < m_corpseData->Items.size(); ++index)
items << m_corpseData->Items[index] << ' ';
uint16 index = 0;
@@ -194,8 +194,8 @@ bool Corpse::LoadCorpseFromDB(ObjectGuid::LowType guid, Field* fields)
SetObjectScale(1.0f);
SetDisplayId(fields[5].GetUInt32());
std::vector<std::string_view> items = Trinity::Tokenize(fields[6].GetStringView(), ' ', false);
- if (items.size() == EQUIPMENT_SLOT_END)
- for (uint32 index = 0; index < EQUIPMENT_SLOT_END; ++index)
+ if (items.size() == m_corpseData->Items.size())
+ for (size_t index = 0; index < m_corpseData->Items.size(); ++index)
SetItem(index, Trinity::StringTo<uint32>(items[index]).value_or(0));
SetRace(fields[7].GetUInt8());
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp
index 16f54b7c9a4..2cf5aaa47e2 100644
--- a/src/server/game/Entities/Creature/GossipDef.cpp
+++ b/src/server/game/Entities/Creature/GossipDef.cpp
@@ -38,53 +38,66 @@ GossipMenu::GossipMenu()
_locale = DEFAULT_LOCALE;
}
-GossipMenu::~GossipMenu()
-{
- ClearMenu();
-}
+GossipMenu::~GossipMenu() = default;
-uint32 GossipMenu::AddMenuItem(int32 menuItemId, GossipOptionNpc optionNpc, std::string const& message, uint32 sender, uint32 action, std::string const& boxMessage, uint32 boxMoney, bool coded /*= false*/)
+uint32 GossipMenu::AddMenuItem(int32 gossipOptionId, int32 orderIndex, GossipOptionNpc optionNpc, std::string optionText, uint32 language,
+ GossipOptionFlags flags, Optional<int32> gossipNpcOptionId, bool boxCoded, uint32 boxMoney, std::string boxText, Optional<int32> spellId,
+ Optional<int32> overrideIconId, uint32 sender, uint32 action)
{
ASSERT(_menuItems.size() <= GOSSIP_MAX_MENU_ITEMS);
// Find a free new id - script case
- if (menuItemId == -1)
+ if (orderIndex == -1)
{
- menuItemId = 0;
+ orderIndex = 0;
if (_menuId)
{
- // set baseline menuItemId as higher than whatever exists in db
+ // set baseline orderIndex as higher than whatever exists in db
Trinity::IteratorPair bounds = sObjectMgr->GetGossipMenuItemsMapBounds(_menuId);
auto itr = std::max_element(bounds.begin(), bounds.end(), [](GossipMenuItemsContainer::value_type const& a, GossipMenuItemsContainer::value_type const& b)
{
- return a.second.OptionID < b.second.OptionID;
+ return a.second.OrderIndex < b.second.OrderIndex;
});
if (itr != bounds.end())
- menuItemId = itr->second.OptionID + 1;
+ orderIndex = itr->second.OrderIndex + 1;
}
if (!_menuItems.empty())
{
for (GossipMenuItemContainer::const_iterator itr = _menuItems.begin(); itr != _menuItems.end(); ++itr)
{
- if (int32(itr->first) > menuItemId)
+ if (int32(itr->OrderIndex) > orderIndex)
break;
- menuItemId = itr->first + 1;
+ orderIndex = itr->OrderIndex + 1;
}
}
}
- GossipMenuItem& menuItem = _menuItems[menuItemId];
+ if (!gossipOptionId)
+ gossipOptionId = -(int32(_menuId) * 100 + orderIndex);
+
+ auto where = std::lower_bound(_menuItems.begin(), _menuItems.end(), orderIndex, [](GossipMenuItem const& item, int32 index)
+ {
+ return int32(item.OrderIndex) < index;
+ });
- menuItem.OptionNpc = optionNpc;
- menuItem.Message = message;
- menuItem.IsCoded = coded;
- menuItem.Sender = sender;
- menuItem.Action = action;
- menuItem.BoxMessage = boxMessage;
- menuItem.BoxMoney = boxMoney;
- return menuItemId;
+ GossipMenuItem& menuItem = *_menuItems.emplace(where);
+ menuItem.GossipOptionID = gossipOptionId;
+ menuItem.OrderIndex = orderIndex;
+ menuItem.OptionNpc = optionNpc;
+ menuItem.OptionText = std::move(optionText);
+ menuItem.Language = language;
+ menuItem.Flags = flags;
+ menuItem.GossipNpcOptionID = gossipNpcOptionId;
+ menuItem.BoxCoded = boxCoded;
+ menuItem.BoxMoney = boxMoney;
+ menuItem.BoxText = std::move(boxText);
+ menuItem.SpellID = spellId;
+ menuItem.OverrideIconID = overrideIconId;
+ menuItem.Sender = sender;
+ menuItem.Action = action;
+ return orderIndex;
}
/**
@@ -103,80 +116,117 @@ void GossipMenu::AddMenuItem(uint32 menuId, uint32 menuItemId, uint32 sender, ui
/// Find the one with the given menu item id.
auto itr = std::find_if(bounds.begin(), bounds.end(), [menuItemId](std::pair<uint32 const, GossipMenuItems> const& itemPair)
{
- return itemPair.second.OptionID == menuItemId;
+ return itemPair.second.OrderIndex == menuItemId;
});
if (itr == bounds.end())
return;
+ AddMenuItem(itr->second, sender, action);
+}
+
+void GossipMenu::AddMenuItem(GossipMenuItems const& menuItem, uint32 sender, uint32 action)
+{
/// Store texts for localization.
std::string strOptionText, strBoxText;
- BroadcastTextEntry const* optionBroadcastText = sBroadcastTextStore.LookupEntry(itr->second.OptionBroadcastTextID);
- BroadcastTextEntry const* boxBroadcastText = sBroadcastTextStore.LookupEntry(itr->second.BoxBroadcastTextID);
+ BroadcastTextEntry const* optionBroadcastText = sBroadcastTextStore.LookupEntry(menuItem.OptionBroadcastTextID);
+ BroadcastTextEntry const* boxBroadcastText = sBroadcastTextStore.LookupEntry(menuItem.BoxBroadcastTextID);
/// OptionText
if (optionBroadcastText)
strOptionText = DB2Manager::GetBroadcastTextValue(optionBroadcastText, GetLocale());
else
- strOptionText = itr->second.OptionText;
+ {
+ strOptionText = menuItem.OptionText;
+
+ /// Find localizations from database.
+ if (GetLocale() != LOCALE_enUS)
+ if (GossipMenuItemsLocale const* gossipMenuLocale = sObjectMgr->GetGossipMenuItemsLocale(menuItem.MenuID, menuItem.OrderIndex))
+ ObjectMgr::GetLocaleString(gossipMenuLocale->OptionText, GetLocale(), strBoxText);
+ }
/// BoxText
if (boxBroadcastText)
strBoxText = DB2Manager::GetBroadcastTextValue(boxBroadcastText, GetLocale());
else
- strBoxText = itr->second.BoxText;
-
- if (!boxBroadcastText)
{
+ strBoxText = menuItem.BoxText;
+
/// Find localizations from database.
- if (GossipMenuItemsLocale const* gossipMenuLocale = sObjectMgr->GetGossipMenuItemsLocale(menuId, menuItemId))
- ObjectMgr::GetLocaleString(gossipMenuLocale->BoxText, GetLocale(), strBoxText);
+ if (GetLocale() != LOCALE_enUS)
+ if (GossipMenuItemsLocale const* gossipMenuLocale = sObjectMgr->GetGossipMenuItemsLocale(menuItem.MenuID, menuItem.OrderIndex))
+ ObjectMgr::GetLocaleString(gossipMenuLocale->BoxText, GetLocale(), strBoxText);
}
- /// Add menu item with existing method. Menu item id -1 is also used in ADD_GOSSIP_ITEM macro.
- AddMenuItem(itr->second.OptionID, itr->second.OptionNpc, strOptionText, sender, action, strBoxText, itr->second.BoxMoney, itr->second.BoxCoded);
- AddGossipMenuItemData(itr->second.OptionID, itr->second.ActionMenuID, itr->second.ActionPoiID);
+ AddMenuItem(menuItem.GossipOptionID, menuItem.OrderIndex, menuItem.OptionNpc, std::move(strOptionText), menuItem.Language, menuItem.Flags,
+ menuItem.GossipNpcOptionID, menuItem.BoxCoded, menuItem.BoxMoney, std::move(strBoxText), menuItem.SpellID, menuItem.OverrideIconID, sender, action);
+ AddGossipMenuItemData(menuItem.OrderIndex, menuItem.ActionMenuID, menuItem.ActionPoiID);
}
void GossipMenu::AddGossipMenuItemData(uint32 menuItemId, uint32 gossipActionMenuId, uint32 gossipActionPoi)
{
- GossipMenuItemData& itemData = _menuItemData[menuItemId];
+ GossipMenuItem& menuItem = _menuItems[menuItemId];
- itemData.GossipActionMenuId = gossipActionMenuId;
- itemData.GossipActionPoi = gossipActionPoi;
+ menuItem.ActionMenuID = gossipActionMenuId;
+ menuItem.ActionPoiID = gossipActionPoi;
}
-uint32 GossipMenu::GetMenuItemSender(uint32 menuItemId) const
+GossipMenuItem const* GossipMenu::GetItem(int32 gossipOptionId) const
{
- GossipMenuItemContainer::const_iterator itr = _menuItems.find(menuItemId);
- if (itr == _menuItems.end())
- return 0;
+ auto itr = std::find_if(_menuItems.begin(), _menuItems.end(), [gossipOptionId](GossipMenuItem const& item)
+ {
+ return item.GossipOptionID == gossipOptionId;
+ });
- return itr->second.Sender;
+ if (itr != _menuItems.end())
+ return &*itr;
+
+ return nullptr;
}
-uint32 GossipMenu::GetMenuItemAction(uint32 menuItemId) const
+GossipMenuItem const* GossipMenu::GetItemByIndex(uint32 orderIndex) const
{
- GossipMenuItemContainer::const_iterator itr = _menuItems.find(menuItemId);
- if (itr == _menuItems.end())
- return 0;
+ auto itr = std::find_if(_menuItems.begin(), _menuItems.end(), [orderIndex](GossipMenuItem const& item)
+ {
+ return item.OrderIndex == orderIndex;
+ });
- return itr->second.Action;
+ if (itr != _menuItems.end())
+ return &*itr;
+
+ return nullptr;
}
-bool GossipMenu::IsMenuItemCoded(uint32 menuItemId) const
+uint32 GossipMenu::GetMenuItemSender(uint32 orderIndex) const
{
- GossipMenuItemContainer::const_iterator itr = _menuItems.find(menuItemId);
- if (itr == _menuItems.end())
- return false;
+ GossipMenuItem const* item = GetItemByIndex(orderIndex);
+ if (item)
+ return item->Sender;
- return itr->second.IsCoded;
+ return 0;
+}
+
+uint32 GossipMenu::GetMenuItemAction(uint32 orderIndex) const
+{
+ GossipMenuItem const* item = GetItemByIndex(orderIndex);
+ if (item)
+ return item->Action;
+
+ return 0;
+}
+
+bool GossipMenu::IsMenuItemCoded(uint32 orderIndex) const
+{
+ GossipMenuItem const* item = GetItemByIndex(orderIndex);
+ if (item)
+ return item->BoxCoded;
+
+ return 0;
}
void GossipMenu::ClearMenu()
{
_menuItems.clear();
- _menuItemData.clear();
}
PlayerMenu::PlayerMenu(WorldSession* session) : _session(session)
@@ -185,10 +235,7 @@ PlayerMenu::PlayerMenu(WorldSession* session) : _session(session)
_gossipMenu.SetLocale(_session->GetSessionDbLocaleIndex());
}
-PlayerMenu::~PlayerMenu()
-{
- ClearMenus();
-}
+PlayerMenu::~PlayerMenu() = default;
void PlayerMenu::ClearMenus()
{
@@ -210,25 +257,26 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID)
if (NpcText const* text = sObjectMgr->GetNpcText(titleTextId))
packet.TextID = Trinity::Containers::SelectRandomWeightedContainerElement(text->Data, [](NpcTextData const& data) { return data.Probability; })->BroadcastTextID;
- packet.GossipOptions.resize(_gossipMenu.GetMenuItems().size());
- uint32 count = 0;
- for (GossipMenuItemContainer::const_iterator itr = _gossipMenu.GetMenuItems().begin(); itr != _gossipMenu.GetMenuItems().end(); ++itr)
+ packet.GossipOptions.reserve(_gossipMenu.GetMenuItems().size());
+ for (GossipMenuItem const& item : _gossipMenu.GetMenuItems())
{
- WorldPackets::NPC::ClientGossipOptions& opt = packet.GossipOptions[count];
- GossipMenuItem const& item = itr->second;
- opt.ClientOption = itr->first;
+ WorldPackets::NPC::ClientGossipOptions& opt = packet.GossipOptions.emplace_back();
+ opt.GossipOptionID = item.GossipOptionID;
opt.OptionNPC = item.OptionNpc;
- opt.OptionFlags = item.IsCoded; // makes pop up box password
+ opt.OptionFlags = item.BoxCoded; // makes pop up box password
opt.OptionCost = item.BoxMoney; // money required to open menu, 2.0.3
opt.OptionLanguage = item.Language;
- opt.Text = item.Message; // text for gossip item
- opt.Confirm = item.BoxMessage; // accept text (related to money) pop up box, 2.0.3
+ opt.Flags = item.Flags;
+ opt.OrderIndex = item.OrderIndex;
+ opt.Text = item.OptionText; // text for gossip item
+ opt.Confirm = item.BoxText; // accept text (related to money) pop up box, 2.0.3
opt.Status = GossipOptionStatus::Available;
- ++count;
+ opt.SpellID = item.SpellID;
+ opt.OverrideIconID = item.OverrideIconID;
}
packet.GossipText.resize(_questMenu.GetMenuItemCount());
- count = 0;
+ uint32 count = 0;
for (uint8 i = 0; i < _questMenu.GetMenuItemCount(); ++i)
{
QuestMenuItem const& item = _questMenu.GetItem(i);
@@ -300,13 +348,10 @@ void PlayerMenu::SendPointOfInterest(uint32 id) const
QuestMenu::QuestMenu()
{
- _questMenuItems.reserve(16); // can be set for max from most often sizes to speedup push_back and less memory use
+ _questMenuItems.reserve(4); // can be set for max from most often sizes to speedup push_back and less memory use
}
-QuestMenu::~QuestMenu()
-{
- ClearMenu();
-}
+QuestMenu::~QuestMenu() = default;
void QuestMenu::AddMenuItem(uint32 QuestId, uint8 Icon)
{
@@ -408,6 +453,13 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGU
packet.PortraitTurnInName = quest->GetPortraitTurnInName();
LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex();
+ std::transform(quest->GetConditionalQuestDescription().begin(), quest->GetConditionalQuestDescription().end(), std::back_inserter(packet.ConditionalDescriptionText), [localeConstant](QuestConditionalText const& text)
+ {
+ std::string_view content = text.Text[LOCALE_enUS];
+ ObjectMgr::GetLocaleString(text.Text, localeConstant, content);
+ return WorldPackets::Quest::ConditionalQuestText{ text.PlayerConditionId, text.QuestgiverCreatureId, content };
+ });
+
if (localeConstant != LOCALE_enUS)
{
if (QuestTemplateLocale const* questTemplateLocale = sObjectMgr->GetQuestLocale(quest->GetQuestId()))
@@ -435,6 +487,7 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGU
packet.DisplayPopup = displayPopup;
packet.QuestFlags[0] = quest->GetFlags() & (sWorld->getBoolConfig(CONFIG_QUEST_IGNORE_AUTO_ACCEPT) ? ~QUEST_FLAGS_AUTO_ACCEPT : ~0);
packet.QuestFlags[1] = quest->GetFlagsEx();
+ packet.QuestFlags[2] = quest->GetFlagsEx2();
packet.SuggestedPartyMembers = quest->GetSuggestedPlayers();
// RewardSpell can teach multiple spells in trigger spell effects. But not all effects must be SPELL_EFFECT_LEARN_SPELL. See example spell 33950
@@ -492,6 +545,13 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, ObjectGuid npcGUI
packet.PortraitTurnInName = quest->GetPortraitTurnInName();
LocaleConstant locale = _session->GetSessionDbLocaleIndex();
+ std::transform(quest->GetConditionalOfferRewardText().begin(), quest->GetConditionalOfferRewardText().end(), std::back_inserter(packet.ConditionalRewardText), [locale](QuestConditionalText const& text)
+ {
+ std::string_view content = text.Text[LOCALE_enUS];
+ ObjectMgr::GetLocaleString(text.Text, locale, content);
+ return WorldPackets::Quest::ConditionalQuestText{ text.PlayerConditionId, text.QuestgiverCreatureId, content };
+ });
+
if (locale != LOCALE_enUS)
{
if (QuestTemplateLocale const* questTemplateLocale = sObjectMgr->GetQuestLocale(quest->GetQuestId()))
@@ -514,7 +574,10 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, ObjectGuid npcGUI
// Is there a better way? what about game objects?
if (Creature const* creature = ObjectAccessor::GetCreature(*_session->GetPlayer(), npcGUID))
+ {
+ packet.QuestGiverCreatureID = creature->GetEntry();
offer.QuestGiverCreatureID = creature->GetCreatureTemplate()->Entry;
+ }
offer.QuestID = quest->GetQuestId();
offer.AutoLaunched = autoLaunched;
@@ -525,6 +588,7 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, ObjectGuid npcGUI
offer.QuestFlags[0] = quest->GetFlags();
offer.QuestFlags[1] = quest->GetFlagsEx();
+ offer.QuestFlags[2] = quest->GetFlagsEx2();
packet.PortraitTurnIn = quest->GetQuestTurnInPortrait();
packet.PortraitGiver = quest->GetQuestGiverPortrait();
@@ -553,6 +617,13 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, ObjectGuid npcGU
packet.CompletionText = quest->GetRequestItemsText();
LocaleConstant locale = _session->GetSessionDbLocaleIndex();
+ std::transform(quest->GetConditionalRequestItemsText().begin(), quest->GetConditionalRequestItemsText().end(), std::back_inserter(packet.ConditionalCompletionText), [locale](QuestConditionalText const& text)
+ {
+ std::string_view content = text.Text[LOCALE_enUS];
+ ObjectMgr::GetLocaleString(text.Text, locale, content);
+ return WorldPackets::Quest::ConditionalQuestText{ text.PlayerConditionId, text.QuestgiverCreatureId, content };
+ });
+
if (locale != LOCALE_enUS)
{
if (QuestTemplateLocale const* questTemplateLocale = sObjectMgr->GetQuestLocale(quest->GetQuestId()))
@@ -583,6 +654,7 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, ObjectGuid npcGU
packet.QuestFlags[0] = quest->GetFlags();
packet.QuestFlags[1] = quest->GetFlagsEx();
+ packet.QuestFlags[2] = quest->GetFlagsEx2();
packet.SuggestPartyMembers = quest->GetSuggestedPlayers();
// incomplete: FD
diff --git a/src/server/game/Entities/Creature/GossipDef.h b/src/server/game/Entities/Creature/GossipDef.h
index 5151bbdafdc..b4f0cd61136 100644
--- a/src/server/game/Entities/Creature/GossipDef.h
+++ b/src/server/game/Entities/Creature/GossipDef.h
@@ -20,11 +20,12 @@
#include "Common.h"
#include "ObjectGuid.h"
-#include <map>
+#include "Optional.h"
class Object;
class Quest;
class WorldSession;
+struct GossipMenuItems;
enum class QuestGiverStatus : uint32;
#define GOSSIP_MAX_MENU_ITEMS 32
@@ -34,24 +35,24 @@ enum class GossipOptionNpc : uint8
{
None = 0, // White chat bubble. Default
Vendor = 1, // Brown bag
- TaxiNode = 2, // White wing
+ Taxinode = 2, // White wing
Trainer = 3, // Brown book
SpiritHealer = 4, // Golden interaction wheel (with red center)
Binder = 5, // Golden interaction wheel
Banker = 6, // Brown bag (with gold coin in lower corner)
PetitionVendor = 7, // White chat bubble (with "..." inside)
TabardVendor = 8, // White tabard
- BattleMaster = 9, // Two crossed swords
+ Battlemaster = 9, // Two crossed swords
Auctioneer = 10, // Stack of gold coins
TalentMaster = 11, // White chat bubble
- StableMaster = 12, // White chat bubble
+ Stablemaster = 12, // White chat bubble
PetSpecializationMaster = 13, /*DEPRECATED*/ // White chat bubble
- GuildBanker = 14, /*NYI*/ // White chat bubble
- SpellClick = 15, /*NYI*/ // White chat bubble
+ GuildBanker = 14, // White chat bubble
+ Spellclick = 15, // White chat bubble
DisableXPGain = 16, // White chat bubble
EnableXPGain = 17, // White chat bubble
Mailbox = 18, // White chat bubble
- WorldPVPQueue = 19, /*NYI*/ // White chat bubble
+ WorldPvPQueue = 19, /*NYI*/ // White chat bubble
LFGDungeon = 20, /*NYI*/ // White chat bubble
ArtifactRespec = 21, /*NYI*/ // White chat bubble
CemeterySelect = 22, /*DEPRECATED*/ // White chat bubble
@@ -59,25 +60,33 @@ enum class GossipOptionNpc : uint8
GlyphMaster = 24, /*DEPRECATED*/ // White chat bubble
QueueScenario = 25, /*NYI*/ // White chat bubble
GarrisonArchitect = 26, /*NYI*/ // White chat bubble
- GarrisonMission = 27, /*NYI*/ // White chat bubble
+ GarrisonMissionNpc = 27, /*NYI*/ // White chat bubble
ShipmentCrafter = 28, /*NYI*/ // Brown document
- GarrisonTradeskill = 29, /*NYI*/ // White chat bubble
+ GarrisonTradeskillNpc = 29, /*NYI*/ // White chat bubble
GarrisonRecruitment = 30, /*NYI*/ // White chat bubble
AdventureMap = 31, /*NYI*/ // White chat bubble
GarrisonTalent = 32, // White chat bubble
ContributionCollector = 33, /*NYI*/ // White chat bubble
Transmogrify = 34, // Purple helm
AzeriteRespec = 35, // White chat bubble
- IslandsMission = 36, /*NYI*/ // White chat bubble
+ IslandsMissionNpc = 36, /*NYI*/ // White chat bubble
UIItemInteraction = 37, /*NYI*/ // White chat bubble
WorldMap = 38, /*NYI*/ // White chat bubble
Soulbind = 39, /*NYI*/ // White chat bubble
- ChromieTime = 40, /*NYI*/ // White chat bubble
- CovenantPreview = 41, /*NYI*/ // White chat bubble
+ ChromieTimeNpc = 40, /*NYI*/ // White chat bubble
+ CovenantPreviewNpc = 41, /*NYI*/ // White chat bubble
RuneforgeLegendaryCrafting = 42, /*NYI*/ // White chat bubble
NewPlayerGuide = 43, /*NYI*/ // White chat bubble
RuneforgeLegendaryUpgrade = 44, /*NYI*/ // White chat bubble
- CovenantRenown = 45, /*NYI*/ // White chat bubble
+ CovenantRenownNpc = 45, /*NYI*/ // White chat bubble
+ BlackMarketAuctionHouse = 46,
+ PerksProgramVendor = 47,
+ ProfessionsCraftingOrder = 48,
+ ProfessionsOpen = 49,
+ ProfessionsCustomerOrder = 50,
+ TraitSystem = 51,
+ BarbersChoice = 52,
+ MajorFactionRenown = 53,
Count
};
@@ -96,29 +105,38 @@ enum class GossipOptionRewardType : uint8
Currency = 1
};
-struct GossipMenuItem
+enum class GossipOptionFlags : int32
{
- GossipOptionNpc OptionNpc;
- bool IsCoded;
- std::string Message;
- uint32 Sender;
- uint32 Action;
- std::string BoxMessage;
- uint32 BoxMoney;
- uint32 Language;
+ None = 0x0,
+ QuestLabelPrepend = 0x1
};
-// need an ordered container
-typedef std::map<uint32, GossipMenuItem> GossipMenuItemContainer;
-
-struct GossipMenuItemData
+struct GossipMenuItem
{
- uint32 GossipActionMenuId; // MenuId of the gossip triggered by this action
- uint32 GossipActionPoi;
+ int32 GossipOptionID;
+ uint32 OrderIndex;
+ GossipOptionNpc OptionNpc;
+ std::string OptionText;
+ uint32 Language;
+ GossipOptionFlags Flags;
+ Optional<int32> GossipNpcOptionID;
+ bool BoxCoded;
+ uint32 BoxMoney;
+ std::string BoxText;
+ Optional<int32> SpellID;
+ Optional<int32> OverrideIconID;
+
+ // action data
+ uint32 ActionMenuID;
+ uint32 ActionPoiID;
+
+ // additional scripting identifiers
+ uint32 Sender;
+ uint32 Action;
};
// need an ordered container
-typedef std::map<uint32, GossipMenuItemData> GossipMenuItemDataContainer;
+typedef std::vector<GossipMenuItem> GossipMenuItemContainer;
struct QuestMenuItem
{
@@ -132,10 +150,17 @@ class TC_GAME_API GossipMenu
{
public:
GossipMenu();
+ GossipMenu(GossipMenu const&) = delete;
+ GossipMenu(GossipMenu&&) = delete;
+ GossipMenu& operator=(GossipMenu const&) = delete;
+ GossipMenu& operator=(GossipMenu&&) = delete;
~GossipMenu();
- uint32 AddMenuItem(int32 menuItemId, GossipOptionNpc optionNpc, std::string const& message, uint32 sender, uint32 action, std::string const& boxMessage, uint32 boxMoney, bool coded = false);
+ uint32 AddMenuItem(int32 gossipOptionId, int32 orderIndex, GossipOptionNpc optionNpc, std::string optionText, uint32 language, GossipOptionFlags flags,
+ Optional<int32> gossipNpcOptionId, bool boxCoded, uint32 boxMoney, std::string boxText, Optional<int32> spellId,
+ Optional<int32> overrideIconId, uint32 sender, uint32 action);
void AddMenuItem(uint32 menuId, uint32 menuItemId, uint32 sender, uint32 action);
+ void AddMenuItem(GossipMenuItems const& menuItem, uint32 sender, uint32 action);
void SetMenuId(uint32 menu_id) { _menuId = menu_id; }
uint32 GetMenuId() const { return _menuId; }
@@ -154,27 +179,12 @@ class TC_GAME_API GossipMenu
return _menuItems.empty();
}
- GossipMenuItem const* GetItem(uint32 id) const
- {
- GossipMenuItemContainer::const_iterator itr = _menuItems.find(id);
- if (itr != _menuItems.end())
- return &itr->second;
-
- return nullptr;
- }
-
- GossipMenuItemData const* GetItemData(uint32 indexId) const
- {
- GossipMenuItemDataContainer::const_iterator itr = _menuItemData.find(indexId);
- if (itr != _menuItemData.end())
- return &itr->second;
-
- return nullptr;
- }
+ GossipMenuItem const* GetItem(int32 gossipOptionId) const;
+ GossipMenuItem const* GetItemByIndex(uint32 orderIndex) const;
- uint32 GetMenuItemSender(uint32 menuItemId) const;
- uint32 GetMenuItemAction(uint32 menuItemId) const;
- bool IsMenuItemCoded(uint32 menuItemId) const;
+ uint32 GetMenuItemSender(uint32 orderIndex) const;
+ uint32 GetMenuItemAction(uint32 orderIndex) const;
+ bool IsMenuItemCoded(uint32 orderIndex) const;
void ClearMenu();
@@ -185,7 +195,6 @@ class TC_GAME_API GossipMenu
private:
GossipMenuItemContainer _menuItems;
- GossipMenuItemDataContainer _menuItemData;
uint32 _menuId;
LocaleConstant _locale;
};
@@ -194,6 +203,10 @@ class TC_GAME_API QuestMenu
{
public:
QuestMenu();
+ QuestMenu(QuestMenu const&) = delete;
+ QuestMenu(QuestMenu&&) = delete;
+ QuestMenu& operator=(QuestMenu const&) = delete;
+ QuestMenu& operator=(QuestMenu&&) = delete;
~QuestMenu();
void AddMenuItem(uint32 QuestId, uint8 Icon);
@@ -210,8 +223,6 @@ class TC_GAME_API QuestMenu
class InteractionData
{
public:
- InteractionData() { Reset(); }
-
void Reset()
{
SourceGuid.Clear();
@@ -220,14 +231,18 @@ class InteractionData
}
ObjectGuid SourceGuid;
- uint32 TrainerId;
- uint32 PlayerChoiceId;
+ uint32 TrainerId = 0;
+ uint32 PlayerChoiceId = 0;
};
class TC_GAME_API PlayerMenu
{
public:
explicit PlayerMenu(WorldSession* session);
+ PlayerMenu(PlayerMenu const&) = delete;
+ PlayerMenu(PlayerMenu&&) = delete;
+ PlayerMenu& operator=(PlayerMenu const&) = delete;
+ PlayerMenu& operator=(PlayerMenu&&) = delete;
~PlayerMenu();
GossipMenu& GetGossipMenu() { return _gossipMenu; }
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 70e088a23ea..8b3946d22c5 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -2927,8 +2927,9 @@ void GameObject::Use(Unit* user)
if (!item)
return;
- WorldPackets::Azerite::OpenHeartForge openHeartForge;
- openHeartForge.ForgeGUID = GetGUID();
+ WorldPackets::GameObject::GameObjectInteraction openHeartForge;
+ openHeartForge.ObjectGUID = GetGUID();
+ openHeartForge.InteractionType = PlayerInteractionType::AzeriteForge;
player->SendDirectMessage(openHeartForge.Write());
break;
}
@@ -2943,9 +2944,25 @@ void GameObject::Use(Unit* user)
if (!player)
return;
- WorldPackets::GameObject::GameObjectUILink gameObjectUILink;
+ WorldPackets::GameObject::GameObjectInteraction gameObjectUILink;
gameObjectUILink.ObjectGUID = GetGUID();
- gameObjectUILink.UILink = GetGOInfo()->UILink.UILinkType;
+ switch (GetGOInfo()->UILink.UILinkType)
+ {
+ case 0:
+ gameObjectUILink.InteractionType = PlayerInteractionType::AdventureJournal;
+ break;
+ case 1:
+ gameObjectUILink.InteractionType = PlayerInteractionType::ObliterumForge;
+ break;
+ case 2:
+ gameObjectUILink.InteractionType = PlayerInteractionType::ScrappingMachine;
+ break;
+ case 3:
+ gameObjectUILink.InteractionType = PlayerInteractionType::ItemInteraction;
+ break;
+ default:
+ break;
+ }
player->SendDirectMessage(gameObjectUILink.Write());
return;
}
diff --git a/src/server/game/Entities/GameObject/GameObjectData.h b/src/server/game/Entities/GameObject/GameObjectData.h
index 8521e460cd6..0e08bb26fea 100644
--- a/src/server/game/Entities/GameObject/GameObjectData.h
+++ b/src/server/game/Entities/GameObject/GameObjectData.h
@@ -40,7 +40,7 @@ struct GameObjectTemplate
int32 ContentTuningId;
union
{
- // 0 GAMEOBJECT_TYPE_DOOR
+ // 0 GAMEOBJECT_TYPE_DOOR
struct
{
uint32 startOpen; // 0 startOpen, enum { false, true, }; Default: false
@@ -56,6 +56,7 @@ struct GameObjectTemplate
uint32 InfiniteAOI; // 10 Infinite AOI, enum { false, true, }; Default: false
uint32 NotLOSBlocking; // 11 Not LOS Blocking, enum { false, true, }; Default: false
uint32 InteractRadiusOverride; // 12 Interact Radius Override (in hundredths), int, Min value: 0, Max value: 2147483647, Default value: 0
+ uint32 Collisionupdatedelayafteropen; // 13 Collision update delay(ms) after open, int, Min value: 0, Max value: 2147483647, Default value: 0
} door;
// 1 GAMEOBJECT_TYPE_BUTTON
struct
@@ -196,6 +197,13 @@ struct GameObjectTemplate
uint32 floatOnWater; // 7 floatOnWater, enum { false, true, }; Default: false
uint32 conditionID1; // 8 conditionID1, References: PlayerCondition, NoValue = 0
uint32 InteractRadiusOverride; // 9 Interact Radius Override (in hundredths), int, Min value: 0, Max value: 2147483647, Default value: 0
+ uint32 gossipID; // 10 gossipID, References: Gossip, NoValue = 0
+ uint32 spellFocusType2; // 11 spellFocusType 2, References: SpellFocusObject, NoValue = 0
+ uint32 spellFocusType3; // 12 spellFocusType 3, References: SpellFocusObject, NoValue = 0
+ uint32 spellFocusType4; // 13 spellFocusType 4, References: SpellFocusObject, NoValue = 0
+ uint32 Profession; // 14 Profession, enum { First Aid, Blacksmithing, Leatherworking, Alchemy, Herbalism, Cooking, Mining, Tailoring, Engineering, Enchanting, Fishing, Skinning, Jewelcrafting, Inscription, Archaeology, }; Default: Blacksmithing
+ uint32 Profession2; // 15 Profession 2, enum { First Aid, Blacksmithing, Leatherworking, Alchemy, Herbalism, Cooking, Mining, Tailoring, Engineering, Enchanting, Fishing, Skinning, Jewelcrafting, Inscription, Archaeology, }; Default: Blacksmithing
+ uint32 Profession3; // 16 Profession 3, enum { First Aid, Blacksmithing, Leatherworking, Alchemy, Herbalism, Cooking, Mining, Tailoring, Engineering, Enchanting, Fishing, Skinning, Jewelcrafting, Inscription, Archaeology, }; Default: Blacksmithing
} spellFocus;
// 9 GAMEOBJECT_TYPE_TEXT
struct
@@ -483,7 +491,7 @@ struct GameObjectTemplate
// 31 GAMEOBJECT_TYPE_DUNGEON_DIFFICULTY
struct
{
- uint32 InstanceType; // 0 Instance Type, enum { Not Instanced, Party Dungeon, Raid Dungeon, PVP Battlefield, Arena Battlefield, Scenario, }; Default: Party Dungeon
+ uint32 InstanceType; // 0 Instance Type, enum { Not Instanced, Party Dungeon, Raid Dungeon, PVP Battlefield, Arena Battlefield, Scenario, WoWLabs, }; Default: Party Dungeon
uint32 DifficultyNormal; // 1 Difficulty Normal, References: animationdata, NoValue = 0
uint32 DifficultyHeroic; // 2 Difficulty Heroic, References: animationdata, NoValue = 0
uint32 DifficultyEpic; // 3 Difficulty Epic, References: animationdata, NoValue = 0
@@ -503,6 +511,7 @@ struct GameObjectTemplate
int32 HeightOffset; // 1 Height Offset (inches), int, Min value: -100, Max value: 100, Default value: 0
uint32 SitAnimKit; // 2 Sit Anim Kit, References: AnimKit, NoValue = 0
uint32 InteractRadiusOverride; // 3 Interact Radius Override (in hundredths), int, Min value: 0, Max value: 2147483647, Default value: 0
+ uint32 CustomizationScope; // 4 Customization Scope, int, Min value: 0, Max value: 2147483647, Default value: 0
} barberChair;
// 33 GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
struct
@@ -794,6 +803,7 @@ struct GameObjectTemplate
uint32 WhenAvailable; // 0 When Available, References: GameObjectDisplayInfo, NoValue = 0
uint32 open; // 1 open, References: Lock_, NoValue = 0
uint32 InteractRadiusOverride; // 2 Interact Radius Override (in hundredths), int, Min value: 0, Max value: 2147483647, Default value: 0
+ uint32 ExpansionLevel; // 3 Expansion Level, int, Min value: 0, Max value: 2147483647, Default value: 0
} weeklyRewardChest;
// 60 GAMEOBJECT_TYPE_CLIENT_MODEL
struct
@@ -803,6 +813,11 @@ struct GameObjectTemplate
uint32 InfiniteAOI; // 2 Infinite AOI, enum { false, true, }; Default: false
uint32 TrueInfiniteAOI; // 3 True Infinite AOI (programmer only!), enum { false, true, }; Default: false
} clientModel;
+ // 61 GAMEOBJECT_TYPE_CRAFTING_TABLE
+ struct
+ {
+ uint32 Profession; // 0 Profession, enum { First Aid, Blacksmithing, Leatherworking, Alchemy, Herbalism, Cooking, Mining, Tailoring, Engineering, Enchanting, Fishing, Skinning, Jewelcrafting, Inscription, Archaeology, }; Default: Blacksmithing
+ } craftingTable;
struct
{
uint32 data[MAX_GAMEOBJECT_DATA];
diff --git a/src/server/game/Entities/Item/AzeriteItem/AzeriteEmpoweredItem.cpp b/src/server/game/Entities/Item/AzeriteItem/AzeriteEmpoweredItem.cpp
index 552e5075603..36a01947955 100644
--- a/src/server/game/Entities/Item/AzeriteItem/AzeriteEmpoweredItem.cpp
+++ b/src/server/game/Entities/Item/AzeriteItem/AzeriteEmpoweredItem.cpp
@@ -142,7 +142,7 @@ void AzeriteEmpoweredItem::ClearSelectedAzeritePowers()
SetUpdateFieldValue(m_values.ModifyValue(&AzeriteEmpoweredItem::m_azeriteEmpoweredItemData).ModifyValue(&UF::AzeriteEmpoweredItemData::Selections, i), 0);
_bonusData.Initialize(GetTemplate());
- for (int32 bonusListID : *m_itemData->BonusListIDs)
+ for (int32 bonusListID : GetBonusListIDs())
_bonusData.AddBonusList(bonusListID);
}
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index 96399f9c00f..3a2e55bb412 100644
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -256,6 +256,8 @@ bool ItemCanGoIntoBag(ItemTemplate const* pProto, ItemTemplate const* pBagProto)
if (!(pProto->GetBagFamily() & BAG_FAMILY_MASK_COOKING_SUPP))
return false;
return true;
+ case ITEM_SUBCLASS_REAGENT_CONTAINER:
+ return pProto->IsCraftingReagent();
default:
return false;
}
@@ -610,7 +612,7 @@ void Item::SaveToDB(CharacterDatabaseTransaction trans)
stmt->setUInt8(++index, uint8(m_itemData->Context));
std::ostringstream bonusListIDs;
- for (int32 bonusListID : *m_itemData->BonusListIDs)
+ for (int32 bonusListID : GetBonusListIDs())
bonusListIDs << bonusListID << ' ';
stmt->setString(++index, bonusListIDs.str());
@@ -1240,7 +1242,8 @@ uint8 Item::GetBagSlot() const
bool Item::IsEquipped() const
{
- return !IsInBag() && m_slot < EQUIPMENT_SLOT_END;
+ return !IsInBag() && ((m_slot >= EQUIPMENT_SLOT_START && m_slot < EQUIPMENT_SLOT_END)
+ || (m_slot >= PROFESSION_SLOT_START && m_slot < PROFESSION_SLOT_END));
}
bool Item::CanBeTraded(bool mail, bool trade) const
@@ -2043,6 +2046,12 @@ int32 const ItemTransmogrificationSlots[MAX_INVTYPE] =
EQUIPMENT_SLOT_MAINHAND, // INVTYPE_RANGEDRIGHT
-1, // INVTYPE_QUIVER
-1 // INVTYPE_RELIC
+ -1, // INVTYPE_PROFESSION_TOOL
+ -1, // INVTYPE_PROFESSION_GEAR
+ -1, // INVTYPE_EQUIPABLE_SPELL_OFFENSIVE
+ -1, // INVTYPE_EQUIPABLE_SPELL_UTILITY
+ -1, // INVTYPE_EQUIPABLE_SPELL_DEFENSIVE
+ -1 // INVTYPE_EQUIPABLE_SPELL_MOBILITY
};
bool Item::CanTransmogrifyItemWithItem(Item const* item, ItemModifiedAppearanceEntry const* itemModifiedAppearance)
@@ -2501,14 +2510,16 @@ uint16 Item::GetVisibleItemVisual(Player const* owner) const
void Item::AddBonuses(uint32 bonusListID)
{
- if (std::find(m_itemData->BonusListIDs->begin(), m_itemData->BonusListIDs->end(), int32(bonusListID)) != m_itemData->BonusListIDs->end())
+ if (std::find(GetBonusListIDs().begin(), GetBonusListIDs().end(), int32(bonusListID)) != GetBonusListIDs().end())
return;
if (DB2Manager::ItemBonusList const* bonuses = sDB2Manager.GetItemBonusList(bonusListID))
{
- std::vector<int32> bonusListIDs = m_itemData->BonusListIDs;
- bonusListIDs.push_back(bonusListID);
- SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::BonusListIDs), std::move(bonusListIDs));
+ WorldPackets::Item::ItemBonusKey itemBonusKey;
+ itemBonusKey.ItemID = GetEntry();
+ itemBonusKey.BonusListIDs = GetBonusListIDs();
+ itemBonusKey.BonusListIDs.push_back(bonusListID);
+ SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::ItemBonusKey), std::move(itemBonusKey));
for (ItemBonusEntry const* bonus : *bonuses)
_bonusData.AddBonus(bonus->Type, bonus->Value);
SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::ItemAppearanceModID), _bonusData.AppearanceModID);
@@ -2517,9 +2528,12 @@ void Item::AddBonuses(uint32 bonusListID)
void Item::SetBonuses(std::vector<int32> bonusListIDs)
{
- SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::BonusListIDs), std::move(bonusListIDs));
+ WorldPackets::Item::ItemBonusKey itemBonusKey;
+ itemBonusKey.ItemID = GetEntry();
+ itemBonusKey.BonusListIDs = std::move(bonusListIDs);
+ SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::ItemBonusKey), std::move(itemBonusKey));
- for (int32 bonusListID : *m_itemData->BonusListIDs)
+ for (int32 bonusListID : GetBonusListIDs())
_bonusData.AddBonusList(bonusListID);
SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::ItemAppearanceModID), _bonusData.AppearanceModID);
@@ -2527,7 +2541,9 @@ void Item::SetBonuses(std::vector<int32> bonusListIDs)
void Item::ClearBonuses()
{
- SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::BonusListIDs), std::vector<int32>());
+ WorldPackets::Item::ItemBonusKey itemBonusKey;
+ itemBonusKey.ItemID = GetEntry();
+ SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::ItemBonusKey), std::move(itemBonusKey));
_bonusData.Initialize(GetTemplate());
SetUpdateFieldValue(m_values.ModifyValue(&Item::m_itemData).ModifyValue(&UF::ItemData::ItemAppearanceModID), _bonusData.AppearanceModID);
}
diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h
index 6a778e0fe65..565c51fd34f 100644
--- a/src/server/game/Entities/Item/Item.h
+++ b/src/server/game/Entities/Item/Item.h
@@ -226,6 +226,7 @@ class TC_GAME_API Item : public Object
void CheckArtifactRelicSlotUnlock(Player const* owner);
void AddBonuses(uint32 bonusListID);
+ std::vector<int32> const& GetBonusListIDs() const { return m_itemData->ItemBonusKey->BonusListIDs; }
void SetBonuses(std::vector<int32> bonusListIDs);
void ClearBonuses();
diff --git a/src/server/game/Entities/Item/ItemDefines.h b/src/server/game/Entities/Item/ItemDefines.h
index d3b65653d1f..318b78c8d00 100644
--- a/src/server/game/Entities/Item/ItemDefines.h
+++ b/src/server/game/Entities/Item/ItemDefines.h
@@ -136,6 +136,11 @@ enum InventoryResult : uint8
EQUIP_ERR_NOT_IN_NPE = 110,// Not available during the tutorial
EQUIP_ERR_ITEM_COOLDOWN = 111,// Item is not ready yet.
EQUIP_ERR_NOT_IN_RATED_BATTLEGROUND = 112,// You can't do that in a rated battleground.
+ EQUIP_ERR_EQUIPABLESPELLS_SLOTS_FULL = 113,
+ EQUIP_ERR_CANT_BE_RECRAFTED = 114,// You can't recraft that itemv
+ EQUIP_ERR_REAGENTBAG_WRONG_SLOT = 115,// Reagent Bags can only be placed in the reagent bag slot.
+ EQUIP_ERR_SLOT_ONLY_REAGENTBAG = 116,// Only Reagent Bags can be placed in the reagent bag slot.
+ EQUIP_ERR_REAGENTBAG_ITEM_TYPE = 117,// Only Reagents can be placed in Reagent Bags.
};
// EnumUtils: DESCRIBE THIS
diff --git a/src/server/game/Entities/Item/ItemTemplate.h b/src/server/game/Entities/Item/ItemTemplate.h
index d2fa2029fa8..842dbe2f4bb 100644
--- a/src/server/game/Entities/Item/ItemTemplate.h
+++ b/src/server/game/Entities/Item/ItemTemplate.h
@@ -402,10 +402,16 @@ enum InventoryType : uint8
INVTYPE_THROWN = 25,
INVTYPE_RANGEDRIGHT = 26,
INVTYPE_QUIVER = 27,
- INVTYPE_RELIC = 28
+ INVTYPE_RELIC = 28,
+ INVTYPE_PROFESSION_TOOL = 29,
+ INVTYPE_PROFESSION_GEAR = 30,
+ INVTYPE_EQUIPABLE_SPELL_OFFENSIVE = 31,
+ INVTYPE_EQUIPABLE_SPELL_UTILITY = 32,
+ INVTYPE_EQUIPABLE_SPELL_DEFENSIVE = 33,
+ INVTYPE_EQUIPABLE_SPELL_MOBILITY = 34
};
-#define MAX_INVTYPE 29
+#define MAX_INVTYPE 35
enum ItemClass : uint8
{
@@ -427,10 +433,11 @@ enum ItemClass : uint8
ITEM_CLASS_MISCELLANEOUS = 15,
ITEM_CLASS_GLYPH = 16,
ITEM_CLASS_BATTLE_PETS = 17,
- ITEM_CLASS_WOW_TOKEN = 18
+ ITEM_CLASS_WOW_TOKEN = 18,
+ ITEM_CLASS_PROFESSION = 19
};
-#define MAX_ITEM_CLASS 19
+#define MAX_ITEM_CLASS 20
enum ItemSubclassConsumable
{
@@ -460,10 +467,11 @@ enum ItemSubclassContainer
ITEM_SUBCLASS_LEATHERWORKING_CONTAINER = 7,
ITEM_SUBCLASS_INSCRIPTION_CONTAINER = 8,
ITEM_SUBCLASS_TACKLE_CONTAINER = 9,
- ITEM_SUBCLASS_COOKING_CONTAINER = 10
+ ITEM_SUBCLASS_COOKING_CONTAINER = 10,
+ ITEM_SUBCLASS_REAGENT_CONTAINER = 11
};
-#define MAX_ITEM_SUBCLASS_CONTAINER 11
+#define MAX_ITEM_SUBCLASS_CONTAINER 12
enum ItemSubclassWeapon
{
@@ -535,10 +543,11 @@ enum ItemSubclassArmor
enum ItemSubclassReagent
{
ITEM_SUBCLASS_REAGENT = 0,
- ITEM_SUBCLASS_KEYSTONE = 1
+ ITEM_SUBCLASS_KEYSTONE = 1,
+ ITEM_SUBCLASS_CONTEXT_TOKEN = 2
};
-#define MAX_ITEM_SUBCLASS_REAGENT 2
+#define MAX_ITEM_SUBCLASS_REAGENT 3
enum ItemSubclassProjectile
{
@@ -570,10 +579,12 @@ enum ItemSubclassTradeGoods
ITEM_SUBCLASS_ENCHANTMENT = 14,
ITEM_SUBCLASS_WEAPON_ENCHANTMENT = 15,
ITEM_SUBCLASS_INSCRIPTION = 16,
- ITEM_SUBCLASS_EXPLOSIVES_DEVICES = 17
+ ITEM_SUBCLASS_EXPLOSIVES_DEVICES = 17,
+ ITEM_SUBCLASS_OPTIONAL_REAGENT = 18,
+ ITEM_SUBCLASS_FINISHING_REAGENT = 19,
};
-#define MAX_ITEM_SUBCLASS_TRADE_GOODS 18
+#define MAX_ITEM_SUBCLASS_TRADE_GOODS 20
enum ItemSubclassItemEnhancement
{
@@ -590,10 +601,11 @@ enum ItemSubclassItemEnhancement
ITEM_SUBCLASS_ITEM_ENHANCEMENT_FINGER = 10,
ITEM_SUBCLASS_ITEM_ENHANCEMENT_WEAPON = 11,
ITEM_SUBCLASS_ITEM_ENHANCEMENT_TWO_HANDED_WEAPON = 12,
- ITEM_SUBCLASS_ITEM_ENHANCEMENT_SHIELD_OFF_HAND = 13
+ ITEM_SUBCLASS_ITEM_ENHANCEMENT_SHIELD_OFF_HAND = 13,
+ ITEM_SUBCLASS_ITEM_ENHANCEMENT_MISC = 14
};
-#define MAX_ITEM_SUBCLASS_ITEM_ENHANCEMENT 14
+#define MAX_ITEM_SUBCLASS_ITEM_ENHANCEMENT 15
enum ItemSubclassRecipe
{
@@ -662,9 +674,10 @@ enum ItemSubclassJunk
ITEM_SUBCLASS_MISCELLANEOUS_HOLIDAY = 3,
ITEM_SUBCLASS_MISCELLANEOUS_OTHER = 4,
ITEM_SUBCLASS_MISCELLANEOUS_MOUNT = 5,
+ ITEM_SUBCLASS_MISCELLANEOUS_MOUNT_EQUIPMENT = 6
};
-#define MAX_ITEM_SUBCLASS_MISCELLANEOUS 6
+#define MAX_ITEM_SUBCLASS_MISCELLANEOUS 7
enum ItemSubclassGlyph
{
@@ -698,6 +711,26 @@ enum ItemSubclassWowToken
#define MAX_ITEM_SUBCLASS_WOW_TOKEN 1
+enum ItemSubclassPorfession
+{
+ ITEM_SUBCLASS_PROFESSION_BLACKSMITHING = 0,
+ ITEM_SUBCLASS_PROFESSION_LEATHERWORKING = 1,
+ ITEM_SUBCLASS_PROFESSION_ALCHEMY = 2,
+ ITEM_SUBCLASS_PROFESSION_HERBALISM = 3,
+ ITEM_SUBCLASS_PROFESSION_COOKING = 4,
+ ITEM_SUBCLASS_PROFESSION_MINING = 5,
+ ITEM_SUBCLASS_PROFESSION_TAILORING = 6,
+ ITEM_SUBCLASS_PROFESSION_ENGINEERING = 7,
+ ITEM_SUBCLASS_PROFESSION_ENCHANTING = 8,
+ ITEM_SUBCLASS_PROFESSION_FISHING = 9,
+ ITEM_SUBCLASS_PROFESSION_SKINNING = 10,
+ ITEM_SUBCLASS_PROFESSION_JEWELCRAFTING = 11,
+ ITEM_SUBCLASS_PROFESSION_INSCRIPTION = 12,
+ ITEM_SUBCLASS_PROFESSION_ARCHAEOLOGY = 13
+};
+
+#define MAX_ITEM_SUBCLASS_PROFESSION 14
+
const uint32 MaxItemSubclassValues[MAX_ITEM_CLASS] =
{
MAX_ITEM_SUBCLASS_CONSUMABLE,
@@ -718,7 +751,8 @@ const uint32 MaxItemSubclassValues[MAX_ITEM_CLASS] =
MAX_ITEM_SUBCLASS_MISCELLANEOUS,
MAX_ITEM_SUBCLASS_GLYPH,
MAX_ITEM_SUBCLASS_BATTLE_PET,
- MAX_ITEM_SUBCLASS_WOW_TOKEN
+ MAX_ITEM_SUBCLASS_WOW_TOKEN,
+ MAX_ITEM_SUBCLASS_PROFESSION
};
#define MAX_ITEM_SUBCLASS_TOTAL 21
diff --git a/src/server/game/Entities/Item/enuminfo_ItemDefines.cpp b/src/server/game/Entities/Item/enuminfo_ItemDefines.cpp
index e52b1abcc88..d186091229b 100644
--- a/src/server/game/Entities/Item/enuminfo_ItemDefines.cpp
+++ b/src/server/game/Entities/Item/enuminfo_ItemDefines.cpp
@@ -144,12 +144,17 @@ TC_API_EXPORT EnumText EnumUtils<InventoryResult>::ToString(InventoryResult valu
case EQUIP_ERR_NOT_IN_NPE: return { "EQUIP_ERR_NOT_IN_NPE", "EQUIP_ERR_NOT_IN_NPE", "Not available during the tutorial" };
case EQUIP_ERR_ITEM_COOLDOWN: return { "EQUIP_ERR_ITEM_COOLDOWN", "EQUIP_ERR_ITEM_COOLDOWN", "Item is not ready yet." };
case EQUIP_ERR_NOT_IN_RATED_BATTLEGROUND: return { "EQUIP_ERR_NOT_IN_RATED_BATTLEGROUND", "EQUIP_ERR_NOT_IN_RATED_BATTLEGROUND", "You can't do that in a rated battleground." };
+ case EQUIP_ERR_EQUIPABLESPELLS_SLOTS_FULL: return { "EQUIP_ERR_EQUIPABLESPELLS_SLOTS_FULL", "EQUIP_ERR_EQUIPABLESPELLS_SLOTS_FULL", "" };
+ case EQUIP_ERR_CANT_BE_RECRAFTED: return { "EQUIP_ERR_CANT_BE_RECRAFTED", "EQUIP_ERR_CANT_BE_RECRAFTED", "You can't recraft that itemv" };
+ case EQUIP_ERR_REAGENTBAG_WRONG_SLOT: return { "EQUIP_ERR_REAGENTBAG_WRONG_SLOT", "EQUIP_ERR_REAGENTBAG_WRONG_SLOT", "Reagent Bags can only be placed in the reagent bag slot." };
+ case EQUIP_ERR_SLOT_ONLY_REAGENTBAG: return { "EQUIP_ERR_SLOT_ONLY_REAGENTBAG", "EQUIP_ERR_SLOT_ONLY_REAGENTBAG", "Only Reagent Bags can be placed in the reagent bag slot." };
+ case EQUIP_ERR_REAGENTBAG_ITEM_TYPE: return { "EQUIP_ERR_REAGENTBAG_ITEM_TYPE", "EQUIP_ERR_REAGENTBAG_ITEM_TYPE", "Only Reagents can be placed in Reagent Bags." };
default: throw std::out_of_range("value");
}
}
template <>
-TC_API_EXPORT size_t EnumUtils<InventoryResult>::Count() { return 113; }
+TC_API_EXPORT size_t EnumUtils<InventoryResult>::Count() { return 118; }
template <>
TC_API_EXPORT InventoryResult EnumUtils<InventoryResult>::FromIndex(size_t index)
@@ -269,6 +274,11 @@ TC_API_EXPORT InventoryResult EnumUtils<InventoryResult>::FromIndex(size_t index
case 110: return EQUIP_ERR_NOT_IN_NPE;
case 111: return EQUIP_ERR_ITEM_COOLDOWN;
case 112: return EQUIP_ERR_NOT_IN_RATED_BATTLEGROUND;
+ case 113: return EQUIP_ERR_EQUIPABLESPELLS_SLOTS_FULL;
+ case 114: return EQUIP_ERR_CANT_BE_RECRAFTED;
+ case 115: return EQUIP_ERR_REAGENTBAG_WRONG_SLOT;
+ case 116: return EQUIP_ERR_SLOT_ONLY_REAGENTBAG;
+ case 117: return EQUIP_ERR_REAGENTBAG_ITEM_TYPE;
default: throw std::out_of_range("index");
}
}
@@ -391,6 +401,11 @@ TC_API_EXPORT size_t EnumUtils<InventoryResult>::ToIndex(InventoryResult value)
case EQUIP_ERR_NOT_IN_NPE: return 110;
case EQUIP_ERR_ITEM_COOLDOWN: return 111;
case EQUIP_ERR_NOT_IN_RATED_BATTLEGROUND: return 112;
+ case EQUIP_ERR_EQUIPABLESPELLS_SLOTS_FULL: return 113;
+ case EQUIP_ERR_CANT_BE_RECRAFTED: return 114;
+ case EQUIP_ERR_REAGENTBAG_WRONG_SLOT: return 115;
+ case EQUIP_ERR_SLOT_ONLY_REAGENTBAG: return 116;
+ case EQUIP_ERR_REAGENTBAG_ITEM_TYPE: return 117;
default: throw std::out_of_range("value");
}
}
diff --git a/src/server/game/Entities/Object/MovementInfo.h b/src/server/game/Entities/Object/MovementInfo.h
index 15b4af8ebfa..9e8c3909b36 100644
--- a/src/server/game/Entities/Object/MovementInfo.h
+++ b/src/server/game/Entities/Object/MovementInfo.h
@@ -60,9 +60,9 @@ struct MovementInfo
struct Inertia
{
- Inertia() : lifetime(0) { }
+ Inertia() : id(0), lifetime(0) { }
- ObjectGuid guid;
+ int32 id;
Position force;
uint32 lifetime;
};
@@ -86,6 +86,15 @@ struct MovementInfo
float stepUpStartElevation;
+ // advflying
+ struct AdvFlying
+ {
+ float forwardVelocity;
+ float upVelocity;
+ };
+
+ Optional<AdvFlying> advFlying;
+
MovementInfo() :
flags(0), flags2(0), flags3(0), time(0), pitch(0.0f), stepUpStartElevation(0.0f)
{
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 1059e2d7686..cca7c5fe890 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -293,6 +293,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe
bool HasFall = HasFallDirection || unit->m_movementInfo.jump.fallTime != 0;
bool HasSpline = unit->IsSplineEnabled();
bool HasInertia = unit->m_movementInfo.inertia.has_value();
+ bool HasAdvFlying = unit->m_movementInfo.advFlying.has_value();
*data << GetGUID(); // MoverGUID
@@ -321,17 +322,24 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe
data->WriteBit(false); // HeightChangeFailed
data->WriteBit(false); // RemoteTimeValid
data->WriteBit(HasInertia); // HasInertia
+ data->WriteBit(HasAdvFlying); // HasAdvFlying
if (!unit->m_movementInfo.transport.guid.IsEmpty())
*data << unit->m_movementInfo.transport;
if (HasInertia)
{
- *data << unit->m_movementInfo.inertia->guid;
+ *data << unit->m_movementInfo.inertia->id;
*data << unit->m_movementInfo.inertia->force.PositionXYZStream();
*data << uint32(unit->m_movementInfo.inertia->lifetime);
}
+ if (HasAdvFlying)
+ {
+ *data << float(unit->m_movementInfo.advFlying->forwardVelocity);
+ *data << float(unit->m_movementInfo.advFlying->upVelocity);
+ }
+
if (HasFall)
{
*data << uint32(unit->m_movementInfo.jump.fallTime); // Time
@@ -366,6 +374,24 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe
*data << float(1.0f); // MovementForcesModMagnitude
}
+ *data << float(2.0f); // advFlyingAirFriction
+ *data << float(65.0f); // advFlyingMaxVel
+ *data << float(1.0f); // advFlyingLiftCoefficient
+ *data << float(3.0f); // advFlyingDoubleJumpVelMod
+ *data << float(10.0f); // advFlyingGlideStartMinHeight
+ *data << float(100.0f); // advFlyingAddImpulseMaxSpeed
+ *data << float(90.0f); // advFlyingMinBankingRate
+ *data << float(140.0f); // advFlyingMaxBankingRate
+ *data << float(180.0f); // advFlyingMinPitchingRateDown
+ *data << float(360.0f); // advFlyingMaxPitchingRateDown
+ *data << float(90.0f); // advFlyingMinPitchingRateUp
+ *data << float(270.0f); // advFlyingMaxPitchingRateUp
+ *data << float(30.0f); // advFlyingMinTurnVelocityThreshold
+ *data << float(80.0f); // advFlyingMaxTurnVelocityThreshold
+ *data << float(2.75f); // advFlyingSurfaceFriction
+ *data << float(7.0f); // advFlyingOverMaxDeceleration
+ *data << float(0.4f); // advFlyingLaunchSpeedCoefficient
+
data->WriteBit(HasSpline);
data->FlushBits();
@@ -438,6 +464,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe
bool hasFaceMovementDir = areaTriggerTemplate && areaTrigger->GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_FACE_MOVEMENT_DIR);
bool hasFollowsTerrain = areaTriggerTemplate && areaTrigger->GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_FOLLOWS_TERRAIN);
bool hasUnk1 = areaTriggerTemplate && areaTrigger->GetTemplate()->HasFlag(AREATRIGGER_FLAG_UNK1);
+ bool hasUnk2 = false;
bool hasTargetRollPitchYaw = areaTriggerTemplate && areaTrigger->GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_TARGET_ROLL_PITCH_YAW);
bool hasScaleCurveID = createProperties && createProperties->ScaleCurveId != 0;
bool hasMorphCurveID = createProperties && createProperties->MorphCurveId != 0;
@@ -448,6 +475,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe
bool hasAreaTriggerPolygon = createProperties && shape.IsPolygon();
bool hasAreaTriggerCylinder = shape.IsCylinder();
bool hasDisk = shape.IsDisk();
+ bool hasBoundedPlane = shape.IsBoudedPlane();
bool hasAreaTriggerSpline = areaTrigger->HasSplines();
bool hasOrbit = areaTrigger->HasOrbit();
bool hasMovementScript = false;
@@ -458,6 +486,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe
data->WriteBit(hasFaceMovementDir);
data->WriteBit(hasFollowsTerrain);
data->WriteBit(hasUnk1);
+ data->WriteBit(hasUnk2);
data->WriteBit(hasTargetRollPitchYaw);
data->WriteBit(hasScaleCurveID);
data->WriteBit(hasMorphCurveID);
@@ -468,6 +497,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe
data->WriteBit(hasAreaTriggerPolygon);
data->WriteBit(hasAreaTriggerCylinder);
data->WriteBit(hasDisk);
+ data->WriteBit(hasBoundedPlane);
data->WriteBit(hasAreaTriggerSpline);
data->WriteBit(hasOrbit);
data->WriteBit(hasMovementScript);
@@ -549,6 +579,14 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags, Playe
*data << float(shape.DiskDatas.LocationZOffsetTarget);
}
+ if (hasBoundedPlane)
+ {
+ *data << float(shape.BoundedPlaneDatas.Extents[0]);
+ *data << float(shape.BoundedPlaneDatas.Extents[1]);
+ *data << float(shape.BoundedPlaneDatas.ExtentsTarget[0]);
+ *data << float(shape.BoundedPlaneDatas.ExtentsTarget[1]);
+ }
+
//if (hasMovementScript)
// *data << *areaTrigger->GetMovementScript(); // AreaTriggerMovementScriptInfo
@@ -2300,10 +2338,10 @@ int32 WorldObject::ModSpellDuration(SpellInfo const* spellInfo, WorldObject cons
if (!positive)
{
- int32 mechanicMask = spellInfo->GetSpellMechanicMaskByEffectMask(effectMask);
+ uint64 mechanicMask = spellInfo->GetSpellMechanicMaskByEffectMask(effectMask);
auto mechanicCheck = [mechanicMask](AuraEffect const* aurEff) -> bool
{
- if (mechanicMask & (1 << aurEff->GetMiscValue()))
+ if (mechanicMask & (UI64LIT(1) << aurEff->GetMiscValue()))
return true;
return false;
};
diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.cpp b/src/server/game/Entities/Object/Updates/UpdateFields.cpp
index c38670e91ff..1b7632da868 100644
--- a/src/server/game/Entities/Object/Updates/UpdateFields.cpp
+++ b/src/server/game/Entities/Object/Updates/UpdateFields.cpp
@@ -268,11 +268,6 @@ void SocketedGem::ClearChangesMask()
void ItemData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Item const* owner, Player const* receiver) const
{
- data << uint32(BonusListIDs->size());
- for (uint32 i = 0; i < BonusListIDs->size(); ++i)
- {
- data << int32((*BonusListIDs)[i]);
- }
data << Owner;
data << ContainedIn;
data << Creator;
@@ -309,6 +304,10 @@ void ItemData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisi
if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner))
{
data << uint32(DynamicFlags2);
+ }
+ data << ItemBonusKey;
+ if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner))
+ {
data << uint16(DEBUGItemLevel);
}
for (uint32 i = 0; i < ArtifactPowers.size(); ++i)
@@ -324,7 +323,7 @@ void ItemData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisi
void ItemData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Item const* owner, Player const* receiver) const
{
- Mask allowedMaskForTarget({ 0xF804E4FFu, 0x000001FFu });
+ Mask allowedMaskForTarget({ 0xF80A727Fu, 0x000001FFu });
AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags);
WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver);
}
@@ -332,12 +331,12 @@ void ItemData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisi
void ItemData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags)
{
if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner))
- allowedMaskForTarget |= { 0x07FB1B00u, 0x00000000u };
+ allowedMaskForTarget |= { 0x07F58D80u, 0x00000000u };
}
void ItemData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags)
{
- Mask allowedMaskForTarget({ 0xF804E4FFu, 0x000001FFu });
+ Mask allowedMaskForTarget({ 0xF80A727Fu, 0x000001FFu });
AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags);
changesMask &= allowedMaskForTarget;
}
@@ -353,24 +352,12 @@ void ItemData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignor
{
if (changesMask[1])
{
- data.WriteBits(BonusListIDs->size(), 32);
- for (uint32 i = 0; i < BonusListIDs->size(); ++i)
- {
- data << int32((*BonusListIDs)[i]);
- }
- }
- }
- data.FlushBits();
- if (changesMask[0])
- {
- if (changesMask[2])
- {
if (!ignoreNestedChangesMask)
ArtifactPowers.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(ArtifactPowers.size(), data);
}
- if (changesMask[3])
+ if (changesMask[2])
{
if (!ignoreNestedChangesMask)
Gems.WriteUpdateMask(data);
@@ -381,7 +368,7 @@ void ItemData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignor
data.FlushBits();
if (changesMask[0])
{
- if (changesMask[2])
+ if (changesMask[1])
{
for (uint32 i = 0; i < ArtifactPowers.size(); ++i)
{
@@ -391,7 +378,7 @@ void ItemData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignor
}
}
}
- if (changesMask[3])
+ if (changesMask[2])
{
for (uint32 i = 0; i < Gems.size(); ++i)
{
@@ -401,71 +388,75 @@ void ItemData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignor
}
}
}
- if (changesMask[4])
+ if (changesMask[3])
{
data << Owner;
}
- if (changesMask[5])
+ if (changesMask[4])
{
data << ContainedIn;
}
- if (changesMask[6])
+ if (changesMask[5])
{
data << Creator;
}
- if (changesMask[7])
+ if (changesMask[6])
{
data << GiftCreator;
}
- if (changesMask[8])
+ if (changesMask[7])
{
data << uint32(StackCount);
}
- if (changesMask[9])
+ if (changesMask[8])
{
data << uint32(Expiration);
}
- if (changesMask[10])
+ if (changesMask[9])
{
data << uint32(DynamicFlags);
}
- if (changesMask[11])
+ if (changesMask[10])
{
data << uint32(Durability);
}
- if (changesMask[12])
+ if (changesMask[11])
{
data << uint32(MaxDurability);
}
- if (changesMask[13])
+ if (changesMask[12])
{
data << uint32(CreatePlayedTime);
}
- if (changesMask[14])
+ if (changesMask[13])
{
data << int32(Context);
}
- if (changesMask[15])
+ if (changesMask[14])
{
data << int64(CreateTime);
}
- if (changesMask[16])
+ if (changesMask[15])
{
data << uint64(ArtifactXP);
}
- if (changesMask[17])
+ if (changesMask[16])
{
data << uint8(ItemAppearanceModID);
}
- if (changesMask[19])
+ if (changesMask[18])
{
data << uint32(DynamicFlags2);
}
+ if (changesMask[19])
+ {
+ data << ItemBonusKey;
+ }
if (changesMask[20])
{
data << uint16(DEBUGItemLevel);
}
- if (changesMask[18])
+ if (changesMask[17])
{
Modifiers->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
}
@@ -494,7 +485,6 @@ void ItemData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignor
void ItemData::ClearChangesMask()
{
- Base::ClearChangesMask(BonusListIDs);
Base::ClearChangesMask(ArtifactPowers);
Base::ClearChangesMask(Gems);
Base::ClearChangesMask(Owner);
@@ -513,6 +503,7 @@ void ItemData::ClearChangesMask()
Base::ClearChangesMask(ItemAppearanceModID);
Base::ClearChangesMask(Modifiers);
Base::ClearChangesMask(DynamicFlags2);
+ Base::ClearChangesMask(ItemBonusKey);
Base::ClearChangesMask(DEBUGItemLevel);
Base::ClearChangesMask(SpellCharges);
Base::ClearChangesMask(Enchantment);
@@ -968,6 +959,7 @@ void UnitData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisi
data << BattlePetCompanionGUID;
data << uint64(BattlePetDBID);
ChannelData->WriteCreate(data, owner, receiver);
+ data << int8(SpellEmpowerStage);
data << uint32(SummonedByHomeRealm);
data << uint8(Race);
data << uint8(ClassId);
@@ -1120,6 +1112,7 @@ void UnitData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisi
data << uint32(PassiveSpells.size());
data << uint32(WorldEffects.size());
data << uint32(ChannelObjects.size());
+ data << int32(FlightCapabilityID);
data << uint32(SilencedSchoolMask);
data << NameplateAttachToGUID;
for (uint32 i = 0; i < PassiveSpells.size(); ++i)
@@ -1138,7 +1131,7 @@ void UnitData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisi
void UnitData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Unit const* owner, Player const* receiver) const
{
- Mask allowedMaskForTarget({ 0xFFFFDFFFu, 0xE1FF7FFFu, 0x001EFFFFu, 0xFFFFFF81u, 0x7F0003FFu, 0x00000000u, 0x00000000u });
+ Mask allowedMaskForTarget({ 0xFFFFDFFFu, 0xC3FEFFFFu, 0x003DFFFFu, 0xFFFFFF01u, 0xFC000FFFu, 0x00000001u, 0x00000000u });
AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags);
WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver);
}
@@ -1146,16 +1139,16 @@ void UnitData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisi
void UnitData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags)
{
if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner))
- allowedMaskForTarget |= { 0x00002000u, 0x1E008000u, 0xFFE10000u, 0x0800007Eu, 0x80FFFC00u, 0xFFFFFFFFu, 0x00000003u };
+ allowedMaskForTarget |= { 0x00002000u, 0x3C010000u, 0xFFC20000u, 0x200000FEu, 0x03FFF000u, 0xFFFFFFFEu, 0x0000000Fu };
if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::UnitAll))
- allowedMaskForTarget |= { 0x00000000u, 0x00000000u, 0x00000000u, 0x08000000u, 0x00FFFC00u, 0x00000000u, 0x00000000u };
+ allowedMaskForTarget |= { 0x00000000u, 0x00000000u, 0x00000000u, 0x20000000u, 0x03FFF000u, 0x00000000u, 0x00000000u };
if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Empath))
- allowedMaskForTarget |= { 0x00000000u, 0x1E000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x000FF000u, 0x00000000u };
+ allowedMaskForTarget |= { 0x00000000u, 0x3C000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x003FC000u, 0x00000000u };
}
void UnitData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags)
{
- Mask allowedMaskForTarget({ 0xFFFFDFFFu, 0xE1FF7FFFu, 0x001EFFFFu, 0xFFFFFF81u, 0x7F0003FFu, 0x00000000u, 0x00000000u });
+ Mask allowedMaskForTarget({ 0xFFFFDFFFu, 0xC3FEFFFFu, 0x003DFFFFu, 0xFFFFFF01u, 0xFC000FFFu, 0x00000001u, 0x00000000u });
AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags);
changesMask &= allowedMaskForTarget;
}
@@ -1310,473 +1303,481 @@ void UnitData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignor
}
if (changesMask[23])
{
- data << uint32(SummonedByHomeRealm);
+ data << int8(SpellEmpowerStage);
}
if (changesMask[24])
{
- data << uint8(Race);
+ data << uint32(SummonedByHomeRealm);
}
if (changesMask[25])
{
- data << uint8(ClassId);
+ data << uint8(Race);
}
if (changesMask[26])
{
- data << uint8(PlayerClassId);
+ data << uint8(ClassId);
}
if (changesMask[27])
{
- data << uint8(Sex);
+ data << uint8(PlayerClassId);
}
if (changesMask[28])
{
- data << uint8(DisplayPower);
+ data << uint8(Sex);
}
if (changesMask[29])
{
- data << uint32(OverrideDisplayPowerID);
+ data << uint8(DisplayPower);
}
if (changesMask[30])
{
- data << int64(Health);
+ data << uint32(OverrideDisplayPowerID);
}
if (changesMask[31])
{
- data << int64(MaxHealth);
+ data << int64(Health);
}
}
if (changesMask[32])
{
if (changesMask[33])
{
- data << int32(Level);
+ data << int64(MaxHealth);
}
if (changesMask[34])
{
- data << int32(EffectiveLevel);
+ data << int32(Level);
}
if (changesMask[35])
{
- data << int32(ContentTuningID);
+ data << int32(EffectiveLevel);
}
if (changesMask[36])
{
- data << int32(ScalingLevelMin);
+ data << int32(ContentTuningID);
}
if (changesMask[37])
{
- data << int32(ScalingLevelMax);
+ data << int32(ScalingLevelMin);
}
if (changesMask[38])
{
- data << int32(ScalingLevelDelta);
+ data << int32(ScalingLevelMax);
}
if (changesMask[39])
{
- data << int32(ScalingFactionGroup);
+ data << int32(ScalingLevelDelta);
}
if (changesMask[40])
{
- data << int32(ScalingHealthItemLevelCurveID);
+ data << int32(ScalingFactionGroup);
}
if (changesMask[41])
{
- data << int32(ScalingDamageItemLevelCurveID);
+ data << int32(ScalingHealthItemLevelCurveID);
}
if (changesMask[42])
{
- data << int32(ViewerDependentValue<FactionTemplateTag>::GetValue(this, owner, receiver));
+ data << int32(ScalingDamageItemLevelCurveID);
}
if (changesMask[43])
{
- data << uint32(ViewerDependentValue<FlagsTag>::GetValue(this, owner, receiver));
+ data << int32(ViewerDependentValue<FactionTemplateTag>::GetValue(this, owner, receiver));
}
if (changesMask[44])
{
- data << uint32(Flags2);
+ data << uint32(ViewerDependentValue<FlagsTag>::GetValue(this, owner, receiver));
}
if (changesMask[45])
{
- data << uint32(ViewerDependentValue<Flags3Tag>::GetValue(this, owner, receiver));
+ data << uint32(Flags2);
}
if (changesMask[46])
{
- data << uint32(ViewerDependentValue<AuraStateTag>::GetValue(this, owner, receiver));
+ data << uint32(ViewerDependentValue<Flags3Tag>::GetValue(this, owner, receiver));
}
if (changesMask[47])
{
- data << uint32(RangedAttackRoundBaseTime);
+ data << uint32(ViewerDependentValue<AuraStateTag>::GetValue(this, owner, receiver));
}
if (changesMask[48])
{
- data << float(BoundingRadius);
+ data << uint32(RangedAttackRoundBaseTime);
}
if (changesMask[49])
{
- data << float(CombatReach);
+ data << float(BoundingRadius);
}
if (changesMask[50])
{
- data << float(DisplayScale);
+ data << float(CombatReach);
}
if (changesMask[51])
{
- data << int32(CreatureFamily);
+ data << float(DisplayScale);
}
if (changesMask[52])
{
- data << int32(CreatureType);
+ data << int32(CreatureFamily);
}
if (changesMask[53])
{
- data << int32(NativeDisplayID);
+ data << int32(CreatureType);
}
if (changesMask[54])
{
- data << float(NativeXDisplayScale);
+ data << int32(NativeDisplayID);
}
if (changesMask[55])
{
- data << int32(MountDisplayID);
+ data << float(NativeXDisplayScale);
}
if (changesMask[56])
{
- data << int32(CosmeticMountDisplayID);
+ data << int32(MountDisplayID);
}
if (changesMask[57])
{
- data << float(MinDamage);
+ data << int32(CosmeticMountDisplayID);
}
if (changesMask[58])
{
- data << float(MaxDamage);
+ data << float(MinDamage);
}
if (changesMask[59])
{
- data << float(MinOffHandDamage);
+ data << float(MaxDamage);
}
if (changesMask[60])
{
- data << float(MaxOffHandDamage);
+ data << float(MinOffHandDamage);
}
if (changesMask[61])
{
- data << uint8(StandState);
+ data << float(MaxOffHandDamage);
}
if (changesMask[62])
{
- data << uint8(PetTalentPoints);
+ data << uint8(StandState);
}
if (changesMask[63])
{
- data << uint8(VisFlags);
+ data << uint8(PetTalentPoints);
}
}
if (changesMask[64])
{
if (changesMask[65])
{
- data << uint8(AnimTier);
+ data << uint8(VisFlags);
}
if (changesMask[66])
{
- data << uint32(PetNumber);
+ data << uint8(AnimTier);
}
if (changesMask[67])
{
- data << uint32(PetNameTimestamp);
+ data << uint32(PetNumber);
}
if (changesMask[68])
{
- data << uint32(PetExperience);
+ data << uint32(PetNameTimestamp);
}
if (changesMask[69])
{
- data << uint32(PetNextLevelExperience);
+ data << uint32(PetExperience);
}
if (changesMask[70])
{
- data << float(ModCastingSpeed);
+ data << uint32(PetNextLevelExperience);
}
if (changesMask[71])
{
- data << float(ModCastingSpeedNeg);
+ data << float(ModCastingSpeed);
}
if (changesMask[72])
{
- data << float(ModSpellHaste);
+ data << float(ModCastingSpeedNeg);
}
if (changesMask[73])
{
- data << float(ModHaste);
+ data << float(ModSpellHaste);
}
if (changesMask[74])
{
- data << float(ModRangedHaste);
+ data << float(ModHaste);
}
if (changesMask[75])
{
- data << float(ModHasteRegen);
+ data << float(ModRangedHaste);
}
if (changesMask[76])
{
- data << float(ModTimeRate);
+ data << float(ModHasteRegen);
}
if (changesMask[77])
{
- data << int32(CreatedBySpell);
+ data << float(ModTimeRate);
}
if (changesMask[78])
{
- data << int32(EmoteState);
+ data << int32(CreatedBySpell);
}
if (changesMask[79])
{
- data << int32(BaseMana);
+ data << int32(EmoteState);
}
if (changesMask[80])
{
- data << int32(BaseHealth);
+ data << int32(BaseMana);
}
if (changesMask[81])
{
- data << uint8(SheatheState);
+ data << int32(BaseHealth);
}
if (changesMask[82])
{
- data << uint8(ViewerDependentValue<PvpFlagsTag>::GetValue(this, owner, receiver));
+ data << uint8(SheatheState);
}
if (changesMask[83])
{
- data << uint8(PetFlags);
+ data << uint8(ViewerDependentValue<PvpFlagsTag>::GetValue(this, owner, receiver));
}
if (changesMask[84])
{
- data << uint8(ShapeshiftForm);
+ data << uint8(PetFlags);
}
if (changesMask[85])
{
- data << int32(AttackPower);
+ data << uint8(ShapeshiftForm);
}
if (changesMask[86])
{
- data << int32(AttackPowerModPos);
+ data << int32(AttackPower);
}
if (changesMask[87])
{
- data << int32(AttackPowerModNeg);
+ data << int32(AttackPowerModPos);
}
if (changesMask[88])
{
- data << float(AttackPowerMultiplier);
+ data << int32(AttackPowerModNeg);
}
if (changesMask[89])
{
- data << int32(RangedAttackPower);
+ data << float(AttackPowerMultiplier);
}
if (changesMask[90])
{
- data << int32(RangedAttackPowerModPos);
+ data << int32(RangedAttackPower);
}
if (changesMask[91])
{
- data << int32(RangedAttackPowerModNeg);
+ data << int32(RangedAttackPowerModPos);
}
if (changesMask[92])
{
- data << float(RangedAttackPowerMultiplier);
+ data << int32(RangedAttackPowerModNeg);
}
if (changesMask[93])
{
- data << int32(MainHandWeaponAttackPower);
+ data << float(RangedAttackPowerMultiplier);
}
if (changesMask[94])
{
- data << int32(OffHandWeaponAttackPower);
+ data << int32(MainHandWeaponAttackPower);
}
if (changesMask[95])
{
- data << int32(RangedWeaponAttackPower);
+ data << int32(OffHandWeaponAttackPower);
}
}
if (changesMask[96])
{
if (changesMask[97])
{
- data << int32(SetAttackSpeedAura);
+ data << int32(RangedWeaponAttackPower);
}
if (changesMask[98])
{
- data << float(Lifesteal);
+ data << int32(SetAttackSpeedAura);
}
if (changesMask[99])
{
- data << float(MinRangedDamage);
+ data << float(Lifesteal);
}
if (changesMask[100])
{
- data << float(MaxRangedDamage);
+ data << float(MinRangedDamage);
}
if (changesMask[101])
{
- data << float(ManaCostMultiplier);
+ data << float(MaxRangedDamage);
}
if (changesMask[102])
{
- data << float(MaxHealthModifier);
+ data << float(ManaCostMultiplier);
}
if (changesMask[103])
{
- data << float(HoverHeight);
+ data << float(MaxHealthModifier);
}
if (changesMask[104])
{
- data << int32(MinItemLevelCutoff);
+ data << float(HoverHeight);
}
if (changesMask[105])
{
- data << int32(MinItemLevel);
+ data << int32(MinItemLevelCutoff);
}
if (changesMask[106])
{
- data << int32(MaxItemLevel);
+ data << int32(MinItemLevel);
}
if (changesMask[107])
{
- data << int32(AzeriteItemLevel);
+ data << int32(MaxItemLevel);
}
if (changesMask[108])
{
- data << int32(WildBattlePetLevel);
+ data << int32(AzeriteItemLevel);
}
if (changesMask[109])
{
- data << int32(BattlePetCompanionExperience);
+ data << int32(WildBattlePetLevel);
}
if (changesMask[110])
{
- data << uint32(BattlePetCompanionNameTimestamp);
+ data << int32(BattlePetCompanionExperience);
}
if (changesMask[111])
{
- data << int32(InteractSpellID);
+ data << uint32(BattlePetCompanionNameTimestamp);
}
if (changesMask[112])
{
- data << int32(ScaleDuration);
+ data << int32(InteractSpellID);
}
if (changesMask[113])
{
- data << int32(LooksLikeMountID);
+ data << int32(ScaleDuration);
}
if (changesMask[114])
{
- data << int32(LooksLikeCreatureID);
+ data << int32(LooksLikeMountID);
}
if (changesMask[115])
{
- data << int32(LookAtControllerID);
+ data << int32(LooksLikeCreatureID);
}
if (changesMask[116])
{
- data << int32(TaxiNodesID);
+ data << int32(LookAtControllerID);
}
if (changesMask[117])
{
- data << GuildGUID;
+ data << int32(TaxiNodesID);
}
if (changesMask[118])
{
- data << uint32(SilencedSchoolMask);
+ data << GuildGUID;
}
if (changesMask[119])
{
+ data << int32(FlightCapabilityID);
+ }
+ if (changesMask[120])
+ {
+ data << uint32(SilencedSchoolMask);
+ }
+ if (changesMask[121])
+ {
data << NameplateAttachToGUID;
}
}
- if (changesMask[120])
+ if (changesMask[122])
{
for (uint32 i = 0; i < 2; ++i)
{
- if (changesMask[121 + i])
+ if (changesMask[123 + i])
{
data << uint32(ViewerDependentValue<NpcFlagsTag>::GetValue(this, i, owner, receiver));
}
}
}
- if (changesMask[123])
+ if (changesMask[125])
{
for (uint32 i = 0; i < 7; ++i)
{
- if (changesMask[124 + i])
+ if (changesMask[126 + i])
{
data << int32(Power[i]);
}
- if (changesMask[131 + i])
+ if (changesMask[133 + i])
{
data << int32(MaxPower[i]);
}
- if (changesMask[138 + i])
+ if (changesMask[140 + i])
{
data << float(PowerRegenFlatModifier[i]);
}
- if (changesMask[145 + i])
+ if (changesMask[147 + i])
{
data << float(PowerRegenInterruptedFlatModifier[i]);
}
}
}
- if (changesMask[152])
+ if (changesMask[154])
{
for (uint32 i = 0; i < 3; ++i)
{
- if (changesMask[153 + i])
+ if (changesMask[155 + i])
{
VirtualItems[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
}
}
}
- if (changesMask[156])
+ if (changesMask[158])
{
for (uint32 i = 0; i < 2; ++i)
{
- if (changesMask[157 + i])
+ if (changesMask[159 + i])
{
data << uint32(AttackRoundBaseTime[i]);
}
}
}
- if (changesMask[159])
+ if (changesMask[161])
{
for (uint32 i = 0; i < 4; ++i)
{
- if (changesMask[160 + i])
+ if (changesMask[162 + i])
{
data << int32(Stats[i]);
}
- if (changesMask[164 + i])
+ if (changesMask[166 + i])
{
data << int32(StatPosBuff[i]);
}
- if (changesMask[168 + i])
+ if (changesMask[170 + i])
{
data << int32(StatNegBuff[i]);
}
}
}
- if (changesMask[172])
+ if (changesMask[174])
{
for (uint32 i = 0; i < 7; ++i)
{
- if (changesMask[173 + i])
+ if (changesMask[175 + i])
{
data << int32(Resistances[i]);
}
- if (changesMask[180 + i])
+ if (changesMask[182 + i])
{
data << int32(BonusResistanceMods[i]);
}
- if (changesMask[187 + i])
+ if (changesMask[189 + i])
{
data << int32(ManaCostModifier[i]);
}
@@ -1808,6 +1809,7 @@ void UnitData::ClearChangesMask()
Base::ClearChangesMask(BattlePetCompanionGUID);
Base::ClearChangesMask(BattlePetDBID);
Base::ClearChangesMask(ChannelData);
+ Base::ClearChangesMask(SpellEmpowerStage);
Base::ClearChangesMask(SummonedByHomeRealm);
Base::ClearChangesMask(Race);
Base::ClearChangesMask(ClassId);
@@ -1900,6 +1902,7 @@ void UnitData::ClearChangesMask()
Base::ClearChangesMask(LookAtControllerID);
Base::ClearChangesMask(TaxiNodesID);
Base::ClearChangesMask(GuildGUID);
+ Base::ClearChangesMask(FlightCapabilityID);
Base::ClearChangesMask(SilencedSchoolMask);
Base::ClearChangesMask(NameplateAttachToGUID);
Base::ClearChangesMask(NpcFlags);
@@ -2133,12 +2136,14 @@ void PlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVi
}
data << uint8(CurrentBattlePetBreedQuality);
data << int32(HonorLevel);
+ data << int64(LogoutTime);
data << uint32(ArenaCooldowns.size());
data << int32(Field_B0);
data << int32(Field_B4);
CtrOptions->WriteCreate(data, owner, receiver);
data << int32(CovenantID);
data << int32(SoulbindID);
+ data << uint32(VisualItemReplacements.size());
for (uint32 i = 0; i < Customizations.size(); ++i)
{
Customizations[i].WriteCreate(data, owner, receiver);
@@ -2154,6 +2159,10 @@ void PlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVi
{
ArenaCooldowns[i].WriteCreate(data, owner, receiver);
}
+ for (uint32 i = 0; i < VisualItemReplacements.size(); ++i)
+ {
+ data << int32(VisualItemReplacements[i]);
+ }
if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::PartyMember))
{
data.WriteBit(HasQuestSession);
@@ -2165,7 +2174,7 @@ void PlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVi
void PlayerData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const
{
- Mask allowedMaskForTarget({ 0xFFFFFFEDu, 0x00000007u, 0x00000000u, 0x00000000u, 0x00000000u, 0x0FFFFFFEu });
+ Mask allowedMaskForTarget({ 0xFFFFFFEDu, 0x0000001Fu, 0x00000000u, 0x00000000u, 0x00000000u, 0x3FFFFFF8u });
AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags);
WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver);
}
@@ -2173,12 +2182,12 @@ void PlayerData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVi
void PlayerData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags)
{
if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::PartyMember))
- allowedMaskForTarget |= { 0x00000012u, 0xFFFFFFF8u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x00000001u };
+ allowedMaskForTarget |= { 0x00000012u, 0xFFFFFFE0u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x00000007u };
}
void PlayerData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags)
{
- Mask allowedMaskForTarget({ 0xFFFFFFEDu, 0x00000007u, 0x00000000u, 0x00000000u, 0x00000000u, 0x0FFFFFFEu });
+ Mask allowedMaskForTarget({ 0xFFFFFFEDu, 0x0000001Fu, 0x00000000u, 0x00000000u, 0x00000000u, 0x3FFFFFF8u });
AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags);
changesMask &= allowedMaskForTarget;
}
@@ -2222,6 +2231,13 @@ void PlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ign
else
WriteCompleteDynamicFieldUpdateMask(ArenaCooldowns.size(), data);
}
+ if (changesMask[6])
+ {
+ if (!ignoreNestedChangesMask)
+ VisualItemReplacements.WriteUpdateMask(data);
+ else
+ WriteCompleteDynamicFieldUpdateMask(VisualItemReplacements.size(), data);
+ }
}
data.FlushBits();
if (changesMask[0])
@@ -2261,125 +2277,139 @@ void PlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ign
}
if (changesMask[6])
{
- data << DuelArbiter;
+ for (uint32 i = 0; i < VisualItemReplacements.size(); ++i)
+ {
+ if (VisualItemReplacements.HasChanged(i) || ignoreNestedChangesMask)
+ {
+ data << int32(VisualItemReplacements[i]);
+ }
+ }
}
if (changesMask[7])
{
- data << WowAccount;
+ data << DuelArbiter;
}
if (changesMask[8])
{
- data << LootTargetGUID;
+ data << WowAccount;
}
if (changesMask[9])
{
- data << uint32(PlayerFlags);
+ data << LootTargetGUID;
}
if (changesMask[10])
{
- data << uint32(PlayerFlagsEx);
+ data << uint32(PlayerFlags);
}
if (changesMask[11])
{
- data << uint32(GuildRankID);
+ data << uint32(PlayerFlagsEx);
}
if (changesMask[12])
{
- data << uint32(GuildDeleteDate);
+ data << uint32(GuildRankID);
}
if (changesMask[13])
{
- data << int32(GuildLevel);
+ data << uint32(GuildDeleteDate);
}
if (changesMask[14])
{
- data << uint8(PartyType);
+ data << int32(GuildLevel);
}
if (changesMask[15])
{
- data << uint8(NativeSex);
+ data << uint8(PartyType);
}
if (changesMask[16])
{
- data << uint8(Inebriation);
+ data << uint8(NativeSex);
}
if (changesMask[17])
{
- data << uint8(PvpTitle);
+ data << uint8(Inebriation);
}
if (changesMask[18])
{
- data << uint8(ArenaFaction);
+ data << uint8(PvpTitle);
}
if (changesMask[19])
{
- data << uint32(DuelTeam);
+ data << uint8(ArenaFaction);
}
if (changesMask[20])
{
- data << int32(GuildTimeStamp);
+ data << uint32(DuelTeam);
}
if (changesMask[21])
{
- data << int32(PlayerTitle);
+ data << int32(GuildTimeStamp);
}
if (changesMask[22])
{
- data << int32(FakeInebriation);
+ data << int32(PlayerTitle);
}
if (changesMask[23])
{
- data << uint32(VirtualPlayerRealm);
+ data << int32(FakeInebriation);
}
if (changesMask[24])
{
- data << uint32(CurrentSpecID);
+ data << uint32(VirtualPlayerRealm);
}
if (changesMask[25])
{
- data << int32(TaxiMountAnimKitID);
+ data << uint32(CurrentSpecID);
}
if (changesMask[26])
{
- data << uint8(CurrentBattlePetBreedQuality);
+ data << int32(TaxiMountAnimKitID);
}
if (changesMask[27])
{
- data << int32(HonorLevel);
+ data << uint8(CurrentBattlePetBreedQuality);
}
if (changesMask[28])
{
- data << int32(Field_B0);
+ data << int32(HonorLevel);
}
if (changesMask[29])
{
- data << int32(Field_B4);
+ data << int64(LogoutTime);
}
if (changesMask[30])
{
- CtrOptions->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
+ data << int32(Field_B0);
}
if (changesMask[31])
{
- data << int32(CovenantID);
+ data << int32(Field_B4);
}
}
if (changesMask[32])
{
if (changesMask[33])
{
- data << int32(SoulbindID);
+ CtrOptions->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
}
if (changesMask[34])
{
+ data << int32(CovenantID);
+ }
+ if (changesMask[35])
+ {
+ data << int32(SoulbindID);
+ }
+ if (changesMask[36])
+ {
data << DungeonScore;
}
}
- if (changesMask[35])
+ if (changesMask[37])
{
for (uint32 i = 0; i < 125; ++i)
{
- if (changesMask[36 + i])
+ if (changesMask[38 + i])
{
if (noQuestLogChangesMask)
QuestLog[i].WriteCreate(data, owner, receiver);
@@ -2388,21 +2418,21 @@ void PlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ign
}
}
}
- if (changesMask[161])
+ if (changesMask[163])
{
for (uint32 i = 0; i < 19; ++i)
{
- if (changesMask[162 + i])
+ if (changesMask[164 + i])
{
VisibleItems[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
}
}
}
- if (changesMask[181])
+ if (changesMask[183])
{
for (uint32 i = 0; i < 6; ++i)
{
- if (changesMask[182 + i])
+ if (changesMask[184 + i])
{
data << float(AvgItemLevel[i]);
}
@@ -2418,6 +2448,7 @@ void PlayerData::ClearChangesMask()
Base::ClearChangesMask(Customizations);
Base::ClearChangesMask(QuestSessionQuestLog);
Base::ClearChangesMask(ArenaCooldowns);
+ Base::ClearChangesMask(VisualItemReplacements);
Base::ClearChangesMask(DuelArbiter);
Base::ClearChangesMask(WowAccount);
Base::ClearChangesMask(LootTargetGUID);
@@ -2440,6 +2471,7 @@ void PlayerData::ClearChangesMask()
Base::ClearChangesMask(TaxiMountAnimKitID);
Base::ClearChangesMask(CurrentBattlePetBreedQuality);
Base::ClearChangesMask(HonorLevel);
+ Base::ClearChangesMask(LogoutTime);
Base::ClearChangesMask(Field_B0);
Base::ClearChangesMask(Field_B4);
Base::ClearChangesMask(CtrOptions);
@@ -2565,6 +2597,8 @@ void RestInfo::ClearChangesMask()
void PVPInfo::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const
{
+ data << int8(Bracket);
+ data << int32(PvpRatingID);
data << uint32(WeeklyPlayed);
data << uint32(WeeklyWon);
data << uint32(SeasonPlayed);
@@ -2576,6 +2610,10 @@ void PVPInfo::WriteCreate(ByteBuffer& data, Player const* owner, Player const* r
data << uint32(WeeklyBestWinPvpTierID);
data << uint32(Field_28);
data << uint32(Field_2C);
+ data << uint32(WeeklyRoundsPlayed);
+ data << uint32(WeeklyRoundsWon);
+ data << uint32(SeasonRoundsPlayed);
+ data << uint32(SeasonRoundsWon);
data.WriteBit(Disqualified);
data.FlushBits();
}
@@ -2586,7 +2624,7 @@ void PVPInfo::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const
if (ignoreChangesMask)
changesMask.SetAll();
- data.WriteBits(changesMask.GetBlock(0), 13);
+ data.WriteBits(changesMask.GetBlock(0), 19);
if (changesMask[0])
{
@@ -2600,48 +2638,72 @@ void PVPInfo::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const
{
if (changesMask[2])
{
- data << uint32(WeeklyPlayed);
+ data << int8(Bracket);
}
if (changesMask[3])
{
- data << uint32(WeeklyWon);
+ data << int32(PvpRatingID);
}
if (changesMask[4])
{
- data << uint32(SeasonPlayed);
+ data << uint32(WeeklyPlayed);
}
if (changesMask[5])
{
- data << uint32(SeasonWon);
+ data << uint32(WeeklyWon);
}
if (changesMask[6])
{
- data << uint32(Rating);
+ data << uint32(SeasonPlayed);
}
if (changesMask[7])
{
- data << uint32(WeeklyBestRating);
+ data << uint32(SeasonWon);
}
if (changesMask[8])
{
- data << uint32(SeasonBestRating);
+ data << uint32(Rating);
}
if (changesMask[9])
{
- data << uint32(PvpTierID);
+ data << uint32(WeeklyBestRating);
}
if (changesMask[10])
{
- data << uint32(WeeklyBestWinPvpTierID);
+ data << uint32(SeasonBestRating);
}
if (changesMask[11])
{
- data << uint32(Field_28);
+ data << uint32(PvpTierID);
}
if (changesMask[12])
{
+ data << uint32(WeeklyBestWinPvpTierID);
+ }
+ if (changesMask[13])
+ {
+ data << uint32(Field_28);
+ }
+ if (changesMask[14])
+ {
data << uint32(Field_2C);
}
+ if (changesMask[15])
+ {
+ data << uint32(WeeklyRoundsPlayed);
+ }
+ if (changesMask[16])
+ {
+ data << uint32(WeeklyRoundsWon);
+ }
+ if (changesMask[17])
+ {
+ data << uint32(SeasonRoundsPlayed);
+ }
+ if (changesMask[18])
+ {
+ data << uint32(SeasonRoundsWon);
+ }
}
data.FlushBits();
}
@@ -2649,6 +2711,8 @@ void PVPInfo::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const
void PVPInfo::ClearChangesMask()
{
Base::ClearChangesMask(Disqualified);
+ Base::ClearChangesMask(Bracket);
+ Base::ClearChangesMask(PvpRatingID);
Base::ClearChangesMask(WeeklyPlayed);
Base::ClearChangesMask(WeeklyWon);
Base::ClearChangesMask(SeasonPlayed);
@@ -2660,6 +2724,10 @@ void PVPInfo::ClearChangesMask()
Base::ClearChangesMask(WeeklyBestWinPvpTierID);
Base::ClearChangesMask(Field_28);
Base::ClearChangesMask(Field_2C);
+ Base::ClearChangesMask(WeeklyRoundsPlayed);
+ Base::ClearChangesMask(WeeklyRoundsWon);
+ Base::ClearChangesMask(SeasonRoundsPlayed);
+ Base::ClearChangesMask(SeasonRoundsWon);
_changesMask.ResetAll();
}
@@ -2926,9 +2994,514 @@ void ReplayedQuest::ClearChangesMask()
_changesMask.ResetAll();
}
+void TraitEntry::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const
+{
+ data << int32(TraitNodeID);
+ data << int32(TraitNodeEntryID);
+ data << int32(Rank);
+ data << int32(GrantedRanks);
+}
+
+void TraitEntry::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const
+{
+ data << int32(TraitNodeID);
+ data << int32(TraitNodeEntryID);
+ data << int32(Rank);
+ data << int32(GrantedRanks);
+}
+
+bool TraitEntry::operator==(TraitEntry const& right) const
+{
+ return TraitNodeID == right.TraitNodeID
+ && TraitNodeEntryID == right.TraitNodeEntryID
+ && Rank == right.Rank
+ && GrantedRanks == right.GrantedRanks;
+}
+
+void TraitConfig::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const
+{
+ data << int32(ID);
+ data << int32(Type);
+ data << uint32(Entries.size());
+ if (Type == 2)
+ {
+ data << int32(SkillLineID);
+ }
+ if (Type == 1)
+ {
+ data << int32(ChrSpecializationID);
+ data << int32(CombatConfigFlags);
+ data << int32(LocalIdentifier);
+ }
+ if (Type == 3)
+ {
+ data << int32(TraitSystemID);
+ }
+ for (uint32 i = 0; i < Entries.size(); ++i)
+ {
+ Entries[i].WriteCreate(data, owner, receiver);
+ }
+ data.WriteBits(Name->size(), 9);
+ data.WriteString(Name);
+ data.FlushBits();
+}
+
+void TraitConfig::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const
+{
+ Mask changesMask = _changesMask;
+ if (ignoreChangesMask)
+ changesMask.SetAll();
+
+ data.WriteBits(changesMask.GetBlock(0), 12);
+
+ if (changesMask[0])
+ {
+ if (changesMask[1])
+ {
+ if (!ignoreChangesMask)
+ Entries.WriteUpdateMask(data);
+ else
+ WriteCompleteDynamicFieldUpdateMask(Entries.size(), data);
+ }
+ }
+ data.FlushBits();
+ if (changesMask[0])
+ {
+ if (changesMask[1])
+ {
+ for (uint32 i = 0; i < Entries.size(); ++i)
+ {
+ if (Entries.HasChanged(i) || ignoreChangesMask)
+ {
+ Entries[i].WriteUpdate(data, ignoreChangesMask, owner, receiver);
+ }
+ }
+ }
+ if (changesMask[2])
+ {
+ data << int32(ID);
+ }
+ }
+ if (changesMask[4])
+ {
+ if (changesMask[5])
+ {
+ data << int32(Type);
+ }
+ if (changesMask[6])
+ {
+ if (Type == 2)
+ {
+ data << int32(SkillLineID);
+ }
+ }
+ if (changesMask[7])
+ {
+ if (Type == 1)
+ {
+ data << int32(ChrSpecializationID);
+ }
+ }
+ }
+ if (changesMask[8])
+ {
+ if (changesMask[9])
+ {
+ if (Type == 1)
+ {
+ data << int32(CombatConfigFlags);
+ }
+ }
+ if (changesMask[10])
+ {
+ if (Type == 1)
+ {
+ data << int32(LocalIdentifier);
+ }
+ }
+ if (changesMask[11])
+ {
+ if (Type == 3)
+ {
+ data << int32(TraitSystemID);
+ }
+ }
+ }
+ if (changesMask[0])
+ {
+ if (changesMask[3])
+ {
+ data.WriteBits(Name->size(), 9);
+ data.WriteString(Name);
+ }
+ }
+ data.FlushBits();
+}
+
+void TraitConfig::ClearChangesMask()
+{
+ Base::ClearChangesMask(Entries);
+ Base::ClearChangesMask(ID);
+ Base::ClearChangesMask(Name);
+ Base::ClearChangesMask(Type);
+ Base::ClearChangesMask(SkillLineID);
+ Base::ClearChangesMask(ChrSpecializationID);
+ Base::ClearChangesMask(CombatConfigFlags);
+ Base::ClearChangesMask(LocalIdentifier);
+ Base::ClearChangesMask(TraitSystemID);
+ _changesMask.ResetAll();
+}
+
+void CraftingOrderItem::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const
+{
+ data << uint64(Field_0);
+ data << ItemGUID;
+ data << OwnerGUID;
+ data << int32(ItemID);
+ data << uint32(Quantity);
+ data << int32(ReagentQuality);
+ data.WriteBits(DataSlotIndex.has_value(), 1);
+ if (DataSlotIndex.has_value())
+ {
+ data << uint8(DataSlotIndex);
+ }
+}
+
+void CraftingOrderItem::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const
+{
+ Mask changesMask = _changesMask;
+ if (ignoreChangesMask)
+ changesMask.SetAll();
+
+ data.WriteBits(changesMask.GetBlock(0), 7);
+
+ data.FlushBits();
+ if (changesMask[0])
+ {
+ data << uint64(Field_0);
+ }
+ if (changesMask[1])
+ {
+ data << ItemGUID;
+ }
+ if (changesMask[2])
+ {
+ data << OwnerGUID;
+ }
+ if (changesMask[3])
+ {
+ data << int32(ItemID);
+ }
+ if (changesMask[4])
+ {
+ data << uint32(Quantity);
+ }
+ if (changesMask[5])
+ {
+ data << int32(ReagentQuality);
+ }
+ data.WriteBits(DataSlotIndex.has_value(), 1);
+ if (changesMask[6])
+ {
+ if (DataSlotIndex.has_value())
+ {
+ data << uint8(DataSlotIndex);
+ }
+ }
+}
+
+void CraftingOrderItem::ClearChangesMask()
+{
+ Base::ClearChangesMask(Field_0);
+ Base::ClearChangesMask(ItemGUID);
+ Base::ClearChangesMask(OwnerGUID);
+ Base::ClearChangesMask(ItemID);
+ Base::ClearChangesMask(Quantity);
+ Base::ClearChangesMask(ReagentQuality);
+ Base::ClearChangesMask(DataSlotIndex);
+ _changesMask.ResetAll();
+}
+
+void CraftingOrderData::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const
+{
+ data << int32(Field_0);
+ data << uint64(OrderID);
+ data << int32(SkillLineAbilityID);
+ data << uint8(OrderState);
+ data << uint8(OrderType);
+ data << uint8(MinQuality);
+ data << int64(ExpirationTime);
+ data << int64(ClaimEndTime);
+ data << int64(TipAmount);
+ data << int64(ConsortiumCut);
+ data << uint32(Flags);
+ data << CustomerGUID;
+ data << CustomerAccountGUID;
+ data << CrafterGUID;
+ data << PersonalCrafterGUID;
+ data << uint32(Reagents.size());
+ data.WriteBits(CustomerNotes->size(), 10);
+ data.WriteBits(OutputItem.has_value(), 1);
+ data.WriteBits(OutputItemData.has_value(), 1);
+ for (uint32 i = 0; i < Reagents.size(); ++i)
+ {
+ Reagents[i].WriteCreate(data, owner, receiver);
+ }
+ data.WriteString(CustomerNotes);
+ if (OutputItem.has_value())
+ {
+ OutputItem->WriteCreate(data, owner, receiver);
+ }
+ if (OutputItemData.has_value())
+ {
+ data << OutputItemData;
+ }
+ data.FlushBits();
+}
+
+void CraftingOrderData::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const
+{
+ Mask changesMask = _changesMask;
+ if (ignoreChangesMask)
+ changesMask.SetAll();
+
+ data.WriteBits(changesMask.GetBlock(0), 24);
+
+ if (changesMask[0])
+ {
+ if (changesMask[1])
+ {
+ if (!ignoreChangesMask)
+ Reagents.WriteUpdateMask(data);
+ else
+ WriteCompleteDynamicFieldUpdateMask(Reagents.size(), data);
+ }
+ }
+ data.FlushBits();
+ if (changesMask[0])
+ {
+ if (changesMask[1])
+ {
+ for (uint32 i = 0; i < Reagents.size(); ++i)
+ {
+ if (Reagents.HasChanged(i) || ignoreChangesMask)
+ {
+ Reagents[i].WriteUpdate(data, ignoreChangesMask, owner, receiver);
+ }
+ }
+ }
+ if (changesMask[2])
+ {
+ data << int32(Field_0);
+ }
+ if (changesMask[3])
+ {
+ data << uint64(OrderID);
+ }
+ if (changesMask[4])
+ {
+ data << int32(SkillLineAbilityID);
+ }
+ }
+ if (changesMask[5])
+ {
+ if (changesMask[6])
+ {
+ data << uint8(OrderState);
+ }
+ if (changesMask[7])
+ {
+ data << uint8(OrderType);
+ }
+ if (changesMask[8])
+ {
+ data << uint8(MinQuality);
+ }
+ if (changesMask[9])
+ {
+ data << int64(ExpirationTime);
+ }
+ }
+ if (changesMask[10])
+ {
+ if (changesMask[11])
+ {
+ data << int64(ClaimEndTime);
+ }
+ if (changesMask[12])
+ {
+ data << int64(TipAmount);
+ }
+ if (changesMask[13])
+ {
+ data << int64(ConsortiumCut);
+ }
+ if (changesMask[14])
+ {
+ data << uint32(Flags);
+ }
+ }
+ if (changesMask[15])
+ {
+ if (changesMask[16])
+ {
+ data << CustomerGUID;
+ }
+ if (changesMask[17])
+ {
+ data << CustomerAccountGUID;
+ }
+ if (changesMask[18])
+ {
+ data << CrafterGUID;
+ }
+ if (changesMask[19])
+ {
+ data << PersonalCrafterGUID;
+ }
+ }
+ if (changesMask[20])
+ {
+ if (changesMask[21])
+ {
+ data.WriteBits(CustomerNotes->size(), 10);
+ data.WriteString(CustomerNotes);
+ }
+ data.WriteBits(OutputItem.has_value(), 1);
+ data.WriteBits(OutputItemData.has_value(), 1);
+ if (changesMask[22])
+ {
+ if (OutputItem.has_value())
+ {
+ OutputItem->WriteUpdate(data, ignoreChangesMask, owner, receiver);
+ }
+ }
+ if (changesMask[23])
+ {
+ if (OutputItemData.has_value())
+ {
+ data << OutputItemData;
+ }
+ }
+ }
+ data.FlushBits();
+}
+
+void CraftingOrderData::ClearChangesMask()
+{
+ Base::ClearChangesMask(Reagents);
+ Base::ClearChangesMask(Field_0);
+ Base::ClearChangesMask(OrderID);
+ Base::ClearChangesMask(SkillLineAbilityID);
+ Base::ClearChangesMask(OrderState);
+ Base::ClearChangesMask(OrderType);
+ Base::ClearChangesMask(MinQuality);
+ Base::ClearChangesMask(ExpirationTime);
+ Base::ClearChangesMask(ClaimEndTime);
+ Base::ClearChangesMask(TipAmount);
+ Base::ClearChangesMask(ConsortiumCut);
+ Base::ClearChangesMask(Flags);
+ Base::ClearChangesMask(CustomerGUID);
+ Base::ClearChangesMask(CustomerAccountGUID);
+ Base::ClearChangesMask(CrafterGUID);
+ Base::ClearChangesMask(PersonalCrafterGUID);
+ Base::ClearChangesMask(CustomerNotes);
+ Base::ClearChangesMask(OutputItem);
+ Base::ClearChangesMask(OutputItemData);
+ _changesMask.ResetAll();
+}
+
+void CraftingOrder::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const
+{
+ Data->WriteCreate(data, owner, receiver);
+ data.WriteBits(RecraftItemInfo.has_value(), 1);
+ data.WriteBits(Enchantments.size(), 4);
+ data.WriteBits(Gems.size(), 2);
+ if (RecraftItemInfo.has_value())
+ {
+ data << RecraftItemInfo;
+ }
+ for (uint32 i = 0; i < Enchantments.size(); ++i)
+ {
+ data << Enchantments[i];
+ }
+ for (uint32 i = 0; i < Gems.size(); ++i)
+ {
+ data << Gems[i];
+ }
+ data.FlushBits();
+}
+
+void CraftingOrder::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const
+{
+ Mask changesMask = _changesMask;
+ if (ignoreChangesMask)
+ changesMask.SetAll();
+
+ data.WriteBits(changesMask.GetBlock(0), 4);
+
+ if (changesMask[0])
+ {
+ if (!ignoreChangesMask)
+ Enchantments.WriteUpdateMask(data, 4);
+ else
+ WriteCompleteDynamicFieldUpdateMask(Enchantments.size(), data, 4);
+ }
+ if (changesMask[1])
+ {
+ if (!ignoreChangesMask)
+ Gems.WriteUpdateMask(data, 2);
+ else
+ WriteCompleteDynamicFieldUpdateMask(Gems.size(), data, 2);
+ }
+ data.FlushBits();
+ if (changesMask[0])
+ {
+ for (uint32 i = 0; i < Enchantments.size(); ++i)
+ {
+ if (Enchantments.HasChanged(i) || ignoreChangesMask)
+ {
+ data << Enchantments[i];
+ }
+ }
+ }
+ if (changesMask[1])
+ {
+ for (uint32 i = 0; i < Gems.size(); ++i)
+ {
+ if (Gems.HasChanged(i) || ignoreChangesMask)
+ {
+ data << Gems[i];
+ }
+ }
+ }
+ if (changesMask[2])
+ {
+ Data->WriteUpdate(data, ignoreChangesMask, owner, receiver);
+ }
+ data.WriteBits(RecraftItemInfo.has_value(), 1);
+ if (changesMask[3])
+ {
+ if (RecraftItemInfo.has_value())
+ {
+ data << RecraftItemInfo;
+ }
+ }
+ data.FlushBits();
+}
+
+void CraftingOrder::ClearChangesMask()
+{
+ Base::ClearChangesMask(Enchantments);
+ Base::ClearChangesMask(Gems);
+ Base::ClearChangesMask(Data);
+ Base::ClearChangesMask(RecraftItemInfo);
+ _changesMask.ResetAll();
+}
+
void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const
{
- for (uint32 i = 0; i < 199; ++i)
+ for (uint32 i = 0; i < 218; ++i)
{
data << InvSlots[i];
}
@@ -3014,6 +3587,7 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f
{
data << int32(CombatRatings[i]);
}
+ data << uint32(PvpInfo.size());
data << int32(MaxLevel);
data << int32(ScalingPlayerLevelDelta);
data << int32(MaxCreatureScalingLevel);
@@ -3040,7 +3614,7 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f
data << uint32(OverrideZonePVPType);
data << BnetAccount;
data << uint64(GuildClubMemberID);
- for (uint32 i = 0; i < 4; ++i)
+ for (uint32 i = 0; i < 5; ++i)
{
data << uint32(BagSlotFlags[i]);
}
@@ -3088,6 +3662,9 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f
data << int32(TransportServerTime);
data << uint32(WeeklyRewardsPeriodSinceOrigin);
data << int16(DEBUGSoulbindConduitRank);
+ data << uint32(TraitConfigs.size());
+ data << uint32(ActiveCombatTraitConfigID);
+ data << uint32(CraftingOrders.size());
for (uint32 i = 0; i < KnownTitles.size(); ++i)
{
data << uint64(KnownTitles[i]);
@@ -3172,10 +3749,6 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f
{
data << int32(DisabledSpells[i]);
}
- for (uint32 i = 0; i < 6; ++i)
- {
- PvpInfo[i].WriteCreate(data, owner, receiver);
- }
data.FlushBits();
data.WriteBit(BackpackAutoSortDisabled);
data.WriteBit(BankAutoSortDisabled);
@@ -3188,10 +3761,22 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f
QuestSession->WriteCreate(data, owner, receiver);
}
data << DungeonScore;
+ for (uint32 i = 0; i < PvpInfo.size(); ++i)
+ {
+ PvpInfo[i].WriteCreate(data, owner, receiver);
+ }
for (uint32 i = 0; i < CharacterRestrictions.size(); ++i)
{
CharacterRestrictions[i].WriteCreate(data, owner, receiver);
}
+ for (uint32 i = 0; i < TraitConfigs.size(); ++i)
+ {
+ TraitConfigs[i].WriteCreate(data, owner, receiver);
+ }
+ for (uint32 i = 0; i < CraftingOrders.size(); ++i)
+ {
+ CraftingOrders[i].WriteCreate(data, owner, receiver);
+ }
data.FlushBits();
}
@@ -3204,8 +3789,8 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
{
for (uint32 i = 0; i < 1; ++i)
data << uint32(changesMask.GetBlocksMask(i));
- data.WriteBits(changesMask.GetBlocksMask(1), 17);
- for (uint32 i = 0; i < 49; ++i)
+ data.WriteBits(changesMask.GetBlocksMask(1), 18);
+ for (uint32 i = 0; i < 50; ++i)
if (changesMask.GetBlock(i))
data.WriteBits(changesMask.GetBlock(i), 32);
@@ -3237,109 +3822,116 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
if (changesMask[6])
{
if (!ignoreNestedChangesMask)
+ PvpInfo.WriteUpdateMask(data);
+ else
+ WriteCompleteDynamicFieldUpdateMask(PvpInfo.size(), data);
+ }
+ if (changesMask[7])
+ {
+ if (!ignoreNestedChangesMask)
ResearchSites.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(ResearchSites.size(), data);
}
- if (changesMask[7])
+ if (changesMask[8])
{
if (!ignoreNestedChangesMask)
ResearchSiteProgress.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(ResearchSiteProgress.size(), data);
}
- if (changesMask[8])
+ if (changesMask[9])
{
if (!ignoreNestedChangesMask)
DailyQuestsCompleted.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(DailyQuestsCompleted.size(), data);
}
- if (changesMask[9])
+ if (changesMask[10])
{
if (!ignoreNestedChangesMask)
AvailableQuestLineXQuestIDs.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(AvailableQuestLineXQuestIDs.size(), data);
}
- if (changesMask[10])
+ if (changesMask[11])
{
if (!ignoreNestedChangesMask)
Heirlooms.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(Heirlooms.size(), data);
}
- if (changesMask[11])
+ if (changesMask[12])
{
if (!ignoreNestedChangesMask)
HeirloomFlags.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(HeirloomFlags.size(), data);
}
- if (changesMask[12])
+ if (changesMask[13])
{
if (!ignoreNestedChangesMask)
Toys.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(Toys.size(), data);
}
- if (changesMask[13])
+ if (changesMask[14])
{
if (!ignoreNestedChangesMask)
ToyFlags.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(ToyFlags.size(), data);
}
- if (changesMask[14])
+ if (changesMask[15])
{
if (!ignoreNestedChangesMask)
Transmog.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(Transmog.size(), data);
}
- if (changesMask[15])
+ if (changesMask[16])
{
if (!ignoreNestedChangesMask)
ConditionalTransmog.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(ConditionalTransmog.size(), data);
}
- if (changesMask[16])
+ if (changesMask[17])
{
if (!ignoreNestedChangesMask)
SelfResSpells.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(SelfResSpells.size(), data);
}
- if (changesMask[17])
+ if (changesMask[18])
{
if (!ignoreNestedChangesMask)
RuneforgePowers.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(RuneforgePowers.size(), data);
}
- if (changesMask[18])
+ if (changesMask[19])
{
if (!ignoreNestedChangesMask)
TransmogIllusions.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(TransmogIllusions.size(), data);
}
- if (changesMask[19])
+ if (changesMask[20])
{
if (!ignoreNestedChangesMask)
CharacterRestrictions.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(CharacterRestrictions.size(), data);
}
- if (changesMask[20])
+ if (changesMask[21])
{
if (!ignoreNestedChangesMask)
SpellPctModByLabel.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(SpellPctModByLabel.size(), data);
}
- if (changesMask[21])
+ if (changesMask[22])
{
if (!ignoreNestedChangesMask)
SpellFlatModByLabel.WriteUpdateMask(data);
@@ -3347,11 +3939,11 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
WriteCompleteDynamicFieldUpdateMask(SpellFlatModByLabel.size(), data);
}
}
- if (changesMask[27])
+ if (changesMask[30])
{
for (uint32 i = 0; i < 1; ++i)
{
- if (changesMask[28 + i])
+ if (changesMask[31 + i])
{
if (!ignoreNestedChangesMask)
Research[i].WriteUpdateMask(data);
@@ -3370,41 +3962,55 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
data.FlushBits();
if (changesMask[0])
{
- if (changesMask[22])
+ if (changesMask[23])
{
if (!ignoreNestedChangesMask)
MawPowers.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(MawPowers.size(), data);
}
- if (changesMask[23])
+ if (changesMask[24])
{
if (!ignoreNestedChangesMask)
MultiFloorExploration.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(MultiFloorExploration.size(), data);
}
- if (changesMask[24])
+ if (changesMask[25])
{
if (!ignoreNestedChangesMask)
RecipeProgression.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(RecipeProgression.size(), data);
}
- if (changesMask[25])
+ if (changesMask[26])
{
if (!ignoreNestedChangesMask)
ReplayedQuests.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(ReplayedQuests.size(), data);
}
- if (changesMask[26])
+ if (changesMask[27])
{
if (!ignoreNestedChangesMask)
DisabledSpells.WriteUpdateMask(data);
else
WriteCompleteDynamicFieldUpdateMask(DisabledSpells.size(), data);
}
+ if (changesMask[28])
+ {
+ if (!ignoreNestedChangesMask)
+ TraitConfigs.WriteUpdateMask(data);
+ else
+ WriteCompleteDynamicFieldUpdateMask(TraitConfigs.size(), data);
+ }
+ if (changesMask[29])
+ {
+ if (!ignoreNestedChangesMask)
+ CraftingOrders.WriteUpdateMask(data);
+ else
+ WriteCompleteDynamicFieldUpdateMask(CraftingOrders.size(), data);
+ }
}
data.FlushBits();
if (changesMask[0])
@@ -3419,7 +4025,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[6])
+ if (changesMask[7])
{
for (uint32 i = 0; i < ResearchSites.size(); ++i)
{
@@ -3429,7 +4035,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[7])
+ if (changesMask[8])
{
for (uint32 i = 0; i < ResearchSiteProgress.size(); ++i)
{
@@ -3439,7 +4045,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[8])
+ if (changesMask[9])
{
for (uint32 i = 0; i < DailyQuestsCompleted.size(); ++i)
{
@@ -3449,7 +4055,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[9])
+ if (changesMask[10])
{
for (uint32 i = 0; i < AvailableQuestLineXQuestIDs.size(); ++i)
{
@@ -3459,7 +4065,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[10])
+ if (changesMask[11])
{
for (uint32 i = 0; i < Heirlooms.size(); ++i)
{
@@ -3469,7 +4075,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[11])
+ if (changesMask[12])
{
for (uint32 i = 0; i < HeirloomFlags.size(); ++i)
{
@@ -3479,7 +4085,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[12])
+ if (changesMask[13])
{
for (uint32 i = 0; i < Toys.size(); ++i)
{
@@ -3489,7 +4095,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[13])
+ if (changesMask[14])
{
for (uint32 i = 0; i < ToyFlags.size(); ++i)
{
@@ -3499,7 +4105,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[14])
+ if (changesMask[15])
{
for (uint32 i = 0; i < Transmog.size(); ++i)
{
@@ -3509,7 +4115,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[15])
+ if (changesMask[16])
{
for (uint32 i = 0; i < ConditionalTransmog.size(); ++i)
{
@@ -3519,7 +4125,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[16])
+ if (changesMask[17])
{
for (uint32 i = 0; i < SelfResSpells.size(); ++i)
{
@@ -3529,7 +4135,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[17])
+ if (changesMask[18])
{
for (uint32 i = 0; i < RuneforgePowers.size(); ++i)
{
@@ -3539,7 +4145,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[18])
+ if (changesMask[19])
{
for (uint32 i = 0; i < TransmogIllusions.size(); ++i)
{
@@ -3549,7 +4155,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[20])
+ if (changesMask[21])
{
for (uint32 i = 0; i < SpellPctModByLabel.size(); ++i)
{
@@ -3559,7 +4165,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[21])
+ if (changesMask[22])
{
for (uint32 i = 0; i < SpellFlatModByLabel.size(); ++i)
{
@@ -3569,7 +4175,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[22])
+ if (changesMask[23])
{
for (uint32 i = 0; i < MawPowers.size(); ++i)
{
@@ -3579,7 +4185,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[23])
+ if (changesMask[24])
{
for (uint32 i = 0; i < MultiFloorExploration.size(); ++i)
{
@@ -3589,7 +4195,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[24])
+ if (changesMask[25])
{
for (uint32 i = 0; i < RecipeProgression.size(); ++i)
{
@@ -3599,7 +4205,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[25])
+ if (changesMask[26])
{
for (uint32 i = 0; i < ReplayedQuests.size(); ++i)
{
@@ -3609,7 +4215,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[26])
+ if (changesMask[27])
{
for (uint32 i = 0; i < DisabledSpells.size(); ++i)
{
@@ -3619,7 +4225,17 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[19])
+ if (changesMask[6])
+ {
+ for (uint32 i = 0; i < PvpInfo.size(); ++i)
+ {
+ if (PvpInfo.HasChanged(i) || ignoreNestedChangesMask)
+ {
+ PvpInfo[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
+ }
+ }
+ }
+ if (changesMask[20])
{
for (uint32 i = 0; i < CharacterRestrictions.size(); ++i)
{
@@ -3629,493 +4245,507 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo
}
}
}
- if (changesMask[29])
- {
- data << FarsightObject;
- }
- if (changesMask[30])
+ if (changesMask[28])
{
- data << SummonedBattlePetGUID;
+ for (uint32 i = 0; i < TraitConfigs.size(); ++i)
+ {
+ if (TraitConfigs.HasChanged(i) || ignoreNestedChangesMask)
+ {
+ TraitConfigs[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
+ }
+ }
}
- if (changesMask[31])
+ if (changesMask[29])
{
- data << uint64(Coinage);
+ for (uint32 i = 0; i < CraftingOrders.size(); ++i)
+ {
+ if (CraftingOrders.HasChanged(i) || ignoreNestedChangesMask)
+ {
+ CraftingOrders[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
+ }
+ }
}
if (changesMask[32])
{
- data << int32(XP);
+ data << FarsightObject;
}
if (changesMask[33])
{
- data << int32(NextLevelXP);
+ data << SummonedBattlePetGUID;
}
}
if (changesMask[34])
{
if (changesMask[35])
{
- data << int32(TrialXP);
+ data << uint64(Coinage);
}
if (changesMask[36])
{
- Skill->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
+ data << int32(XP);
}
if (changesMask[37])
{
- data << int32(CharacterPoints);
+ data << int32(NextLevelXP);
}
if (changesMask[38])
{
- data << int32(MaxTalentTiers);
+ data << int32(TrialXP);
}
if (changesMask[39])
{
- data << uint32(TrackCreatureMask);
+ Skill->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
}
if (changesMask[40])
{
- data << float(MainhandExpertise);
+ data << int32(CharacterPoints);
}
if (changesMask[41])
{
- data << float(OffhandExpertise);
+ data << int32(MaxTalentTiers);
}
if (changesMask[42])
{
- data << float(RangedExpertise);
+ data << uint32(TrackCreatureMask);
}
if (changesMask[43])
{
- data << float(CombatRatingExpertise);
+ data << float(MainhandExpertise);
}
if (changesMask[44])
{
- data << float(BlockPercentage);
+ data << float(OffhandExpertise);
}
if (changesMask[45])
{
- data << float(DodgePercentage);
+ data << float(RangedExpertise);
}
if (changesMask[46])
{
- data << float(DodgePercentageFromAttribute);
+ data << float(CombatRatingExpertise);
}
if (changesMask[47])
{
- data << float(ParryPercentage);
+ data << float(BlockPercentage);
}
if (changesMask[48])
{
- data << float(ParryPercentageFromAttribute);
+ data << float(DodgePercentage);
}
if (changesMask[49])
{
- data << float(CritPercentage);
+ data << float(DodgePercentageFromAttribute);
}
if (changesMask[50])
{
- data << float(RangedCritPercentage);
+ data << float(ParryPercentage);
}
if (changesMask[51])
{
- data << float(OffhandCritPercentage);
+ data << float(ParryPercentageFromAttribute);
}
if (changesMask[52])
{
- data << float(SpellCritPercentage);
+ data << float(CritPercentage);
}
if (changesMask[53])
{
- data << int32(ShieldBlock);
+ data << float(RangedCritPercentage);
}
if (changesMask[54])
{
- data << float(ShieldBlockCritPercentage);
+ data << float(OffhandCritPercentage);
}
if (changesMask[55])
{
- data << float(Mastery);
+ data << float(SpellCritPercentage);
}
if (changesMask[56])
{
- data << float(Speed);
+ data << int32(ShieldBlock);
}
if (changesMask[57])
{
- data << float(Avoidance);
+ data << float(ShieldBlockCritPercentage);
}
if (changesMask[58])
{
- data << float(Sturdiness);
+ data << float(Mastery);
}
if (changesMask[59])
{
- data << int32(Versatility);
+ data << float(Speed);
}
if (changesMask[60])
{
- data << float(VersatilityBonus);
+ data << float(Avoidance);
}
if (changesMask[61])
{
- data << float(PvpPowerDamage);
+ data << float(Sturdiness);
}
if (changesMask[62])
{
- data << float(PvpPowerHealing);
+ data << int32(Versatility);
}
if (changesMask[63])
{
- data << int32(ModHealingDonePos);
+ data << float(VersatilityBonus);
}
if (changesMask[64])
{
- data << float(ModHealingPercent);
+ data << float(PvpPowerDamage);
}
if (changesMask[65])
{
- data << float(ModPeriodicHealingDonePercent);
+ data << float(PvpPowerHealing);
}
}
if (changesMask[66])
{
if (changesMask[67])
{
- data << float(ModSpellPowerPercent);
+ data << int32(ModHealingDonePos);
}
if (changesMask[68])
{
- data << float(ModResiliencePercent);
+ data << float(ModHealingPercent);
}
if (changesMask[69])
{
- data << float(OverrideSpellPowerByAPPercent);
+ data << float(ModPeriodicHealingDonePercent);
}
if (changesMask[70])
{
- data << float(OverrideAPBySpellPowerPercent);
+ data << float(ModSpellPowerPercent);
}
if (changesMask[71])
{
- data << int32(ModTargetResistance);
+ data << float(ModResiliencePercent);
}
if (changesMask[72])
{
- data << int32(ModTargetPhysicalResistance);
+ data << float(OverrideSpellPowerByAPPercent);
}
if (changesMask[73])
{
- data << uint32(LocalFlags);
+ data << float(OverrideAPBySpellPowerPercent);
}
if (changesMask[74])
{
- data << uint8(GrantableLevels);
+ data << int32(ModTargetResistance);
}
if (changesMask[75])
{
- data << uint8(MultiActionBars);
+ data << int32(ModTargetPhysicalResistance);
}
if (changesMask[76])
{
- data << uint8(LifetimeMaxRank);
+ data << uint32(LocalFlags);
}
if (changesMask[77])
{
- data << uint8(NumRespecs);
+ data << uint8(GrantableLevels);
}
if (changesMask[78])
{
- data << uint32(PvpMedals);
+ data << uint8(MultiActionBars);
}
if (changesMask[79])
{
- data << uint16(TodayHonorableKills);
+ data << uint8(LifetimeMaxRank);
}
if (changesMask[80])
{
- data << uint16(YesterdayHonorableKills);
+ data << uint8(NumRespecs);
}
if (changesMask[81])
{
- data << uint32(LifetimeHonorableKills);
+ data << uint32(PvpMedals);
}
if (changesMask[82])
{
- data << int32(WatchedFactionIndex);
+ data << uint16(TodayHonorableKills);
}
if (changesMask[83])
{
- data << int32(MaxLevel);
+ data << uint16(YesterdayHonorableKills);
}
if (changesMask[84])
{
- data << int32(ScalingPlayerLevelDelta);
+ data << uint32(LifetimeHonorableKills);
}
if (changesMask[85])
{
- data << int32(MaxCreatureScalingLevel);
+ data << int32(WatchedFactionIndex);
}
if (changesMask[86])
{
- data << int32(PetSpellPower);
+ data << int32(MaxLevel);
}
if (changesMask[87])
{
- data << float(UiHitModifier);
+ data << int32(ScalingPlayerLevelDelta);
}
if (changesMask[88])
{
- data << float(UiSpellHitModifier);
+ data << int32(MaxCreatureScalingLevel);
}
if (changesMask[89])
{
- data << int32(HomeRealmTimeOffset);
+ data << int32(PetSpellPower);
}
if (changesMask[90])
{
- data << float(ModPetHaste);
+ data << float(UiHitModifier);
}
if (changesMask[91])
{
- data << int8(JailersTowerLevelMax);
+ data << float(UiSpellHitModifier);
}
if (changesMask[92])
{
- data << int8(JailersTowerLevel);
+ data << int32(HomeRealmTimeOffset);
}
if (changesMask[93])
{
- data << uint8(LocalRegenFlags);
+ data << float(ModPetHaste);
}
if (changesMask[94])
{
- data << uint8(AuraVision);
+ data << int8(JailersTowerLevelMax);
}
if (changesMask[95])
{
- data << uint8(NumBackpackSlots);
+ data << int8(JailersTowerLevel);
}
if (changesMask[96])
{
- data << int32(OverrideSpellsID);
+ data << uint8(LocalRegenFlags);
}
if (changesMask[97])
{
- data << uint16(LootSpecID);
+ data << uint8(AuraVision);
}
}
if (changesMask[98])
{
if (changesMask[99])
{
- data << uint32(OverrideZonePVPType);
+ data << uint8(NumBackpackSlots);
}
if (changesMask[100])
{
- data << BnetAccount;
+ data << int32(OverrideSpellsID);
}
if (changesMask[101])
{
- data << uint64(GuildClubMemberID);
+ data << uint16(LootSpecID);
}
if (changesMask[102])
{
- data << int32(Honor);
+ data << uint32(OverrideZonePVPType);
}
if (changesMask[103])
{
- data << int32(HonorNextLevel);
+ data << BnetAccount;
}
if (changesMask[104])
{
- data << uint8(NumBankSlots);
+ data << uint64(GuildClubMemberID);
+ }
+ if (changesMask[105])
+ {
+ data << int32(Honor);
+ }
+ if (changesMask[106])
+ {
+ data << int32(HonorNextLevel);
}
if (changesMask[107])
{
+ data << uint8(NumBankSlots);
+ }
+ if (changesMask[110])
+ {
data << int32(UiChromieTimeExpansionID);
}
- if (changesMask[108])
+ if (changesMask[111])
{
data << int32(TransportServerTime);
}
- if (changesMask[109])
+ if (changesMask[112])
{
data << uint32(WeeklyRewardsPeriodSinceOrigin);
}
- if (changesMask[110])
+ if (changesMask[113])
{
data << int16(DEBUGSoulbindConduitRank);
}
+ if (changesMask[115])
+ {
+ data << uint32(ActiveCombatTraitConfigID);
+ }
}
if (changesMask[98])
{
data.WriteBits(QuestSession.has_value(), 1);
- if (changesMask[106])
+ if (changesMask[109])
{
Field_1410->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
}
- if (changesMask[105])
+ if (changesMask[108])
{
if (QuestSession.has_value())
{
QuestSession->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
}
}
- if (changesMask[111])
+ if (changesMask[114])
{
data << DungeonScore;
}
}
- if (changesMask[112])
+ if (changesMask[116])
{
- for (uint32 i = 0; i < 199; ++i)
+ for (uint32 i = 0; i < 218; ++i)
{
- if (changesMask[113 + i])
+ if (changesMask[117 + i])
{
data << InvSlots[i];
}
}
}
- if (changesMask[312])
+ if (changesMask[335])
{
for (uint32 i = 0; i < 240; ++i)
{
- if (changesMask[313 + i])
+ if (changesMask[336 + i])
{
data << uint64(ExploredZones[i]);
}
}
}
- if (changesMask[553])
+ if (changesMask[576])
{
for (uint32 i = 0; i < 2; ++i)
{
- if (changesMask[554 + i])
+ if (changesMask[577 + i])
{
RestInfo[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
}
}
}
- if (changesMask[556])
+ if (changesMask[579])
{
for (uint32 i = 0; i < 7; ++i)
{
- if (changesMask[557 + i])
+ if (changesMask[580 + i])
{
data << int32(ModDamageDonePos[i]);
}
- if (changesMask[564 + i])
+ if (changesMask[587 + i])
{
data << int32(ModDamageDoneNeg[i]);
}
- if (changesMask[571 + i])
+ if (changesMask[594 + i])
{
data << float(ModDamageDonePercent[i]);
}
- if (changesMask[578 + i])
+ if (changesMask[601 + i])
{
data << float(ModHealingDonePercent[i]);
}
}
}
- if (changesMask[585])
+ if (changesMask[608])
{
for (uint32 i = 0; i < 3; ++i)
{
- if (changesMask[586 + i])
+ if (changesMask[609 + i])
{
data << float(WeaponDmgMultipliers[i]);
}
- if (changesMask[589 + i])
+ if (changesMask[612 + i])
{
data << float(WeaponAtkSpeedMultipliers[i]);
}
}
}
- if (changesMask[592])
+ if (changesMask[615])
{
for (uint32 i = 0; i < 12; ++i)
{
- if (changesMask[593 + i])
+ if (changesMask[616 + i])
{
data << uint32(BuybackPrice[i]);
}
- if (changesMask[605 + i])
+ if (changesMask[628 + i])
{
data << int64(BuybackTimestamp[i]);
}
}
}
- if (changesMask[617])
+ if (changesMask[640])
{
for (uint32 i = 0; i < 32; ++i)
{
- if (changesMask[618 + i])
+ if (changesMask[641 + i])
{
data << int32(CombatRatings[i]);
}
}
}
- if (changesMask[657])
+ if (changesMask[673])
{
for (uint32 i = 0; i < 4; ++i)
{
- if (changesMask[658 + i])
+ if (changesMask[674 + i])
{
data << uint32(NoReagentCostMask[i]);
}
}
}
- if (changesMask[662])
+ if (changesMask[678])
{
for (uint32 i = 0; i < 2; ++i)
{
- if (changesMask[663 + i])
+ if (changesMask[679 + i])
{
data << int32(ProfessionSkillLine[i]);
}
}
}
- if (changesMask[665])
+ if (changesMask[681])
{
- for (uint32 i = 0; i < 4; ++i)
+ for (uint32 i = 0; i < 5; ++i)
{
- if (changesMask[666 + i])
+ if (changesMask[682 + i])
{
data << uint32(BagSlotFlags[i]);
}
}
}
- if (changesMask[670])
+ if (changesMask[687])
{
for (uint32 i = 0; i < 7; ++i)
{
- if (changesMask[671 + i])
+ if (changesMask[688 + i])
{
data << uint32(BankBagSlotFlags[i]);
}
}
}
- if (changesMask[678])
+ if (changesMask[695])
{
for (uint32 i = 0; i < 875; ++i)
{
- if (changesMask[679 + i])
+ if (changesMask[696 + i])
{
data << uint64(QuestCompleted[i]);
}
}
}
- if (changesMask[650])
- {
- for (uint32 i = 0; i < 6; ++i)
- {
- if (changesMask[651 + i])
- {
- PvpInfo[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
- }
- }
- }
data.FlushBits();
}
@@ -4147,7 +4777,10 @@ void ActivePlayerData::ClearChangesMask()
Base::ClearChangesMask(RecipeProgression);
Base::ClearChangesMask(ReplayedQuests);
Base::ClearChangesMask(DisabledSpells);
+ Base::ClearChangesMask(PvpInfo);
Base::ClearChangesMask(CharacterRestrictions);
+ Base::ClearChangesMask(TraitConfigs);
+ Base::ClearChangesMask(CraftingOrders);
Base::ClearChangesMask(FarsightObject);
Base::ClearChangesMask(SummonedBattlePetGUID);
Base::ClearChangesMask(Coinage);
@@ -4228,6 +4861,7 @@ void ActivePlayerData::ClearChangesMask()
Base::ClearChangesMask(WeeklyRewardsPeriodSinceOrigin);
Base::ClearChangesMask(DEBUGSoulbindConduitRank);
Base::ClearChangesMask(DungeonScore);
+ Base::ClearChangesMask(ActiveCombatTraitConfigID);
Base::ClearChangesMask(InvSlots);
Base::ClearChangesMask(ExploredZones);
Base::ClearChangesMask(RestInfo);
@@ -4240,7 +4874,6 @@ void ActivePlayerData::ClearChangesMask()
Base::ClearChangesMask(BuybackPrice);
Base::ClearChangesMask(BuybackTimestamp);
Base::ClearChangesMask(CombatRatings);
- Base::ClearChangesMask(PvpInfo);
Base::ClearChangesMask(NoReagentCostMask);
Base::ClearChangesMask(ProfessionSkillLine);
Base::ClearChangesMask(BagSlotFlags);
@@ -4278,10 +4911,18 @@ void GameObjectData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fie
data << uint32(CustomParam);
data << int32(Level);
data << uint32(AnimGroupInstance);
+ data << uint32(UiWidgetItemID);
+ data << uint32(UiWidgetItemQuality);
+ data << uint32(UiWidgetItemUnknown1000);
+ data << uint32(WorldEffects.size());
for (uint32 i = 0; i < EnableDoodadSets.size(); ++i)
{
data << int32(EnableDoodadSets[i]);
}
+ for (uint32 i = 0; i < WorldEffects.size(); ++i)
+ {
+ data << int32(WorldEffects[i]);
+ }
}
void GameObjectData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, GameObject const* owner, Player const* receiver) const
@@ -4291,7 +4932,7 @@ void GameObjectData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fie
void GameObjectData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, GameObject const* owner, Player const* receiver) const
{
- data.WriteBits(changesMask.GetBlock(0), 21);
+ data.WriteBits(changesMask.GetBlock(0), 25);
if (changesMask[0])
{
@@ -4314,6 +4955,13 @@ void GameObjectData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool
else
WriteCompleteDynamicFieldUpdateMask(EnableDoodadSets.size(), data);
}
+ if (changesMask[3])
+ {
+ if (!ignoreNestedChangesMask)
+ WorldEffects.WriteUpdateMask(data);
+ else
+ WriteCompleteDynamicFieldUpdateMask(WorldEffects.size(), data);
+ }
}
data.FlushBits();
if (changesMask[0])
@@ -4330,79 +4978,101 @@ void GameObjectData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool
}
if (changesMask[3])
{
- data << int32(DisplayID);
+ for (uint32 i = 0; i < WorldEffects.size(); ++i)
+ {
+ if (WorldEffects.HasChanged(i) || ignoreNestedChangesMask)
+ {
+ data << int32(WorldEffects[i]);
+ }
+ }
}
if (changesMask[4])
{
- data << uint32(SpellVisualID);
+ data << int32(DisplayID);
}
if (changesMask[5])
{
- data << uint32(StateSpellVisualID);
+ data << uint32(SpellVisualID);
}
if (changesMask[6])
{
- data << uint32(SpawnTrackingStateAnimID);
+ data << uint32(StateSpellVisualID);
}
if (changesMask[7])
{
- data << uint32(SpawnTrackingStateAnimKitID);
+ data << uint32(SpawnTrackingStateAnimID);
}
if (changesMask[8])
{
- data << uint32(StateWorldEffectsQuestObjectiveID);
+ data << uint32(SpawnTrackingStateAnimKitID);
}
if (changesMask[9])
{
- data << CreatedBy;
+ data << uint32(StateWorldEffectsQuestObjectiveID);
}
if (changesMask[10])
{
- data << GuildGUID;
+ data << CreatedBy;
}
if (changesMask[11])
{
- data << uint32(ViewerDependentValue<FlagsTag>::GetValue(this, owner, receiver));
+ data << GuildGUID;
}
if (changesMask[12])
{
+ data << uint32(ViewerDependentValue<FlagsTag>::GetValue(this, owner, receiver));
+ }
+ if (changesMask[13])
+ {
data << float(ParentRotation->x);
data << float(ParentRotation->y);
data << float(ParentRotation->z);
data << float(ParentRotation->w);
}
- if (changesMask[13])
+ if (changesMask[14])
{
data << int32(FactionTemplate);
}
- if (changesMask[14])
+ if (changesMask[15])
{
data << int8(ViewerDependentValue<StateTag>::GetValue(this, owner, receiver));
}
- if (changesMask[15])
+ if (changesMask[16])
{
data << int8(TypeID);
}
- if (changesMask[16])
+ if (changesMask[17])
{
data << uint8(PercentHealth);
}
- if (changesMask[17])
+ if (changesMask[18])
{
data << uint32(ArtKit);
}
- if (changesMask[18])
+ if (changesMask[19])
{
data << uint32(CustomParam);
}
- if (changesMask[19])
+ if (changesMask[20])
{
data << int32(Level);
}
- if (changesMask[20])
+ if (changesMask[21])
{
data << uint32(AnimGroupInstance);
}
+ if (changesMask[22])
+ {
+ data << uint32(UiWidgetItemID);
+ }
+ if (changesMask[23])
+ {
+ data << uint32(UiWidgetItemQuality);
+ }
+ if (changesMask[24])
+ {
+ data << uint32(UiWidgetItemUnknown1000);
+ }
}
}
@@ -4410,6 +5080,7 @@ void GameObjectData::ClearChangesMask()
{
Base::ClearChangesMask(StateWorldEffectIDs);
Base::ClearChangesMask(EnableDoodadSets);
+ Base::ClearChangesMask(WorldEffects);
Base::ClearChangesMask(DisplayID);
Base::ClearChangesMask(SpellVisualID);
Base::ClearChangesMask(StateSpellVisualID);
@@ -4428,6 +5099,9 @@ void GameObjectData::ClearChangesMask()
Base::ClearChangesMask(CustomParam);
Base::ClearChangesMask(Level);
Base::ClearChangesMask(AnimGroupInstance);
+ Base::ClearChangesMask(UiWidgetItemID);
+ Base::ClearChangesMask(UiWidgetItemQuality);
+ Base::ClearChangesMask(UiWidgetItemUnknown1000);
_changesMask.ResetAll();
}
@@ -4746,6 +5420,7 @@ void AreaTriggerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fi
data << uint32(TimeToTarget);
data << uint32(TimeToTargetScale);
data << uint32(TimeToTargetExtraScale);
+ data << uint32(Field_B0);
data << int32(SpellID);
data << int32(SpellForVisuals);
SpellVisual->WriteCreate(data, owner, receiver);
@@ -4755,7 +5430,11 @@ void AreaTriggerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fi
data << uint32(Field_80);
data << uint32(Field_84);
data << Field_88;
+ data << Field_F8;
ExtraScaleCurve->WriteCreate(data, owner, receiver);
+ Field_C38->WriteCreate(data, owner, receiver);
+ Field_C54->WriteCreate(data, owner, receiver);
+ Field_C70->WriteCreate(data, owner, receiver);
VisualAnim->WriteCreate(data, owner, receiver);
}
@@ -4766,7 +5445,7 @@ void AreaTriggerData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fi
void AreaTriggerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, AreaTrigger const* owner, Player const* receiver) const
{
- data.WriteBits(changesMask.GetBlock(0), 18);
+ data.WriteBits(changesMask.GetBlock(0), 23);
data.FlushBits();
if (changesMask[0])
@@ -4775,67 +5454,87 @@ void AreaTriggerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, boo
{
OverrideScaleCurve->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
}
- if (changesMask[3])
+ if (changesMask[6])
{
data << Caster;
}
- if (changesMask[4])
+ if (changesMask[7])
{
data << uint32(Duration);
}
- if (changesMask[5])
+ if (changesMask[8])
{
data << uint32(TimeToTarget);
}
- if (changesMask[6])
+ if (changesMask[9])
{
data << uint32(TimeToTargetScale);
}
- if (changesMask[7])
+ if (changesMask[10])
{
data << uint32(TimeToTargetExtraScale);
}
- if (changesMask[8])
+ if (changesMask[11])
+ {
+ data << uint32(Field_B0);
+ }
+ if (changesMask[12])
{
data << int32(SpellID);
}
- if (changesMask[9])
+ if (changesMask[13])
{
data << int32(SpellForVisuals);
}
- if (changesMask[10])
+ if (changesMask[14])
{
SpellVisual->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
}
- if (changesMask[11])
+ if (changesMask[15])
{
data << float(BoundsRadius2D);
}
- if (changesMask[12])
+ if (changesMask[16])
{
data << uint32(DecalPropertiesID);
}
- if (changesMask[13])
+ if (changesMask[17])
{
data << CreatingEffectGUID;
}
- if (changesMask[14])
+ if (changesMask[18])
{
data << uint32(Field_80);
}
- if (changesMask[15])
+ if (changesMask[19])
{
data << uint32(Field_84);
}
- if (changesMask[16])
+ if (changesMask[20])
{
data << Field_88;
}
+ if (changesMask[21])
+ {
+ data << Field_F8;
+ }
if (changesMask[2])
{
ExtraScaleCurve->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
}
- if (changesMask[17])
+ if (changesMask[3])
+ {
+ Field_C38->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
+ }
+ if (changesMask[4])
+ {
+ Field_C54->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
+ }
+ if (changesMask[5])
+ {
+ Field_C70->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
+ }
+ if (changesMask[22])
{
VisualAnim->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
}
@@ -4846,11 +5545,15 @@ void AreaTriggerData::ClearChangesMask()
{
Base::ClearChangesMask(OverrideScaleCurve);
Base::ClearChangesMask(ExtraScaleCurve);
+ Base::ClearChangesMask(Field_C38);
+ Base::ClearChangesMask(Field_C54);
+ Base::ClearChangesMask(Field_C70);
Base::ClearChangesMask(Caster);
Base::ClearChangesMask(Duration);
Base::ClearChangesMask(TimeToTarget);
Base::ClearChangesMask(TimeToTargetScale);
Base::ClearChangesMask(TimeToTargetExtraScale);
+ Base::ClearChangesMask(Field_B0);
Base::ClearChangesMask(SpellID);
Base::ClearChangesMask(SpellForVisuals);
Base::ClearChangesMask(SpellVisual);
@@ -4860,6 +5563,7 @@ void AreaTriggerData::ClearChangesMask()
Base::ClearChangesMask(Field_80);
Base::ClearChangesMask(Field_84);
Base::ClearChangesMask(Field_88);
+ Base::ClearChangesMask(Field_F8);
Base::ClearChangesMask(VisualAnim);
_changesMask.ResetAll();
}
diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.h b/src/server/game/Entities/Object/Updates/UpdateFields.h
index 1d6d1499df8..a075a11ab81 100644
--- a/src/server/game/Entities/Object/Updates/UpdateFields.h
+++ b/src/server/game/Entities/Object/Updates/UpdateFields.h
@@ -19,6 +19,7 @@
#define UpdateFields_h__
#include "EnumFlag.h"
+#include "ItemPacketsCommon.h"
#include "MythicPlusPacketsCommon.h"
#include "ObjectGuid.h"
#include "Position.h"
@@ -115,25 +116,25 @@ struct SocketedGem : public IsUpdateFieldStructureTag, public HasChangesMask<20>
struct ItemData : public IsUpdateFieldStructureTag, public HasChangesMask<41>
{
- UpdateField<std::vector<int32>, 0, 1> BonusListIDs;
- DynamicUpdateField<UF::ArtifactPower, 0, 2> ArtifactPowers;
- DynamicUpdateField<UF::SocketedGem, 0, 3> Gems;
- UpdateField<ObjectGuid, 0, 4> Owner;
- UpdateField<ObjectGuid, 0, 5> ContainedIn;
- UpdateField<ObjectGuid, 0, 6> Creator;
- UpdateField<ObjectGuid, 0, 7> GiftCreator;
- UpdateField<uint32, 0, 8> StackCount;
- UpdateField<uint32, 0, 9> Expiration;
- UpdateField<uint32, 0, 10> DynamicFlags;
- UpdateField<uint32, 0, 11> Durability;
- UpdateField<uint32, 0, 12> MaxDurability;
- UpdateField<uint32, 0, 13> CreatePlayedTime;
- UpdateField<int32, 0, 14> Context;
- UpdateField<int64, 0, 15> CreateTime;
- UpdateField<uint64, 0, 16> ArtifactXP;
- UpdateField<uint8, 0, 17> ItemAppearanceModID;
- UpdateField<UF::ItemModList, 0, 18> Modifiers;
- UpdateField<uint32, 0, 19> DynamicFlags2;
+ DynamicUpdateField<UF::ArtifactPower, 0, 1> ArtifactPowers;
+ DynamicUpdateField<UF::SocketedGem, 0, 2> Gems;
+ UpdateField<ObjectGuid, 0, 3> Owner;
+ UpdateField<ObjectGuid, 0, 4> ContainedIn;
+ UpdateField<ObjectGuid, 0, 5> Creator;
+ UpdateField<ObjectGuid, 0, 6> GiftCreator;
+ UpdateField<uint32, 0, 7> StackCount;
+ UpdateField<uint32, 0, 8> Expiration;
+ UpdateField<uint32, 0, 9> DynamicFlags;
+ UpdateField<uint32, 0, 10> Durability;
+ UpdateField<uint32, 0, 11> MaxDurability;
+ UpdateField<uint32, 0, 12> CreatePlayedTime;
+ UpdateField<int32, 0, 13> Context;
+ UpdateField<int64, 0, 14> CreateTime;
+ UpdateField<uint64, 0, 15> ArtifactXP;
+ UpdateField<uint8, 0, 16> ItemAppearanceModID;
+ UpdateField<UF::ItemModList, 0, 17> Modifiers;
+ UpdateField<uint32, 0, 18> DynamicFlags2;
+ UpdateField<WorldPackets::Item::ItemBonusKey, 0, 19> ItemBonusKey;
UpdateField<uint16, 0, 20> DEBUGItemLevel;
UpdateFieldArray<int32, 5, 21, 22> SpellCharges;
UpdateFieldArray<UF::ItemEnchantment, 13, 27, 28> Enchantment;
@@ -254,7 +255,7 @@ struct PassiveSpellHistory : public IsUpdateFieldStructureTag
bool operator!=(PassiveSpellHistory const& right) const { return !(*this == right); }
};
-struct UnitData : public IsUpdateFieldStructureTag, public HasChangesMask<194>
+struct UnitData : public IsUpdateFieldStructureTag, public HasChangesMask<196>
{
UpdateField<std::vector<uint32>, 0, 1> StateWorldEffectIDs;
DynamicUpdateField<UF::PassiveSpellHistory, 0, 2> PassiveSpells;
@@ -279,119 +280,121 @@ struct UnitData : public IsUpdateFieldStructureTag, public HasChangesMask<194>
UpdateField<ObjectGuid, 0, 20> BattlePetCompanionGUID;
UpdateField<uint64, 0, 21> BattlePetDBID;
UpdateField<UF::UnitChannel, 0, 22> ChannelData;
- UpdateField<uint32, 0, 23> SummonedByHomeRealm;
- UpdateField<uint8, 0, 24> Race;
- UpdateField<uint8, 0, 25> ClassId;
- UpdateField<uint8, 0, 26> PlayerClassId;
- UpdateField<uint8, 0, 27> Sex;
- UpdateField<uint8, 0, 28> DisplayPower;
- UpdateField<uint32, 0, 29> OverrideDisplayPowerID;
- UpdateField<int64, 0, 30> Health;
- UpdateField<int64, 0, 31> MaxHealth;
- UpdateField<int32, 32, 33> Level;
- UpdateField<int32, 32, 34> EffectiveLevel;
- UpdateField<int32, 32, 35> ContentTuningID;
- UpdateField<int32, 32, 36> ScalingLevelMin;
- UpdateField<int32, 32, 37> ScalingLevelMax;
- UpdateField<int32, 32, 38> ScalingLevelDelta;
- UpdateField<int32, 32, 39> ScalingFactionGroup;
- UpdateField<int32, 32, 40> ScalingHealthItemLevelCurveID;
- UpdateField<int32, 32, 41> ScalingDamageItemLevelCurveID;
- UpdateField<int32, 32, 42> FactionTemplate;
+ UpdateField<int8, 0, 23> SpellEmpowerStage;
+ UpdateField<uint32, 0, 24> SummonedByHomeRealm;
+ UpdateField<uint8, 0, 25> Race;
+ UpdateField<uint8, 0, 26> ClassId;
+ UpdateField<uint8, 0, 27> PlayerClassId;
+ UpdateField<uint8, 0, 28> Sex;
+ UpdateField<uint8, 0, 29> DisplayPower;
+ UpdateField<uint32, 0, 30> OverrideDisplayPowerID;
+ UpdateField<int64, 0, 31> Health;
+ UpdateField<int64, 32, 33> MaxHealth;
+ UpdateField<int32, 32, 34> Level;
+ UpdateField<int32, 32, 35> EffectiveLevel;
+ UpdateField<int32, 32, 36> ContentTuningID;
+ UpdateField<int32, 32, 37> ScalingLevelMin;
+ UpdateField<int32, 32, 38> ScalingLevelMax;
+ UpdateField<int32, 32, 39> ScalingLevelDelta;
+ UpdateField<int32, 32, 40> ScalingFactionGroup;
+ UpdateField<int32, 32, 41> ScalingHealthItemLevelCurveID;
+ UpdateField<int32, 32, 42> ScalingDamageItemLevelCurveID;
+ UpdateField<int32, 32, 43> FactionTemplate;
struct FactionTemplateTag : ViewerDependentValueTag<int32> {};
- UpdateField<uint32, 32, 43> Flags;
+ UpdateField<uint32, 32, 44> Flags;
struct FlagsTag : ViewerDependentValueTag<uint32> {};
- UpdateField<uint32, 32, 44> Flags2;
- UpdateField<uint32, 32, 45> Flags3;
+ UpdateField<uint32, 32, 45> Flags2;
+ UpdateField<uint32, 32, 46> Flags3;
struct Flags3Tag : ViewerDependentValueTag<uint32> {};
- UpdateField<uint32, 32, 46> AuraState;
+ UpdateField<uint32, 32, 47> AuraState;
struct AuraStateTag : ViewerDependentValueTag<uint32> {};
- UpdateField<uint32, 32, 47> RangedAttackRoundBaseTime;
- UpdateField<float, 32, 48> BoundingRadius;
- UpdateField<float, 32, 49> CombatReach;
- UpdateField<float, 32, 50> DisplayScale;
- UpdateField<int32, 32, 51> CreatureFamily;
- UpdateField<int32, 32, 52> CreatureType;
- UpdateField<int32, 32, 53> NativeDisplayID;
- UpdateField<float, 32, 54> NativeXDisplayScale;
- UpdateField<int32, 32, 55> MountDisplayID;
- UpdateField<int32, 32, 56> CosmeticMountDisplayID;
- UpdateField<float, 32, 57> MinDamage;
- UpdateField<float, 32, 58> MaxDamage;
- UpdateField<float, 32, 59> MinOffHandDamage;
- UpdateField<float, 32, 60> MaxOffHandDamage;
- UpdateField<uint8, 32, 61> StandState;
- UpdateField<uint8, 32, 62> PetTalentPoints;
- UpdateField<uint8, 32, 63> VisFlags;
- UpdateField<uint8, 64, 65> AnimTier;
- UpdateField<uint32, 64, 66> PetNumber;
- UpdateField<uint32, 64, 67> PetNameTimestamp;
- UpdateField<uint32, 64, 68> PetExperience;
- UpdateField<uint32, 64, 69> PetNextLevelExperience;
- UpdateField<float, 64, 70> ModCastingSpeed;
- UpdateField<float, 64, 71> ModCastingSpeedNeg;
- UpdateField<float, 64, 72> ModSpellHaste;
- UpdateField<float, 64, 73> ModHaste;
- UpdateField<float, 64, 74> ModRangedHaste;
- UpdateField<float, 64, 75> ModHasteRegen;
- UpdateField<float, 64, 76> ModTimeRate;
- UpdateField<int32, 64, 77> CreatedBySpell;
- UpdateField<int32, 64, 78> EmoteState;
- UpdateField<int32, 64, 79> BaseMana;
- UpdateField<int32, 64, 80> BaseHealth;
- UpdateField<uint8, 64, 81> SheatheState;
- UpdateField<uint8, 64, 82> PvpFlags;
+ UpdateField<uint32, 32, 48> RangedAttackRoundBaseTime;
+ UpdateField<float, 32, 49> BoundingRadius;
+ UpdateField<float, 32, 50> CombatReach;
+ UpdateField<float, 32, 51> DisplayScale;
+ UpdateField<int32, 32, 52> CreatureFamily;
+ UpdateField<int32, 32, 53> CreatureType;
+ UpdateField<int32, 32, 54> NativeDisplayID;
+ UpdateField<float, 32, 55> NativeXDisplayScale;
+ UpdateField<int32, 32, 56> MountDisplayID;
+ UpdateField<int32, 32, 57> CosmeticMountDisplayID;
+ UpdateField<float, 32, 58> MinDamage;
+ UpdateField<float, 32, 59> MaxDamage;
+ UpdateField<float, 32, 60> MinOffHandDamage;
+ UpdateField<float, 32, 61> MaxOffHandDamage;
+ UpdateField<uint8, 32, 62> StandState;
+ UpdateField<uint8, 32, 63> PetTalentPoints;
+ UpdateField<uint8, 64, 65> VisFlags;
+ UpdateField<uint8, 64, 66> AnimTier;
+ UpdateField<uint32, 64, 67> PetNumber;
+ UpdateField<uint32, 64, 68> PetNameTimestamp;
+ UpdateField<uint32, 64, 69> PetExperience;
+ UpdateField<uint32, 64, 70> PetNextLevelExperience;
+ UpdateField<float, 64, 71> ModCastingSpeed;
+ UpdateField<float, 64, 72> ModCastingSpeedNeg;
+ UpdateField<float, 64, 73> ModSpellHaste;
+ UpdateField<float, 64, 74> ModHaste;
+ UpdateField<float, 64, 75> ModRangedHaste;
+ UpdateField<float, 64, 76> ModHasteRegen;
+ UpdateField<float, 64, 77> ModTimeRate;
+ UpdateField<int32, 64, 78> CreatedBySpell;
+ UpdateField<int32, 64, 79> EmoteState;
+ UpdateField<int32, 64, 80> BaseMana;
+ UpdateField<int32, 64, 81> BaseHealth;
+ UpdateField<uint8, 64, 82> SheatheState;
+ UpdateField<uint8, 64, 83> PvpFlags;
struct PvpFlagsTag : ViewerDependentValueTag<uint8> {};
- UpdateField<uint8, 64, 83> PetFlags;
- UpdateField<uint8, 64, 84> ShapeshiftForm;
- UpdateField<int32, 64, 85> AttackPower;
- UpdateField<int32, 64, 86> AttackPowerModPos;
- UpdateField<int32, 64, 87> AttackPowerModNeg;
- UpdateField<float, 64, 88> AttackPowerMultiplier;
- UpdateField<int32, 64, 89> RangedAttackPower;
- UpdateField<int32, 64, 90> RangedAttackPowerModPos;
- UpdateField<int32, 64, 91> RangedAttackPowerModNeg;
- UpdateField<float, 64, 92> RangedAttackPowerMultiplier;
- UpdateField<int32, 64, 93> MainHandWeaponAttackPower;
- UpdateField<int32, 64, 94> OffHandWeaponAttackPower;
- UpdateField<int32, 64, 95> RangedWeaponAttackPower;
- UpdateField<int32, 96, 97> SetAttackSpeedAura;
- UpdateField<float, 96, 98> Lifesteal;
- UpdateField<float, 96, 99> MinRangedDamage;
- UpdateField<float, 96, 100> MaxRangedDamage;
- UpdateField<float, 96, 101> ManaCostMultiplier;
- UpdateField<float, 96, 102> MaxHealthModifier;
- UpdateField<float, 96, 103> HoverHeight;
- UpdateField<int32, 96, 104> MinItemLevelCutoff;
- UpdateField<int32, 96, 105> MinItemLevel;
- UpdateField<int32, 96, 106> MaxItemLevel;
- UpdateField<int32, 96, 107> AzeriteItemLevel;
- UpdateField<int32, 96, 108> WildBattlePetLevel;
- UpdateField<int32, 96, 109> BattlePetCompanionExperience;
- UpdateField<uint32, 96, 110> BattlePetCompanionNameTimestamp;
- UpdateField<int32, 96, 111> InteractSpellID;
- UpdateField<int32, 96, 112> ScaleDuration;
- UpdateField<int32, 96, 113> LooksLikeMountID;
- UpdateField<int32, 96, 114> LooksLikeCreatureID;
- UpdateField<int32, 96, 115> LookAtControllerID;
- UpdateField<int32, 96, 116> TaxiNodesID;
- UpdateField<ObjectGuid, 96, 117> GuildGUID;
- UpdateField<uint32, 96, 118> SilencedSchoolMask;
- UpdateField<ObjectGuid, 96, 119> NameplateAttachToGUID; // When set, nameplate of this unit will instead appear on that object
- UpdateFieldArray<uint32, 2, 120, 121> NpcFlags;
+ UpdateField<uint8, 64, 84> PetFlags;
+ UpdateField<uint8, 64, 85> ShapeshiftForm;
+ UpdateField<int32, 64, 86> AttackPower;
+ UpdateField<int32, 64, 87> AttackPowerModPos;
+ UpdateField<int32, 64, 88> AttackPowerModNeg;
+ UpdateField<float, 64, 89> AttackPowerMultiplier;
+ UpdateField<int32, 64, 90> RangedAttackPower;
+ UpdateField<int32, 64, 91> RangedAttackPowerModPos;
+ UpdateField<int32, 64, 92> RangedAttackPowerModNeg;
+ UpdateField<float, 64, 93> RangedAttackPowerMultiplier;
+ UpdateField<int32, 64, 94> MainHandWeaponAttackPower;
+ UpdateField<int32, 64, 95> OffHandWeaponAttackPower;
+ UpdateField<int32, 96, 97> RangedWeaponAttackPower;
+ UpdateField<int32, 96, 98> SetAttackSpeedAura;
+ UpdateField<float, 96, 99> Lifesteal;
+ UpdateField<float, 96, 100> MinRangedDamage;
+ UpdateField<float, 96, 101> MaxRangedDamage;
+ UpdateField<float, 96, 102> ManaCostMultiplier;
+ UpdateField<float, 96, 103> MaxHealthModifier;
+ UpdateField<float, 96, 104> HoverHeight;
+ UpdateField<int32, 96, 105> MinItemLevelCutoff;
+ UpdateField<int32, 96, 106> MinItemLevel;
+ UpdateField<int32, 96, 107> MaxItemLevel;
+ UpdateField<int32, 96, 108> AzeriteItemLevel;
+ UpdateField<int32, 96, 109> WildBattlePetLevel;
+ UpdateField<int32, 96, 110> BattlePetCompanionExperience;
+ UpdateField<uint32, 96, 111> BattlePetCompanionNameTimestamp;
+ UpdateField<int32, 96, 112> InteractSpellID;
+ UpdateField<int32, 96, 113> ScaleDuration;
+ UpdateField<int32, 96, 114> LooksLikeMountID;
+ UpdateField<int32, 96, 115> LooksLikeCreatureID;
+ UpdateField<int32, 96, 116> LookAtControllerID;
+ UpdateField<int32, 96, 117> TaxiNodesID;
+ UpdateField<ObjectGuid, 96, 118> GuildGUID;
+ UpdateField<int32, 96, 119> FlightCapabilityID;
+ UpdateField<uint32, 96, 120> SilencedSchoolMask;
+ UpdateField<ObjectGuid, 96, 121> NameplateAttachToGUID; // When set, nameplate of this unit will instead appear on that object
+ UpdateFieldArray<uint32, 2, 122, 123> NpcFlags;
struct NpcFlagsTag : ViewerDependentValueTag<uint32> {};
- UpdateFieldArray<int32, 7, 123, 124> Power;
- UpdateFieldArray<int32, 7, 123, 131> MaxPower;
- UpdateFieldArray<float, 7, 123, 138> PowerRegenFlatModifier;
- UpdateFieldArray<float, 7, 123, 145> PowerRegenInterruptedFlatModifier;
- UpdateFieldArray<UF::VisibleItem, 3, 152, 153> VirtualItems;
- UpdateFieldArray<uint32, 2, 156, 157> AttackRoundBaseTime;
- UpdateFieldArray<int32, 4, 159, 160> Stats;
- UpdateFieldArray<int32, 4, 159, 164> StatPosBuff;
- UpdateFieldArray<int32, 4, 159, 168> StatNegBuff;
- UpdateFieldArray<int32, 7, 172, 173> Resistances;
- UpdateFieldArray<int32, 7, 172, 180> BonusResistanceMods;
- UpdateFieldArray<int32, 7, 172, 187> ManaCostModifier;
+ UpdateFieldArray<int32, 7, 125, 126> Power;
+ UpdateFieldArray<int32, 7, 125, 133> MaxPower;
+ UpdateFieldArray<float, 7, 125, 140> PowerRegenFlatModifier;
+ UpdateFieldArray<float, 7, 125, 147> PowerRegenInterruptedFlatModifier;
+ UpdateFieldArray<UF::VisibleItem, 3, 154, 155> VirtualItems;
+ UpdateFieldArray<uint32, 2, 158, 159> AttackRoundBaseTime;
+ UpdateFieldArray<int32, 4, 161, 162> Stats;
+ UpdateFieldArray<int32, 4, 161, 166> StatPosBuff;
+ UpdateFieldArray<int32, 4, 161, 170> StatNegBuff;
+ UpdateFieldArray<int32, 7, 174, 175> Resistances;
+ UpdateFieldArray<int32, 7, 174, 182> BonusResistanceMods;
+ UpdateFieldArray<int32, 7, 174, 189> ManaCostModifier;
void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Unit const* owner, Player const* receiver) const;
void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Unit const* owner, Player const* receiver) const;
@@ -453,44 +456,46 @@ struct CTROptions : public IsUpdateFieldStructureTag
bool operator!=(CTROptions const& right) const { return !(*this == right); }
};
-struct PlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<188>
+struct PlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<190>
{
UpdateField<bool, 0, 1> HasQuestSession;
UpdateField<bool, 0, 2> HasLevelLink;
DynamicUpdateField<UF::ChrCustomizationChoice, 0, 3> Customizations;
DynamicUpdateField<UF::QuestLog, 0, 4> QuestSessionQuestLog;
DynamicUpdateField<UF::ArenaCooldown, 0, 5> ArenaCooldowns;
- UpdateField<ObjectGuid, 0, 6> DuelArbiter;
- UpdateField<ObjectGuid, 0, 7> WowAccount;
- UpdateField<ObjectGuid, 0, 8> LootTargetGUID;
- UpdateField<uint32, 0, 9> PlayerFlags;
- UpdateField<uint32, 0, 10> PlayerFlagsEx;
- UpdateField<uint32, 0, 11> GuildRankID;
- UpdateField<uint32, 0, 12> GuildDeleteDate;
- UpdateField<int32, 0, 13> GuildLevel;
- UpdateField<uint8, 0, 14> PartyType;
- UpdateField<uint8, 0, 15> NativeSex;
- UpdateField<uint8, 0, 16> Inebriation;
- UpdateField<uint8, 0, 17> PvpTitle;
- UpdateField<uint8, 0, 18> ArenaFaction;
- UpdateField<uint32, 0, 19> DuelTeam;
- UpdateField<int32, 0, 20> GuildTimeStamp;
- UpdateField<int32, 0, 21> PlayerTitle;
- UpdateField<int32, 0, 22> FakeInebriation;
- UpdateField<uint32, 0, 23> VirtualPlayerRealm;
- UpdateField<uint32, 0, 24> CurrentSpecID;
- UpdateField<int32, 0, 25> TaxiMountAnimKitID;
- UpdateField<uint8, 0, 26> CurrentBattlePetBreedQuality;
- UpdateField<int32, 0, 27> HonorLevel;
- UpdateField<int32, 0, 28> Field_B0;
- UpdateField<int32, 0, 29> Field_B4;
- UpdateField<UF::CTROptions, 0, 30> CtrOptions;
- UpdateField<int32, 0, 31> CovenantID;
- UpdateField<int32, 32, 33> SoulbindID;
- UpdateField<WorldPackets::MythicPlus::DungeonScoreSummary, 32, 34> DungeonScore;
- UpdateFieldArray<UF::QuestLog, 125, 35, 36> QuestLog;
- UpdateFieldArray<UF::VisibleItem, 19, 161, 162> VisibleItems;
- UpdateFieldArray<float, 6, 181, 182> AvgItemLevel;
+ DynamicUpdateField<int32, 0, 6> VisualItemReplacements;
+ UpdateField<ObjectGuid, 0, 7> DuelArbiter;
+ UpdateField<ObjectGuid, 0, 8> WowAccount;
+ UpdateField<ObjectGuid, 0, 9> LootTargetGUID;
+ UpdateField<uint32, 0, 10> PlayerFlags;
+ UpdateField<uint32, 0, 11> PlayerFlagsEx;
+ UpdateField<uint32, 0, 12> GuildRankID;
+ UpdateField<uint32, 0, 13> GuildDeleteDate;
+ UpdateField<int32, 0, 14> GuildLevel;
+ UpdateField<uint8, 0, 15> PartyType;
+ UpdateField<uint8, 0, 16> NativeSex;
+ UpdateField<uint8, 0, 17> Inebriation;
+ UpdateField<uint8, 0, 18> PvpTitle;
+ UpdateField<uint8, 0, 19> ArenaFaction;
+ UpdateField<uint32, 0, 20> DuelTeam;
+ UpdateField<int32, 0, 21> GuildTimeStamp;
+ UpdateField<int32, 0, 22> PlayerTitle;
+ UpdateField<int32, 0, 23> FakeInebriation;
+ UpdateField<uint32, 0, 24> VirtualPlayerRealm;
+ UpdateField<uint32, 0, 25> CurrentSpecID;
+ UpdateField<int32, 0, 26> TaxiMountAnimKitID;
+ UpdateField<uint8, 0, 27> CurrentBattlePetBreedQuality;
+ UpdateField<int32, 0, 28> HonorLevel;
+ UpdateField<int64, 0, 29> LogoutTime;
+ UpdateField<int32, 0, 30> Field_B0;
+ UpdateField<int32, 0, 31> Field_B4;
+ UpdateField<UF::CTROptions, 32, 33> CtrOptions;
+ UpdateField<int32, 32, 34> CovenantID;
+ UpdateField<int32, 32, 35> SoulbindID;
+ UpdateField<WorldPackets::MythicPlus::DungeonScoreSummary, 32, 36> DungeonScore;
+ UpdateFieldArray<UF::QuestLog, 125, 37, 38> QuestLog;
+ UpdateFieldArray<UF::VisibleItem, 19, 163, 164> VisibleItems;
+ UpdateFieldArray<float, 6, 183, 184> AvgItemLevel;
void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const;
void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const;
@@ -526,20 +531,26 @@ struct RestInfo : public IsUpdateFieldStructureTag, public HasChangesMask<3>
void ClearChangesMask();
};
-struct PVPInfo : public IsUpdateFieldStructureTag, public HasChangesMask<13>
+struct PVPInfo : public IsUpdateFieldStructureTag, public HasChangesMask<19>
{
UpdateField<bool, 0, 1> Disqualified;
- UpdateField<uint32, 0, 2> WeeklyPlayed;
- UpdateField<uint32, 0, 3> WeeklyWon;
- UpdateField<uint32, 0, 4> SeasonPlayed;
- UpdateField<uint32, 0, 5> SeasonWon;
- UpdateField<uint32, 0, 6> Rating;
- UpdateField<uint32, 0, 7> WeeklyBestRating;
- UpdateField<uint32, 0, 8> SeasonBestRating;
- UpdateField<uint32, 0, 9> PvpTierID;
- UpdateField<uint32, 0, 10> WeeklyBestWinPvpTierID;
- UpdateField<uint32, 0, 11> Field_28;
- UpdateField<uint32, 0, 12> Field_2C;
+ UpdateField<int8, 0, 2> Bracket;
+ UpdateField<int32, 0, 3> PvpRatingID;
+ UpdateField<uint32, 0, 4> WeeklyPlayed;
+ UpdateField<uint32, 0, 5> WeeklyWon;
+ UpdateField<uint32, 0, 6> SeasonPlayed;
+ UpdateField<uint32, 0, 7> SeasonWon;
+ UpdateField<uint32, 0, 8> Rating;
+ UpdateField<uint32, 0, 9> WeeklyBestRating;
+ UpdateField<uint32, 0, 10> SeasonBestRating;
+ UpdateField<uint32, 0, 11> PvpTierID;
+ UpdateField<uint32, 0, 12> WeeklyBestWinPvpTierID;
+ UpdateField<uint32, 0, 13> Field_28;
+ UpdateField<uint32, 0, 14> Field_2C;
+ UpdateField<uint32, 0, 15> WeeklyRoundsPlayed;
+ UpdateField<uint32, 0, 16> WeeklyRoundsWon;
+ UpdateField<uint32, 0, 17> SeasonRoundsPlayed;
+ UpdateField<uint32, 0, 18> SeasonRoundsWon;
void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
@@ -656,133 +667,220 @@ struct ReplayedQuest : public IsUpdateFieldStructureTag, public HasChangesMask<3
void ClearChangesMask();
};
-struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<1554>
+struct TraitEntry : public IsUpdateFieldStructureTag
+{
+ int32 TraitNodeID;
+ int32 TraitNodeEntryID;
+ int32 Rank;
+ int32 GrantedRanks;
+
+ void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
+ void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
+ bool operator==(TraitEntry const& right) const;
+ bool operator!=(TraitEntry const& right) const { return !(*this == right); }
+};
+
+struct TraitConfig : public IsUpdateFieldStructureTag, public HasChangesMask<12>
+{
+ DynamicUpdateField<UF::TraitEntry, 0, 1> Entries;
+ UpdateField<int32, 0, 2> ID;
+ UpdateField<std::string, 0, 3> Name;
+ UpdateField<int32, 4, 5> Type;
+ UpdateField<int32, 4, 6> SkillLineID;
+ UpdateField<int32, 4, 7> ChrSpecializationID;
+ UpdateField<int32, 8, 9> CombatConfigFlags;
+ UpdateField<int32, 8, 10> LocalIdentifier;
+ UpdateField<int32, 8, 11> TraitSystemID;
+
+ void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
+ void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
+ void ClearChangesMask();
+};
+
+struct CraftingOrderItem : public IsUpdateFieldStructureTag, public HasChangesMask<7>
+{
+ UpdateField<uint64, -1, 0> Field_0;
+ UpdateField<ObjectGuid, -1, 1> ItemGUID;
+ UpdateField<ObjectGuid, -1, 2> OwnerGUID;
+ UpdateField<int32, -1, 3> ItemID;
+ UpdateField<uint32, -1, 4> Quantity;
+ UpdateField<int32, -1, 5> ReagentQuality;
+ OptionalUpdateField<uint8, -1, 6> DataSlotIndex;
+
+ void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
+ void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
+ void ClearChangesMask();
+};
+
+struct CraftingOrderData : public IsUpdateFieldStructureTag, public HasChangesMask<24>
+{
+ DynamicUpdateField<UF::CraftingOrderItem, 0, 1> Reagents;
+ UpdateField<int32, 0, 2> Field_0;
+ UpdateField<uint64, 0, 3> OrderID;
+ UpdateField<int32, 0, 4> SkillLineAbilityID;
+ UpdateField<uint8, 5, 6> OrderState;
+ UpdateField<uint8, 5, 7> OrderType;
+ UpdateField<uint8, 5, 8> MinQuality;
+ UpdateField<int64, 5, 9> ExpirationTime;
+ UpdateField<int64, 10, 11> ClaimEndTime;
+ UpdateField<int64, 10, 12> TipAmount;
+ UpdateField<int64, 10, 13> ConsortiumCut;
+ UpdateField<uint32, 10, 14> Flags;
+ UpdateField<ObjectGuid, 15, 16> CustomerGUID;
+ UpdateField<ObjectGuid, 15, 17> CustomerAccountGUID;
+ UpdateField<ObjectGuid, 15, 18> CrafterGUID;
+ UpdateField<ObjectGuid, 15, 19> PersonalCrafterGUID;
+ UpdateField<std::string, 20, 21> CustomerNotes;
+ OptionalUpdateField<UF::CraftingOrderItem, 20, 22> OutputItem;
+ OptionalUpdateField<WorldPackets::Item::ItemInstance, 20, 23> OutputItemData;
+
+ void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
+ void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
+ void ClearChangesMask();
+};
+
+struct CraftingOrder : public IsUpdateFieldStructureTag, public HasChangesMask<4>
+{
+ DynamicUpdateField<WorldPackets::Item::ItemEnchantData, -1, 0> Enchantments;
+ DynamicUpdateField<WorldPackets::Item::ItemGemData, -1, 1> Gems;
+ UpdateField<UF::CraftingOrderData, -1, 2> Data;
+ OptionalUpdateField<WorldPackets::Item::ItemInstance, -1, 3> RecraftItemInfo;
+
+ void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
+ void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
+ void ClearChangesMask();
+};
+
+struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<1571>
{
UpdateField<bool, 0, 1> BackpackAutoSortDisabled;
UpdateField<bool, 0, 2> BankAutoSortDisabled;
UpdateField<bool, 0, 3> SortBagsRightToLeft;
UpdateField<bool, 0, 4> InsertItemsLeftToRight;
- UpdateFieldArray<DynamicUpdateFieldBase<UF::Research>, 1, 27, 28> Research;
+ UpdateFieldArray<DynamicUpdateFieldBase<UF::Research>, 1, 30, 31> Research;
DynamicUpdateField<uint64, 0, 5> KnownTitles;
- DynamicUpdateField<uint16, 0, 6> ResearchSites;
- DynamicUpdateField<uint32, 0, 7> ResearchSiteProgress;
- DynamicUpdateField<int32, 0, 8> DailyQuestsCompleted;
- DynamicUpdateField<int32, 0, 9> AvailableQuestLineXQuestIDs;
- DynamicUpdateField<int32, 0, 10> Heirlooms;
- DynamicUpdateField<uint32, 0, 11> HeirloomFlags;
- DynamicUpdateField<int32, 0, 12> Toys;
- DynamicUpdateField<uint32, 0, 13> ToyFlags;
- DynamicUpdateField<uint32, 0, 14> Transmog;
- DynamicUpdateField<int32, 0, 15> ConditionalTransmog;
- DynamicUpdateField<int32, 0, 16> SelfResSpells;
- DynamicUpdateField<uint32, 0, 17> RuneforgePowers;
- DynamicUpdateField<uint32, 0, 18> TransmogIllusions;
- DynamicUpdateField<UF::SpellPctModByLabel, 0, 20> SpellPctModByLabel;
- DynamicUpdateField<UF::SpellFlatModByLabel, 0, 21> SpellFlatModByLabel;
- DynamicUpdateField<UF::MawPower, 0, 22> MawPowers;
- DynamicUpdateField<UF::MultiFloorExplore, 0, 23> MultiFloorExploration;
- DynamicUpdateField<UF::RecipeProgressionInfo, 0, 24> RecipeProgression;
- DynamicUpdateField<UF::ReplayedQuest, 0, 25> ReplayedQuests;
- DynamicUpdateField<int32, 0, 26> DisabledSpells;
- DynamicUpdateField<UF::CharacterRestriction, 0, 19> CharacterRestrictions;
- UpdateField<ObjectGuid, 0, 29> FarsightObject;
- UpdateField<ObjectGuid, 0, 30> SummonedBattlePetGUID;
- UpdateField<uint64, 0, 31> Coinage;
- UpdateField<int32, 0, 32> XP;
- UpdateField<int32, 0, 33> NextLevelXP;
- UpdateField<int32, 34, 35> TrialXP;
- UpdateField<UF::SkillInfo, 34, 36> Skill;
- UpdateField<int32, 34, 37> CharacterPoints;
- UpdateField<int32, 34, 38> MaxTalentTiers;
- UpdateField<uint32, 34, 39> TrackCreatureMask;
- UpdateField<float, 34, 40> MainhandExpertise;
- UpdateField<float, 34, 41> OffhandExpertise;
- UpdateField<float, 34, 42> RangedExpertise;
- UpdateField<float, 34, 43> CombatRatingExpertise;
- UpdateField<float, 34, 44> BlockPercentage;
- UpdateField<float, 34, 45> DodgePercentage;
- UpdateField<float, 34, 46> DodgePercentageFromAttribute;
- UpdateField<float, 34, 47> ParryPercentage;
- UpdateField<float, 34, 48> ParryPercentageFromAttribute;
- UpdateField<float, 34, 49> CritPercentage;
- UpdateField<float, 34, 50> RangedCritPercentage;
- UpdateField<float, 34, 51> OffhandCritPercentage;
- UpdateField<float, 34, 52> SpellCritPercentage;
- UpdateField<int32, 34, 53> ShieldBlock;
- UpdateField<float, 34, 54> ShieldBlockCritPercentage;
- UpdateField<float, 34, 55> Mastery;
- UpdateField<float, 34, 56> Speed;
- UpdateField<float, 34, 57> Avoidance;
- UpdateField<float, 34, 58> Sturdiness;
- UpdateField<int32, 34, 59> Versatility;
- UpdateField<float, 34, 60> VersatilityBonus;
- UpdateField<float, 34, 61> PvpPowerDamage;
- UpdateField<float, 34, 62> PvpPowerHealing;
- UpdateField<int32, 34, 63> ModHealingDonePos;
- UpdateField<float, 34, 64> ModHealingPercent;
- UpdateField<float, 34, 65> ModPeriodicHealingDonePercent;
- UpdateField<float, 66, 67> ModSpellPowerPercent;
- UpdateField<float, 66, 68> ModResiliencePercent;
- UpdateField<float, 66, 69> OverrideSpellPowerByAPPercent;
- UpdateField<float, 66, 70> OverrideAPBySpellPowerPercent;
- UpdateField<int32, 66, 71> ModTargetResistance;
- UpdateField<int32, 66, 72> ModTargetPhysicalResistance;
- UpdateField<uint32, 66, 73> LocalFlags;
- UpdateField<uint8, 66, 74> GrantableLevels;
- UpdateField<uint8, 66, 75> MultiActionBars;
- UpdateField<uint8, 66, 76> LifetimeMaxRank;
- UpdateField<uint8, 66, 77> NumRespecs;
- UpdateField<uint32, 66, 78> PvpMedals;
- UpdateField<uint16, 66, 79> TodayHonorableKills;
- UpdateField<uint16, 66, 80> YesterdayHonorableKills;
- UpdateField<uint32, 66, 81> LifetimeHonorableKills;
- UpdateField<int32, 66, 82> WatchedFactionIndex;
- UpdateField<int32, 66, 83> MaxLevel;
- UpdateField<int32, 66, 84> ScalingPlayerLevelDelta;
- UpdateField<int32, 66, 85> MaxCreatureScalingLevel;
- UpdateField<int32, 66, 86> PetSpellPower;
- UpdateField<float, 66, 87> UiHitModifier;
- UpdateField<float, 66, 88> UiSpellHitModifier;
- UpdateField<int32, 66, 89> HomeRealmTimeOffset;
- UpdateField<float, 66, 90> ModPetHaste;
- UpdateField<int8, 66, 91> JailersTowerLevelMax;
- UpdateField<int8, 66, 92> JailersTowerLevel;
- UpdateField<uint8, 66, 93> LocalRegenFlags;
- UpdateField<uint8, 66, 94> AuraVision;
- UpdateField<uint8, 66, 95> NumBackpackSlots;
- UpdateField<int32, 66, 96> OverrideSpellsID;
- UpdateField<uint16, 66, 97> LootSpecID;
- UpdateField<uint32, 98, 99> OverrideZonePVPType;
- UpdateField<ObjectGuid, 98, 100> BnetAccount;
- UpdateField<uint64, 98, 101> GuildClubMemberID;
- UpdateField<int32, 98, 102> Honor;
- UpdateField<int32, 98, 103> HonorNextLevel;
- UpdateField<uint8, 98, 104> NumBankSlots;
- UpdateField<UF::ActivePlayerUnk901, 98, 106> Field_1410;
- OptionalUpdateField<UF::QuestSession, 98, 105> QuestSession;
- UpdateField<int32, 98, 107> UiChromieTimeExpansionID;
- UpdateField<int32, 98, 108> TransportServerTime;
- UpdateField<uint32, 98, 109> WeeklyRewardsPeriodSinceOrigin; // week count since Cfg_RegionsEntry::ChallengeOrigin
- UpdateField<int16, 98, 110> DEBUGSoulbindConduitRank;
- UpdateField<WorldPackets::MythicPlus::DungeonScoreData, 98, 111> DungeonScore;
- UpdateFieldArray<ObjectGuid, 199, 112, 113> InvSlots;
- UpdateFieldArray<uint64, 240, 312, 313> ExploredZones;
- UpdateFieldArray<UF::RestInfo, 2, 553, 554> RestInfo;
- UpdateFieldArray<int32, 7, 556, 557> ModDamageDonePos;
- UpdateFieldArray<int32, 7, 556, 564> ModDamageDoneNeg;
- UpdateFieldArray<float, 7, 556, 571> ModDamageDonePercent;
- UpdateFieldArray<float, 7, 556, 578> ModHealingDonePercent;
- UpdateFieldArray<float, 3, 585, 586> WeaponDmgMultipliers;
- UpdateFieldArray<float, 3, 585, 589> WeaponAtkSpeedMultipliers;
- UpdateFieldArray<uint32, 12, 592, 593> BuybackPrice;
- UpdateFieldArray<int64, 12, 592, 605> BuybackTimestamp;
- UpdateFieldArray<int32, 32, 617, 618> CombatRatings;
- UpdateFieldArray<UF::PVPInfo, 6, 650, 651> PvpInfo;
- UpdateFieldArray<uint32, 4, 657, 658> NoReagentCostMask;
- UpdateFieldArray<int32, 2, 662, 663> ProfessionSkillLine;
- UpdateFieldArray<uint32, 4, 665, 666> BagSlotFlags;
- UpdateFieldArray<uint32, 7, 670, 671> BankBagSlotFlags;
- UpdateFieldArray<uint64, 875, 678, 679> QuestCompleted;
+ DynamicUpdateField<uint16, 0, 7> ResearchSites;
+ DynamicUpdateField<uint32, 0, 8> ResearchSiteProgress;
+ DynamicUpdateField<int32, 0, 9> DailyQuestsCompleted;
+ DynamicUpdateField<int32, 0, 10> AvailableQuestLineXQuestIDs;
+ DynamicUpdateField<int32, 0, 11> Heirlooms;
+ DynamicUpdateField<uint32, 0, 12> HeirloomFlags;
+ DynamicUpdateField<int32, 0, 13> Toys;
+ DynamicUpdateField<uint32, 0, 14> ToyFlags;
+ DynamicUpdateField<uint32, 0, 15> Transmog;
+ DynamicUpdateField<int32, 0, 16> ConditionalTransmog;
+ DynamicUpdateField<int32, 0, 17> SelfResSpells;
+ DynamicUpdateField<uint32, 0, 18> RuneforgePowers;
+ DynamicUpdateField<uint32, 0, 19> TransmogIllusions;
+ DynamicUpdateField<UF::SpellPctModByLabel, 0, 21> SpellPctModByLabel;
+ DynamicUpdateField<UF::SpellFlatModByLabel, 0, 22> SpellFlatModByLabel;
+ DynamicUpdateField<UF::MawPower, 0, 23> MawPowers;
+ DynamicUpdateField<UF::MultiFloorExplore, 0, 24> MultiFloorExploration;
+ DynamicUpdateField<UF::RecipeProgressionInfo, 0, 25> RecipeProgression;
+ DynamicUpdateField<UF::ReplayedQuest, 0, 26> ReplayedQuests;
+ DynamicUpdateField<int32, 0, 27> DisabledSpells;
+ DynamicUpdateField<UF::PVPInfo, 0, 6> PvpInfo;
+ DynamicUpdateField<UF::CharacterRestriction, 0, 20> CharacterRestrictions;
+ DynamicUpdateField<UF::TraitConfig, 0, 28> TraitConfigs;
+ DynamicUpdateField<UF::CraftingOrder, 0, 29> CraftingOrders;
+ UpdateField<ObjectGuid, 0, 32> FarsightObject;
+ UpdateField<ObjectGuid, 0, 33> SummonedBattlePetGUID;
+ UpdateField<uint64, 34, 35> Coinage;
+ UpdateField<int32, 34, 36> XP;
+ UpdateField<int32, 34, 37> NextLevelXP;
+ UpdateField<int32, 34, 38> TrialXP;
+ UpdateField<UF::SkillInfo, 34, 39> Skill;
+ UpdateField<int32, 34, 40> CharacterPoints;
+ UpdateField<int32, 34, 41> MaxTalentTiers;
+ UpdateField<uint32, 34, 42> TrackCreatureMask;
+ UpdateField<float, 34, 43> MainhandExpertise;
+ UpdateField<float, 34, 44> OffhandExpertise;
+ UpdateField<float, 34, 45> RangedExpertise;
+ UpdateField<float, 34, 46> CombatRatingExpertise;
+ UpdateField<float, 34, 47> BlockPercentage;
+ UpdateField<float, 34, 48> DodgePercentage;
+ UpdateField<float, 34, 49> DodgePercentageFromAttribute;
+ UpdateField<float, 34, 50> ParryPercentage;
+ UpdateField<float, 34, 51> ParryPercentageFromAttribute;
+ UpdateField<float, 34, 52> CritPercentage;
+ UpdateField<float, 34, 53> RangedCritPercentage;
+ UpdateField<float, 34, 54> OffhandCritPercentage;
+ UpdateField<float, 34, 55> SpellCritPercentage;
+ UpdateField<int32, 34, 56> ShieldBlock;
+ UpdateField<float, 34, 57> ShieldBlockCritPercentage;
+ UpdateField<float, 34, 58> Mastery;
+ UpdateField<float, 34, 59> Speed;
+ UpdateField<float, 34, 60> Avoidance;
+ UpdateField<float, 34, 61> Sturdiness;
+ UpdateField<int32, 34, 62> Versatility;
+ UpdateField<float, 34, 63> VersatilityBonus;
+ UpdateField<float, 34, 64> PvpPowerDamage;
+ UpdateField<float, 34, 65> PvpPowerHealing;
+ UpdateField<int32, 66, 67> ModHealingDonePos;
+ UpdateField<float, 66, 68> ModHealingPercent;
+ UpdateField<float, 66, 69> ModPeriodicHealingDonePercent;
+ UpdateField<float, 66, 70> ModSpellPowerPercent;
+ UpdateField<float, 66, 71> ModResiliencePercent;
+ UpdateField<float, 66, 72> OverrideSpellPowerByAPPercent;
+ UpdateField<float, 66, 73> OverrideAPBySpellPowerPercent;
+ UpdateField<int32, 66, 74> ModTargetResistance;
+ UpdateField<int32, 66, 75> ModTargetPhysicalResistance;
+ UpdateField<uint32, 66, 76> LocalFlags;
+ UpdateField<uint8, 66, 77> GrantableLevels;
+ UpdateField<uint8, 66, 78> MultiActionBars;
+ UpdateField<uint8, 66, 79> LifetimeMaxRank;
+ UpdateField<uint8, 66, 80> NumRespecs;
+ UpdateField<uint32, 66, 81> PvpMedals;
+ UpdateField<uint16, 66, 82> TodayHonorableKills;
+ UpdateField<uint16, 66, 83> YesterdayHonorableKills;
+ UpdateField<uint32, 66, 84> LifetimeHonorableKills;
+ UpdateField<int32, 66, 85> WatchedFactionIndex;
+ UpdateField<int32, 66, 86> MaxLevel;
+ UpdateField<int32, 66, 87> ScalingPlayerLevelDelta;
+ UpdateField<int32, 66, 88> MaxCreatureScalingLevel;
+ UpdateField<int32, 66, 89> PetSpellPower;
+ UpdateField<float, 66, 90> UiHitModifier;
+ UpdateField<float, 66, 91> UiSpellHitModifier;
+ UpdateField<int32, 66, 92> HomeRealmTimeOffset;
+ UpdateField<float, 66, 93> ModPetHaste;
+ UpdateField<int8, 66, 94> JailersTowerLevelMax;
+ UpdateField<int8, 66, 95> JailersTowerLevel;
+ UpdateField<uint8, 66, 96> LocalRegenFlags;
+ UpdateField<uint8, 66, 97> AuraVision;
+ UpdateField<uint8, 98, 99> NumBackpackSlots;
+ UpdateField<int32, 98, 100> OverrideSpellsID;
+ UpdateField<uint16, 98, 101> LootSpecID;
+ UpdateField<uint32, 98, 102> OverrideZonePVPType;
+ UpdateField<ObjectGuid, 98, 103> BnetAccount;
+ UpdateField<uint64, 98, 104> GuildClubMemberID;
+ UpdateField<int32, 98, 105> Honor;
+ UpdateField<int32, 98, 106> HonorNextLevel;
+ UpdateField<uint8, 98, 107> NumBankSlots;
+ UpdateField<UF::ActivePlayerUnk901, 98, 109> Field_1410;
+ OptionalUpdateField<UF::QuestSession, 98, 108> QuestSession;
+ UpdateField<int32, 98, 110> UiChromieTimeExpansionID;
+ UpdateField<int32, 98, 111> TransportServerTime;
+ UpdateField<uint32, 98, 112> WeeklyRewardsPeriodSinceOrigin; // week count since Cfg_RegionsEntry::ChallengeOrigin
+ UpdateField<int16, 98, 113> DEBUGSoulbindConduitRank;
+ UpdateField<WorldPackets::MythicPlus::DungeonScoreData, 98, 114> DungeonScore;
+ UpdateField<uint32, 98, 115> ActiveCombatTraitConfigID;
+ UpdateFieldArray<ObjectGuid, 218, 116, 117> InvSlots;
+ UpdateFieldArray<uint64, 240, 335, 336> ExploredZones;
+ UpdateFieldArray<UF::RestInfo, 2, 576, 577> RestInfo;
+ UpdateFieldArray<int32, 7, 579, 580> ModDamageDonePos;
+ UpdateFieldArray<int32, 7, 579, 587> ModDamageDoneNeg;
+ UpdateFieldArray<float, 7, 579, 594> ModDamageDonePercent;
+ UpdateFieldArray<float, 7, 579, 601> ModHealingDonePercent;
+ UpdateFieldArray<float, 3, 608, 609> WeaponDmgMultipliers;
+ UpdateFieldArray<float, 3, 608, 612> WeaponAtkSpeedMultipliers;
+ UpdateFieldArray<uint32, 12, 615, 616> BuybackPrice;
+ UpdateFieldArray<int64, 12, 615, 628> BuybackTimestamp;
+ UpdateFieldArray<int32, 32, 640, 641> CombatRatings;
+ UpdateFieldArray<uint32, 4, 673, 674> NoReagentCostMask;
+ UpdateFieldArray<int32, 2, 678, 679> ProfessionSkillLine;
+ UpdateFieldArray<uint32, 5, 681, 682> BagSlotFlags;
+ UpdateFieldArray<uint32, 7, 687, 688> BankBagSlotFlags;
+ UpdateFieldArray<uint64, 875, 695, 696> QuestCompleted;
void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const;
void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const;
@@ -790,30 +888,34 @@ struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMas
void ClearChangesMask();
};
-struct GameObjectData : public IsUpdateFieldStructureTag, public HasChangesMask<21>
+struct GameObjectData : public IsUpdateFieldStructureTag, public HasChangesMask<25>
{
UpdateField<std::vector<uint32>, 0, 1> StateWorldEffectIDs;
DynamicUpdateField<int32, 0, 2> EnableDoodadSets;
- UpdateField<int32, 0, 3> DisplayID;
- UpdateField<uint32, 0, 4> SpellVisualID;
- UpdateField<uint32, 0, 5> StateSpellVisualID;
- UpdateField<uint32, 0, 6> SpawnTrackingStateAnimID;
- UpdateField<uint32, 0, 7> SpawnTrackingStateAnimKitID;
- UpdateField<uint32, 0, 8> StateWorldEffectsQuestObjectiveID;
- UpdateField<ObjectGuid, 0, 9> CreatedBy;
- UpdateField<ObjectGuid, 0, 10> GuildGUID;
- UpdateField<uint32, 0, 11> Flags;
+ DynamicUpdateField<int32, 0, 3> WorldEffects;
+ UpdateField<int32, 0, 4> DisplayID;
+ UpdateField<uint32, 0, 5> SpellVisualID;
+ UpdateField<uint32, 0, 6> StateSpellVisualID;
+ UpdateField<uint32, 0, 7> SpawnTrackingStateAnimID;
+ UpdateField<uint32, 0, 8> SpawnTrackingStateAnimKitID;
+ UpdateField<uint32, 0, 9> StateWorldEffectsQuestObjectiveID;
+ UpdateField<ObjectGuid, 0, 10> CreatedBy;
+ UpdateField<ObjectGuid, 0, 11> GuildGUID;
+ UpdateField<uint32, 0, 12> Flags;
struct FlagsTag : ViewerDependentValueTag<uint32> {};
- UpdateField<QuaternionData, 0, 12> ParentRotation;
- UpdateField<int32, 0, 13> FactionTemplate;
- UpdateField<int8, 0, 14> State;
+ UpdateField<QuaternionData, 0, 13> ParentRotation;
+ UpdateField<int32, 0, 14> FactionTemplate;
+ UpdateField<int8, 0, 15> State;
struct StateTag : ViewerDependentValueTag<int8> {};
- UpdateField<int8, 0, 15> TypeID;
- UpdateField<uint8, 0, 16> PercentHealth;
- UpdateField<uint32, 0, 17> ArtKit;
- UpdateField<uint32, 0, 18> CustomParam;
- UpdateField<int32, 0, 19> Level;
- UpdateField<uint32, 0, 20> AnimGroupInstance;
+ UpdateField<int8, 0, 16> TypeID;
+ UpdateField<uint8, 0, 17> PercentHealth;
+ UpdateField<uint32, 0, 18> ArtKit;
+ UpdateField<uint32, 0, 19> CustomParam;
+ UpdateField<int32, 0, 20> Level;
+ UpdateField<uint32, 0, 21> AnimGroupInstance;
+ UpdateField<uint32, 0, 22> UiWidgetItemID;
+ UpdateField<uint32, 0, 23> UiWidgetItemQuality;
+ UpdateField<uint32, 0, 24> UiWidgetItemUnknown1000;
void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, GameObject const* owner, Player const* receiver) const;
void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, GameObject const* owner, Player const* receiver) const;
@@ -882,25 +984,30 @@ struct VisualAnim : public IsUpdateFieldStructureTag, public HasChangesMask<5>
void ClearChangesMask();
};
-struct AreaTriggerData : public IsUpdateFieldStructureTag, public HasChangesMask<18>
+struct AreaTriggerData : public IsUpdateFieldStructureTag, public HasChangesMask<23>
{
UpdateField<UF::ScaleCurve, 0, 1> OverrideScaleCurve;
UpdateField<UF::ScaleCurve, 0, 2> ExtraScaleCurve;
- UpdateField<ObjectGuid, 0, 3> Caster;
- UpdateField<uint32, 0, 4> Duration;
- UpdateField<uint32, 0, 5> TimeToTarget;
- UpdateField<uint32, 0, 6> TimeToTargetScale;
- UpdateField<uint32, 0, 7> TimeToTargetExtraScale;
- UpdateField<int32, 0, 8> SpellID;
- UpdateField<int32, 0, 9> SpellForVisuals;
- UpdateField<UF::SpellCastVisual, 0, 10> SpellVisual;
- UpdateField<float, 0, 11> BoundsRadius2D;
- UpdateField<uint32, 0, 12> DecalPropertiesID;
- UpdateField<ObjectGuid, 0, 13> CreatingEffectGUID;
- UpdateField<uint32, 0, 14> Field_80;
- UpdateField<uint32, 0, 15> Field_84;
- UpdateField<ObjectGuid, 0, 16> Field_88;
- UpdateField<UF::VisualAnim, 0, 17> VisualAnim;
+ UpdateField<UF::ScaleCurve, 0, 3> Field_C38;
+ UpdateField<UF::ScaleCurve, 0, 4> Field_C54;
+ UpdateField<UF::ScaleCurve, 0, 5> Field_C70;
+ UpdateField<ObjectGuid, 0, 6> Caster;
+ UpdateField<uint32, 0, 7> Duration;
+ UpdateField<uint32, 0, 8> TimeToTarget;
+ UpdateField<uint32, 0, 9> TimeToTargetScale;
+ UpdateField<uint32, 0, 10> TimeToTargetExtraScale;
+ UpdateField<uint32, 0, 11> Field_B0;
+ UpdateField<int32, 0, 12> SpellID;
+ UpdateField<int32, 0, 13> SpellForVisuals;
+ UpdateField<UF::SpellCastVisual, 0, 14> SpellVisual;
+ UpdateField<float, 0, 15> BoundsRadius2D;
+ UpdateField<uint32, 0, 16> DecalPropertiesID;
+ UpdateField<ObjectGuid, 0, 17> CreatingEffectGUID;
+ UpdateField<uint32, 0, 18> Field_80;
+ UpdateField<uint32, 0, 19> Field_84;
+ UpdateField<ObjectGuid, 0, 20> Field_88;
+ UpdateField<TaggedPosition<Position::XYZ>, 0, 21> Field_F8;
+ UpdateField<UF::VisualAnim, 0, 22> VisualAnim;
void WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, AreaTrigger const* owner, Player const* receiver) const;
void WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, AreaTrigger const* owner, Player const* receiver) const;
diff --git a/src/server/game/Entities/Player/CollectionMgr.cpp b/src/server/game/Entities/Player/CollectionMgr.cpp
index 296b03b6720..17603908065 100644
--- a/src/server/game/Entities/Player/CollectionMgr.cpp
+++ b/src/server/game/Entities/Player/CollectionMgr.cpp
@@ -322,9 +322,9 @@ void CollectionMgr::CheckHeirloomUpgrades(Item* item)
return;
}
- auto const& bonusListIDs = item->m_itemData->BonusListIDs;
+ std::vector<int32> const& bonusListIDs = item->GetBonusListIDs();
- for (uint32 bonusId : *bonusListIDs)
+ for (uint32 bonusId : bonusListIDs)
{
if (bonusId != itr->second.bonusId)
{
@@ -333,7 +333,7 @@ void CollectionMgr::CheckHeirloomUpgrades(Item* item)
}
}
- if (std::find(bonusListIDs->begin(), bonusListIDs->end(), int32(itr->second.bonusId)) == bonusListIDs->end())
+ if (std::find(bonusListIDs.begin(), bonusListIDs.end(), int32(itr->second.bonusId)) == bonusListIDs.end())
item->AddBonuses(itr->second.bonusId);
}
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 90a414e6ad7..e2cdadfb468 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -537,7 +537,7 @@ bool Player::Create(ObjectGuid::LowType guidlow, WorldPackets::Character::Charac
// original items
for (PlayerCreateInfoItem initialItem : info->item)
- StoreNewItemInBestSlots(initialItem.item_id, initialItem.item_amount);
+ StoreNewItemInBestSlots(initialItem.item_id, initialItem.item_amount, info->itemContext);
// bags and main-hand weapon must equipped at this moment
// now second pass for not equipped (offhand weapon/shield if it attempt equipped before main-hand weapon)
@@ -581,46 +581,45 @@ bool Player::Create(ObjectGuid::LowType guidlow, WorldPackets::Character::Charac
return true;
}
-bool Player::StoreNewItemInBestSlots(uint32 titem_id, uint32 titem_amount)
+bool Player::StoreNewItemInBestSlots(uint32 itemId, uint32 amount, ItemContext context)
{
TC_LOG_DEBUG("entities.player.items", "Player::StoreNewItemInBestSlots: Player '%s' (%s) creates initial item (ItemID: %u, Count: %u)",
- GetName().c_str(), GetGUID().ToString().c_str(), titem_id, titem_amount);
+ GetName().c_str(), GetGUID().ToString().c_str(), itemId, amount);
- ItemContext itemContext = ItemContext::New_Character;
std::vector<int32> bonusListIDs;
- std::set<uint32> contextBonuses = sDB2Manager.GetDefaultItemBonusTree(titem_id, itemContext);
+ std::set<uint32> contextBonuses = sDB2Manager.GetDefaultItemBonusTree(itemId, context);
bonusListIDs.insert(bonusListIDs.begin(), contextBonuses.begin(), contextBonuses.end());
// attempt equip by one
- while (titem_amount > 0)
+ while (amount > 0)
{
uint16 eDest;
- InventoryResult msg = CanEquipNewItem(NULL_SLOT, eDest, titem_id, false);
+ InventoryResult msg = CanEquipNewItem(NULL_SLOT, eDest, itemId, false);
if (msg != EQUIP_ERR_OK)
break;
- Item* item = EquipNewItem(eDest, titem_id, itemContext, true);
+ Item* item = EquipNewItem(eDest, itemId, context, true);
item->SetBonuses(bonusListIDs);
AutoUnequipOffhandIfNeed();
- --titem_amount;
+ --amount;
}
- if (titem_amount == 0)
+ if (amount == 0)
return true; // equipped
// attempt store
ItemPosCountVec sDest;
// store in main bag to simplify second pass (special bags can be not equipped yet at this moment)
- InventoryResult msg = CanStoreNewItem(INVENTORY_SLOT_BAG_0, NULL_SLOT, sDest, titem_id, titem_amount);
+ InventoryResult msg = CanStoreNewItem(INVENTORY_SLOT_BAG_0, NULL_SLOT, sDest, itemId, amount);
if (msg == EQUIP_ERR_OK)
{
- StoreNewItem(sDest, titem_id, true, GenerateItemRandomBonusListId(titem_id), GuidSet(), itemContext, bonusListIDs);
+ StoreNewItem(sDest, itemId, true, GenerateItemRandomBonusListId(itemId), GuidSet(), context, bonusListIDs);
return true; // stored
}
// item can't be added
TC_LOG_ERROR("entities.player.items", "Player::StoreNewItemInBestSlots: Player '%s' (%s) can't equip or store initial item (ItemID: %u, Race: %u, Class: %u, InventoryResult: %u)",
- GetName().c_str(), GetGUID().ToString().c_str(), titem_id, GetRace(), GetClass(), msg);
+ GetName().c_str(), GetGUID().ToString().c_str(), itemId, GetRace(), GetClass(), msg);
return false;
}
@@ -2292,7 +2291,6 @@ void Player::GiveXP(uint32 xp, Unit* victim, float group_rate)
packet.Reason = victim ? LOG_XP_REASON_KILL : LOG_XP_REASON_NO_KILL;
packet.Amount = xp;
packet.GroupBonus = group_rate;
- packet.ReferAFriendBonusType = recruitAFriend ? 1 : 0;
SendDirectMessage(packet.Write());
uint32 nextLvlXP = GetXPForNextLevel();
@@ -3182,10 +3180,11 @@ void Player::LearnSpell(uint32 spell_id, bool dependent, int32 fromSkill /*= 0*/
// prevent duplicated entires in spell book, also not send if not in world (loading)
if (learning && IsInWorld())
{
- WorldPackets::Spells::LearnedSpells packet;
- packet.SpellID.push_back(spell_id);
- packet.SuppressMessaging = suppressMessaging;
- SendDirectMessage(packet.Write());
+ WorldPackets::Spells::LearnedSpells learnedSpells;
+ WorldPackets::Spells::LearnedSpellInfo& learnedSpellInfo = learnedSpells.ClientLearnedSpellData.emplace_back();
+ learnedSpellInfo.SpellID = spell_id;
+ learnedSpells.SuppressMessaging = suppressMessaging;
+ SendDirectMessage(learnedSpells.Write());
}
// learn all disabled higher ranks and required spells (recursive)
@@ -3519,23 +3518,7 @@ void Player::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c
{
if (target == this)
{
- for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
- {
- if (m_items[i] == nullptr)
- continue;
-
- m_items[i]->BuildCreateUpdateBlockForPlayer(data, target);
- }
-
- for (uint8 i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i)
- {
- if (m_items[i] == nullptr)
- continue;
-
- m_items[i]->BuildCreateUpdateBlockForPlayer(data, target);
- }
-
- for (uint8 i = REAGENT_SLOT_START; i < REAGENT_SLOT_END; ++i)
+ for (uint8 i = EQUIPMENT_SLOT_START; i < BANK_SLOT_BAG_END; ++i)
{
if (m_items[i] == nullptr)
continue;
@@ -3543,7 +3526,7 @@ void Player::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c
m_items[i]->BuildCreateUpdateBlockForPlayer(data, target);
}
- for (uint8 i = CHILD_EQUIPMENT_SLOT_START; i < CHILD_EQUIPMENT_SLOT_END; ++i)
+ for (uint8 i = REAGENT_SLOT_START; i < CHILD_EQUIPMENT_SLOT_END; ++i)
{
if (m_items[i] == nullptr)
continue;
@@ -3684,7 +3667,7 @@ void Player::DestroyForPlayer(Player* target) const
if (target == this)
{
- for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
+ for (uint8 i = EQUIPMENT_SLOT_START; i < BANK_SLOT_BAG_END; ++i)
{
if (m_items[i] == nullptr)
continue;
@@ -3692,23 +3675,7 @@ void Player::DestroyForPlayer(Player* target) const
m_items[i]->DestroyForPlayer(target);
}
- for (uint8 i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i)
- {
- if (m_items[i] == nullptr)
- continue;
-
- m_items[i]->DestroyForPlayer(target);
- }
-
- for (uint8 i = REAGENT_SLOT_START; i < REAGENT_SLOT_END; ++i)
- {
- if (m_items[i] == nullptr)
- continue;
-
- m_items[i]->DestroyForPlayer(target);
- }
-
- for (uint8 i = CHILD_EQUIPMENT_SLOT_START; i < CHILD_EQUIPMENT_SLOT_END; ++i)
+ for (uint8 i = REAGENT_SLOT_START; i < CHILD_EQUIPMENT_SLOT_END; ++i)
{
if (m_items[i] == nullptr)
continue;
@@ -4493,7 +4460,7 @@ Corpse* Player::CreateCorpse()
corpse->SetDisplayId(GetNativeDisplayId());
corpse->SetFactionTemplate(sChrRacesStore.AssertEntry(GetRace())->FactionID);
- for (uint8 i = 0; i < EQUIPMENT_SLOT_END; i++)
+ for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; i++)
{
if (m_items[i])
{
@@ -8211,8 +8178,9 @@ void Player::ApplyArtifactPowerRank(Item* artifact, ArtifactPowerRankEntry const
{
AddTemporarySpell(artifactPowerRank->SpellID);
WorldPackets::Spells::LearnedSpells learnedSpells;
+ WorldPackets::Spells::LearnedSpellInfo& learnedSpellInfo = learnedSpells.ClientLearnedSpellData.emplace_back();
+ learnedSpellInfo.SpellID = artifactPowerRank->SpellID;
learnedSpells.SuppressMessaging = true;
- learnedSpells.SpellID.push_back(artifactPowerRank->SpellID);
SendDirectMessage(learnedSpells.Write());
}
else if (!apply)
@@ -8898,8 +8866,11 @@ void Player::SendInitWorldStates(uint32 zoneId, uint32 areaId)
void Player::SetBindPoint(ObjectGuid guid) const
{
- WorldPackets::Misc::BinderConfirm packet(guid);
- SendDirectMessage(packet.Write());
+ WorldPackets::NPC::NPCInteractionOpenResult npcInteraction;
+ npcInteraction.Npc = guid;
+ npcInteraction.InteractionType = PlayerInteractionType::Binder;
+ npcInteraction.Success = true;
+ SendDirectMessage(npcInteraction.Write());
}
void Player::SendRespecWipeConfirm(ObjectGuid const& guid, uint32 cost, SpecResetType respecType) const
@@ -9064,10 +9035,16 @@ uint32 Player::GetFreeInventorySlotCount(EnumFlag<ItemSearchLocation> location /
uint32 freeSlotCount = 0;
if (location.HasFlag(ItemSearchLocation::Equipment))
+ {
for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
if (!GetItemByPos(INVENTORY_SLOT_BAG_0, i))
++freeSlotCount;
+ for (uint8 i = PROFESSION_SLOT_START; i < PROFESSION_SLOT_END; ++i)
+ if (!GetItemByPos(INVENTORY_SLOT_BAG_0, i))
+ ++freeSlotCount;
+ }
+
if (location.HasFlag(ItemSearchLocation::Inventory))
{
uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount();
@@ -9096,9 +9073,17 @@ uint32 Player::GetFreeInventorySlotCount(EnumFlag<ItemSearchLocation> location /
}
if (location.HasFlag(ItemSearchLocation::ReagentBank))
+ {
+ for (uint8 i = REAGENT_BAG_SLOT_START; i < REAGENT_BAG_SLOT_END; ++i)
+ if (Bag* bag = GetBagByPos(i))
+ for (uint32 j = 0; j < GetBagSize(bag); ++j)
+ if (!GetItemInBag(bag, j))
+ ++freeSlotCount;
+
for (uint8 i = REAGENT_SLOT_START; i < REAGENT_SLOT_END; ++i)
if (!GetItemByPos(INVENTORY_SLOT_BAG_0, i))
++freeSlotCount;
+ }
return freeSlotCount;
}
@@ -9233,7 +9218,8 @@ Item* Player::GetUseableItemByPos(uint8 bag, uint8 slot) const
Bag* Player::GetBagByPos(uint8 bag) const
{
if ((bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END)
- || (bag >= BANK_SLOT_BAG_START && bag < BANK_SLOT_BAG_END))
+ || (bag >= BANK_SLOT_BAG_START && bag < BANK_SLOT_BAG_END)
+ || (bag >= REAGENT_BAG_SLOT_START && bag < REAGENT_BAG_SLOT_END))
if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, bag))
return item->ToBag();
return nullptr;
@@ -9355,8 +9341,12 @@ bool Player::IsEquipmentPos(uint8 bag, uint8 slot)
{
if (bag == INVENTORY_SLOT_BAG_0 && (slot < EQUIPMENT_SLOT_END))
return true;
+ if (bag == INVENTORY_SLOT_BAG_0 && (slot >= PROFESSION_SLOT_START && slot < PROFESSION_SLOT_END))
+ return true;
if (bag == INVENTORY_SLOT_BAG_0 && (slot >= INVENTORY_SLOT_BAG_START && slot < INVENTORY_SLOT_BAG_END))
return true;
+ if (bag == INVENTORY_SLOT_BAG_0 && (slot >= REAGENT_BAG_SLOT_START && slot < REAGENT_BAG_SLOT_END))
+ return true;
return false;
}
@@ -9388,6 +9378,8 @@ bool Player::IsBagPos(uint16 pos)
return true;
if (bag == INVENTORY_SLOT_BAG_0 && (slot >= BANK_SLOT_BAG_START && slot < BANK_SLOT_BAG_END))
return true;
+ if (bag == INVENTORY_SLOT_BAG_0 && (slot >= REAGENT_BAG_SLOT_START && slot < REAGENT_BAG_SLOT_END))
+ return true;
return false;
}
@@ -9412,10 +9404,18 @@ bool Player::IsValidPos(uint8 bag, uint8 slot, bool explicit_pos) const
if (slot < EQUIPMENT_SLOT_END)
return true;
+ // profession equipment
+ if (slot >= PROFESSION_SLOT_START && slot < PROFESSION_SLOT_END)
+ return true;
+
// bag equip slots
if (slot >= INVENTORY_SLOT_BAG_START && slot < INVENTORY_SLOT_BAG_END)
return true;
+ // reagent bag equip slots
+ if (slot >= REAGENT_BAG_SLOT_START && slot < REAGENT_BAG_SLOT_END)
+ return true;
+
// backpack slots
if (slot >= INVENTORY_SLOT_ITEM_START && slot < INVENTORY_SLOT_ITEM_START + GetInventorySlotCount())
return true;
@@ -11663,7 +11663,7 @@ void Player::RemoveItem(uint8 bag, uint8 slot, bool update)
pItem->RemoveItemFlag2(ITEM_FIELD_FLAG2_EQUIPPED);
// remove item dependent auras and casts (only weapon and armor slots)
- if (slot < EQUIPMENT_SLOT_END)
+ if (slot < PROFESSION_SLOT_END)
{
// update expertise
if (slot == EQUIPMENT_SLOT_MAINHAND)
@@ -13648,7 +13648,7 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId, bool showQues
{
switch (gossipMenuItem.OptionNpc)
{
- case GossipOptionNpc::TaxiNode:
+ case GossipOptionNpc::Taxinode:
if (GetSession()->SendLearnNewTaxiNode(creature))
return;
break;
@@ -13656,7 +13656,7 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId, bool showQues
if (!isDead())
canTalk = false;
break;
- case GossipOptionNpc::BattleMaster:
+ case GossipOptionNpc::Battlemaster:
if (!creature->isCanInteractWithBattleMaster(this, false))
canTalk = false;
break;
@@ -13666,7 +13666,7 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId, bool showQues
if (!creature->CanResetTalents(this))
canTalk = false;
break;
- case GossipOptionNpc::StableMaster:
+ case GossipOptionNpc::Stablemaster:
case GossipOptionNpc::PetSpecializationMaster:
if (GetClass() != CLASS_HUNTER)
canTalk = false;
@@ -13695,29 +13695,29 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId, bool showQues
canTalk = false; // Deprecated
break;
case GossipOptionNpc::GuildBanker:
- case GossipOptionNpc::SpellClick:
- case GossipOptionNpc::WorldPVPQueue:
+ case GossipOptionNpc::Spellclick:
+ case GossipOptionNpc::WorldPvPQueue:
case GossipOptionNpc::LFGDungeon:
case GossipOptionNpc::ArtifactRespec:
case GossipOptionNpc::QueueScenario:
case GossipOptionNpc::GarrisonArchitect:
- case GossipOptionNpc::GarrisonMission:
+ case GossipOptionNpc::GarrisonMissionNpc:
case GossipOptionNpc::ShipmentCrafter:
- case GossipOptionNpc::GarrisonTradeskill:
+ case GossipOptionNpc::GarrisonTradeskillNpc:
case GossipOptionNpc::GarrisonRecruitment:
case GossipOptionNpc::AdventureMap:
case GossipOptionNpc::GarrisonTalent:
case GossipOptionNpc::ContributionCollector:
- case GossipOptionNpc::IslandsMission:
+ case GossipOptionNpc::IslandsMissionNpc:
case GossipOptionNpc::UIItemInteraction:
case GossipOptionNpc::WorldMap:
case GossipOptionNpc::Soulbind:
- case GossipOptionNpc::ChromieTime:
- case GossipOptionNpc::CovenantPreview:
+ case GossipOptionNpc::ChromieTimeNpc:
+ case GossipOptionNpc::CovenantPreviewNpc:
case GossipOptionNpc::RuneforgeLegendaryCrafting:
case GossipOptionNpc::NewPlayerGuide:
case GossipOptionNpc::RuneforgeLegendaryUpgrade:
- case GossipOptionNpc::CovenantRenown:
+ case GossipOptionNpc::CovenantRenownNpc:
break; // NYI
default:
TC_LOG_ERROR("sql.sql", "Creature entry %u has an unknown gossip option icon %u for menu %u.", creature->GetEntry(), AsUnderlyingType(gossipMenuItem.OptionNpc), gossipMenuItem.MenuID);
@@ -13740,42 +13740,7 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId, bool showQues
}
if (canTalk)
- {
- std::string strOptionText, strBoxText;
- BroadcastTextEntry const* optionBroadcastText = sBroadcastTextStore.LookupEntry(gossipMenuItem.OptionBroadcastTextID);
- BroadcastTextEntry const* boxBroadcastText = sBroadcastTextStore.LookupEntry(gossipMenuItem.BoxBroadcastTextID);
- LocaleConstant locale = GetSession()->GetSessionDbLocaleIndex();
-
- if (optionBroadcastText)
- strOptionText = DB2Manager::GetBroadcastTextValue(optionBroadcastText, locale, GetGender());
- else
- strOptionText = gossipMenuItem.OptionText;
-
- if (boxBroadcastText)
- strBoxText = DB2Manager::GetBroadcastTextValue(boxBroadcastText, locale, GetGender());
- else
- strBoxText = gossipMenuItem.BoxText;
-
- if (locale != DEFAULT_LOCALE)
- {
- if (!optionBroadcastText)
- {
- /// Find localizations from database.
- if (GossipMenuItemsLocale const* gossipMenuLocale = sObjectMgr->GetGossipMenuItemsLocale(menuId, gossipMenuItem.OptionID))
- ObjectMgr::GetLocaleString(gossipMenuLocale->OptionText, locale, strOptionText);
- }
-
- if (!boxBroadcastText)
- {
- /// Find localizations from database.
- if (GossipMenuItemsLocale const* gossipMenuLocale = sObjectMgr->GetGossipMenuItemsLocale(menuId, gossipMenuItem.OptionID))
- ObjectMgr::GetLocaleString(gossipMenuLocale->BoxText, locale, strBoxText);
- }
- }
-
- menu->GetGossipMenu().AddMenuItem(gossipMenuItem.OptionID, gossipMenuItem.OptionNpc, strOptionText, 0, AsUnderlyingType(gossipMenuItem.OptionNpc), strBoxText, gossipMenuItem.BoxMoney, gossipMenuItem.BoxCoded);
- menu->GetGossipMenu().AddGossipMenuItemData(gossipMenuItem.OptionID, gossipMenuItem.ActionMenuID, gossipMenuItem.ActionPoiID);
- }
+ menu->GetGossipMenu().AddMenuItem(gossipMenuItem, gossipMenuItem.MenuID, gossipMenuItem.OrderIndex);
}
}
@@ -13804,7 +13769,7 @@ void Player::SendPreparedGossip(WorldObject* source)
PlayerTalkClass->SendGossipMenu(textId, source->GetGUID());
}
-void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 menuId)
+void Player::OnGossipSelect(WorldObject* source, int32 gossipOptionId, uint32 menuId)
{
GossipMenu& gossipMenu = PlayerTalkClass->GetGossipMenu();
@@ -13812,7 +13777,7 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men
if (menuId != gossipMenu.GetMenuId())
return;
- GossipMenuItem const* item = gossipMenu.GetItem(gossipListId);
+ GossipMenuItem const* item = gossipMenu.GetItem(gossipOptionId);
if (!item)
return;
@@ -13829,10 +13794,6 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men
}
}
- GossipMenuItemData const* menuItemData = gossipMenu.GetItemData(gossipListId);
- if (!menuItemData)
- return;
-
int64 cost = int64(item->BoxMoney);
if (!HasEnoughMoney(cost))
{
@@ -13841,51 +13802,37 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men
return;
}
- switch (gossipOptionNpc)
- {
- case GossipOptionNpc::None:
- {
- if (menuItemData->GossipActionPoi)
- PlayerTalkClass->SendPointOfInterest(menuItemData->GossipActionPoi);
+ if (item->ActionPoiID)
+ PlayerTalkClass->SendPointOfInterest(item->ActionPoiID);
- if (menuItemData->GossipActionMenuId)
- {
- PrepareGossipMenu(source, menuItemData->GossipActionMenuId);
- SendPreparedGossip(source);
- }
+ if (item->ActionMenuID)
+ {
+ PrepareGossipMenu(source, item->ActionMenuID);
+ SendPreparedGossip(source);
+ }
- break;
- }
+ // types that have their dedicated open opcode dont send WorldPackets::NPC::GossipOptionNPCInteraction
+ bool handled = true;
+ switch (gossipOptionNpc)
+ {
case GossipOptionNpc::Vendor:
GetSession()->SendListInventory(guid);
break;
- case GossipOptionNpc::TaxiNode:
+ case GossipOptionNpc::Taxinode:
GetSession()->SendTaxiMenu(source->ToCreature());
break;
case GossipOptionNpc::Trainer:
- GetSession()->SendTrainerList(source->ToCreature(), sObjectMgr->GetCreatureTrainerForGossipOption(source->GetEntry(), menuId, gossipListId));
+ GetSession()->SendTrainerList(source->ToCreature(), sObjectMgr->GetCreatureTrainerForGossipOption(source->GetEntry(), menuId, gossipOptionId));
break;
case GossipOptionNpc::SpiritHealer:
- if (isDead())
- source->ToCreature()->CastSpell(source->ToCreature(), 17251, CastSpellExtraArgs(TRIGGERED_FULL_MASK)
- .SetOriginalCaster(GetGUID()));
- break;
- case GossipOptionNpc::Binder:
- PlayerTalkClass->SendCloseGossip();
- SetBindPoint(guid);
- break;
- case GossipOptionNpc::Banker:
- GetSession()->SendShowBank(guid);
+ source->CastSpell(source->ToCreature(), 17251, CastSpellExtraArgs(TRIGGERED_FULL_MASK).SetOriginalCaster(GetGUID()));
+ handled = false;
break;
case GossipOptionNpc::PetitionVendor:
PlayerTalkClass->SendCloseGossip();
GetSession()->SendPetitionShowList(guid);
break;
- case GossipOptionNpc::TabardVendor:
- PlayerTalkClass->SendCloseGossip();
- GetSession()->SendTabardVendorActivate(guid);
- break;
- case GossipOptionNpc::BattleMaster:
+ case GossipOptionNpc::Battlemaster:
{
BattlegroundTypeId bgTypeId = sBattlegroundMgr->GetBattleMasterBG(source->GetEntry());
@@ -13906,13 +13853,23 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men
PlayerTalkClass->SendCloseGossip();
SendRespecWipeConfirm(guid, sWorld->getBoolConfig(CONFIG_NO_RESET_TALENT_COST) ? 0 : GetNextResetTalentsCost(), SPEC_RESET_TALENTS);
break;
- case GossipOptionNpc::StableMaster:
+ case GossipOptionNpc::Stablemaster:
GetSession()->SendStablePet(guid);
break;
case GossipOptionNpc::PetSpecializationMaster:
PlayerTalkClass->SendCloseGossip();
SendRespecWipeConfirm(guid, sWorld->getBoolConfig(CONFIG_NO_RESET_TALENT_COST) ? 0 : GetNextResetTalentsCost(), SPEC_RESET_PET_TALENTS);
break;
+ case GossipOptionNpc::GuildBanker:
+ if (Guild* const guild = GetGuild())
+ guild->SendBankList(GetSession(), 0, true);
+ else
+ Guild::SendCommandResult(GetSession(), GUILD_COMMAND_VIEW_TAB, ERR_GUILD_PLAYER_NOT_IN_GUILD);
+ break;
+ case GossipOptionNpc::Spellclick:
+ if (Unit* sourceUnit = source->ToUnit())
+ sourceUnit->HandleSpellClick(this);
+ break;
case GossipOptionNpc::DisableXPGain:
PlayerTalkClass->SendCloseGossip();
CastSpell(nullptr, SPELL_EXPERIENCE_ELIMINATED, true);
@@ -13923,9 +13880,6 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men
RemoveAurasDueToSpell(SPELL_EXPERIENCE_ELIMINATED);
RemovePlayerFlag(PLAYER_FLAGS_NO_XP_GAIN);
break;
- case GossipOptionNpc::Mailbox:
- GetSession()->SendShowMailBox(guid);
- break;
case GossipOptionNpc::SpecializationMaster:
PlayerTalkClass->SendCloseGossip();
SendRespecWipeConfirm(guid, 0, SPEC_RESET_SPECIALIZATION);
@@ -13934,24 +13888,77 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men
PlayerTalkClass->SendCloseGossip();
SendRespecWipeConfirm(guid, 0, SPEC_RESET_GLYPHS);
break;
- case GossipOptionNpc::GarrisonTalent:
- {
- GossipMenuAddon const* addon = sObjectMgr->GetGossipMenuAddon(menuId);
- GossipMenuItemAddon const* itemAddon = sObjectMgr->GetGossipMenuItemAddon(menuId, gossipListId);
- SendGarrisonOpenTalentNpc(guid, itemAddon ? itemAddon->GarrTalentTreeID.value_or(0) : 0, addon ? addon->FriendshipFactionID : 0);
+ case GossipOptionNpc::GarrisonTradeskillNpc: // NYI
break;
- }
- case GossipOptionNpc::Transmogrify:
- GetSession()->SendOpenTransmogrifier(guid);
+ case GossipOptionNpc::GarrisonRecruitment: // NYI
break;
- case GossipOptionNpc::AzeriteRespec:
- PlayerTalkClass->SendCloseGossip();
- GetSession()->SendAzeriteRespecNPC(guid);
+ case GossipOptionNpc::ChromieTimeNpc: // NYI
+ break;
+ case GossipOptionNpc::RuneforgeLegendaryCrafting: // NYI
+ break;
+ case GossipOptionNpc::RuneforgeLegendaryUpgrade: // NYI
+ break;
+ case GossipOptionNpc::ProfessionsCraftingOrder: // NYI
+ break;
+ case GossipOptionNpc::ProfessionsCustomerOrder: // NYI
+ break;
+ case GossipOptionNpc::BarbersChoice: // NYI - unknown if needs sending
break;
default:
+ handled = false;
break;
}
+ if (!handled)
+ {
+ if (item->GossipNpcOptionID)
+ {
+ GossipMenuAddon const* addon = sObjectMgr->GetGossipMenuAddon(menuId);
+
+ WorldPackets::NPC::GossipOptionNPCInteraction npcInteraction;
+ npcInteraction.GossipGUID = source->GetGUID();
+ npcInteraction.GossipNpcOptionID = *item->GossipNpcOptionID;
+ if (addon && addon->FriendshipFactionID)
+ npcInteraction.FriendshipFactionID = addon->FriendshipFactionID;
+
+ SendDirectMessage(npcInteraction.Write());
+ }
+ else
+ {
+ static constexpr std::array<PlayerInteractionType, AsUnderlyingType(GossipOptionNpc::Count)> GossipOptionNpcToInteractionType =
+ {
+ PlayerInteractionType::None, PlayerInteractionType::Vendor, PlayerInteractionType::TaxiNode,
+ PlayerInteractionType::Trainer, PlayerInteractionType::SpiritHealer, PlayerInteractionType::Binder,
+ PlayerInteractionType::Banker, PlayerInteractionType::PetitionVendor, PlayerInteractionType::TabardVendor,
+ PlayerInteractionType::BattleMaster, PlayerInteractionType::Auctioneer, PlayerInteractionType::TalentMaster,
+ PlayerInteractionType::StableMaster, PlayerInteractionType::None, PlayerInteractionType::GuildBanker,
+ PlayerInteractionType::None, PlayerInteractionType::None, PlayerInteractionType::None,
+ PlayerInteractionType::MailInfo, PlayerInteractionType::None, PlayerInteractionType::LFGDungeon,
+ PlayerInteractionType::ArtifactForge, PlayerInteractionType::None, PlayerInteractionType::SpecializationMaster,
+ PlayerInteractionType::None, PlayerInteractionType::None, PlayerInteractionType::GarrArchitect,
+ PlayerInteractionType::GarrMission, PlayerInteractionType::ShipmentCrafter, PlayerInteractionType::GarrTradeskill,
+ PlayerInteractionType::GarrRecruitment, PlayerInteractionType::AdventureMap, PlayerInteractionType::GarrTalent,
+ PlayerInteractionType::ContributionCollector, PlayerInteractionType::Transmogrifier, PlayerInteractionType::AzeriteRespec,
+ PlayerInteractionType::IslandQueue, PlayerInteractionType::ItemInteraction, PlayerInteractionType::WorldMap,
+ PlayerInteractionType::Soulbind, PlayerInteractionType::ChromieTime, PlayerInteractionType::CovenantPreview,
+ PlayerInteractionType::LegendaryCrafting, PlayerInteractionType::NewPlayerGuide, PlayerInteractionType::LegendaryCrafting,
+ PlayerInteractionType::Renown, PlayerInteractionType::BlackMarketAuctioneer, PlayerInteractionType::PerksProgramVendor,
+ PlayerInteractionType::ProfessionsCraftingOrder, PlayerInteractionType::Professions, PlayerInteractionType::ProfessionsCustomerOrder,
+ PlayerInteractionType::TraitSystem, PlayerInteractionType::BarbersChoice, PlayerInteractionType::MajorFactionRenown
+ };
+
+ PlayerInteractionType interactionType = GossipOptionNpcToInteractionType[AsUnderlyingType(gossipOptionNpc)];
+ if (interactionType != PlayerInteractionType::None)
+ {
+ WorldPackets::NPC::NPCInteractionOpenResult npcInteraction;
+ npcInteraction.Npc = source->GetGUID();
+ npcInteraction.InteractionType = interactionType;
+ npcInteraction.Success = true;
+ SendDirectMessage(npcInteraction.Write());
+ }
+ }
+ }
+
ModifyMoney(-cost);
}
@@ -16781,7 +16788,7 @@ void Player::_LoadEquipmentSets(PreparedQueryResult result)
eqSet.Data.AssignedSpecIndex = fields[5].GetInt32();
eqSet.State = EQUIPMENT_SET_UNCHANGED;
- for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
+ for (uint32 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
if (ObjectGuid::LowType guid = fields[6 + i].GetUInt64())
eqSet.Data.Pieces[i] = ObjectGuid::Create<HighGuid::Item>(guid);
@@ -16820,7 +16827,7 @@ void Player::_LoadTransmogOutfits(PreparedQueryResult result)
eqSet.State = EQUIPMENT_SET_UNCHANGED;
eqSet.Data.Pieces.fill(ObjectGuid::Empty);
- for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
+ for (uint32 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
eqSet.Data.Appearances[i] = fields[5 + i].GetInt32();
for (std::size_t i = 0; i < eqSet.Data.Enchants.size(); ++i)
@@ -17185,16 +17192,6 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol
InitDisplayIds();
- // cleanup inventory related item value fields (it will be filled correctly in _LoadInventory)
- for (uint8 slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; ++slot)
- {
- SetInvSlot(slot, ObjectGuid::Empty);
- SetVisibleItemSlot(slot, nullptr);
-
- delete m_items[slot];
- m_items[slot] = nullptr;
- }
-
TC_LOG_DEBUG("entities.player.loading", "Player::LoadFromDB: Load Basic value of player '%s' is: ", m_name.c_str());
outDebugValues();
@@ -17489,6 +17486,8 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol
time_t now = GameTime::GetGameTime();
time_t logoutTime = time_t(fields.logout_time);
+ SetUpdateFieldValue(m_values.ModifyValue(&Player::m_playerData).ModifyValue(&UF::PlayerData::LogoutTime), logoutTime);
+
// since last logout (in seconds)
uint32 time_diff = uint32(now - logoutTime); //uint64 is excessive for a time_diff in seconds.. uint32 allows for 136~ year difference.
@@ -19353,7 +19352,7 @@ void Player::SaveToDB(LoginDatabaseTransaction loginTransaction, CharacterDataba
ss.str("");
// cache equipment...
- for (uint32 i = 0; i < INVENTORY_SLOT_BAG_END; ++i)
+ for (uint32 i = 0; i < REAGENT_BAG_SLOT_END; ++i)
{
if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
{
@@ -19501,7 +19500,7 @@ void Player::SaveToDB(LoginDatabaseTransaction loginTransaction, CharacterDataba
ss.str("");
// cache equipment...
- for (uint32 i = 0; i < INVENTORY_SLOT_BAG_END; ++i)
+ for (uint32 i = 0; i < REAGENT_BAG_SLOT_END; ++i)
{
if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
{
@@ -22350,7 +22349,7 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorguid, uint32 vendorslot, uin
return false;
}
- if (iece->MinFactionID && uint32(GetReputationRank(iece->MinFactionID)) < iece->MinReputation)
+ if (iece->MinFactionID && int32(GetReputationRank(iece->MinFactionID)) < iece->MinReputation)
{
SendBuyError(BUY_ERR_REPUTATION_REQUIRE, creature, item, 0);
return false;
@@ -25897,6 +25896,10 @@ TalentLearnResult Player::LearnPvpTalent(uint32 talentID, uint8 slot, int32* spe
if (HasPvpTalent(talentID, GetActiveTalentGroup()))
return TALENT_FAILED_UNKNOWN;
+ if (PlayerConditionEntry const* playerCondition = sPlayerConditionStore.LookupEntry(talentInfo->PlayerConditionID))
+ if (!ConditionMgr::IsPlayerMeetingCondition(this, playerCondition))
+ return TALENT_FAILED_CANT_DO_THAT_RIGHT_NOW;
+
if (PvpTalentEntry const* talent = sPvpTalentStore.LookupEntry(GetPvpTalentMap(GetActiveTalentGroup())[slot]))
{
if (!HasPlayerFlag(PLAYER_FLAGS_RESTING) && !HasUnitFlag2(UNIT_FLAG2_ALLOW_CHANGING_TALENTS))
@@ -26283,7 +26286,7 @@ void Player::_SaveEquipmentSets(CharacterDatabaseTransaction trans)
stmt->setString(j++, eqSet.Data.SetIcon);
stmt->setUInt32(j++, eqSet.Data.IgnoreMask);
stmt->setInt32(j++, eqSet.Data.AssignedSpecIndex);
- for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
+ for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
stmt->setUInt64(j++, eqSet.Data.Pieces[i].GetCounter());
stmt->setUInt64(j++, GetGUID().GetCounter());
stmt->setUInt64(j++, eqSet.Data.Guid);
@@ -26295,7 +26298,7 @@ void Player::_SaveEquipmentSets(CharacterDatabaseTransaction trans)
stmt->setString(j++, eqSet.Data.SetName);
stmt->setString(j++, eqSet.Data.SetIcon);
stmt->setUInt32(j++, eqSet.Data.IgnoreMask);
- for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
+ for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
stmt->setInt32(j++, eqSet.Data.Appearances[i]);
for (std::size_t i = 0; i < eqSet.Data.Enchants.size(); ++i)
stmt->setInt32(j++, eqSet.Data.Enchants[i]);
@@ -26320,7 +26323,7 @@ void Player::_SaveEquipmentSets(CharacterDatabaseTransaction trans)
stmt->setString(j++, eqSet.Data.SetIcon);
stmt->setUInt32(j++, eqSet.Data.IgnoreMask);
stmt->setInt32(j++, eqSet.Data.AssignedSpecIndex);
- for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
+ for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
stmt->setUInt64(j++, eqSet.Data.Pieces[i].GetCounter());
}
else
@@ -26332,7 +26335,7 @@ void Player::_SaveEquipmentSets(CharacterDatabaseTransaction trans)
stmt->setString(j++, eqSet.Data.SetName);
stmt->setString(j++, eqSet.Data.SetIcon);
stmt->setUInt32(j++, eqSet.Data.IgnoreMask);
- for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
+ for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
stmt->setInt32(j++, eqSet.Data.Appearances[i]);
for (std::size_t i = 0; i < eqSet.Data.Enchants.size(); ++i)
stmt->setInt32(j++, eqSet.Data.Enchants[i]);
@@ -27639,8 +27642,9 @@ void Player::ValidateMovementInfo(MovementInfo* mi)
void Player::SendSupercededSpell(uint32 oldSpell, uint32 newSpell) const
{
WorldPackets::Spells::SupercededSpells supercededSpells;
- supercededSpells.SpellID.push_back(newSpell);
- supercededSpells.Superceded.push_back(oldSpell);
+ WorldPackets::Spells::LearnedSpellInfo& learnedSpellInfo = supercededSpells.ClientLearnedSpellData.emplace_back();
+ learnedSpellInfo.SpellID = newSpell;
+ learnedSpellInfo.Superceded = oldSpell;
SendDirectMessage(supercededSpells.Write());
}
@@ -27934,7 +27938,7 @@ void Player::UpdateAverageItemLevelTotal()
ForEachItem(ItemSearchLocation::Everywhere, [this, &bestItemLevels, &sum](Item* item)
{
ItemTemplate const* itemTemplate = item->GetTemplate();
- if (itemTemplate)
+ if (itemTemplate && itemTemplate->GetInventoryType() < INVTYPE_PROFESSION_TOOL)
{
uint16 dest;
if (item->IsEquipped())
@@ -28133,12 +28137,3 @@ void Player::SendDisplayToast(uint32 entry, DisplayToastType type, bool isBonusR
SendDirectMessage(displayToast.Write());
}
-
-void Player::SendGarrisonOpenTalentNpc(ObjectGuid guid, int32 garrTalentTreeId, int32 friendshipFactionId)
-{
- WorldPackets::Garrison::GarrisonOpenTalentNpc openTalentNpc;
- openTalentNpc.NpcGUID = guid;
- openTalentNpc.GarrTalentTreeID = garrTalentTreeId;
- openTalentNpc.FriendshipFactionID = friendshipFactionId;
- SendDirectMessage(openTalentNpc.Write());
-}
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index c155ccd6d01..ff4b3b1afa9 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -358,7 +358,7 @@ struct ActionButton
}
};
-#define MAX_ACTION_BUTTONS 132
+#define MAX_ACTION_BUTTONS 180
typedef std::map<uint8, ActionButton> ActionButtonList;
@@ -637,7 +637,7 @@ enum PlayerSlots
// first slot for item stored (in any way in player m_items data)
PLAYER_SLOT_START = 0,
// last+1 slot for item stored (in any way in player m_items data)
- PLAYER_SLOT_END = 199,
+ PLAYER_SLOT_END = 218,
PLAYER_SLOTS_COUNT = (PLAYER_SLOT_END - PLAYER_SLOT_START)
};
@@ -671,50 +671,82 @@ enum EquipmentSlots : uint8 // 19 slots
EQUIPMENT_SLOT_END = 19
};
-#define VISIBLE_ITEM_ENTRY_OFFSET 0
-#define VISIBLE_ITEM_ENCHANTMENT_OFFSET 1
+enum ProfessionSlots : uint8
+{
+ PROFESSION_SLOT_PROFESSION1_TOOL = 19,
+ PROFESSION_SLOT_PROFESSION1_GEAR1 = 20,
+ PROFESSION_SLOT_PROFESSION1_GEAR2 = 21,
+ PROFESSION_SLOT_PROFESSION2_TOOL = 22,
+ PROFESSION_SLOT_PROFESSION2_GEAR1 = 23,
+ PROFESSION_SLOT_PROFESSION2_GEAR2 = 24,
+ PROFESSION_SLOT_COOKING_TOOL = 25,
+ PROFESSION_SLOT_COOKING_GEAR1 = 26,
+ PROFESSION_SLOT_FISHING_TOOL = 27,
+ PROFESSION_SLOT_FISHING_GEAR1 = 28,
+ PROFESSION_SLOT_FISHING_GEAR2 = 29,
+
+ PROFESSION_SLOT_END,
+ PROFESSION_SLOT_START = PROFESSION_SLOT_PROFESSION1_TOOL
+};
enum InventorySlots : uint8 // 4 slots
{
- INVENTORY_SLOT_BAG_START = 19,
- INVENTORY_SLOT_BAG_END = 23
+ INVENTORY_SLOT_BAG_START = 30,
+ INVENTORY_SLOT_BAG_END = 34
+};
+
+enum ReagentBagSlots : uint8 // 1 slot
+{
+ REAGENT_BAG_SLOT_START = 34,
+ REAGENT_BAG_SLOT_END = 35
};
enum InventoryPackSlots : uint8 // 28 slots
{
- INVENTORY_SLOT_ITEM_START = 23,
- INVENTORY_SLOT_ITEM_END = 51
+ INVENTORY_SLOT_ITEM_START = 35,
+ INVENTORY_SLOT_ITEM_END = 63
};
enum BankItemSlots // 28 slots
{
- BANK_SLOT_ITEM_START = 51,
- BANK_SLOT_ITEM_END = 79
+ BANK_SLOT_ITEM_START = 63,
+ BANK_SLOT_ITEM_END = 91
};
enum BankBagSlots // 7 slots
{
- BANK_SLOT_BAG_START = 79,
- BANK_SLOT_BAG_END = 86
+ BANK_SLOT_BAG_START = 91,
+ BANK_SLOT_BAG_END = 98
};
enum BuyBackSlots // 12 slots
{
// stored in m_buybackitems
- BUYBACK_SLOT_START = 86,
- BUYBACK_SLOT_END = 98
+ BUYBACK_SLOT_START = 98,
+ BUYBACK_SLOT_END = 110
};
enum ReagentSlots // 98 slots
{
- REAGENT_SLOT_START = 98,
- REAGENT_SLOT_END = 196,
+ REAGENT_SLOT_START = 110,
+ REAGENT_SLOT_END = 208,
};
enum ChildEquipmentSlots
{
- CHILD_EQUIPMENT_SLOT_START = 196,
- CHILD_EQUIPMENT_SLOT_END = 199,
+ CHILD_EQUIPMENT_SLOT_START = 208,
+ CHILD_EQUIPMENT_SLOT_END = 211,
+};
+
+enum EquipableSpellSlots
+{
+ EQUIPABLE_SPELL_OFFENSIVE_SLOT1 = 211,
+ EQUIPABLE_SPELL_OFFENSIVE_SLOT2 = 212,
+ EQUIPABLE_SPELL_OFFENSIVE_SLOT3 = 213,
+ EQUIPABLE_SPELL_OFFENSIVE_SLOT4 = 214,
+ EQUIPABLE_SPELL_UTILITY_SLOT1 = 215,
+ EQUIPABLE_SPELL_DEFENSIVE_SLOT1 = 216,
+ EQUIPABLE_SPELL_MOBILITY_SLOT1 = 217
};
struct ItemPosCount
@@ -1037,7 +1069,9 @@ enum TalentLearnResult
TALENT_FAILED_AFFECTING_COMBAT = 5,
TALENT_FAILED_CANT_REMOVE_TALENT = 6,
TALENT_FAILED_CANT_DO_THAT_CHALLENGE_MODE_ACTIVE = 7,
- TALENT_FAILED_REST_AREA = 8
+ TALENT_FAILED_REST_AREA = 8,
+ TALENT_FAILED_UNSPENT_TALENT_POINTS = 9,
+ TALENT_FAILED_IN_PVP_MATCH = 10
};
struct TC_GAME_API SpecializationInfo
@@ -1236,11 +1270,18 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
EnumFlag<ItemSearchLocation> flag = location;
if (flag.HasFlag(ItemSearchLocation::Equipment))
+ {
for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
if (callback(pItem) == ItemSearchCallbackResult::Stop)
return false;
+ for (uint8 i = PROFESSION_SLOT_START; i < PROFESSION_SLOT_END; ++i)
+ if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
+ if (callback(pItem) == ItemSearchCallbackResult::Stop)
+ return false;
+ }
+
if (flag.HasFlag(ItemSearchLocation::Inventory))
{
uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount();
@@ -1278,10 +1319,19 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
}
if (flag.HasFlag(ItemSearchLocation::ReagentBank))
+ {
+ for (uint8 i = REAGENT_BAG_SLOT_START; i < REAGENT_BAG_SLOT_END; ++i)
+ if (Bag* bag = GetBagByPos(i))
+ for (uint32 j = 0; j < GetBagSize(bag); ++j)
+ if (Item* pItem = GetItemInBag(bag, j))
+ if (callback(pItem) == ItemSearchCallbackResult::Stop)
+ return false;
+
for (uint8 i = REAGENT_SLOT_START; i < REAGENT_SLOT_END; ++i)
if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
if (callback(pItem) == ItemSearchCallbackResult::Stop)
return false;
+ }
return true;
}
@@ -1363,7 +1413,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void AutoUnequipOffhandIfNeed(bool force = false);
void EquipChildItem(uint8 parentBag, uint8 parentSlot, Item* parentItem);
void AutoUnequipChildItem(Item* parentItem);
- bool StoreNewItemInBestSlots(uint32 item_id, uint32 item_count);
+ bool StoreNewItemInBestSlots(uint32 itemId, uint32 amount, ItemContext context);
void AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore const& store, ItemContext context = ItemContext::NONE, bool broadcast = false, bool createdByPlayer = false);
void AutoStoreLoot(uint32 loot_id, LootStore const& store, ItemContext context = ItemContext::NONE, bool broadcast = false, bool createdByPlayer = false) { AutoStoreLoot(NULL_BAG, NULL_SLOT, loot_id, store, context, broadcast, createdByPlayer); }
void StoreLootItem(ObjectGuid lootWorldObjectGuid, uint8 lootSlot, Loot* loot, AELootResult* aeResult = nullptr);
@@ -1481,7 +1531,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void PrepareGossipMenu(WorldObject* source, uint32 menuId, bool showQuests = false);
void SendPreparedGossip(WorldObject* source);
- void OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 menuId);
+ void OnGossipSelect(WorldObject* source, int32 gossipOptionId, uint32 menuId);
uint32 GetGossipTextId(uint32 menuId, WorldObject* source);
uint32 GetGossipTextId(WorldObject* source);
@@ -2770,8 +2820,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
bool CanEnableWarModeInArea() const;
void UpdateWarModeAuras();
- void SendGarrisonOpenTalentNpc(ObjectGuid guid, int32 garrTalentTreeId, int32 friendshipFactionId);
-
std::string GetDebugInfo() const override;
UF::UpdateField<UF::PlayerData, 0, TYPEID_PLAYER> m_playerData;
diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp
index 38fec84894d..bb35bf3db24 100644
--- a/src/server/game/Entities/Unit/StatSystem.cpp
+++ b/src/server/game/Entities/Unit/StatSystem.cpp
@@ -595,7 +595,9 @@ float const m_diminishing_k[MAX_CLASSES] =
0.9830f, // Warlock
0.9830f, // Monk
0.9720f, // Druid
- 0.9830f // Demon Hunter
+ 0.9830f, // Demon Hunter
+ 0.9880f, // Evoker
+ 1.0f, // Adventurer
};
// helper function
@@ -634,7 +636,9 @@ float const parry_cap[MAX_CLASSES] =
0.0f, // Warlock
90.6425f, // Monk
0.0f, // Druid
- 65.631440f // Demon Hunter
+ 65.631440f, // Demon Hunter
+ 0.0f, // Evoker
+ 0.0f, // Adventurer
};
void Player::UpdateParryPercentage()
@@ -673,7 +677,9 @@ float const dodge_cap[MAX_CLASSES] =
150.375940f, // Warlock
145.560408f, // Monk
116.890707f, // Druid
- 145.560408f // Demon Hunter
+ 145.560408f, // Demon Hunter
+ 145.560408f, // Evoker
+ 0.0f, // Adventurer
};
void Player::UpdateDodgePercentage()
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 3580a5c2824..96e0da89968 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -6645,6 +6645,11 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui
{
return aurEff->GetCasterGUID() == caster->GetGUID() && aurEff->IsAffectingSpell(spellProto);
});
+
+ TakenTotalMod *= GetTotalAuraMultiplier(SPELL_AURA_MOD_DAMAGE_TAKEN_FROM_CASTER_BY_LABEL, [caster, spellProto](AuraEffect const* aurEff) -> bool
+ {
+ return aurEff->GetCasterGUID() == caster->GetGUID() && spellProto->HasLabel(aurEff->GetMiscValue());
+ });
}
if (damagetype == DOT)
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 9f8c2fbafcb..cd0c4858597 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -188,6 +188,7 @@ enum UnitMods
UNIT_MOD_ARCANE_CHARGES,
UNIT_MOD_FURY,
UNIT_MOD_PAIN,
+ UNIT_MOD_ESSENCE,
UNIT_MOD_ARMOR, // UNIT_MOD_ARMOR..UNIT_MOD_RESISTANCE_ARCANE must be in existed order, it's accessed by index values of SpellSchools enum.
UNIT_MOD_RESISTANCE_HOLY,
UNIT_MOD_RESISTANCE_FIRE,
@@ -207,7 +208,7 @@ enum UnitMods
UNIT_MOD_RESISTANCE_START = UNIT_MOD_ARMOR,
UNIT_MOD_RESISTANCE_END = UNIT_MOD_RESISTANCE_ARCANE + 1,
UNIT_MOD_POWER_START = UNIT_MOD_MANA,
- UNIT_MOD_POWER_END = UNIT_MOD_PAIN + 1
+ UNIT_MOD_POWER_END = UNIT_MOD_ESSENCE + 1
};
static_assert(UNIT_MOD_POWER_END - UNIT_MOD_POWER_START == MAX_POWERS, "UnitMods powers section does not match Powers enum!");
diff --git a/src/server/game/Entities/Unit/UnitDefines.h b/src/server/game/Entities/Unit/UnitDefines.h
index c71b061b07e..0f9b5e35032 100644
--- a/src/server/game/Entities/Unit/UnitDefines.h
+++ b/src/server/game/Entities/Unit/UnitDefines.h
@@ -418,6 +418,8 @@ enum MovementFlags3 : uint32
{
MOVEMENTFLAG3_NONE = 0x00000000,
MOVEMENTFLAG3_DISABLE_INERTIA = 0x00000001,
+ MOVEMENTFLAG3_CAN_ADV_FLY = 0x00000002,
+ MOVEMENTFLAG3_ADV_FLYING = 0x00000004,
};
enum HitInfo