diff options
author | Shauren <shauren.trinity@gmail.com> | 2023-07-12 16:29:00 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2023-07-12 16:29:00 +0200 |
commit | 0cea730fa23473a85c47451c3bd13df816f2b6e4 (patch) | |
tree | 960078875798c5846a1aa465051da876642067e1 /src/server/game/Entities | |
parent | 252da139adedd20c297ce7bdd2abed2234fa1bb6 (diff) |
Core: Update to 10.1.5
Diffstat (limited to 'src/server/game/Entities')
-rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTrigger.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/GossipDef.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/GameObject/GameObjectData.h | 1 | ||||
-rw-r--r-- | src/server/game/Entities/Item/Item.cpp | 13 | ||||
-rw-r--r-- | src/server/game/Entities/Item/Item.h | 1 | ||||
-rw-r--r-- | src/server/game/Entities/Object/ObjectGuid.cpp | 37 | ||||
-rw-r--r-- | src/server/game/Entities/Object/ObjectGuid.h | 7 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateFields.cpp | 1110 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateFields.h | 458 | ||||
-rw-r--r-- | src/server/game/Entities/Pet/Pet.h | 6 | ||||
-rw-r--r-- | src/server/game/Entities/Pet/PetDefines.h | 17 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 290 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 12 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 7 |
14 files changed, 1355 insertions, 612 deletions
diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp index dc601efe9c9..a6fed3e9ab6 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp @@ -567,6 +567,10 @@ void AreaTrigger::HandleUnitEnterExit(std::vector<Unit*> const& newTargetList) _ai->OnUnitExit(leavingUnit); } } + + SetUpdateFieldValue(m_values.ModifyValue(&AreaTrigger::m_areaTriggerData).ModifyValue(&UF::AreaTriggerData::NumUnitsInside), _insideUnits.size()); + SetUpdateFieldValue(m_values.ModifyValue(&AreaTrigger::m_areaTriggerData).ModifyValue(&UF::AreaTriggerData::NumPlayersInside), + std::count_if(_insideUnits.begin(), _insideUnits.end(), [](ObjectGuid const& guid) { return guid.IsPlayer(); })); } AreaTriggerTemplate const* AreaTrigger::GetTemplate() const @@ -857,6 +861,8 @@ void AreaTrigger::InitOrbit(AreaTriggerOrbitInfo const& orbit, uint32 timeToTarg const_cast<UF::AreaTriggerData&>(*m_areaTriggerData).ClearChanged(&UF::AreaTriggerData::TimeToTarget); }); + SetUpdateFieldValue(m_values.ModifyValue(&AreaTrigger::m_areaTriggerData).ModifyValue(&UF::AreaTriggerData::OrbitPathTarget), orbit.PathTarget.value_or(ObjectGuid::Empty)); + _orbitInfo = orbit; _orbitInfo->TimeToTarget = timeToTarget; diff --git a/src/server/game/Entities/Creature/GossipDef.h b/src/server/game/Entities/Creature/GossipDef.h index 42d795b6296..d69f9373b05 100644 --- a/src/server/game/Entities/Creature/GossipDef.h +++ b/src/server/game/Entities/Creature/GossipDef.h @@ -26,7 +26,7 @@ class Object; class Quest; class WorldSession; struct GossipMenuItems; -enum class QuestGiverStatus : uint32; +enum class QuestGiverStatus : uint64; #define GOSSIP_MAX_MENU_ITEMS 32 #define DEFAULT_GOSSIP_MESSAGE 0xffffff diff --git a/src/server/game/Entities/GameObject/GameObjectData.h b/src/server/game/Entities/GameObject/GameObjectData.h index 3e8645f9398..a63e85bb9f4 100644 --- a/src/server/game/Entities/GameObject/GameObjectData.h +++ b/src/server/game/Entities/GameObject/GameObjectData.h @@ -331,6 +331,7 @@ struct GameObjectTemplate struct { uint32 InteractRadiusOverride; // 0 Interact Radius Override (in hundredths), int, Min value: 0, Max value: 2147483647, Default value: 0 + uint32 Willthisduelgountilaplayerdies; // 1 Will this duel go until a player dies?, enum { false, true, }; Default: false } duelFlag; // 17 GAMEOBJECT_TYPE_FISHINGNODE struct diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 7ea5665984b..62cd2f12480 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -2482,6 +2482,19 @@ uint16 Item::GetVisibleAppearanceModId(Player const* owner) const return uint16(GetAppearanceModId()); } +uint32 Item::GetVisibleModifiedAppearanceId(Player const* owner) const +{ + uint32 itemModifiedAppearanceId = GetModifier(AppearanceModifierSlotBySpec[owner->GetActiveTalentGroup()]); + if (!itemModifiedAppearanceId) + itemModifiedAppearanceId = GetModifier(ITEM_MODIFIER_TRANSMOG_APPEARANCE_ALL_SPECS); + + if (!itemModifiedAppearanceId) + if (ItemModifiedAppearanceEntry const* itemModifiedAppearance = GetItemModifiedAppearance()) + itemModifiedAppearanceId = itemModifiedAppearance->ID; + + return itemModifiedAppearanceId; +} + int32 Item::GetVisibleSecondaryModifiedAppearanceId(Player const* owner) const { uint32 itemModifiedAppearanceId = GetModifier(SecondaryAppearanceModifierSlotBySpec[owner->GetActiveTalentGroup()]); diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index 42875e9f74f..ec233c98ffc 100644 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -412,6 +412,7 @@ class TC_GAME_API Item : public Object uint32 GetVisibleEntry(Player const* owner) const; uint16 GetVisibleAppearanceModId(Player const* owner) const; + uint32 GetVisibleModifiedAppearanceId(Player const* owner) const; int32 GetVisibleSecondaryModifiedAppearanceId(Player const* owner) const; uint32 GetVisibleEnchantmentId(Player const* owner) const; uint16 GetVisibleItemVisual(Player const* owner) const; diff --git a/src/server/game/Entities/Object/ObjectGuid.cpp b/src/server/game/Entities/Object/ObjectGuid.cpp index 77e9bef5746..e443d0a13b4 100644 --- a/src/server/game/Entities/Object/ObjectGuid.cpp +++ b/src/server/game/Entities/Object/ObjectGuid.cpp @@ -99,7 +99,9 @@ namespace "WOWGUID_FAKE_MODERATOR", nullptr, nullptr, - "WOWGUID_UNIQUE_ACCOUNT_OBJ_INITIALIZATION" + "WOWGUID_UNIQUE_ACCOUNT_OBJ_INITIALIZATION", + nullptr, + "WOWGUID_PENDING_PERMANENT_CHARACTER_ASSIGNMENT" }; ObjectGuid::LowType id = guid.GetCounter(); @@ -452,6 +454,25 @@ namespace return ObjectGuidFactory::CreateWorldLayer(arg1, arg2, arg3, arg4); } + std::string FormatLMMLobby(char const* typeName, ObjectGuid guid) + { + return Trinity::StringFormat("{}-{}-{}-{}-{}-{:X}", typeName, guid.GetRealmId(), uint32(guid.GetRawValue(1) >> 26) & 0xFFFFFF, + uint32(guid.GetRawValue(1) >> 18) & 0xFF, uint32(guid.GetRawValue(1) >> 10) & 0xFF, guid.GetRawValue(0)); + } + + ObjectGuid ParseLMMLobby(HighGuid /*type*/, char const* guidString) + { + uint32 realmId = 0; + uint32 arg2 = 0; + uint8 arg3 = 0; + uint8 arg4 = 0; + uint64 arg5 = 0; + if (std::sscanf(guidString, "%u-%u-%hhu-%hhu-%" SCNx64, &realmId, &arg2, &arg3, &arg4, &arg5) != 5) + return ObjectGuid::FromStringFailed; + + return ObjectGuidFactory::CreateLMMLobby(realmId, arg2, arg3, arg4, arg5); + } + ObjectGuidInfo(); } Info; @@ -460,7 +481,7 @@ namespace #define SET_GUID_INFO(type, format, parse) \ Names[AsUnderlyingType(HighGuid::type)] = #type;\ ClientFormatFunction[AsUnderlyingType(HighGuid::type)] = &ObjectGuidInfo::format;\ - ClientParseFunction[AsUnderlyingType(HighGuid::type)] = &ObjectGuidInfo::parse; + ClientParseFunction[AsUnderlyingType(HighGuid::type)] = &ObjectGuidInfo::parse SET_GUID_INFO(Null, FormatNull, ParseNull); SET_GUID_INFO(Uniq, FormatUniq, ParseUniq); @@ -515,6 +536,8 @@ namespace SET_GUID_INFO(ToolsClient, FormatToolsClient, ParseToolsClient); SET_GUID_INFO(WorldLayer, FormatWorldLayer, ParseWorldLayer); SET_GUID_INFO(ArenaTeam, FormatGuild, ParseGuild); + SET_GUID_INFO(LMMParty, FormatClient, ParseClient); + SET_GUID_INFO(LMMLobby, FormatLMMLobby, ParseLMMLobby); #undef SET_GUID_INFO } @@ -718,6 +741,16 @@ ObjectGuid ObjectGuidFactory::CreateWorldLayer(uint32 arg1, uint16 arg2, uint8 a | uint64(arg4 & 0x7FFFFF))); } +ObjectGuid ObjectGuidFactory::CreateLMMLobby(uint32 realmId, uint32 arg2, uint8 arg3, uint8 arg4, ObjectGuid::LowType counter) +{ + return ObjectGuid(uint64((uint64(HighGuid::LMMLobby) << 58) + | (uint64(GetRealmIdForObjectGuid(realmId)) << 42) + | (uint64(arg2 & 0xFFFFFFFF) << 26) + | (uint64(arg3 & 0xFF) << 18) + | (uint64(arg4 & 0xFF) << 10)), + counter); +} + ObjectGuid const ObjectGuid::Empty = ObjectGuid(); ObjectGuid const ObjectGuid::FromStringFailed = ObjectGuid::Create<HighGuid::Uniq>(UI64LIT(4)); ObjectGuid const ObjectGuid::TradeItem = ObjectGuid::Create<HighGuid::Uniq>(UI64LIT(10)); diff --git a/src/server/game/Entities/Object/ObjectGuid.h b/src/server/game/Entities/Object/ObjectGuid.h index b3a0213436d..46d88373807 100644 --- a/src/server/game/Entities/Object/ObjectGuid.h +++ b/src/server/game/Entities/Object/ObjectGuid.h @@ -124,6 +124,8 @@ enum class HighGuid ToolsClient = 50, WorldLayer = 51, ArenaTeam = 52, + LMMParty = 53, + LMMLobby = 54, Count, }; @@ -158,6 +160,7 @@ enum class ObjectGuidFormatType ClubFinder, ToolsClient, WorldLayer, + LMMLobby, }; template<HighGuid high> @@ -227,6 +230,8 @@ MAKE_GUID_TRAIT(HighGuid::ClubFinder, ObjectGuidSequenceSource::Global, ObjectGu MAKE_GUID_TRAIT(HighGuid::ToolsClient, ObjectGuidSequenceSource::Realm, ObjectGuidFormatType::ToolsClient); MAKE_GUID_TRAIT(HighGuid::WorldLayer, ObjectGuidSequenceSource::Global, ObjectGuidFormatType::WorldLayer); MAKE_GUID_TRAIT(HighGuid::ArenaTeam, ObjectGuidSequenceSource::Realm, ObjectGuidFormatType::Guild); +MAKE_GUID_TRAIT(HighGuid::LMMParty, ObjectGuidSequenceSource::Realm, ObjectGuidFormatType::Client); +MAKE_GUID_TRAIT(HighGuid::LMMLobby, ObjectGuidSequenceSource::Realm, ObjectGuidFormatType::LMMLobby); class ByteBuffer; class ObjectGuid; @@ -252,6 +257,7 @@ public: static ObjectGuid CreateClubFinder(uint32 realmId, uint8 type, uint32 clubFinderId, uint64 dbId); static ObjectGuid CreateToolsClient(uint16 mapId, uint32 serverId, uint64 counter); static ObjectGuid CreateWorldLayer(uint32 arg1, uint16 arg2, uint8 arg3, uint32 arg4); + static ObjectGuid CreateLMMLobby(uint32 realmId, uint32 arg2, uint8 arg3, uint8 arg4, uint64 counter); }; #pragma pack(push, 1) @@ -367,6 +373,7 @@ class TC_GAME_API ObjectGuid template<HighGuid type> static std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::ClubFinder, ObjectGuid> Create(uint8 clubType, uint32 clubFinderId, ObjectGuid::LowType dbId) { return ObjectGuidFactory::CreateClubFinder(0, clubType, clubFinderId, dbId); } template<HighGuid type> static std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::ToolsClient, ObjectGuid> Create(uint16 mapId, uint32 serverId, ObjectGuid::LowType counter) { return ObjectGuidFactory::CreateToolsClient(mapId, serverId, counter); } template<HighGuid type> static std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::WorldLayer, ObjectGuid> Create(uint32 arg1, uint16 arg2, uint8 arg3, uint32 arg4) { return ObjectGuidFactory::CreateWorldLayer(arg1, arg2, arg3, arg4); } + template<HighGuid type> static std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::LMMLobby, ObjectGuid> Create(uint32 arg2, uint8 arg3, uint8 arg4, ObjectGuid::LowType counter) { return ObjectGuidFactory::CreateLMMLobby(0, arg2, arg3, arg4, counter); } protected: ObjectGuid(uint64 high, uint64 low) diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.cpp b/src/server/game/Entities/Object/Updates/UpdateFields.cpp index ebb9c34207e..93ac9f8c967 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFields.cpp +++ b/src/server/game/Entities/Object/Updates/UpdateFields.cpp @@ -162,25 +162,19 @@ void ItemModList::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Item con if (changesMask[0]) { - if (changesMask[0]) - { - if (!ignoreChangesMask) - Values.WriteUpdateMask(data, 6); - else - WriteCompleteDynamicFieldUpdateMask(Values.size(), data, 6); - } + if (!ignoreChangesMask) + Values.WriteUpdateMask(data, 6); + else + WriteCompleteDynamicFieldUpdateMask(Values.size(), data, 6); } data.FlushBits(); if (changesMask[0]) { - if (changesMask[0]) + for (uint32 i = 0; i < Values.size(); ++i) { - for (uint32 i = 0; i < Values.size(); ++i) + if (Values.HasChanged(i) || ignoreChangesMask) { - if (Values.HasChanged(i) || ignoreChangesMask) - { - Values[i].WriteUpdate(data, ignoreChangesMask, owner, receiver); - } + Values[i].WriteUpdate(data, ignoreChangesMask, owner, receiver); } } } @@ -1048,6 +1042,7 @@ void UnitData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisi data << int32(Stats[i]); data << int32(StatPosBuff[i]); data << int32(StatNegBuff[i]); + data << int32(StatSupportBuff[i]); } } if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner | UpdateFieldFlag::Empath)) @@ -1080,10 +1075,12 @@ void UnitData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisi data << int32(AttackPowerModPos); data << int32(AttackPowerModNeg); data << float(AttackPowerMultiplier); + data << int32(AttackPowerModSupport); data << int32(RangedAttackPower); data << int32(RangedAttackPowerModPos); data << int32(RangedAttackPowerModNeg); data << float(RangedAttackPowerMultiplier); + data << int32(RangedAttackPowerModSupport); data << int32(MainHandWeaponAttackPower); data << int32(OffHandWeaponAttackPower); data << int32(RangedWeaponAttackPower); @@ -1114,7 +1111,9 @@ void UnitData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisi data << uint32(WorldEffects.size()); data << uint32(ChannelObjects.size()); data << int32(FlightCapabilityID); + data << float(GlideEventSpeedDivisor); data << uint32(SilencedSchoolMask); + data << uint32(CurrentAreaID); data << NameplateAttachToGUID; for (uint32 i = 0; i < PassiveSpells.size(); ++i) { @@ -1132,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, 0xC3FEFFFFu, 0x003DFFFFu, 0xFFFFFF01u, 0x0007FFFFu, 0x00003F80u, 0x00000000u }); + Mask allowedMaskForTarget({ 0xFFFFDFFFu, 0xC3FEFFFFu, 0x003DFFFFu, 0xFFFFFC01u, 0x007FFFFFu, 0x0003F800u, 0x00000000u }); AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); } @@ -1140,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, 0x3C010000u, 0xFFC20000u, 0x400000FEu, 0xFFF80000u, 0xFFFFC07Fu, 0x0001FFFFu }; + allowedMaskForTarget |= { 0x00002000u, 0x3C010000u, 0xFFC20000u, 0x000003FEu, 0xFF800004u, 0xFFFC07FFu, 0x01FFFFFFu }; if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::UnitAll)) - allowedMaskForTarget |= { 0x00000000u, 0x00000000u, 0x00000000u, 0x40000000u, 0xFFF80000u, 0x0000007Fu, 0x00000000u }; + allowedMaskForTarget |= { 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xFF800004u, 0x000007FFu, 0x00000000u }; if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Empath)) - allowedMaskForTarget |= { 0x00000000u, 0x3C000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xF8000000u, 0x00000007u }; + allowedMaskForTarget |= { 0x00000000u, 0x3C000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x000007F8u }; } void UnitData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags) { - Mask allowedMaskForTarget({ 0xFFFFDFFFu, 0xC3FEFFFFu, 0x003DFFFFu, 0xFFFFFF01u, 0x0007FFFFu, 0x00003F80u, 0x00000000u }); + Mask allowedMaskForTarget({ 0xFFFFDFFFu, 0xC3FEFFFFu, 0x003DFFFFu, 0xFFFFFC01u, 0x007FFFFFu, 0x0003F800u, 0x00000000u }); AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); changesMask &= allowedMaskForTarget; } @@ -1570,219 +1569,239 @@ void UnitData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignor } if (changesMask[90]) { - data << int32(RangedAttackPower); + data << int32(AttackPowerModSupport); } if (changesMask[91]) { - data << int32(RangedAttackPowerModPos); + data << int32(RangedAttackPower); } if (changesMask[92]) { - data << int32(RangedAttackPowerModNeg); + data << int32(RangedAttackPowerModPos); } if (changesMask[93]) { - data << float(RangedAttackPowerMultiplier); + data << int32(RangedAttackPowerModNeg); } if (changesMask[94]) { - data << int32(MainHandWeaponAttackPower); + data << float(RangedAttackPowerMultiplier); } if (changesMask[95]) { - data << int32(OffHandWeaponAttackPower); + data << int32(RangedAttackPowerModSupport); } } if (changesMask[96]) { if (changesMask[97]) { - data << int32(RangedWeaponAttackPower); + data << int32(MainHandWeaponAttackPower); } if (changesMask[98]) { - data << int32(SetAttackSpeedAura); + data << int32(OffHandWeaponAttackPower); } if (changesMask[99]) { - data << float(Lifesteal); + data << int32(RangedWeaponAttackPower); } if (changesMask[100]) { - data << float(MinRangedDamage); + data << int32(SetAttackSpeedAura); } if (changesMask[101]) { - data << float(MaxRangedDamage); + data << float(Lifesteal); } if (changesMask[102]) { - data << float(ManaCostMultiplier); + data << float(MinRangedDamage); } if (changesMask[103]) { - data << float(MaxHealthModifier); + data << float(MaxRangedDamage); } if (changesMask[104]) { - data << float(HoverHeight); + data << float(ManaCostMultiplier); } if (changesMask[105]) { - data << int32(MinItemLevelCutoff); + data << float(MaxHealthModifier); } if (changesMask[106]) { - data << int32(MinItemLevel); + data << float(HoverHeight); } if (changesMask[107]) { - data << int32(MaxItemLevel); + data << int32(MinItemLevelCutoff); } if (changesMask[108]) { - data << int32(AzeriteItemLevel); + data << int32(MinItemLevel); } if (changesMask[109]) { - data << int32(WildBattlePetLevel); + data << int32(MaxItemLevel); } if (changesMask[110]) { - data << int32(BattlePetCompanionExperience); + data << int32(AzeriteItemLevel); } if (changesMask[111]) { - data << uint32(BattlePetCompanionNameTimestamp); + data << int32(WildBattlePetLevel); } if (changesMask[112]) { - data << int32(InteractSpellID); + data << int32(BattlePetCompanionExperience); } if (changesMask[113]) { - data << int32(ScaleDuration); + data << uint32(BattlePetCompanionNameTimestamp); } if (changesMask[114]) { - data << int32(LooksLikeMountID); + data << int32(InteractSpellID); } if (changesMask[115]) { - data << int32(LooksLikeCreatureID); + data << int32(ScaleDuration); } if (changesMask[116]) { - data << int32(LookAtControllerID); + data << int32(LooksLikeMountID); } if (changesMask[117]) { - data << int32(PerksVendorItemID); + data << int32(LooksLikeCreatureID); } if (changesMask[118]) { - data << int32(TaxiNodesID); + data << int32(LookAtControllerID); } if (changesMask[119]) { - data << GuildGUID; + data << int32(PerksVendorItemID); } if (changesMask[120]) { - data << int32(FlightCapabilityID); + data << int32(TaxiNodesID); } if (changesMask[121]) { - data << uint32(SilencedSchoolMask); + data << GuildGUID; } if (changesMask[122]) { + data << int32(FlightCapabilityID); + } + if (changesMask[123]) + { + data << float(GlideEventSpeedDivisor); + } + if (changesMask[124]) + { + data << uint32(SilencedSchoolMask); + } + if (changesMask[125]) + { + data << uint32(CurrentAreaID); + } + if (changesMask[126]) + { data << NameplateAttachToGUID; } } - if (changesMask[123]) + if (changesMask[127]) { for (uint32 i = 0; i < 2; ++i) { - if (changesMask[124 + i]) + if (changesMask[128 + i]) { data << uint32(ViewerDependentValue<NpcFlagsTag>::GetValue(this, i, owner, receiver)); } } } - if (changesMask[126]) + if (changesMask[130]) { for (uint32 i = 0; i < 10; ++i) { - if (changesMask[127 + i]) + if (changesMask[131 + i]) { data << int32(Power[i]); } - if (changesMask[137 + i]) + if (changesMask[141 + i]) { data << int32(MaxPower[i]); } - if (changesMask[147 + i]) + if (changesMask[151 + i]) { data << float(PowerRegenFlatModifier[i]); } - if (changesMask[157 + i]) + if (changesMask[161 + i]) { data << float(PowerRegenInterruptedFlatModifier[i]); } } } - if (changesMask[167]) + if (changesMask[171]) { for (uint32 i = 0; i < 3; ++i) { - if (changesMask[168 + i]) + if (changesMask[172 + i]) { VirtualItems[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } - if (changesMask[171]) + if (changesMask[175]) { for (uint32 i = 0; i < 2; ++i) { - if (changesMask[172 + i]) + if (changesMask[176 + i]) { data << uint32(AttackRoundBaseTime[i]); } } } - if (changesMask[174]) + if (changesMask[178]) { for (uint32 i = 0; i < 4; ++i) { - if (changesMask[175 + i]) + if (changesMask[179 + i]) { data << int32(Stats[i]); } - if (changesMask[179 + i]) + if (changesMask[183 + i]) { data << int32(StatPosBuff[i]); } - if (changesMask[183 + i]) + if (changesMask[187 + i]) { data << int32(StatNegBuff[i]); } + if (changesMask[191 + i]) + { + data << int32(StatSupportBuff[i]); + } } } - if (changesMask[187]) + if (changesMask[195]) { for (uint32 i = 0; i < 7; ++i) { - if (changesMask[188 + i]) + if (changesMask[196 + i]) { data << int32(Resistances[i]); } - if (changesMask[195 + i]) + if (changesMask[203 + i]) { data << int32(BonusResistanceMods[i]); } - if (changesMask[202 + i]) + if (changesMask[210 + i]) { data << int32(ManaCostModifier[i]); } @@ -1879,10 +1898,12 @@ void UnitData::ClearChangesMask() Base::ClearChangesMask(AttackPowerModPos); Base::ClearChangesMask(AttackPowerModNeg); Base::ClearChangesMask(AttackPowerMultiplier); + Base::ClearChangesMask(AttackPowerModSupport); Base::ClearChangesMask(RangedAttackPower); Base::ClearChangesMask(RangedAttackPowerModPos); Base::ClearChangesMask(RangedAttackPowerModNeg); Base::ClearChangesMask(RangedAttackPowerMultiplier); + Base::ClearChangesMask(RangedAttackPowerModSupport); Base::ClearChangesMask(MainHandWeaponAttackPower); Base::ClearChangesMask(OffHandWeaponAttackPower); Base::ClearChangesMask(RangedWeaponAttackPower); @@ -1909,7 +1930,9 @@ void UnitData::ClearChangesMask() Base::ClearChangesMask(TaxiNodesID); Base::ClearChangesMask(GuildGUID); Base::ClearChangesMask(FlightCapabilityID); + Base::ClearChangesMask(GlideEventSpeedDivisor); Base::ClearChangesMask(SilencedSchoolMask); + Base::ClearChangesMask(CurrentAreaID); Base::ClearChangesMask(NameplateAttachToGUID); Base::ClearChangesMask(NpcFlags); Base::ClearChangesMask(Power); @@ -1921,6 +1944,7 @@ void UnitData::ClearChangesMask() Base::ClearChangesMask(Stats); Base::ClearChangesMask(StatPosBuff); Base::ClearChangesMask(StatNegBuff); + Base::ClearChangesMask(StatSupportBuff); Base::ClearChangesMask(Resistances); Base::ClearChangesMask(BonusResistanceMods); Base::ClearChangesMask(ManaCostModifier); @@ -1947,10 +1971,9 @@ bool ChrCustomizationChoice::operator==(ChrCustomizationChoice const& right) con void QuestLog::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const { + data << int64(EndTime); data << int32(QuestID); data << uint32(StateFlags); - data << uint32(EndTime); - data << uint32(AcceptTime); data << uint32(ObjectiveFlags); for (uint32 i = 0; i < 24; ++i) { @@ -1973,30 +1996,26 @@ void QuestLog::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player cons { if (changesMask[1]) { - data << int32(QuestID); + data << int64(EndTime); } if (changesMask[2]) { - data << uint32(StateFlags); + data << int32(QuestID); } if (changesMask[3]) { - data << uint32(EndTime); + data << uint32(StateFlags); } if (changesMask[4]) { - data << uint32(AcceptTime); - } - if (changesMask[5]) - { data << uint32(ObjectiveFlags); } } - if (changesMask[6]) + if (changesMask[5]) { for (uint32 i = 0; i < 24; ++i) { - if (changesMask[7 + i]) + if (changesMask[6 + i]) { data << int16(ObjectiveProgress[i]); } @@ -2006,10 +2025,9 @@ void QuestLog::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player cons void QuestLog::ClearChangesMask() { + Base::ClearChangesMask(EndTime); Base::ClearChangesMask(QuestID); Base::ClearChangesMask(StateFlags); - Base::ClearChangesMask(EndTime); - Base::ClearChangesMask(AcceptTime); Base::ClearChangesMask(ObjectiveFlags); Base::ClearChangesMask(ObjectiveProgress); _changesMask.ResetAll(); @@ -2826,19 +2844,94 @@ bool SpellFlatModByLabel::operator==(SpellFlatModByLabel const& right) const && LabelID == right.LabelID; } -void Research::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const +void CompletedProject::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const { - data << int16(ResearchProjectID); + data << uint32(ProjectID); + data << int64(FirstCompleted); + data << uint32(CompletionCount); } -void Research::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const +void CompletedProject::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const { - data << int16(ResearchProjectID); + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 4); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << uint32(ProjectID); + } + if (changesMask[2]) + { + data << int64(FirstCompleted); + } + if (changesMask[3]) + { + data << uint32(CompletionCount); + } + } } -bool Research::operator==(Research const& right) const +void CompletedProject::ClearChangesMask() { - return ResearchProjectID == right.ResearchProjectID; + Base::ClearChangesMask(ProjectID); + Base::ClearChangesMask(FirstCompleted); + Base::ClearChangesMask(CompletionCount); + _changesMask.ResetAll(); +} + +void ResearchHistory::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const +{ + data << uint32(CompletedProjects.size()); + for (uint32 i = 0; i < CompletedProjects.size(); ++i) + { + CompletedProjects[i].WriteCreate(data, owner, receiver); + } +} + +void ResearchHistory::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const +{ + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 2); + + if (changesMask[0]) + { + if (changesMask[1]) + { + if (!ignoreChangesMask) + CompletedProjects.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(CompletedProjects.size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + for (uint32 i = 0; i < CompletedProjects.size(); ++i) + { + if (CompletedProjects.HasChanged(i) || ignoreChangesMask) + { + CompletedProjects[i].WriteUpdate(data, ignoreChangesMask, owner, receiver); + } + } + } + } +} + +void ResearchHistory::ClearChangesMask() +{ + Base::ClearChangesMask(CompletedProjects); + _changesMask.ResetAll(); } void MawPower::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const @@ -3188,6 +3281,7 @@ void CraftingOrderItem::WriteCreate(ByteBuffer& data, Player const* owner, Playe data << uint32(Quantity); data << int32(ReagentQuality); data.WriteBits(DataSlotIndex.has_value(), 1); + data.FlushBits(); if (DataSlotIndex.has_value()) { data << uint8(DataSlotIndex); @@ -3228,6 +3322,7 @@ void CraftingOrderItem::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Pl data << int32(ReagentQuality); } data.WriteBits(DataSlotIndex.has_value(), 1); + data.FlushBits(); if (changesMask[6]) { if (DataSlotIndex.has_value()) @@ -3270,6 +3365,7 @@ void CraftingOrderData::WriteCreate(ByteBuffer& data, Player const* owner, Playe data.WriteBits(CustomerNotes->size(), 10); data.WriteBits(OutputItem.has_value(), 1); data.WriteBits(OutputItemData.has_value(), 1); + data.FlushBits(); for (uint32 i = 0; i < Reagents.size(); ++i) { Reagents[i].WriteCreate(data, owner, receiver); @@ -3396,6 +3492,7 @@ void CraftingOrderData::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Pl } data.WriteBits(OutputItem.has_value(), 1); data.WriteBits(OutputItemData.has_value(), 1); + data.FlushBits(); if (changesMask[22]) { if (OutputItem.has_value()) @@ -3444,6 +3541,7 @@ void CraftingOrder::WriteCreate(ByteBuffer& data, Player const* owner, Player co data.WriteBits(RecraftItemInfo.has_value(), 1); data.WriteBits(Enchantments.size(), 4); data.WriteBits(Gems.size(), 2); + data.FlushBits(); if (RecraftItemInfo.has_value()) { data << RecraftItemInfo; @@ -3507,6 +3605,7 @@ void CraftingOrder::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player Data->WriteUpdate(data, ignoreChangesMask, owner, receiver); } data.WriteBits(RecraftItemInfo.has_value(), 1); + data.FlushBits(); if (changesMask[3]) { if (RecraftItemInfo.has_value()) @@ -3580,6 +3679,145 @@ bool WeeklySpellUse::operator==(WeeklySpellUse const& right) const && Uses == right.Uses; } +void StablePetInfo::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const +{ + data << uint32(PetSlot); + data << uint32(PetNumber); + data << uint32(CreatureID); + data << uint32(DisplayID); + data << uint32(ExperienceLevel); + data << uint8(PetFlags); + data.WriteBits(Name->size(), 8); + data.WriteString(Name); + data.FlushBits(); +} + +void StablePetInfo::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const +{ + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 8); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data << uint32(PetSlot); + } + if (changesMask[2]) + { + data << uint32(PetNumber); + } + if (changesMask[3]) + { + data << uint32(CreatureID); + } + if (changesMask[4]) + { + data << uint32(DisplayID); + } + if (changesMask[5]) + { + data << uint32(ExperienceLevel); + } + if (changesMask[7]) + { + data << uint8(PetFlags); + } + if (changesMask[6]) + { + data.WriteBits(Name->size(), 8); + data.WriteString(Name); + } + } + data.FlushBits(); +} + +void StablePetInfo::ClearChangesMask() +{ + Base::ClearChangesMask(PetSlot); + Base::ClearChangesMask(PetNumber); + Base::ClearChangesMask(CreatureID); + Base::ClearChangesMask(DisplayID); + Base::ClearChangesMask(ExperienceLevel); + Base::ClearChangesMask(Name); + Base::ClearChangesMask(PetFlags); + _changesMask.ResetAll(); +} + +void StableInfo::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const +{ + data << uint32(Pets.size()); + data << StableMaster; + for (uint32 i = 0; i < Pets.size(); ++i) + { + Pets[i].WriteCreate(data, owner, receiver); + } +} + +void StableInfo::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const +{ + Mask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 3); + + if (changesMask[0]) + { + if (changesMask[1]) + { + if (!ignoreChangesMask) + Pets.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Pets.size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + for (uint32 i = 0; i < Pets.size(); ++i) + { + if (Pets.HasChanged(i) || ignoreChangesMask) + { + Pets[i].WriteUpdate(data, ignoreChangesMask, owner, receiver); + } + } + } + if (changesMask[2]) + { + data << StableMaster; + } + } +} + +void StableInfo::ClearChangesMask() +{ + Base::ClearChangesMask(Pets); + Base::ClearChangesMask(StableMaster); + _changesMask.ResetAll(); +} + +void Research::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const +{ + data << int16(ResearchProjectID); +} + +void Research::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const +{ + data << int16(ResearchProjectID); +} + +bool Research::operator==(Research const& right) const +{ + return ResearchProjectID == right.ResearchProjectID; +} + void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const { for (uint32 i = 0; i < 227; ++i) @@ -3711,8 +3949,24 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f data << int32(HonorNextLevel); data << int32(PerksProgramCurrency); data << uint8(NumBankSlots); - data << uint32(ResearchSites.size()); - data << uint32(ResearchSiteProgress.size()); + for (uint32 i = 0; i < 1; ++i) + { + data << uint32(ResearchSites[i].size()); + data << uint32(ResearchSiteProgress[i].size()); + data << uint32(Research[i].size()); + for (uint32 j = 0; j < ResearchSites[i].size(); ++j) + { + data << uint16(ResearchSites[i][j]); + } + for (uint32 j = 0; j < ResearchSiteProgress[i].size(); ++j) + { + data << uint32(ResearchSiteProgress[i][j]); + } + for (uint32 j = 0; j < Research[i].size(); ++j) + { + Research[i][j].WriteCreate(data, owner, receiver); + } + } data << uint32(DailyQuestsCompleted.size()); data << uint32(AvailableQuestLineXQuestIDs.size()); data << uint32(Heirlooms.size()); @@ -3727,18 +3981,11 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f data << uint32(CharacterRestrictions.size()); data << uint32(SpellPctModByLabel.size()); data << uint32(SpellFlatModByLabel.size()); - for (uint32 i = 0; i < 1; ++i) - { - data << uint32(Research[i].size()); - for (uint32 j = 0; j < Research[i].size(); ++j) - { - Research[i][j].WriteCreate(data, owner, receiver); - } - } data << uint32(MawPowers.size()); data << uint32(MultiFloorExploration.size()); data << uint32(RecipeProgression.size()); data << uint32(ReplayedQuests.size()); + data << uint32(TaskQuests.size()); data << uint32(DisabledSpells.size()); data << int32(UiChromieTimeExpansionID); data << int32(TransportServerTime); @@ -3754,19 +4001,18 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f { data << float(ItemUpgradeHighWatermark[i]); } + data << int32(ItemUpgradeHighOnehandWeaponItemID); + data << int32(ItemUpgradeHighFingerItemID); + data << float(ItemUpgradeHighFingerWatermark); + data << int32(ItemUpgradeHighTrinketItemID); + data << float(ItemUpgradeHighTrinketWatermark); data << uint64(LootHistoryInstanceID); + data << uint32(TrackedCollectableSources.size()); + data << uint8(RequiredMountCapabilityFlags); for (uint32 i = 0; i < KnownTitles.size(); ++i) { data << uint64(KnownTitles[i]); } - for (uint32 i = 0; i < ResearchSites.size(); ++i) - { - data << uint16(ResearchSites[i]); - } - for (uint32 i = 0; i < ResearchSiteProgress.size(); ++i) - { - data << uint32(ResearchSiteProgress[i]); - } for (uint32 i = 0; i < DailyQuestsCompleted.size(); ++i) { data << int32(DailyQuestsCompleted[i]); @@ -3835,6 +4081,10 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f { ReplayedQuests[i].WriteCreate(data, owner, receiver); } + for (uint32 i = 0; i < TaskQuests.size(); ++i) + { + TaskQuests[i].WriteCreate(data, owner, receiver); + } for (uint32 i = 0; i < DisabledSpells.size(); ++i) { data << int32(DisabledSpells[i]); @@ -3851,6 +4101,10 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f { WeeklySpellUses[i].WriteCreate(data, owner, receiver); } + for (uint32 i = 0; i < TrackedCollectableSources.size(); ++i) + { + data << int64(TrackedCollectableSources[i]); + } data.FlushBits(); data.WriteBit(BackpackAutoSortDisabled); data.WriteBit(BankAutoSortDisabled); @@ -3858,11 +4112,14 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f data.WriteBit(InsertItemsLeftToRight); data.WriteBit(HasPerksProgramPendingReward); data.WriteBits(QuestSession.has_value(), 1); - data << FrozenPerksVendorItem; + data.WriteBits(PetStable.has_value(), 1); + data.FlushBits(); + ResearchHistory->WriteCreate(data, owner, receiver); if (QuestSession.has_value()) { QuestSession->WriteCreate(data, owner, receiver); } + data << FrozenPerksVendorItem; Field_1410->WriteCreate(data, owner, receiver); data << DungeonScore; for (uint32 i = 0; i < PvpInfo.size(); ++i) @@ -3881,6 +4138,10 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> f { CraftingOrders[i].WriteCreate(data, owner, receiver); } + if (PetStable.has_value()) + { + PetStable->WriteCreate(data, owner, receiver); + } data.FlushBits(); } @@ -3934,214 +4195,281 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo else WriteCompleteDynamicFieldUpdateMask(PvpInfo.size(), data); } - if (changesMask[8]) + } + if (changesMask[35]) + { + for (uint32 i = 0; i < 1; ++i) { - if (!ignoreNestedChangesMask) - ResearchSites.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(ResearchSites.size(), data); + if (changesMask[36 + i]) + { + if (!ignoreNestedChangesMask) + ResearchSites[i].WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ResearchSites[i].size(), data); + } } - if (changesMask[9]) + } + if (changesMask[37]) + { + for (uint32 i = 0; i < 1; ++i) { - if (!ignoreNestedChangesMask) - ResearchSiteProgress.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(ResearchSiteProgress.size(), data); + if (changesMask[38 + i]) + { + if (!ignoreNestedChangesMask) + ResearchSiteProgress[i].WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ResearchSiteProgress[i].size(), data); + } } - if (changesMask[10]) + } + if (changesMask[39]) + { + for (uint32 i = 0; i < 1; ++i) + { + if (changesMask[40 + i]) + { + if (!ignoreNestedChangesMask) + Research[i].WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Research[i].size(), data); + } + } + } + if (changesMask[35]) + { + for (uint32 i = 0; i < 1; ++i) + { + if (changesMask[36 + i]) + { + for (uint32 j = 0; j < ResearchSites[i].size(); ++j) + { + if (ResearchSites[i].HasChanged(j) || ignoreNestedChangesMask) + { + data << uint16(ResearchSites[i][j]); + } + } + } + } + } + if (changesMask[37]) + { + for (uint32 i = 0; i < 1; ++i) + { + if (changesMask[38 + i]) + { + for (uint32 j = 0; j < ResearchSiteProgress[i].size(); ++j) + { + if (ResearchSiteProgress[i].HasChanged(j) || ignoreNestedChangesMask) + { + data << uint32(ResearchSiteProgress[i][j]); + } + } + } + } + } + if (changesMask[39]) + { + for (uint32 i = 0; i < 1; ++i) + { + if (changesMask[40 + i]) + { + for (uint32 j = 0; j < Research[i].size(); ++j) + { + if (Research[i].HasChanged(j) || ignoreNestedChangesMask) + { + Research[i][j].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + } + } + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[8]) { if (!ignoreNestedChangesMask) DailyQuestsCompleted.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(DailyQuestsCompleted.size(), data); } - if (changesMask[11]) + if (changesMask[9]) { if (!ignoreNestedChangesMask) AvailableQuestLineXQuestIDs.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(AvailableQuestLineXQuestIDs.size(), data); } - if (changesMask[12]) + if (changesMask[10]) { if (!ignoreNestedChangesMask) Heirlooms.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(Heirlooms.size(), data); } - if (changesMask[13]) + if (changesMask[11]) { if (!ignoreNestedChangesMask) HeirloomFlags.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(HeirloomFlags.size(), data); } - if (changesMask[14]) + if (changesMask[12]) { if (!ignoreNestedChangesMask) Toys.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(Toys.size(), data); } - if (changesMask[15]) + if (changesMask[13]) { if (!ignoreNestedChangesMask) ToyFlags.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(ToyFlags.size(), data); } - if (changesMask[16]) + if (changesMask[14]) { if (!ignoreNestedChangesMask) Transmog.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(Transmog.size(), data); } - if (changesMask[17]) + if (changesMask[15]) { if (!ignoreNestedChangesMask) ConditionalTransmog.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(ConditionalTransmog.size(), data); } - if (changesMask[18]) + if (changesMask[16]) { if (!ignoreNestedChangesMask) SelfResSpells.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(SelfResSpells.size(), data); } - if (changesMask[19]) + if (changesMask[17]) { if (!ignoreNestedChangesMask) RuneforgePowers.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(RuneforgePowers.size(), data); } - if (changesMask[20]) + if (changesMask[18]) { if (!ignoreNestedChangesMask) TransmogIllusions.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(TransmogIllusions.size(), data); } - if (changesMask[21]) + if (changesMask[19]) { if (!ignoreNestedChangesMask) CharacterRestrictions.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(CharacterRestrictions.size(), data); } - if (changesMask[22]) + if (changesMask[20]) { if (!ignoreNestedChangesMask) SpellPctModByLabel.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(SpellPctModByLabel.size(), data); } - if (changesMask[23]) + if (changesMask[21]) { if (!ignoreNestedChangesMask) SpellFlatModByLabel.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(SpellFlatModByLabel.size(), data); } - } - if (changesMask[35]) - { - for (uint32 i = 0; i < 1; ++i) - { - if (changesMask[36 + i]) - { - if (!ignoreNestedChangesMask) - Research[i].WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Research[i].size(), data); - for (uint32 j = 0; j < Research[i].size(); ++j) - { - if (Research[i].HasChanged(j) || ignoreNestedChangesMask) - { - Research[i][j].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); - } - } - } - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[24]) + if (changesMask[22]) { if (!ignoreNestedChangesMask) MawPowers.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(MawPowers.size(), data); } - if (changesMask[25]) + if (changesMask[23]) { if (!ignoreNestedChangesMask) MultiFloorExploration.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(MultiFloorExploration.size(), data); } - if (changesMask[26]) + if (changesMask[24]) { if (!ignoreNestedChangesMask) RecipeProgression.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(RecipeProgression.size(), data); } - if (changesMask[27]) + if (changesMask[25]) { if (!ignoreNestedChangesMask) ReplayedQuests.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(ReplayedQuests.size(), data); } - if (changesMask[28]) + if (changesMask[26]) + { + if (!ignoreNestedChangesMask) + TaskQuests.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(TaskQuests.size(), data); + } + if (changesMask[27]) { if (!ignoreNestedChangesMask) DisabledSpells.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(DisabledSpells.size(), data); } - if (changesMask[29]) + if (changesMask[28]) { if (!ignoreNestedChangesMask) TraitConfigs.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(TraitConfigs.size(), data); } - if (changesMask[30]) + if (changesMask[29]) { if (!ignoreNestedChangesMask) CraftingOrders.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(CraftingOrders.size(), data); } - if (changesMask[31]) + if (changesMask[30]) { if (!ignoreNestedChangesMask) PersonalCraftingOrderCounts.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(PersonalCraftingOrderCounts.size(), data); } + if (changesMask[31]) + { + if (!ignoreNestedChangesMask) + CategoryCooldownMods.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(CategoryCooldownMods.size(), data); + } } if (changesMask[32]) { if (changesMask[33]) { if (!ignoreNestedChangesMask) - CategoryCooldownMods.WriteUpdateMask(data); + WeeklySpellUses.WriteUpdateMask(data); else - WriteCompleteDynamicFieldUpdateMask(CategoryCooldownMods.size(), data); + WriteCompleteDynamicFieldUpdateMask(WeeklySpellUses.size(), data); } if (changesMask[34]) { if (!ignoreNestedChangesMask) - WeeklySpellUses.WriteUpdateMask(data); + TrackedCollectableSources.WriteUpdateMask(data); else - WriteCompleteDynamicFieldUpdateMask(WeeklySpellUses.size(), data); + WriteCompleteDynamicFieldUpdateMask(TrackedCollectableSources.size(), data); } } data.FlushBits(); @@ -4159,26 +4487,6 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } if (changesMask[8]) { - for (uint32 i = 0; i < ResearchSites.size(); ++i) - { - if (ResearchSites.HasChanged(i) || ignoreNestedChangesMask) - { - data << uint16(ResearchSites[i]); - } - } - } - if (changesMask[9]) - { - for (uint32 i = 0; i < ResearchSiteProgress.size(); ++i) - { - if (ResearchSiteProgress.HasChanged(i) || ignoreNestedChangesMask) - { - data << uint32(ResearchSiteProgress[i]); - } - } - } - if (changesMask[10]) - { for (uint32 i = 0; i < DailyQuestsCompleted.size(); ++i) { if (DailyQuestsCompleted.HasChanged(i) || ignoreNestedChangesMask) @@ -4187,7 +4495,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[11]) + if (changesMask[9]) { for (uint32 i = 0; i < AvailableQuestLineXQuestIDs.size(); ++i) { @@ -4197,7 +4505,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[12]) + if (changesMask[10]) { for (uint32 i = 0; i < Heirlooms.size(); ++i) { @@ -4207,7 +4515,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[13]) + if (changesMask[11]) { for (uint32 i = 0; i < HeirloomFlags.size(); ++i) { @@ -4217,7 +4525,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[14]) + if (changesMask[12]) { for (uint32 i = 0; i < Toys.size(); ++i) { @@ -4227,7 +4535,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[15]) + if (changesMask[13]) { for (uint32 i = 0; i < ToyFlags.size(); ++i) { @@ -4237,7 +4545,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[16]) + if (changesMask[14]) { for (uint32 i = 0; i < Transmog.size(); ++i) { @@ -4247,7 +4555,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[17]) + if (changesMask[15]) { for (uint32 i = 0; i < ConditionalTransmog.size(); ++i) { @@ -4257,7 +4565,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[18]) + if (changesMask[16]) { for (uint32 i = 0; i < SelfResSpells.size(); ++i) { @@ -4267,7 +4575,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[19]) + if (changesMask[17]) { for (uint32 i = 0; i < RuneforgePowers.size(); ++i) { @@ -4277,7 +4585,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[20]) + if (changesMask[18]) { for (uint32 i = 0; i < TransmogIllusions.size(); ++i) { @@ -4287,7 +4595,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[22]) + if (changesMask[20]) { for (uint32 i = 0; i < SpellPctModByLabel.size(); ++i) { @@ -4297,7 +4605,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[23]) + if (changesMask[21]) { for (uint32 i = 0; i < SpellFlatModByLabel.size(); ++i) { @@ -4307,7 +4615,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[24]) + if (changesMask[22]) { for (uint32 i = 0; i < MawPowers.size(); ++i) { @@ -4317,7 +4625,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[25]) + if (changesMask[23]) { for (uint32 i = 0; i < MultiFloorExploration.size(); ++i) { @@ -4327,7 +4635,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[26]) + if (changesMask[24]) { for (uint32 i = 0; i < RecipeProgression.size(); ++i) { @@ -4337,7 +4645,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[27]) + if (changesMask[25]) { for (uint32 i = 0; i < ReplayedQuests.size(); ++i) { @@ -4347,7 +4655,17 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[28]) + if (changesMask[26]) + { + for (uint32 i = 0; i < TaskQuests.size(); ++i) + { + if (TaskQuests.HasChanged(i) || ignoreNestedChangesMask) + { + TaskQuests[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + } + } + if (changesMask[27]) { for (uint32 i = 0; i < DisabledSpells.size(); ++i) { @@ -4357,7 +4675,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[31]) + if (changesMask[30]) { for (uint32 i = 0; i < PersonalCraftingOrderCounts.size(); ++i) { @@ -4367,10 +4685,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - } - if (changesMask[32]) - { - if (changesMask[33]) + if (changesMask[31]) { for (uint32 i = 0; i < CategoryCooldownMods.size(); ++i) { @@ -4380,7 +4695,10 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[34]) + } + if (changesMask[32]) + { + if (changesMask[33]) { for (uint32 i = 0; i < WeeklySpellUses.size(); ++i) { @@ -4390,6 +4708,16 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } + if (changesMask[34]) + { + for (uint32 i = 0; i < TrackedCollectableSources.size(); ++i) + { + if (TrackedCollectableSources.HasChanged(i) || ignoreNestedChangesMask) + { + data << int64(TrackedCollectableSources[i]); + } + } + } } if (changesMask[0]) { @@ -4403,7 +4731,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[21]) + if (changesMask[19]) { for (uint32 i = 0; i < CharacterRestrictions.size(); ++i) { @@ -4413,7 +4741,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[29]) + if (changesMask[28]) { for (uint32 i = 0; i < TraitConfigs.size(); ++i) { @@ -4423,7 +4751,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } } } - if (changesMask[30]) + if (changesMask[29]) { for (uint32 i = 0; i < CraftingOrders.size(); ++i) { @@ -4436,501 +4764,541 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bo } if (changesMask[32]) { - if (changesMask[37]) + if (changesMask[41]) { data << FarsightObject; } - if (changesMask[38]) + if (changesMask[42]) { data << SummonedBattlePetGUID; } - if (changesMask[39]) + if (changesMask[43]) { data << uint64(Coinage); } - if (changesMask[40]) + if (changesMask[44]) { data << int32(XP); } - if (changesMask[41]) + if (changesMask[45]) { data << int32(NextLevelXP); } - if (changesMask[42]) + if (changesMask[46]) { data << int32(TrialXP); } - if (changesMask[43]) + if (changesMask[47]) { Skill->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } - if (changesMask[44]) + if (changesMask[48]) { data << int32(CharacterPoints); } - if (changesMask[45]) + if (changesMask[49]) { data << int32(MaxTalentTiers); } - if (changesMask[46]) + if (changesMask[50]) { data << uint32(TrackCreatureMask); } - if (changesMask[47]) + if (changesMask[51]) { data << float(MainhandExpertise); } - if (changesMask[48]) + if (changesMask[52]) { data << float(OffhandExpertise); } - if (changesMask[49]) + if (changesMask[53]) { data << float(RangedExpertise); } - if (changesMask[50]) + if (changesMask[54]) { data << float(CombatRatingExpertise); } - if (changesMask[51]) + if (changesMask[55]) { data << float(BlockPercentage); } - if (changesMask[52]) + if (changesMask[56]) { data << float(DodgePercentage); } - if (changesMask[53]) + if (changesMask[57]) { data << float(DodgePercentageFromAttribute); } - if (changesMask[54]) + if (changesMask[58]) { data << float(ParryPercentage); } - if (changesMask[55]) + if (changesMask[59]) { data << float(ParryPercentageFromAttribute); } - if (changesMask[56]) + if (changesMask[60]) { data << float(CritPercentage); } - if (changesMask[57]) + if (changesMask[61]) { data << float(RangedCritPercentage); } - if (changesMask[58]) + if (changesMask[62]) { data << float(OffhandCritPercentage); } - if (changesMask[59]) + if (changesMask[63]) { data << float(SpellCritPercentage); } - if (changesMask[60]) + if (changesMask[64]) { data << int32(ShieldBlock); } - if (changesMask[61]) + if (changesMask[65]) { data << float(ShieldBlockCritPercentage); } - if (changesMask[62]) + if (changesMask[66]) { data << float(Mastery); } - if (changesMask[63]) + if (changesMask[67]) { data << float(Speed); } - if (changesMask[64]) + if (changesMask[68]) { data << float(Avoidance); } - if (changesMask[65]) + if (changesMask[69]) { data << float(Sturdiness); } } - if (changesMask[66]) + if (changesMask[70]) { - if (changesMask[67]) + if (changesMask[71]) { data << int32(Versatility); } - if (changesMask[68]) + if (changesMask[72]) { data << float(VersatilityBonus); } - if (changesMask[69]) + if (changesMask[73]) { data << float(PvpPowerDamage); } - if (changesMask[70]) + if (changesMask[74]) { data << float(PvpPowerHealing); } - if (changesMask[71]) + if (changesMask[75]) { data << int32(ModHealingDonePos); } - if (changesMask[72]) + if (changesMask[76]) { data << float(ModHealingPercent); } - if (changesMask[73]) + if (changesMask[77]) { data << float(ModPeriodicHealingDonePercent); } - if (changesMask[74]) + if (changesMask[78]) { data << float(ModSpellPowerPercent); } - if (changesMask[75]) + if (changesMask[79]) { data << float(ModResiliencePercent); } - if (changesMask[76]) + if (changesMask[80]) { data << float(OverrideSpellPowerByAPPercent); } - if (changesMask[77]) + if (changesMask[81]) { data << float(OverrideAPBySpellPowerPercent); } - if (changesMask[78]) + if (changesMask[82]) { data << int32(ModTargetResistance); } - if (changesMask[79]) + if (changesMask[83]) { data << int32(ModTargetPhysicalResistance); } - if (changesMask[80]) + if (changesMask[84]) { data << uint32(LocalFlags); } - if (changesMask[81]) + if (changesMask[85]) { data << uint8(GrantableLevels); } - if (changesMask[82]) + if (changesMask[86]) { data << uint8(MultiActionBars); } - if (changesMask[83]) + if (changesMask[87]) { data << uint8(LifetimeMaxRank); } - if (changesMask[84]) + if (changesMask[88]) { data << uint8(NumRespecs); } - if (changesMask[85]) + if (changesMask[89]) { data << uint32(PvpMedals); } - if (changesMask[86]) + if (changesMask[90]) { data << uint16(TodayHonorableKills); } - if (changesMask[87]) + if (changesMask[91]) { data << uint16(YesterdayHonorableKills); } - if (changesMask[88]) + if (changesMask[92]) { data << uint32(LifetimeHonorableKills); } - if (changesMask[89]) + if (changesMask[93]) { data << int32(WatchedFactionIndex); } - if (changesMask[90]) + if (changesMask[94]) { data << int32(MaxLevel); } - if (changesMask[91]) + if (changesMask[95]) { data << int32(ScalingPlayerLevelDelta); } - if (changesMask[92]) + if (changesMask[96]) { data << int32(MaxCreatureScalingLevel); } - if (changesMask[93]) + if (changesMask[97]) { data << int32(PetSpellPower); } - if (changesMask[94]) + if (changesMask[98]) { data << float(UiHitModifier); } - if (changesMask[95]) + if (changesMask[99]) { data << float(UiSpellHitModifier); } - if (changesMask[96]) + if (changesMask[100]) { data << int32(HomeRealmTimeOffset); } - if (changesMask[97]) + if (changesMask[101]) { data << float(ModPetHaste); } } - if (changesMask[98]) + if (changesMask[102]) { - if (changesMask[99]) + if (changesMask[103]) { data << int8(JailersTowerLevelMax); } - if (changesMask[100]) + if (changesMask[104]) { data << int8(JailersTowerLevel); } - if (changesMask[101]) + if (changesMask[105]) { data << uint8(LocalRegenFlags); } - if (changesMask[102]) + if (changesMask[106]) { data << uint8(AuraVision); } - if (changesMask[103]) + if (changesMask[107]) { data << uint8(NumBackpackSlots); } - if (changesMask[104]) + if (changesMask[108]) { data << int32(OverrideSpellsID); } - if (changesMask[105]) + if (changesMask[109]) { data << uint16(LootSpecID); } - if (changesMask[106]) + if (changesMask[110]) { data << uint32(OverrideZonePVPType); } - if (changesMask[107]) + if (changesMask[111]) { data << BnetAccount; } - if (changesMask[108]) + if (changesMask[112]) { data << uint64(GuildClubMemberID); } - if (changesMask[109]) + if (changesMask[113]) { data << int32(Honor); } - if (changesMask[110]) + if (changesMask[114]) { data << int32(HonorNextLevel); } - if (changesMask[111]) + if (changesMask[115]) { data << int32(PerksProgramCurrency); } - if (changesMask[112]) + if (changesMask[116]) { data << uint8(NumBankSlots); } - if (changesMask[116]) + if (changesMask[121]) { data << int32(UiChromieTimeExpansionID); } - if (changesMask[117]) + if (changesMask[122]) { data << int32(TransportServerTime); } - if (changesMask[118]) + if (changesMask[123]) { data << uint32(WeeklyRewardsPeriodSinceOrigin); } - if (changesMask[119]) + if (changesMask[124]) { data << int16(DEBUGSoulbindConduitRank); } - if (changesMask[121]) + if (changesMask[126]) { data << uint32(ActiveCombatTraitConfigID); } - if (changesMask[122]) + if (changesMask[127]) + { + data << int32(ItemUpgradeHighOnehandWeaponItemID); + } + if (changesMask[128]) + { + data << int32(ItemUpgradeHighFingerItemID); + } + if (changesMask[129]) + { + data << float(ItemUpgradeHighFingerWatermark); + } + if (changesMask[130]) + { + data << int32(ItemUpgradeHighTrinketItemID); + } + if (changesMask[131]) + { + data << float(ItemUpgradeHighTrinketWatermark); + } + if (changesMask[132]) { data << uint64(LootHistoryInstanceID); } } - if (changesMask[98]) + if (changesMask[134]) + { + if (changesMask[135]) + { + data << uint8(RequiredMountCapabilityFlags); + } + } + if (changesMask[102]) { data.WriteBits(QuestSession.has_value(), 1); - if (changesMask[113]) + data.WriteBits(PetStable.has_value(), 1); + data.FlushBits(); + if (changesMask[117]) { - data << FrozenPerksVendorItem; + ResearchHistory->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } - if (changesMask[114]) + if (changesMask[119]) { if (QuestSession.has_value()) { QuestSession->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } - if (changesMask[115]) + if (changesMask[118]) { - Field_1410->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + data << FrozenPerksVendorItem; } if (changesMask[120]) { + Field_1410->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + if (changesMask[125]) + { data << DungeonScore; } + if (changesMask[133]) + { + if (PetStable.has_value()) + { + PetStable->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + } } - if (changesMask[123]) + if (changesMask[136]) { for (uint32 i = 0; i < 227; ++i) { - if (changesMask[124 + i]) + if (changesMask[137 + i]) { data << InvSlots[i]; } } } - if (changesMask[351]) + if (changesMask[364]) { for (uint32 i = 0; i < 240; ++i) { - if (changesMask[352 + i]) + if (changesMask[365 + i]) { data << uint64(ExploredZones[i]); } } } - if (changesMask[592]) + if (changesMask[605]) { for (uint32 i = 0; i < 2; ++i) { - if (changesMask[593 + i]) + if (changesMask[606 + i]) { RestInfo[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } - if (changesMask[595]) + if (changesMask[608]) { for (uint32 i = 0; i < 7; ++i) { - if (changesMask[596 + i]) + if (changesMask[609 + i]) { data << int32(ModDamageDonePos[i]); } - if (changesMask[603 + i]) + if (changesMask[616 + i]) { data << int32(ModDamageDoneNeg[i]); } - if (changesMask[610 + i]) + if (changesMask[623 + i]) { data << float(ModDamageDonePercent[i]); } - if (changesMask[617 + i]) + if (changesMask[630 + i]) { data << float(ModHealingDonePercent[i]); } } } - if (changesMask[624]) + if (changesMask[637]) { for (uint32 i = 0; i < 3; ++i) { - if (changesMask[625 + i]) + if (changesMask[638 + i]) { data << float(WeaponDmgMultipliers[i]); } - if (changesMask[628 + i]) + if (changesMask[641 + i]) { data << float(WeaponAtkSpeedMultipliers[i]); } } } - if (changesMask[631]) + if (changesMask[644]) { for (uint32 i = 0; i < 12; ++i) { - if (changesMask[632 + i]) + if (changesMask[645 + i]) { data << uint32(BuybackPrice[i]); } - if (changesMask[644 + i]) + if (changesMask[657 + i]) { data << int64(BuybackTimestamp[i]); } } } - if (changesMask[656]) + if (changesMask[669]) { for (uint32 i = 0; i < 32; ++i) { - if (changesMask[657 + i]) + if (changesMask[670 + i]) { data << int32(CombatRatings[i]); } } } - if (changesMask[689]) + if (changesMask[702]) { for (uint32 i = 0; i < 4; ++i) { - if (changesMask[690 + i]) + if (changesMask[703 + i]) { data << uint32(NoReagentCostMask[i]); } } } - if (changesMask[694]) + if (changesMask[707]) { for (uint32 i = 0; i < 2; ++i) { - if (changesMask[695 + i]) + if (changesMask[708 + i]) { data << int32(ProfessionSkillLine[i]); } } } - if (changesMask[697]) + if (changesMask[710]) { for (uint32 i = 0; i < 5; ++i) { - if (changesMask[698 + i]) + if (changesMask[711 + i]) { data << uint32(BagSlotFlags[i]); } } } - if (changesMask[703]) + if (changesMask[716]) { for (uint32 i = 0; i < 7; ++i) { - if (changesMask[704 + i]) + if (changesMask[717 + i]) { data << uint32(BankBagSlotFlags[i]); } } } - if (changesMask[711]) + if (changesMask[724]) { for (uint32 i = 0; i < 875; ++i) { - if (changesMask[712 + i]) + if (changesMask[725 + i]) { data << uint64(QuestCompleted[i]); } } } - if (changesMask[1587]) + if (changesMask[1600]) { for (uint32 i = 0; i < 17; ++i) { - if (changesMask[1588 + i]) + if (changesMask[1601 + i]) { data << float(ItemUpgradeHighWatermark[i]); } @@ -4946,10 +5314,10 @@ void ActivePlayerData::ClearChangesMask() Base::ClearChangesMask(SortBagsRightToLeft); Base::ClearChangesMask(InsertItemsLeftToRight); Base::ClearChangesMask(HasPerksProgramPendingReward); - Base::ClearChangesMask(Research); - Base::ClearChangesMask(KnownTitles); Base::ClearChangesMask(ResearchSites); Base::ClearChangesMask(ResearchSiteProgress); + Base::ClearChangesMask(Research); + Base::ClearChangesMask(KnownTitles); Base::ClearChangesMask(DailyQuestsCompleted); Base::ClearChangesMask(AvailableQuestLineXQuestIDs); Base::ClearChangesMask(Heirlooms); @@ -4967,10 +5335,12 @@ void ActivePlayerData::ClearChangesMask() Base::ClearChangesMask(MultiFloorExploration); Base::ClearChangesMask(RecipeProgression); Base::ClearChangesMask(ReplayedQuests); + Base::ClearChangesMask(TaskQuests); Base::ClearChangesMask(DisabledSpells); Base::ClearChangesMask(PersonalCraftingOrderCounts); Base::ClearChangesMask(CategoryCooldownMods); Base::ClearChangesMask(WeeklySpellUses); + Base::ClearChangesMask(TrackedCollectableSources); Base::ClearChangesMask(PvpInfo); Base::ClearChangesMask(CharacterRestrictions); Base::ClearChangesMask(TraitConfigs); @@ -5049,6 +5419,7 @@ void ActivePlayerData::ClearChangesMask() Base::ClearChangesMask(HonorNextLevel); Base::ClearChangesMask(PerksProgramCurrency); Base::ClearChangesMask(NumBankSlots); + Base::ClearChangesMask(ResearchHistory); Base::ClearChangesMask(FrozenPerksVendorItem); Base::ClearChangesMask(Field_1410); Base::ClearChangesMask(QuestSession); @@ -5058,7 +5429,14 @@ void ActivePlayerData::ClearChangesMask() Base::ClearChangesMask(DEBUGSoulbindConduitRank); Base::ClearChangesMask(DungeonScore); Base::ClearChangesMask(ActiveCombatTraitConfigID); + Base::ClearChangesMask(ItemUpgradeHighOnehandWeaponItemID); + Base::ClearChangesMask(ItemUpgradeHighFingerItemID); + Base::ClearChangesMask(ItemUpgradeHighFingerWatermark); + Base::ClearChangesMask(ItemUpgradeHighTrinketItemID); + Base::ClearChangesMask(ItemUpgradeHighTrinketWatermark); Base::ClearChangesMask(LootHistoryInstanceID); + Base::ClearChangesMask(PetStable); + Base::ClearChangesMask(RequiredMountCapabilityFlags); Base::ClearChangesMask(InvSlots); Base::ClearChangesMask(ExploredZones); Base::ClearChangesMask(RestInfo); @@ -5618,26 +5996,27 @@ void AreaTriggerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fi data << uint32(TimeToTarget); data << uint32(TimeToTargetScale); data << uint32(TimeToTargetExtraScale); - data << uint32(Field_B0); + data << uint32(TimeToTargetPos); data << int32(SpellID); data << int32(SpellForVisuals); SpellVisual->WriteCreate(data, owner, receiver); data << float(BoundsRadius2D); data << uint32(DecalPropertiesID); data << CreatingEffectGUID; - data << uint32(Field_80); - data << uint32(Field_84); - data << Field_88; - data << Field_F8; + data << uint32(NumUnitsInside); + data << uint32(NumPlayersInside); + data << OrbitPathTarget; + data << RollPitchYaw; + data << int32(PositionalSoundKitID); ExtraScaleCurve->WriteCreate(data, owner, receiver); - data.WriteBit(Field_260); + data.FlushBits(); + data.WriteBit(HeightIgnoresScale); data.WriteBit(Field_261); - Field_C38->WriteCreate(data, owner, receiver); - Field_C54->WriteCreate(data, owner, receiver); - Field_C70->WriteCreate(data, owner, receiver); + OverrideMoveCurveX->WriteCreate(data, owner, receiver); + OverrideMoveCurveY->WriteCreate(data, owner, receiver); + OverrideMoveCurveZ->WriteCreate(data, owner, receiver); VisualAnim->WriteCreate(data, owner, receiver); data.FlushBits(); - data.FlushBits(); } void AreaTriggerData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, AreaTrigger const* owner, Player const* receiver) const @@ -5647,13 +6026,13 @@ 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), 25); + data.WriteBits(changesMask.GetBlock(0), 26); if (changesMask[0]) { if (changesMask[1]) { - data.WriteBit(Field_260); + data.WriteBit(HeightIgnoresScale); } if (changesMask[2]) { @@ -5689,7 +6068,7 @@ void AreaTriggerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, boo } if (changesMask[13]) { - data << uint32(Field_B0); + data << uint32(TimeToTargetPos); } if (changesMask[14]) { @@ -5717,19 +6096,23 @@ void AreaTriggerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, boo } if (changesMask[20]) { - data << uint32(Field_80); + data << uint32(NumUnitsInside); } if (changesMask[21]) { - data << uint32(Field_84); + data << uint32(NumPlayersInside); } if (changesMask[22]) { - data << Field_88; + data << OrbitPathTarget; } if (changesMask[23]) { - data << Field_F8; + data << RollPitchYaw; + } + if (changesMask[24]) + { + data << int32(PositionalSoundKitID); } if (changesMask[4]) { @@ -5737,17 +6120,17 @@ void AreaTriggerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, boo } if (changesMask[5]) { - Field_C38->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + OverrideMoveCurveX->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } if (changesMask[6]) { - Field_C54->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + OverrideMoveCurveY->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } if (changesMask[7]) { - Field_C70->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + OverrideMoveCurveZ->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } - if (changesMask[24]) + if (changesMask[25]) { VisualAnim->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } @@ -5757,29 +6140,30 @@ void AreaTriggerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, boo void AreaTriggerData::ClearChangesMask() { - Base::ClearChangesMask(Field_260); + Base::ClearChangesMask(HeightIgnoresScale); Base::ClearChangesMask(Field_261); Base::ClearChangesMask(OverrideScaleCurve); Base::ClearChangesMask(ExtraScaleCurve); - Base::ClearChangesMask(Field_C38); - Base::ClearChangesMask(Field_C54); - Base::ClearChangesMask(Field_C70); + Base::ClearChangesMask(OverrideMoveCurveX); + Base::ClearChangesMask(OverrideMoveCurveY); + Base::ClearChangesMask(OverrideMoveCurveZ); Base::ClearChangesMask(Caster); Base::ClearChangesMask(Duration); Base::ClearChangesMask(TimeToTarget); Base::ClearChangesMask(TimeToTargetScale); Base::ClearChangesMask(TimeToTargetExtraScale); - Base::ClearChangesMask(Field_B0); + Base::ClearChangesMask(TimeToTargetPos); Base::ClearChangesMask(SpellID); Base::ClearChangesMask(SpellForVisuals); Base::ClearChangesMask(SpellVisual); Base::ClearChangesMask(BoundsRadius2D); Base::ClearChangesMask(DecalPropertiesID); Base::ClearChangesMask(CreatingEffectGUID); - Base::ClearChangesMask(Field_80); - Base::ClearChangesMask(Field_84); - Base::ClearChangesMask(Field_88); - Base::ClearChangesMask(Field_F8); + Base::ClearChangesMask(NumUnitsInside); + Base::ClearChangesMask(NumPlayersInside); + Base::ClearChangesMask(OrbitPathTarget); + Base::ClearChangesMask(RollPitchYaw); + Base::ClearChangesMask(PositionalSoundKitID); 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 9af78fef00f..9d9c3df590f 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFields.h +++ b/src/server/game/Entities/Object/Updates/UpdateFields.h @@ -85,7 +85,7 @@ struct ItemMod : public IsUpdateFieldStructureTag struct ItemModList : public IsUpdateFieldStructureTag, public HasChangesMask<1> { - DynamicUpdateField<UF::ItemMod, 0, 0> Values; + DynamicUpdateField<UF::ItemMod, -1, 0> Values; void WriteCreate(ByteBuffer& data, Item const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Item const* owner, Player const* receiver) const; @@ -256,7 +256,7 @@ struct PassiveSpellHistory : public IsUpdateFieldStructureTag bool operator!=(PassiveSpellHistory const& right) const { return !(*this == right); } }; -struct UnitData : public IsUpdateFieldStructureTag, public HasChangesMask<209> +struct UnitData : public IsUpdateFieldStructureTag, public HasChangesMask<217> { UpdateField<std::vector<uint32>, 0, 1> StateWorldEffectIDs; DynamicUpdateField<UF::PassiveSpellHistory, 0, 2> PassiveSpells; @@ -351,52 +351,57 @@ struct UnitData : public IsUpdateFieldStructureTag, public HasChangesMask<209> 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> PerksVendorItemID; - UpdateField<int32, 96, 118> TaxiNodesID; - UpdateField<ObjectGuid, 96, 119> GuildGUID; - UpdateField<int32, 96, 120> FlightCapabilityID; - UpdateField<uint32, 96, 121> SilencedSchoolMask; - UpdateField<ObjectGuid, 96, 122> NameplateAttachToGUID; // When set, nameplate of this unit will instead appear on that object - UpdateFieldArray<uint32, 2, 123, 124> NpcFlags; + UpdateField<int32, 64, 90> AttackPowerModSupport; + UpdateField<int32, 64, 91> RangedAttackPower; + UpdateField<int32, 64, 92> RangedAttackPowerModPos; + UpdateField<int32, 64, 93> RangedAttackPowerModNeg; + UpdateField<float, 64, 94> RangedAttackPowerMultiplier; + UpdateField<int32, 64, 95> RangedAttackPowerModSupport; + UpdateField<int32, 96, 97> MainHandWeaponAttackPower; + UpdateField<int32, 96, 98> OffHandWeaponAttackPower; + UpdateField<int32, 96, 99> RangedWeaponAttackPower; + UpdateField<int32, 96, 100> SetAttackSpeedAura; + UpdateField<float, 96, 101> Lifesteal; + UpdateField<float, 96, 102> MinRangedDamage; + UpdateField<float, 96, 103> MaxRangedDamage; + UpdateField<float, 96, 104> ManaCostMultiplier; + UpdateField<float, 96, 105> MaxHealthModifier; + UpdateField<float, 96, 106> HoverHeight; + UpdateField<int32, 96, 107> MinItemLevelCutoff; + UpdateField<int32, 96, 108> MinItemLevel; + UpdateField<int32, 96, 109> MaxItemLevel; + UpdateField<int32, 96, 110> AzeriteItemLevel; + UpdateField<int32, 96, 111> WildBattlePetLevel; + UpdateField<int32, 96, 112> BattlePetCompanionExperience; + UpdateField<uint32, 96, 113> BattlePetCompanionNameTimestamp; + UpdateField<int32, 96, 114> InteractSpellID; + UpdateField<int32, 96, 115> ScaleDuration; + UpdateField<int32, 96, 116> LooksLikeMountID; + UpdateField<int32, 96, 117> LooksLikeCreatureID; + UpdateField<int32, 96, 118> LookAtControllerID; + UpdateField<int32, 96, 119> PerksVendorItemID; + UpdateField<int32, 96, 120> TaxiNodesID; + UpdateField<ObjectGuid, 96, 121> GuildGUID; + UpdateField<int32, 96, 122> FlightCapabilityID; + UpdateField<float, 96, 123> GlideEventSpeedDivisor; // Movement speed gets divided by this value when evaluating what GlideEvents to use + UpdateField<uint32, 96, 124> SilencedSchoolMask; + UpdateField<uint32, 96, 125> CurrentAreaID; + UpdateField<ObjectGuid, 96, 126> NameplateAttachToGUID; // When set, nameplate of this unit will instead appear on that object + UpdateFieldArray<uint32, 2, 127, 128> NpcFlags; struct NpcFlagsTag : ViewerDependentValueTag<uint32> {}; - UpdateFieldArray<int32, 10, 126, 127> Power; - UpdateFieldArray<int32, 10, 126, 137> MaxPower; - UpdateFieldArray<float, 10, 126, 147> PowerRegenFlatModifier; - UpdateFieldArray<float, 10, 126, 157> PowerRegenInterruptedFlatModifier; - UpdateFieldArray<UF::VisibleItem, 3, 167, 168> VirtualItems; - UpdateFieldArray<uint32, 2, 171, 172> AttackRoundBaseTime; - UpdateFieldArray<int32, 4, 174, 175> Stats; - UpdateFieldArray<int32, 4, 174, 179> StatPosBuff; - UpdateFieldArray<int32, 4, 174, 183> StatNegBuff; - UpdateFieldArray<int32, 7, 187, 188> Resistances; - UpdateFieldArray<int32, 7, 187, 195> BonusResistanceMods; - UpdateFieldArray<int32, 7, 187, 202> ManaCostModifier; + UpdateFieldArray<int32, 10, 130, 131> Power; + UpdateFieldArray<int32, 10, 130, 141> MaxPower; + UpdateFieldArray<float, 10, 130, 151> PowerRegenFlatModifier; + UpdateFieldArray<float, 10, 130, 161> PowerRegenInterruptedFlatModifier; + UpdateFieldArray<UF::VisibleItem, 3, 171, 172> VirtualItems; + UpdateFieldArray<uint32, 2, 175, 176> AttackRoundBaseTime; + UpdateFieldArray<int32, 4, 178, 179> Stats; + UpdateFieldArray<int32, 4, 178, 183> StatPosBuff; + UpdateFieldArray<int32, 4, 178, 187> StatNegBuff; + UpdateFieldArray<int32, 4, 178, 191> StatSupportBuff; + UpdateFieldArray<int32, 7, 195, 196> Resistances; + UpdateFieldArray<int32, 7, 195, 203> BonusResistanceMods; + UpdateFieldArray<int32, 7, 195, 210> 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; @@ -417,14 +422,13 @@ struct ChrCustomizationChoice : public IsUpdateFieldStructureTag bool operator!=(ChrCustomizationChoice const& right) const { return !(*this == right); } }; -struct QuestLog : public IsUpdateFieldStructureTag, public HasChangesMask<31> +struct QuestLog : public IsUpdateFieldStructureTag, public HasChangesMask<30> { - UpdateField<int32, 0, 1> QuestID; - UpdateField<uint32, 0, 2> StateFlags; - UpdateField<uint32, 0, 3> EndTime; - UpdateField<uint32, 0, 4> AcceptTime; - UpdateField<uint32, 0, 5> ObjectiveFlags; - UpdateFieldArray<int16, 24, 6, 7> ObjectiveProgress; + UpdateField<int64, 0, 1> EndTime; + UpdateField<int32, 0, 2> QuestID; + UpdateField<uint32, 0, 3> StateFlags; + UpdateField<uint32, 0, 4> ObjectiveFlags; + UpdateFieldArray<int16, 24, 5, 6> ObjectiveProgress; void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const; @@ -598,14 +602,24 @@ struct SpellFlatModByLabel : public IsUpdateFieldStructureTag bool operator!=(SpellFlatModByLabel const& right) const { return !(*this == right); } }; -struct Research : public IsUpdateFieldStructureTag +struct CompletedProject : public IsUpdateFieldStructureTag, public HasChangesMask<4> { - int16 ResearchProjectID; + UpdateField<uint32, 0, 1> ProjectID; + UpdateField<int64, 0, 2> FirstCompleted; + UpdateField<uint32, 0, 3> CompletionCount; 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==(Research const& right) const; - bool operator!=(Research const& right) const { return !(*this == right); } + void ClearChangesMask(); +}; + +struct ResearchHistory : public IsUpdateFieldStructureTag, public HasChangesMask<2> +{ + DynamicUpdateField<UF::CompletedProject, 0, 1> CompletedProjects; + + 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 MawPower : public IsUpdateFieldStructureTag @@ -788,144 +802,189 @@ struct WeeklySpellUse : public IsUpdateFieldStructureTag bool operator!=(WeeklySpellUse const& right) const { return !(*this == right); } }; -struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<1605> +struct StablePetInfo : public IsUpdateFieldStructureTag, public HasChangesMask<8> +{ + UpdateField<uint32, 0, 1> PetSlot; + UpdateField<uint32, 0, 2> PetNumber; + UpdateField<uint32, 0, 3> CreatureID; + UpdateField<uint32, 0, 4> DisplayID; + UpdateField<uint32, 0, 5> ExperienceLevel; + UpdateField<std::string, 0, 6> Name; + UpdateField<uint8, 0, 7> PetFlags; + + 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 StableInfo : public IsUpdateFieldStructureTag, public HasChangesMask<3> +{ + DynamicUpdateField<UF::StablePetInfo, 0, 1> Pets; + UpdateField<ObjectGuid, 0, 2> StableMaster; + + 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 Research : public IsUpdateFieldStructureTag +{ + int16 ResearchProjectID; + + 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==(Research const& right) const; + bool operator!=(Research const& right) const { return !(*this == right); } +}; + +struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<1618> { UpdateField<bool, 0, 1> BackpackAutoSortDisabled; UpdateField<bool, 0, 2> BankAutoSortDisabled; UpdateField<bool, 0, 3> SortBagsRightToLeft; UpdateField<bool, 0, 4> InsertItemsLeftToRight; UpdateField<bool, 0, 5> HasPerksProgramPendingReward; - UpdateFieldArray<DynamicUpdateFieldBase<UF::Research>, 1, 35, 36> Research; + UpdateFieldArray<DynamicUpdateFieldBase<uint16>, 1, 35, 36> ResearchSites; + UpdateFieldArray<DynamicUpdateFieldBase<uint32>, 1, 37, 38> ResearchSiteProgress; + UpdateFieldArray<DynamicUpdateFieldBase<UF::Research>, 1, 39, 40> Research; DynamicUpdateField<uint64, 0, 6> KnownTitles; - DynamicUpdateField<uint16, 0, 8> ResearchSites; - DynamicUpdateField<uint32, 0, 9> ResearchSiteProgress; - DynamicUpdateField<int32, 0, 10> DailyQuestsCompleted; - DynamicUpdateField<int32, 0, 11> AvailableQuestLineXQuestIDs; - DynamicUpdateField<int32, 0, 12> Heirlooms; - DynamicUpdateField<uint32, 0, 13> HeirloomFlags; - DynamicUpdateField<int32, 0, 14> Toys; - DynamicUpdateField<uint32, 0, 15> ToyFlags; - DynamicUpdateField<uint32, 0, 16> Transmog; - DynamicUpdateField<int32, 0, 17> ConditionalTransmog; - DynamicUpdateField<int32, 0, 18> SelfResSpells; - DynamicUpdateField<uint32, 0, 19> RuneforgePowers; - DynamicUpdateField<uint32, 0, 20> TransmogIllusions; - DynamicUpdateField<UF::SpellPctModByLabel, 0, 22> SpellPctModByLabel; - DynamicUpdateField<UF::SpellFlatModByLabel, 0, 23> SpellFlatModByLabel; - DynamicUpdateField<UF::MawPower, 0, 24> MawPowers; - DynamicUpdateField<UF::MultiFloorExplore, 0, 25> MultiFloorExploration; - DynamicUpdateField<UF::RecipeProgressionInfo, 0, 26> RecipeProgression; - DynamicUpdateField<UF::ReplayedQuest, 0, 27> ReplayedQuests; - DynamicUpdateField<int32, 0, 28> DisabledSpells; - DynamicUpdateField<UF::PersonalCraftingOrderCount, 0, 31> PersonalCraftingOrderCounts; - DynamicUpdateField<UF::CategoryCooldownMod, 32, 33> CategoryCooldownMods; - DynamicUpdateField<UF::WeeklySpellUse, 32, 34> WeeklySpellUses; + 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<UF::QuestLog, 0, 26> TaskQuests; + DynamicUpdateField<int32, 0, 27> DisabledSpells; + DynamicUpdateField<UF::PersonalCraftingOrderCount, 0, 30> PersonalCraftingOrderCounts; + DynamicUpdateField<UF::CategoryCooldownMod, 0, 31> CategoryCooldownMods; + DynamicUpdateField<UF::WeeklySpellUse, 32, 33> WeeklySpellUses; + DynamicUpdateField<int64, 32, 34> TrackedCollectableSources; DynamicUpdateField<UF::PVPInfo, 0, 7> PvpInfo; - DynamicUpdateField<UF::CharacterRestriction, 0, 21> CharacterRestrictions; - DynamicUpdateField<UF::TraitConfig, 0, 29> TraitConfigs; - DynamicUpdateField<UF::CraftingOrder, 0, 30> CraftingOrders; - UpdateField<ObjectGuid, 32, 37> FarsightObject; - UpdateField<ObjectGuid, 32, 38> SummonedBattlePetGUID; - UpdateField<uint64, 32, 39> Coinage; - UpdateField<int32, 32, 40> XP; - UpdateField<int32, 32, 41> NextLevelXP; - UpdateField<int32, 32, 42> TrialXP; - UpdateField<UF::SkillInfo, 32, 43> Skill; - UpdateField<int32, 32, 44> CharacterPoints; - UpdateField<int32, 32, 45> MaxTalentTiers; - UpdateField<uint32, 32, 46> TrackCreatureMask; - UpdateField<float, 32, 47> MainhandExpertise; - UpdateField<float, 32, 48> OffhandExpertise; - UpdateField<float, 32, 49> RangedExpertise; - UpdateField<float, 32, 50> CombatRatingExpertise; - UpdateField<float, 32, 51> BlockPercentage; - UpdateField<float, 32, 52> DodgePercentage; - UpdateField<float, 32, 53> DodgePercentageFromAttribute; - UpdateField<float, 32, 54> ParryPercentage; - UpdateField<float, 32, 55> ParryPercentageFromAttribute; - UpdateField<float, 32, 56> CritPercentage; - UpdateField<float, 32, 57> RangedCritPercentage; - UpdateField<float, 32, 58> OffhandCritPercentage; - UpdateField<float, 32, 59> SpellCritPercentage; - UpdateField<int32, 32, 60> ShieldBlock; - UpdateField<float, 32, 61> ShieldBlockCritPercentage; - UpdateField<float, 32, 62> Mastery; - UpdateField<float, 32, 63> Speed; - UpdateField<float, 32, 64> Avoidance; - UpdateField<float, 32, 65> Sturdiness; - UpdateField<int32, 66, 67> Versatility; - UpdateField<float, 66, 68> VersatilityBonus; - UpdateField<float, 66, 69> PvpPowerDamage; - UpdateField<float, 66, 70> PvpPowerHealing; - UpdateField<int32, 66, 71> ModHealingDonePos; - UpdateField<float, 66, 72> ModHealingPercent; - UpdateField<float, 66, 73> ModPeriodicHealingDonePercent; - UpdateField<float, 66, 74> ModSpellPowerPercent; - UpdateField<float, 66, 75> ModResiliencePercent; - UpdateField<float, 66, 76> OverrideSpellPowerByAPPercent; - UpdateField<float, 66, 77> OverrideAPBySpellPowerPercent; - UpdateField<int32, 66, 78> ModTargetResistance; - UpdateField<int32, 66, 79> ModTargetPhysicalResistance; - UpdateField<uint32, 66, 80> LocalFlags; - UpdateField<uint8, 66, 81> GrantableLevels; - UpdateField<uint8, 66, 82> MultiActionBars; - UpdateField<uint8, 66, 83> LifetimeMaxRank; - UpdateField<uint8, 66, 84> NumRespecs; - UpdateField<uint32, 66, 85> PvpMedals; - UpdateField<uint16, 66, 86> TodayHonorableKills; - UpdateField<uint16, 66, 87> YesterdayHonorableKills; - UpdateField<uint32, 66, 88> LifetimeHonorableKills; - UpdateField<int32, 66, 89> WatchedFactionIndex; - UpdateField<int32, 66, 90> MaxLevel; - UpdateField<int32, 66, 91> ScalingPlayerLevelDelta; - UpdateField<int32, 66, 92> MaxCreatureScalingLevel; - UpdateField<int32, 66, 93> PetSpellPower; - UpdateField<float, 66, 94> UiHitModifier; - UpdateField<float, 66, 95> UiSpellHitModifier; - UpdateField<int32, 66, 96> HomeRealmTimeOffset; - UpdateField<float, 66, 97> ModPetHaste; - UpdateField<int8, 98, 99> JailersTowerLevelMax; - UpdateField<int8, 98, 100> JailersTowerLevel; - UpdateField<uint8, 98, 101> LocalRegenFlags; - UpdateField<uint8, 98, 102> AuraVision; - UpdateField<uint8, 98, 103> NumBackpackSlots; - UpdateField<int32, 98, 104> OverrideSpellsID; - UpdateField<uint16, 98, 105> LootSpecID; - UpdateField<uint32, 98, 106> OverrideZonePVPType; - UpdateField<ObjectGuid, 98, 107> BnetAccount; - UpdateField<uint64, 98, 108> GuildClubMemberID; - UpdateField<int32, 98, 109> Honor; - UpdateField<int32, 98, 110> HonorNextLevel; - UpdateField<int32, 98, 111> PerksProgramCurrency; - UpdateField<uint8, 98, 112> NumBankSlots; - UpdateField<WorldPackets::PerksProgram::PerksVendorItem, 98, 113> FrozenPerksVendorItem; - UpdateField<UF::ActivePlayerUnk901, 98, 115> Field_1410; - OptionalUpdateField<UF::QuestSession, 98, 114> QuestSession; - UpdateField<int32, 98, 116> UiChromieTimeExpansionID; - UpdateField<int32, 98, 117> TransportServerTime; - UpdateField<uint32, 98, 118> WeeklyRewardsPeriodSinceOrigin; // week count since Cfg_RegionsEntry::ChallengeOrigin - UpdateField<int16, 98, 119> DEBUGSoulbindConduitRank; - UpdateField<WorldPackets::MythicPlus::DungeonScoreData, 98, 120> DungeonScore; - UpdateField<uint32, 98, 121> ActiveCombatTraitConfigID; - UpdateField<uint64, 98, 122> LootHistoryInstanceID; - UpdateFieldArray<ObjectGuid, 227, 123, 124> InvSlots; - UpdateFieldArray<uint64, 240, 351, 352> ExploredZones; - UpdateFieldArray<UF::RestInfo, 2, 592, 593> RestInfo; - UpdateFieldArray<int32, 7, 595, 596> ModDamageDonePos; - UpdateFieldArray<int32, 7, 595, 603> ModDamageDoneNeg; - UpdateFieldArray<float, 7, 595, 610> ModDamageDonePercent; - UpdateFieldArray<float, 7, 595, 617> ModHealingDonePercent; - UpdateFieldArray<float, 3, 624, 625> WeaponDmgMultipliers; - UpdateFieldArray<float, 3, 624, 628> WeaponAtkSpeedMultipliers; - UpdateFieldArray<uint32, 12, 631, 632> BuybackPrice; - UpdateFieldArray<int64, 12, 631, 644> BuybackTimestamp; - UpdateFieldArray<int32, 32, 656, 657> CombatRatings; - UpdateFieldArray<uint32, 4, 689, 690> NoReagentCostMask; - UpdateFieldArray<int32, 2, 694, 695> ProfessionSkillLine; - UpdateFieldArray<uint32, 5, 697, 698> BagSlotFlags; - UpdateFieldArray<uint32, 7, 703, 704> BankBagSlotFlags; - UpdateFieldArray<uint64, 875, 711, 712> QuestCompleted; - UpdateFieldArray<float, 17, 1587, 1588> ItemUpgradeHighWatermark; + DynamicUpdateField<UF::CharacterRestriction, 0, 19> CharacterRestrictions; + DynamicUpdateField<UF::TraitConfig, 0, 28> TraitConfigs; + DynamicUpdateField<UF::CraftingOrder, 0, 29> CraftingOrders; + UpdateField<ObjectGuid, 32, 41> FarsightObject; + UpdateField<ObjectGuid, 32, 42> SummonedBattlePetGUID; + UpdateField<uint64, 32, 43> Coinage; + UpdateField<int32, 32, 44> XP; + UpdateField<int32, 32, 45> NextLevelXP; + UpdateField<int32, 32, 46> TrialXP; + UpdateField<UF::SkillInfo, 32, 47> Skill; + UpdateField<int32, 32, 48> CharacterPoints; + UpdateField<int32, 32, 49> MaxTalentTiers; + UpdateField<uint32, 32, 50> TrackCreatureMask; + UpdateField<float, 32, 51> MainhandExpertise; + UpdateField<float, 32, 52> OffhandExpertise; + UpdateField<float, 32, 53> RangedExpertise; + UpdateField<float, 32, 54> CombatRatingExpertise; + UpdateField<float, 32, 55> BlockPercentage; + UpdateField<float, 32, 56> DodgePercentage; + UpdateField<float, 32, 57> DodgePercentageFromAttribute; + UpdateField<float, 32, 58> ParryPercentage; + UpdateField<float, 32, 59> ParryPercentageFromAttribute; + UpdateField<float, 32, 60> CritPercentage; + UpdateField<float, 32, 61> RangedCritPercentage; + UpdateField<float, 32, 62> OffhandCritPercentage; + UpdateField<float, 32, 63> SpellCritPercentage; + UpdateField<int32, 32, 64> ShieldBlock; + UpdateField<float, 32, 65> ShieldBlockCritPercentage; + UpdateField<float, 32, 66> Mastery; + UpdateField<float, 32, 67> Speed; + UpdateField<float, 32, 68> Avoidance; + UpdateField<float, 32, 69> Sturdiness; + UpdateField<int32, 70, 71> Versatility; + UpdateField<float, 70, 72> VersatilityBonus; + UpdateField<float, 70, 73> PvpPowerDamage; + UpdateField<float, 70, 74> PvpPowerHealing; + UpdateField<int32, 70, 75> ModHealingDonePos; + UpdateField<float, 70, 76> ModHealingPercent; + UpdateField<float, 70, 77> ModPeriodicHealingDonePercent; + UpdateField<float, 70, 78> ModSpellPowerPercent; + UpdateField<float, 70, 79> ModResiliencePercent; + UpdateField<float, 70, 80> OverrideSpellPowerByAPPercent; + UpdateField<float, 70, 81> OverrideAPBySpellPowerPercent; + UpdateField<int32, 70, 82> ModTargetResistance; + UpdateField<int32, 70, 83> ModTargetPhysicalResistance; + UpdateField<uint32, 70, 84> LocalFlags; + UpdateField<uint8, 70, 85> GrantableLevels; + UpdateField<uint8, 70, 86> MultiActionBars; + UpdateField<uint8, 70, 87> LifetimeMaxRank; + UpdateField<uint8, 70, 88> NumRespecs; + UpdateField<uint32, 70, 89> PvpMedals; + UpdateField<uint16, 70, 90> TodayHonorableKills; + UpdateField<uint16, 70, 91> YesterdayHonorableKills; + UpdateField<uint32, 70, 92> LifetimeHonorableKills; + UpdateField<int32, 70, 93> WatchedFactionIndex; + UpdateField<int32, 70, 94> MaxLevel; + UpdateField<int32, 70, 95> ScalingPlayerLevelDelta; + UpdateField<int32, 70, 96> MaxCreatureScalingLevel; + UpdateField<int32, 70, 97> PetSpellPower; + UpdateField<float, 70, 98> UiHitModifier; + UpdateField<float, 70, 99> UiSpellHitModifier; + UpdateField<int32, 70, 100> HomeRealmTimeOffset; + UpdateField<float, 70, 101> ModPetHaste; + UpdateField<int8, 102, 103> JailersTowerLevelMax; + UpdateField<int8, 102, 104> JailersTowerLevel; + UpdateField<uint8, 102, 105> LocalRegenFlags; + UpdateField<uint8, 102, 106> AuraVision; + UpdateField<uint8, 102, 107> NumBackpackSlots; + UpdateField<int32, 102, 108> OverrideSpellsID; + UpdateField<uint16, 102, 109> LootSpecID; + UpdateField<uint32, 102, 110> OverrideZonePVPType; + UpdateField<ObjectGuid, 102, 111> BnetAccount; + UpdateField<uint64, 102, 112> GuildClubMemberID; + UpdateField<int32, 102, 113> Honor; + UpdateField<int32, 102, 114> HonorNextLevel; + UpdateField<int32, 102, 115> PerksProgramCurrency; + UpdateField<uint8, 102, 116> NumBankSlots; + UpdateField<UF::ResearchHistory, 102, 117> ResearchHistory; + UpdateField<WorldPackets::PerksProgram::PerksVendorItem, 102, 118> FrozenPerksVendorItem; + UpdateField<UF::ActivePlayerUnk901, 102, 120> Field_1410; + OptionalUpdateField<UF::QuestSession, 102, 119> QuestSession; + UpdateField<int32, 102, 121> UiChromieTimeExpansionID; + UpdateField<int32, 102, 122> TransportServerTime; + UpdateField<uint32, 102, 123> WeeklyRewardsPeriodSinceOrigin; // week count since Cfg_RegionsEntry::ChallengeOrigin + UpdateField<int16, 102, 124> DEBUGSoulbindConduitRank; + UpdateField<WorldPackets::MythicPlus::DungeonScoreData, 102, 125> DungeonScore; + UpdateField<uint32, 102, 126> ActiveCombatTraitConfigID; + UpdateField<int32, 102, 127> ItemUpgradeHighOnehandWeaponItemID; + UpdateField<int32, 102, 128> ItemUpgradeHighFingerItemID; + UpdateField<float, 102, 129> ItemUpgradeHighFingerWatermark; + UpdateField<int32, 102, 130> ItemUpgradeHighTrinketItemID; + UpdateField<float, 102, 131> ItemUpgradeHighTrinketWatermark; + UpdateField<uint64, 102, 132> LootHistoryInstanceID; + OptionalUpdateField<UF::StableInfo, 102, 133> PetStable; + UpdateField<uint8, 134, 135> RequiredMountCapabilityFlags; + UpdateFieldArray<ObjectGuid, 227, 136, 137> InvSlots; + UpdateFieldArray<uint64, 240, 364, 365> ExploredZones; + UpdateFieldArray<UF::RestInfo, 2, 605, 606> RestInfo; + UpdateFieldArray<int32, 7, 608, 609> ModDamageDonePos; + UpdateFieldArray<int32, 7, 608, 616> ModDamageDoneNeg; + UpdateFieldArray<float, 7, 608, 623> ModDamageDonePercent; + UpdateFieldArray<float, 7, 608, 630> ModHealingDonePercent; + UpdateFieldArray<float, 3, 637, 638> WeaponDmgMultipliers; + UpdateFieldArray<float, 3, 637, 641> WeaponAtkSpeedMultipliers; + UpdateFieldArray<uint32, 12, 644, 645> BuybackPrice; + UpdateFieldArray<int64, 12, 644, 657> BuybackTimestamp; + UpdateFieldArray<int32, 32, 669, 670> CombatRatings; + UpdateFieldArray<uint32, 4, 702, 703> NoReagentCostMask; + UpdateFieldArray<int32, 2, 707, 708> ProfessionSkillLine; + UpdateFieldArray<uint32, 5, 710, 711> BagSlotFlags; + UpdateFieldArray<uint32, 7, 716, 717> BankBagSlotFlags; + UpdateFieldArray<uint64, 875, 724, 725> QuestCompleted; + UpdateFieldArray<float, 17, 1600, 1601> ItemUpgradeHighWatermark; 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; @@ -1029,32 +1088,33 @@ struct VisualAnim : public IsUpdateFieldStructureTag, public HasChangesMask<5> void ClearChangesMask(); }; -struct AreaTriggerData : public IsUpdateFieldStructureTag, public HasChangesMask<25> +struct AreaTriggerData : public IsUpdateFieldStructureTag, public HasChangesMask<26> { - UpdateField<bool, 0, 1> Field_260; + UpdateField<bool, 0, 1> HeightIgnoresScale; UpdateField<bool, 0, 2> Field_261; UpdateField<UF::ScaleCurve, 0, 3> OverrideScaleCurve; UpdateField<UF::ScaleCurve, 0, 4> ExtraScaleCurve; - UpdateField<UF::ScaleCurve, 0, 5> Field_C38; - UpdateField<UF::ScaleCurve, 0, 6> Field_C54; - UpdateField<UF::ScaleCurve, 0, 7> Field_C70; + UpdateField<UF::ScaleCurve, 0, 5> OverrideMoveCurveX; + UpdateField<UF::ScaleCurve, 0, 6> OverrideMoveCurveY; + UpdateField<UF::ScaleCurve, 0, 7> OverrideMoveCurveZ; UpdateField<ObjectGuid, 0, 8> Caster; UpdateField<uint32, 0, 9> Duration; UpdateField<uint32, 0, 10> TimeToTarget; UpdateField<uint32, 0, 11> TimeToTargetScale; UpdateField<uint32, 0, 12> TimeToTargetExtraScale; - UpdateField<uint32, 0, 13> Field_B0; + UpdateField<uint32, 0, 13> TimeToTargetPos; // Linked to m_overrideMoveCurve UpdateField<int32, 0, 14> SpellID; UpdateField<int32, 0, 15> SpellForVisuals; UpdateField<UF::SpellCastVisual, 0, 16> SpellVisual; UpdateField<float, 0, 17> BoundsRadius2D; UpdateField<uint32, 0, 18> DecalPropertiesID; UpdateField<ObjectGuid, 0, 19> CreatingEffectGUID; - UpdateField<uint32, 0, 20> Field_80; - UpdateField<uint32, 0, 21> Field_84; - UpdateField<ObjectGuid, 0, 22> Field_88; - UpdateField<TaggedPosition<Position::XYZ>, 0, 23> Field_F8; - UpdateField<UF::VisualAnim, 0, 24> VisualAnim; + UpdateField<uint32, 0, 20> NumUnitsInside; + UpdateField<uint32, 0, 21> NumPlayersInside; // When not 0 this causes SpellVisualEvent 14 to trigger, playing alternate visuals, typically used by "SOAK THIS" areatriggers + UpdateField<ObjectGuid, 0, 22> OrbitPathTarget; + UpdateField<TaggedPosition<Position::XYZ>, 0, 23> RollPitchYaw; + UpdateField<int32, 0, 24> PositionalSoundKitID; + UpdateField<UF::VisualAnim, 0, 25> 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/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index 0a671d6d549..a03ab823bb4 100644 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -30,12 +30,6 @@ struct PetSpell PetSpellType type; }; -enum PetStableinfo -{ - PET_STABLE_ACTIVE = 1, - PET_STABLE_INACTIVE = 2 -}; - typedef std::unordered_map<uint32, PetSpell> PetSpellMap; typedef std::vector<uint32> AutoSpellList; diff --git a/src/server/game/Entities/Pet/PetDefines.h b/src/server/game/Entities/Pet/PetDefines.h index 607efbf59df..e926cf64966 100644 --- a/src/server/game/Entities/Pet/PetDefines.h +++ b/src/server/game/Entities/Pet/PetDefines.h @@ -58,6 +58,12 @@ constexpr bool IsStabledPetSlot(PetSaveMode slot) return slot >= PET_SAVE_FIRST_STABLE_SLOT && slot < PET_SAVE_LAST_STABLE_SLOT; } +enum PetStableFlags : uint8 +{ + PET_STABLE_ACTIVE = 0x1, + PET_STABLE_INACTIVE = 0x2 +}; + enum PetSpellState { PETSPELL_UNCHANGED = 0, @@ -110,6 +116,17 @@ enum class PetTameResult : uint8 EliteTooHighLevel = 14 }; +enum class StableResult : uint8 +{ + NotEnoughMoney = 1, // "you don't have enough money" + InvalidSlot = 3, // "That slot is locked" + StableSuccess = 8, // stable success + UnstableSuccess = 9, // unstable/swap success + BuySlotSuccess = 10, // buy slot success + CantControlExotic = 11, // "you are unable to control exotic creatures" + InternalError = 12, // "Internal pet error" +}; + constexpr uint32 CALL_PET_SPELL_ID = 883; constexpr uint32 PET_SUMMONING_DISORIENTATION = 32752; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e5476b4a10e..0bdd521593b 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -14133,7 +14133,8 @@ void Player::OnGossipSelect(WorldObject* source, int32 gossipOptionId, uint32 me SendRespecWipeConfirm(guid, sWorld->getBoolConfig(CONFIG_NO_RESET_TALENT_COST) ? 0 : GetNextResetTalentsCost(), SPEC_RESET_TALENTS); break; case GossipOptionNpc::Stablemaster: - GetSession()->SendStablePet(guid); + SetStableMaster(guid); + handled = false; break; case GossipOptionNpc::PetSpecializationMaster: PlayerTalkClass->SendCloseGossip(); @@ -14891,7 +14892,7 @@ void Player::AddQuest(Quest const* quest, Object* questGiver) } SetQuestSlotEndTime(log_slot, endTime); - SetQuestSlotAcceptTime(log_slot, GameTime::GetGameTime()); + questStatusData.AcceptTime = GameTime::GetGameTime(); m_QuestStatusSave[quest_id] = QUEST_DEFAULT_SAVE_TYPE; @@ -16131,7 +16132,9 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object const* questgiver) const switch (GetQuestStatus(questId)) { case QUEST_STATUS_COMPLETE: - if (quest->GetQuestTag() == QuestTagType::CovenantCalling) + if (quest->IsImportant()) + result |= quest->HasFlag(QUEST_FLAGS_HIDE_REWARD_POI) ? QuestGiverStatus::ImportantQuestRewardCompleteNoPOI : QuestGiverStatus::ImportantQuestRewardCompletePOI; + else if (quest->GetQuestTag() == QuestTagType::CovenantCalling) result |= quest->HasFlag(QUEST_FLAGS_HIDE_REWARD_POI) ? QuestGiverStatus::CovenantCallingRewardCompleteNoPOI : QuestGiverStatus::CovenantCallingRewardCompletePOI; else if (quest->HasFlagEx(QUEST_FLAGS_EX_LEGENDARY)) result |= quest->HasFlag(QUEST_FLAGS_HIDE_REWARD_POI) ? QuestGiverStatus::LegendaryRewardCompleteNoPOI : QuestGiverStatus::LegendaryRewardCompletePOI; @@ -16139,8 +16142,12 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object const* questgiver) const result |= quest->HasFlag(QUEST_FLAGS_HIDE_REWARD_POI) ? QuestGiverStatus::RewardCompleteNoPOI : QuestGiverStatus::RewardCompletePOI; break; case QUEST_STATUS_INCOMPLETE: - if (quest->GetQuestTag() == QuestTagType::CovenantCalling) + if (quest->IsImportant()) + result |= QuestGiverStatus::ImportantQuestReward; + else if (quest->GetQuestTag() == QuestTagType::CovenantCalling) result |= QuestGiverStatus::CovenantCallingReward; + else if (quest->HasFlagEx(QUEST_FLAGS_EX_LEGENDARY)) + result |= QuestGiverStatus::LegendaryReward; else result |= QuestGiverStatus::Reward; break; @@ -16172,22 +16179,20 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object const* questgiver) const { if (SatisfyQuestLevel(quest, false)) { - if (GetLevel() <= (GetQuestLevel(quest) + sWorld->getIntConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF))) - { - if (quest->GetQuestTag() == QuestTagType::CovenantCalling) - result |= QuestGiverStatus::CovenantCallingQuest; - else if (quest->HasFlagEx(QUEST_FLAGS_EX_LEGENDARY)) - result |= QuestGiverStatus::LegendaryQuest; - else if (quest->IsDaily()) - result |= QuestGiverStatus::DailyQuest; - else - result |= QuestGiverStatus::Quest; - } + bool isTrivial = GetLevel() <= (GetQuestLevel(quest) + sWorld->getIntConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF)); + if (quest->IsImportant()) + result |= isTrivial ? QuestGiverStatus::TrivialImportantQuest : QuestGiverStatus::ImportantQuest; + else if (quest->GetQuestTag() == QuestTagType::CovenantCalling) + result |= isTrivial ? QuestGiverStatus::TrivialCovenantCallingQuest : QuestGiverStatus::CovenantCallingQuest; + else if (quest->HasFlagEx(QUEST_FLAGS_EX_LEGENDARY)) + result |= isTrivial ? QuestGiverStatus::TrivialLegendaryQuest : QuestGiverStatus::LegendaryQuest; else if (quest->IsDaily()) - result |= QuestGiverStatus::TrivialDailyQuest; + result |= isTrivial ? QuestGiverStatus::TrivialDailyQuest : QuestGiverStatus::DailyQuest; else - result |= QuestGiverStatus::Trivial; + result |= isTrivial ? QuestGiverStatus::Trivial : QuestGiverStatus::Quest; } + else if (quest->HasFlagEx(QUEST_FLAGS_EX_LEGENDARY)) + result |= QuestGiverStatus::FutureLegendaryQuest; else result |= QuestGiverStatus::Future; } @@ -16264,16 +16269,11 @@ uint16 Player::GetQuestSlotCounter(uint16 slot, uint8 counter) const return 0; } -uint32 Player::GetQuestSlotEndTime(uint16 slot) const +int64 Player::GetQuestSlotEndTime(uint16 slot) const { return m_playerData->QuestLog[slot].EndTime; } -uint32 Player::GetQuestSlotAcceptTime(uint16 slot) const -{ - return m_playerData->QuestLog[slot].AcceptTime; -} - bool Player::GetQuestSlotObjectiveFlag(uint16 slot, int8 objectiveIndex) const { if (objectiveIndex < MAX_QUEST_COUNTS) @@ -16309,7 +16309,6 @@ void Player::SetQuestSlot(uint16 slot, uint32 quest_id) SetUpdateFieldValue(questLogField.ModifyValue(&UF::QuestLog::QuestID), quest_id); SetUpdateFieldValue(questLogField.ModifyValue(&UF::QuestLog::StateFlags), 0); SetUpdateFieldValue(questLogField.ModifyValue(&UF::QuestLog::EndTime), 0); - SetUpdateFieldValue(questLogField.ModifyValue(&UF::QuestLog::AcceptTime), 0); SetUpdateFieldValue(questLogField.ModifyValue(&UF::QuestLog::ObjectiveFlags), 0); for (uint32 i = 0; i < MAX_QUEST_COUNTS; ++i) SetUpdateFieldValue(questLogField.ModifyValue(&UF::QuestLog::ObjectiveProgress, i), 0); @@ -16346,13 +16345,6 @@ void Player::SetQuestSlotEndTime(uint16 slot, time_t endTime) .ModifyValue(&UF::QuestLog::EndTime), uint32(endTime)); } -void Player::SetQuestSlotAcceptTime(uint16 slot, time_t acceptTime) -{ - SetUpdateFieldValue(m_values.ModifyValue(&Player::m_playerData) - .ModifyValue(&UF::PlayerData::QuestLog, slot) - .ModifyValue(&UF::QuestLog::AcceptTime), uint32(acceptTime)); -} - void Player::SetQuestSlotObjectiveFlag(uint16 slot, int8 objectiveIndex) { SetUpdateFieldFlagValue(m_values.ModifyValue(&Player::m_playerData) @@ -19030,7 +19022,7 @@ void Player::_LoadQuestStatus(PreparedQueryResult result) SetQuestSlot(slot, quest_id); SetQuestSlotEndTime(slot, endTime); - SetQuestSlotAcceptTime(slot, acceptTime); + questStatusData.AcceptTime = acceptTime; if (questStatusData.Status == QUEST_STATUS_COMPLETE) SetQuestSlotState(slot, QUEST_STATE_COMPLETE); @@ -20490,7 +20482,7 @@ void Player::_SaveQuestStatus(CharacterDatabaseTransaction trans) stmt->setUInt32(1, statusItr->first); stmt->setUInt8(2, uint8(qData.Status)); stmt->setBool(3, qData.Explored); - stmt->setInt64(4, GetQuestSlotAcceptTime(qData.Slot)); + stmt->setInt64(4, qData.AcceptTime); stmt->setInt64(5, GetQuestSlotEndTime(qData.Slot)); trans->Append(stmt); @@ -21075,6 +21067,19 @@ bool Player::IsLockedToDungeonEncounter(uint32 dungeonEncounterId) const return (instanceLock->GetData()->CompletedEncountersMask & (1u << dungeonEncounter->Bit)) != 0; } +bool Player::IsLockedToDungeonEncounter(uint32 dungeonEncounterId, Difficulty difficulty) const +{ + DungeonEncounterEntry const* dungeonEncounter = sDungeonEncounterStore.LookupEntry(dungeonEncounterId); + if (!dungeonEncounter) + return false; + + InstanceLock const* instanceLock = sInstanceLockMgr.FindActiveInstanceLock(GetGUID(), { uint32(dungeonEncounter->MapID), difficulty }); + if (!instanceLock) + return false; + + return (instanceLock->GetData()->CompletedEncountersMask & (1u << dungeonEncounter->Bit)) != 0; +} + /*********************************************************/ /*** Update timers ***/ /*********************************************************/ @@ -21243,8 +21248,24 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent) PetStable::PetInfo const* currentPet = m_petStable->GetCurrentPet(); ASSERT(currentPet && currentPet->PetNumber == pet->GetCharmInfo()->GetPetNumber()); - if (mode == PET_SAVE_NOT_IN_SLOT || mode == PET_SAVE_AS_DELETED) + if (mode == PET_SAVE_NOT_IN_SLOT) m_petStable->CurrentPetIndex.reset(); + else if (mode == PET_SAVE_AS_DELETED) + { + if (m_activePlayerData->PetStable.has_value()) + { + int32 ufIndex = m_activePlayerData->PetStable->Pets.FindIndexIf([currentPet](UF::StablePetInfo const& p) { return p.PetNumber == currentPet->PetNumber; }); + if (ufIndex >= 0) + RemoveDynamicUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData) + .ModifyValue(&UF::ActivePlayerData::PetStable, 0) + .ModifyValue(&UF::StableInfo::Pets), ufIndex); + } + + if (Optional<uint32> petIndex = m_petStable->GetCurrentActivePetIndex()) + m_petStable->ActivePets[*petIndex].reset(); + + m_petStable->CurrentPetIndex.reset(); + } // else if (stable slots) handled in opcode handlers due to required swaps // else (current pet) doesnt need to do anything @@ -28041,6 +28062,196 @@ PetStable& Player::GetOrInitPetStable() return *m_petStable; } +void Player::AddPetToUpdateFields(PetStable::PetInfo const& pet, PetSaveMode slot, PetStableFlags flags) +{ + auto ufStable = m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::PetStable, 0); + auto ufPet = AddDynamicUpdateFieldValue(ufStable.ModifyValue(&UF::StableInfo::Pets)); + ufPet.ModifyValue(&UF::StablePetInfo::PetSlot).SetValue(slot); + ufPet.ModifyValue(&UF::StablePetInfo::PetNumber).SetValue(pet.PetNumber); + ufPet.ModifyValue(&UF::StablePetInfo::CreatureID).SetValue(pet.CreatureId); + ufPet.ModifyValue(&UF::StablePetInfo::DisplayID).SetValue(pet.DisplayId); + ufPet.ModifyValue(&UF::StablePetInfo::ExperienceLevel).SetValue(pet.Level); + ufPet.ModifyValue(&UF::StablePetInfo::PetFlags).SetValue(flags); + ufPet.ModifyValue(&UF::StablePetInfo::Name).SetValue(pet.Name); +} + +void Player::SetPetSlot(uint32 petNumber, PetSaveMode dstPetSlot) +{ + RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::Interacting); + + WorldSession* sess = GetSession(); + PetStable* petStable = GetPetStable(); + if (!petStable) + { + sess->SendPetStableResult(StableResult::InternalError); + return; + } + + auto [srcPet, srcPetSlot] = Pet::GetLoadPetInfo(*petStable, 0, petNumber, {}); + PetStable::PetInfo const* dstPet = Pet::GetLoadPetInfo(*petStable, 0, 0, dstPetSlot).first; + + if (!srcPet || srcPet->Type != HUNTER_PET) + { + sess->SendPetStableResult(StableResult::InternalError); + return; + } + + if (dstPet && dstPet->Type != HUNTER_PET) + { + sess->SendPetStableResult(StableResult::InternalError); + return; + } + + Optional<PetStable::PetInfo>* src = nullptr; + Optional<PetStable::PetInfo>* dst = nullptr; + Optional<uint32> newActivePetIndex; + + if (IsActivePetSlot(srcPetSlot) && IsActivePetSlot(dstPetSlot)) + { + // active<->active: only swap ActivePets and CurrentPetIndex (do not despawn pets) + src = &petStable->ActivePets[srcPetSlot - PET_SAVE_FIRST_ACTIVE_SLOT]; + dst = &petStable->ActivePets[dstPetSlot - PET_SAVE_FIRST_ACTIVE_SLOT]; + + if (petStable->GetCurrentActivePetIndex() == uint32_t(srcPetSlot)) + newActivePetIndex = dstPetSlot; + else if (petStable->GetCurrentActivePetIndex() == uint32(dstPetSlot)) + newActivePetIndex = srcPetSlot; + } + else if (IsStabledPetSlot(srcPetSlot) && IsStabledPetSlot(dstPetSlot)) + { + // stabled<->stabled: only swap StabledPets + src = &petStable->StabledPets[srcPetSlot - PET_SAVE_FIRST_STABLE_SLOT]; + dst = &petStable->StabledPets[dstPetSlot - PET_SAVE_FIRST_STABLE_SLOT]; + } + else if (IsActivePetSlot(srcPetSlot) && IsStabledPetSlot(dstPetSlot)) + { + // active<->stabled: swap petStable contents and despawn active pet if it is involved in swap + if (petStable->CurrentPetIndex == uint32(srcPetSlot)) + { + Pet* oldPet = GetPet(); + if (oldPet && !oldPet->IsAlive()) + { + sess->SendPetStableResult(StableResult::InternalError); + return; + } + + RemovePet(oldPet, PET_SAVE_NOT_IN_SLOT); + } + + if (dstPet) + { + CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(dstPet->CreatureId); + if (!creatureInfo || !creatureInfo->IsTameable(CanTameExoticPets(), creatureInfo->GetDifficulty(DIFFICULTY_NONE))) + { + sess->SendPetStableResult(StableResult::CantControlExotic); + return; + } + } + + src = &petStable->ActivePets[srcPetSlot - PET_SAVE_FIRST_ACTIVE_SLOT]; + dst = &petStable->StabledPets[dstPetSlot - PET_SAVE_FIRST_STABLE_SLOT]; + } + else if (IsStabledPetSlot(srcPetSlot) && IsActivePetSlot(dstPetSlot)) + { + // stabled<->active: swap petStable contents and despawn active pet if it is involved in swap + if (petStable->CurrentPetIndex == uint32(dstPetSlot)) + { + Pet* oldPet = GetPet(); + if (oldPet && !oldPet->IsAlive()) + { + sess->SendPetStableResult(StableResult::InternalError); + return; + } + + RemovePet(oldPet, PET_SAVE_NOT_IN_SLOT); + } + + CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(srcPet->CreatureId); + if (!creatureInfo || !creatureInfo->IsTameable(CanTameExoticPets(), creatureInfo->GetDifficulty(DIFFICULTY_NONE))) + { + sess->SendPetStableResult(StableResult::CantControlExotic); + return; + } + + src = &petStable->StabledPets[srcPetSlot - PET_SAVE_FIRST_STABLE_SLOT]; + dst = &petStable->ActivePets[dstPetSlot - PET_SAVE_FIRST_ACTIVE_SLOT]; + } + + CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); + + CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_PET_SLOT_BY_ID); + stmt->setInt16(0, dstPetSlot); + stmt->setUInt64(1, GetGUID().GetCounter()); + stmt->setUInt32(2, srcPet->PetNumber); + trans->Append(stmt); + + if (dstPet) + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_PET_SLOT_BY_ID); + stmt->setInt16(0, srcPetSlot); + stmt->setUInt64(1, GetGUID().GetCounter()); + stmt->setUInt32(2, dstPet->PetNumber); + trans->Append(stmt); + } + + GetSession()->AddTransactionCallback(CharacterDatabase.AsyncCommitTransaction(trans)).AfterComplete( + [sess = GetSession(), this, src, srcPetSlot = srcPetSlot, dst, dstPetSlot = dstPetSlot, newActivePetIndex](bool success) + { + if (sess->GetPlayer() == this) + { + if (success) + { + std::swap(*src, *dst); + if (newActivePetIndex) + sess->GetPlayer()->GetPetStable()->SetCurrentActivePetIndex(*newActivePetIndex); + + int32 srcPetIndex = m_activePlayerData->PetStable->Pets.FindIndexIf([srcPetSlot](UF::StablePetInfo const& p) { return p.PetSlot == uint32(srcPetSlot); }); + int32 dstPetIndex = m_activePlayerData->PetStable->Pets.FindIndexIf([dstPetSlot](UF::StablePetInfo const& p) { return p.PetSlot == uint32(dstPetSlot); }); + + if (srcPetIndex >= 0) + { + SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData) + .ModifyValue(&UF::ActivePlayerData::PetStable, 0) + .ModifyValue(&UF::StableInfo::Pets, srcPetIndex) + .ModifyValue(&UF::StablePetInfo::PetSlot), dstPetSlot); + } + + if (dstPetIndex >= 0) + { + SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData) + .ModifyValue(&UF::ActivePlayerData::PetStable, 0) + .ModifyValue(&UF::StableInfo::Pets, dstPetIndex) + .ModifyValue(&UF::StablePetInfo::PetSlot), srcPetSlot); + } + + sess->SendPetStableResult(StableResult::StableSuccess); + } + else + { + sess->SendPetStableResult(StableResult::InternalError); + } + } + }); +} + +ObjectGuid Player::GetStableMaster() const +{ + if (!m_activePlayerData->PetStable.has_value()) + return ObjectGuid::Empty; + + return m_activePlayerData->PetStable->StableMaster; +} + +void Player::SetStableMaster(ObjectGuid stableMaster) +{ + if (!m_activePlayerData->PetStable.has_value()) + return; + + SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData) + .ModifyValue(&UF::ActivePlayerData::PetStable, 0) + .ModifyValue(&UF::StableInfo::StableMaster), stableMaster); +} + void Player::SendItemRefundResult(Item* item, ItemExtendedCostEntry const* iece, uint8 error) const { WorldPackets::Item::ItemPurchaseRefundResult itemPurchaseRefundResult; @@ -28252,6 +28463,7 @@ void Player::_LoadPetStable(uint32 summonedPetNumber, PreparedQueryResult result // SELECT id, entry, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType, specialization FROM character_pet WHERE owner = ? if (result) { + do { Field* fields = result->Fetch(); @@ -28273,9 +28485,19 @@ void Player::_LoadPetStable(uint32 summonedPetNumber, PreparedQueryResult result petInfo.Type = PetType(fields[14].GetUInt8()); petInfo.SpecializationId = fields[15].GetUInt16(); if (slot >= PET_SAVE_FIRST_ACTIVE_SLOT && slot < PET_SAVE_LAST_ACTIVE_SLOT) + { m_petStable->ActivePets[slot] = std::move(petInfo); + + if (m_petStable->ActivePets[slot]->Type == HUNTER_PET) + AddPetToUpdateFields(*m_petStable->ActivePets[slot], slot, PET_STABLE_ACTIVE); + } else if (slot >= PET_SAVE_FIRST_STABLE_SLOT && slot < PET_SAVE_LAST_STABLE_SLOT) + { m_petStable->StabledPets[slot - PET_SAVE_FIRST_STABLE_SLOT] = std::move(petInfo); + + if (m_petStable->StabledPets[slot - PET_SAVE_FIRST_STABLE_SLOT]->Type == HUNTER_PET) + AddPetToUpdateFields(*m_petStable->StabledPets[slot - PET_SAVE_FIRST_STABLE_SLOT], slot, PET_STABLE_INACTIVE); + } else if (slot == PET_SAVE_NOT_IN_SLOT) m_petStable->UnslottedPets.push_back(std::move(petInfo)); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index e71ac32a8bc..a46e9b05aa6 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1252,6 +1252,10 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> PetStable* GetPetStable() { return m_petStable.get(); } PetStable& GetOrInitPetStable(); PetStable const* GetPetStable() const { return m_petStable.get(); } + void AddPetToUpdateFields(PetStable::PetInfo const& pet, PetSaveMode slot, PetStableFlags flags); + void SetPetSlot(uint32 petNumber, PetSaveMode dstPetSlot); + ObjectGuid GetStableMaster() const; + void SetStableMaster(ObjectGuid stableMaster); Pet* GetPet() const; Pet* SummonPet(uint32 entry, Optional<PetSaveMode> slot, float x, float y, float z, float ang, uint32 despwtime, bool* isNew = nullptr); @@ -1637,8 +1641,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> uint32 GetQuestSlotQuestId(uint16 slot) const; uint32 GetQuestSlotState(uint16 slot) const; uint16 GetQuestSlotCounter(uint16 slot, uint8 counter) const; - uint32 GetQuestSlotEndTime(uint16 slot) const; - uint32 GetQuestSlotAcceptTime(uint16 slot) const; + int64 GetQuestSlotEndTime(uint16 slot) const; bool GetQuestSlotObjectiveFlag(uint16 slot, int8 objectiveIndex) const; int32 GetQuestSlotObjectiveData(uint16 slot, QuestObjective const& objective) const; void SetQuestSlot(uint16 slot, uint32 quest_id); @@ -1646,7 +1649,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void SetQuestSlotState(uint16 slot, uint32 state); void RemoveQuestSlotState(uint16 slot, uint32 state); void SetQuestSlotEndTime(uint16 slot, time_t endTime); - void SetQuestSlotAcceptTime(uint16 slot, time_t acceptTime); void SetQuestSlotObjectiveFlag(uint16 slot, int8 objectiveIndex); void RemoveQuestSlotObjectiveFlag(uint16 slot, int8 objectiveIndex); void SetQuestCompletedBit(uint32 questBit, bool completed); @@ -2163,6 +2165,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void SendResetInstanceFailed(ResetFailedReason reason, uint32 mapID) const; void SendResetFailedNotify(uint32 mapid) const; bool IsLockedToDungeonEncounter(uint32 dungeonEncounterId) const; + bool IsLockedToDungeonEncounter(uint32 dungeonEncounterId, Difficulty difficulty) const; bool UpdatePosition(float x, float y, float z, float orientation, bool teleport = false) override; bool UpdatePosition(Position const& pos, bool teleport = false) override { return UpdatePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teleport); } @@ -2856,6 +2859,9 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void SetTransportServerTime(int32 transportServerTime) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::TransportServerTime), transportServerTime); } + void SetRequiredMountCapabilityFlag(uint8 flag) { SetUpdateFieldFlagValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::RequiredMountCapabilityFlags), flag); } + void ReplaceAllRequiredMountCapabilityFlags(uint8 flags) { SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::RequiredMountCapabilityFlags), flags); } + bool IsInFriendlyArea() const; bool IsFriendlyArea(AreaTableEntry const* inArea) const; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 63b8ad8f6c2..077b9718f72 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -10579,9 +10579,7 @@ bool Unit::InitTamedPet(Pet* pet, uint8 level, uint32 spell_id) pet->SetCreatorGUID(GetGUID()); pet->SetFaction(GetFaction()); pet->SetCreatedBySpell(spell_id); - - if (GetTypeId() == TYPEID_PLAYER) - pet->SetUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED); + pet->SetUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED); if (!pet->InitStatsForLevel(level)) { @@ -10599,6 +10597,7 @@ bool Unit::InitTamedPet(Pet* pet, uint8 level, uint32 spell_id) petStable.SetCurrentActivePetIndex(std::distance(petStable.ActivePets.begin(), freeActiveSlotItr)); pet->FillPetInfo(&freeActiveSlotItr->emplace()); + player->AddPetToUpdateFields(**freeActiveSlotItr, PetSaveMode(*petStable.GetCurrentActivePetIndex()), PET_STABLE_ACTIVE); return true; } @@ -12019,7 +12018,7 @@ uint32 Unit::GetModelForForm(ShapeshiftForm form, uint32 spellId) const if (ChrCustomizationDisplayInfoEntry const* displayInfo = formModelData->Displays[i]) { ChrCustomizationReqEntry const* choiceReq = sChrCustomizationReqStore.LookupEntry((*formModelData->Choices)[i]->ChrCustomizationReqID); - if (!choiceReq || player->GetSession()->MeetsChrCustomizationReq(choiceReq, Classes(GetClass()), false, + if (!choiceReq || player->GetSession()->MeetsChrCustomizationReq(choiceReq, Races(GetRace()), Classes(GetClass()), false, MakeChrCustomizationChoiceRange(player->m_playerData->Customizations))) displayIds.push_back(displayInfo->DisplayID); } |