From df1ec76d54db3a91759fc93f4d6b6828d4ec0f59 Mon Sep 17 00:00:00 2001 From: Shauren Date: Fri, 16 Aug 2024 00:03:22 +0200 Subject: Core: Updated to 11.0.2 --- src/server/game/Entities/Creature/GossipDef.cpp | 2 + src/server/game/Entities/Item/ItemDefines.h | 12 ++- .../game/Entities/Item/enuminfo_ItemDefines.cpp | 41 +++++++++- .../game/Entities/Object/Updates/UpdateFields.cpp | 92 +++++++++++++++++----- .../game/Entities/Object/Updates/UpdateFields.h | 25 ++++-- .../game/Entities/Object/Updates/UpdateMask.h | 2 +- src/server/game/Entities/Player/Player.cpp | 36 +++++++-- src/server/game/Entities/Player/Player.h | 4 +- .../game/Entities/Unit/enuminfo_UnitDefines.cpp | 2 +- 9 files changed, 174 insertions(+), 42 deletions(-) (limited to 'src/server/game/Entities') 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::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::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::Count() { return 119; } +TC_API_EXPORT size_t EnumUtils::Count() { return 130; } template <> TC_API_EXPORT InventoryResult EnumUtils::FromIndex(size_t index) @@ -246,7 +257,7 @@ TC_API_EXPORT InventoryResult EnumUtils::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::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::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::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 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 fieldVi void PlayerData::WriteUpdate(ByteBuffer& data, EnumFlag 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 fieldVi void PlayerData::AppendAllowedFieldsMaskForFlag(Mask& allowedMaskForTarget, EnumFlag fieldVisibilityFlags) { if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag::PartyMember)) - allowedMaskForTarget |= std::array{ 0x00000022u, 0xFFFE0000u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x00000001u, 0x00000000u, 0x00000000u }; + allowedMaskForTarget |= std::array{ 0x00000022u, 0xFFFE0000u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x00000001u, 0x00000000u, 0x00000000u, 0x00000000u }; } void PlayerData::FilterDisallowedFieldsMaskForFlag(Mask& changesMask, EnumFlag 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 FactionID; + UpdateField 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 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 HasQuestSession; UpdateField HasLevelLink; @@ -552,8 +562,9 @@ struct PlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<289> UpdateFieldArray QuestLog; UpdateFieldArray VisibleItems; UpdateFieldArray AvgItemLevel; - UpdateFieldArray VisibleEquipableSpells; - UpdateFieldArray Field_3120; + UpdateFieldArray ForcedReactions; + UpdateFieldArray VisibleEquipableSpells; + UpdateFieldArray Field_3120; void WriteCreate(ByteBuffer& data, EnumFlag fieldVisibilityFlags, Player const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, EnumFlag 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 Field_0; - UpdateField Field_8; - UpdateField Field_C; - UpdateField Field_10; + UpdateField OrderID; + UpdateField NpcCraftingOrderSetID; + UpdateField NpcTreasureID; + UpdateField 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) { @@ -17314,15 +17343,10 @@ 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 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 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::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%" }; -- cgit v1.2.3