aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2024-08-16 00:03:22 +0200
committerShauren <shauren.trinity@gmail.com>2024-08-16 00:03:22 +0200
commitdf1ec76d54db3a91759fc93f4d6b6828d4ec0f59 (patch)
tree824cd4bc52735c0e23996d9852b9f608b0ab4cfc /src/server/game/Entities
parent3429871a07c1c1ebe2bd94cb771ef187cb46fd46 (diff)
Core: Updated to 11.0.2
Diffstat (limited to 'src/server/game/Entities')
-rw-r--r--src/server/game/Entities/Creature/GossipDef.cpp2
-rw-r--r--src/server/game/Entities/Item/ItemDefines.h12
-rw-r--r--src/server/game/Entities/Item/enuminfo_ItemDefines.cpp41
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateFields.cpp92
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateFields.h25
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateMask.h2
-rw-r--r--src/server/game/Entities/Player/Player.cpp36
-rw-r--r--src/server/game/Entities/Player/Player.h4
-rw-r--r--src/server/game/Entities/Unit/enuminfo_UnitDefines.cpp2
9 files changed, 174 insertions, 42 deletions
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp
index 818bff310e0..9393fd3a0d1 100644
--- a/src/server/game/Entities/Creature/GossipDef.cpp
+++ b/src/server/game/Entities/Creature/GossipDef.cpp
@@ -591,6 +591,7 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, ObjectGuid npcGUI
offer.QuestID = quest->GetQuestId();
offer.AutoLaunched = autoLaunched;
+ offer.ResetByScheduler = quest->IsResetByScheduler();
offer.SuggestedPartyMembers = quest->GetSuggestedPlayers();
offer.QuestInfoID = quest->GetQuestInfoID();
@@ -693,6 +694,7 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, ObjectGuid npcGU
}
packet.AutoLaunched = autoLaunched;
+ packet.ResetByScheduler = quest->IsResetByScheduler();
_session->SendPacket(packet.Write());
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPC={}, questid={}", npcGUID.ToString(), quest->GetQuestId());
diff --git a/src/server/game/Entities/Item/ItemDefines.h b/src/server/game/Entities/Item/ItemDefines.h
index 85a7a558e2a..1d93f470c4a 100644
--- a/src/server/game/Entities/Item/ItemDefines.h
+++ b/src/server/game/Entities/Item/ItemDefines.h
@@ -107,7 +107,7 @@ enum InventoryResult : uint8
EQUIP_ERR_CANT_EQUIP_RATING = 81, // You don't have the personal, team, or battleground rating required to buy that item
EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM = 82,
EQUIP_ERR_NOT_SAME_ACCOUNT = 83, // Account-bound items can only be given to your own characters.
- EQUIP_NONE_3 = 84,
+ EQUIP_ERR_NONE = 84,
EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED_IS = 85, // You can only carry %d %s
EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_SOCKETED_EXCEEDED_IS = 86, // You can only equip %d |4item:items in the %s category
EQUIP_ERR_SCALING_STAT_ITEM_LEVEL_EXCEEDED = 87, // Your level is too high to use that item
@@ -143,6 +143,16 @@ enum InventoryResult : uint8
EQUIP_ERR_REAGENTBAG_ITEM_TYPE = 117,// Only Reagents can be placed in Reagent Bags.
EQUIP_ERR_CANT_BULK_SELL_ITEM_WITH_REFUND = 118,// Items that can be refunded can't be bulk sold.
EQUIP_ERR_NO_SOULBOUND_ITEM_IN_ACCOUNT_BANK = 119,// Soulbound items cannot be stored in the Warband Bank.
+ EQUIP_ERR_CANT_DO_THAT_RIGHT_NOW_3 = 120,// You can't do that right now.
+ EQUIP_ERR_NO_ACCOUNT_INVENTORY_LOCK = 121,// Your character cannot complete this action.
+ EQUIP_ERR_TOO_MANY_ACCOUNT_BANK_TABS = 122,// You have already purchased the maximum amount of tabs.
+ EQUIP_ERR_NO_ACCOUNT_BANK_HERE = 123,// You are too far away from a Warband Bank.
+ EQUIP_ERR_NO_REFUNDABLE_ITEM_IN_ACCOUNT_BANK = 124,// Refundable items cannot be stored in the Warband Bank.
+ EQUIP_ERR_NO_IMMEDIATE_CONTAINER_IN_ACCOUNT_BANK = 125,// You cannot place that in the Warband Bank.
+ EQUIP_ERR_NO_OPEN_IMMEDIATE_CONTAINER_IN_ACCOUNT_BANK = 126,// You cannot open this while it is in the Warband Bank.
+ EQUIP_ERR_CANT_DELETE_IN_ACCOUNT_BANK = 127,// Items must be moved out of the Warband Bank to be deleted.
+ EQUIP_ERR_BANK_NOT_ACCESSIBLE = 128,// This character does not have access to this bank.
+ EQUIP_ERR_CANT_TRADE_ACCOUNT_ITEM = 129,// You can't trade an item from the Warband bank.
};
// EnumUtils: DESCRIBE THIS
diff --git a/src/server/game/Entities/Item/enuminfo_ItemDefines.cpp b/src/server/game/Entities/Item/enuminfo_ItemDefines.cpp
index c5f91ead4b3..f18d83fa079 100644
--- a/src/server/game/Entities/Item/enuminfo_ItemDefines.cpp
+++ b/src/server/game/Entities/Item/enuminfo_ItemDefines.cpp
@@ -115,7 +115,7 @@ TC_API_EXPORT EnumText EnumUtils<InventoryResult>::ToString(InventoryResult valu
case EQUIP_ERR_CANT_EQUIP_RATING: return { "EQUIP_ERR_CANT_EQUIP_RATING", "EQUIP_ERR_CANT_EQUIP_RATING", "You don't have the personal, team, or battleground rating required to buy that item" };
case EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM: return { "EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM", "EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM", "" };
case EQUIP_ERR_NOT_SAME_ACCOUNT: return { "EQUIP_ERR_NOT_SAME_ACCOUNT", "EQUIP_ERR_NOT_SAME_ACCOUNT", "Account-bound items can only be given to your own characters." };
- case EQUIP_NONE_3: return { "EQUIP_NONE_3", "EQUIP_NONE_3", "" };
+ case EQUIP_ERR_NONE: return { "EQUIP_ERR_NONE", "EQUIP_ERR_NONE", "" };
case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED_IS: return { "EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED_IS", "EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED_IS", "You can only carry %d %s" };
case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_SOCKETED_EXCEEDED_IS: return { "EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_SOCKETED_EXCEEDED_IS", "EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_SOCKETED_EXCEEDED_IS", "You can only equip %d |4item:items in the %s category" };
case EQUIP_ERR_SCALING_STAT_ITEM_LEVEL_EXCEEDED: return { "EQUIP_ERR_SCALING_STAT_ITEM_LEVEL_EXCEEDED", "EQUIP_ERR_SCALING_STAT_ITEM_LEVEL_EXCEEDED", "Your level is too high to use that item" };
@@ -150,12 +150,23 @@ TC_API_EXPORT EnumText EnumUtils<InventoryResult>::ToString(InventoryResult valu
case EQUIP_ERR_SLOT_ONLY_REAGENTBAG: return { "EQUIP_ERR_SLOT_ONLY_REAGENTBAG", "EQUIP_ERR_SLOT_ONLY_REAGENTBAG", "Only Reagent Bags can be placed in the reagent bag slot." };
case EQUIP_ERR_REAGENTBAG_ITEM_TYPE: return { "EQUIP_ERR_REAGENTBAG_ITEM_TYPE", "EQUIP_ERR_REAGENTBAG_ITEM_TYPE", "Only Reagents can be placed in Reagent Bags." };
case EQUIP_ERR_CANT_BULK_SELL_ITEM_WITH_REFUND: return { "EQUIP_ERR_CANT_BULK_SELL_ITEM_WITH_REFUND", "EQUIP_ERR_CANT_BULK_SELL_ITEM_WITH_REFUND", "Items that can be refunded can't be bulk sold." };
+ case EQUIP_ERR_NO_SOULBOUND_ITEM_IN_ACCOUNT_BANK: return { "EQUIP_ERR_NO_SOULBOUND_ITEM_IN_ACCOUNT_BANK", "EQUIP_ERR_NO_SOULBOUND_ITEM_IN_ACCOUNT_BANK", "Soulbound items cannot be stored in the Warband Bank." };
+ case EQUIP_ERR_CANT_DO_THAT_RIGHT_NOW_3: return { "EQUIP_ERR_CANT_DO_THAT_RIGHT_NOW_3", "EQUIP_ERR_CANT_DO_THAT_RIGHT_NOW_3", "You can't do that right now." };
+ case EQUIP_ERR_NO_ACCOUNT_INVENTORY_LOCK: return { "EQUIP_ERR_NO_ACCOUNT_INVENTORY_LOCK", "EQUIP_ERR_NO_ACCOUNT_INVENTORY_LOCK", "Your character cannot complete this action." };
+ case EQUIP_ERR_TOO_MANY_ACCOUNT_BANK_TABS: return { "EQUIP_ERR_TOO_MANY_ACCOUNT_BANK_TABS", "EQUIP_ERR_TOO_MANY_ACCOUNT_BANK_TABS", "You have already purchased the maximum amount of tabs." };
+ case EQUIP_ERR_NO_ACCOUNT_BANK_HERE: return { "EQUIP_ERR_NO_ACCOUNT_BANK_HERE", "EQUIP_ERR_NO_ACCOUNT_BANK_HERE", "You are too far away from a Warband Bank." };
+ case EQUIP_ERR_NO_REFUNDABLE_ITEM_IN_ACCOUNT_BANK: return { "EQUIP_ERR_NO_REFUNDABLE_ITEM_IN_ACCOUNT_BANK", "EQUIP_ERR_NO_REFUNDABLE_ITEM_IN_ACCOUNT_BANK", "Refundable items cannot be stored in the Warband Bank." };
+ case EQUIP_ERR_NO_IMMEDIATE_CONTAINER_IN_ACCOUNT_BANK: return { "EQUIP_ERR_NO_IMMEDIATE_CONTAINER_IN_ACCOUNT_BANK", "EQUIP_ERR_NO_IMMEDIATE_CONTAINER_IN_ACCOUNT_BANK", "You cannot place that in the Warband Bank." };
+ case EQUIP_ERR_NO_OPEN_IMMEDIATE_CONTAINER_IN_ACCOUNT_BANK: return { "EQUIP_ERR_NO_OPEN_IMMEDIATE_CONTAINER_IN_ACCOUNT_BANK", "EQUIP_ERR_NO_OPEN_IMMEDIATE_CONTAINER_IN_ACCOUNT_BANK", "You cannot open this while it is in the Warband Bank." };
+ case EQUIP_ERR_CANT_DELETE_IN_ACCOUNT_BANK: return { "EQUIP_ERR_CANT_DELETE_IN_ACCOUNT_BANK", "EQUIP_ERR_CANT_DELETE_IN_ACCOUNT_BANK", "Items must be moved out of the Warband Bank to be deleted." };
+ case EQUIP_ERR_BANK_NOT_ACCESSIBLE: return { "EQUIP_ERR_BANK_NOT_ACCESSIBLE", "EQUIP_ERR_BANK_NOT_ACCESSIBLE", "This character does not have access to this bank." };
+ case EQUIP_ERR_CANT_TRADE_ACCOUNT_ITEM: return { "EQUIP_ERR_CANT_TRADE_ACCOUNT_ITEM", "EQUIP_ERR_CANT_TRADE_ACCOUNT_ITEM", "You can't trade an item from the Warband bank." };
default: throw std::out_of_range("value");
}
}
template <>
-TC_API_EXPORT size_t EnumUtils<InventoryResult>::Count() { return 119; }
+TC_API_EXPORT size_t EnumUtils<InventoryResult>::Count() { return 130; }
template <>
TC_API_EXPORT InventoryResult EnumUtils<InventoryResult>::FromIndex(size_t index)
@@ -246,7 +257,7 @@ TC_API_EXPORT InventoryResult EnumUtils<InventoryResult>::FromIndex(size_t index
case 81: return EQUIP_ERR_CANT_EQUIP_RATING;
case 82: return EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM;
case 83: return EQUIP_ERR_NOT_SAME_ACCOUNT;
- case 84: return EQUIP_NONE_3;
+ case 84: return EQUIP_ERR_NONE;
case 85: return EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED_IS;
case 86: return EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_SOCKETED_EXCEEDED_IS;
case 87: return EQUIP_ERR_SCALING_STAT_ITEM_LEVEL_EXCEEDED;
@@ -281,6 +292,17 @@ TC_API_EXPORT InventoryResult EnumUtils<InventoryResult>::FromIndex(size_t index
case 116: return EQUIP_ERR_SLOT_ONLY_REAGENTBAG;
case 117: return EQUIP_ERR_REAGENTBAG_ITEM_TYPE;
case 118: return EQUIP_ERR_CANT_BULK_SELL_ITEM_WITH_REFUND;
+ case 119: return EQUIP_ERR_NO_SOULBOUND_ITEM_IN_ACCOUNT_BANK;
+ case 120: return EQUIP_ERR_CANT_DO_THAT_RIGHT_NOW_3;
+ case 121: return EQUIP_ERR_NO_ACCOUNT_INVENTORY_LOCK;
+ case 122: return EQUIP_ERR_TOO_MANY_ACCOUNT_BANK_TABS;
+ case 123: return EQUIP_ERR_NO_ACCOUNT_BANK_HERE;
+ case 124: return EQUIP_ERR_NO_REFUNDABLE_ITEM_IN_ACCOUNT_BANK;
+ case 125: return EQUIP_ERR_NO_IMMEDIATE_CONTAINER_IN_ACCOUNT_BANK;
+ case 126: return EQUIP_ERR_NO_OPEN_IMMEDIATE_CONTAINER_IN_ACCOUNT_BANK;
+ case 127: return EQUIP_ERR_CANT_DELETE_IN_ACCOUNT_BANK;
+ case 128: return EQUIP_ERR_BANK_NOT_ACCESSIBLE;
+ case 129: return EQUIP_ERR_CANT_TRADE_ACCOUNT_ITEM;
default: throw std::out_of_range("index");
}
}
@@ -374,7 +396,7 @@ TC_API_EXPORT size_t EnumUtils<InventoryResult>::ToIndex(InventoryResult value)
case EQUIP_ERR_CANT_EQUIP_RATING: return 81;
case EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM: return 82;
case EQUIP_ERR_NOT_SAME_ACCOUNT: return 83;
- case EQUIP_NONE_3: return 84;
+ case EQUIP_ERR_NONE: return 84;
case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED_IS: return 85;
case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_SOCKETED_EXCEEDED_IS: return 86;
case EQUIP_ERR_SCALING_STAT_ITEM_LEVEL_EXCEEDED: return 87;
@@ -409,6 +431,17 @@ TC_API_EXPORT size_t EnumUtils<InventoryResult>::ToIndex(InventoryResult value)
case EQUIP_ERR_SLOT_ONLY_REAGENTBAG: return 116;
case EQUIP_ERR_REAGENTBAG_ITEM_TYPE: return 117;
case EQUIP_ERR_CANT_BULK_SELL_ITEM_WITH_REFUND: return 118;
+ case EQUIP_ERR_NO_SOULBOUND_ITEM_IN_ACCOUNT_BANK: return 119;
+ case EQUIP_ERR_CANT_DO_THAT_RIGHT_NOW_3: return 120;
+ case EQUIP_ERR_NO_ACCOUNT_INVENTORY_LOCK: return 121;
+ case EQUIP_ERR_TOO_MANY_ACCOUNT_BANK_TABS: return 122;
+ case EQUIP_ERR_NO_ACCOUNT_BANK_HERE: return 123;
+ case EQUIP_ERR_NO_REFUNDABLE_ITEM_IN_ACCOUNT_BANK: return 124;
+ case EQUIP_ERR_NO_IMMEDIATE_CONTAINER_IN_ACCOUNT_BANK: return 125;
+ case EQUIP_ERR_NO_OPEN_IMMEDIATE_CONTAINER_IN_ACCOUNT_BANK: return 126;
+ case EQUIP_ERR_CANT_DELETE_IN_ACCOUNT_BANK: return 127;
+ case EQUIP_ERR_BANK_NOT_ACCESSIBLE: return 128;
+ case EQUIP_ERR_CANT_TRADE_ACCOUNT_ITEM: return 129;
default: throw std::out_of_range("value");
}
}
diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.cpp b/src/server/game/Entities/Object/Updates/UpdateFields.cpp
index 8b54351c6c3..074ae923b02 100644
--- a/src/server/game/Entities/Object/Updates/UpdateFields.cpp
+++ b/src/server/game/Entities/Object/Updates/UpdateFields.cpp
@@ -2124,6 +2124,41 @@ void ArenaCooldown::ClearChangesMask()
_changesMask.ResetAll();
}
+void ZonePlayerForcedReaction::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const
+{
+ data << int32(FactionID);
+ data << int32(Reaction);
+}
+
+void ZonePlayerForcedReaction::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);
+
+ data.FlushBits();
+ if (changesMask[0])
+ {
+ if (changesMask[1])
+ {
+ data << int32(FactionID);
+ }
+ if (changesMask[2])
+ {
+ data << int32(Reaction);
+ }
+ }
+}
+
+void ZonePlayerForcedReaction::ClearChangesMask()
+{
+ Base::ClearChangesMask(FactionID);
+ Base::ClearChangesMask(Reaction);
+ _changesMask.ResetAll();
+}
+
void PetCreatureName::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const
{
data << uint32(CreatureID);
@@ -2341,6 +2376,10 @@ void PlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVi
data << int32(HonorLevel);
data << int64(LogoutTime);
data << uint32(ArenaCooldowns.size());
+ for (uint32 i = 0; i < 32; ++i)
+ {
+ ForcedReactions[i].WriteCreate(data, owner, receiver);
+ }
data << int32(Field_1AC);
data << int32(Field_1B0);
data << int32(CurrentBattlePetSpeciesID);
@@ -2406,7 +2445,7 @@ void PlayerData::WriteCreate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVi
void PlayerData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const
{
- Mask allowedMaskForTarget({ 0xFFFFFFDDu, 0x0001FFFFu, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xFFFFFFFEu, 0xFFFFFFFFu, 0x00000001u });
+ Mask allowedMaskForTarget({ 0xFFFFFFDDu, 0x0001FFFFu, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xFFFFFFFEu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x00000003u });
AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags);
WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver);
}
@@ -2414,20 +2453,20 @@ void PlayerData::WriteUpdate(ByteBuffer& data, EnumFlag<UpdateFieldFlag> fieldVi
void PlayerData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags)
{
if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::PartyMember))
- allowedMaskForTarget |= std::array<uint32, 10>{ 0x00000022u, 0xFFFE0000u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x00000001u, 0x00000000u, 0x00000000u };
+ allowedMaskForTarget |= std::array<uint32, 11>{ 0x00000022u, 0xFFFE0000u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x00000001u, 0x00000000u, 0x00000000u, 0x00000000u };
}
void PlayerData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag<UpdateFieldFlag> fieldVisibilityFlags)
{
- Mask allowedMaskForTarget({ 0xFFFFFFDDu, 0x0001FFFFu, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xFFFFFFFEu, 0xFFFFFFFFu, 0x00000001u });
+ Mask allowedMaskForTarget({ 0xFFFFFFDDu, 0x0001FFFFu, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xFFFFFFFEu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x00000003u });
AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags);
changesMask &= allowedMaskForTarget;
}
void PlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ignoreNestedChangesMask, Player const* owner, Player const* receiver) const
{
- data.WriteBits(changesMask.GetBlocksMask(0), 10);
- for (uint32 i = 0; i < 10; ++i)
+ data.WriteBits(changesMask.GetBlocksMask(0), 11);
+ for (uint32 i = 0; i < 11; ++i)
if (changesMask.GetBlock(i))
data.WriteBits(changesMask.GetBlock(i), 32);
@@ -2751,21 +2790,31 @@ void PlayerData::WriteUpdate(ByteBuffer& data, Mask const& changesMask, bool ign
}
}
}
- if (changesMask[269])
+ if (changesMask[252])
+ {
+ for (uint32 i = 0; i < 32; ++i)
+ {
+ if (changesMask[253 + i])
+ {
+ ForcedReactions[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver);
+ }
+ }
+ }
+ if (changesMask[302])
{
for (uint32 i = 0; i < 19; ++i)
{
- if (changesMask[270 + i])
+ if (changesMask[303 + i])
{
data << uint32(Field_3120[i]);
}
}
}
- if (changesMask[252])
+ if (changesMask[285])
{
for (uint32 i = 0; i < 16; ++i)
{
- if (changesMask[253 + i])
+ if (changesMask[286 + i])
{
data << VisibleEquipableSpells[i];
}
@@ -2824,6 +2873,7 @@ void PlayerData::ClearChangesMask()
Base::ClearChangesMask(QuestLog);
Base::ClearChangesMask(VisibleItems);
Base::ClearChangesMask(AvgItemLevel);
+ Base::ClearChangesMask(ForcedReactions);
Base::ClearChangesMask(VisibleEquipableSpells);
Base::ClearChangesMask(Field_3120);
_changesMask.ResetAll();
@@ -4204,10 +4254,10 @@ void PersonalCraftingOrderCount::ClearChangesMask()
void NPCCraftingOrderInfo::WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const
{
- data << uint64(Field_0);
- data << int32(Field_8);
- data << int32(Field_C);
- data << int32(Field_10);
+ data << uint64(OrderID);
+ data << int32(NpcCraftingOrderSetID);
+ data << int32(NpcTreasureID);
+ data << int32(NpcCraftingOrderCustomerID);
}
void NPCCraftingOrderInfo::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const
@@ -4221,28 +4271,28 @@ void NPCCraftingOrderInfo::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask,
data.FlushBits();
if (changesMask[0])
{
- data << uint64(Field_0);
+ data << uint64(OrderID);
}
if (changesMask[1])
{
- data << int32(Field_8);
+ data << int32(NpcCraftingOrderSetID);
}
if (changesMask[2])
{
- data << int32(Field_C);
+ data << int32(NpcTreasureID);
}
if (changesMask[3])
{
- data << int32(Field_10);
+ data << int32(NpcCraftingOrderCustomerID);
}
}
void NPCCraftingOrderInfo::ClearChangesMask()
{
- Base::ClearChangesMask(Field_0);
- Base::ClearChangesMask(Field_8);
- Base::ClearChangesMask(Field_C);
- Base::ClearChangesMask(Field_10);
+ Base::ClearChangesMask(OrderID);
+ Base::ClearChangesMask(NpcCraftingOrderSetID);
+ Base::ClearChangesMask(NpcTreasureID);
+ Base::ClearChangesMask(NpcCraftingOrderCustomerID);
_changesMask.ResetAll();
}
diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.h b/src/server/game/Entities/Object/Updates/UpdateFields.h
index 43b1c60d9a9..cf5a167706b 100644
--- a/src/server/game/Entities/Object/Updates/UpdateFields.h
+++ b/src/server/game/Entities/Object/Updates/UpdateFields.h
@@ -458,6 +458,16 @@ struct ArenaCooldown : public IsUpdateFieldStructureTag, public HasChangesMask<8
void ClearChangesMask();
};
+struct ZonePlayerForcedReaction : public IsUpdateFieldStructureTag, public HasChangesMask<3>
+{
+ UpdateField<int32, 0, 1> FactionID;
+ UpdateField<int32, 0, 2> Reaction;
+
+ 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 PetCreatureName : public IsUpdateFieldStructureTag, public HasChangesMask<3>
{
UpdateField<uint32, 0, 1> CreatureID;
@@ -502,7 +512,7 @@ struct CustomTabardInfo : public IsUpdateFieldStructureTag, public HasChangesMas
void ClearChangesMask();
};
-struct PlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<289>
+struct PlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<322>
{
UpdateField<bool, 0, 1> HasQuestSession;
UpdateField<bool, 0, 2> HasLevelLink;
@@ -552,8 +562,9 @@ struct PlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<289>
UpdateFieldArray<UF::QuestLog, 175, 49, 50> QuestLog;
UpdateFieldArray<UF::VisibleItem, 19, 225, 226> VisibleItems;
UpdateFieldArray<float, 6, 245, 246> AvgItemLevel;
- UpdateFieldArray<WorldPackets::Item::ItemInstance, 16, 252, 253> VisibleEquipableSpells;
- UpdateFieldArray<uint32, 19, 269, 270> Field_3120;
+ UpdateFieldArray<UF::ZonePlayerForcedReaction, 32, 252, 253> ForcedReactions;
+ UpdateFieldArray<WorldPackets::Item::ItemInstance, 16, 285, 286> VisibleEquipableSpells;
+ UpdateFieldArray<uint32, 19, 302, 303> Field_3120;
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;
@@ -887,10 +898,10 @@ struct PersonalCraftingOrderCount : public IsUpdateFieldStructureTag, public Has
struct NPCCraftingOrderInfo : public IsUpdateFieldStructureTag, public HasChangesMask<4>
{
- UpdateField<uint64, -1, 0> Field_0;
- UpdateField<int32, -1, 1> Field_8;
- UpdateField<int32, -1, 2> Field_C;
- UpdateField<int32, -1, 3> Field_10;
+ UpdateField<uint64, -1, 0> OrderID;
+ UpdateField<int32, -1, 1> NpcCraftingOrderSetID;
+ UpdateField<int32, -1, 2> NpcTreasureID;
+ UpdateField<int32, -1, 3> NpcCraftingOrderCustomerID;
void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const;
void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const;
diff --git a/src/server/game/Entities/Object/Updates/UpdateMask.h b/src/server/game/Entities/Object/Updates/UpdateMask.h
index b8262387907..a79b5c038ab 100644
--- a/src/server/game/Entities/Object/Updates/UpdateMask.h
+++ b/src/server/game/Entities/Object/Updates/UpdateMask.h
@@ -63,7 +63,7 @@ public:
constexpr bool operator[](uint32 index) const
{
- return (_blocks[index / 32] & (1 << (index % 32))) != 0;
+ return (_blocks[UpdateMaskHelpers::GetBlockIndex(index)] & UpdateMaskHelpers::GetBlockFlag(index)) != 0;
}
constexpr bool IsAnySet() const
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 8bdef90b5cf..38e4b62507b 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -6604,6 +6604,35 @@ int32 Player::CalculateReputationGain(ReputationSource source, uint32 creatureOr
return CalculatePct(rep, percent);
}
+void Player::SetVisibleForcedReaction(uint32 factionId, ReputationRank rank)
+{
+ auto itr = std::ranges::find(m_playerData->ForcedReactions, int32(factionId), &UF::ZonePlayerForcedReaction::FactionID);
+ if (itr == m_playerData->ForcedReactions.end())
+ itr = std::ranges::find(m_playerData->ForcedReactions, 0, &UF::ZonePlayerForcedReaction::FactionID);
+
+ if (itr == m_playerData->ForcedReactions.end())
+ return; // no more free slots
+
+ auto setter = m_values.ModifyValue(&Player::m_playerData)
+ .ModifyValue(&UF::PlayerData::ForcedReactions, std::ranges::distance(m_playerData->ForcedReactions.begin(), itr));
+
+ SetUpdateFieldValue(setter.ModifyValue(&UF::ZonePlayerForcedReaction::FactionID), factionId);
+ SetUpdateFieldValue(setter.ModifyValue(&UF::ZonePlayerForcedReaction::Reaction), rank);
+}
+
+void Player::RemoveVisibleForcedReaction(uint32 factionId)
+{
+ auto itr = std::ranges::find(m_playerData->ForcedReactions, int32(factionId), &UF::ZonePlayerForcedReaction::FactionID);
+ if (itr == m_playerData->ForcedReactions.end())
+ return;
+
+ auto setter = m_values.ModifyValue(&Player::m_playerData)
+ .ModifyValue(&UF::PlayerData::ForcedReactions, std::ranges::distance(m_playerData->ForcedReactions.begin(), itr));
+
+ SetUpdateFieldValue(setter.ModifyValue(&UF::ZonePlayerForcedReaction::FactionID), 0);
+ SetUpdateFieldValue(setter.ModifyValue(&UF::ZonePlayerForcedReaction::Reaction), 0);
+}
+
// Calculates how many reputation points player gains in victim's enemy factions
void Player::RewardReputation(Unit* victim, float rate)
{
@@ -17315,14 +17344,9 @@ void Player::SendQuestUpdateAddPlayer(Quest const* quest, uint16 newCount) const
void Player::SendQuestGiverStatusMultiple()
{
- SendQuestGiverStatusMultiple(m_clientGUIDs);
-}
-
-void Player::SendQuestGiverStatusMultiple(GuidUnorderedSet const& guids)
-{
WorldPackets::Quest::QuestGiverStatusMultiple response;
- for (auto itr = guids.begin(); itr != guids.end(); ++itr)
+ for (auto itr = m_clientGUIDs.begin(); itr != m_clientGUIDs.end(); ++itr)
{
if (itr->IsAnyTypeCreature())
{
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index f83e54de2bc..43a42c6ab71 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1747,7 +1747,6 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
void SendQuestUpdateAddItem(ItemTemplate const* itemTemplate, QuestObjective const& obj, uint16 count) const;
void SendQuestUpdateAddPlayer(Quest const* quest, uint16 newCount) const;
void SendQuestGiverStatusMultiple();
- void SendQuestGiverStatusMultiple(GuidUnorderedSet const& guids);
void SendDisplayToast(uint32 entry, DisplayToastType type, bool isBonusRoll, uint32 quantity, DisplayToastMethod method, uint32 questId = 0, Item* item = nullptr) const;
uint32 GetSharedQuestID() const { return m_sharedQuestId; }
@@ -2342,6 +2341,9 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
int32 CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool noQuestBonus = false);
+ void SetVisibleForcedReaction(uint32 factionId, ReputationRank rank);
+ void RemoveVisibleForcedReaction(uint32 factionId);
+
void UpdateSkillsForLevel();
void ModifySkillBonus(uint32 skillid, int32 val, bool talent);
diff --git a/src/server/game/Entities/Unit/enuminfo_UnitDefines.cpp b/src/server/game/Entities/Unit/enuminfo_UnitDefines.cpp
index a5fa869ebc2..8160e9fed22 100644
--- a/src/server/game/Entities/Unit/enuminfo_UnitDefines.cpp
+++ b/src/server/game/Entities/Unit/enuminfo_UnitDefines.cpp
@@ -421,7 +421,7 @@ TC_API_EXPORT EnumText EnumUtils<NPCFlags>::ToString(NPCFlags value)
case UNIT_NPC_FLAG_NONE: return { "UNIT_NPC_FLAG_NONE", "UNIT_NPC_FLAG_NONE", "" };
case UNIT_NPC_FLAG_GOSSIP: return { "UNIT_NPC_FLAG_GOSSIP", "has gossip menu", "100%" };
case UNIT_NPC_FLAG_QUESTGIVER: return { "UNIT_NPC_FLAG_QUESTGIVER", "is quest giver", "100%" };
- case UNIT_NPC_FLAG_ACCOUNT_BANKER: return { "UNIT_NPC_FLAG_ACCOUNT_BANKER", "UNIT_NPC_FLAG_ACCOUNT_BANKER", "" };
+ case UNIT_NPC_FLAG_ACCOUNT_BANKER: return { "UNIT_NPC_FLAG_ACCOUNT_BANKER", "is account banker", "" };
case UNIT_NPC_FLAG_UNK2: return { "UNIT_NPC_FLAG_UNK2", "UNIT_NPC_FLAG_UNK2", "" };
case UNIT_NPC_FLAG_TRAINER: return { "UNIT_NPC_FLAG_TRAINER", "is trainer", "100%" };
case UNIT_NPC_FLAG_TRAINER_CLASS: return { "UNIT_NPC_FLAG_TRAINER_CLASS", "is class trainer", "100%" };